Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions packages/builders/__tests__/messages/fileBody.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@ 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')
.setId(1)
.setFilename('greeting.txt')
.setFileData(data)
.setFileContentType('text/plain');

expect(attachment.getRawFile()).toStrictEqual({
contentType: 'text/plain',
data,
key: 'files[0]',
key: 'files[1]',
name: 'greeting.txt',
});

Expand All @@ -27,7 +27,7 @@ test('AttachmentBuilder stores and exposes file data', () => {
test('MessageBuilder.toFileBody returns JSON body and files', () => {
const msg = new MessageBuilder().setContent('here is a file').addAttachments(
new AttachmentBuilder()
.setId('0')
.setId(0)
.setFilename('file.bin')
.setFileData(Buffer.from([1, 2, 3]))
.setFileContentType('application/octet-stream'),
Expand All @@ -47,7 +47,9 @@ test('MessageBuilder.toFileBody returns JSON body and files', () => {
});

test('MessageBuilder.toFileBody returns empty files when attachments reference existing uploads', () => {
const msg = new MessageBuilder().addAttachments(new AttachmentBuilder().setId('123').setFilename('existing.png'));
const msg = new MessageBuilder().addAttachments(
new AttachmentBuilder().setId('12345678901234567890').setFilename('existing.png'),
);

const { body, files } = msg.toFileBody();
expect(body).toEqual(msg.toJSON());
Expand Down
4 changes: 2 additions & 2 deletions packages/builders/__tests__/messages/message.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe('Message', () => {
row.addPrimaryButtonComponents((button) => button.setCustomId('abc').setLabel('def')),
)
.setStickerIds('123', '456')
.addAttachments((attachment) => attachment.setId('hi!').setFilename('abc'))
.addAttachments((attachment) => attachment.setId(0).setFilename('abc'))
.setFlags(MessageFlags.Ephemeral)
.setEnforceNonce(false)
.updatePoll((poll) => poll.addAnswers({ poll_media: { text: 'foo' } }).setQuestion({ text: 'foo' }));
Expand All @@ -83,7 +83,7 @@ describe('Message', () => {
},
],
sticker_ids: ['123', '456'],
attachments: [{ id: 'hi!', filename: 'abc' }],
attachments: [{ id: 0, filename: 'abc' }],
flags: 64,
enforce_nonce: false,
poll: {
Expand Down
1 change: 1 addition & 0 deletions packages/builders/src/Assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ 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 snowflakePredicate = z.string().regex(/^\d{17,20}$/);

export const memberPermissionsPredicate = z.coerce.bigint();

Expand Down
14 changes: 7 additions & 7 deletions packages/builders/src/components/Assertions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ButtonStyle, ChannelType, ComponentType, SelectMenuDefaultValueType } from 'discord-api-types/v10';
import { z } from 'zod';
import { idPredicate, customIdPredicate } from '../Assertions.js';
import { idPredicate, customIdPredicate, snowflakePredicate } from '../Assertions.js';

const labelPredicate = z.string().min(1).max(80);

export const emojiPredicate = z
.strictObject({
id: z.string().optional(),
id: snowflakePredicate.optional(),
name: z.string().min(2).max(32).optional(),
animated: z.boolean().optional(),
})
Expand Down Expand Up @@ -39,7 +39,7 @@ const buttonLinkPredicate = buttonPredicateBase.extend({

const buttonPremiumPredicate = buttonPredicateBase.extend({
style: z.literal(ButtonStyle.Premium),
sku_id: z.string(),
sku_id: snowflakePredicate,
});

export const buttonPredicate = z.discriminatedUnion('style', [
Expand All @@ -64,7 +64,7 @@ export const selectMenuChannelPredicate = selectMenuBasePredicate.extend({
type: z.literal(ComponentType.ChannelSelect),
channel_types: z.enum(ChannelType).array().optional(),
default_values: z
.object({ id: z.string(), type: z.literal(SelectMenuDefaultValueType.Channel) })
.object({ id: snowflakePredicate, type: z.literal(SelectMenuDefaultValueType.Channel) })
.array()
.max(25)
.optional(),
Expand All @@ -74,7 +74,7 @@ export const selectMenuMentionablePredicate = selectMenuBasePredicate.extend({
type: z.literal(ComponentType.MentionableSelect),
default_values: z
.object({
id: z.string(),
id: snowflakePredicate,
type: z.literal([SelectMenuDefaultValueType.Role, SelectMenuDefaultValueType.User]),
})
.array()
Expand All @@ -85,7 +85,7 @@ export const selectMenuMentionablePredicate = selectMenuBasePredicate.extend({
export const selectMenuRolePredicate = selectMenuBasePredicate.extend({
type: z.literal(ComponentType.RoleSelect),
default_values: z
.object({ id: z.string(), type: z.literal(SelectMenuDefaultValueType.Role) })
.object({ id: snowflakePredicate, type: z.literal(SelectMenuDefaultValueType.Role) })
.array()
.max(25)
.optional(),
Expand Down Expand Up @@ -142,7 +142,7 @@ export const selectMenuStringPredicate = selectMenuBasePredicate
export const selectMenuUserPredicate = selectMenuBasePredicate.extend({
type: z.literal(ComponentType.UserSelect),
default_values: z
.object({ id: z.string(), type: z.literal(SelectMenuDefaultValueType.User) })
.object({ id: snowflakePredicate, type: z.literal(SelectMenuDefaultValueType.User) })
.array()
.max(25)
.optional(),
Expand Down
3 changes: 2 additions & 1 deletion packages/builders/src/messages/Assertions.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Buffer } from 'node:buffer';
import { AllowedMentionsTypes, ComponentType, MessageFlags, MessageReferenceType } from 'discord-api-types/v10';
import { z } from 'zod';
import { snowflakePredicate } from '../Assertions.js';
import { embedPredicate } from './embed/Assertions.js';
import { pollPredicate } from './poll/Assertions.js';

Expand All @@ -15,7 +16,7 @@ export const rawFilePredicate = z.object({

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()]),
id: z.union([snowflakePredicate, z.number()]),
description: z.string().max(1_024).optional(),
duration_secs: z
.number()
Expand Down