@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,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringHostname
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates hostname format (RFC 1123)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @see https://tools.ietf.org/html/rfc1123 - RFC 1123: Requirements for Internet Hosts - Application and Support
|
|
8
|
+
* @see https://tools.ietf.org/html/rfc952 - RFC 952: DoD Internet Host Table Specification
|
|
9
|
+
* @see https://en.wikipedia.org/wiki/Hostname - Hostname Format Reference
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* // Basic usage - validates hostname format (RFC 1123 compliant)
|
|
13
|
+
* const validator = Builder()
|
|
14
|
+
* .use(stringHostnamePlugin)
|
|
15
|
+
* .for<{ hostname: string }>()
|
|
16
|
+
* .v("hostname", (b) => b.string.hostname())
|
|
17
|
+
* .build();
|
|
18
|
+
*
|
|
19
|
+
* // ✅ VALID hostnames (RFC 1123)
|
|
20
|
+
* validator.parse({ hostname: "example.com" }); // Standard domain
|
|
21
|
+
* validator.parse({ hostname: "www.example.com" }); // Subdomain
|
|
22
|
+
* validator.parse({ hostname: "mail-server.company.org" }); // With hyphens
|
|
23
|
+
* validator.parse({ hostname: "a.b.c" }); // Short labels
|
|
24
|
+
* validator.parse({ hostname: "host123.domain.co.uk" }); // With numbers
|
|
25
|
+
* validator.parse({ hostname: "localhost" }); // Single label
|
|
26
|
+
* validator.parse({ hostname: "api-v2.service.internal" }); // Multiple hyphens
|
|
27
|
+
* validator.parse({ hostname: "test" }); // Single word
|
|
28
|
+
* validator.parse({ hostname: "1a.2b.3c" }); // Starting with numbers
|
|
29
|
+
* validator.parse({ hostname: "x" }); // Single character
|
|
30
|
+
* validator.parse({ hostname: "sub.domain.example.com" }); // Multiple levels
|
|
31
|
+
* validator.parse({ hostname: "ftp.files.company-name.org" }); // Complex structure
|
|
32
|
+
* validator.parse({ hostname: "db1.cluster.production" }); // Database naming
|
|
33
|
+
* validator.parse({ hostname: "web01.dmz.corp" }); // Network zones
|
|
34
|
+
* validator.parse({ hostname: "backup-server.it.department" }); // Organizational
|
|
35
|
+
*
|
|
36
|
+
* // Edge cases
|
|
37
|
+
* validator.parse({ hostname: "a".repeat(63) }); // Max label length (63 chars)
|
|
38
|
+
* validator.parse({ hostname: "a".repeat(63) + "." + "b".repeat(63) }); // Multiple max labels
|
|
39
|
+
* validator.parse({ hostname: "0" }); // Single digit
|
|
40
|
+
* validator.parse({ hostname: "9a" }); // Number followed by letter
|
|
41
|
+
*
|
|
42
|
+
* // ❌ INVALID hostnames
|
|
43
|
+
* validator.parse({ hostname: "-example.com" }); // Starting with hyphen
|
|
44
|
+
* validator.parse({ hostname: "example-.com" }); // Label ending with hyphen
|
|
45
|
+
* validator.parse({ hostname: "example.com-" }); // Hostname ending with hyphen
|
|
46
|
+
* validator.parse({ hostname: ".example.com" }); // Starting with dot
|
|
47
|
+
* validator.parse({ hostname: "example..com" }); // Double dot (empty label)
|
|
48
|
+
* validator.parse({ hostname: "example.com." }); // Trailing dot
|
|
49
|
+
* validator.parse({ hostname: "" }); // Empty string
|
|
50
|
+
* validator.parse({ hostname: "example .com" }); // Space in hostname
|
|
51
|
+
* validator.parse({ hostname: "example_com" }); // Underscore not allowed
|
|
52
|
+
* validator.parse({ hostname: "EXAMPLE.COM" }); // All caps (valid but not recommended)
|
|
53
|
+
* validator.parse({ hostname: "example.com/path" }); // With path
|
|
54
|
+
* validator.parse({ hostname: "example.com:8080" }); // With port
|
|
55
|
+
* validator.parse({ hostname: "user@example.com" }); // With user
|
|
56
|
+
* validator.parse({ hostname: "http://example.com" }); // Full URL
|
|
57
|
+
* validator.parse({ hostname: "192.168.1.1" }); // IP address (not hostname)
|
|
58
|
+
* validator.parse({ hostname: "[::1]" }); // IPv6 address
|
|
59
|
+
*
|
|
60
|
+
* // Label too long (> 63 characters)
|
|
61
|
+
* validator.parse({ hostname: "a".repeat(64) + ".com" }); // Single label > 63 chars
|
|
62
|
+
*
|
|
63
|
+
* // Hostname too long (> 253 characters total)
|
|
64
|
+
* const longLabel = "a".repeat(50);
|
|
65
|
+
* const longHostname = Array(10).fill(longLabel).join(".") + ".com"; // > 253 chars total
|
|
66
|
+
* validator.parse({ hostname: longHostname });
|
|
67
|
+
*
|
|
68
|
+
* // Special characters not allowed
|
|
69
|
+
* validator.parse({ hostname: "exam@ple.com" }); // @ symbol
|
|
70
|
+
* validator.parse({ hostname: "exam#ple.com" }); // # symbol
|
|
71
|
+
* validator.parse({ hostname: "exam$ple.com" }); // $ symbol
|
|
72
|
+
* validator.parse({ hostname: "exam%ple.com" }); // % symbol
|
|
73
|
+
* validator.parse({ hostname: "exam&ple.com" }); // & symbol
|
|
74
|
+
* validator.parse({ hostname: "example.com!" }); // Exclamation mark
|
|
75
|
+
* validator.parse({ hostname: "example.com?" }); // Question mark
|
|
76
|
+
*
|
|
77
|
+
* // Unicode/international domain names (IDN not supported in basic hostname)
|
|
78
|
+
* validator.parse({ hostname: "ドメイン.com" }); // Japanese characters
|
|
79
|
+
* validator.parse({ hostname: "münchen.de" }); // German umlaut
|
|
80
|
+
* validator.parse({ hostname: "café.fr" }); // French accent
|
|
81
|
+
* ```
|
|
82
|
+
* @params
|
|
83
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
84
|
+
* @returns Validation function that checks hostname format
|
|
85
|
+
* @customError
|
|
86
|
+
* ```typescript
|
|
87
|
+
* .hostname({
|
|
88
|
+
* messageFactory: ({ path, value }) =>
|
|
89
|
+
* `${path} must be valid hostname format, received: ${value}`
|
|
90
|
+
* })
|
|
91
|
+
* ```
|
|
92
|
+
* @since 0.1.0-alpha
|
|
93
|
+
*/
|
|
94
|
+
import type { MessageContext } from "./types";
|
|
95
|
+
export declare const stringHostnamePlugin: import("../..").TypedPlugin<"stringHostname", "hostname", (options?: {
|
|
96
|
+
messageFactory?: (context: MessageContext) => string;
|
|
97
|
+
}) => {
|
|
98
|
+
check: (value: string) => boolean;
|
|
99
|
+
code: string;
|
|
100
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
101
|
+
params: {
|
|
102
|
+
messageFactory?: (context: MessageContext) => string;
|
|
103
|
+
}[];
|
|
104
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringIpv4
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates IPv4 address format
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @see https://tools.ietf.org/html/rfc791 - RFC 791: Internet Protocol - DARPA Internet Program Protocol Specification
|
|
8
|
+
* @see https://en.wikipedia.org/wiki/IPv4 - IPv4 Address Format Reference
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Basic usage - validates IPv4 address format (RFC 791 compliant)
|
|
12
|
+
* const validator = Builder()
|
|
13
|
+
* .use(stringIpv4Plugin)
|
|
14
|
+
* .for<{ ipAddress: string }>()
|
|
15
|
+
* .v("ipAddress", (b) => b.string.ipv4())
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // ✅ VALID IPv4 addresses (RFC 791)
|
|
19
|
+
* validator.parse({ ipAddress: "192.168.1.1" }); // Private network (Class C)
|
|
20
|
+
* validator.parse({ ipAddress: "127.0.0.1" }); // Localhost/loopback
|
|
21
|
+
* validator.parse({ ipAddress: "8.8.8.8" }); // Google DNS
|
|
22
|
+
* validator.parse({ ipAddress: "0.0.0.0" }); // All zeros (any address)
|
|
23
|
+
* validator.parse({ ipAddress: "255.255.255.255" }); // Broadcast address
|
|
24
|
+
* validator.parse({ ipAddress: "10.0.0.1" }); // Private network (Class A)
|
|
25
|
+
* validator.parse({ ipAddress: "172.16.0.1" }); // Private network (Class B)
|
|
26
|
+
* validator.parse({ ipAddress: "203.0.113.1" }); // Documentation/test network
|
|
27
|
+
* validator.parse({ ipAddress: "1.1.1.1" }); // Cloudflare DNS
|
|
28
|
+
* validator.parse({ ipAddress: "192.0.2.146" }); // Documentation network
|
|
29
|
+
* validator.parse({ ipAddress: "198.51.100.1" }); // Documentation network
|
|
30
|
+
* validator.parse({ ipAddress: "169.254.1.1" }); // Link-local address
|
|
31
|
+
* validator.parse({ ipAddress: "224.0.0.1" }); // Multicast address
|
|
32
|
+
* validator.parse({ ipAddress: "239.255.255.255" }); // Local multicast
|
|
33
|
+
* validator.parse({ ipAddress: "1.2.3.4" }); // Simple valid address
|
|
34
|
+
* validator.parse({ ipAddress: "100.64.0.1" }); // Carrier-grade NAT
|
|
35
|
+
*
|
|
36
|
+
* // ❌ INVALID IPv4 addresses
|
|
37
|
+
* validator.parse({ ipAddress: "256.1.1.1" }); // Octet > 255
|
|
38
|
+
* validator.parse({ ipAddress: "192.168.1.256" }); // Last octet > 255
|
|
39
|
+
* validator.parse({ ipAddress: "300.300.300.300" }); // All octets > 255
|
|
40
|
+
* validator.parse({ ipAddress: "192.168.1" }); // Missing octet
|
|
41
|
+
* validator.parse({ ipAddress: "192.168" }); // Only 2 octets
|
|
42
|
+
* validator.parse({ ipAddress: "192" }); // Only 1 octet
|
|
43
|
+
* validator.parse({ ipAddress: "192.168.1.1.1" }); // Extra octet (5 octets)
|
|
44
|
+
* validator.parse({ ipAddress: "192.168.01.1" }); // Leading zeros (octal notation)
|
|
45
|
+
* validator.parse({ ipAddress: "192.168.001.1" }); // Multiple leading zeros
|
|
46
|
+
* validator.parse({ ipAddress: "192.168.-1.1" }); // Negative number
|
|
47
|
+
* validator.parse({ ipAddress: "192.168.1.-1" }); // Negative last octet
|
|
48
|
+
* validator.parse({ ipAddress: "not.an.ip.address" }); // Non-numeric text
|
|
49
|
+
* validator.parse({ ipAddress: "192.168.1.1/24" }); // CIDR notation
|
|
50
|
+
* validator.parse({ ipAddress: "192.168.1.1:8080" }); // With port number
|
|
51
|
+
* validator.parse({ ipAddress: "192.168.1." }); // Trailing dot
|
|
52
|
+
* validator.parse({ ipAddress: ".192.168.1.1" }); // Leading dot
|
|
53
|
+
* validator.parse({ ipAddress: "192..168.1.1" }); // Double dot
|
|
54
|
+
* validator.parse({ ipAddress: "192 168 1 1" }); // Spaces instead of dots
|
|
55
|
+
* validator.parse({ ipAddress: "192,168,1,1" }); // Commas instead of dots
|
|
56
|
+
* validator.parse({ ipAddress: "192-168-1-1" }); // Hyphens instead of dots
|
|
57
|
+
* validator.parse({ ipAddress: "" }); // Empty string
|
|
58
|
+
* validator.parse({ ipAddress: "192.168.1.1 " }); // Trailing space
|
|
59
|
+
* validator.parse({ ipAddress: " 192.168.1.1" }); // Leading space
|
|
60
|
+
* validator.parse({ ipAddress: "192.168.a.1" }); // Letter in octet
|
|
61
|
+
* validator.parse({ ipAddress: "192.168.1.1." }); // Trailing dot after last octet
|
|
62
|
+
* ```
|
|
63
|
+
* @params
|
|
64
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
65
|
+
* @returns Validation function that checks IPv4 format
|
|
66
|
+
* @customError
|
|
67
|
+
* ```typescript
|
|
68
|
+
* .ipv4({
|
|
69
|
+
* messageFactory: ({ path, value }) =>
|
|
70
|
+
* `${path} must be valid IPv4 format, received: ${value}`
|
|
71
|
+
* })
|
|
72
|
+
* ```
|
|
73
|
+
* @since 0.1.0-alpha
|
|
74
|
+
*/
|
|
75
|
+
import type { MessageContext } from "./types";
|
|
76
|
+
export declare const stringIpv4Plugin: import("../..").TypedPlugin<"stringIpv4", "ipv4", (options?: {
|
|
77
|
+
messageFactory?: (context: MessageContext) => string;
|
|
78
|
+
}) => {
|
|
79
|
+
check: (value: string) => boolean;
|
|
80
|
+
code: string;
|
|
81
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
82
|
+
params: {
|
|
83
|
+
messageFactory?: (context: MessageContext) => string;
|
|
84
|
+
}[];
|
|
85
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringIpv6
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates IPv6 address format
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @see https://tools.ietf.org/html/rfc4291 - RFC 4291: IP Version 6 Addressing Architecture
|
|
8
|
+
* @see https://en.wikipedia.org/wiki/IPv6 - IPv6 Address Format Reference
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Basic usage - validates IPv6 address format (RFC 4291 compliant)
|
|
12
|
+
* const validator = Builder()
|
|
13
|
+
* .use(stringIpv6Plugin)
|
|
14
|
+
* .for<{ ipv6Address: string }>()
|
|
15
|
+
* .v("ipv6Address", (b) => b.string.ipv6())
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // ✅ VALID IPv6 addresses (RFC 4291)
|
|
19
|
+
* // Full format (128-bit address)
|
|
20
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334" });
|
|
21
|
+
* validator.parse({ ipv6Address: "2001:0DB8:85A3:0000:0000:8A2E:0370:7334" }); // Case insensitive
|
|
22
|
+
*
|
|
23
|
+
* // Leading zeros omitted
|
|
24
|
+
* validator.parse({ ipv6Address: "2001:db8:85a3:0:0:8a2e:370:7334" });
|
|
25
|
+
* validator.parse({ ipv6Address: "2001:db8:85a3:1:1:8a2e:370:7334" });
|
|
26
|
+
*
|
|
27
|
+
* // Compressed format with :: (consecutive zeros)
|
|
28
|
+
* validator.parse({ ipv6Address: "2001:db8:85a3::8a2e:370:7334" });
|
|
29
|
+
* validator.parse({ ipv6Address: "2001:db8::1" });
|
|
30
|
+
* validator.parse({ ipv6Address: "2001:db8::" });
|
|
31
|
+
* validator.parse({ ipv6Address: "::2001:db8:85a3:0:0:8a2e:370:7334" });
|
|
32
|
+
* validator.parse({ ipv6Address: "2001:db8:85a3:0:0:8a2e::" });
|
|
33
|
+
*
|
|
34
|
+
* // Special addresses
|
|
35
|
+
* validator.parse({ ipv6Address: "::1" }); // IPv6 loopback
|
|
36
|
+
* validator.parse({ ipv6Address: "::" }); // All zeros (unspecified)
|
|
37
|
+
* validator.parse({ ipv6Address: "::ffff:0:0" }); // IPv4-mapped prefix
|
|
38
|
+
* validator.parse({ ipv6Address: "::ffff:192.0.2.1" }); // IPv4-mapped IPv6
|
|
39
|
+
* validator.parse({ ipv6Address: "::ffff:c000:0201" }); // IPv4-mapped (hex format)
|
|
40
|
+
* validator.parse({ ipv6Address: "2001:db8::192.0.2.1" }); // IPv4 suffix notation
|
|
41
|
+
*
|
|
42
|
+
* // Link-local addresses
|
|
43
|
+
* validator.parse({ ipv6Address: "fe80::1" }); // Link-local
|
|
44
|
+
* validator.parse({ ipv6Address: "fe80::1%lo0" }); // With zone identifier
|
|
45
|
+
* validator.parse({ ipv6Address: "fe80::1%eth0" }); // With interface name
|
|
46
|
+
* validator.parse({ ipv6Address: "fe80::200:f8ff:fe21:67cf%en0" }); // Full link-local with zone
|
|
47
|
+
*
|
|
48
|
+
* // Multicast addresses
|
|
49
|
+
* validator.parse({ ipv6Address: "ff02::1" }); // All nodes multicast
|
|
50
|
+
* validator.parse({ ipv6Address: "ff02::2" }); // All routers multicast
|
|
51
|
+
*
|
|
52
|
+
* // Documentation addresses
|
|
53
|
+
* validator.parse({ ipv6Address: "2001:db8::1" }); // Documentation prefix
|
|
54
|
+
* validator.parse({ ipv6Address: "2001:db8:85a3::8a2e:370:7334" }); // RFC 3849 example
|
|
55
|
+
*
|
|
56
|
+
* // Edge cases
|
|
57
|
+
* validator.parse({ ipv6Address: "1:2:3:4:5:6:7:8" }); // All single digits
|
|
58
|
+
* validator.parse({ ipv6Address: "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff" }); // All ones
|
|
59
|
+
*
|
|
60
|
+
* // ❌ INVALID IPv6 addresses
|
|
61
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3::8a2e::7334" }); // Double :: (not allowed)
|
|
62
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334:extra" }); // Too many groups
|
|
63
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370" }); // Too few groups without ::
|
|
64
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370:733g" }); // Invalid hex char (g)
|
|
65
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370:73345" }); // Group too long (5 chars)
|
|
66
|
+
* validator.parse({ ipv6Address: "2001::db8::85a3" }); // Multiple :: not allowed
|
|
67
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370:" }); // Trailing colon
|
|
68
|
+
* validator.parse({ ipv6Address: ":2001:0db8:85a3:0000:0000:8a2e:0370:7334" }); // Leading colon (not ::)
|
|
69
|
+
* validator.parse({ ipv6Address: "2001-0db8-85a3-0000-0000-8a2e-0370-7334" }); // Hyphens instead of colons
|
|
70
|
+
* validator.parse({ ipv6Address: "2001.0db8.85a3.0000.0000.8a2e.0370.7334" }); // Dots instead of colons
|
|
71
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334/64" }); // With CIDR notation
|
|
72
|
+
* validator.parse({ ipv6Address: "gggg::1" }); // Invalid hex chars
|
|
73
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:::8a2e:0370:7334" }); // Triple colon
|
|
74
|
+
* validator.parse({ ipv6Address: "" }); // Empty string
|
|
75
|
+
* validator.parse({ ipv6Address: "not:an:ipv6:address" }); // Non-hex text
|
|
76
|
+
* validator.parse({ ipv6Address: "2001:0db8:85a3:0000:0000:8a2e:0370:7334 " }); // Trailing space
|
|
77
|
+
* validator.parse({ ipv6Address: " 2001:0db8:85a3:0000:0000:8a2e:0370:7334" }); // Leading space
|
|
78
|
+
* validator.parse({ ipv6Address: "::ffff:256.1.1.1" }); // Invalid IPv4 in mapping
|
|
79
|
+
* validator.parse({ ipv6Address: "::ffff:192.168.1" }); // Incomplete IPv4 in mapping
|
|
80
|
+
* validator.parse({ ipv6Address: "192.168.1.1" }); // Plain IPv4 address
|
|
81
|
+
* ```
|
|
82
|
+
* @params
|
|
83
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
84
|
+
* @returns Validation function that checks IPv6 format
|
|
85
|
+
* @customError
|
|
86
|
+
* ```typescript
|
|
87
|
+
* .ipv6({
|
|
88
|
+
* messageFactory: ({ path, value }) =>
|
|
89
|
+
* `${path} must be valid IPv6 format, received: ${value}`
|
|
90
|
+
* })
|
|
91
|
+
* ```
|
|
92
|
+
* @since 0.1.0-alpha
|
|
93
|
+
*/
|
|
94
|
+
import type { MessageContext } from "./types";
|
|
95
|
+
export declare const stringIpv6Plugin: import("../..").TypedPlugin<"stringIpv6", "ipv6", (options?: {
|
|
96
|
+
messageFactory?: (context: MessageContext) => string;
|
|
97
|
+
}) => {
|
|
98
|
+
check: (value: string) => boolean;
|
|
99
|
+
code: string;
|
|
100
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
101
|
+
params: {
|
|
102
|
+
messageFactory?: (context: MessageContext) => string;
|
|
103
|
+
}[];
|
|
104
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringIri
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates IRI (Internationalized Resource Identifier) format (RFC 3987)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @see https://tools.ietf.org/html/rfc3987 - RFC 3987: Internationalized Resource Identifiers (IRIs)
|
|
8
|
+
* @see https://en.wikipedia.org/wiki/Internationalized_Resource_Identifier - IRI Format Reference
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Basic usage - validates IRI format (RFC 3987 compliant)
|
|
12
|
+
* const validator = Builder()
|
|
13
|
+
* .use(stringIriPlugin)
|
|
14
|
+
* .for<{ identifier: string }>()
|
|
15
|
+
* .v("identifier", (b) => b.string.iri())
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // ✅ VALID IRI formats (RFC 3987)
|
|
19
|
+
* // Standard ASCII URIs (subset of IRI)
|
|
20
|
+
* validator.parse({ identifier: "https://www.example.com/path" }); // Regular HTTP URL
|
|
21
|
+
* validator.parse({ identifier: "http://example.org:8080/api/v1" }); // With port and path
|
|
22
|
+
* validator.parse({ identifier: "ftp://files.example.com/file.txt" }); // FTP scheme
|
|
23
|
+
* validator.parse({ identifier: "mailto:user@example.com" }); // Email scheme
|
|
24
|
+
* validator.parse({ identifier: "tel:+1-555-123-4567" }); // Telephone scheme
|
|
25
|
+
*
|
|
26
|
+
* // Internationalized domain names and paths (Unicode)
|
|
27
|
+
* validator.parse({ identifier: "https://例え.jp/パス" }); // Japanese characters
|
|
28
|
+
* validator.parse({ identifier: "http://münchen.de/straße" }); // German umlauts
|
|
29
|
+
* validator.parse({ identifier: "https://café.fr/menu" }); // French accents
|
|
30
|
+
* validator.parse({ identifier: "http://домен.рф/путь" }); // Cyrillic script
|
|
31
|
+
* validator.parse({ identifier: "https://测试.cn/路径" }); // Chinese characters
|
|
32
|
+
* validator.parse({ identifier: "http://테스트.kr/경로" }); // Korean characters
|
|
33
|
+
* validator.parse({ identifier: "https://тест.bg/път" }); // Bulgarian Cyrillic
|
|
34
|
+
* validator.parse({ identifier: "http://δοκιμή.gr/διαδρομή" }); // Greek characters
|
|
35
|
+
* validator.parse({ identifier: "https://परीक्षा.in/पथ" }); // Hindi/Devanagari
|
|
36
|
+
* validator.parse({ identifier: "http://اختبار.sa/مسار" }); // Arabic script
|
|
37
|
+
*
|
|
38
|
+
* // Internationalized email addresses
|
|
39
|
+
* validator.parse({ identifier: "mailto:ユーザー@例え.jp" }); // Japanese email
|
|
40
|
+
* validator.parse({ identifier: "mailto:utilisateur@café.fr" }); // French domain
|
|
41
|
+
* validator.parse({ identifier: "mailto:пользователь@домен.рф" }); // Cyrillic email
|
|
42
|
+
*
|
|
43
|
+
* // Mixed ASCII and Unicode
|
|
44
|
+
* validator.parse({ identifier: "https://api.例え.jp/v1/users" }); // Mixed path
|
|
45
|
+
* validator.parse({ identifier: "https://例え.example.com/path" }); // Mixed domain
|
|
46
|
+
* validator.parse({ identifier: "ftp://files.café.com/données.txt" }); // Mixed filename
|
|
47
|
+
*
|
|
48
|
+
* // Various schemes with Unicode
|
|
49
|
+
* validator.parse({ identifier: "ldap://服务器.com/cn=用户,dc=例子,dc=com" }); // LDAP with Chinese
|
|
50
|
+
* validator.parse({ identifier: "news://nieuws.nl/groep.测试" }); // News with mixed Unicode
|
|
51
|
+
* validator.parse({ identifier: "urn:isbn:978-3-86680-192-9" }); // URN (ASCII)
|
|
52
|
+
*
|
|
53
|
+
* // Edge cases
|
|
54
|
+
* validator.parse({ identifier: "custom-scheme://测试.example/路径" }); // Custom scheme with Unicode
|
|
55
|
+
* validator.parse({ identifier: "x-proprietary://例え.internal" }); // Non-standard scheme
|
|
56
|
+
* validator.parse({ identifier: "data:text/plain;charset=utf-8,你好" }); // Data URI with Unicode
|
|
57
|
+
*
|
|
58
|
+
* // ❌ INVALID IRI formats
|
|
59
|
+
* validator.parse({ identifier: "not-an-iri" }); // No scheme separator
|
|
60
|
+
* validator.parse({ identifier: "://missing-scheme.com" }); // Missing scheme
|
|
61
|
+
* validator.parse({ identifier: "http://" }); // Missing authority
|
|
62
|
+
* validator.parse({ identifier: "https:/" }); // Malformed scheme separator
|
|
63
|
+
* validator.parse({ identifier: "" }); // Empty string
|
|
64
|
+
* validator.parse({ identifier: "http://exam ple.com" }); // Space in authority
|
|
65
|
+
* validator.parse({ identifier: "https://example.com/path with spaces" }); // Spaces in path
|
|
66
|
+
* validator.parse({ identifier: "http://example.com/path\twith\ttabs" }); // Tab characters
|
|
67
|
+
* validator.parse({ identifier: "https://example.com/path\nwith\nnewlines" }); // Newline characters
|
|
68
|
+
* validator.parse({ identifier: "http://example.com/path\rwith\rcarriage" }); // Carriage returns
|
|
69
|
+
* validator.parse({ identifier: "ftp://example.com\x00null" }); // Null character (control char)
|
|
70
|
+
* validator.parse({ identifier: "https://example.com\x01control" }); // Control character
|
|
71
|
+
* validator.parse({ identifier: "http://example.com\x7Fdel" }); // DEL character
|
|
72
|
+
*
|
|
73
|
+
* // Malformed schemes
|
|
74
|
+
* validator.parse({ identifier: "123://invalid-scheme.com" }); // Scheme starting with number
|
|
75
|
+
* validator.parse({ identifier: "-http://invalid-scheme.com" }); // Scheme starting with hyphen
|
|
76
|
+
* validator.parse({ identifier: ".http://invalid-scheme.com" }); // Scheme starting with dot
|
|
77
|
+
* validator.parse({ identifier: "ht@tp://invalid-char.com" }); // Invalid char in scheme
|
|
78
|
+
* validator.parse({ identifier: "ht tp://space-in-scheme.com" }); // Space in scheme
|
|
79
|
+
*
|
|
80
|
+
* // Missing or empty components
|
|
81
|
+
* validator.parse({ identifier: "http:" }); // Scheme only
|
|
82
|
+
* validator.parse({ identifier: ":" }); // Just separator
|
|
83
|
+
* validator.parse({ identifier: "http://example.com:" }); // Trailing colon
|
|
84
|
+
*
|
|
85
|
+
* // Invalid Unicode sequences (rare but possible)
|
|
86
|
+
* validator.parse({ identifier: "https://example.com/\uFFFD" }); // Replacement character
|
|
87
|
+
* validator.parse({ identifier: "http://\uFEFF.example.com" }); // BOM character
|
|
88
|
+
*
|
|
89
|
+
* // Leading/trailing whitespace
|
|
90
|
+
* validator.parse({ identifier: " https://example.com" }); // Leading space
|
|
91
|
+
* validator.parse({ identifier: "https://example.com " }); // Trailing space
|
|
92
|
+
* validator.parse({ identifier: "\thttps://example.com" }); // Leading tab
|
|
93
|
+
* validator.parse({ identifier: "https://example.com\n" }); // Trailing newline
|
|
94
|
+
* ```
|
|
95
|
+
* @params
|
|
96
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
97
|
+
* @returns Validation function that checks IRI format
|
|
98
|
+
* @customError
|
|
99
|
+
* ```typescript
|
|
100
|
+
* .iri({
|
|
101
|
+
* messageFactory: ({ path, value }) =>
|
|
102
|
+
* `${path} must be valid IRI format, received: ${value}`
|
|
103
|
+
* })
|
|
104
|
+
* ```
|
|
105
|
+
* @since 0.1.0-alpha
|
|
106
|
+
*/
|
|
107
|
+
import type { MessageContext } from "./types";
|
|
108
|
+
export declare const stringIriPlugin: import("../..").TypedPlugin<"stringIri", "iri", (options?: {
|
|
109
|
+
messageFactory?: (context: MessageContext) => string;
|
|
110
|
+
}) => {
|
|
111
|
+
check: (value: string) => boolean;
|
|
112
|
+
code: string;
|
|
113
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
114
|
+
params: {
|
|
115
|
+
messageFactory?: (context: MessageContext) => string;
|
|
116
|
+
}[];
|
|
117
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringIriReference
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates IRI-reference format (RFC 3987) - can be absolute or relative
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @example
|
|
8
|
+
* ```typescript
|
|
9
|
+
* const validator = Builder()
|
|
10
|
+
* .use(stringIriReferencePlugin)
|
|
11
|
+
* .for<{ ref: string }>()
|
|
12
|
+
* .v("ref", (b) => b.string.iriReference())
|
|
13
|
+
* .build();
|
|
14
|
+
*
|
|
15
|
+
* // Valid: https://example.com/path
|
|
16
|
+
* // Valid: /relative/path
|
|
17
|
+
* // Valid: ../parent
|
|
18
|
+
* // Valid: #fragment
|
|
19
|
+
* // Valid: ?query=param
|
|
20
|
+
* ```
|
|
21
|
+
* @params
|
|
22
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
23
|
+
* @returns Validation function that checks IRI-reference format
|
|
24
|
+
* @customError
|
|
25
|
+
* ```typescript
|
|
26
|
+
* .iriReference({
|
|
27
|
+
* messageFactory: ({ path, value }) =>
|
|
28
|
+
* `${path} must be valid IRI-reference format, received: ${value}`
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
* @since 0.1.0-alpha
|
|
32
|
+
*/
|
|
33
|
+
import type { MessageContext } from "./types";
|
|
34
|
+
export declare const stringIriReferencePlugin: import("../..").TypedPlugin<"stringIriReference", "iriReference", (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,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @luq-plugin
|
|
3
|
+
* @name stringJsonPointer
|
|
4
|
+
* @category string
|
|
5
|
+
* @description Validates JSON Pointer format (RFC 6901)
|
|
6
|
+
* @allowedTypes ["string"]
|
|
7
|
+
* @see https://tools.ietf.org/html/rfc6901 - RFC 6901: JavaScript Object Notation (JSON) Pointer
|
|
8
|
+
* @see https://datatracker.ietf.org/doc/html/rfc6901 - JSON Pointer Specification
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* // Basic usage - validates JSON Pointer format (RFC 6901 compliant)
|
|
12
|
+
* const validator = Builder()
|
|
13
|
+
* .use(stringJsonPointerPlugin)
|
|
14
|
+
* .for<{ pointer: string }>()
|
|
15
|
+
* .v("pointer", (b) => b.string.jsonPointer())
|
|
16
|
+
* .build();
|
|
17
|
+
*
|
|
18
|
+
* // ✅ VALID JSON Pointers (RFC 6901)
|
|
19
|
+
* validator.parse({ pointer: "" }); // Empty string (points to root document)
|
|
20
|
+
* validator.parse({ pointer: "/" }); // Points to empty property name
|
|
21
|
+
* validator.parse({ pointer: "/foo" }); // Simple property access
|
|
22
|
+
* validator.parse({ pointer: "/foo/bar" }); // Nested property access
|
|
23
|
+
* validator.parse({ pointer: "/foo/0" }); // Array element by index
|
|
24
|
+
* validator.parse({ pointer: "/foo/0/bar" }); // Property of array element
|
|
25
|
+
* validator.parse({ pointer: "/users/123/name" }); // Deep nested access
|
|
26
|
+
* validator.parse({ pointer: "/data/items/0/id" }); // Array element property
|
|
27
|
+
*
|
|
28
|
+
* // Escaped characters (RFC 6901 escape sequences)
|
|
29
|
+
* validator.parse({ pointer: "/~0" }); // Escaped ~ character (represents "~")
|
|
30
|
+
* validator.parse({ pointer: "/~1" }); // Escaped / character (represents "/")
|
|
31
|
+
* validator.parse({ pointer: "/~0~1" }); // Both escapes (represents "~/")
|
|
32
|
+
* validator.parse({ pointer: "/foo~1bar" }); // Forward slash escaped in middle
|
|
33
|
+
* validator.parse({ pointer: "/~0field" }); // Tilde escaped at start of token
|
|
34
|
+
* validator.parse({ pointer: "/field~0" }); // Tilde escaped at end of token
|
|
35
|
+
* validator.parse({ pointer: "/foo~0bar~1baz" }); // Multiple escapes in one token
|
|
36
|
+
*
|
|
37
|
+
* // Real-world JSON structure examples
|
|
38
|
+
* // For JSON: { "user": { "settings": { "theme": "dark" } } }
|
|
39
|
+
* validator.parse({ pointer: "/user" }); // Access user object
|
|
40
|
+
* validator.parse({ pointer: "/user/settings" }); // Access nested settings
|
|
41
|
+
* validator.parse({ pointer: "/user/settings/theme" }); // Access theme value
|
|
42
|
+
*
|
|
43
|
+
* // For JSON: { "items": [{"name": "Item1"}, {"name": "Item2"}] }
|
|
44
|
+
* validator.parse({ pointer: "/items" }); // Access items array
|
|
45
|
+
* validator.parse({ pointer: "/items/0" }); // First item
|
|
46
|
+
* validator.parse({ pointer: "/items/1" }); // Second item
|
|
47
|
+
* validator.parse({ pointer: "/items/0/name" }); // Name of first item
|
|
48
|
+
*
|
|
49
|
+
* // For JSON with special property names
|
|
50
|
+
* // { "": "empty name", "a/b": "slash in name", "c~d": "tilde in name" }
|
|
51
|
+
* validator.parse({ pointer: "/" }); // Empty property name
|
|
52
|
+
* validator.parse({ pointer: "/a~1b" }); // Property "a/b" (/ escaped as ~1)
|
|
53
|
+
* validator.parse({ pointer: "/c~0d" }); // Property "c~d" (~ escaped as ~0)
|
|
54
|
+
*
|
|
55
|
+
* // Edge cases
|
|
56
|
+
* validator.parse({ pointer: "/0" }); // String "0" as property name
|
|
57
|
+
* validator.parse({ pointer: "/-1" }); // String "-1" as property name
|
|
58
|
+
* validator.parse({ pointer: "/123" }); // Numeric string as property name
|
|
59
|
+
* validator.parse({ pointer: "/true" }); // Boolean string as property name
|
|
60
|
+
* validator.parse({ pointer: "/null" }); // Null string as property name
|
|
61
|
+
*
|
|
62
|
+
* // ❌ INVALID JSON Pointers
|
|
63
|
+
* validator.parse({ pointer: "foo" }); // Missing initial slash
|
|
64
|
+
* validator.parse({ pointer: "foo/bar" }); // Missing initial slash
|
|
65
|
+
* validator.parse({ pointer: "/foo/" }); // Trailing slash (points to empty property)
|
|
66
|
+
* validator.parse({ pointer: "/foo//" }); // Double slash (empty token)
|
|
67
|
+
* validator.parse({ pointer: "/~" }); // Incomplete escape sequence
|
|
68
|
+
* validator.parse({ pointer: "/~2" }); // Invalid escape sequence (only ~0 and ~1 allowed)
|
|
69
|
+
* validator.parse({ pointer: "/~3" }); // Invalid escape sequence
|
|
70
|
+
* validator.parse({ pointer: "/foo~" }); // Incomplete escape at end
|
|
71
|
+
* validator.parse({ pointer: "/foo~bar" }); // Tilde without proper escape
|
|
72
|
+
* validator.parse({ pointer: "/foo~/bar" }); // Incomplete escape in middle
|
|
73
|
+
* validator.parse({ pointer: "~/foo" }); // Escape at start without leading slash
|
|
74
|
+
* validator.parse({ pointer: "/foo bar" }); // Space in token (technically valid by RFC but often problematic)
|
|
75
|
+
* validator.parse({ pointer: "/foo\tbar" }); // Tab character
|
|
76
|
+
* validator.parse({ pointer: "/foo\nbar" }); // Newline character
|
|
77
|
+
* validator.parse({ pointer: "/foo\rbar" }); // Carriage return
|
|
78
|
+
* validator.parse({ pointer: "/foo\"bar" }); // Double quote (valid but can be problematic)
|
|
79
|
+
* validator.parse({ pointer: "/foo'bar" }); // Single quote (valid but can be problematic)
|
|
80
|
+
* validator.parse({ pointer: "/foo\\bar" }); // Backslash (valid but can be confusing)
|
|
81
|
+
* validator.parse({ pointer: " /foo" }); // Leading space
|
|
82
|
+
* validator.parse({ pointer: "/foo " }); // Trailing space
|
|
83
|
+
* validator.parse({ pointer: "//foo" }); // Double slash at start
|
|
84
|
+
* ```
|
|
85
|
+
* @params
|
|
86
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional custom error message factory
|
|
87
|
+
* @returns Validation function that checks JSON Pointer format
|
|
88
|
+
* @customError
|
|
89
|
+
* ```typescript
|
|
90
|
+
* .jsonPointer({
|
|
91
|
+
* messageFactory: ({ path, value }) =>
|
|
92
|
+
* `${path} must be valid JSON Pointer format, received: ${value}`
|
|
93
|
+
* })
|
|
94
|
+
* ```
|
|
95
|
+
* @since 0.1.0-alpha
|
|
96
|
+
*/
|
|
97
|
+
import type { MessageContext } from "./types";
|
|
98
|
+
export declare const stringJsonPointerPlugin: import("../..").TypedPlugin<"stringJsonPointer", "jsonPointer", (options?: {
|
|
99
|
+
messageFactory?: (context: MessageContext) => string;
|
|
100
|
+
}) => {
|
|
101
|
+
check: (value: string) => boolean;
|
|
102
|
+
code: string;
|
|
103
|
+
getErrorMessage: (value: string, path: string) => string;
|
|
104
|
+
params: {
|
|
105
|
+
messageFactory?: (context: MessageContext) => string;
|
|
106
|
+
}[];
|
|
107
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ValidationOptions, MessageContext } from "./types";
|
|
2
|
+
export interface StringMaxContext extends MessageContext {
|
|
3
|
+
max: number;
|
|
4
|
+
actual: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* @luq-plugin
|
|
8
|
+
* @name stringMax
|
|
9
|
+
* @category standard
|
|
10
|
+
* @description Validates that a string does not exceed the specified maximum length
|
|
11
|
+
* @allowedTypes ["string"]
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Basic usage - set maximum string length
|
|
15
|
+
* const validator = Builder()
|
|
16
|
+
* .use(stringMaxPlugin)
|
|
17
|
+
* .for<UserProfile>()
|
|
18
|
+
* .v("username", (b) => b.string.max(20))
|
|
19
|
+
* .v("bio", (b) => b.string.max(500))
|
|
20
|
+
* .build();
|
|
21
|
+
*
|
|
22
|
+
* // Combined with min for length range
|
|
23
|
+
* builder.v("description", b => b.string.min(10).max(200))
|
|
24
|
+
* ```
|
|
25
|
+
* @params
|
|
26
|
+
* - max: number - Maximum character count
|
|
27
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
28
|
+
* @returns Validation function that returns true if string length is within the maximum
|
|
29
|
+
* @customError
|
|
30
|
+
* ```typescript
|
|
31
|
+
* .max(100, {
|
|
32
|
+
* messageFactory: ({ path, value, params }) =>
|
|
33
|
+
* `${path} must not exceed ${params.max} characters (current: ${value.length})`
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
* @since 0.1.0-alpha
|
|
37
|
+
*/
|
|
38
|
+
export declare const stringMaxPlugin: import("../..").TypedPlugin<"stringMax", "max", (maxLength: number, options?: ValidationOptions<StringMaxContext>) => {
|
|
39
|
+
check: (value: any) => boolean;
|
|
40
|
+
code: string;
|
|
41
|
+
getErrorMessage: (value: any, path: string) => string;
|
|
42
|
+
params: (number | ValidationOptions<StringMaxContext>)[];
|
|
43
|
+
}, readonly ["string"], "validator", "standard">;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { ValidationOptions, MessageContext } from "./types";
|
|
2
|
+
export interface StringMinContext extends MessageContext {
|
|
3
|
+
min: number;
|
|
4
|
+
actual: number;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* @luq-plugin
|
|
8
|
+
* @name stringMin
|
|
9
|
+
* @category standard
|
|
10
|
+
* @description Validates that a string has at least the specified minimum length
|
|
11
|
+
* @allowedTypes ["string"]
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* // Basic usage - set minimum string length
|
|
15
|
+
* const validator = Builder()
|
|
16
|
+
* .use(stringMinPlugin)
|
|
17
|
+
* .for<UserProfile>()
|
|
18
|
+
* .v("password", (b) => b.string.min(8))
|
|
19
|
+
* .v("username", (b) => b.string.min(3))
|
|
20
|
+
* .build();
|
|
21
|
+
*
|
|
22
|
+
* // Combined with other validators
|
|
23
|
+
* builder.v("bio", b => b.string.required().min(10).max(500))
|
|
24
|
+
* ```
|
|
25
|
+
* @params
|
|
26
|
+
* - min: number - Minimum character count
|
|
27
|
+
* - options?: { messageFactory?: (context: MessageContext) => string } - Optional configuration
|
|
28
|
+
* @returns Validation function that returns true if string length is at least the minimum
|
|
29
|
+
* @customError
|
|
30
|
+
* ```typescript
|
|
31
|
+
* .min(8, {
|
|
32
|
+
* messageFactory: ({ path, value, params }) =>
|
|
33
|
+
* `${path} must be at least ${params.min} characters (current: ${value.length})`
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
* @since 0.1.0-alpha
|
|
37
|
+
*/
|
|
38
|
+
export declare const stringMinPlugin: import("../..").TypedPlugin<"stringMin", "min", (minLength: number, options?: ValidationOptions<StringMinContext>) => {
|
|
39
|
+
check: (value: any) => boolean;
|
|
40
|
+
code: string;
|
|
41
|
+
getErrorMessage: (value: any, path: string) => any;
|
|
42
|
+
params: (number | ValidationOptions<StringMinContext>)[];
|
|
43
|
+
}, readonly ["string"], "validator", "standard">;
|