- Add Foundry project configuration (foundry.toml, foundry.lock) - Add Solidity contracts (TokenFactory138, BridgeVault138, ComplianceRegistry, etc.) - Add API definitions (OpenAPI, GraphQL, gRPC, AsyncAPI) - Add comprehensive test suite (unit, integration, fuzz, invariants) - Add API services (REST, GraphQL, orchestrator, packet service) - Add documentation (ISO20022 mapping, runbooks, adapter guides) - Add development tools (RBC tool, Swagger UI, mock server) - Update OpenZeppelin submodules to v5.0.0
134 lines
3.0 KiB
TypeScript
134 lines
3.0 KiB
TypeScript
/**
|
|
* Schema validation utilities using Ajv
|
|
* Validates JSON payloads against canonical JSON Schemas
|
|
*/
|
|
|
|
import Ajv from 'ajv';
|
|
import addFormats from 'ajv-formats';
|
|
import { readFileSync } from 'fs';
|
|
import { join } from 'path';
|
|
|
|
const ajv = new Ajv({ allErrors: true, strict: false });
|
|
addFormats(ajv);
|
|
|
|
// Schema cache
|
|
const schemaCache = new Map<string, any>();
|
|
|
|
/**
|
|
* Load a JSON Schema from the schemas directory
|
|
*/
|
|
export function loadSchema(schemaName: string, version: string = 'v1'): any {
|
|
const cacheKey = `${version}/${schemaName}`;
|
|
|
|
if (schemaCache.has(cacheKey)) {
|
|
return schemaCache.get(cacheKey);
|
|
}
|
|
|
|
const schemaPath = join(
|
|
__dirname,
|
|
'../../packages/schemas/jsonschema',
|
|
`${schemaName}.json`
|
|
);
|
|
|
|
try {
|
|
const schema = JSON.parse(readFileSync(schemaPath, 'utf-8'));
|
|
schemaCache.set(cacheKey, schema);
|
|
return schema;
|
|
} catch (error) {
|
|
throw new Error(`Failed to load schema ${schemaName}: ${error}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Load an enum schema
|
|
*/
|
|
export function loadEnumSchema(enumName: string): any {
|
|
const cacheKey = `enum/${enumName}`;
|
|
|
|
if (schemaCache.has(cacheKey)) {
|
|
return schemaCache.get(cacheKey);
|
|
}
|
|
|
|
const schemaPath = join(
|
|
__dirname,
|
|
'../../packages/schemas/enums',
|
|
`${enumName}.json`
|
|
);
|
|
|
|
try {
|
|
const schema = JSON.parse(readFileSync(schemaPath, 'utf-8'));
|
|
schemaCache.set(cacheKey, schema);
|
|
return schema;
|
|
} catch (error) {
|
|
throw new Error(`Failed to load enum schema ${enumName}: ${error}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate a JSON object against a schema
|
|
*/
|
|
export function validate<T = any>(
|
|
schemaName: string,
|
|
data: unknown,
|
|
version: string = 'v1'
|
|
): { valid: boolean; data?: T; errors?: any[] } {
|
|
const schema = loadSchema(schemaName, version);
|
|
const validate = ajv.compile(schema);
|
|
|
|
const valid = validate(data);
|
|
|
|
if (valid) {
|
|
return { valid: true, data: data as T };
|
|
} else {
|
|
return {
|
|
valid: false,
|
|
errors: validate.errors || [],
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Validate against an enum schema
|
|
*/
|
|
export function validateEnum(
|
|
enumName: string,
|
|
value: unknown
|
|
): { valid: boolean; errors?: any[] } {
|
|
const schema = loadEnumSchema(enumName);
|
|
const validate = ajv.compile(schema);
|
|
|
|
const valid = validate(value);
|
|
|
|
if (valid) {
|
|
return { valid: true };
|
|
} else {
|
|
return {
|
|
valid: false,
|
|
errors: validate.errors || [],
|
|
};
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create a validator function for a specific schema
|
|
*/
|
|
export function createValidator<T = any>(schemaName: string, version: string = 'v1') {
|
|
return (data: unknown): { valid: boolean; data?: T; errors?: any[] } => {
|
|
return validate<T>(schemaName, data, version);
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Check schema compatibility between versions
|
|
*/
|
|
export function checkCompatibility(
|
|
oldVersion: string,
|
|
newVersion: string,
|
|
schemaName: string
|
|
): { compatible: boolean; breakingChanges?: string[] } {
|
|
// TODO: Implement schema compatibility checking
|
|
// This would compare schemas and detect breaking changes
|
|
return { compatible: true };
|
|
}
|
|
|