81 lines
4.9 KiB
JavaScript
81 lines
4.9 KiB
JavaScript
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 icons = await parse("registry/icons.json");
|
|
const pages = await parse("registry/pages.json");
|
|
const applicationManifestSchema = await parse("registry/schemas/application-manifest-v0.1.schema.json");
|
|
const designProfileSchema = await parse("registry/schemas/design-profile-v0.1.schema.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");
|
|
requireValue(Array.isArray(icons.groups) && icons.groups.length >= 5, "icon registry is incomplete");
|
|
requireValue(pages.schemaVersion === "0.1.0", "page registry schemaVersion must be 0.1.0");
|
|
requireValue(Array.isArray(pages.templates) && pages.templates.length >= 1, "page registry must contain at least one template");
|
|
requireValue(registry.applicationManifestSchema === "schemas/application-manifest-v0.1.schema.json", "application manifest schema must be registered");
|
|
requireValue(registry.designProfileSchema === "schemas/design-profile-v0.1.schema.json", "design profile schema must be registered");
|
|
requireValue(applicationManifestSchema.properties?.schemaVersion?.const === "0.1.0", "application manifest schema version must be 0.1.0");
|
|
requireValue(designProfileSchema.properties?.schemaVersion?.const === "0.1.0", "design profile schema version must be 0.1.0");
|
|
|
|
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");
|
|
const iconNames = icons.groups.flatMap((group) => group.names ?? []);
|
|
requireValue(iconNames.length >= 35, "icon registry must contain the audited baseline set");
|
|
requireValue(new Set(iconNames).size === iconNames.length, "icon names must be unique across groups");
|
|
const pageTemplateKeys = pages.templates.map((template) => `${template.id}@${template.version}`);
|
|
requireValue(new Set(pageTemplateKeys).size === pageTemplateKeys.length, "page template id/version pairs must be unique");
|
|
|
|
for (const template of pages.templates) {
|
|
requireValue(template.schemaVersion === "0.1.0", `unsupported page template schema: ${template.id ?? "unknown"}`);
|
|
requireValue(template.id && template.version && template.title && template.page, `page template entry is incomplete: ${template.id ?? "unknown"}`);
|
|
requireValue(Array.isArray(template.features), `page template features are missing: ${template.id ?? "unknown"}`);
|
|
requireValue(Array.isArray(template.slots), `page template slots are missing: ${template.id ?? "unknown"}`);
|
|
requireValue(Array.isArray(template.actions), `page template actions are missing: ${template.id ?? "unknown"}`);
|
|
}
|
|
|
|
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, ${iconNames.length} icons, ${pages.templates.length} page templates, ${candidates.candidates.length} candidates, ${sources.sources.length} audited sources.`);
|