perfect-payload 1.1.2 → 1.2.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.
- package/.babelrc +3 -3
- package/.github/workflows/publish.yml +124 -0
- package/LICENSE +21 -21
- package/README.md +1863 -375
- package/index.js +1429 -567
- package/package.json +36 -36
package/index.js
CHANGED
|
@@ -1,567 +1,1429 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
rowErrors.push(
|
|
202
|
-
attributeRules?.["typeError"] ||
|
|
203
|
-
`Invalid
|
|
204
|
-
);
|
|
205
|
-
addNextError = false;
|
|
206
|
-
}
|
|
207
|
-
break;
|
|
208
|
-
case "
|
|
209
|
-
if (attributeValue == null && nullAllowed) {
|
|
210
|
-
addNextError = true;
|
|
211
|
-
} else
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
addNextError =
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
addNextError =
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
addNextError =
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
break;
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
addNextError =
|
|
329
|
-
} else {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
addNextError =
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
function
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
1
|
+
let perfectPayloadV1DeprecationWarningShown = false;
|
|
2
|
+
|
|
3
|
+
function showPerfectPayloadV1DeprecationWarning() {
|
|
4
|
+
if (perfectPayloadV1DeprecationWarningShown) return;
|
|
5
|
+
|
|
6
|
+
perfectPayloadV1DeprecationWarningShown = true;
|
|
7
|
+
|
|
8
|
+
const message =
|
|
9
|
+
"perfectPayloadV1() is deprecated and will no longer be supported after March 31, 2027. Use perfectPayload() instead.";
|
|
10
|
+
|
|
11
|
+
if (
|
|
12
|
+
typeof process !== "undefined" &&
|
|
13
|
+
typeof process.emitWarning === "function"
|
|
14
|
+
) {
|
|
15
|
+
process.emitWarning(message, {
|
|
16
|
+
type: "DeprecationWarning",
|
|
17
|
+
code: "PERFECT_PAYLOAD_V1_DEPRECATED",
|
|
18
|
+
});
|
|
19
|
+
} else if (
|
|
20
|
+
typeof console !== "undefined" &&
|
|
21
|
+
typeof console.warn === "function"
|
|
22
|
+
) {
|
|
23
|
+
console.warn(`[perfect-payload] DeprecationWarning: ${message}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function perfectPayloadV1(
|
|
28
|
+
data = {},
|
|
29
|
+
dataValidationRule = {},
|
|
30
|
+
validPayloadResponse = { statusCode: 200, valid: true },
|
|
31
|
+
inValidPayloadResponse = {
|
|
32
|
+
statusCode: 400,
|
|
33
|
+
valid: false,
|
|
34
|
+
message: "One or more attribute values are invalid",
|
|
35
|
+
},
|
|
36
|
+
) {
|
|
37
|
+
showPerfectPayloadV1DeprecationWarning();
|
|
38
|
+
let validatedPayload = {};
|
|
39
|
+
let rowErrors = [];
|
|
40
|
+
for (const attributeName in dataValidationRule) {
|
|
41
|
+
let addNextError = true;
|
|
42
|
+
const attributeRules = dataValidationRule?.[attributeName];
|
|
43
|
+
const attrPath = dataValidationRule?.[attributeName]?.path || null;
|
|
44
|
+
for (const ruleName in attributeRules) {
|
|
45
|
+
const attributePath = `${attrPath ? attrPath + "." : ""}${attributeName}`;
|
|
46
|
+
const attributeValue = data?.[attributeName] ?? null;
|
|
47
|
+
const nullAllowed =
|
|
48
|
+
dataValidationRule?.[attributeName]?.["allowNull"] ?? true;
|
|
49
|
+
const isMandatoryField = attributeRules?.["mandatory"] ?? false;
|
|
50
|
+
const attrExist = Object.keys(data)?.includes(attributeName); //Mandatory value check
|
|
51
|
+
|
|
52
|
+
switch (ruleName) {
|
|
53
|
+
case "mandatory":
|
|
54
|
+
//mandatory value check
|
|
55
|
+
if (isMandatoryField && !attrExist) {
|
|
56
|
+
addNextError = false;
|
|
57
|
+
rowErrors.push(
|
|
58
|
+
attributeRules?.["mandatoryError"] ||
|
|
59
|
+
`${attributePath} is mandatory`,
|
|
60
|
+
);
|
|
61
|
+
} else if (!attrExist) {
|
|
62
|
+
addNextError = false;
|
|
63
|
+
}
|
|
64
|
+
break;
|
|
65
|
+
case "allowNull":
|
|
66
|
+
//allowNull value check
|
|
67
|
+
if (addNextError && attributeValue == null) {
|
|
68
|
+
if (!dataValidationRule?.[attributeName]?.[ruleName]) {
|
|
69
|
+
addNextError = false;
|
|
70
|
+
rowErrors.push(
|
|
71
|
+
attributeRules?.["allowNullError"] ||
|
|
72
|
+
`value null/'' not valid for attribute ${attributePath}`,
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
break;
|
|
77
|
+
case "allowEmptyObject":
|
|
78
|
+
//allowEmptyObject check
|
|
79
|
+
if (addNextError) {
|
|
80
|
+
if (
|
|
81
|
+
!attributeRules?.["allowEmptyObject"] &&
|
|
82
|
+
Object.keys(attributeValue).length == 0
|
|
83
|
+
) {
|
|
84
|
+
rowErrors.push(
|
|
85
|
+
attributeRules?.["emptyObjectError"] ||
|
|
86
|
+
`value {} not valid for attribute ${attributePath}`,
|
|
87
|
+
);
|
|
88
|
+
addNextError = false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
break;
|
|
93
|
+
case "allowEmptyArray":
|
|
94
|
+
//allowEmptyArray check
|
|
95
|
+
if (addNextError) {
|
|
96
|
+
if (
|
|
97
|
+
!attributeRules?.["allowEmptyArray"] &&
|
|
98
|
+
isArray(attributeValue) &&
|
|
99
|
+
attributeValue?.length == 0
|
|
100
|
+
) {
|
|
101
|
+
rowErrors.push(
|
|
102
|
+
attributeRules?.["emptyArrayError"] ||
|
|
103
|
+
`${attributePath} cannot be an empty array`,
|
|
104
|
+
);
|
|
105
|
+
addNextError = false;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
break;
|
|
110
|
+
case "elementConstraints":
|
|
111
|
+
//check array ele type
|
|
112
|
+
if (addNextError) {
|
|
113
|
+
if (isArray(attributeValue) && attributeValue?.length > 0) {
|
|
114
|
+
let elementError = false;
|
|
115
|
+
for (const element of attributeValue) {
|
|
116
|
+
const { statusCode = 200, errors } = perfectPayloadV1(
|
|
117
|
+
{ [attributeName]: element },
|
|
118
|
+
{ [attributeName]: attributeRules[ruleName] },
|
|
119
|
+
);
|
|
120
|
+
if (statusCode == 400) {
|
|
121
|
+
elementError = errors?.[0];
|
|
122
|
+
// addNextError = false;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (elementError) {
|
|
127
|
+
rowErrors.push(
|
|
128
|
+
attributeRules?.["elementConstraintsError"] || elementError,
|
|
129
|
+
);
|
|
130
|
+
addNextError = false;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
break;
|
|
136
|
+
case "regex":
|
|
137
|
+
//custom regex check
|
|
138
|
+
if (addNextError) {
|
|
139
|
+
if (!isPassedRegex(attributeRules[ruleName], attributeValue)) {
|
|
140
|
+
rowErrors.push(
|
|
141
|
+
attributeRules?.["regexError"] ||
|
|
142
|
+
`${attributePath} failed to pass the regex ${attributeRules[ruleName]}`,
|
|
143
|
+
);
|
|
144
|
+
addNextError = false;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
break;
|
|
148
|
+
case "type":
|
|
149
|
+
//value type check
|
|
150
|
+
if (addNextError) {
|
|
151
|
+
if (attributeValue == null && nullAllowed) {
|
|
152
|
+
addNextError = true;
|
|
153
|
+
} else {
|
|
154
|
+
switch (attributeRules[ruleName]) {
|
|
155
|
+
case "number":
|
|
156
|
+
if (!isNumber(attributeValue)) {
|
|
157
|
+
rowErrors.push(
|
|
158
|
+
attributeRules?.["typeError"] ||
|
|
159
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required ${
|
|
160
|
+
attributeRules[ruleName]
|
|
161
|
+
} value`,
|
|
162
|
+
);
|
|
163
|
+
addNextError = false;
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
|
|
167
|
+
case "string":
|
|
168
|
+
if (!isString(attributeValue)) {
|
|
169
|
+
rowErrors.push(
|
|
170
|
+
attributeRules?.["typeError"] ||
|
|
171
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required ${
|
|
172
|
+
attributeRules[ruleName]
|
|
173
|
+
} value`,
|
|
174
|
+
);
|
|
175
|
+
addNextError = false;
|
|
176
|
+
}
|
|
177
|
+
break;
|
|
178
|
+
case "boolean":
|
|
179
|
+
if (!isBoolean(attributeValue)) {
|
|
180
|
+
rowErrors.push(
|
|
181
|
+
attributeRules?.["typeError"] ||
|
|
182
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required ${
|
|
183
|
+
attributeRules[ruleName]
|
|
184
|
+
} value`,
|
|
185
|
+
);
|
|
186
|
+
addNextError = false;
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
case "email":
|
|
190
|
+
if (!isValidEmail(attributeValue)) {
|
|
191
|
+
rowErrors.push(
|
|
192
|
+
attributeRules?.["typeError"] ||
|
|
193
|
+
`Invalid email ID(${attributeValue}) found in attribute ${attributePath}`,
|
|
194
|
+
);
|
|
195
|
+
addNextError = false;
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
|
|
199
|
+
case "url":
|
|
200
|
+
if (!isValidUrl(attributeValue)) {
|
|
201
|
+
rowErrors.push(
|
|
202
|
+
attributeRules?.["typeError"] ||
|
|
203
|
+
`Invalid URL format(${attributeValue}) found in attribute ${attributePath}`,
|
|
204
|
+
);
|
|
205
|
+
addNextError = false;
|
|
206
|
+
}
|
|
207
|
+
break;
|
|
208
|
+
case "enum":
|
|
209
|
+
if (attributeValue == null && nullAllowed) {
|
|
210
|
+
addNextError = true;
|
|
211
|
+
} else {
|
|
212
|
+
const allEnumValues = attributeRules["enumValues"];
|
|
213
|
+
if (!allEnumValues?.includes(attributeValue)) {
|
|
214
|
+
rowErrors.push(
|
|
215
|
+
attributeRules?.["typeError"] ||
|
|
216
|
+
`Invalid value(${attributeValue}) found in attribute ${attributePath}, valid values are ${allEnumValues?.join(
|
|
217
|
+
", ",
|
|
218
|
+
)}`,
|
|
219
|
+
);
|
|
220
|
+
addNextError = false;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
break;
|
|
224
|
+
case "uuid":
|
|
225
|
+
if (attributeValue == null && nullAllowed) {
|
|
226
|
+
addNextError = true;
|
|
227
|
+
} else if (!isUUID(attributeValue)) {
|
|
228
|
+
rowErrors.push(
|
|
229
|
+
attributeRules?.["typeError"] ||
|
|
230
|
+
`Invalid UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
231
|
+
);
|
|
232
|
+
addNextError = false;
|
|
233
|
+
}
|
|
234
|
+
break;
|
|
235
|
+
case "uuidv1":
|
|
236
|
+
if (attributeValue == null && nullAllowed) {
|
|
237
|
+
addNextError = true;
|
|
238
|
+
} else if (!isUUIDv1(attributeValue)) {
|
|
239
|
+
rowErrors.push(
|
|
240
|
+
attributeRules?.["typeError"] ||
|
|
241
|
+
`Invalid v1 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
242
|
+
);
|
|
243
|
+
addNextError = false;
|
|
244
|
+
}
|
|
245
|
+
break;
|
|
246
|
+
case "uuidv3":
|
|
247
|
+
if (attributeValue == null && nullAllowed) {
|
|
248
|
+
addNextError = true;
|
|
249
|
+
} else if (!isUUIDv3(attributeValue)) {
|
|
250
|
+
rowErrors.push(
|
|
251
|
+
attributeRules?.["typeError"] ||
|
|
252
|
+
`Invalid v3 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
253
|
+
);
|
|
254
|
+
addNextError = false;
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
case "uuidv4":
|
|
258
|
+
if (attributeValue == null && nullAllowed) {
|
|
259
|
+
addNextError = true;
|
|
260
|
+
} else if (!isUUIDv4(attributeValue)) {
|
|
261
|
+
rowErrors.push(
|
|
262
|
+
attributeRules?.["typeError"] ||
|
|
263
|
+
`Invalid v4 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
264
|
+
);
|
|
265
|
+
addNextError = false;
|
|
266
|
+
}
|
|
267
|
+
break;
|
|
268
|
+
case "uuidv5":
|
|
269
|
+
if (attributeValue == null && nullAllowed) {
|
|
270
|
+
addNextError = true;
|
|
271
|
+
} else if (!isUUIDv5(attributeValue)) {
|
|
272
|
+
rowErrors.push(
|
|
273
|
+
attributeRules?.["typeError"] ||
|
|
274
|
+
`Invalid v5 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
275
|
+
);
|
|
276
|
+
addNextError = false;
|
|
277
|
+
}
|
|
278
|
+
break;
|
|
279
|
+
case "objectId":
|
|
280
|
+
if (attributeValue == null && nullAllowed) {
|
|
281
|
+
addNextError = true;
|
|
282
|
+
} else {
|
|
283
|
+
if (!isObjectId(attributeValue)) {
|
|
284
|
+
rowErrors.push(
|
|
285
|
+
attributeRules?.["typeError"] ||
|
|
286
|
+
`Invalid ObjectId(${attributeValue}) found in attribute ${attributePath}`,
|
|
287
|
+
);
|
|
288
|
+
addNextError = false;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
|
|
293
|
+
case "array":
|
|
294
|
+
if (!isArray(attributeValue)) {
|
|
295
|
+
rowErrors.push(
|
|
296
|
+
attributeRules?.["typeError"] ||
|
|
297
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required ${
|
|
298
|
+
attributeRules[ruleName]
|
|
299
|
+
} value`,
|
|
300
|
+
);
|
|
301
|
+
addNextError = false;
|
|
302
|
+
}
|
|
303
|
+
break;
|
|
304
|
+
|
|
305
|
+
case "object":
|
|
306
|
+
if (!isObject(attributeValue)) {
|
|
307
|
+
rowErrors.push(
|
|
308
|
+
attributeRules?.["typeError"] ||
|
|
309
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required ${
|
|
310
|
+
attributeRules[ruleName]
|
|
311
|
+
} value`,
|
|
312
|
+
);
|
|
313
|
+
addNextError = false;
|
|
314
|
+
}
|
|
315
|
+
break;
|
|
316
|
+
|
|
317
|
+
default:
|
|
318
|
+
break;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
break;
|
|
324
|
+
case "minLength":
|
|
325
|
+
//minimum string length check
|
|
326
|
+
if (addNextError) {
|
|
327
|
+
if (attributeValue == null && nullAllowed) {
|
|
328
|
+
addNextError = true;
|
|
329
|
+
} else if (typeof attributeValue == "string") {
|
|
330
|
+
if (attributeValue.length < +attributeRules[ruleName])
|
|
331
|
+
rowErrors.push(
|
|
332
|
+
attributeRules?.["minLengthError"] ||
|
|
333
|
+
`${attributePath} should be minimum of ${attributeRules[ruleName]} character`,
|
|
334
|
+
);
|
|
335
|
+
addNextError = false;
|
|
336
|
+
} else {
|
|
337
|
+
rowErrors.push(
|
|
338
|
+
`${attributePath} value should be a string type(minLength specified)`,
|
|
339
|
+
);
|
|
340
|
+
addNextError = false;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
break;
|
|
344
|
+
case "maxLength":
|
|
345
|
+
//max string length check
|
|
346
|
+
if (addNextError) {
|
|
347
|
+
if (attributeValue == null && nullAllowed) {
|
|
348
|
+
addNextError = true;
|
|
349
|
+
} else if (typeof attributeValue == "string") {
|
|
350
|
+
if (attributeValue.length > +attributeRules[ruleName])
|
|
351
|
+
rowErrors.push(
|
|
352
|
+
attributeRules?.["maxLengthError"] ||
|
|
353
|
+
`${attributePath} can have maximum of ${attributeRules[ruleName]} character`,
|
|
354
|
+
);
|
|
355
|
+
addNextError = false;
|
|
356
|
+
} else {
|
|
357
|
+
rowErrors.push(
|
|
358
|
+
`${attributePath} value should be a string type(maxLength specified)`,
|
|
359
|
+
);
|
|
360
|
+
addNextError = false;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
break;
|
|
364
|
+
case "preventDecimal":
|
|
365
|
+
//preventFraction
|
|
366
|
+
if (addNextError) {
|
|
367
|
+
if (attributeValue == null && nullAllowed) {
|
|
368
|
+
addNextError = true;
|
|
369
|
+
} else if (!isNumber(attributeValue)) {
|
|
370
|
+
rowErrors.push(
|
|
371
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required number value`,
|
|
372
|
+
);
|
|
373
|
+
addNextError = false;
|
|
374
|
+
} else if (+attributeValue % 1 !== 0) {
|
|
375
|
+
rowErrors.push(
|
|
376
|
+
attributeRules?.["preventDecimalError"] ||
|
|
377
|
+
`Decimal value not allowed in attribute ${attributePath}(${attributeValue})`,
|
|
378
|
+
);
|
|
379
|
+
addNextError = false;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
break;
|
|
383
|
+
case "min":
|
|
384
|
+
//minimum value check
|
|
385
|
+
if (addNextError) {
|
|
386
|
+
if (attributeValue == null && nullAllowed) {
|
|
387
|
+
addNextError = true;
|
|
388
|
+
} else if (!isNumber(attributeValue)) {
|
|
389
|
+
rowErrors.push(
|
|
390
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required number value`,
|
|
391
|
+
);
|
|
392
|
+
addNextError = false;
|
|
393
|
+
} else if (+attributeValue < +attributeRules[ruleName]) {
|
|
394
|
+
rowErrors.push(
|
|
395
|
+
attributeRules?.["minError"] ||
|
|
396
|
+
`minimum value ${
|
|
397
|
+
attributeRules[ruleName]
|
|
398
|
+
} is allowed in attribute ${attributePath}, found value ${
|
|
399
|
+
data[attributeName] ?? "Nil"
|
|
400
|
+
}`,
|
|
401
|
+
);
|
|
402
|
+
addNextError = false;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
break;
|
|
406
|
+
case "max":
|
|
407
|
+
//maximum value check
|
|
408
|
+
if (addNextError) {
|
|
409
|
+
if (attributeValue == null && nullAllowed) {
|
|
410
|
+
addNextError = true;
|
|
411
|
+
} else if (!isNumber(attributeValue)) {
|
|
412
|
+
rowErrors.push(
|
|
413
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required number value`,
|
|
414
|
+
);
|
|
415
|
+
addNextError = false;
|
|
416
|
+
} else if (+attributeValue > +attributeRules[ruleName]) {
|
|
417
|
+
rowErrors.push(
|
|
418
|
+
attributeRules?.["maxError"] ||
|
|
419
|
+
`maximum value ${
|
|
420
|
+
attributeRules[ruleName]
|
|
421
|
+
} is allowed in attribute ${attributePath}, found value ${
|
|
422
|
+
data[attributeName] ?? "Nil"
|
|
423
|
+
}`,
|
|
424
|
+
);
|
|
425
|
+
addNextError = false;
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
break;
|
|
429
|
+
case "range":
|
|
430
|
+
//value range check
|
|
431
|
+
if (addNextError) {
|
|
432
|
+
if (attributeValue == null && nullAllowed) {
|
|
433
|
+
addNextError = true;
|
|
434
|
+
} else if (!isNumber(attributeValue)) {
|
|
435
|
+
rowErrors.push(
|
|
436
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required number value`,
|
|
437
|
+
);
|
|
438
|
+
addNextError = false;
|
|
439
|
+
} else {
|
|
440
|
+
const [min, max] = attributeRules[ruleName].split("-");
|
|
441
|
+
if (
|
|
442
|
+
!isNumber(attributeValue) ||
|
|
443
|
+
+attributeValue < +min ||
|
|
444
|
+
+attributeValue > +max
|
|
445
|
+
) {
|
|
446
|
+
rowErrors.push(
|
|
447
|
+
attributeRules?.["rangeError"] ||
|
|
448
|
+
`Invalid values(${attributeValue}) found in attribute ${attributePath}, value should be between ${min} and ${max} `,
|
|
449
|
+
);
|
|
450
|
+
addNextError = false;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
break;
|
|
455
|
+
case "objectAttr":
|
|
456
|
+
//nested object attributes check
|
|
457
|
+
if (addNextError) {
|
|
458
|
+
const allObjectAttr = Object.keys(attributeRules?.[ruleName]);
|
|
459
|
+
const objectAttrRules = {};
|
|
460
|
+
for (const attr of allObjectAttr) {
|
|
461
|
+
objectAttrRules[attr] = {
|
|
462
|
+
...attributeRules?.[ruleName]?.[attr],
|
|
463
|
+
path: attributeRules?.[ruleName]?.[attr]?.path
|
|
464
|
+
? attributeRules?.[ruleName]?.[attr]?.path + `.${attr}`
|
|
465
|
+
: `${attributePath}`,
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
const { errors = [] } = perfectPayloadV1(
|
|
470
|
+
attributeValue,
|
|
471
|
+
objectAttrRules,
|
|
472
|
+
);
|
|
473
|
+
rowErrors = [...rowErrors, ...errors];
|
|
474
|
+
addNextError = true;
|
|
475
|
+
}
|
|
476
|
+
break;
|
|
477
|
+
case "dependency":
|
|
478
|
+
//dependency check
|
|
479
|
+
if (addNextError) {
|
|
480
|
+
const allDependencyAttr = Object.keys(attributeRules?.[ruleName]);
|
|
481
|
+
for (const attr of allDependencyAttr) {
|
|
482
|
+
if (
|
|
483
|
+
typeof attributeRules?.[ruleName]?.[attr]?.setDependencyRule ==
|
|
484
|
+
"function"
|
|
485
|
+
) {
|
|
486
|
+
const newRule = attributeRules?.[ruleName]?.[
|
|
487
|
+
attr
|
|
488
|
+
]?.setDependencyRule(attributeValue, data?.[attr]);
|
|
489
|
+
let newData = { [attributeName]: attributeValue };
|
|
490
|
+
if (Object.keys(data).includes(attr)) {
|
|
491
|
+
newData = { ...newData, [attr]: data?.[attr] };
|
|
492
|
+
}
|
|
493
|
+
const { errors = [] } = perfectPayloadV1(newData, {
|
|
494
|
+
[attr]: newRule,
|
|
495
|
+
});
|
|
496
|
+
rowErrors = [...rowErrors, ...errors];
|
|
497
|
+
addNextError = true;
|
|
498
|
+
} else {
|
|
499
|
+
throw new Error(
|
|
500
|
+
`perfect-payload:- function setDependencyRule not found in ${attr} dependency `,
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
break;
|
|
506
|
+
default:
|
|
507
|
+
break;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
if (attrExist && rowErrors.length == 0)
|
|
511
|
+
validatedPayload[attributeName] = attributeValue;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (rowErrors?.length) {
|
|
516
|
+
return { ...inValidPayloadResponse, errors: rowErrors };
|
|
517
|
+
} else {
|
|
518
|
+
return { ...validPayloadResponse, validatedPayload };
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export function perfectPayload(
|
|
523
|
+
data = {},
|
|
524
|
+
dataValidationRule = {},
|
|
525
|
+
validPayloadResponse = { statusCode: 200, valid: true },
|
|
526
|
+
inValidPayloadResponse = {
|
|
527
|
+
statusCode: 400,
|
|
528
|
+
valid: false,
|
|
529
|
+
message: "One or more attribute values are invalid",
|
|
530
|
+
},
|
|
531
|
+
) {
|
|
532
|
+
return perfectPayloadStructured(
|
|
533
|
+
data,
|
|
534
|
+
dataValidationRule,
|
|
535
|
+
validPayloadResponse,
|
|
536
|
+
inValidPayloadResponse,
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
function perfectPayloadStructured(
|
|
541
|
+
data = {},
|
|
542
|
+
dataValidationRule = {},
|
|
543
|
+
validPayloadResponse = { statusCode: 200, valid: true },
|
|
544
|
+
inValidPayloadResponse = {
|
|
545
|
+
statusCode: 400,
|
|
546
|
+
valid: false,
|
|
547
|
+
message: "One or more attribute values are invalid",
|
|
548
|
+
},
|
|
549
|
+
basePath = "",
|
|
550
|
+
) {
|
|
551
|
+
let validatedPayload = {};
|
|
552
|
+
let rowErrors = [];
|
|
553
|
+
|
|
554
|
+
for (const attributeName in dataValidationRule) {
|
|
555
|
+
let addNextError = true;
|
|
556
|
+
|
|
557
|
+
const attributeRules = dataValidationRule?.[attributeName];
|
|
558
|
+
|
|
559
|
+
const attributePath = getAttributePath(
|
|
560
|
+
attributeName,
|
|
561
|
+
attributeRules,
|
|
562
|
+
basePath,
|
|
563
|
+
);
|
|
564
|
+
|
|
565
|
+
const attributeValue = data?.[attributeName] ?? null;
|
|
566
|
+
|
|
567
|
+
const nullAllowed =
|
|
568
|
+
dataValidationRule?.[attributeName]?.["allowNull"] ?? true;
|
|
569
|
+
|
|
570
|
+
const isMandatoryField = attributeRules?.["mandatory"] ?? false;
|
|
571
|
+
|
|
572
|
+
const attrExist = Object.keys(data ?? {}).includes(attributeName);
|
|
573
|
+
|
|
574
|
+
for (const ruleName in attributeRules) {
|
|
575
|
+
switch (ruleName) {
|
|
576
|
+
// ==================================================
|
|
577
|
+
// MANDATORY
|
|
578
|
+
// ==================================================
|
|
579
|
+
|
|
580
|
+
case "mandatory":
|
|
581
|
+
if (isMandatoryField && !attrExist) {
|
|
582
|
+
addNextError = false;
|
|
583
|
+
|
|
584
|
+
addStructuredError(
|
|
585
|
+
rowErrors,
|
|
586
|
+
attributePath,
|
|
587
|
+
"REQUIRED",
|
|
588
|
+
attributeRules?.["mandatoryError"] ||
|
|
589
|
+
`${attributePath} is mandatory`,
|
|
590
|
+
);
|
|
591
|
+
} else if (!attrExist) {
|
|
592
|
+
addNextError = false;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
break;
|
|
596
|
+
|
|
597
|
+
// ==================================================
|
|
598
|
+
// NULL
|
|
599
|
+
// ==================================================
|
|
600
|
+
|
|
601
|
+
case "allowNull":
|
|
602
|
+
if (addNextError && attributeValue == null) {
|
|
603
|
+
if (!attributeRules?.[ruleName]) {
|
|
604
|
+
addNextError = false;
|
|
605
|
+
|
|
606
|
+
addStructuredError(
|
|
607
|
+
rowErrors,
|
|
608
|
+
attributePath,
|
|
609
|
+
"NULL_NOT_ALLOWED",
|
|
610
|
+
attributeRules?.["allowNullError"] ||
|
|
611
|
+
`value null/'' not valid for attribute ${attributePath}`,
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
break;
|
|
617
|
+
|
|
618
|
+
// ==================================================
|
|
619
|
+
// EMPTY OBJECT
|
|
620
|
+
// ==================================================
|
|
621
|
+
|
|
622
|
+
case "allowEmptyObject":
|
|
623
|
+
if (addNextError) {
|
|
624
|
+
if (
|
|
625
|
+
!attributeRules?.["allowEmptyObject"] &&
|
|
626
|
+
attributeValue != null &&
|
|
627
|
+
Object.keys(attributeValue).length === 0
|
|
628
|
+
) {
|
|
629
|
+
addStructuredError(
|
|
630
|
+
rowErrors,
|
|
631
|
+
attributePath,
|
|
632
|
+
"EMPTY_OBJECT_NOT_ALLOWED",
|
|
633
|
+
attributeRules?.["emptyObjectError"] ||
|
|
634
|
+
`value {} not valid for attribute ${attributePath}`,
|
|
635
|
+
);
|
|
636
|
+
|
|
637
|
+
addNextError = false;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
break;
|
|
642
|
+
|
|
643
|
+
// ==================================================
|
|
644
|
+
// EMPTY ARRAY
|
|
645
|
+
// ==================================================
|
|
646
|
+
|
|
647
|
+
case "allowEmptyArray":
|
|
648
|
+
if (addNextError) {
|
|
649
|
+
if (
|
|
650
|
+
!attributeRules?.["allowEmptyArray"] &&
|
|
651
|
+
isArray(attributeValue) &&
|
|
652
|
+
attributeValue.length === 0
|
|
653
|
+
) {
|
|
654
|
+
addStructuredError(
|
|
655
|
+
rowErrors,
|
|
656
|
+
attributePath,
|
|
657
|
+
"EMPTY_ARRAY_NOT_ALLOWED",
|
|
658
|
+
attributeRules?.["emptyArrayError"] ||
|
|
659
|
+
`${attributePath} cannot be an empty array`,
|
|
660
|
+
);
|
|
661
|
+
|
|
662
|
+
addNextError = false;
|
|
663
|
+
}
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
break;
|
|
667
|
+
|
|
668
|
+
// ==================================================
|
|
669
|
+
// ARRAY ELEMENT CONSTRAINTS
|
|
670
|
+
// ==================================================
|
|
671
|
+
|
|
672
|
+
case "elementConstraints":
|
|
673
|
+
if (addNextError) {
|
|
674
|
+
if (isArray(attributeValue) && attributeValue.length > 0) {
|
|
675
|
+
let elementError = null;
|
|
676
|
+
|
|
677
|
+
for (
|
|
678
|
+
let elementIndex = 0;
|
|
679
|
+
elementIndex < attributeValue.length;
|
|
680
|
+
elementIndex++
|
|
681
|
+
) {
|
|
682
|
+
const element = attributeValue[elementIndex];
|
|
683
|
+
|
|
684
|
+
const { errors = [] } = perfectPayloadStructured(
|
|
685
|
+
{
|
|
686
|
+
[attributeName]: element,
|
|
687
|
+
},
|
|
688
|
+
{
|
|
689
|
+
[attributeName]: attributeRules[ruleName],
|
|
690
|
+
},
|
|
691
|
+
);
|
|
692
|
+
|
|
693
|
+
if (errors.length > 0) {
|
|
694
|
+
const firstElementError = errors[0];
|
|
695
|
+
|
|
696
|
+
const indexedPath = replaceRootPath(
|
|
697
|
+
firstElementError.path,
|
|
698
|
+
attributeName,
|
|
699
|
+
`${attributePath}[${elementIndex}]`,
|
|
700
|
+
);
|
|
701
|
+
|
|
702
|
+
if (attributeRules?.["elementConstraintsError"]) {
|
|
703
|
+
elementError = {
|
|
704
|
+
path: indexedPath,
|
|
705
|
+
code: "INVALID_ARRAY_ELEMENT",
|
|
706
|
+
message: attributeRules["elementConstraintsError"],
|
|
707
|
+
};
|
|
708
|
+
} else {
|
|
709
|
+
elementError = {
|
|
710
|
+
...firstElementError,
|
|
711
|
+
path: indexedPath,
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
break;
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
|
|
719
|
+
if (elementError) {
|
|
720
|
+
rowErrors.push(elementError);
|
|
721
|
+
addNextError = false;
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
break;
|
|
727
|
+
|
|
728
|
+
// ==================================================
|
|
729
|
+
// REGEX
|
|
730
|
+
// ==================================================
|
|
731
|
+
|
|
732
|
+
case "regex":
|
|
733
|
+
if (addNextError) {
|
|
734
|
+
if (!isPassedRegex(attributeRules[ruleName], attributeValue)) {
|
|
735
|
+
addStructuredError(
|
|
736
|
+
rowErrors,
|
|
737
|
+
attributePath,
|
|
738
|
+
"REGEX_MISMATCH",
|
|
739
|
+
attributeRules?.["regexError"] ||
|
|
740
|
+
`${attributePath} failed to pass the regex ${attributeRules[ruleName]}`,
|
|
741
|
+
);
|
|
742
|
+
|
|
743
|
+
addNextError = false;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
break;
|
|
748
|
+
|
|
749
|
+
// ==================================================
|
|
750
|
+
// TYPE
|
|
751
|
+
// ==================================================
|
|
752
|
+
|
|
753
|
+
case "type":
|
|
754
|
+
if (addNextError) {
|
|
755
|
+
if (attributeValue == null && nullAllowed) {
|
|
756
|
+
addNextError = true;
|
|
757
|
+
} else {
|
|
758
|
+
const expectedType = attributeRules[ruleName];
|
|
759
|
+
|
|
760
|
+
switch (expectedType) {
|
|
761
|
+
case "number":
|
|
762
|
+
if (!isNumber(attributeValue)) {
|
|
763
|
+
addStructuredError(
|
|
764
|
+
rowErrors,
|
|
765
|
+
attributePath,
|
|
766
|
+
"INVALID_TYPE",
|
|
767
|
+
attributeRules?.["typeError"] ||
|
|
768
|
+
getInvalidTypeMessage(
|
|
769
|
+
attributeValue,
|
|
770
|
+
attributePath,
|
|
771
|
+
expectedType,
|
|
772
|
+
),
|
|
773
|
+
);
|
|
774
|
+
|
|
775
|
+
addNextError = false;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
break;
|
|
779
|
+
|
|
780
|
+
case "string":
|
|
781
|
+
if (!isString(attributeValue)) {
|
|
782
|
+
addStructuredError(
|
|
783
|
+
rowErrors,
|
|
784
|
+
attributePath,
|
|
785
|
+
"INVALID_TYPE",
|
|
786
|
+
attributeRules?.["typeError"] ||
|
|
787
|
+
getInvalidTypeMessage(
|
|
788
|
+
attributeValue,
|
|
789
|
+
attributePath,
|
|
790
|
+
expectedType,
|
|
791
|
+
),
|
|
792
|
+
);
|
|
793
|
+
|
|
794
|
+
addNextError = false;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
break;
|
|
798
|
+
|
|
799
|
+
case "boolean":
|
|
800
|
+
if (!isBoolean(attributeValue)) {
|
|
801
|
+
addStructuredError(
|
|
802
|
+
rowErrors,
|
|
803
|
+
attributePath,
|
|
804
|
+
"INVALID_TYPE",
|
|
805
|
+
attributeRules?.["typeError"] ||
|
|
806
|
+
getInvalidTypeMessage(
|
|
807
|
+
attributeValue,
|
|
808
|
+
attributePath,
|
|
809
|
+
expectedType,
|
|
810
|
+
),
|
|
811
|
+
);
|
|
812
|
+
|
|
813
|
+
addNextError = false;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
break;
|
|
817
|
+
|
|
818
|
+
case "email":
|
|
819
|
+
if (!isValidEmail(attributeValue)) {
|
|
820
|
+
addStructuredError(
|
|
821
|
+
rowErrors,
|
|
822
|
+
attributePath,
|
|
823
|
+
"INVALID_EMAIL",
|
|
824
|
+
attributeRules?.["typeError"] ||
|
|
825
|
+
`Invalid email format for attribute ${attributePath}`,
|
|
826
|
+
);
|
|
827
|
+
|
|
828
|
+
addNextError = false;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
break;
|
|
832
|
+
case "url":
|
|
833
|
+
if (!isValidUrl(attributeValue)) {
|
|
834
|
+
addStructuredError(
|
|
835
|
+
rowErrors,
|
|
836
|
+
attributePath,
|
|
837
|
+
"INVALID_URL",
|
|
838
|
+
attributeRules?.["typeError"] ||
|
|
839
|
+
`Invalid URL format(${attributeValue}) found in attribute ${attributePath}`,
|
|
840
|
+
);
|
|
841
|
+
|
|
842
|
+
addNextError = false;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
break;
|
|
846
|
+
|
|
847
|
+
case "enum": {
|
|
848
|
+
const allEnumValues = attributeRules["enumValues"];
|
|
849
|
+
|
|
850
|
+
if (!allEnumValues?.includes(attributeValue)) {
|
|
851
|
+
addStructuredError(
|
|
852
|
+
rowErrors,
|
|
853
|
+
attributePath,
|
|
854
|
+
"INVALID_ENUM",
|
|
855
|
+
attributeRules?.["typeError"] ||
|
|
856
|
+
`Invalid value(${attributeValue}) found in attribute ${attributePath}, valid values are ${allEnumValues?.join(
|
|
857
|
+
", ",
|
|
858
|
+
)}`,
|
|
859
|
+
);
|
|
860
|
+
|
|
861
|
+
addNextError = false;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
break;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
case "uuid":
|
|
868
|
+
if (!isUUID(attributeValue)) {
|
|
869
|
+
addStructuredError(
|
|
870
|
+
rowErrors,
|
|
871
|
+
attributePath,
|
|
872
|
+
"INVALID_UUID",
|
|
873
|
+
attributeRules?.["typeError"] ||
|
|
874
|
+
`Invalid UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
875
|
+
);
|
|
876
|
+
|
|
877
|
+
addNextError = false;
|
|
878
|
+
}
|
|
879
|
+
|
|
880
|
+
break;
|
|
881
|
+
|
|
882
|
+
case "uuidv1":
|
|
883
|
+
if (!isUUIDv1(attributeValue)) {
|
|
884
|
+
addStructuredError(
|
|
885
|
+
rowErrors,
|
|
886
|
+
attributePath,
|
|
887
|
+
"INVALID_UUID_V1",
|
|
888
|
+
attributeRules?.["typeError"] ||
|
|
889
|
+
`Invalid v1 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
890
|
+
);
|
|
891
|
+
|
|
892
|
+
addNextError = false;
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
break;
|
|
896
|
+
|
|
897
|
+
case "uuidv3":
|
|
898
|
+
if (!isUUIDv3(attributeValue)) {
|
|
899
|
+
addStructuredError(
|
|
900
|
+
rowErrors,
|
|
901
|
+
attributePath,
|
|
902
|
+
"INVALID_UUID_V3",
|
|
903
|
+
attributeRules?.["typeError"] ||
|
|
904
|
+
`Invalid v3 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
905
|
+
);
|
|
906
|
+
|
|
907
|
+
addNextError = false;
|
|
908
|
+
}
|
|
909
|
+
|
|
910
|
+
break;
|
|
911
|
+
|
|
912
|
+
case "uuidv4":
|
|
913
|
+
if (!isUUIDv4(attributeValue)) {
|
|
914
|
+
addStructuredError(
|
|
915
|
+
rowErrors,
|
|
916
|
+
attributePath,
|
|
917
|
+
"INVALID_UUID_V4",
|
|
918
|
+
attributeRules?.["typeError"] ||
|
|
919
|
+
`Invalid v4 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
920
|
+
);
|
|
921
|
+
|
|
922
|
+
addNextError = false;
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
break;
|
|
926
|
+
|
|
927
|
+
case "uuidv5":
|
|
928
|
+
if (!isUUIDv5(attributeValue)) {
|
|
929
|
+
addStructuredError(
|
|
930
|
+
rowErrors,
|
|
931
|
+
attributePath,
|
|
932
|
+
"INVALID_UUID_V5",
|
|
933
|
+
attributeRules?.["typeError"] ||
|
|
934
|
+
`Invalid v5 UUID(${attributeValue}) found in attribute ${attributePath}`,
|
|
935
|
+
);
|
|
936
|
+
|
|
937
|
+
addNextError = false;
|
|
938
|
+
}
|
|
939
|
+
|
|
940
|
+
break;
|
|
941
|
+
|
|
942
|
+
case "objectId":
|
|
943
|
+
if (!isObjectId(attributeValue)) {
|
|
944
|
+
addStructuredError(
|
|
945
|
+
rowErrors,
|
|
946
|
+
attributePath,
|
|
947
|
+
"INVALID_OBJECT_ID",
|
|
948
|
+
attributeRules?.["typeError"] ||
|
|
949
|
+
`Invalid ObjectId(${attributeValue}) found in attribute ${attributePath}`,
|
|
950
|
+
);
|
|
951
|
+
|
|
952
|
+
addNextError = false;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
break;
|
|
956
|
+
|
|
957
|
+
case "array":
|
|
958
|
+
if (!isArray(attributeValue)) {
|
|
959
|
+
addStructuredError(
|
|
960
|
+
rowErrors,
|
|
961
|
+
attributePath,
|
|
962
|
+
"INVALID_TYPE",
|
|
963
|
+
attributeRules?.["typeError"] ||
|
|
964
|
+
getInvalidTypeMessage(
|
|
965
|
+
attributeValue,
|
|
966
|
+
attributePath,
|
|
967
|
+
expectedType,
|
|
968
|
+
),
|
|
969
|
+
);
|
|
970
|
+
|
|
971
|
+
addNextError = false;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
break;
|
|
975
|
+
|
|
976
|
+
case "object":
|
|
977
|
+
if (!isObject(attributeValue)) {
|
|
978
|
+
addStructuredError(
|
|
979
|
+
rowErrors,
|
|
980
|
+
attributePath,
|
|
981
|
+
"INVALID_TYPE",
|
|
982
|
+
attributeRules?.["typeError"] ||
|
|
983
|
+
getInvalidTypeMessage(
|
|
984
|
+
attributeValue,
|
|
985
|
+
attributePath,
|
|
986
|
+
expectedType,
|
|
987
|
+
),
|
|
988
|
+
);
|
|
989
|
+
|
|
990
|
+
addNextError = false;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
break;
|
|
994
|
+
|
|
995
|
+
default:
|
|
996
|
+
break;
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
}
|
|
1000
|
+
|
|
1001
|
+
break;
|
|
1002
|
+
|
|
1003
|
+
// ==================================================
|
|
1004
|
+
// MIN LENGTH
|
|
1005
|
+
// ==================================================
|
|
1006
|
+
|
|
1007
|
+
case "minLength":
|
|
1008
|
+
if (addNextError) {
|
|
1009
|
+
if (attributeValue == null && nullAllowed) {
|
|
1010
|
+
addNextError = true;
|
|
1011
|
+
} else if (typeof attributeValue === "string") {
|
|
1012
|
+
if (attributeValue.length < +attributeRules[ruleName]) {
|
|
1013
|
+
addStructuredError(
|
|
1014
|
+
rowErrors,
|
|
1015
|
+
attributePath,
|
|
1016
|
+
"MIN_LENGTH",
|
|
1017
|
+
attributeRules?.["minLengthError"] ||
|
|
1018
|
+
`${attributePath} should be minimum of ${attributeRules[ruleName]} character`,
|
|
1019
|
+
);
|
|
1020
|
+
|
|
1021
|
+
addNextError = false;
|
|
1022
|
+
}
|
|
1023
|
+
} else {
|
|
1024
|
+
addStructuredError(
|
|
1025
|
+
rowErrors,
|
|
1026
|
+
attributePath,
|
|
1027
|
+
"INVALID_TYPE",
|
|
1028
|
+
`${attributePath} value should be a string type(minLength specified)`,
|
|
1029
|
+
);
|
|
1030
|
+
|
|
1031
|
+
addNextError = false;
|
|
1032
|
+
}
|
|
1033
|
+
}
|
|
1034
|
+
|
|
1035
|
+
break;
|
|
1036
|
+
|
|
1037
|
+
// ==================================================
|
|
1038
|
+
// MAX LENGTH
|
|
1039
|
+
// ==================================================
|
|
1040
|
+
|
|
1041
|
+
case "maxLength":
|
|
1042
|
+
if (addNextError) {
|
|
1043
|
+
if (attributeValue == null && nullAllowed) {
|
|
1044
|
+
addNextError = true;
|
|
1045
|
+
} else if (typeof attributeValue === "string") {
|
|
1046
|
+
if (attributeValue.length > +attributeRules[ruleName]) {
|
|
1047
|
+
addStructuredError(
|
|
1048
|
+
rowErrors,
|
|
1049
|
+
attributePath,
|
|
1050
|
+
"MAX_LENGTH",
|
|
1051
|
+
attributeRules?.["maxLengthError"] ||
|
|
1052
|
+
`${attributePath} can have maximum of ${attributeRules[ruleName]} character`,
|
|
1053
|
+
);
|
|
1054
|
+
|
|
1055
|
+
addNextError = false;
|
|
1056
|
+
}
|
|
1057
|
+
} else {
|
|
1058
|
+
addStructuredError(
|
|
1059
|
+
rowErrors,
|
|
1060
|
+
attributePath,
|
|
1061
|
+
"INVALID_TYPE",
|
|
1062
|
+
`${attributePath} value should be a string type(maxLength specified)`,
|
|
1063
|
+
);
|
|
1064
|
+
|
|
1065
|
+
addNextError = false;
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
|
|
1069
|
+
break;
|
|
1070
|
+
|
|
1071
|
+
// ==================================================
|
|
1072
|
+
// PREVENT DECIMAL
|
|
1073
|
+
// ==================================================
|
|
1074
|
+
|
|
1075
|
+
case "preventDecimal":
|
|
1076
|
+
if (addNextError) {
|
|
1077
|
+
if (attributeValue == null && nullAllowed) {
|
|
1078
|
+
addNextError = true;
|
|
1079
|
+
} else if (!isNumber(attributeValue)) {
|
|
1080
|
+
addStructuredError(
|
|
1081
|
+
rowErrors,
|
|
1082
|
+
attributePath,
|
|
1083
|
+
"INVALID_TYPE",
|
|
1084
|
+
`Invalid ${typeof attributeValue} value(${attributeValue}) found in attribute ${attributePath}, required number value`,
|
|
1085
|
+
);
|
|
1086
|
+
|
|
1087
|
+
addNextError = false;
|
|
1088
|
+
} else if (+attributeValue % 1 !== 0) {
|
|
1089
|
+
addStructuredError(
|
|
1090
|
+
rowErrors,
|
|
1091
|
+
attributePath,
|
|
1092
|
+
"DECIMAL_NOT_ALLOWED",
|
|
1093
|
+
attributeRules?.["preventDecimalError"] ||
|
|
1094
|
+
`Decimal value not allowed in attribute ${attributePath}(${attributeValue})`,
|
|
1095
|
+
);
|
|
1096
|
+
|
|
1097
|
+
addNextError = false;
|
|
1098
|
+
}
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
break;
|
|
1102
|
+
|
|
1103
|
+
// ==================================================
|
|
1104
|
+
// MIN
|
|
1105
|
+
// ==================================================
|
|
1106
|
+
|
|
1107
|
+
case "min":
|
|
1108
|
+
if (addNextError) {
|
|
1109
|
+
if (attributeValue == null && nullAllowed) {
|
|
1110
|
+
addNextError = true;
|
|
1111
|
+
} else if (!isNumber(attributeValue)) {
|
|
1112
|
+
addStructuredError(
|
|
1113
|
+
rowErrors,
|
|
1114
|
+
attributePath,
|
|
1115
|
+
"INVALID_TYPE",
|
|
1116
|
+
`Invalid type for attribute ${attributePath}, required number value`,
|
|
1117
|
+
);
|
|
1118
|
+
|
|
1119
|
+
addNextError = false;
|
|
1120
|
+
} else if (+attributeValue < +attributeRules[ruleName]) {
|
|
1121
|
+
addStructuredError(
|
|
1122
|
+
rowErrors,
|
|
1123
|
+
attributePath,
|
|
1124
|
+
"MIN_VALUE",
|
|
1125
|
+
attributeRules?.["minError"] ||
|
|
1126
|
+
`Minimum value ${attributeRules[ruleName]} is allowed in attribute ${attributePath}`,
|
|
1127
|
+
);
|
|
1128
|
+
|
|
1129
|
+
addNextError = false;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
|
|
1133
|
+
break;
|
|
1134
|
+
// ==================================================
|
|
1135
|
+
// MAX
|
|
1136
|
+
// ==================================================
|
|
1137
|
+
case "max":
|
|
1138
|
+
if (addNextError) {
|
|
1139
|
+
if (attributeValue == null && nullAllowed) {
|
|
1140
|
+
addNextError = true;
|
|
1141
|
+
} else if (!isNumber(attributeValue)) {
|
|
1142
|
+
addStructuredError(
|
|
1143
|
+
rowErrors,
|
|
1144
|
+
attributePath,
|
|
1145
|
+
"INVALID_TYPE",
|
|
1146
|
+
`Invalid type for attribute ${attributePath}, required number value`,
|
|
1147
|
+
);
|
|
1148
|
+
|
|
1149
|
+
addNextError = false;
|
|
1150
|
+
} else if (+attributeValue > +attributeRules[ruleName]) {
|
|
1151
|
+
addStructuredError(
|
|
1152
|
+
rowErrors,
|
|
1153
|
+
attributePath,
|
|
1154
|
+
"MAX_VALUE",
|
|
1155
|
+
attributeRules?.["maxError"] ||
|
|
1156
|
+
`Maximum value ${attributeRules[ruleName]} is allowed in attribute ${attributePath}`,
|
|
1157
|
+
);
|
|
1158
|
+
|
|
1159
|
+
addNextError = false;
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
break;
|
|
1164
|
+
|
|
1165
|
+
// ==================================================
|
|
1166
|
+
// RANGE
|
|
1167
|
+
// ==================================================
|
|
1168
|
+
|
|
1169
|
+
case "range":
|
|
1170
|
+
if (addNextError) {
|
|
1171
|
+
if (attributeValue == null && nullAllowed) {
|
|
1172
|
+
addNextError = true;
|
|
1173
|
+
} else if (!isNumber(attributeValue)) {
|
|
1174
|
+
addStructuredError(
|
|
1175
|
+
rowErrors,
|
|
1176
|
+
attributePath,
|
|
1177
|
+
"INVALID_TYPE",
|
|
1178
|
+
`Invalid type for attribute ${attributePath}, required number value`,
|
|
1179
|
+
);
|
|
1180
|
+
|
|
1181
|
+
addNextError = false;
|
|
1182
|
+
} else {
|
|
1183
|
+
const [min, max] = attributeRules[ruleName].split("-");
|
|
1184
|
+
|
|
1185
|
+
if (+attributeValue < +min || +attributeValue > +max) {
|
|
1186
|
+
addStructuredError(
|
|
1187
|
+
rowErrors,
|
|
1188
|
+
attributePath,
|
|
1189
|
+
"OUT_OF_RANGE",
|
|
1190
|
+
attributeRules?.["rangeError"] ||
|
|
1191
|
+
`Attribute ${attributePath} should have a value between ${min} and ${max}`,
|
|
1192
|
+
);
|
|
1193
|
+
|
|
1194
|
+
addNextError = false;
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
|
|
1199
|
+
break;
|
|
1200
|
+
// ==================================================
|
|
1201
|
+
// NESTED OBJECT
|
|
1202
|
+
// ==================================================
|
|
1203
|
+
|
|
1204
|
+
case "objectAttr":
|
|
1205
|
+
if (addNextError) {
|
|
1206
|
+
const { errors = [] } = perfectPayloadStructured(
|
|
1207
|
+
attributeValue,
|
|
1208
|
+
attributeRules[ruleName],
|
|
1209
|
+
{ statusCode: 200, valid: true },
|
|
1210
|
+
{
|
|
1211
|
+
statusCode: 400,
|
|
1212
|
+
valid: false,
|
|
1213
|
+
message: "One or more attribute values are invalid",
|
|
1214
|
+
},
|
|
1215
|
+
attributePath,
|
|
1216
|
+
);
|
|
1217
|
+
|
|
1218
|
+
rowErrors = [...rowErrors, ...errors];
|
|
1219
|
+
|
|
1220
|
+
addNextError = true;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
break;
|
|
1224
|
+
|
|
1225
|
+
// ==================================================
|
|
1226
|
+
// DEPENDENCY
|
|
1227
|
+
// ==================================================
|
|
1228
|
+
|
|
1229
|
+
case "dependency":
|
|
1230
|
+
if (addNextError) {
|
|
1231
|
+
const allDependencyAttr = Object.keys(attributeRules?.[ruleName]);
|
|
1232
|
+
|
|
1233
|
+
for (const attr of allDependencyAttr) {
|
|
1234
|
+
const dependencyRule = attributeRules?.[ruleName]?.[attr];
|
|
1235
|
+
|
|
1236
|
+
if (typeof dependencyRule?.setDependencyRule === "function") {
|
|
1237
|
+
const newRule = dependencyRule.setDependencyRule(
|
|
1238
|
+
attributeValue,
|
|
1239
|
+
data?.[attr],
|
|
1240
|
+
);
|
|
1241
|
+
|
|
1242
|
+
let newData = {
|
|
1243
|
+
[attributeName]: attributeValue,
|
|
1244
|
+
};
|
|
1245
|
+
|
|
1246
|
+
if (Object.keys(data ?? {}).includes(attr)) {
|
|
1247
|
+
newData = {
|
|
1248
|
+
...newData,
|
|
1249
|
+
[attr]: data?.[attr],
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
const { errors = [] } = perfectPayloadStructured(
|
|
1254
|
+
newData,
|
|
1255
|
+
{
|
|
1256
|
+
[attr]: newRule,
|
|
1257
|
+
},
|
|
1258
|
+
{
|
|
1259
|
+
statusCode: 200,
|
|
1260
|
+
valid: true,
|
|
1261
|
+
},
|
|
1262
|
+
{
|
|
1263
|
+
statusCode: 400,
|
|
1264
|
+
valid: false,
|
|
1265
|
+
message: "One or more attribute values are invalid",
|
|
1266
|
+
},
|
|
1267
|
+
basePath,
|
|
1268
|
+
);
|
|
1269
|
+
|
|
1270
|
+
rowErrors = [...rowErrors, ...errors];
|
|
1271
|
+
|
|
1272
|
+
addNextError = true;
|
|
1273
|
+
} else {
|
|
1274
|
+
throw new Error(
|
|
1275
|
+
`perfect-payload:- function setDependencyRule not found in ${attr} dependency `,
|
|
1276
|
+
);
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
break;
|
|
1282
|
+
|
|
1283
|
+
default:
|
|
1284
|
+
break;
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
if (
|
|
1289
|
+
attrExist &&
|
|
1290
|
+
!rowErrors.some(
|
|
1291
|
+
(error) =>
|
|
1292
|
+
error.path === attributePath ||
|
|
1293
|
+
error.path.startsWith(`${attributePath}.`) ||
|
|
1294
|
+
error.path.startsWith(`${attributePath}[`),
|
|
1295
|
+
)
|
|
1296
|
+
) {
|
|
1297
|
+
validatedPayload[attributeName] = attributeValue;
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
|
|
1301
|
+
if (rowErrors.length > 0) {
|
|
1302
|
+
return {
|
|
1303
|
+
...inValidPayloadResponse,
|
|
1304
|
+
errors: rowErrors,
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
return {
|
|
1309
|
+
...validPayloadResponse,
|
|
1310
|
+
validatedPayload,
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
function addStructuredError(errors, path, code, message) {
|
|
1315
|
+
errors.push({
|
|
1316
|
+
path,
|
|
1317
|
+
code,
|
|
1318
|
+
message,
|
|
1319
|
+
});
|
|
1320
|
+
}
|
|
1321
|
+
|
|
1322
|
+
function getAttributePath(attributeName, attributeRules, basePath) {
|
|
1323
|
+
const customPath = attributeRules?.path;
|
|
1324
|
+
|
|
1325
|
+
if (customPath) {
|
|
1326
|
+
return `${customPath}.${attributeName}`;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
if (basePath) {
|
|
1330
|
+
return `${basePath}.${attributeName}`;
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
return attributeName;
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
function replaceRootPath(currentPath, currentRoot, replacementRoot) {
|
|
1337
|
+
if (currentPath === currentRoot) {
|
|
1338
|
+
return replacementRoot;
|
|
1339
|
+
}
|
|
1340
|
+
|
|
1341
|
+
if (currentPath.startsWith(`${currentRoot}.`)) {
|
|
1342
|
+
return `${replacementRoot}${currentPath.slice(currentRoot.length)}`;
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
if (currentPath.startsWith(`${currentRoot}[`)) {
|
|
1346
|
+
return `${replacementRoot}${currentPath.slice(currentRoot.length)}`;
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
return replacementRoot;
|
|
1350
|
+
}
|
|
1351
|
+
|
|
1352
|
+
function getInvalidTypeMessage(value, attributePath, expectedType) {
|
|
1353
|
+
return `Invalid type for attribute ${attributePath}, required ${expectedType} value`;
|
|
1354
|
+
// return `Invalid ${typeof value} value(${value}) found in attribute ${attributePath}, required ${expectedType} value`;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
function isNumber(value) {
|
|
1358
|
+
return typeof value == "number";
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
function isString(value) {
|
|
1362
|
+
return typeof value == "string";
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1365
|
+
function isBoolean(value) {
|
|
1366
|
+
return typeof value == "boolean";
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
function isArray(value) {
|
|
1370
|
+
return Array.isArray(value);
|
|
1371
|
+
}
|
|
1372
|
+
|
|
1373
|
+
function isObject(value) {
|
|
1374
|
+
return typeof value == "object";
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
function isValidEmail(email) {
|
|
1378
|
+
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
|
|
1379
|
+
return emailRegex.test(email);
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
function isValidUrl(url) {
|
|
1383
|
+
const urlRegex =
|
|
1384
|
+
/^(https?:\/\/)([a-zA-Z0-9.-]+\.[a-zA-Z]{2,})(:[0-9]+)?(\/[^\s]*)?(\?[^\s]*)?$/;
|
|
1385
|
+
return urlRegex.test(url);
|
|
1386
|
+
}
|
|
1387
|
+
|
|
1388
|
+
function isUUID(uuid) {
|
|
1389
|
+
const uuidRegex =
|
|
1390
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1391
|
+
|
|
1392
|
+
return uuidRegex.test(uuid);
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
function isUUIDv1(uuid) {
|
|
1396
|
+
const uuidRegex =
|
|
1397
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-1[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1398
|
+
|
|
1399
|
+
return uuidRegex.test(uuid);
|
|
1400
|
+
}
|
|
1401
|
+
|
|
1402
|
+
function isUUIDv3(uuid) {
|
|
1403
|
+
const uuidRegex =
|
|
1404
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-3[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1405
|
+
|
|
1406
|
+
return uuidRegex.test(uuid);
|
|
1407
|
+
}
|
|
1408
|
+
|
|
1409
|
+
function isUUIDv4(uuid) {
|
|
1410
|
+
const uuidRegex =
|
|
1411
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1412
|
+
|
|
1413
|
+
return uuidRegex.test(uuid);
|
|
1414
|
+
}
|
|
1415
|
+
|
|
1416
|
+
function isUUIDv5(uuid) {
|
|
1417
|
+
const uuidRegex =
|
|
1418
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
1419
|
+
|
|
1420
|
+
return uuidRegex.test(uuid);
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
function isObjectId(id) {
|
|
1424
|
+
return /^[0-9a-fA-F]{24}$/.test(id);
|
|
1425
|
+
}
|
|
1426
|
+
|
|
1427
|
+
function isPassedRegex(reExpression, value) {
|
|
1428
|
+
return reExpression.test(value);
|
|
1429
|
+
}
|