docs: add missing, fix existing (#10842)

* docs: add missing, fix existing

* refactor: new stuff

* fix: requested changes

* fix: use `@link` for `@mixes`

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>

* chore: disable bad eslint rule

---------

Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
This commit is contained in:
Almeida
2025-06-02 18:35:43 +01:00
committed by GitHub
parent 8d50e92516
commit e094faf225
62 changed files with 377 additions and 139 deletions

View File

@@ -135,6 +135,7 @@ export default tseslint.config(
files: [`packages/builders/**/*${commonFiles}`], files: [`packages/builders/**/*${commonFiles}`],
rules: { rules: {
'@typescript-eslint/no-empty-object-type': 0, '@typescript-eslint/no-empty-object-type': 0,
'jsdoc/valid-types': 0,
}, },
}, },
{ {

View File

@@ -1,5 +1,3 @@
/* eslint-disable jsdoc/check-param-names */
import type { import type {
APITextInputComponent, APITextInputComponent,
APIActionRowComponent, APIActionRowComponent,
@@ -43,10 +41,11 @@ export interface ActionRowBuilderData
/** /**
* A builder that creates API-compatible JSON data for action rows. * A builder that creates API-compatible JSON data for action rows.
*
* @typeParam ComponentType - The types of components this action row holds
*/ */
export class ActionRowBuilder extends ComponentBuilder<APIActionRowComponent<APIComponentInActionRow>> { export class ActionRowBuilder extends ComponentBuilder<APIActionRowComponent<APIComponentInActionRow>> {
/**
* @internal
*/
protected readonly data: ActionRowBuilderData; protected readonly data: ActionRowBuilderData;
/** /**
@@ -57,7 +56,7 @@ export class ActionRowBuilder extends ComponentBuilder<APIActionRowComponent<API
} }
/** /**
* Creates a new action row from API data. * Creates a new action row.
* *
* @param data - The API data to create this action row with * @param data - The API data to create this action row with
* @example * @example
@@ -90,12 +89,15 @@ export class ActionRowBuilder extends ComponentBuilder<APIActionRowComponent<API
* .addComponents(button2, button3); * .addComponents(button2, button3);
* ``` * ```
*/ */
public constructor({ components = [], ...data }: Partial<APIActionRowComponent<APIComponentInActionRow>> = {}) { public constructor(data: Partial<APIActionRowComponent<APIComponentInActionRow>> = {}) {
super(); super();
const { components = [], ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
type: ComponentType.ActionRow,
components: components.map((component) => createComponentBuilder(component)), components: components.map((component) => createComponentBuilder(component)),
type: ComponentType.ActionRow,
}; };
} }

View File

@@ -13,6 +13,9 @@ export interface ComponentBuilderBaseData {
export abstract class ComponentBuilder<Component extends APIBaseComponent<ComponentType>> export abstract class ComponentBuilder<Component extends APIBaseComponent<ComponentType>>
implements JSONEncodable<Component> implements JSONEncodable<Component>
{ {
/**
* @internal
*/
protected abstract readonly data: ComponentBuilderBaseData; protected abstract readonly data: ComponentBuilderBaseData;
/** /**

View File

@@ -7,6 +7,9 @@ import { ComponentBuilder } from '../Component.js';
* A builder that creates API-compatible JSON data for buttons. * A builder that creates API-compatible JSON data for buttons.
*/ */
export abstract class BaseButtonBuilder<ButtonData extends APIButtonComponent> extends ComponentBuilder<ButtonData> { export abstract class BaseButtonBuilder<ButtonData extends APIButtonComponent> extends ComponentBuilder<ButtonData> {
/**
* @internal
*/
declare protected readonly data: Partial<ButtonData>; declare protected readonly data: Partial<ButtonData>;
/** /**

View File

@@ -7,6 +7,9 @@ export type CustomIdButtonStyle = APIButtonComponentWithCustomId['style'];
/** /**
* A builder that creates API-compatible JSON data for buttons with custom IDs. * A builder that creates API-compatible JSON data for buttons with custom IDs.
*
* @mixes {@link BaseButtonBuilder}\<{@link discord-api-types/v10#(APIButtonComponentWithCustomId:interface)}\>
* @mixes {@link EmojiOrLabelButtonMixin}
*/ */
export abstract class CustomIdButtonBuilder extends Mixin( export abstract class CustomIdButtonBuilder extends Mixin(
BaseButtonBuilder<APIButtonComponentWithCustomId>, BaseButtonBuilder<APIButtonComponentWithCustomId>,

View File

@@ -10,6 +10,9 @@ import { EmojiOrLabelButtonMixin } from './mixins/EmojiOrLabelButtonMixin.js';
/** /**
* A builder that creates API-compatible JSON data for buttons with links. * A builder that creates API-compatible JSON data for buttons with links.
*
* @mixes {@link BaseButtonBuilder}\<{@link discord-api-types/v10#(APIButtonComponentWithURL:interface)}\>
* @mixes {@link EmojiOrLabelButtonMixin}
*/ */
export class LinkButtonBuilder extends Mixin(BaseButtonBuilder<APIButtonComponentWithURL>, EmojiOrLabelButtonMixin) { export class LinkButtonBuilder extends Mixin(BaseButtonBuilder<APIButtonComponentWithURL>, EmojiOrLabelButtonMixin) {
protected override readonly data: Partial<APIButtonComponentWithURL>; protected override readonly data: Partial<APIButtonComponentWithURL>;

View File

@@ -3,7 +3,13 @@ import type { APIButtonComponent, APIButtonComponentWithSKUId, APIMessageCompone
export interface EmojiOrLabelButtonData export interface EmojiOrLabelButtonData
extends Pick<Exclude<APIButtonComponent, APIButtonComponentWithSKUId>, 'emoji' | 'label'> {} extends Pick<Exclude<APIButtonComponent, APIButtonComponentWithSKUId>, 'emoji' | 'label'> {}
/**
* A mixin that adds emoji and label symbols to a button builder.
*/
export class EmojiOrLabelButtonMixin { export class EmojiOrLabelButtonMixin {
/**
* @internal
*/
declare protected readonly data: EmojiOrLabelButtonData; declare protected readonly data: EmojiOrLabelButtonData;
/** /**

View File

@@ -5,12 +5,15 @@ import { ComponentBuilder } from '../Component.js';
/** /**
* The base select menu builder that contains common symbols for select menu builders. * 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. * @typeParam Data - The type of API data that is stored within the builder
*/ */
export abstract class BaseSelectMenuBuilder<Data extends APISelectMenuComponent> export abstract class BaseSelectMenuBuilder<Data extends APISelectMenuComponent>
extends ComponentBuilder<Data> extends ComponentBuilder<Data>
implements JSONEncodable<APISelectMenuComponent> implements JSONEncodable<APISelectMenuComponent>
{ {
/**
* @internal
*/
protected abstract override readonly data: Partial< protected abstract override readonly data: Partial<
Pick<Data, 'custom_id' | 'disabled' | 'id' | 'max_values' | 'min_values' | 'placeholder'> Pick<Data, 'custom_id' | 'disabled' | 'id' | 'max_values' | 'min_values' | 'placeholder'>
>; >;

View File

@@ -17,9 +17,9 @@ export class ChannelSelectMenuBuilder extends BaseSelectMenuBuilder<APIChannelSe
protected override readonly data: Partial<APIChannelSelectComponent>; protected override readonly data: Partial<APIChannelSelectComponent>;
/** /**
* Creates a new select menu from API data. * Creates a new channel select menu.
* *
* @param data - The API data to create this select menu with * @param data - The API data to create this channel 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

View File

@@ -17,9 +17,9 @@ export class MentionableSelectMenuBuilder extends BaseSelectMenuBuilder<APIMenti
protected override readonly data: Partial<APIMentionableSelectComponent>; protected override readonly data: Partial<APIMentionableSelectComponent>;
/** /**
* Creates a new select menu from API data. * Creates a new mentionable select menu.
* *
* @param data - The API data to create this select menu with * @param data - The API data to create this mentionable 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

View File

@@ -16,9 +16,9 @@ export class RoleSelectMenuBuilder extends BaseSelectMenuBuilder<APIRoleSelectCo
protected override readonly data: Partial<APIRoleSelectComponent>; protected override readonly data: Partial<APIRoleSelectComponent>;
/** /**
* Creates a new select menu from API data. * Creates a new role select menu.
* *
* @param data - The API data to create this select menu with * @param data - The API data to create this role 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

View File

@@ -1,5 +1,3 @@
/* eslint-disable jsdoc/check-param-names */
import { ComponentType } from 'discord-api-types/v10'; import { ComponentType } from 'discord-api-types/v10';
import type { APIStringSelectComponent, APISelectMenuOption } from 'discord-api-types/v10'; import type { APIStringSelectComponent, APISelectMenuOption } from 'discord-api-types/v10';
import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js'; import { normalizeArray, type RestOrArray } from '../../util/normalizeArray.js';
@@ -27,9 +25,9 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
} }
/** /**
* Creates a new select menu from API data. * Creates a new string select menu.
* *
* @param data - The API data to create this select menu with * @param data - The API data to create this string 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
@@ -57,10 +55,13 @@ export class StringSelectMenuBuilder extends BaseSelectMenuBuilder<APIStringSele
* }); * });
* ``` * ```
*/ */
public constructor({ options = [], ...data }: Partial<APIStringSelectComponent> = {}) { public constructor(data: Partial<APIStringSelectComponent> = {}) {
super(); super();
const { options = [], ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
options: options.map((option) => new StringSelectMenuOptionBuilder(option)), options: options.map((option) => new StringSelectMenuOptionBuilder(option)),
type: ComponentType.StringSelect, type: ComponentType.StringSelect,
}; };

View File

@@ -10,7 +10,7 @@ export class StringSelectMenuOptionBuilder implements JSONEncodable<APISelectMen
private readonly data: Partial<APISelectMenuOption>; private readonly data: Partial<APISelectMenuOption>;
/** /**
* Creates a new string select menu option from API data. * Creates a new string select menu option.
* *
* @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

View File

@@ -16,9 +16,9 @@ export class UserSelectMenuBuilder extends BaseSelectMenuBuilder<APIUserSelectCo
protected override readonly data: Partial<APIUserSelectComponent>; protected override readonly data: Partial<APIUserSelectComponent>;
/** /**
* Creates a new select menu from API data. * Creates a new user select menu.
* *
* @param data - The API data to create this select menu with * @param data - The API data to create this user 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

View File

@@ -7,10 +7,13 @@ import { textInputPredicate } from './Assertions.js';
* A builder that creates API-compatible JSON data for text inputs. * A builder that creates API-compatible JSON data for text inputs.
*/ */
export class TextInputBuilder extends ComponentBuilder<APITextInputComponent> { export class TextInputBuilder extends ComponentBuilder<APITextInputComponent> {
/**
* @internal
*/
protected readonly data: Partial<APITextInputComponent>; protected readonly data: Partial<APITextInputComponent>;
/** /**
* Creates a new text input from API data. * Creates a new text input.
* *
* @param data - The API data to create this text input with * @param data - The API data to create this text input with
* @example * @example

View File

@@ -34,11 +34,32 @@ export interface ContainerBuilderData extends Partial<Omit<APIContainerComponent
components: ContainerComponentBuilders[]; components: ContainerComponentBuilders[];
} }
/**
* A builder that creates API-compatible JSON data for containers.
*/
export class ContainerBuilder extends ComponentBuilder<APIContainerComponent> { export class ContainerBuilder extends ComponentBuilder<APIContainerComponent> {
/**
* @internal
*/
protected readonly data: ContainerBuilderData; protected readonly data: ContainerBuilderData;
public constructor({ components = [], ...rest }: Partial<APIContainerComponent> = {}) { /**
* Gets the components within this container.
*/
public get components(): readonly ContainerComponentBuilders[] {
return this.data.components;
}
/**
* Creates a new container builder.
*
* @param data - The API data to create the container with
*/
public constructor(data: Partial<APIContainerComponent> = {}) {
super(); super();
const { components = [], ...rest } = data;
this.data = { this.data = {
...structuredClone(rest), ...structuredClone(rest),
components: components.map((component) => createComponentBuilder(component)), components: components.map((component) => createComponentBuilder(component)),

View File

@@ -3,11 +3,17 @@ import { validate } from '../../util/validation.js';
import { ComponentBuilder } from '../Component.js'; import { ComponentBuilder } from '../Component.js';
import { filePredicate } from './Assertions.js'; import { filePredicate } from './Assertions.js';
/**
* A builder that creates API-compatible JSON data for files.
*/
export class FileBuilder extends ComponentBuilder<APIFileComponent> { export class FileBuilder extends ComponentBuilder<APIFileComponent> {
/**
* @internal
*/
protected readonly data: Partial<APIFileComponent>; protected readonly data: Partial<APIFileComponent>;
/** /**
* Creates a new file from API data. * Creates a new file.
* *
* @param data - The API data to create this file with * @param data - The API data to create this file with
* @example * @example
@@ -33,9 +39,12 @@ export class FileBuilder extends ComponentBuilder<APIFileComponent> {
*/ */
public constructor(data: Partial<APIFileComponent> = {}) { public constructor(data: Partial<APIFileComponent> = {}) {
super(); super();
const { file, ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
file: data.file ? { url: data.file.url } : undefined, file: file && { url: file.url },
type: ComponentType.File, type: ComponentType.File,
}; };
} }

View File

@@ -10,11 +10,24 @@ export interface MediaGalleryBuilderData extends Partial<Omit<APIMediaGalleryCom
items: MediaGalleryItemBuilder[]; items: MediaGalleryItemBuilder[];
} }
/**
* A builder that creates API-compatible JSON data for media galleries.
*/
export class MediaGalleryBuilder extends ComponentBuilder<APIMediaGalleryComponent> { export class MediaGalleryBuilder extends ComponentBuilder<APIMediaGalleryComponent> {
/**
* @internal
*/
protected readonly data: MediaGalleryBuilderData; protected readonly data: MediaGalleryBuilderData;
/** /**
* Creates a new media gallery from API data. * The items in this media gallery.
*/
public get items(): readonly MediaGalleryItemBuilder[] {
return this.data.items;
}
/**
* Creates a new media gallery.
* *
* @param data - The API data to create this container with * @param data - The API data to create this container with
* @example * @example
@@ -49,19 +62,16 @@ export class MediaGalleryBuilder extends ComponentBuilder<APIMediaGalleryCompone
*/ */
public constructor(data: Partial<APIMediaGalleryComponent> = {}) { public constructor(data: Partial<APIMediaGalleryComponent> = {}) {
super(); super();
const { items = [], ...rest } = data;
this.data = { this.data = {
items: data?.items?.map((item) => new MediaGalleryItemBuilder(item)) ?? [], ...structuredClone(rest),
items: items.map((item) => new MediaGalleryItemBuilder(item)),
type: ComponentType.MediaGallery, type: ComponentType.MediaGallery,
}; };
} }
/**
* The items in this media gallery.
*/
public get items(): readonly MediaGalleryItemBuilder[] {
return this.data.items;
}
/** /**
* Adds a media gallery item to this media gallery. * Adds a media gallery item to this media gallery.
* *

View File

@@ -7,7 +7,7 @@ export class MediaGalleryItemBuilder implements JSONEncodable<APIMediaGalleryIte
private readonly data: Partial<APIMediaGalleryItem>; private readonly data: Partial<APIMediaGalleryItem>;
/** /**
* Creates a new media gallery item from API data. * Creates a new media gallery item.
* *
* @param data - The API data to create this media gallery item with * @param data - The API data to create this media gallery item with
* @example * @example
@@ -32,9 +32,7 @@ export class MediaGalleryItemBuilder implements JSONEncodable<APIMediaGalleryIte
* ``` * ```
*/ */
public constructor(data: Partial<APIMediaGalleryItem> = {}) { public constructor(data: Partial<APIMediaGalleryItem> = {}) {
this.data = { this.data = structuredClone(data);
...structuredClone(data),
};
} }
/** /**

View File

@@ -32,15 +32,24 @@ export interface SectionBuilderData extends Partial<Omit<APISectionComponent, 'a
components: TextDisplayBuilder[]; components: TextDisplayBuilder[];
} }
/**
* A builder that creates API-compatible JSON data for sections.
*/
export class SectionBuilder extends ComponentBuilder<APISectionComponent> { export class SectionBuilder extends ComponentBuilder<APISectionComponent> {
/**
* @internal
*/
protected readonly data: SectionBuilderData; protected readonly data: SectionBuilderData;
/**
* The components within this section.
*/
public get components(): readonly TextDisplayBuilder[] { public get components(): readonly TextDisplayBuilder[] {
return this.data.components; return this.data.components;
} }
/** /**
* Creates a new section from API data. * Creates a new section.
* *
* @param data - The API data to create this section with * @param data - The API data to create this section with
* @example * @example
@@ -81,7 +90,7 @@ export class SectionBuilder extends ComponentBuilder<APISectionComponent> {
this.data = { this.data = {
...structuredClone(rest), ...structuredClone(rest),
accessory: accessory ? resolveAccessoryComponent(accessory) : undefined, accessory: accessory && resolveAccessoryComponent(accessory),
components: components.map((component) => new TextDisplayBuilder(component)), components: components.map((component) => new TextDisplayBuilder(component)),
type: ComponentType.Section, type: ComponentType.Section,
}; };

View File

@@ -4,11 +4,17 @@ import { validate } from '../../util/validation.js';
import { ComponentBuilder } from '../Component.js'; import { ComponentBuilder } from '../Component.js';
import { separatorPredicate } from './Assertions.js'; import { separatorPredicate } from './Assertions.js';
/**
* A builder that creates API-compatible JSON data for separators.
*/
export class SeparatorBuilder extends ComponentBuilder<APISeparatorComponent> { export class SeparatorBuilder extends ComponentBuilder<APISeparatorComponent> {
/**
* @internal
*/
protected readonly data: Partial<APISeparatorComponent>; protected readonly data: Partial<APISeparatorComponent>;
/** /**
* Creates a new separator from API data. * Creates a new separator.
* *
* @param data - The API data to create this separator with * @param data - The API data to create this separator with
* @example * @example

View File

@@ -4,11 +4,17 @@ import { validate } from '../../util/validation.js';
import { ComponentBuilder } from '../Component.js'; import { ComponentBuilder } from '../Component.js';
import { textDisplayPredicate } from './Assertions.js'; import { textDisplayPredicate } from './Assertions.js';
/**
* A builder that creates API-compatible JSON data for text displays.
*/
export class TextDisplayBuilder extends ComponentBuilder<APITextDisplayComponent> { export class TextDisplayBuilder extends ComponentBuilder<APITextDisplayComponent> {
/**
* @internal
*/
protected readonly data: Partial<APITextDisplayComponent>; protected readonly data: Partial<APITextDisplayComponent>;
/** /**
* Creates a new text display from API data. * Creates a new text display.
* *
* @param data - The API data to create this text display with * @param data - The API data to create this text display with
* @example * @example

View File

@@ -4,11 +4,17 @@ import { validate } from '../../util/validation.js';
import { ComponentBuilder } from '../Component.js'; import { ComponentBuilder } from '../Component.js';
import { thumbnailPredicate } from './Assertions.js'; import { thumbnailPredicate } from './Assertions.js';
/**
* A builder that creates API-compatible JSON data for thumbnails.
*/
export class ThumbnailBuilder extends ComponentBuilder<APIThumbnailComponent> { export class ThumbnailBuilder extends ComponentBuilder<APIThumbnailComponent> {
/**
* @internal
*/
protected readonly data: Partial<APIThumbnailComponent>; protected readonly data: Partial<APIThumbnailComponent>;
/** /**
* Creates a new thumbnail from API data. * Creates a new thumbnail.
* *
* @param data - The API data to create this thumbnail with * @param data - The API data to create this thumbnail with
* @example * @example
@@ -34,9 +40,12 @@ export class ThumbnailBuilder extends ComponentBuilder<APIThumbnailComponent> {
*/ */
public constructor(data: Partial<APIThumbnailComponent> = {}) { public constructor(data: Partial<APIThumbnailComponent> = {}) {
super(); super();
const { media, ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
media: data.media ? { url: data.media.url } : undefined, media: media && { url: media.url },
type: ComponentType.Thumbnail, type: ComponentType.Thumbnail,
}; };
} }

View File

@@ -16,9 +16,17 @@ export interface CommandData
> >
> {} > {}
/**
* The base class for all command builders.
*/
export abstract class CommandBuilder<Command extends RESTPostAPIApplicationCommandsJSONBody> export abstract class CommandBuilder<Command extends RESTPostAPIApplicationCommandsJSONBody>
implements JSONEncodable<Command> implements JSONEncodable<Command>
{ {
/**
* The API data associated with this command.
*
* @internal
*/
declare protected readonly data: CommandData; declare protected readonly data: CommandData;
/** /**

View File

@@ -7,6 +7,9 @@ export interface SharedNameData
* This mixin holds name and description symbols for chat input commands. * This mixin holds name and description symbols for chat input commands.
*/ */
export class SharedName { export class SharedName {
/**
* @internal
*/
protected readonly data: SharedNameData = {}; protected readonly data: SharedNameData = {};
/** /**

View File

@@ -10,6 +10,9 @@ export interface SharedNameAndDescriptionData
* This mixin holds name and description symbols for chat input commands. * This mixin holds name and description symbols for chat input commands.
*/ */
export class SharedNameAndDescription extends SharedName { export class SharedNameAndDescription extends SharedName {
/**
* @internal
*/
protected override readonly data: SharedNameAndDescriptionData = {}; protected override readonly data: SharedNameAndDescriptionData = {};
/** /**

View File

@@ -1,4 +1,3 @@
/* eslint-disable jsdoc/valid-types */
import { ApplicationCommandType, type RESTPostAPIChatInputApplicationCommandsJSONBody } from 'discord-api-types/v10'; import { ApplicationCommandType, type RESTPostAPIChatInputApplicationCommandsJSONBody } from 'discord-api-types/v10';
import { Mixin } from 'ts-mixer'; import { Mixin } from 'ts-mixer';
import { validate } from '../../../util/validation.js'; import { validate } from '../../../util/validation.js';

View File

@@ -26,8 +26,16 @@ export class ChatInputCommandSubcommandGroupBuilder
extends SharedNameAndDescription extends SharedNameAndDescription
implements JSONEncodable<APIApplicationCommandSubcommandGroupOption> implements JSONEncodable<APIApplicationCommandSubcommandGroupOption>
{ {
/**
* The API data associated with this subcommand group.
*
* @internal
*/
declare protected readonly data: ChatInputCommandSubcommandGroupData & SharedNameAndDescriptionData; declare protected readonly data: ChatInputCommandSubcommandGroupData & SharedNameAndDescriptionData;
/**
* The options within this subcommand group.
*/
public get options(): readonly ChatInputCommandSubcommandBuilder[] { public get options(): readonly ChatInputCommandSubcommandBuilder[] {
return (this.data.options ??= []); return (this.data.options ??= []);
} }
@@ -78,6 +86,8 @@ export class ChatInputCommandSubcommandGroupBuilder
/** /**
* A builder that creates API-compatible JSON data for chat input command subcommands. * A builder that creates API-compatible JSON data for chat input command subcommands.
* *
* @mixes {@link SharedNameAndDescription}
* @mixes {@link SharedChatInputCommandOptions}
* @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}
*/ */
export class ChatInputCommandSubcommandBuilder export class ChatInputCommandSubcommandBuilder

View File

@@ -7,6 +7,9 @@ export interface ApplicationCommandNumericOptionMinMaxValueData
* This mixin holds minimum and maximum symbols used for options. * This mixin holds minimum and maximum symbols used for options.
*/ */
export abstract class ApplicationCommandNumericOptionMinMaxValueMixin { export abstract class ApplicationCommandNumericOptionMinMaxValueMixin {
/**
* @internal
*/
declare protected readonly data: ApplicationCommandNumericOptionMinMaxValueData; declare protected readonly data: ApplicationCommandNumericOptionMinMaxValueData;
/** /**

View File

@@ -26,6 +26,9 @@ export interface ApplicationCommandOptionChannelTypesData
* This mixin holds channel type symbols used for options. * This mixin holds channel type symbols used for options.
*/ */
export class ApplicationCommandOptionChannelTypesMixin { export class ApplicationCommandOptionChannelTypesMixin {
/**
* @internal
*/
declare protected readonly data: ApplicationCommandOptionChannelTypesData; declare protected readonly data: ApplicationCommandOptionChannelTypesData;
/** /**

View File

@@ -15,6 +15,9 @@ export interface ApplicationCommandOptionWithAutocompleteData extends Pick<Autoc
* This mixin holds choices and autocomplete symbols used for options. * This mixin holds choices and autocomplete symbols used for options.
*/ */
export class ApplicationCommandOptionWithAutocompleteMixin { export class ApplicationCommandOptionWithAutocompleteMixin {
/**
* @internal
*/
declare protected readonly data: ApplicationCommandOptionWithAutocompleteData; declare protected readonly data: ApplicationCommandOptionWithAutocompleteData;
/** /**

View File

@@ -8,8 +8,13 @@ export interface ApplicationCommandOptionWithChoicesData {
/** /**
* This mixin holds choices and autocomplete symbols used for options. * This mixin holds choices and autocomplete symbols used for options.
*
* @typeParam ChoiceType - The type of the choices within this option
*/ */
export class ApplicationCommandOptionWithChoicesMixin<ChoiceType extends number | string> { export class ApplicationCommandOptionWithChoicesMixin<ChoiceType extends number | string> {
/**
* @internal
*/
declare protected readonly data: ApplicationCommandOptionWithChoicesData; declare protected readonly data: ApplicationCommandOptionWithChoicesData;
/** /**

View File

@@ -17,12 +17,16 @@ export interface SharedChatInputCommandOptionsData {
/** /**
* This mixin holds symbols that can be shared in chat input command options. * This mixin holds symbols that can be shared in chat input command options.
*
* @typeParam TypeAfterAddingOptions - The type this class should return after adding an option.
*/ */
export class SharedChatInputCommandOptions { export class SharedChatInputCommandOptions {
/**
* @internal
*/
declare protected readonly data: SharedChatInputCommandOptionsData; declare protected readonly data: SharedChatInputCommandOptionsData;
/**
* The options within this command.
*/
public get options(): readonly ApplicationCommandOptionBase[] { public get options(): readonly ApplicationCommandOptionBase[] {
return (this.data.options ??= []); return (this.data.options ??= []);
} }

View File

@@ -12,10 +12,11 @@ export interface SharedChatInputCommandSubcommandsData {
/** /**
* This mixin holds symbols that can be shared in chat input subcommands. * This mixin holds symbols that can be shared in chat input subcommands.
*
* @typeParam TypeAfterAddingSubcommands - The type this class should return after adding a subcommand or subcommand group.
*/ */
export class SharedChatInputCommandSubcommands { export class SharedChatInputCommandSubcommands {
/**
* @internal
*/
declare protected readonly data: SharedChatInputCommandSubcommandsData; declare protected readonly data: SharedChatInputCommandSubcommandsData;
/** /**

View File

@@ -21,10 +21,21 @@ export abstract class ApplicationCommandOptionBase
extends SharedNameAndDescription extends SharedNameAndDescription
implements JSONEncodable<APIApplicationCommandBasicOption> implements JSONEncodable<APIApplicationCommandBasicOption>
{ {
/**
* @internal
*/
protected static readonly predicate: z.ZodTypeAny = basicOptionPredicate; protected static readonly predicate: z.ZodTypeAny = basicOptionPredicate;
/**
* @internal
*/
declare protected readonly data: ApplicationCommandOptionBaseData & SharedNameAndDescriptionData; declare protected readonly data: ApplicationCommandOptionBaseData & SharedNameAndDescriptionData;
/**
* Creates a new application command option builder.
*
* @param type - The type of the option
*/
public constructor(type: ApplicationCommandOptionType) { public constructor(type: ApplicationCommandOptionType) {
super(); super();
this.data.type = type; this.data.type = type;

View File

@@ -5,6 +5,9 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
* A chat input command attachment option. * A chat input command attachment option.
*/ */
export class ChatInputCommandAttachmentOption extends ApplicationCommandOptionBase { export class ChatInputCommandAttachmentOption extends ApplicationCommandOptionBase {
/**
* Creates a new attachment option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.Attachment); super(ApplicationCommandOptionType.Attachment);
} }

View File

@@ -5,6 +5,9 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
* A chat input command boolean option. * A chat input command boolean option.
*/ */
export class ChatInputCommandBooleanOption extends ApplicationCommandOptionBase { export class ChatInputCommandBooleanOption extends ApplicationCommandOptionBase {
/**
* Creates a new boolean option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.Boolean); super(ApplicationCommandOptionType.Boolean);
} }

View File

@@ -6,13 +6,22 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
/** /**
* A chat input command channel option. * A chat input command channel option.
*
* @mixes {@link ApplicationCommandOptionBase}
* @mixes {@link ApplicationCommandOptionChannelTypesMixin}
*/ */
export class ChatInputCommandChannelOption extends Mixin( export class ChatInputCommandChannelOption extends Mixin(
ApplicationCommandOptionBase, ApplicationCommandOptionBase,
ApplicationCommandOptionChannelTypesMixin, ApplicationCommandOptionChannelTypesMixin,
) { ) {
/**
* @internal
*/
protected static override readonly predicate = channelOptionPredicate; protected static override readonly predicate = channelOptionPredicate;
/**
* Creates a new channel option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.Channel); super(ApplicationCommandOptionType.Channel);
} }

View File

@@ -8,6 +8,11 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
/** /**
* A chat input command integer option. * A chat input command integer option.
*
* @mixes {@link ApplicationCommandOptionBase}
* @mixes {@link ApplicationCommandNumericOptionMinMaxValueMixin}
* @mixes {@link ApplicationCommandOptionWithAutocompleteMixin}
* @mixes {@link ApplicationCommandOptionWithChoicesMixin}\<number\>
*/ */
export class ChatInputCommandIntegerOption extends Mixin( export class ChatInputCommandIntegerOption extends Mixin(
ApplicationCommandOptionBase, ApplicationCommandOptionBase,
@@ -15,8 +20,14 @@ export class ChatInputCommandIntegerOption extends Mixin(
ApplicationCommandOptionWithAutocompleteMixin, ApplicationCommandOptionWithAutocompleteMixin,
ApplicationCommandOptionWithChoicesMixin<number>, ApplicationCommandOptionWithChoicesMixin<number>,
) { ) {
/**
* @internal
*/
protected static override readonly predicate = integerOptionPredicate; protected static override readonly predicate = integerOptionPredicate;
/**
* Creates a new integer option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.Integer); super(ApplicationCommandOptionType.Integer);
} }

View File

@@ -5,6 +5,9 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
* A chat input command mentionable option. * A chat input command mentionable option.
*/ */
export class ChatInputCommandMentionableOption extends ApplicationCommandOptionBase { export class ChatInputCommandMentionableOption extends ApplicationCommandOptionBase {
/**
* Creates a new mentionable option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.Mentionable); super(ApplicationCommandOptionType.Mentionable);
} }

View File

@@ -8,6 +8,11 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
/** /**
* A chat input command number option. * A chat input command number option.
*
* @mixes {@link ApplicationCommandOptionBase}
* @mixes {@link ApplicationCommandNumericOptionMinMaxValueMixin}
* @mixes {@link ApplicationCommandOptionWithAutocompleteMixin}
* @mixes {@link ApplicationCommandOptionWithChoicesMixin}\<number\>
*/ */
export class ChatInputCommandNumberOption extends Mixin( export class ChatInputCommandNumberOption extends Mixin(
ApplicationCommandOptionBase, ApplicationCommandOptionBase,
@@ -15,8 +20,14 @@ export class ChatInputCommandNumberOption extends Mixin(
ApplicationCommandOptionWithAutocompleteMixin, ApplicationCommandOptionWithAutocompleteMixin,
ApplicationCommandOptionWithChoicesMixin<number>, ApplicationCommandOptionWithChoicesMixin<number>,
) { ) {
/**
* @internal
*/
protected static override readonly predicate = numberOptionPredicate; protected static override readonly predicate = numberOptionPredicate;
/**
* Creates a new number option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.Number); super(ApplicationCommandOptionType.Number);
} }

View File

@@ -5,6 +5,9 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
* A chat input command role option. * A chat input command role option.
*/ */
export class ChatInputCommandRoleOption extends ApplicationCommandOptionBase { export class ChatInputCommandRoleOption extends ApplicationCommandOptionBase {
/**
* Creates a new role option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.Role); super(ApplicationCommandOptionType.Role);
} }

View File

@@ -10,19 +10,32 @@ import type { ApplicationCommandOptionBaseData } from './ApplicationCommandOptio
/** /**
* A chat input command string option. * A chat input command string option.
*
* @mixes {@link ApplicationCommandOptionBase}
* @mixes {@link ApplicationCommandOptionWithAutocompleteMixin}
* @mixes {@link ApplicationCommandOptionWithChoicesMixin}\<string\>
*/ */
export class ChatInputCommandStringOption extends Mixin( export class ChatInputCommandStringOption extends Mixin(
ApplicationCommandOptionBase, ApplicationCommandOptionBase,
ApplicationCommandOptionWithAutocompleteMixin, ApplicationCommandOptionWithAutocompleteMixin,
ApplicationCommandOptionWithChoicesMixin<string>, ApplicationCommandOptionWithChoicesMixin<string>,
) { ) {
/**
* @internal
*/
protected static override readonly predicate = stringOptionPredicate; protected static override readonly predicate = stringOptionPredicate;
/**
* @internal
*/
declare protected readonly data: ApplicationCommandOptionBaseData & declare protected readonly data: ApplicationCommandOptionBaseData &
ApplicationCommandOptionWithAutocompleteData & ApplicationCommandOptionWithAutocompleteData &
ApplicationCommandOptionWithChoicesData & ApplicationCommandOptionWithChoicesData &
Partial<Pick<APIApplicationCommandStringOption, 'max_length' | 'min_length'>>; Partial<Pick<APIApplicationCommandStringOption, 'max_length' | 'min_length'>>;
/**
* Creates a new string option builder.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.String); super(ApplicationCommandOptionType.String);
} }

View File

@@ -5,6 +5,9 @@ import { ApplicationCommandOptionBase } from './ApplicationCommandOptionBase.js'
* A chat input command user option. * A chat input command user option.
*/ */
export class ChatInputCommandUserOption extends ApplicationCommandOptionBase { export class ChatInputCommandUserOption extends ApplicationCommandOptionBase {
/**
* Creates a new user option.
*/
public constructor() { public constructor() {
super(ApplicationCommandOptionType.User); super(ApplicationCommandOptionType.User);
} }

View File

@@ -10,13 +10,26 @@ export type ContextMenuCommandType = ApplicationCommandType.Message | Applicatio
/** /**
* A builder that creates API-compatible JSON data for context menu commands. * A builder that creates API-compatible JSON data for context menu commands.
*
* @mixes {@link CommandBuilder}\<{@link discord-api-types/v10#(RESTPostAPIContextMenuApplicationCommandsJSONBody:interface)}\>
* @mixes {@link SharedName}
*/ */
export abstract class ContextMenuCommandBuilder extends Mixin( export abstract class ContextMenuCommandBuilder extends Mixin(
CommandBuilder<RESTPostAPIContextMenuApplicationCommandsJSONBody>, CommandBuilder<RESTPostAPIContextMenuApplicationCommandsJSONBody>,
SharedName, SharedName,
) { ) {
/**
* The API data associated with this context menu command.
*
* @internal
*/
protected override readonly data: Partial<RESTPostAPIContextMenuApplicationCommandsJSONBody>; protected override readonly data: Partial<RESTPostAPIContextMenuApplicationCommandsJSONBody>;
/**
* Creates a new context menu command.
*
* @param data - The API data to create this context menu command with
*/
public constructor(data: Partial<RESTPostAPIContextMenuApplicationCommandsJSONBody> = {}) { public constructor(data: Partial<RESTPostAPIContextMenuApplicationCommandsJSONBody> = {}) {
super(); super();
this.data = structuredClone(data); this.data = structuredClone(data);

View File

@@ -3,6 +3,9 @@ import { validate } from '../../../util/validation.js';
import { messageCommandPredicate } from './Assertions.js'; import { messageCommandPredicate } from './Assertions.js';
import { ContextMenuCommandBuilder } from './ContextMenuCommand.js'; import { ContextMenuCommandBuilder } from './ContextMenuCommand.js';
/**
* A builder that creates API-compatible JSON data for message context menu commands.
*/
export class MessageContextCommandBuilder extends ContextMenuCommandBuilder { export class MessageContextCommandBuilder extends ContextMenuCommandBuilder {
/** /**
* {@inheritDoc CommandBuilder.toJSON} * {@inheritDoc CommandBuilder.toJSON}

View File

@@ -3,6 +3,9 @@ import { validate } from '../../../util/validation.js';
import { userCommandPredicate } from './Assertions.js'; import { userCommandPredicate } from './Assertions.js';
import { ContextMenuCommandBuilder } from './ContextMenuCommand.js'; import { ContextMenuCommandBuilder } from './ContextMenuCommand.js';
/**
* A builder that creates API-compatible JSON data for user context menu commands.
*/
export class UserContextCommandBuilder extends ContextMenuCommandBuilder { export class UserContextCommandBuilder extends ContextMenuCommandBuilder {
/** /**
* {@inheritDoc CommandBuilder.toJSON} * {@inheritDoc CommandBuilder.toJSON}

View File

@@ -1,5 +1,3 @@
/* eslint-disable jsdoc/check-param-names */
import type { JSONEncodable } from '@discordjs/util'; import type { JSONEncodable } from '@discordjs/util';
import type { import type {
APIActionRowComponent, APIActionRowComponent,
@@ -34,13 +32,15 @@ export class ModalBuilder implements JSONEncodable<APIModalInteractionResponseCa
} }
/** /**
* Creates a new modal from API data. * Creates a new modal.
* *
* @param data - The API data to create this modal with * @param data - The API data to create this modal with
*/ */
public constructor({ components = [], ...data }: Partial<APIModalInteractionResponseCallbackData> = {}) { public constructor(data: Partial<APIModalInteractionResponseCallbackData> = {}) {
const { components = [], ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
components: components.map((component) => createComponentBuilder(component)), components: components.map((component) => createComponentBuilder(component)),
}; };
} }

View File

@@ -8,12 +8,15 @@ import { allowedMentionPredicate } from './Assertions.js';
* A builder that creates API-compatible JSON data for allowed mentions. * A builder that creates API-compatible JSON data for allowed mentions.
*/ */
export class AllowedMentionsBuilder implements JSONEncodable<APIAllowedMentions> { export class AllowedMentionsBuilder implements JSONEncodable<APIAllowedMentions> {
/**
* The API data associated with these allowed mentions.
*/
private readonly data: Partial<APIAllowedMentions>; private readonly data: Partial<APIAllowedMentions>;
/** /**
* Creates a new allowed mentions builder from API data. * Creates a new allowed mentions builder.
* *
* @param data - The API data to create this allowed mentions builder with * @param data - The API data to create this allowed mentions with
*/ */
public constructor(data: Partial<APIAllowedMentions> = {}) { public constructor(data: Partial<APIAllowedMentions> = {}) {
this.data = structuredClone(data); this.data = structuredClone(data);

View File

@@ -7,12 +7,15 @@ import { attachmentPredicate } from './Assertions.js';
* A builder that creates API-compatible JSON data for attachments. * A builder that creates API-compatible JSON data for attachments.
*/ */
export class AttachmentBuilder implements JSONEncodable<RESTAPIAttachment> { export class AttachmentBuilder implements JSONEncodable<RESTAPIAttachment> {
/**
* The API data associated with this attachment.
*/
private readonly data: Partial<RESTAPIAttachment>; private readonly data: Partial<RESTAPIAttachment>;
/** /**
* Creates a new attachment builder from API data. * Creates a new attachment builder.
* *
* @param data - The API data to create this attachment builder with * @param data - The API data to create this attachment with
*/ */
public constructor(data: Partial<RESTAPIAttachment> = {}) { public constructor(data: Partial<RESTAPIAttachment> = {}) {
this.data = structuredClone(data); this.data = structuredClone(data);

View File

@@ -1,5 +1,3 @@
/* eslint-disable jsdoc/check-param-names */
import type { JSONEncodable } from '@discordjs/util'; import type { JSONEncodable } from '@discordjs/util';
import type { import type {
APIActionRowComponent, APIActionRowComponent,
@@ -86,21 +84,15 @@ export class MessageBuilder implements JSONEncodable<RESTPostAPIChannelMessageJS
} }
/** /**
* Creates a new message builder from API data. * Creates a new message builder.
* *
* @param data - The API data to create this message builder with * @param data - The API data to create this message with
*/ */
public constructor({ public constructor(data: Partial<RESTPostAPIChannelMessageJSONBody> = {}) {
attachments = [], const { attachments = [], embeds = [], components = [], message_reference, poll, allowed_mentions, ...rest } = data;
embeds = [],
components = [],
message_reference,
poll,
allowed_mentions,
...data
}: Partial<RESTPostAPIChannelMessageJSONBody> = {}) {
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
allowed_mentions: allowed_mentions && new AllowedMentionsBuilder(allowed_mentions), allowed_mentions: allowed_mentions && new AllowedMentionsBuilder(allowed_mentions),
attachments: attachments.map((attachment) => new AttachmentBuilder(attachment)), attachments: attachments.map((attachment) => new AttachmentBuilder(attachment)),
embeds: embeds.map((embed) => new EmbedBuilder(embed)), embeds: embeds.map((embed) => new EmbedBuilder(embed)),

View File

@@ -7,12 +7,15 @@ import { messageReferencePredicate } from './Assertions.js';
* A builder that creates API-compatible JSON data for message references. * A builder that creates API-compatible JSON data for message references.
*/ */
export class MessageReferenceBuilder implements JSONEncodable<RESTAPIMessageReference> { export class MessageReferenceBuilder implements JSONEncodable<RESTAPIMessageReference> {
/**
* The API data associated with this message reference.
*/
private readonly data: Partial<RESTAPIMessageReference>; private readonly data: Partial<RESTAPIMessageReference>;
/** /**
* Creates a new message reference builder from API data. * Creates a new message reference builder.
* *
* @param data - The API data to create this message reference builder with * @param data - The API data to create this message reference with
*/ */
public constructor(data: Partial<RESTAPIMessageReference> = {}) { public constructor(data: Partial<RESTAPIMessageReference> = {}) {
this.data = structuredClone(data); this.data = structuredClone(data);

View File

@@ -35,16 +35,18 @@ export class EmbedBuilder implements JSONEncodable<APIEmbed> {
} }
/** /**
* Creates a new embed from API data. * Creates a new embed.
* *
* @param data - The API data to create this embed with * @param data - The API data to create this embed with
*/ */
public constructor(data: APIEmbed = {}) { public constructor(data: Partial<APIEmbed> = {}) {
const { author, fields = [], footer, ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
author: data.author && new EmbedAuthorBuilder(data.author), author: author && new EmbedAuthorBuilder(author),
fields: data.fields?.map((field) => new EmbedFieldBuilder(field)) ?? [], fields: fields.map((field) => new EmbedFieldBuilder(field)),
footer: data.footer && new EmbedFooterBuilder(data.footer), footer: footer && new EmbedFooterBuilder(footer),
}; };
} }
@@ -338,9 +340,9 @@ export class EmbedBuilder implements JSONEncodable<APIEmbed> {
const data = { const data = {
...structuredClone(rest), ...structuredClone(rest),
// Disable validation because the embedPredicate below will validate those as well // Disable validation because the embedPredicate below will validate those as well
author: this.data.author?.toJSON(false), author: author?.toJSON(false),
fields: this.data.fields?.map((field) => field.toJSON(false)), fields: fields.map((field) => field.toJSON(false)),
footer: this.data.footer?.toJSON(false), footer: footer?.toJSON(false),
}; };
validate(embedPredicate, data, validationOverride); validate(embedPredicate, data, validationOverride);

View File

@@ -7,15 +7,18 @@ import { embedAuthorPredicate } from './Assertions.js';
* A builder that creates API-compatible JSON data for the embed author. * A builder that creates API-compatible JSON data for the embed author.
*/ */
export class EmbedAuthorBuilder implements JSONEncodable<APIEmbedAuthor> { export class EmbedAuthorBuilder implements JSONEncodable<APIEmbedAuthor> {
/**
* The API data associated with this embed author.
*/
private readonly data: Partial<APIEmbedAuthor>; private readonly data: Partial<APIEmbedAuthor>;
/** /**
* Creates a new embed author from API data. * Creates a new embed author.
* *
* @param data - The API data to use * @param data - The API data to create this embed author with
*/ */
public constructor(data?: Partial<APIEmbedAuthor>) { public constructor(data: Partial<APIEmbedAuthor> = {}) {
this.data = structuredClone(data) ?? {}; this.data = structuredClone(data);
} }
/** /**

View File

@@ -7,15 +7,18 @@ import { embedFieldPredicate } from './Assertions.js';
* A builder that creates API-compatible JSON data for embed fields. * A builder that creates API-compatible JSON data for embed fields.
*/ */
export class EmbedFieldBuilder implements JSONEncodable<APIEmbedField> { export class EmbedFieldBuilder implements JSONEncodable<APIEmbedField> {
/**
* The API data associated with this embed field.
*/
private readonly data: Partial<APIEmbedField>; private readonly data: Partial<APIEmbedField>;
/** /**
* Creates a new embed field from API data. * Creates a new embed field.
* *
* @param data - The API data to use * @param data - The API data to create this embed field with
*/ */
public constructor(data?: Partial<APIEmbedField>) { public constructor(data: Partial<APIEmbedField> = {}) {
this.data = structuredClone(data) ?? {}; this.data = structuredClone(data);
} }
/** /**

View File

@@ -7,15 +7,18 @@ import { embedFooterPredicate } from './Assertions.js';
* A builder that creates API-compatible JSON data for the embed footer. * A builder that creates API-compatible JSON data for the embed footer.
*/ */
export class EmbedFooterBuilder implements JSONEncodable<APIEmbedFooter> { export class EmbedFooterBuilder implements JSONEncodable<APIEmbedFooter> {
/**
* The API data associated with this embed footer.
*/
private readonly data: Partial<APIEmbedFooter>; private readonly data: Partial<APIEmbedFooter>;
/** /**
* Creates a new embed footer from API data. * Creates a new embed footer.
* *
* @param data - The API data to use * @param data - The API data to create this embed footer with
*/ */
public constructor(data?: Partial<APIEmbedFooter>) { public constructor(data: Partial<APIEmbedFooter> = {}) {
this.data = structuredClone(data) ?? {}; this.data = structuredClone(data);
} }
/** /**

View File

@@ -29,15 +29,17 @@ export class PollBuilder implements JSONEncodable<RESTAPIPoll> {
} }
/** /**
* Creates a new poll from API data. * Creates a new poll.
* *
* @param data - The API data to create this poll with * @param data - The API data to create this poll with
*/ */
public constructor(data: Partial<RESTAPIPoll> = {}) { public constructor(data: Partial<RESTAPIPoll> = {}) {
const { question, answers = [], ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
question: new PollQuestionBuilder(data.question), question: new PollQuestionBuilder(question),
answers: data.answers?.map((answer) => new PollAnswerBuilder(answer)) ?? [], answers: answers.map((answer) => new PollAnswerBuilder(answer)),
}; };
} }

View File

@@ -9,6 +9,9 @@ export interface PollAnswerData extends Omit<APIPollAnswer, 'answer_id' | 'poll_
poll_media: PollAnswerMediaBuilder; poll_media: PollAnswerMediaBuilder;
} }
/**
* A builder that creates API-compatible JSON data for poll answers.
*/
export class PollAnswerBuilder implements JSONEncodable<Omit<APIPollAnswer, 'answer_id'>> { export class PollAnswerBuilder implements JSONEncodable<Omit<APIPollAnswer, 'answer_id'>> {
/** /**
* The API data associated with this poll answer. * The API data associated with this poll answer.
@@ -16,14 +19,16 @@ export class PollAnswerBuilder implements JSONEncodable<Omit<APIPollAnswer, 'ans
private readonly data: PollAnswerData; private readonly data: PollAnswerData;
/** /**
* Creates a new poll answer from API data. * Creates a new poll answer.
* *
* @param data - The API data to create this poll answer with * @param data - The API data to create this poll answer with
*/ */
public constructor(data: Partial<Omit<APIPollAnswer, 'answer_id'>> = {}) { public constructor(data: Partial<Omit<APIPollAnswer, 'answer_id'>> = {}) {
const { poll_media, ...rest } = data;
this.data = { this.data = {
...structuredClone(data), ...structuredClone(rest),
poll_media: new PollAnswerMediaBuilder(data.poll_media), poll_media: new PollAnswerMediaBuilder(poll_media),
}; };
} }

View File

@@ -6,13 +6,15 @@ import type { APIPollMedia } from 'discord-api-types/v10';
export abstract class PollMediaBuilder { export abstract class PollMediaBuilder {
/** /**
* The API data associated with this poll media. * The API data associated with this poll media.
*
* @internal
*/ */
protected readonly data: Partial<APIPollMedia>; protected readonly data: Partial<APIPollMedia>;
/** /**
* Creates new poll media from API data. * Creates new poll media.
* *
* @param data - The API data to use * @param data - The API data to create this poll media with
*/ */
public constructor(data: Partial<APIPollMedia> = {}) { public constructor(data: Partial<APIPollMedia> = {}) {
this.data = structuredClone(data); this.data = structuredClone(data);

View File

@@ -211,11 +211,11 @@ export class Client extends AsyncEventEmitter<MappedEvents> {
public readonly api: API; public readonly api: API;
public constructor({ rest, gateway }: ClientOptions) { public constructor(options: ClientOptions) {
super(); super();
this.rest = rest; this.rest = options.rest;
this.gateway = gateway; this.gateway = options.gateway;
this.api = new API(rest); this.api = new API(this.rest);
this.gateway.on(WebSocketShardEvents.Dispatch, (dispatch, shardId) => { this.gateway.on(WebSocketShardEvents.Dispatch, (dispatch, shardId) => {
this.emit(dispatch.t, this.toEventProps(dispatch.d, shardId)); this.emit(dispatch.t, this.toEventProps(dispatch.d, shardId));

View File

@@ -23,31 +23,19 @@ export class RateLimitError extends Error implements RateLimitData {
public scope: RateLimitData['scope']; public scope: RateLimitData['scope'];
public constructor({ public constructor(data: RateLimitData) {
timeToReset,
limit,
method,
hash,
url,
route,
majorParameter,
global,
retryAfter,
sublimitTimeout,
scope,
}: RateLimitData) {
super(); super();
this.timeToReset = timeToReset; this.timeToReset = data.timeToReset;
this.limit = limit; this.limit = data.limit;
this.method = method; this.method = data.method;
this.hash = hash; this.hash = data.hash;
this.url = url; this.url = data.url;
this.route = route; this.route = data.route;
this.majorParameter = majorParameter; this.majorParameter = data.majorParameter;
this.global = global; this.global = data.global;
this.retryAfter = retryAfter; this.retryAfter = data.retryAfter;
this.sublimitTimeout = sublimitTimeout; this.sublimitTimeout = data.sublimitTimeout;
this.scope = scope; this.scope = data.scope;
} }
/** /**

View File

@@ -56,9 +56,11 @@ export class AudioReceiveStream extends Readable {
private endTimeout?: NodeJS.Timeout; private endTimeout?: NodeJS.Timeout;
public constructor({ end, ...options }: AudioReceiveStreamOptions) { public constructor(options: AudioReceiveStreamOptions) {
const { end, ...rest } = options;
super({ super({
...options, ...rest,
objectMode: true, objectMode: true,
}); });