nox-validation 1.5.5 → 1.5.7
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/constant.js +1 -0
- package/lib/helpers.js +8 -1
- package/lib/validate.js +65 -31
- package/package.json +1 -1
package/lib/constant.js
CHANGED
package/lib/helpers.js
CHANGED
|
@@ -247,7 +247,12 @@ const generateType = (field, api) => {
|
|
|
247
247
|
}
|
|
248
248
|
} else {
|
|
249
249
|
// It is Relational Field, so we have to update type and array type accordingly interface
|
|
250
|
-
if (
|
|
250
|
+
if (
|
|
251
|
+
[
|
|
252
|
+
constants.interfaces.MANY_TO_ONE,
|
|
253
|
+
constants.interfaces.SEO,
|
|
254
|
+
].includes(interfaceType)
|
|
255
|
+
) {
|
|
251
256
|
fieldType = constants.types.OBJECT_ID;
|
|
252
257
|
}
|
|
253
258
|
|
|
@@ -278,6 +283,7 @@ const generateType = (field, api) => {
|
|
|
278
283
|
constants.interfaces.MANY_TO_MANY,
|
|
279
284
|
constants.interfaces.MANY_TO_ANY,
|
|
280
285
|
constants.interfaces.MANY_TO_ONE,
|
|
286
|
+
constants.interfaces.SEO,
|
|
281
287
|
constants.interfaces.TRANSLATIONS,
|
|
282
288
|
].includes(interfaceType)
|
|
283
289
|
) {
|
|
@@ -641,6 +647,7 @@ const getForeignCollectionDetails = ({
|
|
|
641
647
|
|
|
642
648
|
const isSingleRelation = [
|
|
643
649
|
constants.interfaces.MANY_TO_ONE,
|
|
650
|
+
constants.interfaces.SEO,
|
|
644
651
|
constants.interfaces.FILE,
|
|
645
652
|
constants.interfaces.FILE_IMAGE,
|
|
646
653
|
].includes(iFace);
|
package/lib/validate.js
CHANGED
|
@@ -23,6 +23,7 @@ const relational_interfaces = [
|
|
|
23
23
|
constants.interfaces.ONE_TO_MANY,
|
|
24
24
|
constants.interfaces.MANY_TO_ONE,
|
|
25
25
|
constants.interfaces.MANY_TO_ANY,
|
|
26
|
+
constants.interfaces.SEO,
|
|
26
27
|
constants.interfaces.TRANSLATIONS,
|
|
27
28
|
];
|
|
28
29
|
|
|
@@ -218,6 +219,7 @@ const isEmptyRelational = ({
|
|
|
218
219
|
case constants.interfaces.MANY_TO_MANY:
|
|
219
220
|
case constants.interfaces.ONE_TO_MANY:
|
|
220
221
|
case constants.interfaces.MANY_TO_ONE:
|
|
222
|
+
case constants.interfaces.SEO:
|
|
221
223
|
return remainingItems({
|
|
222
224
|
all: Array.isArray(existingValue)
|
|
223
225
|
? existingValue.length === 0
|
|
@@ -416,6 +418,7 @@ const validateMetaRules = (
|
|
|
416
418
|
constants.interfaces.ONE_TO_MANY,
|
|
417
419
|
constants.interfaces.MANY_TO_ONE,
|
|
418
420
|
constants.interfaces.MANY_TO_ANY,
|
|
421
|
+
constants.interfaces.SEO,
|
|
419
422
|
"none",
|
|
420
423
|
].includes(field?.meta?.interface)) ||
|
|
421
424
|
(field?.meta?.interface === constants.interfaces.TRANSLATIONS &&
|
|
@@ -659,22 +662,41 @@ const validateOperatorRule = (
|
|
|
659
662
|
return hh * 3600 + mm * 60 + ss;
|
|
660
663
|
};
|
|
661
664
|
|
|
665
|
+
// Helper to parse date string to UTC midnight timestamp
|
|
666
|
+
const parseDateToUTC = (value) => {
|
|
667
|
+
if (!value) return NaN;
|
|
668
|
+
const date = new Date(value);
|
|
669
|
+
// Set to UTC midnight
|
|
670
|
+
return Date.UTC(
|
|
671
|
+
date.getUTCFullYear(),
|
|
672
|
+
date.getUTCMonth(),
|
|
673
|
+
date.getUTCDate()
|
|
674
|
+
);
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
// Helper to parse datetime string to UTC timestamp (seconds/milliseconds)
|
|
678
|
+
const parseDateTimeToUTC = (value) => {
|
|
679
|
+
if (!value) return NaN;
|
|
680
|
+
const date = new Date(value);
|
|
681
|
+
return date.getTime();
|
|
682
|
+
};
|
|
683
|
+
|
|
662
684
|
const getComparableValue = (value, forMessage = false) => {
|
|
663
685
|
if (isNumber) return Number(value);
|
|
664
686
|
if (isDate) {
|
|
665
|
-
const date = new Date(value);
|
|
666
|
-
date.setHours(0, 0, 0, 0);
|
|
667
687
|
if (forMessage) {
|
|
688
|
+
// Format as YYYY-MM-DD
|
|
689
|
+
const date = new Date(value);
|
|
668
690
|
return `${date.getUTCFullYear()}-${String(
|
|
669
691
|
date.getUTCMonth() + 1
|
|
670
692
|
).padStart(2, "0")}-${String(date.getUTCDate()).padStart(2, "0")}`;
|
|
671
693
|
}
|
|
672
|
-
|
|
694
|
+
// Return UTC midnight timestamp for comparison
|
|
695
|
+
return parseDateToUTC(value);
|
|
673
696
|
}
|
|
674
697
|
if (isDateTime) {
|
|
675
|
-
const date = new Date(value);
|
|
676
|
-
|
|
677
698
|
if (forMessage) {
|
|
699
|
+
const date = new Date(value);
|
|
678
700
|
return (
|
|
679
701
|
`${date.getUTCFullYear()}-${String(date.getUTCMonth() + 1).padStart(
|
|
680
702
|
2,
|
|
@@ -685,8 +707,8 @@ const validateOperatorRule = (
|
|
|
685
707
|
).padStart(2, "0")}:${String(date.getUTCSeconds()).padStart(2, "0")}`
|
|
686
708
|
);
|
|
687
709
|
}
|
|
688
|
-
|
|
689
|
-
return
|
|
710
|
+
// Return UTC timestamp for comparison
|
|
711
|
+
return parseDateTimeToUTC(value);
|
|
690
712
|
}
|
|
691
713
|
if (isTime) {
|
|
692
714
|
if (forMessage) {
|
|
@@ -697,20 +719,23 @@ const validateOperatorRule = (
|
|
|
697
719
|
return value;
|
|
698
720
|
};
|
|
699
721
|
|
|
700
|
-
|
|
701
|
-
const value = isFieldCompare
|
|
702
|
-
? getComparableValue(getValue(formData, key), true)
|
|
703
|
-
: getComparableValue(key, true);
|
|
704
|
-
return value ? value : key;
|
|
705
|
-
});
|
|
706
|
-
|
|
722
|
+
// For date/datetime, parse to comparable value (timestamp)
|
|
707
723
|
const fieldValueParsed = getComparableValue(fieldValue);
|
|
708
724
|
|
|
709
725
|
const messageValue = Array.isArray(rule.value)
|
|
710
|
-
? rule.value.join(", ")
|
|
711
|
-
: String(rule.value);
|
|
726
|
+
? rule.value?.map((key) => getComparableValue(key, true)).join(", ")
|
|
727
|
+
: String(getComparableValue(rule.value, true));
|
|
712
728
|
let message = "";
|
|
713
729
|
|
|
730
|
+
// For date/datetime, rule.value should be parsed to comparable value (timestamp)
|
|
731
|
+
rule.value = rule.value?.map((key) => {
|
|
732
|
+
const value = isFieldCompare
|
|
733
|
+
? getComparableValue(getValue(formData, key), false)
|
|
734
|
+
: getComparableValue(key, false);
|
|
735
|
+
// For date/datetime, allow 0 as valid value
|
|
736
|
+
return value !== undefined && value !== null ? value : key;
|
|
737
|
+
});
|
|
738
|
+
|
|
714
739
|
switch (rule.options.operator) {
|
|
715
740
|
case constants.operatorTypes.AND:
|
|
716
741
|
message = custom_message ?? error_messages.AND;
|
|
@@ -734,57 +759,66 @@ const validateOperatorRule = (
|
|
|
734
759
|
message = custom_message ?? error_messages.EQUAL;
|
|
735
760
|
message = message
|
|
736
761
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
737
|
-
?.replace("{value}",
|
|
738
|
-
valid = fieldValueParsed ===
|
|
762
|
+
?.replace("{value}", messageValue);
|
|
763
|
+
valid = fieldValueParsed === rule.value[0];
|
|
739
764
|
break;
|
|
740
765
|
case constants.operatorTypes.NOT_EQUAL:
|
|
741
766
|
message = custom_message ?? error_messages.NOT_EQUAL;
|
|
742
767
|
message = message
|
|
743
768
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
744
|
-
?.replace("{value}",
|
|
745
|
-
valid = fieldValueParsed !==
|
|
769
|
+
?.replace("{value}", messageValue);
|
|
770
|
+
valid = fieldValueParsed !== rule.value[0];
|
|
746
771
|
break;
|
|
747
772
|
case constants.operatorTypes.LESS_THAN:
|
|
748
773
|
message = custom_message ?? error_messages.LESS_THAN;
|
|
749
774
|
message = message
|
|
750
775
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
751
|
-
?.replace("{value}",
|
|
752
|
-
valid = fieldValueParsed <
|
|
776
|
+
?.replace("{value}", messageValue);
|
|
777
|
+
valid = fieldValueParsed < rule.value[0];
|
|
753
778
|
break;
|
|
754
779
|
case constants.operatorTypes.LESS_THAN_EQUAL:
|
|
755
780
|
message = custom_message ?? error_messages.LESS_THAN_EQUAL;
|
|
756
781
|
message = message
|
|
757
782
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
758
|
-
?.replace("{value}",
|
|
759
|
-
valid = fieldValueParsed <=
|
|
783
|
+
?.replace("{value}", messageValue);
|
|
784
|
+
valid = fieldValueParsed <= rule.value[0];
|
|
760
785
|
break;
|
|
761
786
|
case constants.operatorTypes.GREATER_THAN:
|
|
762
787
|
message = custom_message ?? error_messages.GREATER_THAN;
|
|
763
788
|
message = message
|
|
764
789
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
765
|
-
?.replace("{value}",
|
|
766
|
-
valid = fieldValueParsed >
|
|
790
|
+
?.replace("{value}", messageValue);
|
|
791
|
+
valid = fieldValueParsed > rule.value[0];
|
|
767
792
|
break;
|
|
768
793
|
case constants.operatorTypes.GREATER_THAN_EQUAL:
|
|
769
794
|
message = custom_message ?? error_messages.GREATER_THAN_EQUAL;
|
|
770
795
|
message = message
|
|
771
796
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
772
|
-
?.replace("{value}",
|
|
773
|
-
valid = fieldValueParsed >=
|
|
797
|
+
?.replace("{value}", messageValue);
|
|
798
|
+
valid = fieldValueParsed >= rule.value[0];
|
|
774
799
|
break;
|
|
775
800
|
case constants.operatorTypes.IN:
|
|
776
801
|
message = custom_message ?? error_messages.IN;
|
|
777
802
|
message = message
|
|
778
803
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
779
804
|
?.replace("{value}", messageValue);
|
|
780
|
-
|
|
805
|
+
// For date/datetime, compare timestamps
|
|
806
|
+
if (isDate || isDateTime) {
|
|
807
|
+
valid = rule.value.includes(fieldValueParsed);
|
|
808
|
+
} else {
|
|
809
|
+
valid = rule.value.includes(fieldValue);
|
|
810
|
+
}
|
|
781
811
|
break;
|
|
782
812
|
case constants.operatorTypes.NOT_IN:
|
|
783
813
|
message = custom_message ?? error_messages.NOT_IN;
|
|
784
814
|
message = message
|
|
785
815
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
786
816
|
?.replace("{value}", messageValue);
|
|
787
|
-
|
|
817
|
+
if (isDate || isDateTime) {
|
|
818
|
+
valid = !rule.value.includes(fieldValueParsed);
|
|
819
|
+
} else {
|
|
820
|
+
valid = !rule.value.includes(fieldValue);
|
|
821
|
+
}
|
|
788
822
|
break;
|
|
789
823
|
case constants.operatorTypes.EXISTS:
|
|
790
824
|
message = custom_message ?? error_messages.EXISTS;
|
|
@@ -797,7 +831,7 @@ const validateOperatorRule = (
|
|
|
797
831
|
message = custom_message ?? error_messages.TYPE;
|
|
798
832
|
message = message
|
|
799
833
|
?.replace(`{field}`, formatLabel(field.display_label))
|
|
800
|
-
?.replace("{value}",
|
|
834
|
+
?.replace("{value}", messageValue);
|
|
801
835
|
valid = typeChecks[rule.value[0]](fieldValue);
|
|
802
836
|
break;
|
|
803
837
|
case constants.operatorTypes.MOD:
|