drizzle-cube 0.4.49 → 0.4.50

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/README.md CHANGED
@@ -174,7 +174,8 @@ Drizzle Cube includes a built-in **MCP server** that lets AI agents query your s
174
174
  |------|---------|
175
175
  | `drizzle_cube_discover` | Find relevant cubes by topic |
176
176
  | `drizzle_cube_validate` | Validate queries with auto-corrections |
177
- | `drizzle_cube_load` | Execute queries |
177
+ | `drizzle_cube_load` | Execute queries and return data |
178
+ | `drizzle_cube_chart` | Execute queries with interactive chart visualization |
178
179
 
179
180
  ### Connect AI Tools
180
181
 
@@ -1,3 +1,3 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-Kk_HTCeR.cjs`);let r=require(`express`);r=e._(r);let i=require(`cors`);i=e._(i);function a(a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,jsonLimit:p=`10mb`,cache:m,mcp:h={enabled:!0},agent:g}=a;if(!o||o.length===0)throw Error(`At least one cube must be provided in the cubes array`);let _=(0,r.Router)();d&&_.use((0,i.default)(d)),_.use(r.default.json({limit:p})),_.use(r.default.urlencoded({extended:!0,limit:p}));let v=new t.t({drizzle:s,schema:c,engineType:u,cache:m,rlsSetup:a.rlsSetup});if(o.forEach(e=>{v.registerCube(e)}),_.post(`${f}/load`,async(t,n)=>{try{let r=t.body.query||t.body,i=await l(t,n),a=v.validateQuery(r);if(!a.isValid)return n.status(400).json(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=t.headers[`x-cache-control`]===`no-cache`,s=await v.executeMultiCubeQuery(r,i,{skipCache:o});n.json(e.r(r,s,v))}catch(t){console.error(`Query execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Query execution failed`,500))}}),_.get(`${f}/load`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json(e.i(`Query parameter is required`,400));let i;try{i=JSON.parse(r)}catch{return n.status(400).json(e.i(`Invalid JSON in query parameter`,400))}let a=await l(t,n),o=v.validateQuery(i);if(!o.isValid)return n.status(400).json(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`,c=await v.executeMultiCubeQuery(i,a,{skipCache:s});n.json(e.r(i,c,v))}catch(t){console.error(`Query execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Query execution failed`,500))}}),_.post(`${f}/batch`,async(t,n)=>{try{let{queries:r}=t.body;if(!r||!Array.isArray(r))return n.status(400).json(e.i(`Request body must contain a "queries" array`,400));if(r.length===0)return n.status(400).json(e.i(`Queries array cannot be empty`,400));let i=await e.u(r,await l(t,n),v,{skipCache:t.headers[`x-cache-control`]===`no-cache`});n.json(i)}catch(t){console.error(`Batch execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Batch execution failed`,500))}}),_.get(`${f}/meta`,(t,n)=>{try{let t=v.getMetadata();n.json(e.a(t))}catch(t){console.error(`Metadata error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Failed to fetch metadata`,500))}}),_.post(`${f}/sql`,async(t,n)=>{try{let r=t.body,i=await l(t,n),a=v.validateQuery(r);if(!a.isValid)return n.status(400).json(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return n.status(400).json(e.i(`No measures or dimensions specified`,400));let s=o.split(`.`)[0],c=await v.generateSQL(s,r,i);n.json(e.o(r,c))}catch(t){console.error(`SQL generation error:`,String(t).replace(/\n|\r/g,``)),n.status(500).json(e.i(t instanceof Error?t.message:`SQL generation failed`,500))}}),_.get(`${f}/sql`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json(e.i(`Query parameter is required`,400));let i=JSON.parse(r),a=await l(t,n),o=v.validateQuery(i);if(!o.isValid)return n.status(400).json(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=i.measures?.[0]||i.dimensions?.[0];if(!s)return n.status(400).json(e.i(`No measures or dimensions specified`,400));let c=s.split(`.`)[0],u=await v.generateSQL(c,i,a);n.json(e.o(i,u))}catch(t){console.error(`SQL generation error:`,String(t).replace(/\n|\r/g,``)),n.status(500).json(e.i(t instanceof Error?t.message:`SQL generation failed`,500))}}),_.post(`${f}/dry-run`,async(t,n)=>{try{let r=await e.f(t.body.query||t.body,await l(t,n),v);n.json(r)}catch(e){console.error(`Dry-run error:`,e),n.status(400).json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),_.get(`${f}/dry-run`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json({error:`Query parameter is required`,valid:!1});let i=await e.f(JSON.parse(r),await l(t,n),v);n.json(i)}catch(e){console.error(`Dry-run error:`,e),n.status(400).json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),_.post(`${f}/explain`,async(e,t)=>{try{let n=e.body.query||e.body,r=e.body.options||{},i=await l(e,t),a=v.validateQuery(n);if(!a.isValid)return t.status(400).json({error:`Query validation failed: ${a.errors.join(`, `)}`});let o=await v.explainQuery(n,i,r);t.json(o)}catch(e){console.error(`Explain error:`,e),t.status(500).json({error:e instanceof Error?e.message:`Explain query failed`})}}),g&&_.post(`${f}/agent/chat`,async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require(`../handler-DumFgnNM.cjs`)),{message:r,sessionId:i,history:a}=e.body;if(!r||typeof r!=`string`)return t.status(400).json({error:`message is required and must be a string`});let o=(g.apiKey||``).trim();if(g.allowClientApiKey){let t=e.headers[`x-agent-api-key`];t&&(o=t.trim())}if(!o)return t.status(401).json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`});let s=g.allowClientApiKey?e.headers[`x-agent-provider`]:void 0,c=g.allowClientApiKey?e.headers[`x-agent-model`]:void 0,u=g.allowClientApiKey?e.headers[`x-agent-provider-endpoint`]:void 0,d=await l(e,t),f=g.buildSystemContext?.(d);t.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:r,sessionId:i,history:a,semanticLayer:v,securityContext:d,agentConfig:g,apiKey:o,systemContext:f,providerOverride:s,modelOverride:c,baseURLOverride:u});for await(let n of e)t.write(`data: ${JSON.stringify(n)}\n\n`)}catch(e){let n={type:`error`,data:{message:e instanceof Error?e.message:`Stream failed`}};t.write(`data: ${JSON.stringify(n)}\n\n`)}finally{t.end()}}catch(e){console.error(`Agent chat error:`,e),t.headersSent||t.status(500).json({error:e instanceof Error?e.message:`Agent chat failed`})}}),h.enabled!==!1){let e=h.basePath??`/mcp`;_.post(`${e}`,async(e,t)=>{let r=n._(e.headers.origin,h.allowedOrigins?{allowedOrigins:h.allowedOrigins}:{});if(!r.valid)return t.status(403).json(n.i(null,-32600,r.reason));let i=e.headers.accept;if(!n.g(i))return t.status(400).json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`));let a=n.f(e.headers);if(!a.ok)return t.status(426).json({error:`Unsupported MCP protocol version`,supported:a.supported});let o=n.p(e.body);if(!o)return t.status(400).json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`));let s=n.v(i),c=o.method===`initialize`;try{let r=await n.s(o.method,o.params,{semanticLayer:v,extractSecurityContext:l,rawRequest:e,rawResponse:t,negotiatedProtocol:a.negotiated,appEnabled:!!h.app});if(n.d(o))return t.status(202).end();let i=c&&r&&typeof r==`object`&&`sessionId`in r?r.sessionId:void 0;i&&t.setHeader(n.r,i);let u=n.a(o.id??null,r);if(s){let e=n.m();return t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(`id: ${e}\n\n`),t.write(n.h(u,e)),t.end()}return t.json(u)}catch(e){if(n.d(o))return console.error(`MCP notification processing error:`,String(e).replace(/\n|\r/g,``)),t.status(202).end();console.error(`MCP RPC error:`,String(e).replace(/\n|\r/g,``));let r=e?.code??-32603,i=e?.data,a=e.message||`MCP request failed`,c=n.i(o.id??null,r,a,i);if(s){let e=n.m();return t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(`id: ${e}\n\n`),t.write(n.h(c,e)),t.end()}return t.status(200).json(c)}}),_.get(`${e}`,async(e,t)=>{let r=n.m();t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3));let i=setInterval(()=>{t.write(`: keep-alive
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-B43Mcqo4.cjs`);let r=require(`express`);r=e._(r);let i=require(`cors`);i=e._(i);function a(a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,jsonLimit:p=`10mb`,cache:m,mcp:h={enabled:!0},agent:g}=a;if(!o||o.length===0)throw Error(`At least one cube must be provided in the cubes array`);let _=(0,r.Router)();d&&_.use((0,i.default)(d)),_.use(r.default.json({limit:p})),_.use(r.default.urlencoded({extended:!0,limit:p}));let v=new t.t({drizzle:s,schema:c,engineType:u,cache:m,rlsSetup:a.rlsSetup});if(o.forEach(e=>{v.registerCube(e)}),_.post(`${f}/load`,async(t,n)=>{try{let r=t.body.query||t.body,i=await l(t,n),a=v.validateQuery(r);if(!a.isValid)return n.status(400).json(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=t.headers[`x-cache-control`]===`no-cache`,s=await v.executeMultiCubeQuery(r,i,{skipCache:o});n.json(e.r(r,s,v))}catch(t){console.error(`Query execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Query execution failed`,500))}}),_.get(`${f}/load`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json(e.i(`Query parameter is required`,400));let i;try{i=JSON.parse(r)}catch{return n.status(400).json(e.i(`Invalid JSON in query parameter`,400))}let a=await l(t,n),o=v.validateQuery(i);if(!o.isValid)return n.status(400).json(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`,c=await v.executeMultiCubeQuery(i,a,{skipCache:s});n.json(e.r(i,c,v))}catch(t){console.error(`Query execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Query execution failed`,500))}}),_.post(`${f}/batch`,async(t,n)=>{try{let{queries:r}=t.body;if(!r||!Array.isArray(r))return n.status(400).json(e.i(`Request body must contain a "queries" array`,400));if(r.length===0)return n.status(400).json(e.i(`Queries array cannot be empty`,400));let i=await e.u(r,await l(t,n),v,{skipCache:t.headers[`x-cache-control`]===`no-cache`});n.json(i)}catch(t){console.error(`Batch execution error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Batch execution failed`,500))}}),_.get(`${f}/meta`,(t,n)=>{try{let t=v.getMetadata();n.json(e.a(t))}catch(t){console.error(`Metadata error:`,t),n.status(500).json(e.i(t instanceof Error?t.message:`Failed to fetch metadata`,500))}}),_.post(`${f}/sql`,async(t,n)=>{try{let r=t.body,i=await l(t,n),a=v.validateQuery(r);if(!a.isValid)return n.status(400).json(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return n.status(400).json(e.i(`No measures or dimensions specified`,400));let s=o.split(`.`)[0],c=await v.generateSQL(s,r,i);n.json(e.o(r,c))}catch(t){console.error(`SQL generation error:`,String(t).replace(/\n|\r/g,``)),n.status(500).json(e.i(t instanceof Error?t.message:`SQL generation failed`,500))}}),_.get(`${f}/sql`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json(e.i(`Query parameter is required`,400));let i=JSON.parse(r),a=await l(t,n),o=v.validateQuery(i);if(!o.isValid)return n.status(400).json(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=i.measures?.[0]||i.dimensions?.[0];if(!s)return n.status(400).json(e.i(`No measures or dimensions specified`,400));let c=s.split(`.`)[0],u=await v.generateSQL(c,i,a);n.json(e.o(i,u))}catch(t){console.error(`SQL generation error:`,String(t).replace(/\n|\r/g,``)),n.status(500).json(e.i(t instanceof Error?t.message:`SQL generation failed`,500))}}),_.post(`${f}/dry-run`,async(t,n)=>{try{let r=await e.f(t.body.query||t.body,await l(t,n),v);n.json(r)}catch(e){console.error(`Dry-run error:`,e),n.status(400).json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),_.get(`${f}/dry-run`,async(t,n)=>{try{let r=t.query.query;if(!r)return n.status(400).json({error:`Query parameter is required`,valid:!1});let i=await e.f(JSON.parse(r),await l(t,n),v);n.json(i)}catch(e){console.error(`Dry-run error:`,e),n.status(400).json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),_.post(`${f}/explain`,async(e,t)=>{try{let n=e.body.query||e.body,r=e.body.options||{},i=await l(e,t),a=v.validateQuery(n);if(!a.isValid)return t.status(400).json({error:`Query validation failed: ${a.errors.join(`, `)}`});let o=await v.explainQuery(n,i,r);t.json(o)}catch(e){console.error(`Explain error:`,e),t.status(500).json({error:e instanceof Error?e.message:`Explain query failed`})}}),g&&_.post(`${f}/agent/chat`,async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require(`../handler-DumFgnNM.cjs`)),{message:r,sessionId:i,history:a}=e.body;if(!r||typeof r!=`string`)return t.status(400).json({error:`message is required and must be a string`});let o=(g.apiKey||``).trim();if(g.allowClientApiKey){let t=e.headers[`x-agent-api-key`];t&&(o=t.trim())}if(!o)return t.status(401).json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`});let s=g.allowClientApiKey?e.headers[`x-agent-provider`]:void 0,c=g.allowClientApiKey?e.headers[`x-agent-model`]:void 0,u=g.allowClientApiKey?e.headers[`x-agent-provider-endpoint`]:void 0,d=await l(e,t),f=g.buildSystemContext?.(d);t.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:r,sessionId:i,history:a,semanticLayer:v,securityContext:d,agentConfig:g,apiKey:o,systemContext:f,providerOverride:s,modelOverride:c,baseURLOverride:u});for await(let n of e)t.write(`data: ${JSON.stringify(n)}\n\n`)}catch(e){let n={type:`error`,data:{message:e instanceof Error?e.message:`Stream failed`}};t.write(`data: ${JSON.stringify(n)}\n\n`)}finally{t.end()}}catch(e){console.error(`Agent chat error:`,e),t.headersSent||t.status(500).json({error:e instanceof Error?e.message:`Agent chat failed`})}}),h.enabled!==!1){let e=h.basePath??`/mcp`;_.post(`${e}`,async(e,t)=>{let r=n._(e.headers.origin,h.allowedOrigins?{allowedOrigins:h.allowedOrigins}:{});if(!r.valid)return t.status(403).json(n.i(null,-32600,r.reason));let i=e.headers.accept;if(!n.g(i))return t.status(400).json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`));let a=n.f(e.headers);if(!a.ok)return t.status(426).json({error:`Unsupported MCP protocol version`,supported:a.supported});let o=n.p(e.body);if(!o)return t.status(400).json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`));let s=n.v(i),c=o.method===`initialize`;try{let r=await n.s(o.method,o.params,{semanticLayer:v,extractSecurityContext:l,rawRequest:e,rawResponse:t,negotiatedProtocol:a.negotiated,appEnabled:!!h.app});if(n.d(o))return t.status(202).end();let i=c&&r&&typeof r==`object`&&`sessionId`in r?r.sessionId:void 0;i&&t.setHeader(n.r,i);let u=n.a(o.id??null,r);if(s){let e=n.m();return t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(`id: ${e}\n\n`),t.write(n.h(u,e)),t.end()}return t.json(u)}catch(e){if(n.d(o))return console.error(`MCP notification processing error:`,String(e).replace(/\n|\r/g,``)),t.status(202).end();console.error(`MCP RPC error:`,String(e).replace(/\n|\r/g,``));let r=e?.code??-32603,i=e?.data,a=e.message||`MCP request failed`,c=n.i(o.id??null,r,a,i);if(s){let e=n.m();return t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(`id: ${e}\n\n`),t.write(n.h(c,e)),t.end()}return t.status(200).json(c)}}),_.get(`${e}`,async(e,t)=>{let r=n.m();t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3));let i=setInterval(()=>{t.write(`: keep-alive
2
2
 
3
3
  `)},15e3);e.on(`close`,()=>{clearInterval(i)})}),_.delete(`${e}`,(e,t)=>t.status(405).json({error:`Session termination not supported`}))}return _.use((t,n,r,i)=>{console.error(`Express adapter error:`,t),r.headersSent||r.status(500).json(e.i(t,500))}),_}function o(e,t){let n=a(t);return e.use(`/`,n),e}function s(e){return o((0,r.default)(),e)}exports.createCubeApp=s,exports.createCubeRouter=a,exports.mountCubeRoutes=o;
@@ -1,6 +1,6 @@
1
1
  import { a as e, f as t, i as n, o as r, r as i, u as a } from "../utils-IH1ePsBd.js";
2
2
  import { t as o } from "../compiler-BXfrvebp.js";
3
- import { _ as s, a as c, d as l, f as u, g as d, h as f, i as p, m, p as h, r as g, s as _, v } from "../mcp-transport-BhPqU0Ft.js";
3
+ import { _ as s, a as c, d as l, f as u, g as d, h as f, i as p, m, p as h, r as g, s as _, v } from "../mcp-transport-CgX_c5Sj.js";
4
4
  import y, { Router as b } from "express";
5
5
  import x from "cors";
6
6
  //#region src/adapters/express/index.ts
@@ -1,3 +1,3 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-Kk_HTCeR.cjs`);var r=function(r,i,a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,bodyLimit:p=10485760,cache:m,mcp:h={enabled:!0},agent:g}=i;if(!o||o.length===0)return a(Error(`At least one cube must be provided in the cubes array`));d&&r.register(import(`@fastify/cors`),d),r.addHook(`onRequest`,async(e,t)=>{e.method===`POST`&&(e.body=void 0)});let _=new t.t({drizzle:s,schema:c,engineType:u,cache:m,rlsSetup:i.rlsSetup});if(o.forEach(e=>{_.registerCube(e)}),r.post(`${f}/load`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let r=t.body,i=r.query||r,a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`;return e.r(i,await _.executeMultiCubeQuery(i,a,{skipCache:s}),_)}catch(r){return t.log.error(r,`Query execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Query execution failed`,500))}}),r.get(`${f}/load`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:r}=t.query,i;try{i=JSON.parse(r)}catch{return n.status(400).send(e.i(`Invalid JSON in query parameter`,400))}let a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`,c=await _.executeMultiCubeQuery(i,a,{skipCache:s});return e.r(i,c,_)}catch(r){return t.log.error(r,`Query execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Query execution failed`,500))}}),r.post(`${f}/batch`,{bodyLimit:p,schema:{body:{type:`object`,required:[`queries`],properties:{queries:{type:`array`,items:{type:`object`}}}}}},async(t,n)=>{try{let{queries:r}=t.body;return!r||!Array.isArray(r)?n.status(400).send(e.i(`Request body must contain a "queries" array`,400)):r.length===0?n.status(400).send(e.i(`Queries array cannot be empty`,400)):await e.u(r,await l(t),_,{skipCache:t.headers[`x-cache-control`]===`no-cache`})}catch(r){return t.log.error(r,`Batch execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Batch execution failed`,500))}}),r.get(`${f}/meta`,async(t,n)=>{try{return e.a(_.getMetadata())}catch(r){return t.log.error(r,`Metadata error`),n.status(500).send(e.i(r instanceof Error?r.message:`Failed to fetch metadata`,500))}}),r.post(`${f}/sql`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let r=t.body,i=await l(t),a=_.validateQuery(r);if(!a.isValid)return n.status(400).send(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return n.status(400).send(e.i(`No measures or dimensions specified`,400));let s=o.split(`.`)[0];return e.o(r,await _.generateSQL(s,r,i))}catch(r){return t.log.error({err:String(r).replace(/\n|\r/g,``)},`SQL generation error`),n.status(500).send(e.i(r instanceof Error?r.message:`SQL generation failed`,500))}}),r.get(`${f}/sql`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:r}=t.query,i=JSON.parse(r),a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=i.measures?.[0]||i.dimensions?.[0];if(!s)return n.status(400).send(e.i(`No measures or dimensions specified`,400));let c=s.split(`.`)[0];return e.o(i,await _.generateSQL(c,i,a))}catch(r){return t.log.error({err:String(r).replace(/\n|\r/g,``)},`SQL generation error`),n.status(500).send(e.i(r instanceof Error?r.message:`SQL generation failed`,500))}}),r.post(`${f}/dry-run`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let n=t.body;return await e.f(n.query||n,await l(t),_)}catch(e){return t.log.error(e,`Dry-run error`),n.status(400).send({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),r.get(`${f}/dry-run`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:n}=t.query;return await e.f(JSON.parse(n),await l(t),_)}catch(e){return t.log.error(e,`Dry-run error`),n.status(400).send({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),r.post(`${f}/explain`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{try{let n=e.body,r=n.query||n,i=n.options||{},a=await l(e),o=_.validateQuery(r);return o.isValid?await _.explainQuery(r,a,i):t.status(400).send({error:`Query validation failed: ${o.errors.join(`, `)}`})}catch(n){return e.log.error(n,`Explain error`),t.status(500).send({error:n instanceof Error?n.message:`Explain query failed`})}}),g&&r.post(`${f}/agent/chat`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require(`../handler-DumFgnNM.cjs`)),{message:r,sessionId:i,history:a}=e.body;if(!r||typeof r!=`string`)return t.status(400).send({error:`message is required and must be a string`});let o=(g.apiKey||``).trim();if(g.allowClientApiKey){let t=e.headers[`x-agent-api-key`];t&&(o=t.trim())}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.`});let s=g.allowClientApiKey?e.headers[`x-agent-provider`]:void 0,c=g.allowClientApiKey?e.headers[`x-agent-model`]:void 0,u=g.allowClientApiKey?e.headers[`x-agent-provider-endpoint`]:void 0,d=await l(e),f=g.buildSystemContext?.(d);t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:r,sessionId:i,history:a,semanticLayer:_,securityContext:d,agentConfig:g,apiKey:o,systemContext:f,providerOverride:s,modelOverride:c,baseURLOverride:u});for await(let n of e)t.raw.write(`data: ${JSON.stringify(n)}\n\n`)}catch(e){let n={type:`error`,data:{message:e instanceof Error?e.message:`Stream failed`}};t.raw.write(`data: ${JSON.stringify(n)}\n\n`)}finally{t.raw.end()}}catch(n){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`})}}),h.enabled!==!1){let e=h.basePath??`/mcp`;r.post(`${e}`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{let r=n._(e.headers.origin,h.allowedOrigins?{allowedOrigins:h.allowedOrigins}:{});if(!r.valid)return t.status(403).send(n.i(null,-32600,r.reason));let i=e.headers.accept;if(!n.g(i))return t.status(400).send(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`));let a=n.f(e.headers);if(!a.ok)return t.status(426).send({error:`Unsupported MCP protocol version`,supported:a.supported});let o=n.p(e.body);if(!o)return t.status(400).send(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`));let s=n.v(i),c=o.method===`initialize`;try{let r=await n.s(o.method,o.params,{semanticLayer:_,extractSecurityContext:l,rawRequest:e,rawResponse:t,negotiatedProtocol:a.negotiated,appEnabled:!!h.app});if(n.d(o))return t.status(202).send();let i=c&&r&&typeof r==`object`&&`sessionId`in r?r.sessionId:void 0;i&&t.header(n.r,i);let u=n.a(o.id??null,r);if(s){let e=n.m();t.header(`Content-Type`,`text/event-stream`).header(`Cache-Control`,`no-cache`).header(`Connection`,`keep-alive`).send(`id: ${e}\n\n${n.h(u,e)}`);return}return t.send(u)}catch(r){if(n.d(o))return e.log.error({err:String(r).replace(/\n|\r/g,``)},`MCP notification processing error`),t.status(202).send();e.log.error({err:String(r).replace(/\n|\r/g,``)},`MCP RPC error`);let i=r?.code??-32603,a=r?.data,c=r.message||`MCP request failed`,l=n.i(o.id??null,i,c,a);if(s){let e=n.m();t.header(`Content-Type`,`text/event-stream`).header(`Cache-Control`,`no-cache`).header(`Connection`,`keep-alive`).send(`id: ${e}\n\n${n.h(l,e)}`);return}return t.send(l)}}),r.get(`${e}`,async(e,t)=>{let r=n.m();t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}),t.raw.write(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3));let i=setInterval(()=>{t.raw.write(`: keep-alive
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-B43Mcqo4.cjs`);var r=function(r,i,a){let{cubes:o,drizzle:s,schema:c,extractSecurityContext:l,engineType:u,cors:d,basePath:f=`/cubejs-api/v1`,bodyLimit:p=10485760,cache:m,mcp:h={enabled:!0},agent:g}=i;if(!o||o.length===0)return a(Error(`At least one cube must be provided in the cubes array`));d&&r.register(import(`@fastify/cors`),d),r.addHook(`onRequest`,async(e,t)=>{e.method===`POST`&&(e.body=void 0)});let _=new t.t({drizzle:s,schema:c,engineType:u,cache:m,rlsSetup:i.rlsSetup});if(o.forEach(e=>{_.registerCube(e)}),r.post(`${f}/load`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let r=t.body,i=r.query||r,a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`;return e.r(i,await _.executeMultiCubeQuery(i,a,{skipCache:s}),_)}catch(r){return t.log.error(r,`Query execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Query execution failed`,500))}}),r.get(`${f}/load`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:r}=t.query,i;try{i=JSON.parse(r)}catch{return n.status(400).send(e.i(`Invalid JSON in query parameter`,400))}let a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=t.headers[`x-cache-control`]===`no-cache`,c=await _.executeMultiCubeQuery(i,a,{skipCache:s});return e.r(i,c,_)}catch(r){return t.log.error(r,`Query execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Query execution failed`,500))}}),r.post(`${f}/batch`,{bodyLimit:p,schema:{body:{type:`object`,required:[`queries`],properties:{queries:{type:`array`,items:{type:`object`}}}}}},async(t,n)=>{try{let{queries:r}=t.body;return!r||!Array.isArray(r)?n.status(400).send(e.i(`Request body must contain a "queries" array`,400)):r.length===0?n.status(400).send(e.i(`Queries array cannot be empty`,400)):await e.u(r,await l(t),_,{skipCache:t.headers[`x-cache-control`]===`no-cache`})}catch(r){return t.log.error(r,`Batch execution error`),n.status(500).send(e.i(r instanceof Error?r.message:`Batch execution failed`,500))}}),r.get(`${f}/meta`,async(t,n)=>{try{return e.a(_.getMetadata())}catch(r){return t.log.error(r,`Metadata error`),n.status(500).send(e.i(r instanceof Error?r.message:`Failed to fetch metadata`,500))}}),r.post(`${f}/sql`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let r=t.body,i=await l(t),a=_.validateQuery(r);if(!a.isValid)return n.status(400).send(e.i(`Query validation failed: ${a.errors.join(`, `)}`,400));let o=r.measures?.[0]||r.dimensions?.[0];if(!o)return n.status(400).send(e.i(`No measures or dimensions specified`,400));let s=o.split(`.`)[0];return e.o(r,await _.generateSQL(s,r,i))}catch(r){return t.log.error({err:String(r).replace(/\n|\r/g,``)},`SQL generation error`),n.status(500).send(e.i(r instanceof Error?r.message:`SQL generation failed`,500))}}),r.get(`${f}/sql`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:r}=t.query,i=JSON.parse(r),a=await l(t),o=_.validateQuery(i);if(!o.isValid)return n.status(400).send(e.i(`Query validation failed: ${o.errors.join(`, `)}`,400));let s=i.measures?.[0]||i.dimensions?.[0];if(!s)return n.status(400).send(e.i(`No measures or dimensions specified`,400));let c=s.split(`.`)[0];return e.o(i,await _.generateSQL(c,i,a))}catch(r){return t.log.error({err:String(r).replace(/\n|\r/g,``)},`SQL generation error`),n.status(500).send(e.i(r instanceof Error?r.message:`SQL generation failed`,500))}}),r.post(`${f}/dry-run`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(t,n)=>{try{let n=t.body;return await e.f(n.query||n,await l(t),_)}catch(e){return t.log.error(e,`Dry-run error`),n.status(400).send({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),r.get(`${f}/dry-run`,{schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}},async(t,n)=>{try{let{query:n}=t.query;return await e.f(JSON.parse(n),await l(t),_)}catch(e){return t.log.error(e,`Dry-run error`),n.status(400).send({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1})}}),r.post(`${f}/explain`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{try{let n=e.body,r=n.query||n,i=n.options||{},a=await l(e),o=_.validateQuery(r);return o.isValid?await _.explainQuery(r,a,i):t.status(400).send({error:`Query validation failed: ${o.errors.join(`, `)}`})}catch(n){return e.log.error(n,`Explain error`),t.status(500).send({error:n instanceof Error?n.message:`Explain query failed`})}}),g&&r.post(`${f}/agent/chat`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require(`../handler-DumFgnNM.cjs`)),{message:r,sessionId:i,history:a}=e.body;if(!r||typeof r!=`string`)return t.status(400).send({error:`message is required and must be a string`});let o=(g.apiKey||``).trim();if(g.allowClientApiKey){let t=e.headers[`x-agent-api-key`];t&&(o=t.trim())}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.`});let s=g.allowClientApiKey?e.headers[`x-agent-provider`]:void 0,c=g.allowClientApiKey?e.headers[`x-agent-model`]:void 0,u=g.allowClientApiKey?e.headers[`x-agent-provider-endpoint`]:void 0,d=await l(e),f=g.buildSystemContext?.(d);t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:r,sessionId:i,history:a,semanticLayer:_,securityContext:d,agentConfig:g,apiKey:o,systemContext:f,providerOverride:s,modelOverride:c,baseURLOverride:u});for await(let n of e)t.raw.write(`data: ${JSON.stringify(n)}\n\n`)}catch(e){let n={type:`error`,data:{message:e instanceof Error?e.message:`Stream failed`}};t.raw.write(`data: ${JSON.stringify(n)}\n\n`)}finally{t.raw.end()}}catch(n){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`})}}),h.enabled!==!1){let e=h.basePath??`/mcp`;r.post(`${e}`,{bodyLimit:p,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{let r=n._(e.headers.origin,h.allowedOrigins?{allowedOrigins:h.allowedOrigins}:{});if(!r.valid)return t.status(403).send(n.i(null,-32600,r.reason));let i=e.headers.accept;if(!n.g(i))return t.status(400).send(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`));let a=n.f(e.headers);if(!a.ok)return t.status(426).send({error:`Unsupported MCP protocol version`,supported:a.supported});let o=n.p(e.body);if(!o)return t.status(400).send(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`));let s=n.v(i),c=o.method===`initialize`;try{let r=await n.s(o.method,o.params,{semanticLayer:_,extractSecurityContext:l,rawRequest:e,rawResponse:t,negotiatedProtocol:a.negotiated,appEnabled:!!h.app});if(n.d(o))return t.status(202).send();let i=c&&r&&typeof r==`object`&&`sessionId`in r?r.sessionId:void 0;i&&t.header(n.r,i);let u=n.a(o.id??null,r);if(s){let e=n.m();t.header(`Content-Type`,`text/event-stream`).header(`Cache-Control`,`no-cache`).header(`Connection`,`keep-alive`).send(`id: ${e}\n\n${n.h(u,e)}`);return}return t.send(u)}catch(r){if(n.d(o))return e.log.error({err:String(r).replace(/\n|\r/g,``)},`MCP notification processing error`),t.status(202).send();e.log.error({err:String(r).replace(/\n|\r/g,``)},`MCP RPC error`);let i=r?.code??-32603,a=r?.data,c=r.message||`MCP request failed`,l=n.i(o.id??null,i,c,a);if(s){let e=n.m();t.header(`Content-Type`,`text/event-stream`).header(`Cache-Control`,`no-cache`).header(`Connection`,`keep-alive`).send(`id: ${e}\n\n${n.h(l,e)}`);return}return t.send(l)}}),r.get(`${e}`,async(e,t)=>{let r=n.m();t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}),t.raw.write(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3));let i=setInterval(()=>{t.raw.write(`: keep-alive
2
2
 
3
3
  `)},15e3);e.raw.on(`close`,()=>{clearInterval(i)})}),r.delete(`${e}`,async(e,t)=>t.status(405).send({error:`Session termination not supported`}))}r.setErrorHandler(async(t,n,r)=>(n.log.error(t,`Fastify cube adapter error`),r.statusCode<400&&r.status(500),e.i(t instanceof Error?t:String(t),r.statusCode))),a()};async function i(e,t){await e.register(r,t)}function a(e){let t=require(`fastify`)({logger:!0});return t.register(r,e),t}exports.createCubeApp=a,exports.cubePlugin=r,exports.registerCubeRoutes=i;
@@ -1,6 +1,6 @@
1
1
  import { _ as e, a as t, f as n, i as r, o as i, r as a, u as o } from "../utils-IH1ePsBd.js";
2
2
  import { t as s } from "../compiler-BXfrvebp.js";
3
- import { _ as c, a as l, d as u, f as d, g as f, h as p, i as m, m as h, p as g, r as _, s as v, v as y } from "../mcp-transport-BhPqU0Ft.js";
3
+ import { _ as c, a as l, d as u, f as d, g as f, h as p, i as m, m as h, p as g, r as _, s as v, v as y } from "../mcp-transport-CgX_c5Sj.js";
4
4
  //#region src/adapters/fastify/index.ts
5
5
  var b = function(e, b, x) {
6
6
  let { cubes: S, drizzle: C, schema: w, extractSecurityContext: T, engineType: E, cors: D, basePath: O = "/cubejs-api/v1", bodyLimit: k = 10485760, cache: A, mcp: j = { enabled: !0 }, agent: M } = b;
@@ -1,3 +1,3 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-Kk_HTCeR.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;d&&g.use(`/*`,i(d));let _=a.semanticLayer??new t.t({drizzle:s,schema:c,engineType:u,cache:p,rlsSetup:a.rlsSetup});if(!a.semanticLayer&&o&&o.forEach(e=>{_.registerCube(e)}),g.post(`${f}/load`,async t=>{try{let n=await t.req.json(),r=n.query||n,i=await l(t),a=_.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 _.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,_))}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 l(t),a=_.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 _.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,_))}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 l(t),_,{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=_.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 l(t),i=_.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 _.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 l(t),a=_.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 _.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 l(t),_);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 l(t),_);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 l(e),a=_.validateQuery(n);if(!a.isValid)return e.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=await _.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-DumFgnNM.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,u=await l(e),d=h.buildSystemContext?.(u),f=new TextEncoder,p=new ReadableStream({async start(e){try{let l=t({message:n,sessionId:r,history:i,semanticLayer:_,securityContext:u,agentConfig:h,apiKey:a,systemContext:d,providerOverride:o,modelOverride:s,baseURLOverride:c});for await(let t of l){let n=`data: ${JSON.stringify(t)}\n\n`;e.enqueue(f.encode(n))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(f.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}});return new Response(p,{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(_.getMetadata(),null,2)},t=[...n.l(),e],r=n.c(),i=m.basePath??`/mcp`;g.post(`${i}`,async e=>{let i=n._(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.g(a))return e.json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`),400);let o=n.f(e.req.header());if(!o.ok)return e.json({error:`Unsupported MCP protocol version`,supported:o.supported},426);let s=n.p(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.v(a),u=s.method===`initialize`;try{let i=await n.s(s.method,s.params,{semanticLayer:_,extractSecurityContext:l,rawRequest:e,rawResponse:null,negotiatedProtocol:o.negotiated,resources:t,prompts:r,appEnabled:!!m.app});if(n.d(s))return e.body(null,202);let a=n.a(s.id??null,i),d=u&&i&&typeof i==`object`&&`sessionId`in i?i.sessionId:void 0,f={};if(d&&(f[n.r]=d),c){let e=new TextEncoder,t=n.m(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.h(a,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...f}})}return e.json(a,200,f)}catch(t){if(n.d(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.m(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.h(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=>e.json({error:`Session termination not supported`},405)),g.get(`${i}`,e=>{let t=new TextEncoder,r=n.m(),i,a=new ReadableStream({start(e){e.enqueue(t.encode(n.h({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-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-B43Mcqo4.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;d&&g.use(`/*`,i(d));let _=a.semanticLayer??new t.t({drizzle:s,schema:c,engineType:u,cache:p,rlsSetup:a.rlsSetup});if(!a.semanticLayer&&o&&o.forEach(e=>{_.registerCube(e)}),g.post(`${f}/load`,async t=>{try{let n=await t.req.json(),r=n.query||n,i=await l(t),a=_.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 _.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,_))}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 l(t),a=_.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 _.executeMultiCubeQuery(r,i,{skipCache:o});return t.json(e.r(r,s,_))}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 l(t),_,{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=_.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 l(t),i=_.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 _.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 l(t),a=_.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 _.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 l(t),_);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 l(t),_);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 l(e),a=_.validateQuery(n);if(!a.isValid)return e.json({error:`Query validation failed: ${a.errors.join(`, `)}`},400);let o=await _.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-DumFgnNM.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,u=await l(e),d=h.buildSystemContext?.(u),f=new TextEncoder,p=new ReadableStream({async start(e){try{let l=t({message:n,sessionId:r,history:i,semanticLayer:_,securityContext:u,agentConfig:h,apiKey:a,systemContext:d,providerOverride:o,modelOverride:s,baseURLOverride:c});for await(let t of l){let n=`data: ${JSON.stringify(t)}\n\n`;e.enqueue(f.encode(n))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(f.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}});return new Response(p,{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(_.getMetadata(),null,2)},t=[...n.l(),e],r=n.c(),i=m.basePath??`/mcp`;g.post(`${i}`,async e=>{let i=n._(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.g(a))return e.json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`),400);let o=n.f(e.req.header());if(!o.ok)return e.json({error:`Unsupported MCP protocol version`,supported:o.supported},426);let s=n.p(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.v(a),u=s.method===`initialize`;try{let i=await n.s(s.method,s.params,{semanticLayer:_,extractSecurityContext:l,rawRequest:e,rawResponse:null,negotiatedProtocol:o.negotiated,resources:t,prompts:r,appEnabled:!!m.app});if(n.d(s))return e.body(null,202);let a=n.a(s.id??null,i),d=u&&i&&typeof i==`object`&&`sessionId`in i?i.sessionId:void 0,f={};if(d&&(f[n.r]=d),c){let e=new TextEncoder,t=n.m(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.h(a,t))),r.close()}});return new Response(r,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...f}})}return e.json(a,200,f)}catch(t){if(n.d(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.m(),r=new ReadableStream({start(r){r.enqueue(e.encode(`id: ${t}\n\n`)),r.enqueue(e.encode(n.h(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=>e.json({error:`Session termination not supported`},405)),g.get(`${i}`,e=>{let t=new TextEncoder,r=n.m(),i,a=new ReadableStream({start(e){e.enqueue(t.encode(n.h({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-IH1ePsBd.js";
2
2
  import { t as a } from "../compiler-BXfrvebp.js";
3
- import { _ as o, a as s, c, d as l, f as u, g as d, h as f, i as p, l as m, m as h, p as g, r as _, s as v, v as y } from "../mcp-transport-BhPqU0Ft.js";
3
+ import { _ as o, a as s, c, d as l, f as u, g as d, h as f, i as p, l as m, m as h, p as g, r as _, s as v, v as y } from "../mcp-transport-CgX_c5Sj.js";
4
4
  import { Hono as b } from "hono";
5
5
  //#region node_modules/hono/dist/middleware/cors/index.js
6
6
  var x = (e) => {
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils-CyBt-as9.cjs`),t=require(`./mcp-transport-Kk_HTCeR.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`],prompts:u=t.c(),resources:d,app:f=!1}=i,p=d??t.l(),m=f?[...p,...a()]:p,h=t.o({appEnabled:f}),g=new Map(h.map(e=>[e.name,e])),_=l.filter(e=>g.has(e)).map(e=>{let t=g.get(e),n={name:`${c}${e}`,description:t.description,inputSchema:t.inputSchema},r=t._meta;return r&&(n._meta=r),n}),v=_.map(e=>e.name),y=new Set;for(let e of l)y.add(e),y.add(`${c}${e}`);function b(e){return y.has(e)}async function x(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`)}default:return r(`Unknown tool: ${t}`)}}catch(e){return r(e)}}return{definitions:_,handle:x,handles:b,prompts:u,resources:m,toolNames:v}}function a(){let e=t.u();return e?[{uri:t.n,name:`Drizzle Cube Visualization`,description:`Interactive chart visualization for query results`,mimeType:t.t,text:e}]:[]}exports.getCubeTools=i;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`./utils-CyBt-as9.cjs`),t=require(`./mcp-transport-B43Mcqo4.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.c(),resources:d,app:f=!1}=i,p=d??t.l(),m=f?[...p,...a()]:p,h=t.o({appEnabled:f}),g=new Map(h.map(e=>[e.name,e])),_=l.filter(e=>g.has(e)).map(e=>{let t=g.get(e),n={name:`${c}${e}`,description:t.description,inputSchema:t.inputSchema},r=t._meta;return r&&(n._meta=r),n}),v=_.map(e=>e.name),y=new Set;for(let e of l)y.add(e),y.add(`${c}${e}`);function b(e){return y.has(e)}async function x(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:_,handle:x,handles:b,prompts:u,resources:m,toolNames:v}}function a(){let e=t.u();return e?[{uri:t.n,name:`Drizzle Cube Visualization`,description:`Interactive chart visualization for query results`,mimeType:t.t,text:e}]:[]}exports.getCubeTools=i;
@@ -1,5 +1,5 @@
1
1
  import { d as e, h as t, p as n } from "./utils-IH1ePsBd.js";
2
- import { c as r, l as i, n as a, o, t as s, u as c } from "./mcp-transport-BhPqU0Ft.js";
2
+ import { c as r, l as i, n as a, o, t as s, u as c } from "./mcp-transport-CgX_c5Sj.js";
3
3
  //#region src/adapters/mcp-tools.ts
4
4
  function l(e) {
5
5
  return {
@@ -23,7 +23,8 @@ function d(a) {
23
23
  let { semanticLayer: s, getSecurityContext: c, toolPrefix: d = "drizzle_cube_", tools: p = [
24
24
  "discover",
25
25
  "validate",
26
- "load"
26
+ "load",
27
+ "chart"
27
28
  ], prompts: m = r(), resources: h, app: g = !1 } = a, _ = h ?? i(), v = g ? [..._, ...f()] : _, y = o({ appEnabled: g }), b = new Map(y.map((e) => [e.name, e])), x = p.filter((e) => b.has(e)).map((e) => {
28
29
  let t = b.get(e), n = {
29
30
  name: `${d}${e}`,
@@ -50,6 +51,10 @@ function d(a) {
50
51
  let e = i || {};
51
52
  return e.query ? l(await n(s, await c(a), e)) : u("query is required");
52
53
  }
54
+ case "chart": {
55
+ let e = i || {};
56
+ return e.query ? l(await n(s, await c(a), e)) : u("query is required");
57
+ }
53
58
  default: return u(`Unknown tool: ${r}`);
54
59
  }
55
60
  } catch (e) {
@@ -28,8 +28,12 @@ Key rules:
28
28
  - Time series: use timeDimensions WITH granularity
29
29
  - Top N pattern: filters + order + limit
30
30
 
31
- CHART HINTS: Include a "chart" object to control the MCP App UI visualization.
32
- Chart types: bar, line, area, pie, scatter, bubble, radar, treemap, kpiNumber, kpiDelta, table, heatmap, funnel, sankey, sunburst, retentionHeatmap
33
- Guidelines: single number -> kpiNumber, trend -> line/area, categories -> bar, part-of-whole -> pie, correlation -> scatter/bubble, distribution -> boxPlot`,inputSchema:{type:`object`,required:[`query`],properties:{query:{type:`object`,description:`Semantic query object. Regular: { measures, dimensions, filters, timeDimensions, order, limit }. Funnel: { funnel: {...} }. Flow: { flow: {...} }. Retention: { retention: {...} }.`,properties:t.a},chart:{type:`object`,description:`Optional chart configuration for the MCP App UI. Uses the same chartConfig/displayConfig as the agent portlet system. If omitted, chart type is auto-detected.`,properties:{type:{type:`string`,enum:[`bar`,`line`,`area`,`pie`,`scatter`,`bubble`,`radar`,`radialBar`,`treemap`,`table`,`kpiNumber`,`kpiDelta`,`heatmap`,`boxPlot`,`funnel`,`sankey`,`sunburst`,`retentionHeatmap`,`retentionCombined`,`waterfall`,`activityGrid`],description:`Chart type to render`},title:{type:`string`,description:`Chart title`},chartConfig:{type:`object`,description:`Axis configuration — same schema as agent add_portlet chartConfig.`,properties:{xAxis:{type:`array`,items:{type:`string`},description:`Dimension fields for X axis`},yAxis:{type:`array`,items:{type:`string`},description:`Measure fields for Y axis`},series:{type:`array`,items:{type:`string`},description:`Dimension for series splitting (grouped/stacked)`},yAxisAssignment:{type:`object`,description:`Dual Y-axis: map measure fields to "left" or "right". Only bar/line/area with 2+ measures of different scales.`},sizeField:{type:`string`,description:`Bubble chart size field`},colorField:{type:`string`,description:`Bubble chart color field`}}},displayConfig:{type:`object`,description:`Display options.`,properties:{showLegend:{type:`boolean`},showGrid:{type:`boolean`},showTooltip:{type:`boolean`},stacked:{type:`boolean`},stackType:{type:`string`,enum:[`none`,`normal`,`percent`]},orientation:{type:`string`,enum:[`horizontal`,`vertical`]}}},xAxis:{type:`string`,description:`Deprecated: use chartConfig.xAxis`},yAxis:{type:`array`,items:{type:`string`},description:`Deprecated: use chartConfig.yAxis`}}}}}}];if(e?.appEnabled){let e=n.find(e=>e.name===`load`);e&&(e._meta={ui:{resourceUri:r}})}return n}async function C(t,n){let{semanticLayer:r,extractSecurityContext:i,rawRequest:a,rawResponse:o}=n,s=t||{};if(!s.name)throw v(-32602,`name is required for tools/call`);let c=s.arguments;try{switch(s.name){case`discover`:return w(await e.d(r,c||{}));case`validate`:{let t=c||{};if(!t.query)throw v(-32602,`query is required`);return w(await e.h(r,t))}case`load`:{let t=c||{};if(!t.query)throw v(-32602,`query is required`);return w(await e.p(r,await i(a,o),t))}default:throw v(-32601,`Unknown tool: ${s.name}`)}}catch(e){if(e?.code===-32602||e?.code===-32601)throw e;let t=e instanceof Error?e.message:String(e);return{content:[{type:`text`,text:JSON.stringify({error:t})}],isError:!0}}}function w(e){return{content:[{type:`text`,text:typeof e==`string`?e:JSON.stringify(e)}],isError:!1}}function T(){let e=a();return e?[{uri:r,name:`Drizzle Cube Visualization`,description:`Interactive chart visualization for query results`,mimeType:i,text:e}]:[]}var E=t.i(),D=[{uri:`drizzle-cube://quickstart`,name:`Drizzle Cube MCP Quickstart`,description:`Minimal guide for using discover/validate/load`,mimeType:`text/markdown`,text:[`# Drizzle Cube MCP Quickstart`,``,`Tools:`,`- discover: { topic?, intent?, limit?, minScore? } -> cubes list`,`- validate: { query } -> corrected query + issues`,`- load: { query } -> data + annotation`,``,`Recommended flow:`,`1) tools/list`,`2) tools/call name=discover intent="<goal>"`,`3) tools/call name=validate query=<draft> (optional)`,`4) tools/call name=load query=<validated>`,``,`Query shapes supported:`,`- regular: { measures, dimensions, filters, timeDimensions, order, limit, offset, ungrouped }`,`- funnel: { funnel: { bindingKey, timeDimension, steps[], includeTimeMetrics?, globalTimeWindow? } }`,`- flow: { flow: { bindingKey, timeDimension, eventDimension, startingStep: { name, filter }, stepsBefore, stepsAfter } }`,`- retention: { retention: { timeDimension, bindingKey, dateRange: { start, end }, granularity, periods, retentionType } }`,``,`Filter rules: flat arrays of { member, operator, values }. Use { and: [...] } or { or: [...] } for logical grouping.`].join(`
31
+ Use "load" for data retrieval. Use "chart" to visualise results with an interactive chart.`,inputSchema:{type:`object`,required:[`query`],properties:{query:{type:`object`,description:`Semantic query object. Regular: { measures, dimensions, filters, timeDimensions, order, limit }. Funnel: { funnel: {...} }. Flow: { flow: {...} }. Retention: { retention: {...} }.`,properties:t.a}}}}];if(e?.appEnabled){n.push({name:`chart`,description:`Execute a semantic query and render an interactive chart visualization.
32
+
33
+ Same query format as "load", but renders results in the MCP App chart UI.
34
+ Include a "chart" object to control the visualization.
35
+
36
+ Chart types: bar, line, area, pie, scatter, bubble, radar, treemap, kpiNumber, kpiDelta, table, heatmap, funnel, sankey, sunburst, waterfall, activityGrid, boxPlot
37
+ Guidelines: single number -> kpiNumber, trend -> line/area, categories -> bar, part-of-whole -> pie, correlation -> scatter/bubble, distribution -> boxPlot`,inputSchema:{type:`object`,required:[`query`],properties:{query:{type:`object`,description:`Semantic query object. Same format as the load tool.`,properties:t.a},chart:{type:`object`,description:`Chart configuration for the visualization. If omitted, chart type is auto-detected from query shape.`,properties:{type:{type:`string`,enum:[`bar`,`line`,`area`,`pie`,`scatter`,`bubble`,`radar`,`radialBar`,`treemap`,`table`,`kpiNumber`,`kpiDelta`,`heatmap`,`boxPlot`,`funnel`,`sankey`,`sunburst`,`retentionHeatmap`,`retentionCombined`,`waterfall`,`activityGrid`],description:`Chart type to render`},title:{type:`string`,description:`Chart title`},chartConfig:{type:`object`,description:`Axis configuration — same schema as agent add_portlet chartConfig.`,properties:{xAxis:{type:`array`,items:{type:`string`},description:`Dimension fields for X axis`},yAxis:{type:`array`,items:{type:`string`},description:`Measure fields for Y axis`},series:{type:`array`,items:{type:`string`},description:`Dimension for series splitting (grouped/stacked)`},yAxisAssignment:{type:`object`,description:`Dual Y-axis: map measure fields to "left" or "right". Only bar/line/area with 2+ measures of different scales.`},sizeField:{type:`string`,description:`Bubble chart size field`},colorField:{type:`string`,description:`Bubble chart color field`}}},displayConfig:{type:`object`,description:`Display options.`,properties:{showLegend:{type:`boolean`},showGrid:{type:`boolean`},showTooltip:{type:`boolean`},stacked:{type:`boolean`},stackType:{type:`string`,enum:[`none`,`normal`,`percent`]},orientation:{type:`string`,enum:[`horizontal`,`vertical`]}}},xAxis:{type:`string`,description:`Deprecated: use chartConfig.xAxis`},yAxis:{type:`array`,items:{type:`string`},description:`Deprecated: use chartConfig.yAxis`}}}}}});let e=n.find(e=>e.name===`chart`);e&&(e._meta={ui:{resourceUri:r}})}return n}async function C(t,n){let{semanticLayer:r,extractSecurityContext:i,rawRequest:a,rawResponse:o}=n,s=t||{};if(!s.name)throw v(-32602,`name is required for tools/call`);let c=s.arguments;try{switch(s.name){case`discover`:return w(await e.d(r,c||{}));case`validate`:{let t=c||{};if(!t.query)throw v(-32602,`query is required`);return w(await e.h(r,t))}case`load`:{let t=c||{};if(!t.query)throw v(-32602,`query is required`);return w(await e.p(r,await i(a,o),t))}case`chart`:{let t=c||{};if(!t.query)throw v(-32602,`query is required`);return w(await e.p(r,await i(a,o),t))}default:throw v(-32601,`Unknown tool: ${s.name}`)}}catch(e){if(e?.code===-32602||e?.code===-32601)throw e;let t=e instanceof Error?e.message:String(e);return{content:[{type:`text`,text:JSON.stringify({error:t})}],isError:!0}}}function w(e){return{content:[{type:`text`,text:typeof e==`string`?e:JSON.stringify(e)}],isError:!1}}function T(){let e=a();return e?[{uri:r,name:`Drizzle Cube Visualization`,description:`Interactive chart visualization for query results`,mimeType:i,text:e}]:[]}var E=t.i(),D=[{uri:`drizzle-cube://quickstart`,name:`Drizzle Cube MCP Quickstart`,description:`Minimal guide for using discover/validate/load`,mimeType:`text/markdown`,text:[`# Drizzle Cube MCP Quickstart`,``,`Tools:`,`- discover: { topic?, intent?, limit?, minScore? } -> cubes list`,`- validate: { query } -> corrected query + issues`,`- load: { query } -> data + annotation (text only)`,`- chart: { query, chart? } -> data + interactive chart visualization`,``,`Recommended flow:`,`1) tools/call name=discover intent="<goal>"`,`2) tools/call name=validate query=<draft> (optional)`,`3) tools/call name=load query=<validated> (data only) OR name=chart query=<validated> chart={type, ...} (with visualization)`,``,`Query shapes supported:`,`- regular: { measures, dimensions, filters, timeDimensions, order, limit, offset, ungrouped }`,`- funnel: { funnel: { bindingKey, timeDimension, steps[], includeTimeMetrics?, globalTimeWindow? } }`,`- flow: { flow: { bindingKey, timeDimension, eventDimension, startingStep: { name, filter }, stepsBefore, stepsAfter } }`,`- retention: { retention: { timeDimension, bindingKey, dateRange: { start, end }, granularity, periods, retentionType } }`,``,`Filter rules: flat arrays of { member, operator, values }. Use { and: [...] } or { or: [...] } for logical grouping.`].join(`
34
38
  `)},{uri:`drizzle-cube://query-shapes`,name:`Query Shapes Reference`,description:`Detailed schema examples for regular, funnel, flow, and retention queries`,mimeType:`text/markdown`,text:[`# Query Shapes`,``,`## Regular query`,"```json",`{`,` "measures": ["Sales.count"],`,` "dimensions": ["Sales.channel"],`,` "filters": [`,` { "member": "Sales.status", "operator": "equals", "values": ["paid"] },`,` { "or": [`,` { "member": "Sales.region", "operator": "equals", "values": ["US"] },`,` { "member": "Sales.region", "operator": "equals", "values": ["EU"] }`,` ]}`,` ],`,` "timeDimensions": [{ "dimension": "Sales.createdAt", "dateRange": "last 30 days", "granularity": "day" }],`,` "order": { "Sales.createdAt": "asc" },`,` "limit": 500`,`}`,"```",``,`## Funnel`,"```json",`{`,` "funnel": {`,` "bindingKey": "Events.userId",`,` "timeDimension": "Events.timestamp",`,` "steps": [`,` {`,` "name": "Signup",`,` "filter": [`,` { "member": "Events.eventType", "operator": "equals", "values": ["signup"] },`,` { "member": "Events.timestamp", "operator": "inDateRange", "values": ["last 6 months"] }`,` ]`,` },`,` {`,` "name": "Purchase",`,` "filter": [{ "member": "Events.eventType", "operator": "equals", "values": ["purchase"] }],`,` "timeToConvert": "P7D"`,` }`,` ],`,` "includeTimeMetrics": true`,` }`,`}`,"```",``,`## Flow`,"```json",`{`,` "flow": {`,` "bindingKey": "Events.userId",`,` "timeDimension": "Events.timestamp",`,` "eventDimension": "Events.eventType",`,` "startingStep": {`,` "name": "Checkout",`,` "filter": { "member": "Events.eventType", "operator": "equals", "values": ["checkout"] }`,` },`,` "stepsBefore": 2,`,` "stepsAfter": 3`,` }`,`}`,"```",``,`## Retention`,"```json",`{`,` "retention": {`,` "timeDimension": "Events.timestamp",`,` "bindingKey": "Events.userId",`,` "dateRange": { "start": "2024-01-01", "end": "2024-03-31" },`,` "granularity": "week",`,` "periods": 8,`,` "retentionType": "classic",`,` "breakdownDimensions": ["Events.country"]`,` }`,`}`,"```",``,`### Filter operators`,`String: equals, notEquals, contains, notContains, startsWith, endsWith, like, ilike, regex`,`Numeric: gt, gte, lt, lte, between, notBetween`,`Set: in, notIn, set, notSet, isEmpty, isNotEmpty`,`Date: inDateRange, beforeDate, afterDate`,``,`### Time handling`,`- Aggregated totals: use filters with inDateRange (NOT timeDimensions)`,`- Time series grouping: use timeDimensions with granularity`,`- Both can be combined: inDateRange filter + timeDimensions with granularity`,`- Period comparison: use compareDateRange in timeDimensions`].join(`
35
39
  `)}];function O(){return D}function k(){return E}Object.defineProperty(exports,`_`,{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,`a`,{enumerable:!0,get:function(){return h}}),Object.defineProperty(exports,`c`,{enumerable:!0,get:function(){return k}}),Object.defineProperty(exports,`d`,{enumerable:!0,get:function(){return b}}),Object.defineProperty(exports,`f`,{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,`g`,{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,`h`,{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,`i`,{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,`l`,{enumerable:!0,get:function(){return O}}),Object.defineProperty(exports,`m`,{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,`n`,{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,`o`,{enumerable:!0,get:function(){return S}}),Object.defineProperty(exports,`p`,{enumerable:!0,get:function(){return g}}),Object.defineProperty(exports,`r`,{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,`s`,{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return i}}),Object.defineProperty(exports,`u`,{enumerable:!0,get:function(){return a}}),Object.defineProperty(exports,`v`,{enumerable:!0,get:function(){return l}});
@@ -223,19 +223,34 @@ function E(e) {
223
223
  },
224
224
  {
225
225
  name: "load",
226
- description: "Execute a semantic query and return aggregated results.\n\nSupports regular queries (measures/dimensions), funnel, flow, and retention analysis modes.\nSee the query language prompt for the full DSL reference.\n\nKey rules:\n- Fields are always \"CubeName.fieldName\" format\n- Cross-cube joins: include dimensions from related cubes (system auto-joins)\n- Aggregated totals: use filters with inDateRange (NOT timeDimensions)\n- Time series: use timeDimensions WITH granularity\n- Top N pattern: filters + order + limit\n\nCHART HINTS: Include a \"chart\" object to control the MCP App UI visualization.\nChart types: bar, line, area, pie, scatter, bubble, radar, treemap, kpiNumber, kpiDelta, table, heatmap, funnel, sankey, sunburst, retentionHeatmap\nGuidelines: single number -> kpiNumber, trend -> line/area, categories -> bar, part-of-whole -> pie, correlation -> scatter/bubble, distribution -> boxPlot",
226
+ description: "Execute a semantic query and return aggregated results.\n\nSupports regular queries (measures/dimensions), funnel, flow, and retention analysis modes.\nSee the query language prompt for the full DSL reference.\n\nKey rules:\n- Fields are always \"CubeName.fieldName\" format\n- Cross-cube joins: include dimensions from related cubes (system auto-joins)\n- Aggregated totals: use filters with inDateRange (NOT timeDimensions)\n- Time series: use timeDimensions WITH granularity\n- Top N pattern: filters + order + limit\n\nUse \"load\" for data retrieval. Use \"chart\" to visualise results with an interactive chart.",
227
+ inputSchema: {
228
+ type: "object",
229
+ required: ["query"],
230
+ properties: { query: {
231
+ type: "object",
232
+ description: "Semantic query object. Regular: { measures, dimensions, filters, timeDimensions, order, limit }. Funnel: { funnel: {...} }. Flow: { flow: {...} }. Retention: { retention: {...} }.",
233
+ properties: i
234
+ } }
235
+ }
236
+ }
237
+ ];
238
+ if (e?.appEnabled) {
239
+ t.push({
240
+ name: "chart",
241
+ description: "Execute a semantic query and render an interactive chart visualization.\n\nSame query format as \"load\", but renders results in the MCP App chart UI.\nInclude a \"chart\" object to control the visualization.\n\nChart types: bar, line, area, pie, scatter, bubble, radar, treemap, kpiNumber, kpiDelta, table, heatmap, funnel, sankey, sunburst, waterfall, activityGrid, boxPlot\nGuidelines: single number -> kpiNumber, trend -> line/area, categories -> bar, part-of-whole -> pie, correlation -> scatter/bubble, distribution -> boxPlot",
227
242
  inputSchema: {
228
243
  type: "object",
229
244
  required: ["query"],
230
245
  properties: {
231
246
  query: {
232
247
  type: "object",
233
- description: "Semantic query object. Regular: { measures, dimensions, filters, timeDimensions, order, limit }. Funnel: { funnel: {...} }. Flow: { flow: {...} }. Retention: { retention: {...} }.",
248
+ description: "Semantic query object. Same format as the load tool.",
234
249
  properties: i
235
250
  },
236
251
  chart: {
237
252
  type: "object",
238
- description: "Optional chart configuration for the MCP App UI. Uses the same chartConfig/displayConfig as the agent portlet system. If omitted, chart type is auto-detected.",
253
+ description: "Chart configuration for the visualization. If omitted, chart type is auto-detected from query shape.",
239
254
  properties: {
240
255
  type: {
241
256
  type: "string",
@@ -336,10 +351,8 @@ function E(e) {
336
351
  }
337
352
  }
338
353
  }
339
- }
340
- ];
341
- if (e?.appEnabled) {
342
- let e = t.find((e) => e.name === "load");
354
+ });
355
+ let e = t.find((e) => e.name === "chart");
343
356
  e && (e._meta = { ui: { resourceUri: s } });
344
357
  }
345
358
  return t;
@@ -361,6 +374,11 @@ async function D(e, i) {
361
374
  if (!e.query) throw S(-32602, "query is required");
362
375
  return O(await r(a, await o(s, c), e));
363
376
  }
377
+ case "chart": {
378
+ let e = u || {};
379
+ if (!e.query) throw S(-32602, "query is required");
380
+ return O(await r(a, await o(s, c), e));
381
+ }
364
382
  default: throw S(-32601, `Unknown tool: ${l.name}`);
365
383
  }
366
384
  } catch (e) {
@@ -405,13 +423,13 @@ var A = a(), j = [{
405
423
  "Tools:",
406
424
  "- discover: { topic?, intent?, limit?, minScore? } -> cubes list",
407
425
  "- validate: { query } -> corrected query + issues",
408
- "- load: { query } -> data + annotation",
426
+ "- load: { query } -> data + annotation (text only)",
427
+ "- chart: { query, chart? } -> data + interactive chart visualization",
409
428
  "",
410
429
  "Recommended flow:",
411
- "1) tools/list",
412
- "2) tools/call name=discover intent=\"<goal>\"",
413
- "3) tools/call name=validate query=<draft> (optional)",
414
- "4) tools/call name=load query=<validated>",
430
+ "1) tools/call name=discover intent=\"<goal>\"",
431
+ "2) tools/call name=validate query=<draft> (optional)",
432
+ "3) tools/call name=load query=<validated> (data only) OR name=chart query=<validated> chart={type, ...} (with visualization)",
415
433
  "",
416
434
  "Query shapes supported:",
417
435
  "- regular: { measures, dimensions, filters, timeDimensions, order, limit, offset, ungrouped }",
@@ -103,399 +103,11 @@ export declare function isNotification(request: JsonRpcRequest): boolean;
103
103
  export declare function primeEventId(): string;
104
104
  export declare function buildToolList(options?: {
105
105
  appEnabled?: boolean;
106
- }): ({
106
+ }): {
107
107
  name: string;
108
108
  description: string;
109
- inputSchema: {
110
- type: string;
111
- properties: {
112
- topic: {
113
- type: string;
114
- description: string;
115
- };
116
- intent: {
117
- type: string;
118
- description: string;
119
- };
120
- limit: {
121
- type: string;
122
- description: string;
123
- };
124
- minScore: {
125
- type: string;
126
- description: string;
127
- };
128
- query?: undefined;
129
- chart?: undefined;
130
- };
131
- required?: undefined;
132
- };
133
- } | {
134
- name: string;
135
- description: string;
136
- inputSchema: {
137
- type: string;
138
- required: string[];
139
- properties: {
140
- query: {
141
- type: string;
142
- description: string;
143
- properties?: undefined;
144
- };
145
- topic?: undefined;
146
- intent?: undefined;
147
- limit?: undefined;
148
- minScore?: undefined;
149
- chart?: undefined;
150
- };
151
- };
152
- } | {
153
- name: string;
154
- description: string;
155
- inputSchema: {
156
- type: string;
157
- required: string[];
158
- properties: {
159
- query: {
160
- type: string;
161
- description: string;
162
- properties: {
163
- readonly measures: {
164
- readonly type: "array";
165
- readonly items: {
166
- readonly type: "string";
167
- readonly pattern: "^[A-Z][a-zA-Z0-9]*\\.[a-zA-Z][a-zA-Z0-9]*$";
168
- };
169
- readonly description: "Aggregation measures — EXACTLY \"CubeName.measureName\" (two parts, one dot). Copy field names verbatim from discover results. WRONG: \"Sales.Sales.count\" (double-prefixed). RIGHT: \"Sales.count\".";
170
- };
171
- readonly dimensions: {
172
- readonly type: "array";
173
- readonly items: {
174
- readonly type: "string";
175
- readonly pattern: "^[A-Z][a-zA-Z0-9]*\\.[a-zA-Z][a-zA-Z0-9]*$";
176
- };
177
- readonly description: "Grouping dimensions — EXACTLY \"CubeName.dimensionName\" (two parts, one dot). Copy from discover results. Can include dimensions from RELATED cubes via joins. WRONG: \"Teams.Teams.name\". RIGHT: \"Teams.name\".";
178
- };
179
- readonly filters: {
180
- readonly type: "array";
181
- readonly items: {
182
- readonly type: "object";
183
- readonly properties: {
184
- readonly member: {
185
- readonly type: "string";
186
- readonly description: "\"CubeName.fieldName\"";
187
- };
188
- readonly operator: {
189
- readonly type: "string";
190
- readonly enum: readonly ["equals", "notEquals", "contains", "notContains", "startsWith", "notStartsWith", "endsWith", "notEndsWith", "gt", "gte", "lt", "lte", "between", "notBetween", "in", "notIn", "like", "notLike", "ilike", "regex", "notRegex", "set", "notSet", "isEmpty", "isNotEmpty", "inDateRange", "beforeDate", "afterDate", "arrayContains", "arrayOverlaps", "arrayContained"];
191
- };
192
- readonly values: {
193
- readonly type: "array";
194
- readonly items: {};
195
- readonly description: "Filter values. Omit for set/notSet/isEmpty/isNotEmpty.";
196
- };
197
- };
198
- readonly required: readonly ["member", "operator"];
199
- };
200
- readonly description: "Filter conditions. Flat array — for AND/OR logic use { \"and\": [...] } or { \"or\": [...] } wrappers.";
201
- };
202
- readonly timeDimensions: {
203
- readonly type: "array";
204
- readonly items: {
205
- readonly type: "object";
206
- readonly properties: {
207
- readonly dimension: {
208
- readonly type: "string";
209
- readonly description: "\"CubeName.timeDimension\"";
210
- };
211
- readonly granularity: {
212
- readonly type: "string";
213
- readonly enum: readonly ["second", "minute", "hour", "day", "week", "month", "quarter", "year"];
214
- readonly description: "Time bucket size. REQUIRED for time series; omit only for date range filtering.";
215
- };
216
- readonly dateRange: {
217
- readonly description: "Relative string (\"last 7 days\", \"this month\", \"last quarter\") or absolute tuple [\"YYYY-MM-DD\", \"YYYY-MM-DD\"]";
218
- };
219
- readonly fillMissingDates: {
220
- readonly type: "boolean";
221
- readonly description: "Fill gaps in time series with fillMissingDatesValue (default: true). Requires granularity + dateRange.";
222
- };
223
- readonly compareDateRange: {
224
- readonly type: "array";
225
- readonly items: {};
226
- readonly description: "Period-over-period comparison. Array of date ranges: [\"last 30 days\", [\"2024-01-01\", \"2024-01-30\"]]";
227
- };
228
- };
229
- readonly required: readonly ["dimension"];
230
- };
231
- readonly description: "Time dimensions with optional granularity for time series. Use filters with inDateRange for aggregated totals instead.";
232
- };
233
- readonly order: {
234
- readonly type: "object";
235
- readonly description: "Sort order. Keys MUST be a measure or dimension already in this query, in \"CubeName.fieldName\" format. Values: \"asc\" or \"desc\". Example: {\"Sales.revenue\": \"desc\"}";
236
- };
237
- readonly limit: {
238
- readonly type: "number";
239
- readonly description: "Maximum rows to return";
240
- };
241
- readonly offset: {
242
- readonly type: "number";
243
- readonly description: "Number of rows to skip (for pagination)";
244
- };
245
- readonly ungrouped: {
246
- readonly type: "boolean";
247
- readonly description: "When true, returns raw row-level data without GROUP BY. Requires at least one dimension. Incompatible with count/countDistinct measures and analysis modes.";
248
- };
249
- readonly funnel: {
250
- readonly type: "object";
251
- readonly properties: {
252
- readonly bindingKey: {
253
- readonly type: "string";
254
- readonly description: "Entity identifier dimension (e.g., \"Events.userId\")";
255
- };
256
- readonly timeDimension: {
257
- readonly type: "string";
258
- readonly description: "Time ordering dimension (e.g., \"Events.timestamp\")";
259
- };
260
- readonly steps: {
261
- readonly type: "array";
262
- readonly items: {
263
- readonly type: "object";
264
- readonly properties: {
265
- readonly name: {
266
- readonly type: "string";
267
- readonly description: "Human-readable step name";
268
- };
269
- readonly filter: {
270
- readonly description: "Filter or array of filters for this step";
271
- };
272
- readonly timeToConvert: {
273
- readonly type: "string";
274
- readonly description: "ISO 8601 duration — max time from previous step (e.g., \"P7D\" for 7 days, \"PT1H\" for 1 hour)";
275
- };
276
- };
277
- readonly required: readonly ["name"];
278
- };
279
- readonly description: "Ordered funnel steps (minimum 2). Put inDateRange time filter ONLY on step 0.";
280
- };
281
- readonly includeTimeMetrics: {
282
- readonly type: "boolean";
283
- readonly description: "Include avg/median/p90 time-to-convert per step";
284
- };
285
- readonly globalTimeWindow: {
286
- readonly type: "string";
287
- readonly description: "ISO 8601 duration — all steps must complete within this window from step 0";
288
- };
289
- };
290
- readonly required: readonly ["bindingKey", "timeDimension", "steps"];
291
- readonly description: "Funnel analysis. When provided, measures/dimensions are ignored.";
292
- };
293
- readonly flow: {
294
- readonly type: "object";
295
- readonly properties: {
296
- readonly bindingKey: {
297
- readonly type: "string";
298
- readonly description: "Entity identifier dimension (e.g., \"Events.userId\")";
299
- };
300
- readonly timeDimension: {
301
- readonly type: "string";
302
- readonly description: "Time ordering dimension (e.g., \"Events.timestamp\")";
303
- };
304
- readonly eventDimension: {
305
- readonly type: "string";
306
- readonly description: "Dimension whose values become node labels (e.g., \"Events.eventType\")";
307
- };
308
- readonly startingStep: {
309
- readonly type: "object";
310
- readonly properties: {
311
- readonly name: {
312
- readonly type: "string";
313
- readonly description: "Display name for the starting step";
314
- };
315
- readonly filter: {
316
- readonly description: "Filter(s) identifying the starting event";
317
- };
318
- };
319
- readonly required: readonly ["name"];
320
- readonly description: "The anchor point — an object with { name, filter }, NOT a plain string.";
321
- };
322
- readonly stepsBefore: {
323
- readonly type: "number";
324
- readonly description: "Steps to explore before starting step (0-5)";
325
- };
326
- readonly stepsAfter: {
327
- readonly type: "number";
328
- readonly description: "Steps to explore after starting step (0-5)";
329
- };
330
- readonly entityLimit: {
331
- readonly type: "number";
332
- readonly description: "Max entities to process (performance tuning)";
333
- };
334
- readonly outputMode: {
335
- readonly type: "string";
336
- readonly enum: readonly ["sankey", "sunburst"];
337
- readonly description: "Visualization mode (default: sankey)";
338
- };
339
- };
340
- readonly required: readonly ["bindingKey", "timeDimension", "eventDimension", "startingStep"];
341
- readonly description: "Flow (path) analysis. When provided, measures/dimensions are ignored.";
342
- };
343
- readonly retention: {
344
- readonly type: "object";
345
- readonly properties: {
346
- readonly timeDimension: {
347
- readonly type: "string";
348
- readonly description: "Timestamp dimension (e.g., \"Events.timestamp\")";
349
- };
350
- readonly bindingKey: {
351
- readonly type: "string";
352
- readonly description: "Entity identifier (e.g., \"Events.userId\")";
353
- };
354
- readonly dateRange: {
355
- readonly type: "object";
356
- readonly properties: {
357
- readonly start: {
358
- readonly type: "string";
359
- readonly description: "YYYY-MM-DD";
360
- };
361
- readonly end: {
362
- readonly type: "string";
363
- readonly description: "YYYY-MM-DD";
364
- };
365
- };
366
- readonly required: readonly ["start", "end"];
367
- readonly description: "Cohort date range — MUST be an object { start, end }, NOT an array or string.";
368
- };
369
- readonly granularity: {
370
- readonly type: "string";
371
- readonly enum: readonly ["day", "week", "month"];
372
- readonly description: "Period size for retention buckets";
373
- };
374
- readonly periods: {
375
- readonly type: "number";
376
- readonly description: "Number of retention periods to calculate";
377
- };
378
- readonly retentionType: {
379
- readonly type: "string";
380
- readonly enum: readonly ["classic", "rolling"];
381
- readonly description: "classic = returned in period N exactly; rolling = returned in period N or later";
382
- };
383
- readonly cohortFilters: {
384
- readonly description: "Optional filters on cohort entry events";
385
- };
386
- readonly activityFilters: {
387
- readonly description: "Optional filters on return activity events";
388
- };
389
- readonly breakdownDimensions: {
390
- readonly type: "array";
391
- readonly items: {
392
- readonly type: "string";
393
- };
394
- readonly description: "Segment retention by these dimensions (e.g., [\"Events.country\"])";
395
- };
396
- };
397
- readonly required: readonly ["timeDimension", "bindingKey", "dateRange", "granularity", "periods"];
398
- readonly description: "Retention (cohort) analysis. When provided, measures/dimensions are ignored.";
399
- };
400
- };
401
- };
402
- chart: {
403
- type: string;
404
- description: string;
405
- properties: {
406
- type: {
407
- type: string;
408
- enum: string[];
409
- description: string;
410
- };
411
- title: {
412
- type: string;
413
- description: string;
414
- };
415
- chartConfig: {
416
- type: string;
417
- description: string;
418
- properties: {
419
- xAxis: {
420
- type: string;
421
- items: {
422
- type: string;
423
- };
424
- description: string;
425
- };
426
- yAxis: {
427
- type: string;
428
- items: {
429
- type: string;
430
- };
431
- description: string;
432
- };
433
- series: {
434
- type: string;
435
- items: {
436
- type: string;
437
- };
438
- description: string;
439
- };
440
- yAxisAssignment: {
441
- type: string;
442
- description: string;
443
- };
444
- sizeField: {
445
- type: string;
446
- description: string;
447
- };
448
- colorField: {
449
- type: string;
450
- description: string;
451
- };
452
- };
453
- };
454
- displayConfig: {
455
- type: string;
456
- description: string;
457
- properties: {
458
- showLegend: {
459
- type: string;
460
- };
461
- showGrid: {
462
- type: string;
463
- };
464
- showTooltip: {
465
- type: string;
466
- };
467
- stacked: {
468
- type: string;
469
- };
470
- stackType: {
471
- type: string;
472
- enum: string[];
473
- };
474
- orientation: {
475
- type: string;
476
- enum: string[];
477
- };
478
- };
479
- };
480
- xAxis: {
481
- type: string;
482
- description: string;
483
- };
484
- yAxis: {
485
- type: string;
486
- items: {
487
- type: string;
488
- };
489
- description: string;
490
- };
491
- };
492
- };
493
- topic?: undefined;
494
- intent?: undefined;
495
- limit?: undefined;
496
- minScore?: undefined;
497
- };
498
- };
499
- })[];
109
+ inputSchema: Record<string, unknown>;
110
+ _meta?: unknown;
111
+ }[];
500
112
  export declare function getDefaultResources(): MCPResource[];
501
113
  export declare function getDefaultPrompts(): MCPPrompt[];
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-Kk_HTCeR.cjs`);let r=require(`next/server`);function i(e){let{cubes:n,drizzle:r,schema:i,engineType:a,cache:o,rlsSetup:s}=e;if(!n||n.length===0)throw Error(`At least one cube must be provided in the cubes array`);let c=new t.t({drizzle:r,schema:i,engineType:a,cache:o,rlsSetup:s});return n.forEach(e=>{c.registerCube(e)}),c}function a(e,t){let n=e.headers.get(`origin`),r={};return t.origin&&(typeof t.origin==`string`?r[`Access-Control-Allow-Origin`]=t.origin:Array.isArray(t.origin)?n&&t.origin.includes(n)&&(r[`Access-Control-Allow-Origin`]=n):typeof t.origin==`function`&&n&&t.origin(n)&&(r[`Access-Control-Allow-Origin`]=n)),t.methods&&(r[`Access-Control-Allow-Methods`]=t.methods.join(`, `)),t.allowedHeaders&&(r[`Access-Control-Allow-Headers`]=t.allowedHeaders.join(`, `)),t.credentials&&(r[`Access-Control-Allow-Credentials`]=`true`),r}function o(e){return async function(t){let n=a(t,e);return new Response(null,{status:200,headers:n})}}function s(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{let c;if(t.method===`POST`){let e=await t.json();c=e.query||e}else if(t.method===`GET`){let n=t.nextUrl.searchParams.get(`query`);if(!n)return r.NextResponse.json(e.i(`Query parameter is required`,400),{status:400});try{c=JSON.parse(n)}catch{return r.NextResponse.json(e.i(`Invalid JSON in query parameter`,400),{status:400})}}else return r.NextResponse.json(e.i(`Method not allowed`,405),{status:405});let l=await n(t,i),u=s.validateQuery(c);if(!u.isValid)return r.NextResponse.json(e.i(`Query validation failed: ${u.errors.join(`, `)}`,400),{status:400});let d=t.headers.get(`x-cache-control`)===`no-cache`,f=await s.executeMultiCubeQuery(c,l,{skipCache:d}),p=e.r(c,f,s);return r.NextResponse.json(p,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js load handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query execution failed`,500),{status:500})}}}function c(t){let{cors:n}=t,o=i(t);return async function(t,i){try{let i=e.a(o.getMetadata());return r.NextResponse.json(i,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js meta handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Failed to fetch metadata`,500),{status:500})}}}function l(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{let c;if(t.method===`POST`){let e=await t.json();c=e.query||e}else if(t.method===`GET`){let n=t.nextUrl.searchParams.get(`query`);if(!n)return r.NextResponse.json(e.i(`Query parameter is required`,400),{status:400});try{c=JSON.parse(n)}catch{return r.NextResponse.json(e.i(`Invalid JSON in query parameter`,400),{status:400})}}else return r.NextResponse.json(e.i(`Method not allowed`,405),{status:405});let l=await n(t,i),u=s.validateQuery(c);if(!u.isValid)return r.NextResponse.json(e.i(`Query validation failed: ${u.errors.join(`, `)}`,400),{status:400});let d=c.measures?.[0]||c.dimensions?.[0];if(!d)return r.NextResponse.json(e.i(`No measures or dimensions specified`,400),{status:400});let f=d.split(`.`)[0],p=await s.generateSQL(f,c,l),m=e.o(c,p);return r.NextResponse.json(m,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js SQL handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`SQL generation failed`,500),{status:500})}}}function u(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{let c;if(t.method===`POST`){let e=await t.json();c=e.query||e}else if(t.method===`GET`){let e=t.nextUrl.searchParams.get(`query`);if(!e)return r.NextResponse.json({error:`Query parameter is required`,valid:!1},{status:400});try{c=JSON.parse(e)}catch{return r.NextResponse.json({error:`Invalid JSON in query parameter`,valid:!1},{status:400})}}else return r.NextResponse.json({error:`Method not allowed`,valid:!1},{status:405});let l=await n(t,i),u=await e.f(c,l,s);return r.NextResponse.json(u,{headers:o?a(t,o):{}})}catch(e){return process.env.NODE_ENV!==`test`&&console.error(`Next.js dry-run handler error:`,e),r.NextResponse.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},{status:400})}}}function d(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let{queries:c}=await t.json();if(!c||!Array.isArray(c))return r.NextResponse.json(e.i(`Request body must contain a "queries" array`,400),{status:400});if(c.length===0)return r.NextResponse.json(e.i(`Queries array cannot be empty`,400),{status:400});let l=await e.u(c,await n(t,i),s,{skipCache:t.headers.get(`x-cache-control`)===`no-cache`});return r.NextResponse.json(l,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js batch handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Batch execution failed`,500),{status:500})}}}function f(e){let{extractSecurityContext:t,cors:n}=e,o=i(e);return async function(e,i){try{if(e.method!==`POST`)return r.NextResponse.json({error:`Method not allowed`},{status:405});let s=await e.json(),c=s.query||s,l=s.options||{},u=await t(e,i),d=o.validateQuery(c);if(!d.isValid)return r.NextResponse.json({error:`Query validation failed: ${d.errors.join(`, `)}`},{status:400});let f=await o.explainQuery(c,u,l);return r.NextResponse.json(f,{headers:n?a(e,n):{}})}catch(e){return process.env.NODE_ENV!==`test`&&console.error(`Next.js explain handler error:`,e),r.NextResponse.json({error:e instanceof Error?e.message:`Explain query failed`},{status:500})}}}function p(t){let{cors:n}=t,o=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=await e.d(o,await t.json());return r.NextResponse.json(i,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js discover handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Discovery failed`,500),{status:500})}}}function m(t){let{cors:n}=t,o=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=await t.json();if(!i.naturalLanguage)return r.NextResponse.json(e.i(`naturalLanguage field is required`,400),{status:400});let s=await e.m(o,i);return r.NextResponse.json(s,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js suggest handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query suggestion failed`,500),{status:500})}}}function h(t){let{cors:n}=t,o=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=await t.json();if(!i.query)return r.NextResponse.json(e.i(`query field is required`,400),{status:400});let s=await e.h(o,i);return r.NextResponse.json(s,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js validate handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query validation failed`,500),{status:500})}}}function g(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let c=await t.json();if(!c.query)return r.NextResponse.json(e.i(`query field is required`,400),{status:400});let l=await e.p(s,await n(t,i),c);return r.NextResponse.json(l,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js MCP load handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query execution failed`,500),{status:500})}}}function _(t){let{extractSecurityContext:o,cors:s,mcp:c={enabled:!0}}=t,l=i(t);return async function(t){if(t.method===`DELETE`)return r.NextResponse.json({error:`Session termination not supported`},{status:405});if(t.method===`GET`){let e=new TextEncoder,i=n.m(),o=new ReadableStream({start(t){t.enqueue(e.encode(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},i,15e3)))}}),c=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});if(s){let e=a(t,s);Object.entries(e).forEach(([e,t])=>c.set(e,t))}return new r.NextResponse(o,{status:200,headers:c})}if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=n._(t.headers.get(`origin`),c.allowedOrigins?{allowedOrigins:c.allowedOrigins}:{});if(!i.valid)return r.NextResponse.json(n.i(null,-32600,i.reason),{status:403});let u=t.headers.get(`accept`);if(!n.g(u))return r.NextResponse.json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`),{status:400});let d=n.f(Object.fromEntries(t.headers.entries()));if(!d.ok)return r.NextResponse.json({error:`Unsupported MCP protocol version`,supported:d.supported},{status:426});let f;try{f=await t.json()}catch{f=null}let p=n.p(f);if(!p)return r.NextResponse.json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`),{status:400});let m=n.v(u),h=p.method===`initialize`,g=(e,n=200,i={})=>r.NextResponse.json(e,{status:n,headers:{...s?a(t,s):{},...i}});try{let e=await n.s(p.method,p.params,{semanticLayer:l,extractSecurityContext:e=>o(e),rawRequest:t,rawResponse:null,appEnabled:!!c.app});if(n.d(p))return new r.NextResponse(null,{status:202});let i=h&&e&&typeof e==`object`&&`sessionId`in e?e.sessionId:void 0,u={};i&&(u[n.r]=i);let d=n.a(p.id??null,e);if(m){let e=new TextEncoder,i=n.m(),o=new ReadableStream({start(t){t.enqueue(e.encode(`id: ${i}\n\n`)),t.enqueue(e.encode(n.h(d,i))),t.close()}}),c=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...u});if(s){let e=a(t,s);Object.entries(e).forEach(([e,t])=>c.set(e,t))}return new r.NextResponse(o,{status:200,headers:c})}return g(d,200,u)}catch(e){if(n.d(p))return process.env.NODE_ENV!==`test`&&console.error(`Next.js MCP notification processing error:`,e),new r.NextResponse(null,{status:202});process.env.NODE_ENV!==`test`&&console.error(`Next.js MCP RPC handler error:`,e);let i=e?.code??-32603,o=e?.data,c=e.message||`MCP request failed`,l=n.i(p.id??null,i,c,o);if(m){let e=new TextEncoder,i=n.m(),o=new ReadableStream({start(t){t.enqueue(e.encode(`id: ${i}\n\n`)),t.enqueue(e.encode(n.h(l,i))),t.close()}}),c=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});if(s){let e=a(t,s);Object.entries(e).forEach(([e,t])=>c.set(e,t))}return new r.NextResponse(o,{status:200,headers:c})}return g(l,200)}}}function v(e){let{extractSecurityContext:t,cors:n,agent:o}=e;if(!o)throw Error(`agent config is required for createAgentChatHandler`);let s=i(e);return async function(e,i){try{if(e.method!==`POST`)return r.NextResponse.json({error:`Method not allowed - use POST`},{status:405});let{handleAgentChat:c}=await Promise.resolve().then(()=>require(`../handler-DumFgnNM.cjs`)),{message:l,sessionId:u,history:d}=await e.json();if(!l||typeof l!=`string`)return r.NextResponse.json({error:`message is required and must be a string`},{status:400});let f=(o.apiKey||``).trim();if(o.allowClientApiKey){let t=e.headers.get(`x-agent-api-key`);t&&(f=t.trim())}if(!f)return r.NextResponse.json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`},{status:401});let p=o.allowClientApiKey&&e.headers.get(`x-agent-provider`)||void 0,m=o.allowClientApiKey&&e.headers.get(`x-agent-model`)||void 0,h=o.allowClientApiKey&&e.headers.get(`x-agent-provider-endpoint`)||void 0,g=await t(e,i),_=o.buildSystemContext?.(g),v=new TextEncoder,y=new ReadableStream({async start(e){try{let t=c({message:l,sessionId:u,history:d,semanticLayer:s,securityContext:g,agentConfig:o,apiKey:f,systemContext:_,providerOverride:p,modelOverride:m,baseURLOverride:h});for await(let n of t){let t=`data: ${JSON.stringify(n)}\n\n`;e.enqueue(v.encode(t))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(v.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}}),b=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});if(n){let t=a(e,n);Object.entries(t).forEach(([e,t])=>b.set(e,t))}return new Response(y,{status:200,headers:b})}catch(e){return process.env.NODE_ENV!==`test`&&console.error(`Next.js agent chat handler error:`,e),r.NextResponse.json({error:e instanceof Error?e.message:`Agent chat failed`},{status:500})}}}function y(e){let{mcp:t={enabled:!0}}=e,n={load:s(e),meta:c(e),sql:l(e),dryRun:u(e),batch:d(e),explain:f(e)};return t.enabled!==!1&&(n.mcpRpc=_(e)),e.agent&&(n.agentChat=v(e)),n}exports.createAgentChatHandler=v,exports.createBatchHandler=d,exports.createCubeHandlers=y,exports.createDiscoverHandler=p,exports.createDryRunHandler=u,exports.createExplainHandler=f,exports.createLoadHandler=s,exports.createMcpLoadHandler=g,exports.createMcpRpcHandler=_,exports.createMetaHandler=c,exports.createOptionsHandler=o,exports.createSqlHandler=l,exports.createSuggestHandler=m,exports.createValidateHandler=h;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require(`../utils-CyBt-as9.cjs`),t=require(`../compiler-CPE-YZfe.cjs`),n=require(`../mcp-transport-B43Mcqo4.cjs`);let r=require(`next/server`);function i(e){let{cubes:n,drizzle:r,schema:i,engineType:a,cache:o,rlsSetup:s}=e;if(!n||n.length===0)throw Error(`At least one cube must be provided in the cubes array`);let c=new t.t({drizzle:r,schema:i,engineType:a,cache:o,rlsSetup:s});return n.forEach(e=>{c.registerCube(e)}),c}function a(e,t){let n=e.headers.get(`origin`),r={};return t.origin&&(typeof t.origin==`string`?r[`Access-Control-Allow-Origin`]=t.origin:Array.isArray(t.origin)?n&&t.origin.includes(n)&&(r[`Access-Control-Allow-Origin`]=n):typeof t.origin==`function`&&n&&t.origin(n)&&(r[`Access-Control-Allow-Origin`]=n)),t.methods&&(r[`Access-Control-Allow-Methods`]=t.methods.join(`, `)),t.allowedHeaders&&(r[`Access-Control-Allow-Headers`]=t.allowedHeaders.join(`, `)),t.credentials&&(r[`Access-Control-Allow-Credentials`]=`true`),r}function o(e){return async function(t){let n=a(t,e);return new Response(null,{status:200,headers:n})}}function s(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{let c;if(t.method===`POST`){let e=await t.json();c=e.query||e}else if(t.method===`GET`){let n=t.nextUrl.searchParams.get(`query`);if(!n)return r.NextResponse.json(e.i(`Query parameter is required`,400),{status:400});try{c=JSON.parse(n)}catch{return r.NextResponse.json(e.i(`Invalid JSON in query parameter`,400),{status:400})}}else return r.NextResponse.json(e.i(`Method not allowed`,405),{status:405});let l=await n(t,i),u=s.validateQuery(c);if(!u.isValid)return r.NextResponse.json(e.i(`Query validation failed: ${u.errors.join(`, `)}`,400),{status:400});let d=t.headers.get(`x-cache-control`)===`no-cache`,f=await s.executeMultiCubeQuery(c,l,{skipCache:d}),p=e.r(c,f,s);return r.NextResponse.json(p,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js load handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query execution failed`,500),{status:500})}}}function c(t){let{cors:n}=t,o=i(t);return async function(t,i){try{let i=e.a(o.getMetadata());return r.NextResponse.json(i,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js meta handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Failed to fetch metadata`,500),{status:500})}}}function l(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{let c;if(t.method===`POST`){let e=await t.json();c=e.query||e}else if(t.method===`GET`){let n=t.nextUrl.searchParams.get(`query`);if(!n)return r.NextResponse.json(e.i(`Query parameter is required`,400),{status:400});try{c=JSON.parse(n)}catch{return r.NextResponse.json(e.i(`Invalid JSON in query parameter`,400),{status:400})}}else return r.NextResponse.json(e.i(`Method not allowed`,405),{status:405});let l=await n(t,i),u=s.validateQuery(c);if(!u.isValid)return r.NextResponse.json(e.i(`Query validation failed: ${u.errors.join(`, `)}`,400),{status:400});let d=c.measures?.[0]||c.dimensions?.[0];if(!d)return r.NextResponse.json(e.i(`No measures or dimensions specified`,400),{status:400});let f=d.split(`.`)[0],p=await s.generateSQL(f,c,l),m=e.o(c,p);return r.NextResponse.json(m,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js SQL handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`SQL generation failed`,500),{status:500})}}}function u(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{let c;if(t.method===`POST`){let e=await t.json();c=e.query||e}else if(t.method===`GET`){let e=t.nextUrl.searchParams.get(`query`);if(!e)return r.NextResponse.json({error:`Query parameter is required`,valid:!1},{status:400});try{c=JSON.parse(e)}catch{return r.NextResponse.json({error:`Invalid JSON in query parameter`,valid:!1},{status:400})}}else return r.NextResponse.json({error:`Method not allowed`,valid:!1},{status:405});let l=await n(t,i),u=await e.f(c,l,s);return r.NextResponse.json(u,{headers:o?a(t,o):{}})}catch(e){return process.env.NODE_ENV!==`test`&&console.error(`Next.js dry-run handler error:`,e),r.NextResponse.json({error:e instanceof Error?e.message:`Dry-run validation failed`,valid:!1},{status:400})}}}function d(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let{queries:c}=await t.json();if(!c||!Array.isArray(c))return r.NextResponse.json(e.i(`Request body must contain a "queries" array`,400),{status:400});if(c.length===0)return r.NextResponse.json(e.i(`Queries array cannot be empty`,400),{status:400});let l=await e.u(c,await n(t,i),s,{skipCache:t.headers.get(`x-cache-control`)===`no-cache`});return r.NextResponse.json(l,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js batch handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Batch execution failed`,500),{status:500})}}}function f(e){let{extractSecurityContext:t,cors:n}=e,o=i(e);return async function(e,i){try{if(e.method!==`POST`)return r.NextResponse.json({error:`Method not allowed`},{status:405});let s=await e.json(),c=s.query||s,l=s.options||{},u=await t(e,i),d=o.validateQuery(c);if(!d.isValid)return r.NextResponse.json({error:`Query validation failed: ${d.errors.join(`, `)}`},{status:400});let f=await o.explainQuery(c,u,l);return r.NextResponse.json(f,{headers:n?a(e,n):{}})}catch(e){return process.env.NODE_ENV!==`test`&&console.error(`Next.js explain handler error:`,e),r.NextResponse.json({error:e instanceof Error?e.message:`Explain query failed`},{status:500})}}}function p(t){let{cors:n}=t,o=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=await e.d(o,await t.json());return r.NextResponse.json(i,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js discover handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Discovery failed`,500),{status:500})}}}function m(t){let{cors:n}=t,o=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=await t.json();if(!i.naturalLanguage)return r.NextResponse.json(e.i(`naturalLanguage field is required`,400),{status:400});let s=await e.m(o,i);return r.NextResponse.json(s,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js suggest handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query suggestion failed`,500),{status:500})}}}function h(t){let{cors:n}=t,o=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=await t.json();if(!i.query)return r.NextResponse.json(e.i(`query field is required`,400),{status:400});let s=await e.h(o,i);return r.NextResponse.json(s,{headers:n?a(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js validate handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query validation failed`,500),{status:500})}}}function g(t){let{extractSecurityContext:n,cors:o}=t,s=i(t);return async function(t,i){try{if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let c=await t.json();if(!c.query)return r.NextResponse.json(e.i(`query field is required`,400),{status:400});let l=await e.p(s,await n(t,i),c);return r.NextResponse.json(l,{headers:o?a(t,o):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js MCP load handler error:`,t),r.NextResponse.json(e.i(t instanceof Error?t.message:`Query execution failed`,500),{status:500})}}}function _(t){let{extractSecurityContext:o,cors:s,mcp:c={enabled:!0}}=t,l=i(t);return async function(t){if(t.method===`DELETE`)return r.NextResponse.json({error:`Session termination not supported`},{status:405});if(t.method===`GET`){let e=new TextEncoder,i=n.m(),o=new ReadableStream({start(t){t.enqueue(e.encode(n.h({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},i,15e3)))}}),c=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});if(s){let e=a(t,s);Object.entries(e).forEach(([e,t])=>c.set(e,t))}return new r.NextResponse(o,{status:200,headers:c})}if(t.method!==`POST`)return r.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let i=n._(t.headers.get(`origin`),c.allowedOrigins?{allowedOrigins:c.allowedOrigins}:{});if(!i.valid)return r.NextResponse.json(n.i(null,-32600,i.reason),{status:403});let u=t.headers.get(`accept`);if(!n.g(u))return r.NextResponse.json(n.i(null,-32600,`Accept header must include both application/json and text/event-stream`),{status:400});let d=n.f(Object.fromEntries(t.headers.entries()));if(!d.ok)return r.NextResponse.json({error:`Unsupported MCP protocol version`,supported:d.supported},{status:426});let f;try{f=await t.json()}catch{f=null}let p=n.p(f);if(!p)return r.NextResponse.json(n.i(null,-32600,`Invalid JSON-RPC 2.0 request`),{status:400});let m=n.v(u),h=p.method===`initialize`,g=(e,n=200,i={})=>r.NextResponse.json(e,{status:n,headers:{...s?a(t,s):{},...i}});try{let e=await n.s(p.method,p.params,{semanticLayer:l,extractSecurityContext:e=>o(e),rawRequest:t,rawResponse:null,appEnabled:!!c.app});if(n.d(p))return new r.NextResponse(null,{status:202});let i=h&&e&&typeof e==`object`&&`sessionId`in e?e.sessionId:void 0,u={};i&&(u[n.r]=i);let d=n.a(p.id??null,e);if(m){let e=new TextEncoder,i=n.m(),o=new ReadableStream({start(t){t.enqueue(e.encode(`id: ${i}\n\n`)),t.enqueue(e.encode(n.h(d,i))),t.close()}}),c=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...u});if(s){let e=a(t,s);Object.entries(e).forEach(([e,t])=>c.set(e,t))}return new r.NextResponse(o,{status:200,headers:c})}return g(d,200,u)}catch(e){if(n.d(p))return process.env.NODE_ENV!==`test`&&console.error(`Next.js MCP notification processing error:`,e),new r.NextResponse(null,{status:202});process.env.NODE_ENV!==`test`&&console.error(`Next.js MCP RPC handler error:`,e);let i=e?.code??-32603,o=e?.data,c=e.message||`MCP request failed`,l=n.i(p.id??null,i,c,o);if(m){let e=new TextEncoder,i=n.m(),o=new ReadableStream({start(t){t.enqueue(e.encode(`id: ${i}\n\n`)),t.enqueue(e.encode(n.h(l,i))),t.close()}}),c=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});if(s){let e=a(t,s);Object.entries(e).forEach(([e,t])=>c.set(e,t))}return new r.NextResponse(o,{status:200,headers:c})}return g(l,200)}}}function v(e){let{extractSecurityContext:t,cors:n,agent:o}=e;if(!o)throw Error(`agent config is required for createAgentChatHandler`);let s=i(e);return async function(e,i){try{if(e.method!==`POST`)return r.NextResponse.json({error:`Method not allowed - use POST`},{status:405});let{handleAgentChat:c}=await Promise.resolve().then(()=>require(`../handler-DumFgnNM.cjs`)),{message:l,sessionId:u,history:d}=await e.json();if(!l||typeof l!=`string`)return r.NextResponse.json({error:`message is required and must be a string`},{status:400});let f=(o.apiKey||``).trim();if(o.allowClientApiKey){let t=e.headers.get(`x-agent-api-key`);t&&(f=t.trim())}if(!f)return r.NextResponse.json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`},{status:401});let p=o.allowClientApiKey&&e.headers.get(`x-agent-provider`)||void 0,m=o.allowClientApiKey&&e.headers.get(`x-agent-model`)||void 0,h=o.allowClientApiKey&&e.headers.get(`x-agent-provider-endpoint`)||void 0,g=await t(e,i),_=o.buildSystemContext?.(g),v=new TextEncoder,y=new ReadableStream({async start(e){try{let t=c({message:l,sessionId:u,history:d,semanticLayer:s,securityContext:g,agentConfig:o,apiKey:f,systemContext:_,providerOverride:p,modelOverride:m,baseURLOverride:h});for await(let n of t){let t=`data: ${JSON.stringify(n)}\n\n`;e.enqueue(v.encode(t))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(v.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}}),b=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});if(n){let t=a(e,n);Object.entries(t).forEach(([e,t])=>b.set(e,t))}return new Response(y,{status:200,headers:b})}catch(e){return process.env.NODE_ENV!==`test`&&console.error(`Next.js agent chat handler error:`,e),r.NextResponse.json({error:e instanceof Error?e.message:`Agent chat failed`},{status:500})}}}function y(e){let{mcp:t={enabled:!0}}=e,n={load:s(e),meta:c(e),sql:l(e),dryRun:u(e),batch:d(e),explain:f(e)};return t.enabled!==!1&&(n.mcpRpc=_(e)),e.agent&&(n.agentChat=v(e)),n}exports.createAgentChatHandler=v,exports.createBatchHandler=d,exports.createCubeHandlers=y,exports.createDiscoverHandler=p,exports.createDryRunHandler=u,exports.createExplainHandler=f,exports.createLoadHandler=s,exports.createMcpLoadHandler=g,exports.createMcpRpcHandler=_,exports.createMetaHandler=c,exports.createOptionsHandler=o,exports.createSqlHandler=l,exports.createSuggestHandler=m,exports.createValidateHandler=h;
@@ -1,6 +1,6 @@
1
1
  import { a as e, d as t, f as n, h as r, i, m as a, o, p as s, r as c, u as l } from "../utils-IH1ePsBd.js";
2
2
  import { t as u } from "../compiler-BXfrvebp.js";
3
- import { _ as d, a as f, d as p, f as m, g as h, h as g, i as _, m as v, p as y, r as b, s as x, v as S } from "../mcp-transport-BhPqU0Ft.js";
3
+ import { _ as d, a as f, d as p, f as m, g as h, h as g, i as _, m as v, p as y, r as b, s as x, v as S } from "../mcp-transport-CgX_c5Sj.js";
4
4
  import { NextResponse as C } from "next/server";
5
5
  //#region src/adapters/nextjs/index.ts
6
6
  function w(e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "drizzle-cube",
3
- "version": "0.4.49",
3
+ "version": "0.4.50",
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",