drizzle-cube 0.4.22 → 0.4.24
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.js +2 -2
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +2 -2
- package/dist/adapters/{handler-9Rdn7zM2.js → handler-BV2_dul8.js} +2 -2
- package/dist/adapters/{handler-B-tEntiU.cjs → handler-LMRPeTNJ.cjs} +2 -2
- package/dist/adapters/hono/index.cjs +6 -6
- package/dist/adapters/hono/index.d.ts +13 -6
- package/dist/adapters/hono/index.js +65 -65
- package/dist/{server/index-CFEJ62GJ.js → adapters/index-C3PskWTr.js} +209 -193
- package/dist/{server/index-BIMhF5KZ.cjs → adapters/index-ht4NPca9.cjs} +11 -11
- package/dist/adapters/{mcp-transport-m1X1GtwG.js → mcp-transport-B6ZudTSk.js} +7 -0
- package/dist/adapters/{mcp-transport-8u9G5oNa.cjs → mcp-transport-DCiSGtp1.cjs} +1 -1
- package/dist/adapters/nextjs/index.cjs +2 -2
- package/dist/adapters/nextjs/index.js +2 -2
- package/dist/adapters/{openai-mLo2MCat.cjs → openai-BvA6eLs8.cjs} +1 -1
- package/dist/adapters/{openai-CUSRuKTk.js → openai-mcE24du8.js} +1 -1
- package/dist/client/chunks/{analysis-builder-DVrv9Q4n.js → analysis-builder-KeTsXp1G.js} +141 -141
- package/dist/client/chunks/{analysis-builder-DVrv9Q4n.js.map → analysis-builder-KeTsXp1G.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-shared-CrENEvEk.js → analysis-builder-shared-KSvGUzx6.js} +2 -2
- package/dist/client/chunks/{analysis-builder-shared-CrENEvEk.js.map → analysis-builder-shared-KSvGUzx6.js.map} +1 -1
- package/dist/client/chunks/{components-GzooQM5J.js → components-Dz6XHgnZ.js} +49 -49
- package/dist/client/chunks/{components-GzooQM5J.js.map → components-Dz6XHgnZ.js.map} +1 -1
- package/dist/client/components/AgenticNotebook/NotebookCanvas.d.ts +4 -1
- package/dist/client/components/AgenticNotebook/NotebookPortletBlock.d.ts +2 -0
- package/dist/client/components.js +3 -3
- package/dist/client/index.js +678 -672
- package/dist/client/index.js.map +1 -1
- package/dist/client-bundle-stats.html +1 -1
- package/dist/{adapters/index-CFEJ62GJ.js → server/index-C3PskWTr.js} +209 -193
- package/dist/{adapters/index-BIMhF5KZ.cjs → server/index-ht4NPca9.cjs} +11 -11
- package/dist/server/index.cjs +2 -2
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.js +8 -1
- package/dist/server/{openai-mLo2MCat.cjs → openai-BvA6eLs8.cjs} +1 -1
- package/dist/server/{openai-CUSRuKTk.js → openai-mcE24du8.js} +1 -1
- package/package.json +1 -1
|
@@ -10374,6 +10374,13 @@ ${t.join(`
|
|
|
10374
10374
|
hasCube(e) {
|
|
10375
10375
|
return this.cubes.has(e);
|
|
10376
10376
|
}
|
|
10377
|
+
/**
|
|
10378
|
+
* Unregister a cube by name.
|
|
10379
|
+
* Returns true if the cube existed and was removed, false if not found.
|
|
10380
|
+
*/
|
|
10381
|
+
unregisterCube(e) {
|
|
10382
|
+
return this.removeCube(e);
|
|
10383
|
+
}
|
|
10377
10384
|
/**
|
|
10378
10385
|
* Remove a cube
|
|
10379
10386
|
*/
|
|
@@ -197,7 +197,7 @@
|
|
|
197
197
|
`)}}]},ht={name:"drizzle-cube-date-filtering",description:"CRITICAL: How to correctly filter by date vs group by time period - the #1 source of query mistakes",messages:[{role:"user",content:{type:"text",text:["# Date Filtering vs Time Grouping - CRITICAL GUIDE","","This is the most common mistake when building queries. These are TWO DIFFERENT operations.","","## Quick Decision Tree","","```","User wants data over a time period?",'├── Wants AGGREGATED TOTALS (e.g., "total sales last month")',"│ └── Use: filters with inDateRange operator","│",'└── Wants TIME SERIES breakdown (e.g., "daily sales last month")'," └── Use: timeDimensions with granularity","```","","## For Aggregated Totals (MOST COMMON)","",'When user says: "last 3 months", "over the past year", "in Q1", "since January"',"","```json","{",' "measures": ["Sales.totalRevenue"],',' "dimensions": ["Products.category"],',' "filters": [',' { "member": "Sales.date", "operator": "inDateRange", "values": ["last 3 months"] }'," ]","}","```","","Result: One row per category with TOTAL revenue over the 3-month period.","","## For Time Series (Trend Analysis)","",'When user says: "by month", "per week", "daily trend", "over time"',"","```json","{",' "measures": ["Sales.totalRevenue"],',' "timeDimensions": [',' { "dimension": "Sales.date", "dateRange": "last 3 months", "granularity": "month" }'," ]","}","```","","Result: Multiple rows, one per month.","","## WRONG: timeDimensions Without Granularity","","```json","// This returns ~90 rows (daily) instead of aggregates!","{",' "timeDimensions": [{ "dimension": "Sales.date", "dateRange": "last 3 months" }]',"}","```","","## Both: Filter AND Group","",'When user wants: "monthly breakdown for last quarter"',"","```json","{",' "measures": ["Sales.totalRevenue"],',' "filters": [',' { "member": "Sales.date", "operator": "inDateRange", "values": ["last quarter"] }'," ],",' "timeDimensions": [',' { "dimension": "Sales.date", "granularity": "month" }'," ]","}","```","","## Summary Table","","| User Request | Use | Example |","|-------------|-----|---------|",'| "total for last 3 months" | filters + inDateRange | { filters: [{ operator: "inDateRange", values: ["last 3 months"] }] } |','| "top 5 last quarter" | filters + inDateRange | Same as above + order + limit |','| "monthly trend" | timeDimensions + granularity | { timeDimensions: [{ granularity: "month" }] } |','| "daily breakdown last week" | timeDimensions | { timeDimensions: [{ dateRange: "last week", granularity: "day" }] } |'].join(`
|
|
198
198
|
`)}}]},Bn=[mt,ft,pt,ht];function kn(){return Bn}class Ie{cubes=new Map;dbExecutor;metadataCache;cacheConfig;constructor(e){e?.databaseExecutor?this.dbExecutor=e.databaseExecutor:e?.drizzle&&(this.dbExecutor=Ge(e.drizzle,e.schema,e.engineType)),this.cacheConfig=e?.cache}setDatabaseExecutor(e){this.dbExecutor=e}getEngineType(){return this.dbExecutor?.getEngineType()}setDrizzle(e,t,n){this.dbExecutor=Ge(e,t,n)}hasExecutor(){return!!this.dbExecutor}requireExecutor(){if(!this.dbExecutor)throw new Error("Database executor not configured");return this.dbExecutor}createQueryExecutor(e=!1){const t=this.requireExecutor();return new Pn(t,e?this.cacheConfig:void 0)}formatSqlResult(e){const t=this.requireExecutor().getEngineType();return{sql:Y.formatSqlString(e.sql,t),params:e.params}}registerCube(e){this.validateCalculatedMeasures(e),new X(this.cubes).populateDependencies(e),this.cubes.set(e.name,e),this.invalidateMetadataCache()}validateCalculatedMeasures(e){const t=[];for(const[n,i]of Object.entries(e.measures))if(i.type==="calculated"){if(!i.calculatedSql){t.push(`Calculated measure '${e.name}.${n}' must have calculatedSql property`);continue}const s=dn(i.calculatedSql);if(!s.isValid){t.push(`Invalid calculatedSql syntax in '${e.name}.${n}': ${s.errors.join(", ")}`);continue}const r=new Map(this.cubes);r.set(e.name,e);const a=new X(r);try{a.validateDependencies(e)}catch(u){t.push(u instanceof Error?u.message:String(u))}}if(t.length===0){const n=new Map(this.cubes);n.set(e.name,e);const i=new X(n);i.buildGraph(e);const s=i.detectCycle();s&&t.push(`Circular dependency detected in calculated measures: ${s.join(" -> ")}`)}if(t.length>0)throw new Error(`Calculated measure validation failed for cube '${e.name}':
|
|
199
199
|
${t.join(`
|
|
200
|
-
`)}`)}getCube(e){return this.cubes.get(e)}getAllCubes(){return Array.from(this.cubes.values())}getAllCubesMap(){return this.cubes}async execute(e,t,n){return this.createQueryExecutor(!0).execute(this.cubes,e,t,n)}async executeMultiCubeQuery(e,t,n){return this.execute(e,t,n)}async executeQuery(e,t,n){if(!this.cubes.get(e))throw new Error(`Cube '${e}' not found`);return this.execute(t,n)}getMetadata(){return this.metadataCache?this.metadataCache:(this.metadataCache=Array.from(this.cubes.values()).map(e=>this.generateCubeMetadata(e)),this.metadataCache)}getColumnName(e){if(e&&e.name||e&&e.columnType&&e.name)return e.name;if(typeof e=="string")return e;if(e&&typeof e=="object"){if(e._.name)return e._.name;if(e.name)return e.name;if(e.columnName)return e.columnName}return"unknown_column"}static DEFAULT_TIME_GRANULARITIES=["year","quarter","month","week","day","hour"];generateCubeMetadata(e){const t=Object.keys(e.measures),n=Object.keys(e.dimensions),i=new Array(t.length),s=new Array(n.length);for(let c=0;c<t.length;c++){const l=t[c],m=e.measures[l];let p;m.drillMembers&&m.drillMembers.length>0&&(p=m.drillMembers.map(f=>f.includes(".")?f:`${e.name}.${f}`)),i[c]={name:`${e.name}.${l}`,title:m.title||l,shortTitle:m.title||l,type:m.type,format:void 0,description:m.description,synonyms:m.synonyms,drillMembers:p}}for(let c=0;c<n.length;c++){const l=n[c],m=e.dimensions[l];let p;m.type==="time"&&(p=m.granularities||Ie.DEFAULT_TIME_GRANULARITIES),s[c]={name:`${e.name}.${l}`,title:m.title||l,shortTitle:m.title||l,type:m.type,format:void 0,description:m.description,synonyms:m.synonyms,granularities:p}}const r=[];if(e.joins)for(const[,c]of Object.entries(e.joins)){const l=typeof c.targetCube=="function"?c.targetCube():c.targetCube;r.push({targetCube:l.name,relationship:c.relationship,joinFields:c.on.map(m=>({sourceField:this.getColumnName(m.source),targetField:this.getColumnName(m.target)}))})}const a=[];if(e.hierarchies)for(const[,c]of Object.entries(e.hierarchies))a.push({name:c.name,title:c.title||c.name,cubeName:e.name,levels:c.levels.map(l=>l.includes(".")?l:`${e.name}.${l}`)});return{name:e.name,title:e.title||e.name,description:e.description,exampleQuestions:e.exampleQuestions,measures:i,dimensions:s,segments:[],relationships:r.length>0?r:void 0,hierarchies:a.length>0?a:void 0,meta:e.meta}}async generateSQL(e,t,n){const i=this.getCube(e);if(!i)throw new Error(`Cube '${e}' not found`);const r=await this.createQueryExecutor().generateSQL(i,t,n);return this.formatSqlResult(r)}async generateMultiCubeSQL(e,t){const i=await this.createQueryExecutor().generateMultiCubeSQL(this.cubes,e,t);return this.formatSqlResult(i)}async dryRun(e,t){const i=await this.createQueryExecutor().dryRunSQL(this.cubes,e,t);return this.formatSqlResult(i)}async dryRunFunnel(e,t){return this.dryRun(e,t)}async dryRunFlow(e,t){return this.dryRun(e,t)}async dryRunRetention(e,t){return this.dryRun(e,t)}async explainQuery(e,t,n){return this.createQueryExecutor().explainQuery(this.cubes,e,t,n)}hasCube(e){return this.cubes.has(e)}removeCube(e){const t=this.cubes.delete(e);return t&&this.invalidateMetadataCache(),t}clearCubes(){this.cubes.clear(),this.invalidateMetadataCache()}invalidateMetadataCache(){this.metadataCache=void 0}getCubeNames(){return Array.from(this.cubes.keys())}validateQuery(e){return gt(this.cubes,e)}analyzeQuery(e,t){return this.createQueryExecutor(!0).analyzeQuery(this.cubes,e,t)}}function Un(d){const e=[];return d.timeDimensions?.some(t=>t.compareDateRange&&t.compareDateRange.length>=2)&&e.push("comparison"),d.funnel!==void 0&&d.funnel.steps?.length>=2&&e.push("funnel"),d.flow!==void 0&&d.flow.startingStep!==void 0&&d.flow.eventDimension!==void 0&&e.push("flow"),d.retention!==void 0&&d.retention.timeDimension!=null&&d.retention.bindingKey!=null&&e.push("retention"),e.length===0?[]:e}function gt(d,e){const t=[],n=Un(e);if(n.length>1)return t.push(`Query contains multiple query modes: ${n.join(", ")}`),{isValid:!1,errors:t};const i={funnel:()=>{const r=e.funnel.bindingKey;if(typeof r=="string"){const[a]=r.split(".");a&&!d.has(a)&&t.push(`Funnel binding key cube not found: ${a}`)}else if(Array.isArray(r))for(const a of r)d.has(a.cube)||t.push(`Funnel binding key cube not found: ${a.cube}`)},flow:()=>{const r=e.flow.bindingKey;if(typeof r=="string"){const[a]=r.split(".");a&&!d.has(a)&&t.push(`Flow binding key cube not found: ${a}`)}},retention:()=>{const r=e.retention,a=xn(r.timeDimension);a&&!d.has(a)&&t.push(`Retention cube not found: ${a}`);const u=r.bindingKey;if(typeof u=="string"){const[c]=u.split(".");c&&!d.has(c)&&t.push(`Retention binding key cube not found: ${c}`)}else if(Array.isArray(u))for(const c of u)d.has(c.cube)||t.push(`Retention binding key cube not found: ${c.cube}`);if(r.breakdownDimensions&&Array.isArray(r.breakdownDimensions))for(const c of r.breakdownDimensions){const[l]=c.split(".");l&&!d.has(l)&&t.push(`Retention breakdown cube not found: ${l}`)}}};if(n.length===1&&n[0]!=="comparison"){const r=n[0];return i[r](),{isValid:t.length===0,errors:t}}const s=new Set;if(e.measures)for(const r of e.measures){const[a,u]=r.split(".");if(!a||!u){t.push(`Invalid measure format: ${r}. Expected format: 'CubeName.fieldName'`);continue}s.add(a);const c=d.get(a);if(!c){t.push(`Cube '${a}' not found (referenced in measure '${r}')`);continue}if(!c.measures[u]){const l=u===a?`. Did you mean one of: ${Object.keys(c.measures).slice(0,5).map(m=>`'${a}.${m}'`).join(", ")}?`:"";t.push(`Measure '${u}' not found on cube '${a}'${l}`)}}if(e.dimensions)for(const r of e.dimensions){const[a,u]=r.split(".");if(!a||!u){t.push(`Invalid dimension format: ${r}. Expected format: 'CubeName.fieldName'`);continue}s.add(a);const c=d.get(a);if(!c){t.push(`Cube '${a}' not found (referenced in dimension '${r}')`);continue}if(!c.dimensions[u]){const l=u===a?`. Did you mean one of: ${Object.keys(c.dimensions).slice(0,5).map(m=>`'${a}.${m}'`).join(", ")}?`:"";t.push(`Dimension '${u}' not found on cube '${a}'${l}`)}}if(e.timeDimensions)for(const r of e.timeDimensions){const[a,u]=r.dimension.split(".");if(!a||!u){t.push(`Invalid timeDimension format: ${r.dimension}. Expected format: 'CubeName.fieldName'`);continue}s.add(a);const c=d.get(a);if(!c){t.push(`Cube '${a}' not found (referenced in timeDimension '${r.dimension}')`);continue}c.dimensions[u]||t.push(`TimeDimension '${u}' not found on cube '${a}' (must be a dimension with time type)`)}if(e.filters)for(const r of e.filters)bt(r,d,t,s);return s.size===0&&t.push("Query must reference at least one cube through measures, dimensions, or filters"),{isValid:t.length===0,errors:t}}function bt(d,e,t,n){if("and"in d||"or"in d){const a=d.and||d.or||[];for(const u of a)bt(u,e,t,n);return}if(!("member"in d)){t.push("Filter must have a member field");return}const[i,s]=d.member.split(".");if(!i||!s){t.push(`Invalid filter member format: ${d.member}. Expected format: 'CubeName.fieldName'`);return}n.add(i);const r=e.get(i);if(!r){t.push(`Cube '${i}' not found (referenced in filter '${d.member}')`);return}if(!r.dimensions[s]&&!r.measures[s]){const a=s===i?`. Did you mean one of: ${[...Object.keys(r.dimensions),...Object.keys(r.measures)].slice(0,5).map(u=>`'${i}.${u}'`).join(", ")}?`:"";t.push(`Filter field '${s}' not found on cube '${i}' (must be a dimension or measure)${a}`)}}function xn(d){if(typeof d=="string"){const[e]=d.split(".");return e||null}return d.cube}const le=["2025-11-25","2025-06-18","2025-03-26"],yt="2025-11-25";function Qn(d){const t=Xn(d["mcp-protocol-version"])||yt;return{ok:le.includes(t),negotiated:le.includes(t)?t:null,supported:le}}function Kn(d){if(!d)return!1;const e=d.split(",").map(i=>i.trim().toLowerCase()),t=e.includes("text/event-stream"),n=e.includes("application/json");return t&&!n}const Wn="mcp-session-id";function Jn(d){if(!d)return!1;const e=d.split(",").map(i=>i.trim().toLowerCase().split(";")[0]),t=e.some(i=>i==="application/json"),n=e.some(i=>i==="text/event-stream");return t&&n}function zn(d,e={}){const{allowMissingOrigin:t=!0,allowedOrigins:n}=e;if(!d)return t?{valid:!0}:{valid:!1,reason:"Origin header is required"};if(!n||n.length===0)return{valid:!0};let i;try{i=new URL(d)}catch{return{valid:!1,reason:"Invalid Origin header format"}}return n.map(r=>{try{return new URL(r).origin}catch{return r}}).includes(i.origin)?{valid:!0}:{valid:!1,reason:"Origin not in allowed list"}}function qn(d,e,t){const n=[];return e&&n.push(`id: ${e}`),t&&t>0&&n.push(`retry: ${t}`),n.push("event: message"),n.push(`data: ${JSON.stringify(d)}`),n.push(""),n.join(`
|
|
200
|
+
`)}`)}getCube(e){return this.cubes.get(e)}getAllCubes(){return Array.from(this.cubes.values())}getAllCubesMap(){return this.cubes}async execute(e,t,n){return this.createQueryExecutor(!0).execute(this.cubes,e,t,n)}async executeMultiCubeQuery(e,t,n){return this.execute(e,t,n)}async executeQuery(e,t,n){if(!this.cubes.get(e))throw new Error(`Cube '${e}' not found`);return this.execute(t,n)}getMetadata(){return this.metadataCache?this.metadataCache:(this.metadataCache=Array.from(this.cubes.values()).map(e=>this.generateCubeMetadata(e)),this.metadataCache)}getColumnName(e){if(e&&e.name||e&&e.columnType&&e.name)return e.name;if(typeof e=="string")return e;if(e&&typeof e=="object"){if(e._.name)return e._.name;if(e.name)return e.name;if(e.columnName)return e.columnName}return"unknown_column"}static DEFAULT_TIME_GRANULARITIES=["year","quarter","month","week","day","hour"];generateCubeMetadata(e){const t=Object.keys(e.measures),n=Object.keys(e.dimensions),i=new Array(t.length),s=new Array(n.length);for(let c=0;c<t.length;c++){const l=t[c],m=e.measures[l];let p;m.drillMembers&&m.drillMembers.length>0&&(p=m.drillMembers.map(f=>f.includes(".")?f:`${e.name}.${f}`)),i[c]={name:`${e.name}.${l}`,title:m.title||l,shortTitle:m.title||l,type:m.type,format:void 0,description:m.description,synonyms:m.synonyms,drillMembers:p}}for(let c=0;c<n.length;c++){const l=n[c],m=e.dimensions[l];let p;m.type==="time"&&(p=m.granularities||Ie.DEFAULT_TIME_GRANULARITIES),s[c]={name:`${e.name}.${l}`,title:m.title||l,shortTitle:m.title||l,type:m.type,format:void 0,description:m.description,synonyms:m.synonyms,granularities:p}}const r=[];if(e.joins)for(const[,c]of Object.entries(e.joins)){const l=typeof c.targetCube=="function"?c.targetCube():c.targetCube;r.push({targetCube:l.name,relationship:c.relationship,joinFields:c.on.map(m=>({sourceField:this.getColumnName(m.source),targetField:this.getColumnName(m.target)}))})}const a=[];if(e.hierarchies)for(const[,c]of Object.entries(e.hierarchies))a.push({name:c.name,title:c.title||c.name,cubeName:e.name,levels:c.levels.map(l=>l.includes(".")?l:`${e.name}.${l}`)});return{name:e.name,title:e.title||e.name,description:e.description,exampleQuestions:e.exampleQuestions,measures:i,dimensions:s,segments:[],relationships:r.length>0?r:void 0,hierarchies:a.length>0?a:void 0,meta:e.meta}}async generateSQL(e,t,n){const i=this.getCube(e);if(!i)throw new Error(`Cube '${e}' not found`);const r=await this.createQueryExecutor().generateSQL(i,t,n);return this.formatSqlResult(r)}async generateMultiCubeSQL(e,t){const i=await this.createQueryExecutor().generateMultiCubeSQL(this.cubes,e,t);return this.formatSqlResult(i)}async dryRun(e,t){const i=await this.createQueryExecutor().dryRunSQL(this.cubes,e,t);return this.formatSqlResult(i)}async dryRunFunnel(e,t){return this.dryRun(e,t)}async dryRunFlow(e,t){return this.dryRun(e,t)}async dryRunRetention(e,t){return this.dryRun(e,t)}async explainQuery(e,t,n){return this.createQueryExecutor().explainQuery(this.cubes,e,t,n)}hasCube(e){return this.cubes.has(e)}unregisterCube(e){return this.removeCube(e)}removeCube(e){const t=this.cubes.delete(e);return t&&this.invalidateMetadataCache(),t}clearCubes(){this.cubes.clear(),this.invalidateMetadataCache()}invalidateMetadataCache(){this.metadataCache=void 0}getCubeNames(){return Array.from(this.cubes.keys())}validateQuery(e){return gt(this.cubes,e)}analyzeQuery(e,t){return this.createQueryExecutor(!0).analyzeQuery(this.cubes,e,t)}}function Un(d){const e=[];return d.timeDimensions?.some(t=>t.compareDateRange&&t.compareDateRange.length>=2)&&e.push("comparison"),d.funnel!==void 0&&d.funnel.steps?.length>=2&&e.push("funnel"),d.flow!==void 0&&d.flow.startingStep!==void 0&&d.flow.eventDimension!==void 0&&e.push("flow"),d.retention!==void 0&&d.retention.timeDimension!=null&&d.retention.bindingKey!=null&&e.push("retention"),e.length===0?[]:e}function gt(d,e){const t=[],n=Un(e);if(n.length>1)return t.push(`Query contains multiple query modes: ${n.join(", ")}`),{isValid:!1,errors:t};const i={funnel:()=>{const r=e.funnel.bindingKey;if(typeof r=="string"){const[a]=r.split(".");a&&!d.has(a)&&t.push(`Funnel binding key cube not found: ${a}`)}else if(Array.isArray(r))for(const a of r)d.has(a.cube)||t.push(`Funnel binding key cube not found: ${a.cube}`)},flow:()=>{const r=e.flow.bindingKey;if(typeof r=="string"){const[a]=r.split(".");a&&!d.has(a)&&t.push(`Flow binding key cube not found: ${a}`)}},retention:()=>{const r=e.retention,a=xn(r.timeDimension);a&&!d.has(a)&&t.push(`Retention cube not found: ${a}`);const u=r.bindingKey;if(typeof u=="string"){const[c]=u.split(".");c&&!d.has(c)&&t.push(`Retention binding key cube not found: ${c}`)}else if(Array.isArray(u))for(const c of u)d.has(c.cube)||t.push(`Retention binding key cube not found: ${c.cube}`);if(r.breakdownDimensions&&Array.isArray(r.breakdownDimensions))for(const c of r.breakdownDimensions){const[l]=c.split(".");l&&!d.has(l)&&t.push(`Retention breakdown cube not found: ${l}`)}}};if(n.length===1&&n[0]!=="comparison"){const r=n[0];return i[r](),{isValid:t.length===0,errors:t}}const s=new Set;if(e.measures)for(const r of e.measures){const[a,u]=r.split(".");if(!a||!u){t.push(`Invalid measure format: ${r}. Expected format: 'CubeName.fieldName'`);continue}s.add(a);const c=d.get(a);if(!c){t.push(`Cube '${a}' not found (referenced in measure '${r}')`);continue}if(!c.measures[u]){const l=u===a?`. Did you mean one of: ${Object.keys(c.measures).slice(0,5).map(m=>`'${a}.${m}'`).join(", ")}?`:"";t.push(`Measure '${u}' not found on cube '${a}'${l}`)}}if(e.dimensions)for(const r of e.dimensions){const[a,u]=r.split(".");if(!a||!u){t.push(`Invalid dimension format: ${r}. Expected format: 'CubeName.fieldName'`);continue}s.add(a);const c=d.get(a);if(!c){t.push(`Cube '${a}' not found (referenced in dimension '${r}')`);continue}if(!c.dimensions[u]){const l=u===a?`. Did you mean one of: ${Object.keys(c.dimensions).slice(0,5).map(m=>`'${a}.${m}'`).join(", ")}?`:"";t.push(`Dimension '${u}' not found on cube '${a}'${l}`)}}if(e.timeDimensions)for(const r of e.timeDimensions){const[a,u]=r.dimension.split(".");if(!a||!u){t.push(`Invalid timeDimension format: ${r.dimension}. Expected format: 'CubeName.fieldName'`);continue}s.add(a);const c=d.get(a);if(!c){t.push(`Cube '${a}' not found (referenced in timeDimension '${r.dimension}')`);continue}c.dimensions[u]||t.push(`TimeDimension '${u}' not found on cube '${a}' (must be a dimension with time type)`)}if(e.filters)for(const r of e.filters)bt(r,d,t,s);return s.size===0&&t.push("Query must reference at least one cube through measures, dimensions, or filters"),{isValid:t.length===0,errors:t}}function bt(d,e,t,n){if("and"in d||"or"in d){const a=d.and||d.or||[];for(const u of a)bt(u,e,t,n);return}if(!("member"in d)){t.push("Filter must have a member field");return}const[i,s]=d.member.split(".");if(!i||!s){t.push(`Invalid filter member format: ${d.member}. Expected format: 'CubeName.fieldName'`);return}n.add(i);const r=e.get(i);if(!r){t.push(`Cube '${i}' not found (referenced in filter '${d.member}')`);return}if(!r.dimensions[s]&&!r.measures[s]){const a=s===i?`. Did you mean one of: ${[...Object.keys(r.dimensions),...Object.keys(r.measures)].slice(0,5).map(u=>`'${i}.${u}'`).join(", ")}?`:"";t.push(`Filter field '${s}' not found on cube '${i}' (must be a dimension or measure)${a}`)}}function xn(d){if(typeof d=="string"){const[e]=d.split(".");return e||null}return d.cube}const le=["2025-11-25","2025-06-18","2025-03-26"],yt="2025-11-25";function Qn(d){const t=Xn(d["mcp-protocol-version"])||yt;return{ok:le.includes(t),negotiated:le.includes(t)?t:null,supported:le}}function Kn(d){if(!d)return!1;const e=d.split(",").map(i=>i.trim().toLowerCase()),t=e.includes("text/event-stream"),n=e.includes("application/json");return t&&!n}const Wn="mcp-session-id";function Jn(d){if(!d)return!1;const e=d.split(",").map(i=>i.trim().toLowerCase().split(";")[0]),t=e.some(i=>i==="application/json"),n=e.some(i=>i==="text/event-stream");return t&&n}function zn(d,e={}){const{allowMissingOrigin:t=!0,allowedOrigins:n}=e;if(!d)return t?{valid:!0}:{valid:!1,reason:"Origin header is required"};if(!n||n.length===0)return{valid:!0};let i;try{i=new URL(d)}catch{return{valid:!1,reason:"Invalid Origin header format"}}return n.map(r=>{try{return new URL(r).origin}catch{return r}}).includes(i.origin)?{valid:!0}:{valid:!1,reason:"Origin not in allowed list"}}function qn(d,e,t){const n=[];return e&&n.push(`id: ${e}`),t&&t>0&&n.push(`retry: ${t}`),n.push("event: message"),n.push(`data: ${JSON.stringify(d)}`),n.push(""),n.join(`
|
|
201
201
|
`)}function Vn(d,e,t,n){return{jsonrpc:"2.0",id:d??null,error:{code:e,message:t,...n!==void 0?{data:n}:{}}}}function Gn(d,e){return{jsonrpc:"2.0",id:d??null,result:e}}function Hn(d){if(!d||typeof d!="object")return null;const e=d;return e.jsonrpc!=="2.0"||typeof e.method!="string"?null:{jsonrpc:"2.0",method:e.method,id:e.id,params:e.params}}async function Yn(d,e,t){const{semanticLayer:n,extractSecurityContext:i,rawRequest:s,rawResponse:r}=t,a=t.prompts??wt,u=t.resources??$t;switch(d){case"initialize":{const c=e?.protocolVersion;let l;return c&&le.includes(c)?l=c:l=yt,{protocolVersion:l,capabilities:{tools:{listChanged:!1},resources:{listChanged:!1},prompts:{listChanged:!1},sampling:{}},sessionId:Ct(),serverInfo:{name:"drizzle-cube",version:typeof process<"u"?process.env?.npm_package_version||"dev":"worker"}}}case"list_tools":case"tools/list":return{tools:ei(),nextCursor:""};case"call_tool":case"tools/call":return ti(e,t);case"resources/list":return{resources:u.map(({uri:c,name:l,description:m,mimeType:p})=>({uri:c,name:l,description:m,mimeType:p})),nextCursor:""};case"resources/templates/list":return{resourceTemplates:[],nextCursor:""};case"resources/read":{const c=e?.uri,l=u.find(m=>m.uri===c)||u[0];if(!l)throw G(-32602,"resource not found");return{contents:[{uri:l.uri,mimeType:l.mimeType,text:l.text}]}}case"prompts/list":return{prompts:a.map(({name:c,description:l})=>({name:c,description:l})),nextCursor:""};case"ping":return{};case"notifications/initialized":return{};case"prompts/get":{const c=e?.name,l=a.find(m=>m.name===c)||a[0];if(!l)throw G(-32602,"prompt not found");return{name:l.name,description:l.description,messages:l.messages}}case"discover":return Y.handleDiscover(n,e||{});case"validate":{const c=e||{};if(!c.query)throw G(-32602,"query is required");return Y.handleValidate(n,c)}case"load":{const c=e||{};if(!c.query)throw G(-32602,"query is required");const l=await i(s,r);return Y.handleLoad(n,l,c)}default:throw G(-32601,`Unknown MCP method: ${d}`)}}function G(d,e,t){const n=new Error(e);return n.code=d,n}function Xn(d){return d?Array.isArray(d)?d[0]||null:d:null}function Zn(d){return d.id===void 0||d.id===null}function Ct(){return`evt-${Y.generateRequestId()}`}function ei(){return[{name:"discover",description:`Find relevant cubes based on topic or intent. Call this FIRST to understand available data.
|
|
202
202
|
|
|
203
203
|
Returns cubes with:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("next/server"),f=require("../mcp-transport-8u9G5oNa.cjs"),i=require("../utils.cjs");function v(n){const{cubes:o,drizzle:s,schema:c,engineType:d,cache:a}=n;if(!o||o.length===0)throw new Error("At least one cube must be provided in the cubes array");const t=new f.SemanticLayerCompiler({drizzle:s,schema:c,engineType:d,cache:a});return o.forEach(e=>{t.registerCube(e)}),t}function h(n,o){const s=n.headers.get("origin"),c={};return o.origin&&(typeof o.origin=="string"?c["Access-Control-Allow-Origin"]=o.origin:Array.isArray(o.origin)?s&&o.origin.includes(s)&&(c["Access-Control-Allow-Origin"]=s):typeof o.origin=="function"&&s&&o.origin(s)&&(c["Access-Control-Allow-Origin"]=s)),o.methods&&(c["Access-Control-Allow-Methods"]=o.methods.join(", ")),o.allowedHeaders&&(c["Access-Control-Allow-Headers"]=o.allowedHeaders.join(", ")),o.credentials&&(c["Access-Control-Allow-Credentials"]="true"),c}function J(n){return async function(s){const c=h(s,n);return new Response(null,{status:200,headers:c})}}function T(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{let e;if(a.method==="POST"){const N=await a.json();e=N.query||N}else if(a.method==="GET"){const N=a.nextUrl.searchParams.get("query");if(!N)return r.NextResponse.json(i.formatErrorResponse("Query parameter is required",400),{status:400});try{e=JSON.parse(N)}catch{return r.NextResponse.json(i.formatErrorResponse("Invalid JSON in query parameter",400),{status:400})}}else return r.NextResponse.json(i.formatErrorResponse("Method not allowed",405),{status:405});const l=await o(a,t),y=c.validateQuery(e);if(!y.isValid)return r.NextResponse.json(i.formatErrorResponse(`Query validation failed: ${y.errors.join(", ")}`,400),{status:400});const u=a.headers.get("x-cache-control")==="no-cache",p=await c.executeMultiCubeQuery(e,l,{skipCache:u}),w=i.formatCubeResponse(e,p,c);return r.NextResponse.json(w,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js load handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500),{status:500})}}}function A(n){const{cors:o}=n,s=v(n);return async function(d,a){try{const t=s.getMetadata(),e=i.formatMetaResponse(t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js meta handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Failed to fetch metadata",500),{status:500})}}}function M(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{let e;if(a.method==="POST"){const C=await a.json();e=C.query||C}else if(a.method==="GET"){const C=a.nextUrl.searchParams.get("query");if(!C)return r.NextResponse.json(i.formatErrorResponse("Query parameter is required",400),{status:400});try{e=JSON.parse(C)}catch{return r.NextResponse.json(i.formatErrorResponse("Invalid JSON in query parameter",400),{status:400})}}else return r.NextResponse.json(i.formatErrorResponse("Method not allowed",405),{status:405});const l=await o(a,t),y=c.validateQuery(e);if(!y.isValid)return r.NextResponse.json(i.formatErrorResponse(`Query validation failed: ${y.errors.join(", ")}`,400),{status:400});const u=e.measures?.[0]||e.dimensions?.[0];if(!u)return r.NextResponse.json(i.formatErrorResponse("No measures or dimensions specified",400),{status:400});const p=u.split(".")[0],w=await c.generateSQL(p,e,l),N=i.formatSqlResponse(e,w);return r.NextResponse.json(N,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js SQL handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500),{status:500})}}}function L(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{let e;if(a.method==="POST"){const u=await a.json();e=u.query||u}else if(a.method==="GET"){const u=a.nextUrl.searchParams.get("query");if(!u)return r.NextResponse.json({error:"Query parameter is required",valid:!1},{status:400});try{e=JSON.parse(u)}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});const l=await o(a,t),y=await i.handleDryRun(e,l,c);return r.NextResponse.json(y,{headers:s?h(a,s):{}})}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(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{if(a.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const e=await a.json(),{queries:l}=e;if(!l||!Array.isArray(l))return r.NextResponse.json(i.formatErrorResponse('Request body must contain a "queries" array',400),{status:400});if(l.length===0)return r.NextResponse.json(i.formatErrorResponse("Queries array cannot be empty",400),{status:400});const y=await o(a,t),u=a.headers.get("x-cache-control")==="no-cache",p=await i.handleBatchRequest(l,y,c,{skipCache:u});return r.NextResponse.json(p,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js batch handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"Batch execution failed",500),{status:500})}}}function V(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{if(a.method!=="POST")return r.NextResponse.json({error:"Method not allowed"},{status:405});const e=await a.json(),l=e.query||e,y=e.options||{},u=await o(a,t),p=c.validateQuery(l);if(!p.isValid)return r.NextResponse.json({error:`Query validation failed: ${p.errors.join(", ")}`},{status:400});const w=await c.explainQuery(l,u,y);return r.NextResponse.json(w,{headers:s?h(a,s):{}})}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 k(n){const{cors:o}=n,s=v(n);return async function(d,a){try{if(d.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const t=await d.json(),e=await i.handleDiscover(s,t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js discover handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Discovery failed",500),{status:500})}}}function K(n){const{cors:o}=n,s=v(n);return async function(d,a){try{if(d.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const t=await d.json();if(!t.naturalLanguage)return r.NextResponse.json(i.formatErrorResponse("naturalLanguage field is required",400),{status:400});const e=await i.handleSuggest(s,t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js suggest handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Query suggestion failed",500),{status:500})}}}function z(n){const{cors:o}=n,s=v(n);return async function(d,a){try{if(d.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const t=await d.json();if(!t.query)return r.NextResponse.json(i.formatErrorResponse("query field is required",400),{status:400});const e=await i.handleValidate(s,t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js validate handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Query validation failed",500),{status:500})}}}function $(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{if(a.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const e=await a.json();if(!e.query)return r.NextResponse.json(i.formatErrorResponse("query field is required",400),{status:400});const l=await o(a,t),y=await i.handleLoad(c,l,e);return r.NextResponse.json(y,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js MCP load handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500),{status:500})}}}function _(n){const{extractSecurityContext:o,cors:s,mcp:c={enabled:!0}}=n,d=v(n);return async function(t){if(t.method==="DELETE")return r.NextResponse.json({error:"Session termination not supported"},{status:405});if(t.method==="GET"){const m=new TextEncoder,S=f.primeEventId(),j=new ReadableStream({start(R){R.enqueue(m.encode(f.serializeSseEvent({jsonrpc:"2.0",method:"mcp/ready",params:{protocol:"streamable-http"}},S,15e3)))}}),H=new Headers({"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});if(s){const R=h(t,s);Object.entries(R).forEach(([b,O])=>H.set(b,O))}return new r.NextResponse(j,{status:200,headers:H})}if(t.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const e=f.validateOriginHeader(t.headers.get("origin"),c.allowedOrigins?{allowedOrigins:c.allowedOrigins}:{});if(!e.valid)return r.NextResponse.json(f.buildJsonRpcError(null,-32600,e.reason),{status:403});const l=t.headers.get("accept");if(!f.validateAcceptHeader(l))return r.NextResponse.json(f.buildJsonRpcError(null,-32600,"Accept header must include both application/json and text/event-stream"),{status:400});const y=f.negotiateProtocol(Object.fromEntries(t.headers.entries()));if(!y.ok)return r.NextResponse.json({error:"Unsupported MCP protocol version",supported:y.supported},{status:426});let u;try{u=await t.json()}catch{u=null}const p=f.parseJsonRpc(u);if(!p)return r.NextResponse.json(f.buildJsonRpcError(null,-32600,"Invalid JSON-RPC 2.0 request"),{status:400});const w=f.wantsEventStream(l),N=p.method==="initialize",C=(m,S=200,j={})=>r.NextResponse.json(m,{status:S,headers:{...s?h(t,s):{},...j}});try{const m=await f.dispatchMcpMethod(p.method,p.params,{semanticLayer:d,extractSecurityContext:R=>o(R),rawRequest:t,rawResponse:null});if(f.isNotification(p))return new r.NextResponse(null,{status:202});const S=N&&m&&typeof m=="object"&&"sessionId"in m?m.sessionId:void 0,j={};S&&(j[f.MCP_SESSION_ID_HEADER]=S);const H=f.buildJsonRpcResult(p.id??null,m);if(w){const R=new TextEncoder,b=f.primeEventId(),O=new ReadableStream({start(x){x.enqueue(R.encode(`id: ${b}
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const r=require("next/server"),f=require("../mcp-transport-DCiSGtp1.cjs"),i=require("../utils.cjs");function v(n){const{cubes:o,drizzle:s,schema:c,engineType:d,cache:a}=n;if(!o||o.length===0)throw new Error("At least one cube must be provided in the cubes array");const t=new f.SemanticLayerCompiler({drizzle:s,schema:c,engineType:d,cache:a});return o.forEach(e=>{t.registerCube(e)}),t}function h(n,o){const s=n.headers.get("origin"),c={};return o.origin&&(typeof o.origin=="string"?c["Access-Control-Allow-Origin"]=o.origin:Array.isArray(o.origin)?s&&o.origin.includes(s)&&(c["Access-Control-Allow-Origin"]=s):typeof o.origin=="function"&&s&&o.origin(s)&&(c["Access-Control-Allow-Origin"]=s)),o.methods&&(c["Access-Control-Allow-Methods"]=o.methods.join(", ")),o.allowedHeaders&&(c["Access-Control-Allow-Headers"]=o.allowedHeaders.join(", ")),o.credentials&&(c["Access-Control-Allow-Credentials"]="true"),c}function J(n){return async function(s){const c=h(s,n);return new Response(null,{status:200,headers:c})}}function T(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{let e;if(a.method==="POST"){const N=await a.json();e=N.query||N}else if(a.method==="GET"){const N=a.nextUrl.searchParams.get("query");if(!N)return r.NextResponse.json(i.formatErrorResponse("Query parameter is required",400),{status:400});try{e=JSON.parse(N)}catch{return r.NextResponse.json(i.formatErrorResponse("Invalid JSON in query parameter",400),{status:400})}}else return r.NextResponse.json(i.formatErrorResponse("Method not allowed",405),{status:405});const l=await o(a,t),y=c.validateQuery(e);if(!y.isValid)return r.NextResponse.json(i.formatErrorResponse(`Query validation failed: ${y.errors.join(", ")}`,400),{status:400});const u=a.headers.get("x-cache-control")==="no-cache",p=await c.executeMultiCubeQuery(e,l,{skipCache:u}),w=i.formatCubeResponse(e,p,c);return r.NextResponse.json(w,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js load handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500),{status:500})}}}function A(n){const{cors:o}=n,s=v(n);return async function(d,a){try{const t=s.getMetadata(),e=i.formatMetaResponse(t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js meta handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Failed to fetch metadata",500),{status:500})}}}function M(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{let e;if(a.method==="POST"){const C=await a.json();e=C.query||C}else if(a.method==="GET"){const C=a.nextUrl.searchParams.get("query");if(!C)return r.NextResponse.json(i.formatErrorResponse("Query parameter is required",400),{status:400});try{e=JSON.parse(C)}catch{return r.NextResponse.json(i.formatErrorResponse("Invalid JSON in query parameter",400),{status:400})}}else return r.NextResponse.json(i.formatErrorResponse("Method not allowed",405),{status:405});const l=await o(a,t),y=c.validateQuery(e);if(!y.isValid)return r.NextResponse.json(i.formatErrorResponse(`Query validation failed: ${y.errors.join(", ")}`,400),{status:400});const u=e.measures?.[0]||e.dimensions?.[0];if(!u)return r.NextResponse.json(i.formatErrorResponse("No measures or dimensions specified",400),{status:400});const p=u.split(".")[0],w=await c.generateSQL(p,e,l),N=i.formatSqlResponse(e,w);return r.NextResponse.json(N,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js SQL handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500),{status:500})}}}function L(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{let e;if(a.method==="POST"){const u=await a.json();e=u.query||u}else if(a.method==="GET"){const u=a.nextUrl.searchParams.get("query");if(!u)return r.NextResponse.json({error:"Query parameter is required",valid:!1},{status:400});try{e=JSON.parse(u)}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});const l=await o(a,t),y=await i.handleDryRun(e,l,c);return r.NextResponse.json(y,{headers:s?h(a,s):{}})}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(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{if(a.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const e=await a.json(),{queries:l}=e;if(!l||!Array.isArray(l))return r.NextResponse.json(i.formatErrorResponse('Request body must contain a "queries" array',400),{status:400});if(l.length===0)return r.NextResponse.json(i.formatErrorResponse("Queries array cannot be empty",400),{status:400});const y=await o(a,t),u=a.headers.get("x-cache-control")==="no-cache",p=await i.handleBatchRequest(l,y,c,{skipCache:u});return r.NextResponse.json(p,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js batch handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"Batch execution failed",500),{status:500})}}}function V(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{if(a.method!=="POST")return r.NextResponse.json({error:"Method not allowed"},{status:405});const e=await a.json(),l=e.query||e,y=e.options||{},u=await o(a,t),p=c.validateQuery(l);if(!p.isValid)return r.NextResponse.json({error:`Query validation failed: ${p.errors.join(", ")}`},{status:400});const w=await c.explainQuery(l,u,y);return r.NextResponse.json(w,{headers:s?h(a,s):{}})}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 k(n){const{cors:o}=n,s=v(n);return async function(d,a){try{if(d.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const t=await d.json(),e=await i.handleDiscover(s,t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js discover handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Discovery failed",500),{status:500})}}}function K(n){const{cors:o}=n,s=v(n);return async function(d,a){try{if(d.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const t=await d.json();if(!t.naturalLanguage)return r.NextResponse.json(i.formatErrorResponse("naturalLanguage field is required",400),{status:400});const e=await i.handleSuggest(s,t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js suggest handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Query suggestion failed",500),{status:500})}}}function z(n){const{cors:o}=n,s=v(n);return async function(d,a){try{if(d.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const t=await d.json();if(!t.query)return r.NextResponse.json(i.formatErrorResponse("query field is required",400),{status:400});const e=await i.handleValidate(s,t);return r.NextResponse.json(e,{headers:o?h(d,o):{}})}catch(t){return process.env.NODE_ENV!=="test"&&console.error("Next.js validate handler error:",t),r.NextResponse.json(i.formatErrorResponse(t instanceof Error?t.message:"Query validation failed",500),{status:500})}}}function $(n){const{extractSecurityContext:o,cors:s}=n,c=v(n);return async function(a,t){try{if(a.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const e=await a.json();if(!e.query)return r.NextResponse.json(i.formatErrorResponse("query field is required",400),{status:400});const l=await o(a,t),y=await i.handleLoad(c,l,e);return r.NextResponse.json(y,{headers:s?h(a,s):{}})}catch(e){return process.env.NODE_ENV!=="test"&&console.error("Next.js MCP load handler error:",e),r.NextResponse.json(i.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500),{status:500})}}}function _(n){const{extractSecurityContext:o,cors:s,mcp:c={enabled:!0}}=n,d=v(n);return async function(t){if(t.method==="DELETE")return r.NextResponse.json({error:"Session termination not supported"},{status:405});if(t.method==="GET"){const m=new TextEncoder,S=f.primeEventId(),j=new ReadableStream({start(R){R.enqueue(m.encode(f.serializeSseEvent({jsonrpc:"2.0",method:"mcp/ready",params:{protocol:"streamable-http"}},S,15e3)))}}),H=new Headers({"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});if(s){const R=h(t,s);Object.entries(R).forEach(([b,O])=>H.set(b,O))}return new r.NextResponse(j,{status:200,headers:H})}if(t.method!=="POST")return r.NextResponse.json(i.formatErrorResponse("Method not allowed - use POST",405),{status:405});const e=f.validateOriginHeader(t.headers.get("origin"),c.allowedOrigins?{allowedOrigins:c.allowedOrigins}:{});if(!e.valid)return r.NextResponse.json(f.buildJsonRpcError(null,-32600,e.reason),{status:403});const l=t.headers.get("accept");if(!f.validateAcceptHeader(l))return r.NextResponse.json(f.buildJsonRpcError(null,-32600,"Accept header must include both application/json and text/event-stream"),{status:400});const y=f.negotiateProtocol(Object.fromEntries(t.headers.entries()));if(!y.ok)return r.NextResponse.json({error:"Unsupported MCP protocol version",supported:y.supported},{status:426});let u;try{u=await t.json()}catch{u=null}const p=f.parseJsonRpc(u);if(!p)return r.NextResponse.json(f.buildJsonRpcError(null,-32600,"Invalid JSON-RPC 2.0 request"),{status:400});const w=f.wantsEventStream(l),N=p.method==="initialize",C=(m,S=200,j={})=>r.NextResponse.json(m,{status:S,headers:{...s?h(t,s):{},...j}});try{const m=await f.dispatchMcpMethod(p.method,p.params,{semanticLayer:d,extractSecurityContext:R=>o(R),rawRequest:t,rawResponse:null});if(f.isNotification(p))return new r.NextResponse(null,{status:202});const S=N&&m&&typeof m=="object"&&"sessionId"in m?m.sessionId:void 0,j={};S&&(j[f.MCP_SESSION_ID_HEADER]=S);const H=f.buildJsonRpcResult(p.id??null,m);if(w){const R=new TextEncoder,b=f.primeEventId(),O=new ReadableStream({start(x){x.enqueue(R.encode(`id: ${b}
|
|
2
2
|
|
|
3
3
|
`)),x.enqueue(R.encode(f.serializeSseEvent(H,b))),x.close()}}),E=new Headers({"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive",...j});if(s){const x=h(t,s);Object.entries(x).forEach(([g,P])=>E.set(g,P))}return new r.NextResponse(O,{status:200,headers:E})}return C(H,200,j)}catch(m){if(f.isNotification(p))return process.env.NODE_ENV!=="test"&&console.error("Next.js MCP notification processing error:",m),new r.NextResponse(null,{status:202});process.env.NODE_ENV!=="test"&&console.error("Next.js MCP RPC handler error:",m);const S=m?.code??-32603,j=m?.data,H=m.message||"MCP request failed",R=f.buildJsonRpcError(p.id??null,S,H,j);if(w){const b=new TextEncoder,O=f.primeEventId(),E=new ReadableStream({start(g){g.enqueue(b.encode(`id: ${O}
|
|
4
4
|
|
|
5
|
-
`)),g.enqueue(b.encode(f.serializeSseEvent(R,O))),g.close()}}),x=new Headers({"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});if(s){const g=h(t,s);Object.entries(g).forEach(([P,I])=>x.set(P,I))}return new r.NextResponse(E,{status:200,headers:x})}return C(R,200)}}}function Q(n){const{extractSecurityContext:o,cors:s,agent:c}=n;if(!c)throw new Error("agent config is required for createAgentChatHandler");const d=v(n);return async function(t,e){try{if(t.method!=="POST")return r.NextResponse.json({error:"Method not allowed - use POST"},{status:405});const{handleAgentChat:l}=await Promise.resolve().then(()=>require("../handler-
|
|
5
|
+
`)),g.enqueue(b.encode(f.serializeSseEvent(R,O))),g.close()}}),x=new Headers({"Content-Type":"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"});if(s){const g=h(t,s);Object.entries(g).forEach(([P,I])=>x.set(P,I))}return new r.NextResponse(E,{status:200,headers:x})}return C(R,200)}}}function Q(n){const{extractSecurityContext:o,cors:s,agent:c}=n;if(!c)throw new Error("agent config is required for createAgentChatHandler");const d=v(n);return async function(t,e){try{if(t.method!=="POST")return r.NextResponse.json({error:"Method not allowed - use POST"},{status:405});const{handleAgentChat:l}=await Promise.resolve().then(()=>require("../handler-LMRPeTNJ.cjs")),y=await t.json(),{message:u,sessionId:p,history:w}=y;if(!u||typeof u!="string")return r.NextResponse.json({error:"message is required and must be a string"},{status:400});let N=(c.apiKey||"").trim();if(c.allowClientApiKey){const E=t.headers.get("x-agent-api-key");E&&(N=E.trim())}if(!N)return r.NextResponse.json({error:"No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header."},{status:401});const C=c.allowClientApiKey&&t.headers.get("x-agent-provider")||void 0,m=c.allowClientApiKey&&t.headers.get("x-agent-model")||void 0,S=c.allowClientApiKey&&t.headers.get("x-agent-provider-endpoint")||void 0,j=await o(t,e),H=c.buildSystemContext?.(j),R=new TextEncoder,b=new ReadableStream({async start(E){try{const x=l({message:u,sessionId:p,history:w,semanticLayer:d,securityContext:j,agentConfig:c,apiKey:N,systemContext:H,providerOverride:C,modelOverride:m,baseURLOverride:S});for await(const g of x){const P=`data: ${JSON.stringify(g)}
|
|
6
6
|
|
|
7
7
|
`;E.enqueue(R.encode(P))}}catch(x){const g={type:"error",data:{message:x instanceof Error?x.message:"Stream failed"}};E.enqueue(R.encode(`data: ${JSON.stringify(g)}
|
|
8
8
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { NextResponse as r } from "next/server";
|
|
2
|
-
import { e as T, s as A, v as D, b as R, a as _, n as Q, p as V, w as I, d as J, i as M, M as k, c as K, S as $ } from "../mcp-transport-
|
|
2
|
+
import { e as T, s as A, v as D, b as R, a as _, n as Q, p as V, w as I, d as J, i as M, M as k, c as K, S as $ } from "../mcp-transport-B6ZudTSk.js";
|
|
3
3
|
import { formatErrorResponse as i, formatCubeResponse as z, formatMetaResponse as U, formatSqlResponse as G, handleDryRun as B, handleBatchRequest as F, handleDiscover as X, handleSuggest as q, handleValidate as W, handleLoad as Y } from "../utils.js";
|
|
4
4
|
function E(n) {
|
|
5
5
|
const { cubes: a, drizzle: s, schema: c, engineType: d, cache: o } = n;
|
|
@@ -519,7 +519,7 @@ function oe(n) {
|
|
|
519
519
|
{ error: "Method not allowed - use POST" },
|
|
520
520
|
{ status: 405 }
|
|
521
521
|
);
|
|
522
|
-
const { handleAgentChat: l } = await import("../handler-
|
|
522
|
+
const { handleAgentChat: l } = await import("../handler-BV2_dul8.js"), y = await t.json(), { message: u, sessionId: f, history: C } = y;
|
|
523
523
|
if (!u || typeof u != "string")
|
|
524
524
|
return r.json(
|
|
525
525
|
{ error: "message is required and must be a string" },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class c{client;apiKey;baseURL;initialized=!1;constructor(e,t){this.apiKey=e,this.baseURL=t?.baseURL}async ensureClient(){if(this.initialized)return;let e;try{const s=await Promise.resolve().then(()=>require("./index-
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class c{client;apiKey;baseURL;initialized=!1;constructor(e,t){this.apiKey=e,this.baseURL=t?.baseURL}async ensureClient(){if(this.initialized)return;let e;try{const s=await Promise.resolve().then(()=>require("./index-ht4NPca9.cjs"));e=s.default||s.OpenAI||s}catch{throw new Error("openai is required for the OpenAI provider. Install it with: npm install openai")}const t={apiKey:this.apiKey};this.baseURL&&(t.baseURL=this.baseURL),this.client=new e(t),this.initialized=!0}async createStream(e){await this.ensureClient();const{messages:t}=this.formatMessages(e.messages,e.system);return this.client.chat.completions.create({model:e.model,max_completion_tokens:e.maxTokens,tools:this.formatTools(e.tools),messages:t,stream:!0,stream_options:{include_usage:!0}})}async*parseStreamEvents(e){const t=new Map;for await(const s of e){const n=s;n.usage&&(yield{type:"message_meta",inputTokens:n.usage.prompt_tokens,outputTokens:n.usage.completion_tokens,stopReason:""});const l=n.choices?.[0];if(!l)continue;const r=l.delta;if(r){if(r.content&&(yield{type:"text_delta",text:r.content}),r.tool_calls)for(const i of r.tool_calls){const a=i.index??0;if(i.id&&(t.set(a,{id:i.id,name:i.function?.name||"",arguments:""}),yield{type:"tool_use_start",id:i.id,name:i.function?.name||""}),i.function?.name&&t.has(a)){const o=t.get(a);o.name||(o.name=i.function.name)}if(i.function?.arguments){const o=t.get(a);o&&(o.arguments+=i.function.arguments,yield{type:"tool_input_delta",json:i.function.arguments})}}if(l.finish_reason){for(const[i,a]of t){let o={};try{a.arguments&&(o=JSON.parse(a.arguments))}catch{}yield{type:"tool_use_end",id:a.id,input:o},t.delete(i)}yield{type:"message_meta",stopReason:l.finish_reason}}}}}formatTools(e){return e.map(t=>({type:"function",function:{name:t.name,description:t.description,parameters:t.parameters}}))}formatMessages(e,t){const s=[{role:"system",content:t}];for(const n of e)if(n.role==="user")s.push({role:"user",content:typeof n.content=="string"?n.content:JSON.stringify(n.content)});else if(n.role==="assistant")if(typeof n.content=="string")s.push({role:"assistant",content:n.content});else{const l=n.content,r=l.filter(o=>o.type==="text").map(o=>o.text).join(""),i=l.filter(o=>o.type==="tool_use").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.input||{})}})),a={role:"assistant"};r&&(a.content=r),i.length>0&&(a.tool_calls=i),s.push(a)}else n.role==="tool"?s.push(n):n.role==="tool_result"&&s.push({role:"user",content:typeof n.content=="string"?n.content:JSON.stringify(n.content)});return{messages:s}}formatToolResults(e){return e.map(t=>({role:"tool",tool_call_id:t.toolUseId,content:t.content}))}shouldContinue(e){return e==="tool_calls"}formatError(e){if(!e||!(e instanceof Error))return"Something went wrong. Please try again.";const t=e.message||"",s=e;return s.status===429?"Too many requests. Please wait a moment and try again.":s.status===401?"Authentication failed. Please check your API key configuration.":s.status===503||s.status===502?"The AI service is temporarily unavailable. Please try again in a moment.":s.status===400?"There was a problem with the request. Please try again.":t.startsWith("{")||t.startsWith("Error: {")?"The AI service encountered an error. Please try again.":t}}exports.OpenAIProvider=c;
|