mirror of
https://github.com/discordjs/discord.js.git
synced 2026-03-19 04:53:30 +01:00
feat: components v2 in builders (#10788)
* feat: thumbnail component * chore: just a temp file to track remaining components * feat: file component * feat: section component * feat: text display component * chore: bump alpha version of dtypes * chore: simplify ComponentBuilder base type * feat: MediaGallery * feat: Section builder * chore: tests for sections * chore: forgot you * chore: docs * fix: missing comma * fix: my bad * feat: container builder * chore: requested changes * chore: missed u * chore: type tests * chore: setId/clearId * chore: apply suggestions from code review * chore: unify pick * chore: some requested changes * chore: tests and small fixes * chore: added tests that need fixing * fix: tests * chore: cleanup on isle protected * docs: remove locale * chore: types for new message builder * chore: fix tests * chore: attempt 1 at message builder assertions * chore: apply suggestions * Update packages/builders/src/messages/Assertions.ts Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> * Update packages/builders/src/components/v2/Thumbnail.ts Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> * fix: tests * chore: fmt * Apply suggestions from code review Co-authored-by: Denis-Adrian Cristea <didinele.dev@gmail.com> * chore: fix pnpm lockfile revert --------- Co-authored-by: Qjuh <76154676+Qjuh@users.noreply.github.com> Co-authored-by: Jiralite <33201955+Jiralite@users.noreply.github.com> Co-authored-by: Denis-Adrian Cristea <didinele.dev@gmail.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { AllowedMentionsTypes, ComponentType, MessageReferenceType } from 'discord-api-types/v10';
|
||||
import { AllowedMentionsTypes, ComponentType, MessageFlags, MessageReferenceType } from 'discord-api-types/v10';
|
||||
import { z } from 'zod';
|
||||
import { embedPredicate } from './embed/Assertions.js';
|
||||
import { pollPredicate } from './poll/Assertions.js';
|
||||
@@ -27,40 +27,49 @@ export const messageReferencePredicate = z.object({
|
||||
type: z.nativeEnum(MessageReferenceType).optional(),
|
||||
});
|
||||
|
||||
export const messagePredicate = z
|
||||
.object({
|
||||
const baseMessagePredicate = z.object({
|
||||
nonce: z.union([z.string().max(25), z.number()]).optional(),
|
||||
tts: z.boolean().optional(),
|
||||
allowed_mentions: allowedMentionPredicate.optional(),
|
||||
message_reference: messageReferencePredicate.optional(),
|
||||
attachments: attachmentPredicate.array().max(10).optional(),
|
||||
enforce_nonce: z.boolean().optional(),
|
||||
});
|
||||
|
||||
const basicActionRowPredicate = z.object({
|
||||
type: z.literal(ComponentType.ActionRow),
|
||||
components: z
|
||||
.object({
|
||||
type: z.union([
|
||||
z.literal(ComponentType.Button),
|
||||
z.literal(ComponentType.ChannelSelect),
|
||||
z.literal(ComponentType.MentionableSelect),
|
||||
z.literal(ComponentType.RoleSelect),
|
||||
z.literal(ComponentType.StringSelect),
|
||||
z.literal(ComponentType.UserSelect),
|
||||
]),
|
||||
})
|
||||
.array(),
|
||||
});
|
||||
|
||||
const messageNoComponentsV2Predicate = baseMessagePredicate
|
||||
.extend({
|
||||
content: z.string().optional(),
|
||||
nonce: z.union([z.string().max(25), z.number()]).optional(),
|
||||
tts: z.boolean().optional(),
|
||||
embeds: embedPredicate.array().max(10).optional(),
|
||||
allowed_mentions: allowedMentionPredicate.optional(),
|
||||
message_reference: messageReferencePredicate.optional(),
|
||||
// Partial validation here to ensure the components are valid,
|
||||
// rest of the validation is done in the action row predicate
|
||||
components: z
|
||||
.object({
|
||||
type: z.literal(ComponentType.ActionRow),
|
||||
components: z
|
||||
.object({
|
||||
type: z.union([
|
||||
z.literal(ComponentType.Button),
|
||||
z.literal(ComponentType.ChannelSelect),
|
||||
z.literal(ComponentType.MentionableSelect),
|
||||
z.literal(ComponentType.RoleSelect),
|
||||
z.literal(ComponentType.StringSelect),
|
||||
z.literal(ComponentType.UserSelect),
|
||||
]),
|
||||
})
|
||||
.array(),
|
||||
})
|
||||
.array()
|
||||
.max(5)
|
||||
.optional(),
|
||||
sticker_ids: z.array(z.string()).min(0).max(3).optional(),
|
||||
attachments: attachmentPredicate.array().max(10).optional(),
|
||||
flags: z.number().optional(),
|
||||
enforce_nonce: z.boolean().optional(),
|
||||
poll: pollPredicate.optional(),
|
||||
components: basicActionRowPredicate.array().max(5).optional(),
|
||||
flags: z
|
||||
.number()
|
||||
.optional()
|
||||
.refine((flags) => {
|
||||
// If we have flags, ensure we don't have the ComponentsV2 flag
|
||||
if (flags) {
|
||||
return (flags & MessageFlags.IsComponentsV2) === 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}),
|
||||
})
|
||||
.refine(
|
||||
(data) =>
|
||||
@@ -70,5 +79,37 @@ export const messagePredicate = z
|
||||
(data.attachments !== undefined && data.attachments.length > 0) ||
|
||||
(data.components !== undefined && data.components.length > 0) ||
|
||||
(data.sticker_ids !== undefined && data.sticker_ids.length > 0),
|
||||
{ message: 'Messages must have content, embeds, a poll, attachments, components, or stickers' },
|
||||
{ message: 'Messages must have content, embeds, a poll, attachments, components or stickers' },
|
||||
);
|
||||
|
||||
const allTopLevelComponentsPredicate = z
|
||||
.union([
|
||||
basicActionRowPredicate,
|
||||
z.object({
|
||||
type: z.union([
|
||||
// Components v2
|
||||
z.literal(ComponentType.Container),
|
||||
z.literal(ComponentType.File),
|
||||
z.literal(ComponentType.MediaGallery),
|
||||
z.literal(ComponentType.Section),
|
||||
z.literal(ComponentType.Separator),
|
||||
z.literal(ComponentType.TextDisplay),
|
||||
z.literal(ComponentType.Thumbnail),
|
||||
]),
|
||||
}),
|
||||
])
|
||||
.array()
|
||||
.min(1)
|
||||
.max(10);
|
||||
|
||||
const messageComponentsV2Predicate = baseMessagePredicate.extend({
|
||||
components: allTopLevelComponentsPredicate,
|
||||
flags: z.number().refine((flags) => (flags & MessageFlags.IsComponentsV2) === MessageFlags.IsComponentsV2),
|
||||
// These fields cannot be set
|
||||
content: z.string().length(0).nullish(),
|
||||
embeds: z.array(z.never()).nullish(),
|
||||
sticker_ids: z.array(z.never()).nullish(),
|
||||
poll: z.null().optional(),
|
||||
});
|
||||
|
||||
export const messagePredicate = z.union([messageNoComponentsV2Predicate, messageComponentsV2Predicate]);
|
||||
|
||||
Reference in New Issue
Block a user