meocord 4.2.2 → 4.2.3
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/CHANGELOG.md +130 -0
- package/dist/cjs/_shared/{controller.decorator-U2NBWcoU.cjs → controller.decorator-hp5xdJU4.cjs} +512 -183
- package/dist/cjs/_shared/{startup-roots-lA5xkBFq.cjs → event-sources-DzqTODXg.cjs} +265 -80
- package/dist/cjs/_shared/{providers-B4MOFBrW.cjs → providers-BBvbnmLP.cjs} +780 -281
- package/dist/cjs/_shared/{sharded-cooldown-store-HTUb3Ii_.cjs → sharded-cooldown-store-B62g5O88.cjs} +11 -9
- package/dist/cjs/_shared/{translate-error-CbBHUu5P.cjs → translate-error-wsgfsUET.cjs} +1 -1
- package/dist/cjs/common/index.cjs +4 -104
- package/dist/cjs/core/index.cjs +432 -181
- package/dist/cjs/decorator/index.cjs +85 -120
- package/dist/cjs/testing/index.cjs +1664 -784
- package/dist/cli.json +1 -1
- package/dist/esm/bin/app-template/package.json.template +9 -9
- package/dist/esm/bin/app-template/src/main.ts.template +3 -2
- package/dist/esm/bin/generator.js +6 -4
- package/dist/esm/bin/helper/filter-generator.helper.js +6 -4
- package/dist/esm/bin/helper/guard-generator.helper.js +6 -4
- package/dist/esm/bin/helper/interceptor-generator.helper.js +6 -4
- package/dist/esm/bin/helper/observer-generator.helper.js +6 -4
- package/dist/esm/bin/helper/pipe-generator.helper.js +6 -4
- package/dist/esm/bin/helper/service-generator.helper.js +6 -4
- package/dist/esm/bin/meocord.js +106 -48
- package/dist/esm/build/native-addons.js +75 -19
- package/dist/esm/build/rsbuild-config.js +11 -3
- package/dist/esm/build/typed-externals.js +15 -2
- package/dist/esm/common/cooldown-store.js +38 -14
- package/dist/esm/common/deprecation.js +4 -1
- package/dist/esm/common/execution-context.js +3 -1
- package/dist/esm/common/explained-error.js +7 -3
- package/dist/esm/common/log-level.js +13 -9
- package/dist/esm/common/logger.js +4 -2
- package/dist/esm/common/meocord-text.js +11 -6
- package/dist/esm/common/redis-cooldown-store.js +3 -7
- package/dist/esm/common/response/flags.js +17 -1
- package/dist/esm/common/response/install-context.js +27 -16
- package/dist/esm/common/response/presenter.js +7 -3
- package/dist/esm/common/response/response-state.js +27 -5
- package/dist/esm/common/sharded-cooldown-store.js +11 -9
- package/dist/esm/common/theme.js +3 -1
- package/dist/esm/common/translator.js +17 -8
- package/dist/esm/core/autocomplete-routes.js +26 -0
- package/dist/esm/core/command-conflicts.js +15 -7
- package/dist/esm/core/command-registration.js +15 -1
- package/dist/esm/core/cooldown-runner.js +7 -9
- package/dist/esm/core/defer.js +2 -5
- package/dist/esm/core/dispatcher.js +83 -58
- package/dist/esm/core/event-requirements.js +67 -19
- package/dist/esm/core/event-sources.js +100 -0
- package/dist/esm/core/fallback.js +3 -1
- package/dist/esm/core/filter-runner.js +4 -4
- package/dist/esm/core/guard-runner.js +173 -52
- package/dist/esm/core/handler-input.js +24 -3
- package/dist/esm/core/handler-pipeline.js +44 -28
- package/dist/esm/core/handler-registry.js +51 -21
- package/dist/esm/core/input-runner.js +7 -8
- package/dist/esm/core/interceptor-runner.js +4 -5
- package/dist/esm/core/lifecycle-hooks.js +3 -8
- package/dist/esm/core/lifecycle-order.js +1 -15
- package/dist/esm/core/meocord-classes.js +14 -1
- package/dist/esm/core/meocord-factory.js +80 -53
- package/dist/esm/core/meocord.app.js +174 -89
- package/dist/esm/core/message-help.js +5 -9
- package/dist/esm/core/message-params.js +126 -46
- package/dist/esm/core/message-routes.js +225 -45
- package/dist/esm/core/message-words.js +30 -2
- package/dist/esm/core/observer-runner.js +2 -1
- package/dist/esm/core/process-state.js +19 -0
- package/dist/esm/core/providers.js +28 -3
- package/dist/esm/core/scalar-types.js +57 -16
- package/dist/esm/core/shard-context.js +11 -10
- package/dist/esm/core/shard-exit.js +3 -3
- package/dist/esm/core/shard-manager.js +16 -6
- package/dist/esm/core/startup-roots.js +28 -8
- package/dist/esm/core/theme-resolvers.js +26 -11
- package/dist/esm/core/theme-runtime.js +23 -13
- package/dist/esm/core/theme-scope.js +27 -29
- package/dist/esm/core/theme-validation.js +1 -1
- package/dist/esm/decorator/app.decorator.js +6 -1
- package/dist/esm/decorator/command-builder.decorator.js +14 -0
- package/dist/esm/decorator/controller-class.decorator.js +1 -1
- package/dist/esm/decorator/controller.decorator.js +48 -19
- package/dist/esm/decorator/defer.decorator.js +2 -2
- package/dist/esm/decorator/event.decorator.js +4 -5
- package/dist/esm/decorator/filter.decorator.js +2 -2
- package/dist/esm/decorator/guard.decorator.js +4 -61
- package/dist/esm/decorator/inject.decorator.js +4 -1
- package/dist/esm/decorator/interceptor.decorator.js +2 -2
- package/dist/esm/decorator/theme.decorator.js +4 -3
- package/dist/esm/decorator/validation.decorator.js +5 -5
- package/dist/esm/package.json.js +1 -1
- package/dist/esm/testing/catalog.js +29 -13
- package/dist/esm/testing/cooldown-store-suite.js +3 -3
- package/dist/esm/testing/discord-defaults.js +449 -355
- package/dist/esm/testing/inspect-handler.js +91 -10
- package/dist/esm/testing/meocord-testing-module.js +195 -77
- package/dist/esm/testing/mock-fn.js +8 -2
- package/dist/esm/testing/mock-interaction.js +639 -113
- package/dist/esm/testing/response-log.js +8 -0
- package/dist/esm/testing/response.js +7 -5
- package/dist/esm/testing/routing.js +48 -6
- package/dist/esm/testing/strict-mocks.js +1 -0
- package/dist/esm/testing/theme.js +3 -2
- package/dist/esm/util/common.util.js +30 -9
- package/dist/esm/util/generator-cli.util.js +6 -4
- package/dist/esm/util/inherited-env.util.js +72 -13
- package/dist/esm/util/json.util.js +10 -3
- package/dist/esm/util/meocord-cli.util.js +3 -2
- package/dist/esm/util/meocord-config-loader.util.js +14 -1
- package/dist/esm/util/meocord-config-validation.util.js +13 -3
- package/dist/esm/util/meocord-source-config.util.js +13 -3
- package/dist/esm/util/platform.util.js +3 -2
- package/dist/esm/util/refusal.util.js +29 -11
- package/dist/esm/util/registration-mode.util.js +14 -1
- package/dist/esm/util/timer-limit.util.js +4 -1
- package/dist/esm/util/tsconfig-paths.util.js +38 -7
- package/dist/esm/util/tsconfig.util.js +16 -58
- package/dist/esm/util/user-text.util.js +8 -4
- package/dist/esm/util/value.util.js +15 -4
- package/dist/types/common/index.d.cts +13 -9
- package/dist/types/common/index.d.ts +13 -9
- package/dist/types/core/index.d.cts +21 -11
- package/dist/types/core/index.d.ts +21 -11
- package/dist/types/decorator/index.d.cts +63 -63
- package/dist/types/decorator/index.d.ts +63 -63
- package/dist/types/{index-DKJclIi-.d.ts → index-Brkd6QGL.d.ts} +81 -35
- package/dist/types/{index-Dlf0ZZtS.d.cts → index-CqXImwF_.d.cts} +81 -35
- package/dist/types/interface/index.d.cts +1 -1
- package/dist/types/interface/index.d.ts +1 -1
- package/dist/types/{route-Bh1U13yy.d.ts → route-IQrK-MN2.d.cts} +11 -3
- package/dist/types/{route-Bh1U13yy.d.cts → route-bI-okq7g.d.ts} +11 -3
- package/dist/types/testing/index.d.cts +137 -54
- package/dist/types/testing/index.d.ts +137 -54
- package/dist/types/{theme-resolvers-CyEz9pnv.d.cts → theme-resolvers-AtgeaYqF.d.cts} +1 -1
- package/dist/types/{theme-resolvers-DA204O-q.d.ts → theme-resolvers-BgqysV8d.d.ts} +1 -1
- package/dist/types/{translator-Bg7hwxDF.d.cts → translator-D8aydlCE.d.ts} +12 -11
- package/dist/types/{translator-CeP4bCzp.d.ts → translator-iJhDlgwL.d.cts} +12 -11
- package/package.json +5 -2
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { ServiceIdentifier, Container } from 'inversify';
|
|
2
|
-
import { Client, Interaction, Message, MessageReaction, PartialMessageReaction, User, PartialUser, ClientEvents, Base, Locale, GuildMember, Role, GuildBasedChannel, Guild, APIMessageTopLevelComponent, JSONEncodable, APIEmbed, MessageFlagsResolvable, TextBasedChannel, BaseChannel, APIAuthorizingIntegrationOwnersMap, APIInteractionGuildMember, PermissionResolvable, APIUser, CacheType, CommandInteractionOptionResolver, ThreadChannel, AnyThreadChannel, ChatInputCommandInteraction, AutocompleteInteraction, MessageContextMenuCommandInteraction, UserContextMenuCommandInteraction, PrimaryEntryPointCommandInteraction, ContextMenuCommandInteraction, CommandInteraction, ButtonInteraction, StringSelectMenuInteraction, UserSelectMenuInteraction, RoleSelectMenuInteraction, MentionableSelectMenuInteraction, ChannelSelectMenuInteraction, MessageComponentInteraction, ModalSubmitInteraction, BaseInteraction, DMChannel, PartialGroupDMChannel, OmitPartialGroupDMChannel, Attachment, ModalSubmitFields, MessagePayload, InteractionReplyOptions, InteractionUpdateOptions, InteractionEditReplyOptions, MessageEditOptions, APIModalInteractionResponseCallbackData, ModalComponentData, InteractionDeferReplyOptions, InteractionDeferUpdateOptions, MessageResolvable, DiscordAPIError } from 'discord.js';
|
|
2
|
+
import { Client, Interaction, Message, MessageReaction, PartialMessageReaction, User, PartialUser, ClientEvents, Base, Locale, GuildMember, Role, GuildBasedChannel, Guild, APIMessageTopLevelComponent, JSONEncodable, APIEmbed, MessageFlagsResolvable, TextBasedChannel, BaseChannel, APIAuthorizingIntegrationOwnersMap, APIInteractionGuildMember, PermissionResolvable, APIUser, CacheType, CommandInteractionOptionResolver, ThreadChannel, AnyThreadChannel, ChatInputCommandInteraction, AutocompleteInteraction, MessageContextMenuCommandInteraction, UserContextMenuCommandInteraction, PrimaryEntryPointCommandInteraction, ContextMenuCommandInteraction, CommandInteraction, ButtonInteraction, StringSelectMenuInteraction, UserSelectMenuInteraction, RoleSelectMenuInteraction, MentionableSelectMenuInteraction, ChannelSelectMenuInteraction, MessageComponentInteraction, ModalSubmitInteraction, BaseInteraction, DMChannel, PartialGroupDMChannel, OmitPartialGroupDMChannel, Attachment, ModalSubmitFields, MessagePayload, InteractionReplyOptions, InteractionUpdateOptions, InteractionEditReplyOptions, MessageEditOptions, APIModalInteractionResponseCallbackData, ModalComponentData, InteractionDeferReplyOptions, InteractionDeferUpdateOptions, MessageResolvable, LaunchActivityOptions, ApplicationCommandOptionChoiceData, DiscordAPIError } from 'discord.js';
|
|
3
3
|
import { ReactionHandlerAction, CommandType } from '../enum/index.cjs';
|
|
4
|
-
import { a8 as Provider, P as ProviderToken } from '../index-
|
|
4
|
+
import { a8 as Provider, P as ProviderToken } from '../index-CqXImwF_.cjs';
|
|
5
5
|
import { CooldownStore, ExecutionContextType, ExecutionContext, CooldownScope, MetadataDecorator, ResponsePhase, ResponseCall } from '../common/index.cjs';
|
|
6
6
|
import { DispatchObserver, GuardInterface, InterceptorInterface, ExceptionFilter, ThemeOverride, ThemeResolvers, ThemeResolver, MessageCommandOptions, MessagePrefix, RootTheme, DeepReadonly, MeoCordTheme } from '../interface/index.cjs';
|
|
7
|
-
export { ao as ClassProvider, F as FactoryProvider, ap as ValueProvider } from '../index-
|
|
7
|
+
export { ao as ClassProvider, F as FactoryProvider, ap as ValueProvider } from '../index-CqXImwF_.cjs';
|
|
8
8
|
import { ThemeCache } from '../common/index.cjs';
|
|
9
9
|
import { Translator } from '../common/index.cjs';
|
|
10
10
|
import '@rsbuild/core';
|
|
@@ -216,6 +216,8 @@ declare class TestingModule {
|
|
|
216
216
|
private readonly services;
|
|
217
217
|
/** How long `close()` waits for the `onShutdown` hooks, as the bot's `shutdownTimeout` does. */
|
|
218
218
|
private readonly shutdownTimeout;
|
|
219
|
+
/** The `app`, whose presenter `init()` makes after the providers, as the bot does. */
|
|
220
|
+
private readonly app?;
|
|
219
221
|
constructor(container: Container, controllers?: readonly (new (...args: any[]) => unknown)[], eventClasses?: readonly (new (...args: any[]) => unknown)[], providers?: ProviderMap, order?: readonly unknown[], messageOptions?: MessageCommandOptions, lifecycle?: readonly LifecycleUnit[],
|
|
220
222
|
/** The lifecycle units the container has constructed, which `close()` shuts down. */
|
|
221
223
|
constructed?: ReadonlySet<unknown>,
|
|
@@ -224,8 +226,12 @@ declare class TestingModule {
|
|
|
224
226
|
/** The app's listed services, made at `init()` as the bot makes them before it logs in. */
|
|
225
227
|
services?: readonly (new (...args: any[]) => unknown)[],
|
|
226
228
|
/** How long `close()` waits for the `onShutdown` hooks, as the bot's `shutdownTimeout` does. */
|
|
227
|
-
shutdownTimeout?: number
|
|
229
|
+
shutdownTimeout?: number,
|
|
230
|
+
/** The `app`, whose presenter `init()` makes after the providers, as the bot does. */
|
|
231
|
+
app?: object | undefined);
|
|
228
232
|
private resolving?;
|
|
233
|
+
/** The instances whose `@On` and `@Once` handlers `emit` runs, read at `init()`. */
|
|
234
|
+
private sources?;
|
|
229
235
|
private readying?;
|
|
230
236
|
private closing?;
|
|
231
237
|
/** The `onReady` hooks' pass, which `close()` waits for, less one whose `onReady` called `close()`. */
|
|
@@ -358,16 +364,24 @@ declare class TestingModule {
|
|
|
358
364
|
* command's or an autocomplete's options, or the handler's customId params with a modal's fields or
|
|
359
365
|
* a select menu's choices.
|
|
360
366
|
* An interaction's customId or command name must be one dispatch routes to the handler, ranking
|
|
361
|
-
* every handler of the module as the bot does; a mock built without one is not checked.
|
|
362
|
-
*
|
|
363
|
-
*
|
|
364
|
-
*
|
|
365
|
-
* the
|
|
366
|
-
*
|
|
367
|
+
* every handler of the module as the bot does; a mock built without one is not checked. An autocomplete is
|
|
368
|
+
* checked by its command path and its focused option: one dispatch gives to another `@Autocomplete` handler,
|
|
369
|
+
* or to none, is refused under `useStrictMocks()`, and otherwise warned about once and run.
|
|
370
|
+
* With a message alone, a patterned `@MessageHandler` gets the params its pattern captures from the content,
|
|
371
|
+
* after the prefix of the module's `app`, with typed params resolved as dispatch resolves them, from the
|
|
372
|
+
* message's guild caches first. A message whose `content` isn't a string, as a mock's without
|
|
373
|
+
* `useStrictMocks()`, gets `{}`. Under strict mocks a message has empty `content`, and a patterned handler
|
|
374
|
+
* rejects it, as dispatch runs no handler for a message with no text: give the mock the `content` the handler
|
|
375
|
+
* takes. A word that is not a value of its type, and a prefixed message that names the command but leaves out
|
|
376
|
+
* a param, go through the handler's filters as a `MessageUsageError`, as dispatch answers them.
|
|
377
|
+
* An `@On` or `@Once` handler no route reaches runs as {@link emit} runs it, as an event with the arguments given,
|
|
378
|
+
* under `useStrictMocks()`; without strict mocks it runs as its first argument's type, and `invoke` warns once
|
|
379
|
+
* where that differs.
|
|
367
380
|
* @returns Whether the handler ran, and the error a filter handled, if any. Rejects with an error no
|
|
368
381
|
* filter handles, or with the error a filter throws: the built-in fallback, which answers such
|
|
369
382
|
* errors in the bot, does not run here. Rejects before running anything with an interaction or a
|
|
370
|
-
* message the handler's route does not match, naming both
|
|
383
|
+
* message the handler's route does not match, naming both, and under `useStrictMocks()` with such an
|
|
384
|
+
* autocomplete. Given fewer arguments than the handler
|
|
371
385
|
* declares, with a first that is neither an interaction nor a message, such as a reaction without its
|
|
372
386
|
* `ReactionEvent`, it rejects under `useStrictMocks()`, and otherwise warns once and runs the handler.
|
|
373
387
|
*
|
|
@@ -394,6 +408,22 @@ declare class TestingModule {
|
|
|
394
408
|
invoke<C extends new (...args: any[]) => unknown, M extends HandlerName<C>>(controller: C, methodName: M, ...args: HandlerArgs<C, M>): Promise<InvocationResult>;
|
|
395
409
|
/** The handlers already warned about for being given fewer arguments than they take, so each is named once. */
|
|
396
410
|
private readonly warnedArgumentCounts;
|
|
411
|
+
/** The `@On` and `@Once` handlers already warned about for running other than as an event, so each is named once. */
|
|
412
|
+
private readonly warnedEventRuns;
|
|
413
|
+
/**
|
|
414
|
+
* Warns once, without strict mocks, that `invoke` runs an event handler other than as the bot does: as the type its
|
|
415
|
+
* first argument gives, or with params it added. Only `invoke` warns, on the test's own call.
|
|
416
|
+
*/
|
|
417
|
+
private warnEventRun;
|
|
418
|
+
/** Runs an `@On` or `@Once` handler as the bot and `emit` do: as an event, with its arguments as given. */
|
|
419
|
+
private runEventHandler;
|
|
420
|
+
/** The autocomplete mismatches already warned about without strict mocks, so each handler and route warns once. */
|
|
421
|
+
private readonly warnedAutocompleteRoutes;
|
|
422
|
+
/**
|
|
423
|
+
* Refuses under strict mocks, and otherwise warns once, an autocomplete dispatch gives to another handler or to none.
|
|
424
|
+
* Without strict mocks the handler still runs, since a test that passes that way would fail.
|
|
425
|
+
*/
|
|
426
|
+
private checkAutocompleteRoute;
|
|
397
427
|
/**
|
|
398
428
|
* Refuses under `useStrictMocks()`, or warns once otherwise, a call that gives a handler fewer arguments than it
|
|
399
429
|
* declares when `invoke` builds none for it, as for a reaction given without its `ReactionEvent`.
|
|
@@ -404,10 +434,17 @@ declare class TestingModule {
|
|
|
404
434
|
/** Counts `call` as under way until it settles. */
|
|
405
435
|
private track;
|
|
406
436
|
/**
|
|
407
|
-
* Makes this module the app of the input's client, as the bot is of its own
|
|
408
|
-
*
|
|
437
|
+
* Makes this module the app of the input's client, as the bot is of its own: its answers are drawn by this
|
|
438
|
+
* module's presenter, in its theme and language, `respond()` outside any call included, as in a collector's callback
|
|
439
|
+
* on that client. A module without a presenter clears the client's under strict mocks, so the default draws; default
|
|
440
|
+
* mode leaves another module's in place and warns once.
|
|
409
441
|
*/
|
|
410
442
|
private registerClient;
|
|
443
|
+
/**
|
|
444
|
+
* Makes this module the app of each event argument's client, as the bot is of its own, under strict mocks; default
|
|
445
|
+
* mode leaves the clients as they are and warns once where this module would draw answers otherwise.
|
|
446
|
+
*/
|
|
447
|
+
private registerEventClients;
|
|
411
448
|
private builtComponentRoutes?;
|
|
412
449
|
/** The module's component routes, ranked as dispatch ranks them; throws, as the bot would, for two of one shape. */
|
|
413
450
|
private componentRoutes;
|
|
@@ -451,8 +488,9 @@ declare class TestingModule {
|
|
|
451
488
|
/**
|
|
452
489
|
* Emits a client event to the module's `@On` and `@Once` handlers, through the pipeline the app runs
|
|
453
490
|
* them in up to its event fallback: the global guards of the module's `app`, then each handler's own.
|
|
454
|
-
*
|
|
455
|
-
*
|
|
491
|
+
* As on the bot, every instance the module runs lifecycle hooks on, the cooldown store aside, receives
|
|
492
|
+
* it: the controllers and services, what they and the stages inject, and each provided class or value.
|
|
493
|
+
* A `@Once` handler handles only the first event, as it would on a client.
|
|
456
494
|
*
|
|
457
495
|
* The bot's event fallback doesn't run here. On a bot, a guard's `GuardDeniedError` is logged and the
|
|
458
496
|
* event skipped, and a handler's `UserError` is logged and, when the event carries a message, answered
|
|
@@ -519,7 +557,9 @@ declare class TestingModuleBuilder {
|
|
|
519
557
|
/**
|
|
520
558
|
* Replaces a provider with a test double.
|
|
521
559
|
*
|
|
522
|
-
* The double needs only the members the test uses; misspelled member names are still rejected.
|
|
560
|
+
* The double needs only the members the test uses; misspelled member names are still rejected. A token MeoCord binds
|
|
561
|
+
* itself, such as `ShardContext` or `HandlerRegistry`, takes the double in place of MeoCord's own, so a test can stub
|
|
562
|
+
* cross-shard calls.
|
|
523
563
|
*
|
|
524
564
|
* @param token - The provider to replace.
|
|
525
565
|
* @example
|
|
@@ -747,9 +787,9 @@ type Implementation<T> = {
|
|
|
747
787
|
* @see {@link MockState}
|
|
748
788
|
*/
|
|
749
789
|
interface MockResult<T = unknown> {
|
|
750
|
-
/** `'return'` when the call returned, `'throw'` when it threw. */
|
|
751
|
-
type: 'return' | 'throw';
|
|
752
|
-
/** What the call returned, or the error it threw. */
|
|
790
|
+
/** `'return'` when the call returned, `'throw'` when it threw, `'incomplete'` while it is still running. */
|
|
791
|
+
type: 'return' | 'throw' | 'incomplete';
|
|
792
|
+
/** What the call returned, or the error it threw; `undefined` while it is incomplete. */
|
|
753
793
|
value: T;
|
|
754
794
|
}
|
|
755
795
|
/**
|
|
@@ -1108,12 +1148,14 @@ type NotRaw<T> = T extends {
|
|
|
1108
1148
|
* collections of what it picks, each empty unless given. Other data Discord always sends reads as Discord sends it,
|
|
1109
1149
|
* such as `false` for a flag and `null` for what may be absent; what picks the handler, `commandName` or `customId`, is
|
|
1110
1150
|
* the test's to give. Replies follow Discord's order, so a second `reply()` rejects, and {@link getResponse} reports
|
|
1111
|
-
* every answer the interaction got
|
|
1112
|
-
*
|
|
1113
|
-
* `
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1116
|
-
*
|
|
1151
|
+
* every answer the interaction got; under `useStrictMocks()`, `launchActivity()`, `sendPremiumRequired()` and an
|
|
1152
|
+
* autocomplete's `respond()` count as answers too. Under `useStrictMocks()` an answer marks the interaction `replied`,
|
|
1153
|
+
* `deferred` or, for an autocomplete, `responded` once it resolves, as discord.js does after Discord takes it: an edit
|
|
1154
|
+
* or follow-up made before then rejects with `InteractionNotReplied`, and a second answer sent while the first is in
|
|
1155
|
+
* flight is refused with Discord's 40060. In default mode the mark is made at the call, with a warning where a bot
|
|
1156
|
+
* would fail. Every method is a mock function, and one that returns a promise in discord.js resolves. What the mock
|
|
1157
|
+
* computes for itself, such as `memberPermissions` and `appPermissions`, calls none of them and caches nothing, so a
|
|
1158
|
+
* stub a test sets stays for its own code.
|
|
1117
1159
|
*
|
|
1118
1160
|
* An answer keeps that order whatever it is set to do: one a test gives a value with `mockResolvedValue` replies or
|
|
1119
1161
|
* defers as a real one would, and one that rejects changes nothing. `fetchReply()` reads back what `reply()` or
|
|
@@ -1316,14 +1358,16 @@ interface MockGuildOverrides {
|
|
|
1316
1358
|
* A manager's `fetch(id)` resolves to its cached item with that id, as discord.js looks there first, or to a new one it
|
|
1317
1359
|
* caches under that id: a member, channel, emoji, sticker, scheduled event or AutoMod rule in this guild, a role with
|
|
1318
1360
|
* that id, a ban, or an invite with that code. `members.fetch({ user: ids })` resolves to a collection of each of those
|
|
1319
|
-
* members, found or made the same way; `create()`
|
|
1320
|
-
* as discord.js does, but for an invite, made for the channel given and
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1361
|
+
* members, found or made the same way; `create()` resolves to a mock of its item, a channel of the type its options
|
|
1362
|
+
* name under `useStrictMocks()`, which it caches as discord.js does, but for an invite, made for the channel given and
|
|
1363
|
+
* cached nowhere; `edit()` resolves under `useStrictMocks()` to the item with the id given, found or made the same way,
|
|
1364
|
+
* and under `useStrictMocks()` either takes the `name` its options give. A list fetch resolves to an empty collection.
|
|
1365
|
+
* Members, roles and channels given are put in their managers' caches, where dispatch looks first when it resolves a
|
|
1366
|
+
* message's typed params; a member {@link createMockMember} made without a server is in this one. Its `roles.everyone`
|
|
1367
|
+
* is the role given with the guild's id, or else an @everyone role of its own at position 0, in `roles.cache` as
|
|
1368
|
+
* Discord has it. That role has no permissions in default mode; under `useStrictMocks()` it has the ones Discord
|
|
1369
|
+
* gives @everyone in a new server. The guild is named `'Guild'` and its `preferredLocale` is `'en-US'` unless given,
|
|
1370
|
+
* so `t.forGuild(guild)` translates as for a new English server.
|
|
1327
1371
|
*
|
|
1328
1372
|
* The mock makes a member for any id it's asked for, so a test of an id that isn't a member rejects the fetch, as
|
|
1329
1373
|
* `guild.members.fetch.mockRejectedValue(createDiscordError(10007))`, or resolves a collection without that member.
|
|
@@ -1586,7 +1630,8 @@ interface ChatInputOptions {
|
|
|
1586
1630
|
* entity option carries its id in `value` and the object itself, as the gateway sends it: a user option its `user`,
|
|
1587
1631
|
* and in a server its `member` too. A user option's
|
|
1588
1632
|
* `getMember()` is the user's member in the server of the interaction the options are given to, and `null` in a DM;
|
|
1589
|
-
* a member given resolves `getUser()` to its user.
|
|
1633
|
+
* a member given resolves `getUser()` to its user. Under `useStrictMocks()` a user option's `getMentionable()` is its
|
|
1634
|
+
* member too where there is one, as discord.js reads it; default mode returns the user, with a warning once. A getter throws discord.js's type error for an option of another
|
|
1590
1635
|
* type, as discord.js does, required or not. Only a user or member read as a role, or a role read as a user or member,
|
|
1591
1636
|
* is `null`, or that error when required, as the option may be a mentionable one; a plain `{ id }` reads as any entity.
|
|
1592
1637
|
* A whole number is an Integer option and a fraction a Number one, so
|
|
@@ -1594,7 +1639,13 @@ interface ChatInputOptions {
|
|
|
1594
1639
|
*
|
|
1595
1640
|
* The `focused` option reads as Discord sends it, through `getFocused()`, `getFocused(true)` and `data` alike: a
|
|
1596
1641
|
* string, `''` when no value is given, and marked `focused` in `data`. A number given for it is its digits under
|
|
1597
|
-
* `useStrictMocks()`; otherwise it stays the number, with a warning when read.
|
|
1642
|
+
* `useStrictMocks()`; otherwise it stays the number, with a warning when read. Under `useStrictMocks()` `get()` and the
|
|
1643
|
+
* typed getters read it by name from that same option, as discord.js does; one given no value takes the string,
|
|
1644
|
+
* integer and number getters alike. Default mode reads what was given, `null` for no value, with a warning once.
|
|
1645
|
+
*
|
|
1646
|
+
* Given to an `AutocompleteInteraction`, a user, member, role, channel, mentionable or attachment option reads as
|
|
1647
|
+
* Discord sends an autocomplete's options under `useStrictMocks()`: its id alone, in `data` and the handler's params,
|
|
1648
|
+
* with the entity getters returning `null`. Otherwise it keeps the object given, with a warning once.
|
|
1598
1649
|
*
|
|
1599
1650
|
* @typeParam Cached - `any` by default, to match `createMockInteraction(ChatInputCommandInteraction)`; pass it when the
|
|
1600
1651
|
* interaction under test is cache-pinned.
|
|
@@ -1649,6 +1700,7 @@ declare function createChatInputOptions<Cached extends CacheType = any>(opts?: C
|
|
|
1649
1700
|
*
|
|
1650
1701
|
* `invoke` also refuses a call that gives a handler fewer arguments than it declares where it builds none, such as a
|
|
1651
1702
|
* reaction handler given its reaction without its `ReactionEvent`; without strict mocks, it warns once and calls it.
|
|
1703
|
+
* It refuses an autocomplete that dispatch gives to another `@Autocomplete` handler, or to none, the same way.
|
|
1652
1704
|
*
|
|
1653
1705
|
* `compile()` also refuses an `overrideGuard`, `overrideInterceptor` or `overrideFilter` stub without the stage's
|
|
1654
1706
|
* method, `canActivate`, `intercept` or `catch`; without strict mocks, it warns and builds the module.
|
|
@@ -1715,9 +1767,14 @@ interface MessageToResolve {
|
|
|
1715
1767
|
botId?: string;
|
|
1716
1768
|
/**
|
|
1717
1769
|
* Whether the message is a direct message, where `mention: 'only'` does not apply, and a handler that works only in
|
|
1718
|
-
* a server, by its scope or a `member`, `role` or `channel` param in its pattern, is not reached, as dispatch
|
|
1719
|
-
* it
|
|
1720
|
-
*
|
|
1770
|
+
* a server, by its scope or a `member`, `role` or `channel` param in its pattern, is not reached, as dispatch never
|
|
1771
|
+
* runs it: it answers "This command works in a server only." to a message sent with a prefix or a mention, and
|
|
1772
|
+
* nothing to one without, which may be chat. Under `useStrictMocks()` a handler with a required flag of those types,
|
|
1773
|
+
* or one the message gives, is not reached either, as dispatch refuses it the same way; default mode resolves it,
|
|
1774
|
+
* with a warning. Without it, a mention alone starts what it starts in a server, and a handler of any scope may
|
|
1775
|
+
* answer, with a warning where one that works only in a DM does. Under `useStrictMocks()`, the message is read as
|
|
1776
|
+
* sent in a server, as dispatch reads one: such a handler is passed over for one that works there, or resolves to
|
|
1777
|
+
* `undefined`.
|
|
1721
1778
|
*/
|
|
1722
1779
|
dm?: boolean;
|
|
1723
1780
|
}
|
|
@@ -1889,11 +1946,13 @@ declare function createModalFields(values: Record<string, string | string[] | At
|
|
|
1889
1946
|
*
|
|
1890
1947
|
* Use it in a test for a team that wants no fallback in production. It reports the messages a locale lacks, the
|
|
1891
1948
|
* messages the default catalog doesn't have, the plural forms a language needs but a plural lacks, such as `few` for
|
|
1892
|
-
* Russian, a translation of another shape than the default's, a text for a plural or a plural for a text, and each
|
|
1893
|
-
* `{param}` a translation uses that the message it translates doesn't take. An empty translation, `''`, counts
|
|
1894
|
-
* lacking, as the translator reads it as missing. It reads the catalogs' own strings, so it checks the params of a
|
|
1895
|
-
* catalog from a plain variable or a JSON file too, which the compiler can't. An object
|
|
1896
|
-
* its every key is a plural category, so a group with an `other` key is a group
|
|
1949
|
+
* Russian, a translation of another shape than the default's, a text for a plural or a group, or a plural for a text, and each
|
|
1950
|
+
* `{param}` a translation uses that the message it translates doesn't take. An empty translation, `''` or `null`, counts
|
|
1951
|
+
* as lacking, as the translator reads it as missing. It reads the catalogs' own strings, so it checks the params of a
|
|
1952
|
+
* catalog from a plain variable or a JSON file too, which the compiler can't. An object in the default catalog counts as
|
|
1953
|
+
* a plural only when its every key is a plural category, so a group with an `other` key is a group, and a translation
|
|
1954
|
+
* is read by the default catalog's shapes, as the translator reads it: one that keeps only a group's `other` message
|
|
1955
|
+
* lacks the group's other messages.
|
|
1897
1956
|
*
|
|
1898
1957
|
* @remarks
|
|
1899
1958
|
* MeoCord's own texts, a catalog's `meocord` group, fall back to English by design, so only a key MeoCord lacks, and
|
|
@@ -2082,9 +2141,15 @@ interface HandlerInspection {
|
|
|
2082
2141
|
readonly controller: new (...args: any[]) => unknown;
|
|
2083
2142
|
/** The handler method's name. */
|
|
2084
2143
|
readonly methodName: string;
|
|
2085
|
-
/**
|
|
2144
|
+
/**
|
|
2145
|
+
* The guards that run before the handler, in order: global guards, class guards, then method guards. Under
|
|
2146
|
+
* `useStrictMocks()`, only those for the handler's context types.
|
|
2147
|
+
*/
|
|
2086
2148
|
readonly guards: readonly InspectedGuard[];
|
|
2087
|
-
/**
|
|
2149
|
+
/**
|
|
2150
|
+
* The interceptors around the handler, outermost first: global, class, then method interceptors. Under
|
|
2151
|
+
* `useStrictMocks()`, only those for the handler's context types, and none for an autocomplete.
|
|
2152
|
+
*/
|
|
2088
2153
|
readonly interceptors: readonly InspectedInterceptor[];
|
|
2089
2154
|
/**
|
|
2090
2155
|
* The exception filters for the handler, in the order they are tried: the method's, then the
|
|
@@ -2097,11 +2162,16 @@ interface HandlerInspection {
|
|
|
2097
2162
|
readonly pattern: string | undefined;
|
|
2098
2163
|
/**
|
|
2099
2164
|
* The routes the handler answers because a class its controller extends declares them, such as `slash "ping"`:
|
|
2100
|
-
* those its own class doesn't declare for it. Empty for a handler that declares all it answers.
|
|
2101
|
-
* `
|
|
2165
|
+
* those its own class doesn't declare for it. Empty for a handler that declares all it answers. Under
|
|
2166
|
+
* `useStrictMocks()` it names an inherited `@On` or `@Once` event too, such as `event "guildCreate"`; default mode
|
|
2167
|
+
* leaves events out, with a warning once where it would name one. A test reads it; `toEqual` doesn't compare it, so
|
|
2168
|
+
* an assertion on the other fields holds either way.
|
|
2102
2169
|
*/
|
|
2103
2170
|
readonly inheritedRoutes: readonly string[];
|
|
2104
|
-
/**
|
|
2171
|
+
/**
|
|
2172
|
+
* The `app`'s observers, in the order they are told about the call; empty without an `app`. Under `useStrictMocks()`,
|
|
2173
|
+
* only those whose `types` include the handler's.
|
|
2174
|
+
*/
|
|
2105
2175
|
readonly observers: readonly (new (...args: any[]) => DispatchObserver)[];
|
|
2106
2176
|
/**
|
|
2107
2177
|
* Reads a metadata value as `ExecutionContext.get` does: the method's value, else the controller's.
|
|
@@ -2169,8 +2239,10 @@ interface InspectHandlerOptions {
|
|
|
2169
2239
|
* Reports what runs when a handler is dispatched, and the metadata declared on it, without running anything.
|
|
2170
2240
|
*
|
|
2171
2241
|
* Use it to check that decorators set a handler up as intended: its guards with their params, its interceptors,
|
|
2172
|
-
* filters and cooldowns, in the order dispatch applies them.
|
|
2173
|
-
*
|
|
2242
|
+
* filters and cooldowns, in the order dispatch applies them. Under `useStrictMocks()`, the guards, interceptors and
|
|
2243
|
+
* observers are those dispatch runs for the handler's context types: a stage declared with `types` is listed only for
|
|
2244
|
+
* a handler of one of them, and an autocomplete lists no interceptors. Default mode lists every one, with a warning
|
|
2245
|
+
* once where dispatch runs fewer. To check what a handler does, run it with {@link TestingModule.invoke}.
|
|
2174
2246
|
*
|
|
2175
2247
|
* @param controller - The controller class declaring the handler.
|
|
2176
2248
|
* @param methodName - The handler method's name.
|
|
@@ -2215,7 +2287,8 @@ interface ResponseReport {
|
|
|
2215
2287
|
/**
|
|
2216
2288
|
* Every answer call the interaction got, through `respond()` or discord.js directly, in order: the payload it sent,
|
|
2217
2289
|
* without `withResponse`, and the `error` of one Discord refused. Checking a call's `method` types its `payload` as
|
|
2218
|
-
* that method takes it: the options of a reply, an edit or a deferral, the modal shown,
|
|
2290
|
+
* that method takes it: the options of a reply, an edit or a deferral, the modal shown, the message deleted, or an
|
|
2291
|
+
* autocomplete's choices.
|
|
2219
2292
|
*/
|
|
2220
2293
|
calls: readonly ((ResponseCall & {
|
|
2221
2294
|
method: 'reply' | 'followUp';
|
|
@@ -2241,15 +2314,25 @@ interface ResponseReport {
|
|
|
2241
2314
|
}) | (ResponseCall & {
|
|
2242
2315
|
method: 'deleteReply';
|
|
2243
2316
|
payload?: MessageResolvable | '@original';
|
|
2317
|
+
}) | (ResponseCall & {
|
|
2318
|
+
method: 'launchActivity';
|
|
2319
|
+
payload?: Omit<LaunchActivityOptions, 'withResponse'>;
|
|
2320
|
+
}) | (ResponseCall & {
|
|
2321
|
+
method: 'sendPremiumRequired';
|
|
2322
|
+
payload?: undefined;
|
|
2323
|
+
}) | (ResponseCall & {
|
|
2324
|
+
method: 'respond';
|
|
2325
|
+
payload?: readonly ApplicationCommandOptionChoiceData[];
|
|
2244
2326
|
}))[];
|
|
2245
2327
|
}
|
|
2246
2328
|
/**
|
|
2247
2329
|
* Reports how an interaction was answered: where its answer stands, and every answer call it got, in order.
|
|
2248
2330
|
*
|
|
2249
2331
|
* Use it after `invoke` or `dispatch` to check what the member sees. A mock interaction records each `reply`,
|
|
2250
|
-
* `deferReply`, `editReply`, `followUp`, `deleteReply`, `update`, `deferUpdate` and `showModal`,
|
|
2251
|
-
*
|
|
2252
|
-
*
|
|
2332
|
+
* `deferReply`, `editReply`, `followUp`, `deleteReply`, `update`, `deferUpdate` and `showModal`, and under
|
|
2333
|
+
* `useStrictMocks()` each `launchActivity`, `sendPremiumRequired` and autocomplete `respond` too, whether the handler made
|
|
2334
|
+
* it through `respond()` or with discord.js directly, so both are reported, each once. For a message or a reaction, read
|
|
2335
|
+
* the mock's own methods.
|
|
2253
2336
|
*
|
|
2254
2337
|
* @param interaction - The interaction a handler answered.
|
|
2255
2338
|
* @returns The state, whether anything the member can see was sent, and the calls, in order.
|