@mt-tl/tl 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +40 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +47 -0
- package/dist/cli.js.map +1 -0
- package/dist/codegen/gen-types.d.ts +10 -0
- package/dist/codegen/gen-types.d.ts.map +1 -0
- package/dist/codegen/gen-types.js +190 -0
- package/dist/codegen/gen-types.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +63 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +147 -0
- package/dist/logger.js.map +1 -0
- package/dist/migrate.d.ts +37 -0
- package/dist/migrate.d.ts.map +1 -0
- package/dist/migrate.js +84 -0
- package/dist/migrate.js.map +1 -0
- package/dist/rpc.d.ts +74 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +2 -0
- package/dist/rpc.js.map +1 -0
- package/dist/tl/crc32.d.ts +2 -0
- package/dist/tl/crc32.d.ts.map +1 -0
- package/dist/tl/crc32.js +42 -0
- package/dist/tl/crc32.js.map +1 -0
- package/dist/tl/ir.d.ts +68 -0
- package/dist/tl/ir.d.ts.map +1 -0
- package/dist/tl/ir.js +63 -0
- package/dist/tl/ir.js.map +1 -0
- package/dist/tl/parser.d.ts +22 -0
- package/dist/tl/parser.d.ts.map +1 -0
- package/dist/tl/parser.js +122 -0
- package/dist/tl/parser.js.map +1 -0
- package/dist/tl/value.d.ts +26 -0
- package/dist/tl/value.d.ts.map +1 -0
- package/dist/tl/value.js +44 -0
- package/dist/tl/value.js.map +1 -0
- package/dist/tools/freeze-layer.d.ts +26 -0
- package/dist/tools/freeze-layer.d.ts.map +1 -0
- package/dist/tools/freeze-layer.js +86 -0
- package/dist/tools/freeze-layer.js.map +1 -0
- package/dist/wire.d.ts +12 -0
- package/dist/wire.d.ts.map +1 -0
- package/dist/wire.js +50 -0
- package/dist/wire.js.map +1 -0
- package/package.json +76 -0
- package/schema/scheme_0_protocol.tl +150 -0
- package/src/cli.ts +48 -0
- package/src/codegen/gen-types.ts +203 -0
- package/src/index.ts +22 -0
- package/src/logger.ts +210 -0
- package/src/migrate.ts +101 -0
- package/src/rpc.ts +70 -0
- package/src/tl/crc32.ts +44 -0
- package/src/tl/ir.ts +105 -0
- package/src/tl/parser.ts +144 -0
- package/src/tl/value.ts +60 -0
- package/src/tools/freeze-layer.ts +108 -0
- package/src/wire.ts +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.d.ts","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,OAAO,EAAE,MAAM,eAAe,CAAA;AAEtD;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9D,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACnE;AAED;;;;;;;;;GASG;AACH,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,WAAW,CAAqC;IAExD,6EAA6E;IAC7E,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,IAAI;IAQzD,GAAG,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;IAI/B,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,0EAA0E;IAC1E,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO;IAI9C,0DAA0D;IAC1D,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IAK9C,OAAO,CAAC,OAAO;IAaf,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,UAAU;CAWrB"}
|
package/dist/migrate.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-predicate migration ladders. The gateway normalizes inbound values to the
|
|
3
|
+
* canonical (newest) shape (`up`) before forwarding, and renders canonical values
|
|
4
|
+
* down to a client's layer (`down`) before encoding — so workers only ever see
|
|
5
|
+
* the canonical shape. Scales to N versions: one rung per version; adding a
|
|
6
|
+
* version appends a rung and never touches the others.
|
|
7
|
+
*
|
|
8
|
+
* Only non-additively-changed predicates need a ladder; everything else is
|
|
9
|
+
* handled by decode-union + layered-encode with no rungs (identity here).
|
|
10
|
+
*/
|
|
11
|
+
export class MigrationRegistry {
|
|
12
|
+
byPredicate = new Map();
|
|
13
|
+
/** Register a predicate's ladder (rungs in any order; sorted by `since`). */
|
|
14
|
+
register(predicate, rungs) {
|
|
15
|
+
this.byPredicate.set(predicate, [...rungs].sort((a, b) => a.since - b.since));
|
|
16
|
+
return this;
|
|
17
|
+
}
|
|
18
|
+
has(predicate) {
|
|
19
|
+
return this.byPredicate.has(predicate);
|
|
20
|
+
}
|
|
21
|
+
get size() {
|
|
22
|
+
return this.byPredicate.size;
|
|
23
|
+
}
|
|
24
|
+
/** Normalize a value decoded at `fromLayer` up to the canonical shape. */
|
|
25
|
+
up(value, fromLayer) {
|
|
26
|
+
return this.recurse(value, obj => this.upObject(obj, fromLayer));
|
|
27
|
+
}
|
|
28
|
+
/** Render a canonical value down to `toLayer`'s shape. */
|
|
29
|
+
down(value, toLayer) {
|
|
30
|
+
return this.recurse(value, obj => this.downObject(obj, toLayer));
|
|
31
|
+
}
|
|
32
|
+
// Children-first walk: normalize nested objects, then transform the parent.
|
|
33
|
+
recurse(value, fn) {
|
|
34
|
+
if (Array.isArray(value))
|
|
35
|
+
return value.map(v => this.recurse(v, fn));
|
|
36
|
+
if (value && typeof value === 'object' && !Buffer.isBuffer(value) && '_' in value) {
|
|
37
|
+
const obj = value;
|
|
38
|
+
const next = { _: obj._ };
|
|
39
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
40
|
+
if (k !== '_')
|
|
41
|
+
next[k] = this.recurse(v, fn);
|
|
42
|
+
}
|
|
43
|
+
return fn(next);
|
|
44
|
+
}
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
upObject(obj, fromLayer) {
|
|
48
|
+
const rungs = this.byPredicate.get(obj._);
|
|
49
|
+
if (!rungs)
|
|
50
|
+
return obj;
|
|
51
|
+
let cur = obj;
|
|
52
|
+
for (let i = startRung(rungs, fromLayer); i <= rungs.length - 2; i++) {
|
|
53
|
+
const up = rungs[i].up;
|
|
54
|
+
if (up)
|
|
55
|
+
cur = up(cur);
|
|
56
|
+
}
|
|
57
|
+
return cur;
|
|
58
|
+
}
|
|
59
|
+
downObject(obj, toLayer) {
|
|
60
|
+
const rungs = this.byPredicate.get(obj._);
|
|
61
|
+
if (!rungs)
|
|
62
|
+
return obj;
|
|
63
|
+
const target = startRung(rungs, toLayer);
|
|
64
|
+
let cur = obj;
|
|
65
|
+
for (let i = rungs.length - 2; i >= target; i--) {
|
|
66
|
+
const down = rungs[i].down;
|
|
67
|
+
if (down)
|
|
68
|
+
cur = down(cur);
|
|
69
|
+
}
|
|
70
|
+
return cur;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
/** Index of the rung active at `layer` (the latest with since <= layer; else 0). */
|
|
74
|
+
function startRung(rungs, layer) {
|
|
75
|
+
let idx = 0;
|
|
76
|
+
for (let i = 0; i < rungs.length; i++) {
|
|
77
|
+
if (rungs[i].since <= layer)
|
|
78
|
+
idx = i;
|
|
79
|
+
else
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
return idx;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=migrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
|
package/dist/rpc.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import type { JsonValue } from './tl/value.js';
|
|
2
|
+
/** Per-request connection context the engine attaches to every business call; surfaced as `ctx.request`. */
|
|
3
|
+
export interface RpcContext {
|
|
4
|
+
/** The MTProto session id (hex). */
|
|
5
|
+
sessionId: string;
|
|
6
|
+
/** The connection's auth key id (hex). */
|
|
7
|
+
authKeyId: string;
|
|
8
|
+
/**
|
|
9
|
+
* The **subject** bound to this auth key — your app's *internal* user id,
|
|
10
|
+
* opaque to the framework and safe to share across your services (e.g. a
|
|
11
|
+
* uuid). Set it via `ctx.login(subject)`; `undefined` for an anonymous key.
|
|
12
|
+
*
|
|
13
|
+
* This is deliberately NOT the wire `user_id` your TL schema exposes to
|
|
14
|
+
* clients (Telegram-style `int`/`long`). The framework only routes/persists
|
|
15
|
+
* by `subject`; mapping `subject ⇄ public user_id` is your app's job (see the
|
|
16
|
+
* demo's `users` module). Keeping them separate lets the public id stay an
|
|
17
|
+
* `int` while the protocol runs entirely on your internal id.
|
|
18
|
+
*/
|
|
19
|
+
subject?: string;
|
|
20
|
+
/** The client's negotiated TL layer. */
|
|
21
|
+
apiLayer: number;
|
|
22
|
+
/** `initConnection.api_id` — the client app id, if reported. */
|
|
23
|
+
apiId?: number;
|
|
24
|
+
/** `initConnection.device_model`, if reported. */
|
|
25
|
+
deviceModel?: string;
|
|
26
|
+
/** `initConnection.system_version`, if reported. */
|
|
27
|
+
systemVersion?: string;
|
|
28
|
+
/** `initConnection.app_version`, if reported. */
|
|
29
|
+
appVersion?: string;
|
|
30
|
+
/** `initConnection.lang_code`, if reported. */
|
|
31
|
+
langCode?: string;
|
|
32
|
+
/** Client IP (from the carrier / `X-Forwarded-For`), if known. */
|
|
33
|
+
ip?: string;
|
|
34
|
+
}
|
|
35
|
+
/** A decoded business method call handed to the handler layer. */
|
|
36
|
+
export interface RpcRequest {
|
|
37
|
+
/** Derived from the client's reqMsgId. */
|
|
38
|
+
id: string;
|
|
39
|
+
/** TL method name, e.g. "dust.getConfig". */
|
|
40
|
+
method: string;
|
|
41
|
+
/** Decoded params as tagged JSON (bigint -> {$bigint}, Buffer -> {$bin}). */
|
|
42
|
+
params: JsonValue;
|
|
43
|
+
/** The connection context (see {@link RpcContext}). */
|
|
44
|
+
context: RpcContext;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A side-effect a handler records (via `ctx.login`/`logout`/`revoke`) for the
|
|
48
|
+
* engine to apply to auth-key state, returned alongside the normal result/error.
|
|
49
|
+
* Keeps the engine agnostic to your auth scheme: a `signIn` handler returns
|
|
50
|
+
* `bindUser`, and the engine binds the `subject` (your internal user id) to the
|
|
51
|
+
* auth key.
|
|
52
|
+
*/
|
|
53
|
+
export type SessionEffect = {
|
|
54
|
+
type: 'bindUser';
|
|
55
|
+
subject: string;
|
|
56
|
+
} | {
|
|
57
|
+
type: 'unbindUser';
|
|
58
|
+
} | {
|
|
59
|
+
type: 'revokeKey';
|
|
60
|
+
};
|
|
61
|
+
/**
|
|
62
|
+
* Response envelope (transport-agnostic). Exactly one of `result` / `error` is
|
|
63
|
+
* set; `effects` may accompany either.
|
|
64
|
+
*/
|
|
65
|
+
export interface RpcResponse {
|
|
66
|
+
/** A TL result as tagged JSON ({ _: name, ... }, $bigint/$bin), or a primitive. */
|
|
67
|
+
result?: JsonValue;
|
|
68
|
+
error?: {
|
|
69
|
+
code: number;
|
|
70
|
+
message: string;
|
|
71
|
+
};
|
|
72
|
+
effects?: SessionEffect[];
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=rpc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.d.ts","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAE9C,4GAA4G;AAC5G,MAAM,WAAW,UAAU;IACvB,oCAAoC;IACpC,SAAS,EAAE,MAAM,CAAA;IACjB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;;;;;;OAUG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,wCAAwC;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,oDAAoD;IACpD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iDAAiD;IACjD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,+CAA+C;IAC/C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kEAAkE;IAClE,EAAE,CAAC,EAAE,MAAM,CAAA;CACd;AAED,kEAAkE;AAClE,MAAM,WAAW,UAAU;IACvB,0CAA0C;IAC1C,EAAE,EAAE,MAAM,CAAA;IACV,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAA;IACd,6EAA6E;IAC7E,MAAM,EAAE,SAAS,CAAA;IACjB,uDAAuD;IACvD,OAAO,EAAE,UAAU,CAAA;CACtB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GACnB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,CAAA;AAE3B;;;GAGG;AACH,MAAM,WAAW,WAAW;IACxB,mFAAmF;IACnF,MAAM,CAAC,EAAE,SAAS,CAAA;IAClB,KAAK,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAA;IACzC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAA;CAC5B"}
|
package/dist/rpc.js
ADDED
package/dist/rpc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../src/rpc.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crc32.d.ts","sourceRoot":"","sources":["../../src/tl/crc32.ts"],"names":[],"mappings":"AAuCA,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrD"}
|
package/dist/tl/crc32.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import CRC32 from 'crc-32';
|
|
2
|
+
/**
|
|
3
|
+
* Computes a TL constructor id (crc32 of the normalized definition line),
|
|
4
|
+
* mirroring the existing backend's `get-tl-object-crc32.js` exactly so our
|
|
5
|
+
* validation agrees with the schema's declared ids.
|
|
6
|
+
*
|
|
7
|
+
* Normalization (applied repeatedly until stable):
|
|
8
|
+
* :bytes -> :string
|
|
9
|
+
* ?bytes -> ?string
|
|
10
|
+
* #<hex> -> (constructor id removed)
|
|
11
|
+
* name:flags.N?true -> (removed; presence-only flags don't affect the id)
|
|
12
|
+
* < > and {} and ; -> stripped / spaced
|
|
13
|
+
* collapse double / edge spaces
|
|
14
|
+
*/
|
|
15
|
+
function normalizeSchemaLine(line) {
|
|
16
|
+
const rules = [
|
|
17
|
+
[/:bytes /g, ':string '],
|
|
18
|
+
[/\?bytes /g, '?string '],
|
|
19
|
+
[/#[a-f0-9]+ /g, ' '],
|
|
20
|
+
[/ [a-zA-Z0-9_]+:flags\.[0-9]+\?true/g, ''],
|
|
21
|
+
[/</g, ' '],
|
|
22
|
+
[/>/g, ' '],
|
|
23
|
+
[/;/g, ''],
|
|
24
|
+
[/\{/g, ''],
|
|
25
|
+
[/\}/g, ''],
|
|
26
|
+
];
|
|
27
|
+
let out = line;
|
|
28
|
+
let prev;
|
|
29
|
+
do {
|
|
30
|
+
prev = out;
|
|
31
|
+
for (const [re, to] of rules)
|
|
32
|
+
out = out.replace(re, to);
|
|
33
|
+
out = out.replace(/ {2}/g, ' ').replace(/^ /, '').replace(/ $/, '');
|
|
34
|
+
} while (out !== prev);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
export function getTlObjectCrc32(line) {
|
|
38
|
+
const hashNum = CRC32.bstr(normalizeSchemaLine(line));
|
|
39
|
+
const unsigned = hashNum < 0 ? hashNum + 0x100000000 : hashNum;
|
|
40
|
+
return unsigned.toString(16).padStart(8, '0');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=crc32.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"crc32.js","sourceRoot":"","sources":["../../src/tl/crc32.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,QAAQ,CAAA;AAE1B;;;;;;;;;;;;GAYG;AACH,SAAS,mBAAmB,CAAC,IAAY;IACrC,MAAM,KAAK,GAA4B;QACnC,CAAC,UAAU,EAAE,UAAU,CAAC;QACxB,CAAC,WAAW,EAAE,UAAU,CAAC;QACzB,CAAC,cAAc,EAAE,GAAG,CAAC;QACrB,CAAC,qCAAqC,EAAE,EAAE,CAAC;QAC3C,CAAC,IAAI,EAAE,GAAG,CAAC;QACX,CAAC,IAAI,EAAE,GAAG,CAAC;QACX,CAAC,IAAI,EAAE,EAAE,CAAC;QACV,CAAC,KAAK,EAAE,EAAE,CAAC;QACX,CAAC,KAAK,EAAE,EAAE,CAAC;KACd,CAAA;IAED,IAAI,GAAG,GAAG,IAAI,CAAA;IACd,IAAI,IAAY,CAAA;IAChB,GAAG,CAAC;QACA,IAAI,GAAG,GAAG,CAAA;QACV,KAAK,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,KAAK;YAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;QACvD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;IACvE,CAAC,QAAQ,GAAG,KAAK,IAAI,EAAC;IAEtB,OAAO,GAAG,CAAA;AACd,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IACzC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAA;IACrD,MAAM,QAAQ,GAAG,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAA;IAC9D,OAAO,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AACjD,CAAC"}
|
package/dist/tl/ir.d.ts
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intermediate representation (IR) for the TL schema.
|
|
3
|
+
*
|
|
4
|
+
* A `.tl` file is parsed into a flat list of {@link TlDef} (constructors and
|
|
5
|
+
* methods). Each parameter's textual type is parsed once, at load time, into a
|
|
6
|
+
* structured {@link TlType} so the generic codec can walk it without re-parsing
|
|
7
|
+
* strings on every (de)serialization.
|
|
8
|
+
*/
|
|
9
|
+
export type TlType = {
|
|
10
|
+
kind: 'int';
|
|
11
|
+
} | {
|
|
12
|
+
kind: 'long';
|
|
13
|
+
} | {
|
|
14
|
+
kind: 'double';
|
|
15
|
+
} | {
|
|
16
|
+
kind: 'string';
|
|
17
|
+
} | {
|
|
18
|
+
kind: 'bytes';
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'int128';
|
|
21
|
+
} | {
|
|
22
|
+
kind: 'int256';
|
|
23
|
+
} | {
|
|
24
|
+
kind: 'bool';
|
|
25
|
+
} | {
|
|
26
|
+
kind: 'true';
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'flags';
|
|
29
|
+
} | {
|
|
30
|
+
kind: 'flag';
|
|
31
|
+
flagsField: string;
|
|
32
|
+
bit: number;
|
|
33
|
+
inner: TlType;
|
|
34
|
+
} | {
|
|
35
|
+
kind: 'vector';
|
|
36
|
+
boxed: boolean;
|
|
37
|
+
inner: TlType;
|
|
38
|
+
} | {
|
|
39
|
+
kind: 'object';
|
|
40
|
+
} | {
|
|
41
|
+
kind: 'boxed';
|
|
42
|
+
name: string;
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'bare';
|
|
45
|
+
name: string;
|
|
46
|
+
};
|
|
47
|
+
export interface TlParam {
|
|
48
|
+
name: string;
|
|
49
|
+
/** Original textual type, kept for diagnostics / crc. */
|
|
50
|
+
raw: string;
|
|
51
|
+
type: TlType;
|
|
52
|
+
}
|
|
53
|
+
export interface TlDef {
|
|
54
|
+
/** 8-char lowercase hex constructor id. */
|
|
55
|
+
id: string;
|
|
56
|
+
/** Unsigned 32-bit numeric form of {@link id}. */
|
|
57
|
+
idNum: number;
|
|
58
|
+
/** predicate (constructor) or method name, e.g. `dust.getConfig`. */
|
|
59
|
+
name: string;
|
|
60
|
+
kind: 'constructor' | 'method';
|
|
61
|
+
params: TlParam[];
|
|
62
|
+
/** Boxed result/return type, e.g. `dust.CalculatedExchange`. */
|
|
63
|
+
type: string;
|
|
64
|
+
/** True for the immutable MTProto protocol layer (scheme_0_protocol + core). */
|
|
65
|
+
isProtocol: boolean;
|
|
66
|
+
}
|
|
67
|
+
export declare function parseType(raw: string): TlType;
|
|
68
|
+
//# sourceMappingURL=ir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.d.ts","sourceRoot":"","sources":["../../src/tl/ir.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,MAAM,GACZ;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChE;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpC,MAAM,WAAW,OAAO;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAA;IACX,IAAI,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,KAAK;IAClB,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAA;IACV,kDAAkD;IAClD,KAAK,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,aAAa,GAAG,QAAQ,CAAA;IAC9B,MAAM,EAAE,OAAO,EAAE,CAAA;IACjB,gEAAgE;IAChE,IAAI,EAAE,MAAM,CAAA;IACZ,gFAAgF;IAChF,UAAU,EAAE,OAAO,CAAA;CACtB;AAID,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAsD7C"}
|
package/dist/tl/ir.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Intermediate representation (IR) for the TL schema.
|
|
3
|
+
*
|
|
4
|
+
* A `.tl` file is parsed into a flat list of {@link TlDef} (constructors and
|
|
5
|
+
* methods). Each parameter's textual type is parsed once, at load time, into a
|
|
6
|
+
* structured {@link TlType} so the generic codec can walk it without re-parsing
|
|
7
|
+
* strings on every (de)serialization.
|
|
8
|
+
*/
|
|
9
|
+
const PRIMITIVES = new Set(['int', 'long', 'double', 'string', 'bytes', 'int128', 'int256', 'Bool', 'true']);
|
|
10
|
+
export function parseType(raw) {
|
|
11
|
+
const t = raw.trim();
|
|
12
|
+
if (t === '#')
|
|
13
|
+
return { kind: 'flags' };
|
|
14
|
+
// conditional field: <flagsField>.<bit>?<inner>, e.g. api_hash:flags.1?string
|
|
15
|
+
const cond = t.match(/^(\w+)\.(\d+)\?(.+)$/);
|
|
16
|
+
if (cond) {
|
|
17
|
+
return {
|
|
18
|
+
kind: 'flag',
|
|
19
|
+
flagsField: cond[1],
|
|
20
|
+
bit: Number(cond[2]),
|
|
21
|
+
inner: parseType(cond[3]),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// Vector<T> (boxed) or vector<T> (bare)
|
|
25
|
+
const vec = t.match(/^([Vv])ector<(.+)>$/);
|
|
26
|
+
if (vec) {
|
|
27
|
+
return { kind: 'vector', boxed: vec[1] === 'V', inner: parseType(vec[2]) };
|
|
28
|
+
}
|
|
29
|
+
if (PRIMITIVES.has(t)) {
|
|
30
|
+
switch (t) {
|
|
31
|
+
case 'int':
|
|
32
|
+
return { kind: 'int' };
|
|
33
|
+
case 'long':
|
|
34
|
+
return { kind: 'long' };
|
|
35
|
+
case 'double':
|
|
36
|
+
return { kind: 'double' };
|
|
37
|
+
case 'string':
|
|
38
|
+
return { kind: 'string' };
|
|
39
|
+
case 'bytes':
|
|
40
|
+
return { kind: 'bytes' };
|
|
41
|
+
case 'int128':
|
|
42
|
+
return { kind: 'int128' };
|
|
43
|
+
case 'int256':
|
|
44
|
+
return { kind: 'int256' };
|
|
45
|
+
case 'Bool':
|
|
46
|
+
return { kind: 'bool' };
|
|
47
|
+
case 'true':
|
|
48
|
+
return { kind: 'true' };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
if (t === 'Object' || t === 'X' || t.startsWith('!'))
|
|
52
|
+
return { kind: 'object' };
|
|
53
|
+
if (t.startsWith('%'))
|
|
54
|
+
return { kind: 'bare', name: t.slice(1) };
|
|
55
|
+
// Named type. Boxed iff the final segment is capitalized (e.g. dust.DustBalance,
|
|
56
|
+
// Currency); otherwise a bare constructor reference (e.g. future_salt).
|
|
57
|
+
const lastSeg = t.includes('.') ? t.slice(t.lastIndexOf('.') + 1) : t;
|
|
58
|
+
const first = lastSeg[0] ?? '';
|
|
59
|
+
if (first >= 'A' && first <= 'Z')
|
|
60
|
+
return { kind: 'boxed', name: t };
|
|
61
|
+
return { kind: 'bare', name: t };
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=ir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ir.js","sourceRoot":"","sources":["../../src/tl/ir.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { TlDef } from './ir.js';
|
|
2
|
+
export interface ParsedLine {
|
|
3
|
+
def: TlDef;
|
|
4
|
+
/** declared id differs from the crc32 of the normalized line */
|
|
5
|
+
crcMismatch: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ParseResult {
|
|
8
|
+
defs: TlDef[];
|
|
9
|
+
crcMismatches: Array<{
|
|
10
|
+
name: string;
|
|
11
|
+
id: string;
|
|
12
|
+
computed: string;
|
|
13
|
+
}>;
|
|
14
|
+
}
|
|
15
|
+
export declare function parseTlText(text: string, isProtocol: boolean): ParseResult;
|
|
16
|
+
/**
|
|
17
|
+
* Loads every `*.tl` file from a directory into the IR. `scheme_0_protocol.tl`
|
|
18
|
+
* is flagged as protocol; the manually-parsed MTProto core constructors are
|
|
19
|
+
* merged in. Duplicate constructor ids are de-duplicated (first wins).
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseSchemaDir(dir: string): ParseResult;
|
|
22
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/tl/parser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAW,MAAM,SAAS,CAAA;AAmC7C,MAAM,WAAW,UAAU;IACvB,GAAG,EAAE,KAAK,CAAA;IACV,gEAAgE;IAChE,WAAW,EAAE,OAAO,CAAA;CACvB;AAyBD,MAAM,WAAW,WAAW;IACxB,IAAI,EAAE,KAAK,EAAE,CAAA;IACb,aAAa,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CACvE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,GAAG,WAAW,CA6B1E;AAUD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CA4BvD"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { readdirSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { parseType } from './ir.js';
|
|
4
|
+
import { getTlObjectCrc32 } from './crc32.js';
|
|
5
|
+
const LINE_RE = /^([\w.]+)#([0-9a-fA-F]+)\s*(.*?)\s*=\s*([\w.]+)\s*;\s*$/;
|
|
6
|
+
/**
|
|
7
|
+
* Core MTProto constructors that scheme_0_protocol.tl leaves commented out
|
|
8
|
+
* ("parsed manually"). They still need registry entries for id<->name lookup.
|
|
9
|
+
*/
|
|
10
|
+
const CORE_LINES = [
|
|
11
|
+
{ kind: 'constructor', line: 'vector#1cb5c415 = Vector;' },
|
|
12
|
+
{ kind: 'constructor', line: 'rpc_result#f35c6d01 req_msg_id:long result:Object = RpcResult;' },
|
|
13
|
+
{ kind: 'constructor', line: 'msg_container#73f1f8dc messages:vector<%Message> = MessageContainer;' },
|
|
14
|
+
{
|
|
15
|
+
kind: 'constructor',
|
|
16
|
+
line: 'message#5bb8e511 msg_id:long seqno:int bytes:int body:Object = Message;',
|
|
17
|
+
},
|
|
18
|
+
{ kind: 'constructor', line: 'msg_copy#e06046b2 orig_message:Message = MessageCopy;' },
|
|
19
|
+
{ kind: 'constructor', line: 'gzip_packed#3072cfa1 packed_data:bytes = Object;' },
|
|
20
|
+
];
|
|
21
|
+
function parseParams(paramsStr) {
|
|
22
|
+
if (!paramsStr)
|
|
23
|
+
return [];
|
|
24
|
+
return paramsStr
|
|
25
|
+
.split(/\s+/)
|
|
26
|
+
.filter(tok => tok.includes(':') && !tok.includes('{') && !tok.includes('}'))
|
|
27
|
+
.map(tok => {
|
|
28
|
+
const idx = tok.indexOf(':');
|
|
29
|
+
const name = tok.slice(0, idx);
|
|
30
|
+
const raw = tok.slice(idx + 1);
|
|
31
|
+
return { name, raw, type: parseType(raw) };
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function parseLine(line, kind, isProtocol, validateCrc) {
|
|
35
|
+
const m = line.match(LINE_RE);
|
|
36
|
+
if (!m)
|
|
37
|
+
return null;
|
|
38
|
+
const [, name, hashRaw, paramsStr, type] = m;
|
|
39
|
+
const id = hashRaw.toLowerCase().padStart(8, '0');
|
|
40
|
+
const def = {
|
|
41
|
+
id,
|
|
42
|
+
idNum: parseInt(id, 16) >>> 0,
|
|
43
|
+
name: name,
|
|
44
|
+
kind,
|
|
45
|
+
params: parseParams(paramsStr ?? ''),
|
|
46
|
+
type: type,
|
|
47
|
+
isProtocol,
|
|
48
|
+
};
|
|
49
|
+
const crcMismatch = validateCrc ? getTlObjectCrc32(line.trim()) !== id : false;
|
|
50
|
+
return { def, crcMismatch };
|
|
51
|
+
}
|
|
52
|
+
export function parseTlText(text, isProtocol) {
|
|
53
|
+
const defs = [];
|
|
54
|
+
const crcMismatches = [];
|
|
55
|
+
let kind = 'constructor';
|
|
56
|
+
for (const rawLine of text.split('\n')) {
|
|
57
|
+
const line = rawLine.trim();
|
|
58
|
+
if (!line || line.startsWith('//') || line.startsWith('*') || line.startsWith('/*'))
|
|
59
|
+
continue;
|
|
60
|
+
if (line.includes('---types---')) {
|
|
61
|
+
kind = 'constructor';
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (line.includes('---functions---')) {
|
|
65
|
+
kind = 'method';
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
const parsed = parseLine(line, kind, isProtocol, true);
|
|
69
|
+
if (!parsed)
|
|
70
|
+
continue;
|
|
71
|
+
defs.push(parsed.def);
|
|
72
|
+
if (parsed.crcMismatch) {
|
|
73
|
+
crcMismatches.push({
|
|
74
|
+
name: parsed.def.name,
|
|
75
|
+
id: parsed.def.id,
|
|
76
|
+
computed: getTlObjectCrc32(line),
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return { defs, crcMismatches };
|
|
81
|
+
}
|
|
82
|
+
function parseCoreLines() {
|
|
83
|
+
return CORE_LINES.map(({ kind, line }) => {
|
|
84
|
+
const parsed = parseLine(line, kind, true, false);
|
|
85
|
+
if (!parsed)
|
|
86
|
+
throw new Error(`Failed to parse core line: ${line}`);
|
|
87
|
+
return parsed.def;
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Loads every `*.tl` file from a directory into the IR. `scheme_0_protocol.tl`
|
|
92
|
+
* is flagged as protocol; the manually-parsed MTProto core constructors are
|
|
93
|
+
* merged in. Duplicate constructor ids are de-duplicated (first wins).
|
|
94
|
+
*/
|
|
95
|
+
export function parseSchemaDir(dir) {
|
|
96
|
+
const files = readdirSync(dir)
|
|
97
|
+
.filter(f => f.endsWith('.tl'))
|
|
98
|
+
.sort();
|
|
99
|
+
const seen = new Set();
|
|
100
|
+
const defs = [];
|
|
101
|
+
const crcMismatches = [];
|
|
102
|
+
for (const def of parseCoreLines()) {
|
|
103
|
+
if (seen.has(def.id))
|
|
104
|
+
continue;
|
|
105
|
+
seen.add(def.id);
|
|
106
|
+
defs.push(def);
|
|
107
|
+
}
|
|
108
|
+
for (const file of files) {
|
|
109
|
+
const isProtocol = file === 'scheme_0_protocol.tl';
|
|
110
|
+
const text = readFileSync(join(dir, file), 'utf-8');
|
|
111
|
+
const res = parseTlText(text, isProtocol);
|
|
112
|
+
crcMismatches.push(...res.crcMismatches);
|
|
113
|
+
for (const def of res.defs) {
|
|
114
|
+
if (seen.has(def.id))
|
|
115
|
+
continue;
|
|
116
|
+
seen.add(def.id);
|
|
117
|
+
defs.push(def);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
return { defs, crcMismatches };
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/tl/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-code representation of a decoded TL value.
|
|
3
|
+
*
|
|
4
|
+
* A constructed type is a tagged plain object `{ _: 'predicate.name', ...fields }`
|
|
5
|
+
* (matching the existing `toPrimitiveObject` convention). Wire primitives map to:
|
|
6
|
+
* int -> number, long/flags -> bigint|number, double -> number, string -> string,
|
|
7
|
+
* bytes/int128/int256 -> Buffer, Bool/true -> boolean, vector -> array.
|
|
8
|
+
*/
|
|
9
|
+
export type TlValue = number | bigint | boolean | string | Buffer | TlObject | TlValue[] | null | undefined;
|
|
10
|
+
export interface TlObject {
|
|
11
|
+
_: string;
|
|
12
|
+
[field: string]: TlValue;
|
|
13
|
+
}
|
|
14
|
+
/** JSON-safe encoding so values can cross the JSON-RPC boundary. */
|
|
15
|
+
export type JsonValue = number | boolean | string | null | {
|
|
16
|
+
$bigint: string;
|
|
17
|
+
} | {
|
|
18
|
+
$bin: string;
|
|
19
|
+
} | JsonValue[] | {
|
|
20
|
+
[k: string]: JsonValue;
|
|
21
|
+
};
|
|
22
|
+
export declare function toJson(value: TlValue): JsonValue;
|
|
23
|
+
export declare function fromJson(value: JsonValue): TlValue;
|
|
24
|
+
/** Pretty JSON string for terminal logging (bigint/Buffer made readable). */
|
|
25
|
+
export declare function stringify(value: TlValue, indent?: number): string;
|
|
26
|
+
//# sourceMappingURL=value.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value.d.ts","sourceRoot":"","sources":["../../src/tl/value.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,MAAM,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,EAAE,GAAG,IAAI,GAAG,SAAS,CAAA;AAE3G,MAAM,WAAW,QAAQ;IACrB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CAC3B;AAED,oEAAoE;AACpE,MAAM,MAAM,SAAS,GACf,MAAM,GACN,OAAO,GACP,MAAM,GACN,IAAI,GACJ;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB,SAAS,EAAE,GACX;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAA;AAMhC,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,GAAG,SAAS,CAUhD;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAYlD;AAED,6EAA6E;AAC7E,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,SAAI,GAAG,MAAM,CAE5D"}
|
package/dist/tl/value.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
function isBuffer(v) {
|
|
2
|
+
return Buffer.isBuffer(v);
|
|
3
|
+
}
|
|
4
|
+
export function toJson(value) {
|
|
5
|
+
if (value === null || value === undefined)
|
|
6
|
+
return null;
|
|
7
|
+
if (typeof value === 'bigint')
|
|
8
|
+
return { $bigint: value.toString() };
|
|
9
|
+
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string')
|
|
10
|
+
return value;
|
|
11
|
+
if (isBuffer(value))
|
|
12
|
+
return { $bin: value.toString('base64') };
|
|
13
|
+
if (Array.isArray(value))
|
|
14
|
+
return value.map(toJson);
|
|
15
|
+
// TlObject
|
|
16
|
+
const out = {};
|
|
17
|
+
for (const [k, v] of Object.entries(value))
|
|
18
|
+
out[k] = toJson(v);
|
|
19
|
+
return out;
|
|
20
|
+
}
|
|
21
|
+
export function fromJson(value) {
|
|
22
|
+
if (value === null)
|
|
23
|
+
return null;
|
|
24
|
+
if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'string')
|
|
25
|
+
return value;
|
|
26
|
+
if (Array.isArray(value))
|
|
27
|
+
return value.map(fromJson);
|
|
28
|
+
if (typeof value === 'object') {
|
|
29
|
+
if ('$bigint' in value && typeof value.$bigint === 'string')
|
|
30
|
+
return BigInt(value.$bigint);
|
|
31
|
+
if ('$bin' in value && typeof value.$bin === 'string')
|
|
32
|
+
return Buffer.from(value.$bin, 'base64');
|
|
33
|
+
const out = {};
|
|
34
|
+
for (const [k, v] of Object.entries(value))
|
|
35
|
+
out[k] = fromJson(v);
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
/** Pretty JSON string for terminal logging (bigint/Buffer made readable). */
|
|
41
|
+
export function stringify(value, indent = 2) {
|
|
42
|
+
return JSON.stringify(toJson(value), null, indent);
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=value.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value.js","sourceRoot":"","sources":["../../src/tl/value.ts"],"names":[],"mappings":"AA0BA,SAAS,QAAQ,CAAC,CAAU;IACxB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;AAC7B,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,KAAc;IACjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAA;IACtD,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,EAAE,CAAA;IACnE,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACtG,IAAI,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAA;IAC9D,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;IAClD,WAAW;IACX,MAAM,GAAG,GAA+B,EAAE,CAAA;IAC1C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,GAAG,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,CAAY,CAAC,CAAA;IACzE,OAAO,GAAG,CAAA;AACd,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,KAAgB;IACrC,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,IAAI,CAAA;IAC/B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAA;IACtG,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;IACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC5B,IAAI,SAAS,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,OAAO,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;QACzF,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC/F,MAAM,GAAG,GAA6B,EAAE,CAAA;QACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;YAAE,GAAG,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAc,CAAC,CAAA;QAC7E,OAAO,GAAe,CAAA;IAC1B,CAAC;IACD,OAAO,IAAI,CAAA;AACf,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,SAAS,CAAC,KAAc,EAAE,MAAM,GAAG,CAAC;IAChD,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAA;AACtD,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface FreezeResult {
|
|
2
|
+
constructors: number;
|
|
3
|
+
methods: number;
|
|
4
|
+
/** Path of the JSON snapshot the gateway loads. */
|
|
5
|
+
out: string;
|
|
6
|
+
/** Path of the human-readable `.tl` mirror (not loaded; for inspection/diffs). */
|
|
7
|
+
tlOut: string;
|
|
8
|
+
crcWarnings: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Freezes the `.tl` schema in `schemaDir` into a per-layer snapshot
|
|
12
|
+
* `<outDir>/scheme_<layer>.json` (loaded by the gateway) plus a human-readable
|
|
13
|
+
* `<outDir>/scheme_<layer>.tl` mirror (for inspection/diffs; not loaded). Run
|
|
14
|
+
* this when you SHIP a layer: the `.tl` you edit is the in-progress newest layer;
|
|
15
|
+
* the frozen snapshot is the historical record the gateway uses to encode for
|
|
16
|
+
* clients on that layer.
|
|
17
|
+
*
|
|
18
|
+
* The snapshot is BUSINESS-only: the immutable MTProto protocol/core types are
|
|
19
|
+
* excluded (they live in @mt-tl/tl and are loaded globally), so a business
|
|
20
|
+
* layer never carries protocol definitions.
|
|
21
|
+
*
|
|
22
|
+
* Schema ownership lives in the consumer app, so paths are explicit — apps wrap
|
|
23
|
+
* this in their own `freeze` script.
|
|
24
|
+
*/
|
|
25
|
+
export declare function freezeLayer(schemaDir: string, outDir: string, layer: number): FreezeResult;
|
|
26
|
+
//# sourceMappingURL=freeze-layer.d.ts.map
|