drizzle-cube 0.7.1 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (363) hide show
  1. package/dist/adapters/ActivityGridChart.config-DXUUgx0N.cjs +1 -0
  2. package/dist/adapters/ActivityGridChart.config-Dyozu3VW.js +2 -0
  3. package/dist/adapters/AreaChart.config-Di5odBXp.cjs +1 -0
  4. package/dist/adapters/AreaChart.config-KEaXP_4K.js +2 -0
  5. package/dist/adapters/BarChart.config-B-hBHykR.cjs +1 -0
  6. package/dist/adapters/BarChart.config-C5sqbn0A.js +2 -0
  7. package/dist/adapters/BoxPlotChart.config-B1R4Br7L.js +2 -0
  8. package/dist/adapters/BoxPlotChart.config-C82Fhd3c.cjs +1 -0
  9. package/dist/adapters/BubbleChart.config-CoBxmmfp.js +2 -0
  10. package/dist/adapters/BubbleChart.config-DfOnNjL-.cjs +1 -0
  11. package/dist/adapters/CandlestickChart.config-C5ggV_3j.cjs +1 -0
  12. package/dist/adapters/CandlestickChart.config-ZaJpWVuL.js +2 -0
  13. package/dist/adapters/DataTable.config-Cx2_ACdY.cjs +1 -0
  14. package/dist/adapters/DataTable.config-DkAgD-iz.js +2 -0
  15. package/dist/adapters/FunnelChart.config-CvzcECUB.js +2 -0
  16. package/dist/adapters/FunnelChart.config-DVH7IFnb.cjs +1 -0
  17. package/dist/adapters/GaugeChart.config-Csx8rt8o.cjs +1 -0
  18. package/dist/adapters/GaugeChart.config-DEmrNgMa.js +2 -0
  19. package/dist/adapters/HeatMapChart.config-BfD_dpP7.js +2 -0
  20. package/dist/adapters/HeatMapChart.config-D_jlyPJL.cjs +1 -0
  21. package/dist/adapters/KpiDelta.config-CVBdUL_n.cjs +1 -0
  22. package/dist/adapters/KpiDelta.config-D4dCXOxl.js +2 -0
  23. package/dist/adapters/KpiNumber.config-BK5pgIKz.cjs +1 -0
  24. package/dist/adapters/KpiNumber.config-D6XqjZrm.js +2 -0
  25. package/dist/adapters/KpiText.config-ChphMwG5.js +2 -0
  26. package/dist/adapters/KpiText.config-fO1wc6FH.cjs +1 -0
  27. package/dist/adapters/LineChart.config-CXJrgz1s.js +2 -0
  28. package/dist/adapters/LineChart.config-Cg_h-SiJ.cjs +1 -0
  29. package/dist/adapters/MarkdownChart.config-ByPjX-4O.cjs +1 -0
  30. package/dist/adapters/MarkdownChart.config-Df2yY9AT.js +2 -0
  31. package/dist/adapters/MeasureProfileChart.config-BBWGIteF.cjs +1 -0
  32. package/dist/adapters/MeasureProfileChart.config-C9OFbN9Z.js +2 -0
  33. package/dist/adapters/PieChart.config-C6jJj6xm.js +2 -0
  34. package/dist/adapters/PieChart.config-CmCw_8eN.cjs +1 -0
  35. package/dist/adapters/ProportionBarChart.config-B9NEyFEe.js +2 -0
  36. package/dist/adapters/ProportionBarChart.config-C3GAVPWn.cjs +1 -0
  37. package/dist/adapters/RadarChart.config-5AMwEqUJ.cjs +1 -0
  38. package/dist/adapters/RadarChart.config-Ct_b7IM5.js +2 -0
  39. package/dist/adapters/RadialBarChart.config-Bp-Sl0cm.js +2 -0
  40. package/dist/adapters/RadialBarChart.config-D14yoexI.cjs +1 -0
  41. package/dist/adapters/RecordsTable.config-D2-qmG06.cjs +1 -0
  42. package/dist/adapters/RecordsTable.config-DIwoqZCU.js +2 -0
  43. package/dist/adapters/RetentionCombinedChart.config-BWHipi5M.cjs +1 -0
  44. package/dist/adapters/RetentionCombinedChart.config-D40UgTcl.js +2 -0
  45. package/dist/adapters/RetentionHeatmap.config-GlnSLrjn.js +2 -0
  46. package/dist/adapters/RetentionHeatmap.config-MlhZf26c.cjs +1 -0
  47. package/dist/adapters/SankeyChart.config-Bf1_NHiv.js +2 -0
  48. package/dist/adapters/SankeyChart.config-BoYf6BFE.cjs +1 -0
  49. package/dist/adapters/ScatterChart.config-CV2rdGJp.js +2 -0
  50. package/dist/adapters/ScatterChart.config-DywduGF3.cjs +1 -0
  51. package/dist/adapters/SunburstChart.config-CrqiE1UZ.js +2 -0
  52. package/dist/adapters/SunburstChart.config-D5tbF_GJ.cjs +1 -0
  53. package/dist/adapters/TreeMapChart.config-BJ8HnZU0.cjs +1 -0
  54. package/dist/adapters/TreeMapChart.config-DxgIqIIj.js +2 -0
  55. package/dist/adapters/WaterfallChart.config-Cns8fLFu.js +2 -0
  56. package/dist/adapters/WaterfallChart.config-D_kdL9SN.cjs +1 -0
  57. package/dist/adapters/compiler-BxZHh0UD.cjs +166 -0
  58. package/dist/adapters/{compiler-DiYxWAKg.js → compiler-CBGD_4Et.js} +1389 -1923
  59. package/dist/adapters/core/http-port.d.ts +34 -7
  60. package/dist/adapters/core/index.cjs +1 -1
  61. package/dist/adapters/core/index.d.ts +1 -0
  62. package/dist/adapters/core/index.js +2 -2
  63. package/dist/adapters/core/rest-handlers.d.ts +1 -1
  64. package/dist/adapters/core-CIGuwGuI.cjs +1 -0
  65. package/dist/adapters/{core-BOPRmxPc.js → core-DAAnqPyN.js} +81 -65
  66. package/dist/adapters/express/index.cjs +2 -2
  67. package/dist/adapters/express/index.d.ts +11 -2
  68. package/dist/adapters/express/index.js +14 -14
  69. package/dist/adapters/fastify/index.cjs +2 -2
  70. package/dist/adapters/fastify/index.d.ts +11 -2
  71. package/dist/adapters/fastify/index.js +29 -29
  72. package/dist/{server/google-eKAc20al.js → adapters/google-DRY7jnOh.js} +46 -28
  73. package/dist/adapters/{google-BhvizbFR.cjs → google-PsZzwedr.cjs} +2 -2
  74. package/dist/adapters/handler-BcYTw6zB.cjs +25 -0
  75. package/dist/adapters/{handler-DGud-C-w.js → handler-eA0VJDHj.js} +363 -266
  76. package/dist/adapters/hono/index.cjs +1 -1
  77. package/dist/adapters/hono/index.js +9 -9
  78. package/dist/adapters/mcp-tools-handlers.d.ts +10 -3
  79. package/dist/adapters/mcp-tools.cjs +1 -1
  80. package/dist/adapters/mcp-tools.js +18 -20
  81. package/dist/adapters/mcp-transport-BpG44Fvn.js +730 -0
  82. package/dist/adapters/mcp-transport-CDxZXpc-.cjs +42 -0
  83. package/dist/adapters/mcp-transport.d.ts +13 -2
  84. package/dist/adapters/nextjs/index.cjs +1 -1
  85. package/dist/adapters/nextjs/index.d.ts +5 -2
  86. package/dist/adapters/nextjs/index.js +32 -32
  87. package/dist/adapters/{openai-Crp3X_zg.js → openai-BZ48ioYp.js} +1 -1
  88. package/dist/adapters/{openai-CmdN7Sj1.cjs → openai-Bw1j-OiP.cjs} +1 -1
  89. package/dist/adapters/{openai-Dwt9bxOE.cjs → openai-CLjyL5_J.cjs} +2 -2
  90. package/dist/adapters/{openai-CGJM6Qun.js → openai-CYYjUG_3.js} +4 -4
  91. package/dist/adapters/{utils-DboNUT3A.js → utils-BagURNRb.js} +1963 -1135
  92. package/dist/adapters/utils-BiKIg2tk.cjs +128 -0
  93. package/dist/adapters/utils.cjs +1 -1
  94. package/dist/adapters/utils.d.ts +19 -5
  95. package/dist/adapters/utils.js +1 -1
  96. package/dist/cjs/adapters/core/http-port.d.ts +34 -7
  97. package/dist/cjs/adapters/core/index.d.ts +1 -0
  98. package/dist/cjs/adapters/core/rest-handlers.d.ts +1 -1
  99. package/dist/cjs/adapters/express/index.d.ts +11 -2
  100. package/dist/cjs/adapters/fastify/index.d.ts +11 -2
  101. package/dist/cjs/adapters/mcp-tools-handlers.d.ts +10 -3
  102. package/dist/cjs/adapters/mcp-transport.d.ts +13 -2
  103. package/dist/cjs/adapters/nextjs/index.d.ts +5 -2
  104. package/dist/cjs/adapters/utils.d.ts +19 -5
  105. package/dist/cjs/client/charts/chartConfigRegistry.d.ts +7 -0
  106. package/dist/cjs/client/charts/chartConfigs.d.ts +17 -1
  107. package/dist/cjs/client/client/CubeClient.d.ts +11 -1
  108. package/dist/cjs/client/components/AnalysisBuilder/AnalysisDisplayConfigPanel.d.ts +4 -2
  109. package/dist/cjs/client/components/AnalysisBuilder/ColumnFormatsEditor.d.ts +10 -0
  110. package/dist/cjs/client/components/AnalysisBuilder/DisplayOptionControl.d.ts +3 -2
  111. package/dist/cjs/client/components/AnalysisBuilder/utils/queryUtils.d.ts +7 -1
  112. package/dist/cjs/client/components/analyticsPortlet/PortletChart.d.ts +2 -1
  113. package/dist/cjs/client/components/analyticsPortlet/PortletChartView.d.ts +4 -1
  114. package/dist/cjs/client/components/analyticsPortlet/usePortletDeadMembers.d.ts +24 -0
  115. package/dist/cjs/client/components/analyticsPortlet/usePortletPagination.d.ts +21 -0
  116. package/dist/cjs/client/components/charts/RecordsTable.config.d.ts +10 -0
  117. package/dist/cjs/client/components/charts/RecordsTable.d.ts +4 -0
  118. package/dist/cjs/client/components/charts/recordsTableHooks.d.ts +68 -0
  119. package/dist/cjs/client/icons/types.d.ts +1 -0
  120. package/dist/cjs/client/index.d.ts +2 -2
  121. package/dist/cjs/client/types.d.ts +92 -1
  122. package/dist/cjs/client/utils/recordsTableUtils.d.ts +71 -0
  123. package/dist/cjs/client/utils/rowLinkUtils.d.ts +35 -0
  124. package/dist/cjs/server/adapters/base-adapter.d.ts +46 -0
  125. package/dist/cjs/server/adapters/databend-adapter.d.ts +5 -0
  126. package/dist/cjs/server/adapters/duckdb-adapter.d.ts +5 -0
  127. package/dist/cjs/server/adapters/mysql-adapter.d.ts +14 -0
  128. package/dist/cjs/server/adapters/postgres-adapter.d.ts +15 -0
  129. package/dist/cjs/server/adapters/snowflake-adapter.d.ts +6 -0
  130. package/dist/cjs/server/adapters/sqlite-adapter.d.ts +21 -0
  131. package/dist/cjs/server/agent/chart-validation.d.ts +1 -1
  132. package/dist/cjs/server/ai/chart-schema.d.ts +117 -0
  133. package/dist/cjs/server/ai/discovery-helpers.d.ts +14 -0
  134. package/dist/cjs/server/ai/discovery.d.ts +6 -0
  135. package/dist/cjs/server/ai/query-schema.d.ts +1 -1
  136. package/dist/cjs/server/attribute-dimensions.d.ts +102 -0
  137. package/dist/cjs/server/builders/group-by-builder.d.ts +15 -0
  138. package/dist/cjs/server/cache-utils.d.ts +5 -1
  139. package/dist/cjs/server/compiler-metadata.d.ts +24 -3
  140. package/dist/cjs/server/compiler.d.ts +159 -13
  141. package/dist/cjs/server/execution/query-result-cache.d.ts +1 -1
  142. package/dist/cjs/server/executor.d.ts +15 -0
  143. package/dist/cjs/server/index.d.ts +13 -3
  144. package/dist/cjs/server/query-handlers.d.ts +2 -1
  145. package/dist/cjs/server/query-validator.d.ts +36 -4
  146. package/dist/cjs/server/types/core.d.ts +13 -0
  147. package/dist/cjs/server/types/cube.d.ts +39 -2
  148. package/dist/cjs/server/types/query.d.ts +8 -0
  149. package/dist/cli/index.cjs +130 -52
  150. package/dist/client/charts/chartConfigRegistry.d.ts +7 -0
  151. package/dist/client/charts/chartConfigs.d.ts +17 -1
  152. package/dist/client/charts.js +13 -13
  153. package/dist/client/chunks/{DashboardEditModal-BOfLdTgV.js → DashboardEditModal-_ZDMwaGX.js} +1653 -1188
  154. package/dist/client/chunks/DashboardEditModal-_ZDMwaGX.js.map +1 -0
  155. package/dist/client/chunks/{ProportionBarChart-DwoXU5VP.js → ProportionBarChart-qfpAWhIg.js} +3 -3
  156. package/dist/client/chunks/{ProportionBarChart-DwoXU5VP.js.map → ProportionBarChart-qfpAWhIg.js.map} +1 -1
  157. package/dist/client/chunks/RecordsTable-KmJy94xN.js +556 -0
  158. package/dist/client/chunks/RecordsTable-KmJy94xN.js.map +1 -0
  159. package/dist/client/chunks/{RetentionCombinedChart-BqlSV7yF.js → RetentionCombinedChart-C7X6aj97.js} +3 -3
  160. package/dist/client/chunks/{RetentionCombinedChart-BqlSV7yF.js.map → RetentionCombinedChart-C7X6aj97.js.map} +1 -1
  161. package/dist/client/chunks/{RetentionHeatmap-VdVkBg8Q.js → RetentionHeatmap-PpRpiqR_.js} +2 -2
  162. package/dist/client/chunks/{RetentionHeatmap-VdVkBg8Q.js.map → RetentionHeatmap-PpRpiqR_.js.map} +1 -1
  163. package/dist/client/chunks/{analysis-builder-DXw60SEs.js → analysis-builder-DaqyOjLX.js} +169 -168
  164. package/dist/client/chunks/{analysis-builder-DXw60SEs.js.map → analysis-builder-DaqyOjLX.js.map} +1 -1
  165. package/dist/client/chunks/{analysis-builder-shared-CEvHIlmk.js → analysis-builder-shared-ow9KAHDP.js} +965 -954
  166. package/dist/client/chunks/analysis-builder-shared-ow9KAHDP.js.map +1 -0
  167. package/dist/client/chunks/{chart-activity-grid-4jfS8khG.js → chart-activity-grid-DO82rrbW.js} +140 -84
  168. package/dist/client/chunks/chart-activity-grid-DO82rrbW.js.map +1 -0
  169. package/dist/client/chunks/{chart-area-Dol6s9no.js → chart-area-9SBeG0GM.js} +21 -21
  170. package/dist/client/chunks/{chart-area-Dol6s9no.js.map → chart-area-9SBeG0GM.js.map} +1 -1
  171. package/dist/client/chunks/{chart-bar-5_niozi2.js → chart-bar-tfgmLK2D.js} +5 -5
  172. package/dist/client/chunks/{chart-bar-5_niozi2.js.map → chart-bar-tfgmLK2D.js.map} +1 -1
  173. package/dist/client/chunks/{chart-box-plot-Dhp-VwhD.js → chart-box-plot-BuYW6j6g.js} +2 -2
  174. package/dist/client/chunks/{chart-box-plot-Dhp-VwhD.js.map → chart-box-plot-BuYW6j6g.js.map} +1 -1
  175. package/dist/client/chunks/{chart-bubble-BM2BAMSo.js → chart-bubble-BNmonWqW.js} +2 -2
  176. package/dist/client/chunks/{chart-bubble-BM2BAMSo.js.map → chart-bubble-BNmonWqW.js.map} +1 -1
  177. package/dist/client/chunks/{chart-candlestick-BNwLIBfm.js → chart-candlestick-BYeWNkKl.js} +2 -2
  178. package/dist/client/chunks/{chart-candlestick-BNwLIBfm.js.map → chart-candlestick-BYeWNkKl.js.map} +1 -1
  179. package/dist/client/chunks/{chart-data-table-DoDHQRe7.js → chart-data-table-C_oHiK6N.js} +1094 -1029
  180. package/dist/client/chunks/chart-data-table-C_oHiK6N.js.map +1 -0
  181. package/dist/client/chunks/{chart-funnel-Cd7da_sa.js → chart-funnel-B_CWC3cL.js} +2 -2
  182. package/dist/client/chunks/{chart-funnel-Cd7da_sa.js.map → chart-funnel-B_CWC3cL.js.map} +1 -1
  183. package/dist/client/chunks/{chart-gauge-DOpul-Oz.js → chart-gauge-D7VxwPnx.js} +3 -3
  184. package/dist/client/chunks/{chart-gauge-DOpul-Oz.js.map → chart-gauge-D7VxwPnx.js.map} +1 -1
  185. package/dist/client/chunks/{chart-heat-map-CeKbK655.js → chart-heat-map-q7Vf_dog.js} +3 -3
  186. package/dist/client/chunks/{chart-heat-map-CeKbK655.js.map → chart-heat-map-q7Vf_dog.js.map} +1 -1
  187. package/dist/client/chunks/{chart-kpi-delta-Dq8qUOOT.js → chart-kpi-delta-PEuA3iGs.js} +3 -3
  188. package/dist/client/chunks/{chart-kpi-delta-Dq8qUOOT.js.map → chart-kpi-delta-PEuA3iGs.js.map} +1 -1
  189. package/dist/client/chunks/{chart-kpi-number-DgiqTi9g.js → chart-kpi-number-DlxrO6Pq.js} +5 -5
  190. package/dist/client/chunks/{chart-kpi-number-DgiqTi9g.js.map → chart-kpi-number-DlxrO6Pq.js.map} +1 -1
  191. package/dist/client/chunks/{chart-kpi-text-CsZMVEnM.js → chart-kpi-text-Cx6cJu2s.js} +3 -3
  192. package/dist/client/chunks/{chart-kpi-text-CsZMVEnM.js.map → chart-kpi-text-Cx6cJu2s.js.map} +1 -1
  193. package/dist/client/chunks/{chart-line-DlwOB7C7.js → chart-line-pDe25JzB.js} +3 -3
  194. package/dist/client/chunks/{chart-line-DlwOB7C7.js.map → chart-line-pDe25JzB.js.map} +1 -1
  195. package/dist/client/chunks/{chart-markdown-DPE34SjC.js → chart-markdown-CRY15yp0.js} +2 -2
  196. package/dist/client/chunks/{chart-markdown-DPE34SjC.js.map → chart-markdown-CRY15yp0.js.map} +1 -1
  197. package/dist/client/chunks/{chart-measure-profile-BpTz1fce.js → chart-measure-profile-DyQ-vvuC.js} +3 -3
  198. package/dist/client/chunks/{chart-measure-profile-BpTz1fce.js.map → chart-measure-profile-DyQ-vvuC.js.map} +1 -1
  199. package/dist/client/chunks/{chart-pie-FGw66XAH.js → chart-pie-ZrnBycy1.js} +15 -15
  200. package/dist/client/chunks/{chart-pie-FGw66XAH.js.map → chart-pie-ZrnBycy1.js.map} +1 -1
  201. package/dist/client/chunks/{chart-radar-D-eRDoiA.js → chart-radar-BXbnYMUJ.js} +13 -13
  202. package/dist/client/chunks/{chart-radar-D-eRDoiA.js.map → chart-radar-BXbnYMUJ.js.map} +1 -1
  203. package/dist/client/chunks/{chart-radial-bar-DgtkNTs3.js → chart-radial-bar-CYxH3ryh.js} +3 -3
  204. package/dist/client/chunks/{chart-radial-bar-DgtkNTs3.js.map → chart-radial-bar-CYxH3ryh.js.map} +1 -1
  205. package/dist/client/chunks/{chart-sankey-D0hhb_EQ.js → chart-sankey-C9R_TDDh.js} +2 -2
  206. package/dist/client/chunks/{chart-sankey-D0hhb_EQ.js.map → chart-sankey-C9R_TDDh.js.map} +1 -1
  207. package/dist/client/chunks/{chart-scatter-D9EcAiMQ.js → chart-scatter-DrwRkzzl.js} +3 -3
  208. package/dist/client/chunks/{chart-scatter-D9EcAiMQ.js.map → chart-scatter-DrwRkzzl.js.map} +1 -1
  209. package/dist/client/chunks/{chart-sunburst-DCYmJ5DU.js → chart-sunburst-Bs1yqIPp.js} +3 -3
  210. package/dist/client/chunks/{chart-sunburst-DCYmJ5DU.js.map → chart-sunburst-Bs1yqIPp.js.map} +1 -1
  211. package/dist/client/chunks/{chart-tree-map-D_ACSSiB.js → chart-tree-map-BNjHhhVq.js} +3 -3
  212. package/dist/client/chunks/{chart-tree-map-D_ACSSiB.js.map → chart-tree-map-BNjHhhVq.js.map} +1 -1
  213. package/dist/client/chunks/{chart-waterfall-CVUVNa1R.js → chart-waterfall-CyoC0uLT.js} +3 -3
  214. package/dist/client/chunks/{chart-waterfall-CVUVNa1R.js.map → chart-waterfall-CyoC0uLT.js.map} +1 -1
  215. package/dist/client/chunks/charts-core-DCQ7od_L.js +190 -0
  216. package/dist/client/chunks/charts-core-DCQ7od_L.js.map +1 -0
  217. package/dist/client/chunks/charts-loader-Bya_zDIA.js +86 -0
  218. package/dist/client/chunks/charts-loader-Bya_zDIA.js.map +1 -0
  219. package/dist/client/chunks/{en-US-BE6VoG0o.js → en-US-HP6FHuNy.js} +3 -1
  220. package/dist/client/chunks/{en-US-BE6VoG0o.js.map → en-US-HP6FHuNy.js.map} +1 -1
  221. package/dist/client/chunks/{exceljs.min-DWC_b8G9.js → exceljs.min-CiByP8VQ.js} +2 -3
  222. package/dist/client/chunks/{exceljs.min-DWC_b8G9.js.map → exceljs.min-CiByP8VQ.js.map} +1 -1
  223. package/dist/client/chunks/{nl-NL-DFLVORiD.js → nl-NL-CEdoCz6Q.js} +54 -1
  224. package/dist/client/chunks/nl-NL-CEdoCz6Q.js.map +1 -0
  225. package/dist/client/chunks/{schema-visualization-C6g_LCiA.js → schema-visualization-DfXxFBIY.js} +3 -3
  226. package/dist/client/chunks/{schema-visualization-C6g_LCiA.js.map → schema-visualization-DfXxFBIY.js.map} +1 -1
  227. package/dist/client/chunks/{useDirtyStateTracking-ZfChDEd3.js → useDirtyStateTracking-BFJHiiVK.js} +15 -15
  228. package/dist/client/chunks/{useDirtyStateTracking-ZfChDEd3.js.map → useDirtyStateTracking-BFJHiiVK.js.map} +1 -1
  229. package/dist/client/chunks/{useExplainAI-im9e1rVb.js → useExplainAI-_C4WQE5I.js} +16 -16
  230. package/dist/client/chunks/{useExplainAI-im9e1rVb.js.map → useExplainAI-_C4WQE5I.js.map} +1 -1
  231. package/dist/client/chunks/{vendor-Qa1s8oSX.js → vendor-Gb3lH0cc.js} +49 -49
  232. package/dist/client/chunks/vendor-Gb3lH0cc.js.map +1 -0
  233. package/dist/client/client/CubeClient.d.ts +11 -1
  234. package/dist/client/components/AnalysisBuilder/AnalysisDisplayConfigPanel.d.ts +4 -2
  235. package/dist/client/components/AnalysisBuilder/ColumnFormatsEditor.d.ts +10 -0
  236. package/dist/client/components/AnalysisBuilder/DisplayOptionControl.d.ts +3 -2
  237. package/dist/client/components/AnalysisBuilder/utils/queryUtils.d.ts +7 -1
  238. package/dist/client/components/analyticsPortlet/PortletChart.d.ts +2 -1
  239. package/dist/client/components/analyticsPortlet/PortletChartView.d.ts +4 -1
  240. package/dist/client/components/analyticsPortlet/usePortletDeadMembers.d.ts +24 -0
  241. package/dist/client/components/analyticsPortlet/usePortletPagination.d.ts +21 -0
  242. package/dist/client/components/charts/RecordsTable.config.d.ts +10 -0
  243. package/dist/client/components/charts/RecordsTable.d.ts +4 -0
  244. package/dist/client/components/charts/recordsTableHooks.d.ts +68 -0
  245. package/dist/client/components.js +1 -1
  246. package/dist/client/hooks.js +3 -3
  247. package/dist/client/icons/types.d.ts +1 -0
  248. package/dist/client/icons.js +2 -2
  249. package/dist/client/index.d.ts +2 -2
  250. package/dist/client/index.js +213 -213
  251. package/dist/client/providers.js +1 -1
  252. package/dist/client/schema.js +1 -1
  253. package/dist/client/styles.css +1 -1
  254. package/dist/client/types.d.ts +92 -1
  255. package/dist/client/utils/recordsTableUtils.d.ts +71 -0
  256. package/dist/client/utils/rowLinkUtils.d.ts +35 -0
  257. package/dist/client/utils.js +14 -14
  258. package/dist/client-bundle-stats.html +1 -1
  259. package/dist/mcp-app/mcp-app.html +109 -109
  260. package/dist/server/adapters/base-adapter.d.ts +46 -0
  261. package/dist/server/adapters/databend-adapter.d.ts +5 -0
  262. package/dist/server/adapters/duckdb-adapter.d.ts +5 -0
  263. package/dist/server/adapters/mysql-adapter.d.ts +14 -0
  264. package/dist/server/adapters/postgres-adapter.d.ts +15 -0
  265. package/dist/server/adapters/snowflake-adapter.d.ts +6 -0
  266. package/dist/server/adapters/sqlite-adapter.d.ts +21 -0
  267. package/dist/server/agent/chart-validation.d.ts +1 -1
  268. package/dist/server/ai/chart-schema.d.ts +117 -0
  269. package/dist/server/ai/discovery-helpers.d.ts +14 -0
  270. package/dist/server/ai/discovery.d.ts +6 -0
  271. package/dist/server/ai/query-schema.d.ts +1 -1
  272. package/dist/server/attribute-dimensions.d.ts +102 -0
  273. package/dist/server/builders/group-by-builder.d.ts +15 -0
  274. package/dist/server/cache-utils.d.ts +5 -1
  275. package/dist/server/compiler-metadata.d.ts +24 -3
  276. package/dist/server/compiler.d.ts +159 -13
  277. package/dist/server/execution/query-result-cache.d.ts +1 -1
  278. package/dist/server/executor.d.ts +15 -0
  279. package/dist/{adapters/google-eKAc20al.js → server/google-DRY7jnOh.js} +46 -28
  280. package/dist/server/{google-BhvizbFR.cjs → google-PsZzwedr.cjs} +2 -2
  281. package/dist/server/index.cjs +42 -38
  282. package/dist/server/index.d.ts +13 -3
  283. package/dist/server/index.js +2079 -1573
  284. package/dist/server/{openai-Czk1BdHa.js → openai-6uUf7h-5.js} +1 -1
  285. package/dist/server/{openai-DBwI1OSu.cjs → openai-BBe1XbZd.cjs} +1 -1
  286. package/dist/server/{openai-Cu4TXXjl.cjs → openai-BmADmD1e.cjs} +1 -1
  287. package/dist/server/{openai-CUf4vc3Q.js → openai-C1gLuR-0.js} +1 -1
  288. package/dist/server/query-handlers.d.ts +2 -1
  289. package/dist/server/query-validator.d.ts +36 -4
  290. package/dist/server/types/core.d.ts +13 -0
  291. package/dist/server/types/cube.d.ts +39 -2
  292. package/dist/server/types/query.d.ts +8 -0
  293. package/package.json +2 -2
  294. package/dist/adapters/ActivityGridChart.config-D6hhj345.cjs +0 -1
  295. package/dist/adapters/ActivityGridChart.config-QZKs_NYg.js +0 -2
  296. package/dist/adapters/AreaChart.config-B5XM6G22.js +0 -2
  297. package/dist/adapters/AreaChart.config-NP34BH5y.cjs +0 -1
  298. package/dist/adapters/BarChart.config-Bqlmr81N.js +0 -2
  299. package/dist/adapters/BarChart.config-C3bw-cAP.cjs +0 -1
  300. package/dist/adapters/BoxPlotChart.config-BOAvoj6x.cjs +0 -1
  301. package/dist/adapters/BoxPlotChart.config-CTXiycYY.js +0 -2
  302. package/dist/adapters/BubbleChart.config-CGFIkl4H.cjs +0 -1
  303. package/dist/adapters/BubbleChart.config-Njxx4Eq1.js +0 -2
  304. package/dist/adapters/CandlestickChart.config-BZ_yWaSo.cjs +0 -1
  305. package/dist/adapters/CandlestickChart.config-D4Svhmef.js +0 -2
  306. package/dist/adapters/DataTable.config-B-bT9puT.js +0 -2
  307. package/dist/adapters/DataTable.config-BHtt1cPM.cjs +0 -1
  308. package/dist/adapters/FunnelChart.config-C1e07O7B.cjs +0 -1
  309. package/dist/adapters/FunnelChart.config-CVEy0tV9.js +0 -2
  310. package/dist/adapters/GaugeChart.config-5PLNlQlu.js +0 -2
  311. package/dist/adapters/GaugeChart.config-Cdv6knjZ.cjs +0 -1
  312. package/dist/adapters/HeatMapChart.config-MGTfYpWJ.js +0 -2
  313. package/dist/adapters/HeatMapChart.config-jfBEi1ZI.cjs +0 -1
  314. package/dist/adapters/KpiDelta.config-D2IUsEYz.cjs +0 -1
  315. package/dist/adapters/KpiDelta.config-DT_MmAHw.js +0 -2
  316. package/dist/adapters/KpiNumber.config-ChgbKmx8.cjs +0 -1
  317. package/dist/adapters/KpiNumber.config-CvZ_FhyL.js +0 -2
  318. package/dist/adapters/KpiText.config-Bgkw8gr2.js +0 -2
  319. package/dist/adapters/KpiText.config-Bz9orqt6.cjs +0 -1
  320. package/dist/adapters/LineChart.config-BVew35dI.cjs +0 -1
  321. package/dist/adapters/LineChart.config-DSCCKXNg.js +0 -2
  322. package/dist/adapters/MarkdownChart.config-Bu6XUuhI.js +0 -2
  323. package/dist/adapters/MarkdownChart.config-E4aSVTf3.cjs +0 -1
  324. package/dist/adapters/MeasureProfileChart.config-BF249hc_.cjs +0 -1
  325. package/dist/adapters/MeasureProfileChart.config-lERVe38G.js +0 -2
  326. package/dist/adapters/PieChart.config-7Ujwp8R5.cjs +0 -1
  327. package/dist/adapters/PieChart.config-jQl2HIcA.js +0 -2
  328. package/dist/adapters/ProportionBarChart.config-o0w_Pnlt.js +0 -2
  329. package/dist/adapters/ProportionBarChart.config-phNohhhY.cjs +0 -1
  330. package/dist/adapters/RadarChart.config-BmrYBd9x.js +0 -2
  331. package/dist/adapters/RadarChart.config-Dlt3UflG.cjs +0 -1
  332. package/dist/adapters/RadialBarChart.config-CeEm8xRb.cjs +0 -1
  333. package/dist/adapters/RadialBarChart.config-Dishh6bC.js +0 -2
  334. package/dist/adapters/RetentionCombinedChart.config-BaD4ev85.cjs +0 -1
  335. package/dist/adapters/RetentionCombinedChart.config-m2FjBUi9.js +0 -2
  336. package/dist/adapters/RetentionHeatmap.config-DiMplGdk.js +0 -2
  337. package/dist/adapters/RetentionHeatmap.config-Dp6oYwQZ.cjs +0 -1
  338. package/dist/adapters/SankeyChart.config-C4Y6qzCS.cjs +0 -1
  339. package/dist/adapters/SankeyChart.config-CJHqgjQ1.js +0 -2
  340. package/dist/adapters/ScatterChart.config-C0QqvDrN.cjs +0 -1
  341. package/dist/adapters/ScatterChart.config-DywOsWPW.js +0 -2
  342. package/dist/adapters/SunburstChart.config-DE8RxpDR.cjs +0 -1
  343. package/dist/adapters/SunburstChart.config-DohowrO3.js +0 -2
  344. package/dist/adapters/TreeMapChart.config-D2gXz-zC.cjs +0 -1
  345. package/dist/adapters/TreeMapChart.config-HMlI29GG.js +0 -2
  346. package/dist/adapters/WaterfallChart.config-BO2WV2VB.js +0 -2
  347. package/dist/adapters/WaterfallChart.config-CzwGiheB.cjs +0 -1
  348. package/dist/adapters/compiler-BNjqYdmc.cjs +0 -166
  349. package/dist/adapters/core-CzFfrJzu.cjs +0 -1
  350. package/dist/adapters/handler-m6WgA9xu.cjs +0 -25
  351. package/dist/adapters/mcp-transport-B0b27YUB.cjs +0 -40
  352. package/dist/adapters/mcp-transport-BXyA4dTk.js +0 -603
  353. package/dist/adapters/utils-BoOeig94.cjs +0 -128
  354. package/dist/client/chunks/DashboardEditModal-BOfLdTgV.js.map +0 -1
  355. package/dist/client/chunks/analysis-builder-shared-CEvHIlmk.js.map +0 -1
  356. package/dist/client/chunks/chart-activity-grid-4jfS8khG.js.map +0 -1
  357. package/dist/client/chunks/chart-data-table-DoDHQRe7.js.map +0 -1
  358. package/dist/client/chunks/charts-core-BPD_hLaL.js +0 -215
  359. package/dist/client/chunks/charts-core-BPD_hLaL.js.map +0 -1
  360. package/dist/client/chunks/charts-loader-CwMcOfwT.js +0 -85
  361. package/dist/client/chunks/charts-loader-CwMcOfwT.js.map +0 -1
  362. package/dist/client/chunks/nl-NL-DFLVORiD.js.map +0 -1
  363. package/dist/client/chunks/vendor-Qa1s8oSX.js.map +0 -1
@@ -111,6 +111,17 @@ export interface DatabaseAdapter {
111
111
  * @returns SQL expression with type casting
112
112
  */
113
113
  castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
114
+ /**
115
+ * Cast expression to specific database type, tolerantly: unparseable input yields NULL
116
+ * instead of raising an error (PostgreSQL's `::`/`CAST` on bad input) or silently producing
117
+ * 0 (MySQL/SQLite `CAST` on non-numeric text). Intended for EAV-style schemas where a text
118
+ * column holds numbers/timestamps for some attributes and free text for others, so one dirty
119
+ * value doesn't fail the whole query or masquerade as a real 0.
120
+ * @param fieldExpr - The field expression to cast
121
+ * @param targetType - Target database type
122
+ * @returns SQL expression with tolerant type casting; unparseable/NULL input yields NULL
123
+ */
124
+ tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
114
125
  /**
115
126
  * Build AVG aggregation expression with database-specific null handling
116
127
  * @param fieldExpr - The field expression to average
@@ -216,6 +227,7 @@ export declare abstract class BaseDatabaseAdapter implements DatabaseAdapter {
216
227
  abstract buildPeriodSeriesSubquery(maxPeriod: number): SQL;
217
228
  abstract buildTimeDimension(granularity: TimeGranularity, fieldExpr: AnyColumn | SQL): SQL;
218
229
  abstract castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
230
+ abstract tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
219
231
  abstract getCapabilities(): DatabaseCapabilities;
220
232
  abstract buildPercentile(fieldExpr: AnyColumn | SQL, percentile: number): SQL | null;
221
233
  /**
@@ -303,6 +315,40 @@ export declare abstract class BaseDatabaseAdapter implements DatabaseAdapter {
303
315
  field: AnyColumn | SQL;
304
316
  direction: 'asc' | 'desc';
305
317
  }>, config?: WindowFunctionConfig): SQL | null;
318
+ /**
319
+ * Regex pattern for tryCastToType's decimal guard: optional leading sign, digits with an
320
+ * optional fractional part (or a bare fractional part like `.5`), surrounded by optional
321
+ * spaces; rejects everything else. Shared by PostgreSQL (`~`) and MySQL/SingleStore
322
+ * (`REGEXP`).
323
+ *
324
+ * Deliberately written using only POSIX ERE syntax (`[0-9]` instead of `\d`, a literal
325
+ * space instead of `\s`) rather than Perl/ICU shorthands. PostgreSQL's `~` always
326
+ * understands `\d`/`\s`, and MySQL 8.0.4+'s default ICU regex engine does too — but
327
+ * SingleStore's `REGEXP` is dialect-switchable via the `regexp_format` session variable
328
+ * ('extended' = POSIX ERE, 'advanced' = ICU/PCRE-style), and SingleStore's own docs
329
+ * recommend explicitly opting into 'advanced' for new regex logic, implying 'extended'
330
+ * (POSIX, no `\d`/`\s`) is the default. Since SingleStoreAdapter inherits this pattern
331
+ * unchanged from MySQLAdapter and this repo doesn't control session variables for
332
+ * consumers, the pattern is written as the POSIX-ERE/ICU/ARE intersection so it matches
333
+ * correctly regardless of which dialect is active.
334
+ */
335
+ protected decimalTryCastPattern(): string;
336
+ /**
337
+ * Regex pattern for tryCastToType's integer guard: optional leading sign, digits only,
338
+ * surrounded by optional spaces. Same POSIX-ERE/ICU/ARE-portable rationale as
339
+ * decimalTryCastPattern().
340
+ */
341
+ protected integerTryCastPattern(): string;
342
+ /**
343
+ * Regex pattern for tryCastToType's timestamp guard: an ISO 8601-shaped date, optionally
344
+ * followed by a time component (with optional seconds, fractional seconds and a UTC/offset
345
+ * suffix), surrounded by optional spaces. This only validates the *shape* of the input —
346
+ * it does not catch calendar-invalid dates (e.g. 2024-02-30) or reject strings that "look"
347
+ * like a timestamp but aren't (that would need engine-side parsing, which is exactly what
348
+ * tryCastToType is avoiding relying on for error-safety). Same POSIX-ERE/ICU/ARE-portable
349
+ * rationale as decimalTryCastPattern().
350
+ */
351
+ protected timestampTryCastPattern(): string;
306
352
  /**
307
353
  * Helper method to build pattern for string matching
308
354
  * Can be overridden by specific adapters if needed
@@ -45,6 +45,11 @@ export declare class DatabendAdapter extends BaseDatabaseAdapter {
45
45
  * Databend supports both :: syntax and CAST() function
46
46
  */
47
47
  castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
48
+ /**
49
+ * Build Databend tolerant type casting using the native TRY_CAST function, which returns
50
+ * NULL on conversion failure instead of raising an error (unlike `::`/CAST).
51
+ */
52
+ tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
48
53
  /**
49
54
  * Databend capabilities - start conservative
50
55
  */
@@ -52,6 +52,11 @@ export declare class DuckDBAdapter extends BaseDatabaseAdapter {
52
52
  * DuckDB supports both :: syntax and CAST() function
53
53
  */
54
54
  castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
55
+ /**
56
+ * Build DuckDB tolerant type casting using the native TRY_CAST function, which returns
57
+ * NULL on conversion failure instead of raising an error (unlike `::`/CAST).
58
+ */
59
+ tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
55
60
  /**
56
61
  * DuckDB has full support for statistical and window functions
57
62
  * Note: supportsPercentileSubqueries is false because DuckDB's QUANTILE_CONT
@@ -47,6 +47,20 @@ export declare class MySQLAdapter extends BaseDatabaseAdapter {
47
47
  * MySQL equivalent to PostgreSQL's :: casting syntax
48
48
  */
49
49
  castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
50
+ /**
51
+ * Build MySQL tolerant type casting: NULL on unparseable input instead of MySQL's usual
52
+ * lenient-but-wrong behaviour. `CAST(x AS DECIMAL/SIGNED)` parses a leading numeric prefix
53
+ * (or returns 0 with a warning if there's no numeric prefix at all) rather than erroring —
54
+ * so a dirty value like 'n/a' silently becomes 0. `CAST(x AS DATETIME)` on a string that
55
+ * merely looks date-shaped but is calendar-invalid can, depending on sql_mode, raise an
56
+ * error (strict mode, the MySQL 8 default) rather than returning NULL. Guard all three with
57
+ * REGEXP so we only ever attempt the cast on input that already looks like the target type;
58
+ * anything else short-circuits to NULL first.
59
+ *
60
+ * The timestamp guard only validates ISO 8601 *shape* — it will not catch calendar-invalid
61
+ * dates like 2024-02-30, which could still error under strict SQL mode.
62
+ */
63
+ tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
50
64
  /**
51
65
  * MySQL AVG/STDDEV/VARIANCE use IFNULL (no COALESCE-for-zero idiom mismatch,
52
66
  * but IFNULL is the MySQL-idiomatic null guard).
@@ -43,6 +43,21 @@ export declare class PostgresAdapter extends BaseDatabaseAdapter {
43
43
  * Extracted from various locations where ::timestamp was used
44
44
  */
45
45
  castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
46
+ /**
47
+ * Build PostgreSQL tolerant type casting: NULL on unparseable input instead of an error.
48
+ * PostgreSQL has no TRY_CAST, and `CAST(x AS type DEFAULT NULL ON ERROR)` (added in a
49
+ * recent PostgreSQL release) requires a minimum server version. This repo pins no minimum
50
+ * PostgreSQL version anywhere (CI/dev docker-compose both run `postgres:18`, but nothing
51
+ * documents that as a floor for consumers), so we don't assume newer syntax is available.
52
+ * Instead, guard the cast with a POSIX regex (`~`) so we only ever attempt to cast values
53
+ * that already look like the target type; anything else short-circuits to NULL before the
54
+ * cast runs, so PostgreSQL never gets a chance to raise.
55
+ *
56
+ * The timestamp guard only validates ISO 8601 *shape* (see timestampTryCastPattern) — it
57
+ * will not catch calendar-invalid dates like 2024-02-30, which would still error. A full
58
+ * guarantee would need a helper SQL function (out of scope here).
59
+ */
60
+ tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
46
61
  /**
47
62
  * PostgreSQL has full support for statistical and window functions
48
63
  */
@@ -41,6 +41,12 @@ export declare class SnowflakeAdapter extends BaseDatabaseAdapter {
41
41
  * Snowflake supports both :: syntax and CAST() function
42
42
  */
43
43
  castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
44
+ /**
45
+ * Build Snowflake tolerant type casting using the native TRY_CAST function, which returns
46
+ * NULL on conversion failure instead of raising an error (unlike `::`/CAST). Snowflake's
47
+ * TRY_CAST supports VARCHAR, NUMBER-family types (including DECIMAL) and TIMESTAMP.
48
+ */
49
+ tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
44
50
  /**
45
51
  * Snowflake capabilities - full SQL support
46
52
  */
@@ -51,6 +51,27 @@ export declare class SQLiteAdapter extends BaseDatabaseAdapter {
51
51
  * SQLite has dynamic typing but supports CAST for consistency
52
52
  */
53
53
  castToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
54
+ /**
55
+ * Build SQLite tolerant type casting: NULL on unparseable input instead of SQLite's usual
56
+ * dynamic-typing behaviour. SQLite's CAST-to-numeric applies "prefix" conversion — the
57
+ * longest numeric prefix of the string is used, or 0 if there is none — so `CAST('n/a' AS
58
+ * REAL)` silently yields 0.0 rather than erroring or returning NULL.
59
+ *
60
+ * SQLite has no REGEXP operator by default (it requires loading an extension, same
61
+ * limitation regexCondition() works around with GLOB). GLOB's `*`/`?`/`[...]` syntax can't
62
+ * express "one or more digits" directly, but the standard SQLite idiom for "string contains
63
+ * only characters from a set" is `NOT x GLOB '*[^set]*'` — true only if no character outside
64
+ * the set appears anywhere. That's what's used below to validate the trimmed value contains
65
+ * only the characters a valid decimal/integer/epoch-ms value could use, before attempting
66
+ * the cast; empty/whitespace-only strings are excluded separately.
67
+ *
68
+ * Known limitation: this is a character-set check, not a full grammar check, so a malformed
69
+ * value that still only uses allowed characters (e.g. '1.2.3' or '+-5') passes the guard and
70
+ * is then handled by SQLite's own prefix-based numeric parsing (never an error, but not
71
+ * necessarily NULL either). Clearly non-numeric input (letters, 'n/a', punctuation outside
72
+ * the allowed set) is reliably rejected to NULL, which is the case this method exists for.
73
+ */
74
+ tryCastToType(fieldExpr: AnyColumn | SQL, targetType: 'timestamp' | 'decimal' | 'integer'): SQL;
54
75
  /**
55
76
  * SQLite AVG uses IFNULL rather than COALESCE for null-to-zero handling.
56
77
  */
@@ -12,7 +12,7 @@ interface ValidationResult {
12
12
  /**
13
13
  * Validate chartConfig against the chart type's drop zone requirements.
14
14
  */
15
- export declare function validateChartConfig(chartType: string, chartConfig: Record<string, unknown> | undefined, _query: Record<string, unknown>): ValidationResult;
15
+ export declare function validateChartConfig(chartType: string, chartConfig: Record<string, unknown> | undefined, query: Record<string, unknown>): ValidationResult;
16
16
  export declare function inferChartConfig(chartType: string, chartConfig: Record<string, unknown> | undefined, query: Record<string, unknown>): Record<string, unknown>;
17
17
  /**
18
18
  * Build per-chart-type requirements text for the agent tool description.
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Chart Configuration Schema — shared by the MCP and Agent tools
3
+ *
4
+ * The chart-side sibling of `QUERY_PARAMS_SCHEMA`. Used by BOTH:
5
+ * - MCP `chart` tool (adapters/mcp-transport.ts)
6
+ * - Agent `add_portlet` / `save_as_dashboard` tools (server/agent/tools.ts)
7
+ *
8
+ * Most charts need nothing here — their axes are inferred from the query. The
9
+ * records table is the exception: it lays out `columns` rather than axes, and a
10
+ * column renders as plain text unless the caller says what it is. Formats are
11
+ * never guessed from the data, so a model that cannot see this shape produces a
12
+ * listing of unformatted strings.
13
+ */
14
+ /** `chartConfig` fields specific to the records table. */
15
+ export declare const RECORDS_TABLE_CHART_CONFIG_SCHEMA: {
16
+ readonly columns: {
17
+ readonly type: "array";
18
+ readonly items: {
19
+ readonly type: "string";
20
+ };
21
+ readonly description: "recordsTable only: fields to render as columns, in this order. Omit to show every field the query returns, in query order.";
22
+ };
23
+ readonly hiddenColumns: {
24
+ readonly type: "array";
25
+ readonly items: {
26
+ readonly type: "string";
27
+ };
28
+ readonly description: "recordsTable only: fields fetched for row context or rowLink tokens but never displayed (e.g. an id used in the URL template). Leave empty unless a field is genuinely only needed behind the scenes — anything listed here disappears from the table.";
29
+ };
30
+ };
31
+ /** `displayConfig` fields specific to the records table. */
32
+ export declare const RECORDS_TABLE_DISPLAY_CONFIG_SCHEMA: {
33
+ readonly columnFormats: {
34
+ readonly type: "object";
35
+ readonly description: "recordsTable only: how each column renders, keyed by field name (e.g. \"Employees.salary\"). Formats are never inferred from the data — a column is plain text unless you say otherwise, so set this for any numeric, date, status or ratio column.";
36
+ readonly additionalProperties: {
37
+ readonly type: "object";
38
+ readonly required: readonly ["kind"];
39
+ readonly properties: {
40
+ readonly kind: {
41
+ readonly type: "string";
42
+ readonly enum: readonly ["text", "number", "date", "badge", "progress"];
43
+ readonly description: "Required on every entry. text: as-is. number: formatted numeric. date: formatted date. badge: coloured pill for statuses/categories. progress: bar or ring for a bounded value. Use \"text\" when you only want to set a label.";
44
+ };
45
+ readonly numberFormat: {
46
+ readonly type: "object";
47
+ readonly description: "kind \"number\": { unit: \"currency\"|\"percent\"|\"number\"|\"custom\", decimals, abbreviate (K/M/B), currencyCode, customPrefix, customSuffix }.";
48
+ };
49
+ readonly dateGranularity: {
50
+ readonly type: "string";
51
+ readonly description: "kind \"date\": granularity to render at (e.g. \"day\", \"month\", \"year\").";
52
+ };
53
+ readonly badgeColors: {
54
+ readonly type: "array";
55
+ readonly description: "kind \"badge\": an ARRAY of { value, colorIndex } entries, not an object keyed by value. colorIndex is a number index into the dashboard palette (0, 1, 2, …), never a colour name like \"green\" — the palette is themed, so names would not follow it. A value with no entry renders neutral rather than being assigned a guessed colour.";
56
+ readonly items: {
57
+ readonly type: "object";
58
+ readonly required: readonly ["value", "colorIndex"];
59
+ readonly properties: {
60
+ readonly value: {
61
+ readonly type: "string";
62
+ readonly description: "Cell value to colour, matched exactly";
63
+ };
64
+ readonly colorIndex: {
65
+ readonly type: "number";
66
+ readonly description: "Index into the dashboard colour palette";
67
+ };
68
+ };
69
+ };
70
+ };
71
+ readonly progressMin: {
72
+ readonly type: "number";
73
+ readonly description: "kind \"progress\": lower bound (default 0). Values are clamped.";
74
+ };
75
+ readonly progressMax: {
76
+ readonly type: "number";
77
+ readonly description: "kind \"progress\": upper bound (default 100). Values are clamped.";
78
+ };
79
+ readonly progressStyle: {
80
+ readonly type: "string";
81
+ readonly enum: readonly ["bar", "circle"];
82
+ readonly description: "kind \"progress\": full-width bar, or a compact ring for narrow columns.";
83
+ };
84
+ readonly label: {
85
+ readonly type: "string";
86
+ readonly description: "Header override; defaults to the field title from the cube metadata.";
87
+ };
88
+ readonly align: {
89
+ readonly type: "string";
90
+ readonly enum: readonly ["left", "right"];
91
+ readonly description: "Cell alignment. Numbers usually read better right-aligned.";
92
+ };
93
+ };
94
+ };
95
+ };
96
+ readonly rowLink: {
97
+ readonly type: "object";
98
+ readonly description: "recordsTable only: makes each row a link.";
99
+ readonly required: readonly ["urlTemplate"];
100
+ readonly properties: {
101
+ readonly urlTemplate: {
102
+ readonly type: "string";
103
+ readonly description: "URL with {Cube.field} tokens substituted from the row, including hidden columns (e.g. \"/employees/{Employees.id}\"). Relative paths and http(s) URLs only.";
104
+ };
105
+ readonly target: {
106
+ readonly type: "string";
107
+ readonly enum: readonly ["self", "blank"];
108
+ readonly description: "Open in the same tab (default) or a new one.";
109
+ };
110
+ };
111
+ };
112
+ readonly pageSize: {
113
+ readonly type: "number";
114
+ readonly enum: readonly [25, 50, 100];
115
+ readonly description: "recordsTable only: rows per page (default 25).";
116
+ };
117
+ };
@@ -21,6 +21,20 @@ export declare function accumulateFieldScores(keyword: string, fields: Field[],
21
21
  }): number;
22
22
  /** Return the top-N field names from a score map, highest score first. */
23
23
  export declare function topScoredFields(scores: Map<string, number>, limit: number): string[];
24
+ /**
25
+ * Titles for suggested fields whose name does not already say what they are.
26
+ *
27
+ * Most field names describe themselves (`Employees.salary`), so repeating the
28
+ * title would be noise. A user-defined (EAV) attribute is the case this exists
29
+ * for: it is addressed by a generated slot name like `attr_2`, and the title is
30
+ * the only thing that says it means "Completion %". Discovery scores against
31
+ * that title, so without this the caller is handed an opaque identifier and told
32
+ * it is relevant.
33
+ *
34
+ * Returned as a separate name-keyed map rather than annotated into the field
35
+ * lists, which callers are told to copy verbatim into queries.
36
+ */
37
+ export declare function buildFieldTitles(fields: Field[], suggested: string[]): Record<string, string> | undefined;
24
38
  /**
25
39
  * Score a single field as a best-match candidate (used by findBestFieldMatch).
26
40
  * Returns the best score across name, title and synonyms (no description match).
@@ -11,6 +11,12 @@ export interface CubeDiscoveryResult {
11
11
  matchedOn: ('name' | 'title' | 'description' | 'exampleQuestions' | 'measures' | 'dimensions')[];
12
12
  suggestedMeasures: string[];
13
13
  suggestedDimensions: string[];
14
+ /**
15
+ * Titles for suggested fields whose name does not say what they are — chiefly
16
+ * user-defined (EAV) attributes, addressed as `attr_<id>`. Keyed by field name
17
+ * so the names above stay copyable verbatim. Omitted when nothing needs it.
18
+ */
19
+ fieldTitles?: Record<string, string>;
14
20
  capabilities: {
15
21
  query: true;
16
22
  funnel: boolean;
@@ -97,7 +97,7 @@ export declare const QUERY_PARAMS_SCHEMA: {
97
97
  };
98
98
  readonly ungrouped: {
99
99
  readonly type: "boolean";
100
- readonly description: "When true, returns raw row-level data without GROUP BY. Requires at least one dimension. Incompatible with count/countDistinct measures and analysis modes.";
100
+ readonly description: "When true, returns raw row-level data without GROUP BY. Requires at least one dimension. Incompatible with count/countDistinct measures and analysis modes. Cannot reference two cubes joined by a hasMany relationship in EITHER direction (e.g. Departments hasMany Employees) — an ungrouped query stays at one record grain, so keep it to a single cube plus its to-one joins. A field from a hasMany-related cube has to be pre-aggregated in a grouped query instead.";
101
101
  };
102
102
  readonly funnel: {
103
103
  readonly type: "object";
@@ -0,0 +1,102 @@
1
+ import { AnyColumn, SQL } from 'drizzle-orm';
2
+ import { Dimension, QueryContext } from './types/index.js';
3
+ /** The value types a generated attribute dimension can be cast to. */
4
+ export type AttributeValueType = 'string' | 'number' | 'time';
5
+ /** One admin-defined attribute, as loaded from the application's own table. */
6
+ export interface AttributeDefinition {
7
+ /**
8
+ * Stable identifier. The dimension's member name is derived from this, never
9
+ * from the attribute's name — so renaming an attribute updates every table
10
+ * header without breaking saved dashboards, drill state or share links.
11
+ */
12
+ id: string | number;
13
+ /** Display name. Becomes the dimension's `title`, which the client renders. */
14
+ name: string;
15
+ /**
16
+ * Value type, if the application's attribute table records one. Filtering and
17
+ * sorting happen in SQL over the whole table before any row reaches the
18
+ * browser, so this is not cosmetic — see {@link buildAttributeDimensions}.
19
+ */
20
+ valueType?: AttributeValueType;
21
+ }
22
+ export interface BuildAttributeDimensionsOptions {
23
+ /** The attributes to generate a dimension for. */
24
+ attributes: AttributeDefinition[];
25
+ /** The junction table holding one row per (record, attribute). */
26
+ valueTable: unknown;
27
+ /** Primary key of the record being extended — e.g. `employees.id`. */
28
+ recordKey: AnyColumn;
29
+ /** Column on the junction table pointing back at the record. */
30
+ foreignKey: AnyColumn;
31
+ /** Column on the junction table identifying the attribute. */
32
+ attributeKey: AnyColumn;
33
+ /** Column on the junction table holding the value. */
34
+ valueColumn: AnyColumn;
35
+ /**
36
+ * Row-level security for the junction table. **Required**: the subquery reads
37
+ * the junction table directly, so without this a tenant sees every tenant's
38
+ * attribute values. It is a parameter rather than an option so that omitting
39
+ * it is impossible rather than merely inadvisable.
40
+ */
41
+ security: (ctx: QueryContext) => SQL;
42
+ /**
43
+ * Per-attribute type overrides, keyed by attribute id. Wins over
44
+ * `AttributeDefinition.valueType`.
45
+ */
46
+ types?: Record<string, AttributeValueType>;
47
+ /** Member-name prefix. Defaults to `attr_`. */
48
+ namePrefix?: string;
49
+ /** Passed through to each generated dimension's `shown`. */
50
+ shown?: boolean;
51
+ }
52
+ /**
53
+ * Build one dimension per attribute, each backed by a correlated scalar
54
+ * subquery against the junction table.
55
+ *
56
+ * ```ts
57
+ * dimensions: {
58
+ * ...baseDimensions,
59
+ * ...buildAttributeDimensions({
60
+ * attributes: attrs,
61
+ * valueTable: employeeAttributeValues,
62
+ * recordKey: employees.id,
63
+ * foreignKey: employeeAttributeValues.employeeId,
64
+ * attributeKey: employeeAttributeValues.attributeId,
65
+ * valueColumn: employeeAttributeValues.value,
66
+ * security: (ctx) => eq(employeeAttributeValues.organisationId, ctx.securityContext.organisationId)
67
+ * })
68
+ * }
69
+ * ```
70
+ *
71
+ * Three details that are easy to get wrong, and are handled here:
72
+ *
73
+ * - **Typing is mandatory, not cosmetic.** Sorting and filtering run in SQL
74
+ * over the whole table before a page reaches the browser, so client-side
75
+ * conversion cannot repair them: sorted as text, `100` sorts below `9`, and
76
+ * `> 50` admits `'9'` while rejecting `'100'`. A `number` attribute is cast
77
+ * in SQL — tolerantly, so one `n/a` yields NULL for that row instead of
78
+ * failing the whole query.
79
+ * - **`LIMIT 1`.** EAV tables rarely carry a unique constraint on
80
+ * (record, attribute); without it a duplicate row raises "more than one row
81
+ * returned by a subquery" on Postgres.
82
+ * - **Security inside the subquery**, not merely on the outer query.
83
+ *
84
+ * **Grouping.** The subquery correlates on the record key, so a *grouped* query
85
+ * must also group by that key or Postgres rejects it with "subquery uses
86
+ * ungrouped column … from outer query" (MySQL likewise under
87
+ * `only_full_group_by`; SQLite permits it). The caller does not have to know
88
+ * that: each generated dimension declares its key via `Dimension.correlatesOn`,
89
+ * and the GROUP BY builder adds it. The grouping is therefore per record — the
90
+ * only grain at which a per-record attribute can be read — so an aggregate over
91
+ * an attribute counts records, not attribute values. If you need to aggregate
92
+ * freely *by* an attribute, pivot it into a real column with a view (see the
93
+ * performance ladder below). Record-grain listings (`ungrouped: true`) skip
94
+ * GROUP BY entirely and are unaffected.
95
+ *
96
+ * Performance: projection is cheap (a page of 25 rows is 25 indexed lookups per
97
+ * attribute), but `ORDER BY (SELECT …)` and `WHERE (SELECT …) = …` are
98
+ * proportional to the base table because no index serves them. At tens of
99
+ * thousands of rows that is fine; beyond it, pivot the attributes into real
100
+ * indexable columns via a view.
101
+ */
102
+ export declare function buildAttributeDimensions(options: BuildAttributeDimensionsOptions): Record<string, Dimension>;
@@ -24,6 +24,21 @@ export declare class GroupByBuilder {
24
24
  * Window functions do not require GROUP BY and operate on individual rows.
25
25
  */
26
26
  buildGroupByFields(cubes: Map<string, Cube> | Cube, query: SemanticQuery, context: QueryContext, queryPlan?: PhysicalQueryPlan): (SQL | AnyColumn)[];
27
+ /**
28
+ * Add the correlation key of any selected dimension that declares one.
29
+ *
30
+ * A dimension built from a correlated subquery (`buildAttributeDimensions`)
31
+ * references the record key inside its SQL. Grouping by the subquery alone is
32
+ * rejected by Postgres ("subquery uses ungrouped column … from outer query")
33
+ * and by MySQL under `only_full_group_by`, so the key it correlates on is
34
+ * grouped too.
35
+ *
36
+ * This only ever fires for queries that are invalid on those engines today, so
37
+ * nothing that currently works changes shape. The key is the record's primary
38
+ * key, so adding it makes the grouping per-record — which is the grain such a
39
+ * dimension can be read at in the first place.
40
+ */
41
+ private addCorrelationKeys;
27
42
  /**
28
43
  * Determine whether the query contains at least one aggregate (or calculated,
29
44
  * or post-aggregation window over an aggregate) measure — which forces GROUP BY.
@@ -24,9 +24,13 @@ export interface CacheKeyConfig {
24
24
  * @param query - The semantic query to cache
25
25
  * @param securityContext - Security context for tenant isolation
26
26
  * @param config - Cache key configuration
27
+ * @param cubeSetKey - Identifies the cube definitions behind the result. Always
28
+ * included when present: `includeSecurityContext: false` and a custom
29
+ * `securityContextSerializer` can each hash two tenants identically, so the
30
+ * security-context hash alone cannot keep differing cube sets apart.
27
31
  * @returns Deterministic cache key string
28
32
  */
29
- export declare function generateCacheKey(query: SemanticQuery, securityContext: SecurityContext, config?: CacheKeyConfig): string;
33
+ export declare function generateCacheKey(query: SemanticQuery, securityContext: SecurityContext, config?: CacheKeyConfig, cubeSetKey?: string): string;
30
34
  /**
31
35
  * Normalize query for consistent hashing
32
36
  * Sorts arrays and object keys to ensure same query = same hash
@@ -1,11 +1,32 @@
1
1
  import { Cube, MeasureMetadata, DimensionMetadata, CubeRelationshipMetadata, HierarchyMetadata, TimeGranularity } from './types/index.js';
2
2
  /** Default time granularities used when a time dimension omits `granularities`. */
3
3
  export declare const DEFAULT_TIME_GRANULARITIES: TimeGranularity[];
4
- /** Build measure metadata, normalizing drillMembers to fully-qualified names. */
4
+ /**
5
+ * Build measure metadata, normalizing drillMembers to fully-qualified names.
6
+ *
7
+ * Measures with `shown: false` are omitted from the result — matching Cube.js
8
+ * semantics, where a hidden measure remains fully usable in queries but is
9
+ * excluded from metadata/UI surfaces. `shown: undefined` means shown, so
10
+ * today's behaviour is preserved exactly.
11
+ */
5
12
  export declare function buildMeasureMetadata(cube: Cube): MeasureMetadata[];
6
- /** Build dimension metadata, including granularities for time dimensions. */
13
+ /**
14
+ * Build dimension metadata, including granularities for time dimensions.
15
+ *
16
+ * Dimensions with `shown: false` are omitted from the result — matching
17
+ * Cube.js semantics, where a hidden dimension remains fully usable in queries
18
+ * but is excluded from metadata/UI surfaces. `shown: undefined` means shown,
19
+ * so today's behaviour is preserved exactly.
20
+ */
7
21
  export declare function buildDimensionMetadata(cube: Cube): DimensionMetadata[];
8
22
  /** Build relationship metadata from a cube's joins, resolving target cubes. */
9
23
  export declare function buildRelationshipMetadata(cube: Cube, cubes: Map<string, Cube>, getColumnName: (column: any) => string): CubeRelationshipMetadata[];
10
- /** Build hierarchy metadata, qualifying level names to full member names. */
24
+ /**
25
+ * Build hierarchy metadata, qualifying level names to full member names.
26
+ *
27
+ * Levels referencing a dimension with `shown: false` are dropped, so a
28
+ * hierarchy never emits a dangling reference to a dimension that has been
29
+ * omitted from the cube's own dimension metadata. A hierarchy left with no
30
+ * visible levels is omitted entirely rather than published as empty.
31
+ */
11
32
  export declare function buildHierarchyMetadata(cube: Cube): HierarchyMetadata[];