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