@maroonedog/luq 0.1.0-alpha
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 +9 -0
- package/README.md +879 -0
- package/dist/constants.d.ts +27 -0
- package/dist/core/async.experimental/async-context.d.ts +60 -0
- package/dist/core/builder/array-batch-optimizer.d.ts +66 -0
- package/dist/core/builder/context/field-context.d.ts +31 -0
- package/dist/core/builder/context/field-type-detector.d.ts +19 -0
- package/dist/core/builder/core/builder.d.ts +10 -0
- package/dist/core/builder/core/field-builder.d.ts +13 -0
- package/dist/core/builder/core/index.d.ts +17 -0
- package/dist/core/builder/index.d.ts +24 -0
- package/dist/core/builder/nested-array-processor.d.ts +52 -0
- package/dist/core/builder/plugins/composable-conditional-plugin.d.ts +32 -0
- package/dist/core/builder/plugins/composable-directly-plugin.d.ts +32 -0
- package/dist/core/builder/plugins/composable-plugin.d.ts +242 -0
- package/dist/core/builder/plugins/plugin-creator.d.ts +38 -0
- package/dist/core/builder/plugins/plugin-interfaces.d.ts +343 -0
- package/dist/core/builder/plugins/plugin-types.d.ts +441 -0
- package/dist/core/builder/raw-validator.d.ts +22 -0
- package/dist/core/builder/types/field-options.d.ts +46 -0
- package/dist/core/builder/types/types.d.ts +318 -0
- package/dist/core/builder/ultra-fast-validator.d.ts +30 -0
- package/dist/core/builder/validator-factory.d.ts +29 -0
- package/dist/core/global-config.d.ts +27 -0
- package/dist/core/index.d.ts +36 -0
- package/dist/core/optimization/array-batch-validator.d.ts +68 -0
- package/dist/core/optimization/core/field-utils.d.ts +103 -0
- package/dist/core/optimization/core/strategy-factory.d.ts +84 -0
- package/dist/core/optimization/core/validation-engine.d.ts +107 -0
- package/dist/core/optimization/execution-strategy-selector.d.ts +23 -0
- package/dist/core/optimization/unified-validator.d.ts +45 -0
- package/dist/core/plugin/__tests__/test-utils.d.ts +1 -0
- package/dist/core/plugin/arrayContains.d.ts +37 -0
- package/dist/core/plugin/arrayIncludes.d.ts +42 -0
- package/dist/core/plugin/arrayMaxLength.d.ts +43 -0
- package/dist/core/plugin/arrayMinLength.d.ts +43 -0
- package/dist/core/plugin/arrayUnique.d.ts +41 -0
- package/dist/core/plugin/booleanFalsy.d.ts +41 -0
- package/dist/core/plugin/booleanTruthy.d.ts +38 -0
- package/dist/core/plugin/compareField.d.ts +58 -0
- package/dist/core/plugin/conditionalSchema.d.ts +24 -0
- package/dist/core/plugin/custom.d.ts +60 -0
- package/dist/core/plugin/fromContext.d.ts +150 -0
- package/dist/core/plugin/index.d.ts +71 -0
- package/dist/core/plugin/jsonSchema/dsl-converter.d.ts +22 -0
- package/dist/core/plugin/jsonSchema/error-generation.d.ts +14 -0
- package/dist/core/plugin/jsonSchema/format-validators.d.ts +20 -0
- package/dist/core/plugin/jsonSchema/index.d.ts +11 -0
- package/dist/core/plugin/jsonSchema/plugin.d.ts +35 -0
- package/dist/core/plugin/jsonSchema/ref-resolver.d.ts +14 -0
- package/dist/core/plugin/jsonSchema/types.d.ts +69 -0
- package/dist/core/plugin/jsonSchema/validation-core.d.ts +29 -0
- package/dist/core/plugin/jsonSchemaFullFeature.d.ts +31 -0
- package/dist/core/plugin/literal.d.ts +40 -0
- package/dist/core/plugin/message-factories.d.ts +9 -0
- package/dist/core/plugin/nullable.d.ts +34 -0
- package/dist/core/plugin/numberFinite.d.ts +41 -0
- package/dist/core/plugin/numberInteger.d.ts +41 -0
- package/dist/core/plugin/numberMax.d.ts +49 -0
- package/dist/core/plugin/numberMin.d.ts +49 -0
- package/dist/core/plugin/numberMultipleOf.d.ts +42 -0
- package/dist/core/plugin/numberNegative.d.ts +41 -0
- package/dist/core/plugin/numberPositive.d.ts +41 -0
- package/dist/core/plugin/numberRange.d.ts +48 -0
- package/dist/core/plugin/object.d.ts +43 -0
- package/dist/core/plugin/objectAdditionalProperties.d.ts +51 -0
- package/dist/core/plugin/objectDependentRequired.d.ts +42 -0
- package/dist/core/plugin/objectDependentSchemas.d.ts +40 -0
- package/dist/core/plugin/objectMaxProperties.d.ts +42 -0
- package/dist/core/plugin/objectMinProperties.d.ts +42 -0
- package/dist/core/plugin/objectPatternProperties.d.ts +46 -0
- package/dist/core/plugin/objectPropertyNames.d.ts +36 -0
- package/dist/core/plugin/objectRecursively.d.ts +81 -0
- package/dist/core/plugin/oneOf.d.ts +44 -0
- package/dist/core/plugin/optional.d.ts +35 -0
- package/dist/core/plugin/optionalIf.d.ts +42 -0
- package/dist/core/plugin/orFail.d.ts +132 -0
- package/dist/core/plugin/readOnlyWriteOnly.d.ts +48 -0
- package/dist/core/plugin/required.d.ts +45 -0
- package/dist/core/plugin/requiredIf.d.ts +66 -0
- package/dist/core/plugin/shared-constants.d.ts +45 -0
- package/dist/core/plugin/shared.d.ts +3 -0
- package/dist/core/plugin/skip.d.ts +57 -0
- package/dist/core/plugin/stitch-typed.d.ts +15 -0
- package/dist/core/plugin/stitch.d.ts +1 -0
- package/dist/core/plugin/stitchSimple.d.ts +4 -0
- package/dist/core/plugin/stringAlphanumeric.d.ts +42 -0
- package/dist/core/plugin/stringBase64.d.ts +119 -0
- package/dist/core/plugin/stringContentEncoding.d.ts +43 -0
- package/dist/core/plugin/stringContentMediaType.d.ts +47 -0
- package/dist/core/plugin/stringDate.d.ts +48 -0
- package/dist/core/plugin/stringDatetime.d.ts +108 -0
- package/dist/core/plugin/stringDuration.d.ts +41 -0
- package/dist/core/plugin/stringEmail.d.ts +81 -0
- package/dist/core/plugin/stringEndsWith.d.ts +42 -0
- package/dist/core/plugin/stringExactLength.d.ts +46 -0
- package/dist/core/plugin/stringHostname.d.ts +104 -0
- package/dist/core/plugin/stringIpv4.d.ts +85 -0
- package/dist/core/plugin/stringIpv6.d.ts +104 -0
- package/dist/core/plugin/stringIri.d.ts +117 -0
- package/dist/core/plugin/stringIriReference.d.ts +43 -0
- package/dist/core/plugin/stringJsonPointer.d.ts +107 -0
- package/dist/core/plugin/stringMax.d.ts +43 -0
- package/dist/core/plugin/stringMin.d.ts +43 -0
- package/dist/core/plugin/stringPattern.d.ts +40 -0
- package/dist/core/plugin/stringRelativeJsonPointer.d.ts +42 -0
- package/dist/core/plugin/stringStartsWith.d.ts +42 -0
- package/dist/core/plugin/stringTime.d.ts +39 -0
- package/dist/core/plugin/stringUriTemplate.d.ts +43 -0
- package/dist/core/plugin/stringUrl.d.ts +97 -0
- package/dist/core/plugin/testUtils.d.ts +15 -0
- package/dist/core/plugin/transform-type-restrictions.d.ts +61 -0
- package/dist/core/plugin/transform.d.ts +35 -0
- package/dist/core/plugin/tupleBuilder.d.ts +66 -0
- package/dist/core/plugin/types.d.ts +143 -0
- package/dist/core/plugin/unionGuard.d.ts +50 -0
- package/dist/core/plugin/utils/field-accessor-optimized.d.ts +50 -0
- package/dist/core/plugin/utils/field-accessor.d.ts +107 -0
- package/dist/core/plugin/uuid.d.ts +95 -0
- package/dist/core/plugin/validateIf.d.ts +57 -0
- package/dist/core/registry/plugin-registry.d.ts +116 -0
- package/dist/core/registry.d.ts +6 -0
- package/dist/core/transform/index.d.ts +1 -0
- package/dist/core/transform/string/defaultValue.d.ts +6 -0
- package/dist/core/transform/string/index.d.ts +3 -0
- package/dist/core/transform/string/replace.d.ts +14 -0
- package/dist/core/transform/string/sanitize.d.ts +6 -0
- package/dist/core/utils/type-guards.d.ts +68 -0
- package/dist/index.d.ts +72 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +7 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +7 -0
- package/dist/plugins/arrayContains.d.ts +37 -0
- package/dist/plugins/arrayContains.js +1 -0
- package/dist/plugins/arrayContains.mjs +1 -0
- package/dist/plugins/arrayIncludes.d.ts +42 -0
- package/dist/plugins/arrayIncludes.js +1 -0
- package/dist/plugins/arrayIncludes.mjs +1 -0
- package/dist/plugins/arrayMaxLength.d.ts +43 -0
- package/dist/plugins/arrayMaxLength.js +1 -0
- package/dist/plugins/arrayMaxLength.mjs +1 -0
- package/dist/plugins/arrayMinLength.d.ts +43 -0
- package/dist/plugins/arrayMinLength.js +1 -0
- package/dist/plugins/arrayMinLength.mjs +1 -0
- package/dist/plugins/arrayUnique.d.ts +41 -0
- package/dist/plugins/arrayUnique.js +1 -0
- package/dist/plugins/arrayUnique.mjs +1 -0
- package/dist/plugins/booleanFalsy.d.ts +41 -0
- package/dist/plugins/booleanFalsy.js +1 -0
- package/dist/plugins/booleanFalsy.mjs +1 -0
- package/dist/plugins/booleanTruthy.d.ts +38 -0
- package/dist/plugins/booleanTruthy.js +1 -0
- package/dist/plugins/booleanTruthy.mjs +1 -0
- package/dist/plugins/compareField.d.ts +58 -0
- package/dist/plugins/compareField.js +1 -0
- package/dist/plugins/compareField.mjs +1 -0
- package/dist/plugins/custom.d.ts +60 -0
- package/dist/plugins/custom.js +1 -0
- package/dist/plugins/custom.mjs +1 -0
- package/dist/plugins/jsonSchema.d.ts +11 -0
- package/dist/plugins/jsonSchema.js +1 -0
- package/dist/plugins/jsonSchema.mjs +1 -0
- package/dist/plugins/jsonSchemaFullFeature.d.ts +31 -0
- package/dist/plugins/jsonSchemaFullFeature.js +1 -0
- package/dist/plugins/jsonSchemaFullFeature.mjs +1 -0
- package/dist/plugins/literal.d.ts +40 -0
- package/dist/plugins/literal.js +1 -0
- package/dist/plugins/literal.mjs +1 -0
- package/dist/plugins/nullable.d.ts +34 -0
- package/dist/plugins/nullable.js +1 -0
- package/dist/plugins/nullable.mjs +1 -0
- package/dist/plugins/numberInteger.d.ts +41 -0
- package/dist/plugins/numberInteger.js +1 -0
- package/dist/plugins/numberInteger.mjs +1 -0
- package/dist/plugins/numberMax.d.ts +49 -0
- package/dist/plugins/numberMax.js +1 -0
- package/dist/plugins/numberMax.mjs +1 -0
- package/dist/plugins/numberMin.d.ts +49 -0
- package/dist/plugins/numberMin.js +1 -0
- package/dist/plugins/numberMin.mjs +1 -0
- package/dist/plugins/numberMultipleOf.d.ts +42 -0
- package/dist/plugins/numberMultipleOf.js +1 -0
- package/dist/plugins/numberMultipleOf.mjs +1 -0
- package/dist/plugins/numberNegative.d.ts +41 -0
- package/dist/plugins/numberNegative.js +1 -0
- package/dist/plugins/numberNegative.mjs +1 -0
- package/dist/plugins/numberPositive.d.ts +41 -0
- package/dist/plugins/numberPositive.js +1 -0
- package/dist/plugins/numberPositive.mjs +1 -0
- package/dist/plugins/object.d.ts +43 -0
- package/dist/plugins/object.js +1 -0
- package/dist/plugins/object.mjs +1 -0
- package/dist/plugins/objectAdditionalProperties.d.ts +51 -0
- package/dist/plugins/objectAdditionalProperties.js +1 -0
- package/dist/plugins/objectAdditionalProperties.mjs +1 -0
- package/dist/plugins/objectDependentRequired.d.ts +42 -0
- package/dist/plugins/objectDependentRequired.js +1 -0
- package/dist/plugins/objectDependentRequired.mjs +1 -0
- package/dist/plugins/objectDependentSchemas.d.ts +40 -0
- package/dist/plugins/objectDependentSchemas.js +1 -0
- package/dist/plugins/objectDependentSchemas.mjs +1 -0
- package/dist/plugins/objectMaxProperties.d.ts +42 -0
- package/dist/plugins/objectMaxProperties.js +1 -0
- package/dist/plugins/objectMaxProperties.mjs +1 -0
- package/dist/plugins/objectMinProperties.d.ts +42 -0
- package/dist/plugins/objectMinProperties.js +1 -0
- package/dist/plugins/objectMinProperties.mjs +1 -0
- package/dist/plugins/objectPatternProperties.d.ts +46 -0
- package/dist/plugins/objectPatternProperties.js +1 -0
- package/dist/plugins/objectPatternProperties.mjs +1 -0
- package/dist/plugins/objectPropertyNames.d.ts +36 -0
- package/dist/plugins/objectPropertyNames.js +1 -0
- package/dist/plugins/objectPropertyNames.mjs +1 -0
- package/dist/plugins/oneOf.d.ts +44 -0
- package/dist/plugins/oneOf.js +1 -0
- package/dist/plugins/oneOf.mjs +1 -0
- package/dist/plugins/optional.d.ts +35 -0
- package/dist/plugins/optional.js +1 -0
- package/dist/plugins/optional.mjs +1 -0
- package/dist/plugins/readOnlyWriteOnly.d.ts +48 -0
- package/dist/plugins/readOnlyWriteOnly.js +1 -0
- package/dist/plugins/readOnlyWriteOnly.mjs +1 -0
- package/dist/plugins/required.d.ts +45 -0
- package/dist/plugins/required.js +1 -0
- package/dist/plugins/required.mjs +1 -0
- package/dist/plugins/requiredIf.d.ts +66 -0
- package/dist/plugins/requiredIf.js +1 -0
- package/dist/plugins/requiredIf.mjs +1 -0
- package/dist/plugins/skip.d.ts +57 -0
- package/dist/plugins/skip.js +1 -0
- package/dist/plugins/skip.mjs +1 -0
- package/dist/plugins/stringBase64.d.ts +119 -0
- package/dist/plugins/stringBase64.js +1 -0
- package/dist/plugins/stringBase64.mjs +1 -0
- package/dist/plugins/stringContentEncoding.d.ts +43 -0
- package/dist/plugins/stringContentEncoding.js +1 -0
- package/dist/plugins/stringContentEncoding.mjs +1 -0
- package/dist/plugins/stringContentMediaType.d.ts +47 -0
- package/dist/plugins/stringContentMediaType.js +1 -0
- package/dist/plugins/stringContentMediaType.mjs +1 -0
- package/dist/plugins/stringDate.d.ts +48 -0
- package/dist/plugins/stringDate.js +1 -0
- package/dist/plugins/stringDate.mjs +1 -0
- package/dist/plugins/stringDatetime.d.ts +108 -0
- package/dist/plugins/stringDatetime.js +1 -0
- package/dist/plugins/stringDatetime.mjs +1 -0
- package/dist/plugins/stringDuration.d.ts +41 -0
- package/dist/plugins/stringDuration.js +1 -0
- package/dist/plugins/stringDuration.mjs +1 -0
- package/dist/plugins/stringEmail.d.ts +81 -0
- package/dist/plugins/stringEmail.js +1 -0
- package/dist/plugins/stringEmail.mjs +1 -0
- package/dist/plugins/stringHostname.d.ts +104 -0
- package/dist/plugins/stringHostname.js +1 -0
- package/dist/plugins/stringHostname.mjs +1 -0
- package/dist/plugins/stringIpv4.d.ts +85 -0
- package/dist/plugins/stringIpv4.js +1 -0
- package/dist/plugins/stringIpv4.mjs +1 -0
- package/dist/plugins/stringIpv6.d.ts +104 -0
- package/dist/plugins/stringIpv6.js +1 -0
- package/dist/plugins/stringIpv6.mjs +1 -0
- package/dist/plugins/stringIri.d.ts +117 -0
- package/dist/plugins/stringIri.js +1 -0
- package/dist/plugins/stringIri.mjs +1 -0
- package/dist/plugins/stringIriReference.d.ts +43 -0
- package/dist/plugins/stringIriReference.js +1 -0
- package/dist/plugins/stringIriReference.mjs +1 -0
- package/dist/plugins/stringJsonPointer.d.ts +107 -0
- package/dist/plugins/stringJsonPointer.js +1 -0
- package/dist/plugins/stringJsonPointer.mjs +1 -0
- package/dist/plugins/stringMax.d.ts +43 -0
- package/dist/plugins/stringMax.js +1 -0
- package/dist/plugins/stringMax.mjs +1 -0
- package/dist/plugins/stringMin.d.ts +43 -0
- package/dist/plugins/stringMin.js +1 -0
- package/dist/plugins/stringMin.mjs +1 -0
- package/dist/plugins/stringPattern.d.ts +40 -0
- package/dist/plugins/stringPattern.js +1 -0
- package/dist/plugins/stringPattern.mjs +1 -0
- package/dist/plugins/stringRelativeJsonPointer.d.ts +42 -0
- package/dist/plugins/stringRelativeJsonPointer.js +1 -0
- package/dist/plugins/stringRelativeJsonPointer.mjs +1 -0
- package/dist/plugins/stringTime.d.ts +39 -0
- package/dist/plugins/stringTime.js +1 -0
- package/dist/plugins/stringTime.mjs +1 -0
- package/dist/plugins/stringUriTemplate.d.ts +43 -0
- package/dist/plugins/stringUriTemplate.js +1 -0
- package/dist/plugins/stringUriTemplate.mjs +1 -0
- package/dist/plugins/stringUrl.d.ts +97 -0
- package/dist/plugins/stringUrl.js +1 -0
- package/dist/plugins/stringUrl.mjs +1 -0
- package/dist/plugins/transform.d.ts +35 -0
- package/dist/plugins/transform.js +1 -0
- package/dist/plugins/transform.mjs +1 -0
- package/dist/plugins/tupleBuilder.d.ts +66 -0
- package/dist/plugins/tupleBuilder.js +1 -0
- package/dist/plugins/tupleBuilder.mjs +1 -0
- package/dist/plugins/uuid.d.ts +95 -0
- package/dist/plugins/uuid.js +1 -0
- package/dist/plugins/uuid.mjs +1 -0
- package/dist/plugins/validateIf.d.ts +57 -0
- package/dist/plugins/validateIf.js +1 -0
- package/dist/plugins/validateIf.mjs +1 -0
- package/dist/types/array-type-analysis.d.ts +115 -0
- package/dist/types/index.d.ts +74 -0
- package/dist/types/indexed-result.d.ts +44 -0
- package/dist/types/result.d.ts +159 -0
- package/dist/types/stitch-types.d.ts +118 -0
- package/dist/types/util.d.ts +19 -0
- package/dist/types/valitator.d.ts +10 -0
- package/package.json +353 -0
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Smart plugin creation with advanced type inference
|
|
3
|
+
*/
|
|
4
|
+
import { NestedKeyOf, ParseOptions, TypeOfPath, ValidationOptions, ValidationError, Result } from "../../../types";
|
|
5
|
+
import type { FieldRule } from "../../registry/plugin-registry";
|
|
6
|
+
import { ApplyNestedTransforms } from "../types/types";
|
|
7
|
+
import type { ComposablePlugin } from "../plugins/composable-plugin";
|
|
8
|
+
export type { ParseOptions, ValidationOptions };
|
|
9
|
+
export type TransformFunction<TInput, TOutput> = (value: TInput) => TOutput;
|
|
10
|
+
/**
|
|
11
|
+
* Parse result with transform tracking
|
|
12
|
+
*/
|
|
13
|
+
export interface TransformParseResult<TOriginal, TTransformed> {
|
|
14
|
+
valid: boolean;
|
|
15
|
+
value: TOriginal | null;
|
|
16
|
+
transformedData?: TTransformed;
|
|
17
|
+
originalData?: TOriginal;
|
|
18
|
+
errors: any[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Plugin types
|
|
22
|
+
*/
|
|
23
|
+
export type PluginType = "validator" | "transform";
|
|
24
|
+
/**
|
|
25
|
+
* Plugin category types
|
|
26
|
+
*/
|
|
27
|
+
export type PluginCategory = "standard" | "conditional" | "transform" | "fieldReference" | "multiFieldReference" | "arrayElement" | "composable" | "composable-conditional" | "composable-directly" | "context" | "builder-extension";
|
|
28
|
+
/**
|
|
29
|
+
* Plugin definition with literal type for name
|
|
30
|
+
*/
|
|
31
|
+
export interface TypedPlugin<TName extends string, TMethodName extends string, TMethod extends Function, TAllowedTypes extends readonly TypeName[] | undefined = undefined, TPluginType extends PluginType = "validator", TCategory extends PluginCategory = "standard"> {
|
|
32
|
+
name: TName;
|
|
33
|
+
methodName: TMethodName;
|
|
34
|
+
create(): TMethod;
|
|
35
|
+
allowedTypes?: TAllowedTypes;
|
|
36
|
+
category: TCategory;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Standard method signature for builder extensions
|
|
40
|
+
* All extension methods must follow this pattern: accept TBuilder as type parameter and return it
|
|
41
|
+
*/
|
|
42
|
+
export type BuilderExtensionMethod = {
|
|
43
|
+
<TBuilder>(...args: any[]): TBuilder;
|
|
44
|
+
} | {
|
|
45
|
+
<TBuilder extends FieldBuilder<any, any, any, any>>(...args: any[]): TBuilder;
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Builder extension plugin interface with method signatures
|
|
49
|
+
* TExtensions must follow BuilderExtensionMethod pattern
|
|
50
|
+
*/
|
|
51
|
+
export interface BuilderExtensionPlugin<TName extends string = string, TMethodName extends string = string, TMethodSignature extends BuilderExtensionMethod = BuilderExtensionMethod> {
|
|
52
|
+
name: TName;
|
|
53
|
+
category: "builder-extension";
|
|
54
|
+
methodName: TMethodName;
|
|
55
|
+
extendBuilder: (builderInstance: any) => void;
|
|
56
|
+
impl: TMethodSignature;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Allowed type names
|
|
60
|
+
*/
|
|
61
|
+
export type TypeName = "string" | "number" | "date" | "array" | "union" | "tuple" | "object" | "boolean" | "null" | "any";
|
|
62
|
+
/**
|
|
63
|
+
* Type mapping for type names
|
|
64
|
+
*/
|
|
65
|
+
export type TypeMapping = {
|
|
66
|
+
string: string;
|
|
67
|
+
number: number;
|
|
68
|
+
date: Date;
|
|
69
|
+
array: any[];
|
|
70
|
+
union: any;
|
|
71
|
+
tuple: readonly any[];
|
|
72
|
+
object: object;
|
|
73
|
+
boolean: boolean;
|
|
74
|
+
null: null;
|
|
75
|
+
any: any;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Field validator interface for validating individual field values
|
|
79
|
+
* @template TObject - The parent object type
|
|
80
|
+
* @template TValue - The field value type
|
|
81
|
+
* @template TRequiredKeys - Required keys for validation context
|
|
82
|
+
*/
|
|
83
|
+
export interface FieldValidator<TObject extends object, TValue, TRequiredKeys = undefined> {
|
|
84
|
+
/**
|
|
85
|
+
* Validates a single field value
|
|
86
|
+
* @param value - The field value to validate
|
|
87
|
+
* @param allValues - The complete object context for cross-field validation
|
|
88
|
+
* @param options - Optional validation configuration
|
|
89
|
+
* @returns Validation result for the field
|
|
90
|
+
*/
|
|
91
|
+
validate(value?: TValue | null, allValues?: TRequiredKeys extends undefined ? Partial<TObject> | undefined : Partial<TObject>, options?: ValidationOptions): ValidationResult<TValue>;
|
|
92
|
+
/**
|
|
93
|
+
* Parses and transforms a single field value
|
|
94
|
+
* @param value - The field value to parse
|
|
95
|
+
* @param allValues - The complete object context for cross-field validation
|
|
96
|
+
* @param options - Optional parse configuration
|
|
97
|
+
* @returns Parse result for the field with transformed value
|
|
98
|
+
*/
|
|
99
|
+
parse?(value?: TValue | null, allValues?: TRequiredKeys extends undefined ? Partial<TObject> | undefined : Partial<TObject>, options?: ParseOptions): ValidationResult<TValue>;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Field validation result
|
|
103
|
+
*/
|
|
104
|
+
export interface FieldValidationResult<T> {
|
|
105
|
+
valid: boolean;
|
|
106
|
+
value?: T;
|
|
107
|
+
errors?: Array<{
|
|
108
|
+
path: string;
|
|
109
|
+
message: string;
|
|
110
|
+
code: string;
|
|
111
|
+
}>;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Helper type to check if a field type can be refined to a target type
|
|
115
|
+
* This is more specific to prevent primitive types from being considered as objects
|
|
116
|
+
*/
|
|
117
|
+
type CanRefineToType<TFieldType, TTargetType> = TTargetType extends string ? [TFieldType] extends [string] ? false : true : TTargetType extends number ? [TFieldType] extends [number] ? false : true : TTargetType extends boolean ? [TFieldType] extends [boolean] ? false : true : TTargetType extends Date ? [TFieldType] extends [Date] ? false : true : TTargetType extends readonly any[] ? [TFieldType] extends [readonly any[]] ? false : true : TTargetType extends any[] ? [TFieldType] extends [any[]] ? false : true : TTargetType extends object ? [TFieldType] extends [object] ? [TFieldType] extends [
|
|
118
|
+
string | number | boolean | Date | any[] | readonly any[]
|
|
119
|
+
] ? true : false : true : [TFieldType] extends [TTargetType] ? false : true;
|
|
120
|
+
/**
|
|
121
|
+
* Refine methods for type transitions - only show when type can be refined
|
|
122
|
+
*/
|
|
123
|
+
export interface ChainableFieldBuilderTransformAware<TObject extends object, TPlugins = {}, TFieldType = any> {
|
|
124
|
+
refineString: CanRefineToType<TFieldType, string> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "string", string> : never;
|
|
125
|
+
refineNumber: CanRefineToType<TFieldType, number> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "number", number> : never;
|
|
126
|
+
refineArray: CanRefineToType<TFieldType, any[]> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "array", any[]> : never;
|
|
127
|
+
refineTuple: CanRefineToType<TFieldType, readonly any[]> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "tuple", readonly any[]> : never;
|
|
128
|
+
refineUnion: CanRefineToType<TFieldType, any> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "union", any> : never;
|
|
129
|
+
refineBoolean: CanRefineToType<TFieldType, boolean> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "boolean", boolean> : never;
|
|
130
|
+
refineDate: CanRefineToType<TFieldType, Date> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "date", Date> : never;
|
|
131
|
+
refineObject: CanRefineToType<TFieldType, object> extends true ? () => ChainableFieldBuilder<TObject, TPlugins, "object", object> : never;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Get category from plugin by method name
|
|
135
|
+
*/
|
|
136
|
+
type GetPluginCategoryByMethod<TPlugins, TMethodName extends string> = {
|
|
137
|
+
[K in keyof TPlugins]: TPlugins[K] extends TypedPlugin<any, TMethodName, any, any, any, infer TCategory> ? TCategory : never;
|
|
138
|
+
}[keyof TPlugins];
|
|
139
|
+
/**
|
|
140
|
+
* Get the actual method from plugin by method name
|
|
141
|
+
*/
|
|
142
|
+
type GetPluginMethodByName<TPlugins, TMethodName extends string> = {
|
|
143
|
+
[K in keyof TPlugins]: TPlugins[K] extends TypedPlugin<any, TMethodName, infer TMethod, any, any, any> ? TMethod : never;
|
|
144
|
+
}[keyof TPlugins];
|
|
145
|
+
/**
|
|
146
|
+
* Infer method parameters with actual types applied
|
|
147
|
+
*/
|
|
148
|
+
export type InferMethodParameters<TMethod, TObject, TCurrentType, TPlugins = {}, TMethodName extends string = string> = GetPluginMethodByName<TPlugins, TMethodName> extends infer ActualMethod ? ActualMethod extends (...args: infer P) => any ? P : never : TMethod extends (...args: infer P) => any ? P : never;
|
|
149
|
+
/**
|
|
150
|
+
* Map plugin methods to chainable builder methods
|
|
151
|
+
*/
|
|
152
|
+
type MapPluginMethodsToChainable<TMethods, TObject extends object, TPlugins, TType extends TypeName | undefined, TCurrentType, TTypeState extends TypeStateFlags = {}> = {
|
|
153
|
+
[MethodName in keyof TMethods]: TMethods[MethodName] extends infer TMethod ? TMethod extends (...args: any) => any ? GetPluginCategoryByMethod<TPlugins, MethodName & string> extends infer TCategory ? TCategory extends "conditional" ? (condition: (allValues: TObject) => boolean, options?: ValidationOptions) => ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> : TCategory extends "composable-conditional" ? MethodName extends "guard" ? TType extends "union" ? <TGuardType extends TCurrentType>(condition: (value: unknown) => value is TGuardType, builderFn: (context: FieldBuilderContext<TObject, TPlugins, TGuardType>) => any) => ChainableFieldBuilderWithUnionTracking<TObject, TPlugins, TType, TCurrentType, TGuardType> : ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> : InferMethodParameters<TMethod, TObject, TCurrentType, TPlugins, MethodName & string> extends infer Params ? Params extends readonly any[] ? (...args: Params) => ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> : never : never : TCategory extends "fieldReference" ? (fieldPath: NestedKeyOf<TObject> & string, options?: ValidationOptions) => ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> : TCategory extends "multiFieldReference" ? <const TFields extends readonly (NestedKeyOf<TObject> & string)[]>(fields: TFields, validate: (fieldValues: import("../../../types/stitch-types").FieldsToObject<TObject, TFields>, currentValue: ApplyTypeState<TCurrentType, TTypeState>, allValues: TObject) => {
|
|
154
|
+
valid: boolean;
|
|
155
|
+
message?: string;
|
|
156
|
+
}, options?: ValidationOptions & {
|
|
157
|
+
code?: string;
|
|
158
|
+
messageFactory?: (context: {
|
|
159
|
+
path: string;
|
|
160
|
+
value: ApplyTypeState<TCurrentType, TTypeState>;
|
|
161
|
+
code: string;
|
|
162
|
+
fields: TFields;
|
|
163
|
+
fieldValues: import("../../../types/stitch-types").FieldsToObject<TObject, TFields>;
|
|
164
|
+
allValues: TObject;
|
|
165
|
+
}) => string;
|
|
166
|
+
}) => ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> : TCategory extends "transform" ? <TOutput>(fn: import("../../plugin/transform-type-restrictions").IsForbiddenTransformOutput<TOutput> extends true ? import("../../plugin/transform-type-restrictions").ForbiddenTransformError<TOutput> : (value: ApplyTypeState<TCurrentType, TTypeState>) => TOutput) => ChainableFieldBuilder<TObject, TPlugins, TType, TOutput, TTypeState> : MethodName extends "required" ? InferMethodParameters<TMethod, TObject, TCurrentType, TPlugins, MethodName & string> extends infer Params ? Params extends readonly any[] ? (...args: Params) => ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, {
|
|
167
|
+
excludeUndefined: true;
|
|
168
|
+
excludeNull?: TTypeState["excludeNull"];
|
|
169
|
+
}> : never : never : MethodName extends "optional" ? InferMethodParameters<TMethod, TObject, TCurrentType, TPlugins, MethodName & string> extends infer Params ? Params extends readonly any[] ? (...args: Params) => ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, {
|
|
170
|
+
excludeUndefined: true;
|
|
171
|
+
excludeNull?: TTypeState["excludeNull"];
|
|
172
|
+
}> : never : never : MethodName extends "nullable" ? InferMethodParameters<TMethod, TObject, TCurrentType, TPlugins, MethodName & string> extends infer Params ? Params extends readonly any[] ? (...args: Params) => ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType | null, {
|
|
173
|
+
excludeUndefined?: TTypeState["excludeUndefined"];
|
|
174
|
+
excludeNull: true;
|
|
175
|
+
}> : never : never : InferMethodParameters<TMethod, TObject, TCurrentType, TPlugins, MethodName & string> extends infer Params ? Params extends readonly any[] ? (...args: Params) => InferChainableReturnType<TMethod, TObject, TPlugins, TType, TCurrentType, MethodName & string, TTypeState> : never : never : never : never : never;
|
|
176
|
+
};
|
|
177
|
+
/**
|
|
178
|
+
* Determine the return type of a chainable method based on the plugin
|
|
179
|
+
*/
|
|
180
|
+
type InferChainableReturnType<TMethod, TObject extends object, TPlugins, TType extends TypeName | undefined, TCurrentType, TMethodName extends string, TTypeState extends TypeStateFlags = {}> = GetPluginCategoryByMethod<TPlugins, TMethodName> extends infer TCategory ? TCategory extends "transform" ? <TOutput>(fn: (value: ApplyTypeState<TCurrentType, TTypeState>) => TOutput) => ChainableFieldBuilder<TObject, TPlugins, TType, TOutput, TTypeState> : TMethodName extends "nullable" ? ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType | null, {
|
|
181
|
+
excludeUndefined?: TTypeState["excludeUndefined"];
|
|
182
|
+
excludeNull: true;
|
|
183
|
+
}> : TMethodName extends "guard" ? TType extends "union" ? <TGuardType extends TCurrentType>(condition: (value: unknown) => value is TGuardType, builderFn: (context: FieldBuilderContext<TObject, TPlugins, TGuardType>) => any) => ChainableFieldBuilderWithUnionTracking<TObject, TPlugins, TType, TCurrentType, TGuardType> : ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> : ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> : ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState>;
|
|
184
|
+
/**
|
|
185
|
+
* Extract composable plugin methods
|
|
186
|
+
*/
|
|
187
|
+
export type ExtractComposablePluginMethods<TPlugins> = TPlugins extends {} ? UnionToIntersection<{
|
|
188
|
+
[K in keyof TPlugins]: TPlugins[K] extends TypedPlugin<any, infer TMethodName, infer TMethod, any, any, "composable" | "composable-conditional" | "composable-directly"> ? Record<TMethodName, TMethod> : TPlugins[K] extends {
|
|
189
|
+
category: "composable" | "composable-conditional" | "composable-directly";
|
|
190
|
+
methodName: infer TMethodName;
|
|
191
|
+
} ? TMethodName extends string ? Record<TMethodName, (...args: any[]) => any> : never : never;
|
|
192
|
+
}[keyof TPlugins]> : never;
|
|
193
|
+
/**
|
|
194
|
+
* Base interface for chainable builders - contains common methods
|
|
195
|
+
*/
|
|
196
|
+
interface ChainableFieldBuilderBase<TObject extends object, TPlugins, TType extends TypeName | undefined, TCurrentType, TTypeState extends TypeStateFlags = {}> {
|
|
197
|
+
refineString(): ChainableFieldBuilder<TObject, TPlugins, "string", TCurrentType, TTypeState>;
|
|
198
|
+
refineNumber(): ChainableFieldBuilder<TObject, TPlugins, "number", TCurrentType, TTypeState>;
|
|
199
|
+
refineBoolean(): ChainableFieldBuilder<TObject, TPlugins, "boolean", TCurrentType, TTypeState>;
|
|
200
|
+
refineArray(): ChainableFieldBuilder<TObject, TPlugins, "array", TCurrentType, TTypeState>;
|
|
201
|
+
refineObject(): ChainableFieldBuilder<TObject, TPlugins, "object", TCurrentType, TTypeState>;
|
|
202
|
+
refineTuple(): ChainableFieldBuilder<TObject, TPlugins, "tuple", TCurrentType, TTypeState>;
|
|
203
|
+
refineUnion(): ChainableFieldBuilder<TObject, TPlugins, "union", TCurrentType, TTypeState>;
|
|
204
|
+
refineDate(): ChainableFieldBuilder<TObject, TPlugins, "date", TCurrentType, TTypeState>;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Union builder with exhaustive type checking
|
|
208
|
+
*/
|
|
209
|
+
interface UnionFieldBuilder<TObject extends object, TPlugins, TUnionType, TDeclaredTypes = never> extends ChainableFieldBuilderBase<TObject, TPlugins, "union", TUnionType> {
|
|
210
|
+
build(): Exclude<TUnionType, TDeclaredTypes> extends never ? FieldValidator<TObject, TUnionType> : {
|
|
211
|
+
_error: `Missing guard declarations for union types: ${Exclude<TUnionType, TDeclaredTypes> & string}`;
|
|
212
|
+
_missingTypes: Exclude<TUnionType, TDeclaredTypes>;
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Guard method signature for union types
|
|
217
|
+
*/
|
|
218
|
+
type GuardMethod<TObject extends object, TPlugins, TUnionType, TDeclaredTypes> = <TGuardType extends TUnionType>(condition: (value: unknown) => value is TGuardType, builderFn: (context: FieldBuilderContext<TObject, TPlugins, TGuardType>) => any) => UnionFieldBuilderWithPlugins<TObject, TPlugins, TUnionType, TDeclaredTypes | TGuardType>;
|
|
219
|
+
/**
|
|
220
|
+
* Extract plugin methods for union type
|
|
221
|
+
*/
|
|
222
|
+
type ExtractUnionPluginMethods<TObject extends object, TPlugins, TUnionType, TDeclaredTypes = never> = {
|
|
223
|
+
[K in keyof FlattenPluginMethods<FilterPluginsByType<TPlugins, "union">, TObject, TUnionType>]: K extends "guard" ? GuardMethod<TObject, TPlugins, TUnionType, TDeclaredTypes> : FlattenPluginMethods<FilterPluginsByType<TPlugins, "union">, TObject, TUnionType>[K] extends (...args: infer P) => any ? (...args: P) => UnionFieldBuilderWithPlugins<TObject, TPlugins, TUnionType, TDeclaredTypes> : never;
|
|
224
|
+
};
|
|
225
|
+
/**
|
|
226
|
+
* Complete union field builder with plugins
|
|
227
|
+
*/
|
|
228
|
+
type UnionFieldBuilderWithPlugins<TObject extends object, TPlugins, TUnionType, TDeclaredTypes = never> = UnionFieldBuilder<TObject, TPlugins, TUnionType, TDeclaredTypes> & ExtractUnionPluginMethods<TObject, TPlugins, TUnionType, TDeclaredTypes>;
|
|
229
|
+
/**
|
|
230
|
+
* Chainable field builder with union type tracking
|
|
231
|
+
*/
|
|
232
|
+
export type ChainableFieldBuilderWithUnionTracking<TObject extends object, TPlugins = {}, TType extends TypeName | undefined = undefined, TCurrentType = TType extends TypeName ? TypeMapping[TType] : any, TDeclaredUnionTypes = never> = TType extends "union" ? UnionFieldBuilderWithPlugins<TObject, TPlugins, TCurrentType, TDeclaredUnionTypes> : ChainableFieldBuilder<TObject, TPlugins, TType, TCurrentType>;
|
|
233
|
+
/**
|
|
234
|
+
* Standard field builder interface
|
|
235
|
+
*/
|
|
236
|
+
interface StandardFieldBuilder<TObject extends object, TPlugins, TType extends TypeName | undefined, TCurrentType, TTypeState extends TypeStateFlags = {}> extends ChainableFieldBuilderBase<TObject, TPlugins, TType, TCurrentType, TTypeState> {
|
|
237
|
+
build(): FieldValidator<TObject, TCurrentType>;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Type state tracking for required/optional/nullable
|
|
241
|
+
*/
|
|
242
|
+
export interface TypeStateFlags {
|
|
243
|
+
excludeUndefined?: boolean;
|
|
244
|
+
excludeNull?: boolean;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Apply type state to a type
|
|
248
|
+
*/
|
|
249
|
+
export type ApplyTypeState<T, TState extends TypeStateFlags> = TState["excludeUndefined"] extends true ? TState["excludeNull"] extends true ? NonNullable<T> : Exclude<T, undefined> : TState["excludeNull"] extends true ? Exclude<T, null> : T;
|
|
250
|
+
/**
|
|
251
|
+
* Simplified chainable field builder for better type inference
|
|
252
|
+
*/
|
|
253
|
+
export type ChainableFieldBuilder<TObject extends object, TPlugins = {}, TType extends TypeName | undefined = undefined, TCurrentType = TType extends TypeName ? TypeMapping[TType] : any, TTypeState extends TypeStateFlags = {}> = TType extends TypeName ? StandardFieldBuilder<TObject, TPlugins, TType, TCurrentType, TTypeState> & MapPluginMethodsToChainable<FlattenPluginMethods<FilterPluginsByType<TPlugins, TType>, TObject, TCurrentType>, TObject, TPlugins, TType, TCurrentType, TTypeState> & ExtractComposablePluginMethods<FilterPluginsByType<TPlugins, TType>> : {
|
|
254
|
+
build(): FieldValidator<TObject, TCurrentType>;
|
|
255
|
+
refineString(): ChainableFieldBuilder<TObject, TPlugins, "string", TCurrentType, TTypeState>;
|
|
256
|
+
refineNumber(): ChainableFieldBuilder<TObject, TPlugins, "number", TCurrentType, TTypeState>;
|
|
257
|
+
refineBoolean(): ChainableFieldBuilder<TObject, TPlugins, "boolean", TCurrentType, TTypeState>;
|
|
258
|
+
refineArray(): ChainableFieldBuilder<TObject, TPlugins, "array", TCurrentType, TTypeState>;
|
|
259
|
+
refineObject(): ChainableFieldBuilder<TObject, TPlugins, "object", TCurrentType, TTypeState>;
|
|
260
|
+
refineTuple(): ChainableFieldBuilder<TObject, TPlugins, "tuple", TCurrentType, TTypeState>;
|
|
261
|
+
refineUnion(): ChainableFieldBuilder<TObject, TPlugins, "union", TCurrentType, TTypeState>;
|
|
262
|
+
refineDate(): ChainableFieldBuilder<TObject, TPlugins, "date", TCurrentType, TTypeState>;
|
|
263
|
+
} & {
|
|
264
|
+
[K in keyof FlattenPluginMethods<TPlugins, TObject, TCurrentType>]: K extends "required" ? FlattenPluginMethods<TPlugins, TObject, TCurrentType>[K] extends (...args: infer P) => any ? (...args: P) => ChainableFieldBuilder<TObject, TPlugins, undefined, TCurrentType, {
|
|
265
|
+
excludeUndefined: true;
|
|
266
|
+
excludeNull?: TTypeState["excludeNull"];
|
|
267
|
+
}> : never : K extends "optional" ? FlattenPluginMethods<TPlugins, TObject, TCurrentType>[K] extends (...args: infer P) => any ? (...args: P) => ChainableFieldBuilder<TObject, TPlugins, undefined, TCurrentType, {
|
|
268
|
+
excludeUndefined: true;
|
|
269
|
+
excludeNull?: TTypeState["excludeNull"];
|
|
270
|
+
}> : never : K extends "nullable" ? FlattenPluginMethods<TPlugins, TObject, TCurrentType>[K] extends (...args: infer P) => any ? (...args: P) => ChainableFieldBuilder<TObject, TPlugins, undefined, TCurrentType | null, {
|
|
271
|
+
excludeUndefined?: TTypeState["excludeUndefined"];
|
|
272
|
+
excludeNull: true;
|
|
273
|
+
}> : never : FlattenPluginMethods<TPlugins, TObject, TCurrentType>[K] extends (...args: infer P) => any ? (...args: P) => ChainableFieldBuilder<TObject, TPlugins, undefined, TCurrentType, TTypeState> : never;
|
|
274
|
+
} & ExtractComposablePluginMethods<TPlugins>;
|
|
275
|
+
/**
|
|
276
|
+
* Helper types for union detection and null removal
|
|
277
|
+
*/
|
|
278
|
+
type RemoveNullAndUndefined<T> = NonNullable<T>;
|
|
279
|
+
type IsUnion<T, U = T> = T extends boolean ? false : T extends U ? [U] extends [T] ? false : true : false;
|
|
280
|
+
/**
|
|
281
|
+
* Type-specific field builder context
|
|
282
|
+
* Shows all builders to match runtime behavior, with proper typing for the field type
|
|
283
|
+
*/
|
|
284
|
+
export type FieldBuilderContext<TObject extends object, TPlugins = {}, TFieldType = any> = {
|
|
285
|
+
string: ChainableFieldBuilder<TObject, TPlugins, "string", string>;
|
|
286
|
+
number: ChainableFieldBuilder<TObject, TPlugins, "number", number>;
|
|
287
|
+
boolean: ChainableFieldBuilder<TObject, TPlugins, "boolean", boolean>;
|
|
288
|
+
date: ChainableFieldBuilder<TObject, TPlugins, "date", Date>;
|
|
289
|
+
array: ChainableFieldBuilder<TObject, TPlugins, "array", any[]>;
|
|
290
|
+
tuple: ChainableFieldBuilder<TObject, TPlugins, "tuple", readonly any[]>;
|
|
291
|
+
union: IsUnion<RemoveNullAndUndefined<TFieldType>> extends true ? ValidateUnionType<RemoveNullAndUndefined<TFieldType>> extends UnionArrayObjectError ? ValidateUnionType<RemoveNullAndUndefined<TFieldType>> : ChainableFieldBuilderWithUnionTracking<TObject, TPlugins, "union", RemoveNullAndUndefined<TFieldType>, never> : [TFieldType] extends [never] ? ChainableFieldBuilder<TObject, TPlugins, "union", any> : TFieldType extends string | number | boolean | Date | any[] | object ? ValidateUnionType<TFieldType> extends UnionArrayObjectError ? ValidateUnionType<TFieldType> : ChainableFieldBuilderWithUnionTracking<TObject, TPlugins, "union", TFieldType, never> : ChainableFieldBuilder<TObject, TPlugins, "union", any>;
|
|
292
|
+
object: ChainableFieldBuilder<TObject, TPlugins, "object", object>;
|
|
293
|
+
any: ChainableFieldBuilder<TObject, TPlugins, "any", any>;
|
|
294
|
+
};
|
|
295
|
+
/**
|
|
296
|
+
* Validator interface
|
|
297
|
+
*/
|
|
298
|
+
export interface TransformAwareValidator<T extends object, TTransformed = T> {
|
|
299
|
+
validate(value: Partial<T> | unknown, options?: ValidationOptions): Result<T>;
|
|
300
|
+
parse(value: Partial<T> | unknown, options?: ParseOptions): Result<TTransformed>;
|
|
301
|
+
pick<K extends NestedKeyOf<T>>(key: K): FieldValidator<T, TypeOfPath<T, K>>;
|
|
302
|
+
validateRaw?(value: T, options?: ValidationOptions): boolean;
|
|
303
|
+
parseRaw?(value: T, options?: ParseOptions): {
|
|
304
|
+
valid: boolean;
|
|
305
|
+
data?: TTransformed;
|
|
306
|
+
error?: any;
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Validation result
|
|
311
|
+
*/
|
|
312
|
+
export interface ValidationResult<T> {
|
|
313
|
+
valid: boolean;
|
|
314
|
+
value: T | null;
|
|
315
|
+
errors: ValidationError[];
|
|
316
|
+
originalValue?: T;
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Apply transform map to original type
|
|
320
|
+
* This ensures that transformed fields have their new types in the result
|
|
321
|
+
*/
|
|
322
|
+
export type ApplyFieldTransforms<TObject, TMap> = ApplyNestedTransforms<TObject, TMap>;
|
|
323
|
+
/**
|
|
324
|
+
* Extract the final type from a field builder result
|
|
325
|
+
*/
|
|
326
|
+
export type ExtractFieldType<T> = T extends ChainableFieldBuilder<any, any, any, infer TOutput> ? TOutput : T extends {
|
|
327
|
+
build(): FieldValidator<any, infer TValue>;
|
|
328
|
+
} ? TValue : T extends FieldValidator<any, infer TValue> ? TValue : never;
|
|
329
|
+
/**
|
|
330
|
+
* Helper type to add a field transformation to the map
|
|
331
|
+
* Only adds to map if the type actually changed
|
|
332
|
+
*/
|
|
333
|
+
export type AddFieldTransform<TMap, K extends string, TOriginal, TResult> = TResult extends TOriginal ? TMap : TMap & Record<K, TResult>;
|
|
334
|
+
/**
|
|
335
|
+
* Helper type to track declared fields
|
|
336
|
+
*/
|
|
337
|
+
export type DeclaredFields<T> = T extends Record<infer K, any> ? K : never;
|
|
338
|
+
/**
|
|
339
|
+
* Helper type to check if all required fields are declared
|
|
340
|
+
*/
|
|
341
|
+
export type MissingFields<TObject extends object, TDeclared extends string> = Exclude<NestedKeyOf<TObject>, TDeclared>;
|
|
342
|
+
/**
|
|
343
|
+
* Field definition options for complex cases
|
|
344
|
+
*/
|
|
345
|
+
export interface FieldDefinitionObject<TObject extends object, TPlugins, TFieldType, TPreprocessed = TFieldType, TTransformed = TPreprocessed> {
|
|
346
|
+
/**
|
|
347
|
+
* Required validation definition
|
|
348
|
+
*/
|
|
349
|
+
validate: (context: FieldBuilderContext<TObject, TPlugins, TPreprocessed>) => ChainableFieldBuilder<TObject, TPlugins, any, any> | FieldValidator<TObject, any>;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Field definition can be either a function (simple) or object (complex)
|
|
353
|
+
*/
|
|
354
|
+
export type FieldDefinition<TObject extends object, TPlugins, TFieldType, TFieldBuilder> = (context: FieldBuilderContext<TObject, TPlugins, TFieldType>) => TFieldBuilder;
|
|
355
|
+
/**
|
|
356
|
+
* Forward declaration
|
|
357
|
+
*/
|
|
358
|
+
export interface FieldBuilder<TObject extends object, TMap = {}, TPlugins = {}, TDeclaredFields extends string = never> {
|
|
359
|
+
/**
|
|
360
|
+
* @deprecated Use `v` method instead. This method will be removed in a future version.
|
|
361
|
+
* Define validation rules for a field
|
|
362
|
+
* WIP: Does not validate unknown properties by default
|
|
363
|
+
* @param path - The field path to validate
|
|
364
|
+
* @param definition - Validation rule definition
|
|
365
|
+
* @param options - Optional field configuration
|
|
366
|
+
*/
|
|
367
|
+
field<Key extends NestedKeyOf<TObject> & string, TFieldBuilder>(path: Key, definition: FieldDefinition<TObject, TPlugins, TypeOfPath<TObject, Key>, TFieldBuilder>, options?: import("../types/field-options").FieldConfig<TypeOfPath<TObject, Key>>): FieldBuilder<TObject, AddFieldTransform<TMap, Key, TypeOfPath<TObject, Key>, ExtractFieldType<TFieldBuilder>>, TPlugins, TDeclaredFields | Key>;
|
|
368
|
+
/**
|
|
369
|
+
* Define validation rules for a field (alias for field method)
|
|
370
|
+
* WIP: Does not validate unknown properties by default
|
|
371
|
+
* @param path - The field path to validate
|
|
372
|
+
* @param definition - Validation rule definition
|
|
373
|
+
* @param options - Optional field configuration
|
|
374
|
+
*/
|
|
375
|
+
v<Key extends NestedKeyOf<TObject> & string, TFieldBuilder>(path: Key, definition: FieldDefinition<TObject, TPlugins, TypeOfPath<TObject, Key>, TFieldBuilder>, options?: import("../types/field-options").FieldConfig<TypeOfPath<TObject, Key>>): FieldBuilder<TObject, AddFieldTransform<TMap, Key, TypeOfPath<TObject, Key>, ExtractFieldType<TFieldBuilder>>, TPlugins, TDeclaredFields | Key>;
|
|
376
|
+
/**
|
|
377
|
+
* Register a pre-built field rule
|
|
378
|
+
* Tip: Use PluginRegistry to create type-safe field rules
|
|
379
|
+
* @example
|
|
380
|
+
* ```typescript
|
|
381
|
+
* const registry = createPluginRegistry().use(requiredPlugin);
|
|
382
|
+
* const rules = registry.createFieldRules();
|
|
383
|
+
* builder.useField("name", rules.string.required());
|
|
384
|
+
* ```
|
|
385
|
+
* @param path - The field path to validate
|
|
386
|
+
* @param fieldRule - Pre-built validation rule (create with PluginRegistry)
|
|
387
|
+
*/
|
|
388
|
+
useField<Key extends NestedKeyOf<TObject> & string>(path: Key, fieldRule: FieldRule<TypeOfPath<TObject, Key>>): FieldBuilder<TObject, TMap, TPlugins, TDeclaredFields | Key>;
|
|
389
|
+
/**
|
|
390
|
+
* WIP: Enforces strict mode validation
|
|
391
|
+
* @deprecated This is a work in progress and may change in future versions
|
|
392
|
+
*/
|
|
393
|
+
strict(): MissingFields<TObject, TDeclaredFields> extends never ? FieldBuilder<TObject, TMap, TPlugins, TDeclaredFields> : {
|
|
394
|
+
_error: `Missing field declarations in strict mode: ${MissingFields<TObject, TDeclaredFields> & string}`;
|
|
395
|
+
_missingFields: MissingFields<TObject, TDeclaredFields>;
|
|
396
|
+
};
|
|
397
|
+
/**
|
|
398
|
+
* WIP: Alias for strict mode with editor-specific naming
|
|
399
|
+
* @deprecated This is a work in progress and may change in future versions
|
|
400
|
+
*/
|
|
401
|
+
strictOnEditor(): MissingFields<TObject, TDeclaredFields> extends never ? FieldBuilder<TObject, TMap, TPlugins, TDeclaredFields> : {
|
|
402
|
+
_error: `Missing field declarations in strict mode: ${MissingFields<TObject, TDeclaredFields> & string}`;
|
|
403
|
+
_missingFields: MissingFields<TObject, TDeclaredFields>;
|
|
404
|
+
};
|
|
405
|
+
/**
|
|
406
|
+
* Build the final validator
|
|
407
|
+
* WIP: The built validator does not validate unknown properties by default.
|
|
408
|
+
* Use objectAdditionalProperties plugin for strict property validation.
|
|
409
|
+
* @returns A validator function with validate() and parse() methods
|
|
410
|
+
*/
|
|
411
|
+
build(): TransformAwareValidator<TObject, ApplyFieldTransforms<TObject, TMap>>;
|
|
412
|
+
}
|
|
413
|
+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
414
|
+
type FlattenPluginMethods<TPlugins, TObject = any, TCurrentType = any> = UnionToIntersection<ExtractPluginMethods<TPlugins, TObject, TCurrentType>>;
|
|
415
|
+
type ExtractPluginMethods<TPlugins, TObject = any, TCurrentType = any> = TPlugins extends {} ? {
|
|
416
|
+
[K in keyof TPlugins]: TPlugins[K] extends TypedPlugin<any, infer TMethodName, infer TMethod, any, any, any> ? TMethodName extends string ? TMethod extends Function ? {
|
|
417
|
+
[P in TMethodName]: TMethod;
|
|
418
|
+
} : never : never : TPlugins[K] extends ComposablePlugin<any, infer TMethodName, any> ? TMethodName extends string ? {
|
|
419
|
+
[P in TMethodName]: (...args: any[]) => any;
|
|
420
|
+
} : never : TPlugins[K] extends {
|
|
421
|
+
category: "composable-conditional";
|
|
422
|
+
methodName: infer TMethodName;
|
|
423
|
+
} ? TMethodName extends string ? {
|
|
424
|
+
[P in TMethodName]: (...args: any[]) => any;
|
|
425
|
+
} : never : never;
|
|
426
|
+
}[keyof TPlugins] : never;
|
|
427
|
+
type FilterPluginsByType<TPlugins, TType extends TypeName> = {
|
|
428
|
+
[K in keyof TPlugins as TPlugins[K] extends TypedPlugin<any, any, any, infer TAllowedTypes, any, any> ? TAllowedTypes extends readonly TypeName[] ? TType extends TAllowedTypes[number] ? K : never : K : TPlugins[K] extends {
|
|
429
|
+
category: "composable" | "composable-conditional" | "composable-directly";
|
|
430
|
+
allowedTypes: infer TAllowedTypes;
|
|
431
|
+
} ? TAllowedTypes extends readonly TypeName[] ? TType extends TAllowedTypes[number] ? K : never : K : never]: TPlugins[K];
|
|
432
|
+
};
|
|
433
|
+
type IsArrayElementObject<T> = T extends Array<infer U> ? U extends object ? U extends string | number | boolean | Date | null | undefined ? false : true : false : false;
|
|
434
|
+
type HasArrayWithObjectElement<T> = T extends infer U ? IsArrayElementObject<U> extends true ? true : false : false;
|
|
435
|
+
type UnionHasArrayWithObject<T> = T extends any ? HasArrayWithObjectElement<T> extends true ? true : false : false;
|
|
436
|
+
type UnionArrayObjectError = {
|
|
437
|
+
_error: "❌ Union types with Array<object> are not supported by unionGuard. Use individual field declarations instead.";
|
|
438
|
+
_suggestion: "Example: .v('items[*].property', b => b.type.validators()) instead of union guards";
|
|
439
|
+
_reason: "Array<object> requires field-level validation that unionGuard cannot provide";
|
|
440
|
+
};
|
|
441
|
+
export type ValidateUnionType<T> = UnionHasArrayWithObject<T> extends true ? UnionArrayObjectError : T;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Raw validator interface that completely bypasses Result wrapper
|
|
3
|
+
* For maximum performance (1M+ ops/sec)
|
|
4
|
+
*/
|
|
5
|
+
import { UnifiedValidator } from "../optimization/unified-validator";
|
|
6
|
+
import { Result } from "../../types/result";
|
|
7
|
+
import { ValidationOptions, ParseOptions } from "./plugins/plugin-types";
|
|
8
|
+
export interface RawParseResult<T> {
|
|
9
|
+
valid: boolean;
|
|
10
|
+
data?: T;
|
|
11
|
+
error?: any;
|
|
12
|
+
}
|
|
13
|
+
export interface RawValidator<T> {
|
|
14
|
+
validateRaw(value: T, options?: ValidationOptions): boolean;
|
|
15
|
+
parseRaw(value: T, options?: ParseOptions): RawParseResult<T>;
|
|
16
|
+
validate(value: T, options?: ValidationOptions): Result<T>;
|
|
17
|
+
parse(value: T, options?: ParseOptions): Result<T>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Create raw validator that bypasses Result wrapper completely
|
|
21
|
+
*/
|
|
22
|
+
export declare function createRawValidator<T extends Record<string, any>>(validators: Map<string, UnifiedValidator>): RawValidator<T>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Field-level options that are not validation rules but field configuration
|
|
3
|
+
* Field-level settings (not validation rules)
|
|
4
|
+
*/
|
|
5
|
+
export interface FieldOptions<T = any> {
|
|
6
|
+
/**
|
|
7
|
+
* Default value when the field is undefined or null
|
|
8
|
+
* Can be a static value or a function that returns the value
|
|
9
|
+
*/
|
|
10
|
+
default?: T | (() => T);
|
|
11
|
+
/**
|
|
12
|
+
* Whether to apply default to null values (not just undefined)
|
|
13
|
+
* @default true
|
|
14
|
+
*/
|
|
15
|
+
applyDefaultToNull?: boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Field description for documentation
|
|
18
|
+
*/
|
|
19
|
+
description?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Mark field as deprecated
|
|
22
|
+
*/
|
|
23
|
+
deprecated?: boolean | string;
|
|
24
|
+
/**
|
|
25
|
+
* Custom metadata
|
|
26
|
+
*/
|
|
27
|
+
metadata?: Record<string, any>;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Simplified default value type (for shorthand syntax)
|
|
31
|
+
*/
|
|
32
|
+
export type DefaultValue<T> = T | (() => T);
|
|
33
|
+
/**
|
|
34
|
+
* Field configuration: either just default value or full options
|
|
35
|
+
*/
|
|
36
|
+
export type FieldConfig<T> = DefaultValue<T> | FieldOptions<T>;
|
|
37
|
+
/**
|
|
38
|
+
* Helper to normalize field config
|
|
39
|
+
*/
|
|
40
|
+
export declare function normalizeFieldConfig<T>(config?: FieldConfig<T>): FieldOptions<T> | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Apply default value if needed
|
|
43
|
+
*/
|
|
44
|
+
export declare function applyDefault<T>(value: any, options?: FieldOptions<T>, context?: {
|
|
45
|
+
allValues?: any;
|
|
46
|
+
}): any;
|