feat(builders): multipart form data output support (#11248)

* feat(builders): multipart form data output support

* refactor: proper key management

* chore: add missing remarks

* chore: requested changes

* chore: rename encodables file

* chore: requested changes

* chore: requested changes

* chore: nits

Co-authored-by: Almeida <github@almeidx.dev>

* chore: requested change

* chore: requested change

---------

Co-authored-by: Almeida <github@almeidx.dev>
This commit is contained in:
Denis-Adrian Cristea
2025-11-19 23:59:51 +02:00
committed by GitHub
parent 315f422781
commit 68bb8af58a
10 changed files with 277 additions and 50 deletions

View File

@@ -1,9 +1,20 @@
import { Buffer } from 'node:buffer';
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';
const fileKeyRegex = /^files\[(?<placeholder>\d+?)]$/;
export const rawFilePredicate = z.object({
data: z.union([z.instanceof(Buffer), z.instanceof(Uint8Array), z.string()]),
name: z.string().min(1),
contentType: z.string().optional(),
key: z.string().regex(fileKeyRegex).optional(),
});
export const attachmentPredicate = z.object({
// As a string it only makes sense for edits when we do have an attachment snowflake
id: z.union([z.string(), z.number()]),
description: z.string().max(1_024).optional(),
duration_secs: z
@@ -125,3 +136,11 @@ const messageComponentsV2Predicate = baseMessagePredicate.extend({
});
export const messagePredicate = z.union([messageNoComponentsV2Predicate, messageComponentsV2Predicate]);
// This validator does not assert file.key <-> attachment.id coherence. This is fine, because the builders
// should effectively guarantee that.
export const fileBodyMessagePredicate = z.object({
body: messagePredicate,
// No min length to support message edits
files: rawFilePredicate.array().max(10),
});