@minesa-org/mini-interaction 0.2.10 → 0.2.12
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.
|
@@ -13,130 +13,32 @@ export type MentionableOption = {
|
|
|
13
13
|
value: APIRole;
|
|
14
14
|
};
|
|
15
15
|
export declare const MentionableOption: {};
|
|
16
|
-
/**
|
|
17
|
-
* Provides ergonomic helpers for extracting typed command options from Discord interactions.
|
|
18
|
-
*/
|
|
19
16
|
export declare class CommandInteractionOptionResolver {
|
|
20
17
|
readonly raw: ReadonlyArray<APIApplicationCommandInteractionDataOption>;
|
|
21
18
|
private readonly resolved;
|
|
22
19
|
private readonly focusedOptions;
|
|
23
20
|
private readonly subcommand;
|
|
24
21
|
private readonly subcommandGroup;
|
|
25
|
-
/**
|
|
26
|
-
* Creates a new resolver from raw interaction options.
|
|
27
|
-
*
|
|
28
|
-
* @param options - The raw options provided by Discord.
|
|
29
|
-
* @param resolved - The resolved data map included with the interaction payload.
|
|
30
|
-
*/
|
|
31
22
|
constructor(options: APIApplicationCommandInteractionDataOption[] | undefined, resolved: APIInteractionDataResolved | undefined);
|
|
32
|
-
/**
|
|
33
|
-
* Retrieves the subcommand invoked by the user.
|
|
34
|
-
*
|
|
35
|
-
* @param required - Whether to throw when the subcommand is missing.
|
|
36
|
-
*/
|
|
37
23
|
getSubcommand(required?: boolean): string | null;
|
|
38
|
-
/**
|
|
39
|
-
* Retrieves the subcommand group invoked by the user.
|
|
40
|
-
*
|
|
41
|
-
* @param required - Whether to throw when the subcommand group is missing.
|
|
42
|
-
*/
|
|
43
24
|
getSubcommandGroup(required?: boolean): string | null;
|
|
44
|
-
/**
|
|
45
|
-
* Looks up a string option by name.
|
|
46
|
-
*
|
|
47
|
-
* @param name - The option name to resolve.
|
|
48
|
-
* @param required - Whether to throw when the option is missing.
|
|
49
|
-
*/
|
|
50
25
|
getString(name: string, required?: boolean): string | null;
|
|
51
|
-
/**
|
|
52
|
-
* Looks up an integer option by name.
|
|
53
|
-
*
|
|
54
|
-
* @param name - The option name to resolve.
|
|
55
|
-
* @param required - Whether to throw when the option is missing.
|
|
56
|
-
*/
|
|
57
26
|
getInteger(name: string, required?: boolean): number | null;
|
|
58
|
-
/**
|
|
59
|
-
* Looks up a numeric option by name.
|
|
60
|
-
*
|
|
61
|
-
* @param name - The option name to resolve.
|
|
62
|
-
*/
|
|
63
27
|
getNumber(name: string, required?: boolean): number | null;
|
|
64
|
-
/**
|
|
65
|
-
* Looks up a boolean option by name.
|
|
66
|
-
*
|
|
67
|
-
* @param name - The option name to resolve.
|
|
68
|
-
* @param required - Whether to throw when the option is missing.
|
|
69
|
-
*/
|
|
70
28
|
getBoolean(name: string, required?: boolean): boolean | null;
|
|
71
|
-
/**
|
|
72
|
-
* Resolves a user option, including any guild member payload.
|
|
73
|
-
*
|
|
74
|
-
* @param name - The option name to resolve.
|
|
75
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
76
|
-
*/
|
|
77
29
|
getUser(name: string, required?: boolean): ResolvedUserOption | null;
|
|
78
|
-
/**
|
|
79
|
-
* Resolves a role option to its resolved payload.
|
|
80
|
-
*
|
|
81
|
-
* @param name - The option name to resolve.
|
|
82
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
83
|
-
*/
|
|
84
30
|
getRole(name: string, required?: boolean): APIRole | null;
|
|
85
|
-
/**
|
|
86
|
-
* Resolves a channel option to its resolved payload.
|
|
87
|
-
*
|
|
88
|
-
* @param name - The option name to resolve.
|
|
89
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
90
|
-
*/
|
|
91
31
|
getChannel(name: string, required?: boolean): APIInteractionDataResolvedChannel | null;
|
|
92
|
-
/**
|
|
93
|
-
* Resolves an attachment option to its resolved payload.
|
|
94
|
-
*
|
|
95
|
-
* @param name - The option name to resolve.
|
|
96
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
97
|
-
*/
|
|
98
32
|
getAttachment(name: string, required?: boolean): APIAttachment | null;
|
|
99
|
-
/**
|
|
100
|
-
* Resolves a mentionable option to either a role or user payload.
|
|
101
|
-
*
|
|
102
|
-
* @param name - The option name to resolve.
|
|
103
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
104
|
-
*/
|
|
105
33
|
getMentionable(name: string, required?: boolean): MentionableOption | null;
|
|
106
|
-
/**
|
|
107
|
-
* Returns the raw option payload, bypassing type checks and casting.
|
|
108
|
-
*
|
|
109
|
-
* @param name - The option name to look up.
|
|
110
|
-
*/
|
|
111
34
|
getRawOption(name: string): APIApplicationCommandInteractionDataOption | null;
|
|
112
|
-
/**
|
|
113
|
-
* Extracts a strongly typed option, ensuring it exists and matches the expected type.
|
|
114
|
-
*/
|
|
115
35
|
private extractOption;
|
|
116
|
-
/**
|
|
117
|
-
* Resolves an attachment by identifier from the interaction's resolved payloads.
|
|
118
|
-
*/
|
|
119
36
|
private resolveAttachment;
|
|
120
|
-
/**
|
|
121
|
-
* Resolves a channel by identifier from the interaction's resolved payloads.
|
|
122
|
-
*/
|
|
123
37
|
private resolveChannel;
|
|
124
|
-
/**
|
|
125
|
-
* Resolves a role by identifier from the interaction's resolved payloads.
|
|
126
|
-
*/
|
|
127
38
|
private resolveRole;
|
|
128
|
-
/**
|
|
129
|
-
* Resolves a user and optional member by identifier from the interaction's resolved payloads.
|
|
130
|
-
*/
|
|
131
39
|
private resolveUser;
|
|
132
|
-
/**
|
|
133
|
-
* Retrieves a record from a resolved payload map by identifier.
|
|
134
|
-
*/
|
|
135
40
|
private getResolvedRecord;
|
|
136
41
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Represents a command interaction augmented with helper methods for easy responses.
|
|
139
|
-
*/
|
|
140
42
|
export interface CommandInteraction extends Omit<APIChatInputApplicationCommandInteraction, "data"> {
|
|
141
43
|
data: Omit<APIChatInputApplicationCommandInteraction["data"], "options"> & {
|
|
142
44
|
options: CommandInteractionOptionResolver;
|
|
@@ -144,9 +46,9 @@ export interface CommandInteraction extends Omit<APIChatInputApplicationCommandI
|
|
|
144
46
|
options: CommandInteractionOptionResolver;
|
|
145
47
|
getResponse(): APIInteractionResponse | null;
|
|
146
48
|
reply(data: InteractionMessageData): APIInteractionResponseChannelMessageWithSource;
|
|
147
|
-
followUp(data: InteractionMessageData): Promise<
|
|
49
|
+
followUp(data: InteractionMessageData): Promise<void>;
|
|
148
50
|
edit(data?: InteractionMessageData): APIInteractionResponseUpdateMessage;
|
|
149
|
-
editReply(data?: InteractionMessageData): Promise<
|
|
51
|
+
editReply(data?: InteractionMessageData): Promise<void>;
|
|
150
52
|
deferReply(options?: DeferReplyOptions): APIInteractionResponseDeferredChannelMessageWithSource;
|
|
151
53
|
showModal(data: APIModalInteractionResponseCallbackData | {
|
|
152
54
|
toJSON(): APIModalInteractionResponseCallbackData;
|
|
@@ -158,13 +60,6 @@ export interface CommandInteraction extends Omit<APIChatInputApplicationCommandI
|
|
|
158
60
|
sendFollowUp?(token: string, response: APIInteractionResponse, messageId?: string): Promise<void>;
|
|
159
61
|
}
|
|
160
62
|
export declare const CommandInteraction: {};
|
|
161
|
-
/**
|
|
162
|
-
* Wraps a raw application command interaction with helper methods and option resolvers.
|
|
163
|
-
*
|
|
164
|
-
* @param interaction - The raw interaction payload from Discord.
|
|
165
|
-
* @param helpers - Optional helper methods for state management and logging.
|
|
166
|
-
* @returns A helper-augmented interaction object.
|
|
167
|
-
*/
|
|
168
63
|
export declare function createCommandInteraction(interaction: APIChatInputApplicationCommandInteraction, helpers?: {
|
|
169
64
|
canRespond?: (interactionId: string) => boolean;
|
|
170
65
|
trackResponse?: (interactionId: string, token: string, state: 'responded' | 'deferred') => void;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import { ApplicationCommandOptionType, InteractionResponseType,
|
|
1
|
+
import { ApplicationCommandOptionType, InteractionResponseType, } from "discord-api-types/v10";
|
|
2
2
|
import { normaliseInteractionMessageData, normaliseMessageFlags, } from "./interactionMessageHelpers.js";
|
|
3
3
|
export const ResolvedUserOption = {};
|
|
4
4
|
export const MentionableOption = {};
|
|
5
|
-
/** Maps application command option types to human-readable labels for error messages. */
|
|
6
5
|
const OPTION_TYPE_LABEL = {
|
|
7
6
|
[ApplicationCommandOptionType.Subcommand]: "subcommand",
|
|
8
7
|
[ApplicationCommandOptionType.SubcommandGroup]: "subcommand group",
|
|
@@ -16,28 +15,12 @@ const OPTION_TYPE_LABEL = {
|
|
|
16
15
|
[ApplicationCommandOptionType.Number]: "number",
|
|
17
16
|
[ApplicationCommandOptionType.Attachment]: "attachment",
|
|
18
17
|
};
|
|
19
|
-
/**
|
|
20
|
-
* Determines whether the provided option represents a subcommand.
|
|
21
|
-
*
|
|
22
|
-
* @param option - The option to inspect.
|
|
23
|
-
*/
|
|
24
18
|
function isSubcommandOption(option) {
|
|
25
19
|
return option.type === ApplicationCommandOptionType.Subcommand;
|
|
26
20
|
}
|
|
27
|
-
/**
|
|
28
|
-
* Determines whether the provided option represents a subcommand group.
|
|
29
|
-
*
|
|
30
|
-
* @param option - The option to inspect.
|
|
31
|
-
*/
|
|
32
21
|
function isSubcommandGroupOption(option) {
|
|
33
22
|
return option.type === ApplicationCommandOptionType.SubcommandGroup;
|
|
34
23
|
}
|
|
35
|
-
/**
|
|
36
|
-
* Extracts the most relevant option set from the raw command options hierarchy.
|
|
37
|
-
*
|
|
38
|
-
* @param options - The raw options array from the interaction payload.
|
|
39
|
-
* @returns The resolved subcommand context and focused options for convenience accessors.
|
|
40
|
-
*/
|
|
41
24
|
function resolveFocusedOptions(options) {
|
|
42
25
|
if (!options || options.length === 0) {
|
|
43
26
|
return { subcommandGroup: null, subcommand: null, options: [] };
|
|
@@ -71,21 +54,12 @@ function resolveFocusedOptions(options) {
|
|
|
71
54
|
options: options,
|
|
72
55
|
};
|
|
73
56
|
}
|
|
74
|
-
/**
|
|
75
|
-
* Provides ergonomic helpers for extracting typed command options from Discord interactions.
|
|
76
|
-
*/
|
|
77
57
|
export class CommandInteractionOptionResolver {
|
|
78
58
|
raw;
|
|
79
59
|
resolved;
|
|
80
60
|
focusedOptions;
|
|
81
61
|
subcommand;
|
|
82
62
|
subcommandGroup;
|
|
83
|
-
/**
|
|
84
|
-
* Creates a new resolver from raw interaction options.
|
|
85
|
-
*
|
|
86
|
-
* @param options - The raw options provided by Discord.
|
|
87
|
-
* @param resolved - The resolved data map included with the interaction payload.
|
|
88
|
-
*/
|
|
89
63
|
constructor(options, resolved) {
|
|
90
64
|
this.raw = Object.freeze([...(options ?? [])]);
|
|
91
65
|
this.resolved = resolved;
|
|
@@ -94,11 +68,6 @@ export class CommandInteractionOptionResolver {
|
|
|
94
68
|
this.subcommand = focused.subcommand;
|
|
95
69
|
this.subcommandGroup = focused.subcommandGroup;
|
|
96
70
|
}
|
|
97
|
-
/**
|
|
98
|
-
* Retrieves the subcommand invoked by the user.
|
|
99
|
-
*
|
|
100
|
-
* @param required - Whether to throw when the subcommand is missing.
|
|
101
|
-
*/
|
|
102
71
|
getSubcommand(required = true) {
|
|
103
72
|
if (this.subcommand) {
|
|
104
73
|
return this.subcommand;
|
|
@@ -108,11 +77,6 @@ export class CommandInteractionOptionResolver {
|
|
|
108
77
|
}
|
|
109
78
|
return null;
|
|
110
79
|
}
|
|
111
|
-
/**
|
|
112
|
-
* Retrieves the subcommand group invoked by the user.
|
|
113
|
-
*
|
|
114
|
-
* @param required - Whether to throw when the subcommand group is missing.
|
|
115
|
-
*/
|
|
116
80
|
getSubcommandGroup(required = true) {
|
|
117
81
|
if (this.subcommandGroup) {
|
|
118
82
|
return this.subcommandGroup;
|
|
@@ -122,51 +86,22 @@ export class CommandInteractionOptionResolver {
|
|
|
122
86
|
}
|
|
123
87
|
return null;
|
|
124
88
|
}
|
|
125
|
-
/**
|
|
126
|
-
* Looks up a string option by name.
|
|
127
|
-
*
|
|
128
|
-
* @param name - The option name to resolve.
|
|
129
|
-
* @param required - Whether to throw when the option is missing.
|
|
130
|
-
*/
|
|
131
89
|
getString(name, required = false) {
|
|
132
90
|
const option = this.extractOption(name, ApplicationCommandOptionType.String, required);
|
|
133
91
|
return option ? option.value : null;
|
|
134
92
|
}
|
|
135
|
-
/**
|
|
136
|
-
* Looks up an integer option by name.
|
|
137
|
-
*
|
|
138
|
-
* @param name - The option name to resolve.
|
|
139
|
-
* @param required - Whether to throw when the option is missing.
|
|
140
|
-
*/
|
|
141
93
|
getInteger(name, required = false) {
|
|
142
94
|
const option = this.extractOption(name, ApplicationCommandOptionType.Integer, required);
|
|
143
95
|
return option ? option.value : null;
|
|
144
96
|
}
|
|
145
|
-
/**
|
|
146
|
-
* Looks up a numeric option by name.
|
|
147
|
-
*
|
|
148
|
-
* @param name - The option name to resolve.
|
|
149
|
-
*/
|
|
150
97
|
getNumber(name, required = false) {
|
|
151
98
|
const option = this.extractOption(name, ApplicationCommandOptionType.Number, required);
|
|
152
99
|
return option ? option.value : null;
|
|
153
100
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Looks up a boolean option by name.
|
|
156
|
-
*
|
|
157
|
-
* @param name - The option name to resolve.
|
|
158
|
-
* @param required - Whether to throw when the option is missing.
|
|
159
|
-
*/
|
|
160
101
|
getBoolean(name, required = false) {
|
|
161
102
|
const option = this.extractOption(name, ApplicationCommandOptionType.Boolean, required);
|
|
162
103
|
return option ? option.value : null;
|
|
163
104
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Resolves a user option, including any guild member payload.
|
|
166
|
-
*
|
|
167
|
-
* @param name - The option name to resolve.
|
|
168
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
169
|
-
*/
|
|
170
105
|
getUser(name, required = false) {
|
|
171
106
|
const option = this.extractOption(name, ApplicationCommandOptionType.User, required);
|
|
172
107
|
if (!option) {
|
|
@@ -181,12 +116,6 @@ export class CommandInteractionOptionResolver {
|
|
|
181
116
|
}
|
|
182
117
|
return resolvedUser;
|
|
183
118
|
}
|
|
184
|
-
/**
|
|
185
|
-
* Resolves a role option to its resolved payload.
|
|
186
|
-
*
|
|
187
|
-
* @param name - The option name to resolve.
|
|
188
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
189
|
-
*/
|
|
190
119
|
getRole(name, required = false) {
|
|
191
120
|
const option = this.extractOption(name, ApplicationCommandOptionType.Role, required);
|
|
192
121
|
if (!option) {
|
|
@@ -198,12 +127,6 @@ export class CommandInteractionOptionResolver {
|
|
|
198
127
|
}
|
|
199
128
|
return role ?? null;
|
|
200
129
|
}
|
|
201
|
-
/**
|
|
202
|
-
* Resolves a channel option to its resolved payload.
|
|
203
|
-
*
|
|
204
|
-
* @param name - The option name to resolve.
|
|
205
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
206
|
-
*/
|
|
207
130
|
getChannel(name, required = false) {
|
|
208
131
|
const option = this.extractOption(name, ApplicationCommandOptionType.Channel, required);
|
|
209
132
|
if (!option) {
|
|
@@ -215,12 +138,6 @@ export class CommandInteractionOptionResolver {
|
|
|
215
138
|
}
|
|
216
139
|
return channel ?? null;
|
|
217
140
|
}
|
|
218
|
-
/**
|
|
219
|
-
* Resolves an attachment option to its resolved payload.
|
|
220
|
-
*
|
|
221
|
-
* @param name - The option name to resolve.
|
|
222
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
223
|
-
*/
|
|
224
141
|
getAttachment(name, required = false) {
|
|
225
142
|
const option = this.extractOption(name, ApplicationCommandOptionType.Attachment, required);
|
|
226
143
|
if (!option) {
|
|
@@ -232,12 +149,6 @@ export class CommandInteractionOptionResolver {
|
|
|
232
149
|
}
|
|
233
150
|
return attachment ?? null;
|
|
234
151
|
}
|
|
235
|
-
/**
|
|
236
|
-
* Resolves a mentionable option to either a role or user payload.
|
|
237
|
-
*
|
|
238
|
-
* @param name - The option name to resolve.
|
|
239
|
-
* @param required - Whether to throw when the option is missing or cannot be resolved.
|
|
240
|
-
*/
|
|
241
152
|
getMentionable(name, required = false) {
|
|
242
153
|
const option = this.extractOption(name, ApplicationCommandOptionType.Mentionable, required);
|
|
243
154
|
if (!option) {
|
|
@@ -256,17 +167,9 @@ export class CommandInteractionOptionResolver {
|
|
|
256
167
|
}
|
|
257
168
|
return null;
|
|
258
169
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Returns the raw option payload, bypassing type checks and casting.
|
|
261
|
-
*
|
|
262
|
-
* @param name - The option name to look up.
|
|
263
|
-
*/
|
|
264
170
|
getRawOption(name) {
|
|
265
171
|
return (this.focusedOptions.find((option) => option.name === name) ?? null);
|
|
266
172
|
}
|
|
267
|
-
/**
|
|
268
|
-
* Extracts a strongly typed option, ensuring it exists and matches the expected type.
|
|
269
|
-
*/
|
|
270
173
|
extractOption(name, type, required) {
|
|
271
174
|
const option = this.focusedOptions.find((candidate) => candidate.name === name);
|
|
272
175
|
if (!option) {
|
|
@@ -280,27 +183,15 @@ export class CommandInteractionOptionResolver {
|
|
|
280
183
|
}
|
|
281
184
|
return option;
|
|
282
185
|
}
|
|
283
|
-
/**
|
|
284
|
-
* Resolves an attachment by identifier from the interaction's resolved payloads.
|
|
285
|
-
*/
|
|
286
186
|
resolveAttachment(id) {
|
|
287
187
|
return this.getResolvedRecord(this.resolved?.attachments, id);
|
|
288
188
|
}
|
|
289
|
-
/**
|
|
290
|
-
* Resolves a channel by identifier from the interaction's resolved payloads.
|
|
291
|
-
*/
|
|
292
189
|
resolveChannel(id) {
|
|
293
190
|
return this.getResolvedRecord(this.resolved?.channels, id);
|
|
294
191
|
}
|
|
295
|
-
/**
|
|
296
|
-
* Resolves a role by identifier from the interaction's resolved payloads.
|
|
297
|
-
*/
|
|
298
192
|
resolveRole(id) {
|
|
299
193
|
return this.getResolvedRecord(this.resolved?.roles, id);
|
|
300
194
|
}
|
|
301
|
-
/**
|
|
302
|
-
* Resolves a user and optional member by identifier from the interaction's resolved payloads.
|
|
303
|
-
*/
|
|
304
195
|
resolveUser(id) {
|
|
305
196
|
const user = this.getResolvedRecord(this.resolved?.users, id);
|
|
306
197
|
if (!user) {
|
|
@@ -309,29 +200,16 @@ export class CommandInteractionOptionResolver {
|
|
|
309
200
|
const member = this.getResolvedRecord(this.resolved?.members, id);
|
|
310
201
|
return { user, member: member ?? undefined };
|
|
311
202
|
}
|
|
312
|
-
/**
|
|
313
|
-
* Retrieves a record from a resolved payload map by identifier.
|
|
314
|
-
*/
|
|
315
203
|
getResolvedRecord(records, id) {
|
|
316
204
|
return records?.[id];
|
|
317
205
|
}
|
|
318
206
|
}
|
|
319
207
|
export const CommandInteraction = {};
|
|
320
|
-
/**
|
|
321
|
-
* Wraps a raw application command interaction with helper methods and option resolvers.
|
|
322
|
-
*
|
|
323
|
-
* @param interaction - The raw interaction payload from Discord.
|
|
324
|
-
* @param helpers - Optional helper methods for state management and logging.
|
|
325
|
-
* @returns A helper-augmented interaction object.
|
|
326
|
-
*/
|
|
327
208
|
export function createCommandInteraction(interaction, helpers) {
|
|
328
209
|
const options = new CommandInteractionOptionResolver(interaction.data.options, interaction.data.resolved);
|
|
329
210
|
let capturedResponse = null;
|
|
330
211
|
let isDeferred = false;
|
|
331
212
|
let hasResponded = false;
|
|
332
|
-
/**
|
|
333
|
-
* Stores the most recent response helper payload for later retrieval.
|
|
334
|
-
*/
|
|
335
213
|
const captureResponse = (response) => {
|
|
336
214
|
capturedResponse = response;
|
|
337
215
|
return response;
|
|
@@ -352,9 +230,6 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
352
230
|
}
|
|
353
231
|
return captureResponse({ type });
|
|
354
232
|
}
|
|
355
|
-
/**
|
|
356
|
-
* Creates a deferred response while normalising any helper flag values.
|
|
357
|
-
*/
|
|
358
233
|
const createDeferredResponse = (data) => {
|
|
359
234
|
if (!data) {
|
|
360
235
|
return captureResponse({
|
|
@@ -377,70 +252,58 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
377
252
|
return capturedResponse;
|
|
378
253
|
},
|
|
379
254
|
reply(data) {
|
|
380
|
-
|
|
381
|
-
if (!this.canRespond?.(this.id)) {
|
|
255
|
+
if (this.canRespond && !this.canRespond(this.id)) {
|
|
382
256
|
throw new Error('Interaction cannot respond: already responded or expired');
|
|
383
257
|
}
|
|
384
258
|
const response = createMessageResponse(InteractionResponseType.ChannelMessageWithSource, data);
|
|
385
|
-
// Track response
|
|
386
259
|
this.trackResponse?.(this.id, this.token, 'responded');
|
|
387
260
|
hasResponded = true;
|
|
388
|
-
// Notify acknowledgment
|
|
389
261
|
this.onAck?.(response);
|
|
390
262
|
return response;
|
|
391
263
|
},
|
|
392
264
|
async followUp(data) {
|
|
393
|
-
const
|
|
265
|
+
const normalisedData = normaliseInteractionMessageData(data);
|
|
266
|
+
if (!normalisedData) {
|
|
267
|
+
throw new Error('[MiniInteraction] followUp requires data');
|
|
268
|
+
}
|
|
269
|
+
const response = {
|
|
270
|
+
type: InteractionResponseType.ChannelMessageWithSource,
|
|
271
|
+
data: normalisedData,
|
|
272
|
+
};
|
|
394
273
|
if (this.sendFollowUp) {
|
|
395
|
-
// Empty string for messageId means a new follow-up (POST)
|
|
396
274
|
await this.sendFollowUp(this.token, response, '');
|
|
397
275
|
}
|
|
398
|
-
return response;
|
|
399
276
|
},
|
|
400
277
|
edit(data) {
|
|
401
278
|
return createMessageResponse(InteractionResponseType.UpdateMessage, data);
|
|
402
279
|
},
|
|
403
280
|
async editReply(data) {
|
|
404
|
-
|
|
405
|
-
if (!this.canRespond?.(this.id)) {
|
|
281
|
+
if (this.canRespond && !this.canRespond(this.id)) {
|
|
406
282
|
throw new Error('Interaction cannot edit reply: expired');
|
|
407
283
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
const interactionAny = interaction;
|
|
412
|
-
const isComponent = interactionAny.type === InteractionType.MessageComponent;
|
|
413
|
-
let response;
|
|
414
|
-
if (isComponent) {
|
|
415
|
-
response = createMessageResponse(InteractionResponseType.UpdateMessage, data);
|
|
416
|
-
}
|
|
417
|
-
else {
|
|
418
|
-
response = createMessageResponse(InteractionResponseType.ChannelMessageWithSource, data);
|
|
284
|
+
const normalisedData = normaliseInteractionMessageData(data);
|
|
285
|
+
if (!normalisedData) {
|
|
286
|
+
throw new Error('[MiniInteraction] editReply requires data');
|
|
419
287
|
}
|
|
420
|
-
|
|
421
|
-
|
|
288
|
+
const response = {
|
|
289
|
+
type: InteractionResponseType.ChannelMessageWithSource,
|
|
290
|
+
data: normalisedData,
|
|
291
|
+
};
|
|
292
|
+
if (this.sendFollowUp) {
|
|
422
293
|
await this.sendFollowUp(this.token, response, '@original');
|
|
423
|
-
// If we already sent an ACK (like a DEFERRED_CHANNEL_MESSAGE_WITH_SOURCE),
|
|
424
|
-
// we return the original captured response to avoid sending type 4/7 back to the initial POST.
|
|
425
|
-
return capturedResponse;
|
|
426
294
|
}
|
|
427
|
-
// Track response
|
|
428
295
|
this.trackResponse?.(this.id, this.token, 'responded');
|
|
429
296
|
hasResponded = true;
|
|
430
|
-
return response;
|
|
431
297
|
},
|
|
432
298
|
deferReply(options) {
|
|
433
|
-
|
|
434
|
-
if (!this.canRespond?.(this.id)) {
|
|
299
|
+
if (this.canRespond && !this.canRespond(this.id)) {
|
|
435
300
|
throw new Error('Interaction cannot defer: already responded or expired');
|
|
436
301
|
}
|
|
437
302
|
const response = createDeferredResponse(options?.flags !== undefined
|
|
438
303
|
? { flags: options.flags }
|
|
439
304
|
: undefined);
|
|
440
|
-
// Track deferred state
|
|
441
305
|
this.trackResponse?.(this.id, this.token, 'deferred');
|
|
442
306
|
isDeferred = true;
|
|
443
|
-
// Notify acknowledgment
|
|
444
307
|
this.onAck?.(response);
|
|
445
308
|
return response;
|
|
446
309
|
},
|
|
@@ -455,17 +318,9 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
455
318
|
data: resolvedData,
|
|
456
319
|
});
|
|
457
320
|
},
|
|
458
|
-
/**
|
|
459
|
-
* Creates a delayed response wrapper that automatically defers if the operation takes too long.
|
|
460
|
-
* Use this for operations that might exceed Discord's 3-second limit.
|
|
461
|
-
*
|
|
462
|
-
* @param operation - The async operation to perform
|
|
463
|
-
* @param deferOptions - Options for automatic deferral
|
|
464
|
-
*/
|
|
465
321
|
async withTimeoutProtection(operation, deferOptions) {
|
|
466
322
|
const startTime = Date.now();
|
|
467
323
|
let deferred = false;
|
|
468
|
-
// Set up a timer to auto-defer after 2.5 seconds
|
|
469
324
|
const deferTimer = setTimeout(async () => {
|
|
470
325
|
if (!deferred) {
|
|
471
326
|
console.warn("[MiniInteraction] Auto-deferring interaction due to slow operation. " +
|
|
@@ -489,7 +344,6 @@ export function createCommandInteraction(interaction, helpers) {
|
|
|
489
344
|
throw error;
|
|
490
345
|
}
|
|
491
346
|
},
|
|
492
|
-
// Helper methods for state management
|
|
493
347
|
canRespond: helpers?.canRespond,
|
|
494
348
|
trackResponse: helpers?.trackResponse,
|
|
495
349
|
onAck: helpers?.onAck,
|
package/package.json
CHANGED