@went.tf/discord-bot-framework 2.1.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -35
- package/build/.tsbuildinfo +1 -1
- package/build/commands/build-application-commands-body.d.ts +7 -2
- package/build/commands/build-application-commands-body.d.ts.map +1 -1
- package/build/commands/build-application-commands-body.js +8 -1
- package/build/commands/build-application-commands-body.js.map +1 -1
- package/build/commands/schema/command-file-entry.schema.d.ts +16 -0
- package/build/commands/schema/command-file-entry.schema.d.ts.map +1 -0
- package/build/commands/schema/command-file-entry.schema.js +14 -0
- package/build/commands/schema/command-file-entry.schema.js.map +1 -0
- package/build/commands/schema/command-file-entry.schema.json +11 -0
- package/build/commands/schema/commands-file.schema.d.ts +38 -12
- package/build/commands/schema/commands-file.schema.d.ts.map +1 -1
- package/build/commands/schema/commands-file.schema.js +30 -10
- package/build/commands/schema/commands-file.schema.js.map +1 -1
- package/build/commands/schema/commands-file.schema.json +25 -10
- package/build/commands/schema/index.d.ts +57 -4
- package/build/commands/schema/index.d.ts.map +1 -1
- package/build/commands/schema/index.js +75 -3
- package/build/commands/schema/index.js.map +1 -1
- package/build/interactions/registry.d.ts +7 -0
- package/build/interactions/registry.d.ts.map +1 -1
- package/build/interactions/registry.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -148,6 +148,24 @@ for bots that nest a `.modal` map directly on the owning chat-input command
|
|
|
148
148
|
synthesizes a flat `Registry<string, BotModal<Ctx>>` view so `dispatchModal`
|
|
149
149
|
can consume it unchanged.
|
|
150
150
|
|
|
151
|
+
If other code (e.g. a locale-file type, or a helper building a command
|
|
152
|
+
mention) needs the literal name/id union as a *type*, derive it from the
|
|
153
|
+
registry you already built instead of hand-writing a parallel
|
|
154
|
+
`const enum CommandName { ... }` — that enum is exactly the duplication the
|
|
155
|
+
registry's `const` type inference exists to avoid:
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
import { RegistryName } from '@went.tf/discord-bot-framework/interactions';
|
|
159
|
+
|
|
160
|
+
const chatInputCommandRegistry = createChatInputCommandRegistry([pingCommand, searchCommand]);
|
|
161
|
+
type ChatInputCommandName = RegistryName<typeof chatInputCommandRegistry>; // 'ping' | 'search'
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
A command's name should only ever be written down in two places: its
|
|
165
|
+
`commands.json` entry and its own registry object's `name` field — nothing
|
|
166
|
+
else should define it again, only reference the same string (or the derived
|
|
167
|
+
`RegistryName` type) that those two already agree on.
|
|
168
|
+
|
|
151
169
|
### `@went.tf/discord-bot-framework/commands`
|
|
152
170
|
|
|
153
171
|
**Every command's wire definition (name, description, options, permissions)
|
|
@@ -162,19 +180,31 @@ autocomplete?, modal? }`) no longer describe their own wire shape at all.
|
|
|
162
180
|
below):
|
|
163
181
|
|
|
164
182
|
```json
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
"type": "CHAT_INPUT",
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
183
|
+
{
|
|
184
|
+
"$schema": "./commands.schema.json",
|
|
185
|
+
"commands": [
|
|
186
|
+
{ "type": "CHAT_INPUT", "name": "ping", "description": "Replies with pong" },
|
|
187
|
+
{
|
|
188
|
+
"type": "CHAT_INPUT",
|
|
189
|
+
"name": "search",
|
|
190
|
+
"description": "Search for something",
|
|
191
|
+
"options": [
|
|
192
|
+
{ "type": "STRING", "name": "query", "description": "Query string", "required": true }
|
|
193
|
+
]
|
|
194
|
+
}
|
|
195
|
+
]
|
|
196
|
+
}
|
|
176
197
|
```
|
|
177
198
|
|
|
199
|
+
The `{ "$schema", "commands" }` wrapper is what makes `commands.json`
|
|
200
|
+
editable with real autocomplete/validation in VS Code, JetBrains, or any
|
|
201
|
+
other JSON-Schema-aware editor: `$schema` is only ever valid on a JSON
|
|
202
|
+
*object*, and a bare array can never carry one. A **bare array** (just
|
|
203
|
+
the `commands` value on its own, no wrapper) is still fully supported —
|
|
204
|
+
nothing about the wrapper is required — but you lose the inline `$schema`
|
|
205
|
+
editor hookup if you use it. `buildApplicationCommandsBody` accepts
|
|
206
|
+
either shape directly.
|
|
207
|
+
|
|
178
208
|
`type` (and `contexts`/`integration_types`/`channel_types`) accept either
|
|
179
209
|
Discord's raw numeric value or the UPPER_SNAKE_CASE string alias shown
|
|
180
210
|
above — nobody should have to remember that `3` means `STRING`. Both
|
|
@@ -189,10 +219,14 @@ autocomplete?, modal? }`) no longer describe their own wire shape at all.
|
|
|
189
219
|
|
|
190
220
|
```ts
|
|
191
221
|
import { Ajv } from 'ajv';
|
|
192
|
-
import { parseCommandsFile, registerFrameworkSchemas } from '@went.tf/discord-bot-framework/commands/schema';
|
|
193
|
-
import
|
|
222
|
+
import { parseCommandsFile, registerFrameworkSchemas, resolveCommandsSchemaRefs } from '@went.tf/discord-bot-framework/commands/schema';
|
|
223
|
+
import myCommandsSchemaRaw from './commands.schema.json' with { type: 'json' };
|
|
194
224
|
import commandsData from './commands.json' with { type: 'json' };
|
|
195
225
|
|
|
226
|
+
// Rewrites your schema's relative-path $refs (into node_modules) to each
|
|
227
|
+
// fragment's real ajv-resolvable identity - see "JSON Schema fragments" below.
|
|
228
|
+
const myCommandsSchema = resolveCommandsSchemaRefs(myCommandsSchemaRaw);
|
|
229
|
+
|
|
196
230
|
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true });
|
|
197
231
|
registerFrameworkSchemas(ajv);
|
|
198
232
|
const validate = ajv.compile(myCommandsSchema);
|
|
@@ -243,37 +277,80 @@ This package ships only the **generic, reusable JSON Schema building
|
|
|
243
277
|
blocks** mirroring `discord-api-types`' command/option shapes — it does not
|
|
244
278
|
dictate one rigid schema for your whole `commands.json` file. Compose your
|
|
245
279
|
own schema on top via `$ref`/`allOf`, e.g. to narrow `name` to an enum of
|
|
246
|
-
your bot's actual command names
|
|
280
|
+
your bot's actual command names. Since a bot's own `commands.schema.json` is
|
|
281
|
+
authored as plain JSON (so external tools can consume it too, not just this
|
|
282
|
+
package's TS composition helpers), supporting **both** the bare-array and
|
|
283
|
+
the `{ $schema, commands }` root shapes over the same narrowed entry uses a
|
|
284
|
+
local `$defs` entry referenced from both branches:
|
|
247
285
|
|
|
248
286
|
```json
|
|
249
287
|
{
|
|
250
|
-
"$
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
288
|
+
"$defs": {
|
|
289
|
+
"entry": {
|
|
290
|
+
"oneOf": [
|
|
291
|
+
{
|
|
292
|
+
"allOf": [
|
|
293
|
+
{ "$ref": "../node_modules/@went.tf/discord-bot-framework/build/commands/schema/chat-input-command.json" },
|
|
294
|
+
{ "properties": { "name": { "enum": ["ping", "search"] } } }
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
{ "$ref": "../node_modules/@went.tf/discord-bot-framework/build/commands/schema/context-menu-command.json" }
|
|
298
|
+
]
|
|
299
|
+
}
|
|
300
|
+
},
|
|
301
|
+
"oneOf": [
|
|
302
|
+
{ "type": "array", "items": { "$ref": "#/$defs/entry" } },
|
|
303
|
+
{
|
|
304
|
+
"type": "object",
|
|
305
|
+
"properties": {
|
|
306
|
+
"$schema": { "type": "string" },
|
|
307
|
+
"commands": { "type": "array", "items": { "$ref": "#/$defs/entry" } }
|
|
259
308
|
},
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
309
|
+
"required": ["commands"],
|
|
310
|
+
"additionalProperties": false
|
|
311
|
+
}
|
|
312
|
+
]
|
|
263
313
|
}
|
|
264
314
|
```
|
|
265
315
|
|
|
266
|
-
|
|
267
|
-
|
|
316
|
+
`$ref` uses a **real relative filesystem path** into `node_modules` (the
|
|
317
|
+
exact `../` count doesn't have to be exactly right — see below) rather than
|
|
318
|
+
an opaque URL — this is what makes an editor (VS Code, JetBrains, ...)
|
|
319
|
+
actually able to follow it and offer real autocomplete/validation while you
|
|
320
|
+
hand-edit `commands.schema.json`, since it points at a real file: this
|
|
321
|
+
package ships its raw fragment `.json` mirrors precisely so a path like this
|
|
322
|
+
resolves to something real on disk, no network access involved.
|
|
323
|
+
|
|
324
|
+
**ajv** can't follow that same relative path directly — it resolves relative
|
|
325
|
+
`$ref`s via real RFC3986 URI resolution against the referencing schema's own
|
|
326
|
+
`$id`, and `node_modules` is virtualized under a symlinked store by pnpm (and
|
|
327
|
+
similar tools), so there is no `$id` value that makes ajv's own resolution
|
|
328
|
+
land on the right file for every install. `resolveCommandsSchemaRefs()`
|
|
329
|
+
sidesteps this: it rewrites any `$ref` matching a shipped fragment's
|
|
330
|
+
filename to that fragment's canonical `$id` (whatever relative-path prefix
|
|
331
|
+
you used), which `registerFrameworkSchemas(ajv)` has already registered.
|
|
332
|
+
Your own local refs (e.g. `#/$defs/...`) are left untouched:
|
|
333
|
+
|
|
334
|
+
```ts
|
|
335
|
+
import myCommandsSchemaRaw from './commands.schema.json' with { type: 'json' };
|
|
336
|
+
const myCommandsSchema = resolveCommandsSchemaRefs(myCommandsSchemaRaw);
|
|
337
|
+
registerFrameworkSchemas(ajv); // before ajv.compile(myCommandsSchema)
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
If you don't need the name-narrowing (or any other bot-specific constraint),
|
|
341
|
+
skip authoring your own schema entirely and validate directly against this
|
|
342
|
+
package's own `commandsFileSchema` — it already accepts both root shapes.
|
|
343
|
+
|
|
344
|
+
The fragments this package ships (all under
|
|
268
345
|
`@went.tf/discord-bot-framework/commands/schema`, and as real standalone
|
|
269
346
|
`.json` files under `build/commands/schema/` for non-TS tooling):
|
|
270
|
-
`commands-file`, `
|
|
271
|
-
`application-command-option` (and its
|
|
272
|
-
`application-command-
|
|
273
|
-
|
|
274
|
-
`
|
|
275
|
-
`
|
|
276
|
-
`application-integration-type`, `channel-type`.
|
|
347
|
+
`commands-file`, `command-file-entry`, `chat-input-command`,
|
|
348
|
+
`context-menu-command`, `application-command-option` (and its
|
|
349
|
+
`application-command-leaf-option`/`application-command-subcommand`/
|
|
350
|
+
`application-command-subcommand-group` building blocks),
|
|
351
|
+
`application-command-option-choice`, `default-member-permissions`,
|
|
352
|
+
`option-name`, `context-menu-name`, `application-command-type`,
|
|
353
|
+
`interaction-context-type`, `application-integration-type`, `channel-type`.
|
|
277
354
|
|
|
278
355
|
`./commands/schema` also exports `enum-maps.ts`'s `APPLICATION_COMMAND_TYPE_MAP`,
|
|
279
356
|
`APPLICATION_COMMAND_OPTION_TYPE_MAP`, `INTERACTION_CONTEXT_TYPE_MAP`,
|