core/validators/build.validator.ts
core/validators/build.validator.ts is a file in Bane's Lab Build Scripts. 32 lines of code and 12 definitions.
import { MISSING_BUILD_FILE, oversizePage, pageHeadings } from "#configuration/strings/validation.strings";
import { fileOfAddress, localAddress } from "#core/resolvers/catalog.resolver";
import { Buffer } from "node:buffer";
import type { Finding } from "#types/validation.types";
import { PAGE_BYTE_BUDGET } from "#configuration/constants/site.constants";
import { SITE_URL } from "@banes-lab/web/core/assets/link.assets.ts";
import { readOrNull } from "#core/loaders/build.loader";
export const isServedUrl = function isServedUrl(url: string): boolean {
return url.startsWith(SITE_URL) && readOrNull(fileOfAddress(localAddress(SITE_URL, url))) !== null;
};
export const checkFile = function checkFile(file: string, check: (text: string) => Finding[]): Finding[] {
const text = readOrNull(file);
return text === null ? [{ file, message: MISSING_BUILD_FILE }] : check(text);
};
export const checkPageBytes = function checkPageBytes(file: string, html: string): Finding[] {
const bytes = Buffer.byteLength(html);
return bytes > PAGE_BYTE_BUDGET ? [{ file, message: oversizePage(bytes, PAGE_BYTE_BUDGET) }] : [];
};
const HEADING_OPEN = "<h1";
const HEADING_ENDS: ReadonlySet<string> = new Set([">", " "]);
const headingsIn = function headingsIn(html: string, from = 0, count = 0): number {
const at = html.indexOf(HEADING_OPEN, from);
if (at === -1) {
return count;
}
const next = at + HEADING_OPEN.length;
return headingsIn(html, next, HEADING_ENDS.has(html.charAt(next)) ? count + 1 : count);
};
export const checkPageHeadings = function checkPageHeadings(file: string, html: string): Finding[] {
const count = headingsIn(html);
return count === 1 ? [] : [{ file, message: pageHeadings(count) }];
};