@oxog/vld 1.0.0 → 1.1.1
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 +117 -102
- package/README.md +78 -13
- package/dist/coercion/bigint.d.ts +27 -0
- package/dist/coercion/bigint.d.ts.map +1 -0
- package/dist/coercion/bigint.js +108 -0
- package/dist/coercion/bigint.js.map +1 -0
- package/dist/coercion/boolean.d.ts +20 -0
- package/dist/coercion/boolean.d.ts.map +1 -0
- package/dist/coercion/boolean.js +63 -0
- package/dist/coercion/boolean.js.map +1 -0
- package/dist/coercion/date.d.ts +20 -0
- package/dist/coercion/date.d.ts.map +1 -0
- package/dist/coercion/date.js +52 -0
- package/dist/coercion/date.js.map +1 -0
- package/dist/coercion/number.d.ts +35 -0
- package/dist/coercion/number.d.ts.map +1 -0
- package/dist/coercion/number.js +144 -0
- package/dist/coercion/number.js.map +1 -0
- package/dist/coercion/string.d.ts +38 -0
- package/dist/coercion/string.d.ts.map +1 -0
- package/dist/coercion/string.js +168 -0
- package/dist/coercion/string.js.map +1 -0
- package/dist/index-new.d.ts.map +1 -0
- package/dist/index.d.ts +64 -257
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +86 -1164
- package/dist/index.js.map +1 -1
- package/dist/locales/af.js +3 -3
- package/dist/locales/af.js.map +1 -1
- package/dist/utils/deep-merge.d.ts +18 -0
- package/dist/utils/deep-merge.d.ts.map +1 -0
- package/dist/utils/deep-merge.js +68 -0
- package/dist/utils/deep-merge.js.map +1 -0
- package/dist/validators/any.d.ts +19 -0
- package/dist/validators/any.d.ts.map +1 -0
- package/dist/validators/any.js +25 -0
- package/dist/validators/any.js.map +1 -0
- package/dist/validators/array.d.ts +48 -0
- package/dist/validators/array.d.ts.map +1 -0
- package/dist/validators/array.js +135 -0
- package/dist/validators/array.js.map +1 -0
- package/dist/validators/base.d.ts +155 -0
- package/dist/validators/base.d.ts.map +1 -0
- package/dist/validators/base.js +245 -0
- package/dist/validators/base.js.map +1 -0
- package/dist/validators/bigint.d.ts +60 -0
- package/dist/validators/bigint.d.ts.map +1 -0
- package/dist/validators/bigint.js +104 -0
- package/dist/validators/bigint.js.map +1 -0
- package/dist/validators/boolean.d.ts +32 -0
- package/dist/validators/boolean.d.ts.map +1 -0
- package/dist/validators/boolean.js +86 -0
- package/dist/validators/boolean.js.map +1 -0
- package/dist/validators/date.d.ts +68 -0
- package/dist/validators/date.d.ts.map +1 -0
- package/dist/validators/date.js +148 -0
- package/dist/validators/date.js.map +1 -0
- package/dist/validators/enum.d.ts +25 -0
- package/dist/validators/enum.d.ts.map +1 -0
- package/dist/validators/enum.js +45 -0
- package/dist/validators/enum.js.map +1 -0
- package/dist/validators/index.d.ts +27 -0
- package/dist/validators/index.d.ts.map +1 -0
- package/dist/validators/index.js +30 -0
- package/dist/validators/index.js.map +1 -0
- package/dist/validators/intersection.d.ts +25 -0
- package/dist/validators/intersection.d.ts.map +1 -0
- package/dist/validators/intersection.js +57 -0
- package/dist/validators/intersection.js.map +1 -0
- package/dist/validators/literal.d.ts +25 -0
- package/dist/validators/literal.d.ts.map +1 -0
- package/dist/validators/literal.js +45 -0
- package/dist/validators/literal.js.map +1 -0
- package/dist/validators/map.d.ts +26 -0
- package/dist/validators/map.d.ts.map +1 -0
- package/dist/validators/map.js +54 -0
- package/dist/validators/map.js.map +1 -0
- package/dist/validators/never.d.ts +19 -0
- package/dist/validators/never.d.ts.map +1 -0
- package/dist/validators/never.js +29 -0
- package/dist/validators/never.js.map +1 -0
- package/dist/validators/number.d.ts +92 -0
- package/dist/validators/number.d.ts.map +1 -0
- package/dist/validators/number.js +173 -0
- package/dist/validators/number.js.map +1 -0
- package/dist/validators/object-optimized.d.ts +23 -0
- package/dist/validators/object-optimized.d.ts.map +1 -0
- package/dist/validators/object-optimized.js +179 -0
- package/dist/validators/object-optimized.js.map +1 -0
- package/dist/validators/object-ultra.d.ts +34 -0
- package/dist/validators/object-ultra.d.ts.map +1 -0
- package/dist/validators/object-ultra.js +175 -0
- package/dist/validators/object-ultra.js.map +1 -0
- package/dist/validators/object.d.ts +73 -0
- package/dist/validators/object.d.ts.map +1 -0
- package/dist/validators/object.js +289 -0
- package/dist/validators/object.js.map +1 -0
- package/dist/validators/record.d.ts +25 -0
- package/dist/validators/record.d.ts.map +1 -0
- package/dist/validators/record.js +52 -0
- package/dist/validators/record.js.map +1 -0
- package/dist/validators/set.d.ts +25 -0
- package/dist/validators/set.d.ts.map +1 -0
- package/dist/validators/set.js +51 -0
- package/dist/validators/set.js.map +1 -0
- package/dist/validators/string-ultra.d.ts +49 -0
- package/dist/validators/string-ultra.d.ts.map +1 -0
- package/dist/validators/string-ultra.js +217 -0
- package/dist/validators/string-ultra.js.map +1 -0
- package/dist/validators/string.d.ts +109 -0
- package/dist/validators/string.d.ts.map +1 -0
- package/dist/validators/string.js +242 -0
- package/dist/validators/string.js.map +1 -0
- package/dist/validators/symbol.d.ts +24 -0
- package/dist/validators/symbol.d.ts.map +1 -0
- package/dist/validators/symbol.js +42 -0
- package/dist/validators/symbol.js.map +1 -0
- package/dist/validators/tuple.d.ts +31 -0
- package/dist/validators/tuple.d.ts.map +1 -0
- package/dist/validators/tuple.js +55 -0
- package/dist/validators/tuple.js.map +1 -0
- package/dist/validators/union-optimized.d.ts +15 -0
- package/dist/validators/union-optimized.d.ts.map +1 -0
- package/dist/validators/union-optimized.js +92 -0
- package/dist/validators/union-optimized.js.map +1 -0
- package/dist/validators/union.d.ts +33 -0
- package/dist/validators/union.d.ts.map +1 -0
- package/dist/validators/union.js +121 -0
- package/dist/validators/union.js.map +1 -0
- package/dist/validators/unknown.d.ts +19 -0
- package/dist/validators/unknown.d.ts.map +1 -0
- package/dist/validators/unknown.js +25 -0
- package/dist/validators/unknown.js.map +1 -0
- package/dist/validators/void.d.ts +19 -0
- package/dist/validators/void.d.ts.map +1 -0
- package/dist/validators/void.js +35 -0
- package/dist/validators/void.js.map +1 -0
- package/package.json +12 -6
package/dist/index.js
CHANGED
|
@@ -1,1170 +1,92 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
//
|
|
45
|
-
export
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
52
|
-
parse(value) {
|
|
53
|
-
if (typeof value !== 'string') {
|
|
54
|
-
throw new Error(this.errorMessage || getMessages().invalidString);
|
|
55
|
-
}
|
|
56
|
-
let val = value;
|
|
57
|
-
// Apply transforms
|
|
58
|
-
for (const transform of this.transforms) {
|
|
59
|
-
val = transform(val);
|
|
60
|
-
}
|
|
61
|
-
// Apply checks
|
|
62
|
-
for (const check of this.checks) {
|
|
63
|
-
if (!check(val)) {
|
|
64
|
-
throw new Error(this.errorMessage || getMessages().invalidString);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return val;
|
|
68
|
-
}
|
|
69
|
-
safeParse(value) {
|
|
70
|
-
try {
|
|
71
|
-
return { success: true, data: this.parse(value) };
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
return { success: false, error: error };
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// Chainable methods
|
|
78
|
-
min(length, message) {
|
|
79
|
-
const newValidator = new VldString();
|
|
80
|
-
newValidator.checks = [...this.checks, (v) => v.length >= length];
|
|
81
|
-
newValidator.transforms = [...this.transforms];
|
|
82
|
-
newValidator.errorMessage = message || getMessages().stringMin(length);
|
|
83
|
-
return newValidator;
|
|
84
|
-
}
|
|
85
|
-
max(length, message) {
|
|
86
|
-
const newValidator = new VldString();
|
|
87
|
-
newValidator.checks = [...this.checks, (v) => v.length <= length];
|
|
88
|
-
newValidator.transforms = [...this.transforms];
|
|
89
|
-
newValidator.errorMessage = message || getMessages().stringMax(length);
|
|
90
|
-
return newValidator;
|
|
91
|
-
}
|
|
92
|
-
length(length, message) {
|
|
93
|
-
const newValidator = new VldString();
|
|
94
|
-
newValidator.checks = [...this.checks, (v) => v.length === length];
|
|
95
|
-
newValidator.transforms = [...this.transforms];
|
|
96
|
-
newValidator.errorMessage = message || getMessages().stringLength(length);
|
|
97
|
-
return newValidator;
|
|
98
|
-
}
|
|
99
|
-
email(message) {
|
|
100
|
-
const newValidator = new VldString();
|
|
101
|
-
newValidator.checks = [...this.checks, (v) => EMAIL_REGEX.test(v)];
|
|
102
|
-
newValidator.transforms = [...this.transforms];
|
|
103
|
-
newValidator.errorMessage = message || getMessages().stringEmail;
|
|
104
|
-
return newValidator;
|
|
105
|
-
}
|
|
106
|
-
url(message) {
|
|
107
|
-
const newValidator = new VldString();
|
|
108
|
-
newValidator.checks = [...this.checks, (v) => URL_REGEX.test(v)];
|
|
109
|
-
newValidator.transforms = [...this.transforms];
|
|
110
|
-
newValidator.errorMessage = message || getMessages().stringUrl;
|
|
111
|
-
return newValidator;
|
|
112
|
-
}
|
|
113
|
-
uuid(message) {
|
|
114
|
-
const newValidator = new VldString();
|
|
115
|
-
newValidator.checks = [...this.checks, (v) => UUID_REGEX.test(v)];
|
|
116
|
-
newValidator.transforms = [...this.transforms];
|
|
117
|
-
newValidator.errorMessage = message || getMessages().stringUuid;
|
|
118
|
-
return newValidator;
|
|
119
|
-
}
|
|
120
|
-
regex(pattern, message) {
|
|
121
|
-
const newValidator = new VldString();
|
|
122
|
-
newValidator.checks = [...this.checks, (v) => pattern.test(v)];
|
|
123
|
-
newValidator.transforms = [...this.transforms];
|
|
124
|
-
newValidator.errorMessage = message || getMessages().stringRegex;
|
|
125
|
-
return newValidator;
|
|
126
|
-
}
|
|
127
|
-
trim() {
|
|
128
|
-
const newValidator = new VldString();
|
|
129
|
-
newValidator.checks = [...this.checks];
|
|
130
|
-
newValidator.transforms = [...this.transforms, (v) => v.trim()];
|
|
131
|
-
newValidator.errorMessage = this.errorMessage;
|
|
132
|
-
return newValidator;
|
|
133
|
-
}
|
|
134
|
-
toLowerCase() {
|
|
135
|
-
const newValidator = new VldString();
|
|
136
|
-
newValidator.checks = [...this.checks];
|
|
137
|
-
newValidator.transforms = [...this.transforms, (v) => v.toLowerCase()];
|
|
138
|
-
newValidator.errorMessage = this.errorMessage;
|
|
139
|
-
return newValidator;
|
|
140
|
-
}
|
|
141
|
-
toUpperCase() {
|
|
142
|
-
const newValidator = new VldString();
|
|
143
|
-
newValidator.checks = [...this.checks];
|
|
144
|
-
newValidator.transforms = [...this.transforms, (v) => v.toUpperCase()];
|
|
145
|
-
newValidator.errorMessage = this.errorMessage;
|
|
146
|
-
return newValidator;
|
|
147
|
-
}
|
|
148
|
-
startsWith(str, message) {
|
|
149
|
-
const newValidator = new VldString();
|
|
150
|
-
newValidator.checks = [...this.checks, (v) => v.startsWith(str)];
|
|
151
|
-
newValidator.transforms = [...this.transforms];
|
|
152
|
-
newValidator.errorMessage = message || getMessages().stringStartsWith(str);
|
|
153
|
-
return newValidator;
|
|
154
|
-
}
|
|
155
|
-
endsWith(str, message) {
|
|
156
|
-
const newValidator = new VldString();
|
|
157
|
-
newValidator.checks = [...this.checks, (v) => v.endsWith(str)];
|
|
158
|
-
newValidator.transforms = [...this.transforms];
|
|
159
|
-
newValidator.errorMessage = message || getMessages().stringEndsWith(str);
|
|
160
|
-
return newValidator;
|
|
161
|
-
}
|
|
162
|
-
includes(str, message) {
|
|
163
|
-
const newValidator = new VldString();
|
|
164
|
-
newValidator.checks = [...this.checks, (v) => v.includes(str)];
|
|
165
|
-
newValidator.transforms = [...this.transforms];
|
|
166
|
-
newValidator.errorMessage = message || getMessages().stringIncludes(str);
|
|
167
|
-
return newValidator;
|
|
168
|
-
}
|
|
169
|
-
ip(message) {
|
|
170
|
-
const newValidator = new VldString();
|
|
171
|
-
newValidator.checks = [...this.checks, (v) => IPV4_REGEX.test(v) || IPV6_REGEX.test(v)];
|
|
172
|
-
newValidator.transforms = [...this.transforms];
|
|
173
|
-
newValidator.errorMessage = message || getMessages().stringIp;
|
|
174
|
-
return newValidator;
|
|
175
|
-
}
|
|
176
|
-
ipv4(message) {
|
|
177
|
-
const newValidator = new VldString();
|
|
178
|
-
newValidator.checks = [...this.checks, (v) => IPV4_REGEX.test(v)];
|
|
179
|
-
newValidator.transforms = [...this.transforms];
|
|
180
|
-
newValidator.errorMessage = message || getMessages().stringIpv4;
|
|
181
|
-
return newValidator;
|
|
182
|
-
}
|
|
183
|
-
ipv6(message) {
|
|
184
|
-
const newValidator = new VldString();
|
|
185
|
-
newValidator.checks = [...this.checks, (v) => IPV6_REGEX.test(v)];
|
|
186
|
-
newValidator.transforms = [...this.transforms];
|
|
187
|
-
newValidator.errorMessage = message || getMessages().stringIpv6;
|
|
188
|
-
return newValidator;
|
|
189
|
-
}
|
|
190
|
-
nonempty(message) {
|
|
191
|
-
const newValidator = new VldString();
|
|
192
|
-
newValidator.checks = [...this.checks, (v) => v.length > 0];
|
|
193
|
-
newValidator.transforms = [...this.transforms];
|
|
194
|
-
newValidator.errorMessage = message || getMessages().stringEmpty;
|
|
195
|
-
return newValidator;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
// Number validator
|
|
199
|
-
export class VldNumber extends VldBase {
|
|
200
|
-
constructor() {
|
|
201
|
-
super(...arguments);
|
|
202
|
-
this.checks = [];
|
|
203
|
-
this.errorMessage = getMessages().invalidNumber;
|
|
204
|
-
}
|
|
205
|
-
parse(value) {
|
|
206
|
-
if (typeof value !== 'number' || isNaN(value)) {
|
|
207
|
-
throw new Error(this.errorMessage || getMessages().invalidNumber);
|
|
208
|
-
}
|
|
209
|
-
for (const check of this.checks) {
|
|
210
|
-
if (!check(value)) {
|
|
211
|
-
throw new Error(this.errorMessage || getMessages().invalidNumber);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
return value;
|
|
215
|
-
}
|
|
216
|
-
safeParse(value) {
|
|
217
|
-
try {
|
|
218
|
-
return { success: true, data: this.parse(value) };
|
|
219
|
-
}
|
|
220
|
-
catch (error) {
|
|
221
|
-
return { success: false, error: error };
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
min(value, message) {
|
|
225
|
-
const newValidator = new VldNumber();
|
|
226
|
-
newValidator.checks = [...this.checks, (v) => v >= value];
|
|
227
|
-
newValidator.errorMessage = message || getMessages().numberMin(value);
|
|
228
|
-
return newValidator;
|
|
229
|
-
}
|
|
230
|
-
max(value, message) {
|
|
231
|
-
const newValidator = new VldNumber();
|
|
232
|
-
newValidator.checks = [...this.checks, (v) => v <= value];
|
|
233
|
-
newValidator.errorMessage = message || getMessages().numberMax(value);
|
|
234
|
-
return newValidator;
|
|
235
|
-
}
|
|
236
|
-
int(message) {
|
|
237
|
-
const newValidator = new VldNumber();
|
|
238
|
-
newValidator.checks = [...this.checks, (v) => Number.isInteger(v)];
|
|
239
|
-
newValidator.errorMessage = message || getMessages().numberInt;
|
|
240
|
-
return newValidator;
|
|
241
|
-
}
|
|
242
|
-
positive(message) {
|
|
243
|
-
const newValidator = new VldNumber();
|
|
244
|
-
newValidator.checks = [...this.checks, (v) => v > 0];
|
|
245
|
-
newValidator.errorMessage = message || getMessages().numberPositive;
|
|
246
|
-
return newValidator;
|
|
247
|
-
}
|
|
248
|
-
negative(message) {
|
|
249
|
-
const newValidator = new VldNumber();
|
|
250
|
-
newValidator.checks = [...this.checks, (v) => v < 0];
|
|
251
|
-
newValidator.errorMessage = message || getMessages().numberNegative;
|
|
252
|
-
return newValidator;
|
|
253
|
-
}
|
|
254
|
-
nonnegative(message) {
|
|
255
|
-
const newValidator = new VldNumber();
|
|
256
|
-
newValidator.checks = [...this.checks, (v) => v >= 0];
|
|
257
|
-
newValidator.errorMessage = message || getMessages().numberNonnegative;
|
|
258
|
-
return newValidator;
|
|
259
|
-
}
|
|
260
|
-
nonpositive(message) {
|
|
261
|
-
const newValidator = new VldNumber();
|
|
262
|
-
newValidator.checks = [...this.checks, (v) => v <= 0];
|
|
263
|
-
newValidator.errorMessage = message || getMessages().numberNonpositive;
|
|
264
|
-
return newValidator;
|
|
265
|
-
}
|
|
266
|
-
finite(message) {
|
|
267
|
-
const newValidator = new VldNumber();
|
|
268
|
-
newValidator.checks = [...this.checks, (v) => Number.isFinite(v)];
|
|
269
|
-
newValidator.errorMessage = message || getMessages().numberFinite;
|
|
270
|
-
return newValidator;
|
|
271
|
-
}
|
|
272
|
-
safe(message) {
|
|
273
|
-
const newValidator = new VldNumber();
|
|
274
|
-
newValidator.checks = [...this.checks, (v) => Number.isSafeInteger(v)];
|
|
275
|
-
newValidator.errorMessage = message || getMessages().numberSafe;
|
|
276
|
-
return newValidator;
|
|
277
|
-
}
|
|
278
|
-
multipleOf(value, message) {
|
|
279
|
-
const newValidator = new VldNumber();
|
|
280
|
-
newValidator.checks = [...this.checks, (v) => v % value === 0];
|
|
281
|
-
newValidator.errorMessage = message || getMessages().numberMultipleOf(value);
|
|
282
|
-
return newValidator;
|
|
283
|
-
}
|
|
284
|
-
step(value, message) {
|
|
285
|
-
return this.multipleOf(value, message);
|
|
286
|
-
}
|
|
287
|
-
}
|
|
288
|
-
// Boolean validator
|
|
289
|
-
export class VldBoolean extends VldBase {
|
|
290
|
-
constructor() {
|
|
291
|
-
super(...arguments);
|
|
292
|
-
this.errorMessage = getMessages().invalidBoolean;
|
|
293
|
-
}
|
|
294
|
-
parse(value) {
|
|
295
|
-
if (typeof value !== 'boolean') {
|
|
296
|
-
throw new Error(this.errorMessage || getMessages().invalidBoolean);
|
|
297
|
-
}
|
|
298
|
-
return value;
|
|
299
|
-
}
|
|
300
|
-
safeParse(value) {
|
|
301
|
-
if (typeof value === 'boolean') {
|
|
302
|
-
return { success: true, data: value };
|
|
303
|
-
}
|
|
304
|
-
return { success: false, error: new Error(this.errorMessage) };
|
|
305
|
-
}
|
|
306
|
-
}
|
|
307
|
-
// Array validator
|
|
308
|
-
export class VldArray extends VldBase {
|
|
309
|
-
constructor(itemValidator) {
|
|
310
|
-
super();
|
|
311
|
-
this.itemValidator = itemValidator;
|
|
312
|
-
}
|
|
313
|
-
parse(value) {
|
|
314
|
-
if (!Array.isArray(value)) {
|
|
315
|
-
throw new Error(getMessages().invalidArray);
|
|
316
|
-
}
|
|
317
|
-
return value.map((item, index) => {
|
|
318
|
-
try {
|
|
319
|
-
return this.itemValidator.parse(item);
|
|
320
|
-
}
|
|
321
|
-
catch (error) {
|
|
322
|
-
throw new Error(getMessages().arrayItem(index, error.message));
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
safeParse(value) {
|
|
327
|
-
try {
|
|
328
|
-
return { success: true, data: this.parse(value) };
|
|
329
|
-
}
|
|
330
|
-
catch (error) {
|
|
331
|
-
return { success: false, error: error };
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
min(length, message) {
|
|
335
|
-
const originalParse = this.parse.bind(this);
|
|
336
|
-
this.parse = (value) => {
|
|
337
|
-
const arr = originalParse(value);
|
|
338
|
-
if (arr.length < length) {
|
|
339
|
-
throw new Error(message || getMessages().arrayMin(length));
|
|
340
|
-
}
|
|
341
|
-
return arr;
|
|
342
|
-
};
|
|
343
|
-
return this;
|
|
344
|
-
}
|
|
345
|
-
max(length, message) {
|
|
346
|
-
const originalParse = this.parse.bind(this);
|
|
347
|
-
this.parse = (value) => {
|
|
348
|
-
const arr = originalParse(value);
|
|
349
|
-
if (arr.length > length) {
|
|
350
|
-
throw new Error(message || getMessages().arrayMax(length));
|
|
351
|
-
}
|
|
352
|
-
return arr;
|
|
353
|
-
};
|
|
354
|
-
return this;
|
|
355
|
-
}
|
|
356
|
-
length(length, message) {
|
|
357
|
-
const originalParse = this.parse.bind(this);
|
|
358
|
-
this.parse = (value) => {
|
|
359
|
-
const arr = originalParse(value);
|
|
360
|
-
if (arr.length !== length) {
|
|
361
|
-
throw new Error(message || getMessages().arrayLength(length));
|
|
362
|
-
}
|
|
363
|
-
return arr;
|
|
364
|
-
};
|
|
365
|
-
return this;
|
|
366
|
-
}
|
|
367
|
-
nonempty(message) {
|
|
368
|
-
return this.min(1, message || getMessages().arrayEmpty);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
// Object validator
|
|
372
|
-
export class VldObject extends VldBase {
|
|
373
|
-
constructor(shape) {
|
|
374
|
-
super();
|
|
375
|
-
this.shape = shape;
|
|
376
|
-
}
|
|
377
|
-
parse(value) {
|
|
378
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
379
|
-
throw new Error(getMessages().invalidObject);
|
|
380
|
-
}
|
|
381
|
-
const result = {};
|
|
382
|
-
const obj = value;
|
|
383
|
-
for (const [key, validator] of Object.entries(this.shape)) {
|
|
384
|
-
try {
|
|
385
|
-
result[key] = validator.parse(obj[key]);
|
|
386
|
-
}
|
|
387
|
-
catch (error) {
|
|
388
|
-
throw new Error(getMessages().objectField(key, error.message));
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
return result;
|
|
392
|
-
}
|
|
393
|
-
safeParse(value) {
|
|
394
|
-
try {
|
|
395
|
-
return { success: true, data: this.parse(value) };
|
|
396
|
-
}
|
|
397
|
-
catch (error) {
|
|
398
|
-
return { success: false, error: error };
|
|
399
|
-
}
|
|
400
|
-
}
|
|
401
|
-
partial() {
|
|
402
|
-
const partialShape = {};
|
|
403
|
-
for (const [key, validator] of Object.entries(this.shape)) {
|
|
404
|
-
partialShape[key] = new VldOptional(validator);
|
|
405
|
-
}
|
|
406
|
-
return new VldObject(partialShape);
|
|
407
|
-
}
|
|
408
|
-
strict() {
|
|
409
|
-
const originalParse = this.parse.bind(this);
|
|
410
|
-
this.parse = (value) => {
|
|
411
|
-
const result = originalParse(value);
|
|
412
|
-
const obj = value;
|
|
413
|
-
const extraKeys = Object.keys(obj).filter(key => !(key in this.shape));
|
|
414
|
-
if (extraKeys.length > 0) {
|
|
415
|
-
throw new Error(getMessages().unexpectedKeys(extraKeys));
|
|
416
|
-
}
|
|
417
|
-
return result;
|
|
418
|
-
};
|
|
419
|
-
return this;
|
|
420
|
-
}
|
|
421
|
-
pick(...keys) {
|
|
422
|
-
const pickedShape = {};
|
|
423
|
-
for (const key of keys) {
|
|
424
|
-
if (key in this.shape) {
|
|
425
|
-
pickedShape[key] = this.shape[key];
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
return new VldObject(pickedShape);
|
|
429
|
-
}
|
|
430
|
-
omit(...keys) {
|
|
431
|
-
const omittedShape = {};
|
|
432
|
-
for (const [key, validator] of Object.entries(this.shape)) {
|
|
433
|
-
if (!keys.includes(key)) {
|
|
434
|
-
omittedShape[key] = validator;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
return new VldObject(omittedShape);
|
|
438
|
-
}
|
|
439
|
-
extend(extension) {
|
|
440
|
-
const extendedShape = { ...this.shape };
|
|
441
|
-
for (const [key, validator] of Object.entries(extension)) {
|
|
442
|
-
extendedShape[key] = validator;
|
|
443
|
-
}
|
|
444
|
-
return new VldObject(extendedShape);
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
// Optional validator
|
|
448
|
-
export class VldOptional extends VldBase {
|
|
449
|
-
constructor(validator) {
|
|
450
|
-
super();
|
|
451
|
-
this.validator = validator;
|
|
452
|
-
}
|
|
453
|
-
parse(value) {
|
|
454
|
-
if (value === undefined) {
|
|
455
|
-
return undefined;
|
|
456
|
-
}
|
|
457
|
-
return this.validator.parse(value);
|
|
458
|
-
}
|
|
459
|
-
safeParse(value) {
|
|
460
|
-
if (value === undefined) {
|
|
461
|
-
return { success: true, data: undefined };
|
|
462
|
-
}
|
|
463
|
-
return this.validator.safeParse(value);
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
// Nullable validator
|
|
467
|
-
export class VldNullable extends VldBase {
|
|
468
|
-
constructor(validator) {
|
|
469
|
-
super();
|
|
470
|
-
this.validator = validator;
|
|
471
|
-
}
|
|
472
|
-
parse(value) {
|
|
473
|
-
if (value === null) {
|
|
474
|
-
return null;
|
|
475
|
-
}
|
|
476
|
-
return this.validator.parse(value);
|
|
477
|
-
}
|
|
478
|
-
safeParse(value) {
|
|
479
|
-
if (value === null) {
|
|
480
|
-
return { success: true, data: null };
|
|
481
|
-
}
|
|
482
|
-
return this.validator.safeParse(value);
|
|
483
|
-
}
|
|
484
|
-
}
|
|
485
|
-
// Union validator
|
|
486
|
-
export class VldUnion extends VldBase {
|
|
487
|
-
constructor(validators) {
|
|
488
|
-
super();
|
|
489
|
-
this.validators = validators;
|
|
490
|
-
}
|
|
491
|
-
parse(value) {
|
|
492
|
-
const errors = [];
|
|
493
|
-
for (const validator of this.validators) {
|
|
494
|
-
try {
|
|
495
|
-
return validator.parse(value);
|
|
496
|
-
}
|
|
497
|
-
catch (error) {
|
|
498
|
-
errors.push(error);
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
throw new Error(getMessages().unionNoMatch(errors.map(e => e.message)));
|
|
502
|
-
}
|
|
503
|
-
safeParse(value) {
|
|
504
|
-
try {
|
|
505
|
-
return { success: true, data: this.parse(value) };
|
|
506
|
-
}
|
|
507
|
-
catch (error) {
|
|
508
|
-
return { success: false, error: error };
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
// Intersection validator
|
|
513
|
-
export class VldIntersection extends VldBase {
|
|
514
|
-
constructor(validatorA, validatorB) {
|
|
515
|
-
super();
|
|
516
|
-
this.validatorA = validatorA;
|
|
517
|
-
this.validatorB = validatorB;
|
|
518
|
-
}
|
|
519
|
-
parse(value) {
|
|
520
|
-
try {
|
|
521
|
-
// Both validators must pass
|
|
522
|
-
const resultA = this.validatorA.parse(value);
|
|
523
|
-
const resultB = this.validatorB.parse(value);
|
|
524
|
-
// For object types, deep merge the results
|
|
525
|
-
if (typeof resultA === 'object' && resultA !== null &&
|
|
526
|
-
typeof resultB === 'object' && resultB !== null &&
|
|
527
|
-
!Array.isArray(resultA) && !Array.isArray(resultB)) {
|
|
528
|
-
return deepMerge(resultA, resultB);
|
|
529
|
-
}
|
|
530
|
-
// For primitive types, both must be the same value
|
|
531
|
-
if (resultA === resultB) {
|
|
532
|
-
return resultA;
|
|
533
|
-
}
|
|
534
|
-
// If they're different primitive values, this is an error
|
|
535
|
-
throw new Error(getMessages().intersectionError('Values must be identical for intersection of primitive types'));
|
|
536
|
-
}
|
|
537
|
-
catch (error) {
|
|
538
|
-
throw new Error(getMessages().intersectionError(error.message));
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
safeParse(value) {
|
|
542
|
-
try {
|
|
543
|
-
return { success: true, data: this.parse(value) };
|
|
544
|
-
}
|
|
545
|
-
catch (error) {
|
|
546
|
-
return { success: false, error: error };
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
}
|
|
550
|
-
// Literal validator
|
|
551
|
-
export class VldLiteral extends VldBase {
|
|
552
|
-
constructor(literal) {
|
|
553
|
-
super();
|
|
554
|
-
this.literal = literal;
|
|
555
|
-
}
|
|
556
|
-
parse(value) {
|
|
557
|
-
if (value !== this.literal) {
|
|
558
|
-
throw new Error(getMessages().literalExpected(JSON.stringify(this.literal), JSON.stringify(value)));
|
|
559
|
-
}
|
|
560
|
-
return this.literal;
|
|
561
|
-
}
|
|
562
|
-
safeParse(value) {
|
|
563
|
-
if (value === this.literal) {
|
|
564
|
-
return { success: true, data: this.literal };
|
|
565
|
-
}
|
|
566
|
-
return { success: false, error: new Error(getMessages().literalExpected(JSON.stringify(this.literal), 'received')) };
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
// Enum validator
|
|
570
|
-
export class VldEnum extends VldBase {
|
|
571
|
-
constructor(values) {
|
|
572
|
-
super();
|
|
573
|
-
this.values = values;
|
|
574
|
-
}
|
|
575
|
-
parse(value) {
|
|
576
|
-
if (!this.values.includes(value)) {
|
|
577
|
-
throw new Error(getMessages().enumExpected([...this.values], JSON.stringify(value)));
|
|
578
|
-
}
|
|
579
|
-
return value;
|
|
580
|
-
}
|
|
581
|
-
safeParse(value) {
|
|
582
|
-
if (this.values.includes(value)) {
|
|
583
|
-
return { success: true, data: value };
|
|
584
|
-
}
|
|
585
|
-
return { success: false, error: new Error(getMessages().enumExpected([...this.values], 'received')) };
|
|
586
|
-
}
|
|
587
|
-
}
|
|
588
|
-
// Date validator
|
|
589
|
-
export class VldDate extends VldBase {
|
|
590
|
-
constructor() {
|
|
591
|
-
super(...arguments);
|
|
592
|
-
this.checks = [];
|
|
593
|
-
this.errorMessage = getMessages().invalidDate;
|
|
594
|
-
}
|
|
595
|
-
parse(value) {
|
|
596
|
-
let date;
|
|
597
|
-
if (value instanceof Date) {
|
|
598
|
-
date = value;
|
|
599
|
-
}
|
|
600
|
-
else if (typeof value === 'string' || typeof value === 'number') {
|
|
601
|
-
date = new Date(value);
|
|
602
|
-
}
|
|
603
|
-
else {
|
|
604
|
-
throw new Error(this.errorMessage || getMessages().invalidDate);
|
|
605
|
-
}
|
|
606
|
-
if (isNaN(date.getTime())) {
|
|
607
|
-
throw new Error(this.errorMessage || getMessages().invalidDate);
|
|
608
|
-
}
|
|
609
|
-
for (const check of this.checks) {
|
|
610
|
-
if (!check(date)) {
|
|
611
|
-
throw new Error(this.errorMessage || getMessages().invalidDate);
|
|
612
|
-
}
|
|
613
|
-
}
|
|
614
|
-
return date;
|
|
615
|
-
}
|
|
616
|
-
safeParse(value) {
|
|
617
|
-
try {
|
|
618
|
-
return { success: true, data: this.parse(value) };
|
|
619
|
-
}
|
|
620
|
-
catch (error) {
|
|
621
|
-
return { success: false, error: error };
|
|
622
|
-
}
|
|
623
|
-
}
|
|
624
|
-
min(date, message) {
|
|
625
|
-
const newValidator = new VldDate();
|
|
626
|
-
newValidator.checks = [...this.checks, (v) => v >= date];
|
|
627
|
-
newValidator.errorMessage = message || getMessages().dateMin(date);
|
|
628
|
-
return newValidator;
|
|
629
|
-
}
|
|
630
|
-
max(date, message) {
|
|
631
|
-
const newValidator = new VldDate();
|
|
632
|
-
newValidator.checks = [...this.checks, (v) => v <= date];
|
|
633
|
-
newValidator.errorMessage = message || getMessages().dateMax(date);
|
|
634
|
-
return newValidator;
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
// Any validator
|
|
638
|
-
export class VldAny extends VldBase {
|
|
639
|
-
parse(value) {
|
|
640
|
-
return value;
|
|
641
|
-
}
|
|
642
|
-
safeParse(value) {
|
|
643
|
-
return { success: true, data: value };
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
// Unknown validator
|
|
647
|
-
export class VldUnknown extends VldBase {
|
|
648
|
-
parse(value) {
|
|
649
|
-
return value;
|
|
650
|
-
}
|
|
651
|
-
safeParse(value) {
|
|
652
|
-
return { success: true, data: value };
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
// Void validator
|
|
656
|
-
export class VldVoid extends VldBase {
|
|
657
|
-
parse(value) {
|
|
658
|
-
if (value !== undefined) {
|
|
659
|
-
throw new Error(getMessages().expectedUndefined);
|
|
660
|
-
}
|
|
661
|
-
return undefined;
|
|
662
|
-
}
|
|
663
|
-
safeParse(value) {
|
|
664
|
-
if (value === undefined) {
|
|
665
|
-
return { success: true, data: undefined };
|
|
666
|
-
}
|
|
667
|
-
return { success: false, error: new Error(getMessages().expectedUndefined) };
|
|
668
|
-
}
|
|
669
|
-
}
|
|
670
|
-
// Never validator
|
|
671
|
-
export class VldNever extends VldBase {
|
|
672
|
-
parse(_value) {
|
|
673
|
-
throw new Error(getMessages().neverType);
|
|
674
|
-
}
|
|
675
|
-
safeParse(_value) {
|
|
676
|
-
return { success: false, error: new Error(getMessages().neverType) };
|
|
677
|
-
}
|
|
678
|
-
}
|
|
679
|
-
// BigInt validator
|
|
680
|
-
export class VldBigInt extends VldBase {
|
|
681
|
-
constructor() {
|
|
682
|
-
super(...arguments);
|
|
683
|
-
this.checks = [];
|
|
684
|
-
this.errorMessage = getMessages().invalidBigint;
|
|
685
|
-
}
|
|
686
|
-
parse(value) {
|
|
687
|
-
if (typeof value !== 'bigint') {
|
|
688
|
-
throw new Error(this.errorMessage || getMessages().invalidBigint);
|
|
689
|
-
}
|
|
690
|
-
for (const check of this.checks) {
|
|
691
|
-
if (!check(value)) {
|
|
692
|
-
throw new Error(this.errorMessage || getMessages().invalidBigint);
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
return value;
|
|
696
|
-
}
|
|
697
|
-
safeParse(value) {
|
|
698
|
-
try {
|
|
699
|
-
return { success: true, data: this.parse(value) };
|
|
700
|
-
}
|
|
701
|
-
catch (error) {
|
|
702
|
-
return { success: false, error: error };
|
|
703
|
-
}
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
// Symbol validator
|
|
707
|
-
export class VldSymbol extends VldBase {
|
|
708
|
-
constructor() {
|
|
709
|
-
super(...arguments);
|
|
710
|
-
this.errorMessage = getMessages().invalidSymbol;
|
|
711
|
-
}
|
|
712
|
-
parse(value) {
|
|
713
|
-
if (typeof value !== 'symbol') {
|
|
714
|
-
throw new Error(this.errorMessage || getMessages().invalidSymbol);
|
|
715
|
-
}
|
|
716
|
-
return value;
|
|
717
|
-
}
|
|
718
|
-
safeParse(value) {
|
|
719
|
-
if (typeof value === 'symbol') {
|
|
720
|
-
return { success: true, data: value };
|
|
721
|
-
}
|
|
722
|
-
return { success: false, error: new Error(this.errorMessage) };
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
// Tuple validator
|
|
726
|
-
export class VldTuple extends VldBase {
|
|
727
|
-
constructor(validators) {
|
|
728
|
-
super();
|
|
729
|
-
this.validators = validators;
|
|
730
|
-
}
|
|
731
|
-
parse(value) {
|
|
732
|
-
if (!Array.isArray(value)) {
|
|
733
|
-
throw new Error(getMessages().invalidTuple);
|
|
734
|
-
}
|
|
735
|
-
if (value.length !== this.validators.length) {
|
|
736
|
-
throw new Error(getMessages().tupleLength(this.validators.length, value.length));
|
|
737
|
-
}
|
|
738
|
-
const result = [];
|
|
739
|
-
for (let i = 0; i < this.validators.length; i++) {
|
|
740
|
-
try {
|
|
741
|
-
result[i] = this.validators[i].parse(value[i]);
|
|
742
|
-
}
|
|
743
|
-
catch (error) {
|
|
744
|
-
throw new Error(getMessages().arrayItem(i, error.message));
|
|
745
|
-
}
|
|
746
|
-
}
|
|
747
|
-
return result;
|
|
748
|
-
}
|
|
749
|
-
safeParse(value) {
|
|
750
|
-
try {
|
|
751
|
-
return { success: true, data: this.parse(value) };
|
|
752
|
-
}
|
|
753
|
-
catch (error) {
|
|
754
|
-
return { success: false, error: error };
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
// Record validator
|
|
759
|
-
export class VldRecord extends VldBase {
|
|
760
|
-
constructor(valueValidator) {
|
|
761
|
-
super();
|
|
762
|
-
this.valueValidator = valueValidator;
|
|
763
|
-
}
|
|
764
|
-
parse(value) {
|
|
765
|
-
if (typeof value !== 'object' || value === null || Array.isArray(value)) {
|
|
766
|
-
throw new Error(getMessages().invalidRecord);
|
|
767
|
-
}
|
|
768
|
-
const result = {};
|
|
769
|
-
const obj = value;
|
|
770
|
-
for (const [key, val] of Object.entries(obj)) {
|
|
771
|
-
try {
|
|
772
|
-
result[key] = this.valueValidator.parse(val);
|
|
773
|
-
}
|
|
774
|
-
catch (error) {
|
|
775
|
-
throw new Error(getMessages().objectField(key, error.message));
|
|
776
|
-
}
|
|
777
|
-
}
|
|
778
|
-
return result;
|
|
779
|
-
}
|
|
780
|
-
safeParse(value) {
|
|
781
|
-
try {
|
|
782
|
-
return { success: true, data: this.parse(value) };
|
|
783
|
-
}
|
|
784
|
-
catch (error) {
|
|
785
|
-
return { success: false, error: error };
|
|
786
|
-
}
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
// Set validator
|
|
790
|
-
export class VldSet extends VldBase {
|
|
791
|
-
constructor(itemValidator) {
|
|
792
|
-
super();
|
|
793
|
-
this.itemValidator = itemValidator;
|
|
794
|
-
}
|
|
795
|
-
parse(value) {
|
|
796
|
-
if (!(value instanceof Set)) {
|
|
797
|
-
throw new Error(getMessages().invalidSet);
|
|
798
|
-
}
|
|
799
|
-
const result = new Set();
|
|
800
|
-
for (const item of value) {
|
|
801
|
-
try {
|
|
802
|
-
result.add(this.itemValidator.parse(item));
|
|
803
|
-
}
|
|
804
|
-
catch (error) {
|
|
805
|
-
throw new Error(error.message);
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
return result;
|
|
809
|
-
}
|
|
810
|
-
safeParse(value) {
|
|
811
|
-
try {
|
|
812
|
-
return { success: true, data: this.parse(value) };
|
|
813
|
-
}
|
|
814
|
-
catch (error) {
|
|
815
|
-
return { success: false, error: error };
|
|
816
|
-
}
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
// Map validator
|
|
820
|
-
export class VldMap extends VldBase {
|
|
821
|
-
constructor(keyValidator, valueValidator) {
|
|
822
|
-
super();
|
|
823
|
-
this.keyValidator = keyValidator;
|
|
824
|
-
this.valueValidator = valueValidator;
|
|
825
|
-
}
|
|
826
|
-
parse(value) {
|
|
827
|
-
if (!(value instanceof Map)) {
|
|
828
|
-
throw new Error(getMessages().invalidMap);
|
|
829
|
-
}
|
|
830
|
-
const result = new Map();
|
|
831
|
-
for (const [key, val] of value) {
|
|
832
|
-
try {
|
|
833
|
-
const validKey = this.keyValidator.parse(key);
|
|
834
|
-
const validValue = this.valueValidator.parse(val);
|
|
835
|
-
result.set(validKey, validValue);
|
|
836
|
-
}
|
|
837
|
-
catch (error) {
|
|
838
|
-
throw new Error(error.message);
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
return result;
|
|
842
|
-
}
|
|
843
|
-
safeParse(value) {
|
|
844
|
-
try {
|
|
845
|
-
return { success: true, data: this.parse(value) };
|
|
846
|
-
}
|
|
847
|
-
catch (error) {
|
|
848
|
-
return { success: false, error: error };
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
// Coercion classes
|
|
853
|
-
export class VldCoerceString extends VldString {
|
|
854
|
-
parse(value) {
|
|
855
|
-
try {
|
|
856
|
-
// Attempt coercion to string
|
|
857
|
-
if (value === null || value === undefined) {
|
|
858
|
-
throw new Error(getMessages().coercionFailed('string', value));
|
|
859
|
-
}
|
|
860
|
-
const coerced = String(value);
|
|
861
|
-
// Call parent parse with coerced value
|
|
862
|
-
return super.parse(coerced);
|
|
863
|
-
}
|
|
864
|
-
catch (error) {
|
|
865
|
-
const errorMessage = error.message;
|
|
866
|
-
// If it's a coercion error, re-throw as is
|
|
867
|
-
if (errorMessage.includes('Cannot coerce')) {
|
|
868
|
-
throw error;
|
|
869
|
-
}
|
|
870
|
-
// If it's a validation error from parent, re-throw as is
|
|
871
|
-
if (errorMessage.includes('String must') || errorMessage.includes('Invalid')) {
|
|
872
|
-
throw error;
|
|
873
|
-
}
|
|
874
|
-
// Otherwise, it's a coercion failure
|
|
875
|
-
throw new Error(getMessages().coercionFailed('string', value));
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
safeParse(value) {
|
|
879
|
-
try {
|
|
880
|
-
return { success: true, data: this.parse(value) };
|
|
881
|
-
}
|
|
882
|
-
catch (error) {
|
|
883
|
-
return { success: false, error: error };
|
|
884
|
-
}
|
|
885
|
-
}
|
|
886
|
-
}
|
|
887
|
-
export class VldCoerceNumber extends VldNumber {
|
|
888
|
-
parse(value) {
|
|
889
|
-
try {
|
|
890
|
-
// Attempt coercion to number
|
|
891
|
-
if (typeof value === 'string') {
|
|
892
|
-
const trimmed = value.trim();
|
|
893
|
-
if (trimmed === '') {
|
|
894
|
-
throw new Error(getMessages().coercionFailed('number', value));
|
|
895
|
-
}
|
|
896
|
-
const coerced = Number(trimmed);
|
|
897
|
-
if (isNaN(coerced)) {
|
|
898
|
-
throw new Error(getMessages().coercionFailed('number', value));
|
|
899
|
-
}
|
|
900
|
-
return super.parse(coerced);
|
|
901
|
-
}
|
|
902
|
-
else if (typeof value === 'boolean') {
|
|
903
|
-
return super.parse(value ? 1 : 0);
|
|
904
|
-
}
|
|
905
|
-
else if (value === null || value === undefined) {
|
|
906
|
-
throw new Error(getMessages().coercionFailed('number', value));
|
|
907
|
-
}
|
|
908
|
-
return super.parse(Number(value));
|
|
909
|
-
}
|
|
910
|
-
catch (error) {
|
|
911
|
-
if (error.message.includes('coercionFailed')) {
|
|
912
|
-
throw error;
|
|
913
|
-
}
|
|
914
|
-
throw new Error(getMessages().coercionFailed('number', value));
|
|
915
|
-
}
|
|
916
|
-
}
|
|
917
|
-
safeParse(value) {
|
|
918
|
-
try {
|
|
919
|
-
return { success: true, data: this.parse(value) };
|
|
920
|
-
}
|
|
921
|
-
catch (error) {
|
|
922
|
-
return { success: false, error: error };
|
|
923
|
-
}
|
|
924
|
-
}
|
|
925
|
-
}
|
|
926
|
-
export class VldCoerceBoolean extends VldBoolean {
|
|
927
|
-
parse(value) {
|
|
928
|
-
try {
|
|
929
|
-
// Attempt coercion to boolean
|
|
930
|
-
if (typeof value === 'string') {
|
|
931
|
-
const lower = value.toLowerCase().trim();
|
|
932
|
-
if (lower === 'true' || lower === '1' || lower === 'yes')
|
|
933
|
-
return true;
|
|
934
|
-
if (lower === 'false' || lower === '0' || lower === 'no')
|
|
935
|
-
return false;
|
|
936
|
-
throw new Error(getMessages().coercionFailed('boolean', value));
|
|
937
|
-
}
|
|
938
|
-
else if (typeof value === 'number') {
|
|
939
|
-
if (value === 1)
|
|
940
|
-
return true;
|
|
941
|
-
if (value === 0)
|
|
942
|
-
return false;
|
|
943
|
-
throw new Error(getMessages().coercionFailed('boolean', value));
|
|
944
|
-
}
|
|
945
|
-
else if (value === null || value === undefined) {
|
|
946
|
-
throw new Error(getMessages().coercionFailed('boolean', value));
|
|
947
|
-
}
|
|
948
|
-
return super.parse(Boolean(value));
|
|
949
|
-
}
|
|
950
|
-
catch (error) {
|
|
951
|
-
if (error.message.includes('coercionFailed')) {
|
|
952
|
-
throw error;
|
|
953
|
-
}
|
|
954
|
-
throw new Error(getMessages().coercionFailed('boolean', value));
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
safeParse(value) {
|
|
958
|
-
try {
|
|
959
|
-
return { success: true, data: this.parse(value) };
|
|
960
|
-
}
|
|
961
|
-
catch (error) {
|
|
962
|
-
return { success: false, error: error };
|
|
963
|
-
}
|
|
964
|
-
}
|
|
965
|
-
}
|
|
966
|
-
export class VldCoerceBigInt extends VldBigInt {
|
|
967
|
-
parse(value) {
|
|
968
|
-
try {
|
|
969
|
-
// Attempt coercion to bigint
|
|
970
|
-
if (typeof value === 'string') {
|
|
971
|
-
const trimmed = value.trim();
|
|
972
|
-
if (trimmed === '') {
|
|
973
|
-
throw new Error(getMessages().coercionFailed('bigint', value));
|
|
974
|
-
}
|
|
975
|
-
return super.parse(BigInt(trimmed));
|
|
976
|
-
}
|
|
977
|
-
else if (typeof value === 'number') {
|
|
978
|
-
if (!Number.isInteger(value)) {
|
|
979
|
-
throw new Error(getMessages().coercionFailed('bigint', value));
|
|
980
|
-
}
|
|
981
|
-
return super.parse(BigInt(value));
|
|
982
|
-
}
|
|
983
|
-
else if (value === null || value === undefined) {
|
|
984
|
-
throw new Error(getMessages().coercionFailed('bigint', value));
|
|
985
|
-
}
|
|
986
|
-
return super.parse(BigInt(value));
|
|
987
|
-
}
|
|
988
|
-
catch (error) {
|
|
989
|
-
if (error.message.includes('coercionFailed')) {
|
|
990
|
-
throw error;
|
|
991
|
-
}
|
|
992
|
-
throw new Error(getMessages().coercionFailed('bigint', value));
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
safeParse(value) {
|
|
996
|
-
try {
|
|
997
|
-
return { success: true, data: this.parse(value) };
|
|
998
|
-
}
|
|
999
|
-
catch (error) {
|
|
1000
|
-
return { success: false, error: error };
|
|
1001
|
-
}
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
export class VldCoerceDate extends VldDate {
|
|
1005
|
-
parse(value) {
|
|
1006
|
-
try {
|
|
1007
|
-
// Attempt coercion to date
|
|
1008
|
-
if (typeof value === 'string' || typeof value === 'number') {
|
|
1009
|
-
return super.parse(new Date(value));
|
|
1010
|
-
}
|
|
1011
|
-
else if (value === null || value === undefined) {
|
|
1012
|
-
throw new Error(getMessages().coercionFailed('date', value));
|
|
1013
|
-
}
|
|
1014
|
-
return super.parse(value);
|
|
1015
|
-
}
|
|
1016
|
-
catch (error) {
|
|
1017
|
-
if (error.message.includes('coercionFailed')) {
|
|
1018
|
-
throw error;
|
|
1019
|
-
}
|
|
1020
|
-
throw new Error(getMessages().coercionFailed('date', value));
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
safeParse(value) {
|
|
1024
|
-
try {
|
|
1025
|
-
return { success: true, data: this.parse(value) };
|
|
1026
|
-
}
|
|
1027
|
-
catch (error) {
|
|
1028
|
-
return { success: false, error: error };
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
}
|
|
1032
|
-
// Refine validator - adds custom validation
|
|
1033
|
-
export class VldRefine extends VldBase {
|
|
1034
|
-
constructor(baseValidator, predicate, customMessage) {
|
|
1035
|
-
super();
|
|
1036
|
-
this.baseValidator = baseValidator;
|
|
1037
|
-
this.predicate = predicate;
|
|
1038
|
-
this.customMessage = customMessage;
|
|
1039
|
-
}
|
|
1040
|
-
parse(value) {
|
|
1041
|
-
const baseResult = this.baseValidator.parse(value);
|
|
1042
|
-
try {
|
|
1043
|
-
if (!this.predicate(baseResult)) {
|
|
1044
|
-
throw new Error(this.customMessage || 'Refinement condition not met');
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
catch (error) {
|
|
1048
|
-
throw new Error(getMessages().customValidationError(error.message));
|
|
1049
|
-
}
|
|
1050
|
-
return baseResult;
|
|
1051
|
-
}
|
|
1052
|
-
safeParse(value) {
|
|
1053
|
-
try {
|
|
1054
|
-
return { success: true, data: this.parse(value) };
|
|
1055
|
-
}
|
|
1056
|
-
catch (error) {
|
|
1057
|
-
return { success: false, error: error };
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
// Transform validator - transforms data after validation
|
|
1062
|
-
export class VldTransform extends VldBase {
|
|
1063
|
-
constructor(baseValidator, transformer) {
|
|
1064
|
-
super();
|
|
1065
|
-
this.baseValidator = baseValidator;
|
|
1066
|
-
this.transformer = transformer;
|
|
1067
|
-
}
|
|
1068
|
-
parse(value) {
|
|
1069
|
-
const baseResult = this.baseValidator.parse(value);
|
|
1070
|
-
try {
|
|
1071
|
-
return this.transformer(baseResult);
|
|
1072
|
-
}
|
|
1073
|
-
catch (error) {
|
|
1074
|
-
throw new Error(getMessages().transformError(error.message));
|
|
1075
|
-
}
|
|
1076
|
-
}
|
|
1077
|
-
safeParse(value) {
|
|
1078
|
-
try {
|
|
1079
|
-
return { success: true, data: this.parse(value) };
|
|
1080
|
-
}
|
|
1081
|
-
catch (error) {
|
|
1082
|
-
return { success: false, error: error };
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
}
|
|
1086
|
-
// Default validator - provides default value for undefined
|
|
1087
|
-
export class VldDefault extends VldBase {
|
|
1088
|
-
constructor(baseValidator, defaultValue) {
|
|
1089
|
-
super();
|
|
1090
|
-
this.baseValidator = baseValidator;
|
|
1091
|
-
this.defaultValue = defaultValue;
|
|
1092
|
-
}
|
|
1093
|
-
parse(value) {
|
|
1094
|
-
if (value === undefined) {
|
|
1095
|
-
return this.defaultValue;
|
|
1096
|
-
}
|
|
1097
|
-
return this.baseValidator.parse(value);
|
|
1098
|
-
}
|
|
1099
|
-
safeParse(value) {
|
|
1100
|
-
if (value === undefined) {
|
|
1101
|
-
return { success: true, data: this.defaultValue };
|
|
1102
|
-
}
|
|
1103
|
-
return this.baseValidator.safeParse(value);
|
|
1104
|
-
}
|
|
1105
|
-
}
|
|
1106
|
-
// Catch validator - provides fallback value on validation error
|
|
1107
|
-
export class VldCatch extends VldBase {
|
|
1108
|
-
constructor(baseValidator, fallbackValue) {
|
|
1109
|
-
super();
|
|
1110
|
-
this.baseValidator = baseValidator;
|
|
1111
|
-
this.fallbackValue = fallbackValue;
|
|
1112
|
-
}
|
|
1113
|
-
parse(value) {
|
|
1114
|
-
try {
|
|
1115
|
-
return this.baseValidator.parse(value);
|
|
1116
|
-
}
|
|
1117
|
-
catch {
|
|
1118
|
-
return this.fallbackValue;
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
safeParse(value) {
|
|
1122
|
-
const result = this.baseValidator.safeParse(value);
|
|
1123
|
-
if (result.success) {
|
|
1124
|
-
return result;
|
|
1125
|
-
}
|
|
1126
|
-
else {
|
|
1127
|
-
return { success: true, data: this.fallbackValue };
|
|
1128
|
-
}
|
|
1129
|
-
}
|
|
1130
|
-
}
|
|
1131
|
-
// Main API
|
|
1
|
+
/**
|
|
2
|
+
* VLD - Fast, Type-Safe Validation Library
|
|
3
|
+
* Zero dependencies, blazing fast performance
|
|
4
|
+
*
|
|
5
|
+
* This is the new modular implementation with:
|
|
6
|
+
* - Immutable validators (no memory leaks)
|
|
7
|
+
* - Secure deepMerge (no prototype pollution)
|
|
8
|
+
* - TypeScript strict mode support
|
|
9
|
+
* - Better performance through pooling and memoization
|
|
10
|
+
*/
|
|
11
|
+
// Import validators
|
|
12
|
+
import { VldString } from './validators/string.js';
|
|
13
|
+
import { VldNumber } from './validators/number.js';
|
|
14
|
+
import { VldBoolean } from './validators/boolean.js';
|
|
15
|
+
import { VldDate } from './validators/date.js';
|
|
16
|
+
import { VldArray } from './validators/array.js';
|
|
17
|
+
import { VldObject } from './validators/object.js';
|
|
18
|
+
import { VldUnion } from './validators/union.js';
|
|
19
|
+
import { VldLiteral } from './validators/literal.js';
|
|
20
|
+
import { VldBigInt } from './validators/bigint.js';
|
|
21
|
+
import { VldSymbol } from './validators/symbol.js';
|
|
22
|
+
import { VldTuple } from './validators/tuple.js';
|
|
23
|
+
import { VldRecord } from './validators/record.js';
|
|
24
|
+
import { VldSet } from './validators/set.js';
|
|
25
|
+
import { VldMap } from './validators/map.js';
|
|
26
|
+
import { VldEnum } from './validators/enum.js';
|
|
27
|
+
import { VldIntersection } from './validators/intersection.js';
|
|
28
|
+
import { VldAny } from './validators/any.js';
|
|
29
|
+
import { VldUnknown } from './validators/unknown.js';
|
|
30
|
+
import { VldVoid } from './validators/void.js';
|
|
31
|
+
import { VldNever } from './validators/never.js';
|
|
32
|
+
import { VldOptional } from './validators/base.js';
|
|
33
|
+
import { VldNullable } from './validators/base.js';
|
|
34
|
+
import { VldNullish } from './validators/base.js';
|
|
35
|
+
// Import coercion validators
|
|
36
|
+
import { VldCoerceString } from './coercion/string.js';
|
|
37
|
+
import { VldCoerceNumber } from './coercion/number.js';
|
|
38
|
+
import { VldCoerceBoolean } from './coercion/boolean.js';
|
|
39
|
+
import { VldCoerceDate } from './coercion/date.js';
|
|
40
|
+
import { VldCoerceBigInt } from './coercion/bigint.js';
|
|
41
|
+
// Re-export base classes for extension
|
|
42
|
+
export { VldBase } from './validators/base.js';
|
|
43
|
+
export { VldIntersection } from './validators/intersection.js';
|
|
44
|
+
// Re-export locale functionality
|
|
45
|
+
export { setLocale, getLocale, getMessages } from './locales.js';
|
|
46
|
+
// Re-export error formatting utilities
|
|
47
|
+
export { VldError, treeifyError, prettifyError, flattenError } from './errors.js';
|
|
48
|
+
/**
|
|
49
|
+
* Main API object with factory methods for all validators
|
|
50
|
+
*/
|
|
1132
51
|
export const v = {
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
52
|
+
// Primitive validators
|
|
53
|
+
string: () => VldString.create(),
|
|
54
|
+
number: () => VldNumber.create(),
|
|
55
|
+
boolean: () => VldBoolean.create(),
|
|
56
|
+
date: () => VldDate.create(),
|
|
57
|
+
bigint: () => VldBigInt.create(),
|
|
58
|
+
symbol: () => VldSymbol.create(),
|
|
59
|
+
// Complex validators
|
|
60
|
+
array: (item) => VldArray.create(item),
|
|
61
|
+
object: (shape) => VldObject.create(shape),
|
|
62
|
+
tuple: (...items) => VldTuple.create(...items),
|
|
63
|
+
record: (value) => VldRecord.create(value),
|
|
64
|
+
set: (item) => VldSet.create(item),
|
|
65
|
+
map: (key, value) => VldMap.create(key, value),
|
|
66
|
+
// Union and intersection
|
|
67
|
+
union: (...validators) => VldUnion.create(...validators),
|
|
68
|
+
intersection: (first, second) => VldIntersection.create(first, second),
|
|
69
|
+
// Literal and enum
|
|
70
|
+
literal: (value) => VldLiteral.create(value),
|
|
71
|
+
enum: (...values) => VldEnum.create(values),
|
|
72
|
+
// Special validators
|
|
73
|
+
any: () => VldAny.create(),
|
|
74
|
+
unknown: () => VldUnknown.create(),
|
|
75
|
+
void: () => VldVoid.create(),
|
|
76
|
+
never: () => VldNever.create(),
|
|
77
|
+
// Utility validators
|
|
78
|
+
optional: (validator) => VldOptional.create(validator),
|
|
79
|
+
nullable: (validator) => VldNullable.create(validator),
|
|
80
|
+
nullish: (validator) => VldNullish.create(validator),
|
|
1155
81
|
// Coercion API
|
|
1156
82
|
coerce: {
|
|
1157
|
-
string: () =>
|
|
1158
|
-
number: () =>
|
|
1159
|
-
boolean: () =>
|
|
1160
|
-
|
|
1161
|
-
|
|
83
|
+
string: () => VldCoerceString.create(),
|
|
84
|
+
number: () => VldCoerceNumber.create(),
|
|
85
|
+
boolean: () => VldCoerceBoolean.create(),
|
|
86
|
+
date: () => VldCoerceDate.create(),
|
|
87
|
+
bigint: () => VldCoerceBigInt.create(),
|
|
1162
88
|
}
|
|
1163
89
|
};
|
|
1164
|
-
//
|
|
1165
|
-
export
|
|
1166
|
-
// Export locale functionality
|
|
1167
|
-
export { setLocale, getLocale, getMessages } from './locales/index.js';
|
|
1168
|
-
// Export error formatting utilities
|
|
1169
|
-
export { VldError, treeifyError, prettifyError, flattenError } from './errors.js';
|
|
90
|
+
// For backward compatibility during migration
|
|
91
|
+
export default v;
|
|
1170
92
|
//# sourceMappingURL=index.js.map
|