@esmj/schema 0.0.2 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/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,43 @@ 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
+
21
+ ## Comparison with Similar Libraries
22
+
23
+ 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:
24
+
25
+ | Library | Bundle Size (minified + gzipped) |
26
+ |------------------|---------------------------------|
27
+ | `@esmj/schema` | ~1 KB |
28
+ | Superstruct | ~3,2 KB |
29
+ | Yup | ~12,2 KB |
30
+ | Zod | ~14 KB |
31
+ | Joi | ~40 KB |
32
+
11
33
  ## Usage
12
34
 
13
35
  ### Basic Usage
14
36
 
15
37
  ```typescript
16
- import { s } from '@esmj/schema';
38
+ import { s, type Infer} from '@esmj/schema';
17
39
 
18
40
  const schema = s.object({
19
- username: s.string().optional(),
41
+ username: s.string().optional().refine((val) => val.length <= 255, {
42
+ message: "Username can't be more than 255 characters",
43
+ }),
20
44
  password: s.string().default('unknown'),
21
- account: s.number().default(0),
45
+ birthday: s.preprocess((value) => new Date(value), s.date()),
46
+ account: s.string().default('0').transform((value) => Number.parseInt(value)).pipe(s.number()),
47
+ money: s.number(),
22
48
  address: s.object({
23
49
  street: s.string(),
24
50
  city: s.string().optional(),
@@ -26,12 +52,28 @@ const schema = s.object({
26
52
  records: s.array(s.object({ name: s.string() })).default([]),
27
53
  });
28
54
 
55
+ type schemaType = Infer<typeof schema>;
56
+
29
57
  const result = schema.parse({
30
58
  username: 'john_doe',
59
+ birthday: '2000-01-01T23:59:59.000Z',
31
60
  address: { city: 'New York' },
61
+ money: 100,
32
62
  });
33
63
 
34
64
  console.log(result);
65
+ // {
66
+ // username: 'john_doe',
67
+ // password: 'unknown',
68
+ // birthday: Date('2000-01-01T23:59:59.000Z'),
69
+ // account: 0,
70
+ // money: 100,
71
+ // address: {
72
+ // street: 'unknown',
73
+ // city: 'New York',
74
+ // },
75
+ // records: [],
76
+ // }
35
77
  ```
36
78
 
37
79
  ### Schema Types
@@ -60,6 +102,14 @@ Creates a boolean schema.
60
102
  const booleanSchema = s.boolean();
61
103
  ```
62
104
 
105
+ #### `s.date()`
106
+
107
+ Creates a date schema.
108
+
109
+ ```typescript
110
+ const dateSchema = s.date();
111
+ ```
112
+
63
113
  #### `s.object(definition)`
64
114
 
65
115
  Creates an object schema with the given definition.
@@ -87,6 +137,34 @@ Creates a schema that accepts any value.
87
137
  const anySchema = s.any();
88
138
  ```
89
139
 
140
+ #### `s.enum(values)`
141
+
142
+ Creates an enum schema that validates against a predefined set of string values.
143
+
144
+ - **`values`**: An array of strings representing the allowed values for the enum. Each value must be a string.
145
+
146
+ ```typescript
147
+ const enumSchema = s.enum(['admin', 'user', 'guest']);
148
+
149
+ const validResult = enumSchema.parse('admin');
150
+ console.log(validResult);
151
+ // 'admin'
152
+
153
+ const invalidResult = enumSchema.safeParse('invalidRole');
154
+ console.log(invalidResult.success);
155
+ // false
156
+ console.log(invalidResult.error.message);
157
+ // Error: Invalid enum value. Expected "admin" | "user" | "guest", received "invalidRole".
158
+ ```
159
+
160
+ #### `s.preprocess(callback, schema)`
161
+
162
+ Creates a schema that preprocesses the input value using the provided callback before validating it with the given schema.
163
+
164
+ ```typescript
165
+ const preprocessSchema = s.preprocess((value) => new Date(value), s.date());
166
+ ```
167
+
90
168
  ### Schema Methods
91
169
 
92
170
  #### `parse(value)`
@@ -102,10 +180,7 @@ const result = stringSchema.parse('hello');
102
180
  Safely parses the given value according to the schema, returning a success or error result.
103
181
 
104
182
  ```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() };
183
+ const result = stringSchema.safeParse('hello'); // { success: true, data: 'hello' }
109
184
  ```
110
185
 
111
186
  #### `optional()`
@@ -140,22 +215,220 @@ Sets a default value for the schema.
140
215
  const defaultSchema = stringSchema.default('default value');
141
216
  ```
142
217
 
218
+ #### `transform(callback)`
219
+
220
+ Transforms the parsed value using the provided callback.
221
+
222
+ ```typescript
223
+ const transformedSchema = s.string().transform((value) => value.toUpperCase());
224
+ ```
225
+
226
+ #### `pipe(schema)`
227
+
228
+ Pipes the output of one schema into another schema for further validation or transformation.
229
+
230
+ ```typescript
231
+ const pipedSchema = s.string().pipe(s.number());
232
+ ```
233
+
234
+ #### `refine(validation, { message })`
235
+
236
+ Adds a refinement to the schema with a custom validation function and error message.
237
+
238
+ ```typescript
239
+ const refinedSchema = s.string().refine((val) => val.length <= 255, {
240
+ message: "String can't be more than 255 characters",
241
+ });
242
+ ```
243
+
143
244
  ### Extending Schemas
144
245
 
145
246
  You can extend the schema system with custom logic.
146
247
 
147
248
  ```typescript
148
- import { extend } from '@esmj/schema';
249
+ import { extend, type StringSchemaInterface } from '@esmj/schema';
250
+
251
+ interface StringSchemaInterface {
252
+ customMethod(value: string): string {}
253
+ }
149
254
 
150
255
  extend((schema, validation, options) => {
151
- schema.customMethod = () => {
256
+ schema.customMethod = (value) => {
152
257
  // Custom logic
258
+
259
+ return value;
153
260
  };
154
261
 
155
262
  return schema;
156
263
  });
157
264
  ```
158
265
 
266
+ ### More Examples
267
+
268
+ #### Nested Objects
269
+
270
+ You can define schemas for deeply nested objects.
271
+
272
+ ```typescript
273
+ const nestedSchema = s.object({
274
+ user: s.object({
275
+ id: s.number(),
276
+ profile: s.object({
277
+ name: s.string(),
278
+ age: s.number().optional(),
279
+ }),
280
+ }),
281
+ });
282
+
283
+ const result = nestedSchema.parse({
284
+ user: {
285
+ id: 1,
286
+ profile: {
287
+ name: 'John Doe',
288
+ },
289
+ },
290
+ });
291
+
292
+ console.log(result);
293
+ // {
294
+ // user: {
295
+ // id: 1,
296
+ // profile: {
297
+ // name: 'John Doe',
298
+ // },
299
+ // },
300
+ // }
301
+ ```
302
+
303
+ #### Arrays with Validation
304
+
305
+ You can validate arrays with specific item schemas.
306
+
307
+ ```typescript
308
+ const arraySchema = s.array(s.object({ id: s.number(), name: s.string() }));
309
+
310
+ const result = arraySchema.parse([
311
+ { id: 1, name: 'Item 1' },
312
+ { id: 2, name: 'Item 2' },
313
+ ]);
314
+
315
+ console.log(result);
316
+ // [
317
+ // { id: 1, name: 'Item 1' },
318
+ // { id: 2, name: 'Item 2' },
319
+ // ]
320
+ ```
321
+
322
+ #### Preprocessing Values
323
+
324
+ Use `s.preprocess` to transform input values before validation.
325
+
326
+ ```typescript
327
+ const preprocessSchema = s.preprocess(
328
+ (value) => value.trim(),
329
+ s.string().refine((val) => val.length > 0, { message: 'String cannot be empty' }),
330
+ );
331
+
332
+ const result = preprocessSchema.parse(' hello ');
333
+
334
+ console.log(result);
335
+ // 'hello'
336
+ ```
337
+
338
+ #### Transforming Values
339
+
340
+ Use `transform` to modify the parsed value.
341
+
342
+ ```typescript
343
+ const transformSchema = s.string().transform((value) => value.toUpperCase());
344
+
345
+ const result = transformSchema.parse('hello');
346
+
347
+ console.log(result);
348
+ // 'HELLO'
349
+ ```
350
+
351
+ #### Piping Schemas
352
+
353
+ Pipe the output of one schema into another for further validation or transformation.
354
+
355
+ ```typescript
356
+ const pipedSchema = s.string()
357
+ .transform((value) => Number.parseInt(value))
358
+ .pipe(s.number().refine((val) => val > 0, { message: 'Number must be positive' }));
359
+
360
+ const result = pipedSchema.parse('42');
361
+
362
+ console.log(result);
363
+ // 42
364
+ ```
365
+
366
+ #### Refining Values
367
+
368
+ Add custom validation logic with `refine`.
369
+
370
+ ```typescript
371
+ const refinedSchema = s.string().refine((val) => val.startsWith('A'), {
372
+ message: 'String must start with "A"',
373
+ });
374
+
375
+ const result = refinedSchema.parse('Apple');
376
+
377
+ console.log(result);
378
+ // 'Apple'
379
+ ```
380
+
381
+ #### Default Values
382
+
383
+ Set default values for optional fields.
384
+
385
+ ```typescript
386
+ const defaultSchema = s.object({
387
+ name: s.string().default('Anonymous'),
388
+ age: s.number().optional().default(18),
389
+ });
390
+
391
+ const result = defaultSchema.parse({});
392
+
393
+ console.log(result);
394
+ // { name: 'Anonymous', age: 18 }
395
+ ```
396
+
397
+ #### Safe Parsing
398
+
399
+ Use `safeParse` to handle errors gracefully.
400
+
401
+ ```typescript
402
+ const safeSchema = s.number();
403
+
404
+ const result = safeSchema.safeParse('not a number');
405
+
406
+ if (!result.success) {
407
+ console.error(result.error.message);
408
+ } else {
409
+ console.log(result.data);
410
+ }
411
+ // Error: The value "not a number" must be type of number but is type of "string".
412
+ ```
413
+
414
+ #### Combining Multiple Features
415
+
416
+ Combine multiple features like preprocessing, transformations, and refinements.
417
+
418
+ ```typescript
419
+ const combinedSchema = s.preprocess(
420
+ (value) => value.trim(),
421
+ s.string()
422
+ .transform((value) => value.toUpperCase())
423
+ .refine((val) => val.length <= 10, { message: 'String must be at most 10 characters' }),
424
+ );
425
+
426
+ const result = combinedSchema.parse(' hello ');
427
+
428
+ console.log(result);
429
+ // 'HELLO'
430
+ ```
431
+
159
432
  ## License
160
433
 
161
434
  MIT
package/dist/index.d.mts CHANGED
@@ -8,19 +8,50 @@ 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 EnumSchemaInterface<T extends string> extends SchemaInterface<string, T> {
21
+ }
22
+ interface StringSchemaInterface extends SchemaInterface<string, string> {
23
+ }
24
+ interface NumberSchemaInterface extends SchemaInterface<number, number> {
25
+ }
26
+ interface BooleanSchemaInterface extends SchemaInterface<boolean, boolean> {
27
+ }
28
+ interface DateSchemaInterface extends SchemaInterface<Date, Date> {
29
+ }
30
+ interface ArraySchemaInterface<T extends SchemaType> extends SchemaInterface<Array<T>, Array<ReturnType<T['parse']>>> {
31
+ }
32
+ interface ObjectSchemaInterface<T extends Record<string, SchemaType>> extends SchemaInterface<{
33
+ [Property in keyof T]: T[Property];
34
+ }, {
35
+ [Property in keyof T]: ReturnType<T[Property]['parse']>;
36
+ }> {
37
+ }
38
+ 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> | EnumSchemaInterface<string> | ArraySchemaInterface<StringSchemaInterface | ObjectSchemaInterface<Record<string, SchemaType>> | NumberSchemaInterface | BooleanSchemaInterface | DateSchemaInterface | EnumSchemaInterface<string>> | SchemaInterface<Array<unknown>, Array<unknown>> | SchemaInterface<Array<unknown>, Array<unknown> | undefined> | SchemaInterface<Array<unknown>, Array<unknown> | null> | SchemaInterface<Array<unknown>, Array<unknown> | undefined | null>;
39
+ type ExtenderType = (inter: SchemaType, validation: Function, options: {
40
+ message: string;
41
+ type: string;
42
+ }) => SchemaType;
16
43
  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"]>>>;
44
+ object<T extends Record<string, SchemaType>>(definition: { [Property in keyof T]: T[Property]; }): ObjectSchemaInterface<T>;
45
+ string(): StringSchemaInterface;
46
+ number(): NumberSchemaInterface;
47
+ boolean(): BooleanSchemaInterface;
48
+ date(): DateSchemaInterface;
49
+ enum(definition: Readonly<Array<string>>): EnumSchemaInterface<(typeof definition)[number]>;
50
+ array<T extends SchemaType>(definition: T): ArraySchemaInterface<T>;
22
51
  any(): any;
52
+ preprocess<T extends SchemaType>(callback: Function, schema: T): T;
23
53
  };
24
- declare function extend(callback: Function): void;
54
+ declare function extend(callback: ExtenderType): void;
55
+ type Infer<T> = T extends SchemaType ? ReturnType<T['parse']> : unknown;
25
56
 
26
- export { type SchemaInterface, type SchemaType, extend, s };
57
+ export { type ArraySchemaInterface, type BooleanSchemaInterface, type DateSchemaInterface, type EnumSchemaInterface, 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,50 @@ 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 EnumSchemaInterface<T extends string> extends SchemaInterface<string, T> {
21
+ }
22
+ interface StringSchemaInterface extends SchemaInterface<string, string> {
23
+ }
24
+ interface NumberSchemaInterface extends SchemaInterface<number, number> {
25
+ }
26
+ interface BooleanSchemaInterface extends SchemaInterface<boolean, boolean> {
27
+ }
28
+ interface DateSchemaInterface extends SchemaInterface<Date, Date> {
29
+ }
30
+ interface ArraySchemaInterface<T extends SchemaType> extends SchemaInterface<Array<T>, Array<ReturnType<T['parse']>>> {
31
+ }
32
+ interface ObjectSchemaInterface<T extends Record<string, SchemaType>> extends SchemaInterface<{
33
+ [Property in keyof T]: T[Property];
34
+ }, {
35
+ [Property in keyof T]: ReturnType<T[Property]['parse']>;
36
+ }> {
37
+ }
38
+ 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> | EnumSchemaInterface<string> | ArraySchemaInterface<StringSchemaInterface | ObjectSchemaInterface<Record<string, SchemaType>> | NumberSchemaInterface | BooleanSchemaInterface | DateSchemaInterface | EnumSchemaInterface<string>> | SchemaInterface<Array<unknown>, Array<unknown>> | SchemaInterface<Array<unknown>, Array<unknown> | undefined> | SchemaInterface<Array<unknown>, Array<unknown> | null> | SchemaInterface<Array<unknown>, Array<unknown> | undefined | null>;
39
+ type ExtenderType = (inter: SchemaType, validation: Function, options: {
40
+ message: string;
41
+ type: string;
42
+ }) => SchemaType;
16
43
  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"]>>>;
44
+ object<T extends Record<string, SchemaType>>(definition: { [Property in keyof T]: T[Property]; }): ObjectSchemaInterface<T>;
45
+ string(): StringSchemaInterface;
46
+ number(): NumberSchemaInterface;
47
+ boolean(): BooleanSchemaInterface;
48
+ date(): DateSchemaInterface;
49
+ enum(definition: Readonly<Array<string>>): EnumSchemaInterface<(typeof definition)[number]>;
50
+ array<T extends SchemaType>(definition: T): ArraySchemaInterface<T>;
22
51
  any(): any;
52
+ preprocess<T extends SchemaType>(callback: Function, schema: T): T;
23
53
  };
24
- declare function extend(callback: Function): void;
54
+ declare function extend(callback: ExtenderType): void;
55
+ type Infer<T> = T extends SchemaType ? ReturnType<T['parse']> : unknown;
25
56
 
26
- export { type SchemaInterface, type SchemaType, extend, s };
57
+ export { type ArraySchemaInterface, type BooleanSchemaInterface, type DateSchemaInterface, type EnumSchemaInterface, 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((r,t)=>{if(typeof n[t]?.parse=="function")try{r[t]=n[t].parse(e[t]);}catch(p){throw t=p.cause?.key?`${t}.${p.cause.key}`:t,new Error(`Error parsing key "${t}": ${p.message}`,{cause:{key:t}})}return r},{}):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"})},enum(n){let a=e=>n.includes(e),u=e=>`Invalid ${c} value. Expected ${n.map(r=>`"${r}"`).join(" | ")}, received "${e}".`,c="enum";return i(a,{type:c,message:u})},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,r)=>{try{return n.parse(e)}catch(t){let p=t.cause?.key?`${r}.${t.cause.key}`:r;throw new Error(`Error parsing index "${r}": ${t.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",message:u}={}){u=u||h(a);let 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(r){return {success:false,error:r}}},transform(e){return s(this,"parse",(r,t)=>e(r(t))),this},optional(){return s(this,"parse",(e,r)=>{try{return e(r)}catch{return}}),this},nullable(){return s(this,"parse",(e,r)=>{try{return e(r)}catch{return null}}),this},nullish(){return s(this,"parse",(e,r)=>{try{return e(r)}catch{return r==null?r:null}}),this},default(e){return s(this,"parse",(r,t)=>(t===void 0&&(t=e,t=typeof e=="function"?e():e),t=r(t),t)),this},pipe(e){return s(this,"parse",(r,t)=>e.parse(r(t))),this},refine(e,{message:r}){return s(this,"parse",(t,p)=>{let f=t(p);if(!e(f))throw new Error(r);return f}),this}};return m.reduce((e,r)=>r(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((r,t)=>{if(typeof n[t]?.parse=="function")try{r[t]=n[t].parse(e[t]);}catch(p){throw t=p.cause?.key?`${t}.${p.cause.key}`:t,new Error(`Error parsing key "${t}": ${p.message}`,{cause:{key:t}})}return r},{}):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"})},enum(n){let a=e=>n.includes(e),u=e=>`Invalid ${c} value. Expected ${n.map(r=>`"${r}"`).join(" | ")}, received "${e}".`,c="enum";return i(a,{type:c,message:u})},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,r)=>{try{return n.parse(e)}catch(t){let p=t.cause?.key?`${r}.${t.cause.key}`:r;throw new Error(`Error parsing index "${r}": ${t.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",message:u}={}){u=u||h(a);let 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(r){return {success:false,error:r}}},transform(e){return s(this,"parse",(r,t)=>e(r(t))),this},optional(){return s(this,"parse",(e,r)=>{try{return e(r)}catch{return}}),this},nullable(){return s(this,"parse",(e,r)=>{try{return e(r)}catch{return null}}),this},nullish(){return s(this,"parse",(e,r)=>{try{return e(r)}catch{return r==null?r:null}}),this},default(e){return s(this,"parse",(r,t)=>(t===void 0&&(t=e,t=typeof e=="function"?e():e),t=r(t),t)),this},pipe(e){return s(this,"parse",(r,t)=>e.parse(r(t))),this},refine(e,{message:r}){return s(this,"parse",(t,p)=>{let f=t(p);if(!e(f))throw new Error(r);return f}),this}};return m.reduce((e,r)=>r(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.1",
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",
@@ -62,17 +62,17 @@
62
62
  "homepage": "https://github.com/mjancarik/esmj-schema#readme",
63
63
  "devDependencies": {
64
64
  "@biomejs/biome": "1.9.4",
65
- "@commitlint/cli": "^19.7.1",
66
- "@commitlint/config-conventional": "^19.7.1",
67
- "@typescript-eslint/eslint-plugin": "^8.24.0",
68
- "@typescript-eslint/parser": "^8.24.0",
65
+ "@commitlint/cli": "^19.8.0",
66
+ "@commitlint/config-conventional": "^19.8.0",
67
+ "@typescript-eslint/eslint-plugin": "^8.31.0",
68
+ "@typescript-eslint/parser": "^8.31.0",
69
69
  "commitizen": "^4.3.1",
70
70
  "conventional-changelog-cli": "^5.0.0",
71
71
  "cz-conventional-changelog": "^3.3.0",
72
72
  "git-cz": "^4.9.0",
73
73
  "husky": "^9.1.7",
74
- "lint-staged": "^15.4.3",
75
- "prettier": "^3.5.0",
76
- "tsup": "^8.3.6"
74
+ "lint-staged": "^15.5.1",
75
+ "prettier": "^3.5.3",
76
+ "tsup": "^8.4.0"
77
77
  }
78
78
  }
package/biome.json DELETED
@@ -1,50 +0,0 @@
1
- {
2
- "files": {
3
- "include": ["src/**/*.mjs", "src/**/*.ts", "utils/**/*.mjs"],
4
- "ignore": [".history/**/*"]
5
- },
6
- "formatter": {
7
- "enabled": true,
8
- "formatWithErrors": true,
9
- "indentStyle": "space",
10
- "indentWidth": 2,
11
- "lineEnding": "lf",
12
- "lineWidth": 80,
13
- "attributePosition": "auto"
14
- },
15
- "organizeImports": { "enabled": true },
16
- "linter": {
17
- "enabled": true,
18
- "rules": {
19
- "recommended": true,
20
- "complexity": {
21
- "noForEach": "off",
22
- "noBannedTypes": "off"
23
- },
24
- "style": {
25
- "noParameterAssign": "off"
26
- }
27
- }
28
- },
29
- "javascript": {
30
- "formatter": {
31
- "jsxQuoteStyle": "double",
32
- "quoteProperties": "asNeeded",
33
- "trailingCommas": "all",
34
- "semicolons": "always",
35
- "arrowParentheses": "always",
36
- "bracketSpacing": true,
37
- "bracketSameLine": false,
38
- "quoteStyle": "single",
39
- "attributePosition": "auto"
40
- }
41
- },
42
- "overrides": [
43
- {
44
- "include": ["*.json"],
45
- "formatter": {
46
- "indentWidth": 2
47
- }
48
- }
49
- ]
50
- }