mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-12 09:33:32 +01:00
refactor: builders (#10448)
BREAKING CHANGE: formatters export removed (prev. deprecated) BREAKING CHANGE: `SelectMenuBuilder` and `SelectMenuOptionBuilder` have been removed (prev. deprecated) BREAKING CHANGE: `EmbedBuilder` no longer takes camalCase options BREAKING CHANGE: `ActionRowBuilder` now has specialized `[add/set]X` methods as opposed to the current `[add/set]Components` BREAKING CHANGE: Removed `equals` methods BREAKING CHANGE: Sapphire -> zod for validation BREAKING CHANGE: Removed the ability to pass `null`/`undefined` to clear fields, use `clearX()` instead BREAKING CHANGE: Renamed all "slash command" symbols to instead use "chat input command" BREAKING CHANGE: Removed `ContextMenuCommandBuilder` in favor of `MessageCommandBuilder` and `UserCommandBuilder` BREAKING CHANGE: Removed support for passing the "string key"s of enums BREAKING CHANGE: Removed `Button` class in favor for specialized classes depending on the style BREAKING CHANGE: Removed nested `addX` styled-methods in favor of plural `addXs` Co-authored-by: Vlad Frangu <me@vladfrangu.dev> Co-authored-by: Almeida <github@almeidx.dev>
This commit is contained in:
@@ -1,32 +1,15 @@
|
||||
import { s } from '@sapphire/shapeshift';
|
||||
import { TextInputStyle } from 'discord-api-types/v10';
|
||||
import { isValidationEnabled } from '../../util/validation.js';
|
||||
import { customIdValidator } from '../Assertions.js';
|
||||
import { ComponentType, TextInputStyle } from 'discord-api-types/v10';
|
||||
import { z } from 'zod';
|
||||
import { customIdPredicate } from '../../Assertions.js';
|
||||
|
||||
export const textInputStyleValidator = s.nativeEnum(TextInputStyle);
|
||||
export const minLengthValidator = s
|
||||
.number()
|
||||
.int()
|
||||
.greaterThanOrEqual(0)
|
||||
.lessThanOrEqual(4_000)
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
export const maxLengthValidator = s
|
||||
.number()
|
||||
.int()
|
||||
.greaterThanOrEqual(1)
|
||||
.lessThanOrEqual(4_000)
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
export const requiredValidator = s.boolean();
|
||||
export const valueValidator = s.string().lengthLessThanOrEqual(4_000).setValidationEnabled(isValidationEnabled);
|
||||
export const placeholderValidator = s.string().lengthLessThanOrEqual(100).setValidationEnabled(isValidationEnabled);
|
||||
export const labelValidator = s
|
||||
.string()
|
||||
.lengthGreaterThanOrEqual(1)
|
||||
.lengthLessThanOrEqual(45)
|
||||
.setValidationEnabled(isValidationEnabled);
|
||||
|
||||
export function validateRequiredParameters(customId?: string, style?: TextInputStyle, label?: string) {
|
||||
customIdValidator.parse(customId);
|
||||
textInputStyleValidator.parse(style);
|
||||
labelValidator.parse(label);
|
||||
}
|
||||
export const textInputPredicate = z.object({
|
||||
type: z.literal(ComponentType.TextInput),
|
||||
custom_id: customIdPredicate,
|
||||
label: z.string().min(1).max(45),
|
||||
style: z.nativeEnum(TextInputStyle),
|
||||
min_length: z.number().min(0).max(4_000).optional(),
|
||||
max_length: z.number().min(1).max(4_000).optional(),
|
||||
placeholder: z.string().max(100).optional(),
|
||||
value: z.string().max(4_000).optional(),
|
||||
required: z.boolean().optional(),
|
||||
});
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
import { isJSONEncodable, type Equatable, type JSONEncodable } from '@discordjs/util';
|
||||
import { ComponentType, type TextInputStyle, type APITextInputComponent } from 'discord-api-types/v10';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { customIdValidator } from '../Assertions.js';
|
||||
import { isValidationEnabled } from '../../util/validation.js';
|
||||
import { ComponentBuilder } from '../Component.js';
|
||||
import {
|
||||
maxLengthValidator,
|
||||
minLengthValidator,
|
||||
placeholderValidator,
|
||||
requiredValidator,
|
||||
valueValidator,
|
||||
validateRequiredParameters,
|
||||
labelValidator,
|
||||
textInputStyleValidator,
|
||||
} from './Assertions.js';
|
||||
import { textInputPredicate } from './Assertions.js';
|
||||
|
||||
/**
|
||||
* A builder that creates API-compatible JSON data for text inputs.
|
||||
*/
|
||||
export class TextInputBuilder
|
||||
extends ComponentBuilder<APITextInputComponent>
|
||||
implements Equatable<APITextInputComponent | JSONEncodable<APITextInputComponent>>
|
||||
{
|
||||
export class TextInputBuilder extends ComponentBuilder<APITextInputComponent> {
|
||||
private readonly data: Partial<APITextInputComponent>;
|
||||
|
||||
/**
|
||||
* Creates a new text input from API data.
|
||||
*
|
||||
@@ -44,8 +32,9 @@ export class TextInputBuilder
|
||||
* .setStyle(TextInputStyle.Paragraph);
|
||||
* ```
|
||||
*/
|
||||
public constructor(data?: APITextInputComponent & { type?: ComponentType.TextInput }) {
|
||||
super({ type: ComponentType.TextInput, ...data });
|
||||
public constructor(data: Partial<APITextInputComponent> = {}) {
|
||||
super();
|
||||
this.data = { ...structuredClone(data), type: ComponentType.TextInput };
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -54,7 +43,7 @@ export class TextInputBuilder
|
||||
* @param customId - The custom id to use
|
||||
*/
|
||||
public setCustomId(customId: string) {
|
||||
this.data.custom_id = customIdValidator.parse(customId);
|
||||
this.data.custom_id = customId;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -64,7 +53,7 @@ export class TextInputBuilder
|
||||
* @param label - The label to use
|
||||
*/
|
||||
public setLabel(label: string) {
|
||||
this.data.label = labelValidator.parse(label);
|
||||
this.data.label = label;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -74,7 +63,7 @@ export class TextInputBuilder
|
||||
* @param style - The style to use
|
||||
*/
|
||||
public setStyle(style: TextInputStyle) {
|
||||
this.data.style = textInputStyleValidator.parse(style);
|
||||
this.data.style = style;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -84,7 +73,15 @@ export class TextInputBuilder
|
||||
* @param minLength - The minimum length of text for this text input
|
||||
*/
|
||||
public setMinLength(minLength: number) {
|
||||
this.data.min_length = minLengthValidator.parse(minLength);
|
||||
this.data.min_length = minLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the minimum length of text for this text input.
|
||||
*/
|
||||
public clearMinLength() {
|
||||
this.data.min_length = undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -94,7 +91,15 @@ export class TextInputBuilder
|
||||
* @param maxLength - The maximum length of text for this text input
|
||||
*/
|
||||
public setMaxLength(maxLength: number) {
|
||||
this.data.max_length = maxLengthValidator.parse(maxLength);
|
||||
this.data.max_length = maxLength;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the maximum length of text for this text input.
|
||||
*/
|
||||
public clearMaxLength() {
|
||||
this.data.max_length = undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -104,7 +109,15 @@ export class TextInputBuilder
|
||||
* @param placeholder - The placeholder to use
|
||||
*/
|
||||
public setPlaceholder(placeholder: string) {
|
||||
this.data.placeholder = placeholderValidator.parse(placeholder);
|
||||
this.data.placeholder = placeholder;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the placeholder for this text input.
|
||||
*/
|
||||
public clearPlaceholder() {
|
||||
this.data.placeholder = undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -114,7 +127,15 @@ export class TextInputBuilder
|
||||
* @param value - The value to use
|
||||
*/
|
||||
public setValue(value: string) {
|
||||
this.data.value = valueValidator.parse(value);
|
||||
this.data.value = value;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the value for this text input.
|
||||
*/
|
||||
public clearValue() {
|
||||
this.data.value = undefined;
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -124,29 +145,20 @@ export class TextInputBuilder
|
||||
* @param required - Whether this text input is required
|
||||
*/
|
||||
public setRequired(required = true) {
|
||||
this.data.required = requiredValidator.parse(required);
|
||||
this.data.required = required;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc ComponentBuilder.toJSON}
|
||||
*/
|
||||
public toJSON(): APITextInputComponent {
|
||||
validateRequiredParameters(this.data.custom_id, this.data.style, this.data.label);
|
||||
public toJSON(validationOverride?: boolean): APITextInputComponent {
|
||||
const clone = structuredClone(this.data);
|
||||
|
||||
return {
|
||||
...this.data,
|
||||
} as APITextInputComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this is equal to another structure.
|
||||
*/
|
||||
public equals(other: APITextInputComponent | JSONEncodable<APITextInputComponent>): boolean {
|
||||
if (isJSONEncodable(other)) {
|
||||
return isEqual(other.toJSON(), this.data);
|
||||
if (validationOverride ?? isValidationEnabled()) {
|
||||
textInputPredicate.parse(clone);
|
||||
}
|
||||
|
||||
return isEqual(other, this.data);
|
||||
return clone as APITextInputComponent;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user