mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-11 20:13:30 +08:00
feat: add SQLite state store and ECC status CLI
This commit is contained in:
92
scripts/lib/state-store/schema.js
Normal file
92
scripts/lib/state-store/schema.js
Normal file
@@ -0,0 +1,92 @@
|
||||
'use strict';
|
||||
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const Ajv = require('ajv');
|
||||
|
||||
const SCHEMA_PATH = path.join(__dirname, '..', '..', '..', 'schemas', 'state-store.schema.json');
|
||||
|
||||
const ENTITY_DEFINITIONS = {
|
||||
session: 'session',
|
||||
skillRun: 'skillRun',
|
||||
skillVersion: 'skillVersion',
|
||||
decision: 'decision',
|
||||
installState: 'installState',
|
||||
governanceEvent: 'governanceEvent',
|
||||
};
|
||||
|
||||
let cachedSchema = null;
|
||||
let cachedAjv = null;
|
||||
const cachedValidators = new Map();
|
||||
|
||||
function readSchema() {
|
||||
if (cachedSchema) {
|
||||
return cachedSchema;
|
||||
}
|
||||
|
||||
cachedSchema = JSON.parse(fs.readFileSync(SCHEMA_PATH, 'utf8'));
|
||||
return cachedSchema;
|
||||
}
|
||||
|
||||
function getAjv() {
|
||||
if (cachedAjv) {
|
||||
return cachedAjv;
|
||||
}
|
||||
|
||||
cachedAjv = new Ajv({
|
||||
allErrors: true,
|
||||
strict: false,
|
||||
});
|
||||
return cachedAjv;
|
||||
}
|
||||
|
||||
function getEntityValidator(entityName) {
|
||||
if (cachedValidators.has(entityName)) {
|
||||
return cachedValidators.get(entityName);
|
||||
}
|
||||
|
||||
const schema = readSchema();
|
||||
const definitionName = ENTITY_DEFINITIONS[entityName];
|
||||
|
||||
if (!definitionName || !schema.$defs || !schema.$defs[definitionName]) {
|
||||
throw new Error(`Unknown state-store schema entity: ${entityName}`);
|
||||
}
|
||||
|
||||
const validatorSchema = {
|
||||
$schema: schema.$schema,
|
||||
...schema.$defs[definitionName],
|
||||
$defs: schema.$defs,
|
||||
};
|
||||
const validator = getAjv().compile(validatorSchema);
|
||||
cachedValidators.set(entityName, validator);
|
||||
return validator;
|
||||
}
|
||||
|
||||
function formatValidationErrors(errors = []) {
|
||||
return errors
|
||||
.map(error => `${error.instancePath || '/'} ${error.message}`)
|
||||
.join('; ');
|
||||
}
|
||||
|
||||
function validateEntity(entityName, payload) {
|
||||
const validator = getEntityValidator(entityName);
|
||||
const valid = validator(payload);
|
||||
return {
|
||||
valid,
|
||||
errors: validator.errors || [],
|
||||
};
|
||||
}
|
||||
|
||||
function assertValidEntity(entityName, payload, label) {
|
||||
const result = validateEntity(entityName, payload);
|
||||
if (!result.valid) {
|
||||
throw new Error(`Invalid ${entityName}${label ? ` (${label})` : ''}: ${formatValidationErrors(result.errors)}`);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
assertValidEntity,
|
||||
formatValidationErrors,
|
||||
readSchema,
|
||||
validateEntity,
|
||||
};
|
||||
Reference in New Issue
Block a user