From 808adeb016bbbd86652e3b03e7750d35728fd1e6 Mon Sep 17 00:00:00 2001 From: Elysia <71698422+aiko-chan-ai@users.noreply.github.com> Date: Tue, 28 Feb 2023 13:42:35 +0700 Subject: [PATCH] feat: new select menu (v2) #9174 djs --- src/client/actions/InteractionCreate.js | 24 +++- src/index.js | 7 +- src/structures/Interaction.js | 69 +++++++++-- src/structures/MessageSelectMenu.js | 49 ++++---- src/structures/SelectMenuInteraction.js | 153 +++++++++++++++++++++++- src/util/Constants.js | 56 +++++---- typings/enums.d.ts | 4 + typings/index.d.ts | 111 ++++++++++++++--- 8 files changed, 392 insertions(+), 81 deletions(-) diff --git a/src/client/actions/InteractionCreate.js b/src/client/actions/InteractionCreate.js index 5769939..158b11f 100644 --- a/src/client/actions/InteractionCreate.js +++ b/src/client/actions/InteractionCreate.js @@ -7,7 +7,13 @@ const ButtonInteraction = require('../../structures/ButtonInteraction'); const CommandInteraction = require('../../structures/CommandInteraction'); const MessageContextMenuInteraction = require('../../structures/MessageContextMenuInteraction'); const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction'); -const SelectMenuInteraction = require('../../structures/SelectMenuInteraction'); +const { + ChannelSelectInteraction, + MentionableSelectInteraction, + RoleSelectInteraction, + SelectMenuInteraction, + UserSelectInteraction, +} = require('../../structures/SelectMenuInteraction'); const UserContextMenuInteraction = require('../../structures/UserContextMenuInteraction'); const { Events, InteractionTypes, MessageComponentTypes, ApplicationCommandTypes } = require('../../util/Constants'); @@ -48,12 +54,20 @@ class InteractionCreateAction extends Action { InteractionType = ButtonInteraction; break; case MessageComponentTypes.STRING_SELECT: - case MessageComponentTypes.USER_SELECT: - case MessageComponentTypes.ROLE_SELECT: - case MessageComponentTypes.MENTIONABLE_SELECT: - case MessageComponentTypes.CHANNEL_SELECT: InteractionType = SelectMenuInteraction; break; + case MessageComponentTypes.CHANNEL_SELECT: + InteractionType = ChannelSelectInteraction; + break; + case MessageComponentTypes.MENTIONABLE_SELECT: + InteractionType = MentionableSelectInteraction; + break; + case MessageComponentTypes.ROLE_SELECT: + InteractionType = RoleSelectInteraction; + break; + case MessageComponentTypes.USER_SELECT: + InteractionType = UserSelectInteraction; + break; default: client.emit( Events.DEBUG, diff --git a/src/index.js b/src/index.js index c7e2571..028f2c3 100644 --- a/src/index.js +++ b/src/index.js @@ -151,8 +151,13 @@ exports.getUUID = require('./structures/RichPresence').getUUID; exports.CustomStatus = require('./structures/RichPresence').CustomStatus; exports.RichPresence = require('./structures/RichPresence').RichPresence; exports.SpotifyRPC = require('./structures/RichPresence').SpotifyRPC; +// SelectMenu +exports.ChannelSelectInteraction = require('./structures/SelectMenuInteraction').ChannelSelectInteraction; +exports.MentionableSelectInteraction = require('./structures/SelectMenuInteraction').MentionableSelectInteraction; +exports.RoleSelectInteraction = require('./structures/SelectMenuInteraction').RoleSelectInteraction; +exports.SelectMenuInteraction = require('./structures/SelectMenuInteraction').SelectMenuInteraction; +exports.UserSelectInteraction = require('./structures/SelectMenuInteraction').UserSelectInteraction; // -exports.SelectMenuInteraction = require('./structures/SelectMenuInteraction'); exports.StageChannel = require('./structures/StageChannel'); exports.StageInstance = require('./structures/StageInstance').StageInstance; exports.Sticker = require('./structures/Sticker').Sticker; diff --git a/src/structures/Interaction.js b/src/structures/Interaction.js index c79dc3f..1cbc74c 100644 --- a/src/structures/Interaction.js +++ b/src/structures/Interaction.js @@ -269,16 +269,71 @@ class Interaction extends Base { * Indicates whether this interaction is a {@link SelectMenuInteraction}. * @returns {boolean} */ + isAnySelectMenu() { + return InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && typeof this.values !== 'undefined'; + } + + /** + * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `STRING_SELECT` type. + * @returns {boolean} + * @deprecated Use {@link Interaction#isStringSelect()} instead + */ isSelectMenu() { + return this.isStringSelect(); + } + + /** + * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `STRING_SELECT` type. + * @returns {boolean} + */ + isStringSelect() { return ( InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && - [ - MessageComponentTypes.STRING_SELECT, - MessageComponentTypes.USER_SELECT, - MessageComponentTypes.ROLE_SELECT, - MessageComponentTypes.MENTIONABLE_SELECT, - MessageComponentTypes.CHANNEL_SELECT, - ].includes(MessageComponentTypes[this.componentType]) + MessageComponentTypes[this.componentType] === MessageComponentTypes.STRING_SELECT + ); + } + + /** + * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `USER_SELECT` type. + * @returns {boolean} + */ + isUserSelect() { + return ( + InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && + MessageComponentTypes[this.componentType] === MessageComponentTypes.USER_SELECT + ); + } + + /** + * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `ROLE_SELECT` type. + * @returns {boolean} + */ + isRoleSelect() { + return ( + InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && + MessageComponentTypes[this.componentType] === MessageComponentTypes.ROLE_SELECT + ); + } + + /** + * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `MENTIONABLE_SELECT` type. + * @returns {boolean} + */ + isMentionableSelect() { + return ( + InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && + MessageComponentTypes[this.componentType] === MessageComponentTypes.MENTIONABLE_SELECT + ); + } + + /** + * Indicates whether this interaction is a {@link SelectMenuInteraction} with a `CHANNEL_SELECT` type. + * @returns {boolean} + */ + isChannelSelect() { + return ( + InteractionTypes[this.type] === InteractionTypes.MESSAGE_COMPONENT && + MessageComponentTypes[this.componentType] === MessageComponentTypes.CHANNEL_SELECT ); } diff --git a/src/structures/MessageSelectMenu.js b/src/structures/MessageSelectMenu.js index bc2b42e..03db2e3 100644 --- a/src/structures/MessageSelectMenu.js +++ b/src/structures/MessageSelectMenu.js @@ -2,11 +2,16 @@ const { setTimeout } = require('node:timers'); const BaseMessageComponent = require('./BaseMessageComponent'); -const { MessageComponentTypes, InteractionTypes, ChannelTypes } = require('../util/Constants'); +const { + ChannelTypes, + MessageComponentTypes, + SelectMenuComponentTypes, + InteractionTypes, +} = require('../util/Constants'); const SnowflakeUtil = require('../util/SnowflakeUtil'); -const Util = require('../util/Util'); const { lazy } = require('../util/Util'); const Message = lazy(() => require('./Message').Message); +const Util = require('../util/Util'); /** * Represents a select menu message component @@ -98,28 +103,6 @@ class MessageSelectMenu extends BaseMessageComponent { ) ?? []; } - /** - * @typedef {string} SelectMenuTypes - * Must be one of: - * * `STRING_SELECT` - * * `USER_SELECT` - * * `ROLE_SELECT` - * * `MENTIONABLE_SELECT` - * * `CHANNEL_SELECT` - */ - - /** - * Set type of select menu - * @param {SelectMenuTypes} type Type of select menu - * @returns {MessageSelectMenu} - */ - - setType(type) { - if (!type) type = MessageComponentTypes.STRING_SELECT; - this.type = MessageSelectMenu.resolveType(type); - return this; - } - /** * Adds the channel types to the select menu * @param {...ChannelType[]} channelTypes Added channel types @@ -201,6 +184,17 @@ class MessageSelectMenu extends BaseMessageComponent { return this; } + /** + * Sets the type of the select menu + * @param {SelectMenuComponentType} type Type of the select menu + * @returns {MessageSelectMenu} + */ + setType(type) { + if (!SelectMenuComponentTypes[type]) throw new TypeError('INVALID_TYPE', 'type', 'SelectMenuComponentType'); + this.type = BaseMessageComponent.resolveType(type); + return this; + } + /** * Adds options to the select menu. * @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The options to add @@ -239,13 +233,13 @@ class MessageSelectMenu extends BaseMessageComponent { */ toJSON() { return { + channel_types: this.channelTypes.map(type => (typeof type === 'string' ? ChannelTypes[type] : type)), custom_id: this.customId, disabled: this.disabled, placeholder: this.placeholder, min_values: this.minValues, max_values: this.maxValues ?? (this.minValues ? this.options.length : undefined), options: this.options, - channel_types: this.channelTypes.map(type => (typeof type === 'string' ? ChannelTypes[type] : type)), type: typeof this.type === 'string' ? MessageComponentTypes[this.type] : this.type, }; } @@ -266,10 +260,6 @@ class MessageSelectMenu extends BaseMessageComponent { return { label, value, description, emoji, default: option.default ?? false }; } - static resolveType(type) { - return typeof type === 'string' ? type : MessageComponentTypes[type]; - } - /** * Normalizes option input and resolves strings and emojis. * @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The select menu options to normalize @@ -278,6 +268,7 @@ class MessageSelectMenu extends BaseMessageComponent { static normalizeOptions(...options) { return options.flat(Infinity).map(option => this.normalizeOption(option)); } + // Add /** * Mesage select menu diff --git a/src/structures/SelectMenuInteraction.js b/src/structures/SelectMenuInteraction.js index 42ef0c1..f0663cf 100644 --- a/src/structures/SelectMenuInteraction.js +++ b/src/structures/SelectMenuInteraction.js @@ -1,9 +1,11 @@ 'use strict'; +const { Collection } = require('@discordjs/collection'); const MessageComponentInteraction = require('./MessageComponentInteraction'); +const { Events } = require('../util/Constants'); /** - * Represents a select menu interaction. + * Represents any select menu interaction. * @extends {MessageComponentInteraction} */ class SelectMenuInteraction extends MessageComponentInteraction { @@ -18,4 +20,151 @@ class SelectMenuInteraction extends MessageComponentInteraction { } } -module.exports = SelectMenuInteraction; +module.exports.SelectMenuInteraction = SelectMenuInteraction; + +/** + * Represents a CHANNEL_SELECT interaction. + * @extends {SelectMenuInteraction} + */ +class ChannelSelectInteraction extends SelectMenuInteraction { + constructor(client, data) { + super(client, data); + + const { channels } = data.data.resolved ?? {}; + + /** + * Collection of the selected channels + * @type {Collection} + */ + this.channels = new Collection(); + for (const channel of Object.values(channels)) { + this.channel.set(channel.id, this.client.channels._add(channel)); + } + } +} + +module.exports.ChannelSelectInteraction = ChannelSelectInteraction; + +/** + * Represents a ROLE_SELECT interaction. + * @extends {SelectMenuInteraction} + */ +class RoleSelectInteraction extends SelectMenuInteraction { + constructor(client, data) { + super(client, data); + + const { roles } = data.data.resolved ?? {}; + + /** + * Collection of the selected roles + * @type {Collection} + */ + this.roles = new Collection(); + for (const role of Object.values(roles)) { + this.roles.set(role.id, this.guild?.roles._add(role) ?? role); + } + } +} + +module.exports.RoleSelectInteraction = RoleSelectInteraction; + +/** + * Represents a USER_SELECT interaction. + * @extends {SelectMenuInteraction} + */ +class UserSelectInteraction extends SelectMenuInteraction { + constructor(client, data) { + super(client, data); + + const { members, users } = data.data.resolved ?? {}; + + /** + * Collection of the selected users + * @type {Collection} + */ + this.users = new Collection(); + for (const user of Object.values(users)) { + this.users.set(user.id, this.client.users._add(user)); + } + + if (members) { + /** + * Collection of the selected members + * @type {Collection} + */ + this.members = new Collection(); + for (const [id, member] of Object.entries(members)) { + const user = users[id]; + if (!user) { + this.client.emit(Events.DEBUG, `[SelectMenuInteraction] Received a member without a user, skipping ${id}`); + continue; + } + this.members.set(id, this.guild?.members._add({ user, ...member }) ?? { user, ...member }); + } + } + } +} + +module.exports.UserSelectInteraction = UserSelectInteraction; + +/** + * Represents a MENTIONABLE_SELECT interaction. + * @extends {SelectMenuInteraction} + */ +class MentionableSelectInteraction extends SelectMenuInteraction { + constructor(client, data) { + super(client, data); + + const { members, users, roles, channels } = data.data.resolved ?? {}; + + if (channels) { + /** + * Collection of the selected channels + * @type {Collection} + */ + this.channels = new Collection(); + for (const channel of Object.values(channels)) { + this.channels.set(channel.id, this.client?.channels._add(channel) ?? channel); + } + } + + if (members) { + /** + * Collection of the selected members + * @type {Collection} + */ + this.members = new Collection(); + for (const [id, member] of Object.entries(members)) { + const user = users[id]; + if (!user) { + this.client.emit(Events.DEBUG, `[SelectMenuInteraction] Received a member without a user, skipping ${id}`); + continue; + } + this.members.set(id, this.guild?.members._add({ user, ...member }) ?? { user, ...member }); + } + } + + if (roles) { + /** + * Collection of the selected roles + * @type {Collection} + */ + this.roles = new Collection(); + for (const role of Object.values(roles)) { + this.roles.set(role.id, this.guild?.roles._add(role) ?? role); + } + } + + if (users) { + /** + * Collection of the selected users + * @type {Collection} + */ + this.users = new Collection(); + for (const user of Object.values(users)) { + this.users.set(user.id, this.client.users._add(user)); + } + } + } +} +module.exports.MentionableSelectInteraction = MentionableSelectInteraction; diff --git a/src/util/Constants.js b/src/util/Constants.js index 4b0298d..205ca85 100644 --- a/src/util/Constants.js +++ b/src/util/Constants.js @@ -1620,29 +1620,37 @@ exports.InteractionResponseTypes = createEnum([ * The type of a message component * * ACTION_ROW * * BUTTON - * * STRING_SELECT * * TEXT_INPUT + * * STRING_SELECT * * USER_SELECT * * ROLE_SELECT * * MENTIONABLE_SELECT * * CHANNEL_SELECT + * * SELECT_MENU (deprecated) * @typedef {string} MessageComponentType * @see {@link https://discord.com/developers/docs/interactions/message-components#component-object-component-types} */ -exports.MessageComponentTypes = createEnum([ - null, - 'ACTION_ROW', - 'BUTTON', - 'STRING_SELECT', - 'TEXT_INPUT', - 'USER_SELECT', - 'ROLE_SELECT', - 'MENTIONABLE_SELECT', - 'CHANNEL_SELECT', -]); +exports.MessageComponentTypes = { + ...createEnum([ + null, + 'ACTION_ROW', + 'BUTTON', + 'STRING_SELECT', + 'TEXT_INPUT', + 'USER_SELECT', + 'ROLE_SELECT', + 'MENTIONABLE_SELECT', + 'CHANNEL_SELECT', + ]), + /** @deprecated Use `STRING_SELECT` instead */ + SELECT_MENU: 3, + /** @deprecated Use `STRING_SELECT` instead */ + 3: 'SELECT_MENU', +}; /** * The types of components that are select menus. The available types are: + * * SELECT_MENU (deprecated) * * STRING_MENU * * USER_SELECT * * ROLE_SELECT @@ -1651,15 +1659,19 @@ exports.MessageComponentTypes = createEnum([ * @typedef {string} SelectMenuComponentType * @see {@link https://discord.com/developers/docs/interactions/message-components#component-object-component-types} */ -exports.SelectMenuComponentTypes = createEnum([ - ...new Array(3).fill(null), - 'STRING_MENU', - null, - 'USER_SELECT', - 'ROLE_SELECT', - 'MENTIONABLE_SELECT', - 'CHANNEL_SELECT', -]); +exports.SelectMenuComponentTypes = { + ...createEnum([ + ...new Array(3).fill(null), + 'STRING_MENU', + null, + 'USER_SELECT', + 'ROLE_SELECT', + 'MENTIONABLE_SELECT', + 'CHANNEL_SELECT', + ]), + /** @deprecated Use `STRING_SELECT` instead */ + SELECT_MENU: 3, +}; /** * The style of a message button @@ -1861,7 +1873,7 @@ function createEnum(keys) { * @property {Object} MembershipStates The value set for a team members membership state. * @property {Object} MessageButtonStyles The style of a message button. * @property {Object} MessageComponentTypes The type of a message component. - * @property {Object} SelectMenuComponentTypes The type of any select menu + * @property {Object} SelectMenuComponentTypes The type of any select menu. * @property {Object} MFALevels The required MFA level for a guild. * @property {Object} NSFWLevels NSFW level of a guild. * @property {Opcodes} Opcodes The types of Opcodes sent to the Gateway. diff --git a/typings/enums.d.ts b/typings/enums.d.ts index a8ce2d7..756a7d6 100644 --- a/typings/enums.d.ts +++ b/typings/enums.d.ts @@ -249,6 +249,8 @@ export const enum MessageButtonStyles { export const enum MessageComponentTypes { ACTION_ROW = 1, BUTTON = 2, + /** @deprecated Use `STRING_SELECT` instead */ + SELECT_MENU = 3, STRING_SELECT = 3, TEXT_INPUT = 4, USER_SELECT = 5, @@ -258,6 +260,8 @@ export const enum MessageComponentTypes { } export const enum SelectMenuComponentTypes { + /** @deprecated Use `STRING_SELECT` instead */ + SELECT_MENU = 3, STRING_SELECT = 3, USER_SELECT = 5, ROLE_SELECT = 6, diff --git a/typings/index.d.ts b/typings/index.d.ts index e4e7436..8b21d19 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -53,6 +53,8 @@ import { RESTPostAPIApplicationCommandsJSONBody, Snowflake, LocalizationMap, + APIGuildMember, + APIChannel, } from 'discord-api-types/v9'; import { ChildProcess } from 'node:child_process'; import { EventEmitter } from 'node:events'; @@ -1856,7 +1858,14 @@ export class Interaction extends Base { public isMessageContextMenu(): this is MessageContextMenuInteraction; public isMessageComponent(): this is MessageComponentInteraction; public isModalSubmit(): this is ModalSubmitInteraction; - public isSelectMenu(): this is SelectMenuInteraction; + public isAnySelectMenu(): this is SelectMenuInteraction; + /** @deprecated Use {@link Interaction#isStringSelect()} instead */ + public isSelectMenu(): this is StringSelectInteraction; + public isStringSelect(): this is StringSelectInteraction; + public isUserSelect(): this is UserSelectInteraction; + public isMentionableSelect(): this is MentionableSelectInteraction; + public isRoleSelect(): this is RoleSelectInteraction; + public isChannelSelect(): this is ChannelSelectInteraction; public isRepliable(): this is this & InteractionResponseFields; } @@ -1980,12 +1989,14 @@ export type AwaitMessageCollectorOptionsParams< export interface StringMappedInteractionTypes { BUTTON: ButtonInteraction; - ACTION_ROW: MessageComponentInteraction; + /** @deprecated */ + SELECT_MENU: SelectMenuInteraction; STRING_SELECT: SelectMenuInteraction; USER_SELECT: SelectMenuInteraction; ROLE_SELECT: SelectMenuInteraction; MENTIONABLE_SELECT: SelectMenuInteraction; CHANNEL_SELECT: SelectMenuInteraction; + ACTION_ROW: MessageComponentInteraction; } export type WrapBooleanCache = If; @@ -1994,13 +2005,15 @@ export type MappedInteractionTypes = EnumValue typeof MessageComponentTypes, { BUTTON: ButtonInteraction>; + /** @deprecated */ + SELECT_MENU: StringSelectInteraction>; + STRING_SELECT: StringSelectInteraction>; + USER_SELECT: UserSelectInteraction>; + ROLE_SELECT: RoleSelectInteraction>; + MENTIONABLE_SELECT: MentionableSelectInteraction>; + CHANNEL_SELECT: ChannelSelectInteraction>; ACTION_ROW: MessageComponentInteraction>; TEXT_INPUT: ModalSubmitInteraction>; - STRING_SELECT: SelectMenuInteraction>; - USER_SELECT: SelectMenuInteraction>; - ROLE_SELECT: SelectMenuInteraction>; - MENTIONABLE_SELECT: SelectMenuInteraction>; - CHANNEL_SELECT: SelectMenuInteraction>; } >; @@ -2369,6 +2382,7 @@ export class MessageReaction { export class MessageSelectMenu extends BaseMessageComponent { public constructor(data?: MessageSelectMenu | MessageSelectMenuOptions | APISelectMenuComponent); + public channelTypes: ChannelTypes[]; public customId: string | null; public disabled: boolean; public maxValues: number | null; @@ -2376,17 +2390,16 @@ export class MessageSelectMenu extends BaseMessageComponent { public options: MessageSelectOption[]; public placeholder: string | null; public type: SelectMenuComponentType; - public channelTypes: ChannelTypes[]; + public addChannelTypes(...channelTypes: ChannelTypes[]): this; public addOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this; public setOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this; - public setType(type: SelectMenuComponentType | SelectMenuComponentTypes): this; - public addChannelTypes(...channelTypes: ChannelTypes[]): this; public setChannelTypes(...channelTypes: ChannelTypes[]): this; public setCustomId(customId: string): this; public setDisabled(disabled?: boolean): this; public setMaxValues(maxValues: number): this; public setMinValues(minValues: number): this; public setPlaceholder(placeholder: string): this; + public setType(type: SelectMenuComponentType | SelectMenuComponentTypes): this; public spliceOptions( index: number, deleteCount: number, @@ -2396,7 +2409,6 @@ export class MessageSelectMenu extends BaseMessageComponent { public select(message: Message, values?: any[]): Promise; } -// Todo export class Modal { public constructor(data?: Modal | ModalOptions); public components: MessageActionRow[]; @@ -2675,7 +2687,7 @@ export class Role extends Base { public static comparePositions(role1: Role, role2: Role): number; } -export class SelectMenuInteraction extends MessageComponentInteraction { +export class BaseSelectMenuInteraction extends MessageComponentInteraction { public constructor(client: Client, data: RawMessageSelectMenuInteractionData); public readonly component: CacheTypeReducer< Cached, @@ -2691,6 +2703,71 @@ export class SelectMenuInteraction extends public inRawGuild(): this is SelectMenuInteraction<'raw'>; } +export class ChannelSelectInteraction extends BaseSelectMenuInteraction { + public componentType: 'CHANNEL_SELECT'; + public channels: Collection< + Snowflake, + CacheTypeReducer + >; + public inGuild(): this is ChannelSelectInteraction<'raw' | 'cached'>; + public inCachedGuild(): this is ChannelSelectInteraction<'cached'>; + public inRawGuild(): this is ChannelSelectInteraction<'raw'>; +} + +export class MentionableSelectInteraction< + Cached extends CacheType = CacheType, +> extends BaseSelectMenuInteraction { + public componentType: 'MENTIONABLE_SELECT'; + public channels?: Collection< + Snowflake, + CacheTypeReducer + >; + public members?: Collection< + Snowflake, + CacheTypeReducer + >; + public roles?: Collection>; + public users?: Collection; + public inGuild(): this is MentionableSelectInteraction<'raw' | 'cached'>; + public inCachedGuild(): this is MentionableSelectInteraction<'cached'>; + public inRawGuild(): this is MentionableSelectInteraction<'raw'>; +} + +export class RoleSelectInteraction extends BaseSelectMenuInteraction { + public componentType: 'ROLE_SELECT'; + public roles: Collection>; + public inGuild(): this is RoleSelectInteraction<'raw' | 'cached'>; + public inCachedGuild(): this is RoleSelectInteraction<'cached'>; + public inRawGuild(): this is RoleSelectInteraction<'raw'>; +} + +export class StringSelectInteraction extends BaseSelectMenuInteraction { + public componentType: 'STRING_SELECT'; + public roles: Collection>; + public inGuild(): this is StringSelectInteraction<'raw' | 'cached'>; + public inCachedGuild(): this is StringSelectInteraction<'cached'>; + public inRawGuild(): this is StringSelectInteraction<'raw'>; +} + +export class UserSelectInteraction extends BaseSelectMenuInteraction { + public componentType: 'USER_SELECT'; + public members?: Collection< + Snowflake, + CacheTypeReducer + >; + public users: Collection; + public inGuild(): this is UserSelectInteraction<'raw' | 'cached'>; + public inCachedGuild(): this is UserSelectInteraction<'cached'>; + public inRawGuild(): this is UserSelectInteraction<'raw'>; +} + +export type SelectMenuInteraction = + | StringSelectInteraction + | ChannelSelectInteraction + | MentionableSelectInteraction + | RoleSelectInteraction + | UserSelectInteraction; + export interface ShardEventTypes { spawn: [process: ChildProcess | Worker]; death: [process: ChildProcess | Worker]; @@ -6742,7 +6819,11 @@ export interface BaseMessageSelectMenuOptions { placeholder?: string; } export interface StringMessageSelectMenuOptions extends BaseMessageSelectMenuOptions { - type?: 'STRING_SELECT' | SelectMenuComponentTypes.STRING_SELECT; + type?: + | 'STRING_SELECT' + | 'SELECT_MENU' + | SelectMenuComponentTypes.STRING_SELECT + | SelectMenuComponentTypes.SELECT_MENU; options?: MessageSelectOptionData[]; } @@ -7284,8 +7365,6 @@ export type VerificationLevel = keyof typeof VerificationLevels; export type VideoQualityMode = keyof typeof VideoQualityModes; -export type SelectMenuComponentType = keyof typeof SelectMenuComponentTypes; - export type VoiceBasedChannelTypes = VoiceBasedChannel['type']; export type VoiceChannelResolvable = Snowflake | VoiceChannel; @@ -7546,6 +7625,8 @@ export type GuildForumThreadMessageCreateOptions = MessageOptions & Pick; +export type SelectMenuComponentType = keyof typeof SelectMenuComponentTypes; + export interface GuildForumThreadCreateOptions extends StartThreadOptions { message: GuildForumThreadMessageCreateOptions | MessagePayload; appliedTags?: Snowflake[];