mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 20:43:30 +01:00
feat: new select menus (#8793)
* feat(builders): new select menus * chore: better re-exporting of deprecated classes * feat: new select menus * chore: typings * chore: add missing todo comment * chore: finish updating tests * chore: add runtime deprecation warnings * chore: format deprecation warning * feat(BaseInteraction): isAnySelectMenu * chore: requested changes * fix: deprecation comments * chore: update @deprecated comments in typings * chore: add tests for select menu type narrowing * fix: bad auto imports Co-authored-by: Julian Vennen <julian@aternos.org> * fix: properly handle resolved members * fix: collectors * chore: suggested changes Co-authored-by: Almeida <almeidx@pm.me> * fix(typings): bad class extends * feat(ChannelSelectMenuBuilder): validation * chore: update todo comment * refactor(ChannelSelectMenu): better handling of channel_types state * chore: style nit * chore: suggested nits Co-authored-by: Aura Román <kyradiscord@gmail.com> Co-authored-by: Julian Vennen <julian@aternos.org> Co-authored-by: Almeida <almeidx@pm.me> Co-authored-by: Aura Román <kyradiscord@gmail.com> Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
@@ -55,7 +55,7 @@
|
||||
"@discordjs/util": "workspace:^",
|
||||
"@sapphire/snowflake": "^3.2.2",
|
||||
"@types/ws": "^8.5.3",
|
||||
"discord-api-types": "^0.37.14",
|
||||
"discord-api-types": "^0.37.15",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash.snakecase": "^4.1.1",
|
||||
"tslib": "^2.4.0",
|
||||
|
||||
@@ -4,11 +4,15 @@ const { InteractionType, ComponentType, ApplicationCommandType } = require('disc
|
||||
const Action = require('./Action');
|
||||
const AutocompleteInteraction = require('../../structures/AutocompleteInteraction');
|
||||
const ButtonInteraction = require('../../structures/ButtonInteraction');
|
||||
const ChannelSelectMenuInteraction = require('../../structures/ChannelSelectMenuInteraction');
|
||||
const ChatInputCommandInteraction = require('../../structures/ChatInputCommandInteraction');
|
||||
const MentionableSelectMenuInteraction = require('../../structures/MentionableSelectMenuInteraction');
|
||||
const MessageContextMenuCommandInteraction = require('../../structures/MessageContextMenuCommandInteraction');
|
||||
const ModalSubmitInteraction = require('../../structures/ModalSubmitInteraction');
|
||||
const SelectMenuInteraction = require('../../structures/SelectMenuInteraction');
|
||||
const RoleSelectMenuInteraction = require('../../structures/RoleSelectMenuInteraction');
|
||||
const StringSelectMenuInteraction = require('../../structures/StringSelectMenuInteraction');
|
||||
const UserContextMenuCommandInteraction = require('../../structures/UserContextMenuCommandInteraction');
|
||||
const UserSelectMenuInteraction = require('../../structures/UserSelectMenuInteraction');
|
||||
const Events = require('../../util/Events');
|
||||
|
||||
class InteractionCreateAction extends Action {
|
||||
@@ -49,8 +53,20 @@ class InteractionCreateAction extends Action {
|
||||
case ComponentType.Button:
|
||||
InteractionClass = ButtonInteraction;
|
||||
break;
|
||||
case ComponentType.SelectMenu:
|
||||
InteractionClass = SelectMenuInteraction;
|
||||
case ComponentType.StringSelect:
|
||||
InteractionClass = StringSelectMenuInteraction;
|
||||
break;
|
||||
case ComponentType.UserSelect:
|
||||
InteractionClass = UserSelectMenuInteraction;
|
||||
break;
|
||||
case ComponentType.RoleSelect:
|
||||
InteractionClass = RoleSelectMenuInteraction;
|
||||
break;
|
||||
case ComponentType.MentionableSelect:
|
||||
InteractionClass = MentionableSelectMenuInteraction;
|
||||
break;
|
||||
case ComponentType.ChannelSelect:
|
||||
InteractionClass = ChannelSelectMenuInteraction;
|
||||
break;
|
||||
default:
|
||||
client.emit(
|
||||
|
||||
@@ -154,9 +154,27 @@ exports.ReactionEmoji = require('./structures/ReactionEmoji');
|
||||
exports.RichPresenceAssets = require('./structures/Presence').RichPresenceAssets;
|
||||
exports.Role = require('./structures/Role').Role;
|
||||
exports.SelectMenuBuilder = require('./structures/SelectMenuBuilder');
|
||||
exports.ChannelSelectMenuBuilder = require('./structures/ChannelSelectMenuBuilder');
|
||||
exports.MentionableSelectMenuBuilder = require('./structures/MentionableSelectMenuBuilder');
|
||||
exports.RoleSelectMenuBuilder = require('./structures/RoleSelectMenuBuilder');
|
||||
exports.StringSelectMenuBuilder = require('./structures/StringSelectMenuBuilder');
|
||||
exports.UserSelectMenuBuilder = require('./structures/UserSelectMenuBuilder');
|
||||
exports.BaseSelectMenuComponent = require('./structures/BaseSelectMenuComponent');
|
||||
exports.SelectMenuComponent = require('./structures/SelectMenuComponent');
|
||||
exports.ChannelSelectMenuComponent = require('./structures/ChannelSelectMenuComponent');
|
||||
exports.MentionableSelectMenuComponent = require('./structures/MentionableSelectMenuComponent');
|
||||
exports.RoleSelectMenuComponent = require('./structures/RoleSelectMenuComponent');
|
||||
exports.StringSelectMenuComponent = require('./structures/StringSelectMenuComponent');
|
||||
exports.UserSelectMenuComponent = require('./structures/UserSelectMenuComponent');
|
||||
exports.SelectMenuInteraction = require('./structures/SelectMenuInteraction');
|
||||
exports.ChannelSelectMenuInteraction = require('./structures/ChannelSelectMenuInteraction');
|
||||
exports.MentionableSelectMenuInteraction = require('./structures/MentionableSelectMenuInteraction');
|
||||
exports.MentionableSelectMenuInteraction = require('./structures/MentionableSelectMenuInteraction');
|
||||
exports.RoleSelectMenuInteraction = require('./structures/RoleSelectMenuInteraction');
|
||||
exports.StringSelectMenuInteraction = require('./structures/StringSelectMenuInteraction');
|
||||
exports.UserSelectMenuInteraction = require('./structures/UserSelectMenuInteraction');
|
||||
exports.SelectMenuOptionBuilder = require('./structures/SelectMenuOptionBuilder');
|
||||
exports.StringSelectMenuOptionBuilder = require('./structures/StringSelectMenuOptionBuilder');
|
||||
exports.StageChannel = require('./structures/StageChannel');
|
||||
exports.StageInstance = require('./structures/StageInstance').StageInstance;
|
||||
exports.Sticker = require('./structures/Sticker').Sticker;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
'use strict';
|
||||
|
||||
const { deprecate } = require('node:util');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const { InteractionType, ApplicationCommandType, ComponentType } = require('discord-api-types/v10');
|
||||
const Base = require('./Base');
|
||||
const { SelectMenuTypes } = require('../util/Constants');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
|
||||
/**
|
||||
@@ -268,12 +270,63 @@ class BaseInteraction extends Base {
|
||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.Button;
|
||||
}
|
||||
|
||||
// TODO: Get rid of this in the next major
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link SelectMenuInteraction}.
|
||||
* Indicates whether this interaction is a {@link StringSelectMenuInteraction}.
|
||||
* @returns {boolean}
|
||||
*
|
||||
* @deprecated Use {@link Interaction#isStringSelectMenu} instead
|
||||
*/
|
||||
isSelectMenu() {
|
||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.SelectMenu;
|
||||
return this.isStringSelectMenu();
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a select menu of any known type.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isAnySelectMenu() {
|
||||
return this.type === InteractionType.MessageComponent && SelectMenuTypes.includes(this.componentType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link StringSelectMenuInteraction}.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isStringSelectMenu() {
|
||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.StringSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link UserSelectMenuInteraction}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isUserSelectMenu() {
|
||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.UserSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link RoleSelectMenuInteraction}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isRoleSelectMenu() {
|
||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.RoleSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link ChannelSelectMenuInteraction}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isChannelSelectMenu() {
|
||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.ChannelSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether this interaction is a {@link MenionableSelectMenuInteraction}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
isMentionableSelectMenu() {
|
||||
return this.type === InteractionType.MessageComponent && this.componentType === ComponentType.MentionableSelect;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,4 +338,9 @@ class BaseInteraction extends Base {
|
||||
}
|
||||
}
|
||||
|
||||
BaseInteraction.prototype.isSelectMenu = deprecate(
|
||||
BaseInteraction.prototype.isSelectMenu,
|
||||
'BaseInteraction#isSelectMenu() is deprecated. Use BaseInteraction#isStringSelectMenu() instead.',
|
||||
);
|
||||
|
||||
module.exports = BaseInteraction;
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
'use strict';
|
||||
|
||||
const Component = require('./Component');
|
||||
|
||||
/**
|
||||
* Represents a select menu component
|
||||
* @extends {Component}
|
||||
*/
|
||||
class BaseSelectMenuComponent extends Component {
|
||||
/**
|
||||
* The placeholder for this select menu
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get placeholder() {
|
||||
return this.data.placeholder ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum amount of options that can be selected
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get maxValues() {
|
||||
return this.data.max_values ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum amount of options that must be selected
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get minValues() {
|
||||
return this.data.min_values ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id of this select menu
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
get customId() {
|
||||
return this.data.custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this select menu is disabled
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get disabled() {
|
||||
return this.data.disabled ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = BaseSelectMenuComponent;
|
||||
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const { ChannelSelectMenuBuilder: BuildersChannelSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
* Class used to build select menu components to be sent through the API
|
||||
* @extends {BuildersChannelSelectMenu}
|
||||
*/
|
||||
class ChannelSelectMenuBuilder extends BuildersChannelSelectMenu {
|
||||
constructor(data = {}) {
|
||||
super(toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @returns {ChannelSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChannelSelectMenuBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersChannelSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/ChannelSelectMenuBuilder}
|
||||
*/
|
||||
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||
|
||||
/**
|
||||
* Represents a channel select menu component
|
||||
* @extends {BaseSelectMenuComponent}
|
||||
*/
|
||||
class ChannelSelectMenuComponent extends BaseSelectMenuComponent {
|
||||
/**
|
||||
* The options in this select menu
|
||||
* @type {?(ChannelType[])}
|
||||
* @readonly
|
||||
*/
|
||||
get channelTypes() {
|
||||
return this.data.channel_types ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChannelSelectMenuComponent;
|
||||
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||
|
||||
/**
|
||||
* Represents a {@link ComponentType.ChannelSelect} select menu interaction.
|
||||
* @extends {MessageComponentInteraction}
|
||||
*/
|
||||
class ChannelSelectMenuInteraction extends MessageComponentInteraction {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
|
||||
/**
|
||||
* Collection of the selected channels
|
||||
* @type {Collection<Snowflake, Channel|APIChannel>}
|
||||
*/
|
||||
this.channels = new Collection();
|
||||
for (const channel of Object.values(data.data.resolved.channels)) {
|
||||
this.channels.set(channel.id, this.client.channels._add(channel, this.guild) ?? channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ChannelSelectMenuInteraction;
|
||||
@@ -147,10 +147,17 @@ class InteractionCollector extends Collector {
|
||||
* @event InteractionCollector#collect
|
||||
* @param {BaseInteraction} interaction The interaction that was collected
|
||||
*/
|
||||
|
||||
if (this.interactionType && interaction.type !== this.interactionType) return null;
|
||||
if (this.componentType && interaction.componentType !== this.componentType) return null;
|
||||
if (this.messageId && interaction.message?.id !== this.messageId) return null;
|
||||
if (this.messageInteractionId && interaction.message?.interaction?.id !== this.messageInteractionId) return null;
|
||||
if (
|
||||
this.messageInteractionId &&
|
||||
interaction.message?.interaction?.id &&
|
||||
interaction.message.interaction.id !== this.messageInteractionId
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
if (this.channelId && interaction.channelId !== this.channelId) return null;
|
||||
if (this.guildId && interaction.guildId !== this.guildId) return null;
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const { MentionableSelectMenuBuilder: BuildersMentionableSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
* Class used to build select menu components to be sent through the API
|
||||
* @extends {BuildersMentionableSelectMenu}
|
||||
*/
|
||||
class MentionableSelectMenuBuilder extends BuildersMentionableSelectMenu {
|
||||
constructor(data = {}) {
|
||||
super(toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @returns {MentionableSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MentionableSelectMenuBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersMentionableSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/MentionableSelectMenuBuilder}
|
||||
*/
|
||||
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||
|
||||
/**
|
||||
* Represents a mentionable select menu component
|
||||
* @extends {BaseSelectMenuComponent}
|
||||
*/
|
||||
class MentionableSelectMenuComponent extends BaseSelectMenuComponent {}
|
||||
|
||||
module.exports = MentionableSelectMenuComponent;
|
||||
@@ -0,0 +1,65 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||
const Events = require('../util/Events');
|
||||
|
||||
/**
|
||||
* Represents a {@link ComponentType.MentionableSelect} select menu interaction.
|
||||
* @extends {MessageComponentInteraction}
|
||||
*/
|
||||
class MentionableSelectMenuInteraction extends MessageComponentInteraction {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
|
||||
const { members, users, roles } = data.data.resolved ?? {};
|
||||
|
||||
/**
|
||||
* Collection of the selected users
|
||||
* @type {Collection<Snowflake, User>}
|
||||
*/
|
||||
this.users = new Collection();
|
||||
|
||||
/**
|
||||
* Collection of the selected users
|
||||
* @type {Collection<Snowflake, GuildMember|APIGuildMember>}
|
||||
*/
|
||||
this.members = new Collection();
|
||||
|
||||
/**
|
||||
* Collection of the selected roles
|
||||
* @type {Collection<Snowflake, Role|APIRole>}
|
||||
*/
|
||||
this.roles = new Collection();
|
||||
|
||||
if (members) {
|
||||
for (const [id, member] of Object.entries(members)) {
|
||||
const user = users[id];
|
||||
if (!user) {
|
||||
this.client.emit(
|
||||
Events.Debug,
|
||||
`[MentionableSelectMenuInteraction] Received a member without a user, skipping ${id}`,
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.members.set(id, this.guild?.members._add({ user, ...member }) ?? { user, ...member });
|
||||
}
|
||||
}
|
||||
|
||||
if (users) {
|
||||
for (const user of Object.values(users)) {
|
||||
this.users.set(user.id, this.client.users._add(user));
|
||||
}
|
||||
}
|
||||
|
||||
if (roles) {
|
||||
for (const role of Object.values(roles)) {
|
||||
this.roles.set(role.id, this.guild?.roles._add(role) ?? role);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = MentionableSelectMenuInteraction;
|
||||
33
packages/discord.js/src/structures/RoleSelectMenuBuilder.js
Normal file
33
packages/discord.js/src/structures/RoleSelectMenuBuilder.js
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const { RoleSelectMenuBuilder: BuildersRoleSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
* Class used to build select menu components to be sent through the API
|
||||
* @extends {BuildersRoleSelectMenu}
|
||||
*/
|
||||
class RoleSelectMenuBuilder extends BuildersRoleSelectMenu {
|
||||
constructor(data = {}) {
|
||||
super(toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @returns {RoleSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RoleSelectMenuBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersRoleSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/RoleSelectMenuBuilder}
|
||||
*/
|
||||
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||
|
||||
/**
|
||||
* Represents a role select menu component
|
||||
* @extends {BaseSelectMenuComponent}
|
||||
*/
|
||||
class RoleSelectMenuComponent extends BaseSelectMenuComponent {}
|
||||
|
||||
module.exports = RoleSelectMenuComponent;
|
||||
@@ -0,0 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||
|
||||
/**
|
||||
* Represents a {@link ComponentType.RoleSelect} select menu interaction.
|
||||
* @extends {MessageComponentInteraction}
|
||||
*/
|
||||
class RoleSelectMenuInteraction extends MessageComponentInteraction {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
|
||||
/**
|
||||
* Collection of the selected roles
|
||||
* @type {Collection<Snowflake, Role|APIRole>}
|
||||
*/
|
||||
this.roles = new Collection();
|
||||
for (const role of Object.values(data.data.resolved.roles)) {
|
||||
this.roles.set(role.id, this.guild?.roles._add(role) ?? role);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = RoleSelectMenuInteraction;
|
||||
@@ -1,78 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const { SelectMenuBuilder: BuildersSelectMenu, isJSONEncodable, normalizeArray } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
const process = require('node:process');
|
||||
const StringSelectMenuBuilder = require('./StringSelectMenuBuilder');
|
||||
|
||||
let deprecationEmitted = false;
|
||||
|
||||
/**
|
||||
* Class used to build select menu components to be sent through the API
|
||||
* @extends {BuildersSelectMenu}
|
||||
* @deprecated Use {@link StringSelectMenuBuilder} instead.
|
||||
*/
|
||||
class SelectMenuBuilder extends BuildersSelectMenu {
|
||||
constructor({ options, ...data } = {}) {
|
||||
super(
|
||||
toSnakeCase({
|
||||
...data,
|
||||
options: options?.map(({ emoji, ...option }) => ({
|
||||
...option,
|
||||
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||
})),
|
||||
}),
|
||||
);
|
||||
}
|
||||
class SelectMenuBuilder extends StringSelectMenuBuilder {
|
||||
constructor(...params) {
|
||||
super(...params);
|
||||
|
||||
/**
|
||||
* Normalizes a select menu option emoji
|
||||
* @param {SelectMenuOptionData|JSONEncodable<APISelectMenuOption>} selectMenuOption The option to normalize
|
||||
* @returns {Array<SelectMenuOptionBuilder|APISelectMenuOption>}
|
||||
* @private
|
||||
*/
|
||||
static normalizeEmoji(selectMenuOption) {
|
||||
if (isJSONEncodable(selectMenuOption)) {
|
||||
return selectMenuOption;
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuBuilder class is deprecated, use StringSelectMenuBuilder instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
}
|
||||
|
||||
const { emoji, ...option } = selectMenuOption;
|
||||
return {
|
||||
...option,
|
||||
emoji: typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options to this select menu
|
||||
* @param {RestOrArray<APISelectMenuOption>} options The options to add to this select menu
|
||||
* @returns {SelectMenuBuilder}
|
||||
*/
|
||||
addOptions(...options) {
|
||||
return super.addOptions(normalizeArray(options).map(option => SelectMenuBuilder.normalizeEmoji(option)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options on this select menu
|
||||
* @param {RestOrArray<APISelectMenuOption>} options The options to set on this select menu
|
||||
* @returns {SelectMenuBuilder}
|
||||
*/
|
||||
setOptions(...options) {
|
||||
return super.setOptions(normalizeArray(options).map(option => SelectMenuBuilder.normalizeEmoji(option)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @returns {SelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SelectMenuBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuBuilder}
|
||||
*/
|
||||
|
||||
@@ -1,64 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const Component = require('./Component');
|
||||
const process = require('node:process');
|
||||
const StringSelectMenuComponent = require('./StringSelectMenuComponent');
|
||||
|
||||
let deprecationEmitted = false;
|
||||
|
||||
/**
|
||||
* Represents a select menu component
|
||||
* @extends {Component}
|
||||
* @deprecated Use {@link StringSelectMenuComponent} instead.
|
||||
*/
|
||||
class SelectMenuComponent extends Component {
|
||||
/**
|
||||
* The placeholder for this select menu
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get placeholder() {
|
||||
return this.data.placeholder ?? null;
|
||||
}
|
||||
class SelectMenuComponent extends StringSelectMenuComponent {
|
||||
constructor(...params) {
|
||||
super(...params);
|
||||
|
||||
/**
|
||||
* The maximum amount of options that can be selected
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get maxValues() {
|
||||
return this.data.max_values ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum amount of options that must be selected
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get minValues() {
|
||||
return this.data.min_values ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id of this select menu
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
get customId() {
|
||||
return this.data.custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this select menu is disabled
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get disabled() {
|
||||
return this.data.disabled ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The options in this select menu
|
||||
* @type {APISelectMenuOption[]}
|
||||
* @readonly
|
||||
*/
|
||||
get options() {
|
||||
return this.data.options;
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuComponent class is deprecated, use StringSelectMenuComponent instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||
const process = require('node:process');
|
||||
const StringSelectMenuInteraction = require('./StringSelectMenuInteraction');
|
||||
|
||||
let deprecationEmitted = false;
|
||||
|
||||
/**
|
||||
* Represents a select menu interaction.
|
||||
* @extends {MessageComponentInteraction}
|
||||
* @deprecated Use {@link StringSelectMenuInteraction} instead.
|
||||
*/
|
||||
class SelectMenuInteraction extends MessageComponentInteraction {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
class SelectMenuInteraction extends StringSelectMenuInteraction {
|
||||
constructor(...params) {
|
||||
super(...params);
|
||||
|
||||
/**
|
||||
* The values selected, if the component which was interacted with was a select menu
|
||||
* @type {string[]}
|
||||
*/
|
||||
this.values = data.data.values ?? [];
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuInteraction class is deprecated, use StringSelectMenuInteraction instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,50 +1,25 @@
|
||||
'use strict';
|
||||
|
||||
const { SelectMenuOptionBuilder: BuildersSelectMenuOption, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
const process = require('node:process');
|
||||
const StringSelectMenuOptionBuilder = require('./StringSelectMenuOptionBuilder');
|
||||
|
||||
let deprecationEmitted = false;
|
||||
|
||||
/**
|
||||
* Represents a select menu option builder.
|
||||
* @extends {BuildersSelectMenuOption}
|
||||
* @deprecated Use {@link StringSelectMenuOptionBuilder} instead.
|
||||
*/
|
||||
class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
||||
constructor({ emoji, ...data } = {}) {
|
||||
super(
|
||||
toSnakeCase({
|
||||
...data,
|
||||
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||
}),
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Sets the emoji to display on this option
|
||||
* @param {ComponentEmojiResolvable} emoji The emoji to display on this option
|
||||
* @returns {SelectMenuOptionBuilder}
|
||||
*/
|
||||
setEmoji(emoji) {
|
||||
if (typeof emoji === 'string') {
|
||||
return super.setEmoji(resolvePartialEmoji(emoji));
|
||||
}
|
||||
return super.setEmoji(emoji);
|
||||
}
|
||||
class SelectMenuOptionBuilder extends StringSelectMenuOptionBuilder {
|
||||
constructor(...params) {
|
||||
super(...params);
|
||||
|
||||
/**
|
||||
* Creates a new select menu option builder from JSON data
|
||||
* @param {JSONEncodable<APISelectMenuOption>|APISelectMenuOption} other The other data
|
||||
* @returns {SelectMenuOptionBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
if (!deprecationEmitted) {
|
||||
process.emitWarning(
|
||||
'The SelectMenuOptionBuilder class is deprecated, use StringSelectMenuOptionBuilder instead.',
|
||||
'DeprecationWarning',
|
||||
);
|
||||
deprecationEmitted = true;
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SelectMenuOptionBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersSelectMenuOption
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuOptionBuilder}
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
'use strict';
|
||||
|
||||
const { SelectMenuBuilder: BuildersSelectMenu, isJSONEncodable, normalizeArray } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
|
||||
/**
|
||||
* Class used to build select menu components to be sent through the API
|
||||
* @extends {BuildersSelectMenu}
|
||||
*/
|
||||
class StringSelectMenuBuilder extends BuildersSelectMenu {
|
||||
constructor({ options, ...data } = {}) {
|
||||
super(
|
||||
toSnakeCase({
|
||||
...data,
|
||||
options: options?.map(({ emoji, ...option }) => ({
|
||||
...option,
|
||||
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||
})),
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Normalizes a select menu option emoji
|
||||
* @param {SelectMenuOptionData|JSONEncodable<APISelectMenuOption>} selectMenuOption The option to normalize
|
||||
* @returns {SelectMenuOptionBuilder|APISelectMenuOption}
|
||||
* @private
|
||||
*/
|
||||
static normalizeEmoji(selectMenuOption) {
|
||||
if (isJSONEncodable(selectMenuOption)) {
|
||||
return selectMenuOption;
|
||||
}
|
||||
|
||||
const { emoji, ...option } = selectMenuOption;
|
||||
return {
|
||||
...option,
|
||||
emoji: typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds options to this select menu
|
||||
* @param {RestOrArray<APISelectMenuOption>} options The options to add to this select menu
|
||||
* @returns {StringSelectMenuBuilder}
|
||||
*/
|
||||
addOptions(...options) {
|
||||
return super.addOptions(normalizeArray(options).map(option => StringSelectMenuBuilder.normalizeEmoji(option)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the options on this select menu
|
||||
* @param {RestOrArray<APISelectMenuOption>} options The options to set on this select menu
|
||||
* @returns {StringSelectMenuBuilder}
|
||||
*/
|
||||
setOptions(...options) {
|
||||
return super.setOptions(normalizeArray(options).map(option => StringSelectMenuBuilder.normalizeEmoji(option)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @returns {StringSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StringSelectMenuBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuBuilder}
|
||||
*/
|
||||
@@ -0,0 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||
|
||||
/**
|
||||
* Represents a string select menu component
|
||||
* @extends {BaseSelectMenuComponent}
|
||||
*/
|
||||
class StringSelectMenuComponent extends BaseSelectMenuComponent {
|
||||
/**
|
||||
* The options in this select menu
|
||||
* @type {APISelectMenuOption[]}
|
||||
* @readonly
|
||||
*/
|
||||
get options() {
|
||||
return this.data.options;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StringSelectMenuComponent;
|
||||
@@ -0,0 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||
|
||||
/**
|
||||
* Represents a {@link ComponentType.StringSelect} select menu interaction.
|
||||
* @extends {MessageComponentInteraction}
|
||||
*/
|
||||
class StringSelectMenuInteraction extends MessageComponentInteraction {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
|
||||
/**
|
||||
* The values selected
|
||||
* @type {string[]}
|
||||
*/
|
||||
this.values = data.data.values ?? [];
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StringSelectMenuInteraction;
|
||||
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
const { SelectMenuOptionBuilder: BuildersSelectMenuOption, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
const { resolvePartialEmoji } = require('../util/Util');
|
||||
|
||||
/**
|
||||
* Represents a select menu option builder.
|
||||
* @extends {BuildersSelectMenuOption}
|
||||
*/
|
||||
class StringSelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
||||
constructor({ emoji, ...data } = {}) {
|
||||
super(
|
||||
toSnakeCase({
|
||||
...data,
|
||||
emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the emoji to display on this option
|
||||
* @param {ComponentEmojiResolvable} emoji The emoji to display on this option
|
||||
* @returns {StringSelectMenuOptionBuilder}
|
||||
*/
|
||||
setEmoji(emoji) {
|
||||
if (typeof emoji === 'string') {
|
||||
return super.setEmoji(resolvePartialEmoji(emoji));
|
||||
}
|
||||
return super.setEmoji(emoji);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu option builder from JSON data
|
||||
* @param {JSONEncodable<APISelectMenuOption>|APISelectMenuOption} other The other data
|
||||
* @returns {StringSelectMenuOptionBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = StringSelectMenuOptionBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersSelectMenuOption
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuOptionBuilder}
|
||||
*/
|
||||
33
packages/discord.js/src/structures/UserSelectMenuBuilder.js
Normal file
33
packages/discord.js/src/structures/UserSelectMenuBuilder.js
Normal file
@@ -0,0 +1,33 @@
|
||||
'use strict';
|
||||
|
||||
const { UserSelectMenuBuilder: BuildersUserSelectMenu, isJSONEncodable } = require('@discordjs/builders');
|
||||
const { toSnakeCase } = require('../util/Transformers');
|
||||
|
||||
/**
|
||||
* Class used to build select menu components to be sent through the API
|
||||
* @extends {BuildersUserSelectMenu}
|
||||
*/
|
||||
class UserSelectMenuBuilder extends BuildersUserSelectMenu {
|
||||
constructor(data = {}) {
|
||||
super(toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @returns {UserSelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserSelectMenuBuilder;
|
||||
|
||||
/**
|
||||
* @external BuildersUserSelectMenu
|
||||
* @see {@link https://discord.js.org/#/docs/builders/main/class/UserSelectMenuBuilder}
|
||||
*/
|
||||
@@ -0,0 +1,11 @@
|
||||
'use strict';
|
||||
|
||||
const BaseSelectMenuComponent = require('./BaseSelectMenuComponent');
|
||||
|
||||
/**
|
||||
* Represents a user select menu component
|
||||
* @extends {BaseSelectMenuComponent}
|
||||
*/
|
||||
class UserSelectMenuComponent extends BaseSelectMenuComponent {}
|
||||
|
||||
module.exports = UserSelectMenuComponent;
|
||||
@@ -0,0 +1,49 @@
|
||||
'use strict';
|
||||
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const MessageComponentInteraction = require('./MessageComponentInteraction');
|
||||
const Events = require('../util/Events');
|
||||
|
||||
/**
|
||||
* Represents a {@link ComponentType.UserSelect} select menu interaction.
|
||||
* @extends {MessageComponentInteraction}
|
||||
*/
|
||||
class UserSelectMenuInteraction extends MessageComponentInteraction {
|
||||
constructor(client, data) {
|
||||
super(client, data);
|
||||
|
||||
/**
|
||||
* Collection of the selected users
|
||||
* @type {Collection<Snowflake, User>}
|
||||
*/
|
||||
this.users = new Collection();
|
||||
|
||||
/**
|
||||
* Collection of the selected members
|
||||
* @type {Collection<Snowflake, GuildMember|APIGuildMember>}
|
||||
*/
|
||||
this.members = new Collection();
|
||||
|
||||
for (const user of Object.values(data.data.resolved.users)) {
|
||||
this.users.set(user.id, this.client.users._add(user));
|
||||
}
|
||||
|
||||
if (data.data.resolved.members) {
|
||||
for (const [id, member] of Object.entries(data.data.resolved.members)) {
|
||||
const user = data.data.resolved.users[id];
|
||||
if (!user) {
|
||||
this.client.emit(
|
||||
Events.Debug,
|
||||
`[UserSelectMenuInteraction] Received a member without a user, skipping ${id}`,
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
this.members.set(id, this.guild?.members._add({ user, ...member }) ?? { user, ...member });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = UserSelectMenuInteraction;
|
||||
@@ -82,10 +82,18 @@ function createComponent(data) {
|
||||
return new ActionRow(data);
|
||||
case ComponentType.Button:
|
||||
return new ButtonComponent(data);
|
||||
case ComponentType.SelectMenu:
|
||||
return new SelectMenuComponent(data);
|
||||
case ComponentType.StringSelect:
|
||||
return new StringSelectMenuComponent(data);
|
||||
case ComponentType.TextInput:
|
||||
return new TextInputComponent(data);
|
||||
case ComponentType.UserSelect:
|
||||
return new UserSelectMenuComponent(data);
|
||||
case ComponentType.RoleSelect:
|
||||
return new RoleSelectMenuComponent(data);
|
||||
case ComponentType.MentionableSelect:
|
||||
return new MentionableSelectMenuComponent(data);
|
||||
case ComponentType.ChannelSelect:
|
||||
return new ChannelSelectMenuComponent(data);
|
||||
default:
|
||||
return new Component(data);
|
||||
}
|
||||
@@ -106,10 +114,18 @@ function createComponentBuilder(data) {
|
||||
return new ActionRowBuilder(data);
|
||||
case ComponentType.Button:
|
||||
return new ButtonBuilder(data);
|
||||
case ComponentType.SelectMenu:
|
||||
return new SelectMenuBuilder(data);
|
||||
case ComponentType.StringSelect:
|
||||
return new StringSelectMenuBuilder(data);
|
||||
case ComponentType.TextInput:
|
||||
return new TextInputBuilder(data);
|
||||
case ComponentType.UserSelect:
|
||||
return new UserSelectMenuBuilder(data);
|
||||
case ComponentType.RoleSelect:
|
||||
return new RoleSelectMenuBuilder(data);
|
||||
case ComponentType.MentionableSelect:
|
||||
return new MentionableSelectMenuBuilder(data);
|
||||
case ComponentType.ChannelSelect:
|
||||
return new ChannelSelectMenuBuilder(data);
|
||||
default:
|
||||
return new ComponentBuilder(data);
|
||||
}
|
||||
@@ -121,11 +137,19 @@ const ActionRow = require('../structures/ActionRow');
|
||||
const ActionRowBuilder = require('../structures/ActionRowBuilder');
|
||||
const ButtonBuilder = require('../structures/ButtonBuilder');
|
||||
const ButtonComponent = require('../structures/ButtonComponent');
|
||||
const ChannelSelectMenuBuilder = require('../structures/ChannelSelectMenuBuilder');
|
||||
const ChannelSelectMenuComponent = require('../structures/ChannelSelectMenuComponent');
|
||||
const Component = require('../structures/Component');
|
||||
const SelectMenuBuilder = require('../structures/SelectMenuBuilder');
|
||||
const SelectMenuComponent = require('../structures/SelectMenuComponent');
|
||||
const MentionableSelectMenuBuilder = require('../structures/MentionableSelectMenuBuilder');
|
||||
const MentionableSelectMenuComponent = require('../structures/MentionableSelectMenuComponent');
|
||||
const RoleSelectMenuBuilder = require('../structures/RoleSelectMenuBuilder');
|
||||
const RoleSelectMenuComponent = require('../structures/RoleSelectMenuComponent');
|
||||
const StringSelectMenuBuilder = require('../structures/StringSelectMenuBuilder');
|
||||
const StringSelectMenuComponent = require('../structures/StringSelectMenuComponent');
|
||||
const TextInputBuilder = require('../structures/TextInputBuilder');
|
||||
const TextInputComponent = require('../structures/TextInputComponent');
|
||||
const UserSelectMenuBuilder = require('../structures/UserSelectMenuBuilder');
|
||||
const UserSelectMenuComponent = require('../structures/UserSelectMenuComponent');
|
||||
|
||||
/**
|
||||
* @external JSONEncodable
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { ChannelType, MessageType } = require('discord-api-types/v10');
|
||||
const { ChannelType, MessageType, ComponentType } = require('discord-api-types/v10');
|
||||
|
||||
/**
|
||||
* The name of an item to be swept in Sweepers
|
||||
@@ -113,6 +113,23 @@ exports.ThreadChannelTypes = [ChannelType.AnnouncementThread, ChannelType.Public
|
||||
*/
|
||||
exports.VoiceBasedChannelTypes = [ChannelType.GuildVoice, ChannelType.GuildStageVoice];
|
||||
|
||||
/**
|
||||
* The types of select menus. The available types are:
|
||||
* * {@link ComponentType.StringSelect}
|
||||
* * {@link ComponentType.UserSelect}
|
||||
* * {@link ComponentType.RoleSelect}
|
||||
* * {@link ComponentType.MentionableSelect}
|
||||
* * {@link ComponentType.ChannelSelect}
|
||||
* @typedef {ComponentType[]} SelectMenuTypes
|
||||
*/
|
||||
exports.SelectMenuTypes = [
|
||||
ComponentType.StringSelect,
|
||||
ComponentType.UserSelect,
|
||||
ComponentType.RoleSelect,
|
||||
ComponentType.MentionableSelect,
|
||||
ComponentType.ChannelSelect,
|
||||
];
|
||||
|
||||
/**
|
||||
* @typedef {Object} Constants Constants that can be used in an enum or object-like way.
|
||||
* @property {SweeperKey[]} SweeperKeys The possible names of items that can be swept in sweepers
|
||||
@@ -120,4 +137,5 @@ exports.VoiceBasedChannelTypes = [ChannelType.GuildVoice, ChannelType.GuildStage
|
||||
* @property {TextBasedChannelTypes} TextBasedChannelTypes The types of channels that are text-based
|
||||
* @property {ThreadChannelTypes} ThreadChannelTypes The types of channels that are threads
|
||||
* @property {VoiceBasedChannelTypes} VoiceBasedChannelTypes The types of channels that are voice-based
|
||||
* @property {SelectMenuTypes} SelectMenuTypes The types of components that are select menus.
|
||||
*/
|
||||
|
||||
286
packages/discord.js/typings/index.d.ts
vendored
286
packages/discord.js/typings/index.d.ts
vendored
@@ -14,14 +14,17 @@ import {
|
||||
italic,
|
||||
quote,
|
||||
roleMention,
|
||||
SelectMenuBuilder as BuilderSelectMenuComponent,
|
||||
ChannelSelectMenuBuilder as BuilderChannelSelectMenuComponent,
|
||||
MentionableSelectMenuBuilder as BuilderMentionableSelectMenuComponent,
|
||||
RoleSelectMenuBuilder as BuilderRoleSelectMenuComponent,
|
||||
StringSelectMenuBuilder as BuilderStringSelectMenuComponent,
|
||||
UserSelectMenuBuilder as BuilderUserSelectMenuComponent,
|
||||
TextInputBuilder as BuilderTextInputComponent,
|
||||
SelectMenuOptionBuilder as BuildersSelectMenuOption,
|
||||
spoiler,
|
||||
strikethrough,
|
||||
time,
|
||||
TimestampStyles,
|
||||
TimestampStylesString,
|
||||
underscore,
|
||||
userMention,
|
||||
ModalActionRowComponentBuilder,
|
||||
@@ -35,7 +38,6 @@ import { Collection } from '@discordjs/collection';
|
||||
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
|
||||
import {
|
||||
APIActionRowComponent,
|
||||
APIApplicationCommand,
|
||||
APIApplicationCommandInteractionData,
|
||||
APIApplicationCommandOption,
|
||||
APIAuditLogChange,
|
||||
@@ -126,6 +128,17 @@ import {
|
||||
TextChannelType,
|
||||
ChannelFlags,
|
||||
SortOrderType,
|
||||
APIMessageStringSelectInteractionData,
|
||||
APIMessageUserSelectInteractionData,
|
||||
APIStringSelectComponent,
|
||||
APIUserSelectComponent,
|
||||
APIRoleSelectComponent,
|
||||
APIMentionableSelectComponent,
|
||||
APIChannelSelectComponent,
|
||||
APIGuildMember,
|
||||
APIMessageRoleSelectInteractionData,
|
||||
APIMessageMentionableSelectInteractionData,
|
||||
APIMessageChannelSelectInteractionData,
|
||||
} from 'discord-api-types/v10';
|
||||
import { ChildProcess } from 'node:child_process';
|
||||
import { EventEmitter } from 'node:events';
|
||||
@@ -158,13 +171,11 @@ import {
|
||||
RawInviteData,
|
||||
RawInviteGuildData,
|
||||
RawInviteStageInstance,
|
||||
RawAttachmentData,
|
||||
RawMessageButtonInteractionData,
|
||||
RawMessageComponentInteractionData,
|
||||
RawMessageData,
|
||||
RawMessagePayloadData,
|
||||
RawMessageReactionData,
|
||||
RawMessageSelectMenuInteractionData,
|
||||
RawOAuth2GuildData,
|
||||
RawPartialGroupDMChannelData,
|
||||
RawPartialMessageData,
|
||||
@@ -242,7 +253,11 @@ export interface BaseComponentData {
|
||||
export type MessageActionRowComponentData =
|
||||
| JSONEncodable<APIMessageActionRowComponent>
|
||||
| ButtonComponentData
|
||||
| SelectMenuComponentData;
|
||||
| StringSelectMenuComponentData
|
||||
| UserSelectMenuComponentData
|
||||
| RoleSelectMenuComponentData
|
||||
| MentionableSelectMenuComponentData
|
||||
| ChannelSelectMenuComponentData;
|
||||
|
||||
export type ModalActionRowComponentData = JSONEncodable<APIModalActionRowComponent> | TextInputComponentData;
|
||||
|
||||
@@ -269,7 +284,13 @@ export class ActionRowBuilder<T extends AnyComponentBuilder = AnyComponentBuilde
|
||||
): ActionRowBuilder;
|
||||
}
|
||||
|
||||
export type MessageActionRowComponent = ButtonComponent | SelectMenuComponent;
|
||||
export type MessageActionRowComponent =
|
||||
| ButtonComponent
|
||||
| StringSelectMenuComponent
|
||||
| UserSelectMenuComponent
|
||||
| RoleSelectMenuComponent
|
||||
| MentionableSelectMenuComponent
|
||||
| ChannelSelectMenuComponent;
|
||||
export type ModalActionRowComponent = TextInputComponent;
|
||||
|
||||
export class ActionRow<T extends MessageActionRowComponent | ModalActionRowComponent> extends Component<
|
||||
@@ -604,8 +625,8 @@ export class ButtonBuilder extends BuilderButtonComponent {
|
||||
public override setEmoji(emoji: ComponentEmojiResolvable): this;
|
||||
}
|
||||
|
||||
export class SelectMenuBuilder extends BuilderSelectMenuComponent {
|
||||
public constructor(data?: Partial<SelectMenuComponentData | APISelectMenuComponent>);
|
||||
export class StringSelectMenuBuilder extends BuilderStringSelectMenuComponent {
|
||||
public constructor(data?: Partial<StringSelectMenuComponentData | APIStringSelectComponent>);
|
||||
private static normalizeEmoji(
|
||||
selectMenuOption: JSONEncodable<APISelectMenuOption> | SelectMenuComponentOptionData,
|
||||
): (APISelectMenuOption | SelectMenuOptionBuilder)[];
|
||||
@@ -615,7 +636,34 @@ export class SelectMenuBuilder extends BuilderSelectMenuComponent {
|
||||
public override setOptions(
|
||||
...options: RestOrArray<BuildersSelectMenuOption | SelectMenuComponentOptionData | APISelectMenuOption>
|
||||
): this;
|
||||
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): SelectMenuBuilder;
|
||||
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): StringSelectMenuBuilder;
|
||||
}
|
||||
|
||||
export {
|
||||
/** @deprecated Use {@link StringSelectMenuBuilder} instead */
|
||||
StringSelectMenuBuilder as SelectMenuBuilder,
|
||||
};
|
||||
|
||||
export class UserSelectMenuBuilder extends BuilderUserSelectMenuComponent {
|
||||
public constructor(data?: Partial<UserSelectMenuComponentData | APIUserSelectComponent>);
|
||||
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): UserSelectMenuBuilder;
|
||||
}
|
||||
|
||||
export class RoleSelectMenuBuilder extends BuilderRoleSelectMenuComponent {
|
||||
public constructor(data?: Partial<RoleSelectMenuComponentData | APIRoleSelectComponent>);
|
||||
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): RoleSelectMenuBuilder;
|
||||
}
|
||||
|
||||
export class MentionableSelectMenuBuilder extends BuilderMentionableSelectMenuComponent {
|
||||
public constructor(data?: Partial<MentionableSelectMenuComponentData | APIMentionableSelectComponent>);
|
||||
public static from(
|
||||
other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent,
|
||||
): MentionableSelectMenuBuilder;
|
||||
}
|
||||
|
||||
export class ChannelSelectMenuBuilder extends BuilderChannelSelectMenuComponent {
|
||||
public constructor(data?: Partial<ChannelSelectMenuComponentData | APIChannelSelectComponent>);
|
||||
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): ChannelSelectMenuBuilder;
|
||||
}
|
||||
|
||||
export class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
|
||||
@@ -639,16 +687,34 @@ export class TextInputComponent extends Component<APITextInputComponent> {
|
||||
public get value(): string;
|
||||
}
|
||||
|
||||
export class SelectMenuComponent extends Component<APISelectMenuComponent> {
|
||||
private constructor(data: APISelectMenuComponent);
|
||||
export class BaseSelectMenuComponent<Data extends APISelectMenuComponent> extends Component<Data> {
|
||||
protected constructor(data: Data);
|
||||
public get placeholder(): string | null;
|
||||
public get maxValues(): number | null;
|
||||
public get minValues(): number | null;
|
||||
public get customId(): string;
|
||||
public get disabled(): boolean | null;
|
||||
}
|
||||
|
||||
export class StringSelectMenuComponent extends BaseSelectMenuComponent<APIStringSelectComponent> {
|
||||
public get options(): APISelectMenuOption[];
|
||||
}
|
||||
|
||||
export {
|
||||
/** @deprecated Use {@link StringSelectMenuComponent} instead */
|
||||
StringSelectMenuComponent as SelectMenuComponent,
|
||||
};
|
||||
|
||||
export class UserSelectMenuComponent extends BaseSelectMenuComponent<APIUserSelectComponent> {}
|
||||
|
||||
export class RoleSelectMenuComponent extends BaseSelectMenuComponent<APIRoleSelectComponent> {}
|
||||
|
||||
export class MentionableSelectMenuComponent extends BaseSelectMenuComponent<APIMentionableSelectComponent> {}
|
||||
|
||||
export class ChannelSelectMenuComponent extends BaseSelectMenuComponent<APIChannelSelectComponent> {
|
||||
public getChannelTypes(): ChannelType[] | null;
|
||||
}
|
||||
|
||||
export interface EmbedData {
|
||||
title?: string;
|
||||
type?: EmbedType;
|
||||
@@ -1501,7 +1567,7 @@ export type Interaction<Cached extends CacheType = CacheType> =
|
||||
| ChatInputCommandInteraction<Cached>
|
||||
| MessageContextMenuCommandInteraction<Cached>
|
||||
| UserContextMenuCommandInteraction<Cached>
|
||||
| SelectMenuInteraction<Cached>
|
||||
| AnySelectMenuInteraction<Cached>
|
||||
| ButtonInteraction<Cached>
|
||||
| AutocompleteInteraction<Cached>
|
||||
| ModalSubmitInteraction<Cached>;
|
||||
@@ -1550,7 +1616,14 @@ export class BaseInteraction<Cached extends CacheType = CacheType> extends Base
|
||||
public isMessageContextMenuCommand(): this is MessageContextMenuCommandInteraction<Cached>;
|
||||
public isModalSubmit(): this is ModalSubmitInteraction<Cached>;
|
||||
public isUserContextMenuCommand(): this is UserContextMenuCommandInteraction<Cached>;
|
||||
public isSelectMenu(): this is SelectMenuInteraction<Cached>;
|
||||
/** @deprecated Use {@link BaseInteraction#isStringSelectMenu} instead */
|
||||
public isSelectMenu(): this is StringSelectMenuInteraction<Cached>;
|
||||
public isAnySelectMenu(): this is AnySelectMenuInteraction<Cached>;
|
||||
public isStringSelectMenu(): this is StringSelectMenuInteraction<Cached>;
|
||||
public isUserSelectMenu(): this is UserSelectMenuInteraction<Cached>;
|
||||
public isRoleSelectMenu(): this is RoleSelectMenuInteraction<Cached>;
|
||||
public isMentionableSelectMenu(): this is MentionableSelectMenuInteraction<Cached>;
|
||||
public isChannelSelectMenu(): this is ChannelSelectMenuInteraction<Cached>;
|
||||
public isRepliable(): this is RepliableInteraction<Cached>;
|
||||
}
|
||||
|
||||
@@ -1673,7 +1746,11 @@ export type AwaitMessageCollectorOptionsParams<T extends MessageComponentType, C
|
||||
|
||||
export interface StringMappedInteractionTypes<Cached extends CacheType = CacheType> {
|
||||
Button: ButtonInteraction<Cached>;
|
||||
SelectMenu: SelectMenuInteraction<Cached>;
|
||||
StringSelectMenu: StringSelectMenuInteraction<Cached>;
|
||||
UserSelectMenu: UserSelectMenuInteraction<Cached>;
|
||||
RoleSelectMenu: RoleSelectMenuInteraction<Cached>;
|
||||
MentionableSelectMenu: MentionableSelectMenuInteraction<Cached>;
|
||||
ChannelSelectMenu: ChannelSelectMenuInteraction<Cached>;
|
||||
ActionRow: MessageComponentInteraction<Cached>;
|
||||
}
|
||||
|
||||
@@ -1681,7 +1758,11 @@ export type WrapBooleanCache<T extends boolean> = If<T, 'cached', CacheType>;
|
||||
|
||||
export interface MappedInteractionTypes<Cached extends boolean = boolean> {
|
||||
[ComponentType.Button]: ButtonInteraction<WrapBooleanCache<Cached>>;
|
||||
[ComponentType.SelectMenu]: SelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||
[ComponentType.StringSelect]: StringSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||
[ComponentType.UserSelect]: UserSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||
[ComponentType.RoleSelect]: RoleSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||
[ComponentType.MentionableSelect]: MentionableSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||
[ComponentType.ChannelSelect]: ChannelSelectMenuInteraction<WrapBooleanCache<Cached>>;
|
||||
}
|
||||
|
||||
export class Message<InGuild extends boolean = boolean> extends Base {
|
||||
@@ -2254,22 +2335,116 @@ export class Role extends Base {
|
||||
public toString(): RoleMention;
|
||||
}
|
||||
|
||||
export class SelectMenuInteraction<Cached extends CacheType = CacheType> extends MessageComponentInteraction<Cached> {
|
||||
public constructor(client: Client<true>, data: RawMessageSelectMenuInteractionData);
|
||||
export class StringSelectMenuInteraction<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends MessageComponentInteraction<Cached> {
|
||||
public constructor(client: Client<true>, data: APIMessageStringSelectInteractionData);
|
||||
public get component(): CacheTypeReducer<
|
||||
Cached,
|
||||
SelectMenuComponent,
|
||||
APISelectMenuComponent,
|
||||
SelectMenuComponent | APISelectMenuComponent,
|
||||
SelectMenuComponent | APISelectMenuComponent
|
||||
StringSelectMenuComponent,
|
||||
APIStringSelectComponent,
|
||||
StringSelectMenuComponent | APIStringSelectComponent,
|
||||
StringSelectMenuComponent | APIStringSelectComponent
|
||||
>;
|
||||
public componentType: ComponentType.SelectMenu;
|
||||
public componentType: ComponentType.StringSelect;
|
||||
public values: string[];
|
||||
public inGuild(): this is SelectMenuInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is SelectMenuInteraction<'cached'>;
|
||||
public inRawGuild(): this is SelectMenuInteraction<'raw'>;
|
||||
public inGuild(): this is StringSelectMenuInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is StringSelectMenuInteraction<'cached'>;
|
||||
public inRawGuild(): this is StringSelectMenuInteraction<'raw'>;
|
||||
}
|
||||
|
||||
export {
|
||||
/** @deprecated Use {@link StringSelectMenuInteraction} instead */
|
||||
StringSelectMenuInteraction as SelectMenuInteraction,
|
||||
};
|
||||
|
||||
export class UserSelectMenuInteraction<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends MessageComponentInteraction<Cached> {
|
||||
public constructor(client: Client<true>, data: APIMessageUserSelectInteractionData);
|
||||
public get component(): CacheTypeReducer<
|
||||
Cached,
|
||||
UserSelectMenuComponent,
|
||||
APIUserSelectComponent,
|
||||
UserSelectMenuComponent | APIUserSelectComponent,
|
||||
UserSelectMenuComponent | APIUserSelectComponent
|
||||
>;
|
||||
public componentType: ComponentType.UserSelect;
|
||||
public users: Collection<Snowflake, User>;
|
||||
public members: Collection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIGuildMember>>;
|
||||
public inGuild(): this is UserSelectMenuInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is UserSelectMenuInteraction<'cached'>;
|
||||
public inRawGuild(): this is UserSelectMenuInteraction<'raw'>;
|
||||
}
|
||||
|
||||
export class RoleSelectMenuInteraction<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends MessageComponentInteraction<Cached> {
|
||||
public constructor(client: Client<true>, data: APIMessageRoleSelectInteractionData);
|
||||
public get component(): CacheTypeReducer<
|
||||
Cached,
|
||||
RoleSelectMenuComponent,
|
||||
APIRoleSelectComponent,
|
||||
RoleSelectMenuComponent | APIRoleSelectComponent,
|
||||
RoleSelectMenuComponent | APIRoleSelectComponent
|
||||
>;
|
||||
public componentType: ComponentType.RoleSelect;
|
||||
public roles: Collection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||
public inGuild(): this is RoleSelectMenuInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is RoleSelectMenuInteraction<'cached'>;
|
||||
public inRawGuild(): this is RoleSelectMenuInteraction<'raw'>;
|
||||
}
|
||||
|
||||
export class MentionableSelectMenuInteraction<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends MessageComponentInteraction<Cached> {
|
||||
public constructor(client: Client<true>, data: APIMessageMentionableSelectInteractionData);
|
||||
public get component(): CacheTypeReducer<
|
||||
Cached,
|
||||
MentionableSelectMenuComponent,
|
||||
APIMentionableSelectComponent,
|
||||
MentionableSelectMenuComponent | APIMentionableSelectComponent,
|
||||
MentionableSelectMenuComponent | APIMentionableSelectComponent
|
||||
>;
|
||||
public componentType: ComponentType.MentionableSelect;
|
||||
public users: Collection<Snowflake, User>;
|
||||
public members: Collection<Snowflake, CacheTypeReducer<Cached, GuildMember, APIGuildMember>>;
|
||||
public roles: Collection<Snowflake, CacheTypeReducer<Cached, Role, APIRole>>;
|
||||
public inGuild(): this is MentionableSelectMenuInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is MentionableSelectMenuInteraction<'cached'>;
|
||||
public inRawGuild(): this is MentionableSelectMenuInteraction<'raw'>;
|
||||
}
|
||||
|
||||
export class ChannelSelectMenuInteraction<
|
||||
Cached extends CacheType = CacheType,
|
||||
> extends MessageComponentInteraction<Cached> {
|
||||
public constructor(client: Client<true>, data: APIMessageChannelSelectInteractionData);
|
||||
public get component(): CacheTypeReducer<
|
||||
Cached,
|
||||
ChannelSelectMenuComponent,
|
||||
APIChannelSelectComponent,
|
||||
ChannelSelectMenuComponent | APIChannelSelectComponent,
|
||||
ChannelSelectMenuComponent | APIChannelSelectComponent
|
||||
>;
|
||||
public componentType: ComponentType.ChannelSelect;
|
||||
public channels: Collection<Snowflake, CacheTypeReducer<Cached, Channel, APIChannel>>;
|
||||
public inGuild(): this is ChannelSelectMenuInteraction<'raw' | 'cached'>;
|
||||
public inCachedGuild(): this is ChannelSelectMenuInteraction<'cached'>;
|
||||
public inRawGuild(): this is ChannelSelectMenuInteraction<'raw'>;
|
||||
}
|
||||
|
||||
// Ideally this should be named SelectMenuInteraction, but that's the name of the "old" StringSelectMenuInteraction, meaning
|
||||
// the type name is reserved as a re-export to prevent a breaking change from being made, as such:
|
||||
// TODO: Rename this to SelectMenuInteraction in the next major
|
||||
export type AnySelectMenuInteraction<Cached extends CacheType = CacheType> =
|
||||
| StringSelectMenuInteraction<Cached>
|
||||
| UserSelectMenuInteraction<Cached>
|
||||
| RoleSelectMenuInteraction<Cached>
|
||||
| MentionableSelectMenuInteraction<Cached>
|
||||
| ChannelSelectMenuInteraction<Cached>;
|
||||
|
||||
export type SelectMenuType = APISelectMenuComponent['type'];
|
||||
|
||||
export interface ShardEventTypes {
|
||||
death: [process: ChildProcess | Worker];
|
||||
disconnect: [];
|
||||
@@ -2770,14 +2945,22 @@ export function parseWebhookURL(url: string): WebhookClientDataIdWithToken | nul
|
||||
|
||||
export interface MappedComponentBuilderTypes {
|
||||
[ComponentType.Button]: ButtonBuilder;
|
||||
[ComponentType.SelectMenu]: SelectMenuBuilder;
|
||||
[ComponentType.StringSelect]: StringSelectMenuBuilder;
|
||||
[ComponentType.UserSelect]: UserSelectMenuBuilder;
|
||||
[ComponentType.RoleSelect]: RoleSelectMenuBuilder;
|
||||
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder;
|
||||
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder;
|
||||
[ComponentType.ActionRow]: ActionRowBuilder;
|
||||
[ComponentType.TextInput]: TextInputBuilder;
|
||||
}
|
||||
|
||||
export interface MappedComponentTypes {
|
||||
[ComponentType.Button]: ButtonComponent;
|
||||
[ComponentType.SelectMenu]: SelectMenuComponent;
|
||||
[ComponentType.StringSelect]: StringSelectMenuComponent;
|
||||
[ComponentType.UserSelect]: UserSelectMenuComponent;
|
||||
[ComponentType.RoleSelect]: RoleSelectMenuComponent;
|
||||
[ComponentType.MentionableSelect]: MentionableSelectMenuComponent;
|
||||
[ComponentType.ChannelSelect]: ChannelSelectMenuComponent;
|
||||
[ComponentType.ActionRow]: ActionRowComponent;
|
||||
[ComponentType.TextInput]: TextInputComponent;
|
||||
}
|
||||
@@ -3116,6 +3299,7 @@ export const Constants: {
|
||||
TextBasedChannelTypes: TextBasedChannelTypes[];
|
||||
ThreadChannelTypes: ThreadChannelType[];
|
||||
VoiceBasedChannelTypes: VoiceBasedChannelTypes[];
|
||||
SelectMenuTypes: SelectMenuType[];
|
||||
};
|
||||
|
||||
export const version: string;
|
||||
@@ -5144,7 +5328,11 @@ export interface IntegrationAccount {
|
||||
export type IntegrationType = 'twitch' | 'youtube' | 'discord';
|
||||
|
||||
export type CollectedInteraction<Cached extends CacheType = CacheType> =
|
||||
| SelectMenuInteraction<Cached>
|
||||
| StringSelectMenuInteraction<Cached>
|
||||
| UserSelectMenuInteraction<Cached>
|
||||
| RoleSelectMenuInteraction<Cached>
|
||||
| MentionableSelectMenuInteraction<Cached>
|
||||
| ChannelSelectMenuInteraction<Cached>
|
||||
| ButtonInteraction<Cached>
|
||||
| ModalSubmitInteraction<Cached>;
|
||||
|
||||
@@ -5216,7 +5404,13 @@ export interface MakeErrorOptions {
|
||||
stack: string;
|
||||
}
|
||||
|
||||
export type ActionRowComponentOptions = ButtonComponentData | SelectMenuComponentData;
|
||||
export type ActionRowComponentOptions =
|
||||
| ButtonComponentData
|
||||
| StringSelectMenuComponentData
|
||||
| UserSelectMenuComponentData
|
||||
| RoleSelectMenuComponentData
|
||||
| MentionableSelectMenuComponentData
|
||||
| ChannelSelectMenuComponentData;
|
||||
|
||||
export type MessageActionRowComponentResolvable = MessageActionRowComponent | ActionRowComponentOptions;
|
||||
|
||||
@@ -5253,7 +5447,11 @@ export type MessageComponent =
|
||||
| Component
|
||||
| ActionRowBuilder<MessageActionRowComponentBuilder | ModalActionRowComponentBuilder>
|
||||
| ButtonComponent
|
||||
| SelectMenuComponent;
|
||||
| StringSelectMenuComponent
|
||||
| UserSelectMenuComponent
|
||||
| RoleSelectMenuComponent
|
||||
| MentionableSelectMenuComponent
|
||||
| ChannelSelectMenuComponent;
|
||||
|
||||
export type CollectedMessageInteraction<Cached extends CacheType = CacheType> = Exclude<
|
||||
CollectedInteraction<Cached>,
|
||||
@@ -5351,16 +5549,36 @@ export interface MessageReference {
|
||||
|
||||
export type MessageResolvable = Message | Snowflake;
|
||||
|
||||
export interface SelectMenuComponentData extends BaseComponentData {
|
||||
type: ComponentType.SelectMenu;
|
||||
export interface BaseSelectMenuComponentData extends BaseComponentData {
|
||||
customId: string;
|
||||
disabled?: boolean;
|
||||
maxValues?: number;
|
||||
minValues?: number;
|
||||
options?: SelectMenuComponentOptionData[];
|
||||
placeholder?: string;
|
||||
}
|
||||
|
||||
export interface StringSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||
type: ComponentType.StringSelect;
|
||||
options?: SelectMenuComponentOptionData[];
|
||||
}
|
||||
|
||||
export interface UserSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||
type: ComponentType.UserSelect;
|
||||
}
|
||||
|
||||
export interface RoleSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||
type: ComponentType.RoleSelect;
|
||||
}
|
||||
|
||||
export interface MentionableSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||
type: ComponentType.MentionableSelect;
|
||||
}
|
||||
|
||||
export interface ChannelSelectMenuComponentData extends BaseSelectMenuComponentData {
|
||||
type: ComponentType.ChannelSelect;
|
||||
channelTypes?: ChannelType[];
|
||||
}
|
||||
|
||||
export interface MessageSelectOption {
|
||||
default: boolean;
|
||||
description: string | null;
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
APIEmbed,
|
||||
ApplicationCommandType,
|
||||
APIMessage,
|
||||
APIStringSelectComponent,
|
||||
} from 'discord-api-types/v10';
|
||||
import {
|
||||
ApplicationCommand,
|
||||
@@ -72,7 +73,6 @@ import {
|
||||
ReactionCollector,
|
||||
Role,
|
||||
RoleManager,
|
||||
SelectMenuInteraction,
|
||||
Serialized,
|
||||
ShardClientUtil,
|
||||
ShardingManager,
|
||||
@@ -113,7 +113,7 @@ import {
|
||||
ButtonBuilder,
|
||||
EmbedBuilder,
|
||||
MessageActionRowComponent,
|
||||
SelectMenuBuilder,
|
||||
StringSelectMenuBuilder,
|
||||
TextInputBuilder,
|
||||
TextInputComponent,
|
||||
Embed,
|
||||
@@ -141,6 +141,13 @@ import {
|
||||
ChannelFlagsBitField,
|
||||
GuildForumThreadManager,
|
||||
GuildTextThreadManager,
|
||||
AnySelectMenuInteraction,
|
||||
StringSelectMenuInteraction,
|
||||
StringSelectMenuComponent,
|
||||
UserSelectMenuInteraction,
|
||||
RoleSelectMenuInteraction,
|
||||
ChannelSelectMenuInteraction,
|
||||
MentionableSelectMenuInteraction,
|
||||
} from '.';
|
||||
import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
|
||||
import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
|
||||
@@ -361,14 +368,14 @@ client.on('messageCreate', async message => {
|
||||
expectAssignable<InteractionCollector<ButtonInteraction>>(buttonCollector);
|
||||
|
||||
// Verify that select menus interaction are inferred.
|
||||
const selectMenuCollector = message.createMessageComponentCollector({ componentType: ComponentType.SelectMenu });
|
||||
expectAssignable<Promise<SelectMenuInteraction>>(
|
||||
message.awaitMessageComponent({ componentType: ComponentType.SelectMenu }),
|
||||
const selectMenuCollector = message.createMessageComponentCollector({ componentType: ComponentType.StringSelect });
|
||||
expectAssignable<Promise<StringSelectMenuInteraction>>(
|
||||
message.awaitMessageComponent({ componentType: ComponentType.StringSelect }),
|
||||
);
|
||||
expectAssignable<Promise<SelectMenuInteraction>>(
|
||||
channel.awaitMessageComponent({ componentType: ComponentType.SelectMenu }),
|
||||
expectAssignable<Promise<StringSelectMenuInteraction>>(
|
||||
channel.awaitMessageComponent({ componentType: ComponentType.StringSelect }),
|
||||
);
|
||||
expectAssignable<InteractionCollector<SelectMenuInteraction>>(selectMenuCollector);
|
||||
expectAssignable<InteractionCollector<StringSelectMenuInteraction>>(selectMenuCollector);
|
||||
|
||||
// Verify that message component interactions are default collected types.
|
||||
const defaultCollector = message.createMessageComponentCollector();
|
||||
@@ -405,9 +412,9 @@ client.on('messageCreate', async message => {
|
||||
});
|
||||
|
||||
message.createMessageComponentCollector({
|
||||
componentType: ComponentType.SelectMenu,
|
||||
componentType: ComponentType.StringSelect,
|
||||
filter: i => {
|
||||
expectType<SelectMenuInteraction>(i);
|
||||
expectType<StringSelectMenuInteraction>(i);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
@@ -428,9 +435,9 @@ client.on('messageCreate', async message => {
|
||||
});
|
||||
|
||||
message.awaitMessageComponent({
|
||||
componentType: ComponentType.SelectMenu,
|
||||
componentType: ComponentType.StringSelect,
|
||||
filter: i => {
|
||||
expectType<SelectMenuInteraction>(i);
|
||||
expectType<StringSelectMenuInteraction>(i);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
@@ -464,9 +471,9 @@ client.on('messageCreate', async message => {
|
||||
});
|
||||
|
||||
channel.awaitMessageComponent({
|
||||
componentType: ComponentType.SelectMenu,
|
||||
componentType: ComponentType.StringSelect,
|
||||
filter: i => {
|
||||
expectType<SelectMenuInteraction<'cached'>>(i);
|
||||
expectType<StringSelectMenuInteraction<'cached'>>(i);
|
||||
return true;
|
||||
},
|
||||
});
|
||||
@@ -489,9 +496,9 @@ client.on('messageCreate', async message => {
|
||||
const selectsRow: ActionRowData<MessageActionRowComponentData> = {
|
||||
type: ComponentType.ActionRow,
|
||||
components: [
|
||||
new SelectMenuBuilder(),
|
||||
new StringSelectMenuBuilder(),
|
||||
{
|
||||
type: ComponentType.SelectMenu,
|
||||
type: ComponentType.StringSelect,
|
||||
label: 'select menu',
|
||||
options: [{ label: 'test', value: 'test' }],
|
||||
customId: 'test',
|
||||
@@ -1122,8 +1129,8 @@ client.on('guildCreate', async g => {
|
||||
new ButtonBuilder(),
|
||||
{ type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
|
||||
{ type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
|
||||
{ type: ComponentType.SelectMenu, customId: 'foo' },
|
||||
new SelectMenuBuilder(),
|
||||
{ type: ComponentType.StringSelect, customId: 'foo' },
|
||||
new StringSelectMenuBuilder(),
|
||||
// @ts-expect-error
|
||||
{ type: ComponentType.TextInput, style: TextInputStyle.Paragraph, customId: 'foo', label: 'test' },
|
||||
// @ts-expect-error
|
||||
@@ -1136,7 +1143,7 @@ client.on('guildCreate', async g => {
|
||||
components: [
|
||||
{ type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
|
||||
{ type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
|
||||
{ type: ComponentType.SelectMenu, customId: 'foo' },
|
||||
{ type: ComponentType.StringSelect, customId: 'foo' },
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1508,7 +1515,7 @@ if (interaction.inGuild()) {
|
||||
|
||||
client.on('interactionCreate', async interaction => {
|
||||
if (interaction.type === InteractionType.MessageComponent) {
|
||||
expectType<SelectMenuInteraction | ButtonInteraction>(interaction);
|
||||
expectType<AnySelectMenuInteraction | ButtonInteraction>(interaction);
|
||||
expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
|
||||
expectType<Message>(interaction.message);
|
||||
if (interaction.inCachedGuild()) {
|
||||
@@ -1640,25 +1647,28 @@ client.on('interactionCreate', async interaction => {
|
||||
}
|
||||
}
|
||||
|
||||
if (interaction.type === InteractionType.MessageComponent && interaction.componentType === ComponentType.SelectMenu) {
|
||||
expectType<SelectMenuInteraction>(interaction);
|
||||
expectType<SelectMenuComponent | APISelectMenuComponent>(interaction.component);
|
||||
if (
|
||||
interaction.type === InteractionType.MessageComponent &&
|
||||
interaction.componentType === ComponentType.StringSelect
|
||||
) {
|
||||
expectType<StringSelectMenuInteraction>(interaction);
|
||||
expectType<StringSelectMenuComponent | APIStringSelectComponent>(interaction.component);
|
||||
expectType<Message>(interaction.message);
|
||||
if (interaction.inCachedGuild()) {
|
||||
expectAssignable<SelectMenuInteraction>(interaction);
|
||||
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||
expectType<SelectMenuComponent>(interaction.component);
|
||||
expectType<Message<true>>(interaction.message);
|
||||
expectType<Guild>(interaction.guild);
|
||||
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
|
||||
} else if (interaction.inRawGuild()) {
|
||||
expectAssignable<SelectMenuInteraction>(interaction);
|
||||
expectType<APISelectMenuComponent>(interaction.component);
|
||||
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||
expectType<APIStringSelectComponent>(interaction.component);
|
||||
expectType<Message<false>>(interaction.message);
|
||||
expectType<null>(interaction.guild);
|
||||
expectType<Promise<Message<false>>>(interaction.reply({ fetchReply: true }));
|
||||
} else if (interaction.inGuild()) {
|
||||
expectAssignable<SelectMenuInteraction>(interaction);
|
||||
expectType<SelectMenuComponent | APISelectMenuComponent>(interaction.component);
|
||||
expectAssignable<StringSelectMenuInteraction>(interaction);
|
||||
expectType<SelectMenuComponent | APIStringSelectComponent>(interaction.component);
|
||||
expectType<Message>(interaction.message);
|
||||
expectType<Guild | null>(interaction.guild);
|
||||
expectType<Promise<Message>>(interaction.reply({ fetchReply: true }));
|
||||
@@ -1882,7 +1892,7 @@ const button = new ButtonBuilder({
|
||||
customId: 'test',
|
||||
});
|
||||
|
||||
const selectMenu = new SelectMenuBuilder({
|
||||
const selectMenu = new StringSelectMenuBuilder({
|
||||
maxValues: 10,
|
||||
minValues: 2,
|
||||
customId: 'test',
|
||||
@@ -1892,7 +1902,7 @@ new ActionRowBuilder({
|
||||
components: [selectMenu.toJSON(), button.toJSON()],
|
||||
});
|
||||
|
||||
new SelectMenuBuilder({
|
||||
new StringSelectMenuBuilder({
|
||||
customId: 'foo',
|
||||
});
|
||||
|
||||
@@ -1951,10 +1961,10 @@ chatInputInteraction.showModal({
|
||||
});
|
||||
|
||||
declare const selectMenuData: APISelectMenuComponent;
|
||||
SelectMenuBuilder.from(selectMenuData);
|
||||
StringSelectMenuBuilder.from(selectMenuData);
|
||||
|
||||
declare const selectMenuComp: SelectMenuComponent;
|
||||
SelectMenuBuilder.from(selectMenuComp);
|
||||
StringSelectMenuBuilder.from(selectMenuComp);
|
||||
|
||||
declare const buttonData: APIButtonComponent;
|
||||
ButtonBuilder.from(buttonData);
|
||||
@@ -2025,3 +2035,22 @@ expectType<Readonly<ChannelFlagsBitField>>(categoryChannel.flags);
|
||||
expectType<Readonly<ChannelFlagsBitField>>(threadChannel.flags);
|
||||
|
||||
expectType<null>(partialGroupDMChannel.flags);
|
||||
|
||||
// Select menu type narrowing
|
||||
if (interaction.isAnySelectMenu()) {
|
||||
expectType<AnySelectMenuInteraction>(interaction);
|
||||
}
|
||||
|
||||
declare const anySelectMenu: AnySelectMenuInteraction;
|
||||
|
||||
if (anySelectMenu.isStringSelectMenu()) {
|
||||
expectType<StringSelectMenuInteraction>(anySelectMenu);
|
||||
} else if (anySelectMenu.isUserSelectMenu()) {
|
||||
expectType<UserSelectMenuInteraction>(anySelectMenu);
|
||||
} else if (anySelectMenu.isRoleSelectMenu()) {
|
||||
expectType<RoleSelectMenuInteraction>(anySelectMenu);
|
||||
} else if (anySelectMenu.isChannelSelectMenu()) {
|
||||
expectType<ChannelSelectMenuInteraction>(anySelectMenu);
|
||||
} else if (anySelectMenu.isMentionableSelectMenu()) {
|
||||
expectType<MentionableSelectMenuInteraction>(anySelectMenu);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user