From 839d637bbdc4fdadde39f6208afa8d1fd44da959 Mon Sep 17 00:00:00 2001 From: didinele Date: Wed, 26 Feb 2025 16:05:50 +0200 Subject: [PATCH 01/11] refactor: drop a nuke on the codebase --- packages/discord.js/package.json | 2 +- packages/discord.js/src/index.js | 13 -- .../src/structures/ActionRowBuilder.js | 36 ---- .../src/structures/ButtonBuilder.js | 44 ----- .../structures/ChannelSelectMenuBuilder.js | 31 ---- .../discord.js/src/structures/EmbedBuilder.js | 50 ------ .../MentionableSelectMenuBuilder.js | 32 ---- .../src/structures/MessagePayload.js | 2 +- .../discord.js/src/structures/ModalBuilder.js | 36 ---- .../src/structures/RoleSelectMenuBuilder.js | 31 ---- .../src/structures/StringSelectMenuBuilder.js | 79 --------- .../StringSelectMenuOptionBuilder.js | 49 ------ .../src/structures/TextInputBuilder.js | 31 ---- .../src/structures/UserSelectMenuBuilder.js | 31 ---- packages/discord.js/src/util/Components.js | 155 ------------------ packages/discord.js/typings/index.d.ts | 118 +------------ packages/discord.js/typings/index.test-d.ts | 102 ++++++------ pnpm-lock.yaml | 66 ++------ 18 files changed, 62 insertions(+), 846 deletions(-) delete mode 100644 packages/discord.js/src/structures/ActionRowBuilder.js delete mode 100644 packages/discord.js/src/structures/ButtonBuilder.js delete mode 100644 packages/discord.js/src/structures/ChannelSelectMenuBuilder.js delete mode 100644 packages/discord.js/src/structures/EmbedBuilder.js delete mode 100644 packages/discord.js/src/structures/MentionableSelectMenuBuilder.js delete mode 100644 packages/discord.js/src/structures/ModalBuilder.js delete mode 100644 packages/discord.js/src/structures/RoleSelectMenuBuilder.js delete mode 100644 packages/discord.js/src/structures/StringSelectMenuBuilder.js delete mode 100644 packages/discord.js/src/structures/StringSelectMenuOptionBuilder.js delete mode 100644 packages/discord.js/src/structures/TextInputBuilder.js delete mode 100644 packages/discord.js/src/structures/UserSelectMenuBuilder.js delete mode 100644 packages/discord.js/src/util/Components.js diff --git a/packages/discord.js/package.json b/packages/discord.js/package.json index 50ee98c3f6b4..620edabbce5f 100644 --- a/packages/discord.js/package.json +++ b/packages/discord.js/package.json @@ -65,7 +65,7 @@ "homepage": "https://discord.js.org", "funding": "https://github.com/discordjs/discord.js?sponsor", "dependencies": { - "@discordjs/builders": "^1.9.0", + "@discordjs/builders": "workspace:^", "@discordjs/collection": "workspace:^", "@discordjs/formatters": "workspace:^", "@discordjs/rest": "workspace:^", diff --git a/packages/discord.js/src/index.js b/packages/discord.js/src/index.js index 8fc4eeadff97..a93413cd241a 100644 --- a/packages/discord.js/src/index.js +++ b/packages/discord.js/src/index.js @@ -92,7 +92,6 @@ exports.VoiceStateManager = require('./managers/VoiceStateManager.js').VoiceStat // Structures exports.ActionRow = require('./structures/ActionRow.js').ActionRow; -exports.ActionRowBuilder = require('./structures/ActionRowBuilder.js').ActionRowBuilder; exports.Activity = require('./structures/Presence.js').Activity; exports.AnnouncementChannel = require('./structures/AnnouncementChannel.js').AnnouncementChannel; exports.AnonymousGuild = require('./structures/AnonymousGuild.js').AnonymousGuild; @@ -115,11 +114,9 @@ exports.BaseGuildTextChannel = require('./structures/BaseGuildTextChannel.js').B exports.BaseGuildVoiceChannel = require('./structures/BaseGuildVoiceChannel.js').BaseGuildVoiceChannel; exports.BaseInteraction = require('./structures/BaseInteraction.js').BaseInteraction; exports.BaseSelectMenuComponent = require('./structures/BaseSelectMenuComponent.js').BaseSelectMenuComponent; -exports.ButtonBuilder = require('./structures/ButtonBuilder.js').ButtonBuilder; exports.ButtonComponent = require('./structures/ButtonComponent.js').ButtonComponent; exports.ButtonInteraction = require('./structures/ButtonInteraction.js').ButtonInteraction; exports.CategoryChannel = require('./structures/CategoryChannel.js').CategoryChannel; -exports.ChannelSelectMenuBuilder = require('./structures/ChannelSelectMenuBuilder.js').ChannelSelectMenuBuilder; exports.ChannelSelectMenuComponent = require('./structures/ChannelSelectMenuComponent.js').ChannelSelectMenuComponent; exports.ChannelSelectMenuInteraction = require('./structures/ChannelSelectMenuInteraction.js').ChannelSelectMenuInteraction; @@ -137,7 +134,6 @@ exports.ContextMenuCommandInteraction = require('./structures/ContextMenuCommandInteraction.js').ContextMenuCommandInteraction; exports.DMChannel = require('./structures/DMChannel.js').DMChannel; exports.Embed = require('./structures/Embed.js').Embed; -exports.EmbedBuilder = require('./structures/EmbedBuilder.js').EmbedBuilder; exports.Emoji = require('./structures/Emoji.js').Emoji; exports.Entitlement = require('./structures/Entitlement.js').Entitlement; exports.ForumChannel = require('./structures/ForumChannel.js').ForumChannel; @@ -168,8 +164,6 @@ exports.InteractionWebhook = require('./structures/InteractionWebhook.js').Inter exports.Invite = require('./structures/Invite.js').Invite; exports.InviteGuild = require('./structures/InviteGuild.js').InviteGuild; exports.MediaChannel = require('./structures/MediaChannel.js').MediaChannel; -exports.MentionableSelectMenuBuilder = - require('./structures/MentionableSelectMenuBuilder.js').MentionableSelectMenuBuilder; exports.MentionableSelectMenuComponent = require('./structures/MentionableSelectMenuComponent.js').MentionableSelectMenuComponent; exports.MentionableSelectMenuInteraction = @@ -185,7 +179,6 @@ exports.MessageContextMenuCommandInteraction = exports.MessageMentions = require('./structures/MessageMentions.js').MessageMentions; exports.MessagePayload = require('./structures/MessagePayload.js').MessagePayload; exports.MessageReaction = require('./structures/MessageReaction.js').MessageReaction; -exports.ModalBuilder = require('./structures/ModalBuilder.js').ModalBuilder; exports.ModalSubmitFields = require('./structures/ModalSubmitFields.js').ModalSubmitFields; exports.ModalSubmitInteraction = require('./structures/ModalSubmitInteraction.js').ModalSubmitInteraction; exports.OAuth2Guild = require('./structures/OAuth2Guild.js').OAuth2Guild; @@ -198,7 +191,6 @@ exports.ReactionCollector = require('./structures/ReactionCollector.js').Reactio exports.ReactionEmoji = require('./structures/ReactionEmoji.js').ReactionEmoji; exports.RichPresenceAssets = require('./structures/Presence.js').RichPresenceAssets; exports.Role = require('./structures/Role.js').Role; -exports.RoleSelectMenuBuilder = require('./structures/RoleSelectMenuBuilder.js').RoleSelectMenuBuilder; exports.RoleSelectMenuComponent = require('./structures/RoleSelectMenuComponent.js').RoleSelectMenuComponent; exports.RoleSelectMenuInteraction = require('./structures/RoleSelectMenuInteraction.js').RoleSelectMenuInteraction; exports.SKU = require('./structures/SKU.js').SKU; @@ -206,17 +198,13 @@ exports.StageChannel = require('./structures/StageChannel.js').StageChannel; exports.StageInstance = require('./structures/StageInstance.js').StageInstance; exports.Sticker = require('./structures/Sticker.js').Sticker; exports.StickerPack = require('./structures/StickerPack.js').StickerPack; -exports.StringSelectMenuBuilder = require('./structures/StringSelectMenuBuilder.js').StringSelectMenuBuilder; exports.StringSelectMenuComponent = require('./structures/StringSelectMenuComponent.js').StringSelectMenuComponent; exports.StringSelectMenuInteraction = require('./structures/StringSelectMenuInteraction.js').StringSelectMenuInteraction; -exports.StringSelectMenuOptionBuilder = - require('./structures/StringSelectMenuOptionBuilder.js').StringSelectMenuOptionBuilder; exports.Subscription = require('./structures/Subscription.js').Subscription; exports.Team = require('./structures/Team.js').Team; exports.TeamMember = require('./structures/TeamMember.js').TeamMember; exports.TextChannel = require('./structures/TextChannel.js').TextChannel; -exports.TextInputBuilder = require('./structures/TextInputBuilder.js').TextInputBuilder; exports.TextInputComponent = require('./structures/TextInputComponent.js').TextInputComponent; exports.ThreadChannel = require('./structures/ThreadChannel.js').ThreadChannel; exports.ThreadMember = require('./structures/ThreadMember.js').ThreadMember; @@ -225,7 +213,6 @@ exports.Typing = require('./structures/Typing.js').Typing; exports.User = require('./structures/User.js').User; exports.UserContextMenuCommandInteraction = require('./structures/UserContextMenuCommandInteraction.js').UserContextMenuCommandInteraction; -exports.UserSelectMenuBuilder = require('./structures/UserSelectMenuBuilder.js').UserSelectMenuBuilder; exports.UserSelectMenuComponent = require('./structures/UserSelectMenuComponent.js').UserSelectMenuComponent; exports.UserSelectMenuInteraction = require('./structures/UserSelectMenuInteraction.js').UserSelectMenuInteraction; exports.VoiceChannel = require('./structures/VoiceChannel.js').VoiceChannel; diff --git a/packages/discord.js/src/structures/ActionRowBuilder.js b/packages/discord.js/src/structures/ActionRowBuilder.js deleted file mode 100644 index 1c6d341fb4c8..000000000000 --- a/packages/discord.js/src/structures/ActionRowBuilder.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - -const { ActionRowBuilder: BuildersActionRow } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); - -/** - * Represents an action row builder. - * @extends {BuildersActionRow} - */ -class ActionRowBuilder extends BuildersActionRow { - constructor({ components, ...data } = {}) { - super({ - ...toSnakeCase(data), - components: components?.map(component => createComponentBuilder(component)), - }); - } - - /** - * Creates a new action row builder from JSON data - * @param {ActionRow|ActionRowBuilder|APIActionRowComponent} other The other data - * @returns {ActionRowBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.ActionRowBuilder = ActionRowBuilder; - -const { createComponentBuilder } = require('../util/Components.js'); -const { toSnakeCase } = require('../util/Transformers.js'); - -/** - * @external BuildersActionRow - * @see {@link https://discord.js.org/docs/packages/builders/stable/ActionRowBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/ButtonBuilder.js b/packages/discord.js/src/structures/ButtonBuilder.js deleted file mode 100644 index de4fd7fb2c6a..000000000000 --- a/packages/discord.js/src/structures/ButtonBuilder.js +++ /dev/null @@ -1,44 +0,0 @@ -'use strict'; - -const { ButtonBuilder: BuildersButton } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); -const { resolvePartialEmoji } = require('../util/Util.js'); - -/** - * Represents a button builder. - * @extends {BuildersButton} - */ -class ButtonBuilder extends BuildersButton { - constructor({ emoji, ...data } = {}) { - super(toSnakeCase({ ...data, emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji })); - } - - /** - * Sets the emoji to display on this button - * @param {string|APIMessageComponentEmoji} emoji The emoji to display on this button - * @returns {ButtonBuilder} - */ - setEmoji(emoji) { - if (typeof emoji === 'string') { - return super.setEmoji(resolvePartialEmoji(emoji)); - } - return super.setEmoji(emoji); - } - - /** - * Creates a new button builder from JSON data - * @param {ButtonBuilder|ButtonComponent|APIButtonComponent} other The other data - * @returns {ButtonBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.ButtonBuilder = ButtonBuilder; - -/** - * @external BuildersButton - * @see {@link https://discord.js.org/docs/packages/builders/stable/ButtonBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/ChannelSelectMenuBuilder.js b/packages/discord.js/src/structures/ChannelSelectMenuBuilder.js deleted file mode 100644 index d9f80c710c6e..000000000000 --- a/packages/discord.js/src/structures/ChannelSelectMenuBuilder.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -const { ChannelSelectMenuBuilder: BuildersChannelSelectMenu } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); - -/** - * 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 {ChannelSelectMenuBuilder|ChannelSelectMenuComponent|APIChannelSelectComponent} other The other data - * @returns {ChannelSelectMenuBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.ChannelSelectMenuBuilder = ChannelSelectMenuBuilder; - -/** - * @external BuildersChannelSelectMenu - * @see {@link https://discord.js.org/docs/packages/builders/stable/ChannelSelectMenuBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/EmbedBuilder.js b/packages/discord.js/src/structures/EmbedBuilder.js deleted file mode 100644 index 50634fe5b2c4..000000000000 --- a/packages/discord.js/src/structures/EmbedBuilder.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; - -const { EmbedBuilder: BuildersEmbed, embedLength } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); -const { resolveColor } = require('../util/Util.js'); - -/** - * Represents an embed builder. - * @extends {BuildersEmbed} - */ -class EmbedBuilder extends BuildersEmbed { - constructor(data) { - super(toSnakeCase(data)); - } - - /** - * Sets the color of this embed - * @param {?ColorResolvable} color The color of the embed - * @returns {EmbedBuilder} - */ - setColor(color) { - return super.setColor(color && resolveColor(color)); - } - - /** - * Creates a new embed builder from JSON data - * @param {EmbedBuilder|Embed|APIEmbed} other The other data - * @returns {EmbedBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } - - /** - * The accumulated length for the embed title, description, fields, footer text, and author name. - * @type {number} - * @readonly - */ - get length() { - return embedLength(this.data); - } -} - -exports.EmbedBuilder = EmbedBuilder; - -/** - * @external BuildersEmbed - * @see {@link https://discord.js.org/docs/packages/builders/stable/EmbedBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/MentionableSelectMenuBuilder.js b/packages/discord.js/src/structures/MentionableSelectMenuBuilder.js deleted file mode 100644 index b2065874eb2a..000000000000 --- a/packages/discord.js/src/structures/MentionableSelectMenuBuilder.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -const { MentionableSelectMenuBuilder: BuildersMentionableSelectMenu } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); - -/** - * 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 {MentionableSelectMenuBuilder|MentionableSelectMenuComponent|APIMentionableSelectComponent} other - * The other data - * @returns {MentionableSelectMenuBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.MentionableSelectMenuBuilder = MentionableSelectMenuBuilder; - -/** - * @external BuildersMentionableSelectMenu - * @see {@link https://discord.js.org/docs/packages/builders/stable/MentionableSelectMenuBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/MessagePayload.js b/packages/discord.js/src/structures/MessagePayload.js index 4dfb4bda58d1..9f4a58a871ea 100644 --- a/packages/discord.js/src/structures/MessagePayload.js +++ b/packages/discord.js/src/structures/MessagePayload.js @@ -1,9 +1,9 @@ 'use strict'; const { Buffer } = require('node:buffer'); +const { ActionRowBuilder } = require('@discordjs/builders'); const { isJSONEncodable } = require('@discordjs/util'); const { DiscordSnowflake } = require('@sapphire/snowflake'); -const { ActionRowBuilder } = require('./ActionRowBuilder.js'); const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors/index.js'); const { resolveFile } = require('../util/DataResolver.js'); const { MessageFlagsBitField } = require('../util/MessageFlagsBitField.js'); diff --git a/packages/discord.js/src/structures/ModalBuilder.js b/packages/discord.js/src/structures/ModalBuilder.js deleted file mode 100644 index 3e68632de6cd..000000000000 --- a/packages/discord.js/src/structures/ModalBuilder.js +++ /dev/null @@ -1,36 +0,0 @@ -'use strict'; - -const { ModalBuilder: BuildersModal, ComponentBuilder } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); - -/** - * Represents a modal builder. - * @extends {BuildersModal} - */ -class ModalBuilder extends BuildersModal { - constructor({ components, ...data } = {}) { - super({ - ...toSnakeCase(data), - components: components?.map(component => - component instanceof ComponentBuilder ? component : toSnakeCase(component), - ), - }); - } - - /** - * Creates a new modal builder from JSON data - * @param {ModalBuilder|APIModalComponent} other The other data - * @returns {ModalBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.ModalBuilder = ModalBuilder; - -/** - * @external BuildersModal - * @see {@link https://discord.js.org/docs/packages/builders/stable/ModalBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/RoleSelectMenuBuilder.js b/packages/discord.js/src/structures/RoleSelectMenuBuilder.js deleted file mode 100644 index b031f88a7bd8..000000000000 --- a/packages/discord.js/src/structures/RoleSelectMenuBuilder.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -const { RoleSelectMenuBuilder: BuildersRoleSelectMenu } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); - -/** - * 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 {RoleSelectMenuBuilder|RoleSelectMenuComponent|APIRoleSelectComponent} other The other data - * @returns {RoleSelectMenuBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.RoleSelectMenuBuilder = RoleSelectMenuBuilder; - -/** - * @external BuildersRoleSelectMenu - * @see {@link https://discord.js.org/docs/packages/builders/stable/RoleSelectMenuBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/StringSelectMenuBuilder.js b/packages/discord.js/src/structures/StringSelectMenuBuilder.js deleted file mode 100644 index c90c2e6b43d8..000000000000 --- a/packages/discord.js/src/structures/StringSelectMenuBuilder.js +++ /dev/null @@ -1,79 +0,0 @@ -'use strict'; - -const { SelectMenuBuilder: BuildersSelectMenu, normalizeArray } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); -const { resolvePartialEmoji } = require('../util/Util.js'); - -/** - * 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 {SelectMenuComponentOptionData|APISelectMenuOption} selectMenuOption The option to normalize - * @returns {StringSelectMenuOptionBuilder|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} 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} 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 {StringSelectMenuBuilder|StringSelectMenuComponent|APIStringSelectComponent} other The other data - * @returns {StringSelectMenuBuilder} - */ - static from(other) { - if (isJSONEncodable(other)) { - return new this(other.toJSON()); - } - return new this(other); - } -} - -exports.StringSelectMenuBuilder = StringSelectMenuBuilder; - -/** - * @external BuildersSelectMenu - * @see {@link https://discord.js.org/docs/packages/builders/stable/StringSelectMenuBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/StringSelectMenuOptionBuilder.js b/packages/discord.js/src/structures/StringSelectMenuOptionBuilder.js deleted file mode 100644 index fd3a4524c349..000000000000 --- a/packages/discord.js/src/structures/StringSelectMenuOptionBuilder.js +++ /dev/null @@ -1,49 +0,0 @@ -'use strict'; - -const { SelectMenuOptionBuilder: BuildersSelectMenuOption } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); -const { resolvePartialEmoji } = require('../util/Util.js'); - -/** - * 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 {StringSelectMenuOptionBuilder|APISelectMenuOption} other The other data - * @returns {StringSelectMenuOptionBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.StringSelectMenuOptionBuilder = StringSelectMenuOptionBuilder; - -/** - * @external BuildersSelectMenuOption - * @see {@link https://discord.js.org/docs/packages/builders/stable/StringSelectMenuOptionBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/TextInputBuilder.js b/packages/discord.js/src/structures/TextInputBuilder.js deleted file mode 100644 index 478e09742bda..000000000000 --- a/packages/discord.js/src/structures/TextInputBuilder.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -const { TextInputBuilder: BuildersTextInput } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); - -/** - * Represents a text input builder. - * @extends {BuildersTextInput} - */ -class TextInputBuilder extends BuildersTextInput { - constructor(data) { - super(toSnakeCase(data)); - } - - /** - * Creates a new text input builder from JSON data - * @param {TextInputBuilder|TextInputComponent|APITextInputComponent} other The other data - * @returns {TextInputBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.TextInputBuilder = TextInputBuilder; - -/** - * @external BuildersTextInput - * @see {@link https://discord.js.org/docs/packages/builders/stable/TextInputBuilder:Class} - */ diff --git a/packages/discord.js/src/structures/UserSelectMenuBuilder.js b/packages/discord.js/src/structures/UserSelectMenuBuilder.js deleted file mode 100644 index c41615a8cf17..000000000000 --- a/packages/discord.js/src/structures/UserSelectMenuBuilder.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -const { UserSelectMenuBuilder: BuildersUserSelectMenu } = require('@discordjs/builders'); -const { isJSONEncodable } = require('@discordjs/util'); -const { toSnakeCase } = require('../util/Transformers.js'); - -/** - * 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 {UserSelectMenuBuilder|UserSelectMenuComponent|APIUserSelectComponent} other The other data - * @returns {UserSelectMenuBuilder} - */ - static from(other) { - return new this(isJSONEncodable(other) ? other.toJSON() : other); - } -} - -exports.UserSelectMenuBuilder = UserSelectMenuBuilder; - -/** - * @external BuildersUserSelectMenu - * @see {@link https://discord.js.org/docs/packages/builders/stable/UserSelectMenuBuilder:Class} - */ diff --git a/packages/discord.js/src/util/Components.js b/packages/discord.js/src/util/Components.js deleted file mode 100644 index b3124e4ecf03..000000000000 --- a/packages/discord.js/src/util/Components.js +++ /dev/null @@ -1,155 +0,0 @@ -'use strict'; - -const { ComponentBuilder } = require('@discordjs/builders'); -const { ComponentType } = require('discord-api-types/v10'); - -/** - * @typedef {Object} BaseComponentData - * @property {ComponentType} type The type of component - */ - -/** - * @typedef {BaseComponentData} ActionRowData - * @property {ComponentData[]} components The components in this action row - */ - -/** - * @typedef {BaseComponentData} ButtonComponentData - * @property {ButtonStyle} style The style of the button - * @property {?boolean} disabled Whether this button is disabled - * @property {string} label The label of this button - * @property {?APIMessageComponentEmoji} emoji The emoji on this button - * @property {?string} customId The custom id of the button - * @property {?string} url The URL of the button - */ - -/** - * @typedef {object} SelectMenuComponentOptionData - * @property {string} label The label of the option - * @property {string} value The value of the option - * @property {?string} description The description of the option - * @property {?APIMessageComponentEmoji} emoji The emoji on the option - * @property {?boolean} default Whether this option is selected by default - */ - -/** - * @typedef {BaseComponentData} SelectMenuComponentData - * @property {string} customId The custom id of the select menu - * @property {?boolean} disabled Whether the select menu is disabled or not - * @property {?number} maxValues The maximum amount of options that can be selected - * @property {?number} minValues The minimum amount of options that can be selected - * @property {?SelectMenuComponentOptionData[]} options The options in this select menu - * @property {?string} placeholder The placeholder of the select menu - */ - -/** - * @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} MessageComponentData - */ - -/** - * @typedef {BaseComponentData} TextInputComponentData - * @property {string} customId The custom id of the text input - * @property {TextInputStyle} style The style of the text input - * @property {string} label The text that appears on top of the text input field - * @property {?number} minLength The minimum number of characters that can be entered in the text input - * @property {?number} maxLength The maximum number of characters that can be entered in the text input - * @property {?boolean} required Whether or not the text input is required or not - * @property {?string} value The pre-filled text in the text input - * @property {?string} placeholder Placeholder for the text input - */ - -/** - * @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData|TextInputComponentData} ComponentData - */ - -/** - * Any emoji data that can be used within a button - * @typedef {APIMessageComponentEmoji|string} ComponentEmojiResolvable - */ - -/** - * Transforms API data into a component - * @param {APIMessageComponent|Component} data The data to create the component from - * @returns {Component} - * @ignore - */ -function createComponent(data) { - if (data instanceof Component) { - return data; - } - - switch (data.type) { - case ComponentType.ActionRow: - return new ActionRow(data); - case ComponentType.Button: - return new ButtonComponent(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); - } -} - -/** - * Transforms API data into a component builder - * @param {APIMessageComponent|ComponentBuilder} data The data to create the component from - * @returns {ComponentBuilder} - * @ignore - */ -function createComponentBuilder(data) { - if (data instanceof ComponentBuilder) { - return data; - } - - switch (data.type) { - case ComponentType.ActionRow: - return new ActionRowBuilder(data); - case ComponentType.Button: - return new ButtonBuilder(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); - } -} - -exports.createComponent = createComponent; -exports.createComponentBuilder = createComponentBuilder; - -const { ActionRow } = require('../structures/ActionRow.js'); -const { ActionRowBuilder } = require('../structures/ActionRowBuilder.js'); -const { ButtonBuilder } = require('../structures/ButtonBuilder.js'); -const { ButtonComponent } = require('../structures/ButtonComponent.js'); -const { ChannelSelectMenuBuilder } = require('../structures/ChannelSelectMenuBuilder.js'); -const { ChannelSelectMenuComponent } = require('../structures/ChannelSelectMenuComponent.js'); -const { Component } = require('../structures/Component.js'); -const { MentionableSelectMenuBuilder } = require('../structures/MentionableSelectMenuBuilder.js'); -const { MentionableSelectMenuComponent } = require('../structures/MentionableSelectMenuComponent.js'); -const { RoleSelectMenuBuilder } = require('../structures/RoleSelectMenuBuilder.js'); -const { RoleSelectMenuComponent } = require('../structures/RoleSelectMenuComponent.js'); -const { StringSelectMenuBuilder } = require('../structures/StringSelectMenuBuilder.js'); -const { StringSelectMenuComponent } = require('../structures/StringSelectMenuComponent.js'); -const { TextInputBuilder } = require('../structures/TextInputBuilder.js'); -const { TextInputComponent } = require('../structures/TextInputComponent.js'); -const { UserSelectMenuBuilder } = require('../structures/UserSelectMenuBuilder.js'); -const { UserSelectMenuComponent } = require('../structures/UserSelectMenuComponent.js'); diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 93a828f29af3..ef44dfe98add 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -1,21 +1,3 @@ -import { - ActionRowBuilder as BuilderActionRow, - MessageActionRowComponentBuilder, - ButtonBuilder as BuilderButtonComponent, - EmbedBuilder as BuildersEmbed, - ChannelSelectMenuBuilder as BuilderChannelSelectMenuComponent, - MentionableSelectMenuBuilder as BuilderMentionableSelectMenuComponent, - RoleSelectMenuBuilder as BuilderRoleSelectMenuComponent, - StringSelectMenuBuilder as BuilderStringSelectMenuComponent, - UserSelectMenuBuilder as BuilderUserSelectMenuComponent, - TextInputBuilder as BuilderTextInputComponent, - SelectMenuOptionBuilder as BuildersSelectMenuOption, - ModalActionRowComponentBuilder, - ModalBuilder as BuildersModal, - AnyComponentBuilder, - type RestOrArray, - ApplicationCommandOptionAllowedChannelTypes, -} from '@discordjs/builders'; import { Awaitable, JSONEncodable } from '@discordjs/util'; import { Collection, ReadonlyCollection } from '@discordjs/collection'; import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest'; @@ -237,6 +219,7 @@ import { RawWidgetData, RawWidgetMemberData, } from './rawDataTypes.js'; +import { ApplicationCommandOptionAllowedChannelTypes, MessageActionRowComponentBuilder } from '@discordjs/builders'; //#region Classes @@ -294,22 +277,6 @@ export interface ActionRowData extends BuilderActionRow { - public constructor( - data?: Partial< - | ActionRowData> - | APIActionRowComponent - >, - ); - public static from( - other: - | JSONEncodable>> - | APIActionRowComponent>, - ): ActionRowBuilder; -} - export type MessageActionRowComponent = | ButtonComponent | StringSelectMenuComponent @@ -751,70 +718,6 @@ export class ButtonComponent extends Component { export type ComponentEmojiResolvable = APIMessageComponentEmoji | string; -export class ButtonBuilder extends BuilderButtonComponent { - public constructor(data?: Partial | Partial); - public static from(other: JSONEncodable | APIButtonComponent): ButtonBuilder; - public override setEmoji(emoji: ComponentEmojiResolvable): this; -} - -export class StringSelectMenuBuilder extends BuilderStringSelectMenuComponent { - public constructor(data?: Partial); - private static normalizeEmoji( - selectMenuOption: JSONEncodable | SelectMenuComponentOptionData, - ): (APISelectMenuOption | StringSelectMenuOptionBuilder)[]; - public override addOptions( - ...options: RestOrArray - ): this; - public override setOptions( - ...options: RestOrArray - ): this; - public static from( - other: JSONEncodable | APIStringSelectComponent, - ): StringSelectMenuBuilder; -} - -export class UserSelectMenuBuilder extends BuilderUserSelectMenuComponent { - public constructor(data?: Partial); - public static from(other: JSONEncodable | APIUserSelectComponent): UserSelectMenuBuilder; -} - -export class RoleSelectMenuBuilder extends BuilderRoleSelectMenuComponent { - public constructor(data?: Partial); - public static from(other: JSONEncodable | APIRoleSelectComponent): RoleSelectMenuBuilder; -} - -export class MentionableSelectMenuBuilder extends BuilderMentionableSelectMenuComponent { - public constructor(data?: Partial); - public static from( - other: JSONEncodable | APIMentionableSelectComponent, - ): MentionableSelectMenuBuilder; -} - -export class ChannelSelectMenuBuilder extends BuilderChannelSelectMenuComponent { - public constructor(data?: Partial); - public static from( - other: JSONEncodable | APIChannelSelectComponent, - ): ChannelSelectMenuBuilder; -} - -export class StringSelectMenuOptionBuilder extends BuildersSelectMenuOption { - public constructor(data?: SelectMenuComponentOptionData | APISelectMenuOption); - public override setEmoji(emoji: ComponentEmojiResolvable): this; - public static from(other: JSONEncodable | APISelectMenuOption): StringSelectMenuOptionBuilder; -} - -export class ModalBuilder extends BuildersModal { - public constructor(data?: Partial | Partial); - public static from( - other: JSONEncodable | APIModalInteractionResponseCallbackData, - ): ModalBuilder; -} - -export class TextInputBuilder extends BuilderTextInputComponent { - public constructor(data?: Partial); - public static from(other: JSONEncodable | APITextInputComponent): TextInputBuilder; -} - export class TextInputComponent extends Component { public get customId(): string; public get value(): string; @@ -872,13 +775,6 @@ export interface EmbedAssetData extends Omit { proxyURL?: string; } -export class EmbedBuilder extends BuildersEmbed { - public constructor(data?: EmbedData | APIEmbed); - public override setColor(color: ColorResolvable | null): this; - public static from(other: JSONEncodable | APIEmbed): EmbedBuilder; - public get length(): number; -} - export class Embed { private constructor(data: APIEmbed); public readonly data: Readonly; @@ -6266,16 +6162,6 @@ export interface MessageCollectorOptions extends CollectorOptions<[Message, Coll maxProcessed?: number; } -export type MessageComponent = - | Component - | ActionRowBuilder - | ButtonComponent - | StringSelectMenuComponent - | UserSelectMenuComponent - | RoleSelectMenuComponent - | MentionableSelectMenuComponent - | ChannelSelectMenuComponent; - export type CollectedMessageInteraction = Exclude< CollectedInteraction, ModalSubmitInteraction @@ -6346,7 +6232,7 @@ export interface BaseMessageOptions { | AttachmentPayload )[]; components?: readonly ( - | JSONEncodable> + | JSONEncodable> | ActionRowData | APIActionRowComponent )[]; diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 4396e6a5f843..77526cae8dfb 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -36,6 +36,7 @@ import { GuildScheduledEventRecurrenceRuleFrequency, GuildScheduledEventRecurrenceRuleMonth, GuildScheduledEventRecurrenceRuleWeekday, + APIButtonComponentWithCustomId, } from 'discord-api-types/v10'; import { ApplicationCommand, @@ -218,9 +219,12 @@ import { PartialPollAnswer, PollAnswer, PollAnswerVoterManager, + PrimaryButtonBuilder, + resolveColor, + createComponentBuilder, } from './index.js'; import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd'; -import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders'; +import type { ContextMenuCommandBuilder, ChatInputCommandBuilder } from '@discordjs/builders'; import { ReadonlyCollection } from '@discordjs/collection'; // Test type transformation: @@ -347,11 +351,9 @@ client.on('interactionCreate', async interaction => { if (interaction.type !== InteractionType.ApplicationCommand) return; - void new ActionRowBuilder(); + const button = new PrimaryButtonBuilder(); - const button = new ButtonBuilder(); - - const actionRow = new ActionRowBuilder({ + const actionRow = new ActionRowBuilder({ type: ComponentType.ActionRow, components: [button.toJSON()], }); @@ -622,7 +624,7 @@ client.on('messageCreate', async message => { }); // Check that both builders and builder data can be sent in messages - const row = new ActionRowBuilder(); + const row = new ActionRowBuilder(); const rawButtonsRow: ActionRowData = { type: ComponentType.ActionRow, @@ -639,7 +641,7 @@ client.on('messageCreate', async message => { const buttonsRow: ActionRowData = { type: ComponentType.ActionRow, - components: [new ButtonBuilder()], + components: [new PrimaryButtonBuilder()], }; const rawStringSelectMenuRow: ActionRowData = { @@ -754,7 +756,7 @@ client.on('presenceUpdate', (oldPresence, { client }) => { expectType>(client); }); -declare const slashCommandBuilder: SlashCommandBuilder; +declare const slashCommandBuilder: ChatInputCommandBuilder; declare const contextMenuCommandBuilder: ContextMenuCommandBuilder; client.on('clientReady', async client => { @@ -1326,7 +1328,7 @@ client.on('guildCreate', async g => { const row: ActionRowData = { type: ComponentType.ActionRow, components: [ - new ButtonBuilder(), + new PrimaryButtonBuilder(), { type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' }, { type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' }, { type: ComponentType.StringSelect, customId: 'foo', options: [{ label: 'label', value: 'value' }] }, @@ -1338,12 +1340,12 @@ client.on('guildCreate', async g => { ], }; - const row2 = new ActionRowBuilder({ + const row2 = new ActionRowBuilder({ type: ComponentType.ActionRow, components: [ - { type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' }, + { type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', custom_id: 'foo' }, { type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' }, - { type: ComponentType.StringSelect, customId: 'foo', options: [{ label: 'label', value: 'value' }] }, + { type: ComponentType.StringSelect, custom_id: 'foo', options: [{ label: 'label', value: 'value' }] }, ], }); @@ -2370,16 +2372,16 @@ expectType< >(NonThreadGuildBasedChannel); expectType(GuildTextBasedChannel); -const button = new ButtonBuilder({ +const button = new PrimaryButtonBuilder({ label: 'test', style: ButtonStyle.Primary, - customId: 'test', + custom_id: 'test', }); const selectMenu = new StringSelectMenuBuilder({ - maxValues: 10, - minValues: 2, - customId: 'test', + max_values: 10, + min_values: 2, + custom_id: 'test', }); new ActionRowBuilder({ @@ -2387,16 +2389,16 @@ new ActionRowBuilder({ }); new StringSelectMenuBuilder({ - customId: 'foo', + custom_id: 'foo', }); -new ButtonBuilder({ +new PrimaryButtonBuilder({ style: ButtonStyle.Danger, }) - .setEmoji('') - .setEmoji('<:foo:123>') - .setEmoji('foobar:123') - .setEmoji('😏') + .setEmoji(resolvePartialEmoji('')) + .setEmoji(resolvePartialEmoji('<:foo:123>')) + .setEmoji(resolvePartialEmoji('foobar:123')) + .setEmoji(resolvePartialEmoji('😏')) .setEmoji({ name: 'test', id: '123', @@ -2406,7 +2408,7 @@ new ButtonBuilder({ // @ts-expect-error new EmbedBuilder().setColor('abc'); -new EmbedBuilder().setColor('#ffffff'); +new EmbedBuilder().setColor(resolveColor('#ffffff')); expectNotAssignable>({ type: ComponentType.ActionRow, @@ -2445,73 +2447,61 @@ chatInputInteraction.showModal({ }); declare const stringSelectMenuData: APIStringSelectComponent; -StringSelectMenuBuilder.from(stringSelectMenuData); +new StringSelectMenuBuilder(stringSelectMenuData); declare const userSelectMenuData: APIUserSelectComponent; -UserSelectMenuBuilder.from(userSelectMenuData); +new UserSelectMenuBuilder(userSelectMenuData); declare const roleSelectMenuData: APIRoleSelectComponent; -RoleSelectMenuBuilder.from(roleSelectMenuData); +new RoleSelectMenuBuilder(roleSelectMenuData); declare const channelSelectMenuData: APIChannelSelectComponent; -ChannelSelectMenuBuilder.from(channelSelectMenuData); +new ChannelSelectMenuBuilder(channelSelectMenuData); declare const mentionableSelectMenuData: APIMentionableSelectComponent; -MentionableSelectMenuBuilder.from(mentionableSelectMenuData); +new MentionableSelectMenuBuilder(mentionableSelectMenuData); declare const stringSelectMenuComp: StringSelectMenuComponent; -StringSelectMenuBuilder.from(stringSelectMenuComp); +new StringSelectMenuBuilder(stringSelectMenuComp.toJSON()); declare const userSelectMenuComp: UserSelectMenuComponent; -UserSelectMenuBuilder.from(userSelectMenuComp); +new UserSelectMenuBuilder(userSelectMenuComp.toJSON()); declare const roleSelectMenuComp: RoleSelectMenuComponent; -RoleSelectMenuBuilder.from(roleSelectMenuComp); +new RoleSelectMenuBuilder(roleSelectMenuComp.toJSON()); declare const channelSelectMenuComp: ChannelSelectMenuComponent; -ChannelSelectMenuBuilder.from(channelSelectMenuComp); +new ChannelSelectMenuBuilder(channelSelectMenuComp.toJSON()); declare const mentionableSelectMenuComp: MentionableSelectMenuComponent; -MentionableSelectMenuBuilder.from(mentionableSelectMenuComp); +new MentionableSelectMenuBuilder(mentionableSelectMenuComp.toJSON()); -declare const buttonData: APIButtonComponent; -ButtonBuilder.from(buttonData); +declare const buttonData: APIButtonComponentWithCustomId; +new PrimaryButtonBuilder(buttonData); declare const buttonComp: ButtonComponent; -ButtonBuilder.from(buttonComp); +createComponentBuilder(buttonComp.toJSON()); declare const modalData: APIModalInteractionResponseCallbackData; -ModalBuilder.from(modalData); +new ModalBuilder(modalData); declare const textInputData: APITextInputComponent; -TextInputBuilder.from(textInputData); +new TextInputBuilder(textInputData); declare const textInputComp: TextInputComponent; -TextInputBuilder.from(textInputComp); +new TextInputBuilder(textInputComp); declare const embedData: APIEmbed; -EmbedBuilder.from(embedData); +new EmbedBuilder(embedData); declare const embedComp: Embed; -EmbedBuilder.from(embedComp); +new EmbedBuilder(embedComp.toJSON()); declare const actionRowData: APIActionRowComponent; -ActionRowBuilder.from(actionRowData); +new ActionRowBuilder(actionRowData); declare const actionRowComp: ActionRow; -ActionRowBuilder.from(actionRowComp); - -declare const buttonsActionRowData: APIActionRowComponent; -declare const buttonsActionRowComp: ActionRow; - -expectType>(ActionRowBuilder.from(buttonsActionRowData)); -expectType>(ActionRowBuilder.from(buttonsActionRowComp)); - -declare const anyComponentsActionRowData: APIActionRowComponent; -declare const anyComponentsActionRowComp: ActionRow; - -expectType(ActionRowBuilder.from(anyComponentsActionRowData)); -expectType(ActionRowBuilder.from(anyComponentsActionRowComp)); +new ActionRowBuilder(actionRowComp.toJSON()); type UserMentionChannels = DMChannel | PartialDMChannel; declare const channelMentionChannels: Exclude; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1999d3315606..b12a0ffc3e63 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -896,8 +896,8 @@ importers: packages/discord.js: dependencies: '@discordjs/builders': - specifier: ^1.9.0 - version: 1.9.0 + specifier: workspace:^ + version: link:../builders '@discordjs/collection': specifier: workspace:^ version: link:../collection @@ -2145,26 +2145,18 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} - '@definitelytyped/header-parser@0.2.16': - resolution: {integrity: sha512-UFsgPft5bhZn07UNGz/9ck4AhdKgLFEOmi2DNr7gXcGL89zbe3u5oVafKUT8j1HOtSBjT8ZEQsXHKlbq+wwF/Q==} + '@definitelytyped/header-parser@0.2.17': + resolution: {integrity: sha512-U0juKFkTOcbkSfO83WSzMEJHYDwoBFiq0tf/JszulL3+7UoSiqunpGmxXS54bm3eGqy7GWjV8AqPQHdeoEaWBQ==} engines: {node: '>=18.18.0'} - '@definitelytyped/typescript-versions@0.1.6': - resolution: {integrity: sha512-gQpXFteIKrOw4ldmBZQfBrD3WobaIG1SwOr/3alXWkcYbkOWa2NRxQbiaYQ2IvYTGaZK26miJw0UOAFiuIs4gA==} + '@definitelytyped/typescript-versions@0.1.7': + resolution: {integrity: sha512-sBzBi1SBn79OkSr8V0H+FzR7QumHk23syPyRxod/VRBrSkgN9rCliIe+nqLoWRAKN8EeKbp00ketnJNLZhucdA==} engines: {node: '>=18.18.0'} '@definitelytyped/utils@0.1.8': resolution: {integrity: sha512-4JINx4Rttha29f50PBsJo48xZXx/He5yaIWJRwVarhYAN947+S84YciHl+AIhQNRPAFkg8+5qFngEGtKxQDWXA==} engines: {node: '>=18.18.0'} - '@discordjs/builders@1.9.0': - resolution: {integrity: sha512-0zx8DePNVvQibh5ly5kCEei5wtPBIUbSoE9n+91Rlladz4tgtFbJ36PZMxxZrTEOQ7AHMZ/b0crT/0fCy6FTKg==} - engines: {node: '>=18'} - - '@discordjs/formatters@0.5.0': - resolution: {integrity: sha512-98b3i+Y19RFq1Xke4NkVY46x8KjJQjldHUuEbCqMvp1F5Iq9HgnGpu91jOi/Ufazhty32eRsKnnzS8n4c+L93g==} - engines: {node: '>=18'} - '@discordjs/node-pre-gyp@0.4.5': resolution: {integrity: sha512-YJOVVZ545x24mHzANfYoy0BJX5PDyeZlpiJjDkUBM/V/Ao7TFX9lcUvCN4nr0tbr5ubeaXxtEBILUrHtTphVeQ==} hasBin: true @@ -2173,10 +2165,6 @@ packages: resolution: {integrity: sha512-NEE76A96FtQ5YuoAVlOlB3ryMPrkXbUCTQICHGKb8ShtjXyubGicjRMouHtP1RpuDdm16cDa+oI3aAMo1zQRUQ==} engines: {node: '>=12.0.0'} - '@discordjs/util@1.1.1': - resolution: {integrity: sha512-eddz6UnOBEB1oITPinyrB2Pttej49M9FZQY8NxgEvc3tq6ZICZ19m70RsmzRdDHk80O9NoYN/25AqJl8vPVf/g==} - engines: {node: '>=18'} - '@edge-runtime/format@2.2.1': resolution: {integrity: sha512-JQTRVuiusQLNNLe2W9tnzBlV/GvSVcozLl4XZHk5swnRZ/v6jp8TqR8P7sqmJsQqblDZ3EztcWmLDbhRje/+8g==} engines: {node: '>=16'} @@ -4773,10 +4761,6 @@ packages: resolution: {integrity: sha512-DJbCGmvi8UZAu/hh85auQL8bODFlpcS3cWjRJZ5/cXTLekmGvs/CrRxrIzwbA6+poyYojo5rK4qu8trmjfneog==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} - '@sapphire/shapeshift@4.0.0': - resolution: {integrity: sha512-d9dUmWVA7MMiKobL3VpLF8P2aeanRTu6ypG2OIaEv/ZHH/SUQ2iHOVyi5wAPjQ+HmnMuL0whK9ez8I/raWbtIg==} - engines: {node: '>=v16'} - '@sapphire/snowflake@3.5.5': resolution: {integrity: sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} @@ -7326,9 +7310,6 @@ packages: discord-api-types@0.37.118: resolution: {integrity: sha512-MQkHHZcytmNQ3nQOBj6a0z38swsmHiROX7hdayfd0eWVrLxaQp/6tWBZ7FO2MCKKsc+W3QWnnfOJTbtyk8C4TQ==} - discord-api-types@0.37.97: - resolution: {integrity: sha512-No1BXPcVkyVD4ZVmbNgDKaBoqgeQ+FJpzZ8wqHkfmBnTZig1FcH3iPPersiK1TUIAzgClh2IvOuVUYfcWLQAOA==} - dlv@1.1.3: resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} @@ -13859,13 +13840,13 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 - '@definitelytyped/header-parser@0.2.16': + '@definitelytyped/header-parser@0.2.17': dependencies: - '@definitelytyped/typescript-versions': 0.1.6 + '@definitelytyped/typescript-versions': 0.1.7 '@definitelytyped/utils': 0.1.8 semver: 7.6.3 - '@definitelytyped/typescript-versions@0.1.6': {} + '@definitelytyped/typescript-versions@0.1.7': {} '@definitelytyped/utils@0.1.8': dependencies: @@ -13878,20 +13859,6 @@ snapshots: tar-stream: 3.1.7 which: 4.0.0 - '@discordjs/builders@1.9.0': - dependencies: - '@discordjs/formatters': 0.5.0 - '@discordjs/util': 1.1.1 - '@sapphire/shapeshift': 4.0.0 - discord-api-types: 0.37.97 - fast-deep-equal: 3.1.3 - ts-mixer: 6.0.4 - tslib: 2.8.1 - - '@discordjs/formatters@0.5.0': - dependencies: - discord-api-types: 0.37.97 - '@discordjs/node-pre-gyp@0.4.5(encoding@0.1.13)': dependencies: detect-libc: 2.0.3 @@ -13915,8 +13882,6 @@ snapshots: - encoding - supports-color - '@discordjs/util@1.1.1': {} - '@edge-runtime/format@2.2.1': {} '@edge-runtime/node-utils@2.3.0': {} @@ -16998,11 +16963,6 @@ snapshots: '@sapphire/result@2.7.2': {} - '@sapphire/shapeshift@4.0.0': - dependencies: - fast-deep-equal: 3.1.3 - lodash: 4.17.21 - '@sapphire/snowflake@3.5.5': {} '@sapphire/utilities@3.17.0': {} @@ -20354,8 +20314,6 @@ snapshots: discord-api-types@0.37.118: {} - discord-api-types@0.37.97: {} - dlv@1.1.3: {} dmd@6.2.3: @@ -20405,7 +20363,7 @@ snapshots: dts-critic@3.3.11(typescript@5.5.4): dependencies: - '@definitelytyped/header-parser': 0.2.16 + '@definitelytyped/header-parser': 0.2.17 command-exists: 1.2.9 rimraf: 3.0.2 semver: 6.3.1 @@ -20415,8 +20373,8 @@ snapshots: dtslint@4.2.1(typescript@5.5.4): dependencies: - '@definitelytyped/header-parser': 0.2.16 - '@definitelytyped/typescript-versions': 0.1.6 + '@definitelytyped/header-parser': 0.2.17 + '@definitelytyped/typescript-versions': 0.1.7 '@definitelytyped/utils': 0.1.8 dts-critic: 3.3.11(typescript@5.5.4) fs-extra: 6.0.1 From aa60cd725af3cbd51f8a590a56009d1c02a7c37d Mon Sep 17 00:00:00 2001 From: didinele Date: Wed, 26 Feb 2025 16:16:38 +0200 Subject: [PATCH 02/11] chore: remove unused import --- packages/discord.js/typings/index.test-d.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 77526cae8dfb..85f8ec819c57 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -127,7 +127,6 @@ import { TextInputBuilder, TextInputComponent, Embed, - MessageActionRowComponentBuilder, GuildBanManager, GuildBan, MessageManager, From 4c39d75a02e9488c12ccd72901055169c34a5bc9 Mon Sep 17 00:00:00 2001 From: didinele Date: Thu, 27 Feb 2025 15:04:55 +0200 Subject: [PATCH 03/11] chore: requested changes --- .../src/structures/MessagePayload.js | 7 +- packages/discord.js/src/util/Util.js | 1 - packages/discord.js/typings/index.d.ts | 2 - packages/discord.js/typings/index.test-d.ts | 69 +------------------ 4 files changed, 2 insertions(+), 77 deletions(-) diff --git a/packages/discord.js/src/structures/MessagePayload.js b/packages/discord.js/src/structures/MessagePayload.js index 9f4a58a871ea..6ff2189a7fc1 100644 --- a/packages/discord.js/src/structures/MessagePayload.js +++ b/packages/discord.js/src/structures/MessagePayload.js @@ -1,7 +1,6 @@ 'use strict'; const { Buffer } = require('node:buffer'); -const { ActionRowBuilder } = require('@discordjs/builders'); const { isJSONEncodable } = require('@discordjs/util'); const { DiscordSnowflake } = require('@sapphire/snowflake'); const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors/index.js'); @@ -132,10 +131,6 @@ class MessagePayload { } } - const components = this.options.components?.map(component => - (isJSONEncodable(component) ? component : new ActionRowBuilder(component)).toJSON(), - ); - let username; let avatarURL; let threadName; @@ -215,7 +210,7 @@ class MessagePayload { embeds: this.options.embeds?.map(embed => isJSONEncodable(embed) ? embed.toJSON() : this.target.client.options.jsonTransformer(embed), ), - components, + components: this.options.components, username, avatar_url: avatarURL, allowed_mentions: content === undefined && message_reference === undefined ? undefined : allowedMentions, diff --git a/packages/discord.js/src/util/Util.js b/packages/discord.js/src/util/Util.js index fe8ef235a984..d51553e8f163 100644 --- a/packages/discord.js/src/util/Util.js +++ b/packages/discord.js/src/util/Util.js @@ -112,7 +112,6 @@ function parseEmoji(text) { * Resolves a partial emoji object from an {@link EmojiIdentifierResolvable}, without checking a Client. * @param {Emoji|EmojiIdentifierResolvable} emoji Emoji identifier to resolve * @returns {?(PartialEmoji|PartialEmojiOnlyId)} Supplying a snowflake yields `PartialEmojiOnlyId`. - * @private */ function resolvePartialEmoji(emoji) { if (!emoji) return null; diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index ef44dfe98add..51173e9897a6 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3404,9 +3404,7 @@ export function moveElementInArray( ): number; export function parseEmoji(text: string): PartialEmoji | null; export function resolveColor(color: ColorResolvable): number; -/** @internal */ export function resolvePartialEmoji(emoji: Snowflake): PartialEmojiOnlyId; -/** @internal */ export function resolvePartialEmoji(emoji: Emoji | EmojiIdentifierResolvable): PartialEmoji | null; /** @internal */ export function resolveGuildEmoji(client: Client, emojiId: Snowflake): GuildEmoji | null; diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index 85f8ec819c57..b3151736da1a 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -27,11 +27,6 @@ import { APIActionRowComponent, APIActionRowComponentTypes, APIStringSelectComponent, - APIUserSelectComponent, - APIRoleSelectComponent, - APIChannelSelectComponent, - APIMentionableSelectComponent, - APIModalInteractionResponseCallbackData, WebhookType, GuildScheduledEventRecurrenceRuleFrequency, GuildScheduledEventRecurrenceRuleMonth, @@ -350,11 +345,9 @@ client.on('interactionCreate', async interaction => { if (interaction.type !== InteractionType.ApplicationCommand) return; - const button = new PrimaryButtonBuilder(); - const actionRow = new ActionRowBuilder({ type: ComponentType.ActionRow, - components: [button.toJSON()], + components: [{ custom_id: '123', label: 'test', style: ButtonStyle.Primary, type: ComponentType.Button }], }); actionRow.toJSON(); @@ -2371,42 +2364,6 @@ expectType< >(NonThreadGuildBasedChannel); expectType(GuildTextBasedChannel); -const button = new PrimaryButtonBuilder({ - label: 'test', - style: ButtonStyle.Primary, - custom_id: 'test', -}); - -const selectMenu = new StringSelectMenuBuilder({ - max_values: 10, - min_values: 2, - custom_id: 'test', -}); - -new ActionRowBuilder({ - components: [selectMenu.toJSON(), button.toJSON()], -}); - -new StringSelectMenuBuilder({ - custom_id: 'foo', -}); - -new PrimaryButtonBuilder({ - style: ButtonStyle.Danger, -}) - .setEmoji(resolvePartialEmoji('')) - .setEmoji(resolvePartialEmoji('<:foo:123>')) - .setEmoji(resolvePartialEmoji('foobar:123')) - .setEmoji(resolvePartialEmoji('😏')) - .setEmoji({ - name: 'test', - id: '123', - animated: false, - }); - -// @ts-expect-error -new EmbedBuilder().setColor('abc'); - new EmbedBuilder().setColor(resolveColor('#ffffff')); expectNotAssignable>({ @@ -2445,21 +2402,6 @@ chatInputInteraction.showModal({ ], }); -declare const stringSelectMenuData: APIStringSelectComponent; -new StringSelectMenuBuilder(stringSelectMenuData); - -declare const userSelectMenuData: APIUserSelectComponent; -new UserSelectMenuBuilder(userSelectMenuData); - -declare const roleSelectMenuData: APIRoleSelectComponent; -new RoleSelectMenuBuilder(roleSelectMenuData); - -declare const channelSelectMenuData: APIChannelSelectComponent; -new ChannelSelectMenuBuilder(channelSelectMenuData); - -declare const mentionableSelectMenuData: APIMentionableSelectComponent; -new MentionableSelectMenuBuilder(mentionableSelectMenuData); - declare const stringSelectMenuComp: StringSelectMenuComponent; new StringSelectMenuBuilder(stringSelectMenuComp.toJSON()); @@ -2481,12 +2423,6 @@ new PrimaryButtonBuilder(buttonData); declare const buttonComp: ButtonComponent; createComponentBuilder(buttonComp.toJSON()); -declare const modalData: APIModalInteractionResponseCallbackData; -new ModalBuilder(modalData); - -declare const textInputData: APITextInputComponent; -new TextInputBuilder(textInputData); - declare const textInputComp: TextInputComponent; new TextInputBuilder(textInputComp); @@ -2496,9 +2432,6 @@ new EmbedBuilder(embedData); declare const embedComp: Embed; new EmbedBuilder(embedComp.toJSON()); -declare const actionRowData: APIActionRowComponent; -new ActionRowBuilder(actionRowData); - declare const actionRowComp: ActionRow; new ActionRowBuilder(actionRowComp.toJSON()); From 12287632ef802c41746c5411b53f3e76c980bca1 Mon Sep 17 00:00:00 2001 From: didinele Date: Thu, 27 Feb 2025 16:00:21 +0200 Subject: [PATCH 04/11] chore: unused imports --- packages/discord.js/typings/index.test-d.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index b3151736da1a..a7e469c0c31e 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -20,12 +20,9 @@ import { AuditLogEvent, ButtonStyle, TextInputStyle, - APITextInputComponent, APIEmbed, ApplicationCommandType, APIMessage, - APIActionRowComponent, - APIActionRowComponentTypes, APIStringSelectComponent, WebhookType, GuildScheduledEventRecurrenceRuleFrequency, From d8acf92cc3e44dce01b6fd258974bc8d321bb3e0 Mon Sep 17 00:00:00 2001 From: didinele Date: Thu, 27 Feb 2025 17:38:39 +0200 Subject: [PATCH 05/11] chore: suggested changes --- packages/discord.js/src/structures/MessagePayload.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/discord.js/src/structures/MessagePayload.js b/packages/discord.js/src/structures/MessagePayload.js index 6ff2189a7fc1..bf07b026b743 100644 --- a/packages/discord.js/src/structures/MessagePayload.js +++ b/packages/discord.js/src/structures/MessagePayload.js @@ -131,6 +131,10 @@ class MessagePayload { } } + const components = this.options.components?.map(component => + isJSONEncodable(component) ? component.toJSON() : this.target.client.options.jsonTransformer(component), + ); + let username; let avatarURL; let threadName; @@ -210,7 +214,7 @@ class MessagePayload { embeds: this.options.embeds?.map(embed => isJSONEncodable(embed) ? embed.toJSON() : this.target.client.options.jsonTransformer(embed), ), - components: this.options.components, + components, username, avatar_url: avatarURL, allowed_mentions: content === undefined && message_reference === undefined ? undefined : allowedMentions, From 3c67d84f5431309ed8f230ff1225428278a95e26 Mon Sep 17 00:00:00 2001 From: didinele Date: Thu, 27 Feb 2025 23:22:35 +0200 Subject: [PATCH 06/11] fix: re-introduce needed function --- packages/discord.js/src/util/Components.js | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 packages/discord.js/src/util/Components.js diff --git a/packages/discord.js/src/util/Components.js b/packages/discord.js/src/util/Components.js new file mode 100644 index 000000000000..302b98b95927 --- /dev/null +++ b/packages/discord.js/src/util/Components.js @@ -0,0 +1,41 @@ +'use strict'; + +const { ComponentType } = require('discord-api-types/v10'); +const { ActionRow } = require('../structures/ActionRow.js'); +const { ButtonComponent } = require('../structures/ButtonComponent.js'); +const { ChannelSelectMenuComponent } = require('../structures/ChannelSelectMenuComponent.js'); +const { Component } = require('../structures/Component.js'); +const { MentionableSelectMenuComponent } = require('../structures/MentionableSelectMenuComponent.js'); +const { RoleSelectMenuComponent } = require('../structures/RoleSelectMenuComponent.js'); +const { StringSelectMenuComponent } = require('../structures/StringSelectMenuComponent.js'); +const { TextInputComponent } = require('../structures/TextInputComponent.js'); +const { UserSelectMenuComponent } = require('../structures/UserSelectMenuComponent.js'); + +function createComponent(data) { + if (data instanceof Component) { + return data; + } + + switch (data.type) { + case ComponentType.ActionRow: + return new ActionRow(data); + case ComponentType.Button: + return new ButtonComponent(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); + } +} + +exports.createComponent = createComponent; From bd038175db623b9c2ac23e4a3ca2ee8a0c2b274d Mon Sep 17 00:00:00 2001 From: didinele Date: Fri, 28 Feb 2025 10:33:49 +0200 Subject: [PATCH 07/11] fix: circular dep --- packages/discord.js/src/util/Components.js | 25 ++++++++++++++-------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/packages/discord.js/src/util/Components.js b/packages/discord.js/src/util/Components.js index 302b98b95927..abbe94f94dbc 100644 --- a/packages/discord.js/src/util/Components.js +++ b/packages/discord.js/src/util/Components.js @@ -1,16 +1,13 @@ 'use strict'; const { ComponentType } = require('discord-api-types/v10'); -const { ActionRow } = require('../structures/ActionRow.js'); -const { ButtonComponent } = require('../structures/ButtonComponent.js'); -const { ChannelSelectMenuComponent } = require('../structures/ChannelSelectMenuComponent.js'); -const { Component } = require('../structures/Component.js'); -const { MentionableSelectMenuComponent } = require('../structures/MentionableSelectMenuComponent.js'); -const { RoleSelectMenuComponent } = require('../structures/RoleSelectMenuComponent.js'); -const { StringSelectMenuComponent } = require('../structures/StringSelectMenuComponent.js'); -const { TextInputComponent } = require('../structures/TextInputComponent.js'); -const { UserSelectMenuComponent } = require('../structures/UserSelectMenuComponent.js'); +/** + * Transforms API data into a component + * @param {APIMessageComponent|Component} data The data to create the component from + * @returns {Component} + * @ignore + */ function createComponent(data) { if (data instanceof Component) { return data; @@ -39,3 +36,13 @@ function createComponent(data) { } exports.createComponent = createComponent; + +const { ActionRow } = require('../structures/ActionRow.js'); +const { ButtonComponent } = require('../structures/ButtonComponent.js'); +const { ChannelSelectMenuComponent } = require('../structures/ChannelSelectMenuComponent.js'); +const { Component } = require('../structures/Component.js'); +const { MentionableSelectMenuComponent } = require('../structures/MentionableSelectMenuComponent.js'); +const { RoleSelectMenuComponent } = require('../structures/RoleSelectMenuComponent.js'); +const { StringSelectMenuComponent } = require('../structures/StringSelectMenuComponent.js'); +const { TextInputComponent } = require('../structures/TextInputComponent.js'); +const { UserSelectMenuComponent } = require('../structures/UserSelectMenuComponent.js'); From d1769a00706364ccae69a0afb1b837cca92b6f8b Mon Sep 17 00:00:00 2001 From: didinele Date: Fri, 28 Feb 2025 20:24:15 +0200 Subject: [PATCH 08/11] chore: remove unused type --- packages/discord.js/typings/index.d.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 51173e9897a6..e62ef6b40be9 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3440,11 +3440,6 @@ export function createChannel( extras?: CreateChannelOptions, ): Channel; -export type ComponentData = - | MessageActionRowComponentData - | ModalActionRowComponentData - | ActionRowData; - export class VoiceChannel extends BaseGuildVoiceChannel { public get speakable(): boolean; public type: ChannelType.GuildVoice; From 571e71e0a780dbf1d2db1c2ecf9c174f4b489f0b Mon Sep 17 00:00:00 2001 From: didinele Date: Sat, 1 Mar 2025 12:35:26 +0200 Subject: [PATCH 09/11] chore: fix docs --- packages/discord.js/src/util/Components.js | 59 ++++++++++++++++++++++ packages/discord.js/typings/index.d.ts | 5 ++ 2 files changed, 64 insertions(+) diff --git a/packages/discord.js/src/util/Components.js b/packages/discord.js/src/util/Components.js index abbe94f94dbc..5144de04564e 100644 --- a/packages/discord.js/src/util/Components.js +++ b/packages/discord.js/src/util/Components.js @@ -2,6 +2,65 @@ const { ComponentType } = require('discord-api-types/v10'); +/** + * @typedef {Object} BaseComponentData + * @property {ComponentType} type The type of component + */ + +/** + * @typedef {BaseComponentData} ActionRowData + * @property {ComponentData[]} components The components in this action row + */ + +/** + * @typedef {BaseComponentData} ButtonComponentData + * @property {ButtonStyle} style The style of the button + * @property {?boolean} disabled Whether this button is disabled + * @property {string} label The label of this button + * @property {?APIMessageComponentEmoji} emoji The emoji on this button + * @property {?string} customId The custom id of the button + * @property {?string} url The URL of the button + */ + +/** + * @typedef {object} SelectMenuComponentOptionData + * @property {string} label The label of the option + * @property {string} value The value of the option + * @property {?string} description The description of the option + * @property {?APIMessageComponentEmoji} emoji The emoji on the option + * @property {?boolean} default Whether this option is selected by default + */ + +/** + * @typedef {BaseComponentData} SelectMenuComponentData + * @property {string} customId The custom id of the select menu + * @property {?boolean} disabled Whether the select menu is disabled or not + * @property {?number} maxValues The maximum amount of options that can be selected + * @property {?number} minValues The minimum amount of options that can be selected + * @property {?SelectMenuComponentOptionData[]} options The options in this select menu + * @property {?string} placeholder The placeholder of the select menu + */ + +/** + * @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} MessageComponentData + */ + +/** + * @typedef {BaseComponentData} TextInputComponentData + * @property {string} customId The custom id of the text input + * @property {TextInputStyle} style The style of the text input + * @property {string} label The text that appears on top of the text input field + * @property {?number} minLength The minimum number of characters that can be entered in the text input + * @property {?number} maxLength The maximum number of characters that can be entered in the text input + * @property {?boolean} required Whether or not the text input is required or not + * @property {?string} value The pre-filled text in the text input + * @property {?string} placeholder Placeholder for the text input + */ + +/** + * @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData|TextInputComponentData} ComponentData + */ + /** * Transforms API data into a component * @param {APIMessageComponent|Component} data The data to create the component from diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index e62ef6b40be9..51173e9897a6 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -3440,6 +3440,11 @@ export function createChannel( extras?: CreateChannelOptions, ): Channel; +export type ComponentData = + | MessageActionRowComponentData + | ModalActionRowComponentData + | ActionRowData; + export class VoiceChannel extends BaseGuildVoiceChannel { public get speakable(): boolean; public type: ChannelType.GuildVoice; From fa0ba72008de25b833c650da98dc854e2cffd56a Mon Sep 17 00:00:00 2001 From: didinele Date: Sun, 2 Mar 2025 13:13:33 +0200 Subject: [PATCH 10/11] fix: bad type --- packages/discord.js/typings/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 51173e9897a6..0737a25ba1ee 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -6230,7 +6230,7 @@ export interface BaseMessageOptions { | AttachmentPayload )[]; components?: readonly ( - | JSONEncodable> + | JSONEncodable> | ActionRowData | APIActionRowComponent )[]; From f0a56389e2f8b4d2ab094fadf270eeb9511b4ddc Mon Sep 17 00:00:00 2001 From: didinele Date: Wed, 5 Mar 2025 14:31:55 +0200 Subject: [PATCH 11/11] chore: update tests --- packages/discord.js/typings/index.d.ts | 4 ++-- packages/discord.js/typings/index.test-d.ts | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/discord.js/typings/index.d.ts b/packages/discord.js/typings/index.d.ts index 0737a25ba1ee..4cf6b1b415ed 100644 --- a/packages/discord.js/typings/index.d.ts +++ b/packages/discord.js/typings/index.d.ts @@ -6230,9 +6230,9 @@ export interface BaseMessageOptions { | AttachmentPayload )[]; components?: readonly ( - | JSONEncodable> + | JSONEncodable> | ActionRowData - | APIActionRowComponent + | APIActionRowComponent )[]; } diff --git a/packages/discord.js/typings/index.test-d.ts b/packages/discord.js/typings/index.test-d.ts index a7e469c0c31e..c327afdc02af 100644 --- a/packages/discord.js/typings/index.test-d.ts +++ b/packages/discord.js/typings/index.test-d.ts @@ -347,8 +347,6 @@ client.on('interactionCreate', async interaction => { components: [{ custom_id: '123', label: 'test', style: ButtonStyle.Primary, type: ComponentType.Button }], }); - actionRow.toJSON(); - await interaction.reply({ content: 'Hi!', components: [actionRow] }); // @ts-expect-error