diff --git a/schema/README.md b/schema/README.md index 25e2b8d..c40c61a 100644 --- a/schema/README.md +++ b/schema/README.md @@ -2,7 +2,8 @@ JSON Schema (draft 2020-12) definitions for the IRC-style message protocol. -All messages share a common envelope defined in [`message.schema.json`](message.schema.json). +All messages share a common envelope defined in +[`message.schema.json`](message.schema.json). ## Base Envelope @@ -30,7 +31,7 @@ All messages share a common envelope defined in [`message.schema.json`](message. | MODE | [`c2s/mode.schema.json`](c2s/mode.schema.json) | Set/query modes | | TOPIC | [`c2s/topic.schema.json`](c2s/topic.schema.json) | Set/query topic | | KICK | [`c2s/kick.schema.json`](c2s/kick.schema.json) | Kick user | -| PING | [`c2s/ping.schema.json`](c2s/ping.schema.json) | Client ping | +| PING | [`c2s/ping.schema.json`](c2s/ping.schema.json) | Client keepalive | | PUBKEY | [`c2s/pubkey.schema.json`](c2s/pubkey.schema.json) | Announce public key | ## Server-to-Client (S2C) diff --git a/schema/c2s/join.json b/schema/c2s/join.json deleted file mode 100644 index a1b569c..0000000 --- a/schema/c2s/join.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/join.json", - "title": "C2S Join", - "description": "Join a channel. Submitted via POST /api/v1/channels/join.", - "type": "object", - "properties": { - "channel": { - "type": "string", - "description": "Channel name (# prefix optional, server will add it).", - "pattern": "^#?[a-zA-Z0-9_-]+$", - "examples": ["#general", "dev"] - } - }, - "required": ["channel"], - "additionalProperties": false -} diff --git a/schema/c2s/join.schema.json b/schema/c2s/join.schema.json new file mode 100644 index 0000000..aab9a7c --- /dev/null +++ b/schema/c2s/join.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/join.schema.json", + "title": "JOIN (C2S)", + "description": "Join a channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "JOIN" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Not used" + } + }, + "required": [ + "command", + "to" + ] +} diff --git a/schema/c2s/kick.schema.json b/schema/c2s/kick.schema.json new file mode 100644 index 0000000..7042bd6 --- /dev/null +++ b/schema/c2s/kick.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/kick.schema.json", + "title": "KICK (C2S)", + "description": "Kick user from channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "KICK" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Kick reason" + } + }, + "required": [ + "command", + "to" + ] +} diff --git a/schema/c2s/mode.json b/schema/c2s/mode.json deleted file mode 100644 index 402d0a5..0000000 --- a/schema/c2s/mode.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/mode.json", - "title": "C2S Mode", - "description": "Set channel or user mode flags.", - "type": "object", - "properties": { - "channel": { - "type": "string", - "description": "Target channel.", - "pattern": "^#[a-zA-Z0-9_-]+$" - }, - "mode": { - "type": "string", - "description": "Mode string (e.g. +o, -m, +v).", - "pattern": "^[+-][a-zA-Z]+$", - "examples": ["+o", "-m", "+v", "+i"] - }, - "target": { - "type": "string", - "description": "Target nick for user modes (e.g. +o alice). Omit for channel modes." - } - }, - "required": ["channel", "mode"], - "additionalProperties": false -} diff --git a/schema/c2s/mode.schema.json b/schema/c2s/mode.schema.json new file mode 100644 index 0000000..3f8cc8a --- /dev/null +++ b/schema/c2s/mode.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/mode.schema.json", + "title": "MODE (C2S)", + "description": "Set/query modes", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "MODE" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Mode params" + } + }, + "required": [ + "command", + "to" + ] +} diff --git a/schema/c2s/nick.json b/schema/c2s/nick.json deleted file mode 100644 index 7eda376..0000000 --- a/schema/c2s/nick.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/nick.json", - "title": "C2S Nick", - "description": "Change the user's nickname.", - "type": "object", - "properties": { - "nick": { - "type": "string", - "description": "Desired new nickname.", - "minLength": 1, - "maxLength": 32, - "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$" - } - }, - "required": ["nick"], - "additionalProperties": false -} diff --git a/schema/c2s/nick.schema.json b/schema/c2s/nick.schema.json new file mode 100644 index 0000000..0341173 --- /dev/null +++ b/schema/c2s/nick.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/nick.schema.json", + "title": "NICK (C2S)", + "description": "Request nick change", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "NICK" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Not used" + } + }, + "required": [ + "command", + "to" + ] +} diff --git a/schema/c2s/notice.schema.json b/schema/c2s/notice.schema.json new file mode 100644 index 0000000..89cb838 --- /dev/null +++ b/schema/c2s/notice.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/notice.schema.json", + "title": "NOTICE (C2S)", + "description": "Send a notice (no auto-reply expected)", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "NOTICE" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Text lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/c2s/part.json b/schema/c2s/part.json deleted file mode 100644 index 20e0a2f..0000000 --- a/schema/c2s/part.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/part.json", - "title": "C2S Part", - "description": "Leave a channel. Submitted via DELETE /api/v1/channels/{name}.", - "type": "object", - "properties": { - "channel": { - "type": "string", - "description": "Channel name to leave.", - "pattern": "^#[a-zA-Z0-9_-]+$", - "examples": ["#general"] - }, - "reason": { - "type": "string", - "description": "Optional part reason message.", - "maxLength": 256 - } - }, - "required": ["channel"], - "additionalProperties": false -} diff --git a/schema/c2s/part.schema.json b/schema/c2s/part.schema.json new file mode 100644 index 0000000..c572558 --- /dev/null +++ b/schema/c2s/part.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/part.schema.json", + "title": "PART (C2S)", + "description": "Leave a channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PART" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Part message" + } + }, + "required": [ + "command", + "to" + ] +} diff --git a/schema/c2s/ping.json b/schema/c2s/ping.json deleted file mode 100644 index e604ad5..0000000 --- a/schema/c2s/ping.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/ping.json", - "title": "C2S Ping", - "description": "Client keepalive. Server responds with a pong.", - "type": "object", - "properties": { - "token": { - "type": "string", - "description": "Optional opaque token echoed back in the pong response." - } - }, - "additionalProperties": false -} diff --git a/schema/c2s/ping.schema.json b/schema/c2s/ping.schema.json new file mode 100644 index 0000000..6f6b5fe --- /dev/null +++ b/schema/c2s/ping.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/ping.schema.json", + "title": "PING (C2S)", + "description": "Client keepalive", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PING" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Ping token" + } + }, + "required": [ + "command" + ] +} diff --git a/schema/c2s/privmsg.schema.json b/schema/c2s/privmsg.schema.json new file mode 100644 index 0000000..a8032b4 --- /dev/null +++ b/schema/c2s/privmsg.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/privmsg.schema.json", + "title": "PRIVMSG (C2S)", + "description": "Send message to channel or user", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PRIVMSG" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Text lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/c2s/pubkey.schema.json b/schema/c2s/pubkey.schema.json new file mode 100644 index 0000000..47093f5 --- /dev/null +++ b/schema/c2s/pubkey.schema.json @@ -0,0 +1,33 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/pubkey.schema.json", + "title": "PUBKEY (C2S)", + "description": "Announce public signing key", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PUBKEY" + }, + "body": { + "type": "object", + "required": [ + "alg", + "key" + ], + "properties": { + "alg": { + "type": "string", + "description": "Key algorithm (e.g. ed25519)" + }, + "key": { + "type": "string", + "description": "Base64-encoded public key" + } + } + } + }, + "required": [ + "command", + "body" + ] +} diff --git a/schema/c2s/quit.schema.json b/schema/c2s/quit.schema.json new file mode 100644 index 0000000..9fd70e4 --- /dev/null +++ b/schema/c2s/quit.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/quit.schema.json", + "title": "QUIT (C2S)", + "description": "Disconnect from server", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "QUIT" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Quit message" + } + }, + "required": [ + "command" + ] +} diff --git a/schema/c2s/send.json b/schema/c2s/send.json deleted file mode 100644 index 033717f..0000000 --- a/schema/c2s/send.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/send.json", - "title": "C2S Send", - "description": "Send a message to a channel or user. Submitted via POST /api/v1/messages.", - "type": "object", - "properties": { - "to": { - "type": "string", - "description": "Target: channel name (prefixed with #) or nick for DM.", - "examples": ["#general", "alice"] - }, - "content": { - "type": "string", - "description": "Message body (UTF-8 text).", - "minLength": 1, - "maxLength": 4096 - } - }, - "required": ["to", "content"], - "additionalProperties": false -} diff --git a/schema/c2s/topic.json b/schema/c2s/topic.json deleted file mode 100644 index b6c30a0..0000000 --- a/schema/c2s/topic.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/topic.json", - "title": "C2S Topic", - "description": "Set a channel's topic.", - "type": "object", - "properties": { - "channel": { - "type": "string", - "description": "Target channel.", - "pattern": "^#[a-zA-Z0-9_-]+$" - }, - "topic": { - "type": "string", - "description": "New topic text. Empty string clears the topic.", - "maxLength": 512 - } - }, - "required": ["channel", "topic"], - "additionalProperties": false -} diff --git a/schema/c2s/topic.schema.json b/schema/c2s/topic.schema.json new file mode 100644 index 0000000..5df67cd --- /dev/null +++ b/schema/c2s/topic.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/c2s/topic.schema.json", + "title": "TOPIC (C2S)", + "description": "Set/query topic", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "TOPIC" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Topic lines" + } + }, + "required": [ + "command", + "to" + ] +} diff --git a/schema/commands/JOIN.json b/schema/commands/JOIN.json new file mode 100644 index 0000000..23e9c63 --- /dev/null +++ b/schema/commands/JOIN.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/commands/JOIN.json", + "title": "JOIN", + "description": "Join a channel. C2S: request to join. S2C: notification that a user joined. RFC 1459 §4.2.1.", + "$ref": "../message.json", + "properties": { + "command": { "const": "JOIN" }, + "from": { + "type": "string", + "description": "Nick that joined (S2C only)." + }, + "to": { + "type": "string", + "description": "Channel name.", + "pattern": "^#[a-zA-Z0-9_-]+$" + } + }, + "required": ["command", "to"], + "examples": [ + { "command": "JOIN", "from": "alice", "to": "#general" } + ] +} diff --git a/schema/commands/NOTICE.json b/schema/commands/NOTICE.json new file mode 100644 index 0000000..0f5e873 --- /dev/null +++ b/schema/commands/NOTICE.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/commands/NOTICE.json", + "title": "NOTICE", + "description": "Send a notice. Like PRIVMSG but must not trigger automatic replies. RFC 1459 §4.4.2.", + "$ref": "../message.json", + "properties": { + "command": { "const": "NOTICE" }, + "from": { "type": "string" }, + "to": { + "type": "string", + "description": "Target: #channel, nick, or * (global)." + }, + "body": { + "type": "string", + "description": "Notice text." + } + }, + "required": ["command", "to", "body"], + "examples": [ + { "command": "NOTICE", "from": "server.example.com", "to": "*", "body": "Server restarting in 5 minutes" } + ] +} diff --git a/schema/commands/PART.json b/schema/commands/PART.json new file mode 100644 index 0000000..f71a02a --- /dev/null +++ b/schema/commands/PART.json @@ -0,0 +1,27 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/commands/PART.json", + "title": "PART", + "description": "Leave a channel. C2S: request to leave. S2C: notification that a user left. RFC 1459 §4.2.2.", + "$ref": "../message.json", + "properties": { + "command": { "const": "PART" }, + "from": { + "type": "string", + "description": "Nick that left (S2C only)." + }, + "to": { + "type": "string", + "description": "Channel name.", + "pattern": "^#[a-zA-Z0-9_-]+$" + }, + "body": { + "type": "string", + "description": "Optional part reason." + } + }, + "required": ["command", "to"], + "examples": [ + { "command": "PART", "from": "alice", "to": "#general", "body": "later" } + ] +} diff --git a/schema/commands/PRIVMSG.json b/schema/commands/PRIVMSG.json new file mode 100644 index 0000000..ea56928 --- /dev/null +++ b/schema/commands/PRIVMSG.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/commands/PRIVMSG.json", + "title": "PRIVMSG", + "description": "Send a message to a channel or user. C2S: client sends to server. S2C: server relays to recipients. RFC 1459 §4.4.1.", + "$ref": "../message.json", + "properties": { + "command": { "const": "PRIVMSG" }, + "from": { + "type": "string", + "description": "Sender nick (set by server on S2C relay)." + }, + "to": { + "type": "string", + "description": "Target: #channel or nick.", + "examples": ["#general", "alice"] + }, + "body": { + "type": "string", + "description": "Message text.", + "minLength": 1 + } + }, + "required": ["command", "to", "body"], + "examples": [ + { "command": "PRIVMSG", "from": "bob", "to": "#general", "body": "hello world" }, + { "command": "PRIVMSG", "from": "bob", "to": "alice", "body": "hey" } + ] +} diff --git a/schema/message.json b/schema/message.json new file mode 100644 index 0000000..286d0ea --- /dev/null +++ b/schema/message.json @@ -0,0 +1,46 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/message.json", + "title": "IRC Message Envelope", + "description": "Base envelope for all messages. Mirrors IRC wire format (RFC 1459/2812) encoded as JSON over HTTP. The 'command' field carries either an IRC command name (PRIVMSG, JOIN, etc.) or a three-digit numeric reply code (001, 353, 433, etc.).", + "type": "object", + "properties": { + "id": { + "type": "integer", + "description": "Server-assigned message ID, monotonically increasing. Present on all server-originated messages." + }, + "command": { + "type": "string", + "description": "IRC command name (PRIVMSG, JOIN, NICK, etc.) or three-digit numeric reply code (001, 353, 433, etc.).", + "examples": ["PRIVMSG", "JOIN", "001", "353", "433"] + }, + "from": { + "type": "string", + "description": "Source — nick for user messages, server name for server messages. Equivalent to IRC prefix." + }, + "to": { + "type": "string", + "description": "Target — channel (#name) or nick. Equivalent to first IRC parameter for most commands." + }, + "params": { + "type": "array", + "items": { "type": "string" }, + "description": "Additional parameters (used primarily by numeric replies). Equivalent to IRC middle parameters." + }, + "body": { + "type": "string", + "description": "Message body / trailing parameter. Equivalent to IRC trailing parameter (after the colon)." + }, + "ts": { + "type": "string", + "format": "date-time", + "description": "Server-assigned timestamp (ISO 8601). Not present in original IRC; added for HTTP transport." + }, + "meta": { + "type": "object", + "description": "Extensible metadata (signatures, rich content hints, etc.). Not present in original IRC.", + "additionalProperties": true + } + }, + "required": ["command"] +} diff --git a/schema/message.schema.json b/schema/message.schema.json new file mode 100644 index 0000000..40d2dae --- /dev/null +++ b/schema/message.schema.json @@ -0,0 +1,67 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/message.schema.json", + "title": "Chat Message Envelope", + "description": "Base message envelope. Bodies MUST be objects or arrays (never raw strings) for deterministic canonicalization (RFC 8785 JCS) and signing.", + "type": "object", + "required": [ + "command" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid", + "description": "Server-assigned UUID" + }, + "ts": { + "type": "string", + "format": "date-time", + "description": "Server-assigned timestamp (ISO 8601)" + }, + "command": { + "type": "string", + "description": "IRC command name or numeric reply code" + }, + "from": { + "type": "string", + "description": "Sender nick or server name" + }, + "to": { + "type": "string", + "description": "Destination: channel (#foo) or nick" + }, + "params": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Additional IRC-style parameters" + }, + "body": { + "oneOf": [ + { + "type": "array" + }, + { + "type": "object" + } + ], + "description": "Message body (array or object, never raw string)" + }, + "meta": { + "type": "object", + "description": "Extensible metadata", + "properties": { + "sig": { + "type": "string", + "description": "Cryptographic signature (base64)" + }, + "alg": { + "type": "string", + "description": "Signature algorithm (e.g. ed25519)" + } + } + } + }, + "additionalProperties": false +} diff --git a/schema/s2c/001.schema.json b/schema/s2c/001.schema.json new file mode 100644 index 0000000..5786bdd --- /dev/null +++ b/schema/s2c/001.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/001.schema.json", + "title": "001 RPL_WELCOME (S2C)", + "description": "Welcome message after registration", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "001" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/002.schema.json b/schema/s2c/002.schema.json new file mode 100644 index 0000000..ef8571f --- /dev/null +++ b/schema/s2c/002.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/002.schema.json", + "title": "002 RPL_YOURHOST (S2C)", + "description": "Server host information", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "002" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/322.schema.json b/schema/s2c/322.schema.json new file mode 100644 index 0000000..f704405 --- /dev/null +++ b/schema/s2c/322.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/322.schema.json", + "title": "322 RPL_LIST (S2C)", + "description": "Channel list entry", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "322" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/353.schema.json b/schema/s2c/353.schema.json new file mode 100644 index 0000000..d28371f --- /dev/null +++ b/schema/s2c/353.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/353.schema.json", + "title": "353 RPL_NAMREPLY (S2C)", + "description": "Names list for a channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "353" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/366.schema.json b/schema/s2c/366.schema.json new file mode 100644 index 0000000..522a411 --- /dev/null +++ b/schema/s2c/366.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/366.schema.json", + "title": "366 RPL_ENDOFNAMES (S2C)", + "description": "End of names list", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "366" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/372.schema.json b/schema/s2c/372.schema.json new file mode 100644 index 0000000..d4469cd --- /dev/null +++ b/schema/s2c/372.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/372.schema.json", + "title": "372 RPL_MOTD (S2C)", + "description": "Message of the day line", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "372" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/375.schema.json b/schema/s2c/375.schema.json new file mode 100644 index 0000000..bfa7d88 --- /dev/null +++ b/schema/s2c/375.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/375.schema.json", + "title": "375 RPL_MOTDSTART (S2C)", + "description": "Start of MOTD", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "375" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/376.schema.json b/schema/s2c/376.schema.json new file mode 100644 index 0000000..f5d34bb --- /dev/null +++ b/schema/s2c/376.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/376.schema.json", + "title": "376 RPL_ENDOFMOTD (S2C)", + "description": "End of MOTD", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "376" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/401.schema.json b/schema/s2c/401.schema.json new file mode 100644 index 0000000..1278cba --- /dev/null +++ b/schema/s2c/401.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/401.schema.json", + "title": "401 ERR_NOSUCHNICK (S2C)", + "description": "No such nick or channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "401" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/403.schema.json b/schema/s2c/403.schema.json new file mode 100644 index 0000000..2e0870d --- /dev/null +++ b/schema/s2c/403.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/403.schema.json", + "title": "403 ERR_NOSUCHCHANNEL (S2C)", + "description": "No such channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "403" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/433.schema.json b/schema/s2c/433.schema.json new file mode 100644 index 0000000..cef8c52 --- /dev/null +++ b/schema/s2c/433.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/433.schema.json", + "title": "433 ERR_NICKNAMEINUSE (S2C)", + "description": "Nickname already in use", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "433" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Response lines" + } + }, + "required": [ + "command", + "to", + "body" + ] +} diff --git a/schema/s2c/dm.json b/schema/s2c/dm.json deleted file mode 100644 index a47db8d..0000000 --- a/schema/s2c/dm.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/dm.json", - "title": "S2C Direct Message", - "description": "A direct message delivered via the unified message stream.", - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Server-assigned message ID." - }, - "type": { - "const": "dm" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "from": { - "type": "string", - "description": "Sender nick." - }, - "to": { - "type": "string", - "description": "Recipient nick." - }, - "content": { - "type": "string", - "description": "Message body." - }, - "meta": { - "type": "object", - "additionalProperties": true - } - }, - "required": ["id", "type", "ts", "from", "to", "content"] -} diff --git a/schema/s2c/error.json b/schema/s2c/error.json deleted file mode 100644 index 3eda1d4..0000000 --- a/schema/s2c/error.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/error.json", - "title": "S2C Error", - "description": "Error message delivered via the message stream.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "error" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "code": { - "type": "string", - "description": "Machine-readable error code.", - "examples": ["nick_in_use", "no_such_channel", "not_on_channel", "permission_denied"] - }, - "content": { - "type": "string", - "description": "Human-readable error message." - }, - "channel": { - "type": "string", - "description": "Related channel, if applicable." - } - }, - "required": ["id", "type", "ts", "code", "content"] -} diff --git a/schema/s2c/error.schema.json b/schema/s2c/error.schema.json new file mode 100644 index 0000000..fd4a92d --- /dev/null +++ b/schema/s2c/error.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/error.schema.json", + "title": "ERROR (S2C)", + "description": "Server error", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "ERROR" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Error lines" + } + }, + "required": [ + "command", + "body" + ] +} diff --git a/schema/s2c/join.json b/schema/s2c/join.json deleted file mode 100644 index aa59bc4..0000000 --- a/schema/s2c/join.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/join.json", - "title": "S2C Join", - "description": "A user joined a channel.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "join" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "nick": { - "type": "string", - "description": "The nick that joined." - }, - "channel": { - "type": "string", - "description": "The channel joined.", - "pattern": "^#[a-zA-Z0-9_-]+$" - } - }, - "required": ["id", "type", "ts", "nick", "channel"] -} diff --git a/schema/s2c/join.schema.json b/schema/s2c/join.schema.json new file mode 100644 index 0000000..10a0ff9 --- /dev/null +++ b/schema/s2c/join.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/join.schema.json", + "title": "JOIN (S2C)", + "description": "User joined a channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "JOIN" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Not used" + } + }, + "required": [ + "command", + "from", + "to" + ] +} diff --git a/schema/s2c/kick.schema.json b/schema/s2c/kick.schema.json new file mode 100644 index 0000000..b4503a6 --- /dev/null +++ b/schema/s2c/kick.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/kick.schema.json", + "title": "KICK (S2C)", + "description": "User kicked from channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "KICK" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Kick reason" + } + }, + "required": [ + "command", + "from", + "to" + ] +} diff --git a/schema/s2c/message.json b/schema/s2c/message.json deleted file mode 100644 index 8cd4d3b..0000000 --- a/schema/s2c/message.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/message.json", - "title": "S2C Message", - "description": "A channel message delivered via the unified message stream.", - "type": "object", - "properties": { - "id": { - "type": "integer", - "description": "Server-assigned message ID, monotonically increasing." - }, - "type": { - "const": "message" - }, - "ts": { - "type": "string", - "format": "date-time", - "description": "Server-assigned timestamp (ISO 8601)." - }, - "from": { - "type": "string", - "description": "Sender nick." - }, - "channel": { - "type": "string", - "description": "Channel the message was sent to.", - "pattern": "^#[a-zA-Z0-9_-]+$" - }, - "content": { - "type": "string", - "description": "Message body." - }, - "meta": { - "type": "object", - "description": "Extensible metadata (signatures, rich content, etc.).", - "additionalProperties": true - } - }, - "required": ["id", "type", "ts", "from", "channel", "content"] -} diff --git a/schema/s2c/mode.json b/schema/s2c/mode.json deleted file mode 100644 index c2d5043..0000000 --- a/schema/s2c/mode.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/mode.json", - "title": "S2C Mode", - "description": "A channel or user mode was changed.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "mode" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "nick": { - "type": "string", - "description": "The nick that set the mode." - }, - "channel": { - "type": "string", - "pattern": "^#[a-zA-Z0-9_-]+$" - }, - "mode": { - "type": "string", - "description": "Mode string applied (e.g. +o, -m).", - "pattern": "^[+-][a-zA-Z]+$" - }, - "target": { - "type": "string", - "description": "Target nick for user modes. Absent for channel modes." - } - }, - "required": ["id", "type", "ts", "nick", "channel", "mode"] -} diff --git a/schema/s2c/mode.schema.json b/schema/s2c/mode.schema.json new file mode 100644 index 0000000..be04679 --- /dev/null +++ b/schema/s2c/mode.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/mode.schema.json", + "title": "MODE (S2C)", + "description": "Mode change notification", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "MODE" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Mode params" + } + }, + "required": [ + "command", + "from", + "to" + ] +} diff --git a/schema/s2c/nick.json b/schema/s2c/nick.json deleted file mode 100644 index 32e1940..0000000 --- a/schema/s2c/nick.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/nick.json", - "title": "S2C Nick", - "description": "A user changed their nickname.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "nick" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "oldNick": { - "type": "string", - "description": "Previous nickname." - }, - "newNick": { - "type": "string", - "description": "New nickname." - } - }, - "required": ["id", "type", "ts", "oldNick", "newNick"] -} diff --git a/schema/s2c/nick.schema.json b/schema/s2c/nick.schema.json new file mode 100644 index 0000000..8b0cce0 --- /dev/null +++ b/schema/s2c/nick.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/nick.schema.json", + "title": "NICK (S2C)", + "description": "User changed nick", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "NICK" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Not used" + } + }, + "required": [ + "command", + "from", + "to" + ] +} diff --git a/schema/s2c/notice.json b/schema/s2c/notice.json deleted file mode 100644 index b9bf1e3..0000000 --- a/schema/s2c/notice.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/notice.json", - "title": "S2C Notice", - "description": "A server notice. May be targeted to a channel or user, or global.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "notice" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "from": { - "type": "string", - "description": "Origin (server name or nick)." - }, - "channel": { - "type": "string", - "description": "Target channel, if channel-scoped." - }, - "content": { - "type": "string", - "description": "Notice text." - } - }, - "required": ["id", "type", "ts", "content"] -} diff --git a/schema/s2c/notice.schema.json b/schema/s2c/notice.schema.json new file mode 100644 index 0000000..738719a --- /dev/null +++ b/schema/s2c/notice.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/notice.schema.json", + "title": "NOTICE (S2C)", + "description": "Server or user notice", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "NOTICE" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Text lines" + } + }, + "required": [ + "command", + "body" + ] +} diff --git a/schema/s2c/part.json b/schema/s2c/part.json deleted file mode 100644 index 69930fe..0000000 --- a/schema/s2c/part.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/part.json", - "title": "S2C Part", - "description": "A user left a channel.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "part" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "nick": { - "type": "string", - "description": "The nick that left." - }, - "channel": { - "type": "string", - "pattern": "^#[a-zA-Z0-9_-]+$" - }, - "reason": { - "type": "string", - "description": "Optional part reason." - } - }, - "required": ["id", "type", "ts", "nick", "channel"] -} diff --git a/schema/s2c/part.schema.json b/schema/s2c/part.schema.json new file mode 100644 index 0000000..9c05a99 --- /dev/null +++ b/schema/s2c/part.schema.json @@ -0,0 +1,24 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/part.schema.json", + "title": "PART (S2C)", + "description": "User left a channel", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PART" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Part message" + } + }, + "required": [ + "command", + "from", + "to" + ] +} diff --git a/schema/s2c/pong.json b/schema/s2c/pong.json deleted file mode 100644 index 57ff903..0000000 --- a/schema/s2c/pong.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/pong.json", - "title": "S2C Pong", - "description": "Keepalive response to a client ping.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "pong" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "token": { - "type": "string", - "description": "Echoed token from the client's ping, if provided." - } - }, - "required": ["id", "type", "ts"] -} diff --git a/schema/s2c/pong.schema.json b/schema/s2c/pong.schema.json new file mode 100644 index 0000000..a184887 --- /dev/null +++ b/schema/s2c/pong.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/pong.schema.json", + "title": "PONG (S2C)", + "description": "Server keepalive response", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PONG" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Pong token" + } + }, + "required": [ + "command" + ] +} diff --git a/schema/s2c/privmsg.schema.json b/schema/s2c/privmsg.schema.json new file mode 100644 index 0000000..3e397d6 --- /dev/null +++ b/schema/s2c/privmsg.schema.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/privmsg.schema.json", + "title": "PRIVMSG (S2C)", + "description": "Relayed message from a user", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PRIVMSG" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Text lines" + } + }, + "required": [ + "command", + "from", + "to", + "body" + ] +} diff --git a/schema/s2c/pubkey.schema.json b/schema/s2c/pubkey.schema.json new file mode 100644 index 0000000..f720b0c --- /dev/null +++ b/schema/s2c/pubkey.schema.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/pubkey.schema.json", + "title": "PUBKEY (S2C)", + "description": "Relayed public key announcement", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PUBKEY" + }, + "body": { + "type": "object", + "required": [ + "alg", + "key" + ], + "properties": { + "alg": { + "type": "string", + "description": "Key algorithm (e.g. ed25519)" + }, + "key": { + "type": "string", + "description": "Base64-encoded public key" + } + } + } + }, + "required": [ + "command", + "from", + "body" + ] +} diff --git a/schema/s2c/quit.json b/schema/s2c/quit.json deleted file mode 100644 index e01d61b..0000000 --- a/schema/s2c/quit.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/quit.json", - "title": "S2C Quit", - "description": "A user disconnected from the server.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "quit" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "nick": { - "type": "string", - "description": "The nick that quit." - }, - "reason": { - "type": "string", - "description": "Optional quit reason." - } - }, - "required": ["id", "type", "ts", "nick"] -} diff --git a/schema/s2c/quit.schema.json b/schema/s2c/quit.schema.json new file mode 100644 index 0000000..edb2395 --- /dev/null +++ b/schema/s2c/quit.schema.json @@ -0,0 +1,23 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/quit.schema.json", + "title": "QUIT (S2C)", + "description": "User disconnected", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "QUIT" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Quit message" + } + }, + "required": [ + "command", + "from" + ] +} diff --git a/schema/s2c/system.json b/schema/s2c/system.json deleted file mode 100644 index b841d0a..0000000 --- a/schema/s2c/system.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/system.json", - "title": "S2C System", - "description": "Server system message (MOTD, maintenance notices, etc.).", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "system" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "content": { - "type": "string", - "description": "System message text." - }, - "code": { - "type": "string", - "description": "Optional machine-readable system message code.", - "examples": ["motd", "maintenance", "server_restart"] - } - }, - "required": ["id", "type", "ts", "content"] -} diff --git a/schema/s2c/topic.json b/schema/s2c/topic.json deleted file mode 100644 index a48d72d..0000000 --- a/schema/s2c/topic.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/topic.json", - "title": "S2C Topic", - "description": "A channel topic was changed.", - "type": "object", - "properties": { - "id": { - "type": "integer" - }, - "type": { - "const": "topic" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "nick": { - "type": "string", - "description": "The nick that changed the topic." - }, - "channel": { - "type": "string", - "pattern": "^#[a-zA-Z0-9_-]+$" - }, - "topic": { - "type": "string", - "description": "New topic text." - } - }, - "required": ["id", "type", "ts", "nick", "channel", "topic"] -} diff --git a/schema/s2c/topic.schema.json b/schema/s2c/topic.schema.json new file mode 100644 index 0000000..144b89c --- /dev/null +++ b/schema/s2c/topic.schema.json @@ -0,0 +1,25 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2c/topic.schema.json", + "title": "TOPIC (S2C)", + "description": "Topic change notification", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "TOPIC" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Topic lines" + } + }, + "required": [ + "command", + "from", + "to", + "body" + ] +} diff --git a/schema/s2s/link.json b/schema/s2s/link.json deleted file mode 100644 index f588f00..0000000 --- a/schema/s2s/link.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/link.json", - "title": "S2S Link", - "description": "Server link establishment request/response.", - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "const": "link" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "origin": { - "type": "string", - "description": "Requesting server name." - }, - "version": { - "type": "string", - "description": "Protocol version of the requesting server." - }, - "auth": { - "type": "string", - "description": "HMAC signature over the link request using the shared federation key." - }, - "capabilities": { - "type": "array", - "items": { - "type": "string" - }, - "description": "List of supported protocol capabilities.", - "examples": [["relay", "sync", "presence"]] - } - }, - "required": ["id", "type", "ts", "origin", "auth"] -} diff --git a/schema/s2s/link.schema.json b/schema/s2s/link.schema.json new file mode 100644 index 0000000..1e07586 --- /dev/null +++ b/schema/s2s/link.schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/link.schema.json", + "title": "LINK (S2S)", + "description": "Establish server link", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "LINK" + }, + "body": { + "type": "object", + "description": "Link parameters" + } + }, + "required": [ + "command", + "body" + ] +} diff --git a/schema/s2s/ping.json b/schema/s2s/ping.json deleted file mode 100644 index 1fb7e10..0000000 --- a/schema/s2s/ping.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/ping.json", - "title": "S2S Ping", - "description": "Inter-server keepalive.", - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "const": "ping" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "origin": { - "type": "string", - "description": "Pinging server." - }, - "token": { - "type": "string", - "description": "Opaque token to be echoed in pong." - } - }, - "required": ["id", "type", "ts", "origin"] -} diff --git a/schema/s2s/ping.schema.json b/schema/s2s/ping.schema.json new file mode 100644 index 0000000..14911ed --- /dev/null +++ b/schema/s2s/ping.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/ping.schema.json", + "title": "PING (S2S)", + "description": "Server-to-server keepalive", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PING" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Ping token" + } + }, + "required": [ + "command" + ] +} diff --git a/schema/s2s/pong.json b/schema/s2s/pong.json deleted file mode 100644 index 7b0d5ac..0000000 --- a/schema/s2s/pong.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/pong.json", - "title": "S2S Pong", - "description": "Inter-server keepalive response.", - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "const": "pong" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "origin": { - "type": "string", - "description": "Responding server." - }, - "token": { - "type": "string", - "description": "Echoed token from the ping." - } - }, - "required": ["id", "type", "ts", "origin"] -} diff --git a/schema/s2s/pong.schema.json b/schema/s2s/pong.schema.json new file mode 100644 index 0000000..ae8c628 --- /dev/null +++ b/schema/s2s/pong.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/pong.schema.json", + "title": "PONG (S2S)", + "description": "Server-to-server keepalive response", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "PONG" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Pong token" + } + }, + "required": [ + "command" + ] +} diff --git a/schema/s2s/relay.json b/schema/s2s/relay.json deleted file mode 100644 index 4f6cf09..0000000 --- a/schema/s2s/relay.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/relay.json", - "title": "S2S Relay", - "description": "A message relayed from a remote server in the federation.", - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid", - "description": "Message UUID, globally unique across the federation." - }, - "type": { - "const": "relay" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "origin": { - "type": "string", - "description": "Originating server name." - }, - "message": { - "type": "object", - "description": "The original S2C message being relayed. Preserves the original type, from, channel, content, etc.", - "properties": { - "type": { - "type": "string" - }, - "from": { - "type": "string" - }, - "channel": { - "type": "string" - }, - "content": { - "type": "string" - }, - "ts": { - "type": "string", - "format": "date-time" - } - }, - "required": ["type", "from"] - } - }, - "required": ["id", "type", "ts", "origin", "message"] -} diff --git a/schema/s2s/relay.schema.json b/schema/s2s/relay.schema.json new file mode 100644 index 0000000..aa6b833 --- /dev/null +++ b/schema/s2s/relay.schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/relay.schema.json", + "title": "RELAY (S2S)", + "description": "Relay message to linked server", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "RELAY" + }, + "body": { + "type": "object", + "description": "Wrapped message" + } + }, + "required": [ + "command", + "body" + ] +} diff --git a/schema/s2s/sync.json b/schema/s2s/sync.json deleted file mode 100644 index 03b9f4d..0000000 --- a/schema/s2s/sync.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/sync.json", - "title": "S2S Sync", - "description": "State synchronization between federated servers. Sent after link establishment to share channel and user state.", - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "const": "sync" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "origin": { - "type": "string", - "description": "Server sending the sync." - }, - "channels": { - "type": "array", - "description": "Channels on the origin server.", - "items": { - "type": "object", - "properties": { - "name": { - "type": "string", - "pattern": "^#[a-zA-Z0-9_-]+$" - }, - "topic": { - "type": "string" - }, - "modes": { - "type": "string" - }, - "members": { - "type": "array", - "items": { - "type": "string" - }, - "description": "List of nicks in the channel." - } - }, - "required": ["name"] - } - }, - "users": { - "type": "array", - "description": "Users on the origin server.", - "items": { - "type": "object", - "properties": { - "nick": { - "type": "string" - }, - "server": { - "type": "string", - "description": "Home server for this user." - } - }, - "required": ["nick"] - } - } - }, - "required": ["id", "type", "ts", "origin"] -} diff --git a/schema/s2s/sync.schema.json b/schema/s2s/sync.schema.json new file mode 100644 index 0000000..9218714 --- /dev/null +++ b/schema/s2s/sync.schema.json @@ -0,0 +1,20 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/sync.schema.json", + "title": "SYNC (S2S)", + "description": "Synchronize state between servers", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "SYNC" + }, + "body": { + "type": "object", + "description": "State data" + } + }, + "required": [ + "command", + "body" + ] +} diff --git a/schema/s2s/unlink.json b/schema/s2s/unlink.json deleted file mode 100644 index 32d669b..0000000 --- a/schema/s2s/unlink.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/unlink.json", - "title": "S2S Unlink", - "description": "Server link teardown notification.", - "type": "object", - "properties": { - "id": { - "type": "string", - "format": "uuid" - }, - "type": { - "const": "unlink" - }, - "ts": { - "type": "string", - "format": "date-time" - }, - "origin": { - "type": "string", - "description": "Server initiating the unlink." - }, - "reason": { - "type": "string", - "description": "Optional reason for the unlink.", - "examples": ["shutdown", "configuration change", "timeout"] - } - }, - "required": ["id", "type", "ts", "origin"] -} diff --git a/schema/s2s/unlink.schema.json b/schema/s2s/unlink.schema.json new file mode 100644 index 0000000..dc181d3 --- /dev/null +++ b/schema/s2s/unlink.schema.json @@ -0,0 +1,22 @@ +{ + "$schema": "https://json-schema.org/draft/2020-12/schema", + "$id": "https://git.eeqj.de/sneak/chat/schema/s2s/unlink.schema.json", + "title": "UNLINK (S2S)", + "description": "Tear down server link", + "$ref": "../message.schema.json", + "properties": { + "command": { + "const": "UNLINK" + }, + "body": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Unlink reason" + } + }, + "required": [ + "command" + ] +}