mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-17 20:13:30 +01:00
docs(builders): Add some basic documentation (#9359)
This commit is contained in:
@@ -18,10 +18,21 @@ import type { StringSelectMenuBuilder } from './selectMenu/StringSelectMenu.js';
|
|||||||
import type { UserSelectMenuBuilder } from './selectMenu/UserSelectMenu.js';
|
import type { UserSelectMenuBuilder } from './selectMenu/UserSelectMenu.js';
|
||||||
import type { TextInputBuilder } from './textInput/TextInput.js';
|
import type { TextInputBuilder } from './textInput/TextInput.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The builders that may be used for messages.
|
||||||
|
*/
|
||||||
export type MessageComponentBuilder =
|
export type MessageComponentBuilder =
|
||||||
| ActionRowBuilder<MessageActionRowComponentBuilder>
|
| ActionRowBuilder<MessageActionRowComponentBuilder>
|
||||||
| MessageActionRowComponentBuilder;
|
| MessageActionRowComponentBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The builders that may be used for modals.
|
||||||
|
*/
|
||||||
export type ModalComponentBuilder = ActionRowBuilder<ModalActionRowComponentBuilder> | ModalActionRowComponentBuilder;
|
export type ModalComponentBuilder = ActionRowBuilder<ModalActionRowComponentBuilder> | ModalActionRowComponentBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The builders that may be used within an action row for messages.
|
||||||
|
*/
|
||||||
export type MessageActionRowComponentBuilder =
|
export type MessageActionRowComponentBuilder =
|
||||||
| ButtonBuilder
|
| ButtonBuilder
|
||||||
| ChannelSelectMenuBuilder
|
| ChannelSelectMenuBuilder
|
||||||
@@ -29,11 +40,19 @@ export type MessageActionRowComponentBuilder =
|
|||||||
| RoleSelectMenuBuilder
|
| RoleSelectMenuBuilder
|
||||||
| StringSelectMenuBuilder
|
| StringSelectMenuBuilder
|
||||||
| UserSelectMenuBuilder;
|
| UserSelectMenuBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The builders that may be used within an action row for modals.
|
||||||
|
*/
|
||||||
export type ModalActionRowComponentBuilder = TextInputBuilder;
|
export type ModalActionRowComponentBuilder = TextInputBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any builder.
|
||||||
|
*/
|
||||||
export type AnyComponentBuilder = MessageActionRowComponentBuilder | ModalActionRowComponentBuilder;
|
export type AnyComponentBuilder = MessageActionRowComponentBuilder | ModalActionRowComponentBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an action row component
|
* A builder that creates API-compatible JSON data for action rows.
|
||||||
*
|
*
|
||||||
* @typeParam T - The types of components this action row holds
|
* @typeParam T - The types of components this action row holds
|
||||||
*/
|
*/
|
||||||
@@ -41,16 +60,16 @@ export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBu
|
|||||||
APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>
|
APIActionRowComponent<APIMessageActionRowComponent | APIModalActionRowComponent>
|
||||||
> {
|
> {
|
||||||
/**
|
/**
|
||||||
* The components within this action row
|
* The components within this action row.
|
||||||
*/
|
*/
|
||||||
public readonly components: T[];
|
public readonly components: T[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new action row from API data
|
* Creates a new action row from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this action row with
|
* @param data - The API data to create this action row with
|
||||||
* @example
|
* @example
|
||||||
* Creating an action row from an API data object
|
* Creating an action row from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const actionRow = new ActionRowBuilder({
|
* const actionRow = new ActionRowBuilder({
|
||||||
* components: [
|
* components: [
|
||||||
@@ -64,7 +83,7 @@ export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBu
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating an action row using setters and API data
|
* Creating an action row using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const actionRow = new ActionRowBuilder({
|
* const actionRow = new ActionRowBuilder({
|
||||||
* components: [
|
* components: [
|
||||||
@@ -87,7 +106,7 @@ export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBu
|
|||||||
/**
|
/**
|
||||||
* Adds components to this action row.
|
* Adds components to this action row.
|
||||||
*
|
*
|
||||||
* @param components - The components to add to this action row.
|
* @param components - The components to add
|
||||||
*/
|
*/
|
||||||
public addComponents(...components: RestOrArray<T>) {
|
public addComponents(...components: RestOrArray<T>) {
|
||||||
this.components.push(...normalizeArray(components));
|
this.components.push(...normalizeArray(components));
|
||||||
@@ -95,9 +114,9 @@ export class ActionRowBuilder<T extends AnyComponentBuilder> extends ComponentBu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the components in this action row
|
* Sets components for this action row.
|
||||||
*
|
*
|
||||||
* @param components - The components to set this row to
|
* @param components - The components to set
|
||||||
*/
|
*/
|
||||||
public setComponents(...components: RestOrArray<T>) {
|
public setComponents(...components: RestOrArray<T>) {
|
||||||
this.components.splice(0, this.components.length, ...normalizeArray(components));
|
this.components.splice(0, this.components.length, ...normalizeArray(components));
|
||||||
|
|||||||
@@ -6,10 +6,13 @@ import type {
|
|||||||
ComponentType,
|
ComponentType,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any action row component data represented as an object.
|
||||||
|
*/
|
||||||
export type AnyAPIActionRowComponent = APIActionRowComponent<APIActionRowComponentTypes> | APIActionRowComponentTypes;
|
export type AnyAPIActionRowComponent = APIActionRowComponent<APIActionRowComponentTypes> | APIActionRowComponentTypes;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a discord component
|
* The base component builder that contains common symbols for all sorts of components.
|
||||||
*
|
*
|
||||||
* @typeParam DataType - The type of internal API data that is stored within the component
|
* @typeParam DataType - The type of internal API data that is stored within the component
|
||||||
*/
|
*/
|
||||||
@@ -18,12 +21,12 @@ export abstract class ComponentBuilder<
|
|||||||
> implements JSONEncodable<AnyAPIActionRowComponent>
|
> implements JSONEncodable<AnyAPIActionRowComponent>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* The API data associated with this component
|
* The API data associated with this component.
|
||||||
*/
|
*/
|
||||||
public readonly data: Partial<DataType>;
|
public readonly data: Partial<DataType>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Serializes this component to an API-compatible JSON object
|
* Serializes this builder to API-compatible JSON data.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method runs validations on the data before serializing it.
|
* This method runs validations on the data before serializing it.
|
||||||
@@ -31,6 +34,11 @@ export abstract class ComponentBuilder<
|
|||||||
*/
|
*/
|
||||||
public abstract toJSON(): AnyAPIActionRowComponent;
|
public abstract toJSON(): AnyAPIActionRowComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new kind of component.
|
||||||
|
*
|
||||||
|
* @param data - The data to construct a component out of
|
||||||
|
*/
|
||||||
public constructor(data: Partial<DataType>) {
|
public constructor(data: Partial<DataType>) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,27 +14,63 @@ import { StringSelectMenuBuilder } from './selectMenu/StringSelectMenu.js';
|
|||||||
import { UserSelectMenuBuilder } from './selectMenu/UserSelectMenu.js';
|
import { UserSelectMenuBuilder } from './selectMenu/UserSelectMenu.js';
|
||||||
import { TextInputBuilder } from './textInput/TextInput.js';
|
import { TextInputBuilder } from './textInput/TextInput.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Components here are mapped to their respective builder.
|
||||||
|
*/
|
||||||
export interface MappedComponentTypes {
|
export interface MappedComponentTypes {
|
||||||
|
/**
|
||||||
|
* The action row component type is associated with an {@link ActionRowBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.ActionRow]: ActionRowBuilder<AnyComponentBuilder>;
|
[ComponentType.ActionRow]: ActionRowBuilder<AnyComponentBuilder>;
|
||||||
|
/**
|
||||||
|
* The button component type is associated with an {@link ButtonBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.Button]: ButtonBuilder;
|
[ComponentType.Button]: ButtonBuilder;
|
||||||
|
/**
|
||||||
|
* The string select component type is associated with an {@link StringSelectMenuBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.StringSelect]: StringSelectMenuBuilder;
|
[ComponentType.StringSelect]: StringSelectMenuBuilder;
|
||||||
|
/**
|
||||||
|
* The text inpiut component type is associated with an {@link TextInputBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.TextInput]: TextInputBuilder;
|
[ComponentType.TextInput]: TextInputBuilder;
|
||||||
|
/**
|
||||||
|
* The user select component type is associated with an {@link UserSelectMenuBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.UserSelect]: UserSelectMenuBuilder;
|
[ComponentType.UserSelect]: UserSelectMenuBuilder;
|
||||||
|
/**
|
||||||
|
* The role select component type is associated with an {@link RoleSelectMenuBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.RoleSelect]: RoleSelectMenuBuilder;
|
[ComponentType.RoleSelect]: RoleSelectMenuBuilder;
|
||||||
|
/**
|
||||||
|
* The mentionable select component type is associated with an {@link MentionableSelectMenuBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder;
|
[ComponentType.MentionableSelect]: MentionableSelectMenuBuilder;
|
||||||
|
/**
|
||||||
|
* The channel select component type is associated with an {@link ChannelSelectMenuBuilder}.
|
||||||
|
*/
|
||||||
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder;
|
[ComponentType.ChannelSelect]: ChannelSelectMenuBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory for creating components from API data
|
* Factory for creating components from API data.
|
||||||
*
|
*
|
||||||
* @param data - The api data to transform to a component class
|
* @typeParam T - The type of component to use
|
||||||
|
* @param data - The API data to transform to a component class
|
||||||
*/
|
*/
|
||||||
export function createComponentBuilder<T extends keyof MappedComponentTypes>(
|
export function createComponentBuilder<T extends keyof MappedComponentTypes>(
|
||||||
// eslint-disable-next-line @typescript-eslint/sort-type-union-intersection-members
|
// eslint-disable-next-line @typescript-eslint/sort-type-union-intersection-members
|
||||||
data: (APIModalComponent | APIMessageComponent) & { type: T },
|
data: (APIModalComponent | APIMessageComponent) & { type: T },
|
||||||
): MappedComponentTypes[T];
|
): MappedComponentTypes[T];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory for creating components from API data.
|
||||||
|
*
|
||||||
|
* @typeParam C - The type of component to use
|
||||||
|
* @param data - The API data to transform to a component class
|
||||||
|
*/
|
||||||
export function createComponentBuilder<C extends MessageComponentBuilder | ModalComponentBuilder>(data: C): C;
|
export function createComponentBuilder<C extends MessageComponentBuilder | ModalComponentBuilder>(data: C): C;
|
||||||
|
|
||||||
export function createComponentBuilder(
|
export function createComponentBuilder(
|
||||||
data: APIMessageComponent | APIModalComponent | MessageComponentBuilder,
|
data: APIMessageComponent | APIModalComponent | MessageComponentBuilder,
|
||||||
): ComponentBuilder {
|
): ComponentBuilder {
|
||||||
@@ -60,7 +96,7 @@ export function createComponentBuilder(
|
|||||||
case ComponentType.ChannelSelect:
|
case ComponentType.ChannelSelect:
|
||||||
return new ChannelSelectMenuBuilder(data);
|
return new ChannelSelectMenuBuilder(data);
|
||||||
default:
|
default:
|
||||||
// @ts-expect-error: This case can still occur if we get a newer unsupported component type
|
// @ts-expect-error This case can still occur if we get a newer unsupported component type
|
||||||
throw new Error(`Cannot properly serialize component type: ${data.type}`);
|
throw new Error(`Cannot properly serialize component type: ${data.type}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ import {
|
|||||||
import { ComponentBuilder } from '../Component.js';
|
import { ComponentBuilder } from '../Component.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a button component
|
* A builder that creates API-compatible JSON data for buttons.
|
||||||
*/
|
*/
|
||||||
export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
||||||
/**
|
/**
|
||||||
* Creates a new button from API data
|
* Creates a new button from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this button with
|
* @param data - The API data to create this button with
|
||||||
* @example
|
* @example
|
||||||
* Creating a button from an API data object
|
* Creating a button from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const button = new ButtonBuilder({
|
* const button = new ButtonBuilder({
|
||||||
* custom_id: 'a cool button',
|
* custom_id: 'a cool button',
|
||||||
@@ -39,7 +39,7 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a button using setters and API data
|
* Creating a button using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const button = new ButtonBuilder({
|
* const button = new ButtonBuilder({
|
||||||
* style: ButtonStyle.Secondary,
|
* style: ButtonStyle.Secondary,
|
||||||
@@ -54,9 +54,9 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the style of this button
|
* Sets the style of this button.
|
||||||
*
|
*
|
||||||
* @param style - The style of the button
|
* @param style - The style to use
|
||||||
*/
|
*/
|
||||||
public setStyle(style: ButtonStyle) {
|
public setStyle(style: ButtonStyle) {
|
||||||
this.data.style = buttonStyleValidator.parse(style);
|
this.data.style = buttonStyleValidator.parse(style);
|
||||||
@@ -64,12 +64,12 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the URL for this button
|
* Sets the URL for this button.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method is only available to buttons using the `Link` button style.
|
* This method is only available to buttons using the `Link` button style.
|
||||||
* Only three types of URL schemes are currently supported: `https://`, `http://` and `discord://`
|
* Only three types of URL schemes are currently supported: `https://`, `http://`, and `discord://`.
|
||||||
* @param url - The URL to open when this button is clicked
|
* @param url - The URL to use
|
||||||
*/
|
*/
|
||||||
public setURL(url: string) {
|
public setURL(url: string) {
|
||||||
(this.data as APIButtonComponentWithURL).url = urlValidator.parse(url);
|
(this.data as APIButtonComponentWithURL).url = urlValidator.parse(url);
|
||||||
@@ -77,11 +77,11 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the custom id for this button
|
* Sets the custom id for this button.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method is only applicable to buttons that are not using the `Link` button style.
|
* This method is only applicable to buttons that are not using the `Link` button style.
|
||||||
* @param customId - The custom id to use for this button
|
* @param customId - The custom id to use
|
||||||
*/
|
*/
|
||||||
public setCustomId(customId: string) {
|
public setCustomId(customId: string) {
|
||||||
(this.data as APIButtonComponentWithCustomId).custom_id = customIdValidator.parse(customId);
|
(this.data as APIButtonComponentWithCustomId).custom_id = customIdValidator.parse(customId);
|
||||||
@@ -89,9 +89,9 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the emoji to display on this button
|
* Sets the emoji to display on this button.
|
||||||
*
|
*
|
||||||
* @param emoji - The emoji to display on this button
|
* @param emoji - The emoji to use
|
||||||
*/
|
*/
|
||||||
public setEmoji(emoji: APIMessageComponentEmoji) {
|
public setEmoji(emoji: APIMessageComponentEmoji) {
|
||||||
this.data.emoji = emojiValidator.parse(emoji);
|
this.data.emoji = emojiValidator.parse(emoji);
|
||||||
@@ -99,7 +99,7 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this button is disabled
|
* Sets whether this button is disabled.
|
||||||
*
|
*
|
||||||
* @param disabled - Whether to disable this button
|
* @param disabled - Whether to disable this button
|
||||||
*/
|
*/
|
||||||
@@ -109,9 +109,9 @@ export class ButtonBuilder extends ComponentBuilder<APIButtonComponent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the label for this button
|
* Sets the label for this button.
|
||||||
*
|
*
|
||||||
* @param label - The label to display on this button
|
* @param label - The label to use
|
||||||
*/
|
*/
|
||||||
public setLabel(label: string) {
|
public setLabel(label: string) {
|
||||||
this.data.label = buttonLabelValidator.parse(label);
|
this.data.label = buttonLabelValidator.parse(label);
|
||||||
|
|||||||
@@ -2,13 +2,18 @@ import type { APISelectMenuComponent } from 'discord-api-types/v10';
|
|||||||
import { customIdValidator, disabledValidator, minMaxValidator, placeholderValidator } from '../Assertions.js';
|
import { customIdValidator, disabledValidator, minMaxValidator, placeholderValidator } from '../Assertions.js';
|
||||||
import { ComponentBuilder } from '../Component.js';
|
import { ComponentBuilder } from '../Component.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base select menu builder that contains common symbols for select menu builders.
|
||||||
|
*
|
||||||
|
* @typeParam SelectMenuType - The type of select menu this would be instantiated for.
|
||||||
|
*/
|
||||||
export class BaseSelectMenuBuilder<
|
export class BaseSelectMenuBuilder<
|
||||||
SelectMenuType extends APISelectMenuComponent,
|
SelectMenuType extends APISelectMenuComponent,
|
||||||
> extends ComponentBuilder<SelectMenuType> {
|
> extends ComponentBuilder<SelectMenuType> {
|
||||||
/**
|
/**
|
||||||
* Sets the placeholder for this select menu
|
* Sets the placeholder for this select menu.
|
||||||
*
|
*
|
||||||
* @param placeholder - The placeholder to use for this select menu
|
* @param placeholder - The placeholder to use
|
||||||
*/
|
*/
|
||||||
public setPlaceholder(placeholder: string) {
|
public setPlaceholder(placeholder: string) {
|
||||||
this.data.placeholder = placeholderValidator.parse(placeholder);
|
this.data.placeholder = placeholderValidator.parse(placeholder);
|
||||||
@@ -16,7 +21,7 @@ export class BaseSelectMenuBuilder<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the minimum values that must be selected in the select menu
|
* Sets the minimum values that must be selected in the select menu.
|
||||||
*
|
*
|
||||||
* @param minValues - The minimum values that must be selected
|
* @param minValues - The minimum values that must be selected
|
||||||
*/
|
*/
|
||||||
@@ -26,7 +31,7 @@ export class BaseSelectMenuBuilder<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum values that must be selected in the select menu
|
* Sets the maximum values that must be selected in the select menu.
|
||||||
*
|
*
|
||||||
* @param maxValues - The maximum values that must be selected
|
* @param maxValues - The maximum values that must be selected
|
||||||
*/
|
*/
|
||||||
@@ -36,9 +41,9 @@ export class BaseSelectMenuBuilder<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the custom id for this select menu
|
* Sets the custom id for this select menu.
|
||||||
*
|
*
|
||||||
* @param customId - The custom id to use for this select menu
|
* @param customId - The custom id to use
|
||||||
*/
|
*/
|
||||||
public setCustomId(customId: string) {
|
public setCustomId(customId: string) {
|
||||||
this.data.custom_id = customIdValidator.parse(customId);
|
this.data.custom_id = customIdValidator.parse(customId);
|
||||||
@@ -46,7 +51,7 @@ export class BaseSelectMenuBuilder<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this select menu is disabled
|
* Sets whether this select menu is disabled.
|
||||||
*
|
*
|
||||||
* @param disabled - Whether this select menu is disabled
|
* @param disabled - Whether this select menu is disabled
|
||||||
*/
|
*/
|
||||||
@@ -55,6 +60,9 @@ export class BaseSelectMenuBuilder<
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ComponentBuilder.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): SelectMenuType {
|
public toJSON(): SelectMenuType {
|
||||||
customIdValidator.parse(this.data.custom_id);
|
customIdValidator.parse(this.data.custom_id);
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -4,13 +4,16 @@ import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
|||||||
import { channelTypesValidator, customIdValidator } from '../Assertions.js';
|
import { channelTypesValidator, customIdValidator } from '../Assertions.js';
|
||||||
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for channel select menus.
|
||||||
|
*/
|
||||||
export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder<APIChannelSelectComponent> {
|
export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder<APIChannelSelectComponent> {
|
||||||
/**
|
/**
|
||||||
* Creates a new select menu from API data
|
* Creates a new select menu from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this select menu with
|
* @param data - The API data to create this select menu with
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu from an API data object
|
* Creating a select menu from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new ChannelSelectMenuBuilder({
|
* const selectMenu = new ChannelSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
@@ -19,39 +22,45 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder<APIChannelSe
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu using setters and API data
|
* Creating a select menu using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new ChannelSelectMenuBuilder({
|
* const selectMenu = new ChannelSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
* })
|
* })
|
||||||
* .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
|
* .addChannelTypes(ChannelType.GuildText, ChannelType.GuildAnnouncement)
|
||||||
* .setMinValues(2)
|
* .setMinValues(2);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public constructor(data?: Partial<APIChannelSelectComponent>) {
|
public constructor(data?: Partial<APIChannelSelectComponent>) {
|
||||||
super({ ...data, type: ComponentType.ChannelSelect });
|
super({ ...data, type: ComponentType.ChannelSelect });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds channel types to this select menu.
|
||||||
|
*
|
||||||
|
* @param types - The channel types to use
|
||||||
|
*/
|
||||||
public addChannelTypes(...types: RestOrArray<ChannelType>) {
|
public addChannelTypes(...types: RestOrArray<ChannelType>) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
const normalizedTypes = normalizeArray(types);
|
||||||
types = normalizeArray(types);
|
|
||||||
|
|
||||||
this.data.channel_types ??= [];
|
this.data.channel_types ??= [];
|
||||||
this.data.channel_types.push(...channelTypesValidator.parse(types));
|
this.data.channel_types.push(...channelTypesValidator.parse(normalizedTypes));
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public setChannelTypes(...types: RestOrArray<ChannelType>) {
|
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
types = normalizeArray(types);
|
|
||||||
|
|
||||||
this.data.channel_types ??= [];
|
|
||||||
this.data.channel_types.splice(0, this.data.channel_types.length, ...channelTypesValidator.parse(types));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc ComponentBuilder.toJSON}
|
* Sets channel types for this select menu.
|
||||||
|
*
|
||||||
|
* @param types - The channel types to use
|
||||||
|
*/
|
||||||
|
public setChannelTypes(...types: RestOrArray<ChannelType>) {
|
||||||
|
const normalizedTypes = normalizeArray(types);
|
||||||
|
this.data.channel_types ??= [];
|
||||||
|
this.data.channel_types.splice(0, this.data.channel_types.length, ...channelTypesValidator.parse(normalizedTypes));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc BaseSelectMenuBuilder.toJSON}
|
||||||
*/
|
*/
|
||||||
public override toJSON(): APIChannelSelectComponent {
|
public override toJSON(): APIChannelSelectComponent {
|
||||||
customIdValidator.parse(this.data.custom_id);
|
customIdValidator.parse(this.data.custom_id);
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import type { APIMentionableSelectComponent } from 'discord-api-types/v10';
|
|||||||
import { ComponentType } from 'discord-api-types/v10';
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for mentionable select menus.
|
||||||
|
*/
|
||||||
export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder<APIMentionableSelectComponent> {
|
export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder<APIMentionableSelectComponent> {
|
||||||
/**
|
/**
|
||||||
* Creates a new select menu from API data
|
* Creates a new select menu from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this select menu with
|
* @param data - The API data to create this select menu with
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu from an API data object
|
* Creating a select menu from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new MentionableSelectMenuBuilder({
|
* const selectMenu = new MentionableSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
@@ -17,12 +20,12 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder<APIMenti
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu using setters and API data
|
* Creating a select menu using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new MentionableSelectMenuBuilder({
|
* const selectMenu = new MentionableSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
* })
|
* })
|
||||||
* .setMinValues(1)
|
* .setMinValues(1);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public constructor(data?: Partial<APIMentionableSelectComponent>) {
|
public constructor(data?: Partial<APIMentionableSelectComponent>) {
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import type { APIRoleSelectComponent } from 'discord-api-types/v10';
|
|||||||
import { ComponentType } from 'discord-api-types/v10';
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for role select menus.
|
||||||
|
*/
|
||||||
export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder<APIRoleSelectComponent> {
|
export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder<APIRoleSelectComponent> {
|
||||||
/**
|
/**
|
||||||
* Creates a new select menu from API data
|
* Creates a new select menu from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this select menu with
|
* @param data - The API data to create this select menu with
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu from an API data object
|
* Creating a select menu from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new RoleSelectMenuBuilder({
|
* const selectMenu = new RoleSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
@@ -17,12 +20,12 @@ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder<APIRoleSelectCo
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu using setters and API data
|
* Creating a select menu using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new RoleSelectMenuBuilder({
|
* const selectMenu = new RoleSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
* })
|
* })
|
||||||
* .setMinValues(1)
|
* .setMinValues(1);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public constructor(data?: Partial<APIRoleSelectComponent>) {
|
public constructor(data?: Partial<APIRoleSelectComponent>) {
|
||||||
|
|||||||
@@ -6,20 +6,20 @@ import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
|||||||
import { StringSelectMenuOptionBuilder } from './StringSelectMenuOption.js';
|
import { StringSelectMenuOptionBuilder } from './StringSelectMenuOption.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a string select menu component
|
* A builder that creates API-compatible JSON data for string select menus.
|
||||||
*/
|
*/
|
||||||
export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSelectComponent> {
|
export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSelectComponent> {
|
||||||
/**
|
/**
|
||||||
* The options within this select menu
|
* The options within this select menu.
|
||||||
*/
|
*/
|
||||||
public readonly options: StringSelectMenuOptionBuilder[];
|
public readonly options: StringSelectMenuOptionBuilder[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new select menu from API data
|
* Creates a new select menu from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this select menu with
|
* @param data - The API data to create this select menu with
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu from an API data object
|
* Creating a select menu from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new StringSelectMenuBuilder({
|
* const selectMenu = new StringSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
@@ -33,7 +33,7 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu using setters and API data
|
* Creating a select menu using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new StringSelectMenuBuilder({
|
* const selectMenu = new StringSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
@@ -52,55 +52,52 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds options to this select menu
|
* Adds options to this select menu.
|
||||||
*
|
*
|
||||||
* @param options - The options to add to this select menu
|
* @param options - The options to add
|
||||||
* @returns
|
|
||||||
*/
|
*/
|
||||||
public addOptions(...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>) {
|
public addOptions(...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
const normalizedOptions = normalizeArray(options);
|
||||||
options = normalizeArray(options);
|
optionsLengthValidator.parse(this.options.length + normalizedOptions.length);
|
||||||
optionsLengthValidator.parse(this.options.length + options.length);
|
|
||||||
this.options.push(
|
this.options.push(
|
||||||
...options.map((option) =>
|
...normalizedOptions.map((normalizedOption) =>
|
||||||
option instanceof StringSelectMenuOptionBuilder
|
normalizedOption instanceof StringSelectMenuOptionBuilder
|
||||||
? option
|
? normalizedOption
|
||||||
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
|
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(normalizedOption)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the options on this select menu
|
* Sets the options for this select menu.
|
||||||
*
|
*
|
||||||
* @param options - The options to set on this select menu
|
* @param options - The options to set
|
||||||
*/
|
*/
|
||||||
public setOptions(...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>) {
|
public setOptions(...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>) {
|
||||||
return this.spliceOptions(0, this.options.length, ...options);
|
return this.spliceOptions(0, this.options.length, ...options);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes, replaces, or inserts options in the string select menu.
|
* Removes, replaces, or inserts options for this select menu.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method behaves similarly
|
* This method behaves similarly
|
||||||
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | Array.prototype.splice}.
|
* to {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | Array.prototype.splice()}.
|
||||||
*
|
* It's useful for modifying and adjusting the order of existing options.
|
||||||
* It's useful for modifying and adjusting order of the already-existing options of a string select menu.
|
|
||||||
* @example
|
* @example
|
||||||
* Remove the first option
|
* Remove the first option:
|
||||||
* ```ts
|
* ```ts
|
||||||
* selectMenu.spliceOptions(0, 1);
|
* selectMenu.spliceOptions(0, 1);
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Remove the first n option
|
* Remove the first n option:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const n = 4
|
* const n = 4;
|
||||||
* selectMenu.spliceOptions(0, n);
|
* selectMenu.spliceOptions(0, n);
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Remove the last option
|
* Remove the last option:
|
||||||
* ```ts
|
* ```ts
|
||||||
* selectMenu.spliceOptions(-1, 1);
|
* selectMenu.spliceOptions(-1, 1);
|
||||||
* ```
|
* ```
|
||||||
@@ -113,30 +110,27 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
|
|||||||
deleteCount: number,
|
deleteCount: number,
|
||||||
...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>
|
...options: RestOrArray<APISelectMenuOption | StringSelectMenuOptionBuilder>
|
||||||
) {
|
) {
|
||||||
// eslint-disable-next-line no-param-reassign
|
const normalizedOptions = normalizeArray(options);
|
||||||
options = normalizeArray(options);
|
|
||||||
|
|
||||||
const clone = [...this.options];
|
const clone = [...this.options];
|
||||||
|
|
||||||
clone.splice(
|
clone.splice(
|
||||||
index,
|
index,
|
||||||
deleteCount,
|
deleteCount,
|
||||||
...options.map((option) =>
|
...normalizedOptions.map((normalizedOption) =>
|
||||||
option instanceof StringSelectMenuOptionBuilder
|
normalizedOption instanceof StringSelectMenuOptionBuilder
|
||||||
? option
|
? normalizedOption
|
||||||
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(option)),
|
: new StringSelectMenuOptionBuilder(jsonOptionValidator.parse(normalizedOption)),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
optionsLengthValidator.parse(clone.length);
|
optionsLengthValidator.parse(clone.length);
|
||||||
|
|
||||||
this.options.splice(0, this.options.length, ...clone);
|
this.options.splice(0, this.options.length, ...clone);
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc ComponentBuilder.toJSON}
|
* {@inheritDoc BaseSelectMenuBuilder.toJSON}
|
||||||
*/
|
*/
|
||||||
public override toJSON(): APIStringSelectComponent {
|
public override toJSON(): APIStringSelectComponent {
|
||||||
validateRequiredSelectMenuParameters(this.options, this.data.custom_id);
|
validateRequiredSelectMenuParameters(this.options, this.data.custom_id);
|
||||||
|
|||||||
@@ -8,15 +8,15 @@ import {
|
|||||||
} from '../Assertions.js';
|
} from '../Assertions.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an option within a string select menu component
|
* A builder that creates API-compatible JSON data for string select menu options.
|
||||||
*/
|
*/
|
||||||
export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOption> {
|
export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMenuOption> {
|
||||||
/**
|
/**
|
||||||
* Creates a new string select menu option from API data
|
* Creates a new string select menu option from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this string select menu option with
|
* @param data - The API data to create this string select menu option with
|
||||||
* @example
|
* @example
|
||||||
* Creating a string select menu option from an API data object
|
* Creating a string select menu option from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenuOption = new SelectMenuOptionBuilder({
|
* const selectMenuOption = new SelectMenuOptionBuilder({
|
||||||
* label: 'catchy label',
|
* label: 'catchy label',
|
||||||
@@ -24,21 +24,21 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a string select menu option using setters and API data
|
* Creating a string select menu option using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenuOption = new SelectMenuOptionBuilder({
|
* const selectMenuOption = new SelectMenuOptionBuilder({
|
||||||
* default: true,
|
* default: true,
|
||||||
* value: '1',
|
* value: '1',
|
||||||
* })
|
* })
|
||||||
* .setLabel('woah')
|
* .setLabel('woah');
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public constructor(public data: Partial<APISelectMenuOption> = {}) {}
|
public constructor(public data: Partial<APISelectMenuOption> = {}) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the label of this option
|
* Sets the label for this option.
|
||||||
*
|
*
|
||||||
* @param label - The label to show on this option
|
* @param label - The label to use
|
||||||
*/
|
*/
|
||||||
public setLabel(label: string) {
|
public setLabel(label: string) {
|
||||||
this.data.label = labelValueDescriptionValidator.parse(label);
|
this.data.label = labelValueDescriptionValidator.parse(label);
|
||||||
@@ -46,9 +46,9 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of this option
|
* Sets the value for this option.
|
||||||
*
|
*
|
||||||
* @param value - The value of this option
|
* @param value - The value to use
|
||||||
*/
|
*/
|
||||||
public setValue(value: string) {
|
public setValue(value: string) {
|
||||||
this.data.value = labelValueDescriptionValidator.parse(value);
|
this.data.value = labelValueDescriptionValidator.parse(value);
|
||||||
@@ -56,9 +56,9 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the description of this option
|
* Sets the description for this option.
|
||||||
*
|
*
|
||||||
* @param description - The description of this option
|
* @param description - The description to use
|
||||||
*/
|
*/
|
||||||
public setDescription(description: string) {
|
public setDescription(description: string) {
|
||||||
this.data.description = labelValueDescriptionValidator.parse(description);
|
this.data.description = labelValueDescriptionValidator.parse(description);
|
||||||
@@ -66,7 +66,7 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this option is selected by default
|
* Sets whether this option is selected by default.
|
||||||
*
|
*
|
||||||
* @param isDefault - Whether this option is selected by default
|
* @param isDefault - Whether this option is selected by default
|
||||||
*/
|
*/
|
||||||
@@ -76,9 +76,9 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the emoji to display on this option
|
* Sets the emoji to display for this option.
|
||||||
*
|
*
|
||||||
* @param emoji - The emoji to display on this option
|
* @param emoji - The emoji to use
|
||||||
*/
|
*/
|
||||||
public setEmoji(emoji: APIMessageComponentEmoji) {
|
public setEmoji(emoji: APIMessageComponentEmoji) {
|
||||||
this.data.emoji = emojiValidator.parse(emoji);
|
this.data.emoji = emojiValidator.parse(emoji);
|
||||||
@@ -86,7 +86,7 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc ComponentBuilder.toJSON}
|
* {@inheritDoc BaseSelectMenuBuilder.toJSON}
|
||||||
*/
|
*/
|
||||||
public toJSON(): APISelectMenuOption {
|
public toJSON(): APISelectMenuOption {
|
||||||
validateRequiredSelectMenuOptionParameters(this.data.label, this.data.value);
|
validateRequiredSelectMenuOptionParameters(this.data.label, this.data.value);
|
||||||
|
|||||||
@@ -2,13 +2,16 @@ import type { APIUserSelectComponent } from 'discord-api-types/v10';
|
|||||||
import { ComponentType } from 'discord-api-types/v10';
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
import { BaseSelectMenuBuilder } from './BaseSelectMenu.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for user select menus.
|
||||||
|
*/
|
||||||
export class UserSelectMenuBuilder extends BaseSelectMenuBuilder<APIUserSelectComponent> {
|
export class UserSelectMenuBuilder extends BaseSelectMenuBuilder<APIUserSelectComponent> {
|
||||||
/**
|
/**
|
||||||
* Creates a new select menu from API data
|
* Creates a new select menu from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this select menu with
|
* @param data - The API data to create this select menu with
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu from an API data object
|
* Creating a select menu from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new UserSelectMenuBuilder({
|
* const selectMenu = new UserSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
@@ -17,12 +20,12 @@ export class UserSelectMenuBuilder extends BaseSelectMenuBuilder<APIUserSelectCo
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu using setters and API data
|
* Creating a select menu using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const selectMenu = new UserSelectMenuBuilder({
|
* const selectMenu = new UserSelectMenuBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
* })
|
* })
|
||||||
* .setMinValues(1)
|
* .setMinValues(1);
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
public constructor(data?: Partial<APIUserSelectComponent>) {
|
public constructor(data?: Partial<APIUserSelectComponent>) {
|
||||||
|
|||||||
@@ -14,16 +14,19 @@ import {
|
|||||||
textInputStyleValidator,
|
textInputStyleValidator,
|
||||||
} from './Assertions.js';
|
} from './Assertions.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for text inputs.
|
||||||
|
*/
|
||||||
export class TextInputBuilder
|
export class TextInputBuilder
|
||||||
extends ComponentBuilder<APITextInputComponent>
|
extends ComponentBuilder<APITextInputComponent>
|
||||||
implements Equatable<APITextInputComponent | JSONEncodable<APITextInputComponent>>
|
implements Equatable<APITextInputComponent | JSONEncodable<APITextInputComponent>>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Creates a new text input from API data
|
* Creates a new text input from API data.
|
||||||
*
|
*
|
||||||
* @param data - The API data to create this text input with
|
* @param data - The API data to create this text input with
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu option from an API data object
|
* Creating a select menu option from an API data object:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const textInput = new TextInputBuilder({
|
* const textInput = new TextInputBuilder({
|
||||||
* custom_id: 'a cool select menu',
|
* custom_id: 'a cool select menu',
|
||||||
@@ -32,7 +35,7 @@ export class TextInputBuilder
|
|||||||
* });
|
* });
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Creating a select menu option using setters and API data
|
* Creating a select menu option using setters and API data:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const textInput = new TextInputBuilder({
|
* const textInput = new TextInputBuilder({
|
||||||
* label: 'Type something else',
|
* label: 'Type something else',
|
||||||
@@ -46,9 +49,9 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the custom id for this text input
|
* Sets the custom id for this text input.
|
||||||
*
|
*
|
||||||
* @param customId - The custom id of this text input
|
* @param customId - The custom id to use
|
||||||
*/
|
*/
|
||||||
public setCustomId(customId: string) {
|
public setCustomId(customId: string) {
|
||||||
this.data.custom_id = customIdValidator.parse(customId);
|
this.data.custom_id = customIdValidator.parse(customId);
|
||||||
@@ -56,9 +59,9 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the label for this text input
|
* Sets the label for this text input.
|
||||||
*
|
*
|
||||||
* @param label - The label for this text input
|
* @param label - The label to use
|
||||||
*/
|
*/
|
||||||
public setLabel(label: string) {
|
public setLabel(label: string) {
|
||||||
this.data.label = labelValidator.parse(label);
|
this.data.label = labelValidator.parse(label);
|
||||||
@@ -66,9 +69,9 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the style for this text input
|
* Sets the style for this text input.
|
||||||
*
|
*
|
||||||
* @param style - The style for this text input
|
* @param style - The style to use
|
||||||
*/
|
*/
|
||||||
public setStyle(style: TextInputStyle) {
|
public setStyle(style: TextInputStyle) {
|
||||||
this.data.style = textInputStyleValidator.parse(style);
|
this.data.style = textInputStyleValidator.parse(style);
|
||||||
@@ -76,7 +79,7 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the minimum length of text for this text input
|
* Sets the minimum length of text for this text input.
|
||||||
*
|
*
|
||||||
* @param minLength - The minimum length of text for this text input
|
* @param minLength - The minimum length of text for this text input
|
||||||
*/
|
*/
|
||||||
@@ -86,7 +89,7 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum length of text for this text input
|
* Sets the maximum length of text for this text input.
|
||||||
*
|
*
|
||||||
* @param maxLength - The maximum length of text for this text input
|
* @param maxLength - The maximum length of text for this text input
|
||||||
*/
|
*/
|
||||||
@@ -96,9 +99,9 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the placeholder of this text input
|
* Sets the placeholder for this text input.
|
||||||
*
|
*
|
||||||
* @param placeholder - The placeholder of this text input
|
* @param placeholder - The placeholder to use
|
||||||
*/
|
*/
|
||||||
public setPlaceholder(placeholder: string) {
|
public setPlaceholder(placeholder: string) {
|
||||||
this.data.placeholder = placeholderValidator.parse(placeholder);
|
this.data.placeholder = placeholderValidator.parse(placeholder);
|
||||||
@@ -106,9 +109,9 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of this text input
|
* Sets the value for this text input.
|
||||||
*
|
*
|
||||||
* @param value - The value for this text input
|
* @param value - The value to use
|
||||||
*/
|
*/
|
||||||
public setValue(value: string) {
|
public setValue(value: string) {
|
||||||
this.data.value = valueValidator.parse(value);
|
this.data.value = valueValidator.parse(value);
|
||||||
@@ -116,7 +119,7 @@ export class TextInputBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this text input is required
|
* Sets whether this text input is required.
|
||||||
*
|
*
|
||||||
* @param required - Whether this text input is required
|
* @param required - Whether this text input is required
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -62,8 +62,9 @@ export * from './util/validation.js';
|
|||||||
export * from '@discordjs/util';
|
export * from '@discordjs/util';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link https://github.com/discordjs/discord.js/blob/main/packages/builders/#readme | @discordjs/builders} version
|
* The {@link https://github.com/discordjs/discord.js/blob/main/packages/builders#readme | @discordjs/builders} version
|
||||||
* that you are currently using.
|
* that you are currently using.
|
||||||
|
*
|
||||||
|
* @privateRemarks This needs to explicitly be `string` so it is not typed as a "const string" that gets injected by esbuild.
|
||||||
*/
|
*/
|
||||||
// This needs to explicitly be `string` so it is not typed as a "const string" that gets injected by esbuild
|
|
||||||
export const version = '[VI]{{inject}}[/VI]' as string;
|
export const version = '[VI]{{inject}}[/VI]' as string;
|
||||||
|
|||||||
@@ -15,45 +15,54 @@ import {
|
|||||||
validateDMPermission,
|
validateDMPermission,
|
||||||
} from './Assertions.js';
|
} from './Assertions.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type a context menu command can be.
|
||||||
|
*/
|
||||||
|
export type ContextMenuCommandType = ApplicationCommandType.Message | ApplicationCommandType.User;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for context menu commands.
|
||||||
|
*/
|
||||||
export class ContextMenuCommandBuilder {
|
export class ContextMenuCommandBuilder {
|
||||||
/**
|
/**
|
||||||
* The name of this context menu command
|
* The name of this command.
|
||||||
*/
|
*/
|
||||||
public readonly name: string = undefined!;
|
public readonly name: string = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The localized names for this command
|
* The name localizations of this command.
|
||||||
*/
|
*/
|
||||||
public readonly name_localizations?: LocalizationMap;
|
public readonly name_localizations?: LocalizationMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of this context menu command
|
* The type of this command.
|
||||||
*/
|
*/
|
||||||
public readonly type: ContextMenuCommandType = undefined!;
|
public readonly type: ContextMenuCommandType = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the command is enabled by default when the app is added to a guild
|
* Whether this command is enabled by default when the application is added to a guild.
|
||||||
*
|
*
|
||||||
* @deprecated This property is deprecated and will be removed in the future.
|
* @deprecated Use {@link ContextMenuCommandBuilder.setDefaultMemberPermissions} or {@link ContextMenuCommandBuilder.setDMPermission} instead.
|
||||||
* You should use {@link ContextMenuCommandBuilder.setDefaultMemberPermissions} or {@link ContextMenuCommandBuilder.setDMPermission} instead.
|
|
||||||
*/
|
*/
|
||||||
public readonly default_permission: boolean | undefined = undefined;
|
public readonly default_permission: boolean | undefined = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of permissions represented as a bit set for the command
|
* The set of permissions represented as a bit set for the command.
|
||||||
*/
|
*/
|
||||||
public readonly default_member_permissions: Permissions | null | undefined = undefined;
|
public readonly default_member_permissions: Permissions | null | undefined = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the command is available in DMs with the application, only for globally-scoped commands.
|
* Indicates whether the command is available in direct messages with the application.
|
||||||
* By default, commands are visible.
|
*
|
||||||
|
* @remarks
|
||||||
|
* By default, commands are visible. This property is only for global commands.
|
||||||
*/
|
*/
|
||||||
public readonly dm_permission: boolean | undefined = undefined;
|
public readonly dm_permission: boolean | undefined = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name
|
* Sets the name of this command.
|
||||||
*
|
*
|
||||||
* @param name - The name
|
* @param name - The name to use
|
||||||
*/
|
*/
|
||||||
public setName(name: string) {
|
public setName(name: string) {
|
||||||
// Assert the name matches the conditions
|
// Assert the name matches the conditions
|
||||||
@@ -65,9 +74,9 @@ export class ContextMenuCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the type
|
* Sets the type of this command.
|
||||||
*
|
*
|
||||||
* @param type - The type
|
* @param type - The type to use
|
||||||
*/
|
*/
|
||||||
public setType(type: ContextMenuCommandType) {
|
public setType(type: ContextMenuCommandType) {
|
||||||
// Assert the type is valid
|
// Assert the type is valid
|
||||||
@@ -83,7 +92,7 @@ export class ContextMenuCommandBuilder {
|
|||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* If set to `false`, you will have to later `PUT` the permissions for this command.
|
* If set to `false`, you will have to later `PUT` the permissions for this command.
|
||||||
* @param value - Whether or not to enable this command by default
|
* @param value - Whether to enable this command by default
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
||||||
* @deprecated Use {@link ContextMenuCommandBuilder.setDefaultMemberPermissions} or {@link ContextMenuCommandBuilder.setDMPermission} instead.
|
* @deprecated Use {@link ContextMenuCommandBuilder.setDefaultMemberPermissions} or {@link ContextMenuCommandBuilder.setDMPermission} instead.
|
||||||
*/
|
*/
|
||||||
@@ -97,7 +106,7 @@ export class ContextMenuCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default permissions a member should have in order to run the command.
|
* Sets the default permissions a member should have in order to run this command.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* You can set this to `'0'` to disable the command by default.
|
* You can set this to `'0'` to disable the command by default.
|
||||||
@@ -114,10 +123,11 @@ export class ContextMenuCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets if the command is available in DMs with the application, only for globally-scoped commands.
|
* Sets if the command is available in direct messages with the application.
|
||||||
* By default, commands are visible.
|
|
||||||
*
|
*
|
||||||
* @param enabled - If the command should be enabled in DMs
|
* @remarks
|
||||||
|
* By default, commands are visible. This method is only for global commands.
|
||||||
|
* @param enabled - Whether the command should be enabled in direct messages
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
||||||
*/
|
*/
|
||||||
public setDMPermission(enabled: boolean | null | undefined) {
|
public setDMPermission(enabled: boolean | null | undefined) {
|
||||||
@@ -130,10 +140,10 @@ export class ContextMenuCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a name localization
|
* Sets a name localization for this command.
|
||||||
*
|
*
|
||||||
* @param locale - The locale to set a description for
|
* @param locale - The locale to set
|
||||||
* @param localizedName - The localized description for the given locale
|
* @param localizedName - The localized name for the given `locale`
|
||||||
*/
|
*/
|
||||||
public setNameLocalization(locale: LocaleString, localizedName: string | null) {
|
public setNameLocalization(locale: LocaleString, localizedName: string | null) {
|
||||||
if (!this.name_localizations) {
|
if (!this.name_localizations) {
|
||||||
@@ -154,9 +164,9 @@ export class ContextMenuCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name localizations
|
* Sets the name localizations for this command.
|
||||||
*
|
*
|
||||||
* @param localizedNames - The dictionary of localized descriptions to set
|
* @param localizedNames - The object of localized names to set
|
||||||
*/
|
*/
|
||||||
public setNameLocalizations(localizedNames: LocalizationMap | null) {
|
public setNameLocalizations(localizedNames: LocalizationMap | null) {
|
||||||
if (localizedNames === null) {
|
if (localizedNames === null) {
|
||||||
@@ -172,7 +182,7 @@ export class ContextMenuCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the final data that should be sent to Discord.
|
* Serializes this builder to API-compatible JSON data.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method runs validations on the data before serializing it.
|
* This method runs validations on the data before serializing it.
|
||||||
@@ -186,5 +196,3 @@ export class ContextMenuCommandBuilder {
|
|||||||
return { ...this };
|
return { ...this };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ContextMenuCommandType = ApplicationCommandType.Message | ApplicationCommandType.User;
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
/* eslint-disable jsdoc/check-param-names */
|
||||||
|
|
||||||
import type { JSONEncodable } from '@discordjs/util';
|
import type { JSONEncodable } from '@discordjs/util';
|
||||||
import type {
|
import type {
|
||||||
APIActionRowComponent,
|
APIActionRowComponent,
|
||||||
@@ -10,11 +12,25 @@ import { createComponentBuilder } from '../../components/Components.js';
|
|||||||
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
|
||||||
import { titleValidator, validateRequiredParameters } from './Assertions.js';
|
import { titleValidator, validateRequiredParameters } from './Assertions.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for modals.
|
||||||
|
*/
|
||||||
export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCallbackData> {
|
export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCallbackData> {
|
||||||
|
/**
|
||||||
|
* The API data associated with this modal.
|
||||||
|
*/
|
||||||
public readonly data: Partial<APIModalInteractionResponseCallbackData>;
|
public readonly data: Partial<APIModalInteractionResponseCallbackData>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The components within this modal.
|
||||||
|
*/
|
||||||
public readonly components: ActionRowBuilder<ModalActionRowComponentBuilder>[] = [];
|
public readonly components: ActionRowBuilder<ModalActionRowComponentBuilder>[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new modal from API data.
|
||||||
|
*
|
||||||
|
* @param data - The API data to create this modal with
|
||||||
|
*/
|
||||||
public constructor({ components, ...data }: Partial<APIModalInteractionResponseCallbackData> = {}) {
|
public constructor({ components, ...data }: Partial<APIModalInteractionResponseCallbackData> = {}) {
|
||||||
this.data = { ...data };
|
this.data = { ...data };
|
||||||
this.components = (components?.map((component) => createComponentBuilder(component)) ??
|
this.components = (components?.map((component) => createComponentBuilder(component)) ??
|
||||||
@@ -22,9 +38,9 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the title of the modal
|
* Sets the title of this modal.
|
||||||
*
|
*
|
||||||
* @param title - The title of the modal
|
* @param title - The title to use
|
||||||
*/
|
*/
|
||||||
public setTitle(title: string) {
|
public setTitle(title: string) {
|
||||||
this.data.title = titleValidator.parse(title);
|
this.data.title = titleValidator.parse(title);
|
||||||
@@ -32,9 +48,9 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the custom id of the modal
|
* Sets the custom id of this modal.
|
||||||
*
|
*
|
||||||
* @param customId - The custom id of this modal
|
* @param customId - The custom id to use
|
||||||
*/
|
*/
|
||||||
public setCustomId(customId: string) {
|
public setCustomId(customId: string) {
|
||||||
this.data.custom_id = customIdValidator.parse(customId);
|
this.data.custom_id = customIdValidator.parse(customId);
|
||||||
@@ -42,9 +58,9 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds components to this modal
|
* Adds components to this modal.
|
||||||
*
|
*
|
||||||
* @param components - The components to add to this modal
|
* @param components - The components to add
|
||||||
*/
|
*/
|
||||||
public addComponents(
|
public addComponents(
|
||||||
...components: RestOrArray<
|
...components: RestOrArray<
|
||||||
@@ -62,9 +78,9 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the components in this modal
|
* Sets components for this modal.
|
||||||
*
|
*
|
||||||
* @param components - The components to set this modal to
|
* @param components - The components to set
|
||||||
*/
|
*/
|
||||||
public setComponents(...components: RestOrArray<ActionRowBuilder<ModalActionRowComponentBuilder>>) {
|
public setComponents(...components: RestOrArray<ActionRowBuilder<ModalActionRowComponentBuilder>>) {
|
||||||
this.components.splice(0, this.components.length, ...normalizeArray(components));
|
this.components.splice(0, this.components.length, ...normalizeArray(components));
|
||||||
|
|||||||
@@ -19,76 +19,61 @@ import { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } fro
|
|||||||
import { SharedNameAndDescription } from './mixins/NameAndDescription.js';
|
import { SharedNameAndDescription } from './mixins/NameAndDescription.js';
|
||||||
import { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions.js';
|
import { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A builder that creates API-compatible JSON data for slash commands.
|
||||||
|
*/
|
||||||
@mix(SharedSlashCommandOptions, SharedNameAndDescription)
|
@mix(SharedSlashCommandOptions, SharedNameAndDescription)
|
||||||
export class SlashCommandBuilder {
|
export class SlashCommandBuilder {
|
||||||
/**
|
/**
|
||||||
* The name of this slash command
|
* The name of this command.
|
||||||
*/
|
*/
|
||||||
public readonly name: string = undefined!;
|
public readonly name: string = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The localized names for this command
|
* The name localizations of this command.
|
||||||
*/
|
*/
|
||||||
public readonly name_localizations?: LocalizationMap;
|
public readonly name_localizations?: LocalizationMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The description of this slash command
|
* The description of this command.
|
||||||
*/
|
*/
|
||||||
public readonly description: string = undefined!;
|
public readonly description: string = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The localized descriptions for this command
|
* The description localizations of this command.
|
||||||
*/
|
*/
|
||||||
public readonly description_localizations?: LocalizationMap;
|
public readonly description_localizations?: LocalizationMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The options of this slash command
|
* The options of this command.
|
||||||
*/
|
*/
|
||||||
public readonly options: ToAPIApplicationCommandOptions[] = [];
|
public readonly options: ToAPIApplicationCommandOptions[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether the command is enabled by default when the app is added to a guild
|
* Whether this command is enabled by default when the application is added to a guild.
|
||||||
*
|
*
|
||||||
* @deprecated This property is deprecated and will be removed in the future.
|
* @deprecated Use {@link ContextMenuCommandBuilder.setDefaultMemberPermissions} or {@link ContextMenuCommandBuilder.setDMPermission} instead.
|
||||||
* You should use {@link SlashCommandBuilder.setDefaultMemberPermissions} or {@link SlashCommandBuilder.setDMPermission} instead.
|
|
||||||
*/
|
*/
|
||||||
public readonly default_permission: boolean | undefined = undefined;
|
public readonly default_permission: boolean | undefined = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set of permissions represented as a bit set for the command
|
* The set of permissions represented as a bit set for the command.
|
||||||
*/
|
*/
|
||||||
public readonly default_member_permissions: Permissions | null | undefined = undefined;
|
public readonly default_member_permissions: Permissions | null | undefined = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates whether the command is available in DMs with the application, only for globally-scoped commands.
|
* Indicates whether the command is available in direct messages with the application.
|
||||||
* By default, commands are visible.
|
*
|
||||||
|
* @remarks
|
||||||
|
* By default, commands are visible. This property is only for global commands.
|
||||||
*/
|
*/
|
||||||
public readonly dm_permission: boolean | undefined = undefined;
|
public readonly dm_permission: boolean | undefined = undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this command is NSFW
|
* Whether this command is NSFW.
|
||||||
*/
|
*/
|
||||||
public readonly nsfw: boolean | undefined = undefined;
|
public readonly nsfw: boolean | undefined = undefined;
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the final data that should be sent to Discord.
|
|
||||||
*
|
|
||||||
* @remarks
|
|
||||||
* This method runs validations on the data before serializing it.
|
|
||||||
* As such, it may throw an error if the data is invalid.
|
|
||||||
*/
|
|
||||||
public toJSON(): RESTPostAPIChatInputApplicationCommandsJSONBody {
|
|
||||||
validateRequiredParameters(this.name, this.description, this.options);
|
|
||||||
|
|
||||||
validateLocalizationMap(this.name_localizations);
|
|
||||||
validateLocalizationMap(this.description_localizations);
|
|
||||||
|
|
||||||
return {
|
|
||||||
...this,
|
|
||||||
options: this.options.map((option) => option.toJSON()),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether the command is enabled by default when the application is added to a guild.
|
* Sets whether the command is enabled by default when the application is added to a guild.
|
||||||
*
|
*
|
||||||
@@ -125,10 +110,11 @@ export class SlashCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets if the command is available in DMs with the application, only for globally-scoped commands.
|
* Sets if the command is available in direct messages with the application.
|
||||||
* By default, commands are visible.
|
|
||||||
*
|
*
|
||||||
* @param enabled - If the command should be enabled in DMs
|
* @remarks
|
||||||
|
* By default, commands are visible. This method is only for global commands.
|
||||||
|
* @param enabled - Whether the command should be enabled in direct messages
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
* @see {@link https://discord.com/developers/docs/interactions/application-commands#permissions}
|
||||||
*/
|
*/
|
||||||
public setDMPermission(enabled: boolean | null | undefined) {
|
public setDMPermission(enabled: boolean | null | undefined) {
|
||||||
@@ -141,7 +127,7 @@ export class SlashCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether this command is NSFW
|
* Sets whether this command is NSFW.
|
||||||
*
|
*
|
||||||
* @param nsfw - Whether this command is NSFW
|
* @param nsfw - Whether this command is NSFW
|
||||||
*/
|
*/
|
||||||
@@ -153,9 +139,9 @@ export class SlashCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new subcommand group to this command
|
* Adds a new subcommand group to this command.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns a subcommand group builder, or an already built builder
|
* @param input - A function that returns a subcommand group builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addSubcommandGroup(
|
public addSubcommandGroup(
|
||||||
input:
|
input:
|
||||||
@@ -179,9 +165,9 @@ export class SlashCommandBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new subcommand to this command
|
* Adds a new subcommand to this command.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns a subcommand builder, or an already built builder
|
* @param input - A function that returns a subcommand builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addSubcommand(
|
public addSubcommand(
|
||||||
input:
|
input:
|
||||||
@@ -203,18 +189,47 @@ export class SlashCommandBuilder {
|
|||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes this builder to API-compatible JSON data.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This method runs validations on the data before serializing it.
|
||||||
|
* As such, it may throw an error if the data is invalid.
|
||||||
|
*/
|
||||||
|
public toJSON(): RESTPostAPIChatInputApplicationCommandsJSONBody {
|
||||||
|
validateRequiredParameters(this.name, this.description, this.options);
|
||||||
|
|
||||||
|
validateLocalizationMap(this.name_localizations);
|
||||||
|
validateLocalizationMap(this.description_localizations);
|
||||||
|
|
||||||
|
return {
|
||||||
|
...this,
|
||||||
|
options: this.options.map((option) => option.toJSON()),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SlashCommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions {}
|
export interface SlashCommandBuilder extends SharedNameAndDescription, SharedSlashCommandOptions {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface specifically for slash command subcommands.
|
||||||
|
*/
|
||||||
export interface SlashCommandSubcommandsOnlyBuilder
|
export interface SlashCommandSubcommandsOnlyBuilder
|
||||||
extends Omit<SlashCommandBuilder, Exclude<keyof SharedSlashCommandOptions, 'options'>> {}
|
extends Omit<SlashCommandBuilder, Exclude<keyof SharedSlashCommandOptions, 'options'>> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface specifically for slash command options.
|
||||||
|
*/
|
||||||
export interface SlashCommandOptionsOnlyBuilder
|
export interface SlashCommandOptionsOnlyBuilder
|
||||||
extends SharedNameAndDescription,
|
extends SharedNameAndDescription,
|
||||||
SharedSlashCommandOptions,
|
SharedSlashCommandOptions,
|
||||||
Pick<SlashCommandBuilder, 'toJSON'> {}
|
Pick<SlashCommandBuilder, 'toJSON'> {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface that ensures the `toJSON()` call will return something
|
||||||
|
* that can be serialized into API-compatible data.
|
||||||
|
*/
|
||||||
export interface ToAPIApplicationCommandOptions {
|
export interface ToAPIApplicationCommandOptions {
|
||||||
toJSON(): APIApplicationCommandOption;
|
toJSON(): APIApplicationCommandOption;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,31 +11,31 @@ import { SharedNameAndDescription } from './mixins/NameAndDescription.js';
|
|||||||
import { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions.js';
|
import { SharedSlashCommandOptions } from './mixins/SharedSlashCommandOptions.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a folder for subcommands
|
* Represents a folder for subcommands.
|
||||||
*
|
*
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups}
|
* @see {@link https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups}
|
||||||
*/
|
*/
|
||||||
@mix(SharedNameAndDescription)
|
@mix(SharedNameAndDescription)
|
||||||
export class SlashCommandSubcommandGroupBuilder implements ToAPIApplicationCommandOptions {
|
export class SlashCommandSubcommandGroupBuilder implements ToAPIApplicationCommandOptions {
|
||||||
/**
|
/**
|
||||||
* The name of this subcommand group
|
* The name of this subcommand group.
|
||||||
*/
|
*/
|
||||||
public readonly name: string = undefined!;
|
public readonly name: string = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The description of this subcommand group
|
* The description of this subcommand group.
|
||||||
*/
|
*/
|
||||||
public readonly description: string = undefined!;
|
public readonly description: string = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The subcommands part of this subcommand group
|
* The subcommands within this subcommand group.
|
||||||
*/
|
*/
|
||||||
public readonly options: SlashCommandSubcommandBuilder[] = [];
|
public readonly options: SlashCommandSubcommandBuilder[] = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new subcommand to this group
|
* Adds a new subcommand to this group.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns a subcommand builder, or an already built builder
|
* @param input - A function that returns a subcommand builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addSubcommand(
|
public addSubcommand(
|
||||||
input:
|
input:
|
||||||
@@ -60,6 +60,13 @@ export class SlashCommandSubcommandGroupBuilder implements ToAPIApplicationComma
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes this builder to API-compatible JSON data.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This method runs validations on the data before serializing it.
|
||||||
|
* As such, it may throw an error if the data is invalid.
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandSubcommandGroupOption {
|
public toJSON(): APIApplicationCommandSubcommandGroupOption {
|
||||||
validateRequiredParameters(this.name, this.description, this.options);
|
validateRequiredParameters(this.name, this.description, this.options);
|
||||||
|
|
||||||
@@ -77,27 +84,34 @@ export class SlashCommandSubcommandGroupBuilder implements ToAPIApplicationComma
|
|||||||
export interface SlashCommandSubcommandGroupBuilder extends SharedNameAndDescription {}
|
export interface SlashCommandSubcommandGroupBuilder extends SharedNameAndDescription {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a subcommand
|
* A builder that creates API-compatible JSON data for slash command subcommands.
|
||||||
*
|
*
|
||||||
* @see {@link https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups}
|
* @see {@link https://discord.com/developers/docs/interactions/application-commands#subcommands-and-subcommand-groups}
|
||||||
*/
|
*/
|
||||||
@mix(SharedNameAndDescription, SharedSlashCommandOptions)
|
@mix(SharedNameAndDescription, SharedSlashCommandOptions)
|
||||||
export class SlashCommandSubcommandBuilder implements ToAPIApplicationCommandOptions {
|
export class SlashCommandSubcommandBuilder implements ToAPIApplicationCommandOptions {
|
||||||
/**
|
/**
|
||||||
* The name of this subcommand
|
* The name of this subcommand.
|
||||||
*/
|
*/
|
||||||
public readonly name: string = undefined!;
|
public readonly name: string = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The description of this subcommand
|
* The description of this subcommand.
|
||||||
*/
|
*/
|
||||||
public readonly description: string = undefined!;
|
public readonly description: string = undefined!;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The options of this subcommand
|
* The options within this subcommand.
|
||||||
*/
|
*/
|
||||||
public readonly options: ApplicationCommandOptionBase[] = [];
|
public readonly options: ApplicationCommandOptionBase[] = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes this builder to API-compatible JSON data.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This method runs validations on the data before serializing it.
|
||||||
|
* As such, it may throw an error if the data is invalid.
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandSubcommandOption {
|
public toJSON(): APIApplicationCommandSubcommandOption {
|
||||||
validateRequiredParameters(this.name, this.description, this.options);
|
validateRequiredParameters(this.name, this.description, this.options);
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* This mixin holds minimum and maximum symbols used for options.
|
||||||
|
*/
|
||||||
export abstract class ApplicationCommandNumericOptionMinMaxValueMixin {
|
export abstract class ApplicationCommandNumericOptionMinMaxValueMixin {
|
||||||
|
/**
|
||||||
|
* The maximum value of this option.
|
||||||
|
*/
|
||||||
public readonly max_value?: number;
|
public readonly max_value?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum value of this option.
|
||||||
|
*/
|
||||||
public readonly min_value?: number;
|
public readonly min_value?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum number value of this option
|
* Sets the maximum number value of this option.
|
||||||
*
|
*
|
||||||
* @param max - The maximum value this option can be
|
* @param max - The maximum value this option can be
|
||||||
*/
|
*/
|
||||||
public abstract setMaxValue(max: number): this;
|
public abstract setMaxValue(max: number): this;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the minimum number value of this option
|
* Sets the minimum number value of this option.
|
||||||
*
|
*
|
||||||
* @param min - The minimum value this option can be
|
* @param min - The minimum value this option can be
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -2,15 +2,26 @@ import type { APIApplicationCommandBasicOption, ApplicationCommandOptionType } f
|
|||||||
import { validateRequiredParameters, validateRequired, validateLocalizationMap } from '../Assertions.js';
|
import { validateRequiredParameters, validateRequired, validateLocalizationMap } from '../Assertions.js';
|
||||||
import { SharedNameAndDescription } from './NameAndDescription.js';
|
import { SharedNameAndDescription } from './NameAndDescription.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base application command option builder that contains common symbols for application command builders.
|
||||||
|
*/
|
||||||
export abstract class ApplicationCommandOptionBase extends SharedNameAndDescription {
|
export abstract class ApplicationCommandOptionBase extends SharedNameAndDescription {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public abstract readonly type: ApplicationCommandOptionType;
|
public abstract readonly type: ApplicationCommandOptionType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this option is required.
|
||||||
|
*
|
||||||
|
* @defaultValue `false`
|
||||||
|
*/
|
||||||
public readonly required: boolean = false;
|
public readonly required: boolean = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the option as required
|
* Sets whether this option is required.
|
||||||
*
|
*
|
||||||
* @param required - If this option should be required
|
* @param required - Whether this option should be required
|
||||||
*/
|
*/
|
||||||
public setRequired(required: boolean) {
|
public setRequired(required: boolean) {
|
||||||
// Assert that you actually passed a boolean
|
// Assert that you actually passed a boolean
|
||||||
@@ -21,8 +32,18 @@ export abstract class ApplicationCommandOptionBase extends SharedNameAndDescript
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serializes this builder to API-compatible JSON data.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This method runs validations on the data before serializing it.
|
||||||
|
* As such, it may throw an error if the data is invalid.
|
||||||
|
*/
|
||||||
public abstract toJSON(): APIApplicationCommandBasicOption;
|
public abstract toJSON(): APIApplicationCommandBasicOption;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method runs required validators on this builder.
|
||||||
|
*/
|
||||||
protected runRequiredValidations() {
|
protected runRequiredValidations() {
|
||||||
validateRequiredParameters(this.name, this.description, []);
|
validateRequiredParameters(this.name, this.description, []);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
import { s } from '@sapphire/shapeshift';
|
import { s } from '@sapphire/shapeshift';
|
||||||
import { ChannelType } from 'discord-api-types/v10';
|
import { ChannelType } from 'discord-api-types/v10';
|
||||||
|
|
||||||
// Only allow valid channel types to be used. (This can't be dynamic because const enums are erased at runtime)
|
/**
|
||||||
|
* The allowed channel types used for a channel option in a slash command builder.
|
||||||
|
*
|
||||||
|
* @privateRemarks This can't be dynamic because const enums are erased at runtime.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
const allowedChannelTypes = [
|
const allowedChannelTypes = [
|
||||||
ChannelType.GuildText,
|
ChannelType.GuildText,
|
||||||
ChannelType.GuildVoice,
|
ChannelType.GuildVoice,
|
||||||
@@ -14,17 +19,26 @@ const allowedChannelTypes = [
|
|||||||
ChannelType.GuildForum,
|
ChannelType.GuildForum,
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of allowed channel types used for a channel option.
|
||||||
|
*/
|
||||||
export type ApplicationCommandOptionAllowedChannelTypes = (typeof allowedChannelTypes)[number];
|
export type ApplicationCommandOptionAllowedChannelTypes = (typeof allowedChannelTypes)[number];
|
||||||
|
|
||||||
const channelTypesPredicate = s.array(s.union(...allowedChannelTypes.map((type) => s.literal(type))));
|
const channelTypesPredicate = s.array(s.union(...allowedChannelTypes.map((type) => s.literal(type))));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This mixin holds channel type symbols used for options.
|
||||||
|
*/
|
||||||
export class ApplicationCommandOptionChannelTypesMixin {
|
export class ApplicationCommandOptionChannelTypesMixin {
|
||||||
|
/**
|
||||||
|
* The channel types of this option.
|
||||||
|
*/
|
||||||
public readonly channel_types?: ApplicationCommandOptionAllowedChannelTypes[];
|
public readonly channel_types?: ApplicationCommandOptionAllowedChannelTypes[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds channel types to this option
|
* Adds channel types to this option.
|
||||||
*
|
*
|
||||||
* @param channelTypes - The channel types to add
|
* @param channelTypes - The channel types
|
||||||
*/
|
*/
|
||||||
public addChannelTypes(...channelTypes: ApplicationCommandOptionAllowedChannelTypes[]) {
|
public addChannelTypes(...channelTypes: ApplicationCommandOptionAllowedChannelTypes[]) {
|
||||||
if (this.channel_types === undefined) {
|
if (this.channel_types === undefined) {
|
||||||
|
|||||||
@@ -11,16 +11,29 @@ const choicesPredicate = s.object({
|
|||||||
}).array;
|
}).array;
|
||||||
const booleanPredicate = s.boolean;
|
const booleanPredicate = s.boolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This mixin holds choices and autocomplete symbols used for options.
|
||||||
|
*/
|
||||||
export class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends number | string> {
|
export class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends number | string> {
|
||||||
|
/**
|
||||||
|
* The choices of this option.
|
||||||
|
*/
|
||||||
public readonly choices?: APIApplicationCommandOptionChoice<T>[];
|
public readonly choices?: APIApplicationCommandOptionChoice<T>[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether this option utilizes autocomplete.
|
||||||
|
*/
|
||||||
public readonly autocomplete?: boolean;
|
public readonly autocomplete?: boolean;
|
||||||
|
|
||||||
// Since this is present and this is a mixin, this is needed
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*
|
||||||
|
* @privateRemarks Since this is present and this is a mixin, this is needed.
|
||||||
|
*/
|
||||||
public readonly type!: ApplicationCommandOptionType;
|
public readonly type!: ApplicationCommandOptionType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds multiple choices for this option
|
* Adds multiple choices to this option.
|
||||||
*
|
*
|
||||||
* @param choices - The choices to add
|
* @param choices - The choices to add
|
||||||
*/
|
*/
|
||||||
@@ -51,6 +64,11 @@ export class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends n
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets multiple choices for this option.
|
||||||
|
*
|
||||||
|
* @param choices - The choices to set
|
||||||
|
*/
|
||||||
public setChoices<Input extends APIApplicationCommandOptionChoice<T>[]>(...choices: Input): this {
|
public setChoices<Input extends APIApplicationCommandOptionChoice<T>[]>(...choices: Input): this {
|
||||||
if (choices.length > 0 && this.autocomplete) {
|
if (choices.length > 0 && this.autocomplete) {
|
||||||
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
|
throw new RangeError('Autocomplete and choices are mutually exclusive to each other.');
|
||||||
@@ -65,9 +83,9 @@ export class ApplicationCommandOptionWithChoicesAndAutocompleteMixin<T extends n
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marks the option as autocompletable
|
* Whether this option uses autocomplete.
|
||||||
*
|
*
|
||||||
* @param autocomplete - If this option should be autocompletable
|
* @param autocomplete - Whether this option should use autocomplete
|
||||||
*/
|
*/
|
||||||
public setAutocomplete(autocomplete: boolean): this {
|
public setAutocomplete(autocomplete: boolean): this {
|
||||||
// Assert that you actually passed a boolean
|
// Assert that you actually passed a boolean
|
||||||
|
|||||||
@@ -1,19 +1,34 @@
|
|||||||
import type { LocaleString, LocalizationMap } from 'discord-api-types/v10';
|
import type { LocaleString, LocalizationMap } from 'discord-api-types/v10';
|
||||||
import { validateDescription, validateLocale, validateName } from '../Assertions.js';
|
import { validateDescription, validateLocale, validateName } from '../Assertions.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This mixin holds name and description symbols for slash commands.
|
||||||
|
*/
|
||||||
export class SharedNameAndDescription {
|
export class SharedNameAndDescription {
|
||||||
|
/**
|
||||||
|
* The name of this command.
|
||||||
|
*/
|
||||||
public readonly name!: string;
|
public readonly name!: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name localizations of this command.
|
||||||
|
*/
|
||||||
public readonly name_localizations?: LocalizationMap;
|
public readonly name_localizations?: LocalizationMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description of this command.
|
||||||
|
*/
|
||||||
public readonly description!: string;
|
public readonly description!: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The description localizations of this command.
|
||||||
|
*/
|
||||||
public readonly description_localizations?: LocalizationMap;
|
public readonly description_localizations?: LocalizationMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name
|
* Sets the name of this command.
|
||||||
*
|
*
|
||||||
* @param name - The name
|
* @param name - The name to use
|
||||||
*/
|
*/
|
||||||
public setName(name: string): this {
|
public setName(name: string): this {
|
||||||
// Assert the name matches the conditions
|
// Assert the name matches the conditions
|
||||||
@@ -25,9 +40,9 @@ export class SharedNameAndDescription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the description
|
* Sets the description of this command.
|
||||||
*
|
*
|
||||||
* @param description - The description
|
* @param description - The description to use
|
||||||
*/
|
*/
|
||||||
public setDescription(description: string) {
|
public setDescription(description: string) {
|
||||||
// Assert the description matches the conditions
|
// Assert the description matches the conditions
|
||||||
@@ -39,10 +54,10 @@ export class SharedNameAndDescription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a name localization
|
* SSets a name localization for this command.
|
||||||
*
|
*
|
||||||
* @param locale - The locale to set a description for
|
* @param locale - The locale to set
|
||||||
* @param localizedName - The localized description for the given locale
|
* @param localizedName - The localized name for the given `locale`
|
||||||
*/
|
*/
|
||||||
public setNameLocalization(locale: LocaleString, localizedName: string | null) {
|
public setNameLocalization(locale: LocaleString, localizedName: string | null) {
|
||||||
if (!this.name_localizations) {
|
if (!this.name_localizations) {
|
||||||
@@ -63,9 +78,9 @@ export class SharedNameAndDescription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name localizations
|
* Sets the name localizations for this command.
|
||||||
*
|
*
|
||||||
* @param localizedNames - The dictionary of localized descriptions to set
|
* @param localizedNames - The object of localized names to set
|
||||||
*/
|
*/
|
||||||
public setNameLocalizations(localizedNames: LocalizationMap | null) {
|
public setNameLocalizations(localizedNames: LocalizationMap | null) {
|
||||||
if (localizedNames === null) {
|
if (localizedNames === null) {
|
||||||
@@ -83,9 +98,9 @@ export class SharedNameAndDescription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a description localization
|
* Sets a description localization for this command.
|
||||||
*
|
*
|
||||||
* @param locale - The locale to set a description for
|
* @param locale - The locale to set
|
||||||
* @param localizedDescription - The localized description for the given locale
|
* @param localizedDescription - The localized description for the given locale
|
||||||
*/
|
*/
|
||||||
public setDescriptionLocalization(locale: LocaleString, localizedDescription: string | null) {
|
public setDescriptionLocalization(locale: LocaleString, localizedDescription: string | null) {
|
||||||
@@ -107,9 +122,9 @@ export class SharedNameAndDescription {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the description localizations
|
* Sets the description localizations for this command.
|
||||||
*
|
*
|
||||||
* @param localizedDescriptions - The dictionary of localized descriptions to set
|
* @param localizedDescriptions - The object of localized descriptions to set
|
||||||
*/
|
*/
|
||||||
public setDescriptionLocalizations(localizedDescriptions: LocalizationMap | null) {
|
public setDescriptionLocalizations(localizedDescriptions: LocalizationMap | null) {
|
||||||
if (localizedDescriptions === null) {
|
if (localizedDescriptions === null) {
|
||||||
|
|||||||
@@ -11,13 +11,18 @@ import { SlashCommandStringOption } from '../options/string.js';
|
|||||||
import { SlashCommandUserOption } from '../options/user.js';
|
import { SlashCommandUserOption } from '../options/user.js';
|
||||||
import type { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js';
|
import type { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This mixin holds symbols that can be shared in slash command options.
|
||||||
|
*
|
||||||
|
* @typeParam ShouldOmitSubcommandFunctions - Whether to omit subcommand functions.
|
||||||
|
*/
|
||||||
export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
||||||
public readonly options!: ToAPIApplicationCommandOptions[];
|
public readonly options!: ToAPIApplicationCommandOptions[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a boolean option
|
* Adds a boolean option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addBooleanOption(
|
public addBooleanOption(
|
||||||
input: SlashCommandBooleanOption | ((builder: SlashCommandBooleanOption) => SlashCommandBooleanOption),
|
input: SlashCommandBooleanOption | ((builder: SlashCommandBooleanOption) => SlashCommandBooleanOption),
|
||||||
@@ -26,18 +31,18 @@ export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a user option
|
* Adds a user option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addUserOption(input: SlashCommandUserOption | ((builder: SlashCommandUserOption) => SlashCommandUserOption)) {
|
public addUserOption(input: SlashCommandUserOption | ((builder: SlashCommandUserOption) => SlashCommandUserOption)) {
|
||||||
return this._sharedAddOptionMethod(input, SlashCommandUserOption);
|
return this._sharedAddOptionMethod(input, SlashCommandUserOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a channel option
|
* Adds a channel option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addChannelOption(
|
public addChannelOption(
|
||||||
input: SlashCommandChannelOption | ((builder: SlashCommandChannelOption) => SlashCommandChannelOption),
|
input: SlashCommandChannelOption | ((builder: SlashCommandChannelOption) => SlashCommandChannelOption),
|
||||||
@@ -46,18 +51,18 @@ export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a role option
|
* Adds a role option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addRoleOption(input: SlashCommandRoleOption | ((builder: SlashCommandRoleOption) => SlashCommandRoleOption)) {
|
public addRoleOption(input: SlashCommandRoleOption | ((builder: SlashCommandRoleOption) => SlashCommandRoleOption)) {
|
||||||
return this._sharedAddOptionMethod(input, SlashCommandRoleOption);
|
return this._sharedAddOptionMethod(input, SlashCommandRoleOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an attachment option
|
* Adds an attachment option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addAttachmentOption(
|
public addAttachmentOption(
|
||||||
input: SlashCommandAttachmentOption | ((builder: SlashCommandAttachmentOption) => SlashCommandAttachmentOption),
|
input: SlashCommandAttachmentOption | ((builder: SlashCommandAttachmentOption) => SlashCommandAttachmentOption),
|
||||||
@@ -66,9 +71,9 @@ export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a mentionable option
|
* Adds a mentionable option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addMentionableOption(
|
public addMentionableOption(
|
||||||
input: SlashCommandMentionableOption | ((builder: SlashCommandMentionableOption) => SlashCommandMentionableOption),
|
input: SlashCommandMentionableOption | ((builder: SlashCommandMentionableOption) => SlashCommandMentionableOption),
|
||||||
@@ -77,9 +82,9 @@ export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a string option
|
* Adds a string option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addStringOption(
|
public addStringOption(
|
||||||
input:
|
input:
|
||||||
@@ -97,9 +102,9 @@ export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds an integer option
|
* Adds an integer option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addIntegerOption(
|
public addIntegerOption(
|
||||||
input:
|
input:
|
||||||
@@ -117,9 +122,9 @@ export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a number option
|
* Adds a number option.
|
||||||
*
|
*
|
||||||
* @param input - A function that returns an option builder, or an already built builder
|
* @param input - A function that returns an option builder or an already built builder
|
||||||
*/
|
*/
|
||||||
public addNumberOption(
|
public addNumberOption(
|
||||||
input:
|
input:
|
||||||
@@ -136,6 +141,13 @@ export class SharedSlashCommandOptions<ShouldOmitSubcommandFunctions = true> {
|
|||||||
return this._sharedAddOptionMethod(input, SlashCommandNumberOption);
|
return this._sharedAddOptionMethod(input, SlashCommandNumberOption);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Where the actual adding magic happens. ✨
|
||||||
|
*
|
||||||
|
* @param input - The input. What else?
|
||||||
|
* @param Instance - The instance of whatever is being added
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
private _sharedAddOptionMethod<T extends ApplicationCommandOptionBase>(
|
private _sharedAddOptionMethod<T extends ApplicationCommandOptionBase>(
|
||||||
input:
|
input:
|
||||||
| Omit<T, 'addChoices'>
|
| Omit<T, 'addChoices'>
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
import { ApplicationCommandOptionType, type APIApplicationCommandAttachmentOption } from 'discord-api-types/v10';
|
import { ApplicationCommandOptionType, type APIApplicationCommandAttachmentOption } from 'discord-api-types/v10';
|
||||||
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command attachment option.
|
||||||
|
*/
|
||||||
export class SlashCommandAttachmentOption extends ApplicationCommandOptionBase {
|
export class SlashCommandAttachmentOption extends ApplicationCommandOptionBase {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public override readonly type = ApplicationCommandOptionType.Attachment as const;
|
public override readonly type = ApplicationCommandOptionType.Attachment as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandAttachmentOption {
|
public toJSON(): APIApplicationCommandAttachmentOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
import { ApplicationCommandOptionType, type APIApplicationCommandBooleanOption } from 'discord-api-types/v10';
|
import { ApplicationCommandOptionType, type APIApplicationCommandBooleanOption } from 'discord-api-types/v10';
|
||||||
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command boolean option.
|
||||||
|
*/
|
||||||
export class SlashCommandBooleanOption extends ApplicationCommandOptionBase {
|
export class SlashCommandBooleanOption extends ApplicationCommandOptionBase {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public readonly type = ApplicationCommandOptionType.Boolean as const;
|
public readonly type = ApplicationCommandOptionType.Boolean as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandBooleanOption {
|
public toJSON(): APIApplicationCommandBooleanOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,19 @@ import { mix } from 'ts-mixer';
|
|||||||
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
||||||
import { ApplicationCommandOptionChannelTypesMixin } from '../mixins/ApplicationCommandOptionChannelTypesMixin.js';
|
import { ApplicationCommandOptionChannelTypesMixin } from '../mixins/ApplicationCommandOptionChannelTypesMixin.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command channel option.
|
||||||
|
*/
|
||||||
@mix(ApplicationCommandOptionChannelTypesMixin)
|
@mix(ApplicationCommandOptionChannelTypesMixin)
|
||||||
export class SlashCommandChannelOption extends ApplicationCommandOptionBase {
|
export class SlashCommandChannelOption extends ApplicationCommandOptionBase {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public override readonly type = ApplicationCommandOptionType.Channel as const;
|
public override readonly type = ApplicationCommandOptionType.Channel as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandChannelOption {
|
public toJSON(): APIApplicationCommandChannelOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,17 @@ import { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixi
|
|||||||
|
|
||||||
const numberValidator = s.number.int;
|
const numberValidator = s.number.int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command integer option.
|
||||||
|
*/
|
||||||
@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)
|
@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)
|
||||||
export class SlashCommandIntegerOption
|
export class SlashCommandIntegerOption
|
||||||
extends ApplicationCommandOptionBase
|
extends ApplicationCommandOptionBase
|
||||||
implements ApplicationCommandNumericOptionMinMaxValueMixin
|
implements ApplicationCommandNumericOptionMinMaxValueMixin
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public readonly type = ApplicationCommandOptionType.Integer as const;
|
public readonly type = ApplicationCommandOptionType.Integer as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,6 +42,9 @@ export class SlashCommandIntegerOption
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandIntegerOption {
|
public toJSON(): APIApplicationCommandIntegerOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
import { ApplicationCommandOptionType, type APIApplicationCommandMentionableOption } from 'discord-api-types/v10';
|
import { ApplicationCommandOptionType, type APIApplicationCommandMentionableOption } from 'discord-api-types/v10';
|
||||||
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command mentionable option.
|
||||||
|
*/
|
||||||
export class SlashCommandMentionableOption extends ApplicationCommandOptionBase {
|
export class SlashCommandMentionableOption extends ApplicationCommandOptionBase {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public readonly type = ApplicationCommandOptionType.Mentionable as const;
|
public readonly type = ApplicationCommandOptionType.Mentionable as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandMentionableOption {
|
public toJSON(): APIApplicationCommandMentionableOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -7,11 +7,17 @@ import { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixi
|
|||||||
|
|
||||||
const numberValidator = s.number;
|
const numberValidator = s.number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command number option.
|
||||||
|
*/
|
||||||
@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)
|
@mix(ApplicationCommandNumericOptionMinMaxValueMixin, ApplicationCommandOptionWithChoicesAndAutocompleteMixin)
|
||||||
export class SlashCommandNumberOption
|
export class SlashCommandNumberOption
|
||||||
extends ApplicationCommandOptionBase
|
extends ApplicationCommandOptionBase
|
||||||
implements ApplicationCommandNumericOptionMinMaxValueMixin
|
implements ApplicationCommandNumericOptionMinMaxValueMixin
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public readonly type = ApplicationCommandOptionType.Number as const;
|
public readonly type = ApplicationCommandOptionType.Number as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -36,6 +42,9 @@ export class SlashCommandNumberOption
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandNumberOption {
|
public toJSON(): APIApplicationCommandNumberOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
import { ApplicationCommandOptionType, type APIApplicationCommandRoleOption } from 'discord-api-types/v10';
|
import { ApplicationCommandOptionType, type APIApplicationCommandRoleOption } from 'discord-api-types/v10';
|
||||||
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command role option.
|
||||||
|
*/
|
||||||
export class SlashCommandRoleOption extends ApplicationCommandOptionBase {
|
export class SlashCommandRoleOption extends ApplicationCommandOptionBase {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public override readonly type = ApplicationCommandOptionType.Role as const;
|
public override readonly type = ApplicationCommandOptionType.Role as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandRoleOption {
|
public toJSON(): APIApplicationCommandRoleOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -7,12 +7,24 @@ import { ApplicationCommandOptionWithChoicesAndAutocompleteMixin } from '../mixi
|
|||||||
const minLengthValidator = s.number.greaterThanOrEqual(0).lessThanOrEqual(6_000);
|
const minLengthValidator = s.number.greaterThanOrEqual(0).lessThanOrEqual(6_000);
|
||||||
const maxLengthValidator = s.number.greaterThanOrEqual(1).lessThanOrEqual(6_000);
|
const maxLengthValidator = s.number.greaterThanOrEqual(1).lessThanOrEqual(6_000);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command string option.
|
||||||
|
*/
|
||||||
@mix(ApplicationCommandOptionWithChoicesAndAutocompleteMixin)
|
@mix(ApplicationCommandOptionWithChoicesAndAutocompleteMixin)
|
||||||
export class SlashCommandStringOption extends ApplicationCommandOptionBase {
|
export class SlashCommandStringOption extends ApplicationCommandOptionBase {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public readonly type = ApplicationCommandOptionType.String as const;
|
public readonly type = ApplicationCommandOptionType.String as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum length of this option.
|
||||||
|
*/
|
||||||
public readonly max_length?: number;
|
public readonly max_length?: number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum length of this option.
|
||||||
|
*/
|
||||||
public readonly min_length?: number;
|
public readonly min_length?: number;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -41,6 +53,9 @@ export class SlashCommandStringOption extends ApplicationCommandOptionBase {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandStringOption {
|
public toJSON(): APIApplicationCommandStringOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,18 @@
|
|||||||
import { ApplicationCommandOptionType, type APIApplicationCommandUserOption } from 'discord-api-types/v10';
|
import { ApplicationCommandOptionType, type APIApplicationCommandUserOption } from 'discord-api-types/v10';
|
||||||
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOptionBase.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A slash command user option.
|
||||||
|
*/
|
||||||
export class SlashCommandUserOption extends ApplicationCommandOptionBase {
|
export class SlashCommandUserOption extends ApplicationCommandOptionBase {
|
||||||
|
/**
|
||||||
|
* The type of this option.
|
||||||
|
*/
|
||||||
public readonly type = ApplicationCommandOptionType.User as const;
|
public readonly type = ApplicationCommandOptionType.User as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc ApplicationCommandOptionBase.toJSON}
|
||||||
|
*/
|
||||||
public toJSON(): APIApplicationCommandUserOption {
|
public toJSON(): APIApplicationCommandUserOption {
|
||||||
this.runRequiredValidations();
|
this.runRequiredValidations();
|
||||||
|
|
||||||
|
|||||||
@@ -13,59 +13,91 @@ import {
|
|||||||
validateFieldLength,
|
validateFieldLength,
|
||||||
} from './Assertions.js';
|
} from './Assertions.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A tuple satisfying the RGB color model.
|
||||||
|
*
|
||||||
|
* @see {@link https://developer.mozilla.org/docs/Glossary/RGB}
|
||||||
|
*/
|
||||||
export type RGBTuple = [red: number, green: number, blue: number];
|
export type RGBTuple = [red: number, green: number, blue: number];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base icon data typically used in payloads.
|
||||||
|
*/
|
||||||
export interface IconData {
|
export interface IconData {
|
||||||
/**
|
/**
|
||||||
* The URL of the icon
|
* The URL of the icon.
|
||||||
*/
|
*/
|
||||||
iconURL?: string;
|
iconURL?: string;
|
||||||
/**
|
/**
|
||||||
* The proxy URL of the icon
|
* The proxy URL of the icon.
|
||||||
*/
|
*/
|
||||||
proxyIconURL?: string;
|
proxyIconURL?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the author data of an embed.
|
||||||
|
*/
|
||||||
export type EmbedAuthorData = IconData & Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'>;
|
export type EmbedAuthorData = IconData & Omit<APIEmbedAuthor, 'icon_url' | 'proxy_icon_url'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the author options of an embed.
|
||||||
|
*/
|
||||||
export type EmbedAuthorOptions = Omit<EmbedAuthorData, 'proxyIconURL'>;
|
export type EmbedAuthorOptions = Omit<EmbedAuthorData, 'proxyIconURL'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the footer data of an embed.
|
||||||
|
*/
|
||||||
export type EmbedFooterData = IconData & Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'>;
|
export type EmbedFooterData = IconData & Omit<APIEmbedFooter, 'icon_url' | 'proxy_icon_url'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the footer options of an embed.
|
||||||
|
*/
|
||||||
export type EmbedFooterOptions = Omit<EmbedFooterData, 'proxyIconURL'>;
|
export type EmbedFooterOptions = Omit<EmbedFooterData, 'proxyIconURL'>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the image data of an embed.
|
||||||
|
*/
|
||||||
export interface EmbedImageData extends Omit<APIEmbedImage, 'proxy_url'> {
|
export interface EmbedImageData extends Omit<APIEmbedImage, 'proxy_url'> {
|
||||||
/**
|
/**
|
||||||
* The proxy URL for the image
|
* The proxy URL for the image.
|
||||||
*/
|
*/
|
||||||
proxyURL?: string;
|
proxyURL?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a embed in a message (image/video preview, rich embed, etc.)
|
* A builder that creates API-compatible JSON data for embeds.
|
||||||
*/
|
*/
|
||||||
export class EmbedBuilder {
|
export class EmbedBuilder {
|
||||||
|
/**
|
||||||
|
* The API data associated with this embed.
|
||||||
|
*/
|
||||||
public readonly data: APIEmbed;
|
public readonly data: APIEmbed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new embed from API data.
|
||||||
|
*
|
||||||
|
* @param data - The API data to create this embed with
|
||||||
|
*/
|
||||||
public constructor(data: APIEmbed = {}) {
|
public constructor(data: APIEmbed = {}) {
|
||||||
this.data = { ...data };
|
this.data = { ...data };
|
||||||
if (data.timestamp) this.data.timestamp = new Date(data.timestamp).toISOString();
|
if (data.timestamp) this.data.timestamp = new Date(data.timestamp).toISOString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Appends fields to the embed
|
* Appends fields to the embed.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method accepts either an array of fields or a variable number of field parameters.
|
* This method accepts either an array of fields or a variable number of field parameters.
|
||||||
* The maximum amount of fields that can be added is 25.
|
* The maximum amount of fields that can be added is 25.
|
||||||
* @example
|
* @example
|
||||||
* Using an array
|
* Using an array:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const fields: APIEmbedField[] = ...;
|
* const fields: APIEmbedField[] = ...;
|
||||||
* const embed = new EmbedBuilder()
|
* const embed = new EmbedBuilder()
|
||||||
* .addFields(fields);
|
* .addFields(fields);
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Using rest parameters (variadic)
|
* Using rest parameters (variadic):
|
||||||
* ```ts
|
* ```ts
|
||||||
* const embed = new EmbedBuilder()
|
* const embed = new EmbedBuilder()
|
||||||
* .addFields(
|
* .addFields(
|
||||||
@@ -76,21 +108,20 @@ export class EmbedBuilder {
|
|||||||
* @param fields - The fields to add
|
* @param fields - The fields to add
|
||||||
*/
|
*/
|
||||||
public addFields(...fields: RestOrArray<APIEmbedField>): this {
|
public addFields(...fields: RestOrArray<APIEmbedField>): this {
|
||||||
// eslint-disable-next-line no-param-reassign
|
const normalizedFields = normalizeArray(fields);
|
||||||
fields = normalizeArray(fields);
|
|
||||||
// Ensure adding these fields won't exceed the 25 field limit
|
// Ensure adding these fields won't exceed the 25 field limit
|
||||||
validateFieldLength(fields.length, this.data.fields);
|
validateFieldLength(normalizedFields.length, this.data.fields);
|
||||||
|
|
||||||
// Data assertions
|
// Data assertions
|
||||||
embedFieldsArrayPredicate.parse(fields);
|
embedFieldsArrayPredicate.parse(normalizedFields);
|
||||||
|
|
||||||
if (this.data.fields) this.data.fields.push(...fields);
|
if (this.data.fields) this.data.fields.push(...normalizedFields);
|
||||||
else this.data.fields = fields;
|
else this.data.fields = normalizedFields;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes, replaces, or inserts fields in the embed.
|
* Removes, replaces, or inserts fields for this embed.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method behaves similarly
|
* This method behaves similarly
|
||||||
@@ -99,18 +130,18 @@ export class EmbedBuilder {
|
|||||||
*
|
*
|
||||||
* It's useful for modifying and adjusting order of the already-existing fields of an embed.
|
* It's useful for modifying and adjusting order of the already-existing fields of an embed.
|
||||||
* @example
|
* @example
|
||||||
* Remove the first field
|
* Remove the first field:
|
||||||
* ```ts
|
* ```ts
|
||||||
* embed.spliceFields(0, 1);
|
* embed.spliceFields(0, 1);
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Remove the first n fields
|
* Remove the first n fields:
|
||||||
* ```ts
|
* ```ts
|
||||||
* const n = 4
|
* const n = 4;
|
||||||
* embed.spliceFields(0, n);
|
* embed.spliceFields(0, n);
|
||||||
* ```
|
* ```
|
||||||
* @example
|
* @example
|
||||||
* Remove the last field
|
* Remove the last field:
|
||||||
* ```ts
|
* ```ts
|
||||||
* embed.spliceFields(-1, 1);
|
* embed.spliceFields(-1, 1);
|
||||||
* ```
|
* ```
|
||||||
@@ -130,7 +161,7 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the embed's fields
|
* Sets the fields for this embed.
|
||||||
*
|
*
|
||||||
* @remarks
|
* @remarks
|
||||||
* This method is an alias for {@link EmbedBuilder.spliceFields}. More specifically,
|
* This method is an alias for {@link EmbedBuilder.spliceFields}. More specifically,
|
||||||
@@ -145,9 +176,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the author of this embed
|
* Sets the author of this embed.
|
||||||
*
|
*
|
||||||
* @param options - The options for the author
|
* @param options - The options to use
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public setAuthor(options: EmbedAuthorOptions | null): this {
|
public setAuthor(options: EmbedAuthorOptions | null): this {
|
||||||
@@ -164,9 +195,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the color of this embed
|
* Sets the color of this embed.
|
||||||
*
|
*
|
||||||
* @param color - The color of the embed
|
* @param color - The color to use
|
||||||
*/
|
*/
|
||||||
public setColor(color: RGBTuple | number | null): this {
|
public setColor(color: RGBTuple | number | null): this {
|
||||||
// Data assertions
|
// Data assertions
|
||||||
@@ -183,9 +214,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the description of this embed
|
* Sets the description of this embed.
|
||||||
*
|
*
|
||||||
* @param description - The description
|
* @param description - The description to use
|
||||||
*/
|
*/
|
||||||
public setDescription(description: string | null): this {
|
public setDescription(description: string | null): this {
|
||||||
// Data assertions
|
// Data assertions
|
||||||
@@ -196,9 +227,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the footer of this embed
|
* Sets the footer of this embed.
|
||||||
*
|
*
|
||||||
* @param options - The options for the footer
|
* @param options - The footer to use
|
||||||
*/
|
*/
|
||||||
public setFooter(options: EmbedFooterOptions | null): this {
|
public setFooter(options: EmbedFooterOptions | null): this {
|
||||||
if (options === null) {
|
if (options === null) {
|
||||||
@@ -214,9 +245,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the image of this embed
|
* Sets the image of this embed.
|
||||||
*
|
*
|
||||||
* @param url - The URL of the image
|
* @param url - The image URL to use
|
||||||
*/
|
*/
|
||||||
public setImage(url: string | null): this {
|
public setImage(url: string | null): this {
|
||||||
// Data assertions
|
// Data assertions
|
||||||
@@ -227,9 +258,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the thumbnail of this embed
|
* Sets the thumbnail of this embed.
|
||||||
*
|
*
|
||||||
* @param url - The URL of the thumbnail
|
* @param url - The thumbnail URL to use
|
||||||
*/
|
*/
|
||||||
public setThumbnail(url: string | null): this {
|
public setThumbnail(url: string | null): this {
|
||||||
// Data assertions
|
// Data assertions
|
||||||
@@ -240,9 +271,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the timestamp of this embed
|
* Sets the timestamp of this embed.
|
||||||
*
|
*
|
||||||
* @param timestamp - The timestamp or date
|
* @param timestamp - The timestamp or date to use
|
||||||
*/
|
*/
|
||||||
public setTimestamp(timestamp: Date | number | null = Date.now()): this {
|
public setTimestamp(timestamp: Date | number | null = Date.now()): this {
|
||||||
// Data assertions
|
// Data assertions
|
||||||
@@ -253,9 +284,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the title of this embed
|
* Sets the title for this embed.
|
||||||
*
|
*
|
||||||
* @param title - The title
|
* @param title - The title to use
|
||||||
*/
|
*/
|
||||||
public setTitle(title: string | null): this {
|
public setTitle(title: string | null): this {
|
||||||
// Data assertions
|
// Data assertions
|
||||||
@@ -266,9 +297,9 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the URL of this embed
|
* Sets the URL of this embed.
|
||||||
*
|
*
|
||||||
* @param url - The URL
|
* @param url - The URL to use
|
||||||
*/
|
*/
|
||||||
public setURL(url: string | null): this {
|
public setURL(url: string | null): this {
|
||||||
// Data assertions
|
// Data assertions
|
||||||
@@ -279,7 +310,11 @@ export class EmbedBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms the embed to a plain object
|
* Serializes this builder to API-compatible JSON data.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This method runs validations on the data before serializing it.
|
||||||
|
* As such, it may throw an error if the data is invalid.
|
||||||
*/
|
*/
|
||||||
public toJSON(): APIEmbed {
|
public toJSON(): APIEmbed {
|
||||||
return { ...this.data };
|
return { ...this.data };
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
import type { APIEmbed } from 'discord-api-types/v10';
|
import type { APIEmbed } from 'discord-api-types/v10';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the length of the embed.
|
||||||
|
*
|
||||||
|
* @param data - The embed data to check
|
||||||
|
*/
|
||||||
export function embedLength(data: APIEmbed) {
|
export function embedLength(data: APIEmbed) {
|
||||||
return (
|
return (
|
||||||
(data.title?.length ?? 0) +
|
(data.title?.length ?? 0) +
|
||||||
|
|||||||
@@ -1,6 +1,19 @@
|
|||||||
|
/**
|
||||||
|
* Normalizes data that is a rest parameter or an array into an array with a depth of 1.
|
||||||
|
*
|
||||||
|
* @typeParam T - The data that must satisfy {@link RestOrArray}.
|
||||||
|
* @param arr - The (possibly variadic) data to normalize
|
||||||
|
*/
|
||||||
export function normalizeArray<T>(arr: RestOrArray<T>): T[] {
|
export function normalizeArray<T>(arr: RestOrArray<T>): T[] {
|
||||||
if (Array.isArray(arr[0])) return arr[0];
|
if (Array.isArray(arr[0])) return arr[0];
|
||||||
return arr as T[];
|
return arr as T[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents data that may be an array or came from a rest parameter.
|
||||||
|
*
|
||||||
|
* @remarks
|
||||||
|
* This type is used throughout builders to ensure both an array and variadic arguments
|
||||||
|
* may be used. It is normalized with {@link normalizeArray}.
|
||||||
|
*/
|
||||||
export type RestOrArray<T> = T[] | [T[]];
|
export type RestOrArray<T> = T[] | [T[]];
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
let validate = true;
|
let validate = true;
|
||||||
|
|
||||||
export const enableValidators = () => (validate = true);
|
/**
|
||||||
export const disableValidators = () => (validate = false);
|
* Enables validators.
|
||||||
export const isValidationEnabled = () => validate;
|
*
|
||||||
|
* @returns Whether validation is occurring.
|
||||||
|
*/
|
||||||
|
export function enableValidators() {
|
||||||
|
return (validate = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disables validators.
|
||||||
|
*
|
||||||
|
* @returns Whether validation is occurring.
|
||||||
|
*/
|
||||||
|
export function disableValidators() {
|
||||||
|
return (validate = false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether validation is occurring.
|
||||||
|
*/
|
||||||
|
export function isValidationEnabled() {
|
||||||
|
return validate;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user