From 71e18effad43a1e9b38906928d31b34d9e0c5efd Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 10:17:36 +0200 Subject: [PATCH 01/22] feat(Extension): allows cloud extension download --- app/stores/app.js | 4 +- app/stores/back.js | 2 +- app/stores/viewer.js | 2 +- app/utils/config.js | 14 +++-- app/utils/extension.js | 51 +++++++++++++++++-- server/api/local/{ => app}/kill.post.js | 0 .../{ => app}/project_folder_path.post.js | 0 server/api/local/{ => app}/run_back.post.js | 0 server/api/local/{ => app}/run_viewer.post.js | 0 .../extensions/upload.put.js | 38 +++----------- .../microservice/extensions/download.post.js | 30 +++++++++++ 11 files changed, 99 insertions(+), 42 deletions(-) rename server/api/local/{ => app}/kill.post.js (100%) rename server/api/local/{ => app}/project_folder_path.post.js (100%) rename server/api/local/{ => app}/run_back.post.js (100%) rename server/api/local/{ => app}/run_viewer.post.js (100%) rename server/api/{microservice => local}/extensions/upload.put.js (67%) create mode 100644 server/api/microservice/extensions/download.post.js diff --git a/app/stores/app.js b/app/stores/app.js index 4051efe68..2222f8e4d 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -196,7 +196,7 @@ export const useAppStore = defineStore("app", () => { } function upload(file, callbacks = {}) { - const route = "/api/microservice/extensions/upload"; + const route = "/api/local/extensions/upload"; const store = useAppStore(); return upload_file( store, @@ -244,7 +244,7 @@ export const useAppStore = defineStore("app", () => { function createProjectFolder() { const { PROJECT } = useRuntimeConfig().public; const schema = { - $id: "/api/local/project_folder_path", + $id: "/api/local/app/project_folder_path", methods: ["POST"], type: "object", properties: { PROJECT: { type: "string" } }, diff --git a/app/stores/back.js b/app/stores/back.js index e1a915422..0245ef300 100644 --- a/app/stores/back.js +++ b/app/stores/back.js @@ -81,7 +81,7 @@ export const useBackStore = defineStore("back", { const appStore = useAppStore(); const { COMMAND_BACK, NUXT_ROOT_PATH } = useRuntimeConfig().public; const schema = { - $id: "/api/local/run_back", + $id: "/api/local/app/run_back", methods: ["POST"], type: "object", properties: { diff --git a/app/stores/viewer.js b/app/stores/viewer.js index 51d702d1b..88ab5e65a 100644 --- a/app/stores/viewer.js +++ b/app/stores/viewer.js @@ -133,7 +133,7 @@ export const useViewerStore = defineStore( const { COMMAND_VIEWER, NUXT_ROOT_PATH } = useRuntimeConfig().public; const schema = { - $id: "/api/local/run_viewer", + $id: "/api/local/app/run_viewer", methods: ["POST"], type: "object", properties: { COMMAND_VIEWER: { type: "string" }, NUXT_ROOT_PATH: { type: "string" } }, diff --git a/app/utils/config.js b/app/utils/config.js index 49a517166..1842d7d4a 100644 --- a/app/utils/config.js +++ b/app/utils/config.js @@ -4,6 +4,7 @@ import { unlink } from "node:fs"; // Third party imports import Conf from "conf"; +import sanitize from "sanitize-filename"; // Local imports @@ -18,6 +19,12 @@ function confFolderPath(projectName) { return path.dirname(projectConfig.path); } +function targetExtensionFilePath(projectName, filename) { + const safeFilename = sanitize(filename); + const targetPath = path.join(configFolderPath(projectName), safeFilename); + return targetPath; +} + function extensionsConf(projectName) { const projectConfig = projectConf(projectName); if (!projectConfig.has("extensions")) { @@ -52,10 +59,11 @@ function extensionPathFromConf(projectName, extensionId) { } export { + addExtensionToConf, confFolderPath, - projectConf, + extensionPathFromConf, extensionsConf, - addExtensionToConf, + projectConf, removeExtensionFromConf, - extensionPathFromConf, + targetExtensionFilePath, }; diff --git a/app/utils/extension.js b/app/utils/extension.js index 3afdcf88d..7b9e48be4 100644 --- a/app/utils/extension.js +++ b/app/utils/extension.js @@ -2,16 +2,23 @@ // Third party imports import _ from "lodash"; +import StreamZip from "node-stream-zip"; // Local imports import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; +import { addExtensionToConf } from "@geode/opengeodeweb-front/app/utils/config.js"; async function importExtensionFile(file) { await uploadExtension(file); return registerRunningExtensions(); } +async function importExtensionURL(url) { + await downloadExtension(url); + return registerRunningExtensions(); +} + async function registerRunningExtensions() { const appStore = useAppStore(); const infraStore = useInfraStore(); @@ -42,6 +49,21 @@ async function registerRunningExtensions() { ); } +async function registerExtensionFile(file) { + const StreamZipAsync = StreamZip.async; + const zip = new StreamZipAsync({ + file, + storeEntries: true, + }); + const metadataJson = await zip.entryData("metadata.json"); + const metadata = JSON.parse(metadataJson); + const { id } = metadata; + addExtensionToConf(projectName, { + extensionId: id, + extensionPath: file, + }); +} + async function unloadExtension(extensionId) { const appStore = useAppStore(); console.log("[ExtensionManager] Unloading extension:", extensionId); @@ -74,6 +96,27 @@ async function uploadExtension(file) { await appStore.upload(file); } +async function downloadExtension({ url, extensionFileName }) { + const appStore = useAppStore(); + const params = { projectFolderPath, projectName, url, extensionFileName }; + + const schema = { + $id: "/api/microservice/extensions/download", + methods: ["POST"], + type: "object", + properties: { + extensionFileName: { type: "string" }, + projectFolderPath: { type: "string" }, + projectName: { type: "string" }, + url: { type: "string" }, + }, + required: ["projectFolderPath", "projectName"], + additionalProperties: false, + }; + + return appStore.request({ schema, params }); +} + function runExtensions() { const appStore = useAppStore(); const { projectFolderPath } = appStore; @@ -121,9 +164,11 @@ function killExtension(extensionId) { export { importExtensionFile, - unloadExtension, - uploadExtension, + importExtensionURL, + killExtension, + registerExtensionFile, registerRunningExtensions, runExtensions, - killExtension, + unloadExtension, + uploadExtension, }; diff --git a/server/api/local/kill.post.js b/server/api/local/app/kill.post.js similarity index 100% rename from server/api/local/kill.post.js rename to server/api/local/app/kill.post.js diff --git a/server/api/local/project_folder_path.post.js b/server/api/local/app/project_folder_path.post.js similarity index 100% rename from server/api/local/project_folder_path.post.js rename to server/api/local/app/project_folder_path.post.js diff --git a/server/api/local/run_back.post.js b/server/api/local/app/run_back.post.js similarity index 100% rename from server/api/local/run_back.post.js rename to server/api/local/app/run_back.post.js diff --git a/server/api/local/run_viewer.post.js b/server/api/local/app/run_viewer.post.js similarity index 100% rename from server/api/local/run_viewer.post.js rename to server/api/local/app/run_viewer.post.js diff --git a/server/api/microservice/extensions/upload.put.js b/server/api/local/extensions/upload.put.js similarity index 67% rename from server/api/microservice/extensions/upload.put.js rename to server/api/local/extensions/upload.put.js index 5a812e9e4..cd72087a9 100644 --- a/server/api/microservice/extensions/upload.put.js +++ b/server/api/local/extensions/upload.put.js @@ -2,27 +2,24 @@ import { finished, pipeline } from "node:stream/promises"; import { Readable } from "node:stream"; import fs from "node:fs"; -import path from "node:path"; // Third party imports import { createError, defineEventHandler, getRequestHeaders, getRequestWebStream } from "h3"; -import StreamZip from "node-stream-zip"; import busboy from "busboy"; -import sanitize from "sanitize-filename"; // Local imports -import { addExtensionToConf, confFolderPath } from "@geode/opengeodeweb-front/app/utils/config.js"; +import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; +import { registerExtensionFile } from "@geode/opengeodeweb-front/app/utils/extension.js"; const CODE_201 = 201; const FILE_SIZE_LIMIT = 107_374_182; export default defineEventHandler(async (event) => { - const projectName = "vease"; + const body = await readBody(event); + const { projectName } = body; const writePromises = []; const savedFiles = []; - const configFolderPath = confFolderPath(projectName); - const busboyInstance = busboy({ headers: getRequestHeaders(event), limits: { @@ -37,17 +34,13 @@ export default defineEventHandler(async (event) => { fileStream.resume(); return; } - - const safeFilename = sanitize(info.filename); - const targetPath = path.join(configFolderPath, safeFilename); - + const targetPath = targetExtensionFilePath(projectName, info.filename); const writePromise = (async () => { const writeStream = fs.createWriteStream(targetPath); await pipeline(fileStream, writeStream); savedFiles.push(targetPath); console.log("File written:", targetPath); })(); - writePromises.push(writePromise); fileStream.on("limit", () => busboyInstance.destroy(new Error("File too large"))); }); @@ -62,32 +55,13 @@ export default defineEventHandler(async (event) => { const webStream = getRequestWebStream(event); Readable.fromWeb(webStream).pipe(busboyInstance); await finished(busboyInstance); - if (writePromises.length > 0) { await Promise.all(writePromises); console.log("All disk writes completed"); } - if (savedFiles.length === 0) { throw createError({ statusCode: 400, message: "No file received" }); } - - await Promise.all( - savedFiles.map(async (file) => { - const StreamZipAsync = StreamZip.async; - const zip = new StreamZipAsync({ - file, - storeEntries: true, - }); - const metadataJson = await zip.entryData("metadata.json"); - const metadata = JSON.parse(metadataJson); - const { id } = metadata; - await addExtensionToConf(projectName, { - extensionId: id, - extensionPath: file, - }); - }), - ); - + await Promise.all(savedFiles.map(async (file) => await registerExtensionFile(file))); return { statusCode: CODE_201 }; }); diff --git a/server/api/microservice/extensions/download.post.js b/server/api/microservice/extensions/download.post.js new file mode 100644 index 000000000..ac8fd1be1 --- /dev/null +++ b/server/api/microservice/extensions/download.post.js @@ -0,0 +1,30 @@ +// Node imports +import { promises as fs } from "node:fs"; + +// Third party imports +import { createError, defineEventHandler, readBody } from "h3"; + +// Local imports +import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; +import { registerExtensionFile } from "@geode/opengeodeweb-front/app/utils/extension.js"; + +export default defineEventHandler(async (event) => { + try { + const body = await readBody(event); + const { projectName, url, extensionFileName } = body; + console.log({ projectName, url, extensionFileName }); + const fileBuffer = await fetch(url).then((file) => file.arrayBuffer()); + const filePath = targetExtensionFilePath(projectName, extensionFileName); + await fs.writeFile(filePath, Buffer.from(fileBuffer)); + await registerExtensionFile(filePath); + return { + statusCode: 200, + }; + } catch (error) { + console.error("Error downloading extension:", error); + throw createError({ + statusCode: 500, + statusMessage: error.message, + }); + } +}); From d6bf1050cdd731bfc8ec7a47999e1ce653fa903c Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 10:33:33 +0200 Subject: [PATCH 02/22] ogw_front --- app/utils/extension.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/utils/extension.js b/app/utils/extension.js index 7b9e48be4..a667cede9 100644 --- a/app/utils/extension.js +++ b/app/utils/extension.js @@ -7,7 +7,7 @@ import StreamZip from "node-stream-zip"; // Local imports import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; -import { addExtensionToConf } from "@geode/opengeodeweb-front/app/utils/config.js"; +import { addExtensionToConf } from "@ogw_front/utils/config.js"; async function importExtensionFile(file) { await uploadExtension(file); From a8178982f7bc00269f9d1559aa468aa05cd223d8 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 10:37:36 +0200 Subject: [PATCH 03/22] oxlint --- app/utils/extension.js | 6 +++--- server/api/local/extensions/upload.put.js | 2 +- server/api/microservice/extensions/download.post.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/utils/extension.js b/app/utils/extension.js index a667cede9..9293dad5d 100644 --- a/app/utils/extension.js +++ b/app/utils/extension.js @@ -1,13 +1,13 @@ // Node.js imports // Third party imports -import _ from "lodash"; import StreamZip from "node-stream-zip"; +import _ from "lodash"; // Local imports +import { addExtensionToConf } from "@ogw_front/utils/config.js"; import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; -import { addExtensionToConf } from "@ogw_front/utils/config.js"; async function importExtensionFile(file) { await uploadExtension(file); @@ -96,7 +96,7 @@ async function uploadExtension(file) { await appStore.upload(file); } -async function downloadExtension({ url, extensionFileName }) { +function downloadExtension({ url, extensionFileName }) { const appStore = useAppStore(); const params = { projectFolderPath, projectName, url, extensionFileName }; diff --git a/server/api/local/extensions/upload.put.js b/server/api/local/extensions/upload.put.js index cd72087a9..0b282afcf 100644 --- a/server/api/local/extensions/upload.put.js +++ b/server/api/local/extensions/upload.put.js @@ -8,8 +8,8 @@ import { createError, defineEventHandler, getRequestHeaders, getRequestWebStream import busboy from "busboy"; // Local imports -import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; import { registerExtensionFile } from "@geode/opengeodeweb-front/app/utils/extension.js"; +import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; const CODE_201 = 201; const FILE_SIZE_LIMIT = 107_374_182; diff --git a/server/api/microservice/extensions/download.post.js b/server/api/microservice/extensions/download.post.js index ac8fd1be1..18d37fe78 100644 --- a/server/api/microservice/extensions/download.post.js +++ b/server/api/microservice/extensions/download.post.js @@ -5,8 +5,8 @@ import { promises as fs } from "node:fs"; import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; import { registerExtensionFile } from "@geode/opengeodeweb-front/app/utils/extension.js"; +import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; export default defineEventHandler(async (event) => { try { From ff96603d38655b29d18ab6f5126d877bd58e4e02 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 30 Jul 2026 11:37:13 +0200 Subject: [PATCH 04/22] feat(Stores): refactor app store --- app/stores/app.js | 27 +++++++++++++++++++++++++++ app/stores/back.js | 25 ++++++++++++------------- app/stores/viewer.js | 17 ++++++++--------- app/utils/stores.js | 33 +++++++++++++++++++++++++++++++++ 4 files changed, 80 insertions(+), 22 deletions(-) create mode 100644 app/utils/stores.js diff --git a/app/stores/app.js b/app/stores/app.js index 5eb7cab3c..232e3a773 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -3,11 +3,30 @@ import { api_fetch } from "@ogw_internal/utils/api_fetch.js"; import { upload_file } from "@ogw_internal/utils/upload_file.js"; import { killExtension } from "@ogw_front/utils/extension.js"; +import { isCloudMode, getRestApiProtocol, getRestApiPort } from "@ogw_front/utils/stores.js"; import { useInfraStore } from "@ogw_front/stores/infra"; // oxlint-disable-next-line max-lines-per-function, max-statements export const useAppStore = defineStore("app", () => { const stores = []; + const infraStore = useInfraStore(); + const default_local_port = ref("3000"); + + const protocol = computed(() => { + return getRestApiProtocol() + }); + + const port = computed(() => { + return getRestApiPort(default_local_port.value) + }); + + const base_url = computed(() => { + let app_url = `${protocol.value}://${infraStore.domain_name}:${port.value}`; + if (isCloudMode()) { + app_url += `/server`; + } + return app_url; + }); function registerStore(store) { const isAlreadyRegistered = stores.some((registeredStore) => registeredStore.$id === store.$id); @@ -265,6 +284,13 @@ export const useAppStore = defineStore("app", () => { return { stores, + default_local_port, + request_counter, + status, + protocol, + port, + base_url, + is_busy, registerStore, exportStores, importStores, @@ -285,5 +311,6 @@ export const useAppStore = defineStore("app", () => { createProjectFolder, start_request, stop_request, + }; }); diff --git a/app/stores/back.js b/app/stores/back.js index 486adb6db..247be1318 100644 --- a/app/stores/back.js +++ b/app/stores/back.js @@ -1,12 +1,17 @@ import { Status } from "@ogw_front/utils/status"; import { api_fetch } from "@ogw_internal/utils/api_fetch"; -import { appMode } from "@ogw_front/utils/local/app_mode"; import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json"; import { upload_file } from "@ogw_internal/utils/upload_file.js"; import { useAppStore } from "@ogw_front/stores/app"; import { useFeedbackStore } from "@ogw_front/stores/feedback"; import { useInfraStore } from "@ogw_front/stores/infra"; +import { + isCloudMode, + getRestApiProtocol, + getRestApiPort +} from "@ogw_front/utils/stores"; + const MILLISECONDS_IN_SECOND = 1000; const DEFAULT_PING_INTERVAL_SECONDS = 10; @@ -19,24 +24,18 @@ export const useBackStore = defineStore("back", { }), getters: { protocol() { - if (useInfraStore().app_mode === appMode.CLOUD) { - return "https"; - } - return "http"; + return getRestApiProtocol() }, port() { - if (useInfraStore().app_mode === appMode.CLOUD) { - return "443"; - } - return this.default_local_port; + return getRestApiPort(this.default_local_port) }, base_url() { const infraStore = useInfraStore(); - let geode_url = `${this.protocol}://${infraStore.domain_name}:${this.port}`; - if (infraStore.app_mode === appMode.CLOUD) { - geode_url += `/geode`; + let back_url = `${this.protocol}://${infraStore.domain_name}:${this.port}`; + if (isCloudMode()) { + back_url += `/geode`; } - return geode_url; + return back_url; }, is_busy() { return this.request_counter > 0; diff --git a/app/stores/viewer.js b/app/stores/viewer.js index e034a4daa..297474d9f 100644 --- a/app/stores/viewer.js +++ b/app/stores/viewer.js @@ -13,6 +13,11 @@ import { appMode } from "@ogw_front/utils/local/app_mode"; import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; import { viewer_call } from "@ogw_internal/utils/viewer_call"; +import { + isCloudMode, + getWebsocketApiProtocol, + getWebsocketApiPort +} from "@ogw_front/utils/stores.js"; const MS_PER_SECOND = 1000; const SECONDS_PER_REQUEST = 10; @@ -34,22 +39,16 @@ export const useViewerStore = defineStore( const busy = ref(0); const protocol = computed(() => { - if (infraStore.app_mode === appMode.CLOUD) { - return "wss"; - } - return "ws"; + return getWebsocketApiProtocol(); }); const port = computed(() => { - if (infraStore.app_mode === appMode.CLOUD) { - return "443"; - } - return default_local_port.value; + return getWebsocketApiPort(default_local_port.value); }); const base_url = computed(() => { let viewer_url = `${protocol.value}://${infraStore.domain_name}:${port.value}`; - if (infraStore.app_mode === appMode.CLOUD) { + if (isCloudMode()) { viewer_url += `/viewer`; } viewer_url += "/ws"; diff --git a/app/utils/stores.js b/app/utils/stores.js new file mode 100644 index 000000000..1ad75dfb7 --- /dev/null +++ b/app/utils/stores.js @@ -0,0 +1,33 @@ +import { useInfraStore } from "@ogw_front/stores/infra"; +import { appMode } from "@ogw_front/utils/local/app_mode"; + +function isCloudMode() { + const infraStore = useInfraStore(); + return infraStore.app_mode === appMode.CLOUD; +} + +function getRestApiProtocol() { + const protocol = isCloudMode() ? "https" : "http"; + return protocol +} +function getRestApiPort(defaultLocalPort) { + const port = isCloudMode() ? "443" : defaultLocalPort; + return port +} +function getWebsocketApiProtocol() { + const protocol = isCloudMode() ? "wss" : "ws"; + return protocol +} +function getWebsocketApiPort(defaultLocalPort) { + const port = isCloudMode() ? "443" : defaultLocalPort; + return port +} + + +export { + isCloudMode, + getRestApiPort, + getRestApiProtocol, + getWebsocketApiProtocol, + getWebsocketApiPort +} \ No newline at end of file From f0525654b17af3d2f9f839206b4fbc9b2cd007b9 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 11:37:23 +0200 Subject: [PATCH 05/22] wip --- app/utils/extension.js | 18 ------------------ nuxt.config.js | 1 + .../api/local/app/project_folder_path.post.js | 5 +---- server/api/local/app/run_back.post.js | 5 +---- server/api/local/app/run_viewer.post.js | 5 +---- server/api/local/extensions/upload.put.js | 3 +-- .../microservice/extensions/download.post.js | 3 +-- .../api/microservice/extensions/kill.post.js | 6 +++--- server/api/microservice/extensions/run.post.js | 15 ++++----------- {app => server}/utils/config.js | 17 +++++++++++++++++ {app/utils/local => shared}/path.js | 0 tests/integration/setup.js | 2 +- 12 files changed, 31 insertions(+), 49 deletions(-) rename {app => server}/utils/config.js (81%) rename {app/utils/local => shared}/path.js (100%) diff --git a/app/utils/extension.js b/app/utils/extension.js index 9293dad5d..452a26880 100644 --- a/app/utils/extension.js +++ b/app/utils/extension.js @@ -1,11 +1,9 @@ // Node.js imports // Third party imports -import StreamZip from "node-stream-zip"; import _ from "lodash"; // Local imports -import { addExtensionToConf } from "@ogw_front/utils/config.js"; import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; @@ -49,21 +47,6 @@ async function registerRunningExtensions() { ); } -async function registerExtensionFile(file) { - const StreamZipAsync = StreamZip.async; - const zip = new StreamZipAsync({ - file, - storeEntries: true, - }); - const metadataJson = await zip.entryData("metadata.json"); - const metadata = JSON.parse(metadataJson); - const { id } = metadata; - addExtensionToConf(projectName, { - extensionId: id, - extensionPath: file, - }); -} - async function unloadExtension(extensionId) { const appStore = useAppStore(); console.log("[ExtensionManager] Unloading extension:", extensionId); @@ -166,7 +149,6 @@ export { importExtensionFile, importExtensionURL, killExtension, - registerExtensionFile, registerRunningExtensions, runExtensions, unloadExtension, diff --git a/nuxt.config.js b/nuxt.config.js index 3e6d32304..1142219a0 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -28,6 +28,7 @@ export default defineNuxtConfig({ "@ogw_front": path.resolve(__dirname, "app"), "@ogw_internal": path.resolve(__dirname, "internal"), "@ogw_server": path.resolve(__dirname, "server"), + "@ogw_shared": path.resolve(__dirname, "shared"), "@ogw_tests": path.resolve(__dirname, "tests"), }, diff --git a/server/api/local/app/project_folder_path.post.js b/server/api/local/app/project_folder_path.post.js index 7de3d9498..06f0f5c9a 100644 --- a/server/api/local/app/project_folder_path.post.js +++ b/server/api/local/app/project_folder_path.post.js @@ -4,10 +4,7 @@ import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { - createPath, - generateProjectFolderPath, -} from "@geode/opengeodeweb-front/app/utils/local/path.js"; +import { createPath, generateProjectFolderPath } from "@geode/opengeodeweb-front/shared/path.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/local/app/run_back.post.js b/server/api/local/app/run_back.post.js index f0e8ee805..cb2b68456 100644 --- a/server/api/local/app/run_back.post.js +++ b/server/api/local/app/run_back.post.js @@ -4,10 +4,7 @@ import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { - addMicroserviceMetadatas, - runBack, -} from "@geode/opengeodeweb-front/app/utils/local/microservices.js"; +import { addMicroserviceMetadatas, runBack } from "@ogw_front/utils/local/microservices.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/local/app/run_viewer.post.js b/server/api/local/app/run_viewer.post.js index acd040bc9..d9449af0c 100644 --- a/server/api/local/app/run_viewer.post.js +++ b/server/api/local/app/run_viewer.post.js @@ -4,10 +4,7 @@ import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { - addMicroserviceMetadatas, - runViewer, -} from "@geode/opengeodeweb-front/app/utils/local/microservices.js"; +import { addMicroserviceMetadatas, runViewer } from "@ogw_front/utils/local/microservices.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/local/extensions/upload.put.js b/server/api/local/extensions/upload.put.js index 0b282afcf..3380843e5 100644 --- a/server/api/local/extensions/upload.put.js +++ b/server/api/local/extensions/upload.put.js @@ -8,8 +8,7 @@ import { createError, defineEventHandler, getRequestHeaders, getRequestWebStream import busboy from "busboy"; // Local imports -import { registerExtensionFile } from "@geode/opengeodeweb-front/app/utils/extension.js"; -import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; +import { registerExtensionFile, targetExtensionFilePath } from "@ogw_server/utils/config.js"; const CODE_201 = 201; const FILE_SIZE_LIMIT = 107_374_182; diff --git a/server/api/microservice/extensions/download.post.js b/server/api/microservice/extensions/download.post.js index 18d37fe78..c9b9ced75 100644 --- a/server/api/microservice/extensions/download.post.js +++ b/server/api/microservice/extensions/download.post.js @@ -5,8 +5,7 @@ import { promises as fs } from "node:fs"; import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { registerExtensionFile } from "@geode/opengeodeweb-front/app/utils/extension.js"; -import { targetExtensionFilePath } from "@geode/opengeodeweb-front/app/utils/config.js"; +import { registerExtensionFile, targetExtensionFilePath } from "@ogw_server/utils/config.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/microservice/extensions/kill.post.js b/server/api/microservice/extensions/kill.post.js index b68d300d2..256e3ba76 100644 --- a/server/api/microservice/extensions/kill.post.js +++ b/server/api/microservice/extensions/kill.post.js @@ -9,9 +9,9 @@ import { getMicroserviceByName, killMicroservice, projectMicroservices, -} from "@geode/opengeodeweb-front/app/utils/local/cleanup.js"; -import { extensionFolderPath } from "@geode/opengeodeweb-front/app/utils/local/path.js"; -import { removeExtensionFromConf } from "@geode/opengeodeweb-front/app/utils/config.js"; +} from "@ogw_front/utils/local/cleanup.js"; +import { extensionFolderPath } from "@ogw_shared/path.js"; +import { removeExtensionFromConf } from "@ogw_front/utils/config.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/microservice/extensions/run.post.js b/server/api/microservice/extensions/run.post.js index 355d5206d..e6b14d1c3 100644 --- a/server/api/microservice/extensions/run.post.js +++ b/server/api/microservice/extensions/run.post.js @@ -6,17 +6,10 @@ import path from "node:path"; import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { - addMicroserviceMetadatas, - runBack, -} from "@geode/opengeodeweb-front/app/utils/local/microservices.js"; -import { - executableName, - extensionFolderPath, - extensionFrontendPath, -} from "@geode/opengeodeweb-front/app/utils/local/path.js"; -import { extensionsConf } from "@geode/opengeodeweb-front/app/utils/config.js"; -import { unzipFile } from "@geode/opengeodeweb-front/app/utils/server.js"; +import { addMicroserviceMetadatas, runBack } from "@ogw_front/utils/local/microservices.js"; +import { executableName, extensionFolderPath, extensionFrontendPath } from "@ogw_shared/path.js"; +import { extensionsConf } from "@ogw_front/utils/config.js"; +import { unzipFile } from "@ogw_front/utils/server.js"; export default defineEventHandler(async (event) => { try { diff --git a/app/utils/config.js b/server/utils/config.js similarity index 81% rename from app/utils/config.js rename to server/utils/config.js index 1842d7d4a..638cbc573 100644 --- a/app/utils/config.js +++ b/server/utils/config.js @@ -1,5 +1,6 @@ // Node.js imports import path from "node:path"; +import StreamZip from "node-stream-zip"; import { unlink } from "node:fs"; // Third party imports @@ -58,12 +59,28 @@ function extensionPathFromConf(projectName, extensionId) { return projectConfig.get(`extensions.${extensionId}.path`); } +async function registerExtensionFile(file) { + const StreamZipAsync = StreamZip.async; + const zip = new StreamZipAsync({ + file, + storeEntries: true, + }); + const metadataJson = await zip.entryData("metadata.json"); + const metadata = JSON.parse(metadataJson); + const { id } = metadata; + addExtensionToConf(projectName, { + extensionId: id, + extensionPath: file, + }); +} + export { addExtensionToConf, confFolderPath, extensionPathFromConf, extensionsConf, projectConf, + registerExtensionFile, removeExtensionFromConf, targetExtensionFilePath, }; diff --git a/app/utils/local/path.js b/shared/path.js similarity index 100% rename from app/utils/local/path.js rename to shared/path.js diff --git a/tests/integration/setup.js b/tests/integration/setup.js index 6b8c4e3c8..7883c817d 100644 --- a/tests/integration/setup.js +++ b/tests/integration/setup.js @@ -9,7 +9,7 @@ import { afterAll, beforeAll, expect, vi } from "vitest"; // Local imports import { addMicroserviceMetadatas, runBack, runViewer } from "@ogw_front/utils/local/microservices"; -import { createPath, generateProjectFolderPath } from "@ogw_front/utils/local/path"; +import { createPath, generateProjectFolderPath } from "@ogw_shared/path"; import { Status } from "@ogw_front/utils/status"; import { appMode } from "@ogw_front/utils/local/app_mode"; import { importFile } from "@ogw_front/utils/import_workflow"; From 1a5e46ccc0f926fecbe036285e09b0c888161c59 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Thu, 30 Jul 2026 13:33:08 +0200 Subject: [PATCH 06/22] fix tests --- app/stores/app.js | 3 +++ app/stores/viewer.js | 1 - tests/unit/stores/cloud.nuxt.test.js | 12 ++++++------ tests/unit/stores/infra.nuxt.test.js | 2 +- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 232e3a773..152c34955 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -4,6 +4,7 @@ import { upload_file } from "@ogw_internal/utils/upload_file.js"; import { killExtension } from "@ogw_front/utils/extension.js"; import { isCloudMode, getRestApiProtocol, getRestApiPort } from "@ogw_front/utils/stores.js"; +import { Status } from "@ogw_front/utils/status"; import { useInfraStore } from "@ogw_front/stores/infra"; // oxlint-disable-next-line max-lines-per-function, max-statements @@ -11,6 +12,7 @@ export const useAppStore = defineStore("app", () => { const stores = []; const infraStore = useInfraStore(); const default_local_port = ref("3000"); + const status = ref(Status.NOT_CONNECTED); const protocol = computed(() => { return getRestApiProtocol() @@ -258,6 +260,7 @@ export const useAppStore = defineStore("app", () => { function stop_request() { request_counter.value -= 1; } + const is_busy = computed(() => request_counter.value > 0); const projectFolderPath = ref(""); function createProjectFolder() { diff --git a/app/stores/viewer.js b/app/stores/viewer.js index 297474d9f..bb89029df 100644 --- a/app/stores/viewer.js +++ b/app/stores/viewer.js @@ -9,7 +9,6 @@ import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json // Local imports import { Status } from "@ogw_front/utils/status"; -import { appMode } from "@ogw_front/utils/local/app_mode"; import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; import { viewer_call } from "@ogw_internal/utils/viewer_call"; diff --git a/tests/unit/stores/cloud.nuxt.test.js b/tests/unit/stores/cloud.nuxt.test.js index cc6960abe..698fc14a6 100644 --- a/tests/unit/stores/cloud.nuxt.test.js +++ b/tests/unit/stores/cloud.nuxt.test.js @@ -38,7 +38,7 @@ describe("cloud store", () => { const cloudStore = useCloudStore(); const feedbackStore = useFeedbackStore(); - registerEndpoint("/api/app/run_cloud", { + registerEndpoint("https://localhost:443/server/api/app/run_cloud", { method: "POST", handler: postFakeCall, }); @@ -46,8 +46,8 @@ describe("cloud store", () => { postFakeCall.mockReturnValue({ url: "http://test.com", }); - - await cloudStore.launch("", "", false); + const email = "noreply@example.com"; + await cloudStore.launch(email); expect(cloudStore.status).toBe(Status.CONNECTED); expect(feedbackStore.server_error).toBe(false); @@ -58,7 +58,7 @@ describe("cloud store", () => { const cloudStore = useCloudStore(); const feedbackStore = useFeedbackStore(); - registerEndpoint("/api/app/run_cloud", { + registerEndpoint("https://localhost:443/server/api/app/run_cloud", { method: "POST", handler: postFakeCall, }); @@ -69,8 +69,8 @@ describe("cloud store", () => { statusMessage: "Internal Server Error", }); }); - - await expect(cloudStore.launch("", "", false)).rejects.toThrow("500 Internal Server Error"); + const email = "noreply@example.com"; + await expect(cloudStore.launch(email)).rejects.toThrow("500 Internal Server Error"); expect(cloudStore.status).toBe(Status.NOT_CONNECTED); expect(feedbackStore.server_error).toBe(true); diff --git a/tests/unit/stores/infra.nuxt.test.js b/tests/unit/stores/infra.nuxt.test.js index d1174a36a..a3fdb366a 100644 --- a/tests/unit/stores/infra.nuxt.test.js +++ b/tests/unit/stores/infra.nuxt.test.js @@ -291,7 +291,7 @@ describe("infra store", () => { infraStore.app_mode = appMode.CLOUD; const url = "test.com"; - registerEndpoint("/api/app/run_cloud", { + registerEndpoint("https://localhost:443/server/api/app/run_cloud", { method: "POST", handler: () => ({ url }), }); From 5e6711ce8d443c88f66a8460c6cc50f06df73106 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 13:46:15 +0200 Subject: [PATCH 07/22] wip --- app/components/Launcher.vue | 2 +- app/stores/back.js | 2 +- app/stores/infra.js | 2 +- app/stores/viewer.js | 2 +- nuxt.config.js | 4 ++-- server/api/local/app/project_folder_path.post.js | 3 ++- {app/utils/local => server/utils}/cleanup.js | 0 {app/utils/local => server/utils}/microservices.js | 0 {shared => server/utils}/path.js | 0 {app/utils/local => server/utils}/scripts.js | 0 {app/utils/local => shared}/app_mode.js | 0 tests/integration/setup.js | 2 +- tests/unit/composables/project_manager.nuxt.test.js | 2 +- tests/unit/stores/back.nuxt.test.js | 2 +- tests/unit/stores/infra.nuxt.test.js | 2 +- tests/unit/stores/viewer.nuxt.test.js | 2 +- 16 files changed, 13 insertions(+), 12 deletions(-) rename {app/utils/local => server/utils}/cleanup.js (100%) rename {app/utils/local => server/utils}/microservices.js (100%) rename {shared => server/utils}/path.js (100%) rename {app/utils/local => server/utils}/scripts.js (100%) rename {app/utils/local => shared}/app_mode.js (100%) diff --git a/app/components/Launcher.vue b/app/components/Launcher.vue index dbeb0e556..519d76d02 100644 --- a/app/components/Launcher.vue +++ b/app/components/Launcher.vue @@ -2,7 +2,7 @@ import Loading from "@ogw_front/components/Loading"; import Recaptcha from "@ogw_front/components/Recaptcha"; import { Status } from "@ogw_front/utils/status"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { useInfraStore } from "@ogw_front/stores/infra"; const { appName, email, isUserAuthenticated, logo } = defineProps({ diff --git a/app/stores/back.js b/app/stores/back.js index 0245ef300..e622ed9c3 100644 --- a/app/stores/back.js +++ b/app/stores/back.js @@ -1,6 +1,6 @@ import { Status } from "@ogw_front/utils/status"; import { api_fetch } from "@ogw_internal/utils/api_fetch"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json"; import { upload_file } from "@ogw_internal/utils/upload_file.js"; import { useAppStore } from "@ogw_front/stores/app"; diff --git a/app/stores/infra.js b/app/stores/infra.js index 2fbdeffd8..11df9ee69 100644 --- a/app/stores/infra.js +++ b/app/stores/infra.js @@ -1,5 +1,5 @@ import { Status } from "@ogw_front/utils/status"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { registerRunningExtensions } from "@ogw_front/utils/extension"; import { useAppStore } from "@ogw_front/stores/app"; import { useCloudStore } from "@ogw_front/stores/cloud"; diff --git a/app/stores/viewer.js b/app/stores/viewer.js index 88ab5e65a..60dd42677 100644 --- a/app/stores/viewer.js +++ b/app/stores/viewer.js @@ -9,7 +9,7 @@ import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json // Local imports import { Status } from "@ogw_front/utils/status"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; import { viewer_call } from "@ogw_internal/utils/viewer_call"; diff --git a/nuxt.config.js b/nuxt.config.js index 1142219a0..f01973c08 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -27,9 +27,9 @@ export default defineNuxtConfig({ alias: { "@ogw_front": path.resolve(__dirname, "app"), "@ogw_internal": path.resolve(__dirname, "internal"), - "@ogw_server": path.resolve(__dirname, "server"), - "@ogw_shared": path.resolve(__dirname, "shared"), "@ogw_tests": path.resolve(__dirname, "tests"), + "@ogw_shared": path.resolve(__dirname, "shared"), + "@ogw_server": path.resolve(__dirname, "server"), }, // ** Global CSS diff --git a/server/api/local/app/project_folder_path.post.js b/server/api/local/app/project_folder_path.post.js index 06f0f5c9a..84e5cf57d 100644 --- a/server/api/local/app/project_folder_path.post.js +++ b/server/api/local/app/project_folder_path.post.js @@ -4,7 +4,8 @@ import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { createPath, generateProjectFolderPath } from "@geode/opengeodeweb-front/shared/path.js"; +import { appMode } from "@ogw_shared/app_mode.js"; +import { createPath, generateProjectFolderPath } from "@ogw_server/utils/path.js"; export default defineEventHandler(async (event) => { try { diff --git a/app/utils/local/cleanup.js b/server/utils/cleanup.js similarity index 100% rename from app/utils/local/cleanup.js rename to server/utils/cleanup.js diff --git a/app/utils/local/microservices.js b/server/utils/microservices.js similarity index 100% rename from app/utils/local/microservices.js rename to server/utils/microservices.js diff --git a/shared/path.js b/server/utils/path.js similarity index 100% rename from shared/path.js rename to server/utils/path.js diff --git a/app/utils/local/scripts.js b/server/utils/scripts.js similarity index 100% rename from app/utils/local/scripts.js rename to server/utils/scripts.js diff --git a/app/utils/local/app_mode.js b/shared/app_mode.js similarity index 100% rename from app/utils/local/app_mode.js rename to shared/app_mode.js diff --git a/tests/integration/setup.js b/tests/integration/setup.js index 7883c817d..b573adb16 100644 --- a/tests/integration/setup.js +++ b/tests/integration/setup.js @@ -11,7 +11,7 @@ import { afterAll, beforeAll, expect, vi } from "vitest"; import { addMicroserviceMetadatas, runBack, runViewer } from "@ogw_front/utils/local/microservices"; import { createPath, generateProjectFolderPath } from "@ogw_shared/path"; import { Status } from "@ogw_front/utils/status"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { importFile } from "@ogw_front/utils/import_workflow"; import { setupActivePinia } from "@ogw_tests/utils"; import { useBackStore } from "@ogw_front/stores/back"; diff --git a/tests/unit/composables/project_manager.nuxt.test.js b/tests/unit/composables/project_manager.nuxt.test.js index c35b5a7ca..d5d3dacb5 100644 --- a/tests/unit/composables/project_manager.nuxt.test.js +++ b/tests/unit/composables/project_manager.nuxt.test.js @@ -5,7 +5,7 @@ import { beforeEach, describe, expect, test, vi } from "vitest"; import { exportProject, importProject } from "@ogw_front/composables/project_manager"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { setupActivePinia } from "@ogw_tests/utils"; // Constants diff --git a/tests/unit/stores/back.nuxt.test.js b/tests/unit/stores/back.nuxt.test.js index 233b676e6..c348e7d9c 100644 --- a/tests/unit/stores/back.nuxt.test.js +++ b/tests/unit/stores/back.nuxt.test.js @@ -5,7 +5,7 @@ import { registerEndpoint } from "@nuxt/test-utils/runtime"; // Local imports import { Status } from "@ogw_front/utils/status"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { setupActivePinia } from "@ogw_tests/utils"; import { useBackStore } from "@ogw_front/stores/back"; import { useInfraStore } from "@ogw_front/stores/infra"; diff --git a/tests/unit/stores/infra.nuxt.test.js b/tests/unit/stores/infra.nuxt.test.js index 26e407ce3..12d4e5484 100644 --- a/tests/unit/stores/infra.nuxt.test.js +++ b/tests/unit/stores/infra.nuxt.test.js @@ -4,7 +4,7 @@ import { registerEndpoint } from "@nuxt/test-utils/runtime"; // Local imports import { Status } from "@ogw_front/utils/status"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { setupActivePinia } from "@ogw_tests/utils"; import { useBackStore } from "@ogw_front/stores/back"; import { useInfraStore } from "@ogw_front/stores/infra"; diff --git a/tests/unit/stores/viewer.nuxt.test.js b/tests/unit/stores/viewer.nuxt.test.js index fd0204e5c..06db76893 100644 --- a/tests/unit/stores/viewer.nuxt.test.js +++ b/tests/unit/stores/viewer.nuxt.test.js @@ -3,7 +3,7 @@ import { afterAll, beforeAll, beforeEach, describe, expect, expectTypeOf, test, import { WebSocket } from "ws"; // Local imports -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; import { setupActivePinia } from "@ogw_tests/utils"; import { useInfraStore } from "@ogw_front/stores/infra"; import { useViewerStore } from "@ogw_front/stores/viewer"; From d2ba5d81528a074a40205a7074d207ed796d22e6 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 14:24:39 +0200 Subject: [PATCH 08/22] wip --- server/api/local/app/project_folder_path.post.js | 6 ++++-- server/api/local/app/run_back.post.js | 5 ++++- server/api/local/app/run_viewer.post.js | 5 ++++- server/api/microservice/extensions/run.post.js | 15 +++++++++++---- server/utils/path.js | 2 +- server/utils/scripts.js | 2 +- 6 files changed, 25 insertions(+), 10 deletions(-) diff --git a/server/api/local/app/project_folder_path.post.js b/server/api/local/app/project_folder_path.post.js index 84e5cf57d..b09c26355 100644 --- a/server/api/local/app/project_folder_path.post.js +++ b/server/api/local/app/project_folder_path.post.js @@ -4,8 +4,10 @@ import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { appMode } from "@ogw_shared/app_mode.js"; -import { createPath, generateProjectFolderPath } from "@ogw_server/utils/path.js"; +import { + createPath, + generateProjectFolderPath, +} from "@geode/opengeodeweb-front/server/utils/path.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/local/app/run_back.post.js b/server/api/local/app/run_back.post.js index cb2b68456..90fd46da1 100644 --- a/server/api/local/app/run_back.post.js +++ b/server/api/local/app/run_back.post.js @@ -4,7 +4,10 @@ import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { addMicroserviceMetadatas, runBack } from "@ogw_front/utils/local/microservices.js"; +import { + addMicroserviceMetadatas, + runBack, +} from "@geode/opengeodeweb-front/server/utils/microservices.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/local/app/run_viewer.post.js b/server/api/local/app/run_viewer.post.js index d9449af0c..72adde882 100644 --- a/server/api/local/app/run_viewer.post.js +++ b/server/api/local/app/run_viewer.post.js @@ -4,7 +4,10 @@ import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { addMicroserviceMetadatas, runViewer } from "@ogw_front/utils/local/microservices.js"; +import { + addMicroserviceMetadatas, + runViewer, +} from "@geode/opengeodeweb-front/server/utils/microservices.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/microservice/extensions/run.post.js b/server/api/microservice/extensions/run.post.js index e6b14d1c3..1ae47e3cd 100644 --- a/server/api/microservice/extensions/run.post.js +++ b/server/api/microservice/extensions/run.post.js @@ -6,10 +6,17 @@ import path from "node:path"; import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { addMicroserviceMetadatas, runBack } from "@ogw_front/utils/local/microservices.js"; -import { executableName, extensionFolderPath, extensionFrontendPath } from "@ogw_shared/path.js"; -import { extensionsConf } from "@ogw_front/utils/config.js"; -import { unzipFile } from "@ogw_front/utils/server.js"; +import { + addMicroserviceMetadatas, + runBack, +} from "@geode/opengeodeweb-front/server/utils/microservices.js"; +import { + executableName, + extensionFolderPath, + extensionFrontendPath, +} from "@geode/opengeodeweb-front/server/utils/path.js"; +import { extensionsConf } from "@geode/opengeodeweb-front/server/utils/config.js"; +import { unzipFile } from "@geode/opengeodeweb-front/app/utils/server.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/utils/path.js b/server/utils/path.js index ca5d30971..b34b76702 100644 --- a/server/utils/path.js +++ b/server/utils/path.js @@ -8,7 +8,7 @@ import { setTimeout } from "node:timers/promises"; import { v4 as uuidv4 } from "uuid"; // Local imports -import { appMode } from "./app_mode.js"; +import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js"; import { commandExistsSync } from "./scripts.js"; function findExecutableInDir(baseDir, execName, osExecutableName) { diff --git a/server/utils/scripts.js b/server/utils/scripts.js index 06b903a09..d23446108 100644 --- a/server/utils/scripts.js +++ b/server/utils/scripts.js @@ -9,7 +9,7 @@ import readline from "node:readline"; import { getPort } from "get-port-please"; // Local imports -import { appMode } from "./app_mode.js"; +import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js"; const BYTES_PER_KIBIBYTE = 1024; const MAX_ERROR_BUFFER_KIBIBYTES = 64; From c25520af6705e4242cd8309971b35d9d2e53b8cc Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 14:44:39 +0200 Subject: [PATCH 09/22] fix --- app/utils/extension.js | 6 +++--- app/utils/stores.js | 15 +++++++-------- server/api/local/extensions/upload.put.js | 7 +++++-- .../api/microservice/extensions/download.post.js | 7 +++++-- server/api/microservice/extensions/kill.post.js | 6 +++--- server/api/serverless/run_cloud.js | 2 +- server/utils/config.js | 4 ++-- 7 files changed, 26 insertions(+), 21 deletions(-) diff --git a/app/utils/extension.js b/app/utils/extension.js index 452a26880..bc8504641 100644 --- a/app/utils/extension.js +++ b/app/utils/extension.js @@ -81,7 +81,8 @@ async function uploadExtension(file) { function downloadExtension({ url, extensionFileName }) { const appStore = useAppStore(); - const params = { projectFolderPath, projectName, url, extensionFileName }; + const { PROJECT: projectName } = useRuntimeConfig().public; + const params = { projectName, url, extensionFileName }; const schema = { $id: "/api/microservice/extensions/download", @@ -89,11 +90,10 @@ function downloadExtension({ url, extensionFileName }) { type: "object", properties: { extensionFileName: { type: "string" }, - projectFolderPath: { type: "string" }, projectName: { type: "string" }, url: { type: "string" }, }, - required: ["projectFolderPath", "projectName"], + required: ["extensionFileName", "projectName", "url"], additionalProperties: false, }; diff --git a/app/utils/stores.js b/app/utils/stores.js index 1ad75dfb7..00ac9e47a 100644 --- a/app/utils/stores.js +++ b/app/utils/stores.js @@ -1,5 +1,5 @@ import { useInfraStore } from "@ogw_front/stores/infra"; -import { appMode } from "@ogw_front/utils/local/app_mode"; +import { appMode } from "@ogw_shared/app_mode"; function isCloudMode() { const infraStore = useInfraStore(); @@ -8,26 +8,25 @@ function isCloudMode() { function getRestApiProtocol() { const protocol = isCloudMode() ? "https" : "http"; - return protocol + return protocol; } function getRestApiPort(defaultLocalPort) { const port = isCloudMode() ? "443" : defaultLocalPort; - return port + return port; } function getWebsocketApiProtocol() { const protocol = isCloudMode() ? "wss" : "ws"; - return protocol + return protocol; } function getWebsocketApiPort(defaultLocalPort) { const port = isCloudMode() ? "443" : defaultLocalPort; - return port + return port; } - export { isCloudMode, getRestApiPort, getRestApiProtocol, getWebsocketApiProtocol, - getWebsocketApiPort -} \ No newline at end of file + getWebsocketApiPort, +}; diff --git a/server/api/local/extensions/upload.put.js b/server/api/local/extensions/upload.put.js index 3380843e5..1dc8aa685 100644 --- a/server/api/local/extensions/upload.put.js +++ b/server/api/local/extensions/upload.put.js @@ -8,7 +8,10 @@ import { createError, defineEventHandler, getRequestHeaders, getRequestWebStream import busboy from "busboy"; // Local imports -import { registerExtensionFile, targetExtensionFilePath } from "@ogw_server/utils/config.js"; +import { + registerExtensionFile, + targetExtensionFilePath, +} from "@geode/opengeodeweb-front/server/utils/config.js"; const CODE_201 = 201; const FILE_SIZE_LIMIT = 107_374_182; @@ -61,6 +64,6 @@ export default defineEventHandler(async (event) => { if (savedFiles.length === 0) { throw createError({ statusCode: 400, message: "No file received" }); } - await Promise.all(savedFiles.map(async (file) => await registerExtensionFile(file))); + await Promise.all(savedFiles.map(async (file) => await registerExtensionFile(projectName, file))); return { statusCode: CODE_201 }; }); diff --git a/server/api/microservice/extensions/download.post.js b/server/api/microservice/extensions/download.post.js index c9b9ced75..e6dc1f9a4 100644 --- a/server/api/microservice/extensions/download.post.js +++ b/server/api/microservice/extensions/download.post.js @@ -5,7 +5,10 @@ import { promises as fs } from "node:fs"; import { createError, defineEventHandler, readBody } from "h3"; // Local imports -import { registerExtensionFile, targetExtensionFilePath } from "@ogw_server/utils/config.js"; +import { + registerExtensionFile, + targetExtensionFilePath, +} from "@geode/opengeodeweb-front/server/utils/config.js"; export default defineEventHandler(async (event) => { try { @@ -15,7 +18,7 @@ export default defineEventHandler(async (event) => { const fileBuffer = await fetch(url).then((file) => file.arrayBuffer()); const filePath = targetExtensionFilePath(projectName, extensionFileName); await fs.writeFile(filePath, Buffer.from(fileBuffer)); - await registerExtensionFile(filePath); + await registerExtensionFile(projectName, filePath); return { statusCode: 200, }; diff --git a/server/api/microservice/extensions/kill.post.js b/server/api/microservice/extensions/kill.post.js index 256e3ba76..7f5aaba6e 100644 --- a/server/api/microservice/extensions/kill.post.js +++ b/server/api/microservice/extensions/kill.post.js @@ -9,9 +9,9 @@ import { getMicroserviceByName, killMicroservice, projectMicroservices, -} from "@ogw_front/utils/local/cleanup.js"; -import { extensionFolderPath } from "@ogw_shared/path.js"; -import { removeExtensionFromConf } from "@ogw_front/utils/config.js"; +} from "@geode/opengeodeweb-front/server/utils/cleanup.js"; +import { extensionFolderPath } from "@geode/opengeodeweb-front/shared/path.js"; +import { removeExtensionFromConf } from "@geode/opengeodeweb-front/server/utils/config.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/serverless/run_cloud.js b/server/api/serverless/run_cloud.js index 04ca962fa..da60e4fa1 100644 --- a/server/api/serverless/run_cloud.js +++ b/server/api/serverless/run_cloud.js @@ -6,7 +6,7 @@ import { GoogleAuth } from "google-auth-library"; import { ServicesClient } from "@google-cloud/run"; // Local imports -import { artifactImage, requestConfig } from "@ogw_server/utils/cloud"; +import { artifactImage, requestConfig } from "@geode/opengeodeweb-front/server/utils/cloud"; export default defineEventHandler(async (event) => { try { diff --git a/server/utils/config.js b/server/utils/config.js index 638cbc573..42b72a274 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -22,7 +22,7 @@ function confFolderPath(projectName) { function targetExtensionFilePath(projectName, filename) { const safeFilename = sanitize(filename); - const targetPath = path.join(configFolderPath(projectName), safeFilename); + const targetPath = path.join(confFolderPath(projectName), safeFilename); return targetPath; } @@ -59,7 +59,7 @@ function extensionPathFromConf(projectName, extensionId) { return projectConfig.get(`extensions.${extensionId}.path`); } -async function registerExtensionFile(file) { +async function registerExtensionFile(projectName, file) { const StreamZipAsync = StreamZip.async; const zip = new StreamZipAsync({ file, From 6c9e019910a11823ba562368c9ff7930b0ef115f Mon Sep 17 00:00:00 2001 From: BotellaA <3213882+BotellaA@users.noreply.github.com> Date: Thu, 30 Jul 2026 12:45:44 +0000 Subject: [PATCH 10/22] Apply prepare changes --- app/stores/app.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 9afa593a0..7d1a12634 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -15,11 +15,11 @@ export const useAppStore = defineStore("app", () => { const status = ref(Status.NOT_CONNECTED); const protocol = computed(() => { - return getRestApiProtocol() + return getRestApiProtocol(); }); const port = computed(() => { - return getRestApiPort(default_local_port.value) + return getRestApiPort(default_local_port.value); }); const base_url = computed(() => { @@ -314,6 +314,5 @@ export const useAppStore = defineStore("app", () => { createProjectFolder, start_request, stop_request, - }; }); From 9302dfab9aefadb3ba1cc0a63657a75bc4f48526 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 15:20:04 +0200 Subject: [PATCH 11/22] fix --- app/stores/app.js | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 9afa593a0..1ff862d30 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -10,19 +10,19 @@ import { useInfraStore } from "@ogw_front/stores/infra"; // oxlint-disable-next-line max-lines-per-function, max-statements export const useAppStore = defineStore("app", () => { const stores = []; - const infraStore = useInfraStore(); const default_local_port = ref("3000"); const status = ref(Status.NOT_CONNECTED); const protocol = computed(() => { - return getRestApiProtocol() + return getRestApiProtocol(); }); const port = computed(() => { - return getRestApiPort(default_local_port.value) + return getRestApiPort(default_local_port.value); }); const base_url = computed(() => { + const infraStore = useInfraStore(); let app_url = `${protocol.value}://${infraStore.domain_name}:${port.value}`; if (isCloudMode()) { app_url += `/server`; @@ -314,6 +314,5 @@ export const useAppStore = defineStore("app", () => { createProjectFolder, start_request, stop_request, - }; }); From a6f17031888135a4c7027b537f397b62e483d04a Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 15:28:14 +0200 Subject: [PATCH 12/22] fix tests --- tests/integration/setup.js | 4 ++-- tests/integration/stores/data_style/mesh/cells.nuxt.test.js | 2 +- tests/integration/stores/data_style/mesh/edges.nuxt.test.js | 2 +- tests/integration/stores/data_style/mesh/index.nuxt.test.js | 2 +- tests/integration/stores/data_style/mesh/points.nuxt.test.js | 2 +- .../integration/stores/data_style/mesh/polygons.nuxt.test.js | 2 +- .../integration/stores/data_style/mesh/polyhedra.nuxt.test.js | 2 +- tests/integration/stores/data_style/model/blocks.nuxt.test.js | 2 +- .../integration/stores/data_style/model/corners.nuxt.test.js | 2 +- tests/integration/stores/data_style/model/edges.nuxt.test.js | 2 +- tests/integration/stores/data_style/model/index.nuxt.test.js | 2 +- tests/integration/stores/data_style/model/lines.nuxt.test.js | 2 +- tests/integration/stores/data_style/model/points.nuxt.test.js | 2 +- .../integration/stores/data_style/model/surfaces.nuxt.test.js | 2 +- tests/integration/stores/viewer.nuxt.test.js | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/tests/integration/setup.js b/tests/integration/setup.js index b573adb16..aad2cf66b 100644 --- a/tests/integration/setup.js +++ b/tests/integration/setup.js @@ -8,8 +8,8 @@ import path from "node:path"; import { afterAll, beforeAll, expect, vi } from "vitest"; // Local imports -import { addMicroserviceMetadatas, runBack, runViewer } from "@ogw_front/utils/local/microservices"; -import { createPath, generateProjectFolderPath } from "@ogw_shared/path"; +import { addMicroserviceMetadatas, runBack, runViewer } from "@ogw_server/utils/microservices"; +import { createPath, generateProjectFolderPath } from "@ogw_server/utils/path"; import { Status } from "@ogw_front/utils/status"; import { appMode } from "@ogw_shared/app_mode"; import { importFile } from "@ogw_front/utils/import_workflow"; diff --git a/tests/integration/stores/data_style/mesh/cells.nuxt.test.js b/tests/integration/stores/data_style/mesh/cells.nuxt.test.js index ed96c8b5e..c568e0123 100644 --- a/tests/integration/stores/data_style/mesh/cells.nuxt.test.js +++ b/tests/integration/stores/data_style/mesh/cells.nuxt.test.js @@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap"; import { isMeshCellsVertexAttributeValid } from "@ogw_internal/stores/data_style/mesh/cells/vertex"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; diff --git a/tests/integration/stores/data_style/mesh/edges.nuxt.test.js b/tests/integration/stores/data_style/mesh/edges.nuxt.test.js index 4faa6d380..0714920cb 100644 --- a/tests/integration/stores/data_style/mesh/edges.nuxt.test.js +++ b/tests/integration/stores/data_style/mesh/edges.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/mesh/index.nuxt.test.js b/tests/integration/stores/data_style/mesh/index.nuxt.test.js index c39aa9ff4..0ec5de82e 100644 --- a/tests/integration/stores/data_style/mesh/index.nuxt.test.js +++ b/tests/integration/stores/data_style/mesh/index.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/mesh/points.nuxt.test.js b/tests/integration/stores/data_style/mesh/points.nuxt.test.js index f3ac15190..0640ba060 100644 --- a/tests/integration/stores/data_style/mesh/points.nuxt.test.js +++ b/tests/integration/stores/data_style/mesh/points.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js b/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js index 24221e2c3..74ff1e5cd 100644 --- a/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js +++ b/tests/integration/stores/data_style/mesh/polygons.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js b/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js index 1c5156e32..65863ef37 100644 --- a/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js +++ b/tests/integration/stores/data_style/mesh/polyhedra.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/model/blocks.nuxt.test.js b/tests/integration/stores/data_style/model/blocks.nuxt.test.js index 82c5f3f10..cd9e443a9 100644 --- a/tests/integration/stores/data_style/model/blocks.nuxt.test.js +++ b/tests/integration/stores/data_style/model/blocks.nuxt.test.js @@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { useDataStore } from "@ogw_front/stores/data"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/model/corners.nuxt.test.js b/tests/integration/stores/data_style/model/corners.nuxt.test.js index 256b0f98b..9b4627947 100644 --- a/tests/integration/stores/data_style/model/corners.nuxt.test.js +++ b/tests/integration/stores/data_style/model/corners.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { useDataStore } from "@ogw_front/stores/data"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/model/edges.nuxt.test.js b/tests/integration/stores/data_style/model/edges.nuxt.test.js index 0ab9c78ed..1a144415b 100644 --- a/tests/integration/stores/data_style/model/edges.nuxt.test.js +++ b/tests/integration/stores/data_style/model/edges.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/model/index.nuxt.test.js b/tests/integration/stores/data_style/model/index.nuxt.test.js index d2d81a9c4..c2658c7ee 100644 --- a/tests/integration/stores/data_style/model/index.nuxt.test.js +++ b/tests/integration/stores/data_style/model/index.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { useDataStore } from "@ogw_front/stores/data"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/model/lines.nuxt.test.js b/tests/integration/stores/data_style/model/lines.nuxt.test.js index 25fe6576d..e79b45f7e 100644 --- a/tests/integration/stores/data_style/model/lines.nuxt.test.js +++ b/tests/integration/stores/data_style/model/lines.nuxt.test.js @@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { useDataStore } from "@ogw_front/stores/data"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/model/points.nuxt.test.js b/tests/integration/stores/data_style/model/points.nuxt.test.js index 634804497..18805ba91 100644 --- a/tests/integration/stores/data_style/model/points.nuxt.test.js +++ b/tests/integration/stores/data_style/model/points.nuxt.test.js @@ -5,7 +5,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { useDataStyleStore } from "@ogw_front/stores/data_style"; import { useViewerStore } from "@ogw_front/stores/viewer"; diff --git a/tests/integration/stores/data_style/model/surfaces.nuxt.test.js b/tests/integration/stores/data_style/model/surfaces.nuxt.test.js index 9e676d1c1..7d3a4d3d3 100644 --- a/tests/integration/stores/data_style/model/surfaces.nuxt.test.js +++ b/tests/integration/stores/data_style/model/surfaces.nuxt.test.js @@ -6,7 +6,7 @@ import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schem // Local imports import { beforeAllTimeout, setupIntegrationTests } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { getRGBPointsFromPreset } from "@ogw_front/utils/colormap"; import { isModelSurfacesPolygonAttributeValid } from "@ogw_internal/stores/data_style/model/surfaces/polygon"; import { isModelSurfacesVertexAttributeValid } from "@ogw_internal/stores/data_style/model/surfaces/vertex"; diff --git a/tests/integration/stores/viewer.nuxt.test.js b/tests/integration/stores/viewer.nuxt.test.js index 3b58f0d68..f91ab183d 100644 --- a/tests/integration/stores/viewer.nuxt.test.js +++ b/tests/integration/stores/viewer.nuxt.test.js @@ -7,7 +7,7 @@ import opengeodeweb_viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb // Local imports import { beforeAllTimeout, runMicroservices } from "@ogw_tests/integration/setup"; import { Status } from "@ogw_front/utils/status"; -import { cleanupBackend } from "@ogw_front/utils/local/cleanup"; +import { cleanupBackend } from "@ogw_server/utils/cleanup"; import { setupActivePinia } from "@ogw_tests/utils"; import { useViewerStore } from "@ogw_front/stores/viewer"; From 36110cc83f325e936c02b1289f8ff5a4af229f21 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 15:44:14 +0200 Subject: [PATCH 13/22] oxlint --- app/stores/app.js | 19 +++++++------------ app/stores/back.js | 3 +-- app/stores/viewer.js | 18 +++++++----------- app/utils/stores.js | 2 +- server/utils/config.js | 2 +- 5 files changed, 17 insertions(+), 27 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 1ff862d30..882b0e94d 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -1,10 +1,9 @@ // Local imports +import { getRestApiPort, getRestApiProtocol, isCloudMode } from "@ogw_front/utils/stores.js"; +import { Status } from "@ogw_front/utils/status"; import { api_fetch } from "@ogw_internal/utils/api_fetch.js"; -import { upload_file } from "@ogw_internal/utils/upload_file.js"; - import { killExtension } from "@ogw_front/utils/extension.js"; -import { isCloudMode, getRestApiProtocol, getRestApiPort } from "@ogw_front/utils/stores.js"; -import { Status } from "@ogw_front/utils/status"; +import { upload_file } from "@ogw_internal/utils/upload_file.js"; import { useInfraStore } from "@ogw_front/stores/infra"; // oxlint-disable-next-line max-lines-per-function, max-statements @@ -13,13 +12,9 @@ export const useAppStore = defineStore("app", () => { const default_local_port = ref("3000"); const status = ref(Status.NOT_CONNECTED); - const protocol = computed(() => { - return getRestApiProtocol(); - }); + const protocol = computed(() => getRestApiProtocol()); - const port = computed(() => { - return getRestApiPort(default_local_port.value); - }); + const port = computed(() => getRestApiPort(default_local_port.value)); const base_url = computed(() => { const infraStore = useInfraStore(); @@ -112,7 +107,7 @@ export const useAppStore = defineStore("app", () => { return loadedExtensions.value.get(id); } - async function loadExtension(path, port, backendPath = undefined) { + async function loadExtension(path, extensionPort, backendPath = undefined) { try { let finalURL = path; @@ -129,7 +124,7 @@ export const useAppStore = defineStore("app", () => { // oxlint-disable-next-line no-inline-comments const extensionModule = await import(/* @vite-ignore */ finalURL); const store = extensionModule.metadata.store(); - store.$patch({ default_local_port: port }); + store.$patch({ default_local_port: extensionPort }); if (finalURL !== path && finalURL.startsWith("blob:")) { URL.revokeObjectURL(finalURL); diff --git a/app/stores/back.js b/app/stores/back.js index 214813463..8b6ff01e8 100644 --- a/app/stores/back.js +++ b/app/stores/back.js @@ -1,3 +1,4 @@ +import { getRestApiPort, getRestApiProtocol, isCloudMode } from "@ogw_front/utils/stores"; import { Status } from "@ogw_front/utils/status"; import { api_fetch } from "@ogw_internal/utils/api_fetch"; import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.json"; @@ -6,8 +7,6 @@ import { useAppStore } from "@ogw_front/stores/app"; import { useFeedbackStore } from "@ogw_front/stores/feedback"; import { useInfraStore } from "@ogw_front/stores/infra"; -import { isCloudMode, getRestApiProtocol, getRestApiPort } from "@ogw_front/utils/stores"; - const MILLISECONDS_IN_SECOND = 1000; const DEFAULT_PING_INTERVAL_SECONDS = 10; diff --git a/app/stores/viewer.js b/app/stores/viewer.js index fc9ff70e7..e3763a271 100644 --- a/app/stores/viewer.js +++ b/app/stores/viewer.js @@ -8,15 +8,15 @@ import { connectImageStream } from "@kitware/vtk.js/Rendering/Misc/RemoteView"; import schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json"; // Local imports +import { + getWebsocketApiPort, + getWebsocketApiProtocol, + isCloudMode, +} from "@ogw_front/utils/stores.js"; import { Status } from "@ogw_front/utils/status"; import { useAppStore } from "@ogw_front/stores/app"; import { useInfraStore } from "@ogw_front/stores/infra"; import { viewer_call } from "@ogw_internal/utils/viewer_call"; -import { - isCloudMode, - getWebsocketApiProtocol, - getWebsocketApiPort, -} from "@ogw_front/utils/stores.js"; const MS_PER_SECOND = 1000; const SECONDS_PER_REQUEST = 10; @@ -37,13 +37,9 @@ export const useViewerStore = defineStore( const version = ref("0.0.0"); const busy = ref(0); - const protocol = computed(() => { - return getWebsocketApiProtocol(); - }); + const protocol = computed(() => getWebsocketApiProtocol()); - const port = computed(() => { - return getWebsocketApiPort(default_local_port.value); - }); + const port = computed(() => getWebsocketApiPort(default_local_port.value)); const base_url = computed(() => { let viewer_url = `${protocol.value}://${infraStore.domain_name}:${port.value}`; diff --git a/app/utils/stores.js b/app/utils/stores.js index 00ac9e47a..f1b224d17 100644 --- a/app/utils/stores.js +++ b/app/utils/stores.js @@ -1,5 +1,5 @@ -import { useInfraStore } from "@ogw_front/stores/infra"; import { appMode } from "@ogw_shared/app_mode"; +import { useInfraStore } from "@ogw_front/stores/infra"; function isCloudMode() { const infraStore = useInfraStore(); diff --git a/server/utils/config.js b/server/utils/config.js index 42b72a274..dd6fe1b9e 100644 --- a/server/utils/config.js +++ b/server/utils/config.js @@ -1,10 +1,10 @@ // Node.js imports import path from "node:path"; -import StreamZip from "node-stream-zip"; import { unlink } from "node:fs"; // Third party imports import Conf from "conf"; +import StreamZip from "node-stream-zip"; import sanitize from "sanitize-filename"; // Local imports From b604db80efb7b5c864bbf865494f36d92fde9f84 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 17:05:52 +0200 Subject: [PATCH 14/22] test --- package.json | 3 +++ server/api/microservice/extensions/run.post.js | 2 +- server/utils/path.js | 2 +- server/utils/scripts.js | 2 +- {app => server}/utils/server.js | 0 5 files changed, 6 insertions(+), 3 deletions(-) rename {app => server}/utils/server.js (100%) diff --git a/package.json b/package.json index c20d035e7..76d9086ed 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,9 @@ }, "type": "module", "main": "./nuxt.config.js", + "imports": { + "#shared/*": "./shared/*" + }, "publishConfig": { "access": "public" }, diff --git a/server/api/microservice/extensions/run.post.js b/server/api/microservice/extensions/run.post.js index 1ae47e3cd..ae852aefd 100644 --- a/server/api/microservice/extensions/run.post.js +++ b/server/api/microservice/extensions/run.post.js @@ -16,7 +16,7 @@ import { extensionFrontendPath, } from "@geode/opengeodeweb-front/server/utils/path.js"; import { extensionsConf } from "@geode/opengeodeweb-front/server/utils/config.js"; -import { unzipFile } from "@geode/opengeodeweb-front/app/utils/server.js"; +import { unzipFile } from "@geode/opengeodeweb-front/server/utils/server.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/utils/path.js b/server/utils/path.js index b34b76702..1cc94488c 100644 --- a/server/utils/path.js +++ b/server/utils/path.js @@ -8,7 +8,7 @@ import { setTimeout } from "node:timers/promises"; import { v4 as uuidv4 } from "uuid"; // Local imports -import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js"; +import { appMode } from "#shared/app_mode.js"; import { commandExistsSync } from "./scripts.js"; function findExecutableInDir(baseDir, execName, osExecutableName) { diff --git a/server/utils/scripts.js b/server/utils/scripts.js index d23446108..584127124 100644 --- a/server/utils/scripts.js +++ b/server/utils/scripts.js @@ -9,7 +9,7 @@ import readline from "node:readline"; import { getPort } from "get-port-please"; // Local imports -import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js"; +import { appMode } from "#shared/app_mode.js"; const BYTES_PER_KIBIBYTE = 1024; const MAX_ERROR_BUFFER_KIBIBYTES = 64; diff --git a/app/utils/server.js b/server/utils/server.js similarity index 100% rename from app/utils/server.js rename to server/utils/server.js From 0d225e85fd93bc4f31092b1449f6cbf95eb68b1c Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 17:21:33 +0200 Subject: [PATCH 15/22] test --- server/api/microservice/extensions/kill.post.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/api/microservice/extensions/kill.post.js b/server/api/microservice/extensions/kill.post.js index 7f5aaba6e..ae67af842 100644 --- a/server/api/microservice/extensions/kill.post.js +++ b/server/api/microservice/extensions/kill.post.js @@ -10,7 +10,7 @@ import { killMicroservice, projectMicroservices, } from "@geode/opengeodeweb-front/server/utils/cleanup.js"; -import { extensionFolderPath } from "@geode/opengeodeweb-front/shared/path.js"; +import { extensionFolderPath } from "@geode/opengeodeweb-front/server/utils/path.js"; import { removeExtensionFromConf } from "@geode/opengeodeweb-front/server/utils/config.js"; export default defineEventHandler(async (event) => { From 8d599bfaf75d0f340ae691c8186bac6ff2d550a6 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Thu, 30 Jul 2026 21:03:22 +0200 Subject: [PATCH 16/22] test --- nuxt.config.js | 1 + package.json | 3 --- server/utils/path.js | 2 +- server/utils/scripts.js | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/nuxt.config.js b/nuxt.config.js index f01973c08..47a973507 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -30,6 +30,7 @@ export default defineNuxtConfig({ "@ogw_tests": path.resolve(__dirname, "tests"), "@ogw_shared": path.resolve(__dirname, "shared"), "@ogw_server": path.resolve(__dirname, "server"), + "@geode/opengeodeweb-front/shared": path.resolve(__dirname, "shared"), }, // ** Global CSS diff --git a/package.json b/package.json index 76d9086ed..c20d035e7 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,6 @@ }, "type": "module", "main": "./nuxt.config.js", - "imports": { - "#shared/*": "./shared/*" - }, "publishConfig": { "access": "public" }, diff --git a/server/utils/path.js b/server/utils/path.js index 1cc94488c..b34b76702 100644 --- a/server/utils/path.js +++ b/server/utils/path.js @@ -8,7 +8,7 @@ import { setTimeout } from "node:timers/promises"; import { v4 as uuidv4 } from "uuid"; // Local imports -import { appMode } from "#shared/app_mode.js"; +import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js"; import { commandExistsSync } from "./scripts.js"; function findExecutableInDir(baseDir, execName, osExecutableName) { diff --git a/server/utils/scripts.js b/server/utils/scripts.js index 584127124..d23446108 100644 --- a/server/utils/scripts.js +++ b/server/utils/scripts.js @@ -9,7 +9,7 @@ import readline from "node:readline"; import { getPort } from "get-port-please"; // Local imports -import { appMode } from "#shared/app_mode.js"; +import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js"; const BYTES_PER_KIBIBYTE = 1024; const MAX_ERROR_BUFFER_KIBIBYTES = 64; From bd79c298adac13f6075f9a421330bf3ca4cae5d2 Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Fri, 31 Jul 2026 08:55:48 +0200 Subject: [PATCH 17/22] fix --- nuxt.config.js | 1 - tests/vitest.config.js | 12 +++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/nuxt.config.js b/nuxt.config.js index 47a973507..f01973c08 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -30,7 +30,6 @@ export default defineNuxtConfig({ "@ogw_tests": path.resolve(__dirname, "tests"), "@ogw_shared": path.resolve(__dirname, "shared"), "@ogw_server": path.resolve(__dirname, "server"), - "@geode/opengeodeweb-front/shared": path.resolve(__dirname, "shared"), }, // ** Global CSS diff --git a/tests/vitest.config.js b/tests/vitest.config.js index 4dd35e974..9daf0e533 100644 --- a/tests/vitest.config.js +++ b/tests/vitest.config.js @@ -15,13 +15,13 @@ const CI_WORKERS = 2; const globalRetry = process.env.CI ? RETRIES : DEFAULT_RETRY; const maxWorkers = process.env.CI ? CI_WORKERS : 3; +const aliases = { + "@ogw_tests": path.resolve(__dirname, "."), + "@geode/opengeodeweb-front/shared": path.resolve(__dirname, "..", "shared"), +}; + // oxlint-disable-next-line import/no-default-export export default defineConfig({ - resolve: { - alias: { - "@ogw_tests": path.resolve(__dirname, "."), - }, - }, test: { setupFiles: [path.resolve(__dirname, "./setup_indexeddb.js")], projects: [ @@ -32,6 +32,7 @@ export default defineConfig({ include: ["tests/unit/**/*.test.js"], globals: true, environment: "nuxt", + alias: aliases, testTimeout: TIMEOUTS.unit, setupFiles: [path.resolve(__dirname, "./setup_indexeddb.js")], server: { @@ -49,6 +50,7 @@ export default defineConfig({ include: ["tests/integration/**/*.test.js"], globals: true, environment: "nuxt", + alias: aliases, maxWorkers, testTimeout: TIMEOUTS.integration, setupFiles: [path.resolve(__dirname, "./setup_indexeddb.js")], From 5a6e14603ba1c2e31f4a279fc035450c624c814f Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Fri, 31 Jul 2026 10:50:16 +0200 Subject: [PATCH 18/22] fix --- app/stores/app.js | 2 +- app/stores/cloud.js | 2 + internal/utils/api_fetch.js | 1 + server/api/local/extensions/upload.put.js | 2 +- .../microservice/app/set_app_base_url.post.js | 25 ++++++++++++ .../microservice/extensions/download.post.js | 2 +- .../api/microservice/extensions/kill.post.js | 2 +- .../api/microservice/extensions/run.post.js | 2 +- server/utils/{config.js => app_config.js} | 0 server/utils/scripts.js | 5 ++- server/utils/server_config.js | 38 +++++++++++++++++++ shared/scripts.js | 18 +++++++++ 12 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 server/api/microservice/app/set_app_base_url.post.js rename server/utils/{config.js => app_config.js} (100%) create mode 100644 server/utils/server_config.js create mode 100644 shared/scripts.js diff --git a/app/stores/app.js b/app/stores/app.js index 882b0e94d..0a20e081a 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -9,7 +9,7 @@ import { useInfraStore } from "@ogw_front/stores/infra"; // oxlint-disable-next-line max-lines-per-function, max-statements export const useAppStore = defineStore("app", () => { const stores = []; - const default_local_port = ref("3000"); + const default_local_port = ref(globalThis.location.port); const status = ref(Status.NOT_CONNECTED); const protocol = computed(() => getRestApiProtocol()); diff --git a/app/stores/cloud.js b/app/stores/cloud.js index 2852da698..6a478b93b 100644 --- a/app/stores/cloud.js +++ b/app/stores/cloud.js @@ -1,4 +1,5 @@ import { Status } from "@ogw_front/utils/status"; +import { setAppBaseUrl } from "@ogw_shared/scripts"; import { useAppStore } from "./app"; import { useFeedbackStore } from "./feedback"; import { useInfraStore } from "./infra"; @@ -40,6 +41,7 @@ export const useCloudStore = defineStore("cloud", { infraStore.$patch({ domain_name: response.url, }); + setAppBaseUrl(appStore.base_url); }, response_error_function: () => { feedbackStore.$patch({ server_error: true }); diff --git a/internal/utils/api_fetch.js b/internal/utils/api_fetch.js index 086e48cf3..954810c0c 100644 --- a/internal/utils/api_fetch.js +++ b/internal/utils/api_fetch.js @@ -9,6 +9,7 @@ export function api_fetch( { schema, params, headers }, { request_error_function, response_function, response_error_function, timeout } = {}, ) { + console.log("[API] Fetching", microservice.base_url); const feedbackStore = useFeedbackStore(); const body = params || {}; diff --git a/server/api/local/extensions/upload.put.js b/server/api/local/extensions/upload.put.js index 1dc8aa685..4c6cfc91f 100644 --- a/server/api/local/extensions/upload.put.js +++ b/server/api/local/extensions/upload.put.js @@ -11,7 +11,7 @@ import busboy from "busboy"; import { registerExtensionFile, targetExtensionFilePath, -} from "@geode/opengeodeweb-front/server/utils/config.js"; +} from "@geode/opengeodeweb-front/server/utils/app_config.js"; const CODE_201 = 201; const FILE_SIZE_LIMIT = 107_374_182; diff --git a/server/api/microservice/app/set_app_base_url.post.js b/server/api/microservice/app/set_app_base_url.post.js new file mode 100644 index 000000000..fb8dc99f4 --- /dev/null +++ b/server/api/microservice/app/set_app_base_url.post.js @@ -0,0 +1,25 @@ +// Third party imports +import { createError, defineEventHandler, readBody } from "h3"; + +// Local imports +import { setAppBaseUrl } from "@geode/opengeodeweb-front/server/utils/server_config.js"; + +export default defineEventHandler(async (event) => { + try { + const { baseUrl } = await readBody(event); + if (!baseUrl) { + throw createError({ statusCode: 400, statusMessage: "baseUrl is required" }); + } + + await setAppBaseUrl(baseUrl); + console.log(`Updated APP_BASE_URL to ${baseUrl}`); + + return { statusCode: 200, baseUrl }; + } catch (error) { + console.log(error); + throw createError({ + statusCode: error.statusCode, + statusMessage: error.statusMessage ?? error.message, + }); + } +}); diff --git a/server/api/microservice/extensions/download.post.js b/server/api/microservice/extensions/download.post.js index e6dc1f9a4..ea33ef4e0 100644 --- a/server/api/microservice/extensions/download.post.js +++ b/server/api/microservice/extensions/download.post.js @@ -8,7 +8,7 @@ import { createError, defineEventHandler, readBody } from "h3"; import { registerExtensionFile, targetExtensionFilePath, -} from "@geode/opengeodeweb-front/server/utils/config.js"; +} from "@geode/opengeodeweb-front/server/utils/app_config.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/microservice/extensions/kill.post.js b/server/api/microservice/extensions/kill.post.js index ae67af842..acf4246c8 100644 --- a/server/api/microservice/extensions/kill.post.js +++ b/server/api/microservice/extensions/kill.post.js @@ -11,7 +11,7 @@ import { projectMicroservices, } from "@geode/opengeodeweb-front/server/utils/cleanup.js"; import { extensionFolderPath } from "@geode/opengeodeweb-front/server/utils/path.js"; -import { removeExtensionFromConf } from "@geode/opengeodeweb-front/server/utils/config.js"; +import { removeExtensionFromConf } from "@geode/opengeodeweb-front/server/utils/app_config.js"; export default defineEventHandler(async (event) => { try { diff --git a/server/api/microservice/extensions/run.post.js b/server/api/microservice/extensions/run.post.js index ae852aefd..4297209c2 100644 --- a/server/api/microservice/extensions/run.post.js +++ b/server/api/microservice/extensions/run.post.js @@ -15,7 +15,7 @@ import { extensionFolderPath, extensionFrontendPath, } from "@geode/opengeodeweb-front/server/utils/path.js"; -import { extensionsConf } from "@geode/opengeodeweb-front/server/utils/config.js"; +import { extensionsConf } from "@geode/opengeodeweb-front/server/utils/app_config.js"; import { unzipFile } from "@geode/opengeodeweb-front/server/utils/server.js"; export default defineEventHandler(async (event) => { diff --git a/server/utils/config.js b/server/utils/app_config.js similarity index 100% rename from server/utils/config.js rename to server/utils/app_config.js diff --git a/server/utils/scripts.js b/server/utils/scripts.js index d23446108..b57f3b8a2 100644 --- a/server/utils/scripts.js +++ b/server/utils/scripts.js @@ -10,6 +10,7 @@ import { getPort } from "get-port-please"; // Local imports import { appMode } from "@geode/opengeodeweb-front/shared/app_mode.js"; +import { setAppBaseUrl } from "@geode/opengeodeweb-front/shared/scripts.js"; const BYTES_PER_KIBIBYTE = 1024; const MAX_ERROR_BUFFER_KIBIBYTES = 64; @@ -164,7 +165,9 @@ async function runBrowser(scriptName) { PORT: port, }, }); - return await waitNuxt(nuxtProcess); + await waitNuxt(nuxtProcess); + await setAppBaseUrl(`http://localhost:${port}`); + return port; } export { commandExistsSync, getAvailablePort, runBrowser, waitForReady }; diff --git a/server/utils/server_config.js b/server/utils/server_config.js new file mode 100644 index 000000000..51fa0acc6 --- /dev/null +++ b/server/utils/server_config.js @@ -0,0 +1,38 @@ +import { useStorage } from "#imports"; + +function getConfig() { + return useStorage("config"); +} +function getAppBaseUrl() { + const config = getConfig(); + return config.getItem("APP_BASE_URL"); +} +function setAppBaseUrl(baseUrl) { + const config = getConfig(); + return config.setItem("APP_BASE_URL", baseUrl); +} +function getBackBaseUrl() { + const config = getConfig(); + return config.getItem("BACK_BASE_URL"); +} +function setBackBaseUrl(baseUrl) { + const config = getConfig(); + return config.setItem("BACK_BASE_URL", baseUrl); +} +function getViewerBaseUrl() { + const config = getConfig(); + return config.getItem("VIEWER_BASE_URL"); +} +function setViewerBaseUrl(baseUrl) { + const config = getConfig(); + return config.setItem("VIEWER_BASE_URL", baseUrl); +} + +export { + getAppBaseUrl, + setAppBaseUrl, + getBackBaseUrl, + getViewerBaseUrl, + setBackBaseUrl, + setViewerBaseUrl, +}; diff --git a/shared/scripts.js b/shared/scripts.js new file mode 100644 index 000000000..c19bb4e65 --- /dev/null +++ b/shared/scripts.js @@ -0,0 +1,18 @@ +// Node imports + +// Third party imports + +// Local imports + +function setAppBaseUrl(baseUrl) { + console.log(`Setting APP_BASE_URL to ${baseUrl}`); + return fetch(`${baseUrl}/api/microservice/app/set_app_base_url`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ baseUrl }), + }); +} + +export { setAppBaseUrl }; From 7b6c0e8fcc11174299381792f3835f491e182e8b Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Fri, 31 Jul 2026 10:58:19 +0200 Subject: [PATCH 19/22] fix --- tests/unit/stores/infra.nuxt.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/stores/infra.nuxt.test.js b/tests/unit/stores/infra.nuxt.test.js index 744ac5c2d..95792c2d0 100644 --- a/tests/unit/stores/infra.nuxt.test.js +++ b/tests/unit/stores/infra.nuxt.test.js @@ -291,7 +291,7 @@ describe("infra store", () => { infraStore.app_mode = appMode.CLOUD; const url = "test.com"; - registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", { + registerEndpoint("https://localhost:443/api/serverless/run_cloud", { method: "POST", handler: () => ({ url }), }); From a9ecec85942473aaa3f4bc263a71f9675f25422a Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Fri, 31 Jul 2026 11:04:03 +0200 Subject: [PATCH 20/22] test --- tests/unit/stores/cloud.nuxt.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/unit/stores/cloud.nuxt.test.js b/tests/unit/stores/cloud.nuxt.test.js index c31411727..c064a3a62 100644 --- a/tests/unit/stores/cloud.nuxt.test.js +++ b/tests/unit/stores/cloud.nuxt.test.js @@ -38,7 +38,7 @@ describe("cloud store", () => { const cloudStore = useCloudStore(); const feedbackStore = useFeedbackStore(); - registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", { + registerEndpoint("https://localhost:443/api/serverless/run_cloud", { method: "POST", handler: postFakeCall, }); @@ -58,7 +58,7 @@ describe("cloud store", () => { const cloudStore = useCloudStore(); const feedbackStore = useFeedbackStore(); - registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", { + registerEndpoint("https://localhost:443/api/serverless/run_cloud", { method: "POST", handler: postFakeCall, }); From fa5ac90c3f1d9cfb4d3cb91d7509986f0cd6eddb Mon Sep 17 00:00:00 2001 From: Arnaud Botella Date: Fri, 31 Jul 2026 11:11:02 +0200 Subject: [PATCH 21/22] revert --- tests/unit/stores/cloud.nuxt.test.js | 4 ++-- tests/unit/stores/infra.nuxt.test.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/unit/stores/cloud.nuxt.test.js b/tests/unit/stores/cloud.nuxt.test.js index c064a3a62..c31411727 100644 --- a/tests/unit/stores/cloud.nuxt.test.js +++ b/tests/unit/stores/cloud.nuxt.test.js @@ -38,7 +38,7 @@ describe("cloud store", () => { const cloudStore = useCloudStore(); const feedbackStore = useFeedbackStore(); - registerEndpoint("https://localhost:443/api/serverless/run_cloud", { + registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", { method: "POST", handler: postFakeCall, }); @@ -58,7 +58,7 @@ describe("cloud store", () => { const cloudStore = useCloudStore(); const feedbackStore = useFeedbackStore(); - registerEndpoint("https://localhost:443/api/serverless/run_cloud", { + registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", { method: "POST", handler: postFakeCall, }); diff --git a/tests/unit/stores/infra.nuxt.test.js b/tests/unit/stores/infra.nuxt.test.js index 95792c2d0..744ac5c2d 100644 --- a/tests/unit/stores/infra.nuxt.test.js +++ b/tests/unit/stores/infra.nuxt.test.js @@ -291,7 +291,7 @@ describe("infra store", () => { infraStore.app_mode = appMode.CLOUD; const url = "test.com"; - registerEndpoint("https://localhost:443/api/serverless/run_cloud", { + registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", { method: "POST", handler: () => ({ url }), }); From ec036a8bafbce1ec2b3f78fb1bed4d173cb2fdc0 Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Fri, 31 Jul 2026 11:51:33 +0200 Subject: [PATCH 22/22] fix unit tests --- tests/unit/stores/cloud.nuxt.test.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/unit/stores/cloud.nuxt.test.js b/tests/unit/stores/cloud.nuxt.test.js index c31411727..a51787829 100644 --- a/tests/unit/stores/cloud.nuxt.test.js +++ b/tests/unit/stores/cloud.nuxt.test.js @@ -43,8 +43,13 @@ describe("cloud store", () => { handler: postFakeCall, }); + registerEndpoint("https://test.com:443/server/api/microservice/app/set_app_base_url", { + method: "POST", + handler: () => console.log("coucou from endpoint"), + }); + postFakeCall.mockReturnValue({ - url: "http://test.com", + url: "test.com", }); const email = "noreply@example.com"; await cloudStore.launch(email);