@wolfstar/http-framework 6.2.2 → 6.3.0-next-20261007181329
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 +129 -0
- package/dist/esm/index.d.ts +597 -135
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +425 -65
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -270,23 +270,152 @@ client.on(Events.CommandError, (error, context) => {
|
|
|
270
270
|
| `Events.CommandNameMissing` | `commandNameMissing` | `interaction, response` |
|
|
271
271
|
| `Events.CommandNameUnknown` | `commandNameUnknown` | `interaction, response` |
|
|
272
272
|
| `Events.CommandMethodUnknown` | `commandMethodUnknown` | `context` |
|
|
273
|
+
| `Events.PreChatInputCommandRun` | `preChatInputCommandRun` | `context` |
|
|
274
|
+
| `Events.PreContextMenuCommandRun` | `preContextMenuCommandRun` | `context` |
|
|
275
|
+
| `Events.ChatInputCommandAccepted` | `chatInputCommandAccepted` | `context` |
|
|
276
|
+
| `Events.ContextMenuCommandAccepted` | `contextMenuCommandAccepted` | `context` |
|
|
273
277
|
| `Events.CommandRun` | `commandRun` | `context` |
|
|
274
278
|
| `Events.CommandSuccess` | `commandSuccess` | `context, value: unknown` |
|
|
275
279
|
| `Events.CommandError` | `commandError` | `error: unknown, context` |
|
|
280
|
+
| `Events.ChatInputCommandDenied` | `chatInputCommandDenied` | `error: UserError, context` |
|
|
281
|
+
| `Events.ContextMenuCommandDenied` | `contextMenuCommandDenied` | `error: UserError, context` |
|
|
276
282
|
| `Events.CommandFinish` | `commandFinish` | `context` |
|
|
283
|
+
| `Events.AutocompleteAccepted` | `autocompleteAccepted` | `context` |
|
|
277
284
|
| `Events.AutocompleteRun` | `autocompleteRun` | `context` |
|
|
278
285
|
| `Events.AutocompleteSuccess` | `autocompleteSuccess` | `context, value: unknown` |
|
|
279
286
|
| `Events.AutocompleteError` | `autocompleteError` | `error: unknown, context` |
|
|
287
|
+
| `Events.AutocompleteDenied` | `autocompleteDenied` | `error: UserError, context` |
|
|
280
288
|
| `Events.AutocompleteFinish` | `autocompleteFinish` | `context` |
|
|
281
289
|
| `Events.InteractionHandlerNameInvalid` | `interactionHandlerNameInvalid` | `interaction, response` |
|
|
282
290
|
| `Events.InteractionHandlerNameUnknown` | `interactionHandlerNameUnknown` | `interaction, response` |
|
|
291
|
+
| `Events.InteractionHandlerAccepted` | `interactionHandlerAccepted` | `context` |
|
|
283
292
|
| `Events.InteractionHandlerRun` | `interactionHandlerRun` | `context` |
|
|
284
293
|
| `Events.InteractionHandlerSuccess` | `interactionHandlerSuccess` | `context, value: unknown` |
|
|
285
294
|
| `Events.InteractionHandlerError` | `interactionHandlerError` | `error: unknown, context` |
|
|
295
|
+
| `Events.InteractionHandlerDenied` | `interactionHandlerDenied` | `error: UserError, context` |
|
|
286
296
|
| `Events.InteractionHandlerFinish` | `interactionHandlerFinish` | `context` |
|
|
287
297
|
|
|
288
298
|
The Hot Module Reloading events are listed in [their own section](#hot-module-reloading).
|
|
289
299
|
|
|
300
|
+
#### Expected errors: `*Denied` events
|
|
301
|
+
|
|
302
|
+
When a command, an autocomplete handler, or an interaction handler throws a `UserError` (or a subclass such as
|
|
303
|
+
`PreconditionError` and `ArgumentError`), the failure is an expected one, meant to be shown to the user. The client emits
|
|
304
|
+
it as `chatInputCommandDenied` or `contextMenuCommandDenied` (commands, by the type of the command), `autocompleteDenied`,
|
|
305
|
+
or `interactionHandlerDenied` instead of `commandError`, `autocompleteError`, or `interactionHandlerError`. Anything that
|
|
306
|
+
is not a `UserError` keeps going to the `*Error` events, so a listener that reports bugs, such as the Sentry one of
|
|
307
|
+
`@wolfstar/shared-http-pieces`, no longer sees the expected ones.
|
|
308
|
+
|
|
309
|
+
```typescript
|
|
310
|
+
import { Events, Listener, type ClientEventCommandContext, type UserError } from '@wolfstar/http-framework';
|
|
311
|
+
|
|
312
|
+
export class UserListener extends Listener {
|
|
313
|
+
public constructor(context: Listener.LoaderContext) {
|
|
314
|
+
super(context, { event: Events.ChatInputCommandDenied });
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
public run(error: UserError, context: ClientEventCommandContext) {
|
|
318
|
+
this.container.logger.info(`${context.command.name} denied: ${error.identifier}`);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
The check is `isUserError(error)`, exported for the same use: it accepts `instanceof UserError`, and also an `Error` with a
|
|
324
|
+
string `identifier` and a `context` property, since a bundle that inlines the framework has its own `UserError` class.
|
|
325
|
+
The `error` event and the HTTP response are not affected: both behave as for any other thrown error.
|
|
326
|
+
|
|
327
|
+
> [!WARNING]
|
|
328
|
+
> Before 6.3.0 a thrown `UserError` was emitted as `commandError` (or `autocompleteError` / `interactionHandlerError`).
|
|
329
|
+
> A listener on those events that handles `UserError` or `PreconditionError` has to move to the `*Denied` events.
|
|
330
|
+
|
|
331
|
+
#### Preconditions
|
|
332
|
+
|
|
333
|
+
A precondition is a check that runs before a chat input or context menu command does, before the autocomplete of a
|
|
334
|
+
command, and before an interaction handler. When it denies the interaction, the method is not run and the error is
|
|
335
|
+
emitted as `chatInputCommandDenied`, `contextMenuCommandDenied`, `autocompleteDenied` or `interactionHandlerDenied`, the
|
|
336
|
+
same events as a `UserError` the command throws.
|
|
337
|
+
|
|
338
|
+
The events of a command are, in order: `preChatInputCommandRun` (or `preContextMenuCommandRun`), the preconditions, then
|
|
339
|
+
`chatInputCommandAccepted` (or `contextMenuCommandAccepted`) and `commandRun`, or the `*Denied` event, then
|
|
340
|
+
`commandSuccess` or `commandError`, and `commandFinish`. An autocomplete and an interaction handler emit
|
|
341
|
+
`autocompleteAccepted` and `interactionHandlerAccepted` right before `autocompleteRun` and `interactionHandlerRun`.
|
|
342
|
+
`commandRun` is no longer emitted for a command that was denied.
|
|
343
|
+
|
|
344
|
+
A precondition is a piece: a class that extends `Precondition`, in the `preconditions` directory, loaded into the
|
|
345
|
+
`preconditions` store. It implements `chatInputRun` and/or `contextMenuRun`, and answers with `this.ok()` or
|
|
346
|
+
`this.error(...)`, which builds a `PreconditionError` for the piece.
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
import { Precondition } from '@wolfstar/http-framework';
|
|
350
|
+
|
|
351
|
+
export class UserPrecondition extends Precondition {
|
|
352
|
+
public override chatInputRun(interaction: Precondition.ChatInputInteraction) {
|
|
353
|
+
return interaction.user.id === process.env.OWNER_ID ? this.ok() : this.error({ message: 'Only the owner can use this command.' });
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
A command lists the preconditions it needs by name, in the `preconditions` option. An entry is the name, the name with a
|
|
359
|
+
`context` that the piece receives as its last argument, or a function for a check that does not need a piece of its own.
|
|
360
|
+
They run in the order listed and the first denial stops the rest.
|
|
361
|
+
|
|
362
|
+
```typescript
|
|
363
|
+
import { err, ok } from '@sapphire/result';
|
|
364
|
+
import { Command, PreconditionError, type PreconditionFunction } from '@wolfstar/http-framework';
|
|
365
|
+
|
|
366
|
+
const NotOnMonday: PreconditionFunction = () => (new Date().getDay() === 1 ? err(new PreconditionError({ precondition: 'NotOnMonday' })) : ok());
|
|
367
|
+
|
|
368
|
+
export class UserCommand extends Command {
|
|
369
|
+
public constructor(context: Command.LoaderContext, options: Command.Options) {
|
|
370
|
+
super(context, { ...options, preconditions: ['UserPrecondition', { name: 'Role', context: { roleId: '737141877803057244' } }, NotOnMonday] });
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
An entry can also be an array. The list of a command is an `AND`: every entry has to pass. An array nested in it is an
|
|
376
|
+
`OR`: one entry has to pass, and when none does, the last error is the denial. An array nested in that is an `AND` again,
|
|
377
|
+
and so on, so the following is `Connect && (Moderator || (DJ && SongAuthor))`:
|
|
378
|
+
|
|
379
|
+
```typescript
|
|
380
|
+
super(context, { ...options, preconditions: ['Connect', ['Moderator', ['DJ', 'SongAuthor']]] });
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
The entries run one after the other and stop as soon as the result is known. To start all of them at once, write the list
|
|
384
|
+
as `{ entries, mode: PreconditionRunMode.Parallel }`; the arrays nested in it inherit the mode, every entry is run, and
|
|
385
|
+
the denial is the first error in order for an `AND` and the last one for an `OR`.
|
|
386
|
+
|
|
387
|
+
A precondition with a `position` is global: it runs for every command, in ascending order of `position`, before the ones
|
|
388
|
+
of the command. A piece can also implement `autocompleteRun` and `interactionHandlerRun`, and an interaction handler has
|
|
389
|
+
the same `preconditions` option as a command.
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import { Precondition } from '@wolfstar/http-framework';
|
|
393
|
+
|
|
394
|
+
export class UserPrecondition extends Precondition {
|
|
395
|
+
public constructor(context: Precondition.LoaderContext) {
|
|
396
|
+
super(context, { position: 10 });
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// ...
|
|
400
|
+
}
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
An entry that does not apply to an autocomplete or an interaction handler is left out of the result of its array, so it
|
|
404
|
+
cannot make an `OR` pass.
|
|
405
|
+
|
|
406
|
+
A piece that has no method for the chat input or context menu command it is asked to check denies it with
|
|
407
|
+
`Identifiers.PreconditionMissingChatInputHandler` or `Identifiers.PreconditionMissingContextMenuHandler`. For an
|
|
408
|
+
autocomplete or an interaction handler a piece with no `autocompleteRun` or `interactionHandlerRun` is skipped instead,
|
|
409
|
+
global ones included, so a check written for the commands does not deny their autocomplete or the buttons of the bot, and
|
|
410
|
+
the functions of a command are not run for its autocomplete. A name that is not in the store denies with
|
|
411
|
+
`Identifiers.PreconditionUnavailable`. A precondition that throws is handled like a command that throws: a `UserError`
|
|
412
|
+
goes to the `*Denied` events, anything else to `commandError`.
|
|
413
|
+
|
|
414
|
+
This follows the preconditions of `@sapphire/framework`, except for the message flow, which has no use over HTTP, the
|
|
415
|
+
built-in checks (`Cooldown`, `NSFW`, `GuildOnly`, ...), and the typed registry of precondition names. The checks for
|
|
416
|
+
autocomplete and interaction handlers, and their `Accepted` events, are not in Sapphire. The permission decorators of
|
|
417
|
+
`@wolfstar/decorators` keep working as before.
|
|
418
|
+
|
|
290
419
|
Listeners declared as pieces can use the enum too:
|
|
291
420
|
|
|
292
421
|
```typescript
|