mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-15 19:13:31 +01:00
feat!: use zod v4 (#10922)
* feat: zod 4 * feat: zod v3, but v4 feat: validation error class Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com> * chore: bump --------- Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com>
This commit is contained in:
@@ -1,5 +1,13 @@
|
|||||||
import { describe, test, expect } from 'vitest';
|
import { describe, test, expect } from 'vitest';
|
||||||
import { enableValidators, disableValidators, isValidationEnabled, normalizeArray } from '../src/index.js';
|
import { z } from 'zod/v4';
|
||||||
|
import {
|
||||||
|
enableValidators,
|
||||||
|
disableValidators,
|
||||||
|
isValidationEnabled,
|
||||||
|
normalizeArray,
|
||||||
|
ValidationError,
|
||||||
|
} from '../src/index.js';
|
||||||
|
import { validate } from '../src/util/validation.js';
|
||||||
|
|
||||||
describe('validation', () => {
|
describe('validation', () => {
|
||||||
test('enables validation', () => {
|
test('enables validation', () => {
|
||||||
@@ -11,6 +19,17 @@ describe('validation', () => {
|
|||||||
disableValidators();
|
disableValidators();
|
||||||
expect(isValidationEnabled()).toBeFalsy();
|
expect(isValidationEnabled()).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('validation error', () => {
|
||||||
|
try {
|
||||||
|
validate(z.never(), 1, true);
|
||||||
|
throw new Error('validation should have failed');
|
||||||
|
} catch (error) {
|
||||||
|
expect(error).toBeInstanceOf(ValidationError);
|
||||||
|
expect((error as ValidationError).message).toBe('✖ Invalid input: expected never, received number');
|
||||||
|
expect((error as ValidationError).cause).toBeInstanceOf(z.ZodError);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('normalizeArray', () => {
|
describe('normalizeArray', () => {
|
||||||
|
|||||||
@@ -69,8 +69,7 @@
|
|||||||
"discord-api-types": "^0.38.14",
|
"discord-api-types": "^0.38.14",
|
||||||
"ts-mixer": "^6.0.4",
|
"ts-mixer": "^6.0.4",
|
||||||
"tslib": "^2.8.1",
|
"tslib": "^2.8.1",
|
||||||
"zod": "^3.24.2",
|
"zod": "^3.25.69"
|
||||||
"zod-validation-error": "^3.4.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@discordjs/api-extractor": "workspace:^",
|
"@discordjs/api-extractor": "workspace:^",
|
||||||
|
|||||||
@@ -1,21 +1,13 @@
|
|||||||
import { Locale } from 'discord-api-types/v10';
|
import { Locale } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
|
|
||||||
export const customIdPredicate = z.string().min(1).max(100);
|
export const customIdPredicate = z.string().min(1).max(100);
|
||||||
|
|
||||||
export const memberPermissionsPredicate = z.coerce.bigint();
|
export const memberPermissionsPredicate = z.coerce.bigint();
|
||||||
|
|
||||||
export const localeMapPredicate = z
|
export const localeMapPredicate = z.strictObject(
|
||||||
.object(
|
Object.fromEntries(Object.values(Locale).map((loc) => [loc, z.string().optional()])) as Record<
|
||||||
Object.fromEntries(Object.values(Locale).map((loc) => [loc, z.string().optional()])) as Record<
|
Locale,
|
||||||
Locale,
|
z.ZodOptional<z.ZodString>
|
||||||
z.ZodOptional<z.ZodString>
|
>,
|
||||||
>,
|
);
|
||||||
)
|
|
||||||
.strict();
|
|
||||||
|
|
||||||
export const refineURLPredicate = (allowedProtocols: string[]) => (value: string) => {
|
|
||||||
// eslint-disable-next-line n/prefer-global/url
|
|
||||||
const url = new URL(value);
|
|
||||||
return allowedProtocols.includes(url.protocol);
|
|
||||||
};
|
|
||||||
|
|||||||
@@ -1,21 +1,20 @@
|
|||||||
import { ButtonStyle, ChannelType, ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10';
|
import { ButtonStyle, ChannelType, ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { customIdPredicate, refineURLPredicate } from '../Assertions.js';
|
import { customIdPredicate } from '../Assertions.js';
|
||||||
|
|
||||||
const labelPredicate = z.string().min(1).max(80);
|
const labelPredicate = z.string().min(1).max(80);
|
||||||
|
|
||||||
export const emojiPredicate = z
|
export const emojiPredicate = z
|
||||||
.object({
|
.strictObject({
|
||||||
id: z.string().optional(),
|
id: z.string().optional(),
|
||||||
name: z.string().min(2).max(32).optional(),
|
name: z.string().min(2).max(32).optional(),
|
||||||
animated: z.boolean().optional(),
|
animated: z.boolean().optional(),
|
||||||
})
|
})
|
||||||
.strict()
|
|
||||||
.refine((data) => data.id !== undefined || data.name !== undefined, {
|
.refine((data) => data.id !== undefined || data.name !== undefined, {
|
||||||
message: "Either 'id' or 'name' must be provided",
|
error: "Either 'id' or 'name' must be provided",
|
||||||
});
|
});
|
||||||
|
|
||||||
const buttonPredicateBase = z.object({
|
const buttonPredicateBase = z.strictObject({
|
||||||
type: z.literal(ComponentType.Button),
|
type: z.literal(ComponentType.Button),
|
||||||
disabled: z.boolean().optional(),
|
disabled: z.boolean().optional(),
|
||||||
});
|
});
|
||||||
@@ -26,31 +25,22 @@ const buttonCustomIdPredicateBase = buttonPredicateBase.extend({
|
|||||||
label: labelPredicate,
|
label: labelPredicate,
|
||||||
});
|
});
|
||||||
|
|
||||||
const buttonPrimaryPredicate = buttonCustomIdPredicateBase.extend({ style: z.literal(ButtonStyle.Primary) }).strict();
|
const buttonPrimaryPredicate = buttonCustomIdPredicateBase.extend({ style: z.literal(ButtonStyle.Primary) });
|
||||||
const buttonSecondaryPredicate = buttonCustomIdPredicateBase
|
const buttonSecondaryPredicate = buttonCustomIdPredicateBase.extend({ style: z.literal(ButtonStyle.Secondary) });
|
||||||
.extend({ style: z.literal(ButtonStyle.Secondary) })
|
const buttonSuccessPredicate = buttonCustomIdPredicateBase.extend({ style: z.literal(ButtonStyle.Success) });
|
||||||
.strict();
|
const buttonDangerPredicate = buttonCustomIdPredicateBase.extend({ style: z.literal(ButtonStyle.Danger) });
|
||||||
const buttonSuccessPredicate = buttonCustomIdPredicateBase.extend({ style: z.literal(ButtonStyle.Success) }).strict();
|
|
||||||
const buttonDangerPredicate = buttonCustomIdPredicateBase.extend({ style: z.literal(ButtonStyle.Danger) }).strict();
|
|
||||||
|
|
||||||
const buttonLinkPredicate = buttonPredicateBase
|
const buttonLinkPredicate = buttonPredicateBase.extend({
|
||||||
.extend({
|
style: z.literal(ButtonStyle.Link),
|
||||||
style: z.literal(ButtonStyle.Link),
|
url: z.url({ protocol: /^(?:https?|discord)$/ }),
|
||||||
url: z
|
emoji: emojiPredicate.optional(),
|
||||||
.string()
|
label: labelPredicate,
|
||||||
.url()
|
});
|
||||||
.refine(refineURLPredicate(['http:', 'https:', 'discord:'])),
|
|
||||||
emoji: emojiPredicate.optional(),
|
|
||||||
label: labelPredicate,
|
|
||||||
})
|
|
||||||
.strict();
|
|
||||||
|
|
||||||
const buttonPremiumPredicate = buttonPredicateBase
|
const buttonPremiumPredicate = buttonPredicateBase.extend({
|
||||||
.extend({
|
style: z.literal(ButtonStyle.Premium),
|
||||||
style: z.literal(ButtonStyle.Premium),
|
sku_id: z.string(),
|
||||||
sku_id: z.string(),
|
});
|
||||||
})
|
|
||||||
.strict();
|
|
||||||
|
|
||||||
export const buttonPredicate = z.discriminatedUnion('style', [
|
export const buttonPredicate = z.discriminatedUnion('style', [
|
||||||
buttonLinkPredicate,
|
buttonLinkPredicate,
|
||||||
@@ -71,7 +61,7 @@ const selectMenuBasePredicate = z.object({
|
|||||||
|
|
||||||
export const selectMenuChannelPredicate = selectMenuBasePredicate.extend({
|
export const selectMenuChannelPredicate = selectMenuBasePredicate.extend({
|
||||||
type: z.literal(ComponentType.ChannelSelect),
|
type: z.literal(ComponentType.ChannelSelect),
|
||||||
channel_types: z.nativeEnum(ChannelType).array().optional(),
|
channel_types: z.enum(ChannelType).array().optional(),
|
||||||
default_values: z
|
default_values: z
|
||||||
.object({ id: z.string(), type: z.literal(SelectMenuDefaultValueType.Channel) })
|
.object({ id: z.string(), type: z.literal(SelectMenuDefaultValueType.Channel) })
|
||||||
.array()
|
.array()
|
||||||
@@ -84,7 +74,7 @@ export const selectMenuMentionablePredicate = selectMenuBasePredicate.extend({
|
|||||||
default_values: z
|
default_values: z
|
||||||
.object({
|
.object({
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
type: z.union([z.literal(SelectMenuDefaultValueType.Role), z.literal(SelectMenuDefaultValueType.User)]),
|
type: z.literal([SelectMenuDefaultValueType.Role, SelectMenuDefaultValueType.User]),
|
||||||
})
|
})
|
||||||
.array()
|
.array()
|
||||||
.max(25)
|
.max(25)
|
||||||
@@ -113,23 +103,25 @@ export const selectMenuStringPredicate = selectMenuBasePredicate
|
|||||||
type: z.literal(ComponentType.StringSelect),
|
type: z.literal(ComponentType.StringSelect),
|
||||||
options: selectMenuStringOptionPredicate.array().min(1).max(25),
|
options: selectMenuStringOptionPredicate.array().min(1).max(25),
|
||||||
})
|
})
|
||||||
.superRefine((menu, ctx) => {
|
.check((ctx) => {
|
||||||
const addIssue = (name: string, minimum: number) =>
|
const addIssue = (name: string, minimum: number) =>
|
||||||
ctx.addIssue({
|
ctx.issues.push({
|
||||||
code: 'too_small',
|
code: 'too_small',
|
||||||
message: `The number of options must be greater than or equal to ${name}`,
|
message: `The number of options must be greater than or equal to ${name}`,
|
||||||
inclusive: true,
|
inclusive: true,
|
||||||
minimum,
|
minimum,
|
||||||
type: 'number',
|
type: 'number',
|
||||||
path: ['options'],
|
path: ['options'],
|
||||||
|
origin: 'number',
|
||||||
|
input: minimum,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (menu.max_values !== undefined && menu.options.length < menu.max_values) {
|
if (ctx.value.max_values !== undefined && ctx.value.options.length < ctx.value.max_values) {
|
||||||
addIssue('max_values', menu.max_values);
|
addIssue('max_values', ctx.value.max_values);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (menu.min_values !== undefined && menu.options.length < menu.min_values) {
|
if (ctx.value.min_values !== undefined && ctx.value.options.length < ctx.value.min_values) {
|
||||||
addIssue('min_values', menu.min_values);
|
addIssue('min_values', ctx.value.min_values);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -152,14 +144,13 @@ export const actionRowPredicate = z.object({
|
|||||||
.max(5),
|
.max(5),
|
||||||
z
|
z
|
||||||
.object({
|
.object({
|
||||||
type: z.union([
|
type: z.literal([
|
||||||
z.literal(ComponentType.ChannelSelect),
|
ComponentType.ChannelSelect,
|
||||||
z.literal(ComponentType.MentionableSelect),
|
ComponentType.MentionableSelect,
|
||||||
z.literal(ComponentType.RoleSelect),
|
ComponentType.StringSelect,
|
||||||
z.literal(ComponentType.StringSelect),
|
ComponentType.RoleSelect,
|
||||||
z.literal(ComponentType.UserSelect),
|
ComponentType.TextInput,
|
||||||
// And this!
|
ComponentType.UserSelect,
|
||||||
z.literal(ComponentType.TextInput),
|
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
.array()
|
.array()
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import { ComponentType, TextInputStyle } from 'discord-api-types/v10';
|
import { ComponentType, TextInputStyle } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { customIdPredicate } from '../../Assertions.js';
|
import { customIdPredicate } from '../../Assertions.js';
|
||||||
|
|
||||||
export const textInputPredicate = z.object({
|
export const textInputPredicate = z.object({
|
||||||
type: z.literal(ComponentType.TextInput),
|
type: z.literal(ComponentType.TextInput),
|
||||||
custom_id: customIdPredicate,
|
custom_id: customIdPredicate,
|
||||||
label: z.string().min(1).max(45),
|
label: z.string().min(1).max(45),
|
||||||
style: z.nativeEnum(TextInputStyle),
|
style: z.enum(TextInputStyle),
|
||||||
min_length: z.number().min(0).max(4_000).optional(),
|
min_length: z.number().min(0).max(4_000).optional(),
|
||||||
max_length: z.number().min(1).max(4_000).optional(),
|
max_length: z.number().min(1).max(4_000).optional(),
|
||||||
placeholder: z.string().max(100).optional(),
|
placeholder: z.string().max(100).optional(),
|
||||||
|
|||||||
@@ -1,15 +1,9 @@
|
|||||||
import { ComponentType, SeparatorSpacingSize } from 'discord-api-types/v10';
|
import { ComponentType, SeparatorSpacingSize } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { refineURLPredicate } from '../../Assertions.js';
|
|
||||||
import { actionRowPredicate } from '../Assertions.js';
|
import { actionRowPredicate } from '../Assertions.js';
|
||||||
|
|
||||||
const unfurledMediaItemPredicate = z.object({
|
const unfurledMediaItemPredicate = z.object({
|
||||||
url: z
|
url: z.url({ protocol: /^(?:https?|attachment)$/ }),
|
||||||
.string()
|
|
||||||
.url()
|
|
||||||
.refine(refineURLPredicate(['http:', 'https:', 'attachment:']), {
|
|
||||||
message: 'Invalid protocol for media URL. Must be http:, https:, or attachment:',
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const thumbnailPredicate = z.object({
|
export const thumbnailPredicate = z.object({
|
||||||
@@ -19,12 +13,7 @@ export const thumbnailPredicate = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const unfurledMediaItemAttachmentOnlyPredicate = z.object({
|
const unfurledMediaItemAttachmentOnlyPredicate = z.object({
|
||||||
url: z
|
url: z.url({ protocol: /^attachment$/ }),
|
||||||
.string()
|
|
||||||
.url()
|
|
||||||
.refine(refineURLPredicate(['attachment:']), {
|
|
||||||
message: 'Invalid protocol for file URL. Must be attachment:',
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export const filePredicate = z.object({
|
export const filePredicate = z.object({
|
||||||
@@ -34,7 +23,7 @@ export const filePredicate = z.object({
|
|||||||
|
|
||||||
export const separatorPredicate = z.object({
|
export const separatorPredicate = z.object({
|
||||||
divider: z.boolean().optional(),
|
divider: z.boolean().optional(),
|
||||||
spacing: z.nativeEnum(SeparatorSpacingSize).optional(),
|
spacing: z.enum(SeparatorSpacingSize).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
export const textDisplayPredicate = z.object({
|
export const textDisplayPredicate = z.object({
|
||||||
@@ -73,5 +62,5 @@ export const containerPredicate = z.object({
|
|||||||
)
|
)
|
||||||
.min(1),
|
.min(1),
|
||||||
spoiler: z.boolean().optional(),
|
spoiler: z.boolean().optional(),
|
||||||
accent_color: z.number().int().min(0).max(0xffffff).nullish(),
|
accent_color: z.int().min(0).max(0xffffff).nullish(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export * from './util/componentUtil.js';
|
|||||||
export * from './util/normalizeArray.js';
|
export * from './util/normalizeArray.js';
|
||||||
export * from './util/resolveBuilder.js';
|
export * from './util/resolveBuilder.js';
|
||||||
export { disableValidators, enableValidators, isValidationEnabled } from './util/validation.js';
|
export { disableValidators, enableValidators, isValidationEnabled } from './util/validation.js';
|
||||||
|
export * from './util/ValidationError.js';
|
||||||
|
|
||||||
export * from './Assertions.js';
|
export * from './Assertions.js';
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import {
|
|||||||
InteractionContextType,
|
InteractionContextType,
|
||||||
ApplicationCommandOptionType,
|
ApplicationCommandOptionType,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import type { ZodTypeAny } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { z } from 'zod';
|
|
||||||
import { localeMapPredicate, memberPermissionsPredicate } from '../../../Assertions.js';
|
import { localeMapPredicate, memberPermissionsPredicate } from '../../../Assertions.js';
|
||||||
import { ApplicationCommandOptionAllowedChannelTypes } from './mixins/ApplicationCommandOptionChannelTypesMixin.js';
|
import { ApplicationCommandOptionAllowedChannelTypes } from './mixins/ApplicationCommandOptionChannelTypesMixin.js';
|
||||||
|
|
||||||
@@ -24,26 +23,17 @@ const sharedNameAndDescriptionPredicate = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const numericMixinNumberOptionPredicate = z.object({
|
const numericMixinNumberOptionPredicate = z.object({
|
||||||
max_value: z.number().safe().optional(),
|
max_value: z.float32().optional(),
|
||||||
min_value: z.number().safe().optional(),
|
min_value: z.float32().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const numericMixinIntegerOptionPredicate = z.object({
|
const numericMixinIntegerOptionPredicate = z.object({
|
||||||
max_value: z.number().safe().int().optional(),
|
max_value: z.int().optional(),
|
||||||
min_value: z.number().safe().int().optional(),
|
min_value: z.int().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const channelMixinOptionPredicate = z.object({
|
const channelMixinOptionPredicate = z.object({
|
||||||
channel_types: z
|
channel_types: z.literal(ApplicationCommandOptionAllowedChannelTypes).array().optional(),
|
||||||
.union(
|
|
||||||
ApplicationCommandOptionAllowedChannelTypes.map((type) => z.literal(type)) as unknown as [
|
|
||||||
ZodTypeAny,
|
|
||||||
ZodTypeAny,
|
|
||||||
...ZodTypeAny[],
|
|
||||||
],
|
|
||||||
)
|
|
||||||
.array()
|
|
||||||
.optional(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const autocompleteMixinOptionPredicate = z.object({
|
const autocompleteMixinOptionPredicate = z.object({
|
||||||
@@ -52,7 +42,7 @@ const autocompleteMixinOptionPredicate = z.object({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const choiceValueStringPredicate = z.string().min(1).max(100);
|
const choiceValueStringPredicate = z.string().min(1).max(100);
|
||||||
const choiceValueNumberPredicate = z.number().safe();
|
const choiceValueNumberPredicate = z.number();
|
||||||
const choiceBasePredicate = z.object({
|
const choiceBasePredicate = z.object({
|
||||||
name: choiceValueStringPredicate,
|
name: choiceValueStringPredicate,
|
||||||
name_localizations: localeMapPredicate.optional(),
|
name_localizations: localeMapPredicate.optional(),
|
||||||
@@ -74,7 +64,7 @@ const choiceNumberMixinPredicate = choiceBaseMixinPredicate.extend({
|
|||||||
choices: choiceNumberPredicate.array().max(25).optional(),
|
choices: choiceNumberPredicate.array().max(25).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const basicOptionTypes = [
|
const basicOptionTypesPredicate = z.literal([
|
||||||
ApplicationCommandOptionType.Attachment,
|
ApplicationCommandOptionType.Attachment,
|
||||||
ApplicationCommandOptionType.Boolean,
|
ApplicationCommandOptionType.Boolean,
|
||||||
ApplicationCommandOptionType.Channel,
|
ApplicationCommandOptionType.Channel,
|
||||||
@@ -84,11 +74,7 @@ const basicOptionTypes = [
|
|||||||
ApplicationCommandOptionType.Role,
|
ApplicationCommandOptionType.Role,
|
||||||
ApplicationCommandOptionType.String,
|
ApplicationCommandOptionType.String,
|
||||||
ApplicationCommandOptionType.User,
|
ApplicationCommandOptionType.User,
|
||||||
] as const;
|
]);
|
||||||
|
|
||||||
const basicOptionTypesPredicate = z.union(
|
|
||||||
basicOptionTypes.map((type) => z.literal(type)) as unknown as [ZodTypeAny, ZodTypeAny, ...ZodTypeAny[]],
|
|
||||||
);
|
|
||||||
|
|
||||||
export const basicOptionPredicate = sharedNameAndDescriptionPredicate.extend({
|
export const basicOptionPredicate = sharedNameAndDescriptionPredicate.extend({
|
||||||
required: z.boolean().optional(),
|
required: z.boolean().optional(),
|
||||||
@@ -105,14 +91,23 @@ const autocompleteOrNumberChoicesMixinOptionPredicate = z.discriminatedUnion('au
|
|||||||
choiceNumberMixinPredicate,
|
choiceNumberMixinPredicate,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const channelOptionPredicate = basicOptionPredicate.merge(channelMixinOptionPredicate);
|
export const channelOptionPredicate = z.object({
|
||||||
|
...basicOptionPredicate.shape,
|
||||||
|
...channelMixinOptionPredicate.shape,
|
||||||
|
});
|
||||||
|
|
||||||
export const integerOptionPredicate = basicOptionPredicate
|
export const integerOptionPredicate = z
|
||||||
.merge(numericMixinIntegerOptionPredicate)
|
.object({
|
||||||
|
...basicOptionPredicate.shape,
|
||||||
|
...numericMixinIntegerOptionPredicate.shape,
|
||||||
|
})
|
||||||
.and(autocompleteOrNumberChoicesMixinOptionPredicate);
|
.and(autocompleteOrNumberChoicesMixinOptionPredicate);
|
||||||
|
|
||||||
export const numberOptionPredicate = basicOptionPredicate
|
export const numberOptionPredicate = z
|
||||||
.merge(numericMixinNumberOptionPredicate)
|
.object({
|
||||||
|
...basicOptionPredicate.shape,
|
||||||
|
...numericMixinNumberOptionPredicate.shape,
|
||||||
|
})
|
||||||
.and(autocompleteOrNumberChoicesMixinOptionPredicate);
|
.and(autocompleteOrNumberChoicesMixinOptionPredicate);
|
||||||
|
|
||||||
export const stringOptionPredicate = basicOptionPredicate
|
export const stringOptionPredicate = basicOptionPredicate
|
||||||
@@ -123,9 +118,9 @@ export const stringOptionPredicate = basicOptionPredicate
|
|||||||
.and(autocompleteOrStringChoicesMixinOptionPredicate);
|
.and(autocompleteOrStringChoicesMixinOptionPredicate);
|
||||||
|
|
||||||
const baseChatInputCommandPredicate = sharedNameAndDescriptionPredicate.extend({
|
const baseChatInputCommandPredicate = sharedNameAndDescriptionPredicate.extend({
|
||||||
contexts: z.array(z.nativeEnum(InteractionContextType)).optional(),
|
contexts: z.array(z.enum(InteractionContextType)).optional(),
|
||||||
default_member_permissions: memberPermissionsPredicate.optional(),
|
default_member_permissions: memberPermissionsPredicate.optional(),
|
||||||
integration_types: z.array(z.nativeEnum(ApplicationIntegrationType)).optional(),
|
integration_types: z.array(z.enum(ApplicationIntegrationType)).optional(),
|
||||||
nsfw: z.boolean().optional(),
|
nsfw: z.boolean().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export const ApplicationCommandOptionAllowedChannelTypes = [
|
|||||||
/**
|
/**
|
||||||
* Allowed channel types used for a channel option.
|
* Allowed channel types used for a channel option.
|
||||||
*/
|
*/
|
||||||
export type ApplicationCommandOptionAllowedChannelTypes = (typeof ApplicationCommandOptionAllowedChannelTypes)[number];
|
export type ApplicationCommandOptionAllowedChannelType = (typeof ApplicationCommandOptionAllowedChannelTypes)[number];
|
||||||
|
|
||||||
export interface ApplicationCommandOptionChannelTypesData
|
export interface ApplicationCommandOptionChannelTypesData
|
||||||
extends Pick<APIApplicationCommandChannelOption, 'channel_types'> {}
|
extends Pick<APIApplicationCommandChannelOption, 'channel_types'> {}
|
||||||
@@ -36,7 +36,7 @@ export class ApplicationCommandOptionChannelTypesMixin {
|
|||||||
*
|
*
|
||||||
* @param channelTypes - The channel types
|
* @param channelTypes - The channel types
|
||||||
*/
|
*/
|
||||||
public addChannelTypes(...channelTypes: RestOrArray<ApplicationCommandOptionAllowedChannelTypes>) {
|
public addChannelTypes(...channelTypes: RestOrArray<ApplicationCommandOptionAllowedChannelType>) {
|
||||||
this.data.channel_types ??= [];
|
this.data.channel_types ??= [];
|
||||||
this.data.channel_types.push(...normalizeArray(channelTypes));
|
this.data.channel_types.push(...normalizeArray(channelTypes));
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ export class ApplicationCommandOptionChannelTypesMixin {
|
|||||||
*
|
*
|
||||||
* @param channelTypes - The channel types
|
* @param channelTypes - The channel types
|
||||||
*/
|
*/
|
||||||
public setChannelTypes(...channelTypes: RestOrArray<ApplicationCommandOptionAllowedChannelTypes>) {
|
public setChannelTypes(...channelTypes: RestOrArray<ApplicationCommandOptionAllowedChannelType>) {
|
||||||
this.data.channel_types = normalizeArray(channelTypes);
|
this.data.channel_types = normalizeArray(channelTypes);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type {
|
|||||||
APIApplicationCommandOption,
|
APIApplicationCommandOption,
|
||||||
ApplicationCommandOptionType,
|
ApplicationCommandOptionType,
|
||||||
} from 'discord-api-types/v10';
|
} from 'discord-api-types/v10';
|
||||||
import type { z } from 'zod';
|
import type { z } from 'zod/v4';
|
||||||
import { validate } from '../../../../util/validation.js';
|
import { validate } from '../../../../util/validation.js';
|
||||||
import type { SharedNameAndDescriptionData } from '../../SharedNameAndDescription.js';
|
import type { SharedNameAndDescriptionData } from '../../SharedNameAndDescription.js';
|
||||||
import { SharedNameAndDescription } from '../../SharedNameAndDescription.js';
|
import { SharedNameAndDescription } from '../../SharedNameAndDescription.js';
|
||||||
@@ -24,7 +24,7 @@ export abstract class ApplicationCommandOptionBase
|
|||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
protected static readonly predicate: z.ZodTypeAny = basicOptionPredicate;
|
protected static readonly predicate: z.ZodType = basicOptionPredicate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ApplicationCommandType, ApplicationIntegrationType, InteractionContextType } from 'discord-api-types/v10';
|
import { ApplicationCommandType, ApplicationIntegrationType, InteractionContextType } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { localeMapPredicate, memberPermissionsPredicate } from '../../../Assertions.js';
|
import { localeMapPredicate, memberPermissionsPredicate } from '../../../Assertions.js';
|
||||||
|
|
||||||
const namePredicate = z
|
const namePredicate = z
|
||||||
@@ -8,8 +8,8 @@ const namePredicate = z
|
|||||||
.max(32)
|
.max(32)
|
||||||
.regex(/^(?:(?: *[\p{P}\p{L}\p{N}\p{sc=Devanagari}\p{sc=Thai}\p{Extended_Pictographic}\p{Emoji_Component}]) *)+$/u);
|
.regex(/^(?:(?: *[\p{P}\p{L}\p{N}\p{sc=Devanagari}\p{sc=Thai}\p{Extended_Pictographic}\p{Emoji_Component}]) *)+$/u);
|
||||||
|
|
||||||
const contextsPredicate = z.array(z.nativeEnum(InteractionContextType));
|
const contextsPredicate = z.array(z.enum(InteractionContextType));
|
||||||
const integrationTypesPredicate = z.array(z.nativeEnum(ApplicationIntegrationType));
|
const integrationTypesPredicate = z.array(z.enum(ApplicationIntegrationType));
|
||||||
|
|
||||||
const baseContextMenuCommandPredicate = z.object({
|
const baseContextMenuCommandPredicate = z.object({
|
||||||
contexts: contextsPredicate.optional(),
|
contexts: contextsPredicate.optional(),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { ComponentType } from 'discord-api-types/v10';
|
import { ComponentType } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { customIdPredicate } from '../../Assertions.js';
|
import { customIdPredicate } from '../../Assertions.js';
|
||||||
|
|
||||||
const titlePredicate = z.string().min(1).max(45);
|
const titlePredicate = z.string().min(1).max(45);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { AllowedMentionsTypes, ComponentType, MessageFlags, MessageReferenceType } from 'discord-api-types/v10';
|
import { AllowedMentionsTypes, ComponentType, MessageFlags, MessageReferenceType } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { embedPredicate } from './embed/Assertions.js';
|
import { embedPredicate } from './embed/Assertions.js';
|
||||||
import { pollPredicate } from './poll/Assertions.js';
|
import { pollPredicate } from './poll/Assertions.js';
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ export const attachmentPredicate = z.object({
|
|||||||
|
|
||||||
export const allowedMentionPredicate = z
|
export const allowedMentionPredicate = z
|
||||||
.object({
|
.object({
|
||||||
parse: z.nativeEnum(AllowedMentionsTypes).array().optional(),
|
parse: z.enum(AllowedMentionsTypes).array().optional(),
|
||||||
roles: z.string().array().max(100).optional(),
|
roles: z.string().array().max(100).optional(),
|
||||||
users: z.string().array().max(100).optional(),
|
users: z.string().array().max(100).optional(),
|
||||||
replied_user: z.boolean().optional(),
|
replied_user: z.boolean().optional(),
|
||||||
@@ -29,7 +29,7 @@ export const allowedMentionPredicate = z
|
|||||||
(data.parse?.includes(AllowedMentionsTypes.Role) && data.roles?.length)
|
(data.parse?.includes(AllowedMentionsTypes.Role) && data.roles?.length)
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
message:
|
error:
|
||||||
'Cannot specify both parse: ["users"] and non-empty users array, or parse: ["roles"] and non-empty roles array. These are mutually exclusive',
|
'Cannot specify both parse: ["users"] and non-empty users array, or parse: ["roles"] and non-empty roles array. These are mutually exclusive',
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@@ -39,7 +39,7 @@ export const messageReferencePredicate = z.object({
|
|||||||
fail_if_not_exists: z.boolean().optional(),
|
fail_if_not_exists: z.boolean().optional(),
|
||||||
guild_id: z.string().optional(),
|
guild_id: z.string().optional(),
|
||||||
message_id: z.string(),
|
message_id: z.string(),
|
||||||
type: z.nativeEnum(MessageReferenceType).optional(),
|
type: z.enum(MessageReferenceType).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const baseMessagePredicate = z.object({
|
const baseMessagePredicate = z.object({
|
||||||
@@ -55,13 +55,13 @@ const basicActionRowPredicate = z.object({
|
|||||||
type: z.literal(ComponentType.ActionRow),
|
type: z.literal(ComponentType.ActionRow),
|
||||||
components: z
|
components: z
|
||||||
.object({
|
.object({
|
||||||
type: z.union([
|
type: z.literal([
|
||||||
z.literal(ComponentType.Button),
|
ComponentType.Button,
|
||||||
z.literal(ComponentType.ChannelSelect),
|
ComponentType.ChannelSelect,
|
||||||
z.literal(ComponentType.MentionableSelect),
|
ComponentType.MentionableSelect,
|
||||||
z.literal(ComponentType.RoleSelect),
|
ComponentType.RoleSelect,
|
||||||
z.literal(ComponentType.StringSelect),
|
ComponentType.StringSelect,
|
||||||
z.literal(ComponentType.UserSelect),
|
ComponentType.UserSelect,
|
||||||
]),
|
]),
|
||||||
})
|
})
|
||||||
.array(),
|
.array(),
|
||||||
@@ -75,15 +75,10 @@ const messageNoComponentsV2Predicate = baseMessagePredicate
|
|||||||
poll: pollPredicate.optional(),
|
poll: pollPredicate.optional(),
|
||||||
components: basicActionRowPredicate.array().max(5).optional(),
|
components: basicActionRowPredicate.array().max(5).optional(),
|
||||||
flags: z
|
flags: z
|
||||||
.number()
|
.int()
|
||||||
.optional()
|
.optional()
|
||||||
.refine((flags) => {
|
.refine((flags) => !flags || (flags & MessageFlags.IsComponentsV2) === 0, {
|
||||||
// If we have flags, ensure we don't have the ComponentsV2 flag
|
error: 'Cannot set content, embeds, stickers, or poll with IsComponentsV2 flag set',
|
||||||
if (flags) {
|
|
||||||
return (flags & MessageFlags.IsComponentsV2) === 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
.refine(
|
.refine(
|
||||||
@@ -94,22 +89,22 @@ const messageNoComponentsV2Predicate = baseMessagePredicate
|
|||||||
(data.attachments !== undefined && data.attachments.length > 0) ||
|
(data.attachments !== undefined && data.attachments.length > 0) ||
|
||||||
(data.components !== undefined && data.components.length > 0) ||
|
(data.components !== undefined && data.components.length > 0) ||
|
||||||
(data.sticker_ids !== undefined && data.sticker_ids.length > 0),
|
(data.sticker_ids !== undefined && data.sticker_ids.length > 0),
|
||||||
{ message: 'Messages must have content, embeds, a poll, attachments, components or stickers' },
|
{ error: 'Messages must have content, embeds, a poll, attachments, components or stickers' },
|
||||||
);
|
);
|
||||||
|
|
||||||
const allTopLevelComponentsPredicate = z
|
const allTopLevelComponentsPredicate = z
|
||||||
.union([
|
.union([
|
||||||
basicActionRowPredicate,
|
basicActionRowPredicate,
|
||||||
z.object({
|
z.object({
|
||||||
type: z.union([
|
type: z.literal([
|
||||||
// Components v2
|
// Components v2
|
||||||
z.literal(ComponentType.Container),
|
ComponentType.Container,
|
||||||
z.literal(ComponentType.File),
|
ComponentType.File,
|
||||||
z.literal(ComponentType.MediaGallery),
|
ComponentType.MediaGallery,
|
||||||
z.literal(ComponentType.Section),
|
ComponentType.Section,
|
||||||
z.literal(ComponentType.Separator),
|
ComponentType.Separator,
|
||||||
z.literal(ComponentType.TextDisplay),
|
ComponentType.TextDisplay,
|
||||||
z.literal(ComponentType.Thumbnail),
|
ComponentType.Thumbnail,
|
||||||
]),
|
]),
|
||||||
}),
|
}),
|
||||||
])
|
])
|
||||||
@@ -119,7 +114,9 @@ const allTopLevelComponentsPredicate = z
|
|||||||
|
|
||||||
const messageComponentsV2Predicate = baseMessagePredicate.extend({
|
const messageComponentsV2Predicate = baseMessagePredicate.extend({
|
||||||
components: allTopLevelComponentsPredicate,
|
components: allTopLevelComponentsPredicate,
|
||||||
flags: z.number().refine((flags) => (flags & MessageFlags.IsComponentsV2) === MessageFlags.IsComponentsV2),
|
flags: z.int().refine((flags) => (flags & MessageFlags.IsComponentsV2) === MessageFlags.IsComponentsV2, {
|
||||||
|
error: 'Must set IsComponentsV2 flag to use Components V2',
|
||||||
|
}),
|
||||||
// These fields cannot be set
|
// These fields cannot be set
|
||||||
content: z.string().length(0).nullish(),
|
content: z.string().length(0).nullish(),
|
||||||
embeds: z.array(z.never()).nullish(),
|
embeds: z.array(z.never()).nullish(),
|
||||||
|
|||||||
@@ -1,20 +1,11 @@
|
|||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { refineURLPredicate } from '../../Assertions.js';
|
|
||||||
import { embedLength } from '../../util/componentUtil.js';
|
import { embedLength } from '../../util/componentUtil.js';
|
||||||
|
|
||||||
const namePredicate = z.string().max(256);
|
const namePredicate = z.string().max(256);
|
||||||
|
|
||||||
const URLPredicate = z
|
const URLPredicate = z.url({ protocol: /^https?$/ });
|
||||||
.string()
|
|
||||||
.url()
|
|
||||||
.refine(refineURLPredicate(['http:', 'https:']), { message: 'Invalid protocol for URL. Must be http: or https:' });
|
|
||||||
|
|
||||||
const URLWithAttachmentProtocolPredicate = z
|
const URLWithAttachmentProtocolPredicate = z.url({ protocol: /^(?:https?|attachment)$/ });
|
||||||
.string()
|
|
||||||
.url()
|
|
||||||
.refine(refineURLPredicate(['http:', 'https:', 'attachment:']), {
|
|
||||||
message: 'Invalid protocol for URL. Must be http:, https:, or attachment:',
|
|
||||||
});
|
|
||||||
|
|
||||||
export const embedFieldPredicate = z.object({
|
export const embedFieldPredicate = z.object({
|
||||||
name: namePredicate,
|
name: namePredicate,
|
||||||
@@ -39,7 +30,7 @@ export const embedPredicate = z
|
|||||||
description: z.string().min(1).max(4_096).optional(),
|
description: z.string().min(1).max(4_096).optional(),
|
||||||
url: URLPredicate.optional(),
|
url: URLPredicate.optional(),
|
||||||
timestamp: z.string().optional(),
|
timestamp: z.string().optional(),
|
||||||
color: z.number().int().min(0).max(0xffffff).optional(),
|
color: z.int().min(0).max(0xffffff).optional(),
|
||||||
footer: embedFooterPredicate.optional(),
|
footer: embedFooterPredicate.optional(),
|
||||||
image: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
|
image: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
|
||||||
thumbnail: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
|
thumbnail: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
|
||||||
@@ -56,7 +47,7 @@ export const embedPredicate = z
|
|||||||
embed.image !== undefined ||
|
embed.image !== undefined ||
|
||||||
embed.thumbnail !== undefined,
|
embed.thumbnail !== undefined,
|
||||||
{
|
{
|
||||||
message: 'Embed must have at least a title, description, a field, a footer, an author, an image, OR a thumbnail.',
|
error: 'Embed must have at least a title, description, a field, a footer, an author, an image, OR a thumbnail.',
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.refine((embed) => embedLength(embed) <= 6_000, { message: 'Embeds must not exceed 6000 characters in total.' });
|
.refine((embed) => embedLength(embed) <= 6_000, { error: 'Embeds must not exceed 6000 characters in total.' });
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { PollLayoutType } from 'discord-api-types/v10';
|
import { PollLayoutType } from 'discord-api-types/v10';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod/v4';
|
||||||
import { emojiPredicate } from '../../components/Assertions';
|
import { emojiPredicate } from '../../components/Assertions';
|
||||||
|
|
||||||
export const pollQuestionPredicate = z.object({ text: z.string().min(1).max(300) });
|
export const pollQuestionPredicate = z.object({ text: z.string().min(1).max(300) });
|
||||||
@@ -16,5 +16,5 @@ export const pollPredicate = z.object({
|
|||||||
answers: z.array(pollAnswerPredicate).min(1).max(10),
|
answers: z.array(pollAnswerPredicate).min(1).max(10),
|
||||||
duration: z.number().min(1).max(768).optional(),
|
duration: z.number().min(1).max(768).optional(),
|
||||||
allow_multiselect: z.boolean().optional(),
|
allow_multiselect: z.boolean().optional(),
|
||||||
layout_type: z.nativeEnum(PollLayoutType).optional(),
|
layout_type: z.enum(PollLayoutType).optional(),
|
||||||
});
|
});
|
||||||
|
|||||||
21
packages/builders/src/util/ValidationError.ts
Normal file
21
packages/builders/src/util/ValidationError.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { z } from 'zod/v4';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An error that is thrown when validation fails.
|
||||||
|
*/
|
||||||
|
export class ValidationError extends Error {
|
||||||
|
/**
|
||||||
|
* The underlying cause of the validation error.
|
||||||
|
*/
|
||||||
|
public override readonly cause: z.ZodError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public constructor(error: z.ZodError) {
|
||||||
|
super(z.prettifyError(error));
|
||||||
|
|
||||||
|
this.name = 'ValidationError';
|
||||||
|
this.cause = error;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { z } from 'zod';
|
import type { z } from 'zod/v4';
|
||||||
import { fromZodError } from 'zod-validation-error';
|
import { ValidationError } from './ValidationError.js';
|
||||||
|
|
||||||
let validationEnabled = true;
|
let validationEnabled = true;
|
||||||
|
|
||||||
@@ -35,21 +35,23 @@ export function isValidationEnabled() {
|
|||||||
* @param value - The value to parse
|
* @param value - The value to parse
|
||||||
* @param validationOverride - Force validation to run/not run regardless of your global preference
|
* @param validationOverride - Force validation to run/not run regardless of your global preference
|
||||||
* @returns The result from parsing
|
* @returns The result from parsing
|
||||||
|
* @throws {@link ValidationError}
|
||||||
|
* Throws if the value does not pass validation, if enabled.
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function validate<Validator extends z.ZodTypeAny>(
|
export function validate<Validator extends z.ZodType>(
|
||||||
validator: Validator,
|
validator: Validator,
|
||||||
value: unknown,
|
value: unknown,
|
||||||
validationOverride?: boolean,
|
validationOverride?: boolean,
|
||||||
): z.output<Validator> {
|
): z.output<Validator> {
|
||||||
if (validationOverride === false || !isValidationEnabled()) {
|
if (validationOverride === false || (validationOverride === undefined && !isValidationEnabled())) {
|
||||||
return value;
|
return value as z.output<Validator>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = validator.safeParse(value);
|
const result = validator.safeParse(value);
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw fromZodError(result.error);
|
throw new ValidationError(result.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.data;
|
return result.data;
|
||||||
|
|||||||
@@ -579,7 +579,7 @@ class ApplicationCommand extends Base {
|
|||||||
* {@link ApplicationCommandOptionType.Number} option
|
* {@link ApplicationCommandOptionType.Number} option
|
||||||
* @property {ApplicationCommandOptionChoice[]} [choices] The choices of the option for the user to pick from
|
* @property {ApplicationCommandOptionChoice[]} [choices] The choices of the option for the user to pick from
|
||||||
* @property {ApplicationCommandOption[]} [options] Additional options if this option is a subcommand (group)
|
* @property {ApplicationCommandOption[]} [options] Additional options if this option is a subcommand (group)
|
||||||
* @property {ApplicationCommandOptionAllowedChannelTypes[]} [channelTypes] When the option type is channel,
|
* @property {ApplicationCommandOptionAllowedChannelType[]} [channelTypes] When the option type is channel,
|
||||||
* the allowed types of channels that can be selected
|
* the allowed types of channels that can be selected
|
||||||
* @property {number} [minValue] The minimum value for an {@link ApplicationCommandOptionType.Integer} or
|
* @property {number} [minValue] The minimum value for an {@link ApplicationCommandOptionType.Integer} or
|
||||||
* {@link ApplicationCommandOptionType.Number} option
|
* {@link ApplicationCommandOptionType.Number} option
|
||||||
@@ -653,6 +653,6 @@ class ApplicationCommand extends Base {
|
|||||||
exports.ApplicationCommand = ApplicationCommand;
|
exports.ApplicationCommand = ApplicationCommand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @external ApplicationCommandOptionAllowedChannelTypes
|
* @external ApplicationCommandOptionAllowedChannelType
|
||||||
* @see {@link https://discord.js.org/docs/packages/builders/stable/ApplicationCommandOptionAllowedChannelTypes:TypeAlias}
|
* @see {@link https://discord.js.org/docs/packages/builders/stable/ApplicationCommandOptionAllowedChannelType:TypeAlias}
|
||||||
*/
|
*/
|
||||||
|
|||||||
8
packages/discord.js/typings/index.d.ts
vendored
8
packages/discord.js/typings/index.d.ts
vendored
@@ -2,7 +2,7 @@ import { Buffer } from 'node:buffer';
|
|||||||
import { ChildProcess } from 'node:child_process';
|
import { ChildProcess } from 'node:child_process';
|
||||||
import { Stream } from 'node:stream';
|
import { Stream } from 'node:stream';
|
||||||
import { MessagePort, Worker } from 'node:worker_threads';
|
import { MessagePort, Worker } from 'node:worker_threads';
|
||||||
import { ApplicationCommandOptionAllowedChannelTypes, MessageActionRowComponentBuilder } from '@discordjs/builders';
|
import { ApplicationCommandOptionAllowedChannelType, MessageActionRowComponentBuilder } from '@discordjs/builders';
|
||||||
import { Collection, ReadonlyCollection } from '@discordjs/collection';
|
import { Collection, ReadonlyCollection } from '@discordjs/collection';
|
||||||
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions, EmojiURLOptions } from '@discordjs/rest';
|
import { BaseImageURLOptions, ImageURLOptions, RawFile, REST, RESTOptions, EmojiURLOptions } from '@discordjs/rest';
|
||||||
import { Awaitable, JSONEncodable } from '@discordjs/util';
|
import { Awaitable, JSONEncodable } from '@discordjs/util';
|
||||||
@@ -4823,13 +4823,13 @@ export type ApplicationCommandData =
|
|||||||
| UserApplicationCommandData;
|
| UserApplicationCommandData;
|
||||||
|
|
||||||
export interface ApplicationCommandChannelOptionData extends BaseApplicationCommandOptionsData {
|
export interface ApplicationCommandChannelOptionData extends BaseApplicationCommandOptionsData {
|
||||||
channelTypes?: readonly ApplicationCommandOptionAllowedChannelTypes[];
|
channelTypes?: readonly ApplicationCommandOptionAllowedChannelType[];
|
||||||
channel_types?: readonly ApplicationCommandOptionAllowedChannelTypes[];
|
channel_types?: readonly ApplicationCommandOptionAllowedChannelType[];
|
||||||
type: CommandOptionChannelResolvableType;
|
type: CommandOptionChannelResolvableType;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ApplicationCommandChannelOption extends BaseApplicationCommandOptionsData {
|
export interface ApplicationCommandChannelOption extends BaseApplicationCommandOptionsData {
|
||||||
channelTypes?: readonly ApplicationCommandOptionAllowedChannelTypes[];
|
channelTypes?: readonly ApplicationCommandOptionAllowedChannelType[];
|
||||||
type: ApplicationCommandOptionType.Channel;
|
type: ApplicationCommandOptionType.Channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
27
pnpm-lock.yaml
generated
27
pnpm-lock.yaml
generated
@@ -759,11 +759,8 @@ importers:
|
|||||||
specifier: ^2.8.1
|
specifier: ^2.8.1
|
||||||
version: 2.8.1
|
version: 2.8.1
|
||||||
zod:
|
zod:
|
||||||
specifier: ^3.24.2
|
specifier: ^3.25.69
|
||||||
version: 3.24.3
|
version: 3.25.69
|
||||||
zod-validation-error:
|
|
||||||
specifier: ^3.4.0
|
|
||||||
version: 3.4.0(zod@3.24.3)
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@discordjs/api-extractor':
|
'@discordjs/api-extractor':
|
||||||
specifier: workspace:^
|
specifier: workspace:^
|
||||||
@@ -13998,24 +13995,18 @@ packages:
|
|||||||
zlib-sync@0.1.10:
|
zlib-sync@0.1.10:
|
||||||
resolution: {integrity: sha512-t7/pYg5tLBznL1RuhmbAt8rNp5tbhr+TSrJFnMkRtrGIaPJZ6Dc0uR4u3OoQI2d6cGlVI62E3Gy6gwkxyIqr/w==}
|
resolution: {integrity: sha512-t7/pYg5tLBznL1RuhmbAt8rNp5tbhr+TSrJFnMkRtrGIaPJZ6Dc0uR4u3OoQI2d6cGlVI62E3Gy6gwkxyIqr/w==}
|
||||||
|
|
||||||
zod-validation-error@3.4.0:
|
|
||||||
resolution: {integrity: sha512-ZOPR9SVY6Pb2qqO5XHt+MkkTRxGXb4EVtnjc9JpXUOtUB1T9Ru7mZOT361AN3MsetVe7R0a1KZshJDZdgp9miQ==}
|
|
||||||
engines: {node: '>=18.0.0'}
|
|
||||||
peerDependencies:
|
|
||||||
zod: ^3.18.0
|
|
||||||
|
|
||||||
zod-validation-error@3.4.1:
|
zod-validation-error@3.4.1:
|
||||||
resolution: {integrity: sha512-1KP64yqDPQ3rupxNv7oXhf7KdhHHgaqbKuspVoiN93TT0xrBjql+Svjkdjq/Qh/7GSMmgQs3AfvBT0heE35thw==}
|
resolution: {integrity: sha512-1KP64yqDPQ3rupxNv7oXhf7KdhHHgaqbKuspVoiN93TT0xrBjql+Svjkdjq/Qh/7GSMmgQs3AfvBT0heE35thw==}
|
||||||
engines: {node: '>=18.0.0'}
|
engines: {node: '>=18.0.0'}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
zod: ^3.24.4
|
zod: ^3.24.4
|
||||||
|
|
||||||
zod@3.24.3:
|
|
||||||
resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==}
|
|
||||||
|
|
||||||
zod@3.25.39:
|
zod@3.25.39:
|
||||||
resolution: {integrity: sha512-yrva2T2x4R+FMFTPBVD/YPS7ct8njqjnV93zNx/MlwqLAxcnxwRGbXWyWF63/nErl3rdRd8KARObon7BiWzabQ==}
|
resolution: {integrity: sha512-yrva2T2x4R+FMFTPBVD/YPS7ct8njqjnV93zNx/MlwqLAxcnxwRGbXWyWF63/nErl3rdRd8KARObon7BiWzabQ==}
|
||||||
|
|
||||||
|
zod@3.25.69:
|
||||||
|
resolution: {integrity: sha512-cjUx+boz8dfYGssYKLGNTF5VUF6NETpcZCDTN3knhUUXQTAAvErzRhV3pgeCZm2YsL4HOwtEHPonlsshPu2I0A==}
|
||||||
|
|
||||||
zwitch@2.0.4:
|
zwitch@2.0.4:
|
||||||
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
|
||||||
|
|
||||||
@@ -29506,16 +29497,12 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
nan: 2.22.0
|
nan: 2.22.0
|
||||||
|
|
||||||
zod-validation-error@3.4.0(zod@3.24.3):
|
|
||||||
dependencies:
|
|
||||||
zod: 3.24.3
|
|
||||||
|
|
||||||
zod-validation-error@3.4.1(zod@3.25.39):
|
zod-validation-error@3.4.1(zod@3.25.39):
|
||||||
dependencies:
|
dependencies:
|
||||||
zod: 3.25.39
|
zod: 3.25.39
|
||||||
|
|
||||||
zod@3.24.3: {}
|
|
||||||
|
|
||||||
zod@3.25.39: {}
|
zod@3.25.39: {}
|
||||||
|
|
||||||
|
zod@3.25.69: {}
|
||||||
|
|
||||||
zwitch@2.0.4: {}
|
zwitch@2.0.4: {}
|
||||||
|
|||||||
Reference in New Issue
Block a user