@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,5 @@
1
- import { produce } from "immer";
2
1
  import { numericQuantity, numericRegex as numericRegex$1 } from "numeric-quantity";
3
-
2
+ import { current, isDraft, produce } from "immer";
4
3
  //#region src/defaults.ts
5
4
  /**
6
5
  * @group Defaults
@@ -15,7 +14,7 @@ const defaultPlaceholderLabel = "------";
15
14
  *
16
15
  * @group Defaults
17
16
  */
18
- const defaultPlaceholderFieldName = defaultPlaceholderName;
17
+ const defaultPlaceholderFieldName = "~";
19
18
  /**
20
19
  * Default `label` for placeholder option in the `fields` array.
21
20
  *
@@ -33,7 +32,7 @@ const defaultPlaceholderFieldGroupLabel = defaultPlaceholderLabel;
33
32
  *
34
33
  * @group Defaults
35
34
  */
36
- const defaultPlaceholderOperatorName = defaultPlaceholderName;
35
+ const defaultPlaceholderOperatorName = "~";
37
36
  /**
38
37
  * Default `label` for placeholder option in the `operators` array.
39
38
  *
@@ -51,7 +50,7 @@ const defaultPlaceholderOperatorGroupLabel = defaultPlaceholderLabel;
51
50
  *
52
51
  * @group Defaults
53
52
  */
54
- const defaultPlaceholderValueName = defaultPlaceholderName;
53
+ const defaultPlaceholderValueName = "~";
55
54
  /**
56
55
  * Default `label` for placeholder option in the `values` array.
57
56
  *
@@ -72,19 +71,19 @@ const defaultPlaceholderValueGroupLabel = defaultPlaceholderLabel;
72
71
  const defaultTranslations = {
73
72
  fields: {
74
73
  title: "Field",
75
- placeholderName: defaultPlaceholderFieldName,
74
+ placeholderName: "~",
76
75
  placeholderLabel: defaultPlaceholderFieldLabel,
77
76
  placeholderGroupLabel: defaultPlaceholderFieldGroupLabel
78
77
  },
79
78
  operators: {
80
79
  title: "Operator",
81
- placeholderName: defaultPlaceholderOperatorName,
80
+ placeholderName: "~",
82
81
  placeholderLabel: defaultPlaceholderOperatorLabel,
83
82
  placeholderGroupLabel: defaultPlaceholderOperatorGroupLabel
84
83
  },
85
84
  values: {
86
85
  title: "Values",
87
- placeholderName: defaultPlaceholderValueName,
86
+ placeholderName: "~",
88
87
  placeholderLabel: defaultPlaceholderValueLabel,
89
88
  placeholderGroupLabel: defaultPlaceholderValueGroupLabel
90
89
  },
@@ -562,7 +561,6 @@ const queryBuilderFlagDefaults = {
562
561
  showShiftActions: false,
563
562
  suppressStandardClassnames: false
564
563
  };
565
-
566
564
  //#endregion
567
565
  //#region src/utils/arrayUtils.ts
568
566
  /**
@@ -577,7 +575,7 @@ const queryBuilderFlagDefaults = {
577
575
  * // would return
578
576
  * ['this,,that', '', 'the other', '', '', ',']
579
577
  */
580
- const splitBy = (str, splitChar = defaultJoinChar) => typeof str === "string" ? str.split(`\\${splitChar}`).map((c) => c.split(splitChar)).reduce((prev, curr, idx) => {
578
+ const splitBy = (str, splitChar = ",") => typeof str === "string" ? str.split(`\\${splitChar}`).map((c) => c.split(splitChar)).reduce((prev, curr, idx) => {
581
579
  if (idx === 0) return curr;
582
580
  return [
583
581
  ...prev.slice(0, -1),
@@ -598,7 +596,7 @@ const splitBy = (str, splitChar = defaultJoinChar) => typeof str === "string" ?
598
596
  * // would return
599
597
  * 'this\\,\\,that, , the other, , , \\,'
600
598
  */
601
- const joinWith = (strArr, joinChar = defaultJoinChar) => strArr.map((str) => `${str ?? ""}`.replaceAll(joinChar[0], `\\${joinChar[0]}`)).join(joinChar);
599
+ const joinWith = (strArr, joinChar = ",") => strArr.map((str) => `${str ?? ""}`.replaceAll(joinChar[0], `\\${joinChar[0]}`)).join(joinChar);
602
600
  /**
603
601
  * Trims the value if it is a string. Otherwise returns the value as is.
604
602
  */
@@ -607,12 +605,11 @@ const trimIfString = (val) => typeof val === "string" ? val.trim() : val;
607
605
  * Splits a string by comma then trims each element. Arrays are returned as is except
608
606
  * any string elements are trimmed.
609
607
  */
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] : [];
608
+ 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
609
  /**
612
610
  * Determines if an array is free of `null`/`undefined`.
613
611
  */
614
612
  const nullFreeArray = (arr) => arr.every((el) => el === false || (el ?? false) !== false);
615
-
616
613
  //#endregion
617
614
  //#region src/utils/clsx.ts
618
615
  // istanbul ignore next
@@ -653,7 +650,6 @@ function clsx(...args) {
653
650
  }
654
651
  return str;
655
652
  }
656
-
657
653
  //#endregion
658
654
  //#region src/utils/misc.ts
659
655
  /**
@@ -674,7 +670,6 @@ const isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object
674
670
  * Simple helper to determine whether a value is null, undefined, or an empty string.
675
671
  */
676
672
  const nullOrUndefinedOrEmpty = (value) => value === null || value === void 0 || value === "";
677
-
678
673
  //#endregion
679
674
  //#region src/utils/isRuleGroup.ts
680
675
  /**
@@ -693,7 +688,6 @@ const isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "str
693
688
  * Determines if an object is a {@link RuleGroupTypeIC}.
694
689
  */
695
690
  const isRuleGroupTypeIC = (rg) => isRuleGroup(rg) && rg.combinator === void 0;
696
-
697
691
  //#endregion
698
692
  //#region src/utils/convertQuery.ts
699
693
  const combinatorLevels = [
@@ -705,20 +699,27 @@ const isSameString = (a, b) => lc(a) === b;
705
699
  const generateRuleGroupICWithConsistentCombinators = (rg, baseCombinatorLevel = 0) => {
706
700
  const baseCombinator = combinatorLevels[baseCombinatorLevel];
707
701
  if (!rg.rules.includes(baseCombinator)) return baseCombinatorLevel < combinatorLevels.length - 2 ? generateRuleGroupICWithConsistentCombinators(rg, baseCombinatorLevel + 1) : rg;
708
- return 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));
702
+ const newRules = [...rg.rules];
703
+ let cursor = 0;
704
+ while (cursor < newRules.length - 2) {
705
+ if (isSameString(newRules[cursor + 1], baseCombinator)) {
706
+ cursor += 2;
707
+ continue;
720
708
  }
721
- });
709
+ let nextBaseCombinatorIndex = -1;
710
+ for (let i = cursor + 2; i < newRules.length; i++) if (typeof newRules[i] === "string" && lc(newRules[i]) === baseCombinator) {
711
+ nextBaseCombinatorIndex = i;
712
+ break;
713
+ }
714
+ if (nextBaseCombinatorIndex === -1) {
715
+ newRules.splice(cursor, newRules.length, generateRuleGroupICWithConsistentCombinators({ rules: newRules.slice(cursor) }, baseCombinatorLevel + 1));
716
+ break;
717
+ } else newRules.splice(cursor, nextBaseCombinatorIndex - cursor, generateRuleGroupICWithConsistentCombinators({ rules: newRules.slice(cursor, nextBaseCombinatorIndex) }, baseCombinatorLevel + 1));
718
+ }
719
+ return {
720
+ ...rg,
721
+ rules: newRules
722
+ };
722
723
  };
723
724
  /**
724
725
  * Converts a {@link RuleGroupTypeIC} to {@link RuleGroupType}.
@@ -731,9 +732,11 @@ const generateRuleGroupICWithConsistentCombinators = (rg, baseCombinatorLevel =
731
732
  const convertFromIC = (rg) => {
732
733
  if (isRuleGroupType(rg)) return rg;
733
734
  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");
735
+ const rules = [];
736
+ let combinator = "and";
737
+ for (const [idx, r] of processedRG.rules.entries()) if (typeof r === "string") {
738
+ if (idx === 1) combinator = r;
739
+ } else rules.push(isRuleGroup(r) ? convertFromIC(r) : r);
737
740
  return {
738
741
  ...processedRG,
739
742
  combinator,
@@ -753,7 +756,8 @@ const convertToIC = (rg) => {
753
756
  const { combinator, ...queryWithoutCombinator } = rg;
754
757
  const rules = [];
755
758
  const { length } = rg.rules;
756
- for (const [idx, r] of rg.rules.entries()) {
759
+ for (let idx = 0; idx < length; idx++) {
760
+ const r = rg.rules[idx];
757
761
  if (isRuleGroup(r)) rules.push(convertToIC(r));
758
762
  else rules.push(r);
759
763
  if (combinator && idx < length - 1) rules.push(combinator);
@@ -766,7 +770,6 @@ const convertToIC = (rg) => {
766
770
  function convertQuery(query) {
767
771
  return isRuleGroupTypeIC(query) ? convertFromIC(query) : convertToIC(query);
768
772
  }
769
-
770
773
  //#endregion
771
774
  //#region src/utils/defaultValidator.ts
772
775
  /**
@@ -803,7 +806,6 @@ const defaultValidator = (query) => {
803
806
  validateGroup(query);
804
807
  return result;
805
808
  };
806
-
807
809
  //#endregion
808
810
  //#region src/utils/objectUtils.ts
809
811
  /**
@@ -818,7 +820,11 @@ const objectKeys = Object.keys;
818
820
  * [Original source](https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-entries.ts)
819
821
  */
820
822
  const objectEntries = Object.entries;
821
-
823
+ /**
824
+ * Returns `true` if the key could cause prototype pollution when used
825
+ * as a property name in bracket-notation assignment.
826
+ */
827
+ const isUnsafeKey = (key) => key === "__proto__" || key === "constructor" || key === "prototype";
822
828
  //#endregion
823
829
  //#region src/utils/optGroupUtils.ts
824
830
  const isOptionWithName = (opt) => isPojo(opt) && "name" in opt && typeof opt.name === "string";
@@ -830,24 +836,23 @@ const isOptionWithValue = (opt) => isPojo(opt) && "value" in opt && typeof opt.v
830
836
  * @group Option Lists
831
837
  */
832
838
  function toFullOption(opt, baseProperties, labelMap) {
833
- return 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);
839
+ if (typeof opt === "string") return {
840
+ ...baseProperties,
841
+ name: opt,
842
+ value: opt,
843
+ label: labelMap?.[opt] ?? opt
844
+ };
845
+ const idObj = {};
846
+ let needsUpdating = !!baseProperties;
847
+ if (isOptionWithName(opt) && !isOptionWithValue(opt)) {
848
+ idObj.value = opt.name;
849
+ needsUpdating = true;
850
+ } else if (!isOptionWithName(opt) && isOptionWithValue(opt)) {
851
+ idObj.name = opt.value;
852
+ needsUpdating = true;
853
+ }
854
+ if (needsUpdating) return Object.assign({}, baseProperties, opt, idObj);
855
+ return opt;
851
856
  }
852
857
  /**
853
858
  * Converts an {@link OptionList} or {@link FlexibleOptionList} into a {@link FullOptionList}.
@@ -857,10 +862,12 @@ function toFullOption(opt, baseProperties, labelMap) {
857
862
  */
858
863
  function toFullOptionList(optList, baseProperties, labelMap) {
859
864
  if (!Array.isArray(optList)) return [];
860
- return 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);
865
+ const list = optList;
866
+ if (isFlexibleOptionGroupArray(list)) return list.map((optGroup) => ({
867
+ ...optGroup,
868
+ options: optGroup.options.map((opt) => toFullOption(opt, baseProperties, labelMap))
869
+ }));
870
+ return list.map((opt) => toFullOption(opt, baseProperties, labelMap));
864
871
  }
865
872
  /**
866
873
  * Converts a {@link FlexibleOptionList} into a {@link FullOptionList}.
@@ -997,7 +1004,7 @@ const uniqOptList = (originalArray) => {
997
1004
  };
998
1005
  const prepareOptionList = (props) => {
999
1006
  // istanbul ignore next
1000
- const { optionList: optionListPropOriginal, baseOption = {}, labelMap = {}, placeholder: { placeholderName = defaultPlaceholderName, placeholderLabel = defaultPlaceholderLabel, placeholderGroupLabel = defaultPlaceholderLabel } = {}, autoSelectOption = true } = props;
1007
+ const { optionList: optionListPropOriginal, baseOption = {}, labelMap = {}, placeholder: { placeholderName = "~", placeholderLabel = defaultPlaceholderLabel, placeholderGroupLabel = defaultPlaceholderLabel } = {}, autoSelectOption = true } = props;
1001
1008
  const defaultOption = {
1002
1009
  id: placeholderName,
1003
1010
  name: placeholderName,
@@ -1031,7 +1038,6 @@ const prepareOptionList = (props) => {
1031
1038
  optionsMap
1032
1039
  };
1033
1040
  };
1034
-
1035
1041
  //#endregion
1036
1042
  //#region src/utils/filterFieldsByComparator.ts
1037
1043
  const filterByComparator = (field, operator, fieldToCompare) => {
@@ -1067,7 +1073,6 @@ const filterFieldsByComparator = (field, fields, operator) => {
1067
1073
  })).filter((og) => og.options.length > 0);
1068
1074
  return fields.filter((f) => filterByComparator(field, operator, f));
1069
1075
  };
1070
-
1071
1076
  //#endregion
1072
1077
  //#region src/utils/parseNumber.ts
1073
1078
  /**
@@ -1087,23 +1092,21 @@ const parseNumber = (val, { parseNumbers, bigIntOnOverflow } = {}) => {
1087
1092
  });
1088
1093
  return typeof valAsNum === "bigint" || !Number.isNaN(valAsNum) ? valAsNum : val;
1089
1094
  };
1090
-
1091
1095
  //#endregion
1092
1096
  //#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) => 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];
1097
+ const remapProperties = (obj, propertyMap, deleteRemappedProperties) => {
1098
+ const result = {};
1099
+ for (const key in obj) {
1100
+ if (isUnsafeKey(key)) continue;
1101
+ const mappedKey = propertyMap[key];
1102
+ if (mappedKey === false) continue;
1103
+ if (mappedKey && key !== mappedKey) {
1104
+ if (!isUnsafeKey(mappedKey)) result[mappedKey] = obj[key];
1105
+ if (!deleteRemappedProperties) result[key] = obj[key];
1106
+ } else result[key] = obj[key];
1105
1107
  }
1106
- });
1108
+ return result;
1109
+ };
1107
1110
  function transformQuery(query, options = {}) {
1108
1111
  const { ruleProcessor = (r) => r, ruleGroupProcessor = (rg) => rg, propertyMap = {}, combinatorMap = {}, operatorMap = {}, omitPath = false, deleteRemappedProperties = true } = options;
1109
1112
  const processGroup = (rg) => ({
@@ -1130,7 +1133,6 @@ function transformQuery(query, options = {}) {
1130
1133
  ...omitPath ? null : { path: [] }
1131
1134
  });
1132
1135
  }
1133
-
1134
1136
  //#endregion
1135
1137
  //#region src/utils/isRuleOrGroupValid.ts
1136
1138
  /**
@@ -1154,7 +1156,6 @@ const isRuleOrGroupValid = (rg, validationResult, validator) => {
1154
1156
  }
1155
1157
  return true;
1156
1158
  };
1157
-
1158
1159
  //#endregion
1159
1160
  //#region src/utils/getParseNumberMethod.ts
1160
1161
  const getParseNumberMethod = ({ parseNumbers, inputType }) => {
@@ -1165,7 +1166,6 @@ const getParseNumberMethod = ({ parseNumbers, inputType }) => {
1165
1166
  }
1166
1167
  return parseNumbers ? "strict" : false;
1167
1168
  };
1168
-
1169
1169
  //#endregion
1170
1170
  //#region src/utils/formatQuery/utils.ts
1171
1171
  /**
@@ -1247,7 +1247,8 @@ const jsonLogicAdditionalOperators = {
1247
1247
  endsWith: (a, b) => typeof a === "string" && a.endsWith(b)
1248
1248
  };
1249
1249
  /**
1250
- * Converts all `string`-type `value` properties of a query object into `number` where appropriate.
1250
+ * Returns a new query object with all `string`-type `value` properties converted
1251
+ * to `number` where appropriate.
1251
1252
  *
1252
1253
  * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`.
1253
1254
  *
@@ -1416,7 +1417,6 @@ const bigIntJsonStringifyReplacer = (_key, value) => typeof value === "bigint" ?
1416
1417
  * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
1417
1418
  */
1418
1419
  const bigIntJsonParseReviver = (_key, value) => isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === "string" ? BigInt(value.$bigint) : value;
1419
-
1420
1420
  //#endregion
1421
1421
  //#region src/utils/formatQuery/defaultRuleGroupProcessorCEL.ts
1422
1422
  /**
@@ -1472,7 +1472,6 @@ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
1472
1472
  };
1473
1473
  return processRuleGroup(ruleGroup, true);
1474
1474
  };
1475
-
1476
1475
  //#endregion
1477
1476
  //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts
1478
1477
  const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot");
@@ -1553,7 +1552,6 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
1553
1552
  }
1554
1553
  return "";
1555
1554
  };
1556
-
1557
1555
  //#endregion
1558
1556
  //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDBQuery.ts
1559
1557
  /**
@@ -1591,11 +1589,11 @@ const defaultRuleGroupProcessorMongoDBQuery = (ruleGroup, options, meta) => {
1591
1589
  fieldData
1592
1590
  }, meta);
1593
1591
  }).filter(Boolean);
1594
- return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
1592
+ const result = expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
1593
+ return rg.not ? { $not: result } : result;
1595
1594
  };
1596
1595
  return processRuleGroup(convertFromIC(ruleGroup), true);
1597
1596
  };
1598
-
1599
1597
  //#endregion
1600
1598
  //#region src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts
1601
1599
  const processNumber$1 = (value, fallback, parseNumbers = false) => shouldRenderAsNumber(value, parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: "strict" })) : fallback;
@@ -1724,7 +1722,6 @@ const defaultRuleProcessorMongoDBQuery = (rule, options = {}) => {
1724
1722
  }
1725
1723
  return "";
1726
1724
  };
1727
-
1728
1725
  //#endregion
1729
1726
  //#region src/utils/formatQuery/defaultRuleProcessorMongoDB.ts
1730
1727
  /**
@@ -1738,7 +1735,6 @@ const defaultRuleProcessorMongoDB = (rule, options) => {
1738
1735
  const queryObj = defaultRuleProcessorMongoDBQuery(rule, options);
1739
1736
  return queryObj ? JSON.stringify(queryObj) : "";
1740
1737
  };
1741
-
1742
1738
  //#endregion
1743
1739
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSpEL.ts
1744
1740
  /**
@@ -1794,11 +1790,10 @@ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
1794
1790
  };
1795
1791
  return processRuleGroup(ruleGroup, true);
1796
1792
  };
1797
-
1798
1793
  //#endregion
1799
1794
  //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts
1800
1795
  const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot");
1801
- const wrapInNegation = (clause, negate$1) => negate$1 ? `!(${clause})` : clause;
1796
+ const wrapInNegation = (clause, negate) => negate ? `!(${clause})` : clause;
1802
1797
  const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
1803
1798
  /**
1804
1799
  * Default rule processor used by {@link formatQuery} for "spel" format.
@@ -1851,9 +1846,9 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1851
1846
  case "notnull": return `${field} != null`;
1852
1847
  case "in":
1853
1848
  case "notin": {
1854
- const negate$1 = shouldNegate$1(operatorTL) ? "!" : "";
1849
+ const negate = shouldNegate$1(operatorTL) ? "!" : "";
1855
1850
  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 ")})` : "";
1851
+ return valueAsArray.length > 0 ? `${negate}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
1857
1852
  }
1858
1853
  case "between":
1859
1854
  case "notbetween": {
@@ -1876,7 +1871,6 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1876
1871
  }
1877
1872
  return "";
1878
1873
  };
1879
-
1880
1874
  //#endregion
1881
1875
  //#region src/utils/formatQuery/defaultValueProcessorByRule.ts
1882
1876
  const escapeStringValueQuotes$1 = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
@@ -1932,7 +1926,6 @@ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQ
1932
1926
  if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
1933
1927
  return valueIsField ? wrapFieldName(value) : shouldRenderAsNumber(value, parseNumbers) ? `${trimIfString(value)}` : `${wrapAndEscape(value)}`;
1934
1928
  };
1935
-
1936
1929
  //#endregion
1937
1930
  //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
1938
1931
  /**
@@ -2029,7 +2022,6 @@ const defaultRuleProcessorDrizzle = (rule, _options) => {
2029
2022
  default: return;
2030
2023
  }
2031
2024
  };
2032
-
2033
2025
  //#endregion
2034
2026
  //#region src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts
2035
2027
  /**
@@ -2073,7 +2065,6 @@ const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns
2073
2065
  };
2074
2066
  return processRuleGroup(convertFromIC(ruleGroup), true);
2075
2067
  };
2076
-
2077
2068
  //#endregion
2078
2069
  //#region src/utils/formatQuery/defaultRuleGroupProcessorElasticSearch.ts
2079
2070
  /**
@@ -2102,7 +2093,6 @@ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
2102
2093
  const processedRuleGroup = processRuleGroup(convertFromIC(ruleGroup));
2103
2094
  return processedRuleGroup === false ? {} : processedRuleGroup;
2104
2095
  };
2105
-
2106
2096
  //#endregion
2107
2097
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts
2108
2098
  /**
@@ -2158,7 +2148,6 @@ const defaultRuleGroupProcessorJSONata = (ruleGroup, options) => {
2158
2148
  };
2159
2149
  return processRuleGroup(ruleGroup, true);
2160
2150
  };
2161
-
2162
2151
  //#endregion
2163
2152
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJsonLogic.ts
2164
2153
  /**
@@ -2188,7 +2177,6 @@ const defaultRuleGroupProcessorJsonLogic = (ruleGroup, options) => {
2188
2177
  };
2189
2178
  return processRuleGroup(query, true);
2190
2179
  };
2191
-
2192
2180
  //#endregion
2193
2181
  //#region src/utils/formatQuery/defaultRuleGroupProcessorLDAP.ts
2194
2182
  /**
@@ -2219,7 +2207,6 @@ const defaultRuleGroupProcessorLDAP = (ruleGroup, options) => {
2219
2207
  };
2220
2208
  return processRuleGroup(convertFromIC(ruleGroup), true);
2221
2209
  };
2222
-
2223
2210
  //#endregion
2224
2211
  //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDB.ts
2225
2212
  const isBracketed = (str) => str.startsWith("{") && str.endsWith("}");
@@ -2254,12 +2241,12 @@ const defaultRuleGroupProcessorMongoDB = (ruleGroup, options, meta) => {
2254
2241
  fieldData
2255
2242
  }, meta);
2256
2243
  }).filter(Boolean);
2257
- return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
2244
+ const result = expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
2245
+ return rg.not ? `"$not":${isBracketed(result) ? result : `{${result}}`}` : result;
2258
2246
  };
2259
2247
  const processedQuery = processRuleGroup(convertFromIC(ruleGroup), true);
2260
2248
  return isBracketed(processedQuery) ? processedQuery : `{${processedQuery}}`;
2261
2249
  };
2262
-
2263
2250
  //#endregion
2264
2251
  //#region src/utils/formatQuery/defaultRuleGroupProcessorNL.ts
2265
2252
  /**
@@ -2323,7 +2310,6 @@ const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
2323
2310
  };
2324
2311
  return processRuleGroup(ruleGroup, true);
2325
2312
  };
2326
-
2327
2313
  //#endregion
2328
2314
  //#region src/utils/formatQuery/defaultRuleGroupProcessorParameterized.ts
2329
2315
  /**
@@ -2412,7 +2398,6 @@ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
2412
2398
  params: paramsNamed
2413
2399
  };
2414
2400
  };
2415
-
2416
2401
  //#endregion
2417
2402
  //#region src/utils/formatQuery/defaultRuleGroupProcessorPrisma.ts
2418
2403
  /**
@@ -2455,7 +2440,6 @@ const defaultRuleGroupProcessorPrisma = (ruleGroup, options) => {
2455
2440
  const result = processRuleGroup(convertFromIC(ruleGroup), true);
2456
2441
  return ruleGroup.not ? { NOT: result } : result;
2457
2442
  };
2458
-
2459
2443
  //#endregion
2460
2444
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSequelize.ts
2461
2445
  /**
@@ -2496,7 +2480,6 @@ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
2496
2480
  };
2497
2481
  return processRuleGroup(convertFromIC(ruleGroup), true);
2498
2482
  };
2499
-
2500
2483
  //#endregion
2501
2484
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts
2502
2485
  /**
@@ -2553,7 +2536,6 @@ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
2553
2536
  };
2554
2537
  return processRuleGroup(ruleGroup, true);
2555
2538
  };
2556
-
2557
2539
  //#endregion
2558
2540
  //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
2559
2541
  const rangeOperatorMap = {
@@ -2705,12 +2687,11 @@ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
2705
2687
  }
2706
2688
  return false;
2707
2689
  };
2708
-
2709
2690
  //#endregion
2710
2691
  //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
2711
2692
  const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
2712
2693
  const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
2713
- const negate = (clause, negate$1) => negate$1 ? `$not(${clause})` : clause;
2694
+ const negate = (clause, neg) => neg ? `$not(${clause})` : clause;
2714
2695
  const escapeStringRegex = (s) => `${s}`.replaceAll(/[/$()*+.?[\\\]^{|}]/g, String.raw`\$&`).replaceAll("-", String.raw`\x2d`);
2715
2696
  /**
2716
2697
  * Default rule processor used by {@link formatQuery} for "jsonata" format.
@@ -2792,7 +2773,6 @@ const defaultRuleProcessorJSONata = (rule, options = {}) => {
2792
2773
  }
2793
2774
  return "";
2794
2775
  };
2795
-
2796
2776
  //#endregion
2797
2777
  //#region src/utils/formatQuery/defaultRuleProcessorJsonLogic.ts
2798
2778
  const convertOperator = (op) => op.replace(/^(=)$/, "$1=").replace(/^notnull$/i, "!=").replace(/^null$/i, "==");
@@ -2887,10 +2867,9 @@ const defaultRuleProcessorJsonLogic = (rule, options = {}) => {
2887
2867
  }
2888
2868
  return false;
2889
2869
  };
2890
-
2891
2870
  //#endregion
2892
2871
  //#region src/utils/formatQuery/defaultRuleProcessorLDAP.ts
2893
- const negateIf = (clause, negate$1) => negate$1 ? `(!${clause})` : `${clause}`;
2872
+ const negateIf = (clause, negate) => negate ? `(!${clause})` : `${clause}`;
2894
2873
  const ldapEscape = (s) => `${trimIfString(s)}`.replaceAll(/[()&|=<>~*\\/]/g, (m) => `\\${m.codePointAt(0).toString(16)}`);
2895
2874
  /**
2896
2875
  * Default rule processor used by {@link formatQuery} for "ldap" format.
@@ -2939,7 +2918,6 @@ const defaultRuleProcessorLDAP = (rule, options = {}) => {
2939
2918
  // istanbul ignore next
2940
2919
  return "";
2941
2920
  };
2942
-
2943
2921
  //#endregion
2944
2922
  //#region src/utils/formatQuery/defaultValueProcessorNL.ts
2945
2923
  const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
@@ -2989,7 +2967,6 @@ const defaultValueProcessorNL = (rule, opts = {}) => {
2989
2967
  if (typeof rule.value === "boolean") return rule.value ? trueTL : falseTL;
2990
2968
  return valueIsField ? wrapFieldName(getOption(fields ?? [], rule.value)?.label ?? rule.value) : shouldRenderAsNumber(rule.value, parseNumbers) ? `${trimIfString(rule.value)}` : `${wrapAndEscape(rule.value)}`;
2991
2969
  };
2992
-
2993
2970
  //#endregion
2994
2971
  //#region src/utils/formatQuery/defaultRuleProcessorNL.ts
2995
2972
  /**
@@ -3099,7 +3076,6 @@ const defaultRuleProcessorNL = (rule, opts) => {
3099
3076
  };
3100
3077
  return normalizeConstituentWordOrder(wordOrder).map((term) => `${wordOrderMap[term]}`).join(" ").trim();
3101
3078
  };
3102
-
3103
3079
  //#endregion
3104
3080
  //#region src/utils/formatQuery/defaultRuleProcessorSQL.ts
3105
3081
  /**
@@ -3154,7 +3130,6 @@ const defaultRuleProcessorSQL = (rule, opts = {}) => {
3154
3130
  if ((operatorLowerCase === "in" || operatorLowerCase === "not in" || operatorLowerCase === "between" || operatorLowerCase === "not between") && !value) return "";
3155
3131
  return `${ruleField} ${operator} ${value}`.trim();
3156
3132
  };
3157
-
3158
3133
  //#endregion
3159
3134
  //#region src/utils/formatQuery/defaultRuleProcessorParameterized.ts
3160
3135
  /**
@@ -3259,7 +3234,6 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
3259
3234
  }
3260
3235
  return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${parameterized ? numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?" : `${paramPrefix}${paramName}`}`.trim());
3261
3236
  };
3262
-
3263
3237
  //#endregion
3264
3238
  //#region src/utils/formatQuery/defaultRuleProcessorPrisma.ts
3265
3239
  const processNumber = (value, fallback, parseNumbers) => shouldRenderAsNumber(value, !!parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: !!parseNumbers })) : fallback;
@@ -3321,7 +3295,6 @@ const defaultRuleProcessorPrisma = (rule, options = {}) => {
3321
3295
  }
3322
3296
  return "";
3323
3297
  };
3324
-
3325
3298
  //#endregion
3326
3299
  //#region src/utils/formatQuery/defaultRuleProcessorSequelize.ts
3327
3300
  /**
@@ -3388,7 +3361,6 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
3388
3361
  }
3389
3362
  }
3390
3363
  };
3391
-
3392
3364
  //#endregion
3393
3365
  //#region src/utils/formatQuery/formatQuery.ts
3394
3366
  /**
@@ -3477,8 +3449,8 @@ const defaultFormatQueryOptions = {
3477
3449
  paramsKeepPrefix: false,
3478
3450
  numberedParams: false,
3479
3451
  preserveValueOrder: false,
3480
- placeholderFieldName: defaultPlaceholderFieldName,
3481
- placeholderOperatorName: defaultPlaceholderOperatorName,
3452
+ placeholderFieldName: "~",
3453
+ placeholderOperatorName: "~",
3482
3454
  quoteValuesWith: "'",
3483
3455
  concatOperator: "||",
3484
3456
  preset: "ansi",
@@ -3583,7 +3555,7 @@ function formatQuery(ruleGroup, optionParam = {}) {
3583
3555
  switch (format) {
3584
3556
  case "json":
3585
3557
  case "json_without_ids": {
3586
- const rg = parseNumbers ? produce(ruleGroup, (g) => numerifyValues(g, finalOptions)) : ruleGroup;
3558
+ const rg = parseNumbers ? numerifyValues(ruleGroup, finalOptions) : ruleGroup;
3587
3559
  if (format === "json_without_ids") return JSON.stringify(rg, (key, value) => key === "id" || key === "path" ? void 0 : bigIntJsonStringifyReplacer(key, value));
3588
3560
  return JSON.stringify(rg, bigIntJsonStringifyReplacer, 2);
3589
3561
  }
@@ -3605,7 +3577,6 @@ function formatQuery(ruleGroup, optionParam = {}) {
3605
3577
  default: return "";
3606
3578
  }
3607
3579
  }
3608
-
3609
3580
  //#endregion
3610
3581
  //#region src/utils/formatQuery/index.ts
3611
3582
  const generateValueProcessor = (vpbr) => (field, operator, value, valueSource) => vpbr({
@@ -3656,7 +3627,6 @@ const defaultValueProcessorMongoDBByRule = defaultRuleProcessorMongoDB;
3656
3627
  * @group Export
3657
3628
  */
3658
3629
  const defaultValueProcessorSpELByRule = defaultRuleProcessorSpEL;
3659
-
3660
3630
  //#endregion
3661
3631
  //#region src/utils/pathUtils.ts
3662
3632
  /**
@@ -3715,7 +3685,7 @@ const pathsAreEqual = (path1, path2) => path1.length === path2.length && path1.e
3715
3685
  * Determines if the first path is an ancestor of the second path. The first path must
3716
3686
  * be shorter and exactly match the second path up through the length of the first path.
3717
3687
  */
3718
- const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && (/* @__PURE__ */ new RegExp(`^${maybeAncestor.join("-")}`)).test(path.join("-"));
3688
+ const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && new RegExp(`^${maybeAncestor.join("-")}`).test(path.join("-"));
3719
3689
  /**
3720
3690
  * Finds the deepest/longest path that two paths have in common.
3721
3691
  */
@@ -3748,11 +3718,9 @@ const pathIsDisabled = (path, query) => {
3748
3718
  }
3749
3719
  return disabled;
3750
3720
  };
3751
-
3752
3721
  //#endregion
3753
3722
  //#region src/utils/generateAccessibleDescription.ts
3754
3723
  const generateAccessibleDescription = (params) => pathsAreEqual([], params.path) ? `Query builder` : `Rule group at path ${params.path.join("-")}`;
3755
-
3756
3724
  //#endregion
3757
3725
  //#region src/utils/generateID.ts
3758
3726
  const cryptoModule = globalThis.crypto;
@@ -3787,7 +3755,6 @@ if (cryptoModule) {
3787
3755
  };
3788
3756
  }
3789
3757
  }
3790
-
3791
3758
  //#endregion
3792
3759
  //#region src/utils/getMatchModesUtil.ts
3793
3760
  const dummyFD$1 = {
@@ -3815,7 +3782,6 @@ const getMatchModesUtil = (fieldData, getMatchModes) => {
3815
3782
  label: mm
3816
3783
  }) ?? [];
3817
3784
  };
3818
-
3819
3785
  //#endregion
3820
3786
  //#region src/utils/getValidationClassNames.ts
3821
3787
  /**
@@ -3826,7 +3792,6 @@ const getValidationClassNames = (validationResult) => {
3826
3792
  const valid = typeof validationResult === "boolean" ? validationResult : typeof validationResult === "object" && validationResult !== null ? validationResult.valid : null;
3827
3793
  return typeof valid === "boolean" ? valid ? standardClassnames.valid : standardClassnames.invalid : "";
3828
3794
  };
3829
-
3830
3795
  //#endregion
3831
3796
  //#region src/utils/getValueSourcesUtil.ts
3832
3797
  const defaultValueSourcesArray = [{
@@ -3859,27 +3824,34 @@ const getValueSourcesUtil = (fieldData, operator, getValueSources) => {
3859
3824
  label: vs
3860
3825
  });
3861
3826
  };
3862
-
3863
3827
  //#endregion
3864
3828
  //#region src/utils/mergeAnyTranslations.ts
3865
3829
  /**
3866
3830
  * Merges any number of partial translations into a single definition.
3867
3831
  */
3868
- const mergeAnyTranslations = (base, ...otherTranslations) => produce(base, (draft) => {
3832
+ const mergeAnyTranslations = (base, ...otherTranslations) => {
3833
+ const result = { ...base };
3869
3834
  for (const translations of otherTranslations)
3870
3835
  // 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
- });
3836
+ if (translations) for (const key of objectKeys(translations)) {
3837
+ if (isUnsafeKey(key)) continue;
3838
+ if (result[key]) result[key] = {
3839
+ ...result[key],
3840
+ ...translations[key]
3841
+ };
3842
+ else result[key] = { ...translations[key] };
3843
+ }
3844
+ return result;
3845
+ };
3874
3846
  const mergeAnyTranslation = (el, keyPropContextMap, defaults) => {
3875
- const finalKeys = objectEntries(keyPropContextMap).map(([key, [pT, cT]]) => [key, pT ?? cT ?? defaults?.[el]?.[key]]).filter((k) => !!k[1]);
3847
+ if (isUnsafeKey(el)) return void 0;
3848
+ const finalKeys = objectEntries(keyPropContextMap).map(([key, [pT, cT]]) => [key, pT ?? cT ?? defaults?.[el]?.[key]]).filter((k) => !isUnsafeKey(k[0]) && !!k[1]);
3876
3849
  if (finalKeys.length > 0 || defaults) {
3877
3850
  const defaultProperties = defaults?.[el] ?? {};
3878
3851
  const finalObject = Object.assign({}, defaultProperties, Object.fromEntries(finalKeys));
3879
3852
  return { [el]: finalObject };
3880
3853
  }
3881
3854
  };
3882
-
3883
3855
  //#endregion
3884
3856
  //#region src/utils/mergeClassnames.ts
3885
3857
  const joinClassnamesByName = (name, args) => clsx(args.map((c) => clsx(c?.[name])));
@@ -3929,7 +3901,6 @@ const mergeClassnames = (...args) => ({
3929
3901
  hasSubQuery: joinClassnamesByName("hasSubQuery", args),
3930
3902
  loading: joinClassnamesByName("loading", args)
3931
3903
  });
3932
-
3933
3904
  //#endregion
3934
3905
  //#region src/utils/preferProp.ts
3935
3906
  const preferPropDefaultTrue = (prop, context) => prop === false ? false : prop ? true : !(context === false);
@@ -3952,29 +3923,49 @@ const preferFlagProps = (props = {}, contextVals = {}, finalize) => objectEntrie
3952
3923
  acc[key] = preferProp(def, props[key], contextVals[key], !finalize);
3953
3924
  return acc;
3954
3925
  }, {});
3955
-
3956
3926
  //#endregion
3957
3927
  //#region src/utils/prepareQueryObjects.ts
3958
3928
  /**
3959
3929
  * Ensures that a rule is valid by adding an `id` property if it does not already exist.
3960
3930
  */
3961
- const prepareRule = (rule, { idGenerator = generateID } = {}) => produce(rule, (draft) => {
3962
- if (!draft.id) draft.id = idGenerator();
3963
- if (processMatchMode(draft)) draft.value = prepareRuleGroup(draft.value, { idGenerator });
3964
- });
3931
+ const prepareRule = (rule, { idGenerator = generateID } = {}) => {
3932
+ const needsId = !rule.id;
3933
+ const hasMatchMode = processMatchMode(rule);
3934
+ if (!needsId && !hasMatchMode) return rule;
3935
+ return {
3936
+ ...rule,
3937
+ ...needsId && { id: idGenerator() },
3938
+ ...hasMatchMode && { value: prepareRuleGroup(rule.value, { idGenerator }) }
3939
+ };
3940
+ };
3965
3941
  /**
3966
3942
  * Ensures that a rule group is valid by recursively adding an `id` property to the group itself
3967
3943
  * and all its rules and subgroups where one does not already exist.
3968
3944
  */
3969
- const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => 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
- });
3945
+ const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => {
3946
+ const needsId = !queryObject.id;
3947
+ let rulesChanged = false;
3948
+ const newRules = [];
3949
+ for (let i = 0; i < queryObject.rules.length; i++) {
3950
+ const r = queryObject.rules[i];
3951
+ if (typeof r === "string") newRules.push(r);
3952
+ else {
3953
+ const prepared = isRuleGroup(r) ? prepareRuleGroup(r, { idGenerator }) : prepareRule(r, { idGenerator });
3954
+ newRules.push(prepared);
3955
+ if (prepared !== r) rulesChanged = true;
3956
+ }
3957
+ }
3958
+ if (!needsId && !rulesChanged) return queryObject;
3959
+ return {
3960
+ ...queryObject,
3961
+ ...needsId && { id: idGenerator() },
3962
+ rules: newRules
3963
+ };
3964
+ };
3973
3965
  /**
3974
3966
  * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.
3975
3967
  */
3976
3968
  const prepareRuleOrGroup = (rg, { idGenerator = generateID } = {}) => isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });
3977
-
3978
3969
  //#endregion
3979
3970
  //#region src/utils/regenerateIDs.ts
3980
3971
  /**
@@ -4001,44 +3992,65 @@ const regenerateIDs = (subject, { idGenerator = generateID } = {}) => {
4001
3992
  if (Array.isArray(newGroup.rules)) newGroup.rules = subject.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? regenerateIDs(r, { idGenerator }) : regenerateID(r, { idGenerator }));
4002
3993
  return newGroup;
4003
3994
  };
4004
-
4005
3995
  //#endregion
4006
3996
  //#region src/utils/queryTools.ts
4007
3997
  /**
4008
- * Adds a rule or group to a query.
4009
- * @returns The new query with the rule or group added.
3998
+ * Adds a rule or group to a query without mutating the original query.
3999
+ *
4000
+ * @returns A new query with the rule or group added.
4010
4001
  *
4011
4002
  * @group Query Tools
4012
4003
  */
4013
- const add = (query, ruleOrGroup, parentPathOrID, { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = {}) => produce(query, (draft) => {
4014
- const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, draft) : findID(parentPathOrID, draft);
4015
- if (!parent || !isRuleGroup(parent)) return;
4004
+ const add = (query, ruleOrGroup, parentPathOrID, options = {}) => produce(query, (q) => addInPlace(q, ruleOrGroup, parentPathOrID, options));
4005
+ /**
4006
+ * Adds a rule or group to a query in place.
4007
+ *
4008
+ * @returns The query (mutated in place) with the rule or group added.
4009
+ *
4010
+ * @group Query Tools
4011
+ */
4012
+ const addInPlace = (query, ruleOrGroup, parentPathOrID, options = {}) => {
4013
+ const { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = options;
4014
+ const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, query) : findID(parentPathOrID, query);
4015
+ if (!parent || !isRuleGroup(parent)) return query;
4016
4016
  if (isRuleGroupTypeIC(parent) && parent.rules.length > 0) {
4017
4017
  const prevCombinator = parent.rules.at(-2);
4018
4018
  parent.rules.push(combinatorPreceding ?? (typeof prevCombinator === "string" ? prevCombinator : getFirstOption(combinators)));
4019
4019
  }
4020
4020
  parent.rules.push(prepareRuleOrGroup(ruleOrGroup, { idGenerator }));
4021
- });
4021
+ return query;
4022
+ };
4022
4023
  /**
4023
- * Updates a property of a rule or group within a query.
4024
- * @returns The new query with the rule or group property updated.
4024
+ * Updates a property of a rule or group within a query without mutating the original query.
4025
+ *
4026
+ * @returns A new query with the rule or group property updated.
4025
4027
  *
4026
4028
  * @group Query Tools
4027
4029
  */
4028
- const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = {}) => 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;
4030
+ const update = (query, prop, value, pathOrID, options = {}) => produce(query, (q) => updateInPlace(q, prop, value, pathOrID, options));
4031
+ /**
4032
+ * Updates a property of a rule or group within a query in place.
4033
+ *
4034
+ * @returns The query (mutated in place) with the rule or group property updated.
4035
+ *
4036
+ * @group Query Tools
4037
+ */
4038
+ const updateInPlace = (query, prop, value, pathOrID, options = {}) => {
4039
+ const { resetOnFieldChange: _resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = options;
4040
+ let resetOnFieldChange = _resetOnFieldChange;
4041
+ const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
4042
+ if (!path) return query;
4043
+ if (prop === "combinator" && !isRuleGroupType(query)) {
4044
+ const parentRules = findPath(getParentPath(path), query).rules;
4033
4045
  if (path.at(-1) % 2 === 1) parentRules[path.at(-1)] = value;
4034
- return;
4046
+ return query;
4035
4047
  }
4036
- const ruleOrGroup = findPath(path, draft);
4037
- if (!ruleOrGroup) return;
4048
+ const ruleOrGroup = findPath(path, query);
4049
+ if (!ruleOrGroup) return query;
4038
4050
  const isGroup = isRuleGroup(ruleOrGroup);
4039
- if (ruleOrGroup[prop] === value) return;
4051
+ if (ruleOrGroup[prop] === value) return query;
4040
4052
  if (prop !== "valueSource") ruleOrGroup[prop] = value;
4041
- if (isGroup) return;
4053
+ if (isGroup) return query;
4042
4054
  let resetValueSource = false;
4043
4055
  let resetValue = false;
4044
4056
  if (prop === "field") {
@@ -4073,25 +4085,33 @@ const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, reset
4073
4085
  ruleOrGroup.valueSource = resetValueSource ? defaultValueSource : value;
4074
4086
  }
4075
4087
  if (resetValue) ruleOrGroup.value = getRuleDefaultValue(ruleOrGroup);
4076
- });
4088
+ return query;
4089
+ };
4077
4090
  /**
4078
- * Removes a rule or group from a query.
4079
- * @returns The new query with the rule or group removed.
4091
+ * Removes a rule or group from a query without mutating the original query.
4092
+ *
4093
+ * @returns A new query with the rule or group removed.
4080
4094
  *
4081
4095
  * @group Query Tools
4082
4096
  */
4083
- const remove = (query, pathOrID) => {
4097
+ const remove = (query, pathOrID) => produce(query, (q) => removeInPlace(q, pathOrID));
4098
+ /**
4099
+ * Removes a rule or group from a query in place.
4100
+ *
4101
+ * @returns The query (mutated in place) with the rule or group removed.
4102
+ *
4103
+ * @group Query Tools
4104
+ */
4105
+ const removeInPlace = (query, pathOrID) => {
4084
4106
  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 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
- });
4107
+ if (!path || path.length === 0 || !isRuleGroupType(query) && !findPath(path, query)) return query;
4108
+ const index = path.at(-1);
4109
+ const parent = findPath(getParentPath(path), query);
4110
+ if (parent && isRuleGroup(parent)) if (!isRuleGroupType(parent) && parent.rules.length > 1) {
4111
+ const idxStartDelete = index === 0 ? 0 : index - 1;
4112
+ parent.rules.splice(idxStartDelete, 2);
4113
+ } else parent.rules.splice(index, 1);
4114
+ return query;
4095
4115
  };
4096
4116
  const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4097
4117
  if (Array.isArray(newPathOrShiftDirection)) return newPathOrShiftDirection;
@@ -4118,59 +4138,79 @@ const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
4118
4138
  return currentPath;
4119
4139
  };
4120
4140
  /**
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.
4141
+ * Moves a rule or group from one path to another without mutating the original query.
4142
+ * In the options parameter, pass `{ clone: true }` to copy instead of move.
4143
+ *
4144
+ * @returns A new query with the rule or group moved or cloned.
4124
4145
  *
4125
4146
  * @group Query Tools
4126
4147
  */
4127
- const move = (query, oldPathOrID, newPath, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
4148
+ const move = (query, oldPathOrID, newPath, options = {}) => produce(query, (q) => moveInPlace(q, oldPathOrID, newPath, options));
4149
+ /**
4150
+ * Moves a rule or group from one path to another in place.
4151
+ * In the options parameter, pass `{ clone: true }` to copy instead of move.
4152
+ *
4153
+ * @returns The query (mutated in place) with the rule or group moved or cloned.
4154
+ *
4155
+ * @group Query Tools
4156
+ */
4157
+ const moveInPlace = (query, oldPathOrID, newPath, options = {}) => {
4158
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
4128
4159
  const oldPath = Array.isArray(oldPathOrID) ? oldPathOrID : getPathOfID(oldPathOrID, query);
4129
4160
  if (!oldPath) return query;
4130
4161
  const nextPath = getNextPath(query, oldPath, newPath);
4131
4162
  if (oldPath.length === 0 || pathsAreEqual(oldPath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
4132
4163
  const ruleOrGroupOriginal = findPath(oldPath, query);
4133
4164
  if (!ruleOrGroupOriginal) return query;
4134
- const ruleOrGroup = clone ? regenerateIDs(ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
4135
- return 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
- });
4165
+ const ruleOrGroup = clone ? regenerateIDs(isDraft(ruleOrGroupOriginal) ? current(ruleOrGroupOriginal) : ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
4166
+ const independentCombinators = isRuleGroupTypeIC(query);
4167
+ const parentOfRuleToRemove = findPath(getParentPath(oldPath), query);
4168
+ const ruleToRemoveIndex = oldPath.at(-1);
4169
+ const oldPrevCombinator = independentCombinators && ruleToRemoveIndex > 0 ? parentOfRuleToRemove.rules[ruleToRemoveIndex - 1] : null;
4170
+ const oldNextCombinator = independentCombinators && ruleToRemoveIndex < parentOfRuleToRemove.rules.length - 1 ? parentOfRuleToRemove.rules[ruleToRemoveIndex + 1] : null;
4171
+ if (!clone) {
4172
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4173
+ const deleteLength = independentCombinators ? 2 : 1;
4174
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4175
+ }
4176
+ const newNewPath = [...nextPath];
4177
+ const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);
4178
+ if (!clone && oldPath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4179
+ const parentToInsertInto = findPath(getParentPath(newNewPath), query);
4180
+ const newIndex = newNewPath.at(-1);
4181
+ /**
4182
+ * This function 1) glosses over the need for type assertions to splice directly
4183
+ * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
4184
+ */
4185
+ const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(newIndex, 0, ...args);
4186
+ if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(ruleOrGroup);
4187
+ else if (newIndex === 0) if (ruleToRemoveIndex === 0 && oldNextCombinator) insertRuleOrGroup(ruleOrGroup, oldNextCombinator);
4188
+ else insertRuleOrGroup(ruleOrGroup, parentToInsertInto.rules[1] ?? oldPrevCombinator ?? getFirstOption(combinators));
4189
+ else if (oldPrevCombinator) insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);
4190
+ else insertRuleOrGroup(parentToInsertInto.rules[newIndex - 2] ?? oldNextCombinator ?? getFirstOption(combinators), ruleOrGroup);
4191
+ return query;
4162
4192
  };
4163
4193
  /**
4164
- * Inserts a rule or group into a query.
4165
- * @returns The new query with the rule or group inserted.
4194
+ * Inserts a rule or group into a query without mutating the original query.
4195
+ *
4196
+ * @returns A new query with the rule or group inserted.
4197
+ *
4198
+ * @group Query Tools
4199
+ */
4200
+ const insert = (query, ruleOrGroup, path, options = {}) => produce(query, (q) => insertInPlace(q, ruleOrGroup, path, options));
4201
+ /**
4202
+ * Inserts a rule or group into a query in place.
4203
+ *
4204
+ * @returns The query (mutated in place) with the rule or group inserted.
4166
4205
  *
4167
4206
  * @group Query Tools
4168
4207
  */
4169
- const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = {}) => produce(query, (draft) => {
4170
- const parentToInsertInto = findPath(getParentPath(path), draft);
4171
- if (!parentToInsertInto || !isRuleGroup(parentToInsertInto)) return;
4208
+ const insertInPlace = (query, ruleOrGroup, path, options = {}) => {
4209
+ const { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = options;
4210
+ const parentToInsertInto = findPath(getParentPath(path), query);
4211
+ if (!parentToInsertInto || !isRuleGroup(parentToInsertInto)) return query;
4172
4212
  const rorg = regenerateIDs(ruleOrGroup, { idGenerator });
4173
- const independentCombinators = isRuleGroupTypeIC(draft);
4213
+ const independentCombinators = isRuleGroupTypeIC(query);
4174
4214
  const newIndex = path.at(-1);
4175
4215
  /**
4176
4216
  * This function 1) glosses over the need for type assertions to splice directly
@@ -4186,17 +4226,29 @@ const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, co
4186
4226
  if (combinatorPreceding) insertRuleOrGroup(normalizedNewIndex, combinatorPreceding, rorg);
4187
4227
  else insertRuleOrGroup(normalizedNewIndex, parentToInsertInto.rules[normalizedNewIndex - 2] ?? combinatorSucceeding ?? getFirstOption(combinators), rorg);
4188
4228
  }
4189
- });
4229
+ return query;
4230
+ };
4190
4231
  /**
4191
4232
  * 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.
4233
+ * objects at the target path and the source path without mutating the original query.
4234
+ * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.
4194
4235
  *
4195
- * @returns The new query with the rules or groups grouped.
4236
+ * @returns A new query with the rules or groups grouped.
4196
4237
  *
4197
4238
  * @group Query Tools
4198
4239
  */
4199
- const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
4240
+ const group = (query, sourcePathOrID, targetPathOrID, options = {}) => produce(query, (q) => groupInPlace(q, sourcePathOrID, targetPathOrID, options));
4241
+ /**
4242
+ * Creates a new group at a target path with its `rules` array containing the current
4243
+ * objects at the target path and the source path in place.
4244
+ * In the options parameter, pass `{ clone: true }` to copy the source rule/group instead of move.
4245
+ *
4246
+ * @returns The query (mutated in place) with the rules or groups grouped.
4247
+ *
4248
+ * @group Query Tools
4249
+ */
4250
+ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
4251
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
4200
4252
  const sourcePath = Array.isArray(sourcePathOrID) ? sourcePathOrID : getPathOfID(sourcePathOrID, query);
4201
4253
  const targetPath = Array.isArray(targetPathOrID) ? targetPathOrID : getPathOfID(targetPathOrID, query);
4202
4254
  if (!sourcePath || !targetPath) return query;
@@ -4205,32 +4257,31 @@ const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinato
4205
4257
  const sourceRuleOrGroupOriginal = findPath(sourcePath, query);
4206
4258
  const targetRuleOrGroup = findPath(targetPath, query);
4207
4259
  if (!sourceRuleOrGroupOriginal || !targetRuleOrGroup) return query;
4208
- const sourceRuleOrGroup = clone ? regenerateIDs(sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
4209
- return 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
- });
4260
+ const sourceRuleOrGroup = clone ? regenerateIDs(isDraft(sourceRuleOrGroupOriginal) ? current(sourceRuleOrGroupOriginal) : sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
4261
+ const independentCombinators = isRuleGroupTypeIC(query);
4262
+ const parentOfRuleToRemove = findPath(getParentPath(sourcePath), query);
4263
+ const ruleToRemoveIndex = sourcePath.at(-1);
4264
+ if (!clone) {
4265
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
4266
+ const deleteLength = independentCombinators ? 2 : 1;
4267
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
4268
+ }
4269
+ const newNewPath = [...nextPath];
4270
+ const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);
4271
+ if (!clone && sourcePath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
4272
+ const parentOfTargetPath = findPath(getParentPath(newNewPath), query);
4273
+ const targetPathIndex = newNewPath.at(-1);
4274
+ parentOfTargetPath.rules.splice(targetPathIndex, 1, prepareRuleOrGroup(independentCombinators ? { rules: [
4275
+ targetRuleOrGroup,
4276
+ getFirstOption(combinators),
4277
+ sourceRuleOrGroup
4278
+ ] } : {
4279
+ combinator: getFirstOption(combinators),
4280
+ rules: [targetRuleOrGroup, sourceRuleOrGroup]
4281
+ }, { idGenerator }));
4282
+ return query;
4232
4283
  };
4233
-
4234
4284
  //#endregion
4235
- export { LogType, TestID, add, bigIntJsonParseReviver, bigIntJsonStringifyReplacer, celCombinatorMap, clsx, convertFromIC, convertQuery, convertToIC, defaultCELValueProcessor, defaultCombinatorLabelMap, defaultCombinators, defaultCombinatorsExtended, defaultControlClassnames, defaultExportOperatorMap, defaultJoinChar, defaultMatchModes, defaultMongoDBValueProcessor, defaultNLTranslations, defaultOperatorLabelMap, defaultOperatorNegationMap, defaultOperatorProcessorNL, defaultOperatorProcessorSQL, defaultOperators, defaultPlaceholderFieldGroupLabel, defaultPlaceholderFieldLabel, defaultPlaceholderFieldName, defaultPlaceholderLabel, defaultPlaceholderName, defaultPlaceholderOperatorGroupLabel, defaultPlaceholderOperatorLabel, defaultPlaceholderOperatorName, defaultPlaceholderValueGroupLabel, defaultPlaceholderValueLabel, defaultPlaceholderValueName, defaultRuleGroupProcessorCEL, defaultRuleGroupProcessorDrizzle, defaultRuleGroupProcessorElasticSearch, defaultRuleGroupProcessorJSONata, defaultRuleGroupProcessorJsonLogic, defaultRuleGroupProcessorLDAP, defaultRuleGroupProcessorMongoDB, defaultRuleGroupProcessorMongoDBQuery, defaultRuleGroupProcessorNL, defaultRuleGroupProcessorParameterized, defaultRuleGroupProcessorPrisma, defaultRuleGroupProcessorSQL, defaultRuleGroupProcessorSequelize, defaultRuleGroupProcessorSpEL, defaultRuleProcessorCEL, defaultRuleProcessorDrizzle, defaultRuleProcessorElasticSearch, defaultRuleProcessorJSONata, defaultRuleProcessorJsonLogic, defaultRuleProcessorLDAP, defaultRuleProcessorMongoDB, defaultRuleProcessorMongoDBQuery, defaultRuleProcessorNL, defaultRuleProcessorParameterized, defaultRuleProcessorPrisma, defaultRuleProcessorSQL, defaultRuleProcessorSequelize, defaultRuleProcessorSpEL, defaultSpELValueProcessor, defaultTranslations, defaultValidator, defaultValueProcessor, defaultValueProcessorByRule, defaultValueProcessorCELByRule, defaultValueProcessorMongoDBByRule, defaultValueProcessorNL, defaultValueProcessorSpELByRule, filterFieldsByComparator, findID, findPath, formatQuery, formatQueryOptionPresets, generateAccessibleDescription, generateID, getCommonAncestorPath, getFirstOption, getMatchModesUtil, getNLTranslataion, getOption, getParentPath, getParseNumberMethod, getPathOfID, getQuoteFieldNamesWithArray, getQuotedFieldName, getValidationClassNames, getValueSourcesUtil, group, groupInvalidReasons, insert, isAncestor, isFlexibleOptionArray, isFlexibleOptionGroupArray, isFullOptionArray, isFullOptionGroupArray, isOptionGroupArray, isPojo, isRuleGroup, isRuleGroupType, isRuleGroupTypeIC, isRuleOrGroupValid, isRuleType, isValidValue, isValidationResult, isValueProcessorLegacy, joinWith, jsonLogicAdditionalOperators, lc, mapSQLOperator, mergeAnyTranslation, mergeAnyTranslations, mergeClassnames, mongoDbFallback, mongoOperators, move, normalizeConstituentWordOrder, nullFreeArray, nullOrUndefinedOrEmpty, numericRegex, numerifyValues, objectEntries, objectKeys, parseNumber, pathIsDisabled, pathsAreEqual, preferAnyProp, preferFlagProps, preferProp, prepareOptionList, prepareRule, prepareRuleGroup, prepareRuleOrGroup, prismaFallback, prismaOperators, processMatchMode, queryBuilderFlagDefaults, regenerateID, regenerateIDs, remove, rootPath, shouldRenderAsNumber, splitBy, sqlDialectPresets, standardClassnames, toArray, toFlatOptionArray, toFullOption, toFullOptionList, toFullOptionMap, transformQuery, trimIfString, uniqByIdentifier, uniqByName, uniqOptGroups, uniqOptList, update };
4285
+ export { LogType, TestID, add, addInPlace, bigIntJsonParseReviver, bigIntJsonStringifyReplacer, celCombinatorMap, clsx, convertFromIC, convertQuery, convertToIC, defaultCELValueProcessor, defaultCombinatorLabelMap, defaultCombinators, defaultCombinatorsExtended, defaultControlClassnames, defaultExportOperatorMap, defaultJoinChar, defaultMatchModes, defaultMongoDBValueProcessor, defaultNLTranslations, defaultOperatorLabelMap, defaultOperatorNegationMap, defaultOperatorProcessorNL, defaultOperatorProcessorSQL, defaultOperators, defaultPlaceholderFieldGroupLabel, defaultPlaceholderFieldLabel, defaultPlaceholderFieldName, defaultPlaceholderLabel, defaultPlaceholderName, defaultPlaceholderOperatorGroupLabel, defaultPlaceholderOperatorLabel, defaultPlaceholderOperatorName, defaultPlaceholderValueGroupLabel, defaultPlaceholderValueLabel, defaultPlaceholderValueName, defaultRuleGroupProcessorCEL, defaultRuleGroupProcessorDrizzle, defaultRuleGroupProcessorElasticSearch, defaultRuleGroupProcessorJSONata, defaultRuleGroupProcessorJsonLogic, defaultRuleGroupProcessorLDAP, defaultRuleGroupProcessorMongoDB, defaultRuleGroupProcessorMongoDBQuery, defaultRuleGroupProcessorNL, defaultRuleGroupProcessorParameterized, defaultRuleGroupProcessorPrisma, defaultRuleGroupProcessorSQL, defaultRuleGroupProcessorSequelize, defaultRuleGroupProcessorSpEL, defaultRuleProcessorCEL, defaultRuleProcessorDrizzle, defaultRuleProcessorElasticSearch, defaultRuleProcessorJSONata, defaultRuleProcessorJsonLogic, defaultRuleProcessorLDAP, defaultRuleProcessorMongoDB, defaultRuleProcessorMongoDBQuery, defaultRuleProcessorNL, defaultRuleProcessorParameterized, defaultRuleProcessorPrisma, defaultRuleProcessorSQL, defaultRuleProcessorSequelize, defaultRuleProcessorSpEL, defaultSpELValueProcessor, defaultTranslations, defaultValidator, defaultValueProcessor, defaultValueProcessorByRule, defaultValueProcessorCELByRule, defaultValueProcessorMongoDBByRule, defaultValueProcessorNL, defaultValueProcessorSpELByRule, filterFieldsByComparator, findID, findPath, formatQuery, formatQueryOptionPresets, generateAccessibleDescription, generateID, getCommonAncestorPath, getFirstOption, getMatchModesUtil, getNLTranslataion, getOption, getParentPath, getParseNumberMethod, getPathOfID, getQuoteFieldNamesWithArray, getQuotedFieldName, getValidationClassNames, getValueSourcesUtil, group, groupInPlace, groupInvalidReasons, insert, insertInPlace, isAncestor, isFlexibleOptionArray, isFlexibleOptionGroupArray, isFullOptionArray, isFullOptionGroupArray, isOptionGroupArray, isPojo, isRuleGroup, isRuleGroupType, isRuleGroupTypeIC, isRuleOrGroupValid, isRuleType, isUnsafeKey, isValidValue, isValidationResult, isValueProcessorLegacy, joinWith, jsonLogicAdditionalOperators, lc, mapSQLOperator, mergeAnyTranslation, mergeAnyTranslations, mergeClassnames, mongoDbFallback, mongoOperators, move, moveInPlace, normalizeConstituentWordOrder, nullFreeArray, nullOrUndefinedOrEmpty, numericRegex, numerifyValues, objectEntries, objectKeys, parseNumber, pathIsDisabled, pathsAreEqual, preferAnyProp, preferFlagProps, preferProp, prepareOptionList, prepareRule, prepareRuleGroup, prepareRuleOrGroup, prismaFallback, prismaOperators, processMatchMode, queryBuilderFlagDefaults, regenerateID, regenerateIDs, remove, removeInPlace, rootPath, shouldRenderAsNumber, splitBy, sqlDialectPresets, standardClassnames, toArray, toFlatOptionArray, toFullOption, toFullOptionList, toFullOptionMap, transformQuery, trimIfString, uniqByIdentifier, uniqByName, uniqOptGroups, uniqOptList, update, updateInPlace };
4286
+
4236
4287
  //# sourceMappingURL=react-querybuilder_core.mjs.map