@esmj/schema 0.3.3 → 0.3.5
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/README.md +108 -71
- package/dist/index.d.mts +2 -4
- package/dist/index.d.ts +2 -4
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -21,9 +21,9 @@ npm install @esmj/schema
|
|
|
21
21
|
|
|
22
22
|
### Performance Highlights
|
|
23
23
|
|
|
24
|
-
- **Schema Creation**: Create schemas
|
|
25
|
-
- **Parsing**: Parse data with
|
|
26
|
-
- **Error Handling**: Efficiently manage errors
|
|
24
|
+
- **Schema Creation**: Create schemas at up to 4 370 618 ops/s (0.23 μs latency) with @sinclair/typebox, or 736 810 ops/s (1.36 μs latency) with @esmj/schema. Superstruct and @esmj/schema are also among the fastest for schema creation.
|
|
25
|
+
- **Parsing**: Parse data at up to 4 627 714 ops/s (0.22 μs latency) with @zod/mini (note: @zod/mini was observed to consume 200% CPU, while other libraries used only 100% CPU), or 3 142 587 ops/s (0.32 μs latency) with @esmj/schema. ArkType and effect/Schema also show strong parsing throughput.
|
|
26
|
+
- **Error Handling**: Efficiently manage errors at up to 2 428 049 ops/s (0.41 μs latency) with @esmj/schema, or 1 386 616 ops/s (0.72 μs latency) with @zod/mini.
|
|
27
27
|
|
|
28
28
|
These performance metrics make `@esmj/schema` an excellent choice for both frontend and backend applications where speed and efficiency are critical.
|
|
29
29
|
|
|
@@ -31,54 +31,64 @@ These performance metrics make `@esmj/schema` an excellent choice for both front
|
|
|
31
31
|
|
|
32
32
|
When choosing a schema validation library, bundle size can be an important factor, especially for frontend applications where minimizing JavaScript size is critical. Here's how `@esmj/schema` compares to other popular libraries:
|
|
33
33
|
|
|
34
|
-
| Library
|
|
35
|
-
|
|
36
|
-
| `@esmj/schema`
|
|
37
|
-
| Superstruct
|
|
38
|
-
|
|
|
39
|
-
|
|
|
40
|
-
| @
|
|
41
|
-
|
|
|
42
|
-
|
|
|
43
|
-
|
|
|
34
|
+
| Library | Bundle Size (minified + gzipped) |
|
|
35
|
+
|-------------------|---------------------------------|
|
|
36
|
+
| `@esmj/schema` | `~1,2 KB` |
|
|
37
|
+
| Superstruct | ~3.2 KB |
|
|
38
|
+
| @sinclair/typebox | ~11.7 KB |
|
|
39
|
+
| Yup | ~12.2 KB |
|
|
40
|
+
| Zod@3 | ~13 KB |
|
|
41
|
+
| @zod/mini | ~20,5 KB |
|
|
42
|
+
| Joi | ~40,4 KB |
|
|
43
|
+
| Zod@4 | ~40,8 KB |
|
|
44
|
+
| ArkType | ~41,8 KB |
|
|
45
|
+
| Effect/Schema | ~115.5 KB |
|
|
44
46
|
|
|
45
47
|
### Performance Comparison
|
|
46
48
|
|
|
49
|
+
*All benchmarks were measured on Node.js v24.1.0.*
|
|
50
|
+
|
|
47
51
|
#### Schema Creation Performance
|
|
48
52
|
|
|
49
|
-
| Library
|
|
50
|
-
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
| @zod/mini
|
|
54
|
-
| Yup
|
|
55
|
-
| Superstruct
|
|
56
|
-
| Joi
|
|
57
|
-
|
|
|
53
|
+
| Library | Throughput average (ops/s) | Latency average (μs) |
|
|
54
|
+
|-------------------|-------------------------------:|-------------------------:|
|
|
55
|
+
| @esmj/schema | 736 810.12 ± 3.03% | 1.36 ± 3.24% |
|
|
56
|
+
| Zod@3 | 112 575.50 ± 0.86% | 8.88 ± 0.87% |
|
|
57
|
+
| @zod/mini | 23 456.07 ± 1.26% | 42.64 ± 1.28% |
|
|
58
|
+
| Yup | 75 051.06 ± 4.38% | 13.36 ± 4.41% |
|
|
59
|
+
| Superstruct | 509 401.06 ± 0.80% | 1.96 ± 0.80% |
|
|
60
|
+
| Joi | 42 455.28 ± 1.27% | 23.56 ± 1.30% |
|
|
61
|
+
| `@sinclair/typebox` | `4 370 618.49 ± 1.23%` | `0.23 ± 1.23%` |
|
|
62
|
+
| ArkType | 16 282.69 ± 4.14% | 61.61 ± 4.38% |
|
|
63
|
+
| effect/Schema | 24 919.15 ± 4.31% | 40.31 ± 4.78% |
|
|
58
64
|
|
|
59
65
|
#### Parsing Performance
|
|
60
66
|
|
|
61
|
-
| Library
|
|
62
|
-
|
|
63
|
-
|
|
|
64
|
-
| zod@3
|
|
65
|
-
|
|
|
66
|
-
| Yup
|
|
67
|
-
| Superstruct
|
|
68
|
-
| Joi
|
|
69
|
-
|
|
|
67
|
+
| Library | Throughput average (ops/s) | Latency average (μs) |
|
|
68
|
+
|-------------------|-------------------------------:|-------------------------:|
|
|
69
|
+
| @esmj/schema | 3 142 587.31 ± 0.97% | 0.32 ± 0.99% |
|
|
70
|
+
| zod@3 | 1 018 777.24 ± 0.64% | 0.98 ± 0.65% |
|
|
71
|
+
| `@zod/mini` | `4 627 714.90 ± 2.23%` | `0.22 ± 2.36%` |
|
|
72
|
+
| Yup | 108 361.49 ± 0.50% | 9.23 ± 0.51% |
|
|
73
|
+
| Superstruct | 252 904.42 ± 2.20% | 3.96 ± 2.44% |
|
|
74
|
+
| Joi | 346 094.49 ± 0.65% | 2.89 ± 0.65% |
|
|
75
|
+
| @sinclair/typebox | 228 711.62 ± 2.03% | 4.38 ± 2.23% |
|
|
76
|
+
| ArkType | 1 677 066.00 ± 0.58% | 0.60 ± 0.59% |
|
|
77
|
+
| effect/Schema | 1 060 056.14 ± 0.61% | 0.94 ± 0.61% |
|
|
70
78
|
|
|
71
79
|
#### Error Handling Performance
|
|
72
80
|
|
|
73
|
-
| Library
|
|
74
|
-
|
|
75
|
-
| `@esmj/schema`
|
|
76
|
-
|
|
|
77
|
-
| @zod/mini
|
|
78
|
-
| Yup
|
|
79
|
-
| Superstruct
|
|
80
|
-
| Joi
|
|
81
|
-
|
|
|
81
|
+
| Library | Throughput average (ops/s) | Latency average (μs) |
|
|
82
|
+
|-------------------|-------------------------------:|-------------------------:|
|
|
83
|
+
| `@esmj/schema` | `2 428 049.34 ± 0.54%` | `0.41 ± 0.53%` |
|
|
84
|
+
| zod@3 | 641 504.22 ± 3.67% | 1.57 ± 4.38% |
|
|
85
|
+
| @zod/mini | 1 386 616.61 ± 0.60% | 0.72 ± 0.60% |
|
|
86
|
+
| Yup | 98 904.30 ± 0.61% | 10.11 ± 0.61% |
|
|
87
|
+
| Superstruct | 122 782.09 ± 1.03% | 8.15 ± 1.03% |
|
|
88
|
+
| Joi | 271 301.11 ± 1.58% | 3.69 ± 1.59% |
|
|
89
|
+
| @sinclair/typebox | 228 734.49 ± 0.55% | 4.37 ± 0.56% |
|
|
90
|
+
| ArkType | 258 685.33 ± 1.23% | 3.87 ± 1.23% |
|
|
91
|
+
| effect/Schema | 165 753.69 ± 0.99% | 6.03 ± 1.00% |
|
|
82
92
|
|
|
83
93
|
**Note:** During the performance tests, `@zod/mini` was observed to consume 200% CPU, while other libraries used only 100% CPU. This may affect the interpretation of the results, especially in multi-threaded environments.
|
|
84
94
|
|
|
@@ -134,8 +144,14 @@ console.log(result);
|
|
|
134
144
|
|
|
135
145
|
Creates a string schema. You can optionally pass `options` to customize error messages.
|
|
136
146
|
|
|
147
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
148
|
+
|
|
137
149
|
```typescript
|
|
138
150
|
const stringSchema = s.string({
|
|
151
|
+
message: 'This is a constant error message.',
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
const stringSchemaFunc = s.string({
|
|
139
155
|
message: (value) => `Custom error: "${value}" is not a valid string.`,
|
|
140
156
|
});
|
|
141
157
|
```
|
|
@@ -144,8 +160,14 @@ const stringSchema = s.string({
|
|
|
144
160
|
|
|
145
161
|
Creates a number schema. You can optionally pass `options` to customize error messages.
|
|
146
162
|
|
|
163
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
164
|
+
|
|
147
165
|
```typescript
|
|
148
166
|
const numberSchema = s.number({
|
|
167
|
+
message: 'This is a constant error message.',
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
const numberSchemaFunc = s.number({
|
|
149
171
|
message: (value) => `Custom error: "${value}" is not a valid number.`,
|
|
150
172
|
});
|
|
151
173
|
```
|
|
@@ -154,8 +176,14 @@ const numberSchema = s.number({
|
|
|
154
176
|
|
|
155
177
|
Creates a boolean schema. You can optionally pass `options` to customize error messages.
|
|
156
178
|
|
|
179
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
180
|
+
|
|
157
181
|
```typescript
|
|
158
182
|
const booleanSchema = s.boolean({
|
|
183
|
+
message: 'This is a constant error message.',
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
const booleanSchemaFunc = s.boolean({
|
|
159
187
|
message: (value) => `Custom error: "${value}" is not a valid boolean.`,
|
|
160
188
|
});
|
|
161
189
|
```
|
|
@@ -164,8 +192,14 @@ const booleanSchema = s.boolean({
|
|
|
164
192
|
|
|
165
193
|
Creates a date schema. You can optionally pass `options` to customize error messages.
|
|
166
194
|
|
|
195
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
196
|
+
|
|
167
197
|
```typescript
|
|
168
198
|
const dateSchema = s.date({
|
|
199
|
+
message: 'This is a constant error message.',
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
const dateSchemaFunc = s.date({
|
|
169
203
|
message: (value) => `Custom error: "${value}" is not a valid date.`,
|
|
170
204
|
});
|
|
171
205
|
```
|
|
@@ -174,8 +208,20 @@ const dateSchema = s.date({
|
|
|
174
208
|
|
|
175
209
|
Creates an object schema with the given definition. You can optionally pass `options` to customize error messages.
|
|
176
210
|
|
|
211
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
212
|
+
|
|
177
213
|
```typescript
|
|
178
214
|
const objectSchema = s.object(
|
|
215
|
+
{
|
|
216
|
+
key: s.string(),
|
|
217
|
+
value: s.number(),
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
message: 'This is a constant error message.',
|
|
221
|
+
},
|
|
222
|
+
);
|
|
223
|
+
|
|
224
|
+
const objectSchemaFunc = s.object(
|
|
179
225
|
{
|
|
180
226
|
key: s.string(),
|
|
181
227
|
value: s.number(),
|
|
@@ -190,8 +236,14 @@ const objectSchema = s.object(
|
|
|
190
236
|
|
|
191
237
|
Creates an array schema with the given item definition. You can optionally pass `options` to customize error messages.
|
|
192
238
|
|
|
239
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
240
|
+
|
|
193
241
|
```typescript
|
|
194
242
|
const arraySchema = s.array(s.string(), {
|
|
243
|
+
message: 'This is a constant error message.',
|
|
244
|
+
});
|
|
245
|
+
|
|
246
|
+
const arraySchemaFunc = s.array(s.string(), {
|
|
195
247
|
message: (value) => `Custom error: "${JSON.stringify(value)}" is not a valid array.`,
|
|
196
248
|
});
|
|
197
249
|
```
|
|
@@ -200,10 +252,14 @@ const arraySchema = s.array(s.string(), {
|
|
|
200
252
|
|
|
201
253
|
Creates an enum schema that validates against a predefined set of string values. You can optionally pass `options` to customize error messages.
|
|
202
254
|
|
|
203
|
-
- **`
|
|
255
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
204
256
|
|
|
205
257
|
```typescript
|
|
206
258
|
const enumSchema = s.enum(['admin', 'user', 'guest'], {
|
|
259
|
+
message: 'This is a constant error message.',
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const enumSchemaFunc = s.enum(['admin', 'user', 'guest'], {
|
|
207
263
|
message: (value) => `Custom error: "${value}" is not a valid enum value.`,
|
|
208
264
|
});
|
|
209
265
|
```
|
|
@@ -212,43 +268,24 @@ const enumSchema = s.enum(['admin', 'user', 'guest'], {
|
|
|
212
268
|
|
|
213
269
|
Creates a schema that validates against multiple schemas (a union of schemas). The value must match at least one of the provided schemas. You can optionally pass `options` to customize error messages.
|
|
214
270
|
|
|
215
|
-
- **`
|
|
271
|
+
- **`message`**: Can be either a constant string or a function `(value) => string`.
|
|
216
272
|
|
|
217
273
|
```typescript
|
|
218
274
|
const schema = s.union([
|
|
219
275
|
s.string(),
|
|
220
276
|
s.number(),
|
|
221
277
|
s.boolean(),
|
|
222
|
-
]
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
console.log(validString);
|
|
226
|
-
// 'hello'
|
|
227
|
-
|
|
228
|
-
const validNumber = schema.parse(42);
|
|
229
|
-
console.log(validNumber);
|
|
230
|
-
// 42
|
|
231
|
-
|
|
232
|
-
const validBoolean = schema.parse(true);
|
|
233
|
-
console.log(validBoolean);
|
|
234
|
-
// true
|
|
235
|
-
|
|
236
|
-
const invalidValue = schema.safeParse({ key: 'value' });
|
|
237
|
-
console.log(invalidValue.success);
|
|
238
|
-
// false
|
|
239
|
-
console.log(invalidValue.error.message);
|
|
240
|
-
// Validation failed. Expected the value to match one of the schemas: "string" | "number" | "boolean", but received "object" with value "{"key":"value"}".
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
**Use Case**: The `union` method is useful when you need to validate data that can be of multiple types, such as a value that can be a string, number, or boolean.
|
|
278
|
+
], {
|
|
279
|
+
message: 'This is a constant error message.',
|
|
280
|
+
});
|
|
244
281
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
}
|
|
251
|
-
);
|
|
282
|
+
const schemaFunc = s.union([
|
|
283
|
+
s.string(),
|
|
284
|
+
s.number(),
|
|
285
|
+
s.boolean(),
|
|
286
|
+
], {
|
|
287
|
+
message: (value) => `Custom error: "${value}" does not match any of the union schemas.`,
|
|
288
|
+
});
|
|
252
289
|
```
|
|
253
290
|
|
|
254
291
|
#### `s.any()`
|
package/dist/index.d.mts
CHANGED
|
@@ -24,9 +24,7 @@ interface SchemaInterface<Input, Output> {
|
|
|
24
24
|
nullish(): SchemaInterface<Input, Output | undefined | null>;
|
|
25
25
|
default(defaultValue: Partial<Input> | (() => Partial<Input>) | Partial<Output>): SchemaInterface<Input, Output>;
|
|
26
26
|
pipe<NewOutput>(schema: SchemaInterface<Output, NewOutput>): SchemaInterface<Output, NewOutput>;
|
|
27
|
-
refine(validation: (value: Output) => boolean,
|
|
28
|
-
message: ErrorMessage;
|
|
29
|
-
}): SchemaInterface<Input, Output>;
|
|
27
|
+
refine(validation: (value: Output) => boolean, options?: SchemaInterfaceOptions): SchemaInterface<Input, Output>;
|
|
30
28
|
}
|
|
31
29
|
interface UnionSchemaInterface<T extends Array<SchemaInterface<unknown, unknown>>> extends SchemaInterface<ReturnType<T[number]['parse']>, ReturnType<T[number]['parse']>> {
|
|
32
30
|
}
|
|
@@ -56,7 +54,7 @@ type ExtenderType = (inter: SchemaType, validation: Function, options?: {
|
|
|
56
54
|
}) => SchemaType;
|
|
57
55
|
interface CreateSchemaInterfaceOptions {
|
|
58
56
|
type?: string;
|
|
59
|
-
message?:
|
|
57
|
+
message?: ErrorMessage;
|
|
60
58
|
}
|
|
61
59
|
type SchemaInterfaceOptions = Omit<CreateSchemaInterfaceOptions, 'type'>;
|
|
62
60
|
declare const s: {
|
package/dist/index.d.ts
CHANGED
|
@@ -24,9 +24,7 @@ interface SchemaInterface<Input, Output> {
|
|
|
24
24
|
nullish(): SchemaInterface<Input, Output | undefined | null>;
|
|
25
25
|
default(defaultValue: Partial<Input> | (() => Partial<Input>) | Partial<Output>): SchemaInterface<Input, Output>;
|
|
26
26
|
pipe<NewOutput>(schema: SchemaInterface<Output, NewOutput>): SchemaInterface<Output, NewOutput>;
|
|
27
|
-
refine(validation: (value: Output) => boolean,
|
|
28
|
-
message: ErrorMessage;
|
|
29
|
-
}): SchemaInterface<Input, Output>;
|
|
27
|
+
refine(validation: (value: Output) => boolean, options?: SchemaInterfaceOptions): SchemaInterface<Input, Output>;
|
|
30
28
|
}
|
|
31
29
|
interface UnionSchemaInterface<T extends Array<SchemaInterface<unknown, unknown>>> extends SchemaInterface<ReturnType<T[number]['parse']>, ReturnType<T[number]['parse']>> {
|
|
32
30
|
}
|
|
@@ -56,7 +54,7 @@ type ExtenderType = (inter: SchemaType, validation: Function, options?: {
|
|
|
56
54
|
}) => SchemaType;
|
|
57
55
|
interface CreateSchemaInterfaceOptions {
|
|
58
56
|
type?: string;
|
|
59
|
-
message?:
|
|
57
|
+
message?: ErrorMessage;
|
|
60
58
|
}
|
|
61
59
|
type SchemaInterfaceOptions = Omit<CreateSchemaInterfaceOptions, 'type'>;
|
|
62
60
|
declare const s: {
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
'use strict';var h=e=>typeof e=="string"||e instanceof String,I=e=>typeof e=="number"||e instanceof Number,
|
|
1
|
+
'use strict';var h=e=>typeof e=="string"||e instanceof String,I=e=>typeof e=="number"||e instanceof Number,y=e=>e===true||e===false,l=e=>e instanceof Date&&!Number.isNaN(e.getTime()),S=e=>Array.isArray(e),d=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),b={object(e,c){let s=f(d,{...c,type:"object"});return i(s,"_parse",(u,...o)=>{let n=u(...o);if(n.success===false)return n;let t={};for(let r in e){let a=e[r]._parse(n.data[r]);if(a.success)t[r]=a.data;else {a=a;let p=a?.error?.cause?.key?`${r}.${a?.error?.cause?.key}`:r;return a.error.message=`Error parsing key "${p}": ${a.error.message}`,a.error.cause={key:p},a}}return {success:true,data:t}}),s},string(e){return f(h,{...e,type:"string"})},number(e){return f(I,{...e,type:"number"})},boolean(e){return f(y,{...e,type:"boolean"})},date(e){return f(l,{...e,type:"date"})},enum(e,c){let s=t=>e.includes(t),u=t=>`Invalid ${o} value. Expected ${e.map(r=>`"${r}"`).join(" | ")}, received "${t}".`,o="enum";return f(s,{message:u,...c,type:o})},array(e,c){let s=f(S,{...c,type:"array"});return i(s,"_parse",(u,...o)=>{let n=u(...o);if(n.success===false)return n;let t=[];for(let r=0;r<n.data.length;r++){let a=e._parse(n.data[r]);if(a.success)t.push(a.data);else {a=a;let p=a.error?.cause?.key?`${r}.${a.error.cause.key}`:`${r}`;return a.error.message=`Error parsing index "${r}": ${a.error.message}`,a.error.cause={key:p},a}}return {success:true,data:t}}),s},any(){return f(()=>true)},preprocess(e,c){return i(c,"_parse",(s,u)=>(u=e(u),s(u))),c},union(e,c){return f(n=>{for(let t=0;t<e.length;t++)if(e[t]._parse(n).success)return true;return false},{message:n=>`Invalid union value. Expected the value to match one of the schemas: ${e.map(t=>`"${t._getType()}"`).join(" | ")}, but received "${typeof n}" with value "${n}".`,...c,type:"union"})}};function T(e){return c=>`The value "${c}" must be type of ${e} but is type of "${typeof c}".`}function i(e,c,s){let u=e[c];e[c]=(...o)=>s(u,...o);}function f(e,{type:c="any",message:s}={}){s=s||T(c);let u={message:s,type:c},o={_getType(){return c},_parse(n){return e(n)?{success:true,data:n}:{success:false,error:{message:typeof s=="function"?s(n):s}}},parse(n){let t=o._parse(n);if(!t.success)throw t=t,new Error(t.error.message,{cause:t.error.cause});return t.data},safeParse(n){return o._parse(n)},transform(n){return i(this,"_parse",(t,r)=>{let a=t(r);return a.success&&(a.data=n(a.data)),a}),this},optional(){return i(this,"_parse",(n,t)=>{let r=n(t);return r.success||(r.data=void 0,r.success=true),r}),this},nullable(){return i(this,"_parse",(n,t)=>{let r=n(t);return r.success||(r.data=null,r.success=true),r}),this},nullish(){return i(this,"_parse",(n,t)=>{let r=n(t);return !r.success&&t==null&&(r.success=true,r.data=t),r}),this},default(n){return i(this,"_parse",(t,r)=>(r===void 0&&(r=n,r=typeof n=="function"?n():n),t(r))),this},pipe(n){return i(this,"_parse",(t,r)=>{let a=t(r);return a.success?n._parse(a.data):a}),this},refine(n,{message:t}={}){return i(this,"_parse",(r,a)=>{let p=r(a);return p.success?n(p.data)?p:{success:false,error:{message:typeof t=="function"?t(a):t}}:p}),this}};return m.length>0?m.reduce((n,t)=>t(n,e,u)??n,o):o}var m=[];function g(e){m.push(e);}exports.extend=g;exports.s=b;
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var h=e=>typeof e=="string"||e instanceof String,I=e=>typeof e=="number"||e instanceof Number,
|
|
1
|
+
var h=e=>typeof e=="string"||e instanceof String,I=e=>typeof e=="number"||e instanceof Number,y=e=>e===true||e===false,l=e=>e instanceof Date&&!Number.isNaN(e.getTime()),S=e=>Array.isArray(e),d=e=>typeof e=="object"&&e!==null&&!Array.isArray(e),b={object(e,c){let s=f(d,{...c,type:"object"});return i(s,"_parse",(u,...o)=>{let n=u(...o);if(n.success===false)return n;let t={};for(let r in e){let a=e[r]._parse(n.data[r]);if(a.success)t[r]=a.data;else {a=a;let p=a?.error?.cause?.key?`${r}.${a?.error?.cause?.key}`:r;return a.error.message=`Error parsing key "${p}": ${a.error.message}`,a.error.cause={key:p},a}}return {success:true,data:t}}),s},string(e){return f(h,{...e,type:"string"})},number(e){return f(I,{...e,type:"number"})},boolean(e){return f(y,{...e,type:"boolean"})},date(e){return f(l,{...e,type:"date"})},enum(e,c){let s=t=>e.includes(t),u=t=>`Invalid ${o} value. Expected ${e.map(r=>`"${r}"`).join(" | ")}, received "${t}".`,o="enum";return f(s,{message:u,...c,type:o})},array(e,c){let s=f(S,{...c,type:"array"});return i(s,"_parse",(u,...o)=>{let n=u(...o);if(n.success===false)return n;let t=[];for(let r=0;r<n.data.length;r++){let a=e._parse(n.data[r]);if(a.success)t.push(a.data);else {a=a;let p=a.error?.cause?.key?`${r}.${a.error.cause.key}`:`${r}`;return a.error.message=`Error parsing index "${r}": ${a.error.message}`,a.error.cause={key:p},a}}return {success:true,data:t}}),s},any(){return f(()=>true)},preprocess(e,c){return i(c,"_parse",(s,u)=>(u=e(u),s(u))),c},union(e,c){return f(n=>{for(let t=0;t<e.length;t++)if(e[t]._parse(n).success)return true;return false},{message:n=>`Invalid union value. Expected the value to match one of the schemas: ${e.map(t=>`"${t._getType()}"`).join(" | ")}, but received "${typeof n}" with value "${n}".`,...c,type:"union"})}};function T(e){return c=>`The value "${c}" must be type of ${e} but is type of "${typeof c}".`}function i(e,c,s){let u=e[c];e[c]=(...o)=>s(u,...o);}function f(e,{type:c="any",message:s}={}){s=s||T(c);let u={message:s,type:c},o={_getType(){return c},_parse(n){return e(n)?{success:true,data:n}:{success:false,error:{message:typeof s=="function"?s(n):s}}},parse(n){let t=o._parse(n);if(!t.success)throw t=t,new Error(t.error.message,{cause:t.error.cause});return t.data},safeParse(n){return o._parse(n)},transform(n){return i(this,"_parse",(t,r)=>{let a=t(r);return a.success&&(a.data=n(a.data)),a}),this},optional(){return i(this,"_parse",(n,t)=>{let r=n(t);return r.success||(r.data=void 0,r.success=true),r}),this},nullable(){return i(this,"_parse",(n,t)=>{let r=n(t);return r.success||(r.data=null,r.success=true),r}),this},nullish(){return i(this,"_parse",(n,t)=>{let r=n(t);return !r.success&&t==null&&(r.success=true,r.data=t),r}),this},default(n){return i(this,"_parse",(t,r)=>(r===void 0&&(r=n,r=typeof n=="function"?n():n),t(r))),this},pipe(n){return i(this,"_parse",(t,r)=>{let a=t(r);return a.success?n._parse(a.data):a}),this},refine(n,{message:t}={}){return i(this,"_parse",(r,a)=>{let p=r(a);return p.success?n(p.data)?p:{success:false,error:{message:typeof t=="function"?t(a):t}}:p}),this}};return m.length>0?m.reduce((n,t)=>t(n,e,u)??n,o):o}var m=[];function g(e){m.push(e);}export{g as extend,b as s};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@esmj/schema",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.5",
|
|
4
4
|
"description": "Tiny extendable package for schema validation.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"schema",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"lint": "biome check --no-errors-on-unmatched",
|
|
24
24
|
"lint:fix": "npm run lint -- --fix --unsafe",
|
|
25
|
-
"benchmark": "node benchmark/benchmark.ts",
|
|
25
|
+
"benchmark": "node --expose-gc benchmark/benchmark.ts",
|
|
26
26
|
"dev": "node_modules/.bin/tsup --dts --watch --onSuccess 'node ./dist/index.mjs'",
|
|
27
27
|
"test": "node --test --experimental-strip-types",
|
|
28
28
|
"test:watch": "npm run test -- --watch",
|
|
@@ -65,6 +65,7 @@
|
|
|
65
65
|
"@biomejs/biome": "1.9.4",
|
|
66
66
|
"@commitlint/cli": "^19.8.1",
|
|
67
67
|
"@commitlint/config-conventional": "^19.8.1",
|
|
68
|
+
"@sinclair/typebox": "^0.34.38",
|
|
68
69
|
"@typescript-eslint/eslint-plugin": "^8.33.0",
|
|
69
70
|
"@typescript-eslint/parser": "^8.33.0",
|
|
70
71
|
"@zod/mini": "^4.0.0-beta.0",
|
|
@@ -72,6 +73,7 @@
|
|
|
72
73
|
"commitizen": "^4.3.1",
|
|
73
74
|
"conventional-changelog-cli": "^5.0.0",
|
|
74
75
|
"cz-conventional-changelog": "^3.3.0",
|
|
76
|
+
"effect": "^3.17.6",
|
|
75
77
|
"git-cz": "^4.9.0",
|
|
76
78
|
"husky": "^9.1.7",
|
|
77
79
|
"joi": "^17.13.3",
|