@geode/opengeodeweb-front 10.34.0-rc.9 → 10.34.0
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/{server → .build/server}/utils/app_config.js +10 -9
- package/{server → .build/server}/utils/cleanup.js +31 -17
- package/{server → .build/server}/utils/cloud.js +1 -4
- package/{server → .build/server}/utils/microservices.js +21 -9
- package/{server → .build/server}/utils/path.js +4 -4
- package/{server → .build/server}/utils/scripts.js +9 -9
- package/.build/server/utils/server_config.js +51 -0
- package/.build/server/utils/stream.js +6 -0
- package/{server → .build/server}/utils/ws_client.js +18 -3
- package/{shared → .build/shared}/scripts.js +10 -10
- package/.build/shared/utils/call_raw.js +31 -0
- package/{shared → .build/shared}/utils/call_schema.js +2 -2
- package/.build/shared/utils/fetch_raw.js +52 -0
- package/{shared → .build/shared}/utils/fetch_schema.js +2 -2
- package/{shared → .build/shared}/utils/file.js +3 -1
- package/{shared → .build/shared}/utils/response_handlers/load.js +10 -7
- package/{shared → .build/shared}/utils/validate_schema.js +1 -1
- package/app/components/ActionButton.vue +6 -6
- package/app/components/CameraManager/List.vue +5 -5
- package/app/components/CameraManager/Saver.vue +3 -5
- package/app/components/CameraManager.vue +6 -4
- package/app/components/CameraOrientation.vue +12 -12
- package/app/components/ClippingPlaneCard.vue +4 -2
- package/app/components/ClippingPlanes.vue +8 -8
- package/app/components/CrsSelector.vue +9 -10
- package/app/components/DeleteDialog.vue +4 -2
- package/app/components/DragAndDrop.vue +10 -12
- package/app/components/DragAndDropInternal/DragAndDropInline.vue +4 -2
- package/app/components/ExtensionSelector.vue +4 -4
- package/app/components/FeedBack/ErrorBanner.vue +3 -1
- package/app/components/FeedBack/Snackers.vue +4 -3
- package/app/components/FileSelector.vue +10 -8
- package/app/components/FileUploader.vue +11 -11
- package/app/components/GlassCard.vue +1 -1
- package/app/components/HybridRenderingView.vue +7 -5
- package/app/components/HybridViewerTooltip.vue +7 -7
- package/app/components/Launcher.vue +1 -1
- package/app/components/Loading/EcoMessages.vue +9 -3
- package/app/components/Loading.vue +2 -2
- package/app/components/MissingFilesSelector.vue +12 -10
- package/app/components/ObjectSelector.vue +10 -9
- package/app/components/PackagesVersions.vue +6 -5
- package/app/components/Recaptcha.vue +3 -3
- package/app/components/RemoteRenderingView.vue +6 -7
- package/app/components/Ruler.vue +3 -3
- package/app/components/Screenshot.vue +6 -6
- package/app/components/SearchBar.vue +4 -2
- package/app/components/ShrinkFilter.vue +7 -7
- package/app/components/Step.vue +6 -5
- package/app/components/Stepper.vue +4 -3
- package/app/components/ToolPanel.vue +6 -3
- package/app/components/ViewToolbar.vue +25 -28
- package/app/components/Viewer/ContextMenu/CenterButton.vue +7 -5
- package/app/components/Viewer/ContextMenu/CircularItems.vue +3 -3
- package/app/components/Viewer/ContextMenu/ContextMenu.vue +22 -19
- package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +10 -8
- package/app/components/Viewer/ContextMenu/InfoCard.vue +11 -12
- package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +13 -17
- package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +12 -16
- package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +8 -12
- package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +11 -15
- package/app/components/Viewer/Generic/Model/BlocksOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/CornersOptions.vue +53 -23
- package/app/components/Viewer/Generic/Model/EdgesOptions.vue +1 -3
- package/app/components/Viewer/Generic/Model/LinesOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +31 -15
- package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +2 -3
- package/app/components/Viewer/Generic/Model/PointsOptions.vue +6 -6
- package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +69 -38
- package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +64 -46
- package/app/components/Viewer/ObjectTree/Base/Controls.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +13 -9
- package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +10 -10
- package/app/components/Viewer/ObjectTree/Box.vue +6 -4
- package/app/components/Viewer/ObjectTree/Layout.vue +23 -21
- package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +14 -14
- package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +59 -24
- package/app/components/Viewer/Options/AttributeColorBar.vue +4 -2
- package/app/components/Viewer/Options/AttributeRangeSelector.vue +4 -2
- package/app/components/Viewer/Options/AttributeSelector.vue +7 -9
- package/app/components/Viewer/Options/ColorMapList.vue +15 -13
- package/app/components/Viewer/Options/ColorMapPicker.vue +4 -4
- package/app/components/Viewer/Options/ColorPicker.vue +223 -41
- package/app/components/Viewer/Options/ColoringTypeSelector.vue +16 -16
- package/app/components/Viewer/Options/ColormapQuickPicker.vue +7 -5
- package/app/components/Viewer/Options/OptionsSection.vue +1 -1
- package/app/components/Viewer/Options/TextureItem.vue +8 -6
- package/app/components/Viewer/Options/TexturesSelector.vue +1 -1
- package/app/components/Viewer/OverlappingObjectsPicker.vue +8 -9
- package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +2 -6
- package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +12 -16
- package/app/components/Viewer/Surface/PolygonsOptions.vue +12 -16
- package/app/components/Viewer/Ui.vue +2 -2
- package/app/components/Wrapper.vue +1 -4
- package/app/components/ZScaling.vue +5 -3
- package/app/components/csv-preview/CsvPreviewer.vue +38 -37
- package/app/components/csv-preview/CsvSettings.vue +6 -4
- package/app/components/csv-preview/CsvTable.vue +1 -1
- package/app/composables/batch_style.ts +5 -6
- package/app/composables/clipping_planes_widget.ts +73 -181
- package/app/composables/clipping_planes_widget_entries.ts +189 -0
- package/app/composables/copy_to_clipboard.ts +7 -0
- package/app/composables/global_attribute_style.ts +163 -83
- package/app/composables/hover_highlight.ts +46 -14
- package/app/composables/model_collections.ts +26 -13
- package/app/composables/model_components.ts +26 -13
- package/app/composables/project_manager.ts +76 -19
- package/app/composables/responsive_middle_truncate.ts +13 -13
- package/app/composables/stepper_tree.ts +34 -11
- package/app/composables/tree_filter.ts +66 -44
- package/app/composables/tree_keyboard_nav.ts +25 -11
- package/app/composables/tree_scroll.ts +44 -14
- package/app/composables/use_adaptive_styles.ts +66 -23
- package/app/composables/use_overlapping_picker.ts +66 -16
- package/app/composables/use_quick_colormap.ts +16 -5
- package/app/composables/virtual_tree.ts +75 -43
- package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
- package/app/plugins/auto_store_register.ts +2 -7
- package/app/plugins/click_outside_ignore_snackbars.client.ts +39 -0
- package/app/stores/app.ts +57 -192
- package/app/stores/app_helpers/extension.ts +179 -0
- package/app/stores/back.ts +37 -21
- package/app/stores/camera_manager.ts +22 -20
- package/app/stores/cloud.ts +17 -13
- package/app/stores/data.ts +88 -47
- package/app/stores/data_helpers/collections.ts +36 -38
- package/app/stores/data_helpers/mesh.ts +45 -36
- package/app/stores/data_style.ts +50 -28
- package/app/stores/feedback.ts +6 -6
- package/app/stores/hybrid_viewer.ts +41 -52
- package/app/stores/infra.ts +39 -37
- package/app/stores/menu.ts +23 -14
- package/app/stores/treeview.ts +72 -42
- package/app/stores/viewer.ts +39 -27
- package/app/utils/attributes.ts +3 -3
- package/app/utils/clipping_planes.ts +111 -14
- package/app/utils/color_picker.ts +57 -0
- package/app/utils/colormap.ts +58 -35
- package/app/utils/default_styles/index.ts +2 -2
- package/app/utils/default_styles/meshes.ts +107 -13
- package/app/utils/default_styles/models.ts +83 -14
- package/app/utils/extension.ts +47 -20
- package/app/utils/import_workflow.ts +21 -13
- package/app/utils/name_cleaner.ts +1 -1
- package/app/utils/string.ts +1 -1
- package/app/utils/treeview.ts +2 -2
- package/internal/database/base_database.ts +7 -3
- package/internal/database/database.ts +36 -26
- package/internal/database/extended_database.ts +1 -1
- package/internal/stores/data_style/mesh/cells/cell.ts +70 -34
- package/internal/stores/data_style/mesh/cells/color.ts +12 -6
- package/internal/stores/data_style/mesh/cells/common.ts +18 -8
- package/internal/stores/data_style/mesh/cells/index.ts +122 -42
- package/internal/stores/data_style/mesh/cells/textures.ts +12 -6
- package/internal/stores/data_style/mesh/cells/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/cells/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/color.ts +12 -6
- package/internal/stores/data_style/mesh/edges/common.ts +14 -6
- package/internal/stores/data_style/mesh/edges/edge.ts +71 -39
- package/internal/stores/data_style/mesh/edges/index.ts +117 -42
- package/internal/stores/data_style/mesh/edges/vertex.ts +76 -39
- package/internal/stores/data_style/mesh/edges/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/width.ts +12 -4
- package/internal/stores/data_style/mesh/index.ts +30 -11
- package/internal/stores/data_style/mesh/points/color.ts +12 -6
- package/internal/stores/data_style/mesh/points/common.ts +21 -8
- package/internal/stores/data_style/mesh/points/index.ts +101 -50
- package/internal/stores/data_style/mesh/points/size.ts +12 -4
- package/internal/stores/data_style/mesh/points/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/points/visibility.ts +17 -7
- package/internal/stores/data_style/mesh/polygons/color.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/common.ts +23 -6
- package/internal/stores/data_style/mesh/polygons/index.ts +130 -70
- package/internal/stores/data_style/mesh/polygons/polygon.ts +77 -43
- package/internal/stores/data_style/mesh/polygons/textures.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polygons/visibility.ts +16 -6
- package/internal/stores/data_style/mesh/polyhedra/color.ts +12 -6
- package/internal/stores/data_style/mesh/polyhedra/common.ts +14 -6
- package/internal/stores/data_style/mesh/polyhedra/index.ts +115 -56
- package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +80 -39
- package/internal/stores/data_style/mesh/polyhedra/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polyhedra/visibility.ts +16 -6
- package/internal/stores/data_style/model/blocks/color.ts +43 -13
- package/internal/stores/data_style/model/blocks/common.ts +21 -6
- package/internal/stores/data_style/model/blocks/index.ts +89 -59
- package/internal/stores/data_style/model/blocks/polyhedron.ts +101 -44
- package/internal/stores/data_style/model/blocks/vertex.ts +107 -42
- package/internal/stores/data_style/model/blocks/visibility.ts +17 -4
- package/internal/stores/data_style/model/color.ts +171 -83
- package/internal/stores/data_style/model/common.ts +70 -21
- package/internal/stores/data_style/model/corners/color.ts +43 -11
- package/internal/stores/data_style/model/corners/common.ts +25 -6
- package/internal/stores/data_style/model/corners/index.ts +66 -41
- package/internal/stores/data_style/model/corners/vertex.ts +105 -74
- package/internal/stores/data_style/model/corners/visibility.ts +19 -4
- package/internal/stores/data_style/model/edges/common.ts +12 -4
- package/internal/stores/data_style/model/edges/index.ts +2 -1
- package/internal/stores/data_style/model/edges/visibility.ts +24 -7
- package/internal/stores/data_style/model/index.ts +24 -11
- package/internal/stores/data_style/model/lines/color.ts +41 -11
- package/internal/stores/data_style/model/lines/common.ts +17 -6
- package/internal/stores/data_style/model/lines/edge.ts +105 -42
- package/internal/stores/data_style/model/lines/index.ts +86 -59
- package/internal/stores/data_style/model/lines/vertex.ts +105 -42
- package/internal/stores/data_style/model/lines/visibility.ts +17 -4
- package/internal/stores/data_style/model/points/common.ts +8 -4
- package/internal/stores/data_style/model/points/index.ts +10 -3
- package/internal/stores/data_style/model/points/size.ts +12 -4
- package/internal/stores/data_style/model/points/visibility.ts +16 -6
- package/internal/stores/data_style/model/selection.ts +80 -58
- package/internal/stores/data_style/model/surfaces/color.ts +41 -11
- package/internal/stores/data_style/model/surfaces/common.ts +23 -6
- package/internal/stores/data_style/model/surfaces/index.ts +89 -59
- package/internal/stores/data_style/model/surfaces/polygon.ts +107 -67
- package/internal/stores/data_style/model/surfaces/vertex.ts +111 -67
- package/internal/stores/data_style/model/surfaces/visibility.ts +18 -5
- package/internal/stores/data_style/model/visibility.ts +82 -20
- package/internal/stores/data_style/state.ts +77 -65
- package/internal/stores/hybrid_viewer/brightness.ts +49 -31
- package/internal/stores/hybrid_viewer/camera.ts +191 -177
- package/internal/stores/hybrid_viewer/camera_animation.ts +11 -10
- package/internal/stores/hybrid_viewer/core.ts +64 -0
- package/internal/stores/hybrid_viewer/filters.ts +10 -16
- package/internal/stores/hybrid_viewer/highlight.ts +91 -130
- package/internal/stores/hybrid_viewer/ruler.ts +24 -15
- package/internal/stores/hybrid_viewer/scene.ts +96 -117
- package/internal/stores/hybrid_viewer/viewport.ts +74 -65
- package/internal/stores/hybrid_viewer/vtk_types.ts +13 -29
- package/internal/utils/api_fetch.ts +54 -23
- package/internal/utils/upload_file.ts +74 -53
- package/internal/utils/viewer_call.ts +22 -13
- package/internal/utils/ws_client.ts +24 -13
- package/nuxt.config.ts +58 -1
- package/package.json +20 -8
- package/server/api/cloud/extensions/run.post.ts +6 -10
- package/server/api/local/app/project_folder_path.post.ts +4 -4
- package/server/api/local/app/run_back.post.ts +5 -7
- package/server/api/local/app/run_viewer.post.ts +5 -7
- package/server/api/local/extensions/kill.post.ts +4 -3
- package/server/api/local/extensions/run.post.ts +7 -10
- package/server/api/local/extensions/upload.put.ts +44 -54
- package/server/api/microservice/app/get_is_app_ready.get.ts +4 -5
- package/server/api/microservice/app/set_app_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_back_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_is_app_ready.post.ts +5 -6
- package/server/api/microservice/app/set_viewer_base_url.post.ts +5 -6
- package/server/api/microservice/extensions/download.post.ts +5 -4
- package/server/api/serverless/run_cloud.post.ts +53 -11
- package/server/utils/app_config.ts +29 -22
- package/server/utils/cleanup.ts +60 -30
- package/server/utils/cloud.ts +9 -8
- package/server/utils/extension.ts +23 -9
- package/server/utils/microservices.ts +33 -24
- package/server/utils/path.ts +4 -4
- package/server/utils/scripts.ts +26 -23
- package/server/utils/server.ts +2 -2
- package/server/utils/server_config.ts +41 -27
- package/server/utils/stream.ts +6 -0
- package/server/utils/ws_client.ts +42 -8
- package/shared/scripts.ts +15 -10
- package/shared/utils/call_raw.ts +23 -16
- package/shared/utils/call_schema.ts +5 -8
- package/shared/utils/fetch_raw.ts +87 -47
- package/shared/utils/fetch_schema.ts +6 -9
- package/shared/utils/file.ts +8 -2
- package/shared/utils/response_handlers/load.ts +26 -11
- package/shared/utils/types.ts +9 -9
- package/shared/utils/validate_schema.ts +1 -1
- package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -276
- package/server/types/vendor.d.ts +0 -64
- package/server/utils/server_config.js +0 -43
- package/shared/utils/call_raw.js +0 -30
- package/shared/utils/fetch_raw.js +0 -40
- /package/{opengeodeweb_front_schemas.js → .build/opengeodeweb_front_schemas.js} +0 -0
- /package/{server → .build/server}/utils/server.js +0 -0
- /package/{shared → .build/shared}/app_mode.js +0 -0
- /package/{shared → .build/shared}/utils/parse_boolean.js +0 -0
- /package/{shared → .build/shared}/utils/types.js +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "node:path";
|
|
2
|
-
import { unlink } from "node:fs";
|
|
2
|
+
import { unlink } from "node:fs/promises";
|
|
3
3
|
import Conf from "conf";
|
|
4
4
|
import StreamZip from "node-stream-zip";
|
|
5
5
|
import sanitize from "sanitize-filename";
|
|
@@ -18,9 +18,7 @@ function targetExtensionFilePath(projectName, filename) {
|
|
|
18
18
|
return path.join(confFolderPath(projectName), safeFilename);
|
|
19
19
|
}
|
|
20
20
|
function extensionsConf(projectName) {
|
|
21
|
-
|
|
22
|
-
if (!projectConfig.has("extensions")) projectConfig.set("extensions", {});
|
|
23
|
-
return projectConfig.get("extensions");
|
|
21
|
+
return projectConf(projectName).get("extensions", {});
|
|
24
22
|
}
|
|
25
23
|
function addExtensionToConf(projectName, { extensionId, extensionPath }) {
|
|
26
24
|
projectConf(projectName).set(`extensions.${extensionId}.path`, extensionPath);
|
|
@@ -31,20 +29,23 @@ function extensionPathFromConf(projectName, extensionId) {
|
|
|
31
29
|
async function removeExtensionFromConf(projectName, extensionId) {
|
|
32
30
|
const projectConfig = projectConf(projectName);
|
|
33
31
|
const extensionArchivePath = extensionPathFromConf(projectName, extensionId);
|
|
34
|
-
await unlink(extensionArchivePath
|
|
35
|
-
|
|
36
|
-
console.log(`${extensionArchivePath} was deleted`);
|
|
37
|
-
});
|
|
32
|
+
await unlink(extensionArchivePath);
|
|
33
|
+
console.log(`${extensionArchivePath} was deleted`);
|
|
38
34
|
projectConfig.delete(`extensions.${extensionId}`);
|
|
39
35
|
console.log(`${extensionId} was deleted from ${projectName} config`);
|
|
40
36
|
}
|
|
37
|
+
function isExtensionMetadata(value) {
|
|
38
|
+
return typeof value === "object" && value !== null && "id" in value && typeof value.id === "string";
|
|
39
|
+
}
|
|
41
40
|
async function registerExtensionFile(projectName, file) {
|
|
42
41
|
const StreamZipAsync = StreamZip.async;
|
|
43
42
|
const metadataJson = await new StreamZipAsync({
|
|
44
43
|
file,
|
|
45
44
|
storeEntries: true
|
|
46
45
|
}).entryData("metadata.json");
|
|
47
|
-
const
|
|
46
|
+
const parsedMetadata = JSON.parse(metadataJson.toString("utf8"));
|
|
47
|
+
if (!isExtensionMetadata(parsedMetadata)) throw new TypeError("metadata.json does not match the expected ExtensionMetadata shape");
|
|
48
|
+
const { id } = parsedMetadata;
|
|
48
49
|
addExtensionToConf(projectName, {
|
|
49
50
|
extensionId: id,
|
|
50
51
|
extensionPath: file
|
|
@@ -24,28 +24,35 @@ async function deleteFolderRecursive(folderPath) {
|
|
|
24
24
|
}
|
|
25
25
|
throw new Error(`Failed to delete folder ${folderPath} after ${MAX_DELETE_FOLDER_RETRIES} retries`);
|
|
26
26
|
}
|
|
27
|
-
function
|
|
27
|
+
function isErrorWithMessage(error) {
|
|
28
|
+
return typeof error === "object" && error !== null && "message" in error && typeof error.message === "string";
|
|
29
|
+
}
|
|
30
|
+
async function killHttpMicroservice(microservice) {
|
|
28
31
|
console.log("killHttpMicroservice", { ...microservice });
|
|
29
32
|
const failMessage = `Failed to kill ${microservice.name}`;
|
|
30
33
|
async function do_kill() {
|
|
34
|
+
if (microservice.url === void 0) return;
|
|
31
35
|
try {
|
|
32
36
|
await fetch(microservice.url, { method: microservice.method });
|
|
33
37
|
} catch (error) {
|
|
34
|
-
|
|
38
|
+
const message = isErrorWithMessage(error) ? error.message : String(error);
|
|
39
|
+
console.log(`Expected error during kill of ${microservice.name}:`, message);
|
|
35
40
|
}
|
|
36
41
|
}
|
|
37
|
-
|
|
42
|
+
await pTimeout(do_kill(), {
|
|
38
43
|
milliseconds: 5e3,
|
|
39
44
|
message: failMessage
|
|
40
45
|
});
|
|
41
46
|
}
|
|
42
|
-
function killWebsocketMicroservice(microservice) {
|
|
47
|
+
async function killWebsocketMicroservice(microservice) {
|
|
43
48
|
console.log("killWebsocketMicroservice", { ...microservice });
|
|
44
49
|
const failMessage = `Failed to kill ${microservice.name}`;
|
|
45
50
|
const successMessage = `Disconnected from ${microservice.name} WebSocket server`;
|
|
46
|
-
function do_kill() {
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
async function do_kill() {
|
|
52
|
+
if (microservice.url === void 0) return;
|
|
53
|
+
const socketUrl = microservice.url;
|
|
54
|
+
await new Promise((resolve) => {
|
|
55
|
+
const socket = new WebSocket(socketUrl);
|
|
49
56
|
socket.on("open", () => {
|
|
50
57
|
console.log("Connected to WebSocket server");
|
|
51
58
|
socket.send(JSON.stringify({
|
|
@@ -78,7 +85,7 @@ function killWebsocketMicroservice(microservice) {
|
|
|
78
85
|
});
|
|
79
86
|
});
|
|
80
87
|
}
|
|
81
|
-
|
|
88
|
+
await pTimeout(do_kill(), {
|
|
82
89
|
milliseconds: 5e3,
|
|
83
90
|
message: failMessage
|
|
84
91
|
});
|
|
@@ -86,25 +93,31 @@ function killWebsocketMicroservice(microservice) {
|
|
|
86
93
|
async function killMicroservice(microservice) {
|
|
87
94
|
if (microservice.type === "back") await killHttpMicroservice(microservice);
|
|
88
95
|
else if (microservice.type === "viewer") await killWebsocketMicroservice(microservice);
|
|
89
|
-
else
|
|
96
|
+
else {
|
|
97
|
+
const exhaustiveCheck = microservice.type;
|
|
98
|
+
throw new Error(`Unknown microservice type: ${String(exhaustiveCheck)}`);
|
|
99
|
+
}
|
|
90
100
|
}
|
|
91
101
|
async function killMicroservices(microservices) {
|
|
92
102
|
console.log("killMicroservices", { microservices });
|
|
93
|
-
const results = await Promise.allSettled(microservices.map((microservice) =>
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if (microservice) microservices.splice(microservices.indexOf(microservice), 1);
|
|
98
|
-
}
|
|
103
|
+
const results = await Promise.allSettled(microservices.map(async (microservice) => {
|
|
104
|
+
await killMicroservice(microservice);
|
|
105
|
+
}));
|
|
106
|
+
return microservices.filter((_, index) => results[index]?.status !== "fulfilled");
|
|
99
107
|
}
|
|
100
108
|
function microservicesMetadatasPath(projectFolderPath) {
|
|
101
109
|
return path.join(projectFolderPath, "microservices.json");
|
|
102
110
|
}
|
|
111
|
+
function isMicroservicesMetadatas(value) {
|
|
112
|
+
return typeof value === "object" && value !== null && Array.isArray(value.microservices);
|
|
113
|
+
}
|
|
103
114
|
function projectMicroservices(projectFolderPath) {
|
|
104
115
|
console.log("projectMicroservices", { projectFolderPath });
|
|
105
116
|
const filePath = microservicesMetadatasPath(projectFolderPath);
|
|
106
117
|
if (!fs.existsSync(filePath)) fs.writeFileSync(filePath, JSON.stringify({ microservices: [] }, void 0, 2), "utf8");
|
|
107
|
-
|
|
118
|
+
const parsed = JSON.parse(fs.readFileSync(filePath, "utf8"));
|
|
119
|
+
if (!isMicroservicesMetadatas(parsed)) throw new Error(`Invalid microservices metadata file: ${filePath}`);
|
|
120
|
+
return parsed.microservices;
|
|
108
121
|
}
|
|
109
122
|
async function cleanupBackend(projectFolderPath) {
|
|
110
123
|
if (!fs.existsSync(projectFolderPath)) {
|
|
@@ -115,7 +128,8 @@ async function cleanupBackend(projectFolderPath) {
|
|
|
115
128
|
await deleteFolderRecursive(projectFolderPath);
|
|
116
129
|
}
|
|
117
130
|
function getMicroserviceByName(microservices, name) {
|
|
118
|
-
|
|
131
|
+
const found = microservices.find((microservice) => microservice.name === name);
|
|
132
|
+
return found === void 0 ? void 0 : { ...found };
|
|
119
133
|
}
|
|
120
134
|
//#endregion
|
|
121
135
|
export { cleanupBackend, deleteFolderRecursive, getMicroserviceByName, killMicroservice, microservicesMetadatasPath, projectMicroservices };
|
|
@@ -53,10 +53,7 @@ function requestConfig(parent, image, email, projectName) {
|
|
|
53
53
|
timeout: { seconds: 3600 },
|
|
54
54
|
containers: [{
|
|
55
55
|
image,
|
|
56
|
-
ports: [{
|
|
57
|
-
name: "h2c",
|
|
58
|
-
containerPort: 80
|
|
59
|
-
}],
|
|
56
|
+
ports: [{ containerPort: 80 }],
|
|
60
57
|
resources,
|
|
61
58
|
env: [{
|
|
62
59
|
name: "PARENT",
|
|
@@ -24,7 +24,9 @@ async function runScript(execPath, execName, args, expectedResponse, timeoutSeco
|
|
|
24
24
|
console.log(`[${child.name}] spawned, pid=${child.pid}`);
|
|
25
25
|
});
|
|
26
26
|
const controller = new AbortController();
|
|
27
|
-
const timer = setTimeout(() =>
|
|
27
|
+
const timer = setTimeout(() => {
|
|
28
|
+
controller.abort();
|
|
29
|
+
}, timeoutSeconds * MILLISECONDS_PER_SECOND);
|
|
28
30
|
if (typeof timer.unref === "function") timer.unref();
|
|
29
31
|
try {
|
|
30
32
|
const result = await waitForReady(child, expectedResponse, controller.signal);
|
|
@@ -42,7 +44,7 @@ function isPortInUseError(error) {
|
|
|
42
44
|
function backArgs(args, port) {
|
|
43
45
|
const { projectFolderPath } = args;
|
|
44
46
|
if (!projectFolderPath) throw new Error("projectFolderPath is required");
|
|
45
|
-
const uploadFolderPath = args.uploadFolderPath
|
|
47
|
+
const uploadFolderPath = args.uploadFolderPath !== void 0 && args.uploadFolderPath !== "" ? args.uploadFolderPath : path.join(projectFolderPath, "uploads");
|
|
46
48
|
const executableArgs = [
|
|
47
49
|
"--port",
|
|
48
50
|
String(port),
|
|
@@ -55,7 +57,7 @@ function backArgs(args, port) {
|
|
|
55
57
|
"--timeout",
|
|
56
58
|
"0"
|
|
57
59
|
];
|
|
58
|
-
if (process.env.NODE_ENV ===
|
|
60
|
+
if (process.env.NODE_ENV === void 0 || process.env.NODE_ENV === "development") executableArgs.push("--debug");
|
|
59
61
|
return executableArgs;
|
|
60
62
|
}
|
|
61
63
|
async function runBack(execName, execPath, args = DEFAULT_RUN_ARGS, attempts = 0) {
|
|
@@ -76,6 +78,7 @@ async function runBack(execName, execPath, args = DEFAULT_RUN_ARGS, attempts = 0
|
|
|
76
78
|
return await runBack(execName, execPath, args, attempts + 1);
|
|
77
79
|
}
|
|
78
80
|
}
|
|
81
|
+
throw new Error(`runBack failed to run ${execName}`);
|
|
79
82
|
}
|
|
80
83
|
async function runViewer(execName, execPath, args = DEFAULT_RUN_ARGS, attempts = 0) {
|
|
81
84
|
const { projectFolderPath } = args;
|
|
@@ -96,7 +99,7 @@ async function runViewer(execName, execPath, args = DEFAULT_RUN_ARGS, attempts =
|
|
|
96
99
|
return port;
|
|
97
100
|
} catch (error) {
|
|
98
101
|
if (!isPortInUseError(error)) {
|
|
99
|
-
console.log("
|
|
102
|
+
console.log("runViewer error", error);
|
|
100
103
|
throw error;
|
|
101
104
|
}
|
|
102
105
|
if (attempts <= MAX_PORT_RETRIES) {
|
|
@@ -104,6 +107,7 @@ async function runViewer(execName, execPath, args = DEFAULT_RUN_ARGS, attempts =
|
|
|
104
107
|
return await runViewer(execName, execPath, args, attempts + 1);
|
|
105
108
|
}
|
|
106
109
|
}
|
|
110
|
+
throw new Error(`runViewer failed to run ${execName}`);
|
|
107
111
|
}
|
|
108
112
|
async function runExtension(extensionId, execName, execPath, args = DEFAULT_RUN_ARGS, attempts = 0) {
|
|
109
113
|
let port = void 0;
|
|
@@ -117,7 +121,7 @@ async function runExtension(extensionId, execName, execPath, args = DEFAULT_RUN_
|
|
|
117
121
|
return port;
|
|
118
122
|
} catch (error) {
|
|
119
123
|
if (!isPortInUseError(error)) {
|
|
120
|
-
console.log("
|
|
124
|
+
console.log("runExtension error", error);
|
|
121
125
|
throw error;
|
|
122
126
|
}
|
|
123
127
|
if (attempts <= MAX_PORT_RETRIES) {
|
|
@@ -125,16 +129,24 @@ async function runExtension(extensionId, execName, execPath, args = DEFAULT_RUN_
|
|
|
125
129
|
return await runExtension(extensionId, execName, execPath, args, attempts + 1);
|
|
126
130
|
}
|
|
127
131
|
}
|
|
132
|
+
throw new Error(`runExtension failed to run ${extensionId}`);
|
|
128
133
|
}
|
|
129
134
|
function addMicroserviceMetadatas(projectFolderPath, serviceObj) {
|
|
130
135
|
const microservices = projectMicroservices(projectFolderPath);
|
|
136
|
+
let enriched = { ...serviceObj };
|
|
131
137
|
if (serviceObj.type === "back") {
|
|
132
138
|
const schema = back_schemas.opengeodeweb_back.kill;
|
|
133
|
-
serviceObj.url = `http://localhost:${serviceObj.port}/${schema.$id}`;
|
|
134
139
|
const [method] = schema.methods;
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
140
|
+
enriched = {
|
|
141
|
+
...enriched,
|
|
142
|
+
url: `http://localhost:${serviceObj.port}/${schema.$id}`,
|
|
143
|
+
method
|
|
144
|
+
};
|
|
145
|
+
} else if (serviceObj.type === "viewer") enriched = {
|
|
146
|
+
...enriched,
|
|
147
|
+
url: `ws://localhost:${serviceObj.port}/ws`
|
|
148
|
+
};
|
|
149
|
+
microservices.push(enriched);
|
|
138
150
|
fs.writeFileSync(microservicesMetadatasPath(projectFolderPath), JSON.stringify({ microservices }, void 0, 2));
|
|
139
151
|
}
|
|
140
152
|
//#endregion
|
|
@@ -40,11 +40,11 @@ function executablePath(execPath, execName) {
|
|
|
40
40
|
return osExecutableName;
|
|
41
41
|
}
|
|
42
42
|
const foundAtExecPath = findExecutableInDir(execPath, execName, osExecutableName);
|
|
43
|
-
if (foundAtExecPath) return foundAtExecPath;
|
|
43
|
+
if (foundAtExecPath !== void 0 && foundAtExecPath !== "") return foundAtExecPath;
|
|
44
44
|
if (mode === appMode.DESKTOP && nodeEnv === "production") {
|
|
45
|
-
if (resourcesPath) {
|
|
45
|
+
if (resourcesPath !== void 0 && resourcesPath !== "") {
|
|
46
46
|
const foundInResources = findExecutableInDir(resourcesPath, execName, osExecutableName);
|
|
47
|
-
if (foundInResources) return foundInResources;
|
|
47
|
+
if (foundInResources !== void 0 && foundInResources !== "") return foundInResources;
|
|
48
48
|
}
|
|
49
49
|
throw new Error(`Executable not found in execPath (${execPath}) or resourcesPath (${resourcesPath}): ${osExecutableName}`);
|
|
50
50
|
}
|
|
@@ -94,7 +94,7 @@ async function extensionFrontendPath(unzippedExtensionPath, frontendFile, rootPa
|
|
|
94
94
|
extensionId
|
|
95
95
|
});
|
|
96
96
|
const localFilePath = await lookForLocalExtensionDistPath(rootPath, extensionId.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join("-"), frontendFile);
|
|
97
|
-
if (localFilePath) return localFilePath;
|
|
97
|
+
if (localFilePath !== void 0 && localFilePath !== "") return localFilePath;
|
|
98
98
|
const unzippedfrontendFilePath = path.join(unzippedExtensionPath, frontendFile);
|
|
99
99
|
if (fs.existsSync(unzippedfrontendFilePath)) return unzippedfrontendFilePath;
|
|
100
100
|
throw new Error(`Failed to find ${unzippedfrontendFilePath}`);
|
|
@@ -8,14 +8,14 @@ import readline from "node:readline";
|
|
|
8
8
|
import { getPort } from "get-port-please";
|
|
9
9
|
//#region server/utils/scripts.ts
|
|
10
10
|
const MAX_ERROR_BUFFER_BYTES = 65536;
|
|
11
|
-
function getAvailablePort() {
|
|
12
|
-
return getPort({
|
|
11
|
+
async function getAvailablePort() {
|
|
12
|
+
return await getPort({
|
|
13
13
|
host: "localhost",
|
|
14
14
|
random: true
|
|
15
15
|
});
|
|
16
16
|
}
|
|
17
17
|
function commandExistsSync(execName) {
|
|
18
|
-
return (process.env.PATH
|
|
18
|
+
return (process.env.PATH ?? "").split(path.delimiter).some((directory) => {
|
|
19
19
|
const filePath = path.join(directory, execName);
|
|
20
20
|
return fs.existsSync(filePath) && fs.statSync(filePath).isFile();
|
|
21
21
|
});
|
|
@@ -24,7 +24,7 @@ const encoder = new TextEncoder();
|
|
|
24
24
|
function byteLength(str) {
|
|
25
25
|
return encoder.encode(str).byteLength;
|
|
26
26
|
}
|
|
27
|
-
function waitForReady(child, expectedResponse, signal) {
|
|
27
|
+
async function waitForReady(child, expectedResponse, signal) {
|
|
28
28
|
return new Promise((resolve, reject) => {
|
|
29
29
|
const readlineStdout = readline.createInterface({ input: child.stdout });
|
|
30
30
|
const readlineStderr = readline.createInterface({ input: child.stderr });
|
|
@@ -104,15 +104,15 @@ async function waitNuxt(nuxtProcess) {
|
|
|
104
104
|
console.log(`Nuxt process closed with code ${code}`);
|
|
105
105
|
});
|
|
106
106
|
for await (const [data] of on(nuxtProcess.stdout, "data")) {
|
|
107
|
-
const output = data
|
|
107
|
+
const output = String(data);
|
|
108
108
|
console.log("Nuxt STDOUT:", output.trim());
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
111
|
-
console.log("Nuxt listening on port",
|
|
109
|
+
const port = /Listening on http:\/\/\[::\]:(?<port>\d+)/u.exec(output)?.groups?.port;
|
|
110
|
+
if (port !== void 0) {
|
|
111
|
+
console.log("Nuxt listening on port", port);
|
|
112
112
|
nuxtProcess.stdout.on("data", (newData) => {
|
|
113
113
|
console.log("Nuxt STDOUT:", newData.toString().trim());
|
|
114
114
|
});
|
|
115
|
-
return
|
|
115
|
+
return port;
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
118
|
throw new Error("Nuxt process closed");
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { createServerWsRpcClient } from "./ws_client.js";
|
|
2
|
+
//#region server/utils/server_config.ts
|
|
3
|
+
const stringStorage = /* @__PURE__ */ new Map();
|
|
4
|
+
const booleanStorage = /* @__PURE__ */ new Map();
|
|
5
|
+
const clientStorage = /* @__PURE__ */ new Map();
|
|
6
|
+
function getAppBaseUrl() {
|
|
7
|
+
const value = stringStorage.get("APP_BASE_URL");
|
|
8
|
+
if (value === void 0) throw new Error("APP_BASE_URL is not set");
|
|
9
|
+
return value;
|
|
10
|
+
}
|
|
11
|
+
function setAppBaseUrl(baseUrl) {
|
|
12
|
+
stringStorage.set("APP_BASE_URL", baseUrl);
|
|
13
|
+
}
|
|
14
|
+
function getBackBaseUrl() {
|
|
15
|
+
const value = stringStorage.get("BACK_BASE_URL");
|
|
16
|
+
if (value === void 0) throw new Error("BACK_BASE_URL is not set");
|
|
17
|
+
return value;
|
|
18
|
+
}
|
|
19
|
+
function setBackBaseUrl(baseUrl) {
|
|
20
|
+
stringStorage.set("BACK_BASE_URL", baseUrl);
|
|
21
|
+
}
|
|
22
|
+
function getViewerBaseUrl() {
|
|
23
|
+
const value = stringStorage.get("VIEWER_BASE_URL");
|
|
24
|
+
if (value === void 0) throw new Error("VIEWER_BASE_URL is not set");
|
|
25
|
+
return value;
|
|
26
|
+
}
|
|
27
|
+
function setViewerBaseUrl(baseUrl) {
|
|
28
|
+
stringStorage.set("VIEWER_BASE_URL", baseUrl);
|
|
29
|
+
}
|
|
30
|
+
function getIsAppReady() {
|
|
31
|
+
return booleanStorage.get("IS_APP_READY") ?? false;
|
|
32
|
+
}
|
|
33
|
+
function setIsAppReady(isAppReady) {
|
|
34
|
+
booleanStorage.set("IS_APP_READY", isAppReady);
|
|
35
|
+
}
|
|
36
|
+
async function setViewerWebSocketClient(baseUrl) {
|
|
37
|
+
const client = createServerWsRpcClient(baseUrl);
|
|
38
|
+
client.onConnectionClose(() => {
|
|
39
|
+
if (clientStorage.get("VIEWER_CLIENT") === client) clientStorage.delete("VIEWER_CLIENT");
|
|
40
|
+
});
|
|
41
|
+
await client.ready;
|
|
42
|
+
clientStorage.set("VIEWER_CLIENT", client);
|
|
43
|
+
return client;
|
|
44
|
+
}
|
|
45
|
+
async function getViewerWebSocketClient() {
|
|
46
|
+
const viewerClient = clientStorage.get("VIEWER_CLIENT");
|
|
47
|
+
if (viewerClient !== void 0 && viewerClient.isOpen()) return viewerClient;
|
|
48
|
+
return await setViewerWebSocketClient(getViewerBaseUrl());
|
|
49
|
+
}
|
|
50
|
+
//#endregion
|
|
51
|
+
export { getAppBaseUrl, getBackBaseUrl, getIsAppReady, getViewerBaseUrl, getViewerWebSocketClient, setAppBaseUrl, setBackBaseUrl, setIsAppReady, setViewerBaseUrl, setViewerWebSocketClient };
|
|
@@ -3,6 +3,14 @@ import { v4 } from "uuid";
|
|
|
3
3
|
//#region server/utils/ws_client.ts
|
|
4
4
|
const HELLO_ID = "system:hello";
|
|
5
5
|
const HELLO_SECRET = "wslink-secret";
|
|
6
|
+
function isWsRpcMessage(value) {
|
|
7
|
+
return typeof value === "object" && value !== null;
|
|
8
|
+
}
|
|
9
|
+
function rawDataToString(raw) {
|
|
10
|
+
if (Buffer.isBuffer(raw)) return raw.toString();
|
|
11
|
+
if (Array.isArray(raw)) return Buffer.concat(raw).toString();
|
|
12
|
+
return Buffer.from(raw).toString();
|
|
13
|
+
}
|
|
6
14
|
function createServerWsRpcClient(baseUrl) {
|
|
7
15
|
const socket = new WebSocket(baseUrl);
|
|
8
16
|
const pending = /* @__PURE__ */ new Map();
|
|
@@ -17,10 +25,11 @@ function createServerWsRpcClient(baseUrl) {
|
|
|
17
25
|
}));
|
|
18
26
|
});
|
|
19
27
|
socket.on("message", (raw) => {
|
|
20
|
-
console.log("RAW WS MESSAGE:", raw.toString());
|
|
21
28
|
let message = void 0;
|
|
22
29
|
try {
|
|
23
|
-
|
|
30
|
+
const parsed = JSON.parse(rawDataToString(raw));
|
|
31
|
+
if (!isWsRpcMessage(parsed)) return;
|
|
32
|
+
message = parsed;
|
|
24
33
|
} catch {
|
|
25
34
|
return;
|
|
26
35
|
}
|
|
@@ -32,7 +41,7 @@ function createServerWsRpcClient(baseUrl) {
|
|
|
32
41
|
const entry = message.id === void 0 ? void 0 : pending.get(message.id);
|
|
33
42
|
if (!entry || message.id === void 0) return;
|
|
34
43
|
pending.delete(message.id);
|
|
35
|
-
if (message.error) entry.reject(new Error(message.error.message
|
|
44
|
+
if (message.error) entry.reject(new Error(message.error.message ?? "wslink RPC error"));
|
|
36
45
|
else entry.resolve(message.result);
|
|
37
46
|
});
|
|
38
47
|
socket.on("error", (error) => {
|
|
@@ -65,6 +74,11 @@ function createServerWsRpcClient(baseUrl) {
|
|
|
65
74
|
function close() {
|
|
66
75
|
socket.close();
|
|
67
76
|
}
|
|
77
|
+
function getConnection() {
|
|
78
|
+
return { getSession: () => ({ call: async (rpc, [params]) => {
|
|
79
|
+
return await call(rpc, params);
|
|
80
|
+
} }) };
|
|
81
|
+
}
|
|
68
82
|
function isOpen() {
|
|
69
83
|
return socket.readyState === WebSocket.OPEN;
|
|
70
84
|
}
|
|
@@ -77,6 +91,7 @@ function createServerWsRpcClient(baseUrl) {
|
|
|
77
91
|
return {
|
|
78
92
|
call,
|
|
79
93
|
close,
|
|
94
|
+
getConnection,
|
|
80
95
|
isOpen,
|
|
81
96
|
onConnectionClose,
|
|
82
97
|
onConnectionError,
|
|
@@ -1,46 +1,46 @@
|
|
|
1
1
|
import { fetchSchema } from "./utils/fetch_schema.js";
|
|
2
2
|
import { api } from "../opengeodeweb_front_schemas.js";
|
|
3
3
|
//#region shared/scripts.ts
|
|
4
|
-
function setAppBaseUrl(appBaseUrl) {
|
|
4
|
+
async function setAppBaseUrl(appBaseUrl) {
|
|
5
5
|
console.log("[API] setAppBaseUrl", appBaseUrl);
|
|
6
6
|
const schema = api.microservice.app.set_app_base_url;
|
|
7
|
-
return fetchSchema({
|
|
7
|
+
return await fetchSchema({
|
|
8
8
|
schema,
|
|
9
9
|
params: { baseUrl: appBaseUrl },
|
|
10
10
|
baseURL: appBaseUrl
|
|
11
11
|
});
|
|
12
12
|
}
|
|
13
|
-
function setBackBaseUrl(appBaseUrl, backBaseUrl) {
|
|
13
|
+
async function setBackBaseUrl(appBaseUrl, backBaseUrl) {
|
|
14
14
|
console.log("[API] setBackBaseUrl", appBaseUrl, backBaseUrl);
|
|
15
15
|
const schema = api.microservice.app.set_back_base_url;
|
|
16
|
-
return fetchSchema({
|
|
16
|
+
return await fetchSchema({
|
|
17
17
|
schema,
|
|
18
18
|
params: { baseUrl: backBaseUrl },
|
|
19
19
|
baseURL: appBaseUrl
|
|
20
20
|
});
|
|
21
21
|
}
|
|
22
|
-
function setViewerBaseUrl(appBaseUrl, viewerBaseUrl) {
|
|
22
|
+
async function setViewerBaseUrl(appBaseUrl, viewerBaseUrl) {
|
|
23
23
|
console.log("[API] setViewerBaseUrl", appBaseUrl, viewerBaseUrl);
|
|
24
24
|
const schema = api.microservice.app.set_viewer_base_url;
|
|
25
|
-
return fetchSchema({
|
|
25
|
+
return await fetchSchema({
|
|
26
26
|
schema,
|
|
27
27
|
params: { baseUrl: viewerBaseUrl },
|
|
28
28
|
baseURL: appBaseUrl
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
|
-
function setIsAppReady(appBaseUrl, isReady) {
|
|
31
|
+
async function setIsAppReady(appBaseUrl, isReady) {
|
|
32
32
|
console.log("[API] setIsAppReady", isReady);
|
|
33
33
|
const schema = api.microservice.app.set_is_app_ready;
|
|
34
|
-
return fetchSchema({
|
|
34
|
+
return await fetchSchema({
|
|
35
35
|
schema,
|
|
36
36
|
params: { isReady },
|
|
37
37
|
baseURL: appBaseUrl
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
function getIsAppReady(appBaseUrl) {
|
|
40
|
+
async function getIsAppReady(appBaseUrl) {
|
|
41
41
|
console.log("[API] getIsAppReady");
|
|
42
42
|
const schema = api.microservice.app.get_is_app_ready;
|
|
43
|
-
return fetchSchema({
|
|
43
|
+
return await fetchSchema({
|
|
44
44
|
schema,
|
|
45
45
|
baseURL: appBaseUrl
|
|
46
46
|
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import pTimeout from "p-timeout";
|
|
2
|
+
import "lodash";
|
|
3
|
+
//#region shared/utils/call_raw.ts
|
|
4
|
+
async function callClient({ rpc, params = {}, client }) {
|
|
5
|
+
if (globalThis.window !== void 0) return await client.getConnection().getSession().call(rpc, [params]);
|
|
6
|
+
return await client.call(rpc, params);
|
|
7
|
+
}
|
|
8
|
+
async function callRaw({ rpc, params = {}, client, timeout }, { request_error_function, response_function, response_error_function } = {}) {
|
|
9
|
+
async function performCall() {
|
|
10
|
+
try {
|
|
11
|
+
const response = await callClient({
|
|
12
|
+
rpc,
|
|
13
|
+
params,
|
|
14
|
+
client
|
|
15
|
+
});
|
|
16
|
+
if (response_function) await response_function(response);
|
|
17
|
+
return response;
|
|
18
|
+
} catch (error) {
|
|
19
|
+
if (request_error_function) await request_error_function(error);
|
|
20
|
+
if (response_error_function) await response_error_function(error);
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (timeout !== void 0 && timeout > 0) return await pTimeout(performCall(), {
|
|
25
|
+
milliseconds: timeout,
|
|
26
|
+
message: `${rpc}: Timed out after ${timeout}ms`
|
|
27
|
+
});
|
|
28
|
+
return await performCall();
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { callRaw };
|
|
@@ -2,7 +2,7 @@ import { validateSchema } from "./validate_schema.js";
|
|
|
2
2
|
import { callRaw } from "./call_raw.js";
|
|
3
3
|
//#region shared/utils/call_schema.ts
|
|
4
4
|
const ERROR_400 = 400;
|
|
5
|
-
function callSchema({ schema, params = {}, client, timeout }, { request_error_function, response_function, response_error_function, validation_error_function } = {}) {
|
|
5
|
+
async function callSchema({ schema, params = {}, client, timeout }, { request_error_function, response_function, response_error_function, validation_error_function } = {}) {
|
|
6
6
|
const { valid, error: schema_error } = validateSchema(schema, params);
|
|
7
7
|
if (!valid) {
|
|
8
8
|
if (process.env.NODE_ENV !== "production") console.log("Bad request", schema_error, schema, params);
|
|
@@ -13,7 +13,7 @@ function callSchema({ schema, params = {}, client, timeout }, { request_error_fu
|
|
|
13
13
|
});
|
|
14
14
|
throw new Error(`${schema.$id}: ${schema_error}`);
|
|
15
15
|
}
|
|
16
|
-
return callRaw({
|
|
16
|
+
return await callRaw({
|
|
17
17
|
rpc: schema.$id,
|
|
18
18
|
params,
|
|
19
19
|
client,
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { hasBody } from "./file.js";
|
|
2
|
+
import pTimeout from "p-timeout";
|
|
3
|
+
import { $fetch } from "ofetch";
|
|
4
|
+
import _ from "lodash";
|
|
5
|
+
//#region shared/utils/fetch_raw.ts
|
|
6
|
+
function resolveHeaders(headers, expectEvent) {
|
|
7
|
+
const resolvedHeaders = { ...headers };
|
|
8
|
+
if (expectEvent) {
|
|
9
|
+
const value = "text/event-stream";
|
|
10
|
+
if (_.isEmpty(resolvedHeaders)) resolvedHeaders.Accept = value;
|
|
11
|
+
else resolvedHeaders.Accept = `${resolvedHeaders.Accept}, ${value}`;
|
|
12
|
+
}
|
|
13
|
+
return resolvedHeaders;
|
|
14
|
+
}
|
|
15
|
+
async function performFetch({ route, method, params, baseURL, headers, max_retry, request_error_function, response_function, response_error_function }) {
|
|
16
|
+
return await $fetch(route, {
|
|
17
|
+
baseURL,
|
|
18
|
+
method,
|
|
19
|
+
headers,
|
|
20
|
+
...hasBody(params) ? { body: params } : {},
|
|
21
|
+
...max_retry === void 0 ? {} : { retry: max_retry },
|
|
22
|
+
async onRequestError({ error }) {
|
|
23
|
+
if (request_error_function) await request_error_function(error);
|
|
24
|
+
},
|
|
25
|
+
async onResponse({ response }) {
|
|
26
|
+
if (response.ok && response_function) await response_function(response._data);
|
|
27
|
+
},
|
|
28
|
+
async onResponseError({ response }) {
|
|
29
|
+
if (response_error_function) await response_error_function(response);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async function fetchRaw({ route, method, params = {}, baseURL, headers = {}, max_retry, timeout, expectEvent = false }, { request_error_function, response_function, response_error_function } = {}) {
|
|
34
|
+
const fetchOptions = {
|
|
35
|
+
route,
|
|
36
|
+
method,
|
|
37
|
+
params,
|
|
38
|
+
baseURL,
|
|
39
|
+
headers: resolveHeaders(headers, expectEvent),
|
|
40
|
+
max_retry,
|
|
41
|
+
request_error_function,
|
|
42
|
+
response_function,
|
|
43
|
+
response_error_function
|
|
44
|
+
};
|
|
45
|
+
if (timeout !== void 0 && timeout > 0) return await pTimeout(performFetch(fetchOptions), {
|
|
46
|
+
milliseconds: timeout,
|
|
47
|
+
message: `${route}: Timed out after ${timeout}ms`
|
|
48
|
+
});
|
|
49
|
+
return await performFetch(fetchOptions);
|
|
50
|
+
}
|
|
51
|
+
//#endregion
|
|
52
|
+
export { fetchRaw };
|
|
@@ -2,7 +2,7 @@ import { fetchRaw } from "./fetch_raw.js";
|
|
|
2
2
|
import { validateSchema } from "./validate_schema.js";
|
|
3
3
|
//#region shared/utils/fetch_schema.ts
|
|
4
4
|
const ERROR_400 = 400;
|
|
5
|
-
function fetchSchema({ schema, params = {}, baseURL, headers, timeout, expectEvent = false }, { request_error_function, response_function, response_error_function, validation_error_function } = {}) {
|
|
5
|
+
async function fetchSchema({ schema, params = {}, baseURL, headers, timeout, expectEvent = false }, { request_error_function, response_function, response_error_function, validation_error_function } = {}) {
|
|
6
6
|
const { valid, error: schema_error } = validateSchema(schema, params);
|
|
7
7
|
if (!valid) {
|
|
8
8
|
if (process.env.NODE_ENV !== "production") console.log("Bad request", schema_error, schema, params);
|
|
@@ -13,7 +13,7 @@ function fetchSchema({ schema, params = {}, baseURL, headers, timeout, expectEve
|
|
|
13
13
|
});
|
|
14
14
|
throw new Error(`${schema.$id}: ${schema_error}`);
|
|
15
15
|
}
|
|
16
|
-
return fetchRaw({
|
|
16
|
+
return await fetchRaw({
|
|
17
17
|
route: schema.$id,
|
|
18
18
|
method: schema.methods.find((method) => method !== "OPTIONS"),
|
|
19
19
|
params,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import _ from "lodash";
|
|
2
2
|
//#region shared/utils/file.ts
|
|
3
|
+
const BYTES_PER_KIBIBYTE = 1024;
|
|
4
|
+
const CHUNK_SIZE_BYTES = 8192 * BYTES_PER_KIBIBYTE;
|
|
3
5
|
function assertFile(file) {
|
|
4
6
|
console.log("[ASSERT_FILE] Asserting file", { file });
|
|
5
7
|
if (!(file instanceof File)) throw new Error("file must be an instance of File");
|
|
@@ -9,4 +11,4 @@ function hasBody(params) {
|
|
|
9
11
|
return !_.isEmpty(params);
|
|
10
12
|
}
|
|
11
13
|
//#endregion
|
|
12
|
-
export { assertFile, hasBody };
|
|
14
|
+
export { BYTES_PER_KIBIBYTE, CHUNK_SIZE_BYTES, assertFile, hasBody };
|