drizzle-cube 0.4.35 → 0.4.37

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/adapters/express/index.cjs +1 -1
  2. package/dist/adapters/express/index.js +3 -3
  3. package/dist/adapters/fastify/index.cjs +1 -1
  4. package/dist/adapters/fastify/index.js +3 -3
  5. package/dist/adapters/{handler-DzUX7CBs.cjs → handler-dHHEEbG9.cjs} +1 -1
  6. package/dist/adapters/{handler-J55KQKe5.js → handler-fto6TSVn.js} +1 -1
  7. package/dist/adapters/hono/index.cjs +1 -1
  8. package/dist/adapters/hono/index.js +3 -3
  9. package/dist/adapters/{mcp-transport-Dmf2vbIb.cjs → mcp-transport-ro4OL4BW.cjs} +4 -4
  10. package/dist/adapters/{mcp-transport-Cdisv8il.js → mcp-transport-tB5a7Het.js} +71 -18
  11. package/dist/adapters/nextjs/index.cjs +1 -1
  12. package/dist/adapters/nextjs/index.js +3 -3
  13. package/dist/adapters/{utils-CDExg9uP.cjs → utils-2MwxiQ2o.cjs} +1 -1
  14. package/dist/adapters/{utils-DkKcpkx5.js → utils-_2o905Fi.js} +2 -1
  15. package/dist/adapters/utils.cjs +1 -1
  16. package/dist/adapters/utils.d.ts +2 -0
  17. package/dist/adapters/utils.js +1 -1
  18. package/dist/client/charts.js +3 -3
  19. package/dist/client/chunks/{DashboardEditModal-DsxYiMct.js → DashboardEditModal-B083DSGL.js} +7 -7
  20. package/dist/client/chunks/DashboardEditModal-B083DSGL.js.map +1 -0
  21. package/dist/client/chunks/{FieldSearchModal-CSzgVPdG.js → FieldSearchModal-BxQ5JhWz.js} +2 -2
  22. package/dist/client/chunks/{FieldSearchModal-CSzgVPdG.js.map → FieldSearchModal-BxQ5JhWz.js.map} +1 -1
  23. package/dist/client/chunks/{analysis-builder-CxXZDfFR.js → analysis-builder-BFb3zjl5.js} +1783 -2561
  24. package/dist/client/chunks/analysis-builder-BFb3zjl5.js.map +1 -0
  25. package/dist/client/chunks/{analysis-builder-shared-fwyLiZ48.js → analysis-builder-shared-BFzd2jx_.js} +1498 -716
  26. package/dist/client/chunks/analysis-builder-shared-BFzd2jx_.js.map +1 -0
  27. package/dist/client/chunks/{chart-data-table-CGG-_R93.js → chart-data-table-CW_qZDpt.js} +12 -2
  28. package/dist/client/chunks/chart-data-table-CW_qZDpt.js.map +1 -0
  29. package/dist/client/chunks/{chart-kpi-delta-D9eNhKR6.js → chart-kpi-delta-BPexzOe7.js} +2 -2
  30. package/dist/client/chunks/{chart-kpi-delta-D9eNhKR6.js.map → chart-kpi-delta-BPexzOe7.js.map} +1 -1
  31. package/dist/client/chunks/{chart-kpi-number-IJWReEix.js → chart-kpi-number-BBtGBtZL.js} +3 -3
  32. package/dist/client/chunks/{chart-kpi-number-IJWReEix.js.map → chart-kpi-number-BBtGBtZL.js.map} +1 -1
  33. package/dist/client/chunks/{chart-kpi-text-Dsr7nPmz.js → chart-kpi-text-BqHhmJEB.js} +2 -2
  34. package/dist/client/chunks/{chart-kpi-text-Dsr7nPmz.js.map → chart-kpi-text-BqHhmJEB.js.map} +1 -1
  35. package/dist/client/chunks/{charts-loader-DSdXpr7e.js → charts-loader-gZjOqZwG.js} +5 -5
  36. package/dist/client/chunks/{charts-loader-DSdXpr7e.js.map → charts-loader-gZjOqZwG.js.map} +1 -1
  37. package/dist/client/chunks/{schema-visualization-CBQrcxb8.js → schema-visualization-XLFzV_7p.js} +2 -2
  38. package/dist/client/chunks/{schema-visualization-CBQrcxb8.js.map → schema-visualization-XLFzV_7p.js.map} +1 -1
  39. package/dist/client/chunks/{useDebounce-BbYqb134.js → useDebounce-C_wstEud.js} +2 -2
  40. package/dist/client/chunks/{useDebounce-BbYqb134.js.map → useDebounce-C_wstEud.js.map} +1 -1
  41. package/dist/client/chunks/{useExplainAI-CbAR-1p5.js → useExplainAI-C9ytXRIC.js} +21 -18
  42. package/dist/client/chunks/{useExplainAI-CbAR-1p5.js.map → useExplainAI-C9ytXRIC.js.map} +1 -1
  43. package/dist/client/chunks/{utils-BxLeWUeg.js → utils-3FNmeZJR.js} +2 -2
  44. package/dist/client/chunks/{utils-BxLeWUeg.js.map → utils-3FNmeZJR.js.map} +1 -1
  45. package/dist/client/chunks/{vendor-QBbbDL5y.js → vendor-BPRWulB7.js} +2 -2
  46. package/dist/client/chunks/{vendor-QBbbDL5y.js.map → vendor-BPRWulB7.js.map} +1 -1
  47. package/dist/client/components/AIAssistant/utils.d.ts +1 -1
  48. package/dist/client/components/DataBrowser/DataBrowserSidebar.d.ts +16 -0
  49. package/dist/client/components/DataBrowser/DataBrowserTable.d.ts +16 -0
  50. package/dist/client/components/DataBrowser/DataBrowserToolbar.d.ts +22 -0
  51. package/dist/client/components/DataBrowser/index.d.ts +28 -0
  52. package/dist/client/components.js +3 -3
  53. package/dist/client/hooks/useDataBrowser.d.ts +67 -0
  54. package/dist/client/hooks.js +3 -3
  55. package/dist/client/icons/types.d.ts +1 -0
  56. package/dist/client/icons.js +1 -1
  57. package/dist/client/index.d.ts +3 -0
  58. package/dist/client/index.js +774 -192
  59. package/dist/client/index.js.map +1 -1
  60. package/dist/client/providers/CubeApiProvider.d.ts +1 -0
  61. package/dist/client/providers.js +1 -1
  62. package/dist/client/stores/dataBrowserStore.d.ts +34 -0
  63. package/dist/client/styles.css +1 -1
  64. package/dist/client/types.d.ts +2 -0
  65. package/dist/client/utils.js +3 -3
  66. package/dist/client-bundle-stats.html +1 -1
  67. package/dist/server/index.cjs +3 -3
  68. package/dist/server/index.d.ts +18 -0
  69. package/dist/server/index.js +69 -16
  70. package/package.json +1 -1
  71. package/dist/client/chunks/DashboardEditModal-DsxYiMct.js.map +0 -1
  72. package/dist/client/chunks/analysis-builder-CxXZDfFR.js.map +0 -1
  73. package/dist/client/chunks/analysis-builder-shared-fwyLiZ48.js.map +0 -1
  74. package/dist/client/chunks/chart-data-table-CGG-_R93.js.map +0 -1
@@ -3844,6 +3844,11 @@ export declare interface QueryContext {
3844
3844
  * Created at query start and used throughout query building
3845
3845
  */
3846
3846
  filterCache?: FilterCacheManager;
3847
+ /**
3848
+ * When true, measures should be rendered as raw column expressions
3849
+ * without aggregation wrappers. Set from SemanticQuery.ungrouped.
3850
+ */
3851
+ ungrouped?: boolean;
3847
3852
  }
3848
3853
 
3849
3854
  export declare class QueryExecutor {
@@ -4687,6 +4692,19 @@ export declare interface SemanticQuery {
4687
4692
  * Default: 0
4688
4693
  */
4689
4694
  fillMissingDatesValue?: number | null;
4695
+ /**
4696
+ * When true, returns raw row-level data without GROUP BY or aggregation.
4697
+ * Measures are rendered as raw column expressions (no aggregation wrappers).
4698
+ * Security context and joins still apply normally.
4699
+ *
4700
+ * Constraints:
4701
+ * - Requires at least one dimension
4702
+ * - Only compatible with sum, avg, min, max, and number measure types
4703
+ * - Incompatible with count, countDistinct, calculated, and window function measures
4704
+ * - Incompatible with measure filters, hasMany joins, funnel/flow/retention modes
4705
+ * - Incompatible with compareDateRange and fillMissingDates
4706
+ */
4707
+ ungrouped?: boolean;
4690
4708
  /**
4691
4709
  * Funnel analysis configuration for query-time funnel definition.
4692
4710
  * When specified, the query executes as a funnel analysis instead of
@@ -2711,6 +2711,7 @@ var F = class e {
2711
2711
  if (e.isPostAggregationWindow(t)) throw Error(`Post-aggregation window measure '${t.name}' should be built via buildPostAggregationWindowExpression, not buildMeasureExpression.`);
2712
2712
  if (!t.sql) throw Error(`Measure '${t.name}' of type '${t.type}' is missing required 'sql' property. Only calculated measures and post-aggregation window functions can omit 'sql'.`);
2713
2713
  let a = M(t.sql, r);
2714
+ if (r.ungrouped) return a;
2714
2715
  if (t.filters && t.filters.length > 0) {
2715
2716
  let e = t.filters.map((e) => {
2716
2717
  let t = e(r);
@@ -2920,6 +2921,7 @@ var F = class e {
2920
2921
  ].includes(e);
2921
2922
  }
2922
2923
  buildGroupByFields(e, t, n, r) {
2924
+ if (t.ungrouped) return [];
2923
2925
  let i = [], a = e instanceof Map ? e : new Map([[e.name, e]]), o = t.dimensions && t.dimensions.length > 0 || t.timeDimensions && t.timeDimensions.length > 0, s = t.measures && t.measures.length > 0, c = o && !s, l = !1;
2924
2926
  for (let e of t.measures || []) {
2925
2927
  let [t, n] = e.split("."), r = a.get(t);
@@ -6187,14 +6189,15 @@ function qt(e, t, r, i, a, o, s, c) {
6187
6189
  d = d.where(e);
6188
6190
  }
6189
6191
  let f = c.queryBuilder.buildGroupByFields(e.joinCubes.length > 0 ? i : e.primaryCube, t, r, e);
6190
- f.length > 0 && (d = d.groupBy(...f));
6191
- let p = c.queryBuilder.buildHavingConditions(e.joinCubes.length > 0 ? i : e.primaryCube, t, r, e);
6192
- if (p.length > 0) {
6193
- let e = p.length === 1 ? p[0] : n(...p);
6194
- d = d.having(e);
6192
+ if (f.length > 0 && (d = d.groupBy(...f)), !t.ungrouped) {
6193
+ let a = c.queryBuilder.buildHavingConditions(e.joinCubes.length > 0 ? i : e.primaryCube, t, r, e);
6194
+ if (a.length > 0) {
6195
+ let e = a.length === 1 ? a[0] : n(...a);
6196
+ d = d.having(e);
6197
+ }
6195
6198
  }
6196
- let m = c.queryBuilder.buildOrderBy(t);
6197
- return m.length > 0 && (d = d.orderBy(...m)), d = c.queryBuilder.applyLimitAndOffset(d, t), d;
6199
+ let p = c.queryBuilder.buildOrderBy(t);
6200
+ return p.length > 0 && (d = d.orderBy(...p)), d = c.queryBuilder.applyLimitAndOffset(d, t), d;
6198
6201
  }
6199
6202
  //#endregion
6200
6203
  //#region src/server/physical-plan/processors/shared.ts
@@ -6565,7 +6568,7 @@ var Yt = class {
6565
6568
  //#endregion
6566
6569
  //#region src/server/executor.ts
6567
6570
  function Xt(e, t) {
6568
- if (process.env.DC_DEBUG) try {
6571
+ if (!(typeof process > "u" || !process.env?.DC_DEBUG)) try {
6569
6572
  let { sql: n, params: r } = t.toSQL();
6570
6573
  console.log(`\n[DC_DEBUG] ${e}`), console.log(n), r.length > 0 && console.log("params:", r), console.log();
6571
6574
  } catch {}
@@ -6649,11 +6652,11 @@ var Zt = class {
6649
6652
  }
6650
6653
  }
6651
6654
  buildLogicalPlan(e, t, n) {
6652
- let r = new $e(), i = this.createQueryContext(n, r);
6655
+ let r = new $e(), i = this.createQueryContext(n, r, t);
6653
6656
  return this.preloadFilterCache(t, r, e, i), this.buildRegularQueryArtifacts(e, t, i).optimisedPlan;
6654
6657
  }
6655
6658
  analyzeQuery(e, t, n) {
6656
- let r = new $e(), i = this.createQueryContext(n, r);
6659
+ let r = new $e(), i = this.createQueryContext(n, r, t);
6657
6660
  return this.preloadFilterCache(t, r, e, i), this.buildRegularQueryArtifacts(e, t, i).analysis;
6658
6661
  }
6659
6662
  async executeQuery(e, t, n) {
@@ -6784,7 +6787,7 @@ var Zt = class {
6784
6787
  };
6785
6788
  }
6786
6789
  async executeStandardQuery(e, t, n) {
6787
- let r = new $e(), i = this.createQueryContext(n, r);
6790
+ let r = new $e(), i = this.createQueryContext(n, r, t);
6788
6791
  this.preloadFilterCache(t, r, e, i);
6789
6792
  let { optimisedPlan: a } = this.buildRegularQueryArtifacts(e, t, i), o = this.drizzlePlanBuilder.derivePhysicalPlanContext(a), s = this.drizzlePlanBuilder.build(o, t, i);
6790
6793
  Xt("query", s);
@@ -6807,12 +6810,13 @@ var Zt = class {
6807
6810
  annotation: this.generateAnnotations(o, t)
6808
6811
  };
6809
6812
  }
6810
- createQueryContext(e, t) {
6813
+ createQueryContext(e, t, n) {
6811
6814
  return {
6812
6815
  db: this.dbExecutor.db,
6813
6816
  schema: this.dbExecutor.schema,
6814
6817
  securityContext: e,
6815
- filterCache: t
6818
+ filterCache: t,
6819
+ ungrouped: n?.ungrouped
6816
6820
  };
6817
6821
  }
6818
6822
  getOptimiserEngineType() {
@@ -6900,7 +6904,7 @@ var Zt = class {
6900
6904
  return this.validateQueryForMode(r, e, t), this.generateSqlForMode(r, e, t, n);
6901
6905
  }
6902
6906
  async generateUnifiedSQL(e, t, n) {
6903
- let r = new $e(), i = this.createQueryContext(n, r);
6907
+ let r = new $e(), i = this.createQueryContext(n, r, t);
6904
6908
  this.preloadFilterCache(t, r, e, i);
6905
6909
  let { optimisedPlan: a } = this.buildRegularQueryArtifacts(e, t, i), o = this.drizzlePlanBuilder.derivePhysicalPlanContext(a), s = this.drizzlePlanBuilder.build(o, t, i).toSQL();
6906
6910
  return {
@@ -6946,7 +6950,7 @@ var Zt = class {
6946
6950
  }[qe(e)]();
6947
6951
  }
6948
6952
  async executeRegularQueryWithCache(e, t, n, r) {
6949
- let i = new $e(), a = this.createQueryContext(n, i);
6953
+ let i = new $e(), a = this.createQueryContext(n, i, t);
6950
6954
  this.preloadFilterCache(t, i, e, a);
6951
6955
  let { optimisedPlan: o } = this.buildRegularQueryArtifacts(e, t, a), s = this.drizzlePlanBuilder.derivePhysicalPlanContext(o);
6952
6956
  this.validateSecurityContext(s, a);
@@ -11522,7 +11526,56 @@ function vc(e, t) {
11522
11526
  o.dimensions[i] || n.push(`TimeDimension '${i}' not found on cube '${t}' (must be a dimension with time type)`);
11523
11527
  }
11524
11528
  if (t.filters) for (let r of t.filters) yc(r, e, n, a);
11525
- return a.size === 0 && n.push("Query must reference at least one cube through measures, dimensions, or filters"), {
11529
+ if (a.size === 0 && n.push("Query must reference at least one cube through measures, dimensions, or filters"), t.ungrouped) {
11530
+ t.dimensions && t.dimensions.length > 0 || t.timeDimensions && t.timeDimensions.length > 0 || n.push("Ungrouped queries require at least one dimension or time dimension"), t.funnel && n.push("Ungrouped queries are incompatible with funnel analysis"), t.flow && n.push("Ungrouped queries are incompatible with flow analysis"), t.retention && n.push("Ungrouped queries are incompatible with retention analysis"), t.timeDimensions?.some((e) => e.compareDateRange && e.compareDateRange.length > 0) && n.push("Ungrouped queries are incompatible with compareDateRange"), t.timeDimensions?.some((e) => e.fillMissingDates === !0) && n.push("Ungrouped queries are incompatible with fillMissingDates");
11531
+ let r = new Set([
11532
+ "sum",
11533
+ "avg",
11534
+ "min",
11535
+ "max",
11536
+ "number"
11537
+ ]), i = new Set([
11538
+ "count",
11539
+ "countDistinct",
11540
+ "countDistinctApprox",
11541
+ "calculated",
11542
+ "stddev",
11543
+ "stddevSamp",
11544
+ "variance",
11545
+ "varianceSamp",
11546
+ "median",
11547
+ "p95",
11548
+ "p99",
11549
+ "percentile",
11550
+ "lag",
11551
+ "lead",
11552
+ "rank",
11553
+ "denseRank",
11554
+ "rowNumber",
11555
+ "ntile",
11556
+ "firstValue",
11557
+ "lastValue",
11558
+ "movingAvg",
11559
+ "movingSum"
11560
+ ]);
11561
+ if (t.measures) for (let a of t.measures) {
11562
+ let [t, o] = a.split("."), s = e.get(t);
11563
+ if (s && s.measures[o]) {
11564
+ let e = s.measures[o];
11565
+ i.has(e.type) && n.push(`Measure '${a}' has type '${e.type}' which is incompatible with ungrouped queries. Only ${[...r].join(", ")} types are allowed.`), e.filters && e.filters.length > 0 && n.push(`Measure '${a}' has filters which are incompatible with ungrouped queries (measure filters require aggregation)`);
11566
+ }
11567
+ }
11568
+ for (let t of a) {
11569
+ let r = e.get(t);
11570
+ if (r && r.joins) {
11571
+ for (let [i, o] of Object.entries(r.joins)) if (o.relationship === "hasMany") {
11572
+ let r = j(o.targetCube, e);
11573
+ r && a.has(r.name) && n.push(`Ungrouped queries are incompatible with hasMany relationships (${t} → ${i} is hasMany)`);
11574
+ }
11575
+ }
11576
+ }
11577
+ }
11578
+ return {
11526
11579
  isValid: n.length === 0,
11527
11580
  errors: n
11528
11581
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-cube",
3
- "version": "0.4.35",
3
+ "version": "0.4.37",
4
4
  "description": "Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.",
5
5
  "main": "./dist/server/index.js",
6
6
  "types": "./dist/server/index.d.ts",