@seedcord/gateway 0.5.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +729 -653
- package/dist/index.mjs +308 -202
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -9
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
2
|
import { WinstonConsoleSink, WinstonFileSink } from "@seedcord/logger/node";
|
|
3
|
-
import { AutocompletableNames, AutocompleteRouteBrand, CacheFor, ChoiceValueOf, ComponentDefsBrand, ComponentKindBrand, ContextMenuKindBrand, ContextMenuLeaves, ContextMenuNamesBrand, EntryFor, FocusedField, GateFitsWith, HasComponentDefs, Initializeable, MatchArms, MenuCacheFor, NamesFor, PageCursor, SingleParams, SlashOptions as SlashOptions$1, SlashRouteBrand } from "@seedcord/core/internal";
|
|
4
|
-
import { ArraySourceBase, AutocompleteOptions, BaseHandler as BaseHandler$1, BaseReplySender, Bus, CoreBase, CursorSourceBase, DispatchContext, Gate, GateContextBase, GateNoticeOptions, GuildPermissionsContext, InteractionKind, ModalLike, Notice, PageSourceBase, PaginatorBase, PaginatorConfig, PermissionNoticeOverrides, PermissionScope, RepliableHandler as RepliableHandler$1, RequiredOf, ResolvedEmoji, SlashRegistry, Subscriber as Subscriber$1, SubscriptionKey, WebhookLog as WebhookLog$1 } from "@seedcord/core";
|
|
3
|
+
import { AutocompletableNames, AutocompleteRouteBrand, CacheFor, ChoiceValueOf, ComponentDefsBrand, ComponentKindBrand, ContextMenuKindBrand, ContextMenuLeaves, ContextMenuNamesBrand, EntryFor, FocusedField, GateFitsWith, HasComponentDefs, Initializeable, MatchArms, MenuCacheFor, MiddlewareKindsBrand, NamesFor, PageCursor, SingleParams, SlashOptions as SlashOptions$1, SlashRouteBrand } from "@seedcord/core/internal";
|
|
4
|
+
import { ArraySourceBase, AutocompleteOptions, BaseHandler as BaseHandler$1, BaseReplySender, Bus, CoreBase, CursorSourceBase, DispatchContext, DispatchOutcome, DispatchResult, EventDispatchResult, Gate, GateContextBase, GateNoticeOptions, GuildPermissionsContext, HandlerOutcome, InteractionKind, MiddlewareKind, ModalLike, Notice, PageSourceBase, PaginatorBase, PaginatorConfig, PermissionNoticeOverrides, PermissionScope, RepliableHandler as RepliableHandler$1, RequiredOf, ResolvedEmoji, SlashRegistry, Subscriber as Subscriber$1, SubscriptionKey, WebhookLog as WebhookLog$1 } from "@seedcord/core";
|
|
5
5
|
import { Logger } from "@seedcord/logger";
|
|
6
6
|
import { APIInteractionGuildMember, APIModalInteractionResponseCallbackData, AnySelectMenuInteraction, ApplicationCommandOptionChoiceData, ApplicationCommandType, ApplicationEmoji, AutocompleteInteraction, BaseMessageOptions, BooleanCache, ButtonInteraction, ButtonStyle, CacheType, CacheTypeReducer, ChannelSelectMenuInteraction, ChatInputCommandInteraction, Client, ClientEvents, ClientOptions, CommandInteractionOption, ContextMenuCommandInteraction, Events, Guild, GuildEmoji, GuildMember, Interaction, MentionableSelectMenuInteraction, Message, MessageContextMenuCommandInteraction, ModalSubmitFields, ModalSubmitInteraction, Role, RoleSelectMenuInteraction, StringSelectMenuInteraction, TextChannel, User, UserContextMenuCommandInteraction, UserSelectMenuInteraction } from "discord.js";
|
|
7
7
|
import { Plugin as Plugin$1, PluginLifecycleSpec, PluginOptions, PluginOptions as PluginOptions$1 } from "@seedcord/core/plugin";
|
|
@@ -27,9 +27,25 @@ declare module '@seedcord/core/internal' {
|
|
|
27
27
|
};
|
|
28
28
|
/** Triggered before an event's handlers run. An event that no handler registered never triggers it. */
|
|
29
29
|
eventDispatching: { [Name in keyof ClientEvents]: {
|
|
30
|
+
dispatchId: string;
|
|
30
31
|
name: Name;
|
|
31
32
|
args: ClientEvents[Name];
|
|
32
33
|
}; }[keyof ClientEvents];
|
|
34
|
+
/**
|
|
35
|
+
* Triggered once an event's handlers settle, pairing with `eventDispatching`. A fire that runs no
|
|
36
|
+
* handler triggers neither.
|
|
37
|
+
*/
|
|
38
|
+
eventDispatched: {
|
|
39
|
+
/** The same id `eventDispatching` published for this fire. */
|
|
40
|
+
dispatchId: string;
|
|
41
|
+
name: keyof ClientEvents;
|
|
42
|
+
/** How the middleware chain ended. A chain that refused the event leaves `handlers` empty. */
|
|
43
|
+
outcome: DispatchOutcome;
|
|
44
|
+
/** One entry per handler that ran, in the order they ran. */
|
|
45
|
+
handlers: readonly HandlerOutcome[];
|
|
46
|
+
/** Dispatch entry until every handler settles. A clock change never affects it. */
|
|
47
|
+
durationMs: number;
|
|
48
|
+
};
|
|
33
49
|
/** Triggered for every interaction the bot receives, before routing. */
|
|
34
50
|
anyInteraction: {
|
|
35
51
|
interaction: Interaction;
|
|
@@ -159,6 +175,8 @@ declare class InteractionDispatcher implements Initializeable, HmrAware {
|
|
|
159
175
|
private processInteraction;
|
|
160
176
|
private answer;
|
|
161
177
|
private buildHandler;
|
|
178
|
+
private reporterFor;
|
|
179
|
+
private refusalBeforeHandler;
|
|
162
180
|
private runMiddlewares;
|
|
163
181
|
private gateRefusal;
|
|
164
182
|
private handleInteraction;
|
|
@@ -469,7 +487,7 @@ type EventMatchArms<Names extends ValidNonInteractionKeys, Ret> = { [Name in Nam
|
|
|
469
487
|
*/
|
|
470
488
|
declare abstract class EventHandler<in out Names extends ValidNonInteractionKeys> extends BaseHandler<ClientEvents[Names]> {
|
|
471
489
|
private readonly firedEvent;
|
|
472
|
-
constructor(event: ClientEvents[Names], core: Core, eventName?: Names);
|
|
490
|
+
constructor(event: ClientEvents[Names], core: Core, dispatch: DispatchContext, eventName?: Names);
|
|
473
491
|
protected readonly event: SingleEventPayload<Names>;
|
|
474
492
|
/**
|
|
475
493
|
* Run the arm for whichever event fired. Use this only when the handler is registered for several
|
|
@@ -513,7 +531,7 @@ declare abstract class EventHandler<in out Names extends ValidNonInteractionKeys
|
|
|
513
531
|
*/
|
|
514
532
|
declare abstract class EventMiddleware<in out EventName extends ValidNonInteractionKeys = ValidNonInteractionKeys> extends BaseHandler<ClientEvents[EventName]> {
|
|
515
533
|
private readonly firedEvent;
|
|
516
|
-
constructor(event: ClientEvents[EventName], core: Core, eventName?: EventName);
|
|
534
|
+
constructor(event: ClientEvents[EventName], core: Core, dispatch: DispatchContext, eventName?: EventName);
|
|
517
535
|
protected readonly event: SingleEventPayload<EventName>;
|
|
518
536
|
/**
|
|
519
537
|
* The event that fired this middleware. Read it on a catchall or multi-event middleware, where `this.event`
|
|
@@ -521,6 +539,23 @@ declare abstract class EventMiddleware<in out EventName extends ValidNonInteract
|
|
|
521
539
|
* `this.event` directly and does not need this.
|
|
522
540
|
*/
|
|
523
541
|
protected get eventName(): EventName;
|
|
542
|
+
/**
|
|
543
|
+
* Runs once the event finishes, newest middleware first. Every middleware whose `execute()`
|
|
544
|
+
* started gets the call, a stopped chain and a throw included. Implement it to release something
|
|
545
|
+
* this middleware took in `execute()`. A throw in here is logged and goes no further.
|
|
546
|
+
*
|
|
547
|
+
* @param result - `outcome` reports the chain alone. `handlers` holds one entry per handler that
|
|
548
|
+
* ran, empty exactly when the chain stopped the event.
|
|
549
|
+
*
|
|
550
|
+
* @example
|
|
551
|
+
* ```ts
|
|
552
|
+
* // the base declares it. an implementation carries `override`.
|
|
553
|
+
* override async after(result: EventDispatchResult) {
|
|
554
|
+
* this.span.end();
|
|
555
|
+
* }
|
|
556
|
+
* ```
|
|
557
|
+
*/
|
|
558
|
+
after?(result: EventDispatchResult): Promise<void>;
|
|
524
559
|
}
|
|
525
560
|
//#endregion
|
|
526
561
|
//#region src/bot/decorators/Events.d.ts
|
|
@@ -582,7 +617,7 @@ type SentMessage = Message;
|
|
|
582
617
|
/** Writes interaction responses through discord.js. The repliable handler bases and the dispatcher construct it. */
|
|
583
618
|
declare class ReplySender extends BaseReplySender<SentMessage, GatewayFile> {
|
|
584
619
|
private readonly interaction;
|
|
585
|
-
constructor(interaction: Repliables,
|
|
620
|
+
constructor(interaction: Repliables, dispatch: DispatchContext, bus: Bus);
|
|
586
621
|
protected writeReply(response: GatewayReplyResponse | string, opts?: SendOpts): Promise<SentMessage | undefined>;
|
|
587
622
|
protected writeDefer(opts?: DeferOpts): Promise<void>;
|
|
588
623
|
protected writeDeferUpdate(): Promise<void>;
|
|
@@ -615,7 +650,7 @@ declare class ReplySender extends BaseReplySender<SentMessage, GatewayFile> {
|
|
|
615
650
|
declare abstract class RepliableHandler<Event extends Repliables> extends RepliableHandler$1<Event, Core, SentMessage, GatewayFile, ReplySender> {
|
|
616
651
|
/** @internal */
|
|
617
652
|
getEvent(): Event;
|
|
618
|
-
protected buildSender(event: Event, core: Core,
|
|
653
|
+
protected buildSender(event: Event, core: Core, dispatch: DispatchContext): ReplySender;
|
|
619
654
|
}
|
|
620
655
|
//#endregion
|
|
621
656
|
//#region src/handlers/interaction/InteractionHandler.d.ts
|
|
@@ -629,7 +664,7 @@ declare abstract class RepliableHandler<Event extends Repliables> extends Replia
|
|
|
629
664
|
* @typeParam Repliable - The interaction type this handler processes
|
|
630
665
|
*/
|
|
631
666
|
declare abstract class InteractionHandler<Repliable extends Repliables> extends RepliableHandler<Repliable> {
|
|
632
|
-
constructor(event: Repliable, core: Core, dispatch
|
|
667
|
+
constructor(event: Repliable, core: Core, dispatch: DispatchContext);
|
|
633
668
|
/**
|
|
634
669
|
* Open a modal. Must be the initial response to this interaction. The modal kind rejects this call at
|
|
635
670
|
* compile time (Discord forbids a modal in response to a modal).
|
|
@@ -771,248 +806,649 @@ type FitAll<TCtor extends AnyHandlerCtor, Gates extends readonly Gate<GateContex
|
|
|
771
806
|
*/
|
|
772
807
|
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;
|
|
773
808
|
//#endregion
|
|
774
|
-
//#region src/
|
|
775
|
-
/**
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
interface GatewayLens<Cache extends CacheType> {
|
|
789
|
-
user: NonNullable<CommandInteractionOption<Cache>['user']>;
|
|
790
|
-
member: NonNullable<CommandInteractionOption<Cache>['member']>;
|
|
791
|
-
channel: NonNullable<CommandInteractionOption<Cache>['channel']>;
|
|
792
|
-
role: NonNullable<CommandInteractionOption<Cache>['role']>;
|
|
793
|
-
mentionable: NonNullable<CommandInteractionOption<Cache>['member' | 'role' | 'user']>;
|
|
794
|
-
attachment: NonNullable<CommandInteractionOption<Cache>['attachment']>;
|
|
809
|
+
//#region src/bot/decorators/Middlewares.d.ts
|
|
810
|
+
/** Registration options for an event middleware. */
|
|
811
|
+
interface EventMiddlewareOptions<Events extends NonEmptyTuple<ValidNonInteractionKeys>> {
|
|
812
|
+
/**
|
|
813
|
+
* Restrict this middleware to certain Discord client events. The middleware's `EventMiddleware`
|
|
814
|
+
* generic must list the same events, or applying the decorator is a compile error. Omit it to run on
|
|
815
|
+
* every event.
|
|
816
|
+
*/
|
|
817
|
+
readonly events?: Events;
|
|
818
|
+
/** Lower runs earlier. Two middleware sharing a priority run in registration order.
|
|
819
|
+
*
|
|
820
|
+
* @defaultValue 0
|
|
821
|
+
*/
|
|
822
|
+
readonly priority?: number;
|
|
795
823
|
}
|
|
796
824
|
/**
|
|
797
|
-
*
|
|
798
|
-
* resolver method but restricts its `name` to that route's options of the matching kind, drops the null
|
|
799
|
-
* on required options, narrows `choices` to their literal union, and only appears when the route has an
|
|
800
|
-
* option of that kind. The rich kinds return exactly what the djs resolver returns.
|
|
801
|
-
*
|
|
802
|
-
* A channel option declared with `addChannelTypes` narrows `getChannel` to the matching channel subtype.
|
|
803
|
-
* Pass the raw `this.event.options` resolver for anything this view does not cover.
|
|
804
|
-
*
|
|
805
|
-
* @typeParam Route - A route key from the generated {@link SlashRegistry}.
|
|
806
|
-
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
807
|
-
*/
|
|
808
|
-
type SlashOptions<Route extends keyof SlashRegistry, Cache extends CacheType = CacheFor<Route>> = SlashOptions$1<Route, GatewayLens<Cache>>;
|
|
809
|
-
//#endregion
|
|
810
|
-
//#region src/handlers/interaction/SlashHandler.d.ts
|
|
811
|
-
type SlashMatchArms<Route extends keyof SlashRegistry, Cache extends CacheType, Ret> = { [Key in Route]: (options: SlashOptions<Key, Cache>) => Promisable<Ret>; };
|
|
812
|
-
/**
|
|
813
|
-
* Base class for a chat-input (slash) command handler.
|
|
814
|
-
*
|
|
815
|
-
* Pass the route from the generated registry as the generic, the same string as `@SlashRoute`, then read
|
|
816
|
-
* `this.options` for a single command or `this.match` for several. Command authoring stays plain
|
|
817
|
-
* discord.js, `seedcord codegen` reads its `toJSON()` to type these options.
|
|
825
|
+
* Registers an event middleware. It runs before the handlers for every event it lists.
|
|
818
826
|
*
|
|
819
|
-
* @
|
|
820
|
-
* @
|
|
827
|
+
* @param options - The events this middleware runs on and its ordering.
|
|
828
|
+
* @decorator
|
|
821
829
|
*
|
|
822
830
|
* @example
|
|
823
831
|
* ```ts
|
|
824
|
-
* \@
|
|
825
|
-
* class
|
|
832
|
+
* \@RegisterEventMiddleware({ events: [Events.MessageCreate], priority: 10 })
|
|
833
|
+
* class Audit extends EventMiddleware<Events.MessageCreate> {
|
|
826
834
|
* async execute() {
|
|
827
|
-
*
|
|
828
|
-
* const reason = this.options.getString('reason'); // string | null
|
|
835
|
+
* this.logger.info(this.event[0].id);
|
|
829
836
|
* }
|
|
830
837
|
* }
|
|
831
838
|
* ```
|
|
839
|
+
*
|
|
840
|
+
* @throws A **SeedcordTypeError** If `priority` is not a finite number.
|
|
832
841
|
*/
|
|
833
|
-
declare
|
|
834
|
-
/** @internal */
|
|
835
|
-
readonly [SlashRouteBrand]?: Route;
|
|
836
|
-
/**
|
|
837
|
-
* The typed options for this command's route. Only the getters for kinds this command declares appear.
|
|
838
|
-
* Each getter's name argument is restricted to that command's options of its kind.
|
|
839
|
-
*
|
|
840
|
-
* - A required option drops the null.
|
|
841
|
-
* - Choices narrow to their literal union.
|
|
842
|
-
* - A channel option declared with `addChannelTypes` narrows to those types.
|
|
843
|
-
*
|
|
844
|
-
* Use `this.event.options` directly for anything outside this view, such as `getSubcommand()`.
|
|
845
|
-
* However, for the common case, the methods in this would suffice.
|
|
846
|
-
*/
|
|
847
|
-
protected get options(): SlashOptions<Route, Cache>;
|
|
848
|
-
/**
|
|
849
|
-
* Run the arm for whichever command fired. Use this only when the handler is registered for several
|
|
850
|
-
* routes.
|
|
851
|
-
*
|
|
852
|
-
* Provide one arm per registered route, keyed by its route string, and each arm receives that route's
|
|
853
|
-
* own narrowed options. The arms must cover every route in the generic, a missing route or an unknown
|
|
854
|
-
* key is a compile error.
|
|
855
|
-
*
|
|
856
|
-
* @param arms - One handler per registered route, keyed by route string.
|
|
857
|
-
* @returns The result of the arm that ran.
|
|
858
|
-
*
|
|
859
|
-
* @example
|
|
860
|
-
* ```ts
|
|
861
|
-
* \@SlashRoute('ban', 'kick')
|
|
862
|
-
* class ModHandler extends SlashHandler<'ban' | 'kick'> {
|
|
863
|
-
* async execute() {
|
|
864
|
-
* await this.match({
|
|
865
|
-
* ban: (options) => this.event.guild?.members.ban(options.getUser('target').id),
|
|
866
|
-
* kick: (options) => this.event.guild?.members.kick(options.getUser('member').id)
|
|
867
|
-
* });
|
|
868
|
-
* }
|
|
869
|
-
* }
|
|
870
|
-
* ```
|
|
871
|
-
*/
|
|
872
|
-
protected match<Ret>(arms: SlashMatchArms<Route, Cache, Ret>): Promise<Ret>;
|
|
873
|
-
}
|
|
842
|
+
declare function RegisterEventMiddleware<const Events extends NonEmptyTuple<ValidNonInteractionKeys> = NonEmptyTuple<ValidNonInteractionKeys>>(options?: EventMiddlewareOptions<Events>): (ctor: Constructor<EventMiddleware<Events[number]>>) => void;
|
|
874
843
|
//#endregion
|
|
875
|
-
//#region src/
|
|
876
|
-
type UserMenuArms<Names extends NamesFor<ApplicationCommandType.User>, Ret> = { [Name in Names]: (target: User, member: CacheTypeReducer<MenuCacheFor<ApplicationCommandType.User, Name>, GuildMember, APIInteractionGuildMember> | null) => Promisable<Ret>; };
|
|
877
|
-
type MessageMenuArms<Names extends NamesFor<ApplicationCommandType.Message>, Ret> = { [Name in Names]: (target: Message<BooleanCache<MenuCacheFor<ApplicationCommandType.Message, Name>>>) => Promisable<Ret>; };
|
|
844
|
+
//#region src/bot/gates/catalog/IgnoreBots.d.ts
|
|
878
845
|
/**
|
|
879
|
-
*
|
|
880
|
-
*
|
|
881
|
-
*
|
|
882
|
-
* user from `this.target` and that same user's guild member from `this.targetMember`.
|
|
846
|
+
* Drops a client event whose actor is a bot, with a {@link Silence} so nothing is replied. Event-only, because a
|
|
847
|
+
* Silence on an interaction would leave Discord's failed-interaction state. It rejects an interaction handler at
|
|
848
|
+
* the decorator line. Takes no options, so attach it directly without calling it.
|
|
883
849
|
*
|
|
884
|
-
* @
|
|
885
|
-
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
850
|
+
* @see {@link Gated}
|
|
886
851
|
*
|
|
887
852
|
* @example
|
|
888
853
|
* ```ts
|
|
889
|
-
*
|
|
890
|
-
*
|
|
854
|
+
* import { Events } from 'discord.js';
|
|
855
|
+
*
|
|
856
|
+
* \@Gated(IgnoreBots)
|
|
857
|
+
* class OnMessage extends EventHandler<Events.MessageCreate> {
|
|
891
858
|
* async execute() {
|
|
892
|
-
*
|
|
859
|
+
* // ...
|
|
893
860
|
* }
|
|
894
861
|
* }
|
|
895
862
|
* ```
|
|
896
863
|
*/
|
|
897
|
-
declare
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
/** @internal */
|
|
901
|
-
readonly [ContextMenuNamesBrand]?: Names;
|
|
902
|
-
protected get target(): User;
|
|
903
|
-
/** The right-clicked user's guild member, null outside a guild. */
|
|
904
|
-
protected get targetMember(): CacheTypeReducer<Cache, GuildMember, APIInteractionGuildMember> | null;
|
|
905
|
-
/** Which of the registered commands fired. */
|
|
906
|
-
protected get commandName(): Names;
|
|
907
|
-
/**
|
|
908
|
-
* Run the arm for whichever command fired. Use this only when the handler is registered for several
|
|
909
|
-
* names.
|
|
910
|
-
*
|
|
911
|
-
* Provide one arm per registered name, keyed by the name Discord shows in the right-click menu. Each
|
|
912
|
-
* arm receives the clicked user and that user's guild member, both narrowed to the cache state of that
|
|
913
|
-
* one command. The arms must cover every name in the generic. A missing name or an unknown key is a
|
|
914
|
-
* compile error.
|
|
915
|
-
*
|
|
916
|
-
* @param arms - One handler per registered command name.
|
|
917
|
-
* @returns The result of the arm that ran.
|
|
918
|
-
*
|
|
919
|
-
* @example
|
|
920
|
-
* ```ts
|
|
921
|
-
* \@UserContextMenuRoute('View Profile', 'Warn')
|
|
922
|
-
* class Moderation extends UserContextMenuHandler<'View Profile' | 'Warn'> {
|
|
923
|
-
* async execute() {
|
|
924
|
-
* await this.match({
|
|
925
|
-
* 'View Profile': (user) => this.reply(`Profile for ${user.tag}.`),
|
|
926
|
-
* Warn: (user, member) => this.reply(`Warned ${member?.displayName ?? user.tag}.`)
|
|
927
|
-
* });
|
|
928
|
-
* }
|
|
929
|
-
* }
|
|
930
|
-
* ```
|
|
931
|
-
*/
|
|
932
|
-
protected match<Ret>(arms: UserMenuArms<Names, Ret>): Promise<Ret>;
|
|
933
|
-
}
|
|
864
|
+
declare const IgnoreBots: import("@seedcord/core").Gate<EventGateContext<ValidNonInteractionKeys>, "IgnoreBots">;
|
|
865
|
+
//#endregion
|
|
866
|
+
//#region src/bot/gates/catalog/Nsfw.d.ts
|
|
934
867
|
/**
|
|
935
|
-
*
|
|
868
|
+
* Requires an age-restricted channel, else refuses. Pass {@link GateNoticeOptions} to reword or replace the refusal.
|
|
936
869
|
*
|
|
937
|
-
*
|
|
938
|
-
* message from `this.target`.
|
|
870
|
+
* A thread inherits its parent channel's nsfw flag. ModalSubmit has no reliable channel, so it is excluded.
|
|
939
871
|
*
|
|
940
|
-
* @
|
|
941
|
-
*
|
|
872
|
+
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
873
|
+
*
|
|
874
|
+
* @see {@link Gated}
|
|
942
875
|
*
|
|
943
876
|
* @example
|
|
944
877
|
* ```ts
|
|
945
|
-
* \@
|
|
946
|
-
*
|
|
878
|
+
* \@Gated(Nsfw())
|
|
879
|
+
* \@SlashRoute('nsfwcmd')
|
|
880
|
+
* class NsfwHandler extends SlashHandler<'nsfwcmd'> {
|
|
947
881
|
* async execute() {
|
|
948
|
-
*
|
|
882
|
+
* // ...
|
|
949
883
|
* }
|
|
950
884
|
* }
|
|
951
885
|
* ```
|
|
952
886
|
*/
|
|
953
|
-
declare
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
/**
|
|
962
|
-
|
|
963
|
-
* names.
|
|
964
|
-
*
|
|
965
|
-
* Provide one arm per registered name, keyed by the name Discord shows in the right-click menu. Each
|
|
966
|
-
* arm receives the clicked message, narrowed to the cache state of that one command. The arms must
|
|
967
|
-
* cover every name in the generic. A missing name or an unknown key is a compile error.
|
|
968
|
-
*
|
|
969
|
-
* @param arms - One handler per registered command name.
|
|
970
|
-
* @returns The result of the arm that ran.
|
|
971
|
-
*
|
|
972
|
-
* @example
|
|
973
|
-
* ```ts
|
|
974
|
-
* \@MessageContextMenuRoute('Report Message', 'Pin Message')
|
|
975
|
-
* class MessageTools extends MessageContextMenuHandler<'Report Message' | 'Pin Message'> {
|
|
976
|
-
* async execute() {
|
|
977
|
-
* await this.match({
|
|
978
|
-
* 'Report Message': (message) => this.report(message),
|
|
979
|
-
* 'Pin Message': (message) => message.pin()
|
|
980
|
-
* });
|
|
981
|
-
* }
|
|
982
|
-
* }
|
|
983
|
-
* ```
|
|
984
|
-
*/
|
|
985
|
-
protected match<Ret>(arms: MessageMenuArms<Names, Ret>): Promise<Ret>;
|
|
887
|
+
declare function Nsfw(options?: GateNoticeOptions): Gate<InteractionGateContext<NonModalInteraction>, 'Nsfw'>;
|
|
888
|
+
//#endregion
|
|
889
|
+
//#region src/bot/injectors/EmojiInjector.d.ts
|
|
890
|
+
type SavedEmojiType = GuildEmoji | ApplicationEmoji;
|
|
891
|
+
/** A resolved emoji, plus the discord.js emoji it came from on {@link GatewayEmoji.source}. */
|
|
892
|
+
declare class GatewayEmoji<Source extends SavedEmojiType = SavedEmojiType> extends ResolvedEmoji {
|
|
893
|
+
#private;
|
|
894
|
+
constructor(source: Source);
|
|
895
|
+
/** What discord.js resolved, for `.url` and the management calls. */
|
|
896
|
+
get source(): Source;
|
|
986
897
|
}
|
|
898
|
+
/**
|
|
899
|
+
* The global {@link Emojis} accessor type. Each key's `source` resolves to its precise class, `GuildEmoji`
|
|
900
|
+
* for a `'guild'` tag and `ApplicationEmoji` for an `'application'` tag, the tags `seedcord codegen`
|
|
901
|
+
* writes into {@link EmojiMap}.
|
|
902
|
+
*/
|
|
903
|
+
type InjectedEmojiMap = { [K in keyof EmojiMap]: EmojiMap[K] extends 'guild' ? GatewayEmoji<GuildEmoji> : GatewayEmoji<ApplicationEmoji>; };
|
|
904
|
+
/**
|
|
905
|
+
* The bot's resolved emojis, keyed by {@link EmojiMap}. Filled by {@link EmojiInjector} during startup.
|
|
906
|
+
* Throws if you read a key the injector did not fill.
|
|
907
|
+
*/
|
|
908
|
+
declare const Emojis: InjectedEmojiMap;
|
|
987
909
|
//#endregion
|
|
988
|
-
//#region src/
|
|
989
|
-
type FocusedArms<Route extends keyof SlashRegistry, Ret> = { [Name in AutocompletableNames<Route>]: (value: string, respond: (choices: readonly ApplicationCommandOptionChoiceData<ChoiceValueOf<EntryFor<Route, Name>>>[]) => Promise<void>) => Promisable<Ret>; };
|
|
910
|
+
//#region src/bot/utilities/permissions/checkBotPermissions.d.ts
|
|
990
911
|
/**
|
|
991
|
-
*
|
|
992
|
-
*
|
|
993
|
-
*
|
|
994
|
-
* `@AutocompleteRoute`. Branch on the focused field with `this.match`, read already-entered sibling options
|
|
995
|
-
* with `this.options`, and find which command fired with `this.route`.
|
|
996
|
-
*
|
|
997
|
-
* @typeParam Route - One or more route keys from {@link SlashRegistry}, e.g. `'search'` or `'search' | 'find'`.
|
|
998
|
-
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
912
|
+
* Checks the bot's own permissions in a {@link Guild} or {@link TextChannel}. Refuses when a permission in
|
|
913
|
+
* `scope` is missing, or with `inverse` when one is present. When the bot member is uncached, the refusal
|
|
914
|
+
* reports every permission in `scope` as missing.
|
|
999
915
|
*
|
|
1000
916
|
* @example
|
|
1001
917
|
* ```ts
|
|
1002
|
-
*
|
|
1003
|
-
*
|
|
1004
|
-
*
|
|
1005
|
-
*
|
|
1006
|
-
*
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
*/
|
|
918
|
+
* import { PermissionFlagsBits } from 'discord.js';
|
|
919
|
+
* import { checkBotPermissions } from '@seedcord/gateway';
|
|
920
|
+
*
|
|
921
|
+
* checkBotPermissions(textChannel, [PermissionFlagsBits.SendMessages, PermissionFlagsBits.ViewChannel]);
|
|
922
|
+
* ```
|
|
923
|
+
*/
|
|
924
|
+
declare function checkBotPermissions(target: Guild | TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionNoticeOverrides): void;
|
|
925
|
+
//#endregion
|
|
926
|
+
//#region src/bot/utilities/permissions/checkPermissions.d.ts
|
|
927
|
+
/** Options for {@link checkPermissions}. */
|
|
928
|
+
interface CheckPermissionOptions extends PermissionNoticeOverrides {
|
|
929
|
+
/** The role or member to check. */
|
|
930
|
+
for: Role | GuildMember;
|
|
931
|
+
/** A guild reads the base bits from roles, a text channel reads the overwrite-resolved set. */
|
|
932
|
+
in: Guild | TextChannel;
|
|
933
|
+
/** The permission flag bits to check. */
|
|
934
|
+
scope: PermissionScope;
|
|
935
|
+
/** Refuse when the target holds a scope bit. */
|
|
936
|
+
inverse?: boolean;
|
|
937
|
+
}
|
|
938
|
+
/**
|
|
939
|
+
* Checks a {@link Role} or a {@link GuildMember} against the base permission bits in a {@link Guild},
|
|
940
|
+
* before channel overwrites. Refuses when a permission in `scope` is missing, or with `inverse` when one
|
|
941
|
+
* is present.
|
|
942
|
+
*
|
|
943
|
+
* @example
|
|
944
|
+
* ```ts
|
|
945
|
+
* import { PermissionFlagsBits } from 'discord.js';
|
|
946
|
+
* import { checkPermissions } from '@seedcord/gateway';
|
|
947
|
+
*
|
|
948
|
+
* checkPermissions(role, guild, [PermissionFlagsBits.ManageMessages, PermissionFlagsBits.KickMembers]);
|
|
949
|
+
* ```
|
|
950
|
+
*
|
|
951
|
+
* @example
|
|
952
|
+
* ```ts
|
|
953
|
+
* // refuse when the member holds Administrator, and replace the refusal
|
|
954
|
+
* checkPermissions(member, guild, [PermissionFlagsBits.Administrator], true, {
|
|
955
|
+
* dangerousNotice: CustomDangerousNotice
|
|
956
|
+
* });
|
|
957
|
+
* ```
|
|
958
|
+
*/
|
|
959
|
+
declare function checkPermissions(target: Role | GuildMember, ctx: Guild, scope: PermissionScope, inverse?: boolean, errors?: PermissionNoticeOverrides): void;
|
|
960
|
+
/**
|
|
961
|
+
* Checks a {@link Role} or a {@link GuildMember} against the overwrite-resolved set in a
|
|
962
|
+
* {@link TextChannel}. Refuses when a permission in `scope` is missing, or with `inverse` when one is
|
|
963
|
+
* present.
|
|
964
|
+
*
|
|
965
|
+
* @example
|
|
966
|
+
* ```ts
|
|
967
|
+
* import { PermissionFlagsBits } from 'discord.js';
|
|
968
|
+
* import { checkPermissions } from '@seedcord/gateway';
|
|
969
|
+
*
|
|
970
|
+
* checkPermissions(role, textChannel, [PermissionFlagsBits.SendMessages, PermissionFlagsBits.ViewChannel]);
|
|
971
|
+
* ```
|
|
972
|
+
*/
|
|
973
|
+
declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionNoticeOverrides): void;
|
|
974
|
+
/**
|
|
975
|
+
* Checks permissions with an options object. Refuses when a permission in
|
|
976
|
+
* {@link CheckPermissionOptions.scope} is missing, or with `options.inverse` when one is present.
|
|
977
|
+
*
|
|
978
|
+
* @example
|
|
979
|
+
* ```ts
|
|
980
|
+
* import { PermissionFlagsBits } from 'discord.js';
|
|
981
|
+
* import { checkPermissions } from '@seedcord/gateway';
|
|
982
|
+
*
|
|
983
|
+
* checkPermissions({
|
|
984
|
+
* for: member,
|
|
985
|
+
* in: textChannel,
|
|
986
|
+
* scope: [PermissionFlagsBits.SendMessages, PermissionFlagsBits.ViewChannel]
|
|
987
|
+
* });
|
|
988
|
+
* ```
|
|
989
|
+
*/
|
|
990
|
+
declare function checkPermissions(options: CheckPermissionOptions): void;
|
|
991
|
+
//#endregion
|
|
992
|
+
//#region src/bot/utilities/permissions/hasPermsToAssign.d.ts
|
|
993
|
+
/**
|
|
994
|
+
* Optional custom error constructors for {@link HasPermsToAssignOptions}.
|
|
995
|
+
*/
|
|
996
|
+
interface AssignRoleNoticeOverrides {
|
|
997
|
+
higherNotice?: new (message: string, role: Role, botRole: Role) => Notice;
|
|
998
|
+
managedNotice?: new (message: string) => Notice;
|
|
999
|
+
missingNotice?: new (message: string | undefined, subject: string, missingPerms: readonly string[]) => Notice;
|
|
1000
|
+
}
|
|
1001
|
+
/**
|
|
1002
|
+
* Options for {@link hasPermsToAssign}.
|
|
1003
|
+
*/
|
|
1004
|
+
interface HasPermsToAssignOptions {
|
|
1005
|
+
targetRole: Role;
|
|
1006
|
+
noticeOverrides?: AssignRoleNoticeOverrides;
|
|
1007
|
+
}
|
|
1008
|
+
/**
|
|
1009
|
+
* Validates that 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.
|
|
1010
|
+
*
|
|
1011
|
+
* @param roleOrOptions - Target role or complete options for the check
|
|
1012
|
+
* @throws A `Notice` on refusal, or a `SeedcordError` when the bot has no role in the guild's role cache.
|
|
1013
|
+
*
|
|
1014
|
+
* @example
|
|
1015
|
+
* ```ts
|
|
1016
|
+
* import { hasPermsToAssign } from '@seedcord/gateway';
|
|
1017
|
+
*
|
|
1018
|
+
* // Check if the bot can assign a specific role
|
|
1019
|
+
* hasPermsToAssign(role);
|
|
1020
|
+
*
|
|
1021
|
+
* // Check with custom error handling
|
|
1022
|
+
* hasPermsToAssign({
|
|
1023
|
+
* targetRole: role,
|
|
1024
|
+
* noticeOverrides: {
|
|
1025
|
+
* higherNotice: CustomHigherNotice,
|
|
1026
|
+
* managedNotice: CustomManagedNotice,
|
|
1027
|
+
* missingNotice: CustomMissingPermissionsNotice
|
|
1028
|
+
* }
|
|
1029
|
+
* });
|
|
1030
|
+
* ```
|
|
1031
|
+
*/
|
|
1032
|
+
declare function hasPermsToAssign(roleOrOptions: Role | HasPermsToAssignOptions): void;
|
|
1033
|
+
//#endregion
|
|
1034
|
+
//#region src/bot/confirm/getConfirmation.d.ts
|
|
1035
|
+
type Outcome = ReplyResponse | (() => Promisable<ReplyResponse>);
|
|
1036
|
+
/** Options shared by both confirmation forms. */
|
|
1037
|
+
interface ConfirmOptions {
|
|
1038
|
+
/**
|
|
1039
|
+
* Whether the prompt is ephemeral. Only the invoking user can act on it either way, a non-invoker's
|
|
1040
|
+
* click is ignored.
|
|
1041
|
+
*
|
|
1042
|
+
* @defaultValue `true`
|
|
1043
|
+
*/
|
|
1044
|
+
ephemeral?: boolean;
|
|
1045
|
+
/**
|
|
1046
|
+
* Milliseconds to wait for a click before the prompt is settled and the result resolves to `false`.
|
|
1047
|
+
*
|
|
1048
|
+
* @defaultValue `30_000`
|
|
1049
|
+
*/
|
|
1050
|
+
timeoutMs?: number;
|
|
1051
|
+
/** Shown in place of the prompt when the user confirms. Absent removes the prompt. */
|
|
1052
|
+
onConfirm?: Outcome;
|
|
1053
|
+
/** Shown in place of the prompt when the user cancels. Absent removes the prompt. */
|
|
1054
|
+
onCancel?: Outcome;
|
|
1055
|
+
/** Shown in place of the prompt when the prompt times out. Absent removes the prompt. */
|
|
1056
|
+
onTimeout?: Outcome;
|
|
1057
|
+
}
|
|
1058
|
+
/** Options for the string-prompt form, adding the built-in Confirm/Cancel buttons' labels and style. */
|
|
1059
|
+
interface DefaultConfirmOptions extends ConfirmOptions {
|
|
1060
|
+
/**
|
|
1061
|
+
* Confirm-button label.
|
|
1062
|
+
*
|
|
1063
|
+
* @defaultValue `'Confirm'`
|
|
1064
|
+
*/
|
|
1065
|
+
confirmLabel?: string;
|
|
1066
|
+
/**
|
|
1067
|
+
* Cancel-button label.
|
|
1068
|
+
*
|
|
1069
|
+
* @defaultValue `'Cancel'`
|
|
1070
|
+
*/
|
|
1071
|
+
cancelLabel?: string;
|
|
1072
|
+
/**
|
|
1073
|
+
* Confirm-button style.
|
|
1074
|
+
*
|
|
1075
|
+
* @defaultValue {@link ButtonStyle.Danger}
|
|
1076
|
+
*/
|
|
1077
|
+
confirmStyle?: ButtonStyle;
|
|
1078
|
+
}
|
|
1079
|
+
/**
|
|
1080
|
+
* Shows a confirm/cancel prompt with built-in Confirm and Cancel buttons and resolves to `true` only if the
|
|
1081
|
+
* invoking user clicks confirm. A cancel click or a timeout resolves to `false`. Gate the action behind it
|
|
1082
|
+
* with an early return. A failed prompt send throws into the fault boundary. A {@link ModalHandler} is
|
|
1083
|
+
* excluded at compile time.
|
|
1084
|
+
*
|
|
1085
|
+
* @param handler - The handler to prompt from, `this` inside a non-modal handler.
|
|
1086
|
+
* @param prompt - The message shown above the Confirm and Cancel buttons.
|
|
1087
|
+
* @param options - Ephemeral flag, timeout, the built-in buttons' labels and style, and the optional
|
|
1088
|
+
* `onConfirm`/`onCancel`/`onTimeout` outcome replies that edit the prompt in place.
|
|
1089
|
+
* @returns `true` if confirmed, `false` on cancel or timeout.
|
|
1090
|
+
*
|
|
1091
|
+
* @example
|
|
1092
|
+
* ```ts
|
|
1093
|
+
* import { getConfirmation } from '@seedcord/gateway';
|
|
1094
|
+
*
|
|
1095
|
+
* \@SlashRoute('ban')
|
|
1096
|
+
* class BanHandler extends SlashHandler<'ban'> {
|
|
1097
|
+
* async execute() {
|
|
1098
|
+
* const target = this.options.getUser('target');
|
|
1099
|
+
* if (!(await getConfirmation(this, `Ban ${target.tag}? This cannot be undone.`))) return;
|
|
1100
|
+
* await this.event.guild?.members.ban(target.id);
|
|
1101
|
+
* }
|
|
1102
|
+
* }
|
|
1103
|
+
* ```
|
|
1104
|
+
*/
|
|
1105
|
+
declare function getConfirmation(handler: RepliableHandler<NonModalInteraction>, prompt: string, options?: DefaultConfirmOptions): Promise<boolean>;
|
|
1106
|
+
/**
|
|
1107
|
+
* Shows a confirm/cancel prompt you build yourself and resolves to `true` only if the invoking user clicks
|
|
1108
|
+
* confirm. The factory receives the two minted button ids. Set them on your own buttons. A cancel click or a
|
|
1109
|
+
* timeout resolves to `false`. A failed prompt send throws into the fault boundary. A {@link ModalHandler} is
|
|
1110
|
+
* excluded at compile time.
|
|
1111
|
+
*
|
|
1112
|
+
* @param handler - The handler to prompt from, `this` inside a non-modal handler.
|
|
1113
|
+
* @param prompt - A factory given the minted `{ confirm, cancel }` ids that returns the reply to show. Build
|
|
1114
|
+
* it with the `BuilderComponent` and `RowComponent` wrappers.
|
|
1115
|
+
* @param options - Ephemeral flag, timeout, and the optional `onConfirm`/`onCancel`/`onTimeout` outcome
|
|
1116
|
+
* replies that edit the prompt in place.
|
|
1117
|
+
* @returns `true` if confirmed, `false` on cancel or timeout.
|
|
1118
|
+
*
|
|
1119
|
+
* @remarks
|
|
1120
|
+
* The prompt is collected in-process, so it does not survive a bot restart. Without an outcome hook the
|
|
1121
|
+
* prompt is gone once the user confirms, so deliver the result with a fresh `this.followUp(...)`.
|
|
1122
|
+
*
|
|
1123
|
+
* @example
|
|
1124
|
+
* ```ts
|
|
1125
|
+
* import { ButtonBuilder, TextDisplayBuilder } from '@discordjs/builders';
|
|
1126
|
+
* import { ButtonStyle } from 'discord.js';
|
|
1127
|
+
* import { BuilderComponent, RowComponent, getConfirmation } from '@seedcord/gateway';
|
|
1128
|
+
*
|
|
1129
|
+
* class BanPrompt extends BuilderComponent<'container'> {
|
|
1130
|
+
* constructor(text: string) {
|
|
1131
|
+
* super('container');
|
|
1132
|
+
* this.instance.addTextDisplayComponents(new TextDisplayBuilder().setContent(text));
|
|
1133
|
+
* }
|
|
1134
|
+
* }
|
|
1135
|
+
*
|
|
1136
|
+
* class ConfirmRow extends RowComponent<'button'> {
|
|
1137
|
+
* constructor(ids: { confirm: string; cancel: string }) {
|
|
1138
|
+
* super('button');
|
|
1139
|
+
* const buttons = [
|
|
1140
|
+
* [ids.confirm, 'Ban', ButtonStyle.Danger],
|
|
1141
|
+
* [ids.cancel, 'Cancel', ButtonStyle.Secondary]
|
|
1142
|
+
* ] as const;
|
|
1143
|
+
* this.instance.addComponents(
|
|
1144
|
+
* ...buttons.map(([id, label, style]) => new ButtonBuilder().setCustomId(id).setLabel(label).setStyle(style))
|
|
1145
|
+
* );
|
|
1146
|
+
* }
|
|
1147
|
+
* }
|
|
1148
|
+
*
|
|
1149
|
+
* const target = this.options.getUser('target');
|
|
1150
|
+
* const confirmed = await getConfirmation(
|
|
1151
|
+
* this,
|
|
1152
|
+
* (ids) => ({ components: [new BanPrompt(`Ban ${target.tag}?`).component, new ConfirmRow(ids).component] }),
|
|
1153
|
+
* { onConfirm: { components: [new BanPrompt(`Banned ${target.tag}.`).component] } }
|
|
1154
|
+
* );
|
|
1155
|
+
* if (!confirmed) return;
|
|
1156
|
+
* ```
|
|
1157
|
+
*/
|
|
1158
|
+
declare function getConfirmation(handler: RepliableHandler<NonModalInteraction>, prompt: (ids: {
|
|
1159
|
+
confirm: string;
|
|
1160
|
+
cancel: string;
|
|
1161
|
+
}) => Promisable<ReplyResponse>, options?: ConfirmOptions): Promise<boolean>;
|
|
1162
|
+
//#endregion
|
|
1163
|
+
//#region src/handlers/interaction/middlewareKinds.d.ts
|
|
1164
|
+
interface Payloads {
|
|
1165
|
+
[InteractionKind.Slash]: ChatInputCommandInteraction;
|
|
1166
|
+
[InteractionKind.Button]: ButtonInteraction;
|
|
1167
|
+
[InteractionKind.Modal]: ModalSubmitInteraction;
|
|
1168
|
+
[InteractionKind.StringMenu]: StringSelectMenuInteraction;
|
|
1169
|
+
[InteractionKind.UserMenu]: UserSelectMenuInteraction;
|
|
1170
|
+
[InteractionKind.RoleMenu]: RoleSelectMenuInteraction;
|
|
1171
|
+
[InteractionKind.ChannelMenu]: ChannelSelectMenuInteraction;
|
|
1172
|
+
[InteractionKind.MentionableMenu]: MentionableSelectMenuInteraction;
|
|
1173
|
+
[InteractionKind.MessageContextMenu]: MessageContextMenuCommandInteraction;
|
|
1174
|
+
[InteractionKind.UserContextMenu]: UserContextMenuCommandInteraction;
|
|
1175
|
+
}
|
|
1176
|
+
type InteractionForKind = { [Kind in MiddlewareKind]: Payloads[Kind]; };
|
|
1177
|
+
/** @internal */
|
|
1178
|
+
type InteractionOf<Kind extends MiddlewareKind> = InteractionForKind[Kind];
|
|
1179
|
+
//#endregion
|
|
1180
|
+
//#region src/handlers/interaction/InteractionMiddleware.d.ts
|
|
1181
|
+
/**
|
|
1182
|
+
* Base class for interaction middleware.
|
|
1183
|
+
*
|
|
1184
|
+
* Middleware runs after the dispatcher builds the handler and before the gates, over the handler's own
|
|
1185
|
+
* reply surface. Name the kinds in the generic and list the same ones in `{ kinds }`. Several kinds give
|
|
1186
|
+
* `this.event` a union. The discord.js guards narrow it. A catchall reads every repliable kind.
|
|
1187
|
+
*
|
|
1188
|
+
* @typeParam Kind - One or more {@link InteractionKind} members. Defaults to every repliable kind.
|
|
1189
|
+
*
|
|
1190
|
+
* @example
|
|
1191
|
+
* ```ts
|
|
1192
|
+
* \@RegisterInteractionMiddleware({ kinds: [InteractionKind.Button] })
|
|
1193
|
+
* class Audit extends InteractionMiddleware<InteractionKind.Button> {
|
|
1194
|
+
* async execute() {
|
|
1195
|
+
* this.logger.info(this.event.customId);
|
|
1196
|
+
* }
|
|
1197
|
+
* }
|
|
1198
|
+
* ```
|
|
1199
|
+
*/
|
|
1200
|
+
declare abstract class InteractionMiddleware<in out Kind extends MiddlewareKind = MiddlewareKind> extends RepliableHandler<InteractionOf<Kind>> {
|
|
1201
|
+
/** @internal */
|
|
1202
|
+
readonly [MiddlewareKindsBrand]?: Kind;
|
|
1203
|
+
constructor(event: InteractionOf<Kind>, core: Core, dispatch: DispatchContext, sender: ReplySender);
|
|
1204
|
+
/**
|
|
1205
|
+
* Runs once the handler settles, newest middleware first. A refusal or a throw still reaches it,
|
|
1206
|
+
* since seedcord calls it on every middleware whose `execute()` started. Implement it to release
|
|
1207
|
+
* something this middleware took in `execute()`, such as a lock or an open span. A throw in here
|
|
1208
|
+
* is logged and goes no further.
|
|
1209
|
+
*
|
|
1210
|
+
* @param result - How the dispatch ended. Either failure state carries the thrown value on `caught`.
|
|
1211
|
+
*
|
|
1212
|
+
* @example
|
|
1213
|
+
* ```ts
|
|
1214
|
+
* // the base declares it. an implementation carries `override`.
|
|
1215
|
+
* override async after(result: DispatchResult) {
|
|
1216
|
+
* this.lock.release();
|
|
1217
|
+
* }
|
|
1218
|
+
* ```
|
|
1219
|
+
*/
|
|
1220
|
+
after?(result: DispatchResult): Promise<void>;
|
|
1221
|
+
}
|
|
1222
|
+
//#endregion
|
|
1223
|
+
//#region src/inputs/SlashOptions.d.ts
|
|
1224
|
+
interface GatewayLens<Cache extends CacheType> {
|
|
1225
|
+
user: NonNullable<CommandInteractionOption<Cache>['user']>;
|
|
1226
|
+
member: NonNullable<CommandInteractionOption<Cache>['member']>;
|
|
1227
|
+
channel: NonNullable<CommandInteractionOption<Cache>['channel']>;
|
|
1228
|
+
role: NonNullable<CommandInteractionOption<Cache>['role']>;
|
|
1229
|
+
mentionable: NonNullable<CommandInteractionOption<Cache>['member' | 'role' | 'user']>;
|
|
1230
|
+
attachment: NonNullable<CommandInteractionOption<Cache>['attachment']>;
|
|
1231
|
+
}
|
|
1232
|
+
/**
|
|
1233
|
+
* The typed view over a chat-input command's options for one route. Each getter mirrors the discord.js
|
|
1234
|
+
* resolver method but restricts its `name` to that route's options of the matching kind, drops the null
|
|
1235
|
+
* on required options, narrows `choices` to their literal union, and only appears when the route has an
|
|
1236
|
+
* option of that kind. The rich kinds return exactly what the djs resolver returns.
|
|
1237
|
+
*
|
|
1238
|
+
* A channel option declared with `addChannelTypes` narrows `getChannel` to the matching channel subtype.
|
|
1239
|
+
* Pass the raw `this.event.options` resolver for anything this view does not cover.
|
|
1240
|
+
*
|
|
1241
|
+
* @typeParam Route - A route key from the generated {@link SlashRegistry}.
|
|
1242
|
+
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
1243
|
+
*/
|
|
1244
|
+
type SlashOptions<Route extends keyof SlashRegistry, Cache extends CacheType = CacheFor<Route>> = SlashOptions$1<Route, GatewayLens<Cache>>;
|
|
1245
|
+
//#endregion
|
|
1246
|
+
//#region src/handlers/interaction/SlashHandler.d.ts
|
|
1247
|
+
type SlashMatchArms<Route extends keyof SlashRegistry, Cache extends CacheType, Ret> = { [Key in Route]: (options: SlashOptions<Key, Cache>) => Promisable<Ret>; };
|
|
1248
|
+
/**
|
|
1249
|
+
* Base class for a chat-input (slash) command handler.
|
|
1250
|
+
*
|
|
1251
|
+
* Pass the route from the generated registry as the generic, the same string as `@SlashRoute`, then read
|
|
1252
|
+
* `this.options` for a single command or `this.match` for several. Command authoring stays plain
|
|
1253
|
+
* discord.js, `seedcord codegen` reads its `toJSON()` to type these options.
|
|
1254
|
+
*
|
|
1255
|
+
* @typeParam Route - One or more route keys from {@link SlashRegistry}, e.g. `'ban'` or `'ban' | 'kick'`.
|
|
1256
|
+
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
1257
|
+
*
|
|
1258
|
+
* @example
|
|
1259
|
+
* ```ts
|
|
1260
|
+
* \@SlashRoute('ban')
|
|
1261
|
+
* class BanHandler extends SlashHandler<'ban'> {
|
|
1262
|
+
* async execute() {
|
|
1263
|
+
* const target = this.options.getUser('target'); // User
|
|
1264
|
+
* const reason = this.options.getString('reason'); // string | null
|
|
1265
|
+
* }
|
|
1266
|
+
* }
|
|
1267
|
+
* ```
|
|
1268
|
+
*/
|
|
1269
|
+
declare abstract class SlashHandler<Route extends keyof SlashRegistry, Cache extends CacheType = CacheFor<Route>> extends InteractionHandler<ChatInputCommandInteraction<Cache>> {
|
|
1270
|
+
/** @internal */
|
|
1271
|
+
readonly [SlashRouteBrand]?: Route;
|
|
1272
|
+
/**
|
|
1273
|
+
* The typed options for this command's route. Only the getters for kinds this command declares appear.
|
|
1274
|
+
* Each getter's name argument is restricted to that command's options of its kind.
|
|
1275
|
+
*
|
|
1276
|
+
* - A required option drops the null.
|
|
1277
|
+
* - Choices narrow to their literal union.
|
|
1278
|
+
* - A channel option declared with `addChannelTypes` narrows to those types.
|
|
1279
|
+
*
|
|
1280
|
+
* Use `this.event.options` directly for anything outside this view, such as `getSubcommand()`.
|
|
1281
|
+
* However, for the common case, the methods in this would suffice.
|
|
1282
|
+
*/
|
|
1283
|
+
protected get options(): SlashOptions<Route, Cache>;
|
|
1284
|
+
/**
|
|
1285
|
+
* Run the arm for whichever command fired. Use this only when the handler is registered for several
|
|
1286
|
+
* routes.
|
|
1287
|
+
*
|
|
1288
|
+
* Provide one arm per registered route, keyed by its route string, and each arm receives that route's
|
|
1289
|
+
* own narrowed options. The arms must cover every route in the generic, a missing route or an unknown
|
|
1290
|
+
* key is a compile error.
|
|
1291
|
+
*
|
|
1292
|
+
* @param arms - One handler per registered route, keyed by route string.
|
|
1293
|
+
* @returns The result of the arm that ran.
|
|
1294
|
+
*
|
|
1295
|
+
* @example
|
|
1296
|
+
* ```ts
|
|
1297
|
+
* \@SlashRoute('ban', 'kick')
|
|
1298
|
+
* class ModHandler extends SlashHandler<'ban' | 'kick'> {
|
|
1299
|
+
* async execute() {
|
|
1300
|
+
* await this.match({
|
|
1301
|
+
* ban: (options) => this.event.guild?.members.ban(options.getUser('target').id),
|
|
1302
|
+
* kick: (options) => this.event.guild?.members.kick(options.getUser('member').id)
|
|
1303
|
+
* });
|
|
1304
|
+
* }
|
|
1305
|
+
* }
|
|
1306
|
+
* ```
|
|
1307
|
+
*/
|
|
1308
|
+
protected match<Ret>(arms: SlashMatchArms<Route, Cache, Ret>): Promise<Ret>;
|
|
1309
|
+
}
|
|
1310
|
+
//#endregion
|
|
1311
|
+
//#region src/handlers/interaction/ContextMenuHandler.d.ts
|
|
1312
|
+
type UserMenuArms<Names extends NamesFor<ApplicationCommandType.User>, Ret> = { [Name in Names]: (target: User, member: CacheTypeReducer<MenuCacheFor<ApplicationCommandType.User, Name>, GuildMember, APIInteractionGuildMember> | null) => Promisable<Ret>; };
|
|
1313
|
+
type MessageMenuArms<Names extends NamesFor<ApplicationCommandType.Message>, Ret> = { [Name in Names]: (target: Message<BooleanCache<MenuCacheFor<ApplicationCommandType.Message, Name>>>) => Promisable<Ret>; };
|
|
1314
|
+
/**
|
|
1315
|
+
* Base class for a user context-menu command handler (right-click a user).
|
|
1316
|
+
*
|
|
1317
|
+
* Pass the command name(s) as the generic, the same as `@UserContextMenuRoute`. Read the right-clicked
|
|
1318
|
+
* user from `this.target` and that same user's guild member from `this.targetMember`.
|
|
1319
|
+
*
|
|
1320
|
+
* @typeParam Names - One or more command names from the generated user registry.
|
|
1321
|
+
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
1322
|
+
*
|
|
1323
|
+
* @example
|
|
1324
|
+
* ```ts
|
|
1325
|
+
* \@UserContextMenuRoute('View Profile')
|
|
1326
|
+
* class ViewProfile extends UserContextMenuHandler<'View Profile'> {
|
|
1327
|
+
* async execute() {
|
|
1328
|
+
* const user = this.target;
|
|
1329
|
+
* }
|
|
1330
|
+
* }
|
|
1331
|
+
* ```
|
|
1332
|
+
*/
|
|
1333
|
+
declare abstract class UserContextMenuHandler<Names extends NamesFor<ApplicationCommandType.User>, Cache extends CacheType = MenuCacheFor<ApplicationCommandType.User, Names>> extends InteractionHandler<UserContextMenuCommandInteraction<Cache>> {
|
|
1334
|
+
/** @internal */
|
|
1335
|
+
readonly [ContextMenuKindBrand]?: ApplicationCommandType.User;
|
|
1336
|
+
/** @internal */
|
|
1337
|
+
readonly [ContextMenuNamesBrand]?: Names;
|
|
1338
|
+
protected get target(): User;
|
|
1339
|
+
/** The right-clicked user's guild member, null outside a guild. */
|
|
1340
|
+
protected get targetMember(): CacheTypeReducer<Cache, GuildMember, APIInteractionGuildMember> | null;
|
|
1341
|
+
/** Which of the registered commands fired. */
|
|
1342
|
+
protected get commandName(): Names;
|
|
1343
|
+
/**
|
|
1344
|
+
* Run the arm for whichever command fired. Use this only when the handler is registered for several
|
|
1345
|
+
* names.
|
|
1346
|
+
*
|
|
1347
|
+
* Provide one arm per registered name, keyed by the name Discord shows in the right-click menu. Each
|
|
1348
|
+
* arm receives the clicked user and that user's guild member, both narrowed to the cache state of that
|
|
1349
|
+
* one command. The arms must cover every name in the generic. A missing name or an unknown key is a
|
|
1350
|
+
* compile error.
|
|
1351
|
+
*
|
|
1352
|
+
* @param arms - One handler per registered command name.
|
|
1353
|
+
* @returns The result of the arm that ran.
|
|
1354
|
+
*
|
|
1355
|
+
* @example
|
|
1356
|
+
* ```ts
|
|
1357
|
+
* \@UserContextMenuRoute('View Profile', 'Warn')
|
|
1358
|
+
* class Moderation extends UserContextMenuHandler<'View Profile' | 'Warn'> {
|
|
1359
|
+
* async execute() {
|
|
1360
|
+
* await this.match({
|
|
1361
|
+
* 'View Profile': (user) => this.reply(`Profile for ${user.tag}.`),
|
|
1362
|
+
* Warn: (user, member) => this.reply(`Warned ${member?.displayName ?? user.tag}.`)
|
|
1363
|
+
* });
|
|
1364
|
+
* }
|
|
1365
|
+
* }
|
|
1366
|
+
* ```
|
|
1367
|
+
*/
|
|
1368
|
+
protected match<Ret>(arms: UserMenuArms<Names, Ret>): Promise<Ret>;
|
|
1369
|
+
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Base class for a message context-menu command handler (right-click a message).
|
|
1372
|
+
*
|
|
1373
|
+
* Pass the command name(s) as the generic, the same as `@MessageContextMenuRoute`. Read the right-clicked
|
|
1374
|
+
* message from `this.target`.
|
|
1375
|
+
*
|
|
1376
|
+
* @typeParam Names - One or more command names from the generated message registry.
|
|
1377
|
+
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
1378
|
+
*
|
|
1379
|
+
* @example
|
|
1380
|
+
* ```ts
|
|
1381
|
+
* \@MessageContextMenuRoute('Report Message')
|
|
1382
|
+
* class ReportMessage extends MessageContextMenuHandler<'Report Message'> {
|
|
1383
|
+
* async execute() {
|
|
1384
|
+
* const message = this.target;
|
|
1385
|
+
* }
|
|
1386
|
+
* }
|
|
1387
|
+
* ```
|
|
1388
|
+
*/
|
|
1389
|
+
declare abstract class MessageContextMenuHandler<Names extends NamesFor<ApplicationCommandType.Message>, Cache extends CacheType = MenuCacheFor<ApplicationCommandType.Message, Names>> extends InteractionHandler<MessageContextMenuCommandInteraction<Cache>> {
|
|
1390
|
+
/** @internal */
|
|
1391
|
+
readonly [ContextMenuKindBrand]?: ApplicationCommandType.Message;
|
|
1392
|
+
/** @internal */
|
|
1393
|
+
readonly [ContextMenuNamesBrand]?: Names;
|
|
1394
|
+
protected get target(): Message<BooleanCache<Cache>>;
|
|
1395
|
+
/** Which of the registered commands fired. */
|
|
1396
|
+
protected get commandName(): Names;
|
|
1397
|
+
/**
|
|
1398
|
+
* Run the arm for whichever command fired. Use this only when the handler is registered for several
|
|
1399
|
+
* names.
|
|
1400
|
+
*
|
|
1401
|
+
* Provide one arm per registered name, keyed by the name Discord shows in the right-click menu. Each
|
|
1402
|
+
* arm receives the clicked message, narrowed to the cache state of that one command. The arms must
|
|
1403
|
+
* cover every name in the generic. A missing name or an unknown key is a compile error.
|
|
1404
|
+
*
|
|
1405
|
+
* @param arms - One handler per registered command name.
|
|
1406
|
+
* @returns The result of the arm that ran.
|
|
1407
|
+
*
|
|
1408
|
+
* @example
|
|
1409
|
+
* ```ts
|
|
1410
|
+
* \@MessageContextMenuRoute('Report Message', 'Pin Message')
|
|
1411
|
+
* class MessageTools extends MessageContextMenuHandler<'Report Message' | 'Pin Message'> {
|
|
1412
|
+
* async execute() {
|
|
1413
|
+
* await this.match({
|
|
1414
|
+
* 'Report Message': (message) => this.report(message),
|
|
1415
|
+
* 'Pin Message': (message) => message.pin()
|
|
1416
|
+
* });
|
|
1417
|
+
* }
|
|
1418
|
+
* }
|
|
1419
|
+
* ```
|
|
1420
|
+
*/
|
|
1421
|
+
protected match<Ret>(arms: MessageMenuArms<Names, Ret>): Promise<Ret>;
|
|
1422
|
+
}
|
|
1423
|
+
//#endregion
|
|
1424
|
+
//#region src/handlers/interaction/AutocompleteHandler.d.ts
|
|
1425
|
+
type FocusedArms<Route extends keyof SlashRegistry, Ret> = { [Name in AutocompletableNames<Route>]: (value: string, respond: (choices: readonly ApplicationCommandOptionChoiceData<ChoiceValueOf<EntryFor<Route, Name>>>[]) => Promise<void>) => Promisable<Ret>; };
|
|
1426
|
+
/**
|
|
1427
|
+
* Base class for a Discord autocomplete handler.
|
|
1428
|
+
*
|
|
1429
|
+
* Pass the command route(s) from the generated registry as the generic, the same string(s) as
|
|
1430
|
+
* `@AutocompleteRoute`. Branch on the focused field with `this.match`, read already-entered sibling options
|
|
1431
|
+
* with `this.options`, and find which command fired with `this.route`.
|
|
1432
|
+
*
|
|
1433
|
+
* @typeParam Route - One or more route keys from {@link SlashRegistry}, e.g. `'search'` or `'search' | 'find'`.
|
|
1434
|
+
* @typeParam Cache - The interaction cache state. The command's contexts set it.
|
|
1435
|
+
*
|
|
1436
|
+
* @example
|
|
1437
|
+
* ```ts
|
|
1438
|
+
* \@AutocompleteRoute('search')
|
|
1439
|
+
* class SearchAutocomplete extends AutocompleteHandler<'search'> {
|
|
1440
|
+
* async execute() {
|
|
1441
|
+
* await this.match({
|
|
1442
|
+
* query: (value, respond) => respond([{ name: value, value }])
|
|
1443
|
+
* });
|
|
1444
|
+
* }
|
|
1445
|
+
* }
|
|
1446
|
+
* ```
|
|
1447
|
+
*/
|
|
1012
1448
|
declare abstract class AutocompleteHandler<Route extends keyof SlashRegistry, Cache extends CacheType = CacheFor<Route>> extends BaseHandler<AutocompleteInteraction<Cache>> {
|
|
1013
1449
|
/** @internal */
|
|
1014
1450
|
readonly [AutocompleteRouteBrand]?: Route;
|
|
1015
|
-
constructor(event: AutocompleteInteraction<Cache>, core: Core, dispatch
|
|
1451
|
+
constructor(event: AutocompleteInteraction<Cache>, core: Core, dispatch: DispatchContext);
|
|
1016
1452
|
private decodedFocused?;
|
|
1017
1453
|
/**
|
|
1018
1454
|
* The focused option for this interaction. `value` is always the raw partial string the user is typing,
|
|
@@ -1199,493 +1635,133 @@ declare abstract class SelectMenuHandler<Event extends AnySelectMenuInteraction,
|
|
|
1199
1635
|
*
|
|
1200
1636
|
* Register the customId definitions with `@StringMenuRoute`, list the same ones in the generic, then read
|
|
1201
1637
|
* the chosen option values from `this.values`. Read `this.params` for a single route or `this.match` for
|
|
1202
|
-
* several. Reply through the handler members, or rewrite the source message with `this.update`.
|
|
1203
|
-
*
|
|
1204
|
-
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof TopicsId]`.
|
|
1205
|
-
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1206
|
-
*
|
|
1207
|
-
* @example
|
|
1208
|
-
* ```ts
|
|
1209
|
-
* \@StringMenuRoute(TopicsId)
|
|
1210
|
-
* class Topics extends StringMenuHandler<[typeof TopicsId]> {
|
|
1211
|
-
* async execute() {
|
|
1212
|
-
* const { userId } = this.params;
|
|
1213
|
-
* await this.update(`<@${userId}> now follows ${this.values.join(', ')}`);
|
|
1214
|
-
* }
|
|
1215
|
-
* }
|
|
1216
|
-
* ```
|
|
1217
|
-
*/
|
|
1218
|
-
declare abstract class StringMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<StringSelectMenuInteraction<Cache>, Defs> {
|
|
1219
|
-
/** @internal */
|
|
1220
|
-
readonly [ComponentKindBrand]?: InteractionKind.StringMenu;
|
|
1221
|
-
}
|
|
1222
|
-
/**
|
|
1223
|
-
* Base class for a user select menu handler.
|
|
1224
|
-
*
|
|
1225
|
-
* Beside `this.values` this handler declares `this.users` and `this.members`. Register the customId
|
|
1226
|
-
* definitions with `@UserMenuRoute` and list the same ones in the generic.
|
|
1227
|
-
*
|
|
1228
|
-
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof AssignId]`.
|
|
1229
|
-
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1230
|
-
*
|
|
1231
|
-
* @example
|
|
1232
|
-
* ```ts
|
|
1233
|
-
* \@UserMenuRoute(AssignId)
|
|
1234
|
-
* class Assign extends UserMenuHandler<[typeof AssignId]> {
|
|
1235
|
-
* async execute() {
|
|
1236
|
-
* const { roleId } = this.params;
|
|
1237
|
-
* await this.reply(`assigning ${this.users.size} member(s) to <@&${roleId}>`);
|
|
1238
|
-
* }
|
|
1239
|
-
* }
|
|
1240
|
-
* ```
|
|
1241
|
-
*/
|
|
1242
|
-
declare abstract class UserMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<UserSelectMenuInteraction<Cache>, Defs> {
|
|
1243
|
-
/** @internal */
|
|
1244
|
-
readonly [ComponentKindBrand]?: InteractionKind.UserMenu;
|
|
1245
|
-
/** The users this select picked. */
|
|
1246
|
-
protected get users(): UserSelectMenuInteraction<Cache>['users'];
|
|
1247
|
-
/** The guild members behind the picked users. Discord resolves these only inside a guild. */
|
|
1248
|
-
protected get members(): UserSelectMenuInteraction<Cache>['members'];
|
|
1249
|
-
}
|
|
1250
|
-
/**
|
|
1251
|
-
* Base class for a role select menu handler.
|
|
1252
|
-
*
|
|
1253
|
-
* Beside `this.values` this handler declares `this.roles`. Register the customId definitions with
|
|
1254
|
-
* `@RoleMenuRoute` and list the same ones in the generic.
|
|
1255
|
-
*
|
|
1256
|
-
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof GrantId]`.
|
|
1257
|
-
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1258
|
-
*
|
|
1259
|
-
* @example
|
|
1260
|
-
* ```ts
|
|
1261
|
-
* \@RoleMenuRoute(GrantId)
|
|
1262
|
-
* class Grant extends RoleMenuHandler<[typeof GrantId]> {
|
|
1263
|
-
* async execute() {
|
|
1264
|
-
* await this.update(`granting ${this.roles.size} role(s)`);
|
|
1265
|
-
* }
|
|
1266
|
-
* }
|
|
1267
|
-
* ```
|
|
1268
|
-
*/
|
|
1269
|
-
declare abstract class RoleMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<RoleSelectMenuInteraction<Cache>, Defs> {
|
|
1270
|
-
/** @internal */
|
|
1271
|
-
readonly [ComponentKindBrand]?: InteractionKind.RoleMenu;
|
|
1272
|
-
/** The roles this select picked. */
|
|
1273
|
-
protected get roles(): RoleSelectMenuInteraction<Cache>['roles'];
|
|
1274
|
-
}
|
|
1275
|
-
/**
|
|
1276
|
-
* Base class for a channel select menu handler.
|
|
1277
|
-
*
|
|
1278
|
-
* Beside `this.values` this handler declares `this.channels`. Register the customId definitions with
|
|
1279
|
-
* `@ChannelMenuRoute` and list the same ones in the generic.
|
|
1280
|
-
*
|
|
1281
|
-
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof LogTargetId]`.
|
|
1282
|
-
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1283
|
-
*
|
|
1284
|
-
* @example
|
|
1285
|
-
* ```ts
|
|
1286
|
-
* \@ChannelMenuRoute(LogTargetId)
|
|
1287
|
-
* class LogTarget extends ChannelMenuHandler<[typeof LogTargetId]> {
|
|
1288
|
-
* async execute() {
|
|
1289
|
-
* await this.update(`logging to ${this.channels.size} channel(s)`);
|
|
1290
|
-
* }
|
|
1291
|
-
* }
|
|
1292
|
-
* ```
|
|
1293
|
-
*/
|
|
1294
|
-
declare abstract class ChannelMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<ChannelSelectMenuInteraction<Cache>, Defs> {
|
|
1295
|
-
/** @internal */
|
|
1296
|
-
readonly [ComponentKindBrand]?: InteractionKind.ChannelMenu;
|
|
1297
|
-
/** The channels this select picked. */
|
|
1298
|
-
protected get channels(): ChannelSelectMenuInteraction<Cache>['channels'];
|
|
1299
|
-
}
|
|
1300
|
-
/**
|
|
1301
|
-
* Base class for a mentionable select menu handler.
|
|
1302
|
-
*
|
|
1303
|
-
* A mentionable menu accepts users and roles together. `this.users`, `this.members`, and `this.roles`
|
|
1304
|
-
* can each come back empty.
|
|
1305
|
-
*
|
|
1306
|
-
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof InviteId]`.
|
|
1307
|
-
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1308
|
-
*
|
|
1309
|
-
* @example
|
|
1310
|
-
* ```ts
|
|
1311
|
-
* \@MentionableMenuRoute(InviteId)
|
|
1312
|
-
* class Invite extends MentionableMenuHandler<[typeof InviteId]> {
|
|
1313
|
-
* async execute() {
|
|
1314
|
-
* await this.update(`inviting ${this.users.size} user(s) and ${this.roles.size} role(s)`);
|
|
1315
|
-
* }
|
|
1316
|
-
* }
|
|
1317
|
-
* ```
|
|
1318
|
-
*/
|
|
1319
|
-
declare abstract class MentionableMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<MentionableSelectMenuInteraction<Cache>, Defs> {
|
|
1320
|
-
/** @internal */
|
|
1321
|
-
readonly [ComponentKindBrand]?: InteractionKind.MentionableMenu;
|
|
1322
|
-
/** The users this select picked. */
|
|
1323
|
-
protected get users(): MentionableSelectMenuInteraction<Cache>['users'];
|
|
1324
|
-
/** The guild members behind the picked users. Discord resolves these only inside a guild. */
|
|
1325
|
-
protected get members(): MentionableSelectMenuInteraction<Cache>['members'];
|
|
1326
|
-
/** The roles this select picked. */
|
|
1327
|
-
protected get roles(): MentionableSelectMenuInteraction<Cache>['roles'];
|
|
1328
|
-
}
|
|
1329
|
-
//#endregion
|
|
1330
|
-
//#region src/bot/decorators/Middlewares.d.ts
|
|
1331
|
-
/**
|
|
1332
|
-
* Middleware types supported by Seedcord
|
|
1333
|
-
*/
|
|
1334
|
-
declare enum MiddlewareType {
|
|
1335
|
-
Interaction = "interaction",
|
|
1336
|
-
Event = "event"
|
|
1337
|
-
}
|
|
1338
|
-
/**
|
|
1339
|
-
* Additional middleware registration options
|
|
1340
|
-
*
|
|
1341
|
-
* @typeParam MType - The type of middleware being registered
|
|
1342
|
-
*/
|
|
1343
|
-
interface MiddlewareOptions<MType extends MiddlewareType, Events extends readonly ValidNonInteractionKeys[] = readonly ValidNonInteractionKeys[]> {
|
|
1344
|
-
/**
|
|
1345
|
-
* Restrict event middleware execution to specific Discord client events. The middleware's `EventMiddleware`
|
|
1346
|
-
* generic must list the same events, or applying the decorator is a compile error.
|
|
1347
|
-
*/
|
|
1348
|
-
readonly events?: MType extends MiddlewareType.Event ? Events : never;
|
|
1349
|
-
}
|
|
1350
|
-
/**
|
|
1351
|
-
* Decorator used to register middleware with priority ordering. The lower the priority number, the earlier it runs.
|
|
1352
|
-
*
|
|
1353
|
-
* Interaction middleware cannot specify event filters.
|
|
1354
|
-
*
|
|
1355
|
-
* @param type - Middleware kind from {@link MiddlewareType}
|
|
1356
|
-
* @param priority - Ordering value where lower runs earlier. {@default `0` }
|
|
1357
|
-
* @param options - Additional registration options
|
|
1358
|
-
*
|
|
1359
|
-
* @decorator
|
|
1360
|
-
*
|
|
1361
|
-
* @example
|
|
1362
|
-
* ```ts
|
|
1363
|
-
* \@Middleware(MiddlewareType.Event, 10, { events: [Events.MessageCreate, Events.MessageUpdate] })
|
|
1364
|
-
* class MyEventMiddleware extends EventMiddleware {}
|
|
1365
|
-
* ```
|
|
1366
|
-
* @throws A **SeedcordTypeError** If priority is not a finite number
|
|
1367
|
-
* @throws A **SeedcordError** If interaction middleware specifies event filters
|
|
1368
|
-
*/
|
|
1369
|
-
declare function Middleware<MType extends MiddlewareType, const Events extends readonly ValidNonInteractionKeys[] = []>(type: MType, priority?: number, options?: MiddlewareOptions<MType, Events>): (ctor: MType extends MiddlewareType.Interaction ? Constructor<InteractionMiddleware<Repliables>> : Events extends readonly [] ? Constructor<EventMiddleware<ValidNonInteractionKeys>> : Constructor<EventMiddleware<Events[number]>>) => void;
|
|
1370
|
-
//#endregion
|
|
1371
|
-
//#region src/bot/gates/catalog/IgnoreBots.d.ts
|
|
1372
|
-
/**
|
|
1373
|
-
* Drops a client event whose actor is a bot, with a {@link Silence} so nothing is replied. Event-only, because a
|
|
1374
|
-
* Silence on an interaction would leave Discord's failed-interaction state. It rejects an interaction handler at
|
|
1375
|
-
* the decorator line. Takes no options, so attach it directly without calling it.
|
|
1376
|
-
*
|
|
1377
|
-
* @see {@link Gated}
|
|
1378
|
-
*
|
|
1379
|
-
* @example
|
|
1380
|
-
* ```ts
|
|
1381
|
-
* import { Events } from 'discord.js';
|
|
1382
|
-
*
|
|
1383
|
-
* \@Gated(IgnoreBots)
|
|
1384
|
-
* class OnMessage extends EventHandler<Events.MessageCreate> {
|
|
1385
|
-
* async execute() {
|
|
1386
|
-
* // ...
|
|
1387
|
-
* }
|
|
1388
|
-
* }
|
|
1389
|
-
* ```
|
|
1390
|
-
*/
|
|
1391
|
-
declare const IgnoreBots: import("@seedcord/core").Gate<EventGateContext<ValidNonInteractionKeys>, "IgnoreBots">;
|
|
1392
|
-
//#endregion
|
|
1393
|
-
//#region src/bot/gates/catalog/Nsfw.d.ts
|
|
1394
|
-
/**
|
|
1395
|
-
* Requires an age-restricted channel, else refuses. Pass {@link GateNoticeOptions} to reword or replace the refusal.
|
|
1396
|
-
*
|
|
1397
|
-
* A thread inherits its parent channel's nsfw flag. ModalSubmit has no reliable channel, so it is excluded.
|
|
1398
|
-
*
|
|
1399
|
-
* @param options - Reword the default refusal with `message`, or replace it with `notice`.
|
|
1400
|
-
*
|
|
1401
|
-
* @see {@link Gated}
|
|
1402
|
-
*
|
|
1403
|
-
* @example
|
|
1404
|
-
* ```ts
|
|
1405
|
-
* \@Gated(Nsfw())
|
|
1406
|
-
* \@SlashRoute('nsfwcmd')
|
|
1407
|
-
* class NsfwHandler extends SlashHandler<'nsfwcmd'> {
|
|
1408
|
-
* async execute() {
|
|
1409
|
-
* // ...
|
|
1410
|
-
* }
|
|
1411
|
-
* }
|
|
1412
|
-
* ```
|
|
1413
|
-
*/
|
|
1414
|
-
declare function Nsfw(options?: GateNoticeOptions): Gate<InteractionGateContext<NonModalInteraction>, 'Nsfw'>;
|
|
1415
|
-
//#endregion
|
|
1416
|
-
//#region src/bot/injectors/EmojiInjector.d.ts
|
|
1417
|
-
type SavedEmojiType = GuildEmoji | ApplicationEmoji;
|
|
1418
|
-
/** A resolved emoji, plus the discord.js emoji it came from on {@link GatewayEmoji.source}. */
|
|
1419
|
-
declare class GatewayEmoji<Source extends SavedEmojiType = SavedEmojiType> extends ResolvedEmoji {
|
|
1420
|
-
#private;
|
|
1421
|
-
constructor(source: Source);
|
|
1422
|
-
/** What discord.js resolved, for `.url` and the management calls. */
|
|
1423
|
-
get source(): Source;
|
|
1424
|
-
}
|
|
1425
|
-
/**
|
|
1426
|
-
* The global {@link Emojis} accessor type. Each key's `source` resolves to its precise class, `GuildEmoji`
|
|
1427
|
-
* for a `'guild'` tag and `ApplicationEmoji` for an `'application'` tag, the tags `seedcord codegen`
|
|
1428
|
-
* writes into {@link EmojiMap}.
|
|
1429
|
-
*/
|
|
1430
|
-
type InjectedEmojiMap = { [K in keyof EmojiMap]: EmojiMap[K] extends 'guild' ? GatewayEmoji<GuildEmoji> : GatewayEmoji<ApplicationEmoji>; };
|
|
1431
|
-
/**
|
|
1432
|
-
* The bot's resolved emojis, keyed by {@link EmojiMap}. Filled by {@link EmojiInjector} during startup.
|
|
1433
|
-
* Throws if you read a key the injector did not fill.
|
|
1434
|
-
*/
|
|
1435
|
-
declare const Emojis: InjectedEmojiMap;
|
|
1436
|
-
//#endregion
|
|
1437
|
-
//#region src/bot/utilities/permissions/checkBotPermissions.d.ts
|
|
1438
|
-
/**
|
|
1439
|
-
* Checks the bot's own permissions in a {@link Guild} or {@link TextChannel}. Refuses when a permission in
|
|
1440
|
-
* `scope` is missing, or with `inverse` when one is present. When the bot member is uncached, the refusal
|
|
1441
|
-
* reports every permission in `scope` as missing.
|
|
1442
|
-
*
|
|
1443
|
-
* @example
|
|
1444
|
-
* ```ts
|
|
1445
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1446
|
-
* import { checkBotPermissions } from '@seedcord/gateway';
|
|
1447
|
-
*
|
|
1448
|
-
* checkBotPermissions(textChannel, [PermissionFlagsBits.SendMessages, PermissionFlagsBits.ViewChannel]);
|
|
1449
|
-
* ```
|
|
1450
|
-
*/
|
|
1451
|
-
declare function checkBotPermissions(target: Guild | TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionNoticeOverrides): void;
|
|
1452
|
-
//#endregion
|
|
1453
|
-
//#region src/bot/utilities/permissions/checkPermissions.d.ts
|
|
1454
|
-
/** Options for {@link checkPermissions}. */
|
|
1455
|
-
interface CheckPermissionOptions extends PermissionNoticeOverrides {
|
|
1456
|
-
/** The role or member to check. */
|
|
1457
|
-
for: Role | GuildMember;
|
|
1458
|
-
/** A guild reads the base bits from roles, a text channel reads the overwrite-resolved set. */
|
|
1459
|
-
in: Guild | TextChannel;
|
|
1460
|
-
/** The permission flag bits to check. */
|
|
1461
|
-
scope: PermissionScope;
|
|
1462
|
-
/** Refuse when the target holds a scope bit. */
|
|
1463
|
-
inverse?: boolean;
|
|
1464
|
-
}
|
|
1465
|
-
/**
|
|
1466
|
-
* Checks a {@link Role} or a {@link GuildMember} against the base permission bits in a {@link Guild},
|
|
1467
|
-
* before channel overwrites. Refuses when a permission in `scope` is missing, or with `inverse` when one
|
|
1468
|
-
* is present.
|
|
1469
|
-
*
|
|
1470
|
-
* @example
|
|
1471
|
-
* ```ts
|
|
1472
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1473
|
-
* import { checkPermissions } from '@seedcord/gateway';
|
|
1638
|
+
* several. Reply through the handler members, or rewrite the source message with `this.update`.
|
|
1474
1639
|
*
|
|
1475
|
-
*
|
|
1476
|
-
*
|
|
1640
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof TopicsId]`.
|
|
1641
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1477
1642
|
*
|
|
1478
1643
|
* @example
|
|
1479
1644
|
* ```ts
|
|
1480
|
-
*
|
|
1481
|
-
*
|
|
1482
|
-
*
|
|
1483
|
-
* }
|
|
1645
|
+
* \@StringMenuRoute(TopicsId)
|
|
1646
|
+
* class Topics extends StringMenuHandler<[typeof TopicsId]> {
|
|
1647
|
+
* async execute() {
|
|
1648
|
+
* const { userId } = this.params;
|
|
1649
|
+
* await this.update(`<@${userId}> now follows ${this.values.join(', ')}`);
|
|
1650
|
+
* }
|
|
1651
|
+
* }
|
|
1484
1652
|
* ```
|
|
1485
1653
|
*/
|
|
1486
|
-
declare
|
|
1654
|
+
declare abstract class StringMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<StringSelectMenuInteraction<Cache>, Defs> {
|
|
1655
|
+
/** @internal */
|
|
1656
|
+
readonly [ComponentKindBrand]?: InteractionKind.StringMenu;
|
|
1657
|
+
}
|
|
1487
1658
|
/**
|
|
1488
|
-
*
|
|
1489
|
-
* {@link TextChannel}. Refuses when a permission in `scope` is missing, or with `inverse` when one is
|
|
1490
|
-
* present.
|
|
1659
|
+
* Base class for a user select menu handler.
|
|
1491
1660
|
*
|
|
1492
|
-
*
|
|
1493
|
-
*
|
|
1494
|
-
* import { PermissionFlagsBits } from 'discord.js';
|
|
1495
|
-
* import { checkPermissions } from '@seedcord/gateway';
|
|
1661
|
+
* Beside `this.values` this handler declares `this.users` and `this.members`. Register the customId
|
|
1662
|
+
* definitions with `@UserMenuRoute` and list the same ones in the generic.
|
|
1496
1663
|
*
|
|
1497
|
-
*
|
|
1498
|
-
*
|
|
1499
|
-
*/
|
|
1500
|
-
declare function checkPermissions(target: Role | GuildMember, ctx: TextChannel, scope: PermissionScope, inverse?: boolean, errors?: PermissionNoticeOverrides): void;
|
|
1501
|
-
/**
|
|
1502
|
-
* Checks permissions with an options object. Refuses when a permission in
|
|
1503
|
-
* {@link CheckPermissionOptions.scope} is missing, or with `options.inverse` when one is present.
|
|
1664
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof AssignId]`.
|
|
1665
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1504
1666
|
*
|
|
1505
1667
|
* @example
|
|
1506
1668
|
* ```ts
|
|
1507
|
-
*
|
|
1508
|
-
*
|
|
1509
|
-
*
|
|
1510
|
-
*
|
|
1511
|
-
*
|
|
1512
|
-
*
|
|
1513
|
-
*
|
|
1514
|
-
* });
|
|
1669
|
+
* \@UserMenuRoute(AssignId)
|
|
1670
|
+
* class Assign extends UserMenuHandler<[typeof AssignId]> {
|
|
1671
|
+
* async execute() {
|
|
1672
|
+
* const { roleId } = this.params;
|
|
1673
|
+
* await this.reply(`assigning ${this.users.size} member(s) to <@&${roleId}>`);
|
|
1674
|
+
* }
|
|
1675
|
+
* }
|
|
1515
1676
|
* ```
|
|
1516
1677
|
*/
|
|
1517
|
-
declare
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
/**
|
|
1521
|
-
|
|
1522
|
-
*/
|
|
1523
|
-
|
|
1524
|
-
higherNotice?: new (message: string, role: Role, botRole: Role) => Notice;
|
|
1525
|
-
managedNotice?: new (message: string) => Notice;
|
|
1526
|
-
missingNotice?: new (message: string | undefined, subject: string, missingPerms: readonly string[]) => Notice;
|
|
1527
|
-
}
|
|
1528
|
-
/**
|
|
1529
|
-
* Options for {@link hasPermsToAssign}.
|
|
1530
|
-
*/
|
|
1531
|
-
interface HasPermsToAssignOptions {
|
|
1532
|
-
targetRole: Role;
|
|
1533
|
-
noticeOverrides?: AssignRoleNoticeOverrides;
|
|
1678
|
+
declare abstract class UserMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<UserSelectMenuInteraction<Cache>, Defs> {
|
|
1679
|
+
/** @internal */
|
|
1680
|
+
readonly [ComponentKindBrand]?: InteractionKind.UserMenu;
|
|
1681
|
+
/** The users this select picked. */
|
|
1682
|
+
protected get users(): UserSelectMenuInteraction<Cache>['users'];
|
|
1683
|
+
/** The guild members behind the picked users. Discord resolves these only inside a guild. */
|
|
1684
|
+
protected get members(): UserSelectMenuInteraction<Cache>['members'];
|
|
1534
1685
|
}
|
|
1535
1686
|
/**
|
|
1536
|
-
*
|
|
1687
|
+
* Base class for a role select menu handler.
|
|
1537
1688
|
*
|
|
1538
|
-
*
|
|
1539
|
-
*
|
|
1689
|
+
* Beside `this.values` this handler declares `this.roles`. Register the customId definitions with
|
|
1690
|
+
* `@RoleMenuRoute` and list the same ones in the generic.
|
|
1691
|
+
*
|
|
1692
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof GrantId]`.
|
|
1693
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1540
1694
|
*
|
|
1541
1695
|
* @example
|
|
1542
1696
|
* ```ts
|
|
1543
|
-
*
|
|
1544
|
-
*
|
|
1545
|
-
*
|
|
1546
|
-
*
|
|
1547
|
-
*
|
|
1548
|
-
*
|
|
1549
|
-
* hasPermsToAssign({
|
|
1550
|
-
* targetRole: role,
|
|
1551
|
-
* noticeOverrides: {
|
|
1552
|
-
* higherNotice: CustomHigherNotice,
|
|
1553
|
-
* managedNotice: CustomManagedNotice,
|
|
1554
|
-
* missingNotice: CustomMissingPermissionsNotice
|
|
1555
|
-
* }
|
|
1556
|
-
* });
|
|
1697
|
+
* \@RoleMenuRoute(GrantId)
|
|
1698
|
+
* class Grant extends RoleMenuHandler<[typeof GrantId]> {
|
|
1699
|
+
* async execute() {
|
|
1700
|
+
* await this.update(`granting ${this.roles.size} role(s)`);
|
|
1701
|
+
* }
|
|
1702
|
+
* }
|
|
1557
1703
|
* ```
|
|
1558
1704
|
*/
|
|
1559
|
-
declare
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
interface ConfirmOptions {
|
|
1565
|
-
/**
|
|
1566
|
-
* Whether the prompt is ephemeral. Only the invoking user can act on it either way, a non-invoker's
|
|
1567
|
-
* click is ignored.
|
|
1568
|
-
*
|
|
1569
|
-
* @defaultValue `true`
|
|
1570
|
-
*/
|
|
1571
|
-
ephemeral?: boolean;
|
|
1572
|
-
/**
|
|
1573
|
-
* Milliseconds to wait for a click before the prompt is settled and the result resolves to `false`.
|
|
1574
|
-
*
|
|
1575
|
-
* @defaultValue `30_000`
|
|
1576
|
-
*/
|
|
1577
|
-
timeoutMs?: number;
|
|
1578
|
-
/** Shown in place of the prompt when the user confirms. Absent removes the prompt. */
|
|
1579
|
-
onConfirm?: Outcome;
|
|
1580
|
-
/** Shown in place of the prompt when the user cancels. Absent removes the prompt. */
|
|
1581
|
-
onCancel?: Outcome;
|
|
1582
|
-
/** Shown in place of the prompt when the prompt times out. Absent removes the prompt. */
|
|
1583
|
-
onTimeout?: Outcome;
|
|
1584
|
-
}
|
|
1585
|
-
/** Options for the string-prompt form, adding the built-in Confirm/Cancel buttons' labels and style. */
|
|
1586
|
-
interface DefaultConfirmOptions extends ConfirmOptions {
|
|
1587
|
-
/**
|
|
1588
|
-
* Confirm-button label.
|
|
1589
|
-
*
|
|
1590
|
-
* @defaultValue `'Confirm'`
|
|
1591
|
-
*/
|
|
1592
|
-
confirmLabel?: string;
|
|
1593
|
-
/**
|
|
1594
|
-
* Cancel-button label.
|
|
1595
|
-
*
|
|
1596
|
-
* @defaultValue `'Cancel'`
|
|
1597
|
-
*/
|
|
1598
|
-
cancelLabel?: string;
|
|
1599
|
-
/**
|
|
1600
|
-
* Confirm-button style.
|
|
1601
|
-
*
|
|
1602
|
-
* @defaultValue {@link ButtonStyle.Danger}
|
|
1603
|
-
*/
|
|
1604
|
-
confirmStyle?: ButtonStyle;
|
|
1705
|
+
declare abstract class RoleMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<RoleSelectMenuInteraction<Cache>, Defs> {
|
|
1706
|
+
/** @internal */
|
|
1707
|
+
readonly [ComponentKindBrand]?: InteractionKind.RoleMenu;
|
|
1708
|
+
/** The roles this select picked. */
|
|
1709
|
+
protected get roles(): RoleSelectMenuInteraction<Cache>['roles'];
|
|
1605
1710
|
}
|
|
1606
1711
|
/**
|
|
1607
|
-
*
|
|
1608
|
-
* invoking user clicks confirm. A cancel click or a timeout resolves to `false`. Gate the action behind it
|
|
1609
|
-
* with an early return. A failed prompt send throws into the fault boundary. A {@link ModalHandler} is
|
|
1610
|
-
* excluded at compile time.
|
|
1712
|
+
* Base class for a channel select menu handler.
|
|
1611
1713
|
*
|
|
1612
|
-
*
|
|
1613
|
-
*
|
|
1614
|
-
*
|
|
1615
|
-
*
|
|
1616
|
-
* @
|
|
1714
|
+
* Beside `this.values` this handler declares `this.channels`. Register the customId definitions with
|
|
1715
|
+
* `@ChannelMenuRoute` and list the same ones in the generic.
|
|
1716
|
+
*
|
|
1717
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof LogTargetId]`.
|
|
1718
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1617
1719
|
*
|
|
1618
1720
|
* @example
|
|
1619
1721
|
* ```ts
|
|
1620
|
-
*
|
|
1621
|
-
*
|
|
1622
|
-
* \@SlashRoute('ban')
|
|
1623
|
-
* class BanHandler extends SlashHandler<'ban'> {
|
|
1722
|
+
* \@ChannelMenuRoute(LogTargetId)
|
|
1723
|
+
* class LogTarget extends ChannelMenuHandler<[typeof LogTargetId]> {
|
|
1624
1724
|
* async execute() {
|
|
1625
|
-
*
|
|
1626
|
-
* if (!(await getConfirmation(this, `Ban ${target.tag}? This cannot be undone.`))) return;
|
|
1627
|
-
* await this.event.guild?.members.ban(target.id);
|
|
1725
|
+
* await this.update(`logging to ${this.channels.size} channel(s)`);
|
|
1628
1726
|
* }
|
|
1629
1727
|
* }
|
|
1630
1728
|
* ```
|
|
1631
1729
|
*/
|
|
1632
|
-
declare
|
|
1730
|
+
declare abstract class ChannelMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<ChannelSelectMenuInteraction<Cache>, Defs> {
|
|
1731
|
+
/** @internal */
|
|
1732
|
+
readonly [ComponentKindBrand]?: InteractionKind.ChannelMenu;
|
|
1733
|
+
/** The channels this select picked. */
|
|
1734
|
+
protected get channels(): ChannelSelectMenuInteraction<Cache>['channels'];
|
|
1735
|
+
}
|
|
1633
1736
|
/**
|
|
1634
|
-
*
|
|
1635
|
-
* confirm. The factory receives the two minted button ids. Set them on your own buttons. A cancel click or a
|
|
1636
|
-
* timeout resolves to `false`. A failed prompt send throws into the fault boundary. A {@link ModalHandler} is
|
|
1637
|
-
* excluded at compile time.
|
|
1737
|
+
* Base class for a mentionable select menu handler.
|
|
1638
1738
|
*
|
|
1639
|
-
*
|
|
1640
|
-
*
|
|
1641
|
-
* it with the `BuilderComponent` and `RowComponent` wrappers.
|
|
1642
|
-
* @param options - Ephemeral flag, timeout, and the optional `onConfirm`/`onCancel`/`onTimeout` outcome
|
|
1643
|
-
* replies that edit the prompt in place.
|
|
1644
|
-
* @returns `true` if confirmed, `false` on cancel or timeout.
|
|
1739
|
+
* A mentionable menu accepts users and roles together. `this.users`, `this.members`, and `this.roles`
|
|
1740
|
+
* can each come back empty.
|
|
1645
1741
|
*
|
|
1646
|
-
* @
|
|
1647
|
-
*
|
|
1648
|
-
* prompt is gone once the user confirms, so deliver the result with a fresh `this.followUp(...)`.
|
|
1742
|
+
* @typeParam Defs - The customId definitions this handler decodes, e.g. `[typeof InviteId]`.
|
|
1743
|
+
* @typeParam Cache - The interaction cache state, `'cached'` by default.
|
|
1649
1744
|
*
|
|
1650
1745
|
* @example
|
|
1651
1746
|
* ```ts
|
|
1652
|
-
*
|
|
1653
|
-
*
|
|
1654
|
-
*
|
|
1655
|
-
*
|
|
1656
|
-
* class BanPrompt extends BuilderComponent<'container'> {
|
|
1657
|
-
* constructor(text: string) {
|
|
1658
|
-
* super('container');
|
|
1659
|
-
* this.instance.addTextDisplayComponents(new TextDisplayBuilder().setContent(text));
|
|
1660
|
-
* }
|
|
1661
|
-
* }
|
|
1662
|
-
*
|
|
1663
|
-
* class ConfirmRow extends RowComponent<'button'> {
|
|
1664
|
-
* constructor(ids: { confirm: string; cancel: string }) {
|
|
1665
|
-
* super('button');
|
|
1666
|
-
* const buttons = [
|
|
1667
|
-
* [ids.confirm, 'Ban', ButtonStyle.Danger],
|
|
1668
|
-
* [ids.cancel, 'Cancel', ButtonStyle.Secondary]
|
|
1669
|
-
* ] as const;
|
|
1670
|
-
* this.instance.addComponents(
|
|
1671
|
-
* ...buttons.map(([id, label, style]) => new ButtonBuilder().setCustomId(id).setLabel(label).setStyle(style))
|
|
1672
|
-
* );
|
|
1747
|
+
* \@MentionableMenuRoute(InviteId)
|
|
1748
|
+
* class Invite extends MentionableMenuHandler<[typeof InviteId]> {
|
|
1749
|
+
* async execute() {
|
|
1750
|
+
* await this.update(`inviting ${this.users.size} user(s) and ${this.roles.size} role(s)`);
|
|
1673
1751
|
* }
|
|
1674
1752
|
* }
|
|
1675
|
-
*
|
|
1676
|
-
* const target = this.options.getUser('target');
|
|
1677
|
-
* const confirmed = await getConfirmation(
|
|
1678
|
-
* this,
|
|
1679
|
-
* (ids) => ({ components: [new BanPrompt(`Ban ${target.tag}?`).component, new ConfirmRow(ids).component] }),
|
|
1680
|
-
* { onConfirm: { components: [new BanPrompt(`Banned ${target.tag}.`).component] } }
|
|
1681
|
-
* );
|
|
1682
|
-
* if (!confirmed) return;
|
|
1683
1753
|
* ```
|
|
1684
1754
|
*/
|
|
1685
|
-
declare
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1755
|
+
declare abstract class MentionableMenuHandler<Defs extends readonly AnyCustomId[], Cache extends CacheType = 'cached'> extends SelectMenuHandler<MentionableSelectMenuInteraction<Cache>, Defs> {
|
|
1756
|
+
/** @internal */
|
|
1757
|
+
readonly [ComponentKindBrand]?: InteractionKind.MentionableMenu;
|
|
1758
|
+
/** The users this select picked. */
|
|
1759
|
+
protected get users(): MentionableSelectMenuInteraction<Cache>['users'];
|
|
1760
|
+
/** The guild members behind the picked users. Discord resolves these only inside a guild. */
|
|
1761
|
+
protected get members(): MentionableSelectMenuInteraction<Cache>['members'];
|
|
1762
|
+
/** The roles this select picked. */
|
|
1763
|
+
protected get roles(): MentionableSelectMenuInteraction<Cache>['roles'];
|
|
1764
|
+
}
|
|
1689
1765
|
//#endregion
|
|
1690
1766
|
//#region src/pagination/PageContext.d.ts
|
|
1691
1767
|
/**
|
|
@@ -1703,7 +1779,7 @@ interface PageContext {
|
|
|
1703
1779
|
}
|
|
1704
1780
|
//#endregion
|
|
1705
1781
|
//#region src/pagination/Paginator.d.ts
|
|
1706
|
-
type PaginatorHandlerCtor<Prefix extends string> = new (
|
|
1782
|
+
type PaginatorHandlerCtor<Prefix extends string> = new (...args: ConstructorParameters<typeof ButtonHandler>) => ButtonHandler<[PageCursor<Prefix>], CacheType> & {
|
|
1707
1783
|
execute(): Promise<void>;
|
|
1708
1784
|
};
|
|
1709
1785
|
/**
|
|
@@ -1856,5 +1932,5 @@ declare class Seedcord extends Pluggable<'gateway', 'server'> implements Core, S
|
|
|
1856
1932
|
/** Package version */
|
|
1857
1933
|
declare const version: string;
|
|
1858
1934
|
//#endregion
|
|
1859
|
-
export { ArraySource, AssignRoleNoticeOverrides, AutocompleteHandler, BaseHandler, ButtonHandler, ChannelMenuHandler, type CheckPermissionOptions, ComponentHandler, type ConfirmOptions, type Core, CursorSource, type DefaultConfirmOptions, Emojis, type EventGateContext, EventHandler, EventMiddleware, type EventSpec, type EventsConfig, type GateContext, Gated, type GatewayBotConfig, type GatewayConfig, GatewayEmoji, type GatewayFile, type GatewayPluginOptions, type GatewayReplyResponse, HasPermsToAssignOptions, IgnoreBots, type InjectedEmojiMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, MentionableMenuHandler, MessageContextMenuHandler,
|
|
1935
|
+
export { ArraySource, AssignRoleNoticeOverrides, AutocompleteHandler, BaseHandler, ButtonHandler, ChannelMenuHandler, type CheckPermissionOptions, ComponentHandler, type ConfirmOptions, type Core, CursorSource, type DefaultConfirmOptions, Emojis, type EventGateContext, EventHandler, EventMiddleware, type EventMiddlewareOptions, type EventSpec, type EventsConfig, type GateContext, Gated, type GatewayBotConfig, type GatewayConfig, GatewayEmoji, type GatewayFile, type GatewayPluginOptions, type GatewayReplyResponse, HasPermsToAssignOptions, IgnoreBots, type InjectedEmojiMap, type InteractionGateContext, InteractionHandler, InteractionMiddleware, MentionableMenuHandler, MessageContextMenuHandler, ModalHandler, Nsfw, type PageContext, type PageSource, Paginator, Plugin, type PluginLifecycleSpec, type PluginOptions, RegisterEvent, RegisterEventMiddleware, type RegisterEventOptions, RepliableHandler, type Repliables, ReplySender, RoleMenuHandler, Seedcord, SelectMenuHandler, type SentMessage, SlashHandler, type SlashOptions, StringMenuHandler, Subscriber, UserContextMenuHandler, UserMenuHandler, type ValidEventTypes, type ValidInteractionTypes, type ValidNonInteractionKeys, WebhookLog, WinstonConsoleSink, WinstonFileSink, checkBotPermissions, checkPermissions, getConfirmation, hasPermsToAssign, version };
|
|
1860
1936
|
//# sourceMappingURL=index.d.mts.map
|