refactor: structured body (array|object, never string) for canonicalization
Message bodies are always arrays of strings (text lines) or objects (structured data like PUBKEY). Never raw strings. This enables: - Multiline messages without escape sequences - Deterministic JSON canonicalization (RFC 8785 JCS) for signing - Structured data where needed Update all schemas: body fields use array type with string items. Update message.json envelope: body is oneOf[array, object], id is UUID. Update README: message envelope table, examples, and canonicalization docs. Update schema/README.md: field types, examples with array bodies.
This commit is contained in:
@@ -11,24 +11,33 @@ to IRC wire format:
|
||||
|
||||
```
|
||||
IRC: :nick PRIVMSG #channel :hello world
|
||||
JSON: {"command": "PRIVMSG", "from": "nick", "to": "#channel", "body": "hello world"}
|
||||
JSON: {"command": "PRIVMSG", "from": "nick", "to": "#channel", "body": ["hello world"]}
|
||||
|
||||
IRC: :server 353 nick = #channel :user1 @op1 +voice1
|
||||
JSON: {"command": "353", "to": "nick", "params": ["=", "#channel"], "body": "user1 @op1 +voice1"}
|
||||
JSON: {"command": "353", "to": "nick", "params": ["=", "#channel"], "body": ["user1 @op1 +voice1"]}
|
||||
|
||||
Multiline: {"command": "PRIVMSG", "to": "#ch", "body": ["line 1", "line 2"]}
|
||||
Structured: {"command": "PUBKEY", "body": {"alg": "ed25519", "key": "base64..."}}
|
||||
```
|
||||
|
||||
Common fields (see `message.json` for full schema):
|
||||
|
||||
| Field | Type | Description |
|
||||
|-----------|----------|-------------------------------------------------------|
|
||||
| `id` | integer | Server-assigned ID (monotonically increasing) |
|
||||
| `command` | string | IRC command or 3-digit numeric code |
|
||||
| `from` | string | Source nick or server name (IRC prefix) |
|
||||
| `to` | string | Target: #channel or nick |
|
||||
| `params` | string[] | Middle parameters (mainly for numerics) |
|
||||
| `body` | string | Trailing parameter (message text) |
|
||||
| `ts` | string | ISO 8601 timestamp (server-assigned, not in raw IRC) |
|
||||
| `meta` | object | Extensible metadata (not in raw IRC) |
|
||||
| Field | Type | Description |
|
||||
|-----------|----------------|------------------------------------------------------|
|
||||
| `id` | string (uuid) | Server-assigned message UUID |
|
||||
| `command` | string | IRC command or 3-digit numeric code |
|
||||
| `from` | string | Source nick or server name (IRC prefix) |
|
||||
| `to` | string | Target: #channel or nick |
|
||||
| `params` | string[] | Middle parameters (mainly for numerics) |
|
||||
| `body` | array \| object | Structured body — never a raw string (see below) |
|
||||
| `ts` | string | ISO 8601 timestamp (server-assigned, not in raw IRC) |
|
||||
| `meta` | object | Extensible metadata (signatures, hashes, etc.) |
|
||||
|
||||
**Structured bodies:** `body` is always an array of strings (for text) or an
|
||||
object (for structured data like PUBKEY). Never a raw string. This enables:
|
||||
- Multiline messages without escape sequences
|
||||
- Deterministic canonicalization via RFC 8785 JCS for signing
|
||||
- Structured data where needed
|
||||
|
||||
## Commands
|
||||
|
||||
|
||||
@@ -6,15 +6,8 @@
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "KICK" },
|
||||
"from": {
|
||||
"type": "string",
|
||||
"description": "Nick that performed the kick."
|
||||
},
|
||||
"to": {
|
||||
"type": "string",
|
||||
"description": "Channel name.",
|
||||
"pattern": "^#[a-zA-Z0-9_-]+$"
|
||||
},
|
||||
"from": { "type": "string", "description": "Nick that performed the kick." },
|
||||
"to": { "type": "string", "description": "Channel name.", "pattern": "^#[a-zA-Z0-9_-]+$" },
|
||||
"params": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
@@ -23,12 +16,14 @@
|
||||
"maxItems": 1
|
||||
},
|
||||
"body": {
|
||||
"type": "string",
|
||||
"description": "Optional kick reason."
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Optional kick reason.",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "params"],
|
||||
"examples": [
|
||||
{ "command": "KICK", "from": "op1", "to": "#general", "params": ["troll"], "body": "Behave" }
|
||||
{ "command": "KICK", "from": "op1", "to": "#general", "params": ["troll"], "body": ["Behave"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,10 +7,16 @@
|
||||
"properties": {
|
||||
"command": { "const": "NICK" },
|
||||
"from": { "type": "string", "description": "Old nick (S2C)." },
|
||||
"body": { "type": "string", "description": "New nick.", "minLength": 1, "maxLength": 32, "pattern": "^[a-zA-Z][a-zA-Z0-9_-]*$" }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "New nick (single-element array).",
|
||||
"minItems": 1,
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "body"],
|
||||
"examples": [
|
||||
{ "command": "NICK", "from": "oldnick", "body": "newnick" }
|
||||
{ "command": "NICK", "from": "oldnick", "body": ["newnick"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,10 +8,14 @@
|
||||
"command": { "const": "NOTICE" },
|
||||
"from": { "type": "string" },
|
||||
"to": { "type": "string", "description": "Target: #channel, nick, or * (global)." },
|
||||
"body": { "type": "string", "description": "Notice text." }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Notice text lines."
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "body"],
|
||||
"examples": [
|
||||
{ "command": "NOTICE", "from": "server.example.com", "to": "*", "body": "Server restarting in 5 minutes" }
|
||||
{ "command": "NOTICE", "from": "server.example.com", "to": "*", "body": ["Server restarting in 5 minutes"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,10 +8,15 @@
|
||||
"command": { "const": "PART" },
|
||||
"from": { "type": "string", "description": "Nick that left (S2C)." },
|
||||
"to": { "type": "string", "description": "Channel name.", "pattern": "^#[a-zA-Z0-9_-]+$" },
|
||||
"body": { "type": "string", "description": "Optional part reason." }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Optional part reason.",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to"],
|
||||
"examples": [
|
||||
{ "command": "PART", "from": "alice", "to": "#general", "body": "later" }
|
||||
{ "command": "PART", "from": "alice", "to": "#general", "body": ["later"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
"properties": {
|
||||
"command": { "const": "PING" },
|
||||
"body": {
|
||||
"type": "string",
|
||||
"description": "Opaque token to be echoed in PONG."
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Opaque token to be echoed in PONG (single-element array).",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command"],
|
||||
"examples": [
|
||||
{ "command": "PING", "body": "1707580000" }
|
||||
{ "command": "PING", "body": ["1707580000"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,17 +6,16 @@
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "PONG" },
|
||||
"from": {
|
||||
"type": "string",
|
||||
"description": "Responding server name."
|
||||
},
|
||||
"from": { "type": "string", "description": "Responding server name." },
|
||||
"body": {
|
||||
"type": "string",
|
||||
"description": "Echoed token from PING."
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Echoed token from PING (single-element array).",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command"],
|
||||
"examples": [
|
||||
{ "command": "PONG", "from": "server.example.com", "body": "1707580000" }
|
||||
{ "command": "PONG", "from": "server.example.com", "body": ["1707580000"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,11 +8,17 @@
|
||||
"command": { "const": "PRIVMSG" },
|
||||
"from": { "type": "string", "description": "Sender nick (set by server on relay)." },
|
||||
"to": { "type": "string", "description": "Target: #channel or nick.", "examples": ["#general", "alice"] },
|
||||
"body": { "type": "string", "description": "Message text.", "minLength": 1 }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Message lines. One string per line.",
|
||||
"minItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "body"],
|
||||
"examples": [
|
||||
{ "command": "PRIVMSG", "from": "bob", "to": "#general", "body": "hello world" },
|
||||
{ "command": "PRIVMSG", "from": "bob", "to": "alice", "body": "hey" }
|
||||
{ "command": "PRIVMSG", "from": "bob", "to": "#general", "body": ["hello world"] },
|
||||
{ "command": "PRIVMSG", "from": "bob", "to": "#general", "body": ["line one", "line two"] },
|
||||
{ "command": "PRIVMSG", "from": "bob", "to": "alice", "body": ["hey"], "meta": { "sig": "base64...", "alg": "ed25519" } }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -7,10 +7,15 @@
|
||||
"properties": {
|
||||
"command": { "const": "QUIT" },
|
||||
"from": { "type": "string", "description": "Nick that quit." },
|
||||
"body": { "type": "string", "description": "Optional quit reason." }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Optional quit reason.",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "from"],
|
||||
"examples": [
|
||||
{ "command": "QUIT", "from": "alice", "body": "Connection reset" }
|
||||
{ "command": "QUIT", "from": "alice", "body": ["Connection reset"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -8,10 +8,15 @@
|
||||
"command": { "const": "TOPIC" },
|
||||
"from": { "type": "string", "description": "Nick that changed the topic (S2C)." },
|
||||
"to": { "type": "string", "description": "Channel name.", "pattern": "^#[a-zA-Z0-9_-]+$" },
|
||||
"body": { "type": "string", "description": "New topic text. Empty string clears the topic.", "maxLength": 512 }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "New topic text (single-element array). Empty array clears the topic.",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to"],
|
||||
"examples": [
|
||||
{ "command": "TOPIC", "from": "alice", "to": "#general", "body": "Welcome to the chat" }
|
||||
{ "command": "TOPIC", "from": "alice", "to": "#general", "body": ["Welcome to the chat"] }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -6,8 +6,9 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "integer",
|
||||
"description": "Server-assigned message ID, monotonically increasing. Present on all server-originated messages."
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Server-assigned message UUID. Present on all server-originated messages."
|
||||
},
|
||||
"command": {
|
||||
"type": "string",
|
||||
@@ -28,8 +29,19 @@
|
||||
"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)."
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"description": "Array of strings (one per line for text messages)."
|
||||
},
|
||||
{
|
||||
"type": "object",
|
||||
"description": "Structured data (e.g. PUBKEY key material).",
|
||||
"additionalProperties": true
|
||||
}
|
||||
],
|
||||
"description": "Message body. MUST be an array or object, never a raw string. Arrays represent lines of text; objects carry structured data. This enables deterministic canonicalization (RFC 8785 JCS) for signing."
|
||||
},
|
||||
"ts": {
|
||||
"type": "string",
|
||||
@@ -38,7 +50,21 @@
|
||||
},
|
||||
"meta": {
|
||||
"type": "object",
|
||||
"description": "Extensible metadata (signatures, rich content hints, etc.). Not present in original IRC.",
|
||||
"description": "Extensible metadata. Used for signatures (meta.sig, meta.alg), hashes (meta.hash), and client extensions.",
|
||||
"properties": {
|
||||
"sig": {
|
||||
"type": "string",
|
||||
"description": "Base64-encoded cryptographic signature over the canonical message form."
|
||||
},
|
||||
"alg": {
|
||||
"type": "string",
|
||||
"description": "Signature algorithm (e.g. 'ed25519')."
|
||||
},
|
||||
"hash": {
|
||||
"type": "string",
|
||||
"description": "Hash of the canonical message form (e.g. 'sha256:base64...')."
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
|
||||
@@ -2,19 +2,36 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/001.json",
|
||||
"title": "001 RPL_WELCOME",
|
||||
"description": "Welcome message sent after successful session creation. RFC 2812 §5.1.",
|
||||
"description": "Welcome message sent after successful session creation. RFC 2812 \u00a75.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "001" },
|
||||
"to": { "type": "string", "description": "Target nick." },
|
||||
"command": {
|
||||
"const": "001"
|
||||
},
|
||||
"to": {
|
||||
"type": "string",
|
||||
"description": "Target nick."
|
||||
},
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Welcome text lines."
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "body"],
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"body"
|
||||
],
|
||||
"examples": [
|
||||
{ "command": "001", "to": "alice", "body": ["Welcome to the network, alice"] }
|
||||
{
|
||||
"command": "001",
|
||||
"to": "alice",
|
||||
"body": [
|
||||
"Welcome to the network, alice"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,19 +2,35 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/002.json",
|
||||
"title": "002 RPL_YOURHOST",
|
||||
"description": "Server host info sent after session creation. RFC 2812 §5.1.",
|
||||
"description": "Server host info sent after session creation. RFC 2812 \u00a75.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "002" },
|
||||
"to": { "type": "string" },
|
||||
"command": {
|
||||
"const": "002"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Host info lines."
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "body"],
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"body"
|
||||
],
|
||||
"examples": [
|
||||
{ "command": "002", "to": "alice", "body": ["Your host is chat.example.com, running version 0.1.0"] }
|
||||
{
|
||||
"command": "002",
|
||||
"to": "alice",
|
||||
"body": [
|
||||
"Your host is chat.example.com, running version 0.1.0"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,12 +2,26 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/323.json",
|
||||
"title": "323 RPL_LISTEND",
|
||||
"description": "End of channel list. RFC 1459 §6.2.",
|
||||
"description": "End of channel list. RFC 1459 \u00a76.2.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "323" },
|
||||
"to": { "type": "string" },
|
||||
"body": { "const": "End of /LIST" }
|
||||
"command": {
|
||||
"const": "323"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "End of /LIST",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to"]
|
||||
"required": [
|
||||
"command",
|
||||
"to"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,17 +2,34 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/366.json",
|
||||
"title": "366 RPL_ENDOFNAMES",
|
||||
"description": "End of NAMES list. RFC 1459 §6.2.",
|
||||
"description": "End of NAMES list. RFC 1459 \u00a76.2.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "366" },
|
||||
"to": { "type": "string" },
|
||||
"command": {
|
||||
"const": "366"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "[channel]."
|
||||
},
|
||||
"body": { "const": "End of /NAMES list" }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "End of /NAMES list",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "params"]
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"params"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,12 +2,26 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/376.json",
|
||||
"title": "376 RPL_ENDOFMOTD",
|
||||
"description": "End of MOTD. RFC 2812 §5.1.",
|
||||
"description": "End of MOTD. RFC 2812 \u00a75.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "376" },
|
||||
"to": { "type": "string" },
|
||||
"body": { "const": "End of /MOTD command" }
|
||||
"command": {
|
||||
"const": "376"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "End of /MOTD command",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to"]
|
||||
"required": [
|
||||
"command",
|
||||
"to"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,20 +2,46 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/401.json",
|
||||
"title": "401 ERR_NOSUCHNICK",
|
||||
"description": "No such nick/channel. RFC 1459 §6.1.",
|
||||
"description": "No such nick/channel. RFC 1459 \u00a76.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "401" },
|
||||
"to": { "type": "string" },
|
||||
"command": {
|
||||
"const": "401"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "[target_nick]."
|
||||
},
|
||||
"body": { "const": "No such nick/channel" }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "No such nick/channel",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "params"],
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"params"
|
||||
],
|
||||
"examples": [
|
||||
{ "command": "401", "to": "alice", "params": ["bob"], "body": "No such nick/channel" }
|
||||
{
|
||||
"command": "401",
|
||||
"to": "alice",
|
||||
"params": [
|
||||
"bob"
|
||||
],
|
||||
"body": [
|
||||
"No such nick/channel"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,20 +2,46 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/403.json",
|
||||
"title": "403 ERR_NOSUCHCHANNEL",
|
||||
"description": "No such channel. RFC 1459 §6.1.",
|
||||
"description": "No such channel. RFC 1459 \u00a76.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "403" },
|
||||
"to": { "type": "string" },
|
||||
"command": {
|
||||
"const": "403"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "[channel_name]."
|
||||
},
|
||||
"body": { "const": "No such channel" }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "No such channel",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "params"],
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"params"
|
||||
],
|
||||
"examples": [
|
||||
{ "command": "403", "to": "alice", "params": ["#nonexistent"], "body": "No such channel" }
|
||||
{
|
||||
"command": "403",
|
||||
"to": "alice",
|
||||
"params": [
|
||||
"#nonexistent"
|
||||
],
|
||||
"body": [
|
||||
"No such channel"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,20 +2,46 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/433.json",
|
||||
"title": "433 ERR_NICKNAMEINUSE",
|
||||
"description": "Nickname is already in use. RFC 1459 §6.1.",
|
||||
"description": "Nickname is already in use. RFC 1459 \u00a76.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "433" },
|
||||
"to": { "type": "string" },
|
||||
"command": {
|
||||
"const": "433"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "[requested_nick]."
|
||||
},
|
||||
"body": { "const": "Nickname is already in use" }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Nickname is already in use",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "params"],
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"params"
|
||||
],
|
||||
"examples": [
|
||||
{ "command": "433", "to": "*", "params": ["alice"], "body": "Nickname is already in use" }
|
||||
{
|
||||
"command": "433",
|
||||
"to": "*",
|
||||
"params": [
|
||||
"alice"
|
||||
],
|
||||
"body": [
|
||||
"Nickname is already in use"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,17 +2,34 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/442.json",
|
||||
"title": "442 ERR_NOTONCHANNEL",
|
||||
"description": "You're not on that channel. RFC 1459 §6.1.",
|
||||
"description": "You're not on that channel. RFC 1459 \u00a76.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "442" },
|
||||
"to": { "type": "string" },
|
||||
"command": {
|
||||
"const": "442"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "[channel]."
|
||||
},
|
||||
"body": { "const": "You're not on that channel" }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "You're not on that channel",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "params"]
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"params"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,17 +2,34 @@
|
||||
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
||||
"$id": "https://git.eeqj.de/sneak/chat/schema/numerics/482.json",
|
||||
"title": "482 ERR_CHANOPRIVSNEEDED",
|
||||
"description": "You're not channel operator. RFC 1459 §6.1.",
|
||||
"description": "You're not channel operator. RFC 1459 \u00a76.1.",
|
||||
"$ref": "../message.json",
|
||||
"properties": {
|
||||
"command": { "const": "482" },
|
||||
"to": { "type": "string" },
|
||||
"command": {
|
||||
"const": "482"
|
||||
},
|
||||
"to": {
|
||||
"type": "string"
|
||||
},
|
||||
"params": {
|
||||
"type": "array",
|
||||
"items": { "type": "string" },
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "[channel]."
|
||||
},
|
||||
"body": { "const": "You're not channel operator" }
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "You're not channel operator",
|
||||
"maxItems": 1
|
||||
}
|
||||
},
|
||||
"required": ["command", "to", "params"]
|
||||
"required": [
|
||||
"command",
|
||||
"to",
|
||||
"params"
|
||||
]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user