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