nox-validation 1.7.2 → 1.7.4
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/lib/helpers.js +18 -0
- package/lib/validate.js +118 -45
- package/package.json +1 -1
package/lib/helpers.js
CHANGED
|
@@ -1604,6 +1604,23 @@ const rebuildFullPath = (nodePath, fullPath, modifierFn) => {
|
|
|
1604
1604
|
: `${modifiedNodePath}`.replace(/\.+/g, ".");
|
|
1605
1605
|
};
|
|
1606
1606
|
|
|
1607
|
+
const trimBasicPath = (basePath, staticType = "update") => {
|
|
1608
|
+
const regex = new RegExp(`${staticType}\\[\\d+\\]`, "g");
|
|
1609
|
+
const matches = [...basePath.matchAll(regex)];
|
|
1610
|
+
|
|
1611
|
+
if (matches.length === 0) return basePath; // no update/create/delete/etc found
|
|
1612
|
+
|
|
1613
|
+
// Last matched dynamic segment (e.g. "update[3]")
|
|
1614
|
+
const lastSegment = matches[matches.length - 1][0];
|
|
1615
|
+
|
|
1616
|
+
// Find starting index of this last segment
|
|
1617
|
+
const idx = basePath.lastIndexOf(lastSegment);
|
|
1618
|
+
|
|
1619
|
+
// Return everything BEFORE this segment (and remove trailing dot)
|
|
1620
|
+
const result = basePath.substring(0, idx).replace(/\.$/, "");
|
|
1621
|
+
return result;
|
|
1622
|
+
};
|
|
1623
|
+
|
|
1607
1624
|
module.exports = {
|
|
1608
1625
|
generateModifiedRules,
|
|
1609
1626
|
getFieldsGroupBySchemaId,
|
|
@@ -1628,4 +1645,5 @@ module.exports = {
|
|
|
1628
1645
|
remainingItems,
|
|
1629
1646
|
formatDate,
|
|
1630
1647
|
rebuildFullPath,
|
|
1648
|
+
trimBasicPath,
|
|
1631
1649
|
};
|
package/lib/validate.js
CHANGED
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
remainingItems,
|
|
15
15
|
formatDate,
|
|
16
16
|
rebuildFullPath,
|
|
17
|
+
trimBasicPath,
|
|
17
18
|
} = require("./helpers");
|
|
18
19
|
|
|
19
20
|
const choices = ["radio", "checkboxes", "dropdown_multiple", "dropdown"];
|
|
@@ -399,6 +400,7 @@ const validateMetaRules = (
|
|
|
399
400
|
`{field}`,
|
|
400
401
|
formatLabel(field.display_label)
|
|
401
402
|
);
|
|
403
|
+
|
|
402
404
|
addError(
|
|
403
405
|
currentPath,
|
|
404
406
|
translatedPath
|
|
@@ -470,8 +472,23 @@ const validateMetaRules = (
|
|
|
470
472
|
) {
|
|
471
473
|
getSelectedNodes({
|
|
472
474
|
node: field,
|
|
473
|
-
skipFn: (node) =>
|
|
474
|
-
|
|
475
|
+
skipFn: (node) => {
|
|
476
|
+
let status = false;
|
|
477
|
+
if (node.meta?.interface === constants.interfaces.MANY_TO_ANY)
|
|
478
|
+
status = true;
|
|
479
|
+
|
|
480
|
+
if (
|
|
481
|
+
[
|
|
482
|
+
constants.interfaces.MANY_TO_MANY,
|
|
483
|
+
constants.interfaces.ONE_TO_MANY,
|
|
484
|
+
constants.interfaces.MANY_TO_ONE,
|
|
485
|
+
constants.interfaces.SEO,
|
|
486
|
+
].includes(node.meta?.interface) &&
|
|
487
|
+
(!node.meta?.required || !node.meta?.hidden)
|
|
488
|
+
)
|
|
489
|
+
status = true;
|
|
490
|
+
return status;
|
|
491
|
+
},
|
|
475
492
|
conditionFn: (node) =>
|
|
476
493
|
node.meta?.required === true && !node.isRelationalUpdate,
|
|
477
494
|
mapFn: (node) => ({
|
|
@@ -479,6 +496,24 @@ const validateMetaRules = (
|
|
|
479
496
|
label: node.display_label,
|
|
480
497
|
}),
|
|
481
498
|
actionFn: (node) => {
|
|
499
|
+
const normalize = (path) => path.replace(/\[\d+\]/g, "[]");
|
|
500
|
+
|
|
501
|
+
const getRoot = (path) => normalize(path).split(".")[0];
|
|
502
|
+
|
|
503
|
+
const buildError = (path, translated) => {
|
|
504
|
+
if (!isEmpty(getValue(formData, path))) return;
|
|
505
|
+
let obj = {
|
|
506
|
+
label,
|
|
507
|
+
fieldPath: path,
|
|
508
|
+
description: "",
|
|
509
|
+
message,
|
|
510
|
+
};
|
|
511
|
+
if (translated) {
|
|
512
|
+
obj.translation_path = translated;
|
|
513
|
+
}
|
|
514
|
+
addError(path, obj, node);
|
|
515
|
+
};
|
|
516
|
+
|
|
482
517
|
const isTranslationNode =
|
|
483
518
|
node?.meta?.parentInterface === constants.interfaces.TRANSLATIONS ||
|
|
484
519
|
field?.meta?.interface === constants.interfaces.TRANSLATIONS;
|
|
@@ -498,12 +533,25 @@ const validateMetaRules = (
|
|
|
498
533
|
|
|
499
534
|
if (
|
|
500
535
|
currentPath &&
|
|
501
|
-
currentPath
|
|
502
|
-
!fPath.
|
|
536
|
+
currentPath.trim() !== "" &&
|
|
537
|
+
!normalize(fPath).startsWith(normalize(currentPath)) &&
|
|
538
|
+
getRoot(fPath) !== getRoot(currentPath)
|
|
503
539
|
) {
|
|
504
|
-
fPath
|
|
540
|
+
if (currentPath.includes(fPath)) {
|
|
541
|
+
fPath = currentPath;
|
|
542
|
+
} else fPath = `${currentPath}.${fPath}`;
|
|
505
543
|
}
|
|
506
544
|
|
|
545
|
+
// if (
|
|
546
|
+
// currentPath &&
|
|
547
|
+
// currentPath?.trim() !== "" &&
|
|
548
|
+
// !fPath.includes(currentPath)
|
|
549
|
+
// // TODO: Need to Optimize This fPath => group.items.dropdown currentPath => group.items[0].dropdown final path becomes => group.items[0].dropdown.group.items.dropdown
|
|
550
|
+
// // also translations.create[0].meta_description <=fPath condition currentPath => seo.create[0].translations.create[0].meta_description then condition becomes true but parent is not same then need to merge
|
|
551
|
+
// ) {
|
|
552
|
+
// fPath = `${currentPath}.${fPath}`;
|
|
553
|
+
// }
|
|
554
|
+
|
|
507
555
|
if (staticType === "update") return;
|
|
508
556
|
if (staticType === "delete" && !isTranslationNode) return;
|
|
509
557
|
if (staticType === "existing" && !isTranslationNode) return;
|
|
@@ -511,34 +559,21 @@ const validateMetaRules = (
|
|
|
511
559
|
const label = formatLabel(node.display_label);
|
|
512
560
|
const message = error_messages.REQUIRED.replace("{field}", label);
|
|
513
561
|
|
|
514
|
-
const buildError = (path, translated) => {
|
|
515
|
-
if (!isEmpty(getValue(formData, path))) return;
|
|
516
|
-
let obj = {
|
|
517
|
-
label,
|
|
518
|
-
fieldPath: path,
|
|
519
|
-
description: "",
|
|
520
|
-
message,
|
|
521
|
-
};
|
|
522
|
-
if (translated) {
|
|
523
|
-
obj.translation_path = translated;
|
|
524
|
-
}
|
|
525
|
-
addError(path, obj, node);
|
|
526
|
-
};
|
|
527
|
-
|
|
528
562
|
const isMultiLang =
|
|
529
563
|
isTranslationNode &&
|
|
530
564
|
Array.isArray(language_codes) &&
|
|
531
565
|
language_codes.length > 1;
|
|
566
|
+
|
|
532
567
|
if (isMultiLang) {
|
|
568
|
+
const fullPath = fPath;
|
|
569
|
+
|
|
533
570
|
language_codes.forEach((lang, index) => {
|
|
534
571
|
let langPath, transformedPath;
|
|
535
572
|
let isAdded = false;
|
|
536
|
-
|
|
537
|
-
// Check if current language entry exists in fieldValue.create
|
|
573
|
+
// // Check if current language entry exists in fieldValue.create
|
|
538
574
|
if (
|
|
539
575
|
Array.isArray(fieldValue?.create) &&
|
|
540
576
|
fieldValue?.create.some((item, idx) => {
|
|
541
|
-
// Check by languages_code or by index match
|
|
542
577
|
return item.languages_code === lang || idx === index;
|
|
543
578
|
})
|
|
544
579
|
) {
|
|
@@ -549,25 +584,21 @@ const validateMetaRules = (
|
|
|
549
584
|
node?.value?.includes("create[0].") ||
|
|
550
585
|
node?.value?.includes("create[0]")
|
|
551
586
|
) {
|
|
552
|
-
langPath = rebuildFullPath(node.value,
|
|
587
|
+
langPath = rebuildFullPath(node.value, fPath, (path) =>
|
|
553
588
|
path.replace(/create\[0\]\./, `create[${index}].`)
|
|
554
589
|
);
|
|
555
|
-
transformedPath = rebuildFullPath(
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
?.replace("create", "");
|
|
562
|
-
return newPath;
|
|
563
|
-
}
|
|
564
|
-
);
|
|
590
|
+
transformedPath = rebuildFullPath(node.value, fPath, (path) => {
|
|
591
|
+
const newPath = path
|
|
592
|
+
.replace(/\[0\]\./, `.${lang}.`)
|
|
593
|
+
?.replace("create", "");
|
|
594
|
+
return newPath;
|
|
595
|
+
});
|
|
565
596
|
} else {
|
|
566
|
-
langPath = rebuildFullPath(node.value,
|
|
597
|
+
langPath = rebuildFullPath(node.value, fPath, (path) => {
|
|
567
598
|
return path.replace(/create\./, `create[${index}].`);
|
|
568
599
|
});
|
|
569
600
|
|
|
570
|
-
transformedPath = rebuildFullPath(node.value,
|
|
601
|
+
transformedPath = rebuildFullPath(node.value, fPath, (path) =>
|
|
571
602
|
path.replace(/\[0\]\./, `.${lang}.`)?.replace("create", "")
|
|
572
603
|
);
|
|
573
604
|
}
|
|
@@ -1128,16 +1159,7 @@ const validateField = (
|
|
|
1128
1159
|
timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone,
|
|
1129
1160
|
translatedPath = null
|
|
1130
1161
|
) => {
|
|
1131
|
-
|
|
1132
|
-
onlyFormFields == true &&
|
|
1133
|
-
value === undefined &&
|
|
1134
|
-
![constants.interfaces.TRANSLATIONS, constants.interfaces.SEO].includes(
|
|
1135
|
-
field?.meta?.interface
|
|
1136
|
-
)
|
|
1137
|
-
)
|
|
1138
|
-
return;
|
|
1139
|
-
|
|
1140
|
-
const { is_m2a_item } = field?.meta;
|
|
1162
|
+
const { is_m2a_item, staticType = null, parentInterface } = field?.meta;
|
|
1141
1163
|
const currentPath = fieldPath
|
|
1142
1164
|
? `${fieldPath}.${field.key.split(".").pop()}`
|
|
1143
1165
|
: field.key;
|
|
@@ -1147,6 +1169,50 @@ const validateField = (
|
|
|
1147
1169
|
? `${translatedPath}.${field.key.split(".").pop()}`
|
|
1148
1170
|
: field.key;
|
|
1149
1171
|
}
|
|
1172
|
+
|
|
1173
|
+
if (
|
|
1174
|
+
onlyFormFields == true &&
|
|
1175
|
+
value === undefined &&
|
|
1176
|
+
![constants.interfaces.TRANSLATIONS, constants.interfaces.SEO].includes(
|
|
1177
|
+
field?.meta?.interface
|
|
1178
|
+
)
|
|
1179
|
+
) {
|
|
1180
|
+
if (
|
|
1181
|
+
onlyFormFields == true &&
|
|
1182
|
+
value === undefined &&
|
|
1183
|
+
staticType === "update" &&
|
|
1184
|
+
parentInterface === constants.interfaces.TRANSLATIONS &&
|
|
1185
|
+
field?.meta.required
|
|
1186
|
+
) {
|
|
1187
|
+
const langCode = getValue(formData, fieldPath)?.languages_code;
|
|
1188
|
+
const translationFieldPath = trimBasicPath(currentPath, staticType);
|
|
1189
|
+
const existingItemValue = getValue(
|
|
1190
|
+
existingForm,
|
|
1191
|
+
translationFieldPath
|
|
1192
|
+
)?.find((item) => item.languages_code === langCode)?.[
|
|
1193
|
+
`${field.key.split(".").pop()}`
|
|
1194
|
+
];
|
|
1195
|
+
|
|
1196
|
+
if (isEmpty(existingItemValue)) {
|
|
1197
|
+
const message = error_messages.REQUIRED.replace(
|
|
1198
|
+
`{field}`,
|
|
1199
|
+
formatLabel(`${field.key.split(".").pop()}`)
|
|
1200
|
+
);
|
|
1201
|
+
addError(
|
|
1202
|
+
currentPath,
|
|
1203
|
+
{
|
|
1204
|
+
label: formatLabel(`${field.key.split(".").pop()}`),
|
|
1205
|
+
fieldPath: currentPath,
|
|
1206
|
+
translation_path: translatedPath,
|
|
1207
|
+
description: "",
|
|
1208
|
+
message,
|
|
1209
|
+
},
|
|
1210
|
+
field
|
|
1211
|
+
);
|
|
1212
|
+
}
|
|
1213
|
+
} else return;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1150
1216
|
const fieldLabel = formatLabel(field.display_label);
|
|
1151
1217
|
|
|
1152
1218
|
validateMetaRules(
|
|
@@ -1263,6 +1329,13 @@ const validateField = (
|
|
|
1263
1329
|
)
|
|
1264
1330
|
trPath = trPath.replace(".update.", ".");
|
|
1265
1331
|
|
|
1332
|
+
if (
|
|
1333
|
+
trPath &&
|
|
1334
|
+
field.meta?.staticType === "create" &&
|
|
1335
|
+
trPath.includes(".create.")
|
|
1336
|
+
)
|
|
1337
|
+
trPath = trPath.replace(".create.", ".");
|
|
1338
|
+
|
|
1266
1339
|
validateField(
|
|
1267
1340
|
child,
|
|
1268
1341
|
item[child.key.split(".").pop()],
|