perfect-payload 1.3.0 → 1.4.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 +589 -377
- package/index.js +99 -16
- package/package.json +1 -1
package/index.js
CHANGED
|
@@ -562,7 +562,7 @@ function perfectPayloadStructured(
|
|
|
562
562
|
basePath,
|
|
563
563
|
);
|
|
564
564
|
|
|
565
|
-
|
|
565
|
+
let attributeValue = data?.[attributeName] ?? null;
|
|
566
566
|
|
|
567
567
|
const nullAllowed =
|
|
568
568
|
dataValidationRule?.[attributeName]?.["allowNull"] ?? true;
|
|
@@ -570,7 +570,72 @@ function perfectPayloadStructured(
|
|
|
570
570
|
const isMandatoryField = attributeRules?.["mandatory"] ?? false;
|
|
571
571
|
|
|
572
572
|
const attrExist = Object.keys(data ?? {}).includes(attributeName);
|
|
573
|
+
// TRANSFORMATIONS START
|
|
574
|
+
// NO MULTI TRANSFORMATION
|
|
575
|
+
if (
|
|
576
|
+
attributeRules?.lowercase === true &&
|
|
577
|
+
attributeRules?.uppercase === true
|
|
578
|
+
) {
|
|
579
|
+
throw new Error(
|
|
580
|
+
`perfect-payload:- lowercase and uppercase cannot both be enabled for attribute ${attributePath}`,
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
// TRIM
|
|
584
|
+
if (
|
|
585
|
+
attrExist &&
|
|
586
|
+
attributeValue !== null &&
|
|
587
|
+
attributeRules?.trim === true &&
|
|
588
|
+
typeof attributeValue === "string"
|
|
589
|
+
) {
|
|
590
|
+
attributeValue = attributeValue.trim();
|
|
591
|
+
}
|
|
592
|
+
// LOWERCASE
|
|
593
|
+
if (
|
|
594
|
+
attrExist &&
|
|
595
|
+
attributeValue !== null &&
|
|
596
|
+
attributeRules?.lowercase === true &&
|
|
597
|
+
typeof attributeValue === "string"
|
|
598
|
+
) {
|
|
599
|
+
attributeValue = attributeValue.toLowerCase();
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// UPPERCASE
|
|
603
|
+
|
|
604
|
+
if (
|
|
605
|
+
attrExist &&
|
|
606
|
+
attributeValue !== null &&
|
|
607
|
+
attributeRules?.uppercase === true &&
|
|
608
|
+
typeof attributeValue === "string"
|
|
609
|
+
) {
|
|
610
|
+
attributeValue = attributeValue.toUpperCase();
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
// CUSTOM TRANSFORM
|
|
614
|
+
|
|
615
|
+
if (
|
|
616
|
+
attrExist &&
|
|
617
|
+
attributeValue !== null &&
|
|
618
|
+
attributeRules?.transform !== undefined
|
|
619
|
+
) {
|
|
620
|
+
const transformer = attributeRules.transform;
|
|
621
|
+
|
|
622
|
+
if (typeof transformer !== "function") {
|
|
623
|
+
throw new Error(
|
|
624
|
+
`perfect-payload:- transform must be a function for attribute ${attributePath}`,
|
|
625
|
+
);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const transformedValue = transformer(attributeValue, data);
|
|
629
|
+
|
|
630
|
+
if (transformedValue && typeof transformedValue.then === "function") {
|
|
631
|
+
throw new Error(
|
|
632
|
+
`perfect-payload:- transform must be synchronous for attribute ${attributePath}`,
|
|
633
|
+
);
|
|
634
|
+
}
|
|
573
635
|
|
|
636
|
+
attributeValue = transformedValue;
|
|
637
|
+
}
|
|
638
|
+
// TRANSFORMATIONS END
|
|
574
639
|
for (const ruleName in attributeRules) {
|
|
575
640
|
switch (ruleName) {
|
|
576
641
|
// ==================================================
|
|
@@ -674,6 +739,9 @@ function perfectPayloadStructured(
|
|
|
674
739
|
if (isArray(attributeValue) && attributeValue.length > 0) {
|
|
675
740
|
let elementError = null;
|
|
676
741
|
|
|
742
|
+
// Clone so original payload array is not mutated
|
|
743
|
+
const transformedArray = [...attributeValue];
|
|
744
|
+
|
|
677
745
|
for (
|
|
678
746
|
let elementIndex = 0;
|
|
679
747
|
elementIndex < attributeValue.length;
|
|
@@ -681,7 +749,10 @@ function perfectPayloadStructured(
|
|
|
681
749
|
) {
|
|
682
750
|
const element = attributeValue[elementIndex];
|
|
683
751
|
|
|
684
|
-
const {
|
|
752
|
+
const {
|
|
753
|
+
errors = [],
|
|
754
|
+
validatedPayload: elementValidatedPayload,
|
|
755
|
+
} = perfectPayloadStructured(
|
|
685
756
|
{
|
|
686
757
|
[attributeName]: element,
|
|
687
758
|
},
|
|
@@ -714,11 +785,18 @@ function perfectPayloadStructured(
|
|
|
714
785
|
|
|
715
786
|
break;
|
|
716
787
|
}
|
|
788
|
+
|
|
789
|
+
// Preserve the transformed element
|
|
790
|
+
transformedArray[elementIndex] =
|
|
791
|
+
elementValidatedPayload?.[attributeName];
|
|
717
792
|
}
|
|
718
793
|
|
|
719
794
|
if (elementError) {
|
|
720
795
|
rowErrors.push(elementError);
|
|
721
796
|
addNextError = false;
|
|
797
|
+
} else {
|
|
798
|
+
// All elements passed, so use transformed values
|
|
799
|
+
attributeValue = transformedArray;
|
|
722
800
|
}
|
|
723
801
|
}
|
|
724
802
|
}
|
|
@@ -1200,24 +1278,29 @@ function perfectPayloadStructured(
|
|
|
1200
1278
|
// ==================================================
|
|
1201
1279
|
// NESTED OBJECT
|
|
1202
1280
|
// ==================================================
|
|
1203
|
-
|
|
1204
1281
|
case "objectAttr":
|
|
1205
1282
|
if (addNextError) {
|
|
1206
|
-
const { errors = [] } =
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1283
|
+
const { errors = [], validatedPayload: nestedValidatedPayload } =
|
|
1284
|
+
perfectPayloadStructured(
|
|
1285
|
+
attributeValue,
|
|
1286
|
+
attributeRules?.[ruleName],
|
|
1287
|
+
{
|
|
1288
|
+
statusCode: 200,
|
|
1289
|
+
valid: true,
|
|
1290
|
+
},
|
|
1291
|
+
{
|
|
1292
|
+
statusCode: 400,
|
|
1293
|
+
valid: false,
|
|
1294
|
+
message: "One or more attribute values are invalid",
|
|
1295
|
+
},
|
|
1296
|
+
attributePath,
|
|
1297
|
+
);
|
|
1217
1298
|
|
|
1218
|
-
|
|
1299
|
+
if (errors.length === 0) {
|
|
1300
|
+
attributeValue = nestedValidatedPayload;
|
|
1301
|
+
}
|
|
1219
1302
|
|
|
1220
|
-
|
|
1303
|
+
rowErrors = [...rowErrors, ...errors];
|
|
1221
1304
|
}
|
|
1222
1305
|
|
|
1223
1306
|
break;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "perfect-payload",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Lightweight JSON payload validation library with structured errors, nested validation, field paths, and customizable validation rules.",
|
|
6
6
|
"main": "index.js",
|