drizzle-cube 0.6.3 → 0.6.4
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/compiler-DyyBaLry.cjs +166 -0
- package/dist/adapters/{compiler-LKTN9PTt.js → compiler-lG6eNsoI.js} +214 -210
- package/dist/adapters/express/index.cjs +1 -1
- package/dist/adapters/express/index.js +1 -1
- package/dist/adapters/fastify/index.cjs +1 -1
- package/dist/adapters/fastify/index.js +1 -1
- package/dist/adapters/hono/index.cjs +1 -1
- package/dist/adapters/hono/index.js +1 -1
- package/dist/adapters/nextjs/index.cjs +1 -1
- package/dist/adapters/nextjs/index.d.ts +10 -0
- package/dist/adapters/nextjs/index.js +13 -9
- package/dist/cjs/adapters/nextjs/index.d.ts +10 -0
- package/dist/cjs/client/components/AnalysisBuilder/utils/filterUtils.d.ts +4 -10
- package/dist/cjs/client/components/shared/utils.d.ts +2 -1
- package/dist/cjs/client/shared/filters/filterOperations.d.ts +95 -0
- package/dist/cjs/client/shared/filters/index.d.ts +10 -0
- package/dist/cjs/client/shared/filters/operators.d.ts +23 -0
- package/dist/cjs/client/shared/index.d.ts +3 -2
- package/dist/cjs/client/shared/types.d.ts +3 -10
- package/dist/cjs/client/shared/utils.d.ts +1 -59
- package/dist/cjs/client/utils/filterUtils.d.ts +2 -9
- package/dist/cjs/server/logical-plan/logical-plan-builder.d.ts +0 -5
- package/dist/cjs/server/logical-plan/schema-builder.d.ts +19 -0
- package/dist/client/chunks/{DashboardEditModal-CWurUU2B.js → DashboardEditModal-Cs1ig1_V.js} +1520 -1119
- package/dist/client/chunks/DashboardEditModal-Cs1ig1_V.js.map +1 -0
- package/dist/client/chunks/{analysis-builder-Uj_Fxv0-.js → analysis-builder-B64yaeDe.js} +73 -73
- package/dist/client/chunks/{analysis-builder-Uj_Fxv0-.js.map → analysis-builder-B64yaeDe.js.map} +1 -1
- package/dist/client/chunks/{analysis-builder-shared-AdAYIfj_.js → analysis-builder-shared-CD0n2Nb8.js} +948 -1023
- package/dist/client/chunks/analysis-builder-shared-CD0n2Nb8.js.map +1 -0
- package/dist/client/chunks/{useDirtyStateTracking-BY_IIG1n.js → useDirtyStateTracking-BT6zqCFl.js} +249 -590
- package/dist/client/chunks/useDirtyStateTracking-BT6zqCFl.js.map +1 -0
- package/dist/client/chunks/{useExplainAI-PjMBmj2p.js → useExplainAI-Dq_meKNN.js} +2 -2
- package/dist/client/chunks/{useExplainAI-PjMBmj2p.js.map → useExplainAI-Dq_meKNN.js.map} +1 -1
- package/dist/client/components/AnalysisBuilder/utils/filterUtils.d.ts +4 -10
- package/dist/client/components/shared/utils.d.ts +2 -1
- package/dist/client/components.js +2 -2
- package/dist/client/hooks.js +2 -2
- package/dist/client/index.js +13 -13
- package/dist/client/index.js.map +1 -1
- package/dist/client/shared/filters/filterOperations.d.ts +95 -0
- package/dist/client/shared/filters/index.d.ts +10 -0
- package/dist/client/shared/filters/operators.d.ts +23 -0
- package/dist/client/shared/index.d.ts +3 -2
- package/dist/client/shared/types.d.ts +3 -10
- package/dist/client/shared/utils.d.ts +1 -59
- package/dist/client/utils/filterUtils.d.ts +2 -9
- package/dist/client-bundle-stats.html +1 -1
- package/dist/server/index.cjs +33 -33
- package/dist/server/index.js +1272 -1268
- package/dist/server/logical-plan/logical-plan-builder.d.ts +0 -5
- package/dist/server/logical-plan/schema-builder.d.ts +19 -0
- package/package.json +3 -3
- package/dist/adapters/compiler-ChGO4ZLU.cjs +0 -166
- package/dist/client/chunks/DashboardEditModal-CWurUU2B.js.map +0 -1
- package/dist/client/chunks/analysis-builder-shared-AdAYIfj_.js.map +0 -1
- package/dist/client/chunks/useDirtyStateTracking-BY_IIG1n.js.map +0 -1
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils-_whV4fXL.cjs"),t=require("../compiler-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils-_whV4fXL.cjs"),t=require("../compiler-DyyBaLry.cjs"),n=require("../mcp-transport-CNIPoe1i.cjs"),r=require("../core-F1pCQPde.cjs");let i=require("express");i=e.k(i,1);let a=require("cors");a=e.k(a,1);function o(e,t){return{getHeader:t=>e.get(t),getBody:async()=>e.body,getQueryParam:t=>e.query[t],send:(e,n)=>t.status(e).json(n),setHeader:(e,n)=>{t.setHeader(e,n)},sendEmpty:e=>t.status(e).end(),sendSse:(e,n)=>(t.status(e),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(n),t.end())}}function s(s){let{cubes:c,drizzle:l,schema:u,extractSecurityContext:d,engineType:f,cors:p,basePath:m=`/cubejs-api/v1`,jsonLimit:h=`10mb`,cache:g,mcp:_={enabled:!0},agent:v}=s;if(!c||c.length===0)throw Error(`At least one cube must be provided in the cubes array`);let y=(0,i.Router)();if(p){let e={...p,allowedHeaders:r.i(p.allowedHeaders)};y.use((0,a.default)(e))}y.use(i.default.json({limit:h})),y.use(i.default.urlencoded({extended:!0,limit:h}));let b=new t.t({drizzle:l,schema:u,engineType:f,cache:g,rlsSetup:s.rlsSetup});c.forEach(e=>{b.registerCube(e)});let x=r.t({semanticLayer:b,onError:e=>console.error(`Query execution error:`,e),mcp:_}),S=(e,t)=>()=>d(e,t);if(y.post(`${m}/load`,async(e,t)=>{await x.handleLoadPost(o(e,t),S(e,t))}),y.get(`${m}/load`,async(e,t)=>{await x.handleLoadGet(o(e,t),S(e,t))}),y.post(`${m}/batch`,async(e,t)=>{await x.handleBatchPost(o(e,t),S(e,t))}),y.get(`${m}/meta`,(e,t)=>{x.handleMetaGet(o(e,t))}),y.post(`${m}/sql`,async(e,t)=>{await x.handleSqlPost(o(e,t),S(e,t))}),y.get(`${m}/sql`,async(e,t)=>{await x.handleSqlGet(o(e,t),S(e,t))}),y.post(`${m}/dry-run`,async(e,t)=>{await x.handleDryRunPost(o(e,t),S(e,t))}),y.get(`${m}/dry-run`,async(e,t)=>{await x.handleDryRunGet(o(e,t),S(e,t))}),y.post(`${m}/explain`,async(e,t)=>{await x.handleExplainPost(o(e,t),S(e,t))}),v&&y.post(`${m}/agent/chat`,async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require("../handler-DRZb2ip6.cjs")),{message:i,sessionId:a,history:o}=e.body;if(!i||typeof i!=`string`)return t.status(400).json({error:`message is required and must be a string`});let s=(v.apiKey||``).trim();if(v.allowClientApiKey){let t=e.headers[`x-agent-api-key`];t&&(s=t.trim())}if(!s)return t.status(401).json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`});let c=v.allowClientApiKey?e.headers[`x-agent-provider`]:void 0,l=v.allowClientApiKey?e.headers[`x-agent-model`]:void 0,u=v.allowClientApiKey?e.headers[`x-agent-provider-endpoint`]:void 0,f=r.r(await d(e,t),t=>e.get(t)),p=v.buildSystemContext?.(f);t.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:i,sessionId:a,history:o,semanticLayer:b,securityContext:f,agentConfig:v,apiKey:s,systemContext:p,providerOverride:c,modelOverride:l,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`})}}),_.enabled!==!1){let e=_.basePath??`/mcp`;y.post(`${e}`,async(e,t)=>{await x.handleMcpPost(o(e,t),S(e,t))}),y.get(`${e}`,async(e,t)=>{if(_.resourceMetadataUrl&&!n.u(e.headers.authorization))return t.setHeader(`WWW-Authenticate`,n.c(_.resourceMetadataUrl)),t.status(401).json({error:`Bearer token required`});let r=n._();t.status(200),t.setHeader(`Content-Type`,`text/event-stream`),t.setHeader(`Cache-Control`,`no-cache`),t.setHeader(`Connection`,`keep-alive`),t.write(n.b({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)})}),y.delete(`${e}`,(e,t)=>_.resourceMetadataUrl&&!n.u(e.headers.authorization)?(t.setHeader(`WWW-Authenticate`,n.c(_.resourceMetadataUrl)),t.status(401).json({error:`Bearer token required`})):t.status(405).json({error:`Session termination not supported`}))}return y.use((t,n,r,i)=>{console.error(`Express adapter error:`,t),r.headersSent||r.status(500).json(e.i(t,500))}),y}function c(e,t){let n=s(t);return e.use(`/`,n),e}function l(e){return c((0,i.default)(),e)}exports.createCubeApp=l,exports.createCubeRouter=s,exports.mountCubeRoutes=c;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as e } from "../utils-BPWZsX7k.js";
|
|
2
|
-
import { t } from "../compiler-
|
|
2
|
+
import { t } from "../compiler-lG6eNsoI.js";
|
|
3
3
|
import { _ as n, b as r, c as i, u as a } from "../mcp-transport-Bw_zqky2.js";
|
|
4
4
|
import { i as o, r as s, t as c } from "../core-Bbchr0ui.js";
|
|
5
5
|
import l, { Router as u } from "express";
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils-_whV4fXL.cjs"),t=require("../compiler-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils-_whV4fXL.cjs"),t=require("../compiler-DyyBaLry.cjs"),n=require("../mcp-transport-CNIPoe1i.cjs"),r=require("../core-F1pCQPde.cjs");function i(e,t){let n=e.headers[t.toLowerCase()];return Array.isArray(n)?n[0]:n}function a(e,t){return{getHeader:t=>i(e,t),getBody:async()=>e.body,getQueryParam:t=>e.query?.[t],send:(e,n)=>t.status(e).send(n),setHeader:(e,n)=>{t.header(e,n)},sendEmpty:e=>t.status(e).send(),sendSse:(e,n)=>(t.header(`Content-Type`,`text/event-stream`),t.header(`Cache-Control`,`no-cache`),t.header(`Connection`,`keep-alive`),t.status(e).send(n))}}var o=function(o,s,c){let{cubes:l,drizzle:u,schema:d,extractSecurityContext:f,engineType:p,cors:m,basePath:h=`/cubejs-api/v1`,bodyLimit:g=10485760,cache:_,mcp:v={enabled:!0},agent:y}=s;if(!l||l.length===0)return c(Error(`At least one cube must be provided in the cubes array`));if(m){let e={...m,allowedHeaders:r.i(m.allowedHeaders)};o.register(import(`@fastify/cors`),e)}o.addHook(`onRequest`,async(e,t)=>{e.method===`POST`&&(e.body=void 0)});let b=new t.t({drizzle:u,schema:d,engineType:p,cache:_,rlsSetup:s.rlsSetup});l.forEach(e=>{b.registerCube(e)});let x=r.t({semanticLayer:b,onError:e=>o.log.error(e,`Query execution error`),mcp:v}),S=e=>()=>f(e),C={bodyLimit:g,schema:{body:{type:`object`,additionalProperties:!0}}},w={schema:{querystring:{type:`object`,properties:{query:{type:`string`}},required:[`query`]}}};if(o.post(`${h}/load`,C,(e,t)=>x.handleLoadPost(a(e,t),S(e))),o.get(`${h}/load`,w,(e,t)=>x.handleLoadGet(a(e,t),S(e))),o.post(`${h}/batch`,{bodyLimit:g,schema:{body:{type:`object`,required:[`queries`],properties:{queries:{type:`array`,items:{type:`object`}}}}}},(e,t)=>x.handleBatchPost(a(e,t),S(e))),o.get(`${h}/meta`,(e,t)=>x.handleMetaGet(a(e,t))),o.post(`${h}/sql`,C,(e,t)=>x.handleSqlPost(a(e,t),S(e))),o.get(`${h}/sql`,w,(e,t)=>x.handleSqlGet(a(e,t),S(e))),o.post(`${h}/dry-run`,C,(e,t)=>x.handleDryRunPost(a(e,t),S(e))),o.get(`${h}/dry-run`,w,(e,t)=>x.handleDryRunGet(a(e,t),S(e))),o.post(`${h}/explain`,C,(e,t)=>x.handleExplainPost(a(e,t),S(e))),y&&o.post(`${h}/agent/chat`,{bodyLimit:g,schema:{body:{type:`object`,additionalProperties:!0}}},async(e,t)=>{try{let{handleAgentChat:n}=await Promise.resolve().then(()=>require("../handler-DRZb2ip6.cjs")),{message:a,sessionId:o,history:s}=e.body;if(!a||typeof a!=`string`)return t.status(400).send({error:`message is required and must be a string`});let c=(y.apiKey||``).trim();if(y.allowClientApiKey){let t=i(e,`x-agent-api-key`);t&&(c=t.trim())}if(!c)return t.status(401).send({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`});let l=y.allowClientApiKey?i(e,`x-agent-provider`):void 0,u=y.allowClientApiKey?i(e,`x-agent-model`):void 0,d=y.allowClientApiKey?i(e,`x-agent-provider-endpoint`):void 0,p=r.r(await f(e),t=>i(e,t)),m=y.buildSystemContext?.(p);t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});try{let e=n({message:a,sessionId:o,history:s,semanticLayer:b,securityContext:p,agentConfig:y,apiKey:c,systemContext:m,providerOverride:l,modelOverride:u,baseURLOverride:d});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`})}}),v.enabled!==!1){let e=v.basePath??`/mcp`;o.post(`${e}`,{bodyLimit:g,schema:{body:{type:`object`,additionalProperties:!0}}},(e,t)=>x.handleMcpPost(a(e,t),S(e))),o.get(`${e}`,async(e,t)=>{if(v.resourceMetadataUrl&&!n.u(e.headers.authorization))return t.header(`WWW-Authenticate`,n.c(v.resourceMetadataUrl)),t.status(401).send({error:`Bearer token required`});let r=n._();t.raw.writeHead(200,{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}),t.raw.write(n.b({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)})}),o.delete(`${e}`,async(e,t)=>v.resourceMetadataUrl&&!n.u(e.headers.authorization)?(t.header(`WWW-Authenticate`,n.c(v.resourceMetadataUrl)),t.status(401).send({error:`Bearer token required`})):t.status(405).send({error:`Session termination not supported`}))}o.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))),c()};async function s(e,t){await e.register(o,t)}function c(e){let t=require("fastify")({logger:!0});return t.register(o,e),t}exports.createCubeApp=c,exports.cubePlugin=o,exports.registerCubeRoutes=s;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as e, k as t } from "../utils-BPWZsX7k.js";
|
|
2
|
-
import { t as n } from "../compiler-
|
|
2
|
+
import { t as n } from "../compiler-lG6eNsoI.js";
|
|
3
3
|
import { _ as r, b as i, c as a, u as o } from "../mcp-transport-Bw_zqky2.js";
|
|
4
4
|
import { i as s, r as c, t as l } from "../core-Bbchr0ui.js";
|
|
5
5
|
//#region src/adapters/fastify/index.ts
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../compiler-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../compiler-DyyBaLry.cjs"),t=require("../mcp-transport-CNIPoe1i.cjs"),n=require("../core-F1pCQPde.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===`*`?()=>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!==`*`&&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!==`*`&&e.header(`Vary`,`Origin`,{append:!0})}};function a(e,t){let n=(t.apiKey||``).trim();if(t.allowClientApiKey){let t=e.req.header(`x-agent-api-key`);t&&(n=t.trim())}return n}function o(e,t){return t.allowClientApiKey?{providerOverride:e.req.header(`x-agent-provider`),modelOverride:e.req.header(`x-agent-model`),baseURLOverride:e.req.header(`x-agent-provider-endpoint`)}:{}}function s(e){let t=new TextEncoder,n=new ReadableStream({async start(n){try{for await(let r of e)n.enqueue(t.encode(`data: ${JSON.stringify(r)}\n\n`))}catch(e){let r={type:`error`,data:{message:e instanceof Error?e.message:`Stream failed`}};n.enqueue(t.encode(`data: ${JSON.stringify(r)}\n\n`))}finally{n.close()}}});return new Response(n,{status:200,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`}})}async function c(e,t,n,r){try{let{handleAgentChat:i}=await Promise.resolve().then(()=>require("../handler-DRZb2ip6.cjs")),{message:c,sessionId:l,history:u}=await e.req.json();if(!c||typeof c!=`string`)return e.json({error:`message is required and must be a string`},400);let d=a(e,t);if(!d)return e.json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`},401);let{providerOverride:f,modelOverride:p,baseURLOverride:m}=o(e,t),h=await r(e),g=t.buildSystemContext?.(h);return s(i({message:c,sessionId:l,history:u,semanticLayer:n,securityContext:h,agentConfig:t,apiKey:d,systemContext:g,providerOverride:f,modelOverride:p,baseURLOverride:m}))}catch(t){return console.error(`Agent chat error:`,t),e.json({error:t instanceof Error?t.message:`Agent chat failed`},500)}}function l(e){return{getHeader:t=>e.req.header(t),getBody:async()=>{try{return await e.req.json()}catch{return null}},getQueryParam:t=>e.req.query(t),send:(t,n)=>e.json(n,t),setHeader:(t,n)=>{e.header(t,n)},sendEmpty:t=>e.body(null,t),sendSse:(t,n)=>(e.header(`Content-Type`,`text/event-stream`),e.header(`Cache-Control`,`no-cache`),e.header(`Connection`,`keep-alive`),e.body(n,t))}}function u(a){let{cubes:o,drizzle:s,schema:u,extractSecurityContext:d,engineType:f,cors:p,basePath:m=`/cubejs-api/v1`,cache:h,mcp:g={enabled:!0},agent:_}=a;if(!a.semanticLayer&&(!o||o.length===0))throw Error(`Either semanticLayer or a non-empty cubes array must be provided`);let v=new r.Hono;if(p){let e={...p,allowHeaders:n.i(p.allowHeaders)};v.use(`/*`,i(e))}let y=a.semanticLayer??new e.t({drizzle:s,schema:u,engineType:f,cache:h,rlsSetup:a.rlsSetup});!a.semanticLayer&&o&&o.forEach(e=>{y.registerCube(e)});let b=n.t({semanticLayer:y,onError:e=>console.error(`Query execution error:`,e),mcp:g}),x=e=>()=>d(e);if(v.post(`${m}/load`,e=>b.handleLoadPost(l(e),x(e))),v.get(`${m}/load`,e=>b.handleLoadGet(l(e),x(e))),v.post(`${m}/batch`,e=>b.handleBatchPost(l(e),x(e))),v.get(`${m}/meta`,e=>b.handleMetaGet(l(e))),v.post(`${m}/sql`,e=>b.handleSqlPost(l(e),x(e))),v.get(`${m}/sql`,e=>b.handleSqlGet(l(e),x(e))),v.post(`${m}/dry-run`,e=>b.handleDryRunPost(l(e),x(e))),v.get(`${m}/dry-run`,e=>b.handleDryRunGet(l(e),x(e))),v.post(`${m}/explain`,e=>b.handleExplainPost(l(e),x(e))),_&&v.post(`${m}/agent/chat`,e=>c(e,_,y,e=>Promise.resolve(d(e)).then(t=>n.r(t,t=>e.req.header(t))))),g.enabled!==!1){let e=g.basePath??`/mcp`;v.post(`${e}`,e=>b.handleMcpPost(l(e),x(e))),v.delete(`${e}`,e=>g.resourceMetadataUrl&&!t.u(e.req.header(`authorization`))?(e.header(`WWW-Authenticate`,t.c(g.resourceMetadataUrl)),e.json({error:`Bearer token required`},401)):e.json({error:`Session termination not supported`},405)),v.get(`${e}`,e=>{if(g.resourceMetadataUrl&&!t.u(e.req.header(`authorization`)))return e.header(`WWW-Authenticate`,t.c(g.resourceMetadataUrl)),e.json({error:`Bearer token required`},401);let n=new TextEncoder,r=t._(),i,a=new ReadableStream({start(e){e.enqueue(n.encode(t.b({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},r,15e3))),i=setInterval(()=>{e.enqueue(n.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 v}function d(e,t){let n=u(t);return e.route(`/`,n),e}function f(e){return d(new r.Hono,e)}exports.createCubeApp=f,exports.createCubeRoutes=u,exports.mountCubeRoutes=d;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as e } from "../compiler-
|
|
1
|
+
import { t as e } from "../compiler-lG6eNsoI.js";
|
|
2
2
|
import { _ as t, b as n, c as r, u as i } from "../mcp-transport-Bw_zqky2.js";
|
|
3
3
|
import { i as a, r as o, t as s } from "../core-Bbchr0ui.js";
|
|
4
4
|
import { Hono as c } from "hono";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils-_whV4fXL.cjs"),t=require("../compiler-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../utils-_whV4fXL.cjs"),t=require("../compiler-DyyBaLry.cjs"),n=require("../mcp-transport-CNIPoe1i.cjs"),r=require("../core-F1pCQPde.cjs");let i=require("next/server");function a(e,t){let r=new TextEncoder,a=n._(),o=new ReadableStream({start(e){e.enqueue(r.encode(n.b({jsonrpc:`2.0`,method:`mcp/ready`,params:{protocol:`streamable-http`}},a,15e3)))}}),s=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});return t(e,s),new i.NextResponse(o,{status:200,headers:s})}function o(e){if(e.semanticLayer)return e.semanticLayer;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 s(e){return{extractSecurityContext:async(t,n)=>r.o(await e.extractSecurityContext(t,n),r.a(e=>t.headers.get(e))),cors:e.cors?{...e.cors,allowedHeaders:r.i(e.cors.allowedHeaders)}:void 0}}function c(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 l(e){let t=r.t({semanticLayer:o(e),onError:e=>{process.env.NODE_ENV!==`test`&&console.error(`Next.js handler error:`,e)},mcp:e.mcp}),n=e.cors?{...e.cors,allowedHeaders:r.i(e.cors.allowedHeaders)}:void 0;return{httpHandler:t,corsHeaders:e=>n?c(e,n):{},baseContext:(t,n)=>()=>e.extractSecurityContext(t,n)}}function u(e,t){let n={};return{getHeader:t=>e.headers.get(t)??void 0,getBody:async()=>{try{return await e.json()}catch{return null}},getQueryParam:t=>e.nextUrl.searchParams.get(t)??void 0,send:(e,r)=>i.NextResponse.json(r,{status:e,headers:{...t,...n}}),setHeader:(e,t)=>{n[e]=t},sendEmpty:e=>new i.NextResponse(null,{status:e,headers:{...t,...n}}),sendSse:(e,r)=>new i.NextResponse(r,{status:e,headers:{"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`,...t,...n}})}}function d(e){return async function(t){let n=c(t,{...e,allowedHeaders:r.i(e.allowedHeaders)});return new Response(null,{status:200,headers:n})}}function f(t){let{httpHandler:n,corsHeaders:r,baseContext:a}=l(t);return async function(t,o){let s=u(t,r(t));return t.method===`POST`?n.handleLoadPost(s,a(t,o)):t.method===`GET`?n.handleLoadGet(s,a(t,o)):i.NextResponse.json(e.i(`Method not allowed`,405),{status:405})}}function p(e){let{httpHandler:t,corsHeaders:n}=l(e);return async function(e,r){return t.handleMetaGet(u(e,n(e)))}}function m(t){let{httpHandler:n,corsHeaders:r,baseContext:a}=l(t);return async function(t,o){let s=u(t,r(t));return t.method===`POST`?n.handleSqlPost(s,a(t,o)):t.method===`GET`?n.handleSqlGet(s,a(t,o)):i.NextResponse.json(e.i(`Method not allowed`,405),{status:405})}}function h(e){let{httpHandler:t,corsHeaders:n,baseContext:r}=l(e);return async function(e,a){let o=u(e,n(e));return e.method===`POST`?t.handleDryRunPost(o,r(e,a)):e.method===`GET`?t.handleDryRunGet(o,r(e,a)):i.NextResponse.json({error:`Method not allowed`,valid:!1},{status:405})}}function g(t){let{httpHandler:n,corsHeaders:r,baseContext:a}=l(t);return async function(t,o){return t.method===`POST`?n.handleBatchPost(u(t,r(t)),a(t,o)):i.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405})}}function _(e){let{httpHandler:t,corsHeaders:n,baseContext:r}=l(e);return async function(e,a){return e.method===`POST`?t.handleExplainPost(u(e,n(e)),r(e,a)):i.NextResponse.json({error:`Method not allowed`},{status:405})}}function v(t){let{cors:n}=s(t),r=o(t);return async function(t,a){try{if(t.method!==`POST`)return i.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let a=await e.p(r,await t.json());return i.NextResponse.json(a,{headers:n?c(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js discover handler error:`,t),i.NextResponse.json(e.i(t instanceof Error?t.message:`Discovery failed`,500),{status:500})}}}function y(t){let{cors:n}=s(t),r=o(t);return async function(t,a){try{if(t.method!==`POST`)return i.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let a=await t.json();if(!a.naturalLanguage)return i.NextResponse.json(e.i(`naturalLanguage field is required`,400),{status:400});let o=await e.d(r,a);return i.NextResponse.json(o,{headers:n?c(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js suggest handler error:`,t),i.NextResponse.json(e.i(t instanceof Error?t.message:`Query suggestion failed`,500),{status:500})}}}function b(t){let{cors:n}=s(t),r=o(t);return async function(t,a){try{if(t.method!==`POST`)return i.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let a=await t.json();if(!a.query)return i.NextResponse.json(e.i(`query field is required`,400),{status:400});let o=await e.f(r,a);return i.NextResponse.json(o,{headers:n?c(t,n):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js validate handler error:`,t),i.NextResponse.json(e.i(t instanceof Error?t.message:`Query validation failed`,500),{status:500})}}}function x(t){let{extractSecurityContext:n,cors:r}=s(t),a=o(t);return async function(t,o){try{if(t.method!==`POST`)return i.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405});let s=await t.json();if(!s.query)return i.NextResponse.json(e.i(`query field is required`,400),{status:400});let l=await e.m(a,await n(t,o),s);return i.NextResponse.json(l,{headers:r?c(t,r):{}})}catch(t){return process.env.NODE_ENV!==`test`&&console.error(`Next.js MCP load handler error:`,t),i.NextResponse.json(e.i(t instanceof Error?t.message:`Query execution failed`,500),{status:500})}}}function S(t){let{httpHandler:r,corsHeaders:o,baseContext:s}=l(t),{mcp:c={enabled:!0}}=t,d=(e,t)=>{Object.entries(o(e)).forEach(([e,n])=>t.set(e,n))};return async function(t,l){return c.resourceMetadataUrl&&!n.u(t.headers.get(`authorization`))?i.NextResponse.json({error:`Bearer token required`},{status:401,headers:{"WWW-Authenticate":n.c(c.resourceMetadataUrl)}}):t.method===`DELETE`?i.NextResponse.json({error:`Session termination not supported`},{status:405}):t.method===`GET`?a(t,d):t.method===`POST`?r.handleMcpPost(u(t,o(t)),s(t,l)):i.NextResponse.json(e.i(`Method not allowed - use POST`,405),{status:405})}}function C(e){let{cors:t}=s(e),{agent:n}=e;if(!n)throw Error(`agent config is required for createAgentChatHandler`);let a=o(e);return async function(o,s){try{if(o.method!==`POST`)return i.NextResponse.json({error:`Method not allowed - use POST`},{status:405});let{handleAgentChat:l}=await Promise.resolve().then(()=>require("../handler-DRZb2ip6.cjs")),{message:u,sessionId:d,history:f}=await o.json();if(!u||typeof u!=`string`)return i.NextResponse.json({error:`message is required and must be a string`},{status:400});let p=(n.apiKey||``).trim();if(n.allowClientApiKey){let e=o.headers.get(`x-agent-api-key`);e&&(p=e.trim())}if(!p)return i.NextResponse.json({error:`No API key configured. Set agent.apiKey in server config or send X-Agent-Api-Key header.`},{status:401});let m=n.allowClientApiKey&&o.headers.get(`x-agent-provider`)||void 0,h=n.allowClientApiKey&&o.headers.get(`x-agent-model`)||void 0,g=n.allowClientApiKey&&o.headers.get(`x-agent-provider-endpoint`)||void 0,_=r.r(await e.extractSecurityContext(o,s),e=>o.headers.get(e)??void 0),v=n.buildSystemContext?.(_),y=new TextEncoder,b=new ReadableStream({async start(e){try{let t=l({message:u,sessionId:d,history:f,semanticLayer:a,securityContext:_,agentConfig:n,apiKey:p,systemContext:v,providerOverride:m,modelOverride:h,baseURLOverride:g});for await(let n of t){let t=`data: ${JSON.stringify(n)}\n\n`;e.enqueue(y.encode(t))}}catch(t){let n={type:`error`,data:{message:t instanceof Error?t.message:`Stream failed`}};e.enqueue(y.encode(`data: ${JSON.stringify(n)}\n\n`))}finally{e.close()}}}),x=new Headers({"Content-Type":`text/event-stream`,"Cache-Control":`no-cache`,Connection:`keep-alive`});if(t){let e=c(o,t);Object.entries(e).forEach(([e,t])=>x.set(e,t))}return new Response(b,{status:200,headers:x})}catch(e){return process.env.NODE_ENV!==`test`&&console.error(`Next.js agent chat handler error:`,e),i.NextResponse.json({error:e instanceof Error?e.message:`Agent chat failed`},{status:500})}}}function w(e){let{mcp:t={enabled:!0}}=e,n=o(e),r={...e,semanticLayer:n},i={load:f(r),meta:p(r),sql:m(r),dryRun:h(r),batch:g(r),explain:_(r)};return t.enabled!==!1&&(i.mcpRpc=S(r)),e.agent&&(i.agentChat=C(r)),i}exports.createAgentChatHandler=C,exports.createBatchHandler=g,exports.createCubeHandlers=w,exports.createDiscoverHandler=v,exports.createDryRunHandler=h,exports.createExplainHandler=_,exports.createLoadHandler=f,exports.createMcpLoadHandler=x,exports.createMcpRpcHandler=S,exports.createMetaHandler=p,exports.createOptionsHandler=d,exports.createSqlHandler=m,exports.createSuggestHandler=y,exports.createValidateHandler=b;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextRequest } from 'next/server';
|
|
2
2
|
import { SemanticQuery, SecurityContext, DatabaseExecutor, DrizzleDatabase, Cube, CacheConfig, RLSSetupFn } from '../../server/index.js';
|
|
3
3
|
import { AgentConfig } from '../../server/agent/types.js';
|
|
4
|
+
import { SemanticLayerCompiler } from '../../server/compiler.js';
|
|
4
5
|
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
|
|
5
6
|
import { MySql2Database } from 'drizzle-orm/mysql2';
|
|
6
7
|
import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
|
|
@@ -100,6 +101,15 @@ export interface NextAdapterOptions {
|
|
|
100
101
|
* to configure RLS (e.g., set JWT claims and switch Postgres roles), then runs the query.
|
|
101
102
|
*/
|
|
102
103
|
rlsSetup?: RLSSetupFn;
|
|
104
|
+
/**
|
|
105
|
+
* Pre-built semantic layer to reuse across handlers.
|
|
106
|
+
* When provided, the adapter reuses this compiler instead of constructing a
|
|
107
|
+
* new one (and skips cube registration — register cubes on it yourself).
|
|
108
|
+
* `createCubeHandlers` sets this internally so every handler it returns shares
|
|
109
|
+
* one compiler, keeping metadata/result caches consistent. Mirrors the Hono
|
|
110
|
+
* adapter's `semanticLayer` option.
|
|
111
|
+
*/
|
|
112
|
+
semanticLayer?: SemanticLayerCompiler;
|
|
103
113
|
}
|
|
104
114
|
export interface RouteContext {
|
|
105
115
|
params?: Record<string, string | string[]>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as e, f as t, i as n, m as r, p as i } from "../utils-BPWZsX7k.js";
|
|
2
|
-
import { t as a } from "../compiler-
|
|
2
|
+
import { t as a } from "../compiler-lG6eNsoI.js";
|
|
3
3
|
import { _ as o, b as s, c, u as l } from "../mcp-transport-Bw_zqky2.js";
|
|
4
4
|
import { a as u, i as d, o as f, r as p, t as m } from "../core-Bbchr0ui.js";
|
|
5
5
|
import { NextResponse as h } from "next/server";
|
|
@@ -24,6 +24,7 @@ function g(e, t) {
|
|
|
24
24
|
//#endregion
|
|
25
25
|
//#region src/adapters/nextjs/index.ts
|
|
26
26
|
function _(e) {
|
|
27
|
+
if (e.semanticLayer) return e.semanticLayer;
|
|
27
28
|
let { cubes: t, drizzle: n, schema: r, engineType: i, cache: o, rlsSetup: s } = e;
|
|
28
29
|
if (!t || t.length === 0) throw Error("At least one cube must be provided in the cubes array");
|
|
29
30
|
let c = new a({
|
|
@@ -289,15 +290,18 @@ function P(e) {
|
|
|
289
290
|
};
|
|
290
291
|
}
|
|
291
292
|
function F(e) {
|
|
292
|
-
let { mcp: t = { enabled: !0 } } = e, n = {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
293
|
+
let { mcp: t = { enabled: !0 } } = e, n = _(e), r = {
|
|
294
|
+
...e,
|
|
295
|
+
semanticLayer: n
|
|
296
|
+
}, i = {
|
|
297
|
+
load: C(r),
|
|
298
|
+
meta: w(r),
|
|
299
|
+
sql: T(r),
|
|
300
|
+
dryRun: E(r),
|
|
301
|
+
batch: D(r),
|
|
302
|
+
explain: O(r)
|
|
299
303
|
};
|
|
300
|
-
return t.enabled !== !1 && (
|
|
304
|
+
return t.enabled !== !1 && (i.mcpRpc = N(r)), e.agent && (i.agentChat = P(r)), i;
|
|
301
305
|
}
|
|
302
306
|
//#endregion
|
|
303
307
|
export { P as createAgentChatHandler, D as createBatchHandler, F as createCubeHandlers, k as createDiscoverHandler, E as createDryRunHandler, O as createExplainHandler, C as createLoadHandler, M as createMcpLoadHandler, N as createMcpRpcHandler, w as createMetaHandler, S as createOptionsHandler, T as createSqlHandler, A as createSuggestHandler, j as createValidateHandler };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { NextRequest } from 'next/server';
|
|
2
2
|
import { SemanticQuery, SecurityContext, DatabaseExecutor, DrizzleDatabase, Cube, CacheConfig, RLSSetupFn } from '../../server/index.js';
|
|
3
3
|
import { AgentConfig } from '../../server/agent/types.js';
|
|
4
|
+
import { SemanticLayerCompiler } from '../../server/compiler.js';
|
|
4
5
|
import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
|
|
5
6
|
import { MySql2Database } from 'drizzle-orm/mysql2';
|
|
6
7
|
import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
|
|
@@ -100,6 +101,15 @@ export interface NextAdapterOptions {
|
|
|
100
101
|
* to configure RLS (e.g., set JWT claims and switch Postgres roles), then runs the query.
|
|
101
102
|
*/
|
|
102
103
|
rlsSetup?: RLSSetupFn;
|
|
104
|
+
/**
|
|
105
|
+
* Pre-built semantic layer to reuse across handlers.
|
|
106
|
+
* When provided, the adapter reuses this compiler instead of constructing a
|
|
107
|
+
* new one (and skips cube registration — register cubes on it yourself).
|
|
108
|
+
* `createCubeHandlers` sets this internally so every handler it returns shares
|
|
109
|
+
* one compiler, keeping metadata/result caches consistent. Mirrors the Hono
|
|
110
|
+
* adapter's `semanticLayer` option.
|
|
111
|
+
*/
|
|
112
|
+
semanticLayer?: SemanticLayerCompiler;
|
|
103
113
|
}
|
|
104
114
|
export interface RouteContext {
|
|
105
115
|
params?: Record<string, string | string[]>;
|
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
import { Filter } from '../../../types.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
* Recursively searches filters (including nested and/or groups)
|
|
5
|
-
* Handles both UI format ({type: 'and'/'or', filters: [...]}) and simple filters
|
|
6
|
-
*/
|
|
7
|
-
export declare function findDateFilterForField(filters: Filter[], field: string): {
|
|
8
|
-
dateRange: string | string[];
|
|
9
|
-
} | undefined;
|
|
2
|
+
import { findDateFilterForField } from '../../../shared/filters/index.js';
|
|
3
|
+
export { findDateFilterForField };
|
|
10
4
|
/**
|
|
11
5
|
* Build compareDateRange for a time dimension based on its date filter
|
|
12
6
|
* When comparison is enabled, returns [[currentStart, currentEnd], [priorStart, priorEnd]]
|
|
13
7
|
*/
|
|
14
8
|
export declare function buildCompareDateRangeFromFilter(timeDimensionField: string, filters: Filter[]): [string, string][] | undefined;
|
|
15
9
|
/**
|
|
16
|
-
* Remove
|
|
17
|
-
* Returns a new array with the filter removed (immutable)
|
|
10
|
+
* Remove the inDateRange filter for a specific field from a filters array.
|
|
11
|
+
* Returns a new array with the filter removed (immutable).
|
|
18
12
|
*/
|
|
19
13
|
export declare function removeComparisonDateFilter(filters: Filter[], field: string): Filter[];
|
|
@@ -4,7 +4,8 @@ export { getSortDirection, getSortTooltip, getNextSortDirection, } from './query
|
|
|
4
4
|
export type { DatePreset } from './dateRangeUtils.js';
|
|
5
5
|
export { DATE_PRESETS, XTD_OPTIONS, calculateDateRange, formatDateRangeDisplay, detectPresetFromDateRange, } from './dateRangeUtils.js';
|
|
6
6
|
export { formatFilterValueDisplay } from './filterDisplayUtils.js';
|
|
7
|
-
export { isSimpleFilter, isGroupFilter, isAndFilter, isOrFilter, flattenFilters, countFilters, createSimpleFilter, createAndFilter, createOrFilter, cleanupFilters, transformFiltersForServer, transformFiltersFromServer,
|
|
7
|
+
export { isSimpleFilter, isGroupFilter, isAndFilter, isOrFilter, flattenFilters, countFilters, createSimpleFilter, createAndFilter, createOrFilter, cleanupFilters, transformFiltersForServer, transformFiltersFromServer, getAvailableOperators, } from '../../shared/filters/index.js';
|
|
8
|
+
export { hasQueryContent, cleanQuery, cleanQueryForServer, transformQueryForUI, getCubeNameFromField, getFieldType, getFieldTitle, getAllFilterableFields, convertDateRangeTypeToValue, requiresNumberInput, formatDateForCube, } from '../../shared/utils.js';
|
|
8
9
|
/**
|
|
9
10
|
* Check if a field is selected in the current query
|
|
10
11
|
*/
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { CubeQuery, Filter, SimpleFilter, GroupFilter, CubeMeta } from '../../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Check if a filter is a simple filter.
|
|
4
|
+
*
|
|
5
|
+
* Discriminates against GroupFilter (which has `type`/`filters`, never
|
|
6
|
+
* `member`/`operator`). `values` is intentionally NOT required: valueless
|
|
7
|
+
* filters such as an `inDateRange` carrying only a `dateRange` are still simple.
|
|
8
|
+
*/
|
|
9
|
+
export declare function isSimpleFilter(filter: Filter): filter is SimpleFilter;
|
|
10
|
+
/**
|
|
11
|
+
* Check if a filter is a group filter
|
|
12
|
+
*/
|
|
13
|
+
export declare function isGroupFilter(filter: Filter): filter is GroupFilter;
|
|
14
|
+
/**
|
|
15
|
+
* Check if a filter is an AND filter
|
|
16
|
+
*/
|
|
17
|
+
export declare function isAndFilter(filter: Filter): filter is GroupFilter;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a filter is an OR filter
|
|
20
|
+
*/
|
|
21
|
+
export declare function isOrFilter(filter: Filter): filter is GroupFilter;
|
|
22
|
+
/**
|
|
23
|
+
* Create a new simple filter
|
|
24
|
+
*/
|
|
25
|
+
export declare function createSimpleFilter(member: string, operator?: string, values?: any[]): SimpleFilter;
|
|
26
|
+
/**
|
|
27
|
+
* Create a new AND filter group
|
|
28
|
+
*/
|
|
29
|
+
export declare function createAndFilter(filters?: Filter[]): GroupFilter;
|
|
30
|
+
/**
|
|
31
|
+
* Create a new OR filter group
|
|
32
|
+
*/
|
|
33
|
+
export declare function createOrFilter(filters?: Filter[]): GroupFilter;
|
|
34
|
+
/**
|
|
35
|
+
* Clean up filters - backward compatible (returns filters unchanged)
|
|
36
|
+
* @deprecated This function is no longer used as we now support filtering on any schema field
|
|
37
|
+
*/
|
|
38
|
+
export declare function cleanupFilters(filters: Filter[], _query?: CubeQuery): Filter[];
|
|
39
|
+
/**
|
|
40
|
+
* Flatten all simple filters from a hierarchical filter structure
|
|
41
|
+
*/
|
|
42
|
+
export declare function flattenFilters(filters: Filter[]): SimpleFilter[];
|
|
43
|
+
/**
|
|
44
|
+
* Count total simple filters in a hierarchical structure
|
|
45
|
+
*/
|
|
46
|
+
export declare function countFilters(filters: Filter[]): number;
|
|
47
|
+
/**
|
|
48
|
+
* Extract all member names from a filter tree (handles nested group filters).
|
|
49
|
+
* Returns names in traversal order, including duplicates; callers that need
|
|
50
|
+
* unique fields should de-duplicate.
|
|
51
|
+
*/
|
|
52
|
+
export declare function extractFilterMembers(filters: Filter[]): string[];
|
|
53
|
+
/**
|
|
54
|
+
* Add a simple filter at a specific path in the filter tree.
|
|
55
|
+
* Path is an array of indices, e.g. [0, 2] means filters[0].filters[2].
|
|
56
|
+
* An empty path adds at the root, wrapping bare filters in an AND group as needed.
|
|
57
|
+
*/
|
|
58
|
+
export declare function addFilterAtPath(filters: Filter[], path: number[], newFilter: SimpleFilter): Filter[];
|
|
59
|
+
/**
|
|
60
|
+
* Remove a top-level filter by index, unwrapping a sole remaining single-filter
|
|
61
|
+
* group back to a bare filter (keeps the tree as shallow as possible).
|
|
62
|
+
*/
|
|
63
|
+
export declare function removeFilterAtIndex(filters: Filter[], index: number): Filter[];
|
|
64
|
+
/**
|
|
65
|
+
* Return a copy of a group with its type toggled between AND and OR
|
|
66
|
+
*/
|
|
67
|
+
export declare function toggleGroupType(group: GroupFilter): GroupFilter;
|
|
68
|
+
/**
|
|
69
|
+
* Find the first inDateRange filter for a given member, searching nested
|
|
70
|
+
* groups. Returns its dateRange (preferring the dateRange property).
|
|
71
|
+
*/
|
|
72
|
+
export declare function findDateFilterForField(filters: Filter[], field: string): {
|
|
73
|
+
dateRange: string | string[];
|
|
74
|
+
} | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Remove every simple filter matching a member (optionally restricted to an
|
|
77
|
+
* operator) from a filter tree, pruning groups that become empty. Immutable.
|
|
78
|
+
*/
|
|
79
|
+
export declare function removeFilterForMember(filters: Filter[], member: string, operator?: string): Filter[];
|
|
80
|
+
/**
|
|
81
|
+
* Transform filters from the UI GroupFilter format to the legacy server format.
|
|
82
|
+
* Server expects { and: [...] } / { or: [...] } instead of { type, filters }.
|
|
83
|
+
*/
|
|
84
|
+
export declare function transformFiltersForServer(filters: Filter[]): any[];
|
|
85
|
+
/**
|
|
86
|
+
* Transform filters from server/API format to UI format.
|
|
87
|
+
* Converts { and: [...] } / { or: [...] } to { type, filters } GroupFilters.
|
|
88
|
+
*/
|
|
89
|
+
export declare function transformFiltersFromServer(filters: any[]): Filter[];
|
|
90
|
+
/**
|
|
91
|
+
* Check if a filter's field(s) exist in the cube metadata. Helps identify
|
|
92
|
+
* filters that may not apply to a specific portlet's data. Fails open when no
|
|
93
|
+
* metadata is available.
|
|
94
|
+
*/
|
|
95
|
+
export declare function validateFilterForCube(filter: Filter, cubeMeta: CubeMeta | null): boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filter module — the single home for filter types, operator definitions, and
|
|
3
|
+
* add/remove/update-group manipulation logic. Consumed by both the dashboard
|
|
4
|
+
* filter UI and the analysis-builder filter UI; the two surfaces differ only in
|
|
5
|
+
* their value-source wiring, not in filter semantics.
|
|
6
|
+
*/
|
|
7
|
+
export type { Filter, SimpleFilter, GroupFilter, FilterOperator } from '../../types.js';
|
|
8
|
+
export type { FilterOperatorMeta } from './operators.js';
|
|
9
|
+
export { FILTER_OPERATORS, getAvailableOperators, normalizeFilterFieldType } from './operators.js';
|
|
10
|
+
export { isSimpleFilter, isGroupFilter, isAndFilter, isOrFilter, createSimpleFilter, createAndFilter, createOrFilter, cleanupFilters, flattenFilters, countFilters, extractFilterMembers, addFilterAtPath, removeFilterAtIndex, toggleGroupType, findDateFilterForField, removeFilterForMember, transformFiltersForServer, transformFiltersFromServer, validateFilterForCube } from './filterOperations.js';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FilterOperator } from '../../types.js';
|
|
2
|
+
export interface FilterOperatorMeta {
|
|
3
|
+
label: string;
|
|
4
|
+
description: string;
|
|
5
|
+
requiresValues: boolean;
|
|
6
|
+
supportsMultipleValues: boolean;
|
|
7
|
+
valueType: 'string' | 'number' | 'date' | 'boolean' | 'any';
|
|
8
|
+
fieldTypes: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare const FILTER_OPERATORS: Record<FilterOperator, FilterOperatorMeta>;
|
|
11
|
+
/**
|
|
12
|
+
* Normalize a raw field/measure type to the category used by FILTER_OPERATORS.
|
|
13
|
+
* Measure aggregation types collapse to 'number' so the numeric operators apply
|
|
14
|
+
* (without this, e.g. a `countDistinct` measure would expose no operators).
|
|
15
|
+
*/
|
|
16
|
+
export declare function normalizeFilterFieldType(fieldType: string): string;
|
|
17
|
+
/**
|
|
18
|
+
* Get available operators for a field type
|
|
19
|
+
*/
|
|
20
|
+
export declare function getAvailableOperators(fieldType: string): Array<{
|
|
21
|
+
operator: string;
|
|
22
|
+
label: string;
|
|
23
|
+
}>;
|
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Common types, utilities, and components used across QueryBuilder and AnalysisBuilder
|
|
4
4
|
*/
|
|
5
5
|
export type { MetaField, MetaCube, MetaResponse, QueryAnalysis, PrimaryCubeSelectionReason, PrimaryCubeCandidate, PrimaryCubeAnalysis, JoinPathStep, JoinPathAnalysis, PreAggregationAnalysis, QuerySummary, ValidationResult, FilterOperatorMeta, DateRangeType, DateRangeOption, TimeGranularity } from './types.js';
|
|
6
|
-
export {
|
|
7
|
-
export { isSimpleFilter, isGroupFilter, isAndFilter, isOrFilter, flattenFilters, countFilters, createSimpleFilter, createAndFilter, createOrFilter, transformFiltersForServer, transformFiltersFromServer
|
|
6
|
+
export { DATE_RANGE_OPTIONS, TIME_GRANULARITIES } from './types.js';
|
|
7
|
+
export { FILTER_OPERATORS, getAvailableOperators, isSimpleFilter, isGroupFilter, isAndFilter, isOrFilter, flattenFilters, countFilters, createSimpleFilter, createAndFilter, createOrFilter, transformFiltersForServer, transformFiltersFromServer } from './filters/index.js';
|
|
8
|
+
export { hasQueryContent, cleanQuery, cleanQueryForServer, transformQueryForUI, getCubeNameFromField, getFieldType, getFieldTitle, getAllFilterableFields, convertDateRangeTypeToValue, requiresNumberInput, formatDateForCube } from './utils.js';
|
|
8
9
|
export { default as QueryAnalysisPanel } from './components/QueryAnalysisPanel.js';
|
|
9
10
|
export { default as CodeBlock } from './components/CodeBlock.js';
|
|
10
11
|
export { getChartAvailability, getAllChartAvailability, selectBestChartType, getSmartChartDefaults, shouldAutoSwitchChartType, mergeChartConfigWithDefaults } from './chartDefaults.js';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CubeQuery
|
|
1
|
+
import { CubeQuery } from '../types.js';
|
|
2
2
|
export interface MetaField {
|
|
3
3
|
name: string;
|
|
4
4
|
title: string;
|
|
@@ -162,15 +162,8 @@ export interface ValidationResult {
|
|
|
162
162
|
joinType?: string;
|
|
163
163
|
analysis?: QueryAnalysis;
|
|
164
164
|
}
|
|
165
|
-
export
|
|
166
|
-
|
|
167
|
-
description: string;
|
|
168
|
-
requiresValues: boolean;
|
|
169
|
-
supportsMultipleValues: boolean;
|
|
170
|
-
valueType: 'string' | 'number' | 'date' | 'boolean' | 'any';
|
|
171
|
-
fieldTypes: string[];
|
|
172
|
-
}
|
|
173
|
-
export declare const FILTER_OPERATORS: Record<FilterOperator, FilterOperatorMeta>;
|
|
165
|
+
export type { FilterOperatorMeta } from './filters/operators.js';
|
|
166
|
+
export { FILTER_OPERATORS } from './filters/operators.js';
|
|
174
167
|
export type DateRangeType = 'custom' | 'today' | 'yesterday' | 'this_week' | 'this_month' | 'this_quarter' | 'this_year' | 'last_7_days' | 'last_30_days' | 'last_week' | 'last_month' | 'last_quarter' | 'last_year' | 'last_12_months' | 'last_n_days' | 'last_n_weeks' | 'last_n_months' | 'last_n_quarters' | 'last_n_years';
|
|
175
168
|
export interface DateRangeOption {
|
|
176
169
|
value: DateRangeType;
|
|
@@ -1,58 +1,7 @@
|
|
|
1
|
-
import { CubeQuery
|
|
1
|
+
import { CubeQuery } from '../types.js';
|
|
2
2
|
import { MetaField, MetaResponse } from './types.js';
|
|
3
3
|
import { cleanQuery } from './queryTransforms.js';
|
|
4
4
|
export { cleanQuery };
|
|
5
|
-
/**
|
|
6
|
-
* Check if a filter is a simple filter
|
|
7
|
-
*/
|
|
8
|
-
export declare function isSimpleFilter(filter: Filter): filter is SimpleFilter;
|
|
9
|
-
/**
|
|
10
|
-
* Check if a filter is a group filter
|
|
11
|
-
*/
|
|
12
|
-
export declare function isGroupFilter(filter: Filter): filter is GroupFilter;
|
|
13
|
-
/**
|
|
14
|
-
* Check if a filter is an AND filter
|
|
15
|
-
*/
|
|
16
|
-
export declare function isAndFilter(filter: Filter): filter is GroupFilter;
|
|
17
|
-
/**
|
|
18
|
-
* Check if a filter is an OR filter
|
|
19
|
-
*/
|
|
20
|
-
export declare function isOrFilter(filter: Filter): filter is GroupFilter;
|
|
21
|
-
/**
|
|
22
|
-
* Flatten all simple filters from a hierarchical filter structure
|
|
23
|
-
*/
|
|
24
|
-
export declare function flattenFilters(filters: Filter[]): SimpleFilter[];
|
|
25
|
-
/**
|
|
26
|
-
* Count total filters in hierarchical structure
|
|
27
|
-
*/
|
|
28
|
-
export declare function countFilters(filters: Filter[]): number;
|
|
29
|
-
/**
|
|
30
|
-
* Create a new simple filter
|
|
31
|
-
*/
|
|
32
|
-
export declare function createSimpleFilter(member: string, operator?: string, values?: any[]): SimpleFilter;
|
|
33
|
-
/**
|
|
34
|
-
* Create a new AND filter group
|
|
35
|
-
*/
|
|
36
|
-
export declare function createAndFilter(filters?: Filter[]): GroupFilter;
|
|
37
|
-
/**
|
|
38
|
-
* Create a new OR filter group
|
|
39
|
-
*/
|
|
40
|
-
export declare function createOrFilter(filters?: Filter[]): GroupFilter;
|
|
41
|
-
/**
|
|
42
|
-
* Clean up filters - backward compatible (returns filters unchanged)
|
|
43
|
-
* @deprecated This function is no longer used as we now support filtering on any schema field
|
|
44
|
-
*/
|
|
45
|
-
export declare function cleanupFilters(filters: Filter[], _query?: CubeQuery): Filter[];
|
|
46
|
-
/**
|
|
47
|
-
* Transform filters from new GroupFilter format to legacy server format
|
|
48
|
-
* Server expects { and: [...] } and { or: [...] } instead of { type: 'and', filters: [...] }
|
|
49
|
-
*/
|
|
50
|
-
export declare function transformFiltersForServer(filters: Filter[]): any[];
|
|
51
|
-
/**
|
|
52
|
-
* Transform filters from server/API format to UI format
|
|
53
|
-
* Converts {and: [...]} and {or: [...]} to {type: 'and', filters: [...]} format
|
|
54
|
-
*/
|
|
55
|
-
export declare function transformFiltersFromServer(filters: any[]): Filter[];
|
|
56
5
|
/**
|
|
57
6
|
* Check if query has any content (measures, dimensions, or timeDimensions)
|
|
58
7
|
*/
|
|
@@ -79,13 +28,6 @@ export declare function getFieldType(fieldName: string, schema: MetaResponse): s
|
|
|
79
28
|
* Get field title from schema metadata, falling back to field name
|
|
80
29
|
*/
|
|
81
30
|
export declare function getFieldTitle(fieldName: string, schema: MetaResponse | null): string;
|
|
82
|
-
/**
|
|
83
|
-
* Get available operators for a field type
|
|
84
|
-
*/
|
|
85
|
-
export declare function getAvailableOperators(fieldType: string): Array<{
|
|
86
|
-
operator: string;
|
|
87
|
-
label: string;
|
|
88
|
-
}>;
|
|
89
31
|
/**
|
|
90
32
|
* Get ALL filterable fields from schema
|
|
91
33
|
*/
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { Filter, DashboardFilter, DashboardFilterMapping, DashboardFilterMappingEntry, CubeMeta, DashboardConfig } from '../types.js';
|
|
2
|
+
import { validateFilterForCube } from '../shared/filters/index.js';
|
|
3
|
+
export { validateFilterForCube };
|
|
2
4
|
/**
|
|
3
5
|
* Normalize a portlet filter mapping to entry objects.
|
|
4
6
|
* Plain string entries (the legacy format) become { filterId } with no override.
|
|
@@ -61,14 +63,6 @@ export declare function mergeDashboardAndPortletFilters(dashboardFilters: Filter
|
|
|
61
63
|
* @deprecated Use mergeDashboardAndPortletFilters(filters, portletFilters, 'client') instead
|
|
62
64
|
*/
|
|
63
65
|
export declare function mergeDashboardAndPortletFiltersClientFormat(dashboardFilters: Filter[], portletFilters: Filter[] | undefined): Filter[] | undefined;
|
|
64
|
-
/**
|
|
65
|
-
* Check if a filter field exists in the cube metadata
|
|
66
|
-
* This helps identify filters that might not apply to a specific portlet's data
|
|
67
|
-
* @param filter - The filter to validate
|
|
68
|
-
* @param cubeMeta - Cube metadata to validate against
|
|
69
|
-
* @returns true if the filter field exists in any cube's measures or dimensions
|
|
70
|
-
*/
|
|
71
|
-
export declare function validateFilterForCube(filter: Filter, cubeMeta: CubeMeta | null): boolean;
|
|
72
66
|
/**
|
|
73
67
|
* Validate that all dashboard filters in a portlet's mapping exist and are valid
|
|
74
68
|
* @param dashboardFilters - All available dashboard filters
|
|
@@ -110,4 +104,3 @@ type TimeDimension = {
|
|
|
110
104
|
* @returns Updated timeDimensions array with date ranges applied
|
|
111
105
|
*/
|
|
112
106
|
export declare function applyUniversalTimeFilters(dashboardFilters: DashboardFilter[] | undefined, filterMapping: DashboardFilterMapping | undefined, portletTimeDimensions: TimeDimension[] | undefined): TimeDimension[] | undefined;
|
|
113
|
-
export {};
|
|
@@ -49,10 +49,5 @@ export declare class LogicalPlanBuilder {
|
|
|
49
49
|
private deduplicateColumnRefs;
|
|
50
50
|
private buildQueryNode;
|
|
51
51
|
private buildPreAggregationAnalysis;
|
|
52
|
-
private buildMeasureRefs;
|
|
53
|
-
private buildDimensionRefs;
|
|
54
|
-
private buildTimeDimensionRefs;
|
|
55
52
|
private buildOrderByRefs;
|
|
56
|
-
private toCubeRef;
|
|
57
|
-
private buildCTESchema;
|
|
58
53
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Cube, PhysicalQueryPlan } from '../types/index.js';
|
|
2
|
+
import { SemanticQuery } from '../types/query.js';
|
|
3
|
+
import { CubeRef, MeasureRef, DimensionRef, TimeDimensionRef, LogicalSchema } from './types.js';
|
|
4
|
+
export declare function toCubeRef(cube: Cube): CubeRef;
|
|
5
|
+
export declare function buildMeasureRefs(query: SemanticQuery, cubes: Map<string, Cube>): MeasureRef[];
|
|
6
|
+
export declare function buildDimensionRefs(query: SemanticQuery, cubes: Map<string, Cube>): DimensionRef[];
|
|
7
|
+
export declare function buildTimeDimensionRefs(query: SemanticQuery, cubes: Map<string, Cube>): TimeDimensionRef[];
|
|
8
|
+
/**
|
|
9
|
+
* Compose the full logical schema (measures, dimensions, time dimensions) for a
|
|
10
|
+
* query. This is the primary public interface: `(query, cubes) => LogicalSchema`.
|
|
11
|
+
*/
|
|
12
|
+
export declare function buildLogicalSchema(query: SemanticQuery, cubes: Map<string, Cube>): LogicalSchema;
|
|
13
|
+
/**
|
|
14
|
+
* Derive the measures-only schema for a pre-aggregation CTE. Unlike the
|
|
15
|
+
* query-driven builders above, this intentionally does NOT throw on a missing
|
|
16
|
+
* cube (the cube is guaranteed present by the planner that produced the CTE
|
|
17
|
+
* descriptor) — preserving exact prior behavior keeps generated SQL unchanged.
|
|
18
|
+
*/
|
|
19
|
+
export declare function buildCTESchema(cteInfo: NonNullable<PhysicalQueryPlan['preAggregationCTEs']>[number], cubes: Map<string, Cube>): LogicalSchema;
|