@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.
- package/derivations/package.json +4 -0
- package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +2078 -1665
- package/dist/cjs/react-querybuilder_core.cjs.development.js +1293 -422
- package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
- package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +2078 -1665
- package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
- package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
- package/dist/{convertQuery-Cw76XFIn.js → convertQuery-BLT0GIhM.js} +17 -8
- package/dist/{convertQuery-Cw76XFIn.js.map → convertQuery-BLT0GIhM.js.map} +1 -1
- package/dist/{convertQuery-D_4J7E-Z.mjs → convertQuery-DaXv3h7S.mjs} +6 -3
- package/dist/{convertQuery-D_4J7E-Z.mjs.map → convertQuery-DaXv3h7S.mjs.map} +1 -1
- package/dist/derivations.d.mts +2902 -0
- package/dist/derivations.d.ts +2902 -0
- package/dist/derivations.js +2845 -0
- package/dist/derivations.js.map +1 -0
- package/dist/derivations.mjs +2678 -0
- package/dist/derivations.mjs.map +1 -0
- package/dist/formatQuery.d.mts +2 -895
- package/dist/formatQuery.d.ts +2 -895
- package/dist/formatQuery.js +120 -140
- package/dist/formatQuery.js.map +1 -1
- package/dist/formatQuery.mjs +8 -28
- package/dist/formatQuery.mjs.map +1 -1
- package/dist/{import-DVWI7Fdh.d.mts → import-BdKPtLzo.d.mts} +2 -2
- package/dist/{import-6ExjhifL.d.ts → import-BfZTwhp2.d.ts} +2 -2
- package/dist/{index-CX9mehdL.d.mts → index-DOIE2pwx.d.mts} +274 -3
- package/dist/{index-CX9mehdL.d.ts → index-DOIE2pwx.d.ts} +274 -3
- package/dist/index-OF2Q1gTp.d.mts +895 -0
- package/dist/index-XueTy_XQ.d.ts +895 -0
- package/dist/isRuleOrGroupValid-CIMZNkt4.mjs +27 -0
- package/dist/isRuleOrGroupValid-CIMZNkt4.mjs.map +1 -0
- package/dist/isRuleOrGroupValid-CtUf4_4x.js +38 -0
- package/dist/isRuleOrGroupValid-CtUf4_4x.js.map +1 -0
- package/dist/{isRuleGroup-CqLThsbu.mjs → objectUtils-DDZ-KhV5.mjs} +25 -2
- package/dist/objectUtils-DDZ-KhV5.mjs.map +1 -0
- package/dist/{isRuleGroup-0JNiQgLg.js → objectUtils-DfnEmDSV.js} +48 -1
- package/dist/objectUtils-DfnEmDSV.js.map +1 -0
- package/dist/parseCEL.d.mts +2 -2
- package/dist/parseCEL.d.ts +2 -2
- package/dist/parseCEL.js +19 -16
- package/dist/parseCEL.js.map +1 -1
- package/dist/parseCEL.mjs +12 -9
- package/dist/parseCEL.mjs.map +1 -1
- package/dist/parseCypher.d.mts +1 -1
- package/dist/parseCypher.d.ts +1 -1
- package/dist/parseGremlin.d.mts +1 -1
- package/dist/parseGremlin.d.ts +1 -1
- package/dist/parseJSONata.d.mts +2 -2
- package/dist/parseJSONata.d.ts +2 -2
- package/dist/parseJSONata.js +17 -14
- package/dist/parseJSONata.js.map +1 -1
- package/dist/parseJSONata.mjs +11 -8
- package/dist/parseJSONata.mjs.map +1 -1
- package/dist/parseJsonLogic.d.mts +2 -2
- package/dist/parseJsonLogic.d.ts +2 -2
- package/dist/parseJsonLogic.js +38 -38
- package/dist/parseJsonLogic.js.map +1 -1
- package/dist/parseJsonLogic.mjs +5 -5
- package/dist/parseMongoDB.d.mts +2 -2
- package/dist/parseMongoDB.d.ts +2 -2
- package/dist/parseMongoDB.js +50 -47
- package/dist/parseMongoDB.js.map +1 -1
- package/dist/parseMongoDB.mjs +35 -32
- package/dist/parseMongoDB.mjs.map +1 -1
- package/dist/parseSPARQL.d.mts +1 -1
- package/dist/parseSPARQL.d.ts +1 -1
- package/dist/parseSQL.d.mts +2 -2
- package/dist/parseSQL.d.ts +2 -2
- package/dist/parseSQL.js +27 -23
- package/dist/parseSQL.js.map +1 -1
- package/dist/parseSQL.mjs +21 -17
- package/dist/parseSQL.mjs.map +1 -1
- package/dist/parseSpEL.d.mts +2 -2
- package/dist/parseSpEL.d.ts +2 -2
- package/dist/parseSpEL.js +16 -13
- package/dist/parseSpEL.js.map +1 -1
- package/dist/parseSpEL.mjs +12 -9
- package/dist/parseSpEL.mjs.map +1 -1
- package/dist/parserUtils-BKPstAaO.mjs +30 -0
- package/dist/parserUtils-BKPstAaO.mjs.map +1 -0
- package/dist/parserUtils-DbBXyAht.js +41 -0
- package/dist/parserUtils-DbBXyAht.js.map +1 -0
- package/dist/{prepareQueryObjects-BnGL91Tt.js → prepareQueryObjects-Dj9cTl9D.js} +90 -63
- package/dist/prepareQueryObjects-Dj9cTl9D.js.map +1 -0
- package/dist/{prepareQueryObjects-ChINDIap.mjs → prepareQueryObjects-Dmyf3Wi_.mjs} +56 -59
- package/dist/prepareQueryObjects-Dmyf3Wi_.mjs.map +1 -0
- package/dist/react-querybuilder_core.d.mts +2078 -1665
- package/dist/react-querybuilder_core.legacy-esm.d.ts +2078 -1665
- package/dist/react-querybuilder_core.legacy-esm.js +1445 -635
- package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
- package/dist/react-querybuilder_core.mjs +1288 -424
- package/dist/react-querybuilder_core.mjs.map +1 -1
- package/dist/react-querybuilder_core.production.d.mts +2078 -1665
- package/dist/react-querybuilder_core.production.mjs +1 -1
- package/dist/react-querybuilder_core.production.mjs.map +1 -1
- package/dist/transformQuery-B7d9AWUf.d.mts +116 -0
- package/dist/transformQuery-BXDiUBGB.d.ts +116 -0
- package/dist/transformQuery.d.mts +2 -116
- package/dist/transformQuery.d.ts +2 -116
- package/dist/transformQuery.js +3 -4
- package/dist/transformQuery.js.map +1 -1
- package/dist/transformQuery.mjs +1 -2
- package/dist/transformQuery.mjs.map +1 -1
- package/dist/utils-CP5Jqy1P.mjs +1294 -0
- package/dist/utils-CP5Jqy1P.mjs.map +1 -0
- package/dist/utils-e-7KHkjV.js +1779 -0
- package/dist/utils-e-7KHkjV.js.map +1 -0
- package/package.json +33 -22
- package/dist/isRuleGroup-0JNiQgLg.js.map +0 -1
- package/dist/isRuleGroup-CqLThsbu.mjs.map +0 -1
- package/dist/objectUtils-Cr02aGxb.js +0 -27
- package/dist/objectUtils-Cr02aGxb.js.map +0 -1
- package/dist/objectUtils-DBlmJgBf.mjs +0 -16
- package/dist/objectUtils-DBlmJgBf.mjs.map +0 -1
- package/dist/prepareQueryObjects-BnGL91Tt.js.map +0 -1
- package/dist/prepareQueryObjects-ChINDIap.mjs.map +0 -1
- package/dist/utils-4k-j5FBa.mjs +0 -537
- package/dist/utils-4k-j5FBa.mjs.map +0 -1
- package/dist/utils-C79dxwZb.js +0 -752
- 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
|