n8n/scripts/validate-docs-links.js

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

65 lines
1.8 KiB
JavaScript
Raw Normal View History

#!/usr/bin/env node
const path = require('path');
const https = require('https');
const glob = require('fast-glob');
const pLimit = require('p-limit');
const nodesBaseDir = path.resolve(__dirname, '../packages/nodes-base');
const validateUrl = async (kind, name, documentationUrl) =>
new Promise((resolve, reject) => {
if (!documentationUrl) resolve([name, null]);
const url = new URL(
/^https?:\/\//.test(documentationUrl)
? documentationUrl
: `https://docs.n8n.io/integrations/builtin/${kind}/${documentationUrl.toLowerCase()}/`,
);
https
.request(
{
hostname: url.hostname,
port: 443,
path: url.pathname,
method: 'HEAD',
},
(res) => resolve([name, res.statusCode]),
)
.on('error', (e) => reject(e))
.end();
});
const checkLinks = async (kind) => {
let types = require(path.join(nodesBaseDir, `dist/types/${kind}.json`));
if (kind === 'nodes')
types = types.filter(({ codex }) => !!codex?.resources?.primaryDocumentation);
const limit = pLimit(30);
const statuses = await Promise.all(
types.map((type) =>
limit(() => {
const documentationUrl =
kind === 'credentials'
? type.documentationUrl
: type.codex?.resources?.primaryDocumentation?.[0]?.url;
return validateUrl(kind, type.displayName, documentationUrl);
}),
),
);
const missingDocs = [];
const invalidUrls = [];
for (const [name, statusCode] of statuses) {
if (statusCode === null) missingDocs.push(name);
if (statusCode !== 200) invalidUrls.push(name);
}
if (missingDocs.length) console.log('Documentation URL missing for %s', kind, missingDocs);
if (invalidUrls.length) console.log('Documentation URL invalid for %s', kind, invalidUrls);
if (missingDocs.length || invalidUrls.length) process.exit(1);
};
(async () => {
await checkLinks('credentials');
await checkLinks('nodes');
})();