import { access, readFile } from "node:fs/promises"; import { dirname, resolve } from "node:path"; import { fileURLToPath } from "node:url"; const root = resolve(dirname(fileURLToPath(import.meta.url)), ".."); const parse = async (path) => JSON.parse(await readFile(resolve(root, path), "utf8")); const registry = await parse("registry/registry.json"); const sources = await parse("registry/sources.json"); const components = await parse("registry/components.json"); const candidates = await parse("registry/candidates.json"); const failures = []; const requireValue = (condition, message) => { if (!condition) failures.push(message); }; requireValue(registry.schemaVersion === "1.0.0", "registry schemaVersion must be 1.0.0"); requireValue(registry.libraryVersion, "registry libraryVersion is required"); requireValue(Array.isArray(registry.packages) && registry.packages.length >= 4, "registry must list all packages"); requireValue(Array.isArray(sources.sources) && sources.sources.length >= 6, "source audit is incomplete"); requireValue(Array.isArray(components.components) && components.components.length >= 10, "component registry is incomplete"); requireValue(Array.isArray(candidates.candidates) && candidates.candidates.length >= 10, "candidate registry is incomplete"); const ids = components.components.map((component) => component.id); requireValue(new Set(ids).size === ids.length, "component ids must be unique"); const candidateIds = candidates.candidates.map((component) => component.id); requireValue(new Set(candidateIds).size === candidateIds.length, "candidate ids must be unique"); requireValue(candidateIds.every((id) => !ids.includes(id)), "a component cannot be both baseline and candidate"); for (const component of components.components) { requireValue(component.id && component.status && component.summary, `component entry is incomplete: ${component.id ?? "unknown"}`); } for (const pkg of registry.packages) { try { await access(resolve(root, pkg.path, "package.json")); } catch { failures.push(`missing package manifest: ${pkg.path}/package.json`); } } for (const path of Object.values(registry.documentation)) { try { await access(resolve(root, "registry", path)); } catch { failures.push(`missing documentation target: ${path}`); } } if (failures.length > 0) { console.error(failures.map((failure) => `- ${failure}`).join("\n")); process.exit(1); } console.log(`Registry valid: ${components.components.length} components, ${candidates.candidates.length} candidates, ${sources.sources.length} audited sources.`);