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

@@ -0,0 +1,55 @@
import { Buffer } from 'node:buffer';
import type { RawFile } from '@discordjs/util';
import { test, expect } from 'vitest';
import { AttachmentBuilder, MessageBuilder } from '../../src/index.js';
test('AttachmentBuilder stores and exposes file data', () => {
const data = Buffer.from('hello world');
const attachment = new AttachmentBuilder()
.setId('0')
.setFilename('greeting.txt')
.setFileData(data)
.setFileContentType('text/plain');
expect(attachment.getRawFile()).toStrictEqual({
contentType: 'text/plain',
data,
key: 'files[0]',
name: 'greeting.txt',
});
attachment.clearFileData();
attachment.clearFileContentType();
attachment.clearFilename();
expect(attachment.getRawFile()).toBe(undefined);
});
test('MessageBuilder.toFileBody returns JSON body and files', () => {
const msg = new MessageBuilder().setContent('here is a file').addAttachments(
new AttachmentBuilder()
.setId('0')
.setFilename('file.bin')
.setFileData(Buffer.from([1, 2, 3]))
.setFileContentType('application/octet-stream'),
);
const { body, files } = msg.toFileBody();
// body should match toJSON()
expect(body).toStrictEqual(msg.toJSON());
// files should contain the uploaded file
expect(files).toHaveLength(1);
const [fileEntry] = files as [RawFile];
expect(fileEntry.name).toBe('file.bin');
expect(fileEntry.contentType).toBe('application/octet-stream');
expect(fileEntry.data).toBeDefined();
});
test('MessageBuilder.toFileBody returns empty files when attachments reference existing uploads', () => {
const msg = new MessageBuilder().addAttachments(new AttachmentBuilder().setId('123').setFilename('existing.png'));
const { body, files } = msg.toFileBody();
expect(body).toEqual(msg.toJSON());
expect(files.length).toBe(0);
});