Comprehensive JSON processing and schema validation system built on AJV (Another JSON Schema Validator), providing type-safe validation, format checking, and schema compilation with support for custom validators and smart defaults.
Core JSON value types and utility functions for type checking.
/**
* Union type representing all valid JSON values
*/
type JsonValue = boolean | string | number | JsonArray | JsonObject | null;
/**
* Object with string keys and JsonValue values
*/
interface JsonObject {
[key: string]: JsonValue;
}
/**
* Array of JsonValue items
*/
interface JsonArray extends Array<JsonValue> {}
/**
* Type guard to check if value is a JsonObject
* @param value - Value to check
* @returns True if value is JsonObject
*/
function isJsonObject(value: unknown): value is JsonObject;
/**
* Type guard to check if value is a JsonArray
* @param value - Value to check
* @returns True if value is JsonArray
*/
function isJsonArray(value: unknown): value is JsonArray;Core interfaces and types for JSON schema validation using AJV.
/**
* String type for JSON pointer paths (RFC 6901)
*/
type JsonPointer = string;
/**
* Result of schema validation operation
*/
interface SchemaValidatorResult {
/** Whether validation succeeded */
success: boolean;
/** Validated data (potentially transformed by smart defaults) */
data: JsonValue;
/** Array of validation errors if validation failed */
errors?: SchemaValidatorError[];
}
/**
* Schema validation error information
*/
type SchemaValidatorError = Partial<{
instancePath: string;
schemaPath: string;
keyword: string;
params: Record<string, any>;
message: string;
}>;
/**
* Options for schema validation
*/
interface SchemaValidatorOptions {
/** Whether to apply smart defaults during validation */
withPrompts?: boolean;
/** Custom prompt provider for interactive defaults */
promptProvider?: PromptProvider;
}
/**
* Function type for validating JSON data against a compiled schema
*/
interface SchemaValidator {
(data: JsonValue, options?: SchemaValidatorOptions): Observable<SchemaValidatorResult>;
}Registry for compiling and managing JSON schemas with format validators.
/**
* Format validator function from AJV
*/
type SchemaFormatter = {
readonly async: boolean;
validate(data: any): boolean | Promise<boolean>;
};
/**
* Named format with its validator
*/
interface SchemaFormat {
name: string;
formatter: SchemaFormatter;
}
/**
* Provider function for generating smart default values
*/
interface SmartDefaultProvider<T = JsonValue> {
(schema: JsonObject): Observable<T>;
}
/**
* Custom keyword validator function for schema extensions
*/
interface SchemaKeywordValidator {
(data: any, schema: any, parentSchema: any, currentPath: string): boolean | Observable<boolean>;
}
/**
* Registry interface for schema compilation and validation
*/
interface SchemaRegistry {
/**
* Compile a JSON schema into a validator function
* @param schema - JSON schema object
* @returns Observable emitting compiled validator
*/
compile(schema: JsonObject): Observable<SchemaValidator>;
/**
* Add a custom format validator to the registry
* @param name - Format name
* @param formatter - Format validator implementation
*/
addFormat(name: string, formatter: SchemaFormatter): void;
/**
* Add a smart default provider for a specific schema pattern
* @param pointer - JSON pointer identifying where to apply defaults
* @param provider - Provider function for generating defaults
*/
addSmartDefaultProvider<T = JsonValue>(pointer: string, provider: SmartDefaultProvider<T>): void;
/**
* Register a custom keyword validator
* @param keyword - Keyword name
* @param validator - Validator implementation
*/
registerKeywordValidator(keyword: string, validator: SchemaKeywordValidator): void;
}
/**
* Main schema registry implementation using AJV
* Provides JSON schema compilation and validation with extensible format support
*/
class CoreSchemaRegistry implements SchemaRegistry {
/**
* Create a new schema registry
* @param formats - Optional map of initial format validators
*/
constructor(formats?: { [name: string]: SchemaFormatter });
compile(schema: JsonObject): Observable<SchemaValidator>;
addFormat(name: string, formatter: SchemaFormatter): void;
addSmartDefaultProvider<T = JsonValue>(pointer: string, provider: SmartDefaultProvider<T>): void;
registerKeywordValidator(keyword: string, validator: SchemaKeywordValidator): void;
}Support for interactive prompts during schema validation for gathering user input.
/**
* Definition for an interactive prompt during validation
*/
interface PromptDefinition {
/** Unique identifier for the prompt */
id: string;
/** Question text to display to user */
message: string;
/** Type of prompt (input, confirm, select, etc.) */
type: string;
/** Default value if user provides no input */
default?: JsonValue;
/** Array of choices for selection prompts */
choices?: Array<string | { name: string; value: JsonValue }>;
/** Validation function for user input */
validate?: (value: JsonValue) => boolean | string;
}
/**
* Provider function for handling interactive prompts
* @param definitions - Array of prompt definitions to display
* @returns Promise resolving to user responses
*/
type PromptProvider = (definitions: PromptDefinition[]) => Promise<{ [id: string]: JsonValue }>;Visitor pattern implementation for traversing and transforming JSON schemas and data.
/**
* Visitor function for JSON schema traversal
* @param current - Current schema node being visited
* @param pointer - JSON pointer to current location
* @param parentSchema - Parent schema context
* @param index - Index in parent array (if applicable)
* @returns Modified schema or void to leave unchanged
*/
interface JsonSchemaVisitor {
(current: JsonObject, pointer: JsonPointer, parentSchema?: JsonObject, index?: string): JsonObject | void;
}
/**
* Visitor function for JSON data transformation
* @param value - Current data value being visited
* @param pointer - JSON pointer to current location
* @param schema - Schema context for current value
* @param root - Root data object
* @returns Modified value or void to leave unchanged
*/
interface JsonVisitor {
(value: JsonValue, pointer: JsonPointer, schema?: JsonObject, root?: JsonValue): JsonValue | void;
}
/**
* Visit and potentially transform a JSON schema using visitor pattern
* @param schema - Schema to traverse
* @param visitor - Visitor function to apply
* @param root - Root schema context
* @returns Transformed schema
*/
function visitJsonSchema(schema: JsonObject, visitor: JsonSchemaVisitor, root?: JsonObject): JsonObject;
/**
* Visit and potentially transform JSON data using visitor pattern
* @param data - Data to traverse
* @param visitor - Visitor function to apply
* @param schema - Schema context
* @param root - Root data context
* @returns Transformed data
*/
function visitJson(data: JsonValue, visitor: JsonVisitor, schema?: JsonObject, root?: JsonValue): JsonValue;Utilities for transforming and manipulating JSON schemas.
namespace transforms {
/**
* Add smart defaults to a schema based on provided defaults object
* @param schema - Source schema
* @param defaults - Default values to merge
* @returns Schema with smart defaults applied
*/
function addSmartDefaults(schema: JsonObject, defaults: JsonObject): JsonObject;
/**
* Add undefined values as valid for all properties (makes all properties optional)
* @param schema - Source schema
* @returns Schema with undefined allowed for all properties
*/
function addUndefinedDefaults(schema: JsonObject): JsonObject;
}import { json } from "@angular-devkit/core";
// Create a schema registry
const registry = new json.schema.CoreSchemaRegistry();
// Define a schema
const userSchema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
email: { type: 'string', format: 'email' },
age: { type: 'number', minimum: 0 }
},
required: ['name', 'email']
};
// Compile the schema
const validator = await registry.compile(userSchema).toPromise();
// Validate data
const result = await validator({
name: 'John Doe',
email: 'john@example.com',
age: 30
}).toPromise();
if (result.success) {
console.log('Validation passed:', result.data);
} else {
console.log('Validation failed:', result.errors);
}import { json } from "@angular-devkit/core";
const registry = new json.schema.CoreSchemaRegistry();
// Add custom format validator
registry.addFormat('phone', {
async: false,
validate: (data: string) => /^\+?[\d\s-()]+$/.test(data)
});
const schema = {
type: 'object',
properties: {
phoneNumber: { type: 'string', format: 'phone' }
}
};
const validator = await registry.compile(schema).toPromise();
const result = await validator({ phoneNumber: '+1-555-123-4567' }).toPromise();import { json } from "@angular-devkit/core";
const registry = new json.schema.CoreSchemaRegistry();
// Add smart default provider
registry.addSmartDefaultProvider('/properties/timestamp', (schema) => {
return of(new Date().toISOString());
});
// Custom prompt provider
const promptProvider: json.schema.PromptProvider = async (definitions) => {
const responses: { [id: string]: json.JsonValue } = {};
for (const def of definitions) {
// Simulate user input (in real usage, this would show actual prompts)
responses[def.id] = def.default || '';
}
return responses;
};
const validator = await registry.compile(schema).toPromise();
const result = await validator(data, {
withPrompts: true,
promptProvider
}).toPromise();