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 CHANGED
@@ -149,6 +149,7 @@ const interfaces = Object.freeze({
149
149
  TAGS: "tags",
150
150
  ARRAY_OF_VALUES: "array_of_values",
151
151
  OBJECT: "object",
152
+ SEO: "seo",
152
153
  });
153
154
 
154
155
  const API_VERSION = Object.freeze({
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 ([constants.interfaces.MANY_TO_ONE].includes(interfaceType)) {
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
- return Math.floor(date.getTime() / 1000);
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 Math.floor(date.getTime() / 1000);
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
- rule.value = rule.value?.map((key) => {
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}", rule.value[0]);
738
- valid = fieldValueParsed === getComparableValue(rule.value[0]);
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}", rule.value[0]);
745
- valid = fieldValueParsed !== getComparableValue(rule.value[0]);
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}", rule.value[0]);
752
- valid = fieldValueParsed < getComparableValue(rule.value[0]);
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}", rule.value[0]);
759
- valid = fieldValueParsed <= getComparableValue(rule.value[0]);
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}", rule.value[0]);
766
- valid = fieldValueParsed > getComparableValue(rule.value[0]);
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}", rule.value[0]);
773
- valid = fieldValueParsed >= getComparableValue(rule.value[0]);
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
- valid = rule.value.includes(fieldValue);
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
- valid = !rule.value.includes(fieldValue);
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}", rule.value[0]);
834
+ ?.replace("{value}", messageValue);
801
835
  valid = typeChecks[rule.value[0]](fieldValue);
802
836
  break;
803
837
  case constants.operatorTypes.MOD:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nox-validation",
3
- "version": "1.5.5",
3
+ "version": "1.5.7",
4
4
  "description": "validate dynamic schema",
5
5
  "main": "index.js",
6
6
  "scripts": {