drizzle-cube 0.1.3 → 0.1.5

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 (46) hide show
  1. package/README.md +24 -2
  2. package/dist/adapters/hono/index.d.ts +5 -1
  3. package/dist/adapters/hono/index.js +259 -96
  4. package/dist/client/client/CubeClient.d.ts +15 -0
  5. package/dist/client/components/AnalyticsDashboard.d.ts +2 -0
  6. package/dist/client/components/AnalyticsPage.d.ts +1 -0
  7. package/dist/client/components/AnalyticsPortlet.d.ts +6 -0
  8. package/dist/client/components/ChartConfigEditor.d.ts +8 -0
  9. package/dist/client/components/ChartErrorBoundary.d.ts +21 -0
  10. package/dist/client/components/DashboardEditModal.d.ts +14 -0
  11. package/dist/client/components/DashboardGrid.d.ts +11 -0
  12. package/dist/client/components/Modal.d.ts +16 -0
  13. package/dist/client/components/PortletContainer.d.ts +10 -0
  14. package/dist/client/components/PortletEditModal.d.ts +12 -0
  15. package/dist/client/components/QueryBuilder/CubeMetaExplorer.d.ts +4 -0
  16. package/dist/client/components/QueryBuilder/QueryPanel.d.ts +4 -0
  17. package/dist/client/components/QueryBuilder/ResultsPanel.d.ts +4 -0
  18. package/dist/client/components/QueryBuilder/SetupPanel.d.ts +11 -0
  19. package/dist/client/components/QueryBuilder/index.d.ts +3 -0
  20. package/dist/client/components/QueryBuilder/types.d.ts +132 -0
  21. package/dist/client/components/QueryBuilder/utils.d.ts +42 -0
  22. package/dist/client/components/charts/AreaChart.d.ts +2 -0
  23. package/dist/client/components/charts/BarChart.d.ts +2 -0
  24. package/dist/client/components/charts/ChartContainer.d.ts +7 -0
  25. package/dist/client/components/charts/ChartLegend.d.ts +7 -0
  26. package/dist/client/components/charts/ChartTooltip.d.ts +7 -0
  27. package/dist/client/components/charts/DataTable.d.ts +2 -0
  28. package/dist/client/components/charts/LineChart.d.ts +2 -0
  29. package/dist/client/components/charts/PieChart.d.ts +2 -0
  30. package/dist/client/components/charts/RadarChart.d.ts +2 -0
  31. package/dist/client/components/charts/RadialBarChart.d.ts +2 -0
  32. package/dist/client/components/charts/ScatterChart.d.ts +2 -0
  33. package/dist/client/components/charts/TreeMapChart.d.ts +2 -0
  34. package/dist/client/components/charts/index.d.ts +13 -0
  35. package/dist/client/hooks/useCubeQuery.d.ts +8 -0
  36. package/dist/client/index.d.ts +15 -0
  37. package/dist/client/index.js +25439 -4
  38. package/dist/client/providers/CubeProvider.d.ts +15 -0
  39. package/dist/client/styles.css +1 -0
  40. package/dist/client/types.d.ts +111 -0
  41. package/dist/client/utils/chartConstants.d.ts +15 -0
  42. package/dist/client/utils/chartUtils.d.ts +9 -0
  43. package/dist/client/utils/index.d.ts +87 -0
  44. package/dist/server/index.d.ts +84 -1155
  45. package/dist/server/index.js +1046 -2826
  46. package/package.json +14 -3
package/README.md CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  Transform your Drizzle schema into a powerful, type-safe analytics platform with SQL injection protection and full TypeScript support.
6
6
 
7
+ 📖 **[Documentation](https://www.drizzle-cube.dev/)** • 🚀 **[Try the Sandbox](https://try.drizzle-cube.dev/)**
8
+
7
9
  > **⚠️ DEVELOPMENT WARNING**
8
10
  > **This project is under active development and is not yet fully functional. I will update here when we reach an alpha/working version!**
9
11
  > Feel free to star ⭐ the repo to stay updated on progress.
@@ -318,11 +320,31 @@ Supports all Cube.js filter operators with Drizzle safety:
318
320
 
319
321
  ## Documentation
320
322
 
321
- Coming soon! 📚
323
+ 📚 **[Full Documentation](https://drizzle-cube.dev/help)** - Complete guides and API reference
324
+
325
+ ### Quick Links
326
+ - [Getting Started](https://drizzle-cube.dev/help/getting-started) - Installation and first steps
327
+ - [Core Concepts](https://drizzle-cube.dev/help/getting-started/concepts) - Cubes, dimensions, and measures
328
+ - [Semantic Layer](https://drizzle-cube.dev/help/semantic-layer) - Advanced semantic layer features
329
+ - [React Client](https://drizzle-cube.dev/help/client) - Dashboard and chart components
330
+ - [Hono Adapter](https://drizzle-cube.dev/help/adapters/hono) - Web framework integration
331
+ - [Security](https://drizzle-cube.dev/help/semantic-layer/security) - Multi-tenant security patterns
332
+
333
+ ### Local Development
334
+ ```bash
335
+ # Run documentation site locally
336
+ npm run dev:help
337
+
338
+ # Build documentation site
339
+ npm run build:help
340
+ ```
322
341
 
323
342
  ## Examples
324
343
 
325
- Coming soon! Check the test files for usage patterns in the meantime.
344
+ 🚀 **[Live Examples](https://github.com/cliftonc/drizzle-cube/tree/main/examples)**
345
+
346
+ - **[Basic Example](https://github.com/cliftonc/drizzle-cube/tree/main/examples/basic)** - Simple semantic layer setup
347
+ - **[Hono Example](https://github.com/cliftonc/drizzle-cube/tree/main/examples/hono)** - Full-featured dashboard with Cloudflare Workers
326
348
 
327
349
  ## Contributing
328
350
 
@@ -1,5 +1,8 @@
1
1
  import { Hono } from 'hono';
2
2
  import { SemanticLayerCompiler, SemanticQuery, SecurityContext, DatabaseExecutor, DrizzleDatabase } from '../../server';
3
+ import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
4
+ import { MySql2Database } from 'drizzle-orm/mysql2';
5
+ import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
3
6
  export interface HonoAdapterOptions<TSchema extends Record<string, any> = Record<string, any>> {
4
7
  /**
5
8
  * The semantic layer instance to use
@@ -8,8 +11,9 @@ export interface HonoAdapterOptions<TSchema extends Record<string, any> = Record
8
11
  /**
9
12
  * Drizzle database instance (REQUIRED)
10
13
  * This is the core of drizzle-cube - Drizzle ORM integration
14
+ * Accepts PostgreSQL, MySQL, or SQLite database instances
11
15
  */
12
- drizzle: DrizzleDatabase<TSchema>;
16
+ drizzle: PostgresJsDatabase<TSchema> | MySql2Database<TSchema> | BetterSQLite3Database<TSchema> | DrizzleDatabase<TSchema>;
13
17
  /**
14
18
  * Database schema for type inference (RECOMMENDED)
15
19
  * Provides full type safety for cube definitions
@@ -1,64 +1,79 @@
1
- import { Hono as w } from "hono";
2
- var j = (f) => {
3
- const u = {
1
+ import { Hono as D } from "hono";
2
+ var S = (q) => {
3
+ const d = {
4
4
  ...{
5
5
  origin: "*",
6
6
  allowMethods: ["GET", "HEAD", "PUT", "POST", "DELETE", "PATCH"],
7
7
  allowHeaders: [],
8
8
  exposeHeaders: []
9
9
  },
10
- ...f
11
- }, q = /* @__PURE__ */ ((a) => typeof a == "string" ? a === "*" ? () => a : (t) => a === t ? t : null : typeof a == "function" ? a : (t) => a.includes(t) ? t : null)(u.origin), m = ((a) => typeof a == "function" ? a : Array.isArray(a) ? () => a : () => [])(u.allowMethods);
12
- return async function(t, d) {
13
- var i;
14
- function e(r, n) {
15
- t.res.headers.set(r, n);
10
+ ...q
11
+ }, A = /* @__PURE__ */ ((u) => typeof u == "string" ? u === "*" ? () => u : (n) => u === n ? n : null : typeof u == "function" ? u : (n) => u.includes(n) ? n : null)(d.origin), j = ((u) => typeof u == "function" ? u : Array.isArray(u) ? () => u : () => [])(d.allowMethods);
12
+ return async function(n, m) {
13
+ var x;
14
+ function p(h, f) {
15
+ n.res.headers.set(h, f);
16
16
  }
17
- const o = q(t.req.header("origin") || "", t);
18
- if (o && e("Access-Control-Allow-Origin", o), u.origin !== "*") {
19
- const r = t.req.header("Vary");
20
- r ? e("Vary", r) : e("Vary", "Origin");
17
+ const b = A(n.req.header("origin") || "", n);
18
+ if (b && p("Access-Control-Allow-Origin", b), d.origin !== "*") {
19
+ const h = n.req.header("Vary");
20
+ h ? p("Vary", h) : p("Vary", "Origin");
21
21
  }
22
- if (u.credentials && e("Access-Control-Allow-Credentials", "true"), (i = u.exposeHeaders) != null && i.length && e("Access-Control-Expose-Headers", u.exposeHeaders.join(",")), t.req.method === "OPTIONS") {
23
- u.maxAge != null && e("Access-Control-Max-Age", u.maxAge.toString());
24
- const r = m(t.req.header("origin") || "", t);
25
- r.length && e("Access-Control-Allow-Methods", r.join(","));
26
- let n = u.allowHeaders;
27
- if (!(n != null && n.length)) {
28
- const s = t.req.header("Access-Control-Request-Headers");
29
- s && (n = s.split(/\s*,\s*/));
22
+ if (d.credentials && p("Access-Control-Allow-Credentials", "true"), (x = d.exposeHeaders) != null && x.length && p("Access-Control-Expose-Headers", d.exposeHeaders.join(",")), n.req.method === "OPTIONS") {
23
+ d.maxAge != null && p("Access-Control-Max-Age", d.maxAge.toString());
24
+ const h = j(n.req.header("origin") || "", n);
25
+ h.length && p("Access-Control-Allow-Methods", h.join(","));
26
+ let f = d.allowHeaders;
27
+ if (!(f != null && f.length)) {
28
+ const e = n.req.header("Access-Control-Request-Headers");
29
+ e && (f = e.split(/\s*,\s*/));
30
30
  }
31
- return n != null && n.length && (e("Access-Control-Allow-Headers", n.join(",")), t.res.headers.append("Vary", "Access-Control-Request-Headers")), t.res.headers.delete("Content-Length"), t.res.headers.delete("Content-Type"), new Response(null, {
32
- headers: t.res.headers,
31
+ return f != null && f.length && (p("Access-Control-Allow-Headers", f.join(",")), n.res.headers.append("Vary", "Access-Control-Request-Headers")), n.res.headers.delete("Content-Length"), n.res.headers.delete("Content-Type"), new Response(null, {
32
+ headers: n.res.headers,
33
33
  status: 204,
34
34
  statusText: "No Content"
35
35
  });
36
36
  }
37
- await d();
37
+ await m();
38
38
  };
39
39
  };
40
- function C(f) {
40
+ function E(q) {
41
41
  const {
42
- semanticLayer: l,
43
- drizzle: u,
44
- schema: q,
45
- getSecurityContext: m,
46
- cors: a,
47
- basePath: t = "/cubejs-api/v1"
48
- } = f, d = new w();
49
- return a && d.use("/*", j(a)), l.hasExecutor() || l.setDrizzle(u, q), d.post(`${t}/load`, async (e) => {
50
- var o, i;
42
+ semanticLayer: a,
43
+ drizzle: d,
44
+ schema: A,
45
+ getSecurityContext: j,
46
+ cors: u,
47
+ basePath: n = "/cubejs-api/v1"
48
+ } = q, m = new D();
49
+ u && m.use("/*", S(u)), a.hasExecutor() || a.setDrizzle(d, A), m.post(`${n}/load`, async (e) => {
51
50
  try {
52
- const r = await e.req.json(), n = await m(e);
53
- if (!((o = r.measures) != null && o.length) && !((i = r.dimensions) != null && i.length))
51
+ const r = await e.req.json(), s = r.query || r, t = await j(e), o = a.validateQuery(s);
52
+ if (!o.isValid)
54
53
  return e.json({
55
- error: "Query must specify at least one measure or dimension"
54
+ error: `Query validation failed: ${o.errors.join(", ")}`
56
55
  }, 400);
57
- const s = await l.executeMultiCubeQuery(r, n);
56
+ const i = await a.executeMultiCubeQuery(s, t), l = h(a), y = b(), g = (/* @__PURE__ */ new Date()).toISOString(), Q = x(s);
58
57
  return e.json({
59
- data: s.data,
60
- annotation: s.annotation,
61
- query: r,
58
+ queryType: "regularQuery",
59
+ results: [{
60
+ query: s,
61
+ lastRefreshTime: g,
62
+ usedPreAggregations: {},
63
+ transformedQuery: Q,
64
+ requestId: y,
65
+ annotation: i.annotation,
66
+ dataSource: "default",
67
+ dbType: l,
68
+ extDbType: l,
69
+ external: !1,
70
+ slowQuery: !1,
71
+ data: i.data
72
+ }],
73
+ pivotQuery: {
74
+ ...s,
75
+ queryType: "regularQuery"
76
+ },
62
77
  slowQuery: !1
63
78
  });
64
79
  } catch (r) {
@@ -66,24 +81,39 @@ function C(f) {
66
81
  error: r instanceof Error ? r.message : "Query execution failed"
67
82
  }, 500);
68
83
  }
69
- }), d.get(`${t}/load`, async (e) => {
70
- var o, i;
84
+ }), m.get(`${n}/load`, async (e) => {
71
85
  try {
72
86
  const r = e.req.query("query");
73
87
  if (!r)
74
88
  return e.json({
75
89
  error: "Query parameter is required"
76
90
  }, 400);
77
- const n = JSON.parse(r), s = await m(e);
78
- if (!((o = n.measures) != null && o.length) && !((i = n.dimensions) != null && i.length))
91
+ const s = JSON.parse(r), t = await j(e), o = a.validateQuery(s);
92
+ if (!o.isValid)
79
93
  return e.json({
80
- error: "Query must specify at least one measure or dimension"
94
+ error: `Query validation failed: ${o.errors.join(", ")}`
81
95
  }, 400);
82
- const c = await l.executeMultiCubeQuery(n, s);
96
+ const i = await a.executeMultiCubeQuery(s, t), l = h(a), y = b(), g = (/* @__PURE__ */ new Date()).toISOString(), Q = x(s);
83
97
  return e.json({
84
- data: c.data,
85
- annotation: c.annotation,
86
- query: n,
98
+ queryType: "regularQuery",
99
+ results: [{
100
+ query: s,
101
+ lastRefreshTime: g,
102
+ usedPreAggregations: {},
103
+ transformedQuery: Q,
104
+ requestId: y,
105
+ annotation: i.annotation,
106
+ dataSource: "default",
107
+ dbType: l,
108
+ extDbType: l,
109
+ external: !1,
110
+ slowQuery: !1,
111
+ data: i.data
112
+ }],
113
+ pivotQuery: {
114
+ ...s,
115
+ queryType: "regularQuery"
116
+ },
87
117
  slowQuery: !1
88
118
  });
89
119
  } catch (r) {
@@ -91,82 +121,215 @@ function C(f) {
91
121
  error: r instanceof Error ? r.message : "Query execution failed"
92
122
  }, 500);
93
123
  }
94
- }), d.get(`${t}/meta`, async (e) => {
124
+ }), m.get(`${n}/meta`, (e) => {
95
125
  try {
96
- const o = l.getMetadata();
126
+ const r = a.getMetadata();
97
127
  return e.json({
98
- cubes: o
128
+ cubes: r
99
129
  });
100
- } catch (o) {
101
- return console.error("Metadata error:", o), e.json({
102
- error: o instanceof Error ? o.message : "Failed to fetch metadata"
130
+ } catch (r) {
131
+ return console.error("Metadata error:", r), e.json({
132
+ error: r instanceof Error ? r.message : "Failed to fetch metadata"
103
133
  }, 500);
104
134
  }
105
- }), d.post(`${t}/sql`, async (e) => {
106
- var o, i, r, n;
135
+ }), m.post(`${n}/sql`, async (e) => {
136
+ var r, s;
107
137
  try {
108
- const s = await e.req.json(), c = await m(e);
109
- if (!((o = s.measures) != null && o.length) && !((i = s.dimensions) != null && i.length))
138
+ const t = await e.req.json(), o = await j(e), i = a.validateQuery(t);
139
+ if (!i.isValid)
110
140
  return e.json({
111
- error: "Query must specify at least one measure or dimension"
141
+ error: `Query validation failed: ${i.errors.join(", ")}`
112
142
  }, 400);
113
- const y = ((r = s.measures) == null ? void 0 : r[0]) || ((n = s.dimensions) == null ? void 0 : n[0]);
114
- if (!y)
143
+ const l = ((r = t.measures) == null ? void 0 : r[0]) || ((s = t.dimensions) == null ? void 0 : s[0]);
144
+ if (!l)
115
145
  return e.json({
116
146
  error: "No measures or dimensions specified"
117
147
  }, 400);
118
- const g = y.split(".")[0], h = await l.generateSQL(g, s, c);
148
+ const y = l.split(".")[0], g = await a.generateSQL(y, t, o);
119
149
  return e.json({
120
- sql: h.sql,
121
- params: h.params || [],
122
- query: s
150
+ sql: g.sql,
151
+ params: g.params || [],
152
+ query: t
123
153
  });
124
- } catch (s) {
125
- return console.error("SQL generation error:", s), e.json({
126
- error: s instanceof Error ? s.message : "SQL generation failed"
154
+ } catch (t) {
155
+ return console.error("SQL generation error:", t), e.json({
156
+ error: t instanceof Error ? t.message : "SQL generation failed"
127
157
  }, 500);
128
158
  }
129
- }), d.get(`${t}/sql`, async (e) => {
130
- var o, i, r, n;
159
+ }), m.get(`${n}/sql`, async (e) => {
160
+ var r, s;
131
161
  try {
132
- const s = e.req.query("query");
133
- if (!s)
162
+ const t = e.req.query("query");
163
+ if (!t)
134
164
  return e.json({
135
165
  error: "Query parameter is required"
136
166
  }, 400);
137
- const c = JSON.parse(s), y = await m(e);
138
- if (!((o = c.measures) != null && o.length) && !((i = c.dimensions) != null && i.length))
167
+ const o = JSON.parse(t), i = await j(e), l = a.validateQuery(o);
168
+ if (!l.isValid)
139
169
  return e.json({
140
- error: "Query must specify at least one measure or dimension"
170
+ error: `Query validation failed: ${l.errors.join(", ")}`
141
171
  }, 400);
142
- const g = ((r = c.measures) == null ? void 0 : r[0]) || ((n = c.dimensions) == null ? void 0 : n[0]);
143
- if (!g)
172
+ const y = ((r = o.measures) == null ? void 0 : r[0]) || ((s = o.dimensions) == null ? void 0 : s[0]);
173
+ if (!y)
144
174
  return e.json({
145
175
  error: "No measures or dimensions specified"
146
176
  }, 400);
147
- const h = g.split(".")[0], p = await l.generateSQL(h, c, y);
177
+ const g = y.split(".")[0], Q = await a.generateSQL(g, o, i);
148
178
  return e.json({
149
- sql: p.sql,
150
- params: p.params || [],
151
- query: c
179
+ sql: Q.sql,
180
+ params: Q.params || [],
181
+ query: o
152
182
  });
153
- } catch (s) {
154
- return console.error("SQL generation error:", s), e.json({
155
- error: s instanceof Error ? s.message : "SQL generation failed"
183
+ } catch (t) {
184
+ return console.error("SQL generation error:", t), e.json({
185
+ error: t instanceof Error ? t.message : "SQL generation failed"
156
186
  }, 500);
157
187
  }
158
- }), d;
188
+ });
189
+ function p(e) {
190
+ var s, t, o, i;
191
+ let r = 0;
192
+ return r += (((s = e.measures) == null ? void 0 : s.length) || 0) * 1, r += (((t = e.dimensions) == null ? void 0 : t.length) || 0) * 1, r += (((o = e.filters) == null ? void 0 : o.length) || 0) * 2, r += (((i = e.timeDimensions) == null ? void 0 : i.length) || 0) * 3, r <= 5 ? "low" : r <= 15 ? "medium" : "high";
193
+ }
194
+ function b() {
195
+ const e = Date.now(), r = Math.random().toString(36).substring(2, 9);
196
+ return `${e}-${r}`;
197
+ }
198
+ function x(e) {
199
+ const r = e.dimensions || [], s = e.timeDimensions || [], t = e.measures || [];
200
+ return {
201
+ sortedDimensions: r,
202
+ sortedTimeDimensions: s,
203
+ timeDimensions: s,
204
+ measures: t,
205
+ leafMeasureAdditive: !0,
206
+ leafMeasures: t,
207
+ measureToLeafMeasures: {},
208
+ hasNoTimeDimensionsWithoutGranularity: !0,
209
+ allFiltersWithinSelectedDimensions: !0,
210
+ isAdditive: !0,
211
+ granularityHierarchies: {},
212
+ hasMultipliedMeasures: !1,
213
+ hasCumulativeMeasures: !1,
214
+ windowGranularity: null,
215
+ filterDimensionsSingleValueEqual: {},
216
+ ownedDimensions: r,
217
+ ownedTimeDimensionsWithRollupGranularity: [],
218
+ ownedTimeDimensionsAsIs: [],
219
+ allBackAliasMembers: {},
220
+ hasMultiStage: !1
221
+ };
222
+ }
223
+ function h(e) {
224
+ if (e.hasExecutor()) {
225
+ const r = e.databaseExecutor;
226
+ if (r != null && r.engineType)
227
+ return r.engineType;
228
+ }
229
+ return "postgres";
230
+ }
231
+ async function f(e, r) {
232
+ var y, g, Q, v;
233
+ const s = a.validateQuery(e);
234
+ if (!s.isValid)
235
+ throw new Error(`Query validation failed: ${s.errors.join(", ")}`);
236
+ const t = /* @__PURE__ */ new Set();
237
+ (y = e.measures) == null || y.forEach((c) => {
238
+ const w = c.split(".")[0];
239
+ t.add(w);
240
+ }), (g = e.dimensions) == null || g.forEach((c) => {
241
+ const w = c.split(".")[0];
242
+ t.add(w);
243
+ }), (Q = e.timeDimensions) == null || Q.forEach((c) => {
244
+ const w = c.dimension.split(".")[0];
245
+ t.add(w);
246
+ }), (v = e.filters) == null || v.forEach((c) => {
247
+ if ("member" in c) {
248
+ const w = c.member.split(".")[0];
249
+ t.add(w);
250
+ }
251
+ });
252
+ const o = t.size > 1;
253
+ let i;
254
+ if (o)
255
+ i = await a.generateMultiCubeSQL(e, r);
256
+ else {
257
+ const c = Array.from(t)[0];
258
+ i = await a.generateSQL(c, e, r);
259
+ }
260
+ const l = Array.from(t).map((c) => {
261
+ var w, T;
262
+ return {
263
+ cube: c,
264
+ query: {
265
+ measures: ((w = e.measures) == null ? void 0 : w.filter((C) => C.startsWith(c + "."))) || [],
266
+ dimensions: ((T = e.dimensions) == null ? void 0 : T.filter((C) => C.startsWith(c + "."))) || [],
267
+ filters: e.filters || [],
268
+ timeDimensions: e.timeDimensions || [],
269
+ order: e.order || {},
270
+ limit: e.limit,
271
+ offset: e.offset
272
+ }
273
+ };
274
+ });
275
+ return {
276
+ queryType: "regularQuery",
277
+ normalizedQueries: l,
278
+ queryOrder: Array.from(t),
279
+ transformedQueries: l,
280
+ pivotQuery: {
281
+ query: e,
282
+ cubes: Array.from(t)
283
+ },
284
+ sql: {
285
+ sql: [i.sql],
286
+ params: i.params || []
287
+ },
288
+ complexity: p(e),
289
+ valid: !0,
290
+ cubesUsed: Array.from(t),
291
+ joinType: o ? "multi_cube_join" : "single_cube",
292
+ query: e
293
+ };
294
+ }
295
+ return m.post(`${n}/dry-run`, async (e) => {
296
+ try {
297
+ const r = await e.req.json(), s = r.query || r, t = await j(e), o = await f(s, t);
298
+ return e.json(o);
299
+ } catch (r) {
300
+ return console.error("Dry-run error:", r), e.json({
301
+ error: r instanceof Error ? r.message : "Dry-run validation failed",
302
+ valid: !1
303
+ }, 400);
304
+ }
305
+ }), m.get(`${n}/dry-run`, async (e) => {
306
+ try {
307
+ const r = e.req.query("query");
308
+ if (!r)
309
+ return e.json({
310
+ error: "Query parameter is required",
311
+ valid: !1
312
+ }, 400);
313
+ const s = JSON.parse(r), t = await j(e), o = await f(s, t);
314
+ return e.json(o);
315
+ } catch (r) {
316
+ return console.error("Dry-run error:", r), e.json({
317
+ error: r instanceof Error ? r.message : "Dry-run validation failed",
318
+ valid: !1
319
+ }, 400);
320
+ }
321
+ }), m;
159
322
  }
160
- function x(f, l) {
161
- const u = C(l);
162
- return f.route("/", u), f;
323
+ function M(q, a) {
324
+ const d = E(a);
325
+ return q.route("/", d), q;
163
326
  }
164
- function A(f) {
165
- const l = new w();
166
- return x(l, f);
327
+ function R(q) {
328
+ const a = new D();
329
+ return M(a, q);
167
330
  }
168
331
  export {
169
- A as createCubeApp,
170
- C as createCubeRoutes,
171
- x as mountCubeRoutes
332
+ R as createCubeApp,
333
+ E as createCubeRoutes,
334
+ M as mountCubeRoutes
172
335
  };
@@ -0,0 +1,15 @@
1
+ import { CubeQuery, CubeApiOptions, CubeResultSet } from '../types';
2
+ export declare class CubeClient {
3
+ private apiUrl;
4
+ private headers;
5
+ constructor(token?: string, options?: CubeApiOptions);
6
+ load(query: CubeQuery): Promise<CubeResultSet>;
7
+ meta(): Promise<any>;
8
+ sql(query: CubeQuery): Promise<any>;
9
+ dryRun(query: CubeQuery): Promise<any>;
10
+ }
11
+ /**
12
+ * Factory function to create a cube client
13
+ */
14
+ export declare function createCubeClient(token?: string, options?: CubeApiOptions): CubeClient;
15
+ export declare function cube(token?: string, options?: CubeApiOptions): CubeClient;
@@ -0,0 +1,2 @@
1
+ import { AnalyticsDashboardProps } from '../types';
2
+ export default function AnalyticsDashboard({ config, apiUrl, apiOptions, editable, onConfigChange, onSave, onDirtyStateChange }: AnalyticsDashboardProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1 @@
1
+ export declare function AnalyticsPage(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import { AnalyticsPortletProps } from '../types';
2
+ interface AnalyticsPortletRef {
3
+ refresh: () => void;
4
+ }
5
+ declare const AnalyticsPortlet: import('react').ForwardRefExoticComponent<AnalyticsPortletProps & import('react').RefAttributes<AnalyticsPortletRef>>;
6
+ export default AnalyticsPortlet;
@@ -0,0 +1,8 @@
1
+ import { ChartAxisConfig, ChartDisplayConfig } from '../types';
2
+ interface ChartConfigEditorProps {
3
+ chartConfig: ChartAxisConfig;
4
+ displayConfig?: ChartDisplayConfig;
5
+ onConfigChange: (chartConfig: ChartAxisConfig, displayConfig: ChartDisplayConfig) => void;
6
+ }
7
+ export default function ChartConfigEditor({ chartConfig, displayConfig, onConfigChange }: ChartConfigEditorProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
@@ -0,0 +1,21 @@
1
+ import { default as React, Component, ReactNode } from 'react';
2
+ interface Props {
3
+ children: ReactNode;
4
+ fallback?: ReactNode;
5
+ portletTitle?: string;
6
+ portletConfig?: any;
7
+ cubeQuery?: string;
8
+ }
9
+ interface State {
10
+ hasError: boolean;
11
+ error: Error | null;
12
+ errorInfo: string | null;
13
+ }
14
+ export default class ChartErrorBoundary extends Component<Props, State> {
15
+ constructor(props: Props);
16
+ static getDerivedStateFromError(error: Error): State;
17
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
18
+ handleReset: () => void;
19
+ render(): string | number | boolean | Iterable<React.ReactNode> | import("react/jsx-runtime").JSX.Element | null | undefined;
20
+ }
21
+ export {};
@@ -0,0 +1,14 @@
1
+ interface DashboardEditModalProps {
2
+ isOpen: boolean;
3
+ onClose: () => void;
4
+ onSave: (data: {
5
+ name: string;
6
+ description?: string;
7
+ }) => Promise<void> | void;
8
+ title: string;
9
+ submitText: string;
10
+ initialName?: string;
11
+ initialDescription?: string;
12
+ }
13
+ export default function DashboardEditModal({ isOpen, onClose, onSave, title, submitText, initialName, initialDescription }: DashboardEditModalProps): import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,11 @@
1
+ import { DashboardConfig } from '../types';
2
+ interface DashboardGridProps {
3
+ config: DashboardConfig;
4
+ editable?: boolean;
5
+ onConfigChange?: (config: DashboardConfig) => void;
6
+ onPortletRefresh?: (portletId: string) => void;
7
+ onSave?: (config: DashboardConfig) => Promise<void> | void;
8
+ apiUrl?: string;
9
+ }
10
+ export default function DashboardGrid({ config, editable, onConfigChange, onPortletRefresh, onSave, apiUrl }: DashboardGridProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,16 @@
1
+ import { default as React } from 'react';
2
+ export interface ModalProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ title?: string;
6
+ size?: 'sm' | 'md' | 'lg' | 'xl' | 'full' | 'fullscreen';
7
+ closeOnBackdropClick?: boolean;
8
+ closeOnEscape?: boolean;
9
+ showCloseButton?: boolean;
10
+ className?: string;
11
+ children: React.ReactNode;
12
+ footer?: React.ReactNode;
13
+ noPadding?: boolean;
14
+ }
15
+ declare const Modal: React.FC<ModalProps>;
16
+ export default Modal;
@@ -0,0 +1,10 @@
1
+ import { PortletConfig } from '../types';
2
+ interface PortletContainerProps {
3
+ portlet: PortletConfig;
4
+ editable?: boolean;
5
+ onEdit?: (portlet: PortletConfig) => void;
6
+ onDelete?: (portletId: string) => void;
7
+ onRefresh?: (portletId: string) => void;
8
+ }
9
+ export default function PortletContainer({ portlet, editable, onEdit, onDelete, onRefresh }: PortletContainerProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,12 @@
1
+ import { PortletConfig } from '../types';
2
+ interface PortletEditModalProps {
3
+ isOpen: boolean;
4
+ onClose: () => void;
5
+ onSave: (portlet: PortletConfig | Omit<PortletConfig, 'id' | 'x' | 'y'>) => void;
6
+ portlet?: PortletConfig | null;
7
+ title: string;
8
+ submitText: string;
9
+ apiUrl?: string;
10
+ }
11
+ export default function PortletEditModal({ isOpen, onClose, onSave, portlet, title, submitText, apiUrl }: PortletEditModalProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { CubeMetaExplorerProps } from './types';
3
+ declare const CubeMetaExplorer: React.FC<CubeMetaExplorerProps>;
4
+ export default CubeMetaExplorer;
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { QueryPanelProps } from './types';
3
+ declare const QueryPanel: React.FC<QueryPanelProps>;
4
+ export default QueryPanel;
@@ -0,0 +1,4 @@
1
+ import { default as React } from 'react';
2
+ import { ResultsPanelProps } from './types';
3
+ declare const ResultsPanel: React.FC<ResultsPanelProps>;
4
+ export default ResultsPanel;