Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
12 changes: 12 additions & 0 deletions packages/builders/__tests__/messages/embed.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ describe('Embed', () => {
expect(embed.toJSON()).toStrictEqual({ ...base, thumbnail: { url: 'https://discord.js.org/static/logo.svg' } });
});

test('GIVEN an embed using Embed#setThumbnail with attachment protocol THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setThumbnail('attachment://discordjs.webp');
expect(embed.toJSON()).toStrictEqual({ ...base, thumbnail: { url: 'attachment://discordjs.webp' } });
});

test('GIVEN an embed with a pre-defined thumbnail THEN unset thumbnail THEN return valid toJSON data', () => {
const embed = new EmbedBuilder({ thumbnail: { url: 'https://discord.js.org/static/logo.svg' }, ...dummy });
embed.clearThumbnail();
Expand All @@ -228,6 +234,12 @@ describe('Embed', () => {
expect(embed.toJSON()).toStrictEqual({ ...base, image: { url: 'https://discord.js.org/static/logo.svg' } });
});

test('GIVEN an embed using Embed#setImage with attachment protocol THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setImage('attachment://discordjs.webp');
expect(embed.toJSON()).toStrictEqual({ ...base, image: { url: 'attachment://discordjs.webp' } });
});

test('GIVEN an embed using Embed#setImage THEN returns valid toJSON data', () => {
const embed = new EmbedBuilder();
embed.setImage('https://discord.js.org/static/logo.svg');
Expand Down
20 changes: 10 additions & 10 deletions packages/builders/src/messages/embed/Assertions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ import { embedLength } from '../../util/componentUtil.js';

const namePredicate = z.string().max(256);

const iconURLPredicate = z
const URLPredicate = z
.string()
.url()
.refine(refineURLPredicate(['http:', 'https:', 'attachment:']), {
message: 'Invalid protocol for icon URL. Must be http:, https:, or attachment:',
});
.refine(refineURLPredicate(['http:', 'https:']), { message: 'Invalid protocol for URL. Must be http: or https:' });

const URLPredicate = z
const URLWithAttachmentProtocolPredicate = z
.string()
.url()
.refine(refineURLPredicate(['http:', 'https:']), { message: 'Invalid protocol for URL. Must be http: or https:' });
.refine(refineURLPredicate(['http:', 'https:', 'attachment:']), {
message: 'Invalid protocol for URL. Must be http:, https:, or attachment:',
});

export const embedFieldPredicate = z.object({
name: namePredicate,
Expand All @@ -24,13 +24,13 @@ export const embedFieldPredicate = z.object({

export const embedAuthorPredicate = z.object({
name: namePredicate.min(1),
icon_url: iconURLPredicate.optional(),
icon_url: URLWithAttachmentProtocolPredicate.optional(),
url: URLPredicate.optional(),
});

export const embedFooterPredicate = z.object({
text: z.string().min(1).max(2_048),
icon_url: iconURLPredicate.optional(),
icon_url: URLWithAttachmentProtocolPredicate.optional(),
});

export const embedPredicate = z
Expand All @@ -41,8 +41,8 @@ export const embedPredicate = z
timestamp: z.string().optional(),
color: z.number().int().min(0).max(0xffffff).optional(),
footer: embedFooterPredicate.optional(),
image: z.object({ url: URLPredicate }).optional(),
thumbnail: z.object({ url: URLPredicate }).optional(),
image: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
thumbnail: z.object({ url: URLWithAttachmentProtocolPredicate }).optional(),
author: embedAuthorPredicate.optional(),
fields: z.array(embedFieldPredicate).max(25).optional(),
})
Expand Down