From 4512a6dceae88acfea583b7b8edbbe6fa67c2fa1 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Tue, 26 Jul 2022 18:51:31 +0100 Subject: [PATCH 1/4] feat: add URL formatters --- .../__tests__/messages/formatters.test.ts | 30 ++++++++++ packages/builders/src/messages/formatters.ts | 57 +++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/packages/builders/__tests__/messages/formatters.test.ts b/packages/builders/__tests__/messages/formatters.test.ts index febe7c4e3f95..185b9232c5c9 100644 --- a/packages/builders/__tests__/messages/formatters.test.ts +++ b/packages/builders/__tests__/messages/formatters.test.ts @@ -3,6 +3,7 @@ import { describe, test, expect, vitest } from 'vitest'; import { blockQuote, bold, + channelLink, channelMention, codeBlock, Faces, @@ -11,6 +12,7 @@ import { hyperlink, inlineCode, italic, + messageLink, quote, roleMention, spoiler, @@ -150,6 +152,34 @@ describe('Message formatters', () => { }); }); + describe('channelLink', () => { + test('GIVEN channelId THEN returns "https://discord.com/channels/@me/${channelId}"', () => { + expect<'https://discord.com/channels/@me/123456789012345678'>(channelLink('123456789012345678')).toEqual( + 'https://discord.com/channels/@me/123456789012345678', + ); + }); + + test('GIVEN channelId WITH guildId THEN returns "https://discord.com/channels/987654321987654/123456789012345678"', () => { + expect<'https://discord.com/channels/987654321987654/123456789012345678'>( + channelLink('123456789012345678', '987654321987654'), + ).toEqual('https://discord.com/channels/987654321987654/123456789012345678'); + }); + }); + + describe('messageLink', () => { + test('GIVEN channelId AND messageId THEN returns "`https://discord.com/channels/@me/123456789012345678/102938475657483"', () => { + expect<'https://discord.com/channels/@me/123456789012345678/102938475657483'>( + messageLink('123456789012345678', '102938475657483'), + ).toEqual('https://discord.com/channels/@me/123456789012345678/102938475657483'); + }); + + test('GIVEN channelId AND messageId WITH guildId THEN returns "https://discord.com/channels/987654321987654/123456789012345678/102938475657483"', () => { + expect<'https://discord.com/channels/987654321987654/123456789012345678/102938475657483'>( + messageLink('123456789012345678', '102938475657483', '987654321987654'), + ).toEqual('https://discord.com/channels/987654321987654/123456789012345678/102938475657483'); + }); + }); + describe('time', () => { test('GIVEN no arguments THEN returns ""', () => { vitest.useFakeTimers(); diff --git a/packages/builders/src/messages/formatters.ts b/packages/builders/src/messages/formatters.ts index 73f0b024b9b4..794cf4ec0a30 100644 --- a/packages/builders/src/messages/formatters.ts +++ b/packages/builders/src/messages/formatters.ts @@ -207,6 +207,63 @@ export function formatEmoji(emojiId: C, animated = false): return `<${animated ? 'a' : ''}:_:${emojiId}>`; } +/** + * Formats a channel link for a direct message channel. + * + * @param channelId - The channel's id + */ +export function channelLink(channelId: C): `https://discord.com/channels/@me/${C}`; + +/** + * Formats a channel link for a guild channel. + * + * @param channelId - The channel's id + * @param guildId - The guild's id + */ +export function channelLink( + channelId: C, + guildId: G, +): `https://discord.com/channels/${G}/${C}`; + +export function channelLink( + channelId: C, + guildId?: G, +): `https://discord.com/channels/@me/${C}` | `https://discord.com/channels/${G}/${C}` { + return `https://discord.com/channels/${guildId ?? '@me'}/${channelId}`; +} + +/** + * Formats a message link for a direct message channel. + * + * @param channelId - The channel's id + * @param messageId - The message's id + */ +export function messageLink( + channelId: C, + messageId: M, +): `https://discord.com/channels/@me/${C}/${M}`; + +/** + * Formats a message link for a guild channel. + * + * @param channelId - The channel's id + * @param messageId - The message's id + * @param guildId - The guild's id + */ +export function messageLink( + channelId: C, + messageId: M, + guildId: G, +): `https://discord.com/channels/${G}/${C}/${M}`; + +export function messageLink( + channelId: C, + messageId: M, + guildId?: G, +): `https://discord.com/channels/@me/${C}/${M}` | `https://discord.com/channels/${G}/${C}/${M}` { + return `${typeof guildId === 'undefined' ? channelLink(channelId) : channelLink(channelId, guildId)}/${messageId}`; +} + /** * Formats a date into a short date-time string * From 060522460e9925415a0ecc8faa49871a1869da71 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Tue, 26 Jul 2022 19:14:48 +0100 Subject: [PATCH 2/4] refactor: use new builders methods in discord.js --- packages/discord.js/src/structures/BaseChannel.js | 3 ++- packages/discord.js/src/structures/Message.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/discord.js/src/structures/BaseChannel.js b/packages/discord.js/src/structures/BaseChannel.js index 76ed7c7e9a2d..49d611436e19 100644 --- a/packages/discord.js/src/structures/BaseChannel.js +++ b/packages/discord.js/src/structures/BaseChannel.js @@ -1,5 +1,6 @@ 'use strict'; +const { channelLink } = require('@discordjs/builders'); const { DiscordSnowflake } = require('@sapphire/snowflake'); const { ChannelType, Routes } = require('discord-api-types/v10'); const Base = require('./Base'); @@ -55,7 +56,7 @@ class BaseChannel extends Base { * @readonly */ get url() { - return `https://discord.com/channels/${this.isDMBased() ? '@me' : this.guildId}/${this.id}`; + return this.isDMBased() ? channelLink(this.id) : channelLink(this.id, this.guildId); } /** diff --git a/packages/discord.js/src/structures/Message.js b/packages/discord.js/src/structures/Message.js index 5e4753021f9d..2ce960c03aa8 100644 --- a/packages/discord.js/src/structures/Message.js +++ b/packages/discord.js/src/structures/Message.js @@ -1,5 +1,6 @@ 'use strict'; +const { messageLink } = require('@discordjs/builders'); const { Collection } = require('@discordjs/collection'); const { DiscordSnowflake } = require('@sapphire/snowflake'); const { @@ -439,7 +440,7 @@ class Message extends Base { * @readonly */ get url() { - return `https://discord.com/channels/${this.guildId ?? '@me'}/${this.channelId}/${this.id}`; + return this.inGuild() ? messageLink(this.channelId, this.id, this.guildId) : messageLink(this.channelId, this.id); } /** From d0eb520ea6067bfd7f7e064ebe29ef713364222c Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Wed, 27 Jul 2022 00:59:47 +0100 Subject: [PATCH 3/4] docs: document top-level exports --- packages/discord.js/src/util/Formatters.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/packages/discord.js/src/util/Formatters.js b/packages/discord.js/src/util/Formatters.js index 7a188286e8ca..9d4c28240c92 100644 --- a/packages/discord.js/src/util/Formatters.js +++ b/packages/discord.js/src/util/Formatters.js @@ -132,6 +132,23 @@ const { * @returns {string} */ +/** + * Formats a channel link for a channel. + * @method channelLink + * @param {Snowflake} channelId The id of the channel + * @param {Snowflake} [guildId] The id of the guild + * @returns {string} + */ + +/** + * Formats a message link for a channel. + * @method messageLink + * @param {Snowflake} channelId The id of the channel + * @param {Snowflake} messageId The id of the message + * @param {Snowflake} [guildId] The id of the guild + * @returns {string} + */ + /** * A message formatting timestamp style, as defined in * [here](https://discord.com/developers/docs/reference#message-formatting-timestamp-styles). From 07685caba9cb6bbbc23b98f1f7ed4696dbb348c2 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Wed, 27 Jul 2022 10:33:23 +0100 Subject: [PATCH 4/4] test: consistency in names --- packages/builders/__tests__/messages/formatters.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/builders/__tests__/messages/formatters.test.ts b/packages/builders/__tests__/messages/formatters.test.ts index 185b9232c5c9..92a291f81ac7 100644 --- a/packages/builders/__tests__/messages/formatters.test.ts +++ b/packages/builders/__tests__/messages/formatters.test.ts @@ -159,7 +159,7 @@ describe('Message formatters', () => { ); }); - test('GIVEN channelId WITH guildId THEN returns "https://discord.com/channels/987654321987654/123456789012345678"', () => { + test('GIVEN channelId WITH guildId THEN returns "https://discord.com/channels/${guildId}/${channelId}"', () => { expect<'https://discord.com/channels/987654321987654/123456789012345678'>( channelLink('123456789012345678', '987654321987654'), ).toEqual('https://discord.com/channels/987654321987654/123456789012345678'); @@ -167,13 +167,13 @@ describe('Message formatters', () => { }); describe('messageLink', () => { - test('GIVEN channelId AND messageId THEN returns "`https://discord.com/channels/@me/123456789012345678/102938475657483"', () => { + test('GIVEN channelId AND messageId THEN returns "https://discord.com/channels/@me/${channelId}/${messageId}"', () => { expect<'https://discord.com/channels/@me/123456789012345678/102938475657483'>( messageLink('123456789012345678', '102938475657483'), ).toEqual('https://discord.com/channels/@me/123456789012345678/102938475657483'); }); - test('GIVEN channelId AND messageId WITH guildId THEN returns "https://discord.com/channels/987654321987654/123456789012345678/102938475657483"', () => { + test('GIVEN channelId AND messageId WITH guildId THEN returns "https://discord.com/channels/${guildId}/${channelId}/${messageId}"', () => { expect<'https://discord.com/channels/987654321987654/123456789012345678/102938475657483'>( messageLink('123456789012345678', '102938475657483', '987654321987654'), ).toEqual('https://discord.com/channels/987654321987654/123456789012345678/102938475657483');