@krischoichoi/channel-telegram 0.6.0
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 +129 -0
- package/lib/adapter.d.ts +94 -0
- package/lib/adapter.d.ts.map +1 -0
- package/lib/adapter.js +417 -0
- package/lib/adapter.js.map +1 -0
- package/lib/api-error.d.ts +74 -0
- package/lib/api-error.d.ts.map +1 -0
- package/lib/api-error.js +103 -0
- package/lib/api-error.js.map +1 -0
- package/lib/config.d.ts +115 -0
- package/lib/config.d.ts.map +1 -0
- package/lib/config.js +67 -0
- package/lib/config.js.map +1 -0
- package/lib/definition.d.ts +59 -0
- package/lib/definition.d.ts.map +1 -0
- package/lib/definition.js +158 -0
- package/lib/definition.js.map +1 -0
- package/lib/inbound.d.ts +61 -0
- package/lib/inbound.d.ts.map +1 -0
- package/lib/inbound.js +125 -0
- package/lib/inbound.js.map +1 -0
- package/lib/index.d.ts +52 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +114 -0
- package/lib/index.js.map +1 -0
- package/lib/manifest.d.ts +16 -0
- package/lib/manifest.d.ts.map +1 -0
- package/lib/manifest.js +26 -0
- package/lib/manifest.js.map +1 -0
- package/lib/mapper.d.ts +51 -0
- package/lib/mapper.d.ts.map +1 -0
- package/lib/mapper.js +314 -0
- package/lib/mapper.js.map +1 -0
- package/lib/media-hydrator.d.ts +46 -0
- package/lib/media-hydrator.d.ts.map +1 -0
- package/lib/media-hydrator.js +85 -0
- package/lib/media-hydrator.js.map +1 -0
- package/lib/outbound.d.ts +42 -0
- package/lib/outbound.d.ts.map +1 -0
- package/lib/outbound.js +215 -0
- package/lib/outbound.js.map +1 -0
- package/lib/render/html.d.ts +13 -0
- package/lib/render/html.d.ts.map +1 -0
- package/lib/render/html.js +110 -0
- package/lib/render/html.js.map +1 -0
- package/lib/render/index.d.ts +64 -0
- package/lib/render/index.d.ts.map +1 -0
- package/lib/render/index.js +76 -0
- package/lib/render/index.js.map +1 -0
- package/lib/render/markdown.d.ts +38 -0
- package/lib/render/markdown.d.ts.map +1 -0
- package/lib/render/markdown.js +187 -0
- package/lib/render/markdown.js.map +1 -0
- package/lib/render/plain.d.ts +43 -0
- package/lib/render/plain.d.ts.map +1 -0
- package/lib/render/plain.js +97 -0
- package/lib/render/plain.js.map +1 -0
- package/lib/render/segment.d.ts +39 -0
- package/lib/render/segment.d.ts.map +1 -0
- package/lib/render/segment.js +117 -0
- package/lib/render/segment.js.map +1 -0
- package/lib/rich-message.d.ts +75 -0
- package/lib/rich-message.d.ts.map +1 -0
- package/lib/rich-message.js +11 -0
- package/lib/rich-message.js.map +1 -0
- package/lib/rich-streaming-reply.d.ts +69 -0
- package/lib/rich-streaming-reply.d.ts.map +1 -0
- package/lib/rich-streaming-reply.js +207 -0
- package/lib/rich-streaming-reply.js.map +1 -0
- package/lib/streaming-reply.d.ts +98 -0
- package/lib/streaming-reply.d.ts.map +1 -0
- package/lib/streaming-reply.js +274 -0
- package/lib/streaming-reply.js.map +1 -0
- package/lib/transport.d.ts +38 -0
- package/lib/transport.d.ts.map +1 -0
- package/lib/transport.js +91 -0
- package/lib/transport.js.map +1 -0
- package/lib/upstream.d.ts +174 -0
- package/lib/upstream.d.ts.map +1 -0
- package/lib/upstream.js +452 -0
- package/lib/upstream.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { fromMarkdown } from 'mdast-util-from-markdown';
|
|
2
|
+
import { gfmFromMarkdown, gfmToMarkdown } from 'mdast-util-gfm';
|
|
3
|
+
import { toMarkdown } from 'mdast-util-to-markdown';
|
|
4
|
+
import { toString } from 'mdast-util-to-string';
|
|
5
|
+
import { gfm } from 'micromark-extension-gfm';
|
|
6
|
+
import { RICH_MESSAGE_MAX_BLOCKS, RICH_MESSAGE_MAX_NESTING, RICH_MESSAGE_MAX_TABLE_COLUMNS, RICH_MESSAGE_MAX_UTF8, } from '../rich-message.js';
|
|
7
|
+
import { splitByUtf8Graphemes, utf8Length } from './segment.js';
|
|
8
|
+
export function parseMarkdown(source) {
|
|
9
|
+
return fromMarkdown(source, {
|
|
10
|
+
extensions: [gfm()],
|
|
11
|
+
mdastExtensions: [gfmFromMarkdown()],
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function serializeNode(node) {
|
|
15
|
+
return toMarkdown({ type: 'root', children: [node] }, { extensions: [gfmToMarkdown()] }).trimEnd();
|
|
16
|
+
}
|
|
17
|
+
function tableCells(row) {
|
|
18
|
+
return row.children.map((cell) => toString(cell));
|
|
19
|
+
}
|
|
20
|
+
function sourceMarkdown(source, node) {
|
|
21
|
+
const start = node.position?.start.offset;
|
|
22
|
+
const end = node.position?.end.offset;
|
|
23
|
+
if (start !== undefined && end !== undefined)
|
|
24
|
+
return source.slice(start, end).trimEnd();
|
|
25
|
+
return serializeNode(node);
|
|
26
|
+
}
|
|
27
|
+
function asBlock(source, node) {
|
|
28
|
+
const markdown = sourceMarkdown(source, node);
|
|
29
|
+
switch (node.type) {
|
|
30
|
+
case 'code':
|
|
31
|
+
return { kind: 'code', lang: node.lang ?? '', code: node.value, node, markdown };
|
|
32
|
+
case 'heading':
|
|
33
|
+
return { kind: 'heading', level: node.depth, text: toString(node), node, markdown };
|
|
34
|
+
case 'table':
|
|
35
|
+
return {
|
|
36
|
+
kind: 'table',
|
|
37
|
+
header: node.children[0] ? tableCells(node.children[0]) : [],
|
|
38
|
+
rows: node.children.slice(1).map(tableCells),
|
|
39
|
+
node,
|
|
40
|
+
markdown,
|
|
41
|
+
};
|
|
42
|
+
case 'blockquote':
|
|
43
|
+
return { kind: 'blockquote', content: toString(node), node, markdown };
|
|
44
|
+
case 'list':
|
|
45
|
+
return {
|
|
46
|
+
kind: 'list',
|
|
47
|
+
ordered: node.ordered === true,
|
|
48
|
+
items: node.children.map((item) => toString(item)),
|
|
49
|
+
node,
|
|
50
|
+
markdown,
|
|
51
|
+
};
|
|
52
|
+
default:
|
|
53
|
+
return { kind: 'paragraph', text: toString(node) || markdown, node, markdown };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export function tokenizeMarkdown(source) {
|
|
57
|
+
if (!source)
|
|
58
|
+
return [];
|
|
59
|
+
return parseMarkdown(source).children.map((node) => asBlock(source, node));
|
|
60
|
+
}
|
|
61
|
+
export function renderBlock(block) {
|
|
62
|
+
return block.markdown;
|
|
63
|
+
}
|
|
64
|
+
function nodeStats(node) {
|
|
65
|
+
let count = 0;
|
|
66
|
+
let maxDepth = 0;
|
|
67
|
+
const visit = (value, depth) => {
|
|
68
|
+
if (!value || typeof value !== 'object')
|
|
69
|
+
return;
|
|
70
|
+
count += 1;
|
|
71
|
+
maxDepth = Math.max(maxDepth, depth);
|
|
72
|
+
const children = value.children;
|
|
73
|
+
for (const child of children ?? [])
|
|
74
|
+
visit(child, depth + 1);
|
|
75
|
+
};
|
|
76
|
+
visit(node, 1);
|
|
77
|
+
return { count, depth: maxDepth };
|
|
78
|
+
}
|
|
79
|
+
const MARKDOWN_LITERAL = /[\\`*_[\]{}()<>#+\-.!|>~=]/;
|
|
80
|
+
/** Escape literal text and pack complete escape sequences under a byte limit. */
|
|
81
|
+
function literalChunks(value, limit) {
|
|
82
|
+
const segmenter = new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
83
|
+
const chunks = [];
|
|
84
|
+
let current = '';
|
|
85
|
+
let bytes = 0;
|
|
86
|
+
for (const item of segmenter.segment(value)) {
|
|
87
|
+
const escaped = MARKDOWN_LITERAL.test(item.segment) ? `\\${item.segment}` : item.segment;
|
|
88
|
+
const size = utf8Length(escaped);
|
|
89
|
+
if (current && bytes + size > limit) {
|
|
90
|
+
chunks.push(current);
|
|
91
|
+
current = '';
|
|
92
|
+
bytes = 0;
|
|
93
|
+
}
|
|
94
|
+
current += escaped;
|
|
95
|
+
bytes += size;
|
|
96
|
+
}
|
|
97
|
+
if (current)
|
|
98
|
+
chunks.push(current);
|
|
99
|
+
return chunks;
|
|
100
|
+
}
|
|
101
|
+
function splitCode(node, limit) {
|
|
102
|
+
const bodyBudget = Math.max(1, limit - utf8Length(node.lang ?? '') - 16);
|
|
103
|
+
const result = [];
|
|
104
|
+
for (const value of splitByUtf8Graphemes(node.value, bodyBudget)) {
|
|
105
|
+
const markdown = serializeNode({ ...node, value });
|
|
106
|
+
if (utf8Length(markdown) <= limit)
|
|
107
|
+
result.push(markdown);
|
|
108
|
+
else
|
|
109
|
+
result.push(...literalChunks(value, limit));
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
function splitTable(node, limit) {
|
|
114
|
+
if (node.children.length === 0 || node.children[0].children.length > RICH_MESSAGE_MAX_TABLE_COLUMNS) {
|
|
115
|
+
return literalChunks(toString(node), limit);
|
|
116
|
+
}
|
|
117
|
+
const header = node.children[0];
|
|
118
|
+
const chunks = [];
|
|
119
|
+
let rows = [];
|
|
120
|
+
const flush = () => {
|
|
121
|
+
if (rows.length === 0)
|
|
122
|
+
return;
|
|
123
|
+
chunks.push(serializeNode({ ...node, children: [header, ...rows] }));
|
|
124
|
+
rows = [];
|
|
125
|
+
};
|
|
126
|
+
for (const row of node.children.slice(1)) {
|
|
127
|
+
const candidate = serializeNode({ ...node, children: [header, ...rows, row] });
|
|
128
|
+
if (utf8Length(candidate) <= limit) {
|
|
129
|
+
rows.push(row);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
flush();
|
|
133
|
+
const single = serializeNode({ ...node, children: [header, row] });
|
|
134
|
+
if (utf8Length(single) <= limit)
|
|
135
|
+
chunks.push(single);
|
|
136
|
+
else
|
|
137
|
+
chunks.push(...literalChunks(toString(row), limit));
|
|
138
|
+
}
|
|
139
|
+
flush();
|
|
140
|
+
return chunks.length > 0 ? chunks : [serializeNode(node)];
|
|
141
|
+
}
|
|
142
|
+
function splitBlock(block, limit) {
|
|
143
|
+
if (block.node.type === 'code')
|
|
144
|
+
return splitCode(block.node, limit);
|
|
145
|
+
if (block.node.type === 'table')
|
|
146
|
+
return splitTable(block.node, limit);
|
|
147
|
+
return literalChunks(toString(block.node) || block.markdown, limit);
|
|
148
|
+
}
|
|
149
|
+
/** Segment parsed blocks under Telegram's byte, block-count, and depth limits. */
|
|
150
|
+
export function segmentRich(blocks, limit = RICH_MESSAGE_MAX_UTF8) {
|
|
151
|
+
const messages = [];
|
|
152
|
+
let current = [];
|
|
153
|
+
let bytes = 0;
|
|
154
|
+
let blocksInMessage = 0;
|
|
155
|
+
const flush = () => {
|
|
156
|
+
if (current.length > 0)
|
|
157
|
+
messages.push(current.join('\n\n'));
|
|
158
|
+
current = [];
|
|
159
|
+
bytes = 0;
|
|
160
|
+
blocksInMessage = 0;
|
|
161
|
+
};
|
|
162
|
+
for (const block of blocks) {
|
|
163
|
+
const stats = nodeStats(block.node);
|
|
164
|
+
const rendered = block.markdown;
|
|
165
|
+
const renderedBytes = utf8Length(rendered);
|
|
166
|
+
const separator = current.length > 0 ? 2 : 0;
|
|
167
|
+
const unsafeStructure = stats.depth > RICH_MESSAGE_MAX_NESTING || stats.count > RICH_MESSAGE_MAX_BLOCKS;
|
|
168
|
+
if (unsafeStructure || renderedBytes > limit) {
|
|
169
|
+
flush();
|
|
170
|
+
messages.push(...splitBlock(block, limit));
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
if (bytes + separator + renderedBytes > limit ||
|
|
174
|
+
blocksInMessage + stats.count > RICH_MESSAGE_MAX_BLOCKS)
|
|
175
|
+
flush();
|
|
176
|
+
current.push(rendered);
|
|
177
|
+
bytes += (current.length > 1 ? 2 : 0) + renderedBytes;
|
|
178
|
+
blocksInMessage += stats.count;
|
|
179
|
+
}
|
|
180
|
+
flush();
|
|
181
|
+
return messages;
|
|
182
|
+
}
|
|
183
|
+
export function renderRichMarkdown(source, limit = RICH_MESSAGE_MAX_UTF8) {
|
|
184
|
+
return segmentRich(tokenizeMarkdown(source), limit);
|
|
185
|
+
}
|
|
186
|
+
export { tokenizeMarkdown as tokenize };
|
|
187
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/render/markdown.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plain fallback + MarkdownV2 escaping renderers (plan §5.3 / §20.9).
|
|
3
|
+
*
|
|
4
|
+
* - `renderPlain(source)` — best-effort plain-text fallback, segmented at the
|
|
5
|
+
* regular 4096 grapheme-safe limit. Used when a rich/formatted send fails
|
|
6
|
+
* with a *format* error (and only then).
|
|
7
|
+
* - `renderPlainCaption()` — the 1024-caption variant.
|
|
8
|
+
* - `escapeMarkdownV2(...)` — full escaping of MarkdownV2 special characters.
|
|
9
|
+
* The adapter NEVER sends raw Agent Markdown as MarkdownV2
|
|
10
|
+
* (plan §5.3 red line); a `markdown-v2` config mode must pass every literal
|
|
11
|
+
* through this escape first.
|
|
12
|
+
*
|
|
13
|
+
* The plain fallback is deliberately structural: it strips Markdown markup so
|
|
14
|
+
* the user still sees readable text (headers, bold, code) instead of raw
|
|
15
|
+
* `**`/`#`/backticks, while never throwing on unfinished Markdown.
|
|
16
|
+
*/
|
|
17
|
+
import { type MarkdownBlock } from './markdown.js';
|
|
18
|
+
/** Strip inline Markdown from a single line/paragraph. */
|
|
19
|
+
export declare function inlineMarkdownToPlain(text: string): string;
|
|
20
|
+
/** Render one block to plain text. */
|
|
21
|
+
export declare function blockToPlain(block: MarkdownBlock): string;
|
|
22
|
+
/** Convert Markdown source to a single plain-text string. */
|
|
23
|
+
export declare function markdownToPlain(source: string): string;
|
|
24
|
+
/** Segment plain text into ≤ `limit` grapheme chunks. */
|
|
25
|
+
export declare function segmentPlain(text: string, limit?: number): string[];
|
|
26
|
+
/** Plain fallback for regular messages (4096). */
|
|
27
|
+
export declare function renderPlain(source: string, limit?: number): string[];
|
|
28
|
+
/** Plain fallback for media captions (1024). */
|
|
29
|
+
export declare function renderPlainCaption(source: string, limit?: number): string[];
|
|
30
|
+
/**
|
|
31
|
+
* Escape a piece of literal text for Telegram MarkdownV2 so it cannot be
|
|
32
|
+
* interpreted as formatting. This is the ONLY sanctioned way to send Agent
|
|
33
|
+
* Markdown in `markdown-v2` mode — never pass raw Agent Markdown as the body.
|
|
34
|
+
*/
|
|
35
|
+
export declare function escapeMarkdownV2(text: string): string;
|
|
36
|
+
/**
|
|
37
|
+
* Render MarkdownV2-escaped chunks. `markdown-v2` is an expert-compat mode:
|
|
38
|
+
* the RAW Agent Markdown is fully escaped so Telegram never interprets it as
|
|
39
|
+
* formatting (plan §5.3 red line — never send raw Agent Markdown as a
|
|
40
|
+
* MarkdownV2 body). The visible text keeps its original markdown source.
|
|
41
|
+
*/
|
|
42
|
+
export declare function renderMarkdownV2(source: string, limit?: number): string[];
|
|
43
|
+
//# sourceMappingURL=plain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain.d.ts","sourceRoot":"","sources":["../../src/render/plain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAIrE,0DAA0D;AAC1D,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,sCAAsC;AACtC,wBAAgB,YAAY,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAoBzD;AAED,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED,yDAAyD;AACzD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,SAAsB,GAAG,MAAM,EAAE,CAEhF;AAED,kDAAkD;AAClD,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAsB,GAAG,MAAM,EAAE,CAGjF;AAED,gDAAgD;AAChD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAc,GAAG,MAAM,EAAE,CAIhF;AAKD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,SAAsB,GAAG,MAAM,EAAE,CAGtF"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plain fallback + MarkdownV2 escaping renderers (plan §5.3 / §20.9).
|
|
3
|
+
*
|
|
4
|
+
* - `renderPlain(source)` — best-effort plain-text fallback, segmented at the
|
|
5
|
+
* regular 4096 grapheme-safe limit. Used when a rich/formatted send fails
|
|
6
|
+
* with a *format* error (and only then).
|
|
7
|
+
* - `renderPlainCaption()` — the 1024-caption variant.
|
|
8
|
+
* - `escapeMarkdownV2(...)` — full escaping of MarkdownV2 special characters.
|
|
9
|
+
* The adapter NEVER sends raw Agent Markdown as MarkdownV2
|
|
10
|
+
* (plan §5.3 red line); a `markdown-v2` config mode must pass every literal
|
|
11
|
+
* through this escape first.
|
|
12
|
+
*
|
|
13
|
+
* The plain fallback is deliberately structural: it strips Markdown markup so
|
|
14
|
+
* the user still sees readable text (headers, bold, code) instead of raw
|
|
15
|
+
* `**`/`#`/backticks, while never throwing on unfinished Markdown.
|
|
16
|
+
*/
|
|
17
|
+
import { tokenizeMarkdown } from './markdown.js';
|
|
18
|
+
import { splitByGraphemes } from './segment.js';
|
|
19
|
+
import { CAPTION_MAX, REGULAR_MESSAGE_MAX } from '../rich-message.js';
|
|
20
|
+
/** Strip inline Markdown from a single line/paragraph. */
|
|
21
|
+
export function inlineMarkdownToPlain(text) {
|
|
22
|
+
return text
|
|
23
|
+
.replace(/\*\*(.+?)\*\*/g, '$1')
|
|
24
|
+
.replace(/\*(.+?)\*/g, '$1')
|
|
25
|
+
.replace(/`([^`]+)`/g, '$1')
|
|
26
|
+
.replace(/\[([^\]]*)\]\([^)]*\)/g, '$1');
|
|
27
|
+
}
|
|
28
|
+
/** Render one block to plain text. */
|
|
29
|
+
export function blockToPlain(block) {
|
|
30
|
+
switch (block.kind) {
|
|
31
|
+
case 'heading':
|
|
32
|
+
return block.text;
|
|
33
|
+
case 'code':
|
|
34
|
+
return block.code;
|
|
35
|
+
case 'table':
|
|
36
|
+
return [
|
|
37
|
+
`| ${block.header.join(' | ')} |`,
|
|
38
|
+
...block.rows.map((row) => `| ${row.join(' | ')} |`),
|
|
39
|
+
].join('\n');
|
|
40
|
+
case 'blockquote':
|
|
41
|
+
return block.content.split('\n').map((line) => `> ${line}`).join('\n');
|
|
42
|
+
case 'list':
|
|
43
|
+
return block.items
|
|
44
|
+
.map((item, idx) => `${block.ordered ? `${idx + 1}.` : '-'} ${inlineMarkdownToPlain(item)}`)
|
|
45
|
+
.join('\n');
|
|
46
|
+
case 'paragraph':
|
|
47
|
+
return inlineMarkdownToPlain(block.text);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Convert Markdown source to a single plain-text string. */
|
|
51
|
+
export function markdownToPlain(source) {
|
|
52
|
+
if (source.length === 0)
|
|
53
|
+
return '';
|
|
54
|
+
return tokenizeMarkdown(source)
|
|
55
|
+
.map(blockToPlain)
|
|
56
|
+
.filter((text) => text.length > 0)
|
|
57
|
+
.join('\n\n');
|
|
58
|
+
}
|
|
59
|
+
/** Segment plain text into ≤ `limit` grapheme chunks. */
|
|
60
|
+
export function segmentPlain(text, limit = REGULAR_MESSAGE_MAX) {
|
|
61
|
+
return splitByGraphemes(text, limit);
|
|
62
|
+
}
|
|
63
|
+
/** Plain fallback for regular messages (4096). */
|
|
64
|
+
export function renderPlain(source, limit = REGULAR_MESSAGE_MAX) {
|
|
65
|
+
if (source.length === 0)
|
|
66
|
+
return [];
|
|
67
|
+
return segmentPlain(markdownToPlain(source), limit);
|
|
68
|
+
}
|
|
69
|
+
/** Plain fallback for media captions (1024). */
|
|
70
|
+
export function renderPlainCaption(source, limit = CAPTION_MAX) {
|
|
71
|
+
if (source.length === 0)
|
|
72
|
+
return [''];
|
|
73
|
+
const chunks = segmentPlain(markdownToPlain(source), limit);
|
|
74
|
+
return chunks.length > 0 ? chunks : [''];
|
|
75
|
+
}
|
|
76
|
+
/** Characters Telegram's MarkdownV2 parser reserves; each must be escaped. */
|
|
77
|
+
const MARKDOWN_V2_SPECIAL = /[_*[\]()~`>#+\-=|{}.!\\]/g;
|
|
78
|
+
/**
|
|
79
|
+
* Escape a piece of literal text for Telegram MarkdownV2 so it cannot be
|
|
80
|
+
* interpreted as formatting. This is the ONLY sanctioned way to send Agent
|
|
81
|
+
* Markdown in `markdown-v2` mode — never pass raw Agent Markdown as the body.
|
|
82
|
+
*/
|
|
83
|
+
export function escapeMarkdownV2(text) {
|
|
84
|
+
return text.replace(MARKDOWN_V2_SPECIAL, '\\$&');
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Render MarkdownV2-escaped chunks. `markdown-v2` is an expert-compat mode:
|
|
88
|
+
* the RAW Agent Markdown is fully escaped so Telegram never interprets it as
|
|
89
|
+
* formatting (plan §5.3 red line — never send raw Agent Markdown as a
|
|
90
|
+
* MarkdownV2 body). The visible text keeps its original markdown source.
|
|
91
|
+
*/
|
|
92
|
+
export function renderMarkdownV2(source, limit = REGULAR_MESSAGE_MAX) {
|
|
93
|
+
if (source.length === 0)
|
|
94
|
+
return [];
|
|
95
|
+
return splitByGraphemes(escapeMarkdownV2(source), limit);
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=plain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plain.js","sourceRoot":"","sources":["../../src/render/plain.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/** UTF-8 byte length used by Telegram Rich Message limits. */
|
|
2
|
+
export declare function utf8Length(text: string): number;
|
|
3
|
+
/** Split by UTF-8 byte budget without cutting a grapheme cluster. */
|
|
4
|
+
export declare function splitByUtf8Graphemes(text: string, maxBytes: number): string[];
|
|
5
|
+
/**
|
|
6
|
+
* Total visible length of `text` in grapheme clusters (not code points). Used
|
|
7
|
+
* for the caption / regular rich-message length gates.
|
|
8
|
+
*/
|
|
9
|
+
export declare function visibleLength(text: string): number;
|
|
10
|
+
/**
|
|
11
|
+
* Split `text` into chunks not exceeding `maxLength` grapheme clusters.
|
|
12
|
+
*
|
|
13
|
+
* Guarantees:
|
|
14
|
+
* - no chunk exceeds `maxLength` grapheme clusters
|
|
15
|
+
* - never cuts a grapheme cluster in half
|
|
16
|
+
* - joins graphemes back into the original text in order
|
|
17
|
+
*/
|
|
18
|
+
export declare function splitByGraphemes(text: string, maxLength: number): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Split an already-linearized grapheme array into chunks of at most `maxLength`
|
|
21
|
+
* clusters. This is the low-level primitive used by the block-aware renderer
|
|
22
|
+
* (which works over logical text ranges, not arbitrary code-point slices).
|
|
23
|
+
*/
|
|
24
|
+
export declare function splitGraphemeList(graphemeList: string[], maxLength: number): string[][];
|
|
25
|
+
/**
|
|
26
|
+
* Hard-limit a single text to `maxLength` grapheme clusters, truncating at a
|
|
27
|
+
* grapheme boundary (never mid-cluster). Used for placeholder text and editor
|
|
28
|
+
* previews where splitting is not desired.
|
|
29
|
+
*/
|
|
30
|
+
export declare function truncateGraphemes(text: string, maxLength: number): string;
|
|
31
|
+
/** Return the LAST `n` grapheme clusters of `text` (never mid-cluster). */
|
|
32
|
+
export declare function tailGraphemes(text: string, n: number): string;
|
|
33
|
+
/** Built-in message length limits for plain/regular output. */
|
|
34
|
+
export declare const LIMITS: {
|
|
35
|
+
readonly regular: 4096;
|
|
36
|
+
readonly caption: 1024;
|
|
37
|
+
readonly rich: 32768;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=segment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment.d.ts","sourceRoot":"","sources":["../../src/render/segment.ts"],"names":[],"mappings":"AA4BA,8DAA8D;AAC9D,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED,qEAAqE;AACrE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAyB7E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAI1E;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,CAYvF;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAEzE;AAED,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,+DAA+D;AAC/D,eAAO,MAAM,MAAM;;;;CAIT,CAAC"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unicode-safe segmentation helpers (execution plan §7.2 / §20.8).
|
|
3
|
+
*
|
|
4
|
+
* The legacy splitter (`Array.from(text)` + code-point slicing in the streaming
|
|
5
|
+
* reply) can cut a grapheme cluster (emoji ZWJ sequences, flags, variation
|
|
6
|
+
* selectors, combining marks) in the middle, producing broken glyphs and, worse,
|
|
7
|
+
* breaking a Markdown code fence / table row mid-stream.
|
|
8
|
+
*
|
|
9
|
+
* This module is the single place that performs caller-visible character math
|
|
10
|
+
* for fallback/plain output. It uses `Intl.Segmenter(grapheme)` so a user-visible
|
|
11
|
+
* character never spans two messages.
|
|
12
|
+
*/
|
|
13
|
+
import { CAPTION_MAX, REGULAR_MESSAGE_MAX, RICH_MESSAGE_MAX_UTF8, } from '../rich-message.js';
|
|
14
|
+
let segmenter;
|
|
15
|
+
/** Lazily-built, shared grapheme segmenter (Node >= 16 has Intl.Segmenter). */
|
|
16
|
+
function graphemes(text) {
|
|
17
|
+
segmenter ??= new Intl.Segmenter(undefined, { granularity: 'grapheme' });
|
|
18
|
+
return [...segmenter.segment(text)].map((s) => s.segment);
|
|
19
|
+
}
|
|
20
|
+
const encoder = new TextEncoder();
|
|
21
|
+
/** UTF-8 byte length used by Telegram Rich Message limits. */
|
|
22
|
+
export function utf8Length(text) {
|
|
23
|
+
return encoder.encode(text).byteLength;
|
|
24
|
+
}
|
|
25
|
+
/** Split by UTF-8 byte budget without cutting a grapheme cluster. */
|
|
26
|
+
export function splitByUtf8Graphemes(text, maxBytes) {
|
|
27
|
+
if (text.length === 0)
|
|
28
|
+
return [];
|
|
29
|
+
if (maxBytes <= 0)
|
|
30
|
+
return [text];
|
|
31
|
+
const chunks = [];
|
|
32
|
+
let current = '';
|
|
33
|
+
let currentBytes = 0;
|
|
34
|
+
for (const grapheme of graphemes(text)) {
|
|
35
|
+
const bytes = utf8Length(grapheme);
|
|
36
|
+
if (current && currentBytes + bytes > maxBytes) {
|
|
37
|
+
chunks.push(current);
|
|
38
|
+
current = '';
|
|
39
|
+
currentBytes = 0;
|
|
40
|
+
}
|
|
41
|
+
if (bytes > maxBytes) {
|
|
42
|
+
if (current)
|
|
43
|
+
chunks.push(current);
|
|
44
|
+
chunks.push(grapheme);
|
|
45
|
+
current = '';
|
|
46
|
+
currentBytes = 0;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
current += grapheme;
|
|
50
|
+
currentBytes += bytes;
|
|
51
|
+
}
|
|
52
|
+
if (current)
|
|
53
|
+
chunks.push(current);
|
|
54
|
+
return chunks;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Total visible length of `text` in grapheme clusters (not code points). Used
|
|
58
|
+
* for the caption / regular rich-message length gates.
|
|
59
|
+
*/
|
|
60
|
+
export function visibleLength(text) {
|
|
61
|
+
return graphemes(text).length;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Split `text` into chunks not exceeding `maxLength` grapheme clusters.
|
|
65
|
+
*
|
|
66
|
+
* Guarantees:
|
|
67
|
+
* - no chunk exceeds `maxLength` grapheme clusters
|
|
68
|
+
* - never cuts a grapheme cluster in half
|
|
69
|
+
* - joins graphemes back into the original text in order
|
|
70
|
+
*/
|
|
71
|
+
export function splitByGraphemes(text, maxLength) {
|
|
72
|
+
if (maxLength <= 0)
|
|
73
|
+
return text.length === 0 ? [] : [text];
|
|
74
|
+
if (text.length === 0)
|
|
75
|
+
return [];
|
|
76
|
+
return splitGraphemeList(graphemes(text), maxLength).map((list) => list.join(''));
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Split an already-linearized grapheme array into chunks of at most `maxLength`
|
|
80
|
+
* clusters. This is the low-level primitive used by the block-aware renderer
|
|
81
|
+
* (which works over logical text ranges, not arbitrary code-point slices).
|
|
82
|
+
*/
|
|
83
|
+
export function splitGraphemeList(graphemeList, maxLength) {
|
|
84
|
+
const chunks = [];
|
|
85
|
+
let current = [];
|
|
86
|
+
for (const g of graphemeList) {
|
|
87
|
+
current.push(g);
|
|
88
|
+
if (current.length >= maxLength) {
|
|
89
|
+
chunks.push(current);
|
|
90
|
+
current = [];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (current.length > 0)
|
|
94
|
+
chunks.push(current);
|
|
95
|
+
return chunks;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Hard-limit a single text to `maxLength` grapheme clusters, truncating at a
|
|
99
|
+
* grapheme boundary (never mid-cluster). Used for placeholder text and editor
|
|
100
|
+
* previews where splitting is not desired.
|
|
101
|
+
*/
|
|
102
|
+
export function truncateGraphemes(text, maxLength) {
|
|
103
|
+
return graphemes(text).slice(0, maxLength).join('');
|
|
104
|
+
}
|
|
105
|
+
/** Return the LAST `n` grapheme clusters of `text` (never mid-cluster). */
|
|
106
|
+
export function tailGraphemes(text, n) {
|
|
107
|
+
if (n <= 0)
|
|
108
|
+
return '';
|
|
109
|
+
return graphemes(text).slice(-n).join('');
|
|
110
|
+
}
|
|
111
|
+
/** Built-in message length limits for plain/regular output. */
|
|
112
|
+
export const LIMITS = {
|
|
113
|
+
regular: REGULAR_MESSAGE_MAX, // 4096
|
|
114
|
+
caption: CAPTION_MAX, // 1024
|
|
115
|
+
rich: RICH_MESSAGE_MAX_UTF8, // 32768
|
|
116
|
+
};
|
|
117
|
+
//# sourceMappingURL=segment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"segment.js","sourceRoot":"","sources":["../../src/render/segment.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,qBAAqB,GACtB,MAAM,oBAAoB,CAAC;AAE5B,IAAI,SAAqC,CAAC;AAE1C,+EAA+E;AAC/E,SAAS,SAAS,CAAC,IAAY;IAC7B,SAAS,KAAK,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;AAC5D,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;AAElC,8DAA8D;AAC9D,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC;AACzC,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,QAAgB;IACjE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,QAAQ,IAAI,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,QAAQ,IAAI,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;QACnC,IAAI,OAAO,IAAI,YAAY,GAAG,KAAK,GAAG,QAAQ,EAAE,CAAC;YAC/C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,GAAG,CAAC,CAAC;QACnB,CAAC;QACD,IAAI,KAAK,GAAG,QAAQ,EAAE,CAAC;YACrB,IAAI,OAAO;gBAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACtB,OAAO,GAAG,EAAE,CAAC;YACb,YAAY,GAAG,CAAC,CAAC;YACjB,SAAS;QACX,CAAC;QACD,OAAO,IAAI,QAAQ,CAAC;QACpB,YAAY,IAAI,KAAK,CAAC;IACxB,CAAC;IACD,IAAI,OAAO;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;AAChC,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,SAAiB;IAC9D,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC3D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,iBAAiB,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,YAAsB,EAAE,SAAiB;IACzE,MAAM,MAAM,GAAe,EAAE,CAAC;IAC9B,IAAI,OAAO,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,YAAY,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,IAAI,OAAO,CAAC,MAAM,IAAI,SAAS,EAAE,CAAC;YAChC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrB,OAAO,GAAG,EAAE,CAAC;QACf,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;QAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY,EAAE,SAAiB;IAC/D,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACtD,CAAC;AAED,2EAA2E;AAC3E,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,CAAS;IACnD,IAAI,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACtB,OAAO,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,+DAA+D;AAC/D,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,OAAO,EAAE,mBAAmB,EAAE,OAAO;IACrC,OAAO,EAAE,WAAW,EAAE,OAAO;IAC7B,IAAI,EAAE,qBAAqB,EAAE,QAAQ;CAC7B,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telegram Rich Message + interactive markup payload shapes (Bot API 10.2).
|
|
3
|
+
*
|
|
4
|
+
* This module owns ONLY the Telegram wire contract for rich output and inline
|
|
5
|
+
* buttons. It is a pure-type + constants module (no I/O, no HTTP) so that both
|
|
6
|
+
* the upstream driver and the mapper/outbound layers can share the shapes
|
|
7
|
+
* without duplicating protocol knowledge or pulling the renderer into the
|
|
8
|
+
* transport layer.
|
|
9
|
+
*
|
|
10
|
+
* Wire types come from `@grammyjs/types@4.0.0`, which tracks Bot API 10.2.
|
|
11
|
+
* The local aliases keep protocol details out of the adapter and renderer.
|
|
12
|
+
*/
|
|
13
|
+
import type { InputRichMessage as OfficialInputRichMessage, InlineKeyboardMarkup, Opts } from '@grammyjs/types';
|
|
14
|
+
import type { TelegramErrorParameters } from './api-error.js';
|
|
15
|
+
/** Rich Message content limits (plan §7.2, official 10.2). */
|
|
16
|
+
export declare const RICH_MESSAGE_MAX_UTF8 = 32768;
|
|
17
|
+
export declare const RICH_MESSAGE_MAX_BLOCKS = 500;
|
|
18
|
+
export declare const RICH_MESSAGE_MAX_NESTING = 16;
|
|
19
|
+
export declare const RICH_MESSAGE_MAX_MEDIA = 50;
|
|
20
|
+
export declare const RICH_MESSAGE_MAX_TABLE_COLUMNS = 20;
|
|
21
|
+
/** Regular text message limit after entity parsing (plan §7.1). */
|
|
22
|
+
export declare const REGULAR_MESSAGE_MAX = 4096;
|
|
23
|
+
/** Media caption limit after entity parsing (plan §7.1). */
|
|
24
|
+
export declare const CAPTION_MAX = 1024;
|
|
25
|
+
/** The official rich body for send, draft, and edit methods. */
|
|
26
|
+
export type InputRichMessage = OfficialInputRichMessage<never>;
|
|
27
|
+
export type TelegramInputRichMessage = InputRichMessage;
|
|
28
|
+
export type SendRichMessageParams = Opts<never>['sendRichMessage'];
|
|
29
|
+
export type SendRichMessageDraftParams = Opts<never>['sendRichMessageDraft'];
|
|
30
|
+
export type EditMessageTextParams = Opts<never>['editMessageText'];
|
|
31
|
+
/** Result of `sendRichMessage` / `sendRichMessageDraft`. */
|
|
32
|
+
export interface RichMessageSent {
|
|
33
|
+
messageId: string;
|
|
34
|
+
/** Full Bot API envelope, kept for diagnostics. */
|
|
35
|
+
raw: unknown;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Telegram inline keyboard button. `style` is optional and only meaningful on
|
|
39
|
+
* Bot API 10.2+; every field is validated at the trust boundary in the mapper
|
|
40
|
+
* (untrusted callback_data is never trusted by the adapter).
|
|
41
|
+
*/
|
|
42
|
+
export type TelegramInlineKeyboardButton = InlineKeyboardMarkup['inline_keyboard'][number][number];
|
|
43
|
+
/** Inline keyboard row. */
|
|
44
|
+
export type TelegramInlineKeyboardRow = TelegramInlineKeyboardButton[];
|
|
45
|
+
/** Inline keyboard markup (`reply_markup.inline_keyboard`). */
|
|
46
|
+
export type TelegramInlineKeyboardMarkup = InlineKeyboardMarkup;
|
|
47
|
+
/**
|
|
48
|
+
* The reply_markup value accepted by `sendMessage` / `sendMedia` /
|
|
49
|
+
* `editMessageText` / `answerCallbackQuery`-adjacent sends.
|
|
50
|
+
*/
|
|
51
|
+
export type TelegramReplyMarkup = TelegramInlineKeyboardMarkup | {
|
|
52
|
+
force_reply: boolean;
|
|
53
|
+
input_field_placeholder?: string;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* `answerCallbackQuery` request body. `text`/`show_alert`/`url` are optional;
|
|
57
|
+
* the ACK only needs `callback_query_id` — used as a best-effort, non-blocking
|
|
58
|
+
* acknowledgement (plan §12.2).
|
|
59
|
+
*/
|
|
60
|
+
export interface AnswerCallbackQueryParams {
|
|
61
|
+
callback_query_id: string;
|
|
62
|
+
text?: string;
|
|
63
|
+
show_alert?: boolean;
|
|
64
|
+
url?: string;
|
|
65
|
+
/** Seconds to cache the answer (0–32). */
|
|
66
|
+
cache_time?: number;
|
|
67
|
+
}
|
|
68
|
+
/** Response shape shared by methods that return `true` or an error envelope. */
|
|
69
|
+
export interface TelegramErrorEnvelope {
|
|
70
|
+
ok: boolean;
|
|
71
|
+
error_code?: number;
|
|
72
|
+
description?: string;
|
|
73
|
+
parameters?: TelegramErrorParameters;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=rich-message.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-message.d.ts","sourceRoot":"","sources":["../src/rich-message.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,KAAK,EAAE,gBAAgB,IAAI,wBAAwB,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAChH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAE9D,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,QAAQ,CAAC;AAC3C,eAAO,MAAM,uBAAuB,MAAM,CAAC;AAC3C,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,eAAO,MAAM,8BAA8B,KAAK,CAAC;AAEjD,mEAAmE;AACnE,eAAO,MAAM,mBAAmB,OAAO,CAAC;AACxC,4DAA4D;AAC5D,eAAO,MAAM,WAAW,OAAO,CAAC;AAEhC,gEAAgE;AAChE,MAAM,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,KAAK,CAAC,CAAC;AAC/D,MAAM,MAAM,wBAAwB,GAAG,gBAAgB,CAAC;AACxD,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,CAAC;AACnE,MAAM,MAAM,0BAA0B,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC;AAC7E,MAAM,MAAM,qBAAqB,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAEnE,4DAA4D;AAC5D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,mDAAmD;IACnD,GAAG,EAAE,OAAO,CAAC;CACd;AAED;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG,oBAAoB,CAAC,iBAAiB,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnG,2BAA2B;AAC3B,MAAM,MAAM,yBAAyB,GAAG,4BAA4B,EAAE,CAAC;AAEvE,+DAA+D;AAC/D,MAAM,MAAM,4BAA4B,GAAG,oBAAoB,CAAC;AAEhE;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAC3B,4BAA4B,GAC5B;IAAE,WAAW,EAAE,OAAO,CAAC;IAAC,uBAAuB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D;;;;GAIG;AACH,MAAM,WAAW,yBAAyB;IACxC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,gFAAgF;AAChF,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,OAAO,CAAC;IACZ,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,uBAAuB,CAAC;CACtC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Rich Message content limits (plan §7.2, official 10.2). */
|
|
2
|
+
export const RICH_MESSAGE_MAX_UTF8 = 32768;
|
|
3
|
+
export const RICH_MESSAGE_MAX_BLOCKS = 500;
|
|
4
|
+
export const RICH_MESSAGE_MAX_NESTING = 16;
|
|
5
|
+
export const RICH_MESSAGE_MAX_MEDIA = 50;
|
|
6
|
+
export const RICH_MESSAGE_MAX_TABLE_COLUMNS = 20;
|
|
7
|
+
/** Regular text message limit after entity parsing (plan §7.1). */
|
|
8
|
+
export const REGULAR_MESSAGE_MAX = 4096;
|
|
9
|
+
/** Media caption limit after entity parsing (plan §7.1). */
|
|
10
|
+
export const CAPTION_MAX = 1024;
|
|
11
|
+
//# sourceMappingURL=rich-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rich-message.js","sourceRoot":"","sources":["../src/rich-message.ts"],"names":[],"mappings":"AAeA,8DAA8D;AAC9D,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAC3C,MAAM,CAAC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAC3C,MAAM,CAAC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AACzC,MAAM,CAAC,MAAM,8BAA8B,GAAG,EAAE,CAAC;AAEjD,mEAAmE;AACnE,MAAM,CAAC,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACxC,4DAA4D;AAC5D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC"}
|