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
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1,2595 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core types and interfaces for the FortifyJS Schema system
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Rich validation error with detailed information
|
|
6
|
+
*/
|
|
7
|
+
interface ValidationError {
|
|
8
|
+
/** Field path where the error occurred (e.g., ['user', 'profile', 'email']) */
|
|
9
|
+
path: string[];
|
|
10
|
+
/** Human-readable error message */
|
|
11
|
+
message: string;
|
|
12
|
+
/** Error code for programmatic handling */
|
|
13
|
+
code: string;
|
|
14
|
+
/** Expected value or type */
|
|
15
|
+
expected: string;
|
|
16
|
+
/** Actual received value */
|
|
17
|
+
received: any;
|
|
18
|
+
/** Type of the received value */
|
|
19
|
+
receivedType: string;
|
|
20
|
+
/** Additional context or suggestions */
|
|
21
|
+
context?: {
|
|
22
|
+
suggestion?: string;
|
|
23
|
+
allowedValues?: any[];
|
|
24
|
+
constraints?: Record<string, any>;
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Schema validation result with rich error information
|
|
29
|
+
*/
|
|
30
|
+
interface SchemaValidationResult<T = any> {
|
|
31
|
+
success: boolean;
|
|
32
|
+
data?: T;
|
|
33
|
+
errors: ValidationError[];
|
|
34
|
+
warnings: string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Base schema configuration options
|
|
38
|
+
*/
|
|
39
|
+
interface BaseSchemaOptions {
|
|
40
|
+
optional?: boolean;
|
|
41
|
+
nullable?: boolean;
|
|
42
|
+
default?: any;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* String schema validation options
|
|
46
|
+
*/
|
|
47
|
+
interface StringSchemaOptions extends BaseSchemaOptions {
|
|
48
|
+
minLength?: number;
|
|
49
|
+
maxLength?: number;
|
|
50
|
+
pattern?: RegExp;
|
|
51
|
+
format?: "email" | "url" | "uuid" | "phone" | "slug" | "username";
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Number schema validation options
|
|
55
|
+
*/
|
|
56
|
+
interface NumberSchemaOptions extends BaseSchemaOptions {
|
|
57
|
+
min?: number;
|
|
58
|
+
max?: number;
|
|
59
|
+
integer?: boolean;
|
|
60
|
+
positive?: boolean;
|
|
61
|
+
precision?: number;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Boolean schema validation options
|
|
65
|
+
*/
|
|
66
|
+
interface BooleanSchemaOptions extends BaseSchemaOptions {
|
|
67
|
+
strict?: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Array schema validation options
|
|
71
|
+
*/
|
|
72
|
+
interface ArraySchemaOptions extends BaseSchemaOptions {
|
|
73
|
+
minLength?: number;
|
|
74
|
+
maxLength?: number;
|
|
75
|
+
unique?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Object schema validation options
|
|
79
|
+
*/
|
|
80
|
+
interface ObjectSchemaOptions extends BaseSchemaOptions {
|
|
81
|
+
strict?: boolean;
|
|
82
|
+
allowUnknown?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Schema type definitions
|
|
86
|
+
*/
|
|
87
|
+
type SchemaType = "string" | "number" | "boolean" | "array" | "object" | "date" | "any";
|
|
88
|
+
/**
|
|
89
|
+
* Schema definition for object properties
|
|
90
|
+
*/
|
|
91
|
+
type SchemaDefinition = {
|
|
92
|
+
[key: string]: SchemaConfig;
|
|
93
|
+
};
|
|
94
|
+
/**
|
|
95
|
+
* Complete schema configuration
|
|
96
|
+
*/
|
|
97
|
+
interface SchemaConfig {
|
|
98
|
+
type: SchemaType;
|
|
99
|
+
options?: BaseSchemaOptions;
|
|
100
|
+
elementSchema?: SchemaConfig;
|
|
101
|
+
properties?: SchemaDefinition;
|
|
102
|
+
validator?: (value: any) => void;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Constant value wrapper to distinguish from string types
|
|
107
|
+
*/
|
|
108
|
+
interface ConstantValue {
|
|
109
|
+
const: string | number | boolean;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Union value wrapper for proper type inference
|
|
113
|
+
*/
|
|
114
|
+
interface UnionValue<T extends readonly string[] = readonly string[]> {
|
|
115
|
+
union: T;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Optional constant value wrapper
|
|
119
|
+
*/
|
|
120
|
+
interface OptionalConstantValue {
|
|
121
|
+
const: string | number | boolean;
|
|
122
|
+
optional: true;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Optional schema interface wrapper
|
|
126
|
+
*/
|
|
127
|
+
interface OptionalSchemaInterface {
|
|
128
|
+
optional: true;
|
|
129
|
+
schema: SchemaInterface;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Schema definition using TypeScript-like interface syntax
|
|
133
|
+
*/
|
|
134
|
+
interface SchemaInterface {
|
|
135
|
+
[key: string]: SchemaFieldType | ConstantValue | OptionalConstantValue | SchemaInterface | SchemaInterface[] | any;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Field type definitions using string literals and objects
|
|
139
|
+
*/
|
|
140
|
+
type SchemaFieldType = "string" | "string?" | "number" | "number?" | "boolean" | "boolean?" | "date" | "date?" | "any" | "any?" | "email" | "email?" | "url" | "url?" | "uuid" | "uuid?" | "phone" | "phone?" | "slug" | "slug?" | "username" | "username?" | "ip" | "ip?" | "json" | "json?" | "json.fast" | "json.fast?" | "json.secure" | "json.secure?" | "password" | "password?" | "text" | "text?" | "hexcolor" | "hexcolor?" | "base64" | "base64?" | "jwt" | "jwt?" | "semver" | "semver?" | "object" | "object?" | "int" | "int?" | "positive" | "positive?" | "float" | "float?" | "string[]" | "string[]?" | "number[]" | "number[]?" | "boolean[]" | "boolean[]?" | "int[]" | "int[]?" | "email[]" | "email[]?" | "url[]" | "url[]?" | "ip[]" | "ip[]?" | "json[]" | "json[]?" | "json.fast[]" | "json.fast[]?" | "password[]" | "password[]?" | "text[]" | "text[]?" | "object[]" | "object[]?" | "hexcolor[]" | "hexcolor[]?" | "base64[]" | "base64[]?" | "jwt[]" | "jwt[]?" | "semver[]" | "semver[]?" | string | ConstantValue | OptionalConstantValue | UnionValue | SchemaInterface | SchemaInterface[] | OptionalSchemaInterface;
|
|
141
|
+
/**
|
|
142
|
+
* Schema validation options for fine-tuning
|
|
143
|
+
*/
|
|
144
|
+
interface SchemaOptions {
|
|
145
|
+
minLength?: number;
|
|
146
|
+
maxLength?: number;
|
|
147
|
+
pattern?: RegExp;
|
|
148
|
+
min?: number;
|
|
149
|
+
max?: number;
|
|
150
|
+
precision?: number;
|
|
151
|
+
minItems?: number;
|
|
152
|
+
maxItems?: number;
|
|
153
|
+
unique?: boolean;
|
|
154
|
+
strict?: boolean;
|
|
155
|
+
allowUnknown?: boolean;
|
|
156
|
+
required?: boolean;
|
|
157
|
+
default?: any;
|
|
158
|
+
loose?: boolean;
|
|
159
|
+
enablePerformanceMonitoring?: boolean;
|
|
160
|
+
enableOptimizations?: boolean;
|
|
161
|
+
cacheValidation?: boolean;
|
|
162
|
+
skipOptimization?: boolean;
|
|
163
|
+
}
|
|
164
|
+
type AllowUnknownSchema<T> = T & Record<string, any>;
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* TypeScript Interface-like Schema Definition System
|
|
168
|
+
*
|
|
169
|
+
* Allows defining schemas using TypeScript-like syntax with string literals
|
|
170
|
+
* that feel natural and are much easier to read and write.
|
|
171
|
+
*/
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Interface Schema class for TypeScript-like schema definitions
|
|
175
|
+
*/
|
|
176
|
+
declare class InterfaceSchema<T = any> {
|
|
177
|
+
private definition;
|
|
178
|
+
private options;
|
|
179
|
+
private compiledFields;
|
|
180
|
+
private schemaKeys;
|
|
181
|
+
private ConditionalParser;
|
|
182
|
+
private compiledValidator?;
|
|
183
|
+
private schemaComplexity;
|
|
184
|
+
private isOptimized;
|
|
185
|
+
private precompiledValidator?;
|
|
186
|
+
private optimizationLevel;
|
|
187
|
+
constructor(definition: SchemaInterface, options?: SchemaOptions);
|
|
188
|
+
/**
|
|
189
|
+
* Check if a field type uses conditional syntax using secure regex pattern
|
|
190
|
+
*/
|
|
191
|
+
private isConditionalSyntax;
|
|
192
|
+
/**
|
|
193
|
+
* Apply performance optimizations based on schema characteristics
|
|
194
|
+
*/
|
|
195
|
+
private applyOptimizations;
|
|
196
|
+
/**
|
|
197
|
+
* Create precompiled validator for maximum speed
|
|
198
|
+
* SAFETY: Now includes recursion protection and cycle detection
|
|
199
|
+
*/
|
|
200
|
+
private createPrecompiledValidator;
|
|
201
|
+
/**
|
|
202
|
+
* Check if schema has nested conditional fields
|
|
203
|
+
* CRITICAL FIX: This prevents precompilation for schemas with nested conditionals
|
|
204
|
+
*/
|
|
205
|
+
private hasNestedConditionalFields;
|
|
206
|
+
/**
|
|
207
|
+
* Calculate schema complexity score
|
|
208
|
+
*/
|
|
209
|
+
private calculateComplexity;
|
|
210
|
+
/**
|
|
211
|
+
* Calculate maximum nesting depth to avoid optimization bugs
|
|
212
|
+
*/
|
|
213
|
+
private calculateMaxNestingDepth;
|
|
214
|
+
/**
|
|
215
|
+
* Pre-compile schema for faster validation
|
|
216
|
+
*/
|
|
217
|
+
private precompileSchema;
|
|
218
|
+
/**
|
|
219
|
+
* Validate data against the interface schema - ULTRA-OPTIMIZED version
|
|
220
|
+
*/
|
|
221
|
+
private validate;
|
|
222
|
+
/**
|
|
223
|
+
* Standard validation method (original implementation)
|
|
224
|
+
*/
|
|
225
|
+
private validateStandard;
|
|
226
|
+
/**
|
|
227
|
+
* Validate pre-compiled string field for maximum performance
|
|
228
|
+
*/
|
|
229
|
+
private validatePrecompiledStringField;
|
|
230
|
+
/**
|
|
231
|
+
* Validate individual field
|
|
232
|
+
*/
|
|
233
|
+
private validateField;
|
|
234
|
+
/**
|
|
235
|
+
* Validate string-based field types - optimized version
|
|
236
|
+
*/
|
|
237
|
+
private validateStringFieldType;
|
|
238
|
+
/**
|
|
239
|
+
* Validate basic types with constraints
|
|
240
|
+
*/
|
|
241
|
+
private validateBasicType;
|
|
242
|
+
/**
|
|
243
|
+
* Validate nested object with full data context for conditional field resolution
|
|
244
|
+
* CRITICAL FIX: This method ensures nested conditional validation has access to parent context
|
|
245
|
+
*/
|
|
246
|
+
private validateNestedObjectWithContext;
|
|
247
|
+
/**
|
|
248
|
+
* Validate enhanced conditional field using our new AST-based system
|
|
249
|
+
* FIXED: Now properly handles nested context for field resolution
|
|
250
|
+
*/
|
|
251
|
+
private validateEnhancedConditionalField;
|
|
252
|
+
/**
|
|
253
|
+
* Validate conditional field with full data context
|
|
254
|
+
*/
|
|
255
|
+
private validateConditionalFieldWithContext;
|
|
256
|
+
/**
|
|
257
|
+
* Evaluate a condition against a field value
|
|
258
|
+
*/
|
|
259
|
+
private evaluateCondition;
|
|
260
|
+
/**
|
|
261
|
+
* Validate conditional field based on other field values (legacy method)
|
|
262
|
+
*
|
|
263
|
+
* Note: This method is used when conditional validation is called without
|
|
264
|
+
* full data context. It provides a fallback validation approach.
|
|
265
|
+
*/
|
|
266
|
+
private validateConditionalField;
|
|
267
|
+
/**
|
|
268
|
+
* Helper method to validate a value against a schema type
|
|
269
|
+
*/
|
|
270
|
+
private validateSchemaType;
|
|
271
|
+
/**
|
|
272
|
+
* Parse and validate (throws on error)
|
|
273
|
+
*/
|
|
274
|
+
parse(data: T): T;
|
|
275
|
+
/**
|
|
276
|
+
* Safe parse (returns result object) - strictly typed input
|
|
277
|
+
*/
|
|
278
|
+
safeParse(data: T): SchemaValidationResult<T>;
|
|
279
|
+
/**
|
|
280
|
+
* Safe parse with unknown data (for testing invalid inputs)
|
|
281
|
+
* Use this when you need to test data that might not match the schema
|
|
282
|
+
*/
|
|
283
|
+
safeParseUnknown(data: unknown): SchemaValidationResult<T>;
|
|
284
|
+
/**
|
|
285
|
+
* Set schema options
|
|
286
|
+
*/
|
|
287
|
+
withOptions(opts: SchemaOptions): InterfaceSchema<T>;
|
|
288
|
+
/**
|
|
289
|
+
* Async validation - returns a promise with validation result
|
|
290
|
+
*/
|
|
291
|
+
parseAsync(data: T): Promise<T>;
|
|
292
|
+
/**
|
|
293
|
+
* Async safe parse - returns a promise with validation result object
|
|
294
|
+
*/
|
|
295
|
+
safeParseAsync(data: T): Promise<SchemaValidationResult<T>>;
|
|
296
|
+
/**
|
|
297
|
+
* Async safe parse with unknown data
|
|
298
|
+
*/
|
|
299
|
+
safeParseUnknownAsync(data: unknown): Promise<SchemaValidationResult<T>>;
|
|
300
|
+
/**
|
|
301
|
+
* Enable strict mode (no unknown properties allowed)
|
|
302
|
+
*/
|
|
303
|
+
strict(): InterfaceSchema<T>;
|
|
304
|
+
/**
|
|
305
|
+
* Enable loose mode (allow type coercion)
|
|
306
|
+
*/
|
|
307
|
+
loose(): InterfaceSchema<T>;
|
|
308
|
+
/**
|
|
309
|
+
* Allow unknown properties (not strict about extra fields)
|
|
310
|
+
* Returns a schema that accepts extra properties beyond the defined interface
|
|
311
|
+
*/
|
|
312
|
+
allowUnknown(): InterfaceSchema<AllowUnknownSchema<T>>;
|
|
313
|
+
/**
|
|
314
|
+
* Set minimum constraints
|
|
315
|
+
*/
|
|
316
|
+
min(value: number): InterfaceSchema<T>;
|
|
317
|
+
/**
|
|
318
|
+
* Set maximum constraints
|
|
319
|
+
*/
|
|
320
|
+
max(value: number): InterfaceSchema<T>;
|
|
321
|
+
/**
|
|
322
|
+
* Require unique array values
|
|
323
|
+
*/
|
|
324
|
+
unique(): InterfaceSchema<T>;
|
|
325
|
+
/**
|
|
326
|
+
* Set pattern for string validation
|
|
327
|
+
*/
|
|
328
|
+
pattern(regex: RegExp): InterfaceSchema<T>;
|
|
329
|
+
/**
|
|
330
|
+
* Set default value
|
|
331
|
+
*/
|
|
332
|
+
default(value: any): InterfaceSchema<T>;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* Unified TypeScript Type Inference System
|
|
337
|
+
*
|
|
338
|
+
* Combines core schema type inference with advanced conditional analysis.
|
|
339
|
+
* This is the single source of truth for all TypeScript type operations.
|
|
340
|
+
*/
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* Core type mapping for basic field types
|
|
344
|
+
*/
|
|
345
|
+
type CoreTypeMap = {
|
|
346
|
+
string: string;
|
|
347
|
+
number: number;
|
|
348
|
+
boolean: boolean;
|
|
349
|
+
date: Date;
|
|
350
|
+
any: any;
|
|
351
|
+
email: string;
|
|
352
|
+
url: string;
|
|
353
|
+
uuid: string;
|
|
354
|
+
phone: string;
|
|
355
|
+
slug: string;
|
|
356
|
+
username: string;
|
|
357
|
+
int: number;
|
|
358
|
+
integer: number;
|
|
359
|
+
positive: number;
|
|
360
|
+
negative: number;
|
|
361
|
+
float: number;
|
|
362
|
+
double: number;
|
|
363
|
+
unknown: unknown;
|
|
364
|
+
void: undefined;
|
|
365
|
+
null: null;
|
|
366
|
+
undefined: undefined;
|
|
367
|
+
};
|
|
368
|
+
/**
|
|
369
|
+
* Extract base type from field type string (removes constraints and modifiers)
|
|
370
|
+
*/
|
|
371
|
+
type ExtractBaseType<T extends string> = T extends `${infer Base}(${string})` ? Base : T extends `${infer Base}?` ? Base : T extends `${infer Base}[]` ? Base : T extends `${infer Base}[]?` ? Base : T extends `${infer Base}!` ? Base : T extends `(${infer Content})?` ? Content : T extends `(${infer Content})` ? Content : T;
|
|
372
|
+
/**
|
|
373
|
+
* Check if field type is optional
|
|
374
|
+
*/
|
|
375
|
+
type IsOptional<T extends string> = T extends `${string}?` ? true : false;
|
|
376
|
+
/**
|
|
377
|
+
* Check if field type is an array
|
|
378
|
+
*/
|
|
379
|
+
type IsArray<T extends string> = T extends `${string}[]` | `${string}[]?` ? true : false;
|
|
380
|
+
/**
|
|
381
|
+
* Extract element type from array type, handling parentheses
|
|
382
|
+
*/
|
|
383
|
+
type ExtractElementType<T extends string> = T extends `${infer Element}[]` ? Element extends `(${infer UnionContent})` ? UnionContent : Element : T extends `${infer Element}[]?` ? Element extends `(${infer UnionContent})` ? UnionContent : Element : T;
|
|
384
|
+
/**
|
|
385
|
+
* Map field type string to TypeScript type
|
|
386
|
+
*/
|
|
387
|
+
type MapFieldType<T extends string> = IsArray<T> extends true ? Array<MapFieldType<ExtractElementType<T>>> : T extends `record<${infer K}, ${infer V}>` ? Record<MapFieldType<K> extends string | number | symbol ? MapFieldType<K> : string, MapFieldType<V>> : T extends `Record<${infer K}, ${infer V}>` ? Record<MapFieldType<K> extends string | number | symbol ? MapFieldType<K> : string, MapFieldType<V>> : T extends `when ${string} *? ${string}` ? InferConditionalType<T> : ExtractBaseType<T> extends `${string}|${string}` ? ParseUnionType<ExtractBaseType<T>> : T extends `=${infer Value}?` ? Value | undefined : T extends `=${infer Value}` ? Value : ExtractBaseType<T> extends keyof CoreTypeMap ? CoreTypeMap[ExtractBaseType<T>] : any;
|
|
388
|
+
/**
|
|
389
|
+
* Utility type to trim whitespace from string literal types
|
|
390
|
+
*/
|
|
391
|
+
type Trim<T extends string> = T extends ` ${infer Rest}` ? Trim<Rest> : T extends `${infer Rest} ` ? Trim<Rest> : T;
|
|
392
|
+
/**
|
|
393
|
+
* Parse union type string into union of literal types
|
|
394
|
+
*/
|
|
395
|
+
type ParseUnionType<T extends string> = T extends `(${infer Content})` ? ParseUnionType<Trim<Content>> : T extends `${infer First}|${infer Rest}` ? Trim<First> | ParseUnionType<Rest> : Trim<T>;
|
|
396
|
+
/**
|
|
397
|
+
* Handle optional fields
|
|
398
|
+
*/
|
|
399
|
+
type HandleOptional<T, IsOpt extends boolean> = IsOpt extends true ? T | undefined : T;
|
|
400
|
+
/**
|
|
401
|
+
* Infer type for a single field
|
|
402
|
+
*/
|
|
403
|
+
type InferFieldType$1<T> = T extends string ? HandleOptional<MapFieldType<T>, IsOptional<T>> : T extends ConstantValue ? T["const"] : T extends OptionalConstantValue ? T["const"] | undefined : T extends UnionValue<infer U> & {
|
|
404
|
+
optional: true;
|
|
405
|
+
} ? U[number] | undefined : T extends UnionValue<infer U> ? U[number] : T extends OptionalSchemaInterface ? InferSchemaType<T["schema"]> | undefined : T extends Array<infer U> ? Array<InferSchemaType<U>> : T extends object ? InferSchemaType<T> : any;
|
|
406
|
+
/**
|
|
407
|
+
* Main type inference for schema interfaces
|
|
408
|
+
* FIXED: Handle optional properties correctly in nested objects
|
|
409
|
+
*/
|
|
410
|
+
type InferSchemaType<T> = {
|
|
411
|
+
[K in keyof T as T[K] extends string ? IsOptional<T[K]> extends true ? never : K : K]: InferFieldType$1<T[K]>;
|
|
412
|
+
} & {
|
|
413
|
+
[K in keyof T as T[K] extends string ? IsOptional<T[K]> extends true ? K : never : never]?: InferFieldType$1<T[K]>;
|
|
414
|
+
};
|
|
415
|
+
type InferConditionalType<T extends string, ThenType = unknown, ElseType = unknown> = T extends `${string} *? ${infer Then} : ${infer Else}` ? Then extends `=${infer ThenValue}` ? Else extends `=${infer ElseValue}` ? ThenValue | ElseValue : ThenType | ElseType : ThenType | ElseType : ThenType | ElseType;
|
|
416
|
+
|
|
417
|
+
/**
|
|
418
|
+
* Enhanced schema modification utilities - transform, combine, and manipulate schemas
|
|
419
|
+
*/
|
|
420
|
+
declare class Mod {
|
|
421
|
+
/**
|
|
422
|
+
* Safely access schema internals with proper typing
|
|
423
|
+
*/
|
|
424
|
+
private static getSchemaInternals;
|
|
425
|
+
/**
|
|
426
|
+
* Merge multiple schemas into a single schema
|
|
427
|
+
* @example
|
|
428
|
+
* ```typescript
|
|
429
|
+
* const UserSchema = Interface({ id: "number", name: "string" });
|
|
430
|
+
* const ProfileSchema = Interface({ bio: "string?", avatar: "url?" });
|
|
431
|
+
*
|
|
432
|
+
* const MergedSchema = Mod.merge(UserSchema, ProfileSchema);
|
|
433
|
+
* // Result: { id: number, name: string, bio?: string, avatar?: string }
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
static merge<T, U>(schema1: InterfaceSchema<T>, schema2: InterfaceSchema<U>): InterfaceSchema<T & U>;
|
|
437
|
+
/**
|
|
438
|
+
* Merge multiple schemas with conflict resolution
|
|
439
|
+
* @example
|
|
440
|
+
* ```typescript
|
|
441
|
+
* const schema1 = Interface({ id: "number", name: "string" });
|
|
442
|
+
* const schema2 = Interface({ id: "uuid", email: "email" });
|
|
443
|
+
*
|
|
444
|
+
* const merged = Mod.mergeDeep(schema1, schema2, "second"); // id becomes "uuid"
|
|
445
|
+
* ```
|
|
446
|
+
*/
|
|
447
|
+
static mergeDeep<T, U>(schema1: InterfaceSchema<T>, schema2: InterfaceSchema<U>, strategy?: "first" | "second" | "merge"): InterfaceSchema<T & U>;
|
|
448
|
+
/**
|
|
449
|
+
* Pick specific fields from a schema
|
|
450
|
+
*/
|
|
451
|
+
static pick<T, K extends keyof T>(schema: InterfaceSchema<T>, keys: K[]): InterfaceSchema<Pick<T, K>>;
|
|
452
|
+
/**
|
|
453
|
+
* Omit specific fields from a schema
|
|
454
|
+
*/
|
|
455
|
+
static omit<T, K extends keyof T>(schema: InterfaceSchema<T>, keys: K[]): InterfaceSchema<Omit<T, K>>;
|
|
456
|
+
/**
|
|
457
|
+
* Make all fields in a schema optional
|
|
458
|
+
*/
|
|
459
|
+
static partial<T>(schema: InterfaceSchema<T>): InterfaceSchema<Partial<T>>;
|
|
460
|
+
/**
|
|
461
|
+
* Make all fields in a schema required
|
|
462
|
+
*/
|
|
463
|
+
static required<T>(schema: InterfaceSchema<T>): InterfaceSchema<Required<T>>;
|
|
464
|
+
/**
|
|
465
|
+
* Make specific fields optional in a schema without modifying field types
|
|
466
|
+
*
|
|
467
|
+
* This method allows you to selectively make certain fields optional while keeping
|
|
468
|
+
* all other fields required. It's particularly useful when you want to create
|
|
469
|
+
* flexible versions of strict schemas for different use cases (e.g., partial updates,
|
|
470
|
+
* form validation, API endpoints with optional parameters).
|
|
471
|
+
*
|
|
472
|
+
* The method works with both primitive types and nested objects, properly handling
|
|
473
|
+
* the optional nature at the validation level while maintaining type safety.
|
|
474
|
+
*
|
|
475
|
+
* @param schema - The source schema to modify
|
|
476
|
+
* @param keys - Array of field names to make optional
|
|
477
|
+
* @returns A new schema with specified fields made optional
|
|
478
|
+
*
|
|
479
|
+
* @example Making primitive fields optional
|
|
480
|
+
* ```typescript
|
|
481
|
+
* const UserSchema = Interface({
|
|
482
|
+
* id: "number",
|
|
483
|
+
* name: "string",
|
|
484
|
+
* email: "email",
|
|
485
|
+
* phone: "string"
|
|
486
|
+
* });
|
|
487
|
+
*
|
|
488
|
+
* const FlexibleUserSchema = Mod.makeOptional(UserSchema, ["email", "phone"]);
|
|
489
|
+
*
|
|
490
|
+
* // Now accepts both:
|
|
491
|
+
* FlexibleUserSchema.parse({ id: 1, name: "John" }); // ✅ email and phone optional
|
|
492
|
+
* FlexibleUserSchema.parse({ id: 1, name: "John", email: "john@example.com" }); // ✅
|
|
493
|
+
* ```
|
|
494
|
+
*
|
|
495
|
+
* @example Making nested objects optional
|
|
496
|
+
* ```typescript
|
|
497
|
+
* const ProfileSchema = Interface({
|
|
498
|
+
* id: "number",
|
|
499
|
+
* name: "string",
|
|
500
|
+
* preferences: {
|
|
501
|
+
* theme: "light|dark",
|
|
502
|
+
* notifications: "boolean",
|
|
503
|
+
* language: "en|es|fr"
|
|
504
|
+
* },
|
|
505
|
+
* settings: {
|
|
506
|
+
* privacy: "public|private",
|
|
507
|
+
* newsletter: "boolean"
|
|
508
|
+
* }
|
|
509
|
+
* });
|
|
510
|
+
*
|
|
511
|
+
* const FlexibleProfileSchema = Mod.makeOptional(ProfileSchema, ["preferences", "settings"]);
|
|
512
|
+
*
|
|
513
|
+
* // Now accepts:
|
|
514
|
+
* FlexibleProfileSchema.parse({ id: 1, name: "John" }); // ✅ nested objects optional
|
|
515
|
+
* FlexibleProfileSchema.parse({
|
|
516
|
+
* id: 1,
|
|
517
|
+
* name: "John",
|
|
518
|
+
* preferences: { theme: "dark", notifications: true, language: "en" }
|
|
519
|
+
* }); // ✅
|
|
520
|
+
* ```
|
|
521
|
+
*
|
|
522
|
+
* @example Use case: API endpoints with optional parameters
|
|
523
|
+
* ```typescript
|
|
524
|
+
* const CreateUserSchema = Interface({
|
|
525
|
+
* name: "string",
|
|
526
|
+
* email: "email",
|
|
527
|
+
* password: "string",
|
|
528
|
+
* role: "admin|user|moderator",
|
|
529
|
+
* department: "string",
|
|
530
|
+
* startDate: "date"
|
|
531
|
+
* });
|
|
532
|
+
*
|
|
533
|
+
* // For user registration (minimal required fields)
|
|
534
|
+
* const RegisterSchema = Mod.makeOptional(CreateUserSchema, ["role", "department", "startDate"]);
|
|
535
|
+
*
|
|
536
|
+
* // For admin creation (all fields required)
|
|
537
|
+
* const AdminCreateSchema = CreateUserSchema;
|
|
538
|
+
*
|
|
539
|
+
* // For profile updates (most fields optional)
|
|
540
|
+
* const UpdateProfileSchema = Mod.makeOptional(CreateUserSchema, ["password", "role", "department", "startDate"]);
|
|
541
|
+
* ```
|
|
542
|
+
*/
|
|
543
|
+
static makeOptional<T, K extends keyof T>(schema: InterfaceSchema<T>, keys: K[]): InterfaceSchema<Omit<T, K> & Partial<Pick<T, K>>>;
|
|
544
|
+
/**
|
|
545
|
+
* Extend a schema with additional fields
|
|
546
|
+
*/
|
|
547
|
+
static extend<T, U extends SchemaInterface>(schema: InterfaceSchema<T>, extension: U): InterfaceSchema<T & InferSchemaType<U>>;
|
|
548
|
+
/**
|
|
549
|
+
* Create a deep partial version of a schema (makes ALL fields optional recursively)
|
|
550
|
+
*
|
|
551
|
+
* Unlike the regular `partial()` method which only makes top-level fields optional,
|
|
552
|
+
* `deepPartial()` recursively traverses the entire schema structure and makes every
|
|
553
|
+
* field at every nesting level optional. This is particularly useful for update
|
|
554
|
+
* operations, patch APIs, or form validation where users might only provide
|
|
555
|
+
* partial data at any level of nesting.
|
|
556
|
+
*
|
|
557
|
+
* @param schema - The source schema to make deeply partial
|
|
558
|
+
* @returns A new schema where all fields at all levels are optional
|
|
559
|
+
*
|
|
560
|
+
* @example Basic deep partial transformation
|
|
561
|
+
* ```typescript
|
|
562
|
+
* const UserSchema = Interface({
|
|
563
|
+
* id: "number",
|
|
564
|
+
* name: "string",
|
|
565
|
+
* profile: {
|
|
566
|
+
* bio: "string",
|
|
567
|
+
* avatar: "string",
|
|
568
|
+
* social: {
|
|
569
|
+
* twitter: "string",
|
|
570
|
+
* linkedin: "string"
|
|
571
|
+
* }
|
|
572
|
+
* }
|
|
573
|
+
* });
|
|
574
|
+
*
|
|
575
|
+
* const DeepPartialSchema = Mod.deepPartial(UserSchema);
|
|
576
|
+
*
|
|
577
|
+
* // All of these are now valid:
|
|
578
|
+
* DeepPartialSchema.parse({}); // ✅ Everything optional
|
|
579
|
+
* DeepPartialSchema.parse({ id: 1 }); // ✅ Only id provided
|
|
580
|
+
* DeepPartialSchema.parse({
|
|
581
|
+
* profile: {
|
|
582
|
+
* bio: "Developer"
|
|
583
|
+
* }
|
|
584
|
+
* }); // ✅ Partial nested data
|
|
585
|
+
* DeepPartialSchema.parse({
|
|
586
|
+
* profile: {
|
|
587
|
+
* social: {
|
|
588
|
+
* twitter: "@john"
|
|
589
|
+
* }
|
|
590
|
+
* }
|
|
591
|
+
* }); // ✅ Deep nested partial data
|
|
592
|
+
* ```
|
|
593
|
+
*
|
|
594
|
+
* @example Use case: API PATCH endpoints
|
|
595
|
+
* ```typescript
|
|
596
|
+
* const ArticleSchema = Interface({
|
|
597
|
+
* id: "number",
|
|
598
|
+
* title: "string",
|
|
599
|
+
* content: "string",
|
|
600
|
+
* metadata: {
|
|
601
|
+
* tags: "string[]",
|
|
602
|
+
* category: "string",
|
|
603
|
+
* seo: {
|
|
604
|
+
* title: "string",
|
|
605
|
+
* description: "string",
|
|
606
|
+
* keywords: "string[]"
|
|
607
|
+
* }
|
|
608
|
+
* },
|
|
609
|
+
* author: {
|
|
610
|
+
* id: "number",
|
|
611
|
+
* name: "string"
|
|
612
|
+
* }
|
|
613
|
+
* });
|
|
614
|
+
*
|
|
615
|
+
* // For PATCH /articles/:id - allow partial updates at any level
|
|
616
|
+
* const PatchArticleSchema = Mod.deepPartial(ArticleSchema);
|
|
617
|
+
*
|
|
618
|
+
* // Users can update just the SEO title:
|
|
619
|
+
* PatchArticleSchema.parse({
|
|
620
|
+
* metadata: {
|
|
621
|
+
* seo: {
|
|
622
|
+
* title: "New SEO Title"
|
|
623
|
+
* }
|
|
624
|
+
* }
|
|
625
|
+
* }); // ✅
|
|
626
|
+
* ```
|
|
627
|
+
*
|
|
628
|
+
* @example Difference from regular partial()
|
|
629
|
+
* ```typescript
|
|
630
|
+
* const NestedSchema = Interface({
|
|
631
|
+
* user: {
|
|
632
|
+
* name: "string",
|
|
633
|
+
* email: "email"
|
|
634
|
+
* }
|
|
635
|
+
* });
|
|
636
|
+
*
|
|
637
|
+
* const RegularPartial = Mod.partial(NestedSchema);
|
|
638
|
+
* // Type: { user?: { name: string, email: string } }
|
|
639
|
+
* // user is optional, but if provided, name and email are required
|
|
640
|
+
*
|
|
641
|
+
* const DeepPartial = Mod.deepPartial(NestedSchema);
|
|
642
|
+
* // Type: { user?: { name?: string, email?: string } }
|
|
643
|
+
* // user is optional, and if provided, name and email are also optional
|
|
644
|
+
* ```
|
|
645
|
+
*/
|
|
646
|
+
static deepPartial<T>(schema: InterfaceSchema<T>): InterfaceSchema<DeepPartial<T>>;
|
|
647
|
+
/**
|
|
648
|
+
* Transform field types using a mapper function
|
|
649
|
+
* @example
|
|
650
|
+
* ```typescript
|
|
651
|
+
* const UserSchema = Interface({ id: "number", name: "string" });
|
|
652
|
+
* const StringifiedSchema = Mod.transform(UserSchema, (type) =>
|
|
653
|
+
* type.replace("number", "string")
|
|
654
|
+
* );
|
|
655
|
+
* // Result: { id: string, name: string }
|
|
656
|
+
* ```
|
|
657
|
+
*/
|
|
658
|
+
static transform<T>(schema: InterfaceSchema<T>, mapper: (fieldType: string, fieldName: string) => string): InterfaceSchema<any>;
|
|
659
|
+
/**
|
|
660
|
+
* Rename fields in a schema
|
|
661
|
+
* @example
|
|
662
|
+
* ```typescript
|
|
663
|
+
* const UserSchema = Interface({ user_id: "number", user_name: "string" });
|
|
664
|
+
* const RenamedSchema = Mod.rename(UserSchema, {
|
|
665
|
+
* user_id: "id",
|
|
666
|
+
* user_name: "name"
|
|
667
|
+
* });
|
|
668
|
+
* // Result: { id: number, name: string }
|
|
669
|
+
* ```
|
|
670
|
+
*/
|
|
671
|
+
static rename<T>(schema: InterfaceSchema<T>, fieldMap: Record<string, string>): InterfaceSchema<any>;
|
|
672
|
+
/**
|
|
673
|
+
* Create a schema with default values that are automatically applied during validation
|
|
674
|
+
*
|
|
675
|
+
* This method allows you to specify default values that will be automatically applied
|
|
676
|
+
* to fields when they are missing or undefined in the input data. This is particularly
|
|
677
|
+
* useful for API endpoints, form processing, and configuration objects where you want
|
|
678
|
+
* to ensure certain fields always have sensible default values.
|
|
679
|
+
*
|
|
680
|
+
* Default values are applied during the validation process, so they don't modify the
|
|
681
|
+
* original schema definition but are included in the validated output.
|
|
682
|
+
*
|
|
683
|
+
* @param schema - The source schema to add defaults to
|
|
684
|
+
* @param defaultValues - Object mapping field names to their default values
|
|
685
|
+
* @returns A new schema that applies default values during validation
|
|
686
|
+
*
|
|
687
|
+
* @example Basic default values
|
|
688
|
+
* ```typescript
|
|
689
|
+
* const UserSchema = Interface({
|
|
690
|
+
* id: "number",
|
|
691
|
+
* name: "string",
|
|
692
|
+
* role: "string?",
|
|
693
|
+
* active: "boolean?",
|
|
694
|
+
* createdAt: "date?"
|
|
695
|
+
* });
|
|
696
|
+
*
|
|
697
|
+
* const UserWithDefaults = Mod.defaults(UserSchema, {
|
|
698
|
+
* role: "user",
|
|
699
|
+
* active: true,
|
|
700
|
+
* createdAt: new Date()
|
|
701
|
+
* });
|
|
702
|
+
*
|
|
703
|
+
* const result = UserWithDefaults.parse({
|
|
704
|
+
* id: 1,
|
|
705
|
+
* name: "John Doe"
|
|
706
|
+
* // role, active, and createdAt will be filled with defaults
|
|
707
|
+
* });
|
|
708
|
+
*
|
|
709
|
+
* console.log(result.data);
|
|
710
|
+
* // {
|
|
711
|
+
* // id: 1,
|
|
712
|
+
* // name: "John Doe",
|
|
713
|
+
* // role: "user",
|
|
714
|
+
* // active: true,
|
|
715
|
+
* // createdAt: 2023-12-01T10:30:00.000Z
|
|
716
|
+
* // }
|
|
717
|
+
* ```
|
|
718
|
+
*
|
|
719
|
+
* @example API configuration with defaults
|
|
720
|
+
* ```typescript
|
|
721
|
+
* const ApiConfigSchema = Interface({
|
|
722
|
+
* host: "string",
|
|
723
|
+
* port: "number?",
|
|
724
|
+
* timeout: "number?",
|
|
725
|
+
* retries: "number?",
|
|
726
|
+
* ssl: "boolean?",
|
|
727
|
+
* compression: "boolean?"
|
|
728
|
+
* });
|
|
729
|
+
*
|
|
730
|
+
* const ApiConfigWithDefaults = Mod.defaults(ApiConfigSchema, {
|
|
731
|
+
* port: 3000,
|
|
732
|
+
* timeout: 5000,
|
|
733
|
+
* retries: 3,
|
|
734
|
+
* ssl: false,
|
|
735
|
+
* compression: true
|
|
736
|
+
* });
|
|
737
|
+
*
|
|
738
|
+
* // Users only need to provide the host
|
|
739
|
+
* const config = ApiConfigWithDefaults.parse({
|
|
740
|
+
* host: "api.example.com"
|
|
741
|
+
* });
|
|
742
|
+
* // All other fields get sensible defaults
|
|
743
|
+
* ```
|
|
744
|
+
*
|
|
745
|
+
* @example Form processing with defaults
|
|
746
|
+
* ```typescript
|
|
747
|
+
* const ProfileFormSchema = Interface({
|
|
748
|
+
* name: "string",
|
|
749
|
+
* email: "email",
|
|
750
|
+
* theme: "string?",
|
|
751
|
+
* notifications: "boolean?",
|
|
752
|
+
* language: "string?"
|
|
753
|
+
* });
|
|
754
|
+
*
|
|
755
|
+
* const ProfileWithDefaults = Mod.defaults(ProfileFormSchema, {
|
|
756
|
+
* theme: "light",
|
|
757
|
+
* notifications: true,
|
|
758
|
+
* language: "en"
|
|
759
|
+
* });
|
|
760
|
+
*
|
|
761
|
+
* // Form submissions get defaults for unchecked/unselected fields
|
|
762
|
+
* const profile = ProfileWithDefaults.parse({
|
|
763
|
+
* name: "Jane Smith",
|
|
764
|
+
* email: "jane@example.com"
|
|
765
|
+
* // theme, notifications, language get defaults
|
|
766
|
+
* });
|
|
767
|
+
* ```
|
|
768
|
+
*
|
|
769
|
+
* @example Conditional defaults based on environment
|
|
770
|
+
* ```typescript
|
|
771
|
+
* const AppConfigSchema = Interface({
|
|
772
|
+
* environment: "development|staging|production",
|
|
773
|
+
* debug: "boolean?",
|
|
774
|
+
* logLevel: "string?",
|
|
775
|
+
* cacheEnabled: "boolean?"
|
|
776
|
+
* });
|
|
777
|
+
*
|
|
778
|
+
* const isDevelopment = process.env.NODE_ENV === "development";
|
|
779
|
+
*
|
|
780
|
+
* const AppConfigWithDefaults = Mod.defaults(AppConfigSchema, {
|
|
781
|
+
* debug: isDevelopment,
|
|
782
|
+
* logLevel: isDevelopment ? "debug" : "info",
|
|
783
|
+
* cacheEnabled: !isDevelopment
|
|
784
|
+
* });
|
|
785
|
+
* ```
|
|
786
|
+
*/
|
|
787
|
+
static defaults<T>(schema: InterfaceSchema<T>, defaultValues: Record<string, any>): InterfaceSchema<T>;
|
|
788
|
+
/**
|
|
789
|
+
* Create a strict version of a schema that rejects any additional properties
|
|
790
|
+
*
|
|
791
|
+
* By default, ReliantType ignores extra properties in the input data (they're
|
|
792
|
+
* simply not included in the validated output). The `strict()` method changes this
|
|
793
|
+
* behavior to actively reject any properties that aren't defined in the schema,
|
|
794
|
+
* making validation fail with an error.
|
|
795
|
+
*
|
|
796
|
+
* This is useful for APIs where you want to ensure clients aren't sending
|
|
797
|
+
* unexpected data, form validation where extra fields indicate errors, or
|
|
798
|
+
* configuration parsing where unknown options should be flagged.
|
|
799
|
+
*
|
|
800
|
+
* @param schema - The source schema to make strict
|
|
801
|
+
* @returns A new schema that rejects additional properties
|
|
802
|
+
*
|
|
803
|
+
* @example Basic strict validation
|
|
804
|
+
* ```typescript
|
|
805
|
+
* const UserSchema = Interface({
|
|
806
|
+
* id: "number",
|
|
807
|
+
* name: "string",
|
|
808
|
+
* email: "email"
|
|
809
|
+
* });
|
|
810
|
+
*
|
|
811
|
+
* const StrictUserSchema = Mod.strict(UserSchema);
|
|
812
|
+
*
|
|
813
|
+
* // This will succeed
|
|
814
|
+
* StrictUserSchema.parse({
|
|
815
|
+
* id: 1,
|
|
816
|
+
* name: "John",
|
|
817
|
+
* email: "john@example.com"
|
|
818
|
+
* }); // ✅
|
|
819
|
+
*
|
|
820
|
+
* // This will fail due to extra property
|
|
821
|
+
* StrictUserSchema.parse({
|
|
822
|
+
* id: 1,
|
|
823
|
+
* name: "John",
|
|
824
|
+
* email: "john@example.com",
|
|
825
|
+
* age: 30 // ❌ Error: Unexpected properties: age
|
|
826
|
+
* });
|
|
827
|
+
* ```
|
|
828
|
+
*
|
|
829
|
+
* @example API endpoint validation
|
|
830
|
+
* ```typescript
|
|
831
|
+
* const CreatePostSchema = Interface({
|
|
832
|
+
* title: "string",
|
|
833
|
+
* content: "string",
|
|
834
|
+
* tags: "string[]?",
|
|
835
|
+
* published: "boolean?"
|
|
836
|
+
* });
|
|
837
|
+
*
|
|
838
|
+
* const StrictCreatePostSchema = Mod.strict(CreatePostSchema);
|
|
839
|
+
*
|
|
840
|
+
* // Protect against typos or malicious extra data
|
|
841
|
+
* app.post('/posts', (req, res) => {
|
|
842
|
+
* const result = StrictCreatePostSchema.safeParse(req.body);
|
|
843
|
+
*
|
|
844
|
+
* if (!result.success) {
|
|
845
|
+
* return res.status(400).json({
|
|
846
|
+
* error: "Invalid request data",
|
|
847
|
+
* details: result.errors
|
|
848
|
+
* });
|
|
849
|
+
* }
|
|
850
|
+
*
|
|
851
|
+
* // Guaranteed to only contain expected fields
|
|
852
|
+
* const post = result.data;
|
|
853
|
+
* });
|
|
854
|
+
* ```
|
|
855
|
+
*
|
|
856
|
+
* @example Configuration validation
|
|
857
|
+
* ```typescript
|
|
858
|
+
* const DatabaseConfigSchema = Interface({
|
|
859
|
+
* host: "string",
|
|
860
|
+
* port: "number",
|
|
861
|
+
* username: "string",
|
|
862
|
+
* password: "string",
|
|
863
|
+
* database: "string"
|
|
864
|
+
* });
|
|
865
|
+
*
|
|
866
|
+
* const StrictDatabaseConfig = Mod.strict(DatabaseConfigSchema);
|
|
867
|
+
*
|
|
868
|
+
* // Catch configuration typos early
|
|
869
|
+
* const config = StrictDatabaseConfig.parse({
|
|
870
|
+
* host: "localhost",
|
|
871
|
+
* port: 5432,
|
|
872
|
+
* username: "admin",
|
|
873
|
+
* password: "secret",
|
|
874
|
+
* database: "myapp",
|
|
875
|
+
* connectionTimeout: 5000 // ❌ Error: Unknown config option
|
|
876
|
+
* });
|
|
877
|
+
* ```
|
|
878
|
+
*
|
|
879
|
+
* @example Comparison with default behavior
|
|
880
|
+
* ```typescript
|
|
881
|
+
* const Schema = Interface({ name: "string" });
|
|
882
|
+
* const StrictSchema = Mod.strict(Schema);
|
|
883
|
+
*
|
|
884
|
+
* const input = { name: "John", extra: "ignored" };
|
|
885
|
+
*
|
|
886
|
+
* // Default behavior: extra properties ignored
|
|
887
|
+
* const defaultResult = Schema.parse(input);
|
|
888
|
+
* console.log(defaultResult); // { name: "John" } - extra property ignored
|
|
889
|
+
*
|
|
890
|
+
* // Strict behavior: extra properties cause error
|
|
891
|
+
* const strictResult = StrictSchema.safeParse(input);
|
|
892
|
+
* console.log(strictResult.success); // false
|
|
893
|
+
* console.log(strictResult.errors); // [{ message: "Unexpected properties: extra" }]
|
|
894
|
+
* ```
|
|
895
|
+
*/
|
|
896
|
+
static strict<T>(schema: InterfaceSchema<T>): InterfaceSchema<T>;
|
|
897
|
+
/**
|
|
898
|
+
* Create a passthrough version of a schema that preserves additional properties
|
|
899
|
+
*
|
|
900
|
+
* By default, ReliantType ignores extra properties in the input data (they're
|
|
901
|
+
* not included in the validated output). The `passthrough()` method changes this
|
|
902
|
+
* behavior to explicitly include all additional properties in the validated result,
|
|
903
|
+
* effectively making the schema more permissive.
|
|
904
|
+
*
|
|
905
|
+
* This is useful for proxy APIs, data transformation pipelines, or situations
|
|
906
|
+
* where you want to validate known fields while preserving unknown ones for
|
|
907
|
+
* later processing or forwarding to other systems.
|
|
908
|
+
*
|
|
909
|
+
* @param schema - The source schema to make passthrough
|
|
910
|
+
* @returns A new schema that includes additional properties in the output
|
|
911
|
+
*
|
|
912
|
+
* @example Basic passthrough behavior
|
|
913
|
+
* ```typescript
|
|
914
|
+
* const UserSchema = Interface({
|
|
915
|
+
* id: "number",
|
|
916
|
+
* name: "string",
|
|
917
|
+
* email: "email"
|
|
918
|
+
* });
|
|
919
|
+
*
|
|
920
|
+
* const PassthroughUserSchema = Mod.passthrough(UserSchema);
|
|
921
|
+
*
|
|
922
|
+
* const result = PassthroughUserSchema.parse({
|
|
923
|
+
* id: 1,
|
|
924
|
+
* name: "John",
|
|
925
|
+
* email: "john@example.com",
|
|
926
|
+
* age: 30, // Extra property
|
|
927
|
+
* department: "IT" // Extra property
|
|
928
|
+
* });
|
|
929
|
+
*
|
|
930
|
+
* console.log(result);
|
|
931
|
+
* // {
|
|
932
|
+
* // id: 1,
|
|
933
|
+
* // name: "John",
|
|
934
|
+
* // email: "john@example.com",
|
|
935
|
+
* // age: 30, // ✅ Preserved
|
|
936
|
+
* // department: "IT" // ✅ Preserved
|
|
937
|
+
* // }
|
|
938
|
+
* ```
|
|
939
|
+
*
|
|
940
|
+
* @example API proxy with validation
|
|
941
|
+
* ```typescript
|
|
942
|
+
* const KnownUserFieldsSchema = Interface({
|
|
943
|
+
* id: "number",
|
|
944
|
+
* name: "string",
|
|
945
|
+
* email: "email",
|
|
946
|
+
* role: "admin|user|moderator"
|
|
947
|
+
* });
|
|
948
|
+
*
|
|
949
|
+
* const ProxyUserSchema = Mod.passthrough(KnownUserFieldsSchema);
|
|
950
|
+
*
|
|
951
|
+
* // Validate known fields while preserving unknown ones
|
|
952
|
+
* app.post('/users/proxy', (req, res) => {
|
|
953
|
+
* const result = ProxyUserSchema.safeParse(req.body);
|
|
954
|
+
*
|
|
955
|
+
* if (!result.success) {
|
|
956
|
+
* return res.status(400).json({
|
|
957
|
+
* error: "Invalid known fields",
|
|
958
|
+
* details: result.errors
|
|
959
|
+
* });
|
|
960
|
+
* }
|
|
961
|
+
*
|
|
962
|
+
* // Forward to another service with all data preserved
|
|
963
|
+
* const response = await externalAPI.createUser(result.data);
|
|
964
|
+
* res.json(response);
|
|
965
|
+
* });
|
|
966
|
+
* ```
|
|
967
|
+
*
|
|
968
|
+
* @example Data transformation pipeline
|
|
969
|
+
* ```typescript
|
|
970
|
+
* const CoreDataSchema = Interface({
|
|
971
|
+
* timestamp: "date",
|
|
972
|
+
* userId: "number",
|
|
973
|
+
* action: "string"
|
|
974
|
+
* });
|
|
975
|
+
*
|
|
976
|
+
* const FlexibleDataSchema = Mod.passthrough(CoreDataSchema);
|
|
977
|
+
*
|
|
978
|
+
* // Process events with varying additional metadata
|
|
979
|
+
* function processEvent(rawEvent: unknown) {
|
|
980
|
+
* const result = FlexibleDataSchema.safeParse(rawEvent);
|
|
981
|
+
*
|
|
982
|
+
* if (!result.success) {
|
|
983
|
+
* throw new Error("Invalid core event structure");
|
|
984
|
+
* }
|
|
985
|
+
*
|
|
986
|
+
* const event = result.data;
|
|
987
|
+
*
|
|
988
|
+
* // Core fields are validated and typed
|
|
989
|
+
* console.log(`User ${event.userId} performed ${event.action} at ${event.timestamp}`);
|
|
990
|
+
*
|
|
991
|
+
* // Additional metadata is preserved for downstream processing
|
|
992
|
+
* if ('metadata' in event) {
|
|
993
|
+
* processMetadata(event.metadata);
|
|
994
|
+
* }
|
|
995
|
+
*
|
|
996
|
+
* return event; // All data preserved
|
|
997
|
+
* }
|
|
998
|
+
* ```
|
|
999
|
+
*
|
|
1000
|
+
* @example Comparison with default and strict behavior
|
|
1001
|
+
* ```typescript
|
|
1002
|
+
* const Schema = Interface({ name: "string" });
|
|
1003
|
+
* const PassthroughSchema = Mod.passthrough(Schema);
|
|
1004
|
+
* const StrictSchema = Mod.strict(Schema);
|
|
1005
|
+
*
|
|
1006
|
+
* const input = { name: "John", extra: "data", more: "fields" };
|
|
1007
|
+
*
|
|
1008
|
+
* // Default: extra properties ignored
|
|
1009
|
+
* const defaultResult = Schema.parse(input);
|
|
1010
|
+
* console.log(defaultResult); // { name: "John" }
|
|
1011
|
+
*
|
|
1012
|
+
* // Passthrough: extra properties included
|
|
1013
|
+
* const passthroughResult = PassthroughSchema.parse(input);
|
|
1014
|
+
* console.log(passthroughResult); // { name: "John", extra: "data", more: "fields" }
|
|
1015
|
+
*
|
|
1016
|
+
* // Strict: extra properties cause error
|
|
1017
|
+
* const strictResult = StrictSchema.safeParse(input);
|
|
1018
|
+
* console.log(strictResult.success); // false
|
|
1019
|
+
* ```
|
|
1020
|
+
*/
|
|
1021
|
+
static passthrough<T>(schema: InterfaceSchema<T>): InterfaceSchema<T & Record<string, any>>;
|
|
1022
|
+
/**
|
|
1023
|
+
* Create a schema that accepts null values for all fields
|
|
1024
|
+
* @example
|
|
1025
|
+
* ```typescript
|
|
1026
|
+
* const UserSchema = Interface({ id: "number", name: "string" });
|
|
1027
|
+
* const NullableSchema = Mod.nullable(UserSchema);
|
|
1028
|
+
* // Result: { id: number | null, name: string | null }
|
|
1029
|
+
* ```
|
|
1030
|
+
*/
|
|
1031
|
+
static nullable<T>(schema: InterfaceSchema<T>): InterfaceSchema<{
|
|
1032
|
+
[K in keyof T]: T[K] | null;
|
|
1033
|
+
}>;
|
|
1034
|
+
/**
|
|
1035
|
+
* Get comprehensive metadata and statistics about a schema
|
|
1036
|
+
*
|
|
1037
|
+
* This method analyzes a schema and returns detailed information about its structure,
|
|
1038
|
+
* including field counts, types, and other useful metadata. This is particularly
|
|
1039
|
+
* useful for debugging, documentation generation, schema analysis tools, or
|
|
1040
|
+
* building dynamic UIs based on schema structure.
|
|
1041
|
+
*
|
|
1042
|
+
* @param schema - The schema to analyze
|
|
1043
|
+
* @returns Object containing detailed schema metadata
|
|
1044
|
+
*
|
|
1045
|
+
* @example Basic schema analysis
|
|
1046
|
+
* ```typescript
|
|
1047
|
+
* const UserSchema = Interface({
|
|
1048
|
+
* id: "number",
|
|
1049
|
+
* name: "string",
|
|
1050
|
+
* email: "email?",
|
|
1051
|
+
* profile: {
|
|
1052
|
+
* bio: "string?",
|
|
1053
|
+
* avatar: "string"
|
|
1054
|
+
* },
|
|
1055
|
+
* tags: "string[]?"
|
|
1056
|
+
* });
|
|
1057
|
+
*
|
|
1058
|
+
* const info = Mod.info(UserSchema);
|
|
1059
|
+
* console.log(info);
|
|
1060
|
+
* // {
|
|
1061
|
+
* // fieldCount: 5,
|
|
1062
|
+
* // requiredFields: 3,
|
|
1063
|
+
* // optionalFields: 2,
|
|
1064
|
+
* // types: ["number", "string", "email?", "object", "string[]?"],
|
|
1065
|
+
* // fields: ["id", "name", "email", "profile", "tags"]
|
|
1066
|
+
* // }
|
|
1067
|
+
* ```
|
|
1068
|
+
*
|
|
1069
|
+
* @example Using info for documentation generation
|
|
1070
|
+
* ```typescript
|
|
1071
|
+
* function generateSchemaDoc(schema: InterfaceSchema<any>, name: string) {
|
|
1072
|
+
* const info = Mod.info(schema);
|
|
1073
|
+
*
|
|
1074
|
+
* return `
|
|
1075
|
+
* ## ${name} Schema
|
|
1076
|
+
*
|
|
1077
|
+
* **Fields:** ${info.fieldCount} total (${info.requiredFields} required, ${info.optionalFields} optional)
|
|
1078
|
+
*
|
|
1079
|
+
* **Field Types:**
|
|
1080
|
+
* ${info.fields.map((field, i) => `- ${field}: ${info.types[i]}`).join('\n')}
|
|
1081
|
+
* `;
|
|
1082
|
+
* }
|
|
1083
|
+
*
|
|
1084
|
+
* const doc = generateSchemaDoc(UserSchema, "User");
|
|
1085
|
+
* console.log(doc);
|
|
1086
|
+
* ```
|
|
1087
|
+
*
|
|
1088
|
+
* @example Schema complexity analysis
|
|
1089
|
+
* ```typescript
|
|
1090
|
+
* function analyzeSchemaComplexity(schema: InterfaceSchema<any>) {
|
|
1091
|
+
* const info = Mod.info(schema);
|
|
1092
|
+
*
|
|
1093
|
+
* const complexity = {
|
|
1094
|
+
* simple: info.fieldCount <= 5,
|
|
1095
|
+
* hasOptionalFields: info.optionalFields > 0,
|
|
1096
|
+
* hasArrays: info.types.some(type => type.includes('[]')),
|
|
1097
|
+
* hasNestedObjects: info.types.includes('object'),
|
|
1098
|
+
* typeVariety: new Set(info.types.map(type =>
|
|
1099
|
+
* type.replace(/\?|\[\]/g, '')
|
|
1100
|
+
* )).size
|
|
1101
|
+
* };
|
|
1102
|
+
*
|
|
1103
|
+
* return complexity;
|
|
1104
|
+
* }
|
|
1105
|
+
*
|
|
1106
|
+
* const complexity = analyzeSchemaComplexity(UserSchema);
|
|
1107
|
+
* console.log(complexity);
|
|
1108
|
+
* // {
|
|
1109
|
+
* // simple: false,
|
|
1110
|
+
* // hasOptionalFields: true,
|
|
1111
|
+
* // hasArrays: true,
|
|
1112
|
+
* // hasNestedObjects: true,
|
|
1113
|
+
* // typeVariety: 4
|
|
1114
|
+
* // }
|
|
1115
|
+
* ```
|
|
1116
|
+
*
|
|
1117
|
+
* @example Dynamic form generation
|
|
1118
|
+
* ```typescript
|
|
1119
|
+
* function generateFormFields(schema: InterfaceSchema<any>) {
|
|
1120
|
+
* const info = Mod.info(schema);
|
|
1121
|
+
*
|
|
1122
|
+
* return info.fields.map((fieldName, index) => {
|
|
1123
|
+
* const fieldType = info.types[index];
|
|
1124
|
+
* const isRequired = !fieldType.includes('?');
|
|
1125
|
+
* const baseType = fieldType.replace(/\?|\[\]/g, '');
|
|
1126
|
+
*
|
|
1127
|
+
* return {
|
|
1128
|
+
* name: fieldName,
|
|
1129
|
+
* type: baseType,
|
|
1130
|
+
* required: isRequired,
|
|
1131
|
+
* isArray: fieldType.includes('[]'),
|
|
1132
|
+
* inputType: getInputType(baseType) // Custom function
|
|
1133
|
+
* };
|
|
1134
|
+
* });
|
|
1135
|
+
* }
|
|
1136
|
+
*
|
|
1137
|
+
* function getInputType(type: string): string {
|
|
1138
|
+
* switch (type) {
|
|
1139
|
+
* case 'string': return 'text';
|
|
1140
|
+
* case 'number': return 'number';
|
|
1141
|
+
* case 'email': return 'email';
|
|
1142
|
+
* case 'date': return 'date';
|
|
1143
|
+
* case 'boolean': return 'checkbox';
|
|
1144
|
+
* default: return 'text';
|
|
1145
|
+
* }
|
|
1146
|
+
* }
|
|
1147
|
+
*
|
|
1148
|
+
* const formFields = generateFormFields(UserSchema);
|
|
1149
|
+
* ```
|
|
1150
|
+
*
|
|
1151
|
+
* @example Schema validation and testing
|
|
1152
|
+
* ```typescript
|
|
1153
|
+
* function validateSchemaStructure(schema: InterfaceSchema<any>) {
|
|
1154
|
+
* const info = Mod.info(schema);
|
|
1155
|
+
* const issues: string[] = [];
|
|
1156
|
+
*
|
|
1157
|
+
* if (info.fieldCount === 0) {
|
|
1158
|
+
* issues.push("Schema has no fields");
|
|
1159
|
+
* }
|
|
1160
|
+
*
|
|
1161
|
+
* if (info.requiredFields === 0) {
|
|
1162
|
+
* issues.push("Schema has no required fields");
|
|
1163
|
+
* }
|
|
1164
|
+
*
|
|
1165
|
+
* if (info.fieldCount > 20) {
|
|
1166
|
+
* issues.push("Schema might be too complex (>20 fields)");
|
|
1167
|
+
* }
|
|
1168
|
+
*
|
|
1169
|
+
* const unknownTypes = info.types.filter(type =>
|
|
1170
|
+
* !['string', 'number', 'boolean', 'date', 'email', 'object'].some(known =>
|
|
1171
|
+
* type.replace(/\?|\[\]/g, '').includes(known)
|
|
1172
|
+
* )
|
|
1173
|
+
* );
|
|
1174
|
+
*
|
|
1175
|
+
* if (unknownTypes.length > 0) {
|
|
1176
|
+
* issues.push(`Unknown types found: ${unknownTypes.join(', ')}`);
|
|
1177
|
+
* }
|
|
1178
|
+
*
|
|
1179
|
+
* return {
|
|
1180
|
+
* valid: issues.length === 0,
|
|
1181
|
+
* issues,
|
|
1182
|
+
* info
|
|
1183
|
+
* };
|
|
1184
|
+
* }
|
|
1185
|
+
* ```
|
|
1186
|
+
*/
|
|
1187
|
+
static info<T>(schema: InterfaceSchema<T>): {
|
|
1188
|
+
fieldCount: number;
|
|
1189
|
+
requiredFields: number;
|
|
1190
|
+
optionalFields: number;
|
|
1191
|
+
types: string[];
|
|
1192
|
+
fields: string[];
|
|
1193
|
+
};
|
|
1194
|
+
/**
|
|
1195
|
+
* Clone a schema with optional modifications
|
|
1196
|
+
* @example
|
|
1197
|
+
* ```typescript
|
|
1198
|
+
* const UserSchema = Interface({ id: "number", name: "string" });
|
|
1199
|
+
* const ClonedSchema = Mod.clone(UserSchema, { preserveOptions: true });
|
|
1200
|
+
* ```
|
|
1201
|
+
*/
|
|
1202
|
+
static clone<T>(schema: InterfaceSchema<T>, options?: {
|
|
1203
|
+
preserveOptions?: boolean;
|
|
1204
|
+
}): InterfaceSchema<T>;
|
|
1205
|
+
}
|
|
1206
|
+
type DeepPartial<T> = {
|
|
1207
|
+
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
|
|
1208
|
+
};
|
|
1209
|
+
|
|
1210
|
+
/**
|
|
1211
|
+
* Helper class for creating schema values
|
|
1212
|
+
*/
|
|
1213
|
+
declare class Make {
|
|
1214
|
+
/**
|
|
1215
|
+
* Create a constant value (safer than using raw values)
|
|
1216
|
+
* @example
|
|
1217
|
+
* ```typescript
|
|
1218
|
+
* const schema = Interface({
|
|
1219
|
+
* status: Make.const("pending"),
|
|
1220
|
+
* version: Make.const(1.0),
|
|
1221
|
+
* enabled: Make.const(true)
|
|
1222
|
+
* });
|
|
1223
|
+
* ```
|
|
1224
|
+
*/
|
|
1225
|
+
static const<const T extends string | number | boolean>(value: T): ConstantValue & {
|
|
1226
|
+
const: T;
|
|
1227
|
+
};
|
|
1228
|
+
/**
|
|
1229
|
+
* Create a union type (multiple allowed values) with proper type inference
|
|
1230
|
+
* @example
|
|
1231
|
+
* ```typescript
|
|
1232
|
+
* const schema = Interface({
|
|
1233
|
+
* status: Make.union("pending", "accepted", "rejected"),
|
|
1234
|
+
* priority: Make.union("low", "medium", "high")
|
|
1235
|
+
* });
|
|
1236
|
+
* ```
|
|
1237
|
+
*/
|
|
1238
|
+
static union<const T extends readonly string[]>(...values: T): UnionValue<T>;
|
|
1239
|
+
/**
|
|
1240
|
+
* Create an optional union type with proper type inference
|
|
1241
|
+
* @example
|
|
1242
|
+
* ```typescript
|
|
1243
|
+
* const schema = Interface({
|
|
1244
|
+
* status: Make.unionOptional("pending", "accepted", "rejected")
|
|
1245
|
+
* });
|
|
1246
|
+
* ```
|
|
1247
|
+
*/
|
|
1248
|
+
static unionOptional<const T extends readonly string[]>(...values: T): UnionValue<T> & {
|
|
1249
|
+
optional: true;
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
/**
|
|
1254
|
+
* TypeScript Interface-like Schema System
|
|
1255
|
+
*
|
|
1256
|
+
* The most intuitive way to define schemas - just like TypeScript interfaces!
|
|
1257
|
+
*
|
|
1258
|
+
* @example
|
|
1259
|
+
* ```typescript
|
|
1260
|
+
* import { Interface as IF} from "reliant-type";
|
|
1261
|
+
*
|
|
1262
|
+
* // Define schema like a TypeScript interface
|
|
1263
|
+
* const UserSchema = IF({
|
|
1264
|
+
* id: "number",
|
|
1265
|
+
* email: "email",
|
|
1266
|
+
* name: "string",
|
|
1267
|
+
* age: "number?", // Optional
|
|
1268
|
+
* isActive: "boolean?", // Optional
|
|
1269
|
+
* tags: "string[]?", // Optional array
|
|
1270
|
+
* role: "admin", // Constant value
|
|
1271
|
+
* profile: { // Nested object
|
|
1272
|
+
* bio: "string?",
|
|
1273
|
+
* avatar: "url?"
|
|
1274
|
+
* }
|
|
1275
|
+
* });
|
|
1276
|
+
*
|
|
1277
|
+
* // Validate data
|
|
1278
|
+
* const result = UserSchema.safeParse(userData);
|
|
1279
|
+
* ```
|
|
1280
|
+
*/
|
|
1281
|
+
|
|
1282
|
+
/**
|
|
1283
|
+
* Create a schema using TypeScript interface-like syntax with full type inference
|
|
1284
|
+
*
|
|
1285
|
+
* @param definition - Schema definition using TypeScript-like syntax
|
|
1286
|
+
* @param options - Optional validation options
|
|
1287
|
+
* @returns InterfaceSchema instance with inferred types
|
|
1288
|
+
*
|
|
1289
|
+
* @example Basic Usage
|
|
1290
|
+
* ```typescript
|
|
1291
|
+
* const UserSchema = Interface({
|
|
1292
|
+
* id: "number",
|
|
1293
|
+
* email: "email",
|
|
1294
|
+
* name: "string",
|
|
1295
|
+
* age: "number?",
|
|
1296
|
+
* isActive: "boolean?",
|
|
1297
|
+
* tags: "string[]?"
|
|
1298
|
+
* });
|
|
1299
|
+
*
|
|
1300
|
+
* // result is fully typed as:
|
|
1301
|
+
* // SchemaValidationResult<{
|
|
1302
|
+
* // id: number;
|
|
1303
|
+
* // email: string;
|
|
1304
|
+
* // name: string;
|
|
1305
|
+
* // age?: number;
|
|
1306
|
+
* // isActive?: boolean;
|
|
1307
|
+
* // tags?: string[];
|
|
1308
|
+
* // }>
|
|
1309
|
+
* const result = UserSchema.safeParse(data);
|
|
1310
|
+
* ```
|
|
1311
|
+
*
|
|
1312
|
+
* @example With Constraints
|
|
1313
|
+
* ```typescript
|
|
1314
|
+
* const UserSchema = Interface({
|
|
1315
|
+
* username: "string(3,20)", // 3-20 characters
|
|
1316
|
+
* age: "number(18,120)", // 18-120 years
|
|
1317
|
+
* tags: "string[](1,10)?", // 1-10 tags, optional
|
|
1318
|
+
* });
|
|
1319
|
+
* ```
|
|
1320
|
+
*
|
|
1321
|
+
* @example Nested Objects
|
|
1322
|
+
* ```typescript
|
|
1323
|
+
* const OrderSchema = Interface({
|
|
1324
|
+
* id: "number",
|
|
1325
|
+
* customer: {
|
|
1326
|
+
* name: "string",
|
|
1327
|
+
* email: "email",
|
|
1328
|
+
* address: {
|
|
1329
|
+
* street: "string",
|
|
1330
|
+
* city: "string",
|
|
1331
|
+
* zipCode: "string"
|
|
1332
|
+
* }
|
|
1333
|
+
* },
|
|
1334
|
+
* items: [{
|
|
1335
|
+
* name: "string",
|
|
1336
|
+
* price: "number",
|
|
1337
|
+
* quantity: "int"
|
|
1338
|
+
* }]
|
|
1339
|
+
* });
|
|
1340
|
+
* ```
|
|
1341
|
+
*/
|
|
1342
|
+
declare function Interface<const T extends SchemaInterface>(definition: T, options?: SchemaOptions): InterfaceSchema<InferSchemaType<T>>;
|
|
1343
|
+
/**
|
|
1344
|
+
* Type helper for inferring TypeScript types from schema definitions
|
|
1345
|
+
*
|
|
1346
|
+
* @example
|
|
1347
|
+
* ```typescript
|
|
1348
|
+
* const UserSchema = Interface({
|
|
1349
|
+
* id: "number",
|
|
1350
|
+
* email: "email",
|
|
1351
|
+
* name: "string",
|
|
1352
|
+
* age: "number?",
|
|
1353
|
+
* tags: "string[]?"
|
|
1354
|
+
* });
|
|
1355
|
+
*
|
|
1356
|
+
* // Infer the TypeScript type
|
|
1357
|
+
* type User = InferType<typeof UserSchema>;
|
|
1358
|
+
* // User = {
|
|
1359
|
+
* // id: number;
|
|
1360
|
+
* // email: string;
|
|
1361
|
+
* // name: string;
|
|
1362
|
+
* // age?: number;
|
|
1363
|
+
* // tags?: string[];
|
|
1364
|
+
* // }
|
|
1365
|
+
* ```
|
|
1366
|
+
*/
|
|
1367
|
+
type InferType<T extends InterfaceSchema<any>> = T extends InterfaceSchema<infer U> ? U : never;
|
|
1368
|
+
|
|
1369
|
+
/**
|
|
1370
|
+
* Available field types for schema definitions
|
|
1371
|
+
*/
|
|
1372
|
+
declare const FieldTypes: {
|
|
1373
|
+
readonly STRING: "string";
|
|
1374
|
+
readonly STRING_OPTIONAL: "string?";
|
|
1375
|
+
readonly NUMBER: "number";
|
|
1376
|
+
readonly NUMBER_OPTIONAL: "number?";
|
|
1377
|
+
readonly BOOLEAN: "boolean";
|
|
1378
|
+
readonly BOOLEAN_OPTIONAL: "boolean?";
|
|
1379
|
+
readonly DATE: "date";
|
|
1380
|
+
readonly DATE_OPTIONAL: "date?";
|
|
1381
|
+
readonly ANY: "any";
|
|
1382
|
+
readonly ANY_OPTIONAL: "any?";
|
|
1383
|
+
readonly EMAIL: "email";
|
|
1384
|
+
readonly EMAIL_OPTIONAL: "email?";
|
|
1385
|
+
readonly URL: "url";
|
|
1386
|
+
readonly URL_OPTIONAL: "url?";
|
|
1387
|
+
readonly UUID: "uuid";
|
|
1388
|
+
readonly UUID_OPTIONAL: "uuid?";
|
|
1389
|
+
readonly PHONE: "phone";
|
|
1390
|
+
readonly PHONE_OPTIONAL: "phone?";
|
|
1391
|
+
readonly SLUG: "slug";
|
|
1392
|
+
readonly SLUG_OPTIONAL: "slug?";
|
|
1393
|
+
readonly USERNAME: "username";
|
|
1394
|
+
readonly USERNAME_OPTIONAL: "username?";
|
|
1395
|
+
readonly INT: "int";
|
|
1396
|
+
readonly INT_OPTIONAL: "int?";
|
|
1397
|
+
readonly POSITIVE: "positive";
|
|
1398
|
+
readonly POSITIVE_OPTIONAL: "positive?";
|
|
1399
|
+
readonly FLOAT: "float";
|
|
1400
|
+
readonly FLOAT_OPTIONAL: "float?";
|
|
1401
|
+
readonly STRING_ARRAY: "string[]";
|
|
1402
|
+
readonly STRING_ARRAY_OPTIONAL: "string[]?";
|
|
1403
|
+
readonly NUMBER_ARRAY: "number[]";
|
|
1404
|
+
readonly NUMBER_ARRAY_OPTIONAL: "number[]?";
|
|
1405
|
+
readonly BOOLEAN_ARRAY: "boolean[]";
|
|
1406
|
+
readonly BOOLEAN_ARRAY_OPTIONAL: "boolean[]?";
|
|
1407
|
+
readonly INT_ARRAY: "int[]";
|
|
1408
|
+
readonly INT_ARRAY_OPTIONAL: "int[]?";
|
|
1409
|
+
readonly EMAIL_ARRAY: "email[]";
|
|
1410
|
+
readonly EMAIL_ARRAY_OPTIONAL: "email[]?";
|
|
1411
|
+
readonly URL_ARRAY: "url[]";
|
|
1412
|
+
readonly URL_ARRAY_OPTIONAL: "url[]?";
|
|
1413
|
+
readonly RECORD_STRING_ANY: "record<string,any>";
|
|
1414
|
+
readonly RECORD_STRING_ANY_OPTIONAL: "record<string,any>?";
|
|
1415
|
+
readonly RECORD_STRING_STRING: "record<string,string>";
|
|
1416
|
+
readonly RECORD_STRING_STRING_OPTIONAL: "record<string,string>?";
|
|
1417
|
+
readonly RECORD_STRING_NUMBER: "record<string,number>";
|
|
1418
|
+
readonly RECORD_STRING_NUMBER_OPTIONAL: "record<string,number>?";
|
|
1419
|
+
};
|
|
1420
|
+
/**
|
|
1421
|
+
* Quick schema creation helpers
|
|
1422
|
+
*/
|
|
1423
|
+
declare const QuickSchemas: {
|
|
1424
|
+
/**
|
|
1425
|
+
* User schema with common fields
|
|
1426
|
+
*/
|
|
1427
|
+
User: InterfaceSchema<InferSchemaType<{
|
|
1428
|
+
readonly id: "number";
|
|
1429
|
+
readonly email: "email";
|
|
1430
|
+
readonly name: "string";
|
|
1431
|
+
readonly createdAt: "date?";
|
|
1432
|
+
readonly updatedAt: "date?";
|
|
1433
|
+
}>>;
|
|
1434
|
+
/**
|
|
1435
|
+
* API response schema
|
|
1436
|
+
*/
|
|
1437
|
+
APIResponse: InterfaceSchema<InferSchemaType<{
|
|
1438
|
+
readonly success: "boolean";
|
|
1439
|
+
readonly data: "any?";
|
|
1440
|
+
readonly errors: "string[]?";
|
|
1441
|
+
readonly timestamp: "date?";
|
|
1442
|
+
}>>;
|
|
1443
|
+
/**
|
|
1444
|
+
* Pagination schema
|
|
1445
|
+
*/
|
|
1446
|
+
Pagination: InterfaceSchema<InferSchemaType<{
|
|
1447
|
+
readonly page: "int";
|
|
1448
|
+
readonly limit: "int";
|
|
1449
|
+
readonly total: "int";
|
|
1450
|
+
readonly hasNext: "boolean?";
|
|
1451
|
+
readonly hasPrev: "boolean?";
|
|
1452
|
+
}>>;
|
|
1453
|
+
/**
|
|
1454
|
+
* Address schema
|
|
1455
|
+
*/
|
|
1456
|
+
Address: InterfaceSchema<InferSchemaType<{
|
|
1457
|
+
readonly street: "string";
|
|
1458
|
+
readonly city: "string";
|
|
1459
|
+
readonly state: "string?";
|
|
1460
|
+
readonly zipCode: "string";
|
|
1461
|
+
readonly country: "string";
|
|
1462
|
+
}>>;
|
|
1463
|
+
/**
|
|
1464
|
+
* Contact info schema
|
|
1465
|
+
*/
|
|
1466
|
+
Contact: InterfaceSchema<InferSchemaType<{
|
|
1467
|
+
readonly email: "email?";
|
|
1468
|
+
readonly phone: "phone?";
|
|
1469
|
+
readonly website: "url?";
|
|
1470
|
+
}>>;
|
|
1471
|
+
};
|
|
1472
|
+
|
|
1473
|
+
/**
|
|
1474
|
+
* OpenAPI Converter - Convert schemas to OpenAPI specifications
|
|
1475
|
+
*
|
|
1476
|
+
* This module provides utilities to convert ReliantType definitions
|
|
1477
|
+
* to OpenAPI 3.0 specifications for API documentation.
|
|
1478
|
+
*/
|
|
1479
|
+
|
|
1480
|
+
/**
|
|
1481
|
+
* OpenAPI converter for schema definitions
|
|
1482
|
+
*/
|
|
1483
|
+
declare class OpenAPIConverter {
|
|
1484
|
+
/**
|
|
1485
|
+
* Convert a schema to OpenAPI format
|
|
1486
|
+
*/
|
|
1487
|
+
static convertSchema(schema: SchemaInterface): OpenAPISchemaObject;
|
|
1488
|
+
/**
|
|
1489
|
+
* Convert a single field to OpenAPI property
|
|
1490
|
+
*/
|
|
1491
|
+
private static convertField;
|
|
1492
|
+
/**
|
|
1493
|
+
* Convert string-based field definitions
|
|
1494
|
+
*/
|
|
1495
|
+
private static convertStringField;
|
|
1496
|
+
/**
|
|
1497
|
+
* Convert object field definitions
|
|
1498
|
+
*/
|
|
1499
|
+
private static convertObjectField;
|
|
1500
|
+
/**
|
|
1501
|
+
* Parse string constraints from string(min,max) format
|
|
1502
|
+
*/
|
|
1503
|
+
private static parseStringConstraints;
|
|
1504
|
+
/**
|
|
1505
|
+
* Generate complete OpenAPI specification
|
|
1506
|
+
*/
|
|
1507
|
+
static generateOpenAPISpec(schema: SchemaInterface, options: OpenAPISpecOptions): OpenAPISpecification;
|
|
1508
|
+
/**
|
|
1509
|
+
* Generate schema reference for use in OpenAPI paths
|
|
1510
|
+
*/
|
|
1511
|
+
static generateSchemaReference(schemaName: string): OpenAPIReference;
|
|
1512
|
+
/**
|
|
1513
|
+
* Generate request body specification
|
|
1514
|
+
*/
|
|
1515
|
+
static generateRequestBody(schema: SchemaInterface, options?: RequestBodyOptions): OpenAPIRequestBody;
|
|
1516
|
+
/**
|
|
1517
|
+
* Generate response specification
|
|
1518
|
+
*/
|
|
1519
|
+
static generateResponse(schema: SchemaInterface, options?: ResponseOptions): OpenAPIResponse;
|
|
1520
|
+
}
|
|
1521
|
+
/**
|
|
1522
|
+
* Type definitions
|
|
1523
|
+
*/
|
|
1524
|
+
interface OpenAPISchemaObject {
|
|
1525
|
+
type: string;
|
|
1526
|
+
properties?: Record<string, any>;
|
|
1527
|
+
required?: string[];
|
|
1528
|
+
items?: any;
|
|
1529
|
+
format?: string;
|
|
1530
|
+
pattern?: string;
|
|
1531
|
+
minimum?: number;
|
|
1532
|
+
maximum?: number;
|
|
1533
|
+
exclusiveMinimum?: boolean;
|
|
1534
|
+
exclusiveMaximum?: boolean;
|
|
1535
|
+
minLength?: number;
|
|
1536
|
+
maxLength?: number;
|
|
1537
|
+
minItems?: number;
|
|
1538
|
+
maxItems?: number;
|
|
1539
|
+
}
|
|
1540
|
+
interface OpenAPISpecOptions {
|
|
1541
|
+
title: string;
|
|
1542
|
+
version: string;
|
|
1543
|
+
description?: string;
|
|
1544
|
+
schemaName?: string;
|
|
1545
|
+
servers?: string[];
|
|
1546
|
+
paths?: Record<string, any>;
|
|
1547
|
+
}
|
|
1548
|
+
interface OpenAPISpecification {
|
|
1549
|
+
openapi: string;
|
|
1550
|
+
info: {
|
|
1551
|
+
title: string;
|
|
1552
|
+
version: string;
|
|
1553
|
+
description?: string;
|
|
1554
|
+
};
|
|
1555
|
+
servers?: Array<{
|
|
1556
|
+
url: string;
|
|
1557
|
+
}>;
|
|
1558
|
+
components: {
|
|
1559
|
+
schemas: Record<string, OpenAPISchemaObject>;
|
|
1560
|
+
};
|
|
1561
|
+
paths: Record<string, any>;
|
|
1562
|
+
}
|
|
1563
|
+
interface OpenAPIReference {
|
|
1564
|
+
$ref: string;
|
|
1565
|
+
}
|
|
1566
|
+
interface RequestBodyOptions {
|
|
1567
|
+
description?: string;
|
|
1568
|
+
required?: boolean;
|
|
1569
|
+
examples?: Record<string, any>;
|
|
1570
|
+
}
|
|
1571
|
+
interface OpenAPIRequestBody {
|
|
1572
|
+
description: string;
|
|
1573
|
+
required: boolean;
|
|
1574
|
+
content: Record<string, {
|
|
1575
|
+
schema: OpenAPISchemaObject;
|
|
1576
|
+
examples?: Record<string, any>;
|
|
1577
|
+
}>;
|
|
1578
|
+
}
|
|
1579
|
+
interface ResponseOptions {
|
|
1580
|
+
description?: string;
|
|
1581
|
+
examples?: Record<string, any>;
|
|
1582
|
+
headers?: Record<string, any>;
|
|
1583
|
+
}
|
|
1584
|
+
interface OpenAPIResponse {
|
|
1585
|
+
description: string;
|
|
1586
|
+
content: Record<string, {
|
|
1587
|
+
schema: OpenAPISchemaObject;
|
|
1588
|
+
examples?: Record<string, any>;
|
|
1589
|
+
}>;
|
|
1590
|
+
headers?: Record<string, any>;
|
|
1591
|
+
}
|
|
1592
|
+
|
|
1593
|
+
/**
|
|
1594
|
+
* TypeScript Generator - Generate TypeScript type definitions from schemas
|
|
1595
|
+
*
|
|
1596
|
+
* This module provides utilities to convert ReliantType definitions
|
|
1597
|
+
* to TypeScript type definitions and interfaces.
|
|
1598
|
+
*/
|
|
1599
|
+
|
|
1600
|
+
/**
|
|
1601
|
+
* TypeScript code generator for schema definitions
|
|
1602
|
+
*/
|
|
1603
|
+
declare class TypeScriptGenerator$1 {
|
|
1604
|
+
/**
|
|
1605
|
+
* Generate TypeScript interface from schema
|
|
1606
|
+
*/
|
|
1607
|
+
static generateInterface(schema: SchemaInterface, options?: TypeScriptOptions): string;
|
|
1608
|
+
/**
|
|
1609
|
+
* Extract field definitions from schema object
|
|
1610
|
+
*/
|
|
1611
|
+
private static extractFieldDefinitions;
|
|
1612
|
+
/**
|
|
1613
|
+
* Generate interface definition
|
|
1614
|
+
*/
|
|
1615
|
+
private static generateInterfaceDefinition;
|
|
1616
|
+
/**
|
|
1617
|
+
* Generate type alias definition
|
|
1618
|
+
*/
|
|
1619
|
+
private static generateTypeDefinition;
|
|
1620
|
+
/**
|
|
1621
|
+
* Convert schema field to TypeScript type
|
|
1622
|
+
*/
|
|
1623
|
+
private static convertToTypeScript;
|
|
1624
|
+
/**
|
|
1625
|
+
* Convert string-based field to TypeScript type
|
|
1626
|
+
*/
|
|
1627
|
+
private static convertStringToTypeScript;
|
|
1628
|
+
/**
|
|
1629
|
+
* Convert object to TypeScript type
|
|
1630
|
+
*/
|
|
1631
|
+
private static convertObjectToTypeScript;
|
|
1632
|
+
/**
|
|
1633
|
+
* Check if field is optional
|
|
1634
|
+
*/
|
|
1635
|
+
private static isOptionalField;
|
|
1636
|
+
/**
|
|
1637
|
+
* Generate utility types for schema
|
|
1638
|
+
*/
|
|
1639
|
+
static generateUtilityTypes(schema: SchemaInterface, baseName: string): string;
|
|
1640
|
+
/**
|
|
1641
|
+
* Generate validation function types
|
|
1642
|
+
*/
|
|
1643
|
+
static generateValidationTypes(baseName: string): string;
|
|
1644
|
+
/**
|
|
1645
|
+
* Generate complete TypeScript module
|
|
1646
|
+
*/
|
|
1647
|
+
static generateModule(schema: SchemaInterface, options: ModuleOptions): string;
|
|
1648
|
+
/**
|
|
1649
|
+
* Generate JSDoc comments for schema fields
|
|
1650
|
+
*/
|
|
1651
|
+
static generateJSDoc(schema: SchemaInterface): Record<string, string>;
|
|
1652
|
+
/**
|
|
1653
|
+
* Generate JSDoc for a single field
|
|
1654
|
+
*/
|
|
1655
|
+
private static generateFieldJSDoc;
|
|
1656
|
+
}
|
|
1657
|
+
/**
|
|
1658
|
+
* Type definitions
|
|
1659
|
+
*/
|
|
1660
|
+
interface TypeScriptOptions {
|
|
1661
|
+
exportName?: string;
|
|
1662
|
+
namespace?: string;
|
|
1663
|
+
exportType?: "interface" | "type";
|
|
1664
|
+
}
|
|
1665
|
+
interface ModuleOptions {
|
|
1666
|
+
moduleName?: string;
|
|
1667
|
+
exportName?: string;
|
|
1668
|
+
includeUtilities?: boolean;
|
|
1669
|
+
includeValidation?: boolean;
|
|
1670
|
+
header?: string;
|
|
1671
|
+
}
|
|
1672
|
+
|
|
1673
|
+
/**
|
|
1674
|
+
* Validation Engine - Core validation logic for schema extensions
|
|
1675
|
+
*
|
|
1676
|
+
* This module provides the core validation engine that powers all schema extensions.
|
|
1677
|
+
* It acts as a bridge between extensions and the main validation system, delegating
|
|
1678
|
+
* actual validation to the TypeValidators module to avoid duplication.
|
|
1679
|
+
*/
|
|
1680
|
+
|
|
1681
|
+
/**
|
|
1682
|
+
* Core validation engine for schema validation
|
|
1683
|
+
*/
|
|
1684
|
+
declare class ValidationEngine {
|
|
1685
|
+
/**
|
|
1686
|
+
* Validate a value against a schema field definition
|
|
1687
|
+
* Delegates to TypeValidators for actual validation logic
|
|
1688
|
+
*/
|
|
1689
|
+
static validateField(fieldSchema: any, value: any): ValidationFieldResult;
|
|
1690
|
+
/**
|
|
1691
|
+
* Validate against string-based schema definitions
|
|
1692
|
+
* Uses TypeValidators for consistent validation logic
|
|
1693
|
+
*/
|
|
1694
|
+
private static validateStringSchema;
|
|
1695
|
+
/**
|
|
1696
|
+
* Validate against object schema definitions
|
|
1697
|
+
*/
|
|
1698
|
+
private static validateObjectSchema;
|
|
1699
|
+
/**
|
|
1700
|
+
* Validate entire object against schema
|
|
1701
|
+
*/
|
|
1702
|
+
static validateObject(schema: SchemaInterface, data: any): ValidationResult$1;
|
|
1703
|
+
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Type definitions
|
|
1706
|
+
*/
|
|
1707
|
+
interface ValidationFieldResult {
|
|
1708
|
+
isValid: boolean;
|
|
1709
|
+
errors: string[];
|
|
1710
|
+
}
|
|
1711
|
+
interface ValidationResult$1 {
|
|
1712
|
+
isValid: boolean;
|
|
1713
|
+
data: any;
|
|
1714
|
+
errors: Record<string, string[]>;
|
|
1715
|
+
timestamp: Date;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
/**
|
|
1719
|
+
* Type definitions
|
|
1720
|
+
*/
|
|
1721
|
+
interface DocumentationOptions {
|
|
1722
|
+
title?: string;
|
|
1723
|
+
description?: string;
|
|
1724
|
+
examples?: boolean;
|
|
1725
|
+
interactive?: boolean;
|
|
1726
|
+
}
|
|
1727
|
+
interface InteractiveOptions {
|
|
1728
|
+
title?: string;
|
|
1729
|
+
theme?: "light" | "dark";
|
|
1730
|
+
showExamples?: boolean;
|
|
1731
|
+
allowTesting?: boolean;
|
|
1732
|
+
}
|
|
1733
|
+
interface Documentation {
|
|
1734
|
+
markdown: string;
|
|
1735
|
+
html: string;
|
|
1736
|
+
openapi: OpenAPISpec;
|
|
1737
|
+
json: any;
|
|
1738
|
+
examples: any[];
|
|
1739
|
+
}
|
|
1740
|
+
interface InteractiveDocumentation {
|
|
1741
|
+
html: string;
|
|
1742
|
+
css: string;
|
|
1743
|
+
javascript: string;
|
|
1744
|
+
}
|
|
1745
|
+
interface OpenAPISpec {
|
|
1746
|
+
openapi: string;
|
|
1747
|
+
info: {
|
|
1748
|
+
title: string;
|
|
1749
|
+
version: string;
|
|
1750
|
+
};
|
|
1751
|
+
servers?: Array<{
|
|
1752
|
+
url: string;
|
|
1753
|
+
}>;
|
|
1754
|
+
components: {
|
|
1755
|
+
schemas: Record<string, any>;
|
|
1756
|
+
};
|
|
1757
|
+
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Type definitions
|
|
1760
|
+
*/
|
|
1761
|
+
interface ValidationResult {
|
|
1762
|
+
isValid: boolean;
|
|
1763
|
+
data: any;
|
|
1764
|
+
errors: Record<string, string[]>;
|
|
1765
|
+
timestamp: Date;
|
|
1766
|
+
}
|
|
1767
|
+
interface FieldValidationResult {
|
|
1768
|
+
field: string;
|
|
1769
|
+
value: any;
|
|
1770
|
+
isValid: boolean;
|
|
1771
|
+
errors: string[];
|
|
1772
|
+
}
|
|
1773
|
+
interface ValidationStats {
|
|
1774
|
+
totalValidated: number;
|
|
1775
|
+
validCount: number;
|
|
1776
|
+
invalidCount: number;
|
|
1777
|
+
errorRate: number;
|
|
1778
|
+
startTime: Date;
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
type InferFieldType<T extends string> = T extends "string" ? string : T extends "string?" ? string | undefined : T extends "number" ? number : T extends "number?" ? number | undefined : T extends "boolean" ? boolean : T extends "boolean?" ? boolean | undefined : T extends "string[]" ? string[] : T extends "string[]?" ? string[] | undefined : T extends "number[]" ? number[] : T extends "number[]?" ? number[] | undefined : T extends "boolean[]" ? boolean[] : T extends "boolean[]?" ? boolean[] | undefined : T extends `${string}|${string}` ? string : any;
|
|
1782
|
+
type ConditionalResult<TThen extends string, TElse extends string> = {
|
|
1783
|
+
__conditional: true;
|
|
1784
|
+
__inferredType: InferFieldType<TThen> | InferFieldType<TElse>;
|
|
1785
|
+
};
|
|
1786
|
+
/**
|
|
1787
|
+
* Builder for the "else" part of conditional validation with TypeScript inference
|
|
1788
|
+
* This class is returned after calling .then() and provides the .else() method
|
|
1789
|
+
*/
|
|
1790
|
+
declare class ConditionalElse<TThen extends string = string> {
|
|
1791
|
+
private builder;
|
|
1792
|
+
private condition;
|
|
1793
|
+
private thenSchema;
|
|
1794
|
+
constructor(builder: ConditionalBuilder, condition: (value: any) => boolean, thenSchema: TThen);
|
|
1795
|
+
/**
|
|
1796
|
+
* Specify the schema to use when the condition is false
|
|
1797
|
+
*/
|
|
1798
|
+
else<TElse extends string>(elseSchema: TElse): ConditionalResult<TThen, TElse>;
|
|
1799
|
+
/**
|
|
1800
|
+
* Alias for else() - for backward compatibility
|
|
1801
|
+
*/
|
|
1802
|
+
default<TElse extends string>(defaultSchema: TElse): ConditionalResult<TThen, TElse>;
|
|
1803
|
+
/**
|
|
1804
|
+
* Build without else clause (same as calling .else(undefined))
|
|
1805
|
+
*/
|
|
1806
|
+
build(): any;
|
|
1807
|
+
}
|
|
1808
|
+
|
|
1809
|
+
/**
|
|
1810
|
+
* Builder for the "then" part of conditional validation with TypeScript inference
|
|
1811
|
+
*/
|
|
1812
|
+
declare class ConditionalThen {
|
|
1813
|
+
private builder;
|
|
1814
|
+
private condition;
|
|
1815
|
+
constructor(builder: ConditionalBuilder, condition: (value: any) => boolean);
|
|
1816
|
+
then<T extends string>(schema: T): ConditionalElse<T>;
|
|
1817
|
+
}
|
|
1818
|
+
|
|
1819
|
+
/**
|
|
1820
|
+
* Builder for single field conditional validation with TypeScript inference
|
|
1821
|
+
*/
|
|
1822
|
+
declare class ConditionalBuilder {
|
|
1823
|
+
private fieldName;
|
|
1824
|
+
private conditions;
|
|
1825
|
+
private defaultSchema;
|
|
1826
|
+
constructor(fieldName: string);
|
|
1827
|
+
/**
|
|
1828
|
+
* Check if field equals specific value
|
|
1829
|
+
*/
|
|
1830
|
+
is(value: any): ConditionalThen;
|
|
1831
|
+
/**
|
|
1832
|
+
* Check if field does not equal specific value
|
|
1833
|
+
*/
|
|
1834
|
+
isNot(value: any): ConditionalThen;
|
|
1835
|
+
/**
|
|
1836
|
+
* Check if field exists (not null/undefined)
|
|
1837
|
+
*/
|
|
1838
|
+
exists(): ConditionalThen;
|
|
1839
|
+
/**
|
|
1840
|
+
* Check if field matches pattern
|
|
1841
|
+
*/
|
|
1842
|
+
matches(pattern: RegExp): ConditionalThen;
|
|
1843
|
+
/**
|
|
1844
|
+
* Check if field is in array of values
|
|
1845
|
+
*/
|
|
1846
|
+
in(values: any[]): ConditionalThen;
|
|
1847
|
+
/**
|
|
1848
|
+
* Custom condition function
|
|
1849
|
+
*/
|
|
1850
|
+
when(condition: (value: any) => boolean): ConditionalThen;
|
|
1851
|
+
addCondition(condition: (value: any) => boolean, schema: any): this;
|
|
1852
|
+
default(schema: any): any;
|
|
1853
|
+
build(): any;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
/**
|
|
1857
|
+
* Builder for multi-field "then" part
|
|
1858
|
+
*/
|
|
1859
|
+
declare class MultiConditionalThen {
|
|
1860
|
+
private builder;
|
|
1861
|
+
private conditions;
|
|
1862
|
+
constructor(builder: MultiConditionalBuilder, conditions: Record<string, any>);
|
|
1863
|
+
then(schema: any): MultiConditionalElse;
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Builder for multi-field "else" part
|
|
1867
|
+
*/
|
|
1868
|
+
declare class MultiConditionalElse {
|
|
1869
|
+
private thenSchema;
|
|
1870
|
+
private elseSchema;
|
|
1871
|
+
constructor(thenSchema: any, elseSchema: any);
|
|
1872
|
+
else(schema: any): any;
|
|
1873
|
+
}
|
|
1874
|
+
/**
|
|
1875
|
+
* Custom validator builder
|
|
1876
|
+
*/
|
|
1877
|
+
declare class CustomValidator {
|
|
1878
|
+
private validator;
|
|
1879
|
+
constructor(validator: (data: any) => {
|
|
1880
|
+
valid: true;
|
|
1881
|
+
} | {
|
|
1882
|
+
error: string;
|
|
1883
|
+
});
|
|
1884
|
+
build(): any;
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
/**
|
|
1888
|
+
* Builder for multi-field conditional validation
|
|
1889
|
+
*/
|
|
1890
|
+
declare class MultiConditionalBuilder {
|
|
1891
|
+
private fieldNames;
|
|
1892
|
+
private matchConditions;
|
|
1893
|
+
constructor(fieldNames: string[]);
|
|
1894
|
+
match(conditions: Record<string, any>): MultiConditionalThen;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
/**
|
|
1898
|
+
* Conditional Validation - dependent field validation
|
|
1899
|
+
*
|
|
1900
|
+
* This module provides powerful conditional validation where fields can depend
|
|
1901
|
+
* on other fields' values, making complex business logic validation simple.
|
|
1902
|
+
*/
|
|
1903
|
+
|
|
1904
|
+
/**
|
|
1905
|
+
* Conditional validation utilities
|
|
1906
|
+
*/
|
|
1907
|
+
declare const When: {
|
|
1908
|
+
/**
|
|
1909
|
+
* Create conditional validation based on another field's value
|
|
1910
|
+
*
|
|
1911
|
+
* @example
|
|
1912
|
+
* ```typescript
|
|
1913
|
+
* const UserSchema = Interface({
|
|
1914
|
+
* accountType: Make.union("free", "premium", "enterprise"),
|
|
1915
|
+
* maxProjects: When.field("accountType").is("free").then("int(1,3)")
|
|
1916
|
+
* .is("premium").then("int(1,50)")
|
|
1917
|
+
* .is("enterprise").then("int(1,)")
|
|
1918
|
+
* .default("int(1,1)"),
|
|
1919
|
+
*
|
|
1920
|
+
* paymentMethod: When.field("accountType").isNot("free").then("string").else("string?"),
|
|
1921
|
+
* billingAddress: When.field("paymentMethod").exists().then({
|
|
1922
|
+
* street: "string",
|
|
1923
|
+
* city: "string",
|
|
1924
|
+
* country: "string(2,2)"
|
|
1925
|
+
* }).else("any?")
|
|
1926
|
+
* });
|
|
1927
|
+
* ```
|
|
1928
|
+
*/
|
|
1929
|
+
field(fieldName: string): ConditionalBuilder;
|
|
1930
|
+
/**
|
|
1931
|
+
* Create validation that depends on multiple fields
|
|
1932
|
+
*
|
|
1933
|
+
* @example
|
|
1934
|
+
* ```typescript
|
|
1935
|
+
* const OrderSchema = Interface({
|
|
1936
|
+
* orderType: Make.union("pickup", "delivery"),
|
|
1937
|
+
* address: "string?",
|
|
1938
|
+
* deliveryFee: "number?",
|
|
1939
|
+
*
|
|
1940
|
+
* // Complex conditional validation
|
|
1941
|
+
* ...When.fields(["orderType", "address"]).match({
|
|
1942
|
+
* orderType: "delivery",
|
|
1943
|
+
* address: (val) => val && val.length > 0
|
|
1944
|
+
* }).then({
|
|
1945
|
+
* deliveryFee: "number(0,)" // Required for delivery with address
|
|
1946
|
+
* }).else({
|
|
1947
|
+
* deliveryFee: "number?" // Optional otherwise
|
|
1948
|
+
* })
|
|
1949
|
+
* });
|
|
1950
|
+
* ```
|
|
1951
|
+
*/
|
|
1952
|
+
fields(fieldNames: string[]): MultiConditionalBuilder;
|
|
1953
|
+
/**
|
|
1954
|
+
* Create custom validation logic
|
|
1955
|
+
*
|
|
1956
|
+
* @example
|
|
1957
|
+
* ```typescript
|
|
1958
|
+
* const EventSchema = Interface({
|
|
1959
|
+
* startDate: "date",
|
|
1960
|
+
* endDate: "date",
|
|
1961
|
+
*
|
|
1962
|
+
* // Custom validation: endDate must be after startDate
|
|
1963
|
+
* ...When.custom((data) => {
|
|
1964
|
+
* if (data.endDate <= data.startDate) {
|
|
1965
|
+
* return { error: "End date must be after start date" };
|
|
1966
|
+
* }
|
|
1967
|
+
* return { valid: true };
|
|
1968
|
+
* })
|
|
1969
|
+
* });
|
|
1970
|
+
* ```
|
|
1971
|
+
*/
|
|
1972
|
+
custom(validator: (data: any) => {
|
|
1973
|
+
valid: true;
|
|
1974
|
+
} | {
|
|
1975
|
+
error: string;
|
|
1976
|
+
}): CustomValidator;
|
|
1977
|
+
};
|
|
1978
|
+
|
|
1979
|
+
/**
|
|
1980
|
+
* Smart Schema Inference - TypeScript type-to-schema conversion
|
|
1981
|
+
*
|
|
1982
|
+
* This module provides automatic schema generation from TypeScript types,
|
|
1983
|
+
* making schema definition even more seamless.
|
|
1984
|
+
*/
|
|
1985
|
+
|
|
1986
|
+
/**
|
|
1987
|
+
* Smart inference utilities for automatic schema generation
|
|
1988
|
+
*/
|
|
1989
|
+
declare const Smart: {
|
|
1990
|
+
/**
|
|
1991
|
+
* Infer schema from TypeScript interface using runtime reflection
|
|
1992
|
+
*
|
|
1993
|
+
* @example
|
|
1994
|
+
* ```typescript
|
|
1995
|
+
* interface User {
|
|
1996
|
+
* id: number;
|
|
1997
|
+
* email: string;
|
|
1998
|
+
* name?: string;
|
|
1999
|
+
* }
|
|
2000
|
+
*
|
|
2001
|
+
* // Use with sample data that matches your interface
|
|
2002
|
+
* const UserSchema = Smart.fromType<User>({
|
|
2003
|
+
* id: 1,
|
|
2004
|
+
* email: "user@example.com",
|
|
2005
|
+
* name: "John Doe"
|
|
2006
|
+
* });
|
|
2007
|
+
* // Generates: Interface({ id: "positive", email: "email", name: "string?" })
|
|
2008
|
+
* ```
|
|
2009
|
+
*/
|
|
2010
|
+
fromType<T>(sampleData: T): SchemaInterface;
|
|
2011
|
+
/**
|
|
2012
|
+
* Infer schema from sample data with intelligent type detection
|
|
2013
|
+
*
|
|
2014
|
+
* @example
|
|
2015
|
+
* ```typescript
|
|
2016
|
+
* const sampleUser = {
|
|
2017
|
+
* id: 1,
|
|
2018
|
+
* email: "user@example.com",
|
|
2019
|
+
* name: "John Doe",
|
|
2020
|
+
* tags: ["developer", "typescript"]
|
|
2021
|
+
* };
|
|
2022
|
+
*
|
|
2023
|
+
* const UserSchema = Smart.fromSample(sampleUser);
|
|
2024
|
+
* // Generates: Interface({ id: "positive", email: "email", name: "string", tags: "string[]" })
|
|
2025
|
+
* ```
|
|
2026
|
+
*/
|
|
2027
|
+
fromSample(sample: any): SchemaInterface;
|
|
2028
|
+
/**
|
|
2029
|
+
* Infer field type from value with smart detection
|
|
2030
|
+
*/
|
|
2031
|
+
inferFieldType(value: any): string;
|
|
2032
|
+
/**
|
|
2033
|
+
* Smart format detection utilities
|
|
2034
|
+
*/
|
|
2035
|
+
isEmail(str: string): boolean;
|
|
2036
|
+
isUrl(str: string): boolean;
|
|
2037
|
+
isUuid(str: string): boolean;
|
|
2038
|
+
isPhone(str: string): boolean;
|
|
2039
|
+
/**
|
|
2040
|
+
* Generate schema from JSON Schema (migration helper)
|
|
2041
|
+
*
|
|
2042
|
+
* @example
|
|
2043
|
+
* ```typescript
|
|
2044
|
+
* const jsonSchema = {
|
|
2045
|
+
* type: "object",
|
|
2046
|
+
* properties: {
|
|
2047
|
+
* id: { type: "number" },
|
|
2048
|
+
* email: { type: "string", format: "email" }
|
|
2049
|
+
* }
|
|
2050
|
+
* };
|
|
2051
|
+
*
|
|
2052
|
+
* const schema = Smart.fromJsonSchema(jsonSchema);
|
|
2053
|
+
* ```
|
|
2054
|
+
*/
|
|
2055
|
+
fromJsonSchema(jsonSchema: any): SchemaInterface;
|
|
2056
|
+
convertJsonSchemaProperty(prop: any): string;
|
|
2057
|
+
};
|
|
2058
|
+
|
|
2059
|
+
/**
|
|
2060
|
+
* Live validator for real-time validation
|
|
2061
|
+
*/
|
|
2062
|
+
declare class LiveValidator {
|
|
2063
|
+
private schema;
|
|
2064
|
+
private currentData;
|
|
2065
|
+
private currentErrors;
|
|
2066
|
+
private listeners;
|
|
2067
|
+
private fieldListeners;
|
|
2068
|
+
constructor(schema: SchemaInterface);
|
|
2069
|
+
/**
|
|
2070
|
+
* Validate a single field in real-time
|
|
2071
|
+
*/
|
|
2072
|
+
validateField(fieldName: string, value: any): FieldValidationResult;
|
|
2073
|
+
/**
|
|
2074
|
+
* Validate all current data
|
|
2075
|
+
*/
|
|
2076
|
+
validateAll(): ValidationResult;
|
|
2077
|
+
/**
|
|
2078
|
+
* Listen for validation changes
|
|
2079
|
+
*/
|
|
2080
|
+
onValidation(listener: (result: ValidationResult) => void): void;
|
|
2081
|
+
/**
|
|
2082
|
+
* Listen for specific field validation
|
|
2083
|
+
*/
|
|
2084
|
+
onFieldValidation(fieldName: string, listener: (result: FieldValidationResult) => void): void;
|
|
2085
|
+
/**
|
|
2086
|
+
* Get current validation state
|
|
2087
|
+
*/
|
|
2088
|
+
get isValid(): boolean;
|
|
2089
|
+
get errors(): Record<string, string[]>;
|
|
2090
|
+
get data(): any;
|
|
2091
|
+
private notifyListeners;
|
|
2092
|
+
}
|
|
2093
|
+
|
|
2094
|
+
/**
|
|
2095
|
+
* Form validator with DOM integration
|
|
2096
|
+
*/
|
|
2097
|
+
declare class FormValidator extends LiveValidator {
|
|
2098
|
+
private boundFields;
|
|
2099
|
+
private autoValidationEnabled;
|
|
2100
|
+
private submitListeners;
|
|
2101
|
+
/**
|
|
2102
|
+
* Bind a form field for automatic validation (Node.js compatible)
|
|
2103
|
+
*/
|
|
2104
|
+
bindField(fieldName: string, element: any): void;
|
|
2105
|
+
/**
|
|
2106
|
+
* Enable automatic validation on input changes (Node.js compatible)
|
|
2107
|
+
*/
|
|
2108
|
+
enableAutoValidation(): void;
|
|
2109
|
+
/**
|
|
2110
|
+
* Listen for form submission
|
|
2111
|
+
*/
|
|
2112
|
+
onSubmit(listener: (isValid: boolean, data: any, errors: Record<string, string[]>) => void): void;
|
|
2113
|
+
/**
|
|
2114
|
+
* Trigger form validation (typically on submit)
|
|
2115
|
+
*/
|
|
2116
|
+
submit(): void;
|
|
2117
|
+
private setupFieldListeners;
|
|
2118
|
+
}
|
|
2119
|
+
|
|
2120
|
+
/**
|
|
2121
|
+
* Enhanced Stream Validator with full EventEmitter-like interface
|
|
2122
|
+
* Supports all standard stream methods (.on, .emit, .pipe, etc.)
|
|
2123
|
+
* Synchronized with InterfaceSchema modules
|
|
2124
|
+
*/
|
|
2125
|
+
declare class StreamValidator {
|
|
2126
|
+
private schema;
|
|
2127
|
+
private validListeners;
|
|
2128
|
+
private invalidListeners;
|
|
2129
|
+
private statsListeners;
|
|
2130
|
+
private eventListeners;
|
|
2131
|
+
private onceListeners;
|
|
2132
|
+
private isPaused;
|
|
2133
|
+
private isDestroyed;
|
|
2134
|
+
private dataQueue;
|
|
2135
|
+
private transformers;
|
|
2136
|
+
private filters;
|
|
2137
|
+
private mappers;
|
|
2138
|
+
private stats;
|
|
2139
|
+
constructor(schema: SchemaInterface);
|
|
2140
|
+
/**
|
|
2141
|
+
* Generic event listener (EventEmitter-like interface)
|
|
2142
|
+
*/
|
|
2143
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
2144
|
+
/**
|
|
2145
|
+
* One-time event listener
|
|
2146
|
+
*/
|
|
2147
|
+
once(event: string, listener: (...args: any[]) => void): this;
|
|
2148
|
+
/**
|
|
2149
|
+
* Remove event listener
|
|
2150
|
+
*/
|
|
2151
|
+
off(event: string, listener?: (...args: any[]) => void): this;
|
|
2152
|
+
/**
|
|
2153
|
+
* Emit event to all listeners
|
|
2154
|
+
*/
|
|
2155
|
+
emit(event: string, ...args: any[]): boolean;
|
|
2156
|
+
/**
|
|
2157
|
+
* Enhanced validate method with stream control and InterfaceSchema sync
|
|
2158
|
+
*/
|
|
2159
|
+
validate(data: any): void;
|
|
2160
|
+
private _processData;
|
|
2161
|
+
private _formatErrors;
|
|
2162
|
+
private _applyTransformations;
|
|
2163
|
+
private _passesFilters;
|
|
2164
|
+
/**
|
|
2165
|
+
* Listen for valid data
|
|
2166
|
+
*/
|
|
2167
|
+
onValid(listener: (data: any) => void): void;
|
|
2168
|
+
/**
|
|
2169
|
+
* Listen for invalid data
|
|
2170
|
+
*/
|
|
2171
|
+
onInvalid(listener: (data: any, errors: Record<string, string[]>) => void): void;
|
|
2172
|
+
/**
|
|
2173
|
+
* Listen for validation statistics
|
|
2174
|
+
*/
|
|
2175
|
+
onStats(listener: (stats: ValidationStats) => void): void;
|
|
2176
|
+
/**
|
|
2177
|
+
* Get current validation statistics
|
|
2178
|
+
*/
|
|
2179
|
+
getStats(): ValidationStats;
|
|
2180
|
+
private updateStats;
|
|
2181
|
+
/**
|
|
2182
|
+
* Add data transformer to pipeline
|
|
2183
|
+
*/
|
|
2184
|
+
transform(transformer: (data: any) => any): this;
|
|
2185
|
+
/**
|
|
2186
|
+
* Add data filter to pipeline
|
|
2187
|
+
*/
|
|
2188
|
+
filter(predicate: (data: any) => boolean): this;
|
|
2189
|
+
/**
|
|
2190
|
+
* Add data mapper to pipeline
|
|
2191
|
+
*/
|
|
2192
|
+
map(mapper: (data: any) => any): this;
|
|
2193
|
+
/**
|
|
2194
|
+
* Pipe data to another stream validator
|
|
2195
|
+
*/
|
|
2196
|
+
pipe(destination: StreamValidator): StreamValidator;
|
|
2197
|
+
/**
|
|
2198
|
+
* Pause the stream (queue incoming data)
|
|
2199
|
+
*/
|
|
2200
|
+
pause(): this;
|
|
2201
|
+
/**
|
|
2202
|
+
* Resume the stream (process queued data)
|
|
2203
|
+
*/
|
|
2204
|
+
resume(): this;
|
|
2205
|
+
/**
|
|
2206
|
+
* Destroy the stream (cleanup and prevent further use)
|
|
2207
|
+
*/
|
|
2208
|
+
destroy(): this;
|
|
2209
|
+
/**
|
|
2210
|
+
* Check if stream is destroyed
|
|
2211
|
+
*/
|
|
2212
|
+
get destroyed(): boolean;
|
|
2213
|
+
/**
|
|
2214
|
+
* Check if stream is paused
|
|
2215
|
+
*/
|
|
2216
|
+
get paused(): boolean;
|
|
2217
|
+
/**
|
|
2218
|
+
* Get queue length
|
|
2219
|
+
*/
|
|
2220
|
+
get queueLength(): number;
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
/**
|
|
2224
|
+
* Real-time Validation - live validation system
|
|
2225
|
+
*
|
|
2226
|
+
* This module provides real-time validation with reactive updates,
|
|
2227
|
+
* perfect for forms and live data validation.
|
|
2228
|
+
*
|
|
2229
|
+
* Uses modular validation engine for consistent validation logic.
|
|
2230
|
+
*/
|
|
2231
|
+
|
|
2232
|
+
/**
|
|
2233
|
+
* Real-time validation utilities
|
|
2234
|
+
*/
|
|
2235
|
+
declare const Live: {
|
|
2236
|
+
/**
|
|
2237
|
+
* Create a reactive validator that validates in real-time
|
|
2238
|
+
*
|
|
2239
|
+
* @example
|
|
2240
|
+
* ```typescript
|
|
2241
|
+
* const UserSchema = Interface({
|
|
2242
|
+
* email: "email",
|
|
2243
|
+
* username: "string(3,20)",
|
|
2244
|
+
* password: "string(8,)"
|
|
2245
|
+
* });
|
|
2246
|
+
*
|
|
2247
|
+
* const liveValidator = Live.validator(UserSchema);
|
|
2248
|
+
*
|
|
2249
|
+
* // Listen for validation changes
|
|
2250
|
+
* liveValidator.onValidation((result) => {
|
|
2251
|
+
* console.log('Validation result:', result);
|
|
2252
|
+
* updateUI(result);
|
|
2253
|
+
* });
|
|
2254
|
+
*
|
|
2255
|
+
* // Validate field by field
|
|
2256
|
+
* liveValidator.validateField('email', 'user@example.com');
|
|
2257
|
+
* liveValidator.validateField('username', 'johndoe');
|
|
2258
|
+
*
|
|
2259
|
+
* // Get current state
|
|
2260
|
+
* console.log(liveValidator.isValid); // true/false
|
|
2261
|
+
* console.log(liveValidator.errors); // Current errors
|
|
2262
|
+
* ```
|
|
2263
|
+
*/
|
|
2264
|
+
validator(schema: SchemaInterface): LiveValidator;
|
|
2265
|
+
/**
|
|
2266
|
+
* Create a form validator with field-level validation
|
|
2267
|
+
*
|
|
2268
|
+
* @example
|
|
2269
|
+
* ```typescript
|
|
2270
|
+
* const formValidator = Live.form(UserSchema);
|
|
2271
|
+
*
|
|
2272
|
+
* // Bind to form fields
|
|
2273
|
+
* formValidator.bindField('email', emailInput);
|
|
2274
|
+
* formValidator.bindField('username', usernameInput);
|
|
2275
|
+
*
|
|
2276
|
+
* // Auto-validation on input
|
|
2277
|
+
* formValidator.enableAutoValidation();
|
|
2278
|
+
*
|
|
2279
|
+
* // Submit validation
|
|
2280
|
+
* formValidator.onSubmit((isValid, data, errors) => {
|
|
2281
|
+
* if (isValid) {
|
|
2282
|
+
* submitForm(data);
|
|
2283
|
+
* } else {
|
|
2284
|
+
* showErrors(errors);
|
|
2285
|
+
* }
|
|
2286
|
+
* });
|
|
2287
|
+
* ```
|
|
2288
|
+
*/
|
|
2289
|
+
form(schema: SchemaInterface): FormValidator;
|
|
2290
|
+
/**
|
|
2291
|
+
* Create a stream validator for continuous data validation
|
|
2292
|
+
*
|
|
2293
|
+
* @example
|
|
2294
|
+
* ```typescript
|
|
2295
|
+
* const streamValidator = Live.stream(DataSchema);
|
|
2296
|
+
*
|
|
2297
|
+
* // Validate streaming data
|
|
2298
|
+
* dataStream.subscribe((data) => {
|
|
2299
|
+
* streamValidator.validate(data);
|
|
2300
|
+
* });
|
|
2301
|
+
*
|
|
2302
|
+
* // Handle validation results
|
|
2303
|
+
* streamValidator.onValid((data) => {
|
|
2304
|
+
* processValidData(data);
|
|
2305
|
+
* });
|
|
2306
|
+
*
|
|
2307
|
+
* streamValidator.onInvalid((data, errors) => {
|
|
2308
|
+
* logInvalidData(data, errors);
|
|
2309
|
+
* });
|
|
2310
|
+
* ```
|
|
2311
|
+
*/
|
|
2312
|
+
stream(schema: SchemaInterface): StreamValidator;
|
|
2313
|
+
};
|
|
2314
|
+
|
|
2315
|
+
/**
|
|
2316
|
+
* Auto documentation utilities
|
|
2317
|
+
*/
|
|
2318
|
+
declare const Docs: {
|
|
2319
|
+
/**
|
|
2320
|
+
* Generate comprehensive documentation from schema
|
|
2321
|
+
*
|
|
2322
|
+
* @example
|
|
2323
|
+
* ```typescript
|
|
2324
|
+
* const UserSchema = Interface({
|
|
2325
|
+
* id: "uuid",
|
|
2326
|
+
* email: "email",
|
|
2327
|
+
* name: "string(2,50)",
|
|
2328
|
+
* age: "int(18,120)?",
|
|
2329
|
+
* role: Make.union("user", "admin", "moderator")
|
|
2330
|
+
* });
|
|
2331
|
+
*
|
|
2332
|
+
* const documentation = Docs.generate(UserSchema, {
|
|
2333
|
+
* title: "User API",
|
|
2334
|
+
* description: "User management endpoints",
|
|
2335
|
+
* examples: true,
|
|
2336
|
+
* interactive: true
|
|
2337
|
+
* });
|
|
2338
|
+
*
|
|
2339
|
+
* console.log(documentation.markdown);
|
|
2340
|
+
* console.log(documentation.html);
|
|
2341
|
+
* console.log(documentation.openapi);
|
|
2342
|
+
* ```
|
|
2343
|
+
*/
|
|
2344
|
+
generate(schema: SchemaInterface, options?: DocumentationOptions): Documentation;
|
|
2345
|
+
/**
|
|
2346
|
+
* Generate OpenAPI specification from schema
|
|
2347
|
+
*
|
|
2348
|
+
* @example
|
|
2349
|
+
* ```typescript
|
|
2350
|
+
* const openApiSpec = Docs.openapi(UserSchema, {
|
|
2351
|
+
* title: "User API",
|
|
2352
|
+
* version: "1.0.0",
|
|
2353
|
+
* servers: ["https://api.example.com"]
|
|
2354
|
+
* });
|
|
2355
|
+
* ```
|
|
2356
|
+
*/
|
|
2357
|
+
openapi(schema: SchemaInterface, options: OpenAPISpecOptions): OpenAPISpecification;
|
|
2358
|
+
/**
|
|
2359
|
+
* Generate TypeScript type definitions
|
|
2360
|
+
*
|
|
2361
|
+
* @example
|
|
2362
|
+
* ```typescript
|
|
2363
|
+
* const typeDefinitions = Docs.typescript(UserSchema, {
|
|
2364
|
+
* exportName: "User",
|
|
2365
|
+
* namespace: "API"
|
|
2366
|
+
* });
|
|
2367
|
+
*
|
|
2368
|
+
* // Generates:
|
|
2369
|
+
* // export interface User {
|
|
2370
|
+
* // id: string;
|
|
2371
|
+
* // email: string;
|
|
2372
|
+
* // name: string;
|
|
2373
|
+
* // age?: number;
|
|
2374
|
+
* // role: "user" | "admin" | "moderator";
|
|
2375
|
+
* // }
|
|
2376
|
+
* ```
|
|
2377
|
+
*/
|
|
2378
|
+
typescript(schema: SchemaInterface, options?: TypeScriptOptions): string;
|
|
2379
|
+
/**
|
|
2380
|
+
* Generate interactive documentation with live examples
|
|
2381
|
+
*
|
|
2382
|
+
* @example
|
|
2383
|
+
* ```typescript
|
|
2384
|
+
* const interactiveDocs = Docs.interactive(UserSchema, {
|
|
2385
|
+
* title: "User Schema Playground",
|
|
2386
|
+
* theme: "dark",
|
|
2387
|
+
* showExamples: true,
|
|
2388
|
+
* allowTesting: true
|
|
2389
|
+
* });
|
|
2390
|
+
*
|
|
2391
|
+
* document.body.innerHTML = interactiveDocs.html;
|
|
2392
|
+
* ```
|
|
2393
|
+
*/
|
|
2394
|
+
interactive(schema: SchemaInterface, options?: InteractiveOptions): InteractiveDocumentation;
|
|
2395
|
+
};
|
|
2396
|
+
|
|
2397
|
+
/**
|
|
2398
|
+
* TypeScript generator
|
|
2399
|
+
*/
|
|
2400
|
+
declare class TypeScriptGenerator {
|
|
2401
|
+
private schema;
|
|
2402
|
+
private options;
|
|
2403
|
+
constructor(schema: SchemaInterface, options: TypeScriptOptions);
|
|
2404
|
+
generate(): string;
|
|
2405
|
+
private convertToTypeScript;
|
|
2406
|
+
}
|
|
2407
|
+
|
|
2408
|
+
/**
|
|
2409
|
+
* Extensions Bundle
|
|
2410
|
+
*
|
|
2411
|
+
* All extensions in one convenient object for easy access
|
|
2412
|
+
*/
|
|
2413
|
+
declare const Extensions: {
|
|
2414
|
+
Smart: {
|
|
2415
|
+
fromSample: (sample: any) => SchemaInterface;
|
|
2416
|
+
fromJsonSchema: (jsonSchema: any) => SchemaInterface;
|
|
2417
|
+
fromType: <T>(sampleData: T) => SchemaInterface;
|
|
2418
|
+
};
|
|
2419
|
+
When: {
|
|
2420
|
+
field: (fieldName: string) => ConditionalBuilder;
|
|
2421
|
+
custom: (validator: (data: any) => {
|
|
2422
|
+
valid: true;
|
|
2423
|
+
} | {
|
|
2424
|
+
error: string;
|
|
2425
|
+
}) => CustomValidator;
|
|
2426
|
+
};
|
|
2427
|
+
Live: {
|
|
2428
|
+
validator: (schema: SchemaInterface) => LiveValidator;
|
|
2429
|
+
stream: (schema: SchemaInterface) => StreamValidator;
|
|
2430
|
+
};
|
|
2431
|
+
Docs: {
|
|
2432
|
+
generate: (schema: SchemaInterface, options?: DocumentationOptions) => Documentation;
|
|
2433
|
+
typescript: (schema: SchemaInterface, options?: TypeScriptOptions) => string;
|
|
2434
|
+
openapi: (schema: SchemaInterface, options: OpenAPISpecOptions) => OpenAPISpecification;
|
|
2435
|
+
};
|
|
2436
|
+
Utils: {
|
|
2437
|
+
ValidationEngine: typeof ValidationEngine;
|
|
2438
|
+
OpenAPIConverter: typeof OpenAPIConverter;
|
|
2439
|
+
TypeScriptGenerator: typeof TypeScriptGenerator$1;
|
|
2440
|
+
};
|
|
2441
|
+
};
|
|
2442
|
+
/**
|
|
2443
|
+
* Quick access to most commonly used extensions
|
|
2444
|
+
*/
|
|
2445
|
+
declare const Quick: {
|
|
2446
|
+
fromSample: (sample: any) => SchemaInterface;
|
|
2447
|
+
fromJsonSchema: (jsonSchema: any) => SchemaInterface;
|
|
2448
|
+
when: (fieldName: string) => ConditionalBuilder;
|
|
2449
|
+
live: (schema: SchemaInterface) => LiveValidator;
|
|
2450
|
+
stream: (schema: SchemaInterface) => StreamValidator;
|
|
2451
|
+
docs: (schema: SchemaInterface, options?: DocumentationOptions) => Documentation;
|
|
2452
|
+
typescript: (schema: SchemaInterface, options?: TypeScriptOptions) => string;
|
|
2453
|
+
openapi: (schema: SchemaInterface, options: OpenAPISpecOptions) => OpenAPISpecification;
|
|
2454
|
+
};
|
|
2455
|
+
|
|
2456
|
+
interface OptimizationRecommendation {
|
|
2457
|
+
type: 'cache' | 'precompile' | 'restructure' | 'hotpath' | 'memory';
|
|
2458
|
+
priority: 'low' | 'medium' | 'high' | 'critical';
|
|
2459
|
+
description: string;
|
|
2460
|
+
estimatedImprovement: number;
|
|
2461
|
+
implementation: () => Promise<void>;
|
|
2462
|
+
}
|
|
2463
|
+
interface PerformanceProfile {
|
|
2464
|
+
averageDuration: number;
|
|
2465
|
+
p95Duration: number;
|
|
2466
|
+
p99Duration: number;
|
|
2467
|
+
throughput: number;
|
|
2468
|
+
cacheHitRate: number;
|
|
2469
|
+
memoryUsage: number;
|
|
2470
|
+
bottlenecks: string[];
|
|
2471
|
+
recommendations: OptimizationRecommendation[];
|
|
2472
|
+
}
|
|
2473
|
+
interface PerformanceThresholds {
|
|
2474
|
+
slowOperationMs: number;
|
|
2475
|
+
criticalOperationMs: number;
|
|
2476
|
+
minCacheHitRate: number;
|
|
2477
|
+
maxMemoryMB: number;
|
|
2478
|
+
autoOptimizeThreshold: number;
|
|
2479
|
+
}
|
|
2480
|
+
|
|
2481
|
+
/**
|
|
2482
|
+
* Smart Performance Monitor & Auto-Optimizer
|
|
2483
|
+
*
|
|
2484
|
+
* Monitors validation performance in real-time and automatically
|
|
2485
|
+
* applies optimizations based on usage patterns and bottlenecks.
|
|
2486
|
+
*/
|
|
2487
|
+
|
|
2488
|
+
declare class PerformanceMonitor {
|
|
2489
|
+
private static metrics;
|
|
2490
|
+
private static readonly MAX_METRICS;
|
|
2491
|
+
private static readonly ANALYSIS_INTERVAL;
|
|
2492
|
+
private static readonly CLEANUP_INTERVAL;
|
|
2493
|
+
private static readonly thresholds;
|
|
2494
|
+
private static isMonitoring;
|
|
2495
|
+
private static analysisTimer?;
|
|
2496
|
+
private static cleanupTimer?;
|
|
2497
|
+
private static optimizationHistory;
|
|
2498
|
+
private static optimizationCallbacks;
|
|
2499
|
+
/**
|
|
2500
|
+
* Start performance monitoring
|
|
2501
|
+
*/
|
|
2502
|
+
static startMonitoring(customThresholds?: Partial<PerformanceThresholds>): void;
|
|
2503
|
+
/**
|
|
2504
|
+
* Stop performance monitoring
|
|
2505
|
+
*/
|
|
2506
|
+
static stopMonitoring(): void;
|
|
2507
|
+
/**
|
|
2508
|
+
* Register optimization callback
|
|
2509
|
+
*/
|
|
2510
|
+
static registerOptimization(type: string, callback: () => Promise<void>): void;
|
|
2511
|
+
/**
|
|
2512
|
+
* Record a validation operation
|
|
2513
|
+
*/
|
|
2514
|
+
static recordOperation(operationId: string, duration: number, schemaComplexity: number, cacheHit?: boolean, optimizationApplied?: string): void;
|
|
2515
|
+
/**
|
|
2516
|
+
* Analyze performance and generate recommendations
|
|
2517
|
+
*/
|
|
2518
|
+
static analyzePerformance(): PerformanceProfile;
|
|
2519
|
+
/**
|
|
2520
|
+
* Get performance report
|
|
2521
|
+
*/
|
|
2522
|
+
static getPerformanceReport(): {
|
|
2523
|
+
profile: PerformanceProfile;
|
|
2524
|
+
optimizationHistory: typeof PerformanceMonitor.optimizationHistory;
|
|
2525
|
+
totalMetrics: number;
|
|
2526
|
+
monitoringStatus: boolean;
|
|
2527
|
+
thresholds: PerformanceThresholds;
|
|
2528
|
+
};
|
|
2529
|
+
/**
|
|
2530
|
+
* Clear performance data
|
|
2531
|
+
*/
|
|
2532
|
+
static clearData(): void;
|
|
2533
|
+
/**
|
|
2534
|
+
* Private methods
|
|
2535
|
+
*/
|
|
2536
|
+
private static performAnalysis;
|
|
2537
|
+
private static calculatePerformanceProfile;
|
|
2538
|
+
private static identifyBottlenecks;
|
|
2539
|
+
private static generateRecommendations;
|
|
2540
|
+
private static autoApplyOptimizations;
|
|
2541
|
+
private static applyOptimization;
|
|
2542
|
+
private static executeOptimization;
|
|
2543
|
+
private static handleOperationResult;
|
|
2544
|
+
private static handleCriticalPerformance;
|
|
2545
|
+
private static optimizeCache;
|
|
2546
|
+
private static optimizeMemory;
|
|
2547
|
+
/**
|
|
2548
|
+
* Get current memory usage in MB
|
|
2549
|
+
*/
|
|
2550
|
+
private static getMemoryUsage;
|
|
2551
|
+
private static precompileSchemas;
|
|
2552
|
+
private static optimizeHotPaths;
|
|
2553
|
+
/**
|
|
2554
|
+
* Get schema definitions for operations from integrated schema registry
|
|
2555
|
+
*/
|
|
2556
|
+
private static getSchemaDefinitionsForOperations;
|
|
2557
|
+
/**
|
|
2558
|
+
* Get the global schema registry (integrates with existing Interface schemas)
|
|
2559
|
+
*/
|
|
2560
|
+
private static getSchemaRegistry;
|
|
2561
|
+
private static schemaRegistry;
|
|
2562
|
+
/**
|
|
2563
|
+
* Infer schema structure from historical validation metrics
|
|
2564
|
+
*/
|
|
2565
|
+
private static inferSchemaFromMetrics;
|
|
2566
|
+
/**
|
|
2567
|
+
* Generate schema based on operation ID patterns
|
|
2568
|
+
*/
|
|
2569
|
+
private static generateSchemaFromPattern;
|
|
2570
|
+
/**
|
|
2571
|
+
* Create optimized validator for hot path with real implementation
|
|
2572
|
+
*/
|
|
2573
|
+
private static createHotPathValidator;
|
|
2574
|
+
private static hotPathValidators;
|
|
2575
|
+
/**
|
|
2576
|
+
* Generate sample data for schema pre-warming
|
|
2577
|
+
*/
|
|
2578
|
+
private static generateSampleData;
|
|
2579
|
+
/**
|
|
2580
|
+
* Generate sample value for a field type
|
|
2581
|
+
*/
|
|
2582
|
+
private static generateSampleValue;
|
|
2583
|
+
/**
|
|
2584
|
+
* Generate test data for hot path warming
|
|
2585
|
+
*/
|
|
2586
|
+
private static generateHotPathTestData;
|
|
2587
|
+
private static cleanupOldMetrics;
|
|
2588
|
+
private static getRecentMetrics;
|
|
2589
|
+
private static groupBy;
|
|
2590
|
+
private static countOperations;
|
|
2591
|
+
private static getEmptyProfile;
|
|
2592
|
+
}
|
|
2593
|
+
|
|
2594
|
+
export { Docs, Extensions, FieldTypes, Interface, InterfaceSchema, Live, Make, Mod, PerformanceMonitor, Quick, QuickSchemas, Smart, TypeScriptGenerator, When };
|
|
2595
|
+
export type { ArraySchemaOptions, BooleanSchemaOptions, ConstantValue, InferType, NumberSchemaOptions, ObjectSchemaOptions, SchemaConfig, SchemaFieldType, SchemaInterface, SchemaOptions, SchemaType, SchemaValidationResult, StringSchemaOptions };
|