@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,42 @@
|
|
|
1
|
+
import { ValidationOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* @luq-plugin
|
|
4
|
+
* @name stringAlphanumeric
|
|
5
|
+
* @category standard
|
|
6
|
+
* @description Validates that a string contains only alphanumeric characters (letters and numbers)
|
|
7
|
+
* @allowedTypes ["string"]
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Basic usage - only letters and numbers allowed
|
|
11
|
+
* const validator = Builder()
|
|
12
|
+
* .use(stringAlphanumericPlugin)
|
|
13
|
+
* .for<UserData>()
|
|
14
|
+
* .v("username", (b) => b.string.alphanumeric())
|
|
15
|
+
* .v("userId", (b) => b.string.required().alphanumeric())
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // Allow spaces in addition to alphanumeric characters
|
|
19
|
+
* builder.v("displayName", b => b.string.alphanumeric(true))
|
|
20
|
+
*
|
|
21
|
+
* // Combined with length validation
|
|
22
|
+
* builder.v("productCode", b => b.string.alphanumeric().min(3).max(20))
|
|
23
|
+
* ```
|
|
24
|
+
* @params
|
|
25
|
+
* - allowSpaces?: boolean - Whether to allow spaces (default: false)
|
|
26
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
27
|
+
* @returns Validation function that returns true if string contains only allowed characters
|
|
28
|
+
* @customError
|
|
29
|
+
* ```typescript
|
|
30
|
+
* .alphanumeric(false, {
|
|
31
|
+
* messageFactory: ({ path, value }) =>
|
|
32
|
+
* `${path} must contain only letters and numbers (received: ${value})`
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
* @since 0.1.0-alpha
|
|
36
|
+
*/
|
|
37
|
+
export declare const stringAlphanumericPlugin: import("../..").TypedPlugin<"stringAlphanumeric", "alphanumeric", (allowSpaces?: boolean, options?: ValidationOptions) => {
|
|
38
|
+
check: (value: any) => boolean;
|
|
39
|
+
code: string;
|
|
40
|
+
getErrorMessage: (value: any, path: string) => string;
|
|
41
|
+
params: (boolean | ValidationOptions<{}>)[];
|
|
42
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringBase64
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates base64 encoded string
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @see https://tools.ietf.org/html/rfc4648 - RFC 4648: The Base16, Base32, and Base64 Data Encodings
|
|
8
|
+
* @see https://developer.mozilla.org/en-US/docs/Glossary/Base64 - MDN Base64 Encoding Reference
|
|
9
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/btoa - MDN btoa() Function
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Basic usage - validates base64 encoded string (RFC 4648 compliant)
|
|
13
|
+
* const validator = Builder()
|
|
14
|
+
* .use(stringBase64Plugin)
|
|
15
|
+
* .for<{ encodedData: string }>()
|
|
16
|
+
* .v("encodedData", (b) => b.string.base64())
|
|
17
|
+
* .build();
|
|
18
|
+
*
|
|
19
|
+
* // URL-safe base64 validation
|
|
20
|
+
* const urlSafeValidator = Builder()
|
|
21
|
+
* .use(stringBase64Plugin)
|
|
22
|
+
* .for<{ token: string }>()
|
|
23
|
+
* .v("token", (b) => b.string.base64({ urlSafe: true }))
|
|
24
|
+
* .build();
|
|
25
|
+
*
|
|
26
|
+
* // ✅ VALID base64 strings (RFC 4648)
|
|
27
|
+
* // Standard base64 encoding
|
|
28
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ=" }); // "Hello World"
|
|
29
|
+
* validator.parse({ encodedData: "YW55IGNhcm5hbCBwbGVhc3VyZS4=" }); // "any carnal pleasure."
|
|
30
|
+
* validator.parse({ encodedData: "" }); // Empty string
|
|
31
|
+
* validator.parse({ encodedData: "YQ==" }); // Single char "a"
|
|
32
|
+
* validator.parse({ encodedData: "YWI=" }); // Two chars "ab"
|
|
33
|
+
* validator.parse({ encodedData: "YWJj" }); // Three chars "abc"
|
|
34
|
+
* validator.parse({ encodedData: "YWJjZA==" }); // Four chars "abcd"
|
|
35
|
+
* validator.parse({ encodedData: "VGhpcyBpcyBhIHRlc3Q=" }); // "This is a test"
|
|
36
|
+
*
|
|
37
|
+
* // With numbers and special base64 characters
|
|
38
|
+
* validator.parse({ encodedData: "MTIzNDU2Nzg5MA==" }); // "1234567890"
|
|
39
|
+
* validator.parse({ encodedData: "QUJDREVGRw==" }); // "ABCDEFG"
|
|
40
|
+
* validator.parse({ encodedData: "YWJjZGVmZ2hpams=" }); // "abcdefghijk"
|
|
41
|
+
* validator.parse({ encodedData: "Pz8/Pz8/Pz8=" }); // Contains + and / chars
|
|
42
|
+
* validator.parse({ encodedData: "+/+/+/+/+/+=" }); // All special chars
|
|
43
|
+
*
|
|
44
|
+
* // Different padding scenarios
|
|
45
|
+
* validator.parse({ encodedData: "YWI=" }); // One padding char
|
|
46
|
+
* validator.parse({ encodedData: "YQ==" }); // Two padding chars
|
|
47
|
+
* validator.parse({ encodedData: "YWJj" }); // No padding needed
|
|
48
|
+
* validator.parse({ encodedData: "YWJjZA==" }); // Two padding chars
|
|
49
|
+
*
|
|
50
|
+
* // URL-safe base64 (RFC 4648 Section 5)
|
|
51
|
+
* urlSafeValidator.parse({ token: "SGVsbG8gV29ybGQ" }); // URL-safe without padding
|
|
52
|
+
* urlSafeValidator.parse({ token: "SGVsbG8gV29ybGQ=" }); // URL-safe with padding
|
|
53
|
+
* urlSafeValidator.parse({ token: "YW55IGNhcm5hbC1wbGVhc3VyZS4" }); // Uses - instead of /
|
|
54
|
+
* urlSafeValidator.parse({ token: "YWJjZGVmZ2hpams_" }); // Uses _ instead of +
|
|
55
|
+
* urlSafeValidator.parse({ token: "-_-_-_-_-_-_" }); // All URL-safe special chars
|
|
56
|
+
*
|
|
57
|
+
* // Real-world examples
|
|
58
|
+
* validator.parse({ encodedData: "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9" }); // JWT header
|
|
59
|
+
* validator.parse({ encodedData: "VG8gYmUgb3Igbm90IHRvIGJlLCB0aGF0IGlzIHRoZSBxdWVzdGlvbg==" }); // Long text
|
|
60
|
+
* validator.parse({ encodedData: "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==" }); // Base64 image
|
|
61
|
+
*
|
|
62
|
+
* // ❌ INVALID base64 strings
|
|
63
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ" }); // Wrong length (not multiple of 4)
|
|
64
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ===" }); // Too many padding chars (3)
|
|
65
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ====" }); // Too many padding chars (4)
|
|
66
|
+
* validator.parse({ encodedData: "SGV@bG8gV29ybGQ=" }); // Invalid character (@)
|
|
67
|
+
* validator.parse({ encodedData: "SGV sbG8gV29ybGQ=" }); // Space not allowed
|
|
68
|
+
* validator.parse({ encodedData: "SGV\tbG8gV29ybGQ=" }); // Tab not allowed
|
|
69
|
+
* validator.parse({ encodedData: "SGV\nbG8gV29ybGQ=" }); // Newline not allowed
|
|
70
|
+
* validator.parse({ encodedData: "SGVsbG8\rgV29ybGQ=" }); // Carriage return not allowed
|
|
71
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ=" }); // Non-standard characters
|
|
72
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ!=" }); // Exclamation mark not allowed
|
|
73
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ?=" }); // Question mark not allowed
|
|
74
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ&=" }); // Ampersand not allowed
|
|
75
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ*=" }); // Asterisk not allowed
|
|
76
|
+
*
|
|
77
|
+
* // Padding in wrong position
|
|
78
|
+
* validator.parse({ encodedData: "SGVsbG=gV29ybGQ=" }); // Padding in middle
|
|
79
|
+
* validator.parse({ encodedData: "=GVsbG8gV29ybGQ=" }); // Padding at start
|
|
80
|
+
* validator.parse({ encodedData: "SGVsbG8=V29ybGQ=" }); // Padding before end
|
|
81
|
+
*
|
|
82
|
+
* // URL-safe base64 invalid examples
|
|
83
|
+
* urlSafeValidator.parse({ token: "SGVsbG8gV29ybGQ+" }); // + not allowed in URL-safe
|
|
84
|
+
* urlSafeValidator.parse({ token: "SGVsbG8gV29ybGQ/" }); // / not allowed in URL-safe
|
|
85
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ-" }); // - not allowed in standard
|
|
86
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ_" }); // _ not allowed in standard
|
|
87
|
+
*
|
|
88
|
+
* // Edge cases
|
|
89
|
+
* validator.parse({ encodedData: " SGVsbG8gV29ybGQ=" }); // Leading space
|
|
90
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ= " }); // Trailing space
|
|
91
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ=\n" }); // Trailing newline
|
|
92
|
+
* validator.parse({ encodedData: "SGVsbG8gV29ybGQ=\r\n" }); // CRLF at end
|
|
93
|
+
* ```
|
|
94
|
+
* @params
|
|
95
|
+
* - options?: { messageFactory?: (context: MessageContext) => string; urlSafe?: boolean } - Optional configuration
|
|
96
|
+
* @returns Validation function that checks base64 encoding
|
|
97
|
+
* @customError
|
|
98
|
+
* ```typescript
|
|
99
|
+
* .base64({
|
|
100
|
+
* messageFactory: ({ path, value }) =>
|
|
101
|
+
* `${path} must be valid base64 encoded string (received: ${value.substring(0, 20)}...)`
|
|
102
|
+
* })
|
|
103
|
+
* ```
|
|
104
|
+
* @since 0.1.0-alpha
|
|
105
|
+
*/
|
|
106
|
+
import type { MessageContext } from "./types";
|
|
107
|
+
export declare const stringBase64Plugin: import("../..").TypedPlugin<"stringBase64", "base64", (options?: {
|
|
108
|
+
messageFactory?: (context: MessageContext) => string;
|
|
109
|
+
urlSafe?: boolean;
|
|
110
|
+
}) => {
|
|
111
|
+
check: (value: string) => boolean;
|
|
112
|
+
code: string;
|
|
113
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
114
|
+
messageFactory: (context: MessageContext) => string;
|
|
115
|
+
params: {
|
|
116
|
+
messageFactory?: (context: MessageContext) => string;
|
|
117
|
+
urlSafe?: boolean;
|
|
118
|
+
}[];
|
|
119
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringContentEncoding
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates string content encoding (base64, base32, binary, etc.)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringContentEncodingPlugin)
|
|
11
|
+
* .for<{ data: string }>()
|
|
12
|
+
* .v("data", (b) => b.string.contentEncoding("base64"))
|
|
13
|
+
* .build();
|
|
14
|
+
*
|
|
15
|
+
* // Valid for base64: SGVsbG8gV29ybGQ=
|
|
16
|
+
* // Valid for base32: JBSWY3DPEBLW64TMMQ======
|
|
17
|
+
* // Valid for binary: 01001000 01100101
|
|
18
|
+
* ```
|
|
19
|
+
* @params
|
|
20
|
+
* - encoding: "base64" | "base32" | "binary" | "7bit" | "8bit" | "quoted-printable"
|
|
21
|
+
* - options?: { messageFactory?: (context: MessageContext) => string }
|
|
22
|
+
* @returns Validation function that checks content encoding
|
|
23
|
+
* @customError
|
|
24
|
+
* ```typescript
|
|
25
|
+
* .contentEncoding("base64", {
|
|
26
|
+
* messageFactory: ({ path, value }) =>
|
|
27
|
+
* `${path} must be valid base64 encoded content (received: ${value.substring(0, 20)}...)`
|
|
28
|
+
* })
|
|
29
|
+
* ```
|
|
30
|
+
* @since 0.1.0-alpha
|
|
31
|
+
*/
|
|
32
|
+
import type { MessageContext } from "./types";
|
|
33
|
+
export declare const stringContentEncodingPlugin: import("../..").TypedPlugin<"stringContentEncoding", "contentEncoding", (encoding: "base64" | "base32" | "binary" | "7bit" | "8bit" | "quoted-printable" | string, options?: {
|
|
34
|
+
messageFactory?: (context: MessageContext) => string;
|
|
35
|
+
}) => {
|
|
36
|
+
check: (value: string) => boolean;
|
|
37
|
+
code: string;
|
|
38
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
39
|
+
messageFactory: (context: MessageContext) => string;
|
|
40
|
+
params: (string | {
|
|
41
|
+
messageFactory?: (context: MessageContext) => string;
|
|
42
|
+
})[];
|
|
43
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringContentMediaType
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates that a string's decoded content matches the specified media type
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringContentMediaTypePlugin)
|
|
11
|
+
* .for<{ data: string }>()
|
|
12
|
+
* .v("data", (b) => b.string.contentMediaType("application/json"))
|
|
13
|
+
* .build();
|
|
14
|
+
*
|
|
15
|
+
* // Valid: base64-encoded JSON
|
|
16
|
+
* validator.validate({ data: "eyJrZXkiOiJ2YWx1ZSJ9" }); // {"key":"value"}
|
|
17
|
+
*
|
|
18
|
+
* // Invalid: not valid JSON when decoded
|
|
19
|
+
* validator.validate({ data: "aGVsbG8gd29ybGQ=" }); // "hello world"
|
|
20
|
+
* ```
|
|
21
|
+
* @params
|
|
22
|
+
* - mediaType: string - The expected media type
|
|
23
|
+
* - options?: { encoding?: string; messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
24
|
+
* @returns Validation function that checks content media type
|
|
25
|
+
* @customError
|
|
26
|
+
* ```typescript
|
|
27
|
+
* .contentMediaType("application/json", {
|
|
28
|
+
* messageFactory: ({ path, value }) =>
|
|
29
|
+
* `${path} must contain valid JSON content (received: ${value.substring(0, 20)}...)`
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
* @since 0.1.0-alpha
|
|
33
|
+
*/
|
|
34
|
+
import type { MessageContext } from "./types";
|
|
35
|
+
export declare const stringContentMediaTypePlugin: import("../..").TypedPlugin<"stringContentMediaType", "contentMediaType", (mediaType: string, options?: {
|
|
36
|
+
encoding?: string;
|
|
37
|
+
messageFactory?: (context: MessageContext) => string;
|
|
38
|
+
}) => {
|
|
39
|
+
check: (value: string) => boolean;
|
|
40
|
+
code: string;
|
|
41
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
42
|
+
messageFactory: (context: MessageContext) => string;
|
|
43
|
+
params: (string | {
|
|
44
|
+
encoding?: string;
|
|
45
|
+
messageFactory?: (context: MessageContext) => string;
|
|
46
|
+
})[];
|
|
47
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringDate
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates ISO 8601 date format (YYYY-MM-DD)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringDatePlugin)
|
|
11
|
+
* .for<{ birthDate: string }>()
|
|
12
|
+
* .v("birthDate", (b) => b.string.date())
|
|
13
|
+
* .build();
|
|
14
|
+
*
|
|
15
|
+
* // Valid formats:
|
|
16
|
+
* // 2024-01-15
|
|
17
|
+
* // 2024-12-31
|
|
18
|
+
* // 2000-02-29 (leap year)
|
|
19
|
+
*
|
|
20
|
+
* // Invalid:
|
|
21
|
+
* // 2024-13-01 (invalid month)
|
|
22
|
+
* // 2024-02-30 (invalid day)
|
|
23
|
+
* // 2024-1-1 (must be zero-padded)
|
|
24
|
+
* ```
|
|
25
|
+
* @params
|
|
26
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
27
|
+
* @returns Validation function that checks ISO 8601 date format
|
|
28
|
+
* @customError
|
|
29
|
+
* ```typescript
|
|
30
|
+
* .date({
|
|
31
|
+
* messageFactory: ({ path, value }) =>
|
|
32
|
+
* `${path} must be a valid ISO 8601 date format (received: ${value})`
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
* @since 0.1.0-alpha
|
|
36
|
+
*/
|
|
37
|
+
import type { MessageContext } from "./types";
|
|
38
|
+
export declare const stringDatePlugin: import("../..").TypedPlugin<"stringDate", "date", (options?: {
|
|
39
|
+
messageFactory?: (context: MessageContext) => string;
|
|
40
|
+
}) => {
|
|
41
|
+
check: (value: string) => boolean;
|
|
42
|
+
code: string;
|
|
43
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
44
|
+
messageFactory: (context: MessageContext) => string;
|
|
45
|
+
params: {
|
|
46
|
+
messageFactory?: (context: MessageContext) => string;
|
|
47
|
+
}[];
|
|
48
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { MessageContext } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* @luq-plugin
|
|
4
|
+
* @name stringDatetime
|
|
5
|
+
* @category string
|
|
6
|
+
* @description Validates ISO 8601 datetime format with optional timezone support
|
|
7
|
+
* @allowedTypes ["string"]
|
|
8
|
+
* @see https://tools.ietf.org/html/rfc3339 - RFC 3339: Date and Time on the Internet: Timestamps
|
|
9
|
+
* @see https://en.wikipedia.org/wiki/ISO_8601 - ISO 8601 Date and Time Format
|
|
10
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date - MDN Date Object
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* // Basic usage - validates ISO 8601 datetime format (RFC 3339 compliant)
|
|
14
|
+
* const validator = Builder()
|
|
15
|
+
* .use(stringDatetimePlugin)
|
|
16
|
+
* .for<{ timestamp: string }>()
|
|
17
|
+
* .v("timestamp", (b) => b.string.datetime())
|
|
18
|
+
* .build();
|
|
19
|
+
*
|
|
20
|
+
* // Strict mode - requires timezone
|
|
21
|
+
* const strictValidator = Builder()
|
|
22
|
+
* .use(stringDatetimePlugin)
|
|
23
|
+
* .for<{ timestamp: string }>()
|
|
24
|
+
* .v("timestamp", (b) => b.string.datetime({ strict: true }))
|
|
25
|
+
* .build();
|
|
26
|
+
*
|
|
27
|
+
* // ✅ VALID datetime formats (RFC 3339 / ISO 8601)
|
|
28
|
+
* // UTC timezone
|
|
29
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00Z" }); // UTC with Z
|
|
30
|
+
* validator.parse({ timestamp: "2024-12-31T23:59:59Z" }); // End of year
|
|
31
|
+
* validator.parse({ timestamp: "2000-01-01T00:00:00Z" }); // Y2K date
|
|
32
|
+
*
|
|
33
|
+
* // With timezone offsets
|
|
34
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00+09:00" }); // Japan timezone
|
|
35
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00-05:00" }); // EST timezone
|
|
36
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00+00:00" }); // UTC with offset
|
|
37
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00-12:00" }); // Far west timezone
|
|
38
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00+14:00" }); // Far east timezone
|
|
39
|
+
*
|
|
40
|
+
* // With milliseconds
|
|
41
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00.123Z" }); // 3-digit milliseconds
|
|
42
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00.1Z" }); // 1-digit milliseconds
|
|
43
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00.12Z" }); // 2-digit milliseconds
|
|
44
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00.999+09:00" }); // Max milliseconds with offset
|
|
45
|
+
*
|
|
46
|
+
* // Leap year dates
|
|
47
|
+
* validator.parse({ timestamp: "2024-02-29T12:00:00Z" }); // Valid leap day 2024
|
|
48
|
+
* validator.parse({ timestamp: "2000-02-29T12:00:00Z" }); // Valid leap day 2000
|
|
49
|
+
*
|
|
50
|
+
* // Edge cases
|
|
51
|
+
* validator.parse({ timestamp: "2024-01-01T00:00:00Z" }); // Start of year
|
|
52
|
+
* validator.parse({ timestamp: "2024-12-31T23:59:59.999Z" }); // End of year with ms
|
|
53
|
+
* validator.parse({ timestamp: "1970-01-01T00:00:00Z" }); // Unix epoch
|
|
54
|
+
* validator.parse({ timestamp: "9999-12-31T23:59:59Z" }); // Far future
|
|
55
|
+
*
|
|
56
|
+
* // Without timezone (lenient mode only)
|
|
57
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00" }); // Local time (strict: false)
|
|
58
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00.123" }); // Local time with ms
|
|
59
|
+
*
|
|
60
|
+
* // ❌ INVALID datetime formats
|
|
61
|
+
* validator.parse({ timestamp: "invalid-datetime" }); // Plain text
|
|
62
|
+
* validator.parse({ timestamp: "2024-13-15T10:30:00Z" }); // Invalid month (13)
|
|
63
|
+
* validator.parse({ timestamp: "2024-00-15T10:30:00Z" }); // Invalid month (0)
|
|
64
|
+
* validator.parse({ timestamp: "2024-01-32T10:30:00Z" }); // Invalid day (32)
|
|
65
|
+
* validator.parse({ timestamp: "2024-01-00T10:30:00Z" }); // Invalid day (0)
|
|
66
|
+
* validator.parse({ timestamp: "2024-01-15T25:30:00Z" }); // Invalid hour (25)
|
|
67
|
+
* validator.parse({ timestamp: "2024-01-15T10:60:00Z" }); // Invalid minute (60)
|
|
68
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:61Z" }); // Invalid second (61)
|
|
69
|
+
* validator.parse({ timestamp: "2024-02-30T10:30:00Z" }); // Invalid day for February
|
|
70
|
+
* validator.parse({ timestamp: "2023-02-29T10:30:00Z" }); // Not a leap year
|
|
71
|
+
* validator.parse({ timestamp: "2024-04-31T10:30:00Z" }); // Invalid day for April
|
|
72
|
+
* validator.parse({ timestamp: "2024-01-15 10:30:00Z" }); // Space instead of T
|
|
73
|
+
* validator.parse({ timestamp: "2024/01/15T10:30:00Z" }); // Wrong date separator
|
|
74
|
+
* validator.parse({ timestamp: "24-01-15T10:30:00Z" }); // 2-digit year
|
|
75
|
+
* validator.parse({ timestamp: "2024-1-15T10:30:00Z" }); // Single-digit month
|
|
76
|
+
* validator.parse({ timestamp: "2024-01-5T10:30:00Z" }); // Single-digit day
|
|
77
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00" }); // Missing timezone (strict: true)
|
|
78
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00+25:00" }); // Invalid timezone offset
|
|
79
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00.1234Z" }); // Too many milliseconds digits
|
|
80
|
+
* validator.parse({ timestamp: "" }); // Empty string
|
|
81
|
+
* validator.parse({ timestamp: "2024-01-15T10:30:00Z " }); // Trailing space
|
|
82
|
+
* validator.parse({ timestamp: " 2024-01-15T10:30:00Z" }); // Leading space
|
|
83
|
+
* ```
|
|
84
|
+
* @params
|
|
85
|
+
* - options?: { messageFactory?: (context: MessageContext) => string; strict?: boolean } - Optional configuration
|
|
86
|
+
* @returns Validation function that checks ISO 8601 datetime format
|
|
87
|
+
* @customError
|
|
88
|
+
* ```typescript
|
|
89
|
+
* .datetime({
|
|
90
|
+
* messageFactory: ({ path, value }) =>
|
|
91
|
+
* `${path} must be a valid ISO 8601 datetime (received: ${value})`
|
|
92
|
+
* })
|
|
93
|
+
* ```
|
|
94
|
+
* @since 0.1.0-alpha
|
|
95
|
+
*/
|
|
96
|
+
export declare const stringDatetimePlugin: import("../..").TypedPlugin<"stringDatetime", "datetime", (options?: {
|
|
97
|
+
messageFactory?: (context: MessageContext) => string;
|
|
98
|
+
strict?: boolean;
|
|
99
|
+
}) => {
|
|
100
|
+
check: (value: string) => boolean;
|
|
101
|
+
code: string;
|
|
102
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
103
|
+
messageFactory: (context: MessageContext) => string;
|
|
104
|
+
params: {
|
|
105
|
+
messageFactory?: (context: MessageContext) => string;
|
|
106
|
+
strict?: boolean;
|
|
107
|
+
}[];
|
|
108
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringDuration
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates ISO 8601 duration format
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringDurationPlugin)
|
|
11
|
+
* .for<{ duration: string }>()
|
|
12
|
+
* .v("duration", (b) => b.string.duration())
|
|
13
|
+
* .build();
|
|
14
|
+
*
|
|
15
|
+
* // Valid: P3Y6M4DT12H30M5S (3 years, 6 months, 4 days, 12 hours, 30 minutes, 5 seconds)
|
|
16
|
+
* // Valid: PT1H30M (1 hour, 30 minutes)
|
|
17
|
+
* // Valid: P7D (7 days)
|
|
18
|
+
* ```
|
|
19
|
+
* @params
|
|
20
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
21
|
+
* @returns Validation function that checks ISO 8601 duration format
|
|
22
|
+
* @customError
|
|
23
|
+
* ```typescript
|
|
24
|
+
* .duration({
|
|
25
|
+
* messageFactory: ({ path, value }) =>
|
|
26
|
+
* `${path} must be valid ISO 8601 duration format, received: ${value}`
|
|
27
|
+
* })
|
|
28
|
+
* ```
|
|
29
|
+
* @since 0.1.0-alpha
|
|
30
|
+
*/
|
|
31
|
+
import type { MessageContext } from "./types";
|
|
32
|
+
export declare const stringDurationPlugin: import("../..").TypedPlugin<"stringDuration", "duration", (options?: {
|
|
33
|
+
messageFactory?: (context: MessageContext) => string;
|
|
34
|
+
}) => {
|
|
35
|
+
check: (value: string) => boolean;
|
|
36
|
+
code: string;
|
|
37
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
38
|
+
params: {
|
|
39
|
+
messageFactory?: (context: MessageContext) => string;
|
|
40
|
+
}[];
|
|
41
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { ValidationOptions } from "./types";
|
|
2
|
+
interface EmailValidationOptions extends ValidationOptions {
|
|
3
|
+
allowedDomains?: string[];
|
|
4
|
+
customRegex?: RegExp;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* @luq-plugin
|
|
8
|
+
* @name stringEmail
|
|
9
|
+
* @category standard
|
|
10
|
+
* @description Simple and fast email validation with domain restriction and custom regex support (RFC 5322 compliant)
|
|
11
|
+
* @allowedTypes ["string"]
|
|
12
|
+
* @see https://tools.ietf.org/html/rfc5322 - RFC 5322: Internet Message Format
|
|
13
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/email - MDN Email Input Validation
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Basic usage - validates email format (RFC 5322 compliant)
|
|
17
|
+
* const validator = Builder()
|
|
18
|
+
* .use(stringEmailPlugin)
|
|
19
|
+
* .for<UserProfile>()
|
|
20
|
+
* .v("email", (b) => b.string.email())
|
|
21
|
+
* .v("contactEmail", (b) => b.string.required().email())
|
|
22
|
+
* .build();
|
|
23
|
+
*
|
|
24
|
+
* // Domain restriction (practical: corporate email only)
|
|
25
|
+
* builder.v("workEmail", b => b.string.required().email({
|
|
26
|
+
* allowedDomains: ["company.com", "subsidiary.co.jp"]
|
|
27
|
+
* }))
|
|
28
|
+
*
|
|
29
|
+
* // Custom regex for specific format requirements
|
|
30
|
+
* builder.v("strictEmail", b => b.string.email({
|
|
31
|
+
* customRegex: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
|
|
32
|
+
* }))
|
|
33
|
+
*
|
|
34
|
+
* // For length limits, use existing string plugins:
|
|
35
|
+
* builder.v("email", b => b.string.required().max(100).email())
|
|
36
|
+
*
|
|
37
|
+
* // ✅ VALID email formats (RFC 5322)
|
|
38
|
+
* validator.parse({ email: "user@example.com" }); // Standard format
|
|
39
|
+
* validator.parse({ email: "test.email+tag@domain.co.uk" }); // With plus and dots
|
|
40
|
+
* validator.parse({ email: "user123@test-server.com" }); // Numbers and hyphens
|
|
41
|
+
* validator.parse({ email: "firstname.lastname@example.org" }); // Multiple dots
|
|
42
|
+
* validator.parse({ email: "user+filter@gmail.com" }); // Plus addressing
|
|
43
|
+
* validator.parse({ email: "a@b.co" }); // Minimal valid
|
|
44
|
+
* validator.parse({ email: "test_email@domain-name.com" }); // Underscores and hyphens
|
|
45
|
+
*
|
|
46
|
+
* // ❌ INVALID email formats
|
|
47
|
+
* validator.parse({ email: "plainaddress" }); // No @ symbol
|
|
48
|
+
* validator.parse({ email: "@missingdomain.com" }); // Missing local part
|
|
49
|
+
* validator.parse({ email: "missing.domain@" }); // Missing domain
|
|
50
|
+
* validator.parse({ email: "spaces @domain.com" }); // Spaces not allowed
|
|
51
|
+
* validator.parse({ email: "user@.com" }); // Invalid domain start
|
|
52
|
+
* validator.parse({ email: "user@domain" }); // Missing TLD
|
|
53
|
+
* validator.parse({ email: "user@@domain.com" }); // Double @ symbol
|
|
54
|
+
* validator.parse({ email: "user@domain..com" }); // Double dots in domain
|
|
55
|
+
* validator.parse({ email: ".user@domain.com" }); // Leading dot
|
|
56
|
+
* validator.parse({ email: "user.@domain.com" }); // Trailing dot
|
|
57
|
+
* ```
|
|
58
|
+
* @params
|
|
59
|
+
* - options?: EmailValidationOptions - Simple email validation configuration
|
|
60
|
+
* - allowedDomains?: string[] - Only allow emails from these domains (practical for corporate restrictions)
|
|
61
|
+
* - customRegex?: RegExp - Custom regex to override basic validation (practical escape hatch)
|
|
62
|
+
* - messageFactory?: (context: MessageContext) => string - Custom error message factory
|
|
63
|
+
* @returns Validation function optimized for performance - regex validation with optional domain filtering or custom regex
|
|
64
|
+
* @customError
|
|
65
|
+
* ```typescript
|
|
66
|
+
* .email({
|
|
67
|
+
* allowedDomains: ["company.com"],
|
|
68
|
+
* messageFactory: ({ path, value }) =>
|
|
69
|
+
* `${path} must be a company email address (received: ${value})`
|
|
70
|
+
* })
|
|
71
|
+
* ```
|
|
72
|
+
* @since 0.1.0-alpha
|
|
73
|
+
*/
|
|
74
|
+
export declare const stringEmailPlugin: import("../..").TypedPlugin<"stringEmail", "email", (options?: EmailValidationOptions) => {
|
|
75
|
+
check: (value: any) => boolean;
|
|
76
|
+
code: string;
|
|
77
|
+
getErrorMessage: (value: any, path: string) => string;
|
|
78
|
+
params: EmailValidationOptions[];
|
|
79
|
+
validationOptions: EmailValidationOptions;
|
|
80
|
+
}, readonly ["string"], "validator", "standard">;
|
|
81
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ValidationOptions } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* @luq-plugin
|
|
4
|
+
* @name stringEndsWith
|
|
5
|
+
* @category standard
|
|
6
|
+
* @description Validates that a string ends with a specific suffix
|
|
7
|
+
* @allowedTypes ["string"]
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* // Basic usage - checks if string ends with suffix
|
|
11
|
+
* const validator = Builder()
|
|
12
|
+
* .use(stringEndsWithPlugin)
|
|
13
|
+
* .for<FileData>()
|
|
14
|
+
* .v("filename", (b) => b.string.endsWith(".pdf"))
|
|
15
|
+
* .v("configFile", (b) => b.string.required().endsWith(".json"))
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // For file extension validation
|
|
19
|
+
* builder.v("document", b => b.string.endsWith(".pdf").min(5))
|
|
20
|
+
*
|
|
21
|
+
* // Email domain validation
|
|
22
|
+
* builder.v("email", b => b.string.email().endsWith("@company.com"))
|
|
23
|
+
* ```
|
|
24
|
+
* @params
|
|
25
|
+
* - suffix: string - The suffix that the string must end with
|
|
26
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
27
|
+
* @returns Validation function that returns true if string ends with the suffix
|
|
28
|
+
* @customError
|
|
29
|
+
* ```typescript
|
|
30
|
+
* .endsWith(".json", {
|
|
31
|
+
* messageFactory: ({ path, value, params }) =>
|
|
32
|
+
* `${path} must end with '${params.suffix}' (received: ${value})`
|
|
33
|
+
* })
|
|
34
|
+
* ```
|
|
35
|
+
* @since 0.1.0-alpha
|
|
36
|
+
*/
|
|
37
|
+
export declare const stringEndsWithPlugin: import("../..").TypedPlugin<"stringEndsWith", "endsWith", (suffix: 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,46 @@
|
|
|
1
|
+
import { ValidationOptions, MessageContext } from "./types";
|
|
2
|
+
export interface StringExactLengthContext extends MessageContext {
|
|
3
|
+
expected: number;
|
|
4
|
+
actual: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* @luq-plugin
|
|
8
|
+
* @name stringExactLength
|
|
9
|
+
* @category standard
|
|
10
|
+
* @description Validates that a string has exactly the specified length
|
|
11
|
+
* @allowedTypes ["string"]
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Basic usage - requires exact string length
|
|
15
|
+
* const validator = Builder()
|
|
16
|
+
* .use(stringExactLengthPlugin)
|
|
17
|
+
* .for<FormData>()
|
|
18
|
+
* .v("zipCode", (b) => b.string.exactLength(5))
|
|
19
|
+
* .v("countryCode", (b) => b.string.required().exactLength(2))
|
|
20
|
+
* .build();
|
|
21
|
+
*
|
|
22
|
+
* // For product codes or SKUs
|
|
23
|
+
* builder.v("productCode", b => b.string.exactLength(8).alphanumeric())
|
|
24
|
+
*
|
|
25
|
+
* // For fixed-format phone extensions
|
|
26
|
+
* builder.v("extension", b => b.string.optional().exactLength(4))
|
|
27
|
+
* ```
|
|
28
|
+
* @params
|
|
29
|
+
* - expectedLength: number - The exact length the string must have
|
|
30
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
31
|
+
* @returns Validation function that returns true if string has exact length
|
|
32
|
+
* @customError
|
|
33
|
+
* ```typescript
|
|
34
|
+
* .exactLength(4, {
|
|
35
|
+
* messageFactory: ({ path, value, params }) =>
|
|
36
|
+
* `${path} must be exactly ${params.expected} characters (received: ${params.actual})`
|
|
37
|
+
* })
|
|
38
|
+
* ```
|
|
39
|
+
* @since 0.1.0-alpha
|
|
40
|
+
*/
|
|
41
|
+
export declare const stringExactLengthPlugin: import("../..").TypedPlugin<"stringExactLength", "exactLength", (expectedLength: number, options?: ValidationOptions<StringExactLengthContext>) => {
|
|
42
|
+
check: (value: any) => boolean;
|
|
43
|
+
code: string;
|
|
44
|
+
getErrorMessage: (value: any, path: string) => string;
|
|
45
|
+
params: (number | ValidationOptions<StringExactLengthContext>)[];
|
|
46
|
+
}, readonly ["string"], "validator", "standard">;
|