@react-querybuilder/core 8.14.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-Dxm6jWFu.d.ts → basic-BXJVfD0P.d.ts} +68 -50
  2. package/dist/{basic-GFsWfi0Z.d.mts → basic-CNIjb6rI.d.mts} +68 -50
  3. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +178 -127
  4. package/dist/cjs/react-querybuilder_core.cjs.development.js +299 -251
  5. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  6. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +178 -127
  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-_wipiqJZ.d.mts → export-6x7MilFR.d.mts} +2 -3
  14. package/dist/{export-6VbkhCrf.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 +18 -50
  18. package/dist/formatQuery.js.map +1 -1
  19. package/dist/formatQuery.mjs +17 -49
  20. package/dist/formatQuery.mjs.map +1 -1
  21. package/dist/{import-D8M7awTx.d.ts → import-B5Iq8XmL.d.ts} +2 -3
  22. package/dist/{import-DRmutNSr.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 +9 -11
  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 -13
  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 +9 -11
  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-BxWvIPI4.js → prepareQueryObjects-Dc8rqsYM.js} +49 -34
  64. package/dist/prepareQueryObjects-Dc8rqsYM.js.map +1 -0
  65. package/dist/{prepareQueryObjects-BBayjIn2.mjs → prepareQueryObjects-tMukQHT9.mjs} +34 -18
  66. package/dist/prepareQueryObjects-tMukQHT9.mjs.map +1 -0
  67. package/dist/react-querybuilder_core.d.mts +178 -127
  68. package/dist/react-querybuilder_core.legacy-esm.d.ts +178 -127
  69. package/dist/react-querybuilder_core.legacy-esm.js +296 -279
  70. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  71. package/dist/react-querybuilder_core.mjs +288 -247
  72. package/dist/react-querybuilder_core.mjs.map +1 -1
  73. package/dist/react-querybuilder_core.production.d.mts +178 -127
  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 -2
  79. package/dist/transformQuery.js.map +1 -0
  80. package/dist/transformQuery.mjs +43 -2
  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 +25 -17
  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-BBayjIn2.mjs.map +0 -1
  94. package/dist/prepareQueryObjects-BxWvIPI4.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 = {
@@ -2705,12 +2682,11 @@ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
2705
2682
  }
2706
2683
  return false;
2707
2684
  };
2708
-
2709
2685
  //#endregion
2710
2686
  //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
2711
2687
  const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
2712
2688
  const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
2713
- const negate = (clause, negate$1) => negate$1 ? `$not(${clause})` : clause;
2689
+ const negate = (clause, neg) => neg ? `$not(${clause})` : clause;
2714
2690
  const escapeStringRegex = (s) => `${s}`.replaceAll(/[/$()*+.?[\\\]^{|}]/g, String.raw`\$&`).replaceAll("-", String.raw`\x2d`);
2715
2691
  /**
2716
2692
  * Default rule processor used by {@link formatQuery} for "jsonata" format.
@@ -2792,7 +2768,6 @@ const defaultRuleProcessorJSONata = (rule, options = {}) => {
2792
2768
  }
2793
2769
  return "";
2794
2770
  };
2795
-
2796
2771
  //#endregion
2797
2772
  //#region src/utils/formatQuery/defaultRuleProcessorJsonLogic.ts
2798
2773
  const convertOperator = (op) => op.replace(/^(=)$/, "$1=").replace(/^notnull$/i, "!=").replace(/^null$/i, "==");
@@ -2887,10 +2862,9 @@ const defaultRuleProcessorJsonLogic = (rule, options = {}) => {
2887
2862
  }
2888
2863
  return false;
2889
2864
  };
2890
-
2891
2865
  //#endregion
2892
2866
  //#region src/utils/formatQuery/defaultRuleProcessorLDAP.ts
2893
- const negateIf = (clause, negate$1) => negate$1 ? `(!${clause})` : `${clause}`;
2867
+ const negateIf = (clause, negate) => negate ? `(!${clause})` : `${clause}`;
2894
2868
  const ldapEscape = (s) => `${trimIfString(s)}`.replaceAll(/[()&|=<>~*\\/]/g, (m) => `\\${m.codePointAt(0).toString(16)}`);
2895
2869
  /**
2896
2870
  * Default rule processor used by {@link formatQuery} for "ldap" format.
@@ -2939,7 +2913,6 @@ const defaultRuleProcessorLDAP = (rule, options = {}) => {
2939
2913
  // istanbul ignore next
2940
2914
  return "";
2941
2915
  };
2942
-
2943
2916
  //#endregion
2944
2917
  //#region src/utils/formatQuery/defaultValueProcessorNL.ts
2945
2918
  const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
@@ -2989,7 +2962,6 @@ const defaultValueProcessorNL = (rule, opts = {}) => {
2989
2962
  if (typeof rule.value === "boolean") return rule.value ? trueTL : falseTL;
2990
2963
  return valueIsField ? wrapFieldName(getOption(fields ?? [], rule.value)?.label ?? rule.value) : shouldRenderAsNumber(rule.value, parseNumbers) ? `${trimIfString(rule.value)}` : `${wrapAndEscape(rule.value)}`;
2991
2964
  };
2992
-
2993
2965
  //#endregion
2994
2966
  //#region src/utils/formatQuery/defaultRuleProcessorNL.ts
2995
2967
  /**
@@ -3099,7 +3071,6 @@ const defaultRuleProcessorNL = (rule, opts) => {
3099
3071
  };
3100
3072
  return normalizeConstituentWordOrder(wordOrder).map((term) => `${wordOrderMap[term]}`).join(" ").trim();
3101
3073
  };
3102
-
3103
3074
  //#endregion
3104
3075
  //#region src/utils/formatQuery/defaultRuleProcessorSQL.ts
3105
3076
  /**
@@ -3154,7 +3125,6 @@ const defaultRuleProcessorSQL = (rule, opts = {}) => {
3154
3125
  if ((operatorLowerCase === "in" || operatorLowerCase === "not in" || operatorLowerCase === "between" || operatorLowerCase === "not between") && !value) return "";
3155
3126
  return `${ruleField} ${operator} ${value}`.trim();
3156
3127
  };
3157
-
3158
3128
  //#endregion
3159
3129
  //#region src/utils/formatQuery/defaultRuleProcessorParameterized.ts
3160
3130
  /**
@@ -3259,7 +3229,6 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
3259
3229
  }
3260
3230
  return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${parameterized ? numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?" : `${paramPrefix}${paramName}`}`.trim());
3261
3231
  };
3262
-
3263
3232
  //#endregion
3264
3233
  //#region src/utils/formatQuery/defaultRuleProcessorPrisma.ts
3265
3234
  const processNumber = (value, fallback, parseNumbers) => shouldRenderAsNumber(value, !!parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: !!parseNumbers })) : fallback;
@@ -3321,7 +3290,6 @@ const defaultRuleProcessorPrisma = (rule, options = {}) => {
3321
3290
  }
3322
3291
  return "";
3323
3292
  };
3324
-
3325
3293
  //#endregion
3326
3294
  //#region src/utils/formatQuery/defaultRuleProcessorSequelize.ts
3327
3295
  /**
@@ -3388,7 +3356,6 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
3388
3356
  }
3389
3357
  }
3390
3358
  };
3391
-
3392
3359
  //#endregion
3393
3360
  //#region src/utils/formatQuery/formatQuery.ts
3394
3361
  /**
@@ -3477,8 +3444,8 @@ const defaultFormatQueryOptions = {
3477
3444
  paramsKeepPrefix: false,
3478
3445
  numberedParams: false,
3479
3446
  preserveValueOrder: false,
3480
- placeholderFieldName: defaultPlaceholderFieldName,
3481
- placeholderOperatorName: defaultPlaceholderOperatorName,
3447
+ placeholderFieldName: "~",
3448
+ placeholderOperatorName: "~",
3482
3449
  quoteValuesWith: "'",
3483
3450
  concatOperator: "||",
3484
3451
  preset: "ansi",
@@ -3583,7 +3550,7 @@ function formatQuery(ruleGroup, optionParam = {}) {
3583
3550
  switch (format) {
3584
3551
  case "json":
3585
3552
  case "json_without_ids": {
3586
- const rg = parseNumbers ? (0, immer.produce)(ruleGroup, (g) => numerifyValues(g, finalOptions)) : ruleGroup;
3553
+ const rg = parseNumbers ? numerifyValues(ruleGroup, finalOptions) : ruleGroup;
3587
3554
  if (format === "json_without_ids") return JSON.stringify(rg, (key, value) => key === "id" || key === "path" ? void 0 : bigIntJsonStringifyReplacer(key, value));
3588
3555
  return JSON.stringify(rg, bigIntJsonStringifyReplacer, 2);
3589
3556
  }
@@ -3605,7 +3572,6 @@ function formatQuery(ruleGroup, optionParam = {}) {
3605
3572
  default: return "";
3606
3573
  }
3607
3574
  }
3608
-
3609
3575
  //#endregion
3610
3576
  //#region src/utils/formatQuery/index.ts
3611
3577
  const generateValueProcessor = (vpbr) => (field, operator, value, valueSource) => vpbr({
@@ -3656,7 +3622,6 @@ const defaultValueProcessorMongoDBByRule = defaultRuleProcessorMongoDB;
3656
3622
  * @group Export
3657
3623
  */
3658
3624
  const defaultValueProcessorSpELByRule = defaultRuleProcessorSpEL;
3659
-
3660
3625
  //#endregion
3661
3626
  //#region src/utils/pathUtils.ts
3662
3627
  /**
@@ -3715,7 +3680,7 @@ const pathsAreEqual = (path1, path2) => path1.length === path2.length && path1.e
3715
3680
  * Determines if the first path is an ancestor of the second path. The first path must
3716
3681
  * be shorter and exactly match the second path up through the length of the first path.
3717
3682
  */
3718
- 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("-"));
3719
3684
  /**
3720
3685
  * Finds the deepest/longest path that two paths have in common.
3721
3686
  */
@@ -3748,11 +3713,9 @@ const pathIsDisabled = (path, query) => {
3748
3713
  }
3749
3714
  return disabled;
3750
3715
  };
3751
-
3752
3716
  //#endregion
3753
3717
  //#region src/utils/generateAccessibleDescription.ts
3754
3718
  const generateAccessibleDescription = (params) => pathsAreEqual([], params.path) ? `Query builder` : `Rule group at path ${params.path.join("-")}`;
3755
-
3756
3719
  //#endregion
3757
3720
  //#region src/utils/generateID.ts
3758
3721
  const cryptoModule = globalThis.crypto;
@@ -3787,7 +3750,6 @@ if (cryptoModule) {
3787
3750
  };
3788
3751
  }
3789
3752
  }
3790
-
3791
3753
  //#endregion
3792
3754
  //#region src/utils/getMatchModesUtil.ts
3793
3755
  const dummyFD$1 = {
@@ -3815,7 +3777,6 @@ const getMatchModesUtil = (fieldData, getMatchModes) => {
3815
3777
  label: mm
3816
3778
  }) ?? [];
3817
3779
  };
3818
-
3819
3780
  //#endregion
3820
3781
  //#region src/utils/getValidationClassNames.ts
3821
3782
  /**
@@ -3826,7 +3787,6 @@ const getValidationClassNames = (validationResult) => {
3826
3787
  const valid = typeof validationResult === "boolean" ? validationResult : typeof validationResult === "object" && validationResult !== null ? validationResult.valid : null;
3827
3788
  return typeof valid === "boolean" ? valid ? standardClassnames.valid : standardClassnames.invalid : "";
3828
3789
  };
3829
-
3830
3790
  //#endregion
3831
3791
  //#region src/utils/getValueSourcesUtil.ts
3832
3792
  const defaultValueSourcesArray = [{
@@ -3859,18 +3819,22 @@ const getValueSourcesUtil = (fieldData, operator, getValueSources) => {
3859
3819
  label: vs
3860
3820
  });
3861
3821
  };
3862
-
3863
3822
  //#endregion
3864
3823
  //#region src/utils/mergeAnyTranslations.ts
3865
3824
  /**
3866
3825
  * Merges any number of partial translations into a single definition.
3867
3826
  */
3868
- const mergeAnyTranslations = (base, ...otherTranslations) => (0, immer.produce)(base, (draft) => {
3827
+ const mergeAnyTranslations = (base, ...otherTranslations) => {
3828
+ const result = { ...base };
3869
3829
  for (const translations of otherTranslations)
3870
3830
  // istanbul ignore else
3871
- if (translations) for (const t of objectKeys(translations)) if (draft[t]) Object.assign(draft[t], translations[t]);
3872
- else Object.assign(draft, { [t]: translations[t] });
3873
- });
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
+ };
3874
3838
  const mergeAnyTranslation = (el, keyPropContextMap, defaults) => {
3875
3839
  const finalKeys = objectEntries(keyPropContextMap).map(([key, [pT, cT]]) => [key, pT ?? cT ?? defaults?.[el]?.[key]]).filter((k) => !!k[1]);
3876
3840
  if (finalKeys.length > 0 || defaults) {
@@ -3879,7 +3843,6 @@ const mergeAnyTranslation = (el, keyPropContextMap, defaults) => {
3879
3843
  return { [el]: finalObject };
3880
3844
  }
3881
3845
  };
3882
-
3883
3846
  //#endregion
3884
3847
  //#region src/utils/mergeClassnames.ts
3885
3848
  const joinClassnamesByName = (name, args) => clsx(args.map((c) => clsx(c?.[name])));
@@ -3929,7 +3892,6 @@ const mergeClassnames = (...args) => ({
3929
3892
  hasSubQuery: joinClassnamesByName("hasSubQuery", args),
3930
3893
  loading: joinClassnamesByName("loading", args)
3931
3894
  });
3932
-
3933
3895
  //#endregion
3934
3896
  //#region src/utils/preferProp.ts
3935
3897
  const preferPropDefaultTrue = (prop, context) => prop === false ? false : prop ? true : !(context === false);
@@ -3952,29 +3914,49 @@ const preferFlagProps = (props = {}, contextVals = {}, finalize) => objectEntrie
3952
3914
  acc[key] = preferProp(def, props[key], contextVals[key], !finalize);
3953
3915
  return acc;
3954
3916
  }, {});
3955
-
3956
3917
  //#endregion
3957
3918
  //#region src/utils/prepareQueryObjects.ts
3958
3919
  /**
3959
3920
  * Ensures that a rule is valid by adding an `id` property if it does not already exist.
3960
3921
  */
3961
- const prepareRule = (rule, { idGenerator = generateID } = {}) => (0, immer.produce)(rule, (draft) => {
3962
- if (!draft.id) draft.id = idGenerator();
3963
- if (processMatchMode(draft)) draft.value = prepareRuleGroup(draft.value, { idGenerator });
3964
- });
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
+ };
3965
3932
  /**
3966
3933
  * Ensures that a rule group is valid by recursively adding an `id` property to the group itself
3967
3934
  * and all its rules and subgroups where one does not already exist.
3968
3935
  */
3969
- const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => (0, immer.produce)(queryObject, (draft) => {
3970
- if (!draft.id) draft.id = idGenerator();
3971
- draft.rules = draft.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? prepareRuleGroup(r, { idGenerator }) : prepareRule(r, { idGenerator }));
3972
- });
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
+ };
3973
3956
  /**
3974
3957
  * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.
3975
3958
  */
3976
3959
  const prepareRuleOrGroup = (rg, { idGenerator = generateID } = {}) => isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });
3977
-
3978
3960
  //#endregion
3979
3961
  //#region src/utils/regenerateIDs.ts
3980
3962
  /**
@@ -4001,44 +3983,65 @@ const regenerateIDs = (subject, { idGenerator = generateID } = {}) => {
4001
3983
  if (Array.isArray(newGroup.rules)) newGroup.rules = subject.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? regenerateIDs(r, { idGenerator }) : regenerateID(r, { idGenerator }));
4002
3984
  return newGroup;
4003
3985
  };
4004
-
4005
3986
  //#endregion
4006
3987
  //#region src/utils/queryTools.ts
4007
3988
  /**
4008
- * Adds a rule or group to a query.
4009
- * @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.
4010
3992
  *
4011
3993
  * @group Query Tools
4012
3994
  */
4013
- const add = (query, ruleOrGroup, parentPathOrID, { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = {}) => (0, immer.produce)(query, (draft) => {
4014
- const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, draft) : findID(parentPathOrID, draft);
4015
- 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;
4016
4007
  if (isRuleGroupTypeIC(parent) && parent.rules.length > 0) {
4017
4008
  const prevCombinator = parent.rules.at(-2);
4018
4009
  parent.rules.push(combinatorPreceding ?? (typeof prevCombinator === "string" ? prevCombinator : getFirstOption(combinators)));
4019
4010
  }
4020
4011
  parent.rules.push(prepareRuleOrGroup(ruleOrGroup, { idGenerator }));
4021
- });
4012
+ return query;
4013
+ };
4022
4014
  /**
4023
- * Updates a property of a rule or group within a query.
4024
- * @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.
4025
4018
  *
4026
4019
  * @group Query Tools
4027
4020
  */
4028
- const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = {}) => (0, immer.produce)(query, (draft) => {
4029
- const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, draft);
4030
- if (!path) return;
4031
- if (prop === "combinator" && !isRuleGroupType(draft)) {
4032
- const parentRules = findPath(getParentPath(path), draft).rules;
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.
4026
+ *
4027
+ * @group Query Tools
4028
+ */
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;
4033
4036
  if (path.at(-1) % 2 === 1) parentRules[path.at(-1)] = value;
4034
- return;
4037
+ return query;
4035
4038
  }
4036
- const ruleOrGroup = findPath(path, draft);
4037
- if (!ruleOrGroup) return;
4039
+ const ruleOrGroup = findPath(path, query);
4040
+ if (!ruleOrGroup) return query;
4038
4041
  const isGroup = isRuleGroup(ruleOrGroup);
4039
- if (ruleOrGroup[prop] === value) return;
4042
+ if (ruleOrGroup[prop] === value) return query;
4040
4043
  if (prop !== "valueSource") ruleOrGroup[prop] = value;
4041
- if (isGroup) return;
4044
+ if (isGroup) return query;
4042
4045
  let resetValueSource = false;
4043
4046
  let resetValue = false;
4044
4047
  if (prop === "field") {
@@ -4073,25 +4076,33 @@ const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, reset
4073
4076
  ruleOrGroup.valueSource = resetValueSource ? defaultValueSource : value;
4074
4077
  }
4075
4078
  if (resetValue) ruleOrGroup.value = getRuleDefaultValue(ruleOrGroup);
4076
- });
4079
+ return query;
4080
+ };
4077
4081
  /**
4078
- * Removes a rule or group from a query.
4079
- * @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.
4080
4085
  *
4081
4086
  * @group Query Tools
4082
4087
  */
4083
- const remove = (query, pathOrID) => {
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.
4093
+ *
4094
+ * @group Query Tools
4095
+ */
4096
+ const removeInPlace = (query, pathOrID) => {
4084
4097
  const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
4085
- if (!path) return query;
4086
- if (path.length === 0 || !isRuleGroupType(query) && !findPath(path, query)) return query;
4087
- return (0, immer.produce)(query, (draft) => {
4088
- const index = path.at(-1);
4089
- const parent = findPath(getParentPath(path), draft);
4090
- if (parent && isRuleGroup(parent)) if (!isRuleGroupType(parent) && parent.rules.length > 1) {
4091
- const idxStartDelete = index === 0 ? 0 : index - 1;
4092
- parent.rules.splice(idxStartDelete, 2);
4093
- } else parent.rules.splice(index, 1);
4094
- });
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;
4095
4106
  };
4096
4107
  const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4097
4108
  if (Array.isArray(newPathOrShiftDirection)) return newPathOrShiftDirection;
@@ -4118,59 +4129,79 @@ const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4118
4129
  return currentPath;
4119
4130
  };
4120
4131
  /**
4121
- * Moves a rule or group from one path to another. In the options parameter, pass
4122
- * `{ clone: true }` to copy instead of move.
4123
- * @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.
4124
4136
  *
4125
4137
  * @group Query Tools
4126
4138
  */
4127
- 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;
4128
4150
  const oldPath = Array.isArray(oldPathOrID) ? oldPathOrID : getPathOfID(oldPathOrID, query);
4129
4151
  if (!oldPath) return query;
4130
4152
  const nextPath = getNextPath(query, oldPath, newPath);
4131
4153
  if (oldPath.length === 0 || pathsAreEqual(oldPath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
4132
4154
  const ruleOrGroupOriginal = findPath(oldPath, query);
4133
4155
  if (!ruleOrGroupOriginal) return query;
4134
- const ruleOrGroup = clone ? regenerateIDs(ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
4135
- return (0, immer.produce)(query, (draft) => {
4136
- const independentCombinators = isRuleGroupTypeIC(draft);
4137
- const parentOfRuleToRemove = findPath(getParentPath(oldPath), draft);
4138
- const ruleToRemoveIndex = oldPath.at(-1);
4139
- const oldPrevCombinator = independentCombinators && ruleToRemoveIndex > 0 ? parentOfRuleToRemove.rules[ruleToRemoveIndex - 1] : null;
4140
- const oldNextCombinator = independentCombinators && ruleToRemoveIndex < parentOfRuleToRemove.rules.length - 1 ? parentOfRuleToRemove.rules[ruleToRemoveIndex + 1] : null;
4141
- if (!clone) {
4142
- const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4143
- const deleteLength = independentCombinators ? 2 : 1;
4144
- parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4145
- }
4146
- const newNewPath = [...nextPath];
4147
- const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);
4148
- if (!clone && oldPath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4149
- const parentToInsertInto = findPath(getParentPath(newNewPath), draft);
4150
- const newIndex = newNewPath.at(-1);
4151
- /**
4152
- * This function 1) glosses over the need for type assertions to splice directly
4153
- * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
4154
- */
4155
- const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(newIndex, 0, ...args);
4156
- if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(ruleOrGroup);
4157
- else if (newIndex === 0) if (ruleToRemoveIndex === 0 && oldNextCombinator) insertRuleOrGroup(ruleOrGroup, oldNextCombinator);
4158
- else insertRuleOrGroup(ruleOrGroup, parentToInsertInto.rules[1] ?? oldPrevCombinator ?? getFirstOption(combinators));
4159
- else if (oldPrevCombinator) insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);
4160
- else insertRuleOrGroup(parentToInsertInto.rules[newIndex - 2] ?? oldNextCombinator ?? getFirstOption(combinators), ruleOrGroup);
4161
- });
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;
4162
4183
  };
4163
4184
  /**
4164
- * Inserts a rule or group into a query.
4165
- * @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.
4166
4196
  *
4167
4197
  * @group Query Tools
4168
4198
  */
4169
- const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = {}) => (0, immer.produce)(query, (draft) => {
4170
- const parentToInsertInto = findPath(getParentPath(path), draft);
4171
- 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;
4172
4203
  const rorg = regenerateIDs(ruleOrGroup, { idGenerator });
4173
- const independentCombinators = isRuleGroupTypeIC(draft);
4204
+ const independentCombinators = isRuleGroupTypeIC(query);
4174
4205
  const newIndex = path.at(-1);
4175
4206
  /**
4176
4207
  * This function 1) glosses over the need for type assertions to splice directly
@@ -4186,17 +4217,29 @@ const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, co
4186
4217
  if (combinatorPreceding) insertRuleOrGroup(normalizedNewIndex, combinatorPreceding, rorg);
4187
4218
  else insertRuleOrGroup(normalizedNewIndex, parentToInsertInto.rules[normalizedNewIndex - 2] ?? combinatorSucceeding ?? getFirstOption(combinators), rorg);
4188
4219
  }
4189
- });
4220
+ return query;
4221
+ };
4190
4222
  /**
4191
4223
  * Creates a new group at a target path with its `rules` array containing the current
4192
- * objects at the target path and the source path. In the options parameter, pass
4193
- * `{ clone: true }` to copy the source rule/group instead of move.
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.
4194
4226
  *
4195
- * @returns The new query with the rules or groups grouped.
4227
+ * @returns A new query with the rules or groups grouped.
4196
4228
  *
4197
4229
  * @group Query Tools
4198
4230
  */
4199
- const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
4231
+ const group = (query, sourcePathOrID, targetPathOrID, options = {}) => (0, immer.produce)(query, (q) => groupInPlace(q, sourcePathOrID, targetPathOrID, options));
4232
+ /**
4233
+ * Creates a new group at a target path with its `rules` array containing the current
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.
4236
+ *
4237
+ * @returns The query (mutated in place) with the rules or groups grouped.
4238
+ *
4239
+ * @group Query Tools
4240
+ */
4241
+ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
4242
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
4200
4243
  const sourcePath = Array.isArray(sourcePathOrID) ? sourcePathOrID : getPathOfID(sourcePathOrID, query);
4201
4244
  const targetPath = Array.isArray(targetPathOrID) ? targetPathOrID : getPathOfID(targetPathOrID, query);
4202
4245
  if (!sourcePath || !targetPath) return query;
@@ -4205,36 +4248,35 @@ const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinato
4205
4248
  const sourceRuleOrGroupOriginal = findPath(sourcePath, query);
4206
4249
  const targetRuleOrGroup = findPath(targetPath, query);
4207
4250
  if (!sourceRuleOrGroupOriginal || !targetRuleOrGroup) return query;
4208
- const sourceRuleOrGroup = clone ? regenerateIDs(sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
4209
- return (0, immer.produce)(query, (draft) => {
4210
- const independentCombinators = isRuleGroupTypeIC(draft);
4211
- const parentOfRuleToRemove = findPath(getParentPath(sourcePath), draft);
4212
- const ruleToRemoveIndex = sourcePath.at(-1);
4213
- if (!clone) {
4214
- const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4215
- const deleteLength = independentCombinators ? 2 : 1;
4216
- parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4217
- }
4218
- const newNewPath = [...nextPath];
4219
- const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);
4220
- if (!clone && sourcePath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4221
- const parentOfTargetPath = findPath(getParentPath(newNewPath), draft);
4222
- const targetPathIndex = newNewPath.at(-1);
4223
- parentOfTargetPath.rules.splice(targetPathIndex, 1, prepareRuleOrGroup(independentCombinators ? { rules: [
4224
- targetRuleOrGroup,
4225
- getFirstOption(combinators),
4226
- sourceRuleOrGroup
4227
- ] } : {
4228
- combinator: getFirstOption(combinators),
4229
- rules: [targetRuleOrGroup, sourceRuleOrGroup]
4230
- }, { idGenerator }));
4231
- });
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;
4232
4274
  };
4233
-
4234
4275
  //#endregion
4235
4276
  exports.LogType = LogType;
4236
4277
  exports.TestID = TestID;
4237
4278
  exports.add = add;
4279
+ exports.addInPlace = addInPlace;
4238
4280
  exports.bigIntJsonParseReviver = bigIntJsonParseReviver;
4239
4281
  exports.bigIntJsonStringifyReplacer = bigIntJsonStringifyReplacer;
4240
4282
  exports.celCombinatorMap = celCombinatorMap;
@@ -4311,11 +4353,11 @@ exports.findPath = findPath;
4311
4353
  exports.formatQuery = formatQuery;
4312
4354
  exports.formatQueryOptionPresets = formatQueryOptionPresets;
4313
4355
  exports.generateAccessibleDescription = generateAccessibleDescription;
4314
- Object.defineProperty(exports, 'generateID', {
4315
- enumerable: true,
4316
- get: function () {
4317
- return generateID;
4318
- }
4356
+ Object.defineProperty(exports, "generateID", {
4357
+ enumerable: true,
4358
+ get: function() {
4359
+ return generateID;
4360
+ }
4319
4361
  });
4320
4362
  exports.getCommonAncestorPath = getCommonAncestorPath;
4321
4363
  exports.getFirstOption = getFirstOption;
@@ -4330,8 +4372,10 @@ exports.getQuotedFieldName = getQuotedFieldName;
4330
4372
  exports.getValidationClassNames = getValidationClassNames;
4331
4373
  exports.getValueSourcesUtil = getValueSourcesUtil;
4332
4374
  exports.group = group;
4375
+ exports.groupInPlace = groupInPlace;
4333
4376
  exports.groupInvalidReasons = groupInvalidReasons;
4334
4377
  exports.insert = insert;
4378
+ exports.insertInPlace = insertInPlace;
4335
4379
  exports.isAncestor = isAncestor;
4336
4380
  exports.isFlexibleOptionArray = isFlexibleOptionArray;
4337
4381
  exports.isFlexibleOptionGroupArray = isFlexibleOptionGroupArray;
@@ -4357,6 +4401,7 @@ exports.mergeClassnames = mergeClassnames;
4357
4401
  exports.mongoDbFallback = mongoDbFallback;
4358
4402
  exports.mongoOperators = mongoOperators;
4359
4403
  exports.move = move;
4404
+ exports.moveInPlace = moveInPlace;
4360
4405
  exports.normalizeConstituentWordOrder = normalizeConstituentWordOrder;
4361
4406
  exports.nullFreeArray = nullFreeArray;
4362
4407
  exports.nullOrUndefinedOrEmpty = nullOrUndefinedOrEmpty;
@@ -4381,6 +4426,7 @@ exports.queryBuilderFlagDefaults = queryBuilderFlagDefaults;
4381
4426
  exports.regenerateID = regenerateID;
4382
4427
  exports.regenerateIDs = regenerateIDs;
4383
4428
  exports.remove = remove;
4429
+ exports.removeInPlace = removeInPlace;
4384
4430
  exports.rootPath = rootPath;
4385
4431
  exports.shouldRenderAsNumber = shouldRenderAsNumber;
4386
4432
  exports.splitBy = splitBy;
@@ -4398,4 +4444,6 @@ exports.uniqByName = uniqByName;
4398
4444
  exports.uniqOptGroups = uniqOptGroups;
4399
4445
  exports.uniqOptList = uniqOptList;
4400
4446
  exports.update = update;
4447
+ exports.updateInPlace = updateInPlace;
4448
+
4401
4449
  //# sourceMappingURL=react-querybuilder_core.cjs.development.js.map