feat(types,bot)!: Components V2 (#4080)

* UI

* change component names to match Discord's names

* add divider prop to separator component

* rename thumbnail component image property to media

* Rename MessageFlags.IsUiKit to IsComponentsV2

* Rename FileDisplay component to File component

* Added container component

* add id to container component transformers

* add id to all components

* SectionComponent.accessory now accepts ButtonComponent as well

* Update description for FileComponent.file

* fix bad merge

* Change Component.accessory to ButtonComponent | ThumbnailComponent

* Add section to reverse, fix Component#accessory

* remove type cast on section transform

* Add docs link for CreateGuildChannel

Co-authored-by: LTS (Link) <lts20050703@gmail.com>

* Update comments & split components

* fix type errors

* Really fix CI

* transform UnfurledMediaItem

* Apply suggestions from code review

Co-authored-by: LTS (Link) <lts20050703@gmail.com>

* change DiscordInputTextComponent to DiscordTextInputComponent

* fix order in Transformers.customizers

* Fix missing transformers

* update action row components type

---------

Co-authored-by: Awesome Stickz <awesome@stickz.dev>
Co-authored-by: LTS (Link) <lts20050703@gmail.com>
This commit is contained in:
Fleny
2025-04-26 08:35:06 +02:00
committed by GitHub
co-authored by LTS Awesome Stickz
parent 24703f13dd
commit 3d90d816e7
10 changed files with 746 additions and 226 deletions
+20
View File
@@ -43,6 +43,7 @@ import type {
DiscordInviteStageInstance, DiscordInviteStageInstance,
DiscordLobby, DiscordLobby,
DiscordLobbyMember, DiscordLobbyMember,
DiscordMediaGalleryItem,
DiscordMember, DiscordMember,
DiscordMessage, DiscordMessage,
DiscordMessageCall, DiscordMessageCall,
@@ -65,6 +66,7 @@ import type {
DiscordTemplate, DiscordTemplate,
DiscordThreadMember, DiscordThreadMember,
DiscordThreadMemberGuildCreate, DiscordThreadMemberGuildCreate,
DiscordUnfurledMediaItem,
DiscordUser, DiscordUser,
DiscordVoiceRegion, DiscordVoiceRegion,
DiscordVoiceState, DiscordVoiceState,
@@ -120,6 +122,7 @@ import {
type InviteStageInstance, type InviteStageInstance,
type Lobby, type Lobby,
type LobbyMember, type LobbyMember,
type MediaGalleryItem,
type Member, type Member,
type Message, type Message,
type MessageCall, type MessageCall,
@@ -141,6 +144,7 @@ import {
type Template, type Template,
type ThreadMember, type ThreadMember,
type ThreadMemberGuildCreate, type ThreadMemberGuildCreate,
type UnfurledMediaItem,
type User, type User,
type VoiceRegion, type VoiceRegion,
type VoiceState, type VoiceState,
@@ -190,6 +194,7 @@ import {
transformInviteStageInstance, transformInviteStageInstance,
transformLobby, transformLobby,
transformLobbyMember, transformLobbyMember,
transformMediaGalleryItem,
transformMember, transformMember,
transformMemberToDiscordMember, transformMemberToDiscordMember,
transformMessage, transformMessage,
@@ -213,6 +218,7 @@ import {
transformTemplate, transformTemplate,
transformThreadMember, transformThreadMember,
transformThreadMemberGuildCreate, transformThreadMemberGuildCreate,
transformUnfurledMediaItem,
transformUser, transformUser,
transformUserToDiscordUser, transformUserToDiscordUser,
transformVoiceRegion, transformVoiceRegion,
@@ -225,6 +231,8 @@ import {
import { import {
transformAllowedMentionsToDiscordAllowedMentions, transformAllowedMentionsToDiscordAllowedMentions,
transformCreateApplicationCommandToDiscordCreateApplicationCommand, transformCreateApplicationCommandToDiscordCreateApplicationCommand,
transformMediaGalleryItemToDiscordMediaGalleryItem,
transformUnfurledMediaItemToDiscordUnfurledMediaItem,
} from './transformers/reverse/index.js' } from './transformers/reverse/index.js'
import { bigintToSnowflake, snowflakeToBigint } from './utils.js' import { bigintToSnowflake, snowflakeToBigint } from './utils.js'
@@ -339,6 +347,7 @@ export type Transformers<TProps extends TransformersDesiredProperties, TBehavior
) => any ) => any
lobby: (bot: Bot<TProps, TBehavior>, payload: DiscordLobby, lobby: SetupDesiredProps<Lobby, TProps, TBehavior>) => any lobby: (bot: Bot<TProps, TBehavior>, payload: DiscordLobby, lobby: SetupDesiredProps<Lobby, TProps, TBehavior>) => any
lobbyMember: (bot: Bot<TProps, TBehavior>, payload: DiscordLobbyMember, lobbyMember: SetupDesiredProps<LobbyMember, TProps, TBehavior>) => any lobbyMember: (bot: Bot<TProps, TBehavior>, payload: DiscordLobbyMember, lobbyMember: SetupDesiredProps<LobbyMember, TProps, TBehavior>) => any
mediaGalleryItem: (bot: Bot<TProps, TBehavior>, payload: DiscordMediaGalleryItem, item: MediaGalleryItem) => any
member: (bot: Bot<TProps, TBehavior>, payload: DiscordMember, member: SetupDesiredProps<Member, TProps, TBehavior>) => any member: (bot: Bot<TProps, TBehavior>, payload: DiscordMember, member: SetupDesiredProps<Member, TProps, TBehavior>) => any
message: (bot: Bot<TProps, TBehavior>, payload: DiscordMessage, message: SetupDesiredProps<Message, TProps, TBehavior>) => any message: (bot: Bot<TProps, TBehavior>, payload: DiscordMessage, message: SetupDesiredProps<Message, TProps, TBehavior>) => any
messageCall: (bot: Bot<TProps, TBehavior>, payload: DiscordMessageCall, call: SetupDesiredProps<MessageCall, TProps, TBehavior>) => any messageCall: (bot: Bot<TProps, TBehavior>, payload: DiscordMessageCall, call: SetupDesiredProps<MessageCall, TProps, TBehavior>) => any
@@ -388,6 +397,7 @@ export type Transformers<TProps extends TransformersDesiredProperties, TBehavior
payload: DiscordThreadMemberGuildCreate, payload: DiscordThreadMemberGuildCreate,
threadMemberGuildCreate: ThreadMemberGuildCreate, threadMemberGuildCreate: ThreadMemberGuildCreate,
) => any ) => any
unfurledMediaItem: (bot: Bot<TProps, TBehavior>, payload: DiscordUnfurledMediaItem, unfurledMediaItem: UnfurledMediaItem) => any
user: (bot: Bot<TProps, TBehavior>, payload: DiscordUser, user: SetupDesiredProps<User, TProps, TBehavior>) => any user: (bot: Bot<TProps, TBehavior>, payload: DiscordUser, user: SetupDesiredProps<User, TProps, TBehavior>) => any
voiceRegion: (bot: Bot<TProps, TBehavior>, payload: DiscordVoiceRegion, voiceRegion: VoiceRegion) => any voiceRegion: (bot: Bot<TProps, TBehavior>, payload: DiscordVoiceRegion, voiceRegion: VoiceRegion) => any
voiceState: (bot: Bot<TProps, TBehavior>, payload: DiscordVoiceState, voiceState: SetupDesiredProps<VoiceState, TProps, TBehavior>) => any voiceState: (bot: Bot<TProps, TBehavior>, payload: DiscordVoiceState, voiceState: SetupDesiredProps<VoiceState, TProps, TBehavior>) => any
@@ -408,9 +418,11 @@ export type Transformers<TProps extends TransformersDesiredProperties, TBehavior
component: (bot: Bot<TProps, TBehavior>, payload: Component) => DiscordMessageComponent component: (bot: Bot<TProps, TBehavior>, payload: Component) => DiscordMessageComponent
createApplicationCommand: (bot: Bot<TProps, TBehavior>, payload: CreateApplicationCommand) => DiscordCreateApplicationCommand createApplicationCommand: (bot: Bot<TProps, TBehavior>, payload: CreateApplicationCommand) => DiscordCreateApplicationCommand
embed: (bot: Bot<TProps, TBehavior>, payload: Embed) => DiscordEmbed embed: (bot: Bot<TProps, TBehavior>, payload: Embed) => DiscordEmbed
mediaGalleryItem: (bot: Bot<TProps, TBehavior>, payload: MediaGalleryItem) => DiscordMediaGalleryItem
member: (bot: Bot<TProps, TBehavior>, payload: SetupDesiredProps<Member, TProps, TBehavior>) => DiscordMember member: (bot: Bot<TProps, TBehavior>, payload: SetupDesiredProps<Member, TProps, TBehavior>) => DiscordMember
snowflake: (snowflake: BigString) => string snowflake: (snowflake: BigString) => string
team: (bot: Bot<TProps, TBehavior>, payload: Team) => DiscordTeam team: (bot: Bot<TProps, TBehavior>, payload: Team) => DiscordTeam
unfurledMediaItem: (bot: Bot<TProps, TBehavior>, payload: UnfurledMediaItem) => DiscordUnfurledMediaItem
user: (bot: Bot<TProps, TBehavior>, payload: SetupDesiredProps<User, TProps, TBehavior>) => DiscordUser user: (bot: Bot<TProps, TBehavior>, payload: SetupDesiredProps<User, TProps, TBehavior>) => DiscordUser
} }
activity: (bot: Bot<TProps, TBehavior>, payload: DiscordActivity) => Activity activity: (bot: Bot<TProps, TBehavior>, payload: DiscordActivity) => Activity
@@ -480,6 +492,7 @@ export type Transformers<TProps extends TransformersDesiredProperties, TBehavior
) => SetupDesiredProps<InviteStageInstance, TProps, TBehavior> ) => SetupDesiredProps<InviteStageInstance, TProps, TBehavior>
lobby: (bot: Bot<TProps, TBehavior>, payload: DiscordLobby) => SetupDesiredProps<Lobby, TProps, TBehavior> lobby: (bot: Bot<TProps, TBehavior>, payload: DiscordLobby) => SetupDesiredProps<Lobby, TProps, TBehavior>
lobbyMember: (bot: Bot<TProps, TBehavior>, payload: DiscordLobbyMember) => SetupDesiredProps<LobbyMember, TProps, TBehavior> lobbyMember: (bot: Bot<TProps, TBehavior>, payload: DiscordLobbyMember) => SetupDesiredProps<LobbyMember, TProps, TBehavior>
mediaGalleryItem: (bot: Bot<TProps, TBehavior>, payload: DiscordMediaGalleryItem) => MediaGalleryItem
member: ( member: (
bot: Bot<TProps, TBehavior>, bot: Bot<TProps, TBehavior>,
payload: DiscordMember, payload: DiscordMember,
@@ -516,6 +529,7 @@ export type Transformers<TProps extends TransformersDesiredProperties, TBehavior
template: (bot: Bot<TProps, TBehavior>, payload: DiscordTemplate) => Template template: (bot: Bot<TProps, TBehavior>, payload: DiscordTemplate) => Template
threadMember: (bot: Bot<TProps, TBehavior>, payload: DiscordThreadMember) => ThreadMember threadMember: (bot: Bot<TProps, TBehavior>, payload: DiscordThreadMember) => ThreadMember
threadMemberGuildCreate: (bot: Bot<TProps, TBehavior>, payload: DiscordThreadMemberGuildCreate) => ThreadMemberGuildCreate threadMemberGuildCreate: (bot: Bot<TProps, TBehavior>, payload: DiscordThreadMemberGuildCreate) => ThreadMemberGuildCreate
unfurledMediaItem: (bot: Bot<TProps, TBehavior>, payload: DiscordUnfurledMediaItem) => UnfurledMediaItem
user: (bot: Bot<TProps, TBehavior>, payload: DiscordUser) => SetupDesiredProps<User, TProps, TBehavior> user: (bot: Bot<TProps, TBehavior>, payload: DiscordUser) => SetupDesiredProps<User, TProps, TBehavior>
voiceRegion: (bot: Bot<TProps, TBehavior>, payload: DiscordVoiceRegion) => VoiceRegion voiceRegion: (bot: Bot<TProps, TBehavior>, payload: DiscordVoiceRegion) => VoiceRegion
voiceState: ( voiceState: (
@@ -572,6 +586,7 @@ export function createTransformers<TProps extends TransformersDesiredProperties,
inviteStageInstance: options.customizers?.inviteStageInstance ?? defaultCustomizer, inviteStageInstance: options.customizers?.inviteStageInstance ?? defaultCustomizer,
lobby: options.customizers?.lobby ?? defaultCustomizer, lobby: options.customizers?.lobby ?? defaultCustomizer,
lobbyMember: options.customizers?.lobbyMember ?? defaultCustomizer, lobbyMember: options.customizers?.lobbyMember ?? defaultCustomizer,
mediaGalleryItem: options.customizers?.mediaGalleryItem ?? defaultCustomizer,
member: options.customizers?.member ?? defaultCustomizer, member: options.customizers?.member ?? defaultCustomizer,
message: options.customizers?.message ?? defaultCustomizer, message: options.customizers?.message ?? defaultCustomizer,
messageCall: options.customizers?.messageCall ?? defaultCustomizer, messageCall: options.customizers?.messageCall ?? defaultCustomizer,
@@ -593,6 +608,7 @@ export function createTransformers<TProps extends TransformersDesiredProperties,
template: options.customizers?.template ?? defaultCustomizer, template: options.customizers?.template ?? defaultCustomizer,
threadMember: options.customizers?.threadMember ?? defaultCustomizer, threadMember: options.customizers?.threadMember ?? defaultCustomizer,
threadMemberGuildCreate: options.customizers?.threadMemberGuildCreate ?? defaultCustomizer, threadMemberGuildCreate: options.customizers?.threadMemberGuildCreate ?? defaultCustomizer,
unfurledMediaItem: options.customizers?.unfurledMediaItem ?? defaultCustomizer,
user: options.customizers?.user ?? defaultCustomizer, user: options.customizers?.user ?? defaultCustomizer,
voiceRegion: options.customizers?.voiceRegion ?? defaultCustomizer, voiceRegion: options.customizers?.voiceRegion ?? defaultCustomizer,
voiceState: options.customizers?.voiceState ?? defaultCustomizer, voiceState: options.customizers?.voiceState ?? defaultCustomizer,
@@ -614,9 +630,11 @@ export function createTransformers<TProps extends TransformersDesiredProperties,
component: options.reverse?.component ?? transformComponentToDiscordComponent, component: options.reverse?.component ?? transformComponentToDiscordComponent,
createApplicationCommand: options.reverse?.createApplicationCommand ?? transformCreateApplicationCommandToDiscordCreateApplicationCommand, createApplicationCommand: options.reverse?.createApplicationCommand ?? transformCreateApplicationCommandToDiscordCreateApplicationCommand,
embed: options.reverse?.embed ?? transformEmbedToDiscordEmbed, embed: options.reverse?.embed ?? transformEmbedToDiscordEmbed,
mediaGalleryItem: options.reverse?.mediaGalleryItem ?? transformMediaGalleryItemToDiscordMediaGalleryItem,
member: options.reverse?.member ?? transformMemberToDiscordMember, member: options.reverse?.member ?? transformMemberToDiscordMember,
snowflake: options.reverse?.snowflake ?? bigintToSnowflake, snowflake: options.reverse?.snowflake ?? bigintToSnowflake,
team: options.reverse?.team ?? transformTeamToDiscordTeam, team: options.reverse?.team ?? transformTeamToDiscordTeam,
unfurledMediaItem: options.reverse?.unfurledMediaItem ?? transformUnfurledMediaItemToDiscordUnfurledMediaItem,
user: options.reverse?.user ?? transformUserToDiscordUser, user: options.reverse?.user ?? transformUserToDiscordUser,
}, },
activity: options.activity ?? transformActivity, activity: options.activity ?? transformActivity,
@@ -656,6 +674,7 @@ export function createTransformers<TProps extends TransformersDesiredProperties,
inviteStageInstance: options.inviteStageInstance ?? transformInviteStageInstance, inviteStageInstance: options.inviteStageInstance ?? transformInviteStageInstance,
lobby: options.lobby ?? transformLobby, lobby: options.lobby ?? transformLobby,
lobbyMember: options.lobbyMember ?? transformLobbyMember, lobbyMember: options.lobbyMember ?? transformLobbyMember,
mediaGalleryItem: options.mediaGalleryItem ?? transformMediaGalleryItem,
member: options.member ?? transformMember, member: options.member ?? transformMember,
message: options.message ?? transformMessage, message: options.message ?? transformMessage,
messageCall: options.messageCall ?? transformMessageCall, messageCall: options.messageCall ?? transformMessageCall,
@@ -678,6 +697,7 @@ export function createTransformers<TProps extends TransformersDesiredProperties,
template: options.template ?? transformTemplate, template: options.template ?? transformTemplate,
threadMember: options.threadMember ?? transformThreadMember, threadMember: options.threadMember ?? transformThreadMember,
threadMemberGuildCreate: options.threadMemberGuildCreate ?? transformThreadMemberGuildCreate, threadMemberGuildCreate: options.threadMemberGuildCreate ?? transformThreadMemberGuildCreate,
unfurledMediaItem: options.unfurledMediaItem ?? transformUnfurledMediaItem,
user: options.user ?? transformUser, user: options.user ?? transformUser,
voiceRegion: options.voiceRegion ?? transformVoiceRegion, voiceRegion: options.voiceRegion ?? transformVoiceRegion,
voiceState: options.voiceState ?? transformVoiceState, voiceState: options.voiceState ?? transformVoiceState,
+115 -6
View File
@@ -1,12 +1,26 @@
import { import {
type DiscordActionRow, type DiscordActionRow,
type DiscordButtonComponent, type DiscordButtonComponent,
type DiscordInputTextComponent, type DiscordFileComponent,
type DiscordMediaGalleryComponent,
type DiscordMessageComponent, type DiscordMessageComponent,
type DiscordSectionComponent,
type DiscordSelectMenuComponent, type DiscordSelectMenuComponent,
type DiscordSeparatorComponent,
type DiscordTextDisplayComponent,
type DiscordTextInputComponent,
type DiscordThumbnailComponent,
MessageComponentTypes, MessageComponentTypes,
} from '@discordeno/types' } from '@discordeno/types'
import type { Bot, Component } from '../index.js' import type {
Bot,
Component,
DiscordContainerComponent,
DiscordMediaGalleryItem,
DiscordUnfurledMediaItem,
MediaGalleryItem,
UnfurledMediaItem,
} from '../index.js'
export function transformComponent(bot: Bot, payload: DiscordMessageComponent): Component { export function transformComponent(bot: Bot, payload: DiscordMessageComponent): Component {
let component: Component let component: Component
@@ -17,26 +31,78 @@ export function transformComponent(bot: Bot, payload: DiscordMessageComponent):
component = transformActionRow(bot, payload) component = transformActionRow(bot, payload)
break break
case MessageComponentTypes.Button: case MessageComponentTypes.Button:
component = transformButtonComponent(bot, payload as DiscordButtonComponent) component = transformButtonComponent(bot, payload)
break
case MessageComponentTypes.Container:
component = transformContainerComponent(bot, payload)
break break
case MessageComponentTypes.InputText: case MessageComponentTypes.InputText:
component = transformInputTextComponent(bot, payload as DiscordInputTextComponent) component = transformInputTextComponent(bot, payload)
break break
case MessageComponentTypes.SelectMenu: case MessageComponentTypes.SelectMenu:
case MessageComponentTypes.SelectMenuChannels: case MessageComponentTypes.SelectMenuChannels:
case MessageComponentTypes.SelectMenuRoles: case MessageComponentTypes.SelectMenuRoles:
case MessageComponentTypes.SelectMenuUsers: case MessageComponentTypes.SelectMenuUsers:
case MessageComponentTypes.SelectMenuUsersAndRoles: case MessageComponentTypes.SelectMenuUsersAndRoles:
component = transformSelectMenuComponent(bot, payload as DiscordSelectMenuComponent) component = transformSelectMenuComponent(bot, payload)
break
case MessageComponentTypes.Section:
component = transformSectionComponent(bot, payload)
break
case MessageComponentTypes.Thumbnail:
component = transformThumbnailComponent(bot, payload)
break
case MessageComponentTypes.MediaGallery:
component = transformMediaGalleryComponent(bot, payload)
break
case MessageComponentTypes.File:
component = transformFileComponent(bot, payload)
break
case MessageComponentTypes.Separator:
case MessageComponentTypes.TextDisplay:
component = keepAsIs(bot, payload)
break break
} }
return bot.transformers.customizers.component(bot, payload, component) return bot.transformers.customizers.component(bot, payload, component)
} }
export function transformUnfurledMediaItem(bot: Bot, payload: DiscordUnfurledMediaItem): UnfurledMediaItem {
const mediaItem: UnfurledMediaItem = {
url: payload.url,
proxyUrl: payload.proxy_url,
height: payload.height,
width: payload.width,
contentType: payload.content_type,
}
return bot.transformers.customizers.unfurledMediaItem(bot, payload, mediaItem)
}
export function transformMediaGalleryItem(bot: Bot, payload: DiscordMediaGalleryItem): MediaGalleryItem {
const mediaItem: MediaGalleryItem = {
media: bot.transformers.unfurledMediaItem(bot, payload.media),
description: payload.description,
spoiler: payload.spoiler,
}
return bot.transformers.customizers.mediaGalleryItem(bot, payload, mediaItem)
}
function transformActionRow(bot: Bot, payload: DiscordActionRow): Component { function transformActionRow(bot: Bot, payload: DiscordActionRow): Component {
return { return {
type: MessageComponentTypes.ActionRow, type: MessageComponentTypes.ActionRow,
id: payload.id,
components: payload.components.map((component) => bot.transformers.component(bot, component)),
}
}
function transformContainerComponent(bot: Bot, payload: DiscordContainerComponent): Component {
return {
type: MessageComponentTypes.Container,
id: payload.id,
accentColor: payload.accent_color ?? undefined,
spoiler: payload.spoiler,
components: payload.components.map((component) => bot.transformers.component(bot, component)), components: payload.components.map((component) => bot.transformers.component(bot, component)),
} }
} }
@@ -44,6 +110,7 @@ function transformActionRow(bot: Bot, payload: DiscordActionRow): Component {
function transformButtonComponent(bot: Bot, payload: DiscordButtonComponent): Component { function transformButtonComponent(bot: Bot, payload: DiscordButtonComponent): Component {
return { return {
type: MessageComponentTypes.Button, type: MessageComponentTypes.Button,
id: payload.id,
label: payload.label, label: payload.label,
customId: payload.custom_id, customId: payload.custom_id,
style: payload.style, style: payload.style,
@@ -60,9 +127,10 @@ function transformButtonComponent(bot: Bot, payload: DiscordButtonComponent): Co
} }
} }
function transformInputTextComponent(_bot: Bot, payload: DiscordInputTextComponent): Component { function transformInputTextComponent(_bot: Bot, payload: DiscordTextInputComponent): Component {
return { return {
type: MessageComponentTypes.InputText, type: MessageComponentTypes.InputText,
id: payload.id,
style: payload.style, style: payload.style,
required: payload.required, required: payload.required,
customId: payload.custom_id, customId: payload.custom_id,
@@ -77,6 +145,7 @@ function transformInputTextComponent(_bot: Bot, payload: DiscordInputTextCompone
function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuComponent): Component { function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuComponent): Component {
return { return {
type: payload.type, type: payload.type,
id: payload.id,
customId: payload.custom_id, customId: payload.custom_id,
placeholder: payload.placeholder, placeholder: payload.placeholder,
minValues: payload.min_values, minValues: payload.min_values,
@@ -102,3 +171,43 @@ function transformSelectMenuComponent(bot: Bot, payload: DiscordSelectMenuCompon
disabled: payload.disabled, disabled: payload.disabled,
} }
} }
function transformSectionComponent(bot: Bot, payload: DiscordSectionComponent): Component {
return {
type: MessageComponentTypes.Section,
id: payload.id,
components: payload.components.map((component) => bot.transformers.component(bot, component)),
accessory: bot.transformers.component(bot, payload.accessory),
}
}
function transformThumbnailComponent(bot: Bot, payload: DiscordThumbnailComponent): Component {
return {
type: MessageComponentTypes.Thumbnail,
id: payload.id,
media: bot.transformers.unfurledMediaItem(bot, payload.media),
description: payload.description,
spoiler: payload.spoiler,
}
}
function transformMediaGalleryComponent(bot: Bot, payload: DiscordMediaGalleryComponent): Component {
return {
type: MessageComponentTypes.MediaGallery,
id: payload.id,
items: payload.items.map((media) => bot.transformers.mediaGalleryItem(bot, media)),
}
}
function transformFileComponent(bot: Bot, payload: DiscordFileComponent): Component {
return {
type: MessageComponentTypes.File,
id: payload.id,
file: bot.transformers.unfurledMediaItem(bot, payload.file),
spoiler: payload.spoiler,
}
}
function keepAsIs(_bot: Bot, payload: DiscordTextDisplayComponent | DiscordSeparatorComponent): Component {
return payload
}
@@ -1,5 +1,22 @@
import { type DiscordButtonComponent, type DiscordMessageComponent, MessageComponentTypes, type TextStyles } from '@discordeno/types' import { type DiscordButtonComponent, type DiscordMessageComponent, MessageComponentTypes, type TextStyles } from '@discordeno/types'
import type { Bot, ButtonStyles, Component, DiscordActionRow, DiscordInputTextComponent, DiscordSelectMenuComponent } from '../../index.js' import type {
Bot,
ButtonStyles,
Component,
DiscordActionRow,
DiscordContainerComponent,
DiscordFileComponent,
DiscordMediaGalleryComponent,
DiscordMediaGalleryItem,
DiscordSectionComponent,
DiscordSelectMenuComponent,
DiscordTextDisplayComponent,
DiscordTextInputComponent,
DiscordThumbnailComponent,
DiscordUnfurledMediaItem,
MediaGalleryItem,
UnfurledMediaItem,
} from '../../index.js'
export function transformComponentToDiscordComponent(bot: Bot, payload: Component): DiscordMessageComponent { export function transformComponentToDiscordComponent(bot: Bot, payload: Component): DiscordMessageComponent {
// This switch should include all cases // This switch should include all cases
@@ -8,6 +25,8 @@ export function transformComponentToDiscordComponent(bot: Bot, payload: Componen
return transformActionRow(bot, payload) return transformActionRow(bot, payload)
case MessageComponentTypes.Button: case MessageComponentTypes.Button:
return transformButtonComponent(bot, payload) return transformButtonComponent(bot, payload)
case MessageComponentTypes.Container:
return transformContainerComponent(bot, payload)
case MessageComponentTypes.InputText: case MessageComponentTypes.InputText:
return transformInputTextComponent(bot, payload) return transformInputTextComponent(bot, payload)
case MessageComponentTypes.SelectMenu: case MessageComponentTypes.SelectMenu:
@@ -16,21 +35,64 @@ export function transformComponentToDiscordComponent(bot: Bot, payload: Componen
case MessageComponentTypes.SelectMenuUsers: case MessageComponentTypes.SelectMenuUsers:
case MessageComponentTypes.SelectMenuUsersAndRoles: case MessageComponentTypes.SelectMenuUsersAndRoles:
return transformSelectMenuComponent(bot, payload) return transformSelectMenuComponent(bot, payload)
case MessageComponentTypes.Section:
return transformSectionComponent(bot, payload)
case MessageComponentTypes.File:
return transformFileComponent(bot, payload)
case MessageComponentTypes.MediaGallery:
return transformMediaGalleryComponent(bot, payload)
case MessageComponentTypes.Thumbnail:
return transformThumbnailComponent(bot, payload)
case MessageComponentTypes.Separator:
case MessageComponentTypes.TextDisplay:
// As of now they are compatible
return payload as DiscordMessageComponent
}
}
export function transformUnfurledMediaItemToDiscordUnfurledMediaItem(_bot: Bot, payload: UnfurledMediaItem): DiscordUnfurledMediaItem {
return {
url: payload.url,
proxy_url: payload.proxyUrl,
height: payload.height,
width: payload.width,
content_type: payload.contentType,
}
}
export function transformMediaGalleryItemToDiscordMediaGalleryItem(bot: Bot, payload: MediaGalleryItem): DiscordMediaGalleryItem {
return {
media: bot.transformers.reverse.unfurledMediaItem(bot, payload.media),
description: payload.description,
spoiler: payload.spoiler,
} }
} }
function transformActionRow(bot: Bot, payload: Component): DiscordActionRow { function transformActionRow(bot: Bot, payload: Component): DiscordActionRow {
return { return {
type: MessageComponentTypes.ActionRow, type: MessageComponentTypes.ActionRow,
id: payload.id,
// The actionRow.components type is kinda annoying, so we need a cast for this // The actionRow.components type is kinda annoying, so we need a cast for this
components: (payload.components?.map((component) => bot.transformers.reverse.component(bot, component)) ?? []) as DiscordActionRow['components'], components: (payload.components?.map((component) => bot.transformers.reverse.component(bot, component)) ?? []) as DiscordActionRow['components'],
} }
} }
function transformContainerComponent(bot: Bot, payload: Component): DiscordContainerComponent {
return {
type: MessageComponentTypes.Container,
id: payload.id,
accent_color: payload.accentColor,
spoiler: payload.spoiler,
components: (payload.components?.map((component) => bot.transformers.reverse.component(bot, component)) ??
[]) as DiscordContainerComponent['components'],
}
}
function transformButtonComponent(bot: Bot, payload: Component): DiscordButtonComponent { function transformButtonComponent(bot: Bot, payload: Component): DiscordButtonComponent {
// Since Component is a merge of all components, some casts are necessary // Since Component is a merge of all components, some casts are necessary
return { return {
type: MessageComponentTypes.Button, type: MessageComponentTypes.Button,
id: payload.id,
style: payload.style as ButtonStyles, style: payload.style as ButtonStyles,
custom_id: payload.customId, custom_id: payload.customId,
disabled: payload.disabled, disabled: payload.disabled,
@@ -47,10 +109,11 @@ function transformButtonComponent(bot: Bot, payload: Component): DiscordButtonCo
} }
} }
function transformInputTextComponent(_bot: Bot, payload: Component): DiscordInputTextComponent { function transformInputTextComponent(_bot: Bot, payload: Component): DiscordTextInputComponent {
// Since Component is a merge of all components, some casts are necessary // Since Component is a merge of all components, some casts are necessary
return { return {
type: MessageComponentTypes.InputText, type: MessageComponentTypes.InputText,
id: payload.id,
style: payload.style as TextStyles, style: payload.style as TextStyles,
custom_id: payload.customId!, custom_id: payload.customId!,
label: payload.label!, label: payload.label!,
@@ -65,6 +128,7 @@ function transformInputTextComponent(_bot: Bot, payload: Component): DiscordInpu
function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSelectMenuComponent { function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSelectMenuComponent {
return { return {
type: payload.type as DiscordSelectMenuComponent['type'], type: payload.type as DiscordSelectMenuComponent['type'],
id: payload.id,
custom_id: payload.customId!, custom_id: payload.customId!,
channel_types: payload.channelTypes, channel_types: payload.channelTypes,
default_values: payload.defaultValues?.map((defaultValue) => ({ default_values: payload.defaultValues?.map((defaultValue) => ({
@@ -90,3 +154,39 @@ function transformSelectMenuComponent(bot: Bot, payload: Component): DiscordSele
placeholder: payload.placeholder, placeholder: payload.placeholder,
} }
} }
function transformSectionComponent(bot: Bot, payload: Component): DiscordSectionComponent {
return {
type: MessageComponentTypes.Section,
id: payload.id,
components: payload.components?.map((component) => bot.transformers.reverse.component(bot, component)) as DiscordTextDisplayComponent[],
accessory: (payload.accessory ? bot.transformers.reverse.component(bot, payload.accessory) : undefined) as DiscordSectionComponent['accessory'],
}
}
function transformFileComponent(bot: Bot, payload: Component): DiscordFileComponent {
return {
type: MessageComponentTypes.File,
id: payload.id,
file: bot.transformers.reverse.unfurledMediaItem(bot, payload.file!),
spoiler: payload.spoiler,
}
}
function transformMediaGalleryComponent(bot: Bot, payload: Component): DiscordMediaGalleryComponent {
return {
type: MessageComponentTypes.MediaGallery,
id: payload.id,
items: payload.items?.map((item) => bot.transformers.reverse.mediaGalleryItem(bot, item)) ?? [],
}
}
function transformThumbnailComponent(bot: Bot, payload: Component): DiscordThumbnailComponent {
return {
type: MessageComponentTypes.Thumbnail,
id: payload.id,
media: bot.transformers.reverse.unfurledMediaItem(bot, payload.media!),
description: payload.description,
spoiler: payload.spoiler,
}
}
+45
View File
@@ -58,6 +58,7 @@ import type {
ScheduledEventPrivacyLevel, ScheduledEventPrivacyLevel,
ScheduledEventStatus, ScheduledEventStatus,
SelectOption, SelectOption,
SeparatorSpacingSize,
SkuFlags, SkuFlags,
SortOrderTypes, SortOrderTypes,
StickerFormatTypes, StickerFormatTypes,
@@ -546,6 +547,50 @@ export interface Component {
defaultValues?: DiscordComponentDefaultValue[] defaultValues?: DiscordComponentDefaultValue[]
/** Identifier for a purchasable SKU, only available when using premium-style buttons */ /** Identifier for a purchasable SKU, only available when using premium-style buttons */
skuId?: bigint skuId?: bigint
/** Optional identifier for component */
id?: number
/** A thumbnail or a button component, with a future possibility of adding more compatible components */
accessory?: Component
/** Text that will be displayed similar to a message */
content?: string
/** Alt text for the media */
description?: string
/** Whether the thumbnail should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
/** 1 to 10 media gallery items */
items?: MediaGalleryItem[]
/** Whether a visual divider should be displayed in the component. Defaults to `true` */
divider?: boolean
/** Size of separator padding — `1` for small padding, `2` for large padding. Defaults to `1` */
spacing?: SeparatorSpacingSize
/** This unfurled media item is unique in that it only supports attachment references using the attachment://<filename> syntax */
file?: UnfurledMediaItem
/** This unfurled media item is unique in that it only supports attachment references using the attachment://<filename> syntax */
media?: UnfurledMediaItem
/** Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF */
accentColor?: number
}
export interface UnfurledMediaItem {
/** Supports arbitrary urls and attachment://<filename> references */
url: string
/** The proxied url of the media item. This field is ignored and provided by the API as part of the response */
proxyUrl?: string
/** The height of the media item. This field is ignored and provided by the API as part of the response */
height?: number | null
/** The width of the media item. This field is ignored and provided by the API as part of the response */
width?: number | null
/** The media type of the content. This field is ignored and provided by the API as part of the response */
contentType?: string
}
export interface MediaGalleryItem {
/** A url or attachment */
media: UnfurledMediaItem
/** Alt text for the media */
description?: string
/** Whether the media should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
} }
export interface DiscordComponentDefaultValue { export interface DiscordComponentDefaultValue {
+1 -1
View File
@@ -1,7 +1,7 @@
/** Types for: https://discord.com/developers/docs/resources/channel */ /** Types for: https://discord.com/developers/docs/resources/channel */
import type { DiscordMessageComponents } from './components.js'
import type { DiscordMember } from './guild.js' import type { DiscordMember } from './guild.js'
import type { DiscordMessageComponents } from './interactions.js'
import type { DiscordAllowedMentions, DiscordAttachment, DiscordEmbed, MessageFlags } from './message.js' import type { DiscordAllowedMentions, DiscordAttachment, DiscordEmbed, MessageFlags } from './message.js'
import type { DiscordUser } from './user.js' import type { DiscordUser } from './user.js'
+348
View File
@@ -0,0 +1,348 @@
/** Types for: https://discord.com/developers/docs/components/reference */
import type { ChannelTypes } from './channel.js'
/** https://discord.com/developers/docs/components/reference#component-object-component-types */
export enum MessageComponentTypes {
/** A container for other components */
ActionRow = 1,
/** A button object */
Button,
/** A select menu for picking from choices */
SelectMenu,
/** A text input object */
InputText,
/** Select menu for users */
SelectMenuUsers,
/** Select menu for roles */
SelectMenuRoles,
/** Select menu for users and roles */
SelectMenuUsersAndRoles,
/** Select menu for channels */
SelectMenuChannels,
/** Container to display text alongside an accessory component */
Section,
/** Markdown text */
TextDisplay,
/** Small image that can be used as an accessory */
Thumbnail,
/** Display images and other media */
MediaGallery,
/** Displays an attached file */
File,
/** Component to add vertical padding between other components */
Separator,
/** Container that visually groups a set of components */
Container = 17,
}
export type DiscordMessageComponents = DiscordMessageComponent[]
export type DiscordMessageComponent =
| DiscordActionRow
| DiscordSelectMenuComponent
| DiscordButtonComponent
| DiscordTextInputComponent
| DiscordSectionComponent
| DiscordTextDisplayComponent
| DiscordThumbnailComponent
| DiscordMediaGalleryComponent
| DiscordSeparatorComponent
| DiscordFileComponent
| DiscordContainerComponent
/** https://discord.com/developers/docs/components/reference#anatomy-of-a-component */
export interface DiscordBaseComponent {
/** The type of the component */
type: MessageComponentTypes
/** 32 bit integer used as an optional identifier for component */
id?: number
}
/** https://discord.com/developers/docs/components/reference#action-row-action-row-structure */
export interface DiscordActionRow extends DiscordBaseComponent {
type: MessageComponentTypes.ActionRow
/**
* The components in this row
*
* @remarks
* Up to 5 button components, a single select component or a single text input component
*/
components: (DiscordButtonComponent | DiscordSelectMenuComponent | DiscordTextInputComponent)[]
}
/** https://discord.com/developers/docs/components/reference#button-button-structure */
export interface DiscordButtonComponent extends DiscordBaseComponent {
type: MessageComponentTypes.Button
/** For different styles/colors of the buttons */
style: ButtonStyles
/**
* Text that appears on the button
*
* @remarks
* A label can have a max of 80 characters
* A button of style {@link ButtonStyles.Premium | Premium} cannot have a label
*/
label?: string
/**
* Emoji object that includes fields of name, id, and animated supporting unicode and custom emojis.
*
* @remarks
* A button of style {@link ButtonStyles.Premium | Premium} cannot have an emoji
*/
emoji?: {
/** Emoji id */
id?: string
/** Emoji name */
name?: string
/** Whether this emoji is animated */
animated?: boolean
}
/**
* A dev-defined unique string sent on click (max 100 characters).
*
* @remarks
* A button of style {@link ButtonStyles.Link | Link} or {@link ButtonStyles.Premium | Premium} cannot have a custom_id
*/
custom_id?: string
/**
* Identifier for a purchasable SKU
*
* @remarks
* Buttons of style {@link ButtonStyles.Premium | Premium} must have a sku_id, any other button with a different style can not have a a sku_id
*/
sku_id?: string
/**
* Url for {@link ButtonStyles.Link | link} buttons that can navigate a user to the web.
*
* @remarks
* Buttons of style {@link ButtonStyles.Link | Link} must have an url, any other button with a different style can not have an url
*/
url?: string
/** Whether or not this button is disabled */
disabled?: boolean
}
/** https://discord.com/developers/docs/components/reference#button-button-styles */
export enum ButtonStyles {
/** A blurple button */
Primary = 1,
/** A grey button */
Secondary,
/** A green button */
Success,
/** A red button */
Danger,
/** A button that navigates to a URL */
Link,
/** A blurple button to show a Premium item in the shop */
Premium,
}
/**
* https://discord.com/developers/docs/components/reference#string-select
* https://discord.com/developers/docs/components/reference#user-select
* https://discord.com/developers/docs/components/reference#role-select
* https://discord.com/developers/docs/components/reference#mentionable-select
* https://discord.com/developers/docs/components/reference#channel-select
*/
export interface DiscordSelectMenuComponent extends DiscordBaseComponent {
type:
| MessageComponentTypes.SelectMenu
| MessageComponentTypes.SelectMenuUsers
| MessageComponentTypes.SelectMenuRoles
| MessageComponentTypes.SelectMenuUsersAndRoles
| MessageComponentTypes.SelectMenuChannels
/** A custom identifier for this component. Maximum 100 characters. */
custom_id: string
/** Specified choices in a select menu; 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 1-25. */
min_values?: number
/** The maximum number of items that can be selected. Default 1. Between 1-25. */
max_values?: number
/**
* Whether select menu is disabled
*
* @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://discord.com/developers/docs/components/reference#string-select-select-option-structure */
export interface DiscordSelectOption {
/** The user-facing name of the option. Maximum 25 characters. */
label: string
/** The dev-defined value of the option. Maximum 100 characters. */
value: string
/** An additional description of the option. Maximum 50 characters. */
description?: string
/** The id, name, and animated properties of an emoji. */
emoji?: {
/** Emoji id */
id?: string
/** Emoji name */
name?: string
/** Whether this emoji is animated */
animated?: boolean
}
/** Will render this option as already-selected by default. */
default?: boolean
}
/** https://discord.com/developers/docs/components/reference#text-input-text-input-structure */
export interface DiscordTextInputComponent extends DiscordBaseComponent {
type: MessageComponentTypes.InputText
/** The customId of the InputText */
custom_id: string
/** The style of the InputText */
style: TextStyles
/** The label of the InputText (max 45 characters) */
label: string
/** The minimum length of the text the user has to provide */
min_length?: number
/** The maximum length of the text the user has to provide */
max_length?: number
/** whether this component is required to be filled, default true */
required?: boolean
/** Pre-filled value for input text. */
value?: string
/** The placeholder of the InputText */
placeholder?: string
}
/** https://discord.com/developers/docs/components/reference#text-input-text-input-styles */
export enum TextStyles {
/** Intended for short single-line text */
Short = 1,
/** Intended for much longer inputs */
Paragraph = 2,
}
/** https://discord.com/developers/docs/components/reference#user-select-select-default-value-structure */
export interface DiscordSelectMenuDefaultValue {
/** ID of a user, role, or channel */
id: string
/** Type of value that id represents. */
type: 'user' | 'role' | 'channel'
}
/** https://discord.com/developers/docs/components/reference#section-section-structure */
export interface DiscordSectionComponent extends DiscordBaseComponent {
type: MessageComponentTypes.Section
/** One to three text components */
components: DiscordTextDisplayComponent[]
/** A thumbnail or a button component, with a future possibility of adding more compatible components */
accessory: DiscordButtonComponent | DiscordThumbnailComponent
}
/** https://discord.com/developers/docs/components/reference#text-display-text-display-structure */
export interface DiscordTextDisplayComponent extends DiscordBaseComponent {
type: MessageComponentTypes.TextDisplay
/** Text that will be displayed similar to a message */
content: string
}
export interface DiscordThumbnailComponent extends DiscordBaseComponent {
type: MessageComponentTypes.Thumbnail
/** A url or attachment */
media: DiscordUnfurledMediaItem
/** Alt text for the media */
description?: string
/** Whether the thumbnail should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
}
/** https://discord.com/developers/docs/components/reference#media-gallery-media-gallery-structure */
export interface DiscordMediaGalleryComponent extends DiscordBaseComponent {
type: MessageComponentTypes.MediaGallery
/** 1 to 10 media gallery items */
items: DiscordMediaGalleryItem[]
}
/** https://discord.com/developers/docs/components/reference#media-gallery-media-gallery-item-structure */
export interface DiscordMediaGalleryItem {
/** A url or attachment */
media: DiscordUnfurledMediaItem
/** Alt text for the media */
description?: string
/** Whether the media should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
}
/** https://discord.com/developers/docs/components/reference#file-file-structure */
export interface DiscordFileComponent extends DiscordBaseComponent {
type: MessageComponentTypes.File
/** This unfurled media item is unique in that it only supports attachment references using the attachment://<filename> syntax */
file: DiscordUnfurledMediaItem
/** Whether the media should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
}
/** https://discord.com/developers/docs/components/reference#separator-separator-structure */
export interface DiscordSeparatorComponent extends DiscordBaseComponent {
type: MessageComponentTypes.Separator
/** Whether a visual divider should be displayed in the component. Defaults to `true` */
divider?: boolean
/** Size of separator padding — `1` for small padding, `2` for large padding. Defaults to `1` */
spacing?: SeparatorSpacingSize
}
/** https://discord.com/developers/docs/components/reference#separator-separator-structure, spacing description */
export enum SeparatorSpacingSize {
Small = 1,
Large = 2,
}
/** https://discord.com/developers/docs/components/reference#container-container-structure */
export interface DiscordContainerComponent extends DiscordBaseComponent {
type: MessageComponentTypes.Container
/** Up to 10 components of the type action row, text display, section, media gallery, separator, or file */
components: Array<
| DiscordActionRow
| DiscordTextDisplayComponent
| DiscordSectionComponent
| DiscordMediaGalleryComponent
| DiscordSeparatorComponent
| DiscordFileComponent
>
/** Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF */
accent_color?: number | null
/** Whether the container should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
}
/** https://discord.com/developers/docs/components/reference#unfurled-media-item-structure */
export interface DiscordUnfurledMediaItem {
/** Supports arbitrary urls and attachment://<filename> references */
url: string
/** The proxied url of the media item. This field is ignored and provided by the API as part of the response */
proxy_url?: string
/** The height of the media item. This field is ignored and provided by the API as part of the response */
height?: number | null
/** The width of the media item. This field is ignored and provided by the API as part of the response */
width?: number | null
/** The media type of the content. This field is ignored and provided by the API as part of the response */
content_type?: string
}
+1 -195
View File
@@ -2,11 +2,11 @@
* Types for: * Types for:
* - https://discord.com/developers/docs/interactions/receiving-and-responding * - https://discord.com/developers/docs/interactions/receiving-and-responding
* - https://discord.com/developers/docs/interactions/application-commands * - https://discord.com/developers/docs/interactions/application-commands
* - https://discord.com/developers/docs/interactions/message-components
*/ */
import type { DiscordApplicationIntegrationType } from './application.js' import type { DiscordApplicationIntegrationType } from './application.js'
import type { ChannelTypes, DiscordChannel } from './channel.js' import type { ChannelTypes, DiscordChannel } from './channel.js'
import type { DiscordMessageComponents, MessageComponentTypes } from './components.js'
import type { DiscordEntitlement } from './entitlement.js' import type { DiscordEntitlement } from './entitlement.js'
import type { DiscordGuild, DiscordMember, DiscordMemberWithUser } from './guild.js' import type { DiscordGuild, DiscordMember, DiscordMemberWithUser } from './guild.js'
import type { DiscordAttachment, DiscordMessage } from './message.js' import type { DiscordAttachment, DiscordMessage } from './message.js'
@@ -411,200 +411,6 @@ export enum ApplicationCommandPermissionTypes {
Channel, Channel,
} }
/** https://discord.com/developers/docs/interactions/message-components#component-object-component-types */
export enum MessageComponentTypes {
/** A container for other components */
ActionRow = 1,
/** A button object */
Button,
/** A select menu for picking from choices */
SelectMenu,
/** A text input object */
InputText,
/** Select menu for users */
SelectMenuUsers,
/** Select menu for roles */
SelectMenuRoles,
/** Select menu for users and roles */
SelectMenuUsersAndRoles,
/** Select menu for channels */
SelectMenuChannels,
}
export type DiscordMessageComponents = DiscordMessageComponent[]
export type DiscordMessageComponent = DiscordActionRow | DiscordSelectMenuComponent | DiscordButtonComponent | DiscordInputTextComponent
/** https://discord.com/developers/docs/interactions/message-components#actionrow */
export interface DiscordActionRow {
/** Action rows are a group of buttons. */
type: MessageComponentTypes.ActionRow
/** The components in this row */
components: Exclude<DiscordMessageComponent, DiscordActionRow>[]
}
/** https://discord.com/developers/docs/interactions/message-components#button-object-button-structure */
export interface DiscordButtonComponent {
/** All button components have type 2 */
type: MessageComponentTypes.Button
/**
* Text that appears on the button
*
* @remarks
* A label can have a max of 80 characters
* A button of style {@link ButtonStyles.Premium | Premium} cannot have a label
*/
label?: string
/**
* A dev-defined unique string sent on click (max 100 characters).
*
* @remarks
* A button of style {@link ButtonStyles.Link | Link} or {@link ButtonStyles.Premium | Premium} cannot have a custom_id
*/
custom_id?: string
/** For different styles/colors of the buttons */
style: ButtonStyles
/**
* Emoji object that includes fields of name, id, and animated supporting unicode and custom emojis.
*
* @remarks
* A button of style {@link ButtonStyles.Premium | Premium} cannot have an emoji
*/
emoji?: {
/** Emoji id */
id?: string
/** Emoji name */
name?: string
/** Whether this emoji is animated */
animated?: boolean
}
/**
* Url for {@link ButtonStyles.Link | link} buttons that can navigate a user to the web.
*
* @remarks
* Buttons of style {@link ButtonStyles.Link | Link} must have an url, any other button with a different style can not have an url
*/
url?: string
/** Whether or not this button is disabled */
disabled?: boolean
/**
* Identifier for a purchasable SKU
*
* @remarks
* Buttons of style {@link ButtonStyles.Premium | Premium} must have a sku_id, any other button with a different style can not have a a sku_id
*/
sku_id?: string
}
/** https://discord.com/developers/docs/interactions/message-components#button-object-button-styles */
export enum ButtonStyles {
/** A blurple button */
Primary = 1,
/** A grey button */
Secondary,
/** A green button */
Success,
/** A red button */
Danger,
/** A button that navigates to a URL */
Link,
/** A blurple button to show a Premium item in the shop */
Premium,
}
/** https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure */
export interface DiscordSelectMenuComponent {
type:
| MessageComponentTypes.SelectMenu
| MessageComponentTypes.SelectMenuChannels
| MessageComponentTypes.SelectMenuRoles
| MessageComponentTypes.SelectMenuUsers
| MessageComponentTypes.SelectMenuUsersAndRoles
/** 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
/** The minimum number of items that must be selected. Default 1. Between 1-25. */
min_values?: number
/** The maximum number of items that can be selected. Default 1. Between 1-25. */
max_values?: number
/**
* 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[]
/** The choices! Maximum of 25 items. */
options?: DiscordSelectOption[]
/**
* Whether select menu is disabled
*
* @default false
*/
disabled?: boolean
}
/** https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-option-structure */
export interface DiscordSelectOption {
/** The user-facing name of the option. Maximum 25 characters. */
label: string
/** The dev-defined value of the option. Maximum 100 characters. */
value: string
/** An additional description of the option. Maximum 50 characters. */
description?: string
/** The id, name, and animated properties of an emoji. */
emoji?: {
/** Emoji id */
id?: string
/** Emoji name */
name?: string
/** Whether this emoji is animated */
animated?: boolean
}
/** Will render this option as already-selected by default. */
default?: boolean
}
/** https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-default-value-structure */
export interface DiscordSelectMenuDefaultValue {
/** ID of a user, role, or channel */
id: string
/** Type of value that id represents. */
type: 'user' | 'role' | 'channel'
}
/** https://discord.com/developers/docs/interactions/message-components#text-input-object-text-input-structure */
export interface DiscordInputTextComponent {
/** InputText Component is of type 3 */
type: MessageComponentTypes.InputText
/** The style of the InputText */
style: TextStyles
/** whether this component is required to be filled, default true */
required?: boolean
/** The customId of the InputText */
custom_id: string
/** The label of the InputText (max 45 characters) */
label: string
/** The placeholder of the InputText */
placeholder?: string
/** The minimum length of the text the user has to provide */
min_length?: number
/** The maximum length of the text the user has to provide */
max_length?: number
/** Pre-filled value for input text. */
value?: string
}
/** https://discord.com/developers/docs/interactions/message-components#text-input-object-text-input-styles */
export enum TextStyles {
/** Intended for short single-line text */
Short = 1,
/** Intended for much longer inputs */
Paragraph = 2,
}
/** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-structure specifcly the member propriety */ /** https://discord.com/developers/docs/interactions/receiving-and-responding#interaction-object-interaction-structure specifcly the member propriety */
export interface DiscordInteractionMember extends DiscordMemberWithUser { export interface DiscordInteractionMember extends DiscordMemberWithUser {
/** Total permissions of the member in the channel, including overwrites, returned when in the interaction object */ /** Total permissions of the member in the channel, including overwrites, returned when in the interaction object */
+4 -1
View File
@@ -2,9 +2,10 @@
import type { DiscordApplication } from './application.js' import type { DiscordApplication } from './application.js'
import type { DiscordChannel, DiscordThreadMember } from './channel.js' import type { DiscordChannel, DiscordThreadMember } from './channel.js'
import type { DiscordMessageComponents } from './components.js'
import type { DiscordEmoji } from './emoji.js' import type { DiscordEmoji } from './emoji.js'
import type { DiscordMember } from './guild.js' import type { DiscordMember } from './guild.js'
import type { DiscordAuthorizingIntegrationOwners, DiscordMessageComponents, DiscordMessageInteraction, InteractionTypes } from './interactions.js' import type { DiscordAuthorizingIntegrationOwners, DiscordMessageInteraction, InteractionTypes } from './interactions.js'
import type { DiscordPoll } from './poll.js' import type { DiscordPoll } from './poll.js'
import type { DiscordSticker, DiscordStickerItem } from './sticker.js' import type { DiscordSticker, DiscordStickerItem } from './sticker.js'
import type { DiscordUser } from './user.js' import type { DiscordUser } from './user.js'
@@ -193,6 +194,8 @@ export enum MessageFlags {
IsVoiceMessage = 1 << 13, IsVoiceMessage = 1 << 13,
/** This message has a snapshot (via Message Forwarding) */ /** This message has a snapshot (via Message Forwarding) */
HasSnapshot = 1 << 14, HasSnapshot = 1 << 14,
/** Allows you to create fully component driven messages */
IsComponentV2 = 1 << 15,
} }
/** https://discord.com/developers/docs/resources/message#message-interaction-metadata-object */ /** https://discord.com/developers/docs/resources/message#message-interaction-metadata-object */
+109 -21
View File
@@ -21,6 +21,14 @@ import type {
SortOrderTypes, SortOrderTypes,
VideoQualityModes, VideoQualityModes,
} from './discord/channel.js' } from './discord/channel.js'
import type {
ButtonStyles,
DiscordMediaGalleryItem,
DiscordUnfurledMediaItem,
MessageComponentTypes,
SeparatorSpacingSize,
TextStyles,
} from './discord/components.js'
import type { import type {
DefaultMessageNotificationLevels, DefaultMessageNotificationLevels,
DiscordGuildOnboardingMode, DiscordGuildOnboardingMode,
@@ -38,14 +46,11 @@ import type {
} from './discord/guildScheduledEvent.js' } from './discord/guildScheduledEvent.js'
import type { import type {
ApplicationCommandTypes, ApplicationCommandTypes,
ButtonStyles,
DiscordApplicationCommandOption, DiscordApplicationCommandOption,
DiscordApplicationCommandOptionChoice, DiscordApplicationCommandOptionChoice,
DiscordInteractionContextType, DiscordInteractionContextType,
DiscordInteractionEntryPointCommandHandlerType, DiscordInteractionEntryPointCommandHandlerType,
InteractionResponseTypes, InteractionResponseTypes,
MessageComponentTypes,
TextStyles,
} from './discord/interactions.js' } from './discord/interactions.js'
import type { TargetTypes } from './discord/invite.js' import type { TargetTypes } from './discord/invite.js'
import type { import type {
@@ -115,11 +120,25 @@ export type MessageComponent =
| SelectMenuRolesComponent | SelectMenuRolesComponent
| SelectMenuUsersComponent | SelectMenuUsersComponent
| SelectMenuUsersAndRolesComponent | SelectMenuUsersAndRolesComponent
| SectionComponent
| TextDisplayComponent
| ThumbnailComponent
| MediaGalleryComponent
| SeparatorComponent
| FileComponent
/** https://discord.com/developers/docs/components/reference#anatomy-of-a-component */
export interface BaseComponent {
/** The type of the component */
type: MessageComponentTypes
/** 32 bit integer used as an optional identifier for component */
id?: number
}
/** https://discord.com/developers/docs/interactions/message-components#actionrow */ /** https://discord.com/developers/docs/interactions/message-components#actionrow */
export interface ActionRow { export interface ActionRow extends BaseComponent {
/** Action rows are a group of buttons. */
type: MessageComponentTypes.ActionRow type: MessageComponentTypes.ActionRow
/** The components in this row */ /** The components in this row */
components: components:
| [Exclude<MessageComponent, ActionRow>] | [Exclude<MessageComponent, ActionRow>]
@@ -130,9 +149,9 @@ export interface ActionRow {
} }
/** https://discord.com/developers/docs/interactions/message-components#button-object-button-structure */ /** https://discord.com/developers/docs/interactions/message-components#button-object-button-structure */
export interface ButtonComponent { export interface ButtonComponent extends BaseComponent {
/** All button components have type 2 */
type: MessageComponentTypes.Button type: MessageComponentTypes.Button
/** for what the button says (max 80 characters) */ /** for what the button says (max 80 characters) */
label?: string label?: string
/** a dev-defined unique string sent on click (max 100 characters). type 5 Link buttons can not have a custom_id */ /** a dev-defined unique string sent on click (max 100 characters). type 5 Link buttons can not have a custom_id */
@@ -157,9 +176,9 @@ export interface ButtonComponent {
} }
/** https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure */ /** https://discord.com/developers/docs/interactions/message-components#select-menu-object-select-menu-structure */
export interface SelectMenuComponent { export interface SelectMenuComponent extends BaseComponent {
/** SelectMenu Component is of type 3 */
type: MessageComponentTypes.SelectMenu type: MessageComponentTypes.SelectMenu
/** A custom identifier for this component. Maximum 100 characters. */ /** A custom identifier for this component. Maximum 100 characters. */
customId: string customId: string
/** A custom placeholder text if nothing is selected. Maximum 150 characters. */ /** A custom placeholder text if nothing is selected. Maximum 150 characters. */
@@ -174,9 +193,9 @@ export interface SelectMenuComponent {
disabled?: boolean disabled?: boolean
} }
export interface SelectMenuUsersComponent { export interface SelectMenuUsersComponent extends BaseComponent {
/** SelectMenuChannels Component is of type 5 */
type: MessageComponentTypes.SelectMenuUsers type: MessageComponentTypes.SelectMenuUsers
/** A custom identifier for this component. Maximum 100 characters. */ /** A custom identifier for this component. Maximum 100 characters. */
customId: string customId: string
/** A custom placeholder text if nothing is selected. Maximum 150 characters. */ /** A custom placeholder text if nothing is selected. Maximum 150 characters. */
@@ -194,9 +213,9 @@ export interface SelectMenuUsersComponent {
disabled?: boolean disabled?: boolean
} }
export interface SelectMenuRolesComponent { export interface SelectMenuRolesComponent extends BaseComponent {
/** SelectMenuChannels Component is of type 6 */
type: MessageComponentTypes.SelectMenuRoles type: MessageComponentTypes.SelectMenuRoles
/** A custom identifier for this component. Maximum 100 characters. */ /** A custom identifier for this component. Maximum 100 characters. */
customId: string customId: string
/** A custom placeholder text if nothing is selected. Maximum 150 characters. */ /** A custom placeholder text if nothing is selected. Maximum 150 characters. */
@@ -214,9 +233,9 @@ export interface SelectMenuRolesComponent {
disabled?: boolean disabled?: boolean
} }
export interface SelectMenuUsersAndRolesComponent { export interface SelectMenuUsersAndRolesComponent extends BaseComponent {
/** SelectMenuChannels Component is of type 7 */
type: MessageComponentTypes.SelectMenuUsersAndRoles type: MessageComponentTypes.SelectMenuUsersAndRoles
/** A custom identifier for this component. Maximum 100 characters. */ /** A custom identifier for this component. Maximum 100 characters. */
customId: string customId: string
/** A custom placeholder text if nothing is selected. Maximum 150 characters. */ /** A custom placeholder text if nothing is selected. Maximum 150 characters. */
@@ -234,9 +253,9 @@ export interface SelectMenuUsersAndRolesComponent {
disabled?: boolean disabled?: boolean
} }
export interface SelectMenuChannelsComponent { export interface SelectMenuChannelsComponent extends BaseComponent {
/** SelectMenuChannels Component is of type 8 */
type: MessageComponentTypes.SelectMenuChannels type: MessageComponentTypes.SelectMenuChannels
/** A custom identifier for this component. Maximum 100 characters. */ /** A custom identifier for this component. Maximum 100 characters. */
customId: string customId: string
/** A custom placeholder text if nothing is selected. Maximum 150 characters. */ /** A custom placeholder text if nothing is selected. Maximum 150 characters. */
@@ -284,9 +303,9 @@ export interface SelectMenuDefaultValue {
} }
/** https://discord.com/developers/docs/interactions/message-components#text-inputs-text-input-structure */ /** https://discord.com/developers/docs/interactions/message-components#text-inputs-text-input-structure */
export interface InputTextComponent { export interface InputTextComponent extends BaseComponent {
/** InputText Component is of type 4 */
type: MessageComponentTypes.InputText type: MessageComponentTypes.InputText
/** The style of the InputText */ /** The style of the InputText */
style: TextStyles style: TextStyles
/** The customId of the InputText */ /** The customId of the InputText */
@@ -305,6 +324,76 @@ export interface InputTextComponent {
value?: string value?: string
} }
/** https://discord.com/developers/docs/components/reference#section-section-structure */
export interface SectionComponent extends BaseComponent {
type: MessageComponentTypes.Section
/** One to three text components */
components: TextDisplayComponent[]
/** A thumbnail or a button component, with a future possibility of adding more compatible components */
accessory: ButtonComponent | ThumbnailComponent
}
/** https://discord.com/developers/docs/components/reference#text-display */
export interface TextDisplayComponent extends BaseComponent {
type: MessageComponentTypes.TextDisplay
/** Text that will be displayed similar to a message */
content: string
}
/** https://discord.com/developers/docs/components/reference#thumbnail */
export interface ThumbnailComponent extends BaseComponent {
type: MessageComponentTypes.Thumbnail
/** A url or attachment */
media: DiscordUnfurledMediaItem
/** Alt text for the media */
description?: string
/** Whether the thumbnail should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
}
/** https://discord.com/developers/docs/components/reference#media-gallery */
export interface MediaGalleryComponent extends BaseComponent {
type: MessageComponentTypes.MediaGallery
/** 1 to 10 media gallery items */
items: DiscordMediaGalleryItem[]
}
/** https://discord.com/developers/docs/components/reference#file */
export interface FileComponent extends BaseComponent {
type: MessageComponentTypes.File
/** This unfurled media item is unique in that it only supports attachment references using the attachment://<filename> syntax */
file: DiscordUnfurledMediaItem
/** Whether the media should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
}
/** https://discord.com/developers/docs/components/reference#separator */
export interface SeparatorComponent extends BaseComponent {
type: MessageComponentTypes.Separator
/** Whether a visual divider should be displayed in the component. Defaults to `true` */
divider?: boolean
/** Size of separator padding — `1` for small padding, `2` for large padding. Defaults to `1` */
spacing?: SeparatorSpacingSize
}
/** https://discord.com/developers/docs/components/reference#container */
export interface ContainerComponent extends BaseComponent {
type: MessageComponentTypes.Container
/** Up to 10 components of the type action row, text display, section, media gallery, separator, or file */
components: Array<ActionRow | TextDisplayComponent | SectionComponent | MediaGalleryComponent | SeparatorComponent | FileComponent>
/** Color for the accent on the container as RGB from 0x000000 to 0xFFFFFF */
accentColor?: number
/** Whether the container should be a spoiler (or blurred out). Defaults to `false` */
spoiler?: boolean
}
/** https://discord.com/developers/docs/resources/channel#allowed-mentions-object */ /** https://discord.com/developers/docs/resources/channel#allowed-mentions-object */
export interface AllowedMentions { export interface AllowedMentions {
/** An array of allowed mention types to parse from the content. */ /** An array of allowed mention types to parse from the content. */
@@ -629,8 +718,7 @@ export interface RequestGuildMembers {
nonce?: string nonce?: string
} }
/** https://discord.com/developers/docs/topics/gateway#request-guild-members */ /** https://discord.com/developers/docs/resources/guild#create-guild-channel */
export interface CreateGuildChannel { export interface CreateGuildChannel {
/** Channel name (1-100 characters) */ /** Channel name (1-100 characters) */
name: string name: string
+1
View File
@@ -3,6 +3,7 @@ export * from './discord/applicationRoleConnectionMetadata.js'
export * from './discord/auditLog.js' export * from './discord/auditLog.js'
export * from './discord/autoModeration.js' export * from './discord/autoModeration.js'
export * from './discord/channel.js' export * from './discord/channel.js'
export * from './discord/components.js'
export * from './discord/emoji.js' export * from './discord/emoji.js'
export * from './discord/entitlement.js' export * from './discord/entitlement.js'
export * from './discord/gateway.js' export * from './discord/gateway.js'