@geode/opengeodeweb-front 10.29.1 → 10.30.0-rc.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/app/components/ClippingPlaneCard.vue +112 -0
  2. package/app/components/ClippingPlanes.vue +238 -0
  3. package/app/components/Launcher.vue +1 -1
  4. package/app/components/ObjectSelector.vue +26 -76
  5. package/app/components/ToolPanel.vue +3 -2
  6. package/app/components/ViewToolbar.vue +12 -0
  7. package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +58 -20
  8. package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +42 -40
  9. package/app/composables/clipping_planes_widget.js +262 -0
  10. package/app/composables/hover_highlight.js +6 -0
  11. package/app/composables/project_manager.js +14 -11
  12. package/app/composables/use_overlapping_picker.js +15 -2
  13. package/app/stores/app.js +56 -11
  14. package/app/stores/back.js +10 -27
  15. package/app/stores/cloud.js +7 -1
  16. package/app/stores/data.js +32 -1
  17. package/app/stores/data_style.js +11 -0
  18. package/app/stores/hybrid_viewer.js +13 -5
  19. package/app/stores/infra.js +2 -7
  20. package/app/stores/viewer.js +9 -27
  21. package/app/utils/clipping_planes.js +110 -0
  22. package/app/utils/extension.js +30 -3
  23. package/app/utils/import_workflow.js +9 -12
  24. package/app/utils/log.js +18 -0
  25. package/app/utils/stores.js +32 -0
  26. package/internal/stores/hybrid_viewer.js +8 -63
  27. package/internal/stores/hybrid_viewer_brightness.js +62 -0
  28. package/internal/utils/api_fetch.js +27 -53
  29. package/internal/utils/upload_file.js +36 -29
  30. package/internal/utils/viewer_call.js +7 -2
  31. package/nuxt.config.js +2 -1
  32. package/package.json +4 -3
  33. package/server/api/local/{project_folder_path.post.js → app/project_folder_path.post.js} +1 -1
  34. package/server/api/local/{run_back.post.js → app/run_back.post.js} +1 -1
  35. package/server/api/local/{run_viewer.post.js → app/run_viewer.post.js} +1 -1
  36. package/server/api/{microservice → local}/extensions/upload.put.js +16 -37
  37. package/server/api/microservice/app/set_app_base_url.post.js +25 -0
  38. package/server/api/microservice/app/set_back_base_url.post.js +22 -0
  39. package/server/api/microservice/app/set_viewer_base_url.post.js +22 -0
  40. package/server/api/microservice/extensions/download.post.js +32 -0
  41. package/server/api/microservice/extensions/kill.post.js +3 -3
  42. package/server/api/microservice/extensions/run.post.js +5 -4
  43. package/server/api/serverless/{run_cloud.js → run_cloud.post.js} +1 -1
  44. package/{app/utils/config.js → server/utils/app_config.js} +28 -3
  45. package/{app/utils/local → server/utils}/path.js +1 -1
  46. package/{app/utils/local → server/utils}/scripts.js +5 -2
  47. package/server/utils/server_config.js +32 -0
  48. package/shared/scripts.js +56 -0
  49. package/shared/utils/fetch_raw.js +61 -0
  50. package/shared/utils/fetch_schema.js +46 -0
  51. package/shared/utils/file.js +16 -0
  52. package/shared/utils/response_handlers/load.js +74 -0
  53. package/tests/integration/setup.js +3 -3
  54. package/tests/integration/stores/data_style/mesh/cells.nuxt.test.js +1 -1
  55. package/tests/integration/stores/data_style/mesh/edges.nuxt.test.js +1 -1
  56. package/tests/integration/stores/data_style/mesh/index.nuxt.test.js +1 -1
  57. package/tests/integration/stores/data_style/mesh/points.nuxt.test.js +1 -1
  58. package/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js +1 -1
  59. package/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js +1 -1
  60. package/tests/integration/stores/data_style/model/blocks.nuxt.test.js +1 -1
  61. package/tests/integration/stores/data_style/model/corners.nuxt.test.js +1 -1
  62. package/tests/integration/stores/data_style/model/edges.nuxt.test.js +1 -1
  63. package/tests/integration/stores/data_style/model/index.nuxt.test.js +1 -1
  64. package/tests/integration/stores/data_style/model/lines.nuxt.test.js +1 -1
  65. package/tests/integration/stores/data_style/model/points.nuxt.test.js +1 -1
  66. package/tests/integration/stores/data_style/model/surfaces.nuxt.test.js +1 -1
  67. package/tests/integration/stores/viewer.nuxt.test.js +1 -1
  68. package/tests/unit/composables/project_manager.nuxt.test.js +14 -2
  69. package/tests/unit/composables/upload_file.nuxt.test.js +2 -2
  70. package/tests/unit/stores/back.nuxt.test.js +1 -1
  71. package/tests/unit/stores/cloud.nuxt.test.js +22 -20
  72. package/tests/unit/stores/data.nuxt.test.js +35 -0
  73. package/tests/unit/stores/infra.nuxt.test.js +13 -6
  74. package/tests/unit/stores/viewer.nuxt.test.js +1 -1
  75. package/tests/unit/utils/validate_schema.nuxt.test.js +1 -1
  76. package/tests/vitest.config.js +7 -5
  77. /package/server/api/local/{kill.post.js → app/kill.post.js} +0 -0
  78. /package/{app/utils/local → server/utils}/cleanup.js +0 -0
  79. /package/{app/utils/local → server/utils}/microservices.js +0 -0
  80. /package/{app → server}/utils/server.js +0 -0
  81. /package/{app/utils/local → shared}/app_mode.js +0 -0
  82. /package/{app → shared}/utils/validate_schema.js +0 -0
@@ -1,78 +1,52 @@
1
- import _ from "lodash";
1
+ import { endRequestLog, startRequestLog } from "@ogw_front/utils/log";
2
+ import { fetchSchema } from "@ogw_shared/utils/fetch_schema";
2
3
  import { useFeedbackStore } from "@ogw_front/stores/feedback";
3
- import { validate_schema } from "@ogw_front/utils/validate_schema";
4
-
5
- const ERROR_400 = 400;
6
4
 
7
5
  export function api_fetch(
8
6
  microservice,
9
- { schema, params, headers },
7
+ { schema, params = {}, headers = {} },
10
8
  { request_error_function, response_function, response_error_function, timeout } = {},
11
9
  ) {
10
+ console.log("[API] Fetching", microservice.base_url);
12
11
  const feedbackStore = useFeedbackStore();
13
-
14
- const body = params || {};
15
-
16
- const { valid, error: schema_error } = validate_schema(schema, body);
17
-
18
- if (!valid) {
19
- if (process.env.NODE_ENV !== "production") {
20
- console.log("Bad request", schema_error, schema, params);
21
- }
22
- feedbackStore.add_error(ERROR_400, schema.$id, "Bad request", schema_error);
23
- throw new Error(`${schema.$id}: ${schema_error}`);
24
- }
25
-
26
12
  microservice.start_request();
27
13
 
28
- const method = schema.methods.find((methodItem) => methodItem !== "OPTIONS");
29
- const request_options = {
30
- method,
31
- headers,
32
- };
33
- if (!_.isEmpty(body)) {
34
- request_options.body = body;
35
- }
36
-
37
- if (schema.max_retry) {
38
- request_options.max_retry = schema.max_retry;
39
- }
40
-
41
- function performFetch() {
42
- return $fetch(schema.$id, {
14
+ const requestStartingTime = startRequestLog(microservice, schema);
15
+ return fetchSchema(
16
+ {
17
+ schema,
43
18
  baseURL: microservice.base_url,
44
- ...request_options,
45
- onRequestError({ error }) {
19
+ params,
20
+ headers,
21
+ max_retry: schema.max_retry,
22
+ timeout,
23
+ },
24
+ {
25
+ request_error_function(error) {
46
26
  microservice.stop_request();
47
27
  feedbackStore.add_error(error.code, schema.$id, error.message, error.stack);
48
28
  if (request_error_function) {
49
29
  request_error_function(error);
50
30
  }
51
31
  },
52
- onResponse({ response }) {
53
- if (response.ok) {
54
- microservice.stop_request();
55
- if (response_function) {
56
- response_function(response._data);
57
- }
32
+ response_function(data) {
33
+ endRequestLog(microservice, schema, requestStartingTime);
34
+ microservice.stop_request();
35
+ if (response_function) {
36
+ response_function(data);
58
37
  }
59
38
  },
60
- onResponseError({ response }) {
39
+ response_error_function(response) {
61
40
  microservice.stop_request();
62
41
  feedbackStore.add_error(response.status, schema.$id, response.name, response.description);
63
42
  if (response_error_function) {
64
43
  response_error_function(response);
65
44
  }
66
45
  },
67
- });
68
- }
69
-
70
- if (timeout > 0) {
71
- return pTimeout(performCall(), {
72
- milliseconds: timeout,
73
- message: `${schema.$id}: Timed out after ${timeout}ms`,
74
- });
75
- }
76
-
77
- return performFetch();
46
+ validation_error_function({ code, name, error }) {
47
+ microservice.stop_request();
48
+ feedbackStore.add_error(code, schema.$id, name, error);
49
+ },
50
+ },
51
+ );
78
52
  }
@@ -1,50 +1,57 @@
1
+ import { fetchRaw } from "@ogw_shared/utils/fetch_raw.js";
1
2
  import { useFeedbackStore } from "@ogw_front/stores/feedback.js";
2
3
 
3
- async function upload_file(
4
+ function upload_file(
4
5
  microservice,
5
- { route, file },
6
+ { schema, file, params = {} },
6
7
  { request_error_function, response_function, response_error_function } = {},
7
8
  ) {
8
- console.log("[UPLOAD_FILE] Uploading file", { route, file });
9
+ console.log("[UPLOAD_FILE] Uploading file", { schema, file });
9
10
  const feedbackStore = useFeedbackStore();
11
+
10
12
  if (!(file instanceof File)) {
11
- throw new Error("file must be a instance of File");
13
+ return Promise.reject(new Error("file must be an instance of File"));
12
14
  }
13
15
 
14
16
  const body = new FormData();
17
+ for (const [key, value] of Object.entries(params)) {
18
+ body.append(key, value);
19
+ }
15
20
  body.append("file", file);
16
21
 
17
- const request_options = {
18
- method: "PUT",
19
- body,
20
- };
21
22
  microservice.start_request();
22
- return await $fetch(route, {
23
- baseURL: microservice.base_url || "",
24
- ...request_options,
25
- onRequestError({ error }) {
26
- microservice.stop_request();
27
- feedbackStore.add_error(error.code, route, error.message, error.stack);
28
- if (request_error_function) {
29
- request_error_function(error);
30
- }
23
+ const route = schema.$id;
24
+
25
+ return fetchRaw(
26
+ {
27
+ route,
28
+ method: schema.methods.find((method) => method !== "OPTIONS"),
29
+ params: body,
30
+ baseURL: microservice.base_url,
31
31
  },
32
- onResponse({ response }) {
33
- if (response.ok) {
32
+ {
33
+ request_error_function(error) {
34
+ microservice.stop_request();
35
+ feedbackStore.add_error(error.code, route, error.message, error.stack);
36
+ if (request_error_function) {
37
+ request_error_function(error);
38
+ }
39
+ },
40
+ response_function(data) {
34
41
  microservice.stop_request();
35
42
  if (response_function) {
36
- response_function(response);
43
+ response_function(data);
37
44
  }
38
- }
39
- },
40
- onResponseError({ response }) {
41
- microservice.stop_request();
42
- feedbackStore.add_error(response.status, route, response.name, response.description);
43
- if (response_error_function) {
44
- response_error_function(response);
45
- }
45
+ },
46
+ response_error_function(response) {
47
+ microservice.stop_request();
48
+ feedbackStore.add_error(response.status, route, response.name, response.description);
49
+ if (response_error_function) {
50
+ response_error_function(response);
51
+ }
52
+ },
46
53
  },
47
- });
54
+ );
48
55
  }
49
56
 
50
57
  export { upload_file };
@@ -1,6 +1,10 @@
1
+ // Third party imports
1
2
  import pTimeout from "p-timeout";
3
+
4
+ // Local imports
5
+ import { endRequestLog, startRequestLog } from "@ogw_front/utils/log";
2
6
  import { useFeedbackStore } from "@ogw_front/stores/feedback";
3
- import { validate_schema } from "@ogw_front/utils/validate_schema";
7
+ import { validate_schema } from "@ogw_shared/utils/validate_schema";
4
8
 
5
9
  const ERROR_400 = 400;
6
10
 
@@ -28,9 +32,10 @@ export function viewer_call(
28
32
  return;
29
33
  }
30
34
  microservice.start_request();
31
-
35
+ const requestStart = startRequestLog(microservice, schema);
32
36
  try {
33
37
  const value = await client.getConnection().getSession().call(schema.$id, [params]);
38
+ endRequestLog(microservice, schema, requestStart);
34
39
  if (response_function) {
35
40
  await response_function(value);
36
41
  }
package/nuxt.config.js CHANGED
@@ -27,8 +27,9 @@ export default defineNuxtConfig({
27
27
  alias: {
28
28
  "@ogw_front": path.resolve(__dirname, "app"),
29
29
  "@ogw_internal": path.resolve(__dirname, "internal"),
30
- "@ogw_server": path.resolve(__dirname, "server"),
31
30
  "@ogw_tests": path.resolve(__dirname, "tests"),
31
+ "@ogw_shared": path.resolve(__dirname, "shared"),
32
+ "@ogw_server": path.resolve(__dirname, "server"),
32
33
  },
33
34
 
34
35
  // ** Global CSS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geode/opengeodeweb-front",
3
- "version": "10.29.1",
3
+ "version": "10.30.0-rc.10",
4
4
  "description": "OpenSource Vue/Nuxt/Pinia/Vuetify framework for web applications",
5
5
  "homepage": "https://github.com/Geode-solutions/OpenGeodeWeb-Front",
6
6
  "bugs": {
@@ -34,8 +34,8 @@
34
34
  "build": ""
35
35
  },
36
36
  "dependencies": {
37
- "@geode/opengeodeweb-back": "latest",
38
- "@geode/opengeodeweb-viewer": "latest",
37
+ "@geode/opengeodeweb-back": "next",
38
+ "@geode/opengeodeweb-viewer": "next",
39
39
  "@google-cloud/run": "3.2.0",
40
40
  "@kitware/vtk.js": "33.3.0",
41
41
  "@mdi/font": "7.4.47",
@@ -62,6 +62,7 @@
62
62
  "sanitize-filename": "1.6.3",
63
63
  "sass": "1.87.0",
64
64
  "semver": "7.7.1",
65
+ "unstorage": "1.17.5",
65
66
  "uuid": "11.1.0",
66
67
  "vuetify": "3.12.5",
67
68
  "vuetify-nuxt-module": "0.18.7",
@@ -7,7 +7,7 @@ import { createError, defineEventHandler, readBody } from "h3";
7
7
  import {
8
8
  createPath,
9
9
  generateProjectFolderPath,
10
- } from "@geode/opengeodeweb-front/app/utils/local/path.js";
10
+ } from "@geode/opengeodeweb-front/server/utils/path.js";
11
11
 
12
12
  export default defineEventHandler(async (event) => {
13
13
  try {
@@ -7,7 +7,7 @@ import { createError, defineEventHandler, readBody } from "h3";
7
7
  import {
8
8
  addMicroserviceMetadatas,
9
9
  runBack,
10
- } from "@geode/opengeodeweb-front/app/utils/local/microservices.js";
10
+ } from "@geode/opengeodeweb-front/server/utils/microservices.js";
11
11
 
12
12
  export default defineEventHandler(async (event) => {
13
13
  try {
@@ -7,7 +7,7 @@ import { createError, defineEventHandler, readBody } from "h3";
7
7
  import {
8
8
  addMicroserviceMetadatas,
9
9
  runViewer,
10
- } from "@geode/opengeodeweb-front/app/utils/local/microservices.js";
10
+ } from "@geode/opengeodeweb-front/server/utils/microservices.js";
11
11
 
12
12
  export default defineEventHandler(async (event) => {
13
13
  try {
@@ -2,27 +2,26 @@
2
2
  import { finished, pipeline } from "node:stream/promises";
3
3
  import { Readable } from "node:stream";
4
4
  import fs from "node:fs";
5
- import path from "node:path";
6
5
 
7
6
  // Third party imports
8
7
  import { createError, defineEventHandler, getRequestHeaders, getRequestWebStream } from "h3";
9
- import StreamZip from "node-stream-zip";
10
8
  import busboy from "busboy";
11
- import sanitize from "sanitize-filename";
12
9
 
13
10
  // Local imports
14
- import { addExtensionToConf, confFolderPath } from "@geode/opengeodeweb-front/app/utils/config.js";
11
+ import {
12
+ registerExtensionFile,
13
+ targetExtensionFilePath,
14
+ } from "@geode/opengeodeweb-front/server/utils/app_config.js";
15
15
 
16
16
  const CODE_201 = 201;
17
- const FILE_SIZE_LIMIT = 107_374_182;
17
+ const BYTES_PER_KIBIBYTE = 1024;
18
+ const MAX_FILE_MEGABYTES = 500;
19
+ const FILE_SIZE_LIMIT = MAX_FILE_MEGABYTES * BYTES_PER_KIBIBYTE * BYTES_PER_KIBIBYTE;
18
20
 
19
21
  export default defineEventHandler(async (event) => {
20
- const projectName = "vease";
21
22
  const writePromises = [];
22
23
  const savedFiles = [];
23
24
 
24
- const configFolderPath = confFolderPath(projectName);
25
-
26
25
  const busboyInstance = busboy({
27
26
  headers: getRequestHeaders(event),
28
27
  limits: {
@@ -30,6 +29,13 @@ export default defineEventHandler(async (event) => {
30
29
  files: 1,
31
30
  },
32
31
  });
32
+ let projectName = "";
33
+ busboyInstance.on("field", (name, value) => {
34
+ console.log(`Field ${name}: ${value}`);
35
+ if (name === "projectName") {
36
+ projectName = value;
37
+ }
38
+ });
33
39
 
34
40
  busboyInstance.on("file", (fieldname, fileStream, info) => {
35
41
  if (fieldname !== "file") {
@@ -37,57 +43,30 @@ export default defineEventHandler(async (event) => {
37
43
  fileStream.resume();
38
44
  return;
39
45
  }
40
-
41
- const safeFilename = sanitize(info.filename);
42
- const targetPath = path.join(configFolderPath, safeFilename);
43
-
46
+ const targetPath = targetExtensionFilePath(projectName, info.filename);
44
47
  const writePromise = (async () => {
45
48
  const writeStream = fs.createWriteStream(targetPath);
46
49
  await pipeline(fileStream, writeStream);
47
50
  savedFiles.push(targetPath);
48
51
  console.log("File written:", targetPath);
49
52
  })();
50
-
51
53
  writePromises.push(writePromise);
52
54
  fileStream.on("limit", () => busboyInstance.destroy(new Error("File too large")));
53
55
  });
54
56
 
55
- busboyInstance.on("field", (name, value) => {
56
- console.log(`Field ${name}: ${value}`);
57
- });
58
-
59
57
  busboyInstance.on("filesLimit", () => busboyInstance.destroy(new Error("Too many files")));
60
58
  busboyInstance.on("partsLimit", () => busboyInstance.destroy(new Error("Too many parts")));
61
59
 
62
60
  const webStream = getRequestWebStream(event);
63
61
  Readable.fromWeb(webStream).pipe(busboyInstance);
64
62
  await finished(busboyInstance);
65
-
66
63
  if (writePromises.length > 0) {
67
64
  await Promise.all(writePromises);
68
65
  console.log("All disk writes completed");
69
66
  }
70
-
71
67
  if (savedFiles.length === 0) {
72
68
  throw createError({ statusCode: 400, message: "No file received" });
73
69
  }
74
-
75
- await Promise.all(
76
- savedFiles.map(async (file) => {
77
- const StreamZipAsync = StreamZip.async;
78
- const zip = new StreamZipAsync({
79
- file,
80
- storeEntries: true,
81
- });
82
- const metadataJson = await zip.entryData("metadata.json");
83
- const metadata = JSON.parse(metadataJson);
84
- const { id } = metadata;
85
- await addExtensionToConf(projectName, {
86
- extensionId: id,
87
- extensionPath: file,
88
- });
89
- }),
90
- );
91
-
70
+ await Promise.all(savedFiles.map(async (file) => await registerExtensionFile(projectName, file)));
92
71
  return { statusCode: CODE_201 };
93
72
  });
@@ -0,0 +1,25 @@
1
+ // Third party imports
2
+ import { createError, defineEventHandler, readBody } from "h3";
3
+
4
+ // Local imports
5
+ import { setAppBaseUrl } from "@geode/opengeodeweb-front/server/utils/server_config.js";
6
+
7
+ export default defineEventHandler(async (event) => {
8
+ try {
9
+ const { baseUrl } = await readBody(event);
10
+ if (!baseUrl) {
11
+ throw createError({ statusCode: 400, statusMessage: "baseUrl is required" });
12
+ }
13
+
14
+ await setAppBaseUrl(baseUrl);
15
+ console.log(`Updated APP_BASE_URL to ${baseUrl}`);
16
+
17
+ return { statusCode: 200, baseUrl };
18
+ } catch (error) {
19
+ console.log(error);
20
+ throw createError({
21
+ statusCode: error.statusCode,
22
+ statusMessage: error.statusMessage ?? error.message,
23
+ });
24
+ }
25
+ });
@@ -0,0 +1,22 @@
1
+ // Third party imports
2
+ import { createError, defineEventHandler, readBody } from "h3";
3
+
4
+ // Local imports
5
+ import { setBackBaseUrl } from "@geode/opengeodeweb-front/server/utils/server_config.js";
6
+
7
+ export default defineEventHandler(async (event) => {
8
+ try {
9
+ const { baseUrl } = await readBody(event);
10
+ if (!baseUrl) {
11
+ throw createError({ statusCode: 400, statusMessage: "baseUrl is required" });
12
+ }
13
+ await setBackBaseUrl(baseUrl);
14
+ return { statusCode: 200, baseUrl };
15
+ } catch (error) {
16
+ console.log(error);
17
+ throw createError({
18
+ statusCode: error.statusCode,
19
+ statusMessage: error.message,
20
+ });
21
+ }
22
+ });
@@ -0,0 +1,22 @@
1
+ // Third party imports
2
+ import { createError, defineEventHandler, readBody } from "h3";
3
+
4
+ // Local imports
5
+ import { setViewerBaseUrl } from "@geode/opengeodeweb-front/server/utils/server_config.js";
6
+
7
+ export default defineEventHandler(async (event) => {
8
+ try {
9
+ const { baseUrl } = await readBody(event);
10
+ if (!baseUrl) {
11
+ throw createError({ statusCode: 400, statusMessage: "baseUrl is required" });
12
+ }
13
+ await setViewerBaseUrl(baseUrl);
14
+ return { statusCode: 200, baseUrl };
15
+ } catch (error) {
16
+ console.log(error);
17
+ throw createError({
18
+ statusCode: error.statusCode,
19
+ statusMessage: error.message,
20
+ });
21
+ }
22
+ });
@@ -0,0 +1,32 @@
1
+ // Node imports
2
+ import { promises as fs } from "node:fs";
3
+
4
+ // Third party imports
5
+ import { createError, defineEventHandler, readBody } from "h3";
6
+
7
+ // Local imports
8
+ import {
9
+ registerExtensionFile,
10
+ targetExtensionFilePath,
11
+ } from "@geode/opengeodeweb-front/server/utils/app_config.js";
12
+
13
+ export default defineEventHandler(async (event) => {
14
+ try {
15
+ const body = await readBody(event);
16
+ const { projectName, url, extensionFileName } = body;
17
+ console.log({ projectName, url, extensionFileName });
18
+ const fileBuffer = await fetch(url).then((file) => file.arrayBuffer());
19
+ const filePath = targetExtensionFilePath(projectName, extensionFileName);
20
+ await fs.writeFile(filePath, Buffer.from(fileBuffer));
21
+ await registerExtensionFile(projectName, filePath);
22
+ return {
23
+ statusCode: 200,
24
+ };
25
+ } catch (error) {
26
+ console.error("Error downloading extension:", error);
27
+ throw createError({
28
+ statusCode: 500,
29
+ statusMessage: error.message,
30
+ });
31
+ }
32
+ });
@@ -9,9 +9,9 @@ import {
9
9
  getMicroserviceByName,
10
10
  killMicroservice,
11
11
  projectMicroservices,
12
- } from "@geode/opengeodeweb-front/app/utils/local/cleanup.js";
13
- import { extensionFolderPath } from "@geode/opengeodeweb-front/app/utils/local/path.js";
14
- import { removeExtensionFromConf } from "@geode/opengeodeweb-front/app/utils/config.js";
12
+ } from "@geode/opengeodeweb-front/server/utils/cleanup.js";
13
+ import { extensionFolderPath } from "@geode/opengeodeweb-front/server/utils/path.js";
14
+ import { removeExtensionFromConf } from "@geode/opengeodeweb-front/server/utils/app_config.js";
15
15
 
16
16
  export default defineEventHandler(async (event) => {
17
17
  try {
@@ -9,17 +9,18 @@ import { createError, defineEventHandler, readBody } from "h3";
9
9
  import {
10
10
  addMicroserviceMetadatas,
11
11
  runBack,
12
- } from "@geode/opengeodeweb-front/app/utils/local/microservices.js";
12
+ } from "@geode/opengeodeweb-front/server/utils/microservices.js";
13
13
  import {
14
14
  executableName,
15
15
  extensionFolderPath,
16
16
  extensionFrontendPath,
17
- } from "@geode/opengeodeweb-front/app/utils/local/path.js";
18
- import { extensionsConf } from "@geode/opengeodeweb-front/app/utils/config.js";
19
- import { unzipFile } from "@geode/opengeodeweb-front/app/utils/server.js";
17
+ } from "@geode/opengeodeweb-front/server/utils/path.js";
18
+ import { extensionsConf } from "@geode/opengeodeweb-front/server/utils/app_config.js";
19
+ import { unzipFile } from "@geode/opengeodeweb-front/server/utils/server.js";
20
20
 
21
21
  export default defineEventHandler(async (event) => {
22
22
  try {
23
+ console.log("NITRO: runExtensions", event);
23
24
  const body = await readBody(event);
24
25
  const { projectFolderPath, projectName } = body;
25
26
  const extensionsConfig = extensionsConf(projectName);
@@ -6,7 +6,7 @@ import { GoogleAuth } from "google-auth-library";
6
6
  import { ServicesClient } from "@google-cloud/run";
7
7
 
8
8
  // Local imports
9
- import { artifactImage, requestConfig } from "@ogw_server/utils/cloud";
9
+ import { artifactImage, requestConfig } from "@geode/opengeodeweb-front/server/utils/cloud";
10
10
 
11
11
  export default defineEventHandler(async (event) => {
12
12
  try {
@@ -4,6 +4,8 @@ import { unlink } from "node:fs";
4
4
 
5
5
  // Third party imports
6
6
  import Conf from "conf";
7
+ import StreamZip from "node-stream-zip";
8
+ import sanitize from "sanitize-filename";
7
9
 
8
10
  // Local imports
9
11
 
@@ -18,6 +20,12 @@ function confFolderPath(projectName) {
18
20
  return path.dirname(projectConfig.path);
19
21
  }
20
22
 
23
+ function targetExtensionFilePath(projectName, filename) {
24
+ const safeFilename = sanitize(filename);
25
+ const targetPath = path.join(confFolderPath(projectName), safeFilename);
26
+ return targetPath;
27
+ }
28
+
21
29
  function extensionsConf(projectName) {
22
30
  const projectConfig = projectConf(projectName);
23
31
  if (!projectConfig.has("extensions")) {
@@ -51,11 +59,28 @@ function extensionPathFromConf(projectName, extensionId) {
51
59
  return projectConfig.get(`extensions.${extensionId}.path`);
52
60
  }
53
61
 
62
+ async function registerExtensionFile(projectName, file) {
63
+ const StreamZipAsync = StreamZip.async;
64
+ const zip = new StreamZipAsync({
65
+ file,
66
+ storeEntries: true,
67
+ });
68
+ const metadataJson = await zip.entryData("metadata.json");
69
+ const metadata = JSON.parse(metadataJson);
70
+ const { id } = metadata;
71
+ addExtensionToConf(projectName, {
72
+ extensionId: id,
73
+ extensionPath: file,
74
+ });
75
+ }
76
+
54
77
  export {
78
+ addExtensionToConf,
55
79
  confFolderPath,
56
- projectConf,
80
+ extensionPathFromConf,
57
81
  extensionsConf,
58
- addExtensionToConf,
82
+ projectConf,
83
+ registerExtensionFile,
59
84
  removeExtensionFromConf,
60
- extensionPathFromConf,
85
+ targetExtensionFilePath,
61
86
  };
@@ -8,7 +8,7 @@ import { setTimeout } from "node:timers/promises";
8
8
  import { v4 as uuidv4 } from "uuid";
9
9
 
10
10
  // Local imports
11
- import { appMode } from "./app_mode.js";
11
+ import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js";
12
12
  import { commandExistsSync } from "./scripts.js";
13
13
 
14
14
  function findExecutableInDir(baseDir, execName, osExecutableName) {
@@ -9,7 +9,8 @@ import readline from "node:readline";
9
9
  import { getPort } from "get-port-please";
10
10
 
11
11
  // Local imports
12
- import { appMode } from "./app_mode.js";
12
+ import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js";
13
+ import { setAppBaseUrl } from "@geode/opengeodeweb-front/shared/scripts.js";
13
14
 
14
15
  const BYTES_PER_KIBIBYTE = 1024;
15
16
  const MAX_ERROR_BUFFER_KIBIBYTES = 64;
@@ -164,7 +165,9 @@ async function runBrowser(scriptName) {
164
165
  PORT: port,
165
166
  },
166
167
  });
167
- return await waitNuxt(nuxtProcess);
168
+ await waitNuxt(nuxtProcess);
169
+ await setAppBaseUrl(`http://localhost:${port}`);
170
+ return port;
168
171
  }
169
172
 
170
173
  export { commandExistsSync, getAvailablePort, runBrowser, waitForReady };
@@ -0,0 +1,32 @@
1
+ import { createStorage, prefixStorage } from "unstorage";
2
+
3
+ const storage = createStorage();
4
+ const config = prefixStorage(storage, "config");
5
+
6
+ function getAppBaseUrl() {
7
+ return config.getItem("APP_BASE_URL");
8
+ }
9
+ function setAppBaseUrl(baseUrl) {
10
+ return config.setItem("APP_BASE_URL", baseUrl);
11
+ }
12
+ function getBackBaseUrl() {
13
+ return config.getItem("BACK_BASE_URL");
14
+ }
15
+ function setBackBaseUrl(baseUrl) {
16
+ return config.setItem("BACK_BASE_URL", baseUrl);
17
+ }
18
+ function getViewerBaseUrl() {
19
+ return config.getItem("VIEWER_BASE_URL");
20
+ }
21
+ function setViewerBaseUrl(baseUrl) {
22
+ return config.setItem("VIEWER_BASE_URL", baseUrl);
23
+ }
24
+
25
+ export {
26
+ getAppBaseUrl,
27
+ setAppBaseUrl,
28
+ getBackBaseUrl,
29
+ getViewerBaseUrl,
30
+ setBackBaseUrl,
31
+ setViewerBaseUrl,
32
+ };