@seedcord/gateway 0.1.0-next.1 → 0.1.0-next.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/dist/index.cjs +989 -1268
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +373 -723
- package/dist/index.mjs +914 -1189
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -12
package/dist/index.d.mts
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { CoordinatedShutdown, CoordinatedStartup, Logger, StartupPhase } from "@seedcord/services";
|
|
1
|
+
import { AnyCustomId, AutocompletableNames, BaseReplySender, ChoiceValueOf, EntryFor, FocusedField, GateFitsWith, HasComponentDefs, MatchArms, ModalLike, PageCursor, SingleParams, SlashOptions as SlashOptions$1 } from "@seedcord/core/internal";
|
|
2
|
+
import { AutocompleteOptions, BaseHandler, BuilderComponent, CoreBase, DispatchContext, Gate, GateContextBase, GateNoticeOptions, GuildPermissionsContext, Notice, PageView, PermissionScope, RepliableHandler as RepliableHandler$1, RequiredOf, SelectMenuKind, SlashOptionRegistry } from "@seedcord/core";
|
|
3
|
+
import { Logger } from "@seedcord/logger";
|
|
5
4
|
import { ActionRowBuilder, ButtonBuilder, ContextMenuCommandBuilder, SlashCommandBuilder } from "@discordjs/builders";
|
|
6
|
-
import {
|
|
7
|
-
import { HmrAware, HmrUpdateEvent, SeedcordBrand, SeedcordInstance } from "@seedcord/types/internal";
|
|
5
|
+
import { APIInteractionGuildMember, APIMessageComponentEmoji, APIModalInteractionResponseCallbackData, AnySelectMenuInteraction, ApplicationCommand, ApplicationCommandOptionChoiceData, ApplicationCommandType, ApplicationEmoji, AutocompleteInteraction, BooleanCache, ButtonInteraction, ButtonStyle, CacheType, CacheTypeReducer, ChannelSelectMenuInteraction, ChatInputCommandInteraction, Client, ClientEvents, ClientOptions, Collection, CommandInteractionOption, ContextMenuCommandInteraction, Events, Guild, GuildEmoji, GuildMember, Interaction, MentionableSelectMenuInteraction, Message, MessageContextMenuCommandInteraction, ModalSubmitInteraction, Role, RoleSelectMenuInteraction, Snowflake, StringSelectMenuInteraction, TextChannel, TextChannelResolvable, User, UserContextMenuCommandInteraction, UserSelectMenuInteraction } from "discord.js";
|
|
8
6
|
import { UUID } from "node:crypto";
|
|
9
|
-
import {
|
|
10
|
-
|
|
7
|
+
import { EventMap, NoEvents, TypedEventEmitter } from "@seedcord/event-emitter";
|
|
8
|
+
import { APIMessageTopLevelComponent } from "discord-api-types/v10";
|
|
9
|
+
import { CoordinatedShutdown, CoordinatedStartup, ShutdownPhase, StartupPhase, StartupPhase as StartupPhase$1 } from "@seedcord/core/node";
|
|
10
|
+
import { SeedcordBrand, SeedcordInstance } from "@seedcord/types/internal";
|
|
11
|
+
import { BotConfig, Config, DeferOpts, EmojiMap, HmrAware, HmrUpdateEvent, IRateLimiter, ReplyResponse, SendOpts, Tail, V2Component } from "@seedcord/types";
|
|
11
12
|
export * from "@seedcord/errors";
|
|
12
|
-
export * from "@seedcord/
|
|
13
|
-
export * from "@seedcord/
|
|
13
|
+
export * from "@seedcord/core";
|
|
14
|
+
export * from "@seedcord/logger";
|
|
14
15
|
export * from "@seedcord/event-emitter";
|
|
16
|
+
export * from "@seedcord/utils";
|
|
15
17
|
export * from "@seedcord/rate-limiter";
|
|
16
18
|
export type * from "@seedcord/types";
|
|
17
19
|
|
|
@@ -57,7 +59,6 @@ interface GatewayConfig extends Config {
|
|
|
57
59
|
}
|
|
58
60
|
//#endregion
|
|
59
61
|
//#region src/interfaces/Plugin.d.ts
|
|
60
|
-
/** Interface for objects that can be initialized asynchronously */
|
|
61
62
|
interface Initializeable {
|
|
62
63
|
init(): Promise<void>;
|
|
63
64
|
}
|
|
@@ -69,14 +70,10 @@ interface Initializeable {
|
|
|
69
70
|
*/
|
|
70
71
|
declare abstract class Plugin<TPluginEvents extends EventMap<TPluginEvents> = NoEvents> extends TypedEventEmitter<TPluginEvents> implements Initializeable, HmrAware {
|
|
71
72
|
protected pluggable: Core;
|
|
72
|
-
/** Logger instance for this plugin. */
|
|
73
73
|
abstract logger: Logger;
|
|
74
74
|
name: string;
|
|
75
75
|
constructor(pluggable: Core);
|
|
76
|
-
/**
|
|
77
|
-
* Initialize the plugin.
|
|
78
|
-
* @virtual
|
|
79
|
-
*/
|
|
76
|
+
/** @virtual */
|
|
80
77
|
abstract init(): Promise<void>;
|
|
81
78
|
/**
|
|
82
79
|
* Reloads plugin state on an HMR update. The base implementation is a no-op, override it in your plugin.
|
|
@@ -94,15 +91,13 @@ declare abstract class Plugin<TPluginEvents extends EventMap<TPluginEvents> = No
|
|
|
94
91
|
removeAllListeners(event?: Extract<keyof TPluginEvents, string | symbol>): this;
|
|
95
92
|
}
|
|
96
93
|
/**
|
|
97
|
-
* Constructor type for plugins that can accept
|
|
98
|
-
* @typeParam TPlugin - The plugin type being constructed
|
|
94
|
+
* Constructor type for plugins that can accept extra arguments after Core.
|
|
99
95
|
*
|
|
100
96
|
* @internal
|
|
101
97
|
*/
|
|
102
98
|
type PluginCtor<TPlugin extends Plugin = Plugin> = new (core: Core, ...args: any[]) => TPlugin;
|
|
103
99
|
/**
|
|
104
|
-
* Extracts the argument types for a plugin constructor
|
|
105
|
-
* @typeParam Ctor - The plugin constructor to extract arguments from
|
|
100
|
+
* Extracts the argument types for a plugin constructor, excluding the Core parameter.
|
|
106
101
|
*
|
|
107
102
|
* @internal
|
|
108
103
|
*/
|
|
@@ -143,7 +138,7 @@ declare class Pluggable<TPluggableEvents extends EventMap<TPluggableEvents> = No
|
|
|
143
138
|
* seedcord.attach('db', Mongo, StartupPhase.Configuration, { uri: 'mongodb://...', name: 'seedcord', dir: ... })
|
|
144
139
|
* ```
|
|
145
140
|
*/
|
|
146
|
-
attach<Key extends string, Ctor extends PluginCtor>(this: this, key: Key, Plugin: Ctor, startupPhase: StartupPhase, ...args: PluginArgs<Ctor>): this & Record<Key, InstanceType<Ctor>>;
|
|
141
|
+
attach<Key extends string, Ctor extends PluginCtor>(this: this, key: Key, Plugin: Ctor, startupPhase: StartupPhase$1, ...args: PluginArgs<Ctor>): this & Record<Key, InstanceType<Ctor>>;
|
|
147
142
|
/** @internal */
|
|
148
143
|
removeListener<TEventKey extends Extract<keyof TPluggableEvents, string | symbol>>(event: TEventKey, listener: (...args: TPluggableEvents[TEventKey]) => void): this;
|
|
149
144
|
/** @internal */
|
|
@@ -152,7 +147,7 @@ declare class Pluggable<TPluggableEvents extends EventMap<TPluggableEvents> = No
|
|
|
152
147
|
//#endregion
|
|
153
148
|
//#region src/subscribers/types/Subscriptions.d.ts
|
|
154
149
|
/**
|
|
155
|
-
* Where a reported fault came from.
|
|
150
|
+
* Where a reported fault came from.
|
|
156
151
|
*/
|
|
157
152
|
type FaultSource = InteractionFaultSource | EventFaultSource;
|
|
158
153
|
/**
|
|
@@ -160,19 +155,16 @@ type FaultSource = InteractionFaultSource | EventFaultSource;
|
|
|
160
155
|
*/
|
|
161
156
|
interface InteractionFaultSource {
|
|
162
157
|
kind: 'interaction';
|
|
163
|
-
/** Which interaction kind produced the fault. */
|
|
164
158
|
interactionKind: 'slash' | 'context-menu' | 'button' | 'select' | 'modal';
|
|
165
159
|
/** Slash or context-menu command name, null for component and modal interactions. */
|
|
166
160
|
command: string | null;
|
|
167
161
|
/** Component or modal customId, null for slash and context-menu interactions. */
|
|
168
162
|
customId: string | null;
|
|
169
|
-
/** User who triggered the interaction. */
|
|
170
163
|
userId: string;
|
|
171
164
|
/** Guild the interaction came from, null in DMs. */
|
|
172
165
|
guildId: string | null;
|
|
173
166
|
/** Channel the interaction came from, null when unavailable. */
|
|
174
167
|
channelId: string | null;
|
|
175
|
-
/** The interaction's own id. */
|
|
176
168
|
interactionId: string;
|
|
177
169
|
/** The raw interaction, made JSON-safe at serialization with filterCirculars. */
|
|
178
170
|
raw: unknown;
|
|
@@ -185,25 +177,26 @@ interface EventFaultSource {
|
|
|
185
177
|
kind: 'event';
|
|
186
178
|
eventName: string;
|
|
187
179
|
handler: string;
|
|
188
|
-
/** Actor derived from the event args, null when none is present. */
|
|
189
180
|
userId: string | null;
|
|
190
|
-
/**
|
|
181
|
+
/** Null outside a guild. */
|
|
191
182
|
guildId: string | null;
|
|
192
|
-
/** Channel derived from the event args, null when none is present. */
|
|
193
183
|
channelId: string | null;
|
|
194
184
|
/** The raw event args, made JSON-safe at serialization with filterCirculars. */
|
|
195
185
|
raw: unknown;
|
|
196
186
|
}
|
|
197
|
-
/**
|
|
198
|
-
* Default subscribers that are always available in the framework.
|
|
199
|
-
*/
|
|
200
187
|
interface DefaultSubscriptions {
|
|
201
188
|
/** Triggered when an unhandled exception (a raw non-Notice throw) occurs */
|
|
202
189
|
unknownException: {
|
|
203
190
|
uuid: UUID;
|
|
204
191
|
error: Error;
|
|
205
|
-
guild
|
|
206
|
-
|
|
192
|
+
guild?: {
|
|
193
|
+
id: string;
|
|
194
|
+
name: string;
|
|
195
|
+
} | undefined;
|
|
196
|
+
user?: {
|
|
197
|
+
id: string;
|
|
198
|
+
username: string;
|
|
199
|
+
} | undefined;
|
|
207
200
|
metadata?: unknown;
|
|
208
201
|
};
|
|
209
202
|
/** Triggered when a reported Notice (`report: true`) is caught */
|
|
@@ -214,51 +207,35 @@ interface DefaultSubscriptions {
|
|
|
214
207
|
};
|
|
215
208
|
}
|
|
216
209
|
/**
|
|
217
|
-
* Custom subscribers defined by the application.
|
|
218
|
-
*
|
|
219
|
-
* This interface can be augmented via declaration merging to add
|
|
220
|
-
* type-safe custom subscriber definitions for emitting custom subscribers anywhere in the application.
|
|
210
|
+
* Custom subscribers defined by the application. Augment it via declaration merging to type your
|
|
211
|
+
* own subscriber payloads.
|
|
221
212
|
*
|
|
222
213
|
* @example
|
|
223
214
|
* ```typescript
|
|
224
215
|
* declare module '@seedcord/gateway' {
|
|
225
216
|
* interface Subscriptions {
|
|
226
|
-
* 'userJoin': {
|
|
227
|
-
* 'levelUp': {
|
|
217
|
+
* 'userJoin': { userId: string; guildId: string };
|
|
218
|
+
* 'levelUp': { userId: string; level: number };
|
|
228
219
|
* }
|
|
229
220
|
* }
|
|
230
221
|
* ```
|
|
231
222
|
*/
|
|
232
223
|
interface Subscriptions {}
|
|
233
|
-
/**
|
|
234
|
-
* Combined subscribers interface containing both default and custom subscribers.
|
|
235
|
-
*/
|
|
236
224
|
interface AllSubscriptions extends DefaultSubscriptions, Subscriptions {}
|
|
237
|
-
/**
|
|
238
|
-
* Helper type to extract all available subscriber event names.
|
|
239
|
-
*/
|
|
225
|
+
/** All subscriber event names available to publish and augment. */
|
|
240
226
|
type SubscriptionKey = keyof AllSubscriptions;
|
|
241
227
|
/**
|
|
242
|
-
*
|
|
228
|
+
* The payload type for a subscriber event.
|
|
243
229
|
*
|
|
244
230
|
* @typeParam KeyOfSubscribers - The subscriber event name
|
|
245
231
|
*/
|
|
246
232
|
type SubscriptionData<KeyOfSubscribers extends SubscriptionKey> = AllSubscriptions[KeyOfSubscribers];
|
|
247
|
-
/**
|
|
248
|
-
* Event map for Bus, compatible with TypedEventEmitter.
|
|
249
|
-
*
|
|
250
|
-
* @internal
|
|
251
|
-
*/
|
|
252
233
|
type SubscriptionTuples = { [K in SubscriptionKey]: [AllSubscriptions[K]] };
|
|
253
234
|
//#endregion
|
|
254
235
|
//#region src/subscribers/Bus.d.ts
|
|
255
236
|
/**
|
|
256
|
-
*
|
|
257
|
-
*
|
|
258
|
-
* Provides a centralized system for registering and executing custom subscribers
|
|
259
|
-
* throughout the application lifecycle. Bus subscribers are loaded from configured directories
|
|
260
|
-
* and can be triggered programmatically or by framework events. Accessed via `core.bus`. Do not
|
|
261
|
-
* construct it directly.
|
|
237
|
+
* Registers and dispatches subscribers. Subscribers load from the configured directories and run
|
|
238
|
+
* on a programmatic or framework-event publish. Accessed via `core.bus`. Do not construct it directly.
|
|
262
239
|
*/
|
|
263
240
|
declare class Bus extends Plugin<SubscriptionTuples> {
|
|
264
241
|
protected core: Core;
|
|
@@ -268,12 +245,15 @@ declare class Bus extends Plugin<SubscriptionTuples> {
|
|
|
268
245
|
private isInitialized;
|
|
269
246
|
private readonly subscribersMap;
|
|
270
247
|
private readonly executedOnceHandlers;
|
|
248
|
+
private readonly webhookProbes;
|
|
271
249
|
private readonly hmrHandler?;
|
|
272
250
|
constructor(core: Core);
|
|
273
251
|
private getArtifacts;
|
|
274
252
|
/** @internal */
|
|
275
253
|
init(): Promise<void>;
|
|
276
|
-
/** @internal
|
|
254
|
+
/** @internal Exposed for tests. */
|
|
255
|
+
verifyWebhooks(): Promise<void>;
|
|
256
|
+
/** @internal */
|
|
277
257
|
onHmr(event: HmrUpdateEvent): Promise<void>;
|
|
278
258
|
private loadSubscribers;
|
|
279
259
|
private registerSubscriber;
|
|
@@ -343,12 +323,15 @@ declare class CommandRegistry implements Initializeable, HmrAware {
|
|
|
343
323
|
readonly globalCommands: (SlashCommandBuilder | ContextMenuCommandBuilder)[];
|
|
344
324
|
readonly guildCommands: Collection<string, (SlashCommandBuilder | ContextMenuCommandBuilder)[]>;
|
|
345
325
|
private readonly ctorToCommand;
|
|
326
|
+
private loading;
|
|
327
|
+
private readonly loadedCommands;
|
|
346
328
|
private readonly hmrHandler?;
|
|
347
329
|
private readonly pendingEvents;
|
|
348
330
|
constructor(core: Core, onDeployed?: ((result: DeployResult) => void) | undefined);
|
|
349
331
|
private getArtifacts;
|
|
350
332
|
/** @internal */
|
|
351
333
|
init(): Promise<void>;
|
|
334
|
+
private reportLoad;
|
|
352
335
|
/** @internal */
|
|
353
336
|
refresh(shouldRefresh?: boolean): Promise<void>;
|
|
354
337
|
/** @internal */
|
|
@@ -402,6 +385,8 @@ interface BotEvents {
|
|
|
402
385
|
'any:event': { [K in keyof ClientEvents]: [K, ...ClientEvents[K]] }[keyof ClientEvents];
|
|
403
386
|
/** Emitted for any interaction */
|
|
404
387
|
'any:interaction': [interaction: Interaction];
|
|
388
|
+
/** @internal */
|
|
389
|
+
ready: [];
|
|
405
390
|
}
|
|
406
391
|
/**
|
|
407
392
|
* Discord bot implementation that manages client and controllers
|
|
@@ -459,30 +444,19 @@ declare class Bot extends Plugin<BotEvents> {
|
|
|
459
444
|
protected onListenerError(error: unknown, event: string | symbol): void;
|
|
460
445
|
}
|
|
461
446
|
//#endregion
|
|
462
|
-
//#region src/handlers/
|
|
447
|
+
//#region src/handlers/interactionTypes.d.ts
|
|
463
448
|
type ValidInteractionTypes = ChatInputCommandInteraction | ButtonInteraction | ModalSubmitInteraction | AutocompleteInteraction | AnySelectMenuInteraction | ContextMenuCommandInteraction;
|
|
464
449
|
type ValidNonInteractionKeys = Exclude<keyof ClientEvents, Events.InteractionCreate>;
|
|
465
450
|
type ValidEventTypes = ValidInteractionTypes | ClientEvents[ValidNonInteractionKeys];
|
|
466
451
|
type Repliables = Exclude<ValidInteractionTypes, AutocompleteInteraction>;
|
|
467
452
|
type NonModalInteraction = Exclude<Repliables, ModalSubmitInteraction>;
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
execute(): Promise<void>;
|
|
471
|
-
}
|
|
453
|
+
//#endregion
|
|
454
|
+
//#region src/handlers/BaseHandler.d.ts
|
|
472
455
|
/**
|
|
473
|
-
*
|
|
456
|
+
* The gateway base, fixes the core base's `TCore` to the gateway {@link Core} and adds the `getEvent`
|
|
457
|
+
* gate hook.
|
|
474
458
|
*/
|
|
475
|
-
declare abstract class BaseHandler<ValidEvent extends ValidEventTypes>
|
|
476
|
-
readonly core: Core;
|
|
477
|
-
protected readonly event: ValidEvent;
|
|
478
|
-
protected readonly logger: Logger;
|
|
479
|
-
protected readonly dispatch?: DispatchContext | undefined;
|
|
480
|
-
protected constructor(event: ValidEvent, core: Core, dispatch?: DispatchContext);
|
|
481
|
-
/**
|
|
482
|
-
* Holds the main logic of your handler. The dispatcher calls it after the handler's gates pass, so a
|
|
483
|
-
* gate that refuses stops `execute()` from running.
|
|
484
|
-
*/
|
|
485
|
-
abstract execute(): Promise<void>;
|
|
459
|
+
declare abstract class BaseHandler$1<ValidEvent extends ValidEventTypes> extends BaseHandler<ValidEvent, Core> {
|
|
486
460
|
/** @internal */
|
|
487
461
|
getEvent(): ValidEvent;
|
|
488
462
|
}
|
|
@@ -685,7 +659,7 @@ type EventMatchArms<Names extends ValidNonInteractionKeys, Ret> = { [Name in Nam
|
|
|
685
659
|
* }
|
|
686
660
|
* ```
|
|
687
661
|
*/
|
|
688
|
-
declare abstract class EventHandler<Names extends ValidNonInteractionKeys> extends BaseHandler<ClientEvents[Names]>
|
|
662
|
+
declare abstract class EventHandler<Names extends ValidNonInteractionKeys> extends BaseHandler$1<ClientEvents[Names]> {
|
|
689
663
|
private readonly firedEvent;
|
|
690
664
|
constructor(event: ClientEvents[Names], core: Core, eventName?: Names);
|
|
691
665
|
protected readonly event: SingleEventPayload<Names>;
|
|
@@ -729,7 +703,7 @@ declare abstract class EventHandler<Names extends ValidNonInteractionKeys> exten
|
|
|
729
703
|
*
|
|
730
704
|
* @typeParam EventName - One or more `ClientEvents` keys. Defaults to every event (catchall).
|
|
731
705
|
*/
|
|
732
|
-
declare abstract class EventMiddleware<in out EventName extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends BaseHandler<ClientEvents[EventName]>
|
|
706
|
+
declare abstract class EventMiddleware<in out EventName extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends BaseHandler$1<ClientEvents[EventName]> {
|
|
733
707
|
private readonly firedEvent;
|
|
734
708
|
constructor(event: ClientEvents[EventName], core: Core, eventName?: EventName);
|
|
735
709
|
protected readonly event: SingleEventPayload<EventName>;
|
|
@@ -803,8 +777,8 @@ declare function RegisterEvent<const Defs extends readonly EventSpec<ValidNonInt
|
|
|
803
777
|
//#endregion
|
|
804
778
|
//#region src/bot/gates/Gate.d.ts
|
|
805
779
|
/**
|
|
806
|
-
* The interaction arm. It extends
|
|
807
|
-
* the
|
|
780
|
+
* The interaction arm. It extends {@link GuildPermissionsContext} with the live interaction and
|
|
781
|
+
* the djs objects resolved from the gateway cache. `Repliable` is the interaction type the gate
|
|
808
782
|
* supports, inferred from the `ctx` annotation, so a gate reading button-specific fields is rejected
|
|
809
783
|
* on a slash handler. `interaction` is the reply target, so `user` is always present. Use
|
|
810
784
|
* {@link NonModalInteraction} to exclude ModalSubmit when the gate needs a reliable caller member or
|
|
@@ -822,8 +796,8 @@ declare function RegisterEvent<const Defs extends readonly EventSpec<ValidNonInt
|
|
|
822
796
|
* });
|
|
823
797
|
* ```
|
|
824
798
|
*/
|
|
825
|
-
interface InteractionGateContext<Repliable extends Repliables = Repliables> extends
|
|
826
|
-
/**
|
|
799
|
+
interface InteractionGateContext<Repliable extends Repliables = Repliables> extends GuildPermissionsContext {
|
|
800
|
+
/** The literal `'interaction'`. Narrow on it before reading `interaction`. */
|
|
827
801
|
readonly kind: 'interaction';
|
|
828
802
|
/** The running framework, with the gateway's bot and bus. */
|
|
829
803
|
readonly core: Core;
|
|
@@ -837,7 +811,7 @@ interface InteractionGateContext<Repliable extends Repliables = Repliables> exte
|
|
|
837
811
|
readonly member: GuildMember | null;
|
|
838
812
|
}
|
|
839
813
|
/**
|
|
840
|
-
* The event arm. It extends
|
|
814
|
+
* The event arm. It extends {@link GuildPermissionsContext} with the event payload and the djs
|
|
841
815
|
* objects derived from it. `Names` is the event(s) the gate supports, inferred from the `ctx`
|
|
842
816
|
* annotation, so a gate that reads one event's `payload` is rejected on a handler for a different
|
|
843
817
|
* event. The default supports every event.
|
|
@@ -854,8 +828,8 @@ interface InteractionGateContext<Repliable extends Repliables = Repliables> exte
|
|
|
854
828
|
* });
|
|
855
829
|
* ```
|
|
856
830
|
*/
|
|
857
|
-
interface EventGateContext<Names extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends
|
|
858
|
-
/**
|
|
831
|
+
interface EventGateContext<Names extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends GuildPermissionsContext {
|
|
832
|
+
/** The literal `'event'`, narrow on it before reading `payload`. */
|
|
859
833
|
readonly kind: 'event';
|
|
860
834
|
/** The running framework, with the gateway's bot and bus. */
|
|
861
835
|
readonly core: Core;
|
|
@@ -888,18 +862,68 @@ interface EventGateContext<Names extends ValidNonInteractionKeys = ValidNonInter
|
|
|
888
862
|
*/
|
|
889
863
|
type GateContext = InteractionGateContext | EventGateContext;
|
|
890
864
|
//#endregion
|
|
865
|
+
//#region src/bot/ReplySender.d.ts
|
|
866
|
+
/** The created message a gateway reply resolves to. */
|
|
867
|
+
type SentMessage = Message;
|
|
868
|
+
/**
|
|
869
|
+
* Writes interaction responses through the discord.js interaction. Construction is internal to the repliable
|
|
870
|
+
* handler bases and the dispatcher.
|
|
871
|
+
*/
|
|
872
|
+
declare class ReplySender extends BaseReplySender<SentMessage> {
|
|
873
|
+
private readonly interaction;
|
|
874
|
+
constructor(interaction: Repliables, routeId: string);
|
|
875
|
+
protected writeReply(response: ReplyResponse | string, opts?: SendOpts): Promise<SentMessage | undefined>;
|
|
876
|
+
protected writeDefer(opts?: DeferOpts): Promise<void>;
|
|
877
|
+
protected writeDeferUpdate(): Promise<void>;
|
|
878
|
+
protected writeUpdate(response: ReplyResponse | string): Promise<SentMessage | undefined>;
|
|
879
|
+
protected writeFollowUp(response: ReplyResponse | string, opts?: SendOpts): Promise<SentMessage>;
|
|
880
|
+
protected writeEditOriginal(response: ReplyResponse | string): Promise<SentMessage>;
|
|
881
|
+
protected writeEditTarget(targetId: string, response: ReplyResponse | string): Promise<SentMessage>;
|
|
882
|
+
protected writeDeleteOriginal(): Promise<void>;
|
|
883
|
+
protected writeDeleteTarget(targetId: string): Promise<void>;
|
|
884
|
+
protected writeModal(data: APIModalInteractionResponseCallbackData): Promise<void>;
|
|
885
|
+
protected guardModalSource(): void;
|
|
886
|
+
private rejectModalSubmit;
|
|
887
|
+
private sourceInteraction;
|
|
888
|
+
private replyOptions;
|
|
889
|
+
private editOptions;
|
|
890
|
+
private updateOptions;
|
|
891
|
+
private createdMessage;
|
|
892
|
+
}
|
|
893
|
+
//#endregion
|
|
894
|
+
//#region src/handlers/RepliableHandler.d.ts
|
|
895
|
+
/**
|
|
896
|
+
* Shared base the repliable interaction handlers extend.
|
|
897
|
+
*
|
|
898
|
+
* Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
|
|
899
|
+
* {@link SelectMenuHandler}, or {@link ContextMenuHandler} instead. This class binds the core reply base
|
|
900
|
+
* to the gateway sender.
|
|
901
|
+
*
|
|
902
|
+
* @typeParam Event - The repliable interaction type this handler processes
|
|
903
|
+
*/
|
|
904
|
+
declare abstract class RepliableHandler<Event extends Repliables> extends RepliableHandler$1<Event, Core, SentMessage, ReplySender> {
|
|
905
|
+
/** @internal */
|
|
906
|
+
getEvent(): Event;
|
|
907
|
+
protected buildSender(event: Event, _core: Core, routeId: string): ReplySender;
|
|
908
|
+
}
|
|
909
|
+
//#endregion
|
|
891
910
|
//#region src/handlers/interaction/InteractionHandler.d.ts
|
|
892
911
|
/**
|
|
893
912
|
* Shared base the typed interaction handlers extend.
|
|
894
913
|
*
|
|
895
|
-
* Not a public entry point.
|
|
896
|
-
* or {@link SelectMenuHandler} instead. This class
|
|
897
|
-
*
|
|
914
|
+
* Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
|
|
915
|
+
* or {@link SelectMenuHandler} instead. This class adds `showModal` on top of the reply members those bases
|
|
916
|
+
* share.
|
|
898
917
|
*
|
|
899
918
|
* @typeParam Repliable - The interaction type this handler processes
|
|
900
919
|
*/
|
|
901
|
-
declare abstract class InteractionHandler<Repliable extends Repliables> extends
|
|
920
|
+
declare abstract class InteractionHandler<Repliable extends Repliables> extends RepliableHandler<Repliable> {
|
|
902
921
|
constructor(event: Repliable, core: Core, dispatch?: DispatchContext);
|
|
922
|
+
/**
|
|
923
|
+
* Open a modal. Must be the initial response to this interaction. The modal kind rejects this call at
|
|
924
|
+
* compile time (Discord forbids a modal in response to a modal).
|
|
925
|
+
*/
|
|
926
|
+
protected showModal(this: InteractionHandler<NonModalInteraction>, modal: ModalLike): Promise<void>;
|
|
903
927
|
}
|
|
904
928
|
//#endregion
|
|
905
929
|
//#region src/bot/gates/matching.d.ts
|
|
@@ -949,189 +973,28 @@ type FitAll<TCtor extends AnyHandlerCtor, Gates extends readonly Gate<GateContex
|
|
|
949
973
|
*/
|
|
950
974
|
declare function Gated<const Gates extends NonEmptyTuple<Gate<GateContextBase>>>(...gates: Gates): <TCtor extends AnyHandlerCtor>(ctor: FitAll<TCtor, Gates> extends Gates ? TCtor : FitAll<TCtor, Gates>) => void;
|
|
951
975
|
//#endregion
|
|
952
|
-
//#region src/
|
|
953
|
-
type Row$2<Route extends keyof SlashOptionRegistry> = SlashOptionRegistry[Route];
|
|
954
|
-
type EntryFor$1<Route extends keyof SlashOptionRegistry, Name extends PropertyKey> = Route extends unknown ? Name extends keyof Row$2<Route> ? Row$2<Route>[Name] : never : never;
|
|
955
|
-
type NamesOfKind$1<Route extends keyof SlashOptionRegistry, Kind extends OptionKind> = Route extends unknown ? { [Name in keyof Row$2<Route>]: Row$2<Route>[Name] extends {
|
|
956
|
-
kind: Kind;
|
|
957
|
-
} ? Name : never }[keyof Row$2<Route>] : never;
|
|
958
|
-
type ResolvedValue$1<Entry> = Entry extends {
|
|
959
|
-
choices: readonly (infer Choice)[];
|
|
960
|
-
} ? Choice : Entry extends {
|
|
961
|
-
kind: 'string';
|
|
962
|
-
} ? string : Entry extends {
|
|
963
|
-
kind: 'integer' | 'number';
|
|
964
|
-
} ? number : Entry extends {
|
|
965
|
-
kind: 'boolean';
|
|
966
|
-
} ? boolean : never;
|
|
967
|
-
type Getter$1<Route extends keyof SlashOptionRegistry, Kind extends OptionKind, Method extends string> = IsNever<NamesOfKind$1<Route, Kind>> extends true ? unknown : Record<Method, <Name extends NamesOfKind$1<Route, Kind>>(name: Name) => ResolvedValue$1<EntryFor$1<Route, Name>> | null>;
|
|
968
|
-
/**
|
|
969
|
-
* The sibling-option view for an autocomplete handler. Only the four kinds Discord resolves during autocomplete
|
|
970
|
-
* appear (string, integer, number, boolean), every read is `T | null` because a sibling is partial while the
|
|
971
|
-
* user types the focused field, and a getter appears only when a registered command has an option of that kind.
|
|
972
|
-
* Across several registered commands the view is the union of their options, so a getter for an option absent on
|
|
973
|
-
* the firing command returns null. Read the focused field from `this.focused`.
|
|
974
|
-
*
|
|
975
|
-
* @typeParam Route - One or more route keys from {@link SlashOptionRegistry}.
|
|
976
|
-
*/
|
|
977
|
-
type AutocompleteOptions<Route extends keyof SlashOptionRegistry> = Getter$1<Route, 'string', 'getString'> & Getter$1<Route, 'integer', 'getInteger'> & Getter$1<Route, 'number', 'getNumber'> & Getter$1<Route, 'boolean', 'getBoolean'>;
|
|
978
|
-
//#endregion
|
|
979
|
-
//#region src/handlers/interaction/AutocompleteHandler.d.ts
|
|
980
|
-
type Row$1<Route extends keyof SlashOptionRegistry> = SlashOptionRegistry[Route];
|
|
981
|
-
type AutocompletableNames<Route extends keyof SlashOptionRegistry> = Route extends unknown ? { [Name in keyof Row$1<Route>]: Row$1<Route>[Name] extends {
|
|
982
|
-
autocomplete: true;
|
|
983
|
-
} ? Name : never }[keyof Row$1<Route>] : never;
|
|
984
|
-
type EntryFor<Route extends keyof SlashOptionRegistry, Name extends PropertyKey> = Route extends unknown ? Name extends keyof Row$1<Route> ? Row$1<Route>[Name] : never : never;
|
|
985
|
-
type ChoiceValueOf<Entry> = Entry extends {
|
|
986
|
-
kind: 'string';
|
|
987
|
-
} ? string : Entry extends {
|
|
988
|
-
kind: 'integer' | 'number';
|
|
989
|
-
} ? number : never;
|
|
990
|
-
/** The focused option. `value` is the raw partial Discord delivers mid-type, always a string regardless of kind. */
|
|
991
|
-
interface FocusedField<Route extends keyof SlashOptionRegistry> {
|
|
992
|
-
name: AutocompletableNames<Route>;
|
|
993
|
-
value: string;
|
|
994
|
-
}
|
|
995
|
-
/** One arm per autocompletable field, `value` is the focused partial, `respond` is pinned to the field's choice type. */
|
|
996
|
-
type FocusedArms<Route extends keyof SlashOptionRegistry, Ret> = { [Name in AutocompletableNames<Route>]: (value: string, respond: (choices: readonly ApplicationCommandOptionChoiceData<ChoiceValueOf<EntryFor<Route, Name>>>[]) => Promise<void>) => Promisable<Ret> };
|
|
997
|
-
/**
|
|
998
|
-
* Base class for a Discord autocomplete handler.
|
|
999
|
-
*
|
|
1000
|
-
* Pass the command route(s) from the generated registry as the generic, the same string(s) as
|
|
1001
|
-
* `@AutocompleteRoute`. Branch on the focused field with `this.match`, read already-entered sibling options
|
|
1002
|
-
* with `this.options`, and find which command fired with `this.route`.
|
|
1003
|
-
*
|
|
1004
|
-
* @typeParam Route - One or more route keys from {@link SlashOptionRegistry}, e.g. `'search'` or `'search' | 'find'`.
|
|
1005
|
-
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1006
|
-
*
|
|
1007
|
-
* @example
|
|
1008
|
-
* ```ts
|
|
1009
|
-
* \@AutocompleteRoute('search')
|
|
1010
|
-
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1011
|
-
* async execute() {
|
|
1012
|
-
* await this.match({
|
|
1013
|
-
* query: (value, respond) => respond([{ name: value, value }])
|
|
1014
|
-
* });
|
|
1015
|
-
* }
|
|
1016
|
-
* }
|
|
1017
|
-
* ```
|
|
1018
|
-
*/
|
|
1019
|
-
declare abstract class AutocompleteHandler<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> extends BaseHandler<AutocompleteInteraction<Cache>> implements Handler {
|
|
1020
|
-
constructor(event: AutocompleteInteraction<Cache>, core: Core, dispatch?: DispatchContext);
|
|
1021
|
-
/**
|
|
1022
|
-
* The focused option for this interaction. `value` is always the raw partial string the user is typing,
|
|
1023
|
-
* even for an integer or number option, so coerce it yourself when you need a number.
|
|
1024
|
-
*/
|
|
1025
|
-
private decodedFocused?;
|
|
1026
|
-
protected get focused(): FocusedField<Route>;
|
|
1027
|
-
/**
|
|
1028
|
-
* Run the arm for the focused field. An autocomplete always dispatches by which field is focused, so
|
|
1029
|
-
* match is how you read it. There is no single-field shortcut the way slash/component handlers have one.
|
|
1030
|
-
*
|
|
1031
|
-
* Provide one arm per autocompletable field across the registered commands, keyed by field name. Each
|
|
1032
|
-
* arm receives the focused partial value and a `respond` pinned to that field's choice value type. The
|
|
1033
|
-
* arms must cover every autocompletable field, a missing field or an unknown key is a compile error. A
|
|
1034
|
-
* focused field with no arm, only reachable from a stale-deployed command, throws at runtime.
|
|
1035
|
-
*
|
|
1036
|
-
* @param arms - One handler per autocompletable field, keyed by field name.
|
|
1037
|
-
* @returns The result of the arm that ran.
|
|
1038
|
-
*
|
|
1039
|
-
* @example
|
|
1040
|
-
* ```ts
|
|
1041
|
-
* \@AutocompleteRoute('search')
|
|
1042
|
-
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1043
|
-
* async execute() {
|
|
1044
|
-
* await this.match({
|
|
1045
|
-
* query: (value, respond) => respond(titles(value).map((s) => ({ name: s, value: s }))),
|
|
1046
|
-
* tag: (value, respond) => respond(tags(value).map((s) => ({ name: s, value: s })))
|
|
1047
|
-
* });
|
|
1048
|
-
* }
|
|
1049
|
-
* }
|
|
1050
|
-
* ```
|
|
1051
|
-
*/
|
|
1052
|
-
protected match<Ret>(arms: FocusedArms<Route, Ret>): Promise<Ret>;
|
|
1053
|
-
/** The firing command route, for a field whose completion differs per registered command. */
|
|
1054
|
-
protected get route(): Route;
|
|
1055
|
-
/**
|
|
1056
|
-
* The already-entered options on this command, restricted to the kinds Discord resolves during autocomplete
|
|
1057
|
-
* (string, integer, number, boolean) with every read nullable, since a sibling is partial while the user
|
|
1058
|
-
* types the focused field. Read the focused field from `this.focused`, not here.
|
|
1059
|
-
*/
|
|
1060
|
-
protected get options(): AutocompleteOptions<Route>;
|
|
1061
|
-
}
|
|
1062
|
-
//#endregion
|
|
1063
|
-
//#region src/handlers/interaction/ContextMenuHandler.d.ts
|
|
1064
|
-
type ContextMenuKind = ApplicationCommandType.User | ApplicationCommandType.Message;
|
|
1065
|
-
type InteractionFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? UserContextMenuCommandInteraction<Cache> : MessageContextMenuCommandInteraction<Cache>;
|
|
1066
|
-
type TargetFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? User : Message<BooleanCache<Cache>>;
|
|
1067
|
-
type TargetMemberFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? CacheTypeReducer<Cache, GuildMember, APIInteractionGuildMember> | null : never;
|
|
976
|
+
//#region src/handlers/interaction/InteractionMiddleware.d.ts
|
|
1068
977
|
/**
|
|
1069
|
-
* Base class for
|
|
1070
|
-
*
|
|
1071
|
-
* Pass the kind from `discord.js`'s {@link ApplicationCommandType} as the generic, the same value as
|
|
1072
|
-
* `@ContextMenuRoute`. Read the right-clicked entity from `this.target`, a `User` for a user menu and a
|
|
1073
|
-
* `Message` for a message menu. Context menus carry no options, so a handler registered for several names
|
|
1074
|
-
* reads `this.target` uniformly with no per-name branch.
|
|
978
|
+
* Base class for interaction middleware
|
|
1075
979
|
*
|
|
1076
|
-
*
|
|
1077
|
-
*
|
|
980
|
+
* Middleware runs before interaction handlers and can modify behavior or block execution.
|
|
981
|
+
* Unlike handlers, middleware should not send responses directly.
|
|
1078
982
|
*
|
|
1079
|
-
* @
|
|
1080
|
-
* ```ts
|
|
1081
|
-
* \@ContextMenuRoute(ApplicationCommandType.Message, 'Report Message')
|
|
1082
|
-
* class ReportMessage extends ContextMenuHandler<ApplicationCommandType.Message> {
|
|
1083
|
-
* async execute() {
|
|
1084
|
-
* const message = this.target;
|
|
1085
|
-
* }
|
|
1086
|
-
* }
|
|
1087
|
-
* ```
|
|
983
|
+
* @typeParam Repliable - The interaction type this middleware processes
|
|
1088
984
|
*/
|
|
1089
|
-
declare abstract class
|
|
1090
|
-
|
|
1091
|
-
/**
|
|
1092
|
-
* The invoking guild member, resolved only on user menus. Reading it on a message menu is a compile
|
|
1093
|
-
* error since the type is `never` there.
|
|
1094
|
-
*/
|
|
1095
|
-
protected get targetMember(): TargetMemberFor<Kind, Cache>;
|
|
985
|
+
declare abstract class InteractionMiddleware<Repliable extends Repliables> extends BaseHandler$1<Repliable> {
|
|
986
|
+
constructor(event: Repliable, core: Core);
|
|
1096
987
|
}
|
|
1097
988
|
//#endregion
|
|
1098
989
|
//#region src/inputs/SlashOptions.d.ts
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
}
|
|
1107
|
-
type: ChannelWireType<Types>;
|
|
1108
|
-
}> : NonNullable<CommandInteractionOption<Cache>['channel']>;
|
|
1109
|
-
type ResolvedValue<Cache extends CacheType, Entry> = Entry extends {
|
|
1110
|
-
choices: readonly (infer Choice)[];
|
|
1111
|
-
} ? Choice : Entry extends {
|
|
1112
|
-
kind: 'string';
|
|
1113
|
-
} ? string : Entry extends {
|
|
1114
|
-
kind: 'integer' | 'number';
|
|
1115
|
-
} ? number : Entry extends {
|
|
1116
|
-
kind: 'boolean';
|
|
1117
|
-
} ? boolean : Entry extends {
|
|
1118
|
-
kind: 'user';
|
|
1119
|
-
} ? NonNullable<CommandInteractionOption<Cache>['user']> : Entry extends {
|
|
1120
|
-
kind: 'channel';
|
|
1121
|
-
} ? ResolvedChannel<Cache, Entry> : Entry extends {
|
|
1122
|
-
kind: 'role';
|
|
1123
|
-
} ? NonNullable<CommandInteractionOption<Cache>['role']> : Entry extends {
|
|
1124
|
-
kind: 'mentionable';
|
|
1125
|
-
} ? NonNullable<CommandInteractionOption<Cache>['member' | 'role' | 'user']> : Entry extends {
|
|
1126
|
-
kind: 'attachment';
|
|
1127
|
-
} ? NonNullable<CommandInteractionOption<Cache>['attachment']> : never;
|
|
1128
|
-
type Returned<Cache extends CacheType, Entry> = Entry extends {
|
|
1129
|
-
required: true;
|
|
1130
|
-
} ? ResolvedValue<Cache, Entry> : ResolvedValue<Cache, Entry> | null;
|
|
1131
|
-
type Getter<Route extends keyof SlashOptionRegistry, Cache extends CacheType, Kind extends OptionKind, Method extends string> = IsNever<NamesOfKind<Route, Kind>> extends true ? unknown : Record<Method, <Name extends NamesOfKind<Route, Kind>>(name: Name) => Returned<Cache, Row<Route>[Name]>>;
|
|
1132
|
-
type MemberGetter<Route extends keyof SlashOptionRegistry, Cache extends CacheType> = IsNever<NamesOfKind<Route, 'user'>> extends true ? unknown : {
|
|
1133
|
-
getMember: <Name extends NamesOfKind<Route, 'user'>>(name: Name) => NonNullable<CommandInteractionOption<Cache>['member']> | null;
|
|
1134
|
-
};
|
|
990
|
+
interface GatewayLens<Cache extends CacheType> {
|
|
991
|
+
user: NonNullable<CommandInteractionOption<Cache>['user']>;
|
|
992
|
+
member: NonNullable<CommandInteractionOption<Cache>['member']>;
|
|
993
|
+
channel: NonNullable<CommandInteractionOption<Cache>['channel']>;
|
|
994
|
+
role: NonNullable<CommandInteractionOption<Cache>['role']>;
|
|
995
|
+
mentionable: NonNullable<CommandInteractionOption<Cache>['member' | 'role' | 'user']>;
|
|
996
|
+
attachment: NonNullable<CommandInteractionOption<Cache>['attachment']>;
|
|
997
|
+
}
|
|
1135
998
|
/**
|
|
1136
999
|
* The typed view over a chat-input command's options for one route. Each getter mirrors the discord.js
|
|
1137
1000
|
* resolver method but restricts its `name` to that route's options of the matching kind, drops the null
|
|
@@ -1144,7 +1007,7 @@ type MemberGetter<Route extends keyof SlashOptionRegistry, Cache extends CacheTy
|
|
|
1144
1007
|
* @typeParam Route - A route key from the generated {@link SlashOptionRegistry}.
|
|
1145
1008
|
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1146
1009
|
*/
|
|
1147
|
-
type SlashOptions<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> =
|
|
1010
|
+
type SlashOptions<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> = SlashOptions$1<Route, GatewayLens<Cache>>;
|
|
1148
1011
|
//#endregion
|
|
1149
1012
|
//#region src/handlers/interaction/SlashHandler.d.ts
|
|
1150
1013
|
type SlashMatchArms<Route extends keyof SlashOptionRegistry, Cache extends CacheType, Ret> = { [Key in Route]: (options: SlashOptions<Key, Cache>) => Promisable<Ret> };
|
|
@@ -1170,6 +1033,8 @@ type SlashMatchArms<Route extends keyof SlashOptionRegistry, Cache extends Cache
|
|
|
1170
1033
|
* ```
|
|
1171
1034
|
*/
|
|
1172
1035
|
declare abstract class SlashHandler<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> extends InteractionHandler<ChatInputCommandInteraction<Cache>> {
|
|
1036
|
+
/** @internal */
|
|
1037
|
+
readonly __slashRoute?: Route;
|
|
1173
1038
|
/**
|
|
1174
1039
|
* The typed options for this command's route. Required options drop the null, choices narrow to their
|
|
1175
1040
|
* literal union, and only the getters for kinds this command actually uses appear. Use `this.event.options`
|
|
@@ -1178,7 +1043,7 @@ declare abstract class SlashHandler<Route extends keyof SlashOptionRegistry, Cac
|
|
|
1178
1043
|
protected get options(): SlashOptions<Route, Cache>;
|
|
1179
1044
|
/**
|
|
1180
1045
|
* Run the arm for whichever command fired. Use this only when the handler is registered for several
|
|
1181
|
-
* routes.
|
|
1046
|
+
* routes.
|
|
1182
1047
|
*
|
|
1183
1048
|
* Provide one arm per registered route, keyed by its route string, and each arm receives that route's
|
|
1184
1049
|
* own narrowed options. The arms must cover every route in the generic, a missing route or an unknown
|
|
@@ -1203,211 +1068,122 @@ declare abstract class SlashHandler<Route extends keyof SlashOptionRegistry, Cac
|
|
|
1203
1068
|
protected match<Ret>(arms: SlashMatchArms<Route, Cache, Ret>): Promise<Ret>;
|
|
1204
1069
|
}
|
|
1205
1070
|
//#endregion
|
|
1206
|
-
//#region src/
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
String = "string",
|
|
1212
|
-
User = "user",
|
|
1213
|
-
Role = "role",
|
|
1214
|
-
Channel = "channel",
|
|
1215
|
-
Mentionable = "mentionable"
|
|
1216
|
-
}
|
|
1217
|
-
/** @internal */
|
|
1218
|
-
type HandlerEventType<TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = InstanceType<TCtor> extends InteractionHandler<infer TEvent> ? TEvent : never;
|
|
1219
|
-
/**
|
|
1220
|
-
* Compile-time assertion that the required event type(s) `TRequired` are included in the handler event union.
|
|
1221
|
-
*
|
|
1222
|
-
* @internal
|
|
1223
|
-
*/
|
|
1224
|
-
type AssertHandles<TRequired, TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = Extract<HandlerEventType<TCtor>, TRequired> extends never ? Constructor<['Handler event generic must include', TRequired]> : TCtor;
|
|
1225
|
-
/**
|
|
1226
|
-
* The slash route(s) a handler serves, read off its `SlashHandler` generic.
|
|
1227
|
-
*
|
|
1228
|
-
* @internal
|
|
1229
|
-
*/
|
|
1230
|
-
type SlashRouteOf<TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = InstanceType<TCtor> extends SlashHandler<infer Route, CacheType> ? Route : never;
|
|
1231
|
-
/**
|
|
1232
|
-
* On a route/generic mismatch, resolves to a non-constructor type so applying the decorator is a TS1238.
|
|
1233
|
-
*
|
|
1234
|
-
* @internal
|
|
1235
|
-
*/
|
|
1236
|
-
type AssertSlashRoute<Route extends string, TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = [Route] extends [SlashRouteOf<TCtor>] ? [SlashRouteOf<TCtor>] extends [Route] ? TCtor : Constructor<['SlashHandler declares a route the SlashRoute decorator does not list', SlashRouteOf<TCtor>]> : Constructor<['SlashRoute does not match the SlashHandler generic', Route]>;
|
|
1237
|
-
/**
|
|
1238
|
-
* Routes one or more slash commands to a {@link SlashHandler}.
|
|
1239
|
-
*
|
|
1240
|
-
* Pass the same route string(s) as the handler's generic. A single command reads `this.options`, several
|
|
1241
|
-
* commands branch with `this.match`. The decorator routes and the generic must match exactly, so listing
|
|
1242
|
-
* fewer or more than the handler declares is a compile error. Subcommands use a slash path.
|
|
1243
|
-
*
|
|
1244
|
-
* @param routes - The route string(s) this handler serves, e.g. `'ban'`, `'ban', 'kick'`, or `'demo/setup'`.
|
|
1245
|
-
* @decorator
|
|
1246
|
-
* @example
|
|
1247
|
-
* ```ts
|
|
1248
|
-
* \@SlashRoute('ban')
|
|
1249
|
-
* class BanHandler extends SlashHandler<'ban'> {
|
|
1250
|
-
* async execute() {
|
|
1251
|
-
* const target = this.options.getUser('target');
|
|
1252
|
-
* }
|
|
1253
|
-
* }
|
|
1254
|
-
* ```
|
|
1255
|
-
*
|
|
1256
|
-
* @example
|
|
1257
|
-
* ```ts
|
|
1258
|
-
* \@SlashRoute('ban', 'kick')
|
|
1259
|
-
* class ModerationHandler extends SlashHandler<'ban' | 'kick'> {
|
|
1260
|
-
* async execute() {
|
|
1261
|
-
* await this.match({ ban: (o) => o.getUser('target'), kick: (o) => o.getUser('member') });
|
|
1262
|
-
* }
|
|
1263
|
-
* }
|
|
1264
|
-
* ```
|
|
1265
|
-
*/
|
|
1266
|
-
declare function SlashRoute<const Route extends keyof SlashOptionRegistry>(...routes: Route[]): <TCtor extends new (...args: any[]) => InteractionHandler<Repliables>>(constructor: AssertSlashRoute<Route, TCtor>) => void;
|
|
1267
|
-
/**
|
|
1268
|
-
* Routes button interactions to handler classes.
|
|
1269
|
-
*
|
|
1270
|
-
* Pass the {@link CustomId} definition(s) this handler decodes and list the same ones in the handler's
|
|
1271
|
-
* generic. Passing different definitions to the decorator and the generic is a compile error. Routing
|
|
1272
|
-
* matches the stable prefix, so a wire minted from an older shape still reaches the handler, where
|
|
1273
|
-
* reading this.params throws StaleCustomId and the controller boundary turns it into a reply.
|
|
1274
|
-
*
|
|
1275
|
-
* @param defs - The customId definition(s) this handler decodes, one per route.
|
|
1276
|
-
* @decorator
|
|
1277
|
-
*/
|
|
1278
|
-
declare function ButtonRoute<const Defs extends readonly AnyCustomId[]>(...defs: Defs): <TCtor extends new (...args: any[]) => InteractionHandler<Repliables> & HasComponentDefs<Defs>>(constructor: AssertHandles<ButtonInteraction, TCtor>) => void;
|
|
1279
|
-
/**
|
|
1280
|
-
* Routes modal submissions to handler classes.
|
|
1281
|
-
*
|
|
1282
|
-
* Pass the {@link CustomId} definition(s) this handler decodes and list the same ones in the handler's
|
|
1283
|
-
* generic. Passing different definitions to the decorator and the generic is a compile error. Routing
|
|
1284
|
-
* matches the stable prefix, so an older-shape wire still reaches the handler and throws StaleCustomId
|
|
1285
|
-
* on read, the same as a button route.
|
|
1286
|
-
*
|
|
1287
|
-
* @param defs - The customId definition(s) this handler decodes, one per route.
|
|
1288
|
-
* @decorator
|
|
1289
|
-
*/
|
|
1290
|
-
declare function ModalRoute<const Defs extends readonly AnyCustomId[]>(...defs: Defs): <TCtor extends new (...args: any[]) => InteractionHandler<Repliables> & HasComponentDefs<Defs>>(constructor: AssertHandles<ModalSubmitInteraction, TCtor>) => void;
|
|
1291
|
-
/** The context-menu command names valid for a kind, read off the matching registry. @internal */
|
|
1292
|
-
type NamesFor<Kind extends ApplicationCommandType.User | ApplicationCommandType.Message> = Kind extends ApplicationCommandType.User ? keyof UserContextMenuRegistry : keyof MessageContextMenuRegistry;
|
|
1293
|
-
/**
|
|
1294
|
-
* The context-menu kind a handler serves, read off its event's `commandType` discriminant. Direct
|
|
1295
|
-
* inference from the `ContextMenuHandler` generic widens the kind to the whole union because the handler's
|
|
1296
|
-
* conditional members blur it, so this uses the event literal to keep it narrow.
|
|
1297
|
-
*
|
|
1298
|
-
* @internal
|
|
1299
|
-
*/
|
|
1300
|
-
type ContextMenuKindOf<TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = InstanceType<TCtor> extends ContextMenuHandler<infer Kind, CacheType> ? [Kind] extends [ApplicationCommandType.User | ApplicationCommandType.Message] ? HandlerEventType<TCtor> extends {
|
|
1301
|
-
commandType: infer K;
|
|
1302
|
-
} ? Extract<K, ApplicationCommandType.User | ApplicationCommandType.Message> : never : never : never;
|
|
1071
|
+
//#region src/handlers/interaction/ContextMenuHandler.d.ts
|
|
1072
|
+
type ContextMenuKind = ApplicationCommandType.User | ApplicationCommandType.Message;
|
|
1073
|
+
type InteractionFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? UserContextMenuCommandInteraction<Cache> : MessageContextMenuCommandInteraction<Cache>;
|
|
1074
|
+
type TargetFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? User : Message<BooleanCache<Cache>>;
|
|
1075
|
+
type TargetMemberFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? CacheTypeReducer<Cache, GuildMember, APIInteractionGuildMember> | null : never;
|
|
1303
1076
|
/**
|
|
1304
|
-
*
|
|
1305
|
-
* applying the decorator is a TS1238. Cross-checks both directions, mirroring {@link AssertSlashRoute}.
|
|
1077
|
+
* Base class for a context-menu command handler (right-click a user or a message).
|
|
1306
1078
|
*
|
|
1307
|
-
* @
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
* Routes one or more context-menu commands to a {@link ContextMenuHandler}.
|
|
1079
|
+
* Pass the kind from `discord.js`'s {@link ApplicationCommandType} as the generic, the same value as
|
|
1080
|
+
* `@ContextMenuRoute`. Read the right-clicked entity from `this.target`, a `User` for a user menu and a
|
|
1081
|
+
* `Message` for a message menu. Context menus carry no options, so a handler registered for several names
|
|
1082
|
+
* reads `this.target` uniformly with no per-name branch.
|
|
1312
1083
|
*
|
|
1313
|
-
*
|
|
1314
|
-
*
|
|
1315
|
-
* handler's generic, cross-checked both directions. Context menus carry no options, so a multi-name handler
|
|
1316
|
-
* reads `this.target` uniformly with no branch.
|
|
1084
|
+
* @typeParam Kind - `ApplicationCommandType.User` or `ApplicationCommandType.Message`.
|
|
1085
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1317
1086
|
*
|
|
1318
|
-
* @param kind - The context-menu kind, `ApplicationCommandType.User` or `ApplicationCommandType.Message`.
|
|
1319
|
-
* @param names - The command name(s) this handler serves, keyed off the matching registry.
|
|
1320
|
-
* @decorator
|
|
1321
1087
|
* @example
|
|
1322
1088
|
* ```ts
|
|
1323
|
-
* \@ContextMenuRoute(ApplicationCommandType.
|
|
1324
|
-
* class
|
|
1089
|
+
* \@ContextMenuRoute(ApplicationCommandType.Message, 'Report Message')
|
|
1090
|
+
* class ReportMessage extends ContextMenuHandler<ApplicationCommandType.Message> {
|
|
1325
1091
|
* async execute() {
|
|
1326
|
-
* const
|
|
1092
|
+
* const message = this.target;
|
|
1327
1093
|
* }
|
|
1328
1094
|
* }
|
|
1329
1095
|
* ```
|
|
1330
1096
|
*/
|
|
1331
|
-
declare
|
|
1332
|
-
/**
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1097
|
+
declare abstract class ContextMenuHandler<Kind extends ContextMenuKind, Cache extends CacheType = 'cached'> extends InteractionHandler<InteractionFor<Kind, Cache>> {
|
|
1098
|
+
/** @internal */
|
|
1099
|
+
readonly __ctxKind?: Kind;
|
|
1100
|
+
protected get target(): TargetFor<Kind, Cache>;
|
|
1101
|
+
/**
|
|
1102
|
+
* The invoking guild member, resolved only on user menus. Reading it on a message menu is a compile
|
|
1103
|
+
* error since the type is `never` there.
|
|
1104
|
+
*/
|
|
1105
|
+
protected get targetMember(): TargetMemberFor<Kind, Cache>;
|
|
1106
|
+
}
|
|
1107
|
+
//#endregion
|
|
1108
|
+
//#region src/handlers/interaction/AutocompleteHandler.d.ts
|
|
1109
|
+
type FocusedArms<Route extends keyof SlashOptionRegistry, Ret> = { [Name in AutocompletableNames<Route>]: (value: string, respond: (choices: readonly ApplicationCommandOptionChoiceData<ChoiceValueOf<EntryFor<Route, Name>>>[]) => Promise<void>) => Promisable<Ret> };
|
|
1338
1110
|
/**
|
|
1339
|
-
*
|
|
1111
|
+
* Base class for a Discord autocomplete handler.
|
|
1340
1112
|
*
|
|
1341
|
-
*
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
/**
|
|
1345
|
-
* Routes one or more commands' autocomplete to an {@link AutocompleteHandler}.
|
|
1113
|
+
* Pass the command route(s) from the generated registry as the generic, the same string(s) as
|
|
1114
|
+
* `@AutocompleteRoute`. Branch on the focused field with `this.match`, read already-entered sibling options
|
|
1115
|
+
* with `this.options`, and find which command fired with `this.route`.
|
|
1346
1116
|
*
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1349
|
-
* fields. The decorator routes and the generic must match exactly, so listing fewer or more than the
|
|
1350
|
-
* handler declares is a compile error.
|
|
1117
|
+
* @typeParam Route - One or more route keys from {@link SlashOptionRegistry}, e.g. `'search'` or `'search' | 'find'`.
|
|
1118
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1351
1119
|
*
|
|
1352
|
-
* @param routes - The command route string(s) this handler serves, e.g. `'search'` or `'search', 'find'`.
|
|
1353
|
-
* @decorator
|
|
1354
1120
|
* @example
|
|
1355
1121
|
* ```ts
|
|
1356
1122
|
* \@AutocompleteRoute('search')
|
|
1357
1123
|
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1358
1124
|
* async execute() {
|
|
1359
|
-
* await this.match({
|
|
1125
|
+
* await this.match({
|
|
1126
|
+
* query: (value, respond) => respond([{ name: value, value }])
|
|
1127
|
+
* });
|
|
1360
1128
|
* }
|
|
1361
1129
|
* }
|
|
1362
1130
|
* ```
|
|
1363
1131
|
*/
|
|
1364
|
-
declare
|
|
1365
|
-
/** @internal */
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1132
|
+
declare abstract class AutocompleteHandler<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> extends BaseHandler$1<AutocompleteInteraction<Cache>> {
|
|
1133
|
+
/** @internal */
|
|
1134
|
+
readonly __autocompleteRoute?: Route;
|
|
1135
|
+
constructor(event: AutocompleteInteraction<Cache>, core: Core, dispatch?: DispatchContext);
|
|
1136
|
+
private decodedFocused?;
|
|
1137
|
+
/**
|
|
1138
|
+
* The focused option for this interaction. `value` is always the raw partial string the user is typing,
|
|
1139
|
+
* even for an integer or number option, so coerce it yourself when you need a number.
|
|
1140
|
+
*/
|
|
1141
|
+
protected get focused(): FocusedField<Route>;
|
|
1142
|
+
/**
|
|
1143
|
+
* Run the arm for the focused field. An autocomplete always dispatches by which field is focused, so
|
|
1144
|
+
* match is how you read it. There is no single-field shortcut the way slash/component handlers have one.
|
|
1145
|
+
*
|
|
1146
|
+
* Provide one arm per autocompletable field across the registered commands, keyed by field name. Each
|
|
1147
|
+
* arm receives the focused partial value and a `respond` typed to that field's choice value. The
|
|
1148
|
+
* arms must cover every autocompletable field, a missing field or an unknown key is a compile error. A
|
|
1149
|
+
* focused field with no arm, only reachable from a stale-deployed command, throws at runtime.
|
|
1150
|
+
*
|
|
1151
|
+
* @param arms - One handler per autocompletable field, keyed by field name.
|
|
1152
|
+
* @returns The result of the arm that ran.
|
|
1153
|
+
*
|
|
1154
|
+
* @example
|
|
1155
|
+
* ```ts
|
|
1156
|
+
* \@AutocompleteRoute('search')
|
|
1157
|
+
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1158
|
+
* async execute() {
|
|
1159
|
+
* await this.match({
|
|
1160
|
+
* query: (value, respond) => respond(titles(value).map((s) => ({ name: s, value: s }))),
|
|
1161
|
+
* tag: (value, respond) => respond(tags(value).map((s) => ({ name: s, value: s })))
|
|
1162
|
+
* });
|
|
1163
|
+
* }
|
|
1164
|
+
* }
|
|
1165
|
+
* ```
|
|
1166
|
+
*/
|
|
1167
|
+
protected match<Ret>(arms: FocusedArms<Route, Ret>): Promise<Ret>;
|
|
1168
|
+
/** Send autocomplete suggestions, callback type 8. Prefer {@link match}, which restricts each field's choices to its declared type. */
|
|
1169
|
+
protected respond(choices: readonly ApplicationCommandOptionChoiceData[]): Promise<void>;
|
|
1170
|
+
/** The firing command route, for a field whose completion differs per registered command. */
|
|
1171
|
+
protected get route(): Route;
|
|
1172
|
+
/**
|
|
1173
|
+
* The already-entered options on this command, restricted to the kinds Discord resolves during autocomplete
|
|
1174
|
+
* (string, integer, number, boolean) with every read nullable, since a sibling is partial while the user
|
|
1175
|
+
* types the focused field. The focused field is on `this.focused`.
|
|
1176
|
+
*/
|
|
1177
|
+
protected get options(): AutocompleteOptions<Route>;
|
|
1399
1178
|
}
|
|
1400
1179
|
//#endregion
|
|
1401
1180
|
//#region src/handlers/interaction/components/ComponentHandler.d.ts
|
|
1402
1181
|
type ComponentInteraction = ButtonInteraction | ModalSubmitInteraction | AnySelectMenuInteraction;
|
|
1403
|
-
type SingleParams<Defs extends readonly AnyCustomId[]> = Defs extends readonly [infer One extends AnyCustomId] ? DecodedParams<One['shape']> : never;
|
|
1404
|
-
type MatchArms<Defs extends readonly AnyCustomId[], Ret> = { [Def in Defs[number] as Def['prefix']]: (params: DecodedParams<Def['shape']>) => Promisable<Ret> };
|
|
1405
1182
|
/**
|
|
1406
1183
|
* Shared base the customId-routed component handlers extend.
|
|
1407
1184
|
*
|
|
1408
|
-
* Not a public entry point.
|
|
1409
|
-
*
|
|
1410
|
-
* those bases share, so DO NOT use it directly.
|
|
1185
|
+
* Not a public entry point. Extend {@link ButtonHandler}, {@link SelectMenuHandler}, or {@link ModalHandler}
|
|
1186
|
+
* instead. This class defines the customId decode and the route matching those bases share.
|
|
1411
1187
|
*
|
|
1412
1188
|
* @typeParam Event - The component interaction type this handler processes
|
|
1413
1189
|
* @typeParam Defs - The customId route definitions registered on the concrete handler
|
|
@@ -1415,7 +1191,10 @@ type MatchArms<Defs extends readonly AnyCustomId[], Ret> = { [Def in Defs[number
|
|
|
1415
1191
|
declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs extends readonly AnyCustomId[]> extends InteractionHandler<Event> implements HasComponentDefs<Defs> {
|
|
1416
1192
|
/** @internal */
|
|
1417
1193
|
readonly __componentDefs?: Defs;
|
|
1418
|
-
|
|
1194
|
+
/** Rewrite the source message this component interaction came from. */
|
|
1195
|
+
protected update(response: ReplyResponse | string): Promise<SentMessage>;
|
|
1196
|
+
/** Acknowledge the component without changing the source message. */
|
|
1197
|
+
protected deferUpdate(): Promise<void>;
|
|
1419
1198
|
private decoded?;
|
|
1420
1199
|
private get route();
|
|
1421
1200
|
/**
|
|
@@ -1433,10 +1212,11 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1433
1212
|
* handler `this.params` is `never`, so match is the only way to read the decoded params.
|
|
1434
1213
|
*
|
|
1435
1214
|
* Provide one arm per registered route, keyed by its prefix, and each arm receives that route's own
|
|
1436
|
-
* decoded params. The arms
|
|
1437
|
-
*
|
|
1215
|
+
* decoded params. The arms cover every registered route prefix, checked at compile time, and a prefix
|
|
1216
|
+
* unmatched at runtime throws `CustomIdMatchArmMissing`. Decoding runs before any arm, so a stale or
|
|
1217
|
+
* corrupt wire throws before an arm body executes.
|
|
1438
1218
|
*
|
|
1439
|
-
* @param arms - One
|
|
1219
|
+
* @param arms - One callback per registered route, keyed by prefix.
|
|
1440
1220
|
* @returns The result of the arm that ran.
|
|
1441
1221
|
*
|
|
1442
1222
|
* @example
|
|
@@ -1445,8 +1225,8 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1445
1225
|
* class ReviewButtons extends ButtonHandler<[typeof Approve, typeof Reject]> {
|
|
1446
1226
|
* async execute() {
|
|
1447
1227
|
* await this.match({
|
|
1448
|
-
* approve: ({ userId }) => this.
|
|
1449
|
-
* reject: ({ userId }) => this.
|
|
1228
|
+
* approve: ({ userId }) => this.reply(`approved <@${userId}>`),
|
|
1229
|
+
* reject: ({ userId }) => this.reply(`rejected <@${userId}>`)
|
|
1450
1230
|
* });
|
|
1451
1231
|
* }
|
|
1452
1232
|
* }
|
|
@@ -1460,8 +1240,9 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1460
1240
|
* Base class for a button interaction handler.
|
|
1461
1241
|
*
|
|
1462
1242
|
* Register the customId definitions this handler decodes with `@ButtonRoute`, list the same ones in the
|
|
1463
|
-
* generic, then read `this.params` for a single route or `this.match` for several.
|
|
1464
|
-
*
|
|
1243
|
+
* generic, then read `this.params` for a single route or `this.match` for several. Reply through the handler
|
|
1244
|
+
* members, or rewrite the source message with `this.update`. Passing different definitions to the decorator
|
|
1245
|
+
* and the generic is a compile error.
|
|
1465
1246
|
*
|
|
1466
1247
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof ApproveId]`.
|
|
1467
1248
|
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
@@ -1472,12 +1253,15 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1472
1253
|
* class ApproveButton extends ButtonHandler<[typeof ApproveId]> {
|
|
1473
1254
|
* async execute() {
|
|
1474
1255
|
* const { userId } = this.params;
|
|
1475
|
-
* await this.
|
|
1256
|
+
* await this.reply(`approved <@${userId}>`);
|
|
1476
1257
|
* }
|
|
1477
1258
|
* }
|
|
1478
1259
|
* ```
|
|
1479
1260
|
*/
|
|
1480
|
-
declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ButtonInteraction<Cache>, Defs> {
|
|
1261
|
+
declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ButtonInteraction<Cache>, Defs> {
|
|
1262
|
+
/** @internal */
|
|
1263
|
+
readonly __component?: 'button';
|
|
1264
|
+
}
|
|
1481
1265
|
//#endregion
|
|
1482
1266
|
//#region src/handlers/interaction/components/ModalHandler.d.ts
|
|
1483
1267
|
/**
|
|
@@ -1485,7 +1269,8 @@ declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache
|
|
|
1485
1269
|
*
|
|
1486
1270
|
* Register the customId definitions this handler decodes with `@ModalRoute`, list the same ones in the
|
|
1487
1271
|
* generic, then read `this.params` for a single route or `this.match` for several. Read the submitted
|
|
1488
|
-
* inputs from `this.event.fields
|
|
1272
|
+
* inputs from `this.event.fields`, and reply through the handler members. Discord forbids opening a modal in
|
|
1273
|
+
* response to a modal, so `showModal` fails compilation on this kind.
|
|
1489
1274
|
*
|
|
1490
1275
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof ConfigId]`.
|
|
1491
1276
|
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
@@ -1497,20 +1282,25 @@ declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache
|
|
|
1497
1282
|
* async execute() {
|
|
1498
1283
|
* const { guildId } = this.params;
|
|
1499
1284
|
* const name = this.event.fields.getTextInputValue('name');
|
|
1500
|
-
* await this.
|
|
1285
|
+
* await this.reply(`saved ${name} for ${guildId}`);
|
|
1501
1286
|
* }
|
|
1502
1287
|
* }
|
|
1503
1288
|
* ```
|
|
1504
1289
|
*/
|
|
1505
|
-
declare abstract class ModalHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ModalSubmitInteraction<Cache>, Defs> {
|
|
1290
|
+
declare abstract class ModalHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ModalSubmitInteraction<Cache>, Defs> {
|
|
1291
|
+
/** @internal */
|
|
1292
|
+
readonly __component?: 'modal';
|
|
1293
|
+
}
|
|
1506
1294
|
//#endregion
|
|
1507
1295
|
//#region src/handlers/interaction/components/SelectMenuHandler.d.ts
|
|
1296
|
+
type SelectMenuInteractionFor<SelectMenu extends SelectMenuKind, Cache extends CacheType = CacheType> = SelectMenu extends SelectMenuKind.String ? StringSelectMenuInteraction<Cache> : SelectMenu extends SelectMenuKind.User ? UserSelectMenuInteraction<Cache> : SelectMenu extends SelectMenuKind.Role ? RoleSelectMenuInteraction<Cache> : SelectMenu extends SelectMenuKind.Channel ? ChannelSelectMenuInteraction<Cache> : SelectMenu extends SelectMenuKind.Mentionable ? MentionableSelectMenuInteraction<Cache> : never;
|
|
1508
1297
|
/**
|
|
1509
1298
|
* Base class for a select menu handler.
|
|
1510
1299
|
*
|
|
1511
1300
|
* Pass the select kind first and the customId definitions second, the same order as `@SelectMenuRoute`,
|
|
1512
1301
|
* so `this.event` and `this.event.values` are narrowed to that kind. Read `this.params` for a single
|
|
1513
|
-
* route or `this.match` for several
|
|
1302
|
+
* route or `this.match` for several, and reply through the handler members or rewrite the source message
|
|
1303
|
+
* with `this.update`.
|
|
1514
1304
|
*
|
|
1515
1305
|
* @typeParam Kind - The select kind from {@link SelectMenuKind}, e.g. `SelectMenuKind.User`.
|
|
1516
1306
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof AssignId]`.
|
|
@@ -1522,12 +1312,15 @@ declare abstract class ModalHandler<Defs extends readonly AnyCustomId[], Cache e
|
|
|
1522
1312
|
* class AssignSelect extends SelectMenuHandler<SelectMenuKind.User, [typeof AssignId]> {
|
|
1523
1313
|
* async execute() {
|
|
1524
1314
|
* const { roleId } = this.params;
|
|
1525
|
-
* await this.
|
|
1315
|
+
* await this.reply(`assigning ${this.event.values.length} member(s) to <@&${roleId}>`);
|
|
1526
1316
|
* }
|
|
1527
1317
|
* }
|
|
1528
1318
|
* ```
|
|
1529
1319
|
*/
|
|
1530
|
-
declare abstract class SelectMenuHandler<Kind extends SelectMenuKind, Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<SelectMenuInteractionFor<Kind, Cache>, Defs> {
|
|
1320
|
+
declare abstract class SelectMenuHandler<Kind extends SelectMenuKind, Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<SelectMenuInteractionFor<Kind, Cache>, Defs> {
|
|
1321
|
+
/** @internal */
|
|
1322
|
+
readonly __component?: Kind;
|
|
1323
|
+
}
|
|
1531
1324
|
//#endregion
|
|
1532
1325
|
//#region src/bot/decorators/Middlewares.d.ts
|
|
1533
1326
|
/**
|
|
@@ -1615,36 +1408,37 @@ declare const IgnoreBots: import("@seedcord/core").Gate<EventGateContext<ValidNo
|
|
|
1615
1408
|
*/
|
|
1616
1409
|
declare function Nsfw(options?: GateNoticeOptions): Gate<InteractionGateContext<NonModalInteraction>, 'Nsfw'>;
|
|
1617
1410
|
//#endregion
|
|
1618
|
-
//#region src/bot/
|
|
1619
|
-
/** Whose permissions a check ran against, used to mention and label the subject in a refusal. */
|
|
1620
|
-
type PermSubject = Role | TextChannel | Guild | GuildMember;
|
|
1621
|
-
//#endregion
|
|
1622
|
-
//#region src/bot/utilities/permissions/checkPermissions.d.ts
|
|
1411
|
+
//#region src/bot/utilities/channels/fetchText.d.ts
|
|
1623
1412
|
/**
|
|
1624
|
-
*
|
|
1625
|
-
*
|
|
1413
|
+
* Fetches and validates a text channel. Refuses when the channel doesn't exist or isn't a text channel.
|
|
1414
|
+
*
|
|
1415
|
+
* @param client - The Discord client instance
|
|
1416
|
+
* @param channelId - Channel ID or TextChannel instance
|
|
1417
|
+
* @returns Promise resolving to the text channel
|
|
1626
1418
|
*/
|
|
1627
|
-
|
|
1419
|
+
declare function fetchText(client: Client, channelId: TextChannelResolvable): Promise<TextChannel>;
|
|
1420
|
+
//#endregion
|
|
1421
|
+
//#region src/bot/utilities/permissions/checkPermissions.d.ts
|
|
1628
1422
|
/**
|
|
1629
1423
|
* Optional custom error constructors for {@link CheckPermissionOptions}.
|
|
1630
1424
|
*/
|
|
1631
|
-
interface
|
|
1632
|
-
|
|
1633
|
-
|
|
1425
|
+
interface PermissionErrorNoticeOverrides {
|
|
1426
|
+
missingNotice?: new (message: string | undefined, subject: string, missingPerms: readonly string[]) => Notice;
|
|
1427
|
+
dangerousNotice?: new (message: string | undefined, subject: string, dangerousPerms: readonly string[]) => Notice;
|
|
1634
1428
|
}
|
|
1635
1429
|
/**
|
|
1636
1430
|
* Options for {@link checkPermissions}.
|
|
1637
1431
|
*
|
|
1638
|
-
* @see {@link
|
|
1432
|
+
* @see {@link PermissionErrorNoticeOverrides}
|
|
1639
1433
|
*/
|
|
1640
|
-
interface CheckPermissionOptions extends
|
|
1434
|
+
interface CheckPermissionOptions extends PermissionErrorNoticeOverrides {
|
|
1641
1435
|
/** Role or member whose permissions will be checked */
|
|
1642
1436
|
for: Role | GuildMember;
|
|
1643
|
-
/** Context where permissions apply
|
|
1437
|
+
/** Context where permissions apply */
|
|
1644
1438
|
in: Guild | TextChannel;
|
|
1645
1439
|
/** Permission bits to validate */
|
|
1646
|
-
scope:
|
|
1647
|
-
/** When true, ensure target does
|
|
1440
|
+
scope: PermissionScope;
|
|
1441
|
+
/** When true, ensure target does NOT have the given permissions */
|
|
1648
1442
|
inverse?: boolean;
|
|
1649
1443
|
}
|
|
1650
1444
|
/**
|
|
@@ -1684,7 +1478,7 @@ interface CheckPermissionOptions extends PermissionErrorCtors {
|
|
|
1684
1478
|
* });
|
|
1685
1479
|
* ```
|
|
1686
1480
|
*/
|
|
1687
|
-
declare function checkPermissions(target: Role | GuildMember, ctx: Guild, scope:
|
|
1481
|
+
declare function checkPermissions(target: Role | GuildMember, ctx: Guild, scope: PermissionScope, inverse?: boolean, errors?: PermissionErrorNoticeOverrides): void;
|
|
1688
1482
|
/**
|
|
1689
1483
|
* Checks permissions for a {@link Role} or a {@link GuildMember} in a {@link TextChannel}. Refuses when a
|
|
1690
1484
|
* permission in `scope` is missing, or with `inverse` when one is present.
|
|
@@ -1722,7 +1516,7 @@ declare function checkPermissions(target: Role | GuildMember, ctx: Guild, scope:
|
|
|
1722
1516
|
* });
|
|
1723
1517
|
* ```
|
|
1724
1518
|
*/
|
|
1725
|
-
declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel, scope:
|
|
1519
|
+
declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionErrorNoticeOverrides): void;
|
|
1726
1520
|
/**
|
|
1727
1521
|
* Checks permissions using an options object. Refuses when a permission in {@link CheckPermissionOptions.scope} is missing,
|
|
1728
1522
|
* or with `options.inverse` when one is present.
|
|
@@ -1766,123 +1560,6 @@ declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel,
|
|
|
1766
1560
|
*/
|
|
1767
1561
|
declare function checkPermissions(options: CheckPermissionOptions): void;
|
|
1768
1562
|
//#endregion
|
|
1769
|
-
//#region src/bot/gates/catalog/permissions.d.ts
|
|
1770
|
-
/**
|
|
1771
|
-
* Options for {@link RequirePermissions} and {@link RequireBotPermissions}, one override per refusal the gate
|
|
1772
|
-
* can show.
|
|
1773
|
-
*
|
|
1774
|
-
* @example
|
|
1775
|
-
* ```ts
|
|
1776
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1777
|
-
* import type { Guild, GuildMember, Role, TextChannel } from 'discord.js';
|
|
1778
|
-
*
|
|
1779
|
-
* // `missing` is a Notice ctor: (message, where, missingPerms)
|
|
1780
|
-
* class MissingPermsNotice extends Notice {
|
|
1781
|
-
* public constructor(message: string, where: Role | TextChannel | Guild | GuildMember, missing: string[]) {
|
|
1782
|
-
* super(`${message} (${missing.join(', ')})`);
|
|
1783
|
-
* }
|
|
1784
|
-
* }
|
|
1785
|
-
*
|
|
1786
|
-
* RequirePermissions([PermissionFlagsBits.BanMembers], { missing: MissingPermsNotice });
|
|
1787
|
-
* ```
|
|
1788
|
-
*/
|
|
1789
|
-
interface RequirePermissionsOptions {
|
|
1790
|
-
/** Reword or replace the refusal shown outside a guild. */
|
|
1791
|
-
notInGuild?: GateNoticeOptions;
|
|
1792
|
-
/** Replace the missing-permissions refusal with a ctor that receives the where and the missing perm names. */
|
|
1793
|
-
missing?: PermissionErrorCtors['missing'];
|
|
1794
|
-
}
|
|
1795
|
-
/**
|
|
1796
|
-
* Options for {@link RequireRole}, one override per refusal the gate can show.
|
|
1797
|
-
*/
|
|
1798
|
-
interface RequireRoleOptions {
|
|
1799
|
-
/** Reword or replace the refusal shown outside a guild. */
|
|
1800
|
-
notInGuild?: GateNoticeOptions;
|
|
1801
|
-
/** Reword or replace the refusal shown when the caller lacks the role. */
|
|
1802
|
-
missingRole?: GateNoticeOptions;
|
|
1803
|
-
}
|
|
1804
|
-
/**
|
|
1805
|
-
* Requires the caller to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
|
|
1806
|
-
*
|
|
1807
|
-
* Interaction-only and excludes ModalSubmit, since a modal lacks a reliable cached caller member.
|
|
1808
|
-
*
|
|
1809
|
-
* @param scope - The permission flag bits the caller must all hold.
|
|
1810
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-permissions one with `missing`.
|
|
1811
|
-
*
|
|
1812
|
-
* @see {@link Gated}
|
|
1813
|
-
*
|
|
1814
|
-
* @example
|
|
1815
|
-
* ```ts
|
|
1816
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1817
|
-
*
|
|
1818
|
-
* \@Gated(RequirePermissions([PermissionFlagsBits.BanMembers]))
|
|
1819
|
-
* \@SlashRoute('ban')
|
|
1820
|
-
* class BanHandler extends SlashHandler<'ban'> {
|
|
1821
|
-
* async execute() {
|
|
1822
|
-
* const target = this.options.getUser('target');
|
|
1823
|
-
* }
|
|
1824
|
-
* }
|
|
1825
|
-
* ```
|
|
1826
|
-
*/
|
|
1827
|
-
declare function RequirePermissions(scope: BotPermissionScope, options?: RequirePermissionsOptions): Gate<InteractionGateContext<NonModalInteraction>, 'RequirePermissions'>;
|
|
1828
|
-
/**
|
|
1829
|
-
* Requires the bot to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
|
|
1830
|
-
*
|
|
1831
|
-
* It reads the bot's own member, so it attaches to modal handlers as well.
|
|
1832
|
-
*
|
|
1833
|
-
* @param scope - The permission flag bits the bot must all hold.
|
|
1834
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-permissions one with `missing`.
|
|
1835
|
-
*
|
|
1836
|
-
* @see {@link Gated}
|
|
1837
|
-
*
|
|
1838
|
-
* @example
|
|
1839
|
-
* ```ts
|
|
1840
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1841
|
-
*
|
|
1842
|
-
* \@Gated(RequireBotPermissions([PermissionFlagsBits.BanMembers]))
|
|
1843
|
-
* \@ModalRoute(MyModalId)
|
|
1844
|
-
* class MyModalHandler extends ModalHandler<[typeof MyModalId]> {
|
|
1845
|
-
* async execute() {
|
|
1846
|
-
* // ...
|
|
1847
|
-
* }
|
|
1848
|
-
* }
|
|
1849
|
-
* ```
|
|
1850
|
-
*/
|
|
1851
|
-
declare function RequireBotPermissions(scope: BotPermissionScope, options?: RequirePermissionsOptions): Gate<InteractionGateContext, 'RequireBotPermissions'>;
|
|
1852
|
-
/**
|
|
1853
|
-
* Requires the caller to have `roleId`, read from the member's role cache. Refuses outside a guild first, then
|
|
1854
|
-
* when the role is missing.
|
|
1855
|
-
*
|
|
1856
|
-
* Interaction-only and excludes ModalSubmit.
|
|
1857
|
-
*
|
|
1858
|
-
* @param roleId - The role snowflake the caller must hold, read from the member's role cache.
|
|
1859
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-role one with `missingRole`.
|
|
1860
|
-
*
|
|
1861
|
-
* @see {@link Gated}
|
|
1862
|
-
*
|
|
1863
|
-
* @example
|
|
1864
|
-
* ```ts
|
|
1865
|
-
* \@Gated(RequireRole('123456789012345678'))
|
|
1866
|
-
* \@SlashRoute('vip')
|
|
1867
|
-
* class VipHandler extends SlashHandler<'vip'> {
|
|
1868
|
-
* async execute() {
|
|
1869
|
-
* // ...
|
|
1870
|
-
* }
|
|
1871
|
-
* }
|
|
1872
|
-
* ```
|
|
1873
|
-
*/
|
|
1874
|
-
declare function RequireRole(roleId: string, options?: RequireRoleOptions): Gate<InteractionGateContext<NonModalInteraction>, 'RequireRole'>;
|
|
1875
|
-
//#endregion
|
|
1876
|
-
//#region src/bot/utilities/channels/fetchText.d.ts
|
|
1877
|
-
/**
|
|
1878
|
-
* Fetches and validates a text channel. Refuses when the channel doesn't exist or isn't a text channel.
|
|
1879
|
-
*
|
|
1880
|
-
* @param client - The Discord client instance
|
|
1881
|
-
* @param channelId - Channel ID or TextChannel instance
|
|
1882
|
-
* @returns Promise resolving to the text channel
|
|
1883
|
-
*/
|
|
1884
|
-
declare function fetchText(client: Client, channelId: TextChannelResolvable): Promise<TextChannel>;
|
|
1885
|
-
//#endregion
|
|
1886
1563
|
//#region src/bot/utilities/permissions/checkBotPermissions.d.ts
|
|
1887
1564
|
/**
|
|
1888
1565
|
* Checks if the bot has required permissions in a {@link Guild} or {@link TextChannel}. Refuses when a
|
|
@@ -1905,28 +1582,23 @@ declare function fetchText(client: Client, channelId: TextChannelResolvable): Pr
|
|
|
1905
1582
|
* ]);
|
|
1906
1583
|
* ```
|
|
1907
1584
|
*/
|
|
1908
|
-
declare function checkBotPermissions(target: Guild | TextChannel, scope:
|
|
1585
|
+
declare function checkBotPermissions(target: Guild | TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionErrorNoticeOverrides): void;
|
|
1909
1586
|
//#endregion
|
|
1910
1587
|
//#region src/bot/utilities/permissions/hasPermsToAssign.d.ts
|
|
1911
1588
|
/**
|
|
1912
1589
|
* Optional custom error constructors for {@link HasPermsToAssignOptions}.
|
|
1913
1590
|
*/
|
|
1914
|
-
interface
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
managed?: new (message: string) => Notice;
|
|
1919
|
-
/** Custom error for missing Manage Roles permission */
|
|
1920
|
-
missing?: new (message: string, where: Role | TextChannel | Guild | GuildMember, missingPerms: string[]) => Notice;
|
|
1591
|
+
interface AssignRoleNoticeOverrides {
|
|
1592
|
+
higherNotice?: new (message: string, role: Role, botRole: Role) => Notice;
|
|
1593
|
+
managedNotice?: new (message: string) => Notice;
|
|
1594
|
+
missingNotice?: new (message: string | undefined, subject: string, missingPerms: readonly string[]) => Notice;
|
|
1921
1595
|
}
|
|
1922
1596
|
/**
|
|
1923
1597
|
* Options for {@link hasPermsToAssign}.
|
|
1924
1598
|
*/
|
|
1925
1599
|
interface HasPermsToAssignOptions {
|
|
1926
|
-
/** Target role to validate for assignment */
|
|
1927
1600
|
targetRole: Role;
|
|
1928
|
-
|
|
1929
|
-
errors?: AssignRoleErrorCtors;
|
|
1601
|
+
noticeOverrides?: AssignRoleNoticeOverrides;
|
|
1930
1602
|
}
|
|
1931
1603
|
/**
|
|
1932
1604
|
* Validates if the bot can assign a target role. Refuses when the target role is above the bot's, is managed, or the bot lacks Manage Roles.
|
|
@@ -1943,10 +1615,10 @@ interface HasPermsToAssignOptions {
|
|
|
1943
1615
|
* // Check with custom error handling
|
|
1944
1616
|
* hasPermsToAssign({
|
|
1945
1617
|
* targetRole: role,
|
|
1946
|
-
*
|
|
1947
|
-
*
|
|
1948
|
-
*
|
|
1949
|
-
*
|
|
1618
|
+
* noticeOverrides: {
|
|
1619
|
+
* higherNotice: CustomHigherNotice,
|
|
1620
|
+
* managedNotice: CustomManagedNotice,
|
|
1621
|
+
* missingNotice: CustomMissingPermissionsNotice
|
|
1950
1622
|
* }
|
|
1951
1623
|
* });
|
|
1952
1624
|
* ```
|
|
@@ -2033,41 +1705,7 @@ declare function fetchManyUsers(client: Client, userIds: string[], options?: Fet
|
|
|
2033
1705
|
*/
|
|
2034
1706
|
declare function updateMemberRoles(rolesToAdd: Snowflake[], rolesToRemove: Snowflake[], member: GuildMember): Promise<void>;
|
|
2035
1707
|
//#endregion
|
|
2036
|
-
//#region src/bot/ReplySender.d.ts
|
|
2037
|
-
/**
|
|
2038
|
-
* Sends a {@link ReplyResponse} to an interaction, picking reply, editReply, or followUp from the live
|
|
2039
|
-
* acknowledgement state. Logs and drops its own send failures so a dead token never escapes into the
|
|
2040
|
-
* controller.
|
|
2041
|
-
*/
|
|
2042
|
-
declare class ReplySender {
|
|
2043
|
-
private readonly interaction;
|
|
2044
|
-
private readonly logger;
|
|
2045
|
-
constructor(interaction: Repliables);
|
|
2046
|
-
/**
|
|
2047
|
-
* Sends the reply and returns the sent message so a caller can attach a collector to it. Never throws,
|
|
2048
|
-
* a failed send is logged and dropped and resolves to `undefined`.
|
|
2049
|
-
*
|
|
2050
|
-
* @param response - The ComponentsV2 reply to show.
|
|
2051
|
-
* @param ephemeral - Whether the reply is ephemeral. {@default `true`}
|
|
2052
|
-
* @returns The sent {@link Message}, or `undefined` when the send was swallowed.
|
|
2053
|
-
*/
|
|
2054
|
-
send(response: ReplyResponse, ephemeral?: boolean): Promise<Message | undefined>;
|
|
2055
|
-
/**
|
|
2056
|
-
* Edits an already-sent message to a new {@link ReplyResponse}. Used to swap a confirmation prompt for
|
|
2057
|
-
* its outcome. Never throws, a failed edit is logged and dropped.
|
|
2058
|
-
*
|
|
2059
|
-
* @param message - The message to edit (the handle a prior {@link send} returned).
|
|
2060
|
-
* @param response - The reply to replace it with.
|
|
2061
|
-
*/
|
|
2062
|
-
edit(message: Message, response: ReplyResponse): Promise<void>;
|
|
2063
|
-
private dispatch;
|
|
2064
|
-
private replyOptions;
|
|
2065
|
-
private editBody;
|
|
2066
|
-
private logSwallowed;
|
|
2067
|
-
}
|
|
2068
|
-
//#endregion
|
|
2069
1708
|
//#region src/bot/confirm/getConfirmation.d.ts
|
|
2070
|
-
/** A confirm outcome to show, the reply itself or a factory for it. */
|
|
2071
1709
|
type Outcome = ReplyResponse | (() => Promisable<ReplyResponse>);
|
|
2072
1710
|
/** Options shared by both confirmation forms. */
|
|
2073
1711
|
interface ConfirmOptions {
|
|
@@ -2115,7 +1753,7 @@ interface DefaultConfirmOptions extends ConfirmOptions {
|
|
|
2115
1753
|
/**
|
|
2116
1754
|
* Shows a confirm/cancel prompt with built-in Confirm and Cancel buttons and resolves to `true` only if the
|
|
2117
1755
|
* invoking user clicks confirm. A cancel click or a timeout resolves to `false`. Gate the action behind it
|
|
2118
|
-
* with an early return.
|
|
1756
|
+
* with an early return. A failed prompt send throws into the fault boundary. Not usable from a
|
|
2119
1757
|
* {@link ModalHandler}, the `interaction` parameter excludes a modal submit at compile time.
|
|
2120
1758
|
*
|
|
2121
1759
|
* @param interaction - The repliable interaction to prompt on, `this.event` inside a non-modal handler.
|
|
@@ -2141,8 +1779,9 @@ interface DefaultConfirmOptions extends ConfirmOptions {
|
|
|
2141
1779
|
declare function getConfirmation(interaction: NonModalInteraction, prompt: string, options?: DefaultConfirmOptions): Promise<boolean>;
|
|
2142
1780
|
/**
|
|
2143
1781
|
* Shows a confirm/cancel prompt you build yourself and resolves to `true` only if the invoking user clicks
|
|
2144
|
-
* confirm. The factory receives the two minted button ids
|
|
2145
|
-
* timeout resolves to `false`.
|
|
1782
|
+
* confirm. The factory receives the two minted button ids. Set them on your own buttons. A cancel click or a
|
|
1783
|
+
* timeout resolves to `false`. A failed prompt send throws into the fault boundary. Not usable from a
|
|
1784
|
+
* {@link ModalHandler}.
|
|
2146
1785
|
*
|
|
2147
1786
|
* @param interaction - The repliable interaction to prompt on, `this.event` inside a non-modal handler.
|
|
2148
1787
|
* @param prompt - A factory given the minted `{ confirm, cancel }` ids that returns the reply to show. Build
|
|
@@ -2296,7 +1935,11 @@ interface PaginatorConfig<Item, Prefix extends string> {
|
|
|
2296
1935
|
renderItem?: ItemRender<Item>;
|
|
2297
1936
|
/** Take over the whole page tree. Receives the page data and the controls factory. */
|
|
2298
1937
|
render?: PageRender<Item>;
|
|
2299
|
-
/**
|
|
1938
|
+
/**
|
|
1939
|
+
* Whether the first page is ephemeral.
|
|
1940
|
+
*
|
|
1941
|
+
* @defaultValue `false`
|
|
1942
|
+
*/
|
|
2300
1943
|
ephemeral?: boolean;
|
|
2301
1944
|
}
|
|
2302
1945
|
type PaginatorHandlerCtor<Prefix extends string> = new (event: ButtonInteraction<'cached'>, core: Core) => ButtonHandler<[PageCursor<Prefix>]> & {
|
|
@@ -2329,7 +1972,7 @@ declare class Paginator<Item, const Prefix extends string> {
|
|
|
2329
1972
|
private readonly config;
|
|
2330
1973
|
constructor(config: PaginatorConfig<Item, Prefix>);
|
|
2331
1974
|
/** Render page 0 and send it, picking reply or followUp from the interaction's state. */
|
|
2332
|
-
start(interaction: Repliables, core?: Core): Promise<Message
|
|
1975
|
+
start(interaction: Repliables, core?: Core): Promise<Message>;
|
|
2333
1976
|
/** Render a page as a {@link ReplyResponse}. To post it elsewhere, add `flags: MessageFlags.IsComponentsV2`. */
|
|
2334
1977
|
page(ctx: PageContext, n: number): Promise<ReplyResponse>;
|
|
2335
1978
|
}
|
|
@@ -2400,86 +2043,98 @@ interface SubscribeOptions {
|
|
|
2400
2043
|
*/
|
|
2401
2044
|
declare function Subscribe<TSubscriber extends SubscriptionKey>(subscriber: TSubscriber, options?: SubscribeOptions): <HandlerCtor extends Constructor<Subscriber<TSubscriber>>>(constructor: HandlerCtor) => void;
|
|
2402
2045
|
//#endregion
|
|
2046
|
+
//#region src/subscribers/bases/WebhookSender.d.ts
|
|
2047
|
+
/**
|
|
2048
|
+
* A file attached to a webhook report.
|
|
2049
|
+
*/
|
|
2050
|
+
interface WebhookFile {
|
|
2051
|
+
name: string;
|
|
2052
|
+
description: string;
|
|
2053
|
+
data: Buffer;
|
|
2054
|
+
}
|
|
2055
|
+
/**
|
|
2056
|
+
* The payload {@link WebhookSender.send} posts.
|
|
2057
|
+
*/
|
|
2058
|
+
interface WebhookSendOptions {
|
|
2059
|
+
flags: number;
|
|
2060
|
+
username: string;
|
|
2061
|
+
components: readonly {
|
|
2062
|
+
toJSON(): APIMessageTopLevelComponent;
|
|
2063
|
+
}[];
|
|
2064
|
+
files?: readonly WebhookFile[] | undefined;
|
|
2065
|
+
}
|
|
2066
|
+
/**
|
|
2067
|
+
* Sends component messages to a Discord webhook through `@discordjs/rest`.
|
|
2068
|
+
*
|
|
2069
|
+
* @throws A `SeedcordError` when the url does not carry a webhook id and token.
|
|
2070
|
+
*/
|
|
2071
|
+
declare class WebhookSender {
|
|
2072
|
+
private readonly rest;
|
|
2073
|
+
private readonly route;
|
|
2074
|
+
constructor(url: string);
|
|
2075
|
+
/**
|
|
2076
|
+
* Fetches the webhook object, sending no message. Returns `missing` on a 404 or 401 from
|
|
2077
|
+
* Discord and `unreachable` on any other failure.
|
|
2078
|
+
*/
|
|
2079
|
+
verify(): Promise<'ok' | 'missing' | 'unreachable'>;
|
|
2080
|
+
send(options: WebhookSendOptions): Promise<void>;
|
|
2081
|
+
}
|
|
2082
|
+
//#endregion
|
|
2403
2083
|
//#region src/subscribers/bases/WebhookLog.d.ts
|
|
2404
2084
|
/**
|
|
2405
|
-
*
|
|
2085
|
+
* The content a reporter returns from {@link WebhookLog.report}.
|
|
2086
|
+
*/
|
|
2087
|
+
interface WebhookReport {
|
|
2088
|
+
/** Shown as the webhook message author. Defaults to the reporter's class name. */
|
|
2089
|
+
username?: string;
|
|
2090
|
+
components: readonly {
|
|
2091
|
+
toJSON(): APIMessageTopLevelComponent;
|
|
2092
|
+
}[];
|
|
2093
|
+
files?: readonly WebhookFile[] | undefined;
|
|
2094
|
+
}
|
|
2095
|
+
/**
|
|
2096
|
+
* Base class for subscribers that deliver their event to a Discord webhook.
|
|
2406
2097
|
*
|
|
2407
|
-
*
|
|
2408
|
-
*
|
|
2098
|
+
* Declare the url's environment variable with `@WebhookUrl` and implement {@link report}. Url
|
|
2099
|
+
* resolution, validation, sender reuse, and sending run in the base. When the variable is unset
|
|
2100
|
+
* the reporter is skipped at registration with a boot warning.
|
|
2409
2101
|
*
|
|
2410
|
-
* @typeParam KeyOfSubscribers - The
|
|
2102
|
+
* @typeParam KeyOfSubscribers - The subscription key this reporter receives
|
|
2411
2103
|
*/
|
|
2412
2104
|
declare abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey> extends Subscriber<KeyOfSubscribers> {
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2105
|
+
private static readonly senders;
|
|
2106
|
+
/** Builds the message for one published event. */
|
|
2107
|
+
abstract report(): WebhookReport | Promise<WebhookReport>;
|
|
2108
|
+
execute(): Promise<void>;
|
|
2109
|
+
/** @internal */
|
|
2110
|
+
static senderFor(url: string): WebhookSender;
|
|
2111
|
+
/** @internal */
|
|
2112
|
+
static envKeyOf(ctor: NewableFunction): string;
|
|
2113
|
+
/** @internal Returns null when the env var is unset, throws when set but malformed. */
|
|
2114
|
+
static urlOf(envKey: string): string | null;
|
|
2416
2115
|
}
|
|
2417
2116
|
//#endregion
|
|
2418
|
-
//#region src/
|
|
2419
|
-
/**
|
|
2420
|
-
* Options for configuring the HmrModuleHandler.
|
|
2421
|
-
*
|
|
2422
|
-
* This is only useful during development.
|
|
2423
|
-
*/
|
|
2424
|
-
interface HmrModuleHandlerOptions<THandler, TMiddleware = void, TArtifacts = unknown> {
|
|
2425
|
-
/** Directory containing handler modules. */
|
|
2426
|
-
handlersDir: string;
|
|
2427
|
-
/** Directory containing middleware modules. Optional because not all setups use middleware. */
|
|
2428
|
-
middlewaresDir?: string;
|
|
2429
|
-
/** Function to determine if a value is a handler module of type THandler. */
|
|
2430
|
-
isHandler: (val: unknown) => val is THandler;
|
|
2431
|
-
/** Function to determine if a value is a middleware module of type TMiddleware. Optional because not all setups use middleware. */
|
|
2432
|
-
isMiddleware?: (val: unknown) => val is TMiddleware;
|
|
2433
|
-
/** Function to register a handler module. */
|
|
2434
|
-
registerHandler: (handler: THandler, file: string) => void;
|
|
2435
|
-
/** Function to register a middleware module. Optional because not all setups use middleware. */
|
|
2436
|
-
registerMiddleware?: (middleware: TMiddleware, file: string) => void;
|
|
2437
|
-
/** Function to unregister a handler module. */
|
|
2438
|
-
unregisterHandler: (handler: THandler, artifacts?: TArtifacts) => void;
|
|
2439
|
-
/** Function to unregister a middleware module. Optional because not all setups use middleware. */
|
|
2440
|
-
unregisterMiddleware?: (middleware: TMiddleware) => void;
|
|
2441
|
-
/** Function to extract artifacts from a handler to be stored across hmr cache invalidations. */
|
|
2442
|
-
getArtifacts?: (handler: THandler) => TArtifacts;
|
|
2443
|
-
/** Logger instance for logging HMR activities.*/
|
|
2444
|
-
logger: Logger;
|
|
2445
|
-
}
|
|
2117
|
+
//#region src/subscribers/decorators/WebhookUrl.d.ts
|
|
2446
2118
|
/**
|
|
2447
|
-
*
|
|
2119
|
+
* Declares the environment variable a {@link WebhookLog} reporter reads its webhook url from.
|
|
2448
2120
|
*
|
|
2449
|
-
*
|
|
2121
|
+
* An unset variable disables the reporter with a boot warning. A set but malformed value throws
|
|
2122
|
+
* at boot.
|
|
2450
2123
|
*
|
|
2451
|
-
*
|
|
2124
|
+
* @param envKey - The environment variable name holding the webhook url
|
|
2125
|
+
* @decorator
|
|
2126
|
+
* @example
|
|
2127
|
+
* ```ts
|
|
2128
|
+
* \@Subscribe('memberBanned')
|
|
2129
|
+
* \@WebhookUrl('BAN_LOG_WEBHOOK_URL')
|
|
2130
|
+
* class BanLog extends WebhookLog<'memberBanned'> {
|
|
2131
|
+
* report() {
|
|
2132
|
+
* return { components: [new BanCard(this.data).component] };
|
|
2133
|
+
* }
|
|
2134
|
+
* }
|
|
2135
|
+
* ```
|
|
2452
2136
|
*/
|
|
2453
|
-
declare
|
|
2454
|
-
private readonly store;
|
|
2455
|
-
private readonly options;
|
|
2456
|
-
constructor(options: HmrModuleHandlerOptions<THandler, TMiddleware, TArtifacts>);
|
|
2457
|
-
/**
|
|
2458
|
-
* Handles an HMR update event by reloading affected modules based on the event details and config. It receives an {@link HmrUpdateEvent}, then checks the type of update.
|
|
2459
|
-
*
|
|
2460
|
-
* - If it's a deletion, it unloads the module.
|
|
2461
|
-
* - If it's an update/creation, it checks if the file is tracked, unloads it if so, then reloads the file if it is in the handlers or middlewares directory and is a valid handler/middleware.
|
|
2462
|
-
*/
|
|
2463
|
-
handle(event: HmrUpdateEvent): Promise<void>;
|
|
2464
|
-
private reloadWithRollback;
|
|
2465
|
-
/**
|
|
2466
|
-
* Tracks a handler module as being loaded from a specific file.
|
|
2467
|
-
* @param file - The file path the handler was loaded from.
|
|
2468
|
-
* @param handler - The handler module instance.
|
|
2469
|
-
*/
|
|
2470
|
-
trackHandler(file: string, handler: THandler): void;
|
|
2471
|
-
/**
|
|
2472
|
-
* Tracks a middleware module as being loaded from a specific file.
|
|
2473
|
-
* @param file - The file path the middleware was loaded from.
|
|
2474
|
-
* @param middleware - The middleware module instance.
|
|
2475
|
-
*/
|
|
2476
|
-
trackMiddleware(file: string, middleware: TMiddleware): void;
|
|
2477
|
-
private isTracked;
|
|
2478
|
-
private unload;
|
|
2479
|
-
private reloadFile;
|
|
2480
|
-
private snapshotUnits;
|
|
2481
|
-
private restoreUnits;
|
|
2482
|
-
}
|
|
2137
|
+
declare function WebhookUrl(envKey: string): <HandlerCtor extends Constructor<WebhookLog<SubscriptionKey>>>(constructor: HandlerCtor) => void;
|
|
2483
2138
|
//#endregion
|
|
2484
2139
|
//#region src/Seedcord.d.ts
|
|
2485
2140
|
/**
|
|
@@ -2497,6 +2152,8 @@ declare class Seedcord extends Pluggable implements Core {
|
|
|
2497
2152
|
/** @internal */
|
|
2498
2153
|
readonly version: string;
|
|
2499
2154
|
private static isInstantiated;
|
|
2155
|
+
private readonly healthCheck;
|
|
2156
|
+
private readonly hmrManager;
|
|
2500
2157
|
/** @see {@link CoordinatedShutdown} */
|
|
2501
2158
|
readonly shutdown: CoordinatedShutdown;
|
|
2502
2159
|
/** @see {@link CoordinatedStartup} */
|
|
@@ -2507,10 +2164,6 @@ declare class Seedcord extends Pluggable implements Core {
|
|
|
2507
2164
|
readonly bot: Bot;
|
|
2508
2165
|
/** @see {@link IRateLimiter} */
|
|
2509
2166
|
readonly rateLimiter: IRateLimiter;
|
|
2510
|
-
/** @see {@link HealthCheck} */
|
|
2511
|
-
private readonly healthCheck;
|
|
2512
|
-
/** @see {@link HmrManager} */
|
|
2513
|
-
private readonly hmrManager;
|
|
2514
2167
|
/**
|
|
2515
2168
|
* Creates a new Seedcord instance
|
|
2516
2169
|
*
|
|
@@ -2518,12 +2171,9 @@ declare class Seedcord extends Pluggable implements Core {
|
|
|
2518
2171
|
* @throws A **SeedcordError** When attempting to create multiple instances (singleton)
|
|
2519
2172
|
*/
|
|
2520
2173
|
constructor(config: GatewayConfig);
|
|
2521
|
-
/**
|
|
2174
|
+
/** The bot's discord username, populated after login. */
|
|
2175
|
+
get username(): string | undefined;
|
|
2522
2176
|
private static reset;
|
|
2523
|
-
/**
|
|
2524
|
-
* Registers default startup tasks
|
|
2525
|
-
* @internal
|
|
2526
|
-
*/
|
|
2527
2177
|
private registerStartupTasks;
|
|
2528
2178
|
/**
|
|
2529
2179
|
* Starts the bot and runs all initialization tasks
|
|
@@ -2538,5 +2188,5 @@ declare class Seedcord extends Pluggable implements Core {
|
|
|
2538
2188
|
/** Package version */
|
|
2539
2189
|
declare const version: string;
|
|
2540
2190
|
//#endregion
|
|
2541
|
-
export {
|
|
2191
|
+
export { ArraySource, AssignRoleNoticeOverrides, AutocompleteHandler, type BotEvents, ButtonHandler, type CheckPermissionOptions, CommandMentions, type ConfirmOptions, ContextMenuHandler, type Core, CursorSource, type DefaultConfirmOptions, Emojis, type EventGateContext, EventHandler, EventMiddleware, type EventSpec, type EventsConfig, type FaultSource, FetchUserOptions, type GateContext, Gated, type GatewayBotConfig, type GatewayConfig, HasPermsToAssignOptions, IgnoreBots, type Initializeable, type InjectedEmojiMap, type InjectedMentionMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, Middleware, type MiddlewareOptions, MiddlewareType, ModalHandler, Nsfw, Paginator, type PaginatorControls, type PermissionErrorNoticeOverrides, Pluggable, Plugin, type PluginArgs, type PluginCtor, RegisterEvent, type RegisterEventOptions, RepliableHandler, type Repliables, Seedcord, SelectMenuHandler, ShutdownPhase, SlashHandler, type SlashOptions, StartupPhase, Subscribe, type SubscribeOptions, Subscriber, type SubscriptionData, type SubscriptionKey, type Subscriptions, type ValidEventTypes, type ValidInteractionTypes, type ValidNonInteractionKeys, type WebhookFile, WebhookLog, type WebhookReport, WebhookUrl, checkBotPermissions, checkPermissions, fetchGuildMember, fetchManyGuildMembers, fetchManyUsers, fetchRole, fetchText, fetchUser, getBotRole, getConfirmation, hasPermsToAssign, updateMemberRoles, version };
|
|
2542
2192
|
//# sourceMappingURL=index.d.mts.map
|