@react-querybuilder/core 8.14.0 → 8.14.2

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 (101) 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 +183 -127
  4. package/dist/cjs/react-querybuilder_core.cjs.development.js +311 -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 +183 -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-CeJSNn37.mjs} +30 -22
  10. package/dist/convertQuery-CeJSNn37.mjs.map +1 -0
  11. package/dist/convertQuery-J8LpTG-7.js +94 -0
  12. package/dist/convertQuery-J8LpTG-7.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 +75 -107
  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/objectUtils-ButT0Mng.js +105 -0
  24. package/dist/objectUtils-ButT0Mng.js.map +1 -0
  25. package/dist/{isRuleGroup-DztIOOKa.mjs → objectUtils-C0WB-8ex.mjs} +16 -5
  26. package/dist/objectUtils-C0WB-8ex.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 +40 -5614
  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 +47 -48
  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 +26 -27
  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 +13 -15
  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 +13 -2702
  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-BBayjIn2.mjs → prepareQueryObjects-BfMlS4ql.mjs} +34 -18
  64. package/dist/prepareQueryObjects-BfMlS4ql.mjs.map +1 -0
  65. package/dist/{prepareQueryObjects-BxWvIPI4.js → prepareQueryObjects-DO3qXriW.js} +50 -35
  66. package/dist/prepareQueryObjects-DO3qXriW.js.map +1 -0
  67. package/dist/react-querybuilder_core.d.mts +183 -127
  68. package/dist/react-querybuilder_core.legacy-esm.d.ts +183 -127
  69. package/dist/react-querybuilder_core.legacy-esm.js +307 -280
  70. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  71. package/dist/react-querybuilder_core.mjs +299 -248
  72. package/dist/react-querybuilder_core.mjs.map +1 -1
  73. package/dist/react-querybuilder_core.production.d.mts +183 -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 +45 -2
  79. package/dist/transformQuery.js.map +1 -0
  80. package/dist/transformQuery.mjs +44 -2
  81. package/dist/transformQuery.mjs.map +1 -0
  82. package/dist/{utils-nQU7WCM9.mjs → utils-BlMGIhvx.mjs} +32 -92
  83. package/dist/utils-BlMGIhvx.mjs.map +1 -0
  84. package/dist/{utils-CR1ToTMW.js → utils-CZRhzje-.js} +187 -265
  85. package/dist/utils-CZRhzje-.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 +0 -82
  92. package/dist/isRuleGroup-Cjk1Q2mj.js.map +0 -1
  93. package/dist/isRuleGroup-DztIOOKa.mjs.map +0 -1
  94. package/dist/prepareQueryObjects-BBayjIn2.mjs.map +0 -1
  95. package/dist/prepareQueryObjects-BxWvIPI4.js.map +0 -1
  96. package/dist/transformQuery-ClBRfnFg.js +0 -54
  97. package/dist/transformQuery-ClBRfnFg.js.map +0 -1
  98. package/dist/transformQuery-DUpbpqjX.mjs +0 -48
  99. package/dist/transformQuery-DUpbpqjX.mjs.map +0 -1
  100. package/dist/utils-CR1ToTMW.js.map +0 -1
  101. 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,11 @@ 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
-
824
+ /**
825
+ * Returns `true` if the key could cause prototype pollution when used
826
+ * as a property name in bracket-notation assignment.
827
+ */
828
+ const isUnsafeKey = (key) => key === "__proto__" || key === "constructor" || key === "prototype";
822
829
  //#endregion
823
830
  //#region src/utils/optGroupUtils.ts
824
831
  const isOptionWithName = (opt) => isPojo(opt) && "name" in opt && typeof opt.name === "string";
@@ -830,24 +837,23 @@ const isOptionWithValue = (opt) => isPojo(opt) && "value" in opt && typeof opt.v
830
837
  * @group Option Lists
831
838
  */
832
839
  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);
840
+ if (typeof opt === "string") return {
841
+ ...baseProperties,
842
+ name: opt,
843
+ value: opt,
844
+ label: labelMap?.[opt] ?? opt
845
+ };
846
+ const idObj = {};
847
+ let needsUpdating = !!baseProperties;
848
+ if (isOptionWithName(opt) && !isOptionWithValue(opt)) {
849
+ idObj.value = opt.name;
850
+ needsUpdating = true;
851
+ } else if (!isOptionWithName(opt) && isOptionWithValue(opt)) {
852
+ idObj.name = opt.value;
853
+ needsUpdating = true;
854
+ }
855
+ if (needsUpdating) return Object.assign({}, baseProperties, opt, idObj);
856
+ return opt;
851
857
  }
852
858
  /**
853
859
  * Converts an {@link OptionList} or {@link FlexibleOptionList} into a {@link FullOptionList}.
@@ -857,10 +863,12 @@ function toFullOption(opt, baseProperties, labelMap) {
857
863
  */
858
864
  function toFullOptionList(optList, baseProperties, labelMap) {
859
865
  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);
866
+ const list = optList;
867
+ if (isFlexibleOptionGroupArray(list)) return list.map((optGroup) => ({
868
+ ...optGroup,
869
+ options: optGroup.options.map((opt) => toFullOption(opt, baseProperties, labelMap))
870
+ }));
871
+ return list.map((opt) => toFullOption(opt, baseProperties, labelMap));
864
872
  }
865
873
  /**
866
874
  * Converts a {@link FlexibleOptionList} into a {@link FullOptionList}.
@@ -997,7 +1005,7 @@ const uniqOptList = (originalArray) => {
997
1005
  };
998
1006
  const prepareOptionList = (props) => {
999
1007
  // istanbul ignore next
1000
- const { optionList: optionListPropOriginal, baseOption = {}, labelMap = {}, placeholder: { placeholderName = defaultPlaceholderName, placeholderLabel = defaultPlaceholderLabel, placeholderGroupLabel = defaultPlaceholderLabel } = {}, autoSelectOption = true } = props;
1008
+ const { optionList: optionListPropOriginal, baseOption = {}, labelMap = {}, placeholder: { placeholderName = "~", placeholderLabel = defaultPlaceholderLabel, placeholderGroupLabel = defaultPlaceholderLabel } = {}, autoSelectOption = true } = props;
1001
1009
  const defaultOption = {
1002
1010
  id: placeholderName,
1003
1011
  name: placeholderName,
@@ -1031,7 +1039,6 @@ const prepareOptionList = (props) => {
1031
1039
  optionsMap
1032
1040
  };
1033
1041
  };
1034
-
1035
1042
  //#endregion
1036
1043
  //#region src/utils/filterFieldsByComparator.ts
1037
1044
  const filterByComparator = (field, operator, fieldToCompare) => {
@@ -1067,7 +1074,6 @@ const filterFieldsByComparator = (field, fields, operator) => {
1067
1074
  })).filter((og) => og.options.length > 0);
1068
1075
  return fields.filter((f) => filterByComparator(field, operator, f));
1069
1076
  };
1070
-
1071
1077
  //#endregion
1072
1078
  //#region src/utils/parseNumber.ts
1073
1079
  /**
@@ -1087,23 +1093,21 @@ const parseNumber = (val, { parseNumbers, bigIntOnOverflow } = {}) => {
1087
1093
  });
1088
1094
  return typeof valAsNum === "bigint" || !Number.isNaN(valAsNum) ? valAsNum : val;
1089
1095
  };
1090
-
1091
1096
  //#endregion
1092
1097
  //#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];
1098
+ const remapProperties = (obj, propertyMap, deleteRemappedProperties) => {
1099
+ const result = {};
1100
+ for (const key in obj) {
1101
+ if (isUnsafeKey(key)) continue;
1102
+ const mappedKey = propertyMap[key];
1103
+ if (mappedKey === false) continue;
1104
+ if (mappedKey && key !== mappedKey) {
1105
+ if (!isUnsafeKey(mappedKey)) result[mappedKey] = obj[key];
1106
+ if (!deleteRemappedProperties) result[key] = obj[key];
1107
+ } else result[key] = obj[key];
1105
1108
  }
1106
- });
1109
+ return result;
1110
+ };
1107
1111
  function transformQuery(query, options = {}) {
1108
1112
  const { ruleProcessor = (r) => r, ruleGroupProcessor = (rg) => rg, propertyMap = {}, combinatorMap = {}, operatorMap = {}, omitPath = false, deleteRemappedProperties = true } = options;
1109
1113
  const processGroup = (rg) => ({
@@ -1130,7 +1134,6 @@ function transformQuery(query, options = {}) {
1130
1134
  ...omitPath ? null : { path: [] }
1131
1135
  });
1132
1136
  }
1133
-
1134
1137
  //#endregion
1135
1138
  //#region src/utils/isRuleOrGroupValid.ts
1136
1139
  /**
@@ -1154,7 +1157,6 @@ const isRuleOrGroupValid = (rg, validationResult, validator) => {
1154
1157
  }
1155
1158
  return true;
1156
1159
  };
1157
-
1158
1160
  //#endregion
1159
1161
  //#region src/utils/getParseNumberMethod.ts
1160
1162
  const getParseNumberMethod = ({ parseNumbers, inputType }) => {
@@ -1165,7 +1167,6 @@ const getParseNumberMethod = ({ parseNumbers, inputType }) => {
1165
1167
  }
1166
1168
  return parseNumbers ? "strict" : false;
1167
1169
  };
1168
-
1169
1170
  //#endregion
1170
1171
  //#region src/utils/formatQuery/utils.ts
1171
1172
  /**
@@ -1247,7 +1248,8 @@ const jsonLogicAdditionalOperators = {
1247
1248
  endsWith: (a, b) => typeof a === "string" && a.endsWith(b)
1248
1249
  };
1249
1250
  /**
1250
- * Converts all `string`-type `value` properties of a query object into `number` where appropriate.
1251
+ * Returns a new query object with all `string`-type `value` properties converted
1252
+ * to `number` where appropriate.
1251
1253
  *
1252
1254
  * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`.
1253
1255
  *
@@ -1416,7 +1418,6 @@ const bigIntJsonStringifyReplacer = (_key, value) => typeof value === "bigint" ?
1416
1418
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
1417
1419
  */
1418
1420
  const bigIntJsonParseReviver = (_key, value) => isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === "string" ? BigInt(value.$bigint) : value;
1419
-
1420
1421
  //#endregion
1421
1422
  //#region src/utils/formatQuery/defaultRuleGroupProcessorCEL.ts
1422
1423
  /**
@@ -1472,7 +1473,6 @@ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
1472
1473
  };
1473
1474
  return processRuleGroup(ruleGroup, true);
1474
1475
  };
1475
-
1476
1476
  //#endregion
1477
1477
  //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts
1478
1478
  const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot");
@@ -1553,7 +1553,6 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
1553
1553
  }
1554
1554
  return "";
1555
1555
  };
1556
-
1557
1556
  //#endregion
1558
1557
  //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDBQuery.ts
1559
1558
  /**
@@ -1591,11 +1590,11 @@ const defaultRuleGroupProcessorMongoDBQuery = (ruleGroup, options, meta) => {
1591
1590
  fieldData
1592
1591
  }, meta);
1593
1592
  }).filter(Boolean);
1594
- return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
1593
+ const result = expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
1594
+ return rg.not ? { $not: result } : result;
1595
1595
  };
1596
1596
  return processRuleGroup(convertFromIC(ruleGroup), true);
1597
1597
  };
1598
-
1599
1598
  //#endregion
1600
1599
  //#region src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts
1601
1600
  const processNumber$1 = (value, fallback, parseNumbers = false) => shouldRenderAsNumber(value, parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: "strict" })) : fallback;
@@ -1724,7 +1723,6 @@ const defaultRuleProcessorMongoDBQuery = (rule, options = {}) => {
1724
1723
  }
1725
1724
  return "";
1726
1725
  };
1727
-
1728
1726
  //#endregion
1729
1727
  //#region src/utils/formatQuery/defaultRuleProcessorMongoDB.ts
1730
1728
  /**
@@ -1738,7 +1736,6 @@ const defaultRuleProcessorMongoDB = (rule, options) => {
1738
1736
  const queryObj = defaultRuleProcessorMongoDBQuery(rule, options);
1739
1737
  return queryObj ? JSON.stringify(queryObj) : "";
1740
1738
  };
1741
-
1742
1739
  //#endregion
1743
1740
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSpEL.ts
1744
1741
  /**
@@ -1794,11 +1791,10 @@ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
1794
1791
  };
1795
1792
  return processRuleGroup(ruleGroup, true);
1796
1793
  };
1797
-
1798
1794
  //#endregion
1799
1795
  //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts
1800
1796
  const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot");
1801
- const wrapInNegation = (clause, negate$1) => negate$1 ? `!(${clause})` : clause;
1797
+ const wrapInNegation = (clause, negate) => negate ? `!(${clause})` : clause;
1802
1798
  const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
1803
1799
  /**
1804
1800
  * Default rule processor used by {@link formatQuery} for "spel" format.
@@ -1851,9 +1847,9 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1851
1847
  case "notnull": return `${field} != null`;
1852
1848
  case "in":
1853
1849
  case "notin": {
1854
- const negate$1 = shouldNegate$1(operatorTL) ? "!" : "";
1850
+ const negate = shouldNegate$1(operatorTL) ? "!" : "";
1855
1851
  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 ")})` : "";
1852
+ return valueAsArray.length > 0 ? `${negate}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
1857
1853
  }
1858
1854
  case "between":
1859
1855
  case "notbetween": {
@@ -1876,7 +1872,6 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1876
1872
  }
1877
1873
  return "";
1878
1874
  };
1879
-
1880
1875
  //#endregion
1881
1876
  //#region src/utils/formatQuery/defaultValueProcessorByRule.ts
1882
1877
  const escapeStringValueQuotes$1 = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
@@ -1932,7 +1927,6 @@ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQ
1932
1927
  if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
1933
1928
  return valueIsField ? wrapFieldName(value) : shouldRenderAsNumber(value, parseNumbers) ? `${trimIfString(value)}` : `${wrapAndEscape(value)}`;
1934
1929
  };
1935
-
1936
1930
  //#endregion
1937
1931
  //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
1938
1932
  /**
@@ -2029,7 +2023,6 @@ const defaultRuleProcessorDrizzle = (rule, _options) => {
2029
2023
  default: return;
2030
2024
  }
2031
2025
  };
2032
-
2033
2026
  //#endregion
2034
2027
  //#region src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts
2035
2028
  /**
@@ -2073,7 +2066,6 @@ const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns
2073
2066
  };
2074
2067
  return processRuleGroup(convertFromIC(ruleGroup), true);
2075
2068
  };
2076
-
2077
2069
  //#endregion
2078
2070
  //#region src/utils/formatQuery/defaultRuleGroupProcessorElasticSearch.ts
2079
2071
  /**
@@ -2102,7 +2094,6 @@ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
2102
2094
  const processedRuleGroup = processRuleGroup(convertFromIC(ruleGroup));
2103
2095
  return processedRuleGroup === false ? {} : processedRuleGroup;
2104
2096
  };
2105
-
2106
2097
  //#endregion
2107
2098
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts
2108
2099
  /**
@@ -2158,7 +2149,6 @@ const defaultRuleGroupProcessorJSONata = (ruleGroup, options) => {
2158
2149
  };
2159
2150
  return processRuleGroup(ruleGroup, true);
2160
2151
  };
2161
-
2162
2152
  //#endregion
2163
2153
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJsonLogic.ts
2164
2154
  /**
@@ -2188,7 +2178,6 @@ const defaultRuleGroupProcessorJsonLogic = (ruleGroup, options) => {
2188
2178
  };
2189
2179
  return processRuleGroup(query, true);
2190
2180
  };
2191
-
2192
2181
  //#endregion
2193
2182
  //#region src/utils/formatQuery/defaultRuleGroupProcessorLDAP.ts
2194
2183
  /**
@@ -2219,7 +2208,6 @@ const defaultRuleGroupProcessorLDAP = (ruleGroup, options) => {
2219
2208
  };
2220
2209
  return processRuleGroup(convertFromIC(ruleGroup), true);
2221
2210
  };
2222
-
2223
2211
  //#endregion
2224
2212
  //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDB.ts
2225
2213
  const isBracketed = (str) => str.startsWith("{") && str.endsWith("}");
@@ -2254,12 +2242,12 @@ const defaultRuleGroupProcessorMongoDB = (ruleGroup, options, meta) => {
2254
2242
  fieldData
2255
2243
  }, meta);
2256
2244
  }).filter(Boolean);
2257
- return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
2245
+ const result = expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
2246
+ return rg.not ? `"$not":${isBracketed(result) ? result : `{${result}}`}` : result;
2258
2247
  };
2259
2248
  const processedQuery = processRuleGroup(convertFromIC(ruleGroup), true);
2260
2249
  return isBracketed(processedQuery) ? processedQuery : `{${processedQuery}}`;
2261
2250
  };
2262
-
2263
2251
  //#endregion
2264
2252
  //#region src/utils/formatQuery/defaultRuleGroupProcessorNL.ts
2265
2253
  /**
@@ -2323,7 +2311,6 @@ const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
2323
2311
  };
2324
2312
  return processRuleGroup(ruleGroup, true);
2325
2313
  };
2326
-
2327
2314
  //#endregion
2328
2315
  //#region src/utils/formatQuery/defaultRuleGroupProcessorParameterized.ts
2329
2316
  /**
@@ -2412,7 +2399,6 @@ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
2412
2399
  params: paramsNamed
2413
2400
  };
2414
2401
  };
2415
-
2416
2402
  //#endregion
2417
2403
  //#region src/utils/formatQuery/defaultRuleGroupProcessorPrisma.ts
2418
2404
  /**
@@ -2455,7 +2441,6 @@ const defaultRuleGroupProcessorPrisma = (ruleGroup, options) => {
2455
2441
  const result = processRuleGroup(convertFromIC(ruleGroup), true);
2456
2442
  return ruleGroup.not ? { NOT: result } : result;
2457
2443
  };
2458
-
2459
2444
  //#endregion
2460
2445
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSequelize.ts
2461
2446
  /**
@@ -2496,7 +2481,6 @@ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
2496
2481
  };
2497
2482
  return processRuleGroup(convertFromIC(ruleGroup), true);
2498
2483
  };
2499
-
2500
2484
  //#endregion
2501
2485
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts
2502
2486
  /**
@@ -2553,7 +2537,6 @@ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
2553
2537
  };
2554
2538
  return processRuleGroup(ruleGroup, true);
2555
2539
  };
2556
-
2557
2540
  //#endregion
2558
2541
  //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
2559
2542
  const rangeOperatorMap = {
@@ -2705,12 +2688,11 @@ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
2705
2688
  }
2706
2689
  return false;
2707
2690
  };
2708
-
2709
2691
  //#endregion
2710
2692
  //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
2711
2693
  const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
2712
2694
  const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
2713
- const negate = (clause, negate$1) => negate$1 ? `$not(${clause})` : clause;
2695
+ const negate = (clause, neg) => neg ? `$not(${clause})` : clause;
2714
2696
  const escapeStringRegex = (s) => `${s}`.replaceAll(/[/$()*+.?[\\\]^{|}]/g, String.raw`\$&`).replaceAll("-", String.raw`\x2d`);
2715
2697
  /**
2716
2698
  * Default rule processor used by {@link formatQuery} for "jsonata" format.
@@ -2792,7 +2774,6 @@ const defaultRuleProcessorJSONata = (rule, options = {}) => {
2792
2774
  }
2793
2775
  return "";
2794
2776
  };
2795
-
2796
2777
  //#endregion
2797
2778
  //#region src/utils/formatQuery/defaultRuleProcessorJsonLogic.ts
2798
2779
  const convertOperator = (op) => op.replace(/^(=)$/, "$1=").replace(/^notnull$/i, "!=").replace(/^null$/i, "==");
@@ -2887,10 +2868,9 @@ const defaultRuleProcessorJsonLogic = (rule, options = {}) => {
2887
2868
  }
2888
2869
  return false;
2889
2870
  };
2890
-
2891
2871
  //#endregion
2892
2872
  //#region src/utils/formatQuery/defaultRuleProcessorLDAP.ts
2893
- const negateIf = (clause, negate$1) => negate$1 ? `(!${clause})` : `${clause}`;
2873
+ const negateIf = (clause, negate) => negate ? `(!${clause})` : `${clause}`;
2894
2874
  const ldapEscape = (s) => `${trimIfString(s)}`.replaceAll(/[()&|=<>~*\\/]/g, (m) => `\\${m.codePointAt(0).toString(16)}`);
2895
2875
  /**
2896
2876
  * Default rule processor used by {@link formatQuery} for "ldap" format.
@@ -2939,7 +2919,6 @@ const defaultRuleProcessorLDAP = (rule, options = {}) => {
2939
2919
  // istanbul ignore next
2940
2920
  return "";
2941
2921
  };
2942
-
2943
2922
  //#endregion
2944
2923
  //#region src/utils/formatQuery/defaultValueProcessorNL.ts
2945
2924
  const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
@@ -2989,7 +2968,6 @@ const defaultValueProcessorNL = (rule, opts = {}) => {
2989
2968
  if (typeof rule.value === "boolean") return rule.value ? trueTL : falseTL;
2990
2969
  return valueIsField ? wrapFieldName(getOption(fields ?? [], rule.value)?.label ?? rule.value) : shouldRenderAsNumber(rule.value, parseNumbers) ? `${trimIfString(rule.value)}` : `${wrapAndEscape(rule.value)}`;
2991
2970
  };
2992
-
2993
2971
  //#endregion
2994
2972
  //#region src/utils/formatQuery/defaultRuleProcessorNL.ts
2995
2973
  /**
@@ -3099,7 +3077,6 @@ const defaultRuleProcessorNL = (rule, opts) => {
3099
3077
  };
3100
3078
  return normalizeConstituentWordOrder(wordOrder).map((term) => `${wordOrderMap[term]}`).join(" ").trim();
3101
3079
  };
3102
-
3103
3080
  //#endregion
3104
3081
  //#region src/utils/formatQuery/defaultRuleProcessorSQL.ts
3105
3082
  /**
@@ -3154,7 +3131,6 @@ const defaultRuleProcessorSQL = (rule, opts = {}) => {
3154
3131
  if ((operatorLowerCase === "in" || operatorLowerCase === "not in" || operatorLowerCase === "between" || operatorLowerCase === "not between") && !value) return "";
3155
3132
  return `${ruleField} ${operator} ${value}`.trim();
3156
3133
  };
3157
-
3158
3134
  //#endregion
3159
3135
  //#region src/utils/formatQuery/defaultRuleProcessorParameterized.ts
3160
3136
  /**
@@ -3259,7 +3235,6 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
3259
3235
  }
3260
3236
  return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${parameterized ? numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?" : `${paramPrefix}${paramName}`}`.trim());
3261
3237
  };
3262
-
3263
3238
  //#endregion
3264
3239
  //#region src/utils/formatQuery/defaultRuleProcessorPrisma.ts
3265
3240
  const processNumber = (value, fallback, parseNumbers) => shouldRenderAsNumber(value, !!parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: !!parseNumbers })) : fallback;
@@ -3321,7 +3296,6 @@ const defaultRuleProcessorPrisma = (rule, options = {}) => {
3321
3296
  }
3322
3297
  return "";
3323
3298
  };
3324
-
3325
3299
  //#endregion
3326
3300
  //#region src/utils/formatQuery/defaultRuleProcessorSequelize.ts
3327
3301
  /**
@@ -3388,7 +3362,6 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
3388
3362
  }
3389
3363
  }
3390
3364
  };
3391
-
3392
3365
  //#endregion
3393
3366
  //#region src/utils/formatQuery/formatQuery.ts
3394
3367
  /**
@@ -3477,8 +3450,8 @@ const defaultFormatQueryOptions = {
3477
3450
  paramsKeepPrefix: false,
3478
3451
  numberedParams: false,
3479
3452
  preserveValueOrder: false,
3480
- placeholderFieldName: defaultPlaceholderFieldName,
3481
- placeholderOperatorName: defaultPlaceholderOperatorName,
3453
+ placeholderFieldName: "~",
3454
+ placeholderOperatorName: "~",
3482
3455
  quoteValuesWith: "'",
3483
3456
  concatOperator: "||",
3484
3457
  preset: "ansi",
@@ -3583,7 +3556,7 @@ function formatQuery(ruleGroup, optionParam = {}) {
3583
3556
  switch (format) {
3584
3557
  case "json":
3585
3558
  case "json_without_ids": {
3586
- const rg = parseNumbers ? (0, immer.produce)(ruleGroup, (g) => numerifyValues(g, finalOptions)) : ruleGroup;
3559
+ const rg = parseNumbers ? numerifyValues(ruleGroup, finalOptions) : ruleGroup;
3587
3560
  if (format === "json_without_ids") return JSON.stringify(rg, (key, value) => key === "id" || key === "path" ? void 0 : bigIntJsonStringifyReplacer(key, value));
3588
3561
  return JSON.stringify(rg, bigIntJsonStringifyReplacer, 2);
3589
3562
  }
@@ -3605,7 +3578,6 @@ function formatQuery(ruleGroup, optionParam = {}) {
3605
3578
  default: return "";
3606
3579
  }
3607
3580
  }
3608
-
3609
3581
  //#endregion
3610
3582
  //#region src/utils/formatQuery/index.ts
3611
3583
  const generateValueProcessor = (vpbr) => (field, operator, value, valueSource) => vpbr({
@@ -3656,7 +3628,6 @@ const defaultValueProcessorMongoDBByRule = defaultRuleProcessorMongoDB;
3656
3628
  * @group Export
3657
3629
  */
3658
3630
  const defaultValueProcessorSpELByRule = defaultRuleProcessorSpEL;
3659
-
3660
3631
  //#endregion
3661
3632
  //#region src/utils/pathUtils.ts
3662
3633
  /**
@@ -3715,7 +3686,7 @@ const pathsAreEqual = (path1, path2) => path1.length === path2.length && path1.e
3715
3686
  * Determines if the first path is an ancestor of the second path. The first path must
3716
3687
  * be shorter and exactly match the second path up through the length of the first path.
3717
3688
  */
3718
- const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && (/* @__PURE__ */ new RegExp(`^${maybeAncestor.join("-")}`)).test(path.join("-"));
3689
+ const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && new RegExp(`^${maybeAncestor.join("-")}`).test(path.join("-"));
3719
3690
  /**
3720
3691
  * Finds the deepest/longest path that two paths have in common.
3721
3692
  */
@@ -3748,11 +3719,9 @@ const pathIsDisabled = (path, query) => {
3748
3719
  }
3749
3720
  return disabled;
3750
3721
  };
3751
-
3752
3722
  //#endregion
3753
3723
  //#region src/utils/generateAccessibleDescription.ts
3754
3724
  const generateAccessibleDescription = (params) => pathsAreEqual([], params.path) ? `Query builder` : `Rule group at path ${params.path.join("-")}`;
3755
-
3756
3725
  //#endregion
3757
3726
  //#region src/utils/generateID.ts
3758
3727
  const cryptoModule = globalThis.crypto;
@@ -3787,7 +3756,6 @@ if (cryptoModule) {
3787
3756
  };
3788
3757
  }
3789
3758
  }
3790
-
3791
3759
  //#endregion
3792
3760
  //#region src/utils/getMatchModesUtil.ts
3793
3761
  const dummyFD$1 = {
@@ -3815,7 +3783,6 @@ const getMatchModesUtil = (fieldData, getMatchModes) => {
3815
3783
  label: mm
3816
3784
  }) ?? [];
3817
3785
  };
3818
-
3819
3786
  //#endregion
3820
3787
  //#region src/utils/getValidationClassNames.ts
3821
3788
  /**
@@ -3826,7 +3793,6 @@ const getValidationClassNames = (validationResult) => {
3826
3793
  const valid = typeof validationResult === "boolean" ? validationResult : typeof validationResult === "object" && validationResult !== null ? validationResult.valid : null;
3827
3794
  return typeof valid === "boolean" ? valid ? standardClassnames.valid : standardClassnames.invalid : "";
3828
3795
  };
3829
-
3830
3796
  //#endregion
3831
3797
  //#region src/utils/getValueSourcesUtil.ts
3832
3798
  const defaultValueSourcesArray = [{
@@ -3859,27 +3825,34 @@ const getValueSourcesUtil = (fieldData, operator, getValueSources) => {
3859
3825
  label: vs
3860
3826
  });
3861
3827
  };
3862
-
3863
3828
  //#endregion
3864
3829
  //#region src/utils/mergeAnyTranslations.ts
3865
3830
  /**
3866
3831
  * Merges any number of partial translations into a single definition.
3867
3832
  */
3868
- const mergeAnyTranslations = (base, ...otherTranslations) => (0, immer.produce)(base, (draft) => {
3833
+ const mergeAnyTranslations = (base, ...otherTranslations) => {
3834
+ const result = { ...base };
3869
3835
  for (const translations of otherTranslations)
3870
3836
  // 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
- });
3837
+ if (translations) for (const key of objectKeys(translations)) {
3838
+ if (isUnsafeKey(key)) continue;
3839
+ if (result[key]) result[key] = {
3840
+ ...result[key],
3841
+ ...translations[key]
3842
+ };
3843
+ else result[key] = { ...translations[key] };
3844
+ }
3845
+ return result;
3846
+ };
3874
3847
  const mergeAnyTranslation = (el, keyPropContextMap, defaults) => {
3875
- const finalKeys = objectEntries(keyPropContextMap).map(([key, [pT, cT]]) => [key, pT ?? cT ?? defaults?.[el]?.[key]]).filter((k) => !!k[1]);
3848
+ if (isUnsafeKey(el)) return void 0;
3849
+ const finalKeys = objectEntries(keyPropContextMap).map(([key, [pT, cT]]) => [key, pT ?? cT ?? defaults?.[el]?.[key]]).filter((k) => !isUnsafeKey(k[0]) && !!k[1]);
3876
3850
  if (finalKeys.length > 0 || defaults) {
3877
3851
  const defaultProperties = defaults?.[el] ?? {};
3878
3852
  const finalObject = Object.assign({}, defaultProperties, Object.fromEntries(finalKeys));
3879
3853
  return { [el]: finalObject };
3880
3854
  }
3881
3855
  };
3882
-
3883
3856
  //#endregion
3884
3857
  //#region src/utils/mergeClassnames.ts
3885
3858
  const joinClassnamesByName = (name, args) => clsx(args.map((c) => clsx(c?.[name])));
@@ -3929,7 +3902,6 @@ const mergeClassnames = (...args) => ({
3929
3902
  hasSubQuery: joinClassnamesByName("hasSubQuery", args),
3930
3903
  loading: joinClassnamesByName("loading", args)
3931
3904
  });
3932
-
3933
3905
  //#endregion
3934
3906
  //#region src/utils/preferProp.ts
3935
3907
  const preferPropDefaultTrue = (prop, context) => prop === false ? false : prop ? true : !(context === false);
@@ -3952,29 +3924,49 @@ const preferFlagProps = (props = {}, contextVals = {}, finalize) => objectEntrie
3952
3924
  acc[key] = preferProp(def, props[key], contextVals[key], !finalize);
3953
3925
  return acc;
3954
3926
  }, {});
3955
-
3956
3927
  //#endregion
3957
3928
  //#region src/utils/prepareQueryObjects.ts
3958
3929
  /**
3959
3930
  * Ensures that a rule is valid by adding an `id` property if it does not already exist.
3960
3931
  */
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
- });
3932
+ const prepareRule = (rule, { idGenerator = generateID } = {}) => {
3933
+ const needsId = !rule.id;
3934
+ const hasMatchMode = processMatchMode(rule);
3935
+ if (!needsId && !hasMatchMode) return rule;
3936
+ return {
3937
+ ...rule,
3938
+ ...needsId && { id: idGenerator() },
3939
+ ...hasMatchMode && { value: prepareRuleGroup(rule.value, { idGenerator }) }
3940
+ };
3941
+ };
3965
3942
  /**
3966
3943
  * Ensures that a rule group is valid by recursively adding an `id` property to the group itself
3967
3944
  * and all its rules and subgroups where one does not already exist.
3968
3945
  */
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
- });
3946
+ const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => {
3947
+ const needsId = !queryObject.id;
3948
+ let rulesChanged = false;
3949
+ const newRules = [];
3950
+ for (let i = 0; i < queryObject.rules.length; i++) {
3951
+ const r = queryObject.rules[i];
3952
+ if (typeof r === "string") newRules.push(r);
3953
+ else {
3954
+ const prepared = isRuleGroup(r) ? prepareRuleGroup(r, { idGenerator }) : prepareRule(r, { idGenerator });
3955
+ newRules.push(prepared);
3956
+ if (prepared !== r) rulesChanged = true;
3957
+ }
3958
+ }
3959
+ if (!needsId && !rulesChanged) return queryObject;
3960
+ return {
3961
+ ...queryObject,
3962
+ ...needsId && { id: idGenerator() },
3963
+ rules: newRules
3964
+ };
3965
+ };
3973
3966
  /**
3974
3967
  * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.
3975
3968
  */
3976
3969
  const prepareRuleOrGroup = (rg, { idGenerator = generateID } = {}) => isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });
3977
-
3978
3970
  //#endregion
3979
3971
  //#region src/utils/regenerateIDs.ts
3980
3972
  /**
@@ -4001,44 +3993,65 @@ const regenerateIDs = (subject, { idGenerator = generateID } = {}) => {
4001
3993
  if (Array.isArray(newGroup.rules)) newGroup.rules = subject.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? regenerateIDs(r, { idGenerator }) : regenerateID(r, { idGenerator }));
4002
3994
  return newGroup;
4003
3995
  };
4004
-
4005
3996
  //#endregion
4006
3997
  //#region src/utils/queryTools.ts
4007
3998
  /**
4008
- * Adds a rule or group to a query.
4009
- * @returns The new query with the rule or group added.
3999
+ * Adds a rule or group to a query without mutating the original query.
4000
+ *
4001
+ * @returns A new query with the rule or group added.
4002
+ *
4003
+ * @group Query Tools
4004
+ */
4005
+ const add = (query, ruleOrGroup, parentPathOrID, options = {}) => (0, immer.produce)(query, (q) => addInPlace(q, ruleOrGroup, parentPathOrID, options));
4006
+ /**
4007
+ * Adds a rule or group to a query in place.
4008
+ *
4009
+ * @returns The query (mutated in place) with the rule or group added.
4010
4010
  *
4011
4011
  * @group Query Tools
4012
4012
  */
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;
4013
+ const addInPlace = (query, ruleOrGroup, parentPathOrID, options = {}) => {
4014
+ const { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = options;
4015
+ const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, query) : findID(parentPathOrID, query);
4016
+ if (!parent || !isRuleGroup(parent)) return query;
4016
4017
  if (isRuleGroupTypeIC(parent) && parent.rules.length > 0) {
4017
4018
  const prevCombinator = parent.rules.at(-2);
4018
4019
  parent.rules.push(combinatorPreceding ?? (typeof prevCombinator === "string" ? prevCombinator : getFirstOption(combinators)));
4019
4020
  }
4020
4021
  parent.rules.push(prepareRuleOrGroup(ruleOrGroup, { idGenerator }));
4021
- });
4022
+ return query;
4023
+ };
4024
+ /**
4025
+ * Updates a property of a rule or group within a query without mutating the original query.
4026
+ *
4027
+ * @returns A new query with the rule or group property updated.
4028
+ *
4029
+ * @group Query Tools
4030
+ */
4031
+ const update = (query, prop, value, pathOrID, options = {}) => (0, immer.produce)(query, (q) => updateInPlace(q, prop, value, pathOrID, options));
4022
4032
  /**
4023
- * Updates a property of a rule or group within a query.
4024
- * @returns The new query with the rule or group property updated.
4033
+ * Updates a property of a rule or group within a query in place.
4034
+ *
4035
+ * @returns The query (mutated in place) with the rule or group property updated.
4025
4036
  *
4026
4037
  * @group Query Tools
4027
4038
  */
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;
4039
+ const updateInPlace = (query, prop, value, pathOrID, options = {}) => {
4040
+ const { resetOnFieldChange: _resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = options;
4041
+ let resetOnFieldChange = _resetOnFieldChange;
4042
+ const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
4043
+ if (!path) return query;
4044
+ if (prop === "combinator" && !isRuleGroupType(query)) {
4045
+ const parentRules = findPath(getParentPath(path), query).rules;
4033
4046
  if (path.at(-1) % 2 === 1) parentRules[path.at(-1)] = value;
4034
- return;
4047
+ return query;
4035
4048
  }
4036
- const ruleOrGroup = findPath(path, draft);
4037
- if (!ruleOrGroup) return;
4049
+ const ruleOrGroup = findPath(path, query);
4050
+ if (!ruleOrGroup) return query;
4038
4051
  const isGroup = isRuleGroup(ruleOrGroup);
4039
- if (ruleOrGroup[prop] === value) return;
4052
+ if (ruleOrGroup[prop] === value) return query;
4040
4053
  if (prop !== "valueSource") ruleOrGroup[prop] = value;
4041
- if (isGroup) return;
4054
+ if (isGroup) return query;
4042
4055
  let resetValueSource = false;
4043
4056
  let resetValue = false;
4044
4057
  if (prop === "field") {
@@ -4073,25 +4086,33 @@ const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, reset
4073
4086
  ruleOrGroup.valueSource = resetValueSource ? defaultValueSource : value;
4074
4087
  }
4075
4088
  if (resetValue) ruleOrGroup.value = getRuleDefaultValue(ruleOrGroup);
4076
- });
4089
+ return query;
4090
+ };
4077
4091
  /**
4078
- * Removes a rule or group from a query.
4079
- * @returns The new query with the rule or group removed.
4092
+ * Removes a rule or group from a query without mutating the original query.
4093
+ *
4094
+ * @returns A new query with the rule or group removed.
4080
4095
  *
4081
4096
  * @group Query Tools
4082
4097
  */
4083
- const remove = (query, pathOrID) => {
4098
+ const remove = (query, pathOrID) => (0, immer.produce)(query, (q) => removeInPlace(q, pathOrID));
4099
+ /**
4100
+ * Removes a rule or group from a query in place.
4101
+ *
4102
+ * @returns The query (mutated in place) with the rule or group removed.
4103
+ *
4104
+ * @group Query Tools
4105
+ */
4106
+ const removeInPlace = (query, pathOrID) => {
4084
4107
  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
- });
4108
+ if (!path || path.length === 0 || !isRuleGroupType(query) && !findPath(path, query)) return query;
4109
+ const index = path.at(-1);
4110
+ const parent = findPath(getParentPath(path), query);
4111
+ if (parent && isRuleGroup(parent)) if (!isRuleGroupType(parent) && parent.rules.length > 1) {
4112
+ const idxStartDelete = index === 0 ? 0 : index - 1;
4113
+ parent.rules.splice(idxStartDelete, 2);
4114
+ } else parent.rules.splice(index, 1);
4115
+ return query;
4095
4116
  };
4096
4117
  const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4097
4118
  if (Array.isArray(newPathOrShiftDirection)) return newPathOrShiftDirection;
@@ -4118,59 +4139,79 @@ const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4118
4139
  return currentPath;
4119
4140
  };
4120
4141
  /**
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.
4142
+ * Moves a rule or group from one path to another without mutating the original query.
4143
+ * In the options parameter, pass `{ clone: true }` to copy instead of move.
4144
+ *
4145
+ * @returns A new query with the rule or group moved or cloned.
4146
+ *
4147
+ * @group Query Tools
4148
+ */
4149
+ const move = (query, oldPathOrID, newPath, options = {}) => (0, immer.produce)(query, (q) => moveInPlace(q, oldPathOrID, newPath, options));
4150
+ /**
4151
+ * Moves a rule or group from one path to another in place.
4152
+ * In the options parameter, pass `{ clone: true }` to copy instead of move.
4153
+ *
4154
+ * @returns The query (mutated in place) with the rule or group moved or cloned.
4124
4155
  *
4125
4156
  * @group Query Tools
4126
4157
  */
4127
- const move = (query, oldPathOrID, newPath, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
4158
+ const moveInPlace = (query, oldPathOrID, newPath, options = {}) => {
4159
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
4128
4160
  const oldPath = Array.isArray(oldPathOrID) ? oldPathOrID : getPathOfID(oldPathOrID, query);
4129
4161
  if (!oldPath) return query;
4130
4162
  const nextPath = getNextPath(query, oldPath, newPath);
4131
4163
  if (oldPath.length === 0 || pathsAreEqual(oldPath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
4132
4164
  const ruleOrGroupOriginal = findPath(oldPath, query);
4133
4165
  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
- });
4166
+ const ruleOrGroup = clone ? regenerateIDs((0, immer.isDraft)(ruleOrGroupOriginal) ? (0, immer.current)(ruleOrGroupOriginal) : ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
4167
+ const independentCombinators = isRuleGroupTypeIC(query);
4168
+ const parentOfRuleToRemove = findPath(getParentPath(oldPath), query);
4169
+ const ruleToRemoveIndex = oldPath.at(-1);
4170
+ const oldPrevCombinator = independentCombinators && ruleToRemoveIndex > 0 ? parentOfRuleToRemove.rules[ruleToRemoveIndex - 1] : null;
4171
+ const oldNextCombinator = independentCombinators && ruleToRemoveIndex < parentOfRuleToRemove.rules.length - 1 ? parentOfRuleToRemove.rules[ruleToRemoveIndex + 1] : null;
4172
+ if (!clone) {
4173
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4174
+ const deleteLength = independentCombinators ? 2 : 1;
4175
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4176
+ }
4177
+ const newNewPath = [...nextPath];
4178
+ const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);
4179
+ if (!clone && oldPath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4180
+ const parentToInsertInto = findPath(getParentPath(newNewPath), query);
4181
+ const newIndex = newNewPath.at(-1);
4182
+ /**
4183
+ * This function 1) glosses over the need for type assertions to splice directly
4184
+ * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
4185
+ */
4186
+ const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(newIndex, 0, ...args);
4187
+ if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(ruleOrGroup);
4188
+ else if (newIndex === 0) if (ruleToRemoveIndex === 0 && oldNextCombinator) insertRuleOrGroup(ruleOrGroup, oldNextCombinator);
4189
+ else insertRuleOrGroup(ruleOrGroup, parentToInsertInto.rules[1] ?? oldPrevCombinator ?? getFirstOption(combinators));
4190
+ else if (oldPrevCombinator) insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);
4191
+ else insertRuleOrGroup(parentToInsertInto.rules[newIndex - 2] ?? oldNextCombinator ?? getFirstOption(combinators), ruleOrGroup);
4192
+ return query;
4162
4193
  };
4163
4194
  /**
4164
- * Inserts a rule or group into a query.
4165
- * @returns The new query with the rule or group inserted.
4195
+ * Inserts a rule or group into a query without mutating the original query.
4196
+ *
4197
+ * @returns A new query with the rule or group inserted.
4166
4198
  *
4167
4199
  * @group Query Tools
4168
4200
  */
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;
4201
+ const insert = (query, ruleOrGroup, path, options = {}) => (0, immer.produce)(query, (q) => insertInPlace(q, ruleOrGroup, path, options));
4202
+ /**
4203
+ * Inserts a rule or group into a query in place.
4204
+ *
4205
+ * @returns The query (mutated in place) with the rule or group inserted.
4206
+ *
4207
+ * @group Query Tools
4208
+ */
4209
+ const insertInPlace = (query, ruleOrGroup, path, options = {}) => {
4210
+ const { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = options;
4211
+ const parentToInsertInto = findPath(getParentPath(path), query);
4212
+ if (!parentToInsertInto || !isRuleGroup(parentToInsertInto)) return query;
4172
4213
  const rorg = regenerateIDs(ruleOrGroup, { idGenerator });
4173
- const independentCombinators = isRuleGroupTypeIC(draft);
4214
+ const independentCombinators = isRuleGroupTypeIC(query);
4174
4215
  const newIndex = path.at(-1);
4175
4216
  /**
4176
4217
  * This function 1) glosses over the need for type assertions to splice directly
@@ -4186,17 +4227,29 @@ const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, co
4186
4227
  if (combinatorPreceding) insertRuleOrGroup(normalizedNewIndex, combinatorPreceding, rorg);
4187
4228
  else insertRuleOrGroup(normalizedNewIndex, parentToInsertInto.rules[normalizedNewIndex - 2] ?? combinatorSucceeding ?? getFirstOption(combinators), rorg);
4188
4229
  }
4189
- });
4230
+ return query;
4231
+ };
4190
4232
  /**
4191
4233
  * 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.
4234
+ * objects at the target path and the source path without mutating the original query.
4235
+ * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.
4194
4236
  *
4195
- * @returns The new query with the rules or groups grouped.
4237
+ * @returns A new query with the rules or groups grouped.
4196
4238
  *
4197
4239
  * @group Query Tools
4198
4240
  */
4199
- const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
4241
+ const group = (query, sourcePathOrID, targetPathOrID, options = {}) => (0, immer.produce)(query, (q) => groupInPlace(q, sourcePathOrID, targetPathOrID, options));
4242
+ /**
4243
+ * Creates a new group at a target path with its `rules` array containing the current
4244
+ * objects at the target path and the source path in place.
4245
+ * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.
4246
+ *
4247
+ * @returns The query (mutated in place) with the rules or groups grouped.
4248
+ *
4249
+ * @group Query Tools
4250
+ */
4251
+ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
4252
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
4200
4253
  const sourcePath = Array.isArray(sourcePathOrID) ? sourcePathOrID : getPathOfID(sourcePathOrID, query);
4201
4254
  const targetPath = Array.isArray(targetPathOrID) ? targetPathOrID : getPathOfID(targetPathOrID, query);
4202
4255
  if (!sourcePath || !targetPath) return query;
@@ -4205,36 +4258,35 @@ const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinato
4205
4258
  const sourceRuleOrGroupOriginal = findPath(sourcePath, query);
4206
4259
  const targetRuleOrGroup = findPath(targetPath, query);
4207
4260
  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
- });
4261
+ const sourceRuleOrGroup = clone ? regenerateIDs((0, immer.isDraft)(sourceRuleOrGroupOriginal) ? (0, immer.current)(sourceRuleOrGroupOriginal) : sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
4262
+ const independentCombinators = isRuleGroupTypeIC(query);
4263
+ const parentOfRuleToRemove = findPath(getParentPath(sourcePath), query);
4264
+ const ruleToRemoveIndex = sourcePath.at(-1);
4265
+ if (!clone) {
4266
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4267
+ const deleteLength = independentCombinators ? 2 : 1;
4268
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4269
+ }
4270
+ const newNewPath = [...nextPath];
4271
+ const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);
4272
+ if (!clone && sourcePath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4273
+ const parentOfTargetPath = findPath(getParentPath(newNewPath), query);
4274
+ const targetPathIndex = newNewPath.at(-1);
4275
+ parentOfTargetPath.rules.splice(targetPathIndex, 1, prepareRuleOrGroup(independentCombinators ? { rules: [
4276
+ targetRuleOrGroup,
4277
+ getFirstOption(combinators),
4278
+ sourceRuleOrGroup
4279
+ ] } : {
4280
+ combinator: getFirstOption(combinators),
4281
+ rules: [targetRuleOrGroup, sourceRuleOrGroup]
4282
+ }, { idGenerator }));
4283
+ return query;
4232
4284
  };
4233
-
4234
4285
  //#endregion
4235
4286
  exports.LogType = LogType;
4236
4287
  exports.TestID = TestID;
4237
4288
  exports.add = add;
4289
+ exports.addInPlace = addInPlace;
4238
4290
  exports.bigIntJsonParseReviver = bigIntJsonParseReviver;
4239
4291
  exports.bigIntJsonStringifyReplacer = bigIntJsonStringifyReplacer;
4240
4292
  exports.celCombinatorMap = celCombinatorMap;
@@ -4311,11 +4363,11 @@ exports.findPath = findPath;
4311
4363
  exports.formatQuery = formatQuery;
4312
4364
  exports.formatQueryOptionPresets = formatQueryOptionPresets;
4313
4365
  exports.generateAccessibleDescription = generateAccessibleDescription;
4314
- Object.defineProperty(exports, 'generateID', {
4315
- enumerable: true,
4316
- get: function () {
4317
- return generateID;
4318
- }
4366
+ Object.defineProperty(exports, "generateID", {
4367
+ enumerable: true,
4368
+ get: function() {
4369
+ return generateID;
4370
+ }
4319
4371
  });
4320
4372
  exports.getCommonAncestorPath = getCommonAncestorPath;
4321
4373
  exports.getFirstOption = getFirstOption;
@@ -4330,8 +4382,10 @@ exports.getQuotedFieldName = getQuotedFieldName;
4330
4382
  exports.getValidationClassNames = getValidationClassNames;
4331
4383
  exports.getValueSourcesUtil = getValueSourcesUtil;
4332
4384
  exports.group = group;
4385
+ exports.groupInPlace = groupInPlace;
4333
4386
  exports.groupInvalidReasons = groupInvalidReasons;
4334
4387
  exports.insert = insert;
4388
+ exports.insertInPlace = insertInPlace;
4335
4389
  exports.isAncestor = isAncestor;
4336
4390
  exports.isFlexibleOptionArray = isFlexibleOptionArray;
4337
4391
  exports.isFlexibleOptionGroupArray = isFlexibleOptionGroupArray;
@@ -4344,6 +4398,7 @@ exports.isRuleGroupType = isRuleGroupType;
4344
4398
  exports.isRuleGroupTypeIC = isRuleGroupTypeIC;
4345
4399
  exports.isRuleOrGroupValid = isRuleOrGroupValid;
4346
4400
  exports.isRuleType = isRuleType;
4401
+ exports.isUnsafeKey = isUnsafeKey;
4347
4402
  exports.isValidValue = isValidValue;
4348
4403
  exports.isValidationResult = isValidationResult;
4349
4404
  exports.isValueProcessorLegacy = isValueProcessorLegacy;
@@ -4357,6 +4412,7 @@ exports.mergeClassnames = mergeClassnames;
4357
4412
  exports.mongoDbFallback = mongoDbFallback;
4358
4413
  exports.mongoOperators = mongoOperators;
4359
4414
  exports.move = move;
4415
+ exports.moveInPlace = moveInPlace;
4360
4416
  exports.normalizeConstituentWordOrder = normalizeConstituentWordOrder;
4361
4417
  exports.nullFreeArray = nullFreeArray;
4362
4418
  exports.nullOrUndefinedOrEmpty = nullOrUndefinedOrEmpty;
@@ -4381,6 +4437,7 @@ exports.queryBuilderFlagDefaults = queryBuilderFlagDefaults;
4381
4437
  exports.regenerateID = regenerateID;
4382
4438
  exports.regenerateIDs = regenerateIDs;
4383
4439
  exports.remove = remove;
4440
+ exports.removeInPlace = removeInPlace;
4384
4441
  exports.rootPath = rootPath;
4385
4442
  exports.shouldRenderAsNumber = shouldRenderAsNumber;
4386
4443
  exports.splitBy = splitBy;
@@ -4398,4 +4455,6 @@ exports.uniqByName = uniqByName;
4398
4455
  exports.uniqOptGroups = uniqOptGroups;
4399
4456
  exports.uniqOptList = uniqOptList;
4400
4457
  exports.update = update;
4458
+ exports.updateInPlace = updateInPlace;
4459
+
4401
4460
  //# sourceMappingURL=react-querybuilder_core.cjs.development.js.map