@react-querybuilder/core 8.18.0 → 8.19.1

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 (74) hide show
  1. package/dist/cjs/react-querybuilder_core.cjs.development.d.ts +24 -21
  2. package/dist/cjs/react-querybuilder_core.cjs.development.js +222 -238
  3. package/dist/cjs/react-querybuilder_core.cjs.development.js.map +1 -1
  4. package/dist/cjs/react-querybuilder_core.cjs.production.d.ts +24 -21
  5. package/dist/cjs/react-querybuilder_core.cjs.production.js +1 -1
  6. package/dist/cjs/react-querybuilder_core.cjs.production.js.map +1 -1
  7. package/dist/{convertQuery-BoMPXL7_.js → convertQuery-BJKNgecE.js} +2 -2
  8. package/dist/{convertQuery-BoMPXL7_.js.map → convertQuery-BJKNgecE.js.map} +1 -1
  9. package/dist/{convertQuery-CQwOrjQr.mjs → convertQuery-J1CaoDxe.mjs} +2 -2
  10. package/dist/{convertQuery-CQwOrjQr.mjs.map → convertQuery-J1CaoDxe.mjs.map} +1 -1
  11. package/dist/formatQuery.d.mts +2 -2
  12. package/dist/formatQuery.d.ts +2 -2
  13. package/dist/formatQuery.js +195 -197
  14. package/dist/formatQuery.js.map +1 -1
  15. package/dist/formatQuery.mjs +195 -197
  16. package/dist/formatQuery.mjs.map +1 -1
  17. package/dist/{objectUtils-DxVaGCdg.js → objectUtils-DBJI82bl.js} +2 -2
  18. package/dist/objectUtils-DBJI82bl.js.map +1 -0
  19. package/dist/{objectUtils-D-w8MzpZ.mjs → objectUtils-ZvPkF6u6.mjs} +2 -2
  20. package/dist/objectUtils-ZvPkF6u6.mjs.map +1 -0
  21. package/dist/parseCEL.js +3 -3
  22. package/dist/parseCEL.js.map +1 -1
  23. package/dist/parseCEL.mjs +3 -3
  24. package/dist/parseCEL.mjs.map +1 -1
  25. package/dist/parseCypher.js.map +1 -1
  26. package/dist/parseCypher.mjs.map +1 -1
  27. package/dist/parseGremlin.js.map +1 -1
  28. package/dist/parseGremlin.mjs.map +1 -1
  29. package/dist/parseJSONata.js +2 -2
  30. package/dist/parseJSONata.js.map +1 -1
  31. package/dist/parseJSONata.mjs +2 -2
  32. package/dist/parseJSONata.mjs.map +1 -1
  33. package/dist/parseJsonLogic.js +4 -4
  34. package/dist/parseJsonLogic.js.map +1 -1
  35. package/dist/parseJsonLogic.mjs +4 -4
  36. package/dist/parseJsonLogic.mjs.map +1 -1
  37. package/dist/parseMongoDB.js +4 -4
  38. package/dist/parseMongoDB.js.map +1 -1
  39. package/dist/parseMongoDB.mjs +4 -4
  40. package/dist/parseMongoDB.mjs.map +1 -1
  41. package/dist/parseSPARQL.js.map +1 -1
  42. package/dist/parseSPARQL.mjs.map +1 -1
  43. package/dist/parseSQL.js +3 -3
  44. package/dist/parseSQL.js.map +1 -1
  45. package/dist/parseSQL.mjs +3 -3
  46. package/dist/parseSQL.mjs.map +1 -1
  47. package/dist/parseSpEL.js +3 -3
  48. package/dist/parseSpEL.js.map +1 -1
  49. package/dist/parseSpEL.mjs +3 -3
  50. package/dist/parseSpEL.mjs.map +1 -1
  51. package/dist/{prepareQueryObjects-BXf5aV-A.mjs → prepareQueryObjects-Cd_tt4oy.mjs} +3 -3
  52. package/dist/{prepareQueryObjects-BXf5aV-A.mjs.map → prepareQueryObjects-Cd_tt4oy.mjs.map} +1 -1
  53. package/dist/{prepareQueryObjects-gRQqiBPR.js → prepareQueryObjects-DaAXX792.js} +3 -3
  54. package/dist/{prepareQueryObjects-gRQqiBPR.js.map → prepareQueryObjects-DaAXX792.js.map} +1 -1
  55. package/dist/react-querybuilder_core.d.mts +24 -21
  56. package/dist/react-querybuilder_core.legacy-esm.d.ts +24 -21
  57. package/dist/react-querybuilder_core.legacy-esm.js +221 -236
  58. package/dist/react-querybuilder_core.legacy-esm.js.map +1 -1
  59. package/dist/react-querybuilder_core.mjs +222 -238
  60. package/dist/react-querybuilder_core.mjs.map +1 -1
  61. package/dist/react-querybuilder_core.production.d.mts +24 -21
  62. package/dist/react-querybuilder_core.production.mjs +1 -1
  63. package/dist/react-querybuilder_core.production.mjs.map +1 -1
  64. package/dist/transformQuery.js +1 -1
  65. package/dist/transformQuery.mjs +1 -1
  66. package/dist/{utils-ZlKseh1X.js → utils-BpaOtylk.js} +3 -3
  67. package/dist/utils-BpaOtylk.js.map +1 -0
  68. package/dist/{utils-01WaTGBL.mjs → utils-CJRGiPb-.mjs} +3 -3
  69. package/dist/utils-CJRGiPb-.mjs.map +1 -0
  70. package/package.json +10 -9
  71. package/dist/objectUtils-D-w8MzpZ.mjs.map +0 -1
  72. package/dist/objectUtils-DxVaGCdg.js.map +0 -1
  73. package/dist/utils-01WaTGBL.mjs.map +0 -1
  74. package/dist/utils-ZlKseh1X.js.map +0 -1
@@ -429,7 +429,8 @@ const standardClassnames = {
429
429
  branches: "queryBuilder-branches",
430
430
  justified: "queryBuilder-justified",
431
431
  hasSubQuery: "rule-hasSubQuery",
432
- loading: "queryBuilder-loading"
432
+ loading: "queryBuilder-loading",
433
+ valueDateTimeRelative: "rule-value-dateTimeRelative"
433
434
  };
434
435
  /**
435
436
  * Default classnames for each component.
@@ -479,7 +480,8 @@ const defaultControlClassnames = {
479
480
  valueListItem: "",
480
481
  branches: "",
481
482
  hasSubQuery: "",
482
- loading: ""
483
+ loading: "",
484
+ valueDateTimeRelative: ""
483
485
  };
484
486
  /**
485
487
  * Default reason codes for a group being invalid.
@@ -612,51 +614,25 @@ const trimIfString = (val) => typeof val === "string" ? val.trim() : val;
612
614
  * Splits a string by comma then trims each element. Arrays are returned as is except
613
615
  * any string elements are trimmed.
614
616
  */
615
- const toArray = (a, { retainEmptyStrings } = {}) => Array.isArray(a) ? a.map((v) => trimIfString(v)) : typeof a === "string" ? splitBy(a, ",").filter(retainEmptyStrings ? () => true : (s) => !/^\s*$/.test(s)).map((s) => s.trim()) : typeof a === "number" ? [a] : [];
617
+ const toArray = (a, { retainEmptyStrings } = {}) => Array.isArray(a) ? a.map(trimIfString) : typeof a === "string" ? splitBy(a, ",").filter(retainEmptyStrings ? () => true : (s) => !/^\s*$/.test(s)).map((s) => s.trim()) : typeof a === "number" ? [a] : [];
616
618
  /**
617
619
  * Determines if an array is free of `null`/`undefined`.
618
620
  */
619
621
  const nullFreeArray = (arr) => arr.every((el) => el === false || (el ?? false) !== false);
620
622
  //#endregion
621
- //#region src/utils/clsx.ts
622
- /* v8 ignore start -- @preserve */
623
- function toVal(mix) {
624
- let k;
625
- let y;
626
- let str = "";
627
- if (typeof mix === "string" || typeof mix === "number") str += mix;
628
- else if (typeof mix === "object") {
629
- if (Array.isArray(mix)) {
630
- const len = mix.length;
631
- for (k = 0; k < len; k++) if (mix[k] && (y = toVal(mix[k]))) {
632
- str && (str += " ");
633
- str += y;
634
- }
635
- } else for (y in mix) if (mix[y]) {
636
- str && (str += " ");
637
- str += y;
638
- }
639
- }
640
- return str;
623
+ //#region ../../node_modules/clsx/dist/clsx.mjs
624
+ function r(e) {
625
+ var t, f, n = "";
626
+ if ("string" == typeof e || "number" == typeof e) n += e;
627
+ else if ("object" == typeof e) if (Array.isArray(e)) {
628
+ var o = e.length;
629
+ for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
630
+ } else for (f in e) e[f] && (n && (n += " "), n += f);
631
+ return n;
641
632
  }
642
- /* v8 ignore stop -- @preserve */
643
- /**
644
- * Vendored/adapted version of the `clsx` package.
645
- *
646
- * **NOTE:** Prefer the official package from npm outside the context of React Query Builder.
647
- */
648
- // v8 ignore next
649
- function clsx(...args) {
650
- let i = 0;
651
- let tmp;
652
- let x;
653
- let str = "";
654
- const len = args.length;
655
- for (; i < len; i++) if ((tmp = args[i]) && (x = toVal(tmp))) {
656
- str && (str += " ");
657
- str += x;
658
- }
659
- return str;
633
+ function clsx() {
634
+ for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
635
+ return n;
660
636
  }
661
637
  //#endregion
662
638
  //#region src/utils/misc.ts
@@ -673,7 +649,7 @@ const numericRegex = new RegExp(numericRegex$1.source.replace(/^\^/, String.raw`
673
649
  /**
674
650
  * Determines if a variable is a plain old JavaScript object, aka POJO.
675
651
  */
676
- const isPojo = (obj) => obj === null || typeof obj !== "object" ? false : Object.getPrototypeOf(obj) === Object.prototype;
652
+ const isPojo = (obj) => obj !== null && typeof obj === "object" && Object.getPrototypeOf(obj) === Object.prototype;
677
653
  /**
678
654
  * Simple helper to determine whether a value is null, undefined, or an empty string.
679
655
  */
@@ -2002,106 +1978,6 @@ const defaultRuleGroupProcessorCypher = (ruleGroup, options) => {
2002
1978
  return processRuleGroup(ruleGroup, true);
2003
1979
  };
2004
1980
  //#endregion
2005
- //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
2006
- /**
2007
- * Default rule processor used by {@link formatQuery} for the "drizzle" format.
2008
- *
2009
- * @group Export
2010
- */
2011
- const defaultRuleProcessorDrizzle = (rule, _options) => {
2012
- const opts = _options ?? ( /* v8 ignore start -- @preserve */ {});
2013
- // v8 ignore next
2014
- const { parseNumbers, preserveValueOrder, context = {} } = opts;
2015
- const { columns, drizzleOperators, useRawFields } = context;
2016
- if (!columns || !drizzleOperators) return void 0;
2017
- const { between, eq, gt, gte, inArray, isNotNull, isNull, like, lt, lte, ne, notBetween, notInArray, notLike, sql } = drizzleOperators;
2018
- const { field, operator, value, valueSource } = rule;
2019
- const column = useRawFields && /^[a-z_][a-z0-9_.]*$/i.test(field) ? sql.raw(field) : columns[field];
2020
- const operatorLC = lc(operator);
2021
- const valueIsField = valueSource === "field";
2022
- const asFieldOrValue = (v) => valueIsField ? columns[v] : v;
2023
- const maybeParseNumber = (v) => {
2024
- if (valueIsField || !parseNumbers) return asFieldOrValue(v);
2025
- return shouldRenderAsNumber(v, true) ? parseNumber(v, { parseNumbers: true }) : v;
2026
- };
2027
- if (!column) return void 0;
2028
- const matchEval = processMatchMode(rule);
2029
- if (matchEval === false) return;
2030
- else if (matchEval) {
2031
- if (opts.preset !== "postgresql") return void 0;
2032
- const { mode, threshold } = matchEval;
2033
- const arrayElementAlias = "elem_alias";
2034
- const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(transformQuery(rule.value, { ruleProcessor: (r) => ({
2035
- ...r,
2036
- field: arrayElementAlias
2037
- }) }), {
2038
- ...opts,
2039
- context: {
2040
- ...opts.context,
2041
- useRawFields: true
2042
- }
2043
- });
2044
- switch (mode) {
2045
- case "all": return sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) = array_length(${column}, 1)`;
2046
- case "none": return sql`not exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
2047
- case "some": return sql`exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
2048
- case "atleast":
2049
- case "atmost":
2050
- case "exactly": {
2051
- const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
2052
- return threshold > 0 && threshold < 1 ? sql`(select count(*)::float / array_length(${column}, 1) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}` : sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}`;
2053
- }
2054
- }
2055
- }
2056
- switch (operatorLC) {
2057
- case "=": return eq(column, maybeParseNumber(value));
2058
- case "!=": return ne(column, maybeParseNumber(value));
2059
- case ">": return gt(column, maybeParseNumber(value));
2060
- case "<": return lt(column, maybeParseNumber(value));
2061
- case ">=": return gte(column, maybeParseNumber(value));
2062
- case "<=": return lte(column, maybeParseNumber(value));
2063
- case "beginswith":
2064
- case "doesnotbeginwith": return (operatorLC === "doesnotbeginwith" ? notLike : like)(column, valueIsField ? sql`${asFieldOrValue(value)} || '%'` : `${value}%`);
2065
- case "contains":
2066
- case "doesnotcontain": return (operatorLC === "doesnotcontain" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)} || '%'` : `%${value}%`);
2067
- case "endswith":
2068
- case "doesnotendwith": return (operatorLC === "doesnotendwith" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)}` : `%${value}`);
2069
- case "null": return isNull(column);
2070
- case "notnull": return isNotNull(column);
2071
- case "in":
2072
- case "notin": {
2073
- const valueAsArray = toArray(value).map((v) => maybeParseNumber(v));
2074
- return operatorLC === "notin" ? notInArray(column, valueAsArray) : inArray(column, valueAsArray);
2075
- }
2076
- case "between":
2077
- case "notbetween": {
2078
- const valueAsArray = toArray(value);
2079
- if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
2080
- let [first, second] = valueAsArray;
2081
- const shouldParseNumbers = !(parseNumbers === false);
2082
- if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
2083
- const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
2084
- const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
2085
- if (!preserveValueOrder && secondNum < firstNum) {
2086
- const tempNum = secondNum;
2087
- second = firstNum;
2088
- first = tempNum;
2089
- } else {
2090
- first = firstNum;
2091
- second = secondNum;
2092
- }
2093
- } else if (valueIsField) {
2094
- first = asFieldOrValue(first);
2095
- second = asFieldOrValue(second);
2096
- }
2097
- return operatorLC === "notbetween" ? notBetween(column, first, second) : between(column, first, second);
2098
- }
2099
- return;
2100
- }
2101
- default: return;
2102
- }
2103
- };
2104
- //#endregion
2105
1981
  //#region src/utils/formatQuery/defaultRuleGroupProcessorDrizzle.ts
2106
1982
  /**
2107
1983
  * Default rule group processor used by {@link formatQuery} for the "drizzle" format. The returned
@@ -2116,10 +1992,9 @@ const defaultRuleProcessorDrizzle = (rule, _options) => {
2116
1992
  * @group Export
2117
1993
  */
2118
1994
  const defaultRuleGroupProcessorDrizzle = (ruleGroup, options, _meta) => (columns, drizzleOperators) => {
2119
- const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap } = options;
1995
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap, ruleProcessor } = options;
2120
1996
  if (!columns || !drizzleOperators) return void 0;
2121
1997
  const { and, not, or } = drizzleOperators;
2122
- const ruleProcessor = defaultRuleProcessorDrizzle;
2123
1998
  const processRuleGroup = (rg, _outermost) => {
2124
1999
  if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return;
2125
2000
  const processedRules = rg.rules.map((rule) => {
@@ -2735,96 +2610,6 @@ const defaultRuleGroupProcessorSQL = (ruleGroup, options) => {
2735
2610
  return processRuleGroup(ruleGroup, true);
2736
2611
  };
2737
2612
  //#endregion
2738
- //#region src/utils/formatQuery/defaultRuleProcessorTanStackDB.ts
2739
- /**
2740
- * Default rule processor used by {@link formatQuery} for the "tanstack_db" format.
2741
- *
2742
- * @group Export
2743
- */
2744
- const defaultRuleProcessorTanStackDB = (rule, _options) => {
2745
- const { parseNumbers, preserveValueOrder, context = {} } = _options ?? ( /* v8 ignore start -- @preserve */ {});
2746
- const ops = context.tanStackDbOperators;
2747
- const refs = context._tanstackDbRefs;
2748
- const primaryRef = context._tanstackDbPrimaryRef;
2749
- if (!ops || !refs || !primaryRef) return void 0;
2750
- const { and, eq, gt, gte, inArray, isNull, like, lt, lte, not } = ops;
2751
- const resolveField = (fieldName) => {
2752
- const dotIdx = fieldName.indexOf(".");
2753
- if (dotIdx > 0) {
2754
- const prefix = fieldName.slice(0, dotIdx);
2755
- const rest = fieldName.slice(dotIdx + 1);
2756
- if (refs[prefix]) return refs[prefix][rest];
2757
- }
2758
- return refs[primaryRef][fieldName];
2759
- };
2760
- const { field, operator, value, valueSource } = rule;
2761
- const column = resolveField(field);
2762
- const operatorLC = lc(operator);
2763
- const valueIsField = valueSource === "field";
2764
- const asFieldOrValue = (v) => valueIsField ? resolveField(v) : v;
2765
- const maybeParseNumber = (v) => {
2766
- if (valueIsField || !parseNumbers) return asFieldOrValue(v);
2767
- return shouldRenderAsNumber(v, true) ? parseNumber(v, { parseNumbers: true }) : v;
2768
- };
2769
- switch (operatorLC) {
2770
- case "=": return eq(column, maybeParseNumber(value));
2771
- case "!=": return not(eq(column, maybeParseNumber(value)));
2772
- case ">": return gt(column, maybeParseNumber(value));
2773
- case "<": return lt(column, maybeParseNumber(value));
2774
- case ">=": return gte(column, maybeParseNumber(value));
2775
- case "<=": return lte(column, maybeParseNumber(value));
2776
- case "beginswith":
2777
- case "doesnotbeginwith": {
2778
- const expr = like(column, valueIsField ? void 0 : `${value}%`);
2779
- return operatorLC === "doesnotbeginwith" ? not(expr) : expr;
2780
- }
2781
- case "contains":
2782
- case "doesnotcontain": {
2783
- const expr = like(column, valueIsField ? void 0 : `%${value}%`);
2784
- return operatorLC === "doesnotcontain" ? not(expr) : expr;
2785
- }
2786
- case "endswith":
2787
- case "doesnotendwith": {
2788
- const expr = like(column, valueIsField ? void 0 : `%${value}`);
2789
- return operatorLC === "doesnotendwith" ? not(expr) : expr;
2790
- }
2791
- case "null": return isNull(column);
2792
- case "notnull": return not(isNull(column));
2793
- case "in":
2794
- case "notin": {
2795
- const expr = inArray(column, toArray(value).map((v) => maybeParseNumber(v)));
2796
- return operatorLC === "notin" ? not(expr) : expr;
2797
- }
2798
- case "between":
2799
- case "notbetween": {
2800
- const valueAsArray = toArray(value);
2801
- if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
2802
- let [first, second] = valueAsArray;
2803
- const shouldParseNumbers = !(parseNumbers === false);
2804
- if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
2805
- const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
2806
- const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
2807
- if (!preserveValueOrder && secondNum < firstNum) {
2808
- const tempNum = secondNum;
2809
- second = firstNum;
2810
- first = tempNum;
2811
- } else {
2812
- first = firstNum;
2813
- second = secondNum;
2814
- }
2815
- } else if (valueIsField) {
2816
- first = asFieldOrValue(first);
2817
- second = asFieldOrValue(second);
2818
- }
2819
- const expr = and(gte(column, first), lte(column, second));
2820
- return operatorLC === "notbetween" ? not(expr) : expr;
2821
- }
2822
- return;
2823
- }
2824
- default: return;
2825
- }
2826
- };
2827
- //#endregion
2828
2613
  //#region src/utils/formatQuery/defaultRuleGroupProcessorTanStackDB.ts
2829
2614
  /**
2830
2615
  * Default rule group processor used by {@link formatQuery} for the "tanstack_db" format.
@@ -2837,7 +2622,7 @@ const defaultRuleProcessorTanStackDB = (rule, _options) => {
2837
2622
  * @group Export
2838
2623
  */
2839
2624
  const defaultRuleGroupProcessorTanStackDB = (ruleGroup, options) => (refs) => {
2840
- const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap, context = {} } = options;
2625
+ const { fields, getParseNumberBoolean, placeholderFieldName, placeholderOperatorName, placeholderValueName, validateRule, validationMap, context = {}, ruleProcessor } = options;
2841
2626
  const ops = context.tanStackDbOperators;
2842
2627
  if (!ops) return void 0;
2843
2628
  const { and, eq, not, or } = ops;
@@ -2845,7 +2630,6 @@ const defaultRuleGroupProcessorTanStackDB = (ruleGroup, options) => (refs) => {
2845
2630
  const refKeys = Object.keys(refs);
2846
2631
  /* v8 ignore next -- @preserve */
2847
2632
  if (refKeys.length === 0) return fallback;
2848
- const ruleProcessor = defaultRuleProcessorTanStackDB;
2849
2633
  const processRuleGroup = (rg) => {
2850
2634
  if (!isRuleOrGroupValid(rg, validationMap[rg.id ?? ""])) return;
2851
2635
  const processedRules = rg.rules.map((rule) => {
@@ -3243,6 +3027,106 @@ const defaultRuleProcessorCypher = (rule, opts = {}) => {
3243
3027
  }
3244
3028
  };
3245
3029
  //#endregion
3030
+ //#region src/utils/formatQuery/defaultRuleProcessorDrizzle.ts
3031
+ /**
3032
+ * Default rule processor used by {@link formatQuery} for the "drizzle" format.
3033
+ *
3034
+ * @group Export
3035
+ */
3036
+ const defaultRuleProcessorDrizzle = (rule, _options) => {
3037
+ const opts = _options ?? ( /* v8 ignore start -- @preserve */ {});
3038
+ // v8 ignore next
3039
+ const { parseNumbers, preserveValueOrder, context = {} } = opts;
3040
+ const { columns, drizzleOperators, useRawFields } = context;
3041
+ if (!columns || !drizzleOperators) return void 0;
3042
+ const { between, eq, gt, gte, inArray, isNotNull, isNull, like, lt, lte, ne, notBetween, notInArray, notLike, sql } = drizzleOperators;
3043
+ const { field, operator, value, valueSource } = rule;
3044
+ const column = useRawFields && /^[a-z_][a-z0-9_.]*$/i.test(field) ? sql.raw(field) : columns[field];
3045
+ const operatorLC = lc(operator);
3046
+ const valueIsField = valueSource === "field";
3047
+ const asFieldOrValue = (v) => valueIsField ? columns[v] : v;
3048
+ const maybeParseNumber = (v) => {
3049
+ if (valueIsField || !parseNumbers) return asFieldOrValue(v);
3050
+ return shouldRenderAsNumber(v, true) ? parseNumber(v, { parseNumbers: true }) : v;
3051
+ };
3052
+ if (!column) return void 0;
3053
+ const matchEval = processMatchMode(rule);
3054
+ if (matchEval === false) return;
3055
+ else if (matchEval) {
3056
+ if (opts.preset !== "postgresql") return void 0;
3057
+ const { mode, threshold } = matchEval;
3058
+ const arrayElementAlias = "elem_alias";
3059
+ const nestedArrayFilter = defaultRuleGroupProcessorDrizzle(transformQuery(rule.value, { ruleProcessor: (r) => ({
3060
+ ...r,
3061
+ field: arrayElementAlias
3062
+ }) }), {
3063
+ ...opts,
3064
+ context: {
3065
+ ...opts.context,
3066
+ useRawFields: true
3067
+ }
3068
+ });
3069
+ switch (mode) {
3070
+ case "all": return sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) = array_length(${column}, 1)`;
3071
+ case "none": return sql`not exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
3072
+ case "some": return sql`exists (select 1 from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)})`;
3073
+ case "atleast":
3074
+ case "atmost":
3075
+ case "exactly": {
3076
+ const op = mode === "atleast" ? ">=" : mode === "atmost" ? "<=" : "=";
3077
+ return threshold > 0 && threshold < 1 ? sql`(select count(*)::float / array_length(${column}, 1) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}` : sql`(select count(*) from unnest(${column}) as ${sql.raw(arrayElementAlias)} where ${nestedArrayFilter({}, drizzleOperators)}) ${sql.raw(`${op} ${threshold}`)}`;
3078
+ }
3079
+ }
3080
+ }
3081
+ switch (operatorLC) {
3082
+ case "=": return eq(column, maybeParseNumber(value));
3083
+ case "!=": return ne(column, maybeParseNumber(value));
3084
+ case ">": return gt(column, maybeParseNumber(value));
3085
+ case "<": return lt(column, maybeParseNumber(value));
3086
+ case ">=": return gte(column, maybeParseNumber(value));
3087
+ case "<=": return lte(column, maybeParseNumber(value));
3088
+ case "beginswith":
3089
+ case "doesnotbeginwith": return (operatorLC === "doesnotbeginwith" ? notLike : like)(column, valueIsField ? sql`${asFieldOrValue(value)} || '%'` : `${value}%`);
3090
+ case "contains":
3091
+ case "doesnotcontain": return (operatorLC === "doesnotcontain" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)} || '%'` : `%${value}%`);
3092
+ case "endswith":
3093
+ case "doesnotendwith": return (operatorLC === "doesnotendwith" ? notLike : like)(column, valueIsField ? sql`'%' || ${asFieldOrValue(value)}` : `%${value}`);
3094
+ case "null": return isNull(column);
3095
+ case "notnull": return isNotNull(column);
3096
+ case "in":
3097
+ case "notin": {
3098
+ const valueAsArray = toArray(value).map((v) => maybeParseNumber(v));
3099
+ return operatorLC === "notin" ? notInArray(column, valueAsArray) : inArray(column, valueAsArray);
3100
+ }
3101
+ case "between":
3102
+ case "notbetween": {
3103
+ const valueAsArray = toArray(value);
3104
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
3105
+ let [first, second] = valueAsArray;
3106
+ const shouldParseNumbers = !(parseNumbers === false);
3107
+ if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
3108
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
3109
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
3110
+ if (!preserveValueOrder && secondNum < firstNum) {
3111
+ const tempNum = secondNum;
3112
+ second = firstNum;
3113
+ first = tempNum;
3114
+ } else {
3115
+ first = firstNum;
3116
+ second = secondNum;
3117
+ }
3118
+ } else if (valueIsField) {
3119
+ first = asFieldOrValue(first);
3120
+ second = asFieldOrValue(second);
3121
+ }
3122
+ return operatorLC === "notbetween" ? notBetween(column, first, second) : between(column, first, second);
3123
+ }
3124
+ return;
3125
+ }
3126
+ default: return;
3127
+ }
3128
+ };
3129
+ //#endregion
3246
3130
  //#region src/utils/formatQuery/defaultRuleProcessorElasticSearch.ts
3247
3131
  const rangeOperatorMap = {
3248
3132
  "<": "lt",
@@ -4212,6 +4096,96 @@ const defaultRuleProcessorSPARQL = (rule, opts = {}) => {
4212
4096
  }
4213
4097
  };
4214
4098
  //#endregion
4099
+ //#region src/utils/formatQuery/defaultRuleProcessorTanStackDB.ts
4100
+ /**
4101
+ * Default rule processor used by {@link formatQuery} for the "tanstack_db" format.
4102
+ *
4103
+ * @group Export
4104
+ */
4105
+ const defaultRuleProcessorTanStackDB = (rule, _options) => {
4106
+ const { parseNumbers, preserveValueOrder, context = {} } = _options ?? ( /* v8 ignore start -- @preserve */ {});
4107
+ const ops = context.tanStackDbOperators;
4108
+ const refs = context._tanstackDbRefs;
4109
+ const primaryRef = context._tanstackDbPrimaryRef;
4110
+ if (!ops || !refs || !primaryRef) return void 0;
4111
+ const { and, eq, gt, gte, inArray, isNull, like, lt, lte, not } = ops;
4112
+ const resolveField = (fieldName) => {
4113
+ const dotIdx = fieldName.indexOf(".");
4114
+ if (dotIdx > 0) {
4115
+ const prefix = fieldName.slice(0, dotIdx);
4116
+ const rest = fieldName.slice(dotIdx + 1);
4117
+ if (refs[prefix]) return refs[prefix][rest];
4118
+ }
4119
+ return refs[primaryRef][fieldName];
4120
+ };
4121
+ const { field, operator, value, valueSource } = rule;
4122
+ const column = resolveField(field);
4123
+ const operatorLC = lc(operator);
4124
+ const valueIsField = valueSource === "field";
4125
+ const asFieldOrValue = (v) => valueIsField ? resolveField(v) : v;
4126
+ const maybeParseNumber = (v) => {
4127
+ if (valueIsField || !parseNumbers) return asFieldOrValue(v);
4128
+ return shouldRenderAsNumber(v, true) ? parseNumber(v, { parseNumbers: true }) : v;
4129
+ };
4130
+ switch (operatorLC) {
4131
+ case "=": return eq(column, maybeParseNumber(value));
4132
+ case "!=": return not(eq(column, maybeParseNumber(value)));
4133
+ case ">": return gt(column, maybeParseNumber(value));
4134
+ case "<": return lt(column, maybeParseNumber(value));
4135
+ case ">=": return gte(column, maybeParseNumber(value));
4136
+ case "<=": return lte(column, maybeParseNumber(value));
4137
+ case "beginswith":
4138
+ case "doesnotbeginwith": {
4139
+ const expr = like(column, valueIsField ? void 0 : `${value}%`);
4140
+ return operatorLC === "doesnotbeginwith" ? not(expr) : expr;
4141
+ }
4142
+ case "contains":
4143
+ case "doesnotcontain": {
4144
+ const expr = like(column, valueIsField ? void 0 : `%${value}%`);
4145
+ return operatorLC === "doesnotcontain" ? not(expr) : expr;
4146
+ }
4147
+ case "endswith":
4148
+ case "doesnotendwith": {
4149
+ const expr = like(column, valueIsField ? void 0 : `%${value}`);
4150
+ return operatorLC === "doesnotendwith" ? not(expr) : expr;
4151
+ }
4152
+ case "null": return isNull(column);
4153
+ case "notnull": return not(isNull(column));
4154
+ case "in":
4155
+ case "notin": {
4156
+ const expr = inArray(column, toArray(value).map((v) => maybeParseNumber(v)));
4157
+ return operatorLC === "notin" ? not(expr) : expr;
4158
+ }
4159
+ case "between":
4160
+ case "notbetween": {
4161
+ const valueAsArray = toArray(value);
4162
+ if (valueAsArray.length >= 2 && isValidValue(valueAsArray[0]) && isValidValue(valueAsArray[1])) {
4163
+ let [first, second] = valueAsArray;
4164
+ const shouldParseNumbers = !(parseNumbers === false);
4165
+ if (!valueIsField && shouldRenderAsNumber(first, shouldParseNumbers) && shouldRenderAsNumber(second, shouldParseNumbers)) {
4166
+ const firstNum = parseNumber(first, { parseNumbers: shouldParseNumbers });
4167
+ const secondNum = parseNumber(second, { parseNumbers: shouldParseNumbers });
4168
+ if (!preserveValueOrder && secondNum < firstNum) {
4169
+ const tempNum = secondNum;
4170
+ second = firstNum;
4171
+ first = tempNum;
4172
+ } else {
4173
+ first = firstNum;
4174
+ second = secondNum;
4175
+ }
4176
+ } else if (valueIsField) {
4177
+ first = asFieldOrValue(first);
4178
+ second = asFieldOrValue(second);
4179
+ }
4180
+ const expr = and(gte(column, first), lte(column, second));
4181
+ return operatorLC === "notbetween" ? not(expr) : expr;
4182
+ }
4183
+ return;
4184
+ }
4185
+ default: return;
4186
+ }
4187
+ };
4188
+ //#endregion
4215
4189
  //#region src/utils/formatQuery/formatQuery.ts
4216
4190
  /**
4217
4191
  * A collection of option presets for {@link formatQuery}, specifically for SQL-based formats.
@@ -4730,7 +4704,16 @@ const mergeAnyTranslation = (el, keyPropContextMap, defaults) => {
4730
4704
  };
4731
4705
  //#endregion
4732
4706
  //#region src/utils/mergeClassnames.ts
4733
- const joinClassnamesByName = (name, args) => clsx(args.map((c) => clsx(c?.[name])));
4707
+ const joinClassnamesByName = (name, args) => {
4708
+ let result = "";
4709
+ for (let i = 0; i < args.length; i++) {
4710
+ const v = args[i]?.[name];
4711
+ if (!v) continue;
4712
+ const s = typeof v === "string" ? v : clsx(v);
4713
+ if (s) result = result ? `${result} ${s}` : s;
4714
+ }
4715
+ return result;
4716
+ };
4734
4717
  /**
4735
4718
  * Merges a list of partial {@link Classnames} definitions into a single definition.
4736
4719
  */
@@ -4777,7 +4760,8 @@ const mergeClassnames = (...args) => ({
4777
4760
  matchThreshold: joinClassnamesByName("matchThreshold", args),
4778
4761
  branches: joinClassnamesByName("branches", args),
4779
4762
  hasSubQuery: joinClassnamesByName("hasSubQuery", args),
4780
- loading: joinClassnamesByName("loading", args)
4763
+ loading: joinClassnamesByName("loading", args),
4764
+ valueDateTimeRelative: joinClassnamesByName("valueDateTimeRelative", args)
4781
4765
  });
4782
4766
  //#endregion
4783
4767
  //#region src/utils/preferProp.ts