diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2e02632d..c2a1363d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1080,8 +1080,8 @@ packages: resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} hasBin: true - jschardet@3.1.2: - resolution: {integrity: sha512-mw3CBZGzW8nUBPYhFU2ztZ/kJ6NClQUQVpyzvFMfznZsoC///ZQ30J2RCUanNsr5yF22LqhgYr/lj807/ZleWA==} + jschardet@3.1.3: + resolution: {integrity: sha512-Q1PKVMK/uu+yjdlobgWIYkUOCR1SqUmW9m/eUJNNj4zI2N12i25v8fYpVf+zCakQeaTdBdhnZTFbVIAVZIVVOg==} engines: {node: '>=0.1.90'} json-buffer@3.0.1: @@ -1864,7 +1864,7 @@ snapshots: '@microsoft/eslint-formatter-sarif@3.0.0': dependencies: eslint: 8.56.0 - jschardet: 3.1.2 + jschardet: 3.1.3 lodash: 4.17.21 utf8: 3.0.0 transitivePeerDependencies: @@ -2725,7 +2725,7 @@ snapshots: dependencies: argparse: 2.0.1 - jschardet@3.1.2: {} + jschardet@3.1.3: {} json-buffer@3.0.1: {} diff --git a/src/creator.ts b/src/creator.ts index 9e4b8cb6..b03ebddb 100644 --- a/src/creator.ts +++ b/src/creator.ts @@ -558,7 +558,7 @@ export class BaseSlashCreator extends (EventEmitter as any as new () => TypedEve interaction: AnyRequestData, respond: RespondFunction | null, webserverMode: boolean, - context: unknown + serverContext: unknown ) { this.emit('rawInteraction', interaction); @@ -598,7 +598,7 @@ export class BaseSlashCreator extends (EventEmitter as any as new () => TypedEve webserverMode, this.unknownCommand.deferEphemeral, !this.options.disableTimeouts, - context + serverContext ); return this._runCommand(this.unknownCommand, ctx); } else if (this.options.unknownCommandResponse) @@ -627,7 +627,7 @@ export class BaseSlashCreator extends (EventEmitter as any as new () => TypedEve webserverMode, command.deferEphemeral, !this.options.disableTimeouts, - context + serverContext ); // Ensure the user has permission to use the command @@ -659,7 +659,7 @@ export class BaseSlashCreator extends (EventEmitter as any as new () => TypedEve ); if (this._componentCallbacks.size || this.listenerCount('componentInteraction') > 0) { - const ctx = new ComponentContext(this, interaction, respond, !this.options.disableTimeouts); + const ctx = new ComponentContext(this, interaction, respond, !this.options.disableTimeouts, serverContext); this.emit('componentInteraction', ctx); this.cleanRegisteredComponents(); @@ -685,7 +685,7 @@ export class BaseSlashCreator extends (EventEmitter as any as new () => TypedEve } case InteractionType.APPLICATION_COMMAND_AUTOCOMPLETE: { const command = this._getCommandFromInteraction(interaction); - const ctx = new AutocompleteContext(this, interaction, respond); + const ctx = new AutocompleteContext(this, interaction, respond, serverContext); this.emit('autocompleteInteraction', ctx, command); if (!command) { @@ -716,20 +716,25 @@ export class BaseSlashCreator extends (EventEmitter as any as new () => TypedEve } case InteractionType.MODAL_SUBMIT: { try { - const context = new ModalInteractionContext(this, interaction, respond, !this.options.disableTimeouts); - this.emit('modalInteraction', context); + const ctx = new ModalInteractionContext( + this, + interaction, + respond, + !this.options.disableTimeouts, + serverContext + ); + this.emit('modalInteraction', ctx); this.cleanRegisteredComponents(); - const modalCallbackKey = `${context.user.id}-${context.customID}`; - const globalCallbackKey = `global-${context.customID}`; + const modalCallbackKey = `${ctx.user.id}-${ctx.customID}`; + const globalCallbackKey = `global-${ctx.customID}`; if (this._modalCallbacks.has(modalCallbackKey)) { - this._modalCallbacks.get(modalCallbackKey)!.callback(context); + this._modalCallbacks.get(modalCallbackKey)!.callback(ctx); this._modalCallbacks.delete(modalCallbackKey); return; } - if (this._modalCallbacks.has(globalCallbackKey)) - this._modalCallbacks.get(modalCallbackKey)!.callback(context); + if (this._modalCallbacks.has(globalCallbackKey)) this._modalCallbacks.get(modalCallbackKey)!.callback(ctx); return; } catch (err) { diff --git a/src/structures/interfaces/autocompleteContext.ts b/src/structures/interfaces/autocompleteContext.ts index 77565781..d8245b93 100644 --- a/src/structures/interfaces/autocompleteContext.ts +++ b/src/structures/interfaces/autocompleteContext.ts @@ -5,7 +5,7 @@ import { BaseInteractionContext } from './baseInteraction'; import { CommandContext } from './commandContext'; /** Represents a autocomplete interaction context. */ -export class AutocompleteContext extends BaseInteractionContext { +export class AutocompleteContext extends BaseInteractionContext { /** The full interaction data. */ readonly data: CommandAutocompleteRequestData; /** The options given to the command. */ @@ -24,9 +24,15 @@ export class AutocompleteContext extends BaseInteractionContext { * @param creator The instantiating creator. * @param data The interaction data. * @param respond The response function for the interaction. + * @param serverContext The context of the server. */ - constructor(creator: BaseSlashCreator, data: CommandAutocompleteRequestData, respond: RespondFunction) { - super(creator, data); + constructor( + creator: BaseSlashCreator, + data: CommandAutocompleteRequestData, + respond: RespondFunction, + serverContext: ServerContext + ) { + super(creator, data, serverContext); this._respond = respond; this.data = data; diff --git a/src/structures/interfaces/baseInteraction.ts b/src/structures/interfaces/baseInteraction.ts index 07ac4126..07f8959c 100644 --- a/src/structures/interfaces/baseInteraction.ts +++ b/src/structures/interfaces/baseInteraction.ts @@ -10,9 +10,11 @@ import { ResolvedMember } from '../resolvedMember'; import { Role } from '../role'; /** Represents a basic interaction context. */ -export class BaseInteractionContext { +export class BaseInteractionContext { /** The creator of the interaction request. */ readonly creator: BaseSlashCreator; + /** Context passed by the server */ + readonly serverContext: ServerContext; /** The interaction's token. */ readonly interactionToken: string; /** The interaction's ID. */ @@ -61,9 +63,11 @@ export class BaseInteractionContext { /** * @param creator The instantiating creator. * @param data The interaction data. + * @param serverContext The context of the server. */ - constructor(creator: BaseSlashCreator, data: any) { + constructor(creator: BaseSlashCreator, data: any, serverContext: ServerContext) { this.creator = creator; + this.serverContext = serverContext; this.interactionToken = data.token; this.interactionID = data.id; diff --git a/src/structures/interfaces/commandContext.ts b/src/structures/interfaces/commandContext.ts index 09c516ec..b5383b13 100644 --- a/src/structures/interfaces/commandContext.ts +++ b/src/structures/interfaces/commandContext.ts @@ -4,7 +4,7 @@ import { AnyCommandOption, ApplicationCommandType, InteractionRequestData } from import { ModalSendableContext } from './modalSendableContext'; /** Context representing a command interaction. */ -export class CommandContext extends ModalSendableContext { +export class CommandContext extends ModalSendableContext { /** The full interaction data. */ readonly data: InteractionRequestData; @@ -24,9 +24,6 @@ export class CommandContext extends ModalSe /** Whether the context is from a webserver. */ private webserverMode: boolean; - /** Context passed by the server */ - readonly serverContext: ServerContext; - /** * @param creator The instantiating creator. * @param data The interaction data for the context. @@ -44,7 +41,7 @@ export class CommandContext extends ModalSe useTimeout = true, serverContext: ServerContext ) { - super(creator, data, respond); + super(creator, data, respond, serverContext); this.data = data; this.webserverMode = webserverMode; @@ -54,7 +51,7 @@ export class CommandContext extends ModalSe if (data.data.target_id) this.targetID = data.data.target_id; this.options = data.data.options ? CommandContext.convertOptions(data.data.options) : {}; this.subcommands = data.data.options ? CommandContext.getSubcommandArray(data.data.options) : []; - this.serverContext = serverContext; + // Auto-defer if no response was given in 2 seconds if (useTimeout) this._timeout = setTimeout(() => this.defer(deferEphemeral || false), 2000); } diff --git a/src/structures/interfaces/componentContext.ts b/src/structures/interfaces/componentContext.ts index 07ad0710..3a08d41d 100644 --- a/src/structures/interfaces/componentContext.ts +++ b/src/structures/interfaces/componentContext.ts @@ -7,7 +7,7 @@ import { formatAllowedMentions, FormattedAllowedMentions } from '../../util'; import { ModalSendableContext } from './modalSendableContext'; /** Represents an interaction context from a message component. */ -export class ComponentContext extends ModalSendableContext { +export class ComponentContext extends ModalSendableContext { /** The request data. */ readonly data: MessageComponentRequestData; @@ -25,14 +25,16 @@ export class ComponentContext extends ModalSendableContext { * @param data The interaction data for the context. * @param respond The response function for the interaction. * @param useTimeout Whether to use the acknowledgement timeout. + * @param serverContext The context of the server. */ constructor( creator: BaseSlashCreator, data: MessageComponentRequestData, respond: RespondFunction, - useTimeout = true + useTimeout = true, + serverContext: ServerContext ) { - super(creator, data, respond); + super(creator, data, respond, serverContext); this.data = data; this.customID = data.data.custom_id; diff --git a/src/structures/interfaces/messageInteraction.ts b/src/structures/interfaces/messageInteraction.ts index 57e39827..248dcdc6 100644 --- a/src/structures/interfaces/messageInteraction.ts +++ b/src/structures/interfaces/messageInteraction.ts @@ -6,7 +6,9 @@ import { Message, MessageEmbedOptions } from '../message'; import { BaseInteractionContext } from './baseInteraction'; /** Represents a interaction context that handles messages. */ -export class MessageInteractionContext extends BaseInteractionContext { +export class MessageInteractionContext< + ServerContext extends any = unknown +> extends BaseInteractionContext { /** Whether the initial response was sent. */ initiallyResponded = false; /** Whether there is a deferred message available. */ @@ -22,9 +24,10 @@ export class MessageInteractionContext extends BaseInteractionContext { * @param creator The instantiating creator. * @param data The interaction data. * @param respond The response function for the interaction. + * @param serverContext The context of the server. */ - constructor(creator: BaseSlashCreator, data: any, respond: RespondFunction) { - super(creator, data); + constructor(creator: BaseSlashCreator, data: any, respond: RespondFunction, serverContext: ServerContext) { + super(creator, data, serverContext); this._respond = respond; } diff --git a/src/structures/interfaces/modalInteractionContext.ts b/src/structures/interfaces/modalInteractionContext.ts index e2a643bb..765ac953 100644 --- a/src/structures/interfaces/modalInteractionContext.ts +++ b/src/structures/interfaces/modalInteractionContext.ts @@ -11,7 +11,9 @@ import { Message } from '../message'; import { EditMessageOptions, MessageInteractionContext } from './messageInteraction'; /** Represents an interaction context from a modal submission. */ -export class ModalInteractionContext extends MessageInteractionContext { +export class ModalInteractionContext< + ServerContext extends any = unknown +> extends MessageInteractionContext { /** The request data. */ readonly data: ModalSubmitRequestData; /** The ID of the component to identify its origin from. */ @@ -27,9 +29,16 @@ export class ModalInteractionContext extends MessageInteractionContext { * @param data The interaction data for the context. * @param respond The response function for the interaction. * @param useTimeout Whether to use the deferral timeout. + * @param serverContext The context of the server. */ - constructor(creator: BaseSlashCreator, data: ModalSubmitRequestData, respond: RespondFunction, useTimeout = true) { - super(creator, data, respond); + constructor( + creator: BaseSlashCreator, + data: ModalSubmitRequestData, + respond: RespondFunction, + useTimeout = true, + serverContext: ServerContext + ) { + super(creator, data, respond, serverContext); this.data = data; this.customID = data.data.custom_id; diff --git a/src/structures/interfaces/modalSendableContext.ts b/src/structures/interfaces/modalSendableContext.ts index ce93e102..6a68e6d7 100644 --- a/src/structures/interfaces/modalSendableContext.ts +++ b/src/structures/interfaces/modalSendableContext.ts @@ -5,9 +5,11 @@ import { generateID } from '../../util'; import { MessageInteractionContext } from './messageInteraction'; /** Represents an interaction that can send modals. */ -export class ModalSendableContext extends MessageInteractionContext { - constructor(creator: BaseSlashCreator, data: any, respond: RespondFunction) { - super(creator, data, respond); +export class ModalSendableContext< + ServerContext extends any = unknown +> extends MessageInteractionContext { + constructor(creator: BaseSlashCreator, data: any, respond: RespondFunction, serverContext: ServerContext) { + super(creator, data, respond, serverContext); } /**