refactor: Tidy up builders and components (#7711)

This commit is contained in:
Jiralite
2022-04-14 11:42:25 +01:00
committed by GitHub
parent 01a423d110
commit 96a0d83a13
14 changed files with 166 additions and 63 deletions

View File

@@ -99,7 +99,6 @@ exports.ContextMenuCommandInteraction = require('./structures/ContextMenuCommand
exports.DMChannel = require('./structures/DMChannel'); exports.DMChannel = require('./structures/DMChannel');
exports.Embed = require('./structures/Embed'); exports.Embed = require('./structures/Embed');
exports.EmbedBuilder = require('./structures/EmbedBuilder'); exports.EmbedBuilder = require('./structures/EmbedBuilder');
exports.UnsafeEmbed = require('@discordjs/builders').UnsafeEmbed;
exports.Emoji = require('./structures/Emoji').Emoji; exports.Emoji = require('./structures/Emoji').Emoji;
exports.Guild = require('./structures/Guild').Guild; exports.Guild = require('./structures/Guild').Guild;
exports.GuildAuditLogs = require('./structures/GuildAuditLogs'); exports.GuildAuditLogs = require('./structures/GuildAuditLogs');
@@ -122,6 +121,7 @@ exports.InviteStageInstance = require('./structures/InviteStageInstance');
exports.InviteGuild = require('./structures/InviteGuild'); exports.InviteGuild = require('./structures/InviteGuild');
exports.Message = require('./structures/Message').Message; exports.Message = require('./structures/Message').Message;
exports.MessageAttachment = require('./structures/MessageAttachment'); exports.MessageAttachment = require('./structures/MessageAttachment');
exports.ModalBuilder = require('./structures/ModalBuilder');
exports.MessageCollector = require('./structures/MessageCollector'); exports.MessageCollector = require('./structures/MessageCollector');
exports.MessageComponentInteraction = require('./structures/MessageComponentInteraction'); exports.MessageComponentInteraction = require('./structures/MessageComponentInteraction');
exports.MessageContextMenuCommandInteraction = require('./structures/MessageContextMenuCommandInteraction'); exports.MessageContextMenuCommandInteraction = require('./structures/MessageContextMenuCommandInteraction');
@@ -196,7 +196,6 @@ exports.InviteTargetType = require('discord-api-types/v10').InviteTargetType;
exports.Locale = require('discord-api-types/v10').Locale; exports.Locale = require('discord-api-types/v10').Locale;
exports.MessageType = require('discord-api-types/v10').MessageType; exports.MessageType = require('discord-api-types/v10').MessageType;
exports.MessageFlags = require('discord-api-types/v10').MessageFlags; exports.MessageFlags = require('discord-api-types/v10').MessageFlags;
exports.ModalBuilder = require('@discordjs/builders').ModalBuilder;
exports.OAuth2Scopes = require('discord-api-types/v10').OAuth2Scopes; exports.OAuth2Scopes = require('discord-api-types/v10').OAuth2Scopes;
exports.PermissionFlagsBits = require('discord-api-types/v10').PermissionFlagsBits; exports.PermissionFlagsBits = require('discord-api-types/v10').PermissionFlagsBits;
exports.RESTJSONErrorCodes = require('discord-api-types/v10').RESTJSONErrorCodes; exports.RESTJSONErrorCodes = require('discord-api-types/v10').RESTJSONErrorCodes;
@@ -207,6 +206,7 @@ exports.TextInputStyle = require('discord-api-types/v10').TextInputStyle;
exports.UserFlags = require('discord-api-types/v10').UserFlags; exports.UserFlags = require('discord-api-types/v10').UserFlags;
exports.WebhookType = require('discord-api-types/v10').WebhookType; exports.WebhookType = require('discord-api-types/v10').WebhookType;
exports.UnsafeButtonBuilder = require('@discordjs/builders').UnsafeButtonBuilder; exports.UnsafeButtonBuilder = require('@discordjs/builders').UnsafeButtonBuilder;
exports.UnsafeEmbedBuilder = require('@discordjs/builders').UnsafeEmbedBuilder;
exports.UnsafeSelectMenuBuilder = require('@discordjs/builders').UnsafeSelectMenuBuilder; exports.UnsafeSelectMenuBuilder = require('@discordjs/builders').UnsafeSelectMenuBuilder;
exports.UnsafeSelectMenuOptionBuilder = require('@discordjs/builders').UnsafeSelectMenuOptionBuilder; exports.UnsafeSelectMenuOptionBuilder = require('@discordjs/builders').UnsafeSelectMenuOptionBuilder;
exports.UnsafeModalBuilder = require('@discordjs/builders').UnsafeModalBuilder; exports.UnsafeModalBuilder = require('@discordjs/builders').UnsafeModalBuilder;

View File

@@ -1,5 +1,6 @@
'use strict'; 'use strict';
const { isJSONEncodable } = require('@discordjs/builders');
const Component = require('./Component'); const Component = require('./Component');
const Components = require('../util/Components'); const Components = require('../util/Components');
@@ -10,6 +11,7 @@ const Components = require('../util/Components');
class ActionRow extends Component { class ActionRow extends Component {
constructor({ components, ...data }) { constructor({ components, ...data }) {
super(data); super(data);
/** /**
* The components in this action row * The components in this action row
* @type {Component[]} * @type {Component[]}
@@ -18,6 +20,18 @@ class ActionRow extends Component {
this.components = components.map(c => Components.createComponent(c)); this.components = components.map(c => Components.createComponent(c));
} }
/**
* Creates a new action row builder from JSON data
* @param {JSONEncodable<APIActionRowComponent>|APIActionRowComponent} other The other data
* @returns {ActionRowBuilder}
*/
static from(other) {
if (isJSONEncodable(other)) {
return new this(other.toJSON());
}
return new this(other);
}
/** /**
* Returns the API-compatible JSON for this component * Returns the API-compatible JSON for this component
* @returns {APIActionRowComponent} * @returns {APIActionRowComponent}

View File

@@ -3,13 +3,22 @@
const { ActionRowBuilder: BuildersActionRow, ComponentBuilder } = require('@discordjs/builders'); const { ActionRowBuilder: BuildersActionRow, ComponentBuilder } = require('@discordjs/builders');
const Transformers = require('../util/Transformers'); const Transformers = require('../util/Transformers');
/**
* Represents an action row builder.
* @extends {BuildersActionRow}
*/
class ActionRowBuilder extends BuildersActionRow { class ActionRowBuilder extends BuildersActionRow {
constructor({ components, ...data } = {}) { constructor({ components, ...data } = {}) {
super({ super({
components: components?.map(c => (c instanceof ComponentBuilder ? c : Transformers.toSnakeCase(c))),
...Transformers.toSnakeCase(data), ...Transformers.toSnakeCase(data),
components: components?.map(c => (c instanceof ComponentBuilder ? c : Transformers.toSnakeCase(c))),
}); });
} }
} }
module.exports = ActionRowBuilder; module.exports = ActionRowBuilder;
/**
* @external BuildersActionRow
* @see {@link https://discord.js.org/#/docs/builders/main/class/ActionRowBuilder}
*/

View File

@@ -1,10 +1,14 @@
'use strict'; 'use strict';
const { ButtonBuilder: BuildersButtonComponent, isJSONEncodable } = require('@discordjs/builders'); const { ButtonBuilder: BuildersButton, isJSONEncodable } = require('@discordjs/builders');
const Transformers = require('../util/Transformers'); const Transformers = require('../util/Transformers');
const Util = require('../util/Util'); const Util = require('../util/Util');
class ButtonBuilder extends BuildersButtonComponent { /**
* Represents a button builder.
* @extends {BuildersButton}
*/
class ButtonBuilder extends BuildersButton {
constructor({ emoji, ...data }) { constructor({ emoji, ...data }) {
super( super(
Transformers.toSnakeCase({ ...data, emoji: emoji && typeof emoji === 'string' ? Util.parseEmoji(emoji) : emoji }), Transformers.toSnakeCase({ ...data, emoji: emoji && typeof emoji === 'string' ? Util.parseEmoji(emoji) : emoji }),
@@ -14,7 +18,7 @@ class ButtonBuilder extends BuildersButtonComponent {
/** /**
* Sets the emoji to display on this button * Sets the emoji to display on this button
* @param {string|APIMessageComponentEmoji} emoji The emoji to display on this button * @param {string|APIMessageComponentEmoji} emoji The emoji to display on this button
* @returns {ButtonComponent} * @returns {ButtonBuilder}
*/ */
setEmoji(emoji) { setEmoji(emoji) {
if (typeof emoji === 'string') { if (typeof emoji === 'string') {
@@ -24,8 +28,8 @@ class ButtonBuilder extends BuildersButtonComponent {
} }
/** /**
* Creates a new button builder from json data * Creates a new button builder from JSON data
* @param {JSONEncodable<APIButtonComponent> | APIButtonComponent} other The other data * @param {JSONEncodable<APIButtonComponent>|APIButtonComponent} other The other data
* @returns {ButtonBuilder} * @returns {ButtonBuilder}
*/ */
static from(other) { static from(other) {
@@ -37,3 +41,8 @@ class ButtonBuilder extends BuildersButtonComponent {
} }
module.exports = ButtonBuilder; module.exports = ButtonBuilder;
/**
* @external BuildersButton
* @see {@link https://discord.js.org/#/docs/builders/main/class/ButtonBuilder}
*/

View File

@@ -2,6 +2,9 @@
const isEqual = require('fast-deep-equal'); const isEqual = require('fast-deep-equal');
/**
* Represents an embed.
*/
class Embed { class Embed {
/** /**
* Creates a new embed object * Creates a new embed object

View File

@@ -4,14 +4,27 @@ const { EmbedBuilder: BuildersEmbed, isJSONEncodable } = require('@discordjs/bui
const Transformers = require('../util/Transformers'); const Transformers = require('../util/Transformers');
const Util = require('../util/Util'); const Util = require('../util/Util');
/**
* Represents an embed builder.
* @extends {BuildersEmbed}
*/
class EmbedBuilder extends BuildersEmbed { class EmbedBuilder extends BuildersEmbed {
constructor(data) { constructor(data) {
super(Transformers.toSnakeCase(data)); super(Transformers.toSnakeCase(data));
} }
/** /**
* Creates a new embed builder from json data * Sets the color of this embed
* @param {JSONEncodable<APIEmbed> | APIEmbed} other The other data * @param {?ColorResolvable} color The color of the embed
* @returns {EmbedBuilder}
*/
setColor(color) {
return super.setColor(color && Util.resolveColor(color));
}
/**
* Creates a new embed builder from JSON data
* @param {JSONEncodable<APIEmbed>|APIEmbed} other The other data
* @returns {EmbedBuilder} * @returns {EmbedBuilder}
*/ */
static from(other) { static from(other) {
@@ -20,18 +33,11 @@ class EmbedBuilder extends BuildersEmbed {
} }
return new this(other); return new this(other);
} }
/**
* Sets the color of this embed
* @param {?ColorResolvable} color The color of the embed
* @returns {Embed}
*/
setColor(color) {
if (color === null) {
return super.setColor(null);
}
return super.setColor(Util.resolveColor(color));
}
} }
module.exports = EmbedBuilder; module.exports = EmbedBuilder;
/**
* @external BuildersEmbed
* @see {@link https://discord.js.org/#/docs/builders/main/class/EmbedBuilder}
*/

View File

@@ -107,28 +107,3 @@ module.exports = MessageComponentInteraction;
* @external APIMessageButton * @external APIMessageButton
* @see {@link https://discord.com/developers/docs/interactions/message-components#button-object} * @see {@link https://discord.com/developers/docs/interactions/message-components#button-object}
*/ */
/**
* @external ButtonComponent
* @see {@link https://discord.js.org/#/docs/builders/main/class/ButtonComponent}
*/
/**
* @external SelectMenuComponent
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuComponent}
*/
/**
* @external SelectMenuOption
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuComponent}
*/
/**
* @external ActionRow
* @see {@link https://discord.js.org/#/docs/builders/main/class/ActionRow}
*/
/**
* @external Embed
* @see {@link https://discord.js.org/#/docs/builders/main/class/Embed}
*/

View File

@@ -0,0 +1,36 @@
'use strict';
const { ModalBuilder: BuildersModal, ComponentBuilder, isJSONEncodable } = require('@discordjs/builders');
const Transformers = require('../util/Transformers');
/**
* Represents a modal builder.
* @extends {BuildersModal}
*/
class ModalBuilder extends BuildersModal {
constructor({ components, ...data }) {
super({
...Transformers.toSnakeCase(data),
components: components?.map(c => (c instanceof ComponentBuilder ? c : Transformers.toSnakeCase(c))),
});
}
/**
* Creates a new modal builder from JSON data
* @param {JSONEncodable<APIModalComponent>|APIModalComponent} other The other data
* @returns {ModalBuilder}
*/
static from(other) {
if (isJSONEncodable(other)) {
return new this(other.toJSON());
}
return new this(other);
}
}
module.exports = ModalBuilder;
/**
* @external BuildersModal
* @see {@link https://discord.js.org/#/docs/builders/main/class/ModalBuilder}
*/

View File

@@ -1,10 +1,14 @@
'use strict'; 'use strict';
const { SelectMenuBuilder: BuildersSelectMenuComponent, isJSONEncodable } = require('@discordjs/builders'); const { SelectMenuBuilder: BuildersSelectMenu, isJSONEncodable } = require('@discordjs/builders');
const Transformers = require('../util/Transformers'); const Transformers = require('../util/Transformers');
const Util = require('../util/Util'); const Util = require('../util/Util');
class SelectMenuBuilder extends BuildersSelectMenuComponent { /**
* Represents a select menu builder.
* @extends {BuildersSelectMenu}
*/
class SelectMenuBuilder extends BuildersSelectMenu {
constructor({ options, ...data }) { constructor({ options, ...data }) {
super( super(
Transformers.toSnakeCase({ Transformers.toSnakeCase({
@@ -18,8 +22,8 @@ class SelectMenuBuilder extends BuildersSelectMenuComponent {
} }
/** /**
* Creates a new select menu builder from json data * Creates a new select menu builder from JSON data
* @param {JSONEncodable<APISelectMenuComponent> | APISelectMenuComponent} other The other data * @param {JSONEncodable<APISelectMenuComponent>|APISelectMenuComponent} other The other data
* @returns {SelectMenuBuilder} * @returns {SelectMenuBuilder}
*/ */
static from(other) { static from(other) {
@@ -31,3 +35,8 @@ class SelectMenuBuilder extends BuildersSelectMenuComponent {
} }
module.exports = SelectMenuBuilder; module.exports = SelectMenuBuilder;
/**
* @external BuildersSelectMenu
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuBuilder}
*/

View File

@@ -4,7 +4,8 @@ const { SelectMenuOptionBuilder: BuildersSelectMenuOption } = require('@discordj
const Util = require('../util/Util'); const Util = require('../util/Util');
/** /**
* Represents a select menu option * Represents a select menu option builder.
* @extends {BuildersSelectMenuOption}
*/ */
class SelectMenuOptionBuilder extends BuildersSelectMenuOption { class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
/** /**
@@ -21,3 +22,8 @@ class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
} }
module.exports = SelectMenuOptionBuilder; module.exports = SelectMenuOptionBuilder;
/**
* @external BuildersSelectMenuOption
* @see {@link https://discord.js.org/#/docs/builders/main/class/SelectMenuOptionBuilder}
*/

View File

@@ -1,16 +1,20 @@
'use strict'; 'use strict';
const { TextInputBuilder: BuildersTextInputComponent, isJSONEncodable } = require('@discordjs/builders'); const { TextInputBuilder: BuildersTextInput, isJSONEncodable } = require('@discordjs/builders');
const Transformers = require('../util/Transformers'); const Transformers = require('../util/Transformers');
class TextInputBuilder extends BuildersTextInputComponent { /**
* Represents a text input builder.
* @extends {BuildersTextInput}
*/
class TextInputBuilder extends BuildersTextInput {
constructor(data) { constructor(data) {
super(Transformers.toSnakeCase(data)); super(Transformers.toSnakeCase(data));
} }
/** /**
* Creates a new text input builder from json data * Creates a new text input builder from JSON data
* @param {JSONEncodable<APITextInputComponent> | APITextInputComponent} other The other data * @param {JSONEncodable<APITextInputComponent>|APITextInputComponent} other The other data
* @returns {TextInputBuilder} * @returns {TextInputBuilder}
*/ */
static from(other) { static from(other) {
@@ -22,3 +26,8 @@ class TextInputBuilder extends BuildersTextInputComponent {
} }
module.exports = TextInputBuilder; module.exports = TextInputBuilder;
/**
* @external BuildersTextInput
* @see {@link https://discord.js.org/#/docs/builders/main/class/TextInputBuilder}
*/

View File

@@ -2,9 +2,15 @@
const Component = require('./Component'); const Component = require('./Component');
/**
* Represents a text input component.
* @extends {Component}
*/
class TextInputComponent extends Component { class TextInputComponent extends Component {
/** /**
* The custom id of this text input * The custom id of this text input
* @type {string}
* @readonly
*/ */
get customId() { get customId() {
return this.data.custom_id; return this.data.custom_id;
@@ -12,6 +18,8 @@ class TextInputComponent extends Component {
/** /**
* The value for this text input * The value for this text input
* @type {string}
* @readonly
*/ */
get value() { get value() {
return this.data.value; return this.data.value;

View File

@@ -1,15 +1,17 @@
'use strict'; 'use strict';
// This file contains the typedefs for camel-cased json data // This file contains the typedefs for camel-cased JSON data
const { ComponentType } = require('discord-api-types/v10'); const { ComponentType } = require('discord-api-types/v10');
/** /**
* @typedef {Object} BaseComponentData * @typedef {Object} BaseComponentData
* @property {ComponentType} type The type of component * @property {ComponentType} type The type of component
*/ */
/** /**
* @typedef {BaseComponentData} ActionRowData * @typedef {BaseComponentData} ActionRowData
* @property {ComponentData[]} components The components in this action row * @property {ComponentData[]} components The components in this action row
*/ */
/** /**
* @typedef {BaseComponentData} ButtonComponentData * @typedef {BaseComponentData} ButtonComponentData
* @property {ButtonStyle} style The style of the button * @property {ButtonStyle} style The style of the button
@@ -19,6 +21,7 @@ const { ComponentType } = require('discord-api-types/v10');
* @property {?string} customId The custom id of the button * @property {?string} customId The custom id of the button
* @property {?string} url The URL of the button * @property {?string} url The URL of the button
*/ */
/** /**
* @typedef {object} SelectMenuComponentOptionData * @typedef {object} SelectMenuComponentOptionData
* @property {string} label The label of the option * @property {string} label The label of the option
@@ -27,6 +30,7 @@ const { ComponentType } = require('discord-api-types/v10');
* @property {?APIComponentEmoji} emoji The emoji on the option * @property {?APIComponentEmoji} emoji The emoji on the option
* @property {?boolean} default Whether this option is selected by default * @property {?boolean} default Whether this option is selected by default
*/ */
/** /**
* @typedef {BaseComponentData} SelectMenuComponentData * @typedef {BaseComponentData} SelectMenuComponentData
* @property {string} customId The custom id of the select menu * @property {string} customId The custom id of the select menu
@@ -39,7 +43,7 @@ const { ComponentType } = require('discord-api-types/v10');
/** /**
* @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} MessageComponentData * @typedef {ActionRowData|ButtonComponentData|SelectMenuComponentData} MessageComponentData
/ */
/** /**
* @typedef {BaseComponentData} TextInputComponentData * @typedef {BaseComponentData} TextInputComponentData
@@ -95,3 +99,8 @@ const ButtonComponent = require('../structures/ButtonComponent');
const Component = require('../structures/Component'); const Component = require('../structures/Component');
const SelectMenuComponent = require('../structures/SelectMenuComponent'); const SelectMenuComponent = require('../structures/SelectMenuComponent');
const TextInputComponent = require('../structures/TextInputComponent'); const TextInputComponent = require('../structures/TextInputComponent');
/**
* @external JSONEncodable
* @see {@link https://discord.js.org/#/docs/builders/main/typedef/JSONEncodable}
*/

View File

@@ -27,6 +27,7 @@ import {
underscore, underscore,
userMention, userMention,
ModalActionRowComponentBuilder, ModalActionRowComponentBuilder,
ModalBuilder as BuildersModal,
} from '@discordjs/builders'; } from '@discordjs/builders';
import { Collection } from '@discordjs/collection'; import { Collection } from '@discordjs/collection';
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest'; import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions } from '@discordjs/rest';
@@ -243,6 +244,11 @@ export class ActionRowBuilder<
type?: ComponentType.ActionRow; type?: ComponentType.ActionRow;
}), }),
); );
public static from(
other:
| JSONEncodable<APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>>
| APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>,
): ActionRowBuilder;
} }
export type MessageActionRowComponent = ButtonComponent | SelectMenuComponent; export type MessageActionRowComponent = ButtonComponent | SelectMenuComponent;
@@ -581,6 +587,11 @@ export class SelectMenuOptionBuilder extends BuildersSelectMenuOption {
public setEmoji(emoji: ComponentEmojiResolvable): this; public setEmoji(emoji: ComponentEmojiResolvable): this;
} }
export class ModalBuilder extends BuildersModal {
public constructor(data?: ModalData | APIModalComponent);
public static from(other: JSONEncodable<APIModalComponent> | APIModalComponent): ModalBuilder;
}
export class TextInputBuilder extends BuilderTextInputComponent { export class TextInputBuilder extends BuilderTextInputComponent {
public constructor(data?: TextInputComponentData | APITextInputComponent); public constructor(data?: TextInputComponentData | APITextInputComponent);
public static from(other: JSONEncodable<APITextInputComponent> | APITextInputComponent): TextInputBuilder; public static from(other: JSONEncodable<APITextInputComponent> | APITextInputComponent): TextInputBuilder;
@@ -4865,7 +4876,7 @@ export interface TextInputComponentData extends BaseComponentData {
export interface ModalData { export interface ModalData {
customId: string; customId: string;
title: string; title: string;
components: ActionRowData<ModalActionRowComponentData>[]; components: (ActionRow<ModalActionRowComponent> | ActionRowData<ModalActionRowComponentData>)[];
} }
export type MessageTarget = export type MessageTarget =
@@ -5385,14 +5396,13 @@ export {
WebhookType, WebhookType,
} from 'discord-api-types/v10'; } from 'discord-api-types/v10';
export { export {
UnsafeEmbedBuilder,
UnsafeModalBuilder,
UnsafeTextInputBuilder,
UnsafeButtonBuilder, UnsafeButtonBuilder,
UnsafeSelectMenuBuilder, UnsafeSelectMenuBuilder,
UnsafeSelectMenuOptionBuilder, UnsafeSelectMenuOptionBuilder,
MessageActionRowComponentBuilder, MessageActionRowComponentBuilder,
ModalActionRowComponentBuilder, ModalActionRowComponentBuilder,
UnsafeEmbedBuilder,
ModalBuilder,
UnsafeModalBuilder,
UnsafeTextInputBuilder,
} from '@discordjs/builders'; } from '@discordjs/builders';
export { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest'; export { DiscordAPIError, HTTPError, RateLimitError } from '@discordjs/rest';