Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(builders): update to @sapphire/shapeshift v4 #10291

Merged
merged 1 commit into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/builders/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"dependencies": {
"@discordjs/formatters": "workspace:^",
"@discordjs/util": "workspace:^",
"@sapphire/shapeshift": "^3.9.7",
"@sapphire/shapeshift": "^4.0.0",
"discord-api-types": "0.37.94",
"fast-deep-equal": "^3.1.3",
"ts-mixer": "^6.0.4",
Expand Down
47 changes: 29 additions & 18 deletions packages/builders/src/components/Assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,42 @@ import { ButtonStyle, ChannelType, type APIMessageComponentEmoji } from 'discord
import { isValidationEnabled } from '../util/validation.js';
import { StringSelectMenuOptionBuilder } from './selectMenu/StringSelectMenuOption.js';

export const customIdValidator = s.string
export const customIdValidator = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(100)
.setValidationEnabled(isValidationEnabled);

export const emojiValidator = s
.object({
id: s.string,
name: s.string,
animated: s.boolean,
id: s.string(),
name: s.string(),
animated: s.boolean(),
})
.partial.strict.setValidationEnabled(isValidationEnabled);
.partial()
.strict()
.setValidationEnabled(isValidationEnabled);

export const disabledValidator = s.boolean;
export const disabledValidator = s.boolean();

export const buttonLabelValidator = s.string
export const buttonLabelValidator = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(80)
.setValidationEnabled(isValidationEnabled);

export const buttonStyleValidator = s.nativeEnum(ButtonStyle);

export const placeholderValidator = s.string.lengthLessThanOrEqual(150).setValidationEnabled(isValidationEnabled);
export const minMaxValidator = s.number.int
export const placeholderValidator = s.string().lengthLessThanOrEqual(150).setValidationEnabled(isValidationEnabled);
export const minMaxValidator = s
.number()
.int()
.greaterThanOrEqual(0)
.lessThanOrEqual(25)
.setValidationEnabled(isValidationEnabled);

export const labelValueDescriptionValidator = s.string
export const labelValueDescriptionValidator = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(100)
.setValidationEnabled(isValidationEnabled);
Expand All @@ -40,18 +47,21 @@ export const jsonOptionValidator = s
.object({
label: labelValueDescriptionValidator,
value: labelValueDescriptionValidator,
description: labelValueDescriptionValidator.optional,
emoji: emojiValidator.optional,
default: s.boolean.optional,
description: labelValueDescriptionValidator.optional(),
emoji: emojiValidator.optional(),
default: s.boolean().optional(),
})
.setValidationEnabled(isValidationEnabled);

export const optionValidator = s.instance(StringSelectMenuOptionBuilder).setValidationEnabled(isValidationEnabled);

export const optionsValidator = optionValidator.array
export const optionsValidator = optionValidator
.array()
.lengthGreaterThanOrEqual(0)
.setValidationEnabled(isValidationEnabled);
export const optionsLengthValidator = s.number.int
export const optionsLengthValidator = s
.number()
.int()
.greaterThanOrEqual(0)
.lessThanOrEqual(25)
.setValidationEnabled(isValidationEnabled);
Expand All @@ -61,16 +71,17 @@ export function validateRequiredSelectMenuParameters(options: StringSelectMenuOp
optionsValidator.parse(options);
}

export const defaultValidator = s.boolean;
export const defaultValidator = s.boolean();

export function validateRequiredSelectMenuOptionParameters(label?: string, value?: string) {
labelValueDescriptionValidator.parse(label);
labelValueDescriptionValidator.parse(value);
}

export const channelTypesValidator = s.nativeEnum(ChannelType).array.setValidationEnabled(isValidationEnabled);
export const channelTypesValidator = s.nativeEnum(ChannelType).array().setValidationEnabled(isValidationEnabled);

export const urlValidator = s.string
export const urlValidator = s
.string()
.url({
allowedProtocols: ['http:', 'https:', 'discord:'],
})
Expand Down
17 changes: 11 additions & 6 deletions packages/builders/src/components/textInput/Assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,23 @@ import { isValidationEnabled } from '../../util/validation.js';
import { customIdValidator } from '../Assertions.js';

export const textInputStyleValidator = s.nativeEnum(TextInputStyle);
export const minLengthValidator = s.number.int
export const minLengthValidator = s
.number()
.int()
.greaterThanOrEqual(0)
.lessThanOrEqual(4_000)
.setValidationEnabled(isValidationEnabled);
export const maxLengthValidator = s.number.int
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
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ import { ApplicationCommandType, ApplicationIntegrationType, InteractionContextT
import { isValidationEnabled } from '../../util/validation.js';
import type { ContextMenuCommandType } from './ContextMenuCommandBuilder.js';

const namePredicate = s.string
const namePredicate = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(32)
// eslint-disable-next-line prefer-named-capture-group
.regex(/^( *[\p{P}\p{L}\p{N}\p{sc=Devanagari}\p{sc=Thai}]+ *)+$/u)
.setValidationEnabled(isValidationEnabled);
const typePredicate = s
.union(s.literal(ApplicationCommandType.User), s.literal(ApplicationCommandType.Message))
.union([s.literal(ApplicationCommandType.User), s.literal(ApplicationCommandType.Message)])
.setValidationEnabled(isValidationEnabled);
const booleanPredicate = s.boolean;
const booleanPredicate = s.boolean();

export function validateDefaultPermission(value: unknown): asserts value is boolean {
booleanPredicate.parse(value);
Expand All @@ -34,17 +35,22 @@ export function validateRequiredParameters(name: string, type: number) {
validateType(type);
}

const dmPermissionPredicate = s.boolean.nullish;
const dmPermissionPredicate = s.boolean().nullish();

export function validateDMPermission(value: unknown): asserts value is boolean | null | undefined {
dmPermissionPredicate.parse(value);
}

const memberPermissionPredicate = s.union(
s.bigint.transform((value) => value.toString()),
s.number.safeInt.transform((value) => value.toString()),
s.string.regex(/^\d+$/),
).nullish;
const memberPermissionPredicate = s
.union([
s.bigint().transform((value) => value.toString()),
s
.number()
.safeInt()
.transform((value) => value.toString()),
s.string().regex(/^\d+$/),
])
.nullish();

export function validateDefaultMemberPermissions(permissions: unknown) {
return memberPermissionPredicate.parse(permissions);
Expand Down
6 changes: 4 additions & 2 deletions packages/builders/src/interactions/modals/Assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { ActionRowBuilder, type ModalActionRowComponentBuilder } from '../../com
import { customIdValidator } from '../../components/Assertions.js';
import { isValidationEnabled } from '../../util/validation.js';

export const titleValidator = s.string
export const titleValidator = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(45)
.setValidationEnabled(isValidationEnabled);
export const componentsValidator = s
.instance(ActionRowBuilder)
.array.lengthGreaterThanOrEqual(1)
.array()
.lengthGreaterThanOrEqual(1)
.setValidationEnabled(isValidationEnabled);

export function validateRequiredParameters(
Expand Down
35 changes: 22 additions & 13 deletions packages/builders/src/interactions/slashCommands/Assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import type { ToAPIApplicationCommandOptions } from './SlashCommandBuilder.js';
import type { SlashCommandSubcommandBuilder, SlashCommandSubcommandGroupBuilder } from './SlashCommandSubcommands.js';
import type { ApplicationCommandOptionBase } from './mixins/ApplicationCommandOptionBase.js';

const namePredicate = s.string
const namePredicate = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(32)
.regex(/^[\p{Ll}\p{Lm}\p{Lo}\p{N}\p{sc=Devanagari}\p{sc=Thai}_-]+$/u)
Expand All @@ -21,7 +22,8 @@ export function validateName(name: unknown): asserts name is string {
namePredicate.parse(name);
}

const descriptionPredicate = s.string
const descriptionPredicate = s
.string()
.lengthGreaterThanOrEqual(1)
.lengthLessThanOrEqual(100)
.setValidationEnabled(isValidationEnabled);
Expand All @@ -31,7 +33,7 @@ export function validateDescription(description: unknown): asserts description i
descriptionPredicate.parse(description);
}

const maxArrayLengthPredicate = s.unknown.array.lengthLessThanOrEqual(25).setValidationEnabled(isValidationEnabled);
const maxArrayLengthPredicate = s.unknown().array().lengthLessThanOrEqual(25).setValidationEnabled(isValidationEnabled);
export function validateLocale(locale: unknown) {
return localePredicate.parse(locale);
}
Expand All @@ -55,7 +57,7 @@ export function validateRequiredParameters(
validateMaxOptionsLength(options);
}

const booleanPredicate = s.boolean;
const booleanPredicate = s.boolean();

export function validateDefaultPermission(value: unknown): asserts value is boolean {
booleanPredicate.parse(value);
Expand All @@ -65,7 +67,7 @@ export function validateRequired(required: unknown): asserts required is boolean
booleanPredicate.parse(required);
}

const choicesLengthPredicate = s.number.lessThanOrEqual(25).setValidationEnabled(isValidationEnabled);
const choicesLengthPredicate = s.number().lessThanOrEqual(25).setValidationEnabled(isValidationEnabled);

export function validateChoicesLength(amountAdding: number, choices?: APIApplicationCommandOptionChoice[]): void {
choicesLengthPredicate.parse((choices?.length ?? 0) + amountAdding);
Expand All @@ -78,24 +80,31 @@ export function assertReturnOfBuilder<
}

export const localizationMapPredicate = s
.object<LocalizationMap>(Object.fromEntries(Object.values(Locale).map((locale) => [locale, s.string.nullish])))
.strict.nullish.setValidationEnabled(isValidationEnabled);
.object<LocalizationMap>(Object.fromEntries(Object.values(Locale).map((locale) => [locale, s.string().nullish()])))
.strict()
.nullish()
.setValidationEnabled(isValidationEnabled);

export function validateLocalizationMap(value: unknown): asserts value is LocalizationMap {
localizationMapPredicate.parse(value);
}

const dmPermissionPredicate = s.boolean.nullish;
const dmPermissionPredicate = s.boolean().nullish();

export function validateDMPermission(value: unknown): asserts value is boolean | null | undefined {
dmPermissionPredicate.parse(value);
}

const memberPermissionPredicate = s.union(
s.bigint.transform((value) => value.toString()),
s.number.safeInt.transform((value) => value.toString()),
s.string.regex(/^\d+$/),
).nullish;
const memberPermissionPredicate = s
.union([
s.bigint().transform((value) => value.toString()),
s
.number()
.safeInt()
.transform((value) => value.toString()),
s.string().regex(/^\d+$/),
])
.nullish();

export function validateDefaultMemberPermissions(permissions: unknown) {
return memberPermissionPredicate.parse(permissions);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const allowedChannelTypes = [
*/
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.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { s } from '@sapphire/shapeshift';
import type { ApplicationCommandOptionType } from 'discord-api-types/v10';

const booleanPredicate = s.boolean;
const booleanPredicate = s.boolean();

/**
* This mixin holds choices and autocomplete symbols used for options.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { ApplicationCommandOptionType, type APIApplicationCommandOptionChoice }
import { normalizeArray, type RestOrArray } from '../../../util/normalizeArray.js';
import { localizationMapPredicate, validateChoicesLength } from '../Assertions.js';

const stringPredicate = s.string.lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(100);
const numberPredicate = s.number.greaterThan(Number.NEGATIVE_INFINITY).lessThan(Number.POSITIVE_INFINITY);
const choicesPredicate = s.object({
name: stringPredicate,
name_localizations: localizationMapPredicate,
value: s.union(stringPredicate, numberPredicate),
}).array;
const stringPredicate = s.string().lengthGreaterThanOrEqual(1).lengthLessThanOrEqual(100);
const numberPredicate = s.number().greaterThan(Number.NEGATIVE_INFINITY).lessThan(Number.POSITIVE_INFINITY);
const choicesPredicate = s
.object({
name: stringPredicate,
name_localizations: localizationMapPredicate,
value: s.union([stringPredicate, numberPredicate]),
})
.array();

/**
* This mixin holds choices and autocomplete symbols used for options.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOption
import { ApplicationCommandOptionWithAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithAutocompleteMixin.js';
import { ApplicationCommandOptionWithChoicesMixin } from '../mixins/ApplicationCommandOptionWithChoicesMixin.js';

const numberValidator = s.number.int;
const numberValidator = s.number().int();

/**
* A slash command integer option.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOption
import { ApplicationCommandOptionWithAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithAutocompleteMixin.js';
import { ApplicationCommandOptionWithChoicesMixin } from '../mixins/ApplicationCommandOptionWithChoicesMixin.js';

const numberValidator = s.number;
const numberValidator = s.number();

/**
* A slash command number option.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { ApplicationCommandOptionBase } from '../mixins/ApplicationCommandOption
import { ApplicationCommandOptionWithAutocompleteMixin } from '../mixins/ApplicationCommandOptionWithAutocompleteMixin.js';
import { ApplicationCommandOptionWithChoicesMixin } from '../mixins/ApplicationCommandOptionWithChoicesMixin.js';

const minLengthValidator = s.number.greaterThanOrEqual(0).lessThanOrEqual(6_000);
const maxLengthValidator = s.number.greaterThanOrEqual(1).lessThanOrEqual(6_000);
const minLengthValidator = s.number().greaterThanOrEqual(0).lessThanOrEqual(6_000);
const maxLengthValidator = s.number().greaterThanOrEqual(1).lessThanOrEqual(6_000);

/**
* A slash command string option.
Expand Down
Loading
Loading