@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.
- package/LICENSE +201 -0
- package/README.md +5 -2
- package/lib/__lib__/LegendCubeCommand.d.ts +26 -0
- package/lib/__lib__/LegendCubeCommand.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeCommand.js +40 -0
- package/lib/__lib__/LegendCubeCommand.js.map +1 -0
- package/lib/__lib__/LegendCubeHelpText.d.ts +19 -0
- package/lib/__lib__/LegendCubeHelpText.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeHelpText.js +27 -0
- package/lib/__lib__/LegendCubeHelpText.js.map +1 -0
- package/lib/__lib__/LegendCubeLabels.d.ts +68 -0
- package/lib/__lib__/LegendCubeLabels.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeLabels.js +109 -0
- package/lib/__lib__/LegendCubeLabels.js.map +1 -0
- package/lib/__lib__/LegendCubeTesting.d.ts +33 -0
- package/lib/__lib__/LegendCubeTesting.d.ts.map +1 -0
- package/lib/__lib__/LegendCubeTesting.js +34 -0
- package/lib/__lib__/LegendCubeTesting.js.map +1 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.d.ts +24 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.d.ts.map +1 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.js +37 -0
- package/lib/__test-utils__/CubeCanvasTestUtils.js.map +1 -0
- package/lib/__test-utils__/CubeEngineTestSupport.d.ts +41 -0
- package/lib/__test-utils__/CubeEngineTestSupport.d.ts.map +1 -0
- package/lib/__test-utils__/CubeEngineTestSupport.js +76 -0
- package/lib/__test-utils__/CubeEngineTestSupport.js.map +1 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts +31 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.d.ts.map +1 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.js +102 -0
- package/lib/__test-utils__/CubeNorthwindTestQueries.js.map +1 -0
- package/lib/__test-utils__/CubePageTestUtils.d.ts +33 -0
- package/lib/__test-utils__/CubePageTestUtils.d.ts.map +1 -0
- package/lib/__test-utils__/CubePageTestUtils.js +68 -0
- package/lib/__test-utils__/CubePageTestUtils.js.map +1 -0
- package/lib/__test-utils__/CubeTestApplication.d.ts +30 -0
- package/lib/__test-utils__/CubeTestApplication.d.ts.map +1 -0
- package/lib/__test-utils__/CubeTestApplication.js +57 -0
- package/lib/__test-utils__/CubeTestApplication.js.map +1 -0
- package/lib/__test-utils__/FakeCubeEngine.d.ts +41 -0
- package/lib/__test-utils__/FakeCubeEngine.d.ts.map +1 -0
- package/lib/__test-utils__/FakeCubeEngine.js +85 -0
- package/lib/__test-utils__/FakeCubeEngine.js.map +1 -0
- package/lib/components/CubeButton.d.ts +20 -0
- package/lib/components/CubeButton.d.ts.map +1 -0
- package/lib/components/CubeButton.js +24 -0
- package/lib/components/CubeButton.js.map +1 -0
- package/lib/components/CubeEditor.d.ts +31 -0
- package/lib/components/CubeEditor.d.ts.map +1 -0
- package/lib/components/CubeEditor.js +90 -0
- package/lib/components/CubeEditor.js.map +1 -0
- package/lib/components/CubeNodeIcon.d.ts +23 -0
- package/lib/components/CubeNodeIcon.d.ts.map +1 -0
- package/lib/components/CubeNodeIcon.js +32 -0
- package/lib/components/CubeNodeIcon.js.map +1 -0
- package/lib/components/canvas/CubeCanvas.d.ts +37 -0
- package/lib/components/canvas/CubeCanvas.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvas.js +135 -0
- package/lib/components/canvas/CubeCanvas.js.map +1 -0
- package/lib/components/canvas/CubeCanvasContext.d.ts +19 -0
- package/lib/components/canvas/CubeCanvasContext.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasContext.js +22 -0
- package/lib/components/canvas/CubeCanvasContext.js.map +1 -0
- package/lib/components/canvas/CubeCanvasContextMenu.d.ts +28 -0
- package/lib/components/canvas/CubeCanvasContextMenu.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasContextMenu.js +35 -0
- package/lib/components/canvas/CubeCanvasContextMenu.js.map +1 -0
- package/lib/components/canvas/CubeCanvasDnd.d.ts +43 -0
- package/lib/components/canvas/CubeCanvasDnd.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasDnd.js +51 -0
- package/lib/components/canvas/CubeCanvasDnd.js.map +1 -0
- package/lib/components/canvas/CubeCanvasEdge.d.ts +24 -0
- package/lib/components/canvas/CubeCanvasEdge.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasEdge.js +33 -0
- package/lib/components/canvas/CubeCanvasEdge.js.map +1 -0
- package/lib/components/canvas/CubeCanvasElements.d.ts +64 -0
- package/lib/components/canvas/CubeCanvasElements.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasElements.js +96 -0
- package/lib/components/canvas/CubeCanvasElements.js.map +1 -0
- package/lib/components/canvas/CubeCanvasLayout.d.ts +32 -0
- package/lib/components/canvas/CubeCanvasLayout.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasLayout.js +63 -0
- package/lib/components/canvas/CubeCanvasLayout.js.map +1 -0
- package/lib/components/canvas/CubeCanvasNode.d.ts +29 -0
- package/lib/components/canvas/CubeCanvasNode.d.ts.map +1 -0
- package/lib/components/canvas/CubeCanvasNode.js +72 -0
- package/lib/components/canvas/CubeCanvasNode.js.map +1 -0
- package/lib/components/editors/CubeColumnPicker.d.ts +40 -0
- package/lib/components/editors/CubeColumnPicker.d.ts.map +1 -0
- package/lib/components/editors/CubeColumnPicker.js +51 -0
- package/lib/components/editors/CubeColumnPicker.js.map +1 -0
- package/lib/components/editors/CubeFilterEditor.d.ts +26 -0
- package/lib/components/editors/CubeFilterEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeFilterEditor.js +90 -0
- package/lib/components/editors/CubeFilterEditor.js.map +1 -0
- package/lib/components/editors/CubeJoinEditor.d.ts +26 -0
- package/lib/components/editors/CubeJoinEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeJoinEditor.js +76 -0
- package/lib/components/editors/CubeJoinEditor.js.map +1 -0
- package/lib/components/editors/CubeNodeEditorPanel.d.ts +29 -0
- package/lib/components/editors/CubeNodeEditorPanel.d.ts.map +1 -0
- package/lib/components/editors/CubeNodeEditorPanel.js +71 -0
- package/lib/components/editors/CubeNodeEditorPanel.js.map +1 -0
- package/lib/components/editors/CubeNodeEditorRegistry.d.ts +44 -0
- package/lib/components/editors/CubeNodeEditorRegistry.d.ts.map +1 -0
- package/lib/components/editors/CubeNodeEditorRegistry.js +30 -0
- package/lib/components/editors/CubeNodeEditorRegistry.js.map +1 -0
- package/lib/components/editors/CubeSourceEditor.d.ts +25 -0
- package/lib/components/editors/CubeSourceEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeSourceEditor.js +42 -0
- package/lib/components/editors/CubeSourceEditor.js.map +1 -0
- package/lib/components/editors/CubeValueEditor.d.ts +40 -0
- package/lib/components/editors/CubeValueEditor.d.ts.map +1 -0
- package/lib/components/editors/CubeValueEditor.js +177 -0
- package/lib/components/editors/CubeValueEditor.js.map +1 -0
- package/lib/components/grid/CubeGridRegion.d.ts +23 -0
- package/lib/components/grid/CubeGridRegion.d.ts.map +1 -0
- package/lib/components/grid/CubeGridRegion.js +94 -0
- package/lib/components/grid/CubeGridRegion.js.map +1 -0
- package/lib/components/grid/CubeGridValues.d.ts +25 -0
- package/lib/components/grid/CubeGridValues.d.ts.map +1 -0
- package/lib/components/grid/CubeGridValues.js +95 -0
- package/lib/components/grid/CubeGridValues.js.map +1 -0
- package/lib/components/grid/CubeResultGrid.d.ts +26 -0
- package/lib/components/grid/CubeResultGrid.d.ts.map +1 -0
- package/lib/components/grid/CubeResultGrid.js +50 -0
- package/lib/components/grid/CubeResultGrid.js.map +1 -0
- package/lib/components/palette/CubePalette.d.ts +29 -0
- package/lib/components/palette/CubePalette.d.ts.map +1 -0
- package/lib/components/palette/CubePalette.js +73 -0
- package/lib/components/palette/CubePalette.js.map +1 -0
- package/lib/components/show-pure/CubeShowPureDialog.d.ts +23 -0
- package/lib/components/show-pure/CubeShowPureDialog.d.ts.map +1 -0
- package/lib/components/show-pure/CubeShowPureDialog.js +37 -0
- package/lib/components/show-pure/CubeShowPureDialog.js.map +1 -0
- package/lib/components/source-picker/CubeSourcePicker.d.ts +22 -0
- package/lib/components/source-picker/CubeSourcePicker.d.ts.map +1 -0
- package/lib/components/source-picker/CubeSourcePicker.js +89 -0
- package/lib/components/source-picker/CubeSourcePicker.js.map +1 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts +26 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.d.ts.map +1 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.js +45 -0
- package/lib/components/spec-transfer/CubeSpecTransferDialog.js.map +1 -0
- package/lib/graph-manager/CubeEngine.d.ts +115 -0
- package/lib/graph-manager/CubeEngine.d.ts.map +1 -0
- package/lib/graph-manager/CubeEngine.js +61 -0
- package/lib/graph-manager/CubeEngine.js.map +1 -0
- package/lib/graph-manager/CubeModelOutlineHelper.d.ts +25 -0
- package/lib/graph-manager/CubeModelOutlineHelper.d.ts.map +1 -0
- package/lib/graph-manager/CubeModelOutlineHelper.js +24 -0
- package/lib/graph-manager/CubeModelOutlineHelper.js.map +1 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts +26 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js +22 -0
- package/lib/graph-manager/protocol/pure/CubeEngineBuilder.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts +27 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js +76 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts +27 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js +82 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts +32 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js +195 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts +20 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js +121 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts +24 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js +43 -0
- package/lib/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts +45 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js +171 -0
- package/lib/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.js.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts +22 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.d.ts.map +1 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js +79 -0
- package/lib/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.js.map +1 -0
- package/lib/index.css +17 -0
- package/lib/index.css.map +1 -0
- package/lib/index.d.ts +25 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +24 -0
- package/lib/index.js.map +1 -0
- package/lib/stores/CubeEditorState.d.ts +206 -0
- package/lib/stores/CubeEditorState.d.ts.map +1 -0
- package/lib/stores/CubeEditorState.js +551 -0
- package/lib/stores/CubeEditorState.js.map +1 -0
- package/lib/stores/CubeExecutionState.d.ts +67 -0
- package/lib/stores/CubeExecutionState.d.ts.map +1 -0
- package/lib/stores/CubeExecutionState.js +196 -0
- package/lib/stores/CubeExecutionState.js.map +1 -0
- package/lib/stores/CubeHost.d.ts +31 -0
- package/lib/stores/CubeHost.d.ts.map +1 -0
- package/lib/stores/CubeHost.js +17 -0
- package/lib/stores/CubeHost.js.map +1 -0
- package/lib/stores/CubeNodeEditorState.d.ts +85 -0
- package/lib/stores/CubeNodeEditorState.d.ts.map +1 -0
- package/lib/stores/CubeNodeEditorState.js +207 -0
- package/lib/stores/CubeNodeEditorState.js.map +1 -0
- package/lib/stores/CubeShowPureState.d.ts +38 -0
- package/lib/stores/CubeShowPureState.d.ts.map +1 -0
- package/lib/stores/CubeShowPureState.js +83 -0
- package/lib/stores/CubeShowPureState.js.map +1 -0
- package/lib/stores/CubeSourcePickerState.d.ts +98 -0
- package/lib/stores/CubeSourcePickerState.d.ts.map +1 -0
- package/lib/stores/CubeSourcePickerState.js +334 -0
- package/lib/stores/CubeSourcePickerState.js.map +1 -0
- package/lib/stores/CubeSpecTransferState.d.ts +60 -0
- package/lib/stores/CubeSpecTransferState.d.ts.map +1 -0
- package/lib/stores/CubeSpecTransferState.js +167 -0
- package/lib/stores/CubeSpecTransferState.js.map +1 -0
- package/lib/stores/LocalModelCatalog.d.ts +37 -0
- package/lib/stores/LocalModelCatalog.d.ts.map +1 -0
- package/lib/stores/LocalModelCatalog.js +49 -0
- package/lib/stores/LocalModelCatalog.js.map +1 -0
- package/lib/stores/editors/CubeFilterDraft.d.ts +61 -0
- package/lib/stores/editors/CubeFilterDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeFilterDraft.js +186 -0
- package/lib/stores/editors/CubeFilterDraft.js.map +1 -0
- package/lib/stores/editors/CubeJoinDraft.d.ts +63 -0
- package/lib/stores/editors/CubeJoinDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeJoinDraft.js +136 -0
- package/lib/stores/editors/CubeJoinDraft.js.map +1 -0
- package/lib/stores/editors/CubeNodeDraft.d.ts +38 -0
- package/lib/stores/editors/CubeNodeDraft.d.ts.map +1 -0
- package/lib/stores/editors/CubeNodeDraft.js +35 -0
- package/lib/stores/editors/CubeNodeDraft.js.map +1 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.d.ts +29 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.d.ts.map +1 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.js +33 -0
- package/lib/stores/editors/CubeNodeDraftRegistry.js.map +1 -0
- package/lib/stores/fixtures/CubeNorthwindModel.d.ts +23 -0
- package/lib/stores/fixtures/CubeNorthwindModel.d.ts.map +1 -0
- package/lib/stores/fixtures/CubeNorthwindModel.js +338 -0
- package/lib/stores/fixtures/CubeNorthwindModel.js.map +1 -0
- package/package.json +81 -3
- package/src/__lib__/LegendCubeCommand.ts +44 -0
- package/src/__lib__/LegendCubeHelpText.ts +38 -0
- package/src/__lib__/LegendCubeLabels.ts +141 -0
- package/src/__lib__/LegendCubeTesting.ts +33 -0
- package/src/__test-utils__/CubeCanvasTestUtils.ts +53 -0
- package/src/__test-utils__/CubeEngineTestSupport.ts +137 -0
- package/src/__test-utils__/CubeNorthwindTestQueries.ts +165 -0
- package/src/__test-utils__/CubePageTestUtils.tsx +96 -0
- package/src/__test-utils__/CubeTestApplication.ts +82 -0
- package/src/__test-utils__/FakeCubeEngine.ts +139 -0
- package/src/components/CubeButton.tsx +35 -0
- package/src/components/CubeEditor.tsx +239 -0
- package/src/components/CubeNodeIcon.tsx +47 -0
- package/src/components/canvas/CubeCanvas.tsx +260 -0
- package/src/components/canvas/CubeCanvasContext.ts +31 -0
- package/src/components/canvas/CubeCanvasContextMenu.tsx +89 -0
- package/src/components/canvas/CubeCanvasDnd.ts +82 -0
- package/src/components/canvas/CubeCanvasEdge.tsx +57 -0
- package/src/components/canvas/CubeCanvasElements.ts +150 -0
- package/src/components/canvas/CubeCanvasLayout.ts +88 -0
- package/src/components/canvas/CubeCanvasNode.tsx +141 -0
- package/src/components/editors/CubeColumnPicker.tsx +114 -0
- package/src/components/editors/CubeFilterEditor.tsx +309 -0
- package/src/components/editors/CubeJoinEditor.tsx +224 -0
- package/src/components/editors/CubeNodeEditorPanel.tsx +204 -0
- package/src/components/editors/CubeNodeEditorRegistry.ts +61 -0
- package/src/components/editors/CubeSourceEditor.tsx +116 -0
- package/src/components/editors/CubeValueEditor.tsx +332 -0
- package/src/components/grid/CubeGridRegion.tsx +274 -0
- package/src/components/grid/CubeGridValues.ts +125 -0
- package/src/components/grid/CubeResultGrid.tsx +84 -0
- package/src/components/palette/CubePalette.tsx +177 -0
- package/src/components/show-pure/CubeShowPureDialog.tsx +101 -0
- package/src/components/source-picker/CubeSourcePicker.tsx +304 -0
- package/src/components/spec-transfer/CubeSpecTransferDialog.tsx +157 -0
- package/src/graph-manager/CubeEngine.ts +155 -0
- package/src/graph-manager/CubeModelOutlineHelper.ts +32 -0
- package/src/graph-manager/protocol/pure/CubeEngineBuilder.ts +34 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeEngineErrors.ts +109 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeExecutionResultReader.ts +115 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeLambdaSerializer.ts +257 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeModelOutlineBuilder.ts +157 -0
- package/src/graph-manager/protocol/pure/v1/V1_CubeRelationTypeAdapter.ts +58 -0
- package/src/graph-manager/protocol/pure/v1/V1_LegendCubeEngine.ts +278 -0
- package/src/graph-manager/protocol/pure/v1/__test-utils__/V1_CubeEngineTestUtils.ts +124 -0
- package/src/index.ts +41 -0
- package/src/stores/CubeEditorState.ts +702 -0
- package/src/stores/CubeExecutionState.ts +255 -0
- package/src/stores/CubeHost.ts +32 -0
- package/src/stores/CubeNodeEditorState.ts +255 -0
- package/src/stores/CubeShowPureState.ts +96 -0
- package/src/stores/CubeSourcePickerState.ts +426 -0
- package/src/stores/CubeSpecTransferState.ts +198 -0
- package/src/stores/LocalModelCatalog.ts +70 -0
- package/src/stores/editors/CubeFilterDraft.ts +241 -0
- package/src/stores/editors/CubeJoinDraft.ts +197 -0
- package/src/stores/editors/CubeNodeDraft.ts +46 -0
- package/src/stores/editors/CubeNodeDraftRegistry.ts +49 -0
- package/src/stores/fixtures/CubeNorthwindModel.ts +355 -0
- package/tsconfig.json +118 -0
|
@@ -0,0 +1,304 @@
|
|
|
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
|
+
clsx,
|
|
19
|
+
Dialog,
|
|
20
|
+
Modal,
|
|
21
|
+
ModalBody,
|
|
22
|
+
ModalFooter,
|
|
23
|
+
ModalFooterButton,
|
|
24
|
+
ModalHeader,
|
|
25
|
+
PanelLoadingIndicator,
|
|
26
|
+
} from '@finos/legend-art';
|
|
27
|
+
import { getRelationalDisplayName } from '@finos/legend-cube';
|
|
28
|
+
import { flowResult } from 'mobx';
|
|
29
|
+
import { observer } from 'mobx-react-lite';
|
|
30
|
+
import { useId } from 'react';
|
|
31
|
+
import {
|
|
32
|
+
CUBE_PENDING_LABEL,
|
|
33
|
+
CUBE_TABLE_FLAG_LABELS,
|
|
34
|
+
} from '../../__lib__/LegendCubeLabels.js';
|
|
35
|
+
import type { CubeEditorState } from '../../stores/CubeEditorState.js';
|
|
36
|
+
import { isTableSelectable } from '../../stores/CubeSourcePickerState.js';
|
|
37
|
+
import { CubeButton } from '../CubeButton.js';
|
|
38
|
+
|
|
39
|
+
/** One step of the picker: a labelled list of choices, read-only when the cube fixes it */
|
|
40
|
+
const CubePickerStep: React.FC<{
|
|
41
|
+
label: string;
|
|
42
|
+
value: string | undefined;
|
|
43
|
+
options: readonly { value: string; label: string }[];
|
|
44
|
+
disabled?: boolean;
|
|
45
|
+
onChange: (value: string | undefined) => void;
|
|
46
|
+
}> = ({ label, value, options, disabled, onChange }) => {
|
|
47
|
+
const id = useId();
|
|
48
|
+
return (
|
|
49
|
+
<div className="flex items-center gap-2">
|
|
50
|
+
<label className="w-20 shrink-0 text-base" htmlFor={id}>
|
|
51
|
+
{label}
|
|
52
|
+
</label>
|
|
53
|
+
<select
|
|
54
|
+
id={id}
|
|
55
|
+
className="h-7 min-w-0 flex-1 rounded-sm border border-[var(--color-border-default)] bg-[var(--color-bg-input)] px-1 text-base text-[var(--color-text-primary)] disabled:text-[var(--color-text-secondary)]"
|
|
56
|
+
value={value ?? ''}
|
|
57
|
+
disabled={Boolean(disabled) || !options.length}
|
|
58
|
+
onChange={(event) => onChange(event.target.value || undefined)}
|
|
59
|
+
>
|
|
60
|
+
{value === undefined && <option value="">Choose…</option>}
|
|
61
|
+
{options.map((option) => (
|
|
62
|
+
<option key={option.value} value={option.value}>
|
|
63
|
+
{option.label}
|
|
64
|
+
</option>
|
|
65
|
+
))}
|
|
66
|
+
</select>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Adds a table to the cube (PLAN §6.2.7): a minimal dialog, which M3
|
|
73
|
+
* redesigns. The table lands with its schema; the first one fixes the cube's
|
|
74
|
+
* model and runtime.
|
|
75
|
+
*/
|
|
76
|
+
/** The Model option that offers a text box for Pure text */
|
|
77
|
+
const PASTE_MODEL_OPTION = 'paste';
|
|
78
|
+
|
|
79
|
+
export const CubeSourcePicker = observer(
|
|
80
|
+
(props: { editorState: CubeEditorState }) => {
|
|
81
|
+
const { editorState } = props;
|
|
82
|
+
const picker = editorState.sourcePicker;
|
|
83
|
+
const { applicationStore } = editorState.host;
|
|
84
|
+
const darkMode =
|
|
85
|
+
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled;
|
|
86
|
+
const isFixed = picker.fixedContext !== undefined;
|
|
87
|
+
const fixedModelLabel =
|
|
88
|
+
picker.models.find(
|
|
89
|
+
(model) =>
|
|
90
|
+
JSON.stringify(model.model) ===
|
|
91
|
+
JSON.stringify(picker.fixedContext?.model),
|
|
92
|
+
)?.label ?? "The cube's model";
|
|
93
|
+
const confirm = (): void => {
|
|
94
|
+
flowResult(picker.confirm()).catch(applicationStore.alertUnhandledError);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
return (
|
|
98
|
+
<Dialog open={picker.isOpen} onClose={() => picker.close()}>
|
|
99
|
+
<Modal darkMode={darkMode} className="w-[640px] max-w-full">
|
|
100
|
+
<ModalHeader>
|
|
101
|
+
<div className="modal__title">Add a table</div>
|
|
102
|
+
</ModalHeader>
|
|
103
|
+
<PanelLoadingIndicator
|
|
104
|
+
isLoading={picker.isLoadingModel || picker.isResolving}
|
|
105
|
+
/>
|
|
106
|
+
<ModalBody>
|
|
107
|
+
<div className="flex flex-col gap-2">
|
|
108
|
+
<CubePickerStep
|
|
109
|
+
label="Model"
|
|
110
|
+
value={
|
|
111
|
+
isFixed
|
|
112
|
+
? 'fixed'
|
|
113
|
+
: picker.isPastingModel
|
|
114
|
+
? PASTE_MODEL_OPTION
|
|
115
|
+
: picker.models.find(
|
|
116
|
+
(model) => model.model === picker.model,
|
|
117
|
+
)?.id
|
|
118
|
+
}
|
|
119
|
+
options={
|
|
120
|
+
isFixed
|
|
121
|
+
? [{ value: 'fixed', label: fixedModelLabel }]
|
|
122
|
+
: [
|
|
123
|
+
...picker.models.map((model) => ({
|
|
124
|
+
value: model.id,
|
|
125
|
+
label: model.label,
|
|
126
|
+
})),
|
|
127
|
+
{
|
|
128
|
+
value: PASTE_MODEL_OPTION,
|
|
129
|
+
label: 'Paste Pure model…',
|
|
130
|
+
},
|
|
131
|
+
]
|
|
132
|
+
}
|
|
133
|
+
disabled={isFixed}
|
|
134
|
+
onChange={(id) => {
|
|
135
|
+
if (id === PASTE_MODEL_OPTION) {
|
|
136
|
+
picker.startPastingModel();
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
const model = picker.models.find(
|
|
140
|
+
(candidate) => candidate.id === id,
|
|
141
|
+
);
|
|
142
|
+
if (model) {
|
|
143
|
+
flowResult(picker.selectModel(model.model)).catch(
|
|
144
|
+
applicationStore.alertUnhandledError,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
}}
|
|
148
|
+
/>
|
|
149
|
+
{picker.isPastingModel && !isFixed && (
|
|
150
|
+
<div className="flex flex-col gap-1">
|
|
151
|
+
<textarea
|
|
152
|
+
className="h-40 w-full resize-y rounded-sm border border-[var(--color-border-default)] bg-[var(--color-bg-input)] p-1 font-mono text-sm text-[var(--color-text-primary)]"
|
|
153
|
+
aria-label="Pure model"
|
|
154
|
+
placeholder={
|
|
155
|
+
'###Relational\nDatabase my::Database ( … )\n\n###Runtime\nRuntime my::Runtime { … }'
|
|
156
|
+
}
|
|
157
|
+
spellCheck={false}
|
|
158
|
+
value={picker.pastedModelText}
|
|
159
|
+
onChange={(event) =>
|
|
160
|
+
picker.setPastedModelText(event.target.value)
|
|
161
|
+
}
|
|
162
|
+
/>
|
|
163
|
+
<div className="flex items-center gap-2">
|
|
164
|
+
<CubeButton
|
|
165
|
+
disabled={
|
|
166
|
+
!picker.pastedModelText.trim() || picker.isLoadingModel
|
|
167
|
+
}
|
|
168
|
+
onClick={() => {
|
|
169
|
+
flowResult(picker.loadPastedModel()).catch(
|
|
170
|
+
applicationStore.alertUnhandledError,
|
|
171
|
+
);
|
|
172
|
+
}}
|
|
173
|
+
>
|
|
174
|
+
Load model
|
|
175
|
+
</CubeButton>
|
|
176
|
+
<span className="text-sm text-[var(--color-text-muted)]">
|
|
177
|
+
The cube keeps the model's text, which counts towards
|
|
178
|
+
the 1 MiB a cube spec can hold.
|
|
179
|
+
</span>
|
|
180
|
+
</div>
|
|
181
|
+
</div>
|
|
182
|
+
)}
|
|
183
|
+
{picker.isLoadingModel && (
|
|
184
|
+
<div className="text-base text-[var(--color-text-secondary)]">
|
|
185
|
+
{CUBE_PENDING_LABEL.LOADING_MODEL}
|
|
186
|
+
</div>
|
|
187
|
+
)}
|
|
188
|
+
<CubePickerStep
|
|
189
|
+
label="Database"
|
|
190
|
+
value={picker.databasePath}
|
|
191
|
+
options={picker.databases.map((database) => ({
|
|
192
|
+
value: database.path,
|
|
193
|
+
label: database.path,
|
|
194
|
+
}))}
|
|
195
|
+
disabled={picker.fixedDatabasePath !== undefined}
|
|
196
|
+
onChange={(path) => picker.selectDatabase(path)}
|
|
197
|
+
/>
|
|
198
|
+
<CubePickerStep
|
|
199
|
+
label="Runtime"
|
|
200
|
+
value={picker.runtimePath}
|
|
201
|
+
options={picker.runtimes.map((runtime) => ({
|
|
202
|
+
value: runtime.path,
|
|
203
|
+
label: runtime.path,
|
|
204
|
+
}))}
|
|
205
|
+
disabled={picker.fixedContext?.runtime !== undefined}
|
|
206
|
+
onChange={(path) => picker.selectRuntime(path)}
|
|
207
|
+
/>
|
|
208
|
+
<CubePickerStep
|
|
209
|
+
label="Schema"
|
|
210
|
+
value={picker.schemaName}
|
|
211
|
+
options={picker.schemas.map((schema) => ({
|
|
212
|
+
value: schema.name,
|
|
213
|
+
label: getRelationalDisplayName(schema.name),
|
|
214
|
+
}))}
|
|
215
|
+
onChange={(name) => picker.selectSchema(name)}
|
|
216
|
+
/>
|
|
217
|
+
{picker.schemaName !== undefined && (
|
|
218
|
+
<div className="flex flex-col gap-1">
|
|
219
|
+
<input
|
|
220
|
+
className="h-7 rounded-sm border border-[var(--color-border-default)] bg-[var(--color-bg-input)] px-1 text-base text-[var(--color-text-primary)]"
|
|
221
|
+
placeholder="Search tables"
|
|
222
|
+
aria-label="Search tables"
|
|
223
|
+
value={picker.tableSearch}
|
|
224
|
+
onChange={(event) =>
|
|
225
|
+
picker.setTableSearch(event.target.value)
|
|
226
|
+
}
|
|
227
|
+
/>
|
|
228
|
+
<ul
|
|
229
|
+
className="h-56 overflow-auto rounded-sm border border-[var(--color-border-subtle)]"
|
|
230
|
+
aria-label="Tables"
|
|
231
|
+
>
|
|
232
|
+
{picker.tables.map((table) => {
|
|
233
|
+
const selectable = isTableSelectable(table);
|
|
234
|
+
const isPicked = picker.tableName === table.name;
|
|
235
|
+
return (
|
|
236
|
+
<li key={table.name}>
|
|
237
|
+
<button
|
|
238
|
+
type="button"
|
|
239
|
+
className={clsx(
|
|
240
|
+
'flex w-full items-center gap-2 px-2 py-1 text-left text-base enabled:hover:bg-[var(--color-bg-hover)] disabled:cursor-not-allowed disabled:text-[var(--color-text-disabled)]',
|
|
241
|
+
{ 'bg-[var(--color-bg-selected)]': isPicked },
|
|
242
|
+
)}
|
|
243
|
+
aria-pressed={isPicked}
|
|
244
|
+
disabled={!selectable}
|
|
245
|
+
onClick={() => picker.selectTable(table.name)}
|
|
246
|
+
>
|
|
247
|
+
<span className="min-w-0 flex-1 truncate">
|
|
248
|
+
{getRelationalDisplayName(table.name)}
|
|
249
|
+
</span>
|
|
250
|
+
{table.flags.map((flag) => (
|
|
251
|
+
<span
|
|
252
|
+
key={flag}
|
|
253
|
+
className="rounded-sm bg-[var(--color-status-warn-bg)] px-1 text-sm text-[var(--color-status-warn)]"
|
|
254
|
+
title={CUBE_TABLE_FLAG_LABELS[flag].description}
|
|
255
|
+
>
|
|
256
|
+
{CUBE_TABLE_FLAG_LABELS[flag].label}
|
|
257
|
+
</span>
|
|
258
|
+
))}
|
|
259
|
+
<span className="shrink-0 text-sm text-[var(--color-text-muted)]">
|
|
260
|
+
{table.columnCount} columns
|
|
261
|
+
</span>
|
|
262
|
+
</button>
|
|
263
|
+
</li>
|
|
264
|
+
);
|
|
265
|
+
})}
|
|
266
|
+
</ul>
|
|
267
|
+
</div>
|
|
268
|
+
)}
|
|
269
|
+
{picker.isResolving && (
|
|
270
|
+
<div className="text-base text-[var(--color-text-secondary)]">
|
|
271
|
+
{CUBE_PENDING_LABEL.RESOLVING_SOURCE}
|
|
272
|
+
</div>
|
|
273
|
+
)}
|
|
274
|
+
{picker.error !== undefined && (
|
|
275
|
+
<div
|
|
276
|
+
className="text-base text-[var(--color-status-error)]"
|
|
277
|
+
role="alert"
|
|
278
|
+
>
|
|
279
|
+
{picker.error}
|
|
280
|
+
</div>
|
|
281
|
+
)}
|
|
282
|
+
</div>
|
|
283
|
+
</ModalBody>
|
|
284
|
+
<ModalFooter>
|
|
285
|
+
<ModalFooterButton
|
|
286
|
+
darkMode={darkMode}
|
|
287
|
+
formatText={false}
|
|
288
|
+
text="Add"
|
|
289
|
+
disabled={!picker.canConfirm}
|
|
290
|
+
onClick={confirm}
|
|
291
|
+
/>
|
|
292
|
+
<ModalFooterButton
|
|
293
|
+
darkMode={darkMode}
|
|
294
|
+
formatText={false}
|
|
295
|
+
type="secondary"
|
|
296
|
+
text="Cancel"
|
|
297
|
+
onClick={() => picker.close()}
|
|
298
|
+
/>
|
|
299
|
+
</ModalFooter>
|
|
300
|
+
</Modal>
|
|
301
|
+
</Dialog>
|
|
302
|
+
);
|
|
303
|
+
},
|
|
304
|
+
);
|
|
@@ -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 {
|
|
18
|
+
Dialog,
|
|
19
|
+
Modal,
|
|
20
|
+
ModalBody,
|
|
21
|
+
ModalFooter,
|
|
22
|
+
ModalFooterButton,
|
|
23
|
+
ModalHeader,
|
|
24
|
+
PanelLoadingIndicator,
|
|
25
|
+
} from '@finos/legend-art';
|
|
26
|
+
import { flowResult } from 'mobx';
|
|
27
|
+
import { observer } from 'mobx-react-lite';
|
|
28
|
+
import type { CubeEditorState } from '../../stores/CubeEditorState.js';
|
|
29
|
+
import { CUBE_SPEC_TRANSFER_MODE } from '../../stores/CubeSpecTransferState.js';
|
|
30
|
+
|
|
31
|
+
const TEXT_AREA_CLASS_NAME =
|
|
32
|
+
'h-80 w-full resize-none rounded-sm border border-[var(--color-border-default)] bg-[var(--color-bg-input)] p-1 font-mono text-sm text-[var(--color-text-primary)]';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Export and Import of the cube's saved spec, as text to copy, download,
|
|
36
|
+
* paste or read from a file (PLAN §10.3; developer tools until M8).
|
|
37
|
+
*/
|
|
38
|
+
export const CubeSpecTransferDialog = observer(
|
|
39
|
+
(props: { editorState: CubeEditorState }) => {
|
|
40
|
+
const { editorState } = props;
|
|
41
|
+
const transfer = editorState.specTransfer;
|
|
42
|
+
const { applicationStore } = editorState.host;
|
|
43
|
+
const darkMode =
|
|
44
|
+
!applicationStore.layoutService.TEMPORARY__isLightColorThemeEnabled;
|
|
45
|
+
const isExport = transfer.mode === CUBE_SPEC_TRANSFER_MODE.EXPORT;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<Dialog
|
|
49
|
+
open={transfer.mode !== undefined}
|
|
50
|
+
onClose={() => transfer.close()}
|
|
51
|
+
>
|
|
52
|
+
<Modal darkMode={darkMode} className="w-[720px] max-w-full">
|
|
53
|
+
<ModalHeader>
|
|
54
|
+
<div className="modal__title">
|
|
55
|
+
{isExport ? 'Export spec (dev)' : 'Import spec (dev)'}
|
|
56
|
+
</div>
|
|
57
|
+
</ModalHeader>
|
|
58
|
+
<PanelLoadingIndicator isLoading={transfer.isReadingFile} />
|
|
59
|
+
<ModalBody>
|
|
60
|
+
<div className="flex flex-col gap-2">
|
|
61
|
+
{isExport ? (
|
|
62
|
+
transfer.exportText !== undefined && (
|
|
63
|
+
<textarea
|
|
64
|
+
className={TEXT_AREA_CLASS_NAME}
|
|
65
|
+
aria-label="Cube spec"
|
|
66
|
+
readOnly={true}
|
|
67
|
+
value={transfer.exportText}
|
|
68
|
+
/>
|
|
69
|
+
)
|
|
70
|
+
) : (
|
|
71
|
+
<>
|
|
72
|
+
<div className="text-base text-[var(--color-text-secondary)]">
|
|
73
|
+
Paste a cube spec, or choose a .cube.json file. The spec
|
|
74
|
+
replaces this cube; Undo brings it back.
|
|
75
|
+
</div>
|
|
76
|
+
<input
|
|
77
|
+
className="text-base"
|
|
78
|
+
type="file"
|
|
79
|
+
accept=".json,application/json"
|
|
80
|
+
aria-label="Spec file"
|
|
81
|
+
onChange={(event) => {
|
|
82
|
+
const file = event.target.files?.[0];
|
|
83
|
+
// the same file can be chosen again
|
|
84
|
+
event.target.value = '';
|
|
85
|
+
if (file) {
|
|
86
|
+
flowResult(transfer.readImportFile(file)).catch(
|
|
87
|
+
applicationStore.alertUnhandledError,
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
<textarea
|
|
93
|
+
className={TEXT_AREA_CLASS_NAME}
|
|
94
|
+
aria-label="Cube spec"
|
|
95
|
+
placeholder="Cube spec"
|
|
96
|
+
spellCheck={false}
|
|
97
|
+
value={transfer.importText}
|
|
98
|
+
onChange={(event) =>
|
|
99
|
+
transfer.setImportText(event.target.value)
|
|
100
|
+
}
|
|
101
|
+
/>
|
|
102
|
+
</>
|
|
103
|
+
)}
|
|
104
|
+
{transfer.error !== undefined && (
|
|
105
|
+
<div
|
|
106
|
+
className="break-words text-base text-[var(--color-status-error)]"
|
|
107
|
+
role="alert"
|
|
108
|
+
>
|
|
109
|
+
{transfer.error}
|
|
110
|
+
</div>
|
|
111
|
+
)}
|
|
112
|
+
</div>
|
|
113
|
+
</ModalBody>
|
|
114
|
+
<ModalFooter>
|
|
115
|
+
{isExport ? (
|
|
116
|
+
<>
|
|
117
|
+
<ModalFooterButton
|
|
118
|
+
darkMode={darkMode}
|
|
119
|
+
formatText={false}
|
|
120
|
+
text="Copy"
|
|
121
|
+
disabled={transfer.exportText === undefined}
|
|
122
|
+
onClick={() => {
|
|
123
|
+
transfer
|
|
124
|
+
.copyExport()
|
|
125
|
+
.catch(applicationStore.alertUnhandledError);
|
|
126
|
+
}}
|
|
127
|
+
/>
|
|
128
|
+
<ModalFooterButton
|
|
129
|
+
darkMode={darkMode}
|
|
130
|
+
formatText={false}
|
|
131
|
+
text="Download"
|
|
132
|
+
disabled={transfer.exportText === undefined}
|
|
133
|
+
onClick={() => transfer.downloadExport()}
|
|
134
|
+
/>
|
|
135
|
+
</>
|
|
136
|
+
) : (
|
|
137
|
+
<ModalFooterButton
|
|
138
|
+
darkMode={darkMode}
|
|
139
|
+
formatText={false}
|
|
140
|
+
text="Import"
|
|
141
|
+
disabled={!transfer.importText.trim() || transfer.isReadingFile}
|
|
142
|
+
onClick={() => transfer.importSpec()}
|
|
143
|
+
/>
|
|
144
|
+
)}
|
|
145
|
+
<ModalFooterButton
|
|
146
|
+
darkMode={darkMode}
|
|
147
|
+
formatText={false}
|
|
148
|
+
type="secondary"
|
|
149
|
+
text={isExport ? 'Close' : 'Cancel'}
|
|
150
|
+
onClick={() => transfer.close()}
|
|
151
|
+
/>
|
|
152
|
+
</ModalFooter>
|
|
153
|
+
</Modal>
|
|
154
|
+
</Dialog>
|
|
155
|
+
);
|
|
156
|
+
},
|
|
157
|
+
);
|
|
@@ -0,0 +1,155 @@
|
|
|
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, ModelContext, Schema } from '@finos/legend-cube';
|
|
18
|
+
|
|
19
|
+
// The engine port (PLAN §8.7): what Cube asks of an engine, in Cube's own
|
|
20
|
+
// terms. Only its Legend implementation, under `protocol/pure/v1/`, knows the
|
|
21
|
+
// protocol; nothing here names a V1_* type
|
|
22
|
+
|
|
23
|
+
/** A query node's id */
|
|
24
|
+
export type NodeId = string;
|
|
25
|
+
|
|
26
|
+
/** A table's Database element path, schema name and table name, names as stored (quotes included) */
|
|
27
|
+
export type AccessorPath = readonly [
|
|
28
|
+
database: string,
|
|
29
|
+
schema: string,
|
|
30
|
+
table: string,
|
|
31
|
+
];
|
|
32
|
+
|
|
33
|
+
/** Why a table can't be picked as it is, read from its definition (PLAN §6.2.6) */
|
|
34
|
+
export enum CubeTableFlag {
|
|
35
|
+
/** a binary column: the engine can't type the table */
|
|
36
|
+
UNAVAILABLE = 'unavailable',
|
|
37
|
+
/** a CHAR(n) column: typed with a length of 1 */
|
|
38
|
+
LENGTH_UNKNOWN = 'lengthUnknown',
|
|
39
|
+
/** an OTHER or ARRAY column: typed as a bare String */
|
|
40
|
+
TYPE_UNKNOWN = 'typeUnknown',
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export interface CubeOutlineTable {
|
|
44
|
+
/** As stored, quotes included */
|
|
45
|
+
readonly name: string;
|
|
46
|
+
/** Views are typed as text of length 0, so the picker hides them in v1 */
|
|
47
|
+
readonly isView: boolean;
|
|
48
|
+
readonly columnCount: number;
|
|
49
|
+
readonly flags: readonly CubeTableFlag[];
|
|
50
|
+
/**
|
|
51
|
+
* The columns typed as a bare String because Cube can't read their type
|
|
52
|
+
* (OTHER or ARRAY), unquoted as in the table's schema
|
|
53
|
+
*/
|
|
54
|
+
readonly untypedColumns: readonly string[];
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface CubeOutlineSchema {
|
|
58
|
+
readonly name: string;
|
|
59
|
+
readonly tables: readonly CubeOutlineTable[];
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export interface CubeOutlineDatabase {
|
|
63
|
+
readonly path: string;
|
|
64
|
+
readonly schemas: readonly CubeOutlineSchema[];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export interface CubeOutlineRuntime {
|
|
68
|
+
readonly path: string;
|
|
69
|
+
/** The stores its connections are keyed by, exactly; includes are not followed (PLAN §6.2.5) */
|
|
70
|
+
readonly storePaths: readonly string[];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** What a model offers the source picker: its databases and runtimes, as plain data */
|
|
74
|
+
export interface CubeModelOutline {
|
|
75
|
+
readonly databases: readonly CubeOutlineDatabase[];
|
|
76
|
+
readonly runtimes: readonly CubeOutlineRuntime[];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export enum CubeEngineErrorKind {
|
|
80
|
+
/** the model or a lambda doesn't compile, or a table can't be typed */
|
|
81
|
+
COMPILE = 'compile',
|
|
82
|
+
/** the query failed while running, or its result can't be read */
|
|
83
|
+
EXECUTION = 'execution',
|
|
84
|
+
/** the cube's model is of a kind this version can't run */
|
|
85
|
+
UNSUPPORTED_MODEL = 'unsupportedModel',
|
|
86
|
+
/** the engine couldn't be reached, or answered with no readable error */
|
|
87
|
+
NETWORK = 'network',
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* An engine failure, placed on the node it concerns: the node a stamp in the
|
|
92
|
+
* error points to, else the source being typed or the node being run.
|
|
93
|
+
*/
|
|
94
|
+
export class CubeEngineError extends Error {
|
|
95
|
+
readonly kind: CubeEngineErrorKind;
|
|
96
|
+
readonly nodeId: NodeId | undefined;
|
|
97
|
+
/** The part of the node the error points to (an `EmitRole`), when it is located */
|
|
98
|
+
readonly role: string | undefined;
|
|
99
|
+
/** The first line of the engine's message, shown on the node */
|
|
100
|
+
readonly firstLine: string;
|
|
101
|
+
/** The engine's whole message, without its Java trace, shown in the panel */
|
|
102
|
+
readonly detail: string;
|
|
103
|
+
|
|
104
|
+
constructor(
|
|
105
|
+
kind: CubeEngineErrorKind,
|
|
106
|
+
detail: string,
|
|
107
|
+
nodeId?: NodeId,
|
|
108
|
+
role?: string,
|
|
109
|
+
) {
|
|
110
|
+
const firstLine = detail.split('\n', 1)[0]?.trim() ?? '';
|
|
111
|
+
super(firstLine);
|
|
112
|
+
this.name = 'CubeEngineError';
|
|
113
|
+
this.kind = kind;
|
|
114
|
+
this.detail = detail;
|
|
115
|
+
this.firstLine = firstLine;
|
|
116
|
+
this.nodeId = nodeId;
|
|
117
|
+
this.role = role;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** A value of a result cell: Integer and Decimal values as their exact text, Float values as numbers (PLAN §8.7) */
|
|
122
|
+
export type CubeResultValue = string | number | boolean | null;
|
|
123
|
+
|
|
124
|
+
export interface CubeResult {
|
|
125
|
+
/** Column names, in order; rows match them by position */
|
|
126
|
+
readonly columns: readonly string[];
|
|
127
|
+
/** As many rows as the engine sent, up to the row limit + 1 */
|
|
128
|
+
readonly rows: readonly (readonly CubeResultValue[])[];
|
|
129
|
+
/** The SQL statements the engine ran */
|
|
130
|
+
readonly sql: readonly string[];
|
|
131
|
+
readonly durationMs: number;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface CubeEngine {
|
|
135
|
+
/** The databases and runtimes of a model, parsed once */
|
|
136
|
+
loadModel(model: ModelContext): Promise<CubeModelOutline>;
|
|
137
|
+
/** The schema of each table, in one engine call: one entry per key, failures included */
|
|
138
|
+
resolveSchemas(
|
|
139
|
+
model: ModelContext,
|
|
140
|
+
accessors: ReadonlyMap<NodeId, AccessorPath>,
|
|
141
|
+
): Promise<Map<NodeId, Schema | CubeEngineError>>;
|
|
142
|
+
/** The schema of each lambda, in one engine call: one entry per key, failures included */
|
|
143
|
+
typeLambdas(
|
|
144
|
+
model: ModelContext,
|
|
145
|
+
lambdas: ReadonlyMap<NodeId, IR>,
|
|
146
|
+
): Promise<Map<NodeId, Schema | CubeEngineError>>;
|
|
147
|
+
/** Runs an execution lambda; rejects with a `CubeEngineError` */
|
|
148
|
+
execute(
|
|
149
|
+
model: ModelContext,
|
|
150
|
+
lambda: IR,
|
|
151
|
+
options?: { abortController?: AbortController | undefined },
|
|
152
|
+
): Promise<CubeResult>;
|
|
153
|
+
/** The Pure text of a lambda, for display only: never parsed back */
|
|
154
|
+
renderPure(lambda: IR): Promise<string>;
|
|
155
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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 { CubeModelOutline, CubeOutlineRuntime } from './CubeEngine.js';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The runtimes a query on the database can run with: those with a connection
|
|
21
|
+
* keyed by exactly that database. The engine matches stores by exact element
|
|
22
|
+
* and silently falls back to the first connection otherwise, so a runtime
|
|
23
|
+
* that only reaches the database through an include is not offered (PLAN
|
|
24
|
+
* §6.2.5).
|
|
25
|
+
*/
|
|
26
|
+
export const getRuntimesForDatabase = (
|
|
27
|
+
outline: CubeModelOutline,
|
|
28
|
+
databasePath: string,
|
|
29
|
+
): CubeOutlineRuntime[] =>
|
|
30
|
+
outline.runtimes.filter((runtime) =>
|
|
31
|
+
runtime.storePaths.includes(databasePath),
|
|
32
|
+
);
|
|
@@ -0,0 +1,34 @@
|
|
|
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 { TracerService } from '@finos/legend-shared';
|
|
18
|
+
import type { CubeEngine } from '../../CubeEngine.js';
|
|
19
|
+
import {
|
|
20
|
+
type V1_CubeEngineConfig,
|
|
21
|
+
V1_LegendCubeEngine,
|
|
22
|
+
} from './v1/V1_LegendCubeEngine.js';
|
|
23
|
+
|
|
24
|
+
/** The engine client's configuration, as the host gives it (e.g. Legend Query's engine server URL) */
|
|
25
|
+
export type CubeEngineConfig = V1_CubeEngineConfig;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The Cube engine of a host (PLAN §3.2): the only place that builds the
|
|
29
|
+
* Legend implementation, so hosts never name a V1_* symbol
|
|
30
|
+
*/
|
|
31
|
+
export const buildCubeEngine = (
|
|
32
|
+
config: CubeEngineConfig,
|
|
33
|
+
tracerService: TracerService,
|
|
34
|
+
): CubeEngine => new V1_LegendCubeEngine(config, tracerService);
|