@minesa-org/mini-interaction 0.0.13 → 0.0.15

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.
@@ -0,0 +1,52 @@
1
+ import { SelectMenuDefaultValueType, type APIUserSelectComponent, type APISelectMenuDefaultValue } from "discord-api-types/v10";
2
+ import type { JSONEncodable } from "./shared.js";
3
+ /** Shape describing initial modal user select menu data accepted by the builder. */
4
+ export type ModalUserSelectMenuBuilderData = {
5
+ customId?: string;
6
+ placeholder?: string;
7
+ minValues?: number;
8
+ maxValues?: number;
9
+ disabled?: boolean;
10
+ required?: boolean;
11
+ defaultValues?: APISelectMenuDefaultValue<SelectMenuDefaultValueType.User>[];
12
+ };
13
+ /** Builder for Discord user select menu components in modals. */
14
+ export declare class ModalUserSelectMenuBuilder implements JSONEncodable<APIUserSelectComponent> {
15
+ private data;
16
+ /**
17
+ * Creates a new modal user select menu builder with optional seed data.
18
+ */
19
+ constructor(data?: ModalUserSelectMenuBuilderData);
20
+ /**
21
+ * Sets the unique custom identifier for the select menu interaction.
22
+ */
23
+ setCustomId(customId: string): this;
24
+ /**
25
+ * Sets or clears the placeholder text displayed when no user is selected.
26
+ */
27
+ setPlaceholder(placeholder: string | null | undefined): this;
28
+ /**
29
+ * Sets the minimum number of users that must be selected.
30
+ */
31
+ setMinValues(minValues: number | null | undefined): this;
32
+ /**
33
+ * Sets the maximum number of users that can be selected.
34
+ */
35
+ setMaxValues(maxValues: number | null | undefined): this;
36
+ /**
37
+ * Toggles whether the select menu is disabled.
38
+ */
39
+ setDisabled(disabled: boolean): this;
40
+ /**
41
+ * Marks the select menu as required in the modal.
42
+ */
43
+ setRequired(required: boolean): this;
44
+ /**
45
+ * Replaces the default user selections displayed when the menu renders.
46
+ */
47
+ setDefaultValues(defaultValues: Iterable<APISelectMenuDefaultValue<SelectMenuDefaultValueType.User>>): this;
48
+ /**
49
+ * Serialises the builder into an API compatible user select menu payload.
50
+ */
51
+ toJSON(): APIUserSelectComponent;
52
+ }
@@ -0,0 +1,98 @@
1
+ import { ComponentType, SelectMenuDefaultValueType, } from "discord-api-types/v10";
2
+ /** Builder for Discord user select menu components in modals. */
3
+ export class ModalUserSelectMenuBuilder {
4
+ data;
5
+ /**
6
+ * Creates a new modal user select menu builder with optional seed data.
7
+ */
8
+ constructor(data = {}) {
9
+ this.data = {
10
+ customId: data.customId,
11
+ placeholder: data.placeholder,
12
+ minValues: data.minValues,
13
+ maxValues: data.maxValues,
14
+ disabled: data.disabled,
15
+ required: data.required,
16
+ defaultValues: data.defaultValues
17
+ ? data.defaultValues.map((value) => ({
18
+ ...value,
19
+ type: SelectMenuDefaultValueType.User,
20
+ }))
21
+ : undefined,
22
+ };
23
+ }
24
+ /**
25
+ * Sets the unique custom identifier for the select menu interaction.
26
+ */
27
+ setCustomId(customId) {
28
+ this.data.customId = customId;
29
+ return this;
30
+ }
31
+ /**
32
+ * Sets or clears the placeholder text displayed when no user is selected.
33
+ */
34
+ setPlaceholder(placeholder) {
35
+ this.data.placeholder = placeholder ?? undefined;
36
+ return this;
37
+ }
38
+ /**
39
+ * Sets the minimum number of users that must be selected.
40
+ */
41
+ setMinValues(minValues) {
42
+ this.data.minValues = minValues ?? undefined;
43
+ return this;
44
+ }
45
+ /**
46
+ * Sets the maximum number of users that can be selected.
47
+ */
48
+ setMaxValues(maxValues) {
49
+ this.data.maxValues = maxValues ?? undefined;
50
+ return this;
51
+ }
52
+ /**
53
+ * Toggles whether the select menu is disabled.
54
+ */
55
+ setDisabled(disabled) {
56
+ this.data.disabled = disabled;
57
+ return this;
58
+ }
59
+ /**
60
+ * Marks the select menu as required in the modal.
61
+ */
62
+ setRequired(required) {
63
+ this.data.required = required;
64
+ return this;
65
+ }
66
+ /**
67
+ * Replaces the default user selections displayed when the menu renders.
68
+ */
69
+ setDefaultValues(defaultValues) {
70
+ this.data.defaultValues = Array.from(defaultValues, (value) => ({
71
+ ...value,
72
+ type: SelectMenuDefaultValueType.User,
73
+ }));
74
+ return this;
75
+ }
76
+ /**
77
+ * Serialises the builder into an API compatible user select menu payload.
78
+ */
79
+ toJSON() {
80
+ const { customId } = this.data;
81
+ if (!customId) {
82
+ throw new Error("[ModalUserSelectMenuBuilder] custom id is required.");
83
+ }
84
+ return {
85
+ type: ComponentType.UserSelect,
86
+ custom_id: customId,
87
+ placeholder: this.data.placeholder,
88
+ min_values: this.data.minValues,
89
+ max_values: this.data.maxValues,
90
+ disabled: this.data.disabled,
91
+ required: this.data.required,
92
+ default_values: this.data.defaultValues?.map((value) => ({
93
+ ...value,
94
+ type: SelectMenuDefaultValueType.User,
95
+ })),
96
+ };
97
+ }
98
+ }
@@ -7,7 +7,6 @@ export type RoleSelectMenuBuilderData = {
7
7
  minValues?: number;
8
8
  maxValues?: number;
9
9
  disabled?: boolean;
10
- required?: boolean;
11
10
  defaultValues?: APISelectMenuDefaultValue<SelectMenuDefaultValueType.Role>[];
12
11
  };
13
12
  /** Builder for Discord role select menu components. */
@@ -37,10 +36,6 @@ export declare class RoleSelectMenuBuilder implements JSONEncodable<APIRoleSelec
37
36
  * Toggles whether the select menu is disabled.
38
37
  */
39
38
  setDisabled(disabled: boolean): this;
40
- /**
41
- * Marks the select menu as requiring at least the minimum number of selections.
42
- */
43
- setRequired(required: boolean): this;
44
39
  /**
45
40
  * Replaces the default role selections displayed when the menu renders.
46
41
  */
@@ -12,7 +12,6 @@ export class RoleSelectMenuBuilder {
12
12
  minValues: data.minValues,
13
13
  maxValues: data.maxValues,
14
14
  disabled: data.disabled,
15
- required: data.required,
16
15
  defaultValues: data.defaultValues
17
16
  ? data.defaultValues.map((value) => ({
18
17
  ...value,
@@ -56,13 +55,6 @@ export class RoleSelectMenuBuilder {
56
55
  this.data.disabled = disabled;
57
56
  return this;
58
57
  }
59
- /**
60
- * Marks the select menu as requiring at least the minimum number of selections.
61
- */
62
- setRequired(required) {
63
- this.data.required = required;
64
- return this;
65
- }
66
58
  /**
67
59
  * Replaces the default role selections displayed when the menu renders.
68
60
  */
@@ -88,7 +80,6 @@ export class RoleSelectMenuBuilder {
88
80
  min_values: this.data.minValues,
89
81
  max_values: this.data.maxValues,
90
82
  disabled: this.data.disabled,
91
- required: this.data.required,
92
83
  default_values: this.data.defaultValues?.map((value) => ({
93
84
  ...value,
94
85
  type: SelectMenuDefaultValueType.Role,
@@ -7,7 +7,6 @@ export type StringSelectMenuBuilderData = {
7
7
  minValues?: number;
8
8
  maxValues?: number;
9
9
  disabled?: boolean;
10
- required?: boolean;
11
10
  options?: APISelectMenuOption[];
12
11
  };
13
12
  /** Builder for Discord string select menu components. */
@@ -37,10 +36,6 @@ export declare class StringSelectMenuBuilder implements JSONEncodable<APIStringS
37
36
  * Toggles whether the select menu is disabled.
38
37
  */
39
38
  setDisabled(disabled: boolean): this;
40
- /**
41
- * Marks the select menu options as required.
42
- */
43
- setRequired(required: boolean): this;
44
39
  /**
45
40
  * Appends new option entries to the select menu.
46
41
  */
@@ -12,7 +12,6 @@ export class StringSelectMenuBuilder {
12
12
  minValues: data.minValues,
13
13
  maxValues: data.maxValues,
14
14
  disabled: data.disabled,
15
- required: data.required,
16
15
  options: data.options ? [...data.options] : [],
17
16
  };
18
17
  }
@@ -51,13 +50,6 @@ export class StringSelectMenuBuilder {
51
50
  this.data.disabled = disabled;
52
51
  return this;
53
52
  }
54
- /**
55
- * Marks the select menu options as required.
56
- */
57
- setRequired(required) {
58
- this.data.required = required;
59
- return this;
60
- }
61
53
  /**
62
54
  * Appends new option entries to the select menu.
63
55
  */
@@ -93,7 +85,6 @@ export class StringSelectMenuBuilder {
93
85
  min_values: this.data.minValues,
94
86
  max_values: this.data.maxValues,
95
87
  disabled: this.data.disabled,
96
- required: this.data.required,
97
88
  options: options.map((option) => ({ ...option })),
98
89
  };
99
90
  }
@@ -9,6 +9,16 @@ export { RoleSelectMenuBuilder } from "./RoleSelectMenuBuilder.js";
9
9
  export type { RoleSelectMenuBuilderData } from "./RoleSelectMenuBuilder.js";
10
10
  export { ChannelSelectMenuBuilder } from "./ChannelSelectMenuBuilder.js";
11
11
  export type { ChannelSelectMenuBuilderData } from "./ChannelSelectMenuBuilder.js";
12
+ export { ModalStringSelectMenuBuilder } from "./ModalStringSelectMenuBuilder.js";
13
+ export type { ModalStringSelectMenuBuilderData } from "./ModalStringSelectMenuBuilder.js";
14
+ export { ModalRoleSelectMenuBuilder } from "./ModalRoleSelectMenuBuilder.js";
15
+ export type { ModalRoleSelectMenuBuilderData } from "./ModalRoleSelectMenuBuilder.js";
16
+ export { ModalUserSelectMenuBuilder } from "./ModalUserSelectMenuBuilder.js";
17
+ export type { ModalUserSelectMenuBuilderData } from "./ModalUserSelectMenuBuilder.js";
18
+ export { ModalChannelSelectMenuBuilder } from "./ModalChannelSelectMenuBuilder.js";
19
+ export type { ModalChannelSelectMenuBuilderData } from "./ModalChannelSelectMenuBuilder.js";
20
+ export { ModalMentionableSelectMenuBuilder } from "./ModalMentionableSelectMenuBuilder.js";
21
+ export type { ModalMentionableSelectMenuBuilderData } from "./ModalMentionableSelectMenuBuilder.js";
12
22
  export { ModalBuilder } from "./ModalBuilder.js";
13
23
  export type { ModalBuilderData, ModalComponentLike } from "./ModalBuilder.js";
14
24
  export { TextInputBuilder } from "./TextInputBuilder.js";
@@ -4,6 +4,11 @@ export { ButtonBuilder } from "./ButtonBuilder.js";
4
4
  export { StringSelectMenuBuilder } from "./StringSelectMenuBuilder.js";
5
5
  export { RoleSelectMenuBuilder } from "./RoleSelectMenuBuilder.js";
6
6
  export { ChannelSelectMenuBuilder } from "./ChannelSelectMenuBuilder.js";
7
+ export { ModalStringSelectMenuBuilder } from "./ModalStringSelectMenuBuilder.js";
8
+ export { ModalRoleSelectMenuBuilder } from "./ModalRoleSelectMenuBuilder.js";
9
+ export { ModalUserSelectMenuBuilder } from "./ModalUserSelectMenuBuilder.js";
10
+ export { ModalChannelSelectMenuBuilder } from "./ModalChannelSelectMenuBuilder.js";
11
+ export { ModalMentionableSelectMenuBuilder } from "./ModalMentionableSelectMenuBuilder.js";
7
12
  export { ModalBuilder } from "./ModalBuilder.js";
8
13
  export { TextInputBuilder } from "./TextInputBuilder.js";
9
14
  export { LabelBuilder } from "./LabelBuilder.js";
@@ -201,11 +201,22 @@ export declare class MiniInteraction {
201
201
  private isSupportedModuleFile;
202
202
  /**
203
203
  * Dynamically imports and validates a command module from disk.
204
+ * Supports multiple export patterns:
205
+ * - export default { data, handler }
206
+ * - export const command = { data, handler }
207
+ * - export const ping_command = { data, handler }
208
+ * - export const data = ...; export const handler = ...;
204
209
  */
205
210
  private importCommandModule;
206
211
  /**
207
212
  * Dynamically imports and validates a component module from disk.
208
213
  * Also handles modal components if they're in a "modals" subdirectory.
214
+ * Supports multiple export patterns:
215
+ * - export default { customId, handler }
216
+ * - export const component = { customId, handler }
217
+ * - export const ping_button = { customId, handler }
218
+ * - export const customId = "..."; export const handler = ...;
219
+ * - export const components = [{ customId, handler }, ...]
209
220
  */
210
221
  private importComponentModule;
211
222
  /**
@@ -8,6 +8,7 @@ import { DISCORD_BASE_URL } from "../utils/constants.js";
8
8
  import { createCommandInteraction } from "../utils/CommandInteractionOptions.js";
9
9
  import { createMessageComponentInteraction, } from "../utils/MessageComponentInteraction.js";
10
10
  import { createModalSubmitInteraction, } from "../utils/ModalSubmitInteraction.js";
11
+ import { createUserContextMenuInteraction, createMessageContextMenuInteraction, } from "../utils/ContextMenuInteraction.js";
11
12
  /** File extensions that are treated as loadable modules when auto-loading. */
12
13
  const SUPPORTED_MODULE_EXTENSIONS = new Set([
13
14
  ".js",
@@ -514,15 +515,44 @@ export class MiniInteraction {
514
515
  }
515
516
  /**
516
517
  * Dynamically imports and validates a command module from disk.
518
+ * Supports multiple export patterns:
519
+ * - export default { data, handler }
520
+ * - export const command = { data, handler }
521
+ * - export const ping_command = { data, handler }
522
+ * - export const data = ...; export const handler = ...;
517
523
  */
518
524
  async importCommandModule(absolutePath) {
519
525
  try {
520
526
  const moduleUrl = pathToFileURL(absolutePath).href;
521
527
  const imported = await import(moduleUrl);
522
- const candidate = imported.default ??
528
+ // Try to find a command object from various export patterns
529
+ let candidate = imported.default ??
523
530
  imported.command ??
524
- imported.commandDefinition ??
525
- imported;
531
+ imported.commandDefinition;
532
+ // If not found, look for named exports ending with "_command"
533
+ if (!candidate) {
534
+ for (const [key, value] of Object.entries(imported)) {
535
+ if (key.endsWith("_command") &&
536
+ typeof value === "object" &&
537
+ value !== null) {
538
+ candidate = value;
539
+ break;
540
+ }
541
+ }
542
+ }
543
+ // If still not found, try to construct from separate data/handler exports
544
+ if (!candidate) {
545
+ if (imported.data && imported.handler) {
546
+ candidate = {
547
+ data: imported.data,
548
+ handler: imported.handler,
549
+ };
550
+ }
551
+ else {
552
+ // Last resort: use the entire module
553
+ candidate = imported;
554
+ }
555
+ }
526
556
  if (!candidate || typeof candidate !== "object") {
527
557
  console.warn(`[MiniInteraction] Command module "${absolutePath}" does not export a command object. Skipping.`);
528
558
  return null;
@@ -546,21 +576,55 @@ export class MiniInteraction {
546
576
  /**
547
577
  * Dynamically imports and validates a component module from disk.
548
578
  * Also handles modal components if they're in a "modals" subdirectory.
579
+ * Supports multiple export patterns:
580
+ * - export default { customId, handler }
581
+ * - export const component = { customId, handler }
582
+ * - export const ping_button = { customId, handler }
583
+ * - export const customId = "..."; export const handler = ...;
584
+ * - export const components = [{ customId, handler }, ...]
549
585
  */
550
586
  async importComponentModule(absolutePath) {
551
587
  try {
552
588
  const moduleUrl = pathToFileURL(absolutePath).href;
553
589
  const imported = await import(moduleUrl);
554
- const candidate = imported.default ??
590
+ // Collect all potential component candidates
591
+ const candidates = [];
592
+ // Try standard exports first
593
+ const standardExport = imported.default ??
555
594
  imported.component ??
556
595
  imported.components ??
557
596
  imported.componentDefinition ??
558
597
  imported.modal ??
559
- imported.modals ??
560
- imported;
561
- const candidates = Array.isArray(candidate)
562
- ? candidate
563
- : [candidate];
598
+ imported.modals;
599
+ if (standardExport) {
600
+ if (Array.isArray(standardExport)) {
601
+ candidates.push(...standardExport);
602
+ }
603
+ else {
604
+ candidates.push(standardExport);
605
+ }
606
+ }
607
+ // Look for named exports ending with "_button", "_select", "_modal", etc.
608
+ for (const [key, value] of Object.entries(imported)) {
609
+ if ((key.endsWith("_button") ||
610
+ key.endsWith("_select") ||
611
+ key.endsWith("_modal") ||
612
+ key.endsWith("_component")) &&
613
+ typeof value === "object" &&
614
+ value !== null &&
615
+ !candidates.includes(value)) {
616
+ candidates.push(value);
617
+ }
618
+ }
619
+ // If no candidates found, try to construct from separate customId/handler exports
620
+ if (candidates.length === 0) {
621
+ if (imported.customId && imported.handler) {
622
+ candidates.push({
623
+ customId: imported.customId,
624
+ handler: imported.handler,
625
+ });
626
+ }
627
+ }
564
628
  const components = [];
565
629
  // Check if this file is in a "modals" subdirectory
566
630
  const isModalFile = absolutePath.includes(path.sep + "modals" + path.sep) ||
@@ -842,8 +906,22 @@ export class MiniInteraction {
842
906
  resolvedResponse =
843
907
  response ?? interactionWithHelpers.getResponse();
844
908
  }
909
+ else if (commandInteraction.data.type === ApplicationCommandType.User) {
910
+ // User context menu command
911
+ const interactionWithHelpers = createUserContextMenuInteraction(commandInteraction);
912
+ response = await command.handler(interactionWithHelpers);
913
+ resolvedResponse =
914
+ response ?? interactionWithHelpers.getResponse();
915
+ }
916
+ else if (commandInteraction.data.type === ApplicationCommandType.Message) {
917
+ // Message context menu command
918
+ const interactionWithHelpers = createMessageContextMenuInteraction(commandInteraction);
919
+ response = await command.handler(interactionWithHelpers);
920
+ resolvedResponse =
921
+ response ?? interactionWithHelpers.getResponse();
922
+ }
845
923
  else {
846
- // Context menu commands (User or Message) - pass raw interaction
924
+ // Unknown command type
847
925
  response = await command.handler(commandInteraction);
848
926
  resolvedResponse = response ?? null;
849
927
  }
package/dist/index.d.ts CHANGED
@@ -6,6 +6,7 @@ export { UserCommandBuilder, MessageCommandBuilder, } from "./commands/ContextMe
6
6
  export type { AttachmentOptionBuilder, ChannelOptionBuilder, MentionableOptionBuilder, NumberOptionBuilder, RoleOptionBuilder, StringOptionBuilder, SubcommandBuilder, SubcommandGroupBuilder, UserOptionBuilder, } from "./commands/CommandBuilder.js";
7
7
  export { CommandInteractionOptionResolver, createCommandInteraction, } from "./utils/CommandInteractionOptions.js";
8
8
  export type { CommandInteraction, MentionableOption, ResolvedUserOption, } from "./utils/CommandInteractionOptions.js";
9
+ export type { UserContextMenuInteraction, MessageContextMenuInteraction, } from "./utils/ContextMenuInteraction.js";
9
10
  export type { MiniInteractionFetchHandler, MiniInteractionNodeHandler, MiniInteractionHandlerResult, MiniInteractionRequest, MiniInteractionOptions, } from "./clients/MiniInteraction.js";
10
11
  export type { MiniInteractionCommand, SlashCommandHandler, UserCommandHandler, MessageCommandHandler, CommandHandler, } from "./types/Commands.js";
11
12
  export type { MiniInteractionComponent, MiniInteractionButtonHandler, MiniInteractionStringSelectHandler, MiniInteractionRoleSelectHandler, MiniInteractionUserSelectHandler, MiniInteractionChannelSelectHandler, MiniInteractionMentionableSelectHandler, MiniInteractionComponentHandler, MiniInteractionModal, MiniInteractionModalHandler, MiniInteractionHandler, } from "./clients/MiniInteraction.js";
@@ -1,12 +1,13 @@
1
- import type { APIInteractionResponse, RESTPostAPIChatInputApplicationCommandsJSONBody, RESTPostAPIContextMenuApplicationCommandsJSONBody, APIUserApplicationCommandInteraction, APIMessageApplicationCommandInteraction } from "discord-api-types/v10";
1
+ import type { APIInteractionResponse, RESTPostAPIChatInputApplicationCommandsJSONBody, RESTPostAPIContextMenuApplicationCommandsJSONBody } from "discord-api-types/v10";
2
2
  import type { CommandInteraction } from "../utils/CommandInteractionOptions.js";
3
+ import type { UserContextMenuInteraction, MessageContextMenuInteraction } from "../utils/ContextMenuInteraction.js";
3
4
  import type { MiniInteractionComponent, MiniInteractionModal } from "../clients/MiniInteraction.js";
4
5
  /** Handler signature for slash command executions within MiniInteraction. */
5
6
  export type SlashCommandHandler = (interaction: CommandInteraction) => Promise<APIInteractionResponse | void> | APIInteractionResponse | void;
6
7
  /** Handler signature for user context menu command executions within MiniInteraction. */
7
- export type UserCommandHandler = (interaction: APIUserApplicationCommandInteraction) => Promise<APIInteractionResponse | void> | APIInteractionResponse | void;
8
+ export type UserCommandHandler = (interaction: UserContextMenuInteraction) => Promise<APIInteractionResponse | void> | APIInteractionResponse | void;
8
9
  /** Handler signature for message context menu command executions within MiniInteraction. */
9
- export type MessageCommandHandler = (interaction: APIMessageApplicationCommandInteraction) => Promise<APIInteractionResponse | void> | APIInteractionResponse | void;
10
+ export type MessageCommandHandler = (interaction: MessageContextMenuInteraction) => Promise<APIInteractionResponse | void> | APIInteractionResponse | void;
10
11
  /** Union of all command handler types. */
11
12
  export type CommandHandler = SlashCommandHandler | UserCommandHandler | MessageCommandHandler;
12
13
  /** Structure representing a slash command definition and its runtime handler. */
@@ -0,0 +1,36 @@
1
+ import { type APIInteractionResponse, type APIInteractionResponseChannelMessageWithSource, type APIInteractionResponseDeferredChannelMessageWithSource, type APIMessageApplicationCommandInteraction, type APIModalInteractionResponse, type APIModalInteractionResponseCallbackData, type APIUserApplicationCommandInteraction } from "discord-api-types/v10";
2
+ import { DeferReplyOptions, InteractionMessageData } from "./interactionMessageHelpers.js";
3
+ /**
4
+ * Base helper methods for context menu interactions.
5
+ */
6
+ type ContextMenuInteractionHelpers = {
7
+ getResponse: () => APIInteractionResponse | null;
8
+ reply: (data: InteractionMessageData) => APIInteractionResponseChannelMessageWithSource;
9
+ deferReply: (options?: DeferReplyOptions) => APIInteractionResponseDeferredChannelMessageWithSource;
10
+ showModal: (data: APIModalInteractionResponseCallbackData | {
11
+ toJSON(): APIModalInteractionResponseCallbackData;
12
+ }) => APIModalInteractionResponse;
13
+ };
14
+ /**
15
+ * User context menu interaction with helper methods.
16
+ */
17
+ export type UserContextMenuInteraction = APIUserApplicationCommandInteraction & ContextMenuInteractionHelpers;
18
+ /**
19
+ * Message context menu interaction with helper methods.
20
+ */
21
+ export type MessageContextMenuInteraction = APIMessageApplicationCommandInteraction & ContextMenuInteractionHelpers;
22
+ /**
23
+ * Wraps a raw user context menu interaction with helper methods.
24
+ *
25
+ * @param interaction - The raw user context menu interaction payload from Discord.
26
+ * @returns A helper-augmented interaction object.
27
+ */
28
+ export declare function createUserContextMenuInteraction(interaction: APIUserApplicationCommandInteraction): UserContextMenuInteraction;
29
+ /**
30
+ * Wraps a raw message context menu interaction with helper methods.
31
+ *
32
+ * @param interaction - The raw message context menu interaction payload from Discord.
33
+ * @returns A helper-augmented interaction object.
34
+ */
35
+ export declare function createMessageContextMenuInteraction(interaction: APIMessageApplicationCommandInteraction): MessageContextMenuInteraction;
36
+ export {};
@@ -0,0 +1,94 @@
1
+ import { InteractionResponseType, } from "discord-api-types/v10";
2
+ import { normaliseInteractionMessageData, normaliseMessageFlags, } from "./interactionMessageHelpers.js";
3
+ /**
4
+ * Wraps a raw user context menu interaction with helper methods.
5
+ *
6
+ * @param interaction - The raw user context menu interaction payload from Discord.
7
+ * @returns A helper-augmented interaction object.
8
+ */
9
+ export function createUserContextMenuInteraction(interaction) {
10
+ let capturedResponse = null;
11
+ const reply = (data) => {
12
+ const normalised = normaliseInteractionMessageData(data);
13
+ if (!normalised) {
14
+ throw new Error("[MiniInteraction] Channel message responses require data to be provided.");
15
+ }
16
+ const response = {
17
+ type: InteractionResponseType.ChannelMessageWithSource,
18
+ data: normalised,
19
+ };
20
+ capturedResponse = response;
21
+ return response;
22
+ };
23
+ const deferReply = (options = {}) => {
24
+ const flags = normaliseMessageFlags(options.flags);
25
+ const response = {
26
+ type: InteractionResponseType.DeferredChannelMessageWithSource,
27
+ data: flags ? { flags } : undefined,
28
+ };
29
+ capturedResponse = response;
30
+ return response;
31
+ };
32
+ const showModal = (data) => {
33
+ const modalData = typeof data === "object" && "toJSON" in data ? data.toJSON() : data;
34
+ const response = {
35
+ type: InteractionResponseType.Modal,
36
+ data: modalData,
37
+ };
38
+ capturedResponse = response;
39
+ return response;
40
+ };
41
+ const getResponse = () => capturedResponse;
42
+ return Object.assign(interaction, {
43
+ reply,
44
+ deferReply,
45
+ showModal,
46
+ getResponse,
47
+ });
48
+ }
49
+ /**
50
+ * Wraps a raw message context menu interaction with helper methods.
51
+ *
52
+ * @param interaction - The raw message context menu interaction payload from Discord.
53
+ * @returns A helper-augmented interaction object.
54
+ */
55
+ export function createMessageContextMenuInteraction(interaction) {
56
+ let capturedResponse = null;
57
+ const reply = (data) => {
58
+ const normalised = normaliseInteractionMessageData(data);
59
+ if (!normalised) {
60
+ throw new Error("[MiniInteraction] Channel message responses require data to be provided.");
61
+ }
62
+ const response = {
63
+ type: InteractionResponseType.ChannelMessageWithSource,
64
+ data: normalised,
65
+ };
66
+ capturedResponse = response;
67
+ return response;
68
+ };
69
+ const deferReply = (options = {}) => {
70
+ const flags = normaliseMessageFlags(options.flags);
71
+ const response = {
72
+ type: InteractionResponseType.DeferredChannelMessageWithSource,
73
+ data: flags ? { flags } : undefined,
74
+ };
75
+ capturedResponse = response;
76
+ return response;
77
+ };
78
+ const showModal = (data) => {
79
+ const modalData = typeof data === "object" && "toJSON" in data ? data.toJSON() : data;
80
+ const response = {
81
+ type: InteractionResponseType.Modal,
82
+ data: modalData,
83
+ };
84
+ capturedResponse = response;
85
+ return response;
86
+ };
87
+ const getResponse = () => capturedResponse;
88
+ return Object.assign(interaction, {
89
+ reply,
90
+ deferReply,
91
+ showModal,
92
+ getResponse,
93
+ });
94
+ }