drizzle-cube 0.4.28 → 0.4.29
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.
- package/dist/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.js +2 -2
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +2 -2
- package/dist/adapters/{handler-BV2_dul8.js → handler-BHguLZOY.js} +1 -1
- package/dist/adapters/{handler-LMRPeTNJ.cjs → handler-DOIyiFPg.cjs} +1 -1
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.js +2 -2
- package/dist/adapters/mcp-transport-CWGqDQSI.cjs +259 -0
- package/dist/adapters/{mcp-transport-B6ZudTSk.js → mcp-transport-CyeHMDPl.js} +115 -70
- package/dist/adapters/nextjs/index.cjs +2 -2
- package/dist/adapters/nextjs/index.js +2 -2
- package/dist/server/index.cjs +13 -11
- package/dist/server/index.d.ts +13 -4
- package/dist/server/index.js +98 -53
- package/package.json +1 -1
- package/dist/adapters/mcp-transport-DCiSGtp1.cjs +0 -257
package/dist/server/index.d.ts
CHANGED
|
@@ -857,8 +857,8 @@ export declare interface CubeDiscoveryResult {
|
|
|
857
857
|
* Type-safe cube join definition with lazy loading support
|
|
858
858
|
*/
|
|
859
859
|
export declare interface CubeJoin {
|
|
860
|
-
/** Target cube reference - lazy loaded to avoid circular dependencies */
|
|
861
|
-
targetCube: Cube | (() => Cube);
|
|
860
|
+
/** Target cube reference - lazy loaded to avoid circular dependencies, or string name resolved from registry */
|
|
861
|
+
targetCube: Cube | (() => Cube) | string;
|
|
862
862
|
/** Semantic relationship - determines join behavior */
|
|
863
863
|
relationship: CubeRelationship;
|
|
864
864
|
/** Array of join conditions - supports multi-column joins */
|
|
@@ -4081,9 +4081,12 @@ export declare interface QueryWarning {
|
|
|
4081
4081
|
export declare type QueryWarningSeverity = 'info' | 'warning' | 'error';
|
|
4082
4082
|
|
|
4083
4083
|
/**
|
|
4084
|
-
* Resolve cube reference (handles
|
|
4084
|
+
* Resolve cube reference (handles direct, lazy, and string name references)
|
|
4085
|
+
*
|
|
4086
|
+
* String references are resolved from the optional `cubes` registry map.
|
|
4087
|
+
* Returns `null` when a string ref cannot be resolved (logs a warning).
|
|
4085
4088
|
*/
|
|
4086
|
-
export declare function resolveCubeReference(ref: Cube | (() => Cube)): Cube;
|
|
4089
|
+
export declare function resolveCubeReference(ref: Cube | (() => Cube) | string, cubes?: Map<string, Cube>): Cube | null;
|
|
4087
4090
|
|
|
4088
4091
|
/**
|
|
4089
4092
|
* Resolved measure SQL builders
|
|
@@ -4414,6 +4417,12 @@ export declare class SemanticLayerCompiler {
|
|
|
4414
4417
|
* Validates calculated measures during registration
|
|
4415
4418
|
*/
|
|
4416
4419
|
registerCube(cube: Cube): void;
|
|
4420
|
+
/**
|
|
4421
|
+
* Validate that all string-based cube references in joins resolve to registered cubes.
|
|
4422
|
+
* Call after all cubes are registered for strict startup validation.
|
|
4423
|
+
* Throws an error listing all unresolved references.
|
|
4424
|
+
*/
|
|
4425
|
+
validateCubeReferences(): void;
|
|
4417
4426
|
/**
|
|
4418
4427
|
* Validate calculated measures in a cube
|
|
4419
4428
|
* Checks template syntax, dependency existence, and circular dependencies
|
package/dist/server/index.js
CHANGED
|
@@ -2007,7 +2007,17 @@ function Gt(i, e, t) {
|
|
|
2007
2007
|
return gt(i, e);
|
|
2008
2008
|
throw new Error("Unable to determine database engine type. Please specify engineType parameter.");
|
|
2009
2009
|
}
|
|
2010
|
-
function
|
|
2010
|
+
function k(i, e) {
|
|
2011
|
+
if (typeof i == "string") {
|
|
2012
|
+
if (!e)
|
|
2013
|
+
return console.warn(
|
|
2014
|
+
`[drizzle-cube] Cannot resolve string cube reference '${i}': no cube registry provided. Join will be skipped.`
|
|
2015
|
+
), null;
|
|
2016
|
+
const t = e.get(i);
|
|
2017
|
+
return t || (console.warn(
|
|
2018
|
+
`[drizzle-cube] Cannot resolve cube reference '${i}': no cube with that name is registered. Registered cubes: ${Array.from(e.keys()).join(", ") || "(none)"}. Join will be skipped.`
|
|
2019
|
+
), null);
|
|
2020
|
+
}
|
|
2011
2021
|
return typeof i == "function" ? i() : i;
|
|
2012
2022
|
}
|
|
2013
2023
|
function Ve(i) {
|
|
@@ -3848,7 +3858,9 @@ class De {
|
|
|
3848
3858
|
if (s.joins)
|
|
3849
3859
|
for (const [, n] of Object.entries(s.joins)) {
|
|
3850
3860
|
if (n.relationship === "belongsToMany") continue;
|
|
3851
|
-
const
|
|
3861
|
+
const r = k(n.targetCube, this.cubes);
|
|
3862
|
+
if (!r) continue;
|
|
3863
|
+
const E = r.name;
|
|
3852
3864
|
let a = e.get(E);
|
|
3853
3865
|
a || (a = [], e.set(E, a)), a.push({ definingCube: t, joinDef: n });
|
|
3854
3866
|
}
|
|
@@ -3876,7 +3888,9 @@ class De {
|
|
|
3876
3888
|
const { cube: A, path: o } = E.shift(), R = this.cubes.get(A);
|
|
3877
3889
|
if (R?.joins)
|
|
3878
3890
|
for (const [, l] of Object.entries(R.joins)) {
|
|
3879
|
-
const
|
|
3891
|
+
const N = k(l.targetCube, this.cubes);
|
|
3892
|
+
if (!N) continue;
|
|
3893
|
+
const I = N.name;
|
|
3880
3894
|
if (a.has(I))
|
|
3881
3895
|
continue;
|
|
3882
3896
|
const u = [
|
|
@@ -4011,7 +4025,9 @@ class De {
|
|
|
4011
4025
|
const R = this.cubes.get(a);
|
|
4012
4026
|
if (R?.joins)
|
|
4013
4027
|
for (const [, l] of Object.entries(R.joins)) {
|
|
4014
|
-
const
|
|
4028
|
+
const N = k(l.targetCube, this.cubes);
|
|
4029
|
+
if (!N) continue;
|
|
4030
|
+
const I = N.name;
|
|
4015
4031
|
if (o.has(I))
|
|
4016
4032
|
continue;
|
|
4017
4033
|
const u = [
|
|
@@ -4081,7 +4097,9 @@ class De {
|
|
|
4081
4097
|
const { cube: E, path: a } = n.shift(), A = this.cubes.get(E);
|
|
4082
4098
|
if (A?.joins)
|
|
4083
4099
|
for (const [, o] of Object.entries(A.joins)) {
|
|
4084
|
-
const
|
|
4100
|
+
const R = k(o.targetCube, this.cubes);
|
|
4101
|
+
if (!R) continue;
|
|
4102
|
+
const S = R.name;
|
|
4085
4103
|
if (r.has(S)) continue;
|
|
4086
4104
|
const l = [
|
|
4087
4105
|
...a,
|
|
@@ -4122,7 +4140,9 @@ class De {
|
|
|
4122
4140
|
const n = s.shift(), r = this.cubes.get(n);
|
|
4123
4141
|
if (r?.joins)
|
|
4124
4142
|
for (const [, a] of Object.entries(r.joins)) {
|
|
4125
|
-
const
|
|
4143
|
+
const A = k(a.targetCube, this.cubes);
|
|
4144
|
+
if (!A) continue;
|
|
4145
|
+
const o = A.name;
|
|
4126
4146
|
t.has(o) || (t.add(o), s.push(o));
|
|
4127
4147
|
}
|
|
4128
4148
|
const E = this.reverseIndex.get(n) || [];
|
|
@@ -4300,7 +4320,7 @@ class Un {
|
|
|
4300
4320
|
const R = this.collectPathHintCubes(r), S = /* @__PURE__ */ new Set();
|
|
4301
4321
|
for (const N of o) {
|
|
4302
4322
|
if (N === t.name) continue;
|
|
4303
|
-
this.findHasManyJoinDef(t, N) && S.add(N);
|
|
4323
|
+
this.findHasManyJoinDef(t, N, e) && S.add(N);
|
|
4304
4324
|
}
|
|
4305
4325
|
const l = s.filter((N) => N !== t.name);
|
|
4306
4326
|
for (const N of l) {
|
|
@@ -4470,11 +4490,12 @@ class Un {
|
|
|
4470
4490
|
*/
|
|
4471
4491
|
findJoinInfoToCube(e, t) {
|
|
4472
4492
|
for (const [, s] of e)
|
|
4473
|
-
if (s.name !== t && s.joins)
|
|
4474
|
-
for (const [, n] of Object.entries(s.joins))
|
|
4475
|
-
|
|
4493
|
+
if (s.name !== t && s.joins)
|
|
4494
|
+
for (const [, n] of Object.entries(s.joins)) {
|
|
4495
|
+
const r = k(n.targetCube, e);
|
|
4496
|
+
if (r && r.name === t)
|
|
4476
4497
|
return { sourceCube: s, joinDef: n };
|
|
4477
|
-
|
|
4498
|
+
}
|
|
4478
4499
|
return null;
|
|
4479
4500
|
}
|
|
4480
4501
|
/**
|
|
@@ -4575,23 +4596,26 @@ class Un {
|
|
|
4575
4596
|
* and to search from any source cube, not just the primary
|
|
4576
4597
|
*/
|
|
4577
4598
|
findJoinInfoForCube(e, t, s) {
|
|
4578
|
-
if (t.joins)
|
|
4579
|
-
for (const [, r] of Object.entries(t.joins))
|
|
4580
|
-
|
|
4599
|
+
if (t.joins)
|
|
4600
|
+
for (const [, r] of Object.entries(t.joins)) {
|
|
4601
|
+
const E = k(r.targetCube, e);
|
|
4602
|
+
if (E && E.name === s)
|
|
4581
4603
|
return { sourceCube: t, joinDef: r };
|
|
4582
|
-
|
|
4604
|
+
}
|
|
4583
4605
|
const n = e.get(s);
|
|
4584
|
-
if (n?.joins)
|
|
4585
|
-
for (const [, r] of Object.entries(n.joins))
|
|
4586
|
-
|
|
4606
|
+
if (n?.joins)
|
|
4607
|
+
for (const [, r] of Object.entries(n.joins)) {
|
|
4608
|
+
const E = k(r.targetCube, e);
|
|
4609
|
+
if (E && E.name === t.name)
|
|
4587
4610
|
return { sourceCube: n, joinDef: r, reversed: !0 };
|
|
4588
|
-
|
|
4611
|
+
}
|
|
4589
4612
|
for (const [, r] of e)
|
|
4590
|
-
if (!(r.name === t.name || r.name === s) && r.joins)
|
|
4591
|
-
for (const [, E] of Object.entries(r.joins))
|
|
4592
|
-
|
|
4613
|
+
if (!(r.name === t.name || r.name === s) && r.joins)
|
|
4614
|
+
for (const [, E] of Object.entries(r.joins)) {
|
|
4615
|
+
const a = k(E.targetCube, e);
|
|
4616
|
+
if (a && a.name === s)
|
|
4593
4617
|
return { sourceCube: r, joinDef: E };
|
|
4594
|
-
|
|
4618
|
+
}
|
|
4595
4619
|
return null;
|
|
4596
4620
|
}
|
|
4597
4621
|
/**
|
|
@@ -4626,7 +4650,9 @@ class Un {
|
|
|
4626
4650
|
}
|
|
4627
4651
|
if (e.joins)
|
|
4628
4652
|
for (const [, E] of Object.entries(e.joins)) {
|
|
4629
|
-
const
|
|
4653
|
+
const a = k(E.targetCube, s);
|
|
4654
|
+
if (!a) continue;
|
|
4655
|
+
const A = a.name;
|
|
4630
4656
|
if (r.has(A)) {
|
|
4631
4657
|
let o;
|
|
4632
4658
|
E.relationship === "belongsToMany" && E.through ? o = E.through.sourceKey.map((R) => ({
|
|
@@ -4683,12 +4709,14 @@ class Un {
|
|
|
4683
4709
|
/**
|
|
4684
4710
|
* Find hasMany join definition from primary cube to target cube
|
|
4685
4711
|
*/
|
|
4686
|
-
findHasManyJoinDef(e, t) {
|
|
4712
|
+
findHasManyJoinDef(e, t, s) {
|
|
4687
4713
|
if (!e.joins)
|
|
4688
4714
|
return null;
|
|
4689
|
-
for (const [,
|
|
4690
|
-
|
|
4691
|
-
|
|
4715
|
+
for (const [, n] of Object.entries(e.joins)) {
|
|
4716
|
+
const r = k(n.targetCube, s);
|
|
4717
|
+
if (r && r.name === t && n.relationship === "hasMany")
|
|
4718
|
+
return n;
|
|
4719
|
+
}
|
|
4692
4720
|
return null;
|
|
4693
4721
|
}
|
|
4694
4722
|
/**
|
|
@@ -4713,9 +4741,10 @@ class Un {
|
|
|
4713
4741
|
for (const E of r) {
|
|
4714
4742
|
if (E === t.name) continue;
|
|
4715
4743
|
const a = s.get(E);
|
|
4716
|
-
if (a?.joins)
|
|
4717
|
-
for (const [, A] of Object.entries(a.joins))
|
|
4718
|
-
|
|
4744
|
+
if (a?.joins)
|
|
4745
|
+
for (const [, A] of Object.entries(a.joins)) {
|
|
4746
|
+
const o = k(A.targetCube, s);
|
|
4747
|
+
if (o && o.name === t.name && A.relationship === "hasMany") {
|
|
4719
4748
|
const R = this.extractFiltersForCube(e.filters, E), S = this.extractTimeDimensionFiltersForCube(e, E), l = [...R, ...S];
|
|
4720
4749
|
l.length > 0 && A.on.length > 0 && n.push({
|
|
4721
4750
|
sourceCube: a,
|
|
@@ -4729,7 +4758,7 @@ class Un {
|
|
|
4729
4758
|
}))
|
|
4730
4759
|
});
|
|
4731
4760
|
}
|
|
4732
|
-
|
|
4761
|
+
}
|
|
4733
4762
|
}
|
|
4734
4763
|
return n;
|
|
4735
4764
|
}
|
|
@@ -7248,7 +7277,7 @@ class Vn {
|
|
|
7248
7277
|
return null;
|
|
7249
7278
|
const A = Array.from(n);
|
|
7250
7279
|
if (!A.every(
|
|
7251
|
-
(I) => this.hasDirectJoinToSharedDimension(t.get(I), E)
|
|
7280
|
+
(I) => this.hasDirectJoinToSharedDimension(t.get(I), E, t)
|
|
7252
7281
|
))
|
|
7253
7282
|
return null;
|
|
7254
7283
|
const R = this.buildDimensionRefs(e, t), S = this.buildTimeDimensionRefs(e, t), l = {
|
|
@@ -7277,12 +7306,12 @@ class Vn {
|
|
|
7277
7306
|
mergeStrategy: "fullJoin"
|
|
7278
7307
|
};
|
|
7279
7308
|
}
|
|
7280
|
-
hasDirectJoinToSharedDimension(e, t) {
|
|
7309
|
+
hasDirectJoinToSharedDimension(e, t, s) {
|
|
7281
7310
|
if (!e?.joins)
|
|
7282
7311
|
return !1;
|
|
7283
|
-
for (const [,
|
|
7284
|
-
const
|
|
7285
|
-
if (!(!r || r.name !== t) && (
|
|
7312
|
+
for (const [, n] of Object.entries(e.joins)) {
|
|
7313
|
+
const r = k(n.targetCube, s);
|
|
7314
|
+
if (!(!r || r.name !== t) && (n.relationship === "belongsTo" || n.relationship === "hasOne"))
|
|
7286
7315
|
return !0;
|
|
7287
7316
|
}
|
|
7288
7317
|
return !1;
|
|
@@ -8220,19 +8249,19 @@ class Zn {
|
|
|
8220
8249
|
const o = `${r.multipliedCubeName.toLowerCase()}_keys`, R = `${r.multipliedCubeName.toLowerCase()}_pk_agg`, S = {}, l = [];
|
|
8221
8250
|
if (t.dimensions)
|
|
8222
8251
|
for (const D of t.dimensions) {
|
|
8223
|
-
const [U, B] = D.split("."), w = E.get(U),
|
|
8224
|
-
if (!w || !
|
|
8252
|
+
const [U, B] = D.split("."), w = E.get(U), J = w?.dimensions?.[B];
|
|
8253
|
+
if (!w || !J)
|
|
8225
8254
|
return null;
|
|
8226
|
-
const v = H(
|
|
8255
|
+
const v = H(J.sql, s);
|
|
8227
8256
|
S[D] = T`${v}`.as(D), l.push(v);
|
|
8228
8257
|
}
|
|
8229
8258
|
if (t.timeDimensions)
|
|
8230
8259
|
for (const D of t.timeDimensions) {
|
|
8231
|
-
const [U, B] = D.dimension.split("."), w = E.get(U),
|
|
8232
|
-
if (!w || !
|
|
8260
|
+
const [U, B] = D.dimension.split("."), w = E.get(U), J = w?.dimensions?.[B];
|
|
8261
|
+
if (!w || !J)
|
|
8233
8262
|
return null;
|
|
8234
8263
|
const v = n.queryBuilder.buildTimeDimensionExpression(
|
|
8235
|
-
|
|
8264
|
+
J.sql,
|
|
8236
8265
|
D.granularity,
|
|
8237
8266
|
s
|
|
8238
8267
|
);
|
|
@@ -8325,8 +8354,8 @@ class Zn {
|
|
|
8325
8354
|
if (!y.has(U)) continue;
|
|
8326
8355
|
const B = a.measures?.[U];
|
|
8327
8356
|
if (!B?.sql) return null;
|
|
8328
|
-
const w = H(B.sql, s),
|
|
8329
|
-
h[
|
|
8357
|
+
const w = H(B.sql, s), J = `__avg_sum__${U}`, v = `__avg_count__${U}`;
|
|
8358
|
+
h[J] = T`sum(${w})`.as(J), h[v] = T`count(${w})`.as(v);
|
|
8330
8359
|
}
|
|
8331
8360
|
let b = s.db.select(h).from(m.from);
|
|
8332
8361
|
const Y = [];
|
|
@@ -8350,9 +8379,9 @@ class Zn {
|
|
|
8350
8379
|
);
|
|
8351
8380
|
}
|
|
8352
8381
|
for (const D of I) {
|
|
8353
|
-
const [U, B] = D.split("."),
|
|
8382
|
+
const [U, B] = D.split("."), J = E.get(U)?.measures?.[B], v = `__reg__${D.replace(".", "__")}`;
|
|
8354
8383
|
z[D] = this.buildKeysOuterAggregation(
|
|
8355
|
-
|
|
8384
|
+
J?.type ?? "sum",
|
|
8356
8385
|
o,
|
|
8357
8386
|
v,
|
|
8358
8387
|
D
|
|
@@ -29236,6 +29265,22 @@ class _t {
|
|
|
29236
29265
|
registerCube(e) {
|
|
29237
29266
|
this.validateCalculatedMeasures(e), new oe(this.cubes).populateDependencies(e), this.cubes.set(e.name, e), this.invalidateMetadataCache();
|
|
29238
29267
|
}
|
|
29268
|
+
/**
|
|
29269
|
+
* Validate that all string-based cube references in joins resolve to registered cubes.
|
|
29270
|
+
* Call after all cubes are registered for strict startup validation.
|
|
29271
|
+
* Throws an error listing all unresolved references.
|
|
29272
|
+
*/
|
|
29273
|
+
validateCubeReferences() {
|
|
29274
|
+
const e = [];
|
|
29275
|
+
for (const [t, s] of this.cubes)
|
|
29276
|
+
if (s.joins)
|
|
29277
|
+
for (const [n, r] of Object.entries(s.joins))
|
|
29278
|
+
typeof r.targetCube == "string" && !this.cubes.has(r.targetCube) && e.push(`${t}.joins.${n}: target cube '${r.targetCube}' is not registered`);
|
|
29279
|
+
if (e.length > 0)
|
|
29280
|
+
throw new Error(`Unresolved cube references:
|
|
29281
|
+
${e.map((t) => ` - ${t}`).join(`
|
|
29282
|
+
`)}`);
|
|
29283
|
+
}
|
|
29239
29284
|
/**
|
|
29240
29285
|
* Validate calculated measures in a cube
|
|
29241
29286
|
* Checks template syntax, dependency existence, and circular dependencies
|
|
@@ -29399,8 +29444,8 @@ ${t.join(`
|
|
|
29399
29444
|
const E = [];
|
|
29400
29445
|
if (e.joins)
|
|
29401
29446
|
for (const [, o] of Object.entries(e.joins)) {
|
|
29402
|
-
const R =
|
|
29403
|
-
E.push({
|
|
29447
|
+
const R = k(o.targetCube, this.cubes);
|
|
29448
|
+
R && E.push({
|
|
29404
29449
|
targetCube: R.name,
|
|
29405
29450
|
relationship: o.relationship,
|
|
29406
29451
|
joinFields: o.on.map((S) => ({
|
|
@@ -33359,7 +33404,7 @@ ${i.systemContext}`);
|
|
|
33359
33404
|
};
|
|
33360
33405
|
continue;
|
|
33361
33406
|
}
|
|
33362
|
-
const
|
|
33407
|
+
const J = Date.now();
|
|
33363
33408
|
try {
|
|
33364
33409
|
const v = await w(U);
|
|
33365
33410
|
v.sideEffect && (yield v.sideEffect), Ae.push({
|
|
@@ -33378,7 +33423,7 @@ ${i.systemContext}`);
|
|
|
33378
33423
|
toolName: D,
|
|
33379
33424
|
toolUseId: B,
|
|
33380
33425
|
isError: !!v.isError,
|
|
33381
|
-
durationMs: Date.now() -
|
|
33426
|
+
durationMs: Date.now() - J
|
|
33382
33427
|
});
|
|
33383
33428
|
} catch {
|
|
33384
33429
|
}
|
|
@@ -33400,7 +33445,7 @@ ${i.systemContext}`);
|
|
|
33400
33445
|
toolName: D,
|
|
33401
33446
|
toolUseId: B,
|
|
33402
33447
|
isError: !0,
|
|
33403
|
-
durationMs: Date.now() -
|
|
33448
|
+
durationMs: Date.now() - J
|
|
33404
33449
|
});
|
|
33405
33450
|
} catch {
|
|
33406
33451
|
}
|
|
@@ -34494,7 +34539,7 @@ export {
|
|
|
34494
34539
|
$T as getToolDefinitions,
|
|
34495
34540
|
OA as handleAgentChat,
|
|
34496
34541
|
mn as normalizeQuery,
|
|
34497
|
-
|
|
34542
|
+
k as resolveCubeReference,
|
|
34498
34543
|
H as resolveSqlExpression,
|
|
34499
34544
|
cA as suggestQuery
|
|
34500
34545
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "drizzle-cube",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.29",
|
|
4
4
|
"description": "Drizzle ORM-first semantic layer with Cube.js compatibility. Type-safe analytics and dashboards with SQL injection protection.",
|
|
5
5
|
"main": "./dist/server/index.js",
|
|
6
6
|
"types": "./dist/server/index.d.ts",
|