UNPKG

fortify-schema

Version:

A modern TypeScript validation library designed around familiar interface syntax and powerful conditional validation. Experience schema validation that feels natural to TypeScript developers while unlocking advanced runtime validation capabilities.

200 lines (156 loc) 6.48 kB
# Conditional Validation Implementation ## Overview The conditional validation system in Fortify Schema has been fully implemented, replacing all placeholder TODOs with complete, functional logic. The system supports multiple syntax formats and provides robust validation capabilities. ## ✅ Implementation Status: COMPLETE ### Core Components Implemented 1. **Condition Evaluation Engine** ✅ - Proper condition function execution - Error handling for failed evaluations - Support for all conditional operators 2. **Multiple Syntax Support** ✅ - Revolutionary `*?` syntax: `"when role=admin *? string[] : string[]?"` - Parentheses syntax: `"when(role=admin) then(string[]) else(string[]?)"` - Builder API: `When.field("role").is("admin").then("string[]").else("string[]?")` 3. **Advanced Operators** ✅ - Existence: `exists`, `!exists` - State: `empty`, `!empty`, `null`, `!null` - Comparison: `=`, `!=`, `>`, `<`, `>=`, `<=` - Pattern: `~`, `!~` (regex) - Array: `in`, `!in` - String: `startsWith`, `endsWith`, `contains`, `!contains` 4. **Fallback Validation** ✅ - Graceful handling when full data context is unavailable - Multi-schema validation approach - Meaningful error messages and warnings ## Architecture ### Condition Evaluation Flow ```typescript // 1. Parse conditional syntax const conditionalConfig = ConditionalSyntaxUtils.parse(fieldType); // 2. Evaluate condition with full data context const dependentFieldValue = fullData[conditionalConfig.fieldName]; const conditionMet = this.evaluateCondition(condition, dependentFieldValue); // 3. Select appropriate schema const schemaToUse = conditionMet ? condition.schema : defaultSchema; // 4. Validate value against selected schema const result = this.validateStringFieldType(schemaToUse, value); ``` ### Key Methods Implemented #### `evaluateCondition(condition: any, fieldValue: any): boolean` - Executes condition functions safely - Handles evaluation errors gracefully - Returns boolean result for schema selection #### `validateConditionalFieldWithContext(conditionalDef, value, fullData)` - Primary method for conditional validation with full data access - Evaluates conditions against dependent field values - Selects and applies appropriate schema #### `validateConditionalField(conditionalDef, value)` - Fallback method for validation without full data context - Attempts validation against all possible schemas - Provides warnings about limited context #### `validateSchemaType(schema, value)` - Helper method for validating against different schema types - Handles string schemas and object schemas - Provides consistent error handling ## Syntax Examples ### Revolutionary *? Syntax ```typescript const schema = new InterfaceSchema({ role: "string", permissions: "when role=admin *? string[] : string[]?", salary: "when role.in(admin,manager) *? number : number?", canDelete: "when permissions.contains(delete) *? =true : =false" }); ``` ### Parentheses Syntax ```typescript const schema = new InterfaceSchema({ age: "number", drinkType: "when(age>=21) then(string) else(=water)", canVote: "when(age>=18) then(=true) else(=false)" }); ``` ### Builder API ```typescript const schema = new InterfaceSchema({ status: "string", details: When.field("status").is("active").then("string").else("string?"), priority: When.field("status").in(["urgent", "critical"]).then("number").else("=1") }); ``` ## Error Handling ### Graceful Degradation - Invalid conditions return `false` (condition not met) - Missing dependent fields are handled appropriately - Validation continues with fallback schemas ### Meaningful Error Messages ```typescript // Example error output { success: false, errors: ["permissions: Expected array, got string"], warnings: ["Conditional validation performed without full data context"] } ``` ## Performance Optimizations 1. **Condition Caching**: Parsed conditions are reused 2. **Early Exit**: First successful schema validation is used 3. **Error Boundaries**: Failed conditions don't break entire validation 4. **Lazy Evaluation**: Conditions only evaluated when needed ## Testing Coverage ### Test Categories Implemented - ✅ Revolutionary *? syntax validation - ✅ Parentheses syntax validation - ✅ When Builder API validation - ✅ Advanced operator testing - ✅ Error handling and edge cases - ✅ Performance and nested conditions - ✅ Fallback validation scenarios ### Example Test Cases ```typescript // Role-based permissions const adminResult = schema.validate({ role: "admin", permissions: ["read", "write", "delete"] // Required for admin }); // Age-based restrictions const adultResult = schema.validate({ age: 25, drinkType: "beer" // Allowed for adults }); // File processing logic const fileResult = schema.validate({ filename: "important_document.pdf", needsBackup: true, // Required for important_ prefix extractMetadata: true // Required for .pdf files }); ``` ## Integration Points ### With Type System - Full integration with all 50 supported types - Constraint parsing and application - Type inference for conditional results ### With Validation Pipeline - Seamless integration with main validation flow - Proper error aggregation and reporting - Warning system for edge cases ### With Schema Options - Respects `loose` mode for type coercion - Honors `strict` mode for unknown properties - Applies global constraints appropriately ## Future Enhancements While the implementation is complete and functional, potential future improvements include: 1. **Condition Optimization**: Compile conditions to optimized functions 2. **Dependency Graph**: Build dependency graphs for complex schemas 3. **Async Conditions**: Support for asynchronous condition evaluation 4. **Condition Debugging**: Enhanced debugging tools for complex conditions ## Conclusion The conditional validation system is now **fully implemented** with: - ✅ Complete condition evaluation logic - ✅ Multiple syntax support (3 different formats) - ✅ All 20 conditional operators working - ✅ Robust error handling and fallbacks - ✅ Comprehensive test coverage - ✅ Performance optimizations - ✅ Full integration with the type system The TODO has been successfully resolved with a production-ready implementation that provides powerful, flexible conditional validation capabilities while maintaining excellent developer experience and type safety.