7c4d3ed79f
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
36 lines
1.1 KiB
JavaScript
36 lines
1.1 KiB
JavaScript
#!/usr/bin/env node
|
|
// validate-sidecar — rung-neutral conformance check (spec §6.4, PUC-5).
|
|
// usage:
|
|
// node scripts/validate-sidecar.mjs <sidecar.json>
|
|
// exit 0 = valid, 1 = invalid (per-error JSON paths on stderr), 2 = usage/IO.
|
|
import { readFileSync } from "node:fs";
|
|
import { fileURLToPath } from "node:url";
|
|
import path from "node:path";
|
|
import Ajv from "ajv/dist/2020.js";
|
|
|
|
const here = path.dirname(fileURLToPath(import.meta.url));
|
|
const schema = JSON.parse(readFileSync(path.join(here, "..", "schemas", "coauthoring-sidecar.schema.json"), "utf8"));
|
|
|
|
const file = process.argv[2];
|
|
if (!file) {
|
|
console.error("usage: validate-sidecar.mjs <sidecar.json>");
|
|
process.exit(2);
|
|
}
|
|
|
|
let data;
|
|
try {
|
|
data = JSON.parse(readFileSync(file, "utf8"));
|
|
} catch (err) {
|
|
console.error(`cannot read/parse ${file}: ${err.message}`);
|
|
process.exit(2);
|
|
}
|
|
|
|
const ajv = new Ajv({ allErrors: true });
|
|
const validate = ajv.compile(schema);
|
|
if (validate(data)) {
|
|
console.log(`OK ${file} (schemaVersion ${data.schemaVersion})`);
|
|
process.exit(0);
|
|
}
|
|
for (const e of validate.errors ?? []) console.error(`${e.instancePath || "/"} ${e.message}`);
|
|
process.exit(1);
|