drizzle-cube 0.8.0 → 0.8.2

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 (329) hide show
  1. package/dist/adapters/ActivityGridChart.config-Bc7mPqcf.cjs +1 -0
  2. package/dist/adapters/ActivityGridChart.config-Dd2YDeaM.js +2 -0
  3. package/dist/adapters/AreaChart.config-BqNusnpg.js +2 -0
  4. package/dist/adapters/AreaChart.config-dI84V34B.cjs +1 -0
  5. package/dist/adapters/BarChart.config-B9MQjgLJ.cjs +1 -0
  6. package/dist/adapters/BarChart.config-Cq_qcxBA.js +2 -0
  7. package/dist/adapters/BoxPlotChart.config-XmtRN2xq.cjs +1 -0
  8. package/dist/adapters/BoxPlotChart.config-Zc-JGV-W.js +2 -0
  9. package/dist/adapters/BubbleChart.config-CU_18uxb.js +2 -0
  10. package/dist/adapters/BubbleChart.config-CbhOzA6-.cjs +1 -0
  11. package/dist/adapters/CandlestickChart.config-Bwo3uaa-.js +2 -0
  12. package/dist/adapters/CandlestickChart.config-CmRBlWFv.cjs +1 -0
  13. package/dist/adapters/DataTable.config-7JNSj6qQ.js +2 -0
  14. package/dist/adapters/DataTable.config-DNxm1sYk.cjs +1 -0
  15. package/dist/adapters/DotStripChart.config-B7Dl-T1h.js +2 -0
  16. package/dist/adapters/DotStripChart.config-Co4g1fpZ.cjs +1 -0
  17. package/dist/adapters/FunnelChart.config-D1TpuGtL.cjs +1 -0
  18. package/dist/adapters/FunnelChart.config-vuZScOHQ.js +2 -0
  19. package/dist/adapters/GaugeChart.config-BMgUHKhC.cjs +1 -0
  20. package/dist/adapters/GaugeChart.config-zdpFydo6.js +2 -0
  21. package/dist/adapters/HeatMapChart.config-4XMab1zq.js +2 -0
  22. package/dist/adapters/HeatMapChart.config-C-Ns6QBq.cjs +1 -0
  23. package/dist/adapters/KpiDelta.config-BGdqsHcc.js +2 -0
  24. package/dist/adapters/KpiDelta.config-DuNxrGIi.cjs +1 -0
  25. package/dist/adapters/KpiNumber.config-CkPWpcSz.js +2 -0
  26. package/dist/adapters/KpiNumber.config-DMGmuA3i.cjs +1 -0
  27. package/dist/adapters/KpiText.config-Bvtuv8vE.js +2 -0
  28. package/dist/adapters/KpiText.config-DOMLO16U.cjs +1 -0
  29. package/dist/adapters/LineChart.config-CJmTSmZ1.js +2 -0
  30. package/dist/adapters/LineChart.config-CrkGu0aa.cjs +1 -0
  31. package/dist/adapters/MarkdownChart.config-BgY5Xc97.cjs +1 -0
  32. package/dist/adapters/MarkdownChart.config-Cm6G4Yuh.js +2 -0
  33. package/dist/adapters/MeasureProfileChart.config-BYwDo_ox.cjs +1 -0
  34. package/dist/adapters/MeasureProfileChart.config-Dt7npubZ.js +2 -0
  35. package/dist/adapters/PieChart.config-BRbPctBN.cjs +1 -0
  36. package/dist/adapters/PieChart.config-HZofeody.js +2 -0
  37. package/dist/adapters/ProportionBarChart.config-B_rTtGZr.cjs +1 -0
  38. package/dist/adapters/ProportionBarChart.config-ChCSoM0L.js +2 -0
  39. package/dist/adapters/RadarChart.config-B9OdMEib.js +2 -0
  40. package/dist/adapters/RadarChart.config-BOgPD2Kz.cjs +1 -0
  41. package/dist/adapters/RadialBarChart.config-CeP7jEbq.js +2 -0
  42. package/dist/adapters/RadialBarChart.config-sivA1Jmo.cjs +1 -0
  43. package/dist/adapters/RecordsTable.config-BInSgo-G.js +2 -0
  44. package/dist/adapters/RecordsTable.config-CVmxLdjz.cjs +1 -0
  45. package/dist/adapters/RetentionCombinedChart.config-8ry7gh6X.cjs +1 -0
  46. package/dist/adapters/RetentionCombinedChart.config-Bxtxnlcf.js +2 -0
  47. package/dist/adapters/RetentionHeatmap.config-DCtOD8dO.js +2 -0
  48. package/dist/adapters/RetentionHeatmap.config-i-LgmmIT.cjs +1 -0
  49. package/dist/adapters/SankeyChart.config-DfpeHfNT.cjs +1 -0
  50. package/dist/adapters/SankeyChart.config-hfM0ACm1.js +2 -0
  51. package/dist/adapters/ScatterChart.config-BD2vfOZ6.js +2 -0
  52. package/dist/adapters/ScatterChart.config-CdpvRueF.cjs +1 -0
  53. package/dist/adapters/SunburstChart.config-Boyt88L_.cjs +1 -0
  54. package/dist/adapters/SunburstChart.config-BvrofzMv.js +2 -0
  55. package/dist/adapters/TreeMapChart.config-DBrqwtqT.js +2 -0
  56. package/dist/adapters/TreeMapChart.config-KcRLlZAG.cjs +1 -0
  57. package/dist/adapters/WaterfallChart.config-CuCGaIl5.cjs +1 -0
  58. package/dist/adapters/WaterfallChart.config-DZ8H0V2L.js +2 -0
  59. package/dist/adapters/{compiler-CQJ5GOwF.js → compiler-BFLAXV7W.js} +1160 -1861
  60. package/dist/adapters/compiler-DG6dLFQU.cjs +166 -0
  61. package/dist/adapters/core/index.cjs +1 -1
  62. package/dist/adapters/core/index.js +1 -1
  63. package/dist/adapters/{core-DgTGXxDu.cjs → core-CrJu6vJY.cjs} +1 -1
  64. package/dist/adapters/{core-DXkuSUBg.js → core-l3KMTu9u.js} +3 -3
  65. package/dist/adapters/express/index.cjs +1 -1
  66. package/dist/adapters/express/index.js +5 -5
  67. package/dist/adapters/fastify/index.cjs +1 -1
  68. package/dist/adapters/fastify/index.js +23 -23
  69. package/dist/{server/google-eKAc20al.js → adapters/google-DRY7jnOh.js} +46 -28
  70. package/dist/adapters/{google-BhvizbFR.cjs → google-PsZzwedr.cjs} +2 -2
  71. package/dist/adapters/handler-CRGZ8gd2.cjs +25 -0
  72. package/dist/adapters/{handler-CphYSZRh.js → handler-DESp4wPg.js} +454 -237
  73. package/dist/adapters/hono/index.cjs +1 -1
  74. package/dist/adapters/hono/index.js +4 -4
  75. package/dist/adapters/mcp-tools.cjs +1 -1
  76. package/dist/adapters/mcp-tools.js +2 -2
  77. package/dist/adapters/mcp-transport-BqdBHmXL.js +730 -0
  78. package/dist/adapters/mcp-transport-D8xZJLPD.cjs +42 -0
  79. package/dist/adapters/nextjs/index.cjs +1 -1
  80. package/dist/adapters/nextjs/index.js +5 -5
  81. package/dist/adapters/{openai-CBrN4nxl.js → openai-BJyU4kvE.js} +3 -3
  82. package/dist/adapters/{openai-CSzWluuv.cjs → openai-DH9MtcLA.cjs} +1 -1
  83. package/dist/adapters/{openai-D-VMcPao.js → openai-DK_KWiI7.js} +1 -1
  84. package/dist/adapters/{openai-CI9vGKSf.cjs → openai-GO3M7Hwi.cjs} +2 -2
  85. package/dist/adapters/{utils-DkmShl5f.js → utils-BhlkVCzZ.js} +1985 -1122
  86. package/dist/adapters/utils-C1JpSDOX.cjs +128 -0
  87. package/dist/adapters/utils.cjs +1 -1
  88. package/dist/adapters/utils.d.ts +17 -3
  89. package/dist/adapters/utils.js +1 -1
  90. package/dist/cjs/adapters/utils.d.ts +17 -3
  91. package/dist/cjs/client/charts/chartConfigRegistry.d.ts +7 -0
  92. package/dist/cjs/client/charts/chartConfigs.d.ts +17 -1
  93. package/dist/cjs/client/client/CubeClient.d.ts +11 -1
  94. package/dist/cjs/client/components/AnalysisBuilder/AnalysisDisplayConfigPanel.d.ts +4 -2
  95. package/dist/cjs/client/components/AnalysisBuilder/ColumnFormatsEditor.d.ts +10 -0
  96. package/dist/cjs/client/components/AnalysisBuilder/DisplayOptionControl.d.ts +3 -2
  97. package/dist/cjs/client/components/AnalysisBuilder/utils/queryUtils.d.ts +7 -1
  98. package/dist/cjs/client/components/analyticsPortlet/PortletChart.d.ts +2 -1
  99. package/dist/cjs/client/components/analyticsPortlet/PortletChartView.d.ts +4 -1
  100. package/dist/cjs/client/components/analyticsPortlet/usePortletDeadMembers.d.ts +24 -0
  101. package/dist/cjs/client/components/analyticsPortlet/usePortletPagination.d.ts +21 -0
  102. package/dist/cjs/client/components/charts/DotStripChart.config.d.ts +15 -0
  103. package/dist/cjs/client/components/charts/DotStripChart.d.ts +4 -0
  104. package/dist/cjs/client/components/charts/DotStripChart.helpers.d.ts +91 -0
  105. package/dist/cjs/client/components/charts/RecordsTable.config.d.ts +10 -0
  106. package/dist/cjs/client/components/charts/RecordsTable.d.ts +4 -0
  107. package/dist/cjs/client/components/charts/recordsTableHooks.d.ts +68 -0
  108. package/dist/cjs/client/icons/types.d.ts +2 -0
  109. package/dist/cjs/client/index.d.ts +2 -2
  110. package/dist/cjs/client/types.d.ts +97 -1
  111. package/dist/cjs/client/utils/recordsTableUtils.d.ts +71 -0
  112. package/dist/cjs/client/utils/rowLinkUtils.d.ts +35 -0
  113. package/dist/cjs/server/agent/chart-validation.d.ts +1 -1
  114. package/dist/cjs/server/ai/chart-schema.d.ts +117 -0
  115. package/dist/cjs/server/ai/discovery-helpers.d.ts +14 -0
  116. package/dist/cjs/server/ai/discovery.d.ts +6 -0
  117. package/dist/cjs/server/ai/query-schema.d.ts +1 -1
  118. package/dist/cjs/server/attribute-dimensions.d.ts +11 -8
  119. package/dist/cjs/server/builders/group-by-builder.d.ts +15 -0
  120. package/dist/cjs/server/compiler.d.ts +3 -4
  121. package/dist/cjs/server/executor.d.ts +15 -0
  122. package/dist/cjs/server/index.d.ts +2 -0
  123. package/dist/cjs/server/query-handlers.d.ts +1 -0
  124. package/dist/cjs/server/query-validator.d.ts +36 -4
  125. package/dist/cjs/server/types/core.d.ts +5 -0
  126. package/dist/cjs/server/types/cube.d.ts +12 -0
  127. package/dist/cjs/server/types/query.d.ts +8 -0
  128. package/dist/cli/index.cjs +134 -52
  129. package/dist/client/charts/chartConfigRegistry.d.ts +7 -0
  130. package/dist/client/charts/chartConfigs.d.ts +17 -1
  131. package/dist/client/charts.js +13 -13
  132. package/dist/client/chunks/{DashboardEditModal-9An5EDAz.js → DashboardEditModal-BliiIHcI.js} +1653 -1188
  133. package/dist/client/chunks/DashboardEditModal-BliiIHcI.js.map +1 -0
  134. package/dist/client/chunks/DotStripChart-ChwsVeRU.js +408 -0
  135. package/dist/client/chunks/DotStripChart-ChwsVeRU.js.map +1 -0
  136. package/dist/client/chunks/{ProportionBarChart-BVcbGY2C.js → ProportionBarChart-D-Qt9nkF.js} +3 -3
  137. package/dist/client/chunks/{ProportionBarChart-BVcbGY2C.js.map → ProportionBarChart-D-Qt9nkF.js.map} +1 -1
  138. package/dist/client/chunks/RecordsTable-aG-QYXOH.js +556 -0
  139. package/dist/client/chunks/RecordsTable-aG-QYXOH.js.map +1 -0
  140. package/dist/client/chunks/{RetentionCombinedChart-D68Rvdi-.js → RetentionCombinedChart-BRZ9w7ah.js} +3 -3
  141. package/dist/client/chunks/{RetentionCombinedChart-D68Rvdi-.js.map → RetentionCombinedChart-BRZ9w7ah.js.map} +1 -1
  142. package/dist/client/chunks/{RetentionHeatmap-CE7BAjrB.js → RetentionHeatmap-LkTt89pK.js} +2 -2
  143. package/dist/client/chunks/{RetentionHeatmap-CE7BAjrB.js.map → RetentionHeatmap-LkTt89pK.js.map} +1 -1
  144. package/dist/client/chunks/{analysis-builder-D1pYvvwc.js → analysis-builder-C0gJ3kDD.js} +169 -168
  145. package/dist/client/chunks/{analysis-builder-D1pYvvwc.js.map → analysis-builder-C0gJ3kDD.js.map} +1 -1
  146. package/dist/client/chunks/{analysis-builder-shared-BQvwUc6z.js → analysis-builder-shared-dqcpl_WL.js} +965 -954
  147. package/dist/client/chunks/analysis-builder-shared-dqcpl_WL.js.map +1 -0
  148. package/dist/client/chunks/{chart-activity-grid-DvD_4wJz.js → chart-activity-grid-CJzxC18G.js} +175 -84
  149. package/dist/client/chunks/chart-activity-grid-CJzxC18G.js.map +1 -0
  150. package/dist/client/chunks/{chart-area-DPp3hSOK.js → chart-area-C66dgy84.js} +21 -21
  151. package/dist/client/chunks/{chart-area-DPp3hSOK.js.map → chart-area-C66dgy84.js.map} +1 -1
  152. package/dist/client/chunks/{chart-bar-Od3pOyZ0.js → chart-bar-D9kiSOCT.js} +5 -5
  153. package/dist/client/chunks/{chart-bar-Od3pOyZ0.js.map → chart-bar-D9kiSOCT.js.map} +1 -1
  154. package/dist/client/chunks/{chart-box-plot-l0iFn2n2.js → chart-box-plot-FsLIMisc.js} +2 -2
  155. package/dist/client/chunks/{chart-box-plot-l0iFn2n2.js.map → chart-box-plot-FsLIMisc.js.map} +1 -1
  156. package/dist/client/chunks/{chart-bubble-Dl0RcP8N.js → chart-bubble-BzyvrqKs.js} +2 -2
  157. package/dist/client/chunks/{chart-bubble-Dl0RcP8N.js.map → chart-bubble-BzyvrqKs.js.map} +1 -1
  158. package/dist/client/chunks/{chart-candlestick-DZMqbscF.js → chart-candlestick-6lD35bLw.js} +2 -2
  159. package/dist/client/chunks/{chart-candlestick-DZMqbscF.js.map → chart-candlestick-6lD35bLw.js.map} +1 -1
  160. package/dist/client/chunks/{chart-data-table-DgiNBOWf.js → chart-data-table-Cou9qOab.js} +1222 -1029
  161. package/dist/client/chunks/chart-data-table-Cou9qOab.js.map +1 -0
  162. package/dist/client/chunks/{chart-funnel-YLZlyN1X.js → chart-funnel-B0775aaT.js} +2 -2
  163. package/dist/client/chunks/{chart-funnel-YLZlyN1X.js.map → chart-funnel-B0775aaT.js.map} +1 -1
  164. package/dist/client/chunks/{chart-gauge-BsqE2wwF.js → chart-gauge-pf-2E8w9.js} +3 -3
  165. package/dist/client/chunks/{chart-gauge-BsqE2wwF.js.map → chart-gauge-pf-2E8w9.js.map} +1 -1
  166. package/dist/client/chunks/{chart-heat-map-BsND8RM_.js → chart-heat-map-EzVGe6fl.js} +3 -3
  167. package/dist/client/chunks/{chart-heat-map-BsND8RM_.js.map → chart-heat-map-EzVGe6fl.js.map} +1 -1
  168. package/dist/client/chunks/{chart-kpi-delta-m0azuva-.js → chart-kpi-delta-lfskDdx4.js} +3 -3
  169. package/dist/client/chunks/{chart-kpi-delta-m0azuva-.js.map → chart-kpi-delta-lfskDdx4.js.map} +1 -1
  170. package/dist/client/chunks/{chart-kpi-number-6JS15SqF.js → chart-kpi-number-BnsofbTf.js} +5 -5
  171. package/dist/client/chunks/{chart-kpi-number-6JS15SqF.js.map → chart-kpi-number-BnsofbTf.js.map} +1 -1
  172. package/dist/client/chunks/{chart-kpi-text-BqX8p8Jn.js → chart-kpi-text-U5EdmdkV.js} +3 -3
  173. package/dist/client/chunks/{chart-kpi-text-BqX8p8Jn.js.map → chart-kpi-text-U5EdmdkV.js.map} +1 -1
  174. package/dist/client/chunks/{chart-line-NCmpxBfE.js → chart-line-IwXqPY80.js} +3 -3
  175. package/dist/client/chunks/{chart-line-NCmpxBfE.js.map → chart-line-IwXqPY80.js.map} +1 -1
  176. package/dist/client/chunks/{chart-markdown-ZOobqiiX.js → chart-markdown-yxN_xBP9.js} +2 -2
  177. package/dist/client/chunks/{chart-markdown-ZOobqiiX.js.map → chart-markdown-yxN_xBP9.js.map} +1 -1
  178. package/dist/client/chunks/{chart-measure-profile-CBAZaicJ.js → chart-measure-profile-Bs4vhBJQ.js} +3 -3
  179. package/dist/client/chunks/{chart-measure-profile-CBAZaicJ.js.map → chart-measure-profile-Bs4vhBJQ.js.map} +1 -1
  180. package/dist/client/chunks/{chart-pie-ChrasEI8.js → chart-pie-LDJfDXfX.js} +15 -15
  181. package/dist/client/chunks/{chart-pie-ChrasEI8.js.map → chart-pie-LDJfDXfX.js.map} +1 -1
  182. package/dist/client/chunks/{chart-radar-CxSVF7yL.js → chart-radar-BZY6TP9m.js} +13 -13
  183. package/dist/client/chunks/{chart-radar-CxSVF7yL.js.map → chart-radar-BZY6TP9m.js.map} +1 -1
  184. package/dist/client/chunks/{chart-radial-bar--SN0Wph0.js → chart-radial-bar-aga05X7h.js} +3 -3
  185. package/dist/client/chunks/{chart-radial-bar--SN0Wph0.js.map → chart-radial-bar-aga05X7h.js.map} +1 -1
  186. package/dist/client/chunks/{chart-sankey-CDOSGg9r.js → chart-sankey-MRCoWFd4.js} +2 -2
  187. package/dist/client/chunks/{chart-sankey-CDOSGg9r.js.map → chart-sankey-MRCoWFd4.js.map} +1 -1
  188. package/dist/client/chunks/{chart-scatter-DgcEF-kI.js → chart-scatter-DP-nn9hH.js} +3 -3
  189. package/dist/client/chunks/{chart-scatter-DgcEF-kI.js.map → chart-scatter-DP-nn9hH.js.map} +1 -1
  190. package/dist/client/chunks/{chart-sunburst-MB-jlGBm.js → chart-sunburst-DE4EX7zi.js} +3 -3
  191. package/dist/client/chunks/{chart-sunburst-MB-jlGBm.js.map → chart-sunburst-DE4EX7zi.js.map} +1 -1
  192. package/dist/client/chunks/{chart-tree-map-DeDXveVd.js → chart-tree-map-C3O6uQcP.js} +3 -3
  193. package/dist/client/chunks/{chart-tree-map-DeDXveVd.js.map → chart-tree-map-C3O6uQcP.js.map} +1 -1
  194. package/dist/client/chunks/{chart-waterfall-ur4vkO1j.js → chart-waterfall-DU2Fg_7P.js} +3 -3
  195. package/dist/client/chunks/{chart-waterfall-ur4vkO1j.js.map → chart-waterfall-DU2Fg_7P.js.map} +1 -1
  196. package/dist/client/chunks/charts-core-DnirPG1F.js +190 -0
  197. package/dist/client/chunks/charts-core-DnirPG1F.js.map +1 -0
  198. package/dist/client/chunks/charts-loader-tCSbqT7H.js +87 -0
  199. package/dist/client/chunks/charts-loader-tCSbqT7H.js.map +1 -0
  200. package/dist/client/chunks/{en-US-BE6VoG0o.js → en-US-HP6FHuNy.js} +3 -1
  201. package/dist/client/chunks/{en-US-BE6VoG0o.js.map → en-US-HP6FHuNy.js.map} +1 -1
  202. package/dist/client/chunks/{nl-NL-CMXHDBr0.js → nl-NL-B9VnaVAm.js} +89 -1
  203. package/dist/client/chunks/nl-NL-B9VnaVAm.js.map +1 -0
  204. package/dist/client/chunks/{schema-visualization-BEbFtUIL.js → schema-visualization-o1zzuMQy.js} +3 -3
  205. package/dist/client/chunks/{schema-visualization-BEbFtUIL.js.map → schema-visualization-o1zzuMQy.js.map} +1 -1
  206. package/dist/client/chunks/{useDirtyStateTracking-CSDg96Rw.js → useDirtyStateTracking-DTYbmRBn.js} +15 -15
  207. package/dist/client/chunks/{useDirtyStateTracking-CSDg96Rw.js.map → useDirtyStateTracking-DTYbmRBn.js.map} +1 -1
  208. package/dist/client/chunks/{useExplainAI-BnkoZ-zS.js → useExplainAI-MuC9jBn-.js} +16 -16
  209. package/dist/client/chunks/{useExplainAI-BnkoZ-zS.js.map → useExplainAI-MuC9jBn-.js.map} +1 -1
  210. package/dist/client/chunks/{vendor-BmJDaduD.js → vendor-XQT9APIq.js} +49 -49
  211. package/dist/client/chunks/{vendor-BmJDaduD.js.map → vendor-XQT9APIq.js.map} +1 -1
  212. package/dist/client/client/CubeClient.d.ts +11 -1
  213. package/dist/client/components/AnalysisBuilder/AnalysisDisplayConfigPanel.d.ts +4 -2
  214. package/dist/client/components/AnalysisBuilder/ColumnFormatsEditor.d.ts +10 -0
  215. package/dist/client/components/AnalysisBuilder/DisplayOptionControl.d.ts +3 -2
  216. package/dist/client/components/AnalysisBuilder/utils/queryUtils.d.ts +7 -1
  217. package/dist/client/components/analyticsPortlet/PortletChart.d.ts +2 -1
  218. package/dist/client/components/analyticsPortlet/PortletChartView.d.ts +4 -1
  219. package/dist/client/components/analyticsPortlet/usePortletDeadMembers.d.ts +24 -0
  220. package/dist/client/components/analyticsPortlet/usePortletPagination.d.ts +21 -0
  221. package/dist/client/components/charts/DotStripChart.config.d.ts +15 -0
  222. package/dist/client/components/charts/DotStripChart.d.ts +4 -0
  223. package/dist/client/components/charts/DotStripChart.helpers.d.ts +91 -0
  224. package/dist/client/components/charts/RecordsTable.config.d.ts +10 -0
  225. package/dist/client/components/charts/RecordsTable.d.ts +4 -0
  226. package/dist/client/components/charts/recordsTableHooks.d.ts +68 -0
  227. package/dist/client/components.js +1 -1
  228. package/dist/client/hooks.js +3 -3
  229. package/dist/client/icons/types.d.ts +2 -0
  230. package/dist/client/icons.js +2 -2
  231. package/dist/client/index.d.ts +2 -2
  232. package/dist/client/index.js +213 -213
  233. package/dist/client/providers.js +1 -1
  234. package/dist/client/schema.js +1 -1
  235. package/dist/client/styles.css +1 -1
  236. package/dist/client/types.d.ts +97 -1
  237. package/dist/client/utils/recordsTableUtils.d.ts +71 -0
  238. package/dist/client/utils/rowLinkUtils.d.ts +35 -0
  239. package/dist/client/utils.js +14 -14
  240. package/dist/client-bundle-stats.html +1 -1
  241. package/dist/mcp-app/mcp-app.html +101 -101
  242. package/dist/server/agent/chart-validation.d.ts +1 -1
  243. package/dist/server/ai/chart-schema.d.ts +117 -0
  244. package/dist/server/ai/discovery-helpers.d.ts +14 -0
  245. package/dist/server/ai/discovery.d.ts +6 -0
  246. package/dist/server/ai/query-schema.d.ts +1 -1
  247. package/dist/server/attribute-dimensions.d.ts +11 -8
  248. package/dist/server/builders/group-by-builder.d.ts +15 -0
  249. package/dist/server/compiler.d.ts +3 -4
  250. package/dist/server/executor.d.ts +15 -0
  251. package/dist/{adapters/google-eKAc20al.js → server/google-DRY7jnOh.js} +46 -28
  252. package/dist/server/{google-BhvizbFR.cjs → google-PsZzwedr.cjs} +2 -2
  253. package/dist/server/index.cjs +34 -34
  254. package/dist/server/index.d.ts +2 -0
  255. package/dist/server/index.js +1913 -1445
  256. package/dist/server/query-handlers.d.ts +1 -0
  257. package/dist/server/query-validator.d.ts +36 -4
  258. package/dist/server/types/core.d.ts +5 -0
  259. package/dist/server/types/cube.d.ts +12 -0
  260. package/dist/server/types/query.d.ts +8 -0
  261. package/package.json +1 -1
  262. package/dist/adapters/ActivityGridChart.config-BQhBE_Mr.js +0 -2
  263. package/dist/adapters/ActivityGridChart.config-C3tSuOGV.cjs +0 -1
  264. package/dist/adapters/AreaChart.config-3cme8HyQ.js +0 -2
  265. package/dist/adapters/AreaChart.config-BSxrT52Z.cjs +0 -1
  266. package/dist/adapters/BarChart.config-BKS8IecE.cjs +0 -1
  267. package/dist/adapters/BarChart.config-lt_7PdIi.js +0 -2
  268. package/dist/adapters/BoxPlotChart.config-B7qvRnrF.cjs +0 -1
  269. package/dist/adapters/BoxPlotChart.config-Dv6ECj2j.js +0 -2
  270. package/dist/adapters/BubbleChart.config-BrIH7OAy.cjs +0 -1
  271. package/dist/adapters/BubbleChart.config-Fhotb7Pg.js +0 -2
  272. package/dist/adapters/CandlestickChart.config-CWH41FmF.cjs +0 -1
  273. package/dist/adapters/CandlestickChart.config-RPtXuxsX.js +0 -2
  274. package/dist/adapters/DataTable.config-71L0GzlT.js +0 -2
  275. package/dist/adapters/DataTable.config-BsOMQq3J.cjs +0 -1
  276. package/dist/adapters/FunnelChart.config-Cqte9C04.cjs +0 -1
  277. package/dist/adapters/FunnelChart.config-DJtwWeNz.js +0 -2
  278. package/dist/adapters/GaugeChart.config-WkwZ9VdS.cjs +0 -1
  279. package/dist/adapters/GaugeChart.config-vpVQlP5B.js +0 -2
  280. package/dist/adapters/HeatMapChart.config-DcmkDl07.cjs +0 -1
  281. package/dist/adapters/HeatMapChart.config-DsmMgGxJ.js +0 -2
  282. package/dist/adapters/KpiDelta.config-DVy561BH.js +0 -2
  283. package/dist/adapters/KpiDelta.config-dpqwLHNE.cjs +0 -1
  284. package/dist/adapters/KpiNumber.config-927l8nq8.js +0 -2
  285. package/dist/adapters/KpiNumber.config-BqFBMfPf.cjs +0 -1
  286. package/dist/adapters/KpiText.config-C-fZXuHq.cjs +0 -1
  287. package/dist/adapters/KpiText.config-CWoXuhMA.js +0 -2
  288. package/dist/adapters/LineChart.config-DTp7pqOY.js +0 -2
  289. package/dist/adapters/LineChart.config-DUGvSjcH.cjs +0 -1
  290. package/dist/adapters/MarkdownChart.config-23Dmv2Ty.cjs +0 -1
  291. package/dist/adapters/MarkdownChart.config-Cb2TnS0I.js +0 -2
  292. package/dist/adapters/MeasureProfileChart.config-B2qbWdhy.cjs +0 -1
  293. package/dist/adapters/MeasureProfileChart.config-CvBCeI5b.js +0 -2
  294. package/dist/adapters/PieChart.config-BzJb13QA.js +0 -2
  295. package/dist/adapters/PieChart.config-plCn5Ehr.cjs +0 -1
  296. package/dist/adapters/ProportionBarChart.config-1r-_moBH.cjs +0 -1
  297. package/dist/adapters/ProportionBarChart.config-CN6TtHTp.js +0 -2
  298. package/dist/adapters/RadarChart.config-BYhdj9M7.js +0 -2
  299. package/dist/adapters/RadarChart.config-CeUMP-1g.cjs +0 -1
  300. package/dist/adapters/RadialBarChart.config-B88yXNsq.cjs +0 -1
  301. package/dist/adapters/RadialBarChart.config-ZMK9HMoh.js +0 -2
  302. package/dist/adapters/RetentionCombinedChart.config-B5yvgUHM.cjs +0 -1
  303. package/dist/adapters/RetentionCombinedChart.config-Dd-YMdK8.js +0 -2
  304. package/dist/adapters/RetentionHeatmap.config-BYzDleoV.cjs +0 -1
  305. package/dist/adapters/RetentionHeatmap.config-Dvj7yTB0.js +0 -2
  306. package/dist/adapters/SankeyChart.config-CPFRmgFb.cjs +0 -1
  307. package/dist/adapters/SankeyChart.config-ClgqXM1N.js +0 -2
  308. package/dist/adapters/ScatterChart.config-CvJiqPa5.cjs +0 -1
  309. package/dist/adapters/ScatterChart.config-DLZ3rYMq.js +0 -2
  310. package/dist/adapters/SunburstChart.config-C_1V5hoQ.cjs +0 -1
  311. package/dist/adapters/SunburstChart.config-FNU75NCg.js +0 -2
  312. package/dist/adapters/TreeMapChart.config-CprZk_YF.js +0 -2
  313. package/dist/adapters/TreeMapChart.config-DNwd0ge9.cjs +0 -1
  314. package/dist/adapters/WaterfallChart.config-BBhcN_Fh.cjs +0 -1
  315. package/dist/adapters/WaterfallChart.config-H7s6SSV3.js +0 -2
  316. package/dist/adapters/compiler-BaLO10VN.cjs +0 -166
  317. package/dist/adapters/handler-DrRT6c14.cjs +0 -25
  318. package/dist/adapters/mcp-transport-BGkSz-ZT.cjs +0 -40
  319. package/dist/adapters/mcp-transport-fJud19xz.js +0 -606
  320. package/dist/adapters/utils-BY0-KFyI.cjs +0 -128
  321. package/dist/client/chunks/DashboardEditModal-9An5EDAz.js.map +0 -1
  322. package/dist/client/chunks/analysis-builder-shared-BQvwUc6z.js.map +0 -1
  323. package/dist/client/chunks/chart-activity-grid-DvD_4wJz.js.map +0 -1
  324. package/dist/client/chunks/chart-data-table-DgiNBOWf.js.map +0 -1
  325. package/dist/client/chunks/charts-core-BAH5pkSB.js +0 -215
  326. package/dist/client/chunks/charts-core-BAH5pkSB.js.map +0 -1
  327. package/dist/client/chunks/charts-loader-eToV8je7.js +0 -85
  328. package/dist/client/chunks/charts-loader-eToV8je7.js.map +0 -1
  329. package/dist/client/chunks/nl-NL-CMXHDBr0.js.map +0 -1
@@ -71,7 +71,7 @@ export interface CubeMeta {
71
71
  }
72
72
  export type FieldLabelMap = Record<string, string>;
73
73
  export type { ColorPalette } from './utils/colorPalettes.js';
74
- export type BuiltInChartType = 'line' | 'bar' | 'pie' | 'table' | 'area' | 'scatter' | 'radar' | 'radialBar' | 'treemap' | 'bubble' | 'activityGrid' | 'kpiNumber' | 'kpiDelta' | 'kpiText' | 'markdown' | 'funnel' | 'sankey' | 'sunburst' | 'heatmap' | 'retentionHeatmap' | 'retentionCombined' | 'boxPlot' | 'waterfall' | 'candlestick' | 'proportionBar' | 'measureProfile' | 'gauge';
74
+ export type BuiltInChartType = 'line' | 'bar' | 'pie' | 'table' | 'area' | 'scatter' | 'radar' | 'radialBar' | 'treemap' | 'bubble' | 'activityGrid' | 'kpiNumber' | 'kpiDelta' | 'kpiText' | 'markdown' | 'funnel' | 'sankey' | 'sunburst' | 'heatmap' | 'retentionHeatmap' | 'retentionCombined' | 'boxPlot' | 'dotStrip' | 'waterfall' | 'candlestick' | 'proportionBar' | 'measureProfile' | 'gauge' | 'recordsTable';
75
75
  export type ChartType = BuiltInChartType | (string & {});
76
76
  export interface AxisFormatConfig {
77
77
  label?: string;
@@ -80,6 +80,7 @@ export interface AxisFormatConfig {
80
80
  decimals?: number;
81
81
  customPrefix?: string;
82
82
  customSuffix?: string;
83
+ currencyCode?: string;
83
84
  }
84
85
  export interface ChartAxisConfig {
85
86
  xAxis?: string[];
@@ -89,10 +90,49 @@ export interface ChartAxisConfig {
89
90
  colorField?: string;
90
91
  dateField?: string[];
91
92
  valueField?: string[];
93
+ columns?: string[];
94
+ hiddenColumns?: string[];
92
95
  x?: string;
93
96
  y?: string[];
94
97
  yAxisAssignment?: Record<string, 'left' | 'right'>;
95
98
  }
99
+ /**
100
+ * How a records-table column renders its value. Chosen per column in the chart
101
+ * editor — never inferred from the data, so the same field can be a badge in one
102
+ * dashboard and plain text in another.
103
+ */
104
+ export type ColumnFormatKind = 'text' | 'number' | 'date' | 'badge' | 'progress';
105
+ export interface ColumnFormatConfig {
106
+ kind: ColumnFormatKind;
107
+ /** Numeric formatting for `kind: 'number'` — reuses the shared axis formatter. */
108
+ numberFormat?: AxisFormatConfig;
109
+ /** Granularity for `kind: 'date'`. */
110
+ dateGranularity?: TimeGranularity;
111
+ /**
112
+ * Value → palette colour index for `kind: 'badge'`. Values with no mapping
113
+ * render neutral rather than being assigned a guessed colour.
114
+ */
115
+ badgeColors?: Array<{
116
+ value: string;
117
+ colorIndex: number;
118
+ }>;
119
+ /** Bounds for `kind: 'progress'` (default 0-100). Values are clamped. */
120
+ progressMin?: number;
121
+ progressMax?: number;
122
+ /** How a `kind: 'progress'` cell draws: a full-width bar, or a compact ring for narrow columns. */
123
+ progressStyle?: 'bar' | 'circle';
124
+ /** Header override; falls back to the field's metadata title. */
125
+ label?: string;
126
+ align?: 'left' | 'right';
127
+ }
128
+ /**
129
+ * Row-level click-through for the records table. Tokens of the form
130
+ * `{Cube.field}` are substituted from the row, including hidden columns.
131
+ */
132
+ export interface RowLinkConfig {
133
+ urlTemplate: string;
134
+ target?: 'self' | 'blank';
135
+ }
96
136
  export interface ThresholdBand {
97
137
  value: number;
98
138
  color: string;
@@ -118,7 +158,16 @@ export interface ChartDisplayConfig {
118
158
  showPercentages?: boolean;
119
159
  sortSegments?: boolean;
120
160
  fitToWidth?: boolean;
161
+ showMedianMarker?: boolean;
162
+ showBandStats?: boolean;
163
+ showExtremeLabels?: boolean;
164
+ dotSize?: 'small' | 'medium' | 'large';
165
+ bandSort?: 'none' | 'valueDesc' | 'valueAsc' | 'count';
121
166
  pivotTimeDimension?: boolean;
167
+ columnFormats?: Record<string, ColumnFormatConfig>;
168
+ columnWidths?: Record<string, number>;
169
+ rowLink?: RowLinkConfig;
170
+ pageSize?: number;
122
171
  target?: string;
123
172
  template?: string;
124
173
  prefix?: string;
@@ -353,6 +402,12 @@ export interface CubeQuery {
353
402
  segments?: string[];
354
403
  /** When true, returns raw row-level data without GROUP BY or aggregation */
355
404
  ungrouped?: boolean;
405
+ /**
406
+ * Ask the server for the number of rows the query would return with no
407
+ * limit/offset, read back via `CubeResultSet.totalCount()`. Costs a second
408
+ * round trip, so only paginated views set it.
409
+ */
410
+ total?: boolean;
356
411
  }
357
412
  /**
358
413
  * Merge strategy for combining multiple query results
@@ -389,6 +444,17 @@ export interface CubeApiOptions {
389
444
  headers?: Record<string, string>;
390
445
  credentials?: 'include' | 'omit' | 'same-origin';
391
446
  }
447
+ /**
448
+ * An unknown member the server rejected, mirroring the server's
449
+ * `QueryValidationIssue`. `source` is what decides the response: a projected
450
+ * member can be dropped and the query re-run, whereas dropping a filter would
451
+ * widen the result set and must stay an error.
452
+ */
453
+ export interface CubeValidationIssue {
454
+ source: 'measure' | 'dimension' | 'timeDimension' | 'filter';
455
+ member: string;
456
+ message: string;
457
+ }
392
458
  export interface CubeResultSet {
393
459
  rawData(): any[];
394
460
  tablePivot(): any[];
@@ -401,6 +467,8 @@ export interface CubeResultSet {
401
467
  ttlMs: number;
402
468
  ttlRemainingMs: number;
403
469
  } | undefined;
470
+ /** Rows the query would return without limit/offset — only when `total: true` was asked for. */
471
+ totalCount?(): number | undefined;
404
472
  }
405
473
  export interface AnalyticsPortletProps {
406
474
  query: string;
@@ -464,6 +532,34 @@ export interface ChartProps {
464
532
  onDataPointClick?: (event: import('./types/drill.js').ChartDataPointClickEvent) => void;
465
533
  /** Whether drill-down is enabled (shows pointer cursor on clickable elements) */
466
534
  drillEnabled?: boolean;
535
+ /**
536
+ * Server-side pagination, supplied by hosts that can re-query (the dashboard
537
+ * portlet). Absent in the AnalysisBuilder preview, the notebook and plugin
538
+ * hosts, where a chart pages and sorts over the rows it already has.
539
+ */
540
+ pagination?: ChartPagination;
541
+ }
542
+ /**
543
+ * Paging and sorting state a host drives on the chart's behalf.
544
+ *
545
+ * Sort lives here rather than in the chart because with server-side paging a
546
+ * header click has to re-order the whole result set: sorting only the loaded
547
+ * page would put the wrong rows on page 1.
548
+ */
549
+ export interface ChartPagination {
550
+ page: number;
551
+ pageSize: number;
552
+ pageSizeOptions: number[];
553
+ /** Total matching rows, once the server has reported one. */
554
+ total?: number;
555
+ sort?: {
556
+ column: string;
557
+ direction: 'asc' | 'desc';
558
+ };
559
+ setPage: (page: number) => void;
560
+ setPageSize: (pageSize: number) => void;
561
+ /** Cycles the column asc → desc → unsorted, resetting to the first page. */
562
+ toggleSort: (column: string) => void;
467
563
  }
468
564
  export interface ThumbnailFeatureConfig {
469
565
  enabled: boolean;
@@ -0,0 +1,71 @@
1
+ import { ColumnFormatConfig } from '../types.js';
2
+ /** Fallback when an author has not sized a column. */
3
+ export declare const DEFAULT_COLUMN_WIDTH = 160;
4
+ /** Narrower than this and the resize handle overlaps the header text. */
5
+ export declare const MIN_COLUMN_WIDTH = 60;
6
+ /**
7
+ * Identity under which a viewer's column widths are remembered.
8
+ *
9
+ * A chart component has no portlet id, so widths key on the columns themselves:
10
+ * two records tables showing the same fields share widths, which is the
11
+ * behaviour an author would expect from two views of the same records.
12
+ */
13
+ export declare function columnWidthStorageKey(columns: string[]): string;
14
+ export declare function loadColumnWidths(key: string): Record<string, number>;
15
+ export declare function saveColumnWidths(key: string, widths: Record<string, number>): void;
16
+ /**
17
+ * A viewer's own column order, remembered under the same identity as widths.
18
+ *
19
+ * Stored as a list rather than a map so it survives the author adding or
20
+ * removing a column: {@link applyColumnOrder} reconciles it against the
21
+ * columns that actually exist.
22
+ */
23
+ export declare function loadColumnOrder(key: string): string[];
24
+ export declare function saveColumnOrder(key: string, order: string[]): void;
25
+ /**
26
+ * Lay a remembered order over the columns the chart actually has.
27
+ *
28
+ * Columns the order does not mention keep their authored position relative to
29
+ * the end, so an author adding a column still sees it rather than having it
30
+ * silently swallowed by a stale local order.
31
+ */
32
+ export declare function applyColumnOrder(columns: string[], order: string[]): string[];
33
+ /** Move one column to another's position, returning a new order. */
34
+ export declare function moveColumn(columns: string[], from: string, to: string): string[];
35
+ /**
36
+ * A cell resolved to something renderable. `progress` carries its own shape
37
+ * because the component draws a bar or a ring rather than a string; every
38
+ * other kind reduces to text plus, for badges, a colour.
39
+ *
40
+ * The component only ever sees a `RenderedCell`, so the progress `style` is
41
+ * resolved here rather than being read back out of the column's config.
42
+ */
43
+ export type RenderedCell = {
44
+ kind: 'text';
45
+ text: string;
46
+ } | {
47
+ kind: 'badge';
48
+ text: string;
49
+ colorIndex?: number;
50
+ } | {
51
+ kind: 'progress';
52
+ text: string;
53
+ fraction: number;
54
+ style: 'bar' | 'circle';
55
+ };
56
+ /**
57
+ * Turn a raw cell value into its display form under the column's format.
58
+ *
59
+ * Every kind degrades to text rather than erroring: a non-numeric value under
60
+ * `number`/`progress` renders as-is (EAV columns legitimately contain 'n/a'),
61
+ * and a badge value with no colour mapping renders neutral rather than being
62
+ * given a guessed colour.
63
+ */
64
+ export declare function renderCellValue(value: unknown, format: ColumnFormatConfig | undefined): RenderedCell;
65
+ /**
66
+ * Sort rows by one column, client-side.
67
+ *
68
+ * Only used when the host provides no server-side pagination — with paging on,
69
+ * sorting the loaded page alone would put the wrong rows on page 1.
70
+ */
71
+ export declare function sortRows(rows: Record<string, unknown>[], column: string, direction: 'asc' | 'desc'): Record<string, unknown>[];
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Row click-through URLs for the records table.
3
+ *
4
+ * A dashboard author writes a template such as `/employees/{Employees.id}`,
5
+ * and each row fills its own tokens. The template is author-controlled but the
6
+ * *values* are data, so they are percent-encoded before substitution — an
7
+ * encoded value cannot introduce a scheme, a path segment or a query separator.
8
+ *
9
+ * The resulting URL is then checked rather than trusted: only same-origin
10
+ * relative paths and absolute http(s) URLs are allowed through.
11
+ */
12
+ /**
13
+ * Resolve a row link template against one row.
14
+ *
15
+ * Returns `null` — meaning "render no link" — when the template references a
16
+ * field the row does not carry, or when the result is not a URL we are willing
17
+ * to navigate to. Never throws: a malformed template must not take the table
18
+ * down with it.
19
+ *
20
+ * @param template - e.g. `/employees/{Employees.id}?tab=profile`
21
+ * @param row - the row's values, including hidden columns
22
+ * @param origin - the origin relative URLs are resolved against
23
+ */
24
+ export declare function buildRowUrl(template: string | undefined, row: Record<string, unknown>, origin?: string): string | null;
25
+ /**
26
+ * Whether a URL is one we will navigate to: an absolute `http(s)` URL, or a
27
+ * path that stays on this origin.
28
+ *
29
+ * Rejected, deliberately: `javascript:`, `data:`, `vbscript:` and every other
30
+ * scheme; protocol-relative `//evil.example`, which inherits the current scheme
31
+ * and silently leaves the origin; and backslash forms such as `\\evil.example`
32
+ * or `/\evil.example`, which several browsers normalise into that same
33
+ * protocol-relative shape.
34
+ */
35
+ export declare function isSafeUrl(url: string, origin?: string): boolean;
@@ -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";
@@ -81,14 +81,17 @@ export interface BuildAttributeDimensionsOptions {
81
81
  * returned by a subquery" on Postgres.
82
82
  * - **Security inside the subquery**, not merely on the outer query.
83
83
  *
84
- * **Grouping limitation.** The subquery correlates on the record key, so a
85
- * *grouped* query must also group by that key `dimensions: ['Employees.id',
86
- * 'Employees.attr_1']` is fine, `dimensions: ['Employees.attr_1']` with a
87
- * measure is not. Postgres rejects the latter with "subquery uses ungrouped
88
- * column from outer query", and MySQL with `only_full_group_by`; SQLite
89
- * permits it. Record-grain listings (`ungrouped: true`) — the case this exists
90
- * for are unaffected. If you need to aggregate freely by an attribute, pivot
91
- * it into a real column with a view (see the performance ladder below).
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.
92
95
  *
93
96
  * Performance: projection is cheap (a page of 25 rows is 25 indexed lookups per
94
97
  * attribute), but `ORDER BY (SELECT …)` and `WHERE (SELECT …) = …` are
@@ -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.
@@ -1,6 +1,8 @@
1
1
  import { SemanticQuery, QueryResult, SecurityContext, DatabaseExecutor, CubeMetadata, Cube, QueryAnalysis, CacheConfig, ExplainOptions, ExplainResult, ExecutionOptions, RLSSetupFn } from './types/index.js';
2
+ import { QueryValidationResult } from './query-validator.js';
2
3
  import { PlanOptimiser } from './logical-plan/index.js';
3
4
  export { validateQueryAgainstCubes } from './query-validator.js';
5
+ export type { QueryValidationIssue, QueryValidationResult } from './query-validator.js';
4
6
  /**
5
7
  * Identifier of the base cube set — the cubes registered with {@link
6
8
  * SemanticLayerCompiler.registerCube}, shared by every tenant. The empty string
@@ -346,10 +348,7 @@ export declare class SemanticLayerCompiler {
346
348
  * Validate a query against registered cubes
347
349
  * Ensures all referenced cubes and fields exist
348
350
  */
349
- validateQuery(query: SemanticQuery, securityContext: SecurityContext): {
350
- isValid: boolean;
351
- errors: string[];
352
- };
351
+ validateQuery(query: SemanticQuery, securityContext: SecurityContext): QueryValidationResult;
353
352
  /**
354
353
  * Analyze query planning decisions for debugging and transparency
355
354
  * Returns detailed metadata about how the query would be planned
@@ -95,6 +95,21 @@ export declare class QueryExecutor {
95
95
  * (e.g. comparison period sub-queries cache at the comparison level).
96
96
  */
97
97
  private executeStandardQuery;
98
+ /**
99
+ * Count the rows the query would return with no limit or offset — Cube's
100
+ * `total`.
101
+ *
102
+ * Rebuilds the *same* physical plan with pagination and ordering stripped and
103
+ * counts over it as a subquery. The wrapper is what makes a grouped query
104
+ * count groups rather than base rows, and rebuilding from `planQuery` rather
105
+ * than reading the paginated query's effective values matters because
106
+ * `applyLimitAndOffset` injects a default limit when an offset arrives
107
+ * without one.
108
+ *
109
+ * Runs inside the caller's RLS context, so the count sees exactly the rows
110
+ * the page did.
111
+ */
112
+ private executeTotalCount;
98
113
  /**
99
114
  * Create a query context with optional filter cache.
100
115
  */
@@ -6,6 +6,8 @@ import { SemanticLayerCompiler } from './compiler.js';
6
6
  */
7
7
  export { SemanticLayerCompiler, BASE_CUBE_SET_ID, SINGLE_TENANT_CONTEXT } from './compiler.js';
8
8
  export type { CubeSetRegistrationInfo, CubeSetStats } from './compiler.js';
9
+ export { QueryValidationError } from './query-validator.js';
10
+ export type { QueryValidationIssue, QueryValidationResult } from './query-validator.js';
9
11
  export { buildAttributeDimensions } from './attribute-dimensions.js';
10
12
  export type { AttributeDefinition, AttributeValueType, BuildAttributeDimensionsOptions } from './attribute-dimensions.js';
11
13
  export { QueryExecutor } from './executor.js';
@@ -76,4 +76,5 @@ export declare function handleLoad(semanticLayer: SemanticLayerCompiler, securit
76
76
  data: Record<string, unknown>[];
77
77
  annotation: any;
78
78
  query: SemanticQuery;
79
+ total?: number;
79
80
  }>;
@@ -1,9 +1,41 @@
1
1
  import { SemanticQuery, Cube } from './types/index.js';
2
2
  /**
3
- * Validate a query against a cubes map
4
- * Standalone function that can be used by both compiler and executor
3
+ * A member the query references that no cube provides, reported alongside the
4
+ * human-readable errors.
5
+ *
6
+ * The joined error string cannot be split back apart reliably — the per-field
7
+ * "did you mean" hints contain the same separator — so a caller that wants to
8
+ * react to a *specific* missing member (a dashboard dropping a column for a
9
+ * deleted attribute, say) needs this rather than the prose. `source` is the
10
+ * part that matters: dropping a projected member narrows what is displayed,
11
+ * whereas dropping a filter would widen the result set, so the two cannot be
12
+ * treated alike.
13
+ */
14
+ export interface QueryValidationIssue {
15
+ source: 'measure' | 'dimension' | 'timeDimension' | 'filter';
16
+ /** The full `Cube.field` reference as the query wrote it. */
17
+ member: string;
18
+ message: string;
19
+ }
20
+ /**
21
+ * Thrown when a query fails validation during execution.
22
+ *
23
+ * Carries the structured issues alongside the joined message so a caller can
24
+ * react to a specific unknown member — the batch endpoint, which validates
25
+ * inside execution rather than ahead of it, would otherwise only have prose.
5
26
  */
6
- export declare function validateQueryAgainstCubes(cubes: Map<string, Cube>, query: SemanticQuery): {
27
+ export declare class QueryValidationError extends Error {
28
+ readonly issues: QueryValidationIssue[];
29
+ constructor(message: string, issues: QueryValidationIssue[]);
30
+ }
31
+ export interface QueryValidationResult {
7
32
  isValid: boolean;
8
33
  errors: string[];
9
- };
34
+ /** Unknown members, when any — see {@link QueryValidationIssue}. */
35
+ issues: QueryValidationIssue[];
36
+ }
37
+ /**
38
+ * Validate a query against a cubes map
39
+ * Standalone function that can be used by both compiler and executor
40
+ */
41
+ export declare function validateQueryAgainstCubes(cubes: Map<string, Cube>, query: SemanticQuery): QueryValidationResult;
@@ -57,6 +57,11 @@ export interface QueryResult {
57
57
  };
58
58
  /** Warnings about potential query issues (e.g., fan-out without dimensions) */
59
59
  warnings?: QueryWarning[];
60
+ /**
61
+ * Total rows the query would return with no limit/offset, present only when
62
+ * the query asked for it with `total: true`.
63
+ */
64
+ total?: number;
60
65
  }
61
66
  /**
62
67
  * Period comparison metadata for compareDateRange queries
@@ -160,6 +160,18 @@ export interface Dimension {
160
160
  sql: AnyColumn | SQL | ((ctx: QueryContext) => AnyColumn | SQL);
161
161
  /** Whether this is a primary key */
162
162
  primaryKey?: boolean;
163
+ /**
164
+ * The column this dimension's SQL correlates on, for dimensions built from a
165
+ * correlated subquery (see `buildAttributeDimensions`).
166
+ *
167
+ * A correlated subquery in the SELECT list is only legal under GROUP BY when
168
+ * the column it correlates on is itself grouped: Postgres otherwise rejects
169
+ * the query with "subquery uses ungrouped column … from outer query", and
170
+ * MySQL does the same under `only_full_group_by`. The planner cannot see
171
+ * inside an opaque `sql` function, so a dimension that needs this declares it
172
+ * and the GROUP BY builder adds the key.
173
+ */
174
+ correlatesOn?: AnyColumn;
163
175
  /**
164
176
  * Whether to include this dimension in generated cube metadata (`/meta`,
165
177
  * the client field picker, AI prompts). Defaults to `true` (shown) when
@@ -32,6 +32,14 @@ export interface SemanticQuery {
32
32
  * - Incompatible with compareDateRange and fillMissingDates
33
33
  */
34
34
  ungrouped?: boolean;
35
+ /**
36
+ * Return the number of rows the query would produce with no `limit` or
37
+ * `offset` applied, as `QueryResult.total`. Matches Cube's `total`.
38
+ *
39
+ * Costs a second round trip: the same plan is rebuilt without pagination and
40
+ * counted, wrapped so a grouped query counts groups rather than base rows.
41
+ */
42
+ total?: boolean;
35
43
  /**
36
44
  * Funnel analysis configuration for query-time funnel definition.
37
45
  * When specified, the query executes as a funnel analysis instead of