mithril-vndb/scripts/_lint-docs/lint-http-link.js
Claudia Meadows 0d095d1373
Rewrite docs linter
1. I want to set the stage to deal with #2898 properly.
2. `request` was deprecated years ago. Decided that it's better to just
   move to native Node.js APIs in its place.
3. `glob` was outdated, and it's easier to just toss it than to upgrade
   across a major version.
4. I switched to using Marked's "lexer" directly so I'm not fussing
   with the complexity of renderers. This of course necessitated a more
   complex file processor as its "lexer" is really an AST parser.

I also decided to go a few steps further:
- Drop the cache to simplify everything. I might reverse this later,
  but just caching URLs per-page should be enough to prevent the world
  from crashing down.
- Drop some more dependencies, so I don't have to come back to this
  later nearly as quickly.
- Upgrade to a more modern language version in the scripts.
- Update Marked. It was super outdated.
- Add line and column numbers to the warnings. That took quite a bit of
  work, thanks to a missing Marked feature plus a bug in Marked.
2024-09-23 04:54:17 -07:00

72 lines
1.7 KiB
JavaScript

"use strict"
const {tryFetch} = require("./try-fetch.js")
function checkKnownCorrectRequestFail(href, headers, status, body) {
if (status >= 400 && status <= 499) {
return `${href} is a broken link (status: ${status})`
}
// Don't fail if something weird shows up - it's the internet. Just log it and move on.
// However, some more sophisticated logging is useful.
let message = `HTTP error for ${href} (status: ${status})`
for (const [name, value] of Object.entries(headers)) {
if (Array.isArray(value)) {
for (const v of value) message = `${message}\n>${name}: ${v}`
} else {
message = `${message}\n>${name}: ${value}`
}
}
if (body !== "") {
message = `${message}\n>${body}`
}
return message
}
/**
* Returns `undefined` if no error, a string if an error does occur.
* @param {(message?: string)} callback
*/
function checkHttp(href, callback) {
// Prefer https: > http: where possible, but allow http: when https: is inaccessible.
const url = new URL(href)
url.hash = ""
const isHTTPS = url.protocol === "https:"
url.protocol = "https:"
tryFetch(url, (headers, status, body, sslError) => {
if (status >= 200 && status <= 299) {
if (isHTTPS) {
return callback()
} else {
return callback(`Change ${href} to use \`https:\``)
}
}
if (!sslError) {
return callback(checkKnownCorrectRequestFail(href, headers, status, body))
}
url.protocol = "http:"
tryFetch(url, (headers, status, body) => {
if (status >= 200 && status <= 299) {
if (isHTTPS) {
return callback(`Change ${href} to use \`http:\``)
} else {
return callback()
}
}
return callback(checkKnownCorrectRequestFail(href, headers, status, body))
})
})
}
module.exports = {
checkHttp,
}