fix: Add idPredicate (#11109)

* fix: `idPredicate`

* fix: add test

* test: add negative test
This commit is contained in:
Jiralite
2025-09-26 17:06:22 +01:00
committed by GitHub
parent b3705df547
commit 0d76f1149f
7 changed files with 29 additions and 2 deletions

View File

@@ -32,4 +32,11 @@ describe('Separator', () => {
expect(separator.toJSON()).toEqual({ type: ComponentType.Separator }); expect(separator.toJSON()).toEqual({ type: ComponentType.Separator });
}); });
}); });
describe('Invalid id', () => {
test('GIVEN a separator with a set spacing and an invalid set id THEN throws error', () => {
const separator = new SeparatorBuilder().setSpacing(SeparatorSpacingSize.Large).setId(-1);
expect(() => separator.toJSON()).toThrowError();
});
});
}); });

View File

@@ -14,6 +14,11 @@ describe('TextDisplay', () => {
expect(textDisplay.toJSON()).toEqual({ type: ComponentType.TextDisplay, content: 'foo' }); expect(textDisplay.toJSON()).toEqual({ type: ComponentType.TextDisplay, content: 'foo' });
}); });
test('GIVEN a text display with a set content with an invalid id THEN throws error', () => {
const textDisplay = new TextDisplayBuilder().setContent('foo').setId(5.5);
expect(() => textDisplay.toJSON()).toThrowError();
});
test('GIVEN a text display with a pre-defined content THEN overwritten content THEN return valid toJSON data', () => { test('GIVEN a text display with a pre-defined content THEN overwritten content THEN return valid toJSON data', () => {
const textDisplay = new TextDisplayBuilder({ content: 'foo' }); const textDisplay = new TextDisplayBuilder({ content: 'foo' });
textDisplay.setContent('bar'); textDisplay.setContent('bar');

View File

@@ -1,6 +1,7 @@
import { Locale } from 'discord-api-types/v10'; import { Locale } from 'discord-api-types/v10';
import { z } from 'zod'; import { z } from 'zod';
export const idPredicate = z.int().min(0).max(2_147_483_647).optional();
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();

View File

@@ -1,6 +1,6 @@
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';
import { customIdPredicate } from '../Assertions.js'; import { idPredicate, customIdPredicate } from '../Assertions.js';
const labelPredicate = z.string().min(1).max(80); const labelPredicate = z.string().min(1).max(80);
@@ -52,6 +52,7 @@ export const buttonPredicate = z.discriminatedUnion('style', [
]); ]);
const selectMenuBasePredicate = z.object({ const selectMenuBasePredicate = z.object({
id: idPredicate,
placeholder: z.string().max(150).optional(), placeholder: z.string().max(150).optional(),
min_values: z.number().min(0).max(25).optional(), min_values: z.number().min(0).max(25).optional(),
max_values: z.number().min(0).max(25).optional(), max_values: z.number().min(0).max(25).optional(),
@@ -135,6 +136,7 @@ export const selectMenuUserPredicate = selectMenuBasePredicate.extend({
}); });
export const actionRowPredicate = z.object({ export const actionRowPredicate = z.object({
id: idPredicate,
type: z.literal(ComponentType.ActionRow), type: z.literal(ComponentType.ActionRow),
components: z.union([ components: z.union([
z z

View File

@@ -1,5 +1,6 @@
import { ComponentType } from 'discord-api-types/v10'; import { ComponentType } from 'discord-api-types/v10';
import { z } from 'zod'; import { z } from 'zod';
import { idPredicate } from '../../Assertions';
import { import {
selectMenuChannelPredicate, selectMenuChannelPredicate,
selectMenuMentionablePredicate, selectMenuMentionablePredicate,
@@ -10,6 +11,7 @@ import {
import { textInputPredicate } from '../textInput/Assertions'; import { textInputPredicate } from '../textInput/Assertions';
export const labelPredicate = z.object({ export const labelPredicate = z.object({
id: idPredicate,
type: z.literal(ComponentType.Label), type: z.literal(ComponentType.Label),
label: z.string().min(1).max(45), label: z.string().min(1).max(45),
description: z.string().min(1).max(100).optional(), description: z.string().min(1).max(100).optional(),

View File

@@ -1,8 +1,9 @@
import { ComponentType, TextInputStyle } from 'discord-api-types/v10'; import { ComponentType, TextInputStyle } from 'discord-api-types/v10';
import { z } from 'zod'; import { z } from 'zod';
import { customIdPredicate } from '../../Assertions.js'; import { customIdPredicate, idPredicate } from '../../Assertions.js';
export const textInputPredicate = z.object({ export const textInputPredicate = z.object({
id: idPredicate,
type: z.literal(ComponentType.TextInput), type: z.literal(ComponentType.TextInput),
custom_id: customIdPredicate, custom_id: customIdPredicate,
style: z.enum(TextInputStyle), style: z.enum(TextInputStyle),

View File

@@ -1,5 +1,6 @@
import { ComponentType, SeparatorSpacingSize } from 'discord-api-types/v10'; import { ComponentType, SeparatorSpacingSize } from 'discord-api-types/v10';
import { z } from 'zod'; import { z } from 'zod';
import { idPredicate } from '../../Assertions.js';
import { actionRowPredicate } from '../Assertions.js'; import { actionRowPredicate } from '../Assertions.js';
const unfurledMediaItemPredicate = z.object({ const unfurledMediaItemPredicate = z.object({
@@ -8,6 +9,7 @@ const unfurledMediaItemPredicate = z.object({
export const thumbnailPredicate = z.object({ export const thumbnailPredicate = z.object({
type: z.literal(ComponentType.Thumbnail), type: z.literal(ComponentType.Thumbnail),
id: idPredicate,
media: unfurledMediaItemPredicate, media: unfurledMediaItemPredicate,
description: z.string().min(1).max(1_024).nullish(), description: z.string().min(1).max(1_024).nullish(),
spoiler: z.boolean().optional(), spoiler: z.boolean().optional(),
@@ -19,22 +21,26 @@ const unfurledMediaItemAttachmentOnlyPredicate = z.object({
export const filePredicate = z.object({ export const filePredicate = z.object({
type: z.literal(ComponentType.File), type: z.literal(ComponentType.File),
id: idPredicate,
file: unfurledMediaItemAttachmentOnlyPredicate, file: unfurledMediaItemAttachmentOnlyPredicate,
spoiler: z.boolean().optional(), spoiler: z.boolean().optional(),
}); });
export const separatorPredicate = z.object({ export const separatorPredicate = z.object({
type: z.literal(ComponentType.Separator), type: z.literal(ComponentType.Separator),
id: idPredicate,
divider: z.boolean().optional(), divider: z.boolean().optional(),
spacing: z.enum(SeparatorSpacingSize).optional(), spacing: z.enum(SeparatorSpacingSize).optional(),
}); });
export const textDisplayPredicate = z.object({ export const textDisplayPredicate = z.object({
type: z.literal(ComponentType.TextDisplay), type: z.literal(ComponentType.TextDisplay),
id: idPredicate,
content: z.string().min(1).max(4_000), content: z.string().min(1).max(4_000),
}); });
export const mediaGalleryItemPredicate = z.object({ export const mediaGalleryItemPredicate = z.object({
id: idPredicate,
media: unfurledMediaItemPredicate, media: unfurledMediaItemPredicate,
description: z.string().min(1).max(1_024).nullish(), description: z.string().min(1).max(1_024).nullish(),
spoiler: z.boolean().optional(), spoiler: z.boolean().optional(),
@@ -42,11 +48,13 @@ export const mediaGalleryItemPredicate = z.object({
export const mediaGalleryPredicate = z.object({ export const mediaGalleryPredicate = z.object({
type: z.literal(ComponentType.MediaGallery), type: z.literal(ComponentType.MediaGallery),
id: idPredicate,
items: z.array(mediaGalleryItemPredicate).min(1).max(10), items: z.array(mediaGalleryItemPredicate).min(1).max(10),
}); });
export const sectionPredicate = z.object({ export const sectionPredicate = z.object({
type: z.literal(ComponentType.Section), type: z.literal(ComponentType.Section),
id: idPredicate,
components: z.array(textDisplayPredicate).min(1).max(3), components: z.array(textDisplayPredicate).min(1).max(3),
accessory: z.union([ accessory: z.union([
z.object({ type: z.literal(ComponentType.Button) }), z.object({ type: z.literal(ComponentType.Button) }),
@@ -56,6 +64,7 @@ export const sectionPredicate = z.object({
export const containerPredicate = z.object({ export const containerPredicate = z.object({
type: z.literal(ComponentType.Container), type: z.literal(ComponentType.Container),
id: idPredicate,
components: z components: z
.array( .array(
z.union([ z.union([