Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@
"scripts": "dist/**/*.js",
"assets": [
"node_modules/chalk/**/*",
"containers/agent/seccomp-profile.json"
"containers/agent/seccomp-profile.json",
"dist/awf-config-schema.json"
],
"targets": [
"node18-linux-x64",
Expand Down
30 changes: 6 additions & 24 deletions src/schema-validator.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,21 @@
/**
* Runtime config validation using the published JSON Schema.
*
* The schema JSON is loaded from disk so the emitted JS does not contain a
* fragile runtime `require('./awf-config-schema.json')`. The canonical source
* is generated by `scripts/generate-schema.mjs` and kept in sync via CI.
* The schema is loaded via a static `import` so tsc emits the JSON to
* dist/, esbuild inlines it in the bundle, and pkg includes it in the snapshot.
* The canonical source is generated by `scripts/generate-schema.mjs`.
*/

import Ajv2020, { ErrorObject } from 'ajv/dist/2020';
import { existsSync, readFileSync } from 'fs';
import { join } from 'path';

function loadSchema(): Record<string, unknown> {
const candidatePaths = [
join(__dirname, 'awf-config-schema.json'),
join(__dirname, '../src/awf-config-schema.json'),
];

for (const candidatePath of candidatePaths) {
if (existsSync(candidatePath)) {
return JSON.parse(readFileSync(candidatePath, 'utf8')) as Record<string, unknown>;
}
}
import schemaJson from './awf-config-schema.json';

throw new Error(
`Unable to locate awf-config-schema.json. Checked: ${candidatePaths.join(', ')}`,
);
}
const schema = schemaJson as Record<string, unknown>;

// Compile once (module-level singleton). allErrors collects every violation.
// verbose=true provides parentSchema on errors for richer formatting.
const ajv = new Ajv2020({ allErrors: true, verbose: true });
// 'version' is a metadata keyword (not a standard JSON Schema keyword); register
// it so Ajv strict mode does not reject the schema.
ajv.addKeyword({ keyword: 'version' });
const validate = ajv.compile(loadSchema());
const validate = ajv.compile(schema);

/**
* Check if a schema path points to an array-of-strings field by inspecting
Expand Down
Loading