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,803 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Enhanced Conditional Parser
|
|
3
|
+
*
|
|
4
|
+
* Parses tokenized conditional syntax into an Abstract Syntax Tree (AST)
|
|
5
|
+
* Supports nested conditions, logical operators, and complex expressions
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { ConditionalLexer } from "./ConditionalLexer";
|
|
9
|
+
import { ASTBuilder } from "./ConditionalAST";
|
|
10
|
+
import {
|
|
11
|
+
Token,
|
|
12
|
+
TokenType,
|
|
13
|
+
ConditionalNode,
|
|
14
|
+
ConditionNode,
|
|
15
|
+
LogicalExpressionNode,
|
|
16
|
+
ComparisonNode,
|
|
17
|
+
MethodCallNode,
|
|
18
|
+
FieldAccessNode,
|
|
19
|
+
LiteralNode,
|
|
20
|
+
ConstantNode,
|
|
21
|
+
ArrayNode,
|
|
22
|
+
ValueNode,
|
|
23
|
+
ConditionalError,
|
|
24
|
+
ErrorType,
|
|
25
|
+
ParserConfig,
|
|
26
|
+
} from "../types/ConditionalTypes";
|
|
27
|
+
|
|
28
|
+
export class ConditionalParser {
|
|
29
|
+
private tokens: Token[] = [];
|
|
30
|
+
private current: number = 0;
|
|
31
|
+
private errors: ConditionalError[] = [];
|
|
32
|
+
private config: ParserConfig;
|
|
33
|
+
|
|
34
|
+
constructor(config: Partial<ParserConfig> = {}) {
|
|
35
|
+
this.config = {
|
|
36
|
+
allowNestedConditionals: true,
|
|
37
|
+
maxNestingDepth: 5,
|
|
38
|
+
strictMode: false,
|
|
39
|
+
enableDebug: false,
|
|
40
|
+
...config,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Parse conditional expression from string
|
|
46
|
+
*/
|
|
47
|
+
parse(input: string): { ast?: ConditionalNode; errors: ConditionalError[] } {
|
|
48
|
+
// Tokenize input
|
|
49
|
+
const lexer = new ConditionalLexer(input);
|
|
50
|
+
const { tokens, errors: lexErrors } = lexer.tokenize();
|
|
51
|
+
|
|
52
|
+
this.tokens = tokens;
|
|
53
|
+
this.current = 0;
|
|
54
|
+
this.errors = [...lexErrors];
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const ast = this.parseConditional();
|
|
58
|
+
|
|
59
|
+
// Check for remaining tokens
|
|
60
|
+
if (!this.isAtEnd()) {
|
|
61
|
+
this.addError(
|
|
62
|
+
ErrorType.SYNTAX_ERROR,
|
|
63
|
+
`Unexpected token: ${this.peek().value}`,
|
|
64
|
+
"Remove extra tokens or check syntax"
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return { ast, errors: this.errors };
|
|
69
|
+
} catch (error: any) {
|
|
70
|
+
this.addError(
|
|
71
|
+
ErrorType.SYNTAX_ERROR,
|
|
72
|
+
`Parse error: ${error.message}`,
|
|
73
|
+
"Check conditional syntax"
|
|
74
|
+
);
|
|
75
|
+
return { errors: this.errors };
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Parse conditional expression: when condition *? thenValue : elseValue
|
|
81
|
+
*/
|
|
82
|
+
private parseConditional(): ConditionalNode {
|
|
83
|
+
const position = this.peek().position;
|
|
84
|
+
|
|
85
|
+
// Expect 'when' keyword
|
|
86
|
+
if (!this.match(TokenType.WHEN)) {
|
|
87
|
+
throw new Error('Expected "when" keyword');
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Parse condition
|
|
91
|
+
const condition = this.parseCondition();
|
|
92
|
+
|
|
93
|
+
// Expect '*?' token
|
|
94
|
+
if (!this.match(TokenType.CONDITIONAL_THEN)) {
|
|
95
|
+
throw new Error('Expected "*?" after condition');
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Parse then value
|
|
99
|
+
const thenValue = this.parseValue();
|
|
100
|
+
|
|
101
|
+
// Parse optional else value
|
|
102
|
+
let elseValue: ValueNode | undefined;
|
|
103
|
+
if (this.match(TokenType.COLON)) {
|
|
104
|
+
elseValue = this.parseValue();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return ASTBuilder.createConditional(
|
|
108
|
+
condition,
|
|
109
|
+
thenValue,
|
|
110
|
+
elseValue,
|
|
111
|
+
position
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Parse condition (supports logical expressions)
|
|
117
|
+
*/
|
|
118
|
+
private parseCondition(): ConditionNode {
|
|
119
|
+
return this.parseLogicalOr();
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Parse logical OR expression
|
|
124
|
+
*/
|
|
125
|
+
private parseLogicalOr(): ConditionNode {
|
|
126
|
+
let expr = this.parseLogicalAnd();
|
|
127
|
+
|
|
128
|
+
while (this.match(TokenType.OR)) {
|
|
129
|
+
const operator = "OR";
|
|
130
|
+
const right = this.parseLogicalAnd();
|
|
131
|
+
expr = ASTBuilder.createLogicalExpression(
|
|
132
|
+
operator,
|
|
133
|
+
expr,
|
|
134
|
+
right,
|
|
135
|
+
this.previous().position
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return expr;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Parse logical AND expression
|
|
144
|
+
*/
|
|
145
|
+
private parseLogicalAnd(): ConditionNode {
|
|
146
|
+
let expr = this.parseComparison();
|
|
147
|
+
|
|
148
|
+
while (this.match(TokenType.AND)) {
|
|
149
|
+
const operator = "AND";
|
|
150
|
+
const right = this.parseComparison();
|
|
151
|
+
expr = ASTBuilder.createLogicalExpression(
|
|
152
|
+
operator,
|
|
153
|
+
expr,
|
|
154
|
+
right,
|
|
155
|
+
this.previous().position
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return expr;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Parse comparison or method call
|
|
164
|
+
*/
|
|
165
|
+
private parseComparison(): ConditionNode {
|
|
166
|
+
const position = this.peek().position;
|
|
167
|
+
|
|
168
|
+
// Handle parentheses
|
|
169
|
+
if (this.match(TokenType.LPAREN)) {
|
|
170
|
+
const expr = this.parseCondition();
|
|
171
|
+
if (!this.match(TokenType.RPAREN)) {
|
|
172
|
+
throw new Error('Expected ")" after grouped condition');
|
|
173
|
+
}
|
|
174
|
+
return expr;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Handle NOT operator (!) as prefix
|
|
178
|
+
let isNegated = false;
|
|
179
|
+
if (this.match(TokenType.NOT)) {
|
|
180
|
+
isNegated = true;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// Parse field access
|
|
184
|
+
const field = this.parseFieldAccess();
|
|
185
|
+
|
|
186
|
+
// Check for method call
|
|
187
|
+
if (this.match(TokenType.DOT)) {
|
|
188
|
+
return this.parseMethodCall(field, position, isNegated);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Parse comparison operator
|
|
192
|
+
if (
|
|
193
|
+
this.matchAny([
|
|
194
|
+
TokenType.EQUALS,
|
|
195
|
+
TokenType.NOT_EQUALS,
|
|
196
|
+
TokenType.GREATER_THAN,
|
|
197
|
+
TokenType.GREATER_EQUAL,
|
|
198
|
+
TokenType.LESS_THAN,
|
|
199
|
+
TokenType.LESS_EQUAL,
|
|
200
|
+
TokenType.MATCHES,
|
|
201
|
+
TokenType.NOT_MATCHES,
|
|
202
|
+
])
|
|
203
|
+
) {
|
|
204
|
+
const operator = this.previous().type;
|
|
205
|
+
const right = this.parseComparisonValue();
|
|
206
|
+
return ASTBuilder.createComparison(operator, field, right, position);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
throw new Error(
|
|
210
|
+
`Expected comparison operator or method call after field "${field.path.join(".")}"`
|
|
211
|
+
);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Parse method call: field.$method(args) or field.!method
|
|
216
|
+
*/
|
|
217
|
+
private parseMethodCall(
|
|
218
|
+
field: FieldAccessNode,
|
|
219
|
+
position: number,
|
|
220
|
+
isNegated: boolean = false
|
|
221
|
+
): MethodCallNode {
|
|
222
|
+
let methodName = "";
|
|
223
|
+
let methodType: TokenType | undefined;
|
|
224
|
+
let isRuntimeMethod = false;
|
|
225
|
+
|
|
226
|
+
// Only handle runtime methods that start with $ (like $exists, $empty)
|
|
227
|
+
if (this.check(TokenType.DOLLAR)) {
|
|
228
|
+
this.advance(); // consume '$'
|
|
229
|
+
|
|
230
|
+
if (!this.check(TokenType.IDENTIFIER)) {
|
|
231
|
+
throw new Error('Expected method name after "$"');
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const baseMethodName = this.advance().value; // consume method name
|
|
235
|
+
methodName = `$${baseMethodName}`;
|
|
236
|
+
methodType = this.getMethodTokenType(baseMethodName); // Map to base method type
|
|
237
|
+
isRuntimeMethod = true;
|
|
238
|
+
|
|
239
|
+
// Apply negation if the method call was prefixed with !
|
|
240
|
+
if (isNegated) {
|
|
241
|
+
methodType = this.getNegatedMethodType(methodType);
|
|
242
|
+
methodName = `!${methodName}`;
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
throw new Error(
|
|
246
|
+
"Only $method() syntax is supported. Use property.$method() instead of property.method"
|
|
247
|
+
);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if (!methodType) {
|
|
251
|
+
throw new Error(`Unknown method: ${methodName}`);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
// All runtime methods require parentheses
|
|
255
|
+
if (!this.check(TokenType.LPAREN)) {
|
|
256
|
+
throw new Error(
|
|
257
|
+
`Runtime method "${methodName}" requires parentheses: ${methodName}()`
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Parse method arguments
|
|
262
|
+
this.advance(); // consume '('
|
|
263
|
+
const args: LiteralNode[] = [];
|
|
264
|
+
|
|
265
|
+
if (!this.check(TokenType.RPAREN)) {
|
|
266
|
+
do {
|
|
267
|
+
args.push(this.parseLiteral());
|
|
268
|
+
} while (this.match(TokenType.COMMA));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
if (!this.match(TokenType.RPAREN)) {
|
|
272
|
+
throw new Error('Expected ")" after method arguments');
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return ASTBuilder.createMethodCall(
|
|
276
|
+
methodType,
|
|
277
|
+
field,
|
|
278
|
+
args,
|
|
279
|
+
position,
|
|
280
|
+
isRuntimeMethod
|
|
281
|
+
);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Parse field access: field or field.subfield or field["key"]
|
|
286
|
+
*/
|
|
287
|
+
private parseFieldAccess(): FieldAccessNode {
|
|
288
|
+
const position = this.peek().position;
|
|
289
|
+
const path: string[] = [];
|
|
290
|
+
|
|
291
|
+
if (!this.check(TokenType.IDENTIFIER)) {
|
|
292
|
+
throw new Error("Expected field name");
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
path.push(this.advance().value);
|
|
296
|
+
|
|
297
|
+
// Handle nested field access (dot notation and bracket notation)
|
|
298
|
+
while (true) {
|
|
299
|
+
// Handle dot notation: field.subfield
|
|
300
|
+
if (
|
|
301
|
+
this.check(TokenType.DOT) &&
|
|
302
|
+
this.peekNext()?.type === TokenType.IDENTIFIER
|
|
303
|
+
) {
|
|
304
|
+
// Check if the next token is a runtime method ($method)
|
|
305
|
+
if (this.peekNext()?.type === TokenType.DOLLAR) {
|
|
306
|
+
break; // Stop here, let parseComparison handle the runtime method call
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
this.advance(); // consume '.'
|
|
310
|
+
path.push(this.advance().value);
|
|
311
|
+
}
|
|
312
|
+
// Handle bracket notation: field["key"] or field[0]
|
|
313
|
+
else if (this.check(TokenType.LBRACKET)) {
|
|
314
|
+
this.advance(); // consume '['
|
|
315
|
+
|
|
316
|
+
// FIXED: Accept both string keys and numeric indices
|
|
317
|
+
if (!this.check(TokenType.STRING) && !this.check(TokenType.NUMBER)) {
|
|
318
|
+
throw new Error(
|
|
319
|
+
"Expected string key or numeric index in bracket notation"
|
|
320
|
+
);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const key = this.advance().value;
|
|
324
|
+
path.push(key);
|
|
325
|
+
|
|
326
|
+
if (!this.match(TokenType.RBRACKET)) {
|
|
327
|
+
throw new Error("Expected ']' after bracket notation key");
|
|
328
|
+
}
|
|
329
|
+
} else {
|
|
330
|
+
break; // No more field access patterns
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return ASTBuilder.createFieldAccess(path, position);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Parse value (literal, constant, array, or nested conditional)
|
|
339
|
+
*/
|
|
340
|
+
private parseValue(): ValueNode {
|
|
341
|
+
const position = this.peek().position;
|
|
342
|
+
|
|
343
|
+
// DEBUG: Log current token
|
|
344
|
+
if (this.config.enableDebug) {
|
|
345
|
+
console.log(
|
|
346
|
+
`parseValue: current token = ${this.peek().type} "${this.peek().value}" at position ${this.peek().position}`
|
|
347
|
+
);
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
// Handle nested conditional
|
|
351
|
+
if (this.check(TokenType.WHEN) && this.config.allowNestedConditionals) {
|
|
352
|
+
return this.parseConditional();
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// Handle constant value (=value syntax)
|
|
356
|
+
if (this.check(TokenType.CONSTANT)) {
|
|
357
|
+
const value = this.advance().value;
|
|
358
|
+
return ASTBuilder.createConstant(value, position);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Handle constant value with equals prefix
|
|
362
|
+
if (this.check(TokenType.EQUALS)) {
|
|
363
|
+
if (this.config.enableDebug) {
|
|
364
|
+
console.log(`parseValue: Found EQUALS token, advancing...`);
|
|
365
|
+
}
|
|
366
|
+
this.advance(); // consume '='
|
|
367
|
+
|
|
368
|
+
// Check if it's an array literal
|
|
369
|
+
if (this.check(TokenType.LBRACKET)) {
|
|
370
|
+
if (this.config.enableDebug) {
|
|
371
|
+
console.log(
|
|
372
|
+
`parseValue: Found LBRACKET after EQUALS, parsing array...`
|
|
373
|
+
);
|
|
374
|
+
}
|
|
375
|
+
this.advance(); // consume the '[' token
|
|
376
|
+
const arrayNode = this.parseArray(position);
|
|
377
|
+
// Convert array to string representation for constant
|
|
378
|
+
const arrayValue = JSON.stringify(
|
|
379
|
+
arrayNode.elements.map((el) => el.value)
|
|
380
|
+
);
|
|
381
|
+
return ASTBuilder.createConstant(arrayValue, position);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
// ENHANCED: Check if it's an object literal
|
|
385
|
+
if (this.check(TokenType.LBRACE)) {
|
|
386
|
+
if (this.config.enableDebug) {
|
|
387
|
+
console.log(
|
|
388
|
+
`parseValue: Found LBRACE after EQUALS, parsing object...`
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
const objectLiteral = this.parseObjectLiteral();
|
|
392
|
+
return ASTBuilder.createConstant(objectLiteral, position);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// Handle regular literal
|
|
396
|
+
const literal = this.parseLiteral();
|
|
397
|
+
return ASTBuilder.createConstant(literal.value.toString(), position);
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Handle array
|
|
401
|
+
if (this.match(TokenType.LBRACKET)) {
|
|
402
|
+
return this.parseArray(position);
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Handle literal
|
|
406
|
+
return this.parseLiteral();
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Parse array: [value1, value2, ...]
|
|
411
|
+
*/
|
|
412
|
+
private parseArray(position: number): ArrayNode {
|
|
413
|
+
const elements: LiteralNode[] = [];
|
|
414
|
+
|
|
415
|
+
if (!this.check(TokenType.RBRACKET)) {
|
|
416
|
+
do {
|
|
417
|
+
elements.push(this.parseLiteral());
|
|
418
|
+
} while (this.match(TokenType.COMMA));
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (!this.match(TokenType.RBRACKET)) {
|
|
422
|
+
throw new Error('Expected "]" after array elements');
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
return ASTBuilder.createArray(elements, position);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Parse object literal: {key: value, key2: value2}
|
|
430
|
+
* ENHANCED: Support for complex object constants like ={test: [1]}
|
|
431
|
+
* FIXED: Generate proper JSON format for validation
|
|
432
|
+
*/
|
|
433
|
+
private parseObjectLiteral(): string {
|
|
434
|
+
this.advance(); // consume '{'
|
|
435
|
+
|
|
436
|
+
const objectParts: any = {};
|
|
437
|
+
|
|
438
|
+
// Parse object properties
|
|
439
|
+
while (!this.check(TokenType.RBRACE) && !this.isAtEnd()) {
|
|
440
|
+
// Parse key
|
|
441
|
+
if (!this.check(TokenType.IDENTIFIER) && !this.check(TokenType.STRING)) {
|
|
442
|
+
throw new Error("Expected property name in object literal");
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const keyToken = this.advance();
|
|
446
|
+
let key = keyToken.value;
|
|
447
|
+
|
|
448
|
+
// STRING tokens from lexer already have quotes removed, no need to slice
|
|
449
|
+
// FIXED: Don't remove characters from already-unquoted string tokens
|
|
450
|
+
|
|
451
|
+
// Expect colon
|
|
452
|
+
if (!this.match(TokenType.COLON)) {
|
|
453
|
+
throw new Error('Expected ":" after property name');
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// Parse value
|
|
457
|
+
let value: any;
|
|
458
|
+
|
|
459
|
+
if (this.check(TokenType.LBRACKET)) {
|
|
460
|
+
// Handle array value
|
|
461
|
+
this.advance(); // consume '['
|
|
462
|
+
const arrayNode = this.parseArray(this.peek().position);
|
|
463
|
+
value = arrayNode.elements.map((el) => el.value);
|
|
464
|
+
} else if (this.check(TokenType.LBRACE)) {
|
|
465
|
+
// Handle nested object (recursive)
|
|
466
|
+
const nestedObject = this.parseObjectLiteral();
|
|
467
|
+
value = JSON.parse(nestedObject);
|
|
468
|
+
} else {
|
|
469
|
+
// Handle primitive value (including null)
|
|
470
|
+
if (this.check(TokenType.IDENTIFIER) && this.peek().value === "null") {
|
|
471
|
+
this.advance(); // consume 'null'
|
|
472
|
+
value = null;
|
|
473
|
+
} else {
|
|
474
|
+
const literal = this.parseLiteral();
|
|
475
|
+
value = literal.value;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
objectParts[key] = value;
|
|
480
|
+
|
|
481
|
+
// Check for comma (optional for last property)
|
|
482
|
+
if (this.check(TokenType.COMMA)) {
|
|
483
|
+
this.advance();
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// Expect closing brace
|
|
488
|
+
if (!this.match(TokenType.RBRACE)) {
|
|
489
|
+
throw new Error('Expected "}" to close object literal');
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// Return proper JSON string
|
|
493
|
+
return JSON.stringify(objectParts);
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Parse comparison value (handles regex patterns and complex values)
|
|
498
|
+
*/
|
|
499
|
+
private parseComparisonValue(): LiteralNode {
|
|
500
|
+
const position = this.peek().position;
|
|
501
|
+
|
|
502
|
+
// Handle regex patterns
|
|
503
|
+
if (this.check(TokenType.REGEX_PATTERN)) {
|
|
504
|
+
const pattern = this.advance().value;
|
|
505
|
+
return ASTBuilder.createLiteral(pattern, "string", position);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// Handle parentheses patterns (like (temp|disposable|10min) or @(company|org|gov))
|
|
509
|
+
if (this.check(TokenType.LPAREN) || this.check(TokenType.AT)) {
|
|
510
|
+
return this.parseComplexPattern();
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
// Handle complex patterns with special characters
|
|
514
|
+
if (
|
|
515
|
+
this.check(TokenType.CARET) ||
|
|
516
|
+
this.check(TokenType.AT) ||
|
|
517
|
+
this.check(TokenType.IDENTIFIER)
|
|
518
|
+
) {
|
|
519
|
+
let pattern = "";
|
|
520
|
+
|
|
521
|
+
// Build complex pattern by consuming tokens until we hit a delimiter
|
|
522
|
+
while (
|
|
523
|
+
!this.isAtEnd() &&
|
|
524
|
+
!this.check(TokenType.CONDITIONAL_THEN) &&
|
|
525
|
+
!this.check(TokenType.COLON) &&
|
|
526
|
+
!this.check(TokenType.AND) &&
|
|
527
|
+
!this.check(TokenType.OR) &&
|
|
528
|
+
!this.check(TokenType.RPAREN)
|
|
529
|
+
) {
|
|
530
|
+
const token = this.advance();
|
|
531
|
+
pattern += token.value;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
if (pattern.length > 0) {
|
|
535
|
+
return ASTBuilder.createLiteral(pattern, "string", position);
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
// Fall back to regular literal parsing
|
|
540
|
+
return this.parseLiteral();
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* Parse literal value
|
|
545
|
+
*/
|
|
546
|
+
private parseLiteral(): LiteralNode {
|
|
547
|
+
const position = this.peek().position;
|
|
548
|
+
|
|
549
|
+
if (this.match(TokenType.STRING)) {
|
|
550
|
+
return ASTBuilder.createLiteral(
|
|
551
|
+
this.previous().value,
|
|
552
|
+
"string",
|
|
553
|
+
position
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (this.match(TokenType.NUMBER)) {
|
|
558
|
+
const value = parseFloat(this.previous().value);
|
|
559
|
+
return ASTBuilder.createLiteral(value, "number", position);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
if (this.match(TokenType.BOOLEAN)) {
|
|
563
|
+
const value = this.previous().value === "true";
|
|
564
|
+
return ASTBuilder.createLiteral(value, "boolean", position);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
// Handle DOT followed by identifier (like .tmp in method arguments)
|
|
568
|
+
if (this.match(TokenType.DOT)) {
|
|
569
|
+
let value = ".";
|
|
570
|
+
|
|
571
|
+
// Consume following tokens to build the complete value
|
|
572
|
+
while (
|
|
573
|
+
!this.isAtEnd() &&
|
|
574
|
+
!this.check(TokenType.COMMA) &&
|
|
575
|
+
!this.check(TokenType.RPAREN) &&
|
|
576
|
+
!this.check(TokenType.CONDITIONAL_THEN) &&
|
|
577
|
+
!this.check(TokenType.COLON)
|
|
578
|
+
) {
|
|
579
|
+
const token = this.advance();
|
|
580
|
+
value += token.value;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
return ASTBuilder.createLiteral(value, "string", position);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// Handle complex patterns with parentheses (like @(company|org|gov))
|
|
587
|
+
if (
|
|
588
|
+
this.check(TokenType.AT) ||
|
|
589
|
+
this.check(TokenType.CARET) ||
|
|
590
|
+
this.check(TokenType.IDENTIFIER)
|
|
591
|
+
) {
|
|
592
|
+
return this.parseComplexPattern();
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
if (this.match(TokenType.IDENTIFIER)) {
|
|
596
|
+
const identifier = this.previous().value;
|
|
597
|
+
|
|
598
|
+
// Check for type with constraints (e.g., number(0.1,0.3))
|
|
599
|
+
if (this.check(TokenType.LPAREN)) {
|
|
600
|
+
this.advance(); // consume '('
|
|
601
|
+
let typeWithConstraints = `${identifier}(`;
|
|
602
|
+
|
|
603
|
+
// Parse constraint parameters
|
|
604
|
+
while (!this.check(TokenType.RPAREN) && !this.isAtEnd()) {
|
|
605
|
+
const token = this.advance();
|
|
606
|
+
typeWithConstraints += token.value;
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
if (this.match(TokenType.RPAREN)) {
|
|
610
|
+
typeWithConstraints += ")";
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
return ASTBuilder.createLiteral(
|
|
614
|
+
typeWithConstraints,
|
|
615
|
+
"string",
|
|
616
|
+
position
|
|
617
|
+
);
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// Check if this is a schema type with array notation (e.g., string[], number[])
|
|
621
|
+
if (
|
|
622
|
+
this.check(TokenType.LBRACKET) &&
|
|
623
|
+
this.peekNext()?.type === TokenType.RBRACKET
|
|
624
|
+
) {
|
|
625
|
+
this.advance(); // consume '['
|
|
626
|
+
this.advance(); // consume ']'
|
|
627
|
+
|
|
628
|
+
// Check for optional array notation (e.g., string[]?)
|
|
629
|
+
let schemaType = `${identifier}[]`;
|
|
630
|
+
if (this.check(TokenType.UNKNOWN) && this.peek().value === "?") {
|
|
631
|
+
this.advance(); // consume '?'
|
|
632
|
+
schemaType += "?";
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
return ASTBuilder.createLiteral(schemaType, "string", position);
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
// Check for optional notation (e.g., string?)
|
|
639
|
+
if (this.check(TokenType.UNKNOWN) && this.peek().value === "?") {
|
|
640
|
+
this.advance(); // consume '?'
|
|
641
|
+
return ASTBuilder.createLiteral(`${identifier}?`, "string", position);
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
// Treat identifier as string literal in this context
|
|
645
|
+
return ASTBuilder.createLiteral(identifier, "string", position);
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
throw new Error(`Expected literal value, got ${this.peek().type}`);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
/**
|
|
652
|
+
* Parse complex patterns with parentheses and special characters
|
|
653
|
+
* Handles patterns like @(company|org|gov), (temp|disposable|10min), etc.
|
|
654
|
+
*/
|
|
655
|
+
private parseComplexPattern(): LiteralNode {
|
|
656
|
+
const position = this.peek().position;
|
|
657
|
+
let pattern = "";
|
|
658
|
+
let depth = 0;
|
|
659
|
+
|
|
660
|
+
// Build the complete pattern by consuming tokens
|
|
661
|
+
while (!this.isAtEnd()) {
|
|
662
|
+
const token = this.peek();
|
|
663
|
+
|
|
664
|
+
// Stop at conditional operators or end of expression
|
|
665
|
+
if (
|
|
666
|
+
token.type === TokenType.CONDITIONAL_THEN ||
|
|
667
|
+
token.type === TokenType.COLON ||
|
|
668
|
+
token.type === TokenType.AND ||
|
|
669
|
+
token.type === TokenType.OR
|
|
670
|
+
) {
|
|
671
|
+
break;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// Handle parentheses depth tracking
|
|
675
|
+
if (token.type === TokenType.LPAREN) {
|
|
676
|
+
depth++;
|
|
677
|
+
} else if (token.type === TokenType.RPAREN) {
|
|
678
|
+
depth--;
|
|
679
|
+
// If we close all parentheses, include this token and stop
|
|
680
|
+
if (depth < 0) {
|
|
681
|
+
break;
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Add token to pattern
|
|
686
|
+
pattern += this.advance().value;
|
|
687
|
+
|
|
688
|
+
// If we've closed all parentheses, we're done
|
|
689
|
+
if (depth === 0 && pattern.includes(")")) {
|
|
690
|
+
break;
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
return ASTBuilder.createLiteral(pattern, "string", position);
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
/**
|
|
698
|
+
* Utility methods
|
|
699
|
+
*/
|
|
700
|
+
private match(...types: TokenType[]): boolean {
|
|
701
|
+
for (const type of types) {
|
|
702
|
+
if (this.check(type)) {
|
|
703
|
+
this.advance();
|
|
704
|
+
return true;
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
return false;
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
private matchAny(types: TokenType[]): boolean {
|
|
711
|
+
return this.match(...types);
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
private check(type: TokenType): boolean {
|
|
715
|
+
if (this.isAtEnd()) return false;
|
|
716
|
+
return this.peek().type === type;
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
private advance(): Token {
|
|
720
|
+
if (!this.isAtEnd()) this.current++;
|
|
721
|
+
return this.previous();
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
private isAtEnd(): boolean {
|
|
725
|
+
return this.peek().type === TokenType.EOF;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
private peek(): Token {
|
|
729
|
+
return this.tokens[this.current];
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
private peekNext(): Token | undefined {
|
|
733
|
+
if (this.current + 1 >= this.tokens.length) return undefined;
|
|
734
|
+
return this.tokens[this.current + 1];
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
private previous(): Token {
|
|
738
|
+
return this.tokens[this.current - 1];
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
private getMethodTokenType(methodName: string): TokenType | undefined {
|
|
742
|
+
const methodMap: Record<string, TokenType> = {
|
|
743
|
+
in: TokenType.IN,
|
|
744
|
+
notIn: TokenType.NOT_IN,
|
|
745
|
+
"!in": TokenType.NOT_IN, // Support .!in() syntax
|
|
746
|
+
exists: TokenType.EXISTS,
|
|
747
|
+
notExists: TokenType.NOT_EXISTS,
|
|
748
|
+
"!exists": TokenType.NOT_EXISTS, // Support .!exists syntax
|
|
749
|
+
empty: TokenType.EMPTY,
|
|
750
|
+
"!empty": TokenType.NOT_EMPTY, // Support .!empty syntax
|
|
751
|
+
null: TokenType.NULL, // Support .null syntax
|
|
752
|
+
"!null": TokenType.NOT_NULL, // Support .!null syntax
|
|
753
|
+
contains: TokenType.CONTAINS,
|
|
754
|
+
notContains: TokenType.NOT_CONTAINS,
|
|
755
|
+
"!contains": TokenType.NOT_CONTAINS, // Support .!contains() syntax
|
|
756
|
+
startsWith: TokenType.STARTS_WITH,
|
|
757
|
+
endsWith: TokenType.ENDS_WITH,
|
|
758
|
+
between: TokenType.BETWEEN,
|
|
759
|
+
};
|
|
760
|
+
|
|
761
|
+
return methodMap[methodName];
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Get the negated version of a method type
|
|
766
|
+
*/
|
|
767
|
+
private getNegatedMethodType(
|
|
768
|
+
methodType: TokenType | undefined
|
|
769
|
+
): TokenType | undefined {
|
|
770
|
+
const negationMap: Partial<Record<TokenType, TokenType>> = {
|
|
771
|
+
[TokenType.EXISTS]: TokenType.NOT_EXISTS,
|
|
772
|
+
[TokenType.EMPTY]: TokenType.NOT_EMPTY,
|
|
773
|
+
[TokenType.NULL]: TokenType.NOT_NULL,
|
|
774
|
+
[TokenType.IN]: TokenType.NOT_IN,
|
|
775
|
+
[TokenType.CONTAINS]: TokenType.NOT_CONTAINS,
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
return methodType ? negationMap[methodType] : undefined;
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
private addError(
|
|
782
|
+
type: ErrorType,
|
|
783
|
+
message: string,
|
|
784
|
+
suggestion?: string
|
|
785
|
+
): void {
|
|
786
|
+
const token = this.peek();
|
|
787
|
+
this.errors.push({
|
|
788
|
+
type,
|
|
789
|
+
message,
|
|
790
|
+
position: token.position,
|
|
791
|
+
line: token.line,
|
|
792
|
+
column: token.column,
|
|
793
|
+
suggestion,
|
|
794
|
+
context: {
|
|
795
|
+
nearbyTokens: this.tokens.slice(
|
|
796
|
+
Math.max(0, this.current - 2),
|
|
797
|
+
this.current + 3
|
|
798
|
+
),
|
|
799
|
+
expectedTokens: [],
|
|
800
|
+
},
|
|
801
|
+
});
|
|
802
|
+
}
|
|
803
|
+
}
|