reliant-type 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1305 -0
- package/dist/cjs/constants/SECURITY_CONSTANTS.js +49 -0
- package/dist/cjs/constants/SECURITY_CONSTANTS.js.map +1 -0
- package/dist/cjs/constants/VALIDATION_CONSTANTS.js +103 -0
- package/dist/cjs/constants/VALIDATION_CONSTANTS.js.map +1 -0
- package/dist/cjs/core/schema/extensions/SmartInference.js +200 -0
- package/dist/cjs/core/schema/extensions/SmartInference.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/Docs.js +100 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/Docs.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js +192 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js +174 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js +54 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js +50 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/index.js +15 -0
- package/dist/cjs/core/schema/extensions/components/AutoDocumentation/index.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js +70 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js +40 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js +19 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js +20 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js +49 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/index.js +98 -0
- package/dist/cjs/core/schema/extensions/components/ConditionalValidation/index.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/FormValidator.js +85 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/FormValidator.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/LiveValidator.js +133 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/LiveValidator.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/StreamValidator.js +351 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/StreamValidator.js.map +1 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/index.js +109 -0
- package/dist/cjs/core/schema/extensions/components/RealtimeValidation/index.js.map +1 -0
- package/dist/cjs/core/schema/extensions/index.js +61 -0
- package/dist/cjs/core/schema/extensions/index.js.map +1 -0
- package/dist/cjs/core/schema/extensions/mods/index.js +51 -0
- package/dist/cjs/core/schema/extensions/mods/index.js.map +1 -0
- package/dist/cjs/core/schema/extensions/mods/openapi-converter.js +227 -0
- package/dist/cjs/core/schema/extensions/mods/openapi-converter.js.map +1 -0
- package/dist/cjs/core/schema/extensions/mods/typescript-generator.js +287 -0
- package/dist/cjs/core/schema/extensions/mods/typescript-generator.js.map +1 -0
- package/dist/cjs/core/schema/extensions/mods/validation-engine.js +224 -0
- package/dist/cjs/core/schema/extensions/mods/validation-engine.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/Interface.js +277 -0
- package/dist/cjs/core/schema/mode/interfaces/Interface.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/InterfaceSchema.js +1431 -0
- package/dist/cjs/core/schema/mode/interfaces/InterfaceSchema.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js +520 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js +624 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js +811 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js +599 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js +89 -0
- package/dist/cjs/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/errors/ErrorHandler.js +356 -0
- package/dist/cjs/core/schema/mode/interfaces/errors/ErrorHandler.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/errors/types/errors.type.js +80 -0
- package/dist/cjs/core/schema/mode/interfaces/errors/types/errors.type.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js +778 -0
- package/dist/cjs/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js +523 -0
- package/dist/cjs/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/ConditionalTypes.js +681 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/ConditionalTypes.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/IDESupport.js +430 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/IDESupport.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/TypeInference.js +225 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/TypeInference.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/index.js +44 -0
- package/dist/cjs/core/schema/mode/interfaces/typescript/index.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/ConstraintParser.js +1134 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/ConstraintParser.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/TypeGuards.js +256 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/TypeGuards.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/TypeValidators.js +429 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/TypeValidators.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/UnionCache.js +404 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/UnionCache.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/ValidationHelpers.js +851 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/ValidationHelpers.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/mods/passValidator.js +262 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/mods/passValidator.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/mods/securityValidator.js +887 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/mods/securityValidator.js.map +1 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/mods/urlValidation.js +191 -0
- package/dist/cjs/core/schema/mode/interfaces/validators/mods/urlValidation.js.map +1 -0
- package/dist/cjs/core/schema/optimization/ObjectValidationCache.js +462 -0
- package/dist/cjs/core/schema/optimization/ObjectValidationCache.js.map +1 -0
- package/dist/cjs/core/schema/optimization/PerformanceMonitor.js +773 -0
- package/dist/cjs/core/schema/optimization/PerformanceMonitor.js.map +1 -0
- package/dist/cjs/core/schema/optimization/SchemaCompiler.js +600 -0
- package/dist/cjs/core/schema/optimization/SchemaCompiler.js.map +1 -0
- package/dist/cjs/core/types/ValidatorTypes.js +70 -0
- package/dist/cjs/core/types/ValidatorTypes.js.map +1 -0
- package/dist/cjs/core/types/parser.type.js +12 -0
- package/dist/cjs/core/types/parser.type.js.map +1 -0
- package/dist/cjs/core/utils/Make.js +61 -0
- package/dist/cjs/core/utils/Make.js.map +1 -0
- package/dist/cjs/core/utils/Mod.js +1033 -0
- package/dist/cjs/core/utils/Mod.js.map +1 -0
- package/dist/cjs/core/utils/UrlArgs.js +102 -0
- package/dist/cjs/core/utils/UrlArgs.js.map +1 -0
- package/dist/cjs/core/utils/arrayToEnum.js +18 -0
- package/dist/cjs/core/utils/arrayToEnum.js.map +1 -0
- package/dist/cjs/core/utils/createUrlArgsEnumFArray.js +13 -0
- package/dist/cjs/core/utils/createUrlArgsEnumFArray.js.map +1 -0
- package/dist/cjs/core/utils/securityHelpers.js +215 -0
- package/dist/cjs/core/utils/securityHelpers.js.map +1 -0
- package/dist/cjs/core/utils/securityValidatorHelpers.js +65 -0
- package/dist/cjs/core/utils/securityValidatorHelpers.js.map +1 -0
- package/dist/cjs/index.js +31 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/package.json +3 -0
- package/dist/esm/constants/SECURITY_CONSTANTS.js +47 -0
- package/dist/esm/constants/SECURITY_CONSTANTS.js.map +1 -0
- package/dist/esm/constants/VALIDATION_CONSTANTS.js +98 -0
- package/dist/esm/constants/VALIDATION_CONSTANTS.js.map +1 -0
- package/dist/esm/core/schema/extensions/SmartInference.js +197 -0
- package/dist/esm/core/schema/extensions/SmartInference.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/Docs.js +98 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/Docs.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js +190 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js +172 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js +52 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js +48 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/index.js +12 -0
- package/dist/esm/core/schema/extensions/components/AutoDocumentation/index.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js +68 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js +38 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalElse.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js +17 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/ConditionalThen.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js +18 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js +45 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/index.js +92 -0
- package/dist/esm/core/schema/extensions/components/ConditionalValidation/index.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/FormValidator.js +83 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/FormValidator.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/LiveValidator.js +131 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/LiveValidator.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/StreamValidator.js +349 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/StreamValidator.js.map +1 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/index.js +103 -0
- package/dist/esm/core/schema/extensions/components/RealtimeValidation/index.js.map +1 -0
- package/dist/esm/core/schema/extensions/index.js +53 -0
- package/dist/esm/core/schema/extensions/index.js.map +1 -0
- package/dist/esm/core/schema/extensions/mods/index.js +47 -0
- package/dist/esm/core/schema/extensions/mods/index.js.map +1 -0
- package/dist/esm/core/schema/extensions/mods/openapi-converter.js +225 -0
- package/dist/esm/core/schema/extensions/mods/openapi-converter.js.map +1 -0
- package/dist/esm/core/schema/extensions/mods/typescript-generator.js +284 -0
- package/dist/esm/core/schema/extensions/mods/typescript-generator.js.map +1 -0
- package/dist/esm/core/schema/extensions/mods/validation-engine.js +222 -0
- package/dist/esm/core/schema/extensions/mods/validation-engine.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/Interface.js +269 -0
- package/dist/esm/core/schema/mode/interfaces/Interface.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/InterfaceSchema.js +1429 -0
- package/dist/esm/core/schema/mode/interfaces/InterfaceSchema.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js +518 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js +620 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalAST.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js +809 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js +597 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/parser/ConditionalParser.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js +89 -0
- package/dist/esm/core/schema/mode/interfaces/conditional/types/ConditionalTypes.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/errors/ErrorHandler.js +354 -0
- package/dist/esm/core/schema/mode/interfaces/errors/ErrorHandler.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/errors/types/errors.type.js +80 -0
- package/dist/esm/core/schema/mode/interfaces/errors/types/errors.type.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js +776 -0
- package/dist/esm/core/schema/mode/interfaces/precompilation/FieldPrecompilers.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js +521 -0
- package/dist/esm/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/ConditionalTypes.js +681 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/ConditionalTypes.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/IDESupport.js +428 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/IDESupport.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/TypeInference.js +223 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/TypeInference.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/index.js +35 -0
- package/dist/esm/core/schema/mode/interfaces/typescript/index.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/ConstraintParser.js +1132 -0
- package/dist/esm/core/schema/mode/interfaces/validators/ConstraintParser.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/TypeGuards.js +254 -0
- package/dist/esm/core/schema/mode/interfaces/validators/TypeGuards.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/TypeValidators.js +427 -0
- package/dist/esm/core/schema/mode/interfaces/validators/TypeValidators.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/UnionCache.js +400 -0
- package/dist/esm/core/schema/mode/interfaces/validators/UnionCache.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/ValidationHelpers.js +849 -0
- package/dist/esm/core/schema/mode/interfaces/validators/ValidationHelpers.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/mods/passValidator.js +260 -0
- package/dist/esm/core/schema/mode/interfaces/validators/mods/passValidator.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/mods/securityValidator.js +881 -0
- package/dist/esm/core/schema/mode/interfaces/validators/mods/securityValidator.js.map +1 -0
- package/dist/esm/core/schema/mode/interfaces/validators/mods/urlValidation.js +189 -0
- package/dist/esm/core/schema/mode/interfaces/validators/mods/urlValidation.js.map +1 -0
- package/dist/esm/core/schema/optimization/ObjectValidationCache.js +460 -0
- package/dist/esm/core/schema/optimization/ObjectValidationCache.js.map +1 -0
- package/dist/esm/core/schema/optimization/PerformanceMonitor.js +771 -0
- package/dist/esm/core/schema/optimization/PerformanceMonitor.js.map +1 -0
- package/dist/esm/core/schema/optimization/SchemaCompiler.js +598 -0
- package/dist/esm/core/schema/optimization/SchemaCompiler.js.map +1 -0
- package/dist/esm/core/types/ValidatorTypes.js +65 -0
- package/dist/esm/core/types/ValidatorTypes.js.map +1 -0
- package/dist/esm/core/types/parser.type.js +12 -0
- package/dist/esm/core/types/parser.type.js.map +1 -0
- package/dist/esm/core/utils/Make.js +59 -0
- package/dist/esm/core/utils/Make.js.map +1 -0
- package/dist/esm/core/utils/Mod.js +1031 -0
- package/dist/esm/core/utils/Mod.js.map +1 -0
- package/dist/esm/core/utils/UrlArgs.js +98 -0
- package/dist/esm/core/utils/UrlArgs.js.map +1 -0
- package/dist/esm/core/utils/arrayToEnum.js +16 -0
- package/dist/esm/core/utils/arrayToEnum.js.map +1 -0
- package/dist/esm/core/utils/createUrlArgsEnumFArray.js +11 -0
- package/dist/esm/core/utils/createUrlArgsEnumFArray.js.map +1 -0
- package/dist/esm/core/utils/securityHelpers.js +207 -0
- package/dist/esm/core/utils/securityHelpers.js.map +1 -0
- package/dist/esm/core/utils/securityValidatorHelpers.js +62 -0
- package/dist/esm/core/utils/securityValidatorHelpers.js.map +1 -0
- package/dist/esm/index.js +12 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/schema.d.ts +2595 -0
- package/docs/ALL_TYPES.md +120 -0
- package/docs/API-STABILITY.md +336 -0
- package/docs/CONDITIONAL-VALIDATION.md +637 -0
- package/docs/EXAMPLES.md +876 -0
- package/docs/FIELD-TYPES.md +829 -0
- package/docs/GETTING-STARTED.md +394 -0
- package/docs/LIVE-UTILITY.md +1137 -0
- package/docs/QUICK-REFERENCE.md +346 -0
- package/docs/README.md +205 -0
- package/docs/VSCODE-EXTENSION.md +458 -0
- package/package.json +219 -0
- package/src/bench/BENCHMARK-RESULTS.md +211 -0
- package/src/bench/benchmark-results.json +148 -0
- package/src/bench/performance-comparison.ts +218 -0
- package/src/bench/precompilation-benchmark.ts +218 -0
- package/src/constants/SECURITY_CONSTANTS.ts +44 -0
- package/src/constants/VALIDATION_CONSTANTS.ts +176 -0
- package/src/core/README.md +395 -0
- package/src/core/compiler/SchemaTransformer.ts +279 -0
- package/src/core/compiler/TypeAnalyzer.ts +378 -0
- package/src/core/compiler/TypeScriptCompilerIntegration.ts +220 -0
- package/src/core/compiler/TypeToSchemaConverter.ts +288 -0
- package/src/core/index.ts +70 -0
- package/src/core/schema/extensions/AutoDocumentation.ts +572 -0
- package/src/core/schema/extensions/ConditionalValidation.ts +330 -0
- package/src/core/schema/extensions/README.md +171 -0
- package/src/core/schema/extensions/RealtimeValidation.ts +656 -0
- package/src/core/schema/extensions/SmartInference.ts +224 -0
- package/src/core/schema/extensions/components/AutoDocumentation/Docs.ts +98 -0
- package/src/core/schema/extensions/components/AutoDocumentation/DocumentationGenerator.ts +201 -0
- package/src/core/schema/extensions/components/AutoDocumentation/InteractiveDocumentationGenerator.ts +176 -0
- package/src/core/schema/extensions/components/AutoDocumentation/OpenAPIGenerator.ts +175 -0
- package/src/core/schema/extensions/components/AutoDocumentation/SchemaAnalyzer.ts +49 -0
- package/src/core/schema/extensions/components/AutoDocumentation/TypeScriptGenerator.ts +54 -0
- package/src/core/schema/extensions/components/AutoDocumentation/index.ts +17 -0
- package/src/core/schema/extensions/components/ConditionalValidation/ConditionalBuilder.ts +101 -0
- package/src/core/schema/extensions/components/ConditionalValidation/ConditionalElse.ts +65 -0
- package/src/core/schema/extensions/components/ConditionalValidation/ConditionalThen.ts +33 -0
- package/src/core/schema/extensions/components/ConditionalValidation/Extend.ts +75 -0
- package/src/core/schema/extensions/components/ConditionalValidation/MultiConditionalBuilder.ts +16 -0
- package/src/core/schema/extensions/components/ConditionalValidation/MultiConditionalThen.ts +50 -0
- package/src/core/schema/extensions/components/ConditionalValidation/index.ts +104 -0
- package/src/core/schema/extensions/components/RealtimeValidation/FormValidator.ts +88 -0
- package/src/core/schema/extensions/components/RealtimeValidation/LiveValidator.ts +171 -0
- package/src/core/schema/extensions/components/RealtimeValidation/StreamValidator.ts +397 -0
- package/src/core/schema/extensions/components/RealtimeValidation/index.ts +114 -0
- package/src/core/schema/extensions/index.ts +76 -0
- package/src/core/schema/extensions/mods/index.ts +131 -0
- package/src/core/schema/extensions/mods/openapi-converter.ts +338 -0
- package/src/core/schema/extensions/mods/typescript-generator.ts +379 -0
- package/src/core/schema/extensions/mods/validation-engine.ts +295 -0
- package/src/core/schema/mode/interfaces/Interface.ts +364 -0
- package/src/core/schema/mode/interfaces/InterfaceSchema.ts +1838 -0
- package/src/core/schema/mode/interfaces/README.md +278 -0
- package/src/core/schema/mode/interfaces/conditional/evaluator/ConditionalEvaluator.ts +657 -0
- package/src/core/schema/mode/interfaces/conditional/parser/ConditionalAST.ts +826 -0
- package/src/core/schema/mode/interfaces/conditional/parser/ConditionalLexer.ts +992 -0
- package/src/core/schema/mode/interfaces/conditional/parser/ConditionalParser.ts +803 -0
- package/src/core/schema/mode/interfaces/conditional/parser/readme.md +406 -0
- package/src/core/schema/mode/interfaces/conditional/types/ConditionalTypes.ts +273 -0
- package/src/core/schema/mode/interfaces/errors/ErrorHandler.ts +624 -0
- package/src/core/schema/mode/interfaces/errors/types/errors.type.ts +102 -0
- package/src/core/schema/mode/interfaces/precompilation/FieldPrecompilers.ts +962 -0
- package/src/core/schema/mode/interfaces/precompilation/SchemaPrecompiler.ts +667 -0
- package/src/core/schema/mode/interfaces/typescript/ConditionalTypes.ts +1534 -0
- package/src/core/schema/mode/interfaces/typescript/IDESupport.ts +534 -0
- package/src/core/schema/mode/interfaces/typescript/TypeInference.ts +737 -0
- package/src/core/schema/mode/interfaces/typescript/index.ts +92 -0
- package/src/core/schema/mode/interfaces/validators/ConstraintParser.ts +1438 -0
- package/src/core/schema/mode/interfaces/validators/EnhancedErrorReporting.ts +227 -0
- package/src/core/schema/mode/interfaces/validators/TypeGuards.ts +288 -0
- package/src/core/schema/mode/interfaces/validators/TypeValidators.ts +660 -0
- package/src/core/schema/mode/interfaces/validators/UnionCache.ts +508 -0
- package/src/core/schema/mode/interfaces/validators/ValidationHelpers.ts +1257 -0
- package/src/core/schema/mode/interfaces/validators/index.ts +21 -0
- package/src/core/schema/mode/interfaces/validators/mods/passValidator.ts +424 -0
- package/src/core/schema/mode/interfaces/validators/mods/securityValidator.ts +1634 -0
- package/src/core/schema/mode/interfaces/validators/mods/urlValidation.ts +333 -0
- package/src/core/schema/optimization/ObjectValidationCache.ts +560 -0
- package/src/core/schema/optimization/PerformanceInitializer.ts +188 -0
- package/src/core/schema/optimization/PerformanceMonitor.ts +898 -0
- package/src/core/schema/optimization/SchemaCompiler.ts +730 -0
- package/src/core/testing/TestDataGenerator.ts +590 -0
- package/src/core/types/SchemaValidator.type.ts +210 -0
- package/src/core/types/ValidatorTypes.ts +93 -0
- package/src/core/types/extension.type.ts +109 -0
- package/src/core/types/objValidationCache.ts +17 -0
- package/src/core/types/parser.type.ts +15 -0
- package/src/core/types/perfoMonitor.ts +37 -0
- package/src/core/types/scompiler.ts +22 -0
- package/src/core/types/securityValidator.type.ts +10 -0
- package/src/core/types/types.ts +154 -0
- package/src/core/utils/Make.ts +97 -0
- package/src/core/utils/Mod.ts +1168 -0
- package/src/core/utils/UrlArgs.ts +124 -0
- package/src/core/utils/arrayToEnum.ts +89 -0
- package/src/core/utils/createUrlArgsEnumFArray.ts +11 -0
- package/src/core/utils/securityHelpers.ts +341 -0
- package/src/core/utils/securityValidatorHelpers.ts +76 -0
- package/src/index.ts +124 -0
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Conditional Evaluator
|
|
3
|
+
*
|
|
4
|
+
* Evaluates parsed conditional AST against actual data
|
|
5
|
+
* Supports all operators and provides detailed debugging information
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { ErrorHandler } from "../../errors/ErrorHandler";
|
|
9
|
+
import { ASTWalker, ASTVisitor } from "../parser/ConditionalAST";
|
|
10
|
+
import {
|
|
11
|
+
ConditionalNode,
|
|
12
|
+
LogicalExpressionNode,
|
|
13
|
+
ComparisonNode,
|
|
14
|
+
MethodCallNode,
|
|
15
|
+
FieldAccessNode,
|
|
16
|
+
LiteralNode,
|
|
17
|
+
ConstantNode,
|
|
18
|
+
ArrayNode,
|
|
19
|
+
ValueNode,
|
|
20
|
+
EvaluationContext,
|
|
21
|
+
EvaluationResult,
|
|
22
|
+
TokenType,
|
|
23
|
+
ErrorType,
|
|
24
|
+
} from "../types/ConditionalTypes";
|
|
25
|
+
|
|
26
|
+
export class ConditionalEvaluator {
|
|
27
|
+
// Performance optimization: Cache for field value lookups
|
|
28
|
+
public static readonly fieldValueCache = new Map<string, any>();
|
|
29
|
+
public static readonly methodResultCache = new Map<string, boolean>();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Clear performance caches (call between different data sets)
|
|
33
|
+
*/
|
|
34
|
+
static clearCaches(): void {
|
|
35
|
+
this.fieldValueCache.clear();
|
|
36
|
+
this.methodResultCache.clear();
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Evaluate a conditional AST against data with performance optimizations
|
|
41
|
+
*/
|
|
42
|
+
static evaluate(
|
|
43
|
+
ast: ConditionalNode,
|
|
44
|
+
data: Record<string, any>,
|
|
45
|
+
options: {
|
|
46
|
+
strict?: boolean;
|
|
47
|
+
debug?: boolean;
|
|
48
|
+
schema?: Record<string, any>;
|
|
49
|
+
validatePaths?: boolean;
|
|
50
|
+
enableCaching?: boolean;
|
|
51
|
+
parentContext?: Record<string, any>; // NEW: Support for parent context in nested validation
|
|
52
|
+
} = {}
|
|
53
|
+
): EvaluationResult {
|
|
54
|
+
const context: EvaluationContext = {
|
|
55
|
+
data,
|
|
56
|
+
schema: options.schema,
|
|
57
|
+
fieldPath: [],
|
|
58
|
+
parentContext: options.parentContext, // NEW: Add parent context to evaluation context
|
|
59
|
+
options: {
|
|
60
|
+
strict: false,
|
|
61
|
+
debug: false,
|
|
62
|
+
validatePaths: false,
|
|
63
|
+
enableCaching: true,
|
|
64
|
+
...options,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
const evaluator = new ConditionalEvaluationVisitor(context);
|
|
69
|
+
|
|
70
|
+
// Clear caches if caching is disabled or this is a new evaluation
|
|
71
|
+
if (!options.enableCaching) {
|
|
72
|
+
ConditionalEvaluator.clearCaches();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const result = ASTWalker.walk(ast, evaluator);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
value: result,
|
|
81
|
+
errors: [],
|
|
82
|
+
debugInfo: context.options?.debug
|
|
83
|
+
? evaluator.getDebugInfo()
|
|
84
|
+
: undefined,
|
|
85
|
+
};
|
|
86
|
+
} catch (error) {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
errors: [
|
|
90
|
+
ErrorHandler.createConditionalError(
|
|
91
|
+
context.fieldPath,
|
|
92
|
+
`Conditional evaluation error: ${error instanceof Error ? error.message : "Unknown error"}`,
|
|
93
|
+
data
|
|
94
|
+
),
|
|
95
|
+
],
|
|
96
|
+
debugInfo: context.options?.debug
|
|
97
|
+
? evaluator.getDebugInfo()
|
|
98
|
+
: undefined,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* AST Visitor for evaluating conditional expressions
|
|
106
|
+
*/
|
|
107
|
+
class ConditionalEvaluationVisitor implements ASTVisitor<any> {
|
|
108
|
+
private context: EvaluationContext;
|
|
109
|
+
private debugPath: string[] = [];
|
|
110
|
+
private conditionResults: Record<string, boolean> = {};
|
|
111
|
+
|
|
112
|
+
constructor(context: EvaluationContext) {
|
|
113
|
+
this.context = context;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
getDebugInfo() {
|
|
117
|
+
return {
|
|
118
|
+
evaluationPath: this.debugPath,
|
|
119
|
+
conditionResults: this.conditionResults,
|
|
120
|
+
finalCondition: Object.values(this.conditionResults).pop() || false,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
visitConditional(node: ConditionalNode): any {
|
|
125
|
+
this.debugPath.push("Evaluating conditional");
|
|
126
|
+
|
|
127
|
+
// Evaluate condition
|
|
128
|
+
const conditionResult = ASTWalker.walk(node.condition, this);
|
|
129
|
+
this.conditionResults[`condition_${node.position}`] = conditionResult;
|
|
130
|
+
|
|
131
|
+
if (conditionResult) {
|
|
132
|
+
this.debugPath.push("Condition true - evaluating then branch");
|
|
133
|
+
return ASTWalker.walk(node.thenValue, this);
|
|
134
|
+
} else if (node.elseValue) {
|
|
135
|
+
this.debugPath.push("Condition false - evaluating else branch");
|
|
136
|
+
return ASTWalker.walk(node.elseValue, this);
|
|
137
|
+
} else {
|
|
138
|
+
this.debugPath.push("Condition false - no else branch");
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
visitLogicalExpression(node: LogicalExpressionNode): boolean {
|
|
144
|
+
this.debugPath.push(`Evaluating logical ${node.operator}`);
|
|
145
|
+
|
|
146
|
+
const leftResult = ASTWalker.walk(node.left, this);
|
|
147
|
+
|
|
148
|
+
// Short-circuit evaluation
|
|
149
|
+
if (node.operator === "AND" && !leftResult) {
|
|
150
|
+
this.debugPath.push("AND short-circuit: left is false");
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (node.operator === "OR" && leftResult) {
|
|
155
|
+
this.debugPath.push("OR short-circuit: left is true");
|
|
156
|
+
return true;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
const rightResult = ASTWalker.walk(node.right, this);
|
|
160
|
+
|
|
161
|
+
const result =
|
|
162
|
+
node.operator === "AND"
|
|
163
|
+
? leftResult && rightResult
|
|
164
|
+
: leftResult || rightResult;
|
|
165
|
+
this.debugPath.push(`${node.operator} result: ${result}`);
|
|
166
|
+
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
visitComparison(node: ComparisonNode): boolean {
|
|
171
|
+
const leftValue = ASTWalker.walk(node.left, this);
|
|
172
|
+
const rightValue = ASTWalker.walk(node.right, this);
|
|
173
|
+
|
|
174
|
+
this.debugPath.push(
|
|
175
|
+
`Comparing ${leftValue} ${this.getOperatorSymbol(node.operator)} ${rightValue}`
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
const result = this.performComparison(leftValue, rightValue, node.operator);
|
|
179
|
+
this.debugPath.push(`Comparison result: ${result}`);
|
|
180
|
+
|
|
181
|
+
return result;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
visitMethodCall(node: MethodCallNode): boolean {
|
|
185
|
+
// Use runtime field access for runtime methods, schema validation for legacy methods
|
|
186
|
+
const fieldValue = node.isRuntimeMethod
|
|
187
|
+
? this.getRuntimeFieldValue(node.field.path)
|
|
188
|
+
: ASTWalker.walk(node.field, this);
|
|
189
|
+
|
|
190
|
+
const args = node.arguments
|
|
191
|
+
? node.arguments.map((arg) => ASTWalker.walk(arg, this))
|
|
192
|
+
: [];
|
|
193
|
+
|
|
194
|
+
this.debugPath.push(
|
|
195
|
+
`Calling ${node.isRuntimeMethod ? "runtime" : "legacy"} method ${TokenType[node.method]} on ${fieldValue} with args [${args.join(", ")}]`
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const result = this.performMethodCall(fieldValue, node.method, args);
|
|
199
|
+
this.debugPath.push(`Method result: ${result}`);
|
|
200
|
+
|
|
201
|
+
return result;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
visitFieldAccess(node: FieldAccessNode): any {
|
|
205
|
+
const value = this.getFieldValue(node.path);
|
|
206
|
+
this.debugPath.push(`Field ${node.path.join(".")} = ${value}`);
|
|
207
|
+
return value;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
visitLiteral(node: LiteralNode): any {
|
|
211
|
+
return node.value;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
visitConstant(node: ConstantNode): any {
|
|
215
|
+
// For schema validation, we need to preserve the constant prefix
|
|
216
|
+
// so the validation logic knows this is a constant value
|
|
217
|
+
return `=${node.value}`;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
visitArray(node: ArrayNode): any[] {
|
|
221
|
+
return node.elements.map((element) => ASTWalker.walk(element, this));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Get field value from runtime data without schema validation
|
|
226
|
+
* Used for runtime methods (starting with $) - with performance caching and parent context support
|
|
227
|
+
*
|
|
228
|
+
* FIXED: Path resolution follows user specification:
|
|
229
|
+
* 1. Simple paths (e.g., "p1") resolve from ROOT context first
|
|
230
|
+
* 2. Nested paths (e.g., "nested.p1") resolve as absolute paths from ROOT
|
|
231
|
+
* 3. Only .$exists() method can bypass path validation errors
|
|
232
|
+
*/
|
|
233
|
+
private getRuntimeFieldValue(path: string[]): any {
|
|
234
|
+
const pathKey = path.join(".");
|
|
235
|
+
|
|
236
|
+
// Check cache first if caching is enabled
|
|
237
|
+
if (
|
|
238
|
+
this.context.options?.enableCaching &&
|
|
239
|
+
ConditionalEvaluator.fieldValueCache.has(pathKey)
|
|
240
|
+
) {
|
|
241
|
+
return ConditionalEvaluator.fieldValueCache.get(pathKey);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// FIXED: Try ROOT context first (parent context = main object)
|
|
245
|
+
if (this.context.parentContext) {
|
|
246
|
+
let rootCurrent = this.context.parentContext;
|
|
247
|
+
let foundInRoot = true;
|
|
248
|
+
|
|
249
|
+
for (const segment of path) {
|
|
250
|
+
if (rootCurrent === null || rootCurrent === undefined) {
|
|
251
|
+
foundInRoot = false;
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
if (!(segment in rootCurrent)) {
|
|
255
|
+
foundInRoot = false;
|
|
256
|
+
break;
|
|
257
|
+
}
|
|
258
|
+
rootCurrent = rootCurrent[segment];
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (foundInRoot) {
|
|
262
|
+
// Cache the result if caching is enabled
|
|
263
|
+
if (this.context.options?.enableCaching) {
|
|
264
|
+
ConditionalEvaluator.fieldValueCache.set(pathKey, rootCurrent);
|
|
265
|
+
}
|
|
266
|
+
return rootCurrent;
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// FALLBACK: If not found in root context, try local context
|
|
271
|
+
// This should only happen for paths that don't exist in root
|
|
272
|
+
let current = this.context.data;
|
|
273
|
+
let foundInLocal = true;
|
|
274
|
+
|
|
275
|
+
for (const segment of path) {
|
|
276
|
+
if (current === null || current === undefined) {
|
|
277
|
+
foundInLocal = false;
|
|
278
|
+
break;
|
|
279
|
+
}
|
|
280
|
+
if (!(segment in current)) {
|
|
281
|
+
foundInLocal = false;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
current = current[segment];
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// If found in local context, cache and return the value
|
|
288
|
+
if (foundInLocal) {
|
|
289
|
+
if (this.context.options?.enableCaching) {
|
|
290
|
+
ConditionalEvaluator.fieldValueCache.set(pathKey, current);
|
|
291
|
+
}
|
|
292
|
+
return current;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Field not found in either context
|
|
296
|
+
const result = undefined;
|
|
297
|
+
// Cache the result if caching is enabled
|
|
298
|
+
if (this.context.options?.enableCaching) {
|
|
299
|
+
ConditionalEvaluator.fieldValueCache.set(pathKey, result);
|
|
300
|
+
}
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get field value from data using path
|
|
306
|
+
* Enhanced with schema path validation and parent context support
|
|
307
|
+
*/
|
|
308
|
+
private getFieldValue(path: string[]): any {
|
|
309
|
+
// CRITICAL FIX: Skip strict schema path validation when we have parent context
|
|
310
|
+
// This allows nested conditional validation to reference parent fields
|
|
311
|
+
const shouldValidatePaths =
|
|
312
|
+
this.context.options?.validatePaths &&
|
|
313
|
+
this.context.schema &&
|
|
314
|
+
!this.context.parentContext;
|
|
315
|
+
|
|
316
|
+
if (shouldValidatePaths) {
|
|
317
|
+
const pathValidation = this.validateSchemaPath(path);
|
|
318
|
+
if (!pathValidation.isValid) {
|
|
319
|
+
throw new Error(
|
|
320
|
+
`Invalid property path: ${path.join(".")}. ${pathValidation.error}`
|
|
321
|
+
);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// FIXED: Try ROOT context first (parent context = main object)
|
|
326
|
+
if (this.context.parentContext) {
|
|
327
|
+
let rootCurrent = this.context.parentContext;
|
|
328
|
+
let foundInRoot = true;
|
|
329
|
+
|
|
330
|
+
for (const segment of path) {
|
|
331
|
+
if (rootCurrent === null || rootCurrent === undefined) {
|
|
332
|
+
foundInRoot = false;
|
|
333
|
+
break;
|
|
334
|
+
}
|
|
335
|
+
if (!(segment in rootCurrent)) {
|
|
336
|
+
foundInRoot = false;
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
rootCurrent = rootCurrent[segment];
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
if (foundInRoot) {
|
|
343
|
+
return rootCurrent;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// FALLBACK: If not found in root context, try local context
|
|
348
|
+
// This should only happen for paths that don't exist in root
|
|
349
|
+
let current = this.context.data;
|
|
350
|
+
let foundInLocal = true;
|
|
351
|
+
|
|
352
|
+
for (const segment of path) {
|
|
353
|
+
if (current === null || current === undefined) {
|
|
354
|
+
foundInLocal = false;
|
|
355
|
+
break;
|
|
356
|
+
}
|
|
357
|
+
if (!(segment in current)) {
|
|
358
|
+
foundInLocal = false;
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
current = current[segment];
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
// If found in local context, return the value
|
|
365
|
+
if (foundInLocal) {
|
|
366
|
+
return current;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
// If path validation is enabled and we couldn't find the field anywhere, throw error
|
|
370
|
+
if (this.context.options?.validatePaths) {
|
|
371
|
+
throw new Error(
|
|
372
|
+
`Property path ${path.join(".")} not found in local or parent context`
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return undefined;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Validate that a property path exists in the schema definition
|
|
381
|
+
* FIXED: Handle "any" type fields correctly - they can contain arbitrary nested properties
|
|
382
|
+
*/
|
|
383
|
+
private validateSchemaPath(path: string[]): {
|
|
384
|
+
isValid: boolean;
|
|
385
|
+
error?: string;
|
|
386
|
+
} {
|
|
387
|
+
if (!this.context.schema) {
|
|
388
|
+
return { isValid: true }; // No schema to validate against
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
let currentSchema = this.context.schema;
|
|
392
|
+
const pathSoFar: string[] = [];
|
|
393
|
+
|
|
394
|
+
for (const segment of path) {
|
|
395
|
+
pathSoFar.push(segment);
|
|
396
|
+
|
|
397
|
+
if (typeof currentSchema !== "object" || currentSchema === null) {
|
|
398
|
+
return {
|
|
399
|
+
isValid: false,
|
|
400
|
+
error: `Cannot access property "${segment}" on non-object at path: ${pathSoFar.slice(0, -1).join(".")}`,
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (!(segment in currentSchema)) {
|
|
405
|
+
return {
|
|
406
|
+
isValid: false,
|
|
407
|
+
error: `Property "${segment}" does not exist in schema at path: ${pathSoFar.slice(0, -1).join(".") || "root"}`,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
currentSchema = currentSchema[segment];
|
|
412
|
+
|
|
413
|
+
// FIXED: If we encounter an "any" type field, skip further validation
|
|
414
|
+
// since "any" can contain arbitrary nested properties
|
|
415
|
+
if (typeof currentSchema === "string") {
|
|
416
|
+
const schemaStr = currentSchema as string;
|
|
417
|
+
if (
|
|
418
|
+
schemaStr === "any" ||
|
|
419
|
+
schemaStr === "any?" ||
|
|
420
|
+
schemaStr.startsWith("any") ||
|
|
421
|
+
schemaStr.includes("any")
|
|
422
|
+
) {
|
|
423
|
+
return { isValid: true }; // "any" type allows arbitrary nested access
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return { isValid: true };
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Perform comparison operation
|
|
433
|
+
*/
|
|
434
|
+
private performComparison(
|
|
435
|
+
left: any,
|
|
436
|
+
right: any,
|
|
437
|
+
operator: TokenType
|
|
438
|
+
): boolean {
|
|
439
|
+
switch (operator) {
|
|
440
|
+
case TokenType.EQUALS:
|
|
441
|
+
return left == right; // Loose equality
|
|
442
|
+
|
|
443
|
+
case TokenType.NOT_EQUALS:
|
|
444
|
+
return left != right; // Loose inequality
|
|
445
|
+
|
|
446
|
+
case TokenType.GREATER_THAN:
|
|
447
|
+
return Number(left) > Number(right);
|
|
448
|
+
|
|
449
|
+
case TokenType.GREATER_EQUAL:
|
|
450
|
+
return Number(left) >= Number(right);
|
|
451
|
+
|
|
452
|
+
case TokenType.LESS_THAN:
|
|
453
|
+
return Number(left) < Number(right);
|
|
454
|
+
|
|
455
|
+
case TokenType.LESS_EQUAL:
|
|
456
|
+
return Number(left) <= Number(right);
|
|
457
|
+
|
|
458
|
+
case TokenType.MATCHES:
|
|
459
|
+
return this.performRegexMatch(left, right);
|
|
460
|
+
|
|
461
|
+
case TokenType.NOT_MATCHES:
|
|
462
|
+
return !this.performRegexMatch(left, right);
|
|
463
|
+
|
|
464
|
+
default:
|
|
465
|
+
throw new Error(`Unknown comparison operator: ${TokenType[operator]}`);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Perform method call operation
|
|
471
|
+
*/
|
|
472
|
+
private performMethodCall(
|
|
473
|
+
fieldValue: any,
|
|
474
|
+
method: TokenType,
|
|
475
|
+
args: any[]
|
|
476
|
+
): boolean {
|
|
477
|
+
switch (method) {
|
|
478
|
+
case TokenType.IN:
|
|
479
|
+
if (args.length === 0) {
|
|
480
|
+
return false; // No values to check against
|
|
481
|
+
}
|
|
482
|
+
// Handle comma-separated values that were parsed as a single string
|
|
483
|
+
const inValues = this.expandCommaSeparatedArgs(args);
|
|
484
|
+
return inValues.includes(fieldValue);
|
|
485
|
+
|
|
486
|
+
case TokenType.NOT_IN:
|
|
487
|
+
if (args.length === 0) {
|
|
488
|
+
return true; // If no values provided, field is not in empty set
|
|
489
|
+
}
|
|
490
|
+
// Handle comma-separated values that were parsed as a single string
|
|
491
|
+
const notInValues = this.expandCommaSeparatedArgs(args);
|
|
492
|
+
return !notInValues.includes(fieldValue);
|
|
493
|
+
|
|
494
|
+
case TokenType.EXISTS:
|
|
495
|
+
return fieldValue !== undefined && fieldValue !== null;
|
|
496
|
+
|
|
497
|
+
case TokenType.NOT_EXISTS:
|
|
498
|
+
return fieldValue === undefined || fieldValue === null;
|
|
499
|
+
|
|
500
|
+
case TokenType.EMPTY:
|
|
501
|
+
if (typeof fieldValue === "string") {
|
|
502
|
+
return fieldValue.trim().length === 0;
|
|
503
|
+
}
|
|
504
|
+
if (Array.isArray(fieldValue)) {
|
|
505
|
+
return fieldValue.length === 0;
|
|
506
|
+
}
|
|
507
|
+
if (typeof fieldValue === "object" && fieldValue !== null) {
|
|
508
|
+
return Object.keys(fieldValue).length === 0;
|
|
509
|
+
}
|
|
510
|
+
return fieldValue === null || fieldValue === undefined;
|
|
511
|
+
|
|
512
|
+
case TokenType.NOT_EMPTY:
|
|
513
|
+
if (typeof fieldValue === "string") {
|
|
514
|
+
return fieldValue.trim().length > 0;
|
|
515
|
+
}
|
|
516
|
+
if (Array.isArray(fieldValue)) {
|
|
517
|
+
return fieldValue.length > 0;
|
|
518
|
+
}
|
|
519
|
+
if (typeof fieldValue === "object" && fieldValue !== null) {
|
|
520
|
+
return Object.keys(fieldValue).length > 0;
|
|
521
|
+
}
|
|
522
|
+
return fieldValue !== null && fieldValue !== undefined;
|
|
523
|
+
|
|
524
|
+
case TokenType.NULL:
|
|
525
|
+
return fieldValue === null;
|
|
526
|
+
|
|
527
|
+
case TokenType.NOT_NULL:
|
|
528
|
+
return fieldValue !== null;
|
|
529
|
+
|
|
530
|
+
case TokenType.CONTAINS:
|
|
531
|
+
if (args.length === 0) {
|
|
532
|
+
return false; // No argument provided
|
|
533
|
+
}
|
|
534
|
+
if (typeof fieldValue === "string") {
|
|
535
|
+
return fieldValue.includes(String(args[0]));
|
|
536
|
+
}
|
|
537
|
+
if (Array.isArray(fieldValue)) {
|
|
538
|
+
// For arrays, check if any of the expanded arguments are contained
|
|
539
|
+
const containsValues = this.expandCommaSeparatedArgs(args);
|
|
540
|
+
return containsValues.some((value) => fieldValue.includes(value));
|
|
541
|
+
}
|
|
542
|
+
return false;
|
|
543
|
+
|
|
544
|
+
case TokenType.NOT_CONTAINS:
|
|
545
|
+
return !this.performMethodCall(fieldValue, TokenType.CONTAINS, args);
|
|
546
|
+
|
|
547
|
+
case TokenType.STARTS_WITH:
|
|
548
|
+
if (args.length === 0) {
|
|
549
|
+
return false; // No argument provided
|
|
550
|
+
}
|
|
551
|
+
if (typeof fieldValue === "string") {
|
|
552
|
+
return fieldValue.startsWith(String(args[0]));
|
|
553
|
+
}
|
|
554
|
+
return false;
|
|
555
|
+
|
|
556
|
+
case TokenType.ENDS_WITH:
|
|
557
|
+
if (args.length === 0) {
|
|
558
|
+
return false; // No argument provided
|
|
559
|
+
}
|
|
560
|
+
if (typeof fieldValue === "string") {
|
|
561
|
+
return fieldValue.endsWith(String(args[0]));
|
|
562
|
+
}
|
|
563
|
+
return false;
|
|
564
|
+
|
|
565
|
+
case TokenType.BETWEEN:
|
|
566
|
+
if (args.length >= 2) {
|
|
567
|
+
const num = Number(fieldValue);
|
|
568
|
+
const min = Number(args[0]);
|
|
569
|
+
const max = Number(args[1]);
|
|
570
|
+
|
|
571
|
+
// Validate that all values are valid numbers
|
|
572
|
+
if (isNaN(num) || isNaN(min) || isNaN(max)) {
|
|
573
|
+
return false;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
return num >= min && num <= max;
|
|
577
|
+
}
|
|
578
|
+
return false;
|
|
579
|
+
|
|
580
|
+
default:
|
|
581
|
+
throw new Error(`Unknown method: ${TokenType[method]}`);
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
/**
|
|
586
|
+
* Perform regex matching with enhanced pattern support
|
|
587
|
+
*/
|
|
588
|
+
private performRegexMatch(value: any, pattern: any): boolean {
|
|
589
|
+
const valueStr = String(value);
|
|
590
|
+
const patternStr = String(pattern);
|
|
591
|
+
|
|
592
|
+
try {
|
|
593
|
+
// Handle common patterns that might not be valid regex
|
|
594
|
+
if (
|
|
595
|
+
patternStr.includes("^") ||
|
|
596
|
+
patternStr.includes("$") ||
|
|
597
|
+
patternStr.includes("|")
|
|
598
|
+
) {
|
|
599
|
+
// This looks like a regex pattern
|
|
600
|
+
const regex = new RegExp(patternStr);
|
|
601
|
+
return regex.test(valueStr);
|
|
602
|
+
} else {
|
|
603
|
+
// Simple string matching
|
|
604
|
+
return valueStr.includes(patternStr);
|
|
605
|
+
}
|
|
606
|
+
} catch (error) {
|
|
607
|
+
// Invalid regex, fall back to string contains
|
|
608
|
+
return valueStr.includes(patternStr);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
/**
|
|
613
|
+
* Expand comma-separated arguments for .in() and .!in() methods
|
|
614
|
+
* Handles cases where "admin,manager" is parsed as a single string
|
|
615
|
+
*/
|
|
616
|
+
private expandCommaSeparatedArgs(args: any[]): any[] {
|
|
617
|
+
const expandedArgs: any[] = [];
|
|
618
|
+
|
|
619
|
+
for (const arg of args) {
|
|
620
|
+
if (typeof arg === "string" && arg.includes(",")) {
|
|
621
|
+
// Split comma-separated values and trim whitespace
|
|
622
|
+
const splitValues = arg.split(",").map((v) => v.trim());
|
|
623
|
+
expandedArgs.push(...splitValues);
|
|
624
|
+
} else {
|
|
625
|
+
expandedArgs.push(arg);
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
return expandedArgs;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/**
|
|
633
|
+
* Get operator symbol for debugging
|
|
634
|
+
*/
|
|
635
|
+
private getOperatorSymbol(operator: TokenType): string {
|
|
636
|
+
switch (operator) {
|
|
637
|
+
case TokenType.EQUALS:
|
|
638
|
+
return "=";
|
|
639
|
+
case TokenType.NOT_EQUALS:
|
|
640
|
+
return "!=";
|
|
641
|
+
case TokenType.GREATER_THAN:
|
|
642
|
+
return ">";
|
|
643
|
+
case TokenType.GREATER_EQUAL:
|
|
644
|
+
return ">=";
|
|
645
|
+
case TokenType.LESS_THAN:
|
|
646
|
+
return "<";
|
|
647
|
+
case TokenType.LESS_EQUAL:
|
|
648
|
+
return "<=";
|
|
649
|
+
case TokenType.MATCHES:
|
|
650
|
+
return "~";
|
|
651
|
+
case TokenType.NOT_MATCHES:
|
|
652
|
+
return "!~";
|
|
653
|
+
default:
|
|
654
|
+
return TokenType[operator];
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|