@mtkruto/node 0.70.1 → 0.71.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -4
- package/esm/0_deps.d.ts +2 -2
- package/esm/0_deps.d.ts.map +1 -1
- package/esm/0_deps.js +2 -2
- package/esm/client/0_html.d.ts +2 -1
- package/esm/client/0_html.d.ts.map +1 -1
- package/esm/client/0_html.js +420 -70
- package/esm/client/0_html_test.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/assert/1.0.14/instance_of.d.ts +23 -0
- package/esm/deps/jsr.io/@std/assert/1.0.14/instance_of.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/assert/1.0.14/instance_of.js +52 -0
- package/{script/deps/jsr.io/@std/streams/1.0.11 → esm/deps/jsr.io/@std/streams/1.0.12}/to_array_buffer.d.ts.map +1 -1
- package/package.json +1 -2
- package/script/0_deps.d.ts +2 -2
- package/script/0_deps.d.ts.map +1 -1
- package/script/0_deps.js +4 -4
- package/script/client/0_html.d.ts +2 -1
- package/script/client/0_html.d.ts.map +1 -1
- package/script/client/0_html.js +421 -70
- package/script/client/0_html_test.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/assert/1.0.14/instance_of.d.ts +23 -0
- package/script/deps/jsr.io/@std/assert/1.0.14/instance_of.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/assert/1.0.14/instance_of.js +55 -0
- package/{esm/deps/jsr.io/@std/streams/1.0.11 → script/deps/jsr.io/@std/streams/1.0.12}/to_array_buffer.d.ts.map +1 -1
- /package/esm/deps/jsr.io/@std/streams/{1.0.11 → 1.0.12}/to_array_buffer.d.ts +0 -0
- /package/esm/deps/jsr.io/@std/streams/{1.0.11 → 1.0.12}/to_array_buffer.js +0 -0
- /package/script/deps/jsr.io/@std/streams/{1.0.11 → 1.0.12}/to_array_buffer.d.ts +0 -0
- /package/script/deps/jsr.io/@std/streams/{1.0.11 → 1.0.12}/to_array_buffer.js +0 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// Copyright 2018-2025 the Deno authors. MIT license.
|
|
2
|
+
// This module is browser compatible.
|
|
3
|
+
import { AssertionError } from "./assertion_error.js";
|
|
4
|
+
/**
|
|
5
|
+
* Make an assertion that `obj` is an instance of `type`.
|
|
6
|
+
* If not then throw.
|
|
7
|
+
*
|
|
8
|
+
* @example Usage
|
|
9
|
+
* ```ts ignore
|
|
10
|
+
* import { assertInstanceOf } from "@std/assert";
|
|
11
|
+
*
|
|
12
|
+
* assertInstanceOf(new Date(), Date); // Doesn't throw
|
|
13
|
+
* assertInstanceOf(new Date(), Number); // Throws
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* @typeParam T The expected type of the object.
|
|
17
|
+
* @param actual The object to check.
|
|
18
|
+
* @param expectedType The expected class constructor.
|
|
19
|
+
* @param msg The optional message to display if the assertion fails.
|
|
20
|
+
*/
|
|
21
|
+
export function assertInstanceOf(actual, expectedType, msg = "") {
|
|
22
|
+
if (actual instanceof expectedType)
|
|
23
|
+
return;
|
|
24
|
+
const msgSuffix = msg ? `: ${msg}` : ".";
|
|
25
|
+
const expectedTypeStr = expectedType.name;
|
|
26
|
+
let actualTypeStr = "";
|
|
27
|
+
if (actual === null) {
|
|
28
|
+
actualTypeStr = "null";
|
|
29
|
+
}
|
|
30
|
+
else if (actual === undefined) {
|
|
31
|
+
actualTypeStr = "undefined";
|
|
32
|
+
}
|
|
33
|
+
else if (typeof actual === "object") {
|
|
34
|
+
actualTypeStr = actual.constructor?.name ?? "Object";
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
actualTypeStr = typeof actual;
|
|
38
|
+
}
|
|
39
|
+
if (expectedTypeStr === actualTypeStr) {
|
|
40
|
+
msg =
|
|
41
|
+
`Expected object to be an instance of "${expectedTypeStr}"${msgSuffix}`;
|
|
42
|
+
}
|
|
43
|
+
else if (actualTypeStr === "function") {
|
|
44
|
+
msg =
|
|
45
|
+
`Expected object to be an instance of "${expectedTypeStr}" but was not an instanced object${msgSuffix}`;
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
msg =
|
|
49
|
+
`Expected object to be an instance of "${expectedTypeStr}" but was "${actualTypeStr}"${msgSuffix}`;
|
|
50
|
+
}
|
|
51
|
+
throw new AssertionError(msg);
|
|
52
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"to_array_buffer.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/streams/1.0.
|
|
1
|
+
{"version":3,"file":"to_array_buffer.d.ts","sourceRoot":"","sources":["../../../../../../src/deps/jsr.io/@std/streams/1.0.12/to_array_buffer.ts"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,aAAa,CACjC,cAAc,EAAE,cAAc,CAAC,UAAU,CAAC,GACzC,OAAO,CAAC,WAAW,CAAC,CAetB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mtkruto/node",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.71.1",
|
|
4
4
|
"description": "MTKruto for Node.js",
|
|
5
5
|
"author": "Roj <rojvv@icloud.com>",
|
|
6
6
|
"repository": {
|
|
@@ -24,7 +24,6 @@
|
|
|
24
24
|
"test": "node test_runner.js"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"htmlparser2": "10.0.0",
|
|
28
27
|
"@deno/shim-crypto": "~0.3.1",
|
|
29
28
|
"@deno/shim-prompts": "~0.1.0",
|
|
30
29
|
"ws": "^8.13.0",
|
package/script/0_deps.d.ts
CHANGED
|
@@ -21,6 +21,7 @@ export { assert } from "./deps/jsr.io/@std/assert/1.0.14/assert.js";
|
|
|
21
21
|
export { assertFalse } from "./deps/jsr.io/@std/assert/1.0.14/false.js";
|
|
22
22
|
export { assertEquals } from "./deps/jsr.io/@std/assert/1.0.14/equals.js";
|
|
23
23
|
export { unreachable } from "./deps/jsr.io/@std/assert/1.0.14/unreachable.js";
|
|
24
|
+
export { assertInstanceOf } from "./deps/jsr.io/@std/assert/1.0.14/instance_of.js";
|
|
24
25
|
export { AssertionError } from "./deps/jsr.io/@std/assert/1.0.14/assertion_error.js";
|
|
25
26
|
export { join } from "./deps/jsr.io/@std/path/1.1.2/join.js";
|
|
26
27
|
export { extname } from "./deps/jsr.io/@std/path/1.1.2/extname.js";
|
|
@@ -33,12 +34,11 @@ export { LruCache } from "./deps/jsr.io/@std/cache/0.2.0/lru_cache.js";
|
|
|
33
34
|
export { iterateReader } from "./deps/jsr.io/@std/io/0.225.2/iterate_reader.js";
|
|
34
35
|
export { format } from "./deps/jsr.io/@std/datetime/0.225.5/format.js";
|
|
35
36
|
export { MINUTE, SECOND } from "./deps/jsr.io/@std/datetime/0.225.5/constants.js";
|
|
36
|
-
export { toArrayBuffer } from "./deps/jsr.io/@std/streams/1.0.
|
|
37
|
+
export { toArrayBuffer } from "./deps/jsr.io/@std/streams/1.0.12/to_array_buffer.js";
|
|
37
38
|
export { decodeBase64, encodeBase64 } from "./deps/jsr.io/@std/encoding/1.0.7/base64.js";
|
|
38
39
|
export { encodeHex } from "./deps/jsr.io/@std/encoding/1.0.7/hex.js";
|
|
39
40
|
import { contentType as contentType_ } from "./deps/jsr.io/@std/media-types/1.1.0/content_type.js";
|
|
40
41
|
export declare const contentType: typeof contentType_;
|
|
41
42
|
export declare function extension(mimeType: string): string;
|
|
42
43
|
export { ige256Decrypt, ige256Encrypt, init as initTgCrypto } from "./deps/jsr.io/@roj/tgcrypto/1.0.1/dist/mod.js";
|
|
43
|
-
export { Parser } from "htmlparser2";
|
|
44
44
|
//# sourceMappingURL=0_deps.d.ts.map
|
package/script/0_deps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"0_deps.d.ts","sourceRoot":"","sources":["../src/0_deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,4CAA4C,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,qDAAqD,CAAC;AAErF,OAAO,EAAE,IAAI,EAAE,MAAM,uCAAuC,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,0CAA0C,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE1E,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAE1E,OAAO,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAC;AAEhF,OAAO,EAAE,MAAM,EAAE,MAAM,+CAA+C,CAAC;AAEvE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kDAAkD,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,sDAAsD,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAEzF,OAAO,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAC;AAErE,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,sDAAsD,CAAC;AACnG,eAAO,MAAM,WAAW,EAAE,OAAO,YAMhC,CAAC;AAEF,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,UAMzC;AAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,+CAA+C,CAAC
|
|
1
|
+
{"version":3,"file":"0_deps.d.ts","sourceRoot":"","sources":["../src/0_deps.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,4CAA4C,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,MAAM,4CAA4C,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAE,MAAM,iDAAiD,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iDAAiD,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,MAAM,qDAAqD,CAAC;AAErF,OAAO,EAAE,IAAI,EAAE,MAAM,uCAAuC,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,0CAA0C,CAAC;AACnE,OAAO,EAAE,QAAQ,EAAE,MAAM,2CAA2C,CAAC;AACrE,OAAO,EAAE,SAAS,EAAE,MAAM,8CAA8C,CAAC;AACzE,OAAO,EAAE,UAAU,EAAE,MAAM,8CAA8C,CAAC;AAE1E,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,wCAAwC,CAAC;AAE1E,OAAO,EAAE,MAAM,EAAE,MAAM,0CAA0C,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,6CAA6C,CAAC;AAEvE,OAAO,EAAE,aAAa,EAAE,MAAM,iDAAiD,CAAC;AAEhF,OAAO,EAAE,MAAM,EAAE,MAAM,+CAA+C,CAAC;AAEvE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,kDAAkD,CAAC;AAElF,OAAO,EAAE,aAAa,EAAE,MAAM,sDAAsD,CAAC;AAErF,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,6CAA6C,CAAC;AAEzF,OAAO,EAAE,SAAS,EAAE,MAAM,0CAA0C,CAAC;AAErE,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,sDAAsD,CAAC;AACnG,eAAO,MAAM,WAAW,EAAE,OAAO,YAMhC,CAAC;AAEF,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,UAMzC;AAED,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,IAAI,YAAY,EAAE,MAAM,+CAA+C,CAAC"}
|
package/script/0_deps.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
-
exports.
|
|
22
|
+
exports.initTgCrypto = exports.ige256Encrypt = exports.ige256Decrypt = exports.contentType = exports.encodeHex = exports.encodeBase64 = exports.decodeBase64 = exports.toArrayBuffer = exports.SECOND = exports.MINUTE = exports.format = exports.iterateReader = exports.LruCache = exports.concat = exports.pooledMap = exports.delay = exports.isAbsolute = exports.toFileUrl = exports.basename = exports.extname = exports.join = exports.AssertionError = exports.assertInstanceOf = exports.unreachable = exports.assertEquals = exports.assertFalse = exports.assert = void 0;
|
|
23
23
|
exports.extension = extension;
|
|
24
24
|
var assert_js_1 = require("./deps/jsr.io/@std/assert/1.0.14/assert.js");
|
|
25
25
|
Object.defineProperty(exports, "assert", { enumerable: true, get: function () { return assert_js_1.assert; } });
|
|
@@ -29,6 +29,8 @@ var equals_js_1 = require("./deps/jsr.io/@std/assert/1.0.14/equals.js");
|
|
|
29
29
|
Object.defineProperty(exports, "assertEquals", { enumerable: true, get: function () { return equals_js_1.assertEquals; } });
|
|
30
30
|
var unreachable_js_1 = require("./deps/jsr.io/@std/assert/1.0.14/unreachable.js");
|
|
31
31
|
Object.defineProperty(exports, "unreachable", { enumerable: true, get: function () { return unreachable_js_1.unreachable; } });
|
|
32
|
+
var instance_of_js_1 = require("./deps/jsr.io/@std/assert/1.0.14/instance_of.js");
|
|
33
|
+
Object.defineProperty(exports, "assertInstanceOf", { enumerable: true, get: function () { return instance_of_js_1.assertInstanceOf; } });
|
|
32
34
|
var assertion_error_js_1 = require("./deps/jsr.io/@std/assert/1.0.14/assertion_error.js");
|
|
33
35
|
Object.defineProperty(exports, "AssertionError", { enumerable: true, get: function () { return assertion_error_js_1.AssertionError; } });
|
|
34
36
|
var join_js_1 = require("./deps/jsr.io/@std/path/1.1.2/join.js");
|
|
@@ -55,7 +57,7 @@ Object.defineProperty(exports, "format", { enumerable: true, get: function () {
|
|
|
55
57
|
var constants_js_1 = require("./deps/jsr.io/@std/datetime/0.225.5/constants.js");
|
|
56
58
|
Object.defineProperty(exports, "MINUTE", { enumerable: true, get: function () { return constants_js_1.MINUTE; } });
|
|
57
59
|
Object.defineProperty(exports, "SECOND", { enumerable: true, get: function () { return constants_js_1.SECOND; } });
|
|
58
|
-
var to_array_buffer_js_1 = require("./deps/jsr.io/@std/streams/1.0.
|
|
60
|
+
var to_array_buffer_js_1 = require("./deps/jsr.io/@std/streams/1.0.12/to_array_buffer.js");
|
|
59
61
|
Object.defineProperty(exports, "toArrayBuffer", { enumerable: true, get: function () { return to_array_buffer_js_1.toArrayBuffer; } });
|
|
60
62
|
var base64_js_1 = require("./deps/jsr.io/@std/encoding/1.0.7/base64.js");
|
|
61
63
|
Object.defineProperty(exports, "decodeBase64", { enumerable: true, get: function () { return base64_js_1.decodeBase64; } });
|
|
@@ -85,5 +87,3 @@ var mod_js_2 = require("./deps/jsr.io/@roj/tgcrypto/1.0.1/dist/mod.js");
|
|
|
85
87
|
Object.defineProperty(exports, "ige256Decrypt", { enumerable: true, get: function () { return mod_js_2.ige256Decrypt; } });
|
|
86
88
|
Object.defineProperty(exports, "ige256Encrypt", { enumerable: true, get: function () { return mod_js_2.ige256Encrypt; } });
|
|
87
89
|
Object.defineProperty(exports, "initTgCrypto", { enumerable: true, get: function () { return mod_js_2.init; } });
|
|
88
|
-
var htmlparser2_1 = require("htmlparser2");
|
|
89
|
-
Object.defineProperty(exports, "Parser", { enumerable: true, get: function () { return htmlparser2_1.Parser; } });
|
|
@@ -18,5 +18,6 @@
|
|
|
18
18
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
19
19
|
*/
|
|
20
20
|
import type { MessageEntity } from "../3_types.js";
|
|
21
|
-
export declare function parseHtml(
|
|
21
|
+
export declare function parseHtml(html_: string): [string, MessageEntity[]];
|
|
22
|
+
export declare function parseAttributes(attributes: string[]): Record<string, string>;
|
|
22
23
|
//# sourceMappingURL=0_html.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"0_html.d.ts","sourceRoot":"","sources":["../../src/client/0_html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"0_html.d.ts","sourceRoot":"","sources":["../../src/client/0_html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAA2B,MAAM,eAAe,CAAC;AAuC5E,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,EAAE,CAAC,CA6NlE;AACD,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAyD5E"}
|
package/script/client/0_html.js
CHANGED
|
@@ -20,86 +20,437 @@
|
|
|
20
20
|
*/
|
|
21
21
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
22
|
exports.parseHtml = parseHtml;
|
|
23
|
-
|
|
23
|
+
exports.parseAttributes = parseAttributes;
|
|
24
24
|
const _0_errors_js_1 = require("../0_errors.js");
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
const TAG_NAMES = [
|
|
26
|
+
"a",
|
|
27
|
+
"b",
|
|
28
|
+
"strong",
|
|
29
|
+
"i",
|
|
30
|
+
"em",
|
|
31
|
+
"s",
|
|
32
|
+
"strike",
|
|
33
|
+
"del",
|
|
34
|
+
"u",
|
|
35
|
+
"ins",
|
|
36
|
+
"tg-spoiler",
|
|
37
|
+
"tg-emoji",
|
|
38
|
+
"span",
|
|
39
|
+
"pre",
|
|
40
|
+
"code",
|
|
41
|
+
"blockquote",
|
|
42
|
+
];
|
|
43
|
+
const ENTITY_TYPES = [
|
|
44
|
+
"textLink",
|
|
45
|
+
"bold",
|
|
46
|
+
"bold",
|
|
47
|
+
"italic",
|
|
48
|
+
"italic",
|
|
49
|
+
"strikethrough",
|
|
50
|
+
"strikethrough",
|
|
51
|
+
"strikethrough",
|
|
52
|
+
"underline",
|
|
53
|
+
"underline",
|
|
54
|
+
"spoiler",
|
|
55
|
+
"customEmoji",
|
|
56
|
+
"spoiler",
|
|
57
|
+
"code",
|
|
58
|
+
"code",
|
|
59
|
+
"blockquote",
|
|
60
|
+
];
|
|
61
|
+
function parseHtml(html_) {
|
|
62
|
+
html_ = html_.trim();
|
|
27
63
|
let text = "";
|
|
28
|
-
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
64
|
+
let entities = new Array();
|
|
65
|
+
const entityTags = new Array();
|
|
66
|
+
const tagStack = new Array();
|
|
67
|
+
const html = Array.from(html_);
|
|
68
|
+
for (let i = 0; i < html.length; ++i) {
|
|
69
|
+
const c = html[i];
|
|
70
|
+
if (c === "&") {
|
|
71
|
+
const result = decodeEntity(html, i);
|
|
72
|
+
[text, i] = [text + result[0], i + result[1]];
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
else if (c !== "<") {
|
|
76
|
+
text += c;
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
++i;
|
|
80
|
+
let closing = false;
|
|
81
|
+
let end = i;
|
|
82
|
+
if (html[end] && html[end] === "/") {
|
|
83
|
+
closing = true;
|
|
84
|
+
++i;
|
|
85
|
+
++end;
|
|
86
|
+
}
|
|
87
|
+
while (html[end] && html[end] !== ">") {
|
|
88
|
+
++end;
|
|
89
|
+
}
|
|
90
|
+
const tagName_ = html.slice(i, end);
|
|
91
|
+
let tagName = tagName_.join("");
|
|
92
|
+
let attributes;
|
|
93
|
+
if (closing) {
|
|
94
|
+
tagName = tagName.trim().toLowerCase();
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const index = tagName_.indexOf(" ");
|
|
98
|
+
if (index !== -1) {
|
|
99
|
+
attributes = parseAttributes(tagName_.slice(index));
|
|
100
|
+
tagName = tagName.slice(0, index).toLowerCase();
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
tagName = tagName.toLowerCase();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (closing && !tagName.length && tagStack.length) {
|
|
107
|
+
tagName = tagStack[tagStack.length - 1].tagName;
|
|
108
|
+
}
|
|
109
|
+
if (!tagName.length) {
|
|
110
|
+
throw new _0_errors_js_1.InputError(`Invalid tag at offset ${i}.`);
|
|
111
|
+
}
|
|
112
|
+
else if (!TAG_NAMES.includes(tagName)) {
|
|
113
|
+
throw new _0_errors_js_1.InputError(`Unsupported HTML tag at offset ${i}: ${tagName}`);
|
|
114
|
+
}
|
|
115
|
+
else if (closing) {
|
|
116
|
+
const openTag = tagStack.pop();
|
|
117
|
+
if (openTag?.tagName !== tagName) {
|
|
118
|
+
throw new _0_errors_js_1.InputError(`Unexpected closing tag at offset ${i}.`);
|
|
119
|
+
}
|
|
120
|
+
const offset = openTag.openedAt;
|
|
121
|
+
const length = text.length - openTag.openedAt;
|
|
122
|
+
if (tagName === "a") {
|
|
123
|
+
let url = openTag.url;
|
|
124
|
+
if (!url) {
|
|
125
|
+
const text_ = text.slice(offset, offset + length);
|
|
126
|
+
try {
|
|
127
|
+
url = new URL(text_).href;
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
if (!Array.from(text).some(isSpace)) {
|
|
131
|
+
try {
|
|
132
|
+
url = new URL(`http://${text_}`).href;
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
//
|
|
136
|
+
}
|
|
137
|
+
}
|
|
53
138
|
}
|
|
54
|
-
stack.push({ type: "textLink", offset: text.length, length: 0, url });
|
|
55
|
-
break;
|
|
56
139
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
140
|
+
if (url) {
|
|
141
|
+
entities.push({
|
|
142
|
+
type: "textLink",
|
|
143
|
+
offset,
|
|
144
|
+
length,
|
|
145
|
+
url,
|
|
146
|
+
});
|
|
147
|
+
entityTags.push(openTag);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else if (tagName === "pre") {
|
|
151
|
+
const lastEntity = entities[entities.length - 1];
|
|
152
|
+
const entityTag = entityTags[entityTags.length - 1];
|
|
153
|
+
if (lastEntity && lastEntity.type === "code" && lastEntity.offset === offset && lastEntity.length === length && entityTag.language) {
|
|
154
|
+
entities[entities.length - 1] = {
|
|
155
|
+
type: "pre",
|
|
156
|
+
offset: lastEntity.offset,
|
|
157
|
+
length: lastEntity.length,
|
|
158
|
+
language: entityTag.language,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
entities.push({
|
|
163
|
+
type: "pre",
|
|
164
|
+
offset,
|
|
165
|
+
length,
|
|
166
|
+
language: "",
|
|
167
|
+
});
|
|
168
|
+
entityTags.push(openTag);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
else if (tagName === "code") {
|
|
172
|
+
const lastEntity = entities[entities.length - 1];
|
|
173
|
+
if (lastEntity && lastEntity.type === "pre" && lastEntity.offset === offset && lastEntity.length === length && openTag.language) {
|
|
174
|
+
lastEntity.language = openTag.language;
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
entities.push({
|
|
178
|
+
type: "code",
|
|
179
|
+
offset,
|
|
180
|
+
length,
|
|
181
|
+
});
|
|
182
|
+
entityTags.push(openTag);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
else if (openTag.userId !== undefined) {
|
|
186
|
+
entities.push({
|
|
187
|
+
type: "textMention",
|
|
188
|
+
offset,
|
|
189
|
+
length,
|
|
190
|
+
userId: openTag.userId,
|
|
191
|
+
});
|
|
192
|
+
entityTags.push(openTag);
|
|
193
|
+
}
|
|
194
|
+
else if (tagName === "blockquote") {
|
|
195
|
+
const entity = {
|
|
196
|
+
type: "blockquote",
|
|
197
|
+
offset,
|
|
198
|
+
length,
|
|
199
|
+
};
|
|
200
|
+
if (openTag.collapsible) {
|
|
201
|
+
entity.collapsible = true;
|
|
202
|
+
}
|
|
203
|
+
entities.push(entity);
|
|
204
|
+
entityTags.push(openTag);
|
|
205
|
+
if (openTag.collapsible) {
|
|
206
|
+
entities[entities.length - 1].collapsible = true;
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
else if (openTag.customEmojiId !== undefined) {
|
|
210
|
+
entities.push({
|
|
211
|
+
type: "customEmoji",
|
|
212
|
+
offset,
|
|
213
|
+
length,
|
|
214
|
+
customEmojiId: openTag.customEmojiId,
|
|
215
|
+
});
|
|
216
|
+
entityTags.push(openTag);
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
entities.push({
|
|
220
|
+
type: ENTITY_TYPES[TAG_NAMES.indexOf(openTag.tagName)],
|
|
221
|
+
offset,
|
|
222
|
+
length,
|
|
223
|
+
});
|
|
224
|
+
entityTags.push(openTag);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else if (tagName === "span" && attributes?.class !== "tg-spoiler") {
|
|
228
|
+
throw new _0_errors_js_1.InputError(`Invalid or missing attribute class for tag span at offset ${i}.`);
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
let url;
|
|
232
|
+
let language;
|
|
233
|
+
let userId;
|
|
234
|
+
let collapsible;
|
|
235
|
+
let customEmojiId;
|
|
236
|
+
if (tagName === "a") {
|
|
237
|
+
url = attributes?.href;
|
|
238
|
+
if (url) {
|
|
239
|
+
let url_;
|
|
240
|
+
try {
|
|
241
|
+
url_ = new URL(url);
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
try {
|
|
245
|
+
url_ = new URL(`http://${url}`);
|
|
246
|
+
url = url_.href;
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
throw new _0_errors_js_1.InputError(`Invalid URL specified for tag a at offset ${i}.`);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (url_.protocol !== "tg:" && url_.protocol !== "ton:" && url_.protocol !== "http:" && url_.protocol !== "https:") {
|
|
253
|
+
throw new _0_errors_js_1.InputError(`Unsupported URL protocol at offset ${i}: ${url_.protocol}`);
|
|
254
|
+
}
|
|
255
|
+
if (url_.protocol === "tg:" && url_.hostname === "user") {
|
|
256
|
+
const id = Number(url_.searchParams.get("id"));
|
|
257
|
+
if (!isNaN(id) && id > 0) {
|
|
258
|
+
userId = id;
|
|
259
|
+
url = undefined;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
throw new _0_errors_js_1.InputError(`Invalid ID specified for mention at offset ${i}.`);
|
|
263
|
+
}
|
|
68
264
|
}
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
else if (tagName === "code") {
|
|
268
|
+
language = attributes?.class?.replace("language-", "");
|
|
269
|
+
}
|
|
270
|
+
else if (tagName === "blockquote" && attributes?.expandable !== undefined) {
|
|
271
|
+
collapsible = true;
|
|
272
|
+
}
|
|
273
|
+
else if (tagName === "tg-emoji") {
|
|
274
|
+
customEmojiId = attributes?.["emoji-id"];
|
|
275
|
+
let valid;
|
|
276
|
+
try {
|
|
277
|
+
valid = BigInt(customEmojiId ?? "") !== 0n;
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
valid = false;
|
|
281
|
+
}
|
|
282
|
+
if (!valid) {
|
|
283
|
+
throw new _0_errors_js_1.InputError(`Invalid emoji-id specified for tag tg-emoji at offset ${i}.`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
tagStack.push({ tagName, openedAt: text.length, url, language, userId, collapsible, customEmojiId });
|
|
287
|
+
}
|
|
288
|
+
i += end - i;
|
|
289
|
+
}
|
|
290
|
+
entities = entities.filter((v) => v.length);
|
|
291
|
+
entities = sortEntities(entities);
|
|
292
|
+
return [text, entities];
|
|
293
|
+
}
|
|
294
|
+
function parseAttributes(attributes) {
|
|
295
|
+
const parsed = {};
|
|
296
|
+
for (let i = 0; i < attributes.length; ++i) {
|
|
297
|
+
const c = attributes[i];
|
|
298
|
+
if (isSpace(c)) {
|
|
299
|
+
continue;
|
|
300
|
+
}
|
|
301
|
+
let end = i;
|
|
302
|
+
while (attributes[end] && !isSpace(attributes[end]) && attributes[end] !== "=") {
|
|
303
|
+
++end;
|
|
304
|
+
}
|
|
305
|
+
const name = attributes.slice(i, end);
|
|
306
|
+
while (attributes[end] && isSpace(attributes[end])) {
|
|
307
|
+
++end;
|
|
308
|
+
}
|
|
309
|
+
let value = new Array();
|
|
310
|
+
if (attributes[end] === "=") {
|
|
311
|
+
++end;
|
|
312
|
+
while (attributes[end] && isSpace(attributes[end])) {
|
|
313
|
+
++end;
|
|
314
|
+
}
|
|
315
|
+
if (attributes[end]) {
|
|
316
|
+
const isQuote = attributes[end] === '"' || attributes[end] === "'";
|
|
317
|
+
if (!isQuote) {
|
|
318
|
+
const valueStart = end;
|
|
319
|
+
++end;
|
|
320
|
+
while (attributes[end] && !isSpace(attributes[end])) {
|
|
321
|
+
++end;
|
|
76
322
|
}
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
323
|
+
value = attributes.slice(valueStart, end);
|
|
324
|
+
}
|
|
325
|
+
else {
|
|
326
|
+
const quote = attributes[end];
|
|
327
|
+
++end;
|
|
328
|
+
const valueStart = end;
|
|
329
|
+
while (attributes[end] && attributes[end] !== quote) {
|
|
330
|
+
++end;
|
|
83
331
|
}
|
|
332
|
+
value = attributes.slice(valueStart, end);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
let value_ = "";
|
|
337
|
+
for (let i = 0; i < value.length; ++i) {
|
|
338
|
+
const c = value[i];
|
|
339
|
+
if (c === "&") {
|
|
340
|
+
const result = decodeEntity(value, i);
|
|
341
|
+
[value_, i] = [value_ + result[0], i + result[1]];
|
|
84
342
|
}
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (!text.length) {
|
|
88
|
-
data = data.trimStart();
|
|
343
|
+
else {
|
|
344
|
+
value_ += c;
|
|
89
345
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
346
|
+
}
|
|
347
|
+
parsed[name.join("")] = value_;
|
|
348
|
+
i += end - i;
|
|
349
|
+
}
|
|
350
|
+
return parsed;
|
|
351
|
+
}
|
|
352
|
+
function decodeEntity(html, i) {
|
|
353
|
+
let text = "";
|
|
354
|
+
let end = i + 1;
|
|
355
|
+
let fallback = false;
|
|
356
|
+
if (html[end] === "#") {
|
|
357
|
+
++end;
|
|
358
|
+
let code;
|
|
359
|
+
if (html[end] === "x") {
|
|
360
|
+
++end;
|
|
361
|
+
while (isHex(html[end])) {
|
|
362
|
+
++end;
|
|
93
363
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
364
|
+
const hex = html.slice(i + 3, end).join("");
|
|
365
|
+
code = parseInt(hex, 16);
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
while (isDigit(html[end])) {
|
|
369
|
+
++end;
|
|
99
370
|
}
|
|
100
|
-
|
|
371
|
+
const code_ = html.slice(i + 2, end).join("");
|
|
372
|
+
code = parseInt(code_);
|
|
373
|
+
}
|
|
374
|
+
if (!isNaN(code) && code !== 0 && code < 0x10ffff && end - i < 10) {
|
|
375
|
+
text = String.fromCharCode(code);
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
fallback = true;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
else {
|
|
382
|
+
while (isAlpha(html[end])) {
|
|
383
|
+
++end;
|
|
384
|
+
}
|
|
385
|
+
const name = html.slice(i + 1, end).join("");
|
|
386
|
+
switch (name) {
|
|
387
|
+
case "amp":
|
|
388
|
+
text = "&";
|
|
389
|
+
break;
|
|
390
|
+
case "quot":
|
|
391
|
+
text = '"';
|
|
392
|
+
break;
|
|
393
|
+
case "lt":
|
|
394
|
+
text = "<";
|
|
395
|
+
break;
|
|
396
|
+
case "gt":
|
|
397
|
+
text = ">";
|
|
398
|
+
break;
|
|
399
|
+
default:
|
|
400
|
+
fallback = true;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
if (html[end] === ";") {
|
|
404
|
+
++end;
|
|
405
|
+
}
|
|
406
|
+
if (fallback) {
|
|
407
|
+
text = html.slice(i, end).join("");
|
|
408
|
+
}
|
|
409
|
+
return [text, end - i - 1];
|
|
410
|
+
}
|
|
411
|
+
function isAlpha(string) {
|
|
412
|
+
return "a" <= string && string <= "z";
|
|
413
|
+
}
|
|
414
|
+
function isDigit(string) {
|
|
415
|
+
return "0" <= string && string <= "9";
|
|
416
|
+
}
|
|
417
|
+
function isHex(string) {
|
|
418
|
+
return isDigit(string) || ("a" <= string && string <= "f");
|
|
419
|
+
}
|
|
420
|
+
function isSpace(string) {
|
|
421
|
+
return string === " " || string === "\t" || string === "\r" || string === "\n" || string === "\0" || string === "\v";
|
|
422
|
+
}
|
|
423
|
+
function sortEntities(entities) {
|
|
424
|
+
return entities.sort(({ offset, type, length }, other) => {
|
|
425
|
+
if (offset !== other.offset) {
|
|
426
|
+
return offset < other.offset ? -1 : 1;
|
|
427
|
+
}
|
|
428
|
+
if (length !== other.length) {
|
|
429
|
+
return length > other.length ? -1 : 1;
|
|
430
|
+
}
|
|
431
|
+
const priority = ENTITY_TYPE_PRIORITIES[type];
|
|
432
|
+
const otherPriority = ENTITY_TYPE_PRIORITIES[other.type];
|
|
433
|
+
return priority < otherPriority ? -1 : 1;
|
|
101
434
|
});
|
|
102
|
-
parser.write(html);
|
|
103
|
-
parser.end();
|
|
104
|
-
return [text, entities];
|
|
105
435
|
}
|
|
436
|
+
const ENTITY_TYPE_PRIORITIES = {
|
|
437
|
+
"mention": 50,
|
|
438
|
+
"hashtag": 50,
|
|
439
|
+
"botCommand": 50,
|
|
440
|
+
"url": 50,
|
|
441
|
+
"email": 50,
|
|
442
|
+
"bold": 90,
|
|
443
|
+
"italic": 91,
|
|
444
|
+
"code": 20,
|
|
445
|
+
"pre": 11,
|
|
446
|
+
"textLink": 49,
|
|
447
|
+
"textMention": 49,
|
|
448
|
+
"cashtag": 50,
|
|
449
|
+
"phoneNumber": 50,
|
|
450
|
+
"underline": 92,
|
|
451
|
+
"strikethrough": 93,
|
|
452
|
+
"blockquote": 0,
|
|
453
|
+
"bankCard": 50,
|
|
454
|
+
"spoiler": 94,
|
|
455
|
+
"customEmoji": 99,
|
|
456
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"0_html_test.d.ts","sourceRoot":"","sources":["../../src/client/0_html_test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,2BAA2B,CAAC"}
|