101 lines
3.2 KiB
JavaScript
101 lines
3.2 KiB
JavaScript
#!/usr/bin/env node
|
|
/**
|
|
* Validate config/universal-resource-activation/manifest.json against
|
|
* - universal-resource-activation.manifest.v1.schema.json
|
|
* - universal-resource-activation.resource.v1.schema.json (per item in resources[])
|
|
* - universal-resource-activation.evidence-package.v1.schema.json (per item in evidencePackages[])
|
|
*
|
|
* Usage: from repo root: node scripts/validate/validate-universal-resource-activation.mjs
|
|
* Exit 0 on success, 1 on error.
|
|
*/
|
|
import { readFileSync, existsSync } from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import Ajv from 'ajv';
|
|
import addFormats from 'ajv-formats';
|
|
|
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
const projectRoot = path.join(__dirname, '../..');
|
|
const configDir = path.join(projectRoot, 'config', 'universal-resource-activation');
|
|
|
|
const manifestPath = path.join(configDir, 'manifest.json');
|
|
const manifestSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.manifest.v1.schema.json');
|
|
const resourceSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.resource.v1.schema.json');
|
|
const evidenceSchemaPath = path.join(projectRoot, 'config', 'universal-resource-activation.evidence-package.v1.schema.json');
|
|
|
|
function fail(msg) {
|
|
console.error(`[validate-ura] ${msg}`);
|
|
process.exit(1);
|
|
}
|
|
|
|
if (!existsSync(manifestPath)) {
|
|
fail(`Missing ${manifestPath}`);
|
|
}
|
|
|
|
const ajv = new Ajv({
|
|
allErrors: true,
|
|
strict: false,
|
|
validateSchema: false,
|
|
});
|
|
addFormats(ajv);
|
|
|
|
const manifestSchema = JSON.parse(readFileSync(manifestSchemaPath, 'utf8'));
|
|
const resourceSchema = JSON.parse(readFileSync(resourceSchemaPath, 'utf8'));
|
|
const evidenceSchema = JSON.parse(readFileSync(evidenceSchemaPath, 'utf8'));
|
|
|
|
const validateManifest = ajv.compile(manifestSchema);
|
|
const validateResource = ajv.compile(resourceSchema);
|
|
const validateEvidence = ajv.compile(evidenceSchema);
|
|
|
|
const raw = readFileSync(manifestPath, 'utf8');
|
|
let data;
|
|
try {
|
|
data = JSON.parse(raw);
|
|
} catch (e) {
|
|
fail(`Invalid JSON: ${e.message}`);
|
|
}
|
|
|
|
if (!validateManifest(data)) {
|
|
fail(`Manifest failed manifest schema: ${ajv.errorsText(validateManifest.errors, { separator: '\n' })}`);
|
|
}
|
|
|
|
if (!Array.isArray(data.resources)) {
|
|
fail('resources must be an array');
|
|
}
|
|
if (!Array.isArray(data.evidencePackages)) {
|
|
fail('evidencePackages must be an array');
|
|
}
|
|
|
|
data.resources.forEach((r, i) => {
|
|
if (!validateResource(r)) {
|
|
fail(
|
|
`resources[${i}] (resourceId=${r?.resourceId}): ${ajv.errorsText(validateResource.errors, { separator: '\n' })}`
|
|
);
|
|
}
|
|
});
|
|
|
|
data.evidencePackages.forEach((p, i) => {
|
|
if (!validateEvidence(p)) {
|
|
fail(
|
|
`evidencePackages[${i}] (id=${p?.evidencePackageId}): ${ajv.errorsText(validateEvidence.errors, { separator: '\n' })}`
|
|
);
|
|
}
|
|
});
|
|
|
|
// Cross-check: all resourceIds referenced in evidence exist
|
|
const ids = new Set(data.resources.map((r) => r.resourceId).filter(Boolean));
|
|
data.evidencePackages.forEach((p, pi) => {
|
|
(p.resourceIds || []).forEach((rid) => {
|
|
if (!ids.has(rid)) {
|
|
fail(
|
|
`evidencePackages[${pi}] references unknown resourceId: ${rid}`
|
|
);
|
|
}
|
|
});
|
|
});
|
|
|
|
console.log(
|
|
`[validate-ura] OK: ${data.resources.length} resource(s), ${data.evidencePackages.length} evidence package(s)`
|
|
);
|
|
process.exit(0);
|