Skip to content

Commit

Permalink
feat: Add channel & message URL formatters (#8371)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jiralite committed Jul 29, 2022
1 parent b4e2c0c commit a7deb8f
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 2 deletions.
30 changes: 30 additions & 0 deletions packages/builders/__tests__/messages/formatters.test.ts
Expand Up @@ -3,6 +3,7 @@ import { describe, test, expect, vitest } from 'vitest';
import {
blockQuote,
bold,
channelLink,
channelMention,
codeBlock,
Faces,
Expand All @@ -11,6 +12,7 @@ import {
hyperlink,
inlineCode,
italic,
messageLink,
quote,
roleMention,
spoiler,
Expand Down Expand Up @@ -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/${guildId}/${channelId}"', () => {
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/${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/${guildId}/${channelId}/${messageId}"', () => {
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 "<t:${bigint}>"', () => {
vitest.useFakeTimers();
Expand Down
57 changes: 57 additions & 0 deletions packages/builders/src/messages/formatters.ts
Expand Up @@ -207,6 +207,63 @@ export function formatEmoji<C extends Snowflake>(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<C extends Snowflake>(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<C extends Snowflake, G extends Snowflake>(
channelId: C,
guildId: G,
): `https://discord.com/channels/${G}/${C}`;

export function channelLink<C extends Snowflake, G extends Snowflake>(
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<C extends Snowflake, M extends Snowflake>(
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<C extends Snowflake, M extends Snowflake, G extends Snowflake>(
channelId: C,
messageId: M,
guildId: G,
): `https://discord.com/channels/${G}/${C}/${M}`;

export function messageLink<C extends Snowflake, M extends Snowflake, G extends Snowflake>(
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
*
Expand Down
3 changes: 2 additions & 1 deletion 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');
Expand Down Expand Up @@ -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);
}

/**
Expand Down
3 changes: 2 additions & 1 deletion 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 {
Expand Down Expand Up @@ -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);
}

/**
Expand Down
17 changes: 17 additions & 0 deletions packages/discord.js/src/util/Formatters.js
Expand Up @@ -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).
Expand Down

0 comments on commit a7deb8f

Please sign in to comment.