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()
|