@oxog/vld 1.5.0 → 2.0.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 +116 -0
- package/README.md +558 -517
- package/dist/chunks/bigint-ZKkWLdmi.js +1628 -0
- package/dist/chunks/bigint-ZKkWLdmi.js.map +1 -0
- package/dist/{coercion/string.js → chunks/date-7Iz2BGsL.js} +271 -5
- package/dist/chunks/date-7Iz2BGsL.js.map +1 -0
- package/dist/chunks/index-BoV-4S1F.js +894 -0
- package/dist/chunks/index-BoV-4S1F.js.map +1 -0
- package/dist/chunks/index-eWXdjyyy.js +426 -0
- package/dist/chunks/index-eWXdjyyy.js.map +1 -0
- package/dist/chunks/json-nIhyRPOU.js +1934 -0
- package/dist/chunks/json-nIhyRPOU.js.map +1 -0
- package/dist/{validators/unknown.js → chunks/unknown-CjSRcELI.js} +6 -3
- package/dist/chunks/unknown-CjSRcELI.js.map +1 -0
- package/dist/cjs/errors.cjs +387 -0
- package/dist/cjs/errors.cjs.map +1 -0
- package/dist/cjs/index.cjs +9815 -0
- package/dist/cjs/index.cjs.map +1 -0
- package/dist/cjs/locales/index.cjs +2877 -0
- package/dist/cjs/locales/index.cjs.map +1 -0
- package/dist/cjs/locales/lazy.cjs +3169 -0
- package/dist/cjs/locales/lazy.cjs.map +1 -0
- package/dist/cjs/mini.cjs +7161 -0
- package/dist/cjs/mini.cjs.map +1 -0
- package/dist/codecs/index.js +4 -275
- package/dist/codecs/index.js.map +1 -1
- package/dist/coercion/index.d.ts +11 -0
- package/dist/coercion/index.d.ts.map +1 -0
- package/dist/coercion/{bigint.js → index.js} +7 -4
- package/dist/coercion/index.js.map +1 -0
- package/dist/compat/emitter.js +6 -4
- package/dist/compat/emitter.js.map +1 -1
- package/dist/compat/result.js +21 -19
- package/dist/compat/result.js.map +1 -1
- package/dist/errors.js +13 -10
- package/dist/errors.js.map +1 -1
- package/dist/index.js +225 -126
- package/dist/index.js.map +1 -1
- package/dist/kernel.js +10 -7
- package/dist/kernel.js.map +1 -1
- package/dist/locales/af.js +4 -2
- package/dist/locales/af.js.map +1 -1
- package/dist/locales/ar.js +4 -2
- package/dist/locales/ar.js.map +1 -1
- package/dist/locales/bn.js +4 -2
- package/dist/locales/bn.js.map +1 -1
- package/dist/locales/da.js +4 -2
- package/dist/locales/da.js.map +1 -1
- package/dist/locales/de.js +4 -2
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/en.js +4 -2
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es-MX.js +4 -2
- package/dist/locales/es-MX.js.map +1 -1
- package/dist/locales/es.js +4 -2
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/fi.js +4 -2
- package/dist/locales/fi.js.map +1 -1
- package/dist/locales/fr.js +4 -2
- package/dist/locales/fr.js.map +1 -1
- package/dist/locales/hi.js +4 -2
- package/dist/locales/hi.js.map +1 -1
- package/dist/locales/id.js +4 -2
- package/dist/locales/id.js.map +1 -1
- package/dist/locales/index.js +3 -91
- package/dist/locales/index.js.map +1 -1
- package/dist/locales/it.js +4 -2
- package/dist/locales/it.js.map +1 -1
- package/dist/locales/ja.js +4 -2
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +4 -2
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/lazy.d.ts +111 -0
- package/dist/locales/lazy.d.ts.map +1 -0
- package/dist/locales/lazy.js +220 -0
- package/dist/locales/lazy.js.map +1 -0
- package/dist/locales/nl.js +4 -2
- package/dist/locales/nl.js.map +1 -1
- package/dist/locales/no.js +4 -2
- package/dist/locales/no.js.map +1 -1
- package/dist/locales/pl.js +4 -2
- package/dist/locales/pl.js.map +1 -1
- package/dist/locales/pt-BR.js +4 -2
- package/dist/locales/pt-BR.js.map +1 -1
- package/dist/locales/pt.js +4 -2
- package/dist/locales/pt.js.map +1 -1
- package/dist/locales/ru.js +4 -2
- package/dist/locales/ru.js.map +1 -1
- package/dist/locales/sv.js +4 -2
- package/dist/locales/sv.js.map +1 -1
- package/dist/locales/sw.js +4 -2
- package/dist/locales/sw.js.map +1 -1
- package/dist/locales/th.js +4 -2
- package/dist/locales/th.js.map +1 -1
- package/dist/locales/tr.js +4 -2
- package/dist/locales/tr.js.map +1 -1
- package/dist/locales/vi.js +4 -2
- package/dist/locales/vi.js.map +1 -1
- package/dist/locales/zh.js +4 -2
- package/dist/locales/zh.js.map +1 -1
- package/dist/mini.d.ts +182 -0
- package/dist/mini.d.ts.map +1 -0
- package/dist/mini.js +132 -0
- package/dist/mini.js.map +1 -0
- package/dist/pigment.js +8 -7
- package/dist/pigment.js.map +1 -1
- package/dist/validators/index.js +5 -45
- package/dist/validators/index.js.map +1 -1
- package/package.json +69 -11
- package/dist/cli/benchmark.d.ts +0 -15
- package/dist/cli/benchmark.d.ts.map +0 -1
- package/dist/cli/benchmark.js +0 -248
- package/dist/cli/benchmark.js.map +0 -1
- package/dist/cli/bin.js +0 -35
- package/dist/cli/bin.js.map +0 -1
- package/dist/cli/commands/benchmark.js +0 -204
- package/dist/cli/commands/benchmark.js.map +0 -1
- package/dist/cli/commands/validate.js +0 -157
- package/dist/cli/commands/validate.js.map +0 -1
- package/dist/cli/generate.d.ts +0 -14
- package/dist/cli/generate.d.ts.map +0 -1
- package/dist/cli/generate.js +0 -233
- package/dist/cli/generate.js.map +0 -1
- package/dist/cli/index.js +0 -182
- package/dist/cli/index.js.map +0 -1
- package/dist/cli/validate.d.ts +0 -15
- package/dist/cli/validate.d.ts.map +0 -1
- package/dist/cli/validate.js +0 -162
- package/dist/cli/validate.js.map +0 -1
- package/dist/coercion/bigint.js.map +0 -1
- package/dist/coercion/boolean.js +0 -59
- package/dist/coercion/boolean.js.map +0 -1
- package/dist/coercion/date.js +0 -52
- package/dist/coercion/date.js.map +0 -1
- package/dist/coercion/number.js +0 -160
- package/dist/coercion/number.js.map +0 -1
- package/dist/coercion/string.js.map +0 -1
- package/dist/compat/index.js +0 -14
- package/dist/compat/index.js.map +0 -1
- package/dist/events.js +0 -8
- package/dist/events.js.map +0 -1
- package/dist/guards.d.ts +0 -143
- package/dist/guards.d.ts.map +0 -1
- package/dist/guards.js +0 -238
- package/dist/guards.js.map +0 -1
- package/dist/index-new.d.ts.map +0 -1
- package/dist/locales/backup-en.js +0 -105
- package/dist/locales/backup-en.js.map +0 -1
- package/dist/locales/types.js +0 -2
- package/dist/locales/types.js.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/logger.js +0 -184
- package/dist/logger.js.map +0 -1
- package/dist/plugins/codecs.d.ts +0 -17
- package/dist/plugins/codecs.d.ts.map +0 -1
- package/dist/plugins/codecs.js +0 -29
- package/dist/plugins/codecs.js.map +0 -1
- package/dist/plugins/coercion.d.ts +0 -13
- package/dist/plugins/coercion.d.ts.map +0 -1
- package/dist/plugins/coercion.js +0 -34
- package/dist/plugins/coercion.js.map +0 -1
- package/dist/plugins/core-validators.d.ts +0 -13
- package/dist/plugins/core-validators.d.ts.map +0 -1
- package/dist/plugins/core-validators.js +0 -96
- package/dist/plugins/core-validators.js.map +0 -1
- package/dist/plugins/index.js +0 -8
- package/dist/plugins/index.js.map +0 -1
- package/dist/plugins/kernel.d.ts +0 -29
- package/dist/plugins/kernel.d.ts.map +0 -1
- package/dist/plugins/kernel.js +0 -486
- package/dist/plugins/kernel.js.map +0 -1
- package/dist/plugins/types.js +0 -8
- package/dist/plugins/types.js.map +0 -1
- package/dist/style.d.ts +0 -123
- package/dist/style.d.ts.map +0 -1
- package/dist/style.js +0 -369
- package/dist/style.js.map +0 -1
- package/dist/utils/codec-utils.js +0 -229
- package/dist/utils/codec-utils.js.map +0 -1
- package/dist/utils/deep-merge.js +0 -76
- package/dist/utils/deep-merge.js.map +0 -1
- package/dist/utils/ip-validation.js +0 -98
- package/dist/utils/ip-validation.js.map +0 -1
- package/dist/utils/security.js +0 -61
- package/dist/utils/security.js.map +0 -1
- package/dist/validators/any.js +0 -25
- package/dist/validators/any.js.map +0 -1
- package/dist/validators/array.js +0 -190
- package/dist/validators/array.js.map +0 -1
- package/dist/validators/base.js +0 -499
- package/dist/validators/base.js.map +0 -1
- package/dist/validators/base64.js +0 -65
- package/dist/validators/base64.js.map +0 -1
- package/dist/validators/bigint.js +0 -142
- package/dist/validators/bigint.js.map +0 -1
- package/dist/validators/boolean.js +0 -114
- package/dist/validators/boolean.js.map +0 -1
- package/dist/validators/codec.js +0 -182
- package/dist/validators/codec.js.map +0 -1
- package/dist/validators/custom.js +0 -50
- package/dist/validators/custom.js.map +0 -1
- package/dist/validators/date.js +0 -227
- package/dist/validators/date.js.map +0 -1
- package/dist/validators/discriminated-union.js +0 -98
- package/dist/validators/discriminated-union.js.map +0 -1
- package/dist/validators/enum.js +0 -82
- package/dist/validators/enum.js.map +0 -1
- package/dist/validators/file.js +0 -114
- package/dist/validators/file.js.map +0 -1
- package/dist/validators/function.js +0 -45
- package/dist/validators/function.js.map +0 -1
- package/dist/validators/hex.js +0 -62
- package/dist/validators/hex.js.map +0 -1
- package/dist/validators/intersection.js +0 -64
- package/dist/validators/intersection.js.map +0 -1
- package/dist/validators/json.js +0 -64
- package/dist/validators/json.js.map +0 -1
- package/dist/validators/lazy.js +0 -42
- package/dist/validators/lazy.js.map +0 -1
- package/dist/validators/literal.js +0 -45
- package/dist/validators/literal.js.map +0 -1
- package/dist/validators/map.js +0 -54
- package/dist/validators/map.js.map +0 -1
- package/dist/validators/nan.js +0 -32
- package/dist/validators/nan.js.map +0 -1
- package/dist/validators/never.js +0 -29
- package/dist/validators/never.js.map +0 -1
- package/dist/validators/null.js +0 -31
- package/dist/validators/null.js.map +0 -1
- package/dist/validators/number.js +0 -225
- package/dist/validators/number.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/object.js +0 -458
- package/dist/validators/object.js.map +0 -1
- package/dist/validators/record.js +0 -128
- package/dist/validators/record.js.map +0 -1
- package/dist/validators/set.js +0 -51
- package/dist/validators/set.js.map +0 -1
- package/dist/validators/string-bool.js +0 -127
- package/dist/validators/string-bool.js.map +0 -1
- package/dist/validators/string-formats.js +0 -120
- package/dist/validators/string-formats.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/string.js +0 -253
- package/dist/validators/string.js.map +0 -1
- package/dist/validators/symbol.js +0 -42
- package/dist/validators/symbol.js.map +0 -1
- package/dist/validators/template-literal.js +0 -102
- package/dist/validators/template-literal.js.map +0 -1
- package/dist/validators/tuple.js +0 -55
- package/dist/validators/tuple.js.map +0 -1
- package/dist/validators/uint8array.js +0 -98
- package/dist/validators/uint8array.js.map +0 -1
- package/dist/validators/undefined.js +0 -31
- package/dist/validators/undefined.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
- package/dist/validators/union.js +0 -126
- package/dist/validators/union.js.map +0 -1
- package/dist/validators/unknown.js.map +0 -1
- package/dist/validators/void.js +0 -35
- package/dist/validators/void.js.map +0 -1
- package/dist/validators/xor.js +0 -64
- package/dist/validators/xor.js.map +0 -1
package/dist/validators/date.js
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import { VldBase } from './base.js';
|
|
2
|
-
import { getMessages } from '../locales/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Immutable date validator with chainable methods
|
|
5
|
-
*/
|
|
6
|
-
export class VldDate extends VldBase {
|
|
7
|
-
/**
|
|
8
|
-
* Protected constructor to allow extension while maintaining immutability
|
|
9
|
-
*/
|
|
10
|
-
constructor(config) {
|
|
11
|
-
super();
|
|
12
|
-
this.config = {
|
|
13
|
-
checks: config?.checks || [],
|
|
14
|
-
errorMessage: config?.errorMessage
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* Create a new date validator
|
|
19
|
-
*/
|
|
20
|
-
static create() {
|
|
21
|
-
return new VldDate();
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Parse and validate a date value
|
|
25
|
-
*/
|
|
26
|
-
parse(value) {
|
|
27
|
-
let date;
|
|
28
|
-
if (value instanceof Date) {
|
|
29
|
-
date = value;
|
|
30
|
-
}
|
|
31
|
-
else if (typeof value === 'string' || typeof value === 'number') {
|
|
32
|
-
date = new Date(value);
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
throw new Error(this.config.errorMessage || getMessages().invalidDate);
|
|
36
|
-
}
|
|
37
|
-
// Check if the date is valid
|
|
38
|
-
if (isNaN(date.getTime())) {
|
|
39
|
-
throw new Error(this.config.errorMessage || getMessages().invalidDate);
|
|
40
|
-
}
|
|
41
|
-
// Apply all checks
|
|
42
|
-
for (const check of this.config.checks) {
|
|
43
|
-
if (!check.fn(date)) {
|
|
44
|
-
throw new Error(check.message);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return date;
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Safely parse and validate a date value
|
|
51
|
-
*/
|
|
52
|
-
safeParse(value) {
|
|
53
|
-
try {
|
|
54
|
-
return { success: true, data: this.parse(value) };
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
return { success: false, error: error };
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Create a new validator with minimum date constraint
|
|
62
|
-
* BUG-NEW-009 FIX: Validate that min date is valid before creating validator
|
|
63
|
-
*/
|
|
64
|
-
min(date, message) {
|
|
65
|
-
const minDate = date instanceof Date ? date : new Date(date);
|
|
66
|
-
// Validate that minDate is valid
|
|
67
|
-
if (isNaN(minDate.getTime())) {
|
|
68
|
-
throw new Error(`Invalid date provided to min(): ${date}`);
|
|
69
|
-
}
|
|
70
|
-
return new VldDate({
|
|
71
|
-
...this.config,
|
|
72
|
-
checks: [...this.config.checks, {
|
|
73
|
-
fn: (v) => v >= minDate,
|
|
74
|
-
message: message || getMessages().dateMin(minDate)
|
|
75
|
-
}]
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Create a new validator with maximum date constraint
|
|
80
|
-
* BUG-NEW-009 FIX: Validate that max date is valid before creating validator
|
|
81
|
-
*/
|
|
82
|
-
max(date, message) {
|
|
83
|
-
const maxDate = date instanceof Date ? date : new Date(date);
|
|
84
|
-
// Validate that maxDate is valid
|
|
85
|
-
if (isNaN(maxDate.getTime())) {
|
|
86
|
-
throw new Error(`Invalid date provided to max(): ${date}`);
|
|
87
|
-
}
|
|
88
|
-
return new VldDate({
|
|
89
|
-
...this.config,
|
|
90
|
-
checks: [...this.config.checks, {
|
|
91
|
-
fn: (v) => v <= maxDate,
|
|
92
|
-
message: message || getMessages().dateMax(maxDate)
|
|
93
|
-
}]
|
|
94
|
-
});
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* Create a new validator with a range constraint
|
|
98
|
-
* BUG-NEW-019 FIX: Validate that min/max dates are valid before creating validator
|
|
99
|
-
*/
|
|
100
|
-
between(min, max, message) {
|
|
101
|
-
const minDate = min instanceof Date ? min : new Date(min);
|
|
102
|
-
const maxDate = max instanceof Date ? max : new Date(max);
|
|
103
|
-
// Validate that both dates are valid
|
|
104
|
-
if (isNaN(minDate.getTime())) {
|
|
105
|
-
throw new Error(`Invalid min date provided to between(): ${min}`);
|
|
106
|
-
}
|
|
107
|
-
if (isNaN(maxDate.getTime())) {
|
|
108
|
-
throw new Error(`Invalid max date provided to between(): ${max}`);
|
|
109
|
-
}
|
|
110
|
-
return new VldDate({
|
|
111
|
-
...this.config,
|
|
112
|
-
checks: [...this.config.checks, {
|
|
113
|
-
fn: (v) => v >= minDate && v <= maxDate,
|
|
114
|
-
message: message || `Date must be between ${minDate.toISOString()} and ${maxDate.toISOString()}`
|
|
115
|
-
}]
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Create a new validator that checks if date is in the past
|
|
120
|
-
* BUG-NEW-006 FIX: Capture reference date at validator creation time for deterministic behavior
|
|
121
|
-
*/
|
|
122
|
-
past(message) {
|
|
123
|
-
const referenceDate = new Date(); // Capture NOW at validator creation time
|
|
124
|
-
return new VldDate({
|
|
125
|
-
...this.config,
|
|
126
|
-
checks: [...this.config.checks, {
|
|
127
|
-
fn: (v) => v < referenceDate,
|
|
128
|
-
message: message || 'Date must be in the past'
|
|
129
|
-
}]
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Create a new validator that checks if date is in the future
|
|
134
|
-
* BUG-NEW-006 FIX: Capture reference date at validator creation time for deterministic behavior
|
|
135
|
-
*/
|
|
136
|
-
future(message) {
|
|
137
|
-
const referenceDate = new Date(); // Capture NOW at validator creation time
|
|
138
|
-
return new VldDate({
|
|
139
|
-
...this.config,
|
|
140
|
-
checks: [...this.config.checks, {
|
|
141
|
-
fn: (v) => v > referenceDate,
|
|
142
|
-
message: message || 'Date must be in the future'
|
|
143
|
-
}]
|
|
144
|
-
});
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Create a new validator that checks if date is today
|
|
148
|
-
* BUG-NEW-008 FIX: Capture reference date at validator creation time for deterministic behavior
|
|
149
|
-
*/
|
|
150
|
-
today(message) {
|
|
151
|
-
// Capture the reference date (today) at validator creation time
|
|
152
|
-
const referenceDate = new Date();
|
|
153
|
-
const refYear = referenceDate.getFullYear();
|
|
154
|
-
const refMonth = referenceDate.getMonth();
|
|
155
|
-
const refDate = referenceDate.getDate();
|
|
156
|
-
return new VldDate({
|
|
157
|
-
...this.config,
|
|
158
|
-
checks: [...this.config.checks, {
|
|
159
|
-
fn: (v) => {
|
|
160
|
-
return v.getFullYear() === refYear &&
|
|
161
|
-
v.getMonth() === refMonth &&
|
|
162
|
-
v.getDate() === refDate;
|
|
163
|
-
},
|
|
164
|
-
message: message || 'Date must be today'
|
|
165
|
-
}]
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* Create a new validator that checks if date is a weekday
|
|
170
|
-
*/
|
|
171
|
-
weekday(message) {
|
|
172
|
-
return new VldDate({
|
|
173
|
-
...this.config,
|
|
174
|
-
checks: [...this.config.checks, {
|
|
175
|
-
fn: (v) => {
|
|
176
|
-
const day = v.getDay();
|
|
177
|
-
return day >= 1 && day <= 5;
|
|
178
|
-
},
|
|
179
|
-
message: message || 'Date must be a weekday'
|
|
180
|
-
}]
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
/**
|
|
184
|
-
* Create a new validator that checks if date is a weekend
|
|
185
|
-
*/
|
|
186
|
-
weekend(message) {
|
|
187
|
-
return new VldDate({
|
|
188
|
-
...this.config,
|
|
189
|
-
checks: [...this.config.checks, {
|
|
190
|
-
fn: (v) => {
|
|
191
|
-
const day = v.getDay();
|
|
192
|
-
return day === 0 || day === 6;
|
|
193
|
-
},
|
|
194
|
-
message: message || 'Date must be a weekend'
|
|
195
|
-
}]
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
/**
|
|
199
|
-
* Create a new validator with strict greater than constraint
|
|
200
|
-
* Zod 4 API parity - strictly greater than (not equal to)
|
|
201
|
-
*/
|
|
202
|
-
gt(value, message) {
|
|
203
|
-
const compareDate = value instanceof Date ? value : new Date(value);
|
|
204
|
-
return new VldDate({
|
|
205
|
-
...this.config,
|
|
206
|
-
checks: [...this.config.checks, {
|
|
207
|
-
fn: (v) => v.getTime() > compareDate.getTime(),
|
|
208
|
-
message: message || `Date must be greater than ${compareDate.toISOString()}`
|
|
209
|
-
}]
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
/**
|
|
213
|
-
* Create a new validator with strict less than constraint
|
|
214
|
-
* Zod 4 API parity - strictly less than (not equal to)
|
|
215
|
-
*/
|
|
216
|
-
lt(value, message) {
|
|
217
|
-
const compareDate = value instanceof Date ? value : new Date(value);
|
|
218
|
-
return new VldDate({
|
|
219
|
-
...this.config,
|
|
220
|
-
checks: [...this.config.checks, {
|
|
221
|
-
fn: (v) => v.getTime() < compareDate.getTime(),
|
|
222
|
-
message: message || `Date must be less than ${compareDate.toISOString()}`
|
|
223
|
-
}]
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
//# sourceMappingURL=date.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"date.js","sourceRoot":"","sources":["../../src/validators/date.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldBase, ParseResult } from './base';\r\nimport { getMessages } from '../locales';\r\n\r\n/**\r\n * Type for date validation check functions\r\n */\r\ntype DateCheckFn = (value: Date) => boolean;\r\n\r\ninterface DateCheck {\r\n fn: DateCheckFn;\r\n message: string;\r\n}\r\n\r\n/**\r\n * Configuration for date validator\r\n */\r\ninterface DateValidatorConfig {\r\n readonly checks: ReadonlyArray<DateCheck>;\r\n readonly errorMessage?: string;\r\n}\r\n\r\n/**\r\n * Immutable date validator with chainable methods\r\n */\r\nexport class VldDate extends VldBase<Date, Date> {\r\n private readonly config: DateValidatorConfig;\r\n\r\n /**\r\n * Protected constructor to allow extension while maintaining immutability\r\n */\r\n protected constructor(config?: Partial<DateValidatorConfig>) {\r\n super();\r\n this.config = {\r\n checks: config?.checks || [],\r\n errorMessage: config?.errorMessage\r\n };\r\n }\r\n\r\n /**\r\n * Create a new date validator\r\n */\r\n static create(): VldDate {\r\n return new VldDate();\r\n }\r\n\r\n /**\r\n * Parse and validate a date value\r\n */\r\n parse(value: unknown): Date {\r\n let date: Date;\r\n\r\n if (value instanceof Date) {\r\n date = value;\r\n } else if (typeof value === 'string' || typeof value === 'number') {\r\n date = new Date(value);\r\n } else {\r\n throw new Error(this.config.errorMessage || getMessages().invalidDate);\r\n }\r\n\r\n // Check if the date is valid\r\n if (isNaN(date.getTime())) {\r\n throw new Error(this.config.errorMessage || getMessages().invalidDate);\r\n }\r\n\r\n // Apply all checks\r\n for (const check of this.config.checks) {\r\n if (!check.fn(date)) {\r\n throw new Error(check.message);\r\n }\r\n }\r\n\r\n return date;\r\n }\r\n\r\n /**\r\n * Safely parse and validate a date value\r\n */\r\n safeParse(value: unknown): ParseResult<Date> {\r\n try {\r\n return { success: true, data: this.parse(value) };\r\n } catch (error) {\r\n return { success: false, error: error as Error };\r\n }\r\n }\r\n\r\n /**\r\n * Create a new validator with minimum date constraint\r\n * BUG-NEW-009 FIX: Validate that min date is valid before creating validator\r\n */\r\n min(date: Date | string | number, message?: string): VldDate {\r\n const minDate = date instanceof Date ? date : new Date(date);\r\n\r\n // Validate that minDate is valid\r\n if (isNaN(minDate.getTime())) {\r\n throw new Error(`Invalid date provided to min(): ${date}`);\r\n }\r\n\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => v >= minDate,\r\n message: message || getMessages().dateMin(minDate)\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator with maximum date constraint\r\n * BUG-NEW-009 FIX: Validate that max date is valid before creating validator\r\n */\r\n max(date: Date | string | number, message?: string): VldDate {\r\n const maxDate = date instanceof Date ? date : new Date(date);\r\n\r\n // Validate that maxDate is valid\r\n if (isNaN(maxDate.getTime())) {\r\n throw new Error(`Invalid date provided to max(): ${date}`);\r\n }\r\n\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => v <= maxDate,\r\n message: message || getMessages().dateMax(maxDate)\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator with a range constraint\r\n * BUG-NEW-019 FIX: Validate that min/max dates are valid before creating validator\r\n */\r\n between(\r\n min: Date | string | number,\r\n max: Date | string | number,\r\n message?: string\r\n ): VldDate {\r\n const minDate = min instanceof Date ? min : new Date(min);\r\n const maxDate = max instanceof Date ? max : new Date(max);\r\n\r\n // Validate that both dates are valid\r\n if (isNaN(minDate.getTime())) {\r\n throw new Error(`Invalid min date provided to between(): ${min}`);\r\n }\r\n if (isNaN(maxDate.getTime())) {\r\n throw new Error(`Invalid max date provided to between(): ${max}`);\r\n }\r\n\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => v >= minDate && v <= maxDate,\r\n message: message || `Date must be between ${minDate.toISOString()} and ${maxDate.toISOString()}`\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator that checks if date is in the past\r\n * BUG-NEW-006 FIX: Capture reference date at validator creation time for deterministic behavior\r\n */\r\n past(message?: string): VldDate {\r\n const referenceDate = new Date(); // Capture NOW at validator creation time\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => v < referenceDate,\r\n message: message || 'Date must be in the past'\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator that checks if date is in the future\r\n * BUG-NEW-006 FIX: Capture reference date at validator creation time for deterministic behavior\r\n */\r\n future(message?: string): VldDate {\r\n const referenceDate = new Date(); // Capture NOW at validator creation time\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => v > referenceDate,\r\n message: message || 'Date must be in the future'\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator that checks if date is today\r\n * BUG-NEW-008 FIX: Capture reference date at validator creation time for deterministic behavior\r\n */\r\n today(message?: string): VldDate {\r\n // Capture the reference date (today) at validator creation time\r\n const referenceDate = new Date();\r\n const refYear = referenceDate.getFullYear();\r\n const refMonth = referenceDate.getMonth();\r\n const refDate = referenceDate.getDate();\r\n\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => {\r\n return v.getFullYear() === refYear &&\r\n v.getMonth() === refMonth &&\r\n v.getDate() === refDate;\r\n },\r\n message: message || 'Date must be today'\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator that checks if date is a weekday\r\n */\r\n weekday(message?: string): VldDate {\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => {\r\n const day = v.getDay();\r\n return day >= 1 && day <= 5;\r\n },\r\n message: message || 'Date must be a weekday'\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator that checks if date is a weekend\r\n */\r\n weekend(message?: string): VldDate {\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => {\r\n const day = v.getDay();\r\n return day === 0 || day === 6;\r\n },\r\n message: message || 'Date must be a weekend'\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator with strict greater than constraint\r\n * Zod 4 API parity - strictly greater than (not equal to)\r\n */\r\n gt(value: Date | number, message?: string): VldDate {\r\n const compareDate = value instanceof Date ? value : new Date(value);\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => v.getTime() > compareDate.getTime(),\r\n message: message || `Date must be greater than ${compareDate.toISOString()}`\r\n }]\r\n });\r\n }\r\n\r\n /**\r\n * Create a new validator with strict less than constraint\r\n * Zod 4 API parity - strictly less than (not equal to)\r\n */\r\n lt(value: Date | number, message?: string): VldDate {\r\n const compareDate = value instanceof Date ? value : new Date(value);\r\n return new VldDate({\r\n ...this.config,\r\n checks: [...this.config.checks, {\r\n fn: (v: Date) => v.getTime() < compareDate.getTime(),\r\n message: message || `Date must be less than ${compareDate.toISOString()}`\r\n }]\r\n });\r\n }\r\n}"]}
|
|
@@ -1,98 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"discriminated-union.js","sourceRoot":"","sources":["../../src/validators/discriminated-union.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * VldDiscriminatedUnion - Fast union validation using discriminator field\r\n * Part of Zod 4 API parity implementation\r\n * Provides O(1) lookup performance by using a discriminator key\r\n */\r\n\r\nimport { VldBase } from './base';\r\nimport { VldObject } from './object';\r\nimport { VldLiteral } from './literal';\r\nimport { VldEnum } from './enum';\r\nimport type { ParseResult } from './base';\r\n\r\n/**\r\n * Extract literal values from a schema\r\n */\r\nfunction extractLiteralValues(schema: VldBase<unknown, any>): unknown[] {\r\n if (schema instanceof VldLiteral) {\r\n const value = (schema as any).literal;\r\n return [value];\r\n }\r\n if (schema instanceof VldEnum) {\r\n return (schema as any).values as unknown[];\r\n }\r\n throw new Error('Discriminator must be a literal or enum schema');\r\n}\r\n\r\n/**\r\n * Discriminated union validator - validates union based on discriminator key\r\n * Much faster than regular union when you have a discriminator field\r\n */\r\nexport class VldDiscriminatedUnion<K extends string, Options extends VldBase<any, any>[]>\r\n extends VldBase<unknown, Options[number] extends VldBase<any, infer T> ? T : never> {\r\n\r\n private readonly _discriminatorMap: Map<unknown, VldBase<any, any>>;\r\n\r\n constructor(\r\n private readonly _discriminator: K,\r\n private readonly _options: Options\r\n ) {\r\n super();\r\n\r\n // Build discriminator map for O(1) lookup\r\n this._discriminatorMap = new Map();\r\n\r\n for (const option of _options) {\r\n if (!(option instanceof VldObject)) {\r\n throw new Error('All options in a discriminated union must be objects');\r\n }\r\n\r\n const discriminatorSchema = (option as any).config?.shape?.[this._discriminator];\r\n if (!discriminatorSchema) {\r\n throw new Error(`Missing discriminator key \"${this._discriminator}\" in one of the options`);\r\n }\r\n\r\n const values = extractLiteralValues(discriminatorSchema);\r\n\r\n for (const value of values) {\r\n if (this._discriminatorMap.has(value)) {\r\n throw new Error(`Duplicate discriminator value \"${String(value)}\" found in discriminated union`);\r\n }\r\n this._discriminatorMap.set(value, option);\r\n }\r\n }\r\n }\r\n\r\n static create<K extends string, Options extends VldBase<any, any>[]>(\r\n discriminator: K,\r\n options: Options\r\n ): VldDiscriminatedUnion<K, Options> {\r\n return new VldDiscriminatedUnion(discriminator, options);\r\n }\r\n\r\n parse(value: unknown): Options[number] extends VldBase<any, infer T> ? T : never {\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<Options[number] extends VldBase<any, infer T> ? T : never> {\r\n // Check if input is an object\r\n if (typeof value !== 'object' || value === null) {\r\n return {\r\n success: false,\r\n error: new Error(\r\n `Expected object, received ${value === null ? 'null' : typeof value}`\r\n )\r\n };\r\n }\r\n\r\n // Get discriminator value\r\n const discriminatorValue = (value as any)[this._discriminator];\r\n\r\n // Look up matching schema\r\n const matchedSchema = this._discriminatorMap.get(discriminatorValue);\r\n\r\n if (!matchedSchema) {\r\n const validValues = Array.from(this._discriminatorMap.keys());\r\n return {\r\n success: false,\r\n error: new Error(\r\n `Invalid discriminator value for \"${this._discriminator}\". ` +\r\n `Expected one of: ${JSON.stringify(validValues)}, ` +\r\n `received: ${JSON.stringify(discriminatorValue)}`\r\n )\r\n };\r\n }\r\n\r\n // Validate against matched schema\r\n return matchedSchema.safeParse(value) as ParseResult<Options[number] extends VldBase<any, infer T> ? T : never>;\r\n }\r\n\r\n /**\r\n * Get the discriminator key\r\n */\r\n getDiscriminator(): K {\r\n return this._discriminator;\r\n }\r\n\r\n /**\r\n * Get all options\r\n */\r\n getOptions(): Options {\r\n return this._options;\r\n }\r\n}\r\n"]}
|
package/dist/validators/enum.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { VldBase } from './base.js';
|
|
2
|
-
import { getMessages } from '../locales/index.js';
|
|
3
|
-
/**
|
|
4
|
-
* Immutable enum validator for string enum values
|
|
5
|
-
*/
|
|
6
|
-
export class VldEnum extends VldBase {
|
|
7
|
-
/**
|
|
8
|
-
* Private constructor to enforce immutability
|
|
9
|
-
*/
|
|
10
|
-
constructor(values, errorMessage) {
|
|
11
|
-
super();
|
|
12
|
-
this.values = values;
|
|
13
|
-
this.errorMessage = errorMessage;
|
|
14
|
-
}
|
|
15
|
-
/**
|
|
16
|
-
* Create a new enum validator
|
|
17
|
-
*/
|
|
18
|
-
static create(values) {
|
|
19
|
-
return new VldEnum(values);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Parse and validate an enum value
|
|
23
|
-
*/
|
|
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
|
-
}
|
|
30
|
-
if (!this.values.includes(value)) {
|
|
31
|
-
throw new Error(this.errorMessage ||
|
|
32
|
-
getMessages().enumExpected([...this.values], JSON.stringify(value)));
|
|
33
|
-
}
|
|
34
|
-
return value;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Safely parse and validate an enum value
|
|
38
|
-
*/
|
|
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
|
-
}
|
|
48
|
-
if (this.values.includes(value)) {
|
|
49
|
-
return { success: true, data: value };
|
|
50
|
-
}
|
|
51
|
-
return {
|
|
52
|
-
success: false,
|
|
53
|
-
error: new Error(this.errorMessage ||
|
|
54
|
-
getMessages().enumExpected([...this.values], JSON.stringify(value)))
|
|
55
|
-
};
|
|
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
|
-
}
|
|
81
|
-
}
|
|
82
|
-
//# sourceMappingURL=enum.js.map
|
|
@@ -1 +0,0 @@
|
|
|
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}"]}
|
package/dist/validators/file.js
DELETED
|
@@ -1,114 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/validators/file.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldBase, ParseResult } from './base';\r\nimport { getMessages } from '../locales';\r\n\r\n/**\r\n * File validation check types\r\n */\r\ntype FileCheck =\r\n | { type: 'min'; value: number; message?: string }\r\n | { type: 'max'; value: number; message?: string }\r\n | { type: 'mime'; value: string[]; message?: string };\r\n\r\n/**\r\n * File representation for validation\r\n * In browsers: File object\r\n * In Node.js: Object with size and type properties\r\n */\r\nexport type VldFileValue = File | { size: number; type: string; name?: string };\r\n\r\n/**\r\n * Immutable file validator for file uploads\r\n * Supports size and MIME type validation\r\n */\r\nexport class VldFile extends VldBase<unknown, VldFileValue> {\r\n private constructor(\r\n private readonly checks: readonly FileCheck[] = []\r\n ) {\r\n super();\r\n }\r\n\r\n /**\r\n * Create a new file validator\r\n */\r\n static create(): VldFile {\r\n return new VldFile();\r\n }\r\n\r\n /**\r\n * Parse and validate a file value\r\n */\r\n parse(value: unknown): VldFileValue {\r\n // Check if File API is supported\r\n const FileSupported = typeof File !== 'undefined';\r\n\r\n if (!FileSupported) {\r\n throw new Error(getMessages().fileNotSupported || 'File API not supported in this environment');\r\n }\r\n\r\n // Check if value is a File object\r\n if (!(value instanceof File)) {\r\n // Allow plain object with size and type for Node.js compatibility\r\n if (\r\n typeof value === 'object' &&\r\n value !== null &&\r\n 'size' in value &&\r\n 'type' in value\r\n ) {\r\n const fileObj = value as { size: number; type: string; name?: string };\r\n return this.runChecks(fileObj);\r\n }\r\n\r\n throw new Error(getMessages().invalidFile || 'Expected a File object');\r\n }\r\n\r\n return this.runChecks(value);\r\n }\r\n\r\n /**\r\n * Run all validation checks on the file\r\n */\r\n private runChecks(file: VldFileValue): VldFileValue {\r\n const msgs = getMessages();\r\n\r\n for (const check of this.checks) {\r\n switch (check.type) {\r\n case 'min':\r\n if (file.size < check.value) {\r\n throw new Error(\r\n check.message ||\r\n (msgs.fileMinSize?.(check.value) || `File size must be at least ${check.value} bytes`)\r\n );\r\n }\r\n break;\r\n\r\n case 'max':\r\n if (file.size > check.value) {\r\n throw new Error(\r\n check.message ||\r\n (msgs.fileMaxSize?.(check.value) || `File size must not exceed ${check.value} bytes`)\r\n );\r\n }\r\n break;\r\n\r\n case 'mime':\r\n if (!check.value.includes(file.type)) {\r\n throw new Error(\r\n check.message ||\r\n (msgs.fileMimeType?.(check.value) || `Invalid file type. Expected: ${check.value.join(', ')}`)\r\n );\r\n }\r\n break;\r\n }\r\n }\r\n\r\n return file;\r\n }\r\n\r\n /**\r\n * Safely parse and validate a file value\r\n */\r\n safeParse(value: unknown): ParseResult<VldFileValue> {\r\n try {\r\n return { success: true, data: this.parse(value) };\r\n } catch (error) {\r\n return { success: false, error: error as Error };\r\n }\r\n }\r\n\r\n /**\r\n * Set minimum file size in bytes\r\n */\r\n min(bytes: number, message?: string): VldFile {\r\n return new VldFile([...this.checks, { type: 'min', value: bytes, message }]);\r\n }\r\n\r\n /**\r\n * Set maximum file size in bytes\r\n */\r\n max(bytes: number, message?: string): VldFile {\r\n return new VldFile([...this.checks, { type: 'max', value: bytes, message }]);\r\n }\r\n\r\n /**\r\n * Set allowed MIME types\r\n */\r\n mime(types: string | string[], message?: string): VldFile {\r\n const typeArray = Array.isArray(types) ? types : [types];\r\n return new VldFile([...this.checks, { type: 'mime', value: typeArray, message }]);\r\n }\r\n\r\n /**\r\n * Set both minimum and maximum file size\r\n */\r\n size(min: number, max: number, message?: string): VldFile {\r\n return this.min(min, message).max(max, message);\r\n }\r\n}\r\n\r\n/**\r\n * Helper function to create file validators\r\n * Usage: v.file().min(1024).max(10485760).mime(['image/jpeg', 'image/png'])\r\n */\r\nexport function file(): VldFile {\r\n return VldFile.create();\r\n}\r\n"]}
|
|
@@ -1,45 +0,0 @@
|
|
|
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
|
|
@@ -1 +0,0 @@
|
|
|
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';\r\nimport { getMessages } from '../locales';\r\n\r\n/**\r\n * Immutable function validator\r\n * Validates that a value is a function\r\n */\r\nexport class VldFunction extends VldBase<unknown, Function> {\r\n private constructor() {\r\n super();\r\n }\r\n\r\n /**\r\n * Create a new function validator\r\n */\r\n static create(): VldFunction {\r\n return new VldFunction();\r\n }\r\n\r\n /**\r\n * Parse and validate a function value\r\n */\r\n parse(value: unknown): Function {\r\n if (typeof value !== 'function') {\r\n throw new Error(\r\n getMessages().invalidFunction || 'Expected a function'\r\n );\r\n }\r\n\r\n return value as Function;\r\n }\r\n\r\n /**\r\n * Safely parse and validate a function value\r\n */\r\n safeParse(value: unknown): ParseResult<Function> {\r\n try {\r\n return { success: true, data: this.parse(value) };\r\n } catch (error) {\r\n return { success: false, error: error as Error };\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Helper function to create function validators\r\n * Usage: v.function()\r\n */\r\nexport function functionValidator(): VldFunction {\r\n return VldFunction.create();\r\n}\r\n"]}
|