@react-querybuilder/core 8.22.5 → 8.23.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 (120) hide show
  1. package/derivations/package.json +4 -0
  2. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +2078 -1665
  3. package/dist/cjs/react-querybuilder_core.cjs.development.js +1293 -422
  4. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  5. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +2078 -1665
  6. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  7. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  8. package/dist/{convertQuery-Cw76XFIn.js → convertQuery-BLT0GIhM.js} +17 -8
  9. package/dist/{convertQuery-Cw76XFIn.js.map → convertQuery-BLT0GIhM.js.map} +1 -1
  10. package/dist/{convertQuery-D_4J7E-Z.mjs → convertQuery-DaXv3h7S.mjs} +6 -3
  11. package/dist/{convertQuery-D_4J7E-Z.mjs.map → convertQuery-DaXv3h7S.mjs.map} +1 -1
  12. package/dist/derivations.d.mts +2902 -0
  13. package/dist/derivations.d.ts +2902 -0
  14. package/dist/derivations.js +2845 -0
  15. package/dist/derivations.js.map +1 -0
  16. package/dist/derivations.mjs +2678 -0
  17. package/dist/derivations.mjs.map +1 -0
  18. package/dist/formatQuery.d.mts +2 -895
  19. package/dist/formatQuery.d.ts +2 -895
  20. package/dist/formatQuery.js +120 -140
  21. package/dist/formatQuery.js.map +1 -1
  22. package/dist/formatQuery.mjs +8 -28
  23. package/dist/formatQuery.mjs.map +1 -1
  24. package/dist/{import-DVWI7Fdh.d.mts → import-BdKPtLzo.d.mts} +2 -2
  25. package/dist/{import-6ExjhifL.d.ts → import-BfZTwhp2.d.ts} +2 -2
  26. package/dist/{index-CX9mehdL.d.mts → index-DOIE2pwx.d.mts} +274 -3
  27. package/dist/{index-CX9mehdL.d.ts → index-DOIE2pwx.d.ts} +274 -3
  28. package/dist/index-OF2Q1gTp.d.mts +895 -0
  29. package/dist/index-XueTy_XQ.d.ts +895 -0
  30. package/dist/isRuleOrGroupValid-CIMZNkt4.mjs +27 -0
  31. package/dist/isRuleOrGroupValid-CIMZNkt4.mjs.map +1 -0
  32. package/dist/isRuleOrGroupValid-CtUf4_4x.js +38 -0
  33. package/dist/isRuleOrGroupValid-CtUf4_4x.js.map +1 -0
  34. package/dist/{isRuleGroup-CqLThsbu.mjs → objectUtils-DDZ-KhV5.mjs} +25 -2
  35. package/dist/objectUtils-DDZ-KhV5.mjs.map +1 -0
  36. package/dist/{isRuleGroup-0JNiQgLg.js → objectUtils-DfnEmDSV.js} +48 -1
  37. package/dist/objectUtils-DfnEmDSV.js.map +1 -0
  38. package/dist/parseCEL.d.mts +2 -2
  39. package/dist/parseCEL.d.ts +2 -2
  40. package/dist/parseCEL.js +19 -16
  41. package/dist/parseCEL.js.map +1 -1
  42. package/dist/parseCEL.mjs +12 -9
  43. package/dist/parseCEL.mjs.map +1 -1
  44. package/dist/parseCypher.d.mts +1 -1
  45. package/dist/parseCypher.d.ts +1 -1
  46. package/dist/parseGremlin.d.mts +1 -1
  47. package/dist/parseGremlin.d.ts +1 -1
  48. package/dist/parseJSONata.d.mts +2 -2
  49. package/dist/parseJSONata.d.ts +2 -2
  50. package/dist/parseJSONata.js +17 -14
  51. package/dist/parseJSONata.js.map +1 -1
  52. package/dist/parseJSONata.mjs +11 -8
  53. package/dist/parseJSONata.mjs.map +1 -1
  54. package/dist/parseJsonLogic.d.mts +2 -2
  55. package/dist/parseJsonLogic.d.ts +2 -2
  56. package/dist/parseJsonLogic.js +38 -38
  57. package/dist/parseJsonLogic.js.map +1 -1
  58. package/dist/parseJsonLogic.mjs +5 -5
  59. package/dist/parseMongoDB.d.mts +2 -2
  60. package/dist/parseMongoDB.d.ts +2 -2
  61. package/dist/parseMongoDB.js +50 -47
  62. package/dist/parseMongoDB.js.map +1 -1
  63. package/dist/parseMongoDB.mjs +35 -32
  64. package/dist/parseMongoDB.mjs.map +1 -1
  65. package/dist/parseSPARQL.d.mts +1 -1
  66. package/dist/parseSPARQL.d.ts +1 -1
  67. package/dist/parseSQL.d.mts +2 -2
  68. package/dist/parseSQL.d.ts +2 -2
  69. package/dist/parseSQL.js +27 -23
  70. package/dist/parseSQL.js.map +1 -1
  71. package/dist/parseSQL.mjs +21 -17
  72. package/dist/parseSQL.mjs.map +1 -1
  73. package/dist/parseSpEL.d.mts +2 -2
  74. package/dist/parseSpEL.d.ts +2 -2
  75. package/dist/parseSpEL.js +16 -13
  76. package/dist/parseSpEL.js.map +1 -1
  77. package/dist/parseSpEL.mjs +12 -9
  78. package/dist/parseSpEL.mjs.map +1 -1
  79. package/dist/parserUtils-BKPstAaO.mjs +30 -0
  80. package/dist/parserUtils-BKPstAaO.mjs.map +1 -0
  81. package/dist/parserUtils-DbBXyAht.js +41 -0
  82. package/dist/parserUtils-DbBXyAht.js.map +1 -0
  83. package/dist/{prepareQueryObjects-BnGL91Tt.js → prepareQueryObjects-Dj9cTl9D.js} +90 -63
  84. package/dist/prepareQueryObjects-Dj9cTl9D.js.map +1 -0
  85. package/dist/{prepareQueryObjects-ChINDIap.mjs → prepareQueryObjects-Dmyf3Wi_.mjs} +56 -59
  86. package/dist/prepareQueryObjects-Dmyf3Wi_.mjs.map +1 -0
  87. package/dist/react-querybuilder_core.d.mts +2078 -1665
  88. package/dist/react-querybuilder_core.legacy-esm.d.ts +2078 -1665
  89. package/dist/react-querybuilder_core.legacy-esm.js +1445 -635
  90. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  91. package/dist/react-querybuilder_core.mjs +1288 -424
  92. package/dist/react-querybuilder_core.mjs.map +1 -1
  93. package/dist/react-querybuilder_core.production.d.mts +2078 -1665
  94. package/dist/react-querybuilder_core.production.mjs +1 -1
  95. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  96. package/dist/transformQuery-B7d9AWUf.d.mts +116 -0
  97. package/dist/transformQuery-BXDiUBGB.d.ts +116 -0
  98. package/dist/transformQuery.d.mts +2 -116
  99. package/dist/transformQuery.d.ts +2 -116
  100. package/dist/transformQuery.js +3 -4
  101. package/dist/transformQuery.js.map +1 -1
  102. package/dist/transformQuery.mjs +1 -2
  103. package/dist/transformQuery.mjs.map +1 -1
  104. package/dist/utils-CP5Jqy1P.mjs +1294 -0
  105. package/dist/utils-CP5Jqy1P.mjs.map +1 -0
  106. package/dist/utils-e-7KHkjV.js +1779 -0
  107. package/dist/utils-e-7KHkjV.js.map +1 -0
  108. package/package.json +33 -22
  109. package/dist/isRuleGroup-0JNiQgLg.js.map +0 -1
  110. package/dist/isRuleGroup-CqLThsbu.mjs.map +0 -1
  111. package/dist/objectUtils-Cr02aGxb.js +0 -27
  112. package/dist/objectUtils-Cr02aGxb.js.map +0 -1
  113. package/dist/objectUtils-DBlmJgBf.mjs +0 -16
  114. package/dist/objectUtils-DBlmJgBf.mjs.map +0 -1
  115. package/dist/prepareQueryObjects-BnGL91Tt.js.map +0 -1
  116. package/dist/prepareQueryObjects-ChINDIap.mjs.map +0 -1
  117. package/dist/utils-4k-j5FBa.mjs +0 -537
  118. package/dist/utils-4k-j5FBa.mjs.map +0 -1
  119. package/dist/utils-C79dxwZb.js +0 -752
  120. package/dist/utils-C79dxwZb.js.map +0 -1
@@ -0,0 +1,1294 @@
1
+ import { c as isPojo, d as numericRegex$1, i as isRuleGroup, l as lc, r as objectKeys } from "./objectUtils-DDZ-KhV5.mjs";
2
+ import { numericQuantity } from "numeric-quantity";
3
+ //#region src/defaults.ts
4
+ /**
5
+ * @group Defaults
6
+ */
7
+ const defaultPlaceholderName = "~";
8
+ /**
9
+ * @group Defaults
10
+ */
11
+ const defaultPlaceholderLabel = "------";
12
+ /**
13
+ * Default `name` for placeholder option in the `fields` array.
14
+ *
15
+ * @group Defaults
16
+ */
17
+ const defaultPlaceholderFieldName = "~";
18
+ /**
19
+ * Default `label` for placeholder option in the `fields` array.
20
+ *
21
+ * @group Defaults
22
+ */
23
+ const defaultPlaceholderFieldLabel = defaultPlaceholderLabel;
24
+ /**
25
+ * Default `label` for placeholder option group in the `fields` array.
26
+ *
27
+ * @group Defaults
28
+ */
29
+ const defaultPlaceholderFieldGroupLabel = defaultPlaceholderLabel;
30
+ /**
31
+ * Default `name` for placeholder option in the `operators` array.
32
+ *
33
+ * @group Defaults
34
+ */
35
+ const defaultPlaceholderOperatorName = "~";
36
+ /**
37
+ * Default `label` for placeholder option in the `operators` array.
38
+ *
39
+ * @group Defaults
40
+ */
41
+ const defaultPlaceholderOperatorLabel = defaultPlaceholderLabel;
42
+ /**
43
+ * Default `label` for placeholder option group in the `operators` array.
44
+ *
45
+ * @group Defaults
46
+ */
47
+ const defaultPlaceholderOperatorGroupLabel = defaultPlaceholderLabel;
48
+ /**
49
+ * Default `name` for placeholder option in the `values` array.
50
+ *
51
+ * @group Defaults
52
+ */
53
+ const defaultPlaceholderValueName = "~";
54
+ /**
55
+ * Default `label` for placeholder option in the `values` array.
56
+ *
57
+ * @group Defaults
58
+ */
59
+ const defaultPlaceholderValueLabel = defaultPlaceholderLabel;
60
+ /**
61
+ * Default `label` for placeholder option group in the `values` array.
62
+ *
63
+ * @group Defaults
64
+ */
65
+ const defaultPlaceholderValueGroupLabel = defaultPlaceholderLabel;
66
+ /**
67
+ * Default configuration of translatable strings.
68
+ *
69
+ * @group Defaults
70
+ */
71
+ const defaultTranslations = {
72
+ fields: {
73
+ title: "Field",
74
+ placeholderName: "~",
75
+ placeholderLabel: defaultPlaceholderFieldLabel,
76
+ placeholderGroupLabel: defaultPlaceholderFieldGroupLabel
77
+ },
78
+ operators: {
79
+ title: "Operator",
80
+ placeholderName: "~",
81
+ placeholderLabel: defaultPlaceholderOperatorLabel,
82
+ placeholderGroupLabel: defaultPlaceholderOperatorGroupLabel
83
+ },
84
+ values: {
85
+ title: "Values",
86
+ placeholderName: "~",
87
+ placeholderLabel: defaultPlaceholderValueLabel,
88
+ placeholderGroupLabel: defaultPlaceholderValueGroupLabel
89
+ },
90
+ matchMode: { title: "Match mode" },
91
+ matchThreshold: {
92
+ title: "Match threshold",
93
+ placeholderName: "#"
94
+ },
95
+ value: { title: "Value" },
96
+ removeRule: {
97
+ label: "⨯",
98
+ title: "Remove rule"
99
+ },
100
+ removeGroup: {
101
+ label: "⨯",
102
+ title: "Remove group"
103
+ },
104
+ addRule: {
105
+ label: "+ Rule",
106
+ title: "Add rule"
107
+ },
108
+ addGroup: {
109
+ label: "+ Group",
110
+ title: "Add group"
111
+ },
112
+ combinators: { title: "Combinator" },
113
+ notToggle: {
114
+ label: "Not",
115
+ title: "Invert this group"
116
+ },
117
+ cloneRule: {
118
+ label: "⧉",
119
+ title: "Clone rule"
120
+ },
121
+ cloneRuleGroup: {
122
+ label: "⧉",
123
+ title: "Clone group"
124
+ },
125
+ shiftActionUp: {
126
+ label: "˄",
127
+ title: "Shift up"
128
+ },
129
+ shiftActionDown: {
130
+ label: "˅",
131
+ title: "Shift down"
132
+ },
133
+ undo: {
134
+ label: "↶",
135
+ title: "Undo"
136
+ },
137
+ redo: {
138
+ label: "↷",
139
+ title: "Redo"
140
+ },
141
+ dragHandle: {
142
+ label: "⁞⁞",
143
+ title: "Drag handle"
144
+ },
145
+ lockRule: {
146
+ label: "🔓",
147
+ title: "Lock rule"
148
+ },
149
+ lockGroup: {
150
+ label: "🔓",
151
+ title: "Lock group"
152
+ },
153
+ lockRuleDisabled: {
154
+ label: "🔒",
155
+ title: "Unlock rule"
156
+ },
157
+ lockGroupDisabled: {
158
+ label: "🔒",
159
+ title: "Unlock group"
160
+ },
161
+ muteRule: {
162
+ label: "🔊",
163
+ title: "Mute rule"
164
+ },
165
+ muteGroup: {
166
+ label: "🔊",
167
+ title: "Mute group"
168
+ },
169
+ unmuteRule: {
170
+ label: "🔇",
171
+ title: "Unmute rule"
172
+ },
173
+ unmuteGroup: {
174
+ label: "🔇",
175
+ title: "Unmute group"
176
+ },
177
+ valueSourceSelector: { title: "Value source" }
178
+ };
179
+ /**
180
+ * Default character used to `.join` and `.split` arrays.
181
+ *
182
+ * @group Defaults
183
+ */
184
+ const defaultJoinChar = ",";
185
+ const defaultOperatorLabelMap = {
186
+ "=": "=",
187
+ "!=": "!=",
188
+ "<": "<",
189
+ ">": ">",
190
+ "<=": "<=",
191
+ ">=": ">=",
192
+ contains: "contains",
193
+ beginsWith: "begins with",
194
+ endsWith: "ends with",
195
+ doesNotContain: "does not contain",
196
+ doesNotBeginWith: "does not begin with",
197
+ doesNotEndWith: "does not end with",
198
+ null: "is null",
199
+ notNull: "is not null",
200
+ in: "in",
201
+ notIn: "not in",
202
+ between: "between",
203
+ notBetween: "not between"
204
+ };
205
+ const defaultCombinatorLabelMap = {
206
+ and: "AND",
207
+ or: "OR",
208
+ xor: "XOR"
209
+ };
210
+ /**
211
+ * Default operator list.
212
+ *
213
+ * @group Defaults
214
+ */
215
+ const defaultOperators = [
216
+ {
217
+ name: "=",
218
+ value: "=",
219
+ label: "="
220
+ },
221
+ {
222
+ name: "!=",
223
+ value: "!=",
224
+ label: "!="
225
+ },
226
+ {
227
+ name: "<",
228
+ value: "<",
229
+ label: "<"
230
+ },
231
+ {
232
+ name: ">",
233
+ value: ">",
234
+ label: ">"
235
+ },
236
+ {
237
+ name: "<=",
238
+ value: "<=",
239
+ label: "<="
240
+ },
241
+ {
242
+ name: ">=",
243
+ value: ">=",
244
+ label: ">="
245
+ },
246
+ {
247
+ name: "contains",
248
+ value: "contains",
249
+ label: "contains"
250
+ },
251
+ {
252
+ name: "beginsWith",
253
+ value: "beginsWith",
254
+ label: "begins with"
255
+ },
256
+ {
257
+ name: "endsWith",
258
+ value: "endsWith",
259
+ label: "ends with"
260
+ },
261
+ {
262
+ name: "doesNotContain",
263
+ value: "doesNotContain",
264
+ label: "does not contain"
265
+ },
266
+ {
267
+ name: "doesNotBeginWith",
268
+ value: "doesNotBeginWith",
269
+ label: "does not begin with"
270
+ },
271
+ {
272
+ name: "doesNotEndWith",
273
+ value: "doesNotEndWith",
274
+ label: "does not end with"
275
+ },
276
+ {
277
+ name: "null",
278
+ value: "null",
279
+ label: "is null"
280
+ },
281
+ {
282
+ name: "notNull",
283
+ value: "notNull",
284
+ label: "is not null"
285
+ },
286
+ {
287
+ name: "in",
288
+ value: "in",
289
+ label: "in"
290
+ },
291
+ {
292
+ name: "notIn",
293
+ value: "notIn",
294
+ label: "not in"
295
+ },
296
+ {
297
+ name: "between",
298
+ value: "between",
299
+ label: "between"
300
+ },
301
+ {
302
+ name: "notBetween",
303
+ value: "notBetween",
304
+ label: "not between"
305
+ }
306
+ ];
307
+ /**
308
+ * Map of default operators to their respective opposite/negating operators.
309
+ *
310
+ * @group Defaults
311
+ */
312
+ const defaultOperatorNegationMap = {
313
+ "=": "!=",
314
+ "!=": "=",
315
+ "<": ">=",
316
+ "<=": ">",
317
+ ">": "<=",
318
+ ">=": "<",
319
+ beginsWith: "doesNotBeginWith",
320
+ doesNotBeginWith: "beginsWith",
321
+ endsWith: "doesNotEndWith",
322
+ doesNotEndWith: "endsWith",
323
+ contains: "doesNotContain",
324
+ doesNotContain: "contains",
325
+ between: "notBetween",
326
+ notBetween: "between",
327
+ in: "notIn",
328
+ notIn: "in",
329
+ notNull: "null",
330
+ null: "notNull"
331
+ };
332
+ /**
333
+ * Relational/comparison operators (`=`, `!=`, `<`, `>`, `<=`, `>=`).
334
+ *
335
+ * @group Defaults
336
+ */
337
+ const relationalOperators = /* @__PURE__ */ new Set([
338
+ "=",
339
+ "!=",
340
+ "<",
341
+ ">",
342
+ "<=",
343
+ ">="
344
+ ]);
345
+ /**
346
+ * Substring/text-matching operators (`contains`, `beginsWith`, `endsWith`, and negations).
347
+ *
348
+ * @group Defaults
349
+ */
350
+ const substringOperators = /* @__PURE__ */ new Set([
351
+ "contains",
352
+ "beginsWith",
353
+ "endsWith",
354
+ "doesNotContain",
355
+ "doesNotBeginWith",
356
+ "doesNotEndWith"
357
+ ]);
358
+ /**
359
+ * Null-check operators (`null`, `notNull`).
360
+ *
361
+ * @group Defaults
362
+ */
363
+ const nullOperators = /* @__PURE__ */ new Set(["null", "notNull"]);
364
+ /**
365
+ * List-membership operators (`in`, `notIn`).
366
+ *
367
+ * @group Defaults
368
+ */
369
+ const inOperators = /* @__PURE__ */ new Set(["in", "notIn"]);
370
+ /**
371
+ * Range operators (`between`, `notBetween`).
372
+ *
373
+ * @group Defaults
374
+ */
375
+ const betweenOperators = /* @__PURE__ */ new Set(["between", "notBetween"]);
376
+ /**
377
+ * Default combinator list.
378
+ *
379
+ * @group Defaults
380
+ */
381
+ const defaultCombinators = [{
382
+ name: "and",
383
+ value: "and",
384
+ label: "AND"
385
+ }, {
386
+ name: "or",
387
+ value: "or",
388
+ label: "OR"
389
+ }];
390
+ /**
391
+ * Default combinator list, with `XOR` added.
392
+ *
393
+ * @group Defaults
394
+ */
395
+ const defaultCombinatorsExtended = [...defaultCombinators, {
396
+ name: "xor",
397
+ value: "xor",
398
+ label: "XOR"
399
+ }];
400
+ /**
401
+ * Default match modes.
402
+ *
403
+ * @group Defaults
404
+ */
405
+ const defaultMatchModes = [
406
+ {
407
+ name: "all",
408
+ value: "all",
409
+ label: "all"
410
+ },
411
+ {
412
+ name: "some",
413
+ value: "some",
414
+ label: "some"
415
+ },
416
+ {
417
+ name: "none",
418
+ value: "none",
419
+ label: "none"
420
+ },
421
+ {
422
+ name: "atLeast",
423
+ value: "atLeast",
424
+ label: "at least"
425
+ },
426
+ {
427
+ name: "atMost",
428
+ value: "atMost",
429
+ label: "at most"
430
+ },
431
+ {
432
+ name: "exactly",
433
+ value: "exactly",
434
+ label: "exactly"
435
+ }
436
+ ];
437
+ /**
438
+ * Standard classnames applied to each component.
439
+ *
440
+ * @group Defaults
441
+ */
442
+ const standardClassnames = {
443
+ queryBuilder: "queryBuilder",
444
+ ruleGroup: "ruleGroup",
445
+ header: "ruleGroup-header",
446
+ body: "ruleGroup-body",
447
+ combinators: "ruleGroup-combinators",
448
+ addRule: "ruleGroup-addRule",
449
+ addGroup: "ruleGroup-addGroup",
450
+ cloneRule: "rule-cloneRule",
451
+ cloneGroup: "ruleGroup-cloneGroup",
452
+ removeGroup: "ruleGroup-remove",
453
+ notToggle: "ruleGroup-notToggle",
454
+ rule: "rule",
455
+ fields: "rule-fields",
456
+ matchMode: "rule-matchMode",
457
+ matchThreshold: "rule-matchThreshold",
458
+ operators: "rule-operators",
459
+ value: "rule-value",
460
+ removeRule: "rule-remove",
461
+ betweenRules: "betweenRules",
462
+ valid: "queryBuilder-valid",
463
+ invalid: "queryBuilder-invalid",
464
+ shiftActions: "shiftActions",
465
+ undoRedoActions: "undoRedoActions",
466
+ undoAction: "undoRedoActions-undo",
467
+ redoAction: "undoRedoActions-redo",
468
+ dndDragging: "dndDragging",
469
+ dndOver: "dndOver",
470
+ dndCopy: "dndCopy",
471
+ dndGroup: "dndGroup",
472
+ dndDropNotAllowed: "dndDropNotAllowed",
473
+ dndPreviewPosition: "dndPreviewPosition",
474
+ dndHidden: "dndHidden",
475
+ dragHandle: "queryBuilder-dragHandle",
476
+ disabled: "queryBuilder-disabled",
477
+ muted: "queryBuilder-muted",
478
+ lockRule: "rule-lock",
479
+ lockGroup: "ruleGroup-lock",
480
+ muteRule: "rule-mute",
481
+ muteGroup: "ruleGroup-mute",
482
+ valueSource: "rule-valueSource",
483
+ valueListItem: "rule-value-list-item",
484
+ branches: "queryBuilder-branches",
485
+ justified: "queryBuilder-justified",
486
+ responsive: "queryBuilder-responsive",
487
+ hasSubQuery: "rule-hasSubQuery",
488
+ loading: "queryBuilder-loading",
489
+ valueDateTimeRelative: "rule-value-dateTimeRelative"
490
+ };
491
+ /**
492
+ * Default classnames for each component.
493
+ *
494
+ * @group Defaults
495
+ */
496
+ const defaultControlClassnames = {
497
+ queryBuilder: "",
498
+ ruleGroup: "",
499
+ header: "",
500
+ body: "",
501
+ combinators: "",
502
+ addRule: "",
503
+ addGroup: "",
504
+ cloneRule: "",
505
+ cloneGroup: "",
506
+ removeGroup: "",
507
+ notToggle: "",
508
+ rule: "",
509
+ fields: "",
510
+ matchMode: "",
511
+ matchThreshold: "",
512
+ operators: "",
513
+ value: "",
514
+ removeRule: "",
515
+ shiftActions: "",
516
+ undoRedoActions: "",
517
+ undoAction: "",
518
+ redoAction: "",
519
+ dragHandle: "",
520
+ lockRule: "",
521
+ lockGroup: "",
522
+ muteRule: "",
523
+ muteGroup: "",
524
+ muted: "",
525
+ valueSource: "",
526
+ actionElement: "",
527
+ valueSelector: "",
528
+ betweenRules: "",
529
+ valid: "",
530
+ invalid: "",
531
+ dndDragging: "",
532
+ dndOver: "",
533
+ dndGroup: "",
534
+ dndCopy: "",
535
+ dndDropNotAllowed: "",
536
+ dndPreviewPosition: "",
537
+ dndHidden: "",
538
+ disabled: "",
539
+ valueListItem: "",
540
+ branches: "",
541
+ hasSubQuery: "",
542
+ loading: "",
543
+ valueDateTimeRelative: ""
544
+ };
545
+ /**
546
+ * Default reason codes for a group being invalid.
547
+ *
548
+ * @group Defaults
549
+ */
550
+ const groupInvalidReasons = {
551
+ empty: "empty",
552
+ invalidCombinator: "invalid combinator",
553
+ invalidIndependentCombinators: "invalid independent combinators"
554
+ };
555
+ /**
556
+ * Component identifiers for testing.
557
+ *
558
+ * @group Defaults
559
+ */
560
+ const TestID = {
561
+ rule: "rule",
562
+ ruleGroup: "rule-group",
563
+ inlineCombinator: "inline-combinator",
564
+ addGroup: "add-group",
565
+ removeGroup: "remove-group",
566
+ cloneGroup: "clone-group",
567
+ cloneRule: "clone-rule",
568
+ addRule: "add-rule",
569
+ removeRule: "remove-rule",
570
+ combinators: "combinators",
571
+ fields: "fields",
572
+ operators: "operators",
573
+ valueEditor: "value-editor",
574
+ notToggle: "not-toggle",
575
+ shiftActions: "shift-actions",
576
+ undoRedoActions: "undo-redo-actions",
577
+ undoAction: "undo-action",
578
+ redoAction: "redo-action",
579
+ dragHandle: "drag-handle",
580
+ lockRule: "lock-rule",
581
+ lockGroup: "lock-group",
582
+ muteRule: "mute-rule",
583
+ muteGroup: "mute-group",
584
+ valueSourceSelector: "value-source-selector",
585
+ matchModeEditor: "match-mode-editor"
586
+ };
587
+ const LogType = {
588
+ parentPathDisabled: "action aborted: parent path disabled",
589
+ pathDisabled: "action aborted: path is disabled",
590
+ queryUpdate: "query updated",
591
+ onAddRuleFalse: "onAddRule callback returned false",
592
+ onAddGroupFalse: "onAddGroup callback returned false",
593
+ onGroupRuleFalse: "onGroupRule callback returned false",
594
+ onGroupGroupFalse: "onGroupGroup callback returned false",
595
+ onMoveRuleFalse: "onMoveRule callback returned false",
596
+ onMoveGroupFalse: "onMoveGroup callback returned false",
597
+ onRemoveFalse: "onRemove callback returned false",
598
+ add: "rule or group added",
599
+ remove: "rule or group removed",
600
+ update: "rule or group updated",
601
+ move: "rule or group moved",
602
+ group: "rule or group grouped with another"
603
+ };
604
+ /**
605
+ * The {@link Path} of the root group.
606
+ *
607
+ * @group Defaults
608
+ */
609
+ const rootPath = [];
610
+ /**
611
+ * Default values for all `boolean`
612
+ * {@link react-querybuilder!QueryBuilder QueryBuilder} options.
613
+ *
614
+ * @group Defaults
615
+ */
616
+ const queryBuilderFlagDefaults = {
617
+ addRuleToNewGroups: false,
618
+ autoSelectField: true,
619
+ autoSelectOperator: true,
620
+ autoSelectValue: false,
621
+ debugMode: false,
622
+ enableDragAndDrop: false,
623
+ enableMountQueryChange: true,
624
+ listsAsArrays: false,
625
+ preserveQueryStateOnUnmount: false,
626
+ resetOnFieldChange: true,
627
+ resetOnOperatorChange: false,
628
+ showCloneButtons: false,
629
+ showCombinatorsBetweenRules: false,
630
+ showLockButtons: false,
631
+ showMuteButtons: false,
632
+ showNotToggle: false,
633
+ showShiftActions: false,
634
+ showUndoRedo: false,
635
+ suppressStandardClassnames: false
636
+ };
637
+ /**
638
+ * Default maximum number of undo steps retained by query history.
639
+ *
640
+ * @group Defaults
641
+ */
642
+ const defaultMaxHistory = 50;
643
+ /**
644
+ * Default time window (in milliseconds) within which consecutive changes to the same
645
+ * property of the same rule are coalesced into a single undo step.
646
+ *
647
+ * @group Defaults
648
+ */
649
+ const defaultCoalesceMs = 500;
650
+ //#endregion
651
+ //#region src/utils/arrayUtils.ts
652
+ /**
653
+ * Splits a string by a given character (see {@link defaultJoinChar}). Escaped characters
654
+ * (characters preceded by a backslash) will not apply to the split, and the backslash will
655
+ * be removed in the array element. Inverse of {@link joinWith}.
656
+ *
657
+ * @example
658
+ * splitBy('this\\,\\,that,,the other,,,\\,')
659
+ * // or
660
+ * splitBy('this\\,\\,that,,the other,,,\\,', ',')
661
+ * // would return
662
+ * ['this,,that', '', 'the other', '', '', ',']
663
+ */
664
+ const splitBy = (str, splitChar = ",") => typeof str === "string" ? str.split(`\\${splitChar}`).map((c) => c.split(splitChar)).reduce((prev, curr, idx) => {
665
+ if (idx === 0) return curr;
666
+ return [
667
+ ...prev.slice(0, -1),
668
+ `${prev.at(-1)}${splitChar}${curr[0]}`,
669
+ ...curr.slice(1)
670
+ ];
671
+ }, []) : [];
672
+ /**
673
+ * Joins an array of strings using the given character (see {@link defaultJoinChar}). When
674
+ * the given character appears in an array element, a backslash will be added just before it
675
+ * to distinguish it from the join character. Effectively the inverse of {@link splitBy}.
676
+ *
677
+ * TIP: The join character can actually be a string of any length. Only the first character
678
+ * will be searched for in the array elements and preceded by a backslash.
679
+ *
680
+ * @example
681
+ * joinWith(['this,,that', '', 'the other', '', '', ','], ', ')
682
+ * // would return
683
+ * 'this\\,\\,that, , the other, , , \\,'
684
+ */
685
+ const joinWith = (strArr, joinChar = ",") => strArr.map((str) => `${str ?? ""}`.replaceAll(joinChar[0], `\\${joinChar[0]}`)).join(joinChar);
686
+ /**
687
+ * Trims the value if it is a string. Otherwise returns the value as is.
688
+ */
689
+ const trimIfString = (val) => typeof val === "string" ? val.trim() : val;
690
+ /**
691
+ * Splits a string by comma then trims each element. Arrays are returned as is except
692
+ * any string elements are trimmed.
693
+ */
694
+ const toArray = (a, { retainEmptyStrings } = {}) => Array.isArray(a) ? a.map(trimIfString) : typeof a === "string" ? splitBy(a, ",").filter(retainEmptyStrings ? () => true : (s) => !/^\s*$/.test(s)).map((s) => s.trim()) : typeof a === "number" ? [a] : [];
695
+ /**
696
+ * Determines if an array is free of `null`/`undefined`.
697
+ */
698
+ const nullFreeArray = (arr) => arr.every((el) => el === false || (el ?? false) !== false);
699
+ //#endregion
700
+ //#region src/utils/optGroupUtils.ts
701
+ const isOptionWithName = (opt) => isPojo(opt) && "name" in opt && typeof opt.name === "string";
702
+ const isOptionWithValue = (opt) => isPojo(opt) && "value" in opt && typeof opt.value === "string";
703
+ /**
704
+ * Converts an {@link Option} or {@link ValueOption} (i.e., {@link BaseOption})
705
+ * into a {@link FullOption}. Full options are left unchanged.
706
+ *
707
+ * @group Option Lists
708
+ */
709
+ function toFullOption(opt, baseProperties, labelMap) {
710
+ if (typeof opt === "string") return {
711
+ ...baseProperties,
712
+ name: opt,
713
+ value: opt,
714
+ label: labelMap?.[opt] ?? opt
715
+ };
716
+ const idObj = {};
717
+ let needsUpdating = !!baseProperties;
718
+ if (isOptionWithName(opt) && !isOptionWithValue(opt)) {
719
+ idObj.value = opt.name;
720
+ needsUpdating = true;
721
+ } else if (!isOptionWithName(opt) && isOptionWithValue(opt)) {
722
+ idObj.name = opt.value;
723
+ needsUpdating = true;
724
+ }
725
+ if (needsUpdating) return Object.assign({}, baseProperties, opt, idObj);
726
+ return opt;
727
+ }
728
+ /**
729
+ * Converts an {@link OptionList} or {@link FlexibleOptionList} into a {@link FullOptionList}.
730
+ * Lists of full options are left unchanged.
731
+ *
732
+ * @group Option Lists
733
+ */
734
+ function toFullOptionList(optList, baseProperties, labelMap) {
735
+ if (!Array.isArray(optList)) return [];
736
+ const list = optList;
737
+ if (isFlexibleOptionGroupArray(list)) return list.map((optGroup) => ({
738
+ ...optGroup,
739
+ options: optGroup.options.map((opt) => toFullOption(opt, baseProperties, labelMap))
740
+ }));
741
+ return list.map((opt) => toFullOption(opt, baseProperties, labelMap));
742
+ }
743
+ /**
744
+ * Converts a {@link FlexibleOptionList} into a {@link FullOptionList}.
745
+ * Lists of full options are left unchanged.
746
+ *
747
+ * @group Option Lists
748
+ */
749
+ function toFullOptionMap(optMap, baseProperties) {
750
+ return Object.fromEntries(Object.entries(optMap).map(([k, v]) => [k, toFullOption(v, baseProperties)]));
751
+ }
752
+ /**
753
+ * @deprecated Renamed to {@link uniqByIdentifier}.
754
+ *
755
+ * @group Option Lists
756
+ */
757
+ const uniqByName = (originalArray) => uniqByIdentifier(originalArray);
758
+ /**
759
+ * Generates a new array of objects with duplicates removed based
760
+ * on the identifying property (`value` or `name`)
761
+ *
762
+ * @group Option Lists
763
+ */
764
+ const uniqByIdentifier = (originalArray) => {
765
+ const names = /* @__PURE__ */ new Set();
766
+ const newArray = [];
767
+ for (const el of originalArray) if (!names.has(el.value ?? el.name)) {
768
+ names.add(el.value ?? el.name);
769
+ newArray.push(el);
770
+ }
771
+ return originalArray.length === newArray.length ? originalArray : newArray;
772
+ };
773
+ /**
774
+ * Determines if an {@link OptionList} is an {@link OptionGroup} array.
775
+ *
776
+ * @group Option Lists
777
+ */
778
+ const isOptionGroupArray = (arr) => Array.isArray(arr) && arr.length > 0 && isPojo(arr[0]) && "options" in arr[0] && Array.isArray(arr[0].options);
779
+ /**
780
+ * Determines if an array is a flat array of {@link FlexibleOption}.
781
+ *
782
+ * @group Option Lists
783
+ */
784
+ const isFlexibleOptionArray = (arr) => {
785
+ let isFOA = false;
786
+ if (Array.isArray(arr)) for (const o of arr) if (isOptionWithName(o) || isOptionWithValue(o)) isFOA = true;
787
+ else return false;
788
+ return isFOA;
789
+ };
790
+ /**
791
+ * Determines if an array is a flat array of {@link FullOption}.
792
+ *
793
+ * @group Option Lists
794
+ */
795
+ const isFullOptionArray = (arr) => {
796
+ let isFOA = false;
797
+ if (Array.isArray(arr)) for (const o of arr) if (isOptionWithName(o) && isOptionWithValue(o)) isFOA = true;
798
+ else return false;
799
+ return isFOA;
800
+ };
801
+ /**
802
+ * Determines if a {@link FlexibleOptionList} is a {@link FlexibleOptionGroup} array.
803
+ *
804
+ * @group Option Lists
805
+ */
806
+ const isFlexibleOptionGroupArray = (arr, { allowEmpty = false } = {}) => {
807
+ let isFOGA = false;
808
+ 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;
809
+ else return false;
810
+ return isFOGA;
811
+ };
812
+ /**
813
+ * Determines if a {@link FlexibleOptionList} is a {@link OptionGroup} array of {@link FullOption}.
814
+ *
815
+ * @group Option Lists
816
+ */
817
+ const isFullOptionGroupArray = (arr, { allowEmpty = false } = {}) => {
818
+ let isFOGA = false;
819
+ 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;
820
+ else return false;
821
+ return isFOGA;
822
+ };
823
+ function getOption(arr, name) {
824
+ return (isFlexibleOptionGroupArray(arr, { allowEmpty: true }) ? arr.flatMap((og) => og.options) : arr).find((op) => op.value === name || op.name === name);
825
+ }
826
+ function getFirstOption(arr) {
827
+ if (!Array.isArray(arr) || arr.length === 0) return null;
828
+ else if (isFlexibleOptionGroupArray(arr, { allowEmpty: true })) {
829
+ for (const og of arr) if (og.options.length > 0) return og.options[0].value ?? og.options[0].name;
830
+ // v8 ignore next
831
+ return null;
832
+ }
833
+ return arr[0].value ?? arr[0].name;
834
+ }
835
+ /**
836
+ * Flattens {@link FlexibleOptionGroup} arrays into {@link BaseOption} arrays.
837
+ * If the array is already flat, it is returned as is.
838
+ *
839
+ * @group Option Lists
840
+ */
841
+ const toFlatOptionArray = (arr) => uniqByIdentifier(isOptionGroupArray(arr) ? arr.flatMap((og) => og.options) : arr);
842
+ /**
843
+ * Generates a new {@link OptionGroup} array with duplicates
844
+ * removed based on the identifying property (`value` or `name`).
845
+ *
846
+ * @group Option Lists
847
+ */
848
+ const uniqOptGroups = (originalArray) => {
849
+ const labels = /* @__PURE__ */ new Set();
850
+ const names = /* @__PURE__ */ new Set();
851
+ const newArray = [];
852
+ for (const el of originalArray) if (!labels.has(el.label)) {
853
+ labels.add(el.label);
854
+ const optionsForThisGroup = [];
855
+ for (const opt of el.options) if (!names.has(opt.value ?? opt.name)) {
856
+ names.add(opt.value ?? opt.name);
857
+ optionsForThisGroup.push(toFullOption(opt));
858
+ }
859
+ newArray.push({
860
+ ...el,
861
+ options: optionsForThisGroup
862
+ });
863
+ }
864
+ return newArray;
865
+ };
866
+ /**
867
+ * Generates a new {@link Option} or {@link OptionGroup} array with duplicates
868
+ * removed based on the identifier property (`value` or `name`).
869
+ *
870
+ * @group Option Lists
871
+ */
872
+ const uniqOptList = (originalArray) => {
873
+ if (isFlexibleOptionGroupArray(originalArray)) return uniqOptGroups(originalArray);
874
+ return uniqByIdentifier(originalArray.map((o) => toFullOption(o)));
875
+ };
876
+ /**
877
+ * Normalizes any accepted option list shape—array, option groups, or a record—into a
878
+ * `FullOptionList`, applying `baseOption` properties and (when `autoSelectOption` is `false`)
879
+ * a leading placeholder option. Also returns the flattened lookup map and the option that
880
+ * should be selected by default.
881
+ *
882
+ * Note: `labelMap` overrides only apply to array/option group input (where string options are
883
+ * expanded); record input derives labels from the record values themselves.
884
+ *
885
+ * This is the same normalization `<QueryBuilder />` applies to `fields`, `operators`,
886
+ * `combinators`, and value lists, so a non-React implementation resolves options identically.
887
+ *
888
+ * @group Option Lists
889
+ */
890
+ const prepareOptionList = (props) => {
891
+ // v8 ignore next
892
+ const { optionList: optionListPropOriginal, baseOption = {}, labelMap = {}, placeholder: { placeholderName = "~", placeholderLabel = defaultPlaceholderLabel, placeholderGroupLabel = defaultPlaceholderLabel } = {}, autoSelectOption = true } = props;
893
+ const defaultOption = {
894
+ id: placeholderName,
895
+ name: placeholderName,
896
+ value: placeholderName,
897
+ label: placeholderLabel
898
+ };
899
+ const optionsProp = optionListPropOriginal ?? [defaultOption];
900
+ let optionList;
901
+ const opts = Array.isArray(optionsProp) ? toFullOptionList(optionsProp, baseOption, labelMap) : objectKeys(toFullOptionMap(optionsProp, baseOption)).map((opt) => ({
902
+ ...optionsProp[opt],
903
+ name: opt,
904
+ value: opt
905
+ })).sort((a, b) => a.label.localeCompare(b.label));
906
+ if (isFlexibleOptionGroupArray(opts)) optionList = autoSelectOption ? uniqOptGroups(opts) : uniqOptGroups([{
907
+ label: placeholderGroupLabel,
908
+ options: [defaultOption]
909
+ }, ...opts]);
910
+ else optionList = autoSelectOption ? uniqByIdentifier(opts) : uniqByIdentifier([defaultOption, ...opts]);
911
+ let optionsMap = {};
912
+ if (!Array.isArray(optionsProp)) {
913
+ const op = toFullOptionMap(optionsProp, baseOption);
914
+ optionsMap = autoSelectOption ? op : {
915
+ ...op,
916
+ [placeholderName]: defaultOption
917
+ };
918
+ } else if (isFlexibleOptionGroupArray(optionList)) for (const og of optionList) for (const opt of og.options) optionsMap[opt.value ??
919
+ /* v8 ignore start -- @preserve */ opt.name] = toFullOption(opt, baseOption);
920
+ else for (const opt of optionList) optionsMap[opt.value ??
921
+ /* v8 ignore start -- @preserve */ opt.name] = toFullOption(opt, baseOption);
922
+ return {
923
+ defaultOption,
924
+ optionList,
925
+ optionsMap
926
+ };
927
+ };
928
+ //#endregion
929
+ //#region src/utils/parseNumber.ts
930
+ /**
931
+ * Converts a string to a number. Uses native `parseFloat` if `parseNumbers` is "native",
932
+ * otherwise uses [`numeric-quantity`](https://jakeboone02.github.io/numeric-quantity/).
933
+ * If that returns `NaN`, the string is returned unchanged. Numeric values are returned
934
+ * as-is regardless of the `parseNumbers` option.
935
+ */
936
+ const parseNumber = (val, { parseNumbers, bigIntOnOverflow } = {}) => {
937
+ if (!parseNumbers || typeof val === "bigint" || typeof val === "number") return val;
938
+ if (parseNumbers === "native") return Number.parseFloat(val);
939
+ const valAsNum = numericQuantity(val, {
940
+ allowTrailingInvalid: parseNumbers === "enhanced",
941
+ bigIntOnOverflow,
942
+ romanNumerals: false,
943
+ round: false
944
+ });
945
+ return typeof valAsNum === "bigint" || !Number.isNaN(valAsNum) ? valAsNum : val;
946
+ };
947
+ //#endregion
948
+ //#region src/utils/getParseNumberMethod.ts
949
+ const getParseNumberMethod = ({ parseNumbers, inputType }) => {
950
+ if (typeof parseNumbers === "string") {
951
+ const [method, level] = parseNumbers.split("-");
952
+ if (level === "limited") return inputType === "number" ? method : false;
953
+ return method;
954
+ }
955
+ return parseNumbers ? "strict" : false;
956
+ };
957
+ //#endregion
958
+ //#region src/utils/formatQuery/utils.ts
959
+ /**
960
+ * Maps a {@link DefaultOperatorName} to a SQL operator.
961
+ *
962
+ * @group Export
963
+ */
964
+ const mapSQLOperator = (rqbOperator) => {
965
+ switch (lc(rqbOperator)) {
966
+ case "null": return "is null";
967
+ case "notnull": return "is not null";
968
+ case "notin": return "not in";
969
+ case "notbetween": return "not between";
970
+ case "contains":
971
+ case "beginswith":
972
+ case "endswith": return "like";
973
+ case "doesnotcontain":
974
+ case "doesnotbeginwith":
975
+ case "doesnotendwith": return "not like";
976
+ default: return rqbOperator;
977
+ }
978
+ };
979
+ /**
980
+ * Returns a preset-aware SQL string-concatenation function. Emits `CONCAT(a, b, ...)` when
981
+ * `concatOperator` is `"CONCAT"` (case-insensitive), otherwise joins with the infix operator
982
+ * (e.g. `a || b`, `a + b`).
983
+ *
984
+ * @group Export
985
+ */
986
+ const getSQLConcat = (concatOperator = "||") => (...values) => concatOperator.toUpperCase() === "CONCAT" ? `CONCAT(${values.join(", ")})` : values.join(` ${concatOperator} `);
987
+ /**
988
+ * Returns the `[prefix, suffix]` `LIKE` wildcards for a string-match operator (e.g. `contains`
989
+ * → `['%', '%']`, `beginsWith` → `['', '%']`, `endsWith` → `['%', '']`). Unknown operators
990
+ * yield `['', '']`.
991
+ *
992
+ * @group Export
993
+ */
994
+ const getLikeWildcards = (operatorLC) => {
995
+ switch (operatorLC) {
996
+ case "contains":
997
+ case "doesnotcontain": return ["%", "%"];
998
+ case "beginswith":
999
+ case "doesnotbeginwith": return ["", "%"];
1000
+ case "endswith":
1001
+ case "doesnotendwith": return ["%", ""];
1002
+ default: return ["", ""];
1003
+ }
1004
+ };
1005
+ /**
1006
+ * Wraps an already-serialized SQL fragment (a quoted field name or an expression) with the
1007
+ * `LIKE` wildcards for the given (lowercase) string-match operator, concatenating the literal
1008
+ * `%` markers via the preset-aware {@link getSQLConcat}. Returns the fragment untouched for
1009
+ * operators without wildcards.
1010
+ *
1011
+ * @group Export
1012
+ */
1013
+ const wrapLikeFragment = (fragment, operatorLC, { concatOperator = "||", quoteValuesWith, wrapValueWith = ["", ""] } = {}) => {
1014
+ const [pre, post] = getLikeWildcards(operatorLC);
1015
+ const quoteChar = quoteValuesWith || `'`;
1016
+ const quote = (p) => `${wrapValueWith[0]}${quoteChar}${p}${quoteChar}${wrapValueWith[1]}`;
1017
+ const parts = [
1018
+ pre && quote(pre),
1019
+ fragment,
1020
+ post && quote(post)
1021
+ ].filter(Boolean);
1022
+ return parts.length > 1 ? getSQLConcat(concatOperator)(...parts) : fragment;
1023
+ };
1024
+ /**
1025
+ * Maps a (lowercase) {@link DefaultOperatorName} to a MongoDB operator.
1026
+ *
1027
+ * @group Export
1028
+ */
1029
+ const mongoOperators = {
1030
+ "=": "$eq",
1031
+ "!=": "$ne",
1032
+ "<": "$lt",
1033
+ "<=": "$lte",
1034
+ ">": "$gt",
1035
+ ">=": "$gte",
1036
+ in: "$in",
1037
+ notin: "$nin",
1038
+ notIn: "$nin"
1039
+ };
1040
+ /**
1041
+ * Maps a (lowercase) {@link DefaultOperatorName} to a Prisma ORM operator.
1042
+ *
1043
+ * @group Export
1044
+ */
1045
+ const prismaOperators = {
1046
+ "=": "equals",
1047
+ "!=": "not",
1048
+ "<": "lt",
1049
+ "<=": "lte",
1050
+ ">": "gt",
1051
+ ">=": "gte",
1052
+ in: "in",
1053
+ notin: "notIn"
1054
+ };
1055
+ /**
1056
+ * Maps a {@link DefaultCombinatorName} to a CEL combinator.
1057
+ *
1058
+ * @group Export
1059
+ */
1060
+ const celCombinatorMap = {
1061
+ and: "&&",
1062
+ or: "||"
1063
+ };
1064
+ /**
1065
+ * Register these operators with `jsonLogic` before applying the result
1066
+ * of `formatQuery(query, 'jsonlogic')`.
1067
+ *
1068
+ * @example
1069
+ * ```
1070
+ * for (const [op, func] of Object.entries(jsonLogicAdditionalOperators)) {
1071
+ * jsonLogic.add_operation(op, func);
1072
+ * }
1073
+ * jsonLogic.apply({ "startsWith": [{ "var": "firstName" }, "Stev"] }, data);
1074
+ * ```
1075
+ *
1076
+ * @group Export
1077
+ */
1078
+ const jsonLogicAdditionalOperators = {
1079
+ startsWith: (a, b) => typeof a === "string" && a.startsWith(b),
1080
+ endsWith: (a, b) => typeof a === "string" && a.endsWith(b)
1081
+ };
1082
+ /**
1083
+ * Returns a new query object with all `string`-type `value` properties converted
1084
+ * to `number` where appropriate.
1085
+ *
1086
+ * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`.
1087
+ *
1088
+ * @group Export
1089
+ */
1090
+ const numerifyValues = (rg, options) => ({
1091
+ ...rg,
1092
+ rules: rg.rules.map((r) => {
1093
+ if (typeof r === "string") return r;
1094
+ if (isRuleGroup(r)) return numerifyValues(r, options);
1095
+ const fieldData = getOption(options.fields, r.field);
1096
+ const parseNumbers = getParseNumberMethod({
1097
+ parseNumbers: options.parseNumbers,
1098
+ inputType: fieldData?.inputType
1099
+ });
1100
+ if (Array.isArray(r.value)) return {
1101
+ ...r,
1102
+ value: r.value.map((v) => parseNumber(v, { parseNumbers }))
1103
+ };
1104
+ const valAsArray = toArray(r.value, { retainEmptyStrings: true }).map((v) => parseNumber(v, { parseNumbers }));
1105
+ if (valAsArray.every((v) => typeof v === "number")) {
1106
+ // v8 ignore else
1107
+ if (valAsArray.length > 1) return {
1108
+ ...r,
1109
+ value: valAsArray
1110
+ };
1111
+ else if (valAsArray.length === 1) return {
1112
+ ...r,
1113
+ value: valAsArray[0]
1114
+ };
1115
+ }
1116
+ return r;
1117
+ })
1118
+ });
1119
+ /**
1120
+ * Determines whether a value is _anything_ except an empty `string` or `NaN`.
1121
+ *
1122
+ * @group Export
1123
+ */
1124
+ const isValidValue = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && !Number.isNaN(value) || typeof value !== "string" && typeof value !== "number";
1125
+ /**
1126
+ * Determines whether {@link formatQuery} should render the given value as a number.
1127
+ * As long as `parseNumbers` is `true`, `number` and `bigint` values will return `true` and
1128
+ * `string` values will return `true` if they test positive against {@link numericRegex}.
1129
+ *
1130
+ * @group Export
1131
+ */
1132
+ const shouldRenderAsNumber = (value, parseNumbers) => !!parseNumbers && (typeof value === "number" || typeof value === "bigint" || typeof value === "string" && numericRegex$1.test(value));
1133
+ /**
1134
+ * Used by {@link formatQuery} to determine whether the given value processor is a
1135
+ * "legacy" value processor by counting the number of arguments. Legacy value
1136
+ * processors take 3 arguments (not counting any arguments with default values), while
1137
+ * rule-based value processors take no more than 2 arguments.
1138
+ *
1139
+ * @group Export
1140
+ */
1141
+ const isValueProcessorLegacy = (valueProcessor) => valueProcessor.length >= 3;
1142
+ /**
1143
+ * Converts the `quoteFieldNamesWith` option into an array of two strings.
1144
+ * If the option is a string, the array elements are both that string.
1145
+ *
1146
+ * @default
1147
+ * ['', '']
1148
+ *
1149
+ * @group Export
1150
+ */
1151
+ const getQuoteFieldNamesWithArray = (quoteFieldNamesWith = ["", ""]) => Array.isArray(quoteFieldNamesWith) ? quoteFieldNamesWith : typeof quoteFieldNamesWith === "string" ? [quoteFieldNamesWith, quoteFieldNamesWith] : quoteFieldNamesWith ?? ["", ""];
1152
+ /**
1153
+ * Given a field name and relevant {@link ValueProcessorOptions}, returns the field name
1154
+ * wrapped in the configured quote character(s).
1155
+ *
1156
+ * @group Export
1157
+ */
1158
+ const getQuotedFieldName = (fieldName, { quoteFieldNamesWith, fieldIdentifierSeparator }) => {
1159
+ const [qPre, qPost] = getQuoteFieldNamesWithArray(quoteFieldNamesWith);
1160
+ return typeof fieldIdentifierSeparator === "string" && fieldIdentifierSeparator.length > 0 ? joinWith(splitBy(fieldName, fieldIdentifierSeparator).map((part) => `${qPre}${part}${qPost}`), fieldIdentifierSeparator) : `${qPre}${fieldName}${qPost}`;
1161
+ };
1162
+ const defaultWordOrder = [
1163
+ "S",
1164
+ "V",
1165
+ "O"
1166
+ ];
1167
+ /**
1168
+ * Given a [Constituent word order](https://en.wikipedia.org/wiki/Word_order#Constituent_word_orders)
1169
+ * like "svo" or "sov", returns a permutation of `["S", "V", "O"]` based on the first occurrence of
1170
+ * each letter in the input string (case insensitive). This widens the valid input from abbreviations
1171
+ * like "svo" to more expressive strings like "subject-verb-object" or "sub ver obj". Any missing
1172
+ * letters are appended in the default order "SVO" (e.g., "object" would yield `["O", "S", "V"]`).
1173
+ *
1174
+ * @group Export
1175
+ */
1176
+ const normalizeConstituentWordOrder = (input) => {
1177
+ const result = [];
1178
+ const letterSet = new Set(defaultWordOrder);
1179
+ for (const char of input.toUpperCase()) if (letterSet.has(char)) {
1180
+ result.push(char);
1181
+ letterSet.delete(char);
1182
+ if (letterSet.size === 0) break;
1183
+ }
1184
+ for (const letter of defaultWordOrder) if (letterSet.has(letter)) result.push(letter);
1185
+ return result;
1186
+ };
1187
+ /**
1188
+ * Prefixes a named-parameter value with the given `paramPrefix` unless the value already
1189
+ * begins with it. Used by {@link formatQuery} to render rules whose `valueSource` is
1190
+ * `"parameter"` (e.g. `"p1"` with prefix `":"` → `":p1"`; `":p1"` → `":p1"`).
1191
+ *
1192
+ * @group Export
1193
+ */
1194
+ const withParamPrefix = (value, paramPrefix = ":") => {
1195
+ const v = `${value ?? ""}`;
1196
+ return paramPrefix && v.startsWith(paramPrefix) ? v : `${paramPrefix}${v}`;
1197
+ };
1198
+ /**
1199
+ * Strips a leading `paramPrefix` from a named-parameter value if present. Inverse of
1200
+ * {@link withParamPrefix}; used to normalize parameter names for validation/lookup.
1201
+ *
1202
+ * @group Export
1203
+ */
1204
+ const stripParamPrefix = (value, paramPrefix = ":") => {
1205
+ const v = `${value ?? ""}`;
1206
+ return paramPrefix && v.startsWith(paramPrefix) ? v.slice(paramPrefix.length) : v;
1207
+ };
1208
+ /**
1209
+ * Default translations used by {@link formatQuery} for "natural_language" format.
1210
+ *
1211
+ * @group Export
1212
+ */
1213
+ const defaultNLTranslations = {
1214
+ groupPrefix: "",
1215
+ groupPrefix_not_xor: "either zero or more than one of",
1216
+ groupPrefix_xor: "exactly one of",
1217
+ groupSuffix: "is true",
1218
+ groupSuffix_not: "is not true"
1219
+ };
1220
+ /**
1221
+ * Note: This function assumes `conditions.length > 0`
1222
+ */
1223
+ const translationMatchFilter = (key, keyToTest, conditions) => keyToTest.startsWith(key) && conditions.every((c) => keyToTest.includes(`_${c}`) && keyToTest.match(/_/g)?.length === conditions.length);
1224
+ /**
1225
+ * Used by {@link formatQuery} to get a translation based on certain conditions
1226
+ * for the "natural_language" format.
1227
+ *
1228
+ * @group Export
1229
+ */
1230
+ const getNLTranslataion = (key, translations, conditions = []) => conditions.length === 0 ? translations[key] ?? defaultNLTranslations[key] ??
1231
+ /* v8 ignore start -- @preserve */ "" : Object.entries(translations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))?.[1] ?? Object.entries(defaultNLTranslations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))?.[1] ?? defaultNLTranslations[key] ??
1232
+ /* v8 ignore next -- @preserve */ "";
1233
+ /**
1234
+ * Transforms
1235
+ * - `match: { mode: "atLeast", threshold: 1 }` to `match: { mode: "some" }`
1236
+ * - `match: { mode: "atMost", threshold: 0 }` to `match: { mode: "none" }`.
1237
+ *
1238
+ * Returns:
1239
+ * - Processed `{ mode, threshold }` object for valid subqueries
1240
+ * - `null` if match mode is not applicable for the rule
1241
+ * - `false` if match mode is valid, but either
1242
+ * 1. `threshold` is required and invalid, or
1243
+ * 2. `value` is not a valid rule group.
1244
+ */
1245
+ const processMatchMode = (rule) => {
1246
+ const { mode, threshold } = rule.match ?? {};
1247
+ if (!mode) return null;
1248
+ if (!isRuleGroup(rule.value)) return false;
1249
+ const matchModeLC = lc(mode);
1250
+ const matchModeCoerced = matchModeLC === "atleast" && threshold === 1 ? "some" : matchModeLC === "atmost" && threshold === 0 ? "none" : matchModeLC;
1251
+ if ((matchModeCoerced === "atleast" || matchModeCoerced === "atmost" || matchModeCoerced === "exactly") && (typeof threshold !== "number" || threshold < 0)) return false;
1252
+ return {
1253
+ mode: matchModeCoerced,
1254
+ threshold
1255
+ };
1256
+ };
1257
+ /**
1258
+ * Base alias assigned to the element binding of a subquery generated for a rule's
1259
+ * {@link MatchMode `match` mode} (e.g. `unnest(field) as elem_alias`).
1260
+ */
1261
+ const subqueryElementAliasBase = "elem_alias";
1262
+ /**
1263
+ * Returns the element alias for a subquery at the given nesting depth. Depth 0 (the common,
1264
+ * non-nested case) uses {@link subqueryElementAliasBase} unchanged; deeper levels are suffixed
1265
+ * with the depth, so a subquery nested within a subquery cannot shadow its parent's binding.
1266
+ *
1267
+ * Deterministic by depth rather than randomized, so output remains stable and snapshot-friendly.
1268
+ *
1269
+ * @group Export
1270
+ */
1271
+ const getSubqueryElementAlias = (subqueryDepth = 0) => subqueryDepth > 0 ? `${subqueryElementAliasBase}_${subqueryDepth}` : subqueryElementAliasBase;
1272
+ /**
1273
+ * "Replacer" method for JSON.stringify's second argument. Converts `bigint` values to
1274
+ * objects with a `$bigint` property having a value of a string representation of
1275
+ * the actual `bigint`-type value.
1276
+ *
1277
+ * Inverse of {@link bigIntJsonParseReviver}.
1278
+ *
1279
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
1280
+ */
1281
+ const bigIntJsonStringifyReplacer = (_key, value) => typeof value === "bigint" ? { $bigint: value.toString() } : value;
1282
+ /**
1283
+ * "Reviver" method for JSON.parse's second argument. Converts objects having a single
1284
+ * `$bigint: string` property to an actual `bigint` value.
1285
+ *
1286
+ * Inverse of {@link bigIntJsonStringifyReplacer}.
1287
+ *
1288
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
1289
+ */
1290
+ const bigIntJsonParseReviver = (_key, value) => isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === "string" ? BigInt(value.$bigint) : value;
1291
+ //#endregion
1292
+ export { defaultCombinators as $, isFlexibleOptionGroupArray as A, uniqByName as B, withParamPrefix as C, queryBuilderFlagDefaults as Ct, getFirstOption as D, substringOperators as Dt, parseNumber as E, standardClassnames as Et, toFlatOptionArray as F, splitBy as G, uniqOptList as H, toFullOption as I, LogType as J, toArray as K, toFullOptionList as L, isFullOptionGroupArray as M, isOptionGroupArray as N, getOption as O, prepareOptionList as P, defaultCombinatorLabelMap as Q, toFullOptionMap as R, subqueryElementAliasBase as S, nullOperators as St, getParseNumberMethod as T, rootPath as Tt, joinWith as U, uniqOptGroups as V, nullFreeArray as W, betweenOperators as X, TestID as Y, defaultCoalesceMs as Z, numerifyValues as _, defaultPlaceholderValueLabel as _t, getLikeWildcards as a, defaultOperatorLabelMap as at, shouldRenderAsNumber as b, groupInvalidReasons as bt, getQuotedFieldName as c, defaultPlaceholderFieldGroupLabel as ct, isValidValue as d, defaultPlaceholderLabel as dt, defaultCombinatorsExtended as et, isValueProcessorLegacy as f, defaultPlaceholderName as ft, normalizeConstituentWordOrder as g, defaultPlaceholderValueGroupLabel as gt, mongoOperators as h, defaultPlaceholderOperatorName as ht, defaultNLTranslations as i, defaultMaxHistory as it, isFullOptionArray as j, isFlexibleOptionArray as k, getSQLConcat as l, defaultPlaceholderFieldLabel as lt, mapSQLOperator as m, defaultPlaceholderOperatorLabel as mt, bigIntJsonStringifyReplacer as n, defaultJoinChar as nt, getNLTranslataion as o, defaultOperatorNegationMap as ot, jsonLogicAdditionalOperators as p, defaultPlaceholderOperatorGroupLabel as pt, trimIfString as q, celCombinatorMap as r, defaultMatchModes as rt, getQuoteFieldNamesWithArray as s, defaultOperators as st, bigIntJsonParseReviver as t, defaultControlClassnames as tt, getSubqueryElementAlias as u, defaultPlaceholderFieldName as ut, prismaOperators as v, defaultPlaceholderValueName as vt, wrapLikeFragment as w, relationalOperators as wt, stripParamPrefix as x, inOperators as xt, processMatchMode as y, defaultTranslations as yt, uniqByIdentifier as z };
1293
+
1294
+ //# sourceMappingURL=utils-CP5Jqy1P.mjs.map