@cleverbrush/schema 0.0.16 → 1.0.0-beta.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.
Files changed (75) hide show
  1. package/README.md +224 -149
  2. package/dist/builders/AliasSchemaBuilder.d.ts +14 -0
  3. package/dist/builders/AliasSchemaBuilder.js +91 -0
  4. package/dist/builders/ArraySchemaBuilder.d.ts +15 -0
  5. package/dist/builders/ArraySchemaBuilder.js +141 -0
  6. package/dist/builders/BooleanSchemaBuilder.d.ts +31 -0
  7. package/dist/builders/BooleanSchemaBuilder.js +90 -0
  8. package/dist/builders/FunctionSchemaBuilder.d.ts +25 -0
  9. package/dist/builders/FunctionSchemaBuilder.js +66 -0
  10. package/dist/builders/NumberSchemaBuilder.d.ts +61 -0
  11. package/dist/builders/NumberSchemaBuilder.js +206 -0
  12. package/dist/builders/ObjectSchemaBuilder.d.ts +83 -0
  13. package/dist/builders/ObjectSchemaBuilder.js +344 -0
  14. package/dist/builders/SchemaBuilder.d.ts +36 -0
  15. package/dist/builders/SchemaBuilder.js +88 -0
  16. package/dist/builders/StringSchemaBuilder.d.ts +14 -0
  17. package/dist/builders/StringSchemaBuilder.js +140 -0
  18. package/dist/builders/UnionSchemaBuilder.d.ts +10 -0
  19. package/dist/builders/UnionSchemaBuilder.js +100 -0
  20. package/dist/defaultSchemas.d.ts +4 -0
  21. package/dist/defaultSchemas.js +45 -0
  22. package/dist/index.d.ts +38 -90
  23. package/dist/index.js +30 -4
  24. package/dist/schema.d.ts +242 -0
  25. package/dist/schema.js +2 -0
  26. package/dist/schemaRegistry.d.ts +54 -0
  27. package/dist/schemaRegistry.js +301 -0
  28. package/dist/validators/validateArray.d.ts +3 -2
  29. package/dist/validators/validateBoolean.d.ts +2 -2
  30. package/dist/validators/validateBoolean.js +1 -4
  31. package/dist/validators/validateFunction.d.ts +2 -0
  32. package/dist/validators/validateFunction.js +21 -0
  33. package/dist/validators/validateNumber.d.ts +2 -2
  34. package/dist/validators/validateNumber.js +1 -1
  35. package/dist/validators/validateObject.d.ts +3 -2
  36. package/dist/validators/validateObject.js +33 -11
  37. package/dist/validators/validateString.d.ts +2 -2
  38. package/dist/validators/validateString.js +1 -1
  39. package/dist/validators/validateUnion.d.ts +3 -0
  40. package/dist/validators/validateUnion.js +30 -0
  41. package/package.json +3 -3
  42. package/src/builders/AliasSchemaBuilder.test.ts +124 -0
  43. package/src/builders/AliasSchemaBuilder.ts +250 -0
  44. package/src/builders/ArraySchemaBuilder.test.ts +270 -0
  45. package/src/builders/ArraySchemaBuilder.ts +381 -0
  46. package/src/builders/BooleanSchemaBuilder.test.ts +196 -0
  47. package/src/builders/BooleanSchemaBuilder.ts +155 -0
  48. package/src/builders/FunctionSchemaBuilder.test.ts +134 -0
  49. package/src/builders/FunctionSchemaBuilder.ts +109 -0
  50. package/src/builders/NumberSchemaBuilder.test.ts +493 -0
  51. package/src/builders/NumberSchemaBuilder.ts +789 -0
  52. package/src/builders/ObjectSchemaBuilder.test.ts +657 -0
  53. package/src/builders/ObjectSchemaBuilder.ts +794 -0
  54. package/src/builders/SchemaBuilder.test.ts +73 -0
  55. package/src/builders/SchemaBuilder.ts +135 -0
  56. package/src/builders/StringSchemaBuilder.test.ts +318 -0
  57. package/src/builders/StringSchemaBuilder.ts +392 -0
  58. package/src/builders/UnionSchemaBuilder.test.ts +162 -0
  59. package/src/builders/UnionSchemaBuilder.ts +159 -0
  60. package/src/defaultSchemas.ts +44 -0
  61. package/src/index.ts +70 -190
  62. package/src/schema.ts +922 -0
  63. package/src/schemaRegistry.builders.test.ts +1438 -0
  64. package/src/{schemaValidator.test.ts → schemaRegistry.test.ts} +561 -185
  65. package/src/schemaRegistry.ts +532 -0
  66. package/src/validators/validateArray.ts +4 -7
  67. package/src/validators/validateBoolean.ts +2 -11
  68. package/src/validators/validateFunction.ts +25 -0
  69. package/src/validators/validateNumber.ts +2 -7
  70. package/src/validators/validateObject.ts +32 -21
  71. package/src/validators/validateString.ts +2 -7
  72. package/src/validators/validateUnion.ts +36 -0
  73. package/dist/schemaValidator.d.ts +0 -16
  74. package/dist/schemaValidator.js +0 -234
  75. package/src/schemaValidator.ts +0 -367
@@ -1,13 +1,12 @@
1
1
  import { deepEqual, deepExtend } from '@cleverbrush/deep';
2
- import { ValidationResult } from '../dist/index.js';
3
2
 
4
3
  import {
5
- NumberSchemaDefinition,
6
- ObjectSchemaDefinitionParam,
7
- ObjectSchemaDefinition,
4
+ ValidationResult,
5
+ NumberSchema,
6
+ ObjectSchema,
8
7
  Schema
9
- } from './index';
10
- import SchemaValidator from './schemaValidator';
8
+ } from './schema.js';
9
+ import SchemaRegistry from './schemaRegistry.js';
11
10
 
12
11
  type User = {
13
12
  id: number;
@@ -22,60 +21,71 @@ type User = {
22
21
  spouse?: User;
23
22
  };
24
23
 
25
- const getUserSchema = (): ObjectSchemaDefinitionParam<User> => ({
26
- properties: {
27
- id: 'number',
28
- name: {
29
- type: 'object',
30
- isNullable: false,
31
- isRequired: true,
32
- properties: {
33
- first: {
34
- type: 'string',
35
- isNullable: false,
36
- isRequired: true,
37
- minLength: 1,
38
- maxLength: 100
39
- },
40
- last: {
41
- type: 'string',
42
- isNullable: false,
43
- isRequired: true,
44
- minLength: 1,
45
- maxLength: 100
24
+ const getUserSchema = (): Schema<User> =>
25
+ ({
26
+ type: 'object',
27
+ properties: {
28
+ id: 'number',
29
+ name: {
30
+ type: 'object',
31
+ isNullable: false,
32
+ isRequired: true,
33
+ properties: {
34
+ first: {
35
+ type: 'string',
36
+ isNullable: false,
37
+ isRequired: true,
38
+ minLength: 1,
39
+ maxLength: 100
40
+ },
41
+ last: {
42
+ type: 'string',
43
+ isNullable: false,
44
+ isRequired: true,
45
+ minLength: 1,
46
+ maxLength: 100
47
+ }
46
48
  }
49
+ },
50
+ incomePerMonth: {
51
+ type: 'number',
52
+ min: 0
47
53
  }
48
- },
49
- incomePerMonth: {
50
- type: 'number',
51
- min: 0
52
54
  }
53
- }
54
- });
55
+ } as any);
55
56
 
56
57
  test('Can add schema', () => {
57
- const validator = new SchemaValidator().addSchemaType(
58
- 'something',
59
- getUserSchema()
60
- );
58
+ const validator = new SchemaRegistry().addSchema('something', {
59
+ type: 'object',
60
+ properties: {
61
+ a: 'string'
62
+ }
63
+ });
61
64
  expect(validator.schemas.something).toBeDefined();
62
65
  });
63
66
 
67
+ test('Throws when not array or object is passed to addSchemaType', () => {
68
+ expect(() => {
69
+ new SchemaRegistry().addSchema('something', 1234 as any);
70
+ }).toThrow();
71
+ });
72
+
64
73
  test('Error thrown on adding a schema with duplicate name', () => {
65
74
  expect(() =>
66
- new SchemaValidator()
67
- .addSchemaType('smth', {})
68
- .addSchemaType('smth', {})
75
+ new SchemaRegistry()
76
+ .addSchema('smth', {} as any)
77
+ .addSchema('smth', {} as any)
69
78
  ).toThrow();
70
79
  });
71
80
 
72
81
  test('Receiving the same schema after add', () => {
73
- const schema: ObjectSchemaDefinitionParam<{ name: string }> = {
82
+ const schema: ObjectSchema<{ name: string }> = {
83
+ type: 'object',
74
84
  properties: {
75
85
  name: 'string'
76
86
  }
77
87
  };
78
- const validator = new SchemaValidator().addSchemaType('something', schema);
88
+ const validator = new SchemaRegistry().addSchema('something', schema);
79
89
 
80
90
  expect(
81
91
  deepEqual(
@@ -86,67 +96,72 @@ test('Receiving the same schema after add', () => {
86
96
  });
87
97
 
88
98
  test('Schemas property is cached when reading', () => {
89
- const validator = new SchemaValidator().addSchemaType('something', {});
99
+ const validator = new SchemaRegistry().addSchema('something', {});
90
100
  expect(validator.schemas).toEqual(validator.schemas);
91
101
  });
92
102
 
93
103
  test('Schemas property is updated after adding a new schema', () => {
94
- let validator = new SchemaValidator().addSchemaType('something', {});
104
+ let validator = new SchemaRegistry().addSchema(
105
+ 'something',
106
+ {} as ObjectSchema<any>
107
+ );
95
108
  const s = validator.schemas;
96
- validator = validator.addSchemaType('another', {});
109
+ validator = validator.addSchema('another', {});
97
110
  expect(s).not.toEqual(validator.schemas);
98
111
  });
99
112
 
100
113
  test('Trows when trying to add a schema with name = "number"', () => {
101
- const validator = new SchemaValidator();
102
- expect(() => validator.addSchemaType('number', {})).toThrow();
114
+ const validator = new SchemaRegistry();
115
+ expect(() =>
116
+ validator.addSchema('number', {} as ObjectSchema<any>)
117
+ ).toThrow();
103
118
  });
104
119
 
105
120
  test('Trows when trying to add a schema with name = "array"', () => {
106
- const validator = new SchemaValidator();
107
- expect(() => validator.addSchemaType('array', {})).toThrow();
108
- });
109
-
110
- test('Trows when trying to add a schema with name = "date"', () => {
111
- const validator = new SchemaValidator();
112
- expect(() => validator.addSchemaType('date', {})).toThrow();
121
+ const validator = new SchemaRegistry();
122
+ expect(() =>
123
+ validator.addSchema('array', {} as ObjectSchema<any>)
124
+ ).toThrow();
113
125
  });
114
126
 
115
127
  test('Trows when trying to add a schema with name = "string"', () => {
116
- const validator = new SchemaValidator();
117
- expect(() => validator.addSchemaType('string', {})).toThrow();
128
+ const validator = new SchemaRegistry();
129
+ expect(() =>
130
+ validator.addSchema('string', {} as ObjectSchema<any>)
131
+ ).toThrow();
118
132
  });
119
133
 
120
134
  test('Throws if schema name is empty', () => {
121
- const validator = new SchemaValidator();
122
- expect(() => validator.addSchemaType('', {})).toThrow();
135
+ const validator = new SchemaRegistry();
136
+ expect(() => validator.addSchema('', {} as ObjectSchema<any>)).toThrow();
123
137
  });
124
138
 
125
139
  test('Throws if schema name is not a string', () => {
126
- const validator = new SchemaValidator();
140
+ const validator = new SchemaRegistry();
127
141
  expect(() =>
128
- validator.addSchemaType(new Date() as any as string, {})
142
+ validator.addSchema(
143
+ new Date() as any as string,
144
+ {} as ObjectSchema<any>
145
+ )
129
146
  ).toThrow();
130
147
  });
131
148
 
132
149
  test('Throws if schema is not an object', () => {
133
- const validator = new SchemaValidator();
150
+ const validator = new SchemaRegistry();
134
151
  expect(() =>
135
- validator.addSchemaType(
136
- 'string',
137
- 'string' as any as ObjectSchemaDefinitionParam<any>
138
- )
152
+ validator.addSchema('string', 'string' as any as ObjectSchema<any>)
139
153
  ).toThrow();
140
154
  });
141
155
 
142
- test('Array as schema type', async () => {
143
- const validator = new SchemaValidator()
144
- .addSchemaType('name', {
156
+ test('Union - Array as schema type', async () => {
157
+ const validator = new SchemaRegistry()
158
+ .addSchema('name', {
159
+ type: 'object',
145
160
  properties: {
146
161
  name: 'string'
147
162
  }
148
163
  })
149
- .addSchemaType('number_or_string', ['number', 'string', 'name']);
164
+ .addSchema('number_or_string', ['number', 'string', 'name']);
150
165
 
151
166
  let result = await validator.schemas.number_or_string.validate(123);
152
167
 
@@ -166,8 +181,64 @@ test('Array as schema type', async () => {
166
181
  expect(result).toHaveProperty('valid', true);
167
182
  });
168
183
 
184
+ test('Union - Schema Object - 1', async () => {
185
+ const validator = new SchemaRegistry().addSchema('address', {
186
+ type: 'object',
187
+ properties: {
188
+ first: {
189
+ type: 'union',
190
+ variants: [
191
+ { type: 'number', min: 10, max: 20 },
192
+ { type: 'string', minLength: 2 }
193
+ ]
194
+ }
195
+ }
196
+ });
197
+
198
+ let result = await validator.schemas.address.validate({
199
+ first: 15
200
+ });
201
+ expect(result).toHaveProperty('valid', true);
202
+ result = await validator.schemas.address.validate({
203
+ first: 25
204
+ });
205
+ expect(result).toHaveProperty('valid', false);
206
+ result = await validator.schemas.address.validate({
207
+ first: 'some string'
208
+ });
209
+ expect(result).toHaveProperty('valid', true);
210
+ result = await validator.schemas.address.validate({
211
+ first: 's'
212
+ });
213
+ expect(result).toHaveProperty('valid', false);
214
+ });
215
+
216
+ test('Union - Schema Object - 2', async () => {
217
+ const validator = new SchemaRegistry().addSchema('address', {
218
+ type: 'object',
219
+ properties: {
220
+ first: {
221
+ type: 'union',
222
+ isRequired: false,
223
+ isNullable: true,
224
+ variants: [
225
+ { type: 'number', min: 10, max: 20 },
226
+ { type: 'string', minLength: 2 }
227
+ ]
228
+ }
229
+ }
230
+ });
231
+
232
+ let result = await validator.schemas.address.validate({});
233
+ expect(result).toHaveProperty('valid', true);
234
+ result = await validator.schemas.address.validate({
235
+ first: null
236
+ });
237
+ expect(result).toHaveProperty('valid', true);
238
+ });
239
+
169
240
  test('Validate - no schema', async () => {
170
- const validator = new SchemaValidator();
241
+ const validator = new SchemaRegistry();
171
242
  const cth = jest.fn();
172
243
  validator
173
244
  .validate(null as any, 10)
@@ -178,7 +249,7 @@ test('Validate - no schema', async () => {
178
249
  });
179
250
 
180
251
  test('Validate - no schema type', async () => {
181
- const validator = new SchemaValidator();
252
+ const validator = new SchemaRegistry();
182
253
  const cth = jest.fn();
183
254
  validator
184
255
  .validate(
@@ -194,49 +265,61 @@ test('Validate - no schema type', async () => {
194
265
  });
195
266
 
196
267
  test('Validate - number by value', async () => {
197
- const validator = new SchemaValidator();
268
+ const validator = new SchemaRegistry();
198
269
  const result = await validator.validate(10, 0);
199
270
  expect(result).toHaveProperty('valid', false);
200
271
  });
201
272
 
202
273
  test('Validate - number by value - 2', async () => {
203
- const validator = new SchemaValidator();
274
+ const validator = new SchemaRegistry();
204
275
  const result = await validator.validate(10, 10);
205
276
  expect(result).toHaveProperty('valid', true);
206
277
  });
207
278
 
208
279
  test('Validate - number by value - 3', async () => {
209
- const validator = new SchemaValidator();
280
+ const validator = new SchemaRegistry();
210
281
  const result = await validator.validate(10, {});
211
282
  expect(result).toHaveProperty('valid', false);
212
283
  });
213
284
 
214
285
  test('Validate - number by value - 4', async () => {
215
- const validator = new SchemaValidator();
286
+ const validator = new SchemaRegistry();
216
287
  const result = await validator.validate(10, 15);
217
288
  expect(result).toHaveProperty('valid', false);
218
289
  });
219
290
 
220
291
  test('Validate - number by name: object', async () => {
221
- const validator = new SchemaValidator();
292
+ const validator = new SchemaRegistry();
222
293
  const result = await validator.validate('number', {});
223
294
  expect(result).toHaveProperty('valid', false);
224
295
  });
225
296
 
226
297
  test('Validate - number by name: string', async () => {
227
- const validator = new SchemaValidator();
298
+ const validator = new SchemaRegistry();
228
299
  const result = await validator.validate('number', '10');
229
300
  expect(result).toHaveProperty('valid', false);
230
301
  });
231
302
 
232
303
  test('Validate - number by name - correct', async () => {
233
- const validator = new SchemaValidator();
304
+ const validator = new SchemaRegistry();
234
305
  const result = await validator.validate('number', 10);
235
306
  expect(result).toHaveProperty('valid', true);
236
307
  });
237
308
 
309
+ test('Validate - number by number - correct', async () => {
310
+ const validator = new SchemaRegistry();
311
+ const result = await validator.validate(10, 10);
312
+ expect(result).toHaveProperty('valid', true);
313
+ });
314
+
315
+ test('Validate - number by number - incorrect', async () => {
316
+ const validator = new SchemaRegistry();
317
+ const result = await validator.validate(10, 20);
318
+ expect(result).toHaveProperty('valid', false);
319
+ });
320
+
238
321
  test('Validate - number by schema', async () => {
239
- const validator = new SchemaValidator();
322
+ const validator = new SchemaRegistry();
240
323
  const result = await validator.validate(
241
324
  {
242
325
  type: 'number'
@@ -247,7 +330,7 @@ test('Validate - number by schema', async () => {
247
330
  });
248
331
 
249
332
  test('Validate - number by schema - not number passed', async () => {
250
- const validator = new SchemaValidator();
333
+ const validator = new SchemaRegistry();
251
334
  const result = await validator.validate(
252
335
  {
253
336
  type: 'number'
@@ -258,7 +341,7 @@ test('Validate - number by schema - not number passed', async () => {
258
341
  });
259
342
 
260
343
  test('Validate - number by schema - min', async () => {
261
- const validator = new SchemaValidator();
344
+ const validator = new SchemaRegistry();
262
345
  const result = await validator.validate(
263
346
  {
264
347
  type: 'number',
@@ -270,7 +353,7 @@ test('Validate - number by schema - min', async () => {
270
353
  });
271
354
 
272
355
  test('Validate - number by schema - min 2', async () => {
273
- const validator = new SchemaValidator();
356
+ const validator = new SchemaRegistry();
274
357
  const result = await validator.validate(
275
358
  {
276
359
  type: 'number',
@@ -284,7 +367,7 @@ test('Validate - number by schema - min 2', async () => {
284
367
  });
285
368
 
286
369
  test('Validate - number by schema - min 3', async () => {
287
- const validator = new SchemaValidator();
370
+ const validator = new SchemaRegistry();
288
371
  const result = await validator.validate(
289
372
  {
290
373
  type: 'number',
@@ -296,7 +379,7 @@ test('Validate - number by schema - min 3', async () => {
296
379
  });
297
380
 
298
381
  test('Validate - number by schema - min 4', async () => {
299
- const validator = new SchemaValidator();
382
+ const validator = new SchemaRegistry();
300
383
  const mk = jest.fn();
301
384
  validator
302
385
  .validate(
@@ -313,7 +396,7 @@ test('Validate - number by schema - min 4', async () => {
313
396
  });
314
397
 
315
398
  test('Validate - number by schema - max', async () => {
316
- const validator = new SchemaValidator();
399
+ const validator = new SchemaRegistry();
317
400
  const result = await validator.validate(
318
401
  {
319
402
  type: 'number',
@@ -325,7 +408,7 @@ test('Validate - number by schema - max', async () => {
325
408
  });
326
409
 
327
410
  test('Validate - number by schema - max 2', async () => {
328
- const validator = new SchemaValidator();
411
+ const validator = new SchemaRegistry();
329
412
  const result = await validator.validate(
330
413
  {
331
414
  type: 'number',
@@ -337,7 +420,7 @@ test('Validate - number by schema - max 2', async () => {
337
420
  });
338
421
 
339
422
  test('Validate - number by schema - max 3', async () => {
340
- const validator = new SchemaValidator();
423
+ const validator = new SchemaRegistry();
341
424
  const result = await validator.validate(
342
425
  {
343
426
  type: 'number',
@@ -349,7 +432,7 @@ test('Validate - number by schema - max 3', async () => {
349
432
  });
350
433
 
351
434
  test('Validate - number by schema - max 4', async () => {
352
- const validator = new SchemaValidator();
435
+ const validator = new SchemaRegistry();
353
436
  const mk = jest.fn();
354
437
  validator
355
438
  .validate(
@@ -366,7 +449,7 @@ test('Validate - number by schema - max 4', async () => {
366
449
  });
367
450
 
368
451
  test('Validate - number by schema - range', async () => {
369
- const validator = new SchemaValidator();
452
+ const validator = new SchemaRegistry();
370
453
  const result = await validator.validate(
371
454
  {
372
455
  type: 'number',
@@ -380,7 +463,7 @@ test('Validate - number by schema - range', async () => {
380
463
  });
381
464
 
382
465
  test('Validate - number by schema - range - 2', async () => {
383
- const validator = new SchemaValidator();
466
+ const validator = new SchemaRegistry();
384
467
  const result = await validator.validate(
385
468
  {
386
469
  type: 'number',
@@ -394,7 +477,7 @@ test('Validate - number by schema - range - 2', async () => {
394
477
  });
395
478
 
396
479
  test('Validate - number by schema - range - 3', async () => {
397
- const validator = new SchemaValidator();
480
+ const validator = new SchemaRegistry();
398
481
  const result = await validator.validate(
399
482
  {
400
483
  type: 'number',
@@ -408,7 +491,7 @@ test('Validate - number by schema - range - 3', async () => {
408
491
  });
409
492
 
410
493
  test('Validate - number by schema - range - 4', async () => {
411
- const validator = new SchemaValidator();
494
+ const validator = new SchemaRegistry();
412
495
  const result = await validator.validate(
413
496
  {
414
497
  type: 'number',
@@ -422,7 +505,7 @@ test('Validate - number by schema - range - 4', async () => {
422
505
  });
423
506
 
424
507
  test('Validate - number by schema - range - 5', async () => {
425
- const validator = new SchemaValidator();
508
+ const validator = new SchemaRegistry();
426
509
  const result = await validator.validate(
427
510
  {
428
511
  type: 'number',
@@ -436,7 +519,7 @@ test('Validate - number by schema - range - 5', async () => {
436
519
  });
437
520
 
438
521
  test('Validate - number by schema - range - 6', async () => {
439
- const validator = new SchemaValidator();
522
+ const validator = new SchemaRegistry();
440
523
  const result = await validator.validate(
441
524
  {
442
525
  type: 'number',
@@ -450,7 +533,7 @@ test('Validate - number by schema - range - 6', async () => {
450
533
  });
451
534
 
452
535
  test('Validate - number by schema - NaN', async () => {
453
- const validator = new SchemaValidator();
536
+ const validator = new SchemaRegistry();
454
537
  const result = await validator.validate(
455
538
  {
456
539
  type: 'number',
@@ -463,7 +546,7 @@ test('Validate - number by schema - NaN', async () => {
463
546
  });
464
547
 
465
548
  test('Validate - number by schema - NaN - 2', async () => {
466
- const validator = new SchemaValidator();
549
+ const validator = new SchemaRegistry();
467
550
  const result = await validator.validate(
468
551
  {
469
552
  type: 'number',
@@ -476,7 +559,7 @@ test('Validate - number by schema - NaN - 2', async () => {
476
559
  });
477
560
 
478
561
  test('Validate - number by schema - Infinity', async () => {
479
- const validator = new SchemaValidator();
562
+ const validator = new SchemaRegistry();
480
563
  const result = await validator.validate(
481
564
  {
482
565
  type: 'number'
@@ -488,7 +571,7 @@ test('Validate - number by schema - Infinity', async () => {
488
571
  });
489
572
 
490
573
  test('Validate - number by schema - Infinity - 2', async () => {
491
- const validator = new SchemaValidator();
574
+ const validator = new SchemaRegistry();
492
575
  const result = await validator.validate(
493
576
  {
494
577
  type: 'number',
@@ -501,8 +584,8 @@ test('Validate - number by schema - Infinity - 2', async () => {
501
584
  });
502
585
 
503
586
  test('Validate - number by schema - custom validators - 1', async () => {
504
- const validator = new SchemaValidator();
505
- const schema: NumberSchemaDefinition<any> = {
587
+ const validator = new SchemaRegistry();
588
+ const schema: NumberSchema = {
506
589
  type: 'number',
507
590
  validators: [
508
591
  async (value) => {
@@ -526,8 +609,8 @@ test('Validate - number by schema - custom validators - 1', async () => {
526
609
  });
527
610
 
528
611
  test('Validate - number by schema - custom validators - 2', async () => {
529
- const validator = new SchemaValidator();
530
- const schema: NumberSchemaDefinition<any> = {
612
+ const validator = new SchemaRegistry();
613
+ const schema: NumberSchema = {
531
614
  type: 'number',
532
615
  validators: [
533
616
  (value) => {
@@ -554,8 +637,30 @@ test('Validate - number by schema - custom validators - 2', async () => {
554
637
  expect(result).toHaveProperty('valid', false);
555
638
  });
556
639
 
640
+ test('Validate - number by schema - custom validators - 3', async () => {
641
+ const validator = new SchemaRegistry();
642
+ const schema: NumberSchema = {
643
+ type: 'number',
644
+ validators: [
645
+ async () => {
646
+ throw new Error('error');
647
+ },
648
+ (value) => ({ valid: value > 100 })
649
+ ]
650
+ };
651
+ const result = await validator.validate(schema, 101);
652
+
653
+ expect(result).toHaveProperty('valid', false);
654
+
655
+ // result = await validator.validate(schema, 99);
656
+ // expect(result).toHaveProperty('valid', false);
657
+
658
+ // result = await validator.validate(schema, 100);
659
+ // expect(result).toHaveProperty('valid', false);
660
+ });
661
+
557
662
  test('Validate - boolean - 1', async () => {
558
- const validator = new SchemaValidator();
663
+ const validator = new SchemaRegistry();
559
664
  const result = await validator.validate(
560
665
  {
561
666
  type: 'boolean'
@@ -567,7 +672,7 @@ test('Validate - boolean - 1', async () => {
567
672
  });
568
673
 
569
674
  test('Validate - boolean - 2', async () => {
570
- const validator = new SchemaValidator();
675
+ const validator = new SchemaRegistry();
571
676
  const result = await validator.validate(
572
677
  {
573
678
  type: 'boolean'
@@ -579,7 +684,7 @@ test('Validate - boolean - 2', async () => {
579
684
  });
580
685
 
581
686
  test('Validate - boolean - 3', async () => {
582
- const validator = new SchemaValidator();
687
+ const validator = new SchemaRegistry();
583
688
  const result = await validator.validate(
584
689
  {
585
690
  type: 'boolean'
@@ -591,7 +696,7 @@ test('Validate - boolean - 3', async () => {
591
696
  });
592
697
 
593
698
  test('Validate - boolean - 4', async () => {
594
- const validator = new SchemaValidator();
699
+ const validator = new SchemaRegistry();
595
700
  const result = await validator.validate(
596
701
  {
597
702
  type: 'boolean',
@@ -604,7 +709,7 @@ test('Validate - boolean - 4', async () => {
604
709
  });
605
710
 
606
711
  test('Validate - boolean - 5', async () => {
607
- const validator = new SchemaValidator();
712
+ const validator = new SchemaRegistry();
608
713
  const result = await validator.validate(
609
714
  {
610
715
  type: 'boolean',
@@ -617,51 +722,127 @@ test('Validate - boolean - 5', async () => {
617
722
  });
618
723
 
619
724
  test('Validate - boolean - 6', async () => {
620
- const validator = new SchemaValidator();
725
+ const validator = new SchemaRegistry();
621
726
  const result = await validator.validate('boolean', false);
622
727
 
623
728
  expect(result).toHaveProperty('valid', true);
624
729
  });
625
730
 
626
731
  test('Validate - boolean - 7', async () => {
627
- const validator = new SchemaValidator();
732
+ const validator = new SchemaRegistry();
628
733
  const result = await validator.validate('boolean', '123');
629
734
 
630
735
  expect(result).toHaveProperty('valid', false);
631
736
  });
632
737
 
738
+ test('Validate - boolean - 8', async () => {
739
+ const validator = new SchemaRegistry();
740
+ const result = await validator.validate(
741
+ {
742
+ type: 'boolean',
743
+ isRequired: false
744
+ },
745
+ undefined
746
+ );
747
+
748
+ expect(result).toHaveProperty('valid', true);
749
+ });
750
+
751
+ test('Validate - function - 1', async () => {
752
+ const validator = new SchemaRegistry();
753
+ const result = await validator.validate(
754
+ {
755
+ type: 'function'
756
+ },
757
+ 300
758
+ );
759
+
760
+ expect(result).toHaveProperty('valid', false);
761
+ });
762
+
763
+ test('Validate - function - 2', async () => {
764
+ const validator = new SchemaRegistry();
765
+ const result = await validator.validate(
766
+ {
767
+ type: 'function'
768
+ },
769
+ () => 10
770
+ );
771
+
772
+ expect(result).toHaveProperty('valid', true);
773
+ });
774
+
775
+ test('Validate - function - 3', async () => {
776
+ const validator = new SchemaRegistry();
777
+ const result = await validator.validate(
778
+ {
779
+ type: 'function'
780
+ },
781
+ (a) => a * a
782
+ );
783
+
784
+ expect(result).toHaveProperty('valid', true);
785
+ });
786
+
787
+ test('Validate - function - 4', async () => {
788
+ const validator = new SchemaRegistry();
789
+ const result = await validator.validate('function', () => 20);
790
+
791
+ expect(result).toHaveProperty('valid', true);
792
+ });
793
+
794
+ test('Validate - function - 5', async () => {
795
+ const validator = new SchemaRegistry();
796
+ const result = await validator.validate('function', '123');
797
+
798
+ expect(result).toHaveProperty('valid', false);
799
+ });
800
+
801
+ test('Validate - function - 6', async () => {
802
+ const validator = new SchemaRegistry();
803
+ const result = await validator.validate(
804
+ {
805
+ type: 'function',
806
+ isRequired: false
807
+ },
808
+ undefined
809
+ );
810
+
811
+ expect(result).toHaveProperty('valid', true);
812
+ });
813
+
633
814
  test('Validate - string - 1', async () => {
634
- const validator = new SchemaValidator();
815
+ const validator = new SchemaRegistry();
635
816
  const result = await validator.validate('string', '12345');
636
817
  expect(result).toHaveProperty('valid', true);
637
818
  });
638
819
 
639
820
  test('Validate - string - 2', async () => {
640
- const validator = new SchemaValidator();
821
+ const validator = new SchemaRegistry();
641
822
  const result = await validator.validate('string', 12345);
642
823
  expect(result).toHaveProperty('valid', false);
643
824
  });
644
825
 
645
826
  test('Validate - string - 3', async () => {
646
- const validator = new SchemaValidator();
827
+ const validator = new SchemaRegistry();
647
828
  const result = await validator.validate('12345', '12345');
648
829
  expect(result).toHaveProperty('valid', true);
649
830
  });
650
831
 
651
832
  test('Validate - string - 4', async () => {
652
- const validator = new SchemaValidator();
833
+ const validator = new SchemaRegistry();
653
834
  const result = await validator.validate('12345', '123456');
654
835
  expect(result).toHaveProperty('valid', false);
655
836
  });
656
837
 
657
838
  test('Validate - string - 5', async () => {
658
- const validator = new SchemaValidator();
839
+ const validator = new SchemaRegistry();
659
840
  const result = await validator.validate('12345', 123456);
660
841
  expect(result).toHaveProperty('valid', false);
661
842
  });
662
843
 
663
844
  test('Validate - string - schema object - 1', async () => {
664
- const validator = new SchemaValidator();
845
+ const validator = new SchemaRegistry();
665
846
  const result = await validator.validate(
666
847
  {
667
848
  type: 'string',
@@ -673,7 +854,7 @@ test('Validate - string - schema object - 1', async () => {
673
854
  });
674
855
 
675
856
  test('Validate - string - schema object - 2', async () => {
676
- const validator = new SchemaValidator();
857
+ const validator = new SchemaRegistry();
677
858
  const result = await validator.validate(
678
859
  {
679
860
  type: 'string',
@@ -685,7 +866,7 @@ test('Validate - string - schema object - 2', async () => {
685
866
  });
686
867
 
687
868
  test('Validate - string - schema object - 3', async () => {
688
- const validator = new SchemaValidator();
869
+ const validator = new SchemaRegistry();
689
870
  const result = await validator.validate(
690
871
  {
691
872
  type: 'string',
@@ -697,7 +878,7 @@ test('Validate - string - schema object - 3', async () => {
697
878
  });
698
879
 
699
880
  test('Validate - string - length control - 1', async () => {
700
- const validator = new SchemaValidator();
881
+ const validator = new SchemaRegistry();
701
882
  let result = await validator.validate(
702
883
  {
703
884
  type: 'string',
@@ -750,7 +931,7 @@ test('Validate - string - length control - 1', async () => {
750
931
  });
751
932
 
752
933
  test('Validate - array - 1', async () => {
753
- const validator = new SchemaValidator();
934
+ const validator = new SchemaRegistry();
754
935
  let result = await validator.validate('array', []);
755
936
  expect(result).toHaveProperty('valid', true);
756
937
 
@@ -759,7 +940,7 @@ test('Validate - array - 1', async () => {
759
940
  });
760
941
 
761
942
  test('Validate - array - size control - 1', async () => {
762
- const validator = new SchemaValidator();
943
+ const validator = new SchemaRegistry();
763
944
  let result = await validator.validate(
764
945
  {
765
946
  type: 'array',
@@ -812,7 +993,7 @@ test('Validate - array - size control - 1', async () => {
812
993
  });
813
994
 
814
995
  test('Validate - array - ofType - 1', async () => {
815
- const validator = new SchemaValidator();
996
+ const validator = new SchemaRegistry();
816
997
  let result = await validator.validate(
817
998
  {
818
999
  type: 'array',
@@ -844,20 +1025,42 @@ test('Validate - array - ofType - 1', async () => {
844
1025
  expect(result).toHaveProperty('valid', false);
845
1026
  });
846
1027
 
847
- test('Validate - object - 1', async () => {
848
- const validator = new SchemaValidator().addSchemaType(
849
- 'user',
850
- getUserSchema()
1028
+ test('Validate - array - unknown preprocessor - 1', async () => {
1029
+ expect(async () => {
1030
+ const validator = new SchemaRegistry();
1031
+ await validator.validate(
1032
+ {
1033
+ type: 'array',
1034
+ ofType: 'number',
1035
+ preprocessor: 'DDD'
1036
+ },
1037
+ [1, 2, 3]
1038
+ );
1039
+ }).rejects.toThrow();
1040
+ });
1041
+
1042
+ test('Validate - array - not required - 1', async () => {
1043
+ const validator = new SchemaRegistry();
1044
+ const result = await validator.validate(
1045
+ {
1046
+ type: 'array',
1047
+ ofType: 'number',
1048
+ isRequired: false
1049
+ },
1050
+ undefined
851
1051
  );
852
- const user: User = {
1052
+ expect(result).toHaveProperty('valid', true);
1053
+ });
1054
+
1055
+ test('Validate - object - 1', async () => {
1056
+ const validator = new SchemaRegistry().addSchema('user', getUserSchema());
1057
+ const user = {
853
1058
  id: 1,
854
1059
  name: {
855
1060
  first: 'Andrew',
856
1061
  last: 'Zolotukhin'
857
1062
  },
858
- bornAt: new Date(1986, 4, 30),
859
- incomePerMonth: 134234,
860
- aliases: []
1063
+ incomePerMonth: 134234
861
1064
  };
862
1065
 
863
1066
  let result = await validator.validate('user', user);
@@ -928,7 +1131,7 @@ test('Validate - object - 1', async () => {
928
1131
  });
929
1132
 
930
1133
  test('Validate - object - 2', async () => {
931
- const validator = new SchemaValidator().addSchemaType(
1134
+ const validator = new SchemaRegistry().addSchema(
932
1135
  'user',
933
1136
  deepExtend(getUserSchema(), {
934
1137
  validators: [
@@ -944,7 +1147,7 @@ test('Validate - object - 2', async () => {
944
1147
  };
945
1148
  }
946
1149
  ]
947
- }) as any as ObjectSchemaDefinition<any>
1150
+ }) as any as ObjectSchema<any>
948
1151
  );
949
1152
  const user: User = {
950
1153
  id: 1,
@@ -962,7 +1165,7 @@ test('Validate - object - 2', async () => {
962
1165
  });
963
1166
 
964
1167
  test('Validate - one of - 1', async () => {
965
- const validator = new SchemaValidator();
1168
+ const validator = new SchemaRegistry();
966
1169
 
967
1170
  let result = await validator.validate(['number', 'object'], 'something');
968
1171
  expect(result).toHaveProperty('valid', false);
@@ -992,6 +1195,7 @@ test('Validate - one of - 1', async () => {
992
1195
 
993
1196
  test('Validate schema - 1', async () => {
994
1197
  const authorsReportSpecificationSchema = {
1198
+ type: 'object',
995
1199
  properties: {
996
1200
  type: {
997
1201
  type: 'string',
@@ -1042,8 +1246,9 @@ test('Validate schema - 1', async () => {
1042
1246
  ]
1043
1247
  };
1044
1248
 
1045
- const validator = new SchemaValidator()
1046
- .addSchemaType('Date', {
1249
+ const validator = new SchemaRegistry()
1250
+ .addSchema('Date', {
1251
+ type: 'object',
1047
1252
  validators: [
1048
1253
  (value) =>
1049
1254
  value instanceof Date && !Number.isNaN(value)
@@ -1056,7 +1261,8 @@ test('Validate schema - 1', async () => {
1056
1261
  }
1057
1262
  ]
1058
1263
  })
1059
- .addSchemaType('EqualsFilterCondition', {
1264
+ .addSchema('EqualsFilterCondition', {
1265
+ type: 'object',
1060
1266
  properties: {
1061
1267
  operation: {
1062
1268
  type: 'string',
@@ -1065,7 +1271,8 @@ test('Validate schema - 1', async () => {
1065
1271
  value: ['object', 'string', 'number']
1066
1272
  }
1067
1273
  })
1068
- .addSchemaType('GreaterThanFilterCondition', {
1274
+ .addSchema('GreaterThanFilterCondition', {
1275
+ type: 'object',
1069
1276
  properties: {
1070
1277
  operation: {
1071
1278
  type: 'string',
@@ -1074,7 +1281,8 @@ test('Validate schema - 1', async () => {
1074
1281
  value: 'number'
1075
1282
  }
1076
1283
  })
1077
- .addSchemaType('LessThanFilterCondition', {
1284
+ .addSchema('LessThanFilterCondition', {
1285
+ type: 'object',
1078
1286
  properties: {
1079
1287
  operation: {
1080
1288
  type: 'string',
@@ -1083,7 +1291,8 @@ test('Validate schema - 1', async () => {
1083
1291
  value: 'number'
1084
1292
  }
1085
1293
  })
1086
- .addSchemaType('ContainsFilterCondition', {
1294
+ .addSchema('ContainsFilterCondition', {
1295
+ type: 'object',
1087
1296
  properties: {
1088
1297
  operation: {
1089
1298
  type: 'string',
@@ -1099,13 +1308,15 @@ test('Validate schema - 1', async () => {
1099
1308
  ]
1100
1309
  }
1101
1310
  })
1102
- .addSchemaType('LikeFilterCondition', {
1311
+ .addSchema('LikeFilterCondition', {
1312
+ type: 'object',
1103
1313
  properties: {
1104
1314
  operation: 'like',
1105
1315
  value: 'string'
1106
1316
  }
1107
1317
  })
1108
- .addSchemaType('BetweenFilterCondition', {
1318
+ .addSchema('BetweenFilterCondition', {
1319
+ type: 'object',
1109
1320
  properties: {
1110
1321
  operation: 'between',
1111
1322
  from: 'number',
@@ -1118,18 +1329,19 @@ test('Validate schema - 1', async () => {
1118
1329
  : { valid: false, error: ['from must be <= to'] }
1119
1330
  ]
1120
1331
  })
1121
- .addSchemaType('StringFilterCondition', [
1332
+ .addSchema('StringFilterCondition', [
1122
1333
  'EqualsFilterCondition',
1123
1334
  'LikeFilterCondition'
1124
1335
  ])
1125
- .addSchemaType('AuthorFilter', {
1336
+ .addSchema('AuthorFilter', {
1337
+ type: 'object',
1126
1338
  properties: {
1127
1339
  fullName: 'StringFilterCondition'
1128
1340
  }
1129
1341
  })
1130
- .addSchemaType(
1342
+ .addSchema(
1131
1343
  'AuthorsReportSpecification',
1132
- authorsReportSpecificationSchema as ObjectSchemaDefinitionParam<any>
1344
+ authorsReportSpecificationSchema as ObjectSchema<any>
1133
1345
  );
1134
1346
 
1135
1347
  /**
@@ -1199,8 +1411,9 @@ test('Validate schema - 1', async () => {
1199
1411
  });
1200
1412
 
1201
1413
  test('Validate schema - 2', async () => {
1202
- const validator = new SchemaValidator()
1203
- .addSchemaType('Date', {
1414
+ const validator = new SchemaRegistry()
1415
+ .addSchema('Date', {
1416
+ type: 'object',
1204
1417
  validators: [
1205
1418
  (value) =>
1206
1419
  value instanceof Date && !Number.isNaN(value)
@@ -1213,12 +1426,14 @@ test('Validate schema - 2', async () => {
1213
1426
  }
1214
1427
  ]
1215
1428
  })
1216
- .addSchemaType('Module.Schema1', {
1429
+ .addSchema('Module.Schema1', {
1430
+ type: 'object',
1217
1431
  properties: {
1218
1432
  a: 'string'
1219
1433
  }
1220
1434
  })
1221
- .addSchemaType('Module.Schema2', {
1435
+ .addSchema('Module.Schema2', {
1436
+ type: 'object',
1222
1437
  properties: {
1223
1438
  b: 'number'
1224
1439
  }
@@ -1242,18 +1457,18 @@ test('Validate schema - 2', async () => {
1242
1457
  });
1243
1458
 
1244
1459
  test('Not required alternative schema alias', async () => {
1245
- const validator = new SchemaValidator()
1246
- .addSchemaType('Alternate1', {
1460
+ const validator = new SchemaRegistry()
1461
+ .addSchema('Alternate1', {
1247
1462
  properties: {
1248
1463
  a1: 'string'
1249
1464
  }
1250
1465
  })
1251
- .addSchemaType('Alternate2', {
1466
+ .addSchema('Alternate2', {
1252
1467
  properties: {
1253
1468
  a2: 'string'
1254
1469
  }
1255
1470
  })
1256
- .addSchemaType('Alternate', ['Alternate1', 'Alternate2']);
1471
+ .addSchema('Alternate', ['Alternate1', 'Alternate2']);
1257
1472
 
1258
1473
  let result = await validator.validate(
1259
1474
  {
@@ -1291,8 +1506,46 @@ test('Not required alternative schema alias', async () => {
1291
1506
  expect(result).toHaveProperty('valid', false);
1292
1507
  });
1293
1508
 
1509
+ test('Nullable alias', async () => {
1510
+ const validator = new SchemaRegistry().addSchema('Alias1', {
1511
+ properties: {
1512
+ a2: 'string'
1513
+ }
1514
+ });
1515
+
1516
+ let result = await validator.validate(
1517
+ {
1518
+ type: 'alias',
1519
+ isNullable: true,
1520
+ schemaName: 'Alias1'
1521
+ },
1522
+ null
1523
+ );
1524
+
1525
+ expect(result).toHaveProperty('valid', true);
1526
+
1527
+ result = await validator.validate(
1528
+ {
1529
+ type: 'object',
1530
+ properties: {
1531
+ prop: {
1532
+ type: 'alias',
1533
+ isNullable: true,
1534
+ schemaName: 'Alias1'
1535
+ }
1536
+ }
1537
+ },
1538
+ {
1539
+ prop: null
1540
+ }
1541
+ );
1542
+
1543
+ expect(result).toHaveProperty('valid', true);
1544
+ });
1545
+
1294
1546
  test('Preprocessors - 1', async () => {
1295
- const validator = new SchemaValidator().addSchemaType('Date', {
1547
+ const validator = new SchemaRegistry().addSchema('Date', {
1548
+ type: 'object',
1296
1549
  validators: [
1297
1550
  (value) =>
1298
1551
  value instanceof Date && !Number.isNaN(value)
@@ -1306,13 +1559,16 @@ test('Preprocessors - 1', async () => {
1306
1559
  ]
1307
1560
  });
1308
1561
 
1309
- const schema: Schema<{ bornAt: Date }> = {
1562
+ const schema: Schema<{ name: string; bornAt: Date }> = {
1310
1563
  type: 'object',
1311
1564
  properties: {
1312
- bornAt: 'Date'
1565
+ bornAt: {
1566
+ type: 'alias',
1567
+ schemaName: 'Date'
1568
+ }
1313
1569
  },
1314
1570
  preprocessors: {
1315
- bornAt: (value: unknown): Date | undefined => {
1571
+ bornAt: (value: any): Date | undefined => {
1316
1572
  const time = Date.parse(
1317
1573
  (value as Record<string, unknown>).toString()
1318
1574
  );
@@ -1320,16 +1576,16 @@ test('Preprocessors - 1', async () => {
1320
1576
  return new Date(time);
1321
1577
  }
1322
1578
  }
1323
- };
1579
+ } as any;
1324
1580
 
1325
- const result = await validator.validate(schema, {
1581
+ const result = await validator.validate(schema as Schema, {
1326
1582
  bornAt: new Date().toJSON()
1327
1583
  });
1328
1584
  expect(result).toHaveProperty('valid', true);
1329
1585
  });
1330
1586
 
1331
1587
  test('Preprocessors - 2', async () => {
1332
- const validator = new SchemaValidator().addSchemaType('Date', {
1588
+ const validator = new SchemaRegistry().addSchema('Date', {
1333
1589
  validators: [
1334
1590
  (value) =>
1335
1591
  value instanceof Date && !Number.isNaN(value)
@@ -1351,7 +1607,7 @@ test('Preprocessors - 2', async () => {
1351
1607
  preprocessors: {
1352
1608
  bornAt: 'StringToDate'
1353
1609
  }
1354
- };
1610
+ } as any;
1355
1611
 
1356
1612
  validator.addPreprocessor(
1357
1613
  'StringToDate',
@@ -1377,7 +1633,7 @@ test('Preprocessors - 2', async () => {
1377
1633
  )
1378
1634
  ).toThrow();
1379
1635
 
1380
- const result = await validator.validate(schema, {
1636
+ const result = await validator.validate(schema as Schema, {
1381
1637
  bornAt: new Date().toJSON()
1382
1638
  });
1383
1639
  expect(result).toHaveProperty('valid', true);
@@ -1392,18 +1648,18 @@ test('Preprocessors - 2', async () => {
1392
1648
  bornAt: 'StringToDate',
1393
1649
  diedAt: 'Unregistered'
1394
1650
  }
1395
- };
1651
+ } as any;
1396
1652
  expect(async () => {
1397
- await validator.validate(schema, {
1653
+ await validator.validate(schema as Schema, {
1398
1654
  bornAt: new Date().toJSON()
1399
1655
  });
1400
1656
  }).rejects.toBeInstanceOf(Error);
1401
1657
  });
1402
1658
 
1403
1659
  test('Preprocessors - 3', async () => {
1404
- const validator = new SchemaValidator().addSchemaType('Date', {
1660
+ const validator = new SchemaRegistry().addSchema('Date', {
1405
1661
  validators: [
1406
- (value) =>
1662
+ (value: any) =>
1407
1663
  value instanceof Date && !Number.isNaN(value)
1408
1664
  ? {
1409
1665
  valid: true
@@ -1474,38 +1730,38 @@ test('Preprocessors - 3', async () => {
1474
1730
  });
1475
1731
 
1476
1732
  test('Preprocessors - 3', async () => {
1477
- const validator = new SchemaValidator();
1733
+ const validator = new SchemaRegistry();
1478
1734
 
1479
1735
  type SomeType = { age: number; marriedAt: number };
1480
1736
 
1481
- const schema: ObjectSchemaDefinition<SomeType> = {
1737
+ const schema: Schema<SomeType> = {
1482
1738
  type: 'object',
1483
1739
  properties: {
1484
1740
  age: 'number',
1485
1741
  marriedAt: 'number'
1486
1742
  },
1487
1743
  preprocessors: {
1488
- age: (value): number => 40,
1744
+ age: (): number => 40,
1489
1745
  '*': (value: SomeType): void => {
1490
1746
  if (value.marriedAt > value.age) {
1491
1747
  value.marriedAt = value.age;
1492
1748
  }
1493
1749
  }
1494
1750
  }
1495
- };
1751
+ } as any;
1496
1752
 
1497
1753
  const obj = {
1498
1754
  age: 50,
1499
1755
  marriedAt: 80
1500
1756
  };
1501
- await validator.validate(schema, obj);
1757
+ await validator.validate(schema as Schema, obj);
1502
1758
  expect(obj).toHaveProperty('marriedAt', 40);
1503
1759
  });
1504
1760
 
1505
1761
  test('Preprocessors - 4', async () => {
1506
- const validator = new SchemaValidator().addSchemaType('Date', {
1762
+ const validator = new SchemaRegistry().addSchema('Date', {
1507
1763
  validators: [
1508
- (value) =>
1764
+ (value: any) =>
1509
1765
  value instanceof Date && !Number.isNaN(value)
1510
1766
  ? {
1511
1767
  valid: true
@@ -1575,11 +1831,96 @@ test('Preprocessors - 4', async () => {
1575
1831
  expect(result).toHaveProperty('valid', false);
1576
1832
  });
1577
1833
 
1834
+ test('Preprocessors - 5', async () => {
1835
+ const validator = new SchemaRegistry().addSchema('Date', {
1836
+ type: 'object',
1837
+ validators: [
1838
+ (value) =>
1839
+ value instanceof Date && !Number.isNaN(value)
1840
+ ? {
1841
+ valid: true
1842
+ }
1843
+ : {
1844
+ valid: false,
1845
+ errors: ['should be a valid Date object']
1846
+ }
1847
+ ]
1848
+ });
1849
+
1850
+ const schema: Schema<{ name: string; bornAt: Date }> = {
1851
+ type: 'object',
1852
+ properties: {
1853
+ bornAt: {
1854
+ type: 'alias',
1855
+ schemaName: 'Date',
1856
+ isRequired: false
1857
+ }
1858
+ },
1859
+ preprocessors: {
1860
+ bornAt: () => undefined
1861
+ },
1862
+ validators: [
1863
+ (value) => {
1864
+ expect('bornAt' in value).toEqual(false);
1865
+ return { valid: true };
1866
+ }
1867
+ ]
1868
+ } as any;
1869
+
1870
+ const result = await validator.validate(schema as Schema, {});
1871
+ expect(result).toHaveProperty('valid', true);
1872
+ });
1873
+
1874
+ test('Preprocessors - 6', async () => {
1875
+ const validator = new SchemaRegistry()
1876
+ .addSchema('Date', {
1877
+ type: 'object',
1878
+ validators: [
1879
+ (value) =>
1880
+ value instanceof Date && !Number.isNaN(value)
1881
+ ? {
1882
+ valid: true
1883
+ }
1884
+ : {
1885
+ valid: false,
1886
+ errors: ['should be a valid Date object']
1887
+ }
1888
+ ]
1889
+ })
1890
+ .addPreprocessor('BornAt', () => undefined);
1891
+
1892
+ const schema: Schema<{ name: string; bornAt: Date }> = {
1893
+ type: 'object',
1894
+ properties: {
1895
+ bornAt: {
1896
+ type: 'alias',
1897
+ schemaName: 'Date',
1898
+ isRequired: false
1899
+ }
1900
+ },
1901
+ preprocessors: {
1902
+ bornAt: 'BornAt'
1903
+ },
1904
+ validators: [
1905
+ (value) => {
1906
+ expect('bornAt' in value).toEqual(false);
1907
+ return { valid: true };
1908
+ }
1909
+ ]
1910
+ } as any;
1911
+
1912
+ const result = await validator.validate(schema as Schema, {});
1913
+ expect(result).toHaveProperty('valid', true);
1914
+ });
1915
+
1916
+ test('Preprocessors - 7', async () => {
1917
+ expect(() => {
1918
+ new SchemaRegistry().addPreprocessor('BornAt', 123 as any);
1919
+ }).toThrow();
1920
+ });
1921
+
1578
1922
  test('Submodules - 1', async () => {
1579
- const validator = new SchemaValidator().addSchemaType(
1580
- 'Module1.Schema1',
1581
- {}
1582
- );
1923
+ const validator = new SchemaRegistry().addSchema('Module1.Schema1', {});
1583
1924
 
1584
1925
  const result = validator.schemas;
1585
1926
 
@@ -1588,9 +1929,10 @@ test('Submodules - 1', async () => {
1588
1929
  });
1589
1930
 
1590
1931
  test('Submodules - 2', async () => {
1591
- const validator = new SchemaValidator()
1592
- .addSchemaType('Module1.Schema1', {})
1593
- .addSchemaType('Module1.Schema2', {
1932
+ const validator = new SchemaRegistry()
1933
+ .addSchema('Module1.Schema1', {})
1934
+ .addSchema('Module1.Schema2', {
1935
+ type: 'object',
1594
1936
  properties: {
1595
1937
  a: 'number'
1596
1938
  }
@@ -1609,13 +1951,15 @@ test('Submodules - 2', async () => {
1609
1951
  });
1610
1952
 
1611
1953
  test('Submodules - 3', async () => {
1612
- const validator = new SchemaValidator()
1613
- .addSchemaType('Module1.Schema1', {
1954
+ const validator = new SchemaRegistry()
1955
+ .addSchema('Module1.Schema1', {
1956
+ type: 'object',
1614
1957
  properties: {
1615
1958
  b: 'number'
1616
1959
  }
1617
1960
  })
1618
- .addSchemaType('Module1.Schema2', {
1961
+ .addSchema('Module1.Schema2', {
1962
+ type: 'object',
1619
1963
  properties: {
1620
1964
  a: {
1621
1965
  type: 'alias',
@@ -1633,13 +1977,13 @@ test('Submodules - 3', async () => {
1633
1977
  });
1634
1978
 
1635
1979
  test('Submodules - 4', async () => {
1636
- const validator = new SchemaValidator()
1637
- .addSchemaType('Module1.Schema1', {
1980
+ const validator = new SchemaRegistry()
1981
+ .addSchema('Module1.Schema1', {
1638
1982
  properties: {
1639
1983
  b: 'number'
1640
1984
  }
1641
1985
  })
1642
- .addSchemaType('Module1.Schema2', {
1986
+ .addSchema('Module1.Schema2', {
1643
1987
  properties: {
1644
1988
  a: {
1645
1989
  type: 'alias',
@@ -1654,3 +1998,35 @@ test('Submodules - 4', async () => {
1654
1998
  }
1655
1999
  }).catch((e) => expect(e).toBeInstanceOf(Error));
1656
2000
  });
2001
+
2002
+ test('No unknown fields - 1', async () => {
2003
+ const validator = new SchemaRegistry().addSchema('Schema1', {
2004
+ type: 'object',
2005
+ properties: {
2006
+ b: 'number'
2007
+ },
2008
+ noUnknownProperties: true
2009
+ });
2010
+
2011
+ const result = await validator.schemas.Schema1.validate({
2012
+ b: 20,
2013
+ c: 'something'
2014
+ });
2015
+ expect(result).toHaveProperty('valid', false);
2016
+ });
2017
+
2018
+ test('No unknown fields - 2', async () => {
2019
+ const validator = new SchemaRegistry().addSchema('Schema1', {
2020
+ type: 'object',
2021
+ properties: {
2022
+ b: 'number'
2023
+ },
2024
+ noUnknownProperties: false
2025
+ });
2026
+
2027
+ const result = await validator.schemas.Schema1.validate({
2028
+ b: 20,
2029
+ c: 'something'
2030
+ });
2031
+ expect(result).toHaveProperty('valid', true);
2032
+ });