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,826 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abstract Syntax Tree definitions for conditional expressions
|
|
3
|
+
*
|
|
4
|
+
* Provides a structured representation of parsed conditional syntax
|
|
5
|
+
* that can be efficiently evaluated and analyzed.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { MAX_AST_TRAVERSAL_DEPTH } from "../../../../../../constants/VALIDATION_CONSTANTS";
|
|
9
|
+
import {
|
|
10
|
+
ASTNode,
|
|
11
|
+
ASTNodeType,
|
|
12
|
+
ConditionalNode,
|
|
13
|
+
LogicalExpressionNode,
|
|
14
|
+
ComparisonNode,
|
|
15
|
+
MethodCallNode,
|
|
16
|
+
FieldAccessNode,
|
|
17
|
+
LiteralNode,
|
|
18
|
+
ConstantNode,
|
|
19
|
+
ArrayNode,
|
|
20
|
+
TokenType,
|
|
21
|
+
} from "../types/ConditionalTypes";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* AST Builder - Factory for creating AST nodes
|
|
25
|
+
*/
|
|
26
|
+
export class ASTBuilder {
|
|
27
|
+
// Private validation helpers
|
|
28
|
+
private static readonly VALID_LOGICAL_OPERATORS = ["AND", "OR"] as const;
|
|
29
|
+
private static readonly VALID_DATA_TYPES = [
|
|
30
|
+
"string",
|
|
31
|
+
"number",
|
|
32
|
+
"boolean",
|
|
33
|
+
] as const;
|
|
34
|
+
private static readonly MAX_NESTING_DEPTH = 50;
|
|
35
|
+
private static readonly MAX_ARRAY_SIZE = 1000;
|
|
36
|
+
|
|
37
|
+
private static _validatePosition(position: number): void {
|
|
38
|
+
if (position < 0 || !Number.isInteger(position)) {
|
|
39
|
+
throw new Error(
|
|
40
|
+
`Invalid position: ${position}. Position must be a non-negative integer.`
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
private static _validatePath(path: string[]): void {
|
|
46
|
+
if (!Array.isArray(path) || path.length === 0) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
"Field access path must be a non-empty array of strings."
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
for (const segment of path) {
|
|
53
|
+
if (typeof segment !== "string" || segment.trim() === "") {
|
|
54
|
+
throw new Error(
|
|
55
|
+
`Invalid path segment: ${segment}. All segments must be non-empty strings.`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private static _validateDataType(
|
|
62
|
+
dataType: string
|
|
63
|
+
): asserts dataType is "string" | "number" | "boolean" {
|
|
64
|
+
if (!this.VALID_DATA_TYPES.includes(dataType as any)) {
|
|
65
|
+
throw new Error(
|
|
66
|
+
`Invalid data type: ${dataType}. Must be one of: ${this.VALID_DATA_TYPES.join(", ")}`
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private static _validateLogicalOperator(
|
|
72
|
+
operator: string
|
|
73
|
+
): asserts operator is "AND" | "OR" {
|
|
74
|
+
if (!this.VALID_LOGICAL_OPERATORS.includes(operator as any)) {
|
|
75
|
+
throw new Error(
|
|
76
|
+
`Invalid logical operator: ${operator}. Must be one of: ${this.VALID_LOGICAL_OPERATORS.join(", ")}`
|
|
77
|
+
);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private static _validateArraySize(elements: any[]): void {
|
|
82
|
+
if (elements.length > this.MAX_ARRAY_SIZE) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`Array too large: ${elements.length} elements. Maximum allowed: ${this.MAX_ARRAY_SIZE}`
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
private static _deepFreeze<T extends object>(obj: T): T {
|
|
90
|
+
Object.freeze(obj);
|
|
91
|
+
Object.getOwnPropertyNames(obj).forEach((prop) => {
|
|
92
|
+
const value = (obj as any)[prop];
|
|
93
|
+
if (value && typeof value === "object") {
|
|
94
|
+
this._deepFreeze(value);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return obj;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Create a conditional node
|
|
102
|
+
*/
|
|
103
|
+
static createConditional(
|
|
104
|
+
condition: ConditionalNode["condition"],
|
|
105
|
+
thenValue: ConditionalNode["thenValue"],
|
|
106
|
+
elseValue?: ConditionalNode["elseValue"],
|
|
107
|
+
position: number = 0
|
|
108
|
+
): ConditionalNode {
|
|
109
|
+
// Validate inputs
|
|
110
|
+
this._validatePosition(position);
|
|
111
|
+
|
|
112
|
+
if (!condition) {
|
|
113
|
+
throw new Error("Conditional node requires a condition.");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (!thenValue) {
|
|
117
|
+
throw new Error("Conditional node requires a then value.");
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const node: ConditionalNode = {
|
|
121
|
+
type: ASTNodeType.CONDITIONAL,
|
|
122
|
+
condition,
|
|
123
|
+
thenValue,
|
|
124
|
+
elseValue,
|
|
125
|
+
position,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return this._deepFreeze(node);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Create a logical expression node (AND/OR)
|
|
133
|
+
*/
|
|
134
|
+
static createLogicalExpression(
|
|
135
|
+
operator: "AND" | "OR",
|
|
136
|
+
left: LogicalExpressionNode["left"],
|
|
137
|
+
right: LogicalExpressionNode["right"],
|
|
138
|
+
position: number = 0
|
|
139
|
+
): LogicalExpressionNode {
|
|
140
|
+
// Validate inputs
|
|
141
|
+
this._validatePosition(position);
|
|
142
|
+
this._validateLogicalOperator(operator);
|
|
143
|
+
|
|
144
|
+
if (!left) {
|
|
145
|
+
throw new Error("Logical expression requires a left operand.");
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (!right) {
|
|
149
|
+
throw new Error("Logical expression requires a right operand.");
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const node: LogicalExpressionNode = {
|
|
153
|
+
type: ASTNodeType.LOGICAL_EXPRESSION,
|
|
154
|
+
operator,
|
|
155
|
+
left,
|
|
156
|
+
right,
|
|
157
|
+
position,
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
return this._deepFreeze(node);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Create a comparison node
|
|
165
|
+
*/
|
|
166
|
+
static createComparison(
|
|
167
|
+
operator: TokenType,
|
|
168
|
+
left: FieldAccessNode,
|
|
169
|
+
right: LiteralNode,
|
|
170
|
+
position: number = 0
|
|
171
|
+
): ComparisonNode {
|
|
172
|
+
// Validate inputs
|
|
173
|
+
this._validatePosition(position);
|
|
174
|
+
|
|
175
|
+
if (!operator) {
|
|
176
|
+
throw new Error("Comparison node requires an operator.");
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (!left) {
|
|
180
|
+
throw new Error(
|
|
181
|
+
"Comparison node requires a left operand (field access)."
|
|
182
|
+
);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (!right) {
|
|
186
|
+
throw new Error("Comparison node requires a right operand (literal).");
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const node: ComparisonNode = {
|
|
190
|
+
type: ASTNodeType.COMPARISON,
|
|
191
|
+
operator,
|
|
192
|
+
left,
|
|
193
|
+
right,
|
|
194
|
+
position,
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
return this._deepFreeze(node);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Create a method call node
|
|
202
|
+
*/
|
|
203
|
+
static createMethodCall(
|
|
204
|
+
method: TokenType,
|
|
205
|
+
field: FieldAccessNode,
|
|
206
|
+
args?: LiteralNode[],
|
|
207
|
+
position: number = 0,
|
|
208
|
+
isRuntimeMethod: boolean = false
|
|
209
|
+
): MethodCallNode {
|
|
210
|
+
// Validate inputs
|
|
211
|
+
this._validatePosition(position);
|
|
212
|
+
|
|
213
|
+
if (!method) {
|
|
214
|
+
throw new Error("Method call node requires a method.");
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
if (!field) {
|
|
218
|
+
throw new Error("Method call node requires a field.");
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (args) {
|
|
222
|
+
this._validateArraySize(args);
|
|
223
|
+
|
|
224
|
+
// Validate each argument
|
|
225
|
+
for (let i = 0; i < args.length; i++) {
|
|
226
|
+
if (!args[i] || args[i].type !== ASTNodeType.LITERAL) {
|
|
227
|
+
throw new Error(
|
|
228
|
+
`Invalid argument at index ${i}: Method call arguments must be literal nodes.`
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const node: MethodCallNode = {
|
|
235
|
+
type: ASTNodeType.METHOD_CALL,
|
|
236
|
+
method,
|
|
237
|
+
field,
|
|
238
|
+
arguments: args ? [...args] : undefined, // Shallow copy for safety
|
|
239
|
+
position,
|
|
240
|
+
isRuntimeMethod,
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
return this._deepFreeze(node);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Create a field access node
|
|
248
|
+
*/
|
|
249
|
+
static createFieldAccess(
|
|
250
|
+
path: string[],
|
|
251
|
+
position: number = 0
|
|
252
|
+
): FieldAccessNode {
|
|
253
|
+
// Validate inputs
|
|
254
|
+
this._validatePosition(position);
|
|
255
|
+
this._validatePath(path);
|
|
256
|
+
|
|
257
|
+
const node: FieldAccessNode = {
|
|
258
|
+
type: ASTNodeType.FIELD_ACCESS,
|
|
259
|
+
path: [...path], // Create defensive copy
|
|
260
|
+
position,
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
return this._deepFreeze(node);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Create a literal node
|
|
268
|
+
*/
|
|
269
|
+
static createLiteral(
|
|
270
|
+
value: string | number | boolean,
|
|
271
|
+
dataType: "string" | "number" | "boolean",
|
|
272
|
+
position: number = 0
|
|
273
|
+
): LiteralNode {
|
|
274
|
+
// Validate inputs
|
|
275
|
+
this._validatePosition(position);
|
|
276
|
+
this._validateDataType(dataType);
|
|
277
|
+
|
|
278
|
+
if (value === null || value === undefined) {
|
|
279
|
+
throw new Error("Literal node requires a non-null, non-undefined value.");
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Type consistency validation
|
|
283
|
+
const actualType = typeof value;
|
|
284
|
+
if (actualType !== dataType) {
|
|
285
|
+
throw new Error(
|
|
286
|
+
`Type mismatch: value type '${actualType}' does not match declared type '${dataType}'.`
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Additional validations based on type
|
|
291
|
+
if (dataType === "number" && !Number.isFinite(value as number)) {
|
|
292
|
+
throw new Error("Number literal must be finite.");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
if (
|
|
296
|
+
dataType === "string" &&
|
|
297
|
+
typeof value === "string" &&
|
|
298
|
+
value.length > 10000
|
|
299
|
+
) {
|
|
300
|
+
throw new Error(
|
|
301
|
+
"String literal too long. Maximum length: 10000 characters."
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
const node: LiteralNode = {
|
|
306
|
+
type: ASTNodeType.LITERAL,
|
|
307
|
+
value,
|
|
308
|
+
dataType,
|
|
309
|
+
position,
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
return this._deepFreeze(node);
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Create a constant node
|
|
317
|
+
*/
|
|
318
|
+
static createConstant(value: string, position: number = 0): ConstantNode {
|
|
319
|
+
// Validate inputs
|
|
320
|
+
this._validatePosition(position);
|
|
321
|
+
|
|
322
|
+
if (typeof value !== "string" || value.trim() === "") {
|
|
323
|
+
throw new Error("Constant node requires a non-empty string value.");
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (value.length > 1000) {
|
|
327
|
+
throw new Error(
|
|
328
|
+
"Constant value too long. Maximum length: 1000 characters."
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const node: ConstantNode = {
|
|
333
|
+
type: ASTNodeType.CONSTANT,
|
|
334
|
+
value: value.trim(),
|
|
335
|
+
position,
|
|
336
|
+
};
|
|
337
|
+
|
|
338
|
+
return this._deepFreeze(node);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Create an array node
|
|
343
|
+
*/
|
|
344
|
+
static createArray(elements: LiteralNode[], position: number = 0): ArrayNode {
|
|
345
|
+
// Validate inputs
|
|
346
|
+
this._validatePosition(position);
|
|
347
|
+
|
|
348
|
+
if (!Array.isArray(elements)) {
|
|
349
|
+
throw new Error("Array node requires an array of elements.");
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
this._validateArraySize(elements);
|
|
353
|
+
|
|
354
|
+
// Validate each element
|
|
355
|
+
for (let i = 0; i < elements.length; i++) {
|
|
356
|
+
if (!elements[i] || elements[i].type !== ASTNodeType.LITERAL) {
|
|
357
|
+
throw new Error(
|
|
358
|
+
`Invalid element at index ${i}: Array elements must be literal nodes.`
|
|
359
|
+
);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
const node: ArrayNode = {
|
|
364
|
+
type: ASTNodeType.ARRAY,
|
|
365
|
+
elements: [...elements], // Create defensive copy
|
|
366
|
+
position,
|
|
367
|
+
};
|
|
368
|
+
|
|
369
|
+
return this._deepFreeze(node);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* AST Visitor pattern for traversing and analyzing AST
|
|
375
|
+
*/
|
|
376
|
+
export interface ASTVisitor<T> {
|
|
377
|
+
visitConditional(node: ConditionalNode): T;
|
|
378
|
+
visitLogicalExpression(node: LogicalExpressionNode): T;
|
|
379
|
+
visitComparison(node: ComparisonNode): T;
|
|
380
|
+
visitMethodCall(node: MethodCallNode): T;
|
|
381
|
+
visitFieldAccess(node: FieldAccessNode): T;
|
|
382
|
+
visitLiteral(node: LiteralNode): T;
|
|
383
|
+
visitConstant(node: ConstantNode): T;
|
|
384
|
+
visitArray(node: ArrayNode): T;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* AST Walker - Traverses AST nodes using visitor pattern
|
|
389
|
+
*/
|
|
390
|
+
export class ASTWalker {
|
|
391
|
+
private static readonly MAX_DEPTH = MAX_AST_TRAVERSAL_DEPTH;
|
|
392
|
+
private static _currentDepth = 0;
|
|
393
|
+
|
|
394
|
+
private static _checkDepth(): void {
|
|
395
|
+
if (this._currentDepth >= this.MAX_DEPTH) {
|
|
396
|
+
throw new Error(
|
|
397
|
+
`Maximum traversal depth exceeded: ${this.MAX_DEPTH}. Possible circular reference or deeply nested structure.`
|
|
398
|
+
);
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
private static _validateNode(node: ASTNode): void {
|
|
403
|
+
if (!node || typeof node !== "object") {
|
|
404
|
+
throw new Error("Invalid AST node: node must be a non-null object.");
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (!node.type || !Object.values(ASTNodeType).includes(node.type)) {
|
|
408
|
+
throw new Error(`Invalid AST node type: ${node.type}`);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
private static _validateVisitor<T>(visitor: ASTVisitor<T>): void {
|
|
413
|
+
if (!visitor || typeof visitor !== "object") {
|
|
414
|
+
throw new Error("Visitor must be a non-null object.");
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const requiredMethods = [
|
|
418
|
+
"visitConditional",
|
|
419
|
+
"visitLogicalExpression",
|
|
420
|
+
"visitComparison",
|
|
421
|
+
"visitMethodCall",
|
|
422
|
+
"visitFieldAccess",
|
|
423
|
+
"visitLiteral",
|
|
424
|
+
"visitConstant",
|
|
425
|
+
"visitArray",
|
|
426
|
+
];
|
|
427
|
+
|
|
428
|
+
for (const method of requiredMethods) {
|
|
429
|
+
if (typeof (visitor as any)[method] !== "function") {
|
|
430
|
+
throw new Error(`Visitor missing required method: ${method}`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
static walk<T>(node: ASTNode, visitor: ASTVisitor<T>): T {
|
|
436
|
+
this._validateNode(node);
|
|
437
|
+
this._validateVisitor(visitor);
|
|
438
|
+
this._checkDepth();
|
|
439
|
+
|
|
440
|
+
this._currentDepth++;
|
|
441
|
+
|
|
442
|
+
try {
|
|
443
|
+
switch (node.type) {
|
|
444
|
+
case ASTNodeType.CONDITIONAL:
|
|
445
|
+
return visitor.visitConditional(node as ConditionalNode);
|
|
446
|
+
|
|
447
|
+
case ASTNodeType.LOGICAL_EXPRESSION:
|
|
448
|
+
return visitor.visitLogicalExpression(node as LogicalExpressionNode);
|
|
449
|
+
|
|
450
|
+
case ASTNodeType.COMPARISON:
|
|
451
|
+
return visitor.visitComparison(node as ComparisonNode);
|
|
452
|
+
|
|
453
|
+
case ASTNodeType.METHOD_CALL:
|
|
454
|
+
return visitor.visitMethodCall(node as MethodCallNode);
|
|
455
|
+
|
|
456
|
+
case ASTNodeType.FIELD_ACCESS:
|
|
457
|
+
return visitor.visitFieldAccess(node as FieldAccessNode);
|
|
458
|
+
|
|
459
|
+
case ASTNodeType.LITERAL:
|
|
460
|
+
return visitor.visitLiteral(node as LiteralNode);
|
|
461
|
+
|
|
462
|
+
case ASTNodeType.CONSTANT:
|
|
463
|
+
return visitor.visitConstant(node as ConstantNode);
|
|
464
|
+
|
|
465
|
+
case ASTNodeType.ARRAY:
|
|
466
|
+
return visitor.visitArray(node as ArrayNode);
|
|
467
|
+
|
|
468
|
+
default:
|
|
469
|
+
throw new Error(`Unknown AST node type: ${(node as any).type}`);
|
|
470
|
+
}
|
|
471
|
+
} catch (error: any) {
|
|
472
|
+
// Add context to errors
|
|
473
|
+
const contextError = new Error(
|
|
474
|
+
`Error walking AST at position ${node.position}: ${(error as Error).message}`
|
|
475
|
+
);
|
|
476
|
+
contextError.message = error;
|
|
477
|
+
throw contextError;
|
|
478
|
+
} finally {
|
|
479
|
+
this._currentDepth--;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* AST Analyzer - Provides analysis utilities for AST
|
|
486
|
+
*/
|
|
487
|
+
export class ASTAnalyzer {
|
|
488
|
+
private static readonly FIELD_CACHE = new Map<ASTNode, string[]>();
|
|
489
|
+
private static readonly COMPLEXITY_CACHE = new Map<ASTNode, number>();
|
|
490
|
+
|
|
491
|
+
private static _clearCaches(): void {
|
|
492
|
+
this.FIELD_CACHE.clear();
|
|
493
|
+
this.COMPLEXITY_CACHE.clear();
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
private static _safeWalk<T>(node: ASTNode, visitor: ASTVisitor<T>): T {
|
|
497
|
+
try {
|
|
498
|
+
return ASTWalker.walk(node, visitor);
|
|
499
|
+
} catch (error) {
|
|
500
|
+
throw new Error(`AST analysis failed: ${(error as Error).message}`);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Get all field references in the AST
|
|
506
|
+
*/
|
|
507
|
+
static getFieldReferences(node: ASTNode): string[] {
|
|
508
|
+
// Check cache first
|
|
509
|
+
if (this.FIELD_CACHE.has(node)) {
|
|
510
|
+
return [...this.FIELD_CACHE.get(node)!]; // Return defensive copy
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
const fields: string[] = [];
|
|
514
|
+
|
|
515
|
+
const visitor: ASTVisitor<void> = {
|
|
516
|
+
visitConditional: (n) => {
|
|
517
|
+
this._safeWalk(n.condition, visitor);
|
|
518
|
+
this._safeWalk(n.thenValue, visitor);
|
|
519
|
+
if (n.elseValue) this._safeWalk(n.elseValue, visitor);
|
|
520
|
+
},
|
|
521
|
+
|
|
522
|
+
visitLogicalExpression: (n) => {
|
|
523
|
+
this._safeWalk(n.left, visitor);
|
|
524
|
+
this._safeWalk(n.right, visitor);
|
|
525
|
+
},
|
|
526
|
+
|
|
527
|
+
visitComparison: (n) => {
|
|
528
|
+
this._safeWalk(n.left, visitor);
|
|
529
|
+
this._safeWalk(n.right, visitor);
|
|
530
|
+
},
|
|
531
|
+
|
|
532
|
+
visitMethodCall: (n) => {
|
|
533
|
+
this._safeWalk(n.field, visitor);
|
|
534
|
+
if (n.arguments) {
|
|
535
|
+
n.arguments.forEach((arg) => this._safeWalk(arg, visitor));
|
|
536
|
+
}
|
|
537
|
+
},
|
|
538
|
+
|
|
539
|
+
visitFieldAccess: (n) => {
|
|
540
|
+
const fieldPath = n.path.join(".");
|
|
541
|
+
if (!fields.includes(fieldPath)) {
|
|
542
|
+
fields.push(fieldPath);
|
|
543
|
+
}
|
|
544
|
+
},
|
|
545
|
+
|
|
546
|
+
visitLiteral: () => {},
|
|
547
|
+
visitConstant: () => {},
|
|
548
|
+
visitArray: (n) => {
|
|
549
|
+
n.elements.forEach((el) => this._safeWalk(el, visitor));
|
|
550
|
+
},
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
this._safeWalk(node, visitor);
|
|
554
|
+
|
|
555
|
+
const uniqueFields = [...new Set(fields)];
|
|
556
|
+
this.FIELD_CACHE.set(node, uniqueFields);
|
|
557
|
+
|
|
558
|
+
return [...uniqueFields]; // Return defensive copy
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
/**
|
|
562
|
+
* Get complexity score of the AST
|
|
563
|
+
*/
|
|
564
|
+
static getComplexityScore(node: ASTNode): number {
|
|
565
|
+
// Check cache first
|
|
566
|
+
if (this.COMPLEXITY_CACHE.has(node)) {
|
|
567
|
+
return this.COMPLEXITY_CACHE.get(node)!;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
let totalScore = 0;
|
|
571
|
+
|
|
572
|
+
const visitor: ASTVisitor<number> = {
|
|
573
|
+
visitConditional: (n) => {
|
|
574
|
+
let score = 2; // Base complexity for conditional
|
|
575
|
+
score += this._safeWalk(n.condition, visitor);
|
|
576
|
+
score += this._safeWalk(n.thenValue, visitor);
|
|
577
|
+
if (n.elseValue) score += this._safeWalk(n.elseValue, visitor);
|
|
578
|
+
return score;
|
|
579
|
+
},
|
|
580
|
+
|
|
581
|
+
visitLogicalExpression: (n) => {
|
|
582
|
+
let score = 1; // Logical operators add complexity
|
|
583
|
+
score += this._safeWalk(n.left, visitor);
|
|
584
|
+
score += this._safeWalk(n.right, visitor);
|
|
585
|
+
return score;
|
|
586
|
+
},
|
|
587
|
+
|
|
588
|
+
visitComparison: () => 1, // Simple comparison
|
|
589
|
+
|
|
590
|
+
visitMethodCall: (n) => {
|
|
591
|
+
let score = 2; // Method calls are more complex
|
|
592
|
+
if (n.arguments) score += n.arguments.length;
|
|
593
|
+
return score;
|
|
594
|
+
},
|
|
595
|
+
|
|
596
|
+
visitFieldAccess: () => 0,
|
|
597
|
+
visitLiteral: () => 0,
|
|
598
|
+
visitConstant: () => 0,
|
|
599
|
+
visitArray: (n) => Math.ceil(n.elements.length * 0.5), // Arrays add some complexity
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
totalScore = this._safeWalk(node, visitor);
|
|
603
|
+
this.COMPLEXITY_CACHE.set(node, totalScore);
|
|
604
|
+
|
|
605
|
+
return totalScore;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* Check if AST contains nested conditionals
|
|
610
|
+
*/
|
|
611
|
+
static hasNestedConditionals(node: ASTNode): boolean {
|
|
612
|
+
let hasNested = false;
|
|
613
|
+
let depth = 0;
|
|
614
|
+
|
|
615
|
+
const visitor: ASTVisitor<void> = {
|
|
616
|
+
visitConditional: (n) => {
|
|
617
|
+
depth++;
|
|
618
|
+
if (depth > 1) {
|
|
619
|
+
hasNested = true;
|
|
620
|
+
return; // Early exit
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
this._safeWalk(n.condition, visitor);
|
|
624
|
+
if (!hasNested) this._safeWalk(n.thenValue, visitor);
|
|
625
|
+
if (!hasNested && n.elseValue) this._safeWalk(n.elseValue, visitor);
|
|
626
|
+
|
|
627
|
+
depth--;
|
|
628
|
+
},
|
|
629
|
+
|
|
630
|
+
visitLogicalExpression: (n) => {
|
|
631
|
+
if (!hasNested) this._safeWalk(n.left, visitor);
|
|
632
|
+
if (!hasNested) this._safeWalk(n.right, visitor);
|
|
633
|
+
},
|
|
634
|
+
|
|
635
|
+
visitComparison: (n) => {
|
|
636
|
+
if (!hasNested) this._safeWalk(n.left, visitor);
|
|
637
|
+
if (!hasNested) this._safeWalk(n.right, visitor);
|
|
638
|
+
},
|
|
639
|
+
|
|
640
|
+
visitMethodCall: (n) => {
|
|
641
|
+
if (!hasNested) this._safeWalk(n.field, visitor);
|
|
642
|
+
if (!hasNested && n.arguments) {
|
|
643
|
+
n.arguments.forEach((arg) => this._safeWalk(arg, visitor));
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
|
|
647
|
+
visitFieldAccess: () => {},
|
|
648
|
+
visitLiteral: () => {},
|
|
649
|
+
visitConstant: () => {},
|
|
650
|
+
visitArray: (n) => {
|
|
651
|
+
if (!hasNested) {
|
|
652
|
+
n.elements.forEach((el) => this._safeWalk(el, visitor));
|
|
653
|
+
}
|
|
654
|
+
},
|
|
655
|
+
};
|
|
656
|
+
|
|
657
|
+
this._safeWalk(node, visitor);
|
|
658
|
+
return hasNested;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Validate AST structure
|
|
663
|
+
*/
|
|
664
|
+
static validateAST(node: ASTNode): string[] {
|
|
665
|
+
const errors: string[] = [];
|
|
666
|
+
|
|
667
|
+
const visitor: ASTVisitor<void> = {
|
|
668
|
+
visitConditional: (n) => {
|
|
669
|
+
if (!n.condition) {
|
|
670
|
+
errors.push(
|
|
671
|
+
`Conditional node at position ${n.position} missing condition`
|
|
672
|
+
);
|
|
673
|
+
}
|
|
674
|
+
if (!n.thenValue) {
|
|
675
|
+
errors.push(
|
|
676
|
+
`Conditional node at position ${n.position} missing then value`
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
|
|
680
|
+
try {
|
|
681
|
+
if (n.condition) this._safeWalk(n.condition, visitor);
|
|
682
|
+
if (n.thenValue) this._safeWalk(n.thenValue, visitor);
|
|
683
|
+
if (n.elseValue) this._safeWalk(n.elseValue, visitor);
|
|
684
|
+
} catch (error) {
|
|
685
|
+
errors.push(
|
|
686
|
+
`Error validating conditional at position ${n.position}: ${(error as Error).message}`
|
|
687
|
+
);
|
|
688
|
+
}
|
|
689
|
+
},
|
|
690
|
+
|
|
691
|
+
visitLogicalExpression: (n) => {
|
|
692
|
+
if (!n.left || !n.right) {
|
|
693
|
+
errors.push(
|
|
694
|
+
`Logical expression at position ${n.position} missing operands`
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
if (!["AND", "OR"].includes(n.operator)) {
|
|
698
|
+
errors.push(
|
|
699
|
+
`Invalid logical operator at position ${n.position}: ${n.operator}`
|
|
700
|
+
);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
try {
|
|
704
|
+
if (n.left) this._safeWalk(n.left, visitor);
|
|
705
|
+
if (n.right) this._safeWalk(n.right, visitor);
|
|
706
|
+
} catch (error) {
|
|
707
|
+
errors.push(
|
|
708
|
+
`Error validating logical expression at position ${n.position}: ${(error as Error).message}`
|
|
709
|
+
);
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
|
|
713
|
+
visitComparison: (n) => {
|
|
714
|
+
if (!n.left || !n.right) {
|
|
715
|
+
errors.push(`Comparison at position ${n.position} missing operands`);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
try {
|
|
719
|
+
if (n.left) this._safeWalk(n.left, visitor);
|
|
720
|
+
if (n.right) this._safeWalk(n.right, visitor);
|
|
721
|
+
} catch (error) {
|
|
722
|
+
errors.push(
|
|
723
|
+
`Error validating comparison at position ${n.position}: ${(error as Error).message}`
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
},
|
|
727
|
+
|
|
728
|
+
visitMethodCall: (n) => {
|
|
729
|
+
if (!n.field) {
|
|
730
|
+
errors.push(`Method call at position ${n.position} missing field`);
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
try {
|
|
734
|
+
if (n.field) this._safeWalk(n.field, visitor);
|
|
735
|
+
if (n.arguments) {
|
|
736
|
+
n.arguments.forEach((arg) => this._safeWalk(arg, visitor));
|
|
737
|
+
}
|
|
738
|
+
} catch (error) {
|
|
739
|
+
errors.push(
|
|
740
|
+
`Error validating method call at position ${n.position}: ${(error as Error).message}`
|
|
741
|
+
);
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
|
|
745
|
+
visitFieldAccess: (n) => {
|
|
746
|
+
if (!n.path || n.path.length === 0) {
|
|
747
|
+
errors.push(`Field access at position ${n.position} missing path`);
|
|
748
|
+
} else {
|
|
749
|
+
// Validate path segments
|
|
750
|
+
for (const segment of n.path) {
|
|
751
|
+
if (typeof segment !== "string" || segment.trim() === "") {
|
|
752
|
+
errors.push(
|
|
753
|
+
`Invalid path segment in field access at position ${n.position}: "${segment}"`
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
},
|
|
759
|
+
|
|
760
|
+
visitLiteral: (n) => {
|
|
761
|
+
if (n.value === undefined || n.value === null) {
|
|
762
|
+
errors.push(`Literal node at position ${n.position} missing value`);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
const actualType = typeof n.value;
|
|
766
|
+
if (actualType !== n.dataType) {
|
|
767
|
+
errors.push(
|
|
768
|
+
`Type mismatch in literal at position ${n.position}: expected ${n.dataType}, got ${actualType}`
|
|
769
|
+
);
|
|
770
|
+
}
|
|
771
|
+
},
|
|
772
|
+
|
|
773
|
+
visitConstant: (n) => {
|
|
774
|
+
if (!n.value || typeof n.value !== "string") {
|
|
775
|
+
errors.push(
|
|
776
|
+
`Constant node at position ${n.position} missing or invalid value`
|
|
777
|
+
);
|
|
778
|
+
}
|
|
779
|
+
},
|
|
780
|
+
|
|
781
|
+
visitArray: (n) => {
|
|
782
|
+
if (!n.elements || !Array.isArray(n.elements)) {
|
|
783
|
+
errors.push(
|
|
784
|
+
`Array node at position ${n.position} missing or invalid elements`
|
|
785
|
+
);
|
|
786
|
+
} else {
|
|
787
|
+
for (let i = 0; i < n.elements.length; i++) {
|
|
788
|
+
if (!n.elements[i] || n.elements[i].type !== ASTNodeType.LITERAL) {
|
|
789
|
+
errors.push(
|
|
790
|
+
`Invalid element at index ${i} in array at position ${n.position}`
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
},
|
|
796
|
+
};
|
|
797
|
+
|
|
798
|
+
try {
|
|
799
|
+
this._safeWalk(node, visitor);
|
|
800
|
+
} catch (error) {
|
|
801
|
+
errors.push(`Critical validation error: ${(error as Error).message}`);
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
return errors;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Clear internal caches - useful for memory management
|
|
809
|
+
*/
|
|
810
|
+
static clearCaches(): void {
|
|
811
|
+
this._clearCaches();
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
/**
|
|
815
|
+
* Get cache statistics for debugging
|
|
816
|
+
*/
|
|
817
|
+
static getCacheStats(): {
|
|
818
|
+
fieldCacheSize: number;
|
|
819
|
+
complexityCacheSize: number;
|
|
820
|
+
} {
|
|
821
|
+
return {
|
|
822
|
+
fieldCacheSize: this.FIELD_CACHE.size,
|
|
823
|
+
complexityCacheSize: this.COMPLEXITY_CACHE.size,
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
}
|