@cleverbrush/schema 1.0.0-beta.0 → 1.0.0-beta.2

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 (49) hide show
  1. package/package.json +2 -2
  2. package/src/builders/UnionSchemaBuilder.ts +1 -6
  3. package/src/index.ts +1 -13
  4. package/src/schema.ts +9 -104
  5. package/src/schemaRegistry.builders.test.ts +35 -80
  6. package/src/schemaRegistry.test.ts +2 -1916
  7. package/src/schemaRegistry.ts +55 -126
  8. package/dist/builders/AliasSchemaBuilder.d.ts +0 -14
  9. package/dist/builders/AliasSchemaBuilder.js +0 -91
  10. package/dist/builders/ArraySchemaBuilder.d.ts +0 -15
  11. package/dist/builders/ArraySchemaBuilder.js +0 -141
  12. package/dist/builders/BooleanSchemaBuilder.d.ts +0 -31
  13. package/dist/builders/BooleanSchemaBuilder.js +0 -90
  14. package/dist/builders/FunctionSchemaBuilder.d.ts +0 -25
  15. package/dist/builders/FunctionSchemaBuilder.js +0 -66
  16. package/dist/builders/NumberSchemaBuilder.d.ts +0 -61
  17. package/dist/builders/NumberSchemaBuilder.js +0 -206
  18. package/dist/builders/ObjectSchemaBuilder.d.ts +0 -83
  19. package/dist/builders/ObjectSchemaBuilder.js +0 -344
  20. package/dist/builders/SchemaBuilder.d.ts +0 -36
  21. package/dist/builders/SchemaBuilder.js +0 -88
  22. package/dist/builders/StringSchemaBuilder.d.ts +0 -14
  23. package/dist/builders/StringSchemaBuilder.js +0 -140
  24. package/dist/builders/UnionSchemaBuilder.d.ts +0 -10
  25. package/dist/builders/UnionSchemaBuilder.js +0 -100
  26. package/dist/defaultSchemas.d.ts +0 -4
  27. package/dist/defaultSchemas.js +0 -45
  28. package/dist/index.d.ts +0 -42
  29. package/dist/index.js +0 -35
  30. package/dist/schema.d.ts +0 -242
  31. package/dist/schema.js +0 -2
  32. package/dist/schemaRegistry.d.ts +0 -54
  33. package/dist/schemaRegistry.js +0 -301
  34. package/dist/validators/validateArray.d.ts +0 -3
  35. package/dist/validators/validateArray.js +0 -60
  36. package/dist/validators/validateBoolean.d.ts +0 -2
  37. package/dist/validators/validateBoolean.js +0 -30
  38. package/dist/validators/validateFunction.d.ts +0 -2
  39. package/dist/validators/validateFunction.js +0 -21
  40. package/dist/validators/validateNumber.d.ts +0 -2
  41. package/dist/validators/validateNumber.js +0 -69
  42. package/dist/validators/validateObject.d.ts +0 -3
  43. package/dist/validators/validateObject.js +0 -95
  44. package/dist/validators/validateString.d.ts +0 -2
  45. package/dist/validators/validateString.js +0 -50
  46. package/dist/validators/validateUnion.d.ts +0 -3
  47. package/dist/validators/validateUnion.js +0 -30
  48. package/src/builders/AliasSchemaBuilder.test.ts +0 -124
  49. package/src/builders/AliasSchemaBuilder.ts +0 -250
@@ -1,59 +1,8 @@
1
- import { deepEqual, deepExtend } from '@cleverbrush/deep';
1
+ import { deepEqual } from '@cleverbrush/deep';
2
2
 
3
- import {
4
- ValidationResult,
5
- NumberSchema,
6
- ObjectSchema,
7
- Schema
8
- } from './schema.js';
3
+ import { ObjectSchema } from './schema.js';
9
4
  import SchemaRegistry from './schemaRegistry.js';
10
5
 
11
- type User = {
12
- id: number;
13
- name: {
14
- first: string;
15
- last: string;
16
- };
17
- bornAt: Date;
18
- diedAt?: Date;
19
- incomePerMonth: number;
20
- aliases: string[];
21
- spouse?: User;
22
- };
23
-
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
- }
48
- }
49
- },
50
- incomePerMonth: {
51
- type: 'number',
52
- min: 0
53
- }
54
- }
55
- } as any);
56
-
57
6
  test('Can add schema', () => {
58
7
  const validator = new SchemaRegistry().addSchema('something', {
59
8
  type: 'object',
@@ -153,1767 +102,7 @@ test('Throws if schema is not an object', () => {
153
102
  ).toThrow();
154
103
  });
155
104
 
156
- test('Union - Array as schema type', async () => {
157
- const validator = new SchemaRegistry()
158
- .addSchema('name', {
159
- type: 'object',
160
- properties: {
161
- name: 'string'
162
- }
163
- })
164
- .addSchema('number_or_string', ['number', 'string', 'name']);
165
-
166
- let result = await validator.schemas.number_or_string.validate(123);
167
-
168
- expect(result).toHaveProperty('valid', true);
169
-
170
- result = await validator.schemas.number_or_string.validate('some string');
171
-
172
- expect(result).toHaveProperty('valid', true);
173
-
174
- result = await validator.schemas.number_or_string.validate({});
175
-
176
- expect(result).toHaveProperty('valid', false);
177
-
178
- result = await validator.schemas.number_or_string.validate({
179
- name: 'some name'
180
- });
181
- expect(result).toHaveProperty('valid', true);
182
- });
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
-
240
- test('Validate - no schema', async () => {
241
- const validator = new SchemaRegistry();
242
- const cth = jest.fn();
243
- validator
244
- .validate(null as any, 10)
245
- .catch(cth)
246
- .then(() => {
247
- expect(cth).toBeCalled();
248
- });
249
- });
250
-
251
- test('Validate - no schema type', async () => {
252
- const validator = new SchemaRegistry();
253
- const cth = jest.fn();
254
- validator
255
- .validate(
256
- {
257
- isRequired: true
258
- } as Schema<any>,
259
- 10
260
- )
261
- .catch(cth)
262
- .then(() => {
263
- expect(cth).toBeCalled();
264
- });
265
- });
266
-
267
- test('Validate - number by value', async () => {
268
- const validator = new SchemaRegistry();
269
- const result = await validator.validate(10, 0);
270
- expect(result).toHaveProperty('valid', false);
271
- });
272
-
273
- test('Validate - number by value - 2', async () => {
274
- const validator = new SchemaRegistry();
275
- const result = await validator.validate(10, 10);
276
- expect(result).toHaveProperty('valid', true);
277
- });
278
-
279
- test('Validate - number by value - 3', async () => {
280
- const validator = new SchemaRegistry();
281
- const result = await validator.validate(10, {});
282
- expect(result).toHaveProperty('valid', false);
283
- });
284
-
285
- test('Validate - number by value - 4', async () => {
286
- const validator = new SchemaRegistry();
287
- const result = await validator.validate(10, 15);
288
- expect(result).toHaveProperty('valid', false);
289
- });
290
-
291
- test('Validate - number by name: object', async () => {
292
- const validator = new SchemaRegistry();
293
- const result = await validator.validate('number', {});
294
- expect(result).toHaveProperty('valid', false);
295
- });
296
-
297
- test('Validate - number by name: string', async () => {
298
- const validator = new SchemaRegistry();
299
- const result = await validator.validate('number', '10');
300
- expect(result).toHaveProperty('valid', false);
301
- });
302
-
303
- test('Validate - number by name - correct', async () => {
304
- const validator = new SchemaRegistry();
305
- const result = await validator.validate('number', 10);
306
- expect(result).toHaveProperty('valid', true);
307
- });
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
-
321
- test('Validate - number by schema', async () => {
322
- const validator = new SchemaRegistry();
323
- const result = await validator.validate(
324
- {
325
- type: 'number'
326
- },
327
- 10
328
- );
329
- expect(result).toHaveProperty('valid', true);
330
- });
331
-
332
- test('Validate - number by schema - not number passed', async () => {
333
- const validator = new SchemaRegistry();
334
- const result = await validator.validate(
335
- {
336
- type: 'number'
337
- },
338
- 'str'
339
- );
340
- expect(result).toHaveProperty('valid', false);
341
- });
342
-
343
- test('Validate - number by schema - min', async () => {
344
- const validator = new SchemaRegistry();
345
- const result = await validator.validate(
346
- {
347
- type: 'number',
348
- min: 1000
349
- },
350
- 10
351
- );
352
- expect(result).toHaveProperty('valid', false);
353
- });
354
-
355
- test('Validate - number by schema - min 2', async () => {
356
- const validator = new SchemaRegistry();
357
- const result = await validator.validate(
358
- {
359
- type: 'number',
360
- min: 1000
361
- },
362
- 10000
363
- );
364
- expect(result).toEqual({
365
- valid: true
366
- });
367
- });
368
-
369
- test('Validate - number by schema - min 3', async () => {
370
- const validator = new SchemaRegistry();
371
- const result = await validator.validate(
372
- {
373
- type: 'number',
374
- min: 1000
375
- },
376
- 1000
377
- );
378
- expect(result).toHaveProperty('valid', true);
379
- });
380
-
381
- test('Validate - number by schema - min 4', async () => {
382
- const validator = new SchemaRegistry();
383
- const mk = jest.fn();
384
- validator
385
- .validate(
386
- {
387
- type: 'number',
388
- min: 'string' as any as number
389
- },
390
- 10
391
- )
392
- .catch(mk)
393
- .then(() => {
394
- expect(mk).toBeCalled();
395
- });
396
- });
397
-
398
- test('Validate - number by schema - max', async () => {
399
- const validator = new SchemaRegistry();
400
- const result = await validator.validate(
401
- {
402
- type: 'number',
403
- max: 1000
404
- },
405
- 20000
406
- );
407
- expect(result).toHaveProperty('valid', false);
408
- });
409
-
410
- test('Validate - number by schema - max 2', async () => {
411
- const validator = new SchemaRegistry();
412
- const result = await validator.validate(
413
- {
414
- type: 'number',
415
- max: 40000
416
- },
417
- 10000
418
- );
419
- expect(result).toHaveProperty('valid', true);
420
- });
421
-
422
- test('Validate - number by schema - max 3', async () => {
423
- const validator = new SchemaRegistry();
424
- const result = await validator.validate(
425
- {
426
- type: 'number',
427
- max: 1000
428
- },
429
- 1000
430
- );
431
- expect(result).toHaveProperty('valid', true);
432
- });
433
-
434
- test('Validate - number by schema - max 4', async () => {
435
- const validator = new SchemaRegistry();
436
- const mk = jest.fn();
437
- validator
438
- .validate(
439
- {
440
- type: 'number',
441
- max: 'string' as any as number
442
- },
443
- 10
444
- )
445
- .catch(mk)
446
- .then(() => {
447
- expect(mk).toBeCalled();
448
- });
449
- });
450
-
451
- test('Validate - number by schema - range', async () => {
452
- const validator = new SchemaRegistry();
453
- const result = await validator.validate(
454
- {
455
- type: 'number',
456
- min: 1,
457
- max: 100
458
- },
459
- 10
460
- );
461
-
462
- expect(result).toHaveProperty('valid', true);
463
- });
464
-
465
- test('Validate - number by schema - range - 2', async () => {
466
- const validator = new SchemaRegistry();
467
- const result = await validator.validate(
468
- {
469
- type: 'number',
470
- min: -100,
471
- max: 100
472
- },
473
- -210
474
- );
475
-
476
- expect(result).toHaveProperty('valid', false);
477
- });
478
-
479
- test('Validate - number by schema - range - 3', async () => {
480
- const validator = new SchemaRegistry();
481
- const result = await validator.validate(
482
- {
483
- type: 'number',
484
- min: -100,
485
- max: 100
486
- },
487
- -100
488
- );
489
-
490
- expect(result).toHaveProperty('valid', true);
491
- });
492
-
493
- test('Validate - number by schema - range - 4', async () => {
494
- const validator = new SchemaRegistry();
495
- const result = await validator.validate(
496
- {
497
- type: 'number',
498
- min: -100,
499
- max: 100
500
- },
501
- 100
502
- );
503
-
504
- expect(result).toHaveProperty('valid', true);
505
- });
506
-
507
- test('Validate - number by schema - range - 5', async () => {
508
- const validator = new SchemaRegistry();
509
- const result = await validator.validate(
510
- {
511
- type: 'number',
512
- min: -100,
513
- max: 100
514
- },
515
- 200
516
- );
517
-
518
- expect(result).toHaveProperty('valid', false);
519
- });
520
-
521
- test('Validate - number by schema - range - 6', async () => {
522
- const validator = new SchemaRegistry();
523
- const result = await validator.validate(
524
- {
525
- type: 'number',
526
- min: -100,
527
- max: 100
528
- },
529
- 200
530
- );
531
-
532
- expect(result).toHaveProperty('valid', false);
533
- });
534
-
535
- test('Validate - number by schema - NaN', async () => {
536
- const validator = new SchemaRegistry();
537
- const result = await validator.validate(
538
- {
539
- type: 'number',
540
- min: -100,
541
- max: 100
542
- },
543
- 0 / 0
544
- );
545
- expect(result).toHaveProperty('valid', false);
546
- });
547
-
548
- test('Validate - number by schema - NaN - 2', async () => {
549
- const validator = new SchemaRegistry();
550
- const result = await validator.validate(
551
- {
552
- type: 'number',
553
- ensureNotNaN: false
554
- },
555
- 0 / 0
556
- );
557
-
558
- expect(result).toHaveProperty('valid', true);
559
- });
560
-
561
- test('Validate - number by schema - Infinity', async () => {
562
- const validator = new SchemaRegistry();
563
- const result = await validator.validate(
564
- {
565
- type: 'number'
566
- },
567
- 100 / 0
568
- );
569
-
570
- expect(result).toHaveProperty('valid', false);
571
- });
572
-
573
- test('Validate - number by schema - Infinity - 2', async () => {
574
- const validator = new SchemaRegistry();
575
- const result = await validator.validate(
576
- {
577
- type: 'number',
578
- ensureIsFinite: false
579
- },
580
- 100 / 0
581
- );
582
-
583
- expect(result).toHaveProperty('valid', true);
584
- });
585
-
586
- test('Validate - number by schema - custom validators - 1', async () => {
587
- const validator = new SchemaRegistry();
588
- const schema: NumberSchema = {
589
- type: 'number',
590
- validators: [
591
- async (value) => {
592
- if ((value & 0xb01) === 0)
593
- return {
594
- valid: false,
595
- errors: ['value should be odd!']
596
- };
597
- return {
598
- valid: true
599
- };
600
- }
601
- ]
602
- };
603
- let result = await validator.validate(schema, 101);
604
-
605
- expect(result).toHaveProperty('valid', true);
606
-
607
- result = await validator.validate(schema, 100);
608
- expect(result).toHaveProperty('valid', false);
609
- });
610
-
611
- test('Validate - number by schema - custom validators - 2', async () => {
612
- const validator = new SchemaRegistry();
613
- const schema: NumberSchema = {
614
- type: 'number',
615
- validators: [
616
- (value) => {
617
- if ((value & 0xb01) === 0)
618
- return {
619
- valid: false,
620
- errors: ['value should be odd!']
621
- };
622
- return {
623
- valid: true
624
- };
625
- },
626
- (value) => ({ valid: value > 100 })
627
- ]
628
- };
629
- let result = await validator.validate(schema, 101);
630
-
631
- expect(result).toHaveProperty('valid', true);
632
-
633
- result = await validator.validate(schema, 99);
634
- expect(result).toHaveProperty('valid', false);
635
-
636
- result = await validator.validate(schema, 100);
637
- expect(result).toHaveProperty('valid', false);
638
- });
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
-
662
- test('Validate - boolean - 1', async () => {
663
- const validator = new SchemaRegistry();
664
- const result = await validator.validate(
665
- {
666
- type: 'boolean'
667
- },
668
- 300
669
- );
670
-
671
- expect(result).toHaveProperty('valid', false);
672
- });
673
-
674
- test('Validate - boolean - 2', async () => {
675
- const validator = new SchemaRegistry();
676
- const result = await validator.validate(
677
- {
678
- type: 'boolean'
679
- },
680
- true
681
- );
682
-
683
- expect(result).toHaveProperty('valid', true);
684
- });
685
-
686
- test('Validate - boolean - 3', async () => {
687
- const validator = new SchemaRegistry();
688
- const result = await validator.validate(
689
- {
690
- type: 'boolean'
691
- },
692
- false
693
- );
694
-
695
- expect(result).toHaveProperty('valid', true);
696
- });
697
-
698
- test('Validate - boolean - 4', async () => {
699
- const validator = new SchemaRegistry();
700
- const result = await validator.validate(
701
- {
702
- type: 'boolean',
703
- equals: true
704
- },
705
- false
706
- );
707
-
708
- expect(result).toHaveProperty('valid', false);
709
- });
710
-
711
- test('Validate - boolean - 5', async () => {
712
- const validator = new SchemaRegistry();
713
- const result = await validator.validate(
714
- {
715
- type: 'boolean',
716
- equals: false
717
- },
718
- false
719
- );
720
-
721
- expect(result).toHaveProperty('valid', true);
722
- });
723
-
724
- test('Validate - boolean - 6', async () => {
725
- const validator = new SchemaRegistry();
726
- const result = await validator.validate('boolean', false);
727
-
728
- expect(result).toHaveProperty('valid', true);
729
- });
730
-
731
- test('Validate - boolean - 7', async () => {
732
- const validator = new SchemaRegistry();
733
- const result = await validator.validate('boolean', '123');
734
-
735
- expect(result).toHaveProperty('valid', false);
736
- });
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
-
814
- test('Validate - string - 1', async () => {
815
- const validator = new SchemaRegistry();
816
- const result = await validator.validate('string', '12345');
817
- expect(result).toHaveProperty('valid', true);
818
- });
819
-
820
- test('Validate - string - 2', async () => {
821
- const validator = new SchemaRegistry();
822
- const result = await validator.validate('string', 12345);
823
- expect(result).toHaveProperty('valid', false);
824
- });
825
-
826
- test('Validate - string - 3', async () => {
827
- const validator = new SchemaRegistry();
828
- const result = await validator.validate('12345', '12345');
829
- expect(result).toHaveProperty('valid', true);
830
- });
831
-
832
- test('Validate - string - 4', async () => {
833
- const validator = new SchemaRegistry();
834
- const result = await validator.validate('12345', '123456');
835
- expect(result).toHaveProperty('valid', false);
836
- });
837
-
838
- test('Validate - string - 5', async () => {
839
- const validator = new SchemaRegistry();
840
- const result = await validator.validate('12345', 123456);
841
- expect(result).toHaveProperty('valid', false);
842
- });
843
-
844
- test('Validate - string - schema object - 1', async () => {
845
- const validator = new SchemaRegistry();
846
- const result = await validator.validate(
847
- {
848
- type: 'string',
849
- equals: '123456'
850
- },
851
- '123456'
852
- );
853
- expect(result).toHaveProperty('valid', true);
854
- });
855
-
856
- test('Validate - string - schema object - 2', async () => {
857
- const validator = new SchemaRegistry();
858
- const result = await validator.validate(
859
- {
860
- type: 'string',
861
- equals: '123456'
862
- },
863
- '12345'
864
- );
865
- expect(result).toHaveProperty('valid', false);
866
- });
867
-
868
- test('Validate - string - schema object - 3', async () => {
869
- const validator = new SchemaRegistry();
870
- const result = await validator.validate(
871
- {
872
- type: 'string',
873
- equals: '123456'
874
- },
875
- 1234
876
- );
877
- expect(result).toHaveProperty('valid', false);
878
- });
879
-
880
- test('Validate - string - length control - 1', async () => {
881
- const validator = new SchemaRegistry();
882
- let result = await validator.validate(
883
- {
884
- type: 'string',
885
- minLength: 2,
886
- maxLength: 3
887
- },
888
- 'U'
889
- );
890
- expect(result).toHaveProperty('valid', false);
891
-
892
- result = await validator.validate(
893
- {
894
- type: 'string',
895
- minLength: 2,
896
- maxLength: 3
897
- },
898
- 'US'
899
- );
900
- expect(result).toHaveProperty('valid', true);
901
-
902
- result = await validator.validate(
903
- {
904
- type: 'string',
905
- minLength: 2,
906
- maxLength: 3
907
- },
908
- 'USA'
909
- );
910
- expect(result).toHaveProperty('valid', true);
911
-
912
- result = await validator.validate(
913
- {
914
- type: 'string',
915
- minLength: 2,
916
- maxLength: 3
917
- },
918
- 'USA'
919
- );
920
- expect(result).toHaveProperty('valid', true);
921
-
922
- result = await validator.validate(
923
- {
924
- type: 'string',
925
- minLength: 2,
926
- maxLength: 3
927
- },
928
- 'United States of America'
929
- );
930
- expect(result).toHaveProperty('valid', false);
931
- });
932
-
933
- test('Validate - array - 1', async () => {
934
- const validator = new SchemaRegistry();
935
- let result = await validator.validate('array', []);
936
- expect(result).toHaveProperty('valid', true);
937
-
938
- result = await validator.validate('array', 123);
939
- expect(result).toHaveProperty('valid', false);
940
- });
941
-
942
- test('Validate - array - size control - 1', async () => {
943
- const validator = new SchemaRegistry();
944
- let result = await validator.validate(
945
- {
946
- type: 'array',
947
- minLength: 1,
948
- maxLength: 3
949
- },
950
- []
951
- );
952
- expect(result).toHaveProperty('valid', false);
953
-
954
- result = await validator.validate(
955
- {
956
- type: 'array',
957
- minLength: 1,
958
- maxLength: 3
959
- },
960
- [1]
961
- );
962
- expect(result).toHaveProperty('valid', true);
963
-
964
- result = await validator.validate(
965
- {
966
- type: 'array',
967
- minLength: 1,
968
- maxLength: 3
969
- },
970
- [1, 2]
971
- );
972
- expect(result).toHaveProperty('valid', true);
973
-
974
- result = await validator.validate(
975
- {
976
- type: 'array',
977
- minLength: 1,
978
- maxLength: 3
979
- },
980
- [1, 2, 3]
981
- );
982
- expect(result).toHaveProperty('valid', true);
983
-
984
- result = await validator.validate(
985
- {
986
- type: 'array',
987
- minLength: 1,
988
- maxLength: 3
989
- },
990
- [1, 2, 3, 4]
991
- );
992
- expect(result).toHaveProperty('valid', false);
993
- });
994
-
995
- test('Validate - array - ofType - 1', async () => {
996
- const validator = new SchemaRegistry();
997
- let result = await validator.validate(
998
- {
999
- type: 'array',
1000
- ofType: 'number'
1001
- },
1002
- ['1', 2, 3]
1003
- );
1004
- expect(result).toHaveProperty('valid', false);
1005
-
1006
- result = await validator.validate(
1007
- {
1008
- type: 'array',
1009
- ofType: 'number'
1010
- },
1011
- [1, 2, 3]
1012
- );
1013
- expect(result).toHaveProperty('valid', true);
1014
-
1015
- result = await validator.validate(
1016
- {
1017
- type: 'array',
1018
- ofType: {
1019
- type: 'number',
1020
- min: 10
1021
- }
1022
- },
1023
- [-1, 12, 13]
1024
- );
1025
- expect(result).toHaveProperty('valid', false);
1026
- });
1027
-
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
1051
- );
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 = {
1058
- id: 1,
1059
- name: {
1060
- first: 'Andrew',
1061
- last: 'Zolotukhin'
1062
- },
1063
- incomePerMonth: 134234
1064
- };
1065
-
1066
- let result = await validator.validate('user', user);
1067
-
1068
- expect(result).toHaveProperty('valid', true);
1069
-
1070
- result = await validator.validate('user', 10);
1071
-
1072
- expect(result).toHaveProperty('valid', false);
1073
-
1074
- result = await validator.validate(
1075
- {
1076
- type: 'object',
1077
- properties: {
1078
- name: {
1079
- type: 'string',
1080
- maxLength: 5
1081
- },
1082
- address: {
1083
- type: 'object',
1084
- properties: {
1085
- street: 'string',
1086
- house: {
1087
- type: 'number',
1088
- isRequired: false
1089
- }
1090
- }
1091
- }
1092
- }
1093
- },
1094
- {
1095
- name: 'Andr',
1096
- address: {
1097
- street: 'something'
1098
- }
1099
- }
1100
- );
1101
-
1102
- expect(result).toHaveProperty('valid', true);
1103
-
1104
- result = await validator.validate(
1105
- {
1106
- type: 'object',
1107
- properties: {
1108
- a: 'number',
1109
- b: 'number'
1110
- },
1111
- validators: [
1112
- (value: { a: number; b: number }) => {
1113
- if (value.a + value.b === 5) {
1114
- return {
1115
- valid: true
1116
- };
1117
- }
1118
- return {
1119
- valid: false,
1120
- error: ['some error']
1121
- };
1122
- }
1123
- ]
1124
- },
1125
- {
1126
- a: 1,
1127
- b: 3
1128
- }
1129
- );
1130
- expect(result).toHaveProperty('valid', false);
1131
- });
1132
-
1133
- test('Validate - object - 2', async () => {
1134
- const validator = new SchemaRegistry().addSchema(
1135
- 'user',
1136
- deepExtend(getUserSchema(), {
1137
- validators: [
1138
- (value): ValidationResult => {
1139
- if (value.bornAt < new Date(1990, 0, 1)) {
1140
- return {
1141
- valid: true
1142
- };
1143
- }
1144
- return {
1145
- valid: false,
1146
- errors: [`bornAt should be before Jan 1 1990`]
1147
- };
1148
- }
1149
- ]
1150
- }) as any as ObjectSchema<any>
1151
- );
1152
- const user: User = {
1153
- id: 1,
1154
- name: {
1155
- first: 'Andrew',
1156
- last: 'Zolotukhin'
1157
- },
1158
- bornAt: new Date(1996, 4, 30),
1159
- incomePerMonth: 134234,
1160
- aliases: []
1161
- };
1162
-
1163
- const result = await validator.validate('user', user);
1164
- expect(result).toHaveProperty('valid', false);
1165
- });
1166
-
1167
- test('Validate - one of - 1', async () => {
1168
- const validator = new SchemaRegistry();
1169
-
1170
- let result = await validator.validate(['number', 'object'], 'something');
1171
- expect(result).toHaveProperty('valid', false);
1172
-
1173
- result = await validator.validate(['number', 'string'], 'something');
1174
- expect(result).toHaveProperty('valid', true);
1175
-
1176
- result = await validator.validate(
1177
- [
1178
- 'number',
1179
- 'string',
1180
- {
1181
- type: 'object',
1182
- properties: {
1183
- first: 'string',
1184
- last: 'string'
1185
- }
1186
- }
1187
- ],
1188
- {
1189
- first: 'something',
1190
- last: 'another'
1191
- }
1192
- );
1193
- expect(result).toHaveProperty('valid', true);
1194
- });
1195
-
1196
- test('Validate schema - 1', async () => {
1197
- const authorsReportSpecificationSchema = {
1198
- type: 'object',
1199
- properties: {
1200
- type: {
1201
- type: 'string',
1202
- equals: 'author'
1203
- },
1204
- start: 'Date',
1205
- end: 'Date',
1206
- selectionStart: 'Date',
1207
- selectionEnd: 'Date',
1208
- granularity: ['day', 'week', 'month'],
1209
- metrics: {
1210
- type: 'array',
1211
- ofType: [
1212
- 'articlesPublished',
1213
- 'searchReferrers',
1214
- 'socialReferrers',
1215
- 'views',
1216
- 'visitors',
1217
- 'newVisitors'
1218
- ]
1219
- },
1220
- filters: {
1221
- type: 'object',
1222
- properties: {
1223
- author: 'AuthorFilter'
1224
- // publication: 'PublicationFilter',
1225
- // article: 'ArticleFilter'
1226
- }
1227
- }
1228
- },
1229
- validators: [
1230
- (value) =>
1231
- value.start <= value.end &&
1232
- value.selectionStart <= value.selectionEnd &&
1233
- value.selectionStart >= value.start &&
1234
- value.selectionStart <= value.end &&
1235
- value.selectionEnd >= value.start &&
1236
- value.selectionEnd <= value.end
1237
- ? {
1238
- valid: true
1239
- }
1240
- : {
1241
- valid: false,
1242
- errors: [
1243
- 'selectionStart <=> selectionEnd should be inside the start <=> end interval'
1244
- ]
1245
- }
1246
- ]
1247
- };
1248
-
1249
- const validator = new SchemaRegistry()
1250
- .addSchema('Date', {
1251
- type: 'object',
1252
- validators: [
1253
- (value) =>
1254
- value instanceof Date && !Number.isNaN(value)
1255
- ? {
1256
- valid: true
1257
- }
1258
- : {
1259
- valid: false,
1260
- errors: ['should be a valid Date object']
1261
- }
1262
- ]
1263
- })
1264
- .addSchema('EqualsFilterCondition', {
1265
- type: 'object',
1266
- properties: {
1267
- operation: {
1268
- type: 'string',
1269
- equals: 'equals'
1270
- },
1271
- value: ['object', 'string', 'number']
1272
- }
1273
- })
1274
- .addSchema('GreaterThanFilterCondition', {
1275
- type: 'object',
1276
- properties: {
1277
- operation: {
1278
- type: 'string',
1279
- equals: 'greater_than'
1280
- },
1281
- value: 'number'
1282
- }
1283
- })
1284
- .addSchema('LessThanFilterCondition', {
1285
- type: 'object',
1286
- properties: {
1287
- operation: {
1288
- type: 'string',
1289
- equals: 'less_than'
1290
- },
1291
- value: 'number'
1292
- }
1293
- })
1294
- .addSchema('ContainsFilterCondition', {
1295
- type: 'object',
1296
- properties: {
1297
- operation: {
1298
- type: 'string',
1299
- equals: 'contains'
1300
- },
1301
- value: [
1302
- 'string',
1303
- 'number',
1304
- {
1305
- type: 'array',
1306
- ofType: ['string', 'number']
1307
- }
1308
- ]
1309
- }
1310
- })
1311
- .addSchema('LikeFilterCondition', {
1312
- type: 'object',
1313
- properties: {
1314
- operation: 'like',
1315
- value: 'string'
1316
- }
1317
- })
1318
- .addSchema('BetweenFilterCondition', {
1319
- type: 'object',
1320
- properties: {
1321
- operation: 'between',
1322
- from: 'number',
1323
- to: 'number'
1324
- },
1325
- validators: [
1326
- (value) =>
1327
- value.from <= value.to
1328
- ? { valid: true }
1329
- : { valid: false, error: ['from must be <= to'] }
1330
- ]
1331
- })
1332
- .addSchema('StringFilterCondition', [
1333
- 'EqualsFilterCondition',
1334
- 'LikeFilterCondition'
1335
- ])
1336
- .addSchema('AuthorFilter', {
1337
- type: 'object',
1338
- properties: {
1339
- fullName: 'StringFilterCondition'
1340
- }
1341
- })
1342
- .addSchema(
1343
- 'AuthorsReportSpecification',
1344
- authorsReportSpecificationSchema as ObjectSchema<any>
1345
- );
1346
-
1347
- /**
1348
- * @type {import('smg-iq/editorial-analytics.reports').AuthorsReportSpecification}
1349
- */
1350
- let reportSpec = {
1351
- type: 'author',
1352
- start: new Date(2021, 0, 1),
1353
- end: new Date(),
1354
- selectionStart: new Date(2022, 0, 1),
1355
- selectionEnd: new Date(2022, 2, 1),
1356
- granularity: 'day',
1357
- metrics: [
1358
- 'articlesPublished',
1359
- 'searchReferrers',
1360
- 'socialReferrers',
1361
- 'views',
1362
- 'visitors',
1363
- 'newVisitors'
1364
- ],
1365
- filters: {
1366
- author: {
1367
- fullName: {
1368
- operation: 'between',
1369
- value: 'some name'
1370
- }
1371
- }
1372
- }
1373
- };
1374
-
1375
- let result = await validator.schemas.AuthorsReportSpecification.validate(
1376
- reportSpec
1377
- );
1378
-
1379
- expect(result).toHaveProperty('valid', false);
1380
-
1381
- reportSpec = {
1382
- type: 'author',
1383
- start: new Date(2021, 0, 1),
1384
- end: new Date(),
1385
- selectionStart: new Date(2022, 0, 1),
1386
- selectionEnd: new Date(2022, 2, 1),
1387
- granularity: 'day',
1388
- metrics: [
1389
- 'articlesPublished',
1390
- 'searchReferrers',
1391
- 'socialReferrers',
1392
- 'views',
1393
- 'visitors',
1394
- 'newVisitors'
1395
- ],
1396
- filters: {
1397
- author: {
1398
- fullName: {
1399
- operation: 'equals',
1400
- value: 'some name'
1401
- }
1402
- }
1403
- }
1404
- };
1405
-
1406
- result = await validator.schemas.AuthorsReportSpecification.validate(
1407
- reportSpec
1408
- );
1409
-
1410
- expect(result).toHaveProperty('valid', true);
1411
- });
1412
-
1413
- test('Validate schema - 2', async () => {
1414
- const validator = new SchemaRegistry()
1415
- .addSchema('Date', {
1416
- type: 'object',
1417
- validators: [
1418
- (value) =>
1419
- value instanceof Date && !Number.isNaN(value)
1420
- ? {
1421
- valid: true
1422
- }
1423
- : {
1424
- valid: false,
1425
- errors: ['should be a valid Date object']
1426
- }
1427
- ]
1428
- })
1429
- .addSchema('Module.Schema1', {
1430
- type: 'object',
1431
- properties: {
1432
- a: 'string'
1433
- }
1434
- })
1435
- .addSchema('Module.Schema2', {
1436
- type: 'object',
1437
- properties: {
1438
- b: 'number'
1439
- }
1440
- });
1441
-
1442
- const result = await validator.validate(
1443
- {
1444
- type: 'object',
1445
- properties: {
1446
- date: {
1447
- type: 'alias',
1448
- schemaName: 'Date',
1449
- isRequired: false
1450
- }
1451
- }
1452
- },
1453
- {}
1454
- );
1455
-
1456
- expect(result).toHaveProperty('valid', true);
1457
- });
1458
-
1459
- test('Not required alternative schema alias', async () => {
1460
- const validator = new SchemaRegistry()
1461
- .addSchema('Alternate1', {
1462
- properties: {
1463
- a1: 'string'
1464
- }
1465
- })
1466
- .addSchema('Alternate2', {
1467
- properties: {
1468
- a2: 'string'
1469
- }
1470
- })
1471
- .addSchema('Alternate', ['Alternate1', 'Alternate2']);
1472
-
1473
- let result = await validator.validate(
1474
- {
1475
- type: 'alias',
1476
- isRequired: false,
1477
- schemaName: 'Alternate'
1478
- },
1479
- undefined
1480
- );
1481
-
1482
- expect(result).toHaveProperty('valid', true);
1483
-
1484
- result = await validator.validate(
1485
- {
1486
- type: 'alias',
1487
- isRequired: false,
1488
- schemaName: 'Alternate'
1489
- },
1490
- {
1491
- a2: 'something'
1492
- }
1493
- );
1494
-
1495
- expect(result).toHaveProperty('valid', true);
1496
-
1497
- result = await validator.validate(
1498
- {
1499
- type: 'alias',
1500
- isRequired: false,
1501
- schemaName: 'Alternate'
1502
- },
1503
- 'invalid'
1504
- );
1505
-
1506
- expect(result).toHaveProperty('valid', false);
1507
- });
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
-
1546
105
  test('Preprocessors - 1', async () => {
1547
- const validator = new SchemaRegistry().addSchema('Date', {
1548
- type: 'object',
1549
- validators: [
1550
- (value) =>
1551
- value instanceof Date && !Number.isNaN(value)
1552
- ? {
1553
- valid: true
1554
- }
1555
- : {
1556
- valid: false,
1557
- errors: ['should be a valid Date object']
1558
- }
1559
- ]
1560
- });
1561
-
1562
- const schema: Schema<{ name: string; bornAt: Date }> = {
1563
- type: 'object',
1564
- properties: {
1565
- bornAt: {
1566
- type: 'alias',
1567
- schemaName: 'Date'
1568
- }
1569
- },
1570
- preprocessors: {
1571
- bornAt: (value: any): Date | undefined => {
1572
- const time = Date.parse(
1573
- (value as Record<string, unknown>).toString()
1574
- );
1575
- if (Number.isNaN(time)) return undefined;
1576
- return new Date(time);
1577
- }
1578
- }
1579
- } as any;
1580
-
1581
- const result = await validator.validate(schema as Schema, {
1582
- bornAt: new Date().toJSON()
1583
- });
1584
- expect(result).toHaveProperty('valid', true);
1585
- });
1586
-
1587
- test('Preprocessors - 2', async () => {
1588
- const validator = new SchemaRegistry().addSchema('Date', {
1589
- validators: [
1590
- (value) =>
1591
- value instanceof Date && !Number.isNaN(value)
1592
- ? {
1593
- valid: true
1594
- }
1595
- : {
1596
- valid: false,
1597
- errors: ['should be a valid Date object']
1598
- }
1599
- ]
1600
- });
1601
-
1602
- let schema: Schema<{ bornAt: Date; diedAt?: Date }> = {
1603
- type: 'object',
1604
- properties: {
1605
- bornAt: 'Date'
1606
- },
1607
- preprocessors: {
1608
- bornAt: 'StringToDate'
1609
- }
1610
- } as any;
1611
-
1612
- validator.addPreprocessor(
1613
- 'StringToDate',
1614
- (value: unknown): Date | undefined => {
1615
- const time = Date.parse(
1616
- (value as Record<string, unknown>).toString()
1617
- );
1618
- if (Number.isNaN(time)) return undefined;
1619
- return new Date(time);
1620
- }
1621
- );
1622
-
1623
- expect(() =>
1624
- validator.addPreprocessor(
1625
- 'StringToDate',
1626
- (value: unknown): Date | undefined => {
1627
- const time = Date.parse(
1628
- (value as Record<string, unknown>).toString()
1629
- );
1630
- if (Number.isNaN(time)) return undefined;
1631
- return new Date(time);
1632
- }
1633
- )
1634
- ).toThrow();
1635
-
1636
- const result = await validator.validate(schema as Schema, {
1637
- bornAt: new Date().toJSON()
1638
- });
1639
- expect(result).toHaveProperty('valid', true);
1640
-
1641
- schema = {
1642
- type: 'object',
1643
- properties: {
1644
- bornAt: 'Date',
1645
- diedAt: 'Date'
1646
- },
1647
- preprocessors: {
1648
- bornAt: 'StringToDate',
1649
- diedAt: 'Unregistered'
1650
- }
1651
- } as any;
1652
- expect(async () => {
1653
- await validator.validate(schema as Schema, {
1654
- bornAt: new Date().toJSON()
1655
- });
1656
- }).rejects.toBeInstanceOf(Error);
1657
- });
1658
-
1659
- test('Preprocessors - 3', async () => {
1660
- const validator = new SchemaRegistry().addSchema('Date', {
1661
- validators: [
1662
- (value: any) =>
1663
- value instanceof Date && !Number.isNaN(value)
1664
- ? {
1665
- valid: true
1666
- }
1667
- : {
1668
- valid: false,
1669
- errors: ['should be a valid Date object']
1670
- }
1671
- ]
1672
- });
1673
-
1674
- validator.addPreprocessor(
1675
- 'StringToDate',
1676
- (value: unknown): Date | undefined => {
1677
- const time = Date.parse(
1678
- (value as Record<string, unknown>).toString()
1679
- );
1680
- if (Number.isNaN(time)) return undefined;
1681
- return new Date(time);
1682
- }
1683
- );
1684
-
1685
- let obj = [new Date().toJSON()];
1686
-
1687
- let result = await validator.validate(
1688
- {
1689
- preprocessor: 'StringToDate',
1690
- type: 'array',
1691
- ofType: 'Date'
1692
- },
1693
- obj
1694
- );
1695
- expect(result).toHaveProperty('valid', true);
1696
-
1697
- obj = [new Date().toJSON()];
1698
- result = await validator.validate(
1699
- {
1700
- preprocessor: (value: unknown): Date | undefined => {
1701
- const time = Date.parse(
1702
- (value as Record<string, unknown>).toString()
1703
- );
1704
- if (Number.isNaN(time)) return undefined;
1705
- return new Date(time);
1706
- },
1707
- type: 'array',
1708
- ofType: 'Date'
1709
- },
1710
- obj
1711
- );
1712
- expect(result).toHaveProperty('valid', true);
1713
-
1714
- obj = ['sdfsdf12', new Date().toJSON()];
1715
- result = await validator.validate(
1716
- {
1717
- preprocessor: (value: unknown): Date | undefined => {
1718
- const time = Date.parse(
1719
- (value as Record<string, unknown>).toString()
1720
- );
1721
- if (Number.isNaN(time)) return undefined;
1722
- return new Date(time);
1723
- },
1724
- type: 'array',
1725
- ofType: 'Date'
1726
- },
1727
- obj
1728
- );
1729
- expect(result).toHaveProperty('valid', false);
1730
- });
1731
-
1732
- test('Preprocessors - 3', async () => {
1733
- const validator = new SchemaRegistry();
1734
-
1735
- type SomeType = { age: number; marriedAt: number };
1736
-
1737
- const schema: Schema<SomeType> = {
1738
- type: 'object',
1739
- properties: {
1740
- age: 'number',
1741
- marriedAt: 'number'
1742
- },
1743
- preprocessors: {
1744
- age: (): number => 40,
1745
- '*': (value: SomeType): void => {
1746
- if (value.marriedAt > value.age) {
1747
- value.marriedAt = value.age;
1748
- }
1749
- }
1750
- }
1751
- } as any;
1752
-
1753
- const obj = {
1754
- age: 50,
1755
- marriedAt: 80
1756
- };
1757
- await validator.validate(schema as Schema, obj);
1758
- expect(obj).toHaveProperty('marriedAt', 40);
1759
- });
1760
-
1761
- test('Preprocessors - 4', async () => {
1762
- const validator = new SchemaRegistry().addSchema('Date', {
1763
- validators: [
1764
- (value: any) =>
1765
- value instanceof Date && !Number.isNaN(value)
1766
- ? {
1767
- valid: true
1768
- }
1769
- : {
1770
- valid: false,
1771
- errors: ['should be a valid Date object']
1772
- }
1773
- ]
1774
- });
1775
-
1776
- validator.addPreprocessor(
1777
- 'StringToDate',
1778
- (value: unknown): Date | undefined => {
1779
- const time = Date.parse(
1780
- (value as Record<string, unknown>).toString()
1781
- );
1782
- if (Number.isNaN(time)) return undefined;
1783
- return new Date(time);
1784
- }
1785
- );
1786
-
1787
- let obj = [new Date().toJSON()];
1788
-
1789
- let result = await validator.validate(
1790
- {
1791
- preprocessor: 'StringToDate',
1792
- type: 'array',
1793
- ofType: 'Date'
1794
- },
1795
- obj
1796
- );
1797
- expect(result).toHaveProperty('valid', true);
1798
-
1799
- obj = [new Date().toJSON()];
1800
- result = await validator.validate(
1801
- {
1802
- preprocessor: (value: unknown): Date | undefined => {
1803
- const time = Date.parse(
1804
- (value as Record<string, unknown>).toString()
1805
- );
1806
- if (Number.isNaN(time)) return undefined;
1807
- return new Date(time);
1808
- },
1809
- type: 'array',
1810
- ofType: 'Date'
1811
- },
1812
- obj
1813
- );
1814
- expect(result).toHaveProperty('valid', true);
1815
-
1816
- obj = ['sdfsdf12', new Date().toJSON()];
1817
- result = await validator.validate(
1818
- {
1819
- preprocessor: (value: unknown): Date | undefined => {
1820
- const time = Date.parse(
1821
- (value as Record<string, unknown>).toString()
1822
- );
1823
- if (Number.isNaN(time)) return undefined;
1824
- return new Date(time);
1825
- },
1826
- type: 'array',
1827
- ofType: 'Date'
1828
- },
1829
- obj
1830
- );
1831
- expect(result).toHaveProperty('valid', false);
1832
- });
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
106
  expect(() => {
1918
107
  new SchemaRegistry().addPreprocessor('BornAt', 123 as any);
1919
108
  }).toThrow();
@@ -1927,106 +116,3 @@ test('Submodules - 1', async () => {
1927
116
  expect(result).toHaveProperty('Module1');
1928
117
  expect(result).toHaveProperty('Module1.Schema1');
1929
118
  });
1930
-
1931
- test('Submodules - 2', async () => {
1932
- const validator = new SchemaRegistry()
1933
- .addSchema('Module1.Schema1', {})
1934
- .addSchema('Module1.Schema2', {
1935
- type: 'object',
1936
- properties: {
1937
- a: 'number'
1938
- }
1939
- });
1940
-
1941
- const result = validator.schemas;
1942
-
1943
- expect(result).toHaveProperty('Module1');
1944
- expect(result).toHaveProperty('Module1.Schema1');
1945
- expect(result).toHaveProperty('Module1.Schema2');
1946
-
1947
- const result2 = await validator.schemas.Module1.Schema2.validate({
1948
- a: 234
1949
- });
1950
- expect(result2).toHaveProperty('valid', true);
1951
- });
1952
-
1953
- test('Submodules - 3', async () => {
1954
- const validator = new SchemaRegistry()
1955
- .addSchema('Module1.Schema1', {
1956
- type: 'object',
1957
- properties: {
1958
- b: 'number'
1959
- }
1960
- })
1961
- .addSchema('Module1.Schema2', {
1962
- type: 'object',
1963
- properties: {
1964
- a: {
1965
- type: 'alias',
1966
- schemaName: 'Module1.Schema1'
1967
- }
1968
- }
1969
- });
1970
-
1971
- const result2 = await validator.schemas.Module1.Schema2.validate({
1972
- a: {
1973
- b: 20
1974
- }
1975
- });
1976
- expect(result2).toHaveProperty('valid', true);
1977
- });
1978
-
1979
- test('Submodules - 4', async () => {
1980
- const validator = new SchemaRegistry()
1981
- .addSchema('Module1.Schema1', {
1982
- properties: {
1983
- b: 'number'
1984
- }
1985
- })
1986
- .addSchema('Module1.Schema2', {
1987
- properties: {
1988
- a: {
1989
- type: 'alias',
1990
- schemaName: 'Module1.Schema3'
1991
- }
1992
- }
1993
- });
1994
-
1995
- await validator.schemas.Module1.Schema2.validate({
1996
- a: {
1997
- b: 20
1998
- }
1999
- }).catch((e) => expect(e).toBeInstanceOf(Error));
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
- });