@yaebal/rich 0.0.1 → 0.0.2
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 +104 -30
- package/lib/blocks.d.ts +93 -32
- package/lib/blocks.d.ts.map +1 -1
- package/lib/blocks.js +227 -71
- package/lib/blocks.js.map +1 -1
- package/lib/blocks.test.d.ts +2 -0
- package/lib/blocks.test.d.ts.map +1 -0
- package/lib/blocks.test.js +142 -0
- package/lib/blocks.test.js.map +1 -0
- package/lib/document.d.ts +28 -0
- package/lib/document.d.ts.map +1 -0
- package/lib/document.js +46 -0
- package/lib/document.js.map +1 -0
- package/lib/draft.d.ts +46 -9
- package/lib/draft.d.ts.map +1 -1
- package/lib/draft.js +115 -19
- package/lib/draft.js.map +1 -1
- package/lib/draft.test.d.ts +2 -0
- package/lib/draft.test.d.ts.map +1 -0
- package/lib/draft.test.js +122 -0
- package/lib/draft.test.js.map +1 -0
- package/lib/escape.d.ts +8 -0
- package/lib/escape.d.ts.map +1 -1
- package/lib/escape.js +17 -0
- package/lib/escape.js.map +1 -1
- package/lib/escape.test.d.ts +2 -0
- package/lib/escape.test.d.ts.map +1 -0
- package/lib/escape.test.js +28 -0
- package/lib/escape.test.js.map +1 -0
- package/lib/guards.test.d.ts +2 -0
- package/lib/guards.test.d.ts.map +1 -0
- package/lib/guards.test.js +85 -0
- package/lib/guards.test.js.map +1 -0
- package/lib/index.d.ts +18 -9
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +17 -8
- package/lib/index.js.map +1 -1
- package/lib/index.test.js +73 -103
- package/lib/index.test.js.map +1 -1
- package/lib/inline.d.ts +48 -59
- package/lib/inline.d.ts.map +1 -1
- package/lib/inline.js +87 -82
- package/lib/inline.js.map +1 -1
- package/lib/inline.test.d.ts +2 -0
- package/lib/inline.test.d.ts.map +1 -0
- package/lib/inline.test.js +84 -0
- package/lib/inline.test.js.map +1 -0
- package/lib/node.d.ts +25 -0
- package/lib/node.d.ts.map +1 -0
- package/lib/node.js +21 -0
- package/lib/node.js.map +1 -0
- package/lib/plaintext.test.d.ts +2 -0
- package/lib/plaintext.test.d.ts.map +1 -0
- package/lib/plaintext.test.js +100 -0
- package/lib/plaintext.test.js.map +1 -0
- package/lib/render.d.ts +17 -0
- package/lib/render.d.ts.map +1 -0
- package/lib/render.js +30 -0
- package/lib/render.js.map +1 -0
- package/lib/send.d.ts +6 -3
- package/lib/send.d.ts.map +1 -1
- package/lib/send.js +12 -3
- package/lib/send.js.map +1 -1
- package/lib/template.d.ts +46 -0
- package/lib/template.d.ts.map +1 -0
- package/lib/template.js +82 -0
- package/lib/template.js.map +1 -0
- package/lib/template.test.d.ts +2 -0
- package/lib/template.test.d.ts.map +1 -0
- package/lib/template.test.js +78 -0
- package/lib/template.test.js.map +1 -0
- package/package.json +6 -5
- package/src/blocks.test.ts +233 -0
- package/src/blocks.ts +304 -86
- package/src/document.ts +51 -0
- package/src/draft.test.ts +167 -0
- package/src/draft.ts +148 -21
- package/src/escape.test.ts +38 -0
- package/src/escape.ts +20 -0
- package/src/guards.test.ts +138 -0
- package/src/index.test.ts +79 -140
- package/src/index.ts +26 -11
- package/src/inline.test.ts +125 -0
- package/src/inline.ts +131 -97
- package/src/node.ts +43 -0
- package/src/plaintext.test.ts +141 -0
- package/src/render.ts +54 -0
- package/src/send.ts +17 -10
- package/src/template.test.ts +100 -0
- package/src/template.ts +115 -0
- package/lib/message.d.ts +0 -26
- package/lib/message.d.ts.map +0 -1
- package/lib/message.js +0 -31
- package/lib/message.js.map +0 -1
- package/src/message.ts +0 -45
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { isAnchorBlock, isAnchorLink, isAnchorText, isAnimation, isAudio, isBankCardNumber, isBlockquote, isBold, isBotCommand, isCashtag, isCodeText, isCollage, isCustomEmoji, isDateTime, isDetails, isDivider, isEmailAddress, isFooter, isHashtag, isHeading, isItalic, isList, isMap, isMarked, isMathBlock, isMathText, isMentionText, isParagraph, isPhoneNumber, isPhoto, isPreformatted, isPullquote, isReference, isReferenceLink, isSlideshow, isSpoilerText, isStrikethrough, isSubscript, isSuperscript, isTable, isTextMention, isThinking, isUnderline, isUrlText, isVideo, isVoiceNote, } from "./guards.js";
|
|
4
|
+
const BLOCK_GUARDS = [
|
|
5
|
+
["paragraph", isParagraph],
|
|
6
|
+
["heading", isHeading],
|
|
7
|
+
["pre", isPreformatted],
|
|
8
|
+
["footer", isFooter],
|
|
9
|
+
["divider", isDivider],
|
|
10
|
+
["mathematical_expression", isMathBlock],
|
|
11
|
+
["anchor", isAnchorBlock],
|
|
12
|
+
["list", isList],
|
|
13
|
+
["blockquote", isBlockquote],
|
|
14
|
+
["pullquote", isPullquote],
|
|
15
|
+
["collage", isCollage],
|
|
16
|
+
["slideshow", isSlideshow],
|
|
17
|
+
["table", isTable],
|
|
18
|
+
["details", isDetails],
|
|
19
|
+
["map", isMap],
|
|
20
|
+
["animation", isAnimation],
|
|
21
|
+
["audio", isAudio],
|
|
22
|
+
["photo", isPhoto],
|
|
23
|
+
["video", isVideo],
|
|
24
|
+
["voice_note", isVoiceNote],
|
|
25
|
+
["thinking", isThinking],
|
|
26
|
+
];
|
|
27
|
+
const TEXT_GUARDS = [
|
|
28
|
+
["bold", isBold],
|
|
29
|
+
["italic", isItalic],
|
|
30
|
+
["underline", isUnderline],
|
|
31
|
+
["strikethrough", isStrikethrough],
|
|
32
|
+
["spoiler", isSpoilerText],
|
|
33
|
+
["date_time", isDateTime],
|
|
34
|
+
["text_mention", isTextMention],
|
|
35
|
+
["subscript", isSubscript],
|
|
36
|
+
["superscript", isSuperscript],
|
|
37
|
+
["marked", isMarked],
|
|
38
|
+
["code", isCodeText],
|
|
39
|
+
["custom_emoji", isCustomEmoji],
|
|
40
|
+
["mathematical_expression", isMathText],
|
|
41
|
+
["url", isUrlText],
|
|
42
|
+
["email_address", isEmailAddress],
|
|
43
|
+
["phone_number", isPhoneNumber],
|
|
44
|
+
["bank_card_number", isBankCardNumber],
|
|
45
|
+
["mention", isMentionText],
|
|
46
|
+
["hashtag", isHashtag],
|
|
47
|
+
["cashtag", isCashtag],
|
|
48
|
+
["bot_command", isBotCommand],
|
|
49
|
+
["anchor", isAnchorText],
|
|
50
|
+
["anchor_link", isAnchorLink],
|
|
51
|
+
["reference", isReference],
|
|
52
|
+
["reference_link", isReferenceLink],
|
|
53
|
+
];
|
|
54
|
+
test("every RichBlock guard matches its own .type and rejects every other guard's", () => {
|
|
55
|
+
for (const [type, guard] of BLOCK_GUARDS) {
|
|
56
|
+
const block = { type };
|
|
57
|
+
assert.equal(guard(block), true, `${type} guard should match its own type`);
|
|
58
|
+
for (const [otherType, otherGuard] of BLOCK_GUARDS) {
|
|
59
|
+
if (otherType === type)
|
|
60
|
+
continue;
|
|
61
|
+
assert.equal(otherGuard(block), false, `${otherType} guard should reject a "${type}" block`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
test("every RichText guard matches its own .type and rejects every other guard's", () => {
|
|
66
|
+
for (const [type, guard] of TEXT_GUARDS) {
|
|
67
|
+
const text = { type };
|
|
68
|
+
assert.equal(guard(text), true, `${type} guard should match its own type`);
|
|
69
|
+
for (const [otherType, otherGuard] of TEXT_GUARDS) {
|
|
70
|
+
if (otherType === type)
|
|
71
|
+
continue;
|
|
72
|
+
assert.equal(otherGuard(text), false, `${otherType} guard should reject a "${type}" text`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
test("guards narrow RichBlock by .type despite the generated field being `string`", () => {
|
|
77
|
+
const blocks = [
|
|
78
|
+
{ type: "table", cells: [[{ text: "x", align: "left", valign: "top" }]] },
|
|
79
|
+
{ type: "photo", photo: [] },
|
|
80
|
+
];
|
|
81
|
+
assert.equal(isTable(blocks[0]), true);
|
|
82
|
+
assert.equal(isPhoto(blocks[1]), true);
|
|
83
|
+
assert.equal(isTable(blocks[1]), false);
|
|
84
|
+
});
|
|
85
|
+
//# sourceMappingURL=guards.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guards.test.js","sourceRoot":"","sources":["../src/guards.test.ts"],"names":[],"mappings":"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"}
|
package/lib/index.d.ts
CHANGED
|
@@ -6,12 +6,17 @@
|
|
|
6
6
|
* parses it server-side, and you get the same tree back on `message.rich_message`.
|
|
7
7
|
* this package covers all three parts of that surface:
|
|
8
8
|
*
|
|
9
|
-
* - **write**:
|
|
10
|
-
*
|
|
9
|
+
* - **write**: one dual-dialect builder set. every builder (`bold`, `paragraph`,
|
|
10
|
+
* `table`, …) returns a dialect-agnostic `RichNode`; the `html`/`md` template
|
|
11
|
+
* tags (or `document()`) pick the wire dialect once, at the edge, and emit a
|
|
12
|
+
* `RichDocument` — the `rich_message` envelope with fluent `.rtl()` /
|
|
13
|
+
* `.noEntityDetection()` flags. interpolated text is always dialect-escaped,
|
|
14
|
+
* so user input can never inject markup in either dialect.
|
|
11
15
|
* - **stream**: `RichMessageDraft` (draft.ts) owns the fiddly part of
|
|
12
16
|
* `sendRichMessageDraft` — the draft is ephemeral (telegram drops it 30s after
|
|
13
|
-
* the last push) and must be closed with a real `sendRichMessage` or
|
|
14
|
-
*
|
|
17
|
+
* the last push) and must be closed with a real `sendRichMessage` (`send()`) or
|
|
18
|
+
* explicitly `cancel()`led. `rewrite()` replaces the whole draft, `write()`
|
|
19
|
+
* appends to it.
|
|
15
20
|
* - **read**: type guards (guards.ts) and plain-text flattening (plaintext.ts)
|
|
16
21
|
* cover every `RichBlock`/`RichText` variant telegram can hand back.
|
|
17
22
|
*
|
|
@@ -23,11 +28,15 @@
|
|
|
23
28
|
* /bot_command) auto-detected from plain text by telegram itself.
|
|
24
29
|
*/
|
|
25
30
|
export type { InputRichMessage, InputRichMessageContent, RichBlock, RichBlockAnchor, RichBlockAnimation, RichBlockAudio, RichBlockBlockQuotation, RichBlockCaption, RichBlockCollage, RichBlockDetails, RichBlockDivider, RichBlockFooter, RichBlockList, RichBlockListItem, RichBlockMap, RichBlockMathematicalExpression, RichBlockParagraph, RichBlockPhoto, RichBlockPreformatted, RichBlockPullQuotation, RichBlockSectionHeading, RichBlockSlideshow, RichBlockTable, RichBlockTableCell, RichBlockThinking, RichBlockVideo, RichBlockVoiceNote, RichMessage, RichText, RichTextAnchor, RichTextAnchorLink, RichTextBankCardNumber, RichTextBold, RichTextBotCommand, RichTextCashtag, RichTextCode, RichTextCustomEmoji, RichTextDateTime, RichTextEmailAddress, RichTextHashtag, RichTextItalic, RichTextMarked, RichTextMathematicalExpression, RichTextMention, RichTextPhoneNumber, RichTextReference, RichTextReferenceLink, RichTextSpoiler, RichTextStrikethrough, RichTextSubscript, RichTextSuperscript, RichTextTextMention, RichTextUnderline, RichTextUrl, SendRichMessageDraftParams, SendRichMessageParams, } from "@yaebal/types";
|
|
26
|
-
export { anchorBlock, audio, blockquote, type Caption, cell, collage, type DetailsOptions, details, divider, footer, heading, image, item, type ListItemOptions, type ListOptions, list, type MapOptions, type MediaOptions, map, mathBlock, paragraph, preformatted, pullquote, slideshow, type TableCellOptions, type TableOptions, table, thinking, video, } from "./blocks.js";
|
|
31
|
+
export { anchorBlock, audio, blockquote, type Caption, cell, collage, type DetailsOptions, details, divider, footer, h1, h2, h3, h4, h5, h6, heading, image, item, join, type ListItem, type ListItemOptions, type ListOptions, list, type MapOptions, type MediaOptions, map, mathBlock, paragraph, preformatted, pullquote, slideshow, type TableCell, type TableCellOptions, type TableOptions, table, thinking, video, } from "./blocks.js";
|
|
32
|
+
export { RichDocument } from "./document.js";
|
|
27
33
|
export { RichMessageDraft, type RichMessageDraftOptions } from "./draft.js";
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
30
|
-
export {
|
|
34
|
+
export { escapeMarkdown, escapeMarkdownUrl } from "./escape.js";
|
|
35
|
+
export { isAnchorBlock, isAnchorLink, isAnchorText, isAnimation, isAudio, isBankCardNumber, isBlockquote, isBold, isBotCommand, isCashtag, isCodeText, isCollage, isCustomEmoji, isDateTime, isDetails, isDivider, isEmailAddress, isFooter, isHashtag, isHeading, isItalic, isList, isMap, isMarked, isMathBlock, isMathText, isMentionText, isParagraph, isPhoneNumber, isPhoto, isPreformatted, isPullquote, isReference, isReferenceLink, isSlideshow, isSpoilerText, isStrikethrough, isSubscript, isSuperscript, isTable, isTextMention, isThinking, isUnderline, isUrlText, isVideo, isVoiceNote, } from "./guards.js";
|
|
36
|
+
export { anchor, anchorLink, bold, br, code, customEmoji, dateTime, italic, link, marked, math, reference, referenceLink, spoiler, strikethrough, subscript, superscript, textMention, underline, } from "./inline.js";
|
|
37
|
+
export { type Dialect, isRichNode, type Level, RichError, type RichNode } from "./node.js";
|
|
31
38
|
export { richBlockToPlainText, richMessageToPlainText, richTextToPlainText } from "./plaintext.js";
|
|
32
|
-
export {
|
|
39
|
+
export { escapeFor, type Insertable, render } from "./render.js";
|
|
40
|
+
export { type RichContext, type RichSource, rich, sendRichMessage, sendRichMessageDraft, } from "./send.js";
|
|
41
|
+
export { type DocumentOptions, document, html, md, type RichTemplate } from "./template.js";
|
|
33
42
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAIH,YAAY,EACX,gBAAgB,EAChB,uBAAuB,EACvB,SAAS,EACT,eAAe,EACf,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,aAAa,EACb,iBAAiB,EACjB,YAAY,EACZ,+BAA+B,EAC/B,kBAAkB,EAClB,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,QAAQ,EACR,cAAc,EACd,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,gBAAgB,EAChB,oBAAoB,EACpB,eAAe,EACf,cAAc,EACd,cAAc,EACd,8BAA8B,EAC9B,eAAe,EACf,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,qBAAqB,EACrB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,WAAW,EACX,0BAA0B,EAC1B,qBAAqB,GACrB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACN,WAAW,EACX,KAAK,EACL,UAAU,EACV,KAAK,OAAO,EACZ,IAAI,EACJ,OAAO,EACP,KAAK,cAAc,EACnB,OAAO,EACP,OAAO,EACP,MAAM,EACN,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,OAAO,EACP,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,IAAI,EACJ,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,GAAG,EACH,SAAS,EACT,SAAS,EACT,YAAY,EACZ,SAAS,EACT,SAAS,EACT,KAAK,SAAS,EACd,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,EACL,QAAQ,EACR,KAAK,GACL,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,aAAa,EACb,UAAU,EACV,SAAS,EACT,SAAS,EACT,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,KAAK,EACL,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,OAAO,EACP,cAAc,EACd,WAAW,EACX,WAAW,EACX,eAAe,EACf,WAAW,EACX,aAAa,EACb,eAAe,EACf,WAAW,EACX,aAAa,EACb,OAAO,EACP,aAAa,EACb,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,WAAW,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,MAAM,EACN,UAAU,EACV,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,SAAS,EACT,aAAa,EACb,OAAO,EACP,aAAa,EACb,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,KAAK,OAAO,EAAE,UAAU,EAAE,KAAK,KAAK,EAAE,SAAS,EAAE,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACnG,OAAO,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,IAAI,EACJ,eAAe,EACf,oBAAoB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,eAAe,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -6,12 +6,17 @@
|
|
|
6
6
|
* parses it server-side, and you get the same tree back on `message.rich_message`.
|
|
7
7
|
* this package covers all three parts of that surface:
|
|
8
8
|
*
|
|
9
|
-
* - **write**:
|
|
10
|
-
*
|
|
9
|
+
* - **write**: one dual-dialect builder set. every builder (`bold`, `paragraph`,
|
|
10
|
+
* `table`, …) returns a dialect-agnostic `RichNode`; the `html`/`md` template
|
|
11
|
+
* tags (or `document()`) pick the wire dialect once, at the edge, and emit a
|
|
12
|
+
* `RichDocument` — the `rich_message` envelope with fluent `.rtl()` /
|
|
13
|
+
* `.noEntityDetection()` flags. interpolated text is always dialect-escaped,
|
|
14
|
+
* so user input can never inject markup in either dialect.
|
|
11
15
|
* - **stream**: `RichMessageDraft` (draft.ts) owns the fiddly part of
|
|
12
16
|
* `sendRichMessageDraft` — the draft is ephemeral (telegram drops it 30s after
|
|
13
|
-
* the last push) and must be closed with a real `sendRichMessage` or
|
|
14
|
-
*
|
|
17
|
+
* the last push) and must be closed with a real `sendRichMessage` (`send()`) or
|
|
18
|
+
* explicitly `cancel()`led. `rewrite()` replaces the whole draft, `write()`
|
|
19
|
+
* appends to it.
|
|
15
20
|
* - **read**: type guards (guards.ts) and plain-text flattening (plaintext.ts)
|
|
16
21
|
* cover every `RichBlock`/`RichText` variant telegram can hand back.
|
|
17
22
|
*
|
|
@@ -22,11 +27,15 @@
|
|
|
22
27
|
* documented tag or (for url/email/phone/bank-card/@mention/#hashtag/$cashtag/
|
|
23
28
|
* /bot_command) auto-detected from plain text by telegram itself.
|
|
24
29
|
*/
|
|
25
|
-
export { anchorBlock, audio, blockquote, cell, collage, details, divider, footer, heading, image, item, list, map, mathBlock, paragraph, preformatted, pullquote, slideshow, table, thinking, video, } from "./blocks.js";
|
|
30
|
+
export { anchorBlock, audio, blockquote, cell, collage, details, divider, footer, h1, h2, h3, h4, h5, h6, heading, image, item, join, list, map, mathBlock, paragraph, preformatted, pullquote, slideshow, table, thinking, video, } from "./blocks.js";
|
|
31
|
+
export { RichDocument } from "./document.js";
|
|
26
32
|
export { RichMessageDraft } from "./draft.js";
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
33
|
+
export { escapeMarkdown, escapeMarkdownUrl } from "./escape.js";
|
|
34
|
+
export { isAnchorBlock, isAnchorLink, isAnchorText, isAnimation, isAudio, isBankCardNumber, isBlockquote, isBold, isBotCommand, isCashtag, isCodeText, isCollage, isCustomEmoji, isDateTime, isDetails, isDivider, isEmailAddress, isFooter, isHashtag, isHeading, isItalic, isList, isMap, isMarked, isMathBlock, isMathText, isMentionText, isParagraph, isPhoneNumber, isPhoto, isPreformatted, isPullquote, isReference, isReferenceLink, isSlideshow, isSpoilerText, isStrikethrough, isSubscript, isSuperscript, isTable, isTextMention, isThinking, isUnderline, isUrlText, isVideo, isVoiceNote, } from "./guards.js";
|
|
35
|
+
export { anchor, anchorLink, bold, br, code, customEmoji, dateTime, italic, link, marked, math, reference, referenceLink, spoiler, strikethrough, subscript, superscript, textMention, underline, } from "./inline.js";
|
|
36
|
+
export { isRichNode, RichError } from "./node.js";
|
|
30
37
|
export { richBlockToPlainText, richMessageToPlainText, richTextToPlainText } from "./plaintext.js";
|
|
38
|
+
export { escapeFor, render } from "./render.js";
|
|
31
39
|
export { rich, sendRichMessage, sendRichMessageDraft, } from "./send.js";
|
|
40
|
+
export { document, html, md } from "./template.js";
|
|
32
41
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AA+DH,OAAO,EACN,WAAW,EACX,KAAK,EACL,UAAU,EAEV,IAAI,EACJ,OAAO,EAEP,OAAO,EACP,OAAO,EACP,MAAM,EACN,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,EAAE,EACF,OAAO,EACP,KAAK,EACL,IAAI,EACJ,IAAI,EAIJ,IAAI,EAGJ,GAAG,EACH,SAAS,EACT,SAAS,EACT,YAAY,EACZ,SAAS,EACT,SAAS,EAIT,KAAK,EACL,QAAQ,EACR,KAAK,GACL,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,gBAAgB,EAAgC,MAAM,YAAY,CAAC;AAC5E,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAChE,OAAO,EACN,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,OAAO,EACP,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,YAAY,EACZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,aAAa,EACb,UAAU,EACV,SAAS,EACT,SAAS,EACT,cAAc,EACd,QAAQ,EACR,SAAS,EACT,SAAS,EACT,QAAQ,EACR,MAAM,EACN,KAAK,EACL,QAAQ,EACR,WAAW,EACX,UAAU,EACV,aAAa,EACb,WAAW,EACX,aAAa,EACb,OAAO,EACP,cAAc,EACd,WAAW,EACX,WAAW,EACX,eAAe,EACf,WAAW,EACX,aAAa,EACb,eAAe,EACf,WAAW,EACX,aAAa,EACb,OAAO,EACP,aAAa,EACb,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,WAAW,GACX,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,MAAM,EACN,UAAU,EACV,IAAI,EACJ,EAAE,EACF,IAAI,EACJ,WAAW,EACX,QAAQ,EACR,MAAM,EACN,IAAI,EACJ,MAAM,EACN,IAAI,EACJ,SAAS,EACT,aAAa,EACb,OAAO,EACP,aAAa,EACb,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,GACT,MAAM,aAAa,CAAC;AACrB,OAAO,EAAgB,UAAU,EAAc,SAAS,EAAiB,MAAM,WAAW,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACnG,OAAO,EAAE,SAAS,EAAmB,MAAM,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAGN,IAAI,EACJ,eAAe,EACf,oBAAoB,GACpB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAwB,QAAQ,EAAE,IAAI,EAAE,EAAE,EAAqB,MAAM,eAAe,CAAC"}
|
package/lib/index.test.js
CHANGED
|
@@ -1,72 +1,44 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import test from "node:test";
|
|
3
3
|
import { Composer, Context } from "@yaebal/core";
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
return {};
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
test("html template escapes interpolations and splices RichNode subs", () => {
|
|
16
|
-
const node = html `<p>hi ${"<b>hax</b>"} — ${bold("safe")}</p>`;
|
|
17
|
-
assert.equal(node.html, "<p>hi <b>hax</b> — <b>safe</b></p>");
|
|
18
|
-
});
|
|
19
|
-
test("inline builders emit the documented tags", () => {
|
|
20
|
-
assert.equal(bold("x").html, "<b>x</b>");
|
|
21
|
-
assert.equal(link("https://yaeb.al", "docs").html, '<a href="https://yaeb.al">docs</a>');
|
|
22
|
-
});
|
|
23
|
-
test("block builders compose into a document", () => {
|
|
24
|
-
const input = document([
|
|
25
|
-
heading(1, "title"),
|
|
26
|
-
paragraph("hello ", bold("world")),
|
|
27
|
-
list([item(["a"]), item(["b"], { checkbox: true, checked: true })]),
|
|
28
|
-
details("more", [paragraph("hidden")], { open: false }),
|
|
29
|
-
]);
|
|
30
|
-
assert.equal(input.html, "<h1>title</h1>" +
|
|
31
|
-
"<p>hello <b>world</b></p>" +
|
|
32
|
-
'<ul><li>a</li><li><input type="checkbox" checked/> b</li></ul>' +
|
|
33
|
-
"<details><summary>more</summary><p>hidden</p></details>");
|
|
34
|
-
});
|
|
35
|
-
test("table() and cell() render alignment attributes telegram's schema documents", () => {
|
|
36
|
-
const node = table([
|
|
37
|
-
[cell("a", { header: true, align: "center" }), cell("b", { valign: "middle" })],
|
|
38
|
-
]);
|
|
39
|
-
assert.equal(node.html, '<table><tr><th align="center">a</th><td valign="middle">b</td></tr></table>');
|
|
40
|
-
});
|
|
41
|
-
test("image() wraps caption/credit in figure/figcaption/cite", () => {
|
|
42
|
-
const node = image("https://example.com/x.jpg", { caption: "a cat", credit: "photographer" });
|
|
43
|
-
assert.equal(node.html, '<figure><img src="https://example.com/x.jpg"></img><figcaption>a cat<cite>photographer</cite></figcaption></figure>');
|
|
44
|
-
});
|
|
45
|
-
test("thinking() is exposed for draft-only use", () => {
|
|
46
|
-
assert.equal(thinking("…").html, "<tg-thinking>…</tg-thinking>");
|
|
47
|
-
});
|
|
4
|
+
import { mockApi } from "@yaebal/test";
|
|
5
|
+
import { bold, document, md, paragraph, RichMessageDraft, rich, sendRichMessage, sendRichMessageDraft, } from "./index.js";
|
|
6
|
+
// integration-level coverage for the parts that tie the package together: the raw
|
|
7
|
+
// send/draft functions, and the `rich()` plugin's ctx decoration. per-builder output
|
|
8
|
+
// (blocks.test.ts/inline.test.ts/markdown.test.ts), guards (guards.test.ts),
|
|
9
|
+
// plaintext flattening (plaintext.test.ts), and RichMessageDraft's rewrite/write/send
|
|
10
|
+
// state machine (draft.test.ts) all have their own dedicated test files.
|
|
48
11
|
test("sendRichMessage posts chat_id + rich_message to the raw api", async () => {
|
|
49
|
-
const api = mockApi();
|
|
12
|
+
const { api, calls } = mockApi();
|
|
50
13
|
await sendRichMessage(api, 42, document([paragraph("hi")]), { reply_markup: { x: 1 } });
|
|
51
|
-
assert.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
14
|
+
assert.equal(calls[0]?.method, "sendRichMessage");
|
|
15
|
+
assert.deepEqual(calls[0]?.params, {
|
|
16
|
+
chat_id: 42,
|
|
17
|
+
rich_message: { html: "<p>hi</p>" },
|
|
18
|
+
reply_markup: { x: 1 },
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
test("sendRichMessage unwraps a markdown RichDocument with its fluent flags", async () => {
|
|
22
|
+
const { api, calls } = mockApi();
|
|
23
|
+
await sendRichMessage(api, 42, md `# hi ${bold("there")}`.rtl());
|
|
24
|
+
assert.equal(calls[0]?.method, "sendRichMessage");
|
|
25
|
+
assert.deepEqual(calls[0]?.params, {
|
|
26
|
+
chat_id: 42,
|
|
27
|
+
rich_message: { markdown: "# hi **there**", is_rtl: true },
|
|
28
|
+
});
|
|
57
29
|
});
|
|
58
30
|
test("sendRichMessageDraft posts draft_id alongside chat_id + rich_message", async () => {
|
|
59
|
-
const api = mockApi();
|
|
31
|
+
const { api, calls } = mockApi();
|
|
60
32
|
await sendRichMessageDraft(api, 42, 7, "<tg-thinking>…</tg-thinking>");
|
|
61
|
-
assert.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
33
|
+
assert.equal(calls[0]?.method, "sendRichMessageDraft");
|
|
34
|
+
assert.deepEqual(calls[0]?.params, {
|
|
35
|
+
chat_id: 42,
|
|
36
|
+
draft_id: 7,
|
|
37
|
+
rich_message: { html: "<tg-thinking>…</tg-thinking>" },
|
|
38
|
+
});
|
|
67
39
|
});
|
|
68
|
-
test("rich() plugin decorates ctx.sendRichMessage bound to the current chat", async () => {
|
|
69
|
-
const api = mockApi();
|
|
40
|
+
test("rich() plugin decorates ctx.sendRichMessage/ctx.richMessageDraft bound to the current chat", async () => {
|
|
41
|
+
const { api, calls } = mockApi();
|
|
70
42
|
const composer = new Composer().install(rich());
|
|
71
43
|
const ctx = new Context({
|
|
72
44
|
api,
|
|
@@ -79,52 +51,50 @@ test("rich() plugin decorates ctx.sendRichMessage bound to the current chat", as
|
|
|
79
51
|
await composer.toMiddleware()(ctx, async () => { });
|
|
80
52
|
const decorated = ctx;
|
|
81
53
|
await decorated.sendRichMessage(document([paragraph("hi")]));
|
|
82
|
-
assert.
|
|
83
|
-
|
|
84
|
-
{ chat_id: 5, rich_message: { html: "<p>hi</p>" } },
|
|
85
|
-
]);
|
|
54
|
+
assert.equal(calls[0]?.method, "sendRichMessage");
|
|
55
|
+
assert.deepEqual(calls[0]?.params, { chat_id: 5, rich_message: { html: "<p>hi</p>" } });
|
|
86
56
|
const draft = decorated.richMessageDraft(1);
|
|
87
57
|
assert.ok(draft instanceof RichMessageDraft);
|
|
88
58
|
});
|
|
89
|
-
test("
|
|
90
|
-
const api = mockApi();
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
await draft.push("draft text");
|
|
103
|
-
draft.cancel();
|
|
104
|
-
assert.equal(draft.closed, true);
|
|
105
|
-
assert.equal(api.calls.some(([method]) => method === "sendRichMessage"), false);
|
|
106
|
-
});
|
|
107
|
-
test("guards narrow RichBlock by .type despite the generated field being `string`", () => {
|
|
108
|
-
const blocks = [
|
|
109
|
-
{ type: "table", cells: [[{ text: "x", align: "left", valign: "top" }]] },
|
|
110
|
-
{ type: "photo", photo: [] },
|
|
111
|
-
];
|
|
112
|
-
assert.equal(isTable(blocks[0]), true);
|
|
113
|
-
assert.equal(isPhoto(blocks[1]), true);
|
|
114
|
-
assert.equal(isTable(blocks[1]), false);
|
|
115
|
-
});
|
|
116
|
-
test("richMessageToPlainText flattens a full block tree", () => {
|
|
117
|
-
const message = {
|
|
118
|
-
blocks: [
|
|
119
|
-
{ type: "heading", text: "title", size: 1 },
|
|
120
|
-
{ type: "paragraph", text: [{ type: "bold", text: "hi" }, " there"] },
|
|
121
|
-
{ type: "divider" },
|
|
122
|
-
{
|
|
123
|
-
type: "list",
|
|
124
|
-
items: [{ label: "1", blocks: [{ type: "paragraph", text: "one" }] }],
|
|
59
|
+
test("rich() plugin routes ctx.sendRichMessage through the business connection/topic", async () => {
|
|
60
|
+
const { api, calls } = mockApi();
|
|
61
|
+
const composer = new Composer().install(rich());
|
|
62
|
+
const ctx = new Context({
|
|
63
|
+
api,
|
|
64
|
+
update: {
|
|
65
|
+
update_id: 1,
|
|
66
|
+
business_message: {
|
|
67
|
+
message_id: 1,
|
|
68
|
+
date: 0,
|
|
69
|
+
chat: { id: 5, type: "private" },
|
|
70
|
+
business_connection_id: "bc1",
|
|
71
|
+
message_thread_id: 9,
|
|
125
72
|
},
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
73
|
+
},
|
|
74
|
+
updateType: "business_message",
|
|
75
|
+
});
|
|
76
|
+
await composer.toMiddleware()(ctx, async () => { });
|
|
77
|
+
const decorated = ctx;
|
|
78
|
+
await decorated.sendRichMessage(document([paragraph("hi")]));
|
|
79
|
+
assert.equal(calls[0]?.method, "sendRichMessage");
|
|
80
|
+
assert.deepEqual(calls[0]?.params, {
|
|
81
|
+
chat_id: 5,
|
|
82
|
+
rich_message: { html: "<p>hi</p>" },
|
|
83
|
+
business_connection_id: "bc1",
|
|
84
|
+
message_thread_id: 9,
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
test("sendRichMessage()/richMessageDraft() reject when the update has no chat", async () => {
|
|
88
|
+
const { api } = mockApi();
|
|
89
|
+
const composer = new Composer().install(rich());
|
|
90
|
+
const ctx = new Context({
|
|
91
|
+
api,
|
|
92
|
+
update: { update_id: 1 },
|
|
93
|
+
updateType: "message",
|
|
94
|
+
});
|
|
95
|
+
await composer.toMiddleware()(ctx, async () => { });
|
|
96
|
+
const decorated = ctx;
|
|
97
|
+
await assert.rejects(() => decorated.sendRichMessage("x"), /no chat in this update/);
|
|
98
|
+
assert.throws(() => decorated.richMessageDraft(1), /no chat in this update/);
|
|
129
99
|
});
|
|
130
100
|
//# sourceMappingURL=index.test.js.map
|
package/lib/index.test.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}
|
package/lib/inline.d.ts
CHANGED
|
@@ -1,79 +1,68 @@
|
|
|
1
1
|
import type { User } from "@yaebal/core";
|
|
2
|
+
import { type RichNode } from "./node.js";
|
|
3
|
+
import { type Insertable } from "./render.js";
|
|
4
|
+
/** `RichTextBold` — `<b>` / `**x**`. */
|
|
5
|
+
export declare const bold: (...items: Insertable[]) => RichNode;
|
|
6
|
+
/** `RichTextItalic` — `<i>` / `*x*`. */
|
|
7
|
+
export declare const italic: (...items: Insertable[]) => RichNode;
|
|
8
|
+
/** `RichTextUnderline` — `<u>`; no markdown token, the raw tag is embedded there too. */
|
|
9
|
+
export declare const underline: (...items: Insertable[]) => RichNode;
|
|
10
|
+
/** `RichTextStrikethrough` — `<s>` / `~~x~~`. */
|
|
11
|
+
export declare const strikethrough: (...items: Insertable[]) => RichNode;
|
|
12
|
+
/** `RichTextSpoiler` — `<tg-spoiler>` / `||x||`. */
|
|
13
|
+
export declare const spoiler: (...items: Insertable[]) => RichNode;
|
|
14
|
+
/** `RichTextCode` — `<code>` / `` `x` ``. */
|
|
15
|
+
export declare const code: (...items: Insertable[]) => RichNode;
|
|
16
|
+
/** line break — hard newline in markdown, `<br/>` in html. */
|
|
17
|
+
export declare function br(): RichNode;
|
|
2
18
|
/**
|
|
3
|
-
*
|
|
4
|
-
* `
|
|
5
|
-
* `
|
|
6
|
-
*
|
|
7
|
-
*/
|
|
8
|
-
export interface RichNode {
|
|
9
|
-
readonly html: string;
|
|
10
|
-
}
|
|
11
|
-
export type Insertable = RichNode | string | number | bigint | boolean | null | undefined;
|
|
12
|
-
export declare function isRichNode(value: unknown): value is RichNode;
|
|
13
|
-
/** render one interpolation: a `RichNode` is spliced raw, anything else is escaped text. */
|
|
14
|
-
export declare function toHtml(value: Insertable): string;
|
|
15
|
-
/**
|
|
16
|
-
* an extended-html template: interpolations are auto-escaped (never re-parsed as
|
|
17
|
-
* markup), and a nested `RichNode` (from these builders, or another `html`
|
|
18
|
-
* template) is spliced in raw. mirrors `@yaebal/fmt`'s `html` tag, but for the
|
|
19
|
-
* rich-message dialect instead of the classic entity one.
|
|
20
|
-
*/
|
|
21
|
-
export declare function html(strings: TemplateStringsArray, ...subs: Insertable[]): RichNode;
|
|
22
|
-
/** `RichTextBold`, `<b>`. */
|
|
23
|
-
export declare const bold: (...children: Insertable[]) => RichNode;
|
|
24
|
-
/** `RichTextItalic`, `<i>`. */
|
|
25
|
-
export declare const italic: (...children: Insertable[]) => RichNode;
|
|
26
|
-
/** `RichTextUnderline`, `<u>`. */
|
|
27
|
-
export declare const underline: (...children: Insertable[]) => RichNode;
|
|
28
|
-
/** `RichTextStrikethrough`, `<s>`. */
|
|
29
|
-
export declare const strikethrough: (...children: Insertable[]) => RichNode;
|
|
30
|
-
/** `RichTextSpoiler`, `<tg-spoiler>`. */
|
|
31
|
-
export declare const spoiler: (...children: Insertable[]) => RichNode;
|
|
32
|
-
/** `RichTextCode`, `<code>`. */
|
|
33
|
-
export declare const code: (...children: Insertable[]) => RichNode;
|
|
34
|
-
/**
|
|
35
|
-
* `RichTextCustomEmoji`, `<tg-emoji emoji-id="…">`. same custom tag classic
|
|
36
|
-
* `parse_mode: "HTML"` uses for custom emoji — telegram documents it as reused
|
|
37
|
-
* verbatim here. `fallback` is the plain emoji shown where custom emoji can't render.
|
|
19
|
+
* `RichTextCustomEmoji` — `<tg-emoji emoji-id="…">`, the same custom tag classic
|
|
20
|
+
* `parse_mode: "HTML"` uses (telegram documents it as reused verbatim here);
|
|
21
|
+
* best-effort `` in markdown. `fallback` is the
|
|
22
|
+
* plain emoji shown where custom emoji can't render.
|
|
38
23
|
*/
|
|
39
24
|
export declare function customEmoji(emojiId: string, fallback: string): RichNode;
|
|
25
|
+
/** `RichTextUrl`, an explicit link. for a bare auto-linked url, just write it as plain text. */
|
|
26
|
+
export declare function link(url: string, ...items: Insertable[]): RichNode;
|
|
40
27
|
/**
|
|
41
|
-
* `RichTextTextMention`, a mention of a user who may have no `@username` —
|
|
42
|
-
* `tg://user?id=…` link telegram's classic
|
|
28
|
+
* `RichTextTextMention`, a mention of a user who may have no `@username` — the
|
|
29
|
+
* same `tg://user?id=…` link telegram's classic dialects use for `text_mention`.
|
|
43
30
|
* for `@username` mentions (`RichTextMention`), just write `@username` as plain
|
|
44
|
-
* text — the schema lists it as auto-detected (see `
|
|
31
|
+
* text — the schema lists it as auto-detected (see `noEntityDetection`).
|
|
45
32
|
*/
|
|
46
|
-
export declare function textMention(user: Pick<User, "id">, ...
|
|
47
|
-
/** `
|
|
48
|
-
export declare function link(url: string, ...children: Insertable[]): RichNode;
|
|
49
|
-
/** `RichTextAnchor` (inline form) — a named jump target, `<a name="…">`. */
|
|
33
|
+
export declare function textMention(user: Pick<User, "id">, ...items: Insertable[]): RichNode;
|
|
34
|
+
/** `RichTextAnchor` (inline form) — a named jump target, `<a name="…">` in both dialects. */
|
|
50
35
|
export declare function anchor(name: string): RichNode;
|
|
51
36
|
/**
|
|
52
37
|
* `RichTextAnchorLink`, a link to an `anchor()` elsewhere in the message —
|
|
53
|
-
* `<a href="#name"
|
|
38
|
+
* `<a href="#name">` / `[text](#name)`. an empty `name` jumps back to the top
|
|
39
|
+
* (per the schema).
|
|
54
40
|
*/
|
|
55
|
-
export declare function anchorLink(name: string, ...
|
|
56
|
-
/** `RichTextMarked`, best-effort `<mark>`
|
|
57
|
-
export declare const marked: (...
|
|
58
|
-
/** `RichTextSubscript
|
|
59
|
-
export declare const subscript: (...
|
|
60
|
-
/** `RichTextSuperscript
|
|
61
|
-
export declare const superscript: (...
|
|
41
|
+
export declare function anchorLink(name: string, ...items: Insertable[]): RichNode;
|
|
42
|
+
/** `RichTextMarked`, highlighted text — best-effort `<mark>` / `==x==`. */
|
|
43
|
+
export declare const marked: (...items: Insertable[]) => RichNode;
|
|
44
|
+
/** `RichTextSubscript` — best-effort `<sub>`; no markdown token, raw tag embedded there too. */
|
|
45
|
+
export declare const subscript: (...items: Insertable[]) => RichNode;
|
|
46
|
+
/** `RichTextSuperscript` — best-effort `<sup>`; no markdown token, raw tag embedded there too. */
|
|
47
|
+
export declare const superscript: (...items: Insertable[]) => RichNode;
|
|
62
48
|
/**
|
|
63
|
-
* `RichTextMathematicalExpression` (inline)
|
|
64
|
-
* form is confirmed as `<tg-math-block>` — see `mathBlock` in
|
|
49
|
+
* `RichTextMathematicalExpression` (inline) — best-effort `<tg-math>` / `$x$`
|
|
50
|
+
* (the block form is confirmed as `<tg-math-block>` — see `mathBlock` in
|
|
51
|
+
* blocks.ts). `expression` is raw LaTeX — not markdown-escaped.
|
|
65
52
|
*/
|
|
66
53
|
export declare function math(expression: string): RichNode;
|
|
67
54
|
/**
|
|
68
|
-
* `RichTextDateTime`, best-effort `<time
|
|
69
|
-
*
|
|
55
|
+
* `RichTextDateTime`, auto-formatted date-time — best-effort `<time>` (attribute
|
|
56
|
+
* name `data-format` is a guess) / ``.
|
|
57
|
+
* `format` is telegram's date-time entity format string.
|
|
70
58
|
*/
|
|
71
|
-
export declare function dateTime(unixTime: number, format: string, ...
|
|
59
|
+
export declare function dateTime(unixTime: number, format: string, ...items: Insertable[]): RichNode;
|
|
72
60
|
/**
|
|
73
61
|
* `RichTextReference`, a footnote definition. no tag is documented anywhere in
|
|
74
|
-
* the scraped schema —
|
|
62
|
+
* the scraped schema — `<tg-reference>` is a from-scratch `tg-*`-style guess,
|
|
63
|
+
* `[^name]: …` the standard markdown footnote line (place it at line start).
|
|
75
64
|
*/
|
|
76
|
-
export declare function reference(name: string, ...
|
|
77
|
-
/** `RichTextReferenceLink`, a link to a `reference()
|
|
78
|
-
export declare function referenceLink(name: string, ...
|
|
65
|
+
export declare function reference(name: string, ...items: Insertable[]): RichNode;
|
|
66
|
+
/** `RichTextReferenceLink`, a link to a `reference()` — same caveat as `reference`. */
|
|
67
|
+
export declare function referenceLink(name: string, ...items: Insertable[]): RichNode;
|
|
79
68
|
//# sourceMappingURL=inline.d.ts.map
|
package/lib/inline.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../src/inline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAA0B,KAAK,QAAQ,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAa,KAAK,UAAU,EAAU,MAAM,aAAa,CAAC;AAkBjE,wCAAwC;AACxC,eAAO,MAAM,IAAI,aAPE,UAAU,EAAE,KAAG,QAUjC,CAAC;AACF,wCAAwC;AACxC,eAAO,MAAM,MAAM,aAZA,UAAU,EAAE,KAAG,QAejC,CAAC;AACF,yFAAyF;AACzF,eAAO,MAAM,SAAS,aAjBH,UAAU,EAAE,KAAG,QAoBjC,CAAC;AACF,iDAAiD;AACjD,eAAO,MAAM,aAAa,aAtBP,UAAU,EAAE,KAAG,QAyBjC,CAAC;AACF,oDAAoD;AACpD,eAAO,MAAM,OAAO,aA3BD,UAAU,EAAE,KAAG,QA8BjC,CAAC;AACF,6CAA6C;AAC7C,eAAO,MAAM,IAAI,aAhCE,UAAU,EAAE,KAAG,QAmCjC,CAAC;AAEF,8DAA8D;AAC9D,wBAAgB,EAAE,IAAI,QAAQ,CAE7B;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAMvE;AAQD,gGAAgG;AAChG,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,QAAQ,CAMlE;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,QAAQ,CAEpF;AAED,6FAA6F;AAC7F,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAE7C;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,QAAQ,CAMzE;AAWD,2EAA2E;AAC3E,eAAO,MAAM,MAAM,aA7GA,UAAU,EAAE,KAAG,QAgHjC,CAAC;AACF,gGAAgG;AAChG,eAAO,MAAM,SAAS,aAlHH,UAAU,EAAE,KAAG,QAqHjC,CAAC;AACF,kGAAkG;AAClG,eAAO,MAAM,WAAW,aAvHL,UAAU,EAAE,KAAG,QA0HjC,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,QAAQ,CAIjD;AAED;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,QAAQ,CAQ3F;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,QAAQ,CAMxE;AAED,uFAAuF;AACvF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,KAAK,EAAE,UAAU,EAAE,GAAG,QAAQ,CAM5E"}
|