drizzle-cube 0.5.0 → 0.5.1
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 +2 -2
- package/dist/adapters/express/index.js +103 -99
- package/dist/adapters/fastify/index.cjs +2 -2
- package/dist/adapters/fastify/index.js +106 -102
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.js +38 -42
- package/dist/adapters/mcp-tools.cjs +1 -1
- package/dist/adapters/mcp-tools.d.ts +7 -3
- package/dist/adapters/mcp-tools.js +27 -27
- package/dist/adapters/mcp-transport-C7VLf4T5.js +579 -0
- package/dist/adapters/mcp-transport-poPHl_2j.cjs +39 -0
- package/dist/adapters/mcp-transport.d.ts +14 -2
- package/dist/adapters/nextjs/index.cjs +1 -1
- package/dist/adapters/nextjs/index.js +137 -133
- package/dist/adapters/utils.d.ts +38 -2
- package/dist/mcp-app/mcp-app.html +38 -36
- package/package.json +2 -2
- package/dist/adapters/mcp-transport-45SiFcCH.cjs +0 -39
- package/dist/adapters/mcp-transport-Bxpc4mRy.js +0 -553
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
import { a as e, f as t, i as n, o as r, r as i, u as a, v as o } from "../utils-DOg9oGdt.js";
|
|
2
2
|
import { i as s, n as c, r as l, t as u } from "../locale-DTnJrxm1.js";
|
|
3
|
-
import {
|
|
3
|
+
import { S as d, _ as f, a as p, b as m, c as h, g, h as _, i as v, l as y, m as b, o as x, r as S, u as C, v as w, x as T, y as E } from "../mcp-transport-C7VLf4T5.js";
|
|
4
4
|
//#region src/adapters/fastify/index.ts
|
|
5
|
-
var
|
|
6
|
-
let { cubes:
|
|
7
|
-
if (!
|
|
8
|
-
let
|
|
9
|
-
if (
|
|
5
|
+
var D = function(o, D, O) {
|
|
6
|
+
let { cubes: k, drizzle: A, schema: j, extractSecurityContext: M, engineType: N, cors: P, basePath: F = "/cubejs-api/v1", bodyLimit: I = 10485760, cache: L, mcp: R = { enabled: !0 }, agent: z } = D;
|
|
7
|
+
if (!k || k.length === 0) return O(/* @__PURE__ */ Error("At least one cube must be provided in the cubes array"));
|
|
8
|
+
let B = async (e) => l(await M(e), c((t) => e.headers[t.toLowerCase()]));
|
|
9
|
+
if (P) {
|
|
10
10
|
let e = {
|
|
11
|
-
...
|
|
12
|
-
allowedHeaders: u(
|
|
11
|
+
...P,
|
|
12
|
+
allowedHeaders: u(P.allowedHeaders)
|
|
13
13
|
};
|
|
14
14
|
o.register(import("@fastify/cors"), e);
|
|
15
15
|
}
|
|
16
16
|
o.addHook("onRequest", async (e, t) => {
|
|
17
17
|
e.method === "POST" && (e.body = void 0);
|
|
18
18
|
});
|
|
19
|
-
let
|
|
20
|
-
drizzle:
|
|
21
|
-
schema:
|
|
22
|
-
engineType:
|
|
23
|
-
cache:
|
|
24
|
-
rlsSetup:
|
|
19
|
+
let V = new s({
|
|
20
|
+
drizzle: A,
|
|
21
|
+
schema: j,
|
|
22
|
+
engineType: N,
|
|
23
|
+
cache: L,
|
|
24
|
+
rlsSetup: D.rlsSetup
|
|
25
25
|
});
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
}), o.post(`${
|
|
29
|
-
bodyLimit:
|
|
26
|
+
if (k.forEach((e) => {
|
|
27
|
+
V.registerCube(e);
|
|
28
|
+
}), o.post(`${F}/load`, {
|
|
29
|
+
bodyLimit: I,
|
|
30
30
|
schema: { body: {
|
|
31
31
|
type: "object",
|
|
32
32
|
additionalProperties: !0
|
|
33
33
|
} }
|
|
34
34
|
}, async (e, t) => {
|
|
35
35
|
try {
|
|
36
|
-
let r = e.body, a = r.query || r, o = await
|
|
36
|
+
let r = e.body, a = r.query || r, o = await B(e), s = V.validateQuery(a);
|
|
37
37
|
if (!s.isValid) return t.status(400).send(n(`Query validation failed: ${s.errors.join(", ")}`, 400));
|
|
38
38
|
let c = e.headers["x-cache-control"] === "no-cache";
|
|
39
|
-
return i(a, await
|
|
39
|
+
return i(a, await V.executeMultiCubeQuery(a, o, { skipCache: c }), V);
|
|
40
40
|
} catch (r) {
|
|
41
41
|
return e.log.error(r, "Query execution error"), t.status(500).send(n(r instanceof Error ? r.message : "Query execution failed", 500));
|
|
42
42
|
}
|
|
43
|
-
}), o.get(`${
|
|
43
|
+
}), o.get(`${F}/load`, { schema: { querystring: {
|
|
44
44
|
type: "object",
|
|
45
45
|
properties: { query: { type: "string" } },
|
|
46
46
|
required: ["query"]
|
|
@@ -52,15 +52,15 @@ var T = function(o, T, E) {
|
|
|
52
52
|
} catch {
|
|
53
53
|
return t.status(400).send(n("Invalid JSON in query parameter", 400));
|
|
54
54
|
}
|
|
55
|
-
let o = await
|
|
55
|
+
let o = await B(e), s = V.validateQuery(a);
|
|
56
56
|
if (!s.isValid) return t.status(400).send(n(`Query validation failed: ${s.errors.join(", ")}`, 400));
|
|
57
|
-
let c = e.headers["x-cache-control"] === "no-cache", l = await
|
|
58
|
-
return i(a, l,
|
|
57
|
+
let c = e.headers["x-cache-control"] === "no-cache", l = await V.executeMultiCubeQuery(a, o, { skipCache: c });
|
|
58
|
+
return i(a, l, V);
|
|
59
59
|
} catch (r) {
|
|
60
60
|
return e.log.error(r, "Query execution error"), t.status(500).send(n(r instanceof Error ? r.message : "Query execution failed", 500));
|
|
61
61
|
}
|
|
62
|
-
}), o.post(`${
|
|
63
|
-
bodyLimit:
|
|
62
|
+
}), o.post(`${F}/batch`, {
|
|
63
|
+
bodyLimit: I,
|
|
64
64
|
schema: { body: {
|
|
65
65
|
type: "object",
|
|
66
66
|
required: ["queries"],
|
|
@@ -72,50 +72,50 @@ var T = function(o, T, E) {
|
|
|
72
72
|
}, async (e, t) => {
|
|
73
73
|
try {
|
|
74
74
|
let { queries: r } = e.body;
|
|
75
|
-
return !r || !Array.isArray(r) ? t.status(400).send(n("Request body must contain a \"queries\" array", 400)) : r.length === 0 ? t.status(400).send(n("Queries array cannot be empty", 400)) : await a(r, await
|
|
75
|
+
return !r || !Array.isArray(r) ? t.status(400).send(n("Request body must contain a \"queries\" array", 400)) : r.length === 0 ? t.status(400).send(n("Queries array cannot be empty", 400)) : await a(r, await B(e), V, { skipCache: e.headers["x-cache-control"] === "no-cache" });
|
|
76
76
|
} catch (r) {
|
|
77
77
|
return e.log.error(r, "Batch execution error"), t.status(500).send(n(r instanceof Error ? r.message : "Batch execution failed", 500));
|
|
78
78
|
}
|
|
79
|
-
}), o.get(`${
|
|
79
|
+
}), o.get(`${F}/meta`, async (t, r) => {
|
|
80
80
|
try {
|
|
81
|
-
return e(
|
|
81
|
+
return e(V.getMetadata());
|
|
82
82
|
} catch (e) {
|
|
83
83
|
return t.log.error(e, "Metadata error"), r.status(500).send(n(e instanceof Error ? e.message : "Failed to fetch metadata", 500));
|
|
84
84
|
}
|
|
85
|
-
}), o.post(`${
|
|
86
|
-
bodyLimit:
|
|
85
|
+
}), o.post(`${F}/sql`, {
|
|
86
|
+
bodyLimit: I,
|
|
87
87
|
schema: { body: {
|
|
88
88
|
type: "object",
|
|
89
89
|
additionalProperties: !0
|
|
90
90
|
} }
|
|
91
91
|
}, async (e, t) => {
|
|
92
92
|
try {
|
|
93
|
-
let i = e.body, a = await
|
|
93
|
+
let i = e.body, a = await B(e), o = V.validateQuery(i);
|
|
94
94
|
if (!o.isValid) return t.status(400).send(n(`Query validation failed: ${o.errors.join(", ")}`, 400));
|
|
95
95
|
let s = i.measures?.[0] || i.dimensions?.[0];
|
|
96
96
|
if (!s) return t.status(400).send(n("No measures or dimensions specified", 400));
|
|
97
97
|
let c = s.split(".")[0];
|
|
98
|
-
return r(i, await
|
|
98
|
+
return r(i, await V.generateSQL(c, i, a));
|
|
99
99
|
} catch (r) {
|
|
100
100
|
return e.log.error({ err: String(r).replace(/\n|\r/g, "") }, "SQL generation error"), t.status(500).send(n(r instanceof Error ? r.message : "SQL generation failed", 500));
|
|
101
101
|
}
|
|
102
|
-
}), o.get(`${
|
|
102
|
+
}), o.get(`${F}/sql`, { schema: { querystring: {
|
|
103
103
|
type: "object",
|
|
104
104
|
properties: { query: { type: "string" } },
|
|
105
105
|
required: ["query"]
|
|
106
106
|
} } }, async (e, t) => {
|
|
107
107
|
try {
|
|
108
|
-
let { query: i } = e.query, a = JSON.parse(i), o = await
|
|
108
|
+
let { query: i } = e.query, a = JSON.parse(i), o = await B(e), s = V.validateQuery(a);
|
|
109
109
|
if (!s.isValid) return t.status(400).send(n(`Query validation failed: ${s.errors.join(", ")}`, 400));
|
|
110
110
|
let c = a.measures?.[0] || a.dimensions?.[0];
|
|
111
111
|
if (!c) return t.status(400).send(n("No measures or dimensions specified", 400));
|
|
112
112
|
let l = c.split(".")[0];
|
|
113
|
-
return r(a, await
|
|
113
|
+
return r(a, await V.generateSQL(l, a, o));
|
|
114
114
|
} catch (r) {
|
|
115
115
|
return e.log.error({ err: String(r).replace(/\n|\r/g, "") }, "SQL generation error"), t.status(500).send(n(r instanceof Error ? r.message : "SQL generation failed", 500));
|
|
116
116
|
}
|
|
117
|
-
}), o.post(`${
|
|
118
|
-
bodyLimit:
|
|
117
|
+
}), o.post(`${F}/dry-run`, {
|
|
118
|
+
bodyLimit: I,
|
|
119
119
|
schema: { body: {
|
|
120
120
|
type: "object",
|
|
121
121
|
additionalProperties: !0
|
|
@@ -123,42 +123,42 @@ var T = function(o, T, E) {
|
|
|
123
123
|
}, async (e, n) => {
|
|
124
124
|
try {
|
|
125
125
|
let n = e.body;
|
|
126
|
-
return await t(n.query || n, await
|
|
126
|
+
return await t(n.query || n, await B(e), V);
|
|
127
127
|
} catch (t) {
|
|
128
128
|
return e.log.error(t, "Dry-run error"), n.status(400).send({
|
|
129
129
|
error: t instanceof Error ? t.message : "Dry-run validation failed",
|
|
130
130
|
valid: !1
|
|
131
131
|
});
|
|
132
132
|
}
|
|
133
|
-
}), o.get(`${
|
|
133
|
+
}), o.get(`${F}/dry-run`, { schema: { querystring: {
|
|
134
134
|
type: "object",
|
|
135
135
|
properties: { query: { type: "string" } },
|
|
136
136
|
required: ["query"]
|
|
137
137
|
} } }, async (e, n) => {
|
|
138
138
|
try {
|
|
139
139
|
let { query: n } = e.query;
|
|
140
|
-
return await t(JSON.parse(n), await
|
|
140
|
+
return await t(JSON.parse(n), await B(e), V);
|
|
141
141
|
} catch (t) {
|
|
142
142
|
return e.log.error(t, "Dry-run error"), n.status(400).send({
|
|
143
143
|
error: t instanceof Error ? t.message : "Dry-run validation failed",
|
|
144
144
|
valid: !1
|
|
145
145
|
});
|
|
146
146
|
}
|
|
147
|
-
}), o.post(`${
|
|
148
|
-
bodyLimit:
|
|
147
|
+
}), o.post(`${F}/explain`, {
|
|
148
|
+
bodyLimit: I,
|
|
149
149
|
schema: { body: {
|
|
150
150
|
type: "object",
|
|
151
151
|
additionalProperties: !0
|
|
152
152
|
} }
|
|
153
153
|
}, async (e, t) => {
|
|
154
154
|
try {
|
|
155
|
-
let n = e.body, r = n.query || n, i = n.options || {}, a = await
|
|
156
|
-
return o.isValid ? await
|
|
155
|
+
let n = e.body, r = n.query || n, i = n.options || {}, a = await B(e), o = V.validateQuery(r);
|
|
156
|
+
return o.isValid ? await V.explainQuery(r, a, i) : t.status(400).send({ error: `Query validation failed: ${o.errors.join(", ")}` });
|
|
157
157
|
} catch (n) {
|
|
158
158
|
return e.log.error(n, "Explain error"), t.status(500).send({ error: n instanceof Error ? n.message : "Explain query failed" });
|
|
159
159
|
}
|
|
160
|
-
}),
|
|
161
|
-
bodyLimit:
|
|
160
|
+
}), z && o.post(`${F}/agent/chat`, {
|
|
161
|
+
bodyLimit: I,
|
|
162
162
|
schema: { body: {
|
|
163
163
|
type: "object",
|
|
164
164
|
additionalProperties: !0
|
|
@@ -167,13 +167,13 @@ var T = function(o, T, E) {
|
|
|
167
167
|
try {
|
|
168
168
|
let { handleAgentChat: n } = await import("../handler-3LGcjLtr.js"), { message: r, sessionId: i, history: a } = e.body;
|
|
169
169
|
if (!r || typeof r != "string") return t.status(400).send({ error: "message is required and must be a string" });
|
|
170
|
-
let o = (
|
|
171
|
-
if (
|
|
170
|
+
let o = (z.apiKey || "").trim();
|
|
171
|
+
if (z.allowClientApiKey) {
|
|
172
172
|
let t = e.headers["x-agent-api-key"];
|
|
173
173
|
t && (o = t.trim());
|
|
174
174
|
}
|
|
175
175
|
if (!o) return t.status(401).send({ error: "No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header." });
|
|
176
|
-
let s =
|
|
176
|
+
let s = z.allowClientApiKey ? e.headers["x-agent-provider"] : void 0, c = z.allowClientApiKey ? e.headers["x-agent-model"] : void 0, l = z.allowClientApiKey ? e.headers["x-agent-provider-endpoint"] : void 0, u = await B(e), d = z.buildSystemContext?.(u);
|
|
177
177
|
t.raw.writeHead(200, {
|
|
178
178
|
"Content-Type": "text/event-stream",
|
|
179
179
|
"Cache-Control": "no-cache",
|
|
@@ -184,9 +184,9 @@ var T = function(o, T, E) {
|
|
|
184
184
|
message: r,
|
|
185
185
|
sessionId: i,
|
|
186
186
|
history: a,
|
|
187
|
-
semanticLayer:
|
|
187
|
+
semanticLayer: V,
|
|
188
188
|
securityContext: u,
|
|
189
|
-
agentConfig:
|
|
189
|
+
agentConfig: z,
|
|
190
190
|
apiKey: o,
|
|
191
191
|
systemContext: d,
|
|
192
192
|
providerOverride: s,
|
|
@@ -206,66 +206,70 @@ var T = function(o, T, E) {
|
|
|
206
206
|
} catch (n) {
|
|
207
207
|
if (e.log.error(n, "Agent chat error"), !t.raw.headersSent) return t.status(500).send({ error: n instanceof Error ? n.message : "Agent chat failed" });
|
|
208
208
|
}
|
|
209
|
-
}),
|
|
210
|
-
let e =
|
|
211
|
-
o.post(`${
|
|
212
|
-
bodyLimit:
|
|
209
|
+
}), R.enabled !== !1) {
|
|
210
|
+
let e = x(V, R.resources), t = w(R.prompts), n = R.basePath ?? "/mcp";
|
|
211
|
+
o.post(`${n}`, {
|
|
212
|
+
bodyLimit: I,
|
|
213
213
|
schema: { body: {
|
|
214
214
|
type: "object",
|
|
215
215
|
additionalProperties: !0
|
|
216
216
|
} }
|
|
217
|
-
}, async (
|
|
218
|
-
if (
|
|
219
|
-
let
|
|
220
|
-
if (!
|
|
221
|
-
let
|
|
222
|
-
if (!
|
|
223
|
-
let
|
|
224
|
-
if (!
|
|
217
|
+
}, async (n, r) => {
|
|
218
|
+
if (R.resourceMetadataUrl && !C(n.headers.authorization)) return r.header("WWW-Authenticate", h(R.resourceMetadataUrl)), r.status(401).send({ error: "Bearer token required" });
|
|
219
|
+
let i = T(n.headers.origin, R.allowedOrigins ? { allowedOrigins: R.allowedOrigins } : {});
|
|
220
|
+
if (!i.valid) return r.status(403).send(v(null, -32600, i.reason));
|
|
221
|
+
let a = n.headers.accept;
|
|
222
|
+
if (!m(a)) return r.status(400).send(v(null, -32600, "Accept header must include both application/json and text/event-stream"));
|
|
223
|
+
let o = _(n.headers);
|
|
224
|
+
if (!o.ok) return r.status(426).send({
|
|
225
225
|
error: "Unsupported MCP protocol version",
|
|
226
|
-
supported:
|
|
226
|
+
supported: o.supported
|
|
227
227
|
});
|
|
228
|
-
let
|
|
229
|
-
if (!
|
|
230
|
-
let
|
|
228
|
+
let s = g(n.body);
|
|
229
|
+
if (!s) return r.status(400).send(v(null, -32600, "Invalid JSON-RPC 2.0 request"));
|
|
230
|
+
let c = d(a), l = s.method === "initialize";
|
|
231
231
|
try {
|
|
232
|
-
let
|
|
233
|
-
semanticLayer:
|
|
234
|
-
extractSecurityContext: (e, t) =>
|
|
235
|
-
rawRequest:
|
|
236
|
-
rawResponse:
|
|
237
|
-
negotiatedProtocol:
|
|
238
|
-
|
|
232
|
+
let i = await y(s.method, s.params, {
|
|
233
|
+
semanticLayer: V,
|
|
234
|
+
extractSecurityContext: (e, t) => B(e),
|
|
235
|
+
rawRequest: n,
|
|
236
|
+
rawResponse: r,
|
|
237
|
+
negotiatedProtocol: o.negotiated,
|
|
238
|
+
resources: e,
|
|
239
|
+
prompts: t,
|
|
240
|
+
appEnabled: !!R.app,
|
|
241
|
+
appConfig: typeof R.app == "object" ? R.app : void 0,
|
|
242
|
+
serverName: R.serverName
|
|
239
243
|
});
|
|
240
|
-
if (b(
|
|
241
|
-
let
|
|
242
|
-
|
|
243
|
-
let
|
|
244
|
-
if (
|
|
245
|
-
let e =
|
|
246
|
-
|
|
244
|
+
if (b(s)) return r.status(202).send();
|
|
245
|
+
let a = l && i && typeof i == "object" && "sessionId" in i ? i.sessionId : void 0;
|
|
246
|
+
a && r.header(S, a);
|
|
247
|
+
let u = p(s.id ?? null, i);
|
|
248
|
+
if (c) {
|
|
249
|
+
let e = f();
|
|
250
|
+
r.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive").send(`id: ${e}\n\n${E(u, e)}`);
|
|
247
251
|
return;
|
|
248
252
|
}
|
|
249
|
-
return
|
|
250
|
-
} catch (
|
|
251
|
-
if (b(
|
|
252
|
-
|
|
253
|
-
let
|
|
254
|
-
if (
|
|
255
|
-
let e =
|
|
256
|
-
|
|
253
|
+
return r.send(u);
|
|
254
|
+
} catch (e) {
|
|
255
|
+
if (b(s)) return n.log.error({ err: String(e).replace(/\n|\r/g, "") }, "MCP notification processing error"), r.status(202).send();
|
|
256
|
+
n.log.error({ err: String(e).replace(/\n|\r/g, "") }, "MCP RPC error");
|
|
257
|
+
let t = e?.code ?? -32603, i = e?.data, a = e.message || "MCP request failed", o = v(s.id ?? null, t, a, i);
|
|
258
|
+
if (c) {
|
|
259
|
+
let e = f();
|
|
260
|
+
r.header("Content-Type", "text/event-stream").header("Cache-Control", "no-cache").header("Connection", "keep-alive").send(`id: ${e}\n\n${E(o, e)}`);
|
|
257
261
|
return;
|
|
258
262
|
}
|
|
259
|
-
return
|
|
263
|
+
return r.send(o);
|
|
260
264
|
}
|
|
261
|
-
}), o.get(`${
|
|
262
|
-
if (
|
|
263
|
-
let n =
|
|
265
|
+
}), o.get(`${n}`, async (e, t) => {
|
|
266
|
+
if (R.resourceMetadataUrl && !C(e.headers.authorization)) return t.header("WWW-Authenticate", h(R.resourceMetadataUrl)), t.status(401).send({ error: "Bearer token required" });
|
|
267
|
+
let n = f();
|
|
264
268
|
t.raw.writeHead(200, {
|
|
265
269
|
"Content-Type": "text/event-stream",
|
|
266
270
|
"Cache-Control": "no-cache",
|
|
267
271
|
Connection: "keep-alive"
|
|
268
|
-
}), t.raw.write(
|
|
272
|
+
}), t.raw.write(E({
|
|
269
273
|
jsonrpc: "2.0",
|
|
270
274
|
method: "mcp/ready",
|
|
271
275
|
params: { protocol: "streamable-http" }
|
|
@@ -276,16 +280,16 @@ var T = function(o, T, E) {
|
|
|
276
280
|
e.raw.on("close", () => {
|
|
277
281
|
clearInterval(r);
|
|
278
282
|
});
|
|
279
|
-
}), o.delete(`${
|
|
283
|
+
}), o.delete(`${n}`, async (e, t) => R.resourceMetadataUrl && !C(e.headers.authorization) ? (t.header("WWW-Authenticate", h(R.resourceMetadataUrl)), t.status(401).send({ error: "Bearer token required" })) : t.status(405).send({ error: "Session termination not supported" }));
|
|
280
284
|
}
|
|
281
|
-
o.setErrorHandler(async (e, t, r) => (t.log.error(e, "Fastify cube adapter error"), r.statusCode < 400 && r.status(500), n(e instanceof Error ? e : String(e), r.statusCode))),
|
|
285
|
+
o.setErrorHandler(async (e, t, r) => (t.log.error(e, "Fastify cube adapter error"), r.statusCode < 400 && r.status(500), n(e instanceof Error ? e : String(e), r.statusCode))), O();
|
|
282
286
|
};
|
|
283
|
-
async function
|
|
284
|
-
await e.register(
|
|
287
|
+
async function O(e, t) {
|
|
288
|
+
await e.register(D, t);
|
|
285
289
|
}
|
|
286
|
-
function
|
|
290
|
+
function k(e) {
|
|
287
291
|
let t = o("fastify")({ logger: !0 });
|
|
288
|
-
return t.register(
|
|
292
|
+
return t.register(D, e), t;
|
|
289
293
|
}
|
|
290
294
|
//#endregion
|
|
291
|
-
export {
|
|
295
|
+
export { k as createCubeApp, D as cubePlugin, O as registerCubeRoutes };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-DNrj-ryp.cjs`),t=require(`../locale-DueXjqMh.cjs`),n=require(`../mcp-transport-45SiFcCH.cjs`);let r=require(`hono`);var i=e=>{let t={origin:`*`,allowMethods:[`GET`,`HEAD`,`PUT`,`POST`,`DELETE`,`PATCH`],allowHeaders:[],exposeHeaders:[],...e},n=(e=>typeof e==`string`?e===`*`?t.credentials?e=>e||null:()=>e:t=>e===t?t:null:typeof e==`function`?e:t=>e.includes(t)?t:null)(t.origin),r=(e=>typeof e==`function`?e:Array.isArray(e)?()=>e:()=>[])(t.allowMethods);return async function(e,i){function a(t,n){e.res.headers.set(t,n)}let o=await n(e.req.header(`origin`)||``,e);if(o&&a(`Access-Control-Allow-Origin`,o),t.credentials&&a(`Access-Control-Allow-Credentials`,`true`),t.exposeHeaders?.length&&a(`Access-Control-Expose-Headers`,t.exposeHeaders.join(`,`)),e.req.method===`OPTIONS`){(t.origin!==`*`||t.credentials)&&a(`Vary`,`Origin`),t.maxAge!=null&&a(`Access-Control-Max-Age`,t.maxAge.toString());let n=await r(e.req.header(`origin`)||``,e);n.length&&a(`Access-Control-Allow-Methods`,n.join(`,`));let i=t.allowHeaders;if(!i?.length){let t=e.req.header(`Access-Control-Request-Headers`);t&&(i=t.split(/\s*,\s*/))}return i?.length&&(a(`Access-Control-Allow-Headers`,i.join(`,`)),e.res.headers.append(`Vary`,`Access-Control-Request-Headers`)),e.res.headers.delete(`Content-Length`),e.res.headers.delete(`Content-Type`),new Response(null,{headers:e.res.headers,status:204,statusText:`No Content`})}await i(),(t.origin!==`*`||t.credentials)&&e.header(`Vary`,`Origin`,{append:!0})}};function a(a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,cache:p,mcp:m={enabled:!0},agent:h}=a;if(!a.semanticLayer&&(!o||o.length===0))throw Error(`Either semanticLayer or a non-empty cubes array must be provided`);let g=new r.Hono,_=async e=>t.r(await l(e),t.n(t=>e.req.header(t)));if(d){let e={...d,allowHeaders:t.t(d.allowHeaders)};g.use(`/*`,i(e))}let v=a.semanticLayer??new t.i({drizzle:s,schema:c,engineType:u,cache:p,rlsSetup:a.rlsSetup});if(!a.semanticLayer&&o&&o.forEach(e=>{v.registerCube(e)}),g.post(`${f}/load`,async t=>{try{let n=await t.req.json(),r=n.query||n,i=await _(t),a=v.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=t.req.header(`x-cache-control`)===`no-cache`,s=await v.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,v))}catch(e){return console.error(`Query execution error:`,e),t.json({error:e instanceof Error?e.message:`Query execution failed`},500)}}),g.get(`${f}/load`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`},400);let r;try{r=JSON.parse(n)}catch{return t.json({error:`Invalid JSON in query parameter`},400)}let i=await _(t),a=v.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=t.req.header(`x-cache-control`)===`no-cache`,s=await v.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,v))}catch(e){return console.error(`Query execution error:`,e),t.json({error:e instanceof Error?e.message:`Query execution failed`},500)}}),g.post(`${f}/batch`,async t=>{try{let{queries:n}=await t.req.json();if(!n||!Array.isArray(n))return t.json({error:`Request body must contain a "queries" array`},400);if(n.length===0)return t.json({error:`Queries array cannot be empty`},400);let r=await e.u(n,await _(t),v,{skipCache:t.req.header(`x-cache-control`)===`no-cache`});return t.json(r)}catch(e){return console.error(`Batch execution error:`,e),t.json({error:e instanceof Error?e.message:`Batch execution failed`},500)}}),g.get(`${f}/meta`,t=>{try{let n=v.getMetadata();return t.json(e.a(n))}catch(e){return console.error(`Metadata error:`,e),t.json({error:e instanceof Error?e.message:`Failed to fetch metadata`},500)}}),g.post(`${f}/sql`,async t=>{try{let n=await t.req.json(),r=await _(t),i=v.validateQuery(n);if(!i.isValid)return t.json({error:`Query validation failed: ${i.errors.join(`, `)}`},400);let a=n.measures?.[0]||n.dimensions?.[0];if(!a)return t.json({error:`No measures or dimensions specified`},400);let o=a.split(`.`)[0],s=await v.generateSQL(o,n,r);return t.json(e.o(n,s))}catch(e){return console.error(`SQL generation error:`,e),t.json({error:e instanceof Error?e.message:`SQL generation failed`},500)}}),g.get(`${f}/sql`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`},400);let r=JSON.parse(n),i=await _(t),a=v.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return t.json({error:`No measures or dimensions specified`},400);let s=o.split(`.`)[0],c=await v.generateSQL(s,r,i);return t.json(e.o(r,c))}catch(e){return console.error(`SQL generation error:`,e),t.json({error:e instanceof Error?e.message:`SQL generation failed`},500)}}),g.post(`${f}/dry-run`,async t=>{try{let n=await t.req.json(),r=await e.f(n.query||n,await _(t),v);return t.json(r)}catch(e){return console.error(`Dry-run error:`,e),t.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},400)}}),g.get(`${f}/dry-run`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`,valid:!1},400);let r=await e.f(JSON.parse(n),await _(t),v);return t.json(r)}catch(e){return console.error(`Dry-run error:`,e),t.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},400)}}),g.post(`${f}/explain`,async e=>{try{let t=await e.req.json(),n=t.query||t,r=t.options||{},i=await _(e),a=v.validateQuery(n);if(!a.isValid)return e.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=await v.explainQuery(n,i,r);return e.json(o)}catch(t){return console.error(`Explain error:`,t),e.json({error:t instanceof Error?t.message:`Explain query failed`},500)}}),h&&g.post(`${f}/agent/chat`,async e=>{try{let{handleAgentChat:t}=await Promise.resolve().then(()=>require(`../handler-BzzbVpcl.cjs`)),{message:n,sessionId:r,history:i}=await e.req.json();if(!n||typeof n!=`string`)return e.json({error:`message is required and must be a string`},400);let a=(h.apiKey||``).trim();if(h.allowClientApiKey){let t=e.req.header(`x-agent-api-key`);t&&(a=t.trim())}if(!a)return e.json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`},401);let o=h.allowClientApiKey?e.req.header(`x-agent-provider`):void 0,s=h.allowClientApiKey?e.req.header(`x-agent-model`):void 0,c=h.allowClientApiKey?e.req.header(`x-agent-provider-endpoint`):void 0,l=await _(e),u=h.buildSystemContext?.(l),d=new TextEncoder,f=new ReadableStream({async start(e){try{let f=t({message:n,sessionId:r,history:i,semanticLayer:v,securityContext:l,agentConfig:h,apiKey:a,systemContext:u,providerOverride:o,modelOverride:s,baseURLOverride:c});for await(let t of f){let n=`data: ${JSON.stringify(t)}\n\n`;e.enqueue(d.encode(n))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(d.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}});return new Response(f,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})}catch(t){return console.error(`Agent chat error:`,t),e.json({error:t instanceof Error?t.message:`Agent chat failed`},500)}}),m.enabled!==!1){let e={uri:`drizzle-cube://schema`,name:`Cube Schema`,description:`Current cube metadata as JSON`,mimeType:`application/json`,text:JSON.stringify(v.getMetadata(),null,2)},t=[...n.d(),e],r=n.u(),i=m.basePath??`/mcp`;g.post(`${i}`,async e=>{if(m.resourceMetadataUrl&&!n.l(e.req.header(`authorization`)))return e.header(`WWW-Authenticate`,n.s(m.resourceMetadataUrl)),e.json({error:`Bearer token required`},401);let i=n.y(e.req.header(`origin`),m.allowedOrigins?{allowedOrigins:m.allowedOrigins}:{});if(!i.valid)return e.json(n.i(null,-32600,i.reason),403);let a=e.req.header(`accept`);if(!n.v(a))return e.json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`),400);let o=n.m(e.req.header());if(!o.ok)return e.json({error:`Unsupported MCP protocol version`,supported:o.supported},426);let s=n.h(await e.req.json().catch(()=>null));if(!s)return e.json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`),400);let c=n.b(a),l=s.method===`initialize`;try{let i=await n.c(s.method,s.params,{semanticLayer:v,extractSecurityContext:(e,t)=>_(e),rawRequest:e,rawResponse:null,negotiatedProtocol:o.negotiated,resources:t,prompts:r,appEnabled:!!m.app});if(n.p(s))return e.body(null,202);let a=n.a(s.id??null,i),u=l&&i&&typeof i==`object`&&`sessionId`in i?i.sessionId:void 0,d={};if(u&&(d[n.r]=u),c){let e=new TextEncoder,t=n.g(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n._(a,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...d}})}return e.json(a,200,d)}catch(t){if(n.p(s))return console.error(`MCP notification processing error:`,t),e.body(null,202);console.error(`MCP RPC error:`,t);let r=t?.code??-32603,i=t?.data,a=t.message||`MCP request failed`,o=n.i(s.id??null,r,a,i);if(c){let e=new TextEncoder,t=n.g(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n._(o,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})}return e.json(o,200)}}),g.delete(`${i}`,e=>m.resourceMetadataUrl&&!n.l(e.req.header(`authorization`))?(e.header(`WWW-Authenticate`,n.s(m.resourceMetadataUrl)),e.json({error:`Bearer token required`},401)):e.json({error:`Session termination not supported`},405)),g.get(`${i}`,e=>{if(m.resourceMetadataUrl&&!n.l(e.req.header(`authorization`)))return e.header(`WWW-Authenticate`,n.s(m.resourceMetadataUrl)),e.json({error:`Bearer token required`},401);let t=new TextEncoder,r=n.g(),i,a=new ReadableStream({start(e){e.enqueue(t.encode(n._({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3))),i=setInterval(()=>{e.enqueue(t.encode(`: keep-alive
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-DNrj-ryp.cjs`),t=require(`../locale-DueXjqMh.cjs`),n=require(`../mcp-transport-poPHl_2j.cjs`);let r=require(`hono`);var i=e=>{let t={origin:`*`,allowMethods:[`GET`,`HEAD`,`PUT`,`POST`,`DELETE`,`PATCH`],allowHeaders:[],exposeHeaders:[],...e},n=(e=>typeof e==`string`?e===`*`?t.credentials?e=>e||null:()=>e:t=>e===t?t:null:typeof e==`function`?e:t=>e.includes(t)?t:null)(t.origin),r=(e=>typeof e==`function`?e:Array.isArray(e)?()=>e:()=>[])(t.allowMethods);return async function(e,i){function a(t,n){e.res.headers.set(t,n)}let o=await n(e.req.header(`origin`)||``,e);if(o&&a(`Access-Control-Allow-Origin`,o),t.credentials&&a(`Access-Control-Allow-Credentials`,`true`),t.exposeHeaders?.length&&a(`Access-Control-Expose-Headers`,t.exposeHeaders.join(`,`)),e.req.method===`OPTIONS`){(t.origin!==`*`||t.credentials)&&a(`Vary`,`Origin`),t.maxAge!=null&&a(`Access-Control-Max-Age`,t.maxAge.toString());let n=await r(e.req.header(`origin`)||``,e);n.length&&a(`Access-Control-Allow-Methods`,n.join(`,`));let i=t.allowHeaders;if(!i?.length){let t=e.req.header(`Access-Control-Request-Headers`);t&&(i=t.split(/\s*,\s*/))}return i?.length&&(a(`Access-Control-Allow-Headers`,i.join(`,`)),e.res.headers.append(`Vary`,`Access-Control-Request-Headers`)),e.res.headers.delete(`Content-Length`),e.res.headers.delete(`Content-Type`),new Response(null,{headers:e.res.headers,status:204,statusText:`No Content`})}await i(),(t.origin!==`*`||t.credentials)&&e.header(`Vary`,`Origin`,{append:!0})}};function a(a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,cache:p,mcp:m={enabled:!0},agent:h}=a;if(!a.semanticLayer&&(!o||o.length===0))throw Error(`Either semanticLayer or a non-empty cubes array must be provided`);let g=new r.Hono,_=async e=>t.r(await l(e),t.n(t=>e.req.header(t)));if(d){let e={...d,allowHeaders:t.t(d.allowHeaders)};g.use(`/*`,i(e))}let v=a.semanticLayer??new t.i({drizzle:s,schema:c,engineType:u,cache:p,rlsSetup:a.rlsSetup});if(!a.semanticLayer&&o&&o.forEach(e=>{v.registerCube(e)}),g.post(`${f}/load`,async t=>{try{let n=await t.req.json(),r=n.query||n,i=await _(t),a=v.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=t.req.header(`x-cache-control`)===`no-cache`,s=await v.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,v))}catch(e){return console.error(`Query execution error:`,e),t.json({error:e instanceof Error?e.message:`Query execution failed`},500)}}),g.get(`${f}/load`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`},400);let r;try{r=JSON.parse(n)}catch{return t.json({error:`Invalid JSON in query parameter`},400)}let i=await _(t),a=v.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=t.req.header(`x-cache-control`)===`no-cache`,s=await v.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,v))}catch(e){return console.error(`Query execution error:`,e),t.json({error:e instanceof Error?e.message:`Query execution failed`},500)}}),g.post(`${f}/batch`,async t=>{try{let{queries:n}=await t.req.json();if(!n||!Array.isArray(n))return t.json({error:`Request body must contain a "queries" array`},400);if(n.length===0)return t.json({error:`Queries array cannot be empty`},400);let r=await e.u(n,await _(t),v,{skipCache:t.req.header(`x-cache-control`)===`no-cache`});return t.json(r)}catch(e){return console.error(`Batch execution error:`,e),t.json({error:e instanceof Error?e.message:`Batch execution failed`},500)}}),g.get(`${f}/meta`,t=>{try{let n=v.getMetadata();return t.json(e.a(n))}catch(e){return console.error(`Metadata error:`,e),t.json({error:e instanceof Error?e.message:`Failed to fetch metadata`},500)}}),g.post(`${f}/sql`,async t=>{try{let n=await t.req.json(),r=await _(t),i=v.validateQuery(n);if(!i.isValid)return t.json({error:`Query validation failed: ${i.errors.join(`, `)}`},400);let a=n.measures?.[0]||n.dimensions?.[0];if(!a)return t.json({error:`No measures or dimensions specified`},400);let o=a.split(`.`)[0],s=await v.generateSQL(o,n,r);return t.json(e.o(n,s))}catch(e){return console.error(`SQL generation error:`,e),t.json({error:e instanceof Error?e.message:`SQL generation failed`},500)}}),g.get(`${f}/sql`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`},400);let r=JSON.parse(n),i=await _(t),a=v.validateQuery(r);if(!a.isValid)return t.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return t.json({error:`No measures or dimensions specified`},400);let s=o.split(`.`)[0],c=await v.generateSQL(s,r,i);return t.json(e.o(r,c))}catch(e){return console.error(`SQL generation error:`,e),t.json({error:e instanceof Error?e.message:`SQL generation failed`},500)}}),g.post(`${f}/dry-run`,async t=>{try{let n=await t.req.json(),r=await e.f(n.query||n,await _(t),v);return t.json(r)}catch(e){return console.error(`Dry-run error:`,e),t.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},400)}}),g.get(`${f}/dry-run`,async t=>{try{let n=t.req.query(`query`);if(!n)return t.json({error:`Query parameter is required`,valid:!1},400);let r=await e.f(JSON.parse(n),await _(t),v);return t.json(r)}catch(e){return console.error(`Dry-run error:`,e),t.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},400)}}),g.post(`${f}/explain`,async e=>{try{let t=await e.req.json(),n=t.query||t,r=t.options||{},i=await _(e),a=v.validateQuery(n);if(!a.isValid)return e.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=await v.explainQuery(n,i,r);return e.json(o)}catch(t){return console.error(`Explain error:`,t),e.json({error:t instanceof Error?t.message:`Explain query failed`},500)}}),h&&g.post(`${f}/agent/chat`,async e=>{try{let{handleAgentChat:t}=await Promise.resolve().then(()=>require(`../handler-BzzbVpcl.cjs`)),{message:n,sessionId:r,history:i}=await e.req.json();if(!n||typeof n!=`string`)return e.json({error:`message is required and must be a string`},400);let a=(h.apiKey||``).trim();if(h.allowClientApiKey){let t=e.req.header(`x-agent-api-key`);t&&(a=t.trim())}if(!a)return e.json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`},401);let o=h.allowClientApiKey?e.req.header(`x-agent-provider`):void 0,s=h.allowClientApiKey?e.req.header(`x-agent-model`):void 0,c=h.allowClientApiKey?e.req.header(`x-agent-provider-endpoint`):void 0,l=await _(e),u=h.buildSystemContext?.(l),d=new TextEncoder,f=new ReadableStream({async start(e){try{let f=t({message:n,sessionId:r,history:i,semanticLayer:v,securityContext:l,agentConfig:h,apiKey:a,systemContext:u,providerOverride:o,modelOverride:s,baseURLOverride:c});for await(let t of f){let n=`data: ${JSON.stringify(t)}\n\n`;e.enqueue(d.encode(n))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(d.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}});return new Response(f,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})}catch(t){return console.error(`Agent chat error:`,t),e.json({error:t instanceof Error?t.message:`Agent chat failed`},500)}}),m.enabled!==!1){let e=n.o(v,m.resources),t=n.v(m.prompts),r=m.basePath??`/mcp`;g.post(`${r}`,async r=>{if(m.resourceMetadataUrl&&!n.u(r.req.header(`authorization`)))return r.header(`WWW-Authenticate`,n.c(m.resourceMetadataUrl)),r.json({error:`Bearer token required`},401);let i=n.x(r.req.header(`origin`),m.allowedOrigins?{allowedOrigins:m.allowedOrigins}:{});if(!i.valid)return r.json(n.i(null,-32600,i.reason),403);let a=r.req.header(`accept`);if(!n.b(a))return r.json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`),400);let o=n.h(r.req.header());if(!o.ok)return r.json({error:`Unsupported MCP protocol version`,supported:o.supported},426);let s=n.g(await r.req.json().catch(()=>null));if(!s)return r.json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`),400);let c=n.S(a),l=s.method===`initialize`;try{let i=await n.l(s.method,s.params,{semanticLayer:v,extractSecurityContext:(e,t)=>_(e),rawRequest:r,rawResponse:null,negotiatedProtocol:o.negotiated,resources:e,prompts:t,appEnabled:!!m.app,appConfig:typeof m.app==`object`?m.app:void 0,serverName:m.serverName});if(n.m(s))return r.body(null,202);let a=n.a(s.id??null,i),u=l&&i&&typeof i==`object`&&`sessionId`in i?i.sessionId:void 0,d={};if(u&&(d[n.r]=u),c){let e=new TextEncoder,t=n._(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.y(a,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...d}})}return r.json(a,200,d)}catch(e){if(n.m(s))return console.error(`MCP notification processing error:`,e),r.body(null,202);console.error(`MCP RPC error:`,e);let t=e?.code??-32603,i=e?.data,a=e.message||`MCP request failed`,o=n.i(s.id??null,t,a,i);if(c){let e=new TextEncoder,t=n._(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.y(o,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})}return r.json(o,200)}}),g.delete(`${r}`,e=>m.resourceMetadataUrl&&!n.u(e.req.header(`authorization`))?(e.header(`WWW-Authenticate`,n.c(m.resourceMetadataUrl)),e.json({error:`Bearer token required`},401)):e.json({error:`Session termination not supported`},405)),g.get(`${r}`,e=>{if(m.resourceMetadataUrl&&!n.u(e.req.header(`authorization`)))return e.header(`WWW-Authenticate`,n.c(m.resourceMetadataUrl)),e.json({error:`Bearer token required`},401);let t=new TextEncoder,r=n._(),i,a=new ReadableStream({start(e){e.enqueue(t.encode(n.y({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3))),i=setInterval(()=>{e.enqueue(t.encode(`: keep-alive
|
|
2
2
|
|
|
3
3
|
`))},15e3)},cancel(){clearInterval(i)}});return new Response(a,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})})}return g}function o(e,t){let n=a(t);return e.route(`/`,n),e}function s(e){return o(new r.Hono,e)}exports.createCubeApp=s,exports.createCubeRoutes=a,exports.mountCubeRoutes=o;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { a as e, f as t, o as n, r, u as i } from "../utils-DOg9oGdt.js";
|
|
2
2
|
import { i as a, n as o, r as s, t as c } from "../locale-DTnJrxm1.js";
|
|
3
|
-
import {
|
|
3
|
+
import { S as l, _ as u, a as d, b as f, c as p, g as m, h, i as g, l as _, m as v, o as y, r as b, u as x, v as S, x as C, y as w } from "../mcp-transport-C7VLf4T5.js";
|
|
4
4
|
import { Hono as T } from "hono";
|
|
5
5
|
//#region node_modules/hono/dist/middleware/cors/index.js
|
|
6
6
|
var E = (e) => {
|
|
@@ -215,43 +215,39 @@ function D(D) {
|
|
|
215
215
|
return console.error("Agent chat error:", t), e.json({ error: t instanceof Error ? t.message : "Agent chat failed" }, 500);
|
|
216
216
|
}
|
|
217
217
|
}), I.enabled !== !1) {
|
|
218
|
-
let e =
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
if (
|
|
227
|
-
let r = w(e.req.header("origin"), I.allowedOrigins ? { allowedOrigins: I.allowedOrigins } : {});
|
|
228
|
-
if (!r.valid) return e.json(g(null, -32600, r.reason), 403);
|
|
229
|
-
let i = e.req.header("accept");
|
|
230
|
-
if (!C(i)) return e.json(g(null, -32600, "Accept header must include both application/json and text/event-stream"), 400);
|
|
231
|
-
let a = v(e.req.header());
|
|
232
|
-
if (!a.ok) return e.json({
|
|
218
|
+
let e = y(B, I.resources), t = S(I.prompts), n = I.basePath ?? "/mcp";
|
|
219
|
+
R.post(`${n}`, async (n) => {
|
|
220
|
+
if (I.resourceMetadataUrl && !x(n.req.header("authorization"))) return n.header("WWW-Authenticate", p(I.resourceMetadataUrl)), n.json({ error: "Bearer token required" }, 401);
|
|
221
|
+
let r = C(n.req.header("origin"), I.allowedOrigins ? { allowedOrigins: I.allowedOrigins } : {});
|
|
222
|
+
if (!r.valid) return n.json(g(null, -32600, r.reason), 403);
|
|
223
|
+
let i = n.req.header("accept");
|
|
224
|
+
if (!f(i)) return n.json(g(null, -32600, "Accept header must include both application/json and text/event-stream"), 400);
|
|
225
|
+
let a = h(n.req.header());
|
|
226
|
+
if (!a.ok) return n.json({
|
|
233
227
|
error: "Unsupported MCP protocol version",
|
|
234
228
|
supported: a.supported
|
|
235
229
|
}, 426);
|
|
236
|
-
let o =
|
|
237
|
-
if (!o) return
|
|
238
|
-
let s =
|
|
230
|
+
let o = m(await n.req.json().catch(() => null));
|
|
231
|
+
if (!o) return n.json(g(null, -32600, "Invalid JSON-RPC 2.0 request"), 400);
|
|
232
|
+
let s = l(i), c = o.method === "initialize";
|
|
239
233
|
try {
|
|
240
|
-
let r = await
|
|
234
|
+
let r = await _(o.method, o.params, {
|
|
241
235
|
semanticLayer: B,
|
|
242
236
|
extractSecurityContext: (e, t) => z(e),
|
|
243
|
-
rawRequest:
|
|
237
|
+
rawRequest: n,
|
|
244
238
|
rawResponse: null,
|
|
245
239
|
negotiatedProtocol: a.negotiated,
|
|
246
|
-
resources:
|
|
247
|
-
prompts:
|
|
248
|
-
appEnabled: !!I.app
|
|
240
|
+
resources: e,
|
|
241
|
+
prompts: t,
|
|
242
|
+
appEnabled: !!I.app,
|
|
243
|
+
appConfig: typeof I.app == "object" ? I.app : void 0,
|
|
244
|
+
serverName: I.serverName
|
|
249
245
|
});
|
|
250
|
-
if (
|
|
251
|
-
let i =
|
|
252
|
-
if (
|
|
253
|
-
let e = new TextEncoder(), t =
|
|
254
|
-
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(
|
|
246
|
+
if (v(o)) return n.body(null, 202);
|
|
247
|
+
let i = d(o.id ?? null, r), l = c && r && typeof r == "object" && "sessionId" in r ? r.sessionId : void 0, f = {};
|
|
248
|
+
if (l && (f[b] = l), s) {
|
|
249
|
+
let e = new TextEncoder(), t = u(), n = new ReadableStream({ start(n) {
|
|
250
|
+
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(w(i, t))), n.close();
|
|
255
251
|
} });
|
|
256
252
|
return new Response(n, {
|
|
257
253
|
status: 200,
|
|
@@ -259,18 +255,18 @@ function D(D) {
|
|
|
259
255
|
"Content-Type": "text/event-stream",
|
|
260
256
|
"Cache-Control": "no-cache",
|
|
261
257
|
Connection: "keep-alive",
|
|
262
|
-
...
|
|
258
|
+
...f
|
|
263
259
|
}
|
|
264
260
|
});
|
|
265
261
|
}
|
|
266
|
-
return
|
|
267
|
-
} catch (
|
|
268
|
-
if (
|
|
269
|
-
console.error("MCP RPC error:",
|
|
270
|
-
let
|
|
262
|
+
return n.json(i, 200, f);
|
|
263
|
+
} catch (e) {
|
|
264
|
+
if (v(o)) return console.error("MCP notification processing error:", e), n.body(null, 202);
|
|
265
|
+
console.error("MCP RPC error:", e);
|
|
266
|
+
let t = e?.code ?? -32603, r = e?.data, i = e.message || "MCP request failed", a = g(o.id ?? null, t, i, r);
|
|
271
267
|
if (s) {
|
|
272
|
-
let e = new TextEncoder(), t =
|
|
273
|
-
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(
|
|
268
|
+
let e = new TextEncoder(), t = u(), n = new ReadableStream({ start(n) {
|
|
269
|
+
n.enqueue(e.encode(`id: ${t}\n\n`)), n.enqueue(e.encode(w(a, t))), n.close();
|
|
274
270
|
} });
|
|
275
271
|
return new Response(n, {
|
|
276
272
|
status: 200,
|
|
@@ -281,13 +277,13 @@ function D(D) {
|
|
|
281
277
|
}
|
|
282
278
|
});
|
|
283
279
|
}
|
|
284
|
-
return
|
|
280
|
+
return n.json(a, 200);
|
|
285
281
|
}
|
|
286
|
-
}), R.delete(`${
|
|
287
|
-
if (I.resourceMetadataUrl && !
|
|
288
|
-
let t = new TextEncoder(), n =
|
|
282
|
+
}), R.delete(`${n}`, (e) => I.resourceMetadataUrl && !x(e.req.header("authorization")) ? (e.header("WWW-Authenticate", p(I.resourceMetadataUrl)), e.json({ error: "Bearer token required" }, 401)) : e.json({ error: "Session termination not supported" }, 405)), R.get(`${n}`, (e) => {
|
|
283
|
+
if (I.resourceMetadataUrl && !x(e.req.header("authorization"))) return e.header("WWW-Authenticate", p(I.resourceMetadataUrl)), e.json({ error: "Bearer token required" }, 401);
|
|
284
|
+
let t = new TextEncoder(), n = u(), r, i = new ReadableStream({
|
|
289
285
|
start(e) {
|
|
290
|
-
e.enqueue(t.encode(
|
|
286
|
+
e.enqueue(t.encode(w({
|
|
291
287
|
jsonrpc: "2.0",
|
|
292
288
|
method: "mcp/ready",
|
|
293
289
|
params: { protocol: "streamable-http" }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils-DNrj-ryp.cjs`),t=require(`./mcp-transport-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils-DNrj-ryp.cjs`),t=require(`./mcp-transport-poPHl_2j.cjs`);function n(e){return{content:[{type:`text`,text:typeof e==`string`?e:JSON.stringify(e)}],isError:!1}}function r(e){return{content:[{type:`text`,text:e instanceof Error?e.message:String(e)}],isError:!0}}function i(i){let{semanticLayer:o,getSecurityContext:s,toolPrefix:c=`drizzle_cube_`,tools:l=[`discover`,`validate`,`load`,`chart`],prompts:u=t.d(),resources:d,app:f=!1}=i,p=!!f,m=typeof f==`object`?f:void 0,h=d??t.f(),g=p?[...h,...a(m)]:h,_=t.s({appEnabled:p}),v=new Map(_.map(e=>[e.name,e])),y=l.filter(e=>v.has(e)).map(e=>{let t=v.get(e),n={name:`${c}${e}`,description:t.description,inputSchema:t.inputSchema},r=t._meta;return r&&(n._meta=r),n}),b=y.map(e=>e.name),x=new Set;for(let e of l)x.add(e),x.add(`${c}${e}`);function S(e){return x.has(e)}async function C(t,i,a){let u=t.startsWith(c)?t.slice(c.length):t;if(!l.includes(u))return r(`Unknown tool: ${t}`);try{switch(u){case`discover`:return n(await e.d(o,i||{}));case`validate`:{let t=i||{};return t.query?n(await e.h(o,t)):r(`query is required`)}case`load`:{let t=i||{};return t.query?n(await e.p(o,await s(a),t)):r(`query is required`)}case`chart`:{let t=i||{};return t.query?n(await e.p(o,await s(a),t)):r(`query is required`)}default:return r(`Unknown tool: ${t}`)}}catch(e){return r(e)}}return{definitions:y,handle:C,handles:S,prompts:u,resources:g,toolNames:b}}function a(e){let n=t.p(e);return n?[{uri:t.n,name:`Drizzle Cube Visualization`,description:`Interactive chart visualization for query results`,mimeType:t.t,text:n}]:[]}exports.getCubeTools=i;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SemanticLayerCompiler, SecurityContext } from '../server';
|
|
2
2
|
import { DiscoverRequest, ValidateRequest, LoadRequest } from './utils';
|
|
3
3
|
import { MCPPrompt } from '../server/ai/mcp-prompts';
|
|
4
|
-
import { MCPResource } from './mcp-transport';
|
|
4
|
+
import { MCPResource, McpAppConfig } from './mcp-transport';
|
|
5
5
|
export type { MCPPrompt, MCPResource, DiscoverRequest, ValidateRequest, LoadRequest };
|
|
6
6
|
export type { SecurityContext } from '../server';
|
|
7
7
|
/**
|
|
@@ -55,8 +55,12 @@ export interface GetCubeToolsOptions {
|
|
|
55
55
|
prompts?: MCPPrompt[];
|
|
56
56
|
/** Custom MCP resources (defaults to built-in drizzle-cube resources) */
|
|
57
57
|
resources?: MCPResource[];
|
|
58
|
-
/**
|
|
59
|
-
|
|
58
|
+
/**
|
|
59
|
+
* Enable MCP App visualization for the load tool.
|
|
60
|
+
* Pass `true` to enable with defaults, or a config object to set locale options.
|
|
61
|
+
* @example app: { defaultLocale: 'nl-NL', detectBrowserLocale: false }
|
|
62
|
+
*/
|
|
63
|
+
app?: boolean | McpAppConfig;
|
|
60
64
|
}
|
|
61
65
|
/**
|
|
62
66
|
* The composable tools object returned by getCubeTools()
|