-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathpsl.ts
More file actions
64 lines (53 loc) · 1.76 KB
/
psl.ts
File metadata and controls
64 lines (53 loc) · 1.76 KB
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
/**
* Build psl tree
*/
import { type PslTree } from '@util/psl'
import axios from 'axios'
import { writeFileSync } from 'fs'
import path from 'path'
import punycode from "punycode/"
const LIST_URL = "https://publicsuffix.org/list/effective_tld_names.dat"
const JSON_PATH = path.join(__dirname, "..", "src", "util", "psl", "rules.json")
const downloadList = async (): Promise<string> => {
const response = await axios.get(LIST_URL)
return response.data
}
const parse = (tree: PslTree, parts: string[], index: number) => {
if (index < 0) return
const part = parts[index]
const ascii = punycode.toASCII(part)
let node = tree[ascii]
if (index === 0) {
if (!node) tree[ascii] = 1
if (typeof node === "object") node.l = 1
} else {
if (!node) tree[ascii] = node = { c: {} } satisfies PslTree
if (node === 1) tree[ascii] = node = { c: {}, l: 1 }
const subTree = (node as PslTree).c as PslTree
parse(subTree, parts, index - 1)
}
}
const sortByKey = (tree: PslTree): PslTree => {
if (!tree) return tree
const newTree: PslTree = {}
Object.entries(tree)
.sort((a, b) => a[0].localeCompare(b[0]))
.forEach(([k, v]) => newTree[k] = typeof v === 'number' ? v : sortByKey(v))
return newTree
}
async function main() {
const list = await downloadList()
const lines = list.split("\n")
.filter(l => !l.startsWith("//"))
.map(l => l.trim())
.filter(l => !!l)
let tree: PslTree = {}
lines.forEach(line => {
const parts = line.split('.')
parse(tree, parts, parts.length - 1)
console.log("Parsed " + line)
})
tree = sortByKey(tree)
writeFileSync(JSON_PATH, JSON.stringify(tree, null, 4), { encoding: "utf-8" })
}
main()