@oxog/vld 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -0
- package/README.md +1129 -1128
- package/dist/coercion/bigint.js +1 -1
- package/dist/coercion/boolean.js +1 -1
- package/dist/coercion/date.js +1 -1
- package/dist/coercion/number.d.ts.map +1 -1
- package/dist/coercion/number.js +20 -4
- package/dist/coercion/number.js.map +1 -1
- package/dist/coercion/string.d.ts.map +1 -1
- package/dist/coercion/string.js +9 -73
- package/dist/coercion/string.js.map +1 -1
- package/dist/index.d.ts +593 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +76 -5
- package/dist/index.js.map +1 -1
- package/dist/locales/af.d.ts.map +1 -1
- package/dist/locales/af.js +18 -1
- package/dist/locales/af.js.map +1 -1
- package/dist/locales/ar.d.ts.map +1 -1
- package/dist/locales/ar.js +18 -1
- package/dist/locales/ar.js.map +1 -1
- package/dist/locales/backup-en.d.ts +3 -0
- package/dist/locales/backup-en.d.ts.map +1 -0
- package/dist/locales/backup-en.js +105 -0
- package/dist/locales/backup-en.js.map +1 -0
- package/dist/locales/bn.d.ts.map +1 -1
- package/dist/locales/bn.js +18 -1
- package/dist/locales/bn.js.map +1 -1
- package/dist/locales/da.d.ts.map +1 -1
- package/dist/locales/da.js +18 -1
- package/dist/locales/da.js.map +1 -1
- package/dist/locales/de.d.ts.map +1 -1
- package/dist/locales/de.js +18 -1
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/en.d.ts.map +1 -1
- package/dist/locales/en.js +18 -1
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es-MX.d.ts.map +1 -1
- package/dist/locales/es-MX.js +17 -1
- package/dist/locales/es-MX.js.map +1 -1
- package/dist/locales/es.d.ts.map +1 -1
- package/dist/locales/es.js +18 -1
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fi.d.ts.map +1 -1
- package/dist/locales/fi.js +18 -1
- package/dist/locales/fi.js.map +1 -1
- package/dist/locales/fr.d.ts.map +1 -1
- package/dist/locales/fr.js +18 -1
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/hi.d.ts.map +1 -1
- package/dist/locales/hi.js +18 -1
- package/dist/locales/hi.js.map +1 -1
- package/dist/locales/id.d.ts.map +1 -1
- package/dist/locales/id.js +18 -1
- package/dist/locales/id.js.map +1 -1
- package/dist/locales/it.d.ts.map +1 -1
- package/dist/locales/it.js +18 -1
- package/dist/locales/it.js.map +1 -1
- package/dist/locales/ja.d.ts.map +1 -1
- package/dist/locales/ja.js +18 -1
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.d.ts.map +1 -1
- package/dist/locales/ko.js +18 -1
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/nl.d.ts.map +1 -1
- package/dist/locales/nl.js +18 -1
- package/dist/locales/nl.js.map +1 -1
- package/dist/locales/no.d.ts.map +1 -1
- package/dist/locales/no.js +18 -1
- package/dist/locales/no.js.map +1 -1
- package/dist/locales/pl.d.ts.map +1 -1
- package/dist/locales/pl.js +18 -1
- package/dist/locales/pl.js.map +1 -1
- package/dist/locales/pt-BR.d.ts.map +1 -1
- package/dist/locales/pt-BR.js +18 -1
- package/dist/locales/pt-BR.js.map +1 -1
- package/dist/locales/pt.d.ts.map +1 -1
- package/dist/locales/pt.js +18 -1
- package/dist/locales/pt.js.map +1 -1
- package/dist/locales/ru.d.ts.map +1 -1
- package/dist/locales/ru.js +18 -1
- package/dist/locales/ru.js.map +1 -1
- package/dist/locales/sv.d.ts.map +1 -1
- package/dist/locales/sv.js +18 -1
- package/dist/locales/sv.js.map +1 -1
- package/dist/locales/sw.d.ts.map +1 -1
- package/dist/locales/sw.js +18 -1
- package/dist/locales/sw.js.map +1 -1
- package/dist/locales/th.d.ts.map +1 -1
- package/dist/locales/th.js +18 -1
- package/dist/locales/th.js.map +1 -1
- package/dist/locales/tr.d.ts.map +1 -1
- package/dist/locales/tr.js +18 -1
- package/dist/locales/tr.js.map +1 -1
- package/dist/locales/types.d.ts +13 -0
- package/dist/locales/types.d.ts.map +1 -1
- package/dist/locales/types.js.map +1 -1
- package/dist/locales/vi.d.ts.map +1 -1
- package/dist/locales/vi.js +18 -1
- package/dist/locales/vi.js.map +1 -1
- package/dist/locales/zh.d.ts.map +1 -1
- package/dist/locales/zh.js +18 -1
- package/dist/locales/zh.js.map +1 -1
- package/dist/utils/codec-utils.d.ts +2 -0
- package/dist/utils/codec-utils.d.ts.map +1 -1
- package/dist/utils/codec-utils.js +22 -4
- package/dist/utils/codec-utils.js.map +1 -1
- package/dist/utils/deep-merge.d.ts +2 -0
- package/dist/utils/deep-merge.d.ts.map +1 -1
- package/dist/utils/deep-merge.js +22 -39
- package/dist/utils/deep-merge.js.map +1 -1
- package/dist/utils/ip-validation.d.ts +11 -0
- package/dist/utils/ip-validation.d.ts.map +1 -0
- package/dist/utils/ip-validation.js +78 -0
- package/dist/utils/ip-validation.js.map +1 -0
- package/dist/utils/security.d.ts +12 -0
- package/dist/utils/security.d.ts.map +1 -0
- package/dist/utils/security.js +61 -0
- package/dist/utils/security.js.map +1 -0
- package/dist/validators/array.d.ts +3 -1
- package/dist/validators/array.d.ts.map +1 -1
- package/dist/validators/array.js +41 -15
- package/dist/validators/array.js.map +1 -1
- package/dist/validators/base.d.ts +131 -0
- package/dist/validators/base.d.ts.map +1 -1
- package/dist/validators/base.js +247 -1
- package/dist/validators/base.js.map +1 -1
- package/dist/validators/base64.js +1 -1
- package/dist/validators/bigint.d.ts +20 -0
- package/dist/validators/bigint.d.ts.map +1 -1
- package/dist/validators/bigint.js +39 -1
- package/dist/validators/bigint.js.map +1 -1
- package/dist/validators/boolean.js +29 -1
- package/dist/validators/boolean.js.map +1 -1
- package/dist/validators/codec.js +1 -1
- package/dist/validators/custom.d.ts +47 -0
- package/dist/validators/custom.d.ts.map +1 -0
- package/dist/validators/custom.js +50 -0
- package/dist/validators/custom.js.map +1 -0
- package/dist/validators/date.d.ts +16 -0
- package/dist/validators/date.d.ts.map +1 -1
- package/dist/validators/date.js +62 -7
- package/dist/validators/date.js.map +1 -1
- package/dist/validators/discriminated-union.d.ts +29 -0
- package/dist/validators/discriminated-union.d.ts.map +1 -0
- package/dist/validators/discriminated-union.js +98 -0
- package/dist/validators/discriminated-union.js.map +1 -0
- package/dist/validators/enum.d.ts +10 -0
- package/dist/validators/enum.d.ts.map +1 -1
- package/dist/validators/enum.js +38 -1
- package/dist/validators/enum.js.map +1 -1
- package/dist/validators/file.d.ts +57 -0
- package/dist/validators/file.d.ts.map +1 -0
- package/dist/validators/file.js +114 -0
- package/dist/validators/file.js.map +1 -0
- package/dist/validators/function.d.ts +26 -0
- package/dist/validators/function.d.ts.map +1 -0
- package/dist/validators/function.js +45 -0
- package/dist/validators/function.js.map +1 -0
- package/dist/validators/hex.d.ts.map +1 -1
- package/dist/validators/hex.js +3 -2
- package/dist/validators/hex.js.map +1 -1
- package/dist/validators/index.d.ts +18 -1
- package/dist/validators/index.d.ts.map +1 -1
- package/dist/validators/index.js +16 -1
- package/dist/validators/index.js.map +1 -1
- package/dist/validators/intersection.d.ts.map +1 -1
- package/dist/validators/intersection.js +15 -8
- package/dist/validators/intersection.js.map +1 -1
- package/dist/validators/json.d.ts +26 -0
- package/dist/validators/json.d.ts.map +1 -0
- package/dist/validators/json.js +64 -0
- package/dist/validators/json.js.map +1 -0
- package/dist/validators/lazy.d.ts +28 -0
- package/dist/validators/lazy.d.ts.map +1 -0
- package/dist/validators/lazy.js +42 -0
- package/dist/validators/lazy.js.map +1 -0
- package/dist/validators/literal.js +1 -1
- package/dist/validators/map.js +1 -1
- package/dist/validators/nan.d.ts +17 -0
- package/dist/validators/nan.d.ts.map +1 -0
- package/dist/validators/nan.js +32 -0
- package/dist/validators/nan.js.map +1 -0
- package/dist/validators/never.js +1 -1
- package/dist/validators/null.d.ts +16 -0
- package/dist/validators/null.d.ts.map +1 -0
- package/dist/validators/null.js +31 -0
- package/dist/validators/null.js.map +1 -0
- package/dist/validators/number.d.ts +22 -0
- package/dist/validators/number.d.ts.map +1 -1
- package/dist/validators/number.js +47 -8
- package/dist/validators/number.js.map +1 -1
- package/dist/validators/object.d.ts +32 -0
- package/dist/validators/object.d.ts.map +1 -1
- package/dist/validators/object.js +125 -8
- package/dist/validators/object.js.map +1 -1
- package/dist/validators/record.d.ts +15 -2
- package/dist/validators/record.d.ts.map +1 -1
- package/dist/validators/record.js +74 -4
- package/dist/validators/record.js.map +1 -1
- package/dist/validators/set.js +1 -1
- package/dist/validators/string-bool.d.ts +61 -0
- package/dist/validators/string-bool.d.ts.map +1 -0
- package/dist/validators/string-bool.js +127 -0
- package/dist/validators/string-bool.js.map +1 -0
- package/dist/validators/string-formats.d.ts +97 -0
- package/dist/validators/string-formats.d.ts.map +1 -0
- package/dist/validators/string-formats.js +120 -0
- package/dist/validators/string-formats.js.map +1 -0
- package/dist/validators/string.d.ts.map +1 -1
- package/dist/validators/string.js +2 -73
- package/dist/validators/string.js.map +1 -1
- package/dist/validators/symbol.js +1 -1
- package/dist/validators/template-literal.d.ts +32 -0
- package/dist/validators/template-literal.d.ts.map +1 -0
- package/dist/validators/template-literal.js +101 -0
- package/dist/validators/template-literal.js.map +1 -0
- package/dist/validators/tuple.js +1 -1
- package/dist/validators/uint8array.d.ts +21 -4
- package/dist/validators/uint8array.d.ts.map +1 -1
- package/dist/validators/uint8array.js +34 -23
- package/dist/validators/uint8array.js.map +1 -1
- package/dist/validators/undefined.d.ts +16 -0
- package/dist/validators/undefined.d.ts.map +1 -0
- package/dist/validators/undefined.js +31 -0
- package/dist/validators/undefined.js.map +1 -0
- package/dist/validators/union.d.ts +2 -0
- package/dist/validators/union.d.ts.map +1 -1
- package/dist/validators/union.js +15 -21
- package/dist/validators/union.js.map +1 -1
- package/dist/validators/void.js +1 -1
- package/dist/validators/xor.d.ts +23 -0
- package/dist/validators/xor.d.ts.map +1 -0
- package/dist/validators/xor.js +64 -0
- package/dist/validators/xor.js.map +1 -0
- package/package.json +2 -2
- package/dist/index-new.d.ts.map +0 -1
- package/dist/locales.d.ts +0 -54
- package/dist/locales.d.ts.map +0 -1
- package/dist/locales.js +0 -732
- package/dist/locales.js.map +0 -1
- package/dist/validators/object-optimized.d.ts +0 -23
- package/dist/validators/object-optimized.d.ts.map +0 -1
- package/dist/validators/object-optimized.js +0 -179
- package/dist/validators/object-optimized.js.map +0 -1
- package/dist/validators/object-ultra.d.ts +0 -34
- package/dist/validators/object-ultra.d.ts.map +0 -1
- package/dist/validators/object-ultra.js +0 -175
- package/dist/validators/object-ultra.js.map +0 -1
- package/dist/validators/string-ultra.d.ts +0 -49
- package/dist/validators/string-ultra.d.ts.map +0 -1
- package/dist/validators/string-ultra.js +0 -217
- package/dist/validators/string-ultra.js.map +0 -1
- package/dist/validators/union-optimized.d.ts +0 -15
- package/dist/validators/union-optimized.d.ts.map +0 -1
- package/dist/validators/union-optimized.js +0 -92
- package/dist/validators/union-optimized.js.map +0 -1
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VldDiscriminatedUnion - Fast union validation using discriminator field
|
|
3
|
+
* Part of Zod 4 API parity implementation
|
|
4
|
+
* Provides O(1) lookup performance by using a discriminator key
|
|
5
|
+
*/
|
|
6
|
+
import { VldBase } from './base.js';
|
|
7
|
+
import { VldObject } from './object.js';
|
|
8
|
+
import { VldLiteral } from './literal.js';
|
|
9
|
+
import { VldEnum } from './enum.js';
|
|
10
|
+
/**
|
|
11
|
+
* Extract literal values from a schema
|
|
12
|
+
*/
|
|
13
|
+
function extractLiteralValues(schema) {
|
|
14
|
+
if (schema instanceof VldLiteral) {
|
|
15
|
+
const value = schema.literal;
|
|
16
|
+
return [value];
|
|
17
|
+
}
|
|
18
|
+
if (schema instanceof VldEnum) {
|
|
19
|
+
return schema.values;
|
|
20
|
+
}
|
|
21
|
+
throw new Error('Discriminator must be a literal or enum schema');
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Discriminated union validator - validates union based on discriminator key
|
|
25
|
+
* Much faster than regular union when you have a discriminator field
|
|
26
|
+
*/
|
|
27
|
+
export class VldDiscriminatedUnion extends VldBase {
|
|
28
|
+
constructor(_discriminator, _options) {
|
|
29
|
+
super();
|
|
30
|
+
this._discriminator = _discriminator;
|
|
31
|
+
this._options = _options;
|
|
32
|
+
// Build discriminator map for O(1) lookup
|
|
33
|
+
this._discriminatorMap = new Map();
|
|
34
|
+
for (const option of _options) {
|
|
35
|
+
if (!(option instanceof VldObject)) {
|
|
36
|
+
throw new Error('All options in a discriminated union must be objects');
|
|
37
|
+
}
|
|
38
|
+
const discriminatorSchema = option.config?.shape?.[this._discriminator];
|
|
39
|
+
if (!discriminatorSchema) {
|
|
40
|
+
throw new Error(`Missing discriminator key "${this._discriminator}" in one of the options`);
|
|
41
|
+
}
|
|
42
|
+
const values = extractLiteralValues(discriminatorSchema);
|
|
43
|
+
for (const value of values) {
|
|
44
|
+
if (this._discriminatorMap.has(value)) {
|
|
45
|
+
throw new Error(`Duplicate discriminator value "${String(value)}" found in discriminated union`);
|
|
46
|
+
}
|
|
47
|
+
this._discriminatorMap.set(value, option);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
static create(discriminator, options) {
|
|
52
|
+
return new VldDiscriminatedUnion(discriminator, options);
|
|
53
|
+
}
|
|
54
|
+
parse(value) {
|
|
55
|
+
const result = this.safeParse(value);
|
|
56
|
+
if (!result.success) {
|
|
57
|
+
throw result.error;
|
|
58
|
+
}
|
|
59
|
+
return result.data;
|
|
60
|
+
}
|
|
61
|
+
safeParse(value) {
|
|
62
|
+
// Check if input is an object
|
|
63
|
+
if (typeof value !== 'object' || value === null) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: new Error(`Expected object, received ${value === null ? 'null' : typeof value}`)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
// Get discriminator value
|
|
70
|
+
const discriminatorValue = value[this._discriminator];
|
|
71
|
+
// Look up matching schema
|
|
72
|
+
const matchedSchema = this._discriminatorMap.get(discriminatorValue);
|
|
73
|
+
if (!matchedSchema) {
|
|
74
|
+
const validValues = Array.from(this._discriminatorMap.keys());
|
|
75
|
+
return {
|
|
76
|
+
success: false,
|
|
77
|
+
error: new Error(`Invalid discriminator value for "${this._discriminator}". ` +
|
|
78
|
+
`Expected one of: ${JSON.stringify(validValues)}, ` +
|
|
79
|
+
`received: ${JSON.stringify(discriminatorValue)}`)
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// Validate against matched schema
|
|
83
|
+
return matchedSchema.safeParse(value);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Get the discriminator key
|
|
87
|
+
*/
|
|
88
|
+
getDiscriminator() {
|
|
89
|
+
return this._discriminator;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Get all options
|
|
93
|
+
*/
|
|
94
|
+
getOptions() {
|
|
95
|
+
return this._options;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=discriminated-union.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discriminated-union.js","sourceRoot":"","sources":["../../src/validators/discriminated-union.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGjC;;GAEG;AACH,SAAS,oBAAoB,CAAC,MAA6B;IACzD,IAAI,MAAM,YAAY,UAAU,EAAE,CAAC;QACjC,MAAM,KAAK,GAAI,MAAc,CAAC,OAAO,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;QAC9B,OAAQ,MAAc,CAAC,MAAmB,CAAC;IAC7C,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;AACpE,CAAC;AAED;;;GAGG;AACH,MAAM,OAAO,qBACX,SAAQ,OAA2E;IAInF,YACmB,cAAiB,EACjB,QAAiB;QAElC,KAAK,EAAE,CAAC;QAHS,mBAAc,GAAd,cAAc,CAAG;QACjB,aAAQ,GAAR,QAAQ,CAAS;QAIlC,0CAA0C;QAC1C,IAAI,CAAC,iBAAiB,GAAG,IAAI,GAAG,EAAE,CAAC;QAEnC,KAAK,MAAM,MAAM,IAAI,QAAQ,EAAE,CAAC;YAC9B,IAAI,CAAC,CAAC,MAAM,YAAY,SAAS,CAAC,EAAE,CAAC;gBACnC,MAAM,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC1E,CAAC;YAED,MAAM,mBAAmB,GAAI,MAAc,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;YACjF,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACzB,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,cAAc,yBAAyB,CAAC,CAAC;YAC9F,CAAC;YAED,MAAM,MAAM,GAAG,oBAAoB,CAAC,mBAAmB,CAAC,CAAC;YAEzD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;gBAC3B,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtC,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;gBACnG,CAAC;gBACD,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,MAAM,CACX,aAAgB,EAChB,OAAgB;QAEhB,OAAO,IAAI,qBAAqB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED,KAAK,CAAC,KAAc;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,MAAM,CAAC,KAAK,CAAC;QACrB,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,SAAS,CAAC,KAAc;QACtB,8BAA8B;QAC9B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YAChD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAI,KAAK,CACd,6BAA6B,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CACtE;aACF,CAAC;QACJ,CAAC;QAED,0BAA0B;QAC1B,MAAM,kBAAkB,GAAI,KAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAE/D,0BAA0B;QAC1B,MAAM,aAAa,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;QAErE,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,CAAC,CAAC;YAC9D,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAI,KAAK,CACd,oCAAoC,IAAI,CAAC,cAAc,KAAK;oBAC5D,oBAAoB,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI;oBACnD,aAAa,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,EAAE,CAClD;aACF,CAAC;QACJ,CAAC;QAED,kCAAkC;QAClC,OAAO,aAAa,CAAC,SAAS,CAAC,KAAK,CAA2E,CAAC;IAClH,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,UAAU;QACR,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF","sourcesContent":["/**\n * VldDiscriminatedUnion - Fast union validation using discriminator field\n * Part of Zod 4 API parity implementation\n * Provides O(1) lookup performance by using a discriminator key\n */\n\nimport { VldBase } from './base';\nimport { VldObject } from './object';\nimport { VldLiteral } from './literal';\nimport { VldEnum } from './enum';\nimport type { ParseResult } from './base';\n\n/**\n * Extract literal values from a schema\n */\nfunction extractLiteralValues(schema: VldBase<unknown, any>): unknown[] {\n if (schema instanceof VldLiteral) {\n const value = (schema as any).literal;\n return [value];\n }\n if (schema instanceof VldEnum) {\n return (schema as any).values as unknown[];\n }\n throw new Error('Discriminator must be a literal or enum schema');\n}\n\n/**\n * Discriminated union validator - validates union based on discriminator key\n * Much faster than regular union when you have a discriminator field\n */\nexport class VldDiscriminatedUnion<K extends string, Options extends VldBase<any, any>[]>\n extends VldBase<unknown, Options[number] extends VldBase<any, infer T> ? T : never> {\n\n private readonly _discriminatorMap: Map<unknown, VldBase<any, any>>;\n\n constructor(\n private readonly _discriminator: K,\n private readonly _options: Options\n ) {\n super();\n\n // Build discriminator map for O(1) lookup\n this._discriminatorMap = new Map();\n\n for (const option of _options) {\n if (!(option instanceof VldObject)) {\n throw new Error('All options in a discriminated union must be objects');\n }\n\n const discriminatorSchema = (option as any).config?.shape?.[this._discriminator];\n if (!discriminatorSchema) {\n throw new Error(`Missing discriminator key \"${this._discriminator}\" in one of the options`);\n }\n\n const values = extractLiteralValues(discriminatorSchema);\n\n for (const value of values) {\n if (this._discriminatorMap.has(value)) {\n throw new Error(`Duplicate discriminator value \"${String(value)}\" found in discriminated union`);\n }\n this._discriminatorMap.set(value, option);\n }\n }\n }\n\n static create<K extends string, Options extends VldBase<any, any>[]>(\n discriminator: K,\n options: Options\n ): VldDiscriminatedUnion<K, Options> {\n return new VldDiscriminatedUnion(discriminator, options);\n }\n\n parse(value: unknown): Options[number] extends VldBase<any, infer T> ? T : never {\n const result = this.safeParse(value);\n if (!result.success) {\n throw result.error;\n }\n return result.data;\n }\n\n safeParse(value: unknown): ParseResult<Options[number] extends VldBase<any, infer T> ? T : never> {\n // Check if input is an object\n if (typeof value !== 'object' || value === null) {\n return {\n success: false,\n error: new Error(\n `Expected object, received ${value === null ? 'null' : typeof value}`\n )\n };\n }\n\n // Get discriminator value\n const discriminatorValue = (value as any)[this._discriminator];\n\n // Look up matching schema\n const matchedSchema = this._discriminatorMap.get(discriminatorValue);\n\n if (!matchedSchema) {\n const validValues = Array.from(this._discriminatorMap.keys());\n return {\n success: false,\n error: new Error(\n `Invalid discriminator value for \"${this._discriminator}\". ` +\n `Expected one of: ${JSON.stringify(validValues)}, ` +\n `received: ${JSON.stringify(discriminatorValue)}`\n )\n };\n }\n\n // Validate against matched schema\n return matchedSchema.safeParse(value) as ParseResult<Options[number] extends VldBase<any, infer T> ? T : never>;\n }\n\n /**\n * Get the discriminator key\n */\n getDiscriminator(): K {\n return this._discriminator;\n }\n\n /**\n * Get all options\n */\n getOptions(): Options {\n return this._options;\n }\n}\n"]}
|
|
@@ -21,5 +21,15 @@ export declare class VldEnum<T extends readonly [string, ...string[]]> extends V
|
|
|
21
21
|
* Safely parse and validate an enum value
|
|
22
22
|
*/
|
|
23
23
|
safeParse(value: unknown): ParseResult<T[number]>;
|
|
24
|
+
/**
|
|
25
|
+
* Exclude specific values from the enum
|
|
26
|
+
* Creates a new enum validator without the specified values
|
|
27
|
+
*/
|
|
28
|
+
exclude<const E extends readonly string[]>(...excludeValues: E): VldEnum<T[number] extends E[number] ? never : T[number] extends Exclude<T[number], E[number]> ? T : Exclude<T, E>>;
|
|
29
|
+
/**
|
|
30
|
+
* Extract specific values from the enum
|
|
31
|
+
* Creates a new enum validator with only the specified values
|
|
32
|
+
*/
|
|
33
|
+
extract<const E extends readonly string[]>(...extractValues: E): VldEnum<[string, ...string[]]>;
|
|
24
34
|
}
|
|
25
35
|
//# sourceMappingURL=enum.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enum.d.ts","sourceRoot":"","sources":["../../src/validators/enum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAG9C;;GAEG;AACH,qBAAa,OAAO,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAE,SAAQ,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAK7F,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IALhC;;OAEG;IACH,OAAO;IAOP;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"enum.d.ts","sourceRoot":"","sources":["../../src/validators/enum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAG9C;;GAEG;AACH,qBAAa,OAAO,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAE,SAAQ,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;IAK7F,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC;IALhC;;OAEG;IACH,OAAO;IAOP;;OAEG;IACH,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAI9E;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,CAAC,CAAC,MAAM,CAAC;IAiBhC;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAuBjD;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,EAAE,GAAG,aAAa,EAAE,CAAC,GAAG,OAAO,CACtE,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC,SAAS,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAC1G;IASD;;;OAGG;IACH,OAAO,CAAC,KAAK,CAAC,CAAC,SAAS,SAAS,MAAM,EAAE,EAAE,GAAG,aAAa,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CAQhG"}
|
package/dist/validators/enum.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { VldBase } from './base.js';
|
|
2
|
-
import { getMessages } from '../locales.js';
|
|
2
|
+
import { getMessages } from '../locales/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* Immutable enum validator for string enum values
|
|
5
5
|
*/
|
|
@@ -22,6 +22,11 @@ export class VldEnum extends VldBase {
|
|
|
22
22
|
* Parse and validate an enum value
|
|
23
23
|
*/
|
|
24
24
|
parse(value) {
|
|
25
|
+
// BUG-002 FIX: Add type check before includes() to prevent type confusion
|
|
26
|
+
if (typeof value !== 'string') {
|
|
27
|
+
throw new Error(this.errorMessage ||
|
|
28
|
+
getMessages().enumExpected([...this.values], JSON.stringify(value)));
|
|
29
|
+
}
|
|
25
30
|
if (!this.values.includes(value)) {
|
|
26
31
|
throw new Error(this.errorMessage ||
|
|
27
32
|
getMessages().enumExpected([...this.values], JSON.stringify(value)));
|
|
@@ -32,6 +37,14 @@ export class VldEnum extends VldBase {
|
|
|
32
37
|
* Safely parse and validate an enum value
|
|
33
38
|
*/
|
|
34
39
|
safeParse(value) {
|
|
40
|
+
// BUG-002 FIX: Add type check before includes() to prevent type confusion
|
|
41
|
+
if (typeof value !== 'string') {
|
|
42
|
+
return {
|
|
43
|
+
success: false,
|
|
44
|
+
error: new Error(this.errorMessage ||
|
|
45
|
+
getMessages().enumExpected([...this.values], JSON.stringify(value)))
|
|
46
|
+
};
|
|
47
|
+
}
|
|
35
48
|
if (this.values.includes(value)) {
|
|
36
49
|
return { success: true, data: value };
|
|
37
50
|
}
|
|
@@ -41,5 +54,29 @@ export class VldEnum extends VldBase {
|
|
|
41
54
|
getMessages().enumExpected([...this.values], JSON.stringify(value)))
|
|
42
55
|
};
|
|
43
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Exclude specific values from the enum
|
|
59
|
+
* Creates a new enum validator without the specified values
|
|
60
|
+
*/
|
|
61
|
+
exclude(...excludeValues) {
|
|
62
|
+
const filtered = this.values.filter(v => !excludeValues.includes(v));
|
|
63
|
+
if (filtered.length === 0) {
|
|
64
|
+
throw new Error('Cannot exclude all enum values');
|
|
65
|
+
}
|
|
66
|
+
// Type assertion needed because TypeScript can't guarantee the filtered array maintains the required type
|
|
67
|
+
return new VldEnum(filtered, this.errorMessage);
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Extract specific values from the enum
|
|
71
|
+
* Creates a new enum validator with only the specified values
|
|
72
|
+
*/
|
|
73
|
+
extract(...extractValues) {
|
|
74
|
+
const extracted = this.values.filter(v => extractValues.includes(v));
|
|
75
|
+
if (extracted.length === 0) {
|
|
76
|
+
throw new Error('Cannot extract non-existent enum values');
|
|
77
|
+
}
|
|
78
|
+
// Type assertion needed because TypeScript can't guarantee the extracted array has the required type
|
|
79
|
+
return new VldEnum(extracted, this.errorMessage);
|
|
80
|
+
}
|
|
44
81
|
}
|
|
45
82
|
//# sourceMappingURL=enum.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enum.js","sourceRoot":"","sources":["../../src/validators/enum.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,OAAkD,SAAQ,OAA0B;IAC/F;;OAEG;IACH,YACmB,MAAS,EACT,YAAqB;QAEtC,KAAK,EAAE,CAAC;QAHS,WAAM,GAAN,MAAM,CAAG;QACT,iBAAY,GAAZ,YAAY,CAAS;IAGxC,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,MAAM,CAA2C,MAAS;QAC/D,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAc;QAClB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,
|
|
1
|
+
{"version":3,"file":"enum.js","sourceRoot":"","sources":["../../src/validators/enum.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldBase, ParseResult } from './base';\r\nimport { getMessages } from '../locales';\r\n\r\n/**\r\n * Immutable enum validator for string enum values\r\n */\r\nexport class VldEnum<T extends readonly [string, ...string[]]> extends VldBase<string, T[number]> {\r\n /**\r\n * Private constructor to enforce immutability\r\n */\r\n private constructor(\r\n private readonly values: T,\r\n private readonly errorMessage?: string\r\n ) {\r\n super();\r\n }\r\n \r\n /**\r\n * Create a new enum validator\r\n */\r\n static create<T extends readonly [string, ...string[]]>(values: T): VldEnum<T> {\r\n return new VldEnum(values);\r\n }\r\n \r\n /**\r\n * Parse and validate an enum value\r\n */\r\n parse(value: unknown): T[number] {\r\n // BUG-002 FIX: Add type check before includes() to prevent type confusion\r\n if (typeof value !== 'string') {\r\n throw new Error(\r\n this.errorMessage ||\r\n getMessages().enumExpected([...this.values], JSON.stringify(value))\r\n );\r\n }\r\n if (!this.values.includes(value)) {\r\n throw new Error(\r\n this.errorMessage ||\r\n getMessages().enumExpected([...this.values], JSON.stringify(value))\r\n );\r\n }\r\n return value as T[number];\r\n }\r\n\r\n /**\r\n * Safely parse and validate an enum value\r\n */\r\n safeParse(value: unknown): ParseResult<T[number]> {\r\n // BUG-002 FIX: Add type check before includes() to prevent type confusion\r\n if (typeof value !== 'string') {\r\n return {\r\n success: false,\r\n error: new Error(\r\n this.errorMessage ||\r\n getMessages().enumExpected([...this.values], JSON.stringify(value))\r\n )\r\n };\r\n }\r\n if (this.values.includes(value)) {\r\n return { success: true, data: value as T[number] };\r\n }\r\n return {\r\n success: false,\r\n error: new Error(\r\n this.errorMessage ||\r\n getMessages().enumExpected([...this.values], JSON.stringify(value))\r\n )\r\n };\r\n }\r\n\r\n /**\r\n * Exclude specific values from the enum\r\n * Creates a new enum validator without the specified values\r\n */\r\n exclude<const E extends readonly string[]>(...excludeValues: E): VldEnum<\r\n T[number] extends E[number] ? never : T[number] extends Exclude<T[number], E[number]> ? T : Exclude<T, E>\r\n > {\r\n const filtered = this.values.filter(v => !excludeValues.includes(v));\r\n if (filtered.length === 0) {\r\n throw new Error('Cannot exclude all enum values');\r\n }\r\n // Type assertion needed because TypeScript can't guarantee the filtered array maintains the required type\r\n return new VldEnum(filtered as any, this.errorMessage);\r\n }\r\n\r\n /**\r\n * Extract specific values from the enum\r\n * Creates a new enum validator with only the specified values\r\n */\r\n extract<const E extends readonly string[]>(...extractValues: E): VldEnum<[string, ...string[]]> {\r\n const extracted = this.values.filter(v => extractValues.includes(v));\r\n if (extracted.length === 0) {\r\n throw new Error('Cannot extract non-existent enum values');\r\n }\r\n // Type assertion needed because TypeScript can't guarantee the extracted array has the required type\r\n return new VldEnum(extracted as any, this.errorMessage);\r\n }\r\n}"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { VldBase, ParseResult } from './base';
|
|
2
|
+
/**
|
|
3
|
+
* File representation for validation
|
|
4
|
+
* In browsers: File object
|
|
5
|
+
* In Node.js: Object with size and type properties
|
|
6
|
+
*/
|
|
7
|
+
export type VldFileValue = File | {
|
|
8
|
+
size: number;
|
|
9
|
+
type: string;
|
|
10
|
+
name?: string;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Immutable file validator for file uploads
|
|
14
|
+
* Supports size and MIME type validation
|
|
15
|
+
*/
|
|
16
|
+
export declare class VldFile extends VldBase<unknown, VldFileValue> {
|
|
17
|
+
private readonly checks;
|
|
18
|
+
private constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Create a new file validator
|
|
21
|
+
*/
|
|
22
|
+
static create(): VldFile;
|
|
23
|
+
/**
|
|
24
|
+
* Parse and validate a file value
|
|
25
|
+
*/
|
|
26
|
+
parse(value: unknown): VldFileValue;
|
|
27
|
+
/**
|
|
28
|
+
* Run all validation checks on the file
|
|
29
|
+
*/
|
|
30
|
+
private runChecks;
|
|
31
|
+
/**
|
|
32
|
+
* Safely parse and validate a file value
|
|
33
|
+
*/
|
|
34
|
+
safeParse(value: unknown): ParseResult<VldFileValue>;
|
|
35
|
+
/**
|
|
36
|
+
* Set minimum file size in bytes
|
|
37
|
+
*/
|
|
38
|
+
min(bytes: number, message?: string): VldFile;
|
|
39
|
+
/**
|
|
40
|
+
* Set maximum file size in bytes
|
|
41
|
+
*/
|
|
42
|
+
max(bytes: number, message?: string): VldFile;
|
|
43
|
+
/**
|
|
44
|
+
* Set allowed MIME types
|
|
45
|
+
*/
|
|
46
|
+
mime(types: string | string[], message?: string): VldFile;
|
|
47
|
+
/**
|
|
48
|
+
* Set both minimum and maximum file size
|
|
49
|
+
*/
|
|
50
|
+
size(min: number, max: number, message?: string): VldFile;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Helper function to create file validators
|
|
54
|
+
* Usage: v.file().min(1024).max(10485760).mime(['image/jpeg', 'image/png'])
|
|
55
|
+
*/
|
|
56
|
+
export declare function file(): VldFile;
|
|
57
|
+
//# sourceMappingURL=file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/validators/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAW9C;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhF;;;GAGG;AACH,qBAAa,OAAQ,SAAQ,OAAO,CAAC,OAAO,EAAE,YAAY,CAAC;IAEvD,OAAO,CAAC,QAAQ,CAAC,MAAM;IADzB,OAAO;IAMP;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,OAAO;IAIxB;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,YAAY;IA2BnC;;OAEG;IACH,OAAO,CAAC,SAAS;IAqCjB;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,YAAY,CAAC;IAQpD;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAI7C;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAKzD;;OAEG;IACH,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;CAG1D;AAED;;;GAGG;AACH,wBAAgB,IAAI,IAAI,OAAO,CAE9B"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import { VldBase } from './base.js';
|
|
2
|
+
import { getMessages } from '../locales/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Immutable file validator for file uploads
|
|
5
|
+
* Supports size and MIME type validation
|
|
6
|
+
*/
|
|
7
|
+
export class VldFile extends VldBase {
|
|
8
|
+
constructor(checks = []) {
|
|
9
|
+
super();
|
|
10
|
+
this.checks = checks;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Create a new file validator
|
|
14
|
+
*/
|
|
15
|
+
static create() {
|
|
16
|
+
return new VldFile();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Parse and validate a file value
|
|
20
|
+
*/
|
|
21
|
+
parse(value) {
|
|
22
|
+
// Check if File API is supported
|
|
23
|
+
const FileSupported = typeof File !== 'undefined';
|
|
24
|
+
if (!FileSupported) {
|
|
25
|
+
throw new Error(getMessages().fileNotSupported || 'File API not supported in this environment');
|
|
26
|
+
}
|
|
27
|
+
// Check if value is a File object
|
|
28
|
+
if (!(value instanceof File)) {
|
|
29
|
+
// Allow plain object with size and type for Node.js compatibility
|
|
30
|
+
if (typeof value === 'object' &&
|
|
31
|
+
value !== null &&
|
|
32
|
+
'size' in value &&
|
|
33
|
+
'type' in value) {
|
|
34
|
+
const fileObj = value;
|
|
35
|
+
return this.runChecks(fileObj);
|
|
36
|
+
}
|
|
37
|
+
throw new Error(getMessages().invalidFile || 'Expected a File object');
|
|
38
|
+
}
|
|
39
|
+
return this.runChecks(value);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Run all validation checks on the file
|
|
43
|
+
*/
|
|
44
|
+
runChecks(file) {
|
|
45
|
+
const msgs = getMessages();
|
|
46
|
+
for (const check of this.checks) {
|
|
47
|
+
switch (check.type) {
|
|
48
|
+
case 'min':
|
|
49
|
+
if (file.size < check.value) {
|
|
50
|
+
throw new Error(check.message ||
|
|
51
|
+
(msgs.fileMinSize?.(check.value) || `File size must be at least ${check.value} bytes`));
|
|
52
|
+
}
|
|
53
|
+
break;
|
|
54
|
+
case 'max':
|
|
55
|
+
if (file.size > check.value) {
|
|
56
|
+
throw new Error(check.message ||
|
|
57
|
+
(msgs.fileMaxSize?.(check.value) || `File size must not exceed ${check.value} bytes`));
|
|
58
|
+
}
|
|
59
|
+
break;
|
|
60
|
+
case 'mime':
|
|
61
|
+
if (!check.value.includes(file.type)) {
|
|
62
|
+
throw new Error(check.message ||
|
|
63
|
+
(msgs.fileMimeType?.(check.value) || `Invalid file type. Expected: ${check.value.join(', ')}`));
|
|
64
|
+
}
|
|
65
|
+
break;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return file;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Safely parse and validate a file value
|
|
72
|
+
*/
|
|
73
|
+
safeParse(value) {
|
|
74
|
+
try {
|
|
75
|
+
return { success: true, data: this.parse(value) };
|
|
76
|
+
}
|
|
77
|
+
catch (error) {
|
|
78
|
+
return { success: false, error: error };
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Set minimum file size in bytes
|
|
83
|
+
*/
|
|
84
|
+
min(bytes, message) {
|
|
85
|
+
return new VldFile([...this.checks, { type: 'min', value: bytes, message }]);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Set maximum file size in bytes
|
|
89
|
+
*/
|
|
90
|
+
max(bytes, message) {
|
|
91
|
+
return new VldFile([...this.checks, { type: 'max', value: bytes, message }]);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Set allowed MIME types
|
|
95
|
+
*/
|
|
96
|
+
mime(types, message) {
|
|
97
|
+
const typeArray = Array.isArray(types) ? types : [types];
|
|
98
|
+
return new VldFile([...this.checks, { type: 'mime', value: typeArray, message }]);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Set both minimum and maximum file size
|
|
102
|
+
*/
|
|
103
|
+
size(min, max, message) {
|
|
104
|
+
return this.min(min, message).max(max, message);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Helper function to create file validators
|
|
109
|
+
* Usage: v.file().min(1024).max(10485760).mime(['image/jpeg', 'image/png'])
|
|
110
|
+
*/
|
|
111
|
+
export function file() {
|
|
112
|
+
return VldFile.create();
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/validators/file.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAiBzC;;;GAGG;AACH,MAAM,OAAO,OAAQ,SAAQ,OAA8B;IACzD,YACmB,SAA+B,EAAE;QAElD,KAAK,EAAE,CAAC;QAFS,WAAM,GAAN,MAAM,CAA2B;IAGpD,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,MAAM;QACX,OAAO,IAAI,OAAO,EAAE,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAc;QAClB,iCAAiC;QACjC,MAAM,aAAa,GAAG,OAAO,IAAI,KAAK,WAAW,CAAC;QAElD,IAAI,CAAC,aAAa,EAAE,CAAC;YACnB,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,gBAAgB,IAAI,4CAA4C,CAAC,CAAC;QAClG,CAAC;QAED,kCAAkC;QAClC,IAAI,CAAC,CAAC,KAAK,YAAY,IAAI,CAAC,EAAE,CAAC;YAC7B,kEAAkE;YAClE,IACE,OAAO,KAAK,KAAK,QAAQ;gBACzB,KAAK,KAAK,IAAI;gBACd,MAAM,IAAI,KAAK;gBACf,MAAM,IAAI,KAAK,EACf,CAAC;gBACD,MAAM,OAAO,GAAG,KAAsD,CAAC;gBACvE,OAAO,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACjC,CAAC;YAED,MAAM,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,WAAW,IAAI,wBAAwB,CAAC,CAAC;QACzE,CAAC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACK,SAAS,CAAC,IAAkB;QAClC,MAAM,IAAI,GAAG,WAAW,EAAE,CAAC;QAE3B,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,KAAK;oBACR,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;wBAC5B,MAAM,IAAI,KAAK,CACb,KAAK,CAAC,OAAO;4BACb,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,8BAA8B,KAAK,CAAC,KAAK,QAAQ,CAAC,CACvF,CAAC;oBACJ,CAAC;oBACD,MAAM;gBAER,KAAK,KAAK;oBACR,IAAI,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,KAAK,EAAE,CAAC;wBAC5B,MAAM,IAAI,KAAK,CACb,KAAK,CAAC,OAAO;4BACb,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,6BAA6B,KAAK,CAAC,KAAK,QAAQ,CAAC,CACtF,CAAC;oBACJ,CAAC;oBACD,MAAM;gBAER,KAAK,MAAM;oBACT,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;wBACrC,MAAM,IAAI,KAAK,CACb,KAAK,CAAC,OAAO;4BACb,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,gCAAgC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAC/F,CAAC;oBACJ,CAAC;oBACD,MAAM;YACV,CAAC;QACH,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,KAAc;QACtB,IAAI,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAc,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAa,EAAE,OAAgB;QACjC,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED;;OAEG;IACH,GAAG,CAAC,KAAa,EAAE,OAAgB;QACjC,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,KAAwB,EAAE,OAAgB;QAC7C,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QACzD,OAAO,IAAI,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;IACpF,CAAC;IAED;;OAEG;IACH,IAAI,CAAC,GAAW,EAAE,GAAW,EAAE,OAAgB;QAC7C,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAClD,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,IAAI;IAClB,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC;AAC1B,CAAC","sourcesContent":["import { VldBase, ParseResult } from './base';\nimport { getMessages } from '../locales';\n\n/**\n * File validation check types\n */\ntype FileCheck =\n | { type: 'min'; value: number; message?: string }\n | { type: 'max'; value: number; message?: string }\n | { type: 'mime'; value: string[]; message?: string };\n\n/**\n * File representation for validation\n * In browsers: File object\n * In Node.js: Object with size and type properties\n */\nexport type VldFileValue = File | { size: number; type: string; name?: string };\n\n/**\n * Immutable file validator for file uploads\n * Supports size and MIME type validation\n */\nexport class VldFile extends VldBase<unknown, VldFileValue> {\n private constructor(\n private readonly checks: readonly FileCheck[] = []\n ) {\n super();\n }\n\n /**\n * Create a new file validator\n */\n static create(): VldFile {\n return new VldFile();\n }\n\n /**\n * Parse and validate a file value\n */\n parse(value: unknown): VldFileValue {\n // Check if File API is supported\n const FileSupported = typeof File !== 'undefined';\n\n if (!FileSupported) {\n throw new Error(getMessages().fileNotSupported || 'File API not supported in this environment');\n }\n\n // Check if value is a File object\n if (!(value instanceof File)) {\n // Allow plain object with size and type for Node.js compatibility\n if (\n typeof value === 'object' &&\n value !== null &&\n 'size' in value &&\n 'type' in value\n ) {\n const fileObj = value as { size: number; type: string; name?: string };\n return this.runChecks(fileObj);\n }\n\n throw new Error(getMessages().invalidFile || 'Expected a File object');\n }\n\n return this.runChecks(value);\n }\n\n /**\n * Run all validation checks on the file\n */\n private runChecks(file: VldFileValue): VldFileValue {\n const msgs = getMessages();\n\n for (const check of this.checks) {\n switch (check.type) {\n case 'min':\n if (file.size < check.value) {\n throw new Error(\n check.message ||\n (msgs.fileMinSize?.(check.value) || `File size must be at least ${check.value} bytes`)\n );\n }\n break;\n\n case 'max':\n if (file.size > check.value) {\n throw new Error(\n check.message ||\n (msgs.fileMaxSize?.(check.value) || `File size must not exceed ${check.value} bytes`)\n );\n }\n break;\n\n case 'mime':\n if (!check.value.includes(file.type)) {\n throw new Error(\n check.message ||\n (msgs.fileMimeType?.(check.value) || `Invalid file type. Expected: ${check.value.join(', ')}`)\n );\n }\n break;\n }\n }\n\n return file;\n }\n\n /**\n * Safely parse and validate a file value\n */\n safeParse(value: unknown): ParseResult<VldFileValue> {\n try {\n return { success: true, data: this.parse(value) };\n } catch (error) {\n return { success: false, error: error as Error };\n }\n }\n\n /**\n * Set minimum file size in bytes\n */\n min(bytes: number, message?: string): VldFile {\n return new VldFile([...this.checks, { type: 'min', value: bytes, message }]);\n }\n\n /**\n * Set maximum file size in bytes\n */\n max(bytes: number, message?: string): VldFile {\n return new VldFile([...this.checks, { type: 'max', value: bytes, message }]);\n }\n\n /**\n * Set allowed MIME types\n */\n mime(types: string | string[], message?: string): VldFile {\n const typeArray = Array.isArray(types) ? types : [types];\n return new VldFile([...this.checks, { type: 'mime', value: typeArray, message }]);\n }\n\n /**\n * Set both minimum and maximum file size\n */\n size(min: number, max: number, message?: string): VldFile {\n return this.min(min, message).max(max, message);\n }\n}\n\n/**\n * Helper function to create file validators\n * Usage: v.file().min(1024).max(10485760).mime(['image/jpeg', 'image/png'])\n */\nexport function file(): VldFile {\n return VldFile.create();\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { VldBase, ParseResult } from './base';
|
|
2
|
+
/**
|
|
3
|
+
* Immutable function validator
|
|
4
|
+
* Validates that a value is a function
|
|
5
|
+
*/
|
|
6
|
+
export declare class VldFunction extends VldBase<unknown, Function> {
|
|
7
|
+
private constructor();
|
|
8
|
+
/**
|
|
9
|
+
* Create a new function validator
|
|
10
|
+
*/
|
|
11
|
+
static create(): VldFunction;
|
|
12
|
+
/**
|
|
13
|
+
* Parse and validate a function value
|
|
14
|
+
*/
|
|
15
|
+
parse(value: unknown): Function;
|
|
16
|
+
/**
|
|
17
|
+
* Safely parse and validate a function value
|
|
18
|
+
*/
|
|
19
|
+
safeParse(value: unknown): ParseResult<Function>;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Helper function to create function validators
|
|
23
|
+
* Usage: v.function()
|
|
24
|
+
*/
|
|
25
|
+
export declare function functionValidator(): VldFunction;
|
|
26
|
+
//# sourceMappingURL=function.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function.d.ts","sourceRoot":"","sources":["../../src/validators/function.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAG9C;;;GAGG;AACH,qBAAa,WAAY,SAAQ,OAAO,CAAC,OAAO,EAAE,QAAQ,CAAC;IACzD,OAAO;IAIP;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,WAAW;IAI5B;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,QAAQ;IAU/B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,QAAQ,CAAC;CAOjD;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,IAAI,WAAW,CAE/C"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { VldBase } from './base.js';
|
|
2
|
+
import { getMessages } from '../locales/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Immutable function validator
|
|
5
|
+
* Validates that a value is a function
|
|
6
|
+
*/
|
|
7
|
+
export class VldFunction extends VldBase {
|
|
8
|
+
constructor() {
|
|
9
|
+
super();
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create a new function validator
|
|
13
|
+
*/
|
|
14
|
+
static create() {
|
|
15
|
+
return new VldFunction();
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse and validate a function value
|
|
19
|
+
*/
|
|
20
|
+
parse(value) {
|
|
21
|
+
if (typeof value !== 'function') {
|
|
22
|
+
throw new Error(getMessages().invalidFunction || 'Expected a function');
|
|
23
|
+
}
|
|
24
|
+
return value;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Safely parse and validate a function value
|
|
28
|
+
*/
|
|
29
|
+
safeParse(value) {
|
|
30
|
+
try {
|
|
31
|
+
return { success: true, data: this.parse(value) };
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
return { success: false, error: error };
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Helper function to create function validators
|
|
40
|
+
* Usage: v.function()
|
|
41
|
+
*/
|
|
42
|
+
export function functionValidator() {
|
|
43
|
+
return VldFunction.create();
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=function.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"function.js","sourceRoot":"","sources":["../../src/validators/function.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,OAAO,WAAY,SAAQ,OAA0B;IACzD;QACE,KAAK,EAAE,CAAC;IACV,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,MAAM;QACX,OAAO,IAAI,WAAW,EAAE,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAc;QAClB,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAChC,MAAM,IAAI,KAAK,CACb,WAAW,EAAE,CAAC,eAAe,IAAI,qBAAqB,CACvD,CAAC;QACJ,CAAC;QAED,OAAO,KAAiB,CAAC;IAC3B,CAAC;IAED;;OAEG;IACH,SAAS,CAAC,KAAc;QACtB,IAAI,CAAC;YACH,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;QACpD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAc,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,WAAW,CAAC,MAAM,EAAE,CAAC;AAC9B,CAAC","sourcesContent":["import { VldBase, ParseResult } from './base';\nimport { getMessages } from '../locales';\n\n/**\n * Immutable function validator\n * Validates that a value is a function\n */\nexport class VldFunction extends VldBase<unknown, Function> {\n private constructor() {\n super();\n }\n\n /**\n * Create a new function validator\n */\n static create(): VldFunction {\n return new VldFunction();\n }\n\n /**\n * Parse and validate a function value\n */\n parse(value: unknown): Function {\n if (typeof value !== 'function') {\n throw new Error(\n getMessages().invalidFunction || 'Expected a function'\n );\n }\n\n return value as Function;\n }\n\n /**\n * Safely parse and validate a function value\n */\n safeParse(value: unknown): ParseResult<Function> {\n try {\n return { success: true, data: this.parse(value) };\n } catch (error) {\n return { success: false, error: error as Error };\n }\n }\n}\n\n/**\n * Helper function to create function validators\n * Usage: v.function()\n */\nexport function functionValidator(): VldFunction {\n return VldFunction.create();\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hex.d.ts","sourceRoot":"","sources":["../../src/validators/hex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAI9C;;GAEG;AACH,qBAAa,MAAO,SAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"hex.d.ts","sourceRoot":"","sources":["../../src/validators/hex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAI9C;;GAEG;AACH,qBAAa,MAAO,SAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;IAEjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAErD,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;gBAExB,SAAS,UAAQ;IAK7B,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAQ7B,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;IAoC9C;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB,MAAM,CAAC,MAAM,CAAC,SAAS,UAAQ,GAAG,MAAM;CAGzC"}
|
package/dist/validators/hex.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VldBase } from './base.js';
|
|
2
2
|
import { VldError, createIssue } from '../errors.js';
|
|
3
|
-
import { getMessages } from '../locales.js';
|
|
3
|
+
import { getMessages } from '../locales/index.js';
|
|
4
4
|
/**
|
|
5
5
|
* Hexadecimal string validator
|
|
6
6
|
*/
|
|
@@ -57,5 +57,6 @@ export class VldHex extends VldBase {
|
|
|
57
57
|
return new VldHex(lowercase);
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
|
-
|
|
60
|
+
// BUG-008 FIX: Use * instead of + to allow empty hex strings (consistent with base64 validator)
|
|
61
|
+
VldHex.HEX_REGEX = /^[0-9a-fA-F]*$/;
|
|
61
62
|
//# sourceMappingURL=hex.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../../src/validators/hex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,MAAO,SAAQ,OAAuB;
|
|
1
|
+
{"version":3,"file":"hex.js","sourceRoot":"","sources":["../../src/validators/hex.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;GAEG;AACH,MAAM,OAAO,MAAO,SAAQ,OAAuB;IAMjD,YAAY,SAAS,GAAG,KAAK;QAC3B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,KAAc;QAClB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACpB,MAAM,MAAM,CAAC,KAAK,CAAC;QACrB,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB,CAAC;IAED,SAAS,CAAC,KAAc;QACtB,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAI,QAAQ,CAAC;oBAClB,WAAW,CAAC,cAAc,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,cAAc,CAAC;iBAC9D,CAAC;aACH,CAAC;QACJ,CAAC;QAED,mCAAmC;QACnC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAI,QAAQ,CAAC;oBAClB,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC;iBACpD,CAAC;aACH,CAAC;QACJ,CAAC;QAED,oCAAoC;QACpC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,IAAI,QAAQ,CAAC;oBAClB,WAAW,CAAC,QAAQ,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,UAAU,CAAC;iBACpD,CAAC;aACH,CAAC;QACJ,CAAC;QAED,6BAA6B;QAC7B,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;QAErE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAClD,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,SAAS,GAAG,KAAK;QAC7B,OAAO,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;;AA/DD,gGAAgG;AACxE,gBAAS,GAAG,gBAAgB,CAAC","sourcesContent":["import { VldBase, ParseResult } from './base';\r\nimport { VldError, createIssue } from '../errors';\r\nimport { getMessages } from '../locales';\r\n\r\n/**\r\n * Hexadecimal string validator\r\n */\r\nexport class VldHex extends VldBase<string, string> {\r\n // BUG-008 FIX: Use * instead of + to allow empty hex strings (consistent with base64 validator)\r\n private static readonly HEX_REGEX = /^[0-9a-fA-F]*$/;\r\n \r\n private readonly lowercase: boolean;\r\n \r\n constructor(lowercase = false) {\r\n super();\r\n this.lowercase = lowercase;\r\n }\r\n \r\n parse(value: unknown): string {\r\n const result = this.safeParse(value);\r\n if (!result.success) {\r\n throw result.error;\r\n }\r\n return result.data;\r\n }\r\n \r\n safeParse(value: unknown): ParseResult<string> {\r\n if (typeof value !== 'string') {\r\n return {\r\n success: false,\r\n error: new VldError([\r\n createIssue('invalid_type', [], getMessages().expectedString)\r\n ])\r\n };\r\n }\r\n \r\n // Check if it's a valid hex string\r\n if (!VldHex.HEX_REGEX.test(value)) {\r\n return {\r\n success: false,\r\n error: new VldError([\r\n createIssue('custom', [], getMessages().invalidHex)\r\n ])\r\n };\r\n }\r\n \r\n // Check if even length (full bytes)\r\n if (value.length % 2 !== 0) {\r\n return {\r\n success: false,\r\n error: new VldError([\r\n createIssue('custom', [], getMessages().invalidHex)\r\n ])\r\n };\r\n }\r\n \r\n // Normalize case if required\r\n const normalizedValue = this.lowercase ? value.toLowerCase() : value;\r\n \r\n return { success: true, data: normalizedValue };\r\n }\r\n \r\n /**\r\n * Require lowercase hex characters\r\n */\r\n lowercaseMode(): VldHex {\r\n return new VldHex(true);\r\n }\r\n \r\n static create(lowercase = false): VldHex {\r\n return new VldHex(lowercase);\r\n }\r\n}"]}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Main entry point for all validators
|
|
3
3
|
*/
|
|
4
|
-
export { VldBase, ParseResult, VldRefine, VldTransform, VldDefault, VldCatch, VldOptional, VldNullable, VldNullish } from './base';
|
|
4
|
+
export { VldBase, ParseResult, VldRefine, VldTransform, VldDefault, VldCatch, VldOptional, VldNullable, VldNullish, VldPipe, VldReadonly, VldBrand, SuperRefineContext, VldSuperRefine, VldPreprocess } from './base';
|
|
5
5
|
export { VldString } from './string';
|
|
6
6
|
export { VldNumber } from './number';
|
|
7
7
|
export { VldBoolean } from './boolean';
|
|
8
8
|
export { VldDate } from './date';
|
|
9
|
+
export { VldStringBool } from './string-bool';
|
|
9
10
|
export { VldArray } from './array';
|
|
10
11
|
export { VldObject } from './object';
|
|
11
12
|
export { VldUnion } from './union';
|
|
@@ -22,6 +23,22 @@ export { VldAny } from './any';
|
|
|
22
23
|
export { VldUnknown } from './unknown';
|
|
23
24
|
export { VldVoid } from './void';
|
|
24
25
|
export { VldNever } from './never';
|
|
26
|
+
export { VldNull } from './null';
|
|
27
|
+
export { VldUndefined } from './undefined';
|
|
28
|
+
export { VldNan } from './nan';
|
|
29
|
+
export { VldLazy } from './lazy';
|
|
30
|
+
export { VldDiscriminatedUnion } from './discriminated-union';
|
|
31
|
+
export { VldXor } from './xor';
|
|
32
|
+
export { VldJson } from './json';
|
|
33
|
+
export { VldTemplateLiteral, templateLiteral } from './template-literal';
|
|
34
|
+
export { VldCustom, custom } from './custom';
|
|
35
|
+
export type { CustomValidatorOptions } from './custom';
|
|
36
|
+
export { VldFile, file } from './file';
|
|
37
|
+
export type { VldFileValue } from './file';
|
|
38
|
+
export { VldFunction, functionValidator } from './function';
|
|
39
|
+
export { email, uuid, uuidv4, hostname, emoji, base64, base64url, hex, jwt, nanoid, cuid, cuid2, ulid, ipv4, ipv6, mac, cidrv4, e164, hash, iso, stringFormat, regexes } from './string-formats';
|
|
25
40
|
import { VldBase } from './base';
|
|
26
41
|
export type Infer<T extends VldBase<any, any>> = T extends VldBase<any, infer U> ? U : never;
|
|
42
|
+
export type Input<T extends VldBase<any, any>> = T extends VldBase<infer I, any> ? I : never;
|
|
43
|
+
export type Output<T extends VldBase<any, any>> = T extends VldBase<any, infer O> ? O : never;
|
|
27
44
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,OAAO,EACP,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,UAAU,EACX,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/validators/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,OAAO,EACP,WAAW,EACX,SAAS,EACT,YAAY,EACZ,UAAU,EACV,QAAQ,EACR,WAAW,EACX,WAAW,EACX,UAAU,EACV,OAAO,EACP,WAAW,EACX,QAAQ,EACR,kBAAkB,EAClB,cAAc,EACd,aAAa,EACd,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAGrC,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAC7C,YAAY,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AACvC,YAAY,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAG5D,OAAO,EACL,KAAK,EACL,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,KAAK,EACL,MAAM,EACN,SAAS,EACT,GAAG,EACH,GAAG,EACH,MAAM,EACN,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,IAAI,EACJ,GAAG,EACH,MAAM,EACN,IAAI,EACJ,IAAI,EACJ,GAAG,EACH,YAAY,EACZ,OAAO,EACR,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAGjC,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAG7F,MAAM,MAAM,KAAK,CAAC,CAAC,SAAS,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAC7F,MAAM,MAAM,MAAM,CAAC,CAAC,SAAS,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC"}
|
package/dist/validators/index.js
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
* Main entry point for all validators
|
|
3
3
|
*/
|
|
4
4
|
// Export base types and classes
|
|
5
|
-
export { VldBase, VldRefine, VldTransform, VldDefault, VldCatch, VldOptional, VldNullable, VldNullish } from './base.js';
|
|
5
|
+
export { VldBase, VldRefine, VldTransform, VldDefault, VldCatch, VldOptional, VldNullable, VldNullish, VldPipe, VldReadonly, VldBrand, VldSuperRefine, VldPreprocess } from './base.js';
|
|
6
6
|
// Export primitive validators
|
|
7
7
|
export { VldString } from './string.js';
|
|
8
8
|
export { VldNumber } from './number.js';
|
|
9
9
|
export { VldBoolean } from './boolean.js';
|
|
10
10
|
export { VldDate } from './date.js';
|
|
11
|
+
export { VldStringBool } from './string-bool.js';
|
|
11
12
|
// Export complex validators
|
|
12
13
|
export { VldArray } from './array.js';
|
|
13
14
|
export { VldObject } from './object.js';
|
|
@@ -27,4 +28,18 @@ export { VldAny } from './any.js';
|
|
|
27
28
|
export { VldUnknown } from './unknown.js';
|
|
28
29
|
export { VldVoid } from './void.js';
|
|
29
30
|
export { VldNever } from './never.js';
|
|
31
|
+
// Export Zod 4 parity validators
|
|
32
|
+
export { VldNull } from './null.js';
|
|
33
|
+
export { VldUndefined } from './undefined.js';
|
|
34
|
+
export { VldNan } from './nan.js';
|
|
35
|
+
export { VldLazy } from './lazy.js';
|
|
36
|
+
export { VldDiscriminatedUnion } from './discriminated-union.js';
|
|
37
|
+
export { VldXor } from './xor.js';
|
|
38
|
+
export { VldJson } from './json.js';
|
|
39
|
+
export { VldTemplateLiteral, templateLiteral } from './template-literal.js';
|
|
40
|
+
export { VldCustom, custom } from './custom.js';
|
|
41
|
+
export { VldFile, file } from './file.js';
|
|
42
|
+
export { VldFunction, functionValidator } from './function.js';
|
|
43
|
+
// Export string format validators
|
|
44
|
+
export { email, uuid, uuidv4, hostname, emoji, base64, base64url, hex, jwt, nanoid, cuid, cuid2, ulid, ipv4, ipv6, mac, cidrv4, e164, hash, iso, stringFormat, regexes } from './string-formats.js';
|
|
30
45
|
//# sourceMappingURL=index.js.map
|