From b8ad91285560769271d9ff9984dd79f25e08d2b9 Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 20 Dec 2025 08:24:27 -0600 Subject: [PATCH] add JSON schema for config file --- schema/config.schema.json | 15 + schema/modules.schema.json | 481 ++++++++++++++++++++++++++ schema/processors.schema.json | 631 ++++++++++++++++++++++++++++++++++ schema/routes.schema.json | 22 ++ 4 files changed, 1149 insertions(+) create mode 100644 schema/config.schema.json create mode 100644 schema/modules.schema.json create mode 100644 schema/processors.schema.json create mode 100644 schema/routes.schema.json diff --git a/schema/config.schema.json b/schema/config.schema.json new file mode 100644 index 0000000..b4619cb --- /dev/null +++ b/schema/config.schema.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://showbridge.io/config.schema.json", + "title": "Config", + "description": "showbridge config file", + "type": "object", + "properties": { + "modules": { + "$ref": "https://showbridge.io/modules.schema.json" + }, + "routes": { + "$ref": "https://showbridge.io/routes.schema.json" + } + } +} diff --git a/schema/modules.schema.json b/schema/modules.schema.json new file mode 100644 index 0000000..9513da2 --- /dev/null +++ b/schema/modules.schema.json @@ -0,0 +1,481 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://showbridge.io/modules.schema.json", + "title": "Modules", + "description": "showbridge modules array", + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "title": "HTTPClientModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "http.client" + } + }, + "required": ["id", "type"], + "additionalProperties": false + }, + { + "type": "object", + "title": "HTTPServerModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "http.server" + }, + "params": { + "type": "object", + "properties": { + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + }, + "required": ["port"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "IntervalModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "gen.interval" + }, + "params": { + "type": "object", + "properties": { + "duration": { + "type": "integer" + } + }, + "required": ["duration"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "TimerModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "gen.timer" + }, + "params": { + "type": "object", + "properties": { + "duration": { + "type": "integer" + } + }, + "required": ["duration"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "MIDIInputModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "midi.input" + }, + "params": { + "type": "object", + "properties": { + "port": { + "type": "string" + } + }, + "required": ["port"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "MIDIOutputModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "midi.output" + }, + "params": { + "type": "object", + "properties": { + "port": { + "type": "string" + } + }, + "required": ["port"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "MQTTClientModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "mqtt.client" + }, + "params": { + "type": "object", + "properties": { + "broker": { + "type": "string" + }, + "topic": { + "type": "string" + }, + "clientId": { + "type": "string" + } + }, + "required": ["broker", "topic", "clientId"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "NATSClientModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "nats.client" + }, + "params": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "subject": { + "type": "string" + } + }, + "required": ["url", "subject"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "PSNClientModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "psn.client" + } + }, + "required": ["id", "type"], + "additionalProperties": false + }, + { + "type": "object", + "title": "SerialClientModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "serial.client" + }, + "params": { + "type": "object", + "properties": { + "port": { + "type": "string" + }, + "baudRate": { + "type": "integer" + } + }, + "required": ["port", "baudRate"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "SIPCallServerModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "sip.call.server" + }, + "params": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "default": "0.0.0.0" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 5060 + }, + "transport": { + "type": "string", + "enum": ["udp", "tcp", "ws", "udp4", "tcp4"], + "default": "udp" + }, + "userAgent": { + "type": "string", + "default": "showbridge" + } + }, + "required": [], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "SIPDTMFServerModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "sip.dtmf.server" + }, + "params": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "default": "0.0.0.0" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535, + "default": 5060 + }, + "transport": { + "type": "string", + "enum": ["udp", "tcp", "ws", "udp4", "tcp4"], + "default": "udp" + }, + "separator": { + "type": "string", + "minLength": 1, + "maxLength": 1 + } + }, + "required": ["separator"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "TCPClientModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "net.tcp.client" + }, + "params": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "framing": { + "type": "string", + "enum": ["LF", "CR", "CRLF", "SLIP", "RAW"] + } + }, + "required": ["host", "port", "framing"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "TCPServerModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "net.tcp.server" + }, + "params": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "default": "0.0.0.0" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + }, + "framing": { + "type": "string", + "enum": ["LF", "CR", "CRLF", "SLIP", "RAW"] + } + }, + "required": ["port", "framing"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "UDPClientModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "net.udp.client" + }, + "params": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + }, + "required": ["host", "port"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "UDPMulticastModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "net.udp.multicast" + }, + "params": { + "type": "object", + "properties": { + "ip": { + "type": "string" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + }, + "required": ["ip", "port"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "title": "UDPServerModule", + "properties": { + "id": { + "type": "string" + }, + "type": { + "const": "net.udp.server" + }, + "params": { + "type": "object", + "properties": { + "ip": { + "type": "string", + "default": "0.0.0.0" + }, + "port": { + "type": "integer", + "minimum": 1, + "maximum": 65535 + } + }, + "required": ["port"], + "additionalProperties": false + } + }, + "required": ["id", "type", "params"], + "additionalProperties": false + } + ] + } +} diff --git a/schema/processors.schema.json b/schema/processors.schema.json new file mode 100644 index 0000000..ce361e3 --- /dev/null +++ b/schema/processors.schema.json @@ -0,0 +1,631 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://showbridge.io/processors.schema.json", + "title": "Processors", + "description": "showbridge processors array", + "type": "array", + "items": { + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "debug.log" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "float.parse" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "freed.create" + }, + "params": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "pan": { + "type": "string" + }, + "tilt": { + "type": "string" + }, + "roll": { + "type": "string" + }, + "posX": { + "type": "string" + }, + "posY": { + "type": "string" + }, + "posZ": { + "type": "string" + }, + "zoom": { + "type": "string" + }, + "focus": { + "type": "string" + } + }, + "required": [ + "id", + "pan", + "tilt", + "roll", + "posX", + "posY", + "posZ", + "zoom", + "focus" + ] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "freed.decode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "freed.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "http.request.create" + }, + "params": { + "type": "object", + "properties": { + "method": { + "type": "string", + "enum": ["GET", "POST"] + }, + "url": { + "type": "string" + } + }, + "required": ["method", "url"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "http.request.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "http.request.filter" + }, + "params": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "method": { + "type": "string", + "enum": ["GET", "POST"] + } + }, + "required": ["path"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "http.response.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "int.parse" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "midi.message.create" + }, + "params": { + "type": "object", + "oneOf": [ + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["NoteOn", "noteon", "note_on"] + }, + "channel": { + "type": "string" + }, + "note": { + "type": "string" + }, + "velocity": { + "type": "string" + } + }, + "required": ["type", "channel", "note", "velocity"] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["NoteOff", "noteoff", "note_off"] + }, + "channel": { + "type": "string" + }, + "note": { + "type": "string" + }, + "velocity": { + "type": "string" + } + }, + "required": ["type", "channel", "note", "velocity"] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ControlChange", "controlchange", "control_change"] + }, + "channel": { + "type": "string" + }, + "controller": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["type", "channel", "controller", "value"] + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["ProgramChange", "programchange", "program_change"] + }, + "channel": { + "type": "string" + }, + "program": { + "type": "string" + } + }, + "required": ["type", "channel", "program"] + } + ] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "midi.message.decode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "midi.message.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "midi.message.filter" + }, + "params": { + "type": "object", + "properties": { + "type": { + "type": "string", + "enum": ["NoteOn", "NoteOff", "ControlChange", "ProgramChange"] + } + }, + "required": ["type"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "midi.message.unpack" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "mqtt.message.create" + }, + "params": { + "type": "object", + "properties": { + "topic": { + "type": "string" + }, + "qos": { + "type": "number" + }, + "retained": { + "type": "boolean" + }, + "payload": { + "type": "string" + } + }, + "required": ["topic", "qos", "retained", "payload"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "mqtt.message.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "nats.message.create" + }, + "params": { + "type": "object", + "properties": { + "subject": { + "type": "string" + }, + "payload": { + "type": "string" + } + }, + "required": ["subject", "payload"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "nats.message.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "osc.message.create" + }, + "params": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "args": { + "type": "array", + "items": { + "type": "string" + } + }, + "types": { + "type": "string" + } + }, + "required": ["address"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "osc.message.decode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "osc.message.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "osc.message.filter" + }, + "params": { + "type": "object", + "properties": { + "address": { + "type": "string" + } + }, + "required": ["address"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "osc.message.transform" + }, + "params": { + "type": "object", + "properties": { + "address": { + "type": "string" + } + }, + "required": ["address"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "script.expr" + }, + "params": { + "type": "object", + "properties": { + "expression": { + "type": "string" + } + }, + "required": ["expression"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "script.js" + }, + "params": { + "type": "object", + "properties": { + "program": { + "type": "string" + } + }, + "required": ["program"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string.create" + }, + "params": { + "type": "object", + "properties": { + "template": { + "type": "string" + } + }, + "required": ["template"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string.decode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string.encode" + } + }, + "required": ["type"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string.create" + }, + "params": { + "type": "object", + "properties": { + "pattern": { + "type": "string" + } + }, + "required": ["pattern"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "string.split" + }, + "params": { + "type": "object", + "properties": { + "separator": { + "type": "string" + } + }, + "required": ["separator"] + } + }, + "required": ["type", "params"], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "type": { + "type": "string", + "const": "uint.parse" + } + }, + "required": ["type"], + "additionalProperties": false + } + ] + } +} diff --git a/schema/routes.schema.json b/schema/routes.schema.json new file mode 100644 index 0000000..0485927 --- /dev/null +++ b/schema/routes.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://showbridge.io/routes.schema.json", + "title": "Routes", + "description": "showbridge routes array", + "type": "array", + "items": { + "type": "object", + "properties": { + "input": { + "type": "string" + }, + "processors": { + "$ref": "https://showbridge.io/processors.schema.json" + }, + "output": { + "type": "string" + } + }, + "required": ["input", "output"] + } +}