@react-querybuilder/core 8.13.0 → 8.14.1

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.
Files changed (100) hide show
  1. package/dist/{basic-Cw014pDc.d.mts → basic-BXJVfD0P.d.ts} +77 -59
  2. package/dist/{basic-_KlsCAyT.d.ts → basic-CNIjb6rI.d.mts} +77 -59
  3. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +201 -150
  4. package/dist/cjs/react-querybuilder_core.cjs.development.js +323 -252
  5. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  6. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +201 -150
  7. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  8. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  9. package/dist/{convertQuery-DAj92cbM.mjs → convertQuery-B5Qm_6ut.mjs} +30 -22
  10. package/dist/convertQuery-B5Qm_6ut.mjs.map +1 -0
  11. package/dist/convertQuery-DfZehtnd.js +94 -0
  12. package/dist/convertQuery-DfZehtnd.js.map +1 -0
  13. package/dist/{export-CffjLxEe.d.mts → export-6x7MilFR.d.mts} +2 -3
  14. package/dist/{export-DRA8O1Wz.d.ts → export-CpJOQuZv.d.ts} +2 -3
  15. package/dist/formatQuery.d.mts +4 -3
  16. package/dist/formatQuery.d.ts +4 -3
  17. package/dist/formatQuery.js +42 -51
  18. package/dist/formatQuery.js.map +1 -1
  19. package/dist/formatQuery.mjs +41 -50
  20. package/dist/formatQuery.mjs.map +1 -1
  21. package/dist/{import-CWYJkN_w.d.ts → import-B5Iq8XmL.d.ts} +2 -3
  22. package/dist/{import-DjHGaGhJ.d.mts → import-Bltb2mT4.d.mts} +2 -3
  23. package/dist/{isRuleGroup-Cjk1Q2mj.js → isRuleGroup-BCwaLzDj.js} +38 -40
  24. package/dist/isRuleGroup-BCwaLzDj.js.map +1 -0
  25. package/dist/{isRuleGroup-DztIOOKa.mjs → isRuleGroup-LzP0HCKh.mjs} +2 -4
  26. package/dist/isRuleGroup-LzP0HCKh.mjs.map +1 -0
  27. package/dist/parseCEL.d.mts +2 -2
  28. package/dist/parseCEL.d.ts +2 -2
  29. package/dist/parseCEL.js +14 -16
  30. package/dist/parseCEL.js.map +1 -1
  31. package/dist/parseCEL.mjs +7 -10
  32. package/dist/parseCEL.mjs.map +1 -1
  33. package/dist/parseJSONata.d.mts +2 -3
  34. package/dist/parseJSONata.d.ts +2 -3
  35. package/dist/parseJSONata.js +37 -5611
  36. package/dist/parseJSONata.js.map +1 -1
  37. package/dist/parseJSONata.mjs +11 -14
  38. package/dist/parseJSONata.mjs.map +1 -1
  39. package/dist/parseJsonLogic.d.mts +3 -4
  40. package/dist/parseJsonLogic.d.ts +3 -4
  41. package/dist/parseJsonLogic.js +20 -21
  42. package/dist/parseJsonLogic.js.map +1 -1
  43. package/dist/parseJsonLogic.mjs +19 -21
  44. package/dist/parseJsonLogic.mjs.map +1 -1
  45. package/dist/parseMongoDB.d.mts +2 -3
  46. package/dist/parseMongoDB.d.ts +2 -3
  47. package/dist/parseMongoDB.js +7 -8
  48. package/dist/parseMongoDB.js.map +1 -1
  49. package/dist/parseMongoDB.mjs +6 -8
  50. package/dist/parseMongoDB.mjs.map +1 -1
  51. package/dist/parseSQL.d.mts +2 -3
  52. package/dist/parseSQL.d.ts +2 -3
  53. package/dist/parseSQL.js +14 -16
  54. package/dist/parseSQL.js.map +1 -1
  55. package/dist/parseSQL.mjs +7 -10
  56. package/dist/parseSQL.mjs.map +1 -1
  57. package/dist/parseSpEL.d.mts +2 -3
  58. package/dist/parseSpEL.d.ts +2 -3
  59. package/dist/parseSpEL.js +11 -2700
  60. package/dist/parseSpEL.js.map +1 -1
  61. package/dist/parseSpEL.mjs +7 -9
  62. package/dist/parseSpEL.mjs.map +1 -1
  63. package/dist/{prepareQueryObjects-CkN0bTKm.js → prepareQueryObjects-Dc8rqsYM.js} +50 -38
  64. package/dist/prepareQueryObjects-Dc8rqsYM.js.map +1 -0
  65. package/dist/{prepareQueryObjects-6Bxx4Bs1.mjs → prepareQueryObjects-tMukQHT9.mjs} +35 -22
  66. package/dist/prepareQueryObjects-tMukQHT9.mjs.map +1 -0
  67. package/dist/react-querybuilder_core.d.mts +201 -150
  68. package/dist/react-querybuilder_core.legacy-esm.d.ts +201 -150
  69. package/dist/react-querybuilder_core.legacy-esm.js +317 -280
  70. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  71. package/dist/react-querybuilder_core.mjs +312 -248
  72. package/dist/react-querybuilder_core.mjs.map +1 -1
  73. package/dist/react-querybuilder_core.production.d.mts +201 -150
  74. package/dist/react-querybuilder_core.production.mjs +1 -1
  75. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  76. package/dist/transformQuery.d.mts +1 -2
  77. package/dist/transformQuery.d.ts +1 -2
  78. package/dist/transformQuery.js +44 -3
  79. package/dist/transformQuery.js.map +1 -0
  80. package/dist/transformQuery.mjs +43 -3
  81. package/dist/transformQuery.mjs.map +1 -0
  82. package/dist/{utils-nQU7WCM9.mjs → utils-DQoYnxpa.mjs} +32 -84
  83. package/dist/utils-DQoYnxpa.mjs.map +1 -0
  84. package/dist/{utils-CR1ToTMW.js → utils-EsYRkPtf.js} +182 -246
  85. package/dist/utils-EsYRkPtf.js.map +1 -0
  86. package/package.json +29 -21
  87. package/dist/chunk-U64pC571.js +0 -41
  88. package/dist/convertQuery-DAj92cbM.mjs.map +0 -1
  89. package/dist/convertQuery-DRldbzhZ.js +0 -87
  90. package/dist/convertQuery-DRldbzhZ.js.map +0 -1
  91. package/dist/isRuleGroup-Cjk1Q2mj.js.map +0 -1
  92. package/dist/isRuleGroup-DztIOOKa.mjs.map +0 -1
  93. package/dist/prepareQueryObjects-6Bxx4Bs1.mjs.map +0 -1
  94. package/dist/prepareQueryObjects-CkN0bTKm.js.map +0 -1
  95. package/dist/transformQuery-ClBRfnFg.js +0 -54
  96. package/dist/transformQuery-ClBRfnFg.js.map +0 -1
  97. package/dist/transformQuery-DUpbpqjX.mjs +0 -48
  98. package/dist/transformQuery-DUpbpqjX.mjs.map +0 -1
  99. package/dist/utils-CR1ToTMW.js.map +0 -1
  100. package/dist/utils-nQU7WCM9.mjs.map +0 -1
@@ -1,6 +1,6 @@
1
- let immer = require("immer");
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  let numeric_quantity = require("numeric-quantity");
3
-
3
+ let immer = require("immer");
4
4
  //#region src/defaults.ts
5
5
  /**
6
6
  * @group Defaults
@@ -15,7 +15,7 @@ const defaultPlaceholderLabel = "------";
15
15
  *
16
16
  * @group Defaults
17
17
  */
18
- const defaultPlaceholderFieldName = defaultPlaceholderName;
18
+ const defaultPlaceholderFieldName = "~";
19
19
  /**
20
20
  * Default `label` for placeholder option in the `fields` array.
21
21
  *
@@ -33,7 +33,7 @@ const defaultPlaceholderFieldGroupLabel = defaultPlaceholderLabel;
33
33
  *
34
34
  * @group Defaults
35
35
  */
36
- const defaultPlaceholderOperatorName = defaultPlaceholderName;
36
+ const defaultPlaceholderOperatorName = "~";
37
37
  /**
38
38
  * Default `label` for placeholder option in the `operators` array.
39
39
  *
@@ -51,7 +51,7 @@ const defaultPlaceholderOperatorGroupLabel = defaultPlaceholderLabel;
51
51
  *
52
52
  * @group Defaults
53
53
  */
54
- const defaultPlaceholderValueName = defaultPlaceholderName;
54
+ const defaultPlaceholderValueName = "~";
55
55
  /**
56
56
  * Default `label` for placeholder option in the `values` array.
57
57
  *
@@ -72,19 +72,19 @@ const defaultPlaceholderValueGroupLabel = defaultPlaceholderLabel;
72
72
  const defaultTranslations = {
73
73
  fields: {
74
74
  title: "Field",
75
- placeholderName: defaultPlaceholderFieldName,
75
+ placeholderName: "~",
76
76
  placeholderLabel: defaultPlaceholderFieldLabel,
77
77
  placeholderGroupLabel: defaultPlaceholderFieldGroupLabel
78
78
  },
79
79
  operators: {
80
80
  title: "Operator",
81
- placeholderName: defaultPlaceholderOperatorName,
81
+ placeholderName: "~",
82
82
  placeholderLabel: defaultPlaceholderOperatorLabel,
83
83
  placeholderGroupLabel: defaultPlaceholderOperatorGroupLabel
84
84
  },
85
85
  values: {
86
86
  title: "Values",
87
- placeholderName: defaultPlaceholderValueName,
87
+ placeholderName: "~",
88
88
  placeholderLabel: defaultPlaceholderValueLabel,
89
89
  placeholderGroupLabel: defaultPlaceholderValueGroupLabel
90
90
  },
@@ -562,7 +562,6 @@ const queryBuilderFlagDefaults = {
562
562
  showShiftActions: false,
563
563
  suppressStandardClassnames: false
564
564
  };
565
-
566
565
  //#endregion
567
566
  //#region src/utils/arrayUtils.ts
568
567
  /**
@@ -577,7 +576,7 @@ const queryBuilderFlagDefaults = {
577
576
  * // would return
578
577
  * ['this,,that', '', 'the other', '', '', ',']
579
578
  */
580
- const splitBy = (str, splitChar = defaultJoinChar) => typeof str === "string" ? str.split(`\\${splitChar}`).map((c) => c.split(splitChar)).reduce((prev, curr, idx) => {
579
+ const splitBy = (str, splitChar = ",") => typeof str === "string" ? str.split(`\\${splitChar}`).map((c) => c.split(splitChar)).reduce((prev, curr, idx) => {
581
580
  if (idx === 0) return curr;
582
581
  return [
583
582
  ...prev.slice(0, -1),
@@ -598,7 +597,7 @@ const splitBy = (str, splitChar = defaultJoinChar) => typeof str === "string" ?
598
597
  * // would return
599
598
  * 'this\\,\\,that, , the other, , , \\,'
600
599
  */
601
- const joinWith = (strArr, joinChar = defaultJoinChar) => strArr.map((str) => `${str ?? ""}`.replaceAll(joinChar[0], `\\${joinChar[0]}`)).join(joinChar);
600
+ const joinWith = (strArr, joinChar = ",") => strArr.map((str) => `${str ?? ""}`.replaceAll(joinChar[0], `\\${joinChar[0]}`)).join(joinChar);
602
601
  /**
603
602
  * Trims the value if it is a string. Otherwise returns the value as is.
604
603
  */
@@ -607,12 +606,11 @@ const trimIfString = (val) => typeof val === "string" ? val.trim() : val;
607
606
  * Splits a string by comma then trims each element. Arrays are returned as is except
608
607
  * any string elements are trimmed.
609
608
  */
610
- const toArray = (v, { retainEmptyStrings } = {}) => Array.isArray(v) ? v.map((v$1) => trimIfString(v$1)) : typeof v === "string" ? splitBy(v, defaultJoinChar).filter(retainEmptyStrings ? () => true : (s) => !/^\s*$/.test(s)).map((s) => s.trim()) : typeof v === "number" ? [v] : [];
609
+ const toArray = (a, { retainEmptyStrings } = {}) => Array.isArray(a) ? a.map((v) => trimIfString(v)) : typeof a === "string" ? splitBy(a, ",").filter(retainEmptyStrings ? () => true : (s) => !/^\s*$/.test(s)).map((s) => s.trim()) : typeof a === "number" ? [a] : [];
611
610
  /**
612
611
  * Determines if an array is free of `null`/`undefined`.
613
612
  */
614
613
  const nullFreeArray = (arr) => arr.every((el) => el === false || (el ?? false) !== false);
615
-
616
614
  //#endregion
617
615
  //#region src/utils/clsx.ts
618
616
  // istanbul ignore next
@@ -653,7 +651,6 @@ function clsx(...args) {
653
651
  }
654
652
  return str;
655
653
  }
656
-
657
654
  //#endregion
658
655
  //#region src/utils/misc.ts
659
656
  /**
@@ -674,7 +671,6 @@ const isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object
674
671
  * Simple helper to determine whether a value is null, undefined, or an empty string.
675
672
  */
676
673
  const nullOrUndefinedOrEmpty = (value) => value === null || value === void 0 || value === "";
677
-
678
674
  //#endregion
679
675
  //#region src/utils/isRuleGroup.ts
680
676
  /**
@@ -693,7 +689,6 @@ const isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "str
693
689
  * Determines if an object is a {@link RuleGroupTypeIC}.
694
690
  */
695
691
  const isRuleGroupTypeIC = (rg) => isRuleGroup(rg) && rg.combinator === void 0;
696
-
697
692
  //#endregion
698
693
  //#region src/utils/convertQuery.ts
699
694
  const combinatorLevels = [
@@ -705,20 +700,27 @@ const isSameString = (a, b) => lc(a) === b;
705
700
  const generateRuleGroupICWithConsistentCombinators = (rg, baseCombinatorLevel = 0) => {
706
701
  const baseCombinator = combinatorLevels[baseCombinatorLevel];
707
702
  if (!rg.rules.includes(baseCombinator)) return baseCombinatorLevel < combinatorLevels.length - 2 ? generateRuleGroupICWithConsistentCombinators(rg, baseCombinatorLevel + 1) : rg;
708
- return (0, immer.produce)(rg, (draft) => {
709
- let cursor = 0;
710
- while (cursor < draft.rules.length - 2) {
711
- if (isSameString(draft.rules[cursor + 1], baseCombinator)) {
712
- cursor += 2;
713
- continue;
714
- }
715
- const nextBaseCombinatorIndex = draft.rules.findIndex((r, i) => i > cursor && typeof r === "string" && lc(r) === baseCombinator);
716
- if (nextBaseCombinatorIndex === -1) {
717
- draft.rules.splice(cursor, draft.rules.length, generateRuleGroupICWithConsistentCombinators({ rules: draft.rules.slice(cursor) }, baseCombinatorLevel + 1));
718
- break;
719
- } else draft.rules.splice(cursor, nextBaseCombinatorIndex - cursor, generateRuleGroupICWithConsistentCombinators({ rules: draft.rules.slice(cursor, nextBaseCombinatorIndex) }, baseCombinatorLevel + 1));
703
+ const newRules = [...rg.rules];
704
+ let cursor = 0;
705
+ while (cursor < newRules.length - 2) {
706
+ if (isSameString(newRules[cursor + 1], baseCombinator)) {
707
+ cursor += 2;
708
+ continue;
720
709
  }
721
- });
710
+ let nextBaseCombinatorIndex = -1;
711
+ for (let i = cursor + 2; i < newRules.length; i++) if (typeof newRules[i] === "string" && lc(newRules[i]) === baseCombinator) {
712
+ nextBaseCombinatorIndex = i;
713
+ break;
714
+ }
715
+ if (nextBaseCombinatorIndex === -1) {
716
+ newRules.splice(cursor, newRules.length, generateRuleGroupICWithConsistentCombinators({ rules: newRules.slice(cursor) }, baseCombinatorLevel + 1));
717
+ break;
718
+ } else newRules.splice(cursor, nextBaseCombinatorIndex - cursor, generateRuleGroupICWithConsistentCombinators({ rules: newRules.slice(cursor, nextBaseCombinatorIndex) }, baseCombinatorLevel + 1));
719
+ }
720
+ return {
721
+ ...rg,
722
+ rules: newRules
723
+ };
722
724
  };
723
725
  /**
724
726
  * Converts a {@link RuleGroupTypeIC} to {@link RuleGroupType}.
@@ -731,9 +733,11 @@ const generateRuleGroupICWithConsistentCombinators = (rg, baseCombinatorLevel =
731
733
  const convertFromIC = (rg) => {
732
734
  if (isRuleGroupType(rg)) return rg;
733
735
  const processedRG = generateRuleGroupICWithConsistentCombinators(rg);
734
- const rulesAsMixedList = processedRG.rules.map((r) => typeof r === "string" || !isRuleGroup(r) ? r : convertFromIC(r));
735
- const combinator = rulesAsMixedList.length < 2 ? "and" : rulesAsMixedList[1];
736
- const rules = rulesAsMixedList.filter((r) => typeof r !== "string");
736
+ const rules = [];
737
+ let combinator = "and";
738
+ for (const [idx, r] of processedRG.rules.entries()) if (typeof r === "string") {
739
+ if (idx === 1) combinator = r;
740
+ } else rules.push(isRuleGroup(r) ? convertFromIC(r) : r);
737
741
  return {
738
742
  ...processedRG,
739
743
  combinator,
@@ -753,7 +757,8 @@ const convertToIC = (rg) => {
753
757
  const { combinator, ...queryWithoutCombinator } = rg;
754
758
  const rules = [];
755
759
  const { length } = rg.rules;
756
- for (const [idx, r] of rg.rules.entries()) {
760
+ for (let idx = 0; idx < length; idx++) {
761
+ const r = rg.rules[idx];
757
762
  if (isRuleGroup(r)) rules.push(convertToIC(r));
758
763
  else rules.push(r);
759
764
  if (combinator && idx < length - 1) rules.push(combinator);
@@ -766,7 +771,6 @@ const convertToIC = (rg) => {
766
771
  function convertQuery(query) {
767
772
  return isRuleGroupTypeIC(query) ? convertFromIC(query) : convertToIC(query);
768
773
  }
769
-
770
774
  //#endregion
771
775
  //#region src/utils/defaultValidator.ts
772
776
  /**
@@ -803,7 +807,6 @@ const defaultValidator = (query) => {
803
807
  validateGroup(query);
804
808
  return result;
805
809
  };
806
-
807
810
  //#endregion
808
811
  //#region src/utils/objectUtils.ts
809
812
  /**
@@ -818,7 +821,6 @@ const objectKeys = Object.keys;
818
821
  * [Original source](https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-entries.ts)
819
822
  */
820
823
  const objectEntries = Object.entries;
821
-
822
824
  //#endregion
823
825
  //#region src/utils/optGroupUtils.ts
824
826
  const isOptionWithName = (opt) => isPojo(opt) && "name" in opt && typeof opt.name === "string";
@@ -830,24 +832,23 @@ const isOptionWithValue = (opt) => isPojo(opt) && "value" in opt && typeof opt.v
830
832
  * @group Option Lists
831
833
  */
832
834
  function toFullOption(opt, baseProperties, labelMap) {
833
- return (0, immer.produce)((draft) => {
834
- const idObj = {};
835
- let needsUpdating = !!baseProperties;
836
- if (typeof draft === "string") return {
837
- ...baseProperties,
838
- name: draft,
839
- value: draft,
840
- label: labelMap?.[draft] ?? draft
841
- };
842
- if (isOptionWithName(draft) && !isOptionWithValue(draft)) {
843
- idObj.value = draft.name;
844
- needsUpdating = true;
845
- } else if (!isOptionWithName(draft) && isOptionWithValue(draft)) {
846
- idObj.name = draft.value;
847
- needsUpdating = true;
848
- }
849
- if (needsUpdating) return Object.assign({}, baseProperties, draft, idObj);
850
- })(opt);
835
+ if (typeof opt === "string") return {
836
+ ...baseProperties,
837
+ name: opt,
838
+ value: opt,
839
+ label: labelMap?.[opt] ?? opt
840
+ };
841
+ const idObj = {};
842
+ let needsUpdating = !!baseProperties;
843
+ if (isOptionWithName(opt) && !isOptionWithValue(opt)) {
844
+ idObj.value = opt.name;
845
+ needsUpdating = true;
846
+ } else if (!isOptionWithName(opt) && isOptionWithValue(opt)) {
847
+ idObj.name = opt.value;
848
+ needsUpdating = true;
849
+ }
850
+ if (needsUpdating) return Object.assign({}, baseProperties, opt, idObj);
851
+ return opt;
851
852
  }
852
853
  /**
853
854
  * Converts an {@link OptionList} or {@link FlexibleOptionList} into a {@link FullOptionList}.
@@ -857,10 +858,12 @@ function toFullOption(opt, baseProperties, labelMap) {
857
858
  */
858
859
  function toFullOptionList(optList, baseProperties, labelMap) {
859
860
  if (!Array.isArray(optList)) return [];
860
- return (0, immer.produce)((draft) => {
861
- if (isFlexibleOptionGroupArray(draft)) for (const optGroup of draft) for (const [idx, opt] of optGroup.options.entries()) optGroup.options[idx] = toFullOption(opt, baseProperties, labelMap);
862
- else for (const [idx, opt] of draft.entries()) draft[idx] = toFullOption(opt, baseProperties, labelMap);
863
- })(optList);
861
+ const list = optList;
862
+ if (isFlexibleOptionGroupArray(list)) return list.map((optGroup) => ({
863
+ ...optGroup,
864
+ options: optGroup.options.map((opt) => toFullOption(opt, baseProperties, labelMap))
865
+ }));
866
+ return list.map((opt) => toFullOption(opt, baseProperties, labelMap));
864
867
  }
865
868
  /**
866
869
  * Converts a {@link FlexibleOptionList} into a {@link FullOptionList}.
@@ -997,7 +1000,7 @@ const uniqOptList = (originalArray) => {
997
1000
  };
998
1001
  const prepareOptionList = (props) => {
999
1002
  // istanbul ignore next
1000
- const { optionList: optionListPropOriginal, baseOption = {}, labelMap = {}, placeholder: { placeholderName = defaultPlaceholderName, placeholderLabel = defaultPlaceholderLabel, placeholderGroupLabel = defaultPlaceholderLabel } = {}, autoSelectOption = true } = props;
1003
+ const { optionList: optionListPropOriginal, baseOption = {}, labelMap = {}, placeholder: { placeholderName = "~", placeholderLabel = defaultPlaceholderLabel, placeholderGroupLabel = defaultPlaceholderLabel } = {}, autoSelectOption = true } = props;
1001
1004
  const defaultOption = {
1002
1005
  id: placeholderName,
1003
1006
  name: placeholderName,
@@ -1031,7 +1034,6 @@ const prepareOptionList = (props) => {
1031
1034
  optionsMap
1032
1035
  };
1033
1036
  };
1034
-
1035
1037
  //#endregion
1036
1038
  //#region src/utils/filterFieldsByComparator.ts
1037
1039
  const filterByComparator = (field, operator, fieldToCompare) => {
@@ -1067,7 +1069,6 @@ const filterFieldsByComparator = (field, fields, operator) => {
1067
1069
  })).filter((og) => og.options.length > 0);
1068
1070
  return fields.filter((f) => filterByComparator(field, operator, f));
1069
1071
  };
1070
-
1071
1072
  //#endregion
1072
1073
  //#region src/utils/parseNumber.ts
1073
1074
  /**
@@ -1087,23 +1088,20 @@ const parseNumber = (val, { parseNumbers, bigIntOnOverflow } = {}) => {
1087
1088
  });
1088
1089
  return typeof valAsNum === "bigint" || !Number.isNaN(valAsNum) ? valAsNum : val;
1089
1090
  };
1090
-
1091
1091
  //#endregion
1092
1092
  //#region src/utils/transformQuery.ts
1093
- /**
1094
- * Recursively steps through a query object ({@link index!RuleGroupType RuleGroupType} or {@link index!RuleGroupTypeIC RuleGroupTypeIC}),
1095
- * passing each {@link index!RuleType RuleType} object to a provided `ruleProcessor` function and returning a
1096
- * new query object if there were any referential changes.
1097
- *
1098
- * @module transformQuery
1099
- */
1100
- const remapProperties = (obj, propertyMap, deleteRemappedProperties) => (0, immer.produce)(obj, (draft) => {
1101
- for (const [k, v] of Object.entries(propertyMap)) if (v === false) delete draft[k];
1102
- else if (!!v && k !== v && k in draft) {
1103
- draft[v] = draft[k];
1104
- if (deleteRemappedProperties) delete draft[k];
1093
+ const remapProperties = (obj, propertyMap, deleteRemappedProperties) => {
1094
+ const result = {};
1095
+ for (const key in obj) {
1096
+ const mappedKey = propertyMap[key];
1097
+ if (mappedKey === false) continue;
1098
+ if (mappedKey && key !== mappedKey) {
1099
+ result[mappedKey] = obj[key];
1100
+ if (!deleteRemappedProperties) result[key] = obj[key];
1101
+ } else result[key] = obj[key];
1105
1102
  }
1106
- });
1103
+ return result;
1104
+ };
1107
1105
  function transformQuery(query, options = {}) {
1108
1106
  const { ruleProcessor = (r) => r, ruleGroupProcessor = (rg) => rg, propertyMap = {}, combinatorMap = {}, operatorMap = {}, omitPath = false, deleteRemappedProperties = true } = options;
1109
1107
  const processGroup = (rg) => ({
@@ -1130,7 +1128,6 @@ function transformQuery(query, options = {}) {
1130
1128
  ...omitPath ? null : { path: [] }
1131
1129
  });
1132
1130
  }
1133
-
1134
1131
  //#endregion
1135
1132
  //#region src/utils/isRuleOrGroupValid.ts
1136
1133
  /**
@@ -1154,7 +1151,6 @@ const isRuleOrGroupValid = (rg, validationResult, validator) => {
1154
1151
  }
1155
1152
  return true;
1156
1153
  };
1157
-
1158
1154
  //#endregion
1159
1155
  //#region src/utils/getParseNumberMethod.ts
1160
1156
  const getParseNumberMethod = ({ parseNumbers, inputType }) => {
@@ -1165,7 +1161,6 @@ const getParseNumberMethod = ({ parseNumbers, inputType }) => {
1165
1161
  }
1166
1162
  return parseNumbers ? "strict" : false;
1167
1163
  };
1168
-
1169
1164
  //#endregion
1170
1165
  //#region src/utils/formatQuery/utils.ts
1171
1166
  /**
@@ -1247,7 +1242,8 @@ const jsonLogicAdditionalOperators = {
1247
1242
  endsWith: (a, b) => typeof a === "string" && a.endsWith(b)
1248
1243
  };
1249
1244
  /**
1250
- * Converts all `string`-type `value` properties of a query object into `number` where appropriate.
1245
+ * Returns a new query object with all `string`-type `value` properties converted
1246
+ * to `number` where appropriate.
1251
1247
  *
1252
1248
  * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`.
1253
1249
  *
@@ -1416,7 +1412,6 @@ const bigIntJsonStringifyReplacer = (_key, value) => typeof value === "bigint" ?
1416
1412
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
1417
1413
  */
1418
1414
  const bigIntJsonParseReviver = (_key, value) => isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === "string" ? BigInt(value.$bigint) : value;
1419
-
1420
1415
  //#endregion
1421
1416
  //#region src/utils/formatQuery/defaultRuleGroupProcessorCEL.ts
1422
1417
  /**
@@ -1472,7 +1467,6 @@ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
1472
1467
  };
1473
1468
  return processRuleGroup(ruleGroup, true);
1474
1469
  };
1475
-
1476
1470
  //#endregion
1477
1471
  //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts
1478
1472
  const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot");
@@ -1553,7 +1547,6 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
1553
1547
  }
1554
1548
  return "";
1555
1549
  };
1556
-
1557
1550
  //#endregion
1558
1551
  //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDBQuery.ts
1559
1552
  /**
@@ -1591,11 +1584,11 @@ const defaultRuleGroupProcessorMongoDBQuery = (ruleGroup, options, meta) => {
1591
1584
  fieldData
1592
1585
  }, meta);
1593
1586
  }).filter(Boolean);
1594
- return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
1587
+ const result = expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
1588
+ return rg.not ? { $not: result } : result;
1595
1589
  };
1596
1590
  return processRuleGroup(convertFromIC(ruleGroup), true);
1597
1591
  };
1598
-
1599
1592
  //#endregion
1600
1593
  //#region src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts
1601
1594
  const processNumber$1 = (value, fallback, parseNumbers = false) => shouldRenderAsNumber(value, parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: "strict" })) : fallback;
@@ -1724,7 +1717,6 @@ const defaultRuleProcessorMongoDBQuery = (rule, options = {}) => {
1724
1717
  }
1725
1718
  return "";
1726
1719
  };
1727
-
1728
1720
  //#endregion
1729
1721
  //#region src/utils/formatQuery/defaultRuleProcessorMongoDB.ts
1730
1722
  /**
@@ -1738,7 +1730,6 @@ const defaultRuleProcessorMongoDB = (rule, options) => {
1738
1730
  const queryObj = defaultRuleProcessorMongoDBQuery(rule, options);
1739
1731
  return queryObj ? JSON.stringify(queryObj) : "";
1740
1732
  };
1741
-
1742
1733
  //#endregion
1743
1734
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSpEL.ts
1744
1735
  /**
@@ -1794,11 +1785,10 @@ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
1794
1785
  };
1795
1786
  return processRuleGroup(ruleGroup, true);
1796
1787
  };
1797
-
1798
1788
  //#endregion
1799
1789
  //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts
1800
1790
  const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot");
1801
- const wrapInNegation = (clause, negate$1) => negate$1 ? `!(${clause})` : clause;
1791
+ const wrapInNegation = (clause, negate) => negate ? `!(${clause})` : clause;
1802
1792
  const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
1803
1793
  /**
1804
1794
  * Default rule processor used by {@link formatQuery} for "spel" format.
@@ -1851,9 +1841,9 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1851
1841
  case "notnull": return `${field} != null`;
1852
1842
  case "in":
1853
1843
  case "notin": {
1854
- const negate$1 = shouldNegate$1(operatorTL) ? "!" : "";
1844
+ const negate = shouldNegate$1(operatorTL) ? "!" : "";
1855
1845
  const valueAsArray = toArray(value);
1856
- return valueAsArray.length > 0 ? `${negate$1}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
1846
+ return valueAsArray.length > 0 ? `${negate}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
1857
1847
  }
1858
1848
  case "between":
1859
1849
  case "notbetween": {
@@ -1876,7 +1866,6 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1876
1866
  }
1877
1867
  return "";
1878
1868
  };
1879
-
1880
1869
  //#endregion
1881
1870
  //#region src/utils/formatQuery/defaultValueProcessorByRule.ts
1882
1871
  const escapeStringValueQuotes$1 = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
@@ -1932,7 +1921,6 @@ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQ
1932
1921
  if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
1933
1922
  return valueIsField ? wrapFieldName(value) : shouldRenderAsNumber(value, parseNumbers) ? `${trimIfString(value)}` : `${wrapAndEscape(value)}`;
1934
1923
  };
1935
-
1936
1924
  //#endregion
1937
1925
  //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
1938
1926
  /**
@@ -2029,7 +2017,6 @@ const defaultRuleProcessorDrizzle = (rule, _options) => {
2029
2017
  default: return;
2030
2018
  }
2031
2019
  };
2032
-
2033
2020
  //#endregion
2034
2021
  //#region src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts
2035
2022
  /**
@@ -2073,7 +2060,6 @@ const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns
2073
2060
  };
2074
2061
  return processRuleGroup(convertFromIC(ruleGroup), true);
2075
2062
  };
2076
-
2077
2063
  //#endregion
2078
2064
  //#region src/utils/formatQuery/defaultRuleGroupProcessorElasticSearch.ts
2079
2065
  /**
@@ -2102,7 +2088,6 @@ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
2102
2088
  const processedRuleGroup = processRuleGroup(convertFromIC(ruleGroup));
2103
2089
  return processedRuleGroup === false ? {} : processedRuleGroup;
2104
2090
  };
2105
-
2106
2091
  //#endregion
2107
2092
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts
2108
2093
  /**
@@ -2158,7 +2143,6 @@ const defaultRuleGroupProcessorJSONata = (ruleGroup, options) => {
2158
2143
  };
2159
2144
  return processRuleGroup(ruleGroup, true);
2160
2145
  };
2161
-
2162
2146
  //#endregion
2163
2147
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJsonLogic.ts
2164
2148
  /**
@@ -2188,7 +2172,6 @@ const defaultRuleGroupProcessorJsonLogic = (ruleGroup, options) => {
2188
2172
  };
2189
2173
  return processRuleGroup(query, true);
2190
2174
  };
2191
-
2192
2175
  //#endregion
2193
2176
  //#region src/utils/formatQuery/defaultRuleGroupProcessorLDAP.ts
2194
2177
  /**
@@ -2219,7 +2202,6 @@ const defaultRuleGroupProcessorLDAP = (ruleGroup, options) => {
2219
2202
  };
2220
2203
  return processRuleGroup(convertFromIC(ruleGroup), true);
2221
2204
  };
2222
-
2223
2205
  //#endregion
2224
2206
  //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDB.ts
2225
2207
  const isBracketed = (str) => str.startsWith("{") && str.endsWith("}");
@@ -2254,12 +2236,12 @@ const defaultRuleGroupProcessorMongoDB = (ruleGroup, options, meta) => {
2254
2236
  fieldData
2255
2237
  }, meta);
2256
2238
  }).filter(Boolean);
2257
- return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
2239
+ const result = expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
2240
+ return rg.not ? `"$not":${isBracketed(result) ? result : `{${result}}`}` : result;
2258
2241
  };
2259
2242
  const processedQuery = processRuleGroup(convertFromIC(ruleGroup), true);
2260
2243
  return isBracketed(processedQuery) ? processedQuery : `{${processedQuery}}`;
2261
2244
  };
2262
-
2263
2245
  //#endregion
2264
2246
  //#region src/utils/formatQuery/defaultRuleGroupProcessorNL.ts
2265
2247
  /**
@@ -2323,7 +2305,6 @@ const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
2323
2305
  };
2324
2306
  return processRuleGroup(ruleGroup, true);
2325
2307
  };
2326
-
2327
2308
  //#endregion
2328
2309
  //#region src/utils/formatQuery/defaultRuleGroupProcessorParameterized.ts
2329
2310
  /**
@@ -2412,7 +2393,6 @@ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
2412
2393
  params: paramsNamed
2413
2394
  };
2414
2395
  };
2415
-
2416
2396
  //#endregion
2417
2397
  //#region src/utils/formatQuery/defaultRuleGroupProcessorPrisma.ts
2418
2398
  /**
@@ -2455,7 +2435,6 @@ const defaultRuleGroupProcessorPrisma = (ruleGroup, options) => {
2455
2435
  const result = processRuleGroup(convertFromIC(ruleGroup), true);
2456
2436
  return ruleGroup.not ? { NOT: result } : result;
2457
2437
  };
2458
-
2459
2438
  //#endregion
2460
2439
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSequelize.ts
2461
2440
  /**
@@ -2496,7 +2475,6 @@ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
2496
2475
  };
2497
2476
  return processRuleGroup(convertFromIC(ruleGroup), true);
2498
2477
  };
2499
-
2500
2478
  //#endregion
2501
2479
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts
2502
2480
  /**
@@ -2553,7 +2531,6 @@ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
2553
2531
  };
2554
2532
  return processRuleGroup(ruleGroup, true);
2555
2533
  };
2556
-
2557
2534
  //#endregion
2558
2535
  //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
2559
2536
  const rangeOperatorMap = {
@@ -2585,7 +2562,30 @@ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
2585
2562
  const { field, operator, value, valueSource } = rule;
2586
2563
  const { parseNumbers, preserveValueOrder } = options;
2587
2564
  const operatorLC = lc(operator);
2588
- if (processMatchMode(rule)) return false;
2565
+ const matchEval = processMatchMode(rule);
2566
+ if (matchEval === false) return false;
2567
+ else if (matchEval) {
2568
+ const { mode } = matchEval;
2569
+ const subQuery = defaultRuleGroupProcessorElasticSearch(transformQuery(rule.value, { ruleProcessor: (r) => ({
2570
+ ...r,
2571
+ field: r.field ? `${field}.${r.field}` : field
2572
+ }) }), options);
2573
+ if (Object.keys(subQuery).length === 0) return false;
2574
+ switch (mode) {
2575
+ case "some": return { nested: {
2576
+ path: field,
2577
+ query: subQuery
2578
+ } };
2579
+ case "none": return { bool: { must_not: { nested: {
2580
+ path: field,
2581
+ query: subQuery
2582
+ } } } };
2583
+ case "all":
2584
+ case "atleast":
2585
+ case "atmost":
2586
+ case "exactly": return false;
2587
+ }
2588
+ }
2589
2589
  if (valueSource === "field") {
2590
2590
  if (toArray(value).some((v) => typeof v !== "string")) return false;
2591
2591
  const fieldForScript = escapeSQ(field);
@@ -2682,12 +2682,11 @@ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
2682
2682
  }
2683
2683
  return false;
2684
2684
  };
2685
-
2686
2685
  //#endregion
2687
2686
  //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
2688
2687
  const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
2689
2688
  const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
2690
- const negate = (clause, negate$1) => negate$1 ? `$not(${clause})` : clause;
2689
+ const negate = (clause, neg) => neg ? `$not(${clause})` : clause;
2691
2690
  const escapeStringRegex = (s) => `${s}`.replaceAll(/[/$()*+.?[\\\]^{|}]/g, String.raw`\$&`).replaceAll("-", String.raw`\x2d`);
2692
2691
  /**
2693
2692
  * Default rule processor used by {@link formatQuery} for "jsonata" format.
@@ -2769,7 +2768,6 @@ const defaultRuleProcessorJSONata = (rule, options = {}) => {
2769
2768
  }
2770
2769
  return "";
2771
2770
  };
2772
-
2773
2771
  //#endregion
2774
2772
  //#region src/utils/formatQuery/defaultRuleProcessorJsonLogic.ts
2775
2773
  const convertOperator = (op) => op.replace(/^(=)$/, "$1=").replace(/^notnull$/i, "!=").replace(/^null$/i, "==");
@@ -2864,10 +2862,9 @@ const defaultRuleProcessorJsonLogic = (rule, options = {}) => {
2864
2862
  }
2865
2863
  return false;
2866
2864
  };
2867
-
2868
2865
  //#endregion
2869
2866
  //#region src/utils/formatQuery/defaultRuleProcessorLDAP.ts
2870
- const negateIf = (clause, negate$1) => negate$1 ? `(!${clause})` : `${clause}`;
2867
+ const negateIf = (clause, negate) => negate ? `(!${clause})` : `${clause}`;
2871
2868
  const ldapEscape = (s) => `${trimIfString(s)}`.replaceAll(/[()&|=<>~*\\/]/g, (m) => `\\${m.codePointAt(0).toString(16)}`);
2872
2869
  /**
2873
2870
  * Default rule processor used by {@link formatQuery} for "ldap" format.
@@ -2916,7 +2913,6 @@ const defaultRuleProcessorLDAP = (rule, options = {}) => {
2916
2913
  // istanbul ignore next
2917
2914
  return "";
2918
2915
  };
2919
-
2920
2916
  //#endregion
2921
2917
  //#region src/utils/formatQuery/defaultValueProcessorNL.ts
2922
2918
  const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
@@ -2966,7 +2962,6 @@ const defaultValueProcessorNL = (rule, opts = {}) => {
2966
2962
  if (typeof rule.value === "boolean") return rule.value ? trueTL : falseTL;
2967
2963
  return valueIsField ? wrapFieldName(getOption(fields ?? [], rule.value)?.label ?? rule.value) : shouldRenderAsNumber(rule.value, parseNumbers) ? `${trimIfString(rule.value)}` : `${wrapAndEscape(rule.value)}`;
2968
2964
  };
2969
-
2970
2965
  //#endregion
2971
2966
  //#region src/utils/formatQuery/defaultRuleProcessorNL.ts
2972
2967
  /**
@@ -3076,7 +3071,6 @@ const defaultRuleProcessorNL = (rule, opts) => {
3076
3071
  };
3077
3072
  return normalizeConstituentWordOrder(wordOrder).map((term) => `${wordOrderMap[term]}`).join(" ").trim();
3078
3073
  };
3079
-
3080
3074
  //#endregion
3081
3075
  //#region src/utils/formatQuery/defaultRuleProcessorSQL.ts
3082
3076
  /**
@@ -3131,7 +3125,6 @@ const defaultRuleProcessorSQL = (rule, opts = {}) => {
3131
3125
  if ((operatorLowerCase === "in" || operatorLowerCase === "not in" || operatorLowerCase === "between" || operatorLowerCase === "not between") && !value) return "";
3132
3126
  return `${ruleField} ${operator} ${value}`.trim();
3133
3127
  };
3134
-
3135
3128
  //#endregion
3136
3129
  //#region src/utils/formatQuery/defaultRuleProcessorParameterized.ts
3137
3130
  /**
@@ -3236,7 +3229,6 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
3236
3229
  }
3237
3230
  return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${parameterized ? numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?" : `${paramPrefix}${paramName}`}`.trim());
3238
3231
  };
3239
-
3240
3232
  //#endregion
3241
3233
  //#region src/utils/formatQuery/defaultRuleProcessorPrisma.ts
3242
3234
  const processNumber = (value, fallback, parseNumbers) => shouldRenderAsNumber(value, !!parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: !!parseNumbers })) : fallback;
@@ -3298,7 +3290,6 @@ const defaultRuleProcessorPrisma = (rule, options = {}) => {
3298
3290
  }
3299
3291
  return "";
3300
3292
  };
3301
-
3302
3293
  //#endregion
3303
3294
  //#region src/utils/formatQuery/defaultRuleProcessorSequelize.ts
3304
3295
  /**
@@ -3365,7 +3356,6 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
3365
3356
  }
3366
3357
  }
3367
3358
  };
3368
-
3369
3359
  //#endregion
3370
3360
  //#region src/utils/formatQuery/formatQuery.ts
3371
3361
  /**
@@ -3454,8 +3444,8 @@ const defaultFormatQueryOptions = {
3454
3444
  paramsKeepPrefix: false,
3455
3445
  numberedParams: false,
3456
3446
  preserveValueOrder: false,
3457
- placeholderFieldName: defaultPlaceholderFieldName,
3458
- placeholderOperatorName: defaultPlaceholderOperatorName,
3447
+ placeholderFieldName: "~",
3448
+ placeholderOperatorName: "~",
3459
3449
  quoteValuesWith: "'",
3460
3450
  concatOperator: "||",
3461
3451
  preset: "ansi",
@@ -3560,7 +3550,7 @@ function formatQuery(ruleGroup, optionParam = {}) {
3560
3550
  switch (format) {
3561
3551
  case "json":
3562
3552
  case "json_without_ids": {
3563
- const rg = parseNumbers ? (0, immer.produce)(ruleGroup, (g) => numerifyValues(g, finalOptions)) : ruleGroup;
3553
+ const rg = parseNumbers ? numerifyValues(ruleGroup, finalOptions) : ruleGroup;
3564
3554
  if (format === "json_without_ids") return JSON.stringify(rg, (key, value) => key === "id" || key === "path" ? void 0 : bigIntJsonStringifyReplacer(key, value));
3565
3555
  return JSON.stringify(rg, bigIntJsonStringifyReplacer, 2);
3566
3556
  }
@@ -3582,7 +3572,6 @@ function formatQuery(ruleGroup, optionParam = {}) {
3582
3572
  default: return "";
3583
3573
  }
3584
3574
  }
3585
-
3586
3575
  //#endregion
3587
3576
  //#region src/utils/formatQuery/index.ts
3588
3577
  const generateValueProcessor = (vpbr) => (field, operator, value, valueSource) => vpbr({
@@ -3633,7 +3622,6 @@ const defaultValueProcessorMongoDBByRule = defaultRuleProcessorMongoDB;
3633
3622
  * @group Export
3634
3623
  */
3635
3624
  const defaultValueProcessorSpELByRule = defaultRuleProcessorSpEL;
3636
-
3637
3625
  //#endregion
3638
3626
  //#region src/utils/pathUtils.ts
3639
3627
  /**
@@ -3692,7 +3680,7 @@ const pathsAreEqual = (path1, path2) => path1.length === path2.length && path1.e
3692
3680
  * Determines if the first path is an ancestor of the second path. The first path must
3693
3681
  * be shorter and exactly match the second path up through the length of the first path.
3694
3682
  */
3695
- const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && (/* @__PURE__ */ new RegExp(`^${maybeAncestor.join("-")}`)).test(path.join("-"));
3683
+ const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && new RegExp(`^${maybeAncestor.join("-")}`).test(path.join("-"));
3696
3684
  /**
3697
3685
  * Finds the deepest/longest path that two paths have in common.
3698
3686
  */
@@ -3725,11 +3713,9 @@ const pathIsDisabled = (path, query) => {
3725
3713
  }
3726
3714
  return disabled;
3727
3715
  };
3728
-
3729
3716
  //#endregion
3730
3717
  //#region src/utils/generateAccessibleDescription.ts
3731
3718
  const generateAccessibleDescription = (params) => pathsAreEqual([], params.path) ? `Query builder` : `Rule group at path ${params.path.join("-")}`;
3732
-
3733
3719
  //#endregion
3734
3720
  //#region src/utils/generateID.ts
3735
3721
  const cryptoModule = globalThis.crypto;
@@ -3764,7 +3750,6 @@ if (cryptoModule) {
3764
3750
  };
3765
3751
  }
3766
3752
  }
3767
-
3768
3753
  //#endregion
3769
3754
  //#region src/utils/getMatchModesUtil.ts
3770
3755
  const dummyFD$1 = {
@@ -3792,7 +3777,6 @@ const getMatchModesUtil = (fieldData, getMatchModes) => {
3792
3777
  label: mm
3793
3778
  }) ?? [];
3794
3779
  };
3795
-
3796
3780
  //#endregion
3797
3781
  //#region src/utils/getValidationClassNames.ts
3798
3782
  /**
@@ -3803,7 +3787,6 @@ const getValidationClassNames = (validationResult) => {
3803
3787
  const valid = typeof validationResult === "boolean" ? validationResult : typeof validationResult === "object" && validationResult !== null ? validationResult.valid : null;
3804
3788
  return typeof valid === "boolean" ? valid ? standardClassnames.valid : standardClassnames.invalid : "";
3805
3789
  };
3806
-
3807
3790
  //#endregion
3808
3791
  //#region src/utils/getValueSourcesUtil.ts
3809
3792
  const defaultValueSourcesArray = [{
@@ -3836,18 +3819,22 @@ const getValueSourcesUtil = (fieldData, operator, getValueSources) => {
3836
3819
  label: vs
3837
3820
  });
3838
3821
  };
3839
-
3840
3822
  //#endregion
3841
3823
  //#region src/utils/mergeAnyTranslations.ts
3842
3824
  /**
3843
3825
  * Merges any number of partial translations into a single definition.
3844
3826
  */
3845
- const mergeAnyTranslations = (base, ...otherTranslations) => (0, immer.produce)(base, (draft) => {
3827
+ const mergeAnyTranslations = (base, ...otherTranslations) => {
3828
+ const result = { ...base };
3846
3829
  for (const translations of otherTranslations)
3847
3830
  // istanbul ignore else
3848
- if (translations) for (const t of objectKeys(translations)) if (draft[t]) Object.assign(draft[t], translations[t]);
3849
- else Object.assign(draft, { [t]: translations[t] });
3850
- });
3831
+ if (translations) for (const key of objectKeys(translations)) if (result[key]) result[key] = {
3832
+ ...result[key],
3833
+ ...translations[key]
3834
+ };
3835
+ else result[key] = { ...translations[key] };
3836
+ return result;
3837
+ };
3851
3838
  const mergeAnyTranslation = (el, keyPropContextMap, defaults) => {
3852
3839
  const finalKeys = objectEntries(keyPropContextMap).map(([key, [pT, cT]]) => [key, pT ?? cT ?? defaults?.[el]?.[key]]).filter((k) => !!k[1]);
3853
3840
  if (finalKeys.length > 0 || defaults) {
@@ -3856,7 +3843,6 @@ const mergeAnyTranslation = (el, keyPropContextMap, defaults) => {
3856
3843
  return { [el]: finalObject };
3857
3844
  }
3858
3845
  };
3859
-
3860
3846
  //#endregion
3861
3847
  //#region src/utils/mergeClassnames.ts
3862
3848
  const joinClassnamesByName = (name, args) => clsx(args.map((c) => clsx(c?.[name])));
@@ -3906,7 +3892,6 @@ const mergeClassnames = (...args) => ({
3906
3892
  hasSubQuery: joinClassnamesByName("hasSubQuery", args),
3907
3893
  loading: joinClassnamesByName("loading", args)
3908
3894
  });
3909
-
3910
3895
  //#endregion
3911
3896
  //#region src/utils/preferProp.ts
3912
3897
  const preferPropDefaultTrue = (prop, context) => prop === false ? false : prop ? true : !(context === false);
@@ -3929,29 +3914,49 @@ const preferFlagProps = (props = {}, contextVals = {}, finalize) => objectEntrie
3929
3914
  acc[key] = preferProp(def, props[key], contextVals[key], !finalize);
3930
3915
  return acc;
3931
3916
  }, {});
3932
-
3933
3917
  //#endregion
3934
3918
  //#region src/utils/prepareQueryObjects.ts
3935
3919
  /**
3936
3920
  * Ensures that a rule is valid by adding an `id` property if it does not already exist.
3937
3921
  */
3938
- const prepareRule = (rule, { idGenerator = generateID } = {}) => (0, immer.produce)(rule, (draft) => {
3939
- if (!draft.id) draft.id = idGenerator();
3940
- if (processMatchMode(draft)) draft.value = prepareRuleGroup(draft.value, { idGenerator });
3941
- });
3922
+ const prepareRule = (rule, { idGenerator = generateID } = {}) => {
3923
+ const needsId = !rule.id;
3924
+ const hasMatchMode = processMatchMode(rule);
3925
+ if (!needsId && !hasMatchMode) return rule;
3926
+ return {
3927
+ ...rule,
3928
+ ...needsId && { id: idGenerator() },
3929
+ ...hasMatchMode && { value: prepareRuleGroup(rule.value, { idGenerator }) }
3930
+ };
3931
+ };
3942
3932
  /**
3943
3933
  * Ensures that a rule group is valid by recursively adding an `id` property to the group itself
3944
3934
  * and all its rules and subgroups where one does not already exist.
3945
3935
  */
3946
- const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => (0, immer.produce)(queryObject, (draft) => {
3947
- if (!draft.id) draft.id = idGenerator();
3948
- draft.rules = draft.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? prepareRuleGroup(r, { idGenerator }) : prepareRule(r, { idGenerator }));
3949
- });
3936
+ const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => {
3937
+ const needsId = !queryObject.id;
3938
+ let rulesChanged = false;
3939
+ const newRules = [];
3940
+ for (let i = 0; i < queryObject.rules.length; i++) {
3941
+ const r = queryObject.rules[i];
3942
+ if (typeof r === "string") newRules.push(r);
3943
+ else {
3944
+ const prepared = isRuleGroup(r) ? prepareRuleGroup(r, { idGenerator }) : prepareRule(r, { idGenerator });
3945
+ newRules.push(prepared);
3946
+ if (prepared !== r) rulesChanged = true;
3947
+ }
3948
+ }
3949
+ if (!needsId && !rulesChanged) return queryObject;
3950
+ return {
3951
+ ...queryObject,
3952
+ ...needsId && { id: idGenerator() },
3953
+ rules: newRules
3954
+ };
3955
+ };
3950
3956
  /**
3951
3957
  * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.
3952
3958
  */
3953
3959
  const prepareRuleOrGroup = (rg, { idGenerator = generateID } = {}) => isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });
3954
-
3955
3960
  //#endregion
3956
3961
  //#region src/utils/regenerateIDs.ts
3957
3962
  /**
@@ -3978,44 +3983,65 @@ const regenerateIDs = (subject, { idGenerator = generateID } = {}) => {
3978
3983
  if (Array.isArray(newGroup.rules)) newGroup.rules = subject.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? regenerateIDs(r, { idGenerator }) : regenerateID(r, { idGenerator }));
3979
3984
  return newGroup;
3980
3985
  };
3981
-
3982
3986
  //#endregion
3983
3987
  //#region src/utils/queryTools.ts
3984
3988
  /**
3985
- * Adds a rule or group to a query.
3986
- * @returns The new query with the rule or group added.
3989
+ * Adds a rule or group to a query without mutating the original query.
3990
+ *
3991
+ * @returns A new query with the rule or group added.
3987
3992
  *
3988
3993
  * @group Query Tools
3989
3994
  */
3990
- const add = (query, ruleOrGroup, parentPathOrID, { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = {}) => (0, immer.produce)(query, (draft) => {
3991
- const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, draft) : findID(parentPathOrID, draft);
3992
- if (!parent || !isRuleGroup(parent)) return;
3995
+ const add = (query, ruleOrGroup, parentPathOrID, options = {}) => (0, immer.produce)(query, (q) => addInPlace(q, ruleOrGroup, parentPathOrID, options));
3996
+ /**
3997
+ * Adds a rule or group to a query in place.
3998
+ *
3999
+ * @returns The query (mutated in place) with the rule or group added.
4000
+ *
4001
+ * @group Query Tools
4002
+ */
4003
+ const addInPlace = (query, ruleOrGroup, parentPathOrID, options = {}) => {
4004
+ const { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = options;
4005
+ const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, query) : findID(parentPathOrID, query);
4006
+ if (!parent || !isRuleGroup(parent)) return query;
3993
4007
  if (isRuleGroupTypeIC(parent) && parent.rules.length > 0) {
3994
4008
  const prevCombinator = parent.rules.at(-2);
3995
4009
  parent.rules.push(combinatorPreceding ?? (typeof prevCombinator === "string" ? prevCombinator : getFirstOption(combinators)));
3996
4010
  }
3997
4011
  parent.rules.push(prepareRuleOrGroup(ruleOrGroup, { idGenerator }));
3998
- });
4012
+ return query;
4013
+ };
3999
4014
  /**
4000
- * Updates a property of a rule or group within a query.
4001
- * @returns The new query with the rule or group property updated.
4015
+ * Updates a property of a rule or group within a query without mutating the original query.
4016
+ *
4017
+ * @returns A new query with the rule or group property updated.
4018
+ *
4019
+ * @group Query Tools
4020
+ */
4021
+ const update = (query, prop, value, pathOrID, options = {}) => (0, immer.produce)(query, (q) => updateInPlace(q, prop, value, pathOrID, options));
4022
+ /**
4023
+ * Updates a property of a rule or group within a query in place.
4024
+ *
4025
+ * @returns The query (mutated in place) with the rule or group property updated.
4002
4026
  *
4003
4027
  * @group Query Tools
4004
4028
  */
4005
- const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = {}) => (0, immer.produce)(query, (draft) => {
4006
- const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, draft);
4007
- if (!path) return;
4008
- if (prop === "combinator" && !isRuleGroupType(draft)) {
4009
- const parentRules = findPath(getParentPath(path), draft).rules;
4029
+ const updateInPlace = (query, prop, value, pathOrID, options = {}) => {
4030
+ const { resetOnFieldChange: _resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = options;
4031
+ let resetOnFieldChange = _resetOnFieldChange;
4032
+ const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
4033
+ if (!path) return query;
4034
+ if (prop === "combinator" && !isRuleGroupType(query)) {
4035
+ const parentRules = findPath(getParentPath(path), query).rules;
4010
4036
  if (path.at(-1) % 2 === 1) parentRules[path.at(-1)] = value;
4011
- return;
4037
+ return query;
4012
4038
  }
4013
- const ruleOrGroup = findPath(path, draft);
4014
- if (!ruleOrGroup) return;
4039
+ const ruleOrGroup = findPath(path, query);
4040
+ if (!ruleOrGroup) return query;
4015
4041
  const isGroup = isRuleGroup(ruleOrGroup);
4016
- if (ruleOrGroup[prop] === value) return;
4042
+ if (ruleOrGroup[prop] === value) return query;
4017
4043
  if (prop !== "valueSource") ruleOrGroup[prop] = value;
4018
- if (isGroup) return;
4044
+ if (isGroup) return query;
4019
4045
  let resetValueSource = false;
4020
4046
  let resetValue = false;
4021
4047
  if (prop === "field") {
@@ -4050,25 +4076,33 @@ const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, reset
4050
4076
  ruleOrGroup.valueSource = resetValueSource ? defaultValueSource : value;
4051
4077
  }
4052
4078
  if (resetValue) ruleOrGroup.value = getRuleDefaultValue(ruleOrGroup);
4053
- });
4079
+ return query;
4080
+ };
4054
4081
  /**
4055
- * Removes a rule or group from a query.
4056
- * @returns The new query with the rule or group removed.
4082
+ * Removes a rule or group from a query without mutating the original query.
4083
+ *
4084
+ * @returns A new query with the rule or group removed.
4085
+ *
4086
+ * @group Query Tools
4087
+ */
4088
+ const remove = (query, pathOrID) => (0, immer.produce)(query, (q) => removeInPlace(q, pathOrID));
4089
+ /**
4090
+ * Removes a rule or group from a query in place.
4091
+ *
4092
+ * @returns The query (mutated in place) with the rule or group removed.
4057
4093
  *
4058
4094
  * @group Query Tools
4059
4095
  */
4060
- const remove = (query, pathOrID) => {
4096
+ const removeInPlace = (query, pathOrID) => {
4061
4097
  const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
4062
- if (!path) return query;
4063
- if (path.length === 0 || !isRuleGroupType(query) && !findPath(path, query)) return query;
4064
- return (0, immer.produce)(query, (draft) => {
4065
- const index = path.at(-1);
4066
- const parent = findPath(getParentPath(path), draft);
4067
- if (parent && isRuleGroup(parent)) if (!isRuleGroupType(parent) && parent.rules.length > 1) {
4068
- const idxStartDelete = index === 0 ? 0 : index - 1;
4069
- parent.rules.splice(idxStartDelete, 2);
4070
- } else parent.rules.splice(index, 1);
4071
- });
4098
+ if (!path || path.length === 0 || !isRuleGroupType(query) && !findPath(path, query)) return query;
4099
+ const index = path.at(-1);
4100
+ const parent = findPath(getParentPath(path), query);
4101
+ if (parent && isRuleGroup(parent)) if (!isRuleGroupType(parent) && parent.rules.length > 1) {
4102
+ const idxStartDelete = index === 0 ? 0 : index - 1;
4103
+ parent.rules.splice(idxStartDelete, 2);
4104
+ } else parent.rules.splice(index, 1);
4105
+ return query;
4072
4106
  };
4073
4107
  const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4074
4108
  if (Array.isArray(newPathOrShiftDirection)) return newPathOrShiftDirection;
@@ -4095,59 +4129,79 @@ const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4095
4129
  return currentPath;
4096
4130
  };
4097
4131
  /**
4098
- * Moves a rule or group from one path to another. In the options parameter, pass
4099
- * `{ clone: true }` to copy instead of move.
4100
- * @returns The new query with the rule or group moved or cloned.
4132
+ * Moves a rule or group from one path to another without mutating the original query.
4133
+ * In the options parameter, pass `{ clone: true }` to copy instead of move.
4134
+ *
4135
+ * @returns A new query with the rule or group moved or cloned.
4101
4136
  *
4102
4137
  * @group Query Tools
4103
4138
  */
4104
- const move = (query, oldPathOrID, newPath, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
4139
+ const move = (query, oldPathOrID, newPath, options = {}) => (0, immer.produce)(query, (q) => moveInPlace(q, oldPathOrID, newPath, options));
4140
+ /**
4141
+ * Moves a rule or group from one path to another in place.
4142
+ * In the options parameter, pass `{ clone: true }` to copy instead of move.
4143
+ *
4144
+ * @returns The query (mutated in place) with the rule or group moved or cloned.
4145
+ *
4146
+ * @group Query Tools
4147
+ */
4148
+ const moveInPlace = (query, oldPathOrID, newPath, options = {}) => {
4149
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
4105
4150
  const oldPath = Array.isArray(oldPathOrID) ? oldPathOrID : getPathOfID(oldPathOrID, query);
4106
4151
  if (!oldPath) return query;
4107
4152
  const nextPath = getNextPath(query, oldPath, newPath);
4108
4153
  if (oldPath.length === 0 || pathsAreEqual(oldPath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
4109
4154
  const ruleOrGroupOriginal = findPath(oldPath, query);
4110
4155
  if (!ruleOrGroupOriginal) return query;
4111
- const ruleOrGroup = clone ? regenerateIDs(ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
4112
- return (0, immer.produce)(query, (draft) => {
4113
- const independentCombinators = isRuleGroupTypeIC(draft);
4114
- const parentOfRuleToRemove = findPath(getParentPath(oldPath), draft);
4115
- const ruleToRemoveIndex = oldPath.at(-1);
4116
- const oldPrevCombinator = independentCombinators && ruleToRemoveIndex > 0 ? parentOfRuleToRemove.rules[ruleToRemoveIndex - 1] : null;
4117
- const oldNextCombinator = independentCombinators && ruleToRemoveIndex < parentOfRuleToRemove.rules.length - 1 ? parentOfRuleToRemove.rules[ruleToRemoveIndex + 1] : null;
4118
- if (!clone) {
4119
- const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4120
- const deleteLength = independentCombinators ? 2 : 1;
4121
- parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4122
- }
4123
- const newNewPath = [...nextPath];
4124
- const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);
4125
- if (!clone && oldPath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4126
- const parentToInsertInto = findPath(getParentPath(newNewPath), draft);
4127
- const newIndex = newNewPath.at(-1);
4128
- /**
4129
- * This function 1) glosses over the need for type assertions to splice directly
4130
- * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
4131
- */
4132
- const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(newIndex, 0, ...args);
4133
- if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(ruleOrGroup);
4134
- else if (newIndex === 0) if (ruleToRemoveIndex === 0 && oldNextCombinator) insertRuleOrGroup(ruleOrGroup, oldNextCombinator);
4135
- else insertRuleOrGroup(ruleOrGroup, parentToInsertInto.rules[1] ?? oldPrevCombinator ?? getFirstOption(combinators));
4136
- else if (oldPrevCombinator) insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);
4137
- else insertRuleOrGroup(parentToInsertInto.rules[newIndex - 2] ?? oldNextCombinator ?? getFirstOption(combinators), ruleOrGroup);
4138
- });
4156
+ const ruleOrGroup = clone ? regenerateIDs((0, immer.isDraft)(ruleOrGroupOriginal) ? (0, immer.current)(ruleOrGroupOriginal) : ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
4157
+ const independentCombinators = isRuleGroupTypeIC(query);
4158
+ const parentOfRuleToRemove = findPath(getParentPath(oldPath), query);
4159
+ const ruleToRemoveIndex = oldPath.at(-1);
4160
+ const oldPrevCombinator = independentCombinators && ruleToRemoveIndex > 0 ? parentOfRuleToRemove.rules[ruleToRemoveIndex - 1] : null;
4161
+ const oldNextCombinator = independentCombinators && ruleToRemoveIndex < parentOfRuleToRemove.rules.length - 1 ? parentOfRuleToRemove.rules[ruleToRemoveIndex + 1] : null;
4162
+ if (!clone) {
4163
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4164
+ const deleteLength = independentCombinators ? 2 : 1;
4165
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4166
+ }
4167
+ const newNewPath = [...nextPath];
4168
+ const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);
4169
+ if (!clone && oldPath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4170
+ const parentToInsertInto = findPath(getParentPath(newNewPath), query);
4171
+ const newIndex = newNewPath.at(-1);
4172
+ /**
4173
+ * This function 1) glosses over the need for type assertions to splice directly
4174
+ * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
4175
+ */
4176
+ const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(newIndex, 0, ...args);
4177
+ if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(ruleOrGroup);
4178
+ else if (newIndex === 0) if (ruleToRemoveIndex === 0 && oldNextCombinator) insertRuleOrGroup(ruleOrGroup, oldNextCombinator);
4179
+ else insertRuleOrGroup(ruleOrGroup, parentToInsertInto.rules[1] ?? oldPrevCombinator ?? getFirstOption(combinators));
4180
+ else if (oldPrevCombinator) insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);
4181
+ else insertRuleOrGroup(parentToInsertInto.rules[newIndex - 2] ?? oldNextCombinator ?? getFirstOption(combinators), ruleOrGroup);
4182
+ return query;
4139
4183
  };
4140
4184
  /**
4141
- * Inserts a rule or group into a query.
4142
- * @returns The new query with the rule or group inserted.
4185
+ * Inserts a rule or group into a query without mutating the original query.
4186
+ *
4187
+ * @returns A new query with the rule or group inserted.
4188
+ *
4189
+ * @group Query Tools
4190
+ */
4191
+ const insert = (query, ruleOrGroup, path, options = {}) => (0, immer.produce)(query, (q) => insertInPlace(q, ruleOrGroup, path, options));
4192
+ /**
4193
+ * Inserts a rule or group into a query in place.
4194
+ *
4195
+ * @returns The query (mutated in place) with the rule or group inserted.
4143
4196
  *
4144
4197
  * @group Query Tools
4145
4198
  */
4146
- const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = {}) => (0, immer.produce)(query, (draft) => {
4147
- const parentToInsertInto = findPath(getParentPath(path), draft);
4148
- if (!parentToInsertInto || !isRuleGroup(parentToInsertInto)) return;
4199
+ const insertInPlace = (query, ruleOrGroup, path, options = {}) => {
4200
+ const { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = options;
4201
+ const parentToInsertInto = findPath(getParentPath(path), query);
4202
+ if (!parentToInsertInto || !isRuleGroup(parentToInsertInto)) return query;
4149
4203
  const rorg = regenerateIDs(ruleOrGroup, { idGenerator });
4150
- const independentCombinators = isRuleGroupTypeIC(draft);
4204
+ const independentCombinators = isRuleGroupTypeIC(query);
4151
4205
  const newIndex = path.at(-1);
4152
4206
  /**
4153
4207
  * This function 1) glosses over the need for type assertions to splice directly
@@ -4163,17 +4217,29 @@ const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, co
4163
4217
  if (combinatorPreceding) insertRuleOrGroup(normalizedNewIndex, combinatorPreceding, rorg);
4164
4218
  else insertRuleOrGroup(normalizedNewIndex, parentToInsertInto.rules[normalizedNewIndex - 2] ?? combinatorSucceeding ?? getFirstOption(combinators), rorg);
4165
4219
  }
4166
- });
4220
+ return query;
4221
+ };
4222
+ /**
4223
+ * Creates a new group at a target path with its `rules` array containing the current
4224
+ * objects at the target path and the source path without mutating the original query.
4225
+ * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.
4226
+ *
4227
+ * @returns A new query with the rules or groups grouped.
4228
+ *
4229
+ * @group Query Tools
4230
+ */
4231
+ const group = (query, sourcePathOrID, targetPathOrID, options = {}) => (0, immer.produce)(query, (q) => groupInPlace(q, sourcePathOrID, targetPathOrID, options));
4167
4232
  /**
4168
4233
  * Creates a new group at a target path with its `rules` array containing the current
4169
- * objects at the target path and the source path. In the options parameter, pass
4170
- * `{ clone: true }` to copy the source rule/group instead of move.
4234
+ * objects at the target path and the source path in place.
4235
+ * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.
4171
4236
  *
4172
- * @returns The new query with the rules or groups grouped.
4237
+ * @returns The query (mutated in place) with the rules or groups grouped.
4173
4238
  *
4174
4239
  * @group Query Tools
4175
4240
  */
4176
- const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
4241
+ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
4242
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
4177
4243
  const sourcePath = Array.isArray(sourcePathOrID) ? sourcePathOrID : getPathOfID(sourcePathOrID, query);
4178
4244
  const targetPath = Array.isArray(targetPathOrID) ? targetPathOrID : getPathOfID(targetPathOrID, query);
4179
4245
  if (!sourcePath || !targetPath) return query;
@@ -4182,36 +4248,35 @@ const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinato
4182
4248
  const sourceRuleOrGroupOriginal = findPath(sourcePath, query);
4183
4249
  const targetRuleOrGroup = findPath(targetPath, query);
4184
4250
  if (!sourceRuleOrGroupOriginal || !targetRuleOrGroup) return query;
4185
- const sourceRuleOrGroup = clone ? regenerateIDs(sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
4186
- return (0, immer.produce)(query, (draft) => {
4187
- const independentCombinators = isRuleGroupTypeIC(draft);
4188
- const parentOfRuleToRemove = findPath(getParentPath(sourcePath), draft);
4189
- const ruleToRemoveIndex = sourcePath.at(-1);
4190
- if (!clone) {
4191
- const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4192
- const deleteLength = independentCombinators ? 2 : 1;
4193
- parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4194
- }
4195
- const newNewPath = [...nextPath];
4196
- const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);
4197
- if (!clone && sourcePath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4198
- const parentOfTargetPath = findPath(getParentPath(newNewPath), draft);
4199
- const targetPathIndex = newNewPath.at(-1);
4200
- parentOfTargetPath.rules.splice(targetPathIndex, 1, prepareRuleOrGroup(independentCombinators ? { rules: [
4201
- targetRuleOrGroup,
4202
- getFirstOption(combinators),
4203
- sourceRuleOrGroup
4204
- ] } : {
4205
- combinator: getFirstOption(combinators),
4206
- rules: [targetRuleOrGroup, sourceRuleOrGroup]
4207
- }, { idGenerator }));
4208
- });
4251
+ const sourceRuleOrGroup = clone ? regenerateIDs((0, immer.isDraft)(sourceRuleOrGroupOriginal) ? (0, immer.current)(sourceRuleOrGroupOriginal) : sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
4252
+ const independentCombinators = isRuleGroupTypeIC(query);
4253
+ const parentOfRuleToRemove = findPath(getParentPath(sourcePath), query);
4254
+ const ruleToRemoveIndex = sourcePath.at(-1);
4255
+ if (!clone) {
4256
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4257
+ const deleteLength = independentCombinators ? 2 : 1;
4258
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4259
+ }
4260
+ const newNewPath = [...nextPath];
4261
+ const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);
4262
+ if (!clone && sourcePath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4263
+ const parentOfTargetPath = findPath(getParentPath(newNewPath), query);
4264
+ const targetPathIndex = newNewPath.at(-1);
4265
+ parentOfTargetPath.rules.splice(targetPathIndex, 1, prepareRuleOrGroup(independentCombinators ? { rules: [
4266
+ targetRuleOrGroup,
4267
+ getFirstOption(combinators),
4268
+ sourceRuleOrGroup
4269
+ ] } : {
4270
+ combinator: getFirstOption(combinators),
4271
+ rules: [targetRuleOrGroup, sourceRuleOrGroup]
4272
+ }, { idGenerator }));
4273
+ return query;
4209
4274
  };
4210
-
4211
4275
  //#endregion
4212
4276
  exports.LogType = LogType;
4213
4277
  exports.TestID = TestID;
4214
4278
  exports.add = add;
4279
+ exports.addInPlace = addInPlace;
4215
4280
  exports.bigIntJsonParseReviver = bigIntJsonParseReviver;
4216
4281
  exports.bigIntJsonStringifyReplacer = bigIntJsonStringifyReplacer;
4217
4282
  exports.celCombinatorMap = celCombinatorMap;
@@ -4288,11 +4353,11 @@ exports.findPath = findPath;
4288
4353
  exports.formatQuery = formatQuery;
4289
4354
  exports.formatQueryOptionPresets = formatQueryOptionPresets;
4290
4355
  exports.generateAccessibleDescription = generateAccessibleDescription;
4291
- Object.defineProperty(exports, 'generateID', {
4292
- enumerable: true,
4293
- get: function () {
4294
- return generateID;
4295
- }
4356
+ Object.defineProperty(exports, "generateID", {
4357
+ enumerable: true,
4358
+ get: function() {
4359
+ return generateID;
4360
+ }
4296
4361
  });
4297
4362
  exports.getCommonAncestorPath = getCommonAncestorPath;
4298
4363
  exports.getFirstOption = getFirstOption;
@@ -4307,8 +4372,10 @@ exports.getQuotedFieldName = getQuotedFieldName;
4307
4372
  exports.getValidationClassNames = getValidationClassNames;
4308
4373
  exports.getValueSourcesUtil = getValueSourcesUtil;
4309
4374
  exports.group = group;
4375
+ exports.groupInPlace = groupInPlace;
4310
4376
  exports.groupInvalidReasons = groupInvalidReasons;
4311
4377
  exports.insert = insert;
4378
+ exports.insertInPlace = insertInPlace;
4312
4379
  exports.isAncestor = isAncestor;
4313
4380
  exports.isFlexibleOptionArray = isFlexibleOptionArray;
4314
4381
  exports.isFlexibleOptionGroupArray = isFlexibleOptionGroupArray;
@@ -4334,6 +4401,7 @@ exports.mergeClassnames = mergeClassnames;
4334
4401
  exports.mongoDbFallback = mongoDbFallback;
4335
4402
  exports.mongoOperators = mongoOperators;
4336
4403
  exports.move = move;
4404
+ exports.moveInPlace = moveInPlace;
4337
4405
  exports.normalizeConstituentWordOrder = normalizeConstituentWordOrder;
4338
4406
  exports.nullFreeArray = nullFreeArray;
4339
4407
  exports.nullOrUndefinedOrEmpty = nullOrUndefinedOrEmpty;
@@ -4358,6 +4426,7 @@ exports.queryBuilderFlagDefaults = queryBuilderFlagDefaults;
4358
4426
  exports.regenerateID = regenerateID;
4359
4427
  exports.regenerateIDs = regenerateIDs;
4360
4428
  exports.remove = remove;
4429
+ exports.removeInPlace = removeInPlace;
4361
4430
  exports.rootPath = rootPath;
4362
4431
  exports.shouldRenderAsNumber = shouldRenderAsNumber;
4363
4432
  exports.splitBy = splitBy;
@@ -4375,4 +4444,6 @@ exports.uniqByName = uniqByName;
4375
4444
  exports.uniqOptGroups = uniqOptGroups;
4376
4445
  exports.uniqOptList = uniqOptList;
4377
4446
  exports.update = update;
4447
+ exports.updateInPlace = updateInPlace;
4448
+
4378
4449
  //# sourceMappingURL=react-querybuilder_core.cjs.development.js.map