diff --git a/packages/bot/src/desiredProperties.ts b/packages/bot/src/desiredProperties.ts index eb1b7904a..ec993fcc8 100644 --- a/packages/bot/src/desiredProperties.ts +++ b/packages/bot/src/desiredProperties.ts @@ -354,6 +354,7 @@ export function createDesiredPropertiesObject; @@ -185,12 +201,6 @@ function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuCompon if (props.placeholder && payload.placeholder) select.placeholder = payload.placeholder; if (props.minValues && payload.min_values) select.minValues = payload.min_values; if (props.maxValues && payload.max_values) select.maxValues = payload.max_values; - if (props.defaultValues && payload.default_values) - select.defaultValues = payload.default_values.map((defaultValue) => ({ - id: bot.transformers.snowflake(defaultValue.id), - type: defaultValue.type, - })); - if (props.channelTypes && payload.channel_types) select.channelTypes = payload.channel_types; if (props.options && payload.options) select.options = payload.options.map((option) => ({ label: option.label, @@ -211,6 +221,118 @@ function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuCompon return select; } +function transformUserSelectMenuComponent(bot: Bot, payload: DiscordUserSelectComponent | DiscordUserSelectInteractionResponseFromModal) { + const props = bot.transformers.desiredProperties.component; + const select = {} as SetupDesiredProps; + + if (props.type && payload.type) select.type = payload.type; + if (props.id && payload.id) select.id = payload.id; + if (props.customId && payload.custom_id) select.customId = payload.custom_id; + + // Check if this is the user select response + if ('values' in payload) { + if (props.values && payload.values) select.values = payload.values; + if (props.resolved && payload.resolved) select.resolved = bot.transformers.interactionDataResolved(bot, payload.resolved); + } else { + if (props.placeholder && payload.placeholder) select.placeholder = payload.placeholder; + if (props.minValues && payload.min_values) select.minValues = payload.min_values; + if (props.maxValues && payload.max_values) select.maxValues = payload.max_values; + if (props.defaultValues && payload.default_values) + select.defaultValues = payload.default_values.map((defaultValue) => ({ + id: bot.transformers.snowflake(defaultValue.id), + type: defaultValue.type, + })); + if (props.disabled && payload.disabled) select.disabled = payload.disabled; + } + + return select; +} + +function transformRoleSelectMenuComponent(bot: Bot, payload: DiscordRoleSelectComponent | DiscordRoleSelectInteractionResponseFromModal) { + const props = bot.transformers.desiredProperties.component; + const select = {} as SetupDesiredProps; + + if (props.type && payload.type) select.type = payload.type; + if (props.id && payload.id) select.id = payload.id; + if (props.customId && payload.custom_id) select.customId = payload.custom_id; + + // Check if this is the role select response + if ('values' in payload) { + if (props.values && payload.values) select.values = payload.values; + if (props.resolved && payload.resolved) select.resolved = bot.transformers.interactionDataResolved(bot, payload.resolved); + } else { + if (props.placeholder && payload.placeholder) select.placeholder = payload.placeholder; + if (props.minValues && payload.min_values) select.minValues = payload.min_values; + if (props.maxValues && payload.max_values) select.maxValues = payload.max_values; + if (props.defaultValues && payload.default_values) + select.defaultValues = payload.default_values.map((defaultValue) => ({ + id: bot.transformers.snowflake(defaultValue.id), + type: defaultValue.type, + })); + if (props.disabled && payload.disabled) select.disabled = payload.disabled; + } + + return select; +} + +function transformMentionableSelectMenuComponent( + bot: Bot, + payload: DiscordMentionableSelectComponent | DiscordMentionableSelectInteractionResponseFromModal, +) { + const props = bot.transformers.desiredProperties.component; + const select = {} as SetupDesiredProps; + + if (props.type && payload.type) select.type = payload.type; + if (props.id && payload.id) select.id = payload.id; + if (props.customId && payload.custom_id) select.customId = payload.custom_id; + + // Check if this is the mentionable select response + if ('values' in payload) { + if (props.values && payload.values) select.values = payload.values; + if (props.resolved && payload.resolved) select.resolved = bot.transformers.interactionDataResolved(bot, payload.resolved); + } else { + if (props.placeholder && payload.placeholder) select.placeholder = payload.placeholder; + if (props.minValues && payload.min_values) select.minValues = payload.min_values; + if (props.maxValues && payload.max_values) select.maxValues = payload.max_values; + if (props.defaultValues && payload.default_values) + select.defaultValues = payload.default_values.map((defaultValue) => ({ + id: bot.transformers.snowflake(defaultValue.id), + type: defaultValue.type, + })); + if (props.disabled && payload.disabled) select.disabled = payload.disabled; + } + + return select; +} + +function transformChannelSelectMenuComponent(bot: Bot, payload: DiscordChannelSelectComponent | DiscordChannelSelectInteractionResponseFromModal) { + const props = bot.transformers.desiredProperties.component; + const select = {} as SetupDesiredProps; + + if (props.type && payload.type) select.type = payload.type; + if (props.id && payload.id) select.id = payload.id; + if (props.customId && payload.custom_id) select.customId = payload.custom_id; + + // Check if this is the channel select response + if ('values' in payload) { + if (props.values && payload.values) select.values = payload.values; + if (props.resolved && payload.resolved) select.resolved = bot.transformers.interactionDataResolved(bot, payload.resolved); + } else { + if (props.placeholder && payload.placeholder) select.placeholder = payload.placeholder; + if (props.minValues && payload.min_values) select.minValues = payload.min_values; + if (props.maxValues && payload.max_values) select.maxValues = payload.max_values; + if (props.defaultValues && payload.default_values) + select.defaultValues = payload.default_values.map((defaultValue) => ({ + id: bot.transformers.snowflake(defaultValue.id), + type: defaultValue.type, + })); + if (props.channelTypes && payload.channel_types) select.channelTypes = payload.channel_types; + if (props.disabled && payload.disabled) select.disabled = payload.disabled; + } + + return select; +} + function transformSectionComponent(bot: Bot, payload: DiscordSectionComponent) { const props = bot.transformers.desiredProperties.component; const section = {} as SetupDesiredProps; @@ -303,9 +425,9 @@ function transformLabelComponent(bot: Bot, payload: DiscordLabelComponent | Disc return label; } -function transformFileUploadComponent(bot: Bot, payload: DiscordFileUploadComponent | DiscordFileUploadInteractionResponse): Component { +function transformFileUploadComponent(bot: Bot, payload: DiscordFileUploadComponent | DiscordFileUploadInteractionResponse) { const props = bot.transformers.desiredProperties.component; - const fileUpload = {} as Component; + const fileUpload = {} as SetupDesiredProps; if (props.type && payload.type) fileUpload.type = payload.type; if (props.id && payload.id) fileUpload.id = payload.id; diff --git a/packages/bot/src/transformers/reverse/component.ts b/packages/bot/src/transformers/reverse/component.ts index a6e88b9c3..4aded23a2 100644 --- a/packages/bot/src/transformers/reverse/component.ts +++ b/packages/bot/src/transformers/reverse/component.ts @@ -2,22 +2,30 @@ import { type ButtonStyles, type DiscordActionRow, type DiscordButtonComponent, + type DiscordChannelSelectComponent, + type DiscordChannelSelectInteractionResponseFromModal, type DiscordContainerComponent, type DiscordFileComponent, type DiscordFileUploadComponent, type DiscordLabelComponent, type DiscordMediaGalleryComponent, type DiscordMediaGalleryItem, + type DiscordMentionableSelectComponent, + type DiscordMentionableSelectInteractionResponseFromModal, type DiscordMessageComponent, type DiscordMessageComponentFromModalInteractionResponse, + type DiscordRoleSelectComponent, + type DiscordRoleSelectInteractionResponseFromModal, type DiscordSectionComponent, - type DiscordSelectMenuComponent, + type DiscordStringSelectComponent, type DiscordStringSelectInteractionResponseFromModal, type DiscordTextDisplayComponent, type DiscordTextInputComponent, type DiscordTextInputInteractionResponse, type DiscordThumbnailComponent, type DiscordUnfurledMediaItem, + type DiscordUserSelectComponent, + type DiscordUserSelectInteractionResponseFromModal, MessageComponentTypes, type TextStyles, } from '@discordeno/types'; @@ -39,11 +47,15 @@ export function transformComponentToDiscordComponent( case MessageComponentTypes.TextInput: return transformInputTextComponent(bot, payload); case MessageComponentTypes.StringSelect: - case MessageComponentTypes.ChannelSelect: - case MessageComponentTypes.RoleSelect: + return transformStringSelectMenuComponent(bot, payload); case MessageComponentTypes.UserSelect: + return transformUserSelectMenuComponent(bot, payload); + case MessageComponentTypes.RoleSelect: + return transformRoleSelectMenuComponent(bot, payload); case MessageComponentTypes.MentionableSelect: - return transformSelectMenuComponent(bot, payload); + return transformMentionableSelectMenuComponent(bot, payload); + case MessageComponentTypes.ChannelSelect: + return transformChannelSelectMenuComponent(bot, payload); case MessageComponentTypes.Section: return transformSectionComponent(bot, payload); case MessageComponentTypes.File: @@ -139,25 +151,23 @@ function transformInputTextComponent(_bot: Bot, payload: Component): DiscordText }; } -function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSelectMenuComponent | DiscordStringSelectInteractionResponseFromModal { +function transformStringSelectMenuComponent( + bot: Bot, + payload: Component, +): DiscordStringSelectComponent | DiscordStringSelectInteractionResponseFromModal { if (payload.values) { return { type: MessageComponentTypes.StringSelect, values: payload.values, custom_id: payload.customId!, id: payload.id!, - }; + } satisfies DiscordStringSelectInteractionResponseFromModal; } return { - type: payload.type as DiscordSelectMenuComponent['type'], + type: MessageComponentTypes.StringSelect, id: payload.id, custom_id: payload.customId!, - channel_types: payload.channelTypes, - default_values: payload.defaultValues?.map((defaultValue) => ({ - id: bot.transformers.reverse.snowflake(defaultValue.id), - type: defaultValue.type, - })), disabled: payload.disabled, max_values: payload.maxValues, min_values: payload.minValues, @@ -173,10 +183,117 @@ function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSele } : undefined, default: option.default, - })), + }))!, placeholder: payload.placeholder, required: payload.required, - }; + } satisfies DiscordStringSelectComponent; +} + +function transformUserSelectMenuComponent(bot: Bot, payload: Component): DiscordUserSelectComponent | DiscordUserSelectInteractionResponseFromModal { + if (payload.values) { + return { + type: MessageComponentTypes.UserSelect, + values: payload.values, + custom_id: payload.customId!, + id: payload.id!, + // TODO: Add resolved reverse transformer + resolved: {}, + } satisfies DiscordUserSelectInteractionResponseFromModal; + } + + return { + type: MessageComponentTypes.UserSelect, + id: payload.id, + custom_id: payload.customId!, + disabled: payload.disabled, + max_values: payload.maxValues, + min_values: payload.minValues, + placeholder: payload.placeholder, + default_values: payload.defaultValues?.map((value) => ({ id: bot.transformers.reverse.snowflake(value.id), type: value.type })), + required: payload.required, + } satisfies DiscordUserSelectComponent; +} + +function transformRoleSelectMenuComponent(bot: Bot, payload: Component): DiscordRoleSelectComponent | DiscordRoleSelectInteractionResponseFromModal { + if (payload.values) { + return { + type: MessageComponentTypes.RoleSelect, + values: payload.values, + custom_id: payload.customId!, + id: payload.id!, + // TODO: Add resolved reverse transformer + resolved: {}, + } satisfies DiscordRoleSelectInteractionResponseFromModal; + } + + return { + type: MessageComponentTypes.RoleSelect, + id: payload.id, + custom_id: payload.customId!, + disabled: payload.disabled, + max_values: payload.maxValues, + min_values: payload.minValues, + placeholder: payload.placeholder, + default_values: payload.defaultValues?.map((value) => ({ id: bot.transformers.reverse.snowflake(value.id), type: value.type })), + required: payload.required, + } satisfies DiscordRoleSelectComponent; +} + +function transformMentionableSelectMenuComponent( + bot: Bot, + payload: Component, +): DiscordMentionableSelectComponent | DiscordMentionableSelectInteractionResponseFromModal { + if (payload.values) { + return { + type: MessageComponentTypes.MentionableSelect, + values: payload.values, + custom_id: payload.customId!, + id: payload.id!, + // TODO: Add resolved reverse transformer + resolved: {}, + } satisfies DiscordMentionableSelectInteractionResponseFromModal; + } + + return { + type: MessageComponentTypes.MentionableSelect, + id: payload.id, + custom_id: payload.customId!, + disabled: payload.disabled, + max_values: payload.maxValues, + min_values: payload.minValues, + placeholder: payload.placeholder, + default_values: payload.defaultValues?.map((value) => ({ id: bot.transformers.reverse.snowflake(value.id), type: value.type })), + required: payload.required, + } satisfies DiscordMentionableSelectComponent; +} + +function transformChannelSelectMenuComponent( + bot: Bot, + payload: Component, +): DiscordChannelSelectComponent | DiscordChannelSelectInteractionResponseFromModal { + if (payload.values) { + return { + type: MessageComponentTypes.ChannelSelect, + values: payload.values, + custom_id: payload.customId!, + id: payload.id!, + // TODO: Add resolved reverse transformer + resolved: {}, + } satisfies DiscordChannelSelectInteractionResponseFromModal; + } + + return { + type: MessageComponentTypes.ChannelSelect, + id: payload.id, + custom_id: payload.customId!, + disabled: payload.disabled, + max_values: payload.maxValues, + min_values: payload.minValues, + default_values: payload.defaultValues?.map((value) => ({ id: bot.transformers.reverse.snowflake(value.id), type: value.type })), + placeholder: payload.placeholder, + required: payload.required, + channel_types: payload.channelTypes, + } satisfies DiscordChannelSelectComponent; } function transformSectionComponent(bot: Bot, payload: Component): DiscordSectionComponent { diff --git a/packages/bot/src/transformers/types.ts b/packages/bot/src/transformers/types.ts index 205d82480..19667ff1d 100644 --- a/packages/bot/src/transformers/types.ts +++ b/packages/bot/src/transformers/types.ts @@ -599,7 +599,7 @@ export interface Component { /** a list of child components */ components?: Component[]; /** List of default values for auto-populated select menu components; number of default values must be in the range defined by min_values and max_values */ - defaultValues?: DiscordComponentDefaultValue[]; + defaultValues?: ComponentDefaultValue[]; /** Identifier for a purchasable SKU, only available when using premium-style buttons */ skuId?: bigint; /** Optional identifier for component */ @@ -632,6 +632,8 @@ export interface Component { component?: Component; /** The text of the selected options */ values?: string[]; + /** Resolved entities from selected options */ + resolved?: InteractionDataResolved; } export interface UnfurledMediaItem { @@ -658,7 +660,7 @@ export interface MediaGalleryItem { spoiler?: boolean; } -export interface DiscordComponentDefaultValue { +export interface ComponentDefaultValue { /** ID of a user, role, or channel */ id: bigint; /** Type of value that id represents. */ diff --git a/packages/types/src/discord/components.ts b/packages/types/src/discord/components.ts index ff5350ebc..a8f97dd64 100644 --- a/packages/types/src/discord/components.ts +++ b/packages/types/src/discord/components.ts @@ -46,7 +46,11 @@ export enum MessageComponentTypes { export type DiscordMessageComponents = DiscordMessageComponent[]; export type DiscordMessageComponent = | DiscordActionRow - | DiscordSelectMenuComponent + | DiscordStringSelectComponent + | DiscordUserSelectComponent + | DiscordRoleSelectComponent + | DiscordMentionableSelectComponent + | DiscordChannelSelectComponent | DiscordButtonComponent | DiscordTextInputComponent | DiscordSectionComponent @@ -62,7 +66,12 @@ export type DiscordMessageComponent = export type DiscordMessageComponentFromModalInteractionResponse = | DiscordTextInputInteractionResponse | DiscordTextDisplayInteractionResponse - | DiscordLabelInteractionResponse; + | DiscordLabelInteractionResponse + | DiscordRoleSelectInteractionResponseFromModal + | DiscordUserSelectInteractionResponseFromModal + | DiscordStringSelectInteractionResponseFromModal + | DiscordChannelSelectInteractionResponseFromModal + | DiscordMentionableSelectInteractionResponseFromModal; export type DiscordMessageComponentFromMessageComponentInteractionResponse = | DiscordRoleSelectInteractionResponseFromMessageComponent @@ -92,7 +101,15 @@ export interface DiscordActionRow extends DiscordBaseComponent { * Using a {@link DiscordTextInputComponent} inside the Action Row is deprecated, * use a {@link DiscordLabelComponent} for modals */ - components: (DiscordButtonComponent | DiscordSelectMenuComponent | DiscordTextInputComponent)[]; + components: ( + | DiscordButtonComponent + | DiscordStringSelectComponent + | DiscordUserSelectComponent + | DiscordRoleSelectComponent + | DiscordMentionableSelectComponent + | DiscordChannelSelectComponent + | DiscordTextInputComponent + )[]; } /** https://docs.discord.com/developers/components/reference#button-button-structure */ @@ -159,25 +176,14 @@ export enum ButtonStyles { Premium, } -/** - * https://docs.discord.com/developers/components/reference#string-select - * https://docs.discord.com/developers/components/reference#user-select - * https://docs.discord.com/developers/components/reference#role-select - * https://docs.discord.com/developers/components/reference#mentionable-select - * https://docs.discord.com/developers/components/reference#channel-select - */ -export interface DiscordSelectMenuComponent extends DiscordBaseComponent { - type: - | MessageComponentTypes.StringSelect - | MessageComponentTypes.UserSelect - | MessageComponentTypes.RoleSelect - | MessageComponentTypes.MentionableSelect - | MessageComponentTypes.ChannelSelect; +/** https://docs.discord.com/developers/components/reference#string-select-string-select-structure */ +export interface DiscordStringSelectComponent extends DiscordBaseComponent { + type: MessageComponentTypes.StringSelect; /** A custom identifier for this component. Maximum 100 characters. */ custom_id: string; - /** Specified choices in a select menu; Maximum of 25 items. */ - options?: DiscordSelectOption[]; + /** The choices! Maximum of 25 items. */ + options: DiscordSelectOption[]; /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ placeholder?: string; /** The minimum number of items that must be selected. Default 1. Between 0-25. */ @@ -188,7 +194,7 @@ export interface DiscordSelectMenuComponent extends DiscordBaseComponent { * Whether this component is required to be filled * * @remarks - * This value is only valid for select menus in modals + * This value is only valid for string select menus in modals * * @default true */ @@ -202,15 +208,6 @@ export interface DiscordSelectMenuComponent extends DiscordBaseComponent { * @default false */ disabled?: boolean; - /** - * List of default values for auto-populated select menu components - * - * @remarks - * The number of default values must be in the range defined by min_values and max_values - */ - default_values?: DiscordSelectMenuDefaultValue[]; - /** List of channel types to include in a channel select menu options list */ - channel_types?: ChannelTypes[]; } /** https://docs.discord.com/developers/components/reference#string-select-select-option-structure */ @@ -303,6 +300,43 @@ export interface DiscordTextInputInteractionResponse { value: string; } +/** https://docs.discord.com/developers/components/reference#user-select-user-select-structure */ +export interface DiscordUserSelectComponent extends DiscordBaseComponent { + type: MessageComponentTypes.UserSelect; + + /** A custom identifier for this component. Maximum 100 characters. */ + custom_id: string; + /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ + placeholder?: string; + /** + * List of default values for auto-populated select menu components + * The number of default values must be in the range defined by minValues and maxValues + */ + default_values?: DiscordSelectMenuDefaultValue[]; + /** The minimum number of items that must be selected. Default 1. Between 0-25. */ + min_values?: number; + /** The maximum number of items that can be selected. Default 1. Max 25. */ + max_values?: number; + /** + * Whether this component is required to be filled + * + * @remarks + * This value is only valid for string select menus in modals + * + * @default true + */ + required?: boolean; + /** + * Whether select menu is disabled + * + * @remarks + * This value cannot be set for select menus in modals + * + * @default false + */ + disabled?: boolean; +} + /** https://docs.discord.com/developers/components/reference#user-select-select-default-value-structure */ export interface DiscordSelectMenuDefaultValue { /** ID of a user, role, or channel */ @@ -338,6 +372,43 @@ export type DiscordUserSelectInteractionResponseFromModal = Require, 'component_type'>; +/** https://docs.discord.com/developers/components/reference#role-select-role-select-structure */ +export interface DiscordRoleSelectComponent extends DiscordBaseComponent { + type: MessageComponentTypes.RoleSelect; + + /** A custom identifier for this component. Maximum 100 characters. */ + custom_id: string; + /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ + placeholder?: string; + /** + * List of default values for auto-populated select menu components + * The number of default values must be in the range defined by minValues and maxValues + */ + default_values?: DiscordSelectMenuDefaultValue[]; + /** The minimum number of items that must be selected. Default 1. Between 0-25. */ + min_values?: number; + /** The maximum number of items that can be selected. Default 1. Max 25. */ + max_values?: number; + /** + * Whether this component is required to be filled + * + * @remarks + * This value is only valid for string select menus in modals + * + * @default true + */ + required?: boolean; + /** + * Whether select menu is disabled + * + * @remarks + * This value cannot be set for select menus in modals + * + * @default false + */ + disabled?: boolean; +} + /** https://docs.discord.com/developers/components/reference#role-select-role-select-interaction-response-structure */ export interface DiscordRoleSelectInteractionResponse { /** @@ -365,6 +436,43 @@ export type DiscordRoleSelectInteractionResponseFromModal = Require, 'component_type'>; +/** https://docs.discord.com/developers/components/reference#mentionable-select-mentionable-select-structure */ +export interface DiscordMentionableSelectComponent extends DiscordBaseComponent { + type: MessageComponentTypes.MentionableSelect; + + /** A custom identifier for this component. Maximum 100 characters. */ + custom_id: string; + /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ + placeholder?: string; + /** + * List of default values for auto-populated select menu components + * The number of default values must be in the range defined by minValues and maxValues + */ + default_values?: DiscordSelectMenuDefaultValue[]; + /** The minimum number of items that must be selected. Default 1. Between 0-25. */ + min_values?: number; + /** The maximum number of items that can be selected. Default 1. Max 25. */ + max_values?: number; + /** + * Whether this component is required to be filled + * + * @remarks + * This value is only valid for string select menus in modals + * + * @default true + */ + required?: boolean; + /** + * Whether select menu is disabled + * + * @remarks + * This value cannot be set for select menus in modals + * + * @default false + */ + disabled?: boolean; +} + /** https://docs.discord.com/developers/components/reference#mentionable-select-mentionable-select-interaction-response-structure */ export interface DiscordMentionableSelectInteractionResponse { /** @@ -398,6 +506,45 @@ export type DiscordMentionableSelectInteractionResponseFromMessageComponent = Re 'component_type' >; +/** https://docs.discord.com/developers/components/reference#channel-select-channel-select-structure */ +export interface DiscordChannelSelectComponent extends DiscordBaseComponent { + type: MessageComponentTypes.ChannelSelect; + + /** A custom identifier for this component. Maximum 100 characters. */ + custom_id: string; + /** List of channel types to include in the options list */ + channel_types?: ChannelTypes[]; + /** A custom placeholder text if nothing is selected. Maximum 150 characters. */ + placeholder?: string; + /** + * List of default values for auto-populated select menu components + * The number of default values must be in the range defined by minValues and maxValues + */ + default_values?: DiscordSelectMenuDefaultValue[]; + /** The minimum number of items that must be selected. Default 1. Between 0-25. */ + min_values?: number; + /** The maximum number of items that can be selected. Default 1. Max 25. */ + max_values?: number; + /** + * Whether this component is required to be filled + * + * @remarks + * This value is only valid for string select menus in modals + * + * @default true + */ + required?: boolean; + /** + * Whether select menu is disabled + * + * @remarks + * This value cannot be set for select menus in modals + * + * @default false + */ + disabled?: boolean; +} + /** https://docs.discord.com/developers/components/reference#channel-select-channel-select-interaction-response-structure */ export interface DiscordChannelSelectInteractionResponse { /** @@ -550,7 +697,14 @@ export interface DiscordLabelComponent extends DiscordBaseComponent { */ description?: string; /** The component within the label */ - component: DiscordTextInputComponent | DiscordSelectMenuComponent | DiscordFileUploadComponent; + component: + | DiscordTextInputComponent + | DiscordStringSelectComponent + | DiscordUserSelectComponent + | DiscordRoleSelectComponent + | DiscordMentionableSelectComponent + | DiscordChannelSelectComponent + | DiscordFileUploadComponent; } /** https://docs.discord.com/developers/components/reference#label-label-interaction-response-structure */ diff --git a/packages/types/src/discord/interactions.ts b/packages/types/src/discord/interactions.ts index 3bcd773fb..d99c57416 100644 --- a/packages/types/src/discord/interactions.ts +++ b/packages/types/src/discord/interactions.ts @@ -171,7 +171,7 @@ export interface DiscordInteractionDataResolved { /** The Ids and Message objects */ messages?: Record>; /** The ids and attachment objects */ - attachments: Record; + attachments?: Record; } /** https://docs.discord.com/developers/interactions/receiving-and-responding#interaction-object-application-command-interaction-data-option-structure */