diff --git a/app/components/ObjectSelector.vue b/app/components/ObjectSelector.vue
index 616390ddc..3b0ca5b49 100644
--- a/app/components/ObjectSelector.vue
+++ b/app/components/ObjectSelector.vue
@@ -1,6 +1,7 @@
-
-
+
+
@@ -139,7 +89,7 @@ await get_allowed_objects();
-
+
These files cannot be loaded together because they don't share a common data type.
diff --git a/app/composables/project_manager.js b/app/composables/project_manager.js
index b053e3f3e..ea243407f 100644
--- a/app/composables/project_manager.js
+++ b/app/composables/project_manager.js
@@ -2,8 +2,8 @@ import back_schemas from "@geode/opengeodeweb-back/opengeodeweb_back_schemas.jso
import fileDownload from "js-file-download";
import viewer_schemas from "@geode/opengeodeweb-viewer/opengeodeweb_viewer_schemas.json";
+import { fetchRaw } from "@ogw_shared/utils/fetch_raw";
import { importWorkflowFromSnapshot } from "@ogw_front/utils/import_workflow";
-
import { useAppStore } from "@ogw_front/stores/app";
import { useBackStore } from "@ogw_front/stores/back";
import { useDataStore } from "@ogw_front/stores/data";
@@ -21,12 +21,14 @@ async function exportProject() {
const snapshot = await appStore.exportStores();
const schema = back_schemas.opengeodeweb_back.export_project;
const defaultName = "project.vease";
-
- const result = await $fetch(schema.$id, {
+ const params = { snapshot, filename: defaultName };
+ const result = await fetchRaw({
+ route: schema.$id,
+ params,
+ method: schema.methods[0],
baseURL: backStore.base_url,
- method: schema.methods.find((method) => method !== "OPTIONS"),
- body: { snapshot, filename: defaultName },
});
+
fileDownload(result, defaultName);
feedbackStore.add_success("Project exported successfully");
return { result };
@@ -46,15 +48,15 @@ async function importProject(file) {
if (client && client.getConnection && client.getConnection().getSession) {
await client.getConnection().getSession().call("opengeodeweb_viewer.release_database", [{}]);
}
- const schema = viewer_schemas.opengeodeweb_viewer.viewer.reset_visualization;
+ const resetVisualizationSchema = viewer_schemas.opengeodeweb_viewer.viewer.reset_visualization;
const timeout = undefined;
- await viewerStore.request({ schema, timeout });
+ await viewerStore.request({ schema: resetVisualizationSchema, timeout });
treeviewStore.clear();
dataStore.clear();
hybridViewerStore.clear();
- const schemaImport = back_schemas.opengeodeweb_back.import_project;
+ const importProjectSchema = back_schemas.opengeodeweb_back.import_project;
const form = new FormData();
const originalFileName = file && file.name ? file.name : "project.vease";
if (!originalFileName.toLowerCase().endsWith(".vease")) {
@@ -62,10 +64,11 @@ async function importProject(file) {
}
form.append("file", file, originalFileName);
- const result = await $fetch(schemaImport.$id, {
+ const result = await fetchRaw({
+ route: importProjectSchema.$id,
+ params: form,
+ method: importProjectSchema.methods[0],
baseURL: backStore.base_url,
- method: "POST",
- body: form,
});
const snapshot = result && result.snapshot ? result.snapshot : {};
diff --git a/app/stores/app.js b/app/stores/app.js
index cc970776b..3c291e5a5 100644
--- a/app/stores/app.js
+++ b/app/stores/app.js
@@ -227,13 +227,16 @@ export const useAppStore = defineStore("app", () => {
}
function upload(file, callbacks = {}) {
- const route = "/api/local/extensions/upload";
+ const schema = {
+ $id: "/api/local/extensions/upload",
+ methods: ["OPTIONS", "PUT"],
+ };
const store = useAppStore();
const { PROJECT: projectName } = useRuntimeConfig().public;
const params = { projectName };
return upload_file(
store,
- { route, file, params },
+ { schema, file, params },
{
...callbacks,
response_function: async (response) => {
@@ -247,16 +250,13 @@ export const useAppStore = defineStore("app", () => {
}
function request({ schema, params }, callbacks = {}) {
- console.log("[APP] Request:", schema.$id);
-
const store = useAppStore();
return api_fetch(
store,
- { schema, params, headers: {} },
+ { schema, params },
{
...callbacks,
response_function: async (response) => {
- console.log("[APP] Request completed:", schema.$id);
if (callbacks.response_function) {
await callbacks.response_function(response);
}
@@ -274,7 +274,8 @@ export const useAppStore = defineStore("app", () => {
}
const is_busy = computed(() => request_counter.value > 0);
- const projectFolderPath = ref(isCloudMode() ? "/project" : "");
+ const projectFolderPath = ref("");
+
function createProjectFolder() {
const { PROJECT } = useRuntimeConfig().public;
const schema = {
diff --git a/app/stores/back.js b/app/stores/back.js
index 8b6ff01e8..7469f705b 100644
--- a/app/stores/back.js
+++ b/app/stores/back.js
@@ -104,22 +104,12 @@ export const useBackStore = defineStore("back", {
return Promise.resolve();
},
request({ schema, params = {} }, callbacks = {}) {
- console.log("[GEODE] Request:", schema.$id);
- const start = Date.now();
-
return api_fetch(
this,
{ schema, params, headers: {} },
{
...callbacks,
response_function: async (response) => {
- console.log(
- "[GEODE] Request completed:",
- schema.$id,
- "in",
- (Date.now() - start) / MILLISECONDS_IN_SECOND,
- "s",
- );
if (callbacks.response_function) {
await callbacks.response_function(response);
}
@@ -128,17 +118,16 @@ export const useBackStore = defineStore("back", {
);
},
upload(file, callbacks = {}) {
- const route = back_schemas.opengeodeweb_back.upload_file.$id;
+ const schema = back_schemas.opengeodeweb_back.upload_file;
return upload_file(
this,
{
- route,
+ schema,
file,
},
{
...callbacks,
response_function: async (response) => {
- console.log("[GEODE] Request completed:", route);
if (callbacks.response_function) {
await callbacks.response_function(response);
}
diff --git a/app/stores/cloud.js b/app/stores/cloud.js
index cba02438e..1ad35f43d 100644
--- a/app/stores/cloud.js
+++ b/app/stores/cloud.js
@@ -43,6 +43,9 @@ export const useCloudStore = defineStore("cloud", {
domain_name: response.url,
});
setAppBaseUrl(appStore.base_url);
+ appStore.$patch({
+ projectFolderPath: "/project",
+ });
},
response_error_function: () => {
feedbackStore.$patch({ server_error: true });
diff --git a/app/stores/infra.js b/app/stores/infra.js
index bb8a865b7..1136a014a 100644
--- a/app/stores/infra.js
+++ b/app/stores/infra.js
@@ -77,11 +77,6 @@ export const useInfraStore = defineStore("infra", {
},
async create_connection() {
console.log("[INFRA] Starting create_connection");
- console.log(
- "[INFRA] Connecting microservices:",
- this.microservices.map((store) => store.$id),
- );
-
await Promise.all(
this.microservices.map(async (store) => {
console.log("[INFRA] Connecting to microservice:", store.$id);
diff --git a/app/stores/viewer.js b/app/stores/viewer.js
index e3763a271..f647533a7 100644
--- a/app/stores/viewer.js
+++ b/app/stores/viewer.js
@@ -156,25 +156,13 @@ export const useViewerStore = defineStore(
}
function request({ schema, params = {}, timeout = request_timeout }, callbacks = {}) {
- console.log("[VIEWER] Request:", schema.$id);
- const start = Date.now();
-
- // Get current store instance to pass to viewer_call
const store = useViewerStore();
-
return viewer_call(
store,
{ schema, params, timeout },
{
...callbacks,
response_function: async (response) => {
- console.log(
- "[VIEWER] Request completed:",
- schema.$id,
- "in",
- (Date.now() - start) / MS_PER_SECOND,
- "s",
- );
if (callbacks.response_function) {
await callbacks.response_function(response);
}
diff --git a/app/utils/import_workflow.js b/app/utils/import_workflow.js
index c6364808c..f4a410e75 100644
--- a/app/utils/import_workflow.js
+++ b/app/utils/import_workflow.js
@@ -35,13 +35,6 @@ async function importWorkflow(files) {
return results;
}
-function buildImportItemFromPayloadApi(value, geode_object_type) {
- return {
- geode_object_type,
- ...value,
- };
-}
-
async function importItem(item) {
const dataStore = useDataStore();
const dataStyleStore = useDataStyleStore();
@@ -94,8 +87,7 @@ async function importFile(filename, geode_object_type) {
filename,
};
const response = await backStore.request({ schema, params });
- const item = buildImportItemFromPayloadApi(response, geode_object_type);
- return importItem(item);
+ return importItem(response);
}
async function importWorkflowFromSnapshot(items) {
diff --git a/app/utils/log.js b/app/utils/log.js
new file mode 100644
index 000000000..6fd4bf54a
--- /dev/null
+++ b/app/utils/log.js
@@ -0,0 +1,18 @@
+function startRequestLog(microservice, schema) {
+ console.log(`[${microservice.$id}] Request:`, schema.$id);
+ const requestStartingTime = new Date(Date.now());
+ return requestStartingTime;
+}
+
+function endRequestLog(microservice, schema, requestStartingTime) {
+ const requestEndingTime = new Date(Date.now());
+ console.log(
+ `[${microservice.$id}] Request completed:`,
+ schema.$id,
+ "in",
+ requestEndingTime.getSeconds() - requestStartingTime.getSeconds(),
+ "s",
+ );
+}
+
+export { startRequestLog, endRequestLog };
diff --git a/app/utils/validate_schema.js b/app/utils/validate_schema.js
deleted file mode 100644
index e1b59aa4f..000000000
--- a/app/utils/validate_schema.js
+++ /dev/null
@@ -1,13 +0,0 @@
-import Ajv from "ajv";
-
-function validate_schema(schema, body) {
- const ajv = new Ajv();
- const list_keywords = ["methods", "route", "max_retry", "rpc"];
- for (const keyword of list_keywords) {
- ajv.addKeyword(keyword);
- }
- const valid = ajv.validate(schema, body);
- return { valid, error: ajv.errorsText() };
-}
-
-export { validate_schema };
diff --git a/internal/utils/api_fetch.js b/internal/utils/api_fetch.js
index 954810c0c..a417b1e78 100644
--- a/internal/utils/api_fetch.js
+++ b/internal/utils/api_fetch.js
@@ -1,79 +1,52 @@
-import _ from "lodash";
+import { endRequestLog, startRequestLog } from "@ogw_front/utils/log";
+import { fetchSchema } from "@ogw_shared/utils/fetch_schema";
import { useFeedbackStore } from "@ogw_front/stores/feedback";
-import { validate_schema } from "@ogw_front/utils/validate_schema";
-
-const ERROR_400 = 400;
export function api_fetch(
microservice,
- { schema, params, headers },
+ { 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 || {};
-
- const { valid, error: schema_error } = validate_schema(schema, body);
-
- if (!valid) {
- if (process.env.NODE_ENV !== "production") {
- console.log("Bad request", schema_error, schema, params);
- }
- feedbackStore.add_error(ERROR_400, schema.$id, "Bad request", schema_error);
- throw new Error(`${schema.$id}: ${schema_error}`);
- }
-
microservice.start_request();
- const method = schema.methods.find((methodItem) => methodItem !== "OPTIONS");
- const request_options = {
- method,
- headers,
- };
- if (!_.isEmpty(body)) {
- request_options.body = body;
- }
-
- if (schema.max_retry) {
- request_options.max_retry = schema.max_retry;
- }
-
- function performFetch() {
- return $fetch(schema.$id, {
+ const requestStartingTime = startRequestLog(microservice, schema);
+ return fetchSchema(
+ {
+ schema,
baseURL: microservice.base_url,
- ...request_options,
- onRequestError({ error }) {
+ params,
+ headers,
+ max_retry: schema.max_retry,
+ timeout,
+ },
+ {
+ request_error_function(error) {
microservice.stop_request();
feedbackStore.add_error(error.code, schema.$id, error.message, error.stack);
if (request_error_function) {
request_error_function(error);
}
},
- onResponse({ response }) {
- if (response.ok) {
- microservice.stop_request();
- if (response_function) {
- response_function(response._data);
- }
+ response_function(data) {
+ endRequestLog(microservice, schema, requestStartingTime);
+ microservice.stop_request();
+ if (response_function) {
+ response_function(data);
}
},
- onResponseError({ response }) {
+ response_error_function(response) {
microservice.stop_request();
feedbackStore.add_error(response.status, schema.$id, response.name, response.description);
if (response_error_function) {
response_error_function(response);
}
},
- });
- }
-
- if (timeout > 0) {
- return pTimeout(performCall(), {
- milliseconds: timeout,
- message: `${schema.$id}: Timed out after ${timeout}ms`,
- });
- }
-
- return performFetch();
+ validation_error_function({ code, name, error }) {
+ microservice.stop_request();
+ feedbackStore.add_error(code, schema.$id, name, error);
+ },
+ },
+ );
}
diff --git a/internal/utils/upload_file.js b/internal/utils/upload_file.js
index 8ad91b987..5cb6f183e 100644
--- a/internal/utils/upload_file.js
+++ b/internal/utils/upload_file.js
@@ -1,14 +1,16 @@
+import { fetchRaw } from "@ogw_shared/utils/fetch_raw.js";
import { useFeedbackStore } from "@ogw_front/stores/feedback.js";
-async function upload_file(
+function upload_file(
microservice,
- { route, file, params = {} },
+ { schema, file, params = {} },
{ request_error_function, response_function, response_error_function } = {},
) {
- console.log("[UPLOAD_FILE] Uploading file", { route, file });
+ console.log("[UPLOAD_FILE] Uploading file", { schema, file });
const feedbackStore = useFeedbackStore();
+
if (!(file instanceof File)) {
- throw new Error("file must be a instance of File");
+ return Promise.reject(new Error("file must be an instance of File"));
}
const body = new FormData();
@@ -17,37 +19,39 @@ async function upload_file(
}
body.append("file", file);
- const request_options = {
- method: "PUT",
- body,
- };
microservice.start_request();
- return await $fetch(route, {
- baseURL: microservice.base_url || "",
- ...request_options,
- onRequestError({ error }) {
- microservice.stop_request();
- feedbackStore.add_error(error.code, route, error.message, error.stack);
- if (request_error_function) {
- request_error_function(error);
- }
+ const route = schema.$id;
+
+ return fetchRaw(
+ {
+ route,
+ method: schema.methods.find((method) => method !== "OPTIONS"),
+ params: body,
+ baseURL: microservice.base_url,
},
- onResponse({ response }) {
- if (response.ok) {
+ {
+ request_error_function(error) {
+ microservice.stop_request();
+ feedbackStore.add_error(error.code, route, error.message, error.stack);
+ if (request_error_function) {
+ request_error_function(error);
+ }
+ },
+ response_function(data) {
microservice.stop_request();
if (response_function) {
- response_function(response);
+ response_function(data);
}
- }
- },
- onResponseError({ response }) {
- microservice.stop_request();
- feedbackStore.add_error(response.status, route, response.name, response.description);
- if (response_error_function) {
- response_error_function(response);
- }
+ },
+ response_error_function(response) {
+ microservice.stop_request();
+ feedbackStore.add_error(response.status, route, response.name, response.description);
+ if (response_error_function) {
+ response_error_function(response);
+ }
+ },
},
- });
+ );
}
export { upload_file };
diff --git a/internal/utils/viewer_call.js b/internal/utils/viewer_call.js
index 127933f5a..d03a98484 100644
--- a/internal/utils/viewer_call.js
+++ b/internal/utils/viewer_call.js
@@ -1,6 +1,10 @@
+// Third party imports
import pTimeout from "p-timeout";
+
+// Local imports
+import { endRequestLog, startRequestLog } from "@ogw_front/utils/log";
import { useFeedbackStore } from "@ogw_front/stores/feedback";
-import { validate_schema } from "@ogw_front/utils/validate_schema";
+import { validate_schema } from "@ogw_shared/utils/validate_schema";
const ERROR_400 = 400;
@@ -28,9 +32,10 @@ export function viewer_call(
return;
}
microservice.start_request();
-
+ const requestStart = startRequestLog(microservice, schema);
try {
const value = await client.getConnection().getSession().call(schema.$id, [params]);
+ endRequestLog(microservice, schema, requestStart);
if (response_function) {
await response_function(value);
}
diff --git a/nuxt.config.js b/nuxt.config.js
index 9843dc225..f01973c08 100644
--- a/nuxt.config.js
+++ b/nuxt.config.js
@@ -69,10 +69,4 @@ export default defineNuxtConfig({
],
},
},
-
- nitro: {
- rollupConfig: {
- external: ["events", "node:events"],
- },
- },
});
diff --git a/package.json b/package.json
index c20d035e7..8d0f3b95c 100644
--- a/package.json
+++ b/package.json
@@ -62,6 +62,7 @@
"sanitize-filename": "1.6.3",
"sass": "1.87.0",
"semver": "7.7.1",
+ "unstorage": "1.17.5",
"uuid": "11.1.0",
"vuetify": "3.12.5",
"vuetify-nuxt-module": "0.18.7",
diff --git a/server/api/microservice/app/set_back_base_url.post.js b/server/api/microservice/app/set_back_base_url.post.js
new file mode 100644
index 000000000..068334a1e
--- /dev/null
+++ b/server/api/microservice/app/set_back_base_url.post.js
@@ -0,0 +1,22 @@
+// Third party imports
+import { createError, defineEventHandler, readBody } from "h3";
+
+// Local imports
+import { setBackBaseUrl } 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 setBackBaseUrl(baseUrl);
+ return { statusCode: 200, baseUrl };
+ } catch (error) {
+ console.log(error);
+ throw createError({
+ statusCode: error.statusCode,
+ statusMessage: error.message,
+ });
+ }
+});
diff --git a/server/api/microservice/app/set_viewer_base_url.post.js b/server/api/microservice/app/set_viewer_base_url.post.js
new file mode 100644
index 000000000..b59c9685d
--- /dev/null
+++ b/server/api/microservice/app/set_viewer_base_url.post.js
@@ -0,0 +1,22 @@
+// Third party imports
+import { createError, defineEventHandler, readBody } from "h3";
+
+// Local imports
+import { setViewerBaseUrl } 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 setViewerBaseUrl(baseUrl);
+ return { statusCode: 200, baseUrl };
+ } catch (error) {
+ console.log(error);
+ throw createError({
+ statusCode: error.statusCode,
+ statusMessage: error.message,
+ });
+ }
+});
diff --git a/server/api/serverless/run_cloud.js b/server/api/serverless/run_cloud.post.js
similarity index 100%
rename from server/api/serverless/run_cloud.js
rename to server/api/serverless/run_cloud.post.js
diff --git a/server/utils/server_config.js b/server/utils/server_config.js
index 51fa0acc6..6a3eaf844 100644
--- a/server/utils/server_config.js
+++ b/server/utils/server_config.js
@@ -1,30 +1,24 @@
-import { useStorage } from "#imports";
+import { createStorage, prefixStorage } from "unstorage";
+
+const storage = createStorage();
+const config = prefixStorage(storage, "config");
-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);
}
diff --git a/shared/scripts.js b/shared/scripts.js
index c19bb4e65..f754488a9 100644
--- a/shared/scripts.js
+++ b/shared/scripts.js
@@ -3,16 +3,54 @@
// Third party imports
// Local imports
+import { fetchSchema } from "./utils/fetch_schema.js";
-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",
+function setAppBaseUrl(appBaseUrl) {
+ console.log("[API] setAppBaseUrl", appBaseUrl);
+ const schema = {
+ $id: "/api/microservice/app/set_app_base_url",
+ methods: ["POST"],
+ type: "object",
+ properties: {
+ baseUrl: { type: "string" },
},
- body: JSON.stringify({ baseUrl }),
- });
+ required: ["baseUrl"],
+ additionalProperties: false,
+ };
+ const params = { baseUrl: appBaseUrl };
+ return fetchSchema({ schema, params, baseURL: appBaseUrl });
}
-export { setAppBaseUrl };
+function setBackBaseUrl(appBaseUrl, backBaseUrl) {
+ console.log("[API] setBackBaseUrl", appBaseUrl, backBaseUrl);
+ const schema = {
+ $id: "/api/microservice/app/set_back_base_url",
+ methods: ["POST"],
+ type: "object",
+ properties: {
+ baseUrl: { type: "string" },
+ },
+ required: ["baseUrl"],
+ additionalProperties: false,
+ };
+ const params = { baseUrl: backBaseUrl };
+ return fetchSchema({ schema, params, baseURL: appBaseUrl });
+}
+
+function setViewerBaseUrl(appBaseUrl, viewerBaseUrl) {
+ console.log("[API] setViewerBaseUrl", appBaseUrl, viewerBaseUrl);
+ const schema = {
+ $id: "/api/microservice/app/set_viewer_base_url",
+ methods: ["POST"],
+ type: "object",
+ properties: {
+ baseUrl: { type: "string" },
+ },
+ required: ["baseUrl"],
+ additionalProperties: false,
+ };
+ const params = { baseUrl: viewerBaseUrl };
+ return fetchSchema({ schema, params, baseURL: appBaseUrl });
+}
+
+export { setAppBaseUrl, setBackBaseUrl, setViewerBaseUrl };
diff --git a/shared/utils/fetch_raw.js b/shared/utils/fetch_raw.js
index f9bf43c36..638236cab 100644
--- a/shared/utils/fetch_raw.js
+++ b/shared/utils/fetch_raw.js
@@ -1,4 +1,5 @@
// Third party imports
+import { $fetch } from "ofetch";
import _ from "lodash";
import pTimeout from "p-timeout";
diff --git a/shared/utils/response_handlers/load.js b/shared/utils/response_handlers/load.js
new file mode 100644
index 000000000..94c12ef4e
--- /dev/null
+++ b/shared/utils/response_handlers/load.js
@@ -0,0 +1,74 @@
+function getFileExtension(filename) {
+ return filename.slice(filename.lastIndexOf(".") + 1);
+}
+
+function selectGeodeObject(objectMap) {
+ const objectKeys = Object.keys(objectMap);
+ if (objectKeys.length === 0) {
+ return undefined;
+ }
+ if (objectKeys.length === 1 && objectMap[objectKeys[0]].is_loadable > 0) {
+ return objectKeys[0];
+ }
+
+ const highestLoadScore = Math.max(...objectKeys.map((key) => objectMap[key].is_loadable));
+ if (highestLoadScore <= 0) {
+ return undefined;
+ }
+
+ const bestScoreObjects = objectKeys.filter(
+ (key) => objectMap[key].is_loadable === highestLoadScore,
+ );
+ if (bestScoreObjects.length === 1) {
+ return bestScoreObjects[0];
+ }
+
+ const highestPriority = Math.max(
+ ...bestScoreObjects.map((key) => objectMap[key].object_priority ?? -Infinity),
+ );
+ const bestPriorityObjects = bestScoreObjects.filter(
+ (key) => objectMap[key].object_priority === highestPriority,
+ );
+ if (highestPriority !== -Infinity && bestPriorityObjects.length === 1) {
+ return bestPriorityObjects[0];
+ }
+
+ return undefined;
+}
+
+function intersectAllowedObjects(allowedObjectsList) {
+ const allKeys = [...new Set(allowedObjectsList.flatMap((object) => Object.keys(object)))];
+ const commonKeys = allKeys.filter((key) => allowedObjectsList.every((object) => key in object));
+
+ const mergedAllowedObjects = {};
+ for (const key of commonKeys) {
+ const loadScores = allowedObjectsList.map((object) => object[key].is_loadable);
+ const priorities = allowedObjectsList
+ .map((object) => object[key].object_priority)
+ .filter((priority) => priority !== undefined);
+
+ mergedAllowedObjects[key] = { is_loadable: Math.min(...loadScores) };
+ if (priorities.length > 0) {
+ mergedAllowedObjects[key].object_priority = Math.max(...priorities);
+ }
+ }
+
+ return { commonKeys, allKeys, mergedAllowedObjects };
+}
+
+function resolveAllowedObjects(filenames, allowedObjectsList) {
+ const { commonKeys, allKeys, mergedAllowedObjects } = intersectAllowedObjects(allowedObjectsList);
+
+ const multipleFilesNoCommon =
+ filenames.length > 1 && allKeys.length > 0 && commonKeys.length === 0;
+
+ const selectedGeodeObject = selectGeodeObject(mergedAllowedObjects);
+
+ return {
+ mergedAllowedObjects,
+ multipleFilesNoCommon,
+ selectedGeodeObject,
+ };
+}
+
+export { resolveAllowedObjects, getFileExtension };
diff --git a/tests/unit/composables/project_manager.nuxt.test.js b/tests/unit/composables/project_manager.nuxt.test.js
index eafc1aacc..41fe2d127 100644
--- a/tests/unit/composables/project_manager.nuxt.test.js
+++ b/tests/unit/composables/project_manager.nuxt.test.js
@@ -8,6 +8,12 @@ import { exportProject, importProject } from "@ogw_front/composables/project_man
import { appMode } from "@ogw_shared/app_mode";
import { setupActivePinia } from "@ogw_tests/utils";
+import { $fetch } from "ofetch";
+
+vi.mock(import("ofetch"), () => ({
+ $fetch: vi.fn(),
+}));
+
// Constants
const PANEL_WIDTH = 300;
const Z_SCALE = 1.5;
@@ -141,7 +147,12 @@ const hybridViewerStoreMock = {
};
// MOCKS
-vi.stubGlobal("$fetch", vi.fn().mockResolvedValue({ snapshot: snapshotMock }));
+$fetch.mockImplementation((route, options) => {
+ const data = { snapshot: snapshotMock };
+ // oxlint-disable-next-line eslint/id-length
+ options.onResponse?.({ response: { ok: true, _data: data } });
+ return Promise.resolve(data);
+});
vi.mock(import("@ogw_internal/utils/viewer_call"), () => ({
viewer_call: viewer_call_mock_fn,
}));
diff --git a/tests/unit/composables/upload_file.nuxt.test.js b/tests/unit/composables/upload_file.nuxt.test.js
index 6af978668..55e65520e 100644
--- a/tests/unit/composables/upload_file.nuxt.test.js
+++ b/tests/unit/composables/upload_file.nuxt.test.js
@@ -22,7 +22,7 @@ describe("upload_file", () => {
const backStore = useBackStore();
const file = "toto";
- await expect(backStore.upload(file)).rejects.toThrow("file must be a instance of File");
+ await expect(backStore.upload(file)).rejects.toThrow("file must be an instance of File");
});
test("onResponse", async () => {
@@ -36,7 +36,7 @@ describe("upload_file", () => {
let response_value = "";
await backStore.upload(file, {
response_function: (response) => {
- response_value = response._data.test;
+ response_value = response.test;
},
});
expect(feedbackStore.feedbacks).toHaveLength(ZERO);
diff --git a/tests/unit/stores/cloud.nuxt.test.js b/tests/unit/stores/cloud.nuxt.test.js
index a51787829..256449991 100644
--- a/tests/unit/stores/cloud.nuxt.test.js
+++ b/tests/unit/stores/cloud.nuxt.test.js
@@ -1,6 +1,6 @@
// Third party imports
import { beforeEach, describe, expect, expectTypeOf, test, vi } from "vitest";
-import { registerEndpoint } from "@nuxt/test-utils/runtime";
+import { $fetch } from "ofetch";
// Local imports
import { Status } from "@ogw_front/utils/status";
@@ -8,9 +8,12 @@ import { setupActivePinia } from "@ogw_tests/utils";
import { useCloudStore } from "@ogw_front/stores/cloud";
import { useFeedbackStore } from "@ogw_front/stores/feedback";
+vi.mock(import("ofetch"), () => ({
+ $fetch: vi.fn(),
+}));
+
// CONSTANTS
const PROJECT = "project";
-const STATUS_500 = 500;
function setupConfig() {
const config = useRuntimeConfig();
@@ -31,28 +34,23 @@ describe("cloud store", () => {
describe("actions", () => {
describe("launch", () => {
- const postFakeCall = vi.fn();
+ beforeEach(() => {
+ $fetch.mockReset();
+ });
test("successful launch", async () => {
setupConfig();
const cloudStore = useCloudStore();
const feedbackStore = useFeedbackStore();
- registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", {
- method: "POST",
- handler: postFakeCall,
+ $fetch.mockImplementation((route, options) => {
+ const data = { url: "test.com" };
+ // oxlint-disable-next-line eslint/id-length
+ options.onResponse?.({ response: { ok: true, _data: data } });
+ return Promise.resolve(data);
});
- registerEndpoint("https://test.com:443/server/api/microservice/app/set_app_base_url", {
- method: "POST",
- handler: () => console.log("coucou from endpoint"),
- });
-
- postFakeCall.mockReturnValue({
- url: "test.com",
- });
- const email = "noreply@example.com";
- await cloudStore.launch(email);
+ await cloudStore.launch("noreply@example.com");
expect(cloudStore.status).toBe(Status.CONNECTED);
expect(feedbackStore.server_error).toBe(false);
@@ -63,19 +61,18 @@ describe("cloud store", () => {
const cloudStore = useCloudStore();
const feedbackStore = useFeedbackStore();
- registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", {
- method: "POST",
- handler: postFakeCall,
- });
+ const error = createError({ statusCode: 500, statusMessage: "500 Internal Server Error" });
- postFakeCall.mockImplementation(() => {
- throw createError({
- status: STATUS_500,
- statusMessage: "Internal Server Error",
+ $fetch.mockImplementation((route, options) => {
+ options.onResponseError?.({
+ response: { status: 500, name: "Error", description: "500 Internal Server Error" },
});
+ return Promise.reject(error);
});
- const email = "noreply@example.com";
- await expect(cloudStore.launch(email)).rejects.toThrow("500 Internal Server Error");
+
+ await expect(cloudStore.launch("noreply@example.com")).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 744ac5c2d..0a82ff677 100644
--- a/tests/unit/stores/infra.nuxt.test.js
+++ b/tests/unit/stores/infra.nuxt.test.js
@@ -1,6 +1,6 @@
// Third party imports
import { beforeEach, describe, expect, expectTypeOf, test, vi } from "vitest";
-import { registerEndpoint } from "@nuxt/test-utils/runtime";
+import { $fetch } from "ofetch";
// Local imports
import { Status } from "@ogw_front/utils/status";
@@ -10,6 +10,10 @@ import { useBackStore } from "@ogw_front/stores/back";
import { useInfraStore } from "@ogw_front/stores/infra";
import { useViewerStore } from "@ogw_front/stores/viewer";
+vi.mock(import("ofetch"), () => ({
+ $fetch: vi.fn(),
+}));
+
// Mock navigator.locks API
const mockLockRequest = vi
.fn()
@@ -291,11 +295,14 @@ describe("infra store", () => {
infraStore.app_mode = appMode.CLOUD;
const url = "test.com";
- registerEndpoint("https://localhost:443/server/api/serverless/run_cloud", {
- method: "POST",
- handler: () => ({ url }),
+ $fetch.mockImplementation((route, options) => {
+ const data = { url };
+ // oxlint-disable-next-line eslint/id-length
+ options.onResponse?.({ response: { ok: true, _data: data } });
+ return Promise.resolve(data);
});
- await infraStore.create_backend("", "", false);
+
+ await infraStore.create_backend("noreply@example.com");
expect(infraStore.status).toBe(Status.CREATED);
expect(infraStore.domain_name).toBe(url);
diff --git a/tests/unit/utils/validate_schema.nuxt.test.js b/tests/unit/utils/validate_schema.nuxt.test.js
index dc5706f33..8fa29b267 100644
--- a/tests/unit/utils/validate_schema.nuxt.test.js
+++ b/tests/unit/utils/validate_schema.nuxt.test.js
@@ -2,7 +2,7 @@
import { describe, expect, test } from "vitest";
// Local imports
-import { validate_schema } from "@ogw_front/utils/validate_schema";
+import { validate_schema } from "@ogw_shared/utils/validate_schema";
// CONSTANTS
const MIN_0 = 0;