@seedcord/gateway 0.1.0-next.2 → 0.1.0-next.4
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 +875 -1107
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +397 -768
- package/dist/index.mjs +871 -1081
- package/dist/index.mjs.map +1 -1
- package/package.json +15 -13
package/dist/index.d.mts
CHANGED
|
@@ -1,22 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { APIInteractionGuildMember, APIMessageComponentEmoji, AnySelectMenuInteraction, ApplicationCommand, ApplicationCommandOptionChoiceData, ApplicationCommandType, ApplicationEmoji, AutocompleteInteraction, BooleanCache, ButtonInteraction, ButtonStyle, CacheType, CacheTypeReducer, ChannelSelectMenuInteraction, ChannelType, 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, WebhookClient } from "discord.js";
|
|
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, Initializeable, Notice, PageView, PermissionScope, RepliableHandler as RepliableHandler$1, RequiredOf, SelectMenuKind, SlashOptionRegistry } from "@seedcord/core";
|
|
4
3
|
import { Logger } from "@seedcord/logger";
|
|
5
4
|
import { ActionRowBuilder, ButtonBuilder, ContextMenuCommandBuilder, SlashCommandBuilder } from "@discordjs/builders";
|
|
6
|
-
import {
|
|
7
|
-
import { CoordinatedShutdown, CoordinatedStartup, StartupPhase } from "@seedcord/services";
|
|
8
|
-
import { 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";
|
|
9
6
|
import { UUID } from "node:crypto";
|
|
10
|
-
import {
|
|
11
|
-
|
|
7
|
+
import { APIMessageTopLevelComponent } from "discord-api-types/v10";
|
|
8
|
+
import { REST } from "@discordjs/rest";
|
|
9
|
+
import { CoordinatedShutdown, CoordinatedStartup, Pluggable, PluginCapabilities } from "@seedcord/core/node/internal";
|
|
10
|
+
import { SeedcordBrand, SeedcordInstance } from "@seedcord/types/internal";
|
|
11
|
+
import { TypedEventEmitter } from "@seedcord/event-emitter";
|
|
12
|
+
import { BotConfig, Config, DeferOpts, EmojiMap, HealthCheckOption, HmrAware, HmrUpdateEvent, IRateLimiter, ReplyResponse, SendOpts, V2Component } from "@seedcord/types";
|
|
12
13
|
export * from "@seedcord/errors";
|
|
13
|
-
export * from "@seedcord/
|
|
14
|
+
export * from "@seedcord/core";
|
|
14
15
|
export * from "@seedcord/logger";
|
|
15
|
-
export * from "@seedcord/
|
|
16
|
+
export * from "@seedcord/utils";
|
|
16
17
|
export * from "@seedcord/rate-limiter";
|
|
17
|
-
export * from "@seedcord/
|
|
18
|
+
export * from "@seedcord/event-emitter";
|
|
18
19
|
export type * from "@seedcord/types";
|
|
19
20
|
|
|
21
|
+
//#region src/plugin-capabilities.d.ts
|
|
22
|
+
declare module '@seedcord/core' {
|
|
23
|
+
interface PluginCapabilityTypes {
|
|
24
|
+
client: Client;
|
|
25
|
+
rest: REST;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
20
29
|
//#region src/bot/utilities/miscellaneous/contextMenuLeaves.d.ts
|
|
21
30
|
/** The registered context-menu command names, split by kind, deduplicated. @internal */
|
|
22
31
|
interface ContextMenuLeaves {
|
|
@@ -56,98 +65,18 @@ interface GatewayBotConfig extends BotConfig {
|
|
|
56
65
|
*/
|
|
57
66
|
interface GatewayConfig extends Config {
|
|
58
67
|
bot: GatewayBotConfig;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//#region src/interfaces/Plugin.d.ts
|
|
62
|
-
interface Initializeable {
|
|
63
|
-
init(): Promise<void>;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Base class for Seedcord plugins
|
|
67
|
-
*
|
|
68
|
-
* Extend this class to create plugins that integrate with the Seedcord lifecycle.
|
|
69
|
-
* Plugins have access to the core instance and must implement initialization logic.
|
|
70
|
-
*/
|
|
71
|
-
declare abstract class Plugin<TPluginEvents extends EventMap<TPluginEvents> = NoEvents> extends TypedEventEmitter<TPluginEvents> implements Initializeable, HmrAware {
|
|
72
|
-
protected pluggable: Core;
|
|
73
|
-
abstract logger: Logger;
|
|
74
|
-
name: string;
|
|
75
|
-
constructor(pluggable: Core);
|
|
76
|
-
/** @virtual */
|
|
77
|
-
abstract init(): Promise<void>;
|
|
78
|
-
/**
|
|
79
|
-
* Reloads plugin state on an HMR update. The base implementation is a no-op, override it in your plugin.
|
|
80
|
-
* @virtual
|
|
81
|
-
*/
|
|
82
|
-
onHmr(_event: HmrUpdateEvent): Promise<void>;
|
|
83
|
-
/**
|
|
84
|
-
* Registers critical file patterns that should trigger a full restart when changed in Dev HMR.
|
|
85
|
-
* @param patterns - Glob patterns relative to the project root
|
|
86
|
-
*/
|
|
87
|
-
protected registerCriticalFiles(patterns: string[]): void;
|
|
88
|
-
/** @internal */
|
|
89
|
-
removeListener<TEventKey extends Extract<keyof TPluginEvents, string | symbol>>(event: TEventKey, listener: (...args: TPluginEvents[TEventKey]) => void): this;
|
|
90
|
-
/** @internal */
|
|
91
|
-
removeAllListeners(event?: Extract<keyof TPluginEvents, string | symbol>): this;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Constructor type for plugins that can accept extra arguments after Core.
|
|
95
|
-
*
|
|
96
|
-
* @internal
|
|
97
|
-
*/
|
|
98
|
-
type PluginCtor<TPlugin extends Plugin = Plugin> = new (core: Core, ...args: any[]) => TPlugin;
|
|
99
|
-
/**
|
|
100
|
-
* Extracts the argument types for a plugin constructor, excluding the Core parameter.
|
|
101
|
-
*
|
|
102
|
-
* @internal
|
|
103
|
-
*/
|
|
104
|
-
type PluginArgs<Ctor extends PluginCtor> = Tail<ConstructorParameters<Ctor>>;
|
|
105
|
-
/**
|
|
106
|
-
* Base class for objects that can have plugins attached.
|
|
107
|
-
*
|
|
108
|
-
* Provides plugin attachment capabilities and lifecycle management. Plugins are attached during
|
|
109
|
-
* configuration and initialized during startup. Not constructed directly, the host is a {@link Seedcord}.
|
|
110
|
-
*/
|
|
111
|
-
declare class Pluggable<TPluggableEvents extends EventMap<TPluggableEvents> = NoEvents> extends TypedEventEmitter<TPluggableEvents> {
|
|
112
|
-
protected isInitialized: boolean;
|
|
113
|
-
protected readonly shutdown: CoordinatedShutdown;
|
|
114
|
-
protected readonly startup: CoordinatedStartup;
|
|
115
|
-
protected readonly plugins: Plugin[];
|
|
116
|
-
private static readonly PLUGIN_INIT_TIMEOUT_MS;
|
|
117
|
-
constructor(shutdown: CoordinatedShutdown, startup: CoordinatedStartup);
|
|
118
|
-
/** @internal */
|
|
119
|
-
protected init(): Promise<this>;
|
|
68
|
+
/** The gateway websocket requires a persistent process, so `'server'` is the only value. */
|
|
69
|
+
runtime?: 'server';
|
|
120
70
|
/**
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
* Plugins provide external functionality and are initialized during the specified startup phase.
|
|
124
|
-
* The plugin instance becomes available as a property in `core` wherever it's available.
|
|
125
|
-
*
|
|
126
|
-
* Make sure to augment the {@link Core} interface with the plugin type to ensure TypeScript recognizes it and provides intellisense.
|
|
127
|
-
*
|
|
128
|
-
* @typeParam Key - The property name for accessing the plugin
|
|
129
|
-
* @typeParam Ctor - The plugin constructor type
|
|
130
|
-
* @param key - Property name to access the plugin instance
|
|
131
|
-
* @param Plugin - Plugin constructor class
|
|
132
|
-
* @param startupPhase - When during startup to initialize this plugin ({@link StartupPhase})
|
|
133
|
-
* @param args - Additional arguments to pass to the plugin constructor
|
|
134
|
-
* @returns This instance with the plugin attached as a typed property
|
|
135
|
-
* @throws A **SeedcordError** When called after initialization or if key already exists
|
|
136
|
-
* @example
|
|
137
|
-
* ```typescript
|
|
138
|
-
* seedcord.attach('db', Mongo, StartupPhase.Configuration, { uri: 'mongodb://...', name: 'seedcord', dir: ... })
|
|
139
|
-
* ```
|
|
71
|
+
* The health-check server. `false` disables it, `true` or omit for the defaults, an object
|
|
72
|
+
* configures it.
|
|
140
73
|
*/
|
|
141
|
-
|
|
142
|
-
/** @internal */
|
|
143
|
-
removeListener<TEventKey extends Extract<keyof TPluggableEvents, string | symbol>>(event: TEventKey, listener: (...args: TPluggableEvents[TEventKey]) => void): this;
|
|
144
|
-
/** @internal */
|
|
145
|
-
removeAllListeners(event?: Extract<keyof TPluggableEvents, string | symbol>): this;
|
|
74
|
+
healthCheck?: HealthCheckOption;
|
|
146
75
|
}
|
|
147
76
|
//#endregion
|
|
148
77
|
//#region src/subscribers/types/Subscriptions.d.ts
|
|
149
78
|
/**
|
|
150
|
-
* Where a reported fault came from.
|
|
79
|
+
* Where a reported fault came from.
|
|
151
80
|
*/
|
|
152
81
|
type FaultSource = InteractionFaultSource | EventFaultSource;
|
|
153
82
|
/**
|
|
@@ -155,19 +84,16 @@ type FaultSource = InteractionFaultSource | EventFaultSource;
|
|
|
155
84
|
*/
|
|
156
85
|
interface InteractionFaultSource {
|
|
157
86
|
kind: 'interaction';
|
|
158
|
-
/** Which interaction kind produced the fault. */
|
|
159
87
|
interactionKind: 'slash' | 'context-menu' | 'button' | 'select' | 'modal';
|
|
160
88
|
/** Slash or context-menu command name, null for component and modal interactions. */
|
|
161
89
|
command: string | null;
|
|
162
90
|
/** Component or modal customId, null for slash and context-menu interactions. */
|
|
163
91
|
customId: string | null;
|
|
164
|
-
/** User who triggered the interaction. */
|
|
165
92
|
userId: string;
|
|
166
93
|
/** Guild the interaction came from, null in DMs. */
|
|
167
94
|
guildId: string | null;
|
|
168
95
|
/** Channel the interaction came from, null when unavailable. */
|
|
169
96
|
channelId: string | null;
|
|
170
|
-
/** The interaction's own id. */
|
|
171
97
|
interactionId: string;
|
|
172
98
|
/** The raw interaction, made JSON-safe at serialization with filterCirculars. */
|
|
173
99
|
raw: unknown;
|
|
@@ -180,25 +106,26 @@ interface EventFaultSource {
|
|
|
180
106
|
kind: 'event';
|
|
181
107
|
eventName: string;
|
|
182
108
|
handler: string;
|
|
183
|
-
/** Actor derived from the event args, null when none is present. */
|
|
184
109
|
userId: string | null;
|
|
185
|
-
/**
|
|
110
|
+
/** Null outside a guild. */
|
|
186
111
|
guildId: string | null;
|
|
187
|
-
/** Channel derived from the event args, null when none is present. */
|
|
188
112
|
channelId: string | null;
|
|
189
113
|
/** The raw event args, made JSON-safe at serialization with filterCirculars. */
|
|
190
114
|
raw: unknown;
|
|
191
115
|
}
|
|
192
|
-
/**
|
|
193
|
-
* Default subscribers that are always available in the framework.
|
|
194
|
-
*/
|
|
195
116
|
interface DefaultSubscriptions {
|
|
196
117
|
/** Triggered when an unhandled exception (a raw non-Notice throw) occurs */
|
|
197
118
|
unknownException: {
|
|
198
119
|
uuid: UUID;
|
|
199
120
|
error: Error;
|
|
200
|
-
guild
|
|
201
|
-
|
|
121
|
+
guild?: {
|
|
122
|
+
id: string;
|
|
123
|
+
name: string;
|
|
124
|
+
} | undefined;
|
|
125
|
+
user?: {
|
|
126
|
+
id: string;
|
|
127
|
+
username: string;
|
|
128
|
+
} | undefined;
|
|
202
129
|
metadata?: unknown;
|
|
203
130
|
};
|
|
204
131
|
/** Triggered when a reported Notice (`report: true`) is caught */
|
|
@@ -209,66 +136,51 @@ interface DefaultSubscriptions {
|
|
|
209
136
|
};
|
|
210
137
|
}
|
|
211
138
|
/**
|
|
212
|
-
* Custom subscribers defined by the application.
|
|
213
|
-
*
|
|
214
|
-
* This interface can be augmented via declaration merging to add
|
|
215
|
-
* type-safe custom subscriber definitions for emitting custom subscribers anywhere in the application.
|
|
139
|
+
* Custom subscribers defined by the application. Augment it via declaration merging to type your
|
|
140
|
+
* own subscriber payloads.
|
|
216
141
|
*
|
|
217
142
|
* @example
|
|
218
143
|
* ```typescript
|
|
219
144
|
* declare module '@seedcord/gateway' {
|
|
220
145
|
* interface Subscriptions {
|
|
221
|
-
* 'userJoin': {
|
|
222
|
-
* 'levelUp': {
|
|
146
|
+
* 'userJoin': { userId: string; guildId: string };
|
|
147
|
+
* 'levelUp': { userId: string; level: number };
|
|
223
148
|
* }
|
|
224
149
|
* }
|
|
225
150
|
* ```
|
|
226
151
|
*/
|
|
227
152
|
interface Subscriptions {}
|
|
228
|
-
/**
|
|
229
|
-
* Combined subscribers interface containing both default and custom subscribers.
|
|
230
|
-
*/
|
|
231
153
|
interface AllSubscriptions extends DefaultSubscriptions, Subscriptions {}
|
|
232
|
-
/**
|
|
233
|
-
* Helper type to extract all available subscriber event names.
|
|
234
|
-
*/
|
|
154
|
+
/** All subscriber event names available to publish and augment. */
|
|
235
155
|
type SubscriptionKey = keyof AllSubscriptions;
|
|
236
156
|
/**
|
|
237
|
-
*
|
|
157
|
+
* The payload type for a subscriber event.
|
|
238
158
|
*
|
|
239
159
|
* @typeParam KeyOfSubscribers - The subscriber event name
|
|
240
160
|
*/
|
|
241
161
|
type SubscriptionData<KeyOfSubscribers extends SubscriptionKey> = AllSubscriptions[KeyOfSubscribers];
|
|
242
|
-
/**
|
|
243
|
-
* Event map for Bus, compatible with TypedEventEmitter.
|
|
244
|
-
*
|
|
245
|
-
* @internal
|
|
246
|
-
*/
|
|
247
162
|
type SubscriptionTuples = { [K in SubscriptionKey]: [AllSubscriptions[K]] };
|
|
248
163
|
//#endregion
|
|
249
164
|
//#region src/subscribers/Bus.d.ts
|
|
250
165
|
/**
|
|
251
|
-
*
|
|
252
|
-
*
|
|
253
|
-
* Provides a centralized system for registering and executing custom subscribers
|
|
254
|
-
* throughout the application lifecycle. Bus subscribers are loaded from configured directories
|
|
255
|
-
* and can be triggered programmatically or by framework events. Accessed via `core.bus`. Do not
|
|
256
|
-
* construct it directly.
|
|
166
|
+
* Registers and dispatches subscribers. Subscribers load from the configured directories and run
|
|
167
|
+
* on a programmatic or framework-event publish. Accessed via `core.bus`. Do not construct it directly.
|
|
257
168
|
*/
|
|
258
|
-
declare class Bus extends
|
|
169
|
+
declare class Bus extends TypedEventEmitter<SubscriptionTuples> implements Initializeable, HmrAware {
|
|
259
170
|
protected core: Core;
|
|
260
171
|
readonly logger: Logger;
|
|
261
|
-
/** @internal */
|
|
262
|
-
readonly name = "Subscribers";
|
|
263
172
|
private isInitialized;
|
|
264
173
|
private readonly subscribersMap;
|
|
265
174
|
private readonly executedOnceHandlers;
|
|
175
|
+
private readonly webhookProbes;
|
|
266
176
|
private readonly hmrHandler?;
|
|
267
177
|
constructor(core: Core);
|
|
268
178
|
private getArtifacts;
|
|
269
179
|
/** @internal */
|
|
270
180
|
init(): Promise<void>;
|
|
271
|
-
/** @internal
|
|
181
|
+
/** @internal Exposed for tests. */
|
|
182
|
+
verifyWebhooks(): Promise<void>;
|
|
183
|
+
/** @internal */
|
|
272
184
|
onHmr(event: HmrUpdateEvent): Promise<void>;
|
|
273
185
|
private loadSubscribers;
|
|
274
186
|
private registerSubscriber;
|
|
@@ -332,7 +244,6 @@ interface DeployResult {
|
|
|
332
244
|
declare class CommandRegistry implements Initializeable, HmrAware {
|
|
333
245
|
private readonly core;
|
|
334
246
|
private readonly onDeployed?;
|
|
335
|
-
readonly name = "Commands";
|
|
336
247
|
private readonly logger;
|
|
337
248
|
private isInitialised;
|
|
338
249
|
readonly globalCommands: (SlashCommandBuilder | ContextMenuCommandBuilder)[];
|
|
@@ -400,13 +311,13 @@ interface BotEvents {
|
|
|
400
311
|
'any:event': { [K in keyof ClientEvents]: [K, ...ClientEvents[K]] }[keyof ClientEvents];
|
|
401
312
|
/** Emitted for any interaction */
|
|
402
313
|
'any:interaction': [interaction: Interaction];
|
|
314
|
+
/** @internal */
|
|
315
|
+
ready: [];
|
|
403
316
|
}
|
|
404
317
|
/**
|
|
405
|
-
* Discord
|
|
406
|
-
*
|
|
407
|
-
* Don't instantiate this class directly. Use `core.bot` instead.
|
|
318
|
+
* The Discord client and its controllers. Access it through `core.bot`.
|
|
408
319
|
*/
|
|
409
|
-
declare class Bot extends
|
|
320
|
+
declare class Bot extends TypedEventEmitter<BotEvents> implements Initializeable, HmrAware {
|
|
410
321
|
readonly botToken: string;
|
|
411
322
|
/** @internal */
|
|
412
323
|
readonly logger: Logger;
|
|
@@ -414,39 +325,25 @@ declare class Bot extends Plugin<BotEvents> {
|
|
|
414
325
|
private readonly _client;
|
|
415
326
|
private readonly interactions?;
|
|
416
327
|
private readonly events?;
|
|
417
|
-
readonly commands?: CommandRegistry;
|
|
418
328
|
private readonly emojiInjector;
|
|
329
|
+
readonly commands?: CommandRegistry;
|
|
419
330
|
readonly emojis: InjectedEmojiMap;
|
|
420
331
|
readonly mentions: InjectedMentionMap;
|
|
421
|
-
/** @internal
|
|
332
|
+
/** @internal */
|
|
422
333
|
onHmr(event: HmrUpdateEvent): Promise<void>;
|
|
423
334
|
/** @internal */
|
|
424
335
|
constructor(core: Core);
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
336
|
+
private registerShutdownTasks;
|
|
337
|
+
private stopAccepting;
|
|
338
|
+
private drain;
|
|
339
|
+
/** @internal */
|
|
429
340
|
init(): Promise<void>;
|
|
430
|
-
/**
|
|
431
|
-
* Stops the bot and cleans up connections
|
|
432
|
-
* @internal
|
|
433
|
-
*/
|
|
341
|
+
/** @internal */
|
|
434
342
|
stop(): Promise<void>;
|
|
435
|
-
/**
|
|
436
|
-
* Logs the bot into Discord using the configured token
|
|
437
|
-
*/
|
|
438
343
|
private login;
|
|
439
|
-
/**
|
|
440
|
-
* Logs out and destroys the Discord client connection
|
|
441
|
-
*/
|
|
442
344
|
private logout;
|
|
443
345
|
get client(): Client;
|
|
444
|
-
/**
|
|
445
|
-
* Emits a Discord event with its argument tuple. The overloads enforce the key/args correlation
|
|
446
|
-
* at compile time only; at runtime this forwards straight to the underlying EventEmitter.
|
|
447
|
-
*
|
|
448
|
-
* @internal
|
|
449
|
-
*/
|
|
346
|
+
/** @internal */
|
|
450
347
|
emit<TKey extends keyof ClientEvents>(event: 'any:event', name: TKey, ...args: ClientEvents[TKey]): boolean;
|
|
451
348
|
/** @internal */
|
|
452
349
|
emit<TEventKey extends keyof BotEvents>(event: TEventKey, ...args: BotEvents[TEventKey]): boolean;
|
|
@@ -457,30 +354,19 @@ declare class Bot extends Plugin<BotEvents> {
|
|
|
457
354
|
protected onListenerError(error: unknown, event: string | symbol): void;
|
|
458
355
|
}
|
|
459
356
|
//#endregion
|
|
460
|
-
//#region src/handlers/
|
|
357
|
+
//#region src/handlers/interactionTypes.d.ts
|
|
461
358
|
type ValidInteractionTypes = ChatInputCommandInteraction | ButtonInteraction | ModalSubmitInteraction | AutocompleteInteraction | AnySelectMenuInteraction | ContextMenuCommandInteraction;
|
|
462
359
|
type ValidNonInteractionKeys = Exclude<keyof ClientEvents, Events.InteractionCreate>;
|
|
463
360
|
type ValidEventTypes = ValidInteractionTypes | ClientEvents[ValidNonInteractionKeys];
|
|
464
361
|
type Repliables = Exclude<ValidInteractionTypes, AutocompleteInteraction>;
|
|
465
362
|
type NonModalInteraction = Exclude<Repliables, ModalSubmitInteraction>;
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
execute(): Promise<void>;
|
|
469
|
-
}
|
|
363
|
+
//#endregion
|
|
364
|
+
//#region src/handlers/BaseHandler.d.ts
|
|
470
365
|
/**
|
|
471
|
-
*
|
|
366
|
+
* The gateway base, fixes the core base's `TCore` to the gateway {@link Core} and adds the `getEvent`
|
|
367
|
+
* gate hook.
|
|
472
368
|
*/
|
|
473
|
-
declare abstract class BaseHandler<ValidEvent extends ValidEventTypes>
|
|
474
|
-
readonly core: Core;
|
|
475
|
-
protected readonly event: ValidEvent;
|
|
476
|
-
protected readonly logger: Logger;
|
|
477
|
-
protected readonly dispatch?: DispatchContext | undefined;
|
|
478
|
-
protected constructor(event: ValidEvent, core: Core, dispatch?: DispatchContext);
|
|
479
|
-
/**
|
|
480
|
-
* Holds the main logic of your handler. The dispatcher calls it after the handler's gates pass, so a
|
|
481
|
-
* gate that refuses stops `execute()` from running.
|
|
482
|
-
*/
|
|
483
|
-
abstract execute(): Promise<void>;
|
|
369
|
+
declare abstract class BaseHandler$1<ValidEvent extends ValidEventTypes> extends BaseHandler<ValidEvent, Core> {
|
|
484
370
|
/** @internal */
|
|
485
371
|
getEvent(): ValidEvent;
|
|
486
372
|
}
|
|
@@ -683,7 +569,7 @@ type EventMatchArms<Names extends ValidNonInteractionKeys, Ret> = { [Name in Nam
|
|
|
683
569
|
* }
|
|
684
570
|
* ```
|
|
685
571
|
*/
|
|
686
|
-
declare abstract class EventHandler<Names extends ValidNonInteractionKeys> extends BaseHandler<ClientEvents[Names]>
|
|
572
|
+
declare abstract class EventHandler<Names extends ValidNonInteractionKeys> extends BaseHandler$1<ClientEvents[Names]> {
|
|
687
573
|
private readonly firedEvent;
|
|
688
574
|
constructor(event: ClientEvents[Names], core: Core, eventName?: Names);
|
|
689
575
|
protected readonly event: SingleEventPayload<Names>;
|
|
@@ -727,7 +613,7 @@ declare abstract class EventHandler<Names extends ValidNonInteractionKeys> exten
|
|
|
727
613
|
*
|
|
728
614
|
* @typeParam EventName - One or more `ClientEvents` keys. Defaults to every event (catchall).
|
|
729
615
|
*/
|
|
730
|
-
declare abstract class EventMiddleware<in out EventName extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends BaseHandler<ClientEvents[EventName]>
|
|
616
|
+
declare abstract class EventMiddleware<in out EventName extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends BaseHandler$1<ClientEvents[EventName]> {
|
|
731
617
|
private readonly firedEvent;
|
|
732
618
|
constructor(event: ClientEvents[EventName], core: Core, eventName?: EventName);
|
|
733
619
|
protected readonly event: SingleEventPayload<EventName>;
|
|
@@ -801,8 +687,8 @@ declare function RegisterEvent<const Defs extends readonly EventSpec<ValidNonInt
|
|
|
801
687
|
//#endregion
|
|
802
688
|
//#region src/bot/gates/Gate.d.ts
|
|
803
689
|
/**
|
|
804
|
-
* The interaction arm. It extends
|
|
805
|
-
* the
|
|
690
|
+
* The interaction arm. It extends {@link GuildPermissionsContext} with the live interaction and
|
|
691
|
+
* the djs objects resolved from the gateway cache. `Repliable` is the interaction type the gate
|
|
806
692
|
* supports, inferred from the `ctx` annotation, so a gate reading button-specific fields is rejected
|
|
807
693
|
* on a slash handler. `interaction` is the reply target, so `user` is always present. Use
|
|
808
694
|
* {@link NonModalInteraction} to exclude ModalSubmit when the gate needs a reliable caller member or
|
|
@@ -820,8 +706,8 @@ declare function RegisterEvent<const Defs extends readonly EventSpec<ValidNonInt
|
|
|
820
706
|
* });
|
|
821
707
|
* ```
|
|
822
708
|
*/
|
|
823
|
-
interface InteractionGateContext<Repliable extends Repliables = Repliables> extends
|
|
824
|
-
/**
|
|
709
|
+
interface InteractionGateContext<Repliable extends Repliables = Repliables> extends GuildPermissionsContext {
|
|
710
|
+
/** The literal `'interaction'`. Narrow on it before reading `interaction`. */
|
|
825
711
|
readonly kind: 'interaction';
|
|
826
712
|
/** The running framework, with the gateway's bot and bus. */
|
|
827
713
|
readonly core: Core;
|
|
@@ -835,7 +721,7 @@ interface InteractionGateContext<Repliable extends Repliables = Repliables> exte
|
|
|
835
721
|
readonly member: GuildMember | null;
|
|
836
722
|
}
|
|
837
723
|
/**
|
|
838
|
-
* The event arm. It extends
|
|
724
|
+
* The event arm. It extends {@link GuildPermissionsContext} with the event payload and the djs
|
|
839
725
|
* objects derived from it. `Names` is the event(s) the gate supports, inferred from the `ctx`
|
|
840
726
|
* annotation, so a gate that reads one event's `payload` is rejected on a handler for a different
|
|
841
727
|
* event. The default supports every event.
|
|
@@ -852,8 +738,8 @@ interface InteractionGateContext<Repliable extends Repliables = Repliables> exte
|
|
|
852
738
|
* });
|
|
853
739
|
* ```
|
|
854
740
|
*/
|
|
855
|
-
interface EventGateContext<Names extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends
|
|
856
|
-
/**
|
|
741
|
+
interface EventGateContext<Names extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends GuildPermissionsContext {
|
|
742
|
+
/** The literal `'event'`, narrow on it before reading `payload`. */
|
|
857
743
|
readonly kind: 'event';
|
|
858
744
|
/** The running framework, with the gateway's bot and bus. */
|
|
859
745
|
readonly core: Core;
|
|
@@ -886,18 +772,68 @@ interface EventGateContext<Names extends ValidNonInteractionKeys = ValidNonInter
|
|
|
886
772
|
*/
|
|
887
773
|
type GateContext = InteractionGateContext | EventGateContext;
|
|
888
774
|
//#endregion
|
|
775
|
+
//#region src/bot/ReplySender.d.ts
|
|
776
|
+
/** The created message a gateway reply resolves to. */
|
|
777
|
+
type SentMessage = Message;
|
|
778
|
+
/**
|
|
779
|
+
* Writes interaction responses through the discord.js interaction. Construction is internal to the repliable
|
|
780
|
+
* handler bases and the dispatcher.
|
|
781
|
+
*/
|
|
782
|
+
declare class ReplySender extends BaseReplySender<SentMessage> {
|
|
783
|
+
private readonly interaction;
|
|
784
|
+
constructor(interaction: Repliables, routeId: string);
|
|
785
|
+
protected writeReply(response: ReplyResponse | string, opts?: SendOpts): Promise<SentMessage | undefined>;
|
|
786
|
+
protected writeDefer(opts?: DeferOpts): Promise<void>;
|
|
787
|
+
protected writeDeferUpdate(): Promise<void>;
|
|
788
|
+
protected writeUpdate(response: ReplyResponse | string): Promise<SentMessage | undefined>;
|
|
789
|
+
protected writeFollowUp(response: ReplyResponse | string, opts?: SendOpts): Promise<SentMessage>;
|
|
790
|
+
protected writeEditOriginal(response: ReplyResponse | string): Promise<SentMessage>;
|
|
791
|
+
protected writeEditTarget(targetId: string, response: ReplyResponse | string): Promise<SentMessage>;
|
|
792
|
+
protected writeDeleteOriginal(): Promise<void>;
|
|
793
|
+
protected writeDeleteTarget(targetId: string): Promise<void>;
|
|
794
|
+
protected writeModal(data: APIModalInteractionResponseCallbackData): Promise<void>;
|
|
795
|
+
protected guardModalSource(): void;
|
|
796
|
+
private rejectModalSubmit;
|
|
797
|
+
private sourceInteraction;
|
|
798
|
+
private replyOptions;
|
|
799
|
+
private editOptions;
|
|
800
|
+
private updateOptions;
|
|
801
|
+
private createdMessage;
|
|
802
|
+
}
|
|
803
|
+
//#endregion
|
|
804
|
+
//#region src/handlers/RepliableHandler.d.ts
|
|
805
|
+
/**
|
|
806
|
+
* Shared base the repliable interaction handlers extend.
|
|
807
|
+
*
|
|
808
|
+
* Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
|
|
809
|
+
* {@link SelectMenuHandler}, or {@link ContextMenuHandler} instead. This class binds the core reply base
|
|
810
|
+
* to the gateway sender.
|
|
811
|
+
*
|
|
812
|
+
* @typeParam Event - The repliable interaction type this handler processes
|
|
813
|
+
*/
|
|
814
|
+
declare abstract class RepliableHandler<Event extends Repliables> extends RepliableHandler$1<Event, Core, SentMessage, ReplySender> {
|
|
815
|
+
/** @internal */
|
|
816
|
+
getEvent(): Event;
|
|
817
|
+
protected buildSender(event: Event, _core: Core, routeId: string): ReplySender;
|
|
818
|
+
}
|
|
819
|
+
//#endregion
|
|
889
820
|
//#region src/handlers/interaction/InteractionHandler.d.ts
|
|
890
821
|
/**
|
|
891
822
|
* Shared base the typed interaction handlers extend.
|
|
892
823
|
*
|
|
893
|
-
* Not a public entry point.
|
|
894
|
-
* or {@link SelectMenuHandler} instead. This class
|
|
895
|
-
*
|
|
824
|
+
* Not a public entry point. Extend {@link SlashHandler}, {@link ButtonHandler}, {@link ModalHandler},
|
|
825
|
+
* or {@link SelectMenuHandler} instead. This class adds `showModal` on top of the reply members those bases
|
|
826
|
+
* share.
|
|
896
827
|
*
|
|
897
828
|
* @typeParam Repliable - The interaction type this handler processes
|
|
898
829
|
*/
|
|
899
|
-
declare abstract class InteractionHandler<Repliable extends Repliables> extends
|
|
830
|
+
declare abstract class InteractionHandler<Repliable extends Repliables> extends RepliableHandler<Repliable> {
|
|
900
831
|
constructor(event: Repliable, core: Core, dispatch?: DispatchContext);
|
|
832
|
+
/**
|
|
833
|
+
* Open a modal. Must be the initial response to this interaction. The modal kind rejects this call at
|
|
834
|
+
* compile time (Discord forbids a modal in response to a modal).
|
|
835
|
+
*/
|
|
836
|
+
protected showModal(this: InteractionHandler<NonModalInteraction>, modal: ModalLike): Promise<void>;
|
|
901
837
|
}
|
|
902
838
|
//#endregion
|
|
903
839
|
//#region src/bot/gates/matching.d.ts
|
|
@@ -947,189 +883,28 @@ type FitAll<TCtor extends AnyHandlerCtor, Gates extends readonly Gate<GateContex
|
|
|
947
883
|
*/
|
|
948
884
|
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;
|
|
949
885
|
//#endregion
|
|
950
|
-
//#region src/
|
|
951
|
-
type Row$2<Route extends keyof SlashOptionRegistry> = SlashOptionRegistry[Route];
|
|
952
|
-
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;
|
|
953
|
-
type NamesOfKind$1<Route extends keyof SlashOptionRegistry, Kind extends OptionKind> = Route extends unknown ? { [Name in keyof Row$2<Route>]: Row$2<Route>[Name] extends {
|
|
954
|
-
kind: Kind;
|
|
955
|
-
} ? Name : never }[keyof Row$2<Route>] : never;
|
|
956
|
-
type ResolvedValue$1<Entry> = Entry extends {
|
|
957
|
-
choices: readonly (infer Choice)[];
|
|
958
|
-
} ? Choice : Entry extends {
|
|
959
|
-
kind: 'string';
|
|
960
|
-
} ? string : Entry extends {
|
|
961
|
-
kind: 'integer' | 'number';
|
|
962
|
-
} ? number : Entry extends {
|
|
963
|
-
kind: 'boolean';
|
|
964
|
-
} ? boolean : never;
|
|
965
|
-
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>;
|
|
966
|
-
/**
|
|
967
|
-
* The sibling-option view for an autocomplete handler. Only the four kinds Discord resolves during autocomplete
|
|
968
|
-
* appear (string, integer, number, boolean), every read is `T | null` because a sibling is partial while the
|
|
969
|
-
* user types the focused field, and a getter appears only when a registered command has an option of that kind.
|
|
970
|
-
* Across several registered commands the view is the union of their options, so a getter for an option absent on
|
|
971
|
-
* the firing command returns null. Read the focused field from `this.focused`.
|
|
972
|
-
*
|
|
973
|
-
* @typeParam Route - One or more route keys from {@link SlashOptionRegistry}.
|
|
974
|
-
*/
|
|
975
|
-
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'>;
|
|
976
|
-
//#endregion
|
|
977
|
-
//#region src/handlers/interaction/AutocompleteHandler.d.ts
|
|
978
|
-
type Row$1<Route extends keyof SlashOptionRegistry> = SlashOptionRegistry[Route];
|
|
979
|
-
type AutocompletableNames<Route extends keyof SlashOptionRegistry> = Route extends unknown ? { [Name in keyof Row$1<Route>]: Row$1<Route>[Name] extends {
|
|
980
|
-
autocomplete: true;
|
|
981
|
-
} ? Name : never }[keyof Row$1<Route>] : never;
|
|
982
|
-
type EntryFor<Route extends keyof SlashOptionRegistry, Name extends PropertyKey> = Route extends unknown ? Name extends keyof Row$1<Route> ? Row$1<Route>[Name] : never : never;
|
|
983
|
-
type ChoiceValueOf<Entry> = Entry extends {
|
|
984
|
-
kind: 'string';
|
|
985
|
-
} ? string : Entry extends {
|
|
986
|
-
kind: 'integer' | 'number';
|
|
987
|
-
} ? number : never;
|
|
988
|
-
/** The focused option. `value` is the raw partial Discord delivers mid-type, always a string regardless of kind. */
|
|
989
|
-
interface FocusedField<Route extends keyof SlashOptionRegistry> {
|
|
990
|
-
name: AutocompletableNames<Route>;
|
|
991
|
-
value: string;
|
|
992
|
-
}
|
|
993
|
-
/** One arm per autocompletable field, `value` is the focused partial, `respond` is pinned to the field's choice type. */
|
|
994
|
-
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> };
|
|
995
|
-
/**
|
|
996
|
-
* Base class for a Discord autocomplete handler.
|
|
997
|
-
*
|
|
998
|
-
* Pass the command route(s) from the generated registry as the generic, the same string(s) as
|
|
999
|
-
* `@AutocompleteRoute`. Branch on the focused field with `this.match`, read already-entered sibling options
|
|
1000
|
-
* with `this.options`, and find which command fired with `this.route`.
|
|
1001
|
-
*
|
|
1002
|
-
* @typeParam Route - One or more route keys from {@link SlashOptionRegistry}, e.g. `'search'` or `'search' | 'find'`.
|
|
1003
|
-
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1004
|
-
*
|
|
1005
|
-
* @example
|
|
1006
|
-
* ```ts
|
|
1007
|
-
* \@AutocompleteRoute('search')
|
|
1008
|
-
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1009
|
-
* async execute() {
|
|
1010
|
-
* await this.match({
|
|
1011
|
-
* query: (value, respond) => respond([{ name: value, value }])
|
|
1012
|
-
* });
|
|
1013
|
-
* }
|
|
1014
|
-
* }
|
|
1015
|
-
* ```
|
|
1016
|
-
*/
|
|
1017
|
-
declare abstract class AutocompleteHandler<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> extends BaseHandler<AutocompleteInteraction<Cache>> implements Handler {
|
|
1018
|
-
constructor(event: AutocompleteInteraction<Cache>, core: Core, dispatch?: DispatchContext);
|
|
1019
|
-
/**
|
|
1020
|
-
* The focused option for this interaction. `value` is always the raw partial string the user is typing,
|
|
1021
|
-
* even for an integer or number option, so coerce it yourself when you need a number.
|
|
1022
|
-
*/
|
|
1023
|
-
private decodedFocused?;
|
|
1024
|
-
protected get focused(): FocusedField<Route>;
|
|
1025
|
-
/**
|
|
1026
|
-
* Run the arm for the focused field. An autocomplete always dispatches by which field is focused, so
|
|
1027
|
-
* match is how you read it. There is no single-field shortcut the way slash/component handlers have one.
|
|
1028
|
-
*
|
|
1029
|
-
* Provide one arm per autocompletable field across the registered commands, keyed by field name. Each
|
|
1030
|
-
* arm receives the focused partial value and a `respond` pinned to that field's choice value type. The
|
|
1031
|
-
* arms must cover every autocompletable field, a missing field or an unknown key is a compile error. A
|
|
1032
|
-
* focused field with no arm, only reachable from a stale-deployed command, throws at runtime.
|
|
1033
|
-
*
|
|
1034
|
-
* @param arms - One handler per autocompletable field, keyed by field name.
|
|
1035
|
-
* @returns The result of the arm that ran.
|
|
1036
|
-
*
|
|
1037
|
-
* @example
|
|
1038
|
-
* ```ts
|
|
1039
|
-
* \@AutocompleteRoute('search')
|
|
1040
|
-
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1041
|
-
* async execute() {
|
|
1042
|
-
* await this.match({
|
|
1043
|
-
* query: (value, respond) => respond(titles(value).map((s) => ({ name: s, value: s }))),
|
|
1044
|
-
* tag: (value, respond) => respond(tags(value).map((s) => ({ name: s, value: s })))
|
|
1045
|
-
* });
|
|
1046
|
-
* }
|
|
1047
|
-
* }
|
|
1048
|
-
* ```
|
|
1049
|
-
*/
|
|
1050
|
-
protected match<Ret>(arms: FocusedArms<Route, Ret>): Promise<Ret>;
|
|
1051
|
-
/** The firing command route, for a field whose completion differs per registered command. */
|
|
1052
|
-
protected get route(): Route;
|
|
1053
|
-
/**
|
|
1054
|
-
* The already-entered options on this command, restricted to the kinds Discord resolves during autocomplete
|
|
1055
|
-
* (string, integer, number, boolean) with every read nullable, since a sibling is partial while the user
|
|
1056
|
-
* types the focused field. Read the focused field from `this.focused`, not here.
|
|
1057
|
-
*/
|
|
1058
|
-
protected get options(): AutocompleteOptions<Route>;
|
|
1059
|
-
}
|
|
1060
|
-
//#endregion
|
|
1061
|
-
//#region src/handlers/interaction/ContextMenuHandler.d.ts
|
|
1062
|
-
type ContextMenuKind = ApplicationCommandType.User | ApplicationCommandType.Message;
|
|
1063
|
-
type InteractionFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? UserContextMenuCommandInteraction<Cache> : MessageContextMenuCommandInteraction<Cache>;
|
|
1064
|
-
type TargetFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? User : Message<BooleanCache<Cache>>;
|
|
1065
|
-
type TargetMemberFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? CacheTypeReducer<Cache, GuildMember, APIInteractionGuildMember> | null : never;
|
|
886
|
+
//#region src/handlers/interaction/InteractionMiddleware.d.ts
|
|
1066
887
|
/**
|
|
1067
|
-
* Base class for
|
|
1068
|
-
*
|
|
1069
|
-
* Pass the kind from `discord.js`'s {@link ApplicationCommandType} as the generic, the same value as
|
|
1070
|
-
* `@ContextMenuRoute`. Read the right-clicked entity from `this.target`, a `User` for a user menu and a
|
|
1071
|
-
* `Message` for a message menu. Context menus carry no options, so a handler registered for several names
|
|
1072
|
-
* reads `this.target` uniformly with no per-name branch.
|
|
888
|
+
* Base class for interaction middleware
|
|
1073
889
|
*
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
890
|
+
* Middleware runs before interaction handlers and can modify behavior or block execution.
|
|
891
|
+
* Unlike handlers, middleware should not send responses directly.
|
|
1076
892
|
*
|
|
1077
|
-
* @
|
|
1078
|
-
* ```ts
|
|
1079
|
-
* \@ContextMenuRoute(ApplicationCommandType.Message, 'Report Message')
|
|
1080
|
-
* class ReportMessage extends ContextMenuHandler<ApplicationCommandType.Message> {
|
|
1081
|
-
* async execute() {
|
|
1082
|
-
* const message = this.target;
|
|
1083
|
-
* }
|
|
1084
|
-
* }
|
|
1085
|
-
* ```
|
|
893
|
+
* @typeParam Repliable - The interaction type this middleware processes
|
|
1086
894
|
*/
|
|
1087
|
-
declare abstract class
|
|
1088
|
-
|
|
1089
|
-
/**
|
|
1090
|
-
* The invoking guild member, resolved only on user menus. Reading it on a message menu is a compile
|
|
1091
|
-
* error since the type is `never` there.
|
|
1092
|
-
*/
|
|
1093
|
-
protected get targetMember(): TargetMemberFor<Kind, Cache>;
|
|
895
|
+
declare abstract class InteractionMiddleware<Repliable extends Repliables> extends BaseHandler$1<Repliable> {
|
|
896
|
+
constructor(event: Repliable, core: Core);
|
|
1094
897
|
}
|
|
1095
898
|
//#endregion
|
|
1096
899
|
//#region src/inputs/SlashOptions.d.ts
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
}
|
|
1105
|
-
type: ChannelWireType<Types>;
|
|
1106
|
-
}> : NonNullable<CommandInteractionOption<Cache>['channel']>;
|
|
1107
|
-
type ResolvedValue<Cache extends CacheType, Entry> = Entry extends {
|
|
1108
|
-
choices: readonly (infer Choice)[];
|
|
1109
|
-
} ? Choice : Entry extends {
|
|
1110
|
-
kind: 'string';
|
|
1111
|
-
} ? string : Entry extends {
|
|
1112
|
-
kind: 'integer' | 'number';
|
|
1113
|
-
} ? number : Entry extends {
|
|
1114
|
-
kind: 'boolean';
|
|
1115
|
-
} ? boolean : Entry extends {
|
|
1116
|
-
kind: 'user';
|
|
1117
|
-
} ? NonNullable<CommandInteractionOption<Cache>['user']> : Entry extends {
|
|
1118
|
-
kind: 'channel';
|
|
1119
|
-
} ? ResolvedChannel<Cache, Entry> : Entry extends {
|
|
1120
|
-
kind: 'role';
|
|
1121
|
-
} ? NonNullable<CommandInteractionOption<Cache>['role']> : Entry extends {
|
|
1122
|
-
kind: 'mentionable';
|
|
1123
|
-
} ? NonNullable<CommandInteractionOption<Cache>['member' | 'role' | 'user']> : Entry extends {
|
|
1124
|
-
kind: 'attachment';
|
|
1125
|
-
} ? NonNullable<CommandInteractionOption<Cache>['attachment']> : never;
|
|
1126
|
-
type Returned<Cache extends CacheType, Entry> = Entry extends {
|
|
1127
|
-
required: true;
|
|
1128
|
-
} ? ResolvedValue<Cache, Entry> : ResolvedValue<Cache, Entry> | null;
|
|
1129
|
-
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]>>;
|
|
1130
|
-
type MemberGetter<Route extends keyof SlashOptionRegistry, Cache extends CacheType> = IsNever<NamesOfKind<Route, 'user'>> extends true ? unknown : {
|
|
1131
|
-
getMember: <Name extends NamesOfKind<Route, 'user'>>(name: Name) => NonNullable<CommandInteractionOption<Cache>['member']> | null;
|
|
1132
|
-
};
|
|
900
|
+
interface GatewayLens<Cache extends CacheType> {
|
|
901
|
+
user: NonNullable<CommandInteractionOption<Cache>['user']>;
|
|
902
|
+
member: NonNullable<CommandInteractionOption<Cache>['member']>;
|
|
903
|
+
channel: NonNullable<CommandInteractionOption<Cache>['channel']>;
|
|
904
|
+
role: NonNullable<CommandInteractionOption<Cache>['role']>;
|
|
905
|
+
mentionable: NonNullable<CommandInteractionOption<Cache>['member' | 'role' | 'user']>;
|
|
906
|
+
attachment: NonNullable<CommandInteractionOption<Cache>['attachment']>;
|
|
907
|
+
}
|
|
1133
908
|
/**
|
|
1134
909
|
* The typed view over a chat-input command's options for one route. Each getter mirrors the discord.js
|
|
1135
910
|
* resolver method but restricts its `name` to that route's options of the matching kind, drops the null
|
|
@@ -1142,7 +917,7 @@ type MemberGetter<Route extends keyof SlashOptionRegistry, Cache extends CacheTy
|
|
|
1142
917
|
* @typeParam Route - A route key from the generated {@link SlashOptionRegistry}.
|
|
1143
918
|
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1144
919
|
*/
|
|
1145
|
-
type SlashOptions<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> =
|
|
920
|
+
type SlashOptions<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> = SlashOptions$1<Route, GatewayLens<Cache>>;
|
|
1146
921
|
//#endregion
|
|
1147
922
|
//#region src/handlers/interaction/SlashHandler.d.ts
|
|
1148
923
|
type SlashMatchArms<Route extends keyof SlashOptionRegistry, Cache extends CacheType, Ret> = { [Key in Route]: (options: SlashOptions<Key, Cache>) => Promisable<Ret> };
|
|
@@ -1168,6 +943,8 @@ type SlashMatchArms<Route extends keyof SlashOptionRegistry, Cache extends Cache
|
|
|
1168
943
|
* ```
|
|
1169
944
|
*/
|
|
1170
945
|
declare abstract class SlashHandler<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> extends InteractionHandler<ChatInputCommandInteraction<Cache>> {
|
|
946
|
+
/** @internal */
|
|
947
|
+
readonly __slashRoute?: Route;
|
|
1171
948
|
/**
|
|
1172
949
|
* The typed options for this command's route. Required options drop the null, choices narrow to their
|
|
1173
950
|
* literal union, and only the getters for kinds this command actually uses appear. Use `this.event.options`
|
|
@@ -1176,7 +953,7 @@ declare abstract class SlashHandler<Route extends keyof SlashOptionRegistry, Cac
|
|
|
1176
953
|
protected get options(): SlashOptions<Route, Cache>;
|
|
1177
954
|
/**
|
|
1178
955
|
* Run the arm for whichever command fired. Use this only when the handler is registered for several
|
|
1179
|
-
* routes.
|
|
956
|
+
* routes.
|
|
1180
957
|
*
|
|
1181
958
|
* Provide one arm per registered route, keyed by its route string, and each arm receives that route's
|
|
1182
959
|
* own narrowed options. The arms must cover every route in the generic, a missing route or an unknown
|
|
@@ -1201,211 +978,122 @@ declare abstract class SlashHandler<Route extends keyof SlashOptionRegistry, Cac
|
|
|
1201
978
|
protected match<Ret>(arms: SlashMatchArms<Route, Cache, Ret>): Promise<Ret>;
|
|
1202
979
|
}
|
|
1203
980
|
//#endregion
|
|
1204
|
-
//#region src/
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
String = "string",
|
|
1210
|
-
User = "user",
|
|
1211
|
-
Role = "role",
|
|
1212
|
-
Channel = "channel",
|
|
1213
|
-
Mentionable = "mentionable"
|
|
1214
|
-
}
|
|
1215
|
-
/** @internal */
|
|
1216
|
-
type HandlerEventType<TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = InstanceType<TCtor> extends InteractionHandler<infer TEvent> ? TEvent : never;
|
|
1217
|
-
/**
|
|
1218
|
-
* Compile-time assertion that the required event type(s) `TRequired` are included in the handler event union.
|
|
1219
|
-
*
|
|
1220
|
-
* @internal
|
|
1221
|
-
*/
|
|
1222
|
-
type AssertHandles<TRequired, TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = Extract<HandlerEventType<TCtor>, TRequired> extends never ? Constructor<['Handler event generic must include', TRequired]> : TCtor;
|
|
1223
|
-
/**
|
|
1224
|
-
* The slash route(s) a handler serves, read off its `SlashHandler` generic.
|
|
1225
|
-
*
|
|
1226
|
-
* @internal
|
|
1227
|
-
*/
|
|
1228
|
-
type SlashRouteOf<TCtor extends new (...args: any[]) => InteractionHandler<Repliables>> = InstanceType<TCtor> extends SlashHandler<infer Route, CacheType> ? Route : never;
|
|
1229
|
-
/**
|
|
1230
|
-
* On a route/generic mismatch, resolves to a non-constructor type so applying the decorator is a TS1238.
|
|
1231
|
-
*
|
|
1232
|
-
* @internal
|
|
1233
|
-
*/
|
|
1234
|
-
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]>;
|
|
1235
|
-
/**
|
|
1236
|
-
* Routes one or more slash commands to a {@link SlashHandler}.
|
|
1237
|
-
*
|
|
1238
|
-
* Pass the same route string(s) as the handler's generic. A single command reads `this.options`, several
|
|
1239
|
-
* commands branch with `this.match`. The decorator routes and the generic must match exactly, so listing
|
|
1240
|
-
* fewer or more than the handler declares is a compile error. Subcommands use a slash path.
|
|
1241
|
-
*
|
|
1242
|
-
* @param routes - The route string(s) this handler serves, e.g. `'ban'`, `'ban', 'kick'`, or `'demo/setup'`.
|
|
1243
|
-
* @decorator
|
|
1244
|
-
* @example
|
|
1245
|
-
* ```ts
|
|
1246
|
-
* \@SlashRoute('ban')
|
|
1247
|
-
* class BanHandler extends SlashHandler<'ban'> {
|
|
1248
|
-
* async execute() {
|
|
1249
|
-
* const target = this.options.getUser('target');
|
|
1250
|
-
* }
|
|
1251
|
-
* }
|
|
1252
|
-
* ```
|
|
1253
|
-
*
|
|
1254
|
-
* @example
|
|
1255
|
-
* ```ts
|
|
1256
|
-
* \@SlashRoute('ban', 'kick')
|
|
1257
|
-
* class ModerationHandler extends SlashHandler<'ban' | 'kick'> {
|
|
1258
|
-
* async execute() {
|
|
1259
|
-
* await this.match({ ban: (o) => o.getUser('target'), kick: (o) => o.getUser('member') });
|
|
1260
|
-
* }
|
|
1261
|
-
* }
|
|
1262
|
-
* ```
|
|
1263
|
-
*/
|
|
1264
|
-
declare function SlashRoute<const Route extends keyof SlashOptionRegistry>(...routes: Route[]): <TCtor extends new (...args: any[]) => InteractionHandler<Repliables>>(constructor: AssertSlashRoute<Route, TCtor>) => void;
|
|
1265
|
-
/**
|
|
1266
|
-
* Routes button interactions to handler classes.
|
|
1267
|
-
*
|
|
1268
|
-
* Pass the {@link CustomId} definition(s) this handler decodes and list the same ones in the handler's
|
|
1269
|
-
* generic. Passing different definitions to the decorator and the generic is a compile error. Routing
|
|
1270
|
-
* matches the stable prefix, so a wire minted from an older shape still reaches the handler, where
|
|
1271
|
-
* reading this.params throws StaleCustomId and the controller boundary turns it into a reply.
|
|
1272
|
-
*
|
|
1273
|
-
* @param defs - The customId definition(s) this handler decodes, one per route.
|
|
1274
|
-
* @decorator
|
|
1275
|
-
*/
|
|
1276
|
-
declare function ButtonRoute<const Defs extends readonly AnyCustomId[]>(...defs: Defs): <TCtor extends new (...args: any[]) => InteractionHandler<Repliables> & HasComponentDefs<Defs>>(constructor: AssertHandles<ButtonInteraction, TCtor>) => void;
|
|
1277
|
-
/**
|
|
1278
|
-
* Routes modal submissions to handler classes.
|
|
1279
|
-
*
|
|
1280
|
-
* Pass the {@link CustomId} definition(s) this handler decodes and list the same ones in the handler's
|
|
1281
|
-
* generic. Passing different definitions to the decorator and the generic is a compile error. Routing
|
|
1282
|
-
* matches the stable prefix, so an older-shape wire still reaches the handler and throws StaleCustomId
|
|
1283
|
-
* on read, the same as a button route.
|
|
1284
|
-
*
|
|
1285
|
-
* @param defs - The customId definition(s) this handler decodes, one per route.
|
|
1286
|
-
* @decorator
|
|
1287
|
-
*/
|
|
1288
|
-
declare function ModalRoute<const Defs extends readonly AnyCustomId[]>(...defs: Defs): <TCtor extends new (...args: any[]) => InteractionHandler<Repliables> & HasComponentDefs<Defs>>(constructor: AssertHandles<ModalSubmitInteraction, TCtor>) => void;
|
|
1289
|
-
/** The context-menu command names valid for a kind, read off the matching registry. @internal */
|
|
1290
|
-
type NamesFor<Kind extends ApplicationCommandType.User | ApplicationCommandType.Message> = Kind extends ApplicationCommandType.User ? keyof UserContextMenuRegistry : keyof MessageContextMenuRegistry;
|
|
1291
|
-
/**
|
|
1292
|
-
* The context-menu kind a handler serves, read off its event's `commandType` discriminant. Direct
|
|
1293
|
-
* inference from the `ContextMenuHandler` generic widens the kind to the whole union because the handler's
|
|
1294
|
-
* conditional members blur it, so this uses the event literal to keep it narrow.
|
|
1295
|
-
*
|
|
1296
|
-
* @internal
|
|
1297
|
-
*/
|
|
1298
|
-
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 {
|
|
1299
|
-
commandType: infer K;
|
|
1300
|
-
} ? Extract<K, ApplicationCommandType.User | ApplicationCommandType.Message> : never : never : never;
|
|
981
|
+
//#region src/handlers/interaction/ContextMenuHandler.d.ts
|
|
982
|
+
type ContextMenuKind = ApplicationCommandType.User | ApplicationCommandType.Message;
|
|
983
|
+
type InteractionFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? UserContextMenuCommandInteraction<Cache> : MessageContextMenuCommandInteraction<Cache>;
|
|
984
|
+
type TargetFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? User : Message<BooleanCache<Cache>>;
|
|
985
|
+
type TargetMemberFor<Kind extends ContextMenuKind, Cache extends CacheType> = Kind extends ApplicationCommandType.User ? CacheTypeReducer<Cache, GuildMember, APIInteractionGuildMember> | null : never;
|
|
1301
986
|
/**
|
|
1302
|
-
*
|
|
1303
|
-
* applying the decorator is a TS1238. Cross-checks both directions, mirroring {@link AssertSlashRoute}.
|
|
987
|
+
* Base class for a context-menu command handler (right-click a user or a message).
|
|
1304
988
|
*
|
|
1305
|
-
* @
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
* Routes one or more context-menu commands to a {@link ContextMenuHandler}.
|
|
989
|
+
* Pass the kind from `discord.js`'s {@link ApplicationCommandType} as the generic, the same value as
|
|
990
|
+
* `@ContextMenuRoute`. Read the right-clicked entity from `this.target`, a `User` for a user menu and a
|
|
991
|
+
* `Message` for a message menu. Context menus carry no options, so a handler registered for several names
|
|
992
|
+
* reads `this.target` uniformly with no per-name branch.
|
|
1310
993
|
*
|
|
1311
|
-
*
|
|
1312
|
-
*
|
|
1313
|
-
* handler's generic, cross-checked both directions. Context menus carry no options, so a multi-name handler
|
|
1314
|
-
* reads `this.target` uniformly with no branch.
|
|
994
|
+
* @typeParam Kind - `ApplicationCommandType.User` or `ApplicationCommandType.Message`.
|
|
995
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1315
996
|
*
|
|
1316
|
-
* @param kind - The context-menu kind, `ApplicationCommandType.User` or `ApplicationCommandType.Message`.
|
|
1317
|
-
* @param names - The command name(s) this handler serves, keyed off the matching registry.
|
|
1318
|
-
* @decorator
|
|
1319
997
|
* @example
|
|
1320
998
|
* ```ts
|
|
1321
|
-
* \@ContextMenuRoute(ApplicationCommandType.
|
|
1322
|
-
* class
|
|
999
|
+
* \@ContextMenuRoute(ApplicationCommandType.Message, 'Report Message')
|
|
1000
|
+
* class ReportMessage extends ContextMenuHandler<ApplicationCommandType.Message> {
|
|
1323
1001
|
* async execute() {
|
|
1324
|
-
* const
|
|
1002
|
+
* const message = this.target;
|
|
1325
1003
|
* }
|
|
1326
1004
|
* }
|
|
1327
1005
|
* ```
|
|
1328
1006
|
*/
|
|
1329
|
-
declare
|
|
1330
|
-
/**
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1007
|
+
declare abstract class ContextMenuHandler<Kind extends ContextMenuKind, Cache extends CacheType = 'cached'> extends InteractionHandler<InteractionFor<Kind, Cache>> {
|
|
1008
|
+
/** @internal */
|
|
1009
|
+
readonly __ctxKind?: Kind;
|
|
1010
|
+
protected get target(): TargetFor<Kind, Cache>;
|
|
1011
|
+
/**
|
|
1012
|
+
* The invoking guild member, resolved only on user menus. Reading it on a message menu is a compile
|
|
1013
|
+
* error since the type is `never` there.
|
|
1014
|
+
*/
|
|
1015
|
+
protected get targetMember(): TargetMemberFor<Kind, Cache>;
|
|
1016
|
+
}
|
|
1017
|
+
//#endregion
|
|
1018
|
+
//#region src/handlers/interaction/AutocompleteHandler.d.ts
|
|
1019
|
+
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> };
|
|
1336
1020
|
/**
|
|
1337
|
-
*
|
|
1021
|
+
* Base class for a Discord autocomplete handler.
|
|
1338
1022
|
*
|
|
1339
|
-
*
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
/**
|
|
1343
|
-
* Routes one or more commands' autocomplete to an {@link AutocompleteHandler}.
|
|
1023
|
+
* Pass the command route(s) from the generated registry as the generic, the same string(s) as
|
|
1024
|
+
* `@AutocompleteRoute`. Branch on the focused field with `this.match`, read already-entered sibling options
|
|
1025
|
+
* with `this.options`, and find which command fired with `this.route`.
|
|
1344
1026
|
*
|
|
1345
|
-
*
|
|
1346
|
-
*
|
|
1347
|
-
* fields. The decorator routes and the generic must match exactly, so listing fewer or more than the
|
|
1348
|
-
* handler declares is a compile error.
|
|
1027
|
+
* @typeParam Route - One or more route keys from {@link SlashOptionRegistry}, e.g. `'search'` or `'search' | 'find'`.
|
|
1028
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1349
1029
|
*
|
|
1350
|
-
* @param routes - The command route string(s) this handler serves, e.g. `'search'` or `'search', 'find'`.
|
|
1351
|
-
* @decorator
|
|
1352
1030
|
* @example
|
|
1353
1031
|
* ```ts
|
|
1354
1032
|
* \@AutocompleteRoute('search')
|
|
1355
1033
|
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1356
1034
|
* async execute() {
|
|
1357
|
-
* await this.match({
|
|
1035
|
+
* await this.match({
|
|
1036
|
+
* query: (value, respond) => respond([{ name: value, value }])
|
|
1037
|
+
* });
|
|
1358
1038
|
* }
|
|
1359
1039
|
* }
|
|
1360
1040
|
* ```
|
|
1361
1041
|
*/
|
|
1362
|
-
declare
|
|
1363
|
-
/** @internal */
|
|
1364
|
-
|
|
1365
|
-
|
|
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
|
-
|
|
1042
|
+
declare abstract class AutocompleteHandler<Route extends keyof SlashOptionRegistry, Cache extends CacheType = 'cached'> extends BaseHandler$1<AutocompleteInteraction<Cache>> {
|
|
1043
|
+
/** @internal */
|
|
1044
|
+
readonly __autocompleteRoute?: Route;
|
|
1045
|
+
constructor(event: AutocompleteInteraction<Cache>, core: Core, dispatch?: DispatchContext);
|
|
1046
|
+
private decodedFocused?;
|
|
1047
|
+
/**
|
|
1048
|
+
* The focused option for this interaction. `value` is always the raw partial string the user is typing,
|
|
1049
|
+
* even for an integer or number option, so coerce it yourself when you need a number.
|
|
1050
|
+
*/
|
|
1051
|
+
protected get focused(): FocusedField<Route>;
|
|
1052
|
+
/**
|
|
1053
|
+
* Run the arm for the focused field. An autocomplete always dispatches by which field is focused, so
|
|
1054
|
+
* match is how you read it. There is no single-field shortcut the way slash/component handlers have one.
|
|
1055
|
+
*
|
|
1056
|
+
* Provide one arm per autocompletable field across the registered commands, keyed by field name. Each
|
|
1057
|
+
* arm receives the focused partial value and a `respond` typed to that field's choice value. The
|
|
1058
|
+
* arms must cover every autocompletable field, a missing field or an unknown key is a compile error. A
|
|
1059
|
+
* focused field with no arm, only reachable from a stale-deployed command, throws at runtime.
|
|
1060
|
+
*
|
|
1061
|
+
* @param arms - One handler per autocompletable field, keyed by field name.
|
|
1062
|
+
* @returns The result of the arm that ran.
|
|
1063
|
+
*
|
|
1064
|
+
* @example
|
|
1065
|
+
* ```ts
|
|
1066
|
+
* \@AutocompleteRoute('search')
|
|
1067
|
+
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1068
|
+
* async execute() {
|
|
1069
|
+
* await this.match({
|
|
1070
|
+
* query: (value, respond) => respond(titles(value).map((s) => ({ name: s, value: s }))),
|
|
1071
|
+
* tag: (value, respond) => respond(tags(value).map((s) => ({ name: s, value: s })))
|
|
1072
|
+
* });
|
|
1073
|
+
* }
|
|
1074
|
+
* }
|
|
1075
|
+
* ```
|
|
1076
|
+
*/
|
|
1077
|
+
protected match<Ret>(arms: FocusedArms<Route, Ret>): Promise<Ret>;
|
|
1078
|
+
/** Send autocomplete suggestions, callback type 8. Prefer {@link match}, which restricts each field's choices to its declared type. */
|
|
1079
|
+
protected respond(choices: readonly ApplicationCommandOptionChoiceData[]): Promise<void>;
|
|
1080
|
+
/** The firing command route, for a field whose completion differs per registered command. */
|
|
1081
|
+
protected get route(): Route;
|
|
1082
|
+
/**
|
|
1083
|
+
* The already-entered options on this command, restricted to the kinds Discord resolves during autocomplete
|
|
1084
|
+
* (string, integer, number, boolean) with every read nullable, since a sibling is partial while the user
|
|
1085
|
+
* types the focused field. The focused field is on `this.focused`.
|
|
1086
|
+
*/
|
|
1087
|
+
protected get options(): AutocompleteOptions<Route>;
|
|
1397
1088
|
}
|
|
1398
1089
|
//#endregion
|
|
1399
1090
|
//#region src/handlers/interaction/components/ComponentHandler.d.ts
|
|
1400
1091
|
type ComponentInteraction = ButtonInteraction | ModalSubmitInteraction | AnySelectMenuInteraction;
|
|
1401
|
-
type SingleParams<Defs extends readonly AnyCustomId[]> = Defs extends readonly [infer One extends AnyCustomId] ? DecodedParams<One['shape']> : never;
|
|
1402
|
-
type MatchArms<Defs extends readonly AnyCustomId[], Ret> = { [Def in Defs[number] as Def['prefix']]: (params: DecodedParams<Def['shape']>) => Promisable<Ret> };
|
|
1403
1092
|
/**
|
|
1404
1093
|
* Shared base the customId-routed component handlers extend.
|
|
1405
1094
|
*
|
|
1406
|
-
* Not a public entry point.
|
|
1407
|
-
*
|
|
1408
|
-
* those bases share, so DO NOT use it directly.
|
|
1095
|
+
* Not a public entry point. Extend {@link ButtonHandler}, {@link SelectMenuHandler}, or {@link ModalHandler}
|
|
1096
|
+
* instead. This class defines the customId decode and the route matching those bases share.
|
|
1409
1097
|
*
|
|
1410
1098
|
* @typeParam Event - The component interaction type this handler processes
|
|
1411
1099
|
* @typeParam Defs - The customId route definitions registered on the concrete handler
|
|
@@ -1413,7 +1101,10 @@ type MatchArms<Defs extends readonly AnyCustomId[], Ret> = { [Def in Defs[number
|
|
|
1413
1101
|
declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs extends readonly AnyCustomId[]> extends InteractionHandler<Event> implements HasComponentDefs<Defs> {
|
|
1414
1102
|
/** @internal */
|
|
1415
1103
|
readonly __componentDefs?: Defs;
|
|
1416
|
-
|
|
1104
|
+
/** Rewrite the source message this component interaction came from. */
|
|
1105
|
+
protected update(response: ReplyResponse | string): Promise<SentMessage>;
|
|
1106
|
+
/** Acknowledge the component without changing the source message. */
|
|
1107
|
+
protected deferUpdate(): Promise<void>;
|
|
1417
1108
|
private decoded?;
|
|
1418
1109
|
private get route();
|
|
1419
1110
|
/**
|
|
@@ -1431,10 +1122,11 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1431
1122
|
* handler `this.params` is `never`, so match is the only way to read the decoded params.
|
|
1432
1123
|
*
|
|
1433
1124
|
* Provide one arm per registered route, keyed by its prefix, and each arm receives that route's own
|
|
1434
|
-
* decoded params. The arms
|
|
1435
|
-
*
|
|
1125
|
+
* decoded params. The arms cover every registered route prefix, checked at compile time, and a prefix
|
|
1126
|
+
* unmatched at runtime throws `CustomIdMatchArmMissing`. Decoding runs before any arm, so a stale or
|
|
1127
|
+
* corrupt wire throws before an arm body executes.
|
|
1436
1128
|
*
|
|
1437
|
-
* @param arms - One
|
|
1129
|
+
* @param arms - One callback per registered route, keyed by prefix.
|
|
1438
1130
|
* @returns The result of the arm that ran.
|
|
1439
1131
|
*
|
|
1440
1132
|
* @example
|
|
@@ -1443,8 +1135,8 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1443
1135
|
* class ReviewButtons extends ButtonHandler<[typeof Approve, typeof Reject]> {
|
|
1444
1136
|
* async execute() {
|
|
1445
1137
|
* await this.match({
|
|
1446
|
-
* approve: ({ userId }) => this.
|
|
1447
|
-
* reject: ({ userId }) => this.
|
|
1138
|
+
* approve: ({ userId }) => this.reply(`approved <@${userId}>`),
|
|
1139
|
+
* reject: ({ userId }) => this.reply(`rejected <@${userId}>`)
|
|
1448
1140
|
* });
|
|
1449
1141
|
* }
|
|
1450
1142
|
* }
|
|
@@ -1458,8 +1150,9 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1458
1150
|
* Base class for a button interaction handler.
|
|
1459
1151
|
*
|
|
1460
1152
|
* Register the customId definitions this handler decodes with `@ButtonRoute`, list the same ones in the
|
|
1461
|
-
* generic, then read `this.params` for a single route or `this.match` for several.
|
|
1462
|
-
*
|
|
1153
|
+
* generic, then read `this.params` for a single route or `this.match` for several. Reply through the handler
|
|
1154
|
+
* members, or rewrite the source message with `this.update`. Passing different definitions to the decorator
|
|
1155
|
+
* and the generic is a compile error.
|
|
1463
1156
|
*
|
|
1464
1157
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof ApproveId]`.
|
|
1465
1158
|
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
@@ -1470,12 +1163,15 @@ declare abstract class ComponentHandler<Event extends ComponentInteraction, Defs
|
|
|
1470
1163
|
* class ApproveButton extends ButtonHandler<[typeof ApproveId]> {
|
|
1471
1164
|
* async execute() {
|
|
1472
1165
|
* const { userId } = this.params;
|
|
1473
|
-
* await this.
|
|
1166
|
+
* await this.reply(`approved <@${userId}>`);
|
|
1474
1167
|
* }
|
|
1475
1168
|
* }
|
|
1476
1169
|
* ```
|
|
1477
1170
|
*/
|
|
1478
|
-
declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ButtonInteraction<Cache>, Defs> {
|
|
1171
|
+
declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ButtonInteraction<Cache>, Defs> {
|
|
1172
|
+
/** @internal */
|
|
1173
|
+
readonly __component?: 'button';
|
|
1174
|
+
}
|
|
1479
1175
|
//#endregion
|
|
1480
1176
|
//#region src/handlers/interaction/components/ModalHandler.d.ts
|
|
1481
1177
|
/**
|
|
@@ -1483,7 +1179,8 @@ declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache
|
|
|
1483
1179
|
*
|
|
1484
1180
|
* Register the customId definitions this handler decodes with `@ModalRoute`, list the same ones in the
|
|
1485
1181
|
* generic, then read `this.params` for a single route or `this.match` for several. Read the submitted
|
|
1486
|
-
* inputs from `this.event.fields
|
|
1182
|
+
* inputs from `this.event.fields`, and reply through the handler members. Discord forbids opening a modal in
|
|
1183
|
+
* response to a modal, so `showModal` fails compilation on this kind.
|
|
1487
1184
|
*
|
|
1488
1185
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof ConfigId]`.
|
|
1489
1186
|
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
@@ -1495,20 +1192,25 @@ declare abstract class ButtonHandler<Defs extends readonly AnyCustomId[], Cache
|
|
|
1495
1192
|
* async execute() {
|
|
1496
1193
|
* const { guildId } = this.params;
|
|
1497
1194
|
* const name = this.event.fields.getTextInputValue('name');
|
|
1498
|
-
* await this.
|
|
1195
|
+
* await this.reply(`saved ${name} for ${guildId}`);
|
|
1499
1196
|
* }
|
|
1500
1197
|
* }
|
|
1501
1198
|
* ```
|
|
1502
1199
|
*/
|
|
1503
|
-
declare abstract class ModalHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ModalSubmitInteraction<Cache>, Defs> {
|
|
1200
|
+
declare abstract class ModalHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<ModalSubmitInteraction<Cache>, Defs> {
|
|
1201
|
+
/** @internal */
|
|
1202
|
+
readonly __component?: 'modal';
|
|
1203
|
+
}
|
|
1504
1204
|
//#endregion
|
|
1505
1205
|
//#region src/handlers/interaction/components/SelectMenuHandler.d.ts
|
|
1206
|
+
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;
|
|
1506
1207
|
/**
|
|
1507
1208
|
* Base class for a select menu handler.
|
|
1508
1209
|
*
|
|
1509
1210
|
* Pass the select kind first and the customId definitions second, the same order as `@SelectMenuRoute`,
|
|
1510
1211
|
* so `this.event` and `this.event.values` are narrowed to that kind. Read `this.params` for a single
|
|
1511
|
-
* route or `this.match` for several
|
|
1212
|
+
* route or `this.match` for several, and reply through the handler members or rewrite the source message
|
|
1213
|
+
* with `this.update`.
|
|
1512
1214
|
*
|
|
1513
1215
|
* @typeParam Kind - The select kind from {@link SelectMenuKind}, e.g. `SelectMenuKind.User`.
|
|
1514
1216
|
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof AssignId]`.
|
|
@@ -1520,12 +1222,15 @@ declare abstract class ModalHandler<Defs extends readonly AnyCustomId[], Cache e
|
|
|
1520
1222
|
* class AssignSelect extends SelectMenuHandler<SelectMenuKind.User, [typeof AssignId]> {
|
|
1521
1223
|
* async execute() {
|
|
1522
1224
|
* const { roleId } = this.params;
|
|
1523
|
-
* await this.
|
|
1225
|
+
* await this.reply(`assigning ${this.event.values.length} member(s) to <@&${roleId}>`);
|
|
1524
1226
|
* }
|
|
1525
1227
|
* }
|
|
1526
1228
|
* ```
|
|
1527
1229
|
*/
|
|
1528
|
-
declare abstract class SelectMenuHandler<Kind extends SelectMenuKind, Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<SelectMenuInteractionFor<Kind, Cache>, Defs> {
|
|
1230
|
+
declare abstract class SelectMenuHandler<Kind extends SelectMenuKind, Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends ComponentHandler<SelectMenuInteractionFor<Kind, Cache>, Defs> {
|
|
1231
|
+
/** @internal */
|
|
1232
|
+
readonly __component?: Kind;
|
|
1233
|
+
}
|
|
1529
1234
|
//#endregion
|
|
1530
1235
|
//#region src/bot/decorators/Middlewares.d.ts
|
|
1531
1236
|
/**
|
|
@@ -1613,36 +1318,37 @@ declare const IgnoreBots: import("@seedcord/core").Gate<EventGateContext<ValidNo
|
|
|
1613
1318
|
*/
|
|
1614
1319
|
declare function Nsfw(options?: GateNoticeOptions): Gate<InteractionGateContext<NonModalInteraction>, 'Nsfw'>;
|
|
1615
1320
|
//#endregion
|
|
1616
|
-
//#region src/bot/
|
|
1617
|
-
/** Whose permissions a check ran against, used to mention and label the subject in a refusal. */
|
|
1618
|
-
type PermSubject = Role | TextChannel | Guild | GuildMember;
|
|
1619
|
-
//#endregion
|
|
1620
|
-
//#region src/bot/utilities/permissions/checkPermissions.d.ts
|
|
1321
|
+
//#region src/bot/utilities/channels/fetchText.d.ts
|
|
1621
1322
|
/**
|
|
1622
|
-
*
|
|
1623
|
-
*
|
|
1323
|
+
* Fetches and validates a text channel. Refuses when the channel doesn't exist or isn't a text channel.
|
|
1324
|
+
*
|
|
1325
|
+
* @param client - The Discord client instance
|
|
1326
|
+
* @param channelId - Channel ID or TextChannel instance
|
|
1327
|
+
* @returns Promise resolving to the text channel
|
|
1624
1328
|
*/
|
|
1625
|
-
|
|
1329
|
+
declare function fetchText(client: Client, channelId: TextChannelResolvable): Promise<TextChannel>;
|
|
1330
|
+
//#endregion
|
|
1331
|
+
//#region src/bot/utilities/permissions/checkPermissions.d.ts
|
|
1626
1332
|
/**
|
|
1627
1333
|
* Optional custom error constructors for {@link CheckPermissionOptions}.
|
|
1628
1334
|
*/
|
|
1629
|
-
interface
|
|
1630
|
-
|
|
1631
|
-
|
|
1335
|
+
interface PermissionErrorNoticeOverrides {
|
|
1336
|
+
missingNotice?: new (message: string | undefined, subject: string, missingPerms: readonly string[]) => Notice;
|
|
1337
|
+
dangerousNotice?: new (message: string | undefined, subject: string, dangerousPerms: readonly string[]) => Notice;
|
|
1632
1338
|
}
|
|
1633
1339
|
/**
|
|
1634
1340
|
* Options for {@link checkPermissions}.
|
|
1635
1341
|
*
|
|
1636
|
-
* @see {@link
|
|
1342
|
+
* @see {@link PermissionErrorNoticeOverrides}
|
|
1637
1343
|
*/
|
|
1638
|
-
interface CheckPermissionOptions extends
|
|
1344
|
+
interface CheckPermissionOptions extends PermissionErrorNoticeOverrides {
|
|
1639
1345
|
/** Role or member whose permissions will be checked */
|
|
1640
1346
|
for: Role | GuildMember;
|
|
1641
|
-
/** Context where permissions apply
|
|
1347
|
+
/** Context where permissions apply */
|
|
1642
1348
|
in: Guild | TextChannel;
|
|
1643
1349
|
/** Permission bits to validate */
|
|
1644
|
-
scope:
|
|
1645
|
-
/** When true, ensure target does
|
|
1350
|
+
scope: PermissionScope;
|
|
1351
|
+
/** When true, ensure target does NOT have the given permissions */
|
|
1646
1352
|
inverse?: boolean;
|
|
1647
1353
|
}
|
|
1648
1354
|
/**
|
|
@@ -1682,7 +1388,7 @@ interface CheckPermissionOptions extends PermissionErrorCtors {
|
|
|
1682
1388
|
* });
|
|
1683
1389
|
* ```
|
|
1684
1390
|
*/
|
|
1685
|
-
declare function checkPermissions(target: Role | GuildMember, ctx: Guild, scope:
|
|
1391
|
+
declare function checkPermissions(target: Role | GuildMember, ctx: Guild, scope: PermissionScope, inverse?: boolean, errors?: PermissionErrorNoticeOverrides): void;
|
|
1686
1392
|
/**
|
|
1687
1393
|
* Checks permissions for a {@link Role} or a {@link GuildMember} in a {@link TextChannel}. Refuses when a
|
|
1688
1394
|
* permission in `scope` is missing, or with `inverse` when one is present.
|
|
@@ -1720,7 +1426,7 @@ declare function checkPermissions(target: Role | GuildMember, ctx: Guild, scope:
|
|
|
1720
1426
|
* });
|
|
1721
1427
|
* ```
|
|
1722
1428
|
*/
|
|
1723
|
-
declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel, scope:
|
|
1429
|
+
declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionErrorNoticeOverrides): void;
|
|
1724
1430
|
/**
|
|
1725
1431
|
* Checks permissions using an options object. Refuses when a permission in {@link CheckPermissionOptions.scope} is missing,
|
|
1726
1432
|
* or with `options.inverse` when one is present.
|
|
@@ -1764,123 +1470,6 @@ declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel,
|
|
|
1764
1470
|
*/
|
|
1765
1471
|
declare function checkPermissions(options: CheckPermissionOptions): void;
|
|
1766
1472
|
//#endregion
|
|
1767
|
-
//#region src/bot/gates/catalog/permissions.d.ts
|
|
1768
|
-
/**
|
|
1769
|
-
* Options for {@link RequirePermissions} and {@link RequireBotPermissions}, one override per refusal the gate
|
|
1770
|
-
* can show.
|
|
1771
|
-
*
|
|
1772
|
-
* @example
|
|
1773
|
-
* ```ts
|
|
1774
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1775
|
-
* import type { Guild, GuildMember, Role, TextChannel } from 'discord.js';
|
|
1776
|
-
*
|
|
1777
|
-
* // `missing` is a Notice ctor: (message, where, missingPerms)
|
|
1778
|
-
* class MissingPermsNotice extends Notice {
|
|
1779
|
-
* public constructor(message: string, where: Role | TextChannel | Guild | GuildMember, missing: string[]) {
|
|
1780
|
-
* super(`${message} (${missing.join(', ')})`);
|
|
1781
|
-
* }
|
|
1782
|
-
* }
|
|
1783
|
-
*
|
|
1784
|
-
* RequirePermissions([PermissionFlagsBits.BanMembers], { missing: MissingPermsNotice });
|
|
1785
|
-
* ```
|
|
1786
|
-
*/
|
|
1787
|
-
interface RequirePermissionsOptions {
|
|
1788
|
-
/** Reword or replace the refusal shown outside a guild. */
|
|
1789
|
-
notInGuild?: GateNoticeOptions;
|
|
1790
|
-
/** Replace the missing-permissions refusal with a ctor that receives the where and the missing perm names. */
|
|
1791
|
-
missing?: PermissionErrorCtors['missing'];
|
|
1792
|
-
}
|
|
1793
|
-
/**
|
|
1794
|
-
* Options for {@link RequireRole}, one override per refusal the gate can show.
|
|
1795
|
-
*/
|
|
1796
|
-
interface RequireRoleOptions {
|
|
1797
|
-
/** Reword or replace the refusal shown outside a guild. */
|
|
1798
|
-
notInGuild?: GateNoticeOptions;
|
|
1799
|
-
/** Reword or replace the refusal shown when the caller lacks the role. */
|
|
1800
|
-
missingRole?: GateNoticeOptions;
|
|
1801
|
-
}
|
|
1802
|
-
/**
|
|
1803
|
-
* Requires the caller to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
|
|
1804
|
-
*
|
|
1805
|
-
* Interaction-only and excludes ModalSubmit, since a modal lacks a reliable cached caller member.
|
|
1806
|
-
*
|
|
1807
|
-
* @param scope - The permission flag bits the caller must all hold.
|
|
1808
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-permissions one with `missing`.
|
|
1809
|
-
*
|
|
1810
|
-
* @see {@link Gated}
|
|
1811
|
-
*
|
|
1812
|
-
* @example
|
|
1813
|
-
* ```ts
|
|
1814
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1815
|
-
*
|
|
1816
|
-
* \@Gated(RequirePermissions([PermissionFlagsBits.BanMembers]))
|
|
1817
|
-
* \@SlashRoute('ban')
|
|
1818
|
-
* class BanHandler extends SlashHandler<'ban'> {
|
|
1819
|
-
* async execute() {
|
|
1820
|
-
* const target = this.options.getUser('target');
|
|
1821
|
-
* }
|
|
1822
|
-
* }
|
|
1823
|
-
* ```
|
|
1824
|
-
*/
|
|
1825
|
-
declare function RequirePermissions(scope: BotPermissionScope, options?: RequirePermissionsOptions): Gate<InteractionGateContext<NonModalInteraction>, 'RequirePermissions'>;
|
|
1826
|
-
/**
|
|
1827
|
-
* Requires the bot to hold every permission in `scope`, via `checkPermissions`. Refuses outside a guild.
|
|
1828
|
-
*
|
|
1829
|
-
* It reads the bot's own member, so it attaches to modal handlers as well.
|
|
1830
|
-
*
|
|
1831
|
-
* @param scope - The permission flag bits the bot must all hold.
|
|
1832
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-permissions one with `missing`.
|
|
1833
|
-
*
|
|
1834
|
-
* @see {@link Gated}
|
|
1835
|
-
*
|
|
1836
|
-
* @example
|
|
1837
|
-
* ```ts
|
|
1838
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1839
|
-
*
|
|
1840
|
-
* \@Gated(RequireBotPermissions([PermissionFlagsBits.BanMembers]))
|
|
1841
|
-
* \@ModalRoute(MyModalId)
|
|
1842
|
-
* class MyModalHandler extends ModalHandler<[typeof MyModalId]> {
|
|
1843
|
-
* async execute() {
|
|
1844
|
-
* // ...
|
|
1845
|
-
* }
|
|
1846
|
-
* }
|
|
1847
|
-
* ```
|
|
1848
|
-
*/
|
|
1849
|
-
declare function RequireBotPermissions(scope: BotPermissionScope, options?: RequirePermissionsOptions): Gate<InteractionGateContext, 'RequireBotPermissions'>;
|
|
1850
|
-
/**
|
|
1851
|
-
* Requires the caller to have `roleId`, read from the member's role cache. Refuses outside a guild first, then
|
|
1852
|
-
* when the role is missing.
|
|
1853
|
-
*
|
|
1854
|
-
* Interaction-only and excludes ModalSubmit.
|
|
1855
|
-
*
|
|
1856
|
-
* @param roleId - The role snowflake the caller must hold, read from the member's role cache.
|
|
1857
|
-
* @param options - Override each refusal, the outside-guild one with `notInGuild` and the missing-role one with `missingRole`.
|
|
1858
|
-
*
|
|
1859
|
-
* @see {@link Gated}
|
|
1860
|
-
*
|
|
1861
|
-
* @example
|
|
1862
|
-
* ```ts
|
|
1863
|
-
* \@Gated(RequireRole('123456789012345678'))
|
|
1864
|
-
* \@SlashRoute('vip')
|
|
1865
|
-
* class VipHandler extends SlashHandler<'vip'> {
|
|
1866
|
-
* async execute() {
|
|
1867
|
-
* // ...
|
|
1868
|
-
* }
|
|
1869
|
-
* }
|
|
1870
|
-
* ```
|
|
1871
|
-
*/
|
|
1872
|
-
declare function RequireRole(roleId: string, options?: RequireRoleOptions): Gate<InteractionGateContext<NonModalInteraction>, 'RequireRole'>;
|
|
1873
|
-
//#endregion
|
|
1874
|
-
//#region src/bot/utilities/channels/fetchText.d.ts
|
|
1875
|
-
/**
|
|
1876
|
-
* Fetches and validates a text channel. Refuses when the channel doesn't exist or isn't a text channel.
|
|
1877
|
-
*
|
|
1878
|
-
* @param client - The Discord client instance
|
|
1879
|
-
* @param channelId - Channel ID or TextChannel instance
|
|
1880
|
-
* @returns Promise resolving to the text channel
|
|
1881
|
-
*/
|
|
1882
|
-
declare function fetchText(client: Client, channelId: TextChannelResolvable): Promise<TextChannel>;
|
|
1883
|
-
//#endregion
|
|
1884
1473
|
//#region src/bot/utilities/permissions/checkBotPermissions.d.ts
|
|
1885
1474
|
/**
|
|
1886
1475
|
* Checks if the bot has required permissions in a {@link Guild} or {@link TextChannel}. Refuses when a
|
|
@@ -1903,28 +1492,23 @@ declare function fetchText(client: Client, channelId: TextChannelResolvable): Pr
|
|
|
1903
1492
|
* ]);
|
|
1904
1493
|
* ```
|
|
1905
1494
|
*/
|
|
1906
|
-
declare function checkBotPermissions(target: Guild | TextChannel, scope:
|
|
1495
|
+
declare function checkBotPermissions(target: Guild | TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionErrorNoticeOverrides): void;
|
|
1907
1496
|
//#endregion
|
|
1908
1497
|
//#region src/bot/utilities/permissions/hasPermsToAssign.d.ts
|
|
1909
1498
|
/**
|
|
1910
1499
|
* Optional custom error constructors for {@link HasPermsToAssignOptions}.
|
|
1911
1500
|
*/
|
|
1912
|
-
interface
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
|
|
1916
|
-
managed?: new (message: string) => Notice;
|
|
1917
|
-
/** Custom error for missing Manage Roles permission */
|
|
1918
|
-
missing?: new (message: string, where: Role | TextChannel | Guild | GuildMember, missingPerms: string[]) => Notice;
|
|
1501
|
+
interface AssignRoleNoticeOverrides {
|
|
1502
|
+
higherNotice?: new (message: string, role: Role, botRole: Role) => Notice;
|
|
1503
|
+
managedNotice?: new (message: string) => Notice;
|
|
1504
|
+
missingNotice?: new (message: string | undefined, subject: string, missingPerms: readonly string[]) => Notice;
|
|
1919
1505
|
}
|
|
1920
1506
|
/**
|
|
1921
1507
|
* Options for {@link hasPermsToAssign}.
|
|
1922
1508
|
*/
|
|
1923
1509
|
interface HasPermsToAssignOptions {
|
|
1924
|
-
/** Target role to validate for assignment */
|
|
1925
1510
|
targetRole: Role;
|
|
1926
|
-
|
|
1927
|
-
errors?: AssignRoleErrorCtors;
|
|
1511
|
+
noticeOverrides?: AssignRoleNoticeOverrides;
|
|
1928
1512
|
}
|
|
1929
1513
|
/**
|
|
1930
1514
|
* 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.
|
|
@@ -1941,10 +1525,10 @@ interface HasPermsToAssignOptions {
|
|
|
1941
1525
|
* // Check with custom error handling
|
|
1942
1526
|
* hasPermsToAssign({
|
|
1943
1527
|
* targetRole: role,
|
|
1944
|
-
*
|
|
1945
|
-
*
|
|
1946
|
-
*
|
|
1947
|
-
*
|
|
1528
|
+
* noticeOverrides: {
|
|
1529
|
+
* higherNotice: CustomHigherNotice,
|
|
1530
|
+
* managedNotice: CustomManagedNotice,
|
|
1531
|
+
* missingNotice: CustomMissingPermissionsNotice
|
|
1948
1532
|
* }
|
|
1949
1533
|
* });
|
|
1950
1534
|
* ```
|
|
@@ -2031,41 +1615,7 @@ declare function fetchManyUsers(client: Client, userIds: string[], options?: Fet
|
|
|
2031
1615
|
*/
|
|
2032
1616
|
declare function updateMemberRoles(rolesToAdd: Snowflake[], rolesToRemove: Snowflake[], member: GuildMember): Promise<void>;
|
|
2033
1617
|
//#endregion
|
|
2034
|
-
//#region src/bot/ReplySender.d.ts
|
|
2035
|
-
/**
|
|
2036
|
-
* Sends a {@link ReplyResponse} to an interaction, picking reply, editReply, or followUp from the live
|
|
2037
|
-
* acknowledgement state. Logs and drops its own send failures so a dead token never escapes into the
|
|
2038
|
-
* controller.
|
|
2039
|
-
*/
|
|
2040
|
-
declare class ReplySender {
|
|
2041
|
-
private readonly interaction;
|
|
2042
|
-
private readonly logger;
|
|
2043
|
-
constructor(interaction: Repliables);
|
|
2044
|
-
/**
|
|
2045
|
-
* Sends the reply and returns the sent message so a caller can attach a collector to it. Never throws,
|
|
2046
|
-
* a failed send is logged and dropped and resolves to `undefined`.
|
|
2047
|
-
*
|
|
2048
|
-
* @param response - The ComponentsV2 reply to show.
|
|
2049
|
-
* @param ephemeral - Whether the reply is ephemeral. {@default `true`}
|
|
2050
|
-
* @returns The sent {@link Message}, or `undefined` when the send was swallowed.
|
|
2051
|
-
*/
|
|
2052
|
-
send(response: ReplyResponse, ephemeral?: boolean): Promise<Message | undefined>;
|
|
2053
|
-
/**
|
|
2054
|
-
* Edits an already-sent message to a new {@link ReplyResponse}. Used to swap a confirmation prompt for
|
|
2055
|
-
* its outcome. Never throws, a failed edit is logged and dropped.
|
|
2056
|
-
*
|
|
2057
|
-
* @param message - The message to edit (the handle a prior {@link send} returned).
|
|
2058
|
-
* @param response - The reply to replace it with.
|
|
2059
|
-
*/
|
|
2060
|
-
edit(message: Message, response: ReplyResponse): Promise<void>;
|
|
2061
|
-
private dispatch;
|
|
2062
|
-
private replyOptions;
|
|
2063
|
-
private editBody;
|
|
2064
|
-
private logSwallowed;
|
|
2065
|
-
}
|
|
2066
|
-
//#endregion
|
|
2067
1618
|
//#region src/bot/confirm/getConfirmation.d.ts
|
|
2068
|
-
/** A confirm outcome to show, the reply itself or a factory for it. */
|
|
2069
1619
|
type Outcome = ReplyResponse | (() => Promisable<ReplyResponse>);
|
|
2070
1620
|
/** Options shared by both confirmation forms. */
|
|
2071
1621
|
interface ConfirmOptions {
|
|
@@ -2113,7 +1663,7 @@ interface DefaultConfirmOptions extends ConfirmOptions {
|
|
|
2113
1663
|
/**
|
|
2114
1664
|
* Shows a confirm/cancel prompt with built-in Confirm and Cancel buttons and resolves to `true` only if the
|
|
2115
1665
|
* invoking user clicks confirm. A cancel click or a timeout resolves to `false`. Gate the action behind it
|
|
2116
|
-
* with an early return.
|
|
1666
|
+
* with an early return. A failed prompt send throws into the fault boundary. Not usable from a
|
|
2117
1667
|
* {@link ModalHandler}, the `interaction` parameter excludes a modal submit at compile time.
|
|
2118
1668
|
*
|
|
2119
1669
|
* @param interaction - The repliable interaction to prompt on, `this.event` inside a non-modal handler.
|
|
@@ -2139,8 +1689,9 @@ interface DefaultConfirmOptions extends ConfirmOptions {
|
|
|
2139
1689
|
declare function getConfirmation(interaction: NonModalInteraction, prompt: string, options?: DefaultConfirmOptions): Promise<boolean>;
|
|
2140
1690
|
/**
|
|
2141
1691
|
* Shows a confirm/cancel prompt you build yourself and resolves to `true` only if the invoking user clicks
|
|
2142
|
-
* confirm. The factory receives the two minted button ids
|
|
2143
|
-
* timeout resolves to `false`.
|
|
1692
|
+
* confirm. The factory receives the two minted button ids. Set them on your own buttons. A cancel click or a
|
|
1693
|
+
* timeout resolves to `false`. A failed prompt send throws into the fault boundary. Not usable from a
|
|
1694
|
+
* {@link ModalHandler}.
|
|
2144
1695
|
*
|
|
2145
1696
|
* @param interaction - The repliable interaction to prompt on, `this.event` inside a non-modal handler.
|
|
2146
1697
|
* @param prompt - A factory given the minted `{ confirm, cancel }` ids that returns the reply to show. Build
|
|
@@ -2294,7 +1845,11 @@ interface PaginatorConfig<Item, Prefix extends string> {
|
|
|
2294
1845
|
renderItem?: ItemRender<Item>;
|
|
2295
1846
|
/** Take over the whole page tree. Receives the page data and the controls factory. */
|
|
2296
1847
|
render?: PageRender<Item>;
|
|
2297
|
-
/**
|
|
1848
|
+
/**
|
|
1849
|
+
* Whether the first page is ephemeral.
|
|
1850
|
+
*
|
|
1851
|
+
* @defaultValue `false`
|
|
1852
|
+
*/
|
|
2298
1853
|
ephemeral?: boolean;
|
|
2299
1854
|
}
|
|
2300
1855
|
type PaginatorHandlerCtor<Prefix extends string> = new (event: ButtonInteraction<'cached'>, core: Core) => ButtonHandler<[PageCursor<Prefix>]> & {
|
|
@@ -2327,7 +1882,7 @@ declare class Paginator<Item, const Prefix extends string> {
|
|
|
2327
1882
|
private readonly config;
|
|
2328
1883
|
constructor(config: PaginatorConfig<Item, Prefix>);
|
|
2329
1884
|
/** Render page 0 and send it, picking reply or followUp from the interaction's state. */
|
|
2330
|
-
start(interaction: Repliables, core?: Core): Promise<Message
|
|
1885
|
+
start(interaction: Repliables, core?: Core): Promise<Message>;
|
|
2331
1886
|
/** Render a page as a {@link ReplyResponse}. To post it elsewhere, add `flags: MessageFlags.IsComponentsV2`. */
|
|
2332
1887
|
page(ctx: PageContext, n: number): Promise<ReplyResponse>;
|
|
2333
1888
|
}
|
|
@@ -2398,27 +1953,103 @@ interface SubscribeOptions {
|
|
|
2398
1953
|
*/
|
|
2399
1954
|
declare function Subscribe<TSubscriber extends SubscriptionKey>(subscriber: TSubscriber, options?: SubscribeOptions): <HandlerCtor extends Constructor<Subscriber<TSubscriber>>>(constructor: HandlerCtor) => void;
|
|
2400
1955
|
//#endregion
|
|
1956
|
+
//#region src/subscribers/bases/WebhookSender.d.ts
|
|
1957
|
+
/**
|
|
1958
|
+
* A file attached to a webhook report.
|
|
1959
|
+
*/
|
|
1960
|
+
interface WebhookFile {
|
|
1961
|
+
name: string;
|
|
1962
|
+
description: string;
|
|
1963
|
+
data: Buffer;
|
|
1964
|
+
}
|
|
1965
|
+
/**
|
|
1966
|
+
* The payload {@link WebhookSender.send} posts.
|
|
1967
|
+
*/
|
|
1968
|
+
interface WebhookSendOptions {
|
|
1969
|
+
flags: number;
|
|
1970
|
+
username: string;
|
|
1971
|
+
components: readonly {
|
|
1972
|
+
toJSON(): APIMessageTopLevelComponent;
|
|
1973
|
+
}[];
|
|
1974
|
+
files?: readonly WebhookFile[] | undefined;
|
|
1975
|
+
}
|
|
1976
|
+
/**
|
|
1977
|
+
* Sends component messages to a Discord webhook through `@discordjs/rest`.
|
|
1978
|
+
*
|
|
1979
|
+
* @throws A `SeedcordError` when the url does not carry a webhook id and token.
|
|
1980
|
+
*/
|
|
1981
|
+
declare class WebhookSender {
|
|
1982
|
+
private readonly rest;
|
|
1983
|
+
private readonly route;
|
|
1984
|
+
constructor(url: string);
|
|
1985
|
+
/**
|
|
1986
|
+
* Fetches the webhook object, sending no message. Returns `missing` on a 404 or 401 from
|
|
1987
|
+
* Discord and `unreachable` on any other failure.
|
|
1988
|
+
*/
|
|
1989
|
+
verify(): Promise<'ok' | 'missing' | 'unreachable'>;
|
|
1990
|
+
send(options: WebhookSendOptions): Promise<void>;
|
|
1991
|
+
}
|
|
1992
|
+
//#endregion
|
|
2401
1993
|
//#region src/subscribers/bases/WebhookLog.d.ts
|
|
2402
1994
|
/**
|
|
2403
|
-
*
|
|
1995
|
+
* The content a reporter returns from {@link WebhookLog.report}.
|
|
1996
|
+
*/
|
|
1997
|
+
interface WebhookReport {
|
|
1998
|
+
/** Shown as the webhook message author. Defaults to the reporter's class name. */
|
|
1999
|
+
username?: string;
|
|
2000
|
+
components: readonly {
|
|
2001
|
+
toJSON(): APIMessageTopLevelComponent;
|
|
2002
|
+
}[];
|
|
2003
|
+
files?: readonly WebhookFile[] | undefined;
|
|
2004
|
+
}
|
|
2005
|
+
/**
|
|
2006
|
+
* Base class for subscribers that deliver their event to a Discord webhook.
|
|
2404
2007
|
*
|
|
2405
|
-
*
|
|
2406
|
-
*
|
|
2008
|
+
* Declare the url's environment variable with `@WebhookUrl` and implement {@link report}. Url
|
|
2009
|
+
* resolution, validation, sender reuse, and sending run in the base. When the variable is unset
|
|
2010
|
+
* the reporter is skipped at registration with a boot warning.
|
|
2407
2011
|
*
|
|
2408
|
-
* @typeParam KeyOfSubscribers - The
|
|
2012
|
+
* @typeParam KeyOfSubscribers - The subscription key this reporter receives
|
|
2409
2013
|
*/
|
|
2410
2014
|
declare abstract class WebhookLog<KeyOfSubscribers extends SubscriptionKey> extends Subscriber<KeyOfSubscribers> {
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2015
|
+
private static readonly senders;
|
|
2016
|
+
/** Builds the message for one published event. */
|
|
2017
|
+
abstract report(): WebhookReport | Promise<WebhookReport>;
|
|
2018
|
+
execute(): Promise<void>;
|
|
2019
|
+
/** @internal */
|
|
2020
|
+
static senderFor(url: string): WebhookSender;
|
|
2021
|
+
/** @internal */
|
|
2022
|
+
static envKeyOf(ctor: NewableFunction): string;
|
|
2023
|
+
/** @internal Returns null when the env var is unset, throws when set but malformed. */
|
|
2024
|
+
static urlOf(envKey: string): string | null;
|
|
2414
2025
|
}
|
|
2415
2026
|
//#endregion
|
|
2416
|
-
//#region src/
|
|
2027
|
+
//#region src/subscribers/decorators/WebhookUrl.d.ts
|
|
2417
2028
|
/**
|
|
2418
|
-
*
|
|
2029
|
+
* Declares the environment variable a {@link WebhookLog} reporter reads its webhook url from.
|
|
2030
|
+
*
|
|
2031
|
+
* An unset variable disables the reporter with a boot warning. A set but malformed value throws
|
|
2032
|
+
* at boot.
|
|
2419
2033
|
*
|
|
2420
|
-
*
|
|
2421
|
-
*
|
|
2034
|
+
* @param envKey - The environment variable name holding the webhook url
|
|
2035
|
+
* @decorator
|
|
2036
|
+
* @example
|
|
2037
|
+
* ```ts
|
|
2038
|
+
* \@Subscribe('memberBanned')
|
|
2039
|
+
* \@WebhookUrl('BAN_LOG_WEBHOOK_URL')
|
|
2040
|
+
* class BanLog extends WebhookLog<'memberBanned'> {
|
|
2041
|
+
* report() {
|
|
2042
|
+
* return { components: [new BanCard(this.data).component] };
|
|
2043
|
+
* }
|
|
2044
|
+
* }
|
|
2045
|
+
* ```
|
|
2046
|
+
*/
|
|
2047
|
+
declare function WebhookUrl(envKey: string): <HandlerCtor extends Constructor<WebhookLog<SubscriptionKey>>>(constructor: HandlerCtor) => void;
|
|
2048
|
+
//#endregion
|
|
2049
|
+
//#region src/Seedcord.d.ts
|
|
2050
|
+
/**
|
|
2051
|
+
* The gateway bot host. Opens a discord.js gateway session, discovers handlers, and runs
|
|
2052
|
+
* coordinated startup and shutdown. Attach plugins with `attach()`.
|
|
2422
2053
|
*/
|
|
2423
2054
|
declare class Seedcord extends Pluggable implements Core {
|
|
2424
2055
|
readonly config: GatewayConfig;
|
|
@@ -2428,8 +2059,7 @@ declare class Seedcord extends Pluggable implements Core {
|
|
|
2428
2059
|
readonly augmentTarget = "@seedcord/gateway";
|
|
2429
2060
|
/** @internal */
|
|
2430
2061
|
readonly version: string;
|
|
2431
|
-
private
|
|
2432
|
-
private readonly healthCheck;
|
|
2062
|
+
private readonly healthCheck?;
|
|
2433
2063
|
private readonly hmrManager;
|
|
2434
2064
|
/** @see {@link CoordinatedShutdown} */
|
|
2435
2065
|
readonly shutdown: CoordinatedShutdown;
|
|
@@ -2442,20 +2072,19 @@ declare class Seedcord extends Pluggable implements Core {
|
|
|
2442
2072
|
/** @see {@link IRateLimiter} */
|
|
2443
2073
|
readonly rateLimiter: IRateLimiter;
|
|
2444
2074
|
/**
|
|
2445
|
-
* Creates a new Seedcord instance
|
|
2446
|
-
*
|
|
2447
2075
|
* @param config - Bot configuration including paths and Discord client options
|
|
2448
2076
|
* @throws A **SeedcordError** When attempting to create multiple instances (singleton)
|
|
2449
2077
|
*/
|
|
2450
2078
|
constructor(config: GatewayConfig);
|
|
2451
2079
|
/** The bot's discord username, populated after login. */
|
|
2452
2080
|
get username(): string | undefined;
|
|
2453
|
-
|
|
2081
|
+
protected pluginCapabilities(): PluginCapabilities;
|
|
2082
|
+
protected static reset(): void;
|
|
2454
2083
|
private registerStartupTasks;
|
|
2455
2084
|
/**
|
|
2456
2085
|
* Starts the bot and runs all initialization tasks
|
|
2457
2086
|
*
|
|
2458
|
-
* @returns This Seedcord instance when
|
|
2087
|
+
* @returns This Seedcord instance when initialized
|
|
2459
2088
|
*/
|
|
2460
2089
|
start(): Promise<this>;
|
|
2461
2090
|
private registerHmrAwareModules;
|
|
@@ -2465,5 +2094,5 @@ declare class Seedcord extends Pluggable implements Core {
|
|
|
2465
2094
|
/** Package version */
|
|
2466
2095
|
declare const version: string;
|
|
2467
2096
|
//#endregion
|
|
2468
|
-
export {
|
|
2097
|
+
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 InjectedEmojiMap, type InjectedMentionMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, Middleware, type MiddlewareOptions, MiddlewareType, ModalHandler, Nsfw, Paginator, type PaginatorControls, type PermissionErrorNoticeOverrides, RegisterEvent, type RegisterEventOptions, RepliableHandler, type Repliables, Seedcord, SelectMenuHandler, SlashHandler, type SlashOptions, 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 };
|
|
2469
2098
|
//# sourceMappingURL=index.d.mts.map
|