@ai-devkit/channel-connector 0.12.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.
- package/README.md +4 -1
- package/dist/ConfigStore.d.ts.map +1 -1
- package/dist/ConfigStore.js +1 -0
- package/dist/ConfigStore.js.map +1 -1
- package/dist/__tests__/ChannelManager.test.js +3 -1
- package/dist/__tests__/ChannelManager.test.js.map +1 -1
- package/dist/__tests__/ConfigStore.test.js +33 -4
- package/dist/__tests__/ConfigStore.test.js.map +1 -1
- package/dist/__tests__/adapters/SlackAdapter.test.js +429 -0
- package/dist/__tests__/adapters/SlackAdapter.test.js.map +1 -0
- package/dist/__tests__/utils/SlackDeliveryQueue.test.js +127 -0
- package/dist/__tests__/utils/SlackDeliveryQueue.test.js.map +1 -0
- package/dist/__tests__/utils/slackMarkdown.test.js +44 -0
- package/dist/__tests__/utils/slackMarkdown.test.js.map +1 -0
- package/dist/__tests__/utils/telegramHtml.test.js +46 -2
- package/dist/__tests__/utils/telegramHtml.test.js.map +1 -1
- package/dist/adapters/ChannelAdapter.d.ts +8 -2
- package/dist/adapters/ChannelAdapter.d.ts.map +1 -1
- package/dist/adapters/ChannelAdapter.js +3 -6
- package/dist/adapters/ChannelAdapter.js.map +1 -1
- package/dist/adapters/SlackAdapter.d.ts +71 -0
- package/dist/adapters/SlackAdapter.d.ts.map +1 -0
- package/dist/adapters/SlackAdapter.js +205 -0
- package/dist/adapters/SlackAdapter.js.map +1 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +59 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -3
- package/dist/types.js.map +1 -1
- package/dist/utils/SlackDeliveryQueue.d.ts +33 -0
- package/dist/utils/SlackDeliveryQueue.d.ts.map +1 -0
- package/dist/utils/SlackDeliveryQueue.js +83 -0
- package/dist/utils/SlackDeliveryQueue.js.map +1 -0
- package/dist/utils/slackMarkdown.d.ts +5 -0
- package/dist/utils/slackMarkdown.d.ts.map +1 -0
- package/dist/utils/slackMarkdown.js +150 -0
- package/dist/utils/slackMarkdown.js.map +1 -0
- package/dist/utils/telegramHtml.d.ts.map +1 -1
- package/dist/utils/telegramHtml.js +5 -9
- package/dist/utils/telegramHtml.js.map +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { Marked } from 'marked';
|
|
2
|
+
export const SLACK_MAX_MESSAGE_LENGTH = 4000;
|
|
3
|
+
const lexer = new Marked();
|
|
4
|
+
export function escapeSlackText(text) {
|
|
5
|
+
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
|
6
|
+
}
|
|
7
|
+
export function markdownToSlackMrkdwn(markdown) {
|
|
8
|
+
return renderBlocks(lexer.lexer(markdown)).trimEnd();
|
|
9
|
+
}
|
|
10
|
+
export function chunkMarkdownForSlack(markdown, maxLength = SLACK_MAX_MESSAGE_LENGTH) {
|
|
11
|
+
const tokens = lexer.lexer(markdown);
|
|
12
|
+
const chunks = [];
|
|
13
|
+
let current = '';
|
|
14
|
+
const append = (rendered)=>{
|
|
15
|
+
if (!rendered) return;
|
|
16
|
+
if (rendered.length > maxLength) {
|
|
17
|
+
if (current) {
|
|
18
|
+
chunks.push(current.trimEnd());
|
|
19
|
+
current = '';
|
|
20
|
+
}
|
|
21
|
+
chunks.push(...splitRendered(rendered.trimEnd(), maxLength));
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const candidate = current ? `${current}${rendered}` : rendered;
|
|
25
|
+
if (candidate.trimEnd().length <= maxLength) {
|
|
26
|
+
current = candidate;
|
|
27
|
+
} else {
|
|
28
|
+
chunks.push(current.trimEnd());
|
|
29
|
+
current = rendered;
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
for (const token of tokens){
|
|
33
|
+
if (token.type === 'code') {
|
|
34
|
+
const rendered = renderCode(token);
|
|
35
|
+
if (rendered.length > maxLength) {
|
|
36
|
+
if (current) {
|
|
37
|
+
chunks.push(current.trimEnd());
|
|
38
|
+
current = '';
|
|
39
|
+
}
|
|
40
|
+
chunks.push(...splitCode(token.text, maxLength));
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
append(renderBlock(token));
|
|
45
|
+
}
|
|
46
|
+
if (current.trimEnd()) chunks.push(current.trimEnd());
|
|
47
|
+
return chunks;
|
|
48
|
+
}
|
|
49
|
+
function renderBlocks(tokens) {
|
|
50
|
+
return tokens.map(renderBlock).join('');
|
|
51
|
+
}
|
|
52
|
+
function renderBlock(token) {
|
|
53
|
+
switch(token.type){
|
|
54
|
+
case 'heading':
|
|
55
|
+
return `*${renderInline(token.tokens)}*\n\n`;
|
|
56
|
+
case 'paragraph':
|
|
57
|
+
return `${renderInline(token.tokens)}\n\n`;
|
|
58
|
+
case 'text':
|
|
59
|
+
{
|
|
60
|
+
const text = token;
|
|
61
|
+
return text.tokens ? renderInline(text.tokens) : escapeSlackText(text.text);
|
|
62
|
+
}
|
|
63
|
+
case 'code':
|
|
64
|
+
return `${renderCode(token)}\n\n`;
|
|
65
|
+
case 'blockquote':
|
|
66
|
+
return renderBlocks(token.tokens).trimEnd().split('\n').map((line)=>`> ${line}`).join('\n') + '\n\n';
|
|
67
|
+
case 'list':
|
|
68
|
+
return renderList(token);
|
|
69
|
+
case 'space':
|
|
70
|
+
return '';
|
|
71
|
+
case 'hr':
|
|
72
|
+
return '—\n\n';
|
|
73
|
+
default:
|
|
74
|
+
return escapeSlackText(token.raw ?? '');
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
function renderInline(tokens) {
|
|
78
|
+
return tokens.map((token)=>{
|
|
79
|
+
switch(token.type){
|
|
80
|
+
case 'text':
|
|
81
|
+
return escapeSlackText(token.text);
|
|
82
|
+
case 'strong':
|
|
83
|
+
return `*${renderInline(token.tokens)}*`;
|
|
84
|
+
case 'em':
|
|
85
|
+
return `_${renderInline(token.tokens)}_`;
|
|
86
|
+
case 'del':
|
|
87
|
+
return `~${renderInline(token.tokens)}~`;
|
|
88
|
+
case 'codespan':
|
|
89
|
+
return `\`${escapeSlackText(token.text)}\``;
|
|
90
|
+
case 'link':
|
|
91
|
+
{
|
|
92
|
+
const link = token;
|
|
93
|
+
return `<${escapeLinkTarget(link.href)}|${renderInline(link.tokens)}>`;
|
|
94
|
+
}
|
|
95
|
+
case 'br':
|
|
96
|
+
return '\n';
|
|
97
|
+
default:
|
|
98
|
+
return escapeSlackText(token.raw ?? '');
|
|
99
|
+
}
|
|
100
|
+
}).join('');
|
|
101
|
+
}
|
|
102
|
+
function renderCode(token) {
|
|
103
|
+
return `\`\`\`\n${escapeSlackText(token.text)}\n\`\`\``;
|
|
104
|
+
}
|
|
105
|
+
function renderList(token) {
|
|
106
|
+
return token.items.map((item, index)=>{
|
|
107
|
+
const marker = token.ordered ? `${(token.start || 1) + index}.` : '•';
|
|
108
|
+
return `${marker} ${renderBlocks(item.tokens).trim()}\n`;
|
|
109
|
+
}).join('') + '\n';
|
|
110
|
+
}
|
|
111
|
+
function escapeLinkTarget(href) {
|
|
112
|
+
return href.replace(/&/g, '&').replace(/>/g, '%3E').replace(/\|/g, '%7C');
|
|
113
|
+
}
|
|
114
|
+
function splitCode(code, maxLength) {
|
|
115
|
+
const wrapperLength = 8;
|
|
116
|
+
const contentLimit = Math.max(1, maxLength - wrapperLength);
|
|
117
|
+
const parts = [];
|
|
118
|
+
let current = '';
|
|
119
|
+
for (const char of Array.from(code)){
|
|
120
|
+
const escaped = escapeSlackText(char);
|
|
121
|
+
if (current.length + escaped.length > contentLimit && current) {
|
|
122
|
+
parts.push(current);
|
|
123
|
+
current = '';
|
|
124
|
+
}
|
|
125
|
+
current += escaped;
|
|
126
|
+
}
|
|
127
|
+
if (current) parts.push(current);
|
|
128
|
+
return parts.map((part)=>`\`\`\`\n${part}\n\`\`\``);
|
|
129
|
+
}
|
|
130
|
+
function splitRendered(text, maxLength) {
|
|
131
|
+
return splitText(text, maxLength);
|
|
132
|
+
}
|
|
133
|
+
function splitText(text, maxLength) {
|
|
134
|
+
const chunks = [];
|
|
135
|
+
let current = '';
|
|
136
|
+
for (const unit of text.match(/.*(?:\n|$)|./gu) ?? []){
|
|
137
|
+
if (!unit) continue;
|
|
138
|
+
for (const char of Array.from(unit)){
|
|
139
|
+
if (current.length + char.length > maxLength && current) {
|
|
140
|
+
chunks.push(current);
|
|
141
|
+
current = '';
|
|
142
|
+
}
|
|
143
|
+
current += char;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (current) chunks.push(current);
|
|
147
|
+
return chunks;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
//# sourceMappingURL=slackMarkdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/slackMarkdown.ts"],"sourcesContent":["import { Marked, type Token, type Tokens } from 'marked';\n\nexport const SLACK_MAX_MESSAGE_LENGTH = 4000;\nconst lexer = new Marked();\n\nexport function escapeSlackText(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nexport function markdownToSlackMrkdwn(markdown: string): string {\n return renderBlocks(lexer.lexer(markdown)).trimEnd();\n}\n\nexport function chunkMarkdownForSlack(\n markdown: string,\n maxLength = SLACK_MAX_MESSAGE_LENGTH,\n): string[] {\n const tokens = lexer.lexer(markdown);\n const chunks: string[] = [];\n let current = '';\n\n const append = (rendered: string): void => {\n if (!rendered) return;\n if (rendered.length > maxLength) {\n if (current) {\n chunks.push(current.trimEnd());\n current = '';\n }\n chunks.push(...splitRendered(rendered.trimEnd(), maxLength));\n return;\n }\n const candidate = current ? `${current}${rendered}` : rendered;\n if (candidate.trimEnd().length <= maxLength) {\n current = candidate;\n } else {\n chunks.push(current.trimEnd());\n current = rendered;\n }\n };\n\n for (const token of tokens) {\n if (token.type === 'code') {\n const rendered = renderCode(token as Tokens.Code);\n if (rendered.length > maxLength) {\n if (current) {\n chunks.push(current.trimEnd());\n current = '';\n }\n chunks.push(...splitCode((token as Tokens.Code).text, maxLength));\n continue;\n }\n }\n append(renderBlock(token));\n }\n if (current.trimEnd()) chunks.push(current.trimEnd());\n return chunks;\n}\n\nfunction renderBlocks(tokens: Token[]): string {\n return tokens.map(renderBlock).join('');\n}\n\nfunction renderBlock(token: Token): string {\n switch (token.type) {\n case 'heading':\n return `*${renderInline((token as Tokens.Heading).tokens)}*\\n\\n`;\n case 'paragraph':\n return `${renderInline((token as Tokens.Paragraph).tokens)}\\n\\n`;\n case 'text': {\n const text = token as Tokens.Text;\n return text.tokens ? renderInline(text.tokens) : escapeSlackText(text.text);\n }\n case 'code':\n return `${renderCode(token as Tokens.Code)}\\n\\n`;\n case 'blockquote':\n return renderBlocks((token as Tokens.Blockquote).tokens)\n .trimEnd().split('\\n').map((line) => `> ${line}`).join('\\n') + '\\n\\n';\n case 'list':\n return renderList(token as Tokens.List);\n case 'space':\n return '';\n case 'hr':\n return '—\\n\\n';\n default:\n return escapeSlackText(token.raw ?? '');\n }\n}\n\nfunction renderInline(tokens: Token[]): string {\n return tokens.map((token) => {\n switch (token.type) {\n case 'text':\n return escapeSlackText((token as Tokens.Text).text);\n case 'strong':\n return `*${renderInline((token as Tokens.Strong).tokens)}*`;\n case 'em':\n return `_${renderInline((token as Tokens.Em).tokens)}_`;\n case 'del':\n return `~${renderInline((token as Tokens.Del).tokens)}~`;\n case 'codespan':\n return `\\`${escapeSlackText((token as Tokens.Codespan).text)}\\``;\n case 'link': {\n const link = token as Tokens.Link;\n return `<${escapeLinkTarget(link.href)}|${renderInline(link.tokens)}>`;\n }\n case 'br':\n return '\\n';\n default:\n return escapeSlackText(token.raw ?? '');\n }\n }).join('');\n}\n\nfunction renderCode(token: Tokens.Code): string {\n return `\\`\\`\\`\\n${escapeSlackText(token.text)}\\n\\`\\`\\``;\n}\n\nfunction renderList(token: Tokens.List): string {\n return token.items.map((item, index) => {\n const marker = token.ordered ? `${(token.start || 1) + index}.` : '•';\n return `${marker} ${renderBlocks(item.tokens).trim()}\\n`;\n }).join('') + '\\n';\n}\n\nfunction escapeLinkTarget(href: string): string {\n return href.replace(/&/g, '&').replace(/>/g, '%3E').replace(/\\|/g, '%7C');\n}\n\nfunction splitCode(code: string, maxLength: number): string[] {\n const wrapperLength = 8;\n const contentLimit = Math.max(1, maxLength - wrapperLength);\n const parts: string[] = [];\n let current = '';\n for (const char of Array.from(code)) {\n const escaped = escapeSlackText(char);\n if (current.length + escaped.length > contentLimit && current) {\n parts.push(current);\n current = '';\n }\n current += escaped;\n }\n if (current) parts.push(current);\n return parts.map((part) => `\\`\\`\\`\\n${part}\\n\\`\\`\\``);\n}\n\nfunction splitRendered(text: string, maxLength: number): string[] {\n return splitText(text, maxLength);\n}\n\nfunction splitText(text: string, maxLength: number): string[] {\n const chunks: string[] = [];\n let current = '';\n for (const unit of text.match(/.*(?:\\n|$)|./gu) ?? []) {\n if (!unit) continue;\n for (const char of Array.from(unit)) {\n if (current.length + char.length > maxLength && current) {\n chunks.push(current);\n current = '';\n }\n current += char;\n }\n }\n if (current) chunks.push(current);\n return chunks;\n}\n"],"names":["Marked","SLACK_MAX_MESSAGE_LENGTH","lexer","escapeSlackText","text","replace","markdownToSlackMrkdwn","markdown","renderBlocks","trimEnd","chunkMarkdownForSlack","maxLength","tokens","chunks","current","append","rendered","length","push","splitRendered","candidate","token","type","renderCode","splitCode","renderBlock","map","join","renderInline","split","line","renderList","raw","link","escapeLinkTarget","href","items","item","index","marker","ordered","start","trim","code","wrapperLength","contentLimit","Math","max","parts","char","Array","from","escaped","part","splitText","unit","match"],"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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"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"nx": {
|
|
4
4
|
"name": "channel-connector"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.13.1",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"description": "Generic messaging bridge for connecting to external communication platforms",
|
|
9
9
|
"main": "dist/index.js",
|
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
"directory": "packages/channel-connector"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
+
"@slack/socket-mode": "^3.0.0",
|
|
43
|
+
"@slack/web-api": "^8.0.0",
|
|
42
44
|
"marked": "^15.0.12",
|
|
43
45
|
"telegraf": "^4.16.3",
|
|
44
46
|
"uuid": "14.0.0"
|