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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (301) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +5 -2
  3. package/lib/__lib__/LegendCubeCommand.d.ts +26 -0
  4. package/lib/__lib__/LegendCubeCommand.d.ts.map +1 -0
  5. package/lib/__lib__/LegendCubeCommand.js +40 -0
  6. package/lib/__lib__/LegendCubeCommand.js.map +1 -0
  7. package/lib/__lib__/LegendCubeHelpText.d.ts +19 -0
  8. package/lib/__lib__/LegendCubeHelpText.d.ts.map +1 -0
  9. package/lib/__lib__/LegendCubeHelpText.js +27 -0
  10. package/lib/__lib__/LegendCubeHelpText.js.map +1 -0
  11. package/lib/__lib__/LegendCubeLabels.d.ts +68 -0
  12. package/lib/__lib__/LegendCubeLabels.d.ts.map +1 -0
  13. package/lib/__lib__/LegendCubeLabels.js +109 -0
  14. package/lib/__lib__/LegendCubeLabels.js.map +1 -0
  15. package/lib/__lib__/LegendCubeTesting.d.ts +33 -0
  16. package/lib/__lib__/LegendCubeTesting.d.ts.map +1 -0
  17. package/lib/__lib__/LegendCubeTesting.js +34 -0
  18. package/lib/__lib__/LegendCubeTesting.js.map +1 -0
  19. package/lib/__test-utils__/CubeCanvasTestUtils.d.ts +24 -0
  20. package/lib/__test-utils__/CubeCanvasTestUtils.d.ts.map +1 -0
  21. package/lib/__test-utils__/CubeCanvasTestUtils.js +37 -0
  22. package/lib/__test-utils__/CubeCanvasTestUtils.js.map +1 -0
  23. package/lib/__test-utils__/CubeEngineTestSupport.d.ts +41 -0
  24. package/lib/__test-utils__/CubeEngineTestSupport.d.ts.map +1 -0
  25. package/lib/__test-utils__/CubeEngineTestSupport.js +76 -0
  26. package/lib/__test-utils__/CubeEngineTestSupport.js.map +1 -0
  27. package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts +31 -0
  28. package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts.map +1 -0
  29. package/lib/__test-utils__/CubeNorthwindTestQueries.js +102 -0
  30. package/lib/__test-utils__/CubeNorthwindTestQueries.js.map +1 -0
  31. package/lib/__test-utils__/CubePageTestUtils.d.ts +33 -0
  32. package/lib/__test-utils__/CubePageTestUtils.d.ts.map +1 -0
  33. package/lib/__test-utils__/CubePageTestUtils.js +68 -0
  34. package/lib/__test-utils__/CubePageTestUtils.js.map +1 -0
  35. package/lib/__test-utils__/CubeTestApplication.d.ts +30 -0
  36. package/lib/__test-utils__/CubeTestApplication.d.ts.map +1 -0
  37. package/lib/__test-utils__/CubeTestApplication.js +57 -0
  38. package/lib/__test-utils__/CubeTestApplication.js.map +1 -0
  39. package/lib/__test-utils__/FakeCubeEngine.d.ts +41 -0
  40. package/lib/__test-utils__/FakeCubeEngine.d.ts.map +1 -0
  41. package/lib/__test-utils__/FakeCubeEngine.js +85 -0
  42. package/lib/__test-utils__/FakeCubeEngine.js.map +1 -0
  43. package/lib/components/CubeButton.d.ts +20 -0
  44. package/lib/components/CubeButton.d.ts.map +1 -0
  45. package/lib/components/CubeButton.js +24 -0
  46. package/lib/components/CubeButton.js.map +1 -0
  47. package/lib/components/CubeEditor.d.ts +31 -0
  48. package/lib/components/CubeEditor.d.ts.map +1 -0
  49. package/lib/components/CubeEditor.js +90 -0
  50. package/lib/components/CubeEditor.js.map +1 -0
  51. package/lib/components/CubeNodeIcon.d.ts +23 -0
  52. package/lib/components/CubeNodeIcon.d.ts.map +1 -0
  53. package/lib/components/CubeNodeIcon.js +32 -0
  54. package/lib/components/CubeNodeIcon.js.map +1 -0
  55. package/lib/components/canvas/CubeCanvas.d.ts +37 -0
  56. package/lib/components/canvas/CubeCanvas.d.ts.map +1 -0
  57. package/lib/components/canvas/CubeCanvas.js +135 -0
  58. package/lib/components/canvas/CubeCanvas.js.map +1 -0
  59. package/lib/components/canvas/CubeCanvasContext.d.ts +19 -0
  60. package/lib/components/canvas/CubeCanvasContext.d.ts.map +1 -0
  61. package/lib/components/canvas/CubeCanvasContext.js +22 -0
  62. package/lib/components/canvas/CubeCanvasContext.js.map +1 -0
  63. package/lib/components/canvas/CubeCanvasContextMenu.d.ts +28 -0
  64. package/lib/components/canvas/CubeCanvasContextMenu.d.ts.map +1 -0
  65. package/lib/components/canvas/CubeCanvasContextMenu.js +35 -0
  66. package/lib/components/canvas/CubeCanvasContextMenu.js.map +1 -0
  67. package/lib/components/canvas/CubeCanvasDnd.d.ts +43 -0
  68. package/lib/components/canvas/CubeCanvasDnd.d.ts.map +1 -0
  69. package/lib/components/canvas/CubeCanvasDnd.js +51 -0
  70. package/lib/components/canvas/CubeCanvasDnd.js.map +1 -0
  71. package/lib/components/canvas/CubeCanvasEdge.d.ts +24 -0
  72. package/lib/components/canvas/CubeCanvasEdge.d.ts.map +1 -0
  73. package/lib/components/canvas/CubeCanvasEdge.js +33 -0
  74. package/lib/components/canvas/CubeCanvasEdge.js.map +1 -0
  75. package/lib/components/canvas/CubeCanvasElements.d.ts +64 -0
  76. package/lib/components/canvas/CubeCanvasElements.d.ts.map +1 -0
  77. package/lib/components/canvas/CubeCanvasElements.js +96 -0
  78. package/lib/components/canvas/CubeCanvasElements.js.map +1 -0
  79. package/lib/components/canvas/CubeCanvasLayout.d.ts +32 -0
  80. package/lib/components/canvas/CubeCanvasLayout.d.ts.map +1 -0
  81. package/lib/components/canvas/CubeCanvasLayout.js +63 -0
  82. package/lib/components/canvas/CubeCanvasLayout.js.map +1 -0
  83. package/lib/components/canvas/CubeCanvasNode.d.ts +29 -0
  84. package/lib/components/canvas/CubeCanvasNode.d.ts.map +1 -0
  85. package/lib/components/canvas/CubeCanvasNode.js +72 -0
  86. package/lib/components/canvas/CubeCanvasNode.js.map +1 -0
  87. package/lib/components/editors/CubeColumnPicker.d.ts +40 -0
  88. package/lib/components/editors/CubeColumnPicker.d.ts.map +1 -0
  89. package/lib/components/editors/CubeColumnPicker.js +51 -0
  90. package/lib/components/editors/CubeColumnPicker.js.map +1 -0
  91. package/lib/components/editors/CubeFilterEditor.d.ts +26 -0
  92. package/lib/components/editors/CubeFilterEditor.d.ts.map +1 -0
  93. package/lib/components/editors/CubeFilterEditor.js +90 -0
  94. package/lib/components/editors/CubeFilterEditor.js.map +1 -0
  95. package/lib/components/editors/CubeJoinEditor.d.ts +26 -0
  96. package/lib/components/editors/CubeJoinEditor.d.ts.map +1 -0
  97. package/lib/components/editors/CubeJoinEditor.js +76 -0
  98. package/lib/components/editors/CubeJoinEditor.js.map +1 -0
  99. package/lib/components/editors/CubeNodeEditorPanel.d.ts +29 -0
  100. package/lib/components/editors/CubeNodeEditorPanel.d.ts.map +1 -0
  101. package/lib/components/editors/CubeNodeEditorPanel.js +71 -0
  102. package/lib/components/editors/CubeNodeEditorPanel.js.map +1 -0
  103. package/lib/components/editors/CubeNodeEditorRegistry.d.ts +44 -0
  104. package/lib/components/editors/CubeNodeEditorRegistry.d.ts.map +1 -0
  105. package/lib/components/editors/CubeNodeEditorRegistry.js +30 -0
  106. package/lib/components/editors/CubeNodeEditorRegistry.js.map +1 -0
  107. package/lib/components/editors/CubeSourceEditor.d.ts +25 -0
  108. package/lib/components/editors/CubeSourceEditor.d.ts.map +1 -0
  109. package/lib/components/editors/CubeSourceEditor.js +42 -0
  110. package/lib/components/editors/CubeSourceEditor.js.map +1 -0
  111. package/lib/components/editors/CubeValueEditor.d.ts +40 -0
  112. package/lib/components/editors/CubeValueEditor.d.ts.map +1 -0
  113. package/lib/components/editors/CubeValueEditor.js +177 -0
  114. package/lib/components/editors/CubeValueEditor.js.map +1 -0
  115. package/lib/components/grid/CubeGridRegion.d.ts +23 -0
  116. package/lib/components/grid/CubeGridRegion.d.ts.map +1 -0
  117. package/lib/components/grid/CubeGridRegion.js +94 -0
  118. package/lib/components/grid/CubeGridRegion.js.map +1 -0
  119. package/lib/components/grid/CubeGridValues.d.ts +25 -0
  120. package/lib/components/grid/CubeGridValues.d.ts.map +1 -0
  121. package/lib/components/grid/CubeGridValues.js +95 -0
  122. package/lib/components/grid/CubeGridValues.js.map +1 -0
  123. package/lib/components/grid/CubeResultGrid.d.ts +26 -0
  124. package/lib/components/grid/CubeResultGrid.d.ts.map +1 -0
  125. package/lib/components/grid/CubeResultGrid.js +50 -0
  126. package/lib/components/grid/CubeResultGrid.js.map +1 -0
  127. package/lib/components/palette/CubePalette.d.ts +29 -0
  128. package/lib/components/palette/CubePalette.d.ts.map +1 -0
  129. package/lib/components/palette/CubePalette.js +73 -0
  130. package/lib/components/palette/CubePalette.js.map +1 -0
  131. package/lib/components/show-pure/CubeShowPureDialog.d.ts +23 -0
  132. package/lib/components/show-pure/CubeShowPureDialog.d.ts.map +1 -0
  133. package/lib/components/show-pure/CubeShowPureDialog.js +37 -0
  134. package/lib/components/show-pure/CubeShowPureDialog.js.map +1 -0
  135. package/lib/components/source-picker/CubeSourcePicker.d.ts +22 -0
  136. package/lib/components/source-picker/CubeSourcePicker.d.ts.map +1 -0
  137. package/lib/components/source-picker/CubeSourcePicker.js +89 -0
  138. package/lib/components/source-picker/CubeSourcePicker.js.map +1 -0
  139. package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts +26 -0
  140. package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts.map +1 -0
  141. package/lib/components/spec-transfer/CubeSpecTransferDialog.js +45 -0
  142. package/lib/components/spec-transfer/CubeSpecTransferDialog.js.map +1 -0
  143. package/lib/graph-manager/CubeEngine.d.ts +115 -0
  144. package/lib/graph-manager/CubeEngine.d.ts.map +1 -0
  145. package/lib/graph-manager/CubeEngine.js +61 -0
  146. package/lib/graph-manager/CubeEngine.js.map +1 -0
  147. package/lib/graph-manager/CubeModelOutlineHelper.d.ts +25 -0
  148. package/lib/graph-manager/CubeModelOutlineHelper.d.ts.map +1 -0
  149. package/lib/graph-manager/CubeModelOutlineHelper.js +24 -0
  150. package/lib/graph-manager/CubeModelOutlineHelper.js.map +1 -0
  151. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts +26 -0
  152. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts.map +1 -0
  153. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js +22 -0
  154. package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js.map +1 -0
  155. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts +27 -0
  156. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts.map +1 -0
  157. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js +76 -0
  158. package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js.map +1 -0
  159. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts +27 -0
  160. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts.map +1 -0
  161. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js +82 -0
  162. package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js.map +1 -0
  163. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts +32 -0
  164. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts.map +1 -0
  165. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js +195 -0
  166. package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js.map +1 -0
  167. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts +20 -0
  168. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts.map +1 -0
  169. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js +121 -0
  170. package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js.map +1 -0
  171. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts +24 -0
  172. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts.map +1 -0
  173. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js +43 -0
  174. package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js.map +1 -0
  175. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts +45 -0
  176. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts.map +1 -0
  177. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js +171 -0
  178. package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js.map +1 -0
  179. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts +22 -0
  180. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts.map +1 -0
  181. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js +79 -0
  182. package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js.map +1 -0
  183. package/lib/index.css +17 -0
  184. package/lib/index.css.map +1 -0
  185. package/lib/index.d.ts +25 -0
  186. package/lib/index.d.ts.map +1 -0
  187. package/lib/index.js +24 -0
  188. package/lib/index.js.map +1 -0
  189. package/lib/stores/CubeEditorState.d.ts +206 -0
  190. package/lib/stores/CubeEditorState.d.ts.map +1 -0
  191. package/lib/stores/CubeEditorState.js +551 -0
  192. package/lib/stores/CubeEditorState.js.map +1 -0
  193. package/lib/stores/CubeExecutionState.d.ts +67 -0
  194. package/lib/stores/CubeExecutionState.d.ts.map +1 -0
  195. package/lib/stores/CubeExecutionState.js +196 -0
  196. package/lib/stores/CubeExecutionState.js.map +1 -0
  197. package/lib/stores/CubeHost.d.ts +31 -0
  198. package/lib/stores/CubeHost.d.ts.map +1 -0
  199. package/lib/stores/CubeHost.js +17 -0
  200. package/lib/stores/CubeHost.js.map +1 -0
  201. package/lib/stores/CubeNodeEditorState.d.ts +85 -0
  202. package/lib/stores/CubeNodeEditorState.d.ts.map +1 -0
  203. package/lib/stores/CubeNodeEditorState.js +207 -0
  204. package/lib/stores/CubeNodeEditorState.js.map +1 -0
  205. package/lib/stores/CubeShowPureState.d.ts +38 -0
  206. package/lib/stores/CubeShowPureState.d.ts.map +1 -0
  207. package/lib/stores/CubeShowPureState.js +83 -0
  208. package/lib/stores/CubeShowPureState.js.map +1 -0
  209. package/lib/stores/CubeSourcePickerState.d.ts +98 -0
  210. package/lib/stores/CubeSourcePickerState.d.ts.map +1 -0
  211. package/lib/stores/CubeSourcePickerState.js +334 -0
  212. package/lib/stores/CubeSourcePickerState.js.map +1 -0
  213. package/lib/stores/CubeSpecTransferState.d.ts +60 -0
  214. package/lib/stores/CubeSpecTransferState.d.ts.map +1 -0
  215. package/lib/stores/CubeSpecTransferState.js +167 -0
  216. package/lib/stores/CubeSpecTransferState.js.map +1 -0
  217. package/lib/stores/LocalModelCatalog.d.ts +37 -0
  218. package/lib/stores/LocalModelCatalog.d.ts.map +1 -0
  219. package/lib/stores/LocalModelCatalog.js +49 -0
  220. package/lib/stores/LocalModelCatalog.js.map +1 -0
  221. package/lib/stores/editors/CubeFilterDraft.d.ts +61 -0
  222. package/lib/stores/editors/CubeFilterDraft.d.ts.map +1 -0
  223. package/lib/stores/editors/CubeFilterDraft.js +186 -0
  224. package/lib/stores/editors/CubeFilterDraft.js.map +1 -0
  225. package/lib/stores/editors/CubeJoinDraft.d.ts +63 -0
  226. package/lib/stores/editors/CubeJoinDraft.d.ts.map +1 -0
  227. package/lib/stores/editors/CubeJoinDraft.js +136 -0
  228. package/lib/stores/editors/CubeJoinDraft.js.map +1 -0
  229. package/lib/stores/editors/CubeNodeDraft.d.ts +38 -0
  230. package/lib/stores/editors/CubeNodeDraft.d.ts.map +1 -0
  231. package/lib/stores/editors/CubeNodeDraft.js +35 -0
  232. package/lib/stores/editors/CubeNodeDraft.js.map +1 -0
  233. package/lib/stores/editors/CubeNodeDraftRegistry.d.ts +29 -0
  234. package/lib/stores/editors/CubeNodeDraftRegistry.d.ts.map +1 -0
  235. package/lib/stores/editors/CubeNodeDraftRegistry.js +33 -0
  236. package/lib/stores/editors/CubeNodeDraftRegistry.js.map +1 -0
  237. package/lib/stores/fixtures/CubeNorthwindModel.d.ts +23 -0
  238. package/lib/stores/fixtures/CubeNorthwindModel.d.ts.map +1 -0
  239. package/lib/stores/fixtures/CubeNorthwindModel.js +338 -0
  240. package/lib/stores/fixtures/CubeNorthwindModel.js.map +1 -0
  241. package/package.json +81 -3
  242. package/src/__lib__/LegendCubeCommand.ts +44 -0
  243. package/src/__lib__/LegendCubeHelpText.ts +38 -0
  244. package/src/__lib__/LegendCubeLabels.ts +141 -0
  245. package/src/__lib__/LegendCubeTesting.ts +33 -0
  246. package/src/__test-utils__/CubeCanvasTestUtils.ts +53 -0
  247. package/src/__test-utils__/CubeEngineTestSupport.ts +137 -0
  248. package/src/__test-utils__/CubeNorthwindTestQueries.ts +165 -0
  249. package/src/__test-utils__/CubePageTestUtils.tsx +96 -0
  250. package/src/__test-utils__/CubeTestApplication.ts +82 -0
  251. package/src/__test-utils__/FakeCubeEngine.ts +139 -0
  252. package/src/components/CubeButton.tsx +35 -0
  253. package/src/components/CubeEditor.tsx +239 -0
  254. package/src/components/CubeNodeIcon.tsx +47 -0
  255. package/src/components/canvas/CubeCanvas.tsx +260 -0
  256. package/src/components/canvas/CubeCanvasContext.ts +31 -0
  257. package/src/components/canvas/CubeCanvasContextMenu.tsx +89 -0
  258. package/src/components/canvas/CubeCanvasDnd.ts +82 -0
  259. package/src/components/canvas/CubeCanvasEdge.tsx +57 -0
  260. package/src/components/canvas/CubeCanvasElements.ts +150 -0
  261. package/src/components/canvas/CubeCanvasLayout.ts +88 -0
  262. package/src/components/canvas/CubeCanvasNode.tsx +141 -0
  263. package/src/components/editors/CubeColumnPicker.tsx +114 -0
  264. package/src/components/editors/CubeFilterEditor.tsx +309 -0
  265. package/src/components/editors/CubeJoinEditor.tsx +224 -0
  266. package/src/components/editors/CubeNodeEditorPanel.tsx +204 -0
  267. package/src/components/editors/CubeNodeEditorRegistry.ts +61 -0
  268. package/src/components/editors/CubeSourceEditor.tsx +116 -0
  269. package/src/components/editors/CubeValueEditor.tsx +332 -0
  270. package/src/components/grid/CubeGridRegion.tsx +274 -0
  271. package/src/components/grid/CubeGridValues.ts +125 -0
  272. package/src/components/grid/CubeResultGrid.tsx +84 -0
  273. package/src/components/palette/CubePalette.tsx +177 -0
  274. package/src/components/show-pure/CubeShowPureDialog.tsx +101 -0
  275. package/src/components/source-picker/CubeSourcePicker.tsx +304 -0
  276. package/src/components/spec-transfer/CubeSpecTransferDialog.tsx +157 -0
  277. package/src/graph-manager/CubeEngine.ts +155 -0
  278. package/src/graph-manager/CubeModelOutlineHelper.ts +32 -0
  279. package/src/graph-manager/protocol/pure/CubeEngineBuilder.ts +34 -0
  280. package/src/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.ts +109 -0
  281. package/src/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.ts +115 -0
  282. package/src/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.ts +257 -0
  283. package/src/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.ts +157 -0
  284. package/src/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.ts +58 -0
  285. package/src/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.ts +278 -0
  286. package/src/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.ts +124 -0
  287. package/src/index.ts +41 -0
  288. package/src/stores/CubeEditorState.ts +702 -0
  289. package/src/stores/CubeExecutionState.ts +255 -0
  290. package/src/stores/CubeHost.ts +32 -0
  291. package/src/stores/CubeNodeEditorState.ts +255 -0
  292. package/src/stores/CubeShowPureState.ts +96 -0
  293. package/src/stores/CubeSourcePickerState.ts +426 -0
  294. package/src/stores/CubeSpecTransferState.ts +198 -0
  295. package/src/stores/LocalModelCatalog.ts +70 -0
  296. package/src/stores/editors/CubeFilterDraft.ts +241 -0
  297. package/src/stores/editors/CubeJoinDraft.ts +197 -0
  298. package/src/stores/editors/CubeNodeDraft.ts +46 -0
  299. package/src/stores/editors/CubeNodeDraftRegistry.ts +49 -0
  300. package/src/stores/fixtures/CubeNorthwindModel.ts +355 -0
  301. package/tsconfig.json +118 -0
@@ -0,0 +1,109 @@
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 { NetworkClientError, type PlainObject } from '@finos/legend-shared';
18
+ import {
19
+ CubeEngineError,
20
+ CubeEngineErrorKind,
21
+ type NodeId,
22
+ } from '../../../CubeEngine.js';
23
+ import { V1_parseCubeSourceId } from './V1_CubeLambdaSerializer.js';
24
+
25
+ // Engine errors → `CubeEngineError`s on canvas nodes (PLAN §8.7). A compile
26
+ // error echoes the stamp of the innermost failing protocol node, so it goes on
27
+ // that node; plan-time, database and network errors carry no stamp, so they
28
+ // go on the node being typed or run.
29
+
30
+ const COMPILATION_ERROR_TYPES = new Set(['COMPILATION', 'PARSER']);
31
+
32
+ /** The engine's error payload: `{message, errorType?, sourceInformation?, trace?}` */
33
+ const readPayload = (
34
+ payload: unknown,
35
+ ): { message: string; errorType?: string; sourceId?: string } | undefined => {
36
+ if (!payload || typeof payload !== 'object') {
37
+ return undefined;
38
+ }
39
+ const { message, errorType, sourceInformation } = payload as PlainObject;
40
+ if (typeof message !== 'string' || !message.trim()) {
41
+ return undefined;
42
+ }
43
+ const sourceId =
44
+ sourceInformation && typeof sourceInformation === 'object'
45
+ ? (sourceInformation as PlainObject).sourceId
46
+ : undefined;
47
+ return {
48
+ message,
49
+ ...(typeof errorType === 'string' ? { errorType } : {}),
50
+ ...(typeof sourceId === 'string' ? { sourceId } : {}),
51
+ };
52
+ };
53
+
54
+ /**
55
+ * The error of an engine payload (a failed call's, or a batch key's), placed
56
+ * on the stamped node, or else on the fallback node. Its Java trace is dropped.
57
+ */
58
+ export const V1_buildCubeEngineError = (
59
+ payload: unknown,
60
+ fallbackNodeId: NodeId | undefined,
61
+ kind: CubeEngineErrorKind,
62
+ ): CubeEngineError | undefined => {
63
+ const read = readPayload(payload);
64
+ if (!read) {
65
+ return undefined;
66
+ }
67
+ const origin = V1_parseCubeSourceId(read.sourceId);
68
+ return new CubeEngineError(
69
+ read.errorType && COMPILATION_ERROR_TYPES.has(read.errorType)
70
+ ? CubeEngineErrorKind.COMPILE
71
+ : kind,
72
+ read.message,
73
+ origin?.nodeId ?? fallbackNodeId,
74
+ origin?.role,
75
+ );
76
+ };
77
+
78
+ /**
79
+ * The error of a failed engine call: the engine's own message when it sent
80
+ * one, else a network error
81
+ */
82
+ export const V1_toCubeEngineError = (
83
+ error: unknown,
84
+ fallbackNodeId: NodeId | undefined,
85
+ kind: CubeEngineErrorKind,
86
+ ): CubeEngineError => {
87
+ if (error instanceof CubeEngineError) {
88
+ return error.nodeId !== undefined || fallbackNodeId === undefined
89
+ ? error
90
+ : new CubeEngineError(error.kind, error.detail, fallbackNodeId);
91
+ }
92
+ if (error instanceof NetworkClientError) {
93
+ const fromPayload = V1_buildCubeEngineError(
94
+ error.payload,
95
+ fallbackNodeId,
96
+ kind,
97
+ );
98
+ if (fromPayload) {
99
+ return fromPayload;
100
+ }
101
+ }
102
+ return new CubeEngineError(
103
+ CubeEngineErrorKind.NETWORK,
104
+ error instanceof Error && error.message
105
+ ? error.message
106
+ : `The engine couldn't be reached`,
107
+ fallbackNodeId,
108
+ );
109
+ };
@@ -0,0 +1,115 @@
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 { resolveCubeType, TypeFamily } from '@finos/legend-cube';
18
+ import { parseLosslessJSON, type PlainObject } from '@finos/legend-shared';
19
+ import type { CubeResultValue } from '../../../CubeEngine.js';
20
+
21
+ // An execution response (DEFAULT format, relation result) read losslessly
22
+ // (PLAN §8.7). Each column's values keep one JS type, decided by the type the
23
+ // result builder gives it: Float values are numbers; any other number, an
24
+ // Integer or Decimal value above all, is its exact text ("9007199254740993",
25
+ // "12.30"). Nothing is inferred from the kind of JSON token, since a Float
26
+ // column may hold 5124 and a String column 32.38.
27
+
28
+ const RELATIONAL_ACTIVITY_TYPE = 'relational';
29
+
30
+ export interface V1_CubeExecutionResult {
31
+ readonly columns: readonly string[];
32
+ readonly rows: readonly (readonly CubeResultValue[])[];
33
+ readonly sql: readonly string[];
34
+ }
35
+
36
+ /** Thrown when the body can't be read, e.g. a stack trace streamed into a 200 */
37
+ export class V1_CubeUnreadableResultError extends Error {}
38
+
39
+ const isLosslessNumber = (
40
+ value: unknown,
41
+ ): value is { isLosslessNumber: true; value: string } =>
42
+ typeof value === 'object' &&
43
+ value !== null &&
44
+ (value as { isLosslessNumber?: unknown }).isLosslessNumber === true;
45
+
46
+ const asObject = (value: unknown): PlainObject =>
47
+ value && typeof value === 'object' && !Array.isArray(value)
48
+ ? (value as PlainObject)
49
+ : {};
50
+
51
+ const readCell = (value: unknown, asNumber: boolean): CubeResultValue => {
52
+ if (isLosslessNumber(value)) {
53
+ return asNumber ? Number(value.value) : value.value;
54
+ }
55
+ if (
56
+ value === null ||
57
+ typeof value === 'string' ||
58
+ typeof value === 'boolean'
59
+ ) {
60
+ return value;
61
+ }
62
+ throw new V1_CubeUnreadableResultError(
63
+ `A result value is not a scalar: ${JSON.stringify(value)}`,
64
+ );
65
+ };
66
+
67
+ /** The columns, rows and SQL of an execution response's text */
68
+ export const V1_readCubeExecutionResult = (
69
+ text: string,
70
+ ): V1_CubeExecutionResult => {
71
+ let json: PlainObject;
72
+ try {
73
+ json = asObject(parseLosslessJSON(text));
74
+ } catch (error) {
75
+ throw new V1_CubeUnreadableResultError(
76
+ `The engine's response can't be read: ${(error as Error).message}`,
77
+ );
78
+ }
79
+ const result = asObject(json.result);
80
+ if (!Array.isArray(result.columns) || !Array.isArray(result.rows)) {
81
+ throw new V1_CubeUnreadableResultError(
82
+ `The engine's response has no relation result`,
83
+ );
84
+ }
85
+ const columns = result.columns.map((name) => String(name));
86
+ const builderTypes = new Map(
87
+ (Array.isArray(asObject(json.builder).columns)
88
+ ? (asObject(json.builder).columns as unknown[])
89
+ : []
90
+ ).map((column) => [
91
+ String(asObject(column).name),
92
+ String(asObject(column).type ?? ''),
93
+ ]),
94
+ );
95
+ const asNumber = columns.map((name) => {
96
+ const type = builderTypes.get(name);
97
+ return type ? resolveCubeType(type).family === TypeFamily.FLOAT : false;
98
+ });
99
+ const rows = result.rows.map((row) => {
100
+ const values = asObject(row).values;
101
+ if (!Array.isArray(values) || values.length !== columns.length) {
102
+ throw new V1_CubeUnreadableResultError(
103
+ `A result row doesn't have one value per column`,
104
+ );
105
+ }
106
+ return values.map((value, index) =>
107
+ readCell(value, asNumber[index] ?? false),
108
+ );
109
+ });
110
+ const sql = (Array.isArray(json.activities) ? json.activities : [])
111
+ .map(asObject)
112
+ .filter((activity) => activity._type === RELATIONAL_ACTIVITY_TYPE)
113
+ .map((activity) => String(activity.sql));
114
+ return { columns, rows, sql };
115
+ };
@@ -0,0 +1,257 @@
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 { IR, LiteralValue, Origin } from '@finos/legend-cube';
18
+ import { parseLosslessJSON, type PlainObject } from '@finos/legend-shared';
19
+
20
+ // Cube IR → V1 protocol lambda JSON (PLAN §8.3, §8.5), built as plain JSON,
21
+ // never through legend-graph's value-specification classes, whose serializer
22
+ // drops `sourceInformation`. Numbers are lossless number values, so the
23
+ // request body must be written with `stringifyLosslessJSON`.
24
+
25
+ /** The prefix of the source ids Cube stamps, `cube:<nodeId>:<role>` */
26
+ export const V1_CUBE_SOURCE_ID_PREFIX = 'cube:';
27
+
28
+ /** A JSON number token: what an integer, float or decimal literal must be */
29
+ const NUMBER_TOKEN = /^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$/u;
30
+
31
+ /** The source id of an origin */
32
+ export const V1_buildCubeSourceId = (origin: Origin): string =>
33
+ `${V1_CUBE_SOURCE_ID_PREFIX}${origin.nodeId}:${origin.role}`;
34
+
35
+ /**
36
+ * The origin a source id names, or none when Cube didn't stamp it. A role
37
+ * never contains `:`, so a node id that does still reads back whole.
38
+ */
39
+ export const V1_parseCubeSourceId = (
40
+ sourceId: string | undefined,
41
+ ): Origin | undefined => {
42
+ if (!sourceId?.startsWith(V1_CUBE_SOURCE_ID_PREFIX)) {
43
+ return undefined;
44
+ }
45
+ const rest = sourceId.slice(V1_CUBE_SOURCE_ID_PREFIX.length);
46
+ const at = rest.lastIndexOf(':');
47
+ if (at <= 0 || at === rest.length - 1) {
48
+ return undefined;
49
+ }
50
+ return { nodeId: rest.slice(0, at), role: rest.slice(at + 1) };
51
+ };
52
+
53
+ const stamped = (json: PlainObject, origin: Origin | undefined): PlainObject =>
54
+ origin
55
+ ? {
56
+ ...json,
57
+ sourceInformation: { sourceId: V1_buildCubeSourceId(origin) },
58
+ }
59
+ : json;
60
+
61
+ /** A lossless JSON number for a numeric literal's text, written digit for digit */
62
+ const numberToken = (text: string): unknown => {
63
+ if (!NUMBER_TOKEN.test(text)) {
64
+ throw new Error(`"${text}" is not a number Cube can send`);
65
+ }
66
+ return parseLosslessJSON(text);
67
+ };
68
+
69
+ const serializeLiteral = (value: LiteralValue): PlainObject => {
70
+ switch (value.kind) {
71
+ case 'string':
72
+ case 'boolean':
73
+ case 'strictDate':
74
+ case 'dateTime':
75
+ return { _type: value.kind, value: value.value };
76
+ case 'integer':
77
+ case 'float':
78
+ case 'decimal':
79
+ return { _type: value.kind, value: numberToken(value.value) };
80
+ case 'enum':
81
+ // enumeration values are emitted as `enumValue`, with their enumeration
82
+ throw new Error(
83
+ `Can't send the enumeration value "${value.value}" as a literal`,
84
+ );
85
+ default: {
86
+ const unknown: never = value;
87
+ throw new Error(`Unknown literal ${JSON.stringify(unknown)}`);
88
+ }
89
+ }
90
+ };
91
+
92
+ /**
93
+ * The protocol JSON of an IR node. Every protocol node is stamped with the
94
+ * origin of its IR node, or else of its nearest ancestor that has one.
95
+ */
96
+ const serialize = (ir: IR, inherited: Origin | undefined): PlainObject => {
97
+ switch (ir.k) {
98
+ case 'func': {
99
+ const origin = ir.origin ?? inherited;
100
+ return stamped(
101
+ {
102
+ _type: 'func',
103
+ function: ir.name,
104
+ parameters: ir.params.map((param) => serialize(param, origin)),
105
+ },
106
+ origin,
107
+ );
108
+ }
109
+ case 'property': {
110
+ const origin = ir.origin ?? inherited;
111
+ return stamped(
112
+ {
113
+ _type: 'property',
114
+ property: ir.name,
115
+ parameters: [serialize(ir.receiver, origin)],
116
+ },
117
+ origin,
118
+ );
119
+ }
120
+ case 'var':
121
+ return stamped({ _type: 'var', name: ir.name }, inherited);
122
+ case 'lambda':
123
+ return stamped(
124
+ {
125
+ _type: 'lambda',
126
+ parameters: ir.params.map((name) =>
127
+ stamped({ _type: 'var', name }, inherited),
128
+ ),
129
+ body: ir.body.map((statement) => serialize(statement, inherited)),
130
+ },
131
+ inherited,
132
+ );
133
+ case 'literal':
134
+ return stamped(serializeLiteral(ir.value), ir.origin ?? inherited);
135
+ case 'collection':
136
+ return stamped(
137
+ {
138
+ _type: 'collection',
139
+ multiplicity: {
140
+ lowerBound: ir.values.length,
141
+ upperBound: ir.values.length,
142
+ },
143
+ values: ir.values.map((value) => serialize(value, inherited)),
144
+ },
145
+ inherited,
146
+ );
147
+ case 'colSpec':
148
+ // the engine reports a missing column on the spec's value, which is
149
+ // also what a column list holds, so the value is stamped too
150
+ return stamped(
151
+ {
152
+ _type: 'classInstance',
153
+ type: 'colSpec',
154
+ value: stamped(
155
+ {
156
+ name: ir.name,
157
+ ...(ir.fn1 ? { function1: serialize(ir.fn1, inherited) } : {}),
158
+ ...(ir.fn2 ? { function2: serialize(ir.fn2, inherited) } : {}),
159
+ },
160
+ inherited,
161
+ ),
162
+ },
163
+ inherited,
164
+ );
165
+ case 'colSpecArray':
166
+ return stamped(
167
+ {
168
+ _type: 'classInstance',
169
+ type: 'colSpecArray',
170
+ value: {
171
+ colSpecs: ir.specs.map((spec) => {
172
+ if (spec.k !== 'colSpec') {
173
+ throw new Error(
174
+ `A column list holds only column specs, not "${spec.k}"`,
175
+ );
176
+ }
177
+ return (serialize(spec, inherited) as { value: PlainObject })
178
+ .value;
179
+ }),
180
+ },
181
+ },
182
+ inherited,
183
+ );
184
+ case 'storeAccessor': {
185
+ const origin = ir.origin ?? inherited;
186
+ // the engine reports a wrong database, schema or table on the value
187
+ return stamped(
188
+ {
189
+ _type: 'classInstance',
190
+ type: '>',
191
+ value: stamped({ path: [...ir.path] }, origin),
192
+ },
193
+ origin,
194
+ );
195
+ }
196
+ case 'elementPtr':
197
+ return stamped(
198
+ { _type: 'packageableElementPtr', fullPath: ir.path },
199
+ inherited,
200
+ );
201
+ case 'genericType':
202
+ return stamped(
203
+ {
204
+ _type: 'genericTypeInstance',
205
+ genericType: {
206
+ rawType: { _type: 'packageableType', fullPath: ir.path },
207
+ typeArguments: [],
208
+ multiplicityArguments: [],
209
+ typeVariableValues: (ir.params ?? []).map((param) =>
210
+ stamped(
211
+ { _type: 'integer', value: numberToken(String(param)) },
212
+ inherited,
213
+ ),
214
+ ),
215
+ },
216
+ },
217
+ inherited,
218
+ );
219
+ case 'enumValue': {
220
+ const origin = ir.origin ?? inherited;
221
+ return stamped(
222
+ {
223
+ _type: 'property',
224
+ property: ir.value,
225
+ parameters: [
226
+ stamped(
227
+ { _type: 'packageableElementPtr', fullPath: ir.enumPath },
228
+ origin,
229
+ ),
230
+ ],
231
+ },
232
+ origin,
233
+ );
234
+ }
235
+ case 'let':
236
+ case 'block':
237
+ // window isolation (PLAN §8.6) comes with Partition, in M5
238
+ throw new Error(`Can't send "${ir.k}" yet`);
239
+ case 'raw':
240
+ return ir.json as PlainObject;
241
+ default: {
242
+ const unknown: never = ir;
243
+ throw new Error(`Unknown IR ${JSON.stringify(unknown)}`);
244
+ }
245
+ }
246
+ };
247
+
248
+ /**
249
+ * The protocol JSON of a lambda Cube emitted (a typing or an execution
250
+ * lambda), with lossless numbers: write it with `stringifyLosslessJSON`.
251
+ */
252
+ export const V1_serializeCubeLambda = (ir: IR): PlainObject => {
253
+ if (ir.k !== 'lambda') {
254
+ throw new Error(`Only a lambda can be sent, not "${ir.k}"`);
255
+ }
256
+ return serialize(ir, undefined);
257
+ };
@@ -0,0 +1,157 @@
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 { getRelationalDisplayName } from '@finos/legend-cube';
18
+ import type { PlainObject } from '@finos/legend-shared';
19
+ import {
20
+ CubeTableFlag,
21
+ type CubeModelOutline,
22
+ type CubeOutlineDatabase,
23
+ type CubeOutlineRuntime,
24
+ type CubeOutlineSchema,
25
+ type CubeOutlineTable,
26
+ } from '../../../CubeEngine.js';
27
+
28
+ // The databases and runtimes of a parsed model (`{_type: 'data', elements}`),
29
+ // for the source picker (PLAN §6.2.3-§6.2.6). Read as plain JSON: only names,
30
+ // column types and store paths are needed, and an element's full protocol
31
+ // deserializer needs the graph manager's plugins.
32
+
33
+ const DATABASE_TYPE = 'relational';
34
+ const RUNTIME_TYPE = 'runtime';
35
+ /** The only runtime value whose store keys Cube can read; others are hidden */
36
+ const ENGINE_RUNTIME_TYPE = 'engineRuntime';
37
+
38
+ /** The flag a column type gives its table, if any (PLAN §6.2.6) */
39
+ const COLUMN_TYPE_FLAGS: Record<string, CubeTableFlag> = {
40
+ // the engine fails to type the whole table
41
+ Binary: CubeTableFlag.UNAVAILABLE,
42
+ Varbinary: CubeTableFlag.UNAVAILABLE,
43
+ // typed with a length of 1
44
+ Char: CubeTableFlag.LENGTH_UNKNOWN,
45
+ // an ARRAY column is parsed as Other; both are typed as a bare String
46
+ Other: CubeTableFlag.TYPE_UNKNOWN,
47
+ };
48
+
49
+ const asObject = (value: unknown): PlainObject =>
50
+ value && typeof value === 'object' && !Array.isArray(value)
51
+ ? (value as PlainObject)
52
+ : {};
53
+
54
+ const asList = (value: unknown): unknown[] =>
55
+ Array.isArray(value) ? value : [];
56
+
57
+ const asString = (value: unknown): string | undefined =>
58
+ typeof value === 'string' ? value : undefined;
59
+
60
+ const elementPath = (element: PlainObject): string => {
61
+ const name = asString(element.name) ?? '';
62
+ const pkg = asString(element.package);
63
+ return pkg ? `${pkg}::${name}` : name;
64
+ };
65
+
66
+ const buildTable = (json: unknown): CubeOutlineTable => {
67
+ const table = asObject(json);
68
+ const columns = asList(table.columns).map(asObject);
69
+ const flags = new Set<CubeTableFlag>();
70
+ const untypedColumns: string[] = [];
71
+ columns.forEach((column) => {
72
+ const flag = COLUMN_TYPE_FLAGS[asString(asObject(column.type)._type) ?? ''];
73
+ if (flag) {
74
+ flags.add(flag);
75
+ }
76
+ if (flag === CubeTableFlag.TYPE_UNKNOWN) {
77
+ // unquoted, as the engine names the column in the table's schema
78
+ untypedColumns.push(
79
+ getRelationalDisplayName(asString(column.name) ?? ''),
80
+ );
81
+ }
82
+ });
83
+ return {
84
+ name: asString(table.name) ?? '',
85
+ isView: false,
86
+ columnCount: columns.length,
87
+ flags: Object.values(CubeTableFlag).filter((flag) => flags.has(flag)),
88
+ untypedColumns,
89
+ };
90
+ };
91
+
92
+ const buildView = (json: unknown): CubeOutlineTable => {
93
+ const view = asObject(json);
94
+ return {
95
+ name: asString(view.name) ?? '',
96
+ isView: true,
97
+ columnCount: asList(view.columnMappings).length,
98
+ flags: [],
99
+ untypedColumns: [],
100
+ };
101
+ };
102
+
103
+ const buildSchema = (json: unknown): CubeOutlineSchema => {
104
+ const schema = asObject(json);
105
+ return {
106
+ name: asString(schema.name) ?? '',
107
+ tables: [
108
+ ...asList(schema.tables).map(buildTable),
109
+ ...asList(schema.views).map(buildView),
110
+ ],
111
+ };
112
+ };
113
+
114
+ const buildDatabase = (element: PlainObject): CubeOutlineDatabase => ({
115
+ path: elementPath(element),
116
+ // included stores are not followed (v1)
117
+ schemas: asList(element.schemas).map(buildSchema),
118
+ });
119
+
120
+ /** The stores a runtime's connections are keyed by, in both syntaxes; none when it can't be read */
121
+ const buildRuntime = (element: PlainObject): CubeOutlineRuntime | undefined => {
122
+ const value = asObject(element.runtimeValue);
123
+ if (value._type !== ENGINE_RUNTIME_TYPE) {
124
+ return undefined;
125
+ }
126
+ const storePaths = [
127
+ // `connections: [<store>: [...]]`
128
+ ...asList(value.connections).map((connection) =>
129
+ asString(asObject(asObject(connection).store).path),
130
+ ),
131
+ // `connectionStores: [<connection>: [<store>, ...]]`
132
+ ...asList(value.connectionStores).flatMap((connectionStore) =>
133
+ asList(asObject(connectionStore).storePointers).map((pointer) =>
134
+ asString(asObject(pointer).path),
135
+ ),
136
+ ),
137
+ ].filter((path): path is string => path !== undefined);
138
+ return { path: elementPath(element), storePaths: [...new Set(storePaths)] };
139
+ };
140
+
141
+ /** The outline of a parsed model: its Database elements and its readable runtimes, in model order */
142
+ export const V1_buildCubeModelOutline = (
143
+ modelData: PlainObject,
144
+ ): CubeModelOutline => {
145
+ const elements = asList(modelData.elements).map(asObject);
146
+ return {
147
+ databases: elements
148
+ .filter((element) => element._type === DATABASE_TYPE)
149
+ .map(buildDatabase),
150
+ runtimes: elements
151
+ .filter((element) => element._type === RUNTIME_TYPE)
152
+ .map(buildRuntime)
153
+ .filter(
154
+ (runtime): runtime is CubeOutlineRuntime => runtime !== undefined,
155
+ ),
156
+ };
157
+ };
@@ -0,0 +1,58 @@
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 { resolveCubeType, Schema, SchemaColumn } from '@finos/legend-cube';
18
+ import {
19
+ V1_CInteger,
20
+ V1_PackageableType,
21
+ V1_relationTypeModelSchema,
22
+ } from '@finos/legend-graph';
23
+ import type { PlainObject } from '@finos/legend-shared';
24
+ import { deserialize } from 'serializr';
25
+
26
+ // The engine's relation type → a Cube schema (PLAN §6.2.6), read through
27
+ // legend-graph's protocol schema. Its graph-manager wrappers are bypassed:
28
+ // they drop type parameters (D8).
29
+
30
+ /**
31
+ * The schema of a relation type: one column per relation column, in order,
32
+ * typed by its path and parameters (an unknown type is opaque) and nullable
33
+ * when it may be empty
34
+ */
35
+ export const V1_buildCubeSchema = (json: PlainObject): Schema => {
36
+ const relationType = deserialize(V1_relationTypeModelSchema, json);
37
+ return new Schema(
38
+ relationType.columns.map((column) => {
39
+ const { rawType, typeVariableValues } = column.genericType;
40
+ if (!(rawType instanceof V1_PackageableType)) {
41
+ throw new Error(`Column "${column.name}" has a type Cube can't read`);
42
+ }
43
+ const params = typeVariableValues.map((value) => {
44
+ if (!(value instanceof V1_CInteger)) {
45
+ throw new Error(
46
+ `Column "${column.name}" has a type parameter Cube can't read`,
47
+ );
48
+ }
49
+ return value.value;
50
+ });
51
+ return new SchemaColumn(
52
+ column.name,
53
+ resolveCubeType(rawType.fullPath, params),
54
+ column.multiplicity.lowerBound === 0,
55
+ );
56
+ }),
57
+ );
58
+ };