@react-querybuilder/core 8.21.2 → 8.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +1399 -44
  3. package/dist/cjs/react-querybuilder_core.cjs.development.js +2244 -87
  4. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  5. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +1399 -44
  6. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  7. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  8. package/dist/formatQuery.js +47 -38
  9. package/dist/formatQuery.js.map +1 -1
  10. package/dist/formatQuery.mjs +47 -38
  11. package/dist/formatQuery.mjs.map +1 -1
  12. package/dist/parseCEL.js +6 -8
  13. package/dist/parseCEL.js.map +1 -1
  14. package/dist/parseCEL.mjs +6 -8
  15. package/dist/parseCEL.mjs.map +1 -1
  16. package/dist/parseCypher.js.map +1 -1
  17. package/dist/parseJSONata.js +2 -2
  18. package/dist/parseJSONata.js.map +1 -1
  19. package/dist/parseJSONata.mjs +1 -1
  20. package/dist/parseJsonLogic.js +3 -3
  21. package/dist/parseJsonLogic.js.map +1 -1
  22. package/dist/parseJsonLogic.mjs +3 -3
  23. package/dist/parseJsonLogic.mjs.map +1 -1
  24. package/dist/parseMongoDB.js +2 -2
  25. package/dist/parseMongoDB.mjs +2 -2
  26. package/dist/parseSPARQL.js +0 -1
  27. package/dist/parseSPARQL.js.map +1 -1
  28. package/dist/parseSPARQL.mjs +0 -1
  29. package/dist/parseSPARQL.mjs.map +1 -1
  30. package/dist/parseSQL.js +54 -62
  31. package/dist/parseSQL.js.map +1 -1
  32. package/dist/parseSQL.mjs +54 -62
  33. package/dist/parseSQL.mjs.map +1 -1
  34. package/dist/parseSpEL.js +3 -3
  35. package/dist/parseSpEL.js.map +1 -1
  36. package/dist/parseSpEL.mjs +3 -3
  37. package/dist/parseSpEL.mjs.map +1 -1
  38. package/dist/{prepareQueryObjects-C5dHLhnC.js → prepareQueryObjects-BnGL91Tt.js} +9 -5
  39. package/dist/{prepareQueryObjects-C5dHLhnC.js.map → prepareQueryObjects-BnGL91Tt.js.map} +1 -1
  40. package/dist/{prepareQueryObjects-9emVAGYG.mjs → prepareQueryObjects-ChINDIap.mjs} +9 -5
  41. package/dist/{prepareQueryObjects-9emVAGYG.mjs.map → prepareQueryObjects-ChINDIap.mjs.map} +1 -1
  42. package/dist/query-builder-layout.css +1 -1
  43. package/dist/query-builder-layout.css.map +1 -1
  44. package/dist/query-builder.css +1 -1
  45. package/dist/query-builder.css.map +1 -1
  46. package/dist/react-querybuilder_core.d.mts +1399 -44
  47. package/dist/react-querybuilder_core.legacy-esm.d.ts +1399 -44
  48. package/dist/react-querybuilder_core.legacy-esm.js +2266 -81
  49. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  50. package/dist/react-querybuilder_core.mjs +2202 -89
  51. package/dist/react-querybuilder_core.mjs.map +1 -1
  52. package/dist/react-querybuilder_core.production.d.mts +1399 -44
  53. package/dist/react-querybuilder_core.production.mjs +1 -1
  54. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  55. package/dist/styles/_layout.scss +5 -2
  56. package/dist/{utils-CxWs-N47.mjs → utils-4k-j5FBa.mjs} +4 -2
  57. package/dist/utils-4k-j5FBa.mjs.map +1 -0
  58. package/dist/{utils-SchkzSCN.js → utils-C79dxwZb.js} +4 -2
  59. package/dist/utils-C79dxwZb.js.map +1 -0
  60. package/package.json +9 -8
  61. package/dist/utils-CxWs-N47.mjs.map +0 -1
  62. package/dist/utils-SchkzSCN.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { numericQuantity, numericRegex as numericRegex$1 } from "numeric-quantity";
2
- import { current, isDraft, produce } from "immer";
2
+ import { current, freeze, isDraft, produce } from "immer";
3
3
  //#region src/defaults.ts
4
4
  /**
5
5
  * @group Defaults
@@ -130,6 +130,14 @@ const defaultTranslations = {
130
130
  label: "˅",
131
131
  title: "Shift down"
132
132
  },
133
+ undo: {
134
+ label: "↶",
135
+ title: "Undo"
136
+ },
137
+ redo: {
138
+ label: "↷",
139
+ title: "Redo"
140
+ },
133
141
  dragHandle: {
134
142
  label: "⁞⁞",
135
143
  title: "Drag handle"
@@ -454,6 +462,9 @@ const standardClassnames = {
454
462
  valid: "queryBuilder-valid",
455
463
  invalid: "queryBuilder-invalid",
456
464
  shiftActions: "shiftActions",
465
+ undoRedoActions: "undoRedoActions",
466
+ undoAction: "undoRedoActions-undo",
467
+ redoAction: "undoRedoActions-redo",
457
468
  dndDragging: "dndDragging",
458
469
  dndOver: "dndOver",
459
470
  dndCopy: "dndCopy",
@@ -502,6 +513,9 @@ const defaultControlClassnames = {
502
513
  value: "",
503
514
  removeRule: "",
504
515
  shiftActions: "",
516
+ undoRedoActions: "",
517
+ undoAction: "",
518
+ redoAction: "",
505
519
  dragHandle: "",
506
520
  lockRule: "",
507
521
  lockGroup: "",
@@ -559,6 +573,9 @@ const TestID = {
559
573
  valueEditor: "value-editor",
560
574
  notToggle: "not-toggle",
561
575
  shiftActions: "shift-actions",
576
+ undoRedoActions: "undo-redo-actions",
577
+ undoAction: "undo-action",
578
+ redoAction: "redo-action",
562
579
  dragHandle: "drag-handle",
563
580
  lockRule: "lock-rule",
564
581
  lockGroup: "lock-group",
@@ -605,6 +622,7 @@ const queryBuilderFlagDefaults = {
605
622
  enableDragAndDrop: false,
606
623
  enableMountQueryChange: true,
607
624
  listsAsArrays: false,
625
+ preserveQueryStateOnUnmount: false,
608
626
  resetOnFieldChange: true,
609
627
  resetOnOperatorChange: false,
610
628
  showCloneButtons: false,
@@ -613,8 +631,22 @@ const queryBuilderFlagDefaults = {
613
631
  showMuteButtons: false,
614
632
  showNotToggle: false,
615
633
  showShiftActions: false,
634
+ showUndoRedo: false,
616
635
  suppressStandardClassnames: false
617
636
  };
637
+ /**
638
+ * Default maximum number of undo steps retained by query history.
639
+ *
640
+ * @group Defaults
641
+ */
642
+ const defaultMaxHistory = 50;
643
+ /**
644
+ * Default time window (in milliseconds) within which consecutive changes to the same
645
+ * property of the same rule are coalesced into a single undo step.
646
+ *
647
+ * @group Defaults
648
+ */
649
+ const defaultCoalesceMs = 500;
618
650
  //#endregion
619
651
  //#region src/utils/arrayUtils.ts
620
652
  /**
@@ -718,7 +750,7 @@ const isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "str
718
750
  */
719
751
  const isRuleGroupTypeIC = (rg) => isRuleGroup(rg) && rg.combinator === void 0;
720
752
  //#endregion
721
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/typeof.js
753
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/typeof.js
722
754
  function _typeof(o) {
723
755
  "@babel/helpers - typeof";
724
756
  return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) {
@@ -728,7 +760,7 @@ function _typeof(o) {
728
760
  }, _typeof(o);
729
761
  }
730
762
  //#endregion
731
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPrimitive.js
763
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/toPrimitive.js
732
764
  function toPrimitive(t, r) {
733
765
  if ("object" != _typeof(t) || !t) return t;
734
766
  var e = t[Symbol.toPrimitive];
@@ -740,13 +772,13 @@ function toPrimitive(t, r) {
740
772
  return ("string" === r ? String : Number)(t);
741
773
  }
742
774
  //#endregion
743
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/toPropertyKey.js
775
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/toPropertyKey.js
744
776
  function toPropertyKey(t) {
745
777
  var i = toPrimitive(t, "string");
746
778
  return "symbol" == _typeof(i) ? i : i + "";
747
779
  }
748
780
  //#endregion
749
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/defineProperty.js
781
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/defineProperty.js
750
782
  function _defineProperty(e, r, t) {
751
783
  return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
752
784
  value: t,
@@ -756,7 +788,7 @@ function _defineProperty(e, r, t) {
756
788
  }) : e[r] = t, e;
757
789
  }
758
790
  //#endregion
759
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/objectSpread2.js
791
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/objectSpread2.js
760
792
  function ownKeys(e, r) {
761
793
  var t = Object.keys(e);
762
794
  if (Object.getOwnPropertySymbols) {
@@ -779,7 +811,7 @@ function _objectSpread2(e) {
779
811
  return e;
780
812
  }
781
813
  //#endregion
782
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/objectWithoutPropertiesLoose.js
814
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/objectWithoutPropertiesLoose.js
783
815
  function _objectWithoutPropertiesLoose(r, e) {
784
816
  if (null == r) return {};
785
817
  var t = {};
@@ -790,7 +822,7 @@ function _objectWithoutPropertiesLoose(r, e) {
790
822
  return t;
791
823
  }
792
824
  //#endregion
793
- //#region \0@oxc-project+runtime@0.140.0/helpers/esm/objectWithoutProperties.js
825
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/objectWithoutProperties.js
794
826
  function _objectWithoutProperties(e, t) {
795
827
  if (null == e) return {};
796
828
  var o, r, i = _objectWithoutPropertiesLoose(e, t);
@@ -802,7 +834,7 @@ function _objectWithoutProperties(e, t) {
802
834
  }
803
835
  //#endregion
804
836
  //#region src/utils/convertQuery.ts
805
- const _excluded = ["combinator"];
837
+ const _excluded$1 = ["combinator"];
806
838
  const combinatorLevels = [
807
839
  "or",
808
840
  "xor",
@@ -862,7 +894,7 @@ const convertFromIC = (rg) => {
862
894
  */
863
895
  const convertToIC = (rg) => {
864
896
  if (isRuleGroupTypeIC(rg)) return rg;
865
- const { combinator } = rg, queryWithoutCombinator = _objectWithoutProperties(rg, _excluded);
897
+ const { combinator } = rg, queryWithoutCombinator = _objectWithoutProperties(rg, _excluded$1);
866
898
  const rules = [];
867
899
  const { length } = rg.rules;
868
900
  for (let idx = 0; idx < length; idx++) {
@@ -877,6 +909,208 @@ function convertQuery(query) {
877
909
  return isRuleGroupTypeIC(query) ? convertFromIC(query) : convertToIC(query);
878
910
  }
879
911
  //#endregion
912
+ //#region src/utils/deriveClassNames.ts
913
+ const ruleClassnameSources = {
914
+ shiftActions: ["shiftActions"],
915
+ dragHandle: ["dragHandle"],
916
+ fields: ["valueSelector", "fields"],
917
+ matchMode: ["valueSelector", "matchMode"],
918
+ matchThreshold: ["valueSelector", "matchThreshold"],
919
+ operators: ["valueSelector", "operators"],
920
+ valueSource: ["valueSelector", "valueSource"],
921
+ value: ["value"],
922
+ cloneRule: ["actionElement", "cloneRule"],
923
+ lockRule: ["actionElement", "lockRule"],
924
+ muteRule: ["actionElement", "muteRule"],
925
+ removeRule: ["actionElement", "removeRule"],
926
+ valueListItem: ["valueListItem"]
927
+ };
928
+ const ruleGroupClassnameSources = {
929
+ header: {
930
+ sources: ["header"],
931
+ conditions: [
932
+ {
933
+ key: "dndOver",
934
+ when: (s) => s.isOver,
935
+ standardOnly: true
936
+ },
937
+ {
938
+ key: "dndCopy",
939
+ when: (s) => s.isOver && s.dropEffect === "copy"
940
+ },
941
+ {
942
+ key: "dndDropNotAllowed",
943
+ when: (s) => s.dropNotAllowed
944
+ }
945
+ ]
946
+ },
947
+ shiftActions: ["shiftActions"],
948
+ undoRedoActions: ["undoRedoActions"],
949
+ undoAction: ["actionElement", "undoAction"],
950
+ redoAction: ["actionElement", "redoAction"],
951
+ dragHandle: ["dragHandle"],
952
+ combinators: ["valueSelector", "combinators"],
953
+ notToggle: ["notToggle"],
954
+ addRule: ["actionElement", "addRule"],
955
+ addGroup: ["actionElement", "addGroup"],
956
+ cloneGroup: ["actionElement", "cloneGroup"],
957
+ lockGroup: ["actionElement", "lockGroup"],
958
+ muteGroup: ["actionElement", "muteGroup"],
959
+ removeGroup: ["actionElement", "removeGroup"],
960
+ body: ["body"]
961
+ };
962
+ /**
963
+ * Conditional classes applied to a rule's wrapper element.
964
+ *
965
+ * Note that this is deliberately _not_ the same set as {@link ruleGroupOuterConditions}: a rule
966
+ * reflects more drag-and-drop states than a group does. Declaring each set separately is what
967
+ * keeps an implementation from assuming they're symmetric.
968
+ */
969
+ const ruleOuterConditions = [
970
+ {
971
+ key: "disabled",
972
+ when: (s) => s.disabled
973
+ },
974
+ {
975
+ key: "muted",
976
+ when: (s) => s.muted
977
+ },
978
+ {
979
+ key: "dndDragging",
980
+ when: (s) => s.isDragging
981
+ },
982
+ {
983
+ key: "dndOver",
984
+ when: (s) => s.isOver
985
+ },
986
+ {
987
+ key: "dndCopy",
988
+ when: (s) => s.isOver && s.dropEffect === "copy"
989
+ },
990
+ {
991
+ key: "dndGroup",
992
+ when: (s) => s.isOver && s.groupItems
993
+ },
994
+ {
995
+ key: "dndDropNotAllowed",
996
+ when: (s) => s.dropNotAllowed
997
+ },
998
+ {
999
+ key: "hasSubQuery",
1000
+ when: (s) => s.hasSubQuery
1001
+ }
1002
+ ];
1003
+ /** Conditional classes applied to a rule group's wrapper element. */
1004
+ const ruleGroupOuterConditions = [
1005
+ {
1006
+ key: "disabled",
1007
+ when: (s) => s.disabled
1008
+ },
1009
+ {
1010
+ key: "muted",
1011
+ when: (s) => s.muted
1012
+ },
1013
+ {
1014
+ key: "dndDragging",
1015
+ when: (s) => s.isDragging
1016
+ },
1017
+ {
1018
+ key: "dndGroup",
1019
+ when: (s) => s.isOver && s.groupItems
1020
+ }
1021
+ ];
1022
+ /**
1023
+ * Conditional classes applied to the query builder's wrapper element.
1024
+ *
1025
+ * Only a `boolean` validation result contributes a class; a {@link ValidationMap} describes
1026
+ * individual rules and groups, not the query as a whole.
1027
+ */
1028
+ const queryBuilderOuterConditions = [
1029
+ {
1030
+ key: "disabled",
1031
+ when: (s) => s.disabled
1032
+ },
1033
+ {
1034
+ key: "valid",
1035
+ when: (s) => typeof s.validationResult === "boolean" && s.validationResult
1036
+ },
1037
+ {
1038
+ key: "invalid",
1039
+ when: (s) => typeof s.validationResult === "boolean" && !s.validationResult
1040
+ }
1041
+ ];
1042
+ /**
1043
+ * Expands conditions into `clsx` arguments: every custom class first (in declaration order),
1044
+ * then a single object of standard classes.
1045
+ */
1046
+ const conditionArgs = (conditions, state, { classNames, suppressStandardClassnames }) => {
1047
+ const evaluated = conditions.map((condition) => [condition, !!condition.when(state)]);
1048
+ return [...evaluated.filter(([condition]) => !condition.standardOnly).map(([condition, active]) => active && (classNames === null || classNames === void 0 ? void 0 : classNames[condition.key])), suppressStandardClassnames || Object.fromEntries(evaluated.map(([condition, active]) => [standardClassnames[condition.key], active]))];
1049
+ };
1050
+ /** Composes the classname for a single entry of a spec map. */
1051
+ const deriveFromSpec = (key, spec, state, options) => {
1052
+ const { sources, conditions } = Array.isArray(spec) ? { sources: spec } : spec;
1053
+ return clsx(options.suppressStandardClassnames || standardClassnames[key], ...sources.map((source) => {
1054
+ var _options$classNames;
1055
+ return (_options$classNames = options.classNames) === null || _options$classNames === void 0 ? void 0 : _options$classNames[source];
1056
+ }), ...conditions ? conditionArgs(conditions, state, options) : []);
1057
+ };
1058
+ const deriveFromSpecs = (specs, state, options) => {
1059
+ const result = {};
1060
+ for (const [key, spec] of Object.entries(specs)) result[key] = deriveFromSpec(key, spec, state, options);
1061
+ return result;
1062
+ };
1063
+ /**
1064
+ * Classnames for each element rendered by a rule. This is the framework-agnostic core of the
1065
+ * `classNames` object returned by the `useRule` hook.
1066
+ *
1067
+ * @group Query Tools
1068
+ */
1069
+ const deriveRuleClassNames = (options) => deriveFromSpecs(ruleClassnameSources, {}, options);
1070
+ /**
1071
+ * The classname for a single element of a rule, composed from the same table as
1072
+ * {@link deriveRuleClassNames}. Useful where only one is needed, such as the items of a
1073
+ * multi-value editor.
1074
+ *
1075
+ * @group Query Tools
1076
+ */
1077
+ const deriveRuleClassName = (key, options) => deriveFromSpec(key, ruleClassnameSources[key], {}, options);
1078
+ /**
1079
+ * Classnames for each element rendered by a rule group, including its conditionally-classed
1080
+ * `header`. This is the framework-agnostic core of the `classNames` object returned by the
1081
+ * `useRuleGroup` hook.
1082
+ *
1083
+ * @group Query Tools
1084
+ */
1085
+ const deriveRuleGroupClassNames = (options) => deriveFromSpecs(ruleGroupClassnameSources, options, options);
1086
+ const deriveOuterClassName = (standardKey, conditions, options) => {
1087
+ const { classNames, suppressStandardClassnames, leadingClassNames = [], validationClassName } = options;
1088
+ return clsx(...leadingClassNames, suppressStandardClassnames || standardClassnames[standardKey], classNames === null || classNames === void 0 ? void 0 : classNames[standardKey], ...conditionArgs(conditions, options, options), validationClassName);
1089
+ };
1090
+ /**
1091
+ * The outer (wrapper) classname for a rule, including every conditional state class.
1092
+ *
1093
+ * @group Query Tools
1094
+ */
1095
+ const deriveRuleOuterClassName = (options) => deriveOuterClassName("rule", ruleOuterConditions, options);
1096
+ /**
1097
+ * The outer (wrapper) classname for a rule group, including every conditional state class.
1098
+ *
1099
+ * A group reflects fewer drag-and-drop states than a rule—`dndOver`, `dndCopy`,
1100
+ * `dndDropNotAllowed`, and `hasSubQuery` do not apply—so this is not interchangeable with
1101
+ * {@link deriveRuleOuterClassName}.
1102
+ *
1103
+ * @group Query Tools
1104
+ */
1105
+ const deriveRuleGroupOuterClassName = (options) => deriveOuterClassName("ruleGroup", ruleGroupOuterConditions, options);
1106
+ /**
1107
+ * The outer (wrapper) classname for the query builder itself, including the conditional
1108
+ * `disabled`, `valid`, and `invalid` state classes.
1109
+ *
1110
+ * @group Query Tools
1111
+ */
1112
+ const deriveQueryBuilderClassNames = (options) => deriveOuterClassName("queryBuilder", queryBuilderOuterConditions, options);
1113
+ //#endregion
880
1114
  //#region src/utils/defaultValidator.ts
881
1115
  /**
882
1116
  * This is an example validation function you can pass to {@link react-querybuilder!QueryBuilder QueryBuilder} in the
@@ -1183,7 +1417,7 @@ const filterFieldsByComparator = (field, fields, operator) => {
1183
1417
  if (!field.comparator) {
1184
1418
  const filterOutSameField = (f) => {
1185
1419
  var _f$value, _field$value;
1186
- return ((_f$value = f.value) !== null && _f$value !== void 0 ? _f$value : /* v8 ignore start -- @preserve */ f.name) !== ((_field$value = field.value) !== null && _field$value !== void 0 ? _field$value :
1420
+ return ((_f$value = f.value) !== null && _f$value !== void 0 ? _f$value : /* v8 ignore start -- @preserve */ f.name) !== ((_field$value = field.value) !== null && _field$value !== void 0 ? _field$value :
1187
1421
  /* v8 ignore start -- @preserve */ field.name);
1188
1422
  };
1189
1423
  if (isFlexibleOptionGroupArray(fields)) return fields.map((og) => _objectSpread2(_objectSpread2({}, og), {}, { options: og.options.filter((v) => filterOutSameField(v)) }));
@@ -1193,6 +1427,142 @@ const filterFieldsByComparator = (field, fields, operator) => {
1193
1427
  return fields.filter((f) => filterByComparator(field, operator, f));
1194
1428
  };
1195
1429
  //#endregion
1430
+ //#region src/utils/deriveRuleContext.ts
1431
+ /**
1432
+ * Resolves the field configuration for a rule's `field`, falling back to a minimal option object
1433
+ * when the field isn't present in the field map.
1434
+ */
1435
+ const getFieldData = (field, fieldMap) => {
1436
+ var _fieldMap$field;
1437
+ return (_fieldMap$field = fieldMap === null || fieldMap === void 0 ? void 0 : fieldMap[field]) !== null && _fieldMap$field !== void 0 ? _fieldMap$field : {
1438
+ name: field,
1439
+ value: field,
1440
+ label: field
1441
+ };
1442
+ };
1443
+ /**
1444
+ * The input type for a rule. A field's own `inputType` takes precedence over `getInputType`.
1445
+ */
1446
+ const getRuleInputType = (field, operator, fieldData, getInputType) => {
1447
+ var _fieldData$inputType;
1448
+ return (_fieldData$inputType = fieldData.inputType) !== null && _fieldData$inputType !== void 0 ? _fieldData$inputType : getInputType(field, operator, { fieldData });
1449
+ };
1450
+ /**
1451
+ * Whether the value editor(s) should be hidden for an operator, based on its `arity`.
1452
+ */
1453
+ const hideValueControlsForOperator = (operatorObject) => {
1454
+ const arity = operatorObject === null || operatorObject === void 0 ? void 0 : operatorObject.arity;
1455
+ return typeof arity === "string" && arity === "unary" || typeof arity === "number" && arity < 2;
1456
+ };
1457
+ /**
1458
+ * Value source options for a rule. A `valueSource` present on the rule but absent from the
1459
+ * configured list is appended, so the current selection is always representable.
1460
+ */
1461
+ const getRuleValueSourceOptions = (rule, fieldData, getValueSources) => {
1462
+ const configuredVSs = getValueSources(rule.field, rule.operator, { fieldData });
1463
+ if (rule.valueSource && !getOption(configuredVSs, rule.valueSource)) return [...configuredVSs, {
1464
+ name: rule.valueSource,
1465
+ value: rule.valueSource,
1466
+ label: rule.valueSource
1467
+ }];
1468
+ return configuredVSs;
1469
+ };
1470
+ /**
1471
+ * Normalizes the result of `getParameters` to a non-empty list or `null`.
1472
+ */
1473
+ const getParametersAsList = (parameters) => parameters && parameters.length > 0 ? parameters : null;
1474
+ /**
1475
+ * The value editor type for a rule. `valueSource: "field"` always uses a select list, and
1476
+ * `valueSource: "parameter"` uses a (multi)select when parameters are available.
1477
+ */
1478
+ const getRuleValueEditorType = (rule, fieldData, parametersAsList, getValueEditorType) => rule.valueSource === "field" ? "select" : rule.valueSource === "parameter" ? parametersAsList ? lc(rule.operator) === "in" || lc(rule.operator) === "notin" ? "multiselect" : "select" : "text" : getValueEditorType(rule.field, rule.operator, { fieldData });
1479
+ /**
1480
+ * The option list presented by a rule's value editor, resolved from its `valueSource`.
1481
+ */
1482
+ const getRuleValues = (rule, fieldData, fields, parametersAsList, getValues) => {
1483
+ const v = rule.valueSource === "field" ? filterFieldsByComparator(fieldData, fields, rule.operator) : rule.valueSource === "parameter" ? parametersAsList !== null && parametersAsList !== void 0 ? parametersAsList : [] : getValues(rule.field, rule.operator, { fieldData });
1484
+ return isFlexibleOptionArray(v) || isFlexibleOptionGroupArray(v) ? toFullOptionList(v) : v;
1485
+ };
1486
+ /**
1487
+ * The validation result for a rule: the entry from a query-level {@link ValidationMap} if present,
1488
+ * otherwise the field's own `validator` result, otherwise `null`.
1489
+ */
1490
+ const getRuleValidationResult = (rule, fieldData, validationMap = {}, id = ((_rule$id) => (_rule$id = rule.id) !== null && _rule$id !== void 0 ? _rule$id : "")()) => {
1491
+ var _validationMap$id;
1492
+ return (_validationMap$id = validationMap[id]) !== null && _validationMap$id !== void 0 ? _validationMap$id : typeof fieldData.validator === "function" ? fieldData.validator(rule) : null;
1493
+ };
1494
+ /**
1495
+ * Resolves everything about a single rule that depends on the field/operator configuration:
1496
+ * its field data, operators, value editor type, value list, value sources, match modes, and
1497
+ * validation result.
1498
+ *
1499
+ * This is the framework-agnostic core of the `useRule` hook, shared with
1500
+ * {@link QueryManager.getRuleContext} so that non-React implementations derive identical results.
1501
+ * It performs no memoization; callers are responsible for caching as appropriate.
1502
+ *
1503
+ * @group Query Tools
1504
+ */
1505
+ const deriveRuleContext = (rule, resolvers, options = {}) => {
1506
+ var _fieldData$inputType2, _getSubQueryBuilderPr;
1507
+ const { fields, fieldMap, getInputType, getMatchModes, getOperators, getParameters, getValueEditorType, getValues, getValueSources, getSubQueryBuilderProps } = resolvers;
1508
+ const fieldData = getFieldData(rule.field, fieldMap);
1509
+ const inputType = (_fieldData$inputType2 = fieldData.inputType) !== null && _fieldData$inputType2 !== void 0 ? _fieldData$inputType2 : getInputType(rule.field, rule.operator, { fieldData });
1510
+ const matchModes = getMatchModes(rule.field, { fieldData });
1511
+ const operators = getOperators(rule.field, { fieldData });
1512
+ const operatorObject = getOption(operators, rule.operator);
1513
+ const valueSourceOptions = getRuleValueSourceOptions(rule, fieldData, getValueSources);
1514
+ const parameters = getParametersAsList(getParameters(rule.field, rule.operator, { fieldData }));
1515
+ return {
1516
+ fieldData,
1517
+ hideValueControls: hideValueControlsForOperator(operatorObject),
1518
+ inputType,
1519
+ matchModes,
1520
+ operatorObject,
1521
+ operators,
1522
+ parameters,
1523
+ validationResult: getRuleValidationResult(rule, fieldData, options.validationMap, options.id),
1524
+ valueEditorType: getRuleValueEditorType(rule, fieldData, parameters, getValueEditorType),
1525
+ values: getRuleValues(rule, fieldData, fields, parameters, getValues),
1526
+ valueSourceOptions,
1527
+ valueSources: valueSourceOptions.map(({ value }) => value),
1528
+ subQueryBuilderProps: (_getSubQueryBuilderPr = getSubQueryBuilderProps === null || getSubQueryBuilderProps === void 0 ? void 0 : getSubQueryBuilderProps(rule.field, { fieldData })) !== null && _getSubQueryBuilderPr !== void 0 ? _getSubQueryBuilderPr : {}
1529
+ };
1530
+ };
1531
+ /**
1532
+ * The effective combinator for a group: its own `combinator` when it has one, otherwise the
1533
+ * first configured combinator (which is the case for groups with independent combinators).
1534
+ *
1535
+ * This intentionally covers only the current property-based API. The `RuleGroup` component
1536
+ * additionally falls back to its deprecated `combinator` prop; that fallback stays in the hook.
1537
+ */
1538
+ const getRuleGroupCombinator = (ruleGroup, combinators) => {
1539
+ var _getFirstOption;
1540
+ return isRuleGroupType(ruleGroup) ? ruleGroup.combinator : (_getFirstOption = getFirstOption(combinators)) !== null && _getFirstOption !== void 0 ? _getFirstOption : "";
1541
+ };
1542
+ /**
1543
+ * Resolves everything about a rule group that depends on the combinator configuration, plus its
1544
+ * validation result.
1545
+ *
1546
+ * Note that unlike {@link deriveRuleContext}, there is no field-level validator fallback—a
1547
+ * group's validation result comes only from the query-level {@link ValidationMap}.
1548
+ *
1549
+ * @group Query Tools
1550
+ */
1551
+ const deriveRuleGroupContext = (ruleGroup, combinators, options = {}) => {
1552
+ var _combinatorObject$cla, _ref, _options$validationMa, _ref2, _options$id;
1553
+ const independentCombinators = isRuleGroupTypeIC(ruleGroup);
1554
+ const combinator = getRuleGroupCombinator(ruleGroup, combinators);
1555
+ const combinatorObject = getOption(combinators, combinator);
1556
+ return {
1557
+ combinator,
1558
+ combinatorObject,
1559
+ combinators,
1560
+ combinatorBasedClassName: independentCombinators ? null : (_combinatorObject$cla = combinatorObject === null || combinatorObject === void 0 ? void 0 : combinatorObject.className) !== null && _combinatorObject$cla !== void 0 ? _combinatorObject$cla : "",
1561
+ independentCombinators,
1562
+ validationResult: (_ref = ((_options$validationMa = options.validationMap) !== null && _options$validationMa !== void 0 ? _options$validationMa : {})[(_ref2 = (_options$id = options.id) !== null && _options$id !== void 0 ? _options$id : ruleGroup.id) !== null && _ref2 !== void 0 ? _ref2 : ""]) !== null && _ref !== void 0 ? _ref : null
1563
+ };
1564
+ };
1565
+ //#endregion
1196
1566
  //#region src/utils/parseNumber.ts
1197
1567
  /**
1198
1568
  * Converts a string to a number. Uses native `parseFloat` if `parseNumbers` is "native",
@@ -1212,6 +1582,108 @@ const parseNumber = (val, { parseNumbers, bigIntOnOverflow } = {}) => {
1212
1582
  return typeof valAsNum === "bigint" || !Number.isNaN(valAsNum) ? valAsNum : val;
1213
1583
  };
1214
1584
  //#endregion
1585
+ //#region src/utils/deriveValueEditor.ts
1586
+ /** Operators whose value is a list rather than a single scalar. */
1587
+ const multiValueOperators = /* @__PURE__ */ new Set([
1588
+ "between",
1589
+ "notBetween",
1590
+ "in",
1591
+ "notIn"
1592
+ ]);
1593
+ /**
1594
+ * Whether an operator's value is a list of two bounds.
1595
+ *
1596
+ * @group Value Editors
1597
+ */
1598
+ const isBetweenOperator = (operator) => operator === "between" || operator === "notBetween";
1599
+ /**
1600
+ * Determines whether a rule's `value` needs to be collapsed to a single element because it no
1601
+ * longer represents a list, and what it should become.
1602
+ *
1603
+ * This happens when the value is an array (or a comma-containing string in a `number` input,
1604
+ * which `<input type="number">` can't display) while the operator is not one of the multi-value
1605
+ * operators and the editor is not a multiselect—typically right after the operator changes from
1606
+ * `"in"` or `"between"` to something else.
1607
+ *
1608
+ * The React `useValueEditor` hook applies the result in an effect; other implementations may
1609
+ * apply it wherever is idiomatic.
1610
+ *
1611
+ * @group Value Editors
1612
+ */
1613
+ const getValueEditorReset = ({ skipHook, type, operator, value, inputType }) => {
1614
+ var _toArray$;
1615
+ return !skipHook && type !== "multiselect" && !multiValueOperators.has(operator) && (Array.isArray(value) || inputType === "number" && typeof value === "string" && value.includes(",")) ? {
1616
+ reset: true,
1617
+ value: (_toArray$ = toArray(value, { retainEmptyStrings: true })[0]) !== null && _toArray$ !== void 0 ? _toArray$ : ""
1618
+ } : {
1619
+ reset: false,
1620
+ value
1621
+ };
1622
+ };
1623
+ /**
1624
+ * Produces the next value for a series of value editors when the editor at `index` changes.
1625
+ *
1626
+ * For `between`/`notBetween`, editing the first bound guarantees an array of at least two
1627
+ * elements, seeding the second from the first available option. The result is a comma-joined
1628
+ * string unless `listsAsArrays` is `true`.
1629
+ *
1630
+ * @group Value Editors
1631
+ */
1632
+ const getMultiValueUpdate = ({ value, index, valueAsArray, operator, values, listsAsArrays, parseNumberMethod }) => {
1633
+ const parsedVal = parseNumber(value, { parseNumbers: parseNumberMethod });
1634
+ const needsBetweenFix = index === 0 && isBetweenOperator(operator) && (valueAsArray.length < 2 || valueAsArray[1] === void 0);
1635
+ if (valueAsArray[index] === parsedVal && !needsBetweenFix) return listsAsArrays ? valueAsArray : joinWith(valueAsArray, ",");
1636
+ const v = [...valueAsArray];
1637
+ v[index] = parsedVal;
1638
+ if (needsBetweenFix) {
1639
+ var _getFirstOption;
1640
+ v[1] = (_getFirstOption = getFirstOption(values)) !== null && _getFirstOption !== void 0 ? _getFirstOption : "";
1641
+ }
1642
+ return listsAsArrays ? v : joinWith(v, ",");
1643
+ };
1644
+ /**
1645
+ * Coerces a value to a `bigint`, falling back to the parsed number when it can't be represented
1646
+ * as one (an empty string or a decimal, for example).
1647
+ *
1648
+ * @group Value Editors
1649
+ */
1650
+ const coerceBigIntValue = (value, parseNumberMethod) => {
1651
+ const valAsMaybeNumber = parseNumber(value, {
1652
+ parseNumbers: parseNumberMethod,
1653
+ bigIntOnOverflow: true
1654
+ });
1655
+ try {
1656
+ return BigInt(valAsMaybeNumber);
1657
+ } catch (_unused) {
1658
+ return valAsMaybeNumber;
1659
+ }
1660
+ };
1661
+ /**
1662
+ * The `type` attribute an `<input>` should use for a rule. `bigint` values and the `in`/`notIn`
1663
+ * operators (whose value is a comma-separated list) both require a text input.
1664
+ *
1665
+ * @group Value Editors
1666
+ */
1667
+ const coerceInputType = (inputType, operator) => inputType === "bigint" || operator === "in" || operator === "notIn" ? "text" : inputType || "text";
1668
+ /**
1669
+ * Produces the next value for a value selector. Multiselect values are normalized to an array
1670
+ * first, then comma-joined unless `listsAsArrays` is `true`. Single-select values pass through.
1671
+ *
1672
+ * @group Value Editors
1673
+ */
1674
+ const getValueSelectorUpdate = (value, { multiple, listsAsArrays } = {}) => {
1675
+ if (!multiple) return value;
1676
+ const valueAsArray = toArray(value);
1677
+ return listsAsArrays ? valueAsArray : joinWith(valueAsArray, ",");
1678
+ };
1679
+ /**
1680
+ * Normalizes a value selector's current value for display. Multiselect values become an array of
1681
+ * strings so they match option names, which are always strings (e.g. `[42]` becomes `["42"]`).
1682
+ *
1683
+ * @group Value Editors
1684
+ */
1685
+ const normalizeValueSelectorValue = (value, multiple) => multiple ? toArray(value).map(String) : value;
1686
+ //#endregion
1215
1687
  //#region src/utils/transformQuery.ts
1216
1688
  const remapProperties = (obj, propertyMap, deleteRemappedProperties) => {
1217
1689
  const result = {};
@@ -1615,7 +2087,7 @@ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
1615
2087
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1616
2088
  const processRuleGroup = (rg, outermost) => {
1617
2089
  var _rg$id;
1618
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2090
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
1619
2091
  const processedRules = [];
1620
2092
  let precedingCombinator = "";
1621
2093
  let firstRule = true;
@@ -1682,7 +2154,8 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
1682
2154
  const { mode, threshold } = matchEval;
1683
2155
  const subqueryDepth = (_opts$subqueryDepth = opts.subqueryDepth) !== null && _opts$subqueryDepth !== void 0 ? _opts$subqueryDepth : 0;
1684
2156
  const arrayElementAlias = getSubqueryElementAlias(subqueryDepth);
1685
- const nestedArrayFilter = defaultRuleGroupProcessorCEL(transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: `${arrayElementAlias}${r.field ? `.${r.field}` : ""}` }) }), _objectSpread2(_objectSpread2({}, opts), {}, { subqueryDepth: subqueryDepth + 1 }));
2157
+ const celQuery = transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: `${arrayElementAlias}${r.field ? `.${r.field}` : ""}` }) });
2158
+ const nestedArrayFilter = defaultRuleGroupProcessorCEL(celQuery, _objectSpread2(_objectSpread2({}, opts), {}, { subqueryDepth: subqueryDepth + 1 }));
1686
2159
  switch (mode) {
1687
2160
  case "all": return `${field}.all(${arrayElementAlias}, ${nestedArrayFilter})`;
1688
2161
  case "none":
@@ -1757,7 +2230,7 @@ const defaultRuleGroupProcessorMongoDBQuery = (ruleGroup, options, meta) => {
1757
2230
  const { inExpressionContext } = context !== null && context !== void 0 ? context : {};
1758
2231
  const processRuleGroup = (rg, outermost) => {
1759
2232
  var _rg$id;
1760
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? mongoDbFallback : false;
2233
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? mongoDbFallback : false;
1761
2234
  const combinator = `$${lc(rg.combinator)}`;
1762
2235
  let hasChildRules = false;
1763
2236
  const expressions = rg.rules.map((rule) => {
@@ -1923,7 +2396,7 @@ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
1923
2396
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1924
2397
  const processRuleGroup = (rg, outermost) => {
1925
2398
  var _rg$id;
1926
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2399
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
1927
2400
  const processedRules = [];
1928
2401
  let precedingCombinator = "";
1929
2402
  let firstRule = true;
@@ -2164,7 +2637,7 @@ const defaultRuleGroupProcessorCypher = (ruleGroup, options) => {
2164
2637
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2165
2638
  const processRuleGroup = (rg, outermost) => {
2166
2639
  var _rg$id;
2167
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2640
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2168
2641
  const processedRules = [];
2169
2642
  let precedingCombinator = "";
2170
2643
  let firstRule = true;
@@ -2229,7 +2702,7 @@ const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns
2229
2702
  const { and, not, or } = drizzleOperators;
2230
2703
  const processRuleGroup = (rg, _outermost) => {
2231
2704
  var _rg$id;
2232
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return;
2705
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return;
2233
2706
  const processedRules = rg.rules.map((rule) => {
2234
2707
  if (isRuleGroup(rule)) return processRuleGroup(rule);
2235
2708
  const [validationResult, fieldValidator] = validateRule(rule);
@@ -2261,7 +2734,7 @@ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
2261
2734
  const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2262
2735
  const processRuleGroup = (rg) => {
2263
2736
  var _rg$id;
2264
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return false;
2737
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return false;
2265
2738
  const processedRules = rg.rules.map((rule) => {
2266
2739
  if (isRuleGroup(rule)) return processRuleGroup(rule);
2267
2740
  const [validationResult, fieldValidator] = validateRule(rule);
@@ -2297,7 +2770,9 @@ const defaultRuleGroupProcessorGremlin = (ruleGroup, options) => {
2297
2770
  // v8 ignore next -- @preserve
2298
2771
  if (typeof rule === "string" || isRuleGroup(rule)) return void 0;
2299
2772
  const [validationResult, fieldValidator] = validateRule(rule);
2300
- if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
2773
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) ||
2774
+ /* v8 ignore next 2 -- @preserve */
2775
+ rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
2301
2776
  const fieldData = getOption(fields, rule.field);
2302
2777
  return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
2303
2778
  parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
@@ -2308,7 +2783,7 @@ const defaultRuleGroupProcessorGremlin = (ruleGroup, options) => {
2308
2783
  /** Recursively processes a nested group into `.and()`/`.or()`/`.not()` form. */
2309
2784
  const processNested = (rg) => {
2310
2785
  var _rg$id, _combinator;
2311
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return "";
2786
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return "";
2312
2787
  const predicates = [];
2313
2788
  for (const rule of rg.rules) {
2314
2789
  if (typeof rule === "string") continue;
@@ -2326,7 +2801,7 @@ const defaultRuleGroupProcessorGremlin = (ruleGroup, options) => {
2326
2801
  if (predicates.length === 1 && !rg.not) return predicates[0];
2327
2802
  return `.${prefix}(${predicates.map((p) => p.startsWith(".") ? `__${p}` : p).join(", ")})`;
2328
2803
  };
2329
- if (!isRuleOrGroupValid(ruleGroup, validationMap[(_ruleGroup$id = ruleGroup.id) !== null && _ruleGroup$id !== void 0 ? _ruleGroup$id : /* v8 ignore start -- @preserve */ ""])) return fallbackExpression;
2804
+ if (!isRuleOrGroupValid(ruleGroup, validationMap[(_ruleGroup$id = ruleGroup.id) !== null && _ruleGroup$id !== void 0 ? _ruleGroup$id : /* v8 ignore start -- @preserve */ ""])) return fallbackExpression;
2330
2805
  const steps = [];
2331
2806
  for (const rule of ruleGroup.rules) {
2332
2807
  if (typeof rule === "string") continue;
@@ -2352,7 +2827,7 @@ const defaultRuleGroupProcessorJSONata = (ruleGroup, options) => {
2352
2827
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2353
2828
  const processRuleGroup = (rg, outermost) => {
2354
2829
  var _rg$id;
2355
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2830
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2356
2831
  const processedRules = [];
2357
2832
  let precedingCombinator = "";
2358
2833
  let firstRule = true;
@@ -2409,7 +2884,7 @@ const defaultRuleGroupProcessorJsonLogic = (ruleGroup, options) => {
2409
2884
  const query = convertFromIC(ruleGroup);
2410
2885
  const processRuleGroup = (rg, _outermost) => {
2411
2886
  var _rg$id;
2412
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return false;
2887
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return false;
2413
2888
  const processedRules = rg.rules.map((rule) => {
2414
2889
  if (isRuleGroup(rule)) return processRuleGroup(rule);
2415
2890
  const [validationResult, fieldValidator] = validateRule(rule);
@@ -2437,7 +2912,7 @@ const defaultRuleGroupProcessorLDAP = (ruleGroup, options) => {
2437
2912
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2438
2913
  const processRuleGroup = (rg, outermost) => {
2439
2914
  var _rg$id;
2440
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2915
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2441
2916
  const rules = rg.rules.map((rule) => {
2442
2917
  var _rule$valueSource;
2443
2918
  if (isRuleGroup(rule)) return processRuleGroup(rule);
@@ -2471,7 +2946,7 @@ const defaultRuleGroupProcessorMongoDB = (ruleGroup, options, meta) => {
2471
2946
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2472
2947
  const processRuleGroup = (rg, outermost) => {
2473
2948
  var _rg$id;
2474
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2949
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2475
2950
  const combinator = `"$${lc(rg.combinator)}"`;
2476
2951
  let hasChildRules = false;
2477
2952
  const expressions = rg.rules.map((rule) => {
@@ -2508,7 +2983,7 @@ const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
2508
2983
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, translations, validateRule, validationMap } = options;
2509
2984
  const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
2510
2985
  var _rg$id, _rg2$combinator2, _translations$ruleSep2, _translations2;
2511
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
2986
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
2512
2987
  const rg2 = isRuleGroupTypeIC(rg) && rg.rules.some((r) => typeof r === "string" && lc(r) === "xor") ? convertFromIC(rg) : rg;
2513
2988
  const processedRules = [];
2514
2989
  let precedingCombinator = "";
@@ -2610,7 +3085,7 @@ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
2610
3085
  };
2611
3086
  const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
2612
3087
  var _rg$id;
2613
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
3088
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
2614
3089
  const processedRules = [];
2615
3090
  let precedingCombinator = "";
2616
3091
  let firstRule = true;
@@ -2671,7 +3146,7 @@ const defaultRuleGroupProcessorPrisma = (ruleGroup, options) => {
2671
3146
  const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2672
3147
  const processRuleGroup = (rg, outermost) => {
2673
3148
  var _rg$id;
2674
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? prismaFallback : void 0;
3149
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? prismaFallback : void 0;
2675
3150
  const combinator = rg.combinator.toUpperCase();
2676
3151
  let hasChildRules = false;
2677
3152
  const expressions = rg.rules.map((rule) => {
@@ -2710,7 +3185,7 @@ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
2710
3185
  if (!Op) return void 0;
2711
3186
  const processRuleGroup = (rg, _outermost) => {
2712
3187
  var _rg$id;
2713
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return;
3188
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return;
2714
3189
  const combinator = rg.combinator.toUpperCase();
2715
3190
  let hasChildRules = false;
2716
3191
  const expressions = rg.rules.map((rule) => {
@@ -2749,7 +3224,7 @@ const defaultRuleGroupProcessorSPARQL = (ruleGroup, options) => {
2749
3224
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2750
3225
  const processRuleGroup = (rg, outermost) => {
2751
3226
  var _rg$id;
2752
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
3227
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermost ? fallbackExpression : "";
2753
3228
  const processedRules = [];
2754
3229
  let precedingCombinator = "";
2755
3230
  let firstRule = true;
@@ -2805,7 +3280,7 @@ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
2805
3280
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2806
3281
  const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
2807
3282
  var _rg$id;
2808
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
3283
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
2809
3284
  const processedRules = [];
2810
3285
  let precedingCombinator = "";
2811
3286
  let firstRule = true;
@@ -2875,7 +3350,7 @@ const defaultRuleGroupProcessorTanStackDB = (ruleGroup, options) => (refs) => {
2875
3350
  if (refKeys.length === 0) return fallback;
2876
3351
  const processRuleGroup = (rg) => {
2877
3352
  var _rg$id;
2878
- if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return;
3353
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : /* v8 ignore start -- @preserve */ ""])) return;
2879
3354
  const processedRules = rg.rules.map((rule) => {
2880
3355
  if (isRuleGroup(rule)) return processRuleGroup(rule);
2881
3356
  const [validationResult, fieldValidator] = validateRule(rule);
@@ -3275,7 +3750,7 @@ const defaultRuleProcessorCypher = (rule, opts = {}) => {
3275
3750
  * @group Export
3276
3751
  */
3277
3752
  const defaultRuleProcessorDrizzle = (rule, _options) => {
3278
- const opts = _options !== null && _options !== void 0 ? _options : /* v8 ignore start -- @preserve */ {};
3753
+ const opts = _options !== null && _options !== void 0 ? _options : /* v8 ignore start -- @preserve */ {};
3279
3754
  // v8 ignore next
3280
3755
  const { parseNumbers, preserveValueOrder, context = {} } = opts;
3281
3756
  const { columns, drizzleOperators, useRawFields } = context;
@@ -3299,7 +3774,8 @@ const defaultRuleProcessorDrizzle = (rule, _options) => {
3299
3774
  const { mode, threshold } = matchEval;
3300
3775
  const subqueryDepth = (_opts$subqueryDepth = opts.subqueryDepth) !== null && _opts$subqueryDepth !== void 0 ? _opts$subqueryDepth : 0;
3301
3776
  const arrayElementAlias = getSubqueryElementAlias(subqueryDepth);
3302
- const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: arrayElementAlias }) }), _objectSpread2(_objectSpread2({}, opts), {}, {
3777
+ const sqlQuery = transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: arrayElementAlias }) });
3778
+ const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(sqlQuery, _objectSpread2(_objectSpread2({}, opts), {}, {
3303
3779
  context: _objectSpread2(_objectSpread2({}, opts.context), {}, { useRawFields: true }),
3304
3780
  subqueryDepth: subqueryDepth + 1
3305
3781
  }));
@@ -3830,7 +4306,7 @@ const defaultValueProcessorNL = (rule, opts = {}) => {
3830
4306
  const { escapeQuotes, fields, parseNumbers, quoteFieldNamesWith, quoteValuesWith, fieldIdentifierSeparator, translations } = opts;
3831
4307
  const valueIsField = rule.valueSource === "field";
3832
4308
  const operatorLowerCase = lc(rule.operator);
3833
- const quoteChar = quoteValuesWith || "'";
4309
+ const quoteChar = quoteValuesWith || /* v8 ignore start -- @preserve */ "'";
3834
4310
  const quoteValue = (v) => `${quoteChar}${v}${quoteChar}`;
3835
4311
  const escapeValue = (v) => escapeStringValueQuotes(v, quoteChar, escapeQuotes);
3836
4312
  const wrapAndEscape = (v) => quoteValue(escapeValue(v));
@@ -3838,7 +4314,7 @@ const defaultValueProcessorNL = (rule, opts = {}) => {
3838
4314
  quoteFieldNamesWith,
3839
4315
  fieldIdentifierSeparator
3840
4316
  });
3841
- const t = translations !== null && translations !== void 0 ? translations : /* v8 ignore start -- @preserve */ {};
4317
+ const t = translations !== null && translations !== void 0 ? translations : /* v8 ignore start -- @preserve */ {};
3842
4318
  const orTL = (_t$or = t.or) !== null && _t$or !== void 0 ? _t$or : "or";
3843
4319
  const trueTL = (_t$true = t.true) !== null && _t$true !== void 0 ? _t$true : "true";
3844
4320
  const falseTL = (_t$false = t.false) !== null && _t$false !== void 0 ? _t$false : "false";
@@ -3927,7 +4403,7 @@ const defaultOperatorProcessorNL = (rule, opts = {}) => {
3927
4403
  name: field,
3928
4404
  value: field,
3929
4405
  label: field
3930
- } })) !== null && _getOperators !== void 0 ? _getOperators : /* v8 ignore start -- @preserve */ []), normalizedOperator)) !== null && _getOption !== void 0 ? _getOption : {
4406
+ } })) !== null && _getOperators !== void 0 ? _getOperators : /* v8 ignore start -- @preserve */ []), normalizedOperator)) !== null && _getOption !== void 0 ? _getOption : {
3931
4407
  name: normalizedOperator,
3932
4408
  value: normalizedOperator,
3933
4409
  label: normalizedOperator
@@ -3944,7 +4420,7 @@ const defaultRuleProcessorNL = (rule, opts) => {
3944
4420
  var _fieldData$label, _opts$translations, _translations$afterSu, _translations$afterVe, _translations$afterOb;
3945
4421
  const { field, operator } = rule;
3946
4422
  // v8 ignore next
3947
- const { fieldData, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorNL, valueProcessor = defaultValueProcessorNL, concatOperator = "||", wordOrder = "SVO" } = opts !== null && opts !== void 0 ? opts : /* v8 ignore start -- @preserve */ {};
4423
+ const { fieldData, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorNL, valueProcessor = defaultValueProcessorNL, concatOperator = "||", wordOrder = "SVO" } = opts !== null && opts !== void 0 ? opts : /* v8 ignore start -- @preserve */ {};
3948
4424
  const processedField = getQuotedFieldName((_fieldData$label = fieldData === null || fieldData === void 0 ? void 0 : fieldData.label) !== null && _fieldData$label !== void 0 ? _fieldData$label : field, {
3949
4425
  quoteFieldNamesWith,
3950
4426
  fieldIdentifierSeparator
@@ -4153,7 +4629,7 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
4153
4629
  }
4154
4630
  let paramValue = rule.value;
4155
4631
  if (typeof rule.value === "string") if (shouldRenderAsNumber(rule.value, parseNumbers)) paramValue = parseNumber(rule.value, { parseNumbers });
4156
- else paramValue = /^'.*'$/g.test(value) ? value.replaceAll(/(^'|'$)/g, "") : /* v8 ignore next -- @preserve */ value;
4632
+ else paramValue = /^'.*'$/g.test(value) ? value.replaceAll(/(^'|'$)/g, "") : /* v8 ignore next -- @preserve */ value;
4157
4633
  let paramName = "";
4158
4634
  if (parameterized) params.push(paramValue);
4159
4635
  else {
@@ -4371,7 +4847,7 @@ const defaultRuleProcessorSPARQL = (rule, opts = {}) => {
4371
4847
  * @group Export
4372
4848
  */
4373
4849
  const defaultRuleProcessorTanStackDB = (rule, _options) => {
4374
- const { parseNumbers, preserveValueOrder, context = {} } = _options !== null && _options !== void 0 ? _options : /* v8 ignore start -- @preserve */ {};
4850
+ const { parseNumbers, preserveValueOrder, context = {} } = _options !== null && _options !== void 0 ? _options : /* v8 ignore start -- @preserve */ {};
4375
4851
  const ops = context.tanStackDbOperators;
4376
4852
  const refs = context._tanstackDbRefs;
4377
4853
  const primaryRef = context._tanstackDbPrimaryRef;
@@ -4632,7 +5108,7 @@ function formatQuery(ruleGroup, optionParam = {}) {
4632
5108
  // v8 ignore else
4633
5109
  if (typeof f.validator === "function") {
4634
5110
  var _f$value;
4635
- validatorMap[(_f$value = f.value) !== null && _f$value !== void 0 ? _f$value : /* v8 ignore start -- @preserve */ f.name] = f.validator;
5111
+ validatorMap[(_f$value = f.value) !== null && _f$value !== void 0 ? _f$value : /* v8 ignore start -- @preserve */ f.name] = f.validator;
4636
5112
  }
4637
5113
  const validateRule = (rule) => {
4638
5114
  let validationResult;
@@ -4803,12 +5279,20 @@ const getParentPath = (path) => path.slice(0, -1);
4803
5279
  /**
4804
5280
  * Determines if two paths (each `Path`) are equivalent.
4805
5281
  */
4806
- const pathsAreEqual = (path1, path2) => path1.length === path2.length && path1.every((val, idx) => val === path2[idx]);
5282
+ const pathsAreEqual = (path1, path2) => {
5283
+ if (path1.length !== path2.length) return false;
5284
+ for (let i = 0; i < path1.length; i++) if (path1[i] !== path2[i]) return false;
5285
+ return true;
5286
+ };
4807
5287
  /**
4808
5288
  * Determines if the first path is an ancestor of the second path. The first path must
4809
5289
  * be shorter and exactly match the second path up through the length of the first path.
4810
5290
  */
4811
- const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && new RegExp(`^${maybeAncestor.join("-")}`).test(path.join("-"));
5291
+ const isAncestor = (maybeAncestor, path) => {
5292
+ if (maybeAncestor.length >= path.length) return false;
5293
+ for (let i = 0; i < maybeAncestor.length; i++) if (maybeAncestor[i] !== path[i]) return false;
5294
+ return true;
5295
+ };
4812
5296
  /**
4813
5297
  * Finds the deepest/longest path that two paths have in common.
4814
5298
  */
@@ -4841,11 +5325,38 @@ const pathIsDisabled = (path, query) => {
4841
5325
  }
4842
5326
  return disabled;
4843
5327
  };
5328
+ /**
5329
+ * Determines if the rule or group at the specified path is disabled by `disabledPaths`—the array
5330
+ * form of the `QueryBuilder` `disabled` prop, which disables nodes by position rather than by a
5331
+ * `disabled` property on the node itself. A path is disabled if it appears in `disabledPaths` or
5332
+ * descends from a path that does.
5333
+ *
5334
+ * @group Paths
5335
+ */
5336
+ const pathIsDisabledByPaths = (path, disabledPaths = []) => disabledPaths.some((p) => pathsAreEqual(p, path) || isAncestor(p, path));
5337
+ /**
5338
+ * Builds the {@link PathInfo} for each child of a group at `path`. A child is disabled if its
5339
+ * parent is disabled or if its own path appears in `disabledPaths`.
5340
+ *
5341
+ * @group Paths
5342
+ */
5343
+ const derivePathInfo = (path, childCount, { disabled = false, disabledPaths = [] } = {}) => {
5344
+ const paths = [];
5345
+ for (let i = 0; i < childCount; i++) {
5346
+ const thisPath = [...path, i];
5347
+ paths[i] = {
5348
+ path: thisPath,
5349
+ disabled: disabled || disabledPaths.some((p) => pathsAreEqual(thisPath, p))
5350
+ };
5351
+ }
5352
+ return paths;
5353
+ };
4844
5354
  //#endregion
4845
5355
  //#region src/utils/generateAccessibleDescription.ts
4846
5356
  const generateAccessibleDescription = (params) => pathsAreEqual([], params.path) ? `Query builder` : `Rule group at path ${params.path.join("-")}`;
4847
5357
  //#endregion
4848
5358
  //#region src/utils/generateID.ts
5359
+ /* v8 ignore file -- this is fine */
4849
5360
  const cryptoModule = globalThis.crypto;
4850
5361
  const uuidV4regex = /^[\da-f]{8}-[\da-f]{4}-4[\da-f]{3}-[89ab][\da-f]{3}-[\da-f]{12}$/i;
4851
5362
  /**
@@ -4895,7 +5406,7 @@ const dummyFD$1 = {
4895
5406
  */
4896
5407
  const getMatchModesUtil = (fieldData, getMatchModes) => {
4897
5408
  var _fd$matchModes, _matchModes$map;
4898
- const fd = fieldData ? toFullOption(fieldData) : /* v8 ignore next -- @preserve */ dummyFD$1;
5409
+ const fd = fieldData ? toFullOption(fieldData) : /* v8 ignore next -- @preserve */ dummyFD$1;
4899
5410
  let matchModes = (_fd$matchModes = fd.matchModes) !== null && _fd$matchModes !== void 0 ? _fd$matchModes : false;
4900
5411
  if (!matchModes && getMatchModes) matchModes = getMatchModes(fd.value, { fieldData: fd });
4901
5412
  if (matchModes === true) return defaultMatchModes;
@@ -4916,7 +5427,7 @@ const getFirstOptionsFrom = (opts, r, listsAsArrays) => {
4916
5427
  const firstOption = getFirstOption(opts);
4917
5428
  if (r.operator === "between" || r.operator === "notBetween") {
4918
5429
  const valueAsArray = [firstOption, firstOption];
4919
- return listsAsArrays ? valueAsArray : joinWith(valueAsArray.map((v) => v !== null && v !== void 0 ? v : /* v8 ignore start -- @preserve */ ""), ",");
5430
+ return listsAsArrays ? valueAsArray : joinWith(valueAsArray.map((v) => v !== null && v !== void 0 ? v : /* v8 ignore start -- @preserve */ ""), ",");
4920
5431
  }
4921
5432
  return firstOption;
4922
5433
  };
@@ -5058,6 +5569,9 @@ const mergeClassnames = (...args) => ({
5058
5569
  removeRule: joinClassnamesByName("removeRule", args),
5059
5570
  notToggle: joinClassnamesByName("notToggle", args),
5060
5571
  shiftActions: joinClassnamesByName("shiftActions", args),
5572
+ undoRedoActions: joinClassnamesByName("undoRedoActions", args),
5573
+ undoAction: joinClassnamesByName("undoAction", args),
5574
+ redoAction: joinClassnamesByName("redoAction", args),
5061
5575
  dragHandle: joinClassnamesByName("dragHandle", args),
5062
5576
  lockRule: joinClassnamesByName("lockRule", args),
5063
5577
  lockGroup: joinClassnamesByName("lockGroup", args),
@@ -5087,6 +5601,66 @@ const mergeClassnames = (...args) => ({
5087
5601
  valueDateTimeRelative: joinClassnamesByName("valueDateTimeRelative", args)
5088
5602
  });
5089
5603
  //#endregion
5604
+ //#region src/utils/optionResolvers.ts
5605
+ /**
5606
+ * Resolves the operator list for a field, applying the same precedence as the `QueryBuilder`
5607
+ * component: the field's own `operators`, then the `getOperators` callback, then the
5608
+ * query-level operator list.
5609
+ *
5610
+ * @group Option Lists
5611
+ */
5612
+ const resolveOperatorList = ({ field, fieldData, getOperators, operators, placeholder, baseOption, autoSelectOption }) => {
5613
+ var _ref, _fieldData$operators;
5614
+ return prepareOptionList({
5615
+ optionList: (_ref = (_fieldData$operators = fieldData === null || fieldData === void 0 ? void 0 : fieldData.operators) !== null && _fieldData$operators !== void 0 ? _fieldData$operators : getOperators === null || getOperators === void 0 ? void 0 : getOperators(field, { fieldData })) !== null && _ref !== void 0 ? _ref : operators,
5616
+ placeholder,
5617
+ baseOption,
5618
+ labelMap: defaultOperatorLabelMap,
5619
+ autoSelectOption
5620
+ }).optionList;
5621
+ };
5622
+ /**
5623
+ * Resolves the default operator for a field, applying the same precedence as the `QueryBuilder`
5624
+ * component: the field's own `defaultOperator`, then the `getDefaultOperator` option (a string or
5625
+ * a function), then the first available operator.
5626
+ *
5627
+ * @group Option Lists
5628
+ */
5629
+ const resolveDefaultOperator = ({ field, fieldData, getDefaultOperator, getOperators }) => {
5630
+ var _getFirstOption;
5631
+ if (fieldData === null || fieldData === void 0 ? void 0 : fieldData.defaultOperator) return fieldData.defaultOperator;
5632
+ if (getDefaultOperator) return typeof getDefaultOperator === "function" ? getDefaultOperator(field, { fieldData }) : getDefaultOperator;
5633
+ return (_getFirstOption = getFirstOption(getOperators(field, { fieldData }))) !== null && _getFirstOption !== void 0 ? _getFirstOption : "";
5634
+ };
5635
+ /**
5636
+ * Resolves the value editor type for a field/operator pair, applying the same precedence as the
5637
+ * `QueryBuilder` component: the field's own `valueEditorType` (a string or a function of the
5638
+ * operator), then the `getValueEditorType` callback, then `"text"`.
5639
+ *
5640
+ * @group Option Lists
5641
+ */
5642
+ const resolveValueEditorType = ({ field, operator, fieldData, getValueEditorType }) => {
5643
+ var _getValueEditorType;
5644
+ if (fieldData === null || fieldData === void 0 ? void 0 : fieldData.valueEditorType) return typeof fieldData.valueEditorType === "function" ? fieldData.valueEditorType(operator) : fieldData.valueEditorType;
5645
+ return (_getValueEditorType = getValueEditorType === null || getValueEditorType === void 0 ? void 0 : getValueEditorType(field, operator, { fieldData })) !== null && _getValueEditorType !== void 0 ? _getValueEditorType : "text";
5646
+ };
5647
+ /**
5648
+ * Resolves the value option list for a field/operator pair, applying the same precedence as the
5649
+ * `QueryBuilder` component: the field's own `values`, then the `getValues` callback, then an
5650
+ * empty list.
5651
+ *
5652
+ * @group Option Lists
5653
+ */
5654
+ const resolveValueList = ({ field, operator, fieldData, getValues, placeholder, baseOption, autoSelectOption }) => {
5655
+ var _ref2, _fieldData$values;
5656
+ return prepareOptionList({
5657
+ optionList: (_ref2 = (_fieldData$values = fieldData === null || fieldData === void 0 ? void 0 : fieldData.values) !== null && _fieldData$values !== void 0 ? _fieldData$values : getValues === null || getValues === void 0 ? void 0 : getValues(field, operator, { fieldData })) !== null && _ref2 !== void 0 ? _ref2 : [],
5658
+ placeholder,
5659
+ baseOption,
5660
+ autoSelectOption
5661
+ }).optionList;
5662
+ };
5663
+ //#endregion
5090
5664
  //#region src/utils/preferProp.ts
5091
5665
  const preferPropDefaultTrue = (prop, context) => prop === false ? false : prop ? true : !(context === false);
5092
5666
  const preferPropDefaultFalse = (prop, context) => prop ? true : prop === false ? false : !!context;
@@ -5143,6 +5717,22 @@ const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => {
5143
5717
  * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.
5144
5718
  */
5145
5719
  const prepareRuleOrGroup = (rg, { idGenerator = generateID } = {}) => isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });
5720
+ /**
5721
+ * Resolves the query a query builder should render from the available sources, in precedence
5722
+ * order: the controlled `query`, then whatever is already in the store, then the uncontrolled
5723
+ * `defaultQuery`, then a freshly created empty group.
5724
+ *
5725
+ * The result is prepared with {@link prepareRuleGroup} unless it already has an `id`, which is
5726
+ * taken to mean it has been prepared before—most often because the caller is passing back the
5727
+ * object it received from `onQueryChange`.
5728
+ *
5729
+ * @group Query Tools
5730
+ */
5731
+ const resolveCandidateQuery = (sources, options) => {
5732
+ var _ref, _ref2, _sources$query;
5733
+ const candidateQuery = (_ref = (_ref2 = (_sources$query = sources.query) !== null && _sources$query !== void 0 ? _sources$query : sources.storeQuery) !== null && _ref2 !== void 0 ? _ref2 : sources.defaultQuery) !== null && _ref !== void 0 ? _ref : sources.fallbackQuery;
5734
+ return candidateQuery.id ? candidateQuery : prepareRuleGroup(candidateQuery, options);
5735
+ };
5146
5736
  //#endregion
5147
5737
  //#region src/utils/regenerateIDs.ts
5148
5738
  /**
@@ -5163,6 +5753,28 @@ const regenerateIDs = (subject, { idGenerator = generateID } = {}) => {
5163
5753
  //#endregion
5164
5754
  //#region src/utils/queryTools.ts
5165
5755
  /**
5756
+ * Whether a mutation targeting `pathOrID` is blocked by the given guards, and why.
5757
+ * Returns `null` when the mutation may proceed.
5758
+ *
5759
+ * Exported so that callers which run their own logic before mutating—such as a UI layer that
5760
+ * invokes a confirmation callback—can apply the same rules without duplicating them.
5761
+ *
5762
+ * @group Query Tools
5763
+ */
5764
+ const getGuardAbortReason = (query, pathOrID, guards = {}, { asParent = false } = {}) => {
5765
+ if (guards.queryDisabled) return asParent ? "parent-disabled" : "target-disabled";
5766
+ if (!guards.respectDisabled || pathOrID === void 0) return null;
5767
+ const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
5768
+ if (path && (pathIsDisabled(path, query) || pathIsDisabledByPaths(path, guards.disabledPaths))) return asParent ? "parent-disabled" : "target-disabled";
5769
+ return null;
5770
+ };
5771
+ /**
5772
+ * Whether adding a group beneath `parentPath` would exceed `maxLevels`.
5773
+ *
5774
+ * @group Query Tools
5775
+ */
5776
+ const exceedsMaxLevels = (parentPath, { maxLevels = Infinity } = {}) => !!parentPath && parentPath.length >= maxLevels;
5777
+ /**
5166
5778
  * Adds a rule or group to a query without mutating the original query.
5167
5779
  *
5168
5780
  * @returns A new query with the rule or group added.
@@ -5178,9 +5790,42 @@ const add = (query, ruleOrGroup, parentPathOrID, options = {}) => produce(query,
5178
5790
  * @group Query Tools
5179
5791
  */
5180
5792
  const addInPlace = (query, ruleOrGroup, parentPathOrID, options = {}) => {
5181
- const { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = options;
5793
+ const { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID, onAbort } = options;
5182
5794
  const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, query) : findID(parentPathOrID, query);
5183
- if (!parent || !isRuleGroup(parent)) return query;
5795
+ if (!parent) {
5796
+ onAbort === null || onAbort === void 0 || onAbort({
5797
+ reason: "parent-not-found",
5798
+ operation: "add",
5799
+ pathOrID: parentPathOrID
5800
+ });
5801
+ return query;
5802
+ }
5803
+ if (!isRuleGroup(parent)) {
5804
+ onAbort === null || onAbort === void 0 || onAbort({
5805
+ reason: "parent-not-a-group",
5806
+ operation: "add",
5807
+ pathOrID: parentPathOrID
5808
+ });
5809
+ return query;
5810
+ }
5811
+ const parentPath = Array.isArray(parentPathOrID) ? parentPathOrID : getPathOfID(parentPathOrID, query);
5812
+ const addGuardReason = getGuardAbortReason(query, parentPath, options, { asParent: true });
5813
+ if (addGuardReason) {
5814
+ onAbort === null || onAbort === void 0 || onAbort({
5815
+ reason: addGuardReason,
5816
+ operation: "add",
5817
+ pathOrID: parentPathOrID
5818
+ });
5819
+ return query;
5820
+ }
5821
+ if (isRuleGroup(ruleOrGroup) && exceedsMaxLevels(parentPath, options)) {
5822
+ onAbort === null || onAbort === void 0 || onAbort({
5823
+ reason: "max-levels-exceeded",
5824
+ operation: "add",
5825
+ pathOrID: parentPathOrID
5826
+ });
5827
+ return query;
5828
+ }
5184
5829
  if (isRuleGroupTypeIC(parent) && parent.rules.length > 0) {
5185
5830
  const prevCombinator = parent.rules.at(-2);
5186
5831
  parent.rules.push(combinatorPreceding !== null && combinatorPreceding !== void 0 ? combinatorPreceding : typeof prevCombinator === "string" ? prevCombinator : getFirstOption(combinators));
@@ -5201,7 +5846,7 @@ const updatePropRank = {
5201
5846
  value: 4
5202
5847
  };
5203
5848
  /** Stable-sorts `[prop, value]` entries by {@link updatePropRank}. */
5204
- const orderUpdateEntries = (entries) => entries.sort((x, y) => {
5849
+ const orderUpdateEntries = (entries) => entries.toSorted((x, y) => {
5205
5850
  var _updatePropRank$x$, _updatePropRank$y$;
5206
5851
  return ((_updatePropRank$x$ = updatePropRank[x[0]]) !== null && _updatePropRank$x$ !== void 0 ? _updatePropRank$x$ : 3) - ((_updatePropRank$y$ = updatePropRank[y[0]]) !== null && _updatePropRank$y$ !== void 0 ? _updatePropRank$y$ : 3);
5207
5852
  });
@@ -5272,19 +5917,69 @@ const updateInPlace = ((query, a, b, c, d) => applyUpdatesInPlace(query, a, b, c
5272
5917
  * Updates a single property of a rule or group within a query in place.
5273
5918
  */
5274
5919
  const updateInPlaceSingle = (query, prop, value, pathOrID, options = {}) => {
5275
- const { resetOnFieldChange: _resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = options;
5920
+ const { resetOnFieldChange: _resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [], onAbort } = options;
5276
5921
  let resetOnFieldChange = _resetOnFieldChange;
5277
5922
  const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
5278
- if (!path) return query;
5923
+ if (!path) {
5924
+ onAbort === null || onAbort === void 0 || onAbort({
5925
+ reason: "target-not-found",
5926
+ operation: "update",
5927
+ pathOrID
5928
+ });
5929
+ return query;
5930
+ }
5931
+ const updateGuards = prop === "disabled" ? { queryDisabled: options.queryDisabled } : options;
5932
+ const updateGuardReason = getGuardAbortReason(query, path, updateGuards);
5933
+ if (updateGuardReason) {
5934
+ onAbort === null || onAbort === void 0 || onAbort({
5935
+ reason: updateGuardReason,
5936
+ operation: "update",
5937
+ pathOrID
5938
+ });
5939
+ return query;
5940
+ }
5279
5941
  if (prop === "combinator" && !isRuleGroupType(query)) {
5280
- const parentRules = findPath(getParentPath(path), query).rules;
5281
- if (path.at(-1) % 2 === 1) parentRules[path.at(-1)] = value;
5942
+ const parent = findPath(getParentPath(path), query);
5943
+ if (!parent || !isRuleGroup(parent)) {
5944
+ onAbort === null || onAbort === void 0 || onAbort({
5945
+ reason: "target-not-found",
5946
+ operation: "update",
5947
+ pathOrID
5948
+ });
5949
+ return query;
5950
+ }
5951
+ const parentRules = parent.rules;
5952
+ if (path.at(-1) % 2 === 1) if (parentRules[path.at(-1)] === value) onAbort === null || onAbort === void 0 || onAbort({
5953
+ reason: "no-change",
5954
+ operation: "update",
5955
+ pathOrID
5956
+ });
5957
+ else parentRules[path.at(-1)] = value;
5958
+ else onAbort === null || onAbort === void 0 || onAbort({
5959
+ reason: "not-a-combinator-slot",
5960
+ operation: "update",
5961
+ pathOrID
5962
+ });
5282
5963
  return query;
5283
5964
  }
5284
5965
  const ruleOrGroup = findPath(path, query);
5285
- if (!ruleOrGroup) return query;
5966
+ if (!ruleOrGroup) {
5967
+ onAbort === null || onAbort === void 0 || onAbort({
5968
+ reason: "target-not-found",
5969
+ operation: "update",
5970
+ pathOrID
5971
+ });
5972
+ return query;
5973
+ }
5286
5974
  const isGroup = isRuleGroup(ruleOrGroup);
5287
- if (ruleOrGroup[prop] === value) return query;
5975
+ if (ruleOrGroup[prop] === value) {
5976
+ onAbort === null || onAbort === void 0 || onAbort({
5977
+ reason: "no-change",
5978
+ operation: "update",
5979
+ pathOrID
5980
+ });
5981
+ return query;
5982
+ }
5288
5983
  if (prop !== "valueSource") ruleOrGroup[prop] = value;
5289
5984
  if (isGroup) return query;
5290
5985
  let resetValueSource = false;
@@ -5331,7 +6026,7 @@ const updateInPlaceSingle = (query, prop, value, pathOrID, options = {}) => {
5331
6026
  *
5332
6027
  * @group Query Tools
5333
6028
  */
5334
- const remove = (query, pathOrID) => produce(query, (q) => removeInPlace(q, pathOrID));
6029
+ const remove = (query, pathOrID, options = {}) => produce(query, (q) => removeInPlace(q, pathOrID, options));
5335
6030
  /**
5336
6031
  * Removes a rule or group from a query in place.
5337
6032
  *
@@ -5339,15 +6034,48 @@ const remove = (query, pathOrID) => produce(query, (q) => removeInPlace(q, pathO
5339
6034
  *
5340
6035
  * @group Query Tools
5341
6036
  */
5342
- const removeInPlace = (query, pathOrID) => {
6037
+ const removeInPlace = (query, pathOrID, options = {}) => {
6038
+ const { onAbort } = options;
5343
6039
  const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
5344
- if (!path || path.length === 0 || !isRuleGroupType(query) && !findPath(path, query)) return query;
5345
- const index = path.at(-1);
5346
- const parent = findPath(getParentPath(path), query);
5347
- if (parent && isRuleGroup(parent)) if (!isRuleGroupType(parent) && parent.rules.length > 1) {
5348
- const idxStartDelete = index === 0 ? 0 : index - 1;
5349
- parent.rules.splice(idxStartDelete, 2);
5350
- } else parent.rules.splice(index, 1);
6040
+ if (!path) {
6041
+ onAbort === null || onAbort === void 0 || onAbort({
6042
+ reason: "target-not-found",
6043
+ operation: "remove",
6044
+ pathOrID
6045
+ });
6046
+ return query;
6047
+ }
6048
+ if (path.length === 0) {
6049
+ onAbort === null || onAbort === void 0 || onAbort({
6050
+ reason: "root-not-allowed",
6051
+ operation: "remove",
6052
+ pathOrID
6053
+ });
6054
+ return query;
6055
+ }
6056
+ const removeGuardReason = getGuardAbortReason(query, path, options);
6057
+ if (removeGuardReason) {
6058
+ onAbort === null || onAbort === void 0 || onAbort({
6059
+ reason: removeGuardReason,
6060
+ operation: "remove",
6061
+ pathOrID
6062
+ });
6063
+ return query;
6064
+ }
6065
+ if (!findPath(path, query)) {
6066
+ onAbort === null || onAbort === void 0 || onAbort({
6067
+ reason: "target-not-found",
6068
+ operation: "remove",
6069
+ pathOrID
6070
+ });
6071
+ return query;
6072
+ }
6073
+ const index = path.at(-1);
6074
+ const parent = findPath(getParentPath(path), query);
6075
+ if (!isRuleGroupType(parent) && parent.rules.length > 1) {
6076
+ const idxStartDelete = index === 0 ? 0 : index - 1;
6077
+ parent.rules.splice(idxStartDelete, 2);
6078
+ } else parent.rules.splice(index, 1);
5351
6079
  return query;
5352
6080
  };
5353
6081
  const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
@@ -5369,7 +6097,8 @@ const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
5369
6097
  return [...getParentPath(parentPath), parentPath.at(-1) + 1];
5370
6098
  } else {
5371
6099
  const evaluationPath = [...getParentPath(currentPath), currentPath.at(-1) + (ic ? 2 : 1)];
5372
- if (isRuleGroup(findPath(evaluationPath, query))) return [...evaluationPath, 0];
6100
+ const entityToEvaluate = findPath(evaluationPath, query);
6101
+ if (isRuleGroup(entityToEvaluate)) return [...evaluationPath, 0];
5373
6102
  else return [...getParentPath(currentPath), currentPath.at(-1) + (ic ? 3 : 2)];
5374
6103
  }
5375
6104
  return currentPath;
@@ -5392,13 +6121,67 @@ const move = (query, oldPathOrID, newPath, options = {}) => produce(query, (q) =
5392
6121
  * @group Query Tools
5393
6122
  */
5394
6123
  const moveInPlace = (query, oldPathOrID, newPath, options = {}) => {
5395
- const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
6124
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID, onAbort } = options;
5396
6125
  const oldPath = Array.isArray(oldPathOrID) ? oldPathOrID : getPathOfID(oldPathOrID, query);
5397
- if (!oldPath) return query;
5398
- const nextPath = getNextPath(query, oldPath, newPath);
5399
- if (oldPath.length === 0 || pathsAreEqual(oldPath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
6126
+ if (!oldPath) {
6127
+ onAbort === null || onAbort === void 0 || onAbort({
6128
+ reason: "target-not-found",
6129
+ operation: "move",
6130
+ pathOrID: oldPathOrID
6131
+ });
6132
+ return query;
6133
+ }
5400
6134
  const ruleOrGroupOriginal = findPath(oldPath, query);
5401
- if (!ruleOrGroupOriginal) return query;
6135
+ if (!ruleOrGroupOriginal) {
6136
+ onAbort === null || onAbort === void 0 || onAbort({
6137
+ reason: "target-not-found",
6138
+ operation: "move",
6139
+ pathOrID: oldPathOrID
6140
+ });
6141
+ return query;
6142
+ }
6143
+ const nextPath = getNextPath(query, oldPath, newPath);
6144
+ if (oldPath.length === 0) {
6145
+ onAbort === null || onAbort === void 0 || onAbort({
6146
+ reason: "root-not-allowed",
6147
+ operation: "move",
6148
+ pathOrID: oldPathOrID
6149
+ });
6150
+ return query;
6151
+ }
6152
+ const moveGuardReason = getGuardAbortReason(query, oldPath, options);
6153
+ if (moveGuardReason) {
6154
+ onAbort === null || onAbort === void 0 || onAbort({
6155
+ reason: moveGuardReason,
6156
+ operation: "move",
6157
+ pathOrID: oldPathOrID
6158
+ });
6159
+ return query;
6160
+ }
6161
+ if (pathsAreEqual(oldPath, nextPath)) {
6162
+ onAbort === null || onAbort === void 0 || onAbort({
6163
+ reason: "same-location",
6164
+ operation: "move",
6165
+ pathOrID: oldPathOrID
6166
+ });
6167
+ return query;
6168
+ }
6169
+ if (!findPath(getParentPath(nextPath), query)) {
6170
+ onAbort === null || onAbort === void 0 || onAbort({
6171
+ reason: "destination-not-found",
6172
+ operation: "move",
6173
+ pathOrID: newPath
6174
+ });
6175
+ return query;
6176
+ }
6177
+ if (!clone && isAncestor(oldPath, nextPath)) {
6178
+ onAbort === null || onAbort === void 0 || onAbort({
6179
+ reason: "destination-not-found",
6180
+ operation: "move",
6181
+ pathOrID: newPath
6182
+ });
6183
+ return query;
6184
+ }
5402
6185
  const ruleOrGroup = clone ? regenerateIDs(isDraft(ruleOrGroupOriginal) ? current(ruleOrGroupOriginal) : ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
5403
6186
  const independentCombinators = isRuleGroupTypeIC(query);
5404
6187
  const parentOfRuleToRemove = findPath(getParentPath(oldPath), query);
@@ -5411,15 +6194,18 @@ const moveInPlace = (query, oldPathOrID, newPath, options = {}) => {
5411
6194
  parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
5412
6195
  }
5413
6196
  const newNewPath = [...nextPath];
6197
+ if (independentCombinators && newNewPath.at(-1) % 2 === 1) newNewPath[newNewPath.length - 1] += 1;
5414
6198
  const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);
5415
- if (!clone && oldPath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
5416
- const parentToInsertInto = findPath(getParentPath(newNewPath), query);
6199
+ if (!clone && oldPath.length === commonAncestorPath.length + 1 && newNewPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
6200
+ const newNewParentPath = getParentPath(newNewPath);
6201
+ const parentToInsertInto = findPath(newNewParentPath, query);
5417
6202
  const newIndex = newNewPath.at(-1);
6203
+ const spliceIndex = independentCombinators && newIndex > 0 ? newIndex - 1 : newIndex;
5418
6204
  /**
5419
6205
  * This function 1) glosses over the need for type assertions to splice directly
5420
6206
  * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
5421
6207
  */
5422
- const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(newIndex, 0, ...args);
6208
+ const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(spliceIndex, 0, ...args);
5423
6209
  if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(ruleOrGroup);
5424
6210
  else if (newIndex === 0) if (ruleToRemoveIndex === 0 && oldNextCombinator) insertRuleOrGroup(ruleOrGroup, oldNextCombinator);
5425
6211
  else {
@@ -5429,7 +6215,7 @@ const moveInPlace = (query, oldPathOrID, newPath, options = {}) => {
5429
6215
  else if (oldPrevCombinator) insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);
5430
6216
  else {
5431
6217
  var _ref5, _parentToInsertInto$r2;
5432
- insertRuleOrGroup((_ref5 = (_parentToInsertInto$r2 = parentToInsertInto.rules[newIndex - 2]) !== null && _parentToInsertInto$r2 !== void 0 ? _parentToInsertInto$r2 : oldNextCombinator) !== null && _ref5 !== void 0 ? _ref5 : getFirstOption(combinators), ruleOrGroup);
6218
+ insertRuleOrGroup((_ref5 = (_parentToInsertInto$r2 = parentToInsertInto.rules[spliceIndex - 2]) !== null && _parentToInsertInto$r2 !== void 0 ? _parentToInsertInto$r2 : oldNextCombinator) !== null && _ref5 !== void 0 ? _ref5 : getFirstOption(combinators), ruleOrGroup);
5433
6219
  }
5434
6220
  return query;
5435
6221
  };
@@ -5449,9 +6235,42 @@ const insert = (query, ruleOrGroup, path, options = {}) => produce(query, (q) =>
5449
6235
  * @group Query Tools
5450
6236
  */
5451
6237
  const insertInPlace = (query, ruleOrGroup, path, options = {}) => {
5452
- const { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = options;
6238
+ const { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false, onAbort } = options;
5453
6239
  const parentToInsertInto = findPath(getParentPath(path), query);
5454
- if (!parentToInsertInto || !isRuleGroup(parentToInsertInto)) return query;
6240
+ if (!parentToInsertInto) {
6241
+ onAbort === null || onAbort === void 0 || onAbort({
6242
+ reason: "parent-not-found",
6243
+ operation: "insert",
6244
+ pathOrID: path
6245
+ });
6246
+ return query;
6247
+ }
6248
+ if (!isRuleGroup(parentToInsertInto)) {
6249
+ onAbort === null || onAbort === void 0 || onAbort({
6250
+ reason: "parent-not-a-group",
6251
+ operation: "insert",
6252
+ pathOrID: path
6253
+ });
6254
+ return query;
6255
+ }
6256
+ const parentPath = getParentPath(path);
6257
+ const insertGuardReason = getGuardAbortReason(query, parentPath, options, { asParent: true });
6258
+ if (insertGuardReason) {
6259
+ onAbort === null || onAbort === void 0 || onAbort({
6260
+ reason: insertGuardReason,
6261
+ operation: "insert",
6262
+ pathOrID: path
6263
+ });
6264
+ return query;
6265
+ }
6266
+ if (isRuleGroup(ruleOrGroup) && exceedsMaxLevels(parentPath, options)) {
6267
+ onAbort === null || onAbort === void 0 || onAbort({
6268
+ reason: "max-levels-exceeded",
6269
+ operation: "insert",
6270
+ pathOrID: path
6271
+ });
6272
+ return query;
6273
+ }
5455
6274
  const rorg = regenerateIDs(ruleOrGroup, { idGenerator });
5456
6275
  const independentCombinators = isRuleGroupTypeIC(query);
5457
6276
  const newIndex = path.at(-1);
@@ -5499,15 +6318,85 @@ const group = (query, sourcePathOrID, targetPathOrID, options = {}) => produce(q
5499
6318
  * @group Query Tools
5500
6319
  */
5501
6320
  const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
5502
- const { clone = false, combinators = defaultCombinators, idGenerator = generateID } = options;
6321
+ const { clone = false, combinators = defaultCombinators, idGenerator = generateID, onAbort } = options;
5503
6322
  const sourcePath = Array.isArray(sourcePathOrID) ? sourcePathOrID : getPathOfID(sourcePathOrID, query);
5504
6323
  const targetPath = Array.isArray(targetPathOrID) ? targetPathOrID : getPathOfID(targetPathOrID, query);
5505
- if (!sourcePath || !targetPath) return query;
6324
+ if (!sourcePath) {
6325
+ onAbort === null || onAbort === void 0 || onAbort({
6326
+ reason: "target-not-found",
6327
+ operation: "group",
6328
+ pathOrID: sourcePathOrID
6329
+ });
6330
+ return query;
6331
+ }
6332
+ if (!targetPath) {
6333
+ onAbort === null || onAbort === void 0 || onAbort({
6334
+ reason: "target-not-found",
6335
+ operation: "group",
6336
+ pathOrID: targetPathOrID
6337
+ });
6338
+ return query;
6339
+ }
5506
6340
  const nextPath = getNextPath(query, sourcePath, targetPath);
5507
- if (sourcePath.length === 0 || pathsAreEqual(sourcePath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
6341
+ if (sourcePath.length === 0) {
6342
+ onAbort === null || onAbort === void 0 || onAbort({
6343
+ reason: "root-not-allowed",
6344
+ operation: "group",
6345
+ pathOrID: sourcePathOrID
6346
+ });
6347
+ return query;
6348
+ }
6349
+ const groupGuardReason = getGuardAbortReason(query, sourcePath, options);
6350
+ if (groupGuardReason) {
6351
+ onAbort === null || onAbort === void 0 || onAbort({
6352
+ reason: groupGuardReason,
6353
+ operation: "group",
6354
+ pathOrID: sourcePathOrID
6355
+ });
6356
+ return query;
6357
+ }
6358
+ if (pathsAreEqual(sourcePath, nextPath)) {
6359
+ onAbort === null || onAbort === void 0 || onAbort({
6360
+ reason: "same-location",
6361
+ operation: "group",
6362
+ pathOrID: sourcePathOrID
6363
+ });
6364
+ return query;
6365
+ }
6366
+ if (!findPath(getParentPath(nextPath), query)) {
6367
+ onAbort === null || onAbort === void 0 || onAbort({
6368
+ reason: "destination-not-found",
6369
+ operation: "group",
6370
+ pathOrID: targetPathOrID
6371
+ });
6372
+ return query;
6373
+ }
6374
+ if (!clone && isAncestor(sourcePath, nextPath)) {
6375
+ onAbort === null || onAbort === void 0 || onAbort({
6376
+ reason: "destination-not-found",
6377
+ operation: "group",
6378
+ pathOrID: targetPathOrID
6379
+ });
6380
+ return query;
6381
+ }
5508
6382
  const sourceRuleOrGroupOriginal = findPath(sourcePath, query);
5509
6383
  const targetRuleOrGroup = findPath(targetPath, query);
5510
- if (!sourceRuleOrGroupOriginal || !targetRuleOrGroup) return query;
6384
+ if (!sourceRuleOrGroupOriginal) {
6385
+ onAbort === null || onAbort === void 0 || onAbort({
6386
+ reason: "target-not-found",
6387
+ operation: "group",
6388
+ pathOrID: sourcePathOrID
6389
+ });
6390
+ return query;
6391
+ }
6392
+ if (!targetRuleOrGroup) {
6393
+ onAbort === null || onAbort === void 0 || onAbort({
6394
+ reason: "target-not-found",
6395
+ operation: "group",
6396
+ pathOrID: targetPathOrID
6397
+ });
6398
+ return query;
6399
+ }
5511
6400
  const sourceRuleOrGroup = clone ? regenerateIDs(isDraft(sourceRuleOrGroupOriginal) ? current(sourceRuleOrGroupOriginal) : sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
5512
6401
  const independentCombinators = isRuleGroupTypeIC(query);
5513
6402
  const parentOfRuleToRemove = findPath(getParentPath(sourcePath), query);
@@ -5520,7 +6409,8 @@ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
5520
6409
  const newNewPath = [...nextPath];
5521
6410
  const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);
5522
6411
  if (!clone && sourcePath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
5523
- const parentOfTargetPath = findPath(getParentPath(newNewPath), query);
6412
+ const newNewParentPath = getParentPath(newNewPath);
6413
+ const parentOfTargetPath = findPath(newNewParentPath, query);
5524
6414
  const targetPathIndex = newNewPath.at(-1);
5525
6415
  parentOfTargetPath.rules.splice(targetPathIndex, 1, prepareRuleOrGroup(independentCombinators ? { rules: [
5526
6416
  targetRuleOrGroup,
@@ -5533,6 +6423,1301 @@ const groupInPlace = (query, sourcePathOrID, targetPathOrID, options = {}) => {
5533
6423
  return query;
5534
6424
  };
5535
6425
  //#endregion
5536
- export { LogType, TestID, add, addInPlace, betweenOperators, bigIntJsonParseReviver, bigIntJsonStringifyReplacer, celCombinatorMap, clsx, convertFromIC, convertQuery, convertToIC, cypherCombinatorMap, 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, defaultRuleGroupProcessorCypher, defaultRuleGroupProcessorDiagnostics, defaultRuleGroupProcessorDrizzle, defaultRuleGroupProcessorElasticSearch, defaultRuleGroupProcessorGremlin, defaultRuleGroupProcessorJSONata, defaultRuleGroupProcessorJsonLogic, defaultRuleGroupProcessorLDAP, defaultRuleGroupProcessorMongoDB, defaultRuleGroupProcessorMongoDBQuery, defaultRuleGroupProcessorNL, defaultRuleGroupProcessorParameterized, defaultRuleGroupProcessorPrisma, defaultRuleGroupProcessorSPARQL, defaultRuleGroupProcessorSQL, defaultRuleGroupProcessorSequelize, defaultRuleGroupProcessorSpEL, defaultRuleGroupProcessorTanStackDB, defaultRuleProcessorCEL, defaultRuleProcessorCypher, defaultRuleProcessorDrizzle, defaultRuleProcessorElasticSearch, defaultRuleProcessorGremlin, defaultRuleProcessorJSONata, defaultRuleProcessorJsonLogic, defaultRuleProcessorLDAP, defaultRuleProcessorMongoDB, defaultRuleProcessorMongoDBQuery, defaultRuleProcessorNL, defaultRuleProcessorParameterized, defaultRuleProcessorPrisma, defaultRuleProcessorSPARQL, defaultRuleProcessorSQL, defaultRuleProcessorSequelize, defaultRuleProcessorSpEL, defaultRuleProcessorTanStackDB, defaultSpELValueProcessor, defaultTranslations, defaultValidator, defaultValueProcessor, defaultValueProcessorByRule, defaultValueProcessorCELByRule, defaultValueProcessorMongoDBByRule, defaultValueProcessorNL, defaultValueProcessorSpELByRule, filterFieldsByComparator, findID, findPath, formatQuery, formatQueryOptionPresets, generateAccessibleDescription, generateID, getCommonAncestorPath, getFirstOption, getLikeWildcards, getMatchModesUtil, getNLTranslataion, getOption, getParentPath, getParseNumberMethod, getPathOfID, getQuoteFieldNamesWithArray, getQuotedFieldName, getRuleDefaultValue, getSQLConcat, getSubqueryElementAlias, getValidationClassNames, getValueSourcesUtil, group, groupInPlace, groupInvalidReasons, inOperators, 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, nullOperators, nullOrUndefinedOrEmpty, numericRegex, numerifyValues, objectEntries, objectKeys, parseNumber, pathIsDisabled, pathsAreEqual, preferAnyProp, preferFlagProps, preferProp, prepareOptionList, prepareRule, prepareRuleGroup, prepareRuleOrGroup, prismaFallback, prismaOperators, processMatchMode, queryBuilderFlagDefaults, regenerateID, regenerateIDs, relationalOperators, remove, removeInPlace, rootPath, shouldRenderAsNumber, sparqlVar, splitBy, sqlDialectPresets, standardClassnames, stripParamPrefix, subqueryElementAliasBase, substringOperators, toArray, toFlatOptionArray, toFullOption, toFullOptionList, toFullOptionMap, transformQuery, trimIfString, uniqByIdentifier, uniqByName, uniqOptGroups, uniqOptList, update, updateInPlace, uuidV4regex, withParamPrefix, wrapLikeFragment };
6426
+ //#region src/utils/queryActions.ts
6427
+ /**
6428
+ * Builds the query builder's six mutation handlers as pure functions of the current query.
6429
+ *
6430
+ * This is the framework-agnostic core of the action handlers in `useQueryBuilderSchema`. It owns
6431
+ * the policy that surrounds the query tools—disabled gating, the confirmation callback protocol,
6432
+ * `maxLevels`, and debug logging—so an implementation only has to supply its own storage: read
6433
+ * the current query, call the action, and apply a non-`undefined` result.
6434
+ *
6435
+ * @group Query Tools
6436
+ */
6437
+ const createQueryActions = (config = {}) => {
6438
+ const { qbId, combinators, idGenerator, maxLevels = Infinity, queryDisabled, respectDisabled = true, disabledPaths, resetOnFieldChange, resetOnOperatorChange, getRuleDefaultOperator, getValueSources, getRuleDefaultValue, getMatchModes, onAddRule, onAddGroup, onRemove, onMoveRule, onMoveGroup, onGroupRule, onGroupGroup, onLog } = config;
6439
+ const log = (payload) => onLog === null || onLog === void 0 ? void 0 : onLog(_objectSpread2({ qbId }, payload));
6440
+ const guards = {
6441
+ respectDisabled,
6442
+ queryDisabled,
6443
+ disabledPaths
6444
+ };
6445
+ /** Whether the mutation is blocked, using the same rules the query tools apply internally. */
6446
+ const blocked = (query, path, asParent = false) => !!getGuardAbortReason(query, path, guards, { asParent });
6447
+ return {
6448
+ addRule: (query, rule, parentPath, context) => {
6449
+ if (blocked(query, parentPath, true)) {
6450
+ log({
6451
+ type: LogType.parentPathDisabled,
6452
+ rule,
6453
+ parentPath,
6454
+ query
6455
+ });
6456
+ return;
6457
+ }
6458
+ const nextRule = onAddRule ? onAddRule(rule, parentPath, query, context) : true;
6459
+ if (!nextRule) {
6460
+ log({
6461
+ type: LogType.onAddRuleFalse,
6462
+ rule,
6463
+ parentPath,
6464
+ query
6465
+ });
6466
+ return;
6467
+ }
6468
+ const newRule = nextRule === true ? rule : nextRule;
6469
+ const newQuery = add(query, newRule, parentPath, {
6470
+ combinators,
6471
+ combinatorPreceding: newRule.combinatorPreceding,
6472
+ idGenerator
6473
+ });
6474
+ log({
6475
+ type: LogType.add,
6476
+ query,
6477
+ newQuery,
6478
+ newRule,
6479
+ parentPath
6480
+ });
6481
+ return newQuery;
6482
+ },
6483
+ addGroup: (query, ruleGroup, parentPath, context) => {
6484
+ var _combinatorPreceding;
6485
+ if (parentPath.length >= maxLevels) return void 0;
6486
+ if (blocked(query, parentPath, true)) {
6487
+ log({
6488
+ type: LogType.parentPathDisabled,
6489
+ ruleGroup,
6490
+ parentPath,
6491
+ query
6492
+ });
6493
+ return;
6494
+ }
6495
+ const nextGroup = onAddGroup ? onAddGroup(ruleGroup, parentPath, query, context) : true;
6496
+ if (!nextGroup) {
6497
+ log({
6498
+ type: LogType.onAddGroupFalse,
6499
+ ruleGroup,
6500
+ parentPath,
6501
+ query
6502
+ });
6503
+ return;
6504
+ }
6505
+ const newGroup = nextGroup === true ? ruleGroup : nextGroup;
6506
+ const newQuery = add(query, newGroup, parentPath, {
6507
+ combinators,
6508
+ combinatorPreceding: (_combinatorPreceding = newGroup.combinatorPreceding) !== null && _combinatorPreceding !== void 0 ? _combinatorPreceding : void 0,
6509
+ idGenerator
6510
+ });
6511
+ log({
6512
+ type: LogType.add,
6513
+ query,
6514
+ newQuery,
6515
+ newGroup,
6516
+ parentPath
6517
+ });
6518
+ return newQuery;
6519
+ },
6520
+ propChange: (query, prop, value, path) => {
6521
+ if (getGuardAbortReason(query, path, prop === "disabled" ? { queryDisabled } : guards)) {
6522
+ log({
6523
+ type: LogType.pathDisabled,
6524
+ path,
6525
+ prop,
6526
+ value,
6527
+ query
6528
+ });
6529
+ return;
6530
+ }
6531
+ const newQuery = update(query, prop, value, path, {
6532
+ resetOnFieldChange,
6533
+ resetOnOperatorChange,
6534
+ getRuleDefaultOperator,
6535
+ getValueSources,
6536
+ getRuleDefaultValue,
6537
+ getMatchModes
6538
+ });
6539
+ log({
6540
+ type: LogType.update,
6541
+ query,
6542
+ newQuery,
6543
+ prop,
6544
+ value,
6545
+ path
6546
+ });
6547
+ return newQuery;
6548
+ },
6549
+ removeRuleOrGroup: (query, path, context) => {
6550
+ if (blocked(query, path)) {
6551
+ log({
6552
+ type: LogType.pathDisabled,
6553
+ path,
6554
+ query
6555
+ });
6556
+ return;
6557
+ }
6558
+ const ruleOrGroup = findPath(path, query);
6559
+ /* v8 ignore next -- @preserve */
6560
+ if (!ruleOrGroup) return void 0;
6561
+ if (onRemove && !onRemove(ruleOrGroup, path, query, context)) {
6562
+ log({
6563
+ type: LogType.onRemoveFalse,
6564
+ ruleOrGroup,
6565
+ path,
6566
+ query
6567
+ });
6568
+ return;
6569
+ }
6570
+ const newQuery = remove(query, path);
6571
+ log({
6572
+ type: LogType.remove,
6573
+ query,
6574
+ newQuery,
6575
+ path,
6576
+ ruleOrGroup
6577
+ });
6578
+ return newQuery;
6579
+ },
6580
+ moveRule: (query, oldPath, newPath, clone, context) => {
6581
+ if (blocked(query, oldPath)) {
6582
+ log({
6583
+ type: LogType.pathDisabled,
6584
+ oldPath,
6585
+ newPath,
6586
+ query
6587
+ });
6588
+ return;
6589
+ }
6590
+ const ruleOrGroup = findPath(oldPath, query);
6591
+ if (!ruleOrGroup) return void 0;
6592
+ const nextQuery = move(query, oldPath, newPath, {
6593
+ clone,
6594
+ combinators,
6595
+ idGenerator
6596
+ });
6597
+ const isGroup = isRuleGroup(ruleOrGroup);
6598
+ const callback = isGroup ? onMoveGroup : onMoveRule;
6599
+ const callbackResult = callback ? callback(ruleOrGroup, oldPath, newPath, query, nextQuery, {
6600
+ clone,
6601
+ combinators
6602
+ }, context) : true;
6603
+ if (!callbackResult) {
6604
+ log({
6605
+ type: isGroup ? LogType.onMoveGroupFalse : LogType.onMoveRuleFalse,
6606
+ ruleOrGroup,
6607
+ oldPath,
6608
+ newPath,
6609
+ clone,
6610
+ query,
6611
+ nextQuery
6612
+ });
6613
+ return;
6614
+ }
6615
+ const newQuery = isRuleGroup(callbackResult) ? callbackResult : nextQuery;
6616
+ log({
6617
+ type: LogType.move,
6618
+ query,
6619
+ newQuery,
6620
+ oldPath,
6621
+ newPath,
6622
+ clone
6623
+ });
6624
+ return newQuery;
6625
+ },
6626
+ groupRule: (query, sourcePath, targetPath, clone, context) => {
6627
+ if (blocked(query, sourcePath)) {
6628
+ log({
6629
+ type: LogType.pathDisabled,
6630
+ sourcePath,
6631
+ targetPath,
6632
+ query
6633
+ });
6634
+ return;
6635
+ }
6636
+ const ruleOrGroup = findPath(sourcePath, query);
6637
+ if (!ruleOrGroup) return void 0;
6638
+ const nextQuery = group(query, sourcePath, targetPath, {
6639
+ clone,
6640
+ combinators,
6641
+ idGenerator
6642
+ });
6643
+ const isGroup = isRuleGroup(ruleOrGroup);
6644
+ const callback = isGroup ? onGroupGroup : onGroupRule;
6645
+ const callbackResult = callback ? callback(ruleOrGroup, sourcePath, targetPath, query, nextQuery, {
6646
+ clone,
6647
+ combinators
6648
+ }, context) : true;
6649
+ if (!callbackResult) {
6650
+ log({
6651
+ type: isGroup ? LogType.onGroupGroupFalse : LogType.onGroupRuleFalse,
6652
+ ruleOrGroup,
6653
+ sourcePath,
6654
+ targetPath,
6655
+ clone,
6656
+ query,
6657
+ nextQuery
6658
+ });
6659
+ return;
6660
+ }
6661
+ const newQuery = isRuleGroup(callbackResult) ? callbackResult : nextQuery;
6662
+ log({
6663
+ type: LogType.group,
6664
+ query,
6665
+ newQuery,
6666
+ sourcePath,
6667
+ targetPath,
6668
+ clone
6669
+ });
6670
+ return newQuery;
6671
+ }
6672
+ };
6673
+ };
6674
+ //#endregion
6675
+ //#region src/utils/ruleFactory.ts
6676
+ /**
6677
+ * Creates a rule from the given configuration, applying the same precedence as the
6678
+ * `QueryBuilder` component. The `value` is computed in a second pass, once `field`, `operator`,
6679
+ * and `valueSource` are known, since the default value depends on all three.
6680
+ *
6681
+ * @group Query Tools
6682
+ */
6683
+ const createRule = ({ fields, getDefaultField, getRuleDefaultOperator, getValueSources, getMatchModes, getRuleDefaultValue, idGenerator = generateID }) => {
6684
+ var _getFirstOption, _getFirstOption2;
6685
+ let field = (_getFirstOption = getFirstOption(fields)) !== null && _getFirstOption !== void 0 ? _getFirstOption : "";
6686
+ if (getDefaultField) if (typeof getDefaultField === "function") {
6687
+ const defaultField = getDefaultField(fields);
6688
+ if (defaultField) field = defaultField;
6689
+ } else field = getDefaultField;
6690
+ const fieldData = getOption(fields, field);
6691
+ const operator = getRuleDefaultOperator(field);
6692
+ const valueSource = (_getFirstOption2 = getFirstOption(getValueSources(field, operator, { fieldData }))) !== null && _getFirstOption2 !== void 0 ? _getFirstOption2 : "value";
6693
+ const matchMode = getFirstOption(getMatchModes(field, { fieldData }));
6694
+ const newRule = _objectSpread2({
6695
+ id: idGenerator(),
6696
+ field,
6697
+ operator,
6698
+ valueSource,
6699
+ value: ""
6700
+ }, matchMode ? { match: {
6701
+ mode: matchMode,
6702
+ threshold: 1
6703
+ } } : null);
6704
+ return _objectSpread2(_objectSpread2({}, newRule), {}, { value: getRuleDefaultValue(newRule) });
6705
+ };
6706
+ /**
6707
+ * Creates a group from the given configuration. Pass `true` for `independentCombinators` to omit
6708
+ * the `combinator` property.
6709
+ *
6710
+ * The group's own `id` is generated _before_ any contained rule's, matching the order the
6711
+ * `QueryBuilder` component has always used. This is observable when `idGenerator` is
6712
+ * deterministic, as it often is in tests.
6713
+ *
6714
+ * @group Query Tools
6715
+ */
6716
+ const createRuleGroup = ({ combinators, addRuleToNewGroups, createRule: createRuleMain, idGenerator = generateID }, independentCombinators) => {
6717
+ var _getFirstOption3;
6718
+ const id = idGenerator();
6719
+ const rules = addRuleToNewGroups ? [createRuleMain()] : [];
6720
+ if (independentCombinators) return {
6721
+ id,
6722
+ rules,
6723
+ not: false
6724
+ };
6725
+ return {
6726
+ id,
6727
+ rules,
6728
+ combinator: (_getFirstOption3 = getFirstOption(combinators)) !== null && _getFirstOption3 !== void 0 ? _getFirstOption3 : "",
6729
+ not: false
6730
+ };
6731
+ };
6732
+ //#endregion
6733
+ //#region src/utils/signature.ts
6734
+ /**
6735
+ * Signature returned when a change alters the _shape_ of the query—rules or groups added,
6736
+ * removed, moved, or reordered—rather than the properties of a single node. Structural changes
6737
+ * never coalesce with each other, so each one produces its own history entry.
6738
+ */
6739
+ const structuralSignature = "~structural";
6740
+ /**
6741
+ * Signature returned when two queries differ by reference only, with no observable difference
6742
+ * in their properties.
6743
+ */
6744
+ const unchangedSignature = "";
6745
+ /**
6746
+ * Returns the list of property names that differ between two nodes, ignoring `rules` (which is
6747
+ * compared structurally by the caller).
6748
+ */
6749
+ const changedProps = (prev, next) => {
6750
+ const keys = /* @__PURE__ */ new Set([...Object.keys(prev), ...Object.keys(next)]);
6751
+ keys.delete("rules");
6752
+ const changed = [];
6753
+ for (const key of keys) if (!Object.is(prev[key], next[key])) changed.push(key);
6754
+ return changed.toSorted();
6755
+ };
6756
+ const signatureOfNode = (prev, next, parentId, index) => {
6757
+ var _next$id3;
6758
+ if (prev === next) return "";
6759
+ if (typeof prev === "string" || typeof next === "string") return typeof prev === typeof next ? `${parentId}:combinator[${index}]` : structuralSignature;
6760
+ const prevIsGroup = isRuleGroup(prev);
6761
+ const nextIsGroup = isRuleGroup(next);
6762
+ if (prevIsGroup !== nextIsGroup) return structuralSignature;
6763
+ if (!prevIsGroup || !nextIsGroup) {
6764
+ var _next$id;
6765
+ const props = changedProps(prev, next);
6766
+ return props.length === 0 ? "" : `${(_next$id = next.id) !== null && _next$id !== void 0 ? _next$id : ""}:${props.join(",")}`;
6767
+ }
6768
+ if (prev.rules.length !== next.rules.length) return structuralSignature;
6769
+ const ownProps = changedProps(prev, next);
6770
+ let changedIndex = -1;
6771
+ for (const [i, prevRule] of prev.rules.entries()) if (prevRule !== next.rules[i]) {
6772
+ if (changedIndex !== -1) return structuralSignature;
6773
+ changedIndex = i;
6774
+ }
6775
+ if (changedIndex === -1) {
6776
+ var _next$id2;
6777
+ return ownProps.length === 0 ? "" : `${(_next$id2 = next.id) !== null && _next$id2 !== void 0 ? _next$id2 : ""}:${ownProps.join(",")}`;
6778
+ }
6779
+ if (ownProps.length > 0) return structuralSignature;
6780
+ return signatureOfNode(prev.rules[changedIndex], next.rules[changedIndex], (_next$id3 = next.id) !== null && _next$id3 !== void 0 ? _next$id3 : "", changedIndex);
6781
+ };
6782
+ /**
6783
+ * Describes _what changed_ between two versions of a query as a short string, so that
6784
+ * consecutive edits to the same property of the same rule (e.g. typing in a value editor) can
6785
+ * be recognized and coalesced into a single history entry.
6786
+ *
6787
+ * Returns {@link structuralSignature} for changes to the shape of the query, {@link unchangedSignature} when the
6788
+ * two queries differ by reference only, and `"<id>:<props>"` otherwise.
6789
+ *
6790
+ * The walk prunes on reference equality, so it costs O(depth) rather than O(size) for the
6791
+ * single-node edits that make up the overwhelming majority of changes.
6792
+ *
6793
+ * Note that this relies on the structural sharing that Immer—and therefore every query
6794
+ * produced by RQB's own update functions—guarantees: nodes that did not change keep their
6795
+ * identity. A query that has been wholly rebuilt (deep-cloned, round-tripped through JSON,
6796
+ * re-parsed from a string) shares no identity with its predecessor, so it is reported as
6797
+ * {@link structuralSignature} and will not coalesce. That is a graceful degradation—every change simply
6798
+ * gets its own history entry—but controlled components that clone the query on every change
6799
+ * will not benefit from coalescing.
6800
+ */
6801
+ const signatureOf = (prev, next) => signatureOfNode(prev, next, "", -1);
6802
+ //#endregion
6803
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/checkPrivateRedeclaration.js
6804
+ function _checkPrivateRedeclaration(e, t) {
6805
+ if (t.has(e)) throw new TypeError("Cannot initialize the same private elements twice on an object");
6806
+ }
6807
+ //#endregion
6808
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/classPrivateMethodInitSpec.js
6809
+ function _classPrivateMethodInitSpec(e, a) {
6810
+ _checkPrivateRedeclaration(e, a), a.add(e);
6811
+ }
6812
+ //#endregion
6813
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/classPrivateFieldInitSpec.js
6814
+ function _classPrivateFieldInitSpec(e, t, a) {
6815
+ _checkPrivateRedeclaration(e, t), t.set(e, a);
6816
+ }
6817
+ //#endregion
6818
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/assertClassBrand.js
6819
+ function _assertClassBrand(e, t, n) {
6820
+ if ("function" == typeof e ? e === t : e.has(t)) return arguments.length < 3 ? t : n;
6821
+ throw new TypeError("Private element is not present on this object");
6822
+ }
6823
+ //#endregion
6824
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/classPrivateFieldGet2.js
6825
+ function _classPrivateFieldGet2(s, a) {
6826
+ return s.get(_assertClassBrand(s, a));
6827
+ }
6828
+ //#endregion
6829
+ //#region \0@oxc-project+runtime@0.142.0/helpers/esm/classPrivateFieldSet2.js
6830
+ function _classPrivateFieldSet2(s, a, r) {
6831
+ return s.set(_assertClassBrand(s, a), r), r;
6832
+ }
6833
+ //#endregion
6834
+ //#region src/utils/QueryManager.ts
6835
+ const _excluded = ["strict", "onInvalidTarget"];
6836
+ const _excluded2 = ["strict", "onInvalidTarget"];
6837
+ const _excluded3 = ["strict", "onInvalidTarget"];
6838
+ const _excluded4 = ["strict", "onInvalidTarget"];
6839
+ const _excluded5 = ["strict", "onInvalidTarget"];
6840
+ const _excluded6 = ["strict", "onInvalidTarget"];
6841
+ let _Symbol$iterator;
6842
+ /**
6843
+ * Abort reasons that {@link QueryManager}'s `strict` mode treats as errors. The remaining
6844
+ * reasons—`"same-location"` and `"no-change"`—describe valid operations that had nothing to do,
6845
+ * so they are reported to `onInvalidTarget` but never throw.
6846
+ *
6847
+ * @group Query Tools
6848
+ */
6849
+ const strictAbortReasons = [
6850
+ "target-not-found",
6851
+ "parent-not-found",
6852
+ "parent-not-a-group",
6853
+ "destination-not-found",
6854
+ "root-not-allowed",
6855
+ "not-a-combinator-slot",
6856
+ "target-disabled",
6857
+ "parent-disabled",
6858
+ "max-levels-exceeded"
6859
+ ];
6860
+ const strictAbortReasonSet = new Set(strictAbortReasons);
6861
+ /**
6862
+ * Thrown by {@link QueryManager} methods in `strict` mode when an operation cannot be carried
6863
+ * out because its target could not be used.
6864
+ *
6865
+ * @group Query Tools
6866
+ */
6867
+ var QueryManagerError = class QueryManagerError extends Error {
6868
+ constructor(info) {
6869
+ super(`QueryManager: "${info.operation}" aborted (${info.reason})${info.pathOrID === void 0 ? "" : ` for target ${JSON.stringify(info.pathOrID)}`}.`);
6870
+ _defineProperty(this, "code", void 0);
6871
+ _defineProperty(this, "info", void 0);
6872
+ this.name = "QueryManagerError";
6873
+ this.code = info.reason;
6874
+ this.info = info;
6875
+ Object.setPrototypeOf(this, QueryManagerError.prototype);
6876
+ }
6877
+ };
6878
+ var _query = /* @__PURE__ */ new WeakMap();
6879
+ var _options = /* @__PURE__ */ new WeakMap();
6880
+ var _fields = /* @__PURE__ */ new WeakMap();
6881
+ var _fieldMap = /* @__PURE__ */ new WeakMap();
6882
+ var _operators = /* @__PURE__ */ new WeakMap();
6883
+ var _combinators = /* @__PURE__ */ new WeakMap();
6884
+ var _idGenerator = /* @__PURE__ */ new WeakMap();
6885
+ var _validator = /* @__PURE__ */ new WeakMap();
6886
+ var _strict = /* @__PURE__ */ new WeakMap();
6887
+ var _respectDisabled = /* @__PURE__ */ new WeakMap();
6888
+ var _onInvalidTarget = /* @__PURE__ */ new WeakMap();
6889
+ var _listeners = /* @__PURE__ */ new WeakMap();
6890
+ var _historyEnabled = /* @__PURE__ */ new WeakMap();
6891
+ var _maxHistory = /* @__PURE__ */ new WeakMap();
6892
+ var _coalesceMs = /* @__PURE__ */ new WeakMap();
6893
+ var _now = /* @__PURE__ */ new WeakMap();
6894
+ var _past = /* @__PURE__ */ new WeakMap();
6895
+ var _future = /* @__PURE__ */ new WeakMap();
6896
+ var _lastSig = /* @__PURE__ */ new WeakMap();
6897
+ var _lastAt = /* @__PURE__ */ new WeakMap();
6898
+ var _batchDepth = /* @__PURE__ */ new WeakMap();
6899
+ var _batchSnapshot = /* @__PURE__ */ new WeakMap();
6900
+ var _historyBypassed = /* @__PURE__ */ new WeakMap();
6901
+ var _cacheFor = /* @__PURE__ */ new WeakMap();
6902
+ var _idPathIndex = /* @__PURE__ */ new WeakMap();
6903
+ var _validation = /* @__PURE__ */ new WeakMap();
6904
+ var _QueryManager_brand = /* @__PURE__ */ new WeakSet();
6905
+ _Symbol$iterator = Symbol.iterator;
6906
+ /**
6907
+ * Stateful wrapper around the {@link add}/{@link remove}/{@link update}/{@link move}/
6908
+ * {@link insert}/{@link group} query tools, plus rule/group factories, {@link defaultValidator
6909
+ * validation}, and {@link formatQuery formatting}.
6910
+ *
6911
+ * The query is held internally, so each method takes the same arguments as its `queryTools`
6912
+ * counterpart minus the leading `query` parameter, and returns the manager itself for chaining.
6913
+ * Mutations use the non-`InPlace` tools, so a query previously handed out by
6914
+ * {@link QueryManager.getQuery} is never modified.
6915
+ *
6916
+ * ```ts
6917
+ * const q = new QueryManager(undefined, { fields });
6918
+ * q.add(q.createRule()).add({ field: 'firstName', operator: '=', value: 'Steve' });
6919
+ * q.format('sql');
6920
+ * ```
6921
+ *
6922
+ * Like the underlying query tools, methods are a no-op when the target path or `id` can't be
6923
+ * resolved (including attempts to remove the root group). By default nothing is thrown; pass
6924
+ * `strict: true` to raise a {@link QueryManagerError} instead, or `onInvalidTarget` to observe
6925
+ * aborted operations without changing control flow.
6926
+ *
6927
+ * @group Query Tools
6928
+ */
6929
+ var QueryManager = class QueryManager {
6930
+ constructor(query, options = {}) {
6931
+ var _options$idGenerator, _options$validator, _options$strict, _options$respectDisab, _options$history, _historyOptions$maxHi, _historyOptions$coale, _options$now, _options$operators, _options$combinators;
6932
+ _classPrivateMethodInitSpec(this, _QueryManager_brand);
6933
+ _classPrivateFieldInitSpec(this, _query, void 0);
6934
+ _classPrivateFieldInitSpec(this, _options, void 0);
6935
+ _classPrivateFieldInitSpec(this, _fields, void 0);
6936
+ _classPrivateFieldInitSpec(this, _fieldMap, void 0);
6937
+ _classPrivateFieldInitSpec(this, _operators, void 0);
6938
+ _classPrivateFieldInitSpec(this, _combinators, void 0);
6939
+ _classPrivateFieldInitSpec(this, _idGenerator, void 0);
6940
+ _classPrivateFieldInitSpec(this, _validator, void 0);
6941
+ _classPrivateFieldInitSpec(this, _strict, void 0);
6942
+ _classPrivateFieldInitSpec(this, _respectDisabled, void 0);
6943
+ _classPrivateFieldInitSpec(this, _onInvalidTarget, void 0);
6944
+ _classPrivateFieldInitSpec(this, _listeners, /* @__PURE__ */ new Set());
6945
+ _classPrivateFieldInitSpec(this, _historyEnabled, void 0);
6946
+ _classPrivateFieldInitSpec(this, _maxHistory, void 0);
6947
+ _classPrivateFieldInitSpec(this, _coalesceMs, void 0);
6948
+ _classPrivateFieldInitSpec(this, _now, void 0);
6949
+ _classPrivateFieldInitSpec(this, _past, []);
6950
+ _classPrivateFieldInitSpec(this, _future, []);
6951
+ _classPrivateFieldInitSpec(this, _lastSig, void 0);
6952
+ _classPrivateFieldInitSpec(this, _lastAt, 0);
6953
+ _classPrivateFieldInitSpec(this, _batchDepth, 0);
6954
+ _classPrivateFieldInitSpec(this, _batchSnapshot, void 0);
6955
+ _classPrivateFieldInitSpec(this, _historyBypassed, false);
6956
+ _classPrivateFieldInitSpec(this, _cacheFor, void 0);
6957
+ _classPrivateFieldInitSpec(this, _idPathIndex, void 0);
6958
+ _classPrivateFieldInitSpec(this, _validation, void 0);
6959
+ _defineProperty(
6960
+ this,
6961
+ /**
6962
+ * The current query. The returned object is frozen and structurally shared, so it is safe to
6963
+ * retain and compare by reference to detect changes.
6964
+ *
6965
+ * Like {@link QueryManager.subscribe}, this method is bound to the instance, so it can be
6966
+ * passed as a bare reference (e.g. as the `getSnapshot` argument to `useSyncExternalStore`).
6967
+ */
6968
+ "getQuery",
6969
+ () => _classPrivateFieldGet2(_query, this)
6970
+ );
6971
+ _defineProperty(
6972
+ this,
6973
+ /**
6974
+ * Registers a listener called after every change to the query, and returns a function that
6975
+ * unregisters it. Mutations that resolve to a no-op do not notify, and a
6976
+ * {@link QueryManager.batch batch} notifies once no matter how many changes it contains.
6977
+ *
6978
+ * Together with {@link QueryManager.getQuery}, this satisfies React's `useSyncExternalStore`
6979
+ * contract. Both methods are bound to the instance, so they are stable references across
6980
+ * renders and can be passed directly:
6981
+ *
6982
+ * ```ts
6983
+ * const query = useSyncExternalStore(q.subscribe, q.getQuery);
6984
+ * ```
6985
+ *
6986
+ * In React, prefer the `useQueryManager` hook from `react-querybuilder`, which wraps this.
6987
+ */
6988
+ "subscribe",
6989
+ (listener) => {
6990
+ _classPrivateFieldGet2(_listeners, this).add(listener);
6991
+ return () => {
6992
+ _classPrivateFieldGet2(_listeners, this).delete(listener);
6993
+ };
6994
+ }
6995
+ );
6996
+ _classPrivateFieldSet2(_options, this, options);
6997
+ _classPrivateFieldSet2(_idGenerator, this, (_options$idGenerator = options.idGenerator) !== null && _options$idGenerator !== void 0 ? _options$idGenerator : generateID);
6998
+ _classPrivateFieldSet2(_validator, this, (_options$validator = options.validator) !== null && _options$validator !== void 0 ? _options$validator : defaultValidator);
6999
+ _classPrivateFieldSet2(_strict, this, (_options$strict = options.strict) !== null && _options$strict !== void 0 ? _options$strict : false);
7000
+ _classPrivateFieldSet2(_respectDisabled, this, (_options$respectDisab = options.respectDisabled) !== null && _options$respectDisab !== void 0 ? _options$respectDisab : true);
7001
+ _classPrivateFieldSet2(_onInvalidTarget, this, options.onInvalidTarget);
7002
+ const history = (_options$history = options.history) !== null && _options$history !== void 0 ? _options$history : false;
7003
+ const historyOptions = typeof history === "object" ? history : {};
7004
+ _classPrivateFieldSet2(_historyEnabled, this, history !== false);
7005
+ _classPrivateFieldSet2(_maxHistory, this, (_historyOptions$maxHi = historyOptions.maxHistory) !== null && _historyOptions$maxHi !== void 0 ? _historyOptions$maxHi : 50);
7006
+ _classPrivateFieldSet2(_coalesceMs, this, (_historyOptions$coale = historyOptions.coalesceMs) !== null && _historyOptions$coale !== void 0 ? _historyOptions$coale : 500);
7007
+ _classPrivateFieldSet2(_now, this, (_options$now = options.now) !== null && _options$now !== void 0 ? _options$now : Date.now);
7008
+ const { optionList: fields, optionsMap: fieldMap } = prepareOptionList({
7009
+ optionList: options.fields,
7010
+ baseOption: options.baseField,
7011
+ autoSelectOption: options.autoSelectField
7012
+ });
7013
+ _classPrivateFieldSet2(_fields, this, freeze(fields, true));
7014
+ _classPrivateFieldSet2(_fieldMap, this, freeze(fieldMap, true));
7015
+ _classPrivateFieldSet2(_operators, this, prepareOptionList({
7016
+ optionList: (_options$operators = options.operators) !== null && _options$operators !== void 0 ? _options$operators : defaultOperators,
7017
+ baseOption: options.baseOperator,
7018
+ labelMap: defaultOperatorLabelMap,
7019
+ autoSelectOption: options.autoSelectOperator
7020
+ }).optionList);
7021
+ _classPrivateFieldSet2(_combinators, this, freeze(prepareOptionList({
7022
+ optionList: (_options$combinators = options.combinators) !== null && _options$combinators !== void 0 ? _options$combinators : defaultCombinators,
7023
+ baseOption: options.baseCombinator
7024
+ }).optionList, true));
7025
+ _classPrivateFieldSet2(_query, this, freeze(query ? prepareRuleGroup(query, { idGenerator: _classPrivateFieldGet2(_idGenerator, this) }) : this.createRuleGroup(), true));
7026
+ }
7027
+ /** Replaces the current query, ensuring every rule and group has an `id`. */
7028
+ setQuery(query) {
7029
+ _assertClassBrand(_QueryManager_brand, this, _commit).call(this, freeze(prepareRuleGroup(query, { idGenerator: _classPrivateFieldGet2(_idGenerator, this) }), true));
7030
+ return this;
7031
+ }
7032
+ /**
7033
+ * Creates a rule using the configured fields, operators, and defaults. The rule is not added
7034
+ * to the query—pass it to {@link QueryManager.add} or {@link QueryManager.insert}.
7035
+ */
7036
+ createRule() {
7037
+ return createRule({
7038
+ fields: _classPrivateFieldGet2(_fields, this),
7039
+ getDefaultField: _classPrivateFieldGet2(_options, this).getDefaultField,
7040
+ getRuleDefaultOperator: (f) => _assertClassBrand(_QueryManager_brand, this, _defaultOperator).call(this, f),
7041
+ getValueSources: (f, o) => _assertClassBrand(_QueryManager_brand, this, _valueSourcesFor).call(this, f, o),
7042
+ getMatchModes: (f) => _assertClassBrand(_QueryManager_brand, this, _matchModesFor).call(this, f),
7043
+ getRuleDefaultValue: (r) => _assertClassBrand(_QueryManager_brand, this, _defaultValue).call(this, r),
7044
+ idGenerator: _classPrivateFieldGet2(_idGenerator, this)
7045
+ });
7046
+ }
7047
+ /**
7048
+ * Creates a group. Pass `true` for a group with independent combinators. The group is not
7049
+ * added to the query—pass it to {@link QueryManager.add} or {@link QueryManager.insert}.
7050
+ */
7051
+ createRuleGroup(independentCombinators) {
7052
+ return createRuleGroup({
7053
+ combinators: _classPrivateFieldGet2(_combinators, this),
7054
+ addRuleToNewGroups: _classPrivateFieldGet2(_options, this).addRuleToNewGroups,
7055
+ createRule: () => this.createRule(),
7056
+ idGenerator: _classPrivateFieldGet2(_idGenerator, this)
7057
+ }, independentCombinators);
7058
+ }
7059
+ /**
7060
+ * Adds a rule or group to the end of the group at `parentPathOrID`, which defaults to the
7061
+ * root group.
7062
+ */
7063
+ add(ruleOrGroup, parentPathOrID = [], options = {}) {
7064
+ const { strict, onInvalidTarget } = options, toolOptions = _objectWithoutProperties(options, _excluded);
7065
+ _assertClassBrand(_QueryManager_brand, this, _commit).call(this, add(_classPrivateFieldGet2(_query, this), ruleOrGroup, parentPathOrID, _objectSpread2(_objectSpread2(_objectSpread2({}, _assertClassBrand(_QueryManager_brand, this, _toolOptions).call(this)), toolOptions), {}, { onAbort: _assertClassBrand(_QueryManager_brand, this, _onAbort).call(this, {
7066
+ strict,
7067
+ onInvalidTarget
7068
+ }) })));
7069
+ return this;
7070
+ }
7071
+ /** Removes the rule or group at the given path or `id`. The root group cannot be removed. */
7072
+ remove(pathOrID, options = {}) {
7073
+ const { strict, onInvalidTarget } = options, toolOptions = _objectWithoutProperties(options, _excluded2);
7074
+ _assertClassBrand(_QueryManager_brand, this, _commit).call(this, remove(_classPrivateFieldGet2(_query, this), pathOrID, _objectSpread2(_objectSpread2(_objectSpread2({}, _assertClassBrand(_QueryManager_brand, this, _guardOptions).call(this)), toolOptions), {}, { onAbort: _assertClassBrand(_QueryManager_brand, this, _onAbort).call(this, {
7075
+ strict,
7076
+ onInvalidTarget
7077
+ }) })));
7078
+ return this;
7079
+ }
7080
+ update(a, b, c, d) {
7081
+ var _args$optionsIndex;
7082
+ const optionsIndex = typeof a === "string" || Array.isArray(a) ? 3 : 2;
7083
+ const args = [
7084
+ a,
7085
+ b,
7086
+ c,
7087
+ d
7088
+ ];
7089
+ const _ref = (_args$optionsIndex = args[optionsIndex]) !== null && _args$optionsIndex !== void 0 ? _args$optionsIndex : {}, { strict, onInvalidTarget } = _ref, toolOptions = _objectWithoutProperties(_ref, _excluded3);
7090
+ args[optionsIndex] = _objectSpread2(_objectSpread2(_objectSpread2({}, _assertClassBrand(_QueryManager_brand, this, _updateOptions).call(this)), toolOptions), {}, { onAbort: _assertClassBrand(_QueryManager_brand, this, _onAbort).call(this, {
7091
+ strict,
7092
+ onInvalidTarget
7093
+ }) });
7094
+ _assertClassBrand(_QueryManager_brand, this, _commit).call(this, update(_classPrivateFieldGet2(_query, this), ...args.slice(0, optionsIndex + 1)));
7095
+ return this;
7096
+ }
7097
+ /** Moves the rule or group at `oldPathOrID` to `newPath`, or shifts it `'up'`/`'down'`. */
7098
+ move(oldPathOrID, newPath, options = {}) {
7099
+ const { strict, onInvalidTarget } = options, toolOptions = _objectWithoutProperties(options, _excluded4);
7100
+ _assertClassBrand(_QueryManager_brand, this, _commit).call(this, move(_classPrivateFieldGet2(_query, this), oldPathOrID, newPath, _objectSpread2(_objectSpread2(_objectSpread2({}, _assertClassBrand(_QueryManager_brand, this, _toolOptions).call(this)), toolOptions), {}, { onAbort: _assertClassBrand(_QueryManager_brand, this, _onAbort).call(this, {
7101
+ strict,
7102
+ onInvalidTarget
7103
+ }) })));
7104
+ return this;
7105
+ }
7106
+ /**
7107
+ * Inserts a rule or group at the given path. Unlike the other methods, this accepts a path
7108
+ * only—inserting _at_ an `id` would be ambiguous.
7109
+ */
7110
+ insert(ruleOrGroup, path, options = {}) {
7111
+ const { strict, onInvalidTarget } = options, toolOptions = _objectWithoutProperties(options, _excluded5);
7112
+ _assertClassBrand(_QueryManager_brand, this, _commit).call(this, insert(_classPrivateFieldGet2(_query, this), ruleOrGroup, path, _objectSpread2(_objectSpread2(_objectSpread2({}, _assertClassBrand(_QueryManager_brand, this, _toolOptions).call(this)), toolOptions), {}, { onAbort: _assertClassBrand(_QueryManager_brand, this, _onAbort).call(this, {
7113
+ strict,
7114
+ onInvalidTarget
7115
+ }) })));
7116
+ return this;
7117
+ }
7118
+ /**
7119
+ * Creates a new group at `targetPathOrID` containing the rules/groups currently at
7120
+ * `targetPathOrID` and `sourcePathOrID`.
7121
+ */
7122
+ group(sourcePathOrID, targetPathOrID, options = {}) {
7123
+ const { strict, onInvalidTarget } = options, toolOptions = _objectWithoutProperties(options, _excluded6);
7124
+ _assertClassBrand(_QueryManager_brand, this, _commit).call(this, group(_classPrivateFieldGet2(_query, this), sourcePathOrID, targetPathOrID, _objectSpread2(_objectSpread2(_objectSpread2({}, _assertClassBrand(_QueryManager_brand, this, _toolOptions).call(this)), toolOptions), {}, { onAbort: _assertClassBrand(_QueryManager_brand, this, _onAbort).call(this, {
7125
+ strict,
7126
+ onInvalidTarget
7127
+ }) })));
7128
+ return this;
7129
+ }
7130
+ /**
7131
+ * Creates an independent manager with the same configuration and the current query.
7132
+ *
7133
+ * Subscribers and history are _not_ carried over: the clone starts with no listeners and an
7134
+ * empty undo stack. Because every mutation produces a new query object, the two managers
7135
+ * share the initial query safely and diverge from the first change.
7136
+ *
7137
+ * Pass `{ regenerateIDs: true }` to give every rule and group in the clone a new `id`, which
7138
+ * is useful when both queries will be used together (e.g. inserted into the same tree).
7139
+ */
7140
+ clone(options) {
7141
+ const query = (options === null || options === void 0 ? void 0 : options.regenerateIDs) ? regenerateIDs(_classPrivateFieldGet2(_query, this), { idGenerator: _classPrivateFieldGet2(_idGenerator, this) }) : _classPrivateFieldGet2(_query, this);
7142
+ return new QueryManager(query, _classPrivateFieldGet2(_options, this));
7143
+ }
7144
+ /**
7145
+ * Runs `fn`, deferring history recording and subscriber notification until it returns. The
7146
+ * whole batch becomes a single undo step and triggers a single notification, or neither if
7147
+ * the query ends up unchanged.
7148
+ *
7149
+ * Batches may be nested; only the outermost one commits. If `fn` throws, the query and its
7150
+ * history are restored to their pre-batch state and the error propagates, so a batch either
7151
+ * applies completely or not at all.
7152
+ *
7153
+ * {@link QueryManager.undo}, {@link QueryManager.redo}, and {@link QueryManager.clearHistory}
7154
+ * may be called inside a batch; their notifications are deferred like everything else. Because
7155
+ * they manage the history stacks themselves, a batch containing one of them records no entry of
7156
+ * its own, leaving the stacks exactly as those methods left them.
7157
+ */
7158
+ batch(fn) {
7159
+ var _this$batchDepth;
7160
+ _classPrivateFieldSet2(_batchDepth, this, (_this$batchDepth = _classPrivateFieldGet2(_batchDepth, this), _this$batchDepth++, _this$batchDepth));
7161
+ if (_classPrivateFieldGet2(_batchDepth, this) === 1) _classPrivateFieldSet2(_batchSnapshot, this, {
7162
+ query: _classPrivateFieldGet2(_query, this),
7163
+ past: [..._classPrivateFieldGet2(_past, this)],
7164
+ future: [..._classPrivateFieldGet2(_future, this)],
7165
+ lastSig: _classPrivateFieldGet2(_lastSig, this),
7166
+ lastAt: _classPrivateFieldGet2(_lastAt, this)
7167
+ });
7168
+ try {
7169
+ fn();
7170
+ } catch (error) {
7171
+ if (_classPrivateFieldGet2(_batchDepth, this) === 1) {
7172
+ const snapshot = _classPrivateFieldGet2(_batchSnapshot, this);
7173
+ _classPrivateFieldSet2(_query, this, snapshot.query);
7174
+ _classPrivateFieldSet2(_past, this, snapshot.past);
7175
+ _classPrivateFieldSet2(_future, this, snapshot.future);
7176
+ _classPrivateFieldSet2(_lastSig, this, snapshot.lastSig);
7177
+ _classPrivateFieldSet2(_lastAt, this, snapshot.lastAt);
7178
+ }
7179
+ throw error;
7180
+ } finally {
7181
+ var _this$batchDepth3;
7182
+ _classPrivateFieldSet2(_batchDepth, this, (_this$batchDepth3 = _classPrivateFieldGet2(_batchDepth, this), _this$batchDepth3--, _this$batchDepth3));
7183
+ if (_classPrivateFieldGet2(_batchDepth, this) === 0) {
7184
+ const { query: base } = _classPrivateFieldGet2(_batchSnapshot, this);
7185
+ _classPrivateFieldSet2(_batchSnapshot, this, void 0);
7186
+ if (base !== _classPrivateFieldGet2(_query, this)) {
7187
+ if (!_classPrivateFieldGet2(_historyBypassed, this)) _assertClassBrand(_QueryManager_brand, this, _record).call(this, base, _classPrivateFieldGet2(_query, this));
7188
+ _assertClassBrand(_QueryManager_brand, this, _notify).call(this);
7189
+ }
7190
+ _classPrivateFieldSet2(_historyBypassed, this, false);
7191
+ }
7192
+ }
7193
+ return this;
7194
+ }
7195
+ /** Whether there is a previous query to restore. Always `false` unless `history` is enabled. */
7196
+ canUndo() {
7197
+ return _classPrivateFieldGet2(_past, this).length > 0;
7198
+ }
7199
+ /** Whether there is an undone query to restore. Always `false` unless `history` is enabled. */
7200
+ canRedo() {
7201
+ return _classPrivateFieldGet2(_future, this).length > 0;
7202
+ }
7203
+ /** Restores the previous query. No-op when {@link QueryManager.canUndo} is `false`. */
7204
+ undo() {
7205
+ if (_classPrivateFieldGet2(_past, this).length === 0) return this;
7206
+ _classPrivateFieldGet2(_future, this).unshift(_classPrivateFieldGet2(_query, this));
7207
+ _classPrivateFieldSet2(_query, this, _classPrivateFieldGet2(_past, this).pop());
7208
+ _classPrivateFieldSet2(_lastSig, this, void 0);
7209
+ _assertClassBrand(_QueryManager_brand, this, _markHistoryBypassed).call(this);
7210
+ if (_classPrivateFieldGet2(_batchDepth, this) === 0) _assertClassBrand(_QueryManager_brand, this, _notify).call(this);
7211
+ return this;
7212
+ }
7213
+ /** Restores the most recently undone query. No-op when {@link QueryManager.canRedo} is `false`. */
7214
+ redo() {
7215
+ if (_classPrivateFieldGet2(_future, this).length === 0) return this;
7216
+ _classPrivateFieldGet2(_past, this).push(_classPrivateFieldGet2(_query, this));
7217
+ _classPrivateFieldSet2(_query, this, _classPrivateFieldGet2(_future, this).shift());
7218
+ _classPrivateFieldSet2(_lastSig, this, void 0);
7219
+ _assertClassBrand(_QueryManager_brand, this, _markHistoryBypassed).call(this);
7220
+ if (_classPrivateFieldGet2(_batchDepth, this) === 0) _assertClassBrand(_QueryManager_brand, this, _notify).call(this);
7221
+ return this;
7222
+ }
7223
+ /** Discards all undo/redo history without changing the current query. */
7224
+ clearHistory() {
7225
+ _assertClassBrand(_QueryManager_brand, this, _markHistoryBypassed).call(this);
7226
+ _classPrivateFieldSet2(_past, this, []);
7227
+ _classPrivateFieldSet2(_future, this, []);
7228
+ _classPrivateFieldSet2(_lastSig, this, void 0);
7229
+ return this;
7230
+ }
7231
+ /**
7232
+ * The recorded history: `past` oldest first, `future` newest first. Both are copies, so
7233
+ * mutating them does not affect the manager.
7234
+ */
7235
+ getHistory() {
7236
+ return {
7237
+ past: [..._classPrivateFieldGet2(_past, this)],
7238
+ future: [..._classPrivateFieldGet2(_future, this)]
7239
+ };
7240
+ }
7241
+ /**
7242
+ * Validates the current query with the configured validator.
7243
+ *
7244
+ * The result is cached until the query changes, so a custom `validator` with side effects (or
7245
+ * one that depends on anything other than the query) may run fewer times than expected.
7246
+ */
7247
+ validate() {
7248
+ var _classPrivateFieldGet4;
7249
+ _assertClassBrand(_QueryManager_brand, this, _ensureCache).call(this);
7250
+ (_classPrivateFieldGet4 = _classPrivateFieldGet2(_validation, this)) !== null && _classPrivateFieldGet4 !== void 0 || _classPrivateFieldSet2(_validation, this, _classPrivateFieldGet2(_validator, this).call(this, _classPrivateFieldGet2(_query, this)));
7251
+ return _classPrivateFieldGet2(_validation, this);
7252
+ }
7253
+ format(options) {
7254
+ return formatQuery(_classPrivateFieldGet2(_query, this), options);
7255
+ }
7256
+ /**
7257
+ * Yields every rule and group in the query, depth-first in pre-order, starting with the root
7258
+ * group itself. Combinator strings in independent-combinator groups are skipped.
7259
+ *
7260
+ * ```ts
7261
+ * for (const { node, path, parent } of qm.walk({ rulesOnly: true })) {
7262
+ * console.log(path, node.field);
7263
+ * }
7264
+ * ```
7265
+ *
7266
+ * Traversal operates on the query as it was when iteration began, so mutating the manager
7267
+ * mid-iteration does not affect a walk already in progress. Because generators are lazy, that
7268
+ * happens on the first iteration step rather than when `walk` is called.
7269
+ *
7270
+ * @yields Every rule and group in the query, subject to `options`.
7271
+ */
7272
+ *walk(options = {}) {
7273
+ const { from, rulesOnly, groupsOnly } = options;
7274
+ let start = _classPrivateFieldGet2(_query, this);
7275
+ let startPath = [];
7276
+ let startParent = null;
7277
+ if (from !== void 0) {
7278
+ const path = _assertClassBrand(_QueryManager_brand, this, _toPath).call(this, from);
7279
+ const node = path && findPath(path, _classPrivateFieldGet2(_query, this));
7280
+ if (!path || !node) return;
7281
+ start = node;
7282
+ startPath = path;
7283
+ startParent = path.length === 0 ? null : findPath(getParentPath(path), _classPrivateFieldGet2(_query, this));
7284
+ }
7285
+ for (const entry of _assertClassBrand(_QueryManager_brand, this, _walkFrom).call(this, start, startPath, startParent)) {
7286
+ if (rulesOnly && isRuleGroup(entry.node)) continue;
7287
+ if (groupsOnly && !isRuleGroup(entry.node)) continue;
7288
+ yield entry;
7289
+ }
7290
+ }
7291
+ /** Yields every rule in the query. Shorthand for `walk({ ...options, rulesOnly: true })`. */
7292
+ rules(options = {}) {
7293
+ return this.walk(_objectSpread2(_objectSpread2({}, options), {}, { rulesOnly: true }));
7294
+ }
7295
+ /**
7296
+ * Yields every group in the query, including the root group. Shorthand for
7297
+ * `walk({ ...options, groupsOnly: true })`.
7298
+ */
7299
+ groups(options = {}) {
7300
+ return this.walk(_objectSpread2(_objectSpread2({}, options), {}, { groupsOnly: true }));
7301
+ }
7302
+ /** Returns the first node matching `predicate`, or `null` if there is none. */
7303
+ find(predicate, options = {}) {
7304
+ for (const entry of this.walk(options)) if (predicate(entry)) return entry;
7305
+ return null;
7306
+ }
7307
+ /** Returns every node matching `predicate`. */
7308
+ filter(predicate, options = {}) {
7309
+ const results = [];
7310
+ for (const entry of this.walk(options)) if (predicate(entry)) results.push(entry);
7311
+ return results;
7312
+ }
7313
+ /** Equivalent to {@link QueryManager.walk} with no options, enabling `for...of` and spread. */
7314
+ [_Symbol$iterator]() {
7315
+ return this.walk();
7316
+ }
7317
+ /**
7318
+ * Returns the rule or group at the given path, or `null` if the path can't be resolved.
7319
+ *
7320
+ * Unlike the standalone {@link findPath}, which can return `undefined` for an out-of-range
7321
+ * index, unresolvable paths are always normalized to `null` here.
7322
+ */
7323
+ findPath(path) {
7324
+ var _findPath;
7325
+ return (_findPath = findPath(path, _classPrivateFieldGet2(_query, this))) !== null && _findPath !== void 0 ? _findPath : null;
7326
+ }
7327
+ /**
7328
+ * Returns the rule or group with the given `id`, or `null` if there is none. Backed by an
7329
+ * index built once per query, so repeated lookups are constant time.
7330
+ */
7331
+ findID(id) {
7332
+ const path = _assertClassBrand(_QueryManager_brand, this, _index).call(this).get(id);
7333
+ return path === void 0 ? null : findPath(path, _classPrivateFieldGet2(_query, this));
7334
+ }
7335
+ /**
7336
+ * Returns the {@link Path} of the rule or group with the given `id`, or `null` if there is
7337
+ * none. Backed by an index built once per query, so repeated lookups are constant time.
7338
+ */
7339
+ getPathOfID(id) {
7340
+ var _this$index$get2;
7341
+ return (_this$index$get2 = _assertClassBrand(_QueryManager_brand, this, _index).call(this).get(id)) !== null && _this$index$get2 !== void 0 ? _this$index$get2 : null;
7342
+ }
7343
+ /**
7344
+ * Determines whether the rule or group at the given path is disabled, either itself or by an
7345
+ * ancestor group.
7346
+ */
7347
+ pathIsDisabled(path) {
7348
+ return pathIsDisabled(path, _classPrivateFieldGet2(_query, this));
7349
+ }
7350
+ /** Returns the rule or group at the given path or `id`, or `null` if it can't be resolved. */
7351
+ getNode(pathOrID) {
7352
+ var _findPath2;
7353
+ const path = _assertClassBrand(_QueryManager_brand, this, _toPath).call(this, pathOrID);
7354
+ return path === null ? null : (_findPath2 = findPath(path, _classPrivateFieldGet2(_query, this))) !== null && _findPath2 !== void 0 ? _findPath2 : null;
7355
+ }
7356
+ /**
7357
+ * Returns the rule at the given path or `id`, or `null` if it can't be resolved _or_ resolves
7358
+ * to a group.
7359
+ */
7360
+ getRule(pathOrID) {
7361
+ const node = this.getNode(pathOrID);
7362
+ return node && !isRuleGroup(node) ? node : null;
7363
+ }
7364
+ /**
7365
+ * Returns the group at the given path or `id`, or `null` if it can't be resolved _or_
7366
+ * resolves to a rule.
7367
+ */
7368
+ getGroup(pathOrID) {
7369
+ const node = this.getNode(pathOrID);
7370
+ return node && isRuleGroup(node) ? node : null;
7371
+ }
7372
+ /**
7373
+ * Returns the group containing the rule or group at the given path or `id`. Returns `null`
7374
+ * for the root group, which has no parent, and when the target can't be resolved.
7375
+ */
7376
+ getParent(pathOrID) {
7377
+ const path = _assertClassBrand(_QueryManager_brand, this, _toPath).call(this, pathOrID);
7378
+ if (path === null || path.length === 0) return null;
7379
+ if (!findPath(path, _classPrivateFieldGet2(_query, this))) return null;
7380
+ return findPath(getParentPath(path), _classPrivateFieldGet2(_query, this));
7381
+ }
7382
+ /**
7383
+ * The normalized field list, as the `QueryBuilder` component would render it. Needed to
7384
+ * populate a field selector.
7385
+ */
7386
+ getFields() {
7387
+ return _classPrivateFieldGet2(_fields, this);
7388
+ }
7389
+ /**
7390
+ * The normalized combinator list, as the `QueryBuilder` component would render it. Needed to
7391
+ * populate a combinator selector.
7392
+ */
7393
+ getCombinators() {
7394
+ return _classPrivateFieldGet2(_combinators, this);
7395
+ }
7396
+ /**
7397
+ * The field configuration for a field name. When the field isn't configured, returns the same
7398
+ * minimal fallback (`{ name, value, label }`, all set to the field name) that
7399
+ * {@link QueryManager.getRuleContext} reports as `fieldData`, so both access paths agree.
7400
+ */
7401
+ getFieldData(field) {
7402
+ return getFieldData(field, _classPrivateFieldGet2(_fieldMap, this));
7403
+ }
7404
+ /** The operator list for a field, mirroring `QueryBuilder`'s precedence. */
7405
+ getOperators(field) {
7406
+ return _assertClassBrand(_QueryManager_brand, this, _operatorsFor).call(this, field);
7407
+ }
7408
+ /** The value sources available for a field/operator pair. */
7409
+ getValueSources(field, operator) {
7410
+ return _assertClassBrand(_QueryManager_brand, this, _valueSourcesFor).call(this, field, operator);
7411
+ }
7412
+ /** The match modes available for a field. */
7413
+ getMatchModes(field) {
7414
+ return _assertClassBrand(_QueryManager_brand, this, _matchModesFor).call(this, field);
7415
+ }
7416
+ /** The value option list for a field/operator pair. */
7417
+ getValues(field, operator) {
7418
+ return _assertClassBrand(_QueryManager_brand, this, _valuesFor).call(this, field, operator);
7419
+ }
7420
+ /** The value editor type for a field/operator pair. */
7421
+ getValueEditorType(field, operator) {
7422
+ return _assertClassBrand(_QueryManager_brand, this, _valueEditorTypeFor).call(this, field, operator);
7423
+ }
7424
+ /**
7425
+ * Resolves everything about a rule that depends on the field/operator configuration—field data,
7426
+ * operators, value editor type, value list, value sources, match modes, and validation result.
7427
+ * Returns `null` when the target can't be resolved or isn't a rule.
7428
+ *
7429
+ * This is the same derivation the `useRule` hook performs, so a non-React implementation can
7430
+ * render a rule without reimplementing the configuration precedence rules.
7431
+ */
7432
+ getRuleContext(pathOrID) {
7433
+ const rule = this.getRule(pathOrID);
7434
+ if (!rule) return null;
7435
+ const validation = this.validate();
7436
+ return deriveRuleContext(rule, {
7437
+ fields: _classPrivateFieldGet2(_fields, this),
7438
+ fieldMap: _classPrivateFieldGet2(_fieldMap, this),
7439
+ getInputType: (f, o, misc) => {
7440
+ var _this$options$getInpu, _classPrivateFieldGet5, _classPrivateFieldGet6;
7441
+ return (_this$options$getInpu = (_classPrivateFieldGet5 = (_classPrivateFieldGet6 = _classPrivateFieldGet2(_options, this)).getInputType) === null || _classPrivateFieldGet5 === void 0 ? void 0 : _classPrivateFieldGet5.call(_classPrivateFieldGet6, f, o, misc)) !== null && _this$options$getInpu !== void 0 ? _this$options$getInpu : null;
7442
+ },
7443
+ getMatchModes: (f) => _assertClassBrand(_QueryManager_brand, this, _matchModesFor).call(this, f),
7444
+ getOperators: (f) => _assertClassBrand(_QueryManager_brand, this, _operatorsFor).call(this, f),
7445
+ getParameters: (f, o, misc) => _assertClassBrand(_QueryManager_brand, this, _parametersFor).call(this, f, o, misc),
7446
+ getValueEditorType: (f, o) => _assertClassBrand(_QueryManager_brand, this, _valueEditorTypeFor).call(this, f, o),
7447
+ getValues: (f, o) => _assertClassBrand(_QueryManager_brand, this, _valuesFor).call(this, f, o),
7448
+ getValueSources: (f, o) => this.getValueSources(f, o),
7449
+ getSubQueryBuilderProps: (f, misc) => {
7450
+ var _this$options$getSubQ, _classPrivateFieldGet7, _classPrivateFieldGet8;
7451
+ return (_this$options$getSubQ = (_classPrivateFieldGet7 = (_classPrivateFieldGet8 = _classPrivateFieldGet2(_options, this)).getSubQueryBuilderProps) === null || _classPrivateFieldGet7 === void 0 ? void 0 : _classPrivateFieldGet7.call(_classPrivateFieldGet8, f, misc)) !== null && _this$options$getSubQ !== void 0 ? _this$options$getSubQ : {};
7452
+ }
7453
+ }, {
7454
+ validationMap: typeof validation === "boolean" ? {} : validation,
7455
+ id: rule.id
7456
+ });
7457
+ }
7458
+ /**
7459
+ * Resolves everything about a rule group that depends on the combinator configuration, plus its
7460
+ * validation result. Returns `null` when the target can't be resolved or isn't a group.
7461
+ *
7462
+ * This is the same derivation the `useRuleGroup` hook performs.
7463
+ */
7464
+ getRuleGroupContext(pathOrID = []) {
7465
+ const ruleGroup = this.getGroup(pathOrID);
7466
+ if (!ruleGroup) return null;
7467
+ const validation = this.validate();
7468
+ return deriveRuleGroupContext(ruleGroup, _classPrivateFieldGet2(_combinators, this), {
7469
+ validationMap: typeof validation === "boolean" ? {} : validation,
7470
+ id: ruleGroup.id
7471
+ });
7472
+ }
7473
+ /** Whether the current query uses independent combinators. */
7474
+ isIC() {
7475
+ return isRuleGroupTypeIC(_classPrivateFieldGet2(_query, this));
7476
+ }
7477
+ /**
7478
+ * Returns the signature describing how the current query differs from `other`, as used by
7479
+ * this manager's history coalescing.
7480
+ */
7481
+ signatureOf(other) {
7482
+ return signatureOf(_classPrivateFieldGet2(_query, this), other);
7483
+ }
7484
+ /** Generates a {@link DiagnosticsResult}. Shorthand for `format('diagnostics')`. */
7485
+ diagnostics() {
7486
+ return formatQuery(_classPrivateFieldGet2(_query, this), "diagnostics");
7487
+ }
7488
+ /**
7489
+ * Returns the current query, so `JSON.stringify(queryManager)` produces the same output as
7490
+ * `JSON.stringify(queryManager.getQuery())`.
7491
+ */
7492
+ toJSON() {
7493
+ return _classPrivateFieldGet2(_query, this);
7494
+ }
7495
+ /**
7496
+ * Returns a new manager with the same configuration and the current query converted to use
7497
+ * independent combinators. Idempotent, and never modifies this manager. As with
7498
+ * {@link QueryManager.clone}, subscribers and history are not carried over.
7499
+ */
7500
+ toIC() {
7501
+ return new QueryManager(convertToIC(_classPrivateFieldGet2(_query, this)), _classPrivateFieldGet2(_options, this));
7502
+ }
7503
+ /**
7504
+ * Returns a new manager with the same configuration and the current query converted to use a
7505
+ * single combinator per group. Idempotent, and never modifies this manager. As with
7506
+ * {@link QueryManager.clone}, subscribers and history are not carried over.
7507
+ */
7508
+ fromIC() {
7509
+ return new QueryManager(convertFromIC(_classPrivateFieldGet2(_query, this)), _classPrivateFieldGet2(_options, this));
7510
+ }
7511
+ /**
7512
+ * Runs {@link transformQuery} against the current query and returns its result.
7513
+ *
7514
+ * Unlike {@link QueryManager.toIC}/{@link QueryManager.fromIC}, this returns the raw
7515
+ * transformed value rather than a new manager, since `transformQuery` can produce arbitrary
7516
+ * shapes that are no longer valid queries. This manager is never modified.
7517
+ */
7518
+ transform(options) {
7519
+ return transformQuery(_classPrivateFieldGet2(_query, this), options);
7520
+ }
7521
+ };
7522
+ /** Resolves the field configuration for a field name. */
7523
+ function _fieldData(field) {
7524
+ var _this$fieldMap$field;
7525
+ return (_this$fieldMap$field = _classPrivateFieldGet2(_fieldMap, this)[field]) !== null && _this$fieldMap$field !== void 0 ? _this$fieldMap$field : {};
7526
+ }
7527
+ /** Resolves the operator list for a field, mirroring `QueryBuilder`'s precedence. */
7528
+ function _operatorsFor(field) {
7529
+ return resolveOperatorList({
7530
+ field,
7531
+ fieldData: _assertClassBrand(_QueryManager_brand, this, _fieldData).call(this, field),
7532
+ getOperators: _classPrivateFieldGet2(_options, this).getOperators,
7533
+ operators: _classPrivateFieldGet2(_operators, this),
7534
+ baseOption: _classPrivateFieldGet2(_options, this).baseOperator,
7535
+ autoSelectOption: _classPrivateFieldGet2(_options, this).autoSelectOperator
7536
+ });
7537
+ }
7538
+ /** Resolves the default operator for a field, mirroring `QueryBuilder`'s precedence. */
7539
+ function _defaultOperator(field) {
7540
+ return resolveDefaultOperator({
7541
+ field,
7542
+ fieldData: _assertClassBrand(_QueryManager_brand, this, _fieldData).call(this, field),
7543
+ getDefaultOperator: _classPrivateFieldGet2(_options, this).getDefaultOperator,
7544
+ getOperators: (f) => _assertClassBrand(_QueryManager_brand, this, _operatorsFor).call(this, f)
7545
+ });
7546
+ }
7547
+ function _valueSourcesFor(field, operator) {
7548
+ return getValueSourcesUtil(_assertClassBrand(_QueryManager_brand, this, _fieldData).call(this, field), operator, _classPrivateFieldGet2(_options, this).getValueSources);
7549
+ }
7550
+ function _matchModesFor(field) {
7551
+ return getMatchModesUtil(_assertClassBrand(_QueryManager_brand, this, _fieldData).call(this, field), _classPrivateFieldGet2(_options, this).getMatchModes);
7552
+ }
7553
+ function _valuesFor(field, operator) {
7554
+ return resolveValueList({
7555
+ field,
7556
+ operator,
7557
+ fieldData: _assertClassBrand(_QueryManager_brand, this, _fieldData).call(this, field),
7558
+ getValues: _classPrivateFieldGet2(_options, this).getValues,
7559
+ autoSelectOption: _classPrivateFieldGet2(_options, this).autoSelectValue
7560
+ });
7561
+ }
7562
+ function _valueEditorTypeFor(field, operator) {
7563
+ return resolveValueEditorType({
7564
+ field,
7565
+ operator,
7566
+ fieldData: _assertClassBrand(_QueryManager_brand, this, _fieldData).call(this, field),
7567
+ getValueEditorType: _classPrivateFieldGet2(_options, this).getValueEditorType
7568
+ });
7569
+ }
7570
+ /** Computes the default `value` for a rule, mirroring `QueryBuilder`'s precedence. */
7571
+ function _defaultValue(rule) {
7572
+ const { getDefaultValue, getParameters, listsAsArrays } = _classPrivateFieldGet2(_options, this);
7573
+ return getRuleDefaultValue(rule, {
7574
+ fieldData: _assertClassBrand(_QueryManager_brand, this, _fieldData).call(this, rule.field),
7575
+ fields: _classPrivateFieldGet2(_fields, this),
7576
+ listsAsArrays,
7577
+ getValueEditorType: (f, o) => _assertClassBrand(_QueryManager_brand, this, _valueEditorTypeFor).call(this, f, o),
7578
+ getValues: (f, o) => _assertClassBrand(_QueryManager_brand, this, _valuesFor).call(this, f, o),
7579
+ getDefaultValue: getDefaultValue && ((r, misc) => getDefaultValue(r, misc)),
7580
+ getParameters: getParameters && ((f, o, misc) => _assertClassBrand(_QueryManager_brand, this, _parametersFor).call(this, f, o, misc))
7581
+ });
7582
+ }
7583
+ /**
7584
+ * Resolves the parameter list for a field/operator pair, normalized the same way as every
7585
+ * other option list. Shared by {@link QueryManager.#defaultValue} and
7586
+ * {@link QueryManager.getRuleContext} so both see the same shape.
7587
+ */
7588
+ function _parametersFor(field, operator, misc) {
7589
+ var _this$options$getPara, _classPrivateFieldGet2$1, _classPrivateFieldGet3;
7590
+ return prepareOptionList({
7591
+ optionList: (_this$options$getPara = (_classPrivateFieldGet2$1 = (_classPrivateFieldGet3 = _classPrivateFieldGet2(_options, this)).getParameters) === null || _classPrivateFieldGet2$1 === void 0 ? void 0 : _classPrivateFieldGet2$1.call(_classPrivateFieldGet3, field, operator, misc)) !== null && _this$options$getPara !== void 0 ? _this$options$getPara : [],
7592
+ autoSelectOption: _classPrivateFieldGet2(_options, this).autoSelectValue
7593
+ }).optionList;
7594
+ }
7595
+ /** Defaults shared by every mutating method, overridable per call. */
7596
+ function _guardOptions() {
7597
+ const { maxLevels } = _classPrivateFieldGet2(_options, this);
7598
+ return {
7599
+ maxLevels: (maxLevels !== null && maxLevels !== void 0 ? maxLevels : 0) > 0 ? Number(maxLevels) : Infinity,
7600
+ respectDisabled: _classPrivateFieldGet2(_respectDisabled, this),
7601
+ disabledPaths: _classPrivateFieldGet2(_options, this).disabledPaths,
7602
+ queryDisabled: _classPrivateFieldGet2(_options, this).queryDisabled
7603
+ };
7604
+ }
7605
+ function _toolOptions() {
7606
+ return _objectSpread2({
7607
+ combinators: _classPrivateFieldGet2(_combinators, this),
7608
+ idGenerator: _classPrivateFieldGet2(_idGenerator, this)
7609
+ }, _assertClassBrand(_QueryManager_brand, this, _guardOptions).call(this));
7610
+ }
7611
+ /**
7612
+ * Builds the `onAbort` handler passed to the query tools, applying the per-call overrides on
7613
+ * top of the manager's own options.
7614
+ */
7615
+ function _onAbort({ strict, onInvalidTarget }) {
7616
+ const strictMain = strict !== null && strict !== void 0 ? strict : _classPrivateFieldGet2(_strict, this);
7617
+ const handler = onInvalidTarget !== null && onInvalidTarget !== void 0 ? onInvalidTarget : _classPrivateFieldGet2(_onInvalidTarget, this);
7618
+ return (info) => {
7619
+ handler === null || handler === void 0 || handler(info);
7620
+ if (strictMain && strictAbortReasonSet.has(info.reason)) throw new QueryManagerError(info);
7621
+ };
7622
+ }
7623
+ /** Defaults for {@link update}, so resets mirror `QueryBuilder`'s behavior. */
7624
+ function _updateOptions() {
7625
+ return _objectSpread2({
7626
+ getRuleDefaultOperator: (f) => _assertClassBrand(_QueryManager_brand, this, _defaultOperator).call(this, f),
7627
+ getRuleDefaultValue: (r) => _assertClassBrand(_QueryManager_brand, this, _defaultValue).call(this, r),
7628
+ getValueSources: (f, o) => _assertClassBrand(_QueryManager_brand, this, _valueSourcesFor).call(this, f, o),
7629
+ getMatchModes: (f) => _assertClassBrand(_QueryManager_brand, this, _matchModesFor).call(this, f),
7630
+ resetOnFieldChange: _classPrivateFieldGet2(_options, this).resetOnFieldChange,
7631
+ resetOnOperatorChange: _classPrivateFieldGet2(_options, this).resetOnOperatorChange
7632
+ }, _assertClassBrand(_QueryManager_brand, this, _guardOptions).call(this));
7633
+ }
7634
+ /**
7635
+ * Applies a new query, recording history and notifying subscribers as appropriate. Every
7636
+ * mutation funnels through here. A tool that could not resolve its target returns the same
7637
+ * query object, which is treated as a no-op.
7638
+ */
7639
+ function _commit(next) {
7640
+ const prev = _classPrivateFieldGet2(_query, this);
7641
+ if (prev === next) return;
7642
+ _classPrivateFieldSet2(_query, this, next);
7643
+ if (_classPrivateFieldGet2(_batchDepth, this) > 0) return;
7644
+ _assertClassBrand(_QueryManager_brand, this, _record).call(this, prev, next);
7645
+ _assertClassBrand(_QueryManager_brand, this, _notify).call(this);
7646
+ }
7647
+ /**
7648
+ * Records a change, either as a new history entry or by absorbing it into the current one.
7649
+ * Mirrors the recording semantics of the `react-querybuilder/history` entry point.
7650
+ */
7651
+ function _record(prev, next) {
7652
+ if (!_classPrivateFieldGet2(_historyEnabled, this)) return;
7653
+ const sig = signatureOf(prev, next);
7654
+ if (sig === "") return;
7655
+ const now = _classPrivateFieldGet2(_now, this).call(this);
7656
+ if (!(sig !== "~structural" && sig === _classPrivateFieldGet2(_lastSig, this) && now - _classPrivateFieldGet2(_lastAt, this) < _classPrivateFieldGet2(_coalesceMs, this))) {
7657
+ _classPrivateFieldGet2(_past, this).push(prev);
7658
+ if (_classPrivateFieldGet2(_past, this).length > _classPrivateFieldGet2(_maxHistory, this)) _classPrivateFieldGet2(_past, this).shift();
7659
+ _classPrivateFieldSet2(_future, this, []);
7660
+ }
7661
+ _classPrivateFieldSet2(_lastSig, this, sig);
7662
+ _classPrivateFieldSet2(_lastAt, this, now);
7663
+ }
7664
+ function _notify() {
7665
+ for (const listener of _classPrivateFieldGet2(_listeners, this)) listener();
7666
+ }
7667
+ /**
7668
+ * Records that a history-stack method ran inside the current batch. Those methods manage
7669
+ * `#past`/`#future` themselves, so the batch must not also record an entry on completion —
7670
+ * doing so would push a duplicate onto `#past` and clear the redo stack that `undo` just
7671
+ * populated.
7672
+ */
7673
+ function _markHistoryBypassed() {
7674
+ if (_classPrivateFieldGet2(_batchDepth, this) > 0) _classPrivateFieldSet2(_historyBypassed, this, true);
7675
+ }
7676
+ /**
7677
+ * Discards every cached derivation when the query has been replaced since they were computed.
7678
+ * Called at the top of each cached reader.
7679
+ */
7680
+ function _ensureCache() {
7681
+ if (_classPrivateFieldGet2(_cacheFor, this) === _classPrivateFieldGet2(_query, this)) return;
7682
+ _classPrivateFieldSet2(_cacheFor, this, _classPrivateFieldGet2(_query, this));
7683
+ _classPrivateFieldSet2(_idPathIndex, this, void 0);
7684
+ _classPrivateFieldSet2(_validation, this, void 0);
7685
+ }
7686
+ /**
7687
+ * The single traversal implementation. Combinator strings in independent-combinator groups
7688
+ * are skipped.
7689
+ *
7690
+ * @yields The subtree rooted at `node`, depth-first in pre-order, starting with `node` itself.
7691
+ */
7692
+ function* _walkFrom(node, path, parent) {
7693
+ yield {
7694
+ node,
7695
+ path,
7696
+ parent
7697
+ };
7698
+ if (!isRuleGroup(node)) return;
7699
+ const startGroup = node;
7700
+ for (const [index, child] of startGroup.rules.entries()) {
7701
+ if (typeof child === "string") continue;
7702
+ yield* _assertClassBrand(_QueryManager_brand, this, _walkFrom).call(this, child, [...path, index], startGroup);
7703
+ }
7704
+ }
7705
+ /** Builds (once per query) the `id` to {@link Path} index backing `findID`/`getPathOfID`. */
7706
+ function _index() {
7707
+ _assertClassBrand(_QueryManager_brand, this, _ensureCache).call(this);
7708
+ if (!_classPrivateFieldGet2(_idPathIndex, this)) {
7709
+ const index = /* @__PURE__ */ new Map();
7710
+ for (const { node, path } of _assertClassBrand(_QueryManager_brand, this, _walkFrom).call(this, _classPrivateFieldGet2(_query, this), [], null)) if (node.id !== void 0 && !index.has(node.id)) index.set(node.id, path);
7711
+ _classPrivateFieldSet2(_idPathIndex, this, index);
7712
+ }
7713
+ return _classPrivateFieldGet2(_idPathIndex, this);
7714
+ }
7715
+ /** Resolves a path or `id` to a path, or `null` when the `id` isn't present. */
7716
+ function _toPath(pathOrID) {
7717
+ var _this$index$get;
7718
+ return typeof pathOrID === "string" ? (_this$index$get = _assertClassBrand(_QueryManager_brand, this, _index).call(this).get(pathOrID)) !== null && _this$index$get !== void 0 ? _this$index$get : null : pathOrID;
7719
+ }
7720
+ //#endregion
7721
+ export { LogType, QueryManager, QueryManagerError, TestID, add, addInPlace, betweenOperators, bigIntJsonParseReviver, bigIntJsonStringifyReplacer, celCombinatorMap, clsx, coerceBigIntValue, coerceInputType, convertFromIC, convertQuery, convertToIC, createQueryActions, createRule, createRuleGroup, cypherCombinatorMap, defaultCELValueProcessor, defaultCoalesceMs, defaultCombinatorLabelMap, defaultCombinators, defaultCombinatorsExtended, defaultControlClassnames, defaultExportOperatorMap, defaultJoinChar, defaultMatchModes, defaultMaxHistory, defaultMongoDBValueProcessor, defaultNLTranslations, defaultOperatorLabelMap, defaultOperatorNegationMap, defaultOperatorProcessorNL, defaultOperatorProcessorSQL, defaultOperators, defaultPlaceholderFieldGroupLabel, defaultPlaceholderFieldLabel, defaultPlaceholderFieldName, defaultPlaceholderLabel, defaultPlaceholderName, defaultPlaceholderOperatorGroupLabel, defaultPlaceholderOperatorLabel, defaultPlaceholderOperatorName, defaultPlaceholderValueGroupLabel, defaultPlaceholderValueLabel, defaultPlaceholderValueName, defaultRuleGroupProcessorCEL, defaultRuleGroupProcessorCypher, defaultRuleGroupProcessorDiagnostics, defaultRuleGroupProcessorDrizzle, defaultRuleGroupProcessorElasticSearch, defaultRuleGroupProcessorGremlin, defaultRuleGroupProcessorJSONata, defaultRuleGroupProcessorJsonLogic, defaultRuleGroupProcessorLDAP, defaultRuleGroupProcessorMongoDB, defaultRuleGroupProcessorMongoDBQuery, defaultRuleGroupProcessorNL, defaultRuleGroupProcessorParameterized, defaultRuleGroupProcessorPrisma, defaultRuleGroupProcessorSPARQL, defaultRuleGroupProcessorSQL, defaultRuleGroupProcessorSequelize, defaultRuleGroupProcessorSpEL, defaultRuleGroupProcessorTanStackDB, defaultRuleProcessorCEL, defaultRuleProcessorCypher, defaultRuleProcessorDrizzle, defaultRuleProcessorElasticSearch, defaultRuleProcessorGremlin, defaultRuleProcessorJSONata, defaultRuleProcessorJsonLogic, defaultRuleProcessorLDAP, defaultRuleProcessorMongoDB, defaultRuleProcessorMongoDBQuery, defaultRuleProcessorNL, defaultRuleProcessorParameterized, defaultRuleProcessorPrisma, defaultRuleProcessorSPARQL, defaultRuleProcessorSQL, defaultRuleProcessorSequelize, defaultRuleProcessorSpEL, defaultRuleProcessorTanStackDB, defaultSpELValueProcessor, defaultTranslations, defaultValidator, defaultValueProcessor, defaultValueProcessorByRule, defaultValueProcessorCELByRule, defaultValueProcessorMongoDBByRule, defaultValueProcessorNL, defaultValueProcessorSpELByRule, derivePathInfo, deriveQueryBuilderClassNames, deriveRuleClassName, deriveRuleClassNames, deriveRuleContext, deriveRuleGroupClassNames, deriveRuleGroupContext, deriveRuleGroupOuterClassName, deriveRuleOuterClassName, exceedsMaxLevels, filterFieldsByComparator, findID, findPath, formatQuery, formatQueryOptionPresets, generateAccessibleDescription, generateID, getCommonAncestorPath, getFieldData, getFirstOption, getGuardAbortReason, getLikeWildcards, getMatchModesUtil, getMultiValueUpdate, getNLTranslataion, getOption, getParametersAsList, getParentPath, getParseNumberMethod, getPathOfID, getQuoteFieldNamesWithArray, getQuotedFieldName, getRuleDefaultValue, getRuleGroupCombinator, getRuleInputType, getRuleValidationResult, getRuleValueEditorType, getRuleValueSourceOptions, getRuleValues, getSQLConcat, getSubqueryElementAlias, getValidationClassNames, getValueEditorReset, getValueSelectorUpdate, getValueSourcesUtil, group, groupInPlace, groupInvalidReasons, hideValueControlsForOperator, inOperators, insert, insertInPlace, isAncestor, isBetweenOperator, 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, normalizeValueSelectorValue, nullFreeArray, nullOperators, nullOrUndefinedOrEmpty, numericRegex, numerifyValues, objectEntries, objectKeys, parseNumber, pathIsDisabled, pathIsDisabledByPaths, pathsAreEqual, preferAnyProp, preferFlagProps, preferProp, prepareOptionList, prepareRule, prepareRuleGroup, prepareRuleOrGroup, prismaFallback, prismaOperators, processMatchMode, queryBuilderFlagDefaults, regenerateID, regenerateIDs, relationalOperators, remove, removeInPlace, resolveCandidateQuery, resolveDefaultOperator, resolveOperatorList, resolveValueEditorType, resolveValueList, rootPath, shouldRenderAsNumber, signatureOf, sparqlVar, splitBy, sqlDialectPresets, standardClassnames, strictAbortReasons, stripParamPrefix, structuralSignature, subqueryElementAliasBase, substringOperators, toArray, toFlatOptionArray, toFullOption, toFullOptionList, toFullOptionMap, transformQuery, trimIfString, unchangedSignature, uniqByIdentifier, uniqByName, uniqOptGroups, uniqOptList, update, updateInPlace, uuidV4regex, withParamPrefix, wrapLikeFragment };
5537
7722
 
5538
7723
  //# sourceMappingURL=react-querybuilder_core.legacy-esm.js.map