Initial project setup: Add contracts, API definitions, tests, and documentation
- 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
This commit is contained in:
133
api/shared/validation/schema-validator.ts
Normal file
133
api/shared/validation/schema-validator.ts
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* 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 };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user