drizzle-cube 0.1.4 → 0.1.6

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,9 +1,9 @@
1
- var U = Object.defineProperty;
2
- var k = (s, e, t) => e in s ? U(s, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : s[e] = t;
3
- var E = (s, e, t) => k(s, typeof e != "symbol" ? e + "" : e, t);
4
- import { sql as f, and as p, eq as _, count as $, 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 C, isNull as W, isNotNull as K, notInArray as H, ne as V, inArray as Z } from "drizzle-orm";
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
5
  import { parse as G, stringify as P } from "yaml";
6
- function Ce(s, e) {
6
+ function we(s, e) {
7
7
  return {
8
8
  ...e,
9
9
  name: e.name
@@ -19,16 +19,16 @@ class X extends x {
19
19
  if (e && typeof e == "object") {
20
20
  if (typeof e.execute == "function") {
21
21
  const n = await e.execute();
22
- return Array.isArray(n) ? n.map((r) => this.convertNumericFields(r, t)) : n;
22
+ return Array.isArray(n) ? n.map((o) => this.convertNumericFields(o, t)) : n;
23
23
  }
24
24
  if (this.db && typeof this.db.execute == "function")
25
25
  try {
26
26
  const n = await this.db.execute(e);
27
- return Array.isArray(n) ? n.map((r) => this.convertNumericFields(r, t)) : n;
27
+ return Array.isArray(n) ? n.map((o) => this.convertNumericFields(o, t)) : n;
28
28
  } catch (n) {
29
29
  if (typeof e.getSQL == "function") {
30
- const r = e.getSQL(), a = await this.db.execute(r);
31
- return Array.isArray(a) ? a.map((o) => this.convertNumericFields(o, t)) : a;
30
+ const o = e.getSQL(), a = await this.db.execute(o);
31
+ return Array.isArray(a) ? a.map((r) => this.convertNumericFields(r, t)) : a;
32
32
  }
33
33
  throw n;
34
34
  }
@@ -44,8 +44,8 @@ class X extends x {
44
44
  convertNumericFields(e, t) {
45
45
  if (!e || typeof e != "object") return e;
46
46
  const i = {};
47
- for (const [n, r] of Object.entries(e))
48
- t && t.includes(n) ? i[n] = this.coerceToNumber(r) : i[n] = r;
47
+ for (const [n, o] of Object.entries(e))
48
+ t && t.includes(n) ? i[n] = this.coerceToNumber(o) : i[n] = o;
49
49
  return i;
50
50
  }
51
51
  /**
@@ -104,8 +104,8 @@ class q extends x {
104
104
  convertNumericFields(e, t) {
105
105
  if (!e || typeof e != "object") return e;
106
106
  const i = {};
107
- for (const [n, r] of Object.entries(e))
108
- t && t.includes(n) ? i[n] = this.coerceToNumber(r) : i[n] = r;
107
+ for (const [n, o] of Object.entries(e))
108
+ t && t.includes(n) ? i[n] = this.coerceToNumber(o) : i[n] = o;
109
109
  return i;
110
110
  }
111
111
  /**
@@ -129,7 +129,7 @@ class ee extends x {
129
129
  async execute(e, t) {
130
130
  if (e && typeof e == "object" && typeof e.execute == "function") {
131
131
  const n = await e.execute();
132
- return Array.isArray(n) ? n.map((r) => this.convertNumericFields(r, t)) : n;
132
+ return Array.isArray(n) ? n.map((o) => this.convertNumericFields(o, t)) : n;
133
133
  }
134
134
  if (!this.db.execute)
135
135
  throw new Error("MySQL database instance must have an execute method");
@@ -142,8 +142,8 @@ class ee extends x {
142
142
  convertNumericFields(e, t) {
143
143
  if (!e || typeof e != "object") return e;
144
144
  const i = {};
145
- for (const [n, r] of Object.entries(e))
146
- t && t.includes(n) ? i[n] = this.coerceToNumber(r) : i[n] = r;
145
+ for (const [n, o] of Object.entries(e))
146
+ t && t.includes(n) ? i[n] = this.coerceToNumber(o) : i[n] = o;
147
147
  return i;
148
148
  }
149
149
  /**
@@ -172,7 +172,7 @@ function M(s, e) {
172
172
  function te(s, e) {
173
173
  return new ee(s, e);
174
174
  }
175
- function j(s, e, t) {
175
+ function _(s, e, t) {
176
176
  if (t)
177
177
  switch (t) {
178
178
  case "postgres":
@@ -231,15 +231,15 @@ class ie {
231
231
  * Build a multi-cube query plan
232
232
  */
233
233
  buildMultiCubeQueryPlan(e, t, i) {
234
- const n = this.analyzeCubeUsage(t), r = Array.from(n);
235
- if (r.length === 1)
234
+ const n = this.analyzeCubeUsage(t), o = Array.from(n);
235
+ if (o.length === 1)
236
236
  throw new Error("Single cube query should use QueryExecutor directly");
237
- const a = this.choosePrimaryCube(r, t), o = e.get(a);
238
- if (!o)
237
+ const a = this.choosePrimaryCube(o, t), r = e.get(a);
238
+ if (!r)
239
239
  throw new Error(`Primary cube '${a}' not found`);
240
- const c = this.buildJoinPlan(e, o, r, i.securityContext), l = this.buildMultiCubeSelections(e, t, i.securityContext), u = this.buildMultiCubeWhereConditions(e, t, i), m = this.buildMultiCubeGroupByFields(e, t, i.securityContext);
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);
241
241
  return {
242
- primaryCube: o,
242
+ primaryCube: r,
243
243
  joinCubes: c,
244
244
  selections: l,
245
245
  whereConditions: u,
@@ -264,13 +264,13 @@ class ie {
264
264
  * Build join plan for multi-cube query
265
265
  */
266
266
  buildJoinPlan(e, t, i, n) {
267
- var o;
268
- const r = [], a = i.filter((c) => c !== t.name);
267
+ var r;
268
+ const o = [], a = i.filter((c) => c !== t.name);
269
269
  for (const c of a) {
270
270
  const l = e.get(c);
271
271
  if (!l)
272
272
  throw new Error(`Cube '${c}' not found`);
273
- const u = (o = t.joins) == null ? void 0 : o[c];
273
+ const u = (r = t.joins) == null ? void 0 : r[c];
274
274
  if (!u)
275
275
  throw new Error(`No join definition found from '${t.name}' to '${c}'`);
276
276
  const m = ne(
@@ -284,20 +284,20 @@ class ie {
284
284
  e,
285
285
  l
286
286
  ), d = u.condition(m);
287
- r.push({
287
+ o.push({
288
288
  cube: l,
289
289
  alias: `${c.toLowerCase()}_cube`,
290
290
  joinType: u.type || "left",
291
291
  joinCondition: d
292
292
  });
293
293
  }
294
- return r;
294
+ return o;
295
295
  }
296
296
  /**
297
297
  * Build selections across multiple cubes
298
298
  */
299
299
  buildMultiCubeSelections(e, t, i) {
300
- const n = {}, r = {
300
+ const n = {}, o = {
301
301
  db: {},
302
302
  // Filled during execution
303
303
  schema: {},
@@ -306,28 +306,28 @@ class ie {
306
306
  };
307
307
  if (t.dimensions)
308
308
  for (const a of t.dimensions) {
309
- const [o, c] = a.split("."), l = e.get(o);
309
+ const [r, c] = a.split("."), l = e.get(r);
310
310
  if (l && l.dimensions[c]) {
311
- const u = l.dimensions[c], m = b(u.sql, r);
311
+ const u = l.dimensions[c], m = b(u.sql, o);
312
312
  n[a] = f`${m}`.as(a);
313
313
  }
314
314
  }
315
315
  if (t.measures)
316
316
  for (const a of t.measures) {
317
- const [o, c] = a.split("."), l = e.get(o);
317
+ const [r, c] = a.split("."), l = e.get(r);
318
318
  if (l && l.measures[c]) {
319
- const u = l.measures[c], m = this.buildMeasureExpression(u, r);
319
+ const u = l.measures[c], m = this.buildMeasureExpression(u, o);
320
320
  n[a] = f`${m}`.as(a);
321
321
  }
322
322
  }
323
323
  if (t.timeDimensions)
324
324
  for (const a of t.timeDimensions) {
325
- const [o, c] = a.dimension.split("."), l = e.get(o);
325
+ const [r, c] = a.dimension.split("."), l = e.get(r);
326
326
  if (l && l.dimensions[c]) {
327
327
  const u = l.dimensions[c], m = this.buildTimeDimensionExpression(
328
328
  u.sql,
329
329
  a.granularity,
330
- r
330
+ o
331
331
  );
332
332
  n[a.dimension] = f`${m}`.as(a.dimension);
333
333
  }
@@ -340,7 +340,7 @@ class ie {
340
340
  buildMeasureExpression(e, t) {
341
341
  let i = b(e.sql, t);
342
342
  if (e.filters && e.filters.length > 0) {
343
- const n = e.filters.map((r) => r(t));
343
+ const n = e.filters.map((o) => o(t));
344
344
  i = f`CASE WHEN ${p(...n)} THEN ${i} END`;
345
345
  }
346
346
  switch (e.type) {
@@ -396,11 +396,11 @@ class ie {
396
396
  buildMultiCubeWhereConditions(e, t, i) {
397
397
  const n = [];
398
398
  if (t.filters) {
399
- for (const r of t.filters)
400
- if ("member" in r) {
401
- const [a] = r.member.split("."), o = e.get(a);
402
- if (o) {
403
- const c = this.buildFilterCondition(r, o, i);
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
404
  c && n.push(c);
405
405
  }
406
406
  }
@@ -412,12 +412,12 @@ class ie {
412
412
  */
413
413
  buildFilterCondition(e, t, i) {
414
414
  if (e.operator === "equals" && e.values && e.values.length > 0) {
415
- const [n, r] = e.member.split(".");
415
+ const [n, o] = e.member.split(".");
416
416
  if (n === t.name) {
417
- const a = t.dimensions[r] || t.measures[r];
417
+ const a = t.dimensions[o] || t.measures[o];
418
418
  if (a) {
419
- const o = typeof a.sql == "function" ? a.sql(i) : a.sql;
420
- return _(o, e.values[0]);
419
+ const r = typeof a.sql == "function" ? a.sql(i) : a.sql;
420
+ return v(r, e.values[0]);
421
421
  }
422
422
  }
423
423
  }
@@ -436,20 +436,20 @@ class ie {
436
436
  securityContext: i
437
437
  };
438
438
  if (t.dimensions)
439
- for (const o of t.dimensions) {
440
- const [c, l] = o.split("."), u = e.get(c);
439
+ for (const r of t.dimensions) {
440
+ const [c, l] = r.split("."), u = e.get(c);
441
441
  if (u && u.dimensions[l]) {
442
442
  const m = u.dimensions[l], d = b(m.sql, a);
443
443
  n.push(d);
444
444
  }
445
445
  }
446
446
  if (t.timeDimensions)
447
- for (const o of t.timeDimensions) {
448
- const [c, l] = o.dimension.split("."), u = e.get(c);
447
+ for (const r of t.timeDimensions) {
448
+ const [c, l] = r.dimension.split("."), u = e.get(c);
449
449
  if (u && u.dimensions[l]) {
450
450
  const m = u.dimensions[l], d = this.buildTimeDimensionExpression(
451
451
  m.sql,
452
- o.granularity,
452
+ r.granularity,
453
453
  a
454
454
  );
455
455
  n.push(d);
@@ -458,9 +458,9 @@ class ie {
458
458
  return n;
459
459
  }
460
460
  }
461
- class y {
461
+ class $ {
462
462
  constructor(e) {
463
- E(this, "multiCubeBuilder");
463
+ C(this, "multiCubeBuilder");
464
464
  this.dbExecutor = e, this.multiCubeBuilder = new ie();
465
465
  }
466
466
  /**
@@ -468,17 +468,17 @@ class y {
468
468
  */
469
469
  async execute(e, t, i) {
470
470
  try {
471
- const n = v(e, t);
471
+ const n = j(e, t);
472
472
  if (!n.isValid)
473
473
  throw new Error(`Query validation failed: ${n.errors.join(", ")}`);
474
- const r = this.multiCubeBuilder.analyzeCubeUsage(t);
475
- if (r.size === 0)
474
+ const o = this.multiCubeBuilder.analyzeCubeUsage(t);
475
+ if (o.size === 0)
476
476
  throw new Error("No cubes found for query");
477
- if (r.size === 1) {
478
- const a = Array.from(r)[0], o = e.get(a);
479
- if (!o)
477
+ if (o.size === 1) {
478
+ const a = Array.from(o)[0], r = e.get(a);
479
+ if (!r)
480
480
  throw new Error(`Cube '${a}' not found`);
481
- return this.executeSingleCube(o, t, i);
481
+ return this.executeSingleCube(r, t, i);
482
482
  } else
483
483
  return this.executeMultiCube(e, t, i);
484
484
  } catch (n) {
@@ -507,57 +507,57 @@ class y {
507
507
  db: this.dbExecutor.db,
508
508
  schema: this.dbExecutor.schema,
509
509
  securityContext: i
510
- }, r = e.sql(n), a = this.buildSelections(e, t, n);
511
- let o = n.db.select(a).from(r.from);
512
- if (r.joins)
513
- for (const h of r.joins)
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
514
  switch (h.type || "left") {
515
515
  case "left":
516
- o = o.leftJoin(h.table, h.on);
516
+ r = r.leftJoin(h.table, h.on);
517
517
  break;
518
518
  case "inner":
519
- o = o.innerJoin(h.table, h.on);
519
+ r = r.innerJoin(h.table, h.on);
520
520
  break;
521
521
  case "right":
522
- o = o.rightJoin(h.table, h.on);
522
+ r = r.rightJoin(h.table, h.on);
523
523
  break;
524
524
  case "full":
525
- o = o.fullJoin(h.table, h.on);
525
+ r = r.fullJoin(h.table, h.on);
526
526
  break;
527
527
  }
528
- r.where && (o = o.where(r.where));
528
+ o.where && (r = r.where(o.where));
529
529
  const c = this.buildWhereConditions(e, t, n);
530
530
  if (c.length > 0) {
531
531
  const h = c.length === 1 ? c[0] : p(...c);
532
- o = o.where(h);
532
+ r = r.where(h);
533
533
  }
534
534
  const l = this.buildGroupByFields(e, t, n);
535
- l.length > 0 && (o = o.groupBy(...l));
535
+ l.length > 0 && (r = r.groupBy(...l));
536
536
  const u = this.buildOrderBy(t);
537
- if (u.length > 0 && (o = o.orderBy(...u)), t.limit !== void 0) {
537
+ if (u.length > 0 && (r = r.orderBy(...u)), t.limit !== void 0) {
538
538
  if (t.limit < 0)
539
539
  throw new Error("Limit must be non-negative");
540
- o = o.limit(t.limit);
540
+ r = r.limit(t.limit);
541
541
  }
542
542
  if (t.offset !== void 0) {
543
543
  if (t.offset < 0)
544
544
  throw new Error("Offset must be non-negative");
545
- o = o.offset(t.offset);
545
+ r = r.offset(t.offset);
546
546
  }
547
- const m = t.measures || [], d = await this.dbExecutor.execute(o, m), Q = Array.isArray(d) ? d.map((h) => {
548
- const N = { ...h };
547
+ const m = t.measures || [], d = await this.dbExecutor.execute(r, m), Q = Array.isArray(d) ? d.map((h) => {
548
+ const E = { ...h };
549
549
  if (t.timeDimensions) {
550
550
  for (const D of t.timeDimensions)
551
- if (D.dimension in N) {
552
- let g = N[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")), N[D.dimension] = g;
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;
554
554
  }
555
555
  }
556
- return N;
557
- }) : [d], z = this.generateAnnotations(e, t);
556
+ return E;
557
+ }) : [d], k = this.generateAnnotations(e, t);
558
558
  return {
559
559
  data: Q,
560
- annotation: z
560
+ annotation: k
561
561
  };
562
562
  } catch (n) {
563
563
  throw new Error(`Cube query execution failed: ${n instanceof Error ? n.message : "Unknown error"}`);
@@ -567,11 +567,11 @@ class y {
567
567
  * Execute multi-cube query using JOIN resolution
568
568
  */
569
569
  async executeMultiCube(e, t, i) {
570
- const n = this.buildMultiCubeQuery(e, t, i), r = t.measures || [], a = await this.dbExecutor.execute(n, r), o = {
570
+ const n = this.buildMultiCubeQuery(e, t, i), o = t.measures || [], a = await this.dbExecutor.execute(n, o), r = {
571
571
  db: this.dbExecutor.db,
572
572
  schema: this.dbExecutor.schema,
573
573
  securityContext: i
574
- }, c = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, o), l = this.generateMultiCubeAnnotations(c, t);
574
+ }, c = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, r), l = this.generateMultiCubeAnnotations(c, t);
575
575
  return {
576
576
  data: Array.isArray(a) ? a : [a],
577
577
  annotation: l
@@ -587,10 +587,10 @@ class y {
587
587
  * Generate raw SQL for multi-cube queries without execution
588
588
  */
589
589
  async generateMultiCubeSQL(e, t, i) {
590
- const r = this.buildMultiCubeQuery(e, t, i).toSQL();
590
+ const o = this.buildMultiCubeQuery(e, t, i).toSQL();
591
591
  return {
592
- sql: r.sql,
593
- params: r.params
592
+ sql: o.sql,
593
+ params: o.params
594
594
  };
595
595
  }
596
596
  /**
@@ -601,42 +601,42 @@ class y {
601
601
  db: this.dbExecutor.db,
602
602
  schema: this.dbExecutor.schema,
603
603
  securityContext: i
604
- }, r = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, n), a = r.primaryCube.sql(n);
605
- let o = n.db.select(r.selections).from(a.from);
604
+ }, o = this.multiCubeBuilder.buildMultiCubeQueryPlan(e, t, n), a = o.primaryCube.sql(n);
605
+ let r = n.db.select(o.selections).from(a.from);
606
606
  if (a.joins)
607
607
  for (const u of a.joins)
608
608
  switch (u.type || "left") {
609
609
  case "left":
610
- o = o.leftJoin(u.table, u.on);
610
+ r = r.leftJoin(u.table, u.on);
611
611
  break;
612
612
  case "inner":
613
- o = o.innerJoin(u.table, u.on);
613
+ r = r.innerJoin(u.table, u.on);
614
614
  break;
615
615
  case "right":
616
- o = o.rightJoin(u.table, u.on);
616
+ r = r.rightJoin(u.table, u.on);
617
617
  break;
618
618
  case "full":
619
- o = o.fullJoin(u.table, u.on);
619
+ r = r.fullJoin(u.table, u.on);
620
620
  break;
621
621
  default:
622
- o = o.leftJoin(u.table, u.on);
622
+ r = r.leftJoin(u.table, u.on);
623
623
  }
624
- if (r.joinCubes && r.joinCubes.length > 0)
625
- for (const u of r.joinCubes) {
624
+ if (o.joinCubes && o.joinCubes.length > 0)
625
+ for (const u of o.joinCubes) {
626
626
  const m = u.cube.sql(n);
627
627
  try {
628
628
  switch (u.joinType || "left") {
629
629
  case "left":
630
- o = o.leftJoin(m.from, u.joinCondition);
630
+ r = r.leftJoin(m.from, u.joinCondition);
631
631
  break;
632
632
  case "inner":
633
- o = o.innerJoin(m.from, u.joinCondition);
633
+ r = r.innerJoin(m.from, u.joinCondition);
634
634
  break;
635
635
  case "right":
636
- o = o.rightJoin(m.from, u.joinCondition);
636
+ r = r.rightJoin(m.from, u.joinCondition);
637
637
  break;
638
638
  case "full":
639
- o = o.fullJoin(m.from, u.joinCondition);
639
+ r = r.fullJoin(m.from, u.joinCondition);
640
640
  break;
641
641
  }
642
642
  } catch (d) {
@@ -644,23 +644,23 @@ class y {
644
644
  }
645
645
  }
646
646
  const c = [];
647
- if (a.where && c.push(a.where), r.whereConditions.length > 0 && c.push(...r.whereConditions), c.length > 0) {
647
+ if (a.where && c.push(a.where), o.whereConditions.length > 0 && c.push(...o.whereConditions), c.length > 0) {
648
648
  const u = c.length === 1 ? c[0] : p(...c);
649
- o = o.where(u);
649
+ r = r.where(u);
650
650
  }
651
- r.groupByFields.length > 0 && (o = o.groupBy(...r.groupByFields));
651
+ o.groupByFields.length > 0 && (r = r.groupBy(...o.groupByFields));
652
652
  const l = this.buildOrderBy(t);
653
- if (l.length > 0 && (o = o.orderBy(...l)), t.limit !== void 0) {
653
+ if (l.length > 0 && (r = r.orderBy(...l)), t.limit !== void 0) {
654
654
  if (t.limit < 0)
655
655
  throw new Error("Limit must be non-negative");
656
- o = o.limit(t.limit);
656
+ r = r.limit(t.limit);
657
657
  }
658
658
  if (t.offset !== void 0) {
659
659
  if (t.offset < 0)
660
660
  throw new Error("Offset must be non-negative");
661
- o = o.offset(t.offset);
661
+ r = r.offset(t.offset);
662
662
  }
663
- return o;
663
+ return r;
664
664
  }
665
665
  /**
666
666
  * Generate SQL for Cube
@@ -670,44 +670,44 @@ class y {
670
670
  db: this.dbExecutor.db,
671
671
  schema: this.dbExecutor.schema,
672
672
  securityContext: i
673
- }, r = e.sql(n), a = this.buildSelections(e, t, n);
674
- let o = n.db.select(a).from(r.from);
675
- if (r.joins)
676
- for (const d of r.joins)
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
677
  switch (d.type || "left") {
678
678
  case "left":
679
- o = o.leftJoin(d.table, d.on);
679
+ r = r.leftJoin(d.table, d.on);
680
680
  break;
681
681
  case "inner":
682
- o = o.innerJoin(d.table, d.on);
682
+ r = r.innerJoin(d.table, d.on);
683
683
  break;
684
684
  case "right":
685
- o = o.rightJoin(d.table, d.on);
685
+ r = r.rightJoin(d.table, d.on);
686
686
  break;
687
687
  case "full":
688
- o = o.fullJoin(d.table, d.on);
688
+ r = r.fullJoin(d.table, d.on);
689
689
  break;
690
690
  }
691
- r.where && (o = o.where(r.where));
691
+ o.where && (r = r.where(o.where));
692
692
  const c = this.buildWhereConditions(e, t, n);
693
693
  if (c.length > 0) {
694
694
  const d = c.length === 1 ? c[0] : p(...c);
695
- o = o.where(d);
695
+ r = r.where(d);
696
696
  }
697
697
  const l = this.buildGroupByFields(e, t, n);
698
- l.length > 0 && (o = o.groupBy(...l));
698
+ l.length > 0 && (r = r.groupBy(...l));
699
699
  const u = this.buildOrderBy(t);
700
- if (u.length > 0 && (o = o.orderBy(...u)), t.limit !== void 0) {
700
+ if (u.length > 0 && (r = r.orderBy(...u)), t.limit !== void 0) {
701
701
  if (t.limit < 0)
702
702
  throw new Error("Limit must be non-negative");
703
- o = o.limit(t.limit);
703
+ r = r.limit(t.limit);
704
704
  }
705
705
  if (t.offset !== void 0) {
706
706
  if (t.offset < 0)
707
707
  throw new Error("Offset must be non-negative");
708
- o = o.offset(t.offset);
708
+ r = r.offset(t.offset);
709
709
  }
710
- const m = o.toSQL();
710
+ const m = r.toSQL();
711
711
  return {
712
712
  sql: m.sql,
713
713
  params: m.params
@@ -719,34 +719,34 @@ class y {
719
719
  buildSelections(e, t, i) {
720
720
  const n = {};
721
721
  if (t.dimensions)
722
- for (const r of t.dimensions) {
723
- const [a, o] = r.split(".");
724
- if (a === e.name && e.dimensions[o]) {
725
- const c = e.dimensions[o], l = b(c.sql, i);
726
- n[r] = f`${l}`.as(r);
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);
727
727
  }
728
728
  }
729
729
  if (t.measures)
730
- for (const r of t.measures) {
731
- const [a, o] = r.split(".");
732
- if (a === e.name && e.measures[o]) {
733
- const c = e.measures[o], l = this.buildMeasureExpression(c, i);
734
- n[r] = f`${l}`.as(r);
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);
735
735
  }
736
736
  }
737
737
  if (t.timeDimensions)
738
- for (const r of t.timeDimensions) {
739
- const [a, o] = r.dimension.split(".");
740
- if (a === e.name && e.dimensions[o]) {
741
- const c = e.dimensions[o], l = this.buildTimeDimensionExpression(
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(
742
742
  c.sql,
743
- r.granularity,
743
+ o.granularity,
744
744
  i
745
745
  );
746
- n[r.dimension] = f`${l}`.as(r.dimension);
746
+ n[o.dimension] = f`${l}`.as(o.dimension);
747
747
  }
748
748
  }
749
- return Object.keys(n).length === 0 && (n.count = $()), n;
749
+ return Object.keys(n).length === 0 && (n.count = y()), n;
750
750
  }
751
751
  /**
752
752
  * Build measure expression with aggregation and filters for Cube
@@ -754,12 +754,12 @@ class y {
754
754
  buildMeasureExpression(e, t) {
755
755
  let i = b(e.sql, t);
756
756
  if (e.filters && e.filters.length > 0) {
757
- const n = e.filters.map((r) => r(t));
757
+ const n = e.filters.map((o) => o(t));
758
758
  i = f`CASE WHEN ${p(...n)} THEN ${i} END`;
759
759
  }
760
760
  switch (e.type) {
761
761
  case "count":
762
- return $(i);
762
+ return y(i);
763
763
  case "countDistinct":
764
764
  return Y(i);
765
765
  case "sum":
@@ -773,7 +773,7 @@ class y {
773
773
  case "number":
774
774
  return i;
775
775
  default:
776
- return $(i);
776
+ return y(i);
777
777
  }
778
778
  }
779
779
  /**
@@ -810,15 +810,15 @@ class y {
810
810
  buildWhereConditions(e, t, i) {
811
811
  const n = [];
812
812
  if (t.filters && t.filters.length > 0)
813
- for (const r of t.filters) {
814
- const a = this.processFilter(r, e, i);
813
+ for (const o of t.filters) {
814
+ const a = this.processFilter(o, e, i);
815
815
  a && n.push(a);
816
816
  }
817
817
  if (t.timeDimensions)
818
- for (const r of t.timeDimensions) {
819
- const [a, o] = r.dimension.split(".");
820
- if (a === e.name && e.dimensions[o] && r.dateRange) {
821
- const c = e.dimensions[o], l = b(c.sql, i), u = this.buildDateRangeCondition(l, r.dateRange);
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
822
  u && n.push(u);
823
823
  }
824
824
  }
@@ -839,11 +839,11 @@ class y {
839
839
  return u.length > 0 ? J(...u) : null;
840
840
  }
841
841
  }
842
- const n = e, [r, a] = n.member.split(".");
843
- if (r !== t.name) return null;
844
- const o = t.dimensions[a] || t.measures[a];
845
- if (!o) return null;
846
- const c = b(o.sql, i);
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);
847
847
  return this.buildFilterCondition(c, n.operator, n.values);
848
848
  }
849
849
  /**
@@ -855,48 +855,48 @@ class y {
855
855
  const n = i.filter((a) => !(a == null || a === "" || typeof a == "string" && a.includes("\0")));
856
856
  if (n.length === 0 && !["set", "notSet"].includes(t))
857
857
  return t === "equals" ? f`FALSE` : null;
858
- const r = n[0];
858
+ const o = n[0];
859
859
  switch (t) {
860
860
  case "equals":
861
- return n.length > 1 ? Z(e, n) : n.length === 1 ? _(e, r) : f`FALSE`;
861
+ return n.length > 1 ? Z(e, n) : n.length === 1 ? v(e, o) : f`FALSE`;
862
862
  case "notEquals":
863
- return n.length > 1 ? H(e, n) : n.length === 1 ? V(e, r) : null;
863
+ return n.length > 1 ? H(e, n) : n.length === 1 ? V(e, o) : null;
864
864
  case "contains":
865
- return f`${e} ILIKE ${"%" + r + "%"}`;
865
+ return f`${e} ILIKE ${"%" + o + "%"}`;
866
866
  case "notContains":
867
- return f`${e} NOT ILIKE ${"%" + r + "%"}`;
867
+ return f`${e} NOT ILIKE ${"%" + o + "%"}`;
868
868
  case "startsWith":
869
- return f`${e} ILIKE ${r + "%"}`;
869
+ return f`${e} ILIKE ${o + "%"}`;
870
870
  case "endsWith":
871
- return f`${e} ILIKE ${"%" + r}`;
871
+ return f`${e} ILIKE ${"%" + o}`;
872
872
  case "gt":
873
- return A(e, r);
873
+ return A(e, o);
874
874
  case "gte":
875
- return w(e, r);
875
+ return w(e, o);
876
876
  case "lt":
877
- return F(e, r);
877
+ return F(e, o);
878
878
  case "lte":
879
- return C(e, r);
879
+ return N(e, o);
880
880
  case "set":
881
881
  return K(e);
882
882
  case "notSet":
883
883
  return W(e);
884
884
  case "inDateRange":
885
885
  if (n.length >= 2) {
886
- const a = this.normalizeDate(n[0]), o = this.normalizeDate(n[1]);
887
- if (a && o)
886
+ const a = this.normalizeDate(n[0]), r = this.normalizeDate(n[1]);
887
+ if (a && r)
888
888
  return p(
889
889
  w(e, a),
890
- C(e, o)
890
+ N(e, r)
891
891
  );
892
892
  }
893
893
  return null;
894
894
  case "beforeDate": {
895
- const a = this.normalizeDate(r);
895
+ const a = this.normalizeDate(o);
896
896
  return a ? F(e, a) : null;
897
897
  }
898
898
  case "afterDate": {
899
- const a = this.normalizeDate(r);
899
+ const a = this.normalizeDate(o);
900
900
  return a ? A(e, a) : null;
901
901
  }
902
902
  default:
@@ -912,7 +912,7 @@ class y {
912
912
  const i = this.normalizeDate(t[0]), n = this.normalizeDate(t[1]);
913
913
  return !i || !n ? null : p(
914
914
  w(e, i),
915
- C(e, n)
915
+ N(e, n)
916
916
  );
917
917
  }
918
918
  if (typeof t == "string") {
@@ -920,16 +920,16 @@ class y {
920
920
  if (i)
921
921
  return p(
922
922
  w(e, i.start),
923
- C(e, i.end)
923
+ N(e, i.end)
924
924
  );
925
925
  const n = this.normalizeDate(t);
926
926
  if (!n) return null;
927
- const r = new Date(n);
928
- r.setUTCHours(0, 0, 0, 0);
927
+ const o = new Date(n);
928
+ o.setUTCHours(0, 0, 0, 0);
929
929
  const a = new Date(n);
930
930
  return a.setUTCHours(23, 59, 59, 999), p(
931
- w(e, r),
932
- C(e, a)
931
+ w(e, o),
932
+ N(e, a)
933
933
  );
934
934
  }
935
935
  return null;
@@ -940,27 +940,27 @@ class y {
940
940
  parseRelativeDateRange(e) {
941
941
  const t = /* @__PURE__ */ new Date(), i = e.toLowerCase().trim(), n = i.match(/^last\s+(\d+)\s+days?$/);
942
942
  if (n) {
943
- const o = parseInt(n[1], 10), c = new Date(t);
944
- c.setDate(t.getDate() - o), c.setHours(0, 0, 0, 0);
943
+ const r = parseInt(n[1], 10), c = new Date(t);
944
+ c.setDate(t.getDate() - r), c.setHours(0, 0, 0, 0);
945
945
  const l = new Date(t);
946
946
  return l.setHours(23, 59, 59, 999), { start: c, end: l };
947
947
  }
948
948
  if (i === "this month") {
949
- const o = 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: o, end: c };
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 };
951
951
  }
952
- const r = i.match(/^last\s+(\d+)\s+months?$/);
953
- if (r) {
954
- const o = parseInt(r[1], 10), c = new Date(t.getFullYear(), t.getMonth() - o, 1, 0, 0, 0, 0), l = new Date(t);
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
955
  return l.setHours(23, 59, 59, 999), { start: c, end: l };
956
956
  }
957
957
  if (i === "this year") {
958
- const o = new Date(t.getFullYear(), 0, 1, 0, 0, 0, 0), c = new Date(t.getFullYear(), 11, 31, 23, 59, 59, 999);
959
- return { start: o, end: c };
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 };
960
960
  }
961
961
  const a = i.match(/^last\s+(\d+)\s+years?$/);
962
962
  if (a) {
963
- const o = parseInt(a[1], 10), c = new Date(t.getFullYear() - o, 0, 1, 0, 0, 0, 0), l = new Date(t);
963
+ const r = parseInt(a[1], 10), c = new Date(t.getFullYear() - r, 0, 1, 0, 0, 0, 0), l = new Date(t);
964
964
  return l.setHours(23, 59, 59, 999), { start: c, end: l };
965
965
  }
966
966
  return null;
@@ -986,20 +986,20 @@ class y {
986
986
  buildGroupByFields(e, t, i) {
987
987
  const n = [];
988
988
  if (t.dimensions)
989
- for (const r of t.dimensions) {
990
- const [a, o] = r.split(".");
991
- if (a === e.name && e.dimensions[o]) {
992
- const c = e.dimensions[o], l = b(c.sql, i);
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
993
  n.push(l);
994
994
  }
995
995
  }
996
996
  if (t.timeDimensions)
997
- for (const r of t.timeDimensions) {
998
- const [a, o] = r.dimension.split(".");
999
- if (a === e.name && e.dimensions[o]) {
1000
- const c = e.dimensions[o], l = this.buildTimeDimensionExpression(
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(
1001
1001
  c.sql,
1002
- r.granularity,
1002
+ o.granularity,
1003
1003
  i
1004
1004
  );
1005
1005
  n.push(l);
@@ -1011,24 +1011,24 @@ class y {
1011
1011
  * Build ORDER BY clause with automatic time dimension sorting
1012
1012
  */
1013
1013
  buildOrderBy(e, t) {
1014
- var r;
1014
+ var o;
1015
1015
  const i = [], n = t || [
1016
1016
  ...e.measures || [],
1017
1017
  ...e.dimensions || [],
1018
- ...((r = e.timeDimensions) == null ? void 0 : r.map((a) => a.dimension)) || []
1018
+ ...((o = e.timeDimensions) == null ? void 0 : o.map((a) => a.dimension)) || []
1019
1019
  ];
1020
1020
  if (e.order && Object.keys(e.order).length > 0)
1021
- for (const [a, o] of Object.entries(e.order)) {
1021
+ for (const [a, r] of Object.entries(e.order)) {
1022
1022
  if (!n.includes(a))
1023
1023
  throw new Error(`Cannot order by '${a}': field is not selected in the query`);
1024
- const c = o === "desc" ? f`DESC` : f`ASC`;
1024
+ const c = r === "desc" ? f`DESC` : f`ASC`;
1025
1025
  i.push(f`${f.identifier(a)} ${c}`);
1026
1026
  }
1027
1027
  if (e.timeDimensions && e.timeDimensions.length > 0) {
1028
- const a = new Set(Object.keys(e.order || {})), o = [...e.timeDimensions].sort(
1028
+ const a = new Set(Object.keys(e.order || {})), r = [...e.timeDimensions].sort(
1029
1029
  (c, l) => c.dimension.localeCompare(l.dimension)
1030
1030
  );
1031
- for (const c of o)
1031
+ for (const c of r)
1032
1032
  a.has(c.dimension) || i.push(f`${f.identifier(c.dimension)} ASC`);
1033
1033
  }
1034
1034
  return i;
@@ -1037,11 +1037,11 @@ class y {
1037
1037
  * Generate annotations for UI metadata
1038
1038
  */
1039
1039
  generateAnnotations(e, t) {
1040
- const i = {}, n = {}, r = {};
1040
+ const i = {}, n = {}, o = {};
1041
1041
  if (t.measures)
1042
1042
  for (const a of t.measures) {
1043
- const [o, c] = a.split(".");
1044
- if (o === e.name && e.measures[c]) {
1043
+ const [r, c] = a.split(".");
1044
+ if (r === e.name && e.measures[c]) {
1045
1045
  const l = e.measures[c];
1046
1046
  i[a] = {
1047
1047
  title: l.title || c,
@@ -1052,8 +1052,8 @@ class y {
1052
1052
  }
1053
1053
  if (t.dimensions)
1054
1054
  for (const a of t.dimensions) {
1055
- const [o, c] = a.split(".");
1056
- if (o === e.name && e.dimensions[c]) {
1055
+ const [r, c] = a.split(".");
1056
+ if (r === e.name && e.dimensions[c]) {
1057
1057
  const l = e.dimensions[c];
1058
1058
  n[a] = {
1059
1059
  title: l.title || c,
@@ -1064,10 +1064,10 @@ class y {
1064
1064
  }
1065
1065
  if (t.timeDimensions)
1066
1066
  for (const a of t.timeDimensions) {
1067
- const [o, c] = a.dimension.split(".");
1068
- if (o === e.name && e.dimensions[c]) {
1067
+ const [r, c] = a.dimension.split(".");
1068
+ if (r === e.name && e.dimensions[c]) {
1069
1069
  const l = e.dimensions[c];
1070
- r[a.dimension] = {
1070
+ o[a.dimension] = {
1071
1071
  title: l.title || c,
1072
1072
  shortTitle: l.title || c,
1073
1073
  type: l.type,
@@ -1079,20 +1079,20 @@ class y {
1079
1079
  measures: i,
1080
1080
  dimensions: n,
1081
1081
  segments: {},
1082
- timeDimensions: r
1082
+ timeDimensions: o
1083
1083
  };
1084
1084
  }
1085
1085
  /**
1086
1086
  * Generate annotations for multi-cube queries
1087
1087
  */
1088
1088
  generateMultiCubeAnnotations(e, t) {
1089
- const i = {}, n = {}, r = {}, a = [e.primaryCube];
1090
- if (e.joinCubes && a.push(...e.joinCubes.map((o) => o.cube)), t.measures)
1091
- for (const o of t.measures) {
1092
- const [c, l] = o.split("."), u = a.find((m) => m.name === c);
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
1093
  if (u && u.measures[l]) {
1094
1094
  const m = u.measures[l];
1095
- i[o] = {
1095
+ i[r] = {
1096
1096
  title: m.title || l,
1097
1097
  shortTitle: m.title || l,
1098
1098
  type: m.type
@@ -1100,11 +1100,11 @@ class y {
1100
1100
  }
1101
1101
  }
1102
1102
  if (t.dimensions)
1103
- for (const o of t.dimensions) {
1104
- const [c, l] = o.split("."), u = a.find((m) => m.name === c);
1103
+ for (const r of t.dimensions) {
1104
+ const [c, l] = r.split("."), u = a.find((m) => m.name === c);
1105
1105
  if (u && u.dimensions[l]) {
1106
1106
  const m = u.dimensions[l];
1107
- n[o] = {
1107
+ n[r] = {
1108
1108
  title: m.title || l,
1109
1109
  shortTitle: m.title || l,
1110
1110
  type: m.type
@@ -1112,15 +1112,15 @@ class y {
1112
1112
  }
1113
1113
  }
1114
1114
  if (t.timeDimensions)
1115
- for (const o of t.timeDimensions) {
1116
- const [c, l] = o.dimension.split("."), u = a.find((m) => m.name === c);
1115
+ for (const r of t.timeDimensions) {
1116
+ const [c, l] = r.dimension.split("."), u = a.find((m) => m.name === c);
1117
1117
  if (u && u.dimensions && u.dimensions[l]) {
1118
1118
  const m = u.dimensions[l];
1119
- r[o.dimension] = {
1119
+ o[r.dimension] = {
1120
1120
  title: m.title || l,
1121
1121
  shortTitle: m.title || l,
1122
1122
  type: m.type,
1123
- granularity: o.granularity
1123
+ granularity: r.granularity
1124
1124
  };
1125
1125
  }
1126
1126
  }
@@ -1128,15 +1128,19 @@ class y {
1128
1128
  measures: i,
1129
1129
  dimensions: n,
1130
1130
  segments: {},
1131
- timeDimensions: r
1131
+ timeDimensions: o
1132
1132
  };
1133
1133
  }
1134
1134
  }
1135
1135
  class T {
1136
+ // 5 minutes in milliseconds
1136
1137
  constructor(e) {
1137
- E(this, "cubes", /* @__PURE__ */ new Map());
1138
- E(this, "dbExecutor");
1139
- e != null && e.databaseExecutor ? this.dbExecutor = e.databaseExecutor : e != null && e.drizzle && (this.dbExecutor = j(
1138
+ C(this, "cubes", /* @__PURE__ */ new Map());
1139
+ C(this, "dbExecutor");
1140
+ C(this, "metadataCache");
1141
+ C(this, "metadataCacheTimestamp");
1142
+ C(this, "METADATA_CACHE_TTL", 5 * 60 * 1e3);
1143
+ e != null && e.databaseExecutor ? this.dbExecutor = e.databaseExecutor : e != null && e.drizzle && (this.dbExecutor = _(
1140
1144
  e.drizzle,
1141
1145
  e.schema,
1142
1146
  e.engineType
@@ -1152,7 +1156,7 @@ class T {
1152
1156
  * Set Drizzle instance and schema directly
1153
1157
  */
1154
1158
  setDrizzle(e, t, i) {
1155
- this.dbExecutor = j(e, t, i);
1159
+ this.dbExecutor = _(e, t, i);
1156
1160
  }
1157
1161
  /**
1158
1162
  * Check if database executor is configured
@@ -1164,7 +1168,7 @@ class T {
1164
1168
  * Register a simplified cube with dynamic query building
1165
1169
  */
1166
1170
  registerCube(e) {
1167
- this.cubes.set(e.name, e);
1171
+ this.cubes.set(e.name, e), this.invalidateMetadataCache();
1168
1172
  }
1169
1173
  /**
1170
1174
  * Get a cube by name
@@ -1190,7 +1194,7 @@ class T {
1190
1194
  async execute(e, t) {
1191
1195
  if (!this.dbExecutor)
1192
1196
  throw new Error("Database executor not configured");
1193
- return new y(this.dbExecutor).execute(this.cubes, e, t);
1197
+ return new $(this.dbExecutor).execute(this.cubes, e, t);
1194
1198
  }
1195
1199
  /**
1196
1200
  * Execute a multi-cube query
@@ -1208,37 +1212,51 @@ class T {
1208
1212
  }
1209
1213
  /**
1210
1214
  * Get metadata for all cubes (for API responses)
1215
+ * Uses caching to improve performance for repeated requests
1211
1216
  */
1212
1217
  getMetadata() {
1213
- return Array.from(this.cubes.values()).map((e) => this.generateCubeMetadata(e));
1218
+ const e = Date.now();
1219
+ if (this.metadataCache && this.metadataCacheTimestamp && e - this.metadataCacheTimestamp < this.METADATA_CACHE_TTL)
1220
+ return this.metadataCache;
1221
+ const t = Array.from(this.cubes.values()).map((i) => this.generateCubeMetadata(i));
1222
+ return this.metadataCache = t, this.metadataCacheTimestamp = e, t;
1214
1223
  }
1215
1224
  /**
1216
1225
  * Generate cube metadata for API responses from cubes
1226
+ * Optimized version that minimizes object iterations
1217
1227
  */
1218
1228
  generateCubeMetadata(e) {
1219
- const t = Object.entries(e.measures).map(([n, r]) => ({
1220
- name: `${e.name}.${n}`,
1221
- title: r.title || n,
1222
- shortTitle: r.title || n,
1223
- type: r.type,
1224
- format: void 0,
1225
- // Measure doesn't have format field
1226
- description: r.description
1227
- })), i = Object.entries(e.dimensions).map(([n, r]) => ({
1228
- name: `${e.name}.${n}`,
1229
- title: r.title || n,
1230
- shortTitle: r.title || n,
1231
- type: r.type,
1232
- format: void 0,
1233
- // Dimension doesn't have format field
1234
- description: r.description
1235
- }));
1229
+ const t = Object.keys(e.measures), i = Object.keys(e.dimensions), n = new Array(t.length), o = new Array(i.length);
1230
+ for (let a = 0; a < t.length; a++) {
1231
+ const r = t[a], c = e.measures[r];
1232
+ n[a] = {
1233
+ name: `${e.name}.${r}`,
1234
+ title: c.title || r,
1235
+ shortTitle: c.title || r,
1236
+ type: c.type,
1237
+ format: void 0,
1238
+ // Measure doesn't have format field
1239
+ description: c.description
1240
+ };
1241
+ }
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,
1248
+ type: c.type,
1249
+ format: void 0,
1250
+ // Dimension doesn't have format field
1251
+ description: c.description
1252
+ };
1253
+ }
1236
1254
  return {
1237
1255
  name: e.name,
1238
1256
  title: e.title || e.name,
1239
1257
  description: e.description,
1240
- measures: t,
1241
- dimensions: i,
1258
+ measures: n,
1259
+ dimensions: o,
1242
1260
  segments: []
1243
1261
  // Add segments support later if needed
1244
1262
  };
@@ -1252,7 +1270,7 @@ class T {
1252
1270
  throw new Error(`Cube '${e}' not found`);
1253
1271
  if (!this.dbExecutor)
1254
1272
  throw new Error("Database executor not configured");
1255
- return new y(this.dbExecutor).generateSQL(n, t, i);
1273
+ return new $(this.dbExecutor).generateSQL(n, t, i);
1256
1274
  }
1257
1275
  /**
1258
1276
  * Get SQL for a multi-cube query without executing it (debugging)
@@ -1260,7 +1278,7 @@ class T {
1260
1278
  async generateMultiCubeSQL(e, t) {
1261
1279
  if (!this.dbExecutor)
1262
1280
  throw new Error("Database executor not configured");
1263
- return new y(this.dbExecutor).generateMultiCubeSQL(this.cubes, e, t);
1281
+ return new $(this.dbExecutor).generateMultiCubeSQL(this.cubes, e, t);
1264
1282
  }
1265
1283
  /**
1266
1284
  * Check if a cube exists
@@ -1272,13 +1290,21 @@ class T {
1272
1290
  * Remove a cube
1273
1291
  */
1274
1292
  removeCube(e) {
1275
- return this.cubes.delete(e);
1293
+ const t = this.cubes.delete(e);
1294
+ return t && this.invalidateMetadataCache(), t;
1276
1295
  }
1277
1296
  /**
1278
1297
  * Clear all cubes
1279
1298
  */
1280
1299
  clearCubes() {
1281
- this.cubes.clear();
1300
+ this.cubes.clear(), this.invalidateMetadataCache();
1301
+ }
1302
+ /**
1303
+ * Invalidate the metadata cache
1304
+ * Called whenever cubes are modified
1305
+ */
1306
+ invalidateMetadataCache() {
1307
+ this.metadataCache = void 0, this.metadataCacheTimestamp = void 0;
1282
1308
  }
1283
1309
  /**
1284
1310
  * Get cube names
@@ -1291,55 +1317,55 @@ class T {
1291
1317
  * Ensures all referenced cubes and fields exist
1292
1318
  */
1293
1319
  validateQuery(e) {
1294
- return v(this.cubes, e);
1320
+ return j(this.cubes, e);
1295
1321
  }
1296
1322
  }
1297
- function v(s, e) {
1323
+ function j(s, e) {
1298
1324
  const t = [], i = /* @__PURE__ */ new Set();
1299
1325
  if (e.measures)
1300
1326
  for (const n of e.measures) {
1301
- const [r, a] = n.split(".");
1302
- if (!r || !a) {
1327
+ const [o, a] = n.split(".");
1328
+ if (!o || !a) {
1303
1329
  t.push(`Invalid measure format: ${n}. Expected format: 'CubeName.fieldName'`);
1304
1330
  continue;
1305
1331
  }
1306
- i.add(r);
1307
- const o = s.get(r);
1308
- if (!o) {
1309
- t.push(`Cube '${r}' not found (referenced in measure '${n}')`);
1332
+ i.add(o);
1333
+ const r = s.get(o);
1334
+ if (!r) {
1335
+ t.push(`Cube '${o}' not found (referenced in measure '${n}')`);
1310
1336
  continue;
1311
1337
  }
1312
- o.measures[a] || t.push(`Measure '${a}' not found on cube '${r}'`);
1338
+ r.measures[a] || t.push(`Measure '${a}' not found on cube '${o}'`);
1313
1339
  }
1314
1340
  if (e.dimensions)
1315
1341
  for (const n of e.dimensions) {
1316
- const [r, a] = n.split(".");
1317
- if (!r || !a) {
1342
+ const [o, a] = n.split(".");
1343
+ if (!o || !a) {
1318
1344
  t.push(`Invalid dimension format: ${n}. Expected format: 'CubeName.fieldName'`);
1319
1345
  continue;
1320
1346
  }
1321
- i.add(r);
1322
- const o = s.get(r);
1323
- if (!o) {
1324
- t.push(`Cube '${r}' not found (referenced in dimension '${n}')`);
1347
+ i.add(o);
1348
+ const r = s.get(o);
1349
+ if (!r) {
1350
+ t.push(`Cube '${o}' not found (referenced in dimension '${n}')`);
1325
1351
  continue;
1326
1352
  }
1327
- o.dimensions[a] || t.push(`Dimension '${a}' not found on cube '${r}'`);
1353
+ r.dimensions[a] || t.push(`Dimension '${a}' not found on cube '${o}'`);
1328
1354
  }
1329
1355
  if (e.timeDimensions)
1330
1356
  for (const n of e.timeDimensions) {
1331
- const [r, a] = n.dimension.split(".");
1332
- if (!r || !a) {
1357
+ const [o, a] = n.dimension.split(".");
1358
+ if (!o || !a) {
1333
1359
  t.push(`Invalid timeDimension format: ${n.dimension}. Expected format: 'CubeName.fieldName'`);
1334
1360
  continue;
1335
1361
  }
1336
- i.add(r);
1337
- const o = s.get(r);
1338
- if (!o) {
1339
- t.push(`Cube '${r}' not found (referenced in timeDimension '${n.dimension}')`);
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}')`);
1340
1366
  continue;
1341
1367
  }
1342
- o.dimensions[a] || t.push(`TimeDimension '${a}' not found on cube '${r}' (must be a dimension with time type)`);
1368
+ r.dimensions[a] || t.push(`TimeDimension '${a}' not found on cube '${o}' (must be a dimension with time type)`);
1343
1369
  }
1344
1370
  if (e.filters)
1345
1371
  for (const n of e.filters)
@@ -1351,8 +1377,8 @@ function v(s, e) {
1351
1377
  }
1352
1378
  function L(s, e, t, i) {
1353
1379
  if ("and" in s || "or" in s) {
1354
- const o = s.and || s.or || [];
1355
- for (const c of o)
1380
+ const r = s.and || s.or || [];
1381
+ for (const c of r)
1356
1382
  L(c, e, t, i);
1357
1383
  return;
1358
1384
  }
@@ -1360,8 +1386,8 @@ function L(s, e, t, i) {
1360
1386
  t.push("Filter must have a member field");
1361
1387
  return;
1362
1388
  }
1363
- const [n, r] = s.member.split(".");
1364
- if (!n || !r) {
1389
+ const [n, o] = s.member.split(".");
1390
+ if (!n || !o) {
1365
1391
  t.push(`Invalid filter member format: ${s.member}. Expected format: 'CubeName.fieldName'`);
1366
1392
  return;
1367
1393
  }
@@ -1371,7 +1397,7 @@ function L(s, e, t, i) {
1371
1397
  t.push(`Cube '${n}' not found (referenced in filter '${s.member}')`);
1372
1398
  return;
1373
1399
  }
1374
- !a.dimensions[r] && !a.measures[r] && t.push(`Filter field '${r}' not found on cube '${n}' (must be a dimension or measure)`);
1400
+ !a.dimensions[o] && !a.measures[o] && t.push(`Filter field '${o}' not found on cube '${n}' (must be a dimension or measure)`);
1375
1401
  }
1376
1402
  function Ee(s) {
1377
1403
  return new T(s);
@@ -1416,29 +1442,29 @@ function oe(s) {
1416
1442
  }
1417
1443
  function ae(s) {
1418
1444
  const e = {};
1419
- s.dimensions && s.dimensions.forEach((o) => {
1420
- e[o.name] = ce(o);
1445
+ s.dimensions && s.dimensions.forEach((r) => {
1446
+ e[r.name] = ce(r);
1421
1447
  });
1422
1448
  const t = {};
1423
- s.measures && s.measures.forEach((o) => {
1424
- t[o.name] = le(o);
1449
+ s.measures && s.measures.forEach((r) => {
1450
+ t[r.name] = le(r);
1425
1451
  });
1426
1452
  const i = {};
1427
- s.joins && s.joins.forEach((o) => {
1428
- i[o.name] = fe(o);
1453
+ s.joins && s.joins.forEach((r) => {
1454
+ i[r.name] = fe(r);
1429
1455
  });
1430
1456
  const n = {};
1431
1457
  (s.pre_aggregations || s.preAggregations) && (s.pre_aggregations || s.preAggregations || []).forEach((c) => {
1432
1458
  n[c.name] = de(c);
1433
1459
  });
1434
- let r = s.sql;
1435
- !r && (s.sql_table || s.sqlTable) && (r = `SELECT * FROM ${s.sql_table || s.sqlTable}`);
1460
+ let o = s.sql;
1461
+ !o && (s.sql_table || s.sqlTable) && (o = `SELECT * FROM ${s.sql_table || s.sqlTable}`);
1436
1462
  const a = s.refresh_key || s.refreshKey;
1437
1463
  return {
1438
1464
  name: s.name,
1439
1465
  title: s.title,
1440
1466
  description: s.description,
1441
- sql: r || "",
1467
+ sql: o || "",
1442
1468
  sqlAlias: s.sql_alias || s.sqlAlias,
1443
1469
  dataSource: s.data_source || s.dataSource,
1444
1470
  refreshKey: a ? {
@@ -1552,11 +1578,11 @@ async function De(s) {
1552
1578
  return console.log(`ℹ️ Could not load YAML file ${s}:`, t instanceof Error ? t.message : t), [];
1553
1579
  }
1554
1580
  }
1555
- function $e(s) {
1581
+ function ye(s) {
1556
1582
  let e = s;
1557
1583
  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;
1558
1584
  }
1559
- function ye(s) {
1585
+ function $e(s) {
1560
1586
  const e = {
1561
1587
  name: s.name,
1562
1588
  title: s.title,
@@ -1616,12 +1642,12 @@ const Ae = {
1616
1642
  * Create a simple query builder
1617
1643
  */
1618
1644
  query: () => {
1619
- const s = (e, t = [], i = [], n = [], r, a) => ({
1645
+ const s = (e, t = [], i = [], n = [], o, a) => ({
1620
1646
  measures: e,
1621
1647
  dimensions: t,
1622
1648
  filters: i,
1623
1649
  timeDimensions: n,
1624
- limit: r,
1650
+ limit: o,
1625
1651
  order: a
1626
1652
  });
1627
1653
  return {
@@ -1629,25 +1655,25 @@ const Ae = {
1629
1655
  dimensions: (t = []) => ({
1630
1656
  filters: (i = []) => ({
1631
1657
  timeDimensions: (n = []) => ({
1632
- limit: (r) => ({
1633
- order: (a) => s(e, t, i, n, r, a)
1658
+ limit: (o) => ({
1659
+ order: (a) => s(e, t, i, n, o, a)
1634
1660
  }),
1635
- order: (r) => s(e, t, i, n, void 0, r)
1661
+ order: (o) => s(e, t, i, n, void 0, o)
1636
1662
  }),
1637
1663
  limit: (n) => ({
1638
- order: (r) => s(e, t, i, [], n, r)
1664
+ order: (o) => s(e, t, i, [], n, o)
1639
1665
  }),
1640
1666
  order: (n) => s(e, t, i, [], void 0, n)
1641
1667
  }),
1642
1668
  timeDimensions: (i = []) => ({
1643
1669
  filters: (n = []) => ({
1644
- limit: (r) => ({
1645
- order: (a) => s(e, t, n, i, r, a)
1670
+ limit: (o) => ({
1671
+ order: (a) => s(e, t, n, i, o, a)
1646
1672
  }),
1647
- order: (r) => s(e, t, n, i, void 0, r)
1673
+ order: (o) => s(e, t, n, i, void 0, o)
1648
1674
  }),
1649
1675
  limit: (n) => ({
1650
- order: (r) => s(e, t, [], i, n, r)
1676
+ order: (o) => s(e, t, [], i, n, o)
1651
1677
  }),
1652
1678
  order: (n) => s(e, t, [], i, void 0, n)
1653
1679
  }),
@@ -1659,25 +1685,25 @@ const Ae = {
1659
1685
  filters: (t = []) => ({
1660
1686
  dimensions: (i = []) => ({
1661
1687
  timeDimensions: (n = []) => ({
1662
- limit: (r) => ({
1663
- order: (a) => s(e, i, t, n, r, a)
1688
+ limit: (o) => ({
1689
+ order: (a) => s(e, i, t, n, o, a)
1664
1690
  }),
1665
- order: (r) => s(e, i, t, n, void 0, r)
1691
+ order: (o) => s(e, i, t, n, void 0, o)
1666
1692
  }),
1667
1693
  limit: (n) => ({
1668
- order: (r) => s(e, i, t, [], n, r)
1694
+ order: (o) => s(e, i, t, [], n, o)
1669
1695
  }),
1670
1696
  order: (n) => s(e, i, t, [], void 0, n)
1671
1697
  }),
1672
1698
  timeDimensions: (i = []) => ({
1673
1699
  dimensions: (n = []) => ({
1674
- limit: (r) => ({
1675
- order: (a) => s(e, n, t, i, r, a)
1700
+ limit: (o) => ({
1701
+ order: (a) => s(e, n, t, i, o, a)
1676
1702
  }),
1677
- order: (r) => s(e, n, t, i, void 0, r)
1703
+ order: (o) => s(e, n, t, i, void 0, o)
1678
1704
  }),
1679
1705
  limit: (n) => ({
1680
- order: (r) => s(e, [], t, i, n, r)
1706
+ order: (o) => s(e, [], t, i, n, o)
1681
1707
  }),
1682
1708
  order: (n) => s(e, [], t, i, void 0, n)
1683
1709
  }),
@@ -1722,12 +1748,12 @@ export {
1722
1748
  ie as MultiCubeBuilder,
1723
1749
  ee as MySQLExecutor,
1724
1750
  X as PostgresExecutor,
1725
- y as QueryExecutor,
1751
+ $ as QueryExecutor,
1726
1752
  q as SQLiteExecutor,
1727
1753
  T as SemanticLayerCompiler,
1728
1754
  Ae as SemanticLayerUtils,
1729
- $e as convertCubeReferences,
1730
- j as createDatabaseExecutor,
1755
+ ye as convertCubeReferences,
1756
+ _ as createDatabaseExecutor,
1731
1757
  Te as createDrizzleSemanticLayer,
1732
1758
  ne as createMultiCubeContext,
1733
1759
  te as createMySQLExecutor,
@@ -1736,12 +1762,12 @@ export {
1736
1762
  Ee as createSemanticLayer,
1737
1763
  xe as defaultSemanticLayer,
1738
1764
  Ne as defineCube,
1739
- Ce as defineLegacyCube,
1765
+ we as defineLegacyCube,
1740
1766
  pe as loadYamlCubes,
1741
1767
  De as loadYamlCubesFromFile,
1742
1768
  re as parseYamlCubes,
1743
1769
  b as resolveSqlExpression,
1744
- ye as semanticCubeToYaml,
1770
+ $e as semanticCubeToYaml,
1745
1771
  se as semanticLayer,
1746
1772
  ae as yamlCubeToSemanticCube
1747
1773
  };