@react-querybuilder/core 8.14.4 → 8.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/README.md +114 -53
  2. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +288 -22
  3. package/dist/cjs/react-querybuilder_core.cjs.development.js +796 -77
  4. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  5. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +288 -22
  6. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  7. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  8. package/dist/{convertQuery-CeJSNn37.mjs → convertQuery-BeJJH9BI.mjs} +2 -2
  9. package/dist/convertQuery-BeJJH9BI.mjs.map +1 -0
  10. package/dist/{convertQuery-J8LpTG-7.js → convertQuery-Lx2HQa0m.js} +2 -2
  11. package/dist/convertQuery-Lx2HQa0m.js.map +1 -0
  12. package/dist/formatQuery.d.mts +89 -2
  13. package/dist/formatQuery.d.ts +89 -2
  14. package/dist/formatQuery.js +775 -66
  15. package/dist/formatQuery.js.map +1 -1
  16. package/dist/formatQuery.mjs +768 -67
  17. package/dist/formatQuery.mjs.map +1 -1
  18. package/dist/{import-BwQqExpO.d.mts → import-BHlzBLM_.d.mts} +2 -2
  19. package/dist/{import-CrJf23Nf.d.ts → import-C6imciDf.d.ts} +2 -2
  20. package/dist/{index-CYT4Saz-.d.mts → index-Cjapnb-H.d.ts} +161 -10
  21. package/dist/{index-DBlQeLax.d.ts → index-D-Iej37L.d.mts} +161 -10
  22. package/dist/{objectUtils-ButT0Mng.js → objectUtils-Bzug_QfX.js} +2 -2
  23. package/dist/objectUtils-Bzug_QfX.js.map +1 -0
  24. package/dist/{objectUtils-C0WB-8ex.mjs → objectUtils-D96eEEzL.mjs} +2 -2
  25. package/dist/objectUtils-D96eEEzL.mjs.map +1 -0
  26. package/dist/parseCEL.d.mts +2 -2
  27. package/dist/parseCEL.d.ts +2 -2
  28. package/dist/parseCEL.js +35 -35
  29. package/dist/parseCEL.js.map +1 -1
  30. package/dist/parseCEL.mjs +35 -35
  31. package/dist/parseCEL.mjs.map +1 -1
  32. package/dist/parseCypher.d.mts +49 -0
  33. package/dist/parseCypher.d.ts +49 -0
  34. package/dist/parseCypher.js +578 -0
  35. package/dist/parseCypher.js.map +1 -0
  36. package/dist/parseCypher.mjs +575 -0
  37. package/dist/parseCypher.mjs.map +1 -0
  38. package/dist/parseGremlin.d.mts +35 -0
  39. package/dist/parseGremlin.d.ts +35 -0
  40. package/dist/parseGremlin.js +192 -0
  41. package/dist/parseGremlin.js.map +1 -0
  42. package/dist/parseGremlin.mjs +191 -0
  43. package/dist/parseGremlin.mjs.map +1 -0
  44. package/dist/parseJSONata.d.mts +2 -2
  45. package/dist/parseJSONata.d.ts +2 -2
  46. package/dist/parseJSONata.js +11 -11
  47. package/dist/parseJSONata.js.map +1 -1
  48. package/dist/parseJSONata.mjs +11 -11
  49. package/dist/parseJSONata.mjs.map +1 -1
  50. package/dist/parseJsonLogic.d.mts +2 -2
  51. package/dist/parseJsonLogic.d.ts +2 -2
  52. package/dist/parseJsonLogic.js +6 -6
  53. package/dist/parseJsonLogic.js.map +1 -1
  54. package/dist/parseJsonLogic.mjs +6 -6
  55. package/dist/parseJsonLogic.mjs.map +1 -1
  56. package/dist/parseMongoDB.d.mts +2 -2
  57. package/dist/parseMongoDB.d.ts +2 -2
  58. package/dist/parseMongoDB.js +6 -6
  59. package/dist/parseMongoDB.js.map +1 -1
  60. package/dist/parseMongoDB.mjs +6 -6
  61. package/dist/parseMongoDB.mjs.map +1 -1
  62. package/dist/parseSPARQL.d.mts +34 -0
  63. package/dist/parseSPARQL.d.ts +34 -0
  64. package/dist/parseSPARQL.js +253 -0
  65. package/dist/parseSPARQL.js.map +1 -0
  66. package/dist/parseSPARQL.mjs +251 -0
  67. package/dist/parseSPARQL.mjs.map +1 -0
  68. package/dist/parseSQL.d.mts +2 -2
  69. package/dist/parseSQL.d.ts +2 -2
  70. package/dist/parseSQL.js +16 -16
  71. package/dist/parseSQL.js.map +1 -1
  72. package/dist/parseSQL.mjs +16 -16
  73. package/dist/parseSQL.mjs.map +1 -1
  74. package/dist/parseSpEL.d.mts +2 -2
  75. package/dist/parseSpEL.d.ts +2 -2
  76. package/dist/parseSpEL.js +10 -10
  77. package/dist/parseSpEL.js.map +1 -1
  78. package/dist/parseSpEL.mjs +10 -10
  79. package/dist/parseSpEL.mjs.map +1 -1
  80. package/dist/{prepareQueryObjects-DO3qXriW.js → prepareQueryObjects-BoG5Rt8z.js} +6 -6
  81. package/dist/prepareQueryObjects-BoG5Rt8z.js.map +1 -0
  82. package/dist/{prepareQueryObjects-BfMlS4ql.mjs → prepareQueryObjects-uA10ZpZX.mjs} +6 -6
  83. package/dist/prepareQueryObjects-uA10ZpZX.mjs.map +1 -0
  84. package/dist/query-builder.css +1 -1
  85. package/dist/query-builder.css.map +1 -1
  86. package/dist/react-querybuilder_core.d.mts +288 -22
  87. package/dist/react-querybuilder_core.legacy-esm.d.ts +288 -22
  88. package/dist/react-querybuilder_core.legacy-esm.js +833 -108
  89. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  90. package/dist/react-querybuilder_core.mjs +788 -78
  91. package/dist/react-querybuilder_core.mjs.map +1 -1
  92. package/dist/react-querybuilder_core.production.d.mts +288 -22
  93. package/dist/react-querybuilder_core.production.mjs +1 -1
  94. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  95. package/dist/styles/_main.scss +4 -0
  96. package/dist/transformQuery.d.mts +1 -1
  97. package/dist/transformQuery.d.ts +1 -1
  98. package/dist/transformQuery.js +1 -1
  99. package/dist/transformQuery.mjs +1 -1
  100. package/dist/{utils-BlMGIhvx.mjs → utils-ChLG90DP.mjs} +3 -3
  101. package/dist/utils-ChLG90DP.mjs.map +1 -0
  102. package/dist/{utils-CZRhzje-.js → utils-Qwkq2Q0F.js} +3 -3
  103. package/dist/utils-Qwkq2Q0F.js.map +1 -0
  104. package/formatQuery/package.json +1 -1
  105. package/package.json +53 -14
  106. package/parseCEL/package.json +1 -1
  107. package/parseCypher/package.json +4 -0
  108. package/parseGremlin/package.json +4 -0
  109. package/parseJSONata/package.json +1 -1
  110. package/parseJsonLogic/package.json +1 -1
  111. package/parseMongoDB/package.json +1 -1
  112. package/parseSPARQL/package.json +4 -0
  113. package/parseSQL/package.json +1 -1
  114. package/parseSpEL/package.json +1 -1
  115. package/transformQuery/package.json +1 -1
  116. package/dist/convertQuery-CeJSNn37.mjs.map +0 -1
  117. package/dist/convertQuery-J8LpTG-7.js.map +0 -1
  118. package/dist/objectUtils-ButT0Mng.js.map +0 -1
  119. package/dist/objectUtils-C0WB-8ex.mjs.map +0 -1
  120. package/dist/prepareQueryObjects-BfMlS4ql.mjs.map +0 -1
  121. package/dist/prepareQueryObjects-DO3qXriW.js.map +0 -1
  122. package/dist/utils-BlMGIhvx.mjs.map +0 -1
  123. package/dist/utils-CZRhzje-.js.map +0 -1
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_utils = require("./utils-CZRhzje-.js");
3
- const require_objectUtils = require("./objectUtils-ButT0Mng.js");
2
+ const require_utils = require("./utils-Qwkq2Q0F.js");
3
+ const require_objectUtils = require("./objectUtils-Bzug_QfX.js");
4
4
  const require_transformQuery = require("./transformQuery.js");
5
- const require_convertQuery = require("./convertQuery-J8LpTG-7.js");
5
+ const require_convertQuery = require("./convertQuery-Lx2HQa0m.js");
6
6
  //#region src/utils/isRuleOrGroupValid.ts
7
7
  /**
8
8
  * Determines if an object is useful as a validation result.
@@ -20,7 +20,7 @@ const isRuleOrGroupValid = (rg, validationResult, validator) => {
20
20
  if (typeof validator === "function" && !require_objectUtils.isRuleGroup(rg)) {
21
21
  const vr = validator(rg);
22
22
  if (typeof vr === "boolean") return vr;
23
- // istanbul ignore else
23
+ // v8 ignore else
24
24
  if (isValidationResult(vr)) return vr.valid;
25
25
  }
26
26
  return true;
@@ -83,7 +83,7 @@ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
83
83
  //#endregion
84
84
  //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts
85
85
  const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot");
86
- const escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
86
+ const escapeDoubleQuotes$1 = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
87
87
  /**
88
88
  * Default rule processor used by {@link formatQuery} for "cel" format.
89
89
  *
@@ -125,19 +125,19 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
125
125
  case "==":
126
126
  case "!=":
127
127
  case ">":
128
- case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`}`;
128
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`}`;
129
129
  case "contains":
130
- case "doesnotcontain": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.contains(${valueIsField ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
130
+ case "doesnotcontain": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.contains(${valueIsField ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`})`;
131
131
  case "beginswith":
132
- case "doesnotbeginwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.startsWith(${valueIsField ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
132
+ case "doesnotbeginwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.startsWith(${valueIsField ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`})`;
133
133
  case "endswith":
134
- case "doesnotendwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.endsWith(${valueIsField ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
134
+ case "doesnotendwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.endsWith(${valueIsField ? require_utils.trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`})`;
135
135
  case "null": return `${field} == null`;
136
136
  case "notnull": return `${field} != null`;
137
137
  case "in":
138
138
  case "notin": {
139
139
  const [prefix, suffix] = shouldNegate$2(operatorTL) ? ["!(", ")"] : ["", ""];
140
- return `${prefix}${field} in [${require_utils.toArray(value).map((val) => valueIsField || require_utils.shouldRenderAsNumber(val, parseNumbers) ? `${require_utils.trimIfString(val)}` : `"${escapeDoubleQuotes(val, escapeQuotes)}"`).join(", ")}]${suffix}`;
140
+ return `${prefix}${field} in [${require_utils.toArray(value).map((val) => valueIsField || require_utils.shouldRenderAsNumber(val, parseNumbers) ? `${require_utils.trimIfString(val)}` : `"${escapeDoubleQuotes$1(val, escapeQuotes)}"`).join(", ")}]${suffix}`;
141
141
  }
142
142
  case "between":
143
143
  case "notbetween": {
@@ -147,8 +147,8 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
147
147
  const shouldParseNumbers = !(parseNumbers === false);
148
148
  const firstNum = require_utils.shouldRenderAsNumber(first, shouldParseNumbers) ? require_utils.parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
149
149
  const secondNum = require_utils.shouldRenderAsNumber(second, shouldParseNumbers) ? require_utils.parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
150
- let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes(first, escapeQuotes)}"` : firstNum;
151
- let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `"${escapeDoubleQuotes(second, escapeQuotes)}"` : secondNum;
150
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes$1(first, escapeQuotes)}"` : firstNum;
151
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `"${escapeDoubleQuotes$1(second, escapeQuotes)}"` : secondNum;
152
152
  if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
153
153
  const tempNum = secondNum;
154
154
  secondValue = firstNum;
@@ -404,7 +404,7 @@ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
404
404
  //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts
405
405
  const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot");
406
406
  const wrapInNegation = (clause, negate) => negate ? `!(${clause})` : clause;
407
- const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
407
+ const escapeSingleQuotes$2 = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
408
408
  /**
409
409
  * Default rule processor used by {@link formatQuery} for "spel" format.
410
410
  *
@@ -445,20 +445,20 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
445
445
  case "==":
446
446
  case "!=":
447
447
  case ">":
448
- case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? require_utils.trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`;
448
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? require_utils.trimIfString(value) : `'${escapeSingleQuotes$2(value, escapeQuotes)}'`}`;
449
449
  case "contains":
450
- case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? require_utils.trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
450
+ case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? require_utils.trimIfString(value) : `'${escapeSingleQuotes$2(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
451
451
  case "beginswith":
452
- case "doesnotbeginwith": return wrapInNegation(`${field} matches ${valueIsField ? `'^'.concat(${require_utils.trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
452
+ case "doesnotbeginwith": return wrapInNegation(`${field} matches ${valueIsField ? `'^'.concat(${require_utils.trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes$2(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
453
453
  case "endswith":
454
- case "doesnotendwith": return wrapInNegation(`${field} matches ${valueIsField ? `${require_utils.trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`}`, shouldNegate$1(operatorTL));
454
+ case "doesnotendwith": return wrapInNegation(`${field} matches ${valueIsField ? `${require_utils.trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes$2(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`}`, shouldNegate$1(operatorTL));
455
455
  case "null": return `${field} == null`;
456
456
  case "notnull": return `${field} != null`;
457
457
  case "in":
458
458
  case "notin": {
459
459
  const negate = shouldNegate$1(operatorTL) ? "!" : "";
460
460
  const valueAsArray = require_utils.toArray(value);
461
- return valueAsArray.length > 0 ? `${negate}(${valueAsArray.map((val) => `${field} == ${valueIsField || require_utils.shouldRenderAsNumber(val, parseNumbers) ? `${require_utils.trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
461
+ return valueAsArray.length > 0 ? `${negate}(${valueAsArray.map((val) => `${field} == ${valueIsField || require_utils.shouldRenderAsNumber(val, parseNumbers) ? `${require_utils.trimIfString(val)}` : `'${escapeSingleQuotes$2(val, escapeQuotes)}'`}`).join(" or ")})` : "";
462
462
  }
463
463
  case "between":
464
464
  case "notbetween": {
@@ -468,8 +468,8 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
468
468
  const shouldParseNumbers = !(parseNumbers === false);
469
469
  const firstNum = require_utils.shouldRenderAsNumber(first, shouldParseNumbers) ? require_utils.parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
470
470
  const secondNum = require_utils.shouldRenderAsNumber(second, shouldParseNumbers) ? require_utils.parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
471
- let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes(first, escapeQuotes)}'` : firstNum;
472
- let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `'${escapeSingleQuotes(second, escapeQuotes)}'` : secondNum;
471
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes$2(first, escapeQuotes)}'` : firstNum;
472
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `'${escapeSingleQuotes$2(second, escapeQuotes)}'` : secondNum;
473
473
  if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
474
474
  const tempNum = secondNum;
475
475
  secondValue = firstNum;
@@ -537,6 +537,70 @@ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQ
537
537
  return valueIsField ? wrapFieldName(value) : require_utils.shouldRenderAsNumber(value, parseNumbers) ? `${require_utils.trimIfString(value)}` : `${wrapAndEscape(value)}`;
538
538
  };
539
539
  //#endregion
540
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorCypher.ts
541
+ /**
542
+ * Maps a {@link DefaultCombinatorName} to a Cypher combinator keyword.
543
+ *
544
+ * @group Export
545
+ */
546
+ const cypherCombinatorMap = {
547
+ and: "AND",
548
+ or: "OR"
549
+ };
550
+ /**
551
+ * Rule group processor used by {@link formatQuery} for "cypher" and "gql" formats.
552
+ *
553
+ * @group Export
554
+ */
555
+ const defaultRuleGroupProcessorCypher = (ruleGroup, options) => {
556
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
557
+ const processRuleGroup = (rg, outermost) => {
558
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
559
+ const processedRules = [];
560
+ let precedingCombinator = "";
561
+ let firstRule = true;
562
+ for (const rule of rg.rules) {
563
+ if (typeof rule === "string") {
564
+ precedingCombinator = cypherCombinatorMap[rule];
565
+ continue;
566
+ }
567
+ if (require_objectUtils.isRuleGroup(rule)) {
568
+ const processedGroup = processRuleGroup(rule);
569
+ if (processedGroup) {
570
+ if (!firstRule && precedingCombinator) {
571
+ processedRules.push(precedingCombinator);
572
+ precedingCombinator = "";
573
+ }
574
+ firstRule = false;
575
+ processedRules.push(processedGroup);
576
+ }
577
+ continue;
578
+ }
579
+ const [validationResult, fieldValidator] = validateRule(rule);
580
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) continue;
581
+ const fieldData = require_utils.getOption(fields, rule.field);
582
+ const processedRule = ruleProcessor(rule, {
583
+ ...options,
584
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
585
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
586
+ fieldData
587
+ });
588
+ if (processedRule) {
589
+ if (!firstRule && precedingCombinator) {
590
+ processedRules.push(precedingCombinator);
591
+ precedingCombinator = "";
592
+ }
593
+ firstRule = false;
594
+ processedRules.push(processedRule);
595
+ }
596
+ }
597
+ const expression = processedRules.join(require_objectUtils.isRuleGroupType(rg) ? ` ${cypherCombinatorMap[rg.combinator]} ` : " ");
598
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "NOT " : ""}(`, ")"] : ["", ""];
599
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
600
+ };
601
+ return processRuleGroup(ruleGroup, true);
602
+ };
603
+ //#endregion
540
604
  //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
541
605
  /**
542
606
  * Default rule processor used by {@link formatQuery} for the "drizzle" format.
@@ -544,22 +608,22 @@ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQ
544
608
  * @group Export
545
609
  */
546
610
  const defaultRuleProcessorDrizzle = (rule, _options) => {
547
- const opts = _options ?? ( /* istanbul ignore next */ {});
548
- // istanbul ignore next
611
+ const opts = _options ?? ( /* v8 ignore start -- @preserve */ {});
612
+ // v8 ignore next
549
613
  const { parseNumbers, preserveValueOrder, context = {} } = opts;
550
614
  const { columns, drizzleOperators, useRawFields } = context;
551
- if (!columns || !drizzleOperators) return;
615
+ if (!columns || !drizzleOperators) return void 0;
552
616
  const { between, eq, gt, gte, inArray, isNotNull, isNull, like, lt, lte, ne, notBetween, notInArray, notLike, sql } = drizzleOperators;
553
617
  const { field, operator, value, valueSource } = rule;
554
618
  const column = useRawFields && /[a-z][a-z0-9]*/i.test(field) ? sql.raw(field) : columns[field];
555
619
  const operatorLC = require_objectUtils.lc(operator);
556
620
  const valueIsField = valueSource === "field";
557
621
  const asFieldOrValue = (v) => valueIsField ? columns[v] : v;
558
- if (!column) return;
622
+ if (!column) return void 0;
559
623
  const matchEval = require_utils.processMatchMode(rule);
560
624
  if (matchEval === false) return;
561
625
  else if (matchEval) {
562
- if (opts.preset !== "postgresql") return;
626
+ if (opts.preset !== "postgresql") return void 0;
563
627
  const { mode, threshold } = matchEval;
564
628
  const arrayElementAlias = "elem_alias";
565
629
  const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(require_transformQuery.transformQuery(rule.value, { ruleProcessor: (r) => ({
@@ -648,7 +712,7 @@ const defaultRuleProcessorDrizzle = (rule, _options) => {
648
712
  */
649
713
  const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns, drizzleOperators) => {
650
714
  const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap } = options;
651
- if (!columns || !drizzleOperators) return;
715
+ if (!columns || !drizzleOperators) return void 0;
652
716
  const { and, not, or } = drizzleOperators;
653
717
  const ruleProcessor = defaultRuleProcessorDrizzle;
654
718
  const processRuleGroup = (rg, _outermost) => {
@@ -704,6 +768,67 @@ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
704
768
  return processedRuleGroup === false ? {} : processedRuleGroup;
705
769
  };
706
770
  //#endregion
771
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorGremlin.ts
772
+ /**
773
+ * Rule group processor used by {@link formatQuery} for "gremlin" format.
774
+ *
775
+ * At the top level, filter rules produce chained `.has()` steps (implicit AND).
776
+ * Nested groups use `.and()` / `.or()` / `.not()` compound traversals with
777
+ * `__` anonymous traversal prefixes.
778
+ *
779
+ * @group Export
780
+ */
781
+ const defaultRuleGroupProcessorGremlin = (ruleGroup, options) => {
782
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
783
+ const validateAndProcess = (rule) => {
784
+ // v8 ignore next -- @preserve
785
+ if (typeof rule === "string" || require_objectUtils.isRuleGroup(rule)) return void 0;
786
+ const [validationResult, fieldValidator] = validateRule(rule);
787
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
788
+ const fieldData = require_utils.getOption(fields, rule.field);
789
+ return ruleProcessor(rule, {
790
+ ...options,
791
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
792
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
793
+ fieldData
794
+ });
795
+ };
796
+ /** Recursively processes a nested group into `.and()`/`.or()`/`.not()` form. */
797
+ const processNested = (rg) => {
798
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return "";
799
+ const predicates = [];
800
+ for (const rule of rg.rules) {
801
+ if (typeof rule === "string") continue;
802
+ if (require_objectUtils.isRuleGroup(rule)) {
803
+ const nested = processNested(rule);
804
+ if (nested) predicates.push(nested);
805
+ continue;
806
+ }
807
+ const processed = validateAndProcess(rule);
808
+ if (processed) predicates.push(processed);
809
+ }
810
+ if (predicates.length === 0) return "";
811
+ const combinator = rg.combinator ?? "and";
812
+ const prefix = rg.not ? "not" : combinator;
813
+ if (predicates.length === 1 && !rg.not) return predicates[0];
814
+ return `.${prefix}(${predicates.map((p) => p.startsWith(".") ? `__${p}` : p).join(", ")})`;
815
+ };
816
+ if (!isRuleOrGroupValid(ruleGroup, validationMap[ruleGroup.id ?? ""])) return fallbackExpression;
817
+ const steps = [];
818
+ for (const rule of ruleGroup.rules) {
819
+ if (typeof rule === "string") continue;
820
+ if (require_objectUtils.isRuleGroup(rule)) {
821
+ const compound = processNested(rule);
822
+ if (compound) steps.push(compound);
823
+ continue;
824
+ }
825
+ const processed = validateAndProcess(rule);
826
+ if (processed) steps.push(processed);
827
+ }
828
+ if (steps.length === 0) return fallbackExpression;
829
+ return steps.join("");
830
+ };
831
+ //#endregion
707
832
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts
708
833
  /**
709
834
  * Rule group processor used by {@link formatQuery} for "jsonata" format.
@@ -867,7 +992,7 @@ const defaultRuleGroupProcessorMongoDB = (ruleGroup, options, meta) => {
867
992
  const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
868
993
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, translations, validateRule, validationMap } = options;
869
994
  const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
870
- if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
995
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : /* v8 ignore next -- @preserve */ "";
871
996
  const rg2 = require_objectUtils.isRuleGroupTypeIC(rg) && rg.rules.some((r) => typeof r === "string" && require_objectUtils.lc(r) === "xor") ? require_convertQuery.convertFromIC(rg) : rg;
872
997
  const processedRules = [];
873
998
  let precedingCombinator = "";
@@ -879,7 +1004,7 @@ const defaultRuleGroupProcessorNL = (ruleGroup, options) => {
879
1004
  }
880
1005
  if (require_objectUtils.isRuleGroup(rule)) {
881
1006
  const processedGroup = processRuleGroup(rule, rg2.rules.length === 1 && !(rg2.not || /^xor$/i.test(rg2.combinator ?? "")));
882
- // istanbul ignore else
1007
+ // v8 ignore else
883
1008
  if (processedGroup) {
884
1009
  if (!firstRule && precedingCombinator) {
885
1010
  processedRules.push(precedingCombinator);
@@ -955,7 +1080,7 @@ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
955
1080
  if (!require_objectUtils.isPojo(processedRule)) return "";
956
1081
  const { sql, params: customParams } = processedRule;
957
1082
  if (typeof sql !== "string" || !sql) return "";
958
- // istanbul ignore else
1083
+ // v8 ignore else
959
1084
  if (format === "parameterized" && Array.isArray(customParams)) params.push(...customParams);
960
1085
  else if (format === "parameterized_named" && require_objectUtils.isPojo(customParams)) {
961
1086
  Object.assign(paramsNamed, customParams);
@@ -964,7 +1089,7 @@ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
964
1089
  return sql;
965
1090
  };
966
1091
  const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
967
- if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
1092
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : /* v8 ignore next -- @preserve */ "";
968
1093
  const processedRules = [];
969
1094
  let precedingCombinator = "";
970
1095
  let firstRule = true;
@@ -975,7 +1100,7 @@ const defaultRuleGroupProcessorParameterized = (ruleGroup, options) => {
975
1100
  }
976
1101
  if (require_objectUtils.isRuleGroup(rule)) {
977
1102
  const processedGroup = processRuleGroup(rule, rg.rules.length === 1);
978
- // istanbul ignore else
1103
+ // v8 ignore else
979
1104
  if (processedGroup) {
980
1105
  if (!firstRule && precedingCombinator) {
981
1106
  processedRules.push(precedingCombinator);
@@ -1058,10 +1183,10 @@ const defaultRuleGroupProcessorPrisma = (ruleGroup, options) => {
1058
1183
  * @group Export
1059
1184
  */
1060
1185
  const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
1061
- // istanbul ignore next
1186
+ // v8 ignore next
1062
1187
  const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap, context = {} } = options;
1063
1188
  const { sequelizeOperators: Op } = context;
1064
- if (!Op) return;
1189
+ if (!Op) return void 0;
1065
1190
  const processRuleGroup = (rg, _outermost) => {
1066
1191
  if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return;
1067
1192
  const combinator = rg.combinator.toUpperCase();
@@ -1084,13 +1209,70 @@ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
1084
1209
  fieldData
1085
1210
  });
1086
1211
  }).filter(Boolean);
1087
- if (expressions.length === 0) return;
1212
+ if (expressions.length === 0) return void 0;
1088
1213
  const result = expressions.length === 1 && !hasChildRules ? expressions[0] : { [require_objectUtils.lc(combinator) === "or" ? Op.or : Op.and]: expressions };
1089
1214
  return rg.not ? { [Op.not]: result } : result;
1090
1215
  };
1091
1216
  return processRuleGroup(require_convertQuery.convertFromIC(ruleGroup), true);
1092
1217
  };
1093
1218
  //#endregion
1219
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSPARQL.ts
1220
+ /**
1221
+ * Rule group processor used by {@link formatQuery} for "sparql" format.
1222
+ *
1223
+ * SPARQL uses the same combinators as CEL (`&&` / `||`) and `!()` for negation.
1224
+ *
1225
+ * @group Export
1226
+ */
1227
+ const defaultRuleGroupProcessorSPARQL = (ruleGroup, options) => {
1228
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1229
+ const processRuleGroup = (rg, outermost) => {
1230
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
1231
+ const processedRules = [];
1232
+ let precedingCombinator = "";
1233
+ let firstRule = true;
1234
+ for (const rule of rg.rules) {
1235
+ if (typeof rule === "string") {
1236
+ precedingCombinator = require_utils.celCombinatorMap[rule];
1237
+ continue;
1238
+ }
1239
+ if (require_objectUtils.isRuleGroup(rule)) {
1240
+ const processedGroup = processRuleGroup(rule);
1241
+ if (processedGroup) {
1242
+ if (!firstRule && precedingCombinator) {
1243
+ processedRules.push(precedingCombinator);
1244
+ precedingCombinator = "";
1245
+ }
1246
+ firstRule = false;
1247
+ processedRules.push(processedGroup);
1248
+ }
1249
+ continue;
1250
+ }
1251
+ const [validationResult, fieldValidator] = validateRule(rule);
1252
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) continue;
1253
+ const fieldData = require_utils.getOption(fields, rule.field);
1254
+ const processedRule = ruleProcessor(rule, {
1255
+ ...options,
1256
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1257
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
1258
+ fieldData
1259
+ });
1260
+ if (processedRule) {
1261
+ if (!firstRule && precedingCombinator) {
1262
+ processedRules.push(precedingCombinator);
1263
+ precedingCombinator = "";
1264
+ }
1265
+ firstRule = false;
1266
+ processedRules.push(processedRule);
1267
+ }
1268
+ }
1269
+ const expression = processedRules.join(require_objectUtils.isRuleGroupType(rg) ? ` ${require_utils.celCombinatorMap[rg.combinator]} ` : " ");
1270
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""];
1271
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
1272
+ };
1273
+ return processRuleGroup(ruleGroup, true);
1274
+ };
1275
+ //#endregion
1094
1276
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts
1095
1277
  /**
1096
1278
  * Default rule processor used by {@link formatQuery} for "sql" format.
@@ -1100,7 +1282,7 @@ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
1100
1282
  const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
1101
1283
  const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1102
1284
  const processRuleGroup = (rg, outermostOrLonelyInGroup) => {
1103
- if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : "";
1285
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermostOrLonelyInGroup ? fallbackExpression : /* v8 ignore next -- @preserve */ "";
1104
1286
  const processedRules = [];
1105
1287
  let precedingCombinator = "";
1106
1288
  let firstRule = true;
@@ -1111,7 +1293,7 @@ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
1111
1293
  }
1112
1294
  if (require_objectUtils.isRuleGroup(rule)) {
1113
1295
  const processedGroup = processRuleGroup(rule, rg.rules.length === 1);
1114
- // istanbul ignore else
1296
+ // v8 ignore else
1115
1297
  if (processedGroup) {
1116
1298
  if (!firstRule && precedingCombinator) {
1117
1299
  processedRules.push(precedingCombinator);
@@ -1147,6 +1329,378 @@ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
1147
1329
  return processRuleGroup(ruleGroup, true);
1148
1330
  };
1149
1331
  //#endregion
1332
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorDiagnostics.ts
1333
+ const numericInputTypes = new Set([
1334
+ "number",
1335
+ "range",
1336
+ "bigint"
1337
+ ]);
1338
+ const dateRegex = /^\d{4}-\d{2}-\d{2}$/;
1339
+ const timeRegex = /^\d{2}:\d{2}(:\d{2}(\.\d+)?)?$/;
1340
+ const monthRegex = /^\d{4}-\d{2}$/;
1341
+ const weekRegex = /^\d{4}-W\d{2}$/;
1342
+ const colorRegex = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i;
1343
+ const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
1344
+ const isValidDateComponents = (y, m, d) => {
1345
+ const date = new Date(Date.UTC(y, m - 1, d));
1346
+ return date.getUTCFullYear() === y && date.getUTCMonth() === m - 1 && date.getUTCDate() === d;
1347
+ };
1348
+ const isValidTimeComponents = (s) => {
1349
+ const parts = s.split(":");
1350
+ const h = Number(parts[0]);
1351
+ const m = Number(parts[1]);
1352
+ const sec = parts[2] ? Number.parseFloat(parts[2]) : 0;
1353
+ return h >= 0 && h <= 23 && m >= 0 && m <= 59 && sec >= 0 && sec < 60;
1354
+ };
1355
+ /**
1356
+ * Checks whether a value is compatible with the given {@link FullField.inputType}.
1357
+ * Returns a diagnostic code string if there is a mismatch, or `undefined` if OK.
1358
+ */
1359
+ const checkValueTypeMismatch = (value, inputType) => {
1360
+ if (value === null || value === void 0 || value === "") return void 0;
1361
+ if (numericInputTypes.has(inputType)) {
1362
+ const v = typeof value === "string" ? value.trim() : value;
1363
+ if (typeof v === "number" || typeof v === "bigint") return void 0;
1364
+ if (typeof v === "string" && require_objectUtils.numericRegex.test(v)) return void 0;
1365
+ return "VALUE_TYPE_MISMATCH";
1366
+ }
1367
+ if (inputType === "date") {
1368
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1369
+ const v = value.trim();
1370
+ if (!dateRegex.test(v)) return "VALUE_TYPE_MISMATCH";
1371
+ const [y, m, d] = v.split("-").map(Number);
1372
+ return isValidDateComponents(y, m, d) ? void 0 : "VALUE_TYPE_MISMATCH";
1373
+ }
1374
+ if (inputType === "datetime-local") {
1375
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1376
+ const base = value.trim().replace(/(Z|[+-]\d{2}:?\d{2}|[+-]\d{2})$/, "");
1377
+ const tIndex = base.indexOf("T");
1378
+ if (tIndex === -1) return "VALUE_TYPE_MISMATCH";
1379
+ const datePart = base.slice(0, tIndex);
1380
+ const timePart = base.slice(tIndex + 1);
1381
+ if (!dateRegex.test(datePart) || !timeRegex.test(timePart)) return "VALUE_TYPE_MISMATCH";
1382
+ const [y, m, d] = datePart.split("-").map(Number);
1383
+ if (!isValidDateComponents(y, m, d)) return "VALUE_TYPE_MISMATCH";
1384
+ return isValidTimeComponents(timePart) ? void 0 : "VALUE_TYPE_MISMATCH";
1385
+ }
1386
+ if (inputType === "time") {
1387
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1388
+ const v = value.trim();
1389
+ if (!timeRegex.test(v)) return "VALUE_TYPE_MISMATCH";
1390
+ return isValidTimeComponents(v) ? void 0 : "VALUE_TYPE_MISMATCH";
1391
+ }
1392
+ if (inputType === "month") {
1393
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1394
+ const v = value.trim();
1395
+ if (!monthRegex.test(v)) return "VALUE_TYPE_MISMATCH";
1396
+ const m = Number(v.slice(5));
1397
+ return m >= 1 && m <= 12 ? void 0 : "VALUE_TYPE_MISMATCH";
1398
+ }
1399
+ if (inputType === "week") {
1400
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1401
+ const v = value.trim();
1402
+ if (!weekRegex.test(v)) return "VALUE_TYPE_MISMATCH";
1403
+ const w = Number(v.slice(6));
1404
+ return w >= 1 && w <= 53 ? void 0 : "VALUE_TYPE_MISMATCH";
1405
+ }
1406
+ if (inputType === "color") {
1407
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1408
+ return colorRegex.test(value.trim()) ? void 0 : "VALUE_TYPE_MISMATCH";
1409
+ }
1410
+ if (inputType === "url") {
1411
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1412
+ try {
1413
+ new URL(value.trim());
1414
+ return;
1415
+ } catch {
1416
+ return "VALUE_TYPE_MISMATCH";
1417
+ }
1418
+ }
1419
+ if (inputType === "email") {
1420
+ if (typeof value !== "string") return "VALUE_TYPE_MISMATCH";
1421
+ return emailRegex.test(value.trim()) ? void 0 : "VALUE_TYPE_MISMATCH";
1422
+ }
1423
+ };
1424
+ /**
1425
+ * Rule group processor used by {@link formatQuery} for "diagnostics" format.
1426
+ *
1427
+ * Produces a {@link DiagnosticsResult} containing an annotated copy of the query
1428
+ * tree (`query`) with `valid`, `reasons`, `path`, and `level` properties on every
1429
+ * rule and group; a flat `diagnostics` array; aggregate `stats`; and a per-field
1430
+ * `fieldSummary`.
1431
+ *
1432
+ * @group Export
1433
+ */
1434
+ const defaultRuleGroupProcessorDiagnostics = (ruleGroup, options) => {
1435
+ const { fields: fieldsOption, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap } = options;
1436
+ const diagnostics = [];
1437
+ const stats = {
1438
+ totalRules: 0,
1439
+ totalGroups: 0,
1440
+ validRules: 0,
1441
+ invalidRules: 0,
1442
+ validGroups: 0,
1443
+ invalidGroups: 0
1444
+ };
1445
+ const fieldSummary = {};
1446
+ const uniqueFields = require_utils.toFlatOptionArray(fieldsOption);
1447
+ const fieldsByName = /* @__PURE__ */ new Map();
1448
+ for (const f of uniqueFields) fieldsByName.set(f.name, f);
1449
+ const hasFieldsConfig = fieldsByName.size > 0;
1450
+ const processRuleGroup = (rg, path) => {
1451
+ stats.totalGroups++;
1452
+ const level = path.length;
1453
+ const groupValidationEntry = validationMap[rg.id ?? ""];
1454
+ const groupSelfValid = isRuleOrGroupValid(rg, groupValidationEntry);
1455
+ const groupReasons = getReasons(groupValidationEntry);
1456
+ if (rg.muted) diagnostics.push({
1457
+ id: rg.id ?? "",
1458
+ path,
1459
+ code: "MUTED",
1460
+ message: "Group is muted",
1461
+ source: "muted"
1462
+ });
1463
+ else if (!groupSelfValid && groupValidationEntry !== void 0) diagnostics.push({
1464
+ id: rg.id ?? "",
1465
+ path,
1466
+ code: "CUSTOM_VALIDATOR",
1467
+ message: groupReasons ? `Invalid: ${groupReasons.join(", ")}` : "Group failed validation",
1468
+ source: "query-validator"
1469
+ });
1470
+ let allChildrenValid = true;
1471
+ let ruleIndex = 0;
1472
+ const annotatedRules = [];
1473
+ for (const rule of rg.rules) {
1474
+ if (typeof rule === "string") {
1475
+ annotatedRules.push(rule);
1476
+ ruleIndex++;
1477
+ continue;
1478
+ }
1479
+ const childPath = [...path, ruleIndex];
1480
+ if (require_objectUtils.isRuleGroup(rule)) {
1481
+ const annotatedGroup = processRuleGroup(rule, childPath);
1482
+ if (!annotatedGroup.valid) allChildrenValid = false;
1483
+ annotatedRules.push(annotatedGroup);
1484
+ ruleIndex++;
1485
+ continue;
1486
+ }
1487
+ stats.totalRules++;
1488
+ const childLevel = childPath.length;
1489
+ const [validationResult, fieldValidator] = validateRule(rule);
1490
+ const ruleValid = isRuleOrGroupValid(rule, validationResult, fieldValidator) && rule.field !== placeholderFieldName && rule.operator !== placeholderOperatorName && !(placeholderValueName !== void 0 && rule.value === placeholderValueName);
1491
+ collectRuleDiagnostics(rule, childPath, validationResult, fieldValidator, ruleValid, diagnostics, placeholderFieldName, placeholderOperatorName, placeholderValueName, hasFieldsConfig, fieldsByName);
1492
+ if (!ruleValid) {
1493
+ allChildrenValid = false;
1494
+ stats.invalidRules++;
1495
+ } else stats.validRules++;
1496
+ const fieldName = rule.field;
1497
+ if (!fieldSummary[fieldName]) fieldSummary[fieldName] = {
1498
+ ruleCount: 0,
1499
+ invalidCount: 0
1500
+ };
1501
+ fieldSummary[fieldName].ruleCount++;
1502
+ if (!ruleValid) fieldSummary[fieldName].invalidCount++;
1503
+ const ruleReasons = getReasons(validationResult) ?? getFieldValidatorReasons(rule, fieldValidator);
1504
+ const annotatedRule = {
1505
+ ...rule,
1506
+ valid: ruleValid,
1507
+ ...ruleReasons ? { reasons: ruleReasons } : null,
1508
+ path: childPath,
1509
+ level: childLevel
1510
+ };
1511
+ annotatedRules.push(annotatedRule);
1512
+ ruleIndex++;
1513
+ }
1514
+ const groupValid = groupSelfValid && allChildrenValid;
1515
+ if (groupValid) stats.validGroups++;
1516
+ else stats.invalidGroups++;
1517
+ if (require_objectUtils.isRuleGroupType(rg)) return {
1518
+ ...rg,
1519
+ valid: groupValid,
1520
+ ...groupReasons ? { reasons: groupReasons } : null,
1521
+ path,
1522
+ level,
1523
+ rules: annotatedRules
1524
+ };
1525
+ return {
1526
+ ...rg,
1527
+ valid: groupValid,
1528
+ ...groupReasons ? { reasons: groupReasons } : null,
1529
+ path,
1530
+ level,
1531
+ rules: annotatedRules
1532
+ };
1533
+ };
1534
+ const query = processRuleGroup(ruleGroup, []);
1535
+ if (hasFieldsConfig) {
1536
+ const referencedFields = new Set(Object.keys(fieldSummary));
1537
+ for (const [fieldName] of fieldsByName) if (!referencedFields.has(fieldName)) diagnostics.push({
1538
+ id: "",
1539
+ path: [],
1540
+ code: "UNREFERENCED_FIELD",
1541
+ message: `Field "${fieldName}" is defined in the fields config but not used in the query`,
1542
+ source: "field-check"
1543
+ });
1544
+ }
1545
+ return {
1546
+ query,
1547
+ diagnostics,
1548
+ stats,
1549
+ fieldSummary
1550
+ };
1551
+ };
1552
+ /**
1553
+ * Collects diagnostic entries for a single rule.
1554
+ */
1555
+ const collectRuleDiagnostics = (rule, path, validationResult, fieldValidator, ruleValid, diagnostics, placeholderFieldName, placeholderOperatorName, placeholderValueName, hasFieldsConfig, fieldsByName) => {
1556
+ const id = rule.id ?? "";
1557
+ if (rule.muted) diagnostics.push({
1558
+ id,
1559
+ path,
1560
+ code: "MUTED",
1561
+ message: "Rule is muted",
1562
+ source: "muted"
1563
+ });
1564
+ if (rule.field === placeholderFieldName) diagnostics.push({
1565
+ id,
1566
+ path,
1567
+ code: "PLACEHOLDER_FIELD",
1568
+ message: "Rule has a placeholder field",
1569
+ source: "placeholder"
1570
+ });
1571
+ if (rule.operator === placeholderOperatorName) diagnostics.push({
1572
+ id,
1573
+ path,
1574
+ code: "PLACEHOLDER_OPERATOR",
1575
+ message: "Rule has a placeholder operator",
1576
+ source: "placeholder"
1577
+ });
1578
+ if (placeholderValueName !== void 0 && rule.value === placeholderValueName) diagnostics.push({
1579
+ id,
1580
+ path,
1581
+ code: "PLACEHOLDER_VALUE",
1582
+ message: "Rule has a placeholder value",
1583
+ source: "placeholder"
1584
+ });
1585
+ if (!rule.muted && rule.field !== placeholderFieldName && rule.operator !== placeholderOperatorName && !(placeholderValueName !== void 0 && rule.value === placeholderValueName)) {
1586
+ if (typeof validationResult === "boolean" && !validationResult) diagnostics.push({
1587
+ id,
1588
+ path,
1589
+ code: "CUSTOM_VALIDATOR",
1590
+ message: "Rule failed validation",
1591
+ source: "query-validator"
1592
+ });
1593
+ else if (typeof validationResult !== "boolean" && isValidationResult(validationResult) && !validationResult.valid) {
1594
+ const reasons = validationResult.reasons;
1595
+ diagnostics.push({
1596
+ id,
1597
+ path,
1598
+ code: "CUSTOM_VALIDATOR",
1599
+ message: reasons ? `Invalid: ${reasons.join(", ")}` : "Rule failed validation",
1600
+ source: "query-validator"
1601
+ });
1602
+ } else if (!ruleValid && typeof fieldValidator === "function") {
1603
+ const vr = fieldValidator(rule);
1604
+ const reasons = typeof vr !== "boolean" && isValidationResult(vr) && !vr.valid ? vr.reasons : void 0;
1605
+ diagnostics.push({
1606
+ id,
1607
+ path,
1608
+ code: "CUSTOM_VALIDATOR",
1609
+ message: reasons ? `Invalid: ${reasons.join(", ")}` : "Rule failed field validation",
1610
+ source: "field-validator"
1611
+ });
1612
+ }
1613
+ }
1614
+ if (hasFieldsConfig && !fieldsByName.has(rule.field) && rule.field !== placeholderFieldName) diagnostics.push({
1615
+ id,
1616
+ path,
1617
+ code: "UNDEFINED_FIELD",
1618
+ message: `Field "${rule.field}" is not defined in the fields config`,
1619
+ source: "field-check"
1620
+ });
1621
+ if (hasFieldsConfig) {
1622
+ const fieldDef = fieldsByName.get(rule.field);
1623
+ if (fieldDef?.inputType) {
1624
+ const mismatchCode = checkValueTypeMismatch(rule.value, fieldDef.inputType);
1625
+ if (mismatchCode) diagnostics.push({
1626
+ id,
1627
+ path,
1628
+ code: mismatchCode,
1629
+ message: `Value "${rule.value}" is not compatible with input type "${fieldDef.inputType}"`,
1630
+ source: "type-check"
1631
+ });
1632
+ }
1633
+ }
1634
+ };
1635
+ /**
1636
+ * Extracts `reasons` from a validation result, if present.
1637
+ */
1638
+ const getReasons = (validationResult) => {
1639
+ if (typeof validationResult !== "boolean" && isValidationResult(validationResult) && !validationResult.valid && validationResult.reasons) return validationResult.reasons;
1640
+ };
1641
+ /**
1642
+ * Runs a field-level validator and extracts `reasons` if present.
1643
+ */
1644
+ const getFieldValidatorReasons = (rule, fieldValidator) => {
1645
+ if (typeof fieldValidator === "function") {
1646
+ const vr = fieldValidator(rule);
1647
+ if (typeof vr !== "boolean" && isValidationResult(vr) && !vr.valid && vr.reasons) return vr.reasons;
1648
+ }
1649
+ };
1650
+ //#endregion
1651
+ //#region src/utils/formatQuery/defaultRuleProcessorCypher.ts
1652
+ const escapeSingleQuotes$1 = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll("'", "\\'");
1653
+ /**
1654
+ * Default rule processor used by {@link formatQuery} for "cypher" and "gql" formats.
1655
+ *
1656
+ * @group Export
1657
+ */
1658
+ const defaultRuleProcessorCypher = (rule, opts = {}) => {
1659
+ const { escapeQuotes, parseNumbers } = opts;
1660
+ const { field, operator, value, valueSource } = rule;
1661
+ const valueIsField = valueSource === "field";
1662
+ const operatorTL = operator.toLowerCase();
1663
+ const fmtVal = (v) => {
1664
+ if (v === null || v === void 0) return "null";
1665
+ if (typeof v === "boolean" || typeof v === "bigint") return String(v);
1666
+ if (valueIsField) return require_utils.trimIfString(v);
1667
+ if (typeof v === "number" || require_utils.shouldRenderAsNumber(v, parseNumbers)) return require_utils.trimIfString(v);
1668
+ return `'${escapeSingleQuotes$1(v, escapeQuotes)}'`;
1669
+ };
1670
+ switch (operatorTL) {
1671
+ case "=": return `${field} = ${fmtVal(value)}`;
1672
+ case "!=":
1673
+ case "<>": return `${field} <> ${fmtVal(value)}`;
1674
+ case "<":
1675
+ case ">":
1676
+ case "<=":
1677
+ case ">=": return `${field} ${operatorTL} ${fmtVal(value)}`;
1678
+ case "contains": return `${field} CONTAINS ${fmtVal(value)}`;
1679
+ case "doesnotcontain": return `NOT ${field} CONTAINS ${fmtVal(value)}`;
1680
+ case "beginswith": return `${field} STARTS WITH ${fmtVal(value)}`;
1681
+ case "doesnotbeginwith": return `NOT ${field} STARTS WITH ${fmtVal(value)}`;
1682
+ case "endswith": return `${field} ENDS WITH ${fmtVal(value)}`;
1683
+ case "doesnotendwith": return `NOT ${field} ENDS WITH ${fmtVal(value)}`;
1684
+ case "null": return `${field} IS NULL`;
1685
+ case "notnull": return `${field} IS NOT NULL`;
1686
+ case "in":
1687
+ case "notin": {
1688
+ const values = require_utils.toArray(value).map(fmtVal);
1689
+ if (!values.length) return "";
1690
+ return `${operatorTL === "notin" ? "NOT " : ""}${field} IN [${values.join(", ")}]`;
1691
+ }
1692
+ case "between":
1693
+ case "notbetween": {
1694
+ const arr = require_utils.toArray(value);
1695
+ if (arr.length < 2) return "";
1696
+ const [low, high] = [fmtVal(arr[0]), fmtVal(arr[1])];
1697
+ const expr = `${low} <= ${field} AND ${field} <= ${high}`;
1698
+ return operatorTL === "notbetween" ? `NOT (${expr})` : expr;
1699
+ }
1700
+ default: return `${field} ${operator} ${fmtVal(value)}`;
1701
+ }
1702
+ };
1703
+ //#endregion
1150
1704
  //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
1151
1705
  const rangeOperatorMap = {
1152
1706
  "<": "lt",
@@ -1298,6 +1852,68 @@ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
1298
1852
  return false;
1299
1853
  };
1300
1854
  //#endregion
1855
+ //#region src/utils/formatQuery/defaultRuleProcessorGremlin.ts
1856
+ const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll("'", "\\'");
1857
+ /**
1858
+ * Default rule processor used by {@link formatQuery} for "gremlin" format.
1859
+ *
1860
+ * Each rule becomes a `.has()` step (or `.hasNot()`/`.has()` for null checks).
1861
+ *
1862
+ * @group Export
1863
+ */
1864
+ const defaultRuleProcessorGremlin = (rule, opts = {}) => {
1865
+ const { escapeQuotes, parseNumbers } = opts;
1866
+ const { field, operator, value, valueSource } = rule;
1867
+ const valueIsField = valueSource === "field";
1868
+ const operatorTL = operator.toLowerCase();
1869
+ const prop = field.includes(".") ? field.split(".").pop() : field;
1870
+ const fmtVal = (v) => {
1871
+ if (v === null || v === void 0) return "null";
1872
+ if (typeof v === "boolean" || typeof v === "bigint") return String(v);
1873
+ if (valueIsField) return require_utils.trimIfString(v);
1874
+ if (typeof v === "number" || require_utils.shouldRenderAsNumber(v, parseNumbers)) return require_utils.trimIfString(v);
1875
+ return `'${escapeSingleQuotes(v, escapeQuotes)}'`;
1876
+ };
1877
+ switch (operatorTL) {
1878
+ case "=": return `.has('${prop}', ${fmtVal(value)})`;
1879
+ case "!=":
1880
+ case "<>": return `.has('${prop}', neq(${fmtVal(value)}))`;
1881
+ case "<": return `.has('${prop}', lt(${fmtVal(value)}))`;
1882
+ case ">": return `.has('${prop}', gt(${fmtVal(value)}))`;
1883
+ case "<=": return `.has('${prop}', lte(${fmtVal(value)}))`;
1884
+ case ">=": return `.has('${prop}', gte(${fmtVal(value)}))`;
1885
+ case "contains": return `.has('${prop}', containing(${fmtVal(value)}))`;
1886
+ case "doesnotcontain": return `.has('${prop}', notContaining(${fmtVal(value)}))`;
1887
+ case "beginswith": return `.has('${prop}', startingWith(${fmtVal(value)}))`;
1888
+ case "doesnotbeginwith": return `.has('${prop}', notStartingWith(${fmtVal(value)}))`;
1889
+ case "endswith": return `.has('${prop}', endingWith(${fmtVal(value)}))`;
1890
+ case "doesnotendwith": return `.has('${prop}', notEndingWith(${fmtVal(value)}))`;
1891
+ case "null": return `.hasNot('${prop}')`;
1892
+ case "notnull": return `.has('${prop}')`;
1893
+ case "in": {
1894
+ const items = require_utils.toArray(value).map(fmtVal);
1895
+ if (!items.length) return "";
1896
+ return `.has('${prop}', within(${items.join(", ")}))`;
1897
+ }
1898
+ case "notin": {
1899
+ const items = require_utils.toArray(value).map(fmtVal);
1900
+ if (!items.length) return "";
1901
+ return `.has('${prop}', without(${items.join(", ")}))`;
1902
+ }
1903
+ case "between": {
1904
+ const arr = require_utils.toArray(value);
1905
+ if (arr.length < 2) return "";
1906
+ return `.has('${prop}', between(${fmtVal(arr[0])}, ${fmtVal(arr[1])}))`;
1907
+ }
1908
+ case "notbetween": {
1909
+ const arr = require_utils.toArray(value);
1910
+ if (arr.length < 2) return "";
1911
+ return `.has('${prop}', outside(${fmtVal(arr[0])}, ${fmtVal(arr[1])}))`;
1912
+ }
1913
+ default: return `.has('${prop}', ${fmtVal(value)})`;
1914
+ }
1915
+ };
1916
+ //#endregion
1301
1917
  //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
1302
1918
  const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
1303
1919
  const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
@@ -1525,12 +2141,12 @@ const defaultRuleProcessorLDAP = (rule, options = {}) => {
1525
2141
  return negateIf(`(&(${field}>=${ldapEscape(firstValue)})(${field}<=${ldapEscape(secondValue)}))`, operatorLC === "notbetween");
1526
2142
  }
1527
2143
  }
1528
- // istanbul ignore next
2144
+ // v8 ignore next
1529
2145
  return "";
1530
2146
  };
1531
2147
  //#endregion
1532
2148
  //#region src/utils/formatQuery/defaultValueProcessorNL.ts
1533
- const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : v;
2149
+ const escapeStringValueQuotes = (v, quoteChar, escapeQuotes) => escapeQuotes && typeof v === "string" ? v.replaceAll(`${quoteChar}`, `${quoteChar}${quoteChar}`) : /* v8 ignore next -- @preserve */ v;
1534
2150
  /**
1535
2151
  * Default value processor used by {@link formatQuery} for "natural_language" format.
1536
2152
  *
@@ -1548,7 +2164,7 @@ const defaultValueProcessorNL = (rule, opts = {}) => {
1548
2164
  quoteFieldNamesWith,
1549
2165
  fieldIdentifierSeparator
1550
2166
  });
1551
- const t = translations ?? ( /* istanbul ignore next */ {});
2167
+ const t = translations ?? ( /* v8 ignore start -- @preserve */ {});
1552
2168
  const orTL = t.or ?? "or";
1553
2169
  const trueTL = t.true ?? "true";
1554
2170
  const falseTL = t.false ?? "false";
@@ -1604,7 +2220,7 @@ const defaultExportOperatorMap = {
1604
2220
  between: ["is between", "is between the values in"],
1605
2221
  notbetween: ["is not between", "is not between the values in"]
1606
2222
  };
1607
- /* istanbul ignore next */
2223
+ /* v8 ignore next -- @preserve */
1608
2224
  const defaultGetOperators = () => [];
1609
2225
  /**
1610
2226
  * Default operator processor used by {@link formatQuery} for "natural_language" format.
@@ -1613,7 +2229,7 @@ const defaultGetOperators = () => [];
1613
2229
  */
1614
2230
  const defaultOperatorProcessorNL = (rule, opts = {}) => {
1615
2231
  const { field, operator, valueSource = "value" } = rule;
1616
- // istanbul ignore next
2232
+ // v8 ignore next
1617
2233
  const { getOperators = defaultGetOperators, operatorMap: operatorMapParam = defaultExportOperatorMap } = opts;
1618
2234
  const mergedOperatorMap = new Map(Object.entries(defaultExportOperatorMap));
1619
2235
  for (const [key, value] of Object.entries(operatorMapParam)) mergedOperatorMap.set(require_objectUtils.lc(key), value);
@@ -1642,8 +2258,8 @@ const defaultOperatorProcessorNL = (rule, opts = {}) => {
1642
2258
  */
1643
2259
  const defaultRuleProcessorNL = (rule, opts) => {
1644
2260
  const { field, operator } = rule;
1645
- // istanbul ignore next
1646
- const { fieldData, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorNL, valueProcessor = defaultValueProcessorNL, concatOperator = "||", wordOrder = "SVO" } = opts ?? ( /* istanbul ignore next */ {});
2261
+ // v8 ignore next
2262
+ const { fieldData, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator = "", quoteValuesWith = `'`, operatorProcessor = defaultOperatorProcessorNL, valueProcessor = defaultValueProcessorNL, concatOperator = "||", wordOrder = "SVO" } = opts ?? ( /* v8 ignore start -- @preserve */ {});
1647
2263
  const processedField = require_utils.getQuotedFieldName(fieldData?.label ?? field, {
1648
2264
  quoteFieldNamesWith,
1649
2265
  fieldIdentifierSeparator
@@ -1749,7 +2365,7 @@ const defaultRuleProcessorSQL = (rule, opts = {}) => {
1749
2365
  * @group Export
1750
2366
  */
1751
2367
  const defaultRuleProcessorParameterized = (rule, opts, meta) => {
1752
- // istanbul ignore next
2368
+ // v8 ignore next
1753
2369
  const { fieldData, format, getNextNamedParam, parseNumbers, paramPrefix, paramsKeepPrefix, numberedParams, quoteFieldNamesWith = ["", ""], fieldIdentifierSeparator, concatOperator, operatorProcessor = defaultOperatorProcessorSQL, valueProcessor = defaultValueProcessorByRule } = opts ?? {};
1754
2370
  const { processedParams = [] } = meta ?? {};
1755
2371
  const parameterized = format === "parameterized";
@@ -1768,6 +2384,7 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
1768
2384
  });
1769
2385
  const ruleField = wrapFieldName(rule.field);
1770
2386
  const matchEval = require_utils.processMatchMode(rule);
2387
+ /* v8 ignore start -- @preserve */
1771
2388
  if (matchEval === false) return;
1772
2389
  else if (matchEval) {
1773
2390
  if (opts?.preset !== "postgresql") return finalize("");
@@ -1780,7 +2397,6 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
1780
2397
  ...opts,
1781
2398
  fields: []
1782
2399
  });
1783
- // istanbul ignore else
1784
2400
  if (Array.isArray(nestedParams)) params.push(...nestedParams);
1785
2401
  else Object.assign(paramsNamed, nestedParams);
1786
2402
  switch (mode) {
@@ -1795,6 +2411,7 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
1795
2411
  }
1796
2412
  }
1797
2413
  }
2414
+ /* v8 ignore stop -- @preserve */
1798
2415
  const value = valueProcessor(rule, {
1799
2416
  parseNumbers,
1800
2417
  quoteFieldNamesWith,
@@ -1835,7 +2452,7 @@ const defaultRuleProcessorParameterized = (rule, opts, meta) => {
1835
2452
  }
1836
2453
  let paramValue = rule.value;
1837
2454
  if (typeof rule.value === "string") if (require_utils.shouldRenderAsNumber(rule.value, parseNumbers)) paramValue = require_utils.parseNumber(rule.value, { parseNumbers });
1838
- else paramValue = /^'.*'$/g.test(value) ? value.replaceAll(/(^'|'$)/g, "") : value;
2455
+ else paramValue = /^'.*'$/g.test(value) ? value.replaceAll(/(^'|'$)/g, "") : /* v8 ignore next -- @preserve */ value;
1839
2456
  let paramName = "";
1840
2457
  if (parameterized) params.push(paramValue);
1841
2458
  else {
@@ -1854,9 +2471,9 @@ const processNumber = (value, fallback, parseNumbers) => require_utils.shouldRen
1854
2471
  */
1855
2472
  const defaultRuleProcessorPrisma = (rule, options = {}) => {
1856
2473
  const { field, operator, value, valueSource } = rule;
1857
- // istanbul ignore next
2474
+ // v8 ignore next
1858
2475
  const { parseNumbers, preserveValueOrder } = options;
1859
- if (valueSource === "field" || require_utils.processMatchMode(rule)) return;
2476
+ if (valueSource === "field" || require_utils.processMatchMode(rule)) return void 0;
1860
2477
  const operatorLC = require_objectUtils.lc(operator);
1861
2478
  switch (operatorLC) {
1862
2479
  case "=": return { [field]: processNumber(value, value, parseNumbers) };
@@ -1914,13 +2531,16 @@ const defaultRuleProcessorPrisma = (rule, options = {}) => {
1914
2531
  */
1915
2532
  const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder, context = {} } = {}) => {
1916
2533
  const { sequelizeOperators: Op, sequelizeCol: col, sequelizeFn: fn } = context;
1917
- if (require_utils.processMatchMode(rule)) return;
2534
+ if (require_utils.processMatchMode(rule)) return void 0;
1918
2535
  const { field, operator, value, valueSource } = rule;
1919
2536
  const valueIsField = valueSource === "field";
1920
2537
  const operatorLC = require_objectUtils.lc(operator);
1921
2538
  if (!Op || valueIsField && (!col || !fn && [
2539
+ "contains",
1922
2540
  "doesnotcontain",
2541
+ "beginswith",
1923
2542
  "doesnotbeginwith",
2543
+ "endswith",
1924
2544
  "doesnotendwith"
1925
2545
  ].includes(operatorLC))) return;
1926
2546
  switch (operatorLC) {
@@ -1940,9 +2560,9 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
1940
2560
  }[operatorLC];
1941
2561
  return { [field]: valueIsField && operatorLC === "=" ? { [Op.col]: value } : { [sequelizeOperator]: valueIsField ? col(value) : require_utils.shouldRenderAsNumber(value, parseNumbers) ? require_utils.parseNumber(value, { parseNumbers: "strict" }) : value } };
1942
2562
  }
1943
- case "contains": return { [field]: { [Op.substring]: valueIsField ? col(value) : `${value}` } };
1944
- case "beginswith": return { [field]: { [Op.startsWith]: valueIsField ? col(value) : `${value}` } };
1945
- case "endswith": return { [field]: { [Op.endsWith]: valueIsField ? col(value) : `${value}` } };
2563
+ case "contains": return { [field]: { [valueIsField ? Op.like : Op.substring]: valueIsField ? fn("CONCAT", "%", col(value), "%") : `${value}` } };
2564
+ case "beginswith": return { [field]: { [valueIsField ? Op.like : Op.startsWith]: valueIsField ? fn("CONCAT", col(value), "%") : `${value}` } };
2565
+ case "endswith": return { [field]: { [valueIsField ? Op.like : Op.endsWith]: valueIsField ? fn("CONCAT", "%", col(value)) : `${value}` } };
1946
2566
  case "doesnotcontain": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value), "%") : `%${value}%` } };
1947
2567
  case "doesnotbeginwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", col(value), "%") : `${value}%` } };
1948
2568
  case "doesnotendwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value)) : `%${value}` } };
@@ -1972,6 +2592,68 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
1972
2592
  }
1973
2593
  };
1974
2594
  //#endregion
2595
+ //#region src/utils/formatQuery/defaultRuleProcessorSPARQL.ts
2596
+ const escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
2597
+ /**
2598
+ * Default rule processor used by {@link formatQuery} for "sparql" format.
2599
+ *
2600
+ * @group Export
2601
+ */
2602
+ const defaultRuleProcessorSPARQL = (rule, opts = {}) => {
2603
+ const { escapeQuotes, parseNumbers } = opts;
2604
+ const { field, operator, value, valueSource } = rule;
2605
+ const valueIsField = valueSource === "field";
2606
+ const operatorTL = operator.toLowerCase();
2607
+ const fmtVal = (v) => {
2608
+ if (v === null || v === void 0) return "\"\"";
2609
+ if (typeof v === "boolean") return `"${v}"^^xsd:boolean`;
2610
+ if (typeof v === "bigint") return String(v);
2611
+ if (valueIsField) return require_utils.trimIfString(v);
2612
+ if (typeof v === "number" || require_utils.shouldRenderAsNumber(v, parseNumbers)) return require_utils.trimIfString(v);
2613
+ const s = typeof v === "string" ? v : JSON.stringify(v) ?? "";
2614
+ if (s.startsWith("?") || s.startsWith("<") || s.includes(":")) return s;
2615
+ return `"${escapeDoubleQuotes(s, escapeQuotes)}"`;
2616
+ };
2617
+ switch (operatorTL) {
2618
+ case "=":
2619
+ case "!=":
2620
+ case "<":
2621
+ case ">":
2622
+ case "<=":
2623
+ case ">=": return `${field} ${operatorTL} ${fmtVal(value)}`;
2624
+ case "<>": return `${field} != ${fmtVal(value)}`;
2625
+ case "contains": return `CONTAINS(${field}, ${fmtVal(value)})`;
2626
+ case "doesnotcontain": return `!CONTAINS(${field}, ${fmtVal(value)})`;
2627
+ case "beginswith": return `STRSTARTS(${field}, ${fmtVal(value)})`;
2628
+ case "doesnotbeginwith": return `!STRSTARTS(${field}, ${fmtVal(value)})`;
2629
+ case "endswith": return `STRENDS(${field}, ${fmtVal(value)})`;
2630
+ case "doesnotendwith": return `!STRENDS(${field}, ${fmtVal(value)})`;
2631
+ case "null": return `!BOUND(${field})`;
2632
+ case "notnull": return `BOUND(${field})`;
2633
+ case "in": {
2634
+ const items = require_utils.toArray(value).map(fmtVal);
2635
+ if (!items.length) return "";
2636
+ return items.map((item) => `${field} = ${item}`).join(" || ");
2637
+ }
2638
+ case "notin": {
2639
+ const items = require_utils.toArray(value).map(fmtVal);
2640
+ if (!items.length) return "";
2641
+ return items.map((item) => `${field} != ${item}`).join(" && ");
2642
+ }
2643
+ case "between": {
2644
+ const arr = require_utils.toArray(value);
2645
+ if (arr.length < 2) return "";
2646
+ return `${field} >= ${fmtVal(arr[0])} && ${field} <= ${fmtVal(arr[1])}`;
2647
+ }
2648
+ case "notbetween": {
2649
+ const arr = require_utils.toArray(value);
2650
+ if (arr.length < 2) return "";
2651
+ return `(${field} < ${fmtVal(arr[0])} || ${field} > ${fmtVal(arr[1])})`;
2652
+ }
2653
+ default: return `${field} ${operator} ${fmtVal(value)}`;
2654
+ }
2655
+ };
2656
+ //#endregion
1975
2657
  //#region src/utils/formatQuery/formatQuery.ts
1976
2658
  /**
1977
2659
  * A collection of option presets for {@link formatQuery}, specifically for SQL-based formats.
@@ -2018,9 +2700,14 @@ const defaultRuleProcessors = {
2018
2700
  prisma: defaultRuleProcessorPrisma,
2019
2701
  sequelize: defaultRuleProcessorSequelize,
2020
2702
  spel: defaultRuleProcessorSpEL,
2021
- sql: defaultRuleProcessorSQL
2703
+ sql: defaultRuleProcessorSQL,
2704
+ cypher: defaultRuleProcessorCypher,
2705
+ gql: defaultRuleProcessorCypher,
2706
+ sparql: defaultRuleProcessorSPARQL,
2707
+ gremlin: defaultRuleProcessorGremlin,
2708
+ diagnostics: defaultRuleProcessorSQL
2022
2709
  };
2023
- /* istanbul ignore next */
2710
+ /* v8 ignore next -- @preserve */
2024
2711
  const defaultOperatorProcessor = (r) => r.operator;
2025
2712
  const defaultOperatorProcessors = {
2026
2713
  cel: defaultOperatorProcessor,
@@ -2039,13 +2726,20 @@ const defaultOperatorProcessors = {
2039
2726
  prisma: defaultOperatorProcessor,
2040
2727
  sequelize: defaultOperatorProcessor,
2041
2728
  spel: defaultOperatorProcessor,
2042
- sql: defaultOperatorProcessorSQL
2729
+ sql: defaultOperatorProcessorSQL,
2730
+ cypher: defaultOperatorProcessor,
2731
+ gql: defaultOperatorProcessor,
2732
+ sparql: defaultOperatorProcessor,
2733
+ gremlin: defaultOperatorProcessor,
2734
+ diagnostics: defaultOperatorProcessor
2043
2735
  };
2044
2736
  const defaultFallbackExpressions = {
2045
2737
  cel: "1 == 1",
2046
2738
  ldap: "",
2047
2739
  mongodb: "\"$and\":[{\"$expr\":true}]",
2048
2740
  natural_language: "1 is 1",
2741
+ sparql: "1 = 1",
2742
+ gremlin: "",
2049
2743
  spel: "1 == 1",
2050
2744
  sql: "(1 = 1)"
2051
2745
  };
@@ -2113,24 +2807,26 @@ function formatQuery(ruleGroup, optionParam = {}) {
2113
2807
  const getOperators = (f, m) => require_utils.toFullOptionList(getOperators_option(f, m) ?? []);
2114
2808
  const fallbackExpression = fallbackExpression_option ?? defaultFallbackExpressions[format] ?? defaultFallbackExpressions.sql;
2115
2809
  let validationMap = {};
2116
- // istanbul ignore else
2810
+ // v8 ignore else
2117
2811
  if (typeof validator === "function") {
2118
2812
  const validationResult = validator(ruleGroup);
2119
2813
  if (typeof validationResult === "boolean") {
2120
- // istanbul ignore else
2121
- if (!validationResult) return format === "parameterized" ? {
2122
- sql: fallbackExpression,
2123
- params: []
2124
- } : format === "parameterized_named" ? {
2125
- sql: fallbackExpression,
2126
- params: {}
2127
- } : format === "mongodb" ? `{${fallbackExpression}}` : format === "mongodb_query" ? mongoDbFallback : format === "prisma" ? prismaFallback : format === "jsonlogic" ? false : format === "elasticsearch" ? {} : format === "drizzle" || format === "sequelize" ? void 0 : fallbackExpression;
2814
+ // v8 ignore else
2815
+ if (!validationResult) {
2816
+ if (format !== "diagnostics") return format === "parameterized" ? {
2817
+ sql: fallbackExpression,
2818
+ params: []
2819
+ } : format === "parameterized_named" ? {
2820
+ sql: fallbackExpression,
2821
+ params: {}
2822
+ } : format === "mongodb" ? `{${fallbackExpression}}` : format === "mongodb_query" ? mongoDbFallback : format === "prisma" ? prismaFallback : format === "jsonlogic" ? false : format === "elasticsearch" ? {} : format === "drizzle" || format === "sequelize" ? void 0 : fallbackExpression;
2823
+ }
2128
2824
  } else validationMap = validationResult;
2129
2825
  }
2130
2826
  const validatorMap = {};
2131
2827
  const uniqueFields = require_utils.toFlatOptionArray(fields);
2132
2828
  for (const f of uniqueFields)
2133
- // istanbul ignore else
2829
+ // v8 ignore else
2134
2830
  if (typeof f.validator === "function") validatorMap[f.value ?? f.name] = f.validator;
2135
2831
  const validateRule = (rule) => {
2136
2832
  let validationResult;
@@ -2140,7 +2836,7 @@ function formatQuery(ruleGroup, optionParam = {}) {
2140
2836
  const fieldArr = uniqueFields.filter((f) => f.name === rule.field);
2141
2837
  if (fieldArr.length > 0) {
2142
2838
  const field = fieldArr[0];
2143
- // istanbul ignore else
2839
+ // v8 ignore else
2144
2840
  if (typeof field.validator === "function") fieldValidator = field.validator;
2145
2841
  }
2146
2842
  }
@@ -2184,6 +2880,11 @@ function formatQuery(ruleGroup, optionParam = {}) {
2184
2880
  case "prisma": return defaultRuleGroupProcessorPrisma(ruleGroup, finalOptions);
2185
2881
  case "drizzle": return defaultRuleGroupProcessorDrizzle(ruleGroup, finalOptions);
2186
2882
  case "sequelize": return defaultRuleGroupProcessorSequelize(ruleGroup, finalOptions);
2883
+ case "cypher":
2884
+ case "gql": return defaultRuleGroupProcessorCypher(ruleGroup, finalOptions);
2885
+ case "sparql": return defaultRuleGroupProcessorSPARQL(ruleGroup, finalOptions);
2886
+ case "gremlin": return defaultRuleGroupProcessorGremlin(ruleGroup, finalOptions);
2887
+ case "diagnostics": return defaultRuleGroupProcessorDiagnostics(ruleGroup, finalOptions);
2187
2888
  default: return "";
2188
2889
  }
2189
2890
  }
@@ -2241,6 +2942,7 @@ const defaultValueProcessorSpELByRule = defaultRuleProcessorSpEL;
2241
2942
  exports.bigIntJsonParseReviver = require_utils.bigIntJsonParseReviver;
2242
2943
  exports.bigIntJsonStringifyReplacer = require_utils.bigIntJsonStringifyReplacer;
2243
2944
  exports.celCombinatorMap = require_utils.celCombinatorMap;
2945
+ exports.cypherCombinatorMap = cypherCombinatorMap;
2244
2946
  exports.defaultCELValueProcessor = defaultCELValueProcessor;
2245
2947
  exports.defaultExportOperatorMap = defaultExportOperatorMap;
2246
2948
  exports.defaultMongoDBValueProcessor = defaultMongoDBValueProcessor;
@@ -2248,8 +2950,11 @@ exports.defaultNLTranslations = require_utils.defaultNLTranslations;
2248
2950
  exports.defaultOperatorProcessorNL = defaultOperatorProcessorNL;
2249
2951
  exports.defaultOperatorProcessorSQL = defaultOperatorProcessorSQL;
2250
2952
  exports.defaultRuleGroupProcessorCEL = defaultRuleGroupProcessorCEL;
2953
+ exports.defaultRuleGroupProcessorCypher = defaultRuleGroupProcessorCypher;
2954
+ exports.defaultRuleGroupProcessorDiagnostics = defaultRuleGroupProcessorDiagnostics;
2251
2955
  exports.defaultRuleGroupProcessorDrizzle = defaultRuleGroupProcessorDrizzle;
2252
2956
  exports.defaultRuleGroupProcessorElasticSearch = defaultRuleGroupProcessorElasticSearch;
2957
+ exports.defaultRuleGroupProcessorGremlin = defaultRuleGroupProcessorGremlin;
2253
2958
  exports.defaultRuleGroupProcessorJSONata = defaultRuleGroupProcessorJSONata;
2254
2959
  exports.defaultRuleGroupProcessorJsonLogic = defaultRuleGroupProcessorJsonLogic;
2255
2960
  exports.defaultRuleGroupProcessorLDAP = defaultRuleGroupProcessorLDAP;
@@ -2258,12 +2963,15 @@ exports.defaultRuleGroupProcessorMongoDBQuery = defaultRuleGroupProcessorMongoDB
2258
2963
  exports.defaultRuleGroupProcessorNL = defaultRuleGroupProcessorNL;
2259
2964
  exports.defaultRuleGroupProcessorParameterized = defaultRuleGroupProcessorParameterized;
2260
2965
  exports.defaultRuleGroupProcessorPrisma = defaultRuleGroupProcessorPrisma;
2966
+ exports.defaultRuleGroupProcessorSPARQL = defaultRuleGroupProcessorSPARQL;
2261
2967
  exports.defaultRuleGroupProcessorSQL = defaultRuleGroupProcessorSQL;
2262
2968
  exports.defaultRuleGroupProcessorSequelize = defaultRuleGroupProcessorSequelize;
2263
2969
  exports.defaultRuleGroupProcessorSpEL = defaultRuleGroupProcessorSpEL;
2264
2970
  exports.defaultRuleProcessorCEL = defaultRuleProcessorCEL;
2971
+ exports.defaultRuleProcessorCypher = defaultRuleProcessorCypher;
2265
2972
  exports.defaultRuleProcessorDrizzle = defaultRuleProcessorDrizzle;
2266
2973
  exports.defaultRuleProcessorElasticSearch = defaultRuleProcessorElasticSearch;
2974
+ exports.defaultRuleProcessorGremlin = defaultRuleProcessorGremlin;
2267
2975
  exports.defaultRuleProcessorJSONata = defaultRuleProcessorJSONata;
2268
2976
  exports.defaultRuleProcessorJsonLogic = defaultRuleProcessorJsonLogic;
2269
2977
  exports.defaultRuleProcessorLDAP = defaultRuleProcessorLDAP;
@@ -2272,6 +2980,7 @@ exports.defaultRuleProcessorMongoDBQuery = defaultRuleProcessorMongoDBQuery;
2272
2980
  exports.defaultRuleProcessorNL = defaultRuleProcessorNL;
2273
2981
  exports.defaultRuleProcessorParameterized = defaultRuleProcessorParameterized;
2274
2982
  exports.defaultRuleProcessorPrisma = defaultRuleProcessorPrisma;
2983
+ exports.defaultRuleProcessorSPARQL = defaultRuleProcessorSPARQL;
2275
2984
  exports.defaultRuleProcessorSQL = defaultRuleProcessorSQL;
2276
2985
  exports.defaultRuleProcessorSequelize = defaultRuleProcessorSequelize;
2277
2986
  exports.defaultRuleProcessorSpEL = defaultRuleProcessorSpEL;