39 lines
1.5 KiB
JavaScript
39 lines
1.5 KiB
JavaScript
import { readFile, readdir } from 'node:fs/promises';
|
|
import { join, relative, resolve, sep } from 'node:path';
|
|
import { parseHTML } from 'linkedom';
|
|
|
|
async function listFiles(root, directory = root) {
|
|
const entries = await readdir(directory, { withFileTypes: true });
|
|
const files = [];
|
|
for (const entry of entries) {
|
|
const path = join(directory, entry.name);
|
|
if (entry.isDirectory()) files.push(...await listFiles(root, path));
|
|
else if (entry.isFile()) files.push(path);
|
|
}
|
|
return files.sort();
|
|
}
|
|
|
|
export async function checkRenderedOutput({ distRoot }) {
|
|
const absoluteDistRoot = resolve(distRoot);
|
|
const files = await listFiles(absoluteDistRoot);
|
|
const relativeFiles = files.map((file) => relative(absoluteDistRoot, file).split(sep).join('/'));
|
|
const htmlFiles = files.filter((file) => {
|
|
const path = relative(absoluteDistRoot, file).split(sep).join('/');
|
|
return path.endsWith('.html') && path !== '404.html';
|
|
});
|
|
const headingIssues = [];
|
|
|
|
for (const file of htmlFiles) {
|
|
const path = relative(absoluteDistRoot, file).split(sep).join('/');
|
|
const { document } = parseHTML(await readFile(file, 'utf8'));
|
|
if (document.querySelector('meta[http-equiv="refresh"]')) continue;
|
|
const h1Count = document.querySelectorAll('h1').length;
|
|
if (h1Count !== 1) headingIssues.push({ file: path, h1Count });
|
|
}
|
|
|
|
return {
|
|
htmlFilesChecked: htmlFiles.length,
|
|
headingIssues,
|
|
unpublishedPaths: relativeFiles.filter((path) => path.split('/').includes('to-be-studied')),
|
|
};
|
|
}
|