mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-18 20:43:30 +01:00
refactor: Don't return builders from API data (#7584)
* refactor: don't return builders from API data * Update packages/discord.js/src/structures/ActionRow.js Co-authored-by: Antonio Román <kyradiscord@gmail.com> * fix: circular dependency * fix: circular dependency pt.2 * chore: make requested changes * chore: bump dapi-types * chore: convert text input * chore: convert text input * feat: handle cases of unknown component types better * refactor: refactor modal to builder * feat: add #from for easy builder conversions * refactor: make requested changes * chore: make requested changes * style: fix linting error Co-authored-by: Antonio Román <kyradiscord@gmail.com> Co-authored-by: almeidx <almeidx@pm.me>
This commit is contained in:
@@ -53,6 +53,7 @@
|
||||
"@sapphire/snowflake": "^3.1.0",
|
||||
"@types/ws": "^8.2.2",
|
||||
"discord-api-types": "^0.27.3",
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"lodash.snakecase": "^4.1.1",
|
||||
"undici": "^4.14.1",
|
||||
"ws": "^8.5.0"
|
||||
|
||||
@@ -71,6 +71,7 @@ exports.WebSocketShard = require('./client/websocket/WebSocketShard');
|
||||
|
||||
// Structures
|
||||
exports.ActionRow = require('./structures/ActionRow');
|
||||
exports.ActionRowBuilder = require('./structures/ActionRowBuilder');
|
||||
exports.Activity = require('./structures/Presence').Activity;
|
||||
exports.AnonymousGuild = require('./structures/AnonymousGuild');
|
||||
exports.Application = require('./structures/interfaces/Application');
|
||||
@@ -81,6 +82,7 @@ exports.BaseGuild = require('./structures/BaseGuild');
|
||||
exports.BaseGuildEmoji = require('./structures/BaseGuildEmoji');
|
||||
exports.BaseGuildTextChannel = require('./structures/BaseGuildTextChannel');
|
||||
exports.BaseGuildVoiceChannel = require('./structures/BaseGuildVoiceChannel');
|
||||
exports.ButtonBuilder = require('./structures/ButtonBuilder');
|
||||
exports.ButtonComponent = require('./structures/ButtonComponent');
|
||||
exports.ButtonInteraction = require('./structures/ButtonInteraction');
|
||||
exports.CategoryChannel = require('./structures/CategoryChannel');
|
||||
@@ -92,9 +94,11 @@ exports.ClientUser = require('./structures/ClientUser');
|
||||
exports.CommandInteraction = require('./structures/CommandInteraction');
|
||||
exports.Collector = require('./structures/interfaces/Collector');
|
||||
exports.CommandInteractionOptionResolver = require('./structures/CommandInteractionOptionResolver');
|
||||
exports.Component = require('./structures/Component');
|
||||
exports.ContextMenuCommandInteraction = require('./structures/ContextMenuCommandInteraction');
|
||||
exports.DMChannel = require('./structures/DMChannel');
|
||||
exports.Embed = require('./structures/Embed');
|
||||
exports.EmbedBuilder = require('./structures/EmbedBuilder');
|
||||
exports.UnsafeEmbed = require('@discordjs/builders').UnsafeEmbed;
|
||||
exports.Emoji = require('./structures/Emoji').Emoji;
|
||||
exports.Guild = require('./structures/Guild').Guild;
|
||||
@@ -136,6 +140,7 @@ exports.ReactionCollector = require('./structures/ReactionCollector');
|
||||
exports.ReactionEmoji = require('./structures/ReactionEmoji');
|
||||
exports.RichPresenceAssets = require('./structures/Presence').RichPresenceAssets;
|
||||
exports.Role = require('./structures/Role').Role;
|
||||
exports.SelectMenuBuilder = require('./structures/SelectMenuBuilder');
|
||||
exports.SelectMenuComponent = require('./structures/SelectMenuComponent');
|
||||
exports.SelectMenuInteraction = require('./structures/SelectMenuInteraction');
|
||||
exports.StageChannel = require('./structures/StageChannel');
|
||||
@@ -146,6 +151,7 @@ exports.StoreChannel = require('./structures/StoreChannel');
|
||||
exports.Team = require('./structures/Team');
|
||||
exports.TeamMember = require('./structures/TeamMember');
|
||||
exports.TextChannel = require('./structures/TextChannel');
|
||||
exports.TextInputBuilder = require('./structures/TextInputBuilder');
|
||||
exports.TextInputComponent = require('./structures/TextInputComponent');
|
||||
exports.ThreadChannel = require('./structures/ThreadChannel');
|
||||
exports.ThreadMember = require('./structures/ThreadMember');
|
||||
@@ -191,6 +197,7 @@ exports.InviteTargetType = require('discord-api-types/v9').InviteTargetType;
|
||||
exports.Locale = require('discord-api-types/v9').Locale;
|
||||
exports.MessageType = require('discord-api-types/v9').MessageType;
|
||||
exports.MessageFlags = require('discord-api-types/v9').MessageFlags;
|
||||
exports.ModalBuilder = require('@discordjs/builders').ModalBuilder;
|
||||
exports.OAuth2Scopes = require('discord-api-types/v9').OAuth2Scopes;
|
||||
exports.PermissionFlagsBits = require('discord-api-types/v9').PermissionFlagsBits;
|
||||
exports.RESTJSONErrorCodes = require('discord-api-types/v9').RESTJSONErrorCodes;
|
||||
@@ -200,10 +207,10 @@ exports.StickerFormatType = require('discord-api-types/v9').StickerFormatType;
|
||||
exports.TextInputStyle = require('discord-api-types/v9').TextInputStyle;
|
||||
exports.UserFlags = require('discord-api-types/v9').UserFlags;
|
||||
exports.WebhookType = require('discord-api-types/v9').WebhookType;
|
||||
exports.UnsafeButtonComponent = require('@discordjs/builders').UnsafeButtonComponent;
|
||||
exports.UnsafeSelectMenuComponent = require('@discordjs/builders').UnsafeSelectMenuComponent;
|
||||
exports.SelectMenuOption = require('@discordjs/builders').SelectMenuOption;
|
||||
exports.UnsafeSelectMenuOption = require('@discordjs/builders').UnsafeSelectMenuOption;
|
||||
exports.UnsafeButtonBuilder = require('@discordjs/builders').UnsafeButtonBuilder;
|
||||
exports.UnsafeSelectMenuBuilder = require('@discordjs/builders').UnsafeSelectMenuBuilder;
|
||||
exports.SelectMenuOptionBuilder = require('@discordjs/builders').SelectMenuOptionBuilder;
|
||||
exports.UnsafeSelectMenuOptionBuilder = require('@discordjs/builders').UnsafeSelectMenuOptionBuilder;
|
||||
exports.DiscordAPIError = require('@discordjs/rest').DiscordAPIError;
|
||||
exports.HTTPError = require('@discordjs/rest').HTTPError;
|
||||
exports.RateLimitError = require('@discordjs/rest').RateLimitError;
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
'use strict';
|
||||
|
||||
const { ActionRow: BuildersActionRow, Component } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
const Component = require('./Component');
|
||||
const Components = require('../util/Components');
|
||||
|
||||
class ActionRow extends BuildersActionRow {
|
||||
constructor({ components, ...data } = {}) {
|
||||
super({
|
||||
components: components?.map(c => (c instanceof Component ? c : Transformers.toSnakeCase(c))),
|
||||
...Transformers.toSnakeCase(data),
|
||||
});
|
||||
/**
|
||||
* Represents an action row
|
||||
* @extends {Component}
|
||||
*/
|
||||
class ActionRow extends Component {
|
||||
constructor({ components, ...data }) {
|
||||
super(data);
|
||||
/**
|
||||
* The components in this action row
|
||||
* @type {Component[]}
|
||||
* @readonly
|
||||
*/
|
||||
this.components = components.map(c => Components.createComponent(c));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
15
packages/discord.js/src/structures/ActionRowBuilder.js
Normal file
15
packages/discord.js/src/structures/ActionRowBuilder.js
Normal file
@@ -0,0 +1,15 @@
|
||||
'use strict';
|
||||
|
||||
const { ActionRowBuilder: BuildersActionRow, ComponentBuilder } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
|
||||
class ActionRowBuilder extends BuildersActionRow {
|
||||
constructor({ components, ...data } = {}) {
|
||||
super({
|
||||
components: components?.map(c => (c instanceof ComponentBuilder ? c : Transformers.toSnakeCase(c))),
|
||||
...Transformers.toSnakeCase(data),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ActionRowBuilder;
|
||||
24
packages/discord.js/src/structures/ButtonBuilder.js
Normal file
24
packages/discord.js/src/structures/ButtonBuilder.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const { ButtonBuilder: BuildersButtonComponent, isJSONEncodable } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
|
||||
class ButtonBuilder extends BuildersButtonComponent {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new button builder from json data
|
||||
* @param {JSONEncodable<APIButtonComponent> | APIButtonComponent} other The other data
|
||||
* @returns {ButtonBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = ButtonBuilder;
|
||||
@@ -1,11 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
const { ButtonComponent: BuildersButtonComponent } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
const Component = require('./Component');
|
||||
|
||||
class ButtonComponent extends BuildersButtonComponent {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
/**
|
||||
* Represents a button component
|
||||
* @extends {Component}
|
||||
*/
|
||||
class ButtonComponent extends Component {
|
||||
/**
|
||||
* The style of this button
|
||||
* @type {ButtonStyle}
|
||||
* @readonly
|
||||
*/
|
||||
get style() {
|
||||
return this.data.style;
|
||||
}
|
||||
|
||||
/**
|
||||
* The label of this button
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get label() {
|
||||
return this.data.label ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The emoji used in this button
|
||||
* @type {?APIMessageComponentEmoji}
|
||||
* @readonly
|
||||
*/
|
||||
get emoji() {
|
||||
return this.data.emoji ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this button is disabled
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get disabled() {
|
||||
return this.data.disabled ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id of this button (only defined on non-link buttons)
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get customId() {
|
||||
return this.data.custom_id ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The URL of this button (only defined on link buttons)
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get url() {
|
||||
return this.data.url ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
52
packages/discord.js/src/structures/Component.js
Normal file
52
packages/discord.js/src/structures/Component.js
Normal file
@@ -0,0 +1,52 @@
|
||||
'use strict';
|
||||
|
||||
const isEqual = require('fast-deep-equal');
|
||||
|
||||
/**
|
||||
* Represents a component
|
||||
*/
|
||||
class Component {
|
||||
/**
|
||||
* Creates a new component from API data
|
||||
* @param {APIMessageComponent} data The API component data
|
||||
* @private
|
||||
*/
|
||||
constructor(data) {
|
||||
/**
|
||||
* The API data associated with this component
|
||||
* @type {APIMessageComponent}
|
||||
*/
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of the component
|
||||
* @type {ComponentType}
|
||||
* @readonly
|
||||
*/
|
||||
get type() {
|
||||
return this.data.type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the given components are equal
|
||||
* @param {Component|APIMessageComponent} other The component to compare against
|
||||
* @returns {boolean}
|
||||
*/
|
||||
equals(other) {
|
||||
if (other instanceof Component) {
|
||||
return isEqual(other.data, this.data);
|
||||
}
|
||||
return isEqual(other, this.data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the API-compatible JSON for this component
|
||||
* @returns {APIMessageComponent}
|
||||
*/
|
||||
toJSON() {
|
||||
return { ...this.data };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Component;
|
||||
@@ -1,15 +1,198 @@
|
||||
'use strict';
|
||||
|
||||
const { Embed: BuildersEmbed } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
const Util = require('../util/Util');
|
||||
const isEqual = require('fast-deep-equal');
|
||||
const { Util } = require('../util/Util');
|
||||
|
||||
/**
|
||||
* Represents an embed object
|
||||
*/
|
||||
class Embed extends BuildersEmbed {
|
||||
class Embed {
|
||||
/**
|
||||
* Creates a new embed object
|
||||
* @param {APIEmbed} data API embed data
|
||||
* @private
|
||||
*/
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
/**
|
||||
* The API embed data
|
||||
* @type {APIEmbed}
|
||||
* @readonly
|
||||
*/
|
||||
this.data = { ...data };
|
||||
}
|
||||
|
||||
/**
|
||||
* An array of fields of this embed
|
||||
* @type {?Array<APIEmbedField>}
|
||||
* @readonly
|
||||
*/
|
||||
get fields() {
|
||||
return this.data.fields ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed title
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get title() {
|
||||
return this.data.title ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed description
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get description() {
|
||||
return this.data.description ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed URL
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get url() {
|
||||
return this.data.url ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed color
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get color() {
|
||||
return this.data.color ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The timestamp of the embed in an ISO 8601 format
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get timestamp() {
|
||||
return this.data.timestamp ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed thumbnail data
|
||||
* @type {?EmbedImageData}
|
||||
* @readonly
|
||||
*/
|
||||
get thumbnail() {
|
||||
if (!this.data.thumbnail) return null;
|
||||
return {
|
||||
url: this.data.thumbnail.url,
|
||||
proxyURL: this.data.thumbnail.proxy_url,
|
||||
height: this.data.thumbnail.height,
|
||||
width: this.data.thumbnail.width,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed image data
|
||||
* @type {?EmbedImageData}
|
||||
* @readonly
|
||||
*/
|
||||
get image() {
|
||||
if (!this.data.image) return null;
|
||||
return {
|
||||
url: this.data.image.url,
|
||||
proxyURL: this.data.image.proxy_url,
|
||||
height: this.data.image.height,
|
||||
width: this.data.image.width,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Received video data
|
||||
* @type {?EmbedVideoData}
|
||||
* @readonly
|
||||
*/
|
||||
get video() {
|
||||
return this.data.video ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed author data
|
||||
* @type {?EmbedAuthorData}
|
||||
* @readonly
|
||||
*/
|
||||
get author() {
|
||||
if (!this.data.author) return null;
|
||||
return {
|
||||
name: this.data.author.name,
|
||||
url: this.data.author.url,
|
||||
iconURL: this.data.author.icon_url,
|
||||
proxyIconURL: this.data.author.proxy_icon_url,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Received data about the embed provider
|
||||
* @type {?EmbedProvider}
|
||||
* @readonly
|
||||
*/
|
||||
get provider() {
|
||||
return this.data.provider ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The embed footer data
|
||||
* @type {?EmbedFooterData}
|
||||
* @readonly
|
||||
*/
|
||||
get footer() {
|
||||
if (!this.data.footer) return null;
|
||||
return {
|
||||
text: this.data.footer.text,
|
||||
iconURL: this.data.footer.icon_url,
|
||||
proxyIconURL: this.data.footer.proxy_icon_url,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* The accumulated length for the embed title, description, fields, footer text, and author name
|
||||
* @type {number}
|
||||
* @readonly
|
||||
*/
|
||||
get length() {
|
||||
return (
|
||||
(this.data.title?.length ?? 0) +
|
||||
(this.data.description?.length ?? 0) +
|
||||
(this.data.fields?.reduce((prev, curr) => prev + curr.name.length + curr.value.length, 0) ?? 0) +
|
||||
(this.data.footer?.text.length ?? 0) +
|
||||
(this.data.author?.name.length ?? 0)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The hex color of the current color of the embed
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get hexColor() {
|
||||
return typeof this.data.color === 'number'
|
||||
? `#${this.data.color.toString(16).padStart(6, '0')}`
|
||||
: this.data.color ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the API-compatible JSON for this embed
|
||||
* @returns {APIEmbed}
|
||||
*/
|
||||
toJSON() {
|
||||
return { ...this.data };
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the given embeds are equal
|
||||
* @param {Embed|APIEmbed} other The embed to compare against
|
||||
* @returns {boolean}
|
||||
*/
|
||||
equals(other) {
|
||||
if (other instanceof Embed) {
|
||||
return isEqual(other.data, this.data);
|
||||
}
|
||||
return isEqual(other, this.data);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
24
packages/discord.js/src/structures/EmbedBuilder.js
Normal file
24
packages/discord.js/src/structures/EmbedBuilder.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const { EmbedBuilder: BuildersEmbed, isJSONEncodable } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
|
||||
class EmbedBuilder extends BuildersEmbed {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new embed builder from json data
|
||||
* @param {JSONEncodable<APIEmbed> | APIEmbed} other The other data
|
||||
* @returns {EmbedBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = EmbedBuilder;
|
||||
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const { createComponent, Embed } = require('@discordjs/builders');
|
||||
const { Collection } = require('@discordjs/collection');
|
||||
const { DiscordSnowflake } = require('@sapphire/snowflake');
|
||||
const {
|
||||
@@ -12,6 +11,7 @@ const {
|
||||
} = require('discord-api-types/v9');
|
||||
const Base = require('./Base');
|
||||
const ClientApplication = require('./ClientApplication');
|
||||
const Embed = require('./Embed');
|
||||
const InteractionCollector = require('./InteractionCollector');
|
||||
const MessageAttachment = require('./MessageAttachment');
|
||||
const Mentions = require('./MessageMentions');
|
||||
@@ -20,6 +20,7 @@ const ReactionCollector = require('./ReactionCollector');
|
||||
const { Sticker } = require('./Sticker');
|
||||
const { Error } = require('../errors');
|
||||
const ReactionManager = require('../managers/ReactionManager');
|
||||
const Components = require('../util/Components');
|
||||
const { NonSystemMessageTypes } = require('../util/Constants');
|
||||
const MessageFlagsBitField = require('../util/MessageFlagsBitField');
|
||||
const PermissionsBitField = require('../util/PermissionsBitField');
|
||||
@@ -145,7 +146,7 @@ class Message extends Base {
|
||||
* A list of MessageActionRows in the message
|
||||
* @type {ActionRow[]}
|
||||
*/
|
||||
this.components = data.components.map(c => createComponent(c));
|
||||
this.components = data.components.map(c => Components.createComponent(c));
|
||||
} else {
|
||||
this.components = this.components?.slice() ?? [];
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const { Modal: BuildersModal } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
|
||||
class Modal extends BuildersModal {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Modal;
|
||||
24
packages/discord.js/src/structures/SelectMenuBuilder.js
Normal file
24
packages/discord.js/src/structures/SelectMenuBuilder.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const { SelectMenuBuilder: BuildersSelectMenuComponent, isJSONEncodable } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
|
||||
class SelectMenuBuilder extends BuildersSelectMenuComponent {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new select menu builder from json data
|
||||
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data
|
||||
* @returns {SelectMenuBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = SelectMenuBuilder;
|
||||
@@ -1,11 +1,64 @@
|
||||
'use strict';
|
||||
|
||||
const { SelectMenuComponent: BuildersSelectMenuComponent } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
const Component = require('./Component');
|
||||
|
||||
class SelectMenuComponent extends BuildersSelectMenuComponent {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
/**
|
||||
* Represents a select menu component
|
||||
* @extends {Component}
|
||||
*/
|
||||
class SelectMenuComponent extends Component {
|
||||
/**
|
||||
* The placeholder for this select menu
|
||||
* @type {?string}
|
||||
* @readonly
|
||||
*/
|
||||
get placeholder() {
|
||||
return this.data.placeholder ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The maximum amount of options that can be selected
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get maxValues() {
|
||||
return this.data.max_values ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The minimum amount of options that must be selected
|
||||
* @type {?number}
|
||||
* @readonly
|
||||
*/
|
||||
get minValues() {
|
||||
return this.data.min_values ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The custom id of this select menu
|
||||
* @type {string}
|
||||
* @readonly
|
||||
*/
|
||||
get customId() {
|
||||
return this.data.custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this select menu is disabled
|
||||
* @type {?boolean}
|
||||
* @readonly
|
||||
*/
|
||||
get disabled() {
|
||||
return this.data.disabled ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The options in this select menu
|
||||
* @type {APISelectMenuOption[]}
|
||||
* @readonly
|
||||
*/
|
||||
get options() {
|
||||
return this.data.options;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
24
packages/discord.js/src/structures/TextInputBuilder.js
Normal file
24
packages/discord.js/src/structures/TextInputBuilder.js
Normal file
@@ -0,0 +1,24 @@
|
||||
'use strict';
|
||||
|
||||
const { TextInputBuilder: BuildersTextInputComponent, isJSONEncodable } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
|
||||
class TextInputBuilder extends BuildersTextInputComponent {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new text input builder from json data
|
||||
* @param {JSONEncodable<APITextInputComponent> | APITextInputComponent} other The other data
|
||||
* @returns {TextInputBuilder}
|
||||
*/
|
||||
static from(other) {
|
||||
if (isJSONEncodable(other)) {
|
||||
return new this(other.toJSON());
|
||||
}
|
||||
return new this(other);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = TextInputBuilder;
|
||||
@@ -1,11 +1,20 @@
|
||||
'use strict';
|
||||
|
||||
const { TextInputComponent: BuildersTextInputComponent } = require('@discordjs/builders');
|
||||
const Transformers = require('../util/Transformers');
|
||||
const Component = require('./Component');
|
||||
|
||||
class TextInputComponent extends BuildersTextInputComponent {
|
||||
constructor(data) {
|
||||
super(Transformers.toSnakeCase(data));
|
||||
class TextInputComponent extends Component {
|
||||
/**
|
||||
* The custom id of this text input
|
||||
*/
|
||||
get customId() {
|
||||
return this.data.custom_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* The value for this text input
|
||||
*/
|
||||
get value() {
|
||||
return this.data.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
// This file contains the typedefs for camel-cased json data
|
||||
|
||||
const { ComponentType } = require('discord-api-types/v9');
|
||||
/**
|
||||
* @typedef {Object} BaseComponentData
|
||||
* @property {ComponentType} type The type of component
|
||||
@@ -56,3 +56,34 @@
|
||||
/**
|
||||
* @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData|TextInputComponentData} ComponentData
|
||||
*/
|
||||
|
||||
class Components extends null {
|
||||
/**
|
||||
* Transforms API data into a component
|
||||
* @param {APIMessageComponent|Component} data The data to create the component from
|
||||
* @returns {Component}
|
||||
*/
|
||||
static 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.SelectMenu:
|
||||
return new SelectMenuComponent(data);
|
||||
default:
|
||||
throw new Error(`Found unknown component type: ${data.type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = Components;
|
||||
|
||||
const ActionRow = require('../structures/ActionRow');
|
||||
const ButtonComponent = require('../structures/ButtonComponent');
|
||||
const Component = require('../structures/Component');
|
||||
const SelectMenuComponent = require('../structures/SelectMenuComponent');
|
||||
|
||||
185
packages/discord.js/typings/index.d.ts
vendored
185
packages/discord.js/typings/index.d.ts
vendored
@@ -1,24 +1,24 @@
|
||||
import {
|
||||
ActionRow as BuilderActionRow,
|
||||
MessageActionRowComponent,
|
||||
ActionRowBuilder as BuilderActionRow,
|
||||
MessageActionRowComponentBuilder,
|
||||
blockQuote,
|
||||
bold,
|
||||
ButtonComponent as BuilderButtonComponent,
|
||||
ButtonBuilder as BuilderButtonComponent,
|
||||
channelMention,
|
||||
codeBlock,
|
||||
Component,
|
||||
Embed as BuildersEmbed,
|
||||
EmbedBuilder as BuildersEmbed,
|
||||
formatEmoji,
|
||||
hideLinkEmbed,
|
||||
hyperlink,
|
||||
inlineCode,
|
||||
italic,
|
||||
JSONEncodable,
|
||||
MappedComponentTypes,
|
||||
memberNicknameMention,
|
||||
Modal as BuilderModal,
|
||||
quote,
|
||||
roleMention,
|
||||
SelectMenuComponent as BuilderSelectMenuComponent,
|
||||
TextInputComponent as BuilderTextInputComponent,
|
||||
SelectMenuBuilder as BuilderSelectMenuComponent,
|
||||
TextInputBuilder as BuilderTextInputComponent,
|
||||
spoiler,
|
||||
strikethrough,
|
||||
time,
|
||||
@@ -26,7 +26,7 @@ import {
|
||||
TimestampStylesString,
|
||||
underscore,
|
||||
userMention,
|
||||
ModalActionRowComponent,
|
||||
ModalActionRowComponentBuilder,
|
||||
} from '@discordjs/builders';
|
||||
import { Collection } from '@discordjs/collection';
|
||||
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
|
||||
@@ -105,6 +105,11 @@ import {
|
||||
APITextInputComponent,
|
||||
APIModalActionRowComponent,
|
||||
APIModalComponent,
|
||||
APISelectMenuOption,
|
||||
APIEmbedField,
|
||||
APIEmbedAuthor,
|
||||
APIEmbedFooter,
|
||||
APIEmbedImage,
|
||||
} from 'discord-api-types/v9';
|
||||
import { ChildProcess } from 'node:child_process';
|
||||
import { EventEmitter } from 'node:events';
|
||||
@@ -220,8 +225,10 @@ export interface ActionRowData<T extends ActionRowComponent | ActionRowComponent
|
||||
components: T[];
|
||||
}
|
||||
|
||||
export class ActionRow<
|
||||
T extends MessageActionRowComponent | ModalActionRowComponent = MessageActionRowComponent,
|
||||
export class ActionRowBuilder<
|
||||
T extends MessageActionRowComponentBuilder | ModalActionRowComponentBuilder =
|
||||
| MessageActionRowComponentBuilder
|
||||
| ModalActionRowComponentBuilder,
|
||||
> extends BuilderActionRow<T> {
|
||||
constructor(
|
||||
data?:
|
||||
@@ -232,6 +239,14 @@ export class ActionRow<
|
||||
);
|
||||
}
|
||||
|
||||
export type MessageActionRowComponent = ButtonComponent | SelectMenuComponent;
|
||||
export type ModalActionRowComponent = TextInputComponent;
|
||||
|
||||
export class ActionRow<T extends MessageActionRowComponent | ModalActionRowComponent> {
|
||||
private constructor(data: APIActionRowComponent<APIMessageActionRowComponent>);
|
||||
public readonly components: T[];
|
||||
}
|
||||
|
||||
export class ActivityFlagsBitField extends BitField<ActivityFlagsString> {
|
||||
public static Flags: typeof ActivityFlags;
|
||||
public static resolve(bit?: BitFieldResolvable<ActivityFlagsString, number>): number;
|
||||
@@ -356,7 +371,9 @@ export interface InteractionResponseFields<Cached extends CacheType = CacheType>
|
||||
deferReply(options?: InteractionDeferReplyOptions): Promise<void>;
|
||||
fetchReply(): Promise<GuildCacheMessage<Cached>>;
|
||||
followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
|
||||
showModal(modal: Modal | ModalData | APIModalInteractionResponseCallbackData): Promise<void>;
|
||||
showModal(
|
||||
modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalData | APIModalInteractionResponseCallbackData,
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
export abstract class CommandInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
|
||||
@@ -395,7 +412,9 @@ export abstract class CommandInteraction<Cached extends CacheType = CacheType> e
|
||||
public followUp(options: string | MessagePayload | InteractionReplyOptions): Promise<GuildCacheMessage<Cached>>;
|
||||
public reply(options: InteractionReplyOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
|
||||
public showModal(modal: Modal | ModalData | APIModalInteractionResponseCallbackData): Promise<void>;
|
||||
public showModal(
|
||||
modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalData | APIModalInteractionResponseCallbackData,
|
||||
): Promise<void>;
|
||||
private transformOption(
|
||||
option: APIApplicationCommandOption,
|
||||
resolved: APIApplicationCommandInteractionData['resolved'],
|
||||
@@ -502,22 +521,53 @@ export class ButtonInteraction<Cached extends CacheType = CacheType> extends Mes
|
||||
public inRawGuild(): this is ButtonInteraction<'raw'>;
|
||||
}
|
||||
|
||||
export class ButtonComponent extends BuilderButtonComponent {
|
||||
public constructor(data?: ButtonComponentData | (Omit<APIButtonComponent, 'type'> & { type?: ComponentType.Button }));
|
||||
export class Component<T extends APIMessageComponent | APIModalComponent = APIMessageComponent | APIModalComponent> {
|
||||
public readonly data: Readonly<T>;
|
||||
public get type(): T['type'];
|
||||
public toJSON(): T;
|
||||
public equals(other: this | T): boolean;
|
||||
}
|
||||
|
||||
export class SelectMenuComponent extends BuilderSelectMenuComponent {
|
||||
export class ButtonComponent extends Component<APIButtonComponent> {
|
||||
private constructor(data: APIButtonComponent);
|
||||
public get style(): ButtonStyle;
|
||||
public get label(): string | null;
|
||||
public get emoji(): APIMessageComponentEmoji | null;
|
||||
public get disabled(): boolean | null;
|
||||
public get customId(): string | null;
|
||||
public get url(): string | null;
|
||||
}
|
||||
|
||||
export class ButtonBuilder extends BuilderButtonComponent {
|
||||
public constructor(data?: ButtonComponentData | (Omit<APIButtonComponent, 'type'> & { type?: ComponentType.Button }));
|
||||
public static from(other: JSONEncodable<APIButtonComponent> | APIButtonComponent): ButtonBuilder;
|
||||
}
|
||||
|
||||
export class SelectMenuBuilder extends BuilderSelectMenuComponent {
|
||||
public constructor(
|
||||
data?: SelectMenuComponentData | (Omit<APISelectMenuComponent, 'type'> & { type?: ComponentType.SelectMenu }),
|
||||
);
|
||||
public static from(other: JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent): SelectMenuBuilder;
|
||||
}
|
||||
|
||||
export class TextInputComponent extends BuilderTextInputComponent {
|
||||
export class TextInputBuilder extends BuilderTextInputComponent {
|
||||
public constructor(data?: TextInputComponentData | APITextInputComponent);
|
||||
public static from(other: JSONEncodable<APITextInputComponent> | APITextInputComponent): TextInputBuilder;
|
||||
}
|
||||
|
||||
export class Modal extends BuilderModal {
|
||||
public constructor(data?: ModalData | APIModalActionRowComponent);
|
||||
export class TextInputComponent extends Component<APITextInputComponent> {
|
||||
public get customId(): string;
|
||||
public get value(): string;
|
||||
}
|
||||
|
||||
export class SelectMenuComponent extends Component<APISelectMenuComponent> {
|
||||
private constructor(data: APISelectMenuComponent);
|
||||
public get placeholder(): string | null;
|
||||
public get maxValues(): number | null;
|
||||
public get minValues(): number | null;
|
||||
public get customId(): string;
|
||||
public get disabled(): boolean | null;
|
||||
public get options(): APISelectMenuOption[];
|
||||
}
|
||||
|
||||
export interface EmbedData {
|
||||
@@ -535,18 +585,43 @@ export interface EmbedData {
|
||||
fields?: EmbedFieldData[];
|
||||
}
|
||||
|
||||
export interface EmbedImageData {
|
||||
url?: string;
|
||||
export interface IconData {
|
||||
iconURL?: string;
|
||||
proxyIconURL?: string;
|
||||
}
|
||||
|
||||
export type EmbedAuthorData = Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'> & IconData;
|
||||
|
||||
export type EmbedFooterData = Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'> & IconData;
|
||||
|
||||
export interface EmbedProviderData {
|
||||
name?: string;
|
||||
url?: string;
|
||||
}
|
||||
|
||||
export class Embed extends BuildersEmbed {
|
||||
export interface EmbedImageData extends Omit<APIEmbedImage, 'proxy_url'> {
|
||||
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> | APIEmbed): EmbedBuilder;
|
||||
}
|
||||
|
||||
export class Embed {
|
||||
private constructor(data: APIEmbed);
|
||||
public readonly data: Readonly<APIEmbed>;
|
||||
public get fields(): APIEmbedField[] | null;
|
||||
public get title(): string | null;
|
||||
public get description(): string | null;
|
||||
public get url(): string | null;
|
||||
public get color(): number | null;
|
||||
public get timestamp(): string | null;
|
||||
public get thumbnail(): EmbedImageData | null;
|
||||
public get image(): EmbedImageData | null;
|
||||
public equals(other: Embed | APIEmbed): boolean;
|
||||
public toJSON(): APIEmbed;
|
||||
}
|
||||
|
||||
export interface MappedChannelCategoryTypes {
|
||||
@@ -1652,7 +1727,9 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
|
||||
public reply(options: string | MessagePayload | InteractionReplyOptions): Promise<void>;
|
||||
public update(options: InteractionUpdateOptions & { fetchReply: true }): Promise<GuildCacheMessage<Cached>>;
|
||||
public update(options: string | MessagePayload | InteractionUpdateOptions): Promise<void>;
|
||||
public showModal(modal: Modal | ModalData | APIModalInteractionResponseCallbackData): Promise<void>;
|
||||
public showModal(
|
||||
modal: JSONEncodable<APIModalInteractionResponseCallbackData> | ModalData | APIModalInteractionResponseCallbackData,
|
||||
): Promise<void>;
|
||||
}
|
||||
|
||||
export class MessageContextMenuCommandInteraction<
|
||||
@@ -1741,17 +1818,11 @@ export class MessageReaction {
|
||||
public toJSON(): unknown;
|
||||
}
|
||||
|
||||
export interface ModalFieldData {
|
||||
value: string;
|
||||
type: ComponentType;
|
||||
customId: string;
|
||||
}
|
||||
|
||||
export class ModalSubmitFieldsResolver {
|
||||
constructor(components: ModalFieldData[][]);
|
||||
public components: ModalFieldData[][];
|
||||
public fields: Collection<string, ModalFieldData>;
|
||||
public getField(customId: string): ModalFieldData;
|
||||
constructor(components: ModalActionRowComponent[][]);
|
||||
public components: ActionRow<ModalActionRowComponent>;
|
||||
public fields: Collection<string, ModalActionRowComponent>;
|
||||
public getField(customId: string): ModalActionRowComponent;
|
||||
public getTextInputValue(customId: string): string;
|
||||
}
|
||||
|
||||
@@ -1769,7 +1840,7 @@ export interface ModalMessageModalSubmitInteraction<Cached extends CacheType = C
|
||||
|
||||
export interface ModalSubmitActionRow {
|
||||
type: ComponentType.ActionRow;
|
||||
components: ModalFieldData[];
|
||||
components: ActionRow<TextInputComponent>[];
|
||||
}
|
||||
|
||||
export class ModalSubmitInteraction<Cached extends CacheType = CacheType> extends Interaction<Cached> {
|
||||
@@ -2452,6 +2523,14 @@ export class Util extends null {
|
||||
public static splitMessage(text: string, options?: SplitOptions): string[];
|
||||
}
|
||||
|
||||
export class Components extends null {
|
||||
public static createComponentBuilder<T extends keyof MappedComponentTypes>(
|
||||
data: APIMessageComponent & { type: T },
|
||||
): MappedComponentTypes[T];
|
||||
public static createComponentBuilder<C extends Component>(data: C): C;
|
||||
public static createComponentBuilder(data: APIMessageComponent | Component): Component;
|
||||
}
|
||||
|
||||
export class Formatters extends null {
|
||||
public static blockQuote: typeof blockQuote;
|
||||
public static bold: typeof bold;
|
||||
@@ -3966,12 +4045,6 @@ export interface EditGuildTemplateOptions {
|
||||
description?: string;
|
||||
}
|
||||
|
||||
export interface EmbedAuthorData {
|
||||
name: string;
|
||||
url?: string;
|
||||
iconURL?: string;
|
||||
}
|
||||
|
||||
export interface EmbedField {
|
||||
name: string;
|
||||
value: string;
|
||||
@@ -3984,11 +4057,6 @@ export interface EmbedFieldData {
|
||||
inline?: boolean;
|
||||
}
|
||||
|
||||
export interface EmbedFooterData {
|
||||
text: string;
|
||||
iconURL?: string;
|
||||
}
|
||||
|
||||
export type EmojiIdentifierResolvable = string | EmojiResolvable;
|
||||
|
||||
export type EmojiResolvable = Snowflake | GuildEmoji | ReactionEmoji;
|
||||
@@ -4646,7 +4714,11 @@ export interface MessageCollectorOptions extends CollectorOptions<[Message]> {
|
||||
maxProcessed?: number;
|
||||
}
|
||||
|
||||
export type MessageComponent = Component | ActionRow<MessageActionRowComponent> | ButtonComponent | SelectMenuComponent;
|
||||
export type MessageComponent =
|
||||
| Component
|
||||
| ActionRowBuilder<MessageActionRowComponentBuilder | ModalActionRowComponentBuilder>
|
||||
| ButtonComponent
|
||||
| SelectMenuComponent;
|
||||
|
||||
export type MessageComponentCollectorOptions<T extends MessageComponentInteraction> = Omit<
|
||||
InteractionCollectorOptions<T>,
|
||||
@@ -4666,6 +4738,7 @@ export interface MessageEditOptions {
|
||||
flags?: BitFieldResolvable<MessageFlagsString, number>;
|
||||
allowedMentions?: MessageMentionOptions;
|
||||
components?: (
|
||||
| JSONEncodable<APIActionRowComponent<APIMessageActionRowComponent>>
|
||||
| ActionRow<MessageActionRowComponent>
|
||||
| (Required<BaseComponentData> & ActionRowData<MessageActionRowComponentData | MessageActionRowComponent>)
|
||||
| APIActionRowComponent<APIMessageActionRowComponent>
|
||||
@@ -4705,8 +4778,9 @@ export interface MessageOptions {
|
||||
tts?: boolean;
|
||||
nonce?: string | number;
|
||||
content?: string | null;
|
||||
embeds?: (Embed | APIEmbed)[];
|
||||
embeds?: (JSONEncodable<APIEmbed> | APIEmbed)[];
|
||||
components?: (
|
||||
| JSONEncodable<APIActionRowComponent<APIMessageActionRowComponent>>
|
||||
| ActionRow<MessageActionRowComponent>
|
||||
| (Required<BaseComponentData> & ActionRowData<MessageActionRowComponentData | MessageActionRowComponent>)
|
||||
| APIActionRowComponent<APIMessageActionRowComponent>
|
||||
@@ -5255,6 +5329,8 @@ export {
|
||||
ApplicationCommandType,
|
||||
ApplicationCommandOptionType,
|
||||
ApplicationCommandPermissionType,
|
||||
APIEmbedField,
|
||||
APISelectMenuOption,
|
||||
AuditLogEvent,
|
||||
ButtonStyle,
|
||||
ChannelType,
|
||||
@@ -5290,12 +5366,13 @@ export {
|
||||
WebhookType,
|
||||
} from 'discord-api-types/v9';
|
||||
export {
|
||||
UnsafeButtonComponent,
|
||||
UnsafeSelectMenuComponent,
|
||||
SelectMenuOption,
|
||||
UnsafeSelectMenuOption,
|
||||
MessageActionRowComponent,
|
||||
UnsafeEmbed,
|
||||
ModalActionRowComponent,
|
||||
UnsafeButtonBuilder,
|
||||
UnsafeSelectMenuBuilder,
|
||||
SelectMenuOptionBuilder,
|
||||
UnsafeSelectMenuOptionBuilder,
|
||||
MessageActionRowComponentBuilder,
|
||||
ModalActionRowComponentBuilder,
|
||||
UnsafeEmbedBuilder,
|
||||
ModalBuilder,
|
||||
} from '@discordjs/builders';
|
||||
export { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
AuditLogEvent,
|
||||
ButtonStyle,
|
||||
TextInputStyle,
|
||||
APITextInputComponent,
|
||||
APIEmbed,
|
||||
} from 'discord-api-types/v9';
|
||||
import {
|
||||
ApplicationCommand,
|
||||
@@ -59,7 +61,7 @@ import {
|
||||
MessageCollector,
|
||||
MessageComponentInteraction,
|
||||
MessageReaction,
|
||||
Modal,
|
||||
ModalBuilder,
|
||||
NewsChannel,
|
||||
Options,
|
||||
PartialTextBasedChannelFields,
|
||||
@@ -95,10 +97,10 @@ import {
|
||||
GuildAuditLogs,
|
||||
StageInstance,
|
||||
PartialDMChannel,
|
||||
ActionRow,
|
||||
ActionRowBuilder,
|
||||
ButtonComponent,
|
||||
SelectMenuComponent,
|
||||
MessageActionRowComponent,
|
||||
MessageActionRowComponentBuilder,
|
||||
InteractionResponseFields,
|
||||
ThreadChannelType,
|
||||
Events,
|
||||
@@ -109,6 +111,12 @@ import {
|
||||
MessageActionRowComponentData,
|
||||
PartialThreadMember,
|
||||
ThreadMemberFlagsBitField,
|
||||
ButtonBuilder,
|
||||
EmbedBuilder,
|
||||
MessageActionRowComponent,
|
||||
SelectMenuBuilder,
|
||||
TextInputBuilder,
|
||||
TextInputComponent,
|
||||
Embed,
|
||||
} from '.';
|
||||
import { expectAssignable, expectDeprecated, expectNotAssignable, expectNotType, expectType } from 'tsd';
|
||||
@@ -574,7 +582,7 @@ client.on('messageCreate', async message => {
|
||||
assertIsMessage(channel.send({ embeds: [] }));
|
||||
|
||||
const attachment = new MessageAttachment('file.png');
|
||||
const embed = new Embed();
|
||||
const embed = new EmbedBuilder();
|
||||
assertIsMessage(channel.send({ files: [attachment] }));
|
||||
assertIsMessage(channel.send({ embeds: [embed] }));
|
||||
assertIsMessage(channel.send({ embeds: [embed], files: [attachment] }));
|
||||
@@ -744,23 +752,24 @@ client.on('interactionCreate', async interaction => {
|
||||
|
||||
if (!interaction.isCommand()) return;
|
||||
|
||||
void new ActionRow<MessageActionRowComponent>();
|
||||
void new ActionRowBuilder<MessageActionRowComponentBuilder>();
|
||||
|
||||
const button = new ButtonComponent();
|
||||
const button = new ButtonBuilder();
|
||||
|
||||
const actionRow = new ActionRow<MessageActionRowComponent>({
|
||||
const actionRow = new ActionRowBuilder<MessageActionRowComponentBuilder>({
|
||||
type: ComponentType.ActionRow,
|
||||
components: [button.toJSON()],
|
||||
});
|
||||
|
||||
actionRow.toJSON();
|
||||
|
||||
await interaction.reply({ content: 'Hi!', components: [actionRow] });
|
||||
|
||||
// @ts-expect-error
|
||||
interaction.reply({ content: 'Hi!', components: [[button]] });
|
||||
|
||||
// @ts-expect-error
|
||||
void new ActionRow({});
|
||||
|
||||
void new ActionRowBuilder({});
|
||||
// @ts-expect-error
|
||||
await interaction.reply({ content: 'Hi!', components: [button] });
|
||||
|
||||
@@ -1336,34 +1345,34 @@ expectType<CategoryChannel | NewsChannel | StageChannel | StoreChannel | TextCha
|
||||
);
|
||||
expectType<NewsChannel | TextChannel | ThreadChannel>(GuildTextBasedChannel);
|
||||
|
||||
const button = new ButtonComponent({
|
||||
const button = new ButtonBuilder({
|
||||
label: 'test',
|
||||
style: ButtonStyle.Primary,
|
||||
customId: 'test',
|
||||
});
|
||||
|
||||
const selectMenu = new SelectMenuComponent({
|
||||
const selectMenu = new SelectMenuBuilder({
|
||||
maxValues: 10,
|
||||
minValues: 2,
|
||||
customId: 'test',
|
||||
});
|
||||
|
||||
new ActionRow({
|
||||
new ActionRowBuilder({
|
||||
components: [selectMenu.toJSON(), button.toJSON()],
|
||||
});
|
||||
|
||||
new SelectMenuComponent({
|
||||
new SelectMenuBuilder({
|
||||
customId: 'foo',
|
||||
});
|
||||
|
||||
new ButtonComponent({
|
||||
new ButtonBuilder({
|
||||
style: ButtonStyle.Danger,
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
new Embed().setColor('abc');
|
||||
new EmbedBuilder().setColor('abc');
|
||||
|
||||
new Embed().setColor('#ffffff');
|
||||
new EmbedBuilder().setColor('#ffffff');
|
||||
|
||||
expectNotAssignable<ActionRowData<MessageActionRowComponentData>>({
|
||||
type: ComponentType.ActionRow,
|
||||
@@ -1379,7 +1388,7 @@ declare const chatInputInteraction: ChatInputCommandInteraction;
|
||||
expectType<MessageAttachment>(chatInputInteraction.options.getAttachment('attachment', true));
|
||||
expectType<MessageAttachment | null>(chatInputInteraction.options.getAttachment('attachment'));
|
||||
|
||||
declare const modal: Modal;
|
||||
declare const modal: ModalBuilder;
|
||||
|
||||
chatInputInteraction.showModal(modal);
|
||||
|
||||
@@ -1400,3 +1409,27 @@ chatInputInteraction.showModal({
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
declare const selectMenuData: APISelectMenuComponent;
|
||||
SelectMenuBuilder.from(selectMenuData);
|
||||
|
||||
declare const selectMenuComp: SelectMenuComponent;
|
||||
SelectMenuBuilder.from(selectMenuComp);
|
||||
|
||||
declare const buttonData: APIButtonComponent;
|
||||
ButtonBuilder.from(buttonData);
|
||||
|
||||
declare const buttonComp: ButtonComponent;
|
||||
ButtonBuilder.from(buttonComp);
|
||||
|
||||
declare const textInputData: APITextInputComponent;
|
||||
TextInputBuilder.from(textInputData);
|
||||
|
||||
declare const textInputComp: TextInputComponent;
|
||||
TextInputBuilder.from(textInputComp);
|
||||
|
||||
declare const embedData: APIEmbed;
|
||||
EmbedBuilder.from(embedData);
|
||||
|
||||
declare const embedComp: Embed;
|
||||
EmbedBuilder.from(embedComp);
|
||||
|
||||
Reference in New Issue
Block a user