From 23e0ac56f456c39d925e2644ec3ca209d4410a99 Mon Sep 17 00:00:00 2001 From: Jiralite <33201955+Jiralite@users.noreply.github.com> Date: Mon, 10 Apr 2023 21:29:06 +0100 Subject: [PATCH] docs(formatters): Enhance the documentation (#9364) --- .../formatters/__tests__/formatters.test.ts | 19 +- packages/formatters/src/escapers.ts | 61 +++--- packages/formatters/src/formatters.ts | 204 +++++++++++------- 3 files changed, 173 insertions(+), 111 deletions(-) diff --git a/packages/formatters/__tests__/formatters.test.ts b/packages/formatters/__tests__/formatters.test.ts index beb136907..b6d3ea075 100644 --- a/packages/formatters/__tests__/formatters.test.ts +++ b/packages/formatters/__tests__/formatters.test.ts @@ -240,16 +240,19 @@ describe('Message formatters', () => { }); describe('Faces', () => { - test('GIVEN Faces.Shrug THEN returns "¯\\_(ツ)\\_/¯"', () => { - expect<'¯\\_(ツ)\\_/¯'>(Faces.Shrug).toEqual('¯\\_(ツ)\\_/¯'); + // prettier-ignore + /* eslint-disable no-useless-escape */ + test('GIVEN Faces.Shrug THEN returns "¯\_(ツ)_/¯"', () => { + expect<'¯\_(ツ)_/¯'>(Faces.Shrug).toEqual('¯\_(ツ)_/¯'); + }); + /* eslint-enable no-useless-escape */ + + test('GIVEN Faces.Tableflip THEN returns "(╯°□°)╯︵ ┻━┻"', () => { + expect<'(╯°□°)╯︵ ┻━┻'>(Faces.Tableflip).toEqual('(╯°□°)╯︵ ┻━┻'); }); - test('GIVEN Faces.Tableflip THEN returns "(╯°□°)╯︵ ┻━┻"', () => { - expect<'(╯°□°)╯︵ ┻━┻'>(Faces.Tableflip).toEqual('(╯°□°)╯︵ ┻━┻'); - }); - - test('GIVEN Faces.Unflip THEN returns "┬─┬ ノ( ゜-゜ノ)"', () => { - expect<'┬─┬ ノ( ゜-゜ノ)'>(Faces.Unflip).toEqual('┬─┬ ノ( ゜-゜ノ)'); + test('GIVEN Faces.Unflip THEN returns "┬─┬ノ( º _ ºノ)"', () => { + expect<'┬─┬ノ( º _ ºノ)'>(Faces.Unflip).toEqual('┬─┬ノ( º _ ºノ)'); }); }); }); diff --git a/packages/formatters/src/escapers.ts b/packages/formatters/src/escapers.ts index 3575c0a3d..1c89ce193 100644 --- a/packages/formatters/src/escapers.ts +++ b/packages/formatters/src/escapers.ts @@ -1,106 +1,109 @@ /* eslint-disable prefer-named-capture-group */ +/** + * The options that affect what will be escaped. + */ export interface EscapeMarkdownOptions { /** - * Whether to escape bolds + * Whether to escape bold text. * - * @defaultValue true + * @defaultValue `true` */ bold?: boolean; /** - * Whether to escape bulleted lists + * Whether to escape bulleted lists. * - * @defaultValue false + * @defaultValue `false` */ bulletedList?: boolean; /** - * Whether to escape code blocks + * Whether to escape code blocks. * - * @defaultValue true + * @defaultValue `true` */ codeBlock?: boolean; /** - * Whether to escape text inside code blocks + * Whether to escape text inside code blocks. * - * @defaultValue true + * @defaultValue `true` */ codeBlockContent?: boolean; /** - * Whether to escape escape characters + * Whether to escape `\`. * - * @defaultValue true + * @defaultValue `true` */ escape?: boolean; /** - * Whether to escape headings + * Whether to escape headings. * - * @defaultValue false + * @defaultValue `false` */ heading?: boolean; /** - * Whether to escape inline code + * Whether to escape inline code. * - * @defaultValue true + * @defaultValue `true` */ inlineCode?: boolean; /** - * Whether to escape text inside inline code + * Whether to escape text inside inline code. * - * @defaultValue true + * @defaultValue `true` */ inlineCodeContent?: boolean; /** - * Whether to escape italics + * Whether to escape italics. * - * @defaultValue true + * @defaultValue `true` */ italic?: boolean; /** - * Whether to escape masked links + * Whether to escape masked links. * - * @defaultValue false + * @defaultValue `false` */ maskedLink?: boolean; /** - * Whether to escape numbered lists + * Whether to escape numbered lists. * - * @defaultValue false + * @defaultValue `false` */ numberedList?: boolean; /** - * Whether to escape spoilers + * Whether to escape spoilers. * - * @defaultValue true + * @defaultValue `true` */ spoiler?: boolean; /** - * Whether to escape strikethroughs + * Whether to escape strikethroughs. * - * @defaultValue true + * @defaultValue `true` */ strikethrough?: boolean; /** - * Whether to escape underlines + * Whether to escape underlines. * - * @defaultValue true + * @defaultValue `true` */ underline?: boolean; } /** - * Escapes any Discord-flavour markdown in a string. + * Escapes any Discord-flavored markdown in a string. * * @param text - Content to escape * @param options - Options for escaping the markdown diff --git a/packages/formatters/src/formatters.ts b/packages/formatters/src/formatters.ts index 8b253a977..1faeb0c45 100644 --- a/packages/formatters/src/formatters.ts +++ b/packages/formatters/src/formatters.ts @@ -2,26 +2,31 @@ import type { URL } from 'node:url'; import type { Snowflake } from 'discord-api-types/globals'; /** - * Wraps the content inside a codeblock with no language + * Wraps the content inside a code block with no language. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function codeBlock(content: C): `\`\`\`\n${C}\n\`\`\``; /** - * Wraps the content inside a codeblock with the specified language + * Wraps the content inside a code block with the specified language. * - * @param language - The language for the codeblock + * @typeParam L - This is inferred by the supplied language + * @typeParam C - This is inferred by the supplied content + * @param language - The language for the code block * @param content - The content to wrap */ export function codeBlock(language: L, content: C): `\`\`\`${L}\n${C}\n\`\`\``; + export function codeBlock(language: string, content?: string): string { return content === undefined ? `\`\`\`\n${language}\n\`\`\`` : `\`\`\`${language}\n${content}\n\`\`\``; } /** - * Wraps the content inside \`backticks\`, which formats it as inline code + * Wraps the content inside \`backticks\` which formats it as inline code. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function inlineCode(content: C): `\`${C}\`` { @@ -29,8 +34,9 @@ export function inlineCode(content: C): `\`${C}\`` { } /** - * Formats the content into italic text + * Formats the content into italic text. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function italic(content: C): `_${C}_` { @@ -38,8 +44,9 @@ export function italic(content: C): `_${C}_` { } /** - * Formats the content into bold text + * Formats the content into bold text. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function bold(content: C): `**${C}**` { @@ -47,8 +54,9 @@ export function bold(content: C): `**${C}**` { } /** - * Formats the content into underscored text + * Formats the content into underscored text. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function underscore(content: C): `__${C}__` { @@ -56,8 +64,9 @@ export function underscore(content: C): `__${C}__` { } /** - * Formats the content into strike-through text + * Formats the content into strike-through text. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function strikethrough(content: C): `~~${C}~~` { @@ -65,8 +74,10 @@ export function strikethrough(content: C): `~~${C}~~` { } /** - * Formats the content into a quote. This needs to be at the start of the line for Discord to format it + * Formats the content into a quote. * + * @remarks This needs to be at the start of the line for Discord to format it. + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function quote(content: C): `> ${C}` { @@ -74,8 +85,10 @@ export function quote(content: C): `> ${C}` { } /** - * Formats the content into a block quote. This needs to be at the start of the line for Discord to format it + * Formats the content into a block quote. * + * @remarks This needs to be at the start of the line for Discord to format it. + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function blockQuote(content: C): `>>> ${C}` { @@ -83,41 +96,48 @@ export function blockQuote(content: C): `>>> ${C}` { } /** - * Wraps the URL into `<>`, which stops it from embedding + * Wraps the URL into `<>` which stops it from embedding. * + * @typeParam C - This is inferred by the supplied content * @param url - The URL to wrap */ export function hideLinkEmbed(url: C): `<${C}>`; /** - * Wraps the URL into `<>`, which stops it from embedding + * Wraps the URL into `<>` which stops it from embedding. * * @param url - The URL to wrap */ export function hideLinkEmbed(url: URL): `<${string}>`; + export function hideLinkEmbed(url: URL | string) { return `<${url}>`; } /** - * Formats the content and the URL into a masked URL + * Formats the content and the URL into a masked URL. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to display * @param url - The URL the content links to */ export function hyperlink(content: C, url: URL): `[${C}](${string})`; /** - * Formats the content and the URL into a masked URL + * Formats the content and the URL into a masked URL. * + * @typeParam C - This is inferred by the supplied content + * @typeParam U - This is inferred by the supplied URL * @param content - The content to display * @param url - The URL the content links to */ export function hyperlink(content: C, url: U): `[${C}](${U})`; /** - * Formats the content and the URL into a masked URL + * Formats the content and the URL into a masked URL with a custom tooltip. * + * @typeParam C - This is inferred by the supplied content + * @typeParam T - This is inferred by the supplied title * @param content - The content to display * @param url - The URL the content links to * @param title - The title shown when hovering on the masked link @@ -129,8 +149,11 @@ export function hyperlink( ): `[${C}](${string} "${T}")`; /** - * Formats the content and the URL into a masked URL + * Formats the content and the URL into a masked URL with a custom tooltip. * + * @typeParam C - This is inferred by the supplied content + * @typeParam U - This is inferred by the supplied URL + * @typeParam T - This is inferred by the supplied title * @param content - The content to display * @param url - The URL the content links to * @param title - The title shown when hovering on the masked link @@ -140,13 +163,15 @@ export function hyperlink( url: U, title: T, ): `[${C}](${U} "${T}")`; + export function hyperlink(content: string, url: URL | string, title?: string) { return title ? `[${content}](${url} "${title}")` : `[${content}](${url})`; } /** - * Wraps the content inside spoiler (hidden text) + * Formats the content into a spoiler. * + * @typeParam C - This is inferred by the supplied content * @param content - The content to wrap */ export function spoiler(content: C): `||${C}||` { @@ -154,39 +179,46 @@ export function spoiler(content: C): `||${C}||` { } /** - * Formats a user ID into a user mention + * Formats a user id into a user mention. * - * @param userId - The user ID to format + * @typeParam C - This is inferred by the supplied user id + * @param userId - The user id to format */ export function userMention(userId: C): `<@${C}>` { return `<@${userId}>`; } /** - * Formats a channel ID into a channel mention + * Formats a channel id into a channel mention. * - * @param channelId - The channel ID to format + * @typeParam C - This is inferred by the supplied channel id + * @param channelId - The channel id to format */ export function channelMention(channelId: C): `<#${C}>` { return `<#${channelId}>`; } /** - * Formats a role ID into a role mention + * Formats a role id into a role mention. * - * @param roleId - The role ID to format + * @typeParam C - This is inferred by the supplied role id + * @param roleId - The role id to format */ export function roleMention(roleId: C): `<@&${C}>` { return `<@&${roleId}>`; } /** - * Formats an application command name, subcommand group name, subcommand name, and ID into an application command mention + * Formats an application command name, subcommand group name, subcommand name, and id into an application command mention. * + * @typeParam N - This is inferred by the supplied command name + * @typeParam G - This is inferred by the supplied subcommand group name + * @typeParam S - This is inferred by the supplied subcommand name + * @typeParam I - This is inferred by the supplied command id * @param commandName - The application command name to format * @param subcommandGroupName - The subcommand group name to format * @param subcommandName - The subcommand name to format - * @param commandId - The application command ID to format + * @param commandId - The application command id to format */ export function chatInputApplicationCommandMention< N extends string, @@ -196,11 +228,14 @@ export function chatInputApplicationCommandMention< >(commandName: N, subcommandGroupName: G, subcommandName: S, commandId: I): ``; /** - * Formats an application command name, subcommand name, and ID into an application command mention + * Formats an application command name, subcommand name, and id into an application command mention. * + * @typeParam N - This is inferred by the supplied command name + * @typeParam S - This is inferred by the supplied subcommand name + * @typeParam I - This is inferred by the supplied command id * @param commandName - The application command name to format * @param subcommandName - The subcommand name to format - * @param commandId - The application command ID to format + * @param commandId - The application command id to format */ export function chatInputApplicationCommandMention( commandName: N, @@ -209,24 +244,18 @@ export function chatInputApplicationCommandMention`; /** - * Formats an application command name and ID into an application command mention + * Formats an application command name and id into an application command mention. * + * @typeParam N - This is inferred by the supplied command name + * @typeParam I - This is inferred by the supplied command id * @param commandName - The application command name to format - * @param commandId - The application command ID to format + * @param commandId - The application command id to format */ export function chatInputApplicationCommandMention( commandName: N, commandId: I, ): ``; -/** - * Formats an application command name, subcommand group name, subcommand name, and ID into an application command mention - * - * @param commandName - The application command name to format - * @param subcommandGroupName - The subcommand group name to format - * @param subcommandName - The subcommand name to format - * @param commandId - The application command ID to format - */ export function chatInputApplicationCommandMention< N extends string, G extends Snowflake | string, @@ -250,34 +279,31 @@ export function chatInputApplicationCommandMention< } /** - * Formats an emoji ID into a fully qualified emoji identifier + * Formats a non-animated emoji id into a fully qualified emoji identifier. * - * @param emojiId - The emoji ID to format + * @typeParam C - This is inferred by the supplied emoji id + * @param emojiId - The emoji id to format */ export function formatEmoji(emojiId: C, animated?: false): `<:_:${C}>`; /** - * Formats an emoji ID into a fully qualified emoji identifier + * Formats an animated emoji id into a fully qualified emoji identifier. * - * @param emojiId - The emoji ID to format - * @param animated - Whether the emoji is animated or not. Defaults to `false` + * @typeParam C - This is inferred by the supplied emoji id + * @param emojiId - The emoji id to format + * @param animated - Whether the emoji is animated */ export function formatEmoji(emojiId: C, animated?: true): ``; /** - * Formats an emoji ID into a fully qualified emoji identifier + * Formats an emoji id into a fully qualified emoji identifier. * - * @param emojiId - The emoji ID to format - * @param animated - Whether the emoji is animated or not. Defaults to `false` + * @typeParam C - This is inferred by the supplied emoji id + * @param emojiId - The emoji id to format + * @param animated - Whether the emoji is animated */ export function formatEmoji(emojiId: C, animated?: boolean): `<:_:${C}>` | ``; -/** - * Formats an emoji ID into a fully qualified emoji identifier - * - * @param emojiId - The emoji ID to format - * @param animated - Whether the emoji is animated or not. Defaults to `false` - */ export function formatEmoji(emojiId: C, animated = false): `<:_:${C}>` | `` { return `<${animated ? 'a' : ''}:_:${emojiId}>`; } @@ -285,6 +311,7 @@ export function formatEmoji(emojiId: C, animated = false): /** * Formats a channel link for a direct message channel. * + * @typeParam C - This is inferred by the supplied channel id * @param channelId - The channel's id */ export function channelLink(channelId: C): `https://discord.com/channels/@me/${C}`; @@ -292,6 +319,8 @@ export function channelLink(channelId: C): `https://discord /** * Formats a channel link for a guild channel. * + * @typeParam C - This is inferred by the supplied channel id + * @typeParam G - This is inferred by the supplied guild id * @param channelId - The channel's id * @param guildId - The guild's id */ @@ -310,6 +339,8 @@ export function channelLink( /** * Formats a message link for a direct message channel. * + * @typeParam C - This is inferred by the supplied channel id + * @typeParam M - This is inferred by the supplied message id * @param channelId - The channel's id * @param messageId - The message's id */ @@ -321,6 +352,9 @@ export function messageLink( /** * Formats a message link for a guild channel. * + * @typeParam C - This is inferred by the supplied channel id + * @typeParam M - This is inferred by the supplied message id + * @typeParam G - This is inferred by the supplied guild id * @param channelId - The channel's id * @param messageId - The message's id * @param guildId - The guild's id @@ -340,34 +374,39 @@ export function messageLink`; /** - * Formats a date given a format style + * Formats a date given a format style. * + * @typeParam S - This is inferred by the supplied {@link TimestampStylesString} * @param date - The date to format * @param style - The style to use */ export function time(date: Date, style: S): ``; /** - * Formats the given timestamp into a short date-time string + * Formats the given timestamp into a short date-time string. * - * @param seconds - The time to format, represents an UNIX timestamp in seconds + * @typeParam C - This is inferred by the supplied timestamp + * @param seconds - A Unix timestamp in seconds */ export function time(seconds: C): ``; /** - * Formats the given timestamp into a short date-time string + * Formats the given timestamp into a short date-time string. * - * @param seconds - The time to format, represents an UNIX timestamp in seconds + * @typeParam C - This is inferred by the supplied timestamp + * @typeParam S - This is inferred by the supplied {@link TimestampStylesString} + * @param seconds - A Unix timestamp in seconds * @param style - The style to use */ export function time(seconds: C, style: S): ``; + export function time(timeOrSeconds?: Date | number, style?: TimestampStylesString): string { if (typeof timeOrSeconds !== 'number') { // eslint-disable-next-line no-param-reassign @@ -378,66 +417,83 @@ export function time(timeOrSeconds?: Date | number, style?: TimestampStylesStrin } /** - * The {@link https://discord.com/developers/docs/reference#message-formatting-timestamp-styles | message formatting timestamp styles} supported by Discord + * The {@link https://discord.com/developers/docs/reference#message-formatting-timestamp-styles | message formatting timestamp styles} + * supported by Discord. */ export const TimestampStyles = { /** - * Short time format, consisting of hours and minutes, e.g. 16:20 + * Short time format, consisting of hours and minutes. + * + * @example `16:20` */ ShortTime: 't', /** - * Long time format, consisting of hours, minutes, and seconds, e.g. 16:20:30 + * Long time format, consisting of hours, minutes, and seconds. + * + * @example `16:20:30` */ LongTime: 'T', /** - * Short date format, consisting of day, month, and year, e.g. 20/04/2021 + * Short date format, consisting of day, month, and year. + * + * @example `20/04/2021` */ ShortDate: 'd', /** - * Long date format, consisting of day, month, and year, e.g. 20 April 2021 + * Long date format, consisting of day, month, and year. + * + * @example `20 April 2021` */ LongDate: 'D', /** - * Short date-time format, consisting of short date and short time formats, e.g. 20 April 2021 16:20 + * Short date-time format, consisting of short date and short time formats. + * + * @example `20 April 2021 16:20` */ ShortDateTime: 'f', /** - * Long date-time format, consisting of long date and short time formats, e.g. Tuesday, 20 April 2021 16:20 + * Long date-time format, consisting of long date and short time formats. + * + * @example `Tuesday, 20 April 2021 16:20` */ LongDateTime: 'F', /** - * Relative time format, consisting of a relative duration format, e.g. 2 months ago + * Relative time format, consisting of a relative duration format. + * + * @example `2 months ago` */ RelativeTime: 'R', } as const satisfies Record; /** - * The possible values, see {@link TimestampStyles} for more information + * The possible {@link TimestampStyles} values. */ export type TimestampStylesString = (typeof TimestampStyles)[keyof typeof TimestampStyles]; +// prettier-ignore /** - * An enum with all the available faces from Discord's native slash commands + * All the available faces from Discord's native slash commands. */ export enum Faces { /** - * ¯\\_(ツ)\\_/¯ + * `¯\_(ツ)_/¯` */ - Shrug = '¯\\_(ツ)\\_/¯', + // eslint-disable-next-line no-useless-escape + Shrug = '¯\_(ツ)_/¯', /** - * (╯°□°)╯︵ ┻━┻ + * `(╯°□°)╯︵ ┻━┻` */ - Tableflip = '(╯°□°)╯︵ ┻━┻', + Tableflip = '(╯°□°)╯︵ ┻━┻', /** - * ┬─┬ ノ( ゜-゜ノ) + * `┬─┬ノ( º _ ºノ)` */ - Unflip = '┬─┬ ノ( ゜-゜ノ)', + Unflip = '┬─┬ノ( º _ ºノ)', }