@esmj/schema 0.0.2 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Schema
2
2
 
3
- This small library provides a simple schema validation system for JavaScript/TypeScript. The library has basic types with opportunity for extending.
3
+ This small library provides a simple schema validation system for JavaScript/TypeScript. The library has basic types with opportunities for extending.
4
4
 
5
5
  ## Installation
6
6
 
@@ -8,17 +8,31 @@ This small library provides a simple schema validation system for JavaScript/Typ
8
8
  npm install @esmj/schema
9
9
  ```
10
10
 
11
+ ## Why Use `@esmj/schema`?
12
+
13
+ `@esmj/schema` is a lightweight and flexible schema validation library designed for developers who need a simple yet powerful way to validate and transform data. Here are some reasons to choose this package:
14
+
15
+ 1. **TypeScript First**: Built with TypeScript in mind, it provides strong type inference and ensures type safety throughout your codebase.
16
+ 2. **Extensibility**: Easily extend the library with custom logic using the `extend` function.
17
+ 3. **Rich Features**: Includes advanced features like preprocessing, transformations, piping, and refinements, which are not always available in similar libraries.
18
+ 4. **Lightweight**: None dependencies and a small footprint make it ideal for projects where performance and simplicity are key.
19
+ 5. **Customizable**: Offers fine-grained control over validation and error handling.
20
+
11
21
  ## Usage
12
22
 
13
23
  ### Basic Usage
14
24
 
15
25
  ```typescript
16
- import { s } from '@esmj/schema';
26
+ import { s, type Infer} from '@esmj/schema';
17
27
 
18
28
  const schema = s.object({
19
- username: s.string().optional(),
29
+ username: s.string().optional().refine((val) => val.length <= 255, {
30
+ message: "Username can't be more than 255 characters",
31
+ }),
20
32
  password: s.string().default('unknown'),
21
- account: s.number().default(0),
33
+ birthday: s.preprocess((value) => new Date(value), s.date()),
34
+ account: s.string().default('0').transform((value) => Number.parseInt(value)).pipe(s.number()),
35
+ money: s.number(),
22
36
  address: s.object({
23
37
  street: s.string(),
24
38
  city: s.string().optional(),
@@ -26,12 +40,28 @@ const schema = s.object({
26
40
  records: s.array(s.object({ name: s.string() })).default([]),
27
41
  });
28
42
 
43
+ type schemaType = Infer<typeof schema>;
44
+
29
45
  const result = schema.parse({
30
46
  username: 'john_doe',
47
+ birthday: '2000-01-01T23:59:59.000Z',
31
48
  address: { city: 'New York' },
49
+ money: 100,
32
50
  });
33
51
 
34
52
  console.log(result);
53
+ // {
54
+ // username: 'john_doe',
55
+ // password: 'unknown',
56
+ // birthday: Date('2000-01-01T23:59:59.000Z'),
57
+ // account: 0,
58
+ // money: 100,
59
+ // address: {
60
+ // street: 'unknown',
61
+ // city: 'New York',
62
+ // },
63
+ // records: [],
64
+ // }
35
65
  ```
36
66
 
37
67
  ### Schema Types
@@ -60,6 +90,14 @@ Creates a boolean schema.
60
90
  const booleanSchema = s.boolean();
61
91
  ```
62
92
 
93
+ #### `s.date()`
94
+
95
+ Creates a date schema.
96
+
97
+ ```typescript
98
+ const dateSchema = s.date();
99
+ ```
100
+
63
101
  #### `s.object(definition)`
64
102
 
65
103
  Creates an object schema with the given definition.
@@ -87,6 +125,14 @@ Creates a schema that accepts any value.
87
125
  const anySchema = s.any();
88
126
  ```
89
127
 
128
+ #### `s.preprocess(callback, schema)`
129
+
130
+ Creates a schema that preprocesses the input value using the provided callback before validating it with the given schema.
131
+
132
+ ```typescript
133
+ const preprocessSchema = s.preprocess((value) => new Date(value), s.date());
134
+ ```
135
+
90
136
  ### Schema Methods
91
137
 
92
138
  #### `parse(value)`
@@ -102,10 +148,7 @@ const result = stringSchema.parse('hello');
102
148
  Safely parses the given value according to the schema, returning a success or error result.
103
149
 
104
150
  ```typescript
105
- // correct
106
- const result = stringSchema.safeParse('hello'); // { success: true, data: 'hello' };
107
- // bad
108
- const result = stringSchema.safeParse('hello'); // { success: false, error: new Error() };
151
+ const result = stringSchema.safeParse('hello'); // { success: true, data: 'hello' }
109
152
  ```
110
153
 
111
154
  #### `optional()`
@@ -140,22 +183,220 @@ Sets a default value for the schema.
140
183
  const defaultSchema = stringSchema.default('default value');
141
184
  ```
142
185
 
186
+ #### `transform(callback)`
187
+
188
+ Transforms the parsed value using the provided callback.
189
+
190
+ ```typescript
191
+ const transformedSchema = s.string().transform((value) => value.toUpperCase());
192
+ ```
193
+
194
+ #### `pipe(schema)`
195
+
196
+ Pipes the output of one schema into another schema for further validation or transformation.
197
+
198
+ ```typescript
199
+ const pipedSchema = s.string().pipe(s.number());
200
+ ```
201
+
202
+ #### `refine(validation, { message })`
203
+
204
+ Adds a refinement to the schema with a custom validation function and error message.
205
+
206
+ ```typescript
207
+ const refinedSchema = s.string().refine((val) => val.length <= 255, {
208
+ message: "String can't be more than 255 characters",
209
+ });
210
+ ```
211
+
143
212
  ### Extending Schemas
144
213
 
145
214
  You can extend the schema system with custom logic.
146
215
 
147
216
  ```typescript
148
- import { extend } from '@esmj/schema';
217
+ import { extend, type StringSchemaInterface } from '@esmj/schema';
218
+
219
+ interface StringSchemaInterface {
220
+ customMethod(value: string): string {}
221
+ }
149
222
 
150
223
  extend((schema, validation, options) => {
151
- schema.customMethod = () => {
224
+ schema.customMethod = (value) => {
152
225
  // Custom logic
226
+
227
+ return value;
153
228
  };
154
229
 
155
230
  return schema;
156
231
  });
157
232
  ```
158
233
 
234
+ ### More Examples
235
+
236
+ #### Nested Objects
237
+
238
+ You can define schemas for deeply nested objects.
239
+
240
+ ```typescript
241
+ const nestedSchema = s.object({
242
+ user: s.object({
243
+ id: s.number(),
244
+ profile: s.object({
245
+ name: s.string(),
246
+ age: s.number().optional(),
247
+ }),
248
+ }),
249
+ });
250
+
251
+ const result = nestedSchema.parse({
252
+ user: {
253
+ id: 1,
254
+ profile: {
255
+ name: 'John Doe',
256
+ },
257
+ },
258
+ });
259
+
260
+ console.log(result);
261
+ // {
262
+ // user: {
263
+ // id: 1,
264
+ // profile: {
265
+ // name: 'John Doe',
266
+ // },
267
+ // },
268
+ // }
269
+ ```
270
+
271
+ #### Arrays with Validation
272
+
273
+ You can validate arrays with specific item schemas.
274
+
275
+ ```typescript
276
+ const arraySchema = s.array(s.object({ id: s.number(), name: s.string() }));
277
+
278
+ const result = arraySchema.parse([
279
+ { id: 1, name: 'Item 1' },
280
+ { id: 2, name: 'Item 2' },
281
+ ]);
282
+
283
+ console.log(result);
284
+ // [
285
+ // { id: 1, name: 'Item 1' },
286
+ // { id: 2, name: 'Item 2' },
287
+ // ]
288
+ ```
289
+
290
+ #### Preprocessing Values
291
+
292
+ Use `s.preprocess` to transform input values before validation.
293
+
294
+ ```typescript
295
+ const preprocessSchema = s.preprocess(
296
+ (value) => value.trim(),
297
+ s.string().refine((val) => val.length > 0, { message: 'String cannot be empty' }),
298
+ );
299
+
300
+ const result = preprocessSchema.parse(' hello ');
301
+
302
+ console.log(result);
303
+ // 'hello'
304
+ ```
305
+
306
+ #### Transforming Values
307
+
308
+ Use `transform` to modify the parsed value.
309
+
310
+ ```typescript
311
+ const transformSchema = s.string().transform((value) => value.toUpperCase());
312
+
313
+ const result = transformSchema.parse('hello');
314
+
315
+ console.log(result);
316
+ // 'HELLO'
317
+ ```
318
+
319
+ #### Piping Schemas
320
+
321
+ Pipe the output of one schema into another for further validation or transformation.
322
+
323
+ ```typescript
324
+ const pipedSchema = s.string()
325
+ .transform((value) => Number.parseInt(value))
326
+ .pipe(s.number().refine((val) => val > 0, { message: 'Number must be positive' }));
327
+
328
+ const result = pipedSchema.parse('42');
329
+
330
+ console.log(result);
331
+ // 42
332
+ ```
333
+
334
+ #### Refining Values
335
+
336
+ Add custom validation logic with `refine`.
337
+
338
+ ```typescript
339
+ const refinedSchema = s.string().refine((val) => val.startsWith('A'), {
340
+ message: 'String must start with "A"',
341
+ });
342
+
343
+ const result = refinedSchema.parse('Apple');
344
+
345
+ console.log(result);
346
+ // 'Apple'
347
+ ```
348
+
349
+ #### Default Values
350
+
351
+ Set default values for optional fields.
352
+
353
+ ```typescript
354
+ const defaultSchema = s.object({
355
+ name: s.string().default('Anonymous'),
356
+ age: s.number().optional().default(18),
357
+ });
358
+
359
+ const result = defaultSchema.parse({});
360
+
361
+ console.log(result);
362
+ // { name: 'Anonymous', age: 18 }
363
+ ```
364
+
365
+ #### Safe Parsing
366
+
367
+ Use `safeParse` to handle errors gracefully.
368
+
369
+ ```typescript
370
+ const safeSchema = s.number();
371
+
372
+ const result = safeSchema.safeParse('not a number');
373
+
374
+ if (!result.success) {
375
+ console.error(result.error.message);
376
+ } else {
377
+ console.log(result.data);
378
+ }
379
+ // Error: The value "not a number" must be type of number but is type of "string".
380
+ ```
381
+
382
+ #### Combining Multiple Features
383
+
384
+ Combine multiple features like preprocessing, transformations, and refinements.
385
+
386
+ ```typescript
387
+ const combinedSchema = s.preprocess(
388
+ (value) => value.trim(),
389
+ s.string()
390
+ .transform((value) => value.toUpperCase())
391
+ .refine((val) => val.length <= 10, { message: 'String must be at most 10 characters' }),
392
+ );
393
+
394
+ const result = combinedSchema.parse(' hello ');
395
+
396
+ console.log(result);
397
+ // 'HELLO'
398
+ ```
399
+
159
400
  ## License
160
401
 
161
402
  MIT
package/dist/index.d.mts CHANGED
@@ -8,19 +8,47 @@ interface SchemaInterface<Input, Output> {
8
8
  error: Error;
9
9
  };
10
10
  optional(): SchemaInterface<Input, Partial<Output> | undefined>;
11
+ transform<NewOutput>(callback: (value: Input) => NewOutput): SchemaInterface<Input, NewOutput>;
11
12
  nullable(): SchemaInterface<Input, Output | null>;
12
13
  nullish(): SchemaInterface<Input, Output | undefined | null>;
13
14
  default(defaultValue: Partial<Input> | (() => Partial<Input>) | Partial<Output>): SchemaInterface<Input, Output>;
15
+ pipe<NewOutput>(schema: SchemaInterface<Output, NewOutput>): SchemaInterface<Output, NewOutput>;
16
+ refine(validation: (value: Output) => boolean, { message }: {
17
+ message: string;
18
+ }): SchemaInterface<Input, Output>;
14
19
  }
15
- type SchemaType = SchemaInterface<string, string> | SchemaInterface<string, string | undefined> | SchemaInterface<string, string | null> | SchemaInterface<string, string | undefined | null> | SchemaInterface<object, object> | SchemaInterface<object, object | undefined> | SchemaInterface<object, object | null> | SchemaInterface<object, object | undefined | null> | SchemaInterface<number, number> | SchemaInterface<number, number | undefined> | SchemaInterface<number, number | null> | SchemaInterface<number, number | undefined | null> | SchemaInterface<boolean, boolean> | SchemaInterface<boolean, boolean | undefined> | SchemaInterface<boolean, boolean | null> | SchemaInterface<boolean, boolean | undefined | null> | SchemaInterface<Array<unknown>, Array<unknown>> | SchemaInterface<Array<unknown>, Array<unknown> | undefined> | SchemaInterface<Array<unknown>, Array<unknown> | null> | SchemaInterface<Array<unknown>, Array<unknown> | undefined | null>;
20
+ interface StringSchemaInterface extends SchemaInterface<string, string> {
21
+ }
22
+ interface NumberSchemaInterface extends SchemaInterface<number, number> {
23
+ }
24
+ interface BooleanSchemaInterface extends SchemaInterface<boolean, boolean> {
25
+ }
26
+ interface DateSchemaInterface extends SchemaInterface<Date, Date> {
27
+ }
28
+ interface ArraySchemaInterface<T extends SchemaType> extends SchemaInterface<Array<T>, Array<ReturnType<T['parse']>>> {
29
+ }
30
+ interface ObjectSchemaInterface<T extends Record<string, SchemaType>> extends SchemaInterface<{
31
+ [Property in keyof T]: T[Property];
32
+ }, {
33
+ [Property in keyof T]: ReturnType<T[Property]['parse']>;
34
+ }> {
35
+ }
36
+ type SchemaType = StringSchemaInterface | SchemaInterface<string, string> | SchemaInterface<string, string | undefined> | SchemaInterface<string, string | null> | SchemaInterface<string, string | undefined | null> | ObjectSchemaInterface<Record<string, SchemaType>> | SchemaInterface<object, object> | SchemaInterface<object, object | undefined> | SchemaInterface<object, object | null> | SchemaInterface<object, object | undefined | null> | NumberSchemaInterface | SchemaInterface<number, number> | SchemaInterface<number, number | undefined> | SchemaInterface<number, number | null> | SchemaInterface<number, number | undefined | null> | BooleanSchemaInterface | SchemaInterface<boolean, boolean> | SchemaInterface<boolean, boolean | undefined> | SchemaInterface<boolean, boolean | null> | SchemaInterface<boolean, boolean | undefined | null> | DateSchemaInterface | SchemaInterface<Date, Date> | SchemaInterface<Date, Date | undefined> | SchemaInterface<Date, Date | null> | SchemaInterface<Date, Date | undefined | null> | ArraySchemaInterface<StringSchemaInterface | ObjectSchemaInterface<Record<string, SchemaType>> | NumberSchemaInterface | BooleanSchemaInterface> | SchemaInterface<Array<unknown>, Array<unknown>> | SchemaInterface<Array<unknown>, Array<unknown> | undefined> | SchemaInterface<Array<unknown>, Array<unknown> | null> | SchemaInterface<Array<unknown>, Array<unknown> | undefined | null>;
37
+ type ExtenderType = (inter: SchemaType, validation: Function, options: {
38
+ message: string;
39
+ type: string;
40
+ }) => SchemaType;
16
41
  declare const s: {
17
- object<T extends Record<string, SchemaType>>(definition: { [Property in keyof T]: T[Property]; }): SchemaInterface<{ [Property in keyof T]: T[Property]; }, { [Property in keyof T]: ReturnType<T[Property]["parse"]>; }>;
18
- string(): SchemaInterface<string, string>;
19
- number(): SchemaInterface<number, number>;
20
- boolean(): SchemaInterface<boolean, boolean>;
21
- array<T extends SchemaType>(definition: T): SchemaInterface<Array<T>, Array<ReturnType<T["parse"]>>>;
42
+ object<T extends Record<string, SchemaType>>(definition: { [Property in keyof T]: T[Property]; }): ObjectSchemaInterface<T>;
43
+ string(): StringSchemaInterface;
44
+ number(): NumberSchemaInterface;
45
+ boolean(): BooleanSchemaInterface;
46
+ date(): DateSchemaInterface;
47
+ array<T extends SchemaType>(definition: T): ArraySchemaInterface<T>;
22
48
  any(): any;
49
+ preprocess<T extends SchemaType>(callback: Function, schema: T): T;
23
50
  };
24
- declare function extend(callback: Function): void;
51
+ declare function extend(callback: ExtenderType): void;
52
+ type Infer<T> = T extends SchemaType ? ReturnType<T['parse']> : unknown;
25
53
 
26
- export { type SchemaInterface, type SchemaType, extend, s };
54
+ export { type ArraySchemaInterface, type BooleanSchemaInterface, type DateSchemaInterface, type ExtenderType, type Infer, type NumberSchemaInterface, type ObjectSchemaInterface, type SchemaInterface, type SchemaType, type StringSchemaInterface, extend, s };
package/dist/index.d.ts CHANGED
@@ -8,19 +8,47 @@ interface SchemaInterface<Input, Output> {
8
8
  error: Error;
9
9
  };
10
10
  optional(): SchemaInterface<Input, Partial<Output> | undefined>;
11
+ transform<NewOutput>(callback: (value: Input) => NewOutput): SchemaInterface<Input, NewOutput>;
11
12
  nullable(): SchemaInterface<Input, Output | null>;
12
13
  nullish(): SchemaInterface<Input, Output | undefined | null>;
13
14
  default(defaultValue: Partial<Input> | (() => Partial<Input>) | Partial<Output>): SchemaInterface<Input, Output>;
15
+ pipe<NewOutput>(schema: SchemaInterface<Output, NewOutput>): SchemaInterface<Output, NewOutput>;
16
+ refine(validation: (value: Output) => boolean, { message }: {
17
+ message: string;
18
+ }): SchemaInterface<Input, Output>;
14
19
  }
15
- type SchemaType = SchemaInterface<string, string> | SchemaInterface<string, string | undefined> | SchemaInterface<string, string | null> | SchemaInterface<string, string | undefined | null> | SchemaInterface<object, object> | SchemaInterface<object, object | undefined> | SchemaInterface<object, object | null> | SchemaInterface<object, object | undefined | null> | SchemaInterface<number, number> | SchemaInterface<number, number | undefined> | SchemaInterface<number, number | null> | SchemaInterface<number, number | undefined | null> | SchemaInterface<boolean, boolean> | SchemaInterface<boolean, boolean | undefined> | SchemaInterface<boolean, boolean | null> | SchemaInterface<boolean, boolean | undefined | null> | SchemaInterface<Array<unknown>, Array<unknown>> | SchemaInterface<Array<unknown>, Array<unknown> | undefined> | SchemaInterface<Array<unknown>, Array<unknown> | null> | SchemaInterface<Array<unknown>, Array<unknown> | undefined | null>;
20
+ interface StringSchemaInterface extends SchemaInterface<string, string> {
21
+ }
22
+ interface NumberSchemaInterface extends SchemaInterface<number, number> {
23
+ }
24
+ interface BooleanSchemaInterface extends SchemaInterface<boolean, boolean> {
25
+ }
26
+ interface DateSchemaInterface extends SchemaInterface<Date, Date> {
27
+ }
28
+ interface ArraySchemaInterface<T extends SchemaType> extends SchemaInterface<Array<T>, Array<ReturnType<T['parse']>>> {
29
+ }
30
+ interface ObjectSchemaInterface<T extends Record<string, SchemaType>> extends SchemaInterface<{
31
+ [Property in keyof T]: T[Property];
32
+ }, {
33
+ [Property in keyof T]: ReturnType<T[Property]['parse']>;
34
+ }> {
35
+ }
36
+ type SchemaType = StringSchemaInterface | SchemaInterface<string, string> | SchemaInterface<string, string | undefined> | SchemaInterface<string, string | null> | SchemaInterface<string, string | undefined | null> | ObjectSchemaInterface<Record<string, SchemaType>> | SchemaInterface<object, object> | SchemaInterface<object, object | undefined> | SchemaInterface<object, object | null> | SchemaInterface<object, object | undefined | null> | NumberSchemaInterface | SchemaInterface<number, number> | SchemaInterface<number, number | undefined> | SchemaInterface<number, number | null> | SchemaInterface<number, number | undefined | null> | BooleanSchemaInterface | SchemaInterface<boolean, boolean> | SchemaInterface<boolean, boolean | undefined> | SchemaInterface<boolean, boolean | null> | SchemaInterface<boolean, boolean | undefined | null> | DateSchemaInterface | SchemaInterface<Date, Date> | SchemaInterface<Date, Date | undefined> | SchemaInterface<Date, Date | null> | SchemaInterface<Date, Date | undefined | null> | ArraySchemaInterface<StringSchemaInterface | ObjectSchemaInterface<Record<string, SchemaType>> | NumberSchemaInterface | BooleanSchemaInterface> | SchemaInterface<Array<unknown>, Array<unknown>> | SchemaInterface<Array<unknown>, Array<unknown> | undefined> | SchemaInterface<Array<unknown>, Array<unknown> | null> | SchemaInterface<Array<unknown>, Array<unknown> | undefined | null>;
37
+ type ExtenderType = (inter: SchemaType, validation: Function, options: {
38
+ message: string;
39
+ type: string;
40
+ }) => SchemaType;
16
41
  declare const s: {
17
- object<T extends Record<string, SchemaType>>(definition: { [Property in keyof T]: T[Property]; }): SchemaInterface<{ [Property in keyof T]: T[Property]; }, { [Property in keyof T]: ReturnType<T[Property]["parse"]>; }>;
18
- string(): SchemaInterface<string, string>;
19
- number(): SchemaInterface<number, number>;
20
- boolean(): SchemaInterface<boolean, boolean>;
21
- array<T extends SchemaType>(definition: T): SchemaInterface<Array<T>, Array<ReturnType<T["parse"]>>>;
42
+ object<T extends Record<string, SchemaType>>(definition: { [Property in keyof T]: T[Property]; }): ObjectSchemaInterface<T>;
43
+ string(): StringSchemaInterface;
44
+ number(): NumberSchemaInterface;
45
+ boolean(): BooleanSchemaInterface;
46
+ date(): DateSchemaInterface;
47
+ array<T extends SchemaType>(definition: T): ArraySchemaInterface<T>;
22
48
  any(): any;
49
+ preprocess<T extends SchemaType>(callback: Function, schema: T): T;
23
50
  };
24
- declare function extend(callback: Function): void;
51
+ declare function extend(callback: ExtenderType): void;
52
+ type Infer<T> = T extends SchemaType ? ReturnType<T['parse']> : unknown;
25
53
 
26
- export { type SchemaInterface, type SchemaType, extend, s };
54
+ export { type ArraySchemaInterface, type BooleanSchemaInterface, type DateSchemaInterface, type ExtenderType, type Infer, type NumberSchemaInterface, type ObjectSchemaInterface, type SchemaInterface, type SchemaType, type StringSchemaInterface, extend, s };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- 'use strict';var l={object(t){let c=s(u=>typeof u=="object"&&u!==null&&!Array.isArray(u),{type:"object"});return i(c,"parse",(u,...o)=>{let e=u(...o);return t&&typeof e=="object"?Object.keys(t).reduce((n,r)=>{if(typeof t[r]?.parse=="function")try{n[r]=t[r].parse(e[r]);}catch(p){throw r=p.cause?.key?`${r}.${p.cause.key}`:r,new Error(`Error parsing key "${r}": ${p.message}`,{cause:{key:r}})}return n},{}):e}),c},string(){return s(a=>typeof a=="string",{type:"string"})},number(){return s(a=>typeof a=="number",{type:"number"})},boolean(){return s(a=>a===true||a===false,{type:"boolean"})},array(t){let c=s(u=>Array.isArray(u),{type:"array"});return i(c,"parse",(u,o)=>(o=u(o),t&&Array.isArray(o)?o.map((e,n)=>{try{return t.parse(e)}catch(r){let p=r.cause?.key?`${n}.${r.cause.key}`:n;throw new Error(`Error parsing index "${n}": ${r.message}`,{cause:{key:p}})}}):o)),c},any(){return s(()=>true)}};function y(t){return a=>`The value "${a}" must be type of ${t} but is type of "${typeof a}".`}function i(t,a,c){let u=t[a];t[a]=(...o)=>c(u,...o);}function s(t,{type:a="any"}={}){let c=y(a),u={message:c,type:a},o={parse(e){if(!t(e))throw new Error(c(e));return e},safeParse(e){try{return {success:!0,data:this.parse(e)}}catch(n){return {success:false,error:n}}},optional(){return i(this,"parse",(e,n)=>{try{return e(n)}catch{return}}),this},nullable(){return i(this,"parse",(e,n)=>{try{return e(n)}catch{return null}}),this},nullish(){return i(this,"parse",(e,n)=>{try{return e(n)}catch{return n==null?n:null}}),this},default(e){return i(this,"parse",(n,r)=>(r===void 0&&(r=e,r=typeof e=="function"?e():e),r=n(r),r)),this}};return f.reduce((e,n)=>n(e,t,u)??e,o)}var f=[];function h(t){f.push(t);}exports.extend=h;exports.s=l;
1
+ 'use strict';var y={object(n){let u=i(c=>typeof c=="object"&&c!==null&&!Array.isArray(c),{type:"object"});return s(u,"parse",(c,...o)=>{let e=c(...o);return n&&typeof e=="object"?Object.keys(n).reduce((t,r)=>{if(typeof n[r]?.parse=="function")try{t[r]=n[r].parse(e[r]);}catch(p){throw r=p.cause?.key?`${r}.${p.cause.key}`:r,new Error(`Error parsing key "${r}": ${p.message}`,{cause:{key:r}})}return t},{}):e}),u},string(){return i(a=>typeof a=="string",{type:"string"})},number(){return i(a=>typeof a=="number",{type:"number"})},boolean(){return i(a=>a===true||a===false,{type:"boolean"})},date(){return i(a=>a instanceof Date&&!Number.isNaN(a.getTime()),{type:"date"})},array(n){let u=i(c=>Array.isArray(c),{type:"array"});return s(u,"parse",(c,o)=>(o=c(o),n&&Array.isArray(o)?o.map((e,t)=>{try{return n.parse(e)}catch(r){let p=r.cause?.key?`${t}.${r.cause.key}`:t;throw new Error(`Error parsing index "${t}": ${r.message}`,{cause:{key:p}})}}):o)),u},any(){return i(()=>true)},preprocess(n,a){return s(a,"parse",(u,c)=>(c=n(c),u(c))),a}};function h(n){return a=>`The value "${a}" must be type of ${n} but is type of "${typeof a}".`}function s(n,a,u){let c=n[a];n[a]=(...o)=>u(c,...o);}function i(n,{type:a="any"}={}){let u=h(a),c={message:u,type:a},o={parse(e){if(!n(e))throw new Error(u(e));return e},safeParse(e){try{return {success:!0,data:this.parse(e)}}catch(t){return {success:false,error:t}}},transform(e){return s(this,"parse",(t,r)=>e(t(r))),this},optional(){return s(this,"parse",(e,t)=>{try{return e(t)}catch{return}}),this},nullable(){return s(this,"parse",(e,t)=>{try{return e(t)}catch{return null}}),this},nullish(){return s(this,"parse",(e,t)=>{try{return e(t)}catch{return t==null?t:null}}),this},default(e){return s(this,"parse",(t,r)=>(r===void 0&&(r=e,r=typeof e=="function"?e():e),r=t(r),r)),this},pipe(e){return s(this,"parse",(t,r)=>e.parse(t(r))),this},refine(e,{message:t}){return s(this,"parse",(r,p)=>{let f=r(p);if(!e(f))throw new Error(t);return f}),this}};return m.reduce((e,t)=>t(e,n,c)??e,o)}var m=[];function I(n){m.push(n);}exports.extend=I;exports.s=y;
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- var l={object(t){let c=s(u=>typeof u=="object"&&u!==null&&!Array.isArray(u),{type:"object"});return i(c,"parse",(u,...o)=>{let e=u(...o);return t&&typeof e=="object"?Object.keys(t).reduce((n,r)=>{if(typeof t[r]?.parse=="function")try{n[r]=t[r].parse(e[r]);}catch(p){throw r=p.cause?.key?`${r}.${p.cause.key}`:r,new Error(`Error parsing key "${r}": ${p.message}`,{cause:{key:r}})}return n},{}):e}),c},string(){return s(a=>typeof a=="string",{type:"string"})},number(){return s(a=>typeof a=="number",{type:"number"})},boolean(){return s(a=>a===true||a===false,{type:"boolean"})},array(t){let c=s(u=>Array.isArray(u),{type:"array"});return i(c,"parse",(u,o)=>(o=u(o),t&&Array.isArray(o)?o.map((e,n)=>{try{return t.parse(e)}catch(r){let p=r.cause?.key?`${n}.${r.cause.key}`:n;throw new Error(`Error parsing index "${n}": ${r.message}`,{cause:{key:p}})}}):o)),c},any(){return s(()=>true)}};function y(t){return a=>`The value "${a}" must be type of ${t} but is type of "${typeof a}".`}function i(t,a,c){let u=t[a];t[a]=(...o)=>c(u,...o);}function s(t,{type:a="any"}={}){let c=y(a),u={message:c,type:a},o={parse(e){if(!t(e))throw new Error(c(e));return e},safeParse(e){try{return {success:!0,data:this.parse(e)}}catch(n){return {success:false,error:n}}},optional(){return i(this,"parse",(e,n)=>{try{return e(n)}catch{return}}),this},nullable(){return i(this,"parse",(e,n)=>{try{return e(n)}catch{return null}}),this},nullish(){return i(this,"parse",(e,n)=>{try{return e(n)}catch{return n==null?n:null}}),this},default(e){return i(this,"parse",(n,r)=>(r===void 0&&(r=e,r=typeof e=="function"?e():e),r=n(r),r)),this}};return f.reduce((e,n)=>n(e,t,u)??e,o)}var f=[];function h(t){f.push(t);}export{h as extend,l as s};
1
+ var y={object(n){let u=i(c=>typeof c=="object"&&c!==null&&!Array.isArray(c),{type:"object"});return s(u,"parse",(c,...o)=>{let e=c(...o);return n&&typeof e=="object"?Object.keys(n).reduce((t,r)=>{if(typeof n[r]?.parse=="function")try{t[r]=n[r].parse(e[r]);}catch(p){throw r=p.cause?.key?`${r}.${p.cause.key}`:r,new Error(`Error parsing key "${r}": ${p.message}`,{cause:{key:r}})}return t},{}):e}),u},string(){return i(a=>typeof a=="string",{type:"string"})},number(){return i(a=>typeof a=="number",{type:"number"})},boolean(){return i(a=>a===true||a===false,{type:"boolean"})},date(){return i(a=>a instanceof Date&&!Number.isNaN(a.getTime()),{type:"date"})},array(n){let u=i(c=>Array.isArray(c),{type:"array"});return s(u,"parse",(c,o)=>(o=c(o),n&&Array.isArray(o)?o.map((e,t)=>{try{return n.parse(e)}catch(r){let p=r.cause?.key?`${t}.${r.cause.key}`:t;throw new Error(`Error parsing index "${t}": ${r.message}`,{cause:{key:p}})}}):o)),u},any(){return i(()=>true)},preprocess(n,a){return s(a,"parse",(u,c)=>(c=n(c),u(c))),a}};function h(n){return a=>`The value "${a}" must be type of ${n} but is type of "${typeof a}".`}function s(n,a,u){let c=n[a];n[a]=(...o)=>u(c,...o);}function i(n,{type:a="any"}={}){let u=h(a),c={message:u,type:a},o={parse(e){if(!n(e))throw new Error(u(e));return e},safeParse(e){try{return {success:!0,data:this.parse(e)}}catch(t){return {success:false,error:t}}},transform(e){return s(this,"parse",(t,r)=>e(t(r))),this},optional(){return s(this,"parse",(e,t)=>{try{return e(t)}catch{return}}),this},nullable(){return s(this,"parse",(e,t)=>{try{return e(t)}catch{return null}}),this},nullish(){return s(this,"parse",(e,t)=>{try{return e(t)}catch{return t==null?t:null}}),this},default(e){return s(this,"parse",(t,r)=>(r===void 0&&(r=e,r=typeof e=="function"?e():e),r=t(r),r)),this},pipe(e){return s(this,"parse",(t,r)=>e.parse(t(r))),this},refine(e,{message:t}){return s(this,"parse",(r,p)=>{let f=r(p);if(!e(f))throw new Error(t);return f}),this}};return m.reduce((e,t)=>t(e,n,c)??e,o)}var m=[];function I(n){m.push(n);}export{I as extend,y as s};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esmj/schema",
3
- "version": "0.0.2",
3
+ "version": "0.1.0",
4
4
  "description": "Tiny extendable package for schema validation.",
5
5
  "keywords": [
6
6
  "schema",
@@ -24,7 +24,7 @@
24
24
  "lint:fix": "npm run lint -- --fix --unsafe",
25
25
  "dev": "node_modules/.bin/tsup --dts --watch --onSuccess 'node ./dist/index.mjs'",
26
26
  "test": "node --test --experimental-strip-types",
27
- "test:watch": "npm run test -- --watchAll",
27
+ "test:watch": "npm run test -- --watch",
28
28
  "preversion": "npm test && npm run lint && npm run build",
29
29
  "version": "npm run changelog && git add CHANGELOG.md",
30
30
  "postversion": "git push && git push --tags",