131 lines
4.0 KiB
JavaScript
131 lines
4.0 KiB
JavaScript
const path = require('path');
|
|
const { SiteChecker } = require('broken-link-checker'); // eslint-disable-line import/no-unresolved
|
|
const { Renderer } = require('xlsx-renderer');
|
|
const { logger, spawnProcess } = require('./utils');
|
|
|
|
const ACCEPTABLE_STATUS_CODES = [undefined, 200, 429];
|
|
const PORT = 8088;
|
|
|
|
// start server
|
|
spawnProcess(`http-server ${path.resolve('.vuepress', 'dist')} -s -p ${PORT}`);
|
|
const stats = {
|
|
brokenInternal: 0,
|
|
brokenExternal: 0,
|
|
external: 0,
|
|
internal: 0,
|
|
_set: new Set()
|
|
};
|
|
const links = [];
|
|
|
|
const saveReport = async() => {
|
|
const result = await new Renderer().renderFromFile(path.resolve(__dirname, './check-links-report-template.xlsx'), {
|
|
stats: {
|
|
brokenInternal: stats.brokenInternal,
|
|
brokenExternal: stats.brokenExternal,
|
|
external: stats.external,
|
|
internal: stats.internal,
|
|
},
|
|
links,
|
|
at: new Date().toLocaleString()
|
|
});
|
|
|
|
await result.xlsx.writeFile('./report-check-links.xlsx');
|
|
|
|
logger.info(`XLSX report saved into ${path.resolve('./report-check-links.xlsx')}`);
|
|
};
|
|
|
|
const siteChecker = new SiteChecker(
|
|
{
|
|
excludeInternalLinks: false,
|
|
excludeExternalLinks: true,
|
|
excludeLinksToSamePage: true,
|
|
filterLevel: 2,
|
|
acceptedSchemes: ['http', 'https'],
|
|
excludedKeywords: [
|
|
'linkedin.com', // it always throws an error even if link really works
|
|
'github.com',
|
|
'https://jsfiddle.net/api/post/library/pure/', // from "edit in jsfiddle" button
|
|
'*/docs/*.*.*' // the old documentation
|
|
]
|
|
},
|
|
{
|
|
error: (error) => {
|
|
logger.error(error);
|
|
},
|
|
|
|
link: (result) => {
|
|
const isUnique = !stats._set.has(result.url.resolved);
|
|
|
|
stats._set.add(result.url.resolved);
|
|
|
|
const status = result.http.response?.statusCode;
|
|
|
|
if (result.broken) {
|
|
if (result.http.response && !ACCEPTABLE_STATUS_CODES.includes(status)) {
|
|
if (result.internal) {
|
|
// eslint-disable-next-line max-len
|
|
logger.error(`on: ${result.base.resolved} \t broken internal link ${status} => ${result.url.resolved} \t ${result.url.original} ;`);
|
|
stats.brokenInternal += isUnique;
|
|
} else {
|
|
logger.warn(`on: ${result.base.resolved} \t broken external link ${status} => ${result.url.resolved};`);
|
|
stats.brokenExternal += isUnique;
|
|
}
|
|
}
|
|
} else if (result.internal) {
|
|
stats.internal += isUnique;
|
|
} else {
|
|
logger.log(`on: ${result.base.resolved} \t external link ${status} => ${result.url.resolved};`);
|
|
stats.external += isUnique;
|
|
}
|
|
links.push({
|
|
status,
|
|
isBroken: result.broken,
|
|
isInternal: result.internal,
|
|
linkFrom: result.base.resolved,
|
|
linkTo: result.url.resolved,
|
|
linkToOriginal: result.url.original
|
|
});
|
|
},
|
|
|
|
end: async() => {
|
|
try {
|
|
await saveReport();
|
|
} catch (err) {
|
|
logger.warn('Error thrown while report was being generated', err);
|
|
}
|
|
|
|
logger.info('\nCHECK FOR BROKEN LINKS FINISHED');
|
|
logger.info(`Checked internals : ${stats.internal + stats.brokenInternal}`);
|
|
logger.info(`Checked externals : ${stats.external + stats.brokenExternal}`);
|
|
|
|
if (stats.brokenInternal || stats.brokenExternal) {
|
|
logger.error(`Broken internals: ${stats.brokenInternal}`);
|
|
logger.error(`Broken external: ${stats.brokenExternal}`);
|
|
|
|
if (stats.brokenInternal) {
|
|
logger.error('\nINTERNAL BROKEN LINKS DETECTED!');
|
|
process.exit(1);
|
|
} else {
|
|
logger.warn('\nEXTERNAL BROKEN LINKS DETECTED!');
|
|
process.exit(0);
|
|
}
|
|
}
|
|
logger.success('\nNO BROKEN LINKS DETECTED!');
|
|
process.exit(0);
|
|
}
|
|
}
|
|
);
|
|
|
|
const ARGUMENT_URL_DEFAULT = `http://127.0.0.1:${PORT}/docs/api`;
|
|
|
|
let [urlArg] = process.argv.slice(2);
|
|
|
|
urlArg = urlArg || ARGUMENT_URL_DEFAULT;
|
|
|
|
// run siteChecker
|
|
// timeout is needed because siteChecker would open URL before server started
|
|
setTimeout(() => {
|
|
logger.success('CHECK FOR BROKEN LINKS STARTED');
|
|
siteChecker.enqueue(urlArg);
|
|
}, 3000);
|