@react-querybuilder/core 8.15.0 → 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 (84) hide show
  1. package/README.md +114 -53
  2. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +89 -16
  3. package/dist/cjs/react-querybuilder_core.cjs.development.js +402 -19
  4. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  5. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +89 -16
  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/formatQuery.d.mts +67 -2
  9. package/dist/formatQuery.d.ts +67 -2
  10. package/dist/formatQuery.js +402 -19
  11. package/dist/formatQuery.js.map +1 -1
  12. package/dist/formatQuery.mjs +396 -20
  13. package/dist/formatQuery.mjs.map +1 -1
  14. package/dist/{import-0wp72lLT.d.mts → import-BHlzBLM_.d.mts} +2 -2
  15. package/dist/{import-yRVJh7E1.d.ts → import-C6imciDf.d.ts} +2 -2
  16. package/dist/{index-D5TXNIzF.d.ts → index-Cjapnb-H.d.ts} +14 -7
  17. package/dist/{index-Lht_Wq3V.d.mts → index-D-Iej37L.d.mts} +14 -7
  18. package/dist/parseCEL.d.mts +2 -2
  19. package/dist/parseCEL.d.ts +2 -2
  20. package/dist/parseCEL.js.map +1 -1
  21. package/dist/parseCEL.mjs.map +1 -1
  22. package/dist/parseCypher.d.mts +49 -0
  23. package/dist/parseCypher.d.ts +49 -0
  24. package/dist/parseCypher.js +578 -0
  25. package/dist/parseCypher.js.map +1 -0
  26. package/dist/parseCypher.mjs +575 -0
  27. package/dist/parseCypher.mjs.map +1 -0
  28. package/dist/parseGremlin.d.mts +35 -0
  29. package/dist/parseGremlin.d.ts +35 -0
  30. package/dist/parseGremlin.js +192 -0
  31. package/dist/parseGremlin.js.map +1 -0
  32. package/dist/parseGremlin.mjs +191 -0
  33. package/dist/parseGremlin.mjs.map +1 -0
  34. package/dist/parseJSONata.d.mts +2 -2
  35. package/dist/parseJSONata.d.ts +2 -2
  36. package/dist/parseJSONata.js.map +1 -1
  37. package/dist/parseJSONata.mjs.map +1 -1
  38. package/dist/parseJsonLogic.d.mts +2 -2
  39. package/dist/parseJsonLogic.d.ts +2 -2
  40. package/dist/parseJsonLogic.js.map +1 -1
  41. package/dist/parseJsonLogic.mjs.map +1 -1
  42. package/dist/parseMongoDB.d.mts +2 -2
  43. package/dist/parseMongoDB.d.ts +2 -2
  44. package/dist/parseMongoDB.js.map +1 -1
  45. package/dist/parseMongoDB.mjs.map +1 -1
  46. package/dist/parseSPARQL.d.mts +34 -0
  47. package/dist/parseSPARQL.d.ts +34 -0
  48. package/dist/parseSPARQL.js +253 -0
  49. package/dist/parseSPARQL.js.map +1 -0
  50. package/dist/parseSPARQL.mjs +251 -0
  51. package/dist/parseSPARQL.mjs.map +1 -0
  52. package/dist/parseSQL.d.mts +2 -2
  53. package/dist/parseSQL.d.ts +2 -2
  54. package/dist/parseSQL.js.map +1 -1
  55. package/dist/parseSQL.mjs.map +1 -1
  56. package/dist/parseSpEL.d.mts +2 -2
  57. package/dist/parseSpEL.d.ts +2 -2
  58. package/dist/parseSpEL.js.map +1 -1
  59. package/dist/parseSpEL.mjs.map +1 -1
  60. package/dist/prepareQueryObjects-BoG5Rt8z.js.map +1 -1
  61. package/dist/prepareQueryObjects-uA10ZpZX.mjs.map +1 -1
  62. package/dist/react-querybuilder_core.d.mts +89 -16
  63. package/dist/react-querybuilder_core.legacy-esm.d.ts +89 -16
  64. package/dist/react-querybuilder_core.legacy-esm.js +408 -27
  65. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  66. package/dist/react-querybuilder_core.mjs +396 -20
  67. package/dist/react-querybuilder_core.mjs.map +1 -1
  68. package/dist/react-querybuilder_core.production.d.mts +89 -16
  69. package/dist/react-querybuilder_core.production.mjs +1 -1
  70. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  71. package/dist/transformQuery.d.mts +1 -1
  72. package/dist/transformQuery.d.ts +1 -1
  73. package/formatQuery/package.json +1 -1
  74. package/package.json +47 -3
  75. package/parseCEL/package.json +1 -1
  76. package/parseCypher/package.json +4 -0
  77. package/parseGremlin/package.json +4 -0
  78. package/parseJSONata/package.json +1 -1
  79. package/parseJsonLogic/package.json +1 -1
  80. package/parseMongoDB/package.json +1 -1
  81. package/parseSPARQL/package.json +4 -0
  82. package/parseSQL/package.json +1 -1
  83. package/parseSpEL/package.json +1 -1
  84. package/transformQuery/package.json +1 -1
@@ -1482,7 +1482,7 @@ const defaultRuleGroupProcessorCEL = (ruleGroup, options) => {
1482
1482
  //#endregion
1483
1483
  //#region src/utils/formatQuery/defaultRuleProcessorCEL.ts
1484
1484
  const shouldNegate$2 = (op) => op.startsWith("not") || op.startsWith("doesnot");
1485
- const escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
1485
+ const escapeDoubleQuotes$1 = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
1486
1486
  /**
1487
1487
  * Default rule processor used by {@link formatQuery} for "cel" format.
1488
1488
  *
@@ -1524,19 +1524,19 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
1524
1524
  case "==":
1525
1525
  case "!=":
1526
1526
  case ">":
1527
- case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`}`;
1527
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`}`;
1528
1528
  case "contains":
1529
- case "doesnotcontain": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.contains(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
1529
+ case "doesnotcontain": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.contains(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`})`;
1530
1530
  case "beginswith":
1531
- case "doesnotbeginwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.startsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
1531
+ case "doesnotbeginwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.startsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`})`;
1532
1532
  case "endswith":
1533
- case "doesnotendwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.endsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes(value, escapeQuotes)}"`})`;
1533
+ case "doesnotendwith": return `${shouldNegate$2(operatorTL) ? "!" : ""}${field}.endsWith(${valueIsField ? trimIfString(value) : `"${escapeDoubleQuotes$1(value, escapeQuotes)}"`})`;
1534
1534
  case "null": return `${field} == null`;
1535
1535
  case "notnull": return `${field} != null`;
1536
1536
  case "in":
1537
1537
  case "notin": {
1538
1538
  const [prefix, suffix] = shouldNegate$2(operatorTL) ? ["!(", ")"] : ["", ""];
1539
- return `${prefix}${field} in [${toArray(value).map((val) => valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `"${escapeDoubleQuotes(val, escapeQuotes)}"`).join(", ")}]${suffix}`;
1539
+ return `${prefix}${field} in [${toArray(value).map((val) => valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `"${escapeDoubleQuotes$1(val, escapeQuotes)}"`).join(", ")}]${suffix}`;
1540
1540
  }
1541
1541
  case "between":
1542
1542
  case "notbetween": {
@@ -1546,8 +1546,8 @@ const defaultRuleProcessorCEL = (rule, opts = {}) => {
1546
1546
  const shouldParseNumbers = !(parseNumbers === false);
1547
1547
  const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
1548
1548
  const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
1549
- let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes(first, escapeQuotes)}"` : firstNum;
1550
- let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `"${escapeDoubleQuotes(second, escapeQuotes)}"` : secondNum;
1549
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `"${escapeDoubleQuotes$1(first, escapeQuotes)}"` : firstNum;
1550
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `"${escapeDoubleQuotes$1(second, escapeQuotes)}"` : secondNum;
1551
1551
  if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1552
1552
  const tempNum = secondNum;
1553
1553
  secondValue = firstNum;
@@ -1803,7 +1803,7 @@ const defaultRuleGroupProcessorSpEL = (ruleGroup, options) => {
1803
1803
  //#region src/utils/formatQuery/defaultRuleProcessorSpEL.ts
1804
1804
  const shouldNegate$1 = (op) => op.startsWith("not") || op.startsWith("doesnot");
1805
1805
  const wrapInNegation = (clause, negate) => negate ? `!(${clause})` : clause;
1806
- const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
1806
+ const escapeSingleQuotes$2 = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`'`, `\\'`);
1807
1807
  /**
1808
1808
  * Default rule processor used by {@link formatQuery} for "spel" format.
1809
1809
  *
@@ -1844,20 +1844,20 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1844
1844
  case "==":
1845
1845
  case "!=":
1846
1846
  case ">":
1847
- case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`;
1847
+ case ">=": return `${field} ${operatorTL} ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes$2(value, escapeQuotes)}'`}`;
1848
1848
  case "contains":
1849
- case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
1849
+ case "doesnotcontain": return wrapInNegation(`${field} matches ${valueIsField || useBareValue ? trimIfString(value) : `'${escapeSingleQuotes$2(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
1850
1850
  case "beginswith":
1851
- case "doesnotbeginwith": return wrapInNegation(`${field} matches ${valueIsField ? `'^'.concat(${trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
1851
+ case "doesnotbeginwith": return wrapInNegation(`${field} matches ${valueIsField ? `'^'.concat(${trimIfString(value)})` : `'${typeof value === "string" && !value.startsWith("^") || useBareValue ? "^" : ""}${escapeSingleQuotes$2(value, escapeQuotes)}'`}`, shouldNegate$1(operatorTL));
1852
1852
  case "endswith":
1853
- case "doesnotendwith": return wrapInNegation(`${field} matches ${valueIsField ? `${trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`}`, shouldNegate$1(operatorTL));
1853
+ case "doesnotendwith": return wrapInNegation(`${field} matches ${valueIsField ? `${trimIfString(value)}.concat('$')` : `'${escapeSingleQuotes$2(value, escapeQuotes)}${typeof value === "string" && !value.endsWith("$") || useBareValue ? "$" : ""}'`}`, shouldNegate$1(operatorTL));
1854
1854
  case "null": return `${field} == null`;
1855
1855
  case "notnull": return `${field} != null`;
1856
1856
  case "in":
1857
1857
  case "notin": {
1858
1858
  const negate = shouldNegate$1(operatorTL) ? "!" : "";
1859
1859
  const valueAsArray = toArray(value);
1860
- return valueAsArray.length > 0 ? `${negate}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes(val, escapeQuotes)}'`}`).join(" or ")})` : "";
1860
+ return valueAsArray.length > 0 ? `${negate}(${valueAsArray.map((val) => `${field} == ${valueIsField || shouldRenderAsNumber(val, parseNumbers) ? `${trimIfString(val)}` : `'${escapeSingleQuotes$2(val, escapeQuotes)}'`}`).join(" or ")})` : "";
1861
1861
  }
1862
1862
  case "between":
1863
1863
  case "notbetween": {
@@ -1867,8 +1867,8 @@ const defaultRuleProcessorSpEL = (rule, opts = {}) => {
1867
1867
  const shouldParseNumbers = !(parseNumbers === false);
1868
1868
  const firstNum = shouldRenderAsNumber(first, shouldParseNumbers) ? parseNumber(first, { parseNumbers: shouldParseNumbers }) : NaN;
1869
1869
  const secondNum = shouldRenderAsNumber(second, shouldParseNumbers) ? parseNumber(second, { parseNumbers: shouldParseNumbers }) : NaN;
1870
- let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes(first, escapeQuotes)}'` : firstNum;
1871
- let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `'${escapeSingleQuotes(second, escapeQuotes)}'` : secondNum;
1870
+ let firstValue = Number.isNaN(firstNum) ? valueIsField ? `${first}` : `'${escapeSingleQuotes$2(first, escapeQuotes)}'` : firstNum;
1871
+ let secondValue = Number.isNaN(secondNum) ? valueIsField ? `${second}` : `'${escapeSingleQuotes$2(second, escapeQuotes)}'` : secondNum;
1872
1872
  if (!preserveValueOrder && firstValue === firstNum && secondValue === secondNum && secondNum < firstNum) {
1873
1873
  const tempNum = secondNum;
1874
1874
  secondValue = firstNum;
@@ -1936,6 +1936,70 @@ const defaultValueProcessorByRule = ({ operator, value, valueSource }, { escapeQ
1936
1936
  return valueIsField ? wrapFieldName(value) : shouldRenderAsNumber(value, parseNumbers) ? `${trimIfString(value)}` : `${wrapAndEscape(value)}`;
1937
1937
  };
1938
1938
  //#endregion
1939
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorCypher.ts
1940
+ /**
1941
+ * Maps a {@link DefaultCombinatorName} to a Cypher combinator keyword.
1942
+ *
1943
+ * @group Export
1944
+ */
1945
+ const cypherCombinatorMap = {
1946
+ and: "AND",
1947
+ or: "OR"
1948
+ };
1949
+ /**
1950
+ * Rule group processor used by {@link formatQuery} for "cypher" and "gql" formats.
1951
+ *
1952
+ * @group Export
1953
+ */
1954
+ const defaultRuleGroupProcessorCypher = (ruleGroup, options) => {
1955
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
1956
+ const processRuleGroup = (rg, outermost) => {
1957
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
1958
+ const processedRules = [];
1959
+ let precedingCombinator = "";
1960
+ let firstRule = true;
1961
+ for (const rule of rg.rules) {
1962
+ if (typeof rule === "string") {
1963
+ precedingCombinator = cypherCombinatorMap[rule];
1964
+ continue;
1965
+ }
1966
+ if (isRuleGroup(rule)) {
1967
+ const processedGroup = processRuleGroup(rule);
1968
+ if (processedGroup) {
1969
+ if (!firstRule && precedingCombinator) {
1970
+ processedRules.push(precedingCombinator);
1971
+ precedingCombinator = "";
1972
+ }
1973
+ firstRule = false;
1974
+ processedRules.push(processedGroup);
1975
+ }
1976
+ continue;
1977
+ }
1978
+ const [validationResult, fieldValidator] = validateRule(rule);
1979
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) continue;
1980
+ const fieldData = getOption(fields, rule.field);
1981
+ const processedRule = ruleProcessor(rule, {
1982
+ ...options,
1983
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
1984
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
1985
+ fieldData
1986
+ });
1987
+ if (processedRule) {
1988
+ if (!firstRule && precedingCombinator) {
1989
+ processedRules.push(precedingCombinator);
1990
+ precedingCombinator = "";
1991
+ }
1992
+ firstRule = false;
1993
+ processedRules.push(processedRule);
1994
+ }
1995
+ }
1996
+ const expression = processedRules.join(isRuleGroupType(rg) ? ` ${cypherCombinatorMap[rg.combinator]} ` : " ");
1997
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "NOT " : ""}(`, ")"] : ["", ""];
1998
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
1999
+ };
2000
+ return processRuleGroup(ruleGroup, true);
2001
+ };
2002
+ //#endregion
1939
2003
  //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
1940
2004
  /**
1941
2005
  * Default rule processor used by {@link formatQuery} for the "drizzle" format.
@@ -2103,6 +2167,67 @@ const defaultRuleGroupProcessorElasticSearch = (ruleGroup, options) => {
2103
2167
  return processedRuleGroup === false ? {} : processedRuleGroup;
2104
2168
  };
2105
2169
  //#endregion
2170
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorGremlin.ts
2171
+ /**
2172
+ * Rule group processor used by {@link formatQuery} for "gremlin" format.
2173
+ *
2174
+ * At the top level, filter rules produce chained `.has()` steps (implicit AND).
2175
+ * Nested groups use `.and()` / `.or()` / `.not()` compound traversals with
2176
+ * `__` anonymous traversal prefixes.
2177
+ *
2178
+ * @group Export
2179
+ */
2180
+ const defaultRuleGroupProcessorGremlin = (ruleGroup, options) => {
2181
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2182
+ const validateAndProcess = (rule) => {
2183
+ // v8 ignore next -- @preserve
2184
+ if (typeof rule === "string" || isRuleGroup(rule)) return void 0;
2185
+ const [validationResult, fieldValidator] = validateRule(rule);
2186
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) return;
2187
+ const fieldData = getOption(fields, rule.field);
2188
+ return ruleProcessor(rule, {
2189
+ ...options,
2190
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
2191
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
2192
+ fieldData
2193
+ });
2194
+ };
2195
+ /** Recursively processes a nested group into `.and()`/`.or()`/`.not()` form. */
2196
+ const processNested = (rg) => {
2197
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return "";
2198
+ const predicates = [];
2199
+ for (const rule of rg.rules) {
2200
+ if (typeof rule === "string") continue;
2201
+ if (isRuleGroup(rule)) {
2202
+ const nested = processNested(rule);
2203
+ if (nested) predicates.push(nested);
2204
+ continue;
2205
+ }
2206
+ const processed = validateAndProcess(rule);
2207
+ if (processed) predicates.push(processed);
2208
+ }
2209
+ if (predicates.length === 0) return "";
2210
+ const combinator = rg.combinator ?? "and";
2211
+ const prefix = rg.not ? "not" : combinator;
2212
+ if (predicates.length === 1 && !rg.not) return predicates[0];
2213
+ return `.${prefix}(${predicates.map((p) => p.startsWith(".") ? `__${p}` : p).join(", ")})`;
2214
+ };
2215
+ if (!isRuleOrGroupValid(ruleGroup, validationMap[ruleGroup.id ?? ""])) return fallbackExpression;
2216
+ const steps = [];
2217
+ for (const rule of ruleGroup.rules) {
2218
+ if (typeof rule === "string") continue;
2219
+ if (isRuleGroup(rule)) {
2220
+ const compound = processNested(rule);
2221
+ if (compound) steps.push(compound);
2222
+ continue;
2223
+ }
2224
+ const processed = validateAndProcess(rule);
2225
+ if (processed) steps.push(processed);
2226
+ }
2227
+ if (steps.length === 0) return fallbackExpression;
2228
+ return steps.join("");
2229
+ };
2230
+ //#endregion
2106
2231
  //#region src/utils/formatQuery/defaultRuleGroupProcessorJSONata.ts
2107
2232
  /**
2108
2233
  * Rule group processor used by {@link formatQuery} for "jsonata" format.
@@ -2490,6 +2615,63 @@ const defaultRuleGroupProcessorSequelize = (ruleGroup, options) => {
2490
2615
  return processRuleGroup(convertFromIC(ruleGroup), true);
2491
2616
  };
2492
2617
  //#endregion
2618
+ //#region src/utils/formatQuery/defaultRuleGroupProcessorSPARQL.ts
2619
+ /**
2620
+ * Rule group processor used by {@link formatQuery} for "sparql" format.
2621
+ *
2622
+ * SPARQL uses the same combinators as CEL (`&&` / `||`) and `!()` for negation.
2623
+ *
2624
+ * @group Export
2625
+ */
2626
+ const defaultRuleGroupProcessorSPARQL = (ruleGroup, options) => {
2627
+ const { fields, fallbackExpression, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, ruleProcessor, validateRule, validationMap } = options;
2628
+ const processRuleGroup = (rg, outermost) => {
2629
+ if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return outermost ? fallbackExpression : "";
2630
+ const processedRules = [];
2631
+ let precedingCombinator = "";
2632
+ let firstRule = true;
2633
+ for (const rule of rg.rules) {
2634
+ if (typeof rule === "string") {
2635
+ precedingCombinator = celCombinatorMap[rule];
2636
+ continue;
2637
+ }
2638
+ if (isRuleGroup(rule)) {
2639
+ const processedGroup = processRuleGroup(rule);
2640
+ if (processedGroup) {
2641
+ if (!firstRule && precedingCombinator) {
2642
+ processedRules.push(precedingCombinator);
2643
+ precedingCombinator = "";
2644
+ }
2645
+ firstRule = false;
2646
+ processedRules.push(processedGroup);
2647
+ }
2648
+ continue;
2649
+ }
2650
+ const [validationResult, fieldValidator] = validateRule(rule);
2651
+ if (!isRuleOrGroupValid(rule, validationResult, fieldValidator) || rule.field === placeholderFieldName || rule.operator === placeholderOperatorName || placeholderValueName !== void 0 && rule.value === placeholderValueName) continue;
2652
+ const fieldData = getOption(fields, rule.field);
2653
+ const processedRule = ruleProcessor(rule, {
2654
+ ...options,
2655
+ parseNumbers: getParseNumberBoolean(fieldData?.inputType),
2656
+ escapeQuotes: (rule.valueSource ?? "value") === "value",
2657
+ fieldData
2658
+ });
2659
+ if (processedRule) {
2660
+ if (!firstRule && precedingCombinator) {
2661
+ processedRules.push(precedingCombinator);
2662
+ precedingCombinator = "";
2663
+ }
2664
+ firstRule = false;
2665
+ processedRules.push(processedRule);
2666
+ }
2667
+ }
2668
+ const expression = processedRules.join(isRuleGroupType(rg) ? ` ${celCombinatorMap[rg.combinator]} ` : " ");
2669
+ const [prefix, suffix] = rg.not || !outermost ? [`${rg.not ? "!" : ""}(`, ")"] : ["", ""];
2670
+ return expression ? `${prefix}${expression}${suffix}` : fallbackExpression;
2671
+ };
2672
+ return processRuleGroup(ruleGroup, true);
2673
+ };
2674
+ //#endregion
2493
2675
  //#region src/utils/formatQuery/defaultRuleGroupProcessorSQL.ts
2494
2676
  /**
2495
2677
  * Default rule processor used by {@link formatQuery} for "sql" format.
@@ -2865,6 +3047,59 @@ const getFieldValidatorReasons = (rule, fieldValidator) => {
2865
3047
  }
2866
3048
  };
2867
3049
  //#endregion
3050
+ //#region src/utils/formatQuery/defaultRuleProcessorCypher.ts
3051
+ const escapeSingleQuotes$1 = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll("'", "\\'");
3052
+ /**
3053
+ * Default rule processor used by {@link formatQuery} for "cypher" and "gql" formats.
3054
+ *
3055
+ * @group Export
3056
+ */
3057
+ const defaultRuleProcessorCypher = (rule, opts = {}) => {
3058
+ const { escapeQuotes, parseNumbers } = opts;
3059
+ const { field, operator, value, valueSource } = rule;
3060
+ const valueIsField = valueSource === "field";
3061
+ const operatorTL = operator.toLowerCase();
3062
+ const fmtVal = (v) => {
3063
+ if (v === null || v === void 0) return "null";
3064
+ if (typeof v === "boolean" || typeof v === "bigint") return String(v);
3065
+ if (valueIsField) return trimIfString(v);
3066
+ if (typeof v === "number" || shouldRenderAsNumber(v, parseNumbers)) return trimIfString(v);
3067
+ return `'${escapeSingleQuotes$1(v, escapeQuotes)}'`;
3068
+ };
3069
+ switch (operatorTL) {
3070
+ case "=": return `${field} = ${fmtVal(value)}`;
3071
+ case "!=":
3072
+ case "<>": return `${field} <> ${fmtVal(value)}`;
3073
+ case "<":
3074
+ case ">":
3075
+ case "<=":
3076
+ case ">=": return `${field} ${operatorTL} ${fmtVal(value)}`;
3077
+ case "contains": return `${field} CONTAINS ${fmtVal(value)}`;
3078
+ case "doesnotcontain": return `NOT ${field} CONTAINS ${fmtVal(value)}`;
3079
+ case "beginswith": return `${field} STARTS WITH ${fmtVal(value)}`;
3080
+ case "doesnotbeginwith": return `NOT ${field} STARTS WITH ${fmtVal(value)}`;
3081
+ case "endswith": return `${field} ENDS WITH ${fmtVal(value)}`;
3082
+ case "doesnotendwith": return `NOT ${field} ENDS WITH ${fmtVal(value)}`;
3083
+ case "null": return `${field} IS NULL`;
3084
+ case "notnull": return `${field} IS NOT NULL`;
3085
+ case "in":
3086
+ case "notin": {
3087
+ const values = toArray(value).map(fmtVal);
3088
+ if (!values.length) return "";
3089
+ return `${operatorTL === "notin" ? "NOT " : ""}${field} IN [${values.join(", ")}]`;
3090
+ }
3091
+ case "between":
3092
+ case "notbetween": {
3093
+ const arr = toArray(value);
3094
+ if (arr.length < 2) return "";
3095
+ const [low, high] = [fmtVal(arr[0]), fmtVal(arr[1])];
3096
+ const expr = `${low} <= ${field} AND ${field} <= ${high}`;
3097
+ return operatorTL === "notbetween" ? `NOT (${expr})` : expr;
3098
+ }
3099
+ default: return `${field} ${operator} ${fmtVal(value)}`;
3100
+ }
3101
+ };
3102
+ //#endregion
2868
3103
  //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
2869
3104
  const rangeOperatorMap = {
2870
3105
  "<": "lt",
@@ -3016,6 +3251,68 @@ const defaultRuleProcessorElasticSearch = (rule, options = {}) => {
3016
3251
  return false;
3017
3252
  };
3018
3253
  //#endregion
3254
+ //#region src/utils/formatQuery/defaultRuleProcessorGremlin.ts
3255
+ const escapeSingleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll("'", "\\'");
3256
+ /**
3257
+ * Default rule processor used by {@link formatQuery} for "gremlin" format.
3258
+ *
3259
+ * Each rule becomes a `.has()` step (or `.hasNot()`/`.has()` for null checks).
3260
+ *
3261
+ * @group Export
3262
+ */
3263
+ const defaultRuleProcessorGremlin = (rule, opts = {}) => {
3264
+ const { escapeQuotes, parseNumbers } = opts;
3265
+ const { field, operator, value, valueSource } = rule;
3266
+ const valueIsField = valueSource === "field";
3267
+ const operatorTL = operator.toLowerCase();
3268
+ const prop = field.includes(".") ? field.split(".").pop() : field;
3269
+ const fmtVal = (v) => {
3270
+ if (v === null || v === void 0) return "null";
3271
+ if (typeof v === "boolean" || typeof v === "bigint") return String(v);
3272
+ if (valueIsField) return trimIfString(v);
3273
+ if (typeof v === "number" || shouldRenderAsNumber(v, parseNumbers)) return trimIfString(v);
3274
+ return `'${escapeSingleQuotes(v, escapeQuotes)}'`;
3275
+ };
3276
+ switch (operatorTL) {
3277
+ case "=": return `.has('${prop}', ${fmtVal(value)})`;
3278
+ case "!=":
3279
+ case "<>": return `.has('${prop}', neq(${fmtVal(value)}))`;
3280
+ case "<": return `.has('${prop}', lt(${fmtVal(value)}))`;
3281
+ case ">": return `.has('${prop}', gt(${fmtVal(value)}))`;
3282
+ case "<=": return `.has('${prop}', lte(${fmtVal(value)}))`;
3283
+ case ">=": return `.has('${prop}', gte(${fmtVal(value)}))`;
3284
+ case "contains": return `.has('${prop}', containing(${fmtVal(value)}))`;
3285
+ case "doesnotcontain": return `.has('${prop}', notContaining(${fmtVal(value)}))`;
3286
+ case "beginswith": return `.has('${prop}', startingWith(${fmtVal(value)}))`;
3287
+ case "doesnotbeginwith": return `.has('${prop}', notStartingWith(${fmtVal(value)}))`;
3288
+ case "endswith": return `.has('${prop}', endingWith(${fmtVal(value)}))`;
3289
+ case "doesnotendwith": return `.has('${prop}', notEndingWith(${fmtVal(value)}))`;
3290
+ case "null": return `.hasNot('${prop}')`;
3291
+ case "notnull": return `.has('${prop}')`;
3292
+ case "in": {
3293
+ const items = toArray(value).map(fmtVal);
3294
+ if (!items.length) return "";
3295
+ return `.has('${prop}', within(${items.join(", ")}))`;
3296
+ }
3297
+ case "notin": {
3298
+ const items = toArray(value).map(fmtVal);
3299
+ if (!items.length) return "";
3300
+ return `.has('${prop}', without(${items.join(", ")}))`;
3301
+ }
3302
+ case "between": {
3303
+ const arr = toArray(value);
3304
+ if (arr.length < 2) return "";
3305
+ return `.has('${prop}', between(${fmtVal(arr[0])}, ${fmtVal(arr[1])}))`;
3306
+ }
3307
+ case "notbetween": {
3308
+ const arr = toArray(value);
3309
+ if (arr.length < 2) return "";
3310
+ return `.has('${prop}', outside(${fmtVal(arr[0])}, ${fmtVal(arr[1])}))`;
3311
+ }
3312
+ default: return `.has('${prop}', ${fmtVal(value)})`;
3313
+ }
3314
+ };
3315
+ //#endregion
3019
3316
  //#region src/utils/formatQuery/defaultRuleProcessorJSONata.ts
3020
3317
  const shouldNegate = (op) => op.startsWith("not") || op.startsWith("doesnot");
3021
3318
  const quote = (v, escapeQuotes) => `"${typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`)}"`;
@@ -3638,8 +3935,11 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
3638
3935
  const valueIsField = valueSource === "field";
3639
3936
  const operatorLC = lc(operator);
3640
3937
  if (!Op || valueIsField && (!col || !fn && [
3938
+ "contains",
3641
3939
  "doesnotcontain",
3940
+ "beginswith",
3642
3941
  "doesnotbeginwith",
3942
+ "endswith",
3643
3943
  "doesnotendwith"
3644
3944
  ].includes(operatorLC))) return;
3645
3945
  switch (operatorLC) {
@@ -3659,9 +3959,9 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
3659
3959
  }[operatorLC];
3660
3960
  return { [field]: valueIsField && operatorLC === "=" ? { [Op.col]: value } : { [sequelizeOperator]: valueIsField ? col(value) : shouldRenderAsNumber(value, parseNumbers) ? parseNumber(value, { parseNumbers: "strict" }) : value } };
3661
3961
  }
3662
- case "contains": return { [field]: { [Op.substring]: valueIsField ? col(value) : `${value}` } };
3663
- case "beginswith": return { [field]: { [Op.startsWith]: valueIsField ? col(value) : `${value}` } };
3664
- case "endswith": return { [field]: { [Op.endsWith]: valueIsField ? col(value) : `${value}` } };
3962
+ case "contains": return { [field]: { [valueIsField ? Op.like : Op.substring]: valueIsField ? fn("CONCAT", "%", col(value), "%") : `${value}` } };
3963
+ case "beginswith": return { [field]: { [valueIsField ? Op.like : Op.startsWith]: valueIsField ? fn("CONCAT", col(value), "%") : `${value}` } };
3964
+ case "endswith": return { [field]: { [valueIsField ? Op.like : Op.endsWith]: valueIsField ? fn("CONCAT", "%", col(value)) : `${value}` } };
3665
3965
  case "doesnotcontain": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value), "%") : `%${value}%` } };
3666
3966
  case "doesnotbeginwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", col(value), "%") : `${value}%` } };
3667
3967
  case "doesnotendwith": return { [field]: { [Op.notLike]: valueIsField ? fn("CONCAT", "%", col(value)) : `%${value}` } };
@@ -3691,6 +3991,68 @@ const defaultRuleProcessorSequelize = (rule, { parseNumbers, preserveValueOrder,
3691
3991
  }
3692
3992
  };
3693
3993
  //#endregion
3994
+ //#region src/utils/formatQuery/defaultRuleProcessorSPARQL.ts
3995
+ const escapeDoubleQuotes = (v, escapeQuotes) => typeof v !== "string" || !escapeQuotes ? `${v}` : v.replaceAll(`"`, `\\"`);
3996
+ /**
3997
+ * Default rule processor used by {@link formatQuery} for "sparql" format.
3998
+ *
3999
+ * @group Export
4000
+ */
4001
+ const defaultRuleProcessorSPARQL = (rule, opts = {}) => {
4002
+ const { escapeQuotes, parseNumbers } = opts;
4003
+ const { field, operator, value, valueSource } = rule;
4004
+ const valueIsField = valueSource === "field";
4005
+ const operatorTL = operator.toLowerCase();
4006
+ const fmtVal = (v) => {
4007
+ if (v === null || v === void 0) return "\"\"";
4008
+ if (typeof v === "boolean") return `"${v}"^^xsd:boolean`;
4009
+ if (typeof v === "bigint") return String(v);
4010
+ if (valueIsField) return trimIfString(v);
4011
+ if (typeof v === "number" || shouldRenderAsNumber(v, parseNumbers)) return trimIfString(v);
4012
+ const s = typeof v === "string" ? v : JSON.stringify(v) ?? "";
4013
+ if (s.startsWith("?") || s.startsWith("<") || s.includes(":")) return s;
4014
+ return `"${escapeDoubleQuotes(s, escapeQuotes)}"`;
4015
+ };
4016
+ switch (operatorTL) {
4017
+ case "=":
4018
+ case "!=":
4019
+ case "<":
4020
+ case ">":
4021
+ case "<=":
4022
+ case ">=": return `${field} ${operatorTL} ${fmtVal(value)}`;
4023
+ case "<>": return `${field} != ${fmtVal(value)}`;
4024
+ case "contains": return `CONTAINS(${field}, ${fmtVal(value)})`;
4025
+ case "doesnotcontain": return `!CONTAINS(${field}, ${fmtVal(value)})`;
4026
+ case "beginswith": return `STRSTARTS(${field}, ${fmtVal(value)})`;
4027
+ case "doesnotbeginwith": return `!STRSTARTS(${field}, ${fmtVal(value)})`;
4028
+ case "endswith": return `STRENDS(${field}, ${fmtVal(value)})`;
4029
+ case "doesnotendwith": return `!STRENDS(${field}, ${fmtVal(value)})`;
4030
+ case "null": return `!BOUND(${field})`;
4031
+ case "notnull": return `BOUND(${field})`;
4032
+ case "in": {
4033
+ const items = toArray(value).map(fmtVal);
4034
+ if (!items.length) return "";
4035
+ return items.map((item) => `${field} = ${item}`).join(" || ");
4036
+ }
4037
+ case "notin": {
4038
+ const items = toArray(value).map(fmtVal);
4039
+ if (!items.length) return "";
4040
+ return items.map((item) => `${field} != ${item}`).join(" && ");
4041
+ }
4042
+ case "between": {
4043
+ const arr = toArray(value);
4044
+ if (arr.length < 2) return "";
4045
+ return `${field} >= ${fmtVal(arr[0])} && ${field} <= ${fmtVal(arr[1])}`;
4046
+ }
4047
+ case "notbetween": {
4048
+ const arr = toArray(value);
4049
+ if (arr.length < 2) return "";
4050
+ return `(${field} < ${fmtVal(arr[0])} || ${field} > ${fmtVal(arr[1])})`;
4051
+ }
4052
+ default: return `${field} ${operator} ${fmtVal(value)}`;
4053
+ }
4054
+ };
4055
+ //#endregion
3694
4056
  //#region src/utils/formatQuery/formatQuery.ts
3695
4057
  /**
3696
4058
  * A collection of option presets for {@link formatQuery}, specifically for SQL-based formats.
@@ -3738,6 +4100,10 @@ const defaultRuleProcessors = {
3738
4100
  sequelize: defaultRuleProcessorSequelize,
3739
4101
  spel: defaultRuleProcessorSpEL,
3740
4102
  sql: defaultRuleProcessorSQL,
4103
+ cypher: defaultRuleProcessorCypher,
4104
+ gql: defaultRuleProcessorCypher,
4105
+ sparql: defaultRuleProcessorSPARQL,
4106
+ gremlin: defaultRuleProcessorGremlin,
3741
4107
  diagnostics: defaultRuleProcessorSQL
3742
4108
  };
3743
4109
  /* v8 ignore next -- @preserve */
@@ -3760,6 +4126,10 @@ const defaultOperatorProcessors = {
3760
4126
  sequelize: defaultOperatorProcessor,
3761
4127
  spel: defaultOperatorProcessor,
3762
4128
  sql: defaultOperatorProcessorSQL,
4129
+ cypher: defaultOperatorProcessor,
4130
+ gql: defaultOperatorProcessor,
4131
+ sparql: defaultOperatorProcessor,
4132
+ gremlin: defaultOperatorProcessor,
3763
4133
  diagnostics: defaultOperatorProcessor
3764
4134
  };
3765
4135
  const defaultFallbackExpressions = {
@@ -3767,6 +4137,8 @@ const defaultFallbackExpressions = {
3767
4137
  ldap: "",
3768
4138
  mongodb: "\"$and\":[{\"$expr\":true}]",
3769
4139
  natural_language: "1 is 1",
4140
+ sparql: "1 = 1",
4141
+ gremlin: "",
3770
4142
  spel: "1 == 1",
3771
4143
  sql: "(1 = 1)"
3772
4144
  };
@@ -3907,6 +4279,10 @@ function formatQuery(ruleGroup, optionParam = {}) {
3907
4279
  case "prisma": return defaultRuleGroupProcessorPrisma(ruleGroup, finalOptions);
3908
4280
  case "drizzle": return defaultRuleGroupProcessorDrizzle(ruleGroup, finalOptions);
3909
4281
  case "sequelize": return defaultRuleGroupProcessorSequelize(ruleGroup, finalOptions);
4282
+ case "cypher":
4283
+ case "gql": return defaultRuleGroupProcessorCypher(ruleGroup, finalOptions);
4284
+ case "sparql": return defaultRuleGroupProcessorSPARQL(ruleGroup, finalOptions);
4285
+ case "gremlin": return defaultRuleGroupProcessorGremlin(ruleGroup, finalOptions);
3910
4286
  case "diagnostics": return defaultRuleGroupProcessorDiagnostics(ruleGroup, finalOptions);
3911
4287
  default: return "";
3912
4288
  }
@@ -4630,6 +5006,7 @@ exports.clsx = clsx;
4630
5006
  exports.convertFromIC = convertFromIC;
4631
5007
  exports.convertQuery = convertQuery;
4632
5008
  exports.convertToIC = convertToIC;
5009
+ exports.cypherCombinatorMap = cypherCombinatorMap;
4633
5010
  exports.defaultCELValueProcessor = defaultCELValueProcessor;
4634
5011
  exports.defaultCombinatorLabelMap = defaultCombinatorLabelMap;
4635
5012
  exports.defaultCombinators = defaultCombinators;
@@ -4657,9 +5034,11 @@ exports.defaultPlaceholderValueGroupLabel = defaultPlaceholderValueGroupLabel;
4657
5034
  exports.defaultPlaceholderValueLabel = defaultPlaceholderValueLabel;
4658
5035
  exports.defaultPlaceholderValueName = defaultPlaceholderValueName;
4659
5036
  exports.defaultRuleGroupProcessorCEL = defaultRuleGroupProcessorCEL;
5037
+ exports.defaultRuleGroupProcessorCypher = defaultRuleGroupProcessorCypher;
4660
5038
  exports.defaultRuleGroupProcessorDiagnostics = defaultRuleGroupProcessorDiagnostics;
4661
5039
  exports.defaultRuleGroupProcessorDrizzle = defaultRuleGroupProcessorDrizzle;
4662
5040
  exports.defaultRuleGroupProcessorElasticSearch = defaultRuleGroupProcessorElasticSearch;
5041
+ exports.defaultRuleGroupProcessorGremlin = defaultRuleGroupProcessorGremlin;
4663
5042
  exports.defaultRuleGroupProcessorJSONata = defaultRuleGroupProcessorJSONata;
4664
5043
  exports.defaultRuleGroupProcessorJsonLogic = defaultRuleGroupProcessorJsonLogic;
4665
5044
  exports.defaultRuleGroupProcessorLDAP = defaultRuleGroupProcessorLDAP;
@@ -4668,12 +5047,15 @@ exports.defaultRuleGroupProcessorMongoDBQuery = defaultRuleGroupProcessorMongoDB
4668
5047
  exports.defaultRuleGroupProcessorNL = defaultRuleGroupProcessorNL;
4669
5048
  exports.defaultRuleGroupProcessorParameterized = defaultRuleGroupProcessorParameterized;
4670
5049
  exports.defaultRuleGroupProcessorPrisma = defaultRuleGroupProcessorPrisma;
5050
+ exports.defaultRuleGroupProcessorSPARQL = defaultRuleGroupProcessorSPARQL;
4671
5051
  exports.defaultRuleGroupProcessorSQL = defaultRuleGroupProcessorSQL;
4672
5052
  exports.defaultRuleGroupProcessorSequelize = defaultRuleGroupProcessorSequelize;
4673
5053
  exports.defaultRuleGroupProcessorSpEL = defaultRuleGroupProcessorSpEL;
4674
5054
  exports.defaultRuleProcessorCEL = defaultRuleProcessorCEL;
5055
+ exports.defaultRuleProcessorCypher = defaultRuleProcessorCypher;
4675
5056
  exports.defaultRuleProcessorDrizzle = defaultRuleProcessorDrizzle;
4676
5057
  exports.defaultRuleProcessorElasticSearch = defaultRuleProcessorElasticSearch;
5058
+ exports.defaultRuleProcessorGremlin = defaultRuleProcessorGremlin;
4677
5059
  exports.defaultRuleProcessorJSONata = defaultRuleProcessorJSONata;
4678
5060
  exports.defaultRuleProcessorJsonLogic = defaultRuleProcessorJsonLogic;
4679
5061
  exports.defaultRuleProcessorLDAP = defaultRuleProcessorLDAP;
@@ -4682,6 +5064,7 @@ exports.defaultRuleProcessorMongoDBQuery = defaultRuleProcessorMongoDBQuery;
4682
5064
  exports.defaultRuleProcessorNL = defaultRuleProcessorNL;
4683
5065
  exports.defaultRuleProcessorParameterized = defaultRuleProcessorParameterized;
4684
5066
  exports.defaultRuleProcessorPrisma = defaultRuleProcessorPrisma;
5067
+ exports.defaultRuleProcessorSPARQL = defaultRuleProcessorSPARQL;
4685
5068
  exports.defaultRuleProcessorSQL = defaultRuleProcessorSQL;
4686
5069
  exports.defaultRuleProcessorSequelize = defaultRuleProcessorSequelize;
4687
5070
  exports.defaultRuleProcessorSpEL = defaultRuleProcessorSpEL;