@react-querybuilder/core 8.9.0 → 8.9.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE.md +21 -0
  2. package/dist/arrayUtils-BF1P8iHS.mjs +122 -0
  3. package/dist/arrayUtils-BF1P8iHS.mjs.map +1 -0
  4. package/dist/basic-BfD-7CN3.d.mts +1235 -0
  5. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +21 -10
  6. package/dist/cjs/react-querybuilder_core.cjs.development.js +22 -19
  7. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  8. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +21 -10
  9. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  10. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  11. package/dist/convertQuery-H7RhQiIc.mjs +75 -0
  12. package/dist/convertQuery-H7RhQiIc.mjs.map +1 -0
  13. package/dist/export-r-V7bU31.d.mts +452 -0
  14. package/dist/formatQuery.d.mts +667 -0
  15. package/dist/formatQuery.mjs +2366 -0
  16. package/dist/formatQuery.mjs.map +1 -0
  17. package/dist/import-BwbbP4oU.d.mts +28 -0
  18. package/dist/isRuleGroup-CnhYpLOM.mjs +40 -0
  19. package/dist/isRuleGroup-CnhYpLOM.mjs.map +1 -0
  20. package/dist/isRuleGroup-DqAs2x4E.js.map +1 -1
  21. package/dist/objectUtils-BtWdcZVG.mjs +11 -0
  22. package/dist/objectUtils-BtWdcZVG.mjs.map +1 -0
  23. package/dist/optGroupUtils-Duv-M8rf.mjs +102 -0
  24. package/dist/optGroupUtils-Duv-M8rf.mjs.map +1 -0
  25. package/dist/parseCEL.d.mts +34 -0
  26. package/dist/parseCEL.mjs +2593 -0
  27. package/dist/parseCEL.mjs.map +1 -0
  28. package/dist/parseJSONata.d.mts +36 -0
  29. package/dist/parseJSONata.mjs +268 -0
  30. package/dist/parseJSONata.mjs.map +1 -0
  31. package/dist/parseJsonLogic.d.mts +36 -0
  32. package/dist/parseJsonLogic.mjs +191 -0
  33. package/dist/parseJsonLogic.mjs.map +1 -0
  34. package/dist/parseMongoDB.d.mts +79 -0
  35. package/dist/parseMongoDB.mjs +267 -0
  36. package/dist/parseMongoDB.mjs.map +1 -0
  37. package/dist/parseNumber-BtGKa58z.mjs +24 -0
  38. package/dist/parseNumber-BtGKa58z.mjs.map +1 -0
  39. package/dist/parseSQL.d.mts +37 -0
  40. package/dist/parseSQL.mjs +6626 -0
  41. package/dist/parseSQL.mjs.map +1 -0
  42. package/dist/parseSpEL.d.mts +34 -0
  43. package/dist/parseSpEL.mjs +273 -0
  44. package/dist/parseSpEL.mjs.map +1 -0
  45. package/dist/prepareQueryObjects-CS6Wmhmf.mjs +154 -0
  46. package/dist/prepareQueryObjects-CS6Wmhmf.mjs.map +1 -0
  47. package/dist/react-querybuilder_core.d.mts +21 -10
  48. package/dist/react-querybuilder_core.legacy-esm.d.ts +21 -10
  49. package/dist/react-querybuilder_core.legacy-esm.js +19 -18
  50. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  51. package/dist/react-querybuilder_core.mjs +22 -20
  52. package/dist/react-querybuilder_core.mjs.map +1 -1
  53. package/dist/react-querybuilder_core.production.d.mts +21 -10
  54. package/dist/react-querybuilder_core.production.mjs +1 -1
  55. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  56. package/dist/transformQuery-DdMvmrCh.mjs +41 -0
  57. package/dist/transformQuery-DdMvmrCh.mjs.map +1 -0
  58. package/dist/transformQuery.d.mts +118 -0
  59. package/dist/transformQuery.mjs +4 -0
  60. package/package.json +68 -19
@@ -0,0 +1,2366 @@
1
+ import { defaultPlaceholderFieldName, defaultPlaceholderOperatorName, joinWith, splitBy, toArray, trimIfString } from "./arrayUtils-BF1P8iHS.mjs";
2
+ import { isPojo, isRuleGroup, isRuleGroupType, isRuleGroupTypeIC, lc, nullOrUndefinedOrEmpty, numericRegex } from "./isRuleGroup-CnhYpLOM.mjs";
3
+ import { parseNumber } from "./parseNumber-BtGKa58z.mjs";
4
+ import { transformQuery } from "./transformQuery-DdMvmrCh.mjs";
5
+ import { getOption, toFlatOptionArray, toFullOptionList } from "./optGroupUtils-Duv-M8rf.mjs";
6
+ import { convertFromIC } from "./convertQuery-H7RhQiIc.mjs";
7
+ import { produce } from "immer";
8
+
9
+ //#region src/utils/isRuleOrGroupValid.ts
10
+ /**
11
+ * Determines if an object is useful as a validation result.
12
+ */
13
+ const isValidationResult = (vr) => isPojo(vr) && typeof vr.valid === "boolean";
14
+ /**
15
+ * Determines if a rule or group is valid based on a validation result (if defined)
16
+ * or a validator function. Returns `true` if neither are defined.
17
+ */
18
+ const isRuleOrGroupValid = (rg, validationResult, validator) => {
19
+ if (typeof validationResult === "boolean") return validationResult;
20
+ if (isValidationResult(validationResult)) return validationResult.valid;
21
+ if (typeof validator === "function" && !isRuleGroup(rg)) {
22
+ const vr = validator(rg);
23
+ if (typeof vr === "boolean") return vr;
24
+ // istanbul ignore else
25
+ if (isValidationResult(vr)) return vr.valid;
26
+ }
27
+ return true;
28
+ };
29
+
30
+ //#endregion
31
+ //#region src/utils/getParseNumberMethod.ts
32
+ const getParseNumberMethod = ({ parseNumbers, inputType }) => {
33
+ if (typeof parseNumbers === "string") {
34
+ const [method, level] = parseNumbers.split("-");
35
+ if (level === "limited") return inputType === "number" ? method : false;
36
+ return method;
37
+ }
38
+ return parseNumbers ? "strict" : false;
39
+ };
40
+
41
+ //#endregion
42
+ //#region src/utils/formatQuery/utils.ts
43
+ /**
44
+ * Maps a {@link DefaultOperatorName} to a SQL operator.
45
+ *
46
+ * @group Export
47
+ */
48
+ const mapSQLOperator = (rqbOperator) => {
49
+ switch (lc(rqbOperator)) {
50
+ case "null": return "is null";
51
+ case "notnull": return "is not null";
52
+ case "notin": return "not in";
53
+ case "notbetween": return "not between";
54
+ case "contains":
55
+ case "beginswith":
56
+ case "endswith": return "like";
57
+ case "doesnotcontain":
58
+ case "doesnotbeginwith":
59
+ case "doesnotendwith": return "not like";
60
+ default: return rqbOperator;
61
+ }
62
+ };
63
+ /**
64
+ * Maps a (lowercase) {@link DefaultOperatorName} to a MongoDB operator.
65
+ *
66
+ * @group Export
67
+ */
68
+ const mongoOperators = {
69
+ "=": "$eq",
70
+ "!=": "$ne",
71
+ "<": "$lt",
72
+ "<=": "$lte",
73
+ ">": "$gt",
74
+ ">=": "$gte",
75
+ in: "$in",
76
+ notin: "$nin",
77
+ notIn: "$nin"
78
+ };
79
+ /**
80
+ * Maps a (lowercase) {@link DefaultOperatorName} to a Prisma ORM operator.
81
+ *
82
+ * @group Export
83
+ */
84
+ const prismaOperators = {
85
+ "=": "equals",
86
+ "!=": "not",
87
+ "<": "lt",
88
+ "<=": "lte",
89
+ ">": "gt",
90
+ ">=": "gte",
91
+ in: "in",
92
+ notin: "notIn"
93
+ };
94
+ /**
95
+ * Maps a {@link DefaultCombinatorName} to a CEL combinator.
96
+ *
97
+ * @group Export
98
+ */
99
+ const celCombinatorMap = {
100
+ and: "&&",
101
+ or: "||"
102
+ };
103
+ /**
104
+ * Register these operators with `jsonLogic` before applying the result
105
+ * of `formatQuery(query, 'jsonlogic')`.
106
+ *
107
+ * @example
108
+ * ```
109
+ * for (const [op, func] of Object.entries(jsonLogicAdditionalOperators)) {
110
+ * jsonLogic.add_operation(op, func);
111
+ * }
112
+ * jsonLogic.apply({ "startsWith": [{ "var": "firstName" }, "Stev"] }, data);
113
+ * ```
114
+ *
115
+ * @group Export
116
+ */
117
+ const jsonLogicAdditionalOperators = {
118
+ startsWith: (a, b) => typeof a === "string" && a.startsWith(b),
119
+ endsWith: (a, b) => typeof a === "string" && a.endsWith(b)
120
+ };
121
+ /**
122
+ * Converts all `string`-type `value` properties of a query object into `number` where appropriate.
123
+ *
124
+ * Used by {@link formatQuery} for the `json*` formats when `parseNumbers` is `true`.
125
+ *
126
+ * @group Export
127
+ */
128
+ const numerifyValues = (rg, options) => ({
129
+ ...rg,
130
+ rules: rg.rules.map((r) => {
131
+ if (typeof r === "string") return r;
132
+ if (isRuleGroup(r)) return numerifyValues(r, options);
133
+ const fieldData = getOption(options.fields, r.field);
134
+ const parseNumbers = getParseNumberMethod({
135
+ parseNumbers: options.parseNumbers,
136
+ inputType: fieldData?.inputType
137
+ });
138
+ if (Array.isArray(r.value)) return {
139
+ ...r,
140
+ value: r.value.map((v) => parseNumber(v, { parseNumbers }))
141
+ };
142
+ const valAsArray = toArray(r.value, { retainEmptyStrings: true }).map((v) => parseNumber(v, { parseNumbers }));
143
+ if (valAsArray.every((v) => typeof v === "number")) {
144
+ // istanbul ignore else
145
+ if (valAsArray.length > 1) return {
146
+ ...r,
147
+ value: valAsArray
148
+ };
149
+ else if (valAsArray.length === 1) return {
150
+ ...r,
151
+ value: valAsArray[0]
152
+ };
153
+ }
154
+ return r;
155
+ })
156
+ });
157
+ /**
158
+ * Determines whether a value is _anything_ except an empty `string` or `NaN`.
159
+ *
160
+ * @group Export
161
+ */
162
+ const isValidValue = (value) => typeof value === "string" && value.length > 0 || typeof value === "number" && !Number.isNaN(value) || typeof value !== "string" && typeof value !== "number";
163
+ /**
164
+ * Determines whether {@link formatQuery} should render the given value as a number.
165
+ * As long as `parseNumbers` is `true`, `number` and `bigint` values will return `true` and
166
+ * `string` values will return `true` if they test positive against {@link numericRegex}.
167
+ *
168
+ * @group Export
169
+ */
170
+ const shouldRenderAsNumber = (value, parseNumbers) => !!parseNumbers && (typeof value === "number" || typeof value === "bigint" || typeof value === "string" && numericRegex.test(value));
171
+ /**
172
+ * Used by {@link formatQuery} to determine whether the given value processor is a
173
+ * "legacy" value processor by counting the number of arguments. Legacy value
174
+ * processors take 3 arguments (not counting any arguments with default values), while
175
+ * rule-based value processors take no more than 2 arguments.
176
+ *
177
+ * @group Export
178
+ */
179
+ const isValueProcessorLegacy = (valueProcessor) => valueProcessor.length >= 3;
180
+ /**
181
+ * Converts the `quoteFieldNamesWith` option into an array of two strings.
182
+ * If the option is a string, the array elements are both that string.
183
+ *
184
+ * @default
185
+ * ['', '']
186
+ *
187
+ * @group Export
188
+ */
189
+ const getQuoteFieldNamesWithArray = (quoteFieldNamesWith = ["", ""]) => Array.isArray(quoteFieldNamesWith) ? quoteFieldNamesWith : typeof quoteFieldNamesWith === "string" ? [quoteFieldNamesWith, quoteFieldNamesWith] : quoteFieldNamesWith ?? ["", ""];
190
+ /**
191
+ * Given a field name and relevant {@link ValueProcessorOptions}, returns the field name
192
+ * wrapped in the configured quote character(s).
193
+ *
194
+ * @group Export
195
+ */
196
+ const getQuotedFieldName = (fieldName, { quoteFieldNamesWith, fieldIdentifierSeparator }) => {
197
+ const [qPre, qPost] = getQuoteFieldNamesWithArray(quoteFieldNamesWith);
198
+ return typeof fieldIdentifierSeparator === "string" && fieldIdentifierSeparator.length > 0 ? joinWith(splitBy(fieldName, fieldIdentifierSeparator).map((part) => `${qPre}${part}${qPost}`), fieldIdentifierSeparator) : `${qPre}${fieldName}${qPost}`;
199
+ };
200
+ const defaultWordOrder = [
201
+ "S",
202
+ "V",
203
+ "O"
204
+ ];
205
+ /**
206
+ * Given a [Constituent word order](https://en.wikipedia.org/wiki/Word_order#Constituent_word_orders)
207
+ * like "svo" or "sov", returns a permutation of `["S", "V", "O"]` based on the first occurrence of
208
+ * each letter in the input string (case insensitive). This widens the valid input from abbreviations
209
+ * like "svo" to more expressive strings like "subject-verb-object" or "sub ver obj". Any missing
210
+ * letters are appended in the default order "SVO" (e.g., "object" would yield `["O", "S", "V"]`).
211
+ *
212
+ * @group Export
213
+ */
214
+ const normalizeConstituentWordOrder = (input) => {
215
+ const result = [];
216
+ const letterSet = new Set(defaultWordOrder);
217
+ for (const char of input.toUpperCase()) if (letterSet.has(char)) {
218
+ result.push(char);
219
+ letterSet.delete(char);
220
+ if (letterSet.size === 0) break;
221
+ }
222
+ for (const letter of defaultWordOrder) if (letterSet.has(letter)) result.push(letter);
223
+ return result;
224
+ };
225
+ /**
226
+ * Default translations used by {@link formatQuery} for "natural_language" format.
227
+ *
228
+ * @group Export
229
+ */
230
+ const defaultNLTranslations = {
231
+ groupPrefix: "",
232
+ groupPrefix_not_xor: "either zero or more than one of",
233
+ groupPrefix_xor: "exactly one of",
234
+ groupSuffix: "is true",
235
+ groupSuffix_not: "is not true"
236
+ };
237
+ /**
238
+ * Note: This function assumes `conditions.length > 0`
239
+ */
240
+ const translationMatchFilter = (key, keyToTest, conditions) => keyToTest.startsWith(key) && conditions.every((c) => keyToTest.includes(`_${c}`) && keyToTest.match(/_/g)?.length === conditions.length);
241
+ /**
242
+ * Used by {@link formatQuery} to get a translation based on certain conditions
243
+ * for the "natural_language" format.
244
+ *
245
+ * @group Export
246
+ */
247
+ const getNLTranslataion = (key, translations, conditions = []) => conditions.length === 0 ? translations[key] ?? defaultNLTranslations[key] ?? "" : Object.entries(translations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))?.[1] ?? Object.entries(defaultNLTranslations).find(([keyToTest]) => translationMatchFilter(key, keyToTest, conditions))?.[1] ?? defaultNLTranslations[key] ?? "";
248
+ const processMatchMode = (rule) => {
249
+ const { mode, threshold } = rule.match ?? {};
250
+ if (mode) {
251
+ if (!isRuleGroup(rule.value)) return false;
252
+ const matchModeLC = lc(mode);
253
+ const matchModeCoerced = matchModeLC === "atleast" && threshold === 1 ? "some" : matchModeLC === "atmost" && threshold === 0 ? "none" : matchModeLC;
254
+ if ((matchModeCoerced === "atleast" || matchModeCoerced === "atmost" || matchModeCoerced === "exactly") && (typeof threshold !== "number" || threshold < 0)) return false;
255
+ return {
256
+ mode: matchModeCoerced,
257
+ threshold
258
+ };
259
+ }
260
+ };
261
+ /**
262
+ * "Replacer" method for JSON.stringify's second argument. Converts `bigint` values to
263
+ * objects with a `$bigint` property having a value of a string representation of
264
+ * the actual `bigint`-type value.
265
+ *
266
+ * Inverse of {@link bigIntJsonParseReviver}.
267
+ *
268
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
269
+ */
270
+ const bigIntJsonStringifyReplacer = (_key, value) => typeof value === "bigint" ? { $bigint: value.toString() } : value;
271
+ /**
272
+ * "Reviver" method for JSON.parse's second argument. Converts objects having a single
273
+ * `$bigint: string` property to an actual `bigint` value.
274
+ *
275
+ * Inverse of {@link bigIntJsonStringifyReplacer}.
276
+ *
277
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#use_within_json
278
+ */
279
+ const bigIntJsonParseReviver = (_key, value) => isPojo(value) && Object.keys(value).length === 1 && typeof value.$bigint === "string" ? BigInt(value.$bigint) : value;
280
+
281
+ //#endregion
282
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorCEL.ts
283
+ /**
284
+ * Rule group processor used by {@link formatQuery} for "cel" format.
285
+ *
286
+ * @group Export
287
+ */
288
+ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
289
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
290
+ const processRuleGroup = (rg, outermost) => {
291
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
292
+ const expression = rg.rules.map((rule) => {
293
+ if (typeof rule === "string") return celCombinatorMap[rule];
294
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
295
+ const [validationResult, fieldValidator] = validateRule(rule);
296
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
297
+ const fieldData = getOption(fields, rule.field);
298
+ return ruleProcessor(rule, {
299
+ ...options,
300
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
301
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
302
+ fieldData
303
+ });
304
+ }).filter(Boolean).join(isRuleGroupType(rg) ? ` ${celCombinatorMap[rg.combinator]} ` : " ");
305
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""];
306
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
307
+ };
308
+ return processRuleGroup(ruleGroup, true);
309
+ };
310
+
311
+ //#endregion
312
+ //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts
313
+ const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot");
314
+ const escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
315
+ /**
316
+ * Default rule processor used by {@link formatQuery} for "cel" format.
317
+ *
318
+ * @group Export
319
+ */
320
+ const defaultRuleProcessorCEL = (rule, opts = {}) => {
321
+ const { escapeQuotes, parseNumbers, preserveValueOrder } = opts;
322
+ const { field, operator, value, valueSource } = rule;
323
+ const valueIsField = valueSource === "field";
324
+ const operatorTL = lc(operator === "=" ? "==" : operator);
325
+ const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers);
326
+ const matchEval = processMatchMode(rule);
327
+ if (matchEval === false) return "";
328
+ else if (matchEval) {
329
+ const { mode, threshold } = matchEval;
330
+ const arrayElementAlias = "elem_alias";
331
+ const celQuery = transformQuery(rule.value, { ruleProcessor: (r) => ({
332
+ ...r,
333
+ field: `${arrayElementAlias}${r.field ? `.${r.field}` : ""}`
334
+ }) });
335
+ const nestedArrayFilter = defaultRuleGroupProcessorCEL(celQuery, opts);
336
+ switch (mode) {
337
+ case "all": return `${field}.all(${arrayElementAlias}, ${nestedArrayFilter})`;
338
+ case "none":
339
+ case "some": return `${mode === "none" ? "!" : ""}${field}.exists(${arrayElementAlias}, ${nestedArrayFilter})`;
340
+ case "atleast":
341
+ case "atmost":
342
+ case "exactly": {
343
+ const totalCount = `double(${field}.size())`;
344
+ const filteredCount = `${field}.filter(${arrayElementAlias}, ${nestedArrayFilter}).size()`;
345
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "==";
346
+ if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`;
347
+ return `${filteredCount} ${op} ${threshold}`;
348
+ }
349
+ }
350
+ }
351
+ switch (operatorTL) {
352
+ case "<":
353
+ case "<=":
354
+ case "==":
355
+ case "!=":
356
+ case ">":
357
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`}`;
358
+ case "contains":
359
+ case "doesnotcontain": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.contains(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
360
+ case "beginswith":
361
+ case "doesnotbeginwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.startsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
362
+ case "endswith":
363
+ case "doesnotendwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.endsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
364
+ case "null": return `${field} == null`;
365
+ case "notnull": return `${field} != null`;
366
+ case "in":
367
+ case "notin": {
368
+ const [prefix, suffix] = shouldNegate$2(operatorTL) ? ["!(", ")"] : ["", ""];
369
+ const valueAsArray = toArray(value);
370
+ return `${prefix}${field} in [${valueAsArray.map((val) => valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `"${escapeDoubleQuotes(val, escapeQuotes)}"`).join(", ")}]${suffix}`;
371
+ }
372
+ case "between":
373
+ case "notbetween": {
374
+ const valueAsArray = toArray(value);
375
+ if (valueAsArray.length >= 2 && !nullOrUndefinedOrEmpty(valueAsArray[0]) && !nullOrUndefinedOrEmpty(valueAsArray[1])) {
376
+ const [first, second] = valueAsArray;
377
+ const shouldParseNumbers = !(parseNumbers === false);
378
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
379
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
380
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes(first, escapeQuotes)}"` : firstNum;
381
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `"${escapeDoubleQuotes(second, escapeQuotes)}"` : secondNum;
382
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
383
+ const tempNum = secondNum;
384
+ secondValue = firstNum;
385
+ firstValue = tempNum;
386
+ }
387
+ return operatorTL === "between" ? `(${field} >= ${firstValue} && ${field} <= ${secondValue})` : `(${field} < ${firstValue} || ${field} > ${secondValue})`;
388
+ } else return "";
389
+ }
390
+ }
391
+ return "";
392
+ };
393
+
394
+ //#endregion
395
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDBQuery.ts
396
+ /**
397
+ * Default fallback object used by {@link formatQuery} for "mongodb_query" format.
398
+ *
399
+ * @group Export
400
+ */
401
+ const mongoDbFallback = { $and: [{ $expr: true }] };
402
+ /**
403
+ * Rule group processor used by {@link formatQuery} for "mongodb_query" format.
404
+ *
405
+ * @group Export
406
+ */
407
+ const defaultRuleGroupProcessorMongoDBQuery = (ruleGroup, options, meta) => {
408
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
409
+ const processRuleGroup = (rg, outermost) => {
410
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? mongoDbFallback : false;
411
+ const combinator = `$${lc(rg.combinator)}`;
412
+ let hasChildRules = false;
413
+ const expressions = rg.rules.map((rule) => {
414
+ if (isRuleGroup(rule)) {
415
+ const processedRuleGroup = processRuleGroup(rule);
416
+ if (processedRuleGroup) {
417
+ hasChildRules = true;
418
+ return processedRuleGroup;
419
+ }
420
+ return false;
421
+ }
422
+ const [validationResult, fieldValidator] = validateRule(rule);
423
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false;
424
+ const fieldData = getOption(fields, rule.field);
425
+ return ruleProcessor(rule, {
426
+ ...options,
427
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
428
+ fieldData
429
+ }, meta);
430
+ }).filter(Boolean);
431
+ return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : mongoDbFallback;
432
+ };
433
+ return processRuleGroup(convertFromIC(ruleGroup), true);
434
+ };
435
+
436
+ //#endregion
437
+ //#region src/utils/formatQuery/defaultRuleProcessorMongoDBQuery.ts
438
+ const processNumber$1 = (value, fallback, parseNumbers = false) => shouldRenderAsNumber(value, parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: "strict" })) : fallback;
439
+ /**
440
+ * Default rule processor used by {@link formatQuery} for "mongodb_query" format.
441
+ *
442
+ * @group Export
443
+ */
444
+ const defaultRuleProcessorMongoDBQuery = (rule, options = {}) => {
445
+ const { field, operator, value, valueSource } = rule;
446
+ const { parseNumbers, preserveValueOrder, context } = options;
447
+ const valueIsField = valueSource === "field";
448
+ const { avoidFieldsAsKeys } = context ?? {};
449
+ const matchEval = processMatchMode(rule);
450
+ if (matchEval === false) return;
451
+ else if (matchEval) {
452
+ const { mode, threshold } = matchEval;
453
+ const totalCount = { $size: { $ifNull: [`$${field}`, []] } };
454
+ const subQueryNoAggCtx = defaultRuleGroupProcessorMongoDBQuery(transformQuery(value, { ruleProcessor: (r) => ({
455
+ ...r,
456
+ field: r.field ? `${field}.${r.field}` : field
457
+ }) }), {
458
+ ...options,
459
+ ruleProcessor: defaultRuleProcessorMongoDBQuery,
460
+ context: {
461
+ ...options.context,
462
+ avoidFieldsAsKeys: false
463
+ }
464
+ });
465
+ const subQueryWithAggCtx = defaultRuleGroupProcessorMongoDBQuery(transformQuery(value, { ruleProcessor: (r) => ({
466
+ ...r,
467
+ field: r.field ? `$item.${r.field}` : "$item"
468
+ }) }), {
469
+ ...options,
470
+ ruleProcessor: defaultRuleProcessorMongoDBQuery,
471
+ context: {
472
+ ...options.context,
473
+ avoidFieldsAsKeys: true
474
+ }
475
+ });
476
+ const filteredCount = { $size: { $ifNull: [{ $filter: {
477
+ input: `$${field}`,
478
+ as: "item",
479
+ cond: { $and: [subQueryWithAggCtx] }
480
+ } }, []] } };
481
+ switch (mode) {
482
+ case "all": return { $expr: { $eq: [filteredCount, totalCount] } };
483
+ case "none": return { $nor: [subQueryNoAggCtx] };
484
+ case "some": return subQueryNoAggCtx;
485
+ case "atleast":
486
+ case "atmost":
487
+ case "exactly": {
488
+ const op = mode === "atleast" ? mongoOperators[">="] : mode === "atmost" ? mongoOperators["<="] : mongoOperators["="];
489
+ if (threshold > 0 && threshold < 1) return { $expr: { [op]: [filteredCount, { $multiply: [totalCount, threshold] }] } };
490
+ return { $expr: { [op]: [filteredCount, threshold] } };
491
+ }
492
+ }
493
+ }
494
+ if (operator === "=" && !valueIsField) return avoidFieldsAsKeys ? { $eq: [`$${field}`, processNumber$1(value, value, parseNumbers)] } : { [field]: processNumber$1(value, value, parseNumbers) };
495
+ const operatorLC = lc(operator);
496
+ switch (operatorLC) {
497
+ case "<":
498
+ case "<=":
499
+ case "=":
500
+ case "!=":
501
+ case ">":
502
+ case ">=": {
503
+ const mongoOperator = mongoOperators[operatorLC];
504
+ return valueIsField ? { [mongoOperator]: [`$${field}`, `$${value}`] } : avoidFieldsAsKeys ? { $and: [{ $ne: [`$${field}`, null] }, { [mongoOperator]: [`$${field}`, processNumber$1(value, value, parseNumbers)] }] } : { [field]: { [mongoOperator]: processNumber$1(value, value, parseNumbers) } };
505
+ }
506
+ case "contains": return valueIsField ? { $where: `this.${field}.includes(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: {
507
+ input: `$${field}`,
508
+ regex: value
509
+ } } : { [field]: { $regex: value } };
510
+ case "beginswith": return valueIsField ? { $where: `this.${field}.startsWith(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: {
511
+ input: `$${field}`,
512
+ regex: `^${value}`
513
+ } } : { [field]: { $regex: `^${value}` } };
514
+ case "endswith": return valueIsField ? { $where: `this.${field}.endsWith(this.${value})` } : avoidFieldsAsKeys ? { $regexMatch: {
515
+ input: `$${field}`,
516
+ regex: `${value}$`
517
+ } } : { [field]: { $regex: `${value}$` } };
518
+ case "doesnotcontain": return valueIsField ? { $where: `!this.${field}.includes(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: {
519
+ input: `$${field}`,
520
+ regex: value
521
+ } } } : { [field]: { $not: { $regex: value } } };
522
+ case "doesnotbeginwith": return valueIsField ? { $where: `!this.${field}.startsWith(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: {
523
+ input: `$${field}`,
524
+ regex: `^${value}`
525
+ } } } : { [field]: { $not: { $regex: `^${value}` } } };
526
+ case "doesnotendwith": return valueIsField ? { $where: `!this.${field}.endsWith(this.${value})` } : avoidFieldsAsKeys ? { $not: { $regexMatch: {
527
+ input: `$${field}`,
528
+ regex: `${value}$`
529
+ } } } : { [field]: { $not: { $regex: `${value}$` } } };
530
+ case "null": return avoidFieldsAsKeys ? { $eq: [`$${field}`, null] } : { [field]: null };
531
+ case "notnull": return avoidFieldsAsKeys ? { $ne: [`$${field}`, null] } : { [field]: { $ne: null } };
532
+ case "in":
533
+ case "notin": {
534
+ const valueAsArray = toArray(value);
535
+ return valueIsField ? { $where: `${operatorLC === "notin" ? "!" : ""}[${valueAsArray.map((val) => `this.${val}`).join(",")}].includes(this.${field})` } : avoidFieldsAsKeys ? operatorLC === "notin" ? { $not: { [mongoOperators.in]: [`$${field}`, valueAsArray.map((val) => processNumber$1(val, val, parseNumbers))] } } : { [mongoOperators[operatorLC]]: [`$${field}`, valueAsArray.map((val) => processNumber$1(val, val, parseNumbers))] } : { [field]: { [mongoOperators[operatorLC]]: valueAsArray.map((val) => processNumber$1(val, val, parseNumbers)) } };
536
+ }
537
+ case "between":
538
+ case "notbetween": {
539
+ const valueAsArray = toArray(value);
540
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
541
+ const [first, second] = valueAsArray;
542
+ const firstNum = processNumber$1(first, NaN, true);
543
+ const secondNum = processNumber$1(second, NaN, true);
544
+ let firstValue = valueIsField ? first : Number.isNaN(firstNum) ? first : firstNum;
545
+ let secondValue = valueIsField ? second : Number.isNaN(secondNum) ? second : secondNum;
546
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
547
+ const tempNum = secondNum;
548
+ secondValue = firstNum;
549
+ firstValue = tempNum;
550
+ }
551
+ if (operatorLC === "between") return valueIsField ? {
552
+ $gte: [`$${field}`, `$${firstValue}`],
553
+ $lte: [`$${field}`, `$${secondValue}`]
554
+ } : avoidFieldsAsKeys ? { $and: [{ $gte: [`$${field}`, firstValue] }, { $lte: [`$${field}`, secondValue] }] } : { [field]: {
555
+ $gte: firstValue,
556
+ $lte: secondValue
557
+ } };
558
+ else return valueIsField ? { $or: [{ $lt: [`$${field}`, `$${firstValue}`] }, { $gt: [`$${field}`, `$${secondValue}`] }] } : avoidFieldsAsKeys ? { $or: [{ $lt: [`$${field}`, firstValue] }, { $gt: [`$${field}`, secondValue] }] } : { $or: [{ [field]: { $lt: firstValue } }, { [field]: { $gt: secondValue } }] };
559
+ } else return "";
560
+ }
561
+ }
562
+ return "";
563
+ };
564
+
565
+ //#endregion
566
+ //#region src/utils/formatQuery/defaultRuleProcessorMongoDB.ts
567
+ /**
568
+ * Default rule processor used by {@link formatQuery} for "mongodb" format.
569
+ *
570
+ * Note that the "mongodb" format is deprecated in favor of the "mongodb_query" format.
571
+ *
572
+ * @group Export
573
+ */
574
+ const defaultRuleProcessorMongoDB = (rule, options) => {
575
+ const queryObj = defaultRuleProcessorMongoDBQuery(rule, options);
576
+ return queryObj ? JSON.stringify(queryObj) : "";
577
+ };
578
+
579
+ //#endregion
580
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSpEL.ts
581
+ /**
582
+ * Default rule processor used by {@link formatQuery} for "spel" format.
583
+ *
584
+ * @group Export
585
+ */
586
+ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
587
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
588
+ const processRuleGroup = (rg, outermost) => {
589
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
590
+ const expression = rg.rules.map((rule) => {
591
+ if (typeof rule === "string") return rule;
592
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
593
+ const [validationResult, fieldValidator] = validateRule(rule);
594
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
595
+ const fieldData = getOption(fields, rule.field);
596
+ return ruleProcessor(rule, {
597
+ ...options,
598
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
599
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
600
+ fieldData
601
+ });
602
+ }).filter(Boolean).join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ");
603
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""];
604
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
605
+ };
606
+ return processRuleGroup(ruleGroup, true);
607
+ };
608
+
609
+ //#endregion
610
+ //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts
611
+ const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot");
612
+ const wrapInNegation = (clause, negate$1) => negate$1 ? `!(${clause})` : clause;
613
+ const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
614
+ /**
615
+ * Default rule processor used by {@link formatQuery} for "spel" format.
616
+ *
617
+ * @group Export
618
+ */
619
+ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
620
+ const { field, operator, value, valueSource } = rule;
621
+ const { escapeQuotes, parseNumbers, preserveValueOrder } = opts;
622
+ const valueIsField = valueSource === "field";
623
+ const operatorTL = lc(operator === "=" ? "==" : operator);
624
+ const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers);
625
+ const matchEval = processMatchMode(rule);
626
+ if (matchEval === false) return "";
627
+ else if (matchEval) {
628
+ const { mode, threshold } = matchEval;
629
+ const nestedArrayFilter = defaultRuleGroupProcessorSpEL(transformQuery(rule.value, { ruleProcessor: (r) => ({
630
+ ...r,
631
+ field: r.field || "#this"
632
+ }) }), opts);
633
+ const totalCount = `${field}.size()`;
634
+ const filteredCount = `${field}.?[${nestedArrayFilter}].size()`;
635
+ switch (mode) {
636
+ case "all": return `${filteredCount} == ${totalCount}`;
637
+ case "none": return `${filteredCount} == 0`;
638
+ case "some": return `${filteredCount} >= 1`;
639
+ case "atleast":
640
+ case "atmost":
641
+ case "exactly": {
642
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "==";
643
+ if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`;
644
+ return `${filteredCount} ${op} ${threshold}`;
645
+ }
646
+ }
647
+ }
648
+ switch (operatorTL) {
649
+ case "<":
650
+ case "<=":
651
+ case "==":
652
+ case "!=":
653
+ case ">":
654
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`;
655
+ case "contains":
656
+ case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
657
+ case "beginswith":
658
+ case "doesnotbeginwith": {
659
+ const valueTL = valueIsField ? `'^'.concat(${trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes(value, escapeQuotes)}'`;
660
+ return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate$1(operatorTL));
661
+ }
662
+ case "endswith":
663
+ case "doesnotendwith": {
664
+ const valueTL = valueIsField ? `${trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`;
665
+ return wrapInNegation(`${field} matches ${valueTL}`, shouldNegate$1(operatorTL));
666
+ }
667
+ case "null": return `${field} == null`;
668
+ case "notnull": return `${field} != null`;
669
+ case "in":
670
+ case "notin": {
671
+ const negate$1 = shouldNegate$1(operatorTL) ? "!" : "";
672
+ const valueAsArray = toArray(value);
673
+ return valueAsArray.length > 0 ? `${negate$1}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
674
+ }
675
+ case "between":
676
+ case "notbetween": {
677
+ const valueAsArray = toArray(value);
678
+ if (valueAsArray.length >= 2 && !nullOrUndefinedOrEmpty(valueAsArray[0]) && !nullOrUndefinedOrEmpty(valueAsArray[1])) {
679
+ const [first, second] = valueAsArray;
680
+ const shouldParseNumbers = !(parseNumbers === false);
681
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
682
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
683
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes(first, escapeQuotes)}'` : firstNum;
684
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `'${escapeSingleQuotes(second, escapeQuotes)}'` : secondNum;
685
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
686
+ const tempNum = secondNum;
687
+ secondValue = firstNum;
688
+ firstValue = tempNum;
689
+ }
690
+ return operatorTL === "between" ? `(${field} >= ${firstValue} and ${field} <= ${secondValue})` : `(${field} < ${firstValue} or ${field} > ${secondValue})`;
691
+ } else return "";
692
+ }
693
+ }
694
+ return "";
695
+ };
696
+
697
+ //#endregion
698
+ //#region src/utils/formatQuery/defaultValueProcessorByRule.ts
699
+ const escapeStringValueQuotes$1 = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
700
+ /**
701
+ * Default value processor used by {@link formatQuery} for "sql" format.
702
+ *
703
+ * @group Export
704
+ */
705
+ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQuotes, parseNumbers, preserveValueOrder, quoteFieldNamesWith, quoteValuesWith, concatOperator = "||", fieldIdentifierSeparator, wrapValueWith = ["", ""], translations } = {}) => {
706
+ const valueIsField = valueSource === "field";
707
+ const operatorLowerCase = lc(operator);
708
+ const quoteChar = quoteValuesWith || "'";
709
+ const quoteValue = (v) => `${wrapValueWith[0]}${quoteChar}${v}${quoteChar}${wrapValueWith[1]}`;
710
+ const escapeValue = (v) => escapeStringValueQuotes$1(v, quoteChar, escapeQuotes);
711
+ const wrapAndEscape = (v) => quoteValue(escapeValue(v));
712
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
713
+ quoteFieldNamesWith,
714
+ fieldIdentifierSeparator
715
+ });
716
+ const concat = (...values) => concatOperator.toUpperCase() === "CONCAT" ? `CONCAT(${values.join(", ")})` : values.join(` ${concatOperator} `);
717
+ switch (operatorLowerCase) {
718
+ case "null":
719
+ case "notnull": return "";
720
+ case "in":
721
+ case "notin": {
722
+ const valueAsArray = toArray(value);
723
+ if (valueAsArray.length > 0) return `(${valueAsArray.map((v) => valueIsField ? wrapFieldName(v) : shouldRenderAsNumber(v, parseNumbers) ? `${trimIfString(v)}` : `${wrapAndEscape(v)}`).join(", ")})`;
724
+ return "";
725
+ }
726
+ case "between":
727
+ case "notbetween": {
728
+ const valueAsArray = toArray(value, { retainEmptyStrings: true });
729
+ if (valueAsArray.length < 2 || !isValidValue(valueAsArray[0]) || !isValidValue(valueAsArray[1])) return "";
730
+ const [first, second] = valueAsArray;
731
+ const firstNum = shouldRenderAsNumber(first, parseNumbers) ? parseNumber(first, { parseNumbers: "strict" }) : NaN;
732
+ const secondNum = shouldRenderAsNumber(second, parseNumbers) ? parseNumber(second, { parseNumbers: "strict" }) : NaN;
733
+ const firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : first : firstNum;
734
+ const secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : second : secondNum;
735
+ const valsOneAndTwoOnly = [firstValue, secondValue];
736
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
737
+ valsOneAndTwoOnly[0] = secondNum;
738
+ valsOneAndTwoOnly[1] = firstNum;
739
+ }
740
+ return (valueIsField ? valsOneAndTwoOnly.map((v) => wrapFieldName(v)) : valsOneAndTwoOnly.every((v) => shouldRenderAsNumber(v, parseNumbers)) ? valsOneAndTwoOnly.map((v) => parseNumber(v, { parseNumbers: "strict" })) : valsOneAndTwoOnly.map((v) => wrapAndEscape(v))).join(` ${translations?.and ?? "and"} `);
741
+ }
742
+ case "contains":
743
+ case "doesnotcontain": return valueIsField ? concat(quoteValue("%"), wrapFieldName(value), quoteValue("%")) : quoteValue(`%${escapeValue(value)}%`);
744
+ case "beginswith":
745
+ case "doesnotbeginwith": return valueIsField ? concat(wrapFieldName(value), quoteValue("%")) : quoteValue(`${escapeValue(value)}%`);
746
+ case "endswith":
747
+ case "doesnotendwith": return valueIsField ? concat(quoteValue("%"), wrapFieldName(value)) : quoteValue(`%${escapeValue(value)}`);
748
+ }
749
+ if (typeof value === "boolean") return value ? "TRUE" : "FALSE";
750
+ return valueIsField ? wrapFieldName(value) : shouldRenderAsNumber(value, parseNumbers) ? `${trimIfString(value)}` : `${wrapAndEscape(value)}`;
751
+ };
752
+
753
+ //#endregion
754
+ //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
755
+ /**
756
+ * Default rule processor used by {@link formatQuery} for the "drizzle" format.
757
+ *
758
+ * @group Export
759
+ */
760
+ const defaultRuleProcessorDrizzle = (rule, _options) => {
761
+ const opts = _options ?? ( /* istanbul ignore next */ {});
762
+ // istanbul ignore next
763
+ const { parseNumbers, preserveValueOrder, context = {} } = opts;
764
+ const { columns, drizzleOperators, useRawFields } = context;
765
+ if (!columns || !drizzleOperators) return;
766
+ const { between, eq, gt, gte, inArray, isNotNull, isNull, like, lt, lte, ne, notBetween, notInArray, notLike, sql } = drizzleOperators;
767
+ const { field, operator, value, valueSource } = rule;
768
+ const column = useRawFields && /[a-z][a-z0-9]*/i.test(field) ? sql.raw(field) : columns[field];
769
+ const operatorLC = lc(operator);
770
+ const valueIsField = valueSource === "field";
771
+ const asFieldOrValue = (v) => valueIsField ? columns[v] : v;
772
+ if (!column) return;
773
+ const matchEval = processMatchMode(rule);
774
+ if (matchEval === false) return;
775
+ else if (matchEval) {
776
+ if (opts.preset !== "postgresql") return;
777
+ const { mode, threshold } = matchEval;
778
+ const arrayElementAlias = "elem_alias";
779
+ const sqlQuery = transformQuery(rule.value, { ruleProcessor: (r) => ({
780
+ ...r,
781
+ field: arrayElementAlias
782
+ }) });
783
+ const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(sqlQuery, {
784
+ ...opts,
785
+ context: {
786
+ ...opts.context,
787
+ useRawFields: true
788
+ }
789
+ });
790
+ switch (mode) {
791
+ case "all": return sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) = array_length(${column}, 1)`;
792
+ case "none": return sql`not exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
793
+ case "some": return sql`exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
794
+ case "atleast":
795
+ case "atmost":
796
+ case "exactly": {
797
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
798
+ return threshold > 0 && threshold < 1 ? sql`(select count(*) / array_length(${column}, 1) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}` : sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}`;
799
+ }
800
+ }
801
+ }
802
+ switch (operatorLC) {
803
+ case "=": return eq(column, asFieldOrValue(value));
804
+ case "!=": return ne(column, asFieldOrValue(value));
805
+ case ">": return gt(column, asFieldOrValue(value));
806
+ case "<": return lt(column, asFieldOrValue(value));
807
+ case ">=": return gte(column, asFieldOrValue(value));
808
+ case "<=": return lte(column, asFieldOrValue(value));
809
+ case "beginswith":
810
+ case "doesnotbeginwith": return (operatorLC === "doesnotbeginwith" ? notLike : like)(column, valueIsField ? sql`${asFieldOrValue(value)} || '%'` : `${value}%`);
811
+ case "contains":
812
+ case "doesnotcontain": return (operatorLC === "doesnotcontain" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)} || '%'` : `%${value}%`);
813
+ case "endswith":
814
+ case "doesnotendwith": return (operatorLC === "doesnotendwith" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)}` : `%${value}`);
815
+ case "null": return isNull(column);
816
+ case "notnull": return isNotNull(column);
817
+ case "in":
818
+ case "notin": {
819
+ const valueAsArray = toArray(value).map((v) => asFieldOrValue(v));
820
+ return operatorLC === "notin" ? notInArray(column, valueAsArray) : inArray(column, valueAsArray);
821
+ }
822
+ case "between":
823
+ case "notbetween": {
824
+ const valueAsArray = toArray(value);
825
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
826
+ let [first, second] = valueAsArray;
827
+ const shouldParseNumbers = !(parseNumbers === false);
828
+ if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
829
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
830
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
831
+ if (!preserveValueOrder && secondNum < firstNum) {
832
+ const tempNum = secondNum;
833
+ second = firstNum;
834
+ first = tempNum;
835
+ } else {
836
+ first = firstNum;
837
+ second = secondNum;
838
+ }
839
+ } else if (valueIsField) {
840
+ first = asFieldOrValue(first);
841
+ second = asFieldOrValue(second);
842
+ }
843
+ return operatorLC === "notbetween" ? notBetween(column, first, second) : between(column, first, second);
844
+ }
845
+ return;
846
+ }
847
+ default: return;
848
+ }
849
+ };
850
+
851
+ //#endregion
852
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts
853
+ /**
854
+ * Default rule group processor used by {@link formatQuery} for the "drizzle" format. The returned
855
+ * function can be assigned to the `where` property in the Drizzle relational queries API.
856
+ *
857
+ * @example
858
+ * const where = formatQuery(query, 'drizzle');
859
+ * const results = db.query.users.findMany({ where });
860
+ *
861
+ * @returns Function that takes a Drizzle table config and an object of Drizzle operators.
862
+ *
863
+ * @group Export
864
+ */
865
+ const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns, drizzleOperators) => {
866
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap } = options;
867
+ if (!columns || !drizzleOperators) return;
868
+ const { and, not, or } = drizzleOperators;
869
+ const query = isRuleGroupType(ruleGroup) ? ruleGroup : convertFromIC(ruleGroup);
870
+ const ruleProcessor = defaultRuleProcessorDrizzle;
871
+ const processRuleGroup = (rg, _outermost) => {
872
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return;
873
+ const processedRules = rg.rules.map((rule) => {
874
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
875
+ const [validationResult, fieldValidator] = validateRule(rule);
876
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
877
+ const fieldData = getOption(fields, rule.field);
878
+ return ruleProcessor(rule, {
879
+ ...options,
880
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
881
+ fieldData,
882
+ context: {
883
+ ...options.context,
884
+ columns,
885
+ drizzleOperators
886
+ }
887
+ });
888
+ }).filter(Boolean);
889
+ if (processedRules.length === 0) return;
890
+ const ruleGroupSQL = rg.combinator === "or" ? or(...processedRules) : and(...processedRules);
891
+ return rg.not ? not(ruleGroupSQL) : ruleGroupSQL;
892
+ };
893
+ return processRuleGroup(query, true);
894
+ };
895
+
896
+ //#endregion
897
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorElasticSearch.ts
898
+ /**
899
+ * Rule group processor used by {@link formatQuery} for "elasticsearch" format.
900
+ *
901
+ * @group Export
902
+ */
903
+ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
904
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
905
+ const query = convertFromIC(ruleGroup);
906
+ const processRuleGroup = (rg) => {
907
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return false;
908
+ const processedRules = rg.rules.map((rule) => {
909
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
910
+ const [validationResult, fieldValidator] = validateRule(rule);
911
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false;
912
+ const fieldData = getOption(fields, rule.field);
913
+ return ruleProcessor(rule, {
914
+ ...options,
915
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
916
+ fieldData
917
+ });
918
+ }).filter(Boolean);
919
+ if (processedRules.length === 0) return false;
920
+ return { bool: rg.not ? { must_not: /^or$/i.test(rg.combinator) ? { bool: { should: processedRules } } : processedRules } : { [/^or$/i.test(rg.combinator) ? "should" : "must"]: processedRules } };
921
+ };
922
+ const processedRuleGroup = processRuleGroup(query);
923
+ return processedRuleGroup === false ? {} : processedRuleGroup;
924
+ };
925
+
926
+ //#endregion
927
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts
928
+ /**
929
+ * Rule group processor used by {@link formatQuery} for "jsonata" format.
930
+ *
931
+ * @group Export
932
+ */
933
+ const defaultRuleGroupProcessorJSONata = (ruleGroup, options) => {
934
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
935
+ const processRuleGroup = (rg, outermost) => {
936
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
937
+ const expression = rg.rules.map((rule) => {
938
+ if (typeof rule === "string") return rule;
939
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
940
+ const [validationResult, fieldValidator] = validateRule(rule);
941
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
942
+ const fieldData = getOption(fields, rule.field);
943
+ return ruleProcessor(rule, {
944
+ ...options,
945
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
946
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
947
+ fieldData
948
+ });
949
+ }).filter(Boolean).join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ");
950
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "$not" : ""}(`, ")"] : ["", ""];
951
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
952
+ };
953
+ return processRuleGroup(ruleGroup, true);
954
+ };
955
+
956
+ //#endregion
957
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorJsonLogic.ts
958
+ /**
959
+ * Rule group processor used by {@link formatQuery} for "jsonlogic" format.
960
+ *
961
+ * @group Export
962
+ */
963
+ const defaultRuleGroupProcessorJsonLogic = (ruleGroup, options) => {
964
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
965
+ const query = convertFromIC(ruleGroup);
966
+ const processRuleGroup = (rg, _outermost) => {
967
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return false;
968
+ const processedRules = rg.rules.map((rule) => {
969
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
970
+ const [validationResult, fieldValidator] = validateRule(rule);
971
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return false;
972
+ const fieldData = getOption(fields, rule.field);
973
+ return ruleProcessor(rule, {
974
+ ...options,
975
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
976
+ fieldData
977
+ });
978
+ }).filter(Boolean);
979
+ if (processedRules.length === 0) return false;
980
+ const jsonRuleGroup = { [rg.combinator]: processedRules };
981
+ return rg.not ? { "!": jsonRuleGroup } : jsonRuleGroup;
982
+ };
983
+ return processRuleGroup(query, true);
984
+ };
985
+
986
+ //#endregion
987
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorLDAP.ts
988
+ /**
989
+ * Rule group processor used by {@link formatQuery} for "ldap" format.
990
+ *
991
+ * @group Export
992
+ */
993
+ const defaultRuleGroupProcessorLDAP = (ruleGroup, options) => {
994
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
995
+ const query = convertFromIC(ruleGroup);
996
+ const processRuleGroup = (rg, outermost) => {
997
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
998
+ const rules = rg.rules.map((rule) => {
999
+ if (isRuleGroup(rule)) return processRuleGroup(rule);
1000
+ const [validationResult, fieldValidator] = validateRule(rule);
1001
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1002
+ const fieldData = getOption(fields, rule.field);
1003
+ return ruleProcessor(rule, {
1004
+ ...options,
1005
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1006
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
1007
+ fieldData
1008
+ });
1009
+ }).filter(Boolean);
1010
+ const expression = rules.join("");
1011
+ const [notPrefix, notSuffix] = rg.not ? ["(!", ")"] : ["", ""];
1012
+ const [prefix, suffix] = rules.length > 1 ? [`${notPrefix}(${rg.combinator === "or" ? "|" : "&"}`, `)${notSuffix}`] : [notPrefix, notSuffix];
1013
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
1014
+ };
1015
+ return processRuleGroup(query, true);
1016
+ };
1017
+
1018
+ //#endregion
1019
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorMongoDB.ts
1020
+ const isBracketed = (str) => str.startsWith("{") && str.endsWith("}");
1021
+ /**
1022
+ * Rule group processor used by {@link formatQuery} for "mongodb" format.
1023
+ *
1024
+ * Note that the "mongodb" format is deprecated in favor of the "mongodb_query" format.
1025
+ *
1026
+ * @group Export
1027
+ */
1028
+ const defaultRuleGroupProcessorMongoDB = (ruleGroup, options, meta) => {
1029
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1030
+ const processRuleGroup = (rg, outermost) => {
1031
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
1032
+ const combinator = `"$${lc(rg.combinator)}"`;
1033
+ let hasChildRules = false;
1034
+ const expressions = rg.rules.map((rule) => {
1035
+ if (isRuleGroup(rule)) {
1036
+ const processedRuleGroup = processRuleGroup(rule);
1037
+ if (processedRuleGroup) {
1038
+ hasChildRules = true;
1039
+ return isBracketed(processedRuleGroup) ? processedRuleGroup : `{${processedRuleGroup}}`;
1040
+ }
1041
+ return "";
1042
+ }
1043
+ const [validationResult, fieldValidator] = validateRule(rule);
1044
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1045
+ const fieldData = getOption(fields, rule.field);
1046
+ return ruleProcessor(rule, {
1047
+ ...options,
1048
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1049
+ fieldData
1050
+ }, meta);
1051
+ }).filter(Boolean);
1052
+ return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : `${combinator}:[${expressions.join(",")}]` : fallbackExpression;
1053
+ };
1054
+ const processedQuery = processRuleGroup(convertFromIC(ruleGroup), true);
1055
+ return isBracketed(processedQuery) ? processedQuery : `{${processedQuery}}`;
1056
+ };
1057
+
1058
+ //#endregion
1059
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorNL.ts
1060
+ /**
1061
+ * Rule group processor used by {@link formatQuery} for "natural_language" format.
1062
+ *
1063
+ * @group Export
1064
+ */
1065
+ const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
1066
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, translations, validateRule, validationMap } = options;
1067
+ const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
1068
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
1069
+ const rg2 = isRuleGroupTypeIC(rg) && rg.rules.some((r) => typeof r === "string" && lc(r) === "xor") ? convertFromIC(rg) : rg;
1070
+ const processedRules = rg2.rules.map((rule) => {
1071
+ if (typeof rule === "string") return `, ${translations[rule] ?? rule} `;
1072
+ if (isRuleGroup(rule)) return processRuleGroup(rule, rg2.rules.length === 1 && !(rg2.not || /^xor$/i.test(rg2.combinator ?? "")));
1073
+ const [validationResult, fieldValidator] = validateRule(rule);
1074
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1075
+ const escapeQuotes = (rule.valueSource ?? "value") === "value";
1076
+ const fieldData = getOption(fields, rule.field);
1077
+ return ruleProcessor(rule, {
1078
+ ...options,
1079
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1080
+ escapeQuotes,
1081
+ fieldData
1082
+ });
1083
+ });
1084
+ if (processedRules.length === 0) return fallbackExpression;
1085
+ const isXOR = lc(rg2.combinator ?? "") === "xor";
1086
+ const combinator = isXOR ? rg2.combinator.slice(1) : rg2.combinator;
1087
+ const mustWrap = rg2.not || !outermostOrLonelyInGroup || isXOR && processedRules.length > 1;
1088
+ const [prefixTL, suffixTL] = ["groupPrefix", "groupSuffix"].map((key) => rg2.not ? isXOR ? getNLTranslataion(key, translations, ["not", "xor"]) : getNLTranslataion(key, translations, ["not"]) : isXOR ? getNLTranslataion(key, translations, ["xor"]) : getNLTranslataion(key, translations));
1089
+ const prefix = mustWrap ? `${prefixTL} (`.trim() : "";
1090
+ const suffix = mustWrap ? `) ${suffixTL}`.trim() : "";
1091
+ return `${prefix}${processedRules.filter(Boolean).join(isRuleGroupType(rg2) ? `, ${translations[combinator] ?? combinator} ` : "")}${suffix}`;
1092
+ };
1093
+ return processRuleGroup(ruleGroup, true);
1094
+ };
1095
+
1096
+ //#endregion
1097
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorParameterized.ts
1098
+ /**
1099
+ * Rule group processor used by {@link formatQuery} for "parameterized" and
1100
+ * "parameterized_named" formats.
1101
+ *
1102
+ * @group Export
1103
+ */
1104
+ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
1105
+ const { format, fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1106
+ const parameterized = format === "parameterized";
1107
+ const params = [];
1108
+ const paramsNamed = {};
1109
+ const fieldParams = /* @__PURE__ */ new Map();
1110
+ const getNextNamedParam = (field) => {
1111
+ if (!fieldParams.has(field)) fieldParams.set(field, /* @__PURE__ */ new Set());
1112
+ const nextNamedParam = `${field}_${fieldParams.get(field).size + 1}`;
1113
+ fieldParams.get(field).add(nextNamedParam);
1114
+ return nextNamedParam;
1115
+ };
1116
+ const processRule = (rule) => {
1117
+ const [validationResult, fieldValidator] = validateRule(rule);
1118
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1119
+ const fieldData = getOption(fields, rule.field);
1120
+ const fieldParamNames = Object.fromEntries([...fieldParams.entries()].map(([f, s]) => [f, [...s]]));
1121
+ const processedRule = ruleProcessor(rule, {
1122
+ ...options,
1123
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1124
+ getNextNamedParam,
1125
+ fieldParamNames,
1126
+ fieldData
1127
+ }, { processedParams: params });
1128
+ if (!isPojo(processedRule)) return "";
1129
+ const { sql, params: customParams } = processedRule;
1130
+ if (typeof sql !== "string" || !sql) return "";
1131
+ // istanbul ignore else
1132
+ if (format === "parameterized" && Array.isArray(customParams)) params.push(...customParams);
1133
+ else if (format === "parameterized_named" && isPojo(customParams)) {
1134
+ Object.assign(paramsNamed, customParams);
1135
+ for (const p of Object.keys(customParams)) fieldParams.get(rule.field)?.add(p);
1136
+ }
1137
+ return sql;
1138
+ };
1139
+ const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
1140
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
1141
+ const processedRules = rg.rules.map((rule) => {
1142
+ if (typeof rule === "string") return rule;
1143
+ if (isRuleGroup(rule)) return processRuleGroup(rule, rg.rules.length === 1);
1144
+ return processRule(rule);
1145
+ }).filter(Boolean);
1146
+ if (processedRules.length === 0) return fallbackExpression;
1147
+ return `${rg.not ? "NOT " : ""}(${processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ")})`;
1148
+ };
1149
+ if (parameterized) return {
1150
+ sql: processRuleGroup(ruleGroup, true),
1151
+ params
1152
+ };
1153
+ return {
1154
+ sql: processRuleGroup(ruleGroup, true),
1155
+ params: paramsNamed
1156
+ };
1157
+ };
1158
+
1159
+ //#endregion
1160
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorPrisma.ts
1161
+ /**
1162
+ * Default fallback object used by {@link formatQuery} for "prisma" format.
1163
+ *
1164
+ * @group Export
1165
+ */
1166
+ const prismaFallback = {};
1167
+ /**
1168
+ * Rule group processor used by {@link formatQuery} for "prisma" format.
1169
+ *
1170
+ * @group Export
1171
+ */
1172
+ const defaultRuleGroupProcessorPrisma = (ruleGroup, options) => {
1173
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1174
+ const processRuleGroup = (rg, outermost) => {
1175
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? prismaFallback : void 0;
1176
+ const combinator = rg.combinator.toUpperCase();
1177
+ let hasChildRules = false;
1178
+ const expressions = rg.rules.map((rule) => {
1179
+ if (isRuleGroup(rule)) {
1180
+ const processedRuleGroup = processRuleGroup(rule);
1181
+ if (processedRuleGroup) {
1182
+ hasChildRules = true;
1183
+ return processedRuleGroup;
1184
+ }
1185
+ return;
1186
+ }
1187
+ const [validationResult, fieldValidator] = validateRule(rule);
1188
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
1189
+ const fieldData = getOption(fields, rule.field);
1190
+ return ruleProcessor(rule, {
1191
+ ...options,
1192
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1193
+ fieldData
1194
+ });
1195
+ }).filter(Boolean);
1196
+ return expressions.length > 0 ? expressions.length === 1 && !hasChildRules ? expressions[0] : { [combinator]: expressions } : prismaFallback;
1197
+ };
1198
+ const result = processRuleGroup(convertFromIC(ruleGroup), true);
1199
+ return ruleGroup.not ? { NOT: result } : result;
1200
+ };
1201
+
1202
+ //#endregion
1203
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSequelize.ts
1204
+ /**
1205
+ * Rule group processor used by {@link formatQuery} for "sequelize" format.
1206
+ *
1207
+ * @group Export
1208
+ */
1209
+ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
1210
+ // istanbul ignore next
1211
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap, context = {} } = options;
1212
+ const { sequelizeOperators: Op } = context;
1213
+ if (!Op) return;
1214
+ const processRuleGroup = (rg, _outermost) => {
1215
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return;
1216
+ const combinator = rg.combinator.toUpperCase();
1217
+ let hasChildRules = false;
1218
+ const expressions = rg.rules.map((rule) => {
1219
+ if (isRuleGroup(rule)) {
1220
+ const processedRuleGroup = processRuleGroup(rule);
1221
+ if (processedRuleGroup) {
1222
+ hasChildRules = true;
1223
+ return processedRuleGroup;
1224
+ }
1225
+ return;
1226
+ }
1227
+ const [validationResult, fieldValidator] = validateRule(rule);
1228
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
1229
+ const fieldData = getOption(fields, rule.field);
1230
+ return ruleProcessor(rule, {
1231
+ ...options,
1232
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1233
+ fieldData
1234
+ });
1235
+ }).filter(Boolean);
1236
+ if (expressions.length === 0) return;
1237
+ const result = expressions.length === 1 && !hasChildRules ? expressions[0] : { [lc(combinator) === "or" ? Op.or : Op.and]: expressions };
1238
+ return rg.not ? { [Op.not]: result } : result;
1239
+ };
1240
+ return processRuleGroup(convertFromIC(ruleGroup), true);
1241
+ };
1242
+
1243
+ //#endregion
1244
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts
1245
+ /**
1246
+ * Default rule processor used by {@link formatQuery} for "sql" format.
1247
+ *
1248
+ * @group Export
1249
+ */
1250
+ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
1251
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1252
+ const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
1253
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
1254
+ const processedRules = rg.rules.map((rule) => {
1255
+ if (typeof rule === "string") return rule;
1256
+ if (isRuleGroup(rule)) return processRuleGroup(rule, rg.rules.length === 1);
1257
+ const [validationResult, fieldValidator] = validateRule(rule);
1258
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return "";
1259
+ const escapeQuotes = (rule.valueSource ?? "value") === "value";
1260
+ const fieldData = getOption(fields, rule.field);
1261
+ return ruleProcessor(rule, {
1262
+ ...options,
1263
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1264
+ escapeQuotes,
1265
+ fieldData
1266
+ });
1267
+ }).filter(Boolean);
1268
+ if (processedRules.length === 0) return fallbackExpression;
1269
+ return `${rg.not ? "NOT " : ""}(${processedRules.join(isRuleGroupType(rg) ? ` ${rg.combinator} ` : " ")})`;
1270
+ };
1271
+ return processRuleGroup(ruleGroup, true);
1272
+ };
1273
+
1274
+ //#endregion
1275
+ //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
1276
+ const rangeOperatorMap = {
1277
+ "<": "lt",
1278
+ "<=": "lte",
1279
+ ">": "gt",
1280
+ ">=": "gte"
1281
+ };
1282
+ const negateIfNotOp$1 = (op, elasticSearchRule) => op.startsWith("not") || op.startsWith("doesnot") ? { bool: { must_not: elasticSearchRule } } : elasticSearchRule;
1283
+ const escapeSQ = (s) => s?.replace(/('|\\)/g, `\\$1`);
1284
+ const textFunctionMap = {
1285
+ beginswith: "startsWith",
1286
+ doesnotbeginwith: "startsWith",
1287
+ doesnotcontain: "contains",
1288
+ doesnotendwith: "endsWith",
1289
+ endswith: "endsWith"
1290
+ };
1291
+ const getTextScript = (f, o, v) => {
1292
+ const script = `doc['${f}'].value.${textFunctionMap[o] ?? o}(doc['${v}'].value)`;
1293
+ return o.startsWith("d") ? `!${script}` : script;
1294
+ };
1295
+ const valueRenderer = (v, parseNumbers) => typeof v === "boolean" ? v : shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v;
1296
+ /**
1297
+ * Default rule processor used by {@link formatQuery} for "elasticsearch" format.
1298
+ *
1299
+ * @group Export
1300
+ */
1301
+ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
1302
+ const { field, operator, value, valueSource } = rule;
1303
+ const { parseNumbers, preserveValueOrder } = options;
1304
+ const operatorLC = lc(operator);
1305
+ if (processMatchMode(rule)) return false;
1306
+ if (valueSource === "field") {
1307
+ if (toArray(value).some((v) => typeof v !== "string")) return false;
1308
+ const fieldForScript = escapeSQ(field);
1309
+ switch (operatorLC) {
1310
+ case "=":
1311
+ case "!=":
1312
+ case ">":
1313
+ case ">=":
1314
+ case "<":
1315
+ case "<=": {
1316
+ const operatorForScript = operatorLC === "=" ? "==" : operatorLC;
1317
+ const valueForScript = escapeSQ(value);
1318
+ return valueForScript ? { bool: { filter: { script: { script: `doc['${fieldForScript}'].value ${operatorForScript} doc['${valueForScript}'].value` } } } } : false;
1319
+ }
1320
+ case "in":
1321
+ case "notin": {
1322
+ const valueAsArray = toArray(value);
1323
+ if (valueAsArray.length > 0) {
1324
+ const arr = valueAsArray.map((v) => ({ bool: { filter: { script: { script: `doc['${fieldForScript}'].value == doc['${v}'].value` } } } }));
1325
+ return { bool: operatorLC === "in" ? { should: arr } : { must_not: arr } };
1326
+ }
1327
+ return false;
1328
+ }
1329
+ case "between":
1330
+ case "notbetween": {
1331
+ const valueAsArray = toArray(value);
1332
+ if (valueAsArray.length >= 2 && valueAsArray[0] && valueAsArray[1]) {
1333
+ const script = `doc['${fieldForScript}'].value >= doc['${valueAsArray[0]}'].value && doc['${fieldForScript}'].value <= doc['${valueAsArray[1]}'].value`;
1334
+ return { bool: { filter: { script: { script: operatorLC === "notbetween" ? `!(${script})` : script } } } };
1335
+ }
1336
+ return false;
1337
+ }
1338
+ case "contains":
1339
+ case "doesnotcontain":
1340
+ case "beginswith":
1341
+ case "doesnotbeginwith":
1342
+ case "endswith":
1343
+ case "doesnotendwith": {
1344
+ const valueForScript = escapeSQ(value);
1345
+ if (!valueForScript) return false;
1346
+ return { bool: { filter: { script: { script: getTextScript(fieldForScript, operatorLC, valueForScript) } } } };
1347
+ }
1348
+ }
1349
+ }
1350
+ switch (operatorLC) {
1351
+ case "<":
1352
+ case "<=":
1353
+ case ">":
1354
+ case ">=": return { range: { [field]: { [rangeOperatorMap[operatorLC]]: valueRenderer(value, parseNumbers) } } };
1355
+ case "=": return { term: { [field]: valueRenderer(value, parseNumbers) } };
1356
+ case "!=": return { bool: { must_not: { term: { [field]: valueRenderer(value, parseNumbers) } } } };
1357
+ case "null": return { bool: { must_not: { exists: { field } } } };
1358
+ case "notnull": return { exists: { field } };
1359
+ case "in":
1360
+ case "notin": {
1361
+ const valueAsArray = toArray(value).map((v) => valueRenderer(v, parseNumbers));
1362
+ if (valueAsArray.length > 0) {
1363
+ const arr = valueAsArray.map((v) => ({ term: { [field]: valueRenderer(v, parseNumbers) } }));
1364
+ return { bool: operatorLC === "in" ? { should: arr } : { must_not: arr } };
1365
+ }
1366
+ return false;
1367
+ }
1368
+ case "between":
1369
+ case "notbetween": {
1370
+ const valueAsArray = toArray(value);
1371
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
1372
+ let [first, second] = valueAsArray;
1373
+ const shouldParseNumbers = !(parseNumbers === false);
1374
+ if (shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
1375
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
1376
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
1377
+ if (!preserveValueOrder && secondNum < firstNum) {
1378
+ const tempNum = secondNum;
1379
+ second = firstNum;
1380
+ first = tempNum;
1381
+ } else {
1382
+ first = firstNum;
1383
+ second = secondNum;
1384
+ }
1385
+ }
1386
+ return negateIfNotOp$1(operatorLC, { range: { [field]: {
1387
+ gte: first,
1388
+ lte: second
1389
+ } } });
1390
+ }
1391
+ return false;
1392
+ }
1393
+ case "contains":
1394
+ case "doesnotcontain": return negateIfNotOp$1(operatorLC, { regexp: { [field]: { value: `.*${value}.*` } } });
1395
+ case "beginswith":
1396
+ case "doesnotbeginwith": return negateIfNotOp$1(operatorLC, { regexp: { [field]: { value: `${value}.*` } } });
1397
+ case "endswith":
1398
+ case "doesnotendwith": return negateIfNotOp$1(operatorLC, { regexp: { [field]: { value: `.*${value}` } } });
1399
+ }
1400
+ return false;
1401
+ };
1402
+
1403
+ //#endregion
1404
+ //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
1405
+ const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
1406
+ const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
1407
+ const negate = (clause, negate$1) => negate$1 ? `$not(${clause})` : clause;
1408
+ const escapeStringRegex = (s) => `${s}`.replaceAll(/[/$()*+.?[\\\]^{|}]/g, String.raw`\$&`).replaceAll("-", String.raw`\x2d`);
1409
+ /**
1410
+ * Default rule processor used by {@link formatQuery} for "jsonata" format.
1411
+ *
1412
+ * @group Export
1413
+ */
1414
+ const defaultRuleProcessorJSONata = (rule, options = {}) => {
1415
+ const { field, operator, value, valueSource } = rule;
1416
+ const { escapeQuotes, parseNumbers, preserveValueOrder, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "" } = options;
1417
+ const valueIsField = valueSource === "field";
1418
+ const useBareValue = typeof value === "number" || typeof value === "boolean" || typeof value === "bigint" || shouldRenderAsNumber(value, parseNumbers);
1419
+ const qfn = (f) => getQuotedFieldName(f, {
1420
+ quoteFieldNamesWith,
1421
+ fieldIdentifierSeparator
1422
+ });
1423
+ const matchEval = processMatchMode(rule);
1424
+ if (matchEval === false) return;
1425
+ else if (matchEval) {
1426
+ const { mode, threshold } = matchEval;
1427
+ const totalCount = `$count(${qfn(field)})`;
1428
+ const filteredCount = `$count($filter(${qfn(field)}, function($v) {${defaultRuleGroupProcessorJSONata(transformQuery(value, { ruleProcessor: (r) => ({
1429
+ ...r,
1430
+ field: r.field ? `$v.${r.field}` : "$v"
1431
+ }) }), options)}}))`;
1432
+ switch (mode) {
1433
+ case "all": return `${filteredCount} = ${totalCount}`;
1434
+ case "none": return `${filteredCount} = 0`;
1435
+ case "some": return `${filteredCount} > 0`;
1436
+ case "atleast":
1437
+ case "atmost":
1438
+ case "exactly": {
1439
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
1440
+ if (threshold > 0 && threshold < 1) return `${filteredCount} ${op} (${totalCount} * ${threshold})`;
1441
+ return `${filteredCount} ${op} ${threshold}`;
1442
+ }
1443
+ }
1444
+ }
1445
+ const operatorLC = lc(operator);
1446
+ switch (operatorLC) {
1447
+ case "<":
1448
+ case "<=":
1449
+ case "=":
1450
+ case "!=":
1451
+ case ">":
1452
+ case ">=": return `${qfn(field)} ${operatorLC} ${valueIsField ? qfn(trimIfString(value)) : useBareValue ? trimIfString(value) : quote(value, escapeQuotes)}`;
1453
+ case "contains":
1454
+ case "doesnotcontain": return negate(`$contains(${qfn(field)}, ${valueIsField ? qfn(trimIfString(value)) : quote(value, escapeQuotes)})`, shouldNegate(operatorLC));
1455
+ case "beginswith":
1456
+ case "doesnotbeginwith": return negate(valueIsField ? `$substring(${qfn(field)}, 0, $length(${qfn(trimIfString(value))})) = ${qfn(trimIfString(value))}` : `$contains(${qfn(field)}, /^${escapeStringRegex(value)}/)`, shouldNegate(operatorLC));
1457
+ case "endswith":
1458
+ case "doesnotendwith": return negate(valueIsField ? `$substring(${qfn(field)}, $length(${qfn(field)}) - $length(${qfn(trimIfString(value))})) = ${qfn(trimIfString(value))}` : `$contains(${qfn(field)}, /${escapeStringRegex(value)}$/)`, shouldNegate(operatorLC));
1459
+ case "null": return `${qfn(field)} = null`;
1460
+ case "notnull": return `${qfn(field)} != null`;
1461
+ case "in":
1462
+ case "notin": {
1463
+ const valueAsArray = toArray(value);
1464
+ return negate(`${qfn(field)} in [${valueAsArray.map((val) => valueIsField ? `${qfn(trimIfString(val))}` : shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : quote(val, escapeQuotes)).join(", ")}]`, shouldNegate(operatorLC));
1465
+ }
1466
+ case "between":
1467
+ case "notbetween": {
1468
+ const valueAsArray = toArray(value);
1469
+ if (valueAsArray.length < 2 || nullOrUndefinedOrEmpty(valueAsArray[0]) || nullOrUndefinedOrEmpty(valueAsArray[1])) return "";
1470
+ const [first, second] = valueAsArray;
1471
+ const shouldParseNumbers = !(parseNumbers === false);
1472
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
1473
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
1474
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : first : firstNum;
1475
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : second : secondNum;
1476
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1477
+ const tempNum = secondNum;
1478
+ secondValue = firstNum;
1479
+ firstValue = tempNum;
1480
+ }
1481
+ const renderAsNumbers = shouldRenderAsNumber(first, parseNumbers) && shouldRenderAsNumber(second, parseNumbers);
1482
+ const getValueString = (raw, val) => valueIsField ? qfn(raw) : renderAsNumbers ? val : quote(val, escapeQuotes);
1483
+ const expression = `${qfn(field)} >= ${getValueString(first, firstValue)} and ${qfn(field)} <= ${getValueString(second, secondValue)}`;
1484
+ return operatorLC === "between" ? `(${expression})` : negate(expression, true);
1485
+ }
1486
+ }
1487
+ return "";
1488
+ };
1489
+
1490
+ //#endregion
1491
+ //#region src/utils/formatQuery/defaultRuleProcessorJsonLogic.ts
1492
+ const convertOperator = (op) => op.replace(/^(=)$/, "$1=").replace(/^notnull$/i, "!=").replace(/^null$/i, "==");
1493
+ const negateIfNotOp = (op, jsonRule) => op.startsWith("not") || op.startsWith("doesnot") ? { "!": jsonRule } : jsonRule;
1494
+ /**
1495
+ * Default rule processor used by {@link formatQuery} for "jsonlogic" format.
1496
+ *
1497
+ * @group Export
1498
+ */
1499
+ const defaultRuleProcessorJsonLogic = (rule, options = {}) => {
1500
+ const { field, operator, value, valueSource } = rule;
1501
+ const { parseNumbers, preserveValueOrder } = options;
1502
+ const valueIsField = valueSource === "field";
1503
+ const fieldObject = { var: field };
1504
+ const fieldOrNumberRenderer = (v) => valueIsField ? { var: `${v}` } : shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v;
1505
+ const matchEval = processMatchMode(rule);
1506
+ if (matchEval === false) return false;
1507
+ else if (matchEval) {
1508
+ const { mode, threshold } = matchEval;
1509
+ switch (mode) {
1510
+ case "all":
1511
+ case "none":
1512
+ case "some": return { [mode]: [{ var: field }, value.rules.length === 1 && !isRuleGroup(value.rules[0]) ? defaultRuleProcessorJsonLogic(value.rules[0], options) : defaultRuleGroupProcessorJsonLogic(value, options)] };
1513
+ case "atleast":
1514
+ case "atmost":
1515
+ case "exactly": {
1516
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "==";
1517
+ const filteredCount = { reduce: [
1518
+ { filter: [{ var: field }, value.rules.length === 1 && !isRuleGroup(value.rules[0]) ? defaultRuleProcessorJsonLogic(value.rules[0], options) : defaultRuleGroupProcessorJsonLogic(value, options)] },
1519
+ { "+": [1, { var: "accumulator" }] },
1520
+ 0
1521
+ ] };
1522
+ if (threshold > 0 && threshold < 1) {
1523
+ const totalCount = { reduce: [
1524
+ { var: field },
1525
+ { "+": [1, { var: "accumulator" }] },
1526
+ 0
1527
+ ] };
1528
+ return { [op]: [filteredCount, { "*": [totalCount, threshold] }] };
1529
+ }
1530
+ return { [op]: [filteredCount, threshold] };
1531
+ }
1532
+ }
1533
+ }
1534
+ const operatorLC = lc(operator);
1535
+ switch (operatorLC) {
1536
+ case "<":
1537
+ case "<=":
1538
+ case "=":
1539
+ case "!=":
1540
+ case ">":
1541
+ case ">=": return { [convertOperator(operatorLC)]: [fieldObject, fieldOrNumberRenderer(value)] };
1542
+ case "null":
1543
+ case "notnull": return { [`${operatorLC === "notnull" ? "!" : "="}=`]: [fieldObject, null] };
1544
+ case "in":
1545
+ case "notin": {
1546
+ const valueAsArray = toArray(value).map((v) => fieldOrNumberRenderer(v));
1547
+ return negateIfNotOp(operatorLC, { in: [fieldObject, valueAsArray] });
1548
+ }
1549
+ case "between":
1550
+ case "notbetween": {
1551
+ const valueAsArray = toArray(value);
1552
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
1553
+ let [first, second] = valueAsArray;
1554
+ const shouldParseNumbers = !(parseNumbers === false);
1555
+ if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
1556
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
1557
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
1558
+ if (!preserveValueOrder && secondNum < firstNum) {
1559
+ const tempNum = secondNum;
1560
+ second = firstNum;
1561
+ first = tempNum;
1562
+ } else {
1563
+ first = firstNum;
1564
+ second = secondNum;
1565
+ }
1566
+ } else if (valueIsField) {
1567
+ first = { var: first };
1568
+ second = { var: second };
1569
+ }
1570
+ return negateIfNotOp(operatorLC, { "<=": [
1571
+ first,
1572
+ fieldObject,
1573
+ second
1574
+ ] });
1575
+ }
1576
+ return false;
1577
+ }
1578
+ case "contains":
1579
+ case "doesnotcontain": {
1580
+ const jsonRule = { in: [fieldOrNumberRenderer(value), fieldObject] };
1581
+ return negateIfNotOp(operatorLC, jsonRule);
1582
+ }
1583
+ case "beginswith":
1584
+ case "doesnotbeginwith": {
1585
+ const jsonRule = { startsWith: [fieldObject, fieldOrNumberRenderer(value)] };
1586
+ return negateIfNotOp(operatorLC, jsonRule);
1587
+ }
1588
+ case "endswith":
1589
+ case "doesnotendwith": {
1590
+ const jsonRule = { endsWith: [fieldObject, fieldOrNumberRenderer(value)] };
1591
+ return negateIfNotOp(operatorLC, jsonRule);
1592
+ }
1593
+ }
1594
+ return false;
1595
+ };
1596
+
1597
+ //#endregion
1598
+ //#region src/utils/formatQuery/defaultRuleProcessorLDAP.ts
1599
+ const negateIf = (clause, negate$1) => negate$1 ? `(!${clause})` : `${clause}`;
1600
+ const ldapEscape = (s) => `${trimIfString(s)}`.replaceAll(/[()&|=<>~*\\/]/g, (m) => `\\${m.codePointAt(0).toString(16)}`);
1601
+ /**
1602
+ * Default rule processor used by {@link formatQuery} for "ldap" format.
1603
+ *
1604
+ * @group Export
1605
+ */
1606
+ const defaultRuleProcessorLDAP = (rule, options = {}) => {
1607
+ const { field, operator, value, valueSource } = rule;
1608
+ const { preserveValueOrder } = options;
1609
+ const operatorLC = lc(operator);
1610
+ if (valueSource === "field" || nullOrUndefinedOrEmpty(value) && operatorLC !== "null" && operatorLC !== "notnull" || processMatchMode(rule)) return "";
1611
+ switch (operatorLC) {
1612
+ case "=":
1613
+ case "!=": return negateIf(`(${field}=${ldapEscape(value)})`, operatorLC === "!=");
1614
+ case ">":
1615
+ case ">=": return `(${field}>=${ldapEscape(value)})`;
1616
+ case "<":
1617
+ case "<=": return `(${field}<=${ldapEscape(value)})`;
1618
+ case "contains":
1619
+ case "doesnotcontain": return negateIf(`(${field}=*${ldapEscape(value)}*)`, operatorLC === "doesnotcontain");
1620
+ case "beginswith":
1621
+ case "doesnotbeginwith": return negateIf(`(${field}=${ldapEscape(value)}*)`, operatorLC === "doesnotbeginwith");
1622
+ case "endswith":
1623
+ case "doesnotendwith": return negateIf(`(${field}=*${ldapEscape(value)})`, operatorLC === "doesnotendwith");
1624
+ case "null":
1625
+ case "notnull": return negateIf(`(${field}=*)`, operatorLC === "notnull");
1626
+ case "in":
1627
+ case "notin": {
1628
+ const valueAsArray = toArray(value);
1629
+ return negateIf(`(|${valueAsArray.map((val) => `(${field}=${ldapEscape(val)})`).join("")})`, operatorLC === "notin");
1630
+ }
1631
+ case "between":
1632
+ case "notbetween": {
1633
+ const valueAsArray = toArray(value);
1634
+ if (valueAsArray.length < 2 || nullOrUndefinedOrEmpty(valueAsArray[0]) || nullOrUndefinedOrEmpty(valueAsArray[1])) return "";
1635
+ const [first, second] = valueAsArray;
1636
+ const firstNum = shouldRenderAsNumber(first, true) ? parseNumber(first, { parseNumbers: true }) : NaN;
1637
+ const secondNum = shouldRenderAsNumber(second, true) ? parseNumber(second, { parseNumbers: true }) : NaN;
1638
+ let firstValue = Number.isNaN(firstNum) ? first : firstNum;
1639
+ let secondValue = Number.isNaN(secondNum) ? second : secondNum;
1640
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1641
+ const tempNum = secondNum;
1642
+ secondValue = firstNum;
1643
+ firstValue = tempNum;
1644
+ }
1645
+ return negateIf(`(&(${field}>=${ldapEscape(firstValue)})(${field}<=${ldapEscape(secondValue)}))`, operatorLC === "notbetween");
1646
+ }
1647
+ }
1648
+ // istanbul ignore next
1649
+ return "";
1650
+ };
1651
+
1652
+ //#endregion
1653
+ //#region src/utils/formatQuery/defaultValueProcessorNL.ts
1654
+ const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
1655
+ /**
1656
+ * Default value processor used by {@link formatQuery} for "natural_language" format.
1657
+ *
1658
+ * @group Export
1659
+ */
1660
+ const defaultValueProcessorNL = (rule, opts = {}) => {
1661
+ const { escapeQuotes, fields, parseNumbers, quoteFieldNamesWith, quoteValuesWith, fieldIdentifierSeparator, translations } = opts;
1662
+ const valueIsField = rule.valueSource === "field";
1663
+ const operatorLowerCase = lc(rule.operator);
1664
+ const quoteChar = quoteValuesWith || "'";
1665
+ const quoteValue = (v) => `${quoteChar}${v}${quoteChar}`;
1666
+ const escapeValue = (v) => escapeStringValueQuotes(v, quoteChar, escapeQuotes);
1667
+ const wrapAndEscape = (v) => quoteValue(escapeValue(v));
1668
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
1669
+ quoteFieldNamesWith,
1670
+ fieldIdentifierSeparator
1671
+ });
1672
+ const t = translations ?? ( /* istanbul ignore next */ {});
1673
+ const orTL = t.or ?? "or";
1674
+ const trueTL = t.true ?? "true";
1675
+ const falseTL = t.false ?? "false";
1676
+ switch (operatorLowerCase) {
1677
+ case "null":
1678
+ case "notnull": return "";
1679
+ case "between":
1680
+ case "notbetween": {
1681
+ if (!valueIsField) return defaultValueProcessorByRule(rule, opts);
1682
+ const valueAsArray = toArray(rule.value, { retainEmptyStrings: true }).slice(0, 2).map((v) => wrapFieldName(getOption(fields ?? [], v)?.label ?? v));
1683
+ if (valueAsArray.length < 2 || !isValidValue(valueAsArray[0]) || !isValidValue(valueAsArray[1])) return "";
1684
+ return defaultValueProcessorByRule({
1685
+ ...rule,
1686
+ value: valueAsArray
1687
+ }, opts);
1688
+ }
1689
+ case "in":
1690
+ case "notin": {
1691
+ const valueAsArray = toArray(rule.value);
1692
+ if (valueAsArray.length === 0) return "";
1693
+ const valStringArray = valueAsArray.map((v) => valueIsField ? wrapFieldName(getOption(fields ?? [], v)?.label ?? v) : shouldRenderAsNumber(v, parseNumbers) ? `${trimIfString(v)}` : `${wrapAndEscape(v)}`);
1694
+ return `${valStringArray.slice(0, -1).join(", ")}${valStringArray.length > 2 ? "," : ""} ${orTL} ${valStringArray.at(-1)}`;
1695
+ }
1696
+ }
1697
+ if (typeof rule.value === "boolean") return rule.value ? trueTL : falseTL;
1698
+ return valueIsField ? wrapFieldName(getOption(fields ?? [], rule.value)?.label ?? rule.value) : shouldRenderAsNumber(rule.value, parseNumbers) ? `${trimIfString(rule.value)}` : `${wrapAndEscape(rule.value)}`;
1699
+ };
1700
+
1701
+ //#endregion
1702
+ //#region src/utils/formatQuery/defaultRuleProcessorNL.ts
1703
+ /**
1704
+ * Default operator map used by {@link formatQuery} for "natural_language" format.
1705
+ *
1706
+ * @group Export
1707
+ */
1708
+ const defaultExportOperatorMap = {
1709
+ "=": ["is", "is the same as the value in"],
1710
+ "!=": ["is not", "is not the same as the value in"],
1711
+ "<": ["is less than", "is less than the value in"],
1712
+ ">": ["is greater than", "is greater than the value in"],
1713
+ "<=": ["is less than or equal to", "is less than or equal to the value in"],
1714
+ ">=": ["is greater than or equal to", "is greater than or equal to the value in"],
1715
+ contains: ["contains", "contains the value in"],
1716
+ beginswith: ["starts with", "starts with the value in"],
1717
+ endswith: ["ends with", "ends with the value in"],
1718
+ doesnotcontain: ["does not contain", "does not contain the value in"],
1719
+ doesnotbeginwith: ["does not start with", "does not start with the value in"],
1720
+ doesnotendwith: ["does not end with", "does not end with the value in"],
1721
+ null: "is null",
1722
+ notnull: "is not null",
1723
+ in: ["is one of the values", "is the same as a value in"],
1724
+ notin: ["is not one of the values", "is not the same as any value in"],
1725
+ between: ["is between", "is between the values in"],
1726
+ notbetween: ["is not between", "is not between the values in"]
1727
+ };
1728
+ /* istanbul ignore next */
1729
+ const defaultGetOperators = () => [];
1730
+ /**
1731
+ * Default operator processor used by {@link formatQuery} for "natural_language" format.
1732
+ *
1733
+ * @group Export
1734
+ */
1735
+ const defaultOperatorProcessorNL = (rule, opts = {}) => {
1736
+ const { field, operator, valueSource = "value" } = rule;
1737
+ // istanbul ignore next
1738
+ const { getOperators = defaultGetOperators, operatorMap: operatorMapParam = defaultExportOperatorMap } = opts;
1739
+ const mapOperatorMap = new Map(Object.entries(defaultExportOperatorMap));
1740
+ for (const [key, value] of Object.entries(operatorMapParam)) mapOperatorMap.set(lc(key), value);
1741
+ const operatorMap = Object.fromEntries(mapOperatorMap);
1742
+ const { value: operatorNL, label } = getOption(toFullOptionList(getOperators(field, { fieldData: opts.fieldData ?? {
1743
+ name: field,
1744
+ value: field,
1745
+ label: field
1746
+ } }) ?? []), operator) ?? {
1747
+ name: operator,
1748
+ value: operator,
1749
+ label: operator
1750
+ };
1751
+ const operatorTL = operatorMap[operatorNL] ?? operatorMap[lc(operatorNL)] ?? [label, label];
1752
+ return typeof operatorTL === "string" ? operatorTL : operatorTL[valueSource === "field" ? 1 : 0];
1753
+ };
1754
+ /**
1755
+ * Default rule processor used by {@link formatQuery} for "natural_language" format.
1756
+ *
1757
+ * @group Export
1758
+ */
1759
+ const defaultRuleProcessorNL = (rule, opts) => {
1760
+ const { field, operator } = rule;
1761
+ // istanbul ignore next
1762
+ const { fieldData, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorNL, valueProcessor = defaultValueProcessorNL, concatOperator = "||", wordOrder = "SVO" } = opts ?? ( /* istanbul ignore next */ {});
1763
+ const processedField = getQuotedFieldName(fieldData?.label ?? field, {
1764
+ quoteFieldNamesWith,
1765
+ fieldIdentifierSeparator
1766
+ });
1767
+ const matchEval = processMatchMode(rule);
1768
+ if (matchEval === false) return "";
1769
+ else if (matchEval) {
1770
+ const { mode, threshold } = matchEval;
1771
+ const nestedArrayFilter = defaultRuleGroupProcessorNL(rule.value, {
1772
+ ...opts,
1773
+ fields: toFullOptionList(fieldData?.subproperties ?? [])
1774
+ });
1775
+ const hsp = (fieldData?.subproperties?.length ?? 0) > 0;
1776
+ switch (mode) {
1777
+ case "all": return `(${hsp ? "for " : ""}every item in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
1778
+ case "none": return `(${hsp ? "for " : ""}no item in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
1779
+ case "some": return `(${hsp ? "for " : ""}at least one item in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
1780
+ case "atleast":
1781
+ case "atmost":
1782
+ case "exactly": {
1783
+ const mm = mode.replace("at", "at ");
1784
+ if (threshold > 0 && threshold < 1) return `(${hsp ? "for " : ""}${mm} ${threshold * 100}% of the items in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
1785
+ return `(${hsp ? "for " : ""}${mm} ${threshold} of the items in ${processedField}${hsp ? "," : ""} ${nestedArrayFilter})`;
1786
+ }
1787
+ }
1788
+ }
1789
+ const value = valueProcessor(rule, {
1790
+ ...opts,
1791
+ quoteFieldNamesWith,
1792
+ fieldIdentifierSeparator,
1793
+ quoteValuesWith,
1794
+ concatOperator
1795
+ });
1796
+ const operatorLC = lc(operator);
1797
+ if ((operatorLC === "in" || operatorLC === "notin" || operatorLC === "between" || operatorLC === "notbetween") && !value) return "";
1798
+ const processedOperator = operatorProcessor(rule, opts);
1799
+ const wordOrderMap = {
1800
+ S: processedField,
1801
+ V: processedOperator,
1802
+ O: value
1803
+ };
1804
+ return normalizeConstituentWordOrder(wordOrder).map((term) => `${wordOrderMap[term]}`).join(" ").trim();
1805
+ };
1806
+
1807
+ //#endregion
1808
+ //#region src/utils/formatQuery/defaultRuleProcessorSQL.ts
1809
+ /**
1810
+ * Default operator processor used by {@link formatQuery} for "sql" and "parameterized*" formats.
1811
+ *
1812
+ * @group Export
1813
+ */
1814
+ const defaultOperatorProcessorSQL = (rule) => lc(mapSQLOperator(rule.operator));
1815
+ /**
1816
+ * Default rule processor used by {@link formatQuery} for "sql" format.
1817
+ *
1818
+ * @group Export
1819
+ */
1820
+ const defaultRuleProcessorSQL = (rule, opts = {}) => {
1821
+ const { quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorSQL, valueProcessor = defaultValueProcessorByRule, concatOperator = "||" } = opts;
1822
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
1823
+ quoteFieldNamesWith,
1824
+ fieldIdentifierSeparator
1825
+ });
1826
+ const ruleField = wrapFieldName(rule.field);
1827
+ const matchEval = processMatchMode(rule);
1828
+ if (matchEval === false) return;
1829
+ else if (matchEval) {
1830
+ if (opts?.preset !== "postgresql") return "";
1831
+ const { mode, threshold } = matchEval;
1832
+ const arrayElementAlias = "elem_alias";
1833
+ const nestedArrayFilter = defaultRuleGroupProcessorSQL(transformQuery(rule.value, { ruleProcessor: (r) => ({
1834
+ ...r,
1835
+ field: arrayElementAlias
1836
+ }) }), opts);
1837
+ switch (mode) {
1838
+ case "all": return `(select count(*) from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter}) = array_length(${ruleField}, 1)`;
1839
+ case "none": return `not exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter})`;
1840
+ case "some": return `exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter})`;
1841
+ case "atleast":
1842
+ case "atmost":
1843
+ case "exactly": {
1844
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
1845
+ return `(select count(*)${threshold > 0 && threshold < 1 ? ` / array_length(${ruleField}, 1)` : ""} from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedArrayFilter}) ${op} ${threshold}`;
1846
+ }
1847
+ }
1848
+ }
1849
+ const value = valueProcessor(rule, {
1850
+ ...opts,
1851
+ quoteFieldNamesWith,
1852
+ fieldIdentifierSeparator,
1853
+ quoteValuesWith,
1854
+ concatOperator
1855
+ });
1856
+ const operator = operatorProcessor(rule, opts);
1857
+ const operatorLowerCase = lc(operator);
1858
+ if ((operatorLowerCase === "in" || operatorLowerCase === "not in" || operatorLowerCase === "between" || operatorLowerCase === "not between") && !value) return "";
1859
+ return `${ruleField} ${operator} ${value}`.trim();
1860
+ };
1861
+
1862
+ //#endregion
1863
+ //#region src/utils/formatQuery/defaultRuleProcessorParameterized.ts
1864
+ /**
1865
+ * Default rule processor used by {@link formatQuery} for "parameterized" and
1866
+ * "parameterized_named" formats.
1867
+ *
1868
+ * @group Export
1869
+ */
1870
+ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
1871
+ // istanbul ignore next
1872
+ const { fieldData, format, getNextNamedParam, parseNumbers, paramPrefix, paramsKeepPrefix, numberedParams, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator, concatOperator, operatorProcessor = defaultOperatorProcessorSQL, valueProcessor = defaultValueProcessorByRule } = opts ?? {};
1873
+ const { processedParams = [] } = meta ?? {};
1874
+ const parameterized = format === "parameterized";
1875
+ const params = [];
1876
+ const paramsNamed = {};
1877
+ const finalize = (sql) => parameterized ? {
1878
+ sql,
1879
+ params
1880
+ } : {
1881
+ sql,
1882
+ params: paramsNamed
1883
+ };
1884
+ const wrapFieldName = (v) => getQuotedFieldName(v, {
1885
+ quoteFieldNamesWith,
1886
+ fieldIdentifierSeparator
1887
+ });
1888
+ const ruleField = wrapFieldName(rule.field);
1889
+ const matchEval = processMatchMode(rule);
1890
+ if (matchEval === false) return;
1891
+ else if (matchEval) {
1892
+ if (opts?.preset !== "postgresql") return finalize("");
1893
+ const { mode, threshold } = matchEval;
1894
+ const arrayElementAlias = "elem_alias";
1895
+ const { sql: nestedSQL, params: nestedParams } = defaultRuleGroupProcessorParameterized(transformQuery(rule.value, { ruleProcessor: (r) => ({
1896
+ ...r,
1897
+ field: arrayElementAlias
1898
+ }) }), {
1899
+ ...opts,
1900
+ fields: []
1901
+ });
1902
+ // istanbul ignore else
1903
+ if (Array.isArray(nestedParams)) params.push(...nestedParams);
1904
+ else Object.assign(paramsNamed, nestedParams);
1905
+ switch (mode) {
1906
+ case "all": return finalize(`(select count(*) from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL}) = array_length(${ruleField}, 1)`);
1907
+ case "none": return finalize(`not exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL})`);
1908
+ case "some": return finalize(`exists (select 1 from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL})`);
1909
+ case "atleast":
1910
+ case "atmost":
1911
+ case "exactly": {
1912
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
1913
+ return finalize(`(select count(*)${threshold > 0 && threshold < 1 ? ` / array_length(${ruleField}, 1)` : ""} from unnest(${ruleField}) as ${wrapFieldName(arrayElementAlias)} where ${nestedSQL}) ${op} ${threshold}`);
1914
+ }
1915
+ }
1916
+ }
1917
+ const value = valueProcessor(rule, {
1918
+ parseNumbers,
1919
+ quoteFieldNamesWith,
1920
+ concatOperator,
1921
+ fieldData,
1922
+ format
1923
+ });
1924
+ const sqlOperator = operatorProcessor(rule, opts);
1925
+ const sqlOperatorLowerCase = lc(sqlOperator);
1926
+ const [qPre, qPost] = quoteFieldNamesWith;
1927
+ if ((sqlOperatorLowerCase === "in" || sqlOperatorLowerCase === "not in" || sqlOperatorLowerCase === "between" || sqlOperatorLowerCase === "not between") && !value) return finalize("");
1928
+ else if (sqlOperatorLowerCase === "is null" || sqlOperatorLowerCase === "is not null") return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator}`);
1929
+ else if (rule.valueSource === "field") return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${value}`.trim());
1930
+ else if (sqlOperatorLowerCase === "in" || sqlOperatorLowerCase === "not in") {
1931
+ const splitValue = toArray(rule.value);
1932
+ if (parameterized) {
1933
+ for (const v of splitValue) params.push(shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v);
1934
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} (${splitValue.map((_v, i) => numberedParams ? `${paramPrefix}${processedParams.length + 1 + splitValue.length - (splitValue.length - i)}` : "?").join(", ")})`);
1935
+ }
1936
+ const inParams = [];
1937
+ for (const v of splitValue) {
1938
+ const thisParamName = getNextNamedParam(rule.field);
1939
+ inParams.push(`${paramPrefix}${thisParamName}`);
1940
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${thisParamName}`] = shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v;
1941
+ }
1942
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} (${inParams.join(", ")})`);
1943
+ } else if (sqlOperatorLowerCase === "between" || sqlOperatorLowerCase === "not between") {
1944
+ const [first, second] = toArray(rule.value, { retainEmptyStrings: true }).slice(0, 2).map((v) => shouldRenderAsNumber(v, parseNumbers) ? parseNumber(v, { parseNumbers }) : v);
1945
+ if (parameterized) {
1946
+ params.push(first, second);
1947
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?"} and ${numberedParams ? `${paramPrefix}${processedParams.length + 2}` : "?"}`);
1948
+ }
1949
+ const firstParamName = getNextNamedParam(rule.field);
1950
+ const secondParamName = getNextNamedParam(rule.field);
1951
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${firstParamName}`] = first;
1952
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${secondParamName}`] = second;
1953
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${paramPrefix}${firstParamName} and ${paramPrefix}${secondParamName}`);
1954
+ }
1955
+ let paramValue = rule.value;
1956
+ if (typeof rule.value === "string") if (shouldRenderAsNumber(rule.value, parseNumbers)) paramValue = parseNumber(rule.value, { parseNumbers });
1957
+ else paramValue = /^'.*'$/g.test(value) ? value.replaceAll(/(^'|'$)/g, "") : value;
1958
+ let paramName = "";
1959
+ if (parameterized) params.push(paramValue);
1960
+ else {
1961
+ paramName = getNextNamedParam(rule.field);
1962
+ paramsNamed[`${paramsKeepPrefix ? paramPrefix : ""}${paramName}`] = paramValue;
1963
+ }
1964
+ return finalize(`${qPre}${rule.field}${qPost} ${sqlOperator} ${parameterized ? numberedParams ? `${paramPrefix}${processedParams.length + 1}` : "?" : `${paramPrefix}${paramName}`}`.trim());
1965
+ };
1966
+
1967
+ //#endregion
1968
+ //#region src/utils/formatQuery/defaultRuleProcessorPrisma.ts
1969
+ const processNumber = (value, fallback, parseNumbers) => shouldRenderAsNumber(value, !!parseNumbers || typeof value === "bigint") ? Number(parseNumber(value, { parseNumbers: !!parseNumbers })) : fallback;
1970
+ /**
1971
+ * Default rule processor used by {@link formatQuery} for "prisma" format.
1972
+ *
1973
+ * @group Export
1974
+ */
1975
+ const defaultRuleProcessorPrisma = (rule, options = {}) => {
1976
+ const { field, operator, value, valueSource } = rule;
1977
+ // istanbul ignore next
1978
+ const { parseNumbers, preserveValueOrder } = options;
1979
+ if (valueSource === "field" || processMatchMode(rule)) return;
1980
+ const operatorLC = lc(operator);
1981
+ switch (operatorLC) {
1982
+ case "=": return { [field]: processNumber(value, value, parseNumbers) };
1983
+ case "!=":
1984
+ case "<":
1985
+ case "<=":
1986
+ case ">":
1987
+ case ">=": {
1988
+ const prismaOperator = prismaOperators[operatorLC];
1989
+ return { [field]: { [prismaOperator]: processNumber(value, value, parseNumbers) } };
1990
+ }
1991
+ case "contains": return { [field]: { contains: value } };
1992
+ case "beginswith": return { [field]: { startsWith: value } };
1993
+ case "endswith": return { [field]: { endsWith: value } };
1994
+ case "doesnotcontain": return { NOT: { [field]: { contains: value } } };
1995
+ case "doesnotbeginwith": return { NOT: { [field]: { startsWith: value } } };
1996
+ case "doesnotendwith": return { NOT: { [field]: { endsWith: value } } };
1997
+ case "null": return { [field]: null };
1998
+ case "notnull": return { [field]: { not: null } };
1999
+ case "in":
2000
+ case "notin": {
2001
+ const valueAsArray = toArray(value);
2002
+ return { [field]: { [prismaOperators[operatorLC]]: valueAsArray.map((val) => processNumber(val, val, parseNumbers)) } };
2003
+ }
2004
+ case "between":
2005
+ case "notbetween": {
2006
+ const valueAsArray = toArray(value);
2007
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
2008
+ const [first, second] = valueAsArray;
2009
+ const shouldParseNumbers = !(parseNumbers === false);
2010
+ const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers }) : NaN;
2011
+ const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers }) : NaN;
2012
+ let firstValue = Number.isNaN(firstNum) ? first : firstNum;
2013
+ let secondValue = Number.isNaN(secondNum) ? second : secondNum;
2014
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
2015
+ const tempNum = secondNum;
2016
+ secondValue = firstNum;
2017
+ firstValue = tempNum;
2018
+ }
2019
+ return operatorLC === "between" ? { [field]: {
2020
+ gte: firstValue,
2021
+ lte: secondValue
2022
+ } } : { OR: [{ [field]: { lt: firstValue } }, { [field]: { gt: secondValue } }] };
2023
+ } else return "";
2024
+ }
2025
+ }
2026
+ return "";
2027
+ };
2028
+
2029
+ //#endregion
2030
+ //#region src/utils/formatQuery/defaultRuleProcessorSequelize.ts
2031
+ /**
2032
+ * Default rule processor used by {@link formatQuery} for the "sequelize" format.
2033
+ *
2034
+ * @group Export
2035
+ */
2036
+ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder, context = {} } = {}) => {
2037
+ const { sequelizeOperators: Op, sequelizeCol: col, sequelizeFn: fn } = context;
2038
+ if (processMatchMode(rule)) return;
2039
+ const { field, operator, value, valueSource } = rule;
2040
+ const valueIsField = valueSource === "field";
2041
+ const operatorLC = lc(operator);
2042
+ if (!Op || valueIsField && (!col || !fn && [
2043
+ "doesnotcontain",
2044
+ "doesnotbeginwith",
2045
+ "doesnotendwith"
2046
+ ].includes(operatorLC))) return;
2047
+ switch (operatorLC) {
2048
+ case "=":
2049
+ case "!=":
2050
+ case "<":
2051
+ case "<=":
2052
+ case ">":
2053
+ case ">=": {
2054
+ const sequelizeOperator = {
2055
+ "=": Op.eq,
2056
+ "!=": Op.ne,
2057
+ "<": Op.lt,
2058
+ "<=": Op.lte,
2059
+ ">": Op.gt,
2060
+ ">=": Op.gte
2061
+ }[operatorLC];
2062
+ return { [field]: valueIsField && operatorLC === "=" ? { [Op.col]: value } : { [sequelizeOperator]: valueIsField ? col(value) : shouldRenderAsNumber(value, parseNumbers) ? parseNumber(value, { parseNumbers: "strict" }) : value } };
2063
+ }
2064
+ case "contains": return { [field]: { [Op.substring]: valueIsField ? col(value) : `${value}` } };
2065
+ case "beginswith": return { [field]: { [Op.startsWith]: valueIsField ? col(value) : `${value}` } };
2066
+ case "endswith": return { [field]: { [Op.endsWith]: valueIsField ? col(value) : `${value}` } };
2067
+ case "doesnotcontain": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value), "%") : `%${value}%` } };
2068
+ case "doesnotbeginwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", col(value), "%") : `${value}%` } };
2069
+ case "doesnotendwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value)) : `%${value}` } };
2070
+ case "null": return { [field]: { [Op.is]: null } };
2071
+ case "notnull": return { [field]: { [Op.not]: null } };
2072
+ case "in":
2073
+ case "notin": {
2074
+ const valueAsArray = toArray(value);
2075
+ return { [field]: { [operatorLC === "in" ? Op.in : Op.notIn]: valueAsArray.map((val) => valueIsField ? col(val) : shouldRenderAsNumber(val, parseNumbers) ? parseNumber(val, { parseNumbers: "strict" }) : val) } };
2076
+ }
2077
+ case "between":
2078
+ case "notbetween": {
2079
+ const valueAsArray = toArray(value, { retainEmptyStrings: true });
2080
+ if (valueAsArray.length < 2 || !isValidValue(valueAsArray[0]) || !isValidValue(valueAsArray[1])) return;
2081
+ const [first, second] = valueAsArray;
2082
+ const firstNum = shouldRenderAsNumber(first, parseNumbers) ? parseNumber(first, { parseNumbers: "strict" }) : NaN;
2083
+ const secondNum = shouldRenderAsNumber(second, parseNumbers) ? parseNumber(second, { parseNumbers: "strict" }) : NaN;
2084
+ const firstValue = Number.isNaN(firstNum) ? first : firstNum;
2085
+ const secondValue = Number.isNaN(secondNum) ? second : secondNum;
2086
+ const valsOneAndTwoOnly = [firstValue, secondValue];
2087
+ if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
2088
+ valsOneAndTwoOnly[0] = secondNum;
2089
+ valsOneAndTwoOnly[1] = firstNum;
2090
+ }
2091
+ return { [field]: { [operatorLC === "between" ? Op.between : Op.notBetween]: valueIsField ? valsOneAndTwoOnly.map((v) => col(v)) : valsOneAndTwoOnly.every((v) => shouldRenderAsNumber(v, parseNumbers)) ? valsOneAndTwoOnly.map((v) => parseNumber(v, { parseNumbers: "strict" })) : valsOneAndTwoOnly } };
2092
+ }
2093
+ }
2094
+ };
2095
+
2096
+ //#endregion
2097
+ //#region src/utils/formatQuery/formatQuery.ts
2098
+ /**
2099
+ * A collection of option presets for {@link formatQuery}, specifically for SQL-based formats.
2100
+ *
2101
+ * @group Export
2102
+ */
2103
+ const sqlDialectPresets = {
2104
+ ansi: {},
2105
+ sqlite: { paramsKeepPrefix: true },
2106
+ oracle: {},
2107
+ mssql: {
2108
+ concatOperator: "+",
2109
+ quoteFieldNamesWith: ["[", "]"],
2110
+ fieldIdentifierSeparator: ".",
2111
+ paramPrefix: "@"
2112
+ },
2113
+ mysql: { concatOperator: "CONCAT" },
2114
+ postgresql: {
2115
+ quoteFieldNamesWith: "\"",
2116
+ numberedParams: true,
2117
+ paramPrefix: "$"
2118
+ }
2119
+ };
2120
+ /**
2121
+ * A collection of option presets for {@link formatQuery}.
2122
+ *
2123
+ * @group Export
2124
+ */
2125
+ const formatQueryOptionPresets = { ...sqlDialectPresets };
2126
+ const defaultRuleProcessors = {
2127
+ cel: defaultRuleProcessorCEL,
2128
+ drizzle: defaultRuleProcessorDrizzle,
2129
+ elasticsearch: defaultRuleProcessorElasticSearch,
2130
+ json_without_ids: defaultRuleProcessorSQL,
2131
+ json: defaultRuleProcessorSQL,
2132
+ jsonata: defaultRuleProcessorJSONata,
2133
+ jsonlogic: defaultRuleProcessorJsonLogic,
2134
+ ldap: defaultRuleProcessorLDAP,
2135
+ mongodb_query: defaultRuleProcessorMongoDBQuery,
2136
+ mongodb: defaultRuleProcessorMongoDB,
2137
+ natural_language: defaultRuleProcessorNL,
2138
+ parameterized_named: defaultRuleProcessorParameterized,
2139
+ parameterized: defaultRuleProcessorParameterized,
2140
+ prisma: defaultRuleProcessorPrisma,
2141
+ sequelize: defaultRuleProcessorSequelize,
2142
+ spel: defaultRuleProcessorSpEL,
2143
+ sql: defaultRuleProcessorSQL
2144
+ };
2145
+ /* istanbul ignore next */
2146
+ const defaultOperatorProcessor = (r) => r.operator;
2147
+ const defaultOperatorProcessors = {
2148
+ cel: defaultOperatorProcessor,
2149
+ drizzle: defaultOperatorProcessor,
2150
+ elasticsearch: defaultOperatorProcessor,
2151
+ json_without_ids: defaultOperatorProcessor,
2152
+ json: defaultOperatorProcessor,
2153
+ jsonata: defaultOperatorProcessor,
2154
+ jsonlogic: defaultOperatorProcessor,
2155
+ ldap: defaultOperatorProcessor,
2156
+ mongodb_query: defaultOperatorProcessor,
2157
+ mongodb: defaultOperatorProcessor,
2158
+ natural_language: defaultOperatorProcessorNL,
2159
+ parameterized_named: defaultOperatorProcessorSQL,
2160
+ parameterized: defaultOperatorProcessorSQL,
2161
+ prisma: defaultOperatorProcessor,
2162
+ sequelize: defaultOperatorProcessor,
2163
+ spel: defaultOperatorProcessor,
2164
+ sql: defaultOperatorProcessorSQL
2165
+ };
2166
+ const defaultFallbackExpressions = {
2167
+ cel: "1 == 1",
2168
+ ldap: "",
2169
+ mongodb: "\"$and\":[{\"$expr\":true}]",
2170
+ natural_language: "1 is 1",
2171
+ spel: "1 == 1",
2172
+ sql: "(1 = 1)"
2173
+ };
2174
+ const defaultFormatQueryOptions = {
2175
+ format: "json",
2176
+ fields: [],
2177
+ quoteFieldNamesWith: ["", ""],
2178
+ fieldIdentifierSeparator: "",
2179
+ getOperators: () => [],
2180
+ paramPrefix: ":",
2181
+ paramsKeepPrefix: false,
2182
+ numberedParams: false,
2183
+ preserveValueOrder: false,
2184
+ placeholderFieldName: defaultPlaceholderFieldName,
2185
+ placeholderOperatorName: defaultPlaceholderOperatorName,
2186
+ quoteValuesWith: "'",
2187
+ concatOperator: "||",
2188
+ preset: "ansi",
2189
+ wordOrder: "SVO",
2190
+ translations: {},
2191
+ operatorMap: {}
2192
+ };
2193
+ const valueProcessorCanActAsRuleProcessor = new Set([
2194
+ "cel",
2195
+ "drizzle",
2196
+ "elasticsearch",
2197
+ "jsonata",
2198
+ "jsonlogic",
2199
+ "ldap",
2200
+ "mongodb_query",
2201
+ "mongodb",
2202
+ "prisma",
2203
+ "sequelize",
2204
+ "spel"
2205
+ ]);
2206
+ const sqlFormats = new Set([
2207
+ "sql",
2208
+ "parameterized",
2209
+ "parameterized_named",
2210
+ "drizzle",
2211
+ "prisma",
2212
+ "sequelize"
2213
+ ]);
2214
+ function formatQuery(ruleGroup, optionParam = {}) {
2215
+ const options = typeof optionParam === "string" ? { format: lc(optionParam) } : optionParam;
2216
+ const optObj = {
2217
+ ...defaultFormatQueryOptions,
2218
+ ...!options.format || sqlFormats.has(options.format) ? sqlDialectPresets[options.preset ?? "ansi"] ?? null : null,
2219
+ ...options,
2220
+ ...!options.format && (Object.keys(sqlDialectPresets).includes(options.preset ?? "") ? { format: "sql" } : null)
2221
+ };
2222
+ const format = lc(optObj.format);
2223
+ const { fallbackExpression: fallbackExpression_option, getOperators: getOperators_option, operatorProcessor: operatorProcessor_option, parseNumbers, quoteFieldNamesWith: quoteFieldNamesWith_option, ruleGroupProcessor: ruleGroupProcessor_option, ruleProcessor: ruleProcessor_option, validator, valueProcessor: valueProcessor_option, context } = optObj;
2224
+ const getParseNumberBoolean = (inputType) => {
2225
+ return typeof getParseNumberMethod({
2226
+ parseNumbers,
2227
+ inputType
2228
+ }) === "string" ? true : typeof parseNumbers === "boolean" ? parseNumbers : void 0;
2229
+ };
2230
+ const operatorProcessor = typeof operatorProcessor_option === "function" ? operatorProcessor_option : defaultOperatorProcessors[format] ?? defaultOperatorProcessor;
2231
+ const valueProcessor = typeof valueProcessor_option === "function" ? isValueProcessorLegacy(valueProcessor_option) ? (r) => valueProcessor_option(r.field, r.operator, r.value, r.valueSource) : valueProcessor_option : format === "natural_language" ? defaultValueProcessorNL : valueProcessorCanActAsRuleProcessor.has(format) ? ruleProcessor_option ?? defaultRuleProcessors[format] : defaultValueProcessorByRule;
2232
+ const ruleProcessor = (typeof ruleProcessor_option === "function" ? ruleProcessor_option : null) ?? (valueProcessorCanActAsRuleProcessor.has(format) && typeof ruleProcessor_option !== "function" && valueProcessor_option ? valueProcessor : null) ?? defaultRuleProcessors[format] ?? defaultRuleProcessorSQL;
2233
+ const quoteFieldNamesWith = getQuoteFieldNamesWithArray(quoteFieldNamesWith_option);
2234
+ const fields = toFullOptionList(optObj.fields);
2235
+ const getOperators = (f, m) => toFullOptionList(getOperators_option(f, m) ?? []);
2236
+ const fallbackExpression = fallbackExpression_option ?? defaultFallbackExpressions[format] ?? defaultFallbackExpressions.sql;
2237
+ let validationMap = {};
2238
+ // istanbul ignore else
2239
+ if (typeof validator === "function") {
2240
+ const validationResult = validator(ruleGroup);
2241
+ if (typeof validationResult === "boolean") {
2242
+ // istanbul ignore else
2243
+ if (!validationResult) return format === "parameterized" ? {
2244
+ sql: fallbackExpression,
2245
+ params: []
2246
+ } : format === "parameterized_named" ? {
2247
+ sql: fallbackExpression,
2248
+ params: {}
2249
+ } : format === "mongodb" ? `{${fallbackExpression}}` : format === "mongodb_query" ? mongoDbFallback : format === "prisma" ? prismaFallback : format === "jsonlogic" ? false : format === "elasticsearch" ? {} : format === "drizzle" || format === "sequelize" ? void 0 : fallbackExpression;
2250
+ } else validationMap = validationResult;
2251
+ }
2252
+ const validatorMap = {};
2253
+ const uniqueFields = toFlatOptionArray(fields);
2254
+ for (const f of uniqueFields)
2255
+ // istanbul ignore else
2256
+ if (typeof f.validator === "function") validatorMap[f.value ?? f.name] = f.validator;
2257
+ const validateRule = (rule) => {
2258
+ let validationResult;
2259
+ let fieldValidator;
2260
+ if (rule.id) validationResult = validationMap[rule.id];
2261
+ if (uniqueFields.length > 0) {
2262
+ const fieldArr = uniqueFields.filter((f) => f.name === rule.field);
2263
+ if (fieldArr.length > 0) {
2264
+ const field = fieldArr[0];
2265
+ // istanbul ignore else
2266
+ if (typeof field.validator === "function") fieldValidator = field.validator;
2267
+ }
2268
+ }
2269
+ return [validationResult, fieldValidator];
2270
+ };
2271
+ const finalOptions = {
2272
+ ...optObj,
2273
+ fallbackExpression,
2274
+ fields,
2275
+ format,
2276
+ getOperators,
2277
+ getParseNumberBoolean,
2278
+ quoteFieldNamesWith,
2279
+ operatorProcessor,
2280
+ ruleProcessor,
2281
+ valueProcessor,
2282
+ validateRule,
2283
+ validationMap,
2284
+ context
2285
+ };
2286
+ if (typeof ruleGroupProcessor_option === "function") return ruleGroupProcessor_option(ruleGroup, finalOptions);
2287
+ switch (format) {
2288
+ case "json":
2289
+ case "json_without_ids": {
2290
+ const rg = parseNumbers ? produce(ruleGroup, (g) => numerifyValues(g, finalOptions)) : ruleGroup;
2291
+ if (format === "json_without_ids") return JSON.stringify(rg, (key, value) => key === "id" || key === "path" ? void 0 : bigIntJsonStringifyReplacer(key, value));
2292
+ return JSON.stringify(rg, bigIntJsonStringifyReplacer, 2);
2293
+ }
2294
+ case "sql": return defaultRuleGroupProcessorSQL(ruleGroup, finalOptions);
2295
+ case "parameterized":
2296
+ case "parameterized_named": return defaultRuleGroupProcessorParameterized(ruleGroup, finalOptions);
2297
+ case "mongodb": return defaultRuleGroupProcessorMongoDB(ruleGroup, finalOptions);
2298
+ case "mongodb_query": return defaultRuleGroupProcessorMongoDBQuery(ruleGroup, finalOptions);
2299
+ case "cel": return defaultRuleGroupProcessorCEL(ruleGroup, finalOptions);
2300
+ case "spel": return defaultRuleGroupProcessorSpEL(ruleGroup, finalOptions);
2301
+ case "jsonata": return defaultRuleGroupProcessorJSONata(ruleGroup, finalOptions);
2302
+ case "jsonlogic": return defaultRuleGroupProcessorJsonLogic(ruleGroup, finalOptions);
2303
+ case "elasticsearch": return defaultRuleGroupProcessorElasticSearch(ruleGroup, finalOptions);
2304
+ case "natural_language": return defaultRuleGroupProcessorNL(ruleGroup, finalOptions);
2305
+ case "ldap": return defaultRuleGroupProcessorLDAP(ruleGroup, finalOptions);
2306
+ case "prisma": return defaultRuleGroupProcessorPrisma(ruleGroup, finalOptions);
2307
+ case "drizzle": return defaultRuleGroupProcessorDrizzle(ruleGroup, finalOptions);
2308
+ case "sequelize": return defaultRuleGroupProcessorSequelize(ruleGroup, finalOptions);
2309
+ default: return "";
2310
+ }
2311
+ }
2312
+
2313
+ //#endregion
2314
+ //#region src/utils/formatQuery/index.ts
2315
+ const generateValueProcessor = (vpbr) => (field, operator, value, valueSource) => vpbr({
2316
+ field,
2317
+ operator,
2318
+ value,
2319
+ valueSource
2320
+ }, { parseNumbers: false });
2321
+ /**
2322
+ * Default value processor used by {@link formatQuery} for "sql" format.
2323
+ *
2324
+ * @group Export
2325
+ */
2326
+ const defaultValueProcessor = generateValueProcessor(defaultValueProcessorByRule);
2327
+ /**
2328
+ * @deprecated Prefer {@link defaultRuleProcessorMongoDB}.
2329
+ *
2330
+ * @group Export
2331
+ */
2332
+ const defaultMongoDBValueProcessor = generateValueProcessor(defaultRuleProcessorMongoDB);
2333
+ /**
2334
+ * @deprecated Prefer {@link defaultRuleProcessorCEL}.
2335
+ *
2336
+ * @group Export
2337
+ */
2338
+ const defaultCELValueProcessor = generateValueProcessor(defaultRuleProcessorCEL);
2339
+ /**
2340
+ * @deprecated Prefer {@link defaultRuleProcessorSpEL}.
2341
+ *
2342
+ * @group Export
2343
+ */
2344
+ const defaultSpELValueProcessor = generateValueProcessor(defaultRuleProcessorSpEL);
2345
+ /**
2346
+ * @deprecated Renamed to {@link defaultRuleProcessorCEL}.
2347
+ *
2348
+ * @group Export
2349
+ */
2350
+ const defaultValueProcessorCELByRule = defaultRuleProcessorCEL;
2351
+ /**
2352
+ * @deprecated Renamed to {@link defaultRuleProcessorMongoDB}.
2353
+ *
2354
+ * @group Export
2355
+ */
2356
+ const defaultValueProcessorMongoDBByRule = defaultRuleProcessorMongoDB;
2357
+ /**
2358
+ * @deprecated Renamed to {@link defaultRuleProcessorSpEL}.
2359
+ *
2360
+ * @group Export
2361
+ */
2362
+ const defaultValueProcessorSpELByRule = defaultRuleProcessorSpEL;
2363
+
2364
+ //#endregion
2365
+ export { bigIntJsonParseReviver, bigIntJsonStringifyReplacer, celCombinatorMap, defaultCELValueProcessor, defaultExportOperatorMap, defaultMongoDBValueProcessor, defaultNLTranslations, defaultOperatorProcessorNL, defaultOperatorProcessorSQL, defaultRuleGroupProcessorCEL, defaultRuleGroupProcessorDrizzle, defaultRuleGroupProcessorElasticSearch, defaultRuleGroupProcessorJSONata, defaultRuleGroupProcessorJsonLogic, defaultRuleGroupProcessorLDAP, defaultRuleGroupProcessorMongoDB, defaultRuleGroupProcessorMongoDBQuery, defaultRuleGroupProcessorNL, defaultRuleGroupProcessorParameterized, defaultRuleGroupProcessorPrisma, defaultRuleGroupProcessorSQL, defaultRuleGroupProcessorSequelize, defaultRuleGroupProcessorSpEL, defaultRuleProcessorCEL, defaultRuleProcessorDrizzle, defaultRuleProcessorElasticSearch, defaultRuleProcessorJSONata, defaultRuleProcessorJsonLogic, defaultRuleProcessorLDAP, defaultRuleProcessorMongoDB, defaultRuleProcessorMongoDBQuery, defaultRuleProcessorNL, defaultRuleProcessorParameterized, defaultRuleProcessorPrisma, defaultRuleProcessorSQL, defaultRuleProcessorSequelize, defaultRuleProcessorSpEL, defaultSpELValueProcessor, defaultValueProcessor, defaultValueProcessorByRule, defaultValueProcessorCELByRule, defaultValueProcessorMongoDBByRule, defaultValueProcessorNL, defaultValueProcessorSpELByRule, formatQuery, formatQueryOptionPresets, getNLTranslataion, getQuoteFieldNamesWithArray, getQuotedFieldName, isValidValue, isValueProcessorLegacy, jsonLogicAdditionalOperators, mapSQLOperator, mongoDbFallback, mongoOperators, normalizeConstituentWordOrder, numerifyValues, prismaFallback, prismaOperators, processMatchMode, shouldRenderAsNumber, sqlDialectPresets };
2366
+ //# sourceMappingURL=formatQuery.mjs.map