@mtcute/core 0.30.0 → 0.30.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/client.cjs +8 -0
- package/client.js +8 -0
- package/highlevel/client.d.cts +63 -1
- package/highlevel/client.d.ts +63 -1
- package/highlevel/methods/files/normalize-input-media.cjs +8 -0
- package/highlevel/methods/files/normalize-input-media.js +9 -1
- package/highlevel/methods/messages/create-rich-streaming-draft.cjs +39 -0
- package/highlevel/methods/messages/create-rich-streaming-draft.d.cts +42 -0
- package/highlevel/methods/messages/create-rich-streaming-draft.d.ts +42 -0
- package/highlevel/methods/messages/create-rich-streaming-draft.js +34 -0
- package/highlevel/methods/messages/normalize-rich-message.cjs +157 -0
- package/highlevel/methods/messages/normalize-rich-message.d.cts +10 -0
- package/highlevel/methods/messages/normalize-rich-message.d.ts +10 -0
- package/highlevel/methods/messages/normalize-rich-message.js +152 -0
- package/highlevel/methods/messages/send-rich-message.cjs +49 -0
- package/highlevel/methods/messages/send-rich-message.d.cts +38 -0
- package/highlevel/methods/messages/send-rich-message.d.ts +38 -0
- package/highlevel/methods/messages/send-rich-message.js +44 -0
- package/highlevel/methods.d.cts +3 -0
- package/highlevel/methods.d.ts +3 -0
- package/highlevel/types/bots/inline-message/factories.cjs +14 -0
- package/highlevel/types/bots/inline-message/factories.d.cts +9 -1
- package/highlevel/types/bots/inline-message/factories.d.ts +9 -1
- package/highlevel/types/bots/inline-message/factories.js +14 -0
- package/highlevel/types/bots/inline-message/types.d.cts +17 -1
- package/highlevel/types/bots/inline-message/types.d.ts +17 -1
- package/highlevel/types/media/input-media/types.d.cts +1 -1
- package/highlevel/types/media/input-media/types.d.ts +1 -1
- package/highlevel/types/messages/index.d.cts +1 -1
- package/highlevel/types/messages/index.d.ts +1 -1
- package/highlevel/types/messages/message.cjs +1 -1
- package/highlevel/types/messages/message.d.cts +1 -1
- package/highlevel/types/messages/message.d.ts +1 -1
- package/highlevel/types/messages/message.js +1 -1
- package/highlevel/types/messages/rich/index.d.cts +4 -0
- package/highlevel/types/messages/rich/index.d.ts +4 -0
- package/highlevel/types/messages/rich/inner.cjs +219 -0
- package/highlevel/types/messages/rich/inner.d.cts +127 -0
- package/highlevel/types/messages/rich/inner.d.ts +127 -0
- package/highlevel/types/messages/rich/inner.js +214 -0
- package/highlevel/types/messages/{rich-message.cjs → rich/rich-message.cjs} +6 -6
- package/highlevel/types/messages/{rich-message.d.cts → rich/rich-message.d.cts} +5 -5
- package/highlevel/types/messages/{rich-message.d.ts → rich/rich-message.d.ts} +5 -5
- package/highlevel/types/messages/{rich-message.js → rich/rich-message.js} +6 -6
- package/highlevel/types/messages/rich/types.d.cts +76 -0
- package/highlevel/types/messages/rich/types.d.ts +76 -0
- package/highlevel/updates/manager.cjs +4 -0
- package/highlevel/updates/manager.js +4 -0
- package/highlevel/utils/entities.cjs +176 -0
- package/highlevel/utils/entities.d.cts +18 -0
- package/highlevel/utils/entities.d.ts +18 -0
- package/highlevel/utils/entities.js +177 -1
- package/index.cjs +3 -1
- package/index.js +3 -1
- package/methods.cjs +4 -0
- package/methods.js +4 -0
- package/network/mtproxy/_fake-tls.cjs +169 -107
- package/network/mtproxy/_fake-tls.js +169 -107
- package/network/mtproxy/_fake-tls.test.d.cts +1 -0
- package/network/mtproxy/_fake-tls.test.d.ts +1 -0
- package/network/network-manager.cjs +1 -1
- package/network/network-manager.js +1 -1
- package/package.json +1 -1
- package/tl/api-schema.json +1 -1
- package/tl/binary/reader.cjs +115 -109
- package/tl/binary/reader.js +115 -109
- package/tl/binary/writer.cjs +243 -245
- package/tl/binary/writer.js +243 -245
- package/tl/index.d.cts +227 -216
- package/tl/index.d.ts +227 -216
- package/tl/inner-tl.cjs +3 -1
- package/tl/inner-tl.js +3 -1
- package/types/utils.d.cts +4 -0
- package/types/utils.d.ts +4 -0
- package/utils.cjs +2 -0
- package/utils.js +3 -1
|
@@ -5,11 +5,11 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
|
|
|
5
5
|
}
|
|
6
6
|
"use strict";
|
|
7
7
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
-
const longUtils = require("
|
|
9
|
-
const inspectable = require("
|
|
10
|
-
const memoize = require("
|
|
11
|
-
const documentUtils = require("
|
|
12
|
-
const photo = require("
|
|
8
|
+
const longUtils = require("../../../../utils/long-utils.cjs");
|
|
9
|
+
const inspectable = require("../../../utils/inspectable.cjs");
|
|
10
|
+
const memoize = require("../../../utils/memoize.cjs");
|
|
11
|
+
const documentUtils = require("../../media/document-utils.cjs");
|
|
12
|
+
const photo = require("../../media/photo.cjs");
|
|
13
13
|
class RichMessage {
|
|
14
14
|
constructor(raw) {
|
|
15
15
|
this.raw = raw;
|
|
@@ -31,7 +31,7 @@ class RichMessage {
|
|
|
31
31
|
}
|
|
32
32
|
return map;
|
|
33
33
|
}
|
|
34
|
-
/** Documents (usually videos) in this message */
|
|
34
|
+
/** Documents (usually videos and audios) in this message */
|
|
35
35
|
get documents() {
|
|
36
36
|
const map = new longUtils.LongMap();
|
|
37
37
|
for (const photo2 of this.raw.documents) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { tl } from '
|
|
2
|
-
import { ParsedDocument } from '
|
|
3
|
-
import { LongMap } from '
|
|
4
|
-
import { Photo } from '
|
|
1
|
+
import { tl } from '../../../../tl/index.js';
|
|
2
|
+
import { ParsedDocument } from '../../media/document-utils.js';
|
|
3
|
+
import { LongMap } from '../../../../utils/long-utils.js';
|
|
4
|
+
import { Photo } from '../../media/photo.js';
|
|
5
5
|
export declare class RichMessage {
|
|
6
6
|
readonly raw: tl.TypeRichMessage;
|
|
7
7
|
constructor(raw: tl.TypeRichMessage);
|
|
@@ -11,7 +11,7 @@ export declare class RichMessage {
|
|
|
11
11
|
get isPart(): boolean;
|
|
12
12
|
/** Photos in this message */
|
|
13
13
|
get photos(): LongMap<Photo>;
|
|
14
|
-
/** Documents (usually videos) in this message */
|
|
14
|
+
/** Documents (usually videos and audios) in this message */
|
|
15
15
|
get documents(): LongMap<ParsedDocument>;
|
|
16
16
|
/** Blocks in this message */
|
|
17
17
|
get blocks(): tl.TypePageBlock[];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { tl } from '
|
|
2
|
-
import { ParsedDocument } from '
|
|
3
|
-
import { LongMap } from '
|
|
4
|
-
import { Photo } from '
|
|
1
|
+
import { tl } from '../../../../tl/index.js';
|
|
2
|
+
import { ParsedDocument } from '../../media/document-utils.js';
|
|
3
|
+
import { LongMap } from '../../../../utils/long-utils.js';
|
|
4
|
+
import { Photo } from '../../media/photo.js';
|
|
5
5
|
export declare class RichMessage {
|
|
6
6
|
readonly raw: tl.TypeRichMessage;
|
|
7
7
|
constructor(raw: tl.TypeRichMessage);
|
|
@@ -11,7 +11,7 @@ export declare class RichMessage {
|
|
|
11
11
|
get isPart(): boolean;
|
|
12
12
|
/** Photos in this message */
|
|
13
13
|
get photos(): LongMap<Photo>;
|
|
14
|
-
/** Documents (usually videos) in this message */
|
|
14
|
+
/** Documents (usually videos and audios) in this message */
|
|
15
15
|
get documents(): LongMap<ParsedDocument>;
|
|
16
16
|
/** Blocks in this message */
|
|
17
17
|
get blocks(): tl.TypePageBlock[];
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { LongMap } from "
|
|
2
|
-
import { makeInspectable } from "
|
|
3
|
-
import { memoizeGetters } from "
|
|
4
|
-
import { parseDocument } from "
|
|
5
|
-
import { Photo as Photo$2 } from "
|
|
1
|
+
import { LongMap } from "../../../../utils/long-utils.js";
|
|
2
|
+
import { makeInspectable } from "../../../utils/inspectable.js";
|
|
3
|
+
import { memoizeGetters } from "../../../utils/memoize.js";
|
|
4
|
+
import { parseDocument } from "../../media/document-utils.js";
|
|
5
|
+
import { Photo as Photo$2 } from "../../media/photo.js";
|
|
6
6
|
class RichMessage {
|
|
7
7
|
constructor(raw) {
|
|
8
8
|
this.raw = raw;
|
|
@@ -24,7 +24,7 @@ class RichMessage {
|
|
|
24
24
|
}
|
|
25
25
|
return map;
|
|
26
26
|
}
|
|
27
|
-
/** Documents (usually videos) in this message */
|
|
27
|
+
/** Documents (usually videos and audios) in this message */
|
|
28
28
|
get documents() {
|
|
29
29
|
const map = new LongMap();
|
|
30
30
|
for (const photo of this.raw.documents) {
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { tl } from '../../../../tl/index.js';
|
|
2
|
+
import { ReplaceDeep } from '../../../../types/utils.js';
|
|
3
|
+
import { InputMediaAudio, InputMediaPhoto, InputMediaVideo } from '../../media/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Input rich message media, can be one of:
|
|
6
|
+
* - Bot API-compatible file ID
|
|
7
|
+
* - {@link InputMediaPhoto} (e.g. `InputMedia.photo(...)`)
|
|
8
|
+
* - {@link InputMediaVideo} (e.g. `InputMedia.video(...)`)
|
|
9
|
+
* - {@link InputMediaAudio} (e.g. `InputMedia.audio(...)`)
|
|
10
|
+
* - a raw TL object
|
|
11
|
+
*/
|
|
12
|
+
export type InputRichMessageMedia = string | tl.TypeInputPhoto | tl.TypeInputDocument | InputMediaPhoto | InputMediaVideo | InputMediaAudio;
|
|
13
|
+
/** In-memory cache mapping an {@link InputRichMessageMedia} to its uploaded media, used by streaming drafts */
|
|
14
|
+
export type RichMediaUploadCache = Map<unknown, tl.RawInputMediaPhoto | tl.RawInputMediaDocument>;
|
|
15
|
+
interface InputRichMessageBase {
|
|
16
|
+
/** Whether this message should be rendered RTL */
|
|
17
|
+
rtl?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether to skip automatic entities detection (e.g., URLs, email addresses,
|
|
20
|
+
* username mentions, hashtags, cashtags, bot commands, or phone numbers)
|
|
21
|
+
*/
|
|
22
|
+
skipEntityDetection?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Input rich message that is parsed by the server in the specified format
|
|
26
|
+
*/
|
|
27
|
+
export interface InputServerParsedRichMessage extends InputRichMessageBase {
|
|
28
|
+
type: 'html' | 'markdown';
|
|
29
|
+
/**
|
|
30
|
+
* HTML or Markdown content
|
|
31
|
+
*
|
|
32
|
+
* Format reference is available in the Bot API:
|
|
33
|
+
* - [Markdown](https://core.telegram.org/bots/api#rich-markdown-style),
|
|
34
|
+
* - [HTML](https://core.telegram.org/bots/api#rich-html-style)
|
|
35
|
+
*
|
|
36
|
+
* In addition to the above, you can use the following links to reference non-HTTP/s media:
|
|
37
|
+
* - photos: `tg://photo?id=XXX`
|
|
38
|
+
* - videos/gifs: `tg://video?id=XXX`
|
|
39
|
+
* - audio: `tg://audio?id=XXX`
|
|
40
|
+
*
|
|
41
|
+
* where XXX is a unique identifier of the media in the {@link attachments} map.
|
|
42
|
+
*/
|
|
43
|
+
content: string;
|
|
44
|
+
/**
|
|
45
|
+
* Attachments to the rich message.
|
|
46
|
+
*/
|
|
47
|
+
attachments?: Record<string, InputRichMessageMedia>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A convenience wrapper for the raw page blocks containing a file
|
|
51
|
+
* (photo, video, document, etc.)
|
|
52
|
+
*
|
|
53
|
+
* You can simply pass `Long.ZERO` as the ID inside the block, and pass the
|
|
54
|
+
* actual file in the `file` property, and mtcute will take care of the rest.
|
|
55
|
+
*/
|
|
56
|
+
export interface InputPageBlockWithFile {
|
|
57
|
+
block: InputPageBlock;
|
|
58
|
+
file: InputRichMessageMedia;
|
|
59
|
+
}
|
|
60
|
+
export type InputPageBlock = ReplaceDeep<tl.TypePageBlock, tl.TypePageBlock, InputPageBlockWithFile>;
|
|
61
|
+
/**
|
|
62
|
+
* A page block as accepted in a *nested* position (inside another block's
|
|
63
|
+
* children, list items, etc.) — either a raw {@link tl.TypePageBlock} or
|
|
64
|
+
* an {@link InputPageBlockWithFile} wrapper.
|
|
65
|
+
*/
|
|
66
|
+
export type InputPageBlockOrFile = tl.TypePageBlock | InputPageBlockWithFile;
|
|
67
|
+
/** Input rich message that is built block-by-block */
|
|
68
|
+
export interface InputBlocksRichMessage extends InputRichMessageBase {
|
|
69
|
+
type: 'blocks';
|
|
70
|
+
/**
|
|
71
|
+
* Blocks of the rich message
|
|
72
|
+
*/
|
|
73
|
+
blocks: (InputPageBlock | InputPageBlockWithFile)[];
|
|
74
|
+
}
|
|
75
|
+
export type InputRichMessage = tl.TypeInputRichMessage | InputBlocksRichMessage | InputServerParsedRichMessage;
|
|
76
|
+
export {};
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { tl } from '../../../../tl/index.js';
|
|
2
|
+
import { ReplaceDeep } from '../../../../types/utils.js';
|
|
3
|
+
import { InputMediaAudio, InputMediaPhoto, InputMediaVideo } from '../../media/index.js';
|
|
4
|
+
/**
|
|
5
|
+
* Input rich message media, can be one of:
|
|
6
|
+
* - Bot API-compatible file ID
|
|
7
|
+
* - {@link InputMediaPhoto} (e.g. `InputMedia.photo(...)`)
|
|
8
|
+
* - {@link InputMediaVideo} (e.g. `InputMedia.video(...)`)
|
|
9
|
+
* - {@link InputMediaAudio} (e.g. `InputMedia.audio(...)`)
|
|
10
|
+
* - a raw TL object
|
|
11
|
+
*/
|
|
12
|
+
export type InputRichMessageMedia = string | tl.TypeInputPhoto | tl.TypeInputDocument | InputMediaPhoto | InputMediaVideo | InputMediaAudio;
|
|
13
|
+
/** In-memory cache mapping an {@link InputRichMessageMedia} to its uploaded media, used by streaming drafts */
|
|
14
|
+
export type RichMediaUploadCache = Map<unknown, tl.RawInputMediaPhoto | tl.RawInputMediaDocument>;
|
|
15
|
+
interface InputRichMessageBase {
|
|
16
|
+
/** Whether this message should be rendered RTL */
|
|
17
|
+
rtl?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Whether to skip automatic entities detection (e.g., URLs, email addresses,
|
|
20
|
+
* username mentions, hashtags, cashtags, bot commands, or phone numbers)
|
|
21
|
+
*/
|
|
22
|
+
skipEntityDetection?: boolean;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Input rich message that is parsed by the server in the specified format
|
|
26
|
+
*/
|
|
27
|
+
export interface InputServerParsedRichMessage extends InputRichMessageBase {
|
|
28
|
+
type: 'html' | 'markdown';
|
|
29
|
+
/**
|
|
30
|
+
* HTML or Markdown content
|
|
31
|
+
*
|
|
32
|
+
* Format reference is available in the Bot API:
|
|
33
|
+
* - [Markdown](https://core.telegram.org/bots/api#rich-markdown-style),
|
|
34
|
+
* - [HTML](https://core.telegram.org/bots/api#rich-html-style)
|
|
35
|
+
*
|
|
36
|
+
* In addition to the above, you can use the following links to reference non-HTTP/s media:
|
|
37
|
+
* - photos: `tg://photo?id=XXX`
|
|
38
|
+
* - videos/gifs: `tg://video?id=XXX`
|
|
39
|
+
* - audio: `tg://audio?id=XXX`
|
|
40
|
+
*
|
|
41
|
+
* where XXX is a unique identifier of the media in the {@link attachments} map.
|
|
42
|
+
*/
|
|
43
|
+
content: string;
|
|
44
|
+
/**
|
|
45
|
+
* Attachments to the rich message.
|
|
46
|
+
*/
|
|
47
|
+
attachments?: Record<string, InputRichMessageMedia>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A convenience wrapper for the raw page blocks containing a file
|
|
51
|
+
* (photo, video, document, etc.)
|
|
52
|
+
*
|
|
53
|
+
* You can simply pass `Long.ZERO` as the ID inside the block, and pass the
|
|
54
|
+
* actual file in the `file` property, and mtcute will take care of the rest.
|
|
55
|
+
*/
|
|
56
|
+
export interface InputPageBlockWithFile {
|
|
57
|
+
block: InputPageBlock;
|
|
58
|
+
file: InputRichMessageMedia;
|
|
59
|
+
}
|
|
60
|
+
export type InputPageBlock = ReplaceDeep<tl.TypePageBlock, tl.TypePageBlock, InputPageBlockWithFile>;
|
|
61
|
+
/**
|
|
62
|
+
* A page block as accepted in a *nested* position (inside another block's
|
|
63
|
+
* children, list items, etc.) — either a raw {@link tl.TypePageBlock} or
|
|
64
|
+
* an {@link InputPageBlockWithFile} wrapper.
|
|
65
|
+
*/
|
|
66
|
+
export type InputPageBlockOrFile = tl.TypePageBlock | InputPageBlockWithFile;
|
|
67
|
+
/** Input rich message that is built block-by-block */
|
|
68
|
+
export interface InputBlocksRichMessage extends InputRichMessageBase {
|
|
69
|
+
type: 'blocks';
|
|
70
|
+
/**
|
|
71
|
+
* Blocks of the rich message
|
|
72
|
+
*/
|
|
73
|
+
blocks: (InputPageBlock | InputPageBlockWithFile)[];
|
|
74
|
+
}
|
|
75
|
+
export type InputRichMessage = tl.TypeInputRichMessage | InputBlocksRichMessage | InputServerParsedRichMessage;
|
|
76
|
+
export {};
|
|
@@ -1558,6 +1558,7 @@ class UpdatesManager {
|
|
|
1558
1558
|
localPts,
|
|
1559
1559
|
pending.ptsBefore
|
|
1560
1560
|
);
|
|
1561
|
+
postponedTimer.emitBefore(pending.timeout);
|
|
1561
1562
|
} else {
|
|
1562
1563
|
log.debug(
|
|
1563
1564
|
"gap for postponed %s (cid = %d) wasn't filled, fetching diff (current pts %d, need %d)",
|
|
@@ -1635,6 +1636,8 @@ class UpdatesManager {
|
|
|
1635
1636
|
this.qts,
|
|
1636
1637
|
pending.qtsBefore
|
|
1637
1638
|
);
|
|
1639
|
+
pendingQtsUpdatesPostponed.removeIndex(i);
|
|
1640
|
+
i--;
|
|
1638
1641
|
continue;
|
|
1639
1642
|
}
|
|
1640
1643
|
if (this.qts < pending.qtsBefore) {
|
|
@@ -1647,6 +1650,7 @@ class UpdatesManager {
|
|
|
1647
1650
|
this.qts,
|
|
1648
1651
|
pending.qtsBefore
|
|
1649
1652
|
);
|
|
1653
|
+
postponedTimer.emitBefore(pending.timeout);
|
|
1650
1654
|
} else {
|
|
1651
1655
|
log.debug(
|
|
1652
1656
|
"gap for postponed %s wasn't filled, fetching diff (current qts %d, need %d)",
|
|
@@ -1551,6 +1551,7 @@ class UpdatesManager {
|
|
|
1551
1551
|
localPts,
|
|
1552
1552
|
pending.ptsBefore
|
|
1553
1553
|
);
|
|
1554
|
+
postponedTimer.emitBefore(pending.timeout);
|
|
1554
1555
|
} else {
|
|
1555
1556
|
log.debug(
|
|
1556
1557
|
"gap for postponed %s (cid = %d) wasn't filled, fetching diff (current pts %d, need %d)",
|
|
@@ -1628,6 +1629,8 @@ class UpdatesManager {
|
|
|
1628
1629
|
this.qts,
|
|
1629
1630
|
pending.qtsBefore
|
|
1630
1631
|
);
|
|
1632
|
+
pendingQtsUpdatesPostponed.removeIndex(i);
|
|
1633
|
+
i--;
|
|
1631
1634
|
continue;
|
|
1632
1635
|
}
|
|
1633
1636
|
if (this.qts < pending.qtsBefore) {
|
|
@@ -1640,6 +1643,7 @@ class UpdatesManager {
|
|
|
1640
1643
|
this.qts,
|
|
1641
1644
|
pending.qtsBefore
|
|
1642
1645
|
);
|
|
1646
|
+
postponedTimer.emitBefore(pending.timeout);
|
|
1643
1647
|
} else {
|
|
1644
1648
|
log.debug(
|
|
1645
1649
|
"gap for postponed %s wasn't filled, fetching diff (current qts %d, need %d)",
|
|
@@ -5,6 +5,8 @@ if (typeof globalThis !== "undefined" && !globalThis._MTCUTE_CJS_DEPRECATION_WAR
|
|
|
5
5
|
}
|
|
6
6
|
"use strict";
|
|
7
7
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
8
|
+
const Long = require("long");
|
|
9
|
+
const peerUtils = require("../../utils/peer-utils.cjs");
|
|
8
10
|
function joinTextWithEntities(parts, delim = "") {
|
|
9
11
|
const textParts = [];
|
|
10
12
|
const newEntities = [];
|
|
@@ -36,4 +38,178 @@ function joinTextWithEntities(parts, delim = "") {
|
|
|
36
38
|
entities: newEntities
|
|
37
39
|
};
|
|
38
40
|
}
|
|
41
|
+
function _entityToRichTextWrapper(entity, text) {
|
|
42
|
+
const covered = () => text.slice(entity.offset, entity.offset + entity.length);
|
|
43
|
+
switch (entity._) {
|
|
44
|
+
case "messageEntityBold":
|
|
45
|
+
return (inner) => ({ _: "textBold", text: inner });
|
|
46
|
+
case "messageEntityItalic":
|
|
47
|
+
return (inner) => ({ _: "textItalic", text: inner });
|
|
48
|
+
case "messageEntityUnderline":
|
|
49
|
+
return (inner) => ({ _: "textUnderline", text: inner });
|
|
50
|
+
case "messageEntityStrike":
|
|
51
|
+
return (inner) => ({ _: "textStrike", text: inner });
|
|
52
|
+
case "messageEntityCode":
|
|
53
|
+
case "messageEntityPre":
|
|
54
|
+
return (inner) => ({ _: "textFixed", text: inner });
|
|
55
|
+
case "messageEntitySpoiler":
|
|
56
|
+
return (inner) => ({ _: "textSpoiler", text: inner });
|
|
57
|
+
case "messageEntityMention":
|
|
58
|
+
return (inner) => ({ _: "textMention", text: inner });
|
|
59
|
+
case "messageEntityHashtag":
|
|
60
|
+
return (inner) => ({ _: "textHashtag", text: inner });
|
|
61
|
+
case "messageEntityCashtag":
|
|
62
|
+
return (inner) => ({ _: "textCashtag", text: inner });
|
|
63
|
+
case "messageEntityBotCommand":
|
|
64
|
+
return (inner) => ({ _: "textBotCommand", text: inner });
|
|
65
|
+
case "messageEntityBankCard":
|
|
66
|
+
return (inner) => ({ _: "textBankCard", text: inner });
|
|
67
|
+
case "messageEntityUrl":
|
|
68
|
+
return (inner) => ({ _: "textUrl", text: inner, url: covered(), webpageId: Long.ZERO });
|
|
69
|
+
case "messageEntityTextUrl":
|
|
70
|
+
return (inner) => ({ _: "textUrl", text: inner, url: entity.url, webpageId: Long.ZERO });
|
|
71
|
+
case "messageEntityEmail":
|
|
72
|
+
return (inner) => ({ _: "textEmail", text: inner, email: covered() });
|
|
73
|
+
case "messageEntityPhone":
|
|
74
|
+
return (inner) => ({ _: "textPhone", text: inner, phone: covered() });
|
|
75
|
+
case "messageEntityMentionName":
|
|
76
|
+
return (inner) => ({ _: "textMentionName", text: inner, userId: entity.userId });
|
|
77
|
+
case "inputMessageEntityMentionName":
|
|
78
|
+
return (inner) => ({ _: "textMentionName", text: inner, userId: peerUtils.getMarkedPeerId(entity.userId) });
|
|
79
|
+
case "messageEntityCustomEmoji":
|
|
80
|
+
return () => ({ _: "textCustomEmoji", documentId: entity.documentId, alt: covered() });
|
|
81
|
+
case "messageEntityFormattedDate":
|
|
82
|
+
return (inner) => ({
|
|
83
|
+
_: "textDate",
|
|
84
|
+
text: inner,
|
|
85
|
+
date: entity.date,
|
|
86
|
+
relative: entity.relative,
|
|
87
|
+
shortTime: entity.shortTime,
|
|
88
|
+
longTime: entity.longTime,
|
|
89
|
+
shortDate: entity.shortDate,
|
|
90
|
+
longDate: entity.longDate,
|
|
91
|
+
dayOfWeek: entity.dayOfWeek
|
|
92
|
+
});
|
|
93
|
+
default:
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
function textWithEntitiesToRichText(input) {
|
|
98
|
+
const { text, entities } = input;
|
|
99
|
+
if (!text) return { _: "textEmpty" };
|
|
100
|
+
if (!entities?.length) return { _: "textPlain", text };
|
|
101
|
+
const bounds = /* @__PURE__ */ new Set([0, text.length]);
|
|
102
|
+
for (const e of entities) {
|
|
103
|
+
bounds.add(e.offset);
|
|
104
|
+
bounds.add(e.offset + e.length);
|
|
105
|
+
}
|
|
106
|
+
const sorted = [...bounds].filter((b) => b >= 0 && b <= text.length).sort((a, b) => a - b);
|
|
107
|
+
const segments = [];
|
|
108
|
+
for (let i = 0; i < sorted.length - 1; i++) {
|
|
109
|
+
const start = sorted[i];
|
|
110
|
+
const end = sorted[i + 1];
|
|
111
|
+
if (start === end) continue;
|
|
112
|
+
let node = { _: "textPlain", text: text.slice(start, end) };
|
|
113
|
+
const active = entities.filter((e) => e.offset <= start && e.offset + e.length >= end).sort((a, b) => a.length - b.length);
|
|
114
|
+
for (const e of active) {
|
|
115
|
+
const wrap = _entityToRichTextWrapper(e, text);
|
|
116
|
+
if (wrap) node = wrap(node);
|
|
117
|
+
}
|
|
118
|
+
segments.push(node);
|
|
119
|
+
}
|
|
120
|
+
if (segments.length === 0) return { _: "textEmpty" };
|
|
121
|
+
if (segments.length === 1) return segments[0];
|
|
122
|
+
return { _: "textConcat", texts: segments };
|
|
123
|
+
}
|
|
124
|
+
function _richTextNodeToEntity(node, offset, length) {
|
|
125
|
+
switch (node._) {
|
|
126
|
+
case "textBold":
|
|
127
|
+
return { _: "messageEntityBold", offset, length };
|
|
128
|
+
case "textItalic":
|
|
129
|
+
return { _: "messageEntityItalic", offset, length };
|
|
130
|
+
case "textUnderline":
|
|
131
|
+
return { _: "messageEntityUnderline", offset, length };
|
|
132
|
+
case "textStrike":
|
|
133
|
+
return { _: "messageEntityStrike", offset, length };
|
|
134
|
+
case "textFixed":
|
|
135
|
+
return { _: "messageEntityCode", offset, length };
|
|
136
|
+
case "textSpoiler":
|
|
137
|
+
return { _: "messageEntitySpoiler", offset, length };
|
|
138
|
+
case "textMention":
|
|
139
|
+
return { _: "messageEntityMention", offset, length };
|
|
140
|
+
case "textHashtag":
|
|
141
|
+
return { _: "messageEntityHashtag", offset, length };
|
|
142
|
+
case "textCashtag":
|
|
143
|
+
return { _: "messageEntityCashtag", offset, length };
|
|
144
|
+
case "textBotCommand":
|
|
145
|
+
return { _: "messageEntityBotCommand", offset, length };
|
|
146
|
+
case "textBankCard":
|
|
147
|
+
return { _: "messageEntityBankCard", offset, length };
|
|
148
|
+
case "textUrl":
|
|
149
|
+
return { _: "messageEntityTextUrl", offset, length, url: node.url };
|
|
150
|
+
case "textEmail":
|
|
151
|
+
return { _: "messageEntityEmail", offset, length };
|
|
152
|
+
case "textPhone":
|
|
153
|
+
return { _: "messageEntityPhone", offset, length };
|
|
154
|
+
case "textMentionName":
|
|
155
|
+
return { _: "messageEntityMentionName", offset, length, userId: node.userId };
|
|
156
|
+
case "textDate":
|
|
157
|
+
return {
|
|
158
|
+
_: "messageEntityFormattedDate",
|
|
159
|
+
offset,
|
|
160
|
+
length,
|
|
161
|
+
date: node.date,
|
|
162
|
+
relative: node.relative,
|
|
163
|
+
shortTime: node.shortTime,
|
|
164
|
+
longTime: node.longTime,
|
|
165
|
+
shortDate: node.shortDate,
|
|
166
|
+
longDate: node.longDate,
|
|
167
|
+
dayOfWeek: node.dayOfWeek
|
|
168
|
+
};
|
|
169
|
+
default:
|
|
170
|
+
return null;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
function richTextToTextWithEntities(rich) {
|
|
174
|
+
const entities = [];
|
|
175
|
+
let text = "";
|
|
176
|
+
const walk = (node) => {
|
|
177
|
+
switch (node._) {
|
|
178
|
+
case "textEmpty":
|
|
179
|
+
return;
|
|
180
|
+
case "textPlain":
|
|
181
|
+
text += node.text;
|
|
182
|
+
return;
|
|
183
|
+
case "textConcat":
|
|
184
|
+
for (const t of node.texts) walk(t);
|
|
185
|
+
return;
|
|
186
|
+
case "textImage":
|
|
187
|
+
return;
|
|
188
|
+
case "textMath":
|
|
189
|
+
text += node.source;
|
|
190
|
+
return;
|
|
191
|
+
case "textCustomEmoji": {
|
|
192
|
+
const start = text.length;
|
|
193
|
+
text += node.alt;
|
|
194
|
+
entities.push({
|
|
195
|
+
_: "messageEntityCustomEmoji",
|
|
196
|
+
offset: start,
|
|
197
|
+
length: text.length - start,
|
|
198
|
+
documentId: node.documentId
|
|
199
|
+
});
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
default: {
|
|
203
|
+
const start = text.length;
|
|
204
|
+
walk(node.text);
|
|
205
|
+
const entity = _richTextNodeToEntity(node, start, text.length - start);
|
|
206
|
+
if (entity) entities.push(entity);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
walk(rich);
|
|
211
|
+
return { text, entities };
|
|
212
|
+
}
|
|
39
213
|
exports.joinTextWithEntities = joinTextWithEntities;
|
|
214
|
+
exports.richTextToTextWithEntities = richTextToTextWithEntities;
|
|
215
|
+
exports.textWithEntitiesToRichText = textWithEntitiesToRichText;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { tl } from '../../tl/index.js';
|
|
1
2
|
import { TextWithEntities } from '../types/misc/entities.js';
|
|
2
3
|
/**
|
|
3
4
|
* Join multiple text parts with entities into a single text with entities,
|
|
@@ -17,3 +18,20 @@ import { TextWithEntities } from '../types/misc/entities.js';
|
|
|
17
18
|
* ```
|
|
18
19
|
*/
|
|
19
20
|
export declare function joinTextWithEntities(parts: (string | TextWithEntities)[], delim?: string | TextWithEntities): TextWithEntities;
|
|
21
|
+
/**
|
|
22
|
+
* Convert a {@link TextWithEntities} into a {@link tl.TypeRichText} tree
|
|
23
|
+
* (as used in page blocks / instant view).
|
|
24
|
+
*
|
|
25
|
+
* Overlapping entities are handled by splitting the text at every entity
|
|
26
|
+
* boundary and nesting the wrappers per-segment, so the result may be more
|
|
27
|
+
* fragmented than the input, but always renders identically.
|
|
28
|
+
*/
|
|
29
|
+
export declare function textWithEntitiesToRichText(input: TextWithEntities): tl.TypeRichText;
|
|
30
|
+
/**
|
|
31
|
+
* Convert a {@link tl.TypeRichText} tree back into a {@link TextWithEntities}.
|
|
32
|
+
*
|
|
33
|
+
* This conversion is **lossy**: rich text nodes that have no message entity
|
|
34
|
+
* equivalent (e.g. `textMarked`, `textSubscript`, anchors, images) are dropped,
|
|
35
|
+
* keeping only their textual content.
|
|
36
|
+
*/
|
|
37
|
+
export declare function richTextToTextWithEntities(rich: tl.TypeRichText): TextWithEntities;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { tl } from '../../tl/index.js';
|
|
1
2
|
import { TextWithEntities } from '../types/misc/entities.js';
|
|
2
3
|
/**
|
|
3
4
|
* Join multiple text parts with entities into a single text with entities,
|
|
@@ -17,3 +18,20 @@ import { TextWithEntities } from '../types/misc/entities.js';
|
|
|
17
18
|
* ```
|
|
18
19
|
*/
|
|
19
20
|
export declare function joinTextWithEntities(parts: (string | TextWithEntities)[], delim?: string | TextWithEntities): TextWithEntities;
|
|
21
|
+
/**
|
|
22
|
+
* Convert a {@link TextWithEntities} into a {@link tl.TypeRichText} tree
|
|
23
|
+
* (as used in page blocks / instant view).
|
|
24
|
+
*
|
|
25
|
+
* Overlapping entities are handled by splitting the text at every entity
|
|
26
|
+
* boundary and nesting the wrappers per-segment, so the result may be more
|
|
27
|
+
* fragmented than the input, but always renders identically.
|
|
28
|
+
*/
|
|
29
|
+
export declare function textWithEntitiesToRichText(input: TextWithEntities): tl.TypeRichText;
|
|
30
|
+
/**
|
|
31
|
+
* Convert a {@link tl.TypeRichText} tree back into a {@link TextWithEntities}.
|
|
32
|
+
*
|
|
33
|
+
* This conversion is **lossy**: rich text nodes that have no message entity
|
|
34
|
+
* equivalent (e.g. `textMarked`, `textSubscript`, anchors, images) are dropped,
|
|
35
|
+
* keeping only their textual content.
|
|
36
|
+
*/
|
|
37
|
+
export declare function richTextToTextWithEntities(rich: tl.TypeRichText): TextWithEntities;
|