@ai-devkit/channel-connector 0.13.0 → 0.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -7,10 +7,11 @@ describe('markdownToTelegramHtml', ()=>{
|
|
|
7
7
|
expect(out).toContain('<s>s</s>');
|
|
8
8
|
});
|
|
9
9
|
it('renders inline code and fenced code with language', ()=>{
|
|
10
|
-
const md = 'Run `npm test`\n\n```ts\nconst x = 1;\n```';
|
|
10
|
+
const md = 'Run `npm test`\n\n```ts\nconst x = 1;\n```\n\n```\nplain\n```';
|
|
11
11
|
const out = markdownToTelegramHtml(md);
|
|
12
12
|
expect(out).toContain('<code>npm test</code>');
|
|
13
13
|
expect(out).toContain('<pre><code class="language-ts">const x = 1;</code></pre>');
|
|
14
|
+
expect(out).toContain('<pre><code>plain</code></pre>');
|
|
14
15
|
});
|
|
15
16
|
it('renders links and converts headings to bold', ()=>{
|
|
16
17
|
const md = '# Title\n\nSee [docs](https://x.com).';
|
|
@@ -45,14 +46,57 @@ describe('markdownToTelegramHtml', ()=>{
|
|
|
45
46
|
expect(out).toContain('2. two');
|
|
46
47
|
expect(out).not.toContain('<ol>');
|
|
47
48
|
});
|
|
49
|
+
it('renders inline markup as HTML inside ordered tight lists', ()=>{
|
|
50
|
+
const out = markdownToTelegramHtml('1. **bold** `code` *italic*');
|
|
51
|
+
expect(out).toContain('1. <b>bold</b> <code>code</code> <i>italic</i>');
|
|
52
|
+
expect(out).not.toContain('<b>');
|
|
53
|
+
expect(out).not.toMatch(/\*\*|`/);
|
|
54
|
+
});
|
|
55
|
+
it('renders inline markup as HTML inside unordered tight lists', ()=>{
|
|
56
|
+
const out = markdownToTelegramHtml('- **bold** `code` *italic*');
|
|
57
|
+
expect(out).toContain('• <b>bold</b> <code>code</code> <i>italic</i>');
|
|
58
|
+
expect(out).not.toMatch(/<(?:b|code|i)>/);
|
|
59
|
+
});
|
|
60
|
+
it('renders inline markup in the middle of list item text', ()=>{
|
|
61
|
+
const out = markdownToTelegramHtml('- While editing, `/x` is a **literal** character.');
|
|
62
|
+
expect(out).toContain('• While editing, <code>/x</code> is a <b>literal</b> character.');
|
|
63
|
+
});
|
|
64
|
+
it('renders inline markup in loose multi-paragraph lists', ()=>{
|
|
65
|
+
const out = markdownToTelegramHtml('- First **bold** paragraph.\n\n Second paragraph with *italic*.\n\n- `code` item.');
|
|
66
|
+
expect(out).toContain('• First <b>bold</b> paragraph.');
|
|
67
|
+
expect(out).toContain('Second paragraph with <i>italic</i>.');
|
|
68
|
+
expect(out).toContain('• <code>code</code> item.');
|
|
69
|
+
expect(out).not.toMatch(/<(?:b|code|i)>/);
|
|
70
|
+
});
|
|
71
|
+
it('renders inline markup in nested list items', ()=>{
|
|
72
|
+
const out = markdownToTelegramHtml('- **parent**\n - child with `code`');
|
|
73
|
+
expect(out).toContain('• <b>parent</b>');
|
|
74
|
+
expect(out).toContain('• child with <code>code</code>');
|
|
75
|
+
});
|
|
76
|
+
it('escapes raw HTML inside list items', ()=>{
|
|
77
|
+
const out = markdownToTelegramHtml('- literal <script>alert(1)</script> text');
|
|
78
|
+
expect(out).toContain('<script>');
|
|
79
|
+
expect(out).not.toContain('<script>');
|
|
80
|
+
});
|
|
81
|
+
it('preserves ordered list start numbering with inline markup', ()=>{
|
|
82
|
+
const out = markdownToTelegramHtml('3. **three**\n4. *four*');
|
|
83
|
+
expect(out).toContain('3. <b>three</b>');
|
|
84
|
+
expect(out).toContain('4. <i>four</i>');
|
|
85
|
+
});
|
|
86
|
+
it('renders links as HTML inside list items', ()=>{
|
|
87
|
+
const out = markdownToTelegramHtml('- See [docs](https://example.com?a=1&b=2).');
|
|
88
|
+
expect(out).toContain('• See <a href="https://example.com?a=1&b=2">docs</a>.');
|
|
89
|
+
expect(out).not.toContain('<a href=');
|
|
90
|
+
});
|
|
48
91
|
it('renders tables as ASCII inside <pre>', ()=>{
|
|
49
|
-
const md = '| a | b |\n|---|---|\n| 1 | 2 |';
|
|
92
|
+
const md = '| a | b |\n|---|---|\n| 1 | 2 |\n| 3 |';
|
|
50
93
|
const out = markdownToTelegramHtml(md);
|
|
51
94
|
expect(out.startsWith('<pre>')).toBe(true);
|
|
52
95
|
expect(out).toContain('a');
|
|
53
96
|
expect(out).toContain('b');
|
|
54
97
|
expect(out).toContain('1');
|
|
55
98
|
expect(out).toContain('2');
|
|
99
|
+
expect(out).toContain('3');
|
|
56
100
|
expect(out).not.toContain('<table>');
|
|
57
101
|
});
|
|
58
102
|
it('uses <blockquote> for quotes', ()=>{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/__tests__/utils/telegramHtml.test.ts"],"sourcesContent":["import { markdownToTelegramHtml } from '../../utils/telegramHtml.js';\n\ndescribe('markdownToTelegramHtml', () => {\n it('renders bold, italic, strikethrough', () => {\n const out = markdownToTelegramHtml('**b** _i_ ~~s~~');\n expect(out).toContain('<b>b</b>');\n expect(out).toContain('<i>i</i>');\n expect(out).toContain('<s>s</s>');\n });\n\n it('renders inline code and fenced code with language', () => {\n const md = 'Run `npm test`\\n\\n```ts\\nconst x = 1;\\n```';\n const out = markdownToTelegramHtml(md);\n expect(out).toContain('<code>npm test</code>');\n expect(out).toContain('<pre><code class=\"language-ts\">const x = 1;</code></pre>');\n });\n\n it('renders links and converts headings to bold', () => {\n const md = '# Title\\n\\nSee [docs](https://x.com).';\n const out = markdownToTelegramHtml(md);\n expect(out).toContain('<b>Title</b>');\n expect(out).toContain('<a href=\"https://x.com\">docs</a>');\n });\n\n it('renders images as alt-text links', () => {\n const out = markdownToTelegramHtml('');\n expect(out).toBe('<a href=\"https://x.com/d.png\">diagram</a>');\n });\n\n it('falls back to URL when image has no alt text', () => {\n const out = markdownToTelegramHtml('');\n expect(out).toContain('<a href=\"https://x.com/d.png\">https://x.com/d.png</a>');\n });\n\n it('renders unordered lists with bullets', () => {\n const out = markdownToTelegramHtml('- one\\n- two\\n- three');\n expect(out).toContain('• one');\n expect(out).toContain('• two');\n expect(out).toContain('• three');\n expect(out).not.toContain('<ul>');\n });\n\n it('renders nested lists without throwing', () => {\n const out = markdownToTelegramHtml('- agent\\n - Status');\n\n expect(out).toContain('• agent');\n expect(out).toContain('• Status');\n expect(out).not.toContain('<ul>');\n });\n\n it('renders ordered lists with numbers', () => {\n const out = markdownToTelegramHtml('1. one\\n2. two');\n expect(out).toContain('1. one');\n expect(out).toContain('2. two');\n expect(out).not.toContain('<ol>');\n });\n\n it('renders tables as ASCII inside <pre>', () => {\n const md = '| a | b |\\n|---|---|\\n| 1 | 2 |';\n const out = markdownToTelegramHtml(md);\n expect(out.startsWith('<pre>')).toBe(true);\n expect(out).toContain('a');\n expect(out).toContain('b');\n expect(out).toContain('1');\n expect(out).toContain('2');\n expect(out).not.toContain('<table>');\n });\n\n it('uses <blockquote> for quotes', () => {\n const out = markdownToTelegramHtml('> quoted');\n expect(out).toContain('<blockquote>');\n expect(out).toContain('quoted');\n expect(out).toContain('</blockquote>');\n });\n\n it('escapes HTML special chars in plain text', () => {\n const out = markdownToTelegramHtml('a < b && c > d');\n expect(out).toContain('<');\n expect(out).toContain('&');\n expect(out).toContain('>');\n expect(out).not.toContain(' < ');\n });\n\n it('escapes HTML special chars inside code', () => {\n const out = markdownToTelegramHtml('`<script>`');\n expect(out).toContain('<code><script></code>');\n });\n\n it('strips raw HTML blocks', () => {\n const out = markdownToTelegramHtml('hello\\n\\n<div>raw</div>\\n\\nworld');\n expect(out).not.toContain('<div>');\n expect(out).toContain('hello');\n expect(out).toContain('world');\n });\n\n it('renders horizontal rule as a divider', () => {\n const out = markdownToTelegramHtml('above\\n\\n---\\n\\nbelow');\n expect(out).toContain('above');\n expect(out).toContain('———');\n expect(out).toContain('below');\n });\n\n it('passes plain text through unchanged', () => {\n expect(markdownToTelegramHtml('hello world')).toBe('hello world');\n });\n});\n"],"names":["markdownToTelegramHtml","describe","it","out","expect","toContain","md","toBe","not","startsWith"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/__tests__/utils/telegramHtml.test.ts"],"sourcesContent":["import { markdownToTelegramHtml } from '../../utils/telegramHtml.js';\n\ndescribe('markdownToTelegramHtml', () => {\n it('renders bold, italic, strikethrough', () => {\n const out = markdownToTelegramHtml('**b** _i_ ~~s~~');\n expect(out).toContain('<b>b</b>');\n expect(out).toContain('<i>i</i>');\n expect(out).toContain('<s>s</s>');\n });\n\n it('renders inline code and fenced code with language', () => {\n const md = 'Run `npm test`\\n\\n```ts\\nconst x = 1;\\n```\\n\\n```\\nplain\\n```';\n const out = markdownToTelegramHtml(md);\n expect(out).toContain('<code>npm test</code>');\n expect(out).toContain('<pre><code class=\"language-ts\">const x = 1;</code></pre>');\n expect(out).toContain('<pre><code>plain</code></pre>');\n });\n\n it('renders links and converts headings to bold', () => {\n const md = '# Title\\n\\nSee [docs](https://x.com).';\n const out = markdownToTelegramHtml(md);\n expect(out).toContain('<b>Title</b>');\n expect(out).toContain('<a href=\"https://x.com\">docs</a>');\n });\n\n it('renders images as alt-text links', () => {\n const out = markdownToTelegramHtml('');\n expect(out).toBe('<a href=\"https://x.com/d.png\">diagram</a>');\n });\n\n it('falls back to URL when image has no alt text', () => {\n const out = markdownToTelegramHtml('');\n expect(out).toContain('<a href=\"https://x.com/d.png\">https://x.com/d.png</a>');\n });\n\n it('renders unordered lists with bullets', () => {\n const out = markdownToTelegramHtml('- one\\n- two\\n- three');\n expect(out).toContain('• one');\n expect(out).toContain('• two');\n expect(out).toContain('• three');\n expect(out).not.toContain('<ul>');\n });\n\n it('renders nested lists without throwing', () => {\n const out = markdownToTelegramHtml('- agent\\n - Status');\n\n expect(out).toContain('• agent');\n expect(out).toContain('• Status');\n expect(out).not.toContain('<ul>');\n });\n\n it('renders ordered lists with numbers', () => {\n const out = markdownToTelegramHtml('1. one\\n2. two');\n expect(out).toContain('1. one');\n expect(out).toContain('2. two');\n expect(out).not.toContain('<ol>');\n });\n\n it('renders inline markup as HTML inside ordered tight lists', () => {\n const out = markdownToTelegramHtml('1. **bold** `code` *italic*');\n\n expect(out).toContain('1. <b>bold</b> <code>code</code> <i>italic</i>');\n expect(out).not.toContain('<b>');\n expect(out).not.toMatch(/\\*\\*|`/);\n });\n\n it('renders inline markup as HTML inside unordered tight lists', () => {\n const out = markdownToTelegramHtml('- **bold** `code` *italic*');\n\n expect(out).toContain('• <b>bold</b> <code>code</code> <i>italic</i>');\n expect(out).not.toMatch(/<(?:b|code|i)>/);\n });\n\n it('renders inline markup in the middle of list item text', () => {\n const out = markdownToTelegramHtml(\n '- While editing, `/x` is a **literal** character.'\n );\n\n expect(out).toContain(\n '• While editing, <code>/x</code> is a <b>literal</b> character.'\n );\n });\n\n it('renders inline markup in loose multi-paragraph lists', () => {\n const out = markdownToTelegramHtml(\n '- First **bold** paragraph.\\n\\n Second paragraph with *italic*.\\n\\n- `code` item.'\n );\n\n expect(out).toContain('• First <b>bold</b> paragraph.');\n expect(out).toContain('Second paragraph with <i>italic</i>.');\n expect(out).toContain('• <code>code</code> item.');\n expect(out).not.toMatch(/<(?:b|code|i)>/);\n });\n\n it('renders inline markup in nested list items', () => {\n const out = markdownToTelegramHtml('- **parent**\\n - child with `code`');\n\n expect(out).toContain('• <b>parent</b>');\n expect(out).toContain('• child with <code>code</code>');\n });\n\n it('escapes raw HTML inside list items', () => {\n const out = markdownToTelegramHtml('- literal <script>alert(1)</script> text');\n\n expect(out).toContain('<script>');\n expect(out).not.toContain('<script>');\n });\n\n it('preserves ordered list start numbering with inline markup', () => {\n const out = markdownToTelegramHtml('3. **three**\\n4. *four*');\n\n expect(out).toContain('3. <b>three</b>');\n expect(out).toContain('4. <i>four</i>');\n });\n\n it('renders links as HTML inside list items', () => {\n const out = markdownToTelegramHtml('- See [docs](https://example.com?a=1&b=2).');\n\n expect(out).toContain(\n '• See <a href=\"https://example.com?a=1&b=2\">docs</a>.'\n );\n expect(out).not.toContain('<a href=');\n });\n\n it('renders tables as ASCII inside <pre>', () => {\n const md = '| a | b |\\n|---|---|\\n| 1 | 2 |\\n| 3 |';\n const out = markdownToTelegramHtml(md);\n expect(out.startsWith('<pre>')).toBe(true);\n expect(out).toContain('a');\n expect(out).toContain('b');\n expect(out).toContain('1');\n expect(out).toContain('2');\n expect(out).toContain('3');\n expect(out).not.toContain('<table>');\n });\n\n it('uses <blockquote> for quotes', () => {\n const out = markdownToTelegramHtml('> quoted');\n expect(out).toContain('<blockquote>');\n expect(out).toContain('quoted');\n expect(out).toContain('</blockquote>');\n });\n\n it('escapes HTML special chars in plain text', () => {\n const out = markdownToTelegramHtml('a < b && c > d');\n expect(out).toContain('<');\n expect(out).toContain('&');\n expect(out).toContain('>');\n expect(out).not.toContain(' < ');\n });\n\n it('escapes HTML special chars inside code', () => {\n const out = markdownToTelegramHtml('`<script>`');\n expect(out).toContain('<code><script></code>');\n });\n\n it('strips raw HTML blocks', () => {\n const out = markdownToTelegramHtml('hello\\n\\n<div>raw</div>\\n\\nworld');\n expect(out).not.toContain('<div>');\n expect(out).toContain('hello');\n expect(out).toContain('world');\n });\n\n it('renders horizontal rule as a divider', () => {\n const out = markdownToTelegramHtml('above\\n\\n---\\n\\nbelow');\n expect(out).toContain('above');\n expect(out).toContain('———');\n expect(out).toContain('below');\n });\n\n it('passes plain text through unchanged', () => {\n expect(markdownToTelegramHtml('hello world')).toBe('hello world');\n });\n});\n"],"names":["markdownToTelegramHtml","describe","it","out","expect","toContain","md","toBe","not","toMatch","startsWith"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telegramHtml.d.ts","sourceRoot":"","sources":["../../src/utils/telegramHtml.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"telegramHtml.d.ts","sourceRoot":"","sources":["../../src/utils/telegramHtml.ts"],"names":[],"mappings":"AAyFA;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D"}
|
|
@@ -35,14 +35,13 @@ const renderer = {
|
|
|
35
35
|
const startNum = typeof start === 'number' ? start : 1;
|
|
36
36
|
const lines = items.map((item, i)=>{
|
|
37
37
|
const marker = ordered ? `${startNum + i}.` : '•';
|
|
38
|
-
const inner = this.parser.
|
|
38
|
+
const inner = item.tokens.map((token)=>token.type === 'text' ? this.parser.parseInline(token.tokens) : this.parser.parse([
|
|
39
|
+
token
|
|
40
|
+
])).join('').trimEnd();
|
|
39
41
|
return `${marker} ${inner}`;
|
|
40
42
|
});
|
|
41
43
|
return `${lines.join('\n')}\n\n`;
|
|
42
44
|
},
|
|
43
|
-
listitem (item) {
|
|
44
|
-
return this.parser.parseInline(item.tokens);
|
|
45
|
-
},
|
|
46
45
|
blockquote ({ tokens }) {
|
|
47
46
|
return `<blockquote>${this.parser.parse(tokens).trimEnd()}</blockquote>\n\n`;
|
|
48
47
|
},
|
|
@@ -64,13 +63,10 @@ const renderer = {
|
|
|
64
63
|
br () {
|
|
65
64
|
return '\n';
|
|
66
65
|
},
|
|
67
|
-
html () {
|
|
68
|
-
return '';
|
|
66
|
+
html ({ block, text }) {
|
|
67
|
+
return block ? '' : escapeHtml(text);
|
|
69
68
|
},
|
|
70
69
|
text (token) {
|
|
71
|
-
if ('tokens' in token && token.tokens) {
|
|
72
|
-
return this.parser.parseInline(token.tokens);
|
|
73
|
-
}
|
|
74
70
|
return escapeHtml(token.text);
|
|
75
71
|
}
|
|
76
72
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/utils/telegramHtml.ts"],"sourcesContent":["import { Marked, type RendererObject, type Tokens } from 'marked';\n\nconst escapeHtml = (s: string): string =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nconst escapeUrl = (s: string): string =>\n s.replace(/&/g, '&').replace(/\"/g, '"');\n\nconst renderer: RendererObject = {\n heading({ tokens }: Tokens.Heading): string {\n return `<b>${this.parser.parseInline(tokens)}</b>\\n\\n`;\n },\n paragraph({ tokens }: Tokens.Paragraph): string {\n return `${this.parser.parseInline(tokens)}\\n\\n`;\n },\n strong({ tokens }: Tokens.Strong): string {\n return `<b>${this.parser.parseInline(tokens)}</b>`;\n },\n em({ tokens }: Tokens.Em): string {\n return `<i>${this.parser.parseInline(tokens)}</i>`;\n },\n del({ tokens }: Tokens.Del): string {\n return `<s>${this.parser.parseInline(tokens)}</s>`;\n },\n codespan({ text }: Tokens.Codespan): string {\n return `<code>${escapeHtml(text)}</code>`;\n },\n code({ text, lang }: Tokens.Code): string {\n const langAttr = lang ? ` class=\"language-${escapeHtml(lang.split(/\\s/)[0])}\"` : '';\n return `<pre><code${langAttr}>${escapeHtml(text)}</code></pre>\\n\\n`;\n },\n link({ href, tokens }: Tokens.Link): string {\n return `<a href=\"${escapeUrl(href)}\">${this.parser.parseInline(tokens)}</a>`;\n },\n image({ href, text }: Tokens.Image): string {\n const label = text || href;\n return `<a href=\"${escapeUrl(href)}\">${escapeHtml(label)}</a>`;\n },\n list({ items, ordered, start }: Tokens.List): string {\n const startNum = typeof start === 'number' ? start : 1;\n const lines = items.map((item, i) => {\n const marker = ordered ? `${startNum + i}.` : '•';\n const inner = this.parser.
|
|
1
|
+
{"version":3,"sources":["../../src/utils/telegramHtml.ts"],"sourcesContent":["import { Marked, type RendererObject, type Tokens } from 'marked';\n\nconst escapeHtml = (s: string): string =>\n s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n\nconst escapeUrl = (s: string): string =>\n s.replace(/&/g, '&').replace(/\"/g, '"');\n\nconst renderer: RendererObject = {\n heading({ tokens }: Tokens.Heading): string {\n return `<b>${this.parser.parseInline(tokens)}</b>\\n\\n`;\n },\n paragraph({ tokens }: Tokens.Paragraph): string {\n return `${this.parser.parseInline(tokens)}\\n\\n`;\n },\n strong({ tokens }: Tokens.Strong): string {\n return `<b>${this.parser.parseInline(tokens)}</b>`;\n },\n em({ tokens }: Tokens.Em): string {\n return `<i>${this.parser.parseInline(tokens)}</i>`;\n },\n del({ tokens }: Tokens.Del): string {\n return `<s>${this.parser.parseInline(tokens)}</s>`;\n },\n codespan({ text }: Tokens.Codespan): string {\n return `<code>${escapeHtml(text)}</code>`;\n },\n code({ text, lang }: Tokens.Code): string {\n const langAttr = lang ? ` class=\"language-${escapeHtml(lang.split(/\\s/)[0])}\"` : '';\n return `<pre><code${langAttr}>${escapeHtml(text)}</code></pre>\\n\\n`;\n },\n link({ href, tokens }: Tokens.Link): string {\n return `<a href=\"${escapeUrl(href)}\">${this.parser.parseInline(tokens)}</a>`;\n },\n image({ href, text }: Tokens.Image): string {\n const label = text || href;\n return `<a href=\"${escapeUrl(href)}\">${escapeHtml(label)}</a>`;\n },\n list({ items, ordered, start }: Tokens.List): string {\n const startNum = typeof start === 'number' ? start : 1;\n const lines = items.map((item, i) => {\n const marker = ordered ? `${startNum + i}.` : '•';\n const inner = item.tokens\n .map((token) =>\n token.type === 'text'\n ? this.parser.parseInline(token.tokens!)\n : this.parser.parse([token])\n )\n .join('')\n .trimEnd();\n return `${marker} ${inner}`;\n });\n return `${lines.join('\\n')}\\n\\n`;\n },\n blockquote({ tokens }: Tokens.Blockquote): string {\n return `<blockquote>${this.parser.parse(tokens).trimEnd()}</blockquote>\\n\\n`;\n },\n table({ header, rows }: Tokens.Table): string {\n const headerCells = header.map((c) => c.text);\n const bodyRows = rows.map((row) => row.map((c) => c.text));\n const widths = headerCells.map((h, i) =>\n Math.max(h.length, ...bodyRows.map((row) => (row[i] ?? '').length))\n );\n const pad = (cells: string[]) =>\n cells.map((c, i) => c.padEnd(widths[i] ?? 0)).join(' | ');\n\n const lines = [\n pad(headerCells),\n widths.map((w) => '-'.repeat(w)).join('-+-'),\n ...bodyRows.map(pad),\n ];\n return `<pre>${escapeHtml(lines.join('\\n'))}</pre>\\n\\n`;\n },\n hr(): string {\n return '———\\n\\n';\n },\n br(): string {\n return '\\n';\n },\n html({ block, text }: Tokens.HTML | Tokens.Tag): string {\n return block ? '' : escapeHtml(text);\n },\n text(token: Tokens.Text | Tokens.Escape): string {\n return escapeHtml(token.text);\n },\n};\n\nconst marked = new Marked({ renderer });\n\n/**\n * Convert markdown to Telegram-compatible HTML (uses only the tag subset\n * Telegram's Bot API accepts for parse_mode: 'HTML').\n */\nexport function markdownToTelegramHtml(markdown: string): string {\n return (marked.parse(markdown, { async: false }) as string).trimEnd();\n}\n"],"names":["Marked","escapeHtml","s","replace","escapeUrl","renderer","heading","tokens","parser","parseInline","paragraph","strong","em","del","codespan","text","code","lang","langAttr","split","link","href","image","label","list","items","ordered","start","startNum","lines","map","item","i","marker","inner","token","type","parse","join","trimEnd","blockquote","table","header","rows","headerCells","c","bodyRows","row","widths","h","Math","max","length","pad","cells","padEnd","w","repeat","hr","br","html","block","marked","markdownToTelegramHtml","markdown","async"],"mappings":"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"}
|