@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,40 @@
|
|
|
1
|
+
import { ValidationOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* @luq-plugin
|
|
4
|
+
* @name stringPattern
|
|
5
|
+
* @category standard
|
|
6
|
+
* @description Validates that a string matches a regular expression pattern
|
|
7
|
+
* @allowedTypes ["string"]
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Basic usage - validate against regex pattern
|
|
11
|
+
* const validator = Builder()
|
|
12
|
+
* .use(stringPatternPlugin)
|
|
13
|
+
* .for<UserData>()
|
|
14
|
+
* .v("phone", (b) => b.string.pattern(/^\d{3}-\d{3}-\d{4}$/))
|
|
15
|
+
* .v("zipCode", (b) => b.string.pattern(/^\d{5}(-\d{4})?$/))
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // Common patterns
|
|
19
|
+
* builder.v("hexColor", b => b.string.pattern(/^#[0-9A-Fa-f]{6}$/))
|
|
20
|
+
* builder.v("slug", b => b.string.pattern(/^[a-z0-9-]+$/))
|
|
21
|
+
* ```
|
|
22
|
+
* @params
|
|
23
|
+
* - pattern: RegExp - Regular expression to match against
|
|
24
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
25
|
+
* @returns Validation function that returns true if string matches the pattern
|
|
26
|
+
* @customError
|
|
27
|
+
* ```typescript
|
|
28
|
+
* .pattern(/^[A-Z]{2}\d{4}$/, {
|
|
29
|
+
* messageFactory: ({ path, value, params }) =>
|
|
30
|
+
* `${path} must match pattern ${params.pattern} (received: ${value})`
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
* @since 0.1.0-alpha
|
|
34
|
+
*/
|
|
35
|
+
export declare const stringPatternPlugin: import("../..").TypedPlugin<"stringPattern", "pattern", (regex: RegExp | string, options?: ValidationOptions) => {
|
|
36
|
+
check: (value: any) => boolean;
|
|
37
|
+
code: string;
|
|
38
|
+
getErrorMessage: (value: any, path: string) => string;
|
|
39
|
+
params: (string | RegExp | ValidationOptions<{}>)[];
|
|
40
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringRelativeJsonPointer
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates Relative JSON Pointer format (draft-handrews-relative-json-pointer)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringRelativeJsonPointerPlugin)
|
|
11
|
+
* .for<{ pointer: string }>()
|
|
12
|
+
* .v("pointer", (b) => b.string.relativeJsonPointer())
|
|
13
|
+
* .build();
|
|
14
|
+
*
|
|
15
|
+
* // Valid: 0 (current location)
|
|
16
|
+
* // Valid: 1/foo/bar (up 1 level, then to /foo/bar)
|
|
17
|
+
* // Valid: 2/0 (up 2 levels, then to index 0)
|
|
18
|
+
* // Valid: 0# (current location's key/index)
|
|
19
|
+
* ```
|
|
20
|
+
* @params
|
|
21
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
22
|
+
* @returns Validation function that checks Relative JSON Pointer format
|
|
23
|
+
* @customError
|
|
24
|
+
* ```typescript
|
|
25
|
+
* .relativeJsonPointer({
|
|
26
|
+
* messageFactory: ({ path, value }) =>
|
|
27
|
+
* `${path} must be valid Relative JSON Pointer format, received: ${value}`
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
* @since 0.1.0-alpha
|
|
31
|
+
*/
|
|
32
|
+
import type { MessageContext } from "./types";
|
|
33
|
+
export declare const stringRelativeJsonPointerPlugin: import("../..").TypedPlugin<"stringRelativeJsonPointer", "relativeJsonPointer", (options?: {
|
|
34
|
+
messageFactory?: (context: MessageContext) => string;
|
|
35
|
+
}) => {
|
|
36
|
+
check: (value: string) => boolean;
|
|
37
|
+
code: string;
|
|
38
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
39
|
+
params: {
|
|
40
|
+
messageFactory?: (context: MessageContext) => string;
|
|
41
|
+
}[];
|
|
42
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ValidationOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* @luq-plugin
|
|
4
|
+
* @name stringStartsWith
|
|
5
|
+
* @category standard
|
|
6
|
+
* @description Validates that a string begins with a specific prefix
|
|
7
|
+
* @allowedTypes ["string"]
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Basic usage - checks if string starts with prefix
|
|
11
|
+
* const validator = Builder()
|
|
12
|
+
* .use(stringStartsWithPlugin)
|
|
13
|
+
* .for<ApiData>()
|
|
14
|
+
* .v("url", (b) => b.string.startsWith("https://"))
|
|
15
|
+
* .v("apiKey", (b) => b.string.required().startsWith("sk_"))
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // For protocol validation
|
|
19
|
+
* builder.v("secureUrl", b => b.string.startsWith("https://").url())
|
|
20
|
+
*
|
|
21
|
+
* // For ID prefixes
|
|
22
|
+
* builder.v("orderId", b => b.string.startsWith("ORD-").pattern(/^ORD-\d{8}$/))
|
|
23
|
+
* ```
|
|
24
|
+
* @params
|
|
25
|
+
* - prefix: string - The prefix that the string must start with
|
|
26
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
27
|
+
* @returns Validation function that returns true if string starts with the prefix
|
|
28
|
+
* @customError
|
|
29
|
+
* ```typescript
|
|
30
|
+
* .startsWith("REF-", {
|
|
31
|
+
* messageFactory: ({ path, value, params }) =>
|
|
32
|
+
* `${path} must start with '${params.prefix}' (received: ${value})`
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
* @since 0.1.0-alpha
|
|
36
|
+
*/
|
|
37
|
+
export declare const stringStartsWithPlugin: import("../..").TypedPlugin<"stringStartsWith", "startsWith", (prefix: string, options?: ValidationOptions) => {
|
|
38
|
+
check: (value: any) => boolean;
|
|
39
|
+
code: string;
|
|
40
|
+
getErrorMessage: (value: any, path: string) => string;
|
|
41
|
+
params: (string | ValidationOptions<{}>)[];
|
|
42
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringTime
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates time format (HH:MM:SS or HH:MM:SS.mmm)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringTimePlugin)
|
|
11
|
+
* .for<{ startTime: string }>()
|
|
12
|
+
* .v("startTime", (b) => b.string.time())
|
|
13
|
+
* .build();
|
|
14
|
+
* ```
|
|
15
|
+
* @params
|
|
16
|
+
* - options?: { messageFactory?: (context: MessageContext) => string; allowMilliseconds?: boolean } - Optional configuration
|
|
17
|
+
* @returns Validation function that checks time format
|
|
18
|
+
* @customError
|
|
19
|
+
* ```typescript
|
|
20
|
+
* .time({
|
|
21
|
+
* messageFactory: ({ path, value }) =>
|
|
22
|
+
* `${path} must be a valid time format, received: ${value}`
|
|
23
|
+
* })
|
|
24
|
+
* ```
|
|
25
|
+
* @since 0.1.0-alpha
|
|
26
|
+
*/
|
|
27
|
+
import type { MessageContext } from "./types";
|
|
28
|
+
export declare const stringTimePlugin: import("../..").TypedPlugin<"stringTime", "time", (options?: {
|
|
29
|
+
messageFactory?: (context: MessageContext) => string;
|
|
30
|
+
allowMilliseconds?: boolean;
|
|
31
|
+
}) => {
|
|
32
|
+
check: (value: string) => boolean;
|
|
33
|
+
code: string;
|
|
34
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
35
|
+
params: {
|
|
36
|
+
messageFactory?: (context: MessageContext) => string;
|
|
37
|
+
allowMilliseconds?: boolean;
|
|
38
|
+
}[];
|
|
39
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringUriTemplate
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates URI Template format (RFC 6570)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringUriTemplatePlugin)
|
|
11
|
+
* .for<{ template: string }>()
|
|
12
|
+
* .v("template", (b) => b.string.uriTemplate())
|
|
13
|
+
* .build();
|
|
14
|
+
*
|
|
15
|
+
* // Valid: https://api.example.com/users/{id}
|
|
16
|
+
* // Valid: /search{?q,lang}
|
|
17
|
+
* // Valid: /path{/segments*}
|
|
18
|
+
* // Valid: {+path}/here
|
|
19
|
+
* // Valid: {#section}
|
|
20
|
+
* ```
|
|
21
|
+
* @params
|
|
22
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
23
|
+
* @returns Validation function that checks URI Template format
|
|
24
|
+
* @customError
|
|
25
|
+
* ```typescript
|
|
26
|
+
* .uriTemplate({
|
|
27
|
+
* messageFactory: ({ path, value }) =>
|
|
28
|
+
* `${path} must be a valid URI Template, received: ${value}`
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
* @since 0.1.0-alpha
|
|
32
|
+
*/
|
|
33
|
+
import type { MessageContext } from "./types";
|
|
34
|
+
export declare const stringUriTemplatePlugin: import("../..").TypedPlugin<"stringUriTemplate", "uriTemplate", (options?: {
|
|
35
|
+
messageFactory?: (context: MessageContext) => string;
|
|
36
|
+
}) => {
|
|
37
|
+
check: (value: string) => boolean;
|
|
38
|
+
code: string;
|
|
39
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
40
|
+
params: {
|
|
41
|
+
messageFactory?: (context: MessageContext) => string;
|
|
42
|
+
}[];
|
|
43
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { ValidationOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* @luq-plugin
|
|
4
|
+
* @name stringUrl
|
|
5
|
+
* @category standard
|
|
6
|
+
* @description Validates that a string is a valid URL format
|
|
7
|
+
* @allowedTypes ["string"]
|
|
8
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/URL - MDN URL API Reference
|
|
9
|
+
* @see https://tools.ietf.org/html/rfc3986 - RFC 3986: Uniform Resource Identifier (URI) Generic Syntax
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Basic usage - validates all URL formats (RFC 3986 compliant)
|
|
13
|
+
* const validator = Builder()
|
|
14
|
+
* .use(stringUrlPlugin)
|
|
15
|
+
* .for<UserProfile>()
|
|
16
|
+
* .v("website", (b) => b.string.url())
|
|
17
|
+
* .v("profileUrl", (b) => b.string.required().url())
|
|
18
|
+
* .build();
|
|
19
|
+
*
|
|
20
|
+
* // Custom protocols (e.g., allow ftp://)
|
|
21
|
+
* builder.v("ftpServer", b => b.string.url({
|
|
22
|
+
* protocols: ['ftp:', 'ftps:']
|
|
23
|
+
* }))
|
|
24
|
+
*
|
|
25
|
+
* // Allow URLs without protocol (assumes https://)
|
|
26
|
+
* builder.v("domain", b => b.string.url({
|
|
27
|
+
* allowWithoutProtocol: true
|
|
28
|
+
* }))
|
|
29
|
+
*
|
|
30
|
+
* // ✅ VALID URL formats (RFC 3986)
|
|
31
|
+
* validator.parse({ website: "https://example.com" }); // Standard HTTPS
|
|
32
|
+
* validator.parse({ website: "http://www.test.co.uk/path?q=value#frag" }); // Full URL with query and fragment
|
|
33
|
+
* validator.parse({ website: "ftp://files.domain.com/file.txt" }); // FTP protocol
|
|
34
|
+
* validator.parse({ website: "ws://localhost:3000" }); // WebSocket protocol
|
|
35
|
+
* validator.parse({ website: "https://subdomain.example.com:8080/api" }); // With port and path
|
|
36
|
+
* validator.parse({ website: "https://127.0.0.1:3000" }); // IP address
|
|
37
|
+
* validator.parse({ website: "https://[::1]:8080" }); // IPv6 address
|
|
38
|
+
* validator.parse({ website: "mailto:user@example.com" }); // mailto protocol
|
|
39
|
+
* validator.parse({ website: "tel:+1-555-123-4567" }); // tel protocol
|
|
40
|
+
* validator.parse({ website: "https://user:pass@example.com" }); // With credentials
|
|
41
|
+
*
|
|
42
|
+
* // With allowWithoutProtocol: true
|
|
43
|
+
* const flexValidator = builder.v("site", b => b.string.url({ allowWithoutProtocol: true }));
|
|
44
|
+
* flexValidator.parse({ site: "example.com" }); // Assumes https://
|
|
45
|
+
* flexValidator.parse({ site: "www.domain.co.uk/path" }); // Assumes https://
|
|
46
|
+
*
|
|
47
|
+
* // ❌ INVALID URL formats
|
|
48
|
+
* validator.parse({ website: "not-a-url" }); // Plain text
|
|
49
|
+
* validator.parse({ website: "http://" }); // Missing host
|
|
50
|
+
* validator.parse({ website: "://missing-protocol" }); // Missing protocol
|
|
51
|
+
* validator.parse({ website: "https://" }); // Missing host after protocol
|
|
52
|
+
* validator.parse({ website: "http://.com" }); // Invalid host
|
|
53
|
+
* validator.parse({ website: "https://example." }); // Incomplete domain
|
|
54
|
+
* validator.parse({ website: "just text with spaces" }); // Contains spaces
|
|
55
|
+
* validator.parse({ website: "ftp://[invalid-ipv6]" }); // Invalid IPv6
|
|
56
|
+
* validator.parse({ website: "https://exam ple.com" }); // Space in domain
|
|
57
|
+
* validator.parse({ website: "" }); // Empty string
|
|
58
|
+
* ```
|
|
59
|
+
* @params
|
|
60
|
+
* - options?: StringUrlOptions - URL validation configuration
|
|
61
|
+
* - protocols?: string[] - Allowed protocols (default: all protocols allowed)
|
|
62
|
+
* - allowWithoutProtocol?: boolean - Allow URLs without protocol (default: false)
|
|
63
|
+
* - messageFactory?: (context: MessageContext) => string - Custom error message factory
|
|
64
|
+
* @returns Validation function that returns true if string is a valid URL
|
|
65
|
+
* @customError
|
|
66
|
+
* ```typescript
|
|
67
|
+
* .url({
|
|
68
|
+
* messageFactory: ({ path, value }) =>
|
|
69
|
+
* `${path} must be a valid URL (received: ${value})`
|
|
70
|
+
* })
|
|
71
|
+
*
|
|
72
|
+
* // Restrict to specific protocols
|
|
73
|
+
* .url({
|
|
74
|
+
* protocols: ['https:'],
|
|
75
|
+
* messageFactory: ({ path }) => `${path} must be a secure HTTPS URL`
|
|
76
|
+
* })
|
|
77
|
+
* ```
|
|
78
|
+
* @since 0.1.0-alpha
|
|
79
|
+
*/
|
|
80
|
+
export interface StringUrlOptions extends ValidationOptions {
|
|
81
|
+
/**
|
|
82
|
+
* Array of allowed protocols. Default: null (allow all protocols)
|
|
83
|
+
* @example ['http:', 'https:', 'ftp:', 'ws:', 'wss:']
|
|
84
|
+
*/
|
|
85
|
+
protocols?: string[];
|
|
86
|
+
/**
|
|
87
|
+
* Whether to allow URLs without protocol (will default to https://)
|
|
88
|
+
* @default false
|
|
89
|
+
*/
|
|
90
|
+
allowWithoutProtocol?: boolean;
|
|
91
|
+
}
|
|
92
|
+
export declare const stringUrlPlugin: import("../..").TypedPlugin<"stringUrl", "url", (options?: StringUrlOptions) => {
|
|
93
|
+
check: (value: any) => boolean;
|
|
94
|
+
code: string;
|
|
95
|
+
getErrorMessage: (value: any, path: string) => string;
|
|
96
|
+
params: StringUrlOptions[];
|
|
97
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test utilities for plugin testing
|
|
3
|
+
*/
|
|
4
|
+
export declare const createMockReporter: () => {
|
|
5
|
+
report: jest.Mock<any, any, any>;
|
|
6
|
+
getReports: jest.Mock<any[], [], any>;
|
|
7
|
+
};
|
|
8
|
+
export declare const createMockContext: (path?: string) => {
|
|
9
|
+
path: string;
|
|
10
|
+
reporter: {
|
|
11
|
+
report: jest.Mock<any, any, any>;
|
|
12
|
+
getReports: jest.Mock<any[], [], any>;
|
|
13
|
+
};
|
|
14
|
+
allValues: {};
|
|
15
|
+
};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform type restriction utilities
|
|
3
|
+
* Due to nested array support implementation, transform of Array<object> and Array<union>
|
|
4
|
+
* is no longer supported, so we restrict it at the type level.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Type helper to determine if it's a Union type
|
|
8
|
+
* Uses the properties of distributive conditional types for detection
|
|
9
|
+
*/
|
|
10
|
+
type IsUnionType<T, U = T> = T extends any ? [U] extends [T] ? false : true : false;
|
|
11
|
+
/**
|
|
12
|
+
* Use distributive conditional types to check if Union elements are plain objects
|
|
13
|
+
* Result becomes boolean union (e.g., false | true)
|
|
14
|
+
*/
|
|
15
|
+
type UnionMemberCheck<T> = T extends any ? T extends Record<string, any> ? T extends (...args: any[]) => any ? false : T extends readonly any[] ? false : T extends Date ? false : T extends RegExp ? false : T extends string | number | boolean | null | undefined ? false : true : false : false;
|
|
16
|
+
/**
|
|
17
|
+
* Accurately determine if a Union type contains plain objects
|
|
18
|
+
* If true is included in the result, it's a Union containing plain objects
|
|
19
|
+
*/
|
|
20
|
+
type UnionHasPlainObject<T> = true extends UnionMemberCheck<T> ? true : false;
|
|
21
|
+
/**
|
|
22
|
+
* More accurate approach: Detect Union type first then process
|
|
23
|
+
*/
|
|
24
|
+
type ArrayElementIsObjectOrUnion<T> = T extends readonly (infer U)[] ? IsUnionType<U> extends true ? UnionHasPlainObject<U> extends true ? true : false : U extends Record<string, any> ? U extends (...args: any[]) => any ? false : U extends readonly any[] ? false : U extends Date ? false : U extends RegExp ? false : U extends string | number | boolean | null | undefined ? false : true : false : false;
|
|
25
|
+
/**
|
|
26
|
+
* Determine if the type is forbidden as a Transform return value
|
|
27
|
+
*/
|
|
28
|
+
export type IsForbiddenTransformOutput<T> = T extends readonly any[] ? ArrayElementIsObjectOrUnion<T> extends true ? true : false : false;
|
|
29
|
+
/**
|
|
30
|
+
* Concise and clear English instruction message for forbidden Transform return types
|
|
31
|
+
* Includes specific instructions displayed in TypeScript errors
|
|
32
|
+
*/
|
|
33
|
+
export type ForbiddenTransformError<T> = T extends readonly (infer U)[] ? U extends Record<string, any> ? U extends (...args: any[]) => any | readonly any[] | Date | RegExp ? never : `🚫 FORBIDDEN: Cannot transform to Array<object>. Use Array<primitive> instead. Example: .transform(arr => arr.map(s => s.toUpperCase())) returns string[]` : `🚫 FORBIDDEN: Cannot transform to Array<union with object>. Use Array<primitive> instead. Example: .transform(arr => arr.map(s => s.length)) returns number[]` : never;
|
|
34
|
+
/**
|
|
35
|
+
* Conditional type to validate Transform function return type
|
|
36
|
+
*/
|
|
37
|
+
export type ValidateTransformOutput<T> = IsForbiddenTransformOutput<T> extends true ? ForbiddenTransformError<T> : T;
|
|
38
|
+
/**
|
|
39
|
+
* Safe Transform function type definition
|
|
40
|
+
* Returns error type for forbidden return types, otherwise returns normal function type
|
|
41
|
+
*/
|
|
42
|
+
export type SafeTransformFunction<TInput, TOutput> = IsForbiddenTransformOutput<TOutput> extends true ? ForbiddenTransformError<TOutput> : (value: TInput) => TOutput;
|
|
43
|
+
/**
|
|
44
|
+
* More direct type checking used in actual plugin implementations
|
|
45
|
+
*/
|
|
46
|
+
export type RestrictedTransformFunction<TInput = any, TOutput = any> = TOutput extends readonly any[] ? ArrayElementIsObjectOrUnion<TOutput> extends true ? ForbiddenTransformError<TOutput> : (value: TInput) => TOutput : (value: TInput) => TOutput;
|
|
47
|
+
/**
|
|
48
|
+
* Utility type for displaying Transform function type check results
|
|
49
|
+
*/
|
|
50
|
+
export type CheckTransformFunction<F> = F extends (value: any) => infer R ? IsForbiddenTransformOutput<R> extends true ? {
|
|
51
|
+
_status: "❌ FORBIDDEN";
|
|
52
|
+
_type: R;
|
|
53
|
+
_error: ForbiddenTransformError<R>;
|
|
54
|
+
} : {
|
|
55
|
+
_status: "✅ ALLOWED";
|
|
56
|
+
_type: R;
|
|
57
|
+
} : {
|
|
58
|
+
_status: "❓ UNKNOWN";
|
|
59
|
+
_error: "Not a valid transform function";
|
|
60
|
+
};
|
|
61
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name transform
|
|
4
|
+
* @category transform
|
|
5
|
+
* @description Transforms values after successful validation (type conversion, normalization, computed values)
|
|
6
|
+
* @allowedTypes ["string", "number", "boolean", "array", "object", "date", "union"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // String transformation (lowercase)
|
|
10
|
+
* const validator = Builder()
|
|
11
|
+
* .use(transformPlugin)
|
|
12
|
+
* .for<UserData>()
|
|
13
|
+
* .v("email", (b) =>
|
|
14
|
+
* b.string.required().email().transform(v => v.toLowerCase())
|
|
15
|
+
* )
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // Number to string conversion
|
|
19
|
+
* builder.v("age", b =>
|
|
20
|
+
* b.number.required().min(0).transform(v => String(v))
|
|
21
|
+
* )
|
|
22
|
+
*
|
|
23
|
+
* // Array element transformation
|
|
24
|
+
* builder.v("tags", b =>
|
|
25
|
+
* b.array.transform(tags => tags.map(t => t.trim().toLowerCase()))
|
|
26
|
+
* )
|
|
27
|
+
* ```
|
|
28
|
+
* @params
|
|
29
|
+
* - transformFn: (value: T) => U - Transform function that takes input value and returns transformed value
|
|
30
|
+
* @returns Validation function with transformation
|
|
31
|
+
* @customError
|
|
32
|
+
* Transform plugin does not generate errors. Errors in transform function are treated as exceptions.
|
|
33
|
+
* @since 0.1.0-alpha
|
|
34
|
+
*/
|
|
35
|
+
export declare const transformPlugin: import("../..").TypedPlugin<"transform", "transform", import("../builder/plugins/plugin-interfaces").TransformPluginImplementation<any, any>, readonly ["string", "number", "boolean", "array", "object", "date", "union"], "validator", "transform">;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name tupleBuilder
|
|
4
|
+
* @category composable-directly
|
|
5
|
+
* @description Validates tuple types (fixed-length arrays with different types for each element)
|
|
6
|
+
* @allowedTypes ["tuple"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* // Fixed-length tuple - no options needed
|
|
10
|
+
* type Coordinates = [number, number];
|
|
11
|
+
*
|
|
12
|
+
* const validator = Builder()
|
|
13
|
+
* .use(tupleBuilderPlugin)
|
|
14
|
+
* .for<{ location: Coordinates }>()
|
|
15
|
+
* .v("location", (b) => b.tuple
|
|
16
|
+
* .required()
|
|
17
|
+
* .builder(
|
|
18
|
+
* (a) => a.number.required().min(0),
|
|
19
|
+
* (b) => b.number.required().min(0)
|
|
20
|
+
* )
|
|
21
|
+
* )
|
|
22
|
+
* .build();
|
|
23
|
+
*
|
|
24
|
+
* // Variable-length tuple with rest elements
|
|
25
|
+
* type UserData = [string, number, boolean, ...string[]];
|
|
26
|
+
*
|
|
27
|
+
* const userValidator = Builder()
|
|
28
|
+
* .use(tupleBuilderPlugin)
|
|
29
|
+
* .for<{ data: UserData }>()
|
|
30
|
+
* .v("data", (b) => b.tuple
|
|
31
|
+
* .required()
|
|
32
|
+
* .builder(
|
|
33
|
+
* (a) => a.string.required().min(3), // name
|
|
34
|
+
* (b) => b.number.required().min(0), // age
|
|
35
|
+
* (c) => c.boolean.required(), // isActive
|
|
36
|
+
* { rest: (r) => r.string.optional() } // rest elements
|
|
37
|
+
* )
|
|
38
|
+
* )
|
|
39
|
+
* .build();
|
|
40
|
+
* ```
|
|
41
|
+
* @params
|
|
42
|
+
* - ...builderFns: Array<(context: FieldBuilderContext) => any> - Builder functions for each tuple element
|
|
43
|
+
* - options?: { rest?: (context: FieldBuilderContext) => any } - Optional configuration (automatically defaults to {} when omitted)
|
|
44
|
+
* @returns Composable validation function
|
|
45
|
+
* @customError
|
|
46
|
+
* - Returns false if value is not an array
|
|
47
|
+
* - Returns false if array length doesn't match tuple definition (without rest)
|
|
48
|
+
* - Returns false if any element validation fails
|
|
49
|
+
* @since 0.1.0-alpha
|
|
50
|
+
*/
|
|
51
|
+
import type { FieldBuilderContext } from "../builder/plugins/plugin-types";
|
|
52
|
+
export interface TupleBuilderFunction<TObject extends object, TPlugins> {
|
|
53
|
+
(context: FieldBuilderContext<TObject, TPlugins, any>): any;
|
|
54
|
+
}
|
|
55
|
+
export interface RestBuilderFunction<TObject extends object, TPlugins> {
|
|
56
|
+
(context: FieldBuilderContext<TObject, TPlugins, any>): any;
|
|
57
|
+
}
|
|
58
|
+
export interface TupleBuilderOptions<TObject extends object, TPlugins> {
|
|
59
|
+
rest?: RestBuilderFunction<TObject, TPlugins>;
|
|
60
|
+
messageFactory?: {
|
|
61
|
+
notArray?: (value: unknown) => string;
|
|
62
|
+
lengthMismatch?: (expected: number, actual: number) => string;
|
|
63
|
+
tooShort?: (minimum: number, actual: number) => string;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export declare const tupleBuilderPlugin: import("../builder/plugins/composable-directly-plugin").ComposableDirectlyPlugin<"tupleBuilder", "builder", readonly ["tuple"]>;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { NestedKeyOf } from "../../types";
|
|
2
|
+
import { TypeName, TypeMapping } from "../builder/plugins/plugin-types";
|
|
3
|
+
export { NestedKeyOf };
|
|
4
|
+
export type ExtractTypes<T extends readonly TypeName[]> = TypeMapping[T[number]];
|
|
5
|
+
export declare const SEVERITY: {
|
|
6
|
+
readonly INFO: "INFO";
|
|
7
|
+
readonly WARN: "WARN";
|
|
8
|
+
readonly ERROR: "ERROR";
|
|
9
|
+
};
|
|
10
|
+
export type Severity = (typeof SEVERITY)[keyof typeof SEVERITY];
|
|
11
|
+
/**
|
|
12
|
+
* Zod-style issue factory for generating validation errors
|
|
13
|
+
* @param ctx - Context object containing field path, value, and other metadata
|
|
14
|
+
* @returns Error message string
|
|
15
|
+
*/
|
|
16
|
+
export type MessageFactory<TContext extends Record<string, any> = {}> = (ctx: MessageContext & TContext) => string;
|
|
17
|
+
/**
|
|
18
|
+
* Base context provided to all issue factories
|
|
19
|
+
*/
|
|
20
|
+
export interface MessageContext {
|
|
21
|
+
path: string;
|
|
22
|
+
value: any;
|
|
23
|
+
code: string;
|
|
24
|
+
}
|
|
25
|
+
export interface ValidationOptions<TContext extends Record<string, any> = {}> {
|
|
26
|
+
code?: string;
|
|
27
|
+
fieldName?: string;
|
|
28
|
+
severity?: Severity;
|
|
29
|
+
messageFactory?: MessageFactory<TContext>;
|
|
30
|
+
}
|
|
31
|
+
export interface RecursiveContext<TObject = any> {
|
|
32
|
+
currentDepth: number;
|
|
33
|
+
rootObject: TObject;
|
|
34
|
+
parent?: any;
|
|
35
|
+
current: any;
|
|
36
|
+
}
|
|
37
|
+
export interface ValidationContext<TObject, TInput> {
|
|
38
|
+
originalValue: TInput;
|
|
39
|
+
currentValue: TInput;
|
|
40
|
+
allValues: TObject;
|
|
41
|
+
path: string;
|
|
42
|
+
recursiveContext?: RecursiveContext<TObject>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Context provided to conditional validation functions when validating array items
|
|
46
|
+
* Contains information about the current array index and the object at that index
|
|
47
|
+
*/
|
|
48
|
+
export interface ArrayContext<TItem = any> {
|
|
49
|
+
/** The current index in the array */
|
|
50
|
+
index: number;
|
|
51
|
+
/** The object at the current index */
|
|
52
|
+
item: TItem;
|
|
53
|
+
/** The full array being validated */
|
|
54
|
+
array: TItem[];
|
|
55
|
+
}
|
|
56
|
+
export interface ValidationFunctionReturnType {
|
|
57
|
+
valid: boolean;
|
|
58
|
+
message?: string;
|
|
59
|
+
}
|
|
60
|
+
export type ValidationResult = ValidationFunctionReturnType;
|
|
61
|
+
export interface TransformFunctionReturnType<TOutput> extends ValidationFunctionReturnType {
|
|
62
|
+
transformData?: TOutput;
|
|
63
|
+
}
|
|
64
|
+
export type ValidationFunction<TObject, TInputTypes extends readonly TypeName[] | TypeName> = (value: TInputTypes extends readonly TypeName[] ? TInputTypes[number] extends TypeName ? import("../builder/plugins/plugin-types").TypeMapping[TInputTypes[number]] : never : TInputTypes extends TypeName ? import("../builder/plugins/plugin-types").TypeMapping[TInputTypes] : never, ctx: ValidationContext<TObject, TInputTypes extends readonly TypeName[] ? TInputTypes[number] : TInputTypes>) => ValidationFunctionReturnType;
|
|
65
|
+
export type TransformFunction<TObject, TInputTypes extends readonly TypeName[] | TypeName> = <TOutput>(value: TInputTypes extends readonly TypeName[] ? TInputTypes[number] extends TypeName ? import("../builder/plugins/plugin-types").TypeMapping[TInputTypes[number]] : any : TInputTypes extends TypeName ? import("../builder/plugins/plugin-types").TypeMapping[TInputTypes] : any, ctx: ValidationContext<TObject, TInputTypes extends readonly TypeName[] ? TInputTypes[number] : TInputTypes>) => TransformFunctionReturnType<TOutput>;
|
|
66
|
+
/**
|
|
67
|
+
* Indicates that all remaining validations should be skipped
|
|
68
|
+
* Used by: validateIf, skip
|
|
69
|
+
*/
|
|
70
|
+
export interface SkipAllValidationFlag {
|
|
71
|
+
__skipAllValidation: true;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Indicates that further validations should be skipped (but not transforms)
|
|
75
|
+
* Used by: optional, optionalIf
|
|
76
|
+
*/
|
|
77
|
+
export interface SkipFurtherValidationFlag {
|
|
78
|
+
__skipFurtherValidation: true;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Indicates that this is a transform operation
|
|
82
|
+
* Used by: transform
|
|
83
|
+
*/
|
|
84
|
+
export interface TransformFlag<TOutput = any> {
|
|
85
|
+
__isTransform: true;
|
|
86
|
+
__transformFn: (value: any) => TOutput;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Indicates that the field is nullable
|
|
90
|
+
* Used by: nullable
|
|
91
|
+
*/
|
|
92
|
+
export interface NullableFlag {
|
|
93
|
+
__isNullable: true;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Indicates that the validation should be recursive
|
|
97
|
+
* Used by: objectRecursively
|
|
98
|
+
*/
|
|
99
|
+
export interface RecursiveFlag {
|
|
100
|
+
__isRecursive: true;
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Combined validation result with optional flags
|
|
104
|
+
*/
|
|
105
|
+
export type ValidationResultWithFlags<TFlags = {}> = ValidationFunctionReturnType & TFlags;
|
|
106
|
+
/**
|
|
107
|
+
* Helper type to create validation results with flags
|
|
108
|
+
*/
|
|
109
|
+
export type WithFlags<TFlags> = {
|
|
110
|
+
valid: boolean;
|
|
111
|
+
message?: string;
|
|
112
|
+
} & TFlags;
|
|
113
|
+
/**
|
|
114
|
+
* Type guards for checking flags
|
|
115
|
+
*/
|
|
116
|
+
export declare const ValidationFlags: {
|
|
117
|
+
isSkipAll(result: any): result is ValidationResultWithFlags<SkipAllValidationFlag>;
|
|
118
|
+
isSkipFurther(result: any): result is ValidationResultWithFlags<SkipFurtherValidationFlag>;
|
|
119
|
+
isTransform(result: any): result is ValidationResultWithFlags<TransformFlag>;
|
|
120
|
+
isNullable(result: any): result is ValidationResultWithFlags<NullableFlag>;
|
|
121
|
+
isRecursive(result: any): result is ValidationResultWithFlags<RecursiveFlag>;
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Conditional method signature that preserves the TObject type
|
|
125
|
+
*/
|
|
126
|
+
export type ConditionalMethod<TObject = any> = {
|
|
127
|
+
validateIf?: (condition: (allValues: TObject, arrayContext?: ArrayContext) => boolean, options?: ValidationOptions) => ValidationFunction<any, any>;
|
|
128
|
+
requiredIf?: (condition: (allValues: TObject, arrayContext?: ArrayContext) => boolean, options?: ValidationOptions) => ValidationFunction<any, any>;
|
|
129
|
+
optionalIf?: (condition: (allValues: TObject, arrayContext?: ArrayContext) => boolean, options?: ValidationOptions) => ValidationFunction<any, any>;
|
|
130
|
+
skip?: (condition: (allValues: TObject, arrayContext?: ArrayContext) => boolean, options?: ValidationOptions) => ValidationFunction<any, any>;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Type helper to create properly typed conditional plugin methods
|
|
134
|
+
*/
|
|
135
|
+
export type WithConditionalMethods<TMethods extends Record<string, any>, TObject> = {
|
|
136
|
+
[K in keyof TMethods]: K extends keyof ConditionalMethod<TObject> ? ConditionalMethod<TObject>[K] : TMethods[K];
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Type for validateIf plugin methods
|
|
140
|
+
*/
|
|
141
|
+
export type ValidateIfMethods<TObject = any> = {
|
|
142
|
+
validateIf: (condition: (allValues: TObject, arrayContext?: ArrayContext) => boolean, options?: ValidationOptions) => ValidationFunction<any, any>;
|
|
143
|
+
};
|