y"), "h<e>y");
});
-test('bold italic', t => {
- t.is(format.bold(format.italic('green')), 'green');
+test("bold italic", () => {
+ strictEqual(format.bold(format.italic("green")), "green");
});
-test('user mention', t => {
- t.is(
- format.userMention('inline mention of a user', 123_456_789),
+test("user mention", () => {
+ strictEqual(
+ format.userMention("inline mention of a user", 123_456_789),
'inline mention of a user',
);
});
-test('monospace', t => {
- t.is(
- format.monospace('inline fixed-width code'),
- 'inline fixed-width code
',
+test("monospace", () => {
+ strictEqual(
+ format.monospace("inline fixed-width code"),
+ "inline fixed-width code
",
);
});
-test('monospaceBlock w/o language', t => {
- t.is(
- format.monospaceBlock('pre-formatted fixed-width code block'),
- 'pre-formatted fixed-width code block
',
+test("monospaceBlock w/o language", () => {
+ strictEqual(
+ format.monospaceBlock("pre-formatted fixed-width code block"),
+ "pre-formatted fixed-width code block
",
);
});
-test('monospaceBlock w/ language', t => {
- t.is(
+test("monospaceBlock w/ language", () => {
+ strictEqual(
format.monospaceBlock(
- 'pre-formatted fixed-width code block written in the Python programming language',
- 'python',
+ "pre-formatted fixed-width code block written in the Python programming language",
+ "python",
),
'pre-formatted fixed-width code block written in the Python programming language
',
);
diff --git a/source/html.ts b/source/html.ts
index 174fe64..45e05ad 100644
--- a/source/html.ts
+++ b/source/html.ts
@@ -1,63 +1,64 @@
-import type {Formatter} from './types.js';
+/** https://core.telegram.org/bots/api#html-style */
+export const parse_mode = "HTML";
-function escape(text: string): string {
+/** Escape the input text to be displayed as it is */
+export function escape(text: string): string {
return text
- .replace(/&/g, '&')
- .replace(//g, '>');
+ .replace(/&/g, "&")
+ .replace(//g, ">");
}
-function bold(text: string): string {
+/** Format the input text bold */
+export function bold(text: string): string {
return `${text}`;
}
-function italic(text: string): string {
+/** Format the input text italic */
+export function italic(text: string): string {
return `${text}`;
}
-function strikethrough(text: string): string {
+/** Strikethrough the input text */
+export function strikethrough(text: string): string {
return `${text}`;
}
-function underline(text: string): string {
+/** Underline the input text */
+export function underline(text: string): string {
return `${text}`;
}
-function spoiler(text: string): string {
+/** Format the input text as spoiler */
+export function spoiler(text: string): string {
return `${text}`;
}
-function monospace(text: string): string {
+/** Format the input text as monospace */
+export function monospace(text: string): string {
return `${escape(text)}
`;
}
-function monospaceBlock(text: string, programmingLanguage?: string): string {
+/** Format the input text as a monospace block optionally with a programming language */
+export function monospaceBlock(
+ text: string,
+ programmingLanguage?: string,
+): string {
if (programmingLanguage) {
- return `${escape(text)}
`;
+ return `${
+ escape(text)
+ }
`;
}
return `${escape(text)}
`;
}
-function url(label: string, url: string): string {
+/** Create an url with a label text */
+export function url(label: string, url: string): string {
return `${label}`;
}
-function userMention(label: string, userId: number): string {
+/** Create a user mention with a label text */
+export function userMention(label: string, userId: number): string {
return url(label, `tg://user?id=${userId}`);
}
-
-/** https://core.telegram.org/bots/api#html-style */
-export const html = {
- parse_mode: 'HTML',
- escape,
- bold,
- italic,
- strikethrough,
- underline,
- spoiler,
- monospace,
- monospaceBlock,
- url,
- userMention,
-} as const satisfies Formatter;
diff --git a/source/index.ts b/source/index.ts
deleted file mode 100644
index 41ea91b..0000000
--- a/source/index.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-export type {Formatter} from './types.js';
-
-export {html} from './html.js';
-export {markdown} from './markdown.js';
-export {markdownv2} from './markdownv2.js';
diff --git a/source/markdown.test.ts b/source/markdown.test.ts
index 55a5630..408e282 100644
--- a/source/markdown.test.ts
+++ b/source/markdown.test.ts
@@ -1,75 +1,76 @@
-import test from 'ava';
-import {markdown as format} from './markdown.js';
+import { strictEqual, throws } from "node:assert";
+import { test } from "node:test";
+import * as format from "./markdown.ts";
+import { Formatter } from "./types.ts";
-test('bold', t => {
- t.is(format.bold('bold'), '*bold*');
+format satisfies Formatter;
+
+test("bold", () => {
+ strictEqual(format.bold("bold"), "*bold*");
});
-test('italic', t => {
- t.is(format.italic('italic'), '_italic_');
+test("italic", () => {
+ strictEqual(format.italic("italic"), "_italic_");
});
-test('url', t => {
- t.is(format.url('me', 'https://edjopato.de'), '[me](https://edjopato.de)');
+test("url", () => {
+ strictEqual(
+ format.url("me", "https://edjopato.de"),
+ "[me](https://edjopato.de)",
+ );
});
-test('escape', t => {
- t.is(format.escape('[h_]e(*y)`'), 'hey');
+test("escape", () => {
+ strictEqual(format.escape("[h_]e(*y)`"), "hey");
});
-test('bold malicious', t => {
- t.is(format.bold('bo*ld'), '*bold*');
+test("bold malicious", () => {
+ strictEqual(format.bold("bo*ld"), "*bold*");
});
-test('italic malicious', t => {
- t.is(format.italic('ita_lic'), '_italic_');
+test("italic malicious", () => {
+ strictEqual(format.italic("ita_lic"), "_italic_");
});
-test('user mention', t => {
- t.is(
- format.userMention('inline mention of a user', 123_456_789),
- '[inline mention of a user](tg://user?id=123456789)',
+test("user mention", () => {
+ strictEqual(
+ format.userMention("inline mention of a user", 123_456_789),
+ "[inline mention of a user](tg://user?id=123456789)",
);
});
-test('monospace', t => {
- t.is(
- format.monospace('inline fixed-width code'),
- '`inline fixed-width code`',
+test("monospace", () => {
+ strictEqual(
+ format.monospace("inline fixed-width code"),
+ "`inline fixed-width code`",
);
});
-test('monospaceBlock w/o language', t => {
- t.is(
- format.monospaceBlock('pre-formatted fixed-width code block'),
- '```\npre-formatted fixed-width code block\n```',
+test("monospaceBlock w/o language", () => {
+ strictEqual(
+ format.monospaceBlock("pre-formatted fixed-width code block"),
+ "```\npre-formatted fixed-width code block\n```",
);
});
-test('monospaceBlock w/ language', t => {
- t.is(
+test("monospaceBlock w/ language", () => {
+ strictEqual(
format.monospaceBlock(
- 'pre-formatted fixed-width code block written in the Python programming language',
- 'python',
+ "pre-formatted fixed-width code block written in the Python programming language",
+ "python",
),
- '```python\npre-formatted fixed-width code block written in the Python programming language\n```',
+ "```python\npre-formatted fixed-width code block written in the Python programming language\n```",
);
});
-test('strikethrough', t => {
- t.throws(() => format.strikethrough('1337'), {
- message: 'strikethrough is not supported by Markdown. Use MarkdownV2 instead.',
- });
+test("strikethrough", () => {
+ throws(() => format.strikethrough("1337"));
});
-test('underline', t => {
- t.throws(() => format.underline('1337'), {
- message: 'underline is not supported by Markdown. Use MarkdownV2 instead.',
- });
+test("underline", () => {
+ throws(() => format.underline("1337"));
});
-test('spoiler', t => {
- t.throws(() => format.spoiler('1337'), {
- message: 'spoiler is not supported by Markdown. Use MarkdownV2 instead.',
- });
+test("spoiler", () => {
+ throws(() => format.spoiler("1337"));
});
diff --git a/source/markdown.ts b/source/markdown.ts
index eaccff6..99a710a 100644
--- a/source/markdown.ts
+++ b/source/markdown.ts
@@ -1,67 +1,72 @@
-import type {Formatter} from './types.js';
+/** https://core.telegram.org/bots/api#markdown-style */
+export const parse_mode = "Markdown";
-function escape(text: string): string {
- return text.replace(/[*_`[\]()]/g, '');
+/** Escape the input text to be displayed as it is */
+export function escape(text: string): string {
+ return text.replace(/[*_`[\]()]/g, "");
}
-function bold(text: string): string {
- return `*${text.replace(/\*/g, '')}*`;
+/** Format the input text bold */
+export function bold(text: string): string {
+ return `*${text.replace(/\*/g, "")}*`;
}
-function italic(text: string): string {
- return `_${text.replace(/_/g, '')}_`;
+/** Format the input text italic */
+export function italic(text: string): string {
+ return `_${text.replace(/_/g, "")}_`;
}
-function strikethrough(_text: string): string {
- throw new Error('strikethrough is not supported by Markdown. Use MarkdownV2 instead.');
+/** @deprecated unsupported by Telegram. Use MarkdownV2 or HTML instead */
+export function strikethrough(_text: string): string {
+ throw new Error(
+ "strikethrough is not supported by Markdown. Use MarkdownV2 instead.",
+ );
}
-function underline(_text: string): string {
- throw new Error('underline is not supported by Markdown. Use MarkdownV2 instead.');
+/** @deprecated unsupported by Telegram. Use MarkdownV2 or HTML instead */
+export function underline(_text: string): string {
+ throw new Error(
+ "underline is not supported by Markdown. Use MarkdownV2 instead.",
+ );
}
-function spoiler(_text: string): string {
- throw new Error('spoiler is not supported by Markdown. Use MarkdownV2 instead.');
+/** @deprecated unsupported by Telegram. Use MarkdownV2 or HTML instead */
+export function spoiler(_text: string): string {
+ throw new Error(
+ "spoiler is not supported by Markdown. Use MarkdownV2 instead.",
+ );
}
-function monospace(text: string): string {
- return '`' + text.replace(/`/g, '') + '`';
+/** Format the input text as monospace */
+export function monospace(text: string): string {
+ return "`" + text.replace(/`/g, "") + "`";
}
-function monospaceBlock(text: string, programmingLanguage?: string): string {
- let result = '';
- result += '```';
+/** Format the input text as a monospace block optionally with a programming language */
+export function monospaceBlock(
+ text: string,
+ programmingLanguage?: string,
+): string {
+ let result = "";
+ result += "```";
if (programmingLanguage) {
result += programmingLanguage;
}
- result += '\n';
- result += text.replace(/```/g, '');
- result += '\n';
- result += '```';
+ result += "\n";
+ result += text.replace(/```/g, "");
+ result += "\n";
+ result += "```";
return result;
}
-function url(label: string, url: string): string {
- return `[${label.replace(/]/, '')}](${url.replace(/\)/, '')})`;
+/** Create an url with a label text */
+export function url(label: string, url: string): string {
+ return `[${label.replace(/]/, "")}](${url.replace(/\)/, "")})`;
}
-function userMention(label: string, userId: number): string {
+/** Create a user mention with a label text */
+export function userMention(label: string, userId: number): string {
return url(label, `tg://user?id=${userId}`);
}
-
-/** https://core.telegram.org/bots/api#markdown-style */
-export const markdown = {
- parse_mode: 'Markdown',
- escape,
- bold,
- italic,
- strikethrough,
- underline,
- spoiler,
- monospace,
- monospaceBlock,
- url,
- userMention,
-} as const satisfies Formatter;
diff --git a/source/markdownv2.test.ts b/source/markdownv2.test.ts
index 02a362a..19264fb 100644
--- a/source/markdownv2.test.ts
+++ b/source/markdownv2.test.ts
@@ -1,69 +1,76 @@
-import test from 'ava';
-import {markdownv2 as format} from './markdownv2.js';
+import { strictEqual } from "node:assert";
+import { test } from "node:test";
+import * as format from "./markdownv2.ts";
+import { Formatter } from "./types.ts";
-test('bold', t => {
- t.is(format.bold('bold'), '*bold*');
+format satisfies Formatter;
+
+test("bold", () => {
+ strictEqual(format.bold("bold"), "*bold*");
});
-test('italic', t => {
- t.is(format.italic('italic'), '_italic_');
+test("italic", () => {
+ strictEqual(format.italic("italic"), "_italic_");
});
-test('strikethrough', t => {
- t.is(format.strikethrough('strikethrough'), '~strikethrough~');
+test("strikethrough", () => {
+ strictEqual(format.strikethrough("strikethrough"), "~strikethrough~");
});
-test('underline', t => {
- t.is(format.underline('underline'), '__underline__');
+test("underline", () => {
+ strictEqual(format.underline("underline"), "__underline__");
});
-test('spoiler', t => {
- t.is(format.spoiler('spoiler'), '||spoiler||');
+test("spoiler", () => {
+ strictEqual(format.spoiler("spoiler"), "||spoiler||");
});
-test('url', t => {
- t.is(format.url('me', 'https://edjopato.de'), '[me](https://edjopato.de)');
+test("url", () => {
+ strictEqual(
+ format.url("me", "https://edjopato.de"),
+ "[me](https://edjopato.de)",
+ );
});
-test('escape', t => {
- t.is(format.escape('[h_]e(*y\\)`'), '\\[h\\_\\]e\\(\\*y\\\\\\)\\`');
+test("escape", () => {
+ strictEqual(format.escape("[h_]e(*y\\)`"), "\\[h\\_\\]e\\(\\*y\\\\\\)\\`");
});
-test('escape with number', t => {
- t.is(format.escape('h1e2y'), 'h1e2y');
+test("escape with number", () => {
+ strictEqual(format.escape("h1e2y"), "h1e2y");
});
-test('bold italic', t => {
- t.is(format.bold(format.italic('green')), '*_green_*');
+test("bold italic", () => {
+ strictEqual(format.bold(format.italic("green")), "*_green_*");
});
-test('user mention', t => {
- t.is(
- format.userMention('inline mention of a user', 123_456_789),
- '[inline mention of a user](tg://user?id=123456789)',
+test("user mention", () => {
+ strictEqual(
+ format.userMention("inline mention of a user", 123_456_789),
+ "[inline mention of a user](tg://user?id=123456789)",
);
});
-test('monospace', t => {
- t.is(
- format.monospace('inline fixed-width code'),
- '`inline fixed-width code`',
+test("monospace", () => {
+ strictEqual(
+ format.monospace("inline fixed-width code"),
+ "`inline fixed-width code`",
);
});
-test('monospaceBlock w/o language', t => {
- t.is(
- format.monospaceBlock('pre-formatted fixed-width code block'),
- '```\npre-formatted fixed-width code block\n```',
+test("monospaceBlock w/o language", () => {
+ strictEqual(
+ format.monospaceBlock("pre-formatted fixed-width code block"),
+ "```\npre-formatted fixed-width code block\n```",
);
});
-test('monospaceBlock w/ language', t => {
- t.is(
+test("monospaceBlock w/ language", () => {
+ strictEqual(
format.monospaceBlock(
- 'pre-formatted fixed-width code block written in the Python programming language',
- 'python',
+ "pre-formatted fixed-width code block written in the Python programming language",
+ "python",
),
- '```python\npre-formatted fixed-width code block written in the Python programming language\n```',
+ "```python\npre-formatted fixed-width code block written in the Python programming language\n```",
);
});
diff --git a/source/markdownv2.ts b/source/markdownv2.ts
index e8afe72..8a4d34c 100644
--- a/source/markdownv2.ts
+++ b/source/markdownv2.ts
@@ -1,71 +1,70 @@
-import type {Formatter} from './types.js';
+/** https://core.telegram.org/bots/api#markdownv2-style */
+export const parse_mode = "MarkdownV2";
function escapeInternal(text: string, escapeChars: string): string {
- return text.replace(new RegExp(`[${escapeChars}\\\\]`, 'g'), '\\$&');
+ return text.replace(new RegExp(`[${escapeChars}\\\\]`, "g"), "\\$&");
}
-function escape(text: string): string {
- return text.replace(/[_*[\]()~`>#+\-=|{}.!\\]/g, '\\$&');
+/** Escape the input text to be displayed as it is */
+export function escape(text: string): string {
+ return text.replace(/[_*[\]()~`>#+\-=|{}.!\\]/g, "\\$&");
}
-function bold(text: string): string {
+/** Format the input text bold */
+export function bold(text: string): string {
return `*${text}*`;
}
-function italic(text: string): string {
+/** Format the input text italic */
+export function italic(text: string): string {
return `_${text}_`;
}
-function strikethrough(text: string): string {
+/** Strikethrough the input text */
+export function strikethrough(text: string): string {
return `~${text}~`;
}
-function underline(text: string): string {
+/** Underline the input text */
+export function underline(text: string): string {
return `__${text}__`;
}
-function spoiler(text: string): string {
+/** Format the input text as spoiler */
+export function spoiler(text: string): string {
return `||${text}||`;
}
-function monospace(text: string): string {
- return '`' + escapeInternal(text, '`') + '`';
+/** Format the input text as monospace */
+export function monospace(text: string): string {
+ return "`" + escapeInternal(text, "`") + "`";
}
-function monospaceBlock(text: string, programmingLanguage?: string): string {
- let result = '';
- result += '```';
+/** Format the input text as a monospace block optionally with a programming language */
+export function monospaceBlock(
+ text: string,
+ programmingLanguage?: string,
+): string {
+ let result = "";
+ result += "```";
if (programmingLanguage) {
result += programmingLanguage;
}
- result += '\n';
- result += escapeInternal(text, '`');
- result += '\n';
- result += '```';
+ result += "\n";
+ result += escapeInternal(text, "`");
+ result += "\n";
+ result += "```";
return result;
}
-function url(label: string, url: string): string {
- return `[${label}](${escapeInternal(url, ')')})`;
+/** Create an url with a label text */
+export function url(label: string, url: string): string {
+ return `[${label}](${escapeInternal(url, ")")})`;
}
-function userMention(label: string, userId: number): string {
+/** Create a user mention with a label text */
+export function userMention(label: string, userId: number): string {
return url(label, `tg://user?id=${userId}`);
}
-
-/** https://core.telegram.org/bots/api#markdownv2-style */
-export const markdownv2 = {
- parse_mode: 'MarkdownV2',
- escape,
- bold,
- italic,
- strikethrough,
- underline,
- spoiler,
- monospace,
- monospaceBlock,
- url,
- userMention,
-} as const satisfies Formatter;
diff --git a/source/mod.ts b/source/mod.ts
new file mode 100644
index 0000000..72774d6
--- /dev/null
+++ b/source/mod.ts
@@ -0,0 +1,5 @@
+export type { Formatter } from "./types.ts";
+
+export * as html from "./html.ts";
+export * as markdown from "./markdown.ts";
+export * as markdownv2 from "./markdownv2.ts";
diff --git a/source/types.ts b/source/types.ts
index e14603f..51c97a8 100644
--- a/source/types.ts
+++ b/source/types.ts
@@ -1,13 +1,25 @@
-export type Formatter = {
- parse_mode: 'HTML' | 'Markdown' | 'MarkdownV2';
+/** All exported formatters satisfy this interface */
+export interface Formatter {
+ /** parse_mode which can be used on sendMessage */
+ parse_mode: "HTML" | "Markdown" | "MarkdownV2";
+ /** Format the input text bold */
bold: (text: string) => string;
+ /** Escape the input text to be displayed as it is */
escape: (text: string) => string;
+ /** Format the input text italic */
italic: (text: string) => string;
+ /** Format the input text as monospace */
monospace: (text: string) => string;
+ /** Format the input text as a monospace block optionally with a programming language */
monospaceBlock: (text: string, programmingLanguage?: string) => string;
+ /** Format the input text as spoiler */
spoiler: (text: string) => string;
+ /** Strikethrough the input text */
strikethrough: (text: string) => string;
+ /** Underline the input text */
underline: (text: string) => string;
+ /** Create an url with a label text */
url: (label: string, url: string) => string;
+ /** Create a user mention with a label text */
userMention: (label: string, userId: number) => string;
-};
+}
diff --git a/tsconfig.json b/tsconfig.json
index 431fb68..69bb64e 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,11 +1,10 @@
{
- "extends": "@sindresorhus/tsconfig/tsconfig.json",
"include": [
"source"
],
"compilerOptions": {
- "target": "ES2020",
- "lib": ["ES2020"],
+ "declaration": true,
+ "target": "ES2020", // Node.js 14
"outDir": "dist"
}
}