-
Notifications
You must be signed in to change notification settings - Fork 0
/
types.ts
104 lines (90 loc) · 3.25 KB
/
types.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
const then = performance.now();
import { parse } from "https://deno.land/x/[email protected]/mod.ts";
import { Document, DOMParser, Element } from "jsr:@b-fuze/[email protected]";
import TurndownService from "npm:turndown";
const turndownService = new TurndownService();
async function load(url: string) {
const data = await fetch(url).then((v) => v.text());
const document = new DOMParser().parseFromString(data, "text/html")!;
for (const a of document.getElementsByTagName("a")) {
const href = a.getAttribute("href");
if (href?.startsWith("/")) {
a.setAttribute("href", new URL(href, "https://core.telegram.org").href);
}
}
return document;
}
function getParameters(
document: Document,
): Record<string, { type: string; doc: string }> {
let node = document.getElementById("parameters")?.parentElement?.nextSibling;
while (node?.nodeType == node?.TEXT_NODE) {
node = node?.nextSibling;
}
const table = (node as Element) ?? null;
return Object.fromEntries([
...(table?.querySelector("tbody")
?.getElementsByTagName("tr") ?? []),
]
.map((v) => {
const cells = [...v.getElementsByTagName("td")];
return [cells[0].innerText, {
type: cells[1].innerText,
doc: turndownService.turndown(cells[2].innerHTML),
}];
}));
}
function getDoc(document: Document) {
return turndownService.turndown(
document.getElementById("dev_page_content")?.querySelector("p")?.innerHTML,
) ?? "";
}
export async function fetchType(
name: string,
): Promise<{ doc: string; parameters: ReturnType<typeof getParameters> }> {
const document = await load(`https://core.telegram.org/constructor/${name}`);
return {
doc: getDoc(document),
parameters: getParameters(document),
};
}
export async function fetchFunction(
name: string,
): Promise<{ doc: string; parameters: ReturnType<typeof getParameters> }> {
const document = await load(`https://core.telegram.org/method/${name}`);
return {
doc: getDoc(document),
parameters: getParameters(document),
};
}
const apiContent = Deno.readTextFileSync("api.tl");
const { constructors, functions: functions_ } = parse(apiContent);
if (!Deno.args.includes("--skip-types")) {
const types = {} as Record<string, Awaited<ReturnType<typeof fetchType>>>;
for (const [i, constructor] of constructors.entries()) {
if (!(constructor.predicate in types)) {
try {
types[constructor.predicate] = await fetchType(constructor.predicate);
} catch (err) {
console.error(`Failed to fetch type ${constructor.predicate}:`, err);
}
}
console.log(`${i + 1}/${constructors.length}`);
}
Deno.writeTextFileSync("types.json", JSON.stringify(types, null, 2));
}
if (!Deno.args.includes("--skip-functions")) {
const functions = {} as Record<string, Awaited<ReturnType<typeof fetchType>>>;
for (const [i, func] of functions_.entries()) {
if (!(func.func in functions)) {
try {
functions[func.func] = await fetchFunction(func.func);
} catch (err) {
console.error(`Failed to fetch function ${func.func}:`, err);
}
}
console.log(`${i + 1}/${functions_.length}`);
}
Deno.writeTextFileSync("functions.json", JSON.stringify(functions, null, 2));
}
console.log("Done in", `${performance.now() - then}ms.`);