@finos/legend-cube-builder 0.0.0-stage → 0.0.3

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 (379) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +64 -2
  3. package/docs/adding-an-operation.md +92 -0
  4. package/docs/hosting.md +79 -0
  5. package/docs/testing.md +83 -0
  6. package/lib/__lib__/LegendCubeCommand.d.ts +26 -0
  7. package/lib/__lib__/LegendCubeCommand.d.ts.map +1 -0
  8. package/lib/__lib__/LegendCubeCommand.js +40 -0
  9. package/lib/__lib__/LegendCubeCommand.js.map +1 -0
  10. package/lib/__lib__/LegendCubeHelpText.d.ts +19 -0
  11. package/lib/__lib__/LegendCubeHelpText.d.ts.map +1 -0
  12. package/lib/__lib__/LegendCubeHelpText.js +35 -0
  13. package/lib/__lib__/LegendCubeHelpText.js.map +1 -0
  14. package/lib/__lib__/LegendCubeLabels.d.ts +87 -0
  15. package/lib/__lib__/LegendCubeLabels.d.ts.map +1 -0
  16. package/lib/__lib__/LegendCubeLabels.js +128 -0
  17. package/lib/__lib__/LegendCubeLabels.js.map +1 -0
  18. package/lib/__lib__/LegendCubeTesting.d.ts +33 -0
  19. package/lib/__lib__/LegendCubeTesting.d.ts.map +1 -0
  20. package/lib/__lib__/LegendCubeTesting.js +34 -0
  21. package/lib/__lib__/LegendCubeTesting.js.map +1 -0
  22. package/lib/__test-utils__/CubeCanvasTestUtils.d.ts +24 -0
  23. package/lib/__test-utils__/CubeCanvasTestUtils.d.ts.map +1 -0
  24. package/lib/__test-utils__/CubeCanvasTestUtils.js +37 -0
  25. package/lib/__test-utils__/CubeCanvasTestUtils.js.map +1 -0
  26. package/lib/__test-utils__/CubeEngineTestSupport.d.ts +47 -0
  27. package/lib/__test-utils__/CubeEngineTestSupport.d.ts.map +1 -0
  28. package/lib/__test-utils__/CubeEngineTestSupport.js +106 -0
  29. package/lib/__test-utils__/CubeEngineTestSupport.js.map +1 -0
  30. package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts +31 -0
  31. package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts.map +1 -0
  32. package/lib/__test-utils__/CubeNorthwindTestQueries.js +102 -0
  33. package/lib/__test-utils__/CubeNorthwindTestQueries.js.map +1 -0
  34. package/lib/__test-utils__/CubeOperationsTestUtils.d.ts +42 -0
  35. package/lib/__test-utils__/CubeOperationsTestUtils.d.ts.map +1 -0
  36. package/lib/__test-utils__/CubeOperationsTestUtils.js +92 -0
  37. package/lib/__test-utils__/CubeOperationsTestUtils.js.map +1 -0
  38. package/lib/__test-utils__/CubePageTestUtils.d.ts +33 -0
  39. package/lib/__test-utils__/CubePageTestUtils.d.ts.map +1 -0
  40. package/lib/__test-utils__/CubePageTestUtils.js +68 -0
  41. package/lib/__test-utils__/CubePageTestUtils.js.map +1 -0
  42. package/lib/__test-utils__/CubeTestApplication.d.ts +30 -0
  43. package/lib/__test-utils__/CubeTestApplication.d.ts.map +1 -0
  44. package/lib/__test-utils__/CubeTestApplication.js +57 -0
  45. package/lib/__test-utils__/CubeTestApplication.js.map +1 -0
  46. package/lib/__test-utils__/FakeCubeEngine.d.ts +41 -0
  47. package/lib/__test-utils__/FakeCubeEngine.d.ts.map +1 -0
  48. package/lib/__test-utils__/FakeCubeEngine.js +91 -0
  49. package/lib/__test-utils__/FakeCubeEngine.js.map +1 -0
  50. package/lib/components/CubeButton.d.ts +20 -0
  51. package/lib/components/CubeButton.d.ts.map +1 -0
  52. package/lib/components/CubeButton.js +24 -0
  53. package/lib/components/CubeButton.js.map +1 -0
  54. package/lib/components/CubeEditor.d.ts +31 -0
  55. package/lib/components/CubeEditor.d.ts.map +1 -0
  56. package/lib/components/CubeEditor.js +90 -0
  57. package/lib/components/CubeEditor.js.map +1 -0
  58. package/lib/components/CubeNodeIcon.d.ts +23 -0
  59. package/lib/components/CubeNodeIcon.d.ts.map +1 -0
  60. package/lib/components/CubeNodeIcon.js +42 -0
  61. package/lib/components/CubeNodeIcon.js.map +1 -0
  62. package/lib/components/canvas/CubeCanvas.d.ts +37 -0
  63. package/lib/components/canvas/CubeCanvas.d.ts.map +1 -0
  64. package/lib/components/canvas/CubeCanvas.js +137 -0
  65. package/lib/components/canvas/CubeCanvas.js.map +1 -0
  66. package/lib/components/canvas/CubeCanvasContext.d.ts +19 -0
  67. package/lib/components/canvas/CubeCanvasContext.d.ts.map +1 -0
  68. package/lib/components/canvas/CubeCanvasContext.js +22 -0
  69. package/lib/components/canvas/CubeCanvasContext.js.map +1 -0
  70. package/lib/components/canvas/CubeCanvasContextMenu.d.ts +28 -0
  71. package/lib/components/canvas/CubeCanvasContextMenu.d.ts.map +1 -0
  72. package/lib/components/canvas/CubeCanvasContextMenu.js +35 -0
  73. package/lib/components/canvas/CubeCanvasContextMenu.js.map +1 -0
  74. package/lib/components/canvas/CubeCanvasDnd.d.ts +43 -0
  75. package/lib/components/canvas/CubeCanvasDnd.d.ts.map +1 -0
  76. package/lib/components/canvas/CubeCanvasDnd.js +51 -0
  77. package/lib/components/canvas/CubeCanvasDnd.js.map +1 -0
  78. package/lib/components/canvas/CubeCanvasEdge.d.ts +24 -0
  79. package/lib/components/canvas/CubeCanvasEdge.d.ts.map +1 -0
  80. package/lib/components/canvas/CubeCanvasEdge.js +33 -0
  81. package/lib/components/canvas/CubeCanvasEdge.js.map +1 -0
  82. package/lib/components/canvas/CubeCanvasElements.d.ts +66 -0
  83. package/lib/components/canvas/CubeCanvasElements.d.ts.map +1 -0
  84. package/lib/components/canvas/CubeCanvasElements.js +97 -0
  85. package/lib/components/canvas/CubeCanvasElements.js.map +1 -0
  86. package/lib/components/canvas/CubeCanvasLayout.d.ts +32 -0
  87. package/lib/components/canvas/CubeCanvasLayout.d.ts.map +1 -0
  88. package/lib/components/canvas/CubeCanvasLayout.js +63 -0
  89. package/lib/components/canvas/CubeCanvasLayout.js.map +1 -0
  90. package/lib/components/canvas/CubeCanvasNode.d.ts +29 -0
  91. package/lib/components/canvas/CubeCanvasNode.d.ts.map +1 -0
  92. package/lib/components/canvas/CubeCanvasNode.js +75 -0
  93. package/lib/components/canvas/CubeCanvasNode.js.map +1 -0
  94. package/lib/components/editors/CubeColumnPicker.d.ts +47 -0
  95. package/lib/components/editors/CubeColumnPicker.d.ts.map +1 -0
  96. package/lib/components/editors/CubeColumnPicker.js +56 -0
  97. package/lib/components/editors/CubeColumnPicker.js.map +1 -0
  98. package/lib/components/editors/CubeDistinctEditor.d.ts +23 -0
  99. package/lib/components/editors/CubeDistinctEditor.d.ts.map +1 -0
  100. package/lib/components/editors/CubeDistinctEditor.js +24 -0
  101. package/lib/components/editors/CubeDistinctEditor.js.map +1 -0
  102. package/lib/components/editors/CubeFilterEditor.d.ts +26 -0
  103. package/lib/components/editors/CubeFilterEditor.d.ts.map +1 -0
  104. package/lib/components/editors/CubeFilterEditor.js +90 -0
  105. package/lib/components/editors/CubeFilterEditor.js.map +1 -0
  106. package/lib/components/editors/CubeIntegerField.d.ts +29 -0
  107. package/lib/components/editors/CubeIntegerField.d.ts.map +1 -0
  108. package/lib/components/editors/CubeIntegerField.js +30 -0
  109. package/lib/components/editors/CubeIntegerField.js.map +1 -0
  110. package/lib/components/editors/CubeJoinEditor.d.ts +26 -0
  111. package/lib/components/editors/CubeJoinEditor.d.ts.map +1 -0
  112. package/lib/components/editors/CubeJoinEditor.js +84 -0
  113. package/lib/components/editors/CubeJoinEditor.js.map +1 -0
  114. package/lib/components/editors/CubeNodeEditorPanel.d.ts +29 -0
  115. package/lib/components/editors/CubeNodeEditorPanel.d.ts.map +1 -0
  116. package/lib/components/editors/CubeNodeEditorPanel.js +72 -0
  117. package/lib/components/editors/CubeNodeEditorPanel.js.map +1 -0
  118. package/lib/components/editors/CubeNodeEditorRegistry.d.ts +44 -0
  119. package/lib/components/editors/CubeNodeEditorRegistry.d.ts.map +1 -0
  120. package/lib/components/editors/CubeNodeEditorRegistry.js +43 -0
  121. package/lib/components/editors/CubeNodeEditorRegistry.js.map +1 -0
  122. package/lib/components/editors/CubeRenameEditor.d.ts +26 -0
  123. package/lib/components/editors/CubeRenameEditor.d.ts.map +1 -0
  124. package/lib/components/editors/CubeRenameEditor.js +58 -0
  125. package/lib/components/editors/CubeRenameEditor.js.map +1 -0
  126. package/lib/components/editors/CubeRestrictEditor.d.ts +26 -0
  127. package/lib/components/editors/CubeRestrictEditor.d.ts.map +1 -0
  128. package/lib/components/editors/CubeRestrictEditor.js +23 -0
  129. package/lib/components/editors/CubeRestrictEditor.js.map +1 -0
  130. package/lib/components/editors/CubeRowCountEditor.d.ts +25 -0
  131. package/lib/components/editors/CubeRowCountEditor.d.ts.map +1 -0
  132. package/lib/components/editors/CubeRowCountEditor.js +38 -0
  133. package/lib/components/editors/CubeRowCountEditor.js.map +1 -0
  134. package/lib/components/editors/CubeSliceEditor.d.ts +25 -0
  135. package/lib/components/editors/CubeSliceEditor.d.ts.map +1 -0
  136. package/lib/components/editors/CubeSliceEditor.js +40 -0
  137. package/lib/components/editors/CubeSliceEditor.js.map +1 -0
  138. package/lib/components/editors/CubeSortEditor.d.ts +27 -0
  139. package/lib/components/editors/CubeSortEditor.d.ts.map +1 -0
  140. package/lib/components/editors/CubeSortEditor.js +72 -0
  141. package/lib/components/editors/CubeSortEditor.js.map +1 -0
  142. package/lib/components/editors/CubeSourceEditor.d.ts +25 -0
  143. package/lib/components/editors/CubeSourceEditor.d.ts.map +1 -0
  144. package/lib/components/editors/CubeSourceEditor.js +41 -0
  145. package/lib/components/editors/CubeSourceEditor.js.map +1 -0
  146. package/lib/components/editors/CubeValueEditor.d.ts +40 -0
  147. package/lib/components/editors/CubeValueEditor.d.ts.map +1 -0
  148. package/lib/components/editors/CubeValueEditor.js +178 -0
  149. package/lib/components/editors/CubeValueEditor.js.map +1 -0
  150. package/lib/components/grid/CubeGridRegion.d.ts +23 -0
  151. package/lib/components/grid/CubeGridRegion.d.ts.map +1 -0
  152. package/lib/components/grid/CubeGridRegion.js +94 -0
  153. package/lib/components/grid/CubeGridRegion.js.map +1 -0
  154. package/lib/components/grid/CubeGridValues.d.ts +25 -0
  155. package/lib/components/grid/CubeGridValues.d.ts.map +1 -0
  156. package/lib/components/grid/CubeGridValues.js +95 -0
  157. package/lib/components/grid/CubeGridValues.js.map +1 -0
  158. package/lib/components/grid/CubeResultGrid.d.ts +39 -0
  159. package/lib/components/grid/CubeResultGrid.d.ts.map +1 -0
  160. package/lib/components/grid/CubeResultGrid.js +86 -0
  161. package/lib/components/grid/CubeResultGrid.js.map +1 -0
  162. package/lib/components/palette/CubePalette.d.ts +29 -0
  163. package/lib/components/palette/CubePalette.d.ts.map +1 -0
  164. package/lib/components/palette/CubePalette.js +73 -0
  165. package/lib/components/palette/CubePalette.js.map +1 -0
  166. package/lib/components/show-pure/CubeShowPureDialog.d.ts +23 -0
  167. package/lib/components/show-pure/CubeShowPureDialog.d.ts.map +1 -0
  168. package/lib/components/show-pure/CubeShowPureDialog.js +37 -0
  169. package/lib/components/show-pure/CubeShowPureDialog.js.map +1 -0
  170. package/lib/components/source-picker/CubeSourcePicker.d.ts +22 -0
  171. package/lib/components/source-picker/CubeSourcePicker.d.ts.map +1 -0
  172. package/lib/components/source-picker/CubeSourcePicker.js +89 -0
  173. package/lib/components/source-picker/CubeSourcePicker.js.map +1 -0
  174. package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts +26 -0
  175. package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts.map +1 -0
  176. package/lib/components/spec-transfer/CubeSpecTransferDialog.js +45 -0
  177. package/lib/components/spec-transfer/CubeSpecTransferDialog.js.map +1 -0
  178. package/lib/graph-manager/CubeEngine.d.ts +128 -0
  179. package/lib/graph-manager/CubeEngine.d.ts.map +1 -0
  180. package/lib/graph-manager/CubeEngine.js +61 -0
  181. package/lib/graph-manager/CubeEngine.js.map +1 -0
  182. package/lib/graph-manager/CubeModelOutlineHelper.d.ts +33 -0
  183. package/lib/graph-manager/CubeModelOutlineHelper.d.ts.map +1 -0
  184. package/lib/graph-manager/CubeModelOutlineHelper.js +45 -0
  185. package/lib/graph-manager/CubeModelOutlineHelper.js.map +1 -0
  186. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts +26 -0
  187. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts.map +1 -0
  188. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js +22 -0
  189. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js.map +1 -0
  190. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts +27 -0
  191. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts.map +1 -0
  192. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js +76 -0
  193. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js.map +1 -0
  194. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts +27 -0
  195. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts.map +1 -0
  196. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js +82 -0
  197. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js.map +1 -0
  198. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts +32 -0
  199. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts.map +1 -0
  200. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js +195 -0
  201. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js.map +1 -0
  202. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts +20 -0
  203. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts.map +1 -0
  204. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js +174 -0
  205. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js.map +1 -0
  206. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts +24 -0
  207. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts.map +1 -0
  208. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js +43 -0
  209. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js.map +1 -0
  210. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts +45 -0
  211. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts.map +1 -0
  212. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js +171 -0
  213. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js.map +1 -0
  214. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts +22 -0
  215. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts.map +1 -0
  216. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js +79 -0
  217. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js.map +1 -0
  218. package/lib/index.css +17 -0
  219. package/lib/index.css.map +1 -0
  220. package/lib/index.d.ts +25 -0
  221. package/lib/index.d.ts.map +1 -0
  222. package/lib/index.js +24 -0
  223. package/lib/index.js.map +1 -0
  224. package/lib/stores/CubeEditorState.d.ts +236 -0
  225. package/lib/stores/CubeEditorState.d.ts.map +1 -0
  226. package/lib/stores/CubeEditorState.js +632 -0
  227. package/lib/stores/CubeEditorState.js.map +1 -0
  228. package/lib/stores/CubeExecutionState.d.ts +67 -0
  229. package/lib/stores/CubeExecutionState.d.ts.map +1 -0
  230. package/lib/stores/CubeExecutionState.js +212 -0
  231. package/lib/stores/CubeExecutionState.js.map +1 -0
  232. package/lib/stores/CubeGridQuickActions.d.ts +40 -0
  233. package/lib/stores/CubeGridQuickActions.d.ts.map +1 -0
  234. package/lib/stores/CubeGridQuickActions.js +86 -0
  235. package/lib/stores/CubeGridQuickActions.js.map +1 -0
  236. package/lib/stores/CubeHost.d.ts +31 -0
  237. package/lib/stores/CubeHost.d.ts.map +1 -0
  238. package/lib/stores/CubeHost.js +17 -0
  239. package/lib/stores/CubeHost.js.map +1 -0
  240. package/lib/stores/CubeNodeEditorState.d.ts +103 -0
  241. package/lib/stores/CubeNodeEditorState.d.ts.map +1 -0
  242. package/lib/stores/CubeNodeEditorState.js +262 -0
  243. package/lib/stores/CubeNodeEditorState.js.map +1 -0
  244. package/lib/stores/CubeShowPureState.d.ts +41 -0
  245. package/lib/stores/CubeShowPureState.d.ts.map +1 -0
  246. package/lib/stores/CubeShowPureState.js +100 -0
  247. package/lib/stores/CubeShowPureState.js.map +1 -0
  248. package/lib/stores/CubeSourcePickerState.d.ts +98 -0
  249. package/lib/stores/CubeSourcePickerState.d.ts.map +1 -0
  250. package/lib/stores/CubeSourcePickerState.js +334 -0
  251. package/lib/stores/CubeSourcePickerState.js.map +1 -0
  252. package/lib/stores/CubeSpecTransferState.d.ts +60 -0
  253. package/lib/stores/CubeSpecTransferState.d.ts.map +1 -0
  254. package/lib/stores/CubeSpecTransferState.js +167 -0
  255. package/lib/stores/CubeSpecTransferState.js.map +1 -0
  256. package/lib/stores/LocalModelCatalog.d.ts +37 -0
  257. package/lib/stores/LocalModelCatalog.d.ts.map +1 -0
  258. package/lib/stores/LocalModelCatalog.js +49 -0
  259. package/lib/stores/LocalModelCatalog.js.map +1 -0
  260. package/lib/stores/editors/CubeFilterDraft.d.ts +61 -0
  261. package/lib/stores/editors/CubeFilterDraft.d.ts.map +1 -0
  262. package/lib/stores/editors/CubeFilterDraft.js +186 -0
  263. package/lib/stores/editors/CubeFilterDraft.js.map +1 -0
  264. package/lib/stores/editors/CubeIntegerText.d.ts +24 -0
  265. package/lib/stores/editors/CubeIntegerText.d.ts.map +1 -0
  266. package/lib/stores/editors/CubeIntegerText.js +33 -0
  267. package/lib/stores/editors/CubeIntegerText.js.map +1 -0
  268. package/lib/stores/editors/CubeJoinDraft.d.ts +71 -0
  269. package/lib/stores/editors/CubeJoinDraft.d.ts.map +1 -0
  270. package/lib/stores/editors/CubeJoinDraft.js +145 -0
  271. package/lib/stores/editors/CubeJoinDraft.js.map +1 -0
  272. package/lib/stores/editors/CubeNodeDraft.d.ts +38 -0
  273. package/lib/stores/editors/CubeNodeDraft.d.ts.map +1 -0
  274. package/lib/stores/editors/CubeNodeDraft.js +35 -0
  275. package/lib/stores/editors/CubeNodeDraft.js.map +1 -0
  276. package/lib/stores/editors/CubeNodeDraftRegistry.d.ts +35 -0
  277. package/lib/stores/editors/CubeNodeDraftRegistry.d.ts.map +1 -0
  278. package/lib/stores/editors/CubeNodeDraftRegistry.js +55 -0
  279. package/lib/stores/editors/CubeNodeDraftRegistry.js.map +1 -0
  280. package/lib/stores/editors/CubeRenameDraft.d.ts +44 -0
  281. package/lib/stores/editors/CubeRenameDraft.d.ts.map +1 -0
  282. package/lib/stores/editors/CubeRenameDraft.js +79 -0
  283. package/lib/stores/editors/CubeRenameDraft.js.map +1 -0
  284. package/lib/stores/editors/CubeRestrictDraft.d.ts +37 -0
  285. package/lib/stores/editors/CubeRestrictDraft.d.ts.map +1 -0
  286. package/lib/stores/editors/CubeRestrictDraft.js +73 -0
  287. package/lib/stores/editors/CubeRestrictDraft.js.map +1 -0
  288. package/lib/stores/editors/CubeRowCountDraft.d.ts +42 -0
  289. package/lib/stores/editors/CubeRowCountDraft.d.ts.map +1 -0
  290. package/lib/stores/editors/CubeRowCountDraft.js +55 -0
  291. package/lib/stores/editors/CubeRowCountDraft.js.map +1 -0
  292. package/lib/stores/editors/CubeSliceDraft.d.ts +42 -0
  293. package/lib/stores/editors/CubeSliceDraft.d.ts.map +1 -0
  294. package/lib/stores/editors/CubeSliceDraft.js +72 -0
  295. package/lib/stores/editors/CubeSliceDraft.js.map +1 -0
  296. package/lib/stores/editors/CubeSortDraft.d.ts +49 -0
  297. package/lib/stores/editors/CubeSortDraft.d.ts.map +1 -0
  298. package/lib/stores/editors/CubeSortDraft.js +99 -0
  299. package/lib/stores/editors/CubeSortDraft.js.map +1 -0
  300. package/lib/stores/fixtures/CubeNorthwindModel.d.ts +23 -0
  301. package/lib/stores/fixtures/CubeNorthwindModel.d.ts.map +1 -0
  302. package/lib/stores/fixtures/CubeNorthwindModel.js +338 -0
  303. package/lib/stores/fixtures/CubeNorthwindModel.js.map +1 -0
  304. package/package.json +81 -3
  305. package/src/__lib__/LegendCubeCommand.ts +44 -0
  306. package/src/__lib__/LegendCubeHelpText.ts +58 -0
  307. package/src/__lib__/LegendCubeLabels.ts +171 -0
  308. package/src/__lib__/LegendCubeTesting.ts +33 -0
  309. package/src/__test-utils__/CubeCanvasTestUtils.ts +53 -0
  310. package/src/__test-utils__/CubeEngineTestSupport.ts +172 -0
  311. package/src/__test-utils__/CubeNorthwindTestQueries.ts +165 -0
  312. package/src/__test-utils__/CubeOperationsTestUtils.ts +177 -0
  313. package/src/__test-utils__/CubePageTestUtils.tsx +96 -0
  314. package/src/__test-utils__/CubeTestApplication.ts +82 -0
  315. package/src/__test-utils__/FakeCubeEngine.ts +145 -0
  316. package/src/components/CubeButton.tsx +35 -0
  317. package/src/components/CubeEditor.tsx +239 -0
  318. package/src/components/CubeNodeIcon.tsx +64 -0
  319. package/src/components/canvas/CubeCanvas.tsx +262 -0
  320. package/src/components/canvas/CubeCanvasContext.ts +31 -0
  321. package/src/components/canvas/CubeCanvasContextMenu.tsx +89 -0
  322. package/src/components/canvas/CubeCanvasDnd.ts +82 -0
  323. package/src/components/canvas/CubeCanvasEdge.tsx +57 -0
  324. package/src/components/canvas/CubeCanvasElements.ts +153 -0
  325. package/src/components/canvas/CubeCanvasLayout.ts +88 -0
  326. package/src/components/canvas/CubeCanvasNode.tsx +149 -0
  327. package/src/components/editors/CubeColumnPicker.tsx +138 -0
  328. package/src/components/editors/CubeDistinctEditor.tsx +28 -0
  329. package/src/components/editors/CubeFilterEditor.tsx +309 -0
  330. package/src/components/editors/CubeIntegerField.tsx +51 -0
  331. package/src/components/editors/CubeJoinEditor.tsx +247 -0
  332. package/src/components/editors/CubeNodeEditorPanel.tsx +215 -0
  333. package/src/components/editors/CubeNodeEditorRegistry.ts +81 -0
  334. package/src/components/editors/CubeRenameEditor.tsx +143 -0
  335. package/src/components/editors/CubeRestrictEditor.tsx +103 -0
  336. package/src/components/editors/CubeRowCountEditor.tsx +53 -0
  337. package/src/components/editors/CubeSliceEditor.tsx +69 -0
  338. package/src/components/editors/CubeSortEditor.tsx +206 -0
  339. package/src/components/editors/CubeSourceEditor.tsx +106 -0
  340. package/src/components/editors/CubeValueEditor.tsx +333 -0
  341. package/src/components/grid/CubeGridRegion.tsx +275 -0
  342. package/src/components/grid/CubeGridValues.ts +125 -0
  343. package/src/components/grid/CubeResultGrid.tsx +138 -0
  344. package/src/components/palette/CubePalette.tsx +177 -0
  345. package/src/components/show-pure/CubeShowPureDialog.tsx +101 -0
  346. package/src/components/source-picker/CubeSourcePicker.tsx +304 -0
  347. package/src/components/spec-transfer/CubeSpecTransferDialog.tsx +157 -0
  348. package/src/graph-manager/CubeEngine.ts +169 -0
  349. package/src/graph-manager/CubeModelOutlineHelper.ts +58 -0
  350. package/src/graph-manager/protocol/pure/CubeEngineBuilder.ts +34 -0
  351. package/src/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.ts +109 -0
  352. package/src/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.ts +115 -0
  353. package/src/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.ts +257 -0
  354. package/src/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.ts +243 -0
  355. package/src/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.ts +58 -0
  356. package/src/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.ts +278 -0
  357. package/src/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.ts +127 -0
  358. package/src/index.ts +41 -0
  359. package/src/stores/CubeEditorState.ts +807 -0
  360. package/src/stores/CubeExecutionState.ts +288 -0
  361. package/src/stores/CubeGridQuickActions.ts +129 -0
  362. package/src/stores/CubeHost.ts +32 -0
  363. package/src/stores/CubeNodeEditorState.ts +324 -0
  364. package/src/stores/CubeShowPureState.ts +118 -0
  365. package/src/stores/CubeSourcePickerState.ts +426 -0
  366. package/src/stores/CubeSpecTransferState.ts +198 -0
  367. package/src/stores/LocalModelCatalog.ts +70 -0
  368. package/src/stores/editors/CubeFilterDraft.ts +241 -0
  369. package/src/stores/editors/CubeIntegerText.ts +34 -0
  370. package/src/stores/editors/CubeJoinDraft.ts +224 -0
  371. package/src/stores/editors/CubeNodeDraft.ts +46 -0
  372. package/src/stores/editors/CubeNodeDraftRegistry.ts +83 -0
  373. package/src/stores/editors/CubeRenameDraft.ts +110 -0
  374. package/src/stores/editors/CubeRestrictDraft.ts +83 -0
  375. package/src/stores/editors/CubeRowCountDraft.ts +69 -0
  376. package/src/stores/editors/CubeSliceDraft.ts +87 -0
  377. package/src/stores/editors/CubeSortDraft.ts +135 -0
  378. package/src/stores/fixtures/CubeNorthwindModel.ts +355 -0
  379. package/tsconfig.json +133 -0
@@ -0,0 +1,426 @@
1
+ /**
2
+ * Copyright (c) 2026-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ type CubeContext,
19
+ getRelationalDisplayName,
20
+ type ModelContext,
21
+ RELATIONAL_TABLE_SOURCE_DEFINITION,
22
+ RelationalTableSource,
23
+ } from '@finos/legend-cube';
24
+ import { assertErrorThrown, type GeneratorFn } from '@finos/legend-shared';
25
+ import {
26
+ action,
27
+ computed,
28
+ flow,
29
+ flowResult,
30
+ makeObservable,
31
+ observable,
32
+ } from 'mobx';
33
+ import {
34
+ CubeEngineError,
35
+ CubeEngineErrorKind,
36
+ CubeTableFlag,
37
+ type CubeModelOutline,
38
+ type CubeOutlineDatabase,
39
+ type CubeOutlineRuntime,
40
+ type CubeOutlineSchema,
41
+ type CubeOutlineTable,
42
+ } from '../graph-manager/CubeEngine.js';
43
+ import { getRuntimesForDatabase } from '../graph-manager/CubeModelOutlineHelper.js';
44
+ import type { CubeEditorState } from './CubeEditorState.js';
45
+ import { type BundledModel, createTextModel } from './LocalModelCatalog.js';
46
+
47
+ const toMessage = (error: unknown): string => {
48
+ assertErrorThrown(error);
49
+ return error instanceof CubeEngineError ? error.firstLine : error.message;
50
+ };
51
+
52
+ /** Whether a table can be picked: a table with a column Cube can't read can't */
53
+ export const isTableSelectable = (table: CubeOutlineTable): boolean =>
54
+ !table.flags.includes(CubeTableFlag.UNAVAILABLE);
55
+
56
+ /**
57
+ * The source picker (PLAN §6.2.7, Settled before M1.8): model, then database,
58
+ * then a runtime keyed by that database, then schema and table. A step with
59
+ * a single choice is picked automatically. The first table fixes the cube's
60
+ * model and runtime; later tables come from the same database and runtime.
61
+ * A table is added only once its schema has resolved.
62
+ */
63
+ export class CubeSourcePickerState {
64
+ readonly editorState: CubeEditorState;
65
+
66
+ isOpen = false;
67
+ model: ModelContext | undefined;
68
+ /** The model is Pure text the user pastes, not a bundled one */
69
+ isPastingModel = false;
70
+ pastedModelText = '';
71
+ /** The model the paste box last loaded: only it keeps the box shown */
72
+ private pastedModel: ModelContext | undefined;
73
+ outline: CubeModelOutline | undefined;
74
+ isLoadingModel = false;
75
+ databasePath: string | undefined;
76
+ runtimePath: string | undefined;
77
+ schemaName: string | undefined;
78
+ tableName: string | undefined;
79
+ tableSearch = '';
80
+ isResolving = false;
81
+ /** Why the outline or the table couldn't be loaded, shown in the dialog */
82
+ error: string | undefined;
83
+ /** Counts Add presses: closing the dialog moves it on, so the pending Add is dropped */
84
+ private confirmRequest = 0;
85
+
86
+ constructor(editorState: CubeEditorState) {
87
+ makeObservable(this, {
88
+ isOpen: observable,
89
+ model: observable.ref,
90
+ isPastingModel: observable,
91
+ pastedModelText: observable,
92
+ outline: observable.ref,
93
+ isLoadingModel: observable,
94
+ databasePath: observable,
95
+ runtimePath: observable,
96
+ schemaName: observable,
97
+ tableName: observable,
98
+ tableSearch: observable,
99
+ isResolving: observable,
100
+ error: observable,
101
+ fixedContext: computed,
102
+ fixedDatabasePath: computed,
103
+ databases: computed,
104
+ runtimes: computed,
105
+ schemas: computed,
106
+ tables: computed,
107
+ canConfirm: computed,
108
+ open: action,
109
+ close: action,
110
+ selectDatabase: action,
111
+ selectRuntime: action,
112
+ selectSchema: action,
113
+ selectTable: action,
114
+ setTableSearch: action,
115
+ startPastingModel: action,
116
+ setPastedModelText: action,
117
+ selectModel: flow,
118
+ loadPastedModel: flow,
119
+ confirm: flow,
120
+ });
121
+ this.editorState = editorState;
122
+ }
123
+
124
+ get models(): readonly BundledModel[] {
125
+ return this.editorState.host.modelCatalog.models;
126
+ }
127
+
128
+ /** Once the cube has a model, every table comes from it */
129
+ get fixedContext(): CubeContext | undefined {
130
+ return this.editorState.document.context;
131
+ }
132
+
133
+ /** Once the cube has a table, every other one comes from its database */
134
+ get fixedDatabasePath(): string | undefined {
135
+ return this.editorState.document.query.nodes.find(
136
+ (node): node is RelationalTableSource =>
137
+ node instanceof RelationalTableSource,
138
+ )?.database;
139
+ }
140
+
141
+ get databases(): readonly CubeOutlineDatabase[] {
142
+ const databases = this.outline?.databases ?? [];
143
+ const fixedRuntime = this.fixedContext?.runtime;
144
+ return databases.filter(
145
+ (database) =>
146
+ (this.fixedDatabasePath === undefined ||
147
+ database.path === this.fixedDatabasePath) &&
148
+ (fixedRuntime === undefined ||
149
+ (this.outline &&
150
+ getRuntimesForDatabase(this.outline, database.path).some(
151
+ (runtime) => runtime.path === fixedRuntime,
152
+ ))),
153
+ );
154
+ }
155
+
156
+ get runtimes(): readonly CubeOutlineRuntime[] {
157
+ if (!this.outline || this.databasePath === undefined) {
158
+ return [];
159
+ }
160
+ const fixedRuntime = this.fixedContext?.runtime;
161
+ return getRuntimesForDatabase(this.outline, this.databasePath).filter(
162
+ (runtime) => fixedRuntime === undefined || runtime.path === fixedRuntime,
163
+ );
164
+ }
165
+
166
+ get schemas(): readonly CubeOutlineSchema[] {
167
+ return (
168
+ this.databases.find((database) => database.path === this.databasePath)
169
+ ?.schemas ?? []
170
+ );
171
+ }
172
+
173
+ /** The schema's tables, views left out, filtered by the search text */
174
+ get tables(): readonly CubeOutlineTable[] {
175
+ const search = this.tableSearch.trim().toLowerCase();
176
+ return (
177
+ this.schemas.find((schema) => schema.name === this.schemaName)?.tables ??
178
+ []
179
+ ).filter(
180
+ (table) =>
181
+ !table.isView &&
182
+ getRelationalDisplayName(table.name).toLowerCase().includes(search),
183
+ );
184
+ }
185
+
186
+ get canConfirm(): boolean {
187
+ const table = this.tables.find(
188
+ (candidate) => candidate.name === this.tableName,
189
+ );
190
+ return (
191
+ !this.isLoadingModel &&
192
+ !this.isResolving &&
193
+ this.model !== undefined &&
194
+ this.runtimePath !== undefined &&
195
+ table !== undefined &&
196
+ isTableSelectable(table)
197
+ );
198
+ }
199
+
200
+ /**
201
+ * Opens the dialog on the cube's model, or on the only model offered. A
202
+ * model whose outline failed to load is loaded again. Does nothing while
203
+ * the cube is read-only.
204
+ */
205
+ open(): void {
206
+ if (this.editorState.readOnly) {
207
+ return;
208
+ }
209
+ this.isOpen = true;
210
+ this.error = undefined;
211
+ const model =
212
+ this.fixedContext?.model ??
213
+ (this.models.length === 1 && !this.isPastingModel
214
+ ? this.models[0]?.model
215
+ : this.model);
216
+ if (!model) {
217
+ return;
218
+ }
219
+ if (model !== this.model || !this.outline) {
220
+ flowResult(this.selectModel(model)).catch(
221
+ this.editorState.host.applicationStore.alertUnhandledError,
222
+ );
223
+ } else if (
224
+ this.databasePath !== undefined &&
225
+ !this.databases.some((database) => database.path === this.databasePath)
226
+ ) {
227
+ // the cube changed since the last pick, e.g. by undo
228
+ const [onlyDatabase, ...otherDatabases] = this.databases;
229
+ this.selectDatabase(
230
+ onlyDatabase && !otherDatabases.length ? onlyDatabase.path : undefined,
231
+ );
232
+ }
233
+ }
234
+
235
+ /** Closes the dialog; a table still being typed is not added */
236
+ close(): void {
237
+ this.isOpen = false;
238
+ this.confirmRequest++;
239
+ this.isResolving = false;
240
+ }
241
+
242
+ /** Offers a text box for a Pure model in place of the bundled ones */
243
+ startPastingModel(): void {
244
+ this.isPastingModel = true;
245
+ this.model = undefined;
246
+ this.outline = undefined;
247
+ this.error = undefined;
248
+ this.isLoadingModel = false;
249
+ this.resetFrom('database');
250
+ }
251
+
252
+ setPastedModelText(text: string): void {
253
+ this.pastedModelText = text;
254
+ }
255
+
256
+ /**
257
+ * Loads the pasted Pure text as the model: the cube will hold the text
258
+ * itself, so it counts towards the size a saved cube can have
259
+ */
260
+ *loadPastedModel(): GeneratorFn<void> {
261
+ if (this.pastedModelText.trim()) {
262
+ this.pastedModel = createTextModel(this.pastedModelText);
263
+ yield flowResult(this.selectModel(this.pastedModel));
264
+ }
265
+ }
266
+
267
+ /**
268
+ * Loads a model's outline. Any model but the one the paste box loaded ends
269
+ * pasting, e.g. a bundled model, or the model of a cube opened meanwhile.
270
+ */
271
+ *selectModel(model: ModelContext): GeneratorFn<void> {
272
+ this.isPastingModel = model === this.pastedModel;
273
+ this.model = model;
274
+ this.outline = undefined;
275
+ this.error = undefined;
276
+ this.resetFrom('database');
277
+ this.isLoadingModel = true;
278
+ try {
279
+ const outline = (yield this.editorState.host.modelCatalog.loadOutline(
280
+ model,
281
+ )) as CubeModelOutline;
282
+ if (this.model !== model) {
283
+ return;
284
+ }
285
+ this.outline = outline;
286
+ const [onlyDatabase, ...otherDatabases] = this.databases;
287
+ if (onlyDatabase && !otherDatabases.length) {
288
+ this.selectDatabase(onlyDatabase.path);
289
+ }
290
+ } catch (error) {
291
+ if (this.model === model) {
292
+ this.error = toMessage(error);
293
+ }
294
+ } finally {
295
+ if (this.model === model) {
296
+ this.isLoadingModel = false;
297
+ }
298
+ }
299
+ }
300
+
301
+ selectDatabase(path: string | undefined): void {
302
+ this.databasePath = path;
303
+ this.resetFrom('runtime');
304
+ const [onlyRuntime, ...otherRuntimes] = this.runtimes;
305
+ if (onlyRuntime && !otherRuntimes.length) {
306
+ this.runtimePath = onlyRuntime.path;
307
+ }
308
+ const [onlySchema, ...otherSchemas] = this.schemas;
309
+ if (onlySchema && !otherSchemas.length) {
310
+ this.schemaName = onlySchema.name;
311
+ }
312
+ }
313
+
314
+ selectRuntime(path: string | undefined): void {
315
+ this.runtimePath = path;
316
+ }
317
+
318
+ selectSchema(name: string | undefined): void {
319
+ this.schemaName = name;
320
+ this.resetFrom('table');
321
+ }
322
+
323
+ selectTable(name: string | undefined): void {
324
+ this.tableName = name;
325
+ this.error = undefined;
326
+ }
327
+
328
+ setTableSearch(search: string): void {
329
+ this.tableSearch = search;
330
+ }
331
+
332
+ /**
333
+ * Types the picked table with the engine, then adds it; the first table
334
+ * also sets the cube's model and runtime, in the same undo step. The cube
335
+ * may have changed while the engine answered: the table is added only if
336
+ * the cube still has the same model and runtime and can take it.
337
+ */
338
+ *confirm(): GeneratorFn<void> {
339
+ if (!this.canConfirm) {
340
+ return;
341
+ }
342
+ const { editorState } = this;
343
+ const model = this.model as ModelContext;
344
+ const runtime = this.runtimePath as string;
345
+ const coordinates = {
346
+ database: this.databasePath as string,
347
+ schema: this.schemaName as string,
348
+ table: this.tableName as string,
349
+ };
350
+ const contextBefore = editorState.document.context;
351
+ // the engine stamps the table's accessor with its node id, so the id comes first
352
+ const id = editorState.document.query.generateId(
353
+ RelationalTableSource.TYPE,
354
+ );
355
+ const request = ++this.confirmRequest;
356
+ this.isResolving = true;
357
+ this.error = undefined;
358
+ try {
359
+ const typed = (yield editorState.host.engine.resolveSchemas(
360
+ model,
361
+ new Map([
362
+ [id, [coordinates.database, coordinates.schema, coordinates.table]],
363
+ ]),
364
+ )) as Awaited<ReturnType<typeof editorState.host.engine.resolveSchemas>>;
365
+ if (request !== this.confirmRequest) {
366
+ return;
367
+ }
368
+ const schema = typed.get(id);
369
+ if (schema === undefined || schema instanceof CubeEngineError) {
370
+ throw (
371
+ schema ??
372
+ new CubeEngineError(
373
+ CubeEngineErrorKind.COMPILE,
374
+ `The engine gave no schema for this table`,
375
+ )
376
+ );
377
+ }
378
+ const node = RELATIONAL_TABLE_SOURCE_DEFINITION.resolve(
379
+ RELATIONAL_TABLE_SOURCE_DEFINITION.fromCoordinates(id, coordinates),
380
+ { kind: 'resolved', schema },
381
+ );
382
+ const { document } = editorState;
383
+ if (document.context !== contextBefore || !document.query.canAdd(node)) {
384
+ throw new Error(
385
+ `The cube changed while the table was loading; pick the table again.`,
386
+ );
387
+ }
388
+ const query = document.query.add(node);
389
+ // the first table sets the model and runtime; a cube saved with a model
390
+ // but no runtime takes the picked runtime and keeps the rest
391
+ editorState.applyDocument(
392
+ document.context?.runtime !== undefined
393
+ ? document.withQuery(query)
394
+ : document
395
+ .withContext({
396
+ ...document.context,
397
+ model: document.context?.model ?? model,
398
+ runtime,
399
+ })
400
+ .withQuery(query),
401
+ );
402
+ this.isOpen = false;
403
+ this.resetFrom('table');
404
+ } catch (error) {
405
+ if (request === this.confirmRequest) {
406
+ this.error = toMessage(error);
407
+ }
408
+ } finally {
409
+ if (request === this.confirmRequest) {
410
+ this.isResolving = false;
411
+ }
412
+ }
413
+ }
414
+
415
+ private resetFrom(step: 'database' | 'runtime' | 'table'): void {
416
+ if (step === 'database') {
417
+ this.databasePath = undefined;
418
+ }
419
+ if (step === 'database' || step === 'runtime') {
420
+ this.runtimePath = undefined;
421
+ this.schemaName = undefined;
422
+ }
423
+ this.tableName = undefined;
424
+ this.tableSearch = '';
425
+ }
426
+ }
@@ -0,0 +1,198 @@
1
+ /**
2
+ * Copyright (c) 2026-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ CubeSpecDecodeError,
19
+ MAX_SPEC_BYTES,
20
+ parseCubeSpec,
21
+ serializeCubeSpec,
22
+ } from '@finos/legend-cube';
23
+ import {
24
+ ContentType,
25
+ downloadFileUsingDataURI,
26
+ type GeneratorFn,
27
+ readFileAsText,
28
+ } from '@finos/legend-shared';
29
+ import { action, flow, makeObservable, observable } from 'mobx';
30
+ import type { CubeEditorState } from './CubeEditorState.js';
31
+
32
+ export enum CUBE_SPEC_TRANSFER_MODE {
33
+ EXPORT = 'export',
34
+ IMPORT = 'import',
35
+ }
36
+
37
+ const errorMessage = (error: unknown): string =>
38
+ error instanceof Error ? error.message : String(error);
39
+
40
+ /** Why a spec can't be imported; a broken document names the path of the problem */
41
+ export const getSpecImportError = (error: unknown): string =>
42
+ error instanceof CubeSpecDecodeError
43
+ ? error.path
44
+ ? `Can't import the spec: ${error.path} ${error.detail}`
45
+ : `Can't import the spec: it ${error.detail}`
46
+ : `Can't import the spec: ${errorMessage(error)}`;
47
+
48
+ /** A file name for a cube's spec, from its name */
49
+ export const getCubeSpecFileName = (name: string | undefined): string => {
50
+ const base = name?.trim().replace(/[^\w.-]+/gu, '_') ?? '';
51
+ return `${base.length ? base : 'cube'}.cube.json`;
52
+ };
53
+
54
+ /**
55
+ * Export and import of the saved spec (PLAN §10.3), the only way to keep a
56
+ * cube until the Cube store (M8). Both are developer tools for now, labelled
57
+ * "(dev)" (Settled before M1.8).
58
+ */
59
+ export class CubeSpecTransferState {
60
+ readonly editorState: CubeEditorState;
61
+
62
+ mode: CUBE_SPEC_TRANSFER_MODE | undefined;
63
+ /** The spec to export, once written */
64
+ exportText: string | undefined;
65
+ /** The spec text to import, pasted or read from a file */
66
+ importText = '';
67
+ /** Why the export or the import failed */
68
+ error: string | undefined;
69
+ isReadingFile = false;
70
+ /** Counts file reads, so a read that finishes after another starts is dropped */
71
+ private fileRequest = 0;
72
+
73
+ constructor(editorState: CubeEditorState) {
74
+ makeObservable<CubeSpecTransferState, 'fileRequest'>(this, {
75
+ mode: observable,
76
+ exportText: observable,
77
+ importText: observable,
78
+ error: observable,
79
+ isReadingFile: observable,
80
+ fileRequest: observable,
81
+ openExport: action,
82
+ openImport: action,
83
+ close: action,
84
+ setImportText: action,
85
+ importSpec: action,
86
+ readImportFile: flow,
87
+ });
88
+ this.editorState = editorState;
89
+ }
90
+
91
+ /** Writes the cube's spec, invalid queries included; a spec over the size cap is refused */
92
+ openExport(): void {
93
+ this.mode = CUBE_SPEC_TRANSFER_MODE.EXPORT;
94
+ this.error = undefined;
95
+ this.exportText = undefined;
96
+ const { document, registry } = this.editorState;
97
+ try {
98
+ this.exportText = serializeCubeSpec(document, registry);
99
+ } catch (error) {
100
+ this.error = errorMessage(error);
101
+ }
102
+ }
103
+
104
+ openImport(): void {
105
+ this.mode = CUBE_SPEC_TRANSFER_MODE.IMPORT;
106
+ this.error = undefined;
107
+ this.importText = '';
108
+ this.isReadingFile = false;
109
+ }
110
+
111
+ close(): void {
112
+ this.mode = undefined;
113
+ this.exportText = undefined;
114
+ this.importText = '';
115
+ this.error = undefined;
116
+ this.fileRequest++;
117
+ this.isReadingFile = false;
118
+ }
119
+
120
+ setImportText(text: string): void {
121
+ this.importText = text;
122
+ this.error = undefined;
123
+ }
124
+
125
+ async copyExport(): Promise<void> {
126
+ if (this.exportText !== undefined) {
127
+ await this.editorState.host.applicationStore.clipboardService.copyTextToClipboard(
128
+ this.exportText,
129
+ { notifySuccessMessage: 'Cube spec copied to the clipboard' },
130
+ );
131
+ }
132
+ }
133
+
134
+ downloadExport(): void {
135
+ if (this.exportText !== undefined) {
136
+ downloadFileUsingDataURI(
137
+ getCubeSpecFileName(this.editorState.document.name),
138
+ this.exportText,
139
+ ContentType.APPLICATION_JSON,
140
+ );
141
+ }
142
+ }
143
+
144
+ /** Reads a spec file into the import text; a file over the size cap is refused unread */
145
+ *readImportFile(file: File): GeneratorFn<void> {
146
+ const request = ++this.fileRequest;
147
+ this.error = undefined;
148
+ if (file.size > MAX_SPEC_BYTES) {
149
+ // a file being read before this one is dropped
150
+ this.isReadingFile = false;
151
+ this.error = `The file is too large to import: a spec is at most ${MAX_SPEC_BYTES} bytes`;
152
+ return;
153
+ }
154
+ this.isReadingFile = true;
155
+ try {
156
+ const text = (yield readFileAsText(file)) as string;
157
+ if (request === this.fileRequest) {
158
+ this.importText = text;
159
+ }
160
+ } catch (error) {
161
+ if (request === this.fileRequest) {
162
+ // the browser's FileReader rejects with its error event, not an Error
163
+ const reason =
164
+ error instanceof Error
165
+ ? error.message
166
+ : error instanceof ProgressEvent &&
167
+ error.target instanceof FileReader
168
+ ? (error.target.error?.message ?? 'the browser could not read it')
169
+ : String(error);
170
+ this.error = `Can't read the file: ${reason}`;
171
+ }
172
+ } finally {
173
+ if (request === this.fileRequest) {
174
+ this.isReadingFile = false;
175
+ }
176
+ }
177
+ }
178
+
179
+ /**
180
+ * Opens the spec in place of the cube, as one undo step, and never runs it.
181
+ * A spec that can't be read leaves the cube as it was and says why: a
182
+ * broken document names the path of the problem, e.g. `query.nodes[2].database`.
183
+ */
184
+ importSpec(): boolean {
185
+ let decoded: ReturnType<typeof parseCubeSpec>;
186
+ try {
187
+ decoded = parseCubeSpec(this.importText, {
188
+ registry: this.editorState.registry,
189
+ });
190
+ } catch (error) {
191
+ this.error = getSpecImportError(error);
192
+ return false;
193
+ }
194
+ this.editorState.importDocument(decoded.document, decoded.readOnly);
195
+ this.close();
196
+ return true;
197
+ }
198
+ }
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Copyright (c) 2026-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import type { ModelContext } from '@finos/legend-cube';
18
+ import type {
19
+ CubeEngine,
20
+ CubeModelOutline,
21
+ } from '../graph-manager/CubeEngine.js';
22
+ import { CUBE_NORTHWIND_MODEL } from './fixtures/CubeNorthwindModel.js';
23
+
24
+ // The models of the slice (PLAN §6.2.3): Pure text bundled with Cube, or
25
+ // pasted by the user. Picking one gives the model context the cube saves, the
26
+ // text itself (§6.2.2), so a saved cube needs no catalog to open.
27
+
28
+ export interface BundledModel {
29
+ readonly id: string;
30
+ readonly label: string;
31
+ readonly model: ModelContext;
32
+ }
33
+
34
+ export const BUNDLED_MODELS: readonly BundledModel[] = Object.freeze([
35
+ {
36
+ id: 'cube-northwind',
37
+ label: 'Northwind (Cube fixture)',
38
+ model: CUBE_NORTHWIND_MODEL,
39
+ },
40
+ ]);
41
+
42
+ /** The model context of pasted Pure text */
43
+ export const createTextModel = (code: string): ModelContext =>
44
+ Object.freeze({ _type: 'text', code });
45
+
46
+ /**
47
+ * Loads the outlines of models through the engine port, each model's once:
48
+ * the picker asks again whenever it opens
49
+ */
50
+ export class LocalModelCatalog {
51
+ readonly models = BUNDLED_MODELS;
52
+ private readonly engine: CubeEngine;
53
+ private readonly outlines = new Map<string, Promise<CubeModelOutline>>();
54
+
55
+ constructor(engine: CubeEngine) {
56
+ this.engine = engine;
57
+ }
58
+
59
+ loadOutline(model: ModelContext): Promise<CubeModelOutline> {
60
+ const key = JSON.stringify(model);
61
+ let outline = this.outlines.get(key);
62
+ if (!outline) {
63
+ outline = this.engine.loadModel(model);
64
+ // a failed load is tried again next time
65
+ outline.catch(() => this.outlines.delete(key));
66
+ this.outlines.set(key, outline);
67
+ }
68
+ return outline;
69
+ }
70
+ }