aboutsummaryrefslogtreecommitdiff
path: root/scripts/index.mjs
blob: 576cfb8e0c97ad43b754a9d2f506f47f886efd5b (plain)
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
import { readFile, writeFile } from 'fs/promises'

import centra from 'centra'
import pLimit from 'p-limit'
import { remark } from 'remark'
import remarkGfm from 'remark-gfm'
import { select, selectAll } from 'unist-util-select'

const baseurl = process.argv[2]
const inputFile = process.argv[3]
const outputFile = process.argv[4]

const selector = 'tableCell:first-child inlineCode'
const sortEntries = async tree => {
	const rows = select('table', tree)
	const header = rows.children.shift()

	rows.children.sort((first, second) =>
		select(selector, first).value
			.localeCompare(select(selector, second).value))

	rows.children.unshift(header)
	return tree
}

const makeUrl = link => link.url.startsWith('http') ? link.url : baseurl + link.url

const get404s = async tree => {
	const rows = select('table', tree)
	const links = selectAll('tableCell:first-child link', rows)
		.map(makeUrl)


	const limit = pLimit(5)
	const reqs = links
		.map(url => 
			limit(() => centra(url, 'HEAD')
				.send()
				.then(res => [url, res.statusCode])
				.catch(() => [url, undefined])))
	
	const status = await Promise.all(reqs)
	const good = new Set(status.filter(([_, s]) => typeof s === 'number' && s < 400).map(([url]) => url))

	if (good.size !== status.length) {
		console.log(`Found ${status.length - good.size} broken URLs`)
		status
			.filter(([url]) => !good.has(url))
			.forEach(([url, status]) => console.log(`${url} : ${typeof status === 'number' ? status : 'failed'}`))
	}

	// filter the table
	rows.children = rows.children
		.filter(row => {
			const link = select('tableCell:first-child link', row)
			return link ? good.has(makeUrl(link)) : true
		})


	return tree
}

const main = async () => {
	const file = await readFile(inputFile, { encoding: 'utf-8' })
	const output = await remark()
		.use(remarkGfm)
		.use(() => get404s)
		.use(() => sortEntries)
		.process(file)

	await writeFile(outputFile, String(output))
}

main()