api-docs!: Modal Selects (#4467)

* api-docs!: Modal Selects

* Fix transformer to handle the new response types

* Remove `Component` for consistency

Other interaction response types do not have `Component` in their names, so neither should the TextDisplay and Label interaction response types.

* Fix type errors in component transformers

---------

Co-authored-by: Awesome Stickz <awesome@stickz.dev>
This commit is contained in:
Fleny
2025-10-27 19:32:00 +01:00
committed by GitHub
co-authored by Awesome Stickz
parent 33af3d41c4
commit bd4e6f148c
3 changed files with 186 additions and 28 deletions
+13 -5
View File
@@ -4,6 +4,7 @@ import {
type DiscordContainerComponent,
type DiscordFileComponent,
type DiscordLabelComponent,
type DiscordLabelInteractionResponse,
type DiscordMediaGalleryComponent,
type DiscordMediaGalleryItem,
type DiscordMessageComponent,
@@ -13,6 +14,7 @@ import {
type DiscordSeparatorComponent,
type DiscordStringSelectInteractionResponseFromModal,
type DiscordTextDisplayComponent,
type DiscordTextDisplayInteractionResponse,
type DiscordTextInputComponent,
type DiscordTextInputInteractionResponse,
type DiscordThumbnailComponent,
@@ -251,13 +253,16 @@ function transformFileComponent(bot: Bot, payload: DiscordFileComponent): Compon
return file
}
function transformTextDisplayComponent(bot: Bot, payload: DiscordTextDisplayComponent): Component {
function transformTextDisplayComponent(bot: Bot, payload: DiscordTextDisplayComponent | DiscordTextDisplayInteractionResponse): Component {
const props = bot.transformers.desiredProperties.component
const textDisplay = {} as Component
if (props.type && payload.type) textDisplay.type = payload.type
if (props.id && payload.id) textDisplay.id = payload.id
if (props.content && payload.content) textDisplay.content = payload.content
// That that this isn't a response
if ('content' in payload) {
if (props.content && payload.content) textDisplay.content = payload.content
}
return textDisplay
}
@@ -274,14 +279,17 @@ function transformSeparatorComponent(bot: Bot, payload: DiscordSeparatorComponen
return separator
}
function transformLabelComponent(bot: Bot, payload: DiscordLabelComponent): Component {
function transformLabelComponent(bot: Bot, payload: DiscordLabelComponent | DiscordLabelInteractionResponse): Component {
const props = bot.transformers.desiredProperties.component
const label = {} as Component
if (props.type && payload.type) label.type = payload.type
if (props.id && payload.id) label.id = payload.id
if (props.label && payload.label) label.label = payload.label
if (props.description && payload.description) label.description = payload.description
// Check that this isn't a response
if ('label' in payload) {
if (props.label && payload.label) label.label = payload.label
if (props.description && payload.description) label.description = payload.description
}
if (props.component && payload.component) label.component = bot.transformers.component(bot, payload.component)
return label
+98 -18
View File
@@ -56,24 +56,17 @@ export type DiscordMessageComponent =
| DiscordFileComponent
| DiscordLabelComponent
export type DiscordMessageComponentResponse =
| DiscordTextInputInteractionResponse
| DiscordRoleSelectInteractionResponse
| DiscordUserSelectInteractionResponse
| DiscordStringSelectInteractionResponse
| DiscordChannelSelectInteractionResponse
| DiscordMentionableSelectInteractionResponse
export type DiscordMessageComponentFromModalInteractionResponse =
| DiscordTextInputInteractionResponse
| DiscordStringSelectInteractionResponseFromModal
| DiscordTextDisplayInteractionResponse
| DiscordLabelInteractionResponse
export type DiscordMessageComponentFromMessageComponentInteractionResponse =
| DiscordRoleSelectInteractionResponse
| DiscordUserSelectInteractionResponse
| DiscordRoleSelectInteractionResponseFromMessageComponent
| DiscordUserSelectInteractionResponseFromMessageComponent
| DiscordStringSelectInteractionResponseFromMessageComponent
| DiscordChannelSelectInteractionResponse
| DiscordMentionableSelectInteractionResponse
| DiscordChannelSelectInteractionResponseFromMessageComponent
| DiscordMentionableSelectInteractionResponseFromMessageComponent
/** https://discord.com/developers/docs/components/reference#anatomy-of-a-component */
export interface DiscordBaseComponent {
@@ -192,7 +185,7 @@ export interface DiscordSelectMenuComponent extends DiscordBaseComponent {
* Whether this component is required to be filled
*
* @remarks
* This value is only valid for string select menus in modals
* This value is only valid for select menus in modals
*
* @default true
*/
@@ -317,7 +310,16 @@ export interface DiscordSelectMenuDefaultValue {
/** https://discord.com/developers/docs/components/reference#user-select-user-select-interaction-response-structure */
export interface DiscordUserSelectInteractionResponse {
component_type: MessageComponentTypes.UserSelect
/**
* @remarks
* This is only returned for interaction responses from modals
*/
type?: MessageComponentTypes.UserSelect
/**
* @remarks
* This is only returned for interaction responses from message interactions
*/
component_type?: MessageComponentTypes.UserSelect
/** 32 bit integer used as an optional identifier for component */
id: number
/** The custom id for the user select */
@@ -328,9 +330,23 @@ export interface DiscordUserSelectInteractionResponse {
values: string[]
}
/** https://discord.com/developers/docs/components/reference#user-select-user-select-interaction-response-structure */
export type DiscordUserSelectInteractionResponseFromModal = Require<Omit<DiscordUserSelectInteractionResponse, 'component_type'>, 'type'>
/** https://discord.com/developers/docs/components/reference#user-select-user-select-interaction-response-structure */
export type DiscordUserSelectInteractionResponseFromMessageComponent = Require<Omit<DiscordUserSelectInteractionResponse, 'type'>, 'component_type'>
/** https://discord.com/developers/docs/components/reference#role-select-role-select-interaction-response-structure */
export interface DiscordRoleSelectInteractionResponse {
component_type: MessageComponentTypes.RoleSelect
/**
* @remarks
* This is only returned for interaction responses from modals
*/
type?: MessageComponentTypes.RoleSelect
/**
* @remarks
* This is only returned for interaction responses from message interactions
*/
component_type?: MessageComponentTypes.RoleSelect
/** 32 bit integer used as an optional identifier for component */
id: number
/** The custom id for the role select */
@@ -341,9 +357,23 @@ export interface DiscordRoleSelectInteractionResponse {
values: string[]
}
/** https://discord.com/developers/docs/components/reference#role-select-role-select-interaction-response-structure */
export type DiscordRoleSelectInteractionResponseFromModal = Require<Omit<DiscordRoleSelectInteractionResponse, 'component_type'>, 'type'>
/** https://discord.com/developers/docs/components/reference#role-select-role-select-interaction-response-structure */
export type DiscordRoleSelectInteractionResponseFromMessageComponent = Require<Omit<DiscordRoleSelectInteractionResponse, 'type'>, 'component_type'>
/** https://discord.com/developers/docs/components/reference#mentionable-select-mentionable-select-interaction-response-structure */
export interface DiscordMentionableSelectInteractionResponse {
component_type: MessageComponentTypes.MentionableSelect
/**
* @remarks
* This is only returned for interaction responses from modals
*/
type?: MessageComponentTypes.MentionableSelect
/**
* @remarks
* This is only returned for interaction responses from message interactions
*/
component_type?: MessageComponentTypes.MentionableSelect
/** 32 bit integer used as an optional identifier for component */
id: number
/** The custom id for the mentionable select */
@@ -354,9 +384,29 @@ export interface DiscordMentionableSelectInteractionResponse {
values: string[]
}
/** https://discord.com/developers/docs/components/reference#mentionable-select-mentionable-select-interaction-response-structure */
export type DiscordMentionableSelectInteractionResponseFromModal = Require<
Omit<DiscordMentionableSelectInteractionResponse, 'component_type'>,
'type'
>
/** https://discord.com/developers/docs/components/reference#mentionable-select-mentionable-select-interaction-response-structure */
export type DiscordMentionableSelectInteractionResponseFromMessageComponent = Require<
Omit<DiscordMentionableSelectInteractionResponse, 'type'>,
'component_type'
>
/** https://discord.com/developers/docs/components/reference#channel-select-channel-select-interaction-response-structure */
export interface DiscordChannelSelectInteractionResponse {
component_type: MessageComponentTypes.ChannelSelect
/**
* @remarks
* This is only returned for interaction responses from modals
*/
type?: MessageComponentTypes.ChannelSelect
/**
* @remarks
* This is only returned for interaction responses from message interactions
*/
component_type?: MessageComponentTypes.ChannelSelect
/** 32 bit integer used as an optional identifier for component */
id: number
/** The custom id for the channel select */
@@ -367,6 +417,14 @@ export interface DiscordChannelSelectInteractionResponse {
values: string[]
}
/** https://discord.com/developers/docs/components/reference#channel-select-channel-select-interaction-response-structure */
export type DiscordChannelSelectInteractionResponseFromModal = Require<Omit<DiscordChannelSelectInteractionResponse, 'component_type'>, 'type'>
/** https://discord.com/developers/docs/components/reference#channel-select-channel-select-interaction-response-structure */
export type DiscordChannelSelectInteractionResponseFromMessageComponent = Require<
Omit<DiscordChannelSelectInteractionResponse, 'type'>,
'component_type'
>
/** https://discord.com/developers/docs/components/reference#section-section-structure */
export interface DiscordSectionComponent extends DiscordBaseComponent {
type: MessageComponentTypes.Section
@@ -385,6 +443,13 @@ export interface DiscordTextDisplayComponent extends DiscordBaseComponent {
content: string
}
/** https://discord.com/developers/docs/components/reference#text-display-text-display-interaction-response-structure */
export interface DiscordTextDisplayInteractionResponse {
type: MessageComponentTypes.TextDisplay
/** 32 bit integer used as an optional identifier for component */
id: number
}
export interface DiscordThumbnailComponent extends DiscordBaseComponent {
type: MessageComponentTypes.Thumbnail
@@ -485,6 +550,21 @@ export interface DiscordLabelComponent extends DiscordBaseComponent {
component: DiscordTextInputComponent | DiscordSelectMenuComponent
}
/** https://discord.com/developers/docs/components/reference#label-label-interaction-response-structure */
export interface DiscordLabelInteractionResponse {
type: MessageComponentTypes.Label
/** 32 bit integer used as an optional identifier for component */
id: number
/** The component within the label */
component:
| DiscordTextInputInteractionResponse
| DiscordStringSelectInteractionResponseFromModal
| DiscordUserSelectInteractionResponseFromModal
| DiscordRoleSelectInteractionResponseFromModal
| DiscordMentionableSelectInteractionResponseFromModal
| DiscordChannelSelectInteractionResponseFromModal
}
/** https://discord.com/developers/docs/components/reference#unfurled-media-item-structure */
export interface DiscordUnfurledMediaItem {
/** Supports arbitrary urls and attachment://<filename> references */
+75 -5
View File
@@ -198,7 +198,23 @@ export interface UserSelectComponent extends BaseComponent {
minValues?: number
/** The maximum number of items that can be selected. Default 1. Max 25. */
maxValues?: number
/** Whether or not this select is disabled */
/**
* 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
}
@@ -227,7 +243,23 @@ export interface RoleSelectComponent extends BaseComponent {
minValues?: number
/** The maximum number of items that can be selected. Default 1. Max 25. */
maxValues?: number
/** Whether or not this select is disabled */
/**
* 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
}
@@ -248,7 +280,23 @@ export interface MentionableSelectComponent extends BaseComponent {
minValues?: number
/** The maximum number of items that can be selected. Default 1. Max 25. */
maxValues?: number
/** Whether or not this select is disabled */
/**
* 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
}
@@ -271,7 +319,23 @@ export interface ChannelSelectComponent extends BaseComponent {
minValues?: number
/** The maximum number of items that can be selected. Default 1. Max 25. */
maxValues?: number
/** Whether or not this select is disabled */
/**
* 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
}
@@ -368,5 +432,11 @@ export interface LabelComponent extends BaseComponent {
*/
description?: string
/** The component within the label */
component: TextInputComponent | StringSelectComponent
component:
| TextInputComponent
| StringSelectComponent
| UserSelectComponent
| RoleSelectComponent
| MentionableSelectComponent
| ChannelSelectComponent
}