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,851 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var ValidatorTypes = require('../../../../types/ValidatorTypes.js');
|
|
4
|
+
var UrlArgs = require('../../../../utils/UrlArgs.js');
|
|
5
|
+
var TypeValidators = require('./TypeValidators.js');
|
|
6
|
+
var UnionCache = require('./UnionCache.js');
|
|
7
|
+
var ErrorHandler = require('../errors/ErrorHandler.js');
|
|
8
|
+
var errors_type = require('../errors/types/errors.type.js');
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Validation Helpers Module
|
|
12
|
+
*
|
|
13
|
+
* Contains optimized helper functions for validation operations
|
|
14
|
+
* extracted from InterfaceSchema to improve maintainability.
|
|
15
|
+
*/
|
|
16
|
+
// Cache for parsed constant values with LRU eviction
|
|
17
|
+
const MAX_CACHE_SIZE = 1000;
|
|
18
|
+
const constantCache = new Map();
|
|
19
|
+
// Pre-compiled regex patterns for better performance
|
|
20
|
+
const NUMERIC_PATTERN = /^-?\d+(\.\d+)?([eE][+-]?\d+)?$/;
|
|
21
|
+
const BOOLEAN_PATTERN = /^(true|false|TRUE|FALSE|True|False)$/i;
|
|
22
|
+
const HEX_COLOR_PATTERN = /^#([0-9A-Fa-f]{3}|[0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})$/;
|
|
23
|
+
const BASE64_PATTERN = /^[A-Za-z0-9+/]*={0,2}$/;
|
|
24
|
+
const JWT_PATTERN = /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/;
|
|
25
|
+
const SEMVER_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$/;
|
|
26
|
+
/**
|
|
27
|
+
* Helper functions for validation operations
|
|
28
|
+
*/
|
|
29
|
+
class ValidationHelpers {
|
|
30
|
+
/**
|
|
31
|
+
* Validate constant types (e.g., "=admin", "=user")
|
|
32
|
+
* with better caching, type safety, and deep equality checks
|
|
33
|
+
*/
|
|
34
|
+
static validateConstantType(constantValue, value) {
|
|
35
|
+
// Validate constant types with caching
|
|
36
|
+
// Implement LRU cache behavior
|
|
37
|
+
if (constantCache.size >= MAX_CACHE_SIZE) {
|
|
38
|
+
const firstKey = constantCache.keys().next().value;
|
|
39
|
+
constantCache.delete(firstKey || "");
|
|
40
|
+
}
|
|
41
|
+
let expectedValue = constantCache.get(constantValue);
|
|
42
|
+
if (expectedValue === undefined) {
|
|
43
|
+
try {
|
|
44
|
+
expectedValue = this.parseConstantValue(constantValue);
|
|
45
|
+
constantCache.set(constantValue, expectedValue);
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
return this.createErrorResult(`Invalid constant value format: ${constantValue}`, value);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// equality check including deep object/array comparison
|
|
52
|
+
if (!this.deepEquals(value, expectedValue)) {
|
|
53
|
+
return this.createErrorResult(`Expected constant value: ${JSON.stringify(expectedValue)}, got ${JSON.stringify(value)}`, value);
|
|
54
|
+
}
|
|
55
|
+
return this.createSuccessResult(value);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* deep equality check for constants
|
|
59
|
+
*/
|
|
60
|
+
static deepEquals(a, b) {
|
|
61
|
+
if (a === b)
|
|
62
|
+
return true;
|
|
63
|
+
if (a == null || b == null)
|
|
64
|
+
return a === b;
|
|
65
|
+
if (typeof a !== typeof b)
|
|
66
|
+
return false;
|
|
67
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
68
|
+
if (a.length !== b.length)
|
|
69
|
+
return false;
|
|
70
|
+
return a.every((val, index) => this.deepEquals(val, b[index]));
|
|
71
|
+
}
|
|
72
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
73
|
+
const keysA = Object.keys(a);
|
|
74
|
+
const keysB = Object.keys(b);
|
|
75
|
+
if (keysA.length !== keysB.length)
|
|
76
|
+
return false;
|
|
77
|
+
return keysA.every((key) => keysB.includes(key) && this.deepEquals(a[key], b[key]));
|
|
78
|
+
}
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* constant value parser with better error handling and type support
|
|
83
|
+
*/
|
|
84
|
+
static parseConstantValue(constantValue) {
|
|
85
|
+
if (!constantValue || typeof constantValue !== "string") {
|
|
86
|
+
throw new Error("Invalid constant value");
|
|
87
|
+
}
|
|
88
|
+
// Handle quoted strings (remove quotes and return as string)
|
|
89
|
+
if ((constantValue.startsWith('"') && constantValue.endsWith('"')) ||
|
|
90
|
+
(constantValue.startsWith("'") && constantValue.endsWith("'"))) {
|
|
91
|
+
return constantValue.slice(1, -1);
|
|
92
|
+
}
|
|
93
|
+
// numeric check with scientific notation support
|
|
94
|
+
if (NUMERIC_PATTERN.test(constantValue)) {
|
|
95
|
+
const num = parseFloat(constantValue);
|
|
96
|
+
if (isNaN(num) || !isFinite(num)) {
|
|
97
|
+
throw new Error("Invalid numeric constant");
|
|
98
|
+
}
|
|
99
|
+
return num;
|
|
100
|
+
}
|
|
101
|
+
// boolean check (case insensitive)
|
|
102
|
+
if (BOOLEAN_PATTERN.test(constantValue)) {
|
|
103
|
+
return constantValue.toLowerCase() === "true";
|
|
104
|
+
}
|
|
105
|
+
// Array check with validation
|
|
106
|
+
if (constantValue.startsWith("[") && constantValue.endsWith("]")) {
|
|
107
|
+
try {
|
|
108
|
+
const parsed = JSON.parse(constantValue);
|
|
109
|
+
if (!Array.isArray(parsed)) {
|
|
110
|
+
throw new Error("Invalid array format");
|
|
111
|
+
}
|
|
112
|
+
return parsed;
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
throw new Error("Invalid JSON array format");
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
// Object check with validation
|
|
119
|
+
if (constantValue.startsWith("{") && constantValue.endsWith("}")) {
|
|
120
|
+
try {
|
|
121
|
+
const parsed = JSON.parse(constantValue);
|
|
122
|
+
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
123
|
+
throw new Error("Invalid object format");
|
|
124
|
+
}
|
|
125
|
+
return parsed;
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
throw new Error("Invalid JSON object format");
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// special values
|
|
132
|
+
switch (constantValue.toLowerCase()) {
|
|
133
|
+
case "null":
|
|
134
|
+
return null;
|
|
135
|
+
case "undefined":
|
|
136
|
+
return undefined;
|
|
137
|
+
case "nan":
|
|
138
|
+
return NaN;
|
|
139
|
+
case "infinity":
|
|
140
|
+
return Infinity;
|
|
141
|
+
case "-infinity":
|
|
142
|
+
return -Infinity;
|
|
143
|
+
default:
|
|
144
|
+
return constantValue;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* union type validation with better error messages and nested union support
|
|
149
|
+
*/
|
|
150
|
+
static validateUnionType(unionType, value) {
|
|
151
|
+
if (!unionType || typeof unionType !== "string") {
|
|
152
|
+
return this.createErrorResult("Invalid union type definition", value);
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
// Split union into parts
|
|
156
|
+
const unionParts = unionType.split("|").map((part) => part.trim());
|
|
157
|
+
// Check if this is a type union (contains basic types) or literal union
|
|
158
|
+
const basicTypes = new Set([
|
|
159
|
+
"string",
|
|
160
|
+
"number",
|
|
161
|
+
"boolean",
|
|
162
|
+
"date",
|
|
163
|
+
"any",
|
|
164
|
+
"null",
|
|
165
|
+
"undefined",
|
|
166
|
+
]);
|
|
167
|
+
const isTypeUnion = unionParts.some((part) => basicTypes.has(part));
|
|
168
|
+
if (isTypeUnion) {
|
|
169
|
+
// Handle type union - validate that value matches one of the types
|
|
170
|
+
for (const type of unionParts) {
|
|
171
|
+
const typeResult = this.validateSingleType(type, value);
|
|
172
|
+
if (typeResult.success) {
|
|
173
|
+
return this.createSuccessResult(value);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// None of the types matched
|
|
177
|
+
return this.createErrorResult(`Expected one of types: ${unionParts.join(", ")}, got ${typeof value}`, value);
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
// Handle literal union - use the optimized literal validator
|
|
181
|
+
const result = UnionCache.OptimizedUnionValidator.validateUnion(unionType, value);
|
|
182
|
+
if (!result.isValid) {
|
|
183
|
+
return this.createErrorResult(result.error ||
|
|
184
|
+
`Expected one of: ${unionParts.join(", ")}, got ${value}`, value);
|
|
185
|
+
}
|
|
186
|
+
return this.createSuccessResult(value);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
return this.createErrorResult(`Union type validation error: ${error instanceof Error ? error.message : "Unknown error"}`, value);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Validate a single type (helper for type unions)
|
|
195
|
+
*/
|
|
196
|
+
static validateSingleType(type, value) {
|
|
197
|
+
switch (type) {
|
|
198
|
+
case "string":
|
|
199
|
+
return typeof value === "string"
|
|
200
|
+
? this.createSuccessResult(value)
|
|
201
|
+
: this.createErrorResult(`Expected string, got ${typeof value}`, value);
|
|
202
|
+
case "number":
|
|
203
|
+
return typeof value === "number" && !isNaN(value)
|
|
204
|
+
? this.createSuccessResult(value)
|
|
205
|
+
: this.createErrorResult(`Expected number, got ${typeof value}`, value);
|
|
206
|
+
case "boolean":
|
|
207
|
+
return typeof value === "boolean"
|
|
208
|
+
? this.createSuccessResult(value)
|
|
209
|
+
: this.createErrorResult(`Expected boolean, got ${typeof value}`, value);
|
|
210
|
+
case "date":
|
|
211
|
+
return value instanceof Date
|
|
212
|
+
? this.createSuccessResult(value)
|
|
213
|
+
: this.createErrorResult(`Expected Date object, got ${typeof value}`, value);
|
|
214
|
+
case "any":
|
|
215
|
+
return this.createSuccessResult(value);
|
|
216
|
+
case "null":
|
|
217
|
+
return value === null
|
|
218
|
+
? this.createSuccessResult(value)
|
|
219
|
+
: this.createErrorResult(`Expected null, got ${typeof value}`, value);
|
|
220
|
+
case "undefined":
|
|
221
|
+
return value === undefined
|
|
222
|
+
? this.createSuccessResult(value)
|
|
223
|
+
: this.createErrorResult(`Expected undefined, got ${typeof value}`, value);
|
|
224
|
+
default:
|
|
225
|
+
// For other types, delegate to the type validation system
|
|
226
|
+
return this.routeTypeValidation(type, value, {}, {});
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* record type validation with better type safety and performance
|
|
231
|
+
*/
|
|
232
|
+
static validateRecordType(type, value, validateFieldType) {
|
|
233
|
+
if (!type || typeof type !== "string") {
|
|
234
|
+
return this.createErrorResult("Invalid record type definition", value);
|
|
235
|
+
}
|
|
236
|
+
const recordMatch = type.match(/^record<([^,]+),(.+)>$/);
|
|
237
|
+
if (!recordMatch) {
|
|
238
|
+
return this.createErrorResult(`Invalid Record type format: ${type}. Expected format: record<KeyType,ValueType>`, value);
|
|
239
|
+
}
|
|
240
|
+
if (value === null || value === undefined) {
|
|
241
|
+
return this.createErrorResult("Record cannot be null or undefined", value);
|
|
242
|
+
}
|
|
243
|
+
if (typeof value !== "object" || Array.isArray(value)) {
|
|
244
|
+
return this.createErrorResult(`Expected object for Record type, got ${Array.isArray(value) ? "array" : typeof value}`, value);
|
|
245
|
+
}
|
|
246
|
+
const [, keyType, valueType] = recordMatch;
|
|
247
|
+
const trimmedKeyType = keyType.trim();
|
|
248
|
+
const trimmedValueType = valueType.trim();
|
|
249
|
+
const errors = [];
|
|
250
|
+
const validatedRecord = {};
|
|
251
|
+
// validation with proper key type checking
|
|
252
|
+
for (const [key, val] of Object.entries(value)) {
|
|
253
|
+
// Validate key type more comprehensively
|
|
254
|
+
if (!this.validateKeyType(key, trimmedKeyType)) {
|
|
255
|
+
errors.push(ErrorHandler.ErrorHandler.createError([key], `Record key "${key}" must be of type ${trimmedKeyType}, got ${typeof key}`, errors_type.ErrorCode.TYPE_ERROR, trimmedKeyType, key));
|
|
256
|
+
continue;
|
|
257
|
+
}
|
|
258
|
+
// Validate value type
|
|
259
|
+
const valueResult = validateFieldType(trimmedValueType, val);
|
|
260
|
+
if (!valueResult.success) {
|
|
261
|
+
// Add path context to nested errors
|
|
262
|
+
const nestedErrors = valueResult.errors.map((error) => ({
|
|
263
|
+
...error,
|
|
264
|
+
path: [key, ...error.path],
|
|
265
|
+
}));
|
|
266
|
+
errors.push(...nestedErrors);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
validatedRecord[key] = valueResult.data;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (errors.length > 0) {
|
|
273
|
+
return {
|
|
274
|
+
success: false,
|
|
275
|
+
errors,
|
|
276
|
+
warnings: [],
|
|
277
|
+
data: value,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
return this.createSuccessResult(validatedRecord);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* key type validation for records
|
|
284
|
+
*/
|
|
285
|
+
static validateKeyType(key, keyType) {
|
|
286
|
+
switch (keyType) {
|
|
287
|
+
case "string":
|
|
288
|
+
return typeof key === "string";
|
|
289
|
+
case "number":
|
|
290
|
+
return !isNaN(Number(key)) && isFinite(Number(key));
|
|
291
|
+
case "int":
|
|
292
|
+
case "integer":
|
|
293
|
+
return Number.isInteger(Number(key));
|
|
294
|
+
default:
|
|
295
|
+
return typeof key === "string"; // Default to string for unknown key types
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
/**
|
|
299
|
+
* array validation with better constraint handling and performance
|
|
300
|
+
*/
|
|
301
|
+
static validateArrayWithConstraints(value, elementType, constraints, validateElementType) {
|
|
302
|
+
if (!Array.isArray(value)) {
|
|
303
|
+
return this.createErrorResult(`Expected array, got ${value === null ? "null" : typeof value}`, value);
|
|
304
|
+
}
|
|
305
|
+
// constraint validation
|
|
306
|
+
const constraintErrors = this.validateArrayConstraints(value, constraints);
|
|
307
|
+
if (constraintErrors.length > 0) {
|
|
308
|
+
return {
|
|
309
|
+
success: false,
|
|
310
|
+
errors: constraintErrors,
|
|
311
|
+
warnings: [],
|
|
312
|
+
data: value,
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
// Validate elements with better error aggregation
|
|
316
|
+
const validatedArray = [];
|
|
317
|
+
const errors = [];
|
|
318
|
+
const warnings = [];
|
|
319
|
+
for (let i = 0; i < value.length; i++) {
|
|
320
|
+
const elementResult = validateElementType(elementType, value[i]);
|
|
321
|
+
if (!elementResult.success) {
|
|
322
|
+
// Add index to error paths
|
|
323
|
+
const indexedErrors = elementResult.errors.map((error) => ({
|
|
324
|
+
...error,
|
|
325
|
+
path: [i.toString(), ...error.path],
|
|
326
|
+
}));
|
|
327
|
+
errors.push(...indexedErrors);
|
|
328
|
+
}
|
|
329
|
+
else {
|
|
330
|
+
validatedArray.push(elementResult.data);
|
|
331
|
+
if (elementResult.warnings.length > 0) {
|
|
332
|
+
warnings.push(`Element at index ${i}: ${elementResult.warnings.join(", ")}`);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
if (errors.length > 0) {
|
|
337
|
+
return {
|
|
338
|
+
success: false,
|
|
339
|
+
errors,
|
|
340
|
+
warnings,
|
|
341
|
+
data: value,
|
|
342
|
+
};
|
|
343
|
+
}
|
|
344
|
+
// uniqueness check
|
|
345
|
+
if (constraints.unique) {
|
|
346
|
+
const uniqueCheck = this.checkArrayUniqueness(validatedArray);
|
|
347
|
+
if (!uniqueCheck.success) {
|
|
348
|
+
return uniqueCheck;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
return this.createSuccessResult(validatedArray, warnings);
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* array constraints validation with more constraint types
|
|
355
|
+
*/
|
|
356
|
+
static validateArrayConstraints(value, constraints) {
|
|
357
|
+
const errors = [];
|
|
358
|
+
if (!constraints)
|
|
359
|
+
return errors;
|
|
360
|
+
if (constraints.minItems !== undefined &&
|
|
361
|
+
value.length < constraints.minItems) {
|
|
362
|
+
errors.push(ErrorHandler.ErrorHandler.createArrayError([], `must have at least ${constraints.minItems} items, got ${value.length}`, value, errors_type.ErrorCode.ARRAY_TOO_SHORT));
|
|
363
|
+
}
|
|
364
|
+
if (constraints.maxItems !== undefined &&
|
|
365
|
+
value.length > constraints.maxItems) {
|
|
366
|
+
errors.push(ErrorHandler.ErrorHandler.createArrayError([], `must have at most ${constraints.maxItems} items, got ${value.length}`, value, errors_type.ErrorCode.ARRAY_TOO_LONG));
|
|
367
|
+
}
|
|
368
|
+
if (constraints.exactItems !== undefined &&
|
|
369
|
+
value.length !== constraints.exactItems) {
|
|
370
|
+
errors.push(ErrorHandler.ErrorHandler.createArrayError([], `must have exactly ${constraints.exactItems} items, got ${value.length}`, value, errors_type.ErrorCode.ARRAY_TOO_SHORT));
|
|
371
|
+
}
|
|
372
|
+
return errors;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* array uniqueness check with better performance and type handling
|
|
376
|
+
*/
|
|
377
|
+
static checkArrayUniqueness(array) {
|
|
378
|
+
const seen = new Set();
|
|
379
|
+
const duplicates = [];
|
|
380
|
+
for (let i = 0; i < array.length; i++) {
|
|
381
|
+
const item = array[i];
|
|
382
|
+
let key;
|
|
383
|
+
try {
|
|
384
|
+
key =
|
|
385
|
+
typeof item === "object" && item !== null
|
|
386
|
+
? JSON.stringify(item, Object.keys(item).sort()) // Consistent object serialization
|
|
387
|
+
: String(item);
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
// Handle circular references or non-serializable objects
|
|
391
|
+
key = `[object-${i}]`;
|
|
392
|
+
}
|
|
393
|
+
if (seen.has(key)) {
|
|
394
|
+
duplicates.push(item);
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
seen.add(key);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (duplicates.length > 0) {
|
|
401
|
+
return this.createErrorResult(`Array values must be unique. Duplicate values found: ${duplicates.map((d) => JSON.stringify(d)).join(", ")}`, array);
|
|
402
|
+
}
|
|
403
|
+
return this.createSuccessResult(array);
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* optional value handling with better default value support
|
|
407
|
+
*/
|
|
408
|
+
static handleOptionalValue(value, isOptional, defaultValue) {
|
|
409
|
+
if (value === undefined) {
|
|
410
|
+
if (isOptional) {
|
|
411
|
+
return this.createSuccessResult(defaultValue !== undefined ? defaultValue : undefined);
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
return this.createErrorResult("Required field is missing or undefined");
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
if (value === null) {
|
|
418
|
+
if (isOptional) {
|
|
419
|
+
return this.createSuccessResult(null);
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
return this.createErrorResult("Required field cannot be null");
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return null; // Continue with normal validation
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Check if type is a conditional expression using secure regex pattern
|
|
429
|
+
*/
|
|
430
|
+
static isConditionalExpression(type) {
|
|
431
|
+
// Secure regex pattern to match: when <condition> *? <thenValue> [: <elseValue>]
|
|
432
|
+
const conditionalPattern = /^\s*when\s+.+?\s*\*\?\s*.+/;
|
|
433
|
+
return conditionalPattern.test(type);
|
|
434
|
+
}
|
|
435
|
+
/**
|
|
436
|
+
* type validation routing with new types and better error handling
|
|
437
|
+
*/
|
|
438
|
+
static routeTypeValidation(type, value, options, constraints, required = false) {
|
|
439
|
+
// Debug logging
|
|
440
|
+
// Check for conditional expressions first
|
|
441
|
+
if (this.isConditionalExpression(type)) {
|
|
442
|
+
// Conditional expressions should not be validated here
|
|
443
|
+
// They should be handled by the conditional validation system
|
|
444
|
+
// Return an error indicating this is not supported in this context
|
|
445
|
+
const result = {
|
|
446
|
+
success: false,
|
|
447
|
+
errors: [
|
|
448
|
+
ErrorHandler.ErrorHandler.createValidationError([], `Unknown or unsupported type: ${type}. Please check the type definition.`, value),
|
|
449
|
+
],
|
|
450
|
+
warnings: [],
|
|
451
|
+
data: value,
|
|
452
|
+
};
|
|
453
|
+
return result;
|
|
454
|
+
}
|
|
455
|
+
if (!type || typeof type !== "string") {
|
|
456
|
+
return this.createErrorResult("Invalid type definition", value);
|
|
457
|
+
}
|
|
458
|
+
// Handle array types first (e.g., "string[]", "number[]", etc.)
|
|
459
|
+
if (type.endsWith("[]")) {
|
|
460
|
+
const elementType = type.slice(0, -2);
|
|
461
|
+
return this.validateArrayWithConstraints(value, elementType, constraints, (elementType, elementValue) => this.routeTypeValidation(elementType, elementValue, options, {}));
|
|
462
|
+
}
|
|
463
|
+
// Handle Record types first (both lowercase and TypeScript-style uppercase)
|
|
464
|
+
if ((type.startsWith("record<") && type.endsWith(">")) ||
|
|
465
|
+
(type.startsWith("Record<") && type.endsWith(">"))) {
|
|
466
|
+
// Normalize to lowercase for the validator
|
|
467
|
+
const normalizedType = type.startsWith("Record<")
|
|
468
|
+
? "record<" + type.slice(7)
|
|
469
|
+
: type;
|
|
470
|
+
return this.validateRecordType(normalizedType, value, (fieldType, value) => this.routeTypeValidation(fieldType, value, options, {}));
|
|
471
|
+
}
|
|
472
|
+
const urlType = type.startsWith("url"); // Case-sensitive URL detection
|
|
473
|
+
if (urlType) {
|
|
474
|
+
// For basic "url" type, use "url.web" as default
|
|
475
|
+
const urlArgType = type === "url" ? UrlArgs.UrlArgsEnum.web : type;
|
|
476
|
+
// Validate URL arg before proceeding
|
|
477
|
+
if (urlArgType !== UrlArgs.UrlArgsEnum.web) {
|
|
478
|
+
// Check if it's a valid URL arg
|
|
479
|
+
if (!UrlArgs.UrlArgArray.includes(urlArgType)) {
|
|
480
|
+
const error = this.createValidationError([], `Invalid URL argument: ${urlArgType}. Valid arguments are: ${UrlArgs.UrlArgArray.join(", ")}`, "INVALID_URL_ARGUMENT", `url.${UrlArgs.UrlArgArray.join("|url.")}`, value, {
|
|
481
|
+
allowedValues: [...UrlArgs.UrlArgArray],
|
|
482
|
+
suggestion: `Use one of: ${UrlArgs.UrlArgArray.join(", ")}`,
|
|
483
|
+
});
|
|
484
|
+
return {
|
|
485
|
+
success: false,
|
|
486
|
+
errors: [error],
|
|
487
|
+
warnings: [],
|
|
488
|
+
data: value,
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return TypeValidators.TypeValidators.validateUrl(value, urlArgType);
|
|
493
|
+
}
|
|
494
|
+
// switch with new types and better grouping
|
|
495
|
+
// switch with new types and better grouping using VALIDATOR_TYPES enum
|
|
496
|
+
switch (type.toLowerCase()) {
|
|
497
|
+
case ValidatorTypes.VALIDATOR_TYPES.STRING:
|
|
498
|
+
return TypeValidators.TypeValidators.validateString(value, options, constraints, required);
|
|
499
|
+
case ValidatorTypes.VALIDATOR_TYPES.NUMBER:
|
|
500
|
+
case ValidatorTypes.VALIDATOR_TYPES.FLOAT:
|
|
501
|
+
return TypeValidators.TypeValidators.validateNumber(value, options, constraints, required);
|
|
502
|
+
case ValidatorTypes.VALIDATOR_TYPES.INT:
|
|
503
|
+
case ValidatorTypes.VALIDATOR_TYPES.INTEGER:
|
|
504
|
+
console.log("Got int value");
|
|
505
|
+
return TypeValidators.TypeValidators.validateInteger(value, options, constraints, type);
|
|
506
|
+
case ValidatorTypes.VALIDATOR_TYPES.POSITIVE:
|
|
507
|
+
case ValidatorTypes.VALIDATOR_TYPES.NEGATIVE:
|
|
508
|
+
console.log("Got positive/negative value");
|
|
509
|
+
return TypeValidators.TypeValidators.validateNumber(value, options, { ...constraints, type }, required);
|
|
510
|
+
case ValidatorTypes.VALIDATOR_TYPES.DOUBLE:
|
|
511
|
+
return TypeValidators.TypeValidators.validateFloat(value, options, constraints, "double");
|
|
512
|
+
case ValidatorTypes.VALIDATOR_TYPES.BOOLEAN:
|
|
513
|
+
case ValidatorTypes.VALIDATOR_TYPES.BOOL:
|
|
514
|
+
return TypeValidators.TypeValidators.validateBoolean(value, options, constraints);
|
|
515
|
+
case ValidatorTypes.VALIDATOR_TYPES.DATE:
|
|
516
|
+
case ValidatorTypes.VALIDATOR_TYPES.DATETIME:
|
|
517
|
+
case ValidatorTypes.VALIDATOR_TYPES.TIMESTAMP:
|
|
518
|
+
return TypeValidators.TypeValidators.validateDate(value, options, constraints, type);
|
|
519
|
+
case ValidatorTypes.VALIDATOR_TYPES.EMAIL:
|
|
520
|
+
return TypeValidators.TypeValidators.validateEmail(value);
|
|
521
|
+
case ValidatorTypes.VALIDATOR_TYPES.UUID:
|
|
522
|
+
case ValidatorTypes.VALIDATOR_TYPES.GUID:
|
|
523
|
+
return TypeValidators.TypeValidators.validateUuid(value, type);
|
|
524
|
+
case ValidatorTypes.VALIDATOR_TYPES.PHONE:
|
|
525
|
+
return TypeValidators.TypeValidators.validatePhone(value);
|
|
526
|
+
case ValidatorTypes.VALIDATOR_TYPES.SLUG:
|
|
527
|
+
return TypeValidators.TypeValidators.validateSlug(value);
|
|
528
|
+
case ValidatorTypes.VALIDATOR_TYPES.USERNAME:
|
|
529
|
+
return TypeValidators.TypeValidators.validateUsername(value);
|
|
530
|
+
case ValidatorTypes.VALIDATOR_TYPES.IP:
|
|
531
|
+
return TypeValidators.TypeValidators.validateIp(value);
|
|
532
|
+
case ValidatorTypes.VALIDATOR_TYPES.PASSWORD:
|
|
533
|
+
return TypeValidators.TypeValidators.validatePassword(value);
|
|
534
|
+
case ValidatorTypes.VALIDATOR_TYPES.TEXT:
|
|
535
|
+
return TypeValidators.TypeValidators.validateText(value, {});
|
|
536
|
+
case ValidatorTypes.VALIDATOR_TYPES.JSON:
|
|
537
|
+
return TypeValidators.TypeValidators.validateJson(value, { securityMode: "fast" }); // Default to fast
|
|
538
|
+
case "json.fast":
|
|
539
|
+
return TypeValidators.TypeValidators.validateJson(value, { securityMode: "fast" });
|
|
540
|
+
case "json.secure":
|
|
541
|
+
return TypeValidators.TypeValidators.validateJson(value, { securityMode: "secure" });
|
|
542
|
+
case ValidatorTypes.VALIDATOR_TYPES.OBJECT:
|
|
543
|
+
return TypeValidators.TypeValidators.validateObject(value);
|
|
544
|
+
case ValidatorTypes.VALIDATOR_TYPES.UNKNOWN:
|
|
545
|
+
case ValidatorTypes.VALIDATOR_TYPES.VOID:
|
|
546
|
+
case ValidatorTypes.VALIDATOR_TYPES.NULL:
|
|
547
|
+
case ValidatorTypes.VALIDATOR_TYPES.UNDEFINED:
|
|
548
|
+
case ValidatorTypes.VALIDATOR_TYPES.ANY:
|
|
549
|
+
return TypeValidators.TypeValidators.validateSpecialType(value, type);
|
|
550
|
+
// NEW TYPE CASES
|
|
551
|
+
case ValidatorTypes.VALIDATOR_TYPES.HEXCOLOR:
|
|
552
|
+
return this.validateHexColor(value);
|
|
553
|
+
case ValidatorTypes.VALIDATOR_TYPES.BASE64:
|
|
554
|
+
return this.validateBase64(value);
|
|
555
|
+
case ValidatorTypes.VALIDATOR_TYPES.JWT:
|
|
556
|
+
return this.validateJWT(value);
|
|
557
|
+
case ValidatorTypes.VALIDATOR_TYPES.SEMVER:
|
|
558
|
+
return this.validateSemVer(value);
|
|
559
|
+
default:
|
|
560
|
+
return this.createErrorResult(`Unknown or unsupported type: ${type}. Please check the type definition.`, value);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
/**
|
|
564
|
+
* NEW: Validate hex color codes (#RGB, #RRGGBB, #RRGGBBAA)
|
|
565
|
+
*/
|
|
566
|
+
static validateHexColor(value) {
|
|
567
|
+
if (typeof value !== "string") {
|
|
568
|
+
return this.createErrorResult("Hex color must be a string", value);
|
|
569
|
+
}
|
|
570
|
+
if (!HEX_COLOR_PATTERN.test(value)) {
|
|
571
|
+
return this.createErrorResult("Invalid hex color format. Expected #RGB, #RRGGBB, or #RRGGBBAA", value);
|
|
572
|
+
}
|
|
573
|
+
return this.createSuccessResult(value.toUpperCase());
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* NEW: Validate Base64 encoded strings
|
|
577
|
+
*/
|
|
578
|
+
static validateBase64(value) {
|
|
579
|
+
if (typeof value !== "string") {
|
|
580
|
+
return this.createErrorResult("Base64 must be a string", value);
|
|
581
|
+
}
|
|
582
|
+
if (value.length === 0) {
|
|
583
|
+
return this.createErrorResult("Base64 string cannot be empty", value);
|
|
584
|
+
}
|
|
585
|
+
if (value.length % 4 !== 0) {
|
|
586
|
+
return this.createErrorResult("Base64 string length must be multiple of 4", value);
|
|
587
|
+
}
|
|
588
|
+
if (!BASE64_PATTERN.test(value)) {
|
|
589
|
+
return this.createErrorResult("Invalid Base64 format", value);
|
|
590
|
+
}
|
|
591
|
+
try {
|
|
592
|
+
// Validate by attempting to decode
|
|
593
|
+
if (typeof atob !== "undefined") {
|
|
594
|
+
atob(value);
|
|
595
|
+
}
|
|
596
|
+
else if (typeof Buffer !== "undefined") {
|
|
597
|
+
Buffer.from(value, "base64");
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
catch (error) {
|
|
601
|
+
return this.createErrorResult("Invalid Base64 encoding", value);
|
|
602
|
+
}
|
|
603
|
+
return this.createSuccessResult(value);
|
|
604
|
+
}
|
|
605
|
+
/**
|
|
606
|
+
* NEW: Validate JWT (JSON Web Token) format
|
|
607
|
+
*/
|
|
608
|
+
static validateJWT(value) {
|
|
609
|
+
if (typeof value !== "string") {
|
|
610
|
+
return this.createErrorResult("JWT must be a string", value);
|
|
611
|
+
}
|
|
612
|
+
if (!JWT_PATTERN.test(value)) {
|
|
613
|
+
return this.createErrorResult("Invalid JWT format. Expected three base64url segments separated by dots", value);
|
|
614
|
+
}
|
|
615
|
+
const parts = value.split(".");
|
|
616
|
+
if (parts.length !== 3) {
|
|
617
|
+
return this.createErrorResult("JWT must have exactly 3 parts", value);
|
|
618
|
+
}
|
|
619
|
+
// Validate each part is valid base64url
|
|
620
|
+
for (let i = 0; i < parts.length; i++) {
|
|
621
|
+
const part = parts[i];
|
|
622
|
+
if (!/^[A-Za-z0-9_-]+$/.test(part)) {
|
|
623
|
+
return this.createErrorResult(`JWT part ${i + 1} contains invalid base64url characters`, value);
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
// Try to decode header and payload (not signature for security reasons)
|
|
627
|
+
try {
|
|
628
|
+
const header = JSON.parse(this.base64urlDecode(parts[0]));
|
|
629
|
+
const payload = JSON.parse(this.base64urlDecode(parts[1]));
|
|
630
|
+
if (!header.alg || !header.typ) {
|
|
631
|
+
return this.createErrorResult("JWT header missing required fields (alg, typ)", value);
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
catch (error) {
|
|
635
|
+
return this.createErrorResult("JWT header or payload is not valid JSON", value);
|
|
636
|
+
}
|
|
637
|
+
return this.createSuccessResult(value);
|
|
638
|
+
}
|
|
639
|
+
/**
|
|
640
|
+
* NEW: Validate Semantic Versioning (SemVer) format
|
|
641
|
+
*/
|
|
642
|
+
static validateSemVer(value) {
|
|
643
|
+
if (typeof value !== "string") {
|
|
644
|
+
return this.createErrorResult("SemVer must be a string", value);
|
|
645
|
+
}
|
|
646
|
+
if (!SEMVER_PATTERN.test(value)) {
|
|
647
|
+
return this.createErrorResult("Invalid SemVer format. Expected MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]", value);
|
|
648
|
+
}
|
|
649
|
+
const parts = value.split(".");
|
|
650
|
+
if (parts.length < 3) {
|
|
651
|
+
return this.createErrorResult("SemVer must have at least MAJOR.MINOR.PATCH", value);
|
|
652
|
+
}
|
|
653
|
+
// Validate major, minor, patch are valid numbers
|
|
654
|
+
const [major, minor] = parts;
|
|
655
|
+
const patchPart = parts[2].split("-")[0].split("+")[0]; // Remove prerelease and build
|
|
656
|
+
if (!Number.isInteger(Number(major)) || Number(major) < 0) {
|
|
657
|
+
return this.createErrorResult("SemVer major version must be a non-negative integer", value);
|
|
658
|
+
}
|
|
659
|
+
if (!Number.isInteger(Number(minor)) || Number(minor) < 0) {
|
|
660
|
+
return this.createErrorResult("SemVer minor version must be a non-negative integer", value);
|
|
661
|
+
}
|
|
662
|
+
if (!Number.isInteger(Number(patchPart)) || Number(patchPart) < 0) {
|
|
663
|
+
return this.createErrorResult("SemVer patch version must be a non-negative integer", value);
|
|
664
|
+
}
|
|
665
|
+
return this.createSuccessResult(value);
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Helper: Base64url decode for JWT validation
|
|
669
|
+
*/
|
|
670
|
+
static base64urlDecode(str) {
|
|
671
|
+
// Convert base64url to base64
|
|
672
|
+
let base64 = str.replace(/-/g, "+").replace(/_/g, "/");
|
|
673
|
+
// Pad with = if necessary
|
|
674
|
+
while (base64.length % 4) {
|
|
675
|
+
base64 += "=";
|
|
676
|
+
}
|
|
677
|
+
try {
|
|
678
|
+
if (typeof atob !== "undefined") {
|
|
679
|
+
return atob(base64);
|
|
680
|
+
}
|
|
681
|
+
else if (typeof Buffer !== "undefined") {
|
|
682
|
+
return Buffer.from(base64, "base64").toString();
|
|
683
|
+
}
|
|
684
|
+
else {
|
|
685
|
+
throw new Error("No base64 decoder available");
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
catch (error) {
|
|
689
|
+
throw new Error("Invalid base64url encoding");
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
/**
|
|
693
|
+
* result merging with better performance and warning handling
|
|
694
|
+
*/
|
|
695
|
+
static mergeResults(results) {
|
|
696
|
+
if (results.length === 0) {
|
|
697
|
+
return this.createSuccessResult(undefined);
|
|
698
|
+
}
|
|
699
|
+
if (results.length === 1) {
|
|
700
|
+
return results[0];
|
|
701
|
+
}
|
|
702
|
+
let success = true;
|
|
703
|
+
const errors = [];
|
|
704
|
+
const warnings = [];
|
|
705
|
+
const mergedData = [];
|
|
706
|
+
for (const result of results) {
|
|
707
|
+
if (!result.success) {
|
|
708
|
+
success = false;
|
|
709
|
+
}
|
|
710
|
+
errors.push(...result.errors);
|
|
711
|
+
warnings.push(...result.warnings);
|
|
712
|
+
if (result.data !== undefined) {
|
|
713
|
+
mergedData.push(result.data);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
// Remove duplicate errors by comparing path and message
|
|
717
|
+
const uniqueErrors = errors.filter((error, index, arr) => arr.findIndex((e) => e.path.join(".") === error.path.join(".") &&
|
|
718
|
+
e.message === error.message) === index);
|
|
719
|
+
return {
|
|
720
|
+
success,
|
|
721
|
+
errors: uniqueErrors,
|
|
722
|
+
warnings: [...new Set(warnings)], // Remove duplicates
|
|
723
|
+
data: mergedData.length === 1 ? mergedData[0] : mergedData,
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
/**
|
|
727
|
+
* Create rich error result with detailed information
|
|
728
|
+
*/
|
|
729
|
+
static createErrorResult(error, value, context) {
|
|
730
|
+
const errorObj = ErrorHandler.ErrorHandler.createError(context ? [context] : [], error, errors_type.ErrorCode.VALIDATION_ERROR, "unknown", value);
|
|
731
|
+
return {
|
|
732
|
+
success: false,
|
|
733
|
+
errors: [errorObj],
|
|
734
|
+
warnings: [],
|
|
735
|
+
data: value,
|
|
736
|
+
};
|
|
737
|
+
}
|
|
738
|
+
/**
|
|
739
|
+
* Create detailed validation error object
|
|
740
|
+
*/
|
|
741
|
+
static createValidationError(path, message, code, expected, received, context) {
|
|
742
|
+
return {
|
|
743
|
+
path,
|
|
744
|
+
message,
|
|
745
|
+
code,
|
|
746
|
+
expected,
|
|
747
|
+
received,
|
|
748
|
+
receivedType: this.getValueType(received),
|
|
749
|
+
context,
|
|
750
|
+
};
|
|
751
|
+
}
|
|
752
|
+
/**
|
|
753
|
+
* Create field validation error with path
|
|
754
|
+
*/
|
|
755
|
+
static createFieldError(fieldPath, message, expected, received, code = "FIELD_VALIDATION_ERROR", suggestion) {
|
|
756
|
+
return this.createValidationError(fieldPath.split(".").filter((p) => p.length > 0), message, code, expected, received, suggestion ? { suggestion } : undefined);
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Get detailed type information for values
|
|
760
|
+
*/
|
|
761
|
+
static getValueType(value) {
|
|
762
|
+
if (value === null)
|
|
763
|
+
return "null";
|
|
764
|
+
if (value === undefined)
|
|
765
|
+
return "undefined";
|
|
766
|
+
if (Array.isArray(value))
|
|
767
|
+
return "array";
|
|
768
|
+
if (value instanceof Date)
|
|
769
|
+
return "date";
|
|
770
|
+
if (value instanceof RegExp)
|
|
771
|
+
return "regexp";
|
|
772
|
+
return typeof value;
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
775
|
+
* success result creation
|
|
776
|
+
*/
|
|
777
|
+
static createSuccessResult(data, warnings = []) {
|
|
778
|
+
return {
|
|
779
|
+
success: true,
|
|
780
|
+
errors: [],
|
|
781
|
+
warnings: [...new Set(warnings)], // Remove duplicate warnings
|
|
782
|
+
data,
|
|
783
|
+
};
|
|
784
|
+
}
|
|
785
|
+
/**
|
|
786
|
+
* cache management with selective clearing
|
|
787
|
+
*/
|
|
788
|
+
static clearCaches(cacheType) {
|
|
789
|
+
if (!cacheType || cacheType === "all" || cacheType === "constant") {
|
|
790
|
+
constantCache.clear();
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
/**
|
|
794
|
+
* cache statistics with memory usage estimation
|
|
795
|
+
*/
|
|
796
|
+
static getCacheStats() {
|
|
797
|
+
let memoryEstimate = 0;
|
|
798
|
+
for (const [key, value] of constantCache.entries()) {
|
|
799
|
+
memoryEstimate += key.length * 2; // String characters are 2 bytes each
|
|
800
|
+
memoryEstimate += this.estimateObjectSize(value);
|
|
801
|
+
}
|
|
802
|
+
return {
|
|
803
|
+
constantCacheSize: constantCache.size,
|
|
804
|
+
constantCacheMemoryEstimate: memoryEstimate,
|
|
805
|
+
};
|
|
806
|
+
}
|
|
807
|
+
/**
|
|
808
|
+
* Estimate object size in bytes for cache statistics
|
|
809
|
+
*/
|
|
810
|
+
static estimateObjectSize(obj) {
|
|
811
|
+
if (obj === null || obj === undefined)
|
|
812
|
+
return 8;
|
|
813
|
+
switch (typeof obj) {
|
|
814
|
+
case "boolean":
|
|
815
|
+
return 4;
|
|
816
|
+
case "number":
|
|
817
|
+
return 8;
|
|
818
|
+
case "string":
|
|
819
|
+
return obj.length * 2;
|
|
820
|
+
case "object":
|
|
821
|
+
if (Array.isArray(obj)) {
|
|
822
|
+
return obj.reduce((sum, item) => sum + this.estimateObjectSize(item), 24);
|
|
823
|
+
}
|
|
824
|
+
return Object.entries(obj).reduce((sum, [key, value]) => sum + key.length * 2 + this.estimateObjectSize(value), 24);
|
|
825
|
+
default:
|
|
826
|
+
return 8;
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
/**
|
|
830
|
+
* validation with comprehensive error context
|
|
831
|
+
*/
|
|
832
|
+
static validateWithContext(type, value, options, constraints, fieldPath) {
|
|
833
|
+
const result = this.routeTypeValidation(type, value, options, constraints);
|
|
834
|
+
if (!result.success && fieldPath) {
|
|
835
|
+
// Update error paths with field context
|
|
836
|
+
const updatedErrors = result.errors.map((error) => ({
|
|
837
|
+
...error,
|
|
838
|
+
path: fieldPath.split(".").concat(error.path),
|
|
839
|
+
message: error.message, // Keep original message, path provides context
|
|
840
|
+
}));
|
|
841
|
+
return {
|
|
842
|
+
...result,
|
|
843
|
+
errors: updatedErrors,
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
return result;
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
exports.ValidationHelpers = ValidationHelpers;
|
|
851
|
+
//# sourceMappingURL=ValidationHelpers.js.map
|