@react-querybuilder/core 8.9.0

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 (80) hide show
  1. package/README.md +84 -0
  2. package/dist/arrayUtils-D5EoIsKP.js +164 -0
  3. package/dist/arrayUtils-D5EoIsKP.js.map +1 -0
  4. package/dist/basic-C8xXKHIA.d.ts +1235 -0
  5. package/dist/cjs/index.d.ts +1 -0
  6. package/dist/cjs/index.js +6 -0
  7. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +4786 -0
  8. package/dist/cjs/react-querybuilder_core.cjs.development.js +4033 -0
  9. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -0
  10. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +4786 -0
  11. package/dist/cjs/react-querybuilder_core.cjs.production.js +2 -0
  12. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -0
  13. package/dist/convertQuery-DAqoID3O.js +87 -0
  14. package/dist/convertQuery-DAqoID3O.js.map +1 -0
  15. package/dist/export-DyrnTh6K.d.ts +452 -0
  16. package/dist/formatQuery.d.ts +667 -0
  17. package/dist/formatQuery.js +2428 -0
  18. package/dist/formatQuery.js.map +1 -0
  19. package/dist/import-Cksobmln.d.ts +28 -0
  20. package/dist/isRuleGroup-DqAs2x4E.js +120 -0
  21. package/dist/isRuleGroup-DqAs2x4E.js.map +1 -0
  22. package/dist/objectUtils-BBZSfZJz.js +17 -0
  23. package/dist/objectUtils-BBZSfZJz.js.map +1 -0
  24. package/dist/optGroupUtils-CXLgyg2i.js +138 -0
  25. package/dist/optGroupUtils-CXLgyg2i.js.map +1 -0
  26. package/dist/parseCEL.d.ts +34 -0
  27. package/dist/parseCEL.js +2593 -0
  28. package/dist/parseCEL.js.map +1 -0
  29. package/dist/parseJSONata.d.ts +36 -0
  30. package/dist/parseJSONata.js +5884 -0
  31. package/dist/parseJSONata.js.map +1 -0
  32. package/dist/parseJsonLogic.d.ts +36 -0
  33. package/dist/parseJsonLogic.js +191 -0
  34. package/dist/parseJsonLogic.js.map +1 -0
  35. package/dist/parseMongoDB.d.ts +79 -0
  36. package/dist/parseMongoDB.js +267 -0
  37. package/dist/parseMongoDB.js.map +1 -0
  38. package/dist/parseNumber-Bcys1kOH.js +31 -0
  39. package/dist/parseNumber-Bcys1kOH.js.map +1 -0
  40. package/dist/parseSQL.d.ts +37 -0
  41. package/dist/parseSQL.js +6626 -0
  42. package/dist/parseSQL.js.map +1 -0
  43. package/dist/parseSpEL.d.ts +34 -0
  44. package/dist/parseSpEL.js +2911 -0
  45. package/dist/parseSpEL.js.map +1 -0
  46. package/dist/prepareQueryObjects-BqFEs4eV.js +172 -0
  47. package/dist/prepareQueryObjects-BqFEs4eV.js.map +1 -0
  48. package/dist/query-builder-layout.css +1 -0
  49. package/dist/query-builder-layout.css.map +1 -0
  50. package/dist/query-builder-layout.scss +4 -0
  51. package/dist/query-builder.css +1 -0
  52. package/dist/query-builder.css.map +1 -0
  53. package/dist/query-builder.scss +2 -0
  54. package/dist/react-querybuilder_core.d.mts +4786 -0
  55. package/dist/react-querybuilder_core.legacy-esm.d.ts +4786 -0
  56. package/dist/react-querybuilder_core.legacy-esm.js +3916 -0
  57. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -0
  58. package/dist/react-querybuilder_core.mjs +3852 -0
  59. package/dist/react-querybuilder_core.mjs.map +1 -0
  60. package/dist/react-querybuilder_core.production.d.mts +4786 -0
  61. package/dist/react-querybuilder_core.production.mjs +2 -0
  62. package/dist/react-querybuilder_core.production.mjs.map +1 -0
  63. package/dist/styles/_functions.scss +14 -0
  64. package/dist/styles/_layout.scss +201 -0
  65. package/dist/styles/_main.scss +114 -0
  66. package/dist/styles/_root.scss +66 -0
  67. package/dist/styles/_variables.scss +66 -0
  68. package/dist/transformQuery-FL_nlpp5.js +47 -0
  69. package/dist/transformQuery-FL_nlpp5.js.map +1 -0
  70. package/dist/transformQuery.d.ts +118 -0
  71. package/dist/transformQuery.js +4 -0
  72. package/formatQuery/package.json +4 -0
  73. package/package.json +146 -0
  74. package/parseCEL/package.json +4 -0
  75. package/parseJSONata/package.json +4 -0
  76. package/parseJsonLogic/package.json +4 -0
  77. package/parseMongoDB/package.json +4 -0
  78. package/parseSQL/package.json +4 -0
  79. package/parseSpEL/package.json +4 -0
  80. package/transformQuery/package.json +4 -0
@@ -0,0 +1,3916 @@
1
+ import { produce } from "immer";
2
+ import { numericQuantity, numericRegex as numericRegex$1 } from "numeric-quantity";
3
+
4
+ //#region src/defaults.ts
5
+ /**
6
+ * @group Defaults
7
+ */
8
+ const defaultPlaceholderName = "~";
9
+ /**
10
+ * @group Defaults
11
+ */
12
+ const defaultPlaceholderLabel = "------";
13
+ /**
14
+ * Default `name` for placeholder option in the `fields` array.
15
+ *
16
+ * @group Defaults
17
+ */
18
+ const defaultPlaceholderFieldName = defaultPlaceholderName;
19
+ /**
20
+ * Default `label` for placeholder option in the `fields` array.
21
+ *
22
+ * @group Defaults
23
+ */
24
+ const defaultPlaceholderFieldLabel = defaultPlaceholderLabel;
25
+ /**
26
+ * Default `label` for placeholder option group in the `fields` array.
27
+ *
28
+ * @group Defaults
29
+ */
30
+ const defaultPlaceholderFieldGroupLabel = defaultPlaceholderLabel;
31
+ /**
32
+ * Default `name` for placeholder option in the `operators` array.
33
+ *
34
+ * @group Defaults
35
+ */
36
+ const defaultPlaceholderOperatorName = defaultPlaceholderName;
37
+ /**
38
+ * Default `label` for placeholder option in the `operators` array.
39
+ *
40
+ * @group Defaults
41
+ */
42
+ const defaultPlaceholderOperatorLabel = defaultPlaceholderLabel;
43
+ /**
44
+ * Default `label` for placeholder option group in the `operators` array.
45
+ *
46
+ * @group Defaults
47
+ */
48
+ const defaultPlaceholderOperatorGroupLabel = defaultPlaceholderLabel;
49
+ /**
50
+ * Default `name` for placeholder option in the `values` array.
51
+ *
52
+ * @group Defaults
53
+ */
54
+ const defaultPlaceholderValueName = defaultPlaceholderName;
55
+ /**
56
+ * Default `label` for placeholder option in the `values` array.
57
+ *
58
+ * @group Defaults
59
+ */
60
+ const defaultPlaceholderValueLabel = defaultPlaceholderLabel;
61
+ /**
62
+ * Default `label` for placeholder option group in the `values` array.
63
+ *
64
+ * @group Defaults
65
+ */
66
+ const defaultPlaceholderValueGroupLabel = defaultPlaceholderLabel;
67
+ /**
68
+ * Default character used to `.join` and `.split` arrays.
69
+ *
70
+ * @group Defaults
71
+ */
72
+ const defaultJoinChar = ",";
73
+ const defaultOperatorLabelMap = {
74
+ "=": "=",
75
+ "!=": "!=",
76
+ "<": "<",
77
+ ">": ">",
78
+ "<=": "<=",
79
+ ">=": ">=",
80
+ contains: "contains",
81
+ beginsWith: "begins with",
82
+ endsWith: "ends with",
83
+ doesNotContain: "does not contain",
84
+ doesNotBeginWith: "does not begin with",
85
+ doesNotEndWith: "does not end with",
86
+ null: "is null",
87
+ notNull: "is not null",
88
+ in: "in",
89
+ notIn: "not in",
90
+ between: "between",
91
+ notBetween: "not between"
92
+ };
93
+ const defaultCombinatorLabelMap = {
94
+ and: "AND",
95
+ or: "OR",
96
+ xor: "XOR"
97
+ };
98
+ /**
99
+ * Default operator list.
100
+ *
101
+ * @group Defaults
102
+ */
103
+ const defaultOperators = [
104
+ {
105
+ name: "=",
106
+ value: "=",
107
+ label: "="
108
+ },
109
+ {
110
+ name: "!=",
111
+ value: "!=",
112
+ label: "!="
113
+ },
114
+ {
115
+ name: "<",
116
+ value: "<",
117
+ label: "<"
118
+ },
119
+ {
120
+ name: ">",
121
+ value: ">",
122
+ label: ">"
123
+ },
124
+ {
125
+ name: "<=",
126
+ value: "<=",
127
+ label: "<="
128
+ },
129
+ {
130
+ name: ">=",
131
+ value: ">=",
132
+ label: ">="
133
+ },
134
+ {
135
+ name: "contains",
136
+ value: "contains",
137
+ label: "contains"
138
+ },
139
+ {
140
+ name: "beginsWith",
141
+ value: "beginsWith",
142
+ label: "begins with"
143
+ },
144
+ {
145
+ name: "endsWith",
146
+ value: "endsWith",
147
+ label: "ends with"
148
+ },
149
+ {
150
+ name: "doesNotContain",
151
+ value: "doesNotContain",
152
+ label: "does not contain"
153
+ },
154
+ {
155
+ name: "doesNotBeginWith",
156
+ value: "doesNotBeginWith",
157
+ label: "does not begin with"
158
+ },
159
+ {
160
+ name: "doesNotEndWith",
161
+ value: "doesNotEndWith",
162
+ label: "does not end with"
163
+ },
164
+ {
165
+ name: "null",
166
+ value: "null",
167
+ label: "is null"
168
+ },
169
+ {
170
+ name: "notNull",
171
+ value: "notNull",
172
+ label: "is not null"
173
+ },
174
+ {
175
+ name: "in",
176
+ value: "in",
177
+ label: "in"
178
+ },
179
+ {
180
+ name: "notIn",
181
+ value: "notIn",
182
+ label: "not in"
183
+ },
184
+ {
185
+ name: "between",
186
+ value: "between",
187
+ label: "between"
188
+ },
189
+ {
190
+ name: "notBetween",
191
+ value: "notBetween",
192
+ label: "not between"
193
+ }
194
+ ];
195
+ /**
196
+ * Map of default operators to their respective opposite/negating operators.
197
+ *
198
+ * @group Defaults
199
+ */
200
+ const defaultOperatorNegationMap = {
201
+ "=": "!=",
202
+ "!=": "=",
203
+ "<": ">=",
204
+ "<=": ">",
205
+ ">": "<=",
206
+ ">=": "<",
207
+ beginsWith: "doesNotBeginWith",
208
+ doesNotBeginWith: "beginsWith",
209
+ endsWith: "doesNotEndWith",
210
+ doesNotEndWith: "endsWith",
211
+ contains: "doesNotContain",
212
+ doesNotContain: "contains",
213
+ between: "notBetween",
214
+ notBetween: "between",
215
+ in: "notIn",
216
+ notIn: "in",
217
+ notNull: "null",
218
+ null: "notNull"
219
+ };
220
+ /**
221
+ * Default combinator list.
222
+ *
223
+ * @group Defaults
224
+ */
225
+ const defaultCombinators = [{
226
+ name: "and",
227
+ value: "and",
228
+ label: "AND"
229
+ }, {
230
+ name: "or",
231
+ value: "or",
232
+ label: "OR"
233
+ }];
234
+ /**
235
+ * Default combinator list, with `XOR` added.
236
+ *
237
+ * @group Defaults
238
+ */
239
+ const defaultCombinatorsExtended = [...defaultCombinators, {
240
+ name: "xor",
241
+ value: "xor",
242
+ label: "XOR"
243
+ }];
244
+ /**
245
+ * Default match modes.
246
+ *
247
+ * @group Defaults
248
+ */
249
+ const defaultMatchModes = [
250
+ {
251
+ name: "all",
252
+ value: "all",
253
+ label: "all"
254
+ },
255
+ {
256
+ name: "some",
257
+ value: "some",
258
+ label: "some"
259
+ },
260
+ {
261
+ name: "none",
262
+ value: "none",
263
+ label: "none"
264
+ },
265
+ {
266
+ name: "atLeast",
267
+ value: "atLeast",
268
+ label: "at least"
269
+ },
270
+ {
271
+ name: "atMost",
272
+ value: "atMost",
273
+ label: "at most"
274
+ },
275
+ {
276
+ name: "exactly",
277
+ value: "exactly",
278
+ label: "exactly"
279
+ }
280
+ ];
281
+ /**
282
+ * Standard classnames applied to each component.
283
+ *
284
+ * @group Defaults
285
+ */
286
+ const standardClassnames = {
287
+ queryBuilder: "queryBuilder",
288
+ ruleGroup: "ruleGroup",
289
+ header: "ruleGroup-header",
290
+ body: "ruleGroup-body",
291
+ combinators: "ruleGroup-combinators",
292
+ addRule: "ruleGroup-addRule",
293
+ addGroup: "ruleGroup-addGroup",
294
+ cloneRule: "rule-cloneRule",
295
+ cloneGroup: "ruleGroup-cloneGroup",
296
+ removeGroup: "ruleGroup-remove",
297
+ notToggle: "ruleGroup-notToggle",
298
+ rule: "rule",
299
+ fields: "rule-fields",
300
+ matchMode: "rule-matchMode",
301
+ matchThreshold: "rule-matchThreshold",
302
+ operators: "rule-operators",
303
+ value: "rule-value",
304
+ removeRule: "rule-remove",
305
+ betweenRules: "betweenRules",
306
+ valid: "queryBuilder-valid",
307
+ invalid: "queryBuilder-invalid",
308
+ shiftActions: "shiftActions",
309
+ dndDragging: "dndDragging",
310
+ dndOver: "dndOver",
311
+ dndCopy: "dndCopy",
312
+ dndGroup: "dndGroup",
313
+ dndDropNotAllowed: "dndDropNotAllowed",
314
+ dragHandle: "queryBuilder-dragHandle",
315
+ disabled: "queryBuilder-disabled",
316
+ lockRule: "rule-lock",
317
+ lockGroup: "ruleGroup-lock",
318
+ valueSource: "rule-valueSource",
319
+ valueListItem: "rule-value-list-item",
320
+ branches: "queryBuilder-branches",
321
+ justified: "queryBuilder-justified",
322
+ hasSubQuery: "rule-hasSubQuery"
323
+ };
324
+ /**
325
+ * Default classnames for each component.
326
+ *
327
+ * @group Defaults
328
+ */
329
+ const defaultControlClassnames = {
330
+ queryBuilder: "",
331
+ ruleGroup: "",
332
+ header: "",
333
+ body: "",
334
+ combinators: "",
335
+ addRule: "",
336
+ addGroup: "",
337
+ cloneRule: "",
338
+ cloneGroup: "",
339
+ removeGroup: "",
340
+ notToggle: "",
341
+ rule: "",
342
+ fields: "",
343
+ matchMode: "",
344
+ matchThreshold: "",
345
+ operators: "",
346
+ value: "",
347
+ removeRule: "",
348
+ shiftActions: "",
349
+ dragHandle: "",
350
+ lockRule: "",
351
+ lockGroup: "",
352
+ valueSource: "",
353
+ actionElement: "",
354
+ valueSelector: "",
355
+ betweenRules: "",
356
+ valid: "",
357
+ invalid: "",
358
+ dndDragging: "",
359
+ dndOver: "",
360
+ dndGroup: "",
361
+ dndCopy: "",
362
+ dndDropNotAllowed: "",
363
+ disabled: "",
364
+ valueListItem: "",
365
+ branches: "",
366
+ hasSubQuery: ""
367
+ };
368
+ /**
369
+ * Default reason codes for a group being invalid.
370
+ *
371
+ * @group Defaults
372
+ */
373
+ const groupInvalidReasons = {
374
+ empty: "empty",
375
+ invalidCombinator: "invalid combinator",
376
+ invalidIndependentCombinators: "invalid independent combinators"
377
+ };
378
+ /**
379
+ * Component identifiers for testing.
380
+ *
381
+ * @group Defaults
382
+ */
383
+ const TestID = {
384
+ rule: "rule",
385
+ ruleGroup: "rule-group",
386
+ inlineCombinator: "inline-combinator",
387
+ addGroup: "add-group",
388
+ removeGroup: "remove-group",
389
+ cloneGroup: "clone-group",
390
+ cloneRule: "clone-rule",
391
+ addRule: "add-rule",
392
+ removeRule: "remove-rule",
393
+ combinators: "combinators",
394
+ fields: "fields",
395
+ operators: "operators",
396
+ valueEditor: "value-editor",
397
+ notToggle: "not-toggle",
398
+ shiftActions: "shift-actions",
399
+ dragHandle: "drag-handle",
400
+ lockRule: "lock-rule",
401
+ lockGroup: "lock-group",
402
+ valueSourceSelector: "value-source-selector",
403
+ matchModeEditor: "match-mode-editor"
404
+ };
405
+ const LogType = {
406
+ parentPathDisabled: "action aborted: parent path disabled",
407
+ pathDisabled: "action aborted: path is disabled",
408
+ queryUpdate: "query updated",
409
+ onAddRuleFalse: "onAddRule callback returned false",
410
+ onAddGroupFalse: "onAddGroup callback returned false",
411
+ onGroupRuleFalse: "onGroupRule callback returned false",
412
+ onGroupGroupFalse: "onGroupGroup callback returned false",
413
+ onMoveRuleFalse: "onMoveRule callback returned false",
414
+ onMoveGroupFalse: "onMoveGroup callback returned false",
415
+ onRemoveFalse: "onRemove callback returned false",
416
+ add: "rule or group added",
417
+ remove: "rule or group removed",
418
+ update: "rule or group updated",
419
+ move: "rule or group moved",
420
+ group: "rule or group grouped with another"
421
+ };
422
+ /**
423
+ * The {@link Path} of the root group.
424
+ *
425
+ * @group Defaults
426
+ */
427
+ const rootPath = [];
428
+
429
+ //#endregion
430
+ //#region src/utils/arrayUtils.ts
431
+ /**
432
+ * Splits a string by a given character (see {@link defaultJoinChar}). Escaped characters
433
+ * (characters preceded by a backslash) will not apply to the split, and the backslash will
434
+ * be removed in the array element. Inverse of {@link joinWith}.
435
+ *
436
+ * @example
437
+ * splitBy('this\\,\\,that,,the other,,,\\,')
438
+ * // or
439
+ * splitBy('this\\,\\,that,,the other,,,\\,', ',')
440
+ * // would return
441
+ * ['this,,that', '', 'the other', '', '', ',']
442
+ */
443
+ const splitBy = (str, splitChar = defaultJoinChar) => typeof str === "string" ? str.split(`\\${splitChar}`).map((c) => c.split(splitChar)).reduce((prev, curr, idx) => {
444
+ if (idx === 0) return curr;
445
+ return [
446
+ ...prev.slice(0, -1),
447
+ `${prev.at(-1)}${splitChar}${curr[0]}`,
448
+ ...curr.slice(1)
449
+ ];
450
+ }, []) : [];
451
+ /**
452
+ * Joins an array of strings using the given character (see {@link defaultJoinChar}). When
453
+ * the given character appears in an array element, a backslash will be added just before it
454
+ * to distinguish it from the join character. Effectively the inverse of {@link splitBy}.
455
+ *
456
+ * TIP: The join character can actually be a string of any length. Only the first character
457
+ * will be searched for in the array elements and preceded by a backslash.
458
+ *
459
+ * @example
460
+ * joinWith(['this,,that', '', 'the other', '', '', ','], ', ')
461
+ * // would return
462
+ * 'this\\,\\,that, , the other, , , \\,'
463
+ */
464
+ const joinWith = (strArr, joinChar = defaultJoinChar) => strArr.map((str) => `${str !== null && str !== void 0 ? str : ""}`.replaceAll(joinChar[0], `\\${joinChar[0]}`)).join(joinChar);
465
+ /**
466
+ * Trims the value if it is a string. Otherwise returns the value as is.
467
+ */
468
+ const trimIfString = (val) => typeof val === "string" ? val.trim() : val;
469
+ /**
470
+ * Splits a string by comma then trims each element. Arrays are returned as is except
471
+ * any string elements are trimmed.
472
+ */
473
+ const toArray = (v, { retainEmptyStrings } = {}) => Array.isArray(v) ? v.map((v$1) => trimIfString(v$1)) : typeof v === "string" ? splitBy(v, defaultJoinChar).filter(retainEmptyStrings ? () => true : (s) => !/^\s*$/.test(s)).map((s) => s.trim()) : typeof v === "number" ? [v] : [];
474
+ /**
475
+ * Determines if an array is free of `null`/`undefined`.
476
+ */
477
+ const nullFreeArray = (arr) => arr.every((el) => el === false || (el !== null && el !== void 0 ? el : false) !== false);
478
+
479
+ //#endregion
480
+ //#region src/utils/clsx.ts
481
+ // istanbul ignore next
482
+ function toVal(mix) {
483
+ let k;
484
+ let y;
485
+ let str = "";
486
+ if (typeof mix === "string" || typeof mix === "number") str += mix;
487
+ else if (typeof mix === "object") {
488
+ if (Array.isArray(mix)) {
489
+ const len = mix.length;
490
+ for (k = 0; k < len; k++) if (mix[k] && (y = toVal(mix[k]))) {
491
+ str && (str += " ");
492
+ str += y;
493
+ }
494
+ } else for (y in mix) if (mix[y]) {
495
+ str && (str += " ");
496
+ str += y;
497
+ }
498
+ }
499
+ return str;
500
+ }
501
+ // istanbul ignore next
502
+ function clsx(...args) {
503
+ let i = 0;
504
+ let tmp;
505
+ let x;
506
+ let str = "";
507
+ const len = args.length;
508
+ for (; i < len; i++) if ((tmp = args[i]) && (x = toVal(tmp))) {
509
+ str && (str += " ");
510
+ str += x;
511
+ }
512
+ return str;
513
+ }
514
+
515
+ //#endregion
516
+ //#region src/utils/misc.ts
517
+ /**
518
+ * Converts a value to lowercase if it's a string, otherwise returns the value as is.
519
+ */
520
+ // istanbul ignore next
521
+ const lc = (v) => typeof v === "string" ? v.toLowerCase() : v;
522
+ /**
523
+ * Regex matching numeric strings. Passes for positive/negative integers, decimals,
524
+ * and E notation, with optional surrounding whitespace.
525
+ */
526
+ const numericRegex = new RegExp(numericRegex$1.source.replace(/^\^/, String.raw`^\s*`).replace(/\$$/, String.raw`\s*$`));
527
+ /**
528
+ * Determines if a variable is a plain old JavaScript object, aka POJO.
529
+ */
530
+ const isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype;
531
+ /**
532
+ * Simple helper to determine whether a value is null, undefined, or an empty string.
533
+ */
534
+ const nullOrUndefinedOrEmpty = (value) => value === null || value === void 0 || value === "";
535
+
536
+ //#endregion
537
+ //#region src/utils/isRuleGroup.ts
538
+ /**
539
+ * Determines if an object is a {@link RuleGroupType} or {@link RuleGroupTypeIC}.
540
+ */
541
+ const isRuleGroup = (rg) => isPojo(rg) && Array.isArray(rg.rules);
542
+ /**
543
+ * Determines if an object is a {@link RuleGroupType}.
544
+ */
545
+ const isRuleGroupType = (rg) => isRuleGroup(rg) && typeof rg.combinator === "string";
546
+ /**
547
+ * Determines if an object is a {@link RuleGroupTypeIC}.
548
+ */
549
+ const isRuleGroupTypeIC = (rg) => isRuleGroup(rg) && rg.combinator === void 0;
550
+
551
+ //#endregion
552
+ //#region \0@oxc-project+runtime@0.89.0/helpers/typeof.js
553
+ function _typeof(o) {
554
+ "@babel/helpers - typeof";
555
+ return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o$1) {
556
+ return typeof o$1;
557
+ } : function(o$1) {
558
+ return o$1 && "function" == typeof Symbol && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
559
+ }, _typeof(o);
560
+ }
561
+
562
+ //#endregion
563
+ //#region \0@oxc-project+runtime@0.89.0/helpers/toPrimitive.js
564
+ function toPrimitive(t, r) {
565
+ if ("object" != _typeof(t) || !t) return t;
566
+ var e = t[Symbol.toPrimitive];
567
+ if (void 0 !== e) {
568
+ var i = e.call(t, r || "default");
569
+ if ("object" != _typeof(i)) return i;
570
+ throw new TypeError("@@toPrimitive must return a primitive value.");
571
+ }
572
+ return ("string" === r ? String : Number)(t);
573
+ }
574
+
575
+ //#endregion
576
+ //#region \0@oxc-project+runtime@0.89.0/helpers/toPropertyKey.js
577
+ function toPropertyKey(t) {
578
+ var i = toPrimitive(t, "string");
579
+ return "symbol" == _typeof(i) ? i : i + "";
580
+ }
581
+
582
+ //#endregion
583
+ //#region \0@oxc-project+runtime@0.89.0/helpers/defineProperty.js
584
+ function _defineProperty(e, r, t) {
585
+ return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
586
+ value: t,
587
+ enumerable: !0,
588
+ configurable: !0,
589
+ writable: !0
590
+ }) : e[r] = t, e;
591
+ }
592
+
593
+ //#endregion
594
+ //#region \0@oxc-project+runtime@0.89.0/helpers/objectSpread2.js
595
+ function ownKeys(e, r) {
596
+ var t = Object.keys(e);
597
+ if (Object.getOwnPropertySymbols) {
598
+ var o = Object.getOwnPropertySymbols(e);
599
+ r && (o = o.filter(function(r$1) {
600
+ return Object.getOwnPropertyDescriptor(e, r$1).enumerable;
601
+ })), t.push.apply(t, o);
602
+ }
603
+ return t;
604
+ }
605
+ function _objectSpread2(e) {
606
+ for (var r = 1; r < arguments.length; r++) {
607
+ var t = null != arguments[r] ? arguments[r] : {};
608
+ r % 2 ? ownKeys(Object(t), !0).forEach(function(r$1) {
609
+ _defineProperty(e, r$1, t[r$1]);
610
+ }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function(r$1) {
611
+ Object.defineProperty(e, r$1, Object.getOwnPropertyDescriptor(t, r$1));
612
+ });
613
+ }
614
+ return e;
615
+ }
616
+
617
+ //#endregion
618
+ //#region \0@oxc-project+runtime@0.89.0/helpers/objectWithoutPropertiesLoose.js
619
+ function _objectWithoutPropertiesLoose(r, e) {
620
+ if (null == r) return {};
621
+ var t = {};
622
+ for (var n in r) if ({}.hasOwnProperty.call(r, n)) {
623
+ if (e.includes(n)) continue;
624
+ t[n] = r[n];
625
+ }
626
+ return t;
627
+ }
628
+
629
+ //#endregion
630
+ //#region \0@oxc-project+runtime@0.89.0/helpers/objectWithoutProperties.js
631
+ function _objectWithoutProperties(e, t) {
632
+ if (null == e) return {};
633
+ var o, r, i = _objectWithoutPropertiesLoose(e, t);
634
+ if (Object.getOwnPropertySymbols) {
635
+ var s = Object.getOwnPropertySymbols(e);
636
+ for (r = 0; r < s.length; r++) o = s[r], t.includes(o) || {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]);
637
+ }
638
+ return i;
639
+ }
640
+
641
+ //#endregion
642
+ //#region src/utils/convertQuery.ts
643
+ const _excluded = ["combinator"];
644
+ const combinatorLevels = [
645
+ "or",
646
+ "xor",
647
+ "and"
648
+ ];
649
+ const isSameString = (a, b) => lc(a) === b;
650
+ const generateRuleGroupICWithConsistentCombinators = (rg, baseCombinatorLevel = 0) => {
651
+ const baseCombinator = combinatorLevels[baseCombinatorLevel];
652
+ if (!rg.rules.includes(baseCombinator)) return baseCombinatorLevel < combinatorLevels.length - 2 ? generateRuleGroupICWithConsistentCombinators(rg, baseCombinatorLevel + 1) : rg;
653
+ return produce(rg, (draft) => {
654
+ let cursor = 0;
655
+ while (cursor < draft.rules.length - 2) {
656
+ if (isSameString(draft.rules[cursor + 1], baseCombinator)) {
657
+ cursor += 2;
658
+ continue;
659
+ }
660
+ const nextBaseCombinatorIndex = draft.rules.findIndex((r, i) => i > cursor && typeof r === "string" && lc(r) === baseCombinator);
661
+ if (nextBaseCombinatorIndex === -1) {
662
+ draft.rules.splice(cursor, draft.rules.length, generateRuleGroupICWithConsistentCombinators({ rules: draft.rules.slice(cursor) }, baseCombinatorLevel + 1));
663
+ break;
664
+ } else draft.rules.splice(cursor, nextBaseCombinatorIndex - cursor, generateRuleGroupICWithConsistentCombinators({ rules: draft.rules.slice(cursor, nextBaseCombinatorIndex) }, baseCombinatorLevel + 1));
665
+ }
666
+ });
667
+ };
668
+ /**
669
+ * Converts a {@link RuleGroupTypeIC} to {@link RuleGroupType}.
670
+ *
671
+ * This function is idempotent: {@link RuleGroupType} queries will be
672
+ * returned as-is.
673
+ *
674
+ * @group Query Tools
675
+ */
676
+ const convertFromIC = (rg) => {
677
+ if (isRuleGroupType(rg)) return rg;
678
+ const processedRG = generateRuleGroupICWithConsistentCombinators(rg);
679
+ const rulesAsMixedList = processedRG.rules.map((r) => typeof r === "string" || !isRuleGroup(r) ? r : convertFromIC(r));
680
+ const combinator = rulesAsMixedList.length < 2 ? "and" : rulesAsMixedList[1];
681
+ const rules = rulesAsMixedList.filter((r) => typeof r !== "string");
682
+ return _objectSpread2(_objectSpread2({}, processedRG), {}, {
683
+ combinator,
684
+ rules
685
+ });
686
+ };
687
+ /**
688
+ * Converts a {@link RuleGroupType} to {@link RuleGroupTypeIC}.
689
+ *
690
+ * This function is idempotent: {@link RuleGroupTypeIC} queries will be
691
+ * returned as-is.
692
+ *
693
+ * @group Query Tools
694
+ */
695
+ const convertToIC = (rg) => {
696
+ if (isRuleGroupTypeIC(rg)) return rg;
697
+ const { combinator } = rg, queryWithoutCombinator = _objectWithoutProperties(rg, _excluded);
698
+ const rules = [];
699
+ const { length } = rg.rules;
700
+ for (const [idx, r] of rg.rules.entries()) {
701
+ if (isRuleGroup(r)) rules.push(convertToIC(r));
702
+ else rules.push(r);
703
+ if (combinator && idx < length - 1) rules.push(combinator);
704
+ }
705
+ return _objectSpread2(_objectSpread2({}, queryWithoutCombinator), {}, { rules });
706
+ };
707
+ function convertQuery(query) {
708
+ return isRuleGroupTypeIC(query) ? convertFromIC(query) : convertToIC(query);
709
+ }
710
+
711
+ //#endregion
712
+ //#region src/utils/defaultValidator.ts
713
+ /**
714
+ * This is an example validation function you can pass to {@link QueryBuilder} in the
715
+ * `validator` prop. It assumes that you want to validate groups, and has a no-op
716
+ * for validating rules which you can replace with your own implementation.
717
+ */
718
+ const defaultValidator = (query) => {
719
+ const result = {};
720
+ /**
721
+ * Replace this with your custom rule validator.
722
+ */
723
+ const validateRule = (rule) => {
724
+ // istanbul ignore else
725
+ if (rule.id) result[rule.id];
726
+ };
727
+ const validateGroup = (rg) => {
728
+ const reasons = [];
729
+ if (rg.rules.length === 0) reasons.push(groupInvalidReasons.empty);
730
+ else if (!isRuleGroupType(rg)) {
731
+ let invalidICs = false;
732
+ for (let i = 0; i < rg.rules.length && !invalidICs; i++) if (i % 2 === 0 && typeof rg.rules[i] === "string" || i % 2 === 1 && typeof rg.rules[i] !== "string" || i % 2 === 1 && typeof rg.rules[i] === "string" && !defaultCombinators.map((c) => c.name).includes(rg.rules[i])) invalidICs = true;
733
+ if (invalidICs) reasons.push(groupInvalidReasons.invalidIndependentCombinators);
734
+ }
735
+ if (isRuleGroupType(rg) && !defaultCombinators.map((c) => c.name).includes(rg.combinator) && rg.rules.length > 1) reasons.push(groupInvalidReasons.invalidCombinator);
736
+ /* istanbul ignore else */
737
+ if (rg.id) result[rg.id] = reasons.length > 0 ? {
738
+ valid: false,
739
+ reasons
740
+ } : true;
741
+ for (const r of rg.rules) if (typeof r === "string") {} else if (isRuleGroup(r)) validateGroup(r);
742
+ else validateRule(r);
743
+ };
744
+ validateGroup(query);
745
+ return result;
746
+ };
747
+
748
+ //#endregion
749
+ //#region src/utils/optGroupUtils.ts
750
+ const isOptionWithName = (opt) => isPojo(opt) && "name" in opt && typeof opt.name === "string";
751
+ const isOptionWithValue = (opt) => isPojo(opt) && "value" in opt && typeof opt.value === "string";
752
+ /**
753
+ * Converts an {@link Option} or {@link ValueOption} (i.e., {@link BaseOption})
754
+ * into a {@link FullOption}. Full options are left unchanged.
755
+ *
756
+ * @group Option Lists
757
+ */
758
+ function toFullOption(opt, baseProperties, labelMap) {
759
+ return produce((draft) => {
760
+ const idObj = {};
761
+ let needsUpdating = !!baseProperties;
762
+ if (typeof draft === "string") {
763
+ var _labelMap$draft;
764
+ return _objectSpread2(_objectSpread2({}, baseProperties), {}, {
765
+ name: draft,
766
+ value: draft,
767
+ label: (_labelMap$draft = labelMap === null || labelMap === void 0 ? void 0 : labelMap[draft]) !== null && _labelMap$draft !== void 0 ? _labelMap$draft : draft
768
+ });
769
+ }
770
+ if (isOptionWithName(draft) && !isOptionWithValue(draft)) {
771
+ idObj.value = draft.name;
772
+ needsUpdating = true;
773
+ } else if (!isOptionWithName(draft) && isOptionWithValue(draft)) {
774
+ idObj.name = draft.value;
775
+ needsUpdating = true;
776
+ }
777
+ if (needsUpdating) return Object.assign({}, baseProperties, draft, idObj);
778
+ })(opt);
779
+ }
780
+ /**
781
+ * Converts an {@link OptionList} or {@link FlexibleOptionList} into a {@link FullOptionList}.
782
+ * Lists of full options are left unchanged.
783
+ *
784
+ * @group Option Lists
785
+ */
786
+ function toFullOptionList(optList, baseProperties, labelMap) {
787
+ if (!Array.isArray(optList)) return [];
788
+ return produce((draft) => {
789
+ if (isFlexibleOptionGroupArray(draft)) for (const optGroup of draft) for (const [idx, opt] of optGroup.options.entries()) optGroup.options[idx] = toFullOption(opt, baseProperties, labelMap);
790
+ else for (const [idx, opt] of draft.entries()) draft[idx] = toFullOption(opt, baseProperties, labelMap);
791
+ })(optList);
792
+ }
793
+ /**
794
+ * Converts a {@link FlexibleOptionList} into a {@link FullOptionList}.
795
+ * Lists of full options are left unchanged.
796
+ *
797
+ * @group Option Lists
798
+ */
799
+ function toFullOptionMap(optMap, baseProperties) {
800
+ return Object.fromEntries(Object.entries(optMap).map(([k, v]) => [k, toFullOption(v, baseProperties)]));
801
+ }
802
+ /**
803
+ * @deprecated Renamed to {@link uniqByIdentifier}.
804
+ *
805
+ * @group Option Lists
806
+ */
807
+ const uniqByName = (originalArray) => uniqByIdentifier(originalArray);
808
+ /**
809
+ * Generates a new array of objects with duplicates removed based
810
+ * on the identifying property (`value` or `name`)
811
+ *
812
+ * @group Option Lists
813
+ */
814
+ const uniqByIdentifier = (originalArray) => {
815
+ const names = /* @__PURE__ */ new Set();
816
+ const newArray = [];
817
+ for (const el of originalArray) {
818
+ var _el$value;
819
+ if (!names.has((_el$value = el.value) !== null && _el$value !== void 0 ? _el$value : el.name)) {
820
+ var _el$value2;
821
+ names.add((_el$value2 = el.value) !== null && _el$value2 !== void 0 ? _el$value2 : el.name);
822
+ newArray.push(el);
823
+ }
824
+ }
825
+ return originalArray.length === newArray.length ? originalArray : newArray;
826
+ };
827
+ /**
828
+ * Determines if an {@link OptionList} is an {@link OptionGroup} array.
829
+ *
830
+ * @group Option Lists
831
+ */
832
+ const isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && Array.isArray(arr[0].options);
833
+ /**
834
+ * Determines if an array is a flat array of {@link FlexibleOption}.
835
+ *
836
+ * @group Option Lists
837
+ */
838
+ const isFlexibleOptionArray = (arr) => {
839
+ let isFOA = false;
840
+ if (Array.isArray(arr)) for (const o of arr) if (isOptionWithName(o) || isOptionWithValue(o)) isFOA = true;
841
+ else return false;
842
+ return isFOA;
843
+ };
844
+ /**
845
+ * Determines if an array is a flat array of {@link FullOption}.
846
+ *
847
+ * @group Option Lists
848
+ */
849
+ const isFullOptionArray = (arr) => {
850
+ let isFOA = false;
851
+ if (Array.isArray(arr)) for (const o of arr) if (isOptionWithName(o) && isOptionWithValue(o)) isFOA = true;
852
+ else return false;
853
+ return isFOA;
854
+ };
855
+ /**
856
+ * Determines if a {@link FlexibleOptionList} is a {@link FlexibleOptionGroup} array.
857
+ *
858
+ * @group Option Lists
859
+ */
860
+ const isFlexibleOptionGroupArray = (arr, { allowEmpty = false } = {}) => {
861
+ let isFOGA = false;
862
+ if (Array.isArray(arr)) for (const og of arr) if (isPojo(og) && "options" in og && (isFlexibleOptionArray(og.options) || allowEmpty && Array.isArray(og.options) && og.options.length === 0)) isFOGA = true;
863
+ else return false;
864
+ return isFOGA;
865
+ };
866
+ /**
867
+ * Determines if a {@link FlexibleOptionList} is a {@link OptionGroup} array of {@link FullOption}.
868
+ *
869
+ * @group Option Lists
870
+ */
871
+ const isFullOptionGroupArray = (arr, { allowEmpty = false } = {}) => {
872
+ let isFOGA = false;
873
+ if (Array.isArray(arr)) for (const og of arr) if (isPojo(og) && "options" in og && (isFullOptionArray(og.options) || allowEmpty && Array.isArray(og.options) && og.options.length === 0)) isFOGA = true;
874
+ else return false;
875
+ return isFOGA;
876
+ };
877
+ function getOption(arr, name) {
878
+ return (isFlexibleOptionGroupArray(arr, { allowEmpty: true }) ? arr.flatMap((og) => og.options) : arr).find((op) => op.value === name || op.name === name);
879
+ }
880
+ function getFirstOption(arr) {
881
+ var _arr$0$value;
882
+ if (!Array.isArray(arr) || arr.length === 0) return null;
883
+ else if (isFlexibleOptionGroupArray(arr, { allowEmpty: true })) {
884
+ for (const og of arr) if (og.options.length > 0) {
885
+ var _og$options$0$value;
886
+ return (_og$options$0$value = og.options[0].value) !== null && _og$options$0$value !== void 0 ? _og$options$0$value : og.options[0].name;
887
+ }
888
+ // istanbul ignore next
889
+ return null;
890
+ }
891
+ return (_arr$0$value = arr[0].value) !== null && _arr$0$value !== void 0 ? _arr$0$value : arr[0].name;
892
+ }
893
+ /**
894
+ * Flattens {@link FlexibleOptionGroup} arrays into {@link BaseOption} arrays.
895
+ * If the array is already flat, it is returned as is.
896
+ *
897
+ * @group Option Lists
898
+ */
899
+ const toFlatOptionArray = (arr) => uniqByIdentifier(isOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr);
900
+ /**
901
+ * Generates a new {@link OptionGroup} array with duplicates
902
+ * removed based on the identifying property (`value` or `name`).
903
+ *
904
+ * @group Option Lists
905
+ */
906
+ const uniqOptGroups = (originalArray) => {
907
+ const labels = /* @__PURE__ */ new Set();
908
+ const names = /* @__PURE__ */ new Set();
909
+ const newArray = [];
910
+ for (const el of originalArray) if (!labels.has(el.label)) {
911
+ labels.add(el.label);
912
+ const optionsForThisGroup = [];
913
+ for (const opt of el.options) {
914
+ var _opt$value;
915
+ if (!names.has((_opt$value = opt.value) !== null && _opt$value !== void 0 ? _opt$value : opt.name)) {
916
+ var _opt$value2;
917
+ names.add((_opt$value2 = opt.value) !== null && _opt$value2 !== void 0 ? _opt$value2 : opt.name);
918
+ optionsForThisGroup.push(toFullOption(opt));
919
+ }
920
+ }
921
+ newArray.push(_objectSpread2(_objectSpread2({}, el), {}, { options: optionsForThisGroup }));
922
+ }
923
+ return newArray;
924
+ };
925
+ /**
926
+ * Generates a new {@link Option} or {@link OptionGroup} array with duplicates
927
+ * removed based on the identifier property (`value` or `name`).
928
+ *
929
+ * @group Option Lists
930
+ */
931
+ const uniqOptList = (originalArray) => {
932
+ if (isFlexibleOptionGroupArray(originalArray)) return uniqOptGroups(originalArray);
933
+ return uniqByIdentifier(originalArray.map((o) => toFullOption(o)));
934
+ };
935
+
936
+ //#endregion
937
+ //#region src/utils/filterFieldsByComparator.ts
938
+ const filterByComparator = (field, operator, fieldToCompare) => {
939
+ var _fullField$comparator, _fullField$comparator2;
940
+ const fullField = toFullOption(field);
941
+ const fullFieldToCompare = toFullOption(fieldToCompare);
942
+ if (fullField.value === fullFieldToCompare.value) return false;
943
+ if (typeof fullField.comparator === "string") return fullField[fullField.comparator] === fullFieldToCompare[fullField.comparator];
944
+ return (_fullField$comparator = (_fullField$comparator2 = fullField.comparator) === null || _fullField$comparator2 === void 0 ? void 0 : _fullField$comparator2.call(fullField, fullFieldToCompare, operator)) !== null && _fullField$comparator !== void 0 ? _fullField$comparator : false;
945
+ };
946
+ /**
947
+ * For a given {@link FullField}, returns the `fields` list filtered for
948
+ * other fields that match by `comparator`. Only fields *other than the
949
+ * one in question* will ever be included, even if `comparator` is `null`
950
+ * or `undefined`. If `comparator` is a string, fields with the same value
951
+ * for that property will be included. If `comparator` is a function, each
952
+ * field will be passed to the function along with the `operator` and fields
953
+ * for which the function returns `true` will be included.
954
+ *
955
+ * @group Option Lists
956
+ */
957
+ const filterFieldsByComparator = (field, fields, operator) => {
958
+ if (!field.comparator) {
959
+ const filterOutSameField = (f) => {
960
+ var _f$value, _field$value;
961
+ return ((_f$value = f.value) !== null && _f$value !== void 0 ? _f$value : f.name) !== ((_field$value = field.value) !== null && _field$value !== void 0 ? _field$value : field.name);
962
+ };
963
+ if (isFlexibleOptionGroupArray(fields)) return fields.map((og) => _objectSpread2(_objectSpread2({}, og), {}, { options: og.options.filter((v) => filterOutSameField(v)) }));
964
+ return fields.filter((v) => filterOutSameField(v));
965
+ }
966
+ if (isFlexibleOptionGroupArray(fields)) return fields.map((og) => _objectSpread2(_objectSpread2({}, og), {}, { options: og.options.filter((f) => filterByComparator(field, operator, f)) })).filter((og) => og.options.length > 0);
967
+ return fields.filter((f) => filterByComparator(field, operator, f));
968
+ };
969
+
970
+ //#endregion
971
+ //#region src/utils/parseNumber.ts
972
+ /**
973
+ * Converts a string to a number. Uses native `parseFloat` if `parseNumbers` is "native",
974
+ * otherwise uses [`numeric-quantity`](https://jakeboone02.github.io/numeric-quantity/).
975
+ * If that returns `NaN`, the string is returned unchanged. Numeric values are returned
976
+ * as-is regardless of the `parseNumbers` option.
977
+ */
978
+ const parseNumber = (val, { parseNumbers, bigIntOnOverflow } = {}) => {
979
+ if (!parseNumbers || typeof val === "bigint" || typeof val === "number") return val;
980
+ if (parseNumbers === "native") return Number.parseFloat(val);
981
+ const valAsNum = numericQuantity(val, {
982
+ allowTrailingInvalid: parseNumbers === "enhanced",
983
+ bigIntOnOverflow,
984
+ romanNumerals: false,
985
+ round: false
986
+ });
987
+ return typeof valAsNum === "bigint" || !Number.isNaN(valAsNum) ? valAsNum : val;
988
+ };
989
+
990
+ //#endregion
991
+ //#region src/utils/transformQuery.ts
992
+ const remapProperties = (obj, propertyMap, deleteRemappedProperties) => produce(obj, (draft) => {
993
+ for (const [k, v] of Object.entries(propertyMap)) if (v === false) delete draft[k];
994
+ else if (!!v && k !== v && k in draft) {
995
+ draft[v] = draft[k];
996
+ if (deleteRemappedProperties) delete draft[k];
997
+ }
998
+ });
999
+ function transformQuery(query, options = {}) {
1000
+ const { ruleProcessor = (r) => r, ruleGroupProcessor = (rg) => rg, propertyMap = {}, combinatorMap = {}, operatorMap = {}, omitPath = false, deleteRemappedProperties = true } = options;
1001
+ const processGroup = (rg) => {
1002
+ var _combinatorMap$rg$com, _propertyMap$rules;
1003
+ return _objectSpread2(_objectSpread2({}, ruleGroupProcessor(remapProperties(_objectSpread2(_objectSpread2({}, rg), isRuleGroupType(rg) ? { combinator: (_combinatorMap$rg$com = combinatorMap[rg.combinator]) !== null && _combinatorMap$rg$com !== void 0 ? _combinatorMap$rg$com : rg.combinator } : {}), propertyMap, deleteRemappedProperties))), propertyMap["rules"] === false ? null : { [(_propertyMap$rules = propertyMap["rules"]) !== null && _propertyMap$rules !== void 0 ? _propertyMap$rules : "rules"]: rg.rules.map((r, idx) => {
1004
+ var _operatorMap$r$operat;
1005
+ const pathObject = omitPath ? null : { path: [...rg.path, idx] };
1006
+ if (typeof r === "string") {
1007
+ var _combinatorMap$r;
1008
+ return (_combinatorMap$r = combinatorMap[r]) !== null && _combinatorMap$r !== void 0 ? _combinatorMap$r : r;
1009
+ } else if (isRuleGroup(r)) return processGroup(_objectSpread2(_objectSpread2({}, r), pathObject));
1010
+ return ruleProcessor(remapProperties(_objectSpread2(_objectSpread2(_objectSpread2({}, r), pathObject), "operator" in r ? { operator: (_operatorMap$r$operat = operatorMap[r.operator]) !== null && _operatorMap$r$operat !== void 0 ? _operatorMap$r$operat : r.operator } : {}), propertyMap, deleteRemappedProperties));
1011
+ }) });
1012
+ };
1013
+ return processGroup(_objectSpread2(_objectSpread2({}, query), omitPath ? null : { path: [] }));
1014
+ }
1015
+
1016
+ //#endregion
1017
+ //#region src/utils/isRuleOrGroupValid.ts
1018
+ /**
1019
+ * Determines if an object is useful as a validation result.
1020
+ */
1021
+ const isValidationResult = (vr) => isPojo(vr) && typeof vr.valid === "boolean";
1022
+ /**
1023
+ * Determines if a rule or group is valid based on a validation result (if defined)
1024
+ * or a validator function. Returns `true` if neither are defined.
1025
+ */
1026
+ const isRuleOrGroupValid = (rg, validationResult, validator) => {
1027
+ if (typeof validationResult === "boolean") return validationResult;
1028
+ if (isValidationResult(validationResult)) return validationResult.valid;
1029
+ if (typeof validator === "function" && !isRuleGroup(rg)) {
1030
+ const vr = validator(rg);
1031
+ if (typeof vr === "boolean") return vr;
1032
+ // istanbul ignore else
1033
+ if (isValidationResult(vr)) return vr.valid;
1034
+ }
1035
+ return true;
1036
+ };
1037
+
1038
+ //#endregion
1039
+ //#region src/utils/getParseNumberMethod.ts
1040
+ const getParseNumberMethod = ({ parseNumbers, inputType }) => {
1041
+ if (typeof parseNumbers === "string") {
1042
+ const [method, level] = parseNumbers.split("-");
1043
+ if (level === "limited") return inputType === "number" ? method : false;
1044
+ return method;
1045
+ }
1046
+ return parseNumbers ? "strict" : false;
1047
+ };
1048
+
1049
+ //#endregion
1050
+ //#region src/utils/formatQuery/utils.ts
1051
+ /**
1052
+ * Maps a {@link DefaultOperatorName} to a SQL operator.
1053
+ *
1054
+ * @group Export
1055
+ */
1056
+ const mapSQLOperator = (rqbOperator) => {
1057
+ switch (lc(rqbOperator)) {
1058
+ case "null": return "is null";
1059
+ case "notnull": return "is not null";
1060
+ case "notin": return "not in";
1061
+ case "notbetween": return "not between";
1062
+ case "contains":
1063
+ case "beginswith":
1064
+ case "endswith": return "like";
1065
+ case "doesnotcontain":
1066
+ case "doesnotbeginwith":
1067
+ case "doesnotendwith": return "not like";
1068
+ default: return rqbOperator;
1069
+ }
1070
+ };
1071
+ /**
1072
+ * Maps a (lowercase) {@link DefaultOperatorName} to a MongoDB operator.
1073
+ *
1074
+ * @group Export
1075
+ */
1076
+ const mongoOperators = {
1077
+ "=": "$eq",
1078
+ "!=": "$ne",
1079
+ "<": "$lt",
1080
+ "<=": "$lte",
1081
+ ">": "$gt",
1082
+ ">=": "$gte",
1083
+ in: "$in",
1084
+ notin: "$nin",
1085
+ notIn: "$nin"
1086
+ };
1087
+ /**
1088
+ * Maps a (lowercase) {@link DefaultOperatorName} to a Prisma ORM operator.
1089
+ *
1090
+ * @group Export
1091
+ */
1092
+ const prismaOperators = {
1093
+ "=": "equals",
1094
+ "!=": "not",
1095
+ "<": "lt",
1096
+ "<=": "lte",
1097
+ ">": "gt",
1098
+ ">=": "gte",
1099
+ in: "in",
1100
+ notin: "notIn"
1101
+ };
1102
+ /**
1103
+ * Maps a {@link DefaultCombinatorName} to a CEL combinator.
1104
+ *
1105
+ * @group Export
1106
+ */
1107
+ const celCombinatorMap = {
1108
+ and: "&&",
1109
+ or: "||"
1110
+ };
1111
+ /**
1112
+ * Register these operators with `jsonLogic` before applying the result
1113
+ * of `formatQuery(query, 'jsonlogic')`.
1114
+ *
1115
+ * @example
1116
+ * ```
1117
+ * for (const [op, func] of Object.entries(jsonLogicAdditionalOperators)) {
1118
+ * jsonLogic.add_operation(op, func);
1119
+ * }
1120
+ * jsonLogic.apply({ "startsWith": [{ "var": "firstName" }, "Stev"] }, data);
1121
+ * ```
1122
+ *
1123
+ * @group Export
1124
+ */
1125
+ const jsonLogicAdditionalOperators = {
1126
+ startsWith: (a, b) => typeof a === "string" && a.startsWith(b),
1127
+ endsWith: (a, b) => typeof a === "string" && a.endsWith(b)
1128
+ };
1129
+ /**
1130
+ * Converts all `string`-type `value` properties of a query object into `number` where appropriate.
1131
+ *
1132
+ * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`.
1133
+ *
1134
+ * @group Export
1135
+ */
1136
+ const numerifyValues = (rg, options) => _objectSpread2(_objectSpread2({}, rg), {}, { rules: rg.rules.map((r) => {
1137
+ if (typeof r === "string") return r;
1138
+ if (isRuleGroup(r)) return numerifyValues(r, options);
1139
+ const fieldData = getOption(options.fields, r.field);
1140
+ const parseNumbers = getParseNumberMethod({
1141
+ parseNumbers: options.parseNumbers,
1142
+ inputType: fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType
1143
+ });
1144
+ if (Array.isArray(r.value)) return _objectSpread2(_objectSpread2({}, r), {}, { value: r.value.map((v) => parseNumber(v, { parseNumbers })) });
1145
+ const valAsArray = toArray(r.value, { retainEmptyStrings: true }).map((v) => parseNumber(v, { parseNumbers }));
1146
+ if (valAsArray.every((v) => typeof v === "number")) {
1147
+ // istanbul ignore else
1148
+ if (valAsArray.length > 1) return _objectSpread2(_objectSpread2({}, r), {}, { value: valAsArray });
1149
+ else if (valAsArray.length === 1) return _objectSpread2(_objectSpread2({}, r), {}, { value: valAsArray[0] });
1150
+ }
1151
+ return r;
1152
+ }) });
1153
+ /**
1154
+ * Determines whether a value is _anything_ except an empty `string` or `NaN`.
1155
+ *
1156
+ * @group Export
1157
+ */
1158
+ const isValidValue = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && !Number.isNaN(value) || typeof value !== "string" && typeof value !== "number";
1159
+ /**
1160
+ * Determines whether {@link formatQuery} should render the given value as a number.
1161
+ * As long as `parseNumbers` is `true`, `number` and `bigint` values will return `true` and
1162
+ * `string` values will return `true` if they test positive against {@link numericRegex}.
1163
+ *
1164
+ * @group Export
1165
+ */
1166
+ const shouldRenderAsNumber = (value, parseNumbers) => !!parseNumbers && (typeof value === "number" || typeof value === "bigint" || typeof value === "string" && numericRegex.test(value));
1167
+ /**
1168
+ * Used by {@link formatQuery} to determine whether the given value processor is a
1169
+ * "legacy" value processor by counting the number of arguments. Legacy value
1170
+ * processors take 3 arguments (not counting any arguments with default values), while
1171
+ * rule-based value processors take no more than 2 arguments.
1172
+ *
1173
+ * @group Export
1174
+ */
1175
+ const isValueProcessorLegacy = (valueProcessor) => valueProcessor.length >= 3;
1176
+ /**
1177
+ * Converts the `quoteFieldNamesWith` option into an array of two strings.
1178
+ * If the option is a string, the array elements are both that string.
1179
+ *
1180
+ * @default
1181
+ * ['', '']
1182
+ *
1183
+ * @group Export
1184
+ */
1185
+ const getQuoteFieldNamesWithArray = (quoteFieldNamesWith = ["", ""]) => Array.isArray(quoteFieldNamesWith) ? quoteFieldNamesWith : typeof quoteFieldNamesWith === "string" ? [quoteFieldNamesWith, quoteFieldNamesWith] : quoteFieldNamesWith !== null && quoteFieldNamesWith !== void 0 ? quoteFieldNamesWith : ["", ""];
1186
+ /**
1187
+ * Given a field name and relevant {@link ValueProcessorOptions}, returns the field name
1188
+ * wrapped in the configured quote character(s).
1189
+ *
1190
+ * @group Export
1191
+ */
1192
+ const getQuotedFieldName = (fieldName, { quoteFieldNamesWith, fieldIdentifierSeparator }) => {
1193
+ const [qPre, qPost] = getQuoteFieldNamesWithArray(quoteFieldNamesWith);
1194
+ return typeof fieldIdentifierSeparator === "string" && fieldIdentifierSeparator.length > 0 ? joinWith(splitBy(fieldName, fieldIdentifierSeparator).map((part) => `${qPre}${part}${qPost}`), fieldIdentifierSeparator) : `${qPre}${fieldName}${qPost}`;
1195
+ };
1196
+ const defaultWordOrder = [
1197
+ "S",
1198
+ "V",
1199
+ "O"
1200
+ ];
1201
+ /**
1202
+ * Given a [Constituent word order](https://en.wikipedia.org/wiki/Word_order#Constituent_word_orders)
1203
+ * like "svo" or "sov", returns a permutation of `["S", "V", "O"]` based on the first occurrence of
1204
+ * each letter in the input string (case insensitive). This widens the valid input from abbreviations
1205
+ * like "svo" to more expressive strings like "subject-verb-object" or "sub ver obj". Any missing
1206
+ * letters are appended in the default order "SVO" (e.g., "object" would yield `["O", "S", "V"]`).
1207
+ *
1208
+ * @group Export
1209
+ */
1210
+ const normalizeConstituentWordOrder = (input) => {
1211
+ const result = [];
1212
+ const letterSet = new Set(defaultWordOrder);
1213
+ for (const char of input.toUpperCase()) if (letterSet.has(char)) {
1214
+ result.push(char);
1215
+ letterSet.delete(char);
1216
+ if (letterSet.size === 0) break;
1217
+ }
1218
+ for (const letter of defaultWordOrder) if (letterSet.has(letter)) result.push(letter);
1219
+ return result;
1220
+ };
1221
+ /**
1222
+ * Default translations used by {@link formatQuery} for "natural_language" format.
1223
+ *
1224
+ * @group Export
1225
+ */
1226
+ const defaultNLTranslations = {
1227
+ groupPrefix: "",
1228
+ groupPrefix_not_xor: "either zero or more than one of",
1229
+ groupPrefix_xor: "exactly one of",
1230
+ groupSuffix: "is true",
1231
+ groupSuffix_not: "is not true"
1232
+ };
1233
+ /**
1234
+ * Note: This function assumes `conditions.length > 0`
1235
+ */
1236
+ const translationMatchFilter = (key, keyToTest, conditions) => keyToTest.startsWith(key) && conditions.every((c) => {
1237
+ var _keyToTest$match;
1238
+ return keyToTest.includes(`_${c}`) && ((_keyToTest$match = keyToTest.match(/_/g)) === null || _keyToTest$match === void 0 ? void 0 : _keyToTest$match.length) === conditions.length;
1239
+ });
1240
+ /**
1241
+ * Used by {@link formatQuery} to get a translation based on certain conditions
1242
+ * for the "natural_language" format.
1243
+ *
1244
+ * @group Export
1245
+ */
1246
+ const getNLTranslataion = (key, translations, conditions = []) => {
1247
+ var _ref, _translations$key, _ref2, _ref3, _Object$entries$find$, _Object$entries$find, _Object$entries$find2;
1248
+ return conditions.length === 0 ? (_ref = (_translations$key = translations[key]) !== null && _translations$key !== void 0 ? _translations$key : defaultNLTranslations[key]) !== null && _ref !== void 0 ? _ref : "" : (_ref2 = (_ref3 = (_Object$entries$find$ = (_Object$entries$find = Object.entries(translations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))) === null || _Object$entries$find === void 0 ? void 0 : _Object$entries$find[1]) !== null && _Object$entries$find$ !== void 0 ? _Object$entries$find$ : (_Object$entries$find2 = Object.entries(defaultNLTranslations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))) === null || _Object$entries$find2 === void 0 ? void 0 : _Object$entries$find2[1]) !== null && _ref3 !== void 0 ? _ref3 : defaultNLTranslations[key]) !== null && _ref2 !== void 0 ? _ref2 : "";
1249
+ };
1250
+ const processMatchMode = (rule) => {
1251
+ var _rule$match;
1252
+ const { mode, threshold } = (_rule$match = rule.match) !== null && _rule$match !== void 0 ? _rule$match : {};
1253
+ if (mode) {
1254
+ if (!isRuleGroup(rule.value)) return false;
1255
+ const matchModeLC = lc(mode);
1256
+ const matchModeCoerced = matchModeLC === "atleast" && threshold === 1 ? "some" : matchModeLC === "atmost" && threshold === 0 ? "none" : matchModeLC;
1257
+ if ((matchModeCoerced === "atleast" || matchModeCoerced === "atmost" || matchModeCoerced === "exactly") && (typeof threshold !== "number" || threshold < 0)) return false;
1258
+ return {
1259
+ mode: matchModeCoerced,
1260
+ threshold
1261
+ };
1262
+ }
1263
+ };
1264
+ /**
1265
+ * "Replacer" method for JSON.stringify's second argument. Converts `bigint` values to
1266
+ * objects with a `$bigint` property having a value of a string representation of
1267
+ * the actual `bigint`-type value.
1268
+ *
1269
+ * Inverse of {@link bigIntJsonParseReviver}.
1270
+ *
1271
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
1272
+ */
1273
+ const bigIntJsonStringifyReplacer = (_key, value) => typeof value === "bigint" ? { $bigint: value.toString() } : value;
1274
+ /**
1275
+ * "Reviver" method for JSON.parse's second argument. Converts objects having a single
1276
+ * `$bigint: string` property to an actual `bigint` value.
1277
+ *
1278
+ * Inverse of {@link bigIntJsonStringifyReplacer}.
1279
+ *
1280
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
1281
+ */
1282
+ const bigIntJsonParseReviver = (_key, value) => isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === "string" ? BigInt(value.$bigint) : value;
1283
+
1284
+ //#endregion
1285
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorCEL.ts
1286
+ /**
1287
+ * Rule group processor used by {@link formatQuery} for "cel" format.
1288
+ *
1289
+ * @group Export
1290
+ */
1291
+ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
1292
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1293
+ const processRuleGroup = (rg, outermost) => {
1294
+ var _rg$id;
1295
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermost ? fallbackExpression : "";
1296
+ const expression = rg.rules.map((rule) => {
1297
+ var _rule$valueSource;
1298
+ if (typeof rule === "string") return celCombinatorMap[rule];
1299
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1300
+ const [validationResult, fieldValidator] = validateRule(rule);
1301
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1302
+ const fieldData = getOption(fields, rule.field);
1303
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1304
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1305
+ escapeQuotes: ((_rule$valueSource = rule.valueSource) !== null && _rule$valueSource !== void 0 ? _rule$valueSource : "value") === "value",
1306
+ fieldData
1307
+ }));
1308
+ }).filter(Boolean).join(isRuleGroupType(rg) ? ` ${celCombinatorMap[rg.combinator]} ` : " ");
1309
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""];
1310
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
1311
+ };
1312
+ return processRuleGroup(ruleGroup, true);
1313
+ };
1314
+
1315
+ //#endregion
1316
+ //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts
1317
+ const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot");
1318
+ const escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
1319
+ /**
1320
+ * Default rule processor used by {@link formatQuery} for "cel" format.
1321
+ *
1322
+ * @group Export
1323
+ */
1324
+ const defaultRuleProcessorCEL = (rule, opts = {}) => {
1325
+ const { escapeQuotes, parseNumbers, preserveValueOrder } = opts;
1326
+ const { field, operator, value, valueSource } = rule;
1327
+ const valueIsField = valueSource === "field";
1328
+ const operatorTL = lc(operator === "=" ? "==" : operator);
1329
+ const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers);
1330
+ const matchEval = processMatchMode(rule);
1331
+ if (matchEval === false) return "";
1332
+ else if (matchEval) {
1333
+ const { mode, threshold } = matchEval;
1334
+ const arrayElementAlias = "elem_alias";
1335
+ const celQuery = transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: `${arrayElementAlias}${r.field ? `.${r.field}` : ""}` }) });
1336
+ const nestedArrayFilter = defaultRuleGroupProcessorCEL(celQuery, opts);
1337
+ switch (mode) {
1338
+ case "all": return `${field}.all(${arrayElementAlias}, ${nestedArrayFilter})`;
1339
+ case "none":
1340
+ case "some": return `${mode === "none" ? "!" : ""}${field}.exists(${arrayElementAlias}, ${nestedArrayFilter})`;
1341
+ case "atleast":
1342
+ case "atmost":
1343
+ case "exactly": {
1344
+ const totalCount = `double(${field}.size())`;
1345
+ const filteredCount = `${field}.filter(${arrayElementAlias}, ${nestedArrayFilter}).size()`;
1346
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "==";
1347
+ if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`;
1348
+ return `${filteredCount} ${op} ${threshold}`;
1349
+ }
1350
+ }
1351
+ }
1352
+ switch (operatorTL) {
1353
+ case "<":
1354
+ case "<=":
1355
+ case "==":
1356
+ case "!=":
1357
+ case ">":
1358
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`}`;
1359
+ case "contains":
1360
+ case "doesnotcontain": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.contains(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
1361
+ case "beginswith":
1362
+ case "doesnotbeginwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.startsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
1363
+ case "endswith":
1364
+ case "doesnotendwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.endsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
1365
+ case "null": return `${field} == null`;
1366
+ case "notnull": return `${field} != null`;
1367
+ case "in":
1368
+ case "notin": {
1369
+ const [prefix, suffix] = shouldNegate$2(operatorTL) ? ["!(", ")"] : ["", ""];
1370
+ const valueAsArray = toArray(value);
1371
+ return `${prefix}${field} in [${valueAsArray.map((val) => valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `"${escapeDoubleQuotes(val, escapeQuotes)}"`).join(", ")}]${suffix}`;
1372
+ }
1373
+ case "between":
1374
+ case "notbetween": {
1375
+ const valueAsArray = toArray(value);
1376
+ if (valueAsArray.length >= 2 && !nullOrUndefinedOrEmpty(valueAsArray[0]) && !nullOrUndefinedOrEmpty(valueAsArray[1])) {
1377
+ const [first, second] = valueAsArray;
1378
+ const shouldParseNumbers = !(parseNumbers === false);
1379
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
1380
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
1381
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes(first, escapeQuotes)}"` : firstNum;
1382
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `"${escapeDoubleQuotes(second, escapeQuotes)}"` : secondNum;
1383
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1384
+ const tempNum = secondNum;
1385
+ secondValue = firstNum;
1386
+ firstValue = tempNum;
1387
+ }
1388
+ return operatorTL === "between" ? `(${field} >= ${firstValue} && ${field} <= ${secondValue})` : `(${field} < ${firstValue} || ${field} > ${secondValue})`;
1389
+ } else return "";
1390
+ }
1391
+ }
1392
+ return "";
1393
+ };
1394
+
1395
+ //#endregion
1396
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDBQuery.ts
1397
+ /**
1398
+ * Default fallback object used by {@link formatQuery} for "mongodb_query" format.
1399
+ *
1400
+ * @group Export
1401
+ */
1402
+ const mongoDbFallback = { $and: [{ $expr: true }] };
1403
+ /**
1404
+ * Rule group processor used by {@link formatQuery} for "mongodb_query" format.
1405
+ *
1406
+ * @group Export
1407
+ */
1408
+ const defaultRuleGroupProcessorMongoDBQuery = (ruleGroup, options, meta) => {
1409
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1410
+ const processRuleGroup = (rg, outermost) => {
1411
+ var _rg$id;
1412
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermost ? mongoDbFallback : false;
1413
+ const combinator = `$${lc(rg.combinator)}`;
1414
+ let hasChildRules = false;
1415
+ const expressions = rg.rules.map((rule) => {
1416
+ if (isRuleGroup(rule)) {
1417
+ const processedRuleGroup = processRuleGroup(rule);
1418
+ if (processedRuleGroup) {
1419
+ hasChildRules = true;
1420
+ return processedRuleGroup;
1421
+ }
1422
+ return false;
1423
+ }
1424
+ const [validationResult, fieldValidator] = validateRule(rule);
1425
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false;
1426
+ const fieldData = getOption(fields, rule.field);
1427
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1428
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1429
+ fieldData
1430
+ }), meta);
1431
+ }).filter(Boolean);
1432
+ return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
1433
+ };
1434
+ return processRuleGroup(convertFromIC(ruleGroup), true);
1435
+ };
1436
+
1437
+ //#endregion
1438
+ //#region src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts
1439
+ const processNumber$1 = (value, fallback, parseNumbers = false) => shouldRenderAsNumber(value, parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: "strict" })) : fallback;
1440
+ /**
1441
+ * Default rule processor used by {@link formatQuery} for "mongodb_query" format.
1442
+ *
1443
+ * @group Export
1444
+ */
1445
+ const defaultRuleProcessorMongoDBQuery = (rule, options = {}) => {
1446
+ const { field, operator, value, valueSource } = rule;
1447
+ const { parseNumbers, preserveValueOrder, context } = options;
1448
+ const valueIsField = valueSource === "field";
1449
+ const { avoidFieldsAsKeys } = context !== null && context !== void 0 ? context : {};
1450
+ const matchEval = processMatchMode(rule);
1451
+ if (matchEval === false) return;
1452
+ else if (matchEval) {
1453
+ const { mode, threshold } = matchEval;
1454
+ const totalCount = { $size: { $ifNull: [`$${field}`, []] } };
1455
+ const subQueryNoAggCtx = defaultRuleGroupProcessorMongoDBQuery(transformQuery(value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: r.field ? `${field}.${r.field}` : field }) }), _objectSpread2(_objectSpread2({}, options), {}, {
1456
+ ruleProcessor: defaultRuleProcessorMongoDBQuery,
1457
+ context: _objectSpread2(_objectSpread2({}, options.context), {}, { avoidFieldsAsKeys: false })
1458
+ }));
1459
+ const subQueryWithAggCtx = defaultRuleGroupProcessorMongoDBQuery(transformQuery(value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: r.field ? `$item.${r.field}` : "$item" }) }), _objectSpread2(_objectSpread2({}, options), {}, {
1460
+ ruleProcessor: defaultRuleProcessorMongoDBQuery,
1461
+ context: _objectSpread2(_objectSpread2({}, options.context), {}, { avoidFieldsAsKeys: true })
1462
+ }));
1463
+ const filteredCount = { $size: { $ifNull: [{ $filter: {
1464
+ input: `$${field}`,
1465
+ as: "item",
1466
+ cond: { $and: [subQueryWithAggCtx] }
1467
+ } }, []] } };
1468
+ switch (mode) {
1469
+ case "all": return { $expr: { $eq: [filteredCount, totalCount] } };
1470
+ case "none": return { $nor: [subQueryNoAggCtx] };
1471
+ case "some": return subQueryNoAggCtx;
1472
+ case "atleast":
1473
+ case "atmost":
1474
+ case "exactly": {
1475
+ const op = mode === "atleast" ? mongoOperators[">="] : mode === "atmost" ? mongoOperators["<="] : mongoOperators["="];
1476
+ if (threshold > 0 && threshold < 1) return { $expr: { [op]: [filteredCount, { $multiply: [totalCount, threshold] }] } };
1477
+ return { $expr: { [op]: [filteredCount, threshold] } };
1478
+ }
1479
+ }
1480
+ }
1481
+ if (operator === "=" && !valueIsField) return avoidFieldsAsKeys ? { $eq: [`$${field}`, processNumber$1(value, value, parseNumbers)] } : { [field]: processNumber$1(value, value, parseNumbers) };
1482
+ const operatorLC = lc(operator);
1483
+ switch (operatorLC) {
1484
+ case "<":
1485
+ case "<=":
1486
+ case "=":
1487
+ case "!=":
1488
+ case ">":
1489
+ case ">=": {
1490
+ const mongoOperator = mongoOperators[operatorLC];
1491
+ return valueIsField ? { [mongoOperator]: [`$${field}`, `$${value}`] } : avoidFieldsAsKeys ? { $and: [{ $ne: [`$${field}`, null] }, { [mongoOperator]: [`$${field}`, processNumber$1(value, value, parseNumbers)] }] } : { [field]: { [mongoOperator]: processNumber$1(value, value, parseNumbers) } };
1492
+ }
1493
+ case "contains": return valueIsField ? { $where: `this.${field}.includes(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: {
1494
+ input: `$${field}`,
1495
+ regex: value
1496
+ } } : { [field]: { $regex: value } };
1497
+ case "beginswith": return valueIsField ? { $where: `this.${field}.startsWith(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: {
1498
+ input: `$${field}`,
1499
+ regex: `^${value}`
1500
+ } } : { [field]: { $regex: `^${value}` } };
1501
+ case "endswith": return valueIsField ? { $where: `this.${field}.endsWith(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: {
1502
+ input: `$${field}`,
1503
+ regex: `${value}$`
1504
+ } } : { [field]: { $regex: `${value}$` } };
1505
+ case "doesnotcontain": return valueIsField ? { $where: `!this.${field}.includes(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: {
1506
+ input: `$${field}`,
1507
+ regex: value
1508
+ } } } : { [field]: { $not: { $regex: value } } };
1509
+ case "doesnotbeginwith": return valueIsField ? { $where: `!this.${field}.startsWith(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: {
1510
+ input: `$${field}`,
1511
+ regex: `^${value}`
1512
+ } } } : { [field]: { $not: { $regex: `^${value}` } } };
1513
+ case "doesnotendwith": return valueIsField ? { $where: `!this.${field}.endsWith(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: {
1514
+ input: `$${field}`,
1515
+ regex: `${value}$`
1516
+ } } } : { [field]: { $not: { $regex: `${value}$` } } };
1517
+ case "null": return avoidFieldsAsKeys ? { $eq: [`$${field}`, null] } : { [field]: null };
1518
+ case "notnull": return avoidFieldsAsKeys ? { $ne: [`$${field}`, null] } : { [field]: { $ne: null } };
1519
+ case "in":
1520
+ case "notin": {
1521
+ const valueAsArray = toArray(value);
1522
+ return valueIsField ? { $where: `${operatorLC === "notin" ? "!" : ""}[${valueAsArray.map((val) => `this.${val}`).join(",")}].includes(this.${field})` } : avoidFieldsAsKeys ? operatorLC === "notin" ? { $not: { [mongoOperators.in]: [`$${field}`, valueAsArray.map((val) => processNumber$1(val, val, parseNumbers))] } } : { [mongoOperators[operatorLC]]: [`$${field}`, valueAsArray.map((val) => processNumber$1(val, val, parseNumbers))] } : { [field]: { [mongoOperators[operatorLC]]: valueAsArray.map((val) => processNumber$1(val, val, parseNumbers)) } };
1523
+ }
1524
+ case "between":
1525
+ case "notbetween": {
1526
+ const valueAsArray = toArray(value);
1527
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
1528
+ const [first, second] = valueAsArray;
1529
+ const firstNum = processNumber$1(first, NaN, true);
1530
+ const secondNum = processNumber$1(second, NaN, true);
1531
+ let firstValue = valueIsField ? first : Number.isNaN(firstNum) ? first : firstNum;
1532
+ let secondValue = valueIsField ? second : Number.isNaN(secondNum) ? second : secondNum;
1533
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1534
+ const tempNum = secondNum;
1535
+ secondValue = firstNum;
1536
+ firstValue = tempNum;
1537
+ }
1538
+ if (operatorLC === "between") return valueIsField ? {
1539
+ $gte: [`$${field}`, `$${firstValue}`],
1540
+ $lte: [`$${field}`, `$${secondValue}`]
1541
+ } : avoidFieldsAsKeys ? { $and: [{ $gte: [`$${field}`, firstValue] }, { $lte: [`$${field}`, secondValue] }] } : { [field]: {
1542
+ $gte: firstValue,
1543
+ $lte: secondValue
1544
+ } };
1545
+ else return valueIsField ? { $or: [{ $lt: [`$${field}`, `$${firstValue}`] }, { $gt: [`$${field}`, `$${secondValue}`] }] } : avoidFieldsAsKeys ? { $or: [{ $lt: [`$${field}`, firstValue] }, { $gt: [`$${field}`, secondValue] }] } : { $or: [{ [field]: { $lt: firstValue } }, { [field]: { $gt: secondValue } }] };
1546
+ } else return "";
1547
+ }
1548
+ }
1549
+ return "";
1550
+ };
1551
+
1552
+ //#endregion
1553
+ //#region src/utils/formatQuery/defaultRuleProcessorMongoDB.ts
1554
+ /**
1555
+ * Default rule processor used by {@link formatQuery} for "mongodb" format.
1556
+ *
1557
+ * Note that the "mongodb" format is deprecated in favor of the "mongodb_query" format.
1558
+ *
1559
+ * @group Export
1560
+ */
1561
+ const defaultRuleProcessorMongoDB = (rule, options) => {
1562
+ const queryObj = defaultRuleProcessorMongoDBQuery(rule, options);
1563
+ return queryObj ? JSON.stringify(queryObj) : "";
1564
+ };
1565
+
1566
+ //#endregion
1567
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSpEL.ts
1568
+ /**
1569
+ * Default rule processor used by {@link formatQuery} for "spel" format.
1570
+ *
1571
+ * @group Export
1572
+ */
1573
+ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
1574
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1575
+ const processRuleGroup = (rg, outermost) => {
1576
+ var _rg$id;
1577
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermost ? fallbackExpression : "";
1578
+ const expression = rg.rules.map((rule) => {
1579
+ var _rule$valueSource;
1580
+ if (typeof rule === "string") return rule;
1581
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1582
+ const [validationResult, fieldValidator] = validateRule(rule);
1583
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1584
+ const fieldData = getOption(fields, rule.field);
1585
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1586
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1587
+ escapeQuotes: ((_rule$valueSource = rule.valueSource) !== null && _rule$valueSource !== void 0 ? _rule$valueSource : "value") === "value",
1588
+ fieldData
1589
+ }));
1590
+ }).filter(Boolean).join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ");
1591
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""];
1592
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
1593
+ };
1594
+ return processRuleGroup(ruleGroup, true);
1595
+ };
1596
+
1597
+ //#endregion
1598
+ //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts
1599
+ const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot");
1600
+ const wrapInNegation = (clause, negate$1) => negate$1 ? `!(${clause})` : clause;
1601
+ const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
1602
+ /**
1603
+ * Default rule processor used by {@link formatQuery} for "spel" format.
1604
+ *
1605
+ * @group Export
1606
+ */
1607
+ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1608
+ const { field, operator, value, valueSource } = rule;
1609
+ const { escapeQuotes, parseNumbers, preserveValueOrder } = opts;
1610
+ const valueIsField = valueSource === "field";
1611
+ const operatorTL = lc(operator === "=" ? "==" : operator);
1612
+ const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers);
1613
+ const matchEval = processMatchMode(rule);
1614
+ if (matchEval === false) return "";
1615
+ else if (matchEval) {
1616
+ const { mode, threshold } = matchEval;
1617
+ const nestedArrayFilter = defaultRuleGroupProcessorSpEL(transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: r.field || "#this" }) }), opts);
1618
+ const totalCount = `${field}.size()`;
1619
+ const filteredCount = `${field}.?[${nestedArrayFilter}].size()`;
1620
+ switch (mode) {
1621
+ case "all": return `${filteredCount} == ${totalCount}`;
1622
+ case "none": return `${filteredCount} == 0`;
1623
+ case "some": return `${filteredCount} >= 1`;
1624
+ case "atleast":
1625
+ case "atmost":
1626
+ case "exactly": {
1627
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "==";
1628
+ if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`;
1629
+ return `${filteredCount} ${op} ${threshold}`;
1630
+ }
1631
+ }
1632
+ }
1633
+ switch (operatorTL) {
1634
+ case "<":
1635
+ case "<=":
1636
+ case "==":
1637
+ case "!=":
1638
+ case ">":
1639
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`;
1640
+ case "contains":
1641
+ case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
1642
+ case "beginswith":
1643
+ case "doesnotbeginwith": {
1644
+ const valueTL = valueIsField ? `'^'.concat(${trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes(value, escapeQuotes)}'`;
1645
+ return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate$1(operatorTL));
1646
+ }
1647
+ case "endswith":
1648
+ case "doesnotendwith": {
1649
+ const valueTL = valueIsField ? `${trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`;
1650
+ return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate$1(operatorTL));
1651
+ }
1652
+ case "null": return `${field} == null`;
1653
+ case "notnull": return `${field} != null`;
1654
+ case "in":
1655
+ case "notin": {
1656
+ const negate$1 = shouldNegate$1(operatorTL) ? "!" : "";
1657
+ const valueAsArray = toArray(value);
1658
+ return valueAsArray.length > 0 ? `${negate$1}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
1659
+ }
1660
+ case "between":
1661
+ case "notbetween": {
1662
+ const valueAsArray = toArray(value);
1663
+ if (valueAsArray.length >= 2 && !nullOrUndefinedOrEmpty(valueAsArray[0]) && !nullOrUndefinedOrEmpty(valueAsArray[1])) {
1664
+ const [first, second] = valueAsArray;
1665
+ const shouldParseNumbers = !(parseNumbers === false);
1666
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
1667
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
1668
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes(first, escapeQuotes)}'` : firstNum;
1669
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `'${escapeSingleQuotes(second, escapeQuotes)}'` : secondNum;
1670
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1671
+ const tempNum = secondNum;
1672
+ secondValue = firstNum;
1673
+ firstValue = tempNum;
1674
+ }
1675
+ return operatorTL === "between" ? `(${field} >= ${firstValue} and ${field} <= ${secondValue})` : `(${field} < ${firstValue} or ${field} > ${secondValue})`;
1676
+ } else return "";
1677
+ }
1678
+ }
1679
+ return "";
1680
+ };
1681
+
1682
+ //#endregion
1683
+ //#region src/utils/formatQuery/defaultValueProcessorByRule.ts
1684
+ const escapeStringValueQuotes$1 = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
1685
+ /**
1686
+ * Default value processor used by {@link formatQuery} for "sql" format.
1687
+ *
1688
+ * @group Export
1689
+ */
1690
+ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQuotes, parseNumbers, preserveValueOrder, quoteFieldNamesWith, quoteValuesWith, concatOperator = "||", fieldIdentifierSeparator, wrapValueWith = ["", ""], translations } = {}) => {
1691
+ const valueIsField = valueSource === "field";
1692
+ const operatorLowerCase = lc(operator);
1693
+ const quoteChar = quoteValuesWith || "'";
1694
+ const quoteValue = (v) => `${wrapValueWith[0]}${quoteChar}${v}${quoteChar}${wrapValueWith[1]}`;
1695
+ const escapeValue = (v) => escapeStringValueQuotes$1(v, quoteChar, escapeQuotes);
1696
+ const wrapAndEscape = (v) => quoteValue(escapeValue(v));
1697
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
1698
+ quoteFieldNamesWith,
1699
+ fieldIdentifierSeparator
1700
+ });
1701
+ const concat = (...values) => concatOperator.toUpperCase() === "CONCAT" ? `CONCAT(${values.join(", ")})` : values.join(` ${concatOperator} `);
1702
+ switch (operatorLowerCase) {
1703
+ case "null":
1704
+ case "notnull": return "";
1705
+ case "in":
1706
+ case "notin": {
1707
+ const valueAsArray = toArray(value);
1708
+ if (valueAsArray.length > 0) return `(${valueAsArray.map((v) => valueIsField ? wrapFieldName(v) : shouldRenderAsNumber(v, parseNumbers) ? `${trimIfString(v)}` : `${wrapAndEscape(v)}`).join(", ")})`;
1709
+ return "";
1710
+ }
1711
+ case "between":
1712
+ case "notbetween": {
1713
+ var _translations$and;
1714
+ const valueAsArray = toArray(value, { retainEmptyStrings: true });
1715
+ if (valueAsArray.length < 2 || !isValidValue(valueAsArray[0]) || !isValidValue(valueAsArray[1])) return "";
1716
+ const [first, second] = valueAsArray;
1717
+ const firstNum = shouldRenderAsNumber(first, parseNumbers) ? parseNumber(first, { parseNumbers: "strict" }) : NaN;
1718
+ const secondNum = shouldRenderAsNumber(second, parseNumbers) ? parseNumber(second, { parseNumbers: "strict" }) : NaN;
1719
+ const firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : first : firstNum;
1720
+ const secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : second : secondNum;
1721
+ const valsOneAndTwoOnly = [firstValue, secondValue];
1722
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1723
+ valsOneAndTwoOnly[0] = secondNum;
1724
+ valsOneAndTwoOnly[1] = firstNum;
1725
+ }
1726
+ return (valueIsField ? valsOneAndTwoOnly.map((v) => wrapFieldName(v)) : valsOneAndTwoOnly.every((v) => shouldRenderAsNumber(v, parseNumbers)) ? valsOneAndTwoOnly.map((v) => parseNumber(v, { parseNumbers: "strict" })) : valsOneAndTwoOnly.map((v) => wrapAndEscape(v))).join(` ${(_translations$and = translations === null || translations === void 0 ? void 0 : translations.and) !== null && _translations$and !== void 0 ? _translations$and : "and"} `);
1727
+ }
1728
+ case "contains":
1729
+ case "doesnotcontain": return valueIsField ? concat(quoteValue("%"), wrapFieldName(value), quoteValue("%")) : quoteValue(`%${escapeValue(value)}%`);
1730
+ case "beginswith":
1731
+ case "doesnotbeginwith": return valueIsField ? concat(wrapFieldName(value), quoteValue("%")) : quoteValue(`${escapeValue(value)}%`);
1732
+ case "endswith":
1733
+ case "doesnotendwith": return valueIsField ? concat(quoteValue("%"), wrapFieldName(value)) : quoteValue(`%${escapeValue(value)}`);
1734
+ }
1735
+ if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
1736
+ return valueIsField ? wrapFieldName(value) : shouldRenderAsNumber(value, parseNumbers) ? `${trimIfString(value)}` : `${wrapAndEscape(value)}`;
1737
+ };
1738
+
1739
+ //#endregion
1740
+ //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
1741
+ /**
1742
+ * Default rule processor used by {@link formatQuery} for the "drizzle" format.
1743
+ *
1744
+ * @group Export
1745
+ */
1746
+ const defaultRuleProcessorDrizzle = (rule, _options) => {
1747
+ const opts = _options !== null && _options !== void 0 ? _options : ( /* istanbul ignore next */ {});
1748
+ // istanbul ignore next
1749
+ const { parseNumbers, preserveValueOrder, context = {} } = opts;
1750
+ const { columns, drizzleOperators, useRawFields } = context;
1751
+ if (!columns || !drizzleOperators) return;
1752
+ const { between, eq, gt, gte, inArray, isNotNull, isNull, like, lt, lte, ne, notBetween, notInArray, notLike, sql } = drizzleOperators;
1753
+ const { field, operator, value, valueSource } = rule;
1754
+ const column = useRawFields && /[a-z][a-z0-9]*/i.test(field) ? sql.raw(field) : columns[field];
1755
+ const operatorLC = lc(operator);
1756
+ const valueIsField = valueSource === "field";
1757
+ const asFieldOrValue = (v) => valueIsField ? columns[v] : v;
1758
+ if (!column) return;
1759
+ const matchEval = processMatchMode(rule);
1760
+ if (matchEval === false) return;
1761
+ else if (matchEval) {
1762
+ if (opts.preset !== "postgresql") return;
1763
+ const { mode, threshold } = matchEval;
1764
+ const arrayElementAlias = "elem_alias";
1765
+ const sqlQuery = transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: arrayElementAlias }) });
1766
+ const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(sqlQuery, _objectSpread2(_objectSpread2({}, opts), {}, { context: _objectSpread2(_objectSpread2({}, opts.context), {}, { useRawFields: true }) }));
1767
+ switch (mode) {
1768
+ case "all": return sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) = array_length(${column}, 1)`;
1769
+ case "none": return sql`not exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
1770
+ case "some": return sql`exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
1771
+ case "atleast":
1772
+ case "atmost":
1773
+ case "exactly": {
1774
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
1775
+ return threshold > 0 && threshold < 1 ? sql`(select count(*) / array_length(${column}, 1) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}` : sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}`;
1776
+ }
1777
+ }
1778
+ }
1779
+ switch (operatorLC) {
1780
+ case "=": return eq(column, asFieldOrValue(value));
1781
+ case "!=": return ne(column, asFieldOrValue(value));
1782
+ case ">": return gt(column, asFieldOrValue(value));
1783
+ case "<": return lt(column, asFieldOrValue(value));
1784
+ case ">=": return gte(column, asFieldOrValue(value));
1785
+ case "<=": return lte(column, asFieldOrValue(value));
1786
+ case "beginswith":
1787
+ case "doesnotbeginwith": return (operatorLC === "doesnotbeginwith" ? notLike : like)(column, valueIsField ? sql`${asFieldOrValue(value)} || '%'` : `${value}%`);
1788
+ case "contains":
1789
+ case "doesnotcontain": return (operatorLC === "doesnotcontain" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)} || '%'` : `%${value}%`);
1790
+ case "endswith":
1791
+ case "doesnotendwith": return (operatorLC === "doesnotendwith" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)}` : `%${value}`);
1792
+ case "null": return isNull(column);
1793
+ case "notnull": return isNotNull(column);
1794
+ case "in":
1795
+ case "notin": {
1796
+ const valueAsArray = toArray(value).map((v) => asFieldOrValue(v));
1797
+ return operatorLC === "notin" ? notInArray(column, valueAsArray) : inArray(column, valueAsArray);
1798
+ }
1799
+ case "between":
1800
+ case "notbetween": {
1801
+ const valueAsArray = toArray(value);
1802
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
1803
+ let [first, second] = valueAsArray;
1804
+ const shouldParseNumbers = !(parseNumbers === false);
1805
+ if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
1806
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
1807
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
1808
+ if (!preserveValueOrder && secondNum < firstNum) {
1809
+ const tempNum = secondNum;
1810
+ second = firstNum;
1811
+ first = tempNum;
1812
+ } else {
1813
+ first = firstNum;
1814
+ second = secondNum;
1815
+ }
1816
+ } else if (valueIsField) {
1817
+ first = asFieldOrValue(first);
1818
+ second = asFieldOrValue(second);
1819
+ }
1820
+ return operatorLC === "notbetween" ? notBetween(column, first, second) : between(column, first, second);
1821
+ }
1822
+ return;
1823
+ }
1824
+ default: return;
1825
+ }
1826
+ };
1827
+
1828
+ //#endregion
1829
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts
1830
+ /**
1831
+ * Default rule group processor used by {@link formatQuery} for the "drizzle" format. The returned
1832
+ * function can be assigned to the `where` property in the Drizzle relational queries API.
1833
+ *
1834
+ * @example
1835
+ * const where = formatQuery(query, 'drizzle');
1836
+ * const results = db.query.users.findMany({ where });
1837
+ *
1838
+ * @returns Function that takes a Drizzle table config and an object of Drizzle operators.
1839
+ *
1840
+ * @group Export
1841
+ */
1842
+ const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns, drizzleOperators) => {
1843
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap } = options;
1844
+ if (!columns || !drizzleOperators) return;
1845
+ const { and, not, or } = drizzleOperators;
1846
+ const query = isRuleGroupType(ruleGroup) ? ruleGroup : convertFromIC(ruleGroup);
1847
+ const ruleProcessor = defaultRuleProcessorDrizzle;
1848
+ const processRuleGroup = (rg, _outermost) => {
1849
+ var _rg$id;
1850
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return;
1851
+ const processedRules = rg.rules.map((rule) => {
1852
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1853
+ const [validationResult, fieldValidator] = validateRule(rule);
1854
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
1855
+ const fieldData = getOption(fields, rule.field);
1856
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1857
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1858
+ fieldData,
1859
+ context: _objectSpread2(_objectSpread2({}, options.context), {}, {
1860
+ columns,
1861
+ drizzleOperators
1862
+ })
1863
+ }));
1864
+ }).filter(Boolean);
1865
+ if (processedRules.length === 0) return;
1866
+ const ruleGroupSQL = rg.combinator === "or" ? or(...processedRules) : and(...processedRules);
1867
+ return rg.not ? not(ruleGroupSQL) : ruleGroupSQL;
1868
+ };
1869
+ return processRuleGroup(query, true);
1870
+ };
1871
+
1872
+ //#endregion
1873
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorElasticSearch.ts
1874
+ /**
1875
+ * Rule group processor used by {@link formatQuery} for "elasticsearch" format.
1876
+ *
1877
+ * @group Export
1878
+ */
1879
+ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
1880
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1881
+ const query = convertFromIC(ruleGroup);
1882
+ const processRuleGroup = (rg) => {
1883
+ var _rg$id;
1884
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return false;
1885
+ const processedRules = rg.rules.map((rule) => {
1886
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1887
+ const [validationResult, fieldValidator] = validateRule(rule);
1888
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false;
1889
+ const fieldData = getOption(fields, rule.field);
1890
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1891
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1892
+ fieldData
1893
+ }));
1894
+ }).filter(Boolean);
1895
+ if (processedRules.length === 0) return false;
1896
+ return { bool: rg.not ? { must_not: /^or$/i.test(rg.combinator) ? { bool: { should: processedRules } } : processedRules } : { [/^or$/i.test(rg.combinator) ? "should" : "must"]: processedRules } };
1897
+ };
1898
+ const processedRuleGroup = processRuleGroup(query);
1899
+ return processedRuleGroup === false ? {} : processedRuleGroup;
1900
+ };
1901
+
1902
+ //#endregion
1903
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts
1904
+ /**
1905
+ * Rule group processor used by {@link formatQuery} for "jsonata" format.
1906
+ *
1907
+ * @group Export
1908
+ */
1909
+ const defaultRuleGroupProcessorJSONata = (ruleGroup, options) => {
1910
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1911
+ const processRuleGroup = (rg, outermost) => {
1912
+ var _rg$id;
1913
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermost ? fallbackExpression : "";
1914
+ const expression = rg.rules.map((rule) => {
1915
+ var _rule$valueSource;
1916
+ if (typeof rule === "string") return rule;
1917
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1918
+ const [validationResult, fieldValidator] = validateRule(rule);
1919
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1920
+ const fieldData = getOption(fields, rule.field);
1921
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1922
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1923
+ escapeQuotes: ((_rule$valueSource = rule.valueSource) !== null && _rule$valueSource !== void 0 ? _rule$valueSource : "value") === "value",
1924
+ fieldData
1925
+ }));
1926
+ }).filter(Boolean).join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ");
1927
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "$not" : ""}(`, ")"] : ["", ""];
1928
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
1929
+ };
1930
+ return processRuleGroup(ruleGroup, true);
1931
+ };
1932
+
1933
+ //#endregion
1934
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorJsonLogic.ts
1935
+ /**
1936
+ * Rule group processor used by {@link formatQuery} for "jsonlogic" format.
1937
+ *
1938
+ * @group Export
1939
+ */
1940
+ const defaultRuleGroupProcessorJsonLogic = (ruleGroup, options) => {
1941
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1942
+ const query = convertFromIC(ruleGroup);
1943
+ const processRuleGroup = (rg, _outermost) => {
1944
+ var _rg$id;
1945
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return false;
1946
+ const processedRules = rg.rules.map((rule) => {
1947
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1948
+ const [validationResult, fieldValidator] = validateRule(rule);
1949
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false;
1950
+ const fieldData = getOption(fields, rule.field);
1951
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1952
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1953
+ fieldData
1954
+ }));
1955
+ }).filter(Boolean);
1956
+ if (processedRules.length === 0) return false;
1957
+ const jsonRuleGroup = { [rg.combinator]: processedRules };
1958
+ return rg.not ? { "!": jsonRuleGroup } : jsonRuleGroup;
1959
+ };
1960
+ return processRuleGroup(query, true);
1961
+ };
1962
+
1963
+ //#endregion
1964
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorLDAP.ts
1965
+ /**
1966
+ * Rule group processor used by {@link formatQuery} for "ldap" format.
1967
+ *
1968
+ * @group Export
1969
+ */
1970
+ const defaultRuleGroupProcessorLDAP = (ruleGroup, options) => {
1971
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1972
+ const query = convertFromIC(ruleGroup);
1973
+ const processRuleGroup = (rg, outermost) => {
1974
+ var _rg$id;
1975
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermost ? fallbackExpression : "";
1976
+ const rules = rg.rules.map((rule) => {
1977
+ var _rule$valueSource;
1978
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1979
+ const [validationResult, fieldValidator] = validateRule(rule);
1980
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1981
+ const fieldData = getOption(fields, rule.field);
1982
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
1983
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
1984
+ escapeQuotes: ((_rule$valueSource = rule.valueSource) !== null && _rule$valueSource !== void 0 ? _rule$valueSource : "value") === "value",
1985
+ fieldData
1986
+ }));
1987
+ }).filter(Boolean);
1988
+ const expression = rules.join("");
1989
+ const [notPrefix, notSuffix] = rg.not ? ["(!", ")"] : ["", ""];
1990
+ const [prefix, suffix] = rules.length > 1 ? [`${notPrefix}(${rg.combinator === "or" ? "|" : "&"}`, `)${notSuffix}`] : [notPrefix, notSuffix];
1991
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
1992
+ };
1993
+ return processRuleGroup(query, true);
1994
+ };
1995
+
1996
+ //#endregion
1997
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDB.ts
1998
+ const isBracketed = (str) => str.startsWith("{") && str.endsWith("}");
1999
+ /**
2000
+ * Rule group processor used by {@link formatQuery} for "mongodb" format.
2001
+ *
2002
+ * Note that the "mongodb" format is deprecated in favor of the "mongodb_query" format.
2003
+ *
2004
+ * @group Export
2005
+ */
2006
+ const defaultRuleGroupProcessorMongoDB = (ruleGroup, options, meta) => {
2007
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2008
+ const processRuleGroup = (rg, outermost) => {
2009
+ var _rg$id;
2010
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermost ? fallbackExpression : "";
2011
+ const combinator = `"$${lc(rg.combinator)}"`;
2012
+ let hasChildRules = false;
2013
+ const expressions = rg.rules.map((rule) => {
2014
+ if (isRuleGroup(rule)) {
2015
+ const processedRuleGroup = processRuleGroup(rule);
2016
+ if (processedRuleGroup) {
2017
+ hasChildRules = true;
2018
+ return isBracketed(processedRuleGroup) ? processedRuleGroup : `{${processedRuleGroup}}`;
2019
+ }
2020
+ return "";
2021
+ }
2022
+ const [validationResult, fieldValidator] = validateRule(rule);
2023
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
2024
+ const fieldData = getOption(fields, rule.field);
2025
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
2026
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
2027
+ fieldData
2028
+ }), meta);
2029
+ }).filter(Boolean);
2030
+ return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
2031
+ };
2032
+ const processedQuery = processRuleGroup(convertFromIC(ruleGroup), true);
2033
+ return isBracketed(processedQuery) ? processedQuery : `{${processedQuery}}`;
2034
+ };
2035
+
2036
+ //#endregion
2037
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorNL.ts
2038
+ /**
2039
+ * Rule group processor used by {@link formatQuery} for "natural_language" format.
2040
+ *
2041
+ * @group Export
2042
+ */
2043
+ const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
2044
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, translations, validateRule, validationMap } = options;
2045
+ const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
2046
+ var _rg$id, _rg2$combinator2, _translations2;
2047
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
2048
+ const rg2 = isRuleGroupTypeIC(rg) && rg.rules.some((r) => typeof r === "string" && lc(r) === "xor") ? convertFromIC(rg) : rg;
2049
+ const processedRules = rg2.rules.map((rule) => {
2050
+ var _rule$valueSource;
2051
+ if (typeof rule === "string") {
2052
+ var _translations;
2053
+ return `, ${(_translations = translations[rule]) !== null && _translations !== void 0 ? _translations : rule} `;
2054
+ }
2055
+ if (isRuleGroup(rule)) {
2056
+ var _rg2$combinator;
2057
+ return processRuleGroup(rule, rg2.rules.length === 1 && !(rg2.not || /^xor$/i.test((_rg2$combinator = rg2.combinator) !== null && _rg2$combinator !== void 0 ? _rg2$combinator : "")));
2058
+ }
2059
+ const [validationResult, fieldValidator] = validateRule(rule);
2060
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
2061
+ const escapeQuotes = ((_rule$valueSource = rule.valueSource) !== null && _rule$valueSource !== void 0 ? _rule$valueSource : "value") === "value";
2062
+ const fieldData = getOption(fields, rule.field);
2063
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
2064
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
2065
+ escapeQuotes,
2066
+ fieldData
2067
+ }));
2068
+ });
2069
+ if (processedRules.length === 0) return fallbackExpression;
2070
+ const isXOR = lc((_rg2$combinator2 = rg2.combinator) !== null && _rg2$combinator2 !== void 0 ? _rg2$combinator2 : "") === "xor";
2071
+ const combinator = isXOR ? rg2.combinator.slice(1) : rg2.combinator;
2072
+ const mustWrap = rg2.not || !outermostOrLonelyInGroup || isXOR && processedRules.length > 1;
2073
+ const [prefixTL, suffixTL] = ["groupPrefix", "groupSuffix"].map((key) => rg2.not ? isXOR ? getNLTranslataion(key, translations, ["not", "xor"]) : getNLTranslataion(key, translations, ["not"]) : isXOR ? getNLTranslataion(key, translations, ["xor"]) : getNLTranslataion(key, translations));
2074
+ const prefix = mustWrap ? `${prefixTL} (`.trim() : "";
2075
+ const suffix = mustWrap ? `) ${suffixTL}`.trim() : "";
2076
+ return `${prefix}${processedRules.filter(Boolean).join(isRuleGroupType(rg2) ? `, ${(_translations2 = translations[combinator]) !== null && _translations2 !== void 0 ? _translations2 : combinator} ` : "")}${suffix}`;
2077
+ };
2078
+ return processRuleGroup(ruleGroup, true);
2079
+ };
2080
+
2081
+ //#endregion
2082
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorParameterized.ts
2083
+ /**
2084
+ * Rule group processor used by {@link formatQuery} for "parameterized" and
2085
+ * "parameterized_named" formats.
2086
+ *
2087
+ * @group Export
2088
+ */
2089
+ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
2090
+ const { format, fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2091
+ const parameterized = format === "parameterized";
2092
+ const params = [];
2093
+ const paramsNamed = {};
2094
+ const fieldParams = /* @__PURE__ */ new Map();
2095
+ const getNextNamedParam = (field) => {
2096
+ if (!fieldParams.has(field)) fieldParams.set(field, /* @__PURE__ */ new Set());
2097
+ const nextNamedParam = `${field}_${fieldParams.get(field).size + 1}`;
2098
+ fieldParams.get(field).add(nextNamedParam);
2099
+ return nextNamedParam;
2100
+ };
2101
+ const processRule = (rule) => {
2102
+ const [validationResult, fieldValidator] = validateRule(rule);
2103
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
2104
+ const fieldData = getOption(fields, rule.field);
2105
+ const fieldParamNames = Object.fromEntries([...fieldParams.entries()].map(([f, s]) => [f, [...s]]));
2106
+ const processedRule = ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
2107
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
2108
+ getNextNamedParam,
2109
+ fieldParamNames,
2110
+ fieldData
2111
+ }), { processedParams: params });
2112
+ if (!isPojo(processedRule)) return "";
2113
+ const { sql, params: customParams } = processedRule;
2114
+ if (typeof sql !== "string" || !sql) return "";
2115
+ // istanbul ignore else
2116
+ if (format === "parameterized" && Array.isArray(customParams)) params.push(...customParams);
2117
+ else if (format === "parameterized_named" && isPojo(customParams)) {
2118
+ var _fieldParams$get;
2119
+ Object.assign(paramsNamed, customParams);
2120
+ for (const p of Object.keys(customParams)) (_fieldParams$get = fieldParams.get(rule.field)) === null || _fieldParams$get === void 0 || _fieldParams$get.add(p);
2121
+ }
2122
+ return sql;
2123
+ };
2124
+ const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
2125
+ var _rg$id;
2126
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
2127
+ const processedRules = rg.rules.map((rule) => {
2128
+ if (typeof rule === "string") return rule;
2129
+ if (isRuleGroup(rule)) return processRuleGroup(rule, rg.rules.length === 1);
2130
+ return processRule(rule);
2131
+ }).filter(Boolean);
2132
+ if (processedRules.length === 0) return fallbackExpression;
2133
+ return `${rg.not ? "NOT " : ""}(${processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ")})`;
2134
+ };
2135
+ if (parameterized) return {
2136
+ sql: processRuleGroup(ruleGroup, true),
2137
+ params
2138
+ };
2139
+ return {
2140
+ sql: processRuleGroup(ruleGroup, true),
2141
+ params: paramsNamed
2142
+ };
2143
+ };
2144
+
2145
+ //#endregion
2146
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorPrisma.ts
2147
+ /**
2148
+ * Default fallback object used by {@link formatQuery} for "prisma" format.
2149
+ *
2150
+ * @group Export
2151
+ */
2152
+ const prismaFallback = {};
2153
+ /**
2154
+ * Rule group processor used by {@link formatQuery} for "prisma" format.
2155
+ *
2156
+ * @group Export
2157
+ */
2158
+ const defaultRuleGroupProcessorPrisma = (ruleGroup, options) => {
2159
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2160
+ const processRuleGroup = (rg, outermost) => {
2161
+ var _rg$id;
2162
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermost ? prismaFallback : void 0;
2163
+ const combinator = rg.combinator.toUpperCase();
2164
+ let hasChildRules = false;
2165
+ const expressions = rg.rules.map((rule) => {
2166
+ if (isRuleGroup(rule)) {
2167
+ const processedRuleGroup = processRuleGroup(rule);
2168
+ if (processedRuleGroup) {
2169
+ hasChildRules = true;
2170
+ return processedRuleGroup;
2171
+ }
2172
+ return;
2173
+ }
2174
+ const [validationResult, fieldValidator] = validateRule(rule);
2175
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
2176
+ const fieldData = getOption(fields, rule.field);
2177
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
2178
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
2179
+ fieldData
2180
+ }));
2181
+ }).filter(Boolean);
2182
+ return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : prismaFallback;
2183
+ };
2184
+ const result = processRuleGroup(convertFromIC(ruleGroup), true);
2185
+ return ruleGroup.not ? { NOT: result } : result;
2186
+ };
2187
+
2188
+ //#endregion
2189
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSequelize.ts
2190
+ /**
2191
+ * Rule group processor used by {@link formatQuery} for "sequelize" format.
2192
+ *
2193
+ * @group Export
2194
+ */
2195
+ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
2196
+ // istanbul ignore next
2197
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap, context = {} } = options;
2198
+ const { sequelizeOperators: Op } = context;
2199
+ if (!Op) return;
2200
+ const processRuleGroup = (rg, _outermost) => {
2201
+ var _rg$id;
2202
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return;
2203
+ const combinator = rg.combinator.toUpperCase();
2204
+ let hasChildRules = false;
2205
+ const expressions = rg.rules.map((rule) => {
2206
+ if (isRuleGroup(rule)) {
2207
+ const processedRuleGroup = processRuleGroup(rule);
2208
+ if (processedRuleGroup) {
2209
+ hasChildRules = true;
2210
+ return processedRuleGroup;
2211
+ }
2212
+ return;
2213
+ }
2214
+ const [validationResult, fieldValidator] = validateRule(rule);
2215
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
2216
+ const fieldData = getOption(fields, rule.field);
2217
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
2218
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
2219
+ fieldData
2220
+ }));
2221
+ }).filter(Boolean);
2222
+ if (expressions.length === 0) return;
2223
+ const result = expressions.length === 1 && !hasChildRules ? expressions[0] : { [lc(combinator) === "or" ? Op.or : Op.and]: expressions };
2224
+ return rg.not ? { [Op.not]: result } : result;
2225
+ };
2226
+ return processRuleGroup(convertFromIC(ruleGroup), true);
2227
+ };
2228
+
2229
+ //#endregion
2230
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts
2231
+ /**
2232
+ * Default rule processor used by {@link formatQuery} for "sql" format.
2233
+ *
2234
+ * @group Export
2235
+ */
2236
+ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
2237
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2238
+ const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
2239
+ var _rg$id;
2240
+ if (!isRuleOrGroupValid(rg, validationMap[(_rg$id = rg.id) !== null && _rg$id !== void 0 ? _rg$id : ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
2241
+ const processedRules = rg.rules.map((rule) => {
2242
+ var _rule$valueSource;
2243
+ if (typeof rule === "string") return rule;
2244
+ if (isRuleGroup(rule)) return processRuleGroup(rule, rg.rules.length === 1);
2245
+ const [validationResult, fieldValidator] = validateRule(rule);
2246
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
2247
+ const escapeQuotes = ((_rule$valueSource = rule.valueSource) !== null && _rule$valueSource !== void 0 ? _rule$valueSource : "value") === "value";
2248
+ const fieldData = getOption(fields, rule.field);
2249
+ return ruleProcessor(rule, _objectSpread2(_objectSpread2({}, options), {}, {
2250
+ parseNumbers: getParseNumberBoolean(fieldData === null || fieldData === void 0 ? void 0 : fieldData.inputType),
2251
+ escapeQuotes,
2252
+ fieldData
2253
+ }));
2254
+ }).filter(Boolean);
2255
+ if (processedRules.length === 0) return fallbackExpression;
2256
+ return `${rg.not ? "NOT " : ""}(${processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ")})`;
2257
+ };
2258
+ return processRuleGroup(ruleGroup, true);
2259
+ };
2260
+
2261
+ //#endregion
2262
+ //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
2263
+ const rangeOperatorMap = {
2264
+ "<": "lt",
2265
+ "<=": "lte",
2266
+ ">": "gt",
2267
+ ">=": "gte"
2268
+ };
2269
+ const negateIfNotOp$1 = (op, elasticSearchRule) => op.startsWith("not") || op.startsWith("doesnot") ? { bool: { must_not: elasticSearchRule } } : elasticSearchRule;
2270
+ const escapeSQ = (s) => s === null || s === void 0 ? void 0 : s.replace(/('|\\)/g, `\\$1`);
2271
+ const textFunctionMap = {
2272
+ beginswith: "startsWith",
2273
+ doesnotbeginwith: "startsWith",
2274
+ doesnotcontain: "contains",
2275
+ doesnotendwith: "endsWith",
2276
+ endswith: "endsWith"
2277
+ };
2278
+ const getTextScript = (f, o, v) => {
2279
+ var _textFunctionMap$o;
2280
+ const script = `doc['${f}'].value.${(_textFunctionMap$o = textFunctionMap[o]) !== null && _textFunctionMap$o !== void 0 ? _textFunctionMap$o : o}(doc['${v}'].value)`;
2281
+ return o.startsWith("d") ? `!${script}` : script;
2282
+ };
2283
+ const valueRenderer = (v, parseNumbers) => typeof v === "boolean" ? v : shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v;
2284
+ /**
2285
+ * Default rule processor used by {@link formatQuery} for "elasticsearch" format.
2286
+ *
2287
+ * @group Export
2288
+ */
2289
+ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
2290
+ const { field, operator, value, valueSource } = rule;
2291
+ const { parseNumbers, preserveValueOrder } = options;
2292
+ const operatorLC = lc(operator);
2293
+ if (processMatchMode(rule)) return false;
2294
+ if (valueSource === "field") {
2295
+ if (toArray(value).some((v) => typeof v !== "string")) return false;
2296
+ const fieldForScript = escapeSQ(field);
2297
+ switch (operatorLC) {
2298
+ case "=":
2299
+ case "!=":
2300
+ case ">":
2301
+ case ">=":
2302
+ case "<":
2303
+ case "<=": {
2304
+ const operatorForScript = operatorLC === "=" ? "==" : operatorLC;
2305
+ const valueForScript = escapeSQ(value);
2306
+ return valueForScript ? { bool: { filter: { script: { script: `doc['${fieldForScript}'].value ${operatorForScript} doc['${valueForScript}'].value` } } } } : false;
2307
+ }
2308
+ case "in":
2309
+ case "notin": {
2310
+ const valueAsArray = toArray(value);
2311
+ if (valueAsArray.length > 0) {
2312
+ const arr = valueAsArray.map((v) => ({ bool: { filter: { script: { script: `doc['${fieldForScript}'].value == doc['${v}'].value` } } } }));
2313
+ return { bool: operatorLC === "in" ? { should: arr } : { must_not: arr } };
2314
+ }
2315
+ return false;
2316
+ }
2317
+ case "between":
2318
+ case "notbetween": {
2319
+ const valueAsArray = toArray(value);
2320
+ if (valueAsArray.length >= 2 && valueAsArray[0] && valueAsArray[1]) {
2321
+ const script = `doc['${fieldForScript}'].value >= doc['${valueAsArray[0]}'].value && doc['${fieldForScript}'].value <= doc['${valueAsArray[1]}'].value`;
2322
+ return { bool: { filter: { script: { script: operatorLC === "notbetween" ? `!(${script})` : script } } } };
2323
+ }
2324
+ return false;
2325
+ }
2326
+ case "contains":
2327
+ case "doesnotcontain":
2328
+ case "beginswith":
2329
+ case "doesnotbeginwith":
2330
+ case "endswith":
2331
+ case "doesnotendwith": {
2332
+ const valueForScript = escapeSQ(value);
2333
+ if (!valueForScript) return false;
2334
+ return { bool: { filter: { script: { script: getTextScript(fieldForScript, operatorLC, valueForScript) } } } };
2335
+ }
2336
+ }
2337
+ }
2338
+ switch (operatorLC) {
2339
+ case "<":
2340
+ case "<=":
2341
+ case ">":
2342
+ case ">=": return { range: { [field]: { [rangeOperatorMap[operatorLC]]: valueRenderer(value, parseNumbers) } } };
2343
+ case "=": return { term: { [field]: valueRenderer(value, parseNumbers) } };
2344
+ case "!=": return { bool: { must_not: { term: { [field]: valueRenderer(value, parseNumbers) } } } };
2345
+ case "null": return { bool: { must_not: { exists: { field } } } };
2346
+ case "notnull": return { exists: { field } };
2347
+ case "in":
2348
+ case "notin": {
2349
+ const valueAsArray = toArray(value).map((v) => valueRenderer(v, parseNumbers));
2350
+ if (valueAsArray.length > 0) {
2351
+ const arr = valueAsArray.map((v) => ({ term: { [field]: valueRenderer(v, parseNumbers) } }));
2352
+ return { bool: operatorLC === "in" ? { should: arr } : { must_not: arr } };
2353
+ }
2354
+ return false;
2355
+ }
2356
+ case "between":
2357
+ case "notbetween": {
2358
+ const valueAsArray = toArray(value);
2359
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
2360
+ let [first, second] = valueAsArray;
2361
+ const shouldParseNumbers = !(parseNumbers === false);
2362
+ if (shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
2363
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
2364
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
2365
+ if (!preserveValueOrder && secondNum < firstNum) {
2366
+ const tempNum = secondNum;
2367
+ second = firstNum;
2368
+ first = tempNum;
2369
+ } else {
2370
+ first = firstNum;
2371
+ second = secondNum;
2372
+ }
2373
+ }
2374
+ return negateIfNotOp$1(operatorLC, { range: { [field]: {
2375
+ gte: first,
2376
+ lte: second
2377
+ } } });
2378
+ }
2379
+ return false;
2380
+ }
2381
+ case "contains":
2382
+ case "doesnotcontain": return negateIfNotOp$1(operatorLC, { regexp: { [field]: { value: `.*${value}.*` } } });
2383
+ case "beginswith":
2384
+ case "doesnotbeginwith": return negateIfNotOp$1(operatorLC, { regexp: { [field]: { value: `${value}.*` } } });
2385
+ case "endswith":
2386
+ case "doesnotendwith": return negateIfNotOp$1(operatorLC, { regexp: { [field]: { value: `.*${value}` } } });
2387
+ }
2388
+ return false;
2389
+ };
2390
+
2391
+ //#endregion
2392
+ //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
2393
+ const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
2394
+ const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
2395
+ const negate = (clause, negate$1) => negate$1 ? `$not(${clause})` : clause;
2396
+ const escapeStringRegex = (s) => `${s}`.replaceAll(/[/$()*+.?[\\\]^{|}]/g, String.raw`\$&`).replaceAll("-", String.raw`\x2d`);
2397
+ /**
2398
+ * Default rule processor used by {@link formatQuery} for "jsonata" format.
2399
+ *
2400
+ * @group Export
2401
+ */
2402
+ const defaultRuleProcessorJSONata = (rule, options = {}) => {
2403
+ const { field, operator, value, valueSource } = rule;
2404
+ const { escapeQuotes, parseNumbers, preserveValueOrder, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "" } = options;
2405
+ const valueIsField = valueSource === "field";
2406
+ const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers);
2407
+ const qfn = (f) => getQuotedFieldName(f, {
2408
+ quoteFieldNamesWith,
2409
+ fieldIdentifierSeparator
2410
+ });
2411
+ const matchEval = processMatchMode(rule);
2412
+ if (matchEval === false) return;
2413
+ else if (matchEval) {
2414
+ const { mode, threshold } = matchEval;
2415
+ const totalCount = `$count(${qfn(field)})`;
2416
+ const filteredCount = `$count($filter(${qfn(field)}, function($v) {${defaultRuleGroupProcessorJSONata(transformQuery(value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: r.field ? `$v.${r.field}` : "$v" }) }), options)}}))`;
2417
+ switch (mode) {
2418
+ case "all": return `${filteredCount} = ${totalCount}`;
2419
+ case "none": return `${filteredCount} = 0`;
2420
+ case "some": return `${filteredCount} > 0`;
2421
+ case "atleast":
2422
+ case "atmost":
2423
+ case "exactly": {
2424
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
2425
+ if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`;
2426
+ return `${filteredCount} ${op} ${threshold}`;
2427
+ }
2428
+ }
2429
+ }
2430
+ const operatorLC = lc(operator);
2431
+ switch (operatorLC) {
2432
+ case "<":
2433
+ case "<=":
2434
+ case "=":
2435
+ case "!=":
2436
+ case ">":
2437
+ case ">=": return `${qfn(field)} ${operatorLC} ${valueIsField ? qfn(trimIfString(value)) : useBareValue ? trimIfString(value) : quote(value, escapeQuotes)}`;
2438
+ case "contains":
2439
+ case "doesnotcontain": return negate(`$contains(${qfn(field)}, ${valueIsField ? qfn(trimIfString(value)) : quote(value, escapeQuotes)})`, shouldNegate(operatorLC));
2440
+ case "beginswith":
2441
+ case "doesnotbeginwith": return negate(valueIsField ? `$substring(${qfn(field)}, 0, $length(${qfn(trimIfString(value))})) = ${qfn(trimIfString(value))}` : `$contains(${qfn(field)}, /^${escapeStringRegex(value)}/)`, shouldNegate(operatorLC));
2442
+ case "endswith":
2443
+ case "doesnotendwith": return negate(valueIsField ? `$substring(${qfn(field)}, $length(${qfn(field)}) - $length(${qfn(trimIfString(value))})) = ${qfn(trimIfString(value))}` : `$contains(${qfn(field)}, /${escapeStringRegex(value)}$/)`, shouldNegate(operatorLC));
2444
+ case "null": return `${qfn(field)} = null`;
2445
+ case "notnull": return `${qfn(field)} != null`;
2446
+ case "in":
2447
+ case "notin": {
2448
+ const valueAsArray = toArray(value);
2449
+ return negate(`${qfn(field)} in [${valueAsArray.map((val) => valueIsField ? `${qfn(trimIfString(val))}` : shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : quote(val, escapeQuotes)).join(", ")}]`, shouldNegate(operatorLC));
2450
+ }
2451
+ case "between":
2452
+ case "notbetween": {
2453
+ const valueAsArray = toArray(value);
2454
+ if (valueAsArray.length < 2 || nullOrUndefinedOrEmpty(valueAsArray[0]) || nullOrUndefinedOrEmpty(valueAsArray[1])) return "";
2455
+ const [first, second] = valueAsArray;
2456
+ const shouldParseNumbers = !(parseNumbers === false);
2457
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
2458
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
2459
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : first : firstNum;
2460
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : second : secondNum;
2461
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
2462
+ const tempNum = secondNum;
2463
+ secondValue = firstNum;
2464
+ firstValue = tempNum;
2465
+ }
2466
+ const renderAsNumbers = shouldRenderAsNumber(first, parseNumbers) && shouldRenderAsNumber(second, parseNumbers);
2467
+ const getValueString = (raw, val) => valueIsField ? qfn(raw) : renderAsNumbers ? val : quote(val, escapeQuotes);
2468
+ const expression = `${qfn(field)} >= ${getValueString(first, firstValue)} and ${qfn(field)} <= ${getValueString(second, secondValue)}`;
2469
+ return operatorLC === "between" ? `(${expression})` : negate(expression, true);
2470
+ }
2471
+ }
2472
+ return "";
2473
+ };
2474
+
2475
+ //#endregion
2476
+ //#region src/utils/formatQuery/defaultRuleProcessorJsonLogic.ts
2477
+ const convertOperator = (op) => op.replace(/^(=)$/, "$1=").replace(/^notnull$/i, "!=").replace(/^null$/i, "==");
2478
+ const negateIfNotOp = (op, jsonRule) => op.startsWith("not") || op.startsWith("doesnot") ? { "!": jsonRule } : jsonRule;
2479
+ /**
2480
+ * Default rule processor used by {@link formatQuery} for "jsonlogic" format.
2481
+ *
2482
+ * @group Export
2483
+ */
2484
+ const defaultRuleProcessorJsonLogic = (rule, options = {}) => {
2485
+ const { field, operator, value, valueSource } = rule;
2486
+ const { parseNumbers, preserveValueOrder } = options;
2487
+ const valueIsField = valueSource === "field";
2488
+ const fieldObject = { var: field };
2489
+ const fieldOrNumberRenderer = (v) => valueIsField ? { var: `${v}` } : shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v;
2490
+ const matchEval = processMatchMode(rule);
2491
+ if (matchEval === false) return false;
2492
+ else if (matchEval) {
2493
+ const { mode, threshold } = matchEval;
2494
+ switch (mode) {
2495
+ case "all":
2496
+ case "none":
2497
+ case "some": return { [mode]: [{ var: field }, value.rules.length === 1 && !isRuleGroup(value.rules[0]) ? defaultRuleProcessorJsonLogic(value.rules[0], options) : defaultRuleGroupProcessorJsonLogic(value, options)] };
2498
+ case "atleast":
2499
+ case "atmost":
2500
+ case "exactly": {
2501
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "==";
2502
+ const filteredCount = { reduce: [
2503
+ { filter: [{ var: field }, value.rules.length === 1 && !isRuleGroup(value.rules[0]) ? defaultRuleProcessorJsonLogic(value.rules[0], options) : defaultRuleGroupProcessorJsonLogic(value, options)] },
2504
+ { "+": [1, { var: "accumulator" }] },
2505
+ 0
2506
+ ] };
2507
+ if (threshold > 0 && threshold < 1) {
2508
+ const totalCount = { reduce: [
2509
+ { var: field },
2510
+ { "+": [1, { var: "accumulator" }] },
2511
+ 0
2512
+ ] };
2513
+ return { [op]: [filteredCount, { "*": [totalCount, threshold] }] };
2514
+ }
2515
+ return { [op]: [filteredCount, threshold] };
2516
+ }
2517
+ }
2518
+ }
2519
+ const operatorLC = lc(operator);
2520
+ switch (operatorLC) {
2521
+ case "<":
2522
+ case "<=":
2523
+ case "=":
2524
+ case "!=":
2525
+ case ">":
2526
+ case ">=": return { [convertOperator(operatorLC)]: [fieldObject, fieldOrNumberRenderer(value)] };
2527
+ case "null":
2528
+ case "notnull": return { [`${operatorLC === "notnull" ? "!" : "="}=`]: [fieldObject, null] };
2529
+ case "in":
2530
+ case "notin": {
2531
+ const valueAsArray = toArray(value).map((v) => fieldOrNumberRenderer(v));
2532
+ return negateIfNotOp(operatorLC, { in: [fieldObject, valueAsArray] });
2533
+ }
2534
+ case "between":
2535
+ case "notbetween": {
2536
+ const valueAsArray = toArray(value);
2537
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
2538
+ let [first, second] = valueAsArray;
2539
+ const shouldParseNumbers = !(parseNumbers === false);
2540
+ if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
2541
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
2542
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
2543
+ if (!preserveValueOrder && secondNum < firstNum) {
2544
+ const tempNum = secondNum;
2545
+ second = firstNum;
2546
+ first = tempNum;
2547
+ } else {
2548
+ first = firstNum;
2549
+ second = secondNum;
2550
+ }
2551
+ } else if (valueIsField) {
2552
+ first = { var: first };
2553
+ second = { var: second };
2554
+ }
2555
+ return negateIfNotOp(operatorLC, { "<=": [
2556
+ first,
2557
+ fieldObject,
2558
+ second
2559
+ ] });
2560
+ }
2561
+ return false;
2562
+ }
2563
+ case "contains":
2564
+ case "doesnotcontain": {
2565
+ const jsonRule = { in: [fieldOrNumberRenderer(value), fieldObject] };
2566
+ return negateIfNotOp(operatorLC, jsonRule);
2567
+ }
2568
+ case "beginswith":
2569
+ case "doesnotbeginwith": {
2570
+ const jsonRule = { startsWith: [fieldObject, fieldOrNumberRenderer(value)] };
2571
+ return negateIfNotOp(operatorLC, jsonRule);
2572
+ }
2573
+ case "endswith":
2574
+ case "doesnotendwith": {
2575
+ const jsonRule = { endsWith: [fieldObject, fieldOrNumberRenderer(value)] };
2576
+ return negateIfNotOp(operatorLC, jsonRule);
2577
+ }
2578
+ }
2579
+ return false;
2580
+ };
2581
+
2582
+ //#endregion
2583
+ //#region src/utils/formatQuery/defaultRuleProcessorLDAP.ts
2584
+ const negateIf = (clause, negate$1) => negate$1 ? `(!${clause})` : `${clause}`;
2585
+ const ldapEscape = (s) => `${trimIfString(s)}`.replaceAll(/[()&|=<>~*\\/]/g, (m) => `\\${m.codePointAt(0).toString(16)}`);
2586
+ /**
2587
+ * Default rule processor used by {@link formatQuery} for "ldap" format.
2588
+ *
2589
+ * @group Export
2590
+ */
2591
+ const defaultRuleProcessorLDAP = (rule, options = {}) => {
2592
+ const { field, operator, value, valueSource } = rule;
2593
+ const { preserveValueOrder } = options;
2594
+ const operatorLC = lc(operator);
2595
+ if (valueSource === "field" || nullOrUndefinedOrEmpty(value) && operatorLC !== "null" && operatorLC !== "notnull" || processMatchMode(rule)) return "";
2596
+ switch (operatorLC) {
2597
+ case "=":
2598
+ case "!=": return negateIf(`(${field}=${ldapEscape(value)})`, operatorLC === "!=");
2599
+ case ">":
2600
+ case ">=": return `(${field}>=${ldapEscape(value)})`;
2601
+ case "<":
2602
+ case "<=": return `(${field}<=${ldapEscape(value)})`;
2603
+ case "contains":
2604
+ case "doesnotcontain": return negateIf(`(${field}=*${ldapEscape(value)}*)`, operatorLC === "doesnotcontain");
2605
+ case "beginswith":
2606
+ case "doesnotbeginwith": return negateIf(`(${field}=${ldapEscape(value)}*)`, operatorLC === "doesnotbeginwith");
2607
+ case "endswith":
2608
+ case "doesnotendwith": return negateIf(`(${field}=*${ldapEscape(value)})`, operatorLC === "doesnotendwith");
2609
+ case "null":
2610
+ case "notnull": return negateIf(`(${field}=*)`, operatorLC === "notnull");
2611
+ case "in":
2612
+ case "notin": {
2613
+ const valueAsArray = toArray(value);
2614
+ return negateIf(`(|${valueAsArray.map((val) => `(${field}=${ldapEscape(val)})`).join("")})`, operatorLC === "notin");
2615
+ }
2616
+ case "between":
2617
+ case "notbetween": {
2618
+ const valueAsArray = toArray(value);
2619
+ if (valueAsArray.length < 2 || nullOrUndefinedOrEmpty(valueAsArray[0]) || nullOrUndefinedOrEmpty(valueAsArray[1])) return "";
2620
+ const [first, second] = valueAsArray;
2621
+ const firstNum = shouldRenderAsNumber(first, true) ? parseNumber(first, { parseNumbers: true }) : NaN;
2622
+ const secondNum = shouldRenderAsNumber(second, true) ? parseNumber(second, { parseNumbers: true }) : NaN;
2623
+ let firstValue = Number.isNaN(firstNum) ? first : firstNum;
2624
+ let secondValue = Number.isNaN(secondNum) ? second : secondNum;
2625
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
2626
+ const tempNum = secondNum;
2627
+ secondValue = firstNum;
2628
+ firstValue = tempNum;
2629
+ }
2630
+ return negateIf(`(&(${field}>=${ldapEscape(firstValue)})(${field}<=${ldapEscape(secondValue)}))`, operatorLC === "notbetween");
2631
+ }
2632
+ }
2633
+ // istanbul ignore next
2634
+ return "";
2635
+ };
2636
+
2637
+ //#endregion
2638
+ //#region src/utils/formatQuery/defaultValueProcessorNL.ts
2639
+ const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
2640
+ /**
2641
+ * Default value processor used by {@link formatQuery} for "natural_language" format.
2642
+ *
2643
+ * @group Export
2644
+ */
2645
+ const defaultValueProcessorNL = (rule, opts = {}) => {
2646
+ var _t$or, _t$true, _t$false, _getOption$label3, _getOption3, _ref3;
2647
+ const { escapeQuotes, fields, parseNumbers, quoteFieldNamesWith, quoteValuesWith, fieldIdentifierSeparator, translations } = opts;
2648
+ const valueIsField = rule.valueSource === "field";
2649
+ const operatorLowerCase = lc(rule.operator);
2650
+ const quoteChar = quoteValuesWith || "'";
2651
+ const quoteValue = (v) => `${quoteChar}${v}${quoteChar}`;
2652
+ const escapeValue = (v) => escapeStringValueQuotes(v, quoteChar, escapeQuotes);
2653
+ const wrapAndEscape = (v) => quoteValue(escapeValue(v));
2654
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
2655
+ quoteFieldNamesWith,
2656
+ fieldIdentifierSeparator
2657
+ });
2658
+ const t = translations !== null && translations !== void 0 ? translations : ( /* istanbul ignore next */ {});
2659
+ const orTL = (_t$or = t.or) !== null && _t$or !== void 0 ? _t$or : "or";
2660
+ const trueTL = (_t$true = t.true) !== null && _t$true !== void 0 ? _t$true : "true";
2661
+ const falseTL = (_t$false = t.false) !== null && _t$false !== void 0 ? _t$false : "false";
2662
+ switch (operatorLowerCase) {
2663
+ case "null":
2664
+ case "notnull": return "";
2665
+ case "between":
2666
+ case "notbetween": {
2667
+ if (!valueIsField) return defaultValueProcessorByRule(rule, opts);
2668
+ const valueAsArray = toArray(rule.value, { retainEmptyStrings: true }).slice(0, 2).map((v) => {
2669
+ var _getOption$label, _getOption, _ref;
2670
+ return wrapFieldName((_getOption$label = (_getOption = getOption((_ref = fields) !== null && _ref !== void 0 ? _ref : [], v)) === null || _getOption === void 0 ? void 0 : _getOption.label) !== null && _getOption$label !== void 0 ? _getOption$label : v);
2671
+ });
2672
+ if (valueAsArray.length < 2 || !isValidValue(valueAsArray[0]) || !isValidValue(valueAsArray[1])) return "";
2673
+ return defaultValueProcessorByRule(_objectSpread2(_objectSpread2({}, rule), {}, { value: valueAsArray }), opts);
2674
+ }
2675
+ case "in":
2676
+ case "notin": {
2677
+ const valueAsArray = toArray(rule.value);
2678
+ if (valueAsArray.length === 0) return "";
2679
+ const valStringArray = valueAsArray.map((v) => {
2680
+ var _getOption$label2, _getOption2, _ref2;
2681
+ return valueIsField ? wrapFieldName((_getOption$label2 = (_getOption2 = getOption((_ref2 = fields) !== null && _ref2 !== void 0 ? _ref2 : [], v)) === null || _getOption2 === void 0 ? void 0 : _getOption2.label) !== null && _getOption$label2 !== void 0 ? _getOption$label2 : v) : shouldRenderAsNumber(v, parseNumbers) ? `${trimIfString(v)}` : `${wrapAndEscape(v)}`;
2682
+ });
2683
+ return `${valStringArray.slice(0, -1).join(", ")}${valStringArray.length > 2 ? "," : ""} ${orTL} ${valStringArray.at(-1)}`;
2684
+ }
2685
+ }
2686
+ if (typeof rule.value === "boolean") return rule.value ? trueTL : falseTL;
2687
+ return valueIsField ? wrapFieldName((_getOption$label3 = (_getOption3 = getOption((_ref3 = fields) !== null && _ref3 !== void 0 ? _ref3 : [], rule.value)) === null || _getOption3 === void 0 ? void 0 : _getOption3.label) !== null && _getOption$label3 !== void 0 ? _getOption$label3 : rule.value) : shouldRenderAsNumber(rule.value, parseNumbers) ? `${trimIfString(rule.value)}` : `${wrapAndEscape(rule.value)}`;
2688
+ };
2689
+
2690
+ //#endregion
2691
+ //#region src/utils/formatQuery/defaultRuleProcessorNL.ts
2692
+ /**
2693
+ * Default operator map used by {@link formatQuery} for "natural_language" format.
2694
+ *
2695
+ * @group Export
2696
+ */
2697
+ const defaultExportOperatorMap = {
2698
+ "=": ["is", "is the same as the value in"],
2699
+ "!=": ["is not", "is not the same as the value in"],
2700
+ "<": ["is less than", "is less than the value in"],
2701
+ ">": ["is greater than", "is greater than the value in"],
2702
+ "<=": ["is less than or equal to", "is less than or equal to the value in"],
2703
+ ">=": ["is greater than or equal to", "is greater than or equal to the value in"],
2704
+ contains: ["contains", "contains the value in"],
2705
+ beginswith: ["starts with", "starts with the value in"],
2706
+ endswith: ["ends with", "ends with the value in"],
2707
+ doesnotcontain: ["does not contain", "does not contain the value in"],
2708
+ doesnotbeginwith: ["does not start with", "does not start with the value in"],
2709
+ doesnotendwith: ["does not end with", "does not end with the value in"],
2710
+ null: "is null",
2711
+ notnull: "is not null",
2712
+ in: ["is one of the values", "is the same as a value in"],
2713
+ notin: ["is not one of the values", "is not the same as any value in"],
2714
+ between: ["is between", "is between the values in"],
2715
+ notbetween: ["is not between", "is not between the values in"]
2716
+ };
2717
+ /* istanbul ignore next */
2718
+ const defaultGetOperators = () => [];
2719
+ /**
2720
+ * Default operator processor used by {@link formatQuery} for "natural_language" format.
2721
+ *
2722
+ * @group Export
2723
+ */
2724
+ const defaultOperatorProcessorNL = (rule, opts = {}) => {
2725
+ var _getOption, _getOperators, _opts$fieldData, _ref, _operatorMap;
2726
+ const { field, operator, valueSource = "value" } = rule;
2727
+ // istanbul ignore next
2728
+ const { getOperators = defaultGetOperators, operatorMap: operatorMapParam = defaultExportOperatorMap } = opts;
2729
+ const mapOperatorMap = new Map(Object.entries(defaultExportOperatorMap));
2730
+ for (const [key, value] of Object.entries(operatorMapParam)) mapOperatorMap.set(lc(key), value);
2731
+ const operatorMap = Object.fromEntries(mapOperatorMap);
2732
+ const { value: operatorNL, label } = (_getOption = getOption(toFullOptionList((_getOperators = getOperators(field, { fieldData: (_opts$fieldData = opts.fieldData) !== null && _opts$fieldData !== void 0 ? _opts$fieldData : {
2733
+ name: field,
2734
+ value: field,
2735
+ label: field
2736
+ } })) !== null && _getOperators !== void 0 ? _getOperators : []), operator)) !== null && _getOption !== void 0 ? _getOption : {
2737
+ name: operator,
2738
+ value: operator,
2739
+ label: operator
2740
+ };
2741
+ const operatorTL = (_ref = (_operatorMap = operatorMap[operatorNL]) !== null && _operatorMap !== void 0 ? _operatorMap : operatorMap[lc(operatorNL)]) !== null && _ref !== void 0 ? _ref : [label, label];
2742
+ return typeof operatorTL === "string" ? operatorTL : operatorTL[valueSource === "field" ? 1 : 0];
2743
+ };
2744
+ /**
2745
+ * Default rule processor used by {@link formatQuery} for "natural_language" format.
2746
+ *
2747
+ * @group Export
2748
+ */
2749
+ const defaultRuleProcessorNL = (rule, opts) => {
2750
+ var _fieldData$label;
2751
+ const { field, operator } = rule;
2752
+ // istanbul ignore next
2753
+ const { fieldData, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorNL, valueProcessor = defaultValueProcessorNL, concatOperator = "||", wordOrder = "SVO" } = opts !== null && opts !== void 0 ? opts : ( /* istanbul ignore next */ {});
2754
+ const processedField = getQuotedFieldName((_fieldData$label = fieldData === null || fieldData === void 0 ? void 0 : fieldData.label) !== null && _fieldData$label !== void 0 ? _fieldData$label : field, {
2755
+ quoteFieldNamesWith,
2756
+ fieldIdentifierSeparator
2757
+ });
2758
+ const matchEval = processMatchMode(rule);
2759
+ if (matchEval === false) return "";
2760
+ else if (matchEval) {
2761
+ var _fieldData$subpropert, _fieldData$subpropert2, _fieldData$subpropert3;
2762
+ const { mode, threshold } = matchEval;
2763
+ const nestedArrayFilter = defaultRuleGroupProcessorNL(rule.value, _objectSpread2(_objectSpread2({}, opts), {}, { fields: toFullOptionList((_fieldData$subpropert = fieldData === null || fieldData === void 0 ? void 0 : fieldData.subproperties) !== null && _fieldData$subpropert !== void 0 ? _fieldData$subpropert : []) }));
2764
+ const hsp = ((_fieldData$subpropert2 = fieldData === null || fieldData === void 0 || (_fieldData$subpropert3 = fieldData.subproperties) === null || _fieldData$subpropert3 === void 0 ? void 0 : _fieldData$subpropert3.length) !== null && _fieldData$subpropert2 !== void 0 ? _fieldData$subpropert2 : 0) > 0;
2765
+ switch (mode) {
2766
+ case "all": return `(${hsp ? "for " : ""}every item in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
2767
+ case "none": return `(${hsp ? "for " : ""}no item in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
2768
+ case "some": return `(${hsp ? "for " : ""}at least one item in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
2769
+ case "atleast":
2770
+ case "atmost":
2771
+ case "exactly": {
2772
+ const mm = mode.replace("at", "at ");
2773
+ if (threshold > 0 && threshold < 1) return `(${hsp ? "for " : ""}${mm} ${threshold * 100}% of the items in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
2774
+ return `(${hsp ? "for " : ""}${mm} ${threshold} of the items in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
2775
+ }
2776
+ }
2777
+ }
2778
+ const value = valueProcessor(rule, _objectSpread2(_objectSpread2({}, opts), {}, {
2779
+ quoteFieldNamesWith,
2780
+ fieldIdentifierSeparator,
2781
+ quoteValuesWith,
2782
+ concatOperator
2783
+ }));
2784
+ const operatorLC = lc(operator);
2785
+ if ((operatorLC === "in" || operatorLC === "notin" || operatorLC === "between" || operatorLC === "notbetween") && !value) return "";
2786
+ const processedOperator = operatorProcessor(rule, opts);
2787
+ const wordOrderMap = {
2788
+ S: processedField,
2789
+ V: processedOperator,
2790
+ O: value
2791
+ };
2792
+ return normalizeConstituentWordOrder(wordOrder).map((term) => `${wordOrderMap[term]}`).join(" ").trim();
2793
+ };
2794
+
2795
+ //#endregion
2796
+ //#region src/utils/formatQuery/defaultRuleProcessorSQL.ts
2797
+ /**
2798
+ * Default operator processor used by {@link formatQuery} for "sql" and "parameterized*" formats.
2799
+ *
2800
+ * @group Export
2801
+ */
2802
+ const defaultOperatorProcessorSQL = (rule) => lc(mapSQLOperator(rule.operator));
2803
+ /**
2804
+ * Default rule processor used by {@link formatQuery} for "sql" format.
2805
+ *
2806
+ * @group Export
2807
+ */
2808
+ const defaultRuleProcessorSQL = (rule, opts = {}) => {
2809
+ const { quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorSQL, valueProcessor = defaultValueProcessorByRule, concatOperator = "||" } = opts;
2810
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
2811
+ quoteFieldNamesWith,
2812
+ fieldIdentifierSeparator
2813
+ });
2814
+ const ruleField = wrapFieldName(rule.field);
2815
+ const matchEval = processMatchMode(rule);
2816
+ if (matchEval === false) return;
2817
+ else if (matchEval) {
2818
+ if ((opts === null || opts === void 0 ? void 0 : opts.preset) !== "postgresql") return "";
2819
+ const { mode, threshold } = matchEval;
2820
+ const arrayElementAlias = "elem_alias";
2821
+ const nestedArrayFilter = defaultRuleGroupProcessorSQL(transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: arrayElementAlias }) }), opts);
2822
+ switch (mode) {
2823
+ case "all": return `(select count(*) from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter}) = array_length(${ruleField}, 1)`;
2824
+ case "none": return `not exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter})`;
2825
+ case "some": return `exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter})`;
2826
+ case "atleast":
2827
+ case "atmost":
2828
+ case "exactly": {
2829
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
2830
+ return `(select count(*)${threshold > 0 && threshold < 1 ? ` / array_length(${ruleField}, 1)` : ""} from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter}) ${op} ${threshold}`;
2831
+ }
2832
+ }
2833
+ }
2834
+ const value = valueProcessor(rule, _objectSpread2(_objectSpread2({}, opts), {}, {
2835
+ quoteFieldNamesWith,
2836
+ fieldIdentifierSeparator,
2837
+ quoteValuesWith,
2838
+ concatOperator
2839
+ }));
2840
+ const operator = operatorProcessor(rule, opts);
2841
+ const operatorLowerCase = lc(operator);
2842
+ if ((operatorLowerCase === "in" || operatorLowerCase === "not in" || operatorLowerCase === "between" || operatorLowerCase === "not between") && !value) return "";
2843
+ return `${ruleField} ${operator} ${value}`.trim();
2844
+ };
2845
+
2846
+ //#endregion
2847
+ //#region src/utils/formatQuery/defaultRuleProcessorParameterized.ts
2848
+ /**
2849
+ * Default rule processor used by {@link formatQuery} for "parameterized" and
2850
+ * "parameterized_named" formats.
2851
+ *
2852
+ * @group Export
2853
+ */
2854
+ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
2855
+ // istanbul ignore next
2856
+ const { fieldData, format, getNextNamedParam, parseNumbers, paramPrefix, paramsKeepPrefix, numberedParams, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator, concatOperator, operatorProcessor = defaultOperatorProcessorSQL, valueProcessor = defaultValueProcessorByRule } = opts !== null && opts !== void 0 ? opts : {};
2857
+ const { processedParams = [] } = meta !== null && meta !== void 0 ? meta : {};
2858
+ const parameterized = format === "parameterized";
2859
+ const params = [];
2860
+ const paramsNamed = {};
2861
+ const finalize = (sql) => parameterized ? {
2862
+ sql,
2863
+ params
2864
+ } : {
2865
+ sql,
2866
+ params: paramsNamed
2867
+ };
2868
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
2869
+ quoteFieldNamesWith,
2870
+ fieldIdentifierSeparator
2871
+ });
2872
+ const ruleField = wrapFieldName(rule.field);
2873
+ const matchEval = processMatchMode(rule);
2874
+ if (matchEval === false) return;
2875
+ else if (matchEval) {
2876
+ if ((opts === null || opts === void 0 ? void 0 : opts.preset) !== "postgresql") return finalize("");
2877
+ const { mode, threshold } = matchEval;
2878
+ const arrayElementAlias = "elem_alias";
2879
+ const { sql: nestedSQL, params: nestedParams } = defaultRuleGroupProcessorParameterized(transformQuery(rule.value, { ruleProcessor: (r) => _objectSpread2(_objectSpread2({}, r), {}, { field: arrayElementAlias }) }), _objectSpread2(_objectSpread2({}, opts), {}, { fields: [] }));
2880
+ // istanbul ignore else
2881
+ if (Array.isArray(nestedParams)) params.push(...nestedParams);
2882
+ else Object.assign(paramsNamed, nestedParams);
2883
+ switch (mode) {
2884
+ case "all": return finalize(`(select count(*) from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL}) = array_length(${ruleField}, 1)`);
2885
+ case "none": return finalize(`not exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL})`);
2886
+ case "some": return finalize(`exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL})`);
2887
+ case "atleast":
2888
+ case "atmost":
2889
+ case "exactly": {
2890
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
2891
+ return finalize(`(select count(*)${threshold > 0 && threshold < 1 ? ` / array_length(${ruleField}, 1)` : ""} from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL}) ${op} ${threshold}`);
2892
+ }
2893
+ }
2894
+ }
2895
+ const value = valueProcessor(rule, {
2896
+ parseNumbers,
2897
+ quoteFieldNamesWith,
2898
+ concatOperator,
2899
+ fieldData,
2900
+ format
2901
+ });
2902
+ const sqlOperator = operatorProcessor(rule, opts);
2903
+ const sqlOperatorLowerCase = lc(sqlOperator);
2904
+ const [qPre, qPost] = quoteFieldNamesWith;
2905
+ if ((sqlOperatorLowerCase === "in" || sqlOperatorLowerCase === "not in" || sqlOperatorLowerCase === "between" || sqlOperatorLowerCase === "not between") && !value) return finalize("");
2906
+ else if (sqlOperatorLowerCase === "is null" || sqlOperatorLowerCase === "is not null") return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator}`);
2907
+ else if (rule.valueSource === "field") return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${value}`.trim());
2908
+ else if (sqlOperatorLowerCase === "in" || sqlOperatorLowerCase === "not in") {
2909
+ const splitValue = toArray(rule.value);
2910
+ if (parameterized) {
2911
+ for (const v of splitValue) params.push(shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v);
2912
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} (${splitValue.map((_v, i) => numberedParams ? `${paramPrefix}${processedParams.length + 1 + splitValue.length - (splitValue.length - i)}` : "?").join(", ")})`);
2913
+ }
2914
+ const inParams = [];
2915
+ for (const v of splitValue) {
2916
+ const thisParamName = getNextNamedParam(rule.field);
2917
+ inParams.push(`${paramPrefix}${thisParamName}`);
2918
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${thisParamName}`] = shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v;
2919
+ }
2920
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} (${inParams.join(", ")})`);
2921
+ } else if (sqlOperatorLowerCase === "between" || sqlOperatorLowerCase === "not between") {
2922
+ const [first, second] = toArray(rule.value, { retainEmptyStrings: true }).slice(0, 2).map((v) => shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v);
2923
+ if (parameterized) {
2924
+ params.push(first, second);
2925
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?"} and ${numberedParams ? `${paramPrefix}${processedParams.length + 2}` : "?"}`);
2926
+ }
2927
+ const firstParamName = getNextNamedParam(rule.field);
2928
+ const secondParamName = getNextNamedParam(rule.field);
2929
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${firstParamName}`] = first;
2930
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${secondParamName}`] = second;
2931
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${paramPrefix}${firstParamName} and ${paramPrefix}${secondParamName}`);
2932
+ }
2933
+ let paramValue = rule.value;
2934
+ if (typeof rule.value === "string") if (shouldRenderAsNumber(rule.value, parseNumbers)) paramValue = parseNumber(rule.value, { parseNumbers });
2935
+ else paramValue = /^'.*'$/g.test(value) ? value.replaceAll(/(^'|'$)/g, "") : value;
2936
+ let paramName = "";
2937
+ if (parameterized) params.push(paramValue);
2938
+ else {
2939
+ paramName = getNextNamedParam(rule.field);
2940
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${paramName}`] = paramValue;
2941
+ }
2942
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${parameterized ? numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?" : `${paramPrefix}${paramName}`}`.trim());
2943
+ };
2944
+
2945
+ //#endregion
2946
+ //#region src/utils/formatQuery/defaultRuleProcessorPrisma.ts
2947
+ const processNumber = (value, fallback, parseNumbers) => shouldRenderAsNumber(value, !!parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: !!parseNumbers })) : fallback;
2948
+ /**
2949
+ * Default rule processor used by {@link formatQuery} for "prisma" format.
2950
+ *
2951
+ * @group Export
2952
+ */
2953
+ const defaultRuleProcessorPrisma = (rule, options = {}) => {
2954
+ const { field, operator, value, valueSource } = rule;
2955
+ // istanbul ignore next
2956
+ const { parseNumbers, preserveValueOrder } = options;
2957
+ if (valueSource === "field" || processMatchMode(rule)) return;
2958
+ const operatorLC = lc(operator);
2959
+ switch (operatorLC) {
2960
+ case "=": return { [field]: processNumber(value, value, parseNumbers) };
2961
+ case "!=":
2962
+ case "<":
2963
+ case "<=":
2964
+ case ">":
2965
+ case ">=": {
2966
+ const prismaOperator = prismaOperators[operatorLC];
2967
+ return { [field]: { [prismaOperator]: processNumber(value, value, parseNumbers) } };
2968
+ }
2969
+ case "contains": return { [field]: { contains: value } };
2970
+ case "beginswith": return { [field]: { startsWith: value } };
2971
+ case "endswith": return { [field]: { endsWith: value } };
2972
+ case "doesnotcontain": return { NOT: { [field]: { contains: value } } };
2973
+ case "doesnotbeginwith": return { NOT: { [field]: { startsWith: value } } };
2974
+ case "doesnotendwith": return { NOT: { [field]: { endsWith: value } } };
2975
+ case "null": return { [field]: null };
2976
+ case "notnull": return { [field]: { not: null } };
2977
+ case "in":
2978
+ case "notin": {
2979
+ const valueAsArray = toArray(value);
2980
+ return { [field]: { [prismaOperators[operatorLC]]: valueAsArray.map((val) => processNumber(val, val, parseNumbers)) } };
2981
+ }
2982
+ case "between":
2983
+ case "notbetween": {
2984
+ const valueAsArray = toArray(value);
2985
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
2986
+ const [first, second] = valueAsArray;
2987
+ const shouldParseNumbers = !(parseNumbers === false);
2988
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers }) : NaN;
2989
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers }) : NaN;
2990
+ let firstValue = Number.isNaN(firstNum) ? first : firstNum;
2991
+ let secondValue = Number.isNaN(secondNum) ? second : secondNum;
2992
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
2993
+ const tempNum = secondNum;
2994
+ secondValue = firstNum;
2995
+ firstValue = tempNum;
2996
+ }
2997
+ return operatorLC === "between" ? { [field]: {
2998
+ gte: firstValue,
2999
+ lte: secondValue
3000
+ } } : { OR: [{ [field]: { lt: firstValue } }, { [field]: { gt: secondValue } }] };
3001
+ } else return "";
3002
+ }
3003
+ }
3004
+ return "";
3005
+ };
3006
+
3007
+ //#endregion
3008
+ //#region src/utils/formatQuery/defaultRuleProcessorSequelize.ts
3009
+ /**
3010
+ * Default rule processor used by {@link formatQuery} for the "sequelize" format.
3011
+ *
3012
+ * @group Export
3013
+ */
3014
+ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder, context = {} } = {}) => {
3015
+ const { sequelizeOperators: Op, sequelizeCol: col, sequelizeFn: fn } = context;
3016
+ if (processMatchMode(rule)) return;
3017
+ const { field, operator, value, valueSource } = rule;
3018
+ const valueIsField = valueSource === "field";
3019
+ const operatorLC = lc(operator);
3020
+ if (!Op || valueIsField && (!col || !fn && [
3021
+ "doesnotcontain",
3022
+ "doesnotbeginwith",
3023
+ "doesnotendwith"
3024
+ ].includes(operatorLC))) return;
3025
+ switch (operatorLC) {
3026
+ case "=":
3027
+ case "!=":
3028
+ case "<":
3029
+ case "<=":
3030
+ case ">":
3031
+ case ">=": {
3032
+ const sequelizeOperator = {
3033
+ "=": Op.eq,
3034
+ "!=": Op.ne,
3035
+ "<": Op.lt,
3036
+ "<=": Op.lte,
3037
+ ">": Op.gt,
3038
+ ">=": Op.gte
3039
+ }[operatorLC];
3040
+ return { [field]: valueIsField && operatorLC === "=" ? { [Op.col]: value } : { [sequelizeOperator]: valueIsField ? col(value) : shouldRenderAsNumber(value, parseNumbers) ? parseNumber(value, { parseNumbers: "strict" }) : value } };
3041
+ }
3042
+ case "contains": return { [field]: { [Op.substring]: valueIsField ? col(value) : `${value}` } };
3043
+ case "beginswith": return { [field]: { [Op.startsWith]: valueIsField ? col(value) : `${value}` } };
3044
+ case "endswith": return { [field]: { [Op.endsWith]: valueIsField ? col(value) : `${value}` } };
3045
+ case "doesnotcontain": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value), "%") : `%${value}%` } };
3046
+ case "doesnotbeginwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", col(value), "%") : `${value}%` } };
3047
+ case "doesnotendwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value)) : `%${value}` } };
3048
+ case "null": return { [field]: { [Op.is]: null } };
3049
+ case "notnull": return { [field]: { [Op.not]: null } };
3050
+ case "in":
3051
+ case "notin": {
3052
+ const valueAsArray = toArray(value);
3053
+ return { [field]: { [operatorLC === "in" ? Op.in : Op.notIn]: valueAsArray.map((val) => valueIsField ? col(val) : shouldRenderAsNumber(val, parseNumbers) ? parseNumber(val, { parseNumbers: "strict" }) : val) } };
3054
+ }
3055
+ case "between":
3056
+ case "notbetween": {
3057
+ const valueAsArray = toArray(value, { retainEmptyStrings: true });
3058
+ if (valueAsArray.length < 2 || !isValidValue(valueAsArray[0]) || !isValidValue(valueAsArray[1])) return;
3059
+ const [first, second] = valueAsArray;
3060
+ const firstNum = shouldRenderAsNumber(first, parseNumbers) ? parseNumber(first, { parseNumbers: "strict" }) : NaN;
3061
+ const secondNum = shouldRenderAsNumber(second, parseNumbers) ? parseNumber(second, { parseNumbers: "strict" }) : NaN;
3062
+ const firstValue = Number.isNaN(firstNum) ? first : firstNum;
3063
+ const secondValue = Number.isNaN(secondNum) ? second : secondNum;
3064
+ const valsOneAndTwoOnly = [firstValue, secondValue];
3065
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
3066
+ valsOneAndTwoOnly[0] = secondNum;
3067
+ valsOneAndTwoOnly[1] = firstNum;
3068
+ }
3069
+ return { [field]: { [operatorLC === "between" ? Op.between : Op.notBetween]: valueIsField ? valsOneAndTwoOnly.map((v) => col(v)) : valsOneAndTwoOnly.every((v) => shouldRenderAsNumber(v, parseNumbers)) ? valsOneAndTwoOnly.map((v) => parseNumber(v, { parseNumbers: "strict" })) : valsOneAndTwoOnly } };
3070
+ }
3071
+ }
3072
+ };
3073
+
3074
+ //#endregion
3075
+ //#region src/utils/formatQuery/formatQuery.ts
3076
+ /**
3077
+ * A collection of option presets for {@link formatQuery}, specifically for SQL-based formats.
3078
+ *
3079
+ * @group Export
3080
+ */
3081
+ const sqlDialectPresets = {
3082
+ ansi: {},
3083
+ sqlite: { paramsKeepPrefix: true },
3084
+ oracle: {},
3085
+ mssql: {
3086
+ concatOperator: "+",
3087
+ quoteFieldNamesWith: ["[", "]"],
3088
+ fieldIdentifierSeparator: ".",
3089
+ paramPrefix: "@"
3090
+ },
3091
+ mysql: { concatOperator: "CONCAT" },
3092
+ postgresql: {
3093
+ quoteFieldNamesWith: "\"",
3094
+ numberedParams: true,
3095
+ paramPrefix: "$"
3096
+ }
3097
+ };
3098
+ /**
3099
+ * A collection of option presets for {@link formatQuery}.
3100
+ *
3101
+ * @group Export
3102
+ */
3103
+ const formatQueryOptionPresets = _objectSpread2({}, sqlDialectPresets);
3104
+ const defaultRuleProcessors = {
3105
+ cel: defaultRuleProcessorCEL,
3106
+ drizzle: defaultRuleProcessorDrizzle,
3107
+ elasticsearch: defaultRuleProcessorElasticSearch,
3108
+ json_without_ids: defaultRuleProcessorSQL,
3109
+ json: defaultRuleProcessorSQL,
3110
+ jsonata: defaultRuleProcessorJSONata,
3111
+ jsonlogic: defaultRuleProcessorJsonLogic,
3112
+ ldap: defaultRuleProcessorLDAP,
3113
+ mongodb_query: defaultRuleProcessorMongoDBQuery,
3114
+ mongodb: defaultRuleProcessorMongoDB,
3115
+ natural_language: defaultRuleProcessorNL,
3116
+ parameterized_named: defaultRuleProcessorParameterized,
3117
+ parameterized: defaultRuleProcessorParameterized,
3118
+ prisma: defaultRuleProcessorPrisma,
3119
+ sequelize: defaultRuleProcessorSequelize,
3120
+ spel: defaultRuleProcessorSpEL,
3121
+ sql: defaultRuleProcessorSQL
3122
+ };
3123
+ /* istanbul ignore next */
3124
+ const defaultOperatorProcessor = (r) => r.operator;
3125
+ const defaultOperatorProcessors = {
3126
+ cel: defaultOperatorProcessor,
3127
+ drizzle: defaultOperatorProcessor,
3128
+ elasticsearch: defaultOperatorProcessor,
3129
+ json_without_ids: defaultOperatorProcessor,
3130
+ json: defaultOperatorProcessor,
3131
+ jsonata: defaultOperatorProcessor,
3132
+ jsonlogic: defaultOperatorProcessor,
3133
+ ldap: defaultOperatorProcessor,
3134
+ mongodb_query: defaultOperatorProcessor,
3135
+ mongodb: defaultOperatorProcessor,
3136
+ natural_language: defaultOperatorProcessorNL,
3137
+ parameterized_named: defaultOperatorProcessorSQL,
3138
+ parameterized: defaultOperatorProcessorSQL,
3139
+ prisma: defaultOperatorProcessor,
3140
+ sequelize: defaultOperatorProcessor,
3141
+ spel: defaultOperatorProcessor,
3142
+ sql: defaultOperatorProcessorSQL
3143
+ };
3144
+ const defaultFallbackExpressions = {
3145
+ cel: "1 == 1",
3146
+ ldap: "",
3147
+ mongodb: "\"$and\":[{\"$expr\":true}]",
3148
+ natural_language: "1 is 1",
3149
+ spel: "1 == 1",
3150
+ sql: "(1 = 1)"
3151
+ };
3152
+ const defaultFormatQueryOptions = {
3153
+ format: "json",
3154
+ fields: [],
3155
+ quoteFieldNamesWith: ["", ""],
3156
+ fieldIdentifierSeparator: "",
3157
+ getOperators: () => [],
3158
+ paramPrefix: ":",
3159
+ paramsKeepPrefix: false,
3160
+ numberedParams: false,
3161
+ preserveValueOrder: false,
3162
+ placeholderFieldName: defaultPlaceholderFieldName,
3163
+ placeholderOperatorName: defaultPlaceholderOperatorName,
3164
+ quoteValuesWith: "'",
3165
+ concatOperator: "||",
3166
+ preset: "ansi",
3167
+ wordOrder: "SVO",
3168
+ translations: {},
3169
+ operatorMap: {}
3170
+ };
3171
+ const valueProcessorCanActAsRuleProcessor = new Set([
3172
+ "cel",
3173
+ "drizzle",
3174
+ "elasticsearch",
3175
+ "jsonata",
3176
+ "jsonlogic",
3177
+ "ldap",
3178
+ "mongodb_query",
3179
+ "mongodb",
3180
+ "prisma",
3181
+ "sequelize",
3182
+ "spel"
3183
+ ]);
3184
+ const sqlFormats = new Set([
3185
+ "sql",
3186
+ "parameterized",
3187
+ "parameterized_named",
3188
+ "drizzle",
3189
+ "prisma",
3190
+ "sequelize"
3191
+ ]);
3192
+ function formatQuery(ruleGroup, optionParam = {}) {
3193
+ var _sqlDialectPresets, _options$preset, _options$preset2, _defaultOperatorProce, _ref, _ref2, _ref3, _ref4;
3194
+ const options = typeof optionParam === "string" ? { format: lc(optionParam) } : optionParam;
3195
+ const optObj = _objectSpread2(_objectSpread2(_objectSpread2(_objectSpread2({}, defaultFormatQueryOptions), !options.format || sqlFormats.has(options.format) ? (_sqlDialectPresets = sqlDialectPresets[(_options$preset = options.preset) !== null && _options$preset !== void 0 ? _options$preset : "ansi"]) !== null && _sqlDialectPresets !== void 0 ? _sqlDialectPresets : null : null), options), !options.format && (Object.keys(sqlDialectPresets).includes((_options$preset2 = options.preset) !== null && _options$preset2 !== void 0 ? _options$preset2 : "") ? { format: "sql" } : null));
3196
+ const format = lc(optObj.format);
3197
+ const { fallbackExpression: fallbackExpression_option, getOperators: getOperators_option, operatorProcessor: operatorProcessor_option, parseNumbers, quoteFieldNamesWith: quoteFieldNamesWith_option, ruleGroupProcessor: ruleGroupProcessor_option, ruleProcessor: ruleProcessor_option, validator, valueProcessor: valueProcessor_option, context } = optObj;
3198
+ const getParseNumberBoolean = (inputType) => {
3199
+ return typeof getParseNumberMethod({
3200
+ parseNumbers,
3201
+ inputType
3202
+ }) === "string" ? true : typeof parseNumbers === "boolean" ? parseNumbers : void 0;
3203
+ };
3204
+ const operatorProcessor = typeof operatorProcessor_option === "function" ? operatorProcessor_option : (_defaultOperatorProce = defaultOperatorProcessors[format]) !== null && _defaultOperatorProce !== void 0 ? _defaultOperatorProce : defaultOperatorProcessor;
3205
+ const valueProcessor = typeof valueProcessor_option === "function" ? isValueProcessorLegacy(valueProcessor_option) ? (r) => valueProcessor_option(r.field, r.operator, r.value, r.valueSource) : valueProcessor_option : format === "natural_language" ? defaultValueProcessorNL : valueProcessorCanActAsRuleProcessor.has(format) ? ruleProcessor_option !== null && ruleProcessor_option !== void 0 ? ruleProcessor_option : defaultRuleProcessors[format] : defaultValueProcessorByRule;
3206
+ const ruleProcessor = (_ref = (_ref2 = (_ref3 = typeof ruleProcessor_option === "function" ? ruleProcessor_option : null) !== null && _ref3 !== void 0 ? _ref3 : valueProcessorCanActAsRuleProcessor.has(format) && typeof ruleProcessor_option !== "function" && valueProcessor_option ? valueProcessor : null) !== null && _ref2 !== void 0 ? _ref2 : defaultRuleProcessors[format]) !== null && _ref !== void 0 ? _ref : defaultRuleProcessorSQL;
3207
+ const quoteFieldNamesWith = getQuoteFieldNamesWithArray(quoteFieldNamesWith_option);
3208
+ const fields = toFullOptionList(optObj.fields);
3209
+ const getOperators = (f, m) => {
3210
+ var _getOperators_option;
3211
+ return toFullOptionList((_getOperators_option = getOperators_option(f, m)) !== null && _getOperators_option !== void 0 ? _getOperators_option : []);
3212
+ };
3213
+ const fallbackExpression = (_ref4 = fallbackExpression_option !== null && fallbackExpression_option !== void 0 ? fallbackExpression_option : defaultFallbackExpressions[format]) !== null && _ref4 !== void 0 ? _ref4 : defaultFallbackExpressions.sql;
3214
+ let validationMap = {};
3215
+ // istanbul ignore else
3216
+ if (typeof validator === "function") {
3217
+ const validationResult = validator(ruleGroup);
3218
+ if (typeof validationResult === "boolean") {
3219
+ // istanbul ignore else
3220
+ if (!validationResult) return format === "parameterized" ? {
3221
+ sql: fallbackExpression,
3222
+ params: []
3223
+ } : format === "parameterized_named" ? {
3224
+ sql: fallbackExpression,
3225
+ params: {}
3226
+ } : format === "mongodb" ? `{${fallbackExpression}}` : format === "mongodb_query" ? mongoDbFallback : format === "prisma" ? prismaFallback : format === "jsonlogic" ? false : format === "elasticsearch" ? {} : format === "drizzle" || format === "sequelize" ? void 0 : fallbackExpression;
3227
+ } else validationMap = validationResult;
3228
+ }
3229
+ const validatorMap = {};
3230
+ const uniqueFields = toFlatOptionArray(fields);
3231
+ for (const f of uniqueFields)
3232
+ // istanbul ignore else
3233
+ if (typeof f.validator === "function") {
3234
+ var _f$value;
3235
+ validatorMap[(_f$value = f.value) !== null && _f$value !== void 0 ? _f$value : f.name] = f.validator;
3236
+ }
3237
+ const validateRule = (rule) => {
3238
+ let validationResult;
3239
+ let fieldValidator;
3240
+ if (rule.id) validationResult = validationMap[rule.id];
3241
+ if (uniqueFields.length > 0) {
3242
+ const fieldArr = uniqueFields.filter((f) => f.name === rule.field);
3243
+ if (fieldArr.length > 0) {
3244
+ const field = fieldArr[0];
3245
+ // istanbul ignore else
3246
+ if (typeof field.validator === "function") fieldValidator = field.validator;
3247
+ }
3248
+ }
3249
+ return [validationResult, fieldValidator];
3250
+ };
3251
+ const finalOptions = _objectSpread2(_objectSpread2({}, optObj), {}, {
3252
+ fallbackExpression,
3253
+ fields,
3254
+ format,
3255
+ getOperators,
3256
+ getParseNumberBoolean,
3257
+ quoteFieldNamesWith,
3258
+ operatorProcessor,
3259
+ ruleProcessor,
3260
+ valueProcessor,
3261
+ validateRule,
3262
+ validationMap,
3263
+ context
3264
+ });
3265
+ if (typeof ruleGroupProcessor_option === "function") return ruleGroupProcessor_option(ruleGroup, finalOptions);
3266
+ switch (format) {
3267
+ case "json":
3268
+ case "json_without_ids": {
3269
+ const rg = parseNumbers ? produce(ruleGroup, (g) => numerifyValues(g, finalOptions)) : ruleGroup;
3270
+ if (format === "json_without_ids") return JSON.stringify(rg, (key, value) => key === "id" || key === "path" ? void 0 : bigIntJsonStringifyReplacer(key, value));
3271
+ return JSON.stringify(rg, bigIntJsonStringifyReplacer, 2);
3272
+ }
3273
+ case "sql": return defaultRuleGroupProcessorSQL(ruleGroup, finalOptions);
3274
+ case "parameterized":
3275
+ case "parameterized_named": return defaultRuleGroupProcessorParameterized(ruleGroup, finalOptions);
3276
+ case "mongodb": return defaultRuleGroupProcessorMongoDB(ruleGroup, finalOptions);
3277
+ case "mongodb_query": return defaultRuleGroupProcessorMongoDBQuery(ruleGroup, finalOptions);
3278
+ case "cel": return defaultRuleGroupProcessorCEL(ruleGroup, finalOptions);
3279
+ case "spel": return defaultRuleGroupProcessorSpEL(ruleGroup, finalOptions);
3280
+ case "jsonata": return defaultRuleGroupProcessorJSONata(ruleGroup, finalOptions);
3281
+ case "jsonlogic": return defaultRuleGroupProcessorJsonLogic(ruleGroup, finalOptions);
3282
+ case "elasticsearch": return defaultRuleGroupProcessorElasticSearch(ruleGroup, finalOptions);
3283
+ case "natural_language": return defaultRuleGroupProcessorNL(ruleGroup, finalOptions);
3284
+ case "ldap": return defaultRuleGroupProcessorLDAP(ruleGroup, finalOptions);
3285
+ case "prisma": return defaultRuleGroupProcessorPrisma(ruleGroup, finalOptions);
3286
+ case "drizzle": return defaultRuleGroupProcessorDrizzle(ruleGroup, finalOptions);
3287
+ case "sequelize": return defaultRuleGroupProcessorSequelize(ruleGroup, finalOptions);
3288
+ default: return "";
3289
+ }
3290
+ }
3291
+
3292
+ //#endregion
3293
+ //#region src/utils/formatQuery/index.ts
3294
+ const generateValueProcessor = (vpbr) => (field, operator, value, valueSource) => vpbr({
3295
+ field,
3296
+ operator,
3297
+ value,
3298
+ valueSource
3299
+ }, { parseNumbers: false });
3300
+ /**
3301
+ * Default value processor used by {@link formatQuery} for "sql" format.
3302
+ *
3303
+ * @group Export
3304
+ */
3305
+ const defaultValueProcessor = generateValueProcessor(defaultValueProcessorByRule);
3306
+ /**
3307
+ * @deprecated Prefer {@link defaultRuleProcessorMongoDB}.
3308
+ *
3309
+ * @group Export
3310
+ */
3311
+ const defaultMongoDBValueProcessor = generateValueProcessor(defaultRuleProcessorMongoDB);
3312
+ /**
3313
+ * @deprecated Prefer {@link defaultRuleProcessorCEL}.
3314
+ *
3315
+ * @group Export
3316
+ */
3317
+ const defaultCELValueProcessor = generateValueProcessor(defaultRuleProcessorCEL);
3318
+ /**
3319
+ * @deprecated Prefer {@link defaultRuleProcessorSpEL}.
3320
+ *
3321
+ * @group Export
3322
+ */
3323
+ const defaultSpELValueProcessor = generateValueProcessor(defaultRuleProcessorSpEL);
3324
+ /**
3325
+ * @deprecated Renamed to {@link defaultRuleProcessorCEL}.
3326
+ *
3327
+ * @group Export
3328
+ */
3329
+ const defaultValueProcessorCELByRule = defaultRuleProcessorCEL;
3330
+ /**
3331
+ * @deprecated Renamed to {@link defaultRuleProcessorMongoDB}.
3332
+ *
3333
+ * @group Export
3334
+ */
3335
+ const defaultValueProcessorMongoDBByRule = defaultRuleProcessorMongoDB;
3336
+ /**
3337
+ * @deprecated Renamed to {@link defaultRuleProcessorSpEL}.
3338
+ *
3339
+ * @group Export
3340
+ */
3341
+ const defaultValueProcessorSpELByRule = defaultRuleProcessorSpEL;
3342
+
3343
+ //#endregion
3344
+ //#region src/utils/pathUtils.ts
3345
+ /**
3346
+ * Returns the {@link RuleType} or {@link RuleGroupType}/{@link RuleGroupTypeIC}
3347
+ * at the given path within a query.
3348
+ */
3349
+ const findPath = (path, query) => {
3350
+ let target = query;
3351
+ let level = 0;
3352
+ while (level < path.length && target && isRuleGroup(target)) {
3353
+ const t = target.rules[path[level]];
3354
+ target = typeof t === "string" ? null : t;
3355
+ level++;
3356
+ }
3357
+ return target;
3358
+ };
3359
+ /**
3360
+ * Returns the {@link RuleType} or {@link RuleGroupType}/{@link RuleGroupTypeIC}
3361
+ * with the given `id` within a query.
3362
+ */
3363
+ const findID = (id, query) => {
3364
+ if (query.id === id) return query;
3365
+ for (const rule of query.rules) {
3366
+ if (typeof rule === "string") continue;
3367
+ if (rule.id === id) return rule;
3368
+ else if (isRuleGroup(rule)) {
3369
+ const subRule = findID(id, rule);
3370
+ if (subRule) return subRule;
3371
+ }
3372
+ }
3373
+ return null;
3374
+ };
3375
+ /**
3376
+ * Returns the {@link Path} of the {@link RuleType} or {@link RuleGroupType}/{@link RuleGroupTypeIC}
3377
+ * with the given `id` within a query.
3378
+ */
3379
+ const getPathOfID = (id, query) => {
3380
+ if (query.id === id) return [];
3381
+ const idx = query.rules.findIndex((r) => !(typeof r === "string") && r.id === id);
3382
+ if (idx >= 0) return [idx];
3383
+ for (const [i, r] of Object.entries(query.rules)) if (isRuleGroup(r)) {
3384
+ const subPath = getPathOfID(id, r);
3385
+ if (Array.isArray(subPath)) return [Number.parseInt(i), ...subPath];
3386
+ }
3387
+ return null;
3388
+ };
3389
+ /**
3390
+ * Truncates the last element of an array and returns the result as a new array.
3391
+ */
3392
+ const getParentPath = (path) => path.slice(0, -1);
3393
+ /**
3394
+ * Determines if two paths (each `Path`) are equivalent.
3395
+ */
3396
+ const pathsAreEqual = (path1, path2) => path1.length === path2.length && path1.every((val, idx) => val === path2[idx]);
3397
+ /**
3398
+ * Determines if the first path is an ancestor of the second path. The first path must
3399
+ * be shorter and exactly match the second path up through the length of the first path.
3400
+ */
3401
+ const isAncestor = (maybeAncestor, path) => maybeAncestor.length < path.length && (/* @__PURE__ */ new RegExp(`^${maybeAncestor.join("-")}`)).test(path.join("-"));
3402
+ /**
3403
+ * Finds the deepest/longest path that two paths have in common.
3404
+ */
3405
+ const getCommonAncestorPath = (path1, path2) => {
3406
+ const commonAncestorPath = [];
3407
+ const parentPath1 = getParentPath(path1);
3408
+ const parentPath2 = getParentPath(path2);
3409
+ let i = 0;
3410
+ while (i < parentPath1.length && i < parentPath2.length && parentPath1[i] === parentPath2[i]) {
3411
+ commonAncestorPath.push(parentPath2[i]);
3412
+ i++;
3413
+ }
3414
+ return commonAncestorPath;
3415
+ };
3416
+ /**
3417
+ * Determines if the rule or group at the specified path is either disabled itself
3418
+ * or disabled by an ancestor group.
3419
+ */
3420
+ const pathIsDisabled = (path, query) => {
3421
+ let disabled = !!query.disabled;
3422
+ let target = query;
3423
+ let level = 0;
3424
+ while (level < path.length && !disabled && isRuleGroup(target)) {
3425
+ const t = target.rules[path[level]];
3426
+ if (isPojo(t) && (isRuleGroup(t) || "field" in t && !!t.field)) {
3427
+ disabled = !!t.disabled;
3428
+ target = t;
3429
+ }
3430
+ level++;
3431
+ }
3432
+ return disabled;
3433
+ };
3434
+
3435
+ //#endregion
3436
+ //#region src/utils/generateAccessibleDescription.ts
3437
+ const generateAccessibleDescription = (params) => pathsAreEqual([], params.path) ? `Query builder` : `Rule group at path ${params.path.join("-")}`;
3438
+
3439
+ //#endregion
3440
+ //#region src/utils/generateID.ts
3441
+ const cryptoModule = globalThis.crypto;
3442
+ /**
3443
+ * Default `id` generator. Generates a valid v4 UUID. Uses `crypto.randomUUID()`
3444
+ * when available, otherwise uses an alternate method based on `getRandomValues`.
3445
+ * The returned string is guaranteed to match this regex:
3446
+ * ```
3447
+ * /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i
3448
+ * ```
3449
+ * @returns Valid v4 UUID
3450
+ */
3451
+ // istanbul ignore next
3452
+ let generateID = () => "00-0-4-2-000".replaceAll(/[^-]/g, (s) => ((Math.random() + Math.trunc(s)) * 65536 >> Number.parseInt(s)).toString(16).padStart(4, "0"));
3453
+ // istanbul ignore else
3454
+ if (cryptoModule) {
3455
+ // istanbul ignore else
3456
+ if (typeof cryptoModule.randomUUID === "function") generateID = () => cryptoModule.randomUUID();
3457
+ else if (typeof cryptoModule.getRandomValues === "function") {
3458
+ const position19vals = "89ab";
3459
+ const container = new Uint32Array(32);
3460
+ generateID = () => {
3461
+ cryptoModule.getRandomValues(container);
3462
+ let id = (container[0] % 16).toString(16);
3463
+ for (let i = 1; i < 32; i++) {
3464
+ if (i === 12) id = `${id}4`;
3465
+ else if (i === 16) id = `${id}${position19vals[container[17] % 4]}`;
3466
+ else id = `${id}${(container[i] % 16).toString(16)}`;
3467
+ if (i === 7 || i === 11 || i === 15 || i === 19) id = `${id}-`;
3468
+ }
3469
+ return id;
3470
+ };
3471
+ }
3472
+ }
3473
+
3474
+ //#endregion
3475
+ //#region src/utils/getMatchModesUtil.ts
3476
+ const dummyFD$1 = {
3477
+ name: "name",
3478
+ value: "name",
3479
+ matchModes: null,
3480
+ label: "label"
3481
+ };
3482
+ /**
3483
+ * Utility function to get the match modes array for the given
3484
+ * field. If the field definition does not define a `matchModes`
3485
+ * property, the `getMatchModes` prop is used. Returns
3486
+ * `FullOption<MatchMode>[]` of all match modes by default.
3487
+ */
3488
+ const getMatchModesUtil = (fieldData, getMatchModes) => {
3489
+ var _fd$matchModes, _matchModes$map;
3490
+ const fd = fieldData ? toFullOption(fieldData) : dummyFD$1;
3491
+ let matchModes = (_fd$matchModes = fd.matchModes) !== null && _fd$matchModes !== void 0 ? _fd$matchModes : false;
3492
+ if (!matchModes && getMatchModes) matchModes = getMatchModes(fd.value, { fieldData: fd });
3493
+ if (matchModes === true) return defaultMatchModes;
3494
+ else if (matchModes === false) return [];
3495
+ if (isFlexibleOptionArray(matchModes)) return toFullOptionList(matchModes);
3496
+ return (_matchModes$map = matchModes === null || matchModes === void 0 ? void 0 : matchModes.map((mm) => {
3497
+ var _defaultMatchModes$fi;
3498
+ return (_defaultMatchModes$fi = defaultMatchModes.find((dmm) => dmm.value === lc(mm))) !== null && _defaultMatchModes$fi !== void 0 ? _defaultMatchModes$fi : {
3499
+ name: mm,
3500
+ value: mm,
3501
+ label: mm
3502
+ };
3503
+ })) !== null && _matchModes$map !== void 0 ? _matchModes$map : [];
3504
+ };
3505
+
3506
+ //#endregion
3507
+ //#region src/utils/getValidationClassNames.ts
3508
+ /**
3509
+ * Gets the standard classname for valid or invalid components
3510
+ * based on the given validation result.
3511
+ */
3512
+ const getValidationClassNames = (validationResult) => {
3513
+ const valid = typeof validationResult === "boolean" ? validationResult : typeof validationResult === "object" && validationResult !== null ? validationResult.valid : null;
3514
+ return typeof valid === "boolean" ? valid ? standardClassnames.valid : standardClassnames.invalid : "";
3515
+ };
3516
+
3517
+ //#endregion
3518
+ //#region src/utils/getValueSourcesUtil.ts
3519
+ const defaultValueSourcesArray = [{
3520
+ name: "value",
3521
+ value: "value",
3522
+ label: "value"
3523
+ }];
3524
+ const dummyFD = {
3525
+ name: "name",
3526
+ value: "name",
3527
+ valueSources: null,
3528
+ label: "label"
3529
+ };
3530
+ /**
3531
+ * Utility function to get the value sources array for the given
3532
+ * field and operator. If the field definition does not define a
3533
+ * `valueSources` property, the `getValueSources` prop is used.
3534
+ * Returns `[FullOption<"value">]` by default.
3535
+ */
3536
+ const getValueSourcesUtil = (fieldData, operator, getValueSources) => {
3537
+ var _fd$valueSources;
3538
+ const fd = fieldData ? toFullOption(fieldData) : dummyFD;
3539
+ let valueSourcesNEW = (_fd$valueSources = fd.valueSources) !== null && _fd$valueSources !== void 0 ? _fd$valueSources : false;
3540
+ if (typeof valueSourcesNEW === "function") valueSourcesNEW = valueSourcesNEW(operator);
3541
+ if (!valueSourcesNEW && getValueSources) valueSourcesNEW = getValueSources(fd.value, operator, { fieldData: fd });
3542
+ if (!valueSourcesNEW) return defaultValueSourcesArray;
3543
+ if (isFlexibleOptionArray(valueSourcesNEW)) return toFullOptionList(valueSourcesNEW);
3544
+ return valueSourcesNEW.map((vs) => {
3545
+ var _defaultValueSourcesA;
3546
+ return (_defaultValueSourcesA = defaultValueSourcesArray.find((dmm) => dmm.value === lc(vs))) !== null && _defaultValueSourcesA !== void 0 ? _defaultValueSourcesA : {
3547
+ name: vs,
3548
+ value: vs,
3549
+ label: vs
3550
+ };
3551
+ });
3552
+ };
3553
+
3554
+ //#endregion
3555
+ //#region src/utils/mergeClassnames.ts
3556
+ const joinClassnamesByName = (name, args) => clsx(args.map((c) => clsx(c === null || c === void 0 ? void 0 : c[name])));
3557
+ /**
3558
+ * Merges a list of partial {@link Classnames} definitions into a single definition.
3559
+ */
3560
+ const mergeClassnames = (...args) => ({
3561
+ queryBuilder: joinClassnamesByName("queryBuilder", args),
3562
+ ruleGroup: joinClassnamesByName("ruleGroup", args),
3563
+ header: joinClassnamesByName("header", args),
3564
+ body: joinClassnamesByName("body", args),
3565
+ combinators: joinClassnamesByName("combinators", args),
3566
+ addRule: joinClassnamesByName("addRule", args),
3567
+ addGroup: joinClassnamesByName("addGroup", args),
3568
+ cloneRule: joinClassnamesByName("cloneRule", args),
3569
+ cloneGroup: joinClassnamesByName("cloneGroup", args),
3570
+ removeGroup: joinClassnamesByName("removeGroup", args),
3571
+ rule: joinClassnamesByName("rule", args),
3572
+ fields: joinClassnamesByName("fields", args),
3573
+ operators: joinClassnamesByName("operators", args),
3574
+ value: joinClassnamesByName("value", args),
3575
+ removeRule: joinClassnamesByName("removeRule", args),
3576
+ notToggle: joinClassnamesByName("notToggle", args),
3577
+ shiftActions: joinClassnamesByName("shiftActions", args),
3578
+ dragHandle: joinClassnamesByName("dragHandle", args),
3579
+ lockRule: joinClassnamesByName("lockRule", args),
3580
+ lockGroup: joinClassnamesByName("lockGroup", args),
3581
+ valueSource: joinClassnamesByName("valueSource", args),
3582
+ actionElement: joinClassnamesByName("actionElement", args),
3583
+ valueSelector: joinClassnamesByName("valueSelector", args),
3584
+ betweenRules: joinClassnamesByName("betweenRules", args),
3585
+ valid: joinClassnamesByName("valid", args),
3586
+ invalid: joinClassnamesByName("invalid", args),
3587
+ dndDragging: joinClassnamesByName("dndDragging", args),
3588
+ dndOver: joinClassnamesByName("dndOver", args),
3589
+ dndCopy: joinClassnamesByName("dndCopy", args),
3590
+ dndGroup: joinClassnamesByName("dndGroup", args),
3591
+ dndDropNotAllowed: joinClassnamesByName("dndDropNotAllowed", args),
3592
+ disabled: joinClassnamesByName("disabled", args),
3593
+ valueListItem: joinClassnamesByName("valueListItem", args),
3594
+ matchMode: joinClassnamesByName("matchMode", args),
3595
+ matchThreshold: joinClassnamesByName("matchThreshold", args),
3596
+ branches: joinClassnamesByName("branches", args),
3597
+ hasSubQuery: joinClassnamesByName("hasSubQuery", args)
3598
+ });
3599
+
3600
+ //#endregion
3601
+ //#region src/utils/objectUtils.ts
3602
+ /**
3603
+ * A strongly-typed version of `Object.keys()`.
3604
+ *
3605
+ * [Original source](https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-keys.ts)
3606
+ */
3607
+ const objectKeys = Object.keys;
3608
+ /**
3609
+ * A strongly-typed version of `Object.entries()`.
3610
+ *
3611
+ * [Original source](https://github.com/sindresorhus/ts-extras/blob/44f57392c5f027268330771996c4fdf9260b22d6/source/object-entries.ts)
3612
+ */
3613
+ const objectEntries = Object.entries;
3614
+
3615
+ //#endregion
3616
+ //#region src/utils/prepareQueryObjects.ts
3617
+ /**
3618
+ * Ensures that a rule is valid by adding an `id` property if it does not already exist.
3619
+ */
3620
+ const prepareRule = (rule, { idGenerator = generateID } = {}) => produce(rule, (draft) => {
3621
+ if (!draft.id) draft.id = idGenerator();
3622
+ });
3623
+ /**
3624
+ * Ensures that a rule group is valid by recursively adding an `id` property to the group itself
3625
+ * and all its rules and subgroups where one does not already exist.
3626
+ */
3627
+ const prepareRuleGroup = (queryObject, { idGenerator = generateID } = {}) => produce(queryObject, (draft) => {
3628
+ if (!draft.id) draft.id = idGenerator();
3629
+ draft.rules = draft.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? prepareRuleGroup(r, { idGenerator }) : prepareRule(r, { idGenerator }));
3630
+ });
3631
+ /**
3632
+ * Ensures that a rule or group is valid. See {@link prepareRule} and {@link prepareRuleGroup}.
3633
+ */
3634
+ const prepareRuleOrGroup = (rg, { idGenerator = generateID } = {}) => isRuleGroup(rg) ? prepareRuleGroup(rg, { idGenerator }) : prepareRule(rg, { idGenerator });
3635
+
3636
+ //#endregion
3637
+ //#region src/utils/regenerateIDs.ts
3638
+ /**
3639
+ * Generates a new `id` property for a rule.
3640
+ */
3641
+ const regenerateID = (rule, { idGenerator = generateID } = {}) => structuredClone(_objectSpread2(_objectSpread2({}, rule), {}, { id: idGenerator() }));
3642
+ /**
3643
+ * Recursively generates new `id` properties for a group and all its rules and subgroups.
3644
+ */
3645
+ const regenerateIDs = (ruleOrGroup, { idGenerator = generateID } = {}) => {
3646
+ if (!isPojo(ruleOrGroup)) return ruleOrGroup;
3647
+ if (!isRuleGroup(ruleOrGroup)) return structuredClone(_objectSpread2(_objectSpread2({}, ruleOrGroup), {}, { id: idGenerator() }));
3648
+ if (isRuleGroupType(ruleOrGroup)) {
3649
+ const rules$1 = ruleOrGroup.rules.map((r) => isRuleGroup(r) ? regenerateIDs(r, { idGenerator }) : regenerateID(r, { idGenerator }));
3650
+ return _objectSpread2(_objectSpread2({}, ruleOrGroup), {}, {
3651
+ id: idGenerator(),
3652
+ rules: rules$1
3653
+ });
3654
+ }
3655
+ const rules = ruleOrGroup.rules.map((r) => typeof r === "string" ? r : isRuleGroup(r) ? regenerateIDs(r, { idGenerator }) : regenerateID(r, { idGenerator }));
3656
+ return _objectSpread2(_objectSpread2({}, ruleOrGroup), {}, {
3657
+ id: idGenerator(),
3658
+ rules
3659
+ });
3660
+ };
3661
+
3662
+ //#endregion
3663
+ //#region src/utils/queryTools.ts
3664
+ /**
3665
+ * Adds a rule or group to a query.
3666
+ * @returns The new query with the rule or group added.
3667
+ *
3668
+ * @group Query Tools
3669
+ */
3670
+ const add = (query, ruleOrGroup, parentPathOrID, { combinators = defaultCombinators, combinatorPreceding, idGenerator = generateID } = {}) => produce(query, (draft) => {
3671
+ const parent = Array.isArray(parentPathOrID) ? findPath(parentPathOrID, draft) : findID(parentPathOrID, draft);
3672
+ if (!parent || !isRuleGroup(parent)) return;
3673
+ if (isRuleGroupTypeIC(parent) && parent.rules.length > 0) {
3674
+ const prevCombinator = parent.rules.at(-2);
3675
+ parent.rules.push(combinatorPreceding !== null && combinatorPreceding !== void 0 ? combinatorPreceding : typeof prevCombinator === "string" ? prevCombinator : getFirstOption(combinators));
3676
+ }
3677
+ parent.rules.push(prepareRuleOrGroup(ruleOrGroup, { idGenerator }));
3678
+ });
3679
+ /**
3680
+ * Updates a property of a rule or group within a query.
3681
+ * @returns The new query with the rule or group property updated.
3682
+ *
3683
+ * @group Query Tools
3684
+ */
3685
+ const update = (query, prop, value, pathOrID, { resetOnFieldChange = true, resetOnOperatorChange = false, getRuleDefaultOperator = () => "=", getValueSources = () => ["value"], getRuleDefaultValue = () => "", getMatchModes = () => [] } = {}) => produce(query, (draft) => {
3686
+ const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, draft);
3687
+ if (!path) return;
3688
+ if (prop === "combinator" && !isRuleGroupType(draft)) {
3689
+ const parentRules = findPath(getParentPath(path), draft).rules;
3690
+ if (path.at(-1) % 2 === 1) parentRules[path.at(-1)] = value;
3691
+ return;
3692
+ }
3693
+ const ruleOrGroup = findPath(path, draft);
3694
+ if (!ruleOrGroup) return;
3695
+ const isGroup = isRuleGroup(ruleOrGroup);
3696
+ if (ruleOrGroup[prop] === value) return;
3697
+ if (prop !== "valueSource") ruleOrGroup[prop] = value;
3698
+ if (isGroup) return;
3699
+ let resetValueSource = false;
3700
+ let resetValue = false;
3701
+ if (prop === "field") {
3702
+ const fromFieldMatchModes = getMatchModes(ruleOrGroup.field);
3703
+ const toFieldMatchModes = getMatchModes(value);
3704
+ if (toFieldMatchModes.length === 0) delete ruleOrGroup.match;
3705
+ else {
3706
+ var _ruleOrGroup$match;
3707
+ const nextMatchMode = ((_ruleOrGroup$match = ruleOrGroup.match) === null || _ruleOrGroup$match === void 0 ? void 0 : _ruleOrGroup$match.mode) && getOption(toFieldMatchModes, ruleOrGroup.match.mode) ? null : getFirstOption(toFieldMatchModes);
3708
+ if (nextMatchMode) ruleOrGroup.match = {
3709
+ mode: nextMatchMode,
3710
+ threshold: 1
3711
+ };
3712
+ }
3713
+ if (fromFieldMatchModes.length > 0 || toFieldMatchModes.length > 0) resetOnFieldChange = true;
3714
+ }
3715
+ if (resetOnFieldChange && prop === "field") {
3716
+ ruleOrGroup.operator = getRuleDefaultOperator(value);
3717
+ resetValueSource = true;
3718
+ resetValue = true;
3719
+ }
3720
+ if (resetOnOperatorChange && prop === "operator") {
3721
+ resetValueSource = true;
3722
+ resetValue = true;
3723
+ }
3724
+ const valueSources = getValueSourcesUtil({
3725
+ name: ruleOrGroup.field,
3726
+ value: ruleOrGroup.field,
3727
+ label: ""
3728
+ }, ruleOrGroup.operator, getValueSources);
3729
+ const defaultValueSource = getFirstOption(valueSources);
3730
+ if (resetValueSource && ruleOrGroup.valueSource && defaultValueSource !== ruleOrGroup.valueSource || prop === "valueSource" && value !== ruleOrGroup.valueSource) {
3731
+ resetValue = !!ruleOrGroup.valueSource || !ruleOrGroup.valueSource && value !== defaultValueSource;
3732
+ ruleOrGroup.valueSource = resetValueSource ? defaultValueSource : value;
3733
+ }
3734
+ if (resetValue) ruleOrGroup.value = getRuleDefaultValue(ruleOrGroup);
3735
+ });
3736
+ /**
3737
+ * Removes a rule or group from a query.
3738
+ * @returns The new query with the rule or group removed.
3739
+ *
3740
+ * @group Query Tools
3741
+ */
3742
+ const remove = (query, pathOrID) => {
3743
+ const path = Array.isArray(pathOrID) ? pathOrID : getPathOfID(pathOrID, query);
3744
+ if (!path) return query;
3745
+ if (path.length === 0 || !isRuleGroupType(query) && !findPath(path, query)) return query;
3746
+ return produce(query, (draft) => {
3747
+ const index = path.at(-1);
3748
+ const parent = findPath(getParentPath(path), draft);
3749
+ if (parent && isRuleGroup(parent)) if (!isRuleGroupType(parent) && parent.rules.length > 1) {
3750
+ const idxStartDelete = index === 0 ? 0 : index - 1;
3751
+ parent.rules.splice(idxStartDelete, 2);
3752
+ } else parent.rules.splice(index, 1);
3753
+ });
3754
+ };
3755
+ const getNextPath = (query, currentPath, newPathOrShiftDirection) => {
3756
+ if (Array.isArray(newPathOrShiftDirection)) return newPathOrShiftDirection;
3757
+ const ic = isRuleGroupTypeIC(query);
3758
+ if (newPathOrShiftDirection === "up") if (pathsAreEqual(currentPath, [0])) return currentPath;
3759
+ else if (currentPath.at(-1) === 0) {
3760
+ const parentPath = getParentPath(currentPath);
3761
+ return [...getParentPath(parentPath), Math.max(0, parentPath.at(-1) - (ic ? 1 : 0))];
3762
+ } else {
3763
+ const evaluationPath = [...getParentPath(currentPath), Math.max(0, currentPath.at(-1) - (ic ? 2 : 1))];
3764
+ const entityAtTarget = findPath(evaluationPath, query);
3765
+ if (isRuleGroup(entityAtTarget)) return [...evaluationPath, entityAtTarget.rules.length];
3766
+ else return [...getParentPath(currentPath), Math.max(0, currentPath.at(-1) - (ic ? 3 : 1))];
3767
+ }
3768
+ else if (newPathOrShiftDirection === "down") if (pathsAreEqual([query.rules.length - 1], currentPath)) return currentPath;
3769
+ else if (currentPath.at(-1) === findPath(getParentPath(currentPath), query).rules.length - 1) {
3770
+ const parentPath = getParentPath(currentPath);
3771
+ return [...getParentPath(parentPath), parentPath.at(-1) + 1];
3772
+ } else {
3773
+ const evaluationPath = [...getParentPath(currentPath), currentPath.at(-1) + (ic ? 2 : 1)];
3774
+ const entityToEvaluate = findPath(evaluationPath, query);
3775
+ if (isRuleGroup(entityToEvaluate)) return [...evaluationPath, 0];
3776
+ else return [...getParentPath(currentPath), currentPath.at(-1) + (ic ? 3 : 2)];
3777
+ }
3778
+ return currentPath;
3779
+ };
3780
+ /**
3781
+ * Moves a rule or group from one path to another. In the options parameter, pass
3782
+ * `{ clone: true }` to copy instead of move.
3783
+ * @returns The new query with the rule or group moved or cloned.
3784
+ *
3785
+ * @group Query Tools
3786
+ */
3787
+ const move = (query, oldPathOrID, newPath, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
3788
+ const oldPath = Array.isArray(oldPathOrID) ? oldPathOrID : getPathOfID(oldPathOrID, query);
3789
+ if (!oldPath) return query;
3790
+ const nextPath = getNextPath(query, oldPath, newPath);
3791
+ if (oldPath.length === 0 || pathsAreEqual(oldPath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
3792
+ const ruleOrGroupOriginal = findPath(oldPath, query);
3793
+ if (!ruleOrGroupOriginal) return query;
3794
+ const ruleOrGroup = clone ? regenerateIDs(ruleOrGroupOriginal, { idGenerator }) : ruleOrGroupOriginal;
3795
+ return produce(query, (draft) => {
3796
+ const independentCombinators = isRuleGroupTypeIC(draft);
3797
+ const parentOfRuleToRemove = findPath(getParentPath(oldPath), draft);
3798
+ const ruleToRemoveIndex = oldPath.at(-1);
3799
+ const oldPrevCombinator = independentCombinators && ruleToRemoveIndex > 0 ? parentOfRuleToRemove.rules[ruleToRemoveIndex - 1] : null;
3800
+ const oldNextCombinator = independentCombinators && ruleToRemoveIndex < parentOfRuleToRemove.rules.length - 1 ? parentOfRuleToRemove.rules[ruleToRemoveIndex + 1] : null;
3801
+ if (!clone) {
3802
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
3803
+ const deleteLength = independentCombinators ? 2 : 1;
3804
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
3805
+ }
3806
+ const newNewPath = [...nextPath];
3807
+ const commonAncestorPath = getCommonAncestorPath(oldPath, nextPath);
3808
+ if (!clone && oldPath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > oldPath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
3809
+ const newNewParentPath = getParentPath(newNewPath);
3810
+ const parentToInsertInto = findPath(newNewParentPath, draft);
3811
+ const newIndex = newNewPath.at(-1);
3812
+ /**
3813
+ * This function 1) glosses over the need for type assertions to splice directly
3814
+ * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
3815
+ */
3816
+ const insertRuleOrGroup = (...args) => parentToInsertInto.rules.splice(newIndex, 0, ...args);
3817
+ if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(ruleOrGroup);
3818
+ else if (newIndex === 0) if (ruleToRemoveIndex === 0 && oldNextCombinator) insertRuleOrGroup(ruleOrGroup, oldNextCombinator);
3819
+ else {
3820
+ var _ref, _parentToInsertInto$r;
3821
+ const newNextCombinator = (_ref = (_parentToInsertInto$r = parentToInsertInto.rules[1]) !== null && _parentToInsertInto$r !== void 0 ? _parentToInsertInto$r : oldPrevCombinator) !== null && _ref !== void 0 ? _ref : getFirstOption(combinators);
3822
+ insertRuleOrGroup(ruleOrGroup, newNextCombinator);
3823
+ }
3824
+ else if (oldPrevCombinator) insertRuleOrGroup(oldPrevCombinator, ruleOrGroup);
3825
+ else {
3826
+ var _ref2, _parentToInsertInto$r2;
3827
+ const newPrevCombinator = (_ref2 = (_parentToInsertInto$r2 = parentToInsertInto.rules[newIndex - 2]) !== null && _parentToInsertInto$r2 !== void 0 ? _parentToInsertInto$r2 : oldNextCombinator) !== null && _ref2 !== void 0 ? _ref2 : getFirstOption(combinators);
3828
+ insertRuleOrGroup(newPrevCombinator, ruleOrGroup);
3829
+ }
3830
+ });
3831
+ };
3832
+ /**
3833
+ * Inserts a rule or group into a query.
3834
+ * @returns The new query with the rule or group inserted.
3835
+ *
3836
+ * @group Query Tools
3837
+ */
3838
+ const insert = (query, ruleOrGroup, path, { combinators = defaultCombinators, combinatorPreceding, combinatorSucceeding, idGenerator = generateID, replace = false } = {}) => produce(query, (draft) => {
3839
+ const parentToInsertInto = findPath(getParentPath(path), draft);
3840
+ if (!parentToInsertInto || !isRuleGroup(parentToInsertInto)) return;
3841
+ const rorg = regenerateIDs(ruleOrGroup, { idGenerator });
3842
+ const independentCombinators = isRuleGroupTypeIC(draft);
3843
+ const newIndex = path.at(-1);
3844
+ /**
3845
+ * This function 1) glosses over the need for type assertions to splice directly
3846
+ * into `parentToInsertInto.rules`, and 2) shortens the actual insertion code.
3847
+ */
3848
+ const insertRuleOrGroup = (idx, ...args) => parentToInsertInto.rules.splice(idx, replace ? args.length : 0, ...args);
3849
+ if (parentToInsertInto.rules.length === 0 || !independentCombinators) insertRuleOrGroup(newIndex, rorg);
3850
+ else if (replace && independentCombinators) insertRuleOrGroup(newIndex + newIndex % 2, rorg);
3851
+ else if (newIndex === 0) {
3852
+ var _rorg$path;
3853
+ if (((_rorg$path = rorg.path) === null || _rorg$path === void 0 ? void 0 : _rorg$path.at(-1)) === 0 && combinatorSucceeding) insertRuleOrGroup(newIndex, rorg, combinatorSucceeding);
3854
+ else {
3855
+ var _ref3, _parentToInsertInto$r3;
3856
+ const newNextCombinator = (_ref3 = (_parentToInsertInto$r3 = parentToInsertInto.rules[1]) !== null && _parentToInsertInto$r3 !== void 0 ? _parentToInsertInto$r3 : combinatorPreceding) !== null && _ref3 !== void 0 ? _ref3 : getFirstOption(combinators);
3857
+ insertRuleOrGroup(newIndex, rorg, newNextCombinator);
3858
+ }
3859
+ } else {
3860
+ const normalizedNewIndex = newIndex % 2 === 0 ? newIndex - 1 : newIndex;
3861
+ if (combinatorPreceding) insertRuleOrGroup(normalizedNewIndex, combinatorPreceding, rorg);
3862
+ else {
3863
+ var _ref4, _parentToInsertInto$r4;
3864
+ const newPrevCombinator = (_ref4 = (_parentToInsertInto$r4 = parentToInsertInto.rules[normalizedNewIndex - 2]) !== null && _parentToInsertInto$r4 !== void 0 ? _parentToInsertInto$r4 : combinatorSucceeding) !== null && _ref4 !== void 0 ? _ref4 : getFirstOption(combinators);
3865
+ insertRuleOrGroup(normalizedNewIndex, newPrevCombinator, rorg);
3866
+ }
3867
+ }
3868
+ });
3869
+ /**
3870
+ * Creates a new group at a target path with its `rules` array containing the current
3871
+ * objects at the target path and the source path. In the options parameter, pass
3872
+ * `{ clone: true }` to copy the source rule/group instead of move.
3873
+ *
3874
+ * @returns The new query with the rules or groups grouped.
3875
+ *
3876
+ * @group Query Tools
3877
+ */
3878
+ const group = (query, sourcePathOrID, targetPathOrID, { clone = false, combinators = defaultCombinators, idGenerator = generateID } = {}) => {
3879
+ const sourcePath = Array.isArray(sourcePathOrID) ? sourcePathOrID : getPathOfID(sourcePathOrID, query);
3880
+ const targetPath = Array.isArray(targetPathOrID) ? targetPathOrID : getPathOfID(targetPathOrID, query);
3881
+ if (!sourcePath || !targetPath) return query;
3882
+ const nextPath = getNextPath(query, sourcePath, targetPath);
3883
+ if (sourcePath.length === 0 || pathsAreEqual(sourcePath, nextPath) || !findPath(getParentPath(nextPath), query)) return query;
3884
+ const sourceRuleOrGroupOriginal = findPath(sourcePath, query);
3885
+ const targetRuleOrGroup = findPath(targetPath, query);
3886
+ if (!sourceRuleOrGroupOriginal || !targetRuleOrGroup) return query;
3887
+ const sourceRuleOrGroup = clone ? regenerateIDs(sourceRuleOrGroupOriginal, { idGenerator }) : sourceRuleOrGroupOriginal;
3888
+ return produce(query, (draft) => {
3889
+ const independentCombinators = isRuleGroupTypeIC(draft);
3890
+ const parentOfRuleToRemove = findPath(getParentPath(sourcePath), draft);
3891
+ const ruleToRemoveIndex = sourcePath.at(-1);
3892
+ if (!clone) {
3893
+ const idxStartDelete = independentCombinators ? Math.max(0, ruleToRemoveIndex - 1) : ruleToRemoveIndex;
3894
+ const deleteLength = independentCombinators ? 2 : 1;
3895
+ parentOfRuleToRemove.rules.splice(idxStartDelete, deleteLength);
3896
+ }
3897
+ const newNewPath = [...nextPath];
3898
+ const commonAncestorPath = getCommonAncestorPath(sourcePath, nextPath);
3899
+ if (!clone && sourcePath.length === commonAncestorPath.length + 1 && nextPath[commonAncestorPath.length] > sourcePath[commonAncestorPath.length]) newNewPath[commonAncestorPath.length] -= independentCombinators ? 2 : 1;
3900
+ const newNewParentPath = getParentPath(newNewPath);
3901
+ const parentOfTargetPath = findPath(newNewParentPath, draft);
3902
+ const targetPathIndex = newNewPath.at(-1);
3903
+ parentOfTargetPath.rules.splice(targetPathIndex, 1, prepareRuleOrGroup(independentCombinators ? { rules: [
3904
+ targetRuleOrGroup,
3905
+ getFirstOption(combinators),
3906
+ sourceRuleOrGroup
3907
+ ] } : {
3908
+ combinator: getFirstOption(combinators),
3909
+ rules: [targetRuleOrGroup, sourceRuleOrGroup]
3910
+ }, { idGenerator }));
3911
+ });
3912
+ };
3913
+
3914
+ //#endregion
3915
+ export { LogType, TestID, add, bigIntJsonParseReviver, bigIntJsonStringifyReplacer, celCombinatorMap, clsx, convertFromIC, convertQuery, convertToIC, defaultCELValueProcessor, defaultCombinatorLabelMap, defaultCombinators, defaultCombinatorsExtended, defaultControlClassnames, defaultExportOperatorMap, defaultJoinChar, defaultMatchModes, defaultMongoDBValueProcessor, defaultNLTranslations, defaultOperatorLabelMap, defaultOperatorNegationMap, defaultOperatorProcessorNL, defaultOperatorProcessorSQL, defaultOperators, defaultPlaceholderFieldGroupLabel, defaultPlaceholderFieldLabel, defaultPlaceholderFieldName, defaultPlaceholderLabel, defaultPlaceholderName, defaultPlaceholderOperatorGroupLabel, defaultPlaceholderOperatorLabel, defaultPlaceholderOperatorName, defaultPlaceholderValueGroupLabel, defaultPlaceholderValueLabel, defaultPlaceholderValueName, defaultRuleGroupProcessorCEL, defaultRuleGroupProcessorDrizzle, defaultRuleGroupProcessorElasticSearch, defaultRuleGroupProcessorJSONata, defaultRuleGroupProcessorJsonLogic, defaultRuleGroupProcessorLDAP, defaultRuleGroupProcessorMongoDB, defaultRuleGroupProcessorMongoDBQuery, defaultRuleGroupProcessorNL, defaultRuleGroupProcessorParameterized, defaultRuleGroupProcessorPrisma, defaultRuleGroupProcessorSQL, defaultRuleGroupProcessorSequelize, defaultRuleGroupProcessorSpEL, defaultRuleProcessorCEL, defaultRuleProcessorDrizzle, defaultRuleProcessorElasticSearch, defaultRuleProcessorJSONata, defaultRuleProcessorJsonLogic, defaultRuleProcessorLDAP, defaultRuleProcessorMongoDB, defaultRuleProcessorMongoDBQuery, defaultRuleProcessorNL, defaultRuleProcessorParameterized, defaultRuleProcessorPrisma, defaultRuleProcessorSQL, defaultRuleProcessorSequelize, defaultRuleProcessorSpEL, defaultSpELValueProcessor, defaultValidator, defaultValueProcessor, defaultValueProcessorByRule, defaultValueProcessorCELByRule, defaultValueProcessorMongoDBByRule, defaultValueProcessorNL, defaultValueProcessorSpELByRule, filterFieldsByComparator, findID, findPath, formatQuery, formatQueryOptionPresets, generateAccessibleDescription, generateID, getCommonAncestorPath, getFirstOption, getMatchModesUtil, getNLTranslataion, getOption, getParentPath, getParseNumberMethod, getPathOfID, getQuoteFieldNamesWithArray, getQuotedFieldName, getValidationClassNames, getValueSourcesUtil, group, groupInvalidReasons, insert, isAncestor, isFlexibleOptionArray, isFlexibleOptionGroupArray, isFullOptionArray, isFullOptionGroupArray, isOptionGroupArray, isPojo, isRuleGroup, isRuleGroupType, isRuleGroupTypeIC, isRuleOrGroupValid, isValidValue, isValidationResult, isValueProcessorLegacy, joinWith, jsonLogicAdditionalOperators, lc, mapSQLOperator, mergeClassnames, mongoDbFallback, mongoOperators, move, normalizeConstituentWordOrder, nullFreeArray, nullOrUndefinedOrEmpty, numericRegex, numerifyValues, objectEntries, objectKeys, parseNumber, pathIsDisabled, pathsAreEqual, prepareRule, prepareRuleGroup, prepareRuleOrGroup, prismaFallback, prismaOperators, processMatchMode, regenerateID, regenerateIDs, remove, rootPath, shouldRenderAsNumber, splitBy, sqlDialectPresets, standardClassnames, toArray, toFlatOptionArray, toFullOption, toFullOptionList, toFullOptionMap, transformQuery, trimIfString, uniqByIdentifier, uniqByName, uniqOptGroups, uniqOptList, update };
3916
+ //# sourceMappingURL=react-querybuilder_core.legacy-esm.js.map