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.
148 lines (117 loc) โข 5.03 kB
Markdown
## ๐ **Bug Found and Fixed**
### **Original Issue**
The conditional validation system was not properly applying constraint validation. Test data that should have failed validation was passing:
```typescript
const invalidData = {
accountType: "free",
maxProjects: 59, // Should fail (max 3 for free accounts)
storageLimit: 60, // Should fail (max 50 for free accounts)
};
// This was incorrectly returning success: true
const result = schema.safeParse(invalidData);
```
### **Root Cause**
In `InterfaceSchema.ts`, the `validateStringFieldType` method was calling `this.validateBasicType(elementType, value)` where `elementType` was the parsed type without constraints (e.g., `"int"`) instead of the original field type with constraints (e.g., `"int(1,3)"`).
**File**: `src/core/schema/mode/interfaces/InterfaceSchema.ts`
**Line**: 608
**Problem**: `return this.validateBasicType(elementType, value);`
**Fix**: `return this.validateBasicType(fieldType, value);`
### **Impact**
This bug affected ALL conditional validation that used constraint syntax, causing validation to pass when it should fail.
## ๐ง **Additional Bug Fixed**
### **Method Call Arguments Bug**
The `.in()` method was not working correctly because comma-separated arguments like `admin,manager` were being parsed as a single string `"admin,manager"` instead of an array `["admin", "manager"]`.
**File**: `src/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.ts`
**Solution**: Added `expandCommaSeparatedArgs()` method to properly split comma-separated values.
```typescript
private expandCommaSeparatedArgs(args: any[]): any[] {
const expandedArgs: any[] = [];
for (const arg of args) {
if (typeof arg === "string" && arg.includes(",")) {
const splitValues = arg.split(",").map(v => v.trim());
expandedArgs.push(...splitValues);
} else {
expandedArgs.push(arg);
}
}
return expandedArgs;
}
```
## โ
**Features Now Working Correctly**
### **1. Constraint Syntax in Conditionals** โ
```typescript
const schema = Interface({
accountType: "free|premium",
maxProjects: "when accountType=free *? int(1,3) : int(1,100)",
storageLimit: "when accountType=premium *? int(100,) : int(10,50)",
nameLength: "when role=admin *? string(5,50) : string(3,20)",
discount: "when age>=65 *? number(0.1,0.3) : number(0,0.1)",
});
```
### **2. Method Calls** โ
```typescript
const schema = Interface({
role: "admin|manager|user|guest",
elevatedAccess: "when role.in(admin,manager) *? =granted : =denied",
notifications: "when email.exists *? =email : =none",
premiumFeatures: "when tags.contains(premium) *? =enabled : =disabled",
});
```
### **3. Logical Operators** โ
```typescript
const schema = Interface({
fullAccess: "when role=admin && age>=18 *? =granted : =denied",
managerAccess: "when role=admin || role=manager *? =granted : =denied",
specialFeatures: "when role.in(admin,manager) || age>=65 *? =enabled : =disabled",
});
```
### **4. Nested Conditionals** โ
```typescript
const schema = Interface({
access: "when status=active *? when role=admin *? =full : =limited : =none",
features: "when status=active *? when role=admin *? when level>=5 *? =all : =admin : =user : =none",
});
```
### **5. All Comparison Operators** โ
- `=` (equality)
- `!=` (inequality)
- `>=`, `>`, `<=`, `<` (numeric comparisons)
## ๐ **Documentation Updated**
Updated `docs/CONDITIONAL_VALIDATION_GUIDE.md` to reflect that constraint syntax is now fully supported in conditionals, replacing the previous "Not Supported" section with comprehensive examples.
## ๐งช **Tests Added**
Created comprehensive regression test suite in `src/core/tests/conditional-validation-regression.test.ts` to ensure these features continue working correctly.
## ๐ฏ **Verification**
All features verified with comprehensive test suite:
- โ
Constraint syntax validation
- โ
Method calls (`.in()`, `.exists`, `.contains()`)
- โ
Logical operators (`&&`, `||`)
- โ
Nested conditionals
- โ
All comparison operators
- โ
Proper error messages for invalid data
## ๐ **Before vs After**
### **Before Fix**
```typescript
const result = schema.safeParse({
accountType: "free",
maxProjects: 59, // Should fail but didn't
storageLimit: 60, // Should fail but didn't
});
// Result: { success: true, data: {...} } โ WRONG
```
### **After Fix**
```typescript
const result = schema.safeParse({
accountType: "free",
maxProjects: 59, // Correctly fails
storageLimit: 60, // Correctly fails
});
// Result: {
// success: false,
// errors: [
// "maxProjects: Integer must be at most 3",
// "storageLimit: Integer must be at most 50"
// ]
// } โ
CORRECT
```
## ๐ **Impact**
This fix significantly improves the conditional validation system, making it production-ready for complex business logic validation scenarios. The system now properly enforces all constraints in conditional expressions, preventing data integrity issues.