drizzle-cube 0.1.8 → 0.1.10

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.
@@ -1,58 +1,311 @@
1
- var z = Object.defineProperty;
2
- var U = (s, e, t) => e in s ? z(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var C = (s, e, t) => U(s, typeof e != "symbol" ? e + "" : e, t);
4
- import { sql as f, and as p, eq as v, count as y, max as B, min as O, avg as R, sum as I, countDistinct as Y, or as J, gt as A, lt as F, gte as w, lte as N, isNull as W, isNotNull as K, notInArray as H, ne as V, inArray as Z } from "drizzle-orm";
5
- import { parse as G, stringify as P } from "yaml";
6
- function we(s, e) {
1
+ var W = Object.defineProperty;
2
+ var B = (o, e, t) => e in o ? W(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
3
+ var C = (o, e, t) => B(o, typeof e != "symbol" ? e + "" : e, t);
4
+ import { sql as m, and as h, or as j, gt as N, lt as $, gte as w, lte as D, isNull as _, isNotNull as z, eq as v, count as y, max as Y, min as R, avg as K, sum as J, countDistinct as H, notInArray as V, ne as G, inArray as P } from "drizzle-orm";
5
+ import { parse as Z, stringify as X } from "yaml";
6
+ class O {
7
+ /**
8
+ * Helper method to build pattern for string matching
9
+ * Can be overridden by specific adapters if needed
10
+ */
11
+ buildPattern(e, t) {
12
+ switch (e) {
13
+ case "contains":
14
+ case "notContains":
15
+ return `%${t}%`;
16
+ case "startsWith":
17
+ return `${t}%`;
18
+ case "endsWith":
19
+ return `%${t}`;
20
+ default:
21
+ return t;
22
+ }
23
+ }
24
+ }
25
+ class q extends O {
26
+ getEngineType() {
27
+ return "postgres";
28
+ }
29
+ /**
30
+ * Build PostgreSQL time dimension using DATE_TRUNC function
31
+ * Extracted from executor.ts:649-670 and multi-cube-builder.ts:306-320
32
+ */
33
+ buildTimeDimension(e, t) {
34
+ switch (e) {
35
+ case "year":
36
+ return m`DATE_TRUNC('year', ${t}::timestamp)`;
37
+ case "quarter":
38
+ return m`DATE_TRUNC('quarter', ${t}::timestamp)`;
39
+ case "month":
40
+ return m`DATE_TRUNC('month', ${t}::timestamp)`;
41
+ case "week":
42
+ return m`DATE_TRUNC('week', ${t}::timestamp)`;
43
+ case "day":
44
+ return m`DATE_TRUNC('day', ${t}::timestamp)::timestamp`;
45
+ case "hour":
46
+ return m`DATE_TRUNC('hour', ${t}::timestamp)`;
47
+ case "minute":
48
+ return m`DATE_TRUNC('minute', ${t}::timestamp)`;
49
+ case "second":
50
+ return m`DATE_TRUNC('second', ${t}::timestamp)`;
51
+ default:
52
+ return t;
53
+ }
54
+ }
55
+ /**
56
+ * Build PostgreSQL string matching conditions using ILIKE (case-insensitive)
57
+ * Extracted from executor.ts:807-813 and multi-cube-builder.ts:468-474
58
+ */
59
+ buildStringCondition(e, t, s) {
60
+ const n = this.buildPattern(t, s);
61
+ switch (t) {
62
+ case "contains":
63
+ return m`${e} ILIKE ${n}`;
64
+ case "notContains":
65
+ return m`${e} NOT ILIKE ${n}`;
66
+ case "startsWith":
67
+ return m`${e} ILIKE ${n}`;
68
+ case "endsWith":
69
+ return m`${e} ILIKE ${n}`;
70
+ default:
71
+ throw new Error(`Unsupported string operator: ${t}`);
72
+ }
73
+ }
74
+ /**
75
+ * Build PostgreSQL type casting using :: syntax
76
+ * Extracted from various locations where ::timestamp was used
77
+ */
78
+ castToType(e, t) {
79
+ switch (t) {
80
+ case "timestamp":
81
+ return m`${e}::timestamp`;
82
+ case "decimal":
83
+ return m`${e}::decimal`;
84
+ case "integer":
85
+ return m`${e}::integer`;
86
+ default:
87
+ throw new Error(`Unsupported cast type: ${t}`);
88
+ }
89
+ }
90
+ /**
91
+ * Build PostgreSQL COUNT aggregation
92
+ * Extracted from multi-cube-builder.ts:278
93
+ */
94
+ buildCount(e) {
95
+ return m`COUNT(${e})`;
96
+ }
97
+ /**
98
+ * Build PostgreSQL COUNT DISTINCT aggregation
99
+ * Extracted from multi-cube-builder.ts:280
100
+ */
101
+ buildCountDistinct(e) {
102
+ return m`COUNT(DISTINCT ${e})`;
103
+ }
104
+ /**
105
+ * Build PostgreSQL SUM aggregation
106
+ * Extracted from multi-cube-builder.ts:282
107
+ */
108
+ buildSum(e) {
109
+ return m`SUM(${e})`;
110
+ }
111
+ /**
112
+ * Build PostgreSQL AVG aggregation with COALESCE for NULL handling
113
+ * PostgreSQL AVG returns NULL for empty sets, so we use COALESCE for consistent behavior
114
+ * Extracted from multi-cube-builder.ts:284
115
+ */
116
+ buildAvg(e) {
117
+ return m`COALESCE(AVG(${e}), 0)`;
118
+ }
119
+ /**
120
+ * Build PostgreSQL MIN aggregation
121
+ * Extracted from multi-cube-builder.ts:286
122
+ */
123
+ buildMin(e) {
124
+ return m`MIN(${e})`;
125
+ }
126
+ /**
127
+ * Build PostgreSQL MAX aggregation
128
+ * Extracted from multi-cube-builder.ts:288
129
+ */
130
+ buildMax(e) {
131
+ return m`MAX(${e})`;
132
+ }
133
+ }
134
+ class ee extends O {
135
+ getEngineType() {
136
+ return "mysql";
137
+ }
138
+ /**
139
+ * Build MySQL time dimension using DATE_FORMAT function
140
+ * MySQL equivalent to PostgreSQL's DATE_TRUNC
141
+ */
142
+ buildTimeDimension(e, t) {
143
+ const s = {
144
+ year: "%Y-01-01 00:00:00",
145
+ quarter: "%Y-%q-01 00:00:00",
146
+ // %q gives quarter (1,2,3,4), but we need to map this properly
147
+ month: "%Y-%m-01 00:00:00",
148
+ week: "%Y-%u-01 00:00:00",
149
+ // %u gives week of year
150
+ day: "%Y-%m-%d 00:00:00",
151
+ hour: "%Y-%m-%d %H:00:00",
152
+ minute: "%Y-%m-%d %H:%i:00",
153
+ second: "%Y-%m-%d %H:%i:%s"
154
+ };
155
+ switch (e) {
156
+ case "quarter":
157
+ return m`DATE_ADD(MAKEDATE(YEAR(${t}), 1), INTERVAL (QUARTER(${t}) - 1) * 3 MONTH)`;
158
+ case "week":
159
+ return m`DATE_SUB(${t}, INTERVAL WEEKDAY(${t}) DAY)`;
160
+ default:
161
+ const n = s[e];
162
+ return n ? m`STR_TO_DATE(DATE_FORMAT(${t}, ${n}), '%Y-%m-%d %H:%i:%s')` : t;
163
+ }
164
+ }
165
+ /**
166
+ * Build MySQL string matching conditions using LIKE
167
+ * MySQL LIKE is case-insensitive by default (depending on collation)
168
+ * For guaranteed case-insensitive matching, we use LOWER() functions
169
+ */
170
+ buildStringCondition(e, t, s) {
171
+ const n = this.buildPattern(t, s.toLowerCase());
172
+ switch (t) {
173
+ case "contains":
174
+ return m`LOWER(${e}) LIKE ${n}`;
175
+ case "notContains":
176
+ return m`LOWER(${e}) NOT LIKE ${n}`;
177
+ case "startsWith":
178
+ return m`LOWER(${e}) LIKE ${n}`;
179
+ case "endsWith":
180
+ return m`LOWER(${e}) LIKE ${n}`;
181
+ default:
182
+ throw new Error(`Unsupported string operator: ${t}`);
183
+ }
184
+ }
185
+ /**
186
+ * Build MySQL type casting using CAST() function
187
+ * MySQL equivalent to PostgreSQL's :: casting syntax
188
+ */
189
+ castToType(e, t) {
190
+ switch (t) {
191
+ case "timestamp":
192
+ return m`CAST(${e} AS DATETIME)`;
193
+ case "decimal":
194
+ return m`CAST(${e} AS DECIMAL(10,2))`;
195
+ case "integer":
196
+ return m`CAST(${e} AS SIGNED INTEGER)`;
197
+ default:
198
+ throw new Error(`Unsupported cast type: ${t}`);
199
+ }
200
+ }
201
+ /**
202
+ * Build MySQL COUNT aggregation
203
+ * Standard SQL COUNT function
204
+ */
205
+ buildCount(e) {
206
+ return m`COUNT(${e})`;
207
+ }
208
+ /**
209
+ * Build MySQL COUNT DISTINCT aggregation
210
+ * Standard SQL COUNT DISTINCT function
211
+ */
212
+ buildCountDistinct(e) {
213
+ return m`COUNT(DISTINCT ${e})`;
214
+ }
215
+ /**
216
+ * Build MySQL SUM aggregation
217
+ * Standard SQL SUM function
218
+ */
219
+ buildSum(e) {
220
+ return m`SUM(${e})`;
221
+ }
222
+ /**
223
+ * Build MySQL AVG aggregation with IFNULL for NULL handling
224
+ * MySQL AVG returns NULL for empty sets, using IFNULL for consistency
225
+ */
226
+ buildAvg(e) {
227
+ return m`IFNULL(AVG(${e}), 0)`;
228
+ }
229
+ /**
230
+ * Build MySQL MIN aggregation
231
+ * Standard SQL MIN function
232
+ */
233
+ buildMin(e) {
234
+ return m`MIN(${e})`;
235
+ }
236
+ /**
237
+ * Build MySQL MAX aggregation
238
+ * Standard SQL MAX function
239
+ */
240
+ buildMax(e) {
241
+ return m`MAX(${e})`;
242
+ }
243
+ }
244
+ function te(o) {
245
+ switch (o) {
246
+ case "postgres":
247
+ return new q();
248
+ case "mysql":
249
+ return new ee();
250
+ case "sqlite":
251
+ throw new Error("SQLite adapter not yet implemented");
252
+ default:
253
+ throw new Error(`Unsupported database engine: ${o}`);
254
+ }
255
+ }
256
+ function $e(o, e) {
7
257
  return {
8
258
  ...e,
9
259
  name: e.name
10
260
  };
11
261
  }
12
- class x {
13
- constructor(e, t) {
262
+ class S {
263
+ constructor(e, t, s) {
264
+ C(this, "databaseAdapter");
14
265
  this.db = e, this.schema = t;
266
+ const n = s || this.getEngineType();
267
+ this.databaseAdapter = te(n);
15
268
  }
16
269
  }
17
- class X extends x {
270
+ class ne extends S {
18
271
  async execute(e, t) {
19
272
  if (e && typeof e == "object") {
20
273
  if (typeof e.execute == "function") {
21
274
  const n = await e.execute();
22
- return Array.isArray(n) ? n.map((o) => this.convertNumericFields(o, t)) : n;
275
+ return Array.isArray(n) ? n.map((r) => this.convertNumericFields(r, t)) : n;
23
276
  }
24
277
  if (this.db && typeof this.db.execute == "function")
25
278
  try {
26
279
  const n = await this.db.execute(e);
27
- return Array.isArray(n) ? n.map((o) => this.convertNumericFields(o, t)) : n;
280
+ return Array.isArray(n) ? n.map((r) => this.convertNumericFields(r, t)) : n;
28
281
  } catch (n) {
29
282
  if (typeof e.getSQL == "function") {
30
- const o = e.getSQL(), a = await this.db.execute(o);
31
- return Array.isArray(a) ? a.map((r) => this.convertNumericFields(r, t)) : a;
283
+ const r = e.getSQL(), a = await this.db.execute(r);
284
+ return Array.isArray(a) ? a.map((i) => this.convertNumericFields(i, t)) : a;
32
285
  }
33
286
  throw n;
34
287
  }
35
288
  }
36
289
  if (!this.db.execute)
37
290
  throw new Error("PostgreSQL database instance must have an execute method");
38
- const i = await this.db.execute(e);
39
- return Array.isArray(i) ? i.map((n) => this.convertNumericFields(n, t)) : i;
291
+ const s = await this.db.execute(e);
292
+ return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
40
293
  }
41
294
  /**
42
295
  * Convert numeric string fields to numbers (only for measure fields)
43
296
  */
44
297
  convertNumericFields(e, t) {
45
298
  if (!e || typeof e != "object") return e;
46
- const i = {};
47
- for (const [n, o] of Object.entries(e))
48
- t && t.includes(n) ? i[n] = this.coerceToNumber(o) : i[n] = o;
49
- return i;
299
+ const s = {};
300
+ for (const [n, r] of Object.entries(e))
301
+ t && t.includes(n) ? s[n] = this.coerceToNumber(r) : s[n] = r;
302
+ return s;
50
303
  }
51
304
  /**
52
305
  * Coerce a value to a number if it represents a numeric type
53
306
  */
54
307
  coerceToNumber(e) {
55
- var t, i;
308
+ var t, s;
56
309
  if (e == null || typeof e == "number") return e;
57
310
  if (typeof e == "bigint") return Number(e);
58
311
  if (e && typeof e == "object") {
@@ -61,7 +314,7 @@ class X extends x {
61
314
  if (/^-?\d+(\.\d+)?$/.test(n))
62
315
  return n.includes(".") ? parseFloat(n) : parseInt(n, 10);
63
316
  }
64
- if (((t = e.constructor) == null ? void 0 : t.name) === "Numeric" || ((i = e.constructor) == null ? void 0 : i.name) === "Decimal" || "digits" in e || "sign" in e) {
317
+ if (((t = e.constructor) == null ? void 0 : t.name) === "Numeric" || ((s = e.constructor) == null ? void 0 : s.name) === "Decimal" || "digits" in e || "sign" in e) {
65
318
  const n = e.toString();
66
319
  return parseFloat(n);
67
320
  }
@@ -79,23 +332,23 @@ class X extends x {
79
332
  return "postgres";
80
333
  }
81
334
  }
82
- class q extends x {
335
+ class se extends S {
83
336
  async execute(e, t) {
84
337
  if (e && typeof e == "object" && typeof e.execute == "function") {
85
- const i = await e.execute();
86
- return Array.isArray(i) ? i.map((n) => this.convertNumericFields(n, t)) : i;
338
+ const s = await e.execute();
339
+ return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
87
340
  }
88
341
  try {
89
342
  if (this.db.all) {
90
- const i = this.db.all(e);
91
- return Array.isArray(i) ? i.map((n) => this.convertNumericFields(n, t)) : i;
343
+ const s = this.db.all(e);
344
+ return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
92
345
  } else {
93
346
  if (this.db.run)
94
347
  return this.db.run(e);
95
348
  throw new Error("SQLite database instance must have an all() or run() method");
96
349
  }
97
- } catch (i) {
98
- throw new Error(`SQLite execution failed: ${i instanceof Error ? i.message : "Unknown error"}`);
350
+ } catch (s) {
351
+ throw new Error(`SQLite execution failed: ${s instanceof Error ? s.message : "Unknown error"}`);
99
352
  }
100
353
  }
101
354
  /**
@@ -103,10 +356,10 @@ class q extends x {
103
356
  */
104
357
  convertNumericFields(e, t) {
105
358
  if (!e || typeof e != "object") return e;
106
- const i = {};
107
- for (const [n, o] of Object.entries(e))
108
- t && t.includes(n) ? i[n] = this.coerceToNumber(o) : i[n] = o;
109
- return i;
359
+ const s = {};
360
+ for (const [n, r] of Object.entries(e))
361
+ t && t.includes(n) ? s[n] = this.coerceToNumber(r) : s[n] = r;
362
+ return s;
110
363
  }
111
364
  /**
112
365
  * Coerce a value to a number if it represents a numeric type
@@ -125,26 +378,26 @@ class q extends x {
125
378
  return "sqlite";
126
379
  }
127
380
  }
128
- class ee extends x {
381
+ class ie extends S {
129
382
  async execute(e, t) {
130
383
  if (e && typeof e == "object" && typeof e.execute == "function") {
131
384
  const n = await e.execute();
132
- return Array.isArray(n) ? n.map((o) => this.convertNumericFields(o, t)) : n;
385
+ return Array.isArray(n) ? n.map((r) => this.convertNumericFields(r, t)) : n;
133
386
  }
134
387
  if (!this.db.execute)
135
388
  throw new Error("MySQL database instance must have an execute method");
136
- const i = await this.db.execute(e);
137
- return Array.isArray(i) ? i.map((n) => this.convertNumericFields(n, t)) : i;
389
+ const s = await this.db.execute(e);
390
+ return Array.isArray(s) ? s.map((n) => this.convertNumericFields(n, t)) : s;
138
391
  }
139
392
  /**
140
- * Convert numeric string fields to numbers (only for measure fields)
393
+ * Convert numeric string fields to numbers (measure fields + numeric dimensions)
141
394
  */
142
395
  convertNumericFields(e, t) {
143
396
  if (!e || typeof e != "object") return e;
144
- const i = {};
145
- for (const [n, o] of Object.entries(e))
146
- t && t.includes(n) ? i[n] = this.coerceToNumber(o) : i[n] = o;
147
- return i;
397
+ const s = {};
398
+ for (const [n, r] of Object.entries(e))
399
+ t && t.includes(n) ? s[n] = this.coerceToNumber(r) : s[n] = r;
400
+ return s;
148
401
  }
149
402
  /**
150
403
  * Coerce a value to a number if it represents a numeric type
@@ -163,66 +416,75 @@ class ee extends x {
163
416
  return "mysql";
164
417
  }
165
418
  }
166
- function S(s, e) {
167
- return new X(s, e);
419
+ function F(o, e) {
420
+ return new ne(o, e, "postgres");
168
421
  }
169
- function M(s, e) {
170
- return new q(s, e);
422
+ function M(o, e) {
423
+ return new se(o, e, "sqlite");
171
424
  }
172
- function te(s, e) {
173
- return new ee(s, e);
425
+ function re(o, e) {
426
+ return new ie(o, e, "mysql");
174
427
  }
175
- function _(s, e, t) {
428
+ function L(o, e, t) {
176
429
  if (t)
177
430
  switch (t) {
178
431
  case "postgres":
179
- return S(s, e);
432
+ return F(o, e);
180
433
  case "mysql":
181
- return te(s, e);
434
+ return re(o, e);
182
435
  case "sqlite":
183
- return M(s, e);
436
+ return M(o, e);
184
437
  }
185
- if (s.all && s.run)
186
- return M(s, e);
187
- if (s.execute)
188
- return S(s, e);
438
+ if (o.all && o.run)
439
+ return M(o, e);
440
+ if (o.execute)
441
+ return F(o, e);
189
442
  throw new Error("Unable to determine database engine type. Please specify engineType parameter.");
190
443
  }
191
- function Ne(s, e) {
444
+ function Ee(o, e) {
192
445
  return {
193
- name: s,
446
+ name: o,
194
447
  ...e
195
448
  };
196
449
  }
197
- function b(s, e) {
198
- return typeof s == "function" ? s(e) : s;
450
+ function b(o, e) {
451
+ return typeof o == "function" ? o(e) : o;
199
452
  }
200
- function ne(s, e, t) {
453
+ function oe(o, e, t) {
201
454
  return {
202
- ...s,
455
+ ...o,
203
456
  cubes: e,
204
457
  currentCube: t
205
458
  };
206
459
  }
207
- class ie {
460
+ class ae {
461
+ constructor(e) {
462
+ this.databaseAdapter = e;
463
+ }
464
+ /**
465
+ * Set the database adapter (for use when not provided in constructor)
466
+ */
467
+ setDatabaseAdapter(e) {
468
+ this.databaseAdapter = e;
469
+ }
208
470
  /**
209
471
  * Analyze a semantic query to determine which cubes are involved
210
472
  */
211
473
  analyzeCubeUsage(e) {
212
474
  const t = /* @__PURE__ */ new Set();
213
475
  if (e.measures)
214
- for (const i of e.measures) {
215
- const [n] = i.split(".");
476
+ for (const s of e.measures) {
477
+ const [n] = s.split(".");
216
478
  t.add(n);
217
479
  }
218
480
  if (e.dimensions)
219
- for (const i of e.dimensions) {
220
- const [n] = i.split(".");
481
+ for (const s of e.dimensions) {
482
+ const [n] = s.split(".");
221
483
  t.add(n);
222
484
  }
223
485
  if (e.timeDimensions)
224
- for (const i of e.timeDimensions) {
225
- const [n] = i.dimension.split(".");
486
+ for (const s of e.timeDimensions) {
487
+ const [n] = s.dimension.split(".");
226
488
  t.add(n);
227
489
  }
228
490
  return t;
@@ -230,20 +492,20 @@ class ie {
230
492
  /**
231
493
  * Build a multi-cube query plan
232
494
  */
233
- buildMultiCubeQueryPlan(e, t, i) {
234
- const n = this.analyzeCubeUsage(t), o = Array.from(n);
235
- if (o.length === 1)
495
+ buildMultiCubeQueryPlan(e, t, s) {
496
+ const n = this.analyzeCubeUsage(t), r = Array.from(n);
497
+ if (r.length === 1)
236
498
  throw new Error("Single cube query should use QueryExecutor directly");
237
- const a = this.choosePrimaryCube(o, t), r = e.get(a);
238
- if (!r)
499
+ const a = this.choosePrimaryCube(r, t), i = e.get(a);
500
+ if (!i)
239
501
  throw new Error(`Primary cube '${a}' not found`);
240
- const c = this.buildJoinPlan(e, r, o, i.securityContext), l = this.buildMultiCubeSelections(e, t, i.securityContext), u = this.buildMultiCubeWhereConditions(e, t, i), m = this.buildMultiCubeGroupByFields(e, t, i.securityContext);
502
+ const c = this.buildJoinPlan(e, i, r, s), u = this.buildMultiCubeSelections(e, t, s.securityContext), l = this.buildMultiCubeWhereConditions(e, t, s), d = this.buildMultiCubeGroupByFields(e, t, s.securityContext);
241
503
  return {
242
- primaryCube: r,
504
+ primaryCube: i,
243
505
  joinCubes: c,
244
- selections: l,
245
- whereConditions: u,
246
- groupByFields: m
506
+ selections: u,
507
+ whereConditions: l,
508
+ groupByFields: d
247
509
  };
248
510
  }
249
511
  /**
@@ -251,85 +513,79 @@ class ie {
251
513
  */
252
514
  choosePrimaryCube(e, t) {
253
515
  if (t.measures && t.measures.length > 0) {
254
- const [i] = t.measures[0].split(".");
255
- return i;
516
+ const [s] = t.measures[0].split(".");
517
+ return s;
256
518
  }
257
519
  if (t.dimensions && t.dimensions.length > 0) {
258
- const [i] = t.dimensions[0].split(".");
259
- return i;
520
+ const [s] = t.dimensions[0].split(".");
521
+ return s;
260
522
  }
261
523
  return e[0];
262
524
  }
263
525
  /**
264
526
  * Build join plan for multi-cube query
265
527
  */
266
- buildJoinPlan(e, t, i, n) {
267
- var r;
268
- const o = [], a = i.filter((c) => c !== t.name);
528
+ buildJoinPlan(e, t, s, n) {
529
+ var i;
530
+ const r = [], a = s.filter((c) => c !== t.name);
269
531
  for (const c of a) {
270
- const l = e.get(c);
271
- if (!l)
272
- throw new Error(`Cube '${c}' not found`);
273
- const u = (r = t.joins) == null ? void 0 : r[c];
532
+ const u = e.get(c);
274
533
  if (!u)
534
+ throw new Error(`Cube '${c}' not found`);
535
+ const l = (i = t.joins) == null ? void 0 : i[c];
536
+ if (!l)
275
537
  throw new Error(`No join definition found from '${t.name}' to '${c}'`);
276
- const m = ne(
277
- {
278
- db: {},
279
- // Will be filled in during execution
280
- schema: {},
281
- // Will be filled in during execution
282
- securityContext: n
283
- },
538
+ const d = oe(
539
+ n,
284
540
  e,
285
- l
286
- ), d = u.condition(m);
287
- o.push({
288
- cube: l,
541
+ u
542
+ ), f = l.condition(d);
543
+ r.push({
544
+ cube: u,
289
545
  alias: `${c.toLowerCase()}_cube`,
290
- joinType: u.type || "left",
291
- joinCondition: d
546
+ joinType: l.type || "left",
547
+ joinCondition: f
292
548
  });
293
549
  }
294
- return o;
550
+ return r;
295
551
  }
296
552
  /**
297
553
  * Build selections across multiple cubes
298
554
  */
299
- buildMultiCubeSelections(e, t, i) {
300
- const n = {}, o = {
555
+ buildMultiCubeSelections(e, t, s) {
556
+ const n = {}, r = {
301
557
  db: {},
302
558
  // Filled during execution
303
559
  schema: {},
304
560
  // Filled during execution
305
- securityContext: i
561
+ securityContext: s
306
562
  };
307
563
  if (t.dimensions)
308
564
  for (const a of t.dimensions) {
309
- const [r, c] = a.split("."), l = e.get(r);
310
- if (l && l.dimensions[c]) {
311
- const u = l.dimensions[c], m = b(u.sql, o);
312
- n[a] = f`${m}`.as(a);
565
+ const [i, c] = a.split("."), u = e.get(i);
566
+ if (u && u.dimensions[c]) {
567
+ const l = u.dimensions[c], d = b(l.sql, r);
568
+ n[a] = m`${d}`.as(a);
313
569
  }
314
570
  }
315
571
  if (t.measures)
316
572
  for (const a of t.measures) {
317
- const [r, c] = a.split("."), l = e.get(r);
318
- if (l && l.measures[c]) {
319
- const u = l.measures[c], m = this.buildMeasureExpression(u, o);
320
- n[a] = f`${m}`.as(a);
573
+ const [i, c] = a.split("."), u = e.get(i);
574
+ if (u && u.measures[c]) {
575
+ const l = u.measures[c], d = this.buildMeasureExpression(l, r);
576
+ n[a] = m`${d}`.as(a);
321
577
  }
322
578
  }
323
579
  if (t.timeDimensions)
324
580
  for (const a of t.timeDimensions) {
325
- const [r, c] = a.dimension.split("."), l = e.get(r);
326
- if (l && l.dimensions[c]) {
327
- const u = l.dimensions[c], m = this.buildTimeDimensionExpression(
328
- u.sql,
581
+ const [i, c] = a.dimension.split("."), u = e.get(i);
582
+ if (u && u.dimensions[c]) {
583
+ const l = u.dimensions[c], d = this.buildTimeDimensionExpression(
584
+ l.sql,
329
585
  a.granularity,
330
- o
586
+ r
331
587
  );
332
- n[a.dimension] = f`${m}`.as(a.dimension);
588
+ n[a.dimension] = m`${d}`.as(a.dimension);
333
589
  }
334
590
  }
335
591
  return n;
@@ -338,149 +594,272 @@ class ie {
338
594
  * Build measure expression with aggregation (similar to single-cube approach)
339
595
  */
340
596
  buildMeasureExpression(e, t) {
341
- let i = b(e.sql, t);
597
+ let s = b(e.sql, t);
342
598
  if (e.filters && e.filters.length > 0) {
343
- const n = e.filters.map((o) => o(t));
344
- i = f`CASE WHEN ${p(...n)} THEN ${i} END`;
599
+ const n = e.filters.map((r) => r(t));
600
+ s = m`CASE WHEN ${h(...n)} THEN ${s} END`;
345
601
  }
602
+ if (!this.databaseAdapter)
603
+ throw new Error("DatabaseAdapter is required for measure aggregation");
346
604
  switch (e.type) {
347
605
  case "count":
348
- return f`COUNT(${i})`;
606
+ return this.databaseAdapter.buildCount(s);
349
607
  case "countDistinct":
350
- return f`COUNT(DISTINCT ${i})`;
608
+ return this.databaseAdapter.buildCountDistinct(s);
351
609
  case "sum":
352
- return f`SUM(${i})`;
610
+ return this.databaseAdapter.buildSum(s);
353
611
  case "avg":
354
- return f`AVG(${i})`;
612
+ return this.databaseAdapter.buildAvg(s);
355
613
  case "min":
356
- return f`MIN(${i})`;
614
+ return this.databaseAdapter.buildMin(s);
357
615
  case "max":
358
- return f`MAX(${i})`;
616
+ return this.databaseAdapter.buildMax(s);
359
617
  case "number":
360
- return i;
618
+ return s;
361
619
  default:
362
- return f`COUNT(${i})`;
620
+ return this.databaseAdapter.buildCount(s);
363
621
  }
364
622
  }
365
623
  /**
366
624
  * Build time dimension expression (similar to single-cube approach)
367
625
  */
368
- buildTimeDimensionExpression(e, t, i) {
369
- const n = b(e, i);
626
+ buildTimeDimensionExpression(e, t, s) {
627
+ const n = b(e, s);
370
628
  if (!t)
371
629
  return n;
372
- switch (t) {
373
- case "year":
374
- return f`DATE_TRUNC('year', ${n}::timestamp)`;
375
- case "quarter":
376
- return f`DATE_TRUNC('quarter', ${n}::timestamp)`;
377
- case "month":
378
- return f`DATE_TRUNC('month', ${n}::timestamp)`;
379
- case "week":
380
- return f`DATE_TRUNC('week', ${n}::timestamp)`;
381
- case "day":
382
- return f`DATE_TRUNC('day', ${n}::timestamp)`;
383
- case "hour":
384
- return f`DATE_TRUNC('hour', ${n}::timestamp)`;
385
- case "minute":
386
- return f`DATE_TRUNC('minute', ${n}::timestamp)`;
387
- case "second":
388
- return f`DATE_TRUNC('second', ${n}::timestamp)`;
389
- default:
390
- return n;
391
- }
630
+ if (!this.databaseAdapter)
631
+ throw new Error("DatabaseAdapter is required for time dimension building");
632
+ return this.databaseAdapter.buildTimeDimension(t, n);
392
633
  }
393
634
  /**
394
635
  * Build WHERE conditions for multi-cube query
395
636
  */
396
- buildMultiCubeWhereConditions(e, t, i) {
637
+ buildMultiCubeWhereConditions(e, t, s) {
397
638
  const n = [];
398
- if (t.filters) {
399
- for (const o of t.filters)
400
- if ("member" in o) {
401
- const [a] = o.member.split("."), r = e.get(a);
402
- if (r) {
403
- const c = this.buildFilterCondition(o, r, i);
404
- c && n.push(c);
639
+ if (t.filters)
640
+ for (const r of t.filters) {
641
+ const a = this.processMultiCubeFilter(r, e, s);
642
+ a && n.push(a);
643
+ }
644
+ if (t.timeDimensions) {
645
+ for (const r of t.timeDimensions)
646
+ if (r.dateRange) {
647
+ const [a, i] = r.dimension.split("."), c = e.get(a);
648
+ if (c && c.dimensions[i]) {
649
+ const u = c.dimensions[i], l = b(u.sql, s), d = this.buildDateRangeCondition(l, r.dateRange);
650
+ d && n.push(d);
405
651
  }
406
652
  }
407
653
  }
408
654
  return n;
409
655
  }
410
656
  /**
411
- * Filter condition builder (would reuse logic from DrizzleExecutor)
657
+ * Process a single filter for multi-cube queries (handles logical and simple filters)
412
658
  */
413
- buildFilterCondition(e, t, i) {
414
- if (e.operator === "equals" && e.values && e.values.length > 0) {
415
- const [n, o] = e.member.split(".");
416
- if (n === t.name) {
417
- const a = t.dimensions[o] || t.measures[o];
418
- if (a) {
419
- const r = typeof a.sql == "function" ? a.sql(i) : a.sql;
420
- return v(r, e.values[0]);
659
+ processMultiCubeFilter(e, t, s) {
660
+ if ("and" in e || "or" in e) {
661
+ if (e.and) {
662
+ const n = e.and.map((r) => this.processMultiCubeFilter(r, t, s)).filter((r) => r !== null);
663
+ return n.length > 0 ? h(...n) : null;
664
+ }
665
+ if (e.or) {
666
+ const n = e.or.map((r) => this.processMultiCubeFilter(r, t, s)).filter((r) => r !== null);
667
+ return n.length > 0 ? j(...n) : null;
668
+ }
669
+ }
670
+ if ("member" in e) {
671
+ const [n] = e.member.split("."), r = t.get(n);
672
+ if (r)
673
+ return this.buildFilterCondition(e, r, s);
674
+ }
675
+ return null;
676
+ }
677
+ /**
678
+ * Filter condition builder with comprehensive operator support
679
+ */
680
+ buildFilterCondition(e, t, s) {
681
+ if (!e.member || !e.operator)
682
+ return null;
683
+ const [n, r] = e.member.split(".");
684
+ if (n !== t.name)
685
+ return null;
686
+ const a = t.dimensions[r] || t.measures[r];
687
+ if (!a)
688
+ return null;
689
+ const i = b(a.sql, s), u = (e.values || []).filter((d) => d != null);
690
+ if (u.length === 0 && !["set", "notSet"].includes(e.operator))
691
+ return null;
692
+ const l = u[0];
693
+ switch (e.operator) {
694
+ case "equals":
695
+ if (u.length === 0)
696
+ return m`1 = 0`;
697
+ if (u.length === 1) {
698
+ const d = a.type === "time" && this.normalizeDate(l) || l;
699
+ return v(i, d);
700
+ } else if (a.type === "time") {
701
+ const d = u.map((f) => this.normalizeDate(f) || f);
702
+ return m`${i} IN (${m.join(d.map((f) => m`${f}`), m`, `)})`;
703
+ } else
704
+ return m`${i} IN (${m.join(u.map((d) => m`${d}`), m`, `)})`;
705
+ case "notEquals":
706
+ return u.length === 1 ? m`${i} <> ${l}` : u.length > 1 ? m`${i} NOT IN (${m.join(u.map((d) => m`${d}`), m`, `)})` : null;
707
+ case "contains":
708
+ if (!this.databaseAdapter)
709
+ throw new Error("DatabaseAdapter is required for string conditions");
710
+ return this.databaseAdapter.buildStringCondition(i, "contains", l);
711
+ case "notContains":
712
+ if (!this.databaseAdapter)
713
+ throw new Error("DatabaseAdapter is required for string conditions");
714
+ return this.databaseAdapter.buildStringCondition(i, "notContains", l);
715
+ case "startsWith":
716
+ if (!this.databaseAdapter)
717
+ throw new Error("DatabaseAdapter is required for string conditions");
718
+ return this.databaseAdapter.buildStringCondition(i, "startsWith", l);
719
+ case "endsWith":
720
+ if (!this.databaseAdapter)
721
+ throw new Error("DatabaseAdapter is required for string conditions");
722
+ return this.databaseAdapter.buildStringCondition(i, "endsWith", l);
723
+ case "gt":
724
+ return N(i, l);
725
+ case "gte":
726
+ return w(i, l);
727
+ case "lt":
728
+ return $(i, l);
729
+ case "lte":
730
+ return D(i, l);
731
+ case "set":
732
+ return z(i);
733
+ case "notSet":
734
+ return _(i);
735
+ case "inDateRange":
736
+ if (u.length >= 2) {
737
+ const d = this.normalizeDate(u[0]), f = this.normalizeDate(u[1]);
738
+ if (d && f)
739
+ return h(
740
+ w(i, d),
741
+ D(i, f)
742
+ );
421
743
  }
744
+ return null;
745
+ case "beforeDate": {
746
+ const d = this.normalizeDate(l);
747
+ return d ? $(i, d) : null;
422
748
  }
749
+ case "afterDate": {
750
+ const d = this.normalizeDate(l);
751
+ return d ? N(i, d) : null;
752
+ }
753
+ default:
754
+ return null;
755
+ }
756
+ }
757
+ /**
758
+ * Build date range condition for time dimensions
759
+ */
760
+ buildDateRangeCondition(e, t) {
761
+ if (!t) return null;
762
+ if (Array.isArray(t) && t.length >= 2) {
763
+ const s = this.normalizeDate(t[0]), n = this.normalizeDate(t[1]);
764
+ return !s || !n ? null : h(
765
+ w(e, s),
766
+ D(e, n)
767
+ );
768
+ }
769
+ if (typeof t == "string") {
770
+ const s = this.normalizeDate(t);
771
+ if (!s) return null;
772
+ const n = new Date(s);
773
+ n.setUTCHours(0, 0, 0, 0);
774
+ const r = new Date(s);
775
+ return r.setUTCHours(23, 59, 59, 999), h(
776
+ w(e, n),
777
+ D(e, r)
778
+ );
779
+ }
780
+ return null;
781
+ }
782
+ /**
783
+ * Normalize date values to handle both string and Date objects
784
+ * For PostgreSQL timestamp fields, Drizzle expects Date objects
785
+ */
786
+ normalizeDate(e) {
787
+ if (!e) return null;
788
+ if (e instanceof Date)
789
+ return isNaN(e.getTime()) ? null : e;
790
+ if (typeof e == "string") {
791
+ const t = new Date(e);
792
+ return isNaN(t.getTime()) ? null : t;
793
+ }
794
+ try {
795
+ const t = new Date(e);
796
+ if (!isNaN(t.getTime()))
797
+ return t;
798
+ } catch {
423
799
  }
424
800
  return null;
425
801
  }
426
802
  /**
427
803
  * Build GROUP BY fields for multi-cube query
428
804
  */
429
- buildMultiCubeGroupByFields(e, t, i) {
805
+ buildMultiCubeGroupByFields(e, t, s) {
430
806
  const n = [];
431
807
  if (!(t.measures && t.measures.length > 0))
432
808
  return [];
433
809
  const a = {
434
810
  db: {},
435
811
  schema: {},
436
- securityContext: i
812
+ securityContext: s
437
813
  };
438
814
  if (t.dimensions)
439
- for (const r of t.dimensions) {
440
- const [c, l] = r.split("."), u = e.get(c);
441
- if (u && u.dimensions[l]) {
442
- const m = u.dimensions[l], d = b(m.sql, a);
443
- n.push(d);
815
+ for (const i of t.dimensions) {
816
+ const [c, u] = i.split("."), l = e.get(c);
817
+ if (l && l.dimensions[u]) {
818
+ const d = l.dimensions[u], f = b(d.sql, a);
819
+ n.push(f);
444
820
  }
445
821
  }
446
822
  if (t.timeDimensions)
447
- for (const r of t.timeDimensions) {
448
- const [c, l] = r.dimension.split("."), u = e.get(c);
449
- if (u && u.dimensions[l]) {
450
- const m = u.dimensions[l], d = this.buildTimeDimensionExpression(
451
- m.sql,
452
- r.granularity,
823
+ for (const i of t.timeDimensions) {
824
+ const [c, u] = i.dimension.split("."), l = e.get(c);
825
+ if (l && l.dimensions[u]) {
826
+ const d = l.dimensions[u], f = this.buildTimeDimensionExpression(
827
+ d.sql,
828
+ i.granularity,
453
829
  a
454
830
  );
455
- n.push(d);
831
+ n.push(f);
456
832
  }
457
833
  }
458
834
  return n;
459
835
  }
460
836
  }
461
- class $ {
837
+ class T {
462
838
  constructor(e) {
463
839
  C(this, "multiCubeBuilder");
464
- this.dbExecutor = e, this.multiCubeBuilder = new ie();
840
+ C(this, "databaseAdapter");
841
+ if (this.dbExecutor = e, this.databaseAdapter = e.databaseAdapter, !this.databaseAdapter)
842
+ throw new Error("DatabaseExecutor must have a databaseAdapter property");
843
+ this.multiCubeBuilder = new ae(this.databaseAdapter);
465
844
  }
466
845
  /**
467
846
  * Unified query execution method that handles both single and multi-cube queries
468
847
  */
469
- async execute(e, t, i) {
848
+ async execute(e, t, s) {
470
849
  try {
471
- const n = j(e, t);
850
+ const n = Q(e, t);
472
851
  if (!n.isValid)
473
852
  throw new Error(`Query validation failed: ${n.errors.join(", ")}`);
474
- const o = this.multiCubeBuilder.analyzeCubeUsage(t);
475
- if (o.size === 0)
853
+ const r = this.multiCubeBuilder.analyzeCubeUsage(t);
854
+ if (r.size === 0)
476
855
  throw new Error("No cubes found for query");
477
- if (o.size === 1) {
478
- const a = Array.from(o)[0], r = e.get(a);
479
- if (!r)
856
+ if (r.size === 1) {
857
+ const a = Array.from(r)[0], i = e.get(a);
858
+ if (!i)
480
859
  throw new Error(`Cube '${a}' not found`);
481
- return this.executeSingleCube(r, t, i);
860
+ return this.executeSingleCube(i, t, s);
482
861
  } else
483
- return this.executeMultiCube(e, t, i);
862
+ return this.executeMultiCube(e, t, s);
484
863
  } catch (n) {
485
864
  throw new Error(`Query execution failed: ${n instanceof Error ? n.message : "Unknown error"}`);
486
865
  }
@@ -488,76 +867,67 @@ class $ {
488
867
  /**
489
868
  * Legacy interface for single cube queries
490
869
  */
491
- async executeQuery(e, t, i) {
870
+ async executeQuery(e, t, s) {
492
871
  const n = /* @__PURE__ */ new Map();
493
- return n.set(e.name, e), this.execute(n, t, i);
872
+ return n.set(e.name, e), this.execute(n, t, s);
494
873
  }
495
874
  /**
496
875
  * Execute a single cube query
497
876
  */
498
- async executeSingleCube(e, t, i) {
499
- return this.executeCube(e, t, i);
877
+ async executeSingleCube(e, t, s) {
878
+ return this.executeCube(e, t, s);
500
879
  }
501
880
  /**
502
881
  * Execute a Cube query (dynamic query building)
503
882
  */
504
- async executeCube(e, t, i) {
883
+ async executeCube(e, t, s) {
505
884
  try {
506
885
  const n = {
507
886
  db: this.dbExecutor.db,
508
887
  schema: this.dbExecutor.schema,
509
- securityContext: i
510
- }, o = e.sql(n), a = this.buildSelections(e, t, n);
511
- let r = n.db.select(a).from(o.from);
512
- if (o.joins)
513
- for (const h of o.joins)
514
- switch (h.type || "left") {
888
+ securityContext: s
889
+ }, r = e.sql(n), a = this.buildSelections(e, t, n);
890
+ let i = n.db.select(a).from(r.from);
891
+ if (r.joins)
892
+ for (const p of r.joins)
893
+ switch (p.type || "left") {
515
894
  case "left":
516
- r = r.leftJoin(h.table, h.on);
895
+ i = i.leftJoin(p.table, p.on);
517
896
  break;
518
897
  case "inner":
519
- r = r.innerJoin(h.table, h.on);
898
+ i = i.innerJoin(p.table, p.on);
520
899
  break;
521
900
  case "right":
522
- r = r.rightJoin(h.table, h.on);
901
+ i = i.rightJoin(p.table, p.on);
523
902
  break;
524
903
  case "full":
525
- r = r.fullJoin(h.table, h.on);
904
+ i = i.fullJoin(p.table, p.on);
526
905
  break;
527
906
  }
528
- o.where && (r = r.where(o.where));
907
+ r.where && (i = i.where(r.where));
529
908
  const c = this.buildWhereConditions(e, t, n);
530
909
  if (c.length > 0) {
531
- const h = c.length === 1 ? c[0] : p(...c);
532
- r = r.where(h);
910
+ const p = c.length === 1 ? c[0] : h(...c);
911
+ i = i.where(p);
533
912
  }
534
- const l = this.buildGroupByFields(e, t, n);
535
- l.length > 0 && (r = r.groupBy(...l));
536
- const u = this.buildOrderBy(t);
537
- if (u.length > 0 && (r = r.orderBy(...u)), t.limit !== void 0) {
538
- if (t.limit < 0)
539
- throw new Error("Limit must be non-negative");
540
- r = r.limit(t.limit);
541
- }
542
- if (t.offset !== void 0) {
543
- if (t.offset < 0)
544
- throw new Error("Offset must be non-negative");
545
- r = r.offset(t.offset);
546
- }
547
- const m = t.measures || [], d = await this.dbExecutor.execute(r, m), Q = Array.isArray(d) ? d.map((h) => {
548
- const E = { ...h };
913
+ const u = this.buildGroupByFields(e, t, n);
914
+ u.length > 0 && (i = i.groupBy(...u));
915
+ const l = this.buildOrderBy(t);
916
+ l.length > 0 && (i = i.orderBy(...l)), i = this.applyLimitAndOffset(i, t);
917
+ const d = this.collectNumericFields(e, t), f = await this.dbExecutor.execute(i, d), I = Array.isArray(f) ? f.map((p) => {
918
+ const A = { ...p };
549
919
  if (t.timeDimensions) {
550
- for (const D of t.timeDimensions)
551
- if (D.dimension in E) {
552
- let g = E[D.dimension];
553
- typeof g == "string" && g.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/) && (g = g.replace(" ", "T"), !g.endsWith("Z") && !g.includes("+") && (g = g + "Z")), E[D.dimension] = g;
920
+ for (const E of t.timeDimensions)
921
+ if (E.dimension in A) {
922
+ let g = A[E.dimension];
923
+ typeof g == "string" && g.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/) && (g = g.replace(" ", "T"), !g.endsWith("Z") && !g.includes("+") && (g = g + "Z")), A[E.dimension] = g;
554
924
  }
555
925
  }
556
- return E;
557
- }) : [d], k = this.generateAnnotations(e, t);
926
+ return A;
927
+ }) : [f], U = this.generateAnnotations(e, t);
558
928
  return {
559
- data: Q,
560
- annotation: k
929
+ data: I,
930
+ annotation: U
561
931
  };
562
932
  } catch (n) {
563
933
  throw new Error(`Cube query execution failed: ${n instanceof Error ? n.message : "Unknown error"}`);
@@ -566,184 +936,224 @@ class $ {
566
936
  /**
567
937
  * Execute multi-cube query using JOIN resolution
568
938
  */
569
- async executeMultiCube(e, t, i) {
570
- const n = this.buildMultiCubeQuery(e, t, i), o = t.measures || [], a = await this.dbExecutor.execute(n, o), r = {
939
+ async executeMultiCube(e, t, s) {
940
+ const n = this.buildMultiCubeQuery(e, t, s), r = this.collectNumericFieldsMultiCube(e, t), a = await this.dbExecutor.execute(n, r), i = {
571
941
  db: this.dbExecutor.db,
572
942
  schema: this.dbExecutor.schema,
573
- securityContext: i
574
- }, c = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, r), l = this.generateMultiCubeAnnotations(c, t);
943
+ securityContext: s
944
+ }, c = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, i), u = this.generateMultiCubeAnnotations(c, t);
575
945
  return {
576
946
  data: Array.isArray(a) ? a : [a],
577
- annotation: l
947
+ annotation: u
578
948
  };
579
949
  }
580
950
  /**
581
951
  * Generate raw SQL for debugging (without execution)
582
952
  */
583
- async generateSQL(e, t, i) {
584
- return this.generateCubeSQL(e, t, i);
953
+ async generateSQL(e, t, s) {
954
+ return this.generateCubeSQL(e, t, s);
585
955
  }
586
956
  /**
587
957
  * Generate raw SQL for multi-cube queries without execution
588
958
  */
589
- async generateMultiCubeSQL(e, t, i) {
590
- const o = this.buildMultiCubeQuery(e, t, i).toSQL();
959
+ async generateMultiCubeSQL(e, t, s) {
960
+ const r = this.buildMultiCubeQuery(e, t, s).toSQL();
591
961
  return {
592
- sql: o.sql,
593
- params: o.params
962
+ sql: r.sql,
963
+ params: r.params
594
964
  };
595
965
  }
596
966
  /**
597
967
  * Build multi-cube query (extracted from executeMultiCube for reuse)
598
968
  */
599
- buildMultiCubeQuery(e, t, i) {
969
+ buildMultiCubeQuery(e, t, s) {
600
970
  const n = {
601
971
  db: this.dbExecutor.db,
602
972
  schema: this.dbExecutor.schema,
603
- securityContext: i
604
- }, o = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, n), a = o.primaryCube.sql(n);
605
- let r = n.db.select(o.selections).from(a.from);
973
+ securityContext: s
974
+ }, r = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, n), a = r.primaryCube.sql(n);
975
+ let i = n.db.select(r.selections).from(a.from);
606
976
  if (a.joins)
607
- for (const u of a.joins)
608
- switch (u.type || "left") {
977
+ for (const l of a.joins)
978
+ switch (l.type || "left") {
609
979
  case "left":
610
- r = r.leftJoin(u.table, u.on);
980
+ i = i.leftJoin(l.table, l.on);
611
981
  break;
612
982
  case "inner":
613
- r = r.innerJoin(u.table, u.on);
983
+ i = i.innerJoin(l.table, l.on);
614
984
  break;
615
985
  case "right":
616
- r = r.rightJoin(u.table, u.on);
986
+ i = i.rightJoin(l.table, l.on);
617
987
  break;
618
988
  case "full":
619
- r = r.fullJoin(u.table, u.on);
989
+ i = i.fullJoin(l.table, l.on);
620
990
  break;
621
991
  default:
622
- r = r.leftJoin(u.table, u.on);
992
+ i = i.leftJoin(l.table, l.on);
623
993
  }
624
- if (o.joinCubes && o.joinCubes.length > 0)
625
- for (const u of o.joinCubes) {
626
- const m = u.cube.sql(n);
994
+ if (r.joinCubes && r.joinCubes.length > 0)
995
+ for (const l of r.joinCubes) {
996
+ const d = l.cube.sql(n);
627
997
  try {
628
- switch (u.joinType || "left") {
998
+ switch (l.joinType || "left") {
629
999
  case "left":
630
- r = r.leftJoin(m.from, u.joinCondition);
1000
+ i = i.leftJoin(d.from, l.joinCondition);
631
1001
  break;
632
1002
  case "inner":
633
- r = r.innerJoin(m.from, u.joinCondition);
1003
+ i = i.innerJoin(d.from, l.joinCondition);
634
1004
  break;
635
1005
  case "right":
636
- r = r.rightJoin(m.from, u.joinCondition);
1006
+ i = i.rightJoin(d.from, l.joinCondition);
637
1007
  break;
638
1008
  case "full":
639
- r = r.fullJoin(m.from, u.joinCondition);
1009
+ i = i.fullJoin(d.from, l.joinCondition);
640
1010
  break;
641
1011
  }
642
- } catch (d) {
643
- console.warn(`Multi-cube join failed for ${u.cube.name}: ${d instanceof Error ? d.message : "Unknown error"}`);
1012
+ } catch (f) {
1013
+ console.warn(`Multi-cube join failed for ${l.cube.name}: ${f instanceof Error ? f.message : "Unknown error"}`);
644
1014
  }
645
1015
  }
646
1016
  const c = [];
647
- if (a.where && c.push(a.where), o.whereConditions.length > 0 && c.push(...o.whereConditions), c.length > 0) {
648
- const u = c.length === 1 ? c[0] : p(...c);
649
- r = r.where(u);
1017
+ if (a.where && c.push(a.where), r.whereConditions.length > 0 && c.push(...r.whereConditions), c.length > 0) {
1018
+ const l = c.length === 1 ? c[0] : h(...c);
1019
+ i = i.where(l);
650
1020
  }
651
- o.groupByFields.length > 0 && (r = r.groupBy(...o.groupByFields));
652
- const l = this.buildOrderBy(t);
653
- if (l.length > 0 && (r = r.orderBy(...l)), t.limit !== void 0) {
654
- if (t.limit < 0)
1021
+ r.groupByFields.length > 0 && (i = i.groupBy(...r.groupByFields));
1022
+ const u = this.buildOrderBy(t);
1023
+ return u.length > 0 && (i = i.orderBy(...u)), i = this.applyLimitAndOffset(i, t), i;
1024
+ }
1025
+ /**
1026
+ * Collect numeric field names (measures + numeric dimensions) for type conversion
1027
+ */
1028
+ collectNumericFields(e, t) {
1029
+ const s = [];
1030
+ if (t.measures && s.push(...t.measures), t.dimensions)
1031
+ for (const n of t.dimensions) {
1032
+ const r = n.includes(".") ? n.split(".")[1] : n, a = e.dimensions[r];
1033
+ a && a.type === "number" && s.push(n);
1034
+ }
1035
+ return s;
1036
+ }
1037
+ /**
1038
+ * Collect numeric field names for multi-cube queries
1039
+ */
1040
+ collectNumericFieldsMultiCube(e, t) {
1041
+ const s = [];
1042
+ if (t.measures && s.push(...t.measures), t.dimensions)
1043
+ for (const n of t.dimensions) {
1044
+ const r = n.includes(".") ? n.split(".")[1] : n;
1045
+ for (const a of e.values()) {
1046
+ const i = a.dimensions[r];
1047
+ if (i && i.type === "number") {
1048
+ s.push(n);
1049
+ break;
1050
+ }
1051
+ }
1052
+ }
1053
+ return s;
1054
+ }
1055
+ /**
1056
+ * Apply LIMIT and OFFSET to a query with validation
1057
+ * If offset is provided without limit, add a reasonable default limit
1058
+ */
1059
+ applyLimitAndOffset(e, t) {
1060
+ let s = t.limit;
1061
+ t.offset !== void 0 && t.offset > 0 && s === void 0 && (s = 50);
1062
+ let n = e;
1063
+ if (s !== void 0) {
1064
+ if (s < 0)
655
1065
  throw new Error("Limit must be non-negative");
656
- r = r.limit(t.limit);
1066
+ n = n.limit(s);
657
1067
  }
658
1068
  if (t.offset !== void 0) {
659
1069
  if (t.offset < 0)
660
1070
  throw new Error("Offset must be non-negative");
661
- r = r.offset(t.offset);
1071
+ n = n.offset(t.offset);
662
1072
  }
663
- return r;
1073
+ return n;
664
1074
  }
665
1075
  /**
666
1076
  * Generate SQL for Cube
667
1077
  */
668
- async generateCubeSQL(e, t, i) {
1078
+ async generateCubeSQL(e, t, s) {
669
1079
  const n = {
670
1080
  db: this.dbExecutor.db,
671
1081
  schema: this.dbExecutor.schema,
672
- securityContext: i
673
- }, o = e.sql(n), a = this.buildSelections(e, t, n);
674
- let r = n.db.select(a).from(o.from);
675
- if (o.joins)
676
- for (const d of o.joins)
677
- switch (d.type || "left") {
1082
+ securityContext: s
1083
+ }, r = e.sql(n), a = this.buildSelections(e, t, n);
1084
+ let i = n.db.select(a).from(r.from);
1085
+ if (r.joins)
1086
+ for (const f of r.joins)
1087
+ switch (f.type || "left") {
678
1088
  case "left":
679
- r = r.leftJoin(d.table, d.on);
1089
+ i = i.leftJoin(f.table, f.on);
680
1090
  break;
681
1091
  case "inner":
682
- r = r.innerJoin(d.table, d.on);
1092
+ i = i.innerJoin(f.table, f.on);
683
1093
  break;
684
1094
  case "right":
685
- r = r.rightJoin(d.table, d.on);
1095
+ i = i.rightJoin(f.table, f.on);
686
1096
  break;
687
1097
  case "full":
688
- r = r.fullJoin(d.table, d.on);
1098
+ i = i.fullJoin(f.table, f.on);
689
1099
  break;
690
1100
  }
691
- o.where && (r = r.where(o.where));
1101
+ r.where && (i = i.where(r.where));
692
1102
  const c = this.buildWhereConditions(e, t, n);
693
1103
  if (c.length > 0) {
694
- const d = c.length === 1 ? c[0] : p(...c);
695
- r = r.where(d);
1104
+ const f = c.length === 1 ? c[0] : h(...c);
1105
+ i = i.where(f);
696
1106
  }
697
- const l = this.buildGroupByFields(e, t, n);
698
- l.length > 0 && (r = r.groupBy(...l));
699
- const u = this.buildOrderBy(t);
700
- if (u.length > 0 && (r = r.orderBy(...u)), t.limit !== void 0) {
1107
+ const u = this.buildGroupByFields(e, t, n);
1108
+ u.length > 0 && (i = i.groupBy(...u));
1109
+ const l = this.buildOrderBy(t);
1110
+ if (l.length > 0 && (i = i.orderBy(...l)), t.limit !== void 0) {
701
1111
  if (t.limit < 0)
702
1112
  throw new Error("Limit must be non-negative");
703
- r = r.limit(t.limit);
1113
+ i = i.limit(t.limit);
704
1114
  }
705
1115
  if (t.offset !== void 0) {
706
1116
  if (t.offset < 0)
707
1117
  throw new Error("Offset must be non-negative");
708
- r = r.offset(t.offset);
1118
+ i = i.offset(t.offset);
709
1119
  }
710
- const m = r.toSQL();
1120
+ const d = i.toSQL();
711
1121
  return {
712
- sql: m.sql,
713
- params: m.params
1122
+ sql: d.sql,
1123
+ params: d.params
714
1124
  };
715
1125
  }
716
1126
  /**
717
1127
  * Build dynamic selections for Cube measures and dimensions
718
1128
  */
719
- buildSelections(e, t, i) {
1129
+ buildSelections(e, t, s) {
720
1130
  const n = {};
721
1131
  if (t.dimensions)
722
- for (const o of t.dimensions) {
723
- const [a, r] = o.split(".");
724
- if (a === e.name && e.dimensions[r]) {
725
- const c = e.dimensions[r], l = b(c.sql, i);
726
- n[o] = f`${l}`.as(o);
1132
+ for (const r of t.dimensions) {
1133
+ const [a, i] = r.split(".");
1134
+ if (a === e.name && e.dimensions[i]) {
1135
+ const c = e.dimensions[i], u = b(c.sql, s);
1136
+ n[r] = m`${u}`.as(r);
727
1137
  }
728
1138
  }
729
1139
  if (t.measures)
730
- for (const o of t.measures) {
731
- const [a, r] = o.split(".");
732
- if (a === e.name && e.measures[r]) {
733
- const c = e.measures[r], l = this.buildMeasureExpression(c, i);
734
- n[o] = f`${l}`.as(o);
1140
+ for (const r of t.measures) {
1141
+ const [a, i] = r.split(".");
1142
+ if (a === e.name && e.measures[i]) {
1143
+ const c = e.measures[i], u = this.buildMeasureExpression(c, s);
1144
+ n[r] = m`${u}`.as(r);
735
1145
  }
736
1146
  }
737
1147
  if (t.timeDimensions)
738
- for (const o of t.timeDimensions) {
739
- const [a, r] = o.dimension.split(".");
740
- if (a === e.name && e.dimensions[r]) {
741
- const c = e.dimensions[r], l = this.buildTimeDimensionExpression(
1148
+ for (const r of t.timeDimensions) {
1149
+ const [a, i] = r.dimension.split(".");
1150
+ if (a === e.name && e.dimensions[i]) {
1151
+ const c = e.dimensions[i], u = this.buildTimeDimensionExpression(
742
1152
  c.sql,
743
- o.granularity,
744
- i
1153
+ r.granularity,
1154
+ s
745
1155
  );
746
- n[o.dimension] = f`${l}`.as(o.dimension);
1156
+ n[r.dimension] = m`${u}`.as(r.dimension);
747
1157
  }
748
1158
  }
749
1159
  return Object.keys(n).length === 0 && (n.count = y()), n;
@@ -752,74 +1162,53 @@ class $ {
752
1162
  * Build measure expression with aggregation and filters for Cube
753
1163
  */
754
1164
  buildMeasureExpression(e, t) {
755
- let i = b(e.sql, t);
1165
+ let s = b(e.sql, t);
756
1166
  if (e.filters && e.filters.length > 0) {
757
- const n = e.filters.map((o) => o(t));
758
- i = f`CASE WHEN ${p(...n)} THEN ${i} END`;
1167
+ const n = e.filters.map((r) => r(t));
1168
+ s = m`CASE WHEN ${h(...n)} THEN ${s} END`;
759
1169
  }
760
1170
  switch (e.type) {
761
1171
  case "count":
762
- return y(i);
1172
+ return y(s);
763
1173
  case "countDistinct":
764
- return Y(i);
1174
+ return H(s);
765
1175
  case "sum":
766
- return I(i);
1176
+ return J(s);
767
1177
  case "avg":
768
- return R(i);
1178
+ return K(s);
769
1179
  case "min":
770
- return O(i);
1180
+ return R(s);
771
1181
  case "max":
772
- return B(i);
1182
+ return Y(s);
773
1183
  case "number":
774
- return i;
1184
+ return s;
775
1185
  default:
776
- return y(i);
1186
+ return y(s);
777
1187
  }
778
1188
  }
779
1189
  /**
780
- * Build time dimension expression with granularity
1190
+ * Build time dimension expression with granularity using database adapter
781
1191
  */
782
- buildTimeDimensionExpression(e, t, i) {
783
- const n = b(e, i);
784
- if (!t)
785
- return f`${n}`;
786
- switch (t) {
787
- case "year":
788
- return f`DATE_TRUNC('year', ${n}::timestamp)`;
789
- case "quarter":
790
- return f`DATE_TRUNC('quarter', ${n}::timestamp)`;
791
- case "month":
792
- return f`DATE_TRUNC('month', ${n}::timestamp)`;
793
- case "week":
794
- return f`DATE_TRUNC('week', ${n}::timestamp)`;
795
- case "day":
796
- return f`DATE_TRUNC('day', ${n}::timestamp)::timestamp`;
797
- case "hour":
798
- return f`DATE_TRUNC('hour', ${n}::timestamp)`;
799
- case "minute":
800
- return f`DATE_TRUNC('minute', ${n}::timestamp)`;
801
- case "second":
802
- return f`DATE_TRUNC('second', ${n}::timestamp)`;
803
- default:
804
- return n;
805
- }
1192
+ buildTimeDimensionExpression(e, t, s) {
1193
+ const n = b(e, s);
1194
+ return t ? this.databaseAdapter.buildTimeDimension(t, n) : m`${n}`;
806
1195
  }
807
1196
  /**
808
1197
  * Build WHERE conditions from semantic query filters (Cube)
809
1198
  */
810
- buildWhereConditions(e, t, i) {
1199
+ buildWhereConditions(e, t, s) {
811
1200
  const n = [];
812
1201
  if (t.filters && t.filters.length > 0)
813
- for (const o of t.filters) {
814
- const a = this.processFilter(o, e, i);
1202
+ for (const r of t.filters) {
1203
+ const a = this.processFilter(r, e, s);
815
1204
  a && n.push(a);
816
1205
  }
817
1206
  if (t.timeDimensions)
818
- for (const o of t.timeDimensions) {
819
- const [a, r] = o.dimension.split(".");
820
- if (a === e.name && e.dimensions[r] && o.dateRange) {
821
- const c = e.dimensions[r], l = b(c.sql, i), u = this.buildDateRangeCondition(l, o.dateRange);
822
- u && n.push(u);
1207
+ for (const r of t.timeDimensions) {
1208
+ const [a, i] = r.dimension.split(".");
1209
+ if (a === e.name && e.dimensions[i] && r.dateRange) {
1210
+ const c = e.dimensions[i], u = b(c.sql, s), l = this.buildDateRangeCondition(u, r.dateRange);
1211
+ l && n.push(l);
823
1212
  }
824
1213
  }
825
1214
  return n;
@@ -827,77 +1216,77 @@ class $ {
827
1216
  /**
828
1217
  * Process a single filter for Cube (basic or logical)
829
1218
  */
830
- processFilter(e, t, i) {
1219
+ processFilter(e, t, s) {
831
1220
  if ("and" in e || "or" in e) {
832
- const l = e;
833
- if (l.and) {
834
- const u = l.and.map((m) => this.processFilter(m, t, i)).filter((m) => m !== null);
835
- return u.length > 0 ? p(...u) : null;
1221
+ const u = e;
1222
+ if (u.and) {
1223
+ const l = u.and.map((d) => this.processFilter(d, t, s)).filter((d) => d !== null);
1224
+ return l.length > 0 ? h(...l) : null;
836
1225
  }
837
- if (l.or) {
838
- const u = l.or.map((m) => this.processFilter(m, t, i)).filter((m) => m !== null);
839
- return u.length > 0 ? J(...u) : null;
1226
+ if (u.or) {
1227
+ const l = u.or.map((d) => this.processFilter(d, t, s)).filter((d) => d !== null);
1228
+ return l.length > 0 ? j(...l) : null;
840
1229
  }
841
1230
  }
842
- const n = e, [o, a] = n.member.split(".");
843
- if (o !== t.name) return null;
844
- const r = t.dimensions[a] || t.measures[a];
845
- if (!r) return null;
846
- const c = b(r.sql, i);
1231
+ const n = e, [r, a] = n.member.split(".");
1232
+ if (r !== t.name) return null;
1233
+ const i = t.dimensions[a] || t.measures[a];
1234
+ if (!i) return null;
1235
+ const c = b(i.sql, s);
847
1236
  return this.buildFilterCondition(c, n.operator, n.values);
848
1237
  }
849
1238
  /**
850
1239
  * Build filter condition using Drizzle operators
851
1240
  */
852
- buildFilterCondition(e, t, i) {
853
- if (!i || i.length === 0)
854
- return t === "equals" ? f`FALSE` : null;
855
- const n = i.filter((a) => !(a == null || a === "" || typeof a == "string" && a.includes("\0")));
1241
+ buildFilterCondition(e, t, s) {
1242
+ if (!s || s.length === 0)
1243
+ return t === "equals" ? m`FALSE` : null;
1244
+ const n = s.filter((a) => !(a == null || a === "" || typeof a == "string" && a.includes("\0")));
856
1245
  if (n.length === 0 && !["set", "notSet"].includes(t))
857
- return t === "equals" ? f`FALSE` : null;
858
- const o = n[0];
1246
+ return t === "equals" ? m`FALSE` : null;
1247
+ const r = n[0];
859
1248
  switch (t) {
860
1249
  case "equals":
861
- return n.length > 1 ? Z(e, n) : n.length === 1 ? v(e, o) : f`FALSE`;
1250
+ return n.length > 1 ? P(e, n) : n.length === 1 ? v(e, r) : m`FALSE`;
862
1251
  case "notEquals":
863
- return n.length > 1 ? H(e, n) : n.length === 1 ? V(e, o) : null;
1252
+ return n.length > 1 ? V(e, n) : n.length === 1 ? G(e, r) : null;
864
1253
  case "contains":
865
- return f`${e} ILIKE ${"%" + o + "%"}`;
1254
+ return this.databaseAdapter.buildStringCondition(e, "contains", r);
866
1255
  case "notContains":
867
- return f`${e} NOT ILIKE ${"%" + o + "%"}`;
1256
+ return this.databaseAdapter.buildStringCondition(e, "notContains", r);
868
1257
  case "startsWith":
869
- return f`${e} ILIKE ${o + "%"}`;
1258
+ return this.databaseAdapter.buildStringCondition(e, "startsWith", r);
870
1259
  case "endsWith":
871
- return f`${e} ILIKE ${"%" + o}`;
1260
+ return this.databaseAdapter.buildStringCondition(e, "endsWith", r);
872
1261
  case "gt":
873
- return A(e, o);
1262
+ return N(e, r);
874
1263
  case "gte":
875
- return w(e, o);
1264
+ return w(e, r);
876
1265
  case "lt":
877
- return F(e, o);
1266
+ return $(e, r);
878
1267
  case "lte":
879
- return N(e, o);
1268
+ return D(e, r);
880
1269
  case "set":
881
- return K(e);
1270
+ return z(e);
882
1271
  case "notSet":
883
- return W(e);
1272
+ return _(e);
884
1273
  case "inDateRange":
885
1274
  if (n.length >= 2) {
886
- const a = this.normalizeDate(n[0]), r = this.normalizeDate(n[1]);
887
- if (a && r)
888
- return p(
1275
+ const a = this.normalizeDate(n[0]), i = this.normalizeDate(n[1]);
1276
+ if (a && i)
1277
+ return h(
889
1278
  w(e, a),
890
- N(e, r)
1279
+ D(e, i)
891
1280
  );
892
1281
  }
893
1282
  return null;
894
1283
  case "beforeDate": {
895
- const a = this.normalizeDate(o);
896
- return a ? F(e, a) : null;
1284
+ const a = this.normalizeDate(r);
1285
+ return a ? $(e, a) : null;
897
1286
  }
898
1287
  case "afterDate": {
899
- const a = this.normalizeDate(o);
900
- return a ? A(e, a) : null;
1288
+ const a = this.normalizeDate(r);
1289
+ return a ? N(e, a) : null;
901
1290
  }
902
1291
  default:
903
1292
  return null;
@@ -909,27 +1298,27 @@ class $ {
909
1298
  buildDateRangeCondition(e, t) {
910
1299
  if (!t) return null;
911
1300
  if (Array.isArray(t) && t.length >= 2) {
912
- const i = this.normalizeDate(t[0]), n = this.normalizeDate(t[1]);
913
- return !i || !n ? null : p(
914
- w(e, i),
915
- N(e, n)
1301
+ const s = this.normalizeDate(t[0]), n = this.normalizeDate(t[1]);
1302
+ return !s || !n ? null : h(
1303
+ w(e, s),
1304
+ D(e, n)
916
1305
  );
917
1306
  }
918
1307
  if (typeof t == "string") {
919
- const i = this.parseRelativeDateRange(t);
920
- if (i)
921
- return p(
922
- w(e, i.start),
923
- N(e, i.end)
1308
+ const s = this.parseRelativeDateRange(t);
1309
+ if (s)
1310
+ return h(
1311
+ w(e, s.start),
1312
+ D(e, s.end)
924
1313
  );
925
1314
  const n = this.normalizeDate(t);
926
1315
  if (!n) return null;
927
- const o = new Date(n);
928
- o.setUTCHours(0, 0, 0, 0);
1316
+ const r = new Date(n);
1317
+ r.setUTCHours(0, 0, 0, 0);
929
1318
  const a = new Date(n);
930
- return a.setUTCHours(23, 59, 59, 999), p(
931
- w(e, o),
932
- N(e, a)
1319
+ return a.setUTCHours(23, 59, 59, 999), h(
1320
+ w(e, r),
1321
+ D(e, a)
933
1322
  );
934
1323
  }
935
1324
  return null;
@@ -938,30 +1327,30 @@ class $ {
938
1327
  * Parse relative date range expressions like "last 7 days", "this month"
939
1328
  */
940
1329
  parseRelativeDateRange(e) {
941
- const t = /* @__PURE__ */ new Date(), i = e.toLowerCase().trim(), n = i.match(/^last\s+(\d+)\s+days?$/);
1330
+ const t = /* @__PURE__ */ new Date(), s = e.toLowerCase().trim(), n = s.match(/^last\s+(\d+)\s+days?$/);
942
1331
  if (n) {
943
- const r = parseInt(n[1], 10), c = new Date(t);
944
- c.setDate(t.getDate() - r), c.setHours(0, 0, 0, 0);
945
- const l = new Date(t);
946
- return l.setHours(23, 59, 59, 999), { start: c, end: l };
1332
+ const i = parseInt(n[1], 10), c = new Date(t);
1333
+ c.setDate(t.getDate() - i), c.setHours(0, 0, 0, 0);
1334
+ const u = new Date(t);
1335
+ return u.setHours(23, 59, 59, 999), { start: c, end: u };
947
1336
  }
948
- if (i === "this month") {
949
- const r = new Date(t.getFullYear(), t.getMonth(), 1, 0, 0, 0, 0), c = new Date(t.getFullYear(), t.getMonth() + 1, 0, 23, 59, 59, 999);
950
- return { start: r, end: c };
1337
+ if (s === "this month") {
1338
+ const i = new Date(t.getFullYear(), t.getMonth(), 1, 0, 0, 0, 0), c = new Date(t.getFullYear(), t.getMonth() + 1, 0, 23, 59, 59, 999);
1339
+ return { start: i, end: c };
951
1340
  }
952
- const o = i.match(/^last\s+(\d+)\s+months?$/);
953
- if (o) {
954
- const r = parseInt(o[1], 10), c = new Date(t.getFullYear(), t.getMonth() - r, 1, 0, 0, 0, 0), l = new Date(t);
955
- return l.setHours(23, 59, 59, 999), { start: c, end: l };
1341
+ const r = s.match(/^last\s+(\d+)\s+months?$/);
1342
+ if (r) {
1343
+ const i = parseInt(r[1], 10), c = new Date(t.getFullYear(), t.getMonth() - i, 1, 0, 0, 0, 0), u = new Date(t);
1344
+ return u.setHours(23, 59, 59, 999), { start: c, end: u };
956
1345
  }
957
- if (i === "this year") {
958
- const r = new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0), c = new Date(t.getFullYear(), 11, 31, 23, 59, 59, 999);
959
- return { start: r, end: c };
1346
+ if (s === "this year") {
1347
+ const i = new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0), c = new Date(t.getFullYear(), 11, 31, 23, 59, 59, 999);
1348
+ return { start: i, end: c };
960
1349
  }
961
- const a = i.match(/^last\s+(\d+)\s+years?$/);
1350
+ const a = s.match(/^last\s+(\d+)\s+years?$/);
962
1351
  if (a) {
963
- const r = parseInt(a[1], 10), c = new Date(t.getFullYear() - r, 0, 1, 0, 0, 0, 0), l = new Date(t);
964
- return l.setHours(23, 59, 59, 999), { start: c, end: l };
1352
+ const i = parseInt(a[1], 10), c = new Date(t.getFullYear() - i, 0, 1, 0, 0, 0, 0), u = new Date(t);
1353
+ return u.setHours(23, 59, 59, 999), { start: c, end: u };
965
1354
  }
966
1355
  return null;
967
1356
  }
@@ -974,8 +1363,8 @@ class $ {
974
1363
  if (e instanceof Date)
975
1364
  return isNaN(e.getTime()) ? null : e;
976
1365
  if (typeof e == "string") {
977
- const i = new Date(e);
978
- return isNaN(i.getTime()) ? null : i;
1366
+ const s = new Date(e);
1367
+ return isNaN(s.getTime()) ? null : s;
979
1368
  }
980
1369
  const t = new Date(e);
981
1370
  return isNaN(t.getTime()) ? null : t;
@@ -983,26 +1372,26 @@ class $ {
983
1372
  /**
984
1373
  * Build GROUP BY fields from dimensions and time dimensions (Cube)
985
1374
  */
986
- buildGroupByFields(e, t, i) {
1375
+ buildGroupByFields(e, t, s) {
987
1376
  const n = [];
988
1377
  if (t.dimensions)
989
- for (const o of t.dimensions) {
990
- const [a, r] = o.split(".");
991
- if (a === e.name && e.dimensions[r]) {
992
- const c = e.dimensions[r], l = b(c.sql, i);
993
- n.push(l);
1378
+ for (const r of t.dimensions) {
1379
+ const [a, i] = r.split(".");
1380
+ if (a === e.name && e.dimensions[i]) {
1381
+ const c = e.dimensions[i], u = b(c.sql, s);
1382
+ n.push(u);
994
1383
  }
995
1384
  }
996
1385
  if (t.timeDimensions)
997
- for (const o of t.timeDimensions) {
998
- const [a, r] = o.dimension.split(".");
999
- if (a === e.name && e.dimensions[r]) {
1000
- const c = e.dimensions[r], l = this.buildTimeDimensionExpression(
1386
+ for (const r of t.timeDimensions) {
1387
+ const [a, i] = r.dimension.split(".");
1388
+ if (a === e.name && e.dimensions[i]) {
1389
+ const c = e.dimensions[i], u = this.buildTimeDimensionExpression(
1001
1390
  c.sql,
1002
- o.granularity,
1003
- i
1391
+ r.granularity,
1392
+ s
1004
1393
  );
1005
- n.push(l);
1394
+ n.push(u);
1006
1395
  }
1007
1396
  }
1008
1397
  return n;
@@ -1011,128 +1400,128 @@ class $ {
1011
1400
  * Build ORDER BY clause with automatic time dimension sorting
1012
1401
  */
1013
1402
  buildOrderBy(e, t) {
1014
- var o;
1015
- const i = [], n = t || [
1403
+ var r;
1404
+ const s = [], n = t || [
1016
1405
  ...e.measures || [],
1017
1406
  ...e.dimensions || [],
1018
- ...((o = e.timeDimensions) == null ? void 0 : o.map((a) => a.dimension)) || []
1407
+ ...((r = e.timeDimensions) == null ? void 0 : r.map((a) => a.dimension)) || []
1019
1408
  ];
1020
1409
  if (e.order && Object.keys(e.order).length > 0)
1021
- for (const [a, r] of Object.entries(e.order)) {
1410
+ for (const [a, i] of Object.entries(e.order)) {
1022
1411
  if (!n.includes(a))
1023
1412
  throw new Error(`Cannot order by '${a}': field is not selected in the query`);
1024
- const c = r === "desc" ? f`DESC` : f`ASC`;
1025
- i.push(f`${f.identifier(a)} ${c}`);
1413
+ const c = i === "desc" ? m`DESC` : m`ASC`;
1414
+ s.push(m`${m.identifier(a)} ${c}`);
1026
1415
  }
1027
1416
  if (e.timeDimensions && e.timeDimensions.length > 0) {
1028
- const a = new Set(Object.keys(e.order || {})), r = [...e.timeDimensions].sort(
1029
- (c, l) => c.dimension.localeCompare(l.dimension)
1417
+ const a = new Set(Object.keys(e.order || {})), i = [...e.timeDimensions].sort(
1418
+ (c, u) => c.dimension.localeCompare(u.dimension)
1030
1419
  );
1031
- for (const c of r)
1032
- a.has(c.dimension) || i.push(f`${f.identifier(c.dimension)} ASC`);
1420
+ for (const c of i)
1421
+ a.has(c.dimension) || s.push(m`${m.identifier(c.dimension)} ASC`);
1033
1422
  }
1034
- return i;
1423
+ return s;
1035
1424
  }
1036
1425
  /**
1037
1426
  * Generate annotations for UI metadata
1038
1427
  */
1039
1428
  generateAnnotations(e, t) {
1040
- const i = {}, n = {}, o = {};
1429
+ const s = {}, n = {}, r = {};
1041
1430
  if (t.measures)
1042
1431
  for (const a of t.measures) {
1043
- const [r, c] = a.split(".");
1044
- if (r === e.name && e.measures[c]) {
1045
- const l = e.measures[c];
1046
- i[a] = {
1047
- title: l.title || c,
1048
- shortTitle: l.title || c,
1049
- type: l.type
1432
+ const [i, c] = a.split(".");
1433
+ if (i === e.name && e.measures[c]) {
1434
+ const u = e.measures[c];
1435
+ s[a] = {
1436
+ title: u.title || c,
1437
+ shortTitle: u.title || c,
1438
+ type: u.type
1050
1439
  };
1051
1440
  }
1052
1441
  }
1053
1442
  if (t.dimensions)
1054
1443
  for (const a of t.dimensions) {
1055
- const [r, c] = a.split(".");
1056
- if (r === e.name && e.dimensions[c]) {
1057
- const l = e.dimensions[c];
1444
+ const [i, c] = a.split(".");
1445
+ if (i === e.name && e.dimensions[c]) {
1446
+ const u = e.dimensions[c];
1058
1447
  n[a] = {
1059
- title: l.title || c,
1060
- shortTitle: l.title || c,
1061
- type: l.type
1448
+ title: u.title || c,
1449
+ shortTitle: u.title || c,
1450
+ type: u.type
1062
1451
  };
1063
1452
  }
1064
1453
  }
1065
1454
  if (t.timeDimensions)
1066
1455
  for (const a of t.timeDimensions) {
1067
- const [r, c] = a.dimension.split(".");
1068
- if (r === e.name && e.dimensions[c]) {
1069
- const l = e.dimensions[c];
1070
- o[a.dimension] = {
1071
- title: l.title || c,
1072
- shortTitle: l.title || c,
1073
- type: l.type,
1456
+ const [i, c] = a.dimension.split(".");
1457
+ if (i === e.name && e.dimensions[c]) {
1458
+ const u = e.dimensions[c];
1459
+ r[a.dimension] = {
1460
+ title: u.title || c,
1461
+ shortTitle: u.title || c,
1462
+ type: u.type,
1074
1463
  granularity: a.granularity
1075
1464
  };
1076
1465
  }
1077
1466
  }
1078
1467
  return {
1079
- measures: i,
1468
+ measures: s,
1080
1469
  dimensions: n,
1081
1470
  segments: {},
1082
- timeDimensions: o
1471
+ timeDimensions: r
1083
1472
  };
1084
1473
  }
1085
1474
  /**
1086
1475
  * Generate annotations for multi-cube queries
1087
1476
  */
1088
1477
  generateMultiCubeAnnotations(e, t) {
1089
- const i = {}, n = {}, o = {}, a = [e.primaryCube];
1090
- if (e.joinCubes && a.push(...e.joinCubes.map((r) => r.cube)), t.measures)
1091
- for (const r of t.measures) {
1092
- const [c, l] = r.split("."), u = a.find((m) => m.name === c);
1093
- if (u && u.measures[l]) {
1094
- const m = u.measures[l];
1095
- i[r] = {
1096
- title: m.title || l,
1097
- shortTitle: m.title || l,
1098
- type: m.type
1478
+ const s = {}, n = {}, r = {}, a = [e.primaryCube];
1479
+ if (e.joinCubes && a.push(...e.joinCubes.map((i) => i.cube)), t.measures)
1480
+ for (const i of t.measures) {
1481
+ const [c, u] = i.split("."), l = a.find((d) => d.name === c);
1482
+ if (l && l.measures[u]) {
1483
+ const d = l.measures[u];
1484
+ s[i] = {
1485
+ title: d.title || u,
1486
+ shortTitle: d.title || u,
1487
+ type: d.type
1099
1488
  };
1100
1489
  }
1101
1490
  }
1102
1491
  if (t.dimensions)
1103
- for (const r of t.dimensions) {
1104
- const [c, l] = r.split("."), u = a.find((m) => m.name === c);
1105
- if (u && u.dimensions[l]) {
1106
- const m = u.dimensions[l];
1107
- n[r] = {
1108
- title: m.title || l,
1109
- shortTitle: m.title || l,
1110
- type: m.type
1492
+ for (const i of t.dimensions) {
1493
+ const [c, u] = i.split("."), l = a.find((d) => d.name === c);
1494
+ if (l && l.dimensions[u]) {
1495
+ const d = l.dimensions[u];
1496
+ n[i] = {
1497
+ title: d.title || u,
1498
+ shortTitle: d.title || u,
1499
+ type: d.type
1111
1500
  };
1112
1501
  }
1113
1502
  }
1114
1503
  if (t.timeDimensions)
1115
- for (const r of t.timeDimensions) {
1116
- const [c, l] = r.dimension.split("."), u = a.find((m) => m.name === c);
1117
- if (u && u.dimensions && u.dimensions[l]) {
1118
- const m = u.dimensions[l];
1119
- o[r.dimension] = {
1120
- title: m.title || l,
1121
- shortTitle: m.title || l,
1122
- type: m.type,
1123
- granularity: r.granularity
1504
+ for (const i of t.timeDimensions) {
1505
+ const [c, u] = i.dimension.split("."), l = a.find((d) => d.name === c);
1506
+ if (l && l.dimensions && l.dimensions[u]) {
1507
+ const d = l.dimensions[u];
1508
+ r[i.dimension] = {
1509
+ title: d.title || u,
1510
+ shortTitle: d.title || u,
1511
+ type: d.type,
1512
+ granularity: i.granularity
1124
1513
  };
1125
1514
  }
1126
1515
  }
1127
1516
  return {
1128
- measures: i,
1517
+ measures: s,
1129
1518
  dimensions: n,
1130
1519
  segments: {},
1131
- timeDimensions: o
1520
+ timeDimensions: r
1132
1521
  };
1133
1522
  }
1134
1523
  }
1135
- class T {
1524
+ class x {
1136
1525
  // 5 minutes in milliseconds
1137
1526
  constructor(e) {
1138
1527
  C(this, "cubes", /* @__PURE__ */ new Map());
@@ -1140,7 +1529,7 @@ class T {
1140
1529
  C(this, "metadataCache");
1141
1530
  C(this, "metadataCacheTimestamp");
1142
1531
  C(this, "METADATA_CACHE_TTL", 5 * 60 * 1e3);
1143
- e != null && e.databaseExecutor ? this.dbExecutor = e.databaseExecutor : e != null && e.drizzle && (this.dbExecutor = _(
1532
+ e != null && e.databaseExecutor ? this.dbExecutor = e.databaseExecutor : e != null && e.drizzle && (this.dbExecutor = L(
1144
1533
  e.drizzle,
1145
1534
  e.schema,
1146
1535
  e.engineType
@@ -1155,8 +1544,8 @@ class T {
1155
1544
  /**
1156
1545
  * Set Drizzle instance and schema directly
1157
1546
  */
1158
- setDrizzle(e, t, i) {
1159
- this.dbExecutor = _(e, t, i);
1547
+ setDrizzle(e, t, s) {
1548
+ this.dbExecutor = L(e, t, s);
1160
1549
  }
1161
1550
  /**
1162
1551
  * Check if database executor is configured
@@ -1194,7 +1583,7 @@ class T {
1194
1583
  async execute(e, t) {
1195
1584
  if (!this.dbExecutor)
1196
1585
  throw new Error("Database executor not configured");
1197
- return new $(this.dbExecutor).execute(this.cubes, e, t);
1586
+ return new T(this.dbExecutor).execute(this.cubes, e, t);
1198
1587
  }
1199
1588
  /**
1200
1589
  * Execute a multi-cube query
@@ -1205,10 +1594,10 @@ class T {
1205
1594
  /**
1206
1595
  * Execute a single cube query
1207
1596
  */
1208
- async executeQuery(e, t, i) {
1597
+ async executeQuery(e, t, s) {
1209
1598
  if (!this.cubes.get(e))
1210
1599
  throw new Error(`Cube '${e}' not found`);
1211
- return this.execute(t, i);
1600
+ return this.execute(t, s);
1212
1601
  }
1213
1602
  /**
1214
1603
  * Get metadata for all cubes (for API responses)
@@ -1218,7 +1607,7 @@ class T {
1218
1607
  const e = Date.now();
1219
1608
  if (this.metadataCache && this.metadataCacheTimestamp && e - this.metadataCacheTimestamp < this.METADATA_CACHE_TTL)
1220
1609
  return this.metadataCache;
1221
- const t = Array.from(this.cubes.values()).map((i) => this.generateCubeMetadata(i));
1610
+ const t = Array.from(this.cubes.values()).map((s) => this.generateCubeMetadata(s));
1222
1611
  return this.metadataCache = t, this.metadataCacheTimestamp = e, t;
1223
1612
  }
1224
1613
  /**
@@ -1226,25 +1615,25 @@ class T {
1226
1615
  * Optimized version that minimizes object iterations
1227
1616
  */
1228
1617
  generateCubeMetadata(e) {
1229
- const t = Object.keys(e.measures), i = Object.keys(e.dimensions), n = new Array(t.length), o = new Array(i.length);
1618
+ const t = Object.keys(e.measures), s = Object.keys(e.dimensions), n = new Array(t.length), r = new Array(s.length);
1230
1619
  for (let a = 0; a < t.length; a++) {
1231
- const r = t[a], c = e.measures[r];
1620
+ const i = t[a], c = e.measures[i];
1232
1621
  n[a] = {
1233
- name: `${e.name}.${r}`,
1234
- title: c.title || r,
1235
- shortTitle: c.title || r,
1622
+ name: `${e.name}.${i}`,
1623
+ title: c.title || i,
1624
+ shortTitle: c.title || i,
1236
1625
  type: c.type,
1237
1626
  format: void 0,
1238
1627
  // Measure doesn't have format field
1239
1628
  description: c.description
1240
1629
  };
1241
1630
  }
1242
- for (let a = 0; a < i.length; a++) {
1243
- const r = i[a], c = e.dimensions[r];
1244
- o[a] = {
1245
- name: `${e.name}.${r}`,
1246
- title: c.title || r,
1247
- shortTitle: c.title || r,
1631
+ for (let a = 0; a < s.length; a++) {
1632
+ const i = s[a], c = e.dimensions[i];
1633
+ r[a] = {
1634
+ name: `${e.name}.${i}`,
1635
+ title: c.title || i,
1636
+ shortTitle: c.title || i,
1248
1637
  type: c.type,
1249
1638
  format: void 0,
1250
1639
  // Dimension doesn't have format field
@@ -1256,7 +1645,7 @@ class T {
1256
1645
  title: e.title || e.name,
1257
1646
  description: e.description,
1258
1647
  measures: n,
1259
- dimensions: o,
1648
+ dimensions: r,
1260
1649
  segments: []
1261
1650
  // Add segments support later if needed
1262
1651
  };
@@ -1264,13 +1653,13 @@ class T {
1264
1653
  /**
1265
1654
  * Get SQL for a query without executing it (debugging)
1266
1655
  */
1267
- async generateSQL(e, t, i) {
1656
+ async generateSQL(e, t, s) {
1268
1657
  const n = this.getCube(e);
1269
1658
  if (!n)
1270
1659
  throw new Error(`Cube '${e}' not found`);
1271
1660
  if (!this.dbExecutor)
1272
1661
  throw new Error("Database executor not configured");
1273
- return new $(this.dbExecutor).generateSQL(n, t, i);
1662
+ return new T(this.dbExecutor).generateSQL(n, t, s);
1274
1663
  }
1275
1664
  /**
1276
1665
  * Get SQL for a multi-cube query without executing it (debugging)
@@ -1278,7 +1667,7 @@ class T {
1278
1667
  async generateMultiCubeSQL(e, t) {
1279
1668
  if (!this.dbExecutor)
1280
1669
  throw new Error("Database executor not configured");
1281
- return new $(this.dbExecutor).generateMultiCubeSQL(this.cubes, e, t);
1670
+ return new T(this.dbExecutor).generateMultiCubeSQL(this.cubes, e, t);
1282
1671
  }
1283
1672
  /**
1284
1673
  * Check if a cube exists
@@ -1317,93 +1706,93 @@ class T {
1317
1706
  * Ensures all referenced cubes and fields exist
1318
1707
  */
1319
1708
  validateQuery(e) {
1320
- return j(this.cubes, e);
1709
+ return Q(this.cubes, e);
1321
1710
  }
1322
1711
  }
1323
- function j(s, e) {
1324
- const t = [], i = /* @__PURE__ */ new Set();
1712
+ function Q(o, e) {
1713
+ const t = [], s = /* @__PURE__ */ new Set();
1325
1714
  if (e.measures)
1326
1715
  for (const n of e.measures) {
1327
- const [o, a] = n.split(".");
1328
- if (!o || !a) {
1716
+ const [r, a] = n.split(".");
1717
+ if (!r || !a) {
1329
1718
  t.push(`Invalid measure format: ${n}. Expected format: 'CubeName.fieldName'`);
1330
1719
  continue;
1331
1720
  }
1332
- i.add(o);
1333
- const r = s.get(o);
1334
- if (!r) {
1335
- t.push(`Cube '${o}' not found (referenced in measure '${n}')`);
1721
+ s.add(r);
1722
+ const i = o.get(r);
1723
+ if (!i) {
1724
+ t.push(`Cube '${r}' not found (referenced in measure '${n}')`);
1336
1725
  continue;
1337
1726
  }
1338
- r.measures[a] || t.push(`Measure '${a}' not found on cube '${o}'`);
1727
+ i.measures[a] || t.push(`Measure '${a}' not found on cube '${r}'`);
1339
1728
  }
1340
1729
  if (e.dimensions)
1341
1730
  for (const n of e.dimensions) {
1342
- const [o, a] = n.split(".");
1343
- if (!o || !a) {
1731
+ const [r, a] = n.split(".");
1732
+ if (!r || !a) {
1344
1733
  t.push(`Invalid dimension format: ${n}. Expected format: 'CubeName.fieldName'`);
1345
1734
  continue;
1346
1735
  }
1347
- i.add(o);
1348
- const r = s.get(o);
1349
- if (!r) {
1350
- t.push(`Cube '${o}' not found (referenced in dimension '${n}')`);
1736
+ s.add(r);
1737
+ const i = o.get(r);
1738
+ if (!i) {
1739
+ t.push(`Cube '${r}' not found (referenced in dimension '${n}')`);
1351
1740
  continue;
1352
1741
  }
1353
- r.dimensions[a] || t.push(`Dimension '${a}' not found on cube '${o}'`);
1742
+ i.dimensions[a] || t.push(`Dimension '${a}' not found on cube '${r}'`);
1354
1743
  }
1355
1744
  if (e.timeDimensions)
1356
1745
  for (const n of e.timeDimensions) {
1357
- const [o, a] = n.dimension.split(".");
1358
- if (!o || !a) {
1746
+ const [r, a] = n.dimension.split(".");
1747
+ if (!r || !a) {
1359
1748
  t.push(`Invalid timeDimension format: ${n.dimension}. Expected format: 'CubeName.fieldName'`);
1360
1749
  continue;
1361
1750
  }
1362
- i.add(o);
1363
- const r = s.get(o);
1364
- if (!r) {
1365
- t.push(`Cube '${o}' not found (referenced in timeDimension '${n.dimension}')`);
1751
+ s.add(r);
1752
+ const i = o.get(r);
1753
+ if (!i) {
1754
+ t.push(`Cube '${r}' not found (referenced in timeDimension '${n.dimension}')`);
1366
1755
  continue;
1367
1756
  }
1368
- r.dimensions[a] || t.push(`TimeDimension '${a}' not found on cube '${o}' (must be a dimension with time type)`);
1757
+ i.dimensions[a] || t.push(`TimeDimension '${a}' not found on cube '${r}' (must be a dimension with time type)`);
1369
1758
  }
1370
1759
  if (e.filters)
1371
1760
  for (const n of e.filters)
1372
- L(n, s, t, i);
1373
- return i.size === 0 && t.push("Query must reference at least one cube through measures, dimensions, or filters"), {
1761
+ k(n, o, t, s);
1762
+ return s.size === 0 && t.push("Query must reference at least one cube through measures, dimensions, or filters"), {
1374
1763
  isValid: t.length === 0,
1375
1764
  errors: t
1376
1765
  };
1377
1766
  }
1378
- function L(s, e, t, i) {
1379
- if ("and" in s || "or" in s) {
1380
- const r = s.and || s.or || [];
1381
- for (const c of r)
1382
- L(c, e, t, i);
1767
+ function k(o, e, t, s) {
1768
+ if ("and" in o || "or" in o) {
1769
+ const i = o.and || o.or || [];
1770
+ for (const c of i)
1771
+ k(c, e, t, s);
1383
1772
  return;
1384
1773
  }
1385
- if (!("member" in s)) {
1774
+ if (!("member" in o)) {
1386
1775
  t.push("Filter must have a member field");
1387
1776
  return;
1388
1777
  }
1389
- const [n, o] = s.member.split(".");
1390
- if (!n || !o) {
1391
- t.push(`Invalid filter member format: ${s.member}. Expected format: 'CubeName.fieldName'`);
1778
+ const [n, r] = o.member.split(".");
1779
+ if (!n || !r) {
1780
+ t.push(`Invalid filter member format: ${o.member}. Expected format: 'CubeName.fieldName'`);
1392
1781
  return;
1393
1782
  }
1394
- i.add(n);
1783
+ s.add(n);
1395
1784
  const a = e.get(n);
1396
1785
  if (!a) {
1397
- t.push(`Cube '${n}' not found (referenced in filter '${s.member}')`);
1786
+ t.push(`Cube '${n}' not found (referenced in filter '${o.member}')`);
1398
1787
  return;
1399
1788
  }
1400
- !a.dimensions[o] && !a.measures[o] && t.push(`Filter field '${o}' not found on cube '${n}' (must be a dimension or measure)`);
1789
+ !a.dimensions[r] && !a.measures[r] && t.push(`Filter field '${r}' not found on cube '${n}' (must be a dimension or measure)`);
1401
1790
  }
1402
- function Ee(s) {
1403
- return new T(s);
1791
+ function ye(o) {
1792
+ return new x(o);
1404
1793
  }
1405
- const se = new T();
1406
- function re(s) {
1794
+ const ce = new x();
1795
+ function ue(o) {
1407
1796
  const e = {
1408
1797
  valid: !0,
1409
1798
  errors: [],
@@ -1411,7 +1800,7 @@ function re(s) {
1411
1800
  cubes: []
1412
1801
  };
1413
1802
  try {
1414
- const t = G(s);
1803
+ const t = Z(o);
1415
1804
  if (!t)
1416
1805
  return e.valid = !1, e.errors.push("Invalid YAML: empty or malformed content"), e;
1417
1806
  if (t.cubes && Array.isArray(t.cubes))
@@ -1420,8 +1809,8 @@ function re(s) {
1420
1809
  e.cubes = [t];
1421
1810
  else
1422
1811
  return e.valid = !1, e.errors.push('YAML must contain either a "cubes" array or cube properties at root level'), e;
1423
- for (const i of e.cubes) {
1424
- const n = oe(i);
1812
+ for (const s of e.cubes) {
1813
+ const n = le(s);
1425
1814
  e.errors.push(...n);
1426
1815
  }
1427
1816
  e.valid = e.errors.length === 0;
@@ -1430,87 +1819,87 @@ function re(s) {
1430
1819
  }
1431
1820
  return e;
1432
1821
  }
1433
- function oe(s) {
1822
+ function le(o) {
1434
1823
  const e = [];
1435
- return s.name || e.push("Cube name is required"), !s.sql && !s.sql_table && !s.sqlTable && e.push('Cube must have either "sql", "sql_table", or "sqlTable" property'), s.dimensions && s.dimensions.forEach((t, i) => {
1436
- t.name || e.push(`Dimension at index ${i} is missing name`), t.type || e.push(`Dimension "${t.name}" is missing type`), t.sql || e.push(`Dimension "${t.name}" is missing sql`);
1437
- }), s.measures && s.measures.forEach((t, i) => {
1438
- t.name || e.push(`Measure at index ${i} is missing name`), t.type || e.push(`Measure "${t.name}" is missing type`), t.sql || e.push(`Measure "${t.name}" is missing sql`);
1439
- }), s.joins && s.joins.forEach((t, i) => {
1440
- t.name || e.push(`Join at index ${i} is missing name`), t.relationship || e.push(`Join "${t.name}" is missing relationship`), t.sql || e.push(`Join "${t.name}" is missing sql`);
1824
+ return o.name || e.push("Cube name is required"), !o.sql && !o.sql_table && !o.sqlTable && e.push('Cube must have either "sql", "sql_table", or "sqlTable" property'), o.dimensions && o.dimensions.forEach((t, s) => {
1825
+ t.name || e.push(`Dimension at index ${s} is missing name`), t.type || e.push(`Dimension "${t.name}" is missing type`), t.sql || e.push(`Dimension "${t.name}" is missing sql`);
1826
+ }), o.measures && o.measures.forEach((t, s) => {
1827
+ t.name || e.push(`Measure at index ${s} is missing name`), t.type || e.push(`Measure "${t.name}" is missing type`), t.sql || e.push(`Measure "${t.name}" is missing sql`);
1828
+ }), o.joins && o.joins.forEach((t, s) => {
1829
+ t.name || e.push(`Join at index ${s} is missing name`), t.relationship || e.push(`Join "${t.name}" is missing relationship`), t.sql || e.push(`Join "${t.name}" is missing sql`);
1441
1830
  }), e;
1442
1831
  }
1443
- function ae(s) {
1832
+ function de(o) {
1444
1833
  const e = {};
1445
- s.dimensions && s.dimensions.forEach((r) => {
1446
- e[r.name] = ce(r);
1834
+ o.dimensions && o.dimensions.forEach((i) => {
1835
+ e[i.name] = me(i);
1447
1836
  });
1448
1837
  const t = {};
1449
- s.measures && s.measures.forEach((r) => {
1450
- t[r.name] = le(r);
1838
+ o.measures && o.measures.forEach((i) => {
1839
+ t[i.name] = fe(i);
1451
1840
  });
1452
- const i = {};
1453
- s.joins && s.joins.forEach((r) => {
1454
- i[r.name] = fe(r);
1841
+ const s = {};
1842
+ o.joins && o.joins.forEach((i) => {
1843
+ s[i.name] = be(i);
1455
1844
  });
1456
1845
  const n = {};
1457
- (s.pre_aggregations || s.preAggregations) && (s.pre_aggregations || s.preAggregations || []).forEach((c) => {
1458
- n[c.name] = de(c);
1846
+ (o.pre_aggregations || o.preAggregations) && (o.pre_aggregations || o.preAggregations || []).forEach((c) => {
1847
+ n[c.name] = ge(c);
1459
1848
  });
1460
- let o = s.sql;
1461
- !o && (s.sql_table || s.sqlTable) && (o = `SELECT * FROM ${s.sql_table || s.sqlTable}`);
1462
- const a = s.refresh_key || s.refreshKey;
1849
+ let r = o.sql;
1850
+ !r && (o.sql_table || o.sqlTable) && (r = `SELECT * FROM ${o.sql_table || o.sqlTable}`);
1851
+ const a = o.refresh_key || o.refreshKey;
1463
1852
  return {
1464
- name: s.name,
1465
- title: s.title,
1466
- description: s.description,
1467
- sql: o || "",
1468
- sqlAlias: s.sql_alias || s.sqlAlias,
1469
- dataSource: s.data_source || s.dataSource,
1853
+ name: o.name,
1854
+ title: o.title,
1855
+ description: o.description,
1856
+ sql: r || "",
1857
+ sqlAlias: o.sql_alias || o.sqlAlias,
1858
+ dataSource: o.data_source || o.dataSource,
1470
1859
  refreshKey: a ? {
1471
1860
  every: a.every,
1472
1861
  sql: a.sql
1473
1862
  } : void 0,
1474
1863
  dimensions: e,
1475
1864
  measures: t,
1476
- joins: Object.keys(i).length > 0 ? i : void 0,
1865
+ joins: Object.keys(s).length > 0 ? s : void 0,
1477
1866
  preAggregations: Object.keys(n).length > 0 ? n : void 0,
1478
- meta: s.meta
1867
+ meta: o.meta
1479
1868
  };
1480
1869
  }
1481
- function ce(s) {
1870
+ function me(o) {
1482
1871
  return {
1483
- name: s.name,
1484
- title: s.title,
1485
- description: s.description,
1486
- type: s.type,
1487
- sql: s.sql,
1488
- primaryKey: s.primary_key || s.primaryKey,
1489
- shown: s.shown,
1490
- format: s.format,
1491
- meta: s.meta
1872
+ name: o.name,
1873
+ title: o.title,
1874
+ description: o.description,
1875
+ type: o.type,
1876
+ sql: o.sql,
1877
+ primaryKey: o.primary_key || o.primaryKey,
1878
+ shown: o.shown,
1879
+ format: o.format,
1880
+ meta: o.meta
1492
1881
  };
1493
1882
  }
1494
- function le(s) {
1495
- var i;
1496
- const e = (i = s.filters) == null ? void 0 : i.map((n) => ({
1883
+ function fe(o) {
1884
+ var s;
1885
+ const e = (s = o.filters) == null ? void 0 : s.map((n) => ({
1497
1886
  sql: n.sql
1498
- })), t = s.rolling_window || s.rollingWindow;
1887
+ })), t = o.rolling_window || o.rollingWindow;
1499
1888
  return {
1500
- name: s.name,
1501
- title: s.title,
1502
- description: s.description,
1503
- type: s.type,
1504
- sql: s.sql,
1505
- format: s.format,
1506
- shown: s.shown,
1889
+ name: o.name,
1890
+ title: o.title,
1891
+ description: o.description,
1892
+ type: o.type,
1893
+ sql: o.sql,
1894
+ format: o.format,
1895
+ shown: o.shown,
1507
1896
  filters: e,
1508
1897
  rollingWindow: t,
1509
- meta: s.meta
1898
+ meta: o.meta
1510
1899
  };
1511
1900
  }
1512
- function ue(s) {
1513
- switch (s) {
1901
+ function he(o) {
1902
+ switch (o) {
1514
1903
  case "one_to_one":
1515
1904
  return "hasOne";
1516
1905
  case "one_to_many":
@@ -1521,8 +1910,8 @@ function ue(s) {
1521
1910
  return "belongsTo";
1522
1911
  }
1523
1912
  }
1524
- function me(s) {
1525
- switch (s) {
1913
+ function pe(o) {
1914
+ switch (o) {
1526
1915
  case "hasOne":
1527
1916
  return "one_to_one";
1528
1917
  case "hasMany":
@@ -1533,62 +1922,62 @@ function me(s) {
1533
1922
  return "many_to_one";
1534
1923
  }
1535
1924
  }
1536
- function fe(s) {
1925
+ function be(o) {
1537
1926
  return {
1538
- name: s.name,
1539
- type: s.type,
1540
- relationship: ue(s.relationship),
1541
- sql: s.sql
1927
+ name: o.name,
1928
+ type: o.type,
1929
+ relationship: he(o.relationship),
1930
+ sql: o.sql
1542
1931
  };
1543
1932
  }
1544
- function de(s) {
1545
- const e = s.time_dimension || s.timeDimension, t = s.refresh_key || s.refreshKey;
1933
+ function ge(o) {
1934
+ const e = o.time_dimension || o.timeDimension, t = o.refresh_key || o.refreshKey;
1546
1935
  return {
1547
- name: s.name,
1548
- measures: s.measures,
1549
- dimensions: s.dimensions,
1936
+ name: o.name,
1937
+ measures: o.measures,
1938
+ dimensions: o.dimensions,
1550
1939
  timeDimension: e,
1551
1940
  refreshKey: t,
1552
- indexes: s.indexes
1941
+ indexes: o.indexes
1553
1942
  };
1554
1943
  }
1555
- async function he() {
1944
+ async function Ce() {
1556
1945
  try {
1557
- const { promises: s } = await import("fs"), e = await s.readFile("non-existent-file.txt", "utf-8").catch((t) => t.message);
1946
+ const { promises: o } = await import("fs"), e = await o.readFile("non-existent-file.txt", "utf-8").catch((t) => t.message);
1558
1947
  return !(typeof e == "string" && e.includes("not implemented"));
1559
1948
  } catch {
1560
1949
  return !1;
1561
1950
  }
1562
1951
  }
1563
- function pe(s) {
1564
- const e = re(s);
1952
+ function we(o) {
1953
+ const e = ue(o);
1565
1954
  if (!e.valid)
1566
1955
  throw new Error(`Invalid YAML cube definition:
1567
1956
  ${e.errors.join(`
1568
1957
  `)}`);
1569
- return e.cubes.map((t) => ae(t));
1958
+ return e.cubes.map((t) => de(t));
1570
1959
  }
1571
- async function De(s) {
1572
- if (!await he())
1960
+ async function Te(o) {
1961
+ if (!await Ce())
1573
1962
  return console.log("ℹ️ YAML file loading not supported in this environment (Cloudflare Workers/Edge Runtime). Use inline YAML strings or build-time transformations instead."), [];
1574
1963
  try {
1575
- const { promises: t } = await import("fs"), i = await t.readFile(s, "utf-8");
1576
- return pe(i);
1964
+ const { promises: t } = await import("fs"), s = await t.readFile(o, "utf-8");
1965
+ return we(s);
1577
1966
  } catch (t) {
1578
- return console.log(`ℹ️ Could not load YAML file ${s}:`, t instanceof Error ? t.message : t), [];
1967
+ return console.log(`ℹ️ Could not load YAML file ${o}:`, t instanceof Error ? t.message : t), [];
1579
1968
  }
1580
1969
  }
1581
- function ye(s) {
1582
- let e = s;
1970
+ function Se(o) {
1971
+ let e = o;
1583
1972
  return e = e.replace(/\{CUBE\}/g, "${CUBE}"), e = e.replace(/\{([A-Za-z_][A-Za-z0-9_]*\.[A-Za-z_][A-Za-z0-9_]*)\}/g, "${$1}"), e = e.replace(/\{([A-Za-z_][A-Za-z0-9_]*)\}/g, "${$1}"), e = e.replace(/\$\$\{/g, "${"), e;
1584
1973
  }
1585
- function $e(s) {
1974
+ function xe(o) {
1586
1975
  const e = {
1587
- name: s.name,
1588
- title: s.title,
1589
- description: s.description,
1590
- sql: typeof s.sql == "string" ? s.sql : void 0,
1591
- dimensions: Object.values(s.dimensions).map((t) => ({
1976
+ name: o.name,
1977
+ title: o.title,
1978
+ description: o.description,
1979
+ sql: typeof o.sql == "string" ? o.sql : void 0,
1980
+ dimensions: Object.values(o.dimensions).map((t) => ({
1592
1981
  name: t.name,
1593
1982
  title: t.title,
1594
1983
  description: t.description,
@@ -1599,8 +1988,8 @@ function $e(s) {
1599
1988
  format: t.format,
1600
1989
  meta: t.meta
1601
1990
  })),
1602
- measures: Object.values(s.measures).map((t) => {
1603
- var i;
1991
+ measures: Object.values(o.measures).map((t) => {
1992
+ var s;
1604
1993
  return {
1605
1994
  name: t.name,
1606
1995
  title: t.title,
@@ -1609,108 +1998,108 @@ function $e(s) {
1609
1998
  sql: typeof t.sql == "string" ? t.sql : "",
1610
1999
  format: t.format,
1611
2000
  shown: t.shown,
1612
- filters: (i = t.filters) == null ? void 0 : i.map((n) => ({
2001
+ filters: (s = t.filters) == null ? void 0 : s.map((n) => ({
1613
2002
  sql: typeof n.sql == "string" ? n.sql : ""
1614
2003
  })),
1615
2004
  rolling_window: t.rollingWindow,
1616
2005
  meta: t.meta
1617
2006
  };
1618
2007
  }),
1619
- joins: s.joins ? Object.values(s.joins).map((t) => ({
2008
+ joins: o.joins ? Object.values(o.joins).map((t) => ({
1620
2009
  name: t.name || "",
1621
2010
  type: t.type,
1622
- relationship: me(t.relationship),
2011
+ relationship: pe(t.relationship),
1623
2012
  sql: typeof t.sql == "string" ? t.sql : ""
1624
2013
  })) : void 0,
1625
- meta: s.meta
2014
+ meta: o.meta
1626
2015
  };
1627
- return P(e, {
2016
+ return X(e, {
1628
2017
  indent: 2,
1629
2018
  lineWidth: 120,
1630
2019
  minContentWidth: 40
1631
2020
  });
1632
2021
  }
1633
- const xe = se;
1634
- function Te(s) {
1635
- return new T({
1636
- drizzle: s.drizzle,
1637
- schema: s.schema
2022
+ const Fe = ce;
2023
+ function Me(o) {
2024
+ return new x({
2025
+ drizzle: o.drizzle,
2026
+ schema: o.schema
1638
2027
  });
1639
2028
  }
1640
- const Ae = {
2029
+ const Le = {
1641
2030
  /**
1642
2031
  * Create a simple query builder
1643
2032
  */
1644
2033
  query: () => {
1645
- const s = (e, t = [], i = [], n = [], o, a) => ({
2034
+ const o = (e, t = [], s = [], n = [], r, a) => ({
1646
2035
  measures: e,
1647
2036
  dimensions: t,
1648
- filters: i,
2037
+ filters: s,
1649
2038
  timeDimensions: n,
1650
- limit: o,
2039
+ limit: r,
1651
2040
  order: a
1652
2041
  });
1653
2042
  return {
1654
2043
  measures: (e) => ({
1655
2044
  dimensions: (t = []) => ({
1656
- filters: (i = []) => ({
2045
+ filters: (s = []) => ({
1657
2046
  timeDimensions: (n = []) => ({
1658
- limit: (o) => ({
1659
- order: (a) => s(e, t, i, n, o, a)
2047
+ limit: (r) => ({
2048
+ order: (a) => o(e, t, s, n, r, a)
1660
2049
  }),
1661
- order: (o) => s(e, t, i, n, void 0, o)
2050
+ order: (r) => o(e, t, s, n, void 0, r)
1662
2051
  }),
1663
2052
  limit: (n) => ({
1664
- order: (o) => s(e, t, i, [], n, o)
2053
+ order: (r) => o(e, t, s, [], n, r)
1665
2054
  }),
1666
- order: (n) => s(e, t, i, [], void 0, n)
2055
+ order: (n) => o(e, t, s, [], void 0, n)
1667
2056
  }),
1668
- timeDimensions: (i = []) => ({
2057
+ timeDimensions: (s = []) => ({
1669
2058
  filters: (n = []) => ({
1670
- limit: (o) => ({
1671
- order: (a) => s(e, t, n, i, o, a)
2059
+ limit: (r) => ({
2060
+ order: (a) => o(e, t, n, s, r, a)
1672
2061
  }),
1673
- order: (o) => s(e, t, n, i, void 0, o)
2062
+ order: (r) => o(e, t, n, s, void 0, r)
1674
2063
  }),
1675
2064
  limit: (n) => ({
1676
- order: (o) => s(e, t, [], i, n, o)
2065
+ order: (r) => o(e, t, [], s, n, r)
1677
2066
  }),
1678
- order: (n) => s(e, t, [], i, void 0, n)
2067
+ order: (n) => o(e, t, [], s, void 0, n)
1679
2068
  }),
1680
- limit: (i) => ({
1681
- order: (n) => s(e, t, [], [], i, n)
2069
+ limit: (s) => ({
2070
+ order: (n) => o(e, t, [], [], s, n)
1682
2071
  }),
1683
- order: (i) => s(e, t, [], [], void 0, i)
2072
+ order: (s) => o(e, t, [], [], void 0, s)
1684
2073
  }),
1685
2074
  filters: (t = []) => ({
1686
- dimensions: (i = []) => ({
2075
+ dimensions: (s = []) => ({
1687
2076
  timeDimensions: (n = []) => ({
1688
- limit: (o) => ({
1689
- order: (a) => s(e, i, t, n, o, a)
2077
+ limit: (r) => ({
2078
+ order: (a) => o(e, s, t, n, r, a)
1690
2079
  }),
1691
- order: (o) => s(e, i, t, n, void 0, o)
2080
+ order: (r) => o(e, s, t, n, void 0, r)
1692
2081
  }),
1693
2082
  limit: (n) => ({
1694
- order: (o) => s(e, i, t, [], n, o)
2083
+ order: (r) => o(e, s, t, [], n, r)
1695
2084
  }),
1696
- order: (n) => s(e, i, t, [], void 0, n)
2085
+ order: (n) => o(e, s, t, [], void 0, n)
1697
2086
  }),
1698
- timeDimensions: (i = []) => ({
2087
+ timeDimensions: (s = []) => ({
1699
2088
  dimensions: (n = []) => ({
1700
- limit: (o) => ({
1701
- order: (a) => s(e, n, t, i, o, a)
2089
+ limit: (r) => ({
2090
+ order: (a) => o(e, n, t, s, r, a)
1702
2091
  }),
1703
- order: (o) => s(e, n, t, i, void 0, o)
2092
+ order: (r) => o(e, n, t, s, void 0, r)
1704
2093
  }),
1705
2094
  limit: (n) => ({
1706
- order: (o) => s(e, [], t, i, n, o)
2095
+ order: (r) => o(e, [], t, s, n, r)
1707
2096
  }),
1708
- order: (n) => s(e, [], t, i, void 0, n)
2097
+ order: (n) => o(e, [], t, s, void 0, n)
1709
2098
  }),
1710
- limit: (i) => ({
1711
- order: (n) => s(e, [], t, [], i, n)
2099
+ limit: (s) => ({
2100
+ order: (n) => o(e, [], t, [], s, n)
1712
2101
  }),
1713
- order: (i) => s(e, [], t, [], void 0, i)
2102
+ order: (s) => o(e, [], t, [], void 0, s)
1714
2103
  })
1715
2104
  })
1716
2105
  };
@@ -1719,55 +2108,55 @@ const Ae = {
1719
2108
  * Create filters
1720
2109
  */
1721
2110
  filters: {
1722
- equals: (s, e) => ({ member: s, operator: "equals", values: [e] }),
1723
- notEquals: (s, e) => ({ member: s, operator: "notEquals", values: [e] }),
1724
- contains: (s, e) => ({ member: s, operator: "contains", values: [e] }),
1725
- greaterThan: (s, e) => ({ member: s, operator: "gt", values: [e] }),
1726
- lessThan: (s, e) => ({ member: s, operator: "lt", values: [e] }),
1727
- inDateRange: (s, e, t) => ({
1728
- member: s,
2111
+ equals: (o, e) => ({ member: o, operator: "equals", values: [e] }),
2112
+ notEquals: (o, e) => ({ member: o, operator: "notEquals", values: [e] }),
2113
+ contains: (o, e) => ({ member: o, operator: "contains", values: [e] }),
2114
+ greaterThan: (o, e) => ({ member: o, operator: "gt", values: [e] }),
2115
+ lessThan: (o, e) => ({ member: o, operator: "lt", values: [e] }),
2116
+ inDateRange: (o, e, t) => ({
2117
+ member: o,
1729
2118
  operator: "inDateRange",
1730
2119
  values: [e, t]
1731
2120
  }),
1732
- set: (s) => ({ member: s, operator: "set", values: [] }),
1733
- notSet: (s) => ({ member: s, operator: "notSet", values: [] })
2121
+ set: (o) => ({ member: o, operator: "set", values: [] }),
2122
+ notSet: (o) => ({ member: o, operator: "notSet", values: [] })
1734
2123
  },
1735
2124
  /**
1736
2125
  * Create time dimensions
1737
2126
  */
1738
2127
  timeDimensions: {
1739
- create: (s, e, t) => ({
1740
- dimension: s,
2128
+ create: (o, e, t) => ({
2129
+ dimension: o,
1741
2130
  granularity: e,
1742
2131
  dateRange: t
1743
2132
  })
1744
2133
  }
1745
2134
  };
1746
2135
  export {
1747
- x as BaseDatabaseExecutor,
1748
- ie as MultiCubeBuilder,
1749
- ee as MySQLExecutor,
1750
- X as PostgresExecutor,
1751
- $ as QueryExecutor,
1752
- q as SQLiteExecutor,
1753
- T as SemanticLayerCompiler,
1754
- Ae as SemanticLayerUtils,
1755
- ye as convertCubeReferences,
1756
- _ as createDatabaseExecutor,
1757
- Te as createDrizzleSemanticLayer,
1758
- ne as createMultiCubeContext,
1759
- te as createMySQLExecutor,
1760
- S as createPostgresExecutor,
2136
+ S as BaseDatabaseExecutor,
2137
+ ae as MultiCubeBuilder,
2138
+ ie as MySQLExecutor,
2139
+ ne as PostgresExecutor,
2140
+ T as QueryExecutor,
2141
+ se as SQLiteExecutor,
2142
+ x as SemanticLayerCompiler,
2143
+ Le as SemanticLayerUtils,
2144
+ Se as convertCubeReferences,
2145
+ L as createDatabaseExecutor,
2146
+ Me as createDrizzleSemanticLayer,
2147
+ oe as createMultiCubeContext,
2148
+ re as createMySQLExecutor,
2149
+ F as createPostgresExecutor,
1761
2150
  M as createSQLiteExecutor,
1762
- Ee as createSemanticLayer,
1763
- xe as defaultSemanticLayer,
1764
- Ne as defineCube,
1765
- we as defineLegacyCube,
1766
- pe as loadYamlCubes,
1767
- De as loadYamlCubesFromFile,
1768
- re as parseYamlCubes,
2151
+ ye as createSemanticLayer,
2152
+ Fe as defaultSemanticLayer,
2153
+ Ee as defineCube,
2154
+ $e as defineLegacyCube,
2155
+ we as loadYamlCubes,
2156
+ Te as loadYamlCubesFromFile,
2157
+ ue as parseYamlCubes,
1769
2158
  b as resolveSqlExpression,
1770
- $e as semanticCubeToYaml,
1771
- se as semanticLayer,
1772
- ae as yamlCubeToSemanticCube
2159
+ xe as semanticCubeToYaml,
2160
+ ce as semanticLayer,
2161
+ de as yamlCubeToSemanticCube
1773
2162
  };