perfect-payload 1.2.0 → 1.2.2-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.
package/README.md CHANGED
@@ -19,30 +19,24 @@ import { perfectPayload } from "perfect-payload";
19
19
 
20
20
  const payload = {
21
21
  name: "Kiran",
22
-
23
22
  email: "kiran@example.com",
24
-
25
23
  age: 29,
26
24
  };
27
25
 
28
26
  const validationRules = {
29
27
  name: {
30
28
  mandatory: true,
31
-
32
29
  type: "string",
33
30
  },
34
31
 
35
32
  email: {
36
33
  mandatory: true,
37
-
38
34
  type: "email",
39
35
  },
40
36
 
41
37
  age: {
42
38
  mandatory: true,
43
-
44
39
  type: "number",
45
-
46
40
  min: 18,
47
41
  },
48
42
  };
@@ -57,21 +51,13 @@ console.log(result);
57
51
  ```js
58
52
 
59
53
  {
60
-
61
54
    statusCode: 200,
62
-
63
55
    valid: true,
64
-
65
56
    validatedPayload: {
66
-
67
57
      name: "Kiran",
68
-
69
58
      email: "kiran@example.com",
70
-
71
59
      age: 29
72
-
73
60
    }
74
-
75
61
  }
76
62
  ```
77
63
 
@@ -85,27 +71,16 @@ to safely overwrite request.body or assign it to a new request property
85
71
  ```js
86
72
 
87
73
  {
88
-
89
74
    statusCode: 400,
90
-
91
75
    valid: false,
92
-
93
76
    message: "One or more attribute values are invalid",
94
-
95
77
    errors: [
96
-
97
78
      {
98
-
99
79
        path: "email",
100
-
101
80
        code: "INVALID_EMAIL",
102
-
103
81
        message: "Invalid email format for attribute email"
104
-
105
82
      }
106
-
107
83
    ]
108
-
109
84
  }
110
85
  ```
111
86
 
@@ -114,13 +89,9 @@ Each error returned by `perfectPayload()` contains:
114
89
  ```js
115
90
 
116
91
  {
117
-
118
92
    path: "field.path",
119
-
120
93
    code: "ERROR_CODE",
121
-
122
94
    message: "Human readable validation message"
123
-
124
95
  }
125
96
  ```
126
97
 
@@ -160,9 +131,7 @@ while the new `perfectPayload()` API returns structured errors:
160
131
  errors: [
161
132
  {
162
133
  path: "email",
163
-
164
134
  code: "INVALID_EMAIL",
165
-
166
135
  message: "Invalid email format for attribute email",
167
136
  },
168
137
  ];
@@ -227,7 +196,6 @@ Example:
227
196
  const rules = {
228
197
  address: {
229
198
  type: "object",
230
-
231
199
  allowEmptyObject: false,
232
200
  },
233
201
  };
@@ -249,7 +217,6 @@ Example:
249
217
  const rules = {
250
218
  products: {
251
219
  type: "array",
252
-
253
220
  allowEmptyArray: false,
254
221
  },
255
222
  };
@@ -268,31 +235,18 @@ Supported values:
268
235
  ```text
269
236
 
270
237
  number
271
-
272
238
  string
273
-
274
239
  boolean
275
-
276
240
  email
277
-
278
241
  url
279
-
280
242
  enum
281
-
282
243
  uuid
283
-
284
244
  uuidv1
285
-
286
245
  uuidv3
287
-
288
246
  uuidv4
289
-
290
247
  uuidv5
291
-
292
248
  objectId
293
-
294
249
  array
295
-
296
250
  object
297
251
  ```
298
252
 
@@ -303,11 +257,9 @@ const rules = {
303
257
  age: {
304
258
  type: "number",
305
259
  },
306
-
307
260
  email: {
308
261
  type: "email",
309
262
  },
310
-
311
263
  active: {
312
264
  type: "boolean",
313
265
  },
@@ -328,7 +280,6 @@ Example:
328
280
  const rules = {
329
281
  status: {
330
282
  type: "enum",
331
-
332
283
  enumValues: ["active", "inactive", "blocked", 1, 0],
333
284
  },
334
285
  };
@@ -348,7 +299,6 @@ Example:
348
299
  const rules = {
349
300
  status: {
350
301
  type: "enum",
351
-
352
302
  enumValues: ["active", "inactive", "blocked"],
353
303
  },
354
304
  };
@@ -361,23 +311,14 @@ Possible error codes for types:
361
311
  ```text
362
312
 
363
313
  INVALID_TYPE
364
-
365
314
  INVALID_EMAIL
366
-
367
315
  INVALID_URL
368
-
369
316
  INVALID_ENUM
370
-
371
317
  INVALID_UUID
372
-
373
318
  INVALID_UUID_V1
374
-
375
319
  INVALID_UUID_V3
376
-
377
320
  INVALID_UUID_V4
378
-
379
321
  INVALID_UUID_V5
380
-
381
322
  INVALID_OBJECT_ID
382
323
  ```
383
324
 
@@ -395,7 +336,6 @@ Example:
395
336
  const rules = {
396
337
  employeeCode: {
397
338
  type: "string",
398
-
399
339
  regex: /^[A-Z]{3}[0-9]{3}$/,
400
340
  },
401
341
  };
@@ -417,7 +357,6 @@ Example:
417
357
  const rules = {
418
358
  username: {
419
359
  type: "string",
420
-
421
360
  minLength: 5,
422
361
  },
423
362
  };
@@ -439,7 +378,6 @@ Example:
439
378
  const rules = {
440
379
  username: {
441
380
  type: "string",
442
-
443
381
  maxLength: 20,
444
382
  },
445
383
  };
@@ -461,7 +399,6 @@ Example:
461
399
  const rules = {
462
400
  quantity: {
463
401
  type: "number",
464
-
465
402
  preventDecimal: true,
466
403
  },
467
404
  };
@@ -483,7 +420,6 @@ Example:
483
420
  const rules = {
484
421
  age: {
485
422
  type: "number",
486
-
487
423
  min: 18,
488
424
  },
489
425
  };
@@ -505,7 +441,6 @@ Example:
505
441
  const rules = {
506
442
  quantity: {
507
443
  type: "number",
508
-
509
444
  max: 100,
510
445
  },
511
446
  };
@@ -527,7 +462,6 @@ Example:
527
462
  const rules = {
528
463
  marks: {
529
464
  type: "number",
530
-
531
465
  range: "0-100",
532
466
  },
533
467
  };
@@ -547,10 +481,8 @@ Example:
547
481
  const rules = {
548
482
  marks: {
549
483
  type: "array",
550
-
551
484
  elementConstraints: {
552
485
  type: "number",
553
-
554
486
  range: "0-100",
555
487
  },
556
488
  },
@@ -564,13 +496,9 @@ Example error:
564
496
  {
565
497
 
566
498
    path: "marks[2]",
567
-
568
499
    code: "OUT_OF_RANGE",
569
-
570
500
    message:
571
-
572
501
      "Attribute marks[2] should have a value between 0 and 100"
573
-
574
502
  }
575
503
  ```
576
504
 
@@ -583,11 +511,9 @@ Example:
583
511
  const rules = {
584
512
  marks: {
585
513
  type: "array",
586
-
587
514
  elementConstraints: {
588
515
  type: "number",
589
516
  },
590
-
591
517
  elementConstraintsError: "Every marks element must be a number",
592
518
  },
593
519
  };
@@ -605,22 +531,17 @@ Example:
605
531
  const rules = {
606
532
  address: {
607
533
  type: "object",
608
-
609
534
  objectAttr: {
610
535
  city: {
611
536
  mandatory: true,
612
-
613
537
  type: "string",
614
538
  },
615
-
616
539
  location: {
617
540
  type: "object",
618
-
619
541
  objectAttr: {
620
542
  latitude: {
621
543
  type: "number",
622
544
  },
623
-
624
545
  longitude: {
625
546
  type: "number",
626
547
  },
@@ -636,15 +557,10 @@ Nested errors include the complete field path:
636
557
  ```js
637
558
 
638
559
  {
639
-
640
560
    path: "address.location.latitude",
641
-
642
561
    code: "INVALID_TYPE",
643
-
644
562
    message:
645
-
646
563
      "Invalid type for attribute address.location.latitude, required number value"
647
-
648
564
  }
649
565
  ```
650
566
 
@@ -660,14 +576,11 @@ Example:
660
576
  const rules = {
661
577
  minSalary: {
662
578
  type: "number",
663
-
664
579
  dependency: {
665
580
  maxSalary: {
666
581
  setDependencyRule: (minSalary, maxSalary) => ({
667
582
  type: "number",
668
-
669
583
  min: minSalary + 1,
670
-
671
584
  minError: "maxSalary must be more than minSalary",
672
585
  }),
673
586
  },
@@ -683,13 +596,9 @@ Example error:
683
596
  {
684
597
 
685
598
    path: "maxSalary",
686
-
687
599
    code: "MIN_VALUE",
688
-
689
600
    message:
690
-
691
601
      "maxSalary must be more than minSalary"
692
-
693
602
  }
694
603
  ```
695
604
 
@@ -701,47 +610,26 @@ validation error codes:
701
610
  ```text
702
611
 
703
612
  REQUIRED
704
-
705
613
  NULL_NOT_ALLOWED
706
-
707
614
  EMPTY_OBJECT_NOT_ALLOWED
708
-
709
615
  EMPTY_ARRAY_NOT_ALLOWED
710
-
711
616
  INVALID_ARRAY_ELEMENT
712
-
713
617
  REGEX_MISMATCH
714
-
715
618
  INVALID_TYPE
716
-
717
619
  INVALID_EMAIL
718
-
719
620
  INVALID_URL
720
-
721
621
  INVALID_ENUM
722
-
723
622
  INVALID_UUID
724
-
725
623
  INVALID_UUID_V1
726
-
727
624
  INVALID_UUID_V3
728
-
729
625
  INVALID_UUID_V4
730
-
731
626
  INVALID_UUID_V5
732
-
733
627
  INVALID_OBJECT_ID
734
-
735
628
  MIN_LENGTH
736
-
737
629
  MAX_LENGTH
738
-
739
630
  DECIMAL_NOT_ALLOWED
740
-
741
631
  MIN_VALUE
742
-
743
632
  MAX_VALUE
744
-
745
633
  OUT_OF_RANGE
746
634
  ```
747
635
 
@@ -774,13 +662,9 @@ keeping the same structured error format:
774
662
  ```js
775
663
 
776
664
  {
777
-
778
665
    path: "email",
779
-
780
666
    code: "INVALID_EMAIL",
781
-
782
667
    message: "Email address is invalid"
783
-
784
668
  }
785
669
  ```
786
670
 
@@ -790,11 +674,8 @@ Example:
790
674
  const rules = {
791
675
  email: {
792
676
  mandatory: true,
793
-
794
677
  type: "email",
795
-
796
678
  mandatoryError: "Email is required",
797
-
798
679
  typeError: "Email address is invalid",
799
680
  },
800
681
  };
@@ -805,13 +686,9 @@ If `email` is missing:
805
686
  ```js
806
687
 
807
688
  {
808
-
809
689
    path: "email",
810
-
811
690
    code: "REQUIRED",
812
-
813
691
    message: "Email is required"
814
-
815
692
  }
816
693
  ```
817
694
 
@@ -820,13 +697,9 @@ If `email` is present but invalid:
820
697
  ```js
821
698
 
822
699
  {
823
-
824
700
    path: "email",
825
-
826
701
    code: "INVALID_EMAIL",
827
-
828
702
    message: "Email address is invalid"
829
-
830
703
  }
831
704
  ```
832
705
 
@@ -867,40 +740,27 @@ If `email` is present but invalid:
867
740
  ```js
868
741
  const payload = {
869
742
  username: "ab",
870
-
871
743
  age: 15,
872
-
873
744
  score: 120,
874
745
  };
875
746
 
876
747
  const rules = {
877
748
  username: {
878
749
  mandatory: true,
879
-
880
750
  type: "string",
881
-
882
751
  minLength: 3,
883
-
884
752
  mandatoryError: "Username is required",
885
-
886
753
  typeError: "Username must be a string",
887
-
888
754
  minLengthError: "Username must contain at least 3 characters",
889
755
  },
890
-
891
756
  age: {
892
757
  type: "number",
893
-
894
758
  min: 18,
895
-
896
759
  minError: "Age must be at least 18",
897
760
  },
898
-
899
761
  score: {
900
762
  type: "number",
901
-
902
763
  range: "0-100",
903
-
904
764
  rangeError: "Score must be between 0 and 100",
905
765
  },
906
766
  };
@@ -913,55 +773,30 @@ Example result:
913
773
  ```js
914
774
 
915
775
  {
916
-
917
776
    statusCode: 400,
918
-
919
777
    valid: false,
920
-
921
778
    message:
922
-
923
779
      "One or more attribute values are invalid",
924
-
925
780
    errors: [
926
-
927
781
      {
928
-
929
782
        path: "username",
930
-
931
783
        code: "MIN_LENGTH",
932
-
933
784
        message:
934
-
935
785
          "Username must contain at least 3 characters"
936
-
937
786
      },
938
-
939
787
      {
940
-
941
788
        path: "age",
942
-
943
789
        code: "MIN_VALUE",
944
-
945
790
        message:
946
-
947
791
          "Age must be at least 18"
948
-
949
792
      },
950
-
951
793
      {
952
-
953
794
        path: "score",
954
-
955
795
        code: "OUT_OF_RANGE",
956
-
957
796
        message:
958
-
959
797
          "Score must be between 0 and 100"
960
-
961
798
      }
962
-
963
799
    ]
964
-
965
800
  }
966
801
  ```
967
802
 
@@ -977,9 +812,7 @@ For example:
977
812
  const rules = {
978
813
  age: {
979
814
  type: "number",
980
-
981
815
  min: 18,
982
-
983
816
  minError: "You must be 18 or older",
984
817
  },
985
818
  };
@@ -990,13 +823,9 @@ Still returns:
990
823
  ```js
991
824
 
992
825
  {
993
-
994
826
    path: "age",
995
-
996
827
    code: "MIN_VALUE",
997
-
998
828
    message: "You must be 18 or older"
999
-
1000
829
  }
1001
830
  ```
1002
831
 
@@ -1023,9 +852,7 @@ Example:
1023
852
  ```js
1024
853
  const customValidResponse = {
1025
854
  statusCode: 201,
1026
-
1027
855
  valid: true,
1028
-
1029
856
  message: "Payload validated successfully",
1030
857
  };
1031
858
 
@@ -1037,23 +864,14 @@ When validation succeeds, `validatedPayload` is automatically added:
1037
864
  ```js
1038
865
 
1039
866
  {
1040
-
1041
867
    statusCode: 201,
1042
-
1043
868
    valid: true,
1044
-
1045
869
    message: "Payload validated successfully",
1046
-
1047
870
    validatedPayload: {
1048
-
1049
871
      name: "Kiran",
1050
-
1051
872
      email: "kiran@example.com",
1052
-
1053
873
      age: 29
1054
-
1055
874
    }
1056
-
1057
875
  }
1058
876
  ```
1059
877
 
@@ -1064,19 +882,14 @@ Example:
1064
882
  ```js
1065
883
  const customInvalidResponse = {
1066
884
  statusCode: 422,
1067
-
1068
885
  valid: false,
1069
-
1070
886
  message: "Payload validation failed",
1071
887
  };
1072
888
 
1073
889
  const result = perfectPayload(
1074
890
  payload,
1075
-
1076
891
  validationRules,
1077
-
1078
892
  undefined,
1079
-
1080
893
  customInvalidResponse,
1081
894
  );
1082
895
  ```
@@ -1088,27 +901,16 @@ When validation fails, `errors` is automatically added:
1088
901
  {
1089
902
 
1090
903
    statusCode: 422,
1091
-
1092
904
    valid: false,
1093
-
1094
905
    message: "Payload validation failed",
1095
-
1096
906
    errors: [
1097
-
1098
907
      {
1099
-
1100
908
        path: "email",
1101
-
1102
909
        code: "INVALID_EMAIL",
1103
-
1104
910
        message:
1105
-
1106
911
          "Invalid email format for attribute email"
1107
-
1108
912
      }
1109
-
1110
913
    ]
1111
-
1112
914
  }
1113
915
  ```
1114
916
 
@@ -1117,27 +919,20 @@ When validation fails, `errors` is automatically added:
1117
919
  ```js
1118
920
  const customValidResponse = {
1119
921
  statusCode: 201,
1120
-
1121
922
  valid: true,
1122
-
1123
923
  message: "CUSTOM_VALID_RESPONSE",
1124
924
  };
1125
925
 
1126
926
  const customInvalidResponse = {
1127
927
  statusCode: 422,
1128
-
1129
928
  valid: false,
1130
-
1131
929
  message: "CUSTOM_INVALID_RESPONSE",
1132
930
  };
1133
931
 
1134
932
  const result = perfectPayload(
1135
933
  payload,
1136
-
1137
934
  validationRules,
1138
-
1139
935
  customValidResponse,
1140
-
1141
936
  customInvalidResponse,
1142
937
  );
1143
938
  ```
@@ -1167,17 +962,11 @@ is:
1167
962
  ```js
1168
963
 
1169
964
  {
1170
-
1171
965
    statusCode: 200,
1172
-
1173
966
    valid: true,
1174
-
1175
967
    validatedPayload: {
1176
-
1177
968
      // validated fields
1178
-
1179
969
    }
1180
-
1181
970
  }
1182
971
  ```
1183
972
 
@@ -1186,27 +975,16 @@ The default invalid response is:
1186
975
  ```js
1187
976
 
1188
977
  {
1189
-
1190
978
    statusCode: 400,
1191
-
1192
979
    valid: false,
1193
-
1194
980
    message: "One or more attribute values are invalid",
1195
-
1196
981
    errors: [
1197
-
1198
982
      {
1199
-
1200
983
        path: "field",
1201
-
1202
984
        code: "ERROR_CODE",
1203
-
1204
985
        message: "Validation error message"
1205
-
1206
986
      }
1207
-
1208
987
    ]
1209
-
1210
988
  }
1211
989
  ```
1212
990
 
@@ -1233,13 +1011,9 @@ An error can be returned as:
1233
1011
  ```js
1234
1012
 
1235
1013
  {
1236
-
1237
1014
    path: "email",
1238
-
1239
1015
    code: "INVALID_EMAIL",
1240
-
1241
1016
    message: "Invalid email format for attribute email"
1242
-
1243
1017
  }
1244
1018
  ```
1245
1019
 
@@ -1251,10 +1025,8 @@ Use `objectAttr` to validate properties inside an object.
1251
1025
  const payload = {
1252
1026
  address: {
1253
1027
  city: "Bengaluru",
1254
-
1255
1028
  location: {
1256
1029
  latitude: "12.9716",
1257
-
1258
1030
  longitude: 77.5946,
1259
1031
  },
1260
1032
  },
@@ -1263,20 +1035,16 @@ const payload = {
1263
1035
  const rules = {
1264
1036
  address: {
1265
1037
  type: "object",
1266
-
1267
1038
  objectAttr: {
1268
1039
  city: {
1269
1040
  type: "string",
1270
1041
  },
1271
-
1272
1042
  location: {
1273
1043
  type: "object",
1274
-
1275
1044
  objectAttr: {
1276
1045
  latitude: {
1277
1046
  type: "number",
1278
1047
  },
1279
-
1280
1048
  longitude: {
1281
1049
  type: "number",
1282
1050
  },
@@ -1295,15 +1063,10 @@ its complete nested path:
1295
1063
  ```js
1296
1064
 
1297
1065
  {
1298
-
1299
1066
    path: "address.location.latitude",
1300
-
1301
1067
    code: "INVALID_TYPE",
1302
-
1303
1068
    message:
1304
-
1305
1069
      "Invalid type for attribute address.location.latitude, required number value"
1306
-
1307
1070
  }
1308
1071
  ```
1309
1072
 
@@ -1312,9 +1075,7 @@ Nested paths use dot notation:
1312
1075
  ```text
1313
1076
 
1314
1077
  address.city
1315
-
1316
1078
  address.location.latitude
1317
-
1318
1079
  address.location.longitude
1319
1080
  ```
1320
1081
 
@@ -1331,10 +1092,8 @@ const payload = {
1331
1092
  const rules = {
1332
1093
  marks: {
1333
1094
  type: "array",
1334
-
1335
1095
  elementConstraints: {
1336
1096
  type: "number",
1337
-
1338
1097
  range: "0-100",
1339
1098
  },
1340
1099
  },
@@ -1348,15 +1107,10 @@ The invalid third element is reported as:
1348
1107
  ```js
1349
1108
 
1350
1109
  {
1351
-
1352
1110
    path: "marks[2]",
1353
-
1354
1111
    code: "OUT_OF_RANGE",
1355
-
1356
1112
    message:
1357
-
1358
1113
      "Attribute marks[2] should have a value between 0 and 100"
1359
-
1360
1114
  }
1361
1115
  ```
1362
1116
 
@@ -1365,9 +1119,7 @@ Array paths use zero-based indexes:
1365
1119
  ```text
1366
1120
 
1367
1121
  marks[0]
1368
-
1369
1122
  marks[1]
1370
-
1371
1123
  marks[2]
1372
1124
  ```
1373
1125
 
@@ -1380,9 +1132,7 @@ For example:
1380
1132
  ```text
1381
1133
 
1382
1134
  products[0].quantity
1383
-
1384
1135
  products[1].quantity
1385
-
1386
1136
  products[2].price
1387
1137
  ```
1388
1138
 
@@ -1426,17 +1176,9 @@ Result:
1426
1176
 
1427
1177
  {
1428
1178
 
1429
-   "email":
1430
-
1431
-     "Invalid email format for attribute email",
1432
-
1433
-   "address.location.latitude":
1434
-
1435
-     "Invalid type for attribute address.location.latitude, required number value",
1436
-
1437
-   "marks[2]":
1438
-
1439
-     "Attribute marks[2] should have a value between 0 and 100"
1179
+   "email": "Invalid email format for attribute email",
1180
+   "address.location.latitude": "Invalid type for attribute address.location.latitude, required number value",
1181
+   "marks[2]": "Attribute marks[2] should have a value between 0 and 100"
1440
1182
 
1441
1183
  }
1442
1184
  ```
@@ -1452,61 +1194,33 @@ sample-1
1452
1194
  {
1453
1195
 
1454
1196
    firstName: {
1455
-
1456
1197
      mandatory: true,
1457
-
1458
1198
      allowNull: false,
1459
-
1460
1199
      type: "string",
1461
-
1462
1200
      minLength: 3,
1463
-
1464
1201
      minLengthError:"First name must have minimum 3 characters."
1465
-
1466
1202
    },
1467
-
1468
1203
    lastName: {
1469
-
1470
1204
      mandatory: false,
1471
-
1472
1205
      allowNull: true,
1473
-
1474
1206
      type: "string",
1475
-
1476
1207
    },
1477
-
1478
1208
    email: {
1479
-
1480
1209
      mandatory: true,
1481
-
1482
1210
      allowNull: false,
1483
-
1484
1211
      type: "email",
1485
-
1486
1212
    },
1487
-
1488
1213
    phone: {
1489
-
1490
1214
      mandatory: true,
1491
-
1492
1215
      allowNull: false,
1493
-
1494
1216
      type: "string",
1495
-
1496
1217
    },
1497
-
1498
1218
    age: {
1499
-
1500
1219
      mandatory: false,
1501
-
1502
1220
      type: "number",
1503
-
1504
1221
      min: 1,
1505
-
1506
1222
      max: 120,
1507
-
1508
1223
    },
1509
-
1510
1224
  };
1511
1225
  ```
1512
1226
 
@@ -1515,273 +1229,139 @@ sample-2
1515
1229
  ```javascript
1516
1230
 
1517
1231
  {
1518
-
1519
1232
    id: {
1520
-
1521
1233
      mandatory: true,
1522
-
1523
1234
      allowNull: true,
1524
-
1525
1235
      type: "uuidv4",
1526
-
1527
1236
    },
1528
-
1529
1237
    batchId: {
1530
-
1531
1238
      mandatory: true,
1532
-
1533
1239
      allowNull: true,
1534
-
1535
1240
      type: "objectId",
1536
-
1537
1241
    },
1538
-
1539
1242
    firstName: {
1540
-
1541
1243
      mandatory: true,
1542
-
1543
1244
      type: "string",
1544
-
1545
1245
      minLength: 3,
1546
-
1547
1246
    },
1548
-
1549
1247
    lastName: {
1550
-
1551
1248
      mandatory: false,
1552
-
1553
1249
      allowNull: true,
1554
-
1555
1250
      type: "string",
1556
-
1557
1251
    },
1558
-
1559
1252
    age: {
1560
-
1561
1253
      type: "number",
1562
-
1563
1254
      min: 0.1,
1564
-
1565
1255
      max: 120,
1566
-
1567
1256
    },
1568
-
1569
1257
    isAdult: {
1570
-
1571
1258
      type: "boolean",
1572
-
1573
1259
    },
1574
-
1575
1260
    totalWins: {
1576
-
1577
1261
      type: "number",
1578
-
1579
1262
      min: 0,
1580
-
1581
1263
      preventDecimal: true,
1582
-
1583
1264
    },
1584
-
1585
1265
    email: {
1586
-
1587
1266
      regex: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$/,
1588
-
1589
1267
    },
1590
-
1591
1268
    githubLink: {
1592
-
1593
1269
      type: "url",
1594
-
1595
1270
    },
1596
-
1597
1271
    accountStatus: {
1598
-
1599
1272
      type: "enum",
1600
-
1601
1273
      enumValues: ["Active", "Inactive", 200],
1602
-
1603
1274
    },
1604
-
1605
1275
    marks: {
1606
-
1607
1276
      range: "0-100",
1608
-
1609
1277
    },
1610
-
1611
1278
    allMarks: {
1612
-
1613
1279
      type: "array",
1614
-
1615
1280
      allowEmptyArray: false,
1616
-
1617
1281
      elementConstraints: {
1618
-
1619
1282
        type: "number",
1620
-
1621
1283
        allowNull: false,
1622
-
1623
1284
        range: "0-100",
1624
-
1625
1285
      },
1626
-
1627
1286
    },
1628
-
1629
1287
    totalScore: {
1630
-
1631
1288
      type: "number",
1632
-
1633
1289
      dependency: {
1634
-
1635
1290
        result: {
1636
-
1637
1291
          setDependencyRule: (totalScore, result) => {
1638
-
1639
1292
            return { mandatory: true, allowNull: false, type: "string" };
1640
-
1641
1293
          },
1642
-
1643
1294
        },
1644
-
1645
1295
      },
1646
-
1647
1296
    },
1648
-
1649
1297
    result: {
1650
-
1651
1298
      type: "string",
1652
-
1653
1299
      dependency: {
1654
-
1655
1300
        totalScore: {
1656
-
1657
1301
          setDependencyRule: (result, totalScore) => {
1658
-
1659
1302
            return { mandatory: true, allowNull: false, type: "number" };
1660
-
1661
1303
          },
1662
-
1663
1304
        },
1664
-
1665
1305
      },
1666
-
1667
1306
    },
1668
-
1669
1307
    minSalary: {
1670
-
1671
1308
      mandatory: true,
1672
-
1673
1309
      min: 1,
1674
-
1675
1310
      type: "number",
1676
-
1677
1311
      dependency: {
1678
-
1679
1312
        maxSalary: {
1680
-
1681
1313
          setDependencyRule: (minSalary, maxSalary) => {
1682
-
1683
1314
            return {
1684
-
1685
1315
              mandatory: true,
1686
-
1687
1316
              min: minSalary + 1,
1688
-
1689
1317
              minError: "maxSalary must be more than minSalary",
1690
-
1691
1318
            };
1692
-
1693
1319
          },
1694
-
1695
1320
        },
1696
-
1697
1321
      },
1698
-
1699
1322
    },
1700
-
1701
1323
    maxSalary: {
1702
-
1703
1324
      dependency: {
1704
-
1705
1325
        minSalary: {
1706
-
1707
1326
          setDependencyRule: (maxSalary, minSalary) => {
1708
-
1709
1327
            return {
1710
-
1711
1328
              mandatory: true,
1712
-
1713
1329
              max: maxSalary - 1,
1714
-
1715
1330
              maxError: "minSalary must be less than maxSalary",
1716
-
1717
1331
            };
1718
-
1719
1332
          },
1720
-
1721
1333
        },
1722
-
1723
1334
      },
1724
-
1725
1335
    },
1726
-
1727
1336
    address: {
1728
-
1729
1337
      mandatory: true,
1730
-
1731
1338
      type: "object",
1732
-
1733
1339
      allowEmptyObject: false,
1734
-
1735
1340
      objectAttr: {
1736
-
1737
1341
        country: { mandatory: true, type: "string" },
1738
-
1739
1342
        state: {
1740
-
1741
1343
          mandatory: true,
1742
-
1743
1344
          type: "string",
1744
-
1745
1345
        },
1746
-
1747
1346
        city: {},
1748
-
1749
1347
        zip: {
1750
-
1751
1348
          mandatory: true,
1752
-
1753
1349
          type: "string",
1754
-
1755
1350
        },
1756
-
1757
1351
        position: {
1758
-
1759
1352
          mandatory: true,
1760
-
1761
1353
          type: "object",
1762
-
1763
1354
          allowEmptyObject: false,
1764
-
1765
1355
          objectAttr: {
1766
-
1767
1356
            lattitude: { mandatory: true, type: "number" },
1768
-
1769
1357
            longitude: {
1770
-
1771
1358
              mandatory: true,
1772
-
1773
1359
              type: "number",
1774
-
1775
1360
            },
1776
-
1777
1361
          },
1778
-
1779
1362
        },
1780
-
1781
1363
      },
1782
-
1783
1364
    },
1784
-
1785
1365
  }
1786
1366
  ```
1787
1367
 
@@ -1794,13 +1374,9 @@ sample-2
1794
1374
  //Here validatePayload is your middleware function, where you're invoking perfect payload
1795
1375
 
1796
1376
  router.post(
1797
-
1798
1377
    "/payload-validation",
1799
-
1800
1378
    validatePayload({ rule: <your validation rule json object> }),
1801
-
1802
1379
    (req, res) => res.send("OK")
1803
-
1804
1380
  );
1805
1381
  ```
1806
1382
 
@@ -1813,15 +1389,12 @@ export const validatePayload = ({ rule }) => {
1813
1389
  return (req, res, next) => {
1814
1390
  try {
1815
1391
  const { statusCode, ...response } = perfectPayloadV1(req?.body, rule);
1816
-
1817
1392
  if (+statusCode >= 200 && +statusCode <= 299) {
1818
1393
  req.validatedBody = response?.validatedPayload;
1819
-
1820
1394
  next();
1821
1395
  } else res.status(statusCode).json(response);
1822
1396
  } catch (error) {
1823
1397
  console.error("Error validating payload", error);
1824
-
1825
1398
  res.status(500).json({ error: "Internal Server Error" });
1826
1399
  }
1827
1400
  };
@@ -1835,19 +1408,15 @@ function validatePayload({ rule }) {
1835
1408
  return async (req, res, next) => {
1836
1409
  try {
1837
1410
  const { perfectPayloadV1 } = await import("perfect-payload");
1838
-
1839
1411
  const { statusCode, ...response } = perfectPayloadV1(req?.body, rule);
1840
-
1841
1412
  if (+statusCode >= 200 && +statusCode <= 299) {
1842
1413
  req.validatedBody = response?.validatedPayload;
1843
-
1844
1414
  next();
1845
1415
  } else {
1846
1416
  res.status(statusCode).json(response);
1847
1417
  }
1848
1418
  } catch (error) {
1849
1419
  console.error("Error validating payload", error);
1850
-
1851
1420
  res.status(500).json({ error: "Internal Server Error" });
1852
1421
  }
1853
1422
  };