discord.js 15.0.0-dev.1740746538-46be1567a → 15.0.0-dev.1740874409-d1f56ffb2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "discord.js",
4
- "version": "15.0.0-dev.1740746538-46be1567a",
4
+ "version": "15.0.0-dev.1740874409-d1f56ffb2",
5
5
  "description": "A powerful library for interacting with the Discord API",
6
6
  "main": "./src/index.js",
7
7
  "types": "./typings/index.d.ts",
@@ -52,6 +52,7 @@
52
52
  "homepage": "https://discord.js.org",
53
53
  "funding": "https://github.com/discordjs/discord.js?sponsor",
54
54
  "dependencies": {
55
+ "@discordjs/builders": "^1.9.0",
55
56
  "@sapphire/snowflake": "3.5.5",
56
57
  "@vladfrangu/async_event_emitter": "^2.4.6",
57
58
  "discord-api-types": "^0.37.118",
@@ -59,11 +60,10 @@
59
60
  "lodash.snakecase": "4.1.1",
60
61
  "tslib": "^2.8.1",
61
62
  "undici": "6.21.1",
62
- "@discordjs/builders": "^1.9.0",
63
- "@discordjs/collection": "^2.1.1",
64
63
  "@discordjs/formatters": "^0.5.0",
65
- "@discordjs/util": "^1.1.1",
64
+ "@discordjs/collection": "^2.1.1",
66
65
  "@discordjs/rest": "^2.4.0",
66
+ "@discordjs/util": "^1.1.1",
67
67
  "@discordjs/ws": "^2.0.0"
68
68
  },
69
69
  "devDependencies": {
@@ -81,9 +81,9 @@
81
81
  "tslint": "6.1.3",
82
82
  "turbo": "^2.3.3",
83
83
  "typescript": "~5.5.4",
84
- "@discordjs/docgen": "^0.12.1",
84
+ "@discordjs/api-extractor": "^7.38.1",
85
85
  "@discordjs/scripts": "^0.1.0",
86
- "@discordjs/api-extractor": "^7.38.1"
86
+ "@discordjs/docgen": "^0.12.1"
87
87
  },
88
88
  "engines": {
89
89
  "node": ">=22.12.0"
package/src/index.js CHANGED
@@ -92,6 +92,7 @@ exports.VoiceStateManager = require('./managers/VoiceStateManager.js').VoiceStat
92
92
 
93
93
  // Structures
94
94
  exports.ActionRow = require('./structures/ActionRow.js').ActionRow;
95
+ exports.ActionRowBuilder = require('./structures/ActionRowBuilder.js').ActionRowBuilder;
95
96
  exports.Activity = require('./structures/Presence.js').Activity;
96
97
  exports.AnnouncementChannel = require('./structures/AnnouncementChannel.js').AnnouncementChannel;
97
98
  exports.AnonymousGuild = require('./structures/AnonymousGuild.js').AnonymousGuild;
@@ -114,9 +115,11 @@ exports.BaseGuildTextChannel = require('./structures/BaseGuildTextChannel.js').B
114
115
  exports.BaseGuildVoiceChannel = require('./structures/BaseGuildVoiceChannel.js').BaseGuildVoiceChannel;
115
116
  exports.BaseInteraction = require('./structures/BaseInteraction.js').BaseInteraction;
116
117
  exports.BaseSelectMenuComponent = require('./structures/BaseSelectMenuComponent.js').BaseSelectMenuComponent;
118
+ exports.ButtonBuilder = require('./structures/ButtonBuilder.js').ButtonBuilder;
117
119
  exports.ButtonComponent = require('./structures/ButtonComponent.js').ButtonComponent;
118
120
  exports.ButtonInteraction = require('./structures/ButtonInteraction.js').ButtonInteraction;
119
121
  exports.CategoryChannel = require('./structures/CategoryChannel.js').CategoryChannel;
122
+ exports.ChannelSelectMenuBuilder = require('./structures/ChannelSelectMenuBuilder.js').ChannelSelectMenuBuilder;
120
123
  exports.ChannelSelectMenuComponent = require('./structures/ChannelSelectMenuComponent.js').ChannelSelectMenuComponent;
121
124
  exports.ChannelSelectMenuInteraction =
122
125
  require('./structures/ChannelSelectMenuInteraction.js').ChannelSelectMenuInteraction;
@@ -134,6 +137,7 @@ exports.ContextMenuCommandInteraction =
134
137
  require('./structures/ContextMenuCommandInteraction.js').ContextMenuCommandInteraction;
135
138
  exports.DMChannel = require('./structures/DMChannel.js').DMChannel;
136
139
  exports.Embed = require('./structures/Embed.js').Embed;
140
+ exports.EmbedBuilder = require('./structures/EmbedBuilder.js').EmbedBuilder;
137
141
  exports.Emoji = require('./structures/Emoji.js').Emoji;
138
142
  exports.Entitlement = require('./structures/Entitlement.js').Entitlement;
139
143
  exports.ForumChannel = require('./structures/ForumChannel.js').ForumChannel;
@@ -164,6 +168,8 @@ exports.InteractionWebhook = require('./structures/InteractionWebhook.js').Inter
164
168
  exports.Invite = require('./structures/Invite.js').Invite;
165
169
  exports.InviteGuild = require('./structures/InviteGuild.js').InviteGuild;
166
170
  exports.MediaChannel = require('./structures/MediaChannel.js').MediaChannel;
171
+ exports.MentionableSelectMenuBuilder =
172
+ require('./structures/MentionableSelectMenuBuilder.js').MentionableSelectMenuBuilder;
167
173
  exports.MentionableSelectMenuComponent =
168
174
  require('./structures/MentionableSelectMenuComponent.js').MentionableSelectMenuComponent;
169
175
  exports.MentionableSelectMenuInteraction =
@@ -179,6 +185,7 @@ exports.MessageContextMenuCommandInteraction =
179
185
  exports.MessageMentions = require('./structures/MessageMentions.js').MessageMentions;
180
186
  exports.MessagePayload = require('./structures/MessagePayload.js').MessagePayload;
181
187
  exports.MessageReaction = require('./structures/MessageReaction.js').MessageReaction;
188
+ exports.ModalBuilder = require('./structures/ModalBuilder.js').ModalBuilder;
182
189
  exports.ModalSubmitFields = require('./structures/ModalSubmitFields.js').ModalSubmitFields;
183
190
  exports.ModalSubmitInteraction = require('./structures/ModalSubmitInteraction.js').ModalSubmitInteraction;
184
191
  exports.OAuth2Guild = require('./structures/OAuth2Guild.js').OAuth2Guild;
@@ -191,6 +198,7 @@ exports.ReactionCollector = require('./structures/ReactionCollector.js').Reactio
191
198
  exports.ReactionEmoji = require('./structures/ReactionEmoji.js').ReactionEmoji;
192
199
  exports.RichPresenceAssets = require('./structures/Presence.js').RichPresenceAssets;
193
200
  exports.Role = require('./structures/Role.js').Role;
201
+ exports.RoleSelectMenuBuilder = require('./structures/RoleSelectMenuBuilder.js').RoleSelectMenuBuilder;
194
202
  exports.RoleSelectMenuComponent = require('./structures/RoleSelectMenuComponent.js').RoleSelectMenuComponent;
195
203
  exports.RoleSelectMenuInteraction = require('./structures/RoleSelectMenuInteraction.js').RoleSelectMenuInteraction;
196
204
  exports.SKU = require('./structures/SKU.js').SKU;
@@ -198,13 +206,17 @@ exports.StageChannel = require('./structures/StageChannel.js').StageChannel;
198
206
  exports.StageInstance = require('./structures/StageInstance.js').StageInstance;
199
207
  exports.Sticker = require('./structures/Sticker.js').Sticker;
200
208
  exports.StickerPack = require('./structures/StickerPack.js').StickerPack;
209
+ exports.StringSelectMenuBuilder = require('./structures/StringSelectMenuBuilder.js').StringSelectMenuBuilder;
201
210
  exports.StringSelectMenuComponent = require('./structures/StringSelectMenuComponent.js').StringSelectMenuComponent;
202
211
  exports.StringSelectMenuInteraction =
203
212
  require('./structures/StringSelectMenuInteraction.js').StringSelectMenuInteraction;
213
+ exports.StringSelectMenuOptionBuilder =
214
+ require('./structures/StringSelectMenuOptionBuilder.js').StringSelectMenuOptionBuilder;
204
215
  exports.Subscription = require('./structures/Subscription.js').Subscription;
205
216
  exports.Team = require('./structures/Team.js').Team;
206
217
  exports.TeamMember = require('./structures/TeamMember.js').TeamMember;
207
218
  exports.TextChannel = require('./structures/TextChannel.js').TextChannel;
219
+ exports.TextInputBuilder = require('./structures/TextInputBuilder.js').TextInputBuilder;
208
220
  exports.TextInputComponent = require('./structures/TextInputComponent.js').TextInputComponent;
209
221
  exports.ThreadChannel = require('./structures/ThreadChannel.js').ThreadChannel;
210
222
  exports.ThreadMember = require('./structures/ThreadMember.js').ThreadMember;
@@ -213,6 +225,7 @@ exports.Typing = require('./structures/Typing.js').Typing;
213
225
  exports.User = require('./structures/User.js').User;
214
226
  exports.UserContextMenuCommandInteraction =
215
227
  require('./structures/UserContextMenuCommandInteraction.js').UserContextMenuCommandInteraction;
228
+ exports.UserSelectMenuBuilder = require('./structures/UserSelectMenuBuilder.js').UserSelectMenuBuilder;
216
229
  exports.UserSelectMenuComponent = require('./structures/UserSelectMenuComponent.js').UserSelectMenuComponent;
217
230
  exports.UserSelectMenuInteraction = require('./structures/UserSelectMenuInteraction.js').UserSelectMenuInteraction;
218
231
  exports.VoiceChannel = require('./structures/VoiceChannel.js').VoiceChannel;
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ const { ActionRowBuilder: BuildersActionRow } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+
6
+ /**
7
+ * Represents an action row builder.
8
+ * @extends {BuildersActionRow}
9
+ */
10
+ class ActionRowBuilder extends BuildersActionRow {
11
+ constructor({ components, ...data } = {}) {
12
+ super({
13
+ ...toSnakeCase(data),
14
+ components: components?.map(component => createComponentBuilder(component)),
15
+ });
16
+ }
17
+
18
+ /**
19
+ * Creates a new action row builder from JSON data
20
+ * @param {ActionRow|ActionRowBuilder|APIActionRowComponent} other The other data
21
+ * @returns {ActionRowBuilder}
22
+ */
23
+ static from(other) {
24
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
25
+ }
26
+ }
27
+
28
+ exports.ActionRowBuilder = ActionRowBuilder;
29
+
30
+ const { createComponentBuilder } = require('../util/Components.js');
31
+ const { toSnakeCase } = require('../util/Transformers.js');
32
+
33
+ /**
34
+ * @external BuildersActionRow
35
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/ActionRowBuilder:Class}
36
+ */
@@ -0,0 +1,44 @@
1
+ 'use strict';
2
+
3
+ const { ButtonBuilder: BuildersButton } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+ const { resolvePartialEmoji } = require('../util/Util.js');
7
+
8
+ /**
9
+ * Represents a button builder.
10
+ * @extends {BuildersButton}
11
+ */
12
+ class ButtonBuilder extends BuildersButton {
13
+ constructor({ emoji, ...data } = {}) {
14
+ super(toSnakeCase({ ...data, emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji }));
15
+ }
16
+
17
+ /**
18
+ * Sets the emoji to display on this button
19
+ * @param {string|APIMessageComponentEmoji} emoji The emoji to display on this button
20
+ * @returns {ButtonBuilder}
21
+ */
22
+ setEmoji(emoji) {
23
+ if (typeof emoji === 'string') {
24
+ return super.setEmoji(resolvePartialEmoji(emoji));
25
+ }
26
+ return super.setEmoji(emoji);
27
+ }
28
+
29
+ /**
30
+ * Creates a new button builder from JSON data
31
+ * @param {ButtonBuilder|ButtonComponent|APIButtonComponent} other The other data
32
+ * @returns {ButtonBuilder}
33
+ */
34
+ static from(other) {
35
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
36
+ }
37
+ }
38
+
39
+ exports.ButtonBuilder = ButtonBuilder;
40
+
41
+ /**
42
+ * @external BuildersButton
43
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/ButtonBuilder:Class}
44
+ */
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const { ChannelSelectMenuBuilder: BuildersChannelSelectMenu } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+
7
+ /**
8
+ * Class used to build select menu components to be sent through the API
9
+ * @extends {BuildersChannelSelectMenu}
10
+ */
11
+ class ChannelSelectMenuBuilder extends BuildersChannelSelectMenu {
12
+ constructor(data = {}) {
13
+ super(toSnakeCase(data));
14
+ }
15
+
16
+ /**
17
+ * Creates a new select menu builder from JSON data
18
+ * @param {ChannelSelectMenuBuilder|ChannelSelectMenuComponent|APIChannelSelectComponent} other The other data
19
+ * @returns {ChannelSelectMenuBuilder}
20
+ */
21
+ static from(other) {
22
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
23
+ }
24
+ }
25
+
26
+ exports.ChannelSelectMenuBuilder = ChannelSelectMenuBuilder;
27
+
28
+ /**
29
+ * @external BuildersChannelSelectMenu
30
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/ChannelSelectMenuBuilder:Class}
31
+ */
@@ -0,0 +1,50 @@
1
+ 'use strict';
2
+
3
+ const { EmbedBuilder: BuildersEmbed, embedLength } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+ const { resolveColor } = require('../util/Util.js');
7
+
8
+ /**
9
+ * Represents an embed builder.
10
+ * @extends {BuildersEmbed}
11
+ */
12
+ class EmbedBuilder extends BuildersEmbed {
13
+ constructor(data) {
14
+ super(toSnakeCase(data));
15
+ }
16
+
17
+ /**
18
+ * Sets the color of this embed
19
+ * @param {?ColorResolvable} color The color of the embed
20
+ * @returns {EmbedBuilder}
21
+ */
22
+ setColor(color) {
23
+ return super.setColor(color && resolveColor(color));
24
+ }
25
+
26
+ /**
27
+ * Creates a new embed builder from JSON data
28
+ * @param {EmbedBuilder|Embed|APIEmbed} other The other data
29
+ * @returns {EmbedBuilder}
30
+ */
31
+ static from(other) {
32
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
33
+ }
34
+
35
+ /**
36
+ * The accumulated length for the embed title, description, fields, footer text, and author name.
37
+ * @type {number}
38
+ * @readonly
39
+ */
40
+ get length() {
41
+ return embedLength(this.data);
42
+ }
43
+ }
44
+
45
+ exports.EmbedBuilder = EmbedBuilder;
46
+
47
+ /**
48
+ * @external BuildersEmbed
49
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/EmbedBuilder:Class}
50
+ */
@@ -0,0 +1,32 @@
1
+ 'use strict';
2
+
3
+ const { MentionableSelectMenuBuilder: BuildersMentionableSelectMenu } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+
7
+ /**
8
+ * Class used to build select menu components to be sent through the API
9
+ * @extends {BuildersMentionableSelectMenu}
10
+ */
11
+ class MentionableSelectMenuBuilder extends BuildersMentionableSelectMenu {
12
+ constructor(data = {}) {
13
+ super(toSnakeCase(data));
14
+ }
15
+
16
+ /**
17
+ * Creates a new select menu builder from JSON data
18
+ * @param {MentionableSelectMenuBuilder|MentionableSelectMenuComponent|APIMentionableSelectComponent} other
19
+ * The other data
20
+ * @returns {MentionableSelectMenuBuilder}
21
+ */
22
+ static from(other) {
23
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
24
+ }
25
+ }
26
+
27
+ exports.MentionableSelectMenuBuilder = MentionableSelectMenuBuilder;
28
+
29
+ /**
30
+ * @external BuildersMentionableSelectMenu
31
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/MentionableSelectMenuBuilder:Class}
32
+ */
@@ -3,6 +3,7 @@
3
3
  const { Buffer } = require('node:buffer');
4
4
  const { isJSONEncodable } = require('@discordjs/util');
5
5
  const { DiscordSnowflake } = require('@sapphire/snowflake');
6
+ const { ActionRowBuilder } = require('./ActionRowBuilder.js');
6
7
  const { DiscordjsError, DiscordjsRangeError, ErrorCodes } = require('../errors/index.js');
7
8
  const { resolveFile } = require('../util/DataResolver.js');
8
9
  const { MessageFlagsBitField } = require('../util/MessageFlagsBitField.js');
@@ -132,7 +133,7 @@ class MessagePayload {
132
133
  }
133
134
 
134
135
  const components = this.options.components?.map(component =>
135
- isJSONEncodable(component) ? component.toJSON() : this.target.client.options.jsonTransformer(component),
136
+ (isJSONEncodable(component) ? component : new ActionRowBuilder(component)).toJSON(),
136
137
  );
137
138
 
138
139
  let username;
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ const { ModalBuilder: BuildersModal, ComponentBuilder } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+
7
+ /**
8
+ * Represents a modal builder.
9
+ * @extends {BuildersModal}
10
+ */
11
+ class ModalBuilder extends BuildersModal {
12
+ constructor({ components, ...data } = {}) {
13
+ super({
14
+ ...toSnakeCase(data),
15
+ components: components?.map(component =>
16
+ component instanceof ComponentBuilder ? component : toSnakeCase(component),
17
+ ),
18
+ });
19
+ }
20
+
21
+ /**
22
+ * Creates a new modal builder from JSON data
23
+ * @param {ModalBuilder|APIModalComponent} other The other data
24
+ * @returns {ModalBuilder}
25
+ */
26
+ static from(other) {
27
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
28
+ }
29
+ }
30
+
31
+ exports.ModalBuilder = ModalBuilder;
32
+
33
+ /**
34
+ * @external BuildersModal
35
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/ModalBuilder:Class}
36
+ */
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const { RoleSelectMenuBuilder: BuildersRoleSelectMenu } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+
7
+ /**
8
+ * Class used to build select menu components to be sent through the API
9
+ * @extends {BuildersRoleSelectMenu}
10
+ */
11
+ class RoleSelectMenuBuilder extends BuildersRoleSelectMenu {
12
+ constructor(data = {}) {
13
+ super(toSnakeCase(data));
14
+ }
15
+
16
+ /**
17
+ * Creates a new select menu builder from JSON data
18
+ * @param {RoleSelectMenuBuilder|RoleSelectMenuComponent|APIRoleSelectComponent} other The other data
19
+ * @returns {RoleSelectMenuBuilder}
20
+ */
21
+ static from(other) {
22
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
23
+ }
24
+ }
25
+
26
+ exports.RoleSelectMenuBuilder = RoleSelectMenuBuilder;
27
+
28
+ /**
29
+ * @external BuildersRoleSelectMenu
30
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/RoleSelectMenuBuilder:Class}
31
+ */
@@ -0,0 +1,79 @@
1
+ 'use strict';
2
+
3
+ const { SelectMenuBuilder: BuildersSelectMenu, normalizeArray } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+ const { resolvePartialEmoji } = require('../util/Util.js');
7
+
8
+ /**
9
+ * Class used to build select menu components to be sent through the API
10
+ * @extends {BuildersSelectMenu}
11
+ */
12
+ class StringSelectMenuBuilder extends BuildersSelectMenu {
13
+ constructor({ options, ...data } = {}) {
14
+ super(
15
+ toSnakeCase({
16
+ ...data,
17
+ options: options?.map(({ emoji, ...option }) => ({
18
+ ...option,
19
+ emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
20
+ })),
21
+ }),
22
+ );
23
+ }
24
+
25
+ /**
26
+ * Normalizes a select menu option emoji
27
+ * @param {SelectMenuComponentOptionData|APISelectMenuOption} selectMenuOption The option to normalize
28
+ * @returns {StringSelectMenuOptionBuilder|APISelectMenuOption}
29
+ * @private
30
+ */
31
+ static normalizeEmoji(selectMenuOption) {
32
+ if (isJSONEncodable(selectMenuOption)) {
33
+ return selectMenuOption;
34
+ }
35
+
36
+ const { emoji, ...option } = selectMenuOption;
37
+ return {
38
+ ...option,
39
+ emoji: typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
40
+ };
41
+ }
42
+
43
+ /**
44
+ * Adds options to this select menu
45
+ * @param {RestOrArray<APISelectMenuOption>} options The options to add to this select menu
46
+ * @returns {StringSelectMenuBuilder}
47
+ */
48
+ addOptions(...options) {
49
+ return super.addOptions(normalizeArray(options).map(option => StringSelectMenuBuilder.normalizeEmoji(option)));
50
+ }
51
+
52
+ /**
53
+ * Sets the options on this select menu
54
+ * @param {RestOrArray<APISelectMenuOption>} options The options to set on this select menu
55
+ * @returns {StringSelectMenuBuilder}
56
+ */
57
+ setOptions(...options) {
58
+ return super.setOptions(normalizeArray(options).map(option => StringSelectMenuBuilder.normalizeEmoji(option)));
59
+ }
60
+
61
+ /**
62
+ * Creates a new select menu builder from json data
63
+ * @param {StringSelectMenuBuilder|StringSelectMenuComponent|APIStringSelectComponent} other The other data
64
+ * @returns {StringSelectMenuBuilder}
65
+ */
66
+ static from(other) {
67
+ if (isJSONEncodable(other)) {
68
+ return new this(other.toJSON());
69
+ }
70
+ return new this(other);
71
+ }
72
+ }
73
+
74
+ exports.StringSelectMenuBuilder = StringSelectMenuBuilder;
75
+
76
+ /**
77
+ * @external BuildersSelectMenu
78
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/StringSelectMenuBuilder:Class}
79
+ */
@@ -0,0 +1,49 @@
1
+ 'use strict';
2
+
3
+ const { SelectMenuOptionBuilder: BuildersSelectMenuOption } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+ const { resolvePartialEmoji } = require('../util/Util.js');
7
+
8
+ /**
9
+ * Represents a select menu option builder.
10
+ * @extends {BuildersSelectMenuOption}
11
+ */
12
+ class StringSelectMenuOptionBuilder extends BuildersSelectMenuOption {
13
+ constructor({ emoji, ...data } = {}) {
14
+ super(
15
+ toSnakeCase({
16
+ ...data,
17
+ emoji: emoji && typeof emoji === 'string' ? resolvePartialEmoji(emoji) : emoji,
18
+ }),
19
+ );
20
+ }
21
+
22
+ /**
23
+ * Sets the emoji to display on this option
24
+ * @param {ComponentEmojiResolvable} emoji The emoji to display on this option
25
+ * @returns {StringSelectMenuOptionBuilder}
26
+ */
27
+ setEmoji(emoji) {
28
+ if (typeof emoji === 'string') {
29
+ return super.setEmoji(resolvePartialEmoji(emoji));
30
+ }
31
+ return super.setEmoji(emoji);
32
+ }
33
+
34
+ /**
35
+ * Creates a new select menu option builder from JSON data
36
+ * @param {StringSelectMenuOptionBuilder|APISelectMenuOption} other The other data
37
+ * @returns {StringSelectMenuOptionBuilder}
38
+ */
39
+ static from(other) {
40
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
41
+ }
42
+ }
43
+
44
+ exports.StringSelectMenuOptionBuilder = StringSelectMenuOptionBuilder;
45
+
46
+ /**
47
+ * @external BuildersSelectMenuOption
48
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/StringSelectMenuOptionBuilder:Class}
49
+ */
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const { TextInputBuilder: BuildersTextInput } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+
7
+ /**
8
+ * Represents a text input builder.
9
+ * @extends {BuildersTextInput}
10
+ */
11
+ class TextInputBuilder extends BuildersTextInput {
12
+ constructor(data) {
13
+ super(toSnakeCase(data));
14
+ }
15
+
16
+ /**
17
+ * Creates a new text input builder from JSON data
18
+ * @param {TextInputBuilder|TextInputComponent|APITextInputComponent} other The other data
19
+ * @returns {TextInputBuilder}
20
+ */
21
+ static from(other) {
22
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
23
+ }
24
+ }
25
+
26
+ exports.TextInputBuilder = TextInputBuilder;
27
+
28
+ /**
29
+ * @external BuildersTextInput
30
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/TextInputBuilder:Class}
31
+ */
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ const { UserSelectMenuBuilder: BuildersUserSelectMenu } = require('@discordjs/builders');
4
+ const { isJSONEncodable } = require('@discordjs/util');
5
+ const { toSnakeCase } = require('../util/Transformers.js');
6
+
7
+ /**
8
+ * Class used to build select menu components to be sent through the API
9
+ * @extends {BuildersUserSelectMenu}
10
+ */
11
+ class UserSelectMenuBuilder extends BuildersUserSelectMenu {
12
+ constructor(data = {}) {
13
+ super(toSnakeCase(data));
14
+ }
15
+
16
+ /**
17
+ * Creates a new select menu builder from JSON data
18
+ * @param {UserSelectMenuBuilder|UserSelectMenuComponent|APIUserSelectComponent} other The other data
19
+ * @returns {UserSelectMenuBuilder}
20
+ */
21
+ static from(other) {
22
+ return new this(isJSONEncodable(other) ? other.toJSON() : other);
23
+ }
24
+ }
25
+
26
+ exports.UserSelectMenuBuilder = UserSelectMenuBuilder;
27
+
28
+ /**
29
+ * @external BuildersUserSelectMenu
30
+ * @see {@link https://discord.js.org/docs/packages/builders/stable/UserSelectMenuBuilder:Class}
31
+ */
@@ -1,7 +1,72 @@
1
1
  'use strict';
2
2
 
3
+ const { ComponentBuilder } = require('@discordjs/builders');
3
4
  const { ComponentType } = require('discord-api-types/v10');
4
5
 
6
+ /**
7
+ * @typedef {Object} BaseComponentData
8
+ * @property {ComponentType} type The type of component
9
+ */
10
+
11
+ /**
12
+ * @typedef {BaseComponentData} ActionRowData
13
+ * @property {ComponentData[]} components The components in this action row
14
+ */
15
+
16
+ /**
17
+ * @typedef {BaseComponentData} ButtonComponentData
18
+ * @property {ButtonStyle} style The style of the button
19
+ * @property {?boolean} disabled Whether this button is disabled
20
+ * @property {string} label The label of this button
21
+ * @property {?APIMessageComponentEmoji} emoji The emoji on this button
22
+ * @property {?string} customId The custom id of the button
23
+ * @property {?string} url The URL of the button
24
+ */
25
+
26
+ /**
27
+ * @typedef {object} SelectMenuComponentOptionData
28
+ * @property {string} label The label of the option
29
+ * @property {string} value The value of the option
30
+ * @property {?string} description The description of the option
31
+ * @property {?APIMessageComponentEmoji} emoji The emoji on the option
32
+ * @property {?boolean} default Whether this option is selected by default
33
+ */
34
+
35
+ /**
36
+ * @typedef {BaseComponentData} SelectMenuComponentData
37
+ * @property {string} customId The custom id of the select menu
38
+ * @property {?boolean} disabled Whether the select menu is disabled or not
39
+ * @property {?number} maxValues The maximum amount of options that can be selected
40
+ * @property {?number} minValues The minimum amount of options that can be selected
41
+ * @property {?SelectMenuComponentOptionData[]} options The options in this select menu
42
+ * @property {?string} placeholder The placeholder of the select menu
43
+ */
44
+
45
+ /**
46
+ * @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} MessageComponentData
47
+ */
48
+
49
+ /**
50
+ * @typedef {BaseComponentData} TextInputComponentData
51
+ * @property {string} customId The custom id of the text input
52
+ * @property {TextInputStyle} style The style of the text input
53
+ * @property {string} label The text that appears on top of the text input field
54
+ * @property {?number} minLength The minimum number of characters that can be entered in the text input
55
+ * @property {?number} maxLength The maximum number of characters that can be entered in the text input
56
+ * @property {?boolean} required Whether or not the text input is required or not
57
+ * @property {?string} value The pre-filled text in the text input
58
+ * @property {?string} placeholder Placeholder for the text input
59
+ */
60
+
61
+ /**
62
+ * @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData|TextInputComponentData} ComponentData
63
+ */
64
+
65
+ /**
66
+ * Any emoji data that can be used within a button
67
+ * @typedef {APIMessageComponentEmoji|string} ComponentEmojiResolvable
68
+ */
69
+
5
70
  /**
6
71
  * Transforms API data into a component
7
72
  * @param {APIMessageComponent|Component} data The data to create the component from
@@ -35,14 +100,56 @@ function createComponent(data) {
35
100
  }
36
101
  }
37
102
 
103
+ /**
104
+ * Transforms API data into a component builder
105
+ * @param {APIMessageComponent|ComponentBuilder} data The data to create the component from
106
+ * @returns {ComponentBuilder}
107
+ * @ignore
108
+ */
109
+ function createComponentBuilder(data) {
110
+ if (data instanceof ComponentBuilder) {
111
+ return data;
112
+ }
113
+
114
+ switch (data.type) {
115
+ case ComponentType.ActionRow:
116
+ return new ActionRowBuilder(data);
117
+ case ComponentType.Button:
118
+ return new ButtonBuilder(data);
119
+ case ComponentType.StringSelect:
120
+ return new StringSelectMenuBuilder(data);
121
+ case ComponentType.TextInput:
122
+ return new TextInputBuilder(data);
123
+ case ComponentType.UserSelect:
124
+ return new UserSelectMenuBuilder(data);
125
+ case ComponentType.RoleSelect:
126
+ return new RoleSelectMenuBuilder(data);
127
+ case ComponentType.MentionableSelect:
128
+ return new MentionableSelectMenuBuilder(data);
129
+ case ComponentType.ChannelSelect:
130
+ return new ChannelSelectMenuBuilder(data);
131
+ default:
132
+ return new ComponentBuilder(data);
133
+ }
134
+ }
135
+
38
136
  exports.createComponent = createComponent;
137
+ exports.createComponentBuilder = createComponentBuilder;
39
138
 
40
139
  const { ActionRow } = require('../structures/ActionRow.js');
140
+ const { ActionRowBuilder } = require('../structures/ActionRowBuilder.js');
141
+ const { ButtonBuilder } = require('../structures/ButtonBuilder.js');
41
142
  const { ButtonComponent } = require('../structures/ButtonComponent.js');
143
+ const { ChannelSelectMenuBuilder } = require('../structures/ChannelSelectMenuBuilder.js');
42
144
  const { ChannelSelectMenuComponent } = require('../structures/ChannelSelectMenuComponent.js');
43
145
  const { Component } = require('../structures/Component.js');
146
+ const { MentionableSelectMenuBuilder } = require('../structures/MentionableSelectMenuBuilder.js');
44
147
  const { MentionableSelectMenuComponent } = require('../structures/MentionableSelectMenuComponent.js');
148
+ const { RoleSelectMenuBuilder } = require('../structures/RoleSelectMenuBuilder.js');
45
149
  const { RoleSelectMenuComponent } = require('../structures/RoleSelectMenuComponent.js');
150
+ const { StringSelectMenuBuilder } = require('../structures/StringSelectMenuBuilder.js');
46
151
  const { StringSelectMenuComponent } = require('../structures/StringSelectMenuComponent.js');
152
+ const { TextInputBuilder } = require('../structures/TextInputBuilder.js');
47
153
  const { TextInputComponent } = require('../structures/TextInputComponent.js');
154
+ const { UserSelectMenuBuilder } = require('../structures/UserSelectMenuBuilder.js');
48
155
  const { UserSelectMenuComponent } = require('../structures/UserSelectMenuComponent.js');
package/src/util/Util.js CHANGED
@@ -112,6 +112,7 @@ function parseEmoji(text) {
112
112
  * Resolves a partial emoji object from an {@link EmojiIdentifierResolvable}, without checking a Client.
113
113
  * @param {Emoji|EmojiIdentifierResolvable} emoji Emoji identifier to resolve
114
114
  * @returns {?(PartialEmoji|PartialEmojiOnlyId)} Supplying a snowflake yields `PartialEmojiOnlyId`.
115
+ * @private
115
116
  */
116
117
  function resolvePartialEmoji(emoji) {
117
118
  if (!emoji) return null;
@@ -1,3 +1,21 @@
1
+ import {
2
+ ActionRowBuilder as BuilderActionRow,
3
+ MessageActionRowComponentBuilder,
4
+ ButtonBuilder as BuilderButtonComponent,
5
+ EmbedBuilder as BuildersEmbed,
6
+ ChannelSelectMenuBuilder as BuilderChannelSelectMenuComponent,
7
+ MentionableSelectMenuBuilder as BuilderMentionableSelectMenuComponent,
8
+ RoleSelectMenuBuilder as BuilderRoleSelectMenuComponent,
9
+ StringSelectMenuBuilder as BuilderStringSelectMenuComponent,
10
+ UserSelectMenuBuilder as BuilderUserSelectMenuComponent,
11
+ TextInputBuilder as BuilderTextInputComponent,
12
+ SelectMenuOptionBuilder as BuildersSelectMenuOption,
13
+ ModalActionRowComponentBuilder,
14
+ ModalBuilder as BuildersModal,
15
+ AnyComponentBuilder,
16
+ type RestOrArray,
17
+ ApplicationCommandOptionAllowedChannelTypes,
18
+ } from '@discordjs/builders';
1
19
  import { Awaitable, JSONEncodable } from '@discordjs/util';
2
20
  import { Collection, ReadonlyCollection } from '@discordjs/collection';
3
21
  import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
@@ -219,7 +237,6 @@ import {
219
237
  RawWidgetData,
220
238
  RawWidgetMemberData,
221
239
  } from './rawDataTypes.mjs';
222
- import { ApplicationCommandOptionAllowedChannelTypes, MessageActionRowComponentBuilder } from '@discordjs/builders';
223
240
 
224
241
  //#region Classes
225
242
 
@@ -277,6 +294,22 @@ export interface ActionRowData<ComponentType extends JSONEncodable<APIActionRowC
277
294
  components: readonly ComponentType[];
278
295
  }
279
296
 
297
+ export class ActionRowBuilder<
298
+ ComponentType extends AnyComponentBuilder = AnyComponentBuilder,
299
+ > extends BuilderActionRow<ComponentType> {
300
+ public constructor(
301
+ data?: Partial<
302
+ | ActionRowData<ActionRowComponentData | JSONEncodable<APIActionRowComponentTypes>>
303
+ | APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>
304
+ >,
305
+ );
306
+ public static from<ComponentType extends AnyComponentBuilder = AnyComponentBuilder>(
307
+ other:
308
+ | JSONEncodable<APIActionRowComponent<ReturnType<ComponentType['toJSON']>>>
309
+ | APIActionRowComponent<ReturnType<ComponentType['toJSON']>>,
310
+ ): ActionRowBuilder<ComponentType>;
311
+ }
312
+
280
313
  export type MessageActionRowComponent =
281
314
  | ButtonComponent
282
315
  | StringSelectMenuComponent
@@ -718,6 +751,70 @@ export class ButtonComponent extends Component<APIButtonComponent> {
718
751
 
719
752
  export type ComponentEmojiResolvable = APIMessageComponentEmoji | string;
720
753
 
754
+ export class ButtonBuilder extends BuilderButtonComponent {
755
+ public constructor(data?: Partial<ButtonComponentData> | Partial<APIButtonComponent>);
756
+ public static from(other: JSONEncodable<APIButtonComponent> | APIButtonComponent): ButtonBuilder;
757
+ public override setEmoji(emoji: ComponentEmojiResolvable): this;
758
+ }
759
+
760
+ export class StringSelectMenuBuilder extends BuilderStringSelectMenuComponent {
761
+ public constructor(data?: Partial<StringSelectMenuComponentData | APIStringSelectComponent>);
762
+ private static normalizeEmoji(
763
+ selectMenuOption: JSONEncodable<APISelectMenuOption> | SelectMenuComponentOptionData,
764
+ ): (APISelectMenuOption | StringSelectMenuOptionBuilder)[];
765
+ public override addOptions(
766
+ ...options: RestOrArray<BuildersSelectMenuOption | SelectMenuComponentOptionData | APISelectMenuOption>
767
+ ): this;
768
+ public override setOptions(
769
+ ...options: RestOrArray<BuildersSelectMenuOption | SelectMenuComponentOptionData | APISelectMenuOption>
770
+ ): this;
771
+ public static from(
772
+ other: JSONEncodable<APIStringSelectComponent> | APIStringSelectComponent,
773
+ ): StringSelectMenuBuilder;
774
+ }
775
+
776
+ export class UserSelectMenuBuilder extends BuilderUserSelectMenuComponent {
777
+ public constructor(data?: Partial<UserSelectMenuComponentData | APIUserSelectComponent>);
778
+ public static from(other: JSONEncodable<APIUserSelectComponent> | APIUserSelectComponent): UserSelectMenuBuilder;
779
+ }
780
+
781
+ export class RoleSelectMenuBuilder extends BuilderRoleSelectMenuComponent {
782
+ public constructor(data?: Partial<RoleSelectMenuComponentData | APIRoleSelectComponent>);
783
+ public static from(other: JSONEncodable<APIRoleSelectComponent> | APIRoleSelectComponent): RoleSelectMenuBuilder;
784
+ }
785
+
786
+ export class MentionableSelectMenuBuilder extends BuilderMentionableSelectMenuComponent {
787
+ public constructor(data?: Partial<MentionableSelectMenuComponentData | APIMentionableSelectComponent>);
788
+ public static from(
789
+ other: JSONEncodable<APIMentionableSelectComponent> | APIMentionableSelectComponent,
790
+ ): MentionableSelectMenuBuilder;
791
+ }
792
+
793
+ export class ChannelSelectMenuBuilder extends BuilderChannelSelectMenuComponent {
794
+ public constructor(data?: Partial<ChannelSelectMenuComponentData | APIChannelSelectComponent>);
795
+ public static from(
796
+ other: JSONEncodable<APIChannelSelectComponent> | APIChannelSelectComponent,
797
+ ): ChannelSelectMenuBuilder;
798
+ }
799
+
800
+ export class StringSelectMenuOptionBuilder extends BuildersSelectMenuOption {
801
+ public constructor(data?: SelectMenuComponentOptionData | APISelectMenuOption);
802
+ public override setEmoji(emoji: ComponentEmojiResolvable): this;
803
+ public static from(other: JSONEncodable<APISelectMenuOption> | APISelectMenuOption): StringSelectMenuOptionBuilder;
804
+ }
805
+
806
+ export class ModalBuilder extends BuildersModal {
807
+ public constructor(data?: Partial<ModalComponentData> | Partial<APIModalInteractionResponseCallbackData>);
808
+ public static from(
809
+ other: JSONEncodable<APIModalInteractionResponseCallbackData> | APIModalInteractionResponseCallbackData,
810
+ ): ModalBuilder;
811
+ }
812
+
813
+ export class TextInputBuilder extends BuilderTextInputComponent {
814
+ public constructor(data?: Partial<TextInputComponentData | APITextInputComponent>);
815
+ public static from(other: JSONEncodable<APITextInputComponent> | APITextInputComponent): TextInputBuilder;
816
+ }
817
+
721
818
  export class TextInputComponent extends Component<APITextInputComponent> {
722
819
  public get customId(): string;
723
820
  public get value(): string;
@@ -775,6 +872,13 @@ export interface EmbedAssetData extends Omit<APIEmbedImage, 'proxy_url'> {
775
872
  proxyURL?: string;
776
873
  }
777
874
 
875
+ export class EmbedBuilder extends BuildersEmbed {
876
+ public constructor(data?: EmbedData | APIEmbed);
877
+ public override setColor(color: ColorResolvable | null): this;
878
+ public static from(other: JSONEncodable<APIEmbed> | APIEmbed): EmbedBuilder;
879
+ public get length(): number;
880
+ }
881
+
778
882
  export class Embed {
779
883
  private constructor(data: APIEmbed);
780
884
  public readonly data: Readonly<APIEmbed>;
@@ -3404,7 +3508,9 @@ export function moveElementInArray(
3404
3508
  ): number;
3405
3509
  export function parseEmoji(text: string): PartialEmoji | null;
3406
3510
  export function resolveColor(color: ColorResolvable): number;
3511
+ /** @internal */
3407
3512
  export function resolvePartialEmoji(emoji: Snowflake): PartialEmojiOnlyId;
3513
+ /** @internal */
3408
3514
  export function resolvePartialEmoji(emoji: Emoji | EmojiIdentifierResolvable): PartialEmoji | null;
3409
3515
  /** @internal */
3410
3516
  export function resolveGuildEmoji(client: Client, emojiId: Snowflake): GuildEmoji | null;
@@ -6160,6 +6266,16 @@ export interface MessageCollectorOptions extends CollectorOptions<[Message, Coll
6160
6266
  maxProcessed?: number;
6161
6267
  }
6162
6268
 
6269
+ export type MessageComponent =
6270
+ | Component
6271
+ | ActionRowBuilder<MessageActionRowComponentBuilder | ModalActionRowComponentBuilder>
6272
+ | ButtonComponent
6273
+ | StringSelectMenuComponent
6274
+ | UserSelectMenuComponent
6275
+ | RoleSelectMenuComponent
6276
+ | MentionableSelectMenuComponent
6277
+ | ChannelSelectMenuComponent;
6278
+
6163
6279
  export type CollectedMessageInteraction<Cached extends CacheType = CacheType> = Exclude<
6164
6280
  CollectedInteraction<Cached>,
6165
6281
  ModalSubmitInteraction
@@ -6230,7 +6346,7 @@ export interface BaseMessageOptions {
6230
6346
  | AttachmentPayload
6231
6347
  )[];
6232
6348
  components?: readonly (
6233
- | JSONEncodable<APIActionRowComponent<APIActionRowComponentTypes>>
6349
+ | JSONEncodable<APIActionRowComponent<APIMessageActionRowComponent>>
6234
6350
  | ActionRowData<MessageActionRowComponentData | MessageActionRowComponentBuilder>
6235
6351
  | APIActionRowComponent<APIMessageActionRowComponent>
6236
6352
  )[];
@@ -1,3 +1,21 @@
1
+ import {
2
+ ActionRowBuilder as BuilderActionRow,
3
+ MessageActionRowComponentBuilder,
4
+ ButtonBuilder as BuilderButtonComponent,
5
+ EmbedBuilder as BuildersEmbed,
6
+ ChannelSelectMenuBuilder as BuilderChannelSelectMenuComponent,
7
+ MentionableSelectMenuBuilder as BuilderMentionableSelectMenuComponent,
8
+ RoleSelectMenuBuilder as BuilderRoleSelectMenuComponent,
9
+ StringSelectMenuBuilder as BuilderStringSelectMenuComponent,
10
+ UserSelectMenuBuilder as BuilderUserSelectMenuComponent,
11
+ TextInputBuilder as BuilderTextInputComponent,
12
+ SelectMenuOptionBuilder as BuildersSelectMenuOption,
13
+ ModalActionRowComponentBuilder,
14
+ ModalBuilder as BuildersModal,
15
+ AnyComponentBuilder,
16
+ type RestOrArray,
17
+ ApplicationCommandOptionAllowedChannelTypes,
18
+ } from '@discordjs/builders';
1
19
  import { Awaitable, JSONEncodable } from '@discordjs/util';
2
20
  import { Collection, ReadonlyCollection } from '@discordjs/collection';
3
21
  import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
@@ -219,7 +237,6 @@ import {
219
237
  RawWidgetData,
220
238
  RawWidgetMemberData,
221
239
  } from './rawDataTypes.js';
222
- import { ApplicationCommandOptionAllowedChannelTypes, MessageActionRowComponentBuilder } from '@discordjs/builders';
223
240
 
224
241
  //#region Classes
225
242
 
@@ -277,6 +294,22 @@ export interface ActionRowData<ComponentType extends JSONEncodable<APIActionRowC
277
294
  components: readonly ComponentType[];
278
295
  }
279
296
 
297
+ export class ActionRowBuilder<
298
+ ComponentType extends AnyComponentBuilder = AnyComponentBuilder,
299
+ > extends BuilderActionRow<ComponentType> {
300
+ public constructor(
301
+ data?: Partial<
302
+ | ActionRowData<ActionRowComponentData | JSONEncodable<APIActionRowComponentTypes>>
303
+ | APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>
304
+ >,
305
+ );
306
+ public static from<ComponentType extends AnyComponentBuilder = AnyComponentBuilder>(
307
+ other:
308
+ | JSONEncodable<APIActionRowComponent<ReturnType<ComponentType['toJSON']>>>
309
+ | APIActionRowComponent<ReturnType<ComponentType['toJSON']>>,
310
+ ): ActionRowBuilder<ComponentType>;
311
+ }
312
+
280
313
  export type MessageActionRowComponent =
281
314
  | ButtonComponent
282
315
  | StringSelectMenuComponent
@@ -718,6 +751,70 @@ export class ButtonComponent extends Component<APIButtonComponent> {
718
751
 
719
752
  export type ComponentEmojiResolvable = APIMessageComponentEmoji | string;
720
753
 
754
+ export class ButtonBuilder extends BuilderButtonComponent {
755
+ public constructor(data?: Partial<ButtonComponentData> | Partial<APIButtonComponent>);
756
+ public static from(other: JSONEncodable<APIButtonComponent> | APIButtonComponent): ButtonBuilder;
757
+ public override setEmoji(emoji: ComponentEmojiResolvable): this;
758
+ }
759
+
760
+ export class StringSelectMenuBuilder extends BuilderStringSelectMenuComponent {
761
+ public constructor(data?: Partial<StringSelectMenuComponentData | APIStringSelectComponent>);
762
+ private static normalizeEmoji(
763
+ selectMenuOption: JSONEncodable<APISelectMenuOption> | SelectMenuComponentOptionData,
764
+ ): (APISelectMenuOption | StringSelectMenuOptionBuilder)[];
765
+ public override addOptions(
766
+ ...options: RestOrArray<BuildersSelectMenuOption | SelectMenuComponentOptionData | APISelectMenuOption>
767
+ ): this;
768
+ public override setOptions(
769
+ ...options: RestOrArray<BuildersSelectMenuOption | SelectMenuComponentOptionData | APISelectMenuOption>
770
+ ): this;
771
+ public static from(
772
+ other: JSONEncodable<APIStringSelectComponent> | APIStringSelectComponent,
773
+ ): StringSelectMenuBuilder;
774
+ }
775
+
776
+ export class UserSelectMenuBuilder extends BuilderUserSelectMenuComponent {
777
+ public constructor(data?: Partial<UserSelectMenuComponentData | APIUserSelectComponent>);
778
+ public static from(other: JSONEncodable<APIUserSelectComponent> | APIUserSelectComponent): UserSelectMenuBuilder;
779
+ }
780
+
781
+ export class RoleSelectMenuBuilder extends BuilderRoleSelectMenuComponent {
782
+ public constructor(data?: Partial<RoleSelectMenuComponentData | APIRoleSelectComponent>);
783
+ public static from(other: JSONEncodable<APIRoleSelectComponent> | APIRoleSelectComponent): RoleSelectMenuBuilder;
784
+ }
785
+
786
+ export class MentionableSelectMenuBuilder extends BuilderMentionableSelectMenuComponent {
787
+ public constructor(data?: Partial<MentionableSelectMenuComponentData | APIMentionableSelectComponent>);
788
+ public static from(
789
+ other: JSONEncodable<APIMentionableSelectComponent> | APIMentionableSelectComponent,
790
+ ): MentionableSelectMenuBuilder;
791
+ }
792
+
793
+ export class ChannelSelectMenuBuilder extends BuilderChannelSelectMenuComponent {
794
+ public constructor(data?: Partial<ChannelSelectMenuComponentData | APIChannelSelectComponent>);
795
+ public static from(
796
+ other: JSONEncodable<APIChannelSelectComponent> | APIChannelSelectComponent,
797
+ ): ChannelSelectMenuBuilder;
798
+ }
799
+
800
+ export class StringSelectMenuOptionBuilder extends BuildersSelectMenuOption {
801
+ public constructor(data?: SelectMenuComponentOptionData | APISelectMenuOption);
802
+ public override setEmoji(emoji: ComponentEmojiResolvable): this;
803
+ public static from(other: JSONEncodable<APISelectMenuOption> | APISelectMenuOption): StringSelectMenuOptionBuilder;
804
+ }
805
+
806
+ export class ModalBuilder extends BuildersModal {
807
+ public constructor(data?: Partial<ModalComponentData> | Partial<APIModalInteractionResponseCallbackData>);
808
+ public static from(
809
+ other: JSONEncodable<APIModalInteractionResponseCallbackData> | APIModalInteractionResponseCallbackData,
810
+ ): ModalBuilder;
811
+ }
812
+
813
+ export class TextInputBuilder extends BuilderTextInputComponent {
814
+ public constructor(data?: Partial<TextInputComponentData | APITextInputComponent>);
815
+ public static from(other: JSONEncodable<APITextInputComponent> | APITextInputComponent): TextInputBuilder;
816
+ }
817
+
721
818
  export class TextInputComponent extends Component<APITextInputComponent> {
722
819
  public get customId(): string;
723
820
  public get value(): string;
@@ -775,6 +872,13 @@ export interface EmbedAssetData extends Omit<APIEmbedImage, 'proxy_url'> {
775
872
  proxyURL?: string;
776
873
  }
777
874
 
875
+ export class EmbedBuilder extends BuildersEmbed {
876
+ public constructor(data?: EmbedData | APIEmbed);
877
+ public override setColor(color: ColorResolvable | null): this;
878
+ public static from(other: JSONEncodable<APIEmbed> | APIEmbed): EmbedBuilder;
879
+ public get length(): number;
880
+ }
881
+
778
882
  export class Embed {
779
883
  private constructor(data: APIEmbed);
780
884
  public readonly data: Readonly<APIEmbed>;
@@ -3404,7 +3508,9 @@ export function moveElementInArray(
3404
3508
  ): number;
3405
3509
  export function parseEmoji(text: string): PartialEmoji | null;
3406
3510
  export function resolveColor(color: ColorResolvable): number;
3511
+ /** @internal */
3407
3512
  export function resolvePartialEmoji(emoji: Snowflake): PartialEmojiOnlyId;
3513
+ /** @internal */
3408
3514
  export function resolvePartialEmoji(emoji: Emoji | EmojiIdentifierResolvable): PartialEmoji | null;
3409
3515
  /** @internal */
3410
3516
  export function resolveGuildEmoji(client: Client, emojiId: Snowflake): GuildEmoji | null;
@@ -6160,6 +6266,16 @@ export interface MessageCollectorOptions extends CollectorOptions<[Message, Coll
6160
6266
  maxProcessed?: number;
6161
6267
  }
6162
6268
 
6269
+ export type MessageComponent =
6270
+ | Component
6271
+ | ActionRowBuilder<MessageActionRowComponentBuilder | ModalActionRowComponentBuilder>
6272
+ | ButtonComponent
6273
+ | StringSelectMenuComponent
6274
+ | UserSelectMenuComponent
6275
+ | RoleSelectMenuComponent
6276
+ | MentionableSelectMenuComponent
6277
+ | ChannelSelectMenuComponent;
6278
+
6163
6279
  export type CollectedMessageInteraction<Cached extends CacheType = CacheType> = Exclude<
6164
6280
  CollectedInteraction<Cached>,
6165
6281
  ModalSubmitInteraction
@@ -6230,7 +6346,7 @@ export interface BaseMessageOptions {
6230
6346
  | AttachmentPayload
6231
6347
  )[];
6232
6348
  components?: readonly (
6233
- | JSONEncodable<APIActionRowComponent<APIActionRowComponentTypes>>
6349
+ | JSONEncodable<APIActionRowComponent<APIMessageActionRowComponent>>
6234
6350
  | ActionRowData<MessageActionRowComponentData | MessageActionRowComponentBuilder>
6235
6351
  | APIActionRowComponent<APIMessageActionRowComponent>
6236
6352
  )[];
@@ -20,15 +20,22 @@ import {
20
20
  AuditLogEvent,
21
21
  ButtonStyle,
22
22
  TextInputStyle,
23
+ APITextInputComponent,
23
24
  APIEmbed,
24
25
  ApplicationCommandType,
25
26
  APIMessage,
27
+ APIActionRowComponent,
28
+ APIActionRowComponentTypes,
26
29
  APIStringSelectComponent,
30
+ APIUserSelectComponent,
31
+ APIRoleSelectComponent,
32
+ APIChannelSelectComponent,
33
+ APIMentionableSelectComponent,
34
+ APIModalInteractionResponseCallbackData,
27
35
  WebhookType,
28
36
  GuildScheduledEventRecurrenceRuleFrequency,
29
37
  GuildScheduledEventRecurrenceRuleMonth,
30
38
  GuildScheduledEventRecurrenceRuleWeekday,
31
- APIButtonComponentWithCustomId,
32
39
  } from 'discord-api-types/v10';
33
40
  import {
34
41
  ApplicationCommand,
@@ -119,6 +126,7 @@ import {
119
126
  TextInputBuilder,
120
127
  TextInputComponent,
121
128
  Embed,
129
+ MessageActionRowComponentBuilder,
122
130
  GuildBanManager,
123
131
  GuildBan,
124
132
  MessageManager,
@@ -210,12 +218,9 @@ import {
210
218
  PartialPollAnswer,
211
219
  PollAnswer,
212
220
  PollAnswerVoterManager,
213
- PrimaryButtonBuilder,
214
- resolveColor,
215
- createComponentBuilder,
216
221
  } from './index.js';
217
222
  import { expectAssignable, expectNotAssignable, expectNotType, expectType } from 'tsd';
218
- import type { ContextMenuCommandBuilder, ChatInputCommandBuilder } from '@discordjs/builders';
223
+ import type { ContextMenuCommandBuilder, SlashCommandBuilder } from '@discordjs/builders';
219
224
  import { ReadonlyCollection } from '@discordjs/collection';
220
225
 
221
226
  // Test type transformation:
@@ -342,9 +347,13 @@ client.on('interactionCreate', async interaction => {
342
347
 
343
348
  if (interaction.type !== InteractionType.ApplicationCommand) return;
344
349
 
345
- const actionRow = new ActionRowBuilder({
350
+ void new ActionRowBuilder<MessageActionRowComponentBuilder>();
351
+
352
+ const button = new ButtonBuilder();
353
+
354
+ const actionRow = new ActionRowBuilder<MessageActionRowComponentBuilder>({
346
355
  type: ComponentType.ActionRow,
347
- components: [{ custom_id: '123', label: 'test', style: ButtonStyle.Primary, type: ComponentType.Button }],
356
+ components: [button.toJSON()],
348
357
  });
349
358
 
350
359
  actionRow.toJSON();
@@ -613,7 +622,7 @@ client.on('messageCreate', async message => {
613
622
  });
614
623
 
615
624
  // Check that both builders and builder data can be sent in messages
616
- const row = new ActionRowBuilder();
625
+ const row = new ActionRowBuilder<MessageActionRowComponentBuilder>();
617
626
 
618
627
  const rawButtonsRow: ActionRowData<ButtonComponentData> = {
619
628
  type: ComponentType.ActionRow,
@@ -630,7 +639,7 @@ client.on('messageCreate', async message => {
630
639
 
631
640
  const buttonsRow: ActionRowData<ButtonBuilder> = {
632
641
  type: ComponentType.ActionRow,
633
- components: [new PrimaryButtonBuilder()],
642
+ components: [new ButtonBuilder()],
634
643
  };
635
644
 
636
645
  const rawStringSelectMenuRow: ActionRowData<StringSelectMenuComponentData> = {
@@ -745,7 +754,7 @@ client.on('presenceUpdate', (oldPresence, { client }) => {
745
754
  expectType<Client<true>>(client);
746
755
  });
747
756
 
748
- declare const slashCommandBuilder: ChatInputCommandBuilder;
757
+ declare const slashCommandBuilder: SlashCommandBuilder;
749
758
  declare const contextMenuCommandBuilder: ContextMenuCommandBuilder;
750
759
 
751
760
  client.on('clientReady', async client => {
@@ -1317,7 +1326,7 @@ client.on('guildCreate', async g => {
1317
1326
  const row: ActionRowData<MessageActionRowComponentData> = {
1318
1327
  type: ComponentType.ActionRow,
1319
1328
  components: [
1320
- new PrimaryButtonBuilder(),
1329
+ new ButtonBuilder(),
1321
1330
  { type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
1322
1331
  { type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
1323
1332
  { type: ComponentType.StringSelect, customId: 'foo', options: [{ label: 'label', value: 'value' }] },
@@ -1329,12 +1338,12 @@ client.on('guildCreate', async g => {
1329
1338
  ],
1330
1339
  };
1331
1340
 
1332
- const row2 = new ActionRowBuilder({
1341
+ const row2 = new ActionRowBuilder<MessageActionRowComponentBuilder>({
1333
1342
  type: ComponentType.ActionRow,
1334
1343
  components: [
1335
- { type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', custom_id: 'foo' },
1344
+ { type: ComponentType.Button, style: ButtonStyle.Primary, label: 'string', customId: 'foo' },
1336
1345
  { type: ComponentType.Button, style: ButtonStyle.Link, label: 'test', url: 'test' },
1337
- { type: ComponentType.StringSelect, custom_id: 'foo', options: [{ label: 'label', value: 'value' }] },
1346
+ { type: ComponentType.StringSelect, customId: 'foo', options: [{ label: 'label', value: 'value' }] },
1338
1347
  ],
1339
1348
  });
1340
1349
 
@@ -2361,7 +2370,43 @@ expectType<
2361
2370
  >(NonThreadGuildBasedChannel);
2362
2371
  expectType<GuildTextBasedChannel>(GuildTextBasedChannel);
2363
2372
 
2364
- new EmbedBuilder().setColor(resolveColor('#ffffff'));
2373
+ const button = new ButtonBuilder({
2374
+ label: 'test',
2375
+ style: ButtonStyle.Primary,
2376
+ customId: 'test',
2377
+ });
2378
+
2379
+ const selectMenu = new StringSelectMenuBuilder({
2380
+ maxValues: 10,
2381
+ minValues: 2,
2382
+ customId: 'test',
2383
+ });
2384
+
2385
+ new ActionRowBuilder({
2386
+ components: [selectMenu.toJSON(), button.toJSON()],
2387
+ });
2388
+
2389
+ new StringSelectMenuBuilder({
2390
+ customId: 'foo',
2391
+ });
2392
+
2393
+ new ButtonBuilder({
2394
+ style: ButtonStyle.Danger,
2395
+ })
2396
+ .setEmoji('<a:foo:123>')
2397
+ .setEmoji('<:foo:123>')
2398
+ .setEmoji('foobar:123')
2399
+ .setEmoji('😏')
2400
+ .setEmoji({
2401
+ name: 'test',
2402
+ id: '123',
2403
+ animated: false,
2404
+ });
2405
+
2406
+ // @ts-expect-error
2407
+ new EmbedBuilder().setColor('abc');
2408
+
2409
+ new EmbedBuilder().setColor('#ffffff');
2365
2410
 
2366
2411
  expectNotAssignable<ActionRowData<MessageActionRowComponentData>>({
2367
2412
  type: ComponentType.ActionRow,
@@ -2399,38 +2444,74 @@ chatInputInteraction.showModal({
2399
2444
  ],
2400
2445
  });
2401
2446
 
2447
+ declare const stringSelectMenuData: APIStringSelectComponent;
2448
+ StringSelectMenuBuilder.from(stringSelectMenuData);
2449
+
2450
+ declare const userSelectMenuData: APIUserSelectComponent;
2451
+ UserSelectMenuBuilder.from(userSelectMenuData);
2452
+
2453
+ declare const roleSelectMenuData: APIRoleSelectComponent;
2454
+ RoleSelectMenuBuilder.from(roleSelectMenuData);
2455
+
2456
+ declare const channelSelectMenuData: APIChannelSelectComponent;
2457
+ ChannelSelectMenuBuilder.from(channelSelectMenuData);
2458
+
2459
+ declare const mentionableSelectMenuData: APIMentionableSelectComponent;
2460
+ MentionableSelectMenuBuilder.from(mentionableSelectMenuData);
2461
+
2402
2462
  declare const stringSelectMenuComp: StringSelectMenuComponent;
2403
- new StringSelectMenuBuilder(stringSelectMenuComp.toJSON());
2463
+ StringSelectMenuBuilder.from(stringSelectMenuComp);
2404
2464
 
2405
2465
  declare const userSelectMenuComp: UserSelectMenuComponent;
2406
- new UserSelectMenuBuilder(userSelectMenuComp.toJSON());
2466
+ UserSelectMenuBuilder.from(userSelectMenuComp);
2407
2467
 
2408
2468
  declare const roleSelectMenuComp: RoleSelectMenuComponent;
2409
- new RoleSelectMenuBuilder(roleSelectMenuComp.toJSON());
2469
+ RoleSelectMenuBuilder.from(roleSelectMenuComp);
2410
2470
 
2411
2471
  declare const channelSelectMenuComp: ChannelSelectMenuComponent;
2412
- new ChannelSelectMenuBuilder(channelSelectMenuComp.toJSON());
2472
+ ChannelSelectMenuBuilder.from(channelSelectMenuComp);
2413
2473
 
2414
2474
  declare const mentionableSelectMenuComp: MentionableSelectMenuComponent;
2415
- new MentionableSelectMenuBuilder(mentionableSelectMenuComp.toJSON());
2475
+ MentionableSelectMenuBuilder.from(mentionableSelectMenuComp);
2416
2476
 
2417
- declare const buttonData: APIButtonComponentWithCustomId;
2418
- new PrimaryButtonBuilder(buttonData);
2477
+ declare const buttonData: APIButtonComponent;
2478
+ ButtonBuilder.from(buttonData);
2419
2479
 
2420
2480
  declare const buttonComp: ButtonComponent;
2421
- createComponentBuilder(buttonComp.toJSON());
2481
+ ButtonBuilder.from(buttonComp);
2482
+
2483
+ declare const modalData: APIModalInteractionResponseCallbackData;
2484
+ ModalBuilder.from(modalData);
2485
+
2486
+ declare const textInputData: APITextInputComponent;
2487
+ TextInputBuilder.from(textInputData);
2422
2488
 
2423
2489
  declare const textInputComp: TextInputComponent;
2424
- new TextInputBuilder(textInputComp);
2490
+ TextInputBuilder.from(textInputComp);
2425
2491
 
2426
2492
  declare const embedData: APIEmbed;
2427
- new EmbedBuilder(embedData);
2493
+ EmbedBuilder.from(embedData);
2428
2494
 
2429
2495
  declare const embedComp: Embed;
2430
- new EmbedBuilder(embedComp.toJSON());
2496
+ EmbedBuilder.from(embedComp);
2497
+
2498
+ declare const actionRowData: APIActionRowComponent<APIActionRowComponentTypes>;
2499
+ ActionRowBuilder.from(actionRowData);
2431
2500
 
2432
2501
  declare const actionRowComp: ActionRow<ActionRowComponent>;
2433
- new ActionRowBuilder(actionRowComp.toJSON());
2502
+ ActionRowBuilder.from(actionRowComp);
2503
+
2504
+ declare const buttonsActionRowData: APIActionRowComponent<APIButtonComponent>;
2505
+ declare const buttonsActionRowComp: ActionRow<ButtonComponent>;
2506
+
2507
+ expectType<ActionRowBuilder<ButtonBuilder>>(ActionRowBuilder.from<ButtonBuilder>(buttonsActionRowData));
2508
+ expectType<ActionRowBuilder<ButtonBuilder>>(ActionRowBuilder.from<ButtonBuilder>(buttonsActionRowComp));
2509
+
2510
+ declare const anyComponentsActionRowData: APIActionRowComponent<APIActionRowComponentTypes>;
2511
+ declare const anyComponentsActionRowComp: ActionRow<ActionRowComponent>;
2512
+
2513
+ expectType<ActionRowBuilder>(ActionRowBuilder.from(anyComponentsActionRowData));
2514
+ expectType<ActionRowBuilder>(ActionRowBuilder.from(anyComponentsActionRowComp));
2434
2515
 
2435
2516
  type UserMentionChannels = DMChannel | PartialDMChannel;
2436
2517
  declare const channelMentionChannels: Exclude<Channel | DirectoryChannel, UserMentionChannels>;