drizzle-cube 0.3.13 → 0.3.16

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.
Files changed (182) hide show
  1. package/dist/adapters/express/index.cjs +1 -1
  2. package/dist/adapters/express/index.d.ts +8 -1
  3. package/dist/adapters/express/index.js +162 -99
  4. package/dist/adapters/fastify/index.cjs +1 -1
  5. package/dist/adapters/fastify/index.d.ts +8 -1
  6. package/dist/adapters/fastify/index.js +183 -96
  7. package/dist/adapters/hono/index.cjs +1 -1
  8. package/dist/adapters/hono/index.d.ts +8 -1
  9. package/dist/adapters/hono/index.js +198 -142
  10. package/dist/adapters/nextjs/index.cjs +1 -1
  11. package/dist/adapters/nextjs/index.d.ts +29 -1
  12. package/dist/adapters/nextjs/index.js +251 -132
  13. package/dist/adapters/utils.d.ts +100 -1
  14. package/dist/adapters/validation-Bgauxvm6.cjs +214 -0
  15. package/dist/adapters/{compiler-DTOU8IsK.js → validation-_UkKJ2pC.js} +9582 -5295
  16. package/dist/client/adapters/index.d.ts +2 -0
  17. package/dist/client/adapters/retentionModeAdapter.d.ts +3 -0
  18. package/dist/client/charts.js +12 -12
  19. package/dist/client/chunks/RetentionCombinedChart-DirfDaZH.js +256 -0
  20. package/dist/client/chunks/RetentionCombinedChart-DirfDaZH.js.map +1 -0
  21. package/dist/client/chunks/RetentionCombinedChart.config-C-ILIaEb.js +47 -0
  22. package/dist/client/chunks/RetentionCombinedChart.config-C-ILIaEb.js.map +1 -0
  23. package/dist/client/chunks/RetentionHeatmap-Bofadstm.js +178 -0
  24. package/dist/client/chunks/RetentionHeatmap-Bofadstm.js.map +1 -0
  25. package/dist/client/chunks/RetentionHeatmap.config-CIvhc-GT.js +28 -0
  26. package/dist/client/chunks/RetentionHeatmap.config-CIvhc-GT.js.map +1 -0
  27. package/dist/client/chunks/analysis-builder-APeCxkEH.js +6939 -0
  28. package/dist/client/chunks/analysis-builder-APeCxkEH.js.map +1 -0
  29. package/dist/client/chunks/analysis-builder-shared-DEovRjrp.js +2779 -0
  30. package/dist/client/chunks/analysis-builder-shared-DEovRjrp.js.map +1 -0
  31. package/dist/client/chunks/{chart-activity-grid-CuPARsr1.js → chart-activity-grid-BnweuBvr.js} +11 -11
  32. package/dist/client/chunks/{chart-activity-grid-CuPARsr1.js.map → chart-activity-grid-BnweuBvr.js.map} +1 -1
  33. package/dist/client/chunks/{chart-area-cPrJnhLj.js → chart-area-DLmXFWWy.js} +2 -2
  34. package/dist/client/chunks/{chart-area-cPrJnhLj.js.map → chart-area-DLmXFWWy.js.map} +1 -1
  35. package/dist/client/chunks/{chart-bar-D68HFPpa.js → chart-bar-7y0-F27Q.js} +2 -2
  36. package/dist/client/chunks/{chart-bar-D68HFPpa.js.map → chart-bar-7y0-F27Q.js.map} +1 -1
  37. package/dist/client/chunks/{chart-bubble-CquyYfNO.js → chart-bubble-3jYKCA2B.js} +2 -2
  38. package/dist/client/chunks/{chart-bubble-CquyYfNO.js.map → chart-bubble-3jYKCA2B.js.map} +1 -1
  39. package/dist/client/chunks/{chart-config-activity-grid-Bkvx0F-G.js → chart-config-activity-grid-BBSNCbkb.js} +2 -2
  40. package/dist/client/chunks/{chart-config-activity-grid-Bkvx0F-G.js.map → chart-config-activity-grid-BBSNCbkb.js.map} +1 -1
  41. package/dist/client/chunks/{chart-config-area-OApsRaYC.js → chart-config-area-CyyJOO2T.js} +2 -2
  42. package/dist/client/chunks/{chart-config-area-OApsRaYC.js.map → chart-config-area-CyyJOO2T.js.map} +1 -1
  43. package/dist/client/chunks/{chart-config-bar-Dy21oaIA.js → chart-config-bar-BJKGnfLt.js} +2 -2
  44. package/dist/client/chunks/{chart-config-bar-Dy21oaIA.js.map → chart-config-bar-BJKGnfLt.js.map} +1 -1
  45. package/dist/client/chunks/{chart-config-bubble-Chv0SoFm.js → chart-config-bubble-CuSsCHZ4.js} +2 -2
  46. package/dist/client/chunks/{chart-config-bubble-Chv0SoFm.js.map → chart-config-bubble-CuSsCHZ4.js.map} +1 -1
  47. package/dist/client/chunks/{chart-config-data-table-DTIdC35a.js → chart-config-data-table-BhgqwoqT.js} +2 -2
  48. package/dist/client/chunks/{chart-config-data-table-DTIdC35a.js.map → chart-config-data-table-BhgqwoqT.js.map} +1 -1
  49. package/dist/client/chunks/{chart-config-funnel-f17Livgr.js → chart-config-funnel-BlSQYng0.js} +4 -4
  50. package/dist/client/chunks/{chart-config-funnel-f17Livgr.js.map → chart-config-funnel-BlSQYng0.js.map} +1 -1
  51. package/dist/client/chunks/{chart-config-heat-map-DPhNICha.js → chart-config-heat-map-DHQGFZhX.js} +2 -2
  52. package/dist/client/chunks/{chart-config-heat-map-DPhNICha.js.map → chart-config-heat-map-DHQGFZhX.js.map} +1 -1
  53. package/dist/client/chunks/{chart-config-kpi-delta-CCl1d-St.js → chart-config-kpi-delta-yTA5ug_l.js} +2 -2
  54. package/dist/client/chunks/{chart-config-kpi-delta-CCl1d-St.js.map → chart-config-kpi-delta-yTA5ug_l.js.map} +1 -1
  55. package/dist/client/chunks/{chart-config-kpi-number-DkE3eSwH.js → chart-config-kpi-number-nVAwDXzq.js} +2 -2
  56. package/dist/client/chunks/{chart-config-kpi-number-DkE3eSwH.js.map → chart-config-kpi-number-nVAwDXzq.js.map} +1 -1
  57. package/dist/client/chunks/{chart-config-kpi-text-BMbgdxZm.js → chart-config-kpi-text-DZjqsx-b.js} +2 -2
  58. package/dist/client/chunks/{chart-config-kpi-text-BMbgdxZm.js.map → chart-config-kpi-text-DZjqsx-b.js.map} +1 -1
  59. package/dist/client/chunks/{chart-config-line-BnLlRUQE.js → chart-config-line-DR0ThxZy.js} +2 -2
  60. package/dist/client/chunks/{chart-config-line-BnLlRUQE.js.map → chart-config-line-DR0ThxZy.js.map} +1 -1
  61. package/dist/client/chunks/{chart-config-markdown-DIaMFC0Z.js → chart-config-markdown-DZxdGNVQ.js} +2 -2
  62. package/dist/client/chunks/{chart-config-markdown-DIaMFC0Z.js.map → chart-config-markdown-DZxdGNVQ.js.map} +1 -1
  63. package/dist/client/chunks/{chart-config-pie-O9y_T0BQ.js → chart-config-pie-BM5lgH-w.js} +2 -2
  64. package/dist/client/chunks/{chart-config-pie-O9y_T0BQ.js.map → chart-config-pie-BM5lgH-w.js.map} +1 -1
  65. package/dist/client/chunks/{chart-config-radar-CXa0354h.js → chart-config-radar-BBAVIF0S.js} +2 -2
  66. package/dist/client/chunks/{chart-config-radar-CXa0354h.js.map → chart-config-radar-BBAVIF0S.js.map} +1 -1
  67. package/dist/client/chunks/{chart-config-radial-bar-BppJU8-Q.js → chart-config-radial-bar-CTwjDRnB.js} +2 -2
  68. package/dist/client/chunks/{chart-config-radial-bar-BppJU8-Q.js.map → chart-config-radial-bar-CTwjDRnB.js.map} +1 -1
  69. package/dist/client/chunks/{chart-config-sankey-BfBHgL4x.js → chart-config-sankey-CNAgsMQ4.js} +2 -2
  70. package/dist/client/chunks/{chart-config-sankey-BfBHgL4x.js.map → chart-config-sankey-CNAgsMQ4.js.map} +1 -1
  71. package/dist/client/chunks/{chart-config-scatter-BTt8a10R.js → chart-config-scatter-CWvN2E-X.js} +2 -2
  72. package/dist/client/chunks/{chart-config-scatter-BTt8a10R.js.map → chart-config-scatter-CWvN2E-X.js.map} +1 -1
  73. package/dist/client/chunks/{chart-config-sunburst-DNmQpIIx.js → chart-config-sunburst-W_SKwaj0.js} +4 -4
  74. package/dist/client/chunks/{chart-config-sunburst-DNmQpIIx.js.map → chart-config-sunburst-W_SKwaj0.js.map} +1 -1
  75. package/dist/client/chunks/{chart-config-tree-map-HVgG4oa0.js → chart-config-tree-map-CLmRvvMR.js} +2 -2
  76. package/dist/client/chunks/{chart-config-tree-map-HVgG4oa0.js.map → chart-config-tree-map-CLmRvvMR.js.map} +1 -1
  77. package/dist/client/chunks/{chart-data-table-D4WDqbM0.js → chart-data-table-rUFLqysu.js} +4 -4
  78. package/dist/client/chunks/{chart-data-table-D4WDqbM0.js.map → chart-data-table-rUFLqysu.js.map} +1 -1
  79. package/dist/client/chunks/{chart-funnel-Csdn4FbN.js → chart-funnel-C7zGBfSw.js} +2 -2
  80. package/dist/client/chunks/{chart-funnel-Csdn4FbN.js.map → chart-funnel-C7zGBfSw.js.map} +1 -1
  81. package/dist/client/chunks/{chart-heat-map-v1afxnjq.js → chart-heat-map-B-l8hK8b.js} +2 -2
  82. package/dist/client/chunks/{chart-heat-map-v1afxnjq.js.map → chart-heat-map-B-l8hK8b.js.map} +1 -1
  83. package/dist/client/chunks/chart-kpi-delta-sfZEvQZm.js +351 -0
  84. package/dist/client/chunks/chart-kpi-delta-sfZEvQZm.js.map +1 -0
  85. package/dist/client/chunks/chart-kpi-number-BxGNOtzI.js +473 -0
  86. package/dist/client/chunks/chart-kpi-number-BxGNOtzI.js.map +1 -0
  87. package/dist/client/chunks/{chart-kpi-text-CRp8QWYG.js → chart-kpi-text-BLQ_CWQP.js} +3 -3
  88. package/dist/client/chunks/{chart-kpi-text-CRp8QWYG.js.map → chart-kpi-text-BLQ_CWQP.js.map} +1 -1
  89. package/dist/client/chunks/{chart-line-DqqE7ky9.js → chart-line-FSEpBk6Y.js} +5 -5
  90. package/dist/client/chunks/{chart-line-DqqE7ky9.js.map → chart-line-FSEpBk6Y.js.map} +1 -1
  91. package/dist/client/chunks/{chart-pie-B5WBzIRH.js → chart-pie-BRQEH9e-.js} +2 -2
  92. package/dist/client/chunks/{chart-pie-B5WBzIRH.js.map → chart-pie-BRQEH9e-.js.map} +1 -1
  93. package/dist/client/chunks/{chart-radar-DL_dvhA-.js → chart-radar-DgsFyiIP.js} +2 -2
  94. package/dist/client/chunks/{chart-radar-DL_dvhA-.js.map → chart-radar-DgsFyiIP.js.map} +1 -1
  95. package/dist/client/chunks/{chart-radial-bar-DDRo6nz-.js → chart-radial-bar-CUMoXyl9.js} +2 -2
  96. package/dist/client/chunks/{chart-radial-bar-DDRo6nz-.js.map → chart-radial-bar-CUMoXyl9.js.map} +1 -1
  97. package/dist/client/chunks/{chart-sankey-C_bgIfg-.js → chart-sankey-IAKDEe7A.js} +2 -2
  98. package/dist/client/chunks/{chart-sankey-C_bgIfg-.js.map → chart-sankey-IAKDEe7A.js.map} +1 -1
  99. package/dist/client/chunks/{chart-scatter-DjmJRlK0.js → chart-scatter-D6XwOD2W.js} +15 -15
  100. package/dist/client/chunks/{chart-scatter-DjmJRlK0.js.map → chart-scatter-D6XwOD2W.js.map} +1 -1
  101. package/dist/client/chunks/{chart-sunburst-CbMEnaes.js → chart-sunburst-CP_pnj0S.js} +2 -2
  102. package/dist/client/chunks/{chart-sunburst-CbMEnaes.js.map → chart-sunburst-CP_pnj0S.js.map} +1 -1
  103. package/dist/client/chunks/{chart-tree-map-DEfJtJVC.js → chart-tree-map-DQMsn47a.js} +30 -30
  104. package/dist/client/chunks/{chart-tree-map-DEfJtJVC.js.map → chart-tree-map-DQMsn47a.js.map} +1 -1
  105. package/dist/client/chunks/chartConfigRegistry-BumUIPw4.js +44 -0
  106. package/dist/client/chunks/{chartConfigRegistry-CiOq-PqX.js.map → chartConfigRegistry-BumUIPw4.js.map} +1 -1
  107. package/dist/client/chunks/charts-Dk_9XrA7.js +230 -0
  108. package/dist/client/chunks/charts-Dk_9XrA7.js.map +1 -0
  109. package/dist/client/chunks/{charts-core-CXrhEEVF.js → charts-core-CjQZBxmv.js} +10 -10
  110. package/dist/client/chunks/{charts-core-CXrhEEVF.js.map → charts-core-CjQZBxmv.js.map} +1 -1
  111. package/dist/client/chunks/{charts-loader-BtsnUO4Q.js → charts-loader-ChTUa_-G.js} +30 -28
  112. package/dist/client/chunks/charts-loader-ChTUa_-G.js.map +1 -0
  113. package/dist/client/chunks/{components-BDrlf9Er.js → components-BKZ7EAg0.js} +3575 -3208
  114. package/dist/client/chunks/components-BKZ7EAg0.js.map +1 -0
  115. package/dist/client/chunks/{core-B8zw0qRf.js → core-BRC075EG.js} +2 -2
  116. package/dist/client/chunks/{core-B8zw0qRf.js.map → core-BRC075EG.js.map} +1 -1
  117. package/dist/client/chunks/hooks-D7APQ8uS.js +150 -0
  118. package/dist/client/chunks/{hooks-B8Zw5PfL.js.map → hooks-D7APQ8uS.js.map} +1 -1
  119. package/dist/client/chunks/{icons-NzFHtqeM.js → icons-DRreo6m8.js} +128 -112
  120. package/dist/client/chunks/{icons-NzFHtqeM.js.map → icons-DRreo6m8.js.map} +1 -1
  121. package/dist/client/chunks/{providers-CqCiJTEj.js → providers-Cj7PQfXn.js} +2 -2
  122. package/dist/client/chunks/{providers-CqCiJTEj.js.map → providers-Cj7PQfXn.js.map} +1 -1
  123. package/dist/client/chunks/retention-CzCo8262.js +120 -0
  124. package/dist/client/chunks/retention-CzCo8262.js.map +1 -0
  125. package/dist/client/chunks/{useDirtyStateTracking-C_mitVwh.js → useDirtyStateTracking-ZSi3voVl.js} +101 -99
  126. package/dist/client/chunks/useDirtyStateTracking-ZSi3voVl.js.map +1 -0
  127. package/dist/client/chunks/{vendor-DzzxS7Ay.js → vendor-cTQhZ_G3.js} +549 -541
  128. package/dist/client/chunks/vendor-cTQhZ_G3.js.map +1 -0
  129. package/dist/client/components/AnalysisBuilder/AnalysisTypeSelector.d.ts +3 -1
  130. package/dist/client/components/AnalysisBuilder/RetentionConfigPanel.d.ts +36 -0
  131. package/dist/client/components/AnalysisBuilder/RetentionModeContent.d.ts +71 -0
  132. package/dist/client/components/AnalysisBuilder/types.d.ts +99 -0
  133. package/dist/client/components/DebugModal.d.ts +2 -1
  134. package/dist/client/components/charts/RetentionCombinedChart.config.d.ts +2 -0
  135. package/dist/client/components/charts/RetentionCombinedChart.d.ts +14 -0
  136. package/dist/client/components/charts/RetentionHeatmap.config.d.ts +2 -0
  137. package/dist/client/components/charts/RetentionHeatmap.d.ts +7 -0
  138. package/dist/client/components.js +2 -2
  139. package/dist/client/hooks/queries/index.d.ts +2 -1
  140. package/dist/client/hooks/queries/useDryRunQuery.d.ts +26 -0
  141. package/dist/client/hooks/queries/useExplainQuery.d.ts +3 -1
  142. package/dist/client/hooks/queries/useFlowQuery.d.ts +5 -0
  143. package/dist/client/hooks/queries/useRetentionQuery.d.ts +67 -0
  144. package/dist/client/hooks/useAnalysisBuilderHook.d.ts +61 -0
  145. package/dist/client/hooks/useAnalysisQueryExecution.d.ts +42 -1
  146. package/dist/client/hooks.js +3 -3
  147. package/dist/client/icons/customIcons.d.ts +7 -0
  148. package/dist/client/icons/types.d.ts +1 -0
  149. package/dist/client/icons.js +1 -1
  150. package/dist/client/index.js +11 -11
  151. package/dist/client/providers.js +1 -1
  152. package/dist/client/stores/analysisBuilderStore.d.ts +86 -1
  153. package/dist/client/stores/dashboardStore.d.ts +2 -1
  154. package/dist/client/stores/slices/index.d.ts +2 -0
  155. package/dist/client/stores/slices/retentionSlice.d.ts +66 -0
  156. package/dist/client/styles.css +1 -1
  157. package/dist/client/types/analysisConfig.d.ts +29 -4
  158. package/dist/client/types/funnel.d.ts +5 -0
  159. package/dist/client/types/retention.d.ts +301 -0
  160. package/dist/client/types.d.ts +6 -3
  161. package/dist/client-bundle-stats.html +1 -1
  162. package/dist/server/index.cjs +101 -79
  163. package/dist/server/index.d.ts +427 -0
  164. package/dist/server/index.js +9140 -4934
  165. package/package.json +5 -2
  166. package/dist/adapters/compiler-CO13DaEb.cjs +0 -192
  167. package/dist/client/chunks/analysis-builder-Dc9NrG_N.js +0 -6013
  168. package/dist/client/chunks/analysis-builder-Dc9NrG_N.js.map +0 -1
  169. package/dist/client/chunks/analysis-builder-shared-B3-UWqQ2.js +0 -2540
  170. package/dist/client/chunks/analysis-builder-shared-B3-UWqQ2.js.map +0 -1
  171. package/dist/client/chunks/chart-kpi-delta-Bs5R5xr4.js +0 -435
  172. package/dist/client/chunks/chart-kpi-delta-Bs5R5xr4.js.map +0 -1
  173. package/dist/client/chunks/chart-kpi-number-Cf4Pgkm9.js +0 -392
  174. package/dist/client/chunks/chart-kpi-number-Cf4Pgkm9.js.map +0 -1
  175. package/dist/client/chunks/chartConfigRegistry-CiOq-PqX.js +0 -44
  176. package/dist/client/chunks/charts-loader-BtsnUO4Q.js.map +0 -1
  177. package/dist/client/chunks/charts-xNubY0vm.js +0 -226
  178. package/dist/client/chunks/charts-xNubY0vm.js.map +0 -1
  179. package/dist/client/chunks/components-BDrlf9Er.js.map +0 -1
  180. package/dist/client/chunks/hooks-B8Zw5PfL.js +0 -123
  181. package/dist/client/chunks/useDirtyStateTracking-C_mitVwh.js.map +0 -1
  182. package/dist/client/chunks/vendor-DzzxS7Ay.js.map +0 -1
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("express"),q=require("cors"),o=require("../compiler-CO13DaEb.cjs");function R(f){const{cubes:d,drizzle:j,schema:x,extractSecurityContext:y,engineType:g,cors:h,basePath:l="/cubejs-api/v1",jsonLimit:b="10mb",cache:Q}=f;if(!d||d.length===0)throw new Error("At least one cube must be provided in the cubes array");const u=p.Router();h&&u.use(q(h)),u.use(p.json({limit:b})),u.use(p.urlencoded({extended:!0,limit:b}));const a=new o.SemanticLayerCompiler({drizzle:j,schema:x,engineType:g,cache:Q});return d.forEach(t=>{a.registerCube(t)}),u.post(`${l}/load`,async(t,r)=>{try{const e=t.body.query||t.body,s=await y(t,r),n=a.validateQuery(e);if(!n.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${n.errors.join(", ")}`,400));const i=t.headers["x-cache-control"]==="no-cache",c=await a.executeMultiCubeQuery(e,s,{skipCache:i});r.json(o.formatCubeResponse(e,c,a))}catch(e){console.error("Query execution error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),u.get(`${l}/load`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json(o.formatErrorResponse("Query parameter is required",400));let s;try{s=JSON.parse(e)}catch{return r.status(400).json(o.formatErrorResponse("Invalid JSON in query parameter",400))}const n=await y(t,r),i=a.validateQuery(s);if(!i.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${i.errors.join(", ")}`,400));const c=t.headers["x-cache-control"]==="no-cache",m=await a.executeMultiCubeQuery(s,n,{skipCache:c});r.json(o.formatCubeResponse(s,m,a))}catch(e){console.error("Query execution error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),u.post(`${l}/batch`,async(t,r)=>{try{const{queries:e}=t.body;if(!e||!Array.isArray(e))return r.status(400).json(o.formatErrorResponse('Request body must contain a "queries" array',400));if(e.length===0)return r.status(400).json(o.formatErrorResponse("Queries array cannot be empty",400));const s=await y(t,r),n=t.headers["x-cache-control"]==="no-cache",i=await o.handleBatchRequest(e,s,a,{skipCache:n});r.json(i)}catch(e){console.error("Batch execution error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Batch execution failed",500))}}),u.get(`${l}/meta`,(t,r)=>{try{const e=a.getMetadata();r.json(o.formatMetaResponse(e))}catch(e){console.error("Metadata error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"Failed to fetch metadata",500))}}),u.post(`${l}/sql`,async(t,r)=>{try{const e=t.body,s=await y(t,r),n=a.validateQuery(e);if(!n.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${n.errors.join(", ")}`,400));const i=e.measures?.[0]||e.dimensions?.[0];if(!i)return r.status(400).json(o.formatErrorResponse("No measures or dimensions specified",400));const c=i.split(".")[0],m=await a.generateSQL(c,e,s);r.json(o.formatSqlResponse(e,m))}catch(e){console.error("SQL generation error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),u.get(`${l}/sql`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json(o.formatErrorResponse("Query parameter is required",400));const s=JSON.parse(e),n=await y(t,r),i=a.validateQuery(s);if(!i.isValid)return r.status(400).json(o.formatErrorResponse(`Query validation failed: ${i.errors.join(", ")}`,400));const c=s.measures?.[0]||s.dimensions?.[0];if(!c)return r.status(400).json(o.formatErrorResponse("No measures or dimensions specified",400));const m=c.split(".")[0],C=await a.generateSQL(m,s,n);r.json(o.formatSqlResponse(s,C))}catch(e){console.error("SQL generation error:",e),r.status(500).json(o.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),u.post(`${l}/dry-run`,async(t,r)=>{try{const e=t.body.query||t.body,s=await y(t,r),n=await o.handleDryRun(e,s,a);r.json(n)}catch(e){console.error("Dry-run error:",e),r.status(400).json({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),u.get(`${l}/dry-run`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json({error:"Query parameter is required",valid:!1});const s=JSON.parse(e),n=await y(t,r),i=await o.handleDryRun(s,n,a);r.json(i)}catch(e){console.error("Dry-run error:",e),r.status(400).json({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),u.post(`${l}/explain`,async(t,r)=>{try{const e=t.body.query||t.body,s=t.body.options||{},n=await y(t,r),i=a.validateQuery(e);if(!i.isValid)return r.status(400).json({error:`Query validation failed: ${i.errors.join(", ")}`});const c=await a.explainQuery(e,n,s);r.json(c)}catch(e){console.error("Explain error:",e),r.status(500).json({error:e instanceof Error?e.message:"Explain query failed"})}}),u.use((t,r,e,s)=>{console.error("Express adapter error:",t),e.headersSent||e.status(500).json(o.formatErrorResponse(t,500))}),u}function E(f,d){const j=R(d);return f.use("/",j),f}function v(f){const d=p();return E(d,f)}exports.createCubeApp=v;exports.createCubeRouter=R;exports.mountCubeRoutes=E;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const p=require("express"),C=require("cors"),a=require("../validation-Bgauxvm6.cjs");function R(f){const{cubes:y,drizzle:j,schema:v,extractSecurityContext:l,engineType:x,cors:b,basePath:d="/cubejs-api/v1",jsonLimit:g="10mb",cache:q,mcp:h={enabled:!0}}=f;if(!y||y.length===0)throw new Error("At least one cube must be provided in the cubes array");const c=p.Router();b&&c.use(C(b)),c.use(p.json({limit:g})),c.use(p.urlencoded({extended:!0,limit:g}));const i=new a.SemanticLayerCompiler({drizzle:j,schema:v,engineType:x,cache:q});if(y.forEach(t=>{i.registerCube(t)}),c.post(`${d}/load`,async(t,r)=>{try{const e=t.body.query||t.body,s=await l(t,r),o=i.validateQuery(e);if(!o.isValid)return r.status(400).json(a.formatErrorResponse(`Query validation failed: ${o.errors.join(", ")}`,400));const n=t.headers["x-cache-control"]==="no-cache",u=await i.executeMultiCubeQuery(e,s,{skipCache:n});r.json(a.formatCubeResponse(e,u,i))}catch(e){console.error("Query execution error:",e),r.status(500).json(a.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),c.get(`${d}/load`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json(a.formatErrorResponse("Query parameter is required",400));let s;try{s=JSON.parse(e)}catch{return r.status(400).json(a.formatErrorResponse("Invalid JSON in query parameter",400))}const o=await l(t,r),n=i.validateQuery(s);if(!n.isValid)return r.status(400).json(a.formatErrorResponse(`Query validation failed: ${n.errors.join(", ")}`,400));const u=t.headers["x-cache-control"]==="no-cache",m=await i.executeMultiCubeQuery(s,o,{skipCache:u});r.json(a.formatCubeResponse(s,m,i))}catch(e){console.error("Query execution error:",e),r.status(500).json(a.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),c.post(`${d}/batch`,async(t,r)=>{try{const{queries:e}=t.body;if(!e||!Array.isArray(e))return r.status(400).json(a.formatErrorResponse('Request body must contain a "queries" array',400));if(e.length===0)return r.status(400).json(a.formatErrorResponse("Queries array cannot be empty",400));const s=await l(t,r),o=t.headers["x-cache-control"]==="no-cache",n=await a.handleBatchRequest(e,s,i,{skipCache:o});r.json(n)}catch(e){console.error("Batch execution error:",e),r.status(500).json(a.formatErrorResponse(e instanceof Error?e.message:"Batch execution failed",500))}}),c.get(`${d}/meta`,(t,r)=>{try{const e=i.getMetadata();r.json(a.formatMetaResponse(e))}catch(e){console.error("Metadata error:",e),r.status(500).json(a.formatErrorResponse(e instanceof Error?e.message:"Failed to fetch metadata",500))}}),c.post(`${d}/sql`,async(t,r)=>{try{const e=t.body,s=await l(t,r),o=i.validateQuery(e);if(!o.isValid)return r.status(400).json(a.formatErrorResponse(`Query validation failed: ${o.errors.join(", ")}`,400));const n=e.measures?.[0]||e.dimensions?.[0];if(!n)return r.status(400).json(a.formatErrorResponse("No measures or dimensions specified",400));const u=n.split(".")[0],m=await i.generateSQL(u,e,s);r.json(a.formatSqlResponse(e,m))}catch(e){console.error("SQL generation error:",e),r.status(500).json(a.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),c.get(`${d}/sql`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json(a.formatErrorResponse("Query parameter is required",400));const s=JSON.parse(e),o=await l(t,r),n=i.validateQuery(s);if(!n.isValid)return r.status(400).json(a.formatErrorResponse(`Query validation failed: ${n.errors.join(", ")}`,400));const u=s.measures?.[0]||s.dimensions?.[0];if(!u)return r.status(400).json(a.formatErrorResponse("No measures or dimensions specified",400));const m=u.split(".")[0],Q=await i.generateSQL(m,s,o);r.json(a.formatSqlResponse(s,Q))}catch(e){console.error("SQL generation error:",e),r.status(500).json(a.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),c.post(`${d}/dry-run`,async(t,r)=>{try{const e=t.body.query||t.body,s=await l(t,r),o=await a.handleDryRun(e,s,i);r.json(o)}catch(e){console.error("Dry-run error:",e),r.status(400).json({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),c.get(`${d}/dry-run`,async(t,r)=>{try{const e=t.query.query;if(!e)return r.status(400).json({error:"Query parameter is required",valid:!1});const s=JSON.parse(e),o=await l(t,r),n=await a.handleDryRun(s,o,i);r.json(n)}catch(e){console.error("Dry-run error:",e),r.status(400).json({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),c.post(`${d}/explain`,async(t,r)=>{try{const e=t.body.query||t.body,s=t.body.options||{},o=await l(t,r),n=i.validateQuery(e);if(!n.isValid)return r.status(400).json({error:`Query validation failed: ${n.errors.join(", ")}`});const u=await i.explainQuery(e,o,s);r.json(u)}catch(e){console.error("Explain error:",e),r.status(500).json({error:e instanceof Error?e.message:"Explain query failed"})}}),h.enabled!==!1){const t=h.tools||["discover","suggest","validate","load"],r=h.basePath??"/mcp";t.includes("discover")&&c.post(`${r}/discover`,async(e,s)=>{try{const o=e.body,n=await a.handleDiscover(i,o);s.json(n)}catch(o){console.error("Discover error:",o),s.status(500).json(a.formatErrorResponse(o instanceof Error?o.message:"Discovery failed",500))}}),t.includes("suggest")&&c.post(`${r}/suggest`,async(e,s)=>{try{const o=e.body;if(!o.naturalLanguage)return s.status(400).json(a.formatErrorResponse("naturalLanguage field is required",400));const n=await a.handleSuggest(i,o);s.json(n)}catch(o){console.error("Suggest error:",o),s.status(500).json(a.formatErrorResponse(o instanceof Error?o.message:"Query suggestion failed",500))}}),t.includes("validate")&&c.post(`${r}/validate`,async(e,s)=>{try{const o=e.body;if(!o.query)return s.status(400).json(a.formatErrorResponse("query field is required",400));const n=await a.handleValidate(i,o);s.json(n)}catch(o){console.error("Validate error:",o),s.status(500).json(a.formatErrorResponse(o instanceof Error?o.message:"Query validation failed",500))}}),t.includes("load")&&c.post(`${r}/load`,async(e,s)=>{try{const o=e.body;if(!o.query)return s.status(400).json(a.formatErrorResponse("query field is required",400));const n=await l(e,s),u=await a.handleLoad(i,n,o);s.json(u)}catch(o){console.error("Load error:",o),s.status(500).json(a.formatErrorResponse(o instanceof Error?o.message:"Query execution failed",500))}})}return c.use((t,r,e,s)=>{console.error("Express adapter error:",t),e.headersSent||e.status(500).json(a.formatErrorResponse(t,500))}),c}function E(f,y){const j=R(y);return f.use("/",j),f}function w(f){const y=p();return E(y,f)}exports.createCubeApp=w;exports.createCubeRouter=R;exports.mountCubeRoutes=E;
@@ -4,6 +4,7 @@ import { SemanticQuery, SecurityContext, DatabaseExecutor, DrizzleDatabase, Cube
4
4
  import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
5
5
  import { MySql2Database } from 'drizzle-orm/mysql2';
6
6
  import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
7
+ import { MCPOptions } from '../utils';
7
8
  export interface ExpressAdapterOptions {
8
9
  /**
9
10
  * Array of cube definitions to register
@@ -48,7 +49,7 @@ export interface ExpressAdapterOptions {
48
49
  /**
49
50
  * Database engine type (optional - auto-detected if not provided)
50
51
  */
51
- engineType?: 'postgres' | 'mysql' | 'sqlite';
52
+ engineType?: 'postgres' | 'mysql' | 'sqlite' | 'singlestore' | 'duckdb';
52
53
  /**
53
54
  * CORS configuration (optional)
54
55
  */
@@ -66,6 +67,12 @@ export interface ExpressAdapterOptions {
66
67
  * When provided, query results will be cached using the specified provider
67
68
  */
68
69
  cache?: CacheConfig;
70
+ /**
71
+ * MCP (AI-Ready) endpoint configuration
72
+ * Enables AI agents to discover and query your data
73
+ * @default { enabled: true }
74
+ */
75
+ mcp?: MCPOptions;
69
76
  }
70
77
  /**
71
78
  * Create Express router for Cube.js-compatible API
@@ -1,212 +1,275 @@
1
- import h, { Router as E } from "express";
2
- import R from "cors";
3
- import { S, d as a, f as x, h as $, a as L, b as Q, c as g } from "../compiler-DTOU8IsK.js";
4
- function N(f) {
1
+ import h, { Router as $ } from "express";
2
+ import S from "cors";
3
+ import { S as R, j as n, f as v, h as L, a as D, b as x, c as Q, d as N, e as M, g as V, i as P } from "../validation-_UkKJ2pC.js";
4
+ function A(f) {
5
5
  const {
6
- cubes: d,
7
- drizzle: p,
8
- schema: v,
6
+ cubes: y,
7
+ drizzle: j,
8
+ schema: q,
9
9
  extractSecurityContext: l,
10
- engineType: C,
11
- cors: j,
12
- basePath: y = "/cubejs-api/v1",
10
+ engineType: w,
11
+ cors: g,
12
+ basePath: d = "/cubejs-api/v1",
13
13
  jsonLimit: b = "10mb",
14
- cache: q
14
+ cache: C,
15
+ mcp: p = { enabled: !0 }
15
16
  } = f;
16
- if (!d || d.length === 0)
17
+ if (!y || y.length === 0)
17
18
  throw new Error("At least one cube must be provided in the cubes array");
18
- const c = E();
19
- j && c.use(R(j)), c.use(h.json({ limit: b })), c.use(h.urlencoded({ extended: !0, limit: b }));
20
- const s = new S({
21
- drizzle: p,
22
- schema: v,
23
- engineType: C,
24
- cache: q
19
+ const c = $();
20
+ g && c.use(S(g)), c.use(h.json({ limit: b })), c.use(h.urlencoded({ extended: !0, limit: b }));
21
+ const i = new R({
22
+ drizzle: j,
23
+ schema: q,
24
+ engineType: w,
25
+ cache: C
25
26
  });
26
- return d.forEach((r) => {
27
- s.registerCube(r);
28
- }), c.post(`${y}/load`, async (r, t) => {
27
+ if (y.forEach((o) => {
28
+ i.registerCube(o);
29
+ }), c.post(`${d}/load`, async (o, t) => {
29
30
  try {
30
- const e = r.body.query || r.body, o = await l(r, t), n = s.validateQuery(e);
31
- if (!n.isValid)
32
- return t.status(400).json(a(
33
- `Query validation failed: ${n.errors.join(", ")}`,
31
+ const e = o.body.query || o.body, s = await l(o, t), r = i.validateQuery(e);
32
+ if (!r.isValid)
33
+ return t.status(400).json(n(
34
+ `Query validation failed: ${r.errors.join(", ")}`,
34
35
  400
35
36
  ));
36
- const i = r.headers["x-cache-control"] === "no-cache", u = await s.executeMultiCubeQuery(e, o, { skipCache: i });
37
- t.json(x(e, u, s));
37
+ const a = o.headers["x-cache-control"] === "no-cache", u = await i.executeMultiCubeQuery(e, s, { skipCache: a });
38
+ t.json(v(e, u, i));
38
39
  } catch (e) {
39
- console.error("Query execution error:", e), t.status(500).json(a(
40
+ console.error("Query execution error:", e), t.status(500).json(n(
40
41
  e instanceof Error ? e.message : "Query execution failed",
41
42
  500
42
43
  ));
43
44
  }
44
- }), c.get(`${y}/load`, async (r, t) => {
45
+ }), c.get(`${d}/load`, async (o, t) => {
45
46
  try {
46
- const e = r.query.query;
47
+ const e = o.query.query;
47
48
  if (!e)
48
- return t.status(400).json(a(
49
+ return t.status(400).json(n(
49
50
  "Query parameter is required",
50
51
  400
51
52
  ));
52
- let o;
53
+ let s;
53
54
  try {
54
- o = JSON.parse(e);
55
+ s = JSON.parse(e);
55
56
  } catch {
56
- return t.status(400).json(a(
57
+ return t.status(400).json(n(
57
58
  "Invalid JSON in query parameter",
58
59
  400
59
60
  ));
60
61
  }
61
- const n = await l(r, t), i = s.validateQuery(o);
62
- if (!i.isValid)
63
- return t.status(400).json(a(
64
- `Query validation failed: ${i.errors.join(", ")}`,
62
+ const r = await l(o, t), a = i.validateQuery(s);
63
+ if (!a.isValid)
64
+ return t.status(400).json(n(
65
+ `Query validation failed: ${a.errors.join(", ")}`,
65
66
  400
66
67
  ));
67
- const u = r.headers["x-cache-control"] === "no-cache", m = await s.executeMultiCubeQuery(o, n, { skipCache: u });
68
- t.json(x(o, m, s));
68
+ const u = o.headers["x-cache-control"] === "no-cache", m = await i.executeMultiCubeQuery(s, r, { skipCache: u });
69
+ t.json(v(s, m, i));
69
70
  } catch (e) {
70
- console.error("Query execution error:", e), t.status(500).json(a(
71
+ console.error("Query execution error:", e), t.status(500).json(n(
71
72
  e instanceof Error ? e.message : "Query execution failed",
72
73
  500
73
74
  ));
74
75
  }
75
- }), c.post(`${y}/batch`, async (r, t) => {
76
+ }), c.post(`${d}/batch`, async (o, t) => {
76
77
  try {
77
- const { queries: e } = r.body;
78
+ const { queries: e } = o.body;
78
79
  if (!e || !Array.isArray(e))
79
- return t.status(400).json(a(
80
+ return t.status(400).json(n(
80
81
  'Request body must contain a "queries" array',
81
82
  400
82
83
  ));
83
84
  if (e.length === 0)
84
- return t.status(400).json(a(
85
+ return t.status(400).json(n(
85
86
  "Queries array cannot be empty",
86
87
  400
87
88
  ));
88
- const o = await l(r, t), n = r.headers["x-cache-control"] === "no-cache", i = await $(e, o, s, { skipCache: n });
89
- t.json(i);
89
+ const s = await l(o, t), r = o.headers["x-cache-control"] === "no-cache", a = await L(e, s, i, { skipCache: r });
90
+ t.json(a);
90
91
  } catch (e) {
91
- console.error("Batch execution error:", e), t.status(500).json(a(
92
+ console.error("Batch execution error:", e), t.status(500).json(n(
92
93
  e instanceof Error ? e.message : "Batch execution failed",
93
94
  500
94
95
  ));
95
96
  }
96
- }), c.get(`${y}/meta`, (r, t) => {
97
+ }), c.get(`${d}/meta`, (o, t) => {
97
98
  try {
98
- const e = s.getMetadata();
99
- t.json(L(e));
99
+ const e = i.getMetadata();
100
+ t.json(D(e));
100
101
  } catch (e) {
101
- console.error("Metadata error:", e), t.status(500).json(a(
102
+ console.error("Metadata error:", e), t.status(500).json(n(
102
103
  e instanceof Error ? e.message : "Failed to fetch metadata",
103
104
  500
104
105
  ));
105
106
  }
106
- }), c.post(`${y}/sql`, async (r, t) => {
107
+ }), c.post(`${d}/sql`, async (o, t) => {
107
108
  try {
108
- const e = r.body, o = await l(r, t), n = s.validateQuery(e);
109
- if (!n.isValid)
110
- return t.status(400).json(a(
111
- `Query validation failed: ${n.errors.join(", ")}`,
109
+ const e = o.body, s = await l(o, t), r = i.validateQuery(e);
110
+ if (!r.isValid)
111
+ return t.status(400).json(n(
112
+ `Query validation failed: ${r.errors.join(", ")}`,
112
113
  400
113
114
  ));
114
- const i = e.measures?.[0] || e.dimensions?.[0];
115
- if (!i)
116
- return t.status(400).json(a(
115
+ const a = e.measures?.[0] || e.dimensions?.[0];
116
+ if (!a)
117
+ return t.status(400).json(n(
117
118
  "No measures or dimensions specified",
118
119
  400
119
120
  ));
120
- const u = i.split(".")[0], m = await s.generateSQL(u, e, o);
121
- t.json(Q(e, m));
121
+ const u = a.split(".")[0], m = await i.generateSQL(u, e, s);
122
+ t.json(x(e, m));
122
123
  } catch (e) {
123
- console.error("SQL generation error:", e), t.status(500).json(a(
124
+ console.error("SQL generation error:", e), t.status(500).json(n(
124
125
  e instanceof Error ? e.message : "SQL generation failed",
125
126
  500
126
127
  ));
127
128
  }
128
- }), c.get(`${y}/sql`, async (r, t) => {
129
+ }), c.get(`${d}/sql`, async (o, t) => {
129
130
  try {
130
- const e = r.query.query;
131
+ const e = o.query.query;
131
132
  if (!e)
132
- return t.status(400).json(a(
133
+ return t.status(400).json(n(
133
134
  "Query parameter is required",
134
135
  400
135
136
  ));
136
- const o = JSON.parse(e), n = await l(r, t), i = s.validateQuery(o);
137
- if (!i.isValid)
138
- return t.status(400).json(a(
139
- `Query validation failed: ${i.errors.join(", ")}`,
137
+ const s = JSON.parse(e), r = await l(o, t), a = i.validateQuery(s);
138
+ if (!a.isValid)
139
+ return t.status(400).json(n(
140
+ `Query validation failed: ${a.errors.join(", ")}`,
140
141
  400
141
142
  ));
142
- const u = o.measures?.[0] || o.dimensions?.[0];
143
+ const u = s.measures?.[0] || s.dimensions?.[0];
143
144
  if (!u)
144
- return t.status(400).json(a(
145
+ return t.status(400).json(n(
145
146
  "No measures or dimensions specified",
146
147
  400
147
148
  ));
148
- const m = u.split(".")[0], w = await s.generateSQL(m, o, n);
149
- t.json(Q(o, w));
149
+ const m = u.split(".")[0], E = await i.generateSQL(m, s, r);
150
+ t.json(x(s, E));
150
151
  } catch (e) {
151
- console.error("SQL generation error:", e), t.status(500).json(a(
152
+ console.error("SQL generation error:", e), t.status(500).json(n(
152
153
  e instanceof Error ? e.message : "SQL generation failed",
153
154
  500
154
155
  ));
155
156
  }
156
- }), c.post(`${y}/dry-run`, async (r, t) => {
157
+ }), c.post(`${d}/dry-run`, async (o, t) => {
157
158
  try {
158
- const e = r.body.query || r.body, o = await l(r, t), n = await g(e, o, s);
159
- t.json(n);
159
+ const e = o.body.query || o.body, s = await l(o, t), r = await Q(e, s, i);
160
+ t.json(r);
160
161
  } catch (e) {
161
162
  console.error("Dry-run error:", e), t.status(400).json({
162
163
  error: e instanceof Error ? e.message : "Dry-run validation failed",
163
164
  valid: !1
164
165
  });
165
166
  }
166
- }), c.get(`${y}/dry-run`, async (r, t) => {
167
+ }), c.get(`${d}/dry-run`, async (o, t) => {
167
168
  try {
168
- const e = r.query.query;
169
+ const e = o.query.query;
169
170
  if (!e)
170
171
  return t.status(400).json({
171
172
  error: "Query parameter is required",
172
173
  valid: !1
173
174
  });
174
- const o = JSON.parse(e), n = await l(r, t), i = await g(o, n, s);
175
- t.json(i);
175
+ const s = JSON.parse(e), r = await l(o, t), a = await Q(s, r, i);
176
+ t.json(a);
176
177
  } catch (e) {
177
178
  console.error("Dry-run error:", e), t.status(400).json({
178
179
  error: e instanceof Error ? e.message : "Dry-run validation failed",
179
180
  valid: !1
180
181
  });
181
182
  }
182
- }), c.post(`${y}/explain`, async (r, t) => {
183
+ }), c.post(`${d}/explain`, async (o, t) => {
183
184
  try {
184
- const e = r.body.query || r.body, o = r.body.options || {}, n = await l(r, t), i = s.validateQuery(e);
185
- if (!i.isValid)
185
+ const e = o.body.query || o.body, s = o.body.options || {}, r = await l(o, t), a = i.validateQuery(e);
186
+ if (!a.isValid)
186
187
  return t.status(400).json({
187
- error: `Query validation failed: ${i.errors.join(", ")}`
188
+ error: `Query validation failed: ${a.errors.join(", ")}`
188
189
  });
189
- const u = await s.explainQuery(e, n, o);
190
+ const u = await i.explainQuery(e, r, s);
190
191
  t.json(u);
191
192
  } catch (e) {
192
193
  console.error("Explain error:", e), t.status(500).json({
193
194
  error: e instanceof Error ? e.message : "Explain query failed"
194
195
  });
195
196
  }
196
- }), c.use((r, t, e, o) => {
197
- console.error("Express adapter error:", r), e.headersSent || e.status(500).json(a(r, 500));
197
+ }), p.enabled !== !1) {
198
+ const o = p.tools || ["discover", "suggest", "validate", "load"], t = p.basePath ?? "/mcp";
199
+ o.includes("discover") && c.post(`${t}/discover`, async (e, s) => {
200
+ try {
201
+ const r = e.body, a = await N(i, r);
202
+ s.json(a);
203
+ } catch (r) {
204
+ console.error("Discover error:", r), s.status(500).json(n(
205
+ r instanceof Error ? r.message : "Discovery failed",
206
+ 500
207
+ ));
208
+ }
209
+ }), o.includes("suggest") && c.post(`${t}/suggest`, async (e, s) => {
210
+ try {
211
+ const r = e.body;
212
+ if (!r.naturalLanguage)
213
+ return s.status(400).json(n(
214
+ "naturalLanguage field is required",
215
+ 400
216
+ ));
217
+ const a = await M(i, r);
218
+ s.json(a);
219
+ } catch (r) {
220
+ console.error("Suggest error:", r), s.status(500).json(n(
221
+ r instanceof Error ? r.message : "Query suggestion failed",
222
+ 500
223
+ ));
224
+ }
225
+ }), o.includes("validate") && c.post(`${t}/validate`, async (e, s) => {
226
+ try {
227
+ const r = e.body;
228
+ if (!r.query)
229
+ return s.status(400).json(n(
230
+ "query field is required",
231
+ 400
232
+ ));
233
+ const a = await V(i, r);
234
+ s.json(a);
235
+ } catch (r) {
236
+ console.error("Validate error:", r), s.status(500).json(n(
237
+ r instanceof Error ? r.message : "Query validation failed",
238
+ 500
239
+ ));
240
+ }
241
+ }), o.includes("load") && c.post(`${t}/load`, async (e, s) => {
242
+ try {
243
+ const r = e.body;
244
+ if (!r.query)
245
+ return s.status(400).json(n(
246
+ "query field is required",
247
+ 400
248
+ ));
249
+ const a = await l(e, s), u = await P(i, a, r);
250
+ s.json(u);
251
+ } catch (r) {
252
+ console.error("Load error:", r), s.status(500).json(n(
253
+ r instanceof Error ? r.message : "Query execution failed",
254
+ 500
255
+ ));
256
+ }
257
+ });
258
+ }
259
+ return c.use((o, t, e, s) => {
260
+ console.error("Express adapter error:", o), e.headersSent || e.status(500).json(n(o, 500));
198
261
  }), c;
199
262
  }
200
- function M(f, d) {
201
- const p = N(d);
202
- return f.use("/", p), f;
263
+ function B(f, y) {
264
+ const j = A(y);
265
+ return f.use("/", j), f;
203
266
  }
204
- function J(f) {
205
- const d = h();
206
- return M(d, f);
267
+ function _(f) {
268
+ const y = h();
269
+ return B(y, f);
207
270
  }
208
271
  export {
209
- J as createCubeApp,
210
- N as createCubeRouter,
211
- M as mountCubeRoutes
272
+ _ as createCubeApp,
273
+ A as createCubeRouter,
274
+ B as mountCubeRoutes
212
275
  };
@@ -1 +1 @@
1
- "use strict";var w=Object.create;var E=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var $=Object.getPrototypeOf,P=Object.prototype.hasOwnProperty;var L=(u,s,g,b)=>{if(s&&typeof s=="object"||typeof s=="function")for(let y of j(s))!P.call(u,y)&&y!==g&&E(u,y,{get:()=>s[y],enumerable:!(b=S(s,y))||b.enumerable});return u};var M=(u,s,g)=>(g=u!=null?w($(u)):{},L(s||!u||!u.__esModule?E(g,"default",{value:u,enumerable:!0}):g,u));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../compiler-CO13DaEb.cjs"),h=function(s,g,b){const{cubes:y,drizzle:q,schema:x,extractSecurityContext:p,engineType:C,cors:R,basePath:l="/cubejs-api/v1",bodyLimit:f=10485760,cache:v}=g;if(!y||y.length===0)return b(new Error("At least one cube must be provided in the cubes array"));R&&s.register(import("@fastify/cors"),R),s.addHook("onRequest",async(r,t)=>{r.method==="POST"&&(r.body=void 0)});const n=new a.SemanticLayerCompiler({drizzle:q,schema:x,engineType:C,cache:v});y.forEach(r=>{n.registerCube(r)}),s.post(`${l}/load`,{bodyLimit:f,schema:{body:{type:"object",additionalProperties:!0}}},async(r,t)=>{try{const e=r.body,o=e.query||e,i=await p(r),c=n.validateQuery(o);if(!c.isValid)return t.status(400).send(a.formatErrorResponse(`Query validation failed: ${c.errors.join(", ")}`,400));const d=r.headers["x-cache-control"]==="no-cache",m=await n.executeMultiCubeQuery(o,i,{skipCache:d});return a.formatCubeResponse(o,m,n)}catch(e){return r.log.error(e,"Query execution error"),t.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),s.get(`${l}/load`,{schema:{querystring:{type:"object",properties:{query:{type:"string"}},required:["query"]}}},async(r,t)=>{try{const{query:e}=r.query;let o;try{o=JSON.parse(e)}catch{return t.status(400).send(a.formatErrorResponse("Invalid JSON in query parameter",400))}const i=await p(r),c=n.validateQuery(o);if(!c.isValid)return t.status(400).send(a.formatErrorResponse(`Query validation failed: ${c.errors.join(", ")}`,400));const d=r.headers["x-cache-control"]==="no-cache",m=await n.executeMultiCubeQuery(o,i,{skipCache:d});return a.formatCubeResponse(o,m,n)}catch(e){return r.log.error(e,"Query execution error"),t.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),s.post(`${l}/batch`,{bodyLimit:f,schema:{body:{type:"object",required:["queries"],properties:{queries:{type:"array",items:{type:"object"}}}}}},async(r,t)=>{try{const{queries:e}=r.body;if(!e||!Array.isArray(e))return t.status(400).send(a.formatErrorResponse('Request body must contain a "queries" array',400));if(e.length===0)return t.status(400).send(a.formatErrorResponse("Queries array cannot be empty",400));const o=await p(r),i=r.headers["x-cache-control"]==="no-cache";return await a.handleBatchRequest(e,o,n,{skipCache:i})}catch(e){return r.log.error(e,"Batch execution error"),t.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Batch execution failed",500))}}),s.get(`${l}/meta`,async(r,t)=>{try{const e=n.getMetadata();return a.formatMetaResponse(e)}catch(e){return r.log.error(e,"Metadata error"),t.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Failed to fetch metadata",500))}}),s.post(`${l}/sql`,{bodyLimit:f,schema:{body:{type:"object",additionalProperties:!0}}},async(r,t)=>{try{const e=r.body,o=await p(r),i=n.validateQuery(e);if(!i.isValid)return t.status(400).send(a.formatErrorResponse(`Query validation failed: ${i.errors.join(", ")}`,400));const c=e.measures?.[0]||e.dimensions?.[0];if(!c)return t.status(400).send(a.formatErrorResponse("No measures or dimensions specified",400));const d=c.split(".")[0],m=await n.generateSQL(d,e,o);return a.formatSqlResponse(e,m)}catch(e){return r.log.error(e,"SQL generation error"),t.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),s.get(`${l}/sql`,{schema:{querystring:{type:"object",properties:{query:{type:"string"}},required:["query"]}}},async(r,t)=>{try{const{query:e}=r.query,o=JSON.parse(e),i=await p(r),c=n.validateQuery(o);if(!c.isValid)return t.status(400).send(a.formatErrorResponse(`Query validation failed: ${c.errors.join(", ")}`,400));const d=o.measures?.[0]||o.dimensions?.[0];if(!d)return t.status(400).send(a.formatErrorResponse("No measures or dimensions specified",400));const m=d.split(".")[0],Q=await n.generateSQL(m,o,i);return a.formatSqlResponse(o,Q)}catch(e){return r.log.error(e,"SQL generation error"),t.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),s.post(`${l}/dry-run`,{bodyLimit:f,schema:{body:{type:"object",additionalProperties:!0}}},async(r,t)=>{try{const e=r.body,o=e.query||e,i=await p(r);return await a.handleDryRun(o,i,n)}catch(e){return r.log.error(e,"Dry-run error"),t.status(400).send({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),s.get(`${l}/dry-run`,{schema:{querystring:{type:"object",properties:{query:{type:"string"}},required:["query"]}}},async(r,t)=>{try{const{query:e}=r.query,o=JSON.parse(e),i=await p(r);return await a.handleDryRun(o,i,n)}catch(e){return r.log.error(e,"Dry-run error"),t.status(400).send({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),s.post(`${l}/explain`,{bodyLimit:f,schema:{body:{type:"object",additionalProperties:!0}}},async(r,t)=>{try{const e=r.body,o=e.query||e,i=e.options||{},c=await p(r),d=n.validateQuery(o);return d.isValid?await n.explainQuery(o,c,i):t.status(400).send({error:`Query validation failed: ${d.errors.join(", ")}`})}catch(e){return r.log.error(e,"Explain error"),t.status(500).send({error:e instanceof Error?e.message:"Explain query failed"})}}),s.setErrorHandler(async(r,t,e)=>{t.log.error(r,"Fastify cube adapter error"),e.statusCode<400&&e.status(500);const o=r instanceof Error?r:String(r);return a.formatErrorResponse(o,e.statusCode)}),b()};async function N(u,s){await u.register(h,s)}function A(u){const s=require("fastify")({logger:!0});return s.register(h,u),s}exports.createCubeApp=A;exports.cubePlugin=h;exports.registerCubeRoutes=N;
1
+ "use strict";var j=Object.create;var v=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,L=Object.prototype.hasOwnProperty;var D=(u,n,b,h)=>{if(n&&typeof n=="object"||typeof n=="function")for(let y of S(n))!L.call(u,y)&&y!==b&&v(u,y,{get:()=>n[y],enumerable:!(h=$(n,y))||h.enumerable});return u};var M=(u,n,b)=>(b=u!=null?j(P(u)):{},D(n||!u||!u.__esModule?v(b,"default",{value:u,enumerable:!0}):b,u));Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("../validation-Bgauxvm6.cjs"),E=function(n,b,h){const{cubes:y,drizzle:q,schema:x,extractSecurityContext:l,engineType:Q,cors:R,basePath:p="/cubejs-api/v1",bodyLimit:m=10485760,cache:C,mcp:f={enabled:!0}}=b;if(!y||y.length===0)return h(new Error("At least one cube must be provided in the cubes array"));R&&n.register(import("@fastify/cors"),R),n.addHook("onRequest",async(r,o)=>{r.method==="POST"&&(r.body=void 0)});const i=new a.SemanticLayerCompiler({drizzle:q,schema:x,engineType:Q,cache:C});if(y.forEach(r=>{i.registerCube(r)}),n.post(`${p}/load`,{bodyLimit:m,schema:{body:{type:"object",additionalProperties:!0}}},async(r,o)=>{try{const e=r.body,s=e.query||e,t=await l(r),c=i.validateQuery(s);if(!c.isValid)return o.status(400).send(a.formatErrorResponse(`Query validation failed: ${c.errors.join(", ")}`,400));const d=r.headers["x-cache-control"]==="no-cache",g=await i.executeMultiCubeQuery(s,t,{skipCache:d});return a.formatCubeResponse(s,g,i)}catch(e){return r.log.error(e,"Query execution error"),o.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),n.get(`${p}/load`,{schema:{querystring:{type:"object",properties:{query:{type:"string"}},required:["query"]}}},async(r,o)=>{try{const{query:e}=r.query;let s;try{s=JSON.parse(e)}catch{return o.status(400).send(a.formatErrorResponse("Invalid JSON in query parameter",400))}const t=await l(r),c=i.validateQuery(s);if(!c.isValid)return o.status(400).send(a.formatErrorResponse(`Query validation failed: ${c.errors.join(", ")}`,400));const d=r.headers["x-cache-control"]==="no-cache",g=await i.executeMultiCubeQuery(s,t,{skipCache:d});return a.formatCubeResponse(s,g,i)}catch(e){return r.log.error(e,"Query execution error"),o.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Query execution failed",500))}}),n.post(`${p}/batch`,{bodyLimit:m,schema:{body:{type:"object",required:["queries"],properties:{queries:{type:"array",items:{type:"object"}}}}}},async(r,o)=>{try{const{queries:e}=r.body;if(!e||!Array.isArray(e))return o.status(400).send(a.formatErrorResponse('Request body must contain a "queries" array',400));if(e.length===0)return o.status(400).send(a.formatErrorResponse("Queries array cannot be empty",400));const s=await l(r),t=r.headers["x-cache-control"]==="no-cache";return await a.handleBatchRequest(e,s,i,{skipCache:t})}catch(e){return r.log.error(e,"Batch execution error"),o.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Batch execution failed",500))}}),n.get(`${p}/meta`,async(r,o)=>{try{const e=i.getMetadata();return a.formatMetaResponse(e)}catch(e){return r.log.error(e,"Metadata error"),o.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"Failed to fetch metadata",500))}}),n.post(`${p}/sql`,{bodyLimit:m,schema:{body:{type:"object",additionalProperties:!0}}},async(r,o)=>{try{const e=r.body,s=await l(r),t=i.validateQuery(e);if(!t.isValid)return o.status(400).send(a.formatErrorResponse(`Query validation failed: ${t.errors.join(", ")}`,400));const c=e.measures?.[0]||e.dimensions?.[0];if(!c)return o.status(400).send(a.formatErrorResponse("No measures or dimensions specified",400));const d=c.split(".")[0],g=await i.generateSQL(d,e,s);return a.formatSqlResponse(e,g)}catch(e){return r.log.error(e,"SQL generation error"),o.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),n.get(`${p}/sql`,{schema:{querystring:{type:"object",properties:{query:{type:"string"}},required:["query"]}}},async(r,o)=>{try{const{query:e}=r.query,s=JSON.parse(e),t=await l(r),c=i.validateQuery(s);if(!c.isValid)return o.status(400).send(a.formatErrorResponse(`Query validation failed: ${c.errors.join(", ")}`,400));const d=s.measures?.[0]||s.dimensions?.[0];if(!d)return o.status(400).send(a.formatErrorResponse("No measures or dimensions specified",400));const g=d.split(".")[0],w=await i.generateSQL(g,s,t);return a.formatSqlResponse(s,w)}catch(e){return r.log.error(e,"SQL generation error"),o.status(500).send(a.formatErrorResponse(e instanceof Error?e.message:"SQL generation failed",500))}}),n.post(`${p}/dry-run`,{bodyLimit:m,schema:{body:{type:"object",additionalProperties:!0}}},async(r,o)=>{try{const e=r.body,s=e.query||e,t=await l(r);return await a.handleDryRun(s,t,i)}catch(e){return r.log.error(e,"Dry-run error"),o.status(400).send({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),n.get(`${p}/dry-run`,{schema:{querystring:{type:"object",properties:{query:{type:"string"}},required:["query"]}}},async(r,o)=>{try{const{query:e}=r.query,s=JSON.parse(e),t=await l(r);return await a.handleDryRun(s,t,i)}catch(e){return r.log.error(e,"Dry-run error"),o.status(400).send({error:e instanceof Error?e.message:"Dry-run validation failed",valid:!1})}}),n.post(`${p}/explain`,{bodyLimit:m,schema:{body:{type:"object",additionalProperties:!0}}},async(r,o)=>{try{const e=r.body,s=e.query||e,t=e.options||{},c=await l(r),d=i.validateQuery(s);return d.isValid?await i.explainQuery(s,c,t):o.status(400).send({error:`Query validation failed: ${d.errors.join(", ")}`})}catch(e){return r.log.error(e,"Explain error"),o.status(500).send({error:e instanceof Error?e.message:"Explain query failed"})}}),f.enabled!==!1){const r=f.tools||["discover","suggest","validate","load"],o=f.basePath??"/mcp";r.includes("discover")&&n.post(`${o}/discover`,{bodyLimit:m,schema:{body:{type:"object",additionalProperties:!0}}},async(e,s)=>{try{const t=e.body;return await a.handleDiscover(i,t)}catch(t){return e.log.error(t,"Discover error"),s.status(500).send(a.formatErrorResponse(t instanceof Error?t.message:"Discovery failed",500))}}),r.includes("suggest")&&n.post(`${o}/suggest`,{bodyLimit:m,schema:{body:{type:"object",required:["naturalLanguage"],properties:{naturalLanguage:{type:"string"},cube:{type:"string"}}}}},async(e,s)=>{try{const t=e.body;return await a.handleSuggest(i,t)}catch(t){return e.log.error(t,"Suggest error"),s.status(500).send(a.formatErrorResponse(t instanceof Error?t.message:"Query suggestion failed",500))}}),r.includes("validate")&&n.post(`${o}/validate`,{bodyLimit:m,schema:{body:{type:"object",required:["query"],properties:{query:{type:"object"}}}}},async(e,s)=>{try{const t=e.body;return await a.handleValidate(i,t)}catch(t){return e.log.error(t,"Validate error"),s.status(500).send(a.formatErrorResponse(t instanceof Error?t.message:"Query validation failed",500))}}),r.includes("load")&&n.post(`${o}/load`,{bodyLimit:m,schema:{body:{type:"object",required:["query"],properties:{query:{type:"object"}}}}},async(e,s)=>{try{const t=e.body,c=await l(e);return await a.handleLoad(i,c,t)}catch(t){return e.log.error(t,"Load error"),s.status(500).send(a.formatErrorResponse(t instanceof Error?t.message:"Query execution failed",500))}})}n.setErrorHandler(async(r,o,e)=>{o.log.error(r,"Fastify cube adapter error"),e.statusCode<400&&e.status(500);const s=r instanceof Error?r:String(r);return a.formatErrorResponse(s,e.statusCode)}),h()};async function N(u,n){await u.register(E,n)}function V(u){const n=require("fastify")({logger:!0});return n.register(E,u),n}exports.createCubeApp=V;exports.cubePlugin=E;exports.registerCubeRoutes=N;
@@ -4,6 +4,7 @@ import { SemanticQuery, SecurityContext, DatabaseExecutor, DrizzleDatabase, Cube
4
4
  import { PostgresJsDatabase } from 'drizzle-orm/postgres-js';
5
5
  import { MySql2Database } from 'drizzle-orm/mysql2';
6
6
  import { BetterSQLite3Database } from 'drizzle-orm/better-sqlite3';
7
+ import { MCPOptions } from '../utils';
7
8
  export interface FastifyAdapterOptions {
8
9
  /**
9
10
  * Array of cube definitions to register
@@ -47,7 +48,7 @@ export interface FastifyAdapterOptions {
47
48
  /**
48
49
  * Database engine type (optional - auto-detected if not provided)
49
50
  */
50
- engineType?: 'postgres' | 'mysql' | 'sqlite';
51
+ engineType?: 'postgres' | 'mysql' | 'sqlite' | 'singlestore' | 'duckdb';
51
52
  /**
52
53
  * CORS configuration (optional)
53
54
  */
@@ -65,6 +66,12 @@ export interface FastifyAdapterOptions {
65
66
  * When provided, query results will be cached using the specified provider
66
67
  */
67
68
  cache?: CacheConfig;
69
+ /**
70
+ * MCP (AI-Ready) endpoint configuration
71
+ * Enables AI agents to discover and query your data
72
+ * @default { enabled: true }
73
+ */
74
+ mcp?: MCPOptions;
68
75
  }
69
76
  /**
70
77
  * Fastify plugin for Cube.js-compatible API