refactor: remove djs components and use /builders components instead (#7252)

Co-authored-by: Vlad Frangu <kingdgrizzle@gmail.com>
This commit is contained in:
Suneet Tipirneni
2022-01-17 07:13:48 -05:00
committed by GitHub
parent 599f96740e
commit 101d7c5ffa
9 changed files with 58 additions and 697 deletions

View File

@@ -77,7 +77,6 @@ exports.BaseGuild = require('./structures/BaseGuild');
exports.BaseGuildEmoji = require('./structures/BaseGuildEmoji');
exports.BaseGuildTextChannel = require('./structures/BaseGuildTextChannel');
exports.BaseGuildVoiceChannel = require('./structures/BaseGuildVoiceChannel');
exports.BaseMessageComponent = require('./structures/BaseMessageComponent');
exports.ButtonInteraction = require('./structures/ButtonInteraction');
exports.CategoryChannel = require('./structures/CategoryChannel');
exports.Channel = require('./structures/Channel').Channel;
@@ -111,9 +110,7 @@ exports.Invite = require('./structures/Invite');
exports.InviteStageInstance = require('./structures/InviteStageInstance');
exports.InviteGuild = require('./structures/InviteGuild');
exports.Message = require('./structures/Message').Message;
exports.MessageActionRow = require('./structures/MessageActionRow');
exports.MessageAttachment = require('./structures/MessageAttachment');
exports.MessageButton = require('./structures/MessageButton');
exports.MessageCollector = require('./structures/MessageCollector');
exports.MessageComponentInteraction = require('./structures/MessageComponentInteraction');
exports.MessageContextMenuCommandInteraction = require('./structures/MessageContextMenuCommandInteraction');
@@ -121,7 +118,6 @@ exports.MessageEmbed = require('./structures/MessageEmbed');
exports.MessageMentions = require('./structures/MessageMentions');
exports.MessagePayload = require('./structures/MessagePayload');
exports.MessageReaction = require('./structures/MessageReaction');
exports.MessageSelectMenu = require('./structures/MessageSelectMenu');
exports.NewsChannel = require('./structures/NewsChannel');
exports.OAuth2Guild = require('./structures/OAuth2Guild');
exports.PartialGroupDMChannel = require('./structures/PartialGroupDMChannel');
@@ -180,3 +176,7 @@ exports.StageInstancePrivacyLevel = require('discord-api-types/v9').StageInstanc
exports.StickerType = require('discord-api-types/v9').StickerType;
exports.StickerFormatType = require('discord-api-types/v9').StickerFormatType;
exports.WebhookType = require('discord-api-types/v9').WebhookType;
exports.ActionRow = require('@discordjs/builders').ActionRow;
exports.ButtonComponent = require('@discordjs/builders').ButtonComponent;
exports.SelectMenuComponent = require('@discordjs/builders').SelectMenuComponent;
exports.SelectMenuOption = require('@discordjs/builders').SelectMenuOption;

View File

@@ -1,104 +0,0 @@
'use strict';
const { ComponentType } = require('discord-api-types/v9');
const { TypeError } = require('../errors');
const { Events } = require('../util/Constants');
/**
* Represents an interactive component of a Message. It should not be necessary to construct this directly.
* See {@link MessageComponent}
*/
class BaseMessageComponent {
/**
* Options for a BaseMessageComponent
* @typedef {Object} BaseMessageComponentOptions
* @property {MessageComponentTypeResolvable} type The type of this component
*/
/**
* Data that can be resolved into options for a MessageComponent. This can be:
* * MessageActionRowOptions
* * MessageButtonOptions
* * MessageSelectMenuOptions
* @typedef {MessageActionRowOptions|MessageButtonOptions|MessageSelectMenuOptions} MessageComponentOptions
*/
/**
* Components that can be sent in a message. These can be:
* * MessageActionRow
* * MessageButton
* * MessageSelectMenu
* @typedef {MessageActionRow|MessageButton|MessageSelectMenu} MessageComponent
* @see {@link https://discord.com/developers/docs/interactions/message-components#component-object-component-types}
*/
/**
* Data that can be resolved to a MessageComponentType. This can be:
* * MessageComponentType
* * string
* * number
* @typedef {string|number|MessageComponentType} MessageComponentTypeResolvable
*/
/**
* @param {BaseMessageComponent|BaseMessageComponentOptions} [data={}] The options for this component
*/
constructor(data) {
/**
* The type of this component
* @type {?MessageComponentType}
*/
this.type = 'type' in data ? BaseMessageComponent.resolveType(data.type) : null;
}
/**
* Constructs a MessageComponent based on the type of the incoming data
* @param {MessageComponentOptions} data Data for a MessageComponent
* @param {Client|WebhookClient} [client] Client constructing this component
* @returns {?MessageComponent}
* @private
*/
static create(data, client) {
let component;
let type = data.type;
if (typeof type === 'string') type = ComponentType[type];
switch (type) {
case ComponentType.ActionRow: {
const MessageActionRow = require('./MessageActionRow');
component = data instanceof MessageActionRow ? data : new MessageActionRow(data, client);
break;
}
case ComponentType.Button: {
const MessageButton = require('./MessageButton');
component = data instanceof MessageButton ? data : new MessageButton(data);
break;
}
case ComponentType.SelectMenu: {
const MessageSelectMenu = require('./MessageSelectMenu');
component = data instanceof MessageSelectMenu ? data : new MessageSelectMenu(data);
break;
}
default:
if (client) {
client.emit(Events.DEBUG, `[BaseMessageComponent] Received component with unknown type: ${data.type}`);
} else {
throw new TypeError('INVALID_TYPE', 'data.type', 'valid MessageComponentType');
}
}
return component;
}
/**
* Resolves the type of a MessageComponent
* @param {MessageComponentTypeResolvable} type The type to resolve
* @returns {MessageComponentType}
* @private
*/
static resolveType(type) {
return typeof type === 'string' ? type : ComponentType[type];
}
}
module.exports = BaseMessageComponent;

View File

@@ -1,10 +1,10 @@
'use strict';
const { createComponent } = require('@discordjs/builders');
const { Collection } = require('@discordjs/collection');
const { DiscordSnowflake } = require('@sapphire/snowflake');
const { MessageType, InteractionType } = require('discord-api-types/v9');
const Base = require('./Base');
const BaseMessageComponent = require('./BaseMessageComponent');
const ClientApplication = require('./ClientApplication');
const InteractionCollector = require('./InteractionCollector');
const MessageAttachment = require('./MessageAttachment');
@@ -138,9 +138,9 @@ class Message extends Base {
if ('components' in data) {
/**
* A list of MessageActionRows in the message
* @type {MessageActionRow[]}
* @type {ActionRow[]}
*/
this.components = data.components.map(c => BaseMessageComponent.create(c, this.client));
this.components = data.components.map(c => createComponent(c));
} else {
this.components = this.components?.slice() ?? [];
}

View File

@@ -1,101 +0,0 @@
'use strict';
const { ComponentType } = require('discord-api-types/v9');
const BaseMessageComponent = require('./BaseMessageComponent');
/**
* Represents an action row containing message components.
* @extends {BaseMessageComponent}
*/
class MessageActionRow extends BaseMessageComponent {
/**
* Components that can be placed in an action row
* * MessageButton
* * MessageSelectMenu
* @typedef {MessageButton|MessageSelectMenu} MessageActionRowComponent
*/
/**
* Options for components that can be placed in an action row
* * MessageButtonOptions
* * MessageSelectMenuOptions
* @typedef {MessageButtonOptions|MessageSelectMenuOptions} MessageActionRowComponentOptions
*/
/**
* Data that can be resolved into components that can be placed in an action row
* * MessageActionRowComponent
* * MessageActionRowComponentOptions
* @typedef {MessageActionRowComponent|MessageActionRowComponentOptions} MessageActionRowComponentResolvable
*/
/**
* @typedef {BaseMessageComponentOptions} MessageActionRowOptions
* @property {MessageActionRowComponentResolvable[]} [components]
* The components to place in this action row
*/
/**
* @param {MessageActionRow|MessageActionRowOptions} [data={}] MessageActionRow to clone or raw data
* @param {Client} [client] The client constructing this MessageActionRow, if provided
*/
constructor(data = {}, client = null) {
super({ type: 'ACTION_ROW' });
/**
* The components in this action row
* @type {MessageActionRowComponent[]}
*/
this.components = data.components?.map(c => BaseMessageComponent.create(c, client)) ?? [];
}
/**
* Adds components to the action row.
* @param {...MessageActionRowComponentResolvable[]} components The components to add
* @returns {MessageActionRow}
*/
addComponents(...components) {
this.components.push(...components.flat(Infinity).map(c => BaseMessageComponent.create(c)));
return this;
}
/**
* Sets the components of the action row.
* @param {...MessageActionRowComponentResolvable[]} components The components to set
* @returns {MessageActionRow}
*/
setComponents(...components) {
this.spliceComponents(0, this.components.length, components);
return this;
}
/**
* Removes, replaces, and inserts components in the action row.
* @param {number} index The index to start at
* @param {number} deleteCount The number of components to remove
* @param {...MessageActionRowComponentResolvable[]} [components] The replacing components
* @returns {MessageActionRow}
*/
spliceComponents(index, deleteCount, ...components) {
this.components.splice(index, deleteCount, ...components.flat(Infinity).map(c => BaseMessageComponent.create(c)));
return this;
}
/**
* Transforms the action row to a plain object.
* @returns {APIMessageComponent} The raw data of this action row
*/
toJSON() {
return {
components: this.components.map(c => c.toJSON()),
type: ComponentType[this.type],
};
}
}
module.exports = MessageActionRow;
/**
* @external APIMessageComponent
* @see {@link https://discord.com/developers/docs/interactions/message-components#component-object}
*/

View File

@@ -1,165 +0,0 @@
'use strict';
const { ButtonStyle, ComponentType } = require('discord-api-types/v9');
const BaseMessageComponent = require('./BaseMessageComponent');
const { RangeError } = require('../errors');
const Util = require('../util/Util');
/**
* Represents a button message component.
* @extends {BaseMessageComponent}
*/
class MessageButton extends BaseMessageComponent {
/**
* @typedef {BaseMessageComponentOptions} MessageButtonOptions
* @property {string} [label] The text to be displayed on this button
* @property {string} [customId] A unique string to be sent in the interaction when clicked
* @property {MessageButtonStyleResolvable} [style] The style of this button
* @property {EmojiIdentifierResolvable} [emoji] The emoji to be displayed to the left of the text
* @property {string} [url] Optional URL for link-style buttons
* @property {boolean} [disabled=false] Disables the button to prevent interactions
*/
/**
* @param {MessageButton|MessageButtonOptions} [data={}] MessageButton to clone or raw data
*/
constructor(data = {}) {
super({ type: 'BUTTON' });
this.setup(data);
}
setup(data) {
/**
* The text to be displayed on this button
* @type {?string}
*/
this.label = data.label ?? null;
/**
* A unique string to be sent in the interaction when clicked
* @type {?string}
*/
this.customId = data.custom_id ?? data.customId ?? null;
/**
* The style of this button
* @type {?MessageButtonStyle}
*/
this.style = data.style ? MessageButton.resolveStyle(data.style) : null;
/**
* Emoji for this button
* @type {?RawEmoji}
*/
this.emoji = data.emoji ? Util.resolvePartialEmoji(data.emoji) : null;
/**
* The URL this button links to, if it is a Link style button
* @type {?string}
*/
this.url = data.url ?? null;
/**
* Whether this button is currently disabled
* @type {boolean}
*/
this.disabled = data.disabled ?? false;
}
/**
* Sets the custom id for this button
* @param {string} customId A unique string to be sent in the interaction when clicked
* @returns {MessageButton}
*/
setCustomId(customId) {
this.customId = Util.verifyString(customId, RangeError, 'BUTTON_CUSTOM_ID');
return this;
}
/**
* Sets the interactive status of the button
* @param {boolean} [disabled=true] Whether this button should be disabled
* @returns {MessageButton}
*/
setDisabled(disabled = true) {
this.disabled = disabled;
return this;
}
/**
* Set the emoji of this button
* @param {EmojiIdentifierResolvable} emoji The emoji to be displayed on this button
* @returns {MessageButton}
*/
setEmoji(emoji) {
this.emoji = Util.resolvePartialEmoji(emoji);
return this;
}
/**
* Sets the label of this button
* @param {string} label The text to be displayed on this button
* @returns {MessageButton}
*/
setLabel(label) {
this.label = Util.verifyString(label, RangeError, 'BUTTON_LABEL');
return this;
}
/**
* Sets the style of this button
* @param {MessageButtonStyleResolvable} style The style of this button
* @returns {MessageButton}
*/
setStyle(style) {
this.style = MessageButton.resolveStyle(style);
return this;
}
/**
* Sets the URL of this button.
* <info>MessageButton#style must be LINK when setting a URL</info>
* @param {string} url The URL of this button
* @returns {MessageButton}
*/
setURL(url) {
this.url = Util.verifyString(url, RangeError, 'BUTTON_URL');
return this;
}
/**
* Transforms the button to a plain object.
* @returns {APIMessageButton} The raw data of this button
*/
toJSON() {
return {
custom_id: this.customId,
disabled: this.disabled,
emoji: this.emoji,
label: this.label,
style: ButtonStyle[this.style],
type: ComponentType[this.type],
url: this.url,
};
}
/**
* Data that can be resolved to a MessageButtonStyle. This can be
* * MessageButtonStyle
* * number
* @typedef {number|MessageButtonStyle} MessageButtonStyleResolvable
*/
/**
* Resolves the style of a button
* @param {MessageButtonStyleResolvable} style The style to resolve
* @returns {MessageButtonStyle}
* @private
*/
static resolveStyle(style) {
return typeof style === 'string' ? style : ButtonStyle[style];
}
}
module.exports = MessageButton;

View File

@@ -1,7 +1,7 @@
'use strict';
const { Buffer } = require('node:buffer');
const BaseMessageComponent = require('./BaseMessageComponent');
const { createComponent } = require('@discordjs/builders');
const MessageEmbed = require('./MessageEmbed');
const { RangeError } = require('../errors');
const DataResolver = require('../util/DataResolver');
@@ -138,7 +138,7 @@ class MessagePayload {
}
}
const components = this.options.components?.map(c => BaseMessageComponent.create(c).toJSON());
const components = this.options.components?.map(c => createComponent(c).toJSON());
let username;
let avatarURL;

View File

@@ -1,212 +0,0 @@
'use strict';
const { ComponentType } = require('discord-api-types/v9');
const BaseMessageComponent = require('./BaseMessageComponent');
const Util = require('../util/Util');
/**
* Represents a select menu message component
* @extends {BaseMessageComponent}
*/
class MessageSelectMenu extends BaseMessageComponent {
/**
* @typedef {BaseMessageComponentOptions} MessageSelectMenuOptions
* @property {string} [customId] A unique string to be sent in the interaction when clicked
* @property {string} [placeholder] Custom placeholder text to display when nothing is selected
* @property {number} [minValues] The minimum number of selections required
* @property {number} [maxValues] The maximum number of selections allowed
* @property {MessageSelectOption[]} [options] Options for the select menu
* @property {boolean} [disabled=false] Disables the select menu to prevent interactions
*/
/**
* @typedef {Object} MessageSelectOption
* @property {string} label The text to be displayed on this option
* @property {string} value The value to be sent for this option
* @property {?string} description Optional description to show for this option
* @property {?RawEmoji} emoji Emoji to display for this option
* @property {boolean} default Render this option as the default selection
*/
/**
* @typedef {Object} MessageSelectOptionData
* @property {string} label The text to be displayed on this option
* @property {string} value The value to be sent for this option
* @property {string} [description] Optional description to show for this option
* @property {EmojiIdentifierResolvable} [emoji] Emoji to display for this option
* @property {boolean} [default] Render this option as the default selection
*/
/**
* @param {MessageSelectMenu|MessageSelectMenuOptions} [data={}] MessageSelectMenu to clone or raw data
*/
constructor(data = {}) {
super({ type: 'SELECT_MENU' });
this.setup(data);
}
setup(data) {
/**
* A unique string to be sent in the interaction when clicked
* @type {?string}
*/
this.customId = data.custom_id ?? data.customId ?? null;
/**
* Custom placeholder text to display when nothing is selected
* @type {?string}
*/
this.placeholder = data.placeholder ?? null;
/**
* The minimum number of selections required
* @type {?number}
*/
this.minValues = data.min_values ?? data.minValues ?? null;
/**
* The maximum number of selections allowed
* @type {?number}
*/
this.maxValues = data.max_values ?? data.maxValues ?? null;
/**
* Options for the select menu
* @type {MessageSelectOption[]}
*/
this.options = this.constructor.normalizeOptions(data.options ?? []);
/**
* Whether this select menu is currently disabled
* @type {boolean}
*/
this.disabled = data.disabled ?? false;
}
/**
* Sets the custom id of this select menu
* @param {string} customId A unique string to be sent in the interaction when clicked
* @returns {MessageSelectMenu}
*/
setCustomId(customId) {
this.customId = Util.verifyString(customId, RangeError, 'SELECT_MENU_CUSTOM_ID');
return this;
}
/**
* Sets the interactive status of the select menu
* @param {boolean} [disabled=true] Whether this select menu should be disabled
* @returns {MessageSelectMenu}
*/
setDisabled(disabled = true) {
this.disabled = disabled;
return this;
}
/**
* Sets the maximum number of selections allowed for this select menu
* @param {number} maxValues Number of selections to be allowed
* @returns {MessageSelectMenu}
*/
setMaxValues(maxValues) {
this.maxValues = maxValues;
return this;
}
/**
* Sets the minimum number of selections required for this select menu
* <info>This will default the maxValues to the number of options, unless manually set</info>
* @param {number} minValues Number of selections to be required
* @returns {MessageSelectMenu}
*/
setMinValues(minValues) {
this.minValues = minValues;
return this;
}
/**
* Sets the placeholder of this select menu
* @param {string} placeholder Custom placeholder text to display when nothing is selected
* @returns {MessageSelectMenu}
*/
setPlaceholder(placeholder) {
this.placeholder = Util.verifyString(placeholder, RangeError, 'SELECT_MENU_PLACEHOLDER');
return this;
}
/**
* Adds options to the select menu.
* @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The options to add
* @returns {MessageSelectMenu}
*/
addOptions(...options) {
this.options.push(...this.constructor.normalizeOptions(options));
return this;
}
/**
* Sets the options of the select menu.
* @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The options to set
* @returns {MessageSelectMenu}
*/
setOptions(...options) {
this.spliceOptions(0, this.options.length, options);
return this;
}
/**
* Removes, replaces, and inserts options in the select menu.
* @param {number} index The index to start at
* @param {number} deleteCount The number of options to remove
* @param {...MessageSelectOptionData|MessageSelectOptionData[]} [options] The replacing option objects
* @returns {MessageSelectMenu}
*/
spliceOptions(index, deleteCount, ...options) {
this.options.splice(index, deleteCount, ...this.constructor.normalizeOptions(...options));
return this;
}
/**
* Transforms the select menu into a plain object
* @returns {APIMessageSelectMenu} The raw data of this select menu
*/
toJSON() {
return {
custom_id: this.customId,
disabled: this.disabled,
placeholder: this.placeholder,
min_values: this.minValues,
max_values: this.maxValues ?? (this.minValues ? this.options.length : undefined),
options: this.options,
type: typeof this.type === 'string' ? ComponentType[this.type] : this.type,
};
}
/**
* Normalizes option input and resolves strings and emojis.
* @param {MessageSelectOptionData} option The select menu option to normalize
* @returns {MessageSelectOption}
*/
static normalizeOption(option) {
let { label, value, description, emoji } = option;
label = Util.verifyString(label, RangeError, 'SELECT_OPTION_LABEL');
value = Util.verifyString(value, RangeError, 'SELECT_OPTION_VALUE');
emoji = emoji ? Util.resolvePartialEmoji(emoji) : null;
description = description ? Util.verifyString(description, RangeError, 'SELECT_OPTION_DESCRIPTION', true) : null;
return { label, value, description, emoji, default: option.default ?? false };
}
/**
* Normalizes option input and resolves strings and emojis.
* @param {...MessageSelectOptionData|MessageSelectOptionData[]} options The select menu options to normalize
* @returns {MessageSelectOption[]}
*/
static normalizeOptions(...options) {
return options.flat(Infinity).map(option => this.normalizeOption(option));
}
}
module.exports = MessageSelectMenu;

View File

@@ -1,8 +1,12 @@
import {
ActionRow,
ActionRowComponent,
blockQuote,
bold,
ButtonComponent,
channelMention,
codeBlock,
Component,
formatEmoji,
hideLinkEmbed,
hyperlink,
@@ -11,6 +15,7 @@ import {
memberNicknameMention,
quote,
roleMention,
SelectMenuComponent,
spoiler,
strikethrough,
time,
@@ -424,13 +429,6 @@ export class BaseGuildVoiceChannel extends GuildChannel {
public fetchInvites(cache?: boolean): Promise<Collection<string, Invite>>;
}
export class BaseMessageComponent {
protected constructor(data?: BaseMessageComponent | BaseMessageComponentOptions);
public type: MessageComponentTypeKey | null;
private static create(data: MessageComponentOptions, client?: Client | WebhookClient): MessageComponent | undefined;
private static resolveType(type: MessageComponentTypeResolvable): MessageComponentTypeKey;
}
export class BitField<S extends string, N extends number | bigint = number> {
public constructor(bits?: BitFieldResolvable<S, N>);
public bitfield: N;
@@ -454,10 +452,10 @@ export class ButtonInteraction<Cached extends CacheType = CacheType> extends Mes
private constructor(client: Client, data: RawMessageButtonInteractionData);
public readonly component: CacheTypeReducer<
Cached,
MessageButton,
ButtonComponent,
APIButtonComponent,
MessageButton | APIButtonComponent,
MessageButton | APIButtonComponent
ButtonComponent | APIButtonComponent,
ButtonComponent | APIButtonComponent
>;
public componentType: 'Button';
public inGuild(): this is ButtonInteraction<'raw' | 'cached'>;
@@ -1476,7 +1474,7 @@ export class Message<Cached extends boolean = boolean> extends Base {
public readonly channel: If<Cached, GuildTextBasedChannel, TextBasedChannel>;
public channelId: Snowflake;
public readonly cleanContent: string;
public components: MessageActionRow[];
public components: ActionRow<ActionRowComponent>[];
public content: string;
public readonly createdAt: Date;
public createdTimestamp: number;
@@ -1527,7 +1525,7 @@ export class Message<Cached extends boolean = boolean> extends Base {
public react(emoji: EmojiIdentifierResolvable): Promise<MessageReaction>;
public removeAttachments(): Promise<Message>;
public reply(options: string | MessagePayload | ReplyMessageOptions): Promise<Message>;
public resolveComponent(customId: string): MessageActionRowComponent | null;
public resolveComponent(customId: string): ActionRowComponent | null;
public startThread(options: StartThreadOptions): Promise<ThreadChannel>;
public suppressEmbeds(suppress?: boolean): Promise<Message>;
public toJSON(): unknown;
@@ -1536,24 +1534,6 @@ export class Message<Cached extends boolean = boolean> extends Base {
public inGuild(): this is Message<true> & this;
}
export class MessageActionRow extends BaseMessageComponent {
public constructor(data?: MessageActionRow | MessageActionRowOptions | APIActionRowComponent);
public type: 'ActionRow';
public components: MessageActionRowComponent[];
public addComponents(
...components: MessageActionRowComponentResolvable[] | MessageActionRowComponentResolvable[][]
): this;
public setComponents(
...components: MessageActionRowComponentResolvable[] | MessageActionRowComponentResolvable[][]
): this;
public spliceComponents(
index: number,
deleteCount: number,
...components: MessageActionRowComponentResolvable[] | MessageActionRowComponentResolvable[][]
): this;
public toJSON(): APIActionRowComponent;
}
export class MessageAttachment {
public constructor(attachment: BufferResolvable | Stream, name?: string, data?: RawMessageAttachmentData);
@@ -1576,25 +1556,6 @@ export class MessageAttachment {
public toJSON(): unknown;
}
export class MessageButton extends BaseMessageComponent {
public constructor(data?: MessageButton | MessageButtonOptions | APIButtonComponent);
public customId: string | null;
public disabled: boolean;
public emoji: APIPartialEmoji | null;
public label: string | null;
public style: ButtonStyleKey | null;
public type: 'Button';
public url: string | null;
public setCustomId(customId: string): this;
public setDisabled(disabled?: boolean): this;
public setEmoji(emoji: EmojiIdentifierResolvable): this;
public setLabel(label: string): this;
public setStyle(style: MessageButtonStyleResolvable): this;
public setURL(url: string): this;
public toJSON(): APIButtonComponent;
private static resolveStyle(style: MessageButtonStyleResolvable): ButtonStyleKey;
}
export class MessageCollector extends Collector<Snowflake, Message> {
public constructor(channel: TextBasedChannel, options?: MessageCollectorOptions);
private _handleChannelDeletion(channel: NonThreadGuildBasedChannel): void;
@@ -1613,10 +1574,10 @@ export class MessageComponentInteraction<Cached extends CacheType = CacheType> e
protected constructor(client: Client, data: RawMessageComponentInteractionData);
public readonly component: CacheTypeReducer<
Cached,
MessageActionRowComponent,
ActionRowComponent,
Exclude<APIMessageComponent, APIActionRowComponent>,
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent>,
MessageActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent>
ActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent>,
ActionRowComponent | Exclude<APIMessageComponent, APIActionRowComponent>
>;
public componentType: Exclude<keyof typeof ComponentType, 'ActionRow'>;
public customId: string;
@@ -1776,30 +1737,6 @@ export class MessageReaction {
public toJSON(): unknown;
}
export class MessageSelectMenu extends BaseMessageComponent {
public constructor(data?: MessageSelectMenu | MessageSelectMenuOptions | APISelectMenuComponent);
public customId: string | null;
public disabled: boolean;
public maxValues: number | null;
public minValues: number | null;
public options: MessageSelectOption[];
public placeholder: string | null;
public type: 'SelectMenu';
public addOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this;
public setOptions(...options: MessageSelectOptionData[] | MessageSelectOptionData[][]): this;
public setCustomId(customId: string): this;
public setDisabled(disabled?: boolean): this;
public setMaxValues(maxValues: number): this;
public setMinValues(minValues: number): this;
public setPlaceholder(placeholder: string): this;
public spliceOptions(
index: number,
deleteCount: number,
...options: MessageSelectOptionData[] | MessageSelectOptionData[][]
): this;
public toJSON(): APISelectMenuComponent;
}
export class NewsChannel extends BaseGuildTextChannel {
public threads: ThreadManager<AllowedThreadTypeForNewsChannel>;
public type: 'GuildNews';
@@ -1951,10 +1888,10 @@ export class SelectMenuInteraction<Cached extends CacheType = CacheType> extends
public constructor(client: Client, data: RawMessageSelectMenuInteractionData);
public readonly component: CacheTypeReducer<
Cached,
MessageSelectMenu,
SelectMenuComponent,
APISelectMenuComponent,
MessageSelectMenu | APISelectMenuComponent,
MessageSelectMenu | APISelectMenuComponent
SelectMenuComponent | APISelectMenuComponent,
SelectMenuComponent | APISelectMenuComponent
>;
public componentType: 'SelectMenu';
public values: string[];
@@ -4696,16 +4633,14 @@ export type MemberMention = UserMention | `<@!${Snowflake}>`;
export type TeamMemberMembershipStateKey = keyof typeof TeamMemberMembershipState;
export type MessageActionRowComponent = MessageButton | MessageSelectMenu;
export type MessageActionRowComponentOptions =
export type ActionRowComponentOptions =
| (Required<BaseMessageComponentOptions> & MessageButtonOptions)
| (Required<BaseMessageComponentOptions> & MessageSelectMenuOptions);
export type MessageActionRowComponentResolvable = MessageActionRowComponent | MessageActionRowComponentOptions;
export type MessageActionRowComponentResolvable = ActionRowComponent | ActionRowComponentOptions;
export interface MessageActionRowOptions extends BaseMessageComponentOptions {
components: MessageActionRowComponentResolvable[];
export interface ActionRowOptions extends BaseMessageComponentOptions {
components: ActionRowComponent[];
}
export interface MessageActivity {
@@ -4740,7 +4675,7 @@ export interface MessageCollectorOptions extends CollectorOptions<[Message]> {
maxProcessed?: number;
}
export type MessageComponent = BaseMessageComponent | MessageActionRow | MessageButton | MessageSelectMenu;
export type MessageComponent = Component | ActionRow<ActionRowComponent> | ButtonComponent | SelectMenuComponent;
export type MessageComponentCollectorOptions<T extends MessageComponentInteraction> = Omit<
InteractionCollectorOptions<T>,
@@ -4754,7 +4689,7 @@ export type MessageChannelComponentCollectorOptions<T extends MessageComponentIn
export type MessageComponentOptions =
| BaseMessageComponentOptions
| MessageActionRowOptions
| ActionRowOptions
| MessageButtonOptions
| MessageSelectMenuOptions;
@@ -4769,7 +4704,7 @@ export interface MessageEditOptions {
files?: (FileOptions | BufferResolvable | Stream | MessageAttachment)[];
flags?: BitFieldResolvable<MessageFlagsString, number>;
allowedMentions?: MessageMentionOptions;
components?: (MessageActionRow | (Required<BaseMessageComponentOptions> & MessageActionRowOptions))[];
components?: (ActionRow<ActionRowComponent> | (Required<BaseMessageComponentOptions> & ActionRowOptions))[];
}
export interface MessageEmbedAuthor {
@@ -4868,7 +4803,7 @@ export interface MessageOptions {
nonce?: string | number;
content?: string | null;
embeds?: (MessageEmbed | MessageEmbedOptions | APIEmbed)[];
components?: (MessageActionRow | (Required<BaseMessageComponentOptions> & MessageActionRowOptions))[];
components?: (ActionRow<ActionRowComponent> | (Required<BaseMessageComponentOptions> & ActionRowOptions))[];
allowedMentions?: MessageMentionOptions;
files?: (FileOptions | BufferResolvable | Stream | MessageAttachment)[];
reply?: ReplyOptions;
@@ -5545,3 +5480,10 @@ export {
StickerFormatType,
WebhookType,
} from 'discord-api-types/v9';
export {
ActionRow,
ButtonComponent,
SelectMenuComponent,
SelectMenuOption,
ActionRowComponent,
} from '@discordjs/builders';

View File

@@ -1,5 +1,5 @@
import type { ChildProcess } from 'child_process';
import type {
import {
APIInteractionGuildMember,
APIMessage,
APIPartialChannel,
@@ -10,6 +10,7 @@ import type {
APIButtonComponent,
APISelectMenuComponent,
ApplicationCommandOptionType,
ComponentType,
} from 'discord-api-types/v9';
import { AuditLogEvent } from 'discord-api-types/v9';
import {
@@ -47,9 +48,7 @@ import {
Interaction,
InteractionCollector,
Message,
MessageActionRow,
MessageAttachment,
MessageButton,
MessageCollector,
MessageComponentInteraction,
MessageEmbed,
@@ -88,9 +87,11 @@ import {
GuildAuditLogsEntry,
GuildAuditLogs,
StageInstance,
MessageActionRowComponent,
MessageSelectMenu,
PartialDMChannel,
ActionRow,
ButtonComponent,
SelectMenuComponent,
ActionRowComponent,
} from '.';
import { expectAssignable, expectDeprecated, expectNotAssignable, expectNotType, expectType } from 'tsd';
@@ -668,11 +669,11 @@ client.on('interactionCreate', async interaction => {
if (!interaction.isCommand()) return;
void new MessageActionRow();
void new ActionRow<ActionRowComponent>();
const button = new MessageButton();
const button = new ButtonComponent();
const actionRow = new MessageActionRow({ components: [button] });
const actionRow = new ActionRow({ type: ComponentType.ActionRow, components: [button] });
await interaction.reply({ content: 'Hi!', components: [actionRow] });
@@ -993,11 +994,11 @@ client.on('interactionCreate', async interaction => {
if (interaction.isButton()) {
expectType<ButtonInteraction>(interaction);
expectType<MessageButton | APIButtonComponent>(interaction.component);
expectType<ButtonComponent | APIButtonComponent>(interaction.component);
expectType<Message | APIMessage>(interaction.message);
if (interaction.inCachedGuild()) {
expectAssignable<ButtonInteraction>(interaction);
expectType<MessageButton>(interaction.component);
expectType<ButtonComponent>(interaction.component);
expectType<Message<true>>(interaction.message);
expectType<Guild>(interaction.guild);
expectAssignable<Promise<Message>>(interaction.reply({ fetchReply: true }));
@@ -1009,7 +1010,7 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<APIMessage>>(interaction.reply({ fetchReply: true }));
} else if (interaction.inGuild()) {
expectAssignable<ButtonInteraction>(interaction);
expectType<MessageButton | APIButtonComponent>(interaction.component);
expectType<ButtonComponent | APIButtonComponent>(interaction.component);
expectType<Message | APIMessage>(interaction.message);
expectAssignable<Guild | null>(interaction.guild);
expectType<Promise<APIMessage | Message>>(interaction.reply({ fetchReply: true }));
@@ -1018,11 +1019,11 @@ client.on('interactionCreate', async interaction => {
if (interaction.isMessageComponent()) {
expectType<MessageComponentInteraction>(interaction);
expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
expectType<ActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
expectType<Message | APIMessage>(interaction.message);
if (interaction.inCachedGuild()) {
expectAssignable<MessageComponentInteraction>(interaction);
expectType<MessageActionRowComponent>(interaction.component);
expectType<ActionRowComponent>(interaction.component);
expectType<Message<true>>(interaction.message);
expectType<Guild>(interaction.guild);
expectAssignable<Promise<Message>>(interaction.reply({ fetchReply: true }));
@@ -1034,7 +1035,7 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<APIMessage>>(interaction.reply({ fetchReply: true }));
} else if (interaction.inGuild()) {
expectAssignable<MessageComponentInteraction>(interaction);
expectType<MessageActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
expectType<ActionRowComponent | APIButtonComponent | APISelectMenuComponent>(interaction.component);
expectType<Message | APIMessage>(interaction.message);
expectType<Guild | null>(interaction.guild);
expectType<Promise<APIMessage | Message>>(interaction.reply({ fetchReply: true }));
@@ -1043,11 +1044,11 @@ client.on('interactionCreate', async interaction => {
if (interaction.isSelectMenu()) {
expectType<SelectMenuInteraction>(interaction);
expectType<MessageSelectMenu | APISelectMenuComponent>(interaction.component);
expectType<SelectMenuComponent | APISelectMenuComponent>(interaction.component);
expectType<Message | APIMessage>(interaction.message);
if (interaction.inCachedGuild()) {
expectAssignable<SelectMenuInteraction>(interaction);
expectType<MessageSelectMenu>(interaction.component);
expectType<SelectMenuComponent>(interaction.component);
expectType<Message<true>>(interaction.message);
expectType<Guild>(interaction.guild);
expectType<Promise<Message<true>>>(interaction.reply({ fetchReply: true }));
@@ -1059,7 +1060,7 @@ client.on('interactionCreate', async interaction => {
expectType<Promise<APIMessage>>(interaction.reply({ fetchReply: true }));
} else if (interaction.inGuild()) {
expectAssignable<SelectMenuInteraction>(interaction);
expectType<MessageSelectMenu | APISelectMenuComponent>(interaction.component);
expectType<SelectMenuComponent | APISelectMenuComponent>(interaction.component);
expectType<Message | APIMessage>(interaction.message);
expectType<Guild | null>(interaction.guild);
expectType<Promise<Message | APIMessage>>(interaction.reply({ fetchReply: true }));