@finos/legend-cube-builder 0.0.4 → 0.0.6

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 (719) hide show
  1. package/README.md +9 -3
  2. package/docs/adding-an-operation.md +24 -12
  3. package/docs/demo/DEMO-FAST-NOTES.md +67 -0
  4. package/docs/demo/README.md +102 -0
  5. package/docs/demo/specs/duckdb-sales-pivot.cube.json +110 -0
  6. package/docs/demo/specs/trades-desks-1-joined.cube.json +123 -0
  7. package/docs/demo/specs/trades-desks-2-grouped.cube.json +140 -0
  8. package/docs/demo/specs/trades-desks-3-ranked.cube.json +158 -0
  9. package/docs/demo/specs/trades-desks-4-extended.cube.json +208 -0
  10. package/docs/demo/specs/trades-desks-5-final.cube.json +248 -0
  11. package/docs/hosting.md +83 -5
  12. package/docs/testing.md +32 -0
  13. package/lib/__lib__/LegendCubeCommand.d.ts +2 -0
  14. package/lib/__lib__/LegendCubeCommand.d.ts.map +1 -1
  15. package/lib/__lib__/LegendCubeCommand.js +7 -0
  16. package/lib/__lib__/LegendCubeCommand.js.map +1 -1
  17. package/lib/__lib__/LegendCubeFunctionLabels.d.ts +29 -0
  18. package/lib/__lib__/LegendCubeFunctionLabels.d.ts.map +1 -0
  19. package/lib/__lib__/LegendCubeFunctionLabels.js +31 -0
  20. package/lib/__lib__/LegendCubeFunctionLabels.js.map +1 -0
  21. package/lib/__lib__/LegendCubeHelpText.d.ts +5 -1
  22. package/lib/__lib__/LegendCubeHelpText.d.ts.map +1 -1
  23. package/lib/__lib__/LegendCubeHelpText.js +16 -2
  24. package/lib/__lib__/LegendCubeHelpText.js.map +1 -1
  25. package/lib/__lib__/LegendCubeLabels.d.ts +130 -9
  26. package/lib/__lib__/LegendCubeLabels.d.ts.map +1 -1
  27. package/lib/__lib__/LegendCubeLabels.js +169 -17
  28. package/lib/__lib__/LegendCubeLabels.js.map +1 -1
  29. package/lib/__lib__/LegendCubeNavigation.d.ts +23 -0
  30. package/lib/__lib__/LegendCubeNavigation.d.ts.map +1 -0
  31. package/lib/__lib__/LegendCubeNavigation.js +33 -0
  32. package/lib/__lib__/LegendCubeNavigation.js.map +1 -0
  33. package/lib/__lib__/LegendCubeProjectSourceLabels.d.ts +26 -0
  34. package/lib/__lib__/LegendCubeProjectSourceLabels.d.ts.map +1 -0
  35. package/lib/__lib__/LegendCubeProjectSourceLabels.js +26 -0
  36. package/lib/__lib__/LegendCubeProjectSourceLabels.js.map +1 -0
  37. package/lib/__lib__/LegendCubeServiceLabels.d.ts +27 -0
  38. package/lib/__lib__/LegendCubeServiceLabels.d.ts.map +1 -0
  39. package/lib/__lib__/LegendCubeServiceLabels.js +32 -0
  40. package/lib/__lib__/LegendCubeServiceLabels.js.map +1 -0
  41. package/lib/__lib__/LegendCubeTesting.d.ts +10 -1
  42. package/lib/__lib__/LegendCubeTesting.d.ts.map +1 -1
  43. package/lib/__lib__/LegendCubeTesting.js +9 -0
  44. package/lib/__lib__/LegendCubeTesting.js.map +1 -1
  45. package/lib/__lib__/LegendCubeTour.d.ts +62 -0
  46. package/lib/__lib__/LegendCubeTour.d.ts.map +1 -0
  47. package/lib/__lib__/LegendCubeTour.js +149 -0
  48. package/lib/__lib__/LegendCubeTour.js.map +1 -0
  49. package/lib/__test-utils__/CubeEngineTestSupport.d.ts +1 -1
  50. package/lib/__test-utils__/CubeEngineTestSupport.d.ts.map +1 -1
  51. package/lib/__test-utils__/CubeEngineTestSupport.js +2 -2
  52. package/lib/__test-utils__/CubeEngineTestSupport.js.map +1 -1
  53. package/lib/__test-utils__/CubeExampleTestUtils.d.ts +34 -0
  54. package/lib/__test-utils__/CubeExampleTestUtils.d.ts.map +1 -0
  55. package/lib/__test-utils__/CubeExampleTestUtils.js +72 -0
  56. package/lib/__test-utils__/CubeExampleTestUtils.js.map +1 -0
  57. package/lib/__test-utils__/CubeExpressionTestUtils.d.ts +8 -1
  58. package/lib/__test-utils__/CubeExpressionTestUtils.d.ts.map +1 -1
  59. package/lib/__test-utils__/CubeExpressionTestUtils.js +20 -3
  60. package/lib/__test-utils__/CubeExpressionTestUtils.js.map +1 -1
  61. package/lib/__test-utils__/CubeFunctionTestOutline.d.ts +26 -0
  62. package/lib/__test-utils__/CubeFunctionTestOutline.d.ts.map +1 -0
  63. package/lib/__test-utils__/CubeFunctionTestOutline.js +56 -0
  64. package/lib/__test-utils__/CubeFunctionTestOutline.js.map +1 -0
  65. package/lib/__test-utils__/CubeLambdaCorpus.d.ts +36 -0
  66. package/lib/__test-utils__/CubeLambdaCorpus.d.ts.map +1 -0
  67. package/lib/__test-utils__/CubeLambdaCorpus.js +83 -0
  68. package/lib/__test-utils__/CubeLambdaCorpus.js.map +1 -0
  69. package/lib/__test-utils__/CubePageTestUtils.d.ts +6 -0
  70. package/lib/__test-utils__/CubePageTestUtils.d.ts.map +1 -1
  71. package/lib/__test-utils__/CubePageTestUtils.js +21 -0
  72. package/lib/__test-utils__/CubePageTestUtils.js.map +1 -1
  73. package/lib/__test-utils__/CubeTestApplication.d.ts +9 -0
  74. package/lib/__test-utils__/CubeTestApplication.d.ts.map +1 -1
  75. package/lib/__test-utils__/CubeTestApplication.js +16 -0
  76. package/lib/__test-utils__/CubeTestApplication.js.map +1 -1
  77. package/lib/__test-utils__/CubeVariantTestUtils.d.ts +16 -0
  78. package/lib/__test-utils__/CubeVariantTestUtils.d.ts.map +1 -0
  79. package/lib/__test-utils__/CubeVariantTestUtils.js +66 -0
  80. package/lib/__test-utils__/CubeVariantTestUtils.js.map +1 -0
  81. package/lib/__test-utils__/FakeCubeEngine.d.ts +5 -0
  82. package/lib/__test-utils__/FakeCubeEngine.d.ts.map +1 -1
  83. package/lib/__test-utils__/FakeCubeEngine.js +17 -0
  84. package/lib/__test-utils__/FakeCubeEngine.js.map +1 -1
  85. package/lib/__test-utils__/FakeCubeIngestCatalog.d.ts +7 -1
  86. package/lib/__test-utils__/FakeCubeIngestCatalog.d.ts.map +1 -1
  87. package/lib/__test-utils__/FakeCubeIngestCatalog.js +16 -0
  88. package/lib/__test-utils__/FakeCubeIngestCatalog.js.map +1 -1
  89. package/lib/__test-utils__/FakeCubeServiceCatalog.d.ts +26 -0
  90. package/lib/__test-utils__/FakeCubeServiceCatalog.d.ts.map +1 -0
  91. package/lib/__test-utils__/FakeCubeServiceCatalog.js +40 -0
  92. package/lib/__test-utils__/FakeCubeServiceCatalog.js.map +1 -0
  93. package/lib/components/CubeAddItems.d.ts.map +1 -1
  94. package/lib/components/CubeAddItems.js +11 -7
  95. package/lib/components/CubeAddItems.js.map +1 -1
  96. package/lib/components/CubeDialogTheme.d.ts +25 -0
  97. package/lib/components/CubeDialogTheme.d.ts.map +1 -0
  98. package/lib/components/CubeDialogTheme.js +25 -0
  99. package/lib/components/CubeDialogTheme.js.map +1 -0
  100. package/lib/components/CubeEditor.d.ts +12 -1
  101. package/lib/components/CubeEditor.d.ts.map +1 -1
  102. package/lib/components/CubeEditor.js +22 -14
  103. package/lib/components/CubeEditor.js.map +1 -1
  104. package/lib/components/CubeFileMenu.d.ts +28 -0
  105. package/lib/components/CubeFileMenu.d.ts.map +1 -0
  106. package/lib/components/CubeFileMenu.js +78 -0
  107. package/lib/components/CubeFileMenu.js.map +1 -0
  108. package/lib/components/CubeLambdaImportBanner.d.ts +26 -0
  109. package/lib/components/CubeLambdaImportBanner.d.ts.map +1 -0
  110. package/lib/components/CubeLambdaImportBanner.js +47 -0
  111. package/lib/components/CubeLambdaImportBanner.js.map +1 -0
  112. package/lib/components/CubeNodeIcon.d.ts.map +1 -1
  113. package/lib/components/CubeNodeIcon.js +6 -1
  114. package/lib/components/CubeNodeIcon.js.map +1 -1
  115. package/lib/components/CubeSchemaColumnsTable.d.ts.map +1 -1
  116. package/lib/components/CubeSchemaColumnsTable.js +2 -2
  117. package/lib/components/CubeSchemaColumnsTable.js.map +1 -1
  118. package/lib/components/canvas/CubeCanvas.d.ts.map +1 -1
  119. package/lib/components/canvas/CubeCanvas.js +40 -6
  120. package/lib/components/canvas/CubeCanvas.js.map +1 -1
  121. package/lib/components/canvas/CubeCanvasContextMenu.d.ts.map +1 -1
  122. package/lib/components/canvas/CubeCanvasContextMenu.js +2 -1
  123. package/lib/components/canvas/CubeCanvasContextMenu.js.map +1 -1
  124. package/lib/components/canvas/CubeCanvasElements.d.ts +18 -1
  125. package/lib/components/canvas/CubeCanvasElements.d.ts.map +1 -1
  126. package/lib/components/canvas/CubeCanvasElements.js +58 -3
  127. package/lib/components/canvas/CubeCanvasElements.js.map +1 -1
  128. package/lib/components/canvas/CubeCanvasLayout.js +1 -1
  129. package/lib/components/canvas/CubeCanvasNode.d.ts.map +1 -1
  130. package/lib/components/canvas/CubeCanvasNode.js +11 -4
  131. package/lib/components/canvas/CubeCanvasNode.js.map +1 -1
  132. package/lib/components/dev-settings/CubeDevSettings.d.ts +35 -0
  133. package/lib/components/dev-settings/CubeDevSettings.d.ts.map +1 -0
  134. package/lib/components/dev-settings/CubeDevSettings.js +54 -0
  135. package/lib/components/dev-settings/CubeDevSettings.js.map +1 -0
  136. package/lib/components/editors/CubeColumnChecklist.d.ts.map +1 -1
  137. package/lib/components/editors/CubeColumnChecklist.js +2 -2
  138. package/lib/components/editors/CubeColumnChecklist.js.map +1 -1
  139. package/lib/components/editors/CubeColumnPicker.d.ts.map +1 -1
  140. package/lib/components/editors/CubeColumnPicker.js +6 -4
  141. package/lib/components/editors/CubeColumnPicker.js.map +1 -1
  142. package/lib/components/editors/CubeConcatEditor.js +2 -2
  143. package/lib/components/editors/CubeConcatEditor.js.map +1 -1
  144. package/lib/components/editors/CubeExplodeEditor.d.ts +26 -0
  145. package/lib/components/editors/CubeExplodeEditor.d.ts.map +1 -0
  146. package/lib/components/editors/CubeExplodeEditor.js +61 -0
  147. package/lib/components/editors/CubeExplodeEditor.js.map +1 -0
  148. package/lib/components/editors/CubeExpressionFilterEditor.d.ts +25 -0
  149. package/lib/components/editors/CubeExpressionFilterEditor.d.ts.map +1 -0
  150. package/lib/components/editors/CubeExpressionFilterEditor.js +86 -0
  151. package/lib/components/editors/CubeExpressionFilterEditor.js.map +1 -0
  152. package/lib/components/editors/CubeExtendEditor.d.ts.map +1 -1
  153. package/lib/components/editors/CubeExtendEditor.js +13 -12
  154. package/lib/components/editors/CubeExtendEditor.js.map +1 -1
  155. package/lib/components/editors/CubeFilterEditor.d.ts.map +1 -1
  156. package/lib/components/editors/CubeFilterEditor.js +13 -2
  157. package/lib/components/editors/CubeFilterEditor.js.map +1 -1
  158. package/lib/components/editors/CubeFunctionSourceEditor.d.ts +25 -0
  159. package/lib/components/editors/CubeFunctionSourceEditor.d.ts.map +1 -0
  160. package/lib/components/editors/CubeFunctionSourceEditor.js +55 -0
  161. package/lib/components/editors/CubeFunctionSourceEditor.js.map +1 -0
  162. package/lib/components/editors/CubeJoinEditor.d.ts.map +1 -1
  163. package/lib/components/editors/CubeJoinEditor.js +16 -4
  164. package/lib/components/editors/CubeJoinEditor.js.map +1 -1
  165. package/lib/components/editors/CubeJsonFieldsTree.d.ts +46 -0
  166. package/lib/components/editors/CubeJsonFieldsTree.d.ts.map +1 -0
  167. package/lib/components/editors/CubeJsonFieldsTree.js +93 -0
  168. package/lib/components/editors/CubeJsonFieldsTree.js.map +1 -0
  169. package/lib/components/editors/CubeNodeEditorPanel.d.ts.map +1 -1
  170. package/lib/components/editors/CubeNodeEditorPanel.js +18 -8
  171. package/lib/components/editors/CubeNodeEditorPanel.js.map +1 -1
  172. package/lib/components/editors/CubeNodeEditorPopper.d.ts +5 -1
  173. package/lib/components/editors/CubeNodeEditorPopper.d.ts.map +1 -1
  174. package/lib/components/editors/CubeNodeEditorPopper.js +10 -2
  175. package/lib/components/editors/CubeNodeEditorPopper.js.map +1 -1
  176. package/lib/components/editors/CubeNodeEditorRegistry.d.ts.map +1 -1
  177. package/lib/components/editors/CubeNodeEditorRegistry.js +11 -1
  178. package/lib/components/editors/CubeNodeEditorRegistry.js.map +1 -1
  179. package/lib/components/editors/CubePivotEditor.d.ts +26 -0
  180. package/lib/components/editors/CubePivotEditor.d.ts.map +1 -0
  181. package/lib/components/editors/CubePivotEditor.js +93 -0
  182. package/lib/components/editors/CubePivotEditor.js.map +1 -0
  183. package/lib/components/editors/CubeRestrictEditor.d.ts.map +1 -1
  184. package/lib/components/editors/CubeRestrictEditor.js +2 -2
  185. package/lib/components/editors/CubeRestrictEditor.js.map +1 -1
  186. package/lib/components/editors/CubeServiceSourceEditor.d.ts +25 -0
  187. package/lib/components/editors/CubeServiceSourceEditor.d.ts.map +1 -0
  188. package/lib/components/editors/CubeServiceSourceEditor.js +41 -0
  189. package/lib/components/editors/CubeServiceSourceEditor.js.map +1 -0
  190. package/lib/components/grid/CubeColumnFormatDialog.d.ts +28 -0
  191. package/lib/components/grid/CubeColumnFormatDialog.d.ts.map +1 -0
  192. package/lib/components/grid/CubeColumnFormatDialog.js +94 -0
  193. package/lib/components/grid/CubeColumnFormatDialog.js.map +1 -0
  194. package/lib/components/grid/CubeDrilldownBar.d.ts +37 -0
  195. package/lib/components/grid/CubeDrilldownBar.d.ts.map +1 -0
  196. package/lib/components/grid/CubeDrilldownBar.js +77 -0
  197. package/lib/components/grid/CubeDrilldownBar.js.map +1 -0
  198. package/lib/components/grid/CubeGridRegion.d.ts.map +1 -1
  199. package/lib/components/grid/CubeGridRegion.js +43 -28
  200. package/lib/components/grid/CubeGridRegion.js.map +1 -1
  201. package/lib/components/grid/CubeGridValues.d.ts +36 -4
  202. package/lib/components/grid/CubeGridValues.d.ts.map +1 -1
  203. package/lib/components/grid/CubeGridValues.js +116 -4
  204. package/lib/components/grid/CubeGridValues.js.map +1 -1
  205. package/lib/components/grid/CubeJsonExplorerDialog.d.ts +27 -0
  206. package/lib/components/grid/CubeJsonExplorerDialog.d.ts.map +1 -0
  207. package/lib/components/grid/CubeJsonExplorerDialog.js +102 -0
  208. package/lib/components/grid/CubeJsonExplorerDialog.js.map +1 -0
  209. package/lib/components/grid/CubeJsonViewerDialog.d.ts +27 -0
  210. package/lib/components/grid/CubeJsonViewerDialog.d.ts.map +1 -0
  211. package/lib/components/grid/CubeJsonViewerDialog.js +68 -0
  212. package/lib/components/grid/CubeJsonViewerDialog.js.map +1 -0
  213. package/lib/components/grid/CubeResultGrid.d.ts +81 -6
  214. package/lib/components/grid/CubeResultGrid.d.ts.map +1 -1
  215. package/lib/components/grid/CubeResultGrid.js +400 -35
  216. package/lib/components/grid/CubeResultGrid.js.map +1 -1
  217. package/lib/components/grid/CubeRunStatsPanel.d.ts +28 -0
  218. package/lib/components/grid/CubeRunStatsPanel.d.ts.map +1 -0
  219. package/lib/components/grid/CubeRunStatsPanel.js +61 -0
  220. package/lib/components/grid/CubeRunStatsPanel.js.map +1 -0
  221. package/lib/components/grid/CubeServerSideGrid.d.ts +36 -0
  222. package/lib/components/grid/CubeServerSideGrid.d.ts.map +1 -0
  223. package/lib/components/grid/CubeServerSideGrid.js +116 -0
  224. package/lib/components/grid/CubeServerSideGrid.js.map +1 -0
  225. package/lib/components/grid/CubeSqlDialog.d.ts +24 -0
  226. package/lib/components/grid/CubeSqlDialog.d.ts.map +1 -0
  227. package/lib/components/grid/CubeSqlDialog.js +39 -0
  228. package/lib/components/grid/CubeSqlDialog.js.map +1 -0
  229. package/lib/components/grid/CubeSqlFormat.d.ts +20 -0
  230. package/lib/components/grid/CubeSqlFormat.d.ts.map +1 -0
  231. package/lib/components/grid/CubeSqlFormat.js +32 -0
  232. package/lib/components/grid/CubeSqlFormat.js.map +1 -0
  233. package/lib/components/palette/CubePalette.d.ts.map +1 -1
  234. package/lib/components/palette/CubePalette.js +36 -14
  235. package/lib/components/palette/CubePalette.js.map +1 -1
  236. package/lib/components/show-pure/CubeShowPureDialog.d.ts +4 -1
  237. package/lib/components/show-pure/CubeShowPureDialog.d.ts.map +1 -1
  238. package/lib/components/show-pure/CubeShowPureDialog.js +8 -4
  239. package/lib/components/show-pure/CubeShowPureDialog.js.map +1 -1
  240. package/lib/components/source-picker/CubeDataProductTab.d.ts.map +1 -1
  241. package/lib/components/source-picker/CubeDataProductTab.js +37 -16
  242. package/lib/components/source-picker/CubeDataProductTab.js.map +1 -1
  243. package/lib/components/source-picker/CubeDirectConnectionTab.d.ts.map +1 -1
  244. package/lib/components/source-picker/CubeDirectConnectionTab.js +6 -4
  245. package/lib/components/source-picker/CubeDirectConnectionTab.js.map +1 -1
  246. package/lib/components/source-picker/CubeFunctionSteps.d.ts +36 -0
  247. package/lib/components/source-picker/CubeFunctionSteps.d.ts.map +1 -0
  248. package/lib/components/source-picker/CubeFunctionSteps.js +76 -0
  249. package/lib/components/source-picker/CubeFunctionSteps.js.map +1 -0
  250. package/lib/components/source-picker/CubeIngestTab.d.ts +2 -2
  251. package/lib/components/source-picker/CubeIngestTab.d.ts.map +1 -1
  252. package/lib/components/source-picker/CubeIngestTab.js +49 -20
  253. package/lib/components/source-picker/CubeIngestTab.js.map +1 -1
  254. package/lib/components/source-picker/CubeInlineModelTab.d.ts +3 -2
  255. package/lib/components/source-picker/CubeInlineModelTab.d.ts.map +1 -1
  256. package/lib/components/source-picker/CubeInlineModelTab.js +23 -13
  257. package/lib/components/source-picker/CubeInlineModelTab.js.map +1 -1
  258. package/lib/components/source-picker/CubePickerListItem.d.ts +47 -0
  259. package/lib/components/source-picker/CubePickerListItem.d.ts.map +1 -0
  260. package/lib/components/source-picker/CubePickerListItem.js +62 -0
  261. package/lib/components/source-picker/CubePickerListItem.js.map +1 -0
  262. package/lib/components/source-picker/CubeProjectTab.d.ts +4 -3
  263. package/lib/components/source-picker/CubeProjectTab.d.ts.map +1 -1
  264. package/lib/components/source-picker/CubeProjectTab.js +7 -4
  265. package/lib/components/source-picker/CubeProjectTab.js.map +1 -1
  266. package/lib/components/source-picker/CubeServiceTab.d.ts +27 -0
  267. package/lib/components/source-picker/CubeServiceTab.d.ts.map +1 -0
  268. package/lib/components/source-picker/CubeServiceTab.js +36 -0
  269. package/lib/components/source-picker/CubeServiceTab.js.map +1 -0
  270. package/lib/components/source-picker/CubeSourcePicker.d.ts.map +1 -1
  271. package/lib/components/source-picker/CubeSourcePicker.js +16 -3
  272. package/lib/components/source-picker/CubeSourcePicker.js.map +1 -1
  273. package/lib/components/source-picker/CubeTablePreview.d.ts +29 -0
  274. package/lib/components/source-picker/CubeTablePreview.d.ts.map +1 -0
  275. package/lib/components/source-picker/CubeTablePreview.js +10 -0
  276. package/lib/components/source-picker/CubeTablePreview.js.map +1 -0
  277. package/lib/components/spec-transfer/CubeImportPureDialog.d.ts +27 -0
  278. package/lib/components/spec-transfer/CubeImportPureDialog.d.ts.map +1 -0
  279. package/lib/components/spec-transfer/CubeImportPureDialog.js +38 -0
  280. package/lib/components/spec-transfer/CubeImportPureDialog.js.map +1 -0
  281. package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts.map +1 -1
  282. package/lib/components/spec-transfer/CubeSpecTransferDialog.js +9 -3
  283. package/lib/components/spec-transfer/CubeSpecTransferDialog.js.map +1 -1
  284. package/lib/components/tour/CubeTour.d.ts +36 -0
  285. package/lib/components/tour/CubeTour.d.ts.map +1 -0
  286. package/lib/components/tour/CubeTour.js +183 -0
  287. package/lib/components/tour/CubeTour.js.map +1 -0
  288. package/lib/graph-manager/CubeDataProductCatalog.d.ts +10 -0
  289. package/lib/graph-manager/CubeDataProductCatalog.d.ts.map +1 -1
  290. package/lib/graph-manager/CubeDataProductCatalog.js.map +1 -1
  291. package/lib/graph-manager/CubeEngine.d.ts +46 -1
  292. package/lib/graph-manager/CubeEngine.d.ts.map +1 -1
  293. package/lib/graph-manager/CubeEngine.js.map +1 -1
  294. package/lib/graph-manager/CubeEngineClientSettings.d.ts +43 -0
  295. package/lib/graph-manager/CubeEngineClientSettings.d.ts.map +1 -0
  296. package/lib/graph-manager/CubeEngineClientSettings.js +51 -0
  297. package/lib/graph-manager/CubeEngineClientSettings.js.map +1 -0
  298. package/lib/graph-manager/CubeIngest.d.ts +5 -0
  299. package/lib/graph-manager/CubeIngest.d.ts.map +1 -1
  300. package/lib/graph-manager/CubeIngest.js +10 -0
  301. package/lib/graph-manager/CubeIngest.js.map +1 -1
  302. package/lib/graph-manager/CubeIngestCatalog.d.ts +26 -0
  303. package/lib/graph-manager/CubeIngestCatalog.d.ts.map +1 -1
  304. package/lib/graph-manager/CubeIngestCatalog.js +6 -0
  305. package/lib/graph-manager/CubeIngestCatalog.js.map +1 -1
  306. package/lib/graph-manager/CubeLakehouseRuntime.d.ts +29 -0
  307. package/lib/graph-manager/CubeLakehouseRuntime.d.ts.map +1 -0
  308. package/lib/graph-manager/CubeLakehouseRuntime.js +40 -0
  309. package/lib/graph-manager/CubeLakehouseRuntime.js.map +1 -0
  310. package/lib/graph-manager/CubeProjectCatalog.d.ts +3 -3
  311. package/lib/graph-manager/CubeService.d.ts +20 -0
  312. package/lib/graph-manager/CubeService.d.ts.map +1 -0
  313. package/lib/graph-manager/CubeService.js +22 -0
  314. package/lib/graph-manager/CubeService.js.map +1 -0
  315. package/lib/graph-manager/CubeServiceCatalog.d.ts +31 -0
  316. package/lib/graph-manager/CubeServiceCatalog.d.ts.map +1 -0
  317. package/lib/graph-manager/CubeServiceCatalog.js +17 -0
  318. package/lib/graph-manager/CubeServiceCatalog.js.map +1 -0
  319. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts +52 -5
  320. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts.map +1 -1
  321. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js +63 -5
  322. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js.map +1 -1
  323. package/lib/graph-manager/protocol/pure/v1/V1_CubeDataProductModel.d.ts +9 -6
  324. package/lib/graph-manager/protocol/pure/v1/V1_CubeDataProductModel.d.ts.map +1 -1
  325. package/lib/graph-manager/protocol/pure/v1/V1_CubeDataProductModel.js +12 -8
  326. package/lib/graph-manager/protocol/pure/v1/V1_CubeDataProductModel.js.map +1 -1
  327. package/lib/graph-manager/protocol/pure/v1/V1_CubeFunctionOutlineBuilder.d.ts +30 -0
  328. package/lib/graph-manager/protocol/pure/v1/V1_CubeFunctionOutlineBuilder.d.ts.map +1 -0
  329. package/lib/graph-manager/protocol/pure/v1/V1_CubeFunctionOutlineBuilder.js +229 -0
  330. package/lib/graph-manager/protocol/pure/v1/V1_CubeFunctionOutlineBuilder.js.map +1 -0
  331. package/lib/graph-manager/protocol/pure/v1/V1_CubeIngestDefinition.d.ts.map +1 -1
  332. package/lib/graph-manager/protocol/pure/v1/V1_CubeIngestDefinition.js +18 -9
  333. package/lib/graph-manager/protocol/pure/v1/V1_CubeIngestDefinition.js.map +1 -1
  334. package/lib/graph-manager/protocol/pure/v1/V1_CubeIngestModel.d.ts +4 -9
  335. package/lib/graph-manager/protocol/pure/v1/V1_CubeIngestModel.d.ts.map +1 -1
  336. package/lib/graph-manager/protocol/pure/v1/V1_CubeIngestModel.js +2 -1
  337. package/lib/graph-manager/protocol/pure/v1/V1_CubeIngestModel.js.map +1 -1
  338. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaReader.d.ts +34 -0
  339. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaReader.d.ts.map +1 -0
  340. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaReader.js +332 -0
  341. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaReader.js.map +1 -0
  342. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts.map +1 -1
  343. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js +49 -10
  344. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js.map +1 -1
  345. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts +1 -1
  346. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts.map +1 -1
  347. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js +3 -1
  348. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js.map +1 -1
  349. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeConnectionExplorer.d.ts +2 -1
  350. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeConnectionExplorer.d.ts.map +1 -1
  351. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeConnectionExplorer.js +2 -1
  352. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeConnectionExplorer.js.map +1 -1
  353. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts +18 -0
  354. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts.map +1 -1
  355. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js +74 -6
  356. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js.map +1 -1
  357. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeProjectCatalog.d.ts.map +1 -1
  358. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeProjectCatalog.js +7 -4
  359. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeProjectCatalog.js.map +1 -1
  360. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeServiceCatalog.d.ts +31 -0
  361. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeServiceCatalog.d.ts.map +1 -0
  362. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeServiceCatalog.js +69 -0
  363. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeServiceCatalog.js.map +1 -0
  364. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts.map +1 -1
  365. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js +6 -2
  366. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js.map +1 -1
  367. package/lib/index.css +2 -2
  368. package/lib/index.css.map +1 -1
  369. package/lib/index.d.ts +13 -3
  370. package/lib/index.d.ts.map +1 -1
  371. package/lib/index.js +11 -1
  372. package/lib/index.js.map +1 -1
  373. package/lib/stores/CubeAddPlacement.d.ts +10 -3
  374. package/lib/stores/CubeAddPlacement.d.ts.map +1 -1
  375. package/lib/stores/CubeAddPlacement.js +16 -5
  376. package/lib/stores/CubeAddPlacement.js.map +1 -1
  377. package/lib/stores/CubeDevSettingsState.d.ts +47 -0
  378. package/lib/stores/CubeDevSettingsState.d.ts.map +1 -0
  379. package/lib/stores/CubeDevSettingsState.js +99 -0
  380. package/lib/stores/CubeDevSettingsState.js.map +1 -0
  381. package/lib/stores/CubeEditorState.d.ts +189 -43
  382. package/lib/stores/CubeEditorState.d.ts.map +1 -1
  383. package/lib/stores/CubeEditorState.js +532 -117
  384. package/lib/stores/CubeEditorState.js.map +1 -1
  385. package/lib/stores/CubeEngineChecks.d.ts +59 -0
  386. package/lib/stores/CubeEngineChecks.d.ts.map +1 -0
  387. package/lib/stores/CubeEngineChecks.js +100 -0
  388. package/lib/stores/CubeEngineChecks.js.map +1 -0
  389. package/lib/stores/CubeExamples.d.ts.map +1 -1
  390. package/lib/stores/CubeExamples.js +136 -2
  391. package/lib/stores/CubeExamples.js.map +1 -1
  392. package/lib/stores/CubeExamplesState.d.ts +1 -1
  393. package/lib/stores/CubeExamplesState.d.ts.map +1 -1
  394. package/lib/stores/CubeExamplesState.js +6 -3
  395. package/lib/stores/CubeExamplesState.js.map +1 -1
  396. package/lib/stores/CubeExecutionState.d.ts.map +1 -1
  397. package/lib/stores/CubeExecutionState.js +24 -33
  398. package/lib/stores/CubeExecutionState.js.map +1 -1
  399. package/lib/stores/CubeExportState.d.ts +41 -0
  400. package/lib/stores/CubeExportState.d.ts.map +1 -0
  401. package/lib/stores/CubeExportState.js +134 -0
  402. package/lib/stores/CubeExportState.js.map +1 -0
  403. package/lib/stores/CubeExpressionFilterCheck.d.ts +51 -0
  404. package/lib/stores/CubeExpressionFilterCheck.d.ts.map +1 -0
  405. package/lib/stores/CubeExpressionFilterCheck.js +134 -0
  406. package/lib/stores/CubeExpressionFilterCheck.js.map +1 -0
  407. package/lib/stores/CubeExtendTyping.d.ts +6 -14
  408. package/lib/stores/CubeExtendTyping.d.ts.map +1 -1
  409. package/lib/stores/CubeExtendTyping.js +6 -33
  410. package/lib/stores/CubeExtendTyping.js.map +1 -1
  411. package/lib/stores/CubeFunctionRecheck.d.ts +30 -0
  412. package/lib/stores/CubeFunctionRecheck.d.ts.map +1 -0
  413. package/lib/stores/CubeFunctionRecheck.js +67 -0
  414. package/lib/stores/CubeFunctionRecheck.js.map +1 -0
  415. package/lib/stores/CubeGridFetcher.d.ts +75 -0
  416. package/lib/stores/CubeGridFetcher.d.ts.map +1 -0
  417. package/lib/stores/CubeGridFetcher.js +197 -0
  418. package/lib/stores/CubeGridFetcher.js.map +1 -0
  419. package/lib/stores/CubeGridQuickActions.d.ts +25 -6
  420. package/lib/stores/CubeGridQuickActions.d.ts.map +1 -1
  421. package/lib/stores/CubeGridQuickActions.js +52 -23
  422. package/lib/stores/CubeGridQuickActions.js.map +1 -1
  423. package/lib/stores/CubeGridState.d.ts +136 -0
  424. package/lib/stores/CubeGridState.d.ts.map +1 -0
  425. package/lib/stores/CubeGridState.js +317 -0
  426. package/lib/stores/CubeGridState.js.map +1 -0
  427. package/lib/stores/CubeHost.d.ts +42 -0
  428. package/lib/stores/CubeHost.d.ts.map +1 -1
  429. package/lib/stores/CubeHost.js +4 -0
  430. package/lib/stores/CubeHost.js.map +1 -1
  431. package/lib/stores/CubeLambdaImportState.d.ts +118 -0
  432. package/lib/stores/CubeLambdaImportState.d.ts.map +1 -0
  433. package/lib/stores/CubeLambdaImportState.js +302 -0
  434. package/lib/stores/CubeLambdaImportState.js.map +1 -0
  435. package/lib/stores/CubeLambdaSources.d.ts +45 -0
  436. package/lib/stores/CubeLambdaSources.d.ts.map +1 -0
  437. package/lib/stores/CubeLambdaSources.js +261 -0
  438. package/lib/stores/CubeLambdaSources.js.map +1 -0
  439. package/lib/stores/CubePureText.d.ts +20 -0
  440. package/lib/stores/CubePureText.d.ts.map +1 -0
  441. package/lib/stores/CubePureText.js +24 -0
  442. package/lib/stores/CubePureText.js.map +1 -0
  443. package/lib/stores/CubeQueryRun.d.ts +59 -0
  444. package/lib/stores/CubeQueryRun.d.ts.map +1 -0
  445. package/lib/stores/CubeQueryRun.js +101 -0
  446. package/lib/stores/CubeQueryRun.js.map +1 -0
  447. package/lib/stores/CubeRunStatsState.d.ts +61 -0
  448. package/lib/stores/CubeRunStatsState.d.ts.map +1 -0
  449. package/lib/stores/CubeRunStatsState.js +54 -0
  450. package/lib/stores/CubeRunStatsState.js.map +1 -0
  451. package/lib/stores/CubeRunningStepLambda.d.ts +25 -0
  452. package/lib/stores/CubeRunningStepLambda.d.ts.map +1 -0
  453. package/lib/stores/CubeRunningStepLambda.js +45 -0
  454. package/lib/stores/CubeRunningStepLambda.js.map +1 -0
  455. package/lib/stores/CubeServiceRecheck.d.ts +29 -0
  456. package/lib/stores/CubeServiceRecheck.d.ts.map +1 -0
  457. package/lib/stores/CubeServiceRecheck.js +33 -0
  458. package/lib/stores/CubeServiceRecheck.js.map +1 -0
  459. package/lib/stores/CubeShowPureState.d.ts +14 -1
  460. package/lib/stores/CubeShowPureState.d.ts.map +1 -1
  461. package/lib/stores/CubeShowPureState.js +41 -11
  462. package/lib/stores/CubeShowPureState.js.map +1 -1
  463. package/lib/stores/CubeSourcePickerState.d.ts +20 -4
  464. package/lib/stores/CubeSourcePickerState.d.ts.map +1 -1
  465. package/lib/stores/CubeSourcePickerState.js +75 -14
  466. package/lib/stores/CubeSourcePickerState.js.map +1 -1
  467. package/lib/stores/CubeTourState.d.ts +49 -0
  468. package/lib/stores/CubeTourState.d.ts.map +1 -0
  469. package/lib/stores/CubeTourState.js +92 -0
  470. package/lib/stores/CubeTourState.js.map +1 -0
  471. package/lib/stores/LegendCubeHost.d.ts +88 -0
  472. package/lib/stores/LegendCubeHost.d.ts.map +1 -0
  473. package/lib/stores/LegendCubeHost.js +149 -0
  474. package/lib/stores/LegendCubeHost.js.map +1 -0
  475. package/lib/stores/LocalModelCatalog.d.ts.map +1 -1
  476. package/lib/stores/LocalModelCatalog.js +3 -1
  477. package/lib/stores/LocalModelCatalog.js.map +1 -1
  478. package/lib/stores/editors/CubeExplodeDraft.d.ts +87 -0
  479. package/lib/stores/editors/CubeExplodeDraft.d.ts.map +1 -0
  480. package/lib/stores/editors/CubeExplodeDraft.js +221 -0
  481. package/lib/stores/editors/CubeExplodeDraft.js.map +1 -0
  482. package/lib/stores/editors/CubeExpressionFilterDraft.d.ts +94 -0
  483. package/lib/stores/editors/CubeExpressionFilterDraft.d.ts.map +1 -0
  484. package/lib/stores/editors/CubeExpressionFilterDraft.js +258 -0
  485. package/lib/stores/editors/CubeExpressionFilterDraft.js.map +1 -0
  486. package/lib/stores/editors/CubeExtendDraft.d.ts +9 -0
  487. package/lib/stores/editors/CubeExtendDraft.d.ts.map +1 -1
  488. package/lib/stores/editors/CubeExtendDraft.js +26 -0
  489. package/lib/stores/editors/CubeExtendDraft.js.map +1 -1
  490. package/lib/stores/editors/CubeFunctionDraft.d.ts +34 -0
  491. package/lib/stores/editors/CubeFunctionDraft.d.ts.map +1 -0
  492. package/lib/stores/editors/CubeFunctionDraft.js +69 -0
  493. package/lib/stores/editors/CubeFunctionDraft.js.map +1 -0
  494. package/lib/stores/editors/CubeNodeDraftRegistry.d.ts +4 -2
  495. package/lib/stores/editors/CubeNodeDraftRegistry.d.ts.map +1 -1
  496. package/lib/stores/editors/CubeNodeDraftRegistry.js +25 -3
  497. package/lib/stores/editors/CubeNodeDraftRegistry.js.map +1 -1
  498. package/lib/stores/editors/CubePivotDraft.d.ts +93 -0
  499. package/lib/stores/editors/CubePivotDraft.d.ts.map +1 -0
  500. package/lib/stores/editors/CubePivotDraft.js +267 -0
  501. package/lib/stores/editors/CubePivotDraft.js.map +1 -0
  502. package/lib/stores/fixtures/CubeSalesDuckDbModel.d.ts +27 -0
  503. package/lib/stores/fixtures/CubeSalesDuckDbModel.d.ts.map +1 -0
  504. package/lib/stores/fixtures/CubeSalesDuckDbModel.js +52 -0
  505. package/lib/stores/fixtures/CubeSalesDuckDbModel.js.map +1 -0
  506. package/lib/stores/fixtures/CubeTradesModel.d.ts +4 -0
  507. package/lib/stores/fixtures/CubeTradesModel.d.ts.map +1 -1
  508. package/lib/stores/fixtures/CubeTradesModel.js +31 -1
  509. package/lib/stores/fixtures/CubeTradesModel.js.map +1 -1
  510. package/lib/stores/source-picker/CubeDataProductTabState.d.ts +34 -5
  511. package/lib/stores/source-picker/CubeDataProductTabState.d.ts.map +1 -1
  512. package/lib/stores/source-picker/CubeDataProductTabState.js +111 -26
  513. package/lib/stores/source-picker/CubeDataProductTabState.js.map +1 -1
  514. package/lib/stores/source-picker/CubeDirectConnectionTabState.d.ts +25 -2
  515. package/lib/stores/source-picker/CubeDirectConnectionTabState.d.ts.map +1 -1
  516. package/lib/stores/source-picker/CubeDirectConnectionTabState.js +183 -31
  517. package/lib/stores/source-picker/CubeDirectConnectionTabState.js.map +1 -1
  518. package/lib/stores/source-picker/CubeIngestTabState.d.ts +62 -15
  519. package/lib/stores/source-picker/CubeIngestTabState.d.ts.map +1 -1
  520. package/lib/stores/source-picker/CubeIngestTabState.js +212 -60
  521. package/lib/stores/source-picker/CubeIngestTabState.js.map +1 -1
  522. package/lib/stores/source-picker/CubeInlineModelTabState.d.ts +100 -4
  523. package/lib/stores/source-picker/CubeInlineModelTabState.d.ts.map +1 -1
  524. package/lib/stores/source-picker/CubeInlineModelTabState.js +415 -28
  525. package/lib/stores/source-picker/CubeInlineModelTabState.js.map +1 -1
  526. package/lib/stores/source-picker/CubeProjectTabState.d.ts +18 -3
  527. package/lib/stores/source-picker/CubeProjectTabState.d.ts.map +1 -1
  528. package/lib/stores/source-picker/CubeProjectTabState.js +26 -1
  529. package/lib/stores/source-picker/CubeProjectTabState.js.map +1 -1
  530. package/lib/stores/source-picker/CubeServiceTabState.d.ts +74 -0
  531. package/lib/stores/source-picker/CubeServiceTabState.d.ts.map +1 -0
  532. package/lib/stores/source-picker/CubeServiceTabState.js +216 -0
  533. package/lib/stores/source-picker/CubeServiceTabState.js.map +1 -0
  534. package/lib/stores/source-picker/CubeSourcePickerTab.d.ts +15 -3
  535. package/lib/stores/source-picker/CubeSourcePickerTab.d.ts.map +1 -1
  536. package/lib/stores/source-picker/CubeSourcePickerTab.js +21 -0
  537. package/lib/stores/source-picker/CubeSourcePickerTab.js.map +1 -1
  538. package/lib/stores/variant/CubeJson.d.ts +48 -0
  539. package/lib/stores/variant/CubeJson.d.ts.map +1 -0
  540. package/lib/stores/variant/CubeJson.js +207 -0
  541. package/lib/stores/variant/CubeJson.js.map +1 -0
  542. package/lib/stores/variant/CubeJsonExplorerState.d.ts +88 -0
  543. package/lib/stores/variant/CubeJsonExplorerState.d.ts.map +1 -0
  544. package/lib/stores/variant/CubeJsonExplorerState.js +297 -0
  545. package/lib/stores/variant/CubeJsonExplorerState.js.map +1 -0
  546. package/lib/stores/variant/CubeJsonFieldsState.d.ts +83 -0
  547. package/lib/stores/variant/CubeJsonFieldsState.d.ts.map +1 -0
  548. package/lib/stores/variant/CubeJsonFieldsState.js +207 -0
  549. package/lib/stores/variant/CubeJsonFieldsState.js.map +1 -0
  550. package/lib/stores/variant/CubeJsonOffers.d.ts +76 -0
  551. package/lib/stores/variant/CubeJsonOffers.d.ts.map +1 -0
  552. package/lib/stores/variant/CubeJsonOffers.js +250 -0
  553. package/lib/stores/variant/CubeJsonOffers.js.map +1 -0
  554. package/lib/stores/variant/CubeJsonParse.d.ts +28 -0
  555. package/lib/stores/variant/CubeJsonParse.d.ts.map +1 -0
  556. package/lib/stores/variant/CubeJsonParse.js +53 -0
  557. package/lib/stores/variant/CubeJsonParse.js.map +1 -0
  558. package/lib/stores/variant/CubeJsonSampling.d.ts +41 -0
  559. package/lib/stores/variant/CubeJsonSampling.d.ts.map +1 -0
  560. package/lib/stores/variant/CubeJsonSampling.js +59 -0
  561. package/lib/stores/variant/CubeJsonSampling.js.map +1 -0
  562. package/lib/stores/variant/CubeJsonShape.d.ts +87 -0
  563. package/lib/stores/variant/CubeJsonShape.d.ts.map +1 -0
  564. package/lib/stores/variant/CubeJsonShape.js +209 -0
  565. package/lib/stores/variant/CubeJsonShape.js.map +1 -0
  566. package/lib/stores/variant/CubeJsonViewerState.d.ts +33 -0
  567. package/lib/stores/variant/CubeJsonViewerState.d.ts.map +1 -0
  568. package/lib/stores/variant/CubeJsonViewerState.js +53 -0
  569. package/lib/stores/variant/CubeJsonViewerState.js.map +1 -0
  570. package/package.json +10 -9
  571. package/src/__lib__/LegendCubeCommand.ts +7 -0
  572. package/src/__lib__/LegendCubeFunctionLabels.ts +41 -0
  573. package/src/__lib__/LegendCubeHelpText.ts +27 -1
  574. package/src/__lib__/LegendCubeLabels.ts +225 -16
  575. package/src/__lib__/LegendCubeNavigation.ts +48 -0
  576. package/src/__lib__/LegendCubeProjectSourceLabels.ts +26 -0
  577. package/src/__lib__/LegendCubeServiceLabels.ts +41 -0
  578. package/src/__lib__/LegendCubeTesting.ts +9 -0
  579. package/src/__lib__/LegendCubeTour.ts +173 -0
  580. package/src/__test-utils__/CubeEngineTestSupport.ts +2 -1
  581. package/src/__test-utils__/CubeExampleTestUtils.ts +119 -0
  582. package/src/__test-utils__/CubeExpressionTestUtils.ts +29 -2
  583. package/src/__test-utils__/CubeFunctionTestOutline.ts +78 -0
  584. package/src/__test-utils__/CubeLambdaCorpus.ts +137 -0
  585. package/src/__test-utils__/CubePageTestUtils.tsx +34 -0
  586. package/src/__test-utils__/CubeTestApplication.ts +25 -0
  587. package/src/__test-utils__/CubeVariantTestUtils.ts +103 -0
  588. package/src/__test-utils__/FakeCubeEngine.ts +27 -0
  589. package/src/__test-utils__/FakeCubeIngestCatalog.ts +18 -0
  590. package/src/__test-utils__/FakeCubeServiceCatalog.ts +57 -0
  591. package/src/components/CubeAddItems.tsx +15 -6
  592. package/src/components/CubeDialogTheme.ts +25 -0
  593. package/src/components/CubeEditor.tsx +170 -129
  594. package/src/components/CubeFileMenu.tsx +129 -0
  595. package/src/components/CubeLambdaImportBanner.tsx +97 -0
  596. package/src/components/CubeNodeIcon.tsx +9 -0
  597. package/src/components/CubeSchemaColumnsTable.tsx +7 -2
  598. package/src/components/canvas/CubeCanvas.tsx +65 -10
  599. package/src/components/canvas/CubeCanvasContextMenu.tsx +33 -2
  600. package/src/components/canvas/CubeCanvasElements.ts +76 -3
  601. package/src/components/canvas/CubeCanvasLayout.ts +1 -1
  602. package/src/components/canvas/CubeCanvasNode.tsx +37 -3
  603. package/src/components/dev-settings/CubeDevSettings.tsx +169 -0
  604. package/src/components/editors/CubeColumnChecklist.tsx +8 -2
  605. package/src/components/editors/CubeColumnPicker.tsx +9 -3
  606. package/src/components/editors/CubeConcatEditor.tsx +2 -2
  607. package/src/components/editors/CubeExplodeEditor.tsx +207 -0
  608. package/src/components/editors/CubeExpressionFilterEditor.tsx +210 -0
  609. package/src/components/editors/CubeExtendEditor.tsx +34 -21
  610. package/src/components/editors/CubeFilterEditor.tsx +13 -1
  611. package/src/components/editors/CubeFunctionSourceEditor.tsx +140 -0
  612. package/src/components/editors/CubeJoinEditor.tsx +23 -4
  613. package/src/components/editors/CubeJsonFieldsTree.tsx +316 -0
  614. package/src/components/editors/CubeNodeEditorPanel.tsx +22 -10
  615. package/src/components/editors/CubeNodeEditorPopper.tsx +9 -1
  616. package/src/components/editors/CubeNodeEditorRegistry.ts +15 -0
  617. package/src/components/editors/CubePivotEditor.tsx +277 -0
  618. package/src/components/editors/CubeRestrictEditor.tsx +8 -2
  619. package/src/components/editors/CubeServiceSourceEditor.tsx +77 -0
  620. package/src/components/grid/CubeColumnFormatDialog.tsx +289 -0
  621. package/src/components/grid/CubeDrilldownBar.tsx +219 -0
  622. package/src/components/grid/CubeGridRegion.tsx +190 -56
  623. package/src/components/grid/CubeGridValues.ts +154 -4
  624. package/src/components/grid/CubeJsonExplorerDialog.tsx +304 -0
  625. package/src/components/grid/CubeJsonViewerDialog.tsx +190 -0
  626. package/src/components/grid/CubeResultGrid.tsx +586 -42
  627. package/src/components/grid/CubeRunStatsPanel.tsx +156 -0
  628. package/src/components/grid/CubeServerSideGrid.tsx +213 -0
  629. package/src/components/grid/CubeSqlDialog.tsx +90 -0
  630. package/src/components/grid/CubeSqlFormat.ts +37 -0
  631. package/src/components/palette/CubePalette.tsx +54 -12
  632. package/src/components/show-pure/CubeShowPureDialog.tsx +19 -5
  633. package/src/components/source-picker/CubeDataProductTab.tsx +169 -75
  634. package/src/components/source-picker/CubeDirectConnectionTab.tsx +42 -30
  635. package/src/components/source-picker/CubeFunctionSteps.tsx +244 -0
  636. package/src/components/source-picker/CubeIngestTab.tsx +195 -83
  637. package/src/components/source-picker/CubeInlineModelTab.tsx +110 -81
  638. package/src/components/source-picker/CubePickerListItem.tsx +118 -0
  639. package/src/components/source-picker/CubeProjectTab.tsx +6 -3
  640. package/src/components/source-picker/CubeServiceTab.tsx +151 -0
  641. package/src/components/source-picker/CubeSourcePicker.tsx +54 -18
  642. package/src/components/source-picker/CubeTablePreview.tsx +49 -0
  643. package/src/components/spec-transfer/CubeImportPureDialog.tsx +122 -0
  644. package/src/components/spec-transfer/CubeSpecTransferDialog.tsx +21 -8
  645. package/src/components/tour/CubeTour.tsx +317 -0
  646. package/src/graph-manager/CubeDataProductCatalog.ts +11 -0
  647. package/src/graph-manager/CubeEngine.ts +51 -1
  648. package/src/graph-manager/CubeEngineClientSettings.ts +64 -0
  649. package/src/graph-manager/CubeIngest.ts +15 -0
  650. package/src/graph-manager/CubeIngestCatalog.ts +33 -0
  651. package/src/graph-manager/CubeLakehouseRuntime.ts +43 -0
  652. package/src/graph-manager/CubeProjectCatalog.ts +3 -3
  653. package/src/graph-manager/CubeService.ts +29 -0
  654. package/src/graph-manager/CubeServiceCatalog.ts +35 -0
  655. package/src/graph-manager/protocol/pure/CubeEngineBuilder.ts +115 -5
  656. package/src/graph-manager/protocol/pure/v1/V1_CubeDataProductModel.ts +13 -7
  657. package/src/graph-manager/protocol/pure/v1/V1_CubeFunctionOutlineBuilder.ts +312 -0
  658. package/src/graph-manager/protocol/pure/v1/V1_CubeIngestDefinition.ts +35 -9
  659. package/src/graph-manager/protocol/pure/v1/V1_CubeIngestModel.ts +6 -15
  660. package/src/graph-manager/protocol/pure/v1/V1_CubeLambdaReader.ts +471 -0
  661. package/src/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.ts +70 -15
  662. package/src/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.ts +3 -1
  663. package/src/graph-manager/protocol/pure/v1/V1_LegendCubeConnectionExplorer.ts +7 -1
  664. package/src/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.ts +122 -7
  665. package/src/graph-manager/protocol/pure/v1/V1_LegendCubeProjectCatalog.ts +9 -4
  666. package/src/graph-manager/protocol/pure/v1/V1_LegendCubeServiceCatalog.ts +92 -0
  667. package/src/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.ts +6 -1
  668. package/src/index.ts +39 -2
  669. package/src/stores/CubeAddPlacement.ts +25 -5
  670. package/src/stores/CubeDevSettingsState.ts +117 -0
  671. package/src/stores/CubeEditorState.ts +722 -201
  672. package/src/stores/CubeEngineChecks.ts +240 -0
  673. package/src/stores/CubeExamples.ts +188 -1
  674. package/src/stores/CubeExamplesState.ts +13 -3
  675. package/src/stores/CubeExecutionState.ts +26 -57
  676. package/src/stores/CubeExportState.ts +196 -0
  677. package/src/stores/CubeExpressionFilterCheck.ts +218 -0
  678. package/src/stores/CubeExtendTyping.ts +6 -46
  679. package/src/stores/CubeFunctionRecheck.ts +97 -0
  680. package/src/stores/CubeGridFetcher.ts +302 -0
  681. package/src/stores/CubeGridQuickActions.ts +56 -23
  682. package/src/stores/CubeGridState.ts +450 -0
  683. package/src/stores/CubeHost.ts +48 -0
  684. package/src/stores/CubeLambdaImportState.ts +434 -0
  685. package/src/stores/CubeLambdaSources.ts +390 -0
  686. package/src/stores/CubePureText.ts +28 -0
  687. package/src/stores/CubeQueryRun.ts +169 -0
  688. package/src/stores/CubeRunStatsState.ts +91 -0
  689. package/src/stores/CubeRunningStepLambda.ts +62 -0
  690. package/src/stores/CubeServiceRecheck.ts +53 -0
  691. package/src/stores/CubeShowPureState.ts +51 -12
  692. package/src/stores/CubeSourcePickerState.ts +89 -13
  693. package/src/stores/CubeTourState.ts +116 -0
  694. package/src/stores/LegendCubeHost.ts +243 -0
  695. package/src/stores/LocalModelCatalog.ts +6 -1
  696. package/src/stores/editors/CubeExplodeDraft.ts +272 -0
  697. package/src/stores/editors/CubeExpressionFilterDraft.ts +389 -0
  698. package/src/stores/editors/CubeExtendDraft.ts +29 -0
  699. package/src/stores/editors/CubeFunctionDraft.ts +92 -0
  700. package/src/stores/editors/CubeNodeDraftRegistry.ts +34 -2
  701. package/src/stores/editors/CubePivotDraft.ts +355 -0
  702. package/src/stores/fixtures/CubeSalesDuckDbModel.ts +60 -0
  703. package/src/stores/fixtures/CubeTradesModel.ts +36 -1
  704. package/src/stores/source-picker/CubeDataProductTabState.ts +162 -35
  705. package/src/stores/source-picker/CubeDirectConnectionTabState.ts +246 -47
  706. package/src/stores/source-picker/CubeIngestTabState.ts +331 -106
  707. package/src/stores/source-picker/CubeInlineModelTabState.ts +514 -34
  708. package/src/stores/source-picker/CubeProjectTabState.ts +35 -3
  709. package/src/stores/source-picker/CubeServiceTabState.ts +288 -0
  710. package/src/stores/source-picker/CubeSourcePickerTab.ts +31 -2
  711. package/src/stores/variant/CubeJson.ts +229 -0
  712. package/src/stores/variant/CubeJsonExplorerState.ts +378 -0
  713. package/src/stores/variant/CubeJsonFieldsState.ts +252 -0
  714. package/src/stores/variant/CubeJsonOffers.ts +359 -0
  715. package/src/stores/variant/CubeJsonParse.ts +75 -0
  716. package/src/stores/variant/CubeJsonSampling.ts +90 -0
  717. package/src/stores/variant/CubeJsonShape.ts +279 -0
  718. package/src/stores/variant/CubeJsonViewerState.ts +59 -0
  719. package/tsconfig.json +72 -1
@@ -21,10 +21,11 @@ import {
21
21
  createNodeRegistry,
22
22
  CubeDocument,
23
23
  diffSchemas,
24
- Extend,
24
+ dependsOnDatabaseType,
25
25
  findLostSortOrders,
26
+ getDatabaseProblemOfType,
27
+ getDatabaseProblems,
26
28
  isTypingError,
27
- type JsonObject,
28
29
  MESSAGE_SORT_COLUMNS_CUT,
29
30
  MESSAGE_SORT_COLUMNS_DROPPED,
30
31
  MESSAGE_SORT_ORDER_LOST,
@@ -38,7 +39,13 @@ import {
38
39
  rereadQueryFilterValues,
39
40
  type Schema,
40
41
  type SchemaInferenceResult,
42
+ ServiceSource,
41
43
  type SourceDefinition,
44
+ foldColumnName,
45
+ FunctionSource,
46
+ copyQueryNode,
47
+ type CubeContext,
48
+ SourceNode,
42
49
  } from '@finos/legend-cube';
43
50
  import type { CommandRegistrar } from '@finos/legend-application';
44
51
  import type { GeneratorFn } from '@finos/legend-shared';
@@ -58,7 +65,6 @@ import {
58
65
  CUBE_EDITOR_CLOSED_REASON,
59
66
  DEFAULT_ROW_LIMIT,
60
67
  getSchemaDriftWarning,
61
- getExtendRetypeWarning,
62
68
  getSourceRecheckWarning,
63
69
  LEGEND_CUBE_USER_DATA_KEY,
64
70
  MAX_UNDO_STEPS,
@@ -75,31 +81,52 @@ import {
75
81
  } from '../__lib__/LegendCubeIngestLabels.js';
76
82
  import { isCubeDataProductModel } from '../graph-manager/CubeDataProduct.js';
77
83
  import { isCubeIngestModel } from '../graph-manager/CubeIngest.js';
84
+ import { isCubeServiceModel } from '../graph-manager/CubeService.js';
78
85
  import {
79
86
  CubeEngineError,
80
87
  CubeEngineErrorKind,
81
88
  type CubeModelOutline,
82
89
  type NodeId,
83
90
  } from '../graph-manager/CubeEngine.js';
91
+ import {
92
+ CUBE_LAKEHOUSE_RUNTIME_KIND,
93
+ getLakehouseDatabaseType,
94
+ } from '../graph-manager/CubeLakehouseRuntime.js';
84
95
  import { getDatabaseType } from '../graph-manager/CubeModelOutlineHelper.js';
85
96
  import { recheckCubeDataProductSources } from './CubeDataProductRecheck.js';
86
97
  import { recheckCubeIngestSources } from './CubeIngestRecheck.js';
98
+ import { recheckCubeServiceSources } from './CubeServiceRecheck.js';
99
+ import {
100
+ CUBE_FUNCTION_MESSAGE,
101
+ getFunctionDriftWarning,
102
+ getFunctionRecheckWarning,
103
+ } from '../__lib__/LegendCubeFunctionLabels.js';
104
+ import { recheckCubeFunctionSources } from './CubeFunctionRecheck.js';
87
105
  import { CubeDataProductRuntimeState } from './CubeDataProductRuntimeState.js';
88
106
  import { CubeExamplesState } from './CubeExamplesState.js';
107
+ import { CubeTourState } from './CubeTourState.js';
108
+ import { CubeExportState } from './CubeExportState.js';
109
+ import { CubeGridFetcher } from './CubeGridFetcher.js';
110
+ import { CubeGridState } from './CubeGridState.js';
111
+ import { CubeDevSettingsState } from './CubeDevSettingsState.js';
112
+ import { CubeRunStatsState } from './CubeRunStatsState.js';
89
113
  import { CubeExecutionState } from './CubeExecutionState.js';
114
+ import { CubeExpressionFilterDraft } from './editors/CubeExpressionFilterDraft.js';
90
115
  import { CubeExtendDraft } from './editors/CubeExtendDraft.js';
91
116
  import {
92
- buildCubeExtendTypingLambdas,
93
- createStaleCubeExtendTypingRule,
94
- getCubeExtendTypingUpstream,
95
- getCubeExtendUpstream,
96
- isCubeExtendTypingCurrent,
97
- isSameCubeExtendTyping,
98
- readCubeExtendTyping,
99
- } from './CubeExtendTyping.js';
117
+ buildCubeEngineCheckRequest,
118
+ type CubeEngineCheckedNode,
119
+ createStaleCubeEngineCheckRule,
120
+ getCubeEngineCheckUpstream,
121
+ isCubeEngineCheckedNode,
122
+ } from './CubeEngineChecks.js';
123
+ import { getCubeExtendUpstream } from './CubeExtendTyping.js';
100
124
  import { type CubeHost, loadCubeModelOutline } from './CubeHost.js';
101
125
  import { CubeNodeEditorState } from './CubeNodeEditorState.js';
102
126
  import { CubeShowPureState } from './CubeShowPureState.js';
127
+ import { CubeJsonViewerState } from './variant/CubeJsonViewerState.js';
128
+ import { CubeJsonExplorerState } from './variant/CubeJsonExplorerState.js';
129
+ import { CubeLambdaImportState } from './CubeLambdaImportState.js';
103
130
  import { CubeSourcePickerState } from './CubeSourcePickerState.js';
104
131
  import { CubeSpecTransferState } from './CubeSpecTransferState.js';
105
132
 
@@ -128,11 +155,13 @@ const isFocusInNodeEditor = (): boolean =>
128
155
  `[data-testid="${LEGEND_CUBE_TEST_ID.NODE_EDITOR}"]`,
129
156
  ) !== null && document.activeElement !== null;
130
157
 
131
- /** A source Cube types again to see drift: a table, or a data product's access point */
158
+ /** A source Cube types again to see drift: a table, a function, an access point, an ingest data set or a service */
132
159
  type RecheckedSource =
133
160
  | RelationalTableSource
161
+ | FunctionSource
134
162
  | DataProductAccessPointSource
135
- | IngestDatasetSource;
163
+ | IngestDatasetSource
164
+ | ServiceSource;
136
165
 
137
166
  /**
138
167
  * The state of one Cube page (PLAN §7.8). The document is immutable: every
@@ -144,20 +173,65 @@ export class CubeEditorState implements CommandRegistrar {
144
173
  readonly host: CubeHost;
145
174
  /** One registry for inference, emission and the saved spec */
146
175
  readonly registry: NodeRegistry;
147
- /** The editor's own query rule: an Extend typed for another input than its own waits to be typed again (PLAN §11.7) */
148
- private readonly staleExtendTyping: QueryRule;
176
+ /**
177
+ * The editor's own query rule: an Extend typed, or a Filter by Expression
178
+ * checked, for another input than its own waits to be checked again (PLAN
179
+ * §11.7, §11.11)
180
+ */
181
+ private readonly staleEngineChecks: QueryRule;
182
+ /**
183
+ * The editor's query rule for the database a node runs on: `%` or `_`
184
+ * given to a pattern on DuckDB (PLAN §11.11), once the model's outline
185
+ * tells the database
186
+ */
187
+ private readonly databaseRefusals: QueryRule;
149
188
  readonly execution: CubeExecutionState;
189
+ /** The latest runs, fetches and exports (spec §12.6) */
190
+ readonly runStats: CubeRunStatsState;
191
+ /** The Dev Settings, at the top left (PLAN §11.16) */
192
+ readonly devSettings: CubeDevSettingsState;
193
+ /** The grid's server-side levels (PLAN §11.10) */
194
+ readonly gridFetcher: CubeGridFetcher;
195
+ /** The grid's mode and its server-side levels (PLAN §11.10) */
196
+ readonly grid: CubeGridState;
197
+ /** The results' export (spec §12.5) */
198
+ readonly export: CubeExportState;
150
199
  /** Where a lakehouse cube runs, a data product's or an ingest one's: its class and warehouse */
151
200
  readonly dataProductRuntime: CubeDataProductRuntimeState;
152
201
  readonly sourcePicker: CubeSourcePickerState;
153
202
  readonly specTransfer: CubeSpecTransferState;
154
203
  readonly examples: CubeExamplesState;
155
204
  readonly showPure: CubeShowPureState;
205
+ /** The editor's guided tour (PLAN §11.21) */
206
+ readonly tour: CubeTourState;
207
+ /** Open JSON: a Variant cell's document as a tree (PLAN §11.20) */
208
+ readonly jsonViewer = new CubeJsonViewerState();
209
+ /** Explore JSON: a Variant column's fields, and the columns they can become (PLAN §11.20) */
210
+ readonly jsonExplorer: CubeJsonExplorerState;
211
+ /** Import Pure: the lambda the page opened on, read into the cube (PLAN §11.18) */
212
+ readonly lambdaImport: CubeLambdaImportState;
156
213
  readonly nodeEditor: CubeNodeEditorState;
157
214
 
158
215
  document: CubeDocument;
159
216
  /** Earlier documents, oldest first */
160
217
  history: readonly CubeDocument[] = [];
218
+ /**
219
+ * The step copied last, as it was, with the cube's context then, which a
220
+ * pasted source needs; kept for the page, across cubes
221
+ */
222
+ copiedNode:
223
+ | { readonly node: QueryNode; readonly context: CubeContext | undefined }
224
+ | undefined;
225
+ /**
226
+ * The changes undone, the latest last, to redo; a new change clears them.
227
+ * Each keeps whether it was read-only and whether undoing it left another
228
+ * cube (an import), so a redo restores both
229
+ */
230
+ redoStack: readonly {
231
+ readonly document: CubeDocument;
232
+ readonly readOnly: boolean;
233
+ readonly opensAnotherCube: boolean;
234
+ }[] = [];
161
235
  /** Engine errors by node id: shown with the node's own errors, never part of inference */
162
236
  hostIssues: ReadonlyMap<string, CubeHostIssue> = new Map();
163
237
  /**
@@ -166,18 +240,31 @@ export class CubeEditorState implements CommandRegistrar {
166
240
  */
167
241
  warnings: ReadonlyMap<number, readonly string[]> = new Map();
168
242
  /**
169
- * The outline of each model the cube used, loaded when an editor needs it,
170
- * e.g. for the Join's 'type unknown' warning; by reference, never observed
171
- * deeply
243
+ * The outline of each model the cube used, by the model's JSON
244
+ * (`modelKey`): loaded when the cube reads a table, or an editor or a run
245
+ * needs it, e.g. for the Join's 'type unknown' warning or the database a
246
+ * node runs on (PLAN §11.12); by reference, never observed deeply
172
247
  */
173
- private modelOutlines: ReadonlyMap<ModelContext, CubeModelOutline> =
174
- new Map();
248
+ private modelOutlines: ReadonlyMap<string, CubeModelOutline> = new Map();
249
+ /** Each model's key in `modelOutlines`, its JSON, worked out once per model object */
250
+ private readonly modelKeys = new WeakMap<ModelContext, string>();
251
+ /** The outlines on their way, by model key, so a second load waits for the first */
252
+ private readonly loadingOutlines = new Map<
253
+ string,
254
+ Promise<CubeModelOutline>
255
+ >();
175
256
  /** Sources sent to the engine to be typed again, until it answers */
176
257
  private pendingSources: ReadonlySet<QueryNode> = new Set();
177
- /** Extends sent to the engine to be typed, until it answers (PLAN §11.7) */
178
- private typingExtends: ReadonlySet<QueryNode> = new Set();
179
- /** Types the Extends that wait for it, whenever one does (PLAN §11.7 Q4) */
180
- private readonly retyping: IReactionDisposer;
258
+ /** Extends and Filters by Expression sent to the engine to be checked, until it answers (PLAN §11.7, §11.11) */
259
+ private checkingNodes: ReadonlySet<QueryNode> = new Set();
260
+ /** Checks the nodes that wait for the engine, whenever one does (PLAN §11.7 Q4) */
261
+ private readonly rechecking: IReactionDisposer;
262
+ /**
263
+ * Loads the model's outline once the cube reads a table, so the database it
264
+ * runs on is known before any run: some nodes are refused there, or written
265
+ * another way (PLAN §11.4, §11.11, §11.12)
266
+ */
267
+ private readonly outlineLoading: IReactionDisposer;
181
268
  /** The rows a run returns; kept per user, never in the cube */
182
269
  rowLimit: number;
183
270
  /** The palette shows icons only; kept per user, never in the cube */
@@ -195,18 +282,21 @@ export class CubeEditorState implements CommandRegistrar {
195
282
  constructor(host: CubeHost, document = new CubeDocument()) {
196
283
  makeObservable<
197
284
  CubeEditorState,
198
- 'pendingSources' | 'modelOutlines' | 'typingExtends'
285
+ 'pendingSources' | 'modelOutlines' | 'checkingNodes'
199
286
  >(this, {
200
287
  pendingSources: observable.ref,
201
- typingExtends: observable.ref,
202
- extendsToType: computed,
203
- isTypingExtends: computed,
204
- retypeExtends: flow,
288
+ checkingNodes: observable.ref,
289
+ nodesToCheck: computed,
290
+ isCheckingExpressions: computed,
291
+ checkExpressions: flow,
205
292
  modelOutlines: observable.ref,
206
293
  modelOutline: computed,
207
294
  loadModelOutline: flow,
208
295
  document: observable.ref,
209
296
  history: observable.ref,
297
+ redoStack: observable.ref,
298
+ canRedo: computed,
299
+ redo: action,
210
300
  hostIssues: observable.ref,
211
301
  warnings: observable.ref,
212
302
  derivedWarnings: computed,
@@ -220,10 +310,14 @@ export class CubeEditorState implements CommandRegistrar {
220
310
  hasEditsToApply: computed,
221
311
  executeEdited: action,
222
312
  undoEdited: action,
313
+ redoEdited: action,
223
314
  isDialogOpen: computed,
224
315
  applyDocument: action,
225
316
  undo: action,
226
317
  importDocument: action,
318
+ openDocument: action,
319
+ startNewCube: action,
320
+ isEmptyCube: computed,
227
321
  reresolveSources: flow,
228
322
  refreshSource: flow,
229
323
  applyQuery: action,
@@ -231,21 +325,37 @@ export class CubeEditorState implements CommandRegistrar {
231
325
  connect: action,
232
326
  addNode: action,
233
327
  addConfiguredNode: action,
328
+ addConfiguredNodes: action,
234
329
  dropNode: action,
235
330
  removeNode: action,
331
+ copiedNode: observable.ref,
332
+ canPaste: computed,
333
+ copyNode: action,
334
+ pasteNode: action,
335
+ duplicateNode: action,
236
336
  swapInputs: action,
237
337
  setShowGraph: action,
238
338
  setPaletteCollapsed: action,
239
339
  setHostIssue: action,
240
340
  clearHostIssues: action,
241
341
  setRowLimit: action,
342
+ setColumnWidth: action,
242
343
  });
243
344
  this.host = host;
244
345
  this.registry = createNodeRegistry();
245
- this.staleExtendTyping = createStaleCubeExtendTypingRule(
346
+ this.staleEngineChecks = createStaleCubeEngineCheckRule(
246
347
  this.registry,
247
348
  () => this.document.context?.model,
248
349
  );
350
+ this.databaseRefusals = (query) =>
351
+ new Map(
352
+ query.nodes
353
+ .map((node): [string, string[]] => [
354
+ node.id,
355
+ this.getNodeDatabaseProblems(query, node),
356
+ ])
357
+ .filter(([, problems]) => problems.length > 0),
358
+ );
249
359
  this.document = document;
250
360
  const storedLimit = host.applicationStore.userDataService.getNumericValue(
251
361
  LEGEND_CUBE_USER_DATA_KEY.ROW_LIMIT,
@@ -258,17 +368,42 @@ export class CubeEditorState implements CommandRegistrar {
258
368
  LEGEND_CUBE_USER_DATA_KEY.PALETTE_COLLAPSED,
259
369
  ) ?? false;
260
370
  this.execution = new CubeExecutionState(this);
371
+ this.runStats = new CubeRunStatsState();
372
+ this.devSettings = new CubeDevSettingsState(host);
373
+ this.gridFetcher = new CubeGridFetcher(this);
374
+ this.grid = new CubeGridState(this);
375
+ this.export = new CubeExportState(this);
261
376
  this.dataProductRuntime = new CubeDataProductRuntimeState(this);
262
377
  this.sourcePicker = new CubeSourcePickerState(this);
263
378
  this.specTransfer = new CubeSpecTransferState(this);
264
379
  this.examples = new CubeExamplesState(this);
265
380
  this.showPure = new CubeShowPureState(this);
381
+ this.tour = new CubeTourState(this);
382
+ this.jsonExplorer = new CubeJsonExplorerState(this);
383
+ this.lambdaImport = new CubeLambdaImportState(this);
266
384
  this.nodeEditor = new CubeNodeEditorState(this);
267
- this.retyping = reaction(
268
- () => this.extendsToType,
385
+ this.rechecking = reaction(
386
+ () => this.nodesToCheck,
269
387
  (waiting) => {
270
388
  if (waiting.length) {
271
- flowResult(this.retypeExtends(waiting)).catch(
389
+ flowResult(this.checkExpressions(waiting)).catch(
390
+ this.host.applicationStore.alertUnhandledError,
391
+ );
392
+ }
393
+ },
394
+ { fireImmediately: true },
395
+ );
396
+ // the model, while the cube reads a table: another model loads too
397
+ this.outlineLoading = reaction(
398
+ () =>
399
+ this.document.query.nodes.some(
400
+ (node) => node instanceof RelationalTableSource,
401
+ )
402
+ ? this.document.context?.model
403
+ : undefined,
404
+ (model) => {
405
+ if (model !== undefined) {
406
+ flowResult(this.loadModelOutline(model)).catch(
272
407
  this.host.applicationStore.alertUnhandledError,
273
408
  );
274
409
  }
@@ -279,13 +414,15 @@ export class CubeEditorState implements CommandRegistrar {
279
414
 
280
415
  /**
281
416
  * Each node's schema and errors, query-level rules included, as the
282
- * emitter sees them, and an Extend typed for another input than its own
283
- * waiting (`ERR_TYPING`), which only the editor can tell
417
+ * emitter sees them; an Extend or a Filter by Expression checked for
418
+ * another input than its own waiting, and a filter its database would
419
+ * misread refused, which only the editor can tell
284
420
  */
285
421
  get analysis(): SchemaInferenceResult {
286
422
  return buildSchemasAndValidity(this.document.query, [
287
423
  ...this.registry.queryRules,
288
- this.staleExtendTyping,
424
+ this.staleEngineChecks,
425
+ this.databaseRefusals,
289
426
  ]);
290
427
  }
291
428
 
@@ -306,47 +443,50 @@ export class CubeEditorState implements CommandRegistrar {
306
443
  }
307
444
 
308
445
  /**
309
- * The Extends of the cube shown that wait for the engine to type their
310
- * columns, their input valid, and that aren't being typed (PLAN §11.7):
311
- * new expressions, or an input that changed
446
+ * The Extends and Filters by Expression of the cube shown that wait for
447
+ * the engine, their input valid, and that aren't being checked (PLAN §11.7,
448
+ * §11.11): new expressions, or an input that changed
312
449
  */
313
- get extendsToType(): readonly Extend[] {
450
+ get nodesToCheck(): readonly CubeEngineCheckedNode[] {
314
451
  const { validity } = this.analysis;
315
452
  return this.document.query.nodes.filter(
316
- (node): node is Extend =>
317
- node instanceof Extend &&
318
- !this.typingExtends.has(node) &&
453
+ (node): node is CubeEngineCheckedNode =>
454
+ isCubeEngineCheckedNode(node) &&
455
+ !this.checkingNodes.has(node) &&
319
456
  (validity.get(node.id) ?? []).some(isTypingError),
320
457
  );
321
458
  }
322
459
 
323
- /** The cube shown has Extends the engine is typing */
324
- get isTypingExtends(): boolean {
460
+ /** The cube shown has expressions the engine is checking: an Extend's columns, a filter's condition */
461
+ get isCheckingExpressions(): boolean {
325
462
  return this.document.query.nodes.some((node) =>
326
- this.typingExtends.has(node),
463
+ this.checkingNodes.has(node),
327
464
  );
328
465
  }
329
466
 
330
- /** The node waits for the engine to type it, or is being typed: an Extend (PLAN §11.7) */
467
+ /** The node waits for the engine to check it, or is being checked: an Extend or a Filter by Expression (PLAN §11.7, §11.11) */
331
468
  isTypingNode(node: QueryNode): boolean {
332
469
  return (
333
- this.typingExtends.has(node) ||
470
+ this.checkingNodes.has(node) ||
334
471
  (this.analysis.validity.get(node.id) ?? []).some(isTypingError)
335
472
  );
336
473
  }
337
474
 
338
475
  /**
339
- * Types Extends' columns with the engine, in one call, outside the undo
340
- * history (PLAN §11.7 Q4): each for the input it has now, its columns
341
- * after its input's relation, as typing types any node. The typing goes in
342
- * place of the very nodes sent, in the cube shown and the undo snapshots
343
- * that give the engine the same input; one the user changed meanwhile is
344
- * left to type again. Each typing records the input as the engine was given
345
- * it (`upstream`). A typing the engine couldn't give names the column it
346
- * failed on; when the engine can't be reached, a typing still current for
347
- * the input is kept, with a warning, as a source's saved columns are.
476
+ * Checks expressions with the engine, in one call, outside the undo history
477
+ * (PLAN §11.7 Q4, §11.11): an Extend's columns typed, a Filter by
478
+ * Expression's condition checked, each for the input it has now, after its
479
+ * input's relation, as typing types any node. The check goes in place of
480
+ * the very nodes sent, in the cube shown and the undo snapshots that give
481
+ * the engine the same input; one the user changed meanwhile is left to
482
+ * check again. Each check records the input as the engine was given it
483
+ * (`upstream`). A check the engine couldn't give says why; when the engine
484
+ * can't be reached, a check still current for the input is kept, with a
485
+ * warning, as a source's saved columns are.
348
486
  */
349
- *retypeExtends(nodes: readonly Extend[]): GeneratorFn<void> {
487
+ *checkExpressions(
488
+ nodes: readonly CubeEngineCheckedNode[],
489
+ ): GeneratorFn<void> {
350
490
  const { context, query } = this.document;
351
491
  if (!context) {
352
492
  return;
@@ -358,37 +498,25 @@ export class CubeEditorState implements CommandRegistrar {
358
498
  const input = inputId === undefined ? undefined : schemas.get(inputId);
359
499
  if (
360
500
  query.getNode(node.id) !== node ||
361
- this.typingExtends.has(node) ||
362
- !input ||
363
- node.columns.some(({ lambda }) => lambda === undefined)
501
+ this.checkingNodes.has(node) ||
502
+ !input
364
503
  ) {
365
504
  return [];
366
505
  }
367
- const columns = node.columns.map(({ name, lambda }) => ({
368
- name,
369
- lambda: lambda as JsonObject,
370
- }));
371
- return [
372
- {
373
- node,
374
- input,
375
- columns,
376
- upstream: getCubeExtendUpstream(emitter, node.id, context.model),
377
- lambdas: buildCubeExtendTypingLambdas(
378
- query,
379
- node,
380
- columns,
381
- this.registry,
382
- false,
383
- ),
384
- },
385
- ];
506
+ const request = buildCubeEngineCheckRequest(
507
+ query,
508
+ node,
509
+ input,
510
+ getCubeExtendUpstream(emitter, node.id, context.model),
511
+ this.registry,
512
+ );
513
+ return request ? [request] : [];
386
514
  });
387
515
  if (!requests.length) {
388
516
  return;
389
517
  }
390
- const sent = requests.map(({ node }) => node);
391
- this.typingExtends = new Set([...this.typingExtends, ...sent]);
518
+ const sent: readonly QueryNode[] = requests.map(({ node }) => node);
519
+ this.checkingNodes = new Set([...this.checkingNodes, ...sent]);
392
520
  let answers: ReadonlyMap<NodeId, Schema | CubeEngineError>;
393
521
  try {
394
522
  answers = (yield this.host.engine.typeLambdas(
@@ -409,41 +537,31 @@ export class CubeEditorState implements CommandRegistrar {
409
537
  ),
410
538
  );
411
539
  } finally {
412
- this.typingExtends = new Set(
413
- [...this.typingExtends].filter(
414
- (node) => !sent.includes(node as Extend),
415
- ),
540
+ this.checkingNodes = new Set(
541
+ [...this.checkingNodes].filter((node) => !sent.includes(node)),
416
542
  );
417
543
  }
418
- // a typing that comes back the same leaves its node, and the query, alone
544
+ // a check that comes back the same leaves its node, and the query, alone
419
545
  const warnings = new Map(this.warnings);
420
546
  const replacements = new Map<QueryNode, QueryNode>(
421
- requests.flatMap(({ node, input, columns, upstream }) => {
422
- const { typing, error } = readCubeExtendTyping(
423
- answers,
424
- node,
425
- input,
426
- columns,
427
- upstream,
428
- );
429
- if (
430
- error?.kind === CubeEngineErrorKind.NETWORK &&
431
- isCubeExtendTypingCurrent(node, input, upstream)
432
- ) {
433
- warnings.set(node.key, [getExtendRetypeWarning(error.firstLine)]);
547
+ requests.flatMap((request) => {
548
+ const { node } = request;
549
+ const outcome = request.read(answers);
550
+ if (outcome.keptWarning !== undefined) {
551
+ warnings.set(node.key, [outcome.keptWarning]);
434
552
  return [];
435
553
  }
436
554
  warnings.delete(node.key);
437
- return isSameCubeExtendTyping(typing, node.typing)
438
- ? []
439
- : [[node, node.withTyping(typing)] as const];
555
+ return outcome.node ? [[node, outcome.node] as const] : [];
440
556
  }),
441
557
  );
442
558
  this.warnings = warnings;
443
- // an undo snapshot whose input differs keeps the typing it had
559
+ // an undo snapshot whose input differs keeps the check it had
444
560
  const emitters = new Map<Query, QueryEmitter>([[query, emitter]]);
445
561
  this.replaceOutsideHistory(replacements, (snapshot, resolved) => {
446
- const upstream = getCubeExtendTypingUpstream((resolved as Extend).typing);
562
+ const upstream = getCubeEngineCheckUpstream(
563
+ resolved as CubeEngineCheckedNode,
564
+ );
447
565
  if (upstream === undefined) {
448
566
  return true;
449
567
  }
@@ -525,17 +643,31 @@ export class CubeEditorState implements CommandRegistrar {
525
643
  return model === undefined ? undefined : this.getModelOutline(model);
526
644
  }
527
645
 
646
+ /**
647
+ * A model's key for its outline: its JSON, so a cube imported on the same
648
+ * model, a new object with the same content, shares the outline loaded
649
+ */
650
+ private modelKey(model: ModelContext): string {
651
+ let key = this.modelKeys.get(model);
652
+ if (key === undefined) {
653
+ key = JSON.stringify(model);
654
+ this.modelKeys.set(model, key);
655
+ }
656
+ return key;
657
+ }
658
+
528
659
  /** The outline of a model, once loaded */
529
660
  getModelOutline(model: ModelContext): CubeModelOutline | undefined {
530
- return this.modelOutlines.get(model);
661
+ return this.modelOutlines.get(this.modelKey(model));
531
662
  }
532
663
 
533
664
  /**
534
665
  * The database type a run of the query up to the node needs, with the
535
- * model's runtime (PLAN §11.4), from the model's outline once it is loaded
536
- * (`loadModelOutline`): the type of the runtime's connections to the
537
- * databases the node reads. None without an outline, which writes every
538
- * operation the native way.
666
+ * model's runtime (PLAN §11.4): for a data product or ingest cube, the
667
+ * database its lakehouse runtime routes to (§11.12); else, from the model's
668
+ * outline once it is loaded (`loadModelOutline`), the type of the runtime's
669
+ * connections to the databases the node reads. None without an outline,
670
+ * which writes every operation the native way.
539
671
  */
540
672
  getRunDatabaseType(
541
673
  query: Query,
@@ -543,6 +675,9 @@ export class CubeEditorState implements CommandRegistrar {
543
675
  model: ModelContext,
544
676
  runtime: string,
545
677
  ): string | undefined {
678
+ if (isCubeDataProductModel(model) || isCubeIngestModel(model)) {
679
+ return getLakehouseDatabaseType(CUBE_LAKEHOUSE_RUNTIME_KIND);
680
+ }
546
681
  const outline = this.getModelOutline(model);
547
682
  if (!outline) {
548
683
  return undefined;
@@ -552,6 +687,11 @@ export class CubeEditorState implements CommandRegistrar {
552
687
  const node = query.getNode(id);
553
688
  if (node instanceof RelationalTableSource) {
554
689
  databases.add(node.database);
690
+ } else if (node instanceof FunctionSource) {
691
+ // a function reads what Cube can't see: any database of the runtime
692
+ outline.runtimes
693
+ .find(({ path }) => path === runtime)
694
+ ?.connections?.forEach(({ storePath }) => databases.add(storePath));
555
695
  }
556
696
  query
557
697
  .getInputIds(id)
@@ -562,34 +702,88 @@ export class CubeEditorState implements CommandRegistrar {
562
702
  }
563
703
 
564
704
  /**
565
- * Loads the outline of a model, the cube's by default, once per model. It
566
- * only adds warnings and database types, so a model that fails to load
567
- * shows none and runs every operation the native way.
705
+ * A node's problems on the database the query up to it runs on, with the
706
+ * cube's runtime (`getRunDatabaseType`): a Pivot where it can't run (PLAN
707
+ * §11.12); a filter giving `%` or `_` to a pattern on DuckDB, which would
708
+ * match them as wildcards (§11.11). None when the database isn't known.
709
+ */
710
+ getNodeDatabaseProblems(query: Query, node: QueryNode): string[] {
711
+ const { context } = this.document;
712
+ const runtime = context?.runtime;
713
+ if (!context || runtime === undefined || !dependsOnDatabaseType(node)) {
714
+ return [];
715
+ }
716
+ return getDatabaseProblems(
717
+ node,
718
+ this.getRunDatabaseType(query, node.id, context.model, runtime),
719
+ );
720
+ }
721
+
722
+ /**
723
+ * Why a node of the type can't be added after the node, on the database the
724
+ * query up to that node runs on (PLAN §11.12): a Pivot where it can't run.
725
+ * `undefined` when it can, or the database isn't known.
726
+ */
727
+ getAddDatabaseProblem(
728
+ type: string,
729
+ afterId: string | undefined,
730
+ ): string | undefined {
731
+ const { context, query } = this.document;
732
+ const runtime = context?.runtime;
733
+ if (!context || runtime === undefined || afterId === undefined) {
734
+ return undefined;
735
+ }
736
+ return getDatabaseProblemOfType(
737
+ type,
738
+ this.getRunDatabaseType(query, afterId, context.model, runtime),
739
+ );
740
+ }
741
+
742
+ /**
743
+ * Loads the outline of a model, the cube's by default, once per model: a
744
+ * load already on its way is waited for, not started again, e.g. a run's
745
+ * while the cube's opening load is still out. It only adds warnings,
746
+ * database types and a database's refusals (PLAN §11.11, §11.12), so a
747
+ * model that fails to load shows none and runs every operation the native
748
+ * way.
568
749
  */
569
750
  *loadModelOutline(
570
751
  model: ModelContext | undefined = this.document.context?.model,
571
752
  ): GeneratorFn<void> {
572
- if (model === undefined || this.modelOutlines.has(model)) {
753
+ if (model === undefined) {
754
+ return;
755
+ }
756
+ const key = this.modelKey(model);
757
+ if (this.modelOutlines.has(key)) {
573
758
  return;
574
759
  }
760
+ let loading = this.loadingOutlines.get(key);
761
+ if (!loading) {
762
+ loading = loadCubeModelOutline(this.host, model);
763
+ this.loadingOutlines.set(key, loading);
764
+ }
575
765
  try {
576
- const outline = (yield loadCubeModelOutline(
577
- this.host,
578
- model,
579
- )) as CubeModelOutline;
580
- this.modelOutlines = new Map([...this.modelOutlines, [model, outline]]);
766
+ const outline = (yield loading) as CubeModelOutline;
767
+ if (!this.modelOutlines.has(key)) {
768
+ this.modelOutlines = new Map([...this.modelOutlines, [key, outline]]);
769
+ }
581
770
  } catch {
582
771
  // no outline, no warning: nothing is blocked on it
772
+ } finally {
773
+ this.loadingOutlines.delete(key);
583
774
  }
584
775
  }
585
776
 
586
- /** One of Cube's dialogs is open: the source picker, Import or Export, Show Pure */
777
+ /** One of Cube's dialogs is open: the source picker, Examples, the group rows' settings, Import or Export, Show Pure, or the tour */
587
778
  get isDialogOpen(): boolean {
588
779
  return (
589
780
  this.sourcePicker.isOpen ||
590
781
  this.examples.isOpen ||
782
+ this.grid.isSettingsShown ||
783
+ this.grid.formatColumn !== undefined ||
591
784
  this.specTransfer.mode !== undefined ||
592
- this.showPure.isOpen
785
+ this.showPure.isOpen ||
786
+ this.tour.isOpen
593
787
  );
594
788
  }
595
789
 
@@ -617,7 +811,7 @@ export class CubeEditorState implements CommandRegistrar {
617
811
  isFocusInNodeEditor(),
618
812
  ),
619
813
  });
620
- // F10 in the Extend editor (PLAN §11.7)
814
+ // F10 in the Extend and Filter by Expression editors (PLAN §11.7, §11.11)
621
815
  commandService.registerCommand({
622
816
  key: LEGEND_CUBE_COMMAND_KEY.VALIDATE_EXPRESSIONS,
623
817
  trigger: () => {
@@ -625,19 +819,36 @@ export class CubeEditorState implements CommandRegistrar {
625
819
  return (
626
820
  !this.isDialogOpen &&
627
821
  !this.readOnly &&
628
- draft instanceof CubeExtendDraft &&
822
+ (draft instanceof CubeExtendDraft ||
823
+ draft instanceof CubeExpressionFilterDraft) &&
629
824
  !draft.validating
630
825
  );
631
826
  },
632
827
  action: () => {
633
828
  const { draft } = this.nodeEditor;
634
- if (draft instanceof CubeExtendDraft) {
829
+ if (
830
+ draft instanceof CubeExtendDraft ||
831
+ draft instanceof CubeExpressionFilterDraft
832
+ ) {
635
833
  flowResult(draft.validate()).catch(
636
834
  this.host.applicationStore.alertUnhandledError,
637
835
  );
638
836
  }
639
837
  },
640
838
  });
839
+ commandService.registerCommand({
840
+ key: LEGEND_CUBE_COMMAND_KEY.REDO,
841
+ trigger: () =>
842
+ !this.isDialogOpen &&
843
+ !this.nodeEditor.isHeld &&
844
+ this.canRedo &&
845
+ !isTypingText(),
846
+ action: () =>
847
+ this.nodeEditor.runFromKeyboard(
848
+ () => this.redoEdited(),
849
+ isFocusInNodeEditor(),
850
+ ),
851
+ });
641
852
  commandService.registerCommand({
642
853
  key: LEGEND_CUBE_COMMAND_KEY.UNDO,
643
854
  trigger: () =>
@@ -694,6 +905,10 @@ export class CubeEditorState implements CommandRegistrar {
694
905
  return this.history.length > 0 && !this.readOnly;
695
906
  }
696
907
 
908
+ get canRedo(): boolean {
909
+ return this.redoStack.length > 0;
910
+ }
911
+
697
912
  /** The one way to change the cube; the document before goes to the undo history */
698
913
  applyDocument(next: CubeDocument): void {
699
914
  if (next === this.document) {
@@ -709,6 +924,41 @@ export class CubeEditorState implements CommandRegistrar {
709
924
  * without applying its edits, and drops the last run's rows and errors,
710
925
  * which belong to the cube before. Never runs the cube.
711
926
  */
927
+ /** Whether the cube is a new one: no name, no context, no node */
928
+ get isEmptyCube(): boolean {
929
+ const { document } = this;
930
+ return (
931
+ document.name === undefined &&
932
+ document.context === undefined &&
933
+ document.query.nodes.length === 0
934
+ );
935
+ }
936
+
937
+ /**
938
+ * Replaces the cube with a new, empty one, as an import does (one undo
939
+ * step, so Undo brings the cube back); a cube already new is left as it is
940
+ */
941
+ startNewCube(): void {
942
+ if (!this.isEmptyCube) {
943
+ this.importDocument(new CubeDocument(), false);
944
+ }
945
+ }
946
+
947
+ /**
948
+ * Opens the page on a cube read for it, as `initialDocument` opens one:
949
+ * no undo step, as there was no cube before it (Import Pure's
950
+ * `initialLambda`, PLAN §11.18). Its sources come typed; its expressions
951
+ * are checked as any are.
952
+ */
953
+ openDocument(next: CubeDocument): void {
954
+ this.execution.reset();
955
+ this.sourcePicker.close();
956
+ this.nodeEditor.discard(CUBE_EDITOR_CLOSED_REASON.CUBE_REPLACED);
957
+ this.hostIssues = new Map();
958
+ this.document = next;
959
+ this.readOnly = false;
960
+ }
961
+
712
962
  importDocument(next: CubeDocument, readOnly: boolean): void {
713
963
  this.pushHistory();
714
964
  this.importedOver.add(this.document);
@@ -723,14 +973,10 @@ export class CubeEditorState implements CommandRegistrar {
723
973
  flowResult(this.reresolveSources()).catch(
724
974
  this.host.applicationStore.alertUnhandledError,
725
975
  );
726
- // typed once on load too, as sources are checked again: the model may
727
- // have changed the types of its functions (PLAN §11.7)
976
+ // checked once on load too, as sources are checked again: the model may
977
+ // have changed the types of its functions (PLAN §11.7, §11.11)
728
978
  flowResult(
729
- this.retypeExtends(
730
- next.query.nodes.filter(
731
- (node): node is Extend => node instanceof Extend,
732
- ),
733
- ),
979
+ this.checkExpressions(next.query.nodes.filter(isCubeEngineCheckedNode)),
734
980
  ).catch(this.host.applicationStore.alertUnhandledError);
735
981
  }
736
982
 
@@ -784,10 +1030,27 @@ export class CubeEditorState implements CommandRegistrar {
784
1030
  node instanceof IngestDatasetSource,
785
1031
  )
786
1032
  : [];
1033
+ // a function on another kind of cube is the no-mix rule's to flag
1034
+ const functions =
1035
+ isCubeDataProductModel(context.model) ||
1036
+ isCubeIngestModel(context.model) ||
1037
+ isCubeServiceModel(context.model)
1038
+ ? []
1039
+ : kept.filter(
1040
+ (node): node is FunctionSource => node instanceof FunctionSource,
1041
+ );
1042
+ // services are typed in one place, still to come (PLAN §6.4)
1043
+ const services = isCubeServiceModel(context.model)
1044
+ ? kept.filter(
1045
+ (node): node is ServiceSource => node instanceof ServiceSource,
1046
+ )
1047
+ : [];
787
1048
  const sources: readonly RecheckedSource[] = [
788
1049
  ...tables,
1050
+ ...functions,
789
1051
  ...accessPoints,
790
1052
  ...dataSets,
1053
+ ...services,
791
1054
  ];
792
1055
  if (!sources.length) {
793
1056
  return;
@@ -795,53 +1058,72 @@ export class CubeEditorState implements CommandRegistrar {
795
1058
  this.pendingSources = new Set([...this.pendingSources, ...sources]);
796
1059
  let answers: ReadonlyMap<string, Schema | CubeEngineError>;
797
1060
  try {
798
- const [tableAnswers, accessPointAnswers, dataSetAnswers] =
799
- (yield Promise.all([
800
- tables.length
801
- ? this.host.engine
802
- .resolveSchemas(
803
- context.model,
804
- new Map(
805
- tables.map((source) => [
806
- source.id,
807
- [source.database, source.schema, source.table],
808
- ]),
809
- ),
810
- )
811
- .catch((error: unknown) => {
812
- const failure =
813
- error instanceof CubeEngineError
814
- ? error
815
- : new CubeEngineError(
816
- CubeEngineErrorKind.NETWORK,
817
- error instanceof Error
818
- ? error.message
819
- : String(error),
820
- );
821
- return new Map(tables.map((source) => [source.id, failure]));
822
- })
823
- : new Map(),
824
- accessPoints.length
825
- ? recheckCubeDataProductSources(
826
- this.host.dataProductCatalog,
827
- context.model,
828
- accessPoints,
829
- fresh,
830
- )
831
- : new Map(),
832
- dataSets.length
833
- ? recheckCubeIngestSources(
834
- this.host.ingestCatalog,
1061
+ const [
1062
+ tableAnswers,
1063
+ accessPointAnswers,
1064
+ dataSetAnswers,
1065
+ serviceAnswers,
1066
+ functionAnswers,
1067
+ ] = (yield Promise.all([
1068
+ tables.length
1069
+ ? this.host.engine
1070
+ .resolveSchemas(
835
1071
  context.model,
836
- dataSets,
837
- fresh,
1072
+ new Map(
1073
+ tables.map((source) => [
1074
+ source.id,
1075
+ [source.database, source.schema, source.table],
1076
+ ]),
1077
+ ),
838
1078
  )
839
- : new Map(),
840
- ])) as ReadonlyMap<string, Schema | CubeEngineError>[];
1079
+ .catch((error: unknown) => {
1080
+ const failure =
1081
+ error instanceof CubeEngineError
1082
+ ? error
1083
+ : new CubeEngineError(
1084
+ CubeEngineErrorKind.NETWORK,
1085
+ error instanceof Error ? error.message : String(error),
1086
+ );
1087
+ return new Map(tables.map((source) => [source.id, failure]));
1088
+ })
1089
+ : new Map(),
1090
+ accessPoints.length
1091
+ ? recheckCubeDataProductSources(
1092
+ this.host.dataProductCatalog,
1093
+ context.model,
1094
+ accessPoints,
1095
+ fresh,
1096
+ )
1097
+ : new Map(),
1098
+ dataSets.length
1099
+ ? recheckCubeIngestSources(
1100
+ this.host.ingestCatalog,
1101
+ context.model,
1102
+ dataSets,
1103
+ fresh,
1104
+ )
1105
+ : new Map(),
1106
+ services.length
1107
+ ? recheckCubeServiceSources(
1108
+ this.host.serviceCatalog,
1109
+ context.model,
1110
+ services,
1111
+ )
1112
+ : new Map(),
1113
+ functions.length
1114
+ ? recheckCubeFunctionSources(
1115
+ this.host.engine,
1116
+ context.model,
1117
+ functions,
1118
+ )
1119
+ : new Map(),
1120
+ ])) as ReadonlyMap<string, Schema | CubeEngineError>[];
841
1121
  answers = new Map([
842
1122
  ...(tableAnswers ?? []),
843
1123
  ...(accessPointAnswers ?? []),
844
1124
  ...(dataSetAnswers ?? []),
1125
+ ...(serviceAnswers ?? []),
1126
+ ...(functionAnswers ?? []),
845
1127
  ]);
846
1128
  } finally {
847
1129
  this.pendingSources = new Set(
@@ -856,6 +1138,7 @@ export class CubeEditorState implements CommandRegistrar {
856
1138
  sources.forEach((source) => {
857
1139
  const isAccessPoint = source instanceof DataProductAccessPointSource;
858
1140
  const isDataSet = source instanceof IngestDatasetSource;
1141
+ const isFunction = source instanceof FunctionSource;
859
1142
  const answer =
860
1143
  answers.get(source.id) ??
861
1144
  new CubeEngineError(
@@ -864,7 +1147,9 @@ export class CubeEditorState implements CommandRegistrar {
864
1147
  ? CUBE_DATA_PRODUCT_RECHECK_MESSAGE.NO_ANSWER
865
1148
  : isDataSet
866
1149
  ? CUBE_INGEST_RECHECK_MESSAGE.NO_ANSWER
867
- : 'The engine gave no schema for this table',
1150
+ : isFunction
1151
+ ? CUBE_FUNCTION_MESSAGE.NO_ANSWER
1152
+ : 'The engine gave no schema for this table',
868
1153
  source.id,
869
1154
  );
870
1155
  const saved =
@@ -878,7 +1163,9 @@ export class CubeEditorState implements CommandRegistrar {
878
1163
  ? getAccessPointRecheckWarning(answer.firstLine)
879
1164
  : isDataSet
880
1165
  ? getDataSetRecheckWarning(answer.firstLine)
881
- : getSourceRecheckWarning(answer.firstLine),
1166
+ : isFunction
1167
+ ? getFunctionRecheckWarning(answer.firstLine)
1168
+ : getSourceRecheckWarning(answer.firstLine),
882
1169
  ]);
883
1170
  } else if (
884
1171
  source.resolution.kind !== 'failed' ||
@@ -907,7 +1194,9 @@ export class CubeEditorState implements CommandRegistrar {
907
1194
  ? getAccessPointDriftWarning(diff)
908
1195
  : isDataSet
909
1196
  ? getDataSetDriftWarning(diff)
910
- : getSchemaDriftWarning(diff),
1197
+ : isFunction
1198
+ ? getFunctionDriftWarning(diff)
1199
+ : getSchemaDriftWarning(diff),
911
1200
  ]);
912
1201
  }
913
1202
  replacements.set(source, resolved);
@@ -964,6 +1253,11 @@ export class CubeEditorState implements CommandRegistrar {
964
1253
  return next;
965
1254
  };
966
1255
  this.history = this.history.map(check);
1256
+ // a change undone meanwhile is redone with the checked nodes too
1257
+ this.redoStack = this.redoStack.map((entry) => ({
1258
+ ...entry,
1259
+ document: check(entry.document),
1260
+ }));
967
1261
  const next = check(this.document);
968
1262
  if (next !== this.document) {
969
1263
  this.replaceDocument(next);
@@ -981,7 +1275,9 @@ export class CubeEditorState implements CommandRegistrar {
981
1275
  if (
982
1276
  source instanceof RelationalTableSource ||
983
1277
  source instanceof DataProductAccessPointSource ||
984
- source instanceof IngestDatasetSource
1278
+ source instanceof IngestDatasetSource ||
1279
+ source instanceof ServiceSource ||
1280
+ source instanceof FunctionSource
985
1281
  ) {
986
1282
  // a Refresh reads the deployed artifact or definition again
987
1283
  yield flowResult(this.reresolveSources([source], true));
@@ -1003,25 +1299,91 @@ export class CubeEditorState implements CommandRegistrar {
1003
1299
  return;
1004
1300
  }
1005
1301
  this.history = this.history.slice(0, -1);
1302
+ this.redoStack = [
1303
+ ...this.redoStack,
1304
+ {
1305
+ document: this.document,
1306
+ readOnly: this.readOnly,
1307
+ opensAnotherCube: this.importedOver.has(previous),
1308
+ },
1309
+ ];
1006
1310
  this.readOnly = this.readOnlyDocuments.has(previous);
1007
1311
  if (this.importedOver.has(previous)) {
1008
1312
  // the cube before an import is another cube, as the import was
1009
1313
  this.sourcePicker.close();
1010
1314
  this.nodeEditor.discard(CUBE_EDITOR_CLOSED_REASON.CUBE_REPLACED);
1011
1315
  }
1012
- const { query } = this.document;
1316
+ const { query, meta } = this.document;
1317
+ const restored = previous.withQuery(
1318
+ previous.query === query ? query : previous.query.clone(),
1319
+ );
1320
+ // widths take no undo step, so the same cube keeps the ones set since
1321
+ // (review of M7); the cube before an import keeps its own
1322
+ this.replaceDocument(
1323
+ this.importedOver.has(previous)
1324
+ ? restored
1325
+ : restored.withMeta({
1326
+ ...restored.meta,
1327
+ presentation: {
1328
+ ...restored.meta.presentation,
1329
+ columnWidths: meta.presentation.columnWidths,
1330
+ },
1331
+ }),
1332
+ );
1333
+ }
1334
+
1335
+ /**
1336
+ * Brings back the last change undone, as Ctrl+Shift+Z does: the cube shown
1337
+ * goes back to the undo history, and a change that opened another cube
1338
+ * (an import, New) closes the editor and the source dialog again
1339
+ */
1340
+ redo(): void {
1341
+ const next = this.redoStack.at(-1);
1342
+ if (!next) {
1343
+ return;
1344
+ }
1345
+ this.redoStack = this.redoStack.slice(0, -1);
1346
+ this.pushHistory(true);
1347
+ if (next.opensAnotherCube) {
1348
+ this.importedOver.add(this.history.at(-1) as CubeDocument);
1349
+ this.sourcePicker.close();
1350
+ this.nodeEditor.discard(CUBE_EDITOR_CLOSED_REASON.CUBE_REPLACED);
1351
+ }
1352
+ this.readOnly = next.readOnly;
1353
+ const { query, meta } = this.document;
1354
+ const restored = next.document.withQuery(
1355
+ next.document.query === query ? query : next.document.query.clone(),
1356
+ );
1357
+ // widths take no undo step: the same cube keeps the ones set since
1013
1358
  this.replaceDocument(
1014
- previous.withQuery(
1015
- previous.query === query ? query : previous.query.clone(),
1016
- ),
1359
+ next.opensAnotherCube
1360
+ ? restored
1361
+ : restored.withMeta({
1362
+ ...restored.meta,
1363
+ presentation: {
1364
+ ...restored.meta.presentation,
1365
+ columnWidths: meta.presentation.columnWidths,
1366
+ },
1367
+ }),
1017
1368
  );
1018
1369
  }
1019
1370
 
1020
- private pushHistory(): void {
1371
+ /** Redo, as its button and Ctrl+Shift+Z do: finishes the node editor first */
1372
+ redoEdited(): void {
1373
+ if (this.nodeEditor.finishApplied() && this.canRedo) {
1374
+ this.redo();
1375
+ }
1376
+ }
1377
+
1378
+ /** Keeps the cube shown for undo; a new change, not a redo, drops what was undone */
1379
+ private pushHistory(keepRedo = false): void {
1021
1380
  if (this.readOnly) {
1022
1381
  this.readOnlyDocuments.add(this.document);
1023
1382
  }
1024
1383
  this.history = [...this.history, this.document].slice(-MAX_UNDO_STEPS);
1384
+ if (!keepRedo) {
1385
+ this.redoStack = [];
1386
+ }
1025
1387
  }
1026
1388
 
1027
1389
  /**
@@ -1063,17 +1425,43 @@ export class CubeEditorState implements CommandRegistrar {
1063
1425
  }
1064
1426
 
1065
1427
  /**
1066
- * The kinds of source the host serves: data products and ingest data sets
1067
- * only with their catalogs. The cube's kind may still disable one
1068
- * (`canAddNode`)
1428
+ * The kinds of source the host serves: data products, ingest data sets and
1429
+ * services only with their catalogs, tables and functions only with a tab
1430
+ * that reads them (Studio offers ingest data sets alone). The cube's kind
1431
+ * may still disable one (`canAddNode`)
1069
1432
  */
1070
1433
  get offeredSources(): readonly SourceDefinition[] {
1071
- return this.registry.sources.filter(
1072
- (definition) =>
1073
- (definition.type !== DataProductAccessPointSource.TYPE ||
1074
- this.sourcePicker.dataProductTab.isAvailable) &&
1075
- (definition.type !== IngestDatasetSource.TYPE ||
1076
- this.sourcePicker.ingestTab.isAvailable),
1434
+ const {
1435
+ modelTab,
1436
+ projectTab,
1437
+ projectFunctionTab,
1438
+ directTab,
1439
+ dataProductTab,
1440
+ ingestTab,
1441
+ serviceTab,
1442
+ } = this.sourcePicker;
1443
+ const isServed = (type: string): boolean => {
1444
+ switch (type) {
1445
+ case DataProductAccessPointSource.TYPE:
1446
+ return dataProductTab.isAvailable;
1447
+ case IngestDatasetSource.TYPE:
1448
+ return ingestTab.isAvailable;
1449
+ case ServiceSource.TYPE:
1450
+ return serviceTab.isAvailable;
1451
+ case FunctionSource.TYPE:
1452
+ return modelTab.isAvailable || projectFunctionTab.isAvailable;
1453
+ case RelationalTableSource.TYPE:
1454
+ return (
1455
+ modelTab.isAvailable ||
1456
+ projectTab.isAvailable ||
1457
+ directTab.isAvailable
1458
+ );
1459
+ default:
1460
+ return true;
1461
+ }
1462
+ };
1463
+ return this.registry.sources.filter((definition) =>
1464
+ isServed(definition.type),
1077
1465
  );
1078
1466
  }
1079
1467
 
@@ -1108,19 +1496,19 @@ export class CubeEditorState implements CommandRegistrar {
1108
1496
  * after `afterId`; a source opens the source picker, which adds it once
1109
1497
  * the engine has typed it. Does nothing `canAddNode` refuses.
1110
1498
  */
1111
- addNode(type: string, afterId?: string): void {
1499
+ addNode(type: string, afterId?: string): string | undefined {
1112
1500
  const definition = this.registry.get(type);
1113
1501
  if (!definition || !this.canAddNode(type, afterId)) {
1114
- return;
1502
+ return undefined;
1115
1503
  }
1116
1504
  if (definition.kind === 'source') {
1117
- this.sourcePicker.open(this.sourcePicker.tabForSourceType(type)?.key);
1118
- return;
1505
+ this.sourcePicker.openForSourceType(type);
1506
+ return undefined;
1119
1507
  }
1120
1508
  const { query } = this.document;
1121
- this.applyQuery(
1122
- query.add(definition.create(query.generateId(type)), afterId),
1123
- );
1509
+ const id = query.generateId(type);
1510
+ this.applyQuery(query.add(definition.create(id), afterId));
1511
+ return id;
1124
1512
  }
1125
1513
 
1126
1514
  /**
@@ -1130,11 +1518,29 @@ export class CubeEditorState implements CommandRegistrar {
1130
1518
  * read-only cube, or when the query can't take it.
1131
1519
  */
1132
1520
  addConfiguredNode(node: QueryNode, afterId?: string): void {
1133
- const { query } = this.document;
1134
- if (this.readOnly || !query.canAdd(node, afterId)) {
1521
+ this.addConfiguredNodes([node], afterId);
1522
+ }
1523
+
1524
+ /**
1525
+ * Adds nodes made elsewhere one after another, the first spliced in after
1526
+ * `afterId`, as one undo step, the last then running when that one did
1527
+ * (Explore JSON's Extend then Explode Array). Does nothing in a read-only
1528
+ * cube, or when the query can't take one of them.
1529
+ */
1530
+ addConfiguredNodes(nodes: readonly QueryNode[], afterId?: string): void {
1531
+ if (this.readOnly || !nodes.length) {
1135
1532
  return;
1136
1533
  }
1137
- this.applyQuery(query.add(node, afterId));
1534
+ let query = this.document.query;
1535
+ let after = afterId;
1536
+ for (const node of nodes) {
1537
+ if (!query.canAdd(node, after)) {
1538
+ return;
1539
+ }
1540
+ query = query.add(node, after);
1541
+ after = node.id;
1542
+ }
1543
+ this.applyQuery(query);
1138
1544
  }
1139
1545
 
1140
1546
  /** Whether dropping a node on another does anything: connect it, or else move it after it */
@@ -1184,6 +1590,95 @@ export class CubeEditorState implements CommandRegistrar {
1184
1590
  );
1185
1591
  }
1186
1592
 
1593
+ /** Whether a step can be copied: a known type's, so its copy reads back */
1594
+ canCopyNode(nodeId: string): boolean {
1595
+ const node = this.document.query.getNode(nodeId);
1596
+ return node !== undefined && this.registry.get(node.type) !== undefined;
1597
+ }
1598
+
1599
+ /** Copies a step, as Cmd/Ctrl+C on it does, for Paste */
1600
+ copyNode(nodeId: string): void {
1601
+ const node = this.document.query.getNode(nodeId);
1602
+ if (node && this.canCopyNode(nodeId)) {
1603
+ this.copiedNode = { node, context: this.document.context };
1604
+ }
1605
+ }
1606
+
1607
+ /**
1608
+ * Whether the step copied can be pasted here: a transform always; a source
1609
+ * only into a cube of the same model and runtime, or an empty cube, which
1610
+ * takes them, as a first table does
1611
+ */
1612
+ get canPaste(): boolean {
1613
+ const copied = this.copiedNode;
1614
+ return (
1615
+ copied !== undefined &&
1616
+ !this.readOnly &&
1617
+ this.canTakeCopy(copied.node, copied.context)
1618
+ );
1619
+ }
1620
+
1621
+ /** Pastes the step copied: after the step given when it takes an input, else on its own; one undo step */
1622
+ pasteNode(afterId?: string): void {
1623
+ const copied = this.copiedNode;
1624
+ if (copied && this.canPaste) {
1625
+ this.addCopy(copied.node, copied.context, afterId);
1626
+ }
1627
+ }
1628
+
1629
+ canDuplicateNode(nodeId: string): boolean {
1630
+ return !this.readOnly && this.canCopyNode(nodeId);
1631
+ }
1632
+
1633
+ /** A copy of the step after it, as Cmd/Ctrl+D does, leaving the step copied for Paste as it was */
1634
+ duplicateNode(nodeId: string): void {
1635
+ const node = this.document.query.getNode(nodeId);
1636
+ if (node && this.canDuplicateNode(nodeId)) {
1637
+ this.addCopy(node, this.document.context, nodeId);
1638
+ }
1639
+ }
1640
+
1641
+ private canTakeCopy(
1642
+ node: QueryNode,
1643
+ context: CubeContext | undefined,
1644
+ ): boolean {
1645
+ if (!(node instanceof SourceNode)) {
1646
+ return true;
1647
+ }
1648
+ const { document } = this;
1649
+ return (
1650
+ document.query.isEmpty ||
1651
+ JSON.stringify(document.context) === JSON.stringify(context)
1652
+ );
1653
+ }
1654
+
1655
+ private addCopy(
1656
+ node: QueryNode,
1657
+ context: CubeContext | undefined,
1658
+ afterId?: string,
1659
+ ): void {
1660
+ const { document } = this;
1661
+ const copy = copyQueryNode(
1662
+ node,
1663
+ document.query.generateId(node.type),
1664
+ this.registry,
1665
+ );
1666
+ if (!copy) {
1667
+ return;
1668
+ }
1669
+ const after =
1670
+ afterId !== undefined && document.query.canAdd(copy, afterId)
1671
+ ? afterId
1672
+ : undefined;
1673
+ const query = document.query.add(copy, after);
1674
+ // a source pasted into an empty cube brings its model and runtime
1675
+ this.applyDocument(
1676
+ copy instanceof SourceNode && document.query.isEmpty && context
1677
+ ? document.withContext(context).withQuery(query)
1678
+ : document.withQuery(query),
1679
+ );
1680
+ }
1681
+
1187
1682
  canSwapInputs(nodeId: string): boolean {
1188
1683
  return !this.readOnly && this.document.query.canSwapInputs(nodeId);
1189
1684
  }
@@ -1211,6 +1706,31 @@ export class CubeEditorState implements CommandRegistrar {
1211
1706
  }
1212
1707
  }
1213
1708
 
1709
+ /**
1710
+ * Keeps a grid column's width, which the cube saves (PLAN §11.10): by the
1711
+ * column's name, in any case. Presentation the user sets by dragging, so
1712
+ * no undo step, and the rows stay current.
1713
+ */
1714
+ setColumnWidth(column: string, width: number): void {
1715
+ if (!Number.isFinite(width) || width <= 0) {
1716
+ return;
1717
+ }
1718
+ const { meta } = this.document;
1719
+ const { presentation } = meta;
1720
+ const others = presentation.columnWidths.filter(
1721
+ (each) => foldColumnName(each.column) !== foldColumnName(column),
1722
+ );
1723
+ this.replaceDocument(
1724
+ this.document.withMeta({
1725
+ ...meta,
1726
+ presentation: {
1727
+ ...presentation,
1728
+ columnWidths: [...others, { column, width: Math.round(width) }],
1729
+ },
1730
+ }),
1731
+ );
1732
+ }
1733
+
1214
1734
  setHostIssue(nodeId: string, error: CubeEngineError): void {
1215
1735
  this.hostIssues = new Map([
1216
1736
  ...this.hostIssues,
@@ -1248,7 +1768,8 @@ export class CubeEditorState implements CommandRegistrar {
1248
1768
 
1249
1769
  /** Stops any run; call when the page closes */
1250
1770
  dispose(): void {
1251
- this.retyping();
1771
+ this.rechecking();
1772
+ this.outlineLoading();
1252
1773
  this.execution.stop();
1253
1774
  this.nodeEditor.dispose();
1254
1775
  }