From 5871a71b7a2255cca53f5f7a59c5a8f93d8bde1a Mon Sep 17 00:00:00 2001 From: SpliiT Date: Tue, 25 Nov 2025 17:41:31 +0100 Subject: [PATCH 01/25] app js edited --- stores/app.js | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/stores/app.js b/stores/app.js index 4fb94817..a572b3dc 100644 --- a/stores/app.js +++ b/stores/app.js @@ -67,10 +67,143 @@ export const useAppStore = defineStore("app", () => { console.log(`[AppStore] Imported ${importedCount} stores`) } + // Extension loading system + const loadedExtensions = ref(new Map()) + const extensionAPI = ref(null) + + function setExtensionAPI(api) { + extensionAPI.value = api + } + + async function loadExtension(path) { + try { + // Check if already loaded + if (loadedExtensions.value.has(path)) { + console.warn(`[AppStore] Extension already loaded: ${path}`) + return loadedExtensions.value.get(path) + } + + if (!extensionAPI.value) { + throw new Error("Extension API not initialized") + } + + let finalURL = path + + // For blob URLs, we need to rewrite imports to use available modules + if (path.startsWith('blob:')) { + const response = await fetch(path) + let code = await response.text() + + // Replace Vue imports - handle all patterns including multiline + code = code.replace( + /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']vue["'];?/gs, + (match, namedImports, namespaceImport, defaultImport) => { + if (namedImports) { + // Named imports: import { ref, computed } from 'vue' + // Convert 'as' to ':' for object destructuring + const converted = namedImports.replace(/\s+as\s+/g, ': ') + return `const {${converted}} = window.__VUE_RUNTIME__;` + } else if (namespaceImport) { + // Namespace import: import * as Vue from 'vue' + return `const ${namespaceImport} = window.__VUE_RUNTIME__;` + } else if (defaultImport) { + // Default import: import Vue from 'vue' + return `const ${defaultImport} = window.__VUE_RUNTIME__;` + } + return match + } + ) + + // Replace Pinia imports + code = code.replace( + /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']pinia["'];?/gs, + (match, namedImports, namespaceImport, defaultImport) => { + if (namedImports) { + const converted = namedImports.replace(/\s+as\s+/g, ': ') + return `const {${converted}} = window.__PINIA__;` + } else if (namespaceImport) { + return `const ${namespaceImport} = window.__PINIA__;` + } else if (defaultImport) { + return `const ${defaultImport} = window.__PINIA__;` + } + return match + } + ) + + // Replace @geode/* imports - just comment them out for now + code = code.replace( + /import\s+[^;]+from\s+["']@geode\/[^"']+["'];?/gs, + (match) => `/* ${match} */ // External dependency - resolved at runtime\n` + ) + + // Replace @ogw_* imports + code = code.replace( + /import\s+[^;]+from\s+["']@ogw_[^"']+["'];?/gs, + (match) => `/* ${match} */ // External dependency - resolved at runtime\n` + ) + + console.log('[AppStore] Rewritten extension code preview:', code.substring(0, 800)) + + // Create new blob with rewritten code + const newBlob = new Blob([code], { type: 'application/javascript' }) + finalURL = URL.createObjectURL(newBlob) + } + + // Dynamic import of the extension module + const extensionModule = await import(/* @vite-ignore */ finalURL) + + // Clean up temporary blob URL + if (finalURL !== path && finalURL.startsWith('blob:')) { + URL.revokeObjectURL(finalURL) + } + + // Check if extension has an install function + if (typeof extensionModule.install === 'function') { + // Call install with the Extension API + await extensionModule.install(extensionAPI.value) + + // Store the loaded extension + const extensionData = { + module: extensionModule, + path, + loadedAt: new Date().toISOString(), + } + loadedExtensions.value.set(path, extensionData) + + console.log(`[AppStore] Extension loaded successfully: ${path}`) + + return extensionModule + } else { + throw new Error('Extension must export an install function') + } + } catch (error) { + console.error(`[AppStore] Failed to load extension from ${path}:`, error) + throw error + } + } + + function getLoadedExtensions() { + return Array.from(loadedExtensions.value.values()) + } + + function unloadExtension(path) { + if (loadedExtensions.value.has(path)) { + loadedExtensions.value.delete(path) + console.log(`[AppStore] Extension unloaded: ${path}`) + return true + } + return false + } + return { stores, registerStore, exportStores, importStores, + loadedExtensions, + setExtensionAPI, + loadExtension, + getLoadedExtensions, + unloadExtension, } }) From ab5e1872aad841fbdb03e689652163431c5b1f3a Mon Sep 17 00:00:00 2001 From: SpliiT Date: Wed, 26 Nov 2025 10:32:38 +0100 Subject: [PATCH 02/25] App.js changes --- stores/app.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/stores/app.js b/stores/app.js index a572b3dc..408fb337 100644 --- a/stores/app.js +++ b/stores/app.js @@ -159,14 +159,15 @@ export const useAppStore = defineStore("app", () => { // Check if extension has an install function if (typeof extensionModule.install === 'function') { - // Call install with the Extension API - await extensionModule.install(extensionAPI.value) + // Call install with the Extension API and the extension path + await extensionModule.install(extensionAPI.value, path) // Store the loaded extension const extensionData = { module: extensionModule, path, loadedAt: new Date().toISOString(), + metadata: extensionModule.metadata || {}, } loadedExtensions.value.set(path, extensionData) @@ -188,6 +189,24 @@ export const useAppStore = defineStore("app", () => { function unloadExtension(path) { if (loadedExtensions.value.has(path)) { + const extensionData = loadedExtensions.value.get(path) + + // Call uninstall function if it exists + if (extensionData.module && typeof extensionData.module.uninstall === 'function') { + try { + extensionData.module.uninstall(extensionAPI.value, path) + console.log(`[AppStore] Extension uninstall called: ${path}`) + } catch (error) { + console.error(`[AppStore] Error calling uninstall for ${path}:`, error) + } + } + + // Clean up all tools registered by this extension + if (extensionAPI.value) { + extensionAPI.value.unregisterToolsByExtension(path) + } + + // Remove from loaded extensions loadedExtensions.value.delete(path) console.log(`[AppStore] Extension unloaded: ${path}`) return true From 9e4a4356025742e4668470cccd281f48178c876d Mon Sep 17 00:00:00 2001 From: SpliiT Date: Wed, 26 Nov 2025 13:29:02 +0100 Subject: [PATCH 03/25] changes app.js --- stores/app.js | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/stores/app.js b/stores/app.js index 408fb337..227c6b8b 100644 --- a/stores/app.js +++ b/stores/app.js @@ -77,10 +77,10 @@ export const useAppStore = defineStore("app", () => { async function loadExtension(path) { try { - // Check if already loaded + // Check if already loaded by path if (loadedExtensions.value.has(path)) { - console.warn(`[AppStore] Extension already loaded: ${path}`) - return loadedExtensions.value.get(path) + console.warn(`[AppStore] Extension already loaded from this path: ${path}`) + throw new Error('This extension file is already loaded') } if (!extensionAPI.value) { @@ -157,6 +157,18 @@ export const useAppStore = defineStore("app", () => { URL.revokeObjectURL(finalURL) } + // Check for duplicate extension by name + const extensionName = extensionModule.metadata?.name + if (extensionName) { + const alreadyLoaded = Array.from(loadedExtensions.value.values()).find( + ext => ext.metadata?.name === extensionName + ) + if (alreadyLoaded) { + console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) + throw new Error(`Extension "${extensionName}" is already loaded. Please unload it first.`) + } + } + // Check if extension has an install function if (typeof extensionModule.install === 'function') { // Call install with the Extension API and the extension path From c33784502a7a6aacf3496509b95c4c7b1091c75e Mon Sep 17 00:00:00 2001 From: SpliiT Date: Wed, 26 Nov 2025 13:39:09 +0100 Subject: [PATCH 04/25] app.js changes --- stores/app.js | 240 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 240 insertions(+) create mode 100644 stores/app.js diff --git a/stores/app.js b/stores/app.js new file mode 100644 index 00000000..227c6b8b --- /dev/null +++ b/stores/app.js @@ -0,0 +1,240 @@ +export const useAppStore = defineStore("app", () => { + const stores = [] + + function registerStore(store) { + const isAlreadyRegistered = stores.some( + (registeredStore) => registeredStore.$id === store.$id, + ) + if (isAlreadyRegistered) { + console.log( + `[AppStore] Store "${store.$id}" already registered, skipping`, + ) + return + } + console.log("[AppStore] Registering store", store.$id) + stores.push(store) + } + + function exportStores() { + const snapshot = {} + let exportCount = 0 + + for (const store of stores) { + if (!store.exportStores) continue + const storeId = store.$id + try { + snapshot[storeId] = store.exportStores() + exportCount++ + } catch (error) { + console.error(`[AppStore] Error exporting store "${storeId}":`, error) + } + } + console.log( + `[AppStore] Exported ${exportCount} stores; snapshot keys:`, + Object.keys(snapshot), + ) + return snapshot + } + + async function importStores(snapshot) { + if (!snapshot) { + console.warn("[AppStore] import called with invalid snapshot") + return + } + console.log("[AppStore] Import snapshot keys:", Object.keys(snapshot || {})) + + let importedCount = 0 + const notFoundStores = [] + for (const store of stores) { + if (!store.importStores) continue + const storeId = store.$id + if (!snapshot[storeId]) { + notFoundStores.push(storeId) + continue + } + try { + await store.importStores(snapshot[storeId]) + importedCount++ + } catch (error) { + console.error(`[AppStore] Error importing store "${storeId}":`, error) + } + } + if (notFoundStores.length > 0) { + console.warn( + `[AppStore] Stores not found in snapshot: ${notFoundStores.join(", ")}`, + ) + } + console.log(`[AppStore] Imported ${importedCount} stores`) + } + + // Extension loading system + const loadedExtensions = ref(new Map()) + const extensionAPI = ref(null) + + function setExtensionAPI(api) { + extensionAPI.value = api + } + + async function loadExtension(path) { + try { + // Check if already loaded by path + if (loadedExtensions.value.has(path)) { + console.warn(`[AppStore] Extension already loaded from this path: ${path}`) + throw new Error('This extension file is already loaded') + } + + if (!extensionAPI.value) { + throw new Error("Extension API not initialized") + } + + let finalURL = path + + // For blob URLs, we need to rewrite imports to use available modules + if (path.startsWith('blob:')) { + const response = await fetch(path) + let code = await response.text() + + // Replace Vue imports - handle all patterns including multiline + code = code.replace( + /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']vue["'];?/gs, + (match, namedImports, namespaceImport, defaultImport) => { + if (namedImports) { + // Named imports: import { ref, computed } from 'vue' + // Convert 'as' to ':' for object destructuring + const converted = namedImports.replace(/\s+as\s+/g, ': ') + return `const {${converted}} = window.__VUE_RUNTIME__;` + } else if (namespaceImport) { + // Namespace import: import * as Vue from 'vue' + return `const ${namespaceImport} = window.__VUE_RUNTIME__;` + } else if (defaultImport) { + // Default import: import Vue from 'vue' + return `const ${defaultImport} = window.__VUE_RUNTIME__;` + } + return match + } + ) + + // Replace Pinia imports + code = code.replace( + /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']pinia["'];?/gs, + (match, namedImports, namespaceImport, defaultImport) => { + if (namedImports) { + const converted = namedImports.replace(/\s+as\s+/g, ': ') + return `const {${converted}} = window.__PINIA__;` + } else if (namespaceImport) { + return `const ${namespaceImport} = window.__PINIA__;` + } else if (defaultImport) { + return `const ${defaultImport} = window.__PINIA__;` + } + return match + } + ) + + // Replace @geode/* imports - just comment them out for now + code = code.replace( + /import\s+[^;]+from\s+["']@geode\/[^"']+["'];?/gs, + (match) => `/* ${match} */ // External dependency - resolved at runtime\n` + ) + + // Replace @ogw_* imports + code = code.replace( + /import\s+[^;]+from\s+["']@ogw_[^"']+["'];?/gs, + (match) => `/* ${match} */ // External dependency - resolved at runtime\n` + ) + + console.log('[AppStore] Rewritten extension code preview:', code.substring(0, 800)) + + // Create new blob with rewritten code + const newBlob = new Blob([code], { type: 'application/javascript' }) + finalURL = URL.createObjectURL(newBlob) + } + + // Dynamic import of the extension module + const extensionModule = await import(/* @vite-ignore */ finalURL) + + // Clean up temporary blob URL + if (finalURL !== path && finalURL.startsWith('blob:')) { + URL.revokeObjectURL(finalURL) + } + + // Check for duplicate extension by name + const extensionName = extensionModule.metadata?.name + if (extensionName) { + const alreadyLoaded = Array.from(loadedExtensions.value.values()).find( + ext => ext.metadata?.name === extensionName + ) + if (alreadyLoaded) { + console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) + throw new Error(`Extension "${extensionName}" is already loaded. Please unload it first.`) + } + } + + // Check if extension has an install function + if (typeof extensionModule.install === 'function') { + // Call install with the Extension API and the extension path + await extensionModule.install(extensionAPI.value, path) + + // Store the loaded extension + const extensionData = { + module: extensionModule, + path, + loadedAt: new Date().toISOString(), + metadata: extensionModule.metadata || {}, + } + loadedExtensions.value.set(path, extensionData) + + console.log(`[AppStore] Extension loaded successfully: ${path}`) + + return extensionModule + } else { + throw new Error('Extension must export an install function') + } + } catch (error) { + console.error(`[AppStore] Failed to load extension from ${path}:`, error) + throw error + } + } + + function getLoadedExtensions() { + return Array.from(loadedExtensions.value.values()) + } + + function unloadExtension(path) { + if (loadedExtensions.value.has(path)) { + const extensionData = loadedExtensions.value.get(path) + + // Call uninstall function if it exists + if (extensionData.module && typeof extensionData.module.uninstall === 'function') { + try { + extensionData.module.uninstall(extensionAPI.value, path) + console.log(`[AppStore] Extension uninstall called: ${path}`) + } catch (error) { + console.error(`[AppStore] Error calling uninstall for ${path}:`, error) + } + } + + // Clean up all tools registered by this extension + if (extensionAPI.value) { + extensionAPI.value.unregisterToolsByExtension(path) + } + + // Remove from loaded extensions + loadedExtensions.value.delete(path) + console.log(`[AppStore] Extension unloaded: ${path}`) + return true + } + return false + } + + return { + stores, + registerStore, + exportStores, + importStores, + loadedExtensions, + setExtensionAPI, + loadExtension, + getLoadedExtensions, + unloadExtension, + } +}) From 28250e1da530dab68eea521121f283ce5700814f Mon Sep 17 00:00:00 2001 From: SpliiT Date: Wed, 26 Nov 2025 16:01:18 +0100 Subject: [PATCH 05/25] aoi --- stores/app.js | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/stores/app.js b/stores/app.js index 227c6b8b..c5e4f868 100644 --- a/stores/app.js +++ b/stores/app.js @@ -94,12 +94,12 @@ export const useAppStore = defineStore("app", () => { const response = await fetch(path) let code = await response.text() - // Replace Vue imports - handle all patterns including multiline + // Replace Vue imports - handle all patterns including multiline and minified code = code.replace( - /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']vue["'];?/gs, + /import\s*(?:{([^}]+)}|\*\s*as\s+(\w+)|(\w+))\s*from\s*["']vue["'];?/gs, (match, namedImports, namespaceImport, defaultImport) => { if (namedImports) { - // Named imports: import { ref, computed } from 'vue' + // Named imports: import { ref, computed } from 'vue' or import{ref}from"vue" // Convert 'as' to ':' for object destructuring const converted = namedImports.replace(/\s+as\s+/g, ': ') return `const {${converted}} = window.__VUE_RUNTIME__;` @@ -116,7 +116,7 @@ export const useAppStore = defineStore("app", () => { // Replace Pinia imports code = code.replace( - /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']pinia["'];?/gs, + /import\s*(?:{([^}]+)}|\*\s*as\s+(\w+)|(\w+))\s*from\s*["']pinia["'];?/gs, (match, namedImports, namespaceImport, defaultImport) => { if (namedImports) { const converted = namedImports.replace(/\s+as\s+/g, ': ') @@ -129,16 +129,32 @@ export const useAppStore = defineStore("app", () => { return match } ) + + // Replace back schemas import FIRST (before other @geode imports) + let schemasReplaced = false + code = code.replace( + /import\s+(\w+)\s*from\s*["']@geode\/opengeodeweb-back\/opengeodeweb_back_schemas\.json["'];?/g, + (match, defaultImport) => { + console.log('[AppStore] ✓ Replacing back schemas:', match) + schemasReplaced = true + return `const ${defaultImport} = window.__GEODE_BACK_SCHEMAS__;` + } + ) + + if (!schemasReplaced) { + console.warn('[AppStore] ⚠️ Back schemas import NOT found!') + console.log('[AppStore] First 300 chars after Vue/Pinia replacement:', code.substring(0, 300)) + } - // Replace @geode/* imports - just comment them out for now + // Replace other @geode/* imports - comment them out code = code.replace( - /import\s+[^;]+from\s+["']@geode\/[^"']+["'];?/gs, - (match) => `/* ${match} */ // External dependency - resolved at runtime\n` + /import\s+[^;]+from\s*["']@geode\/[^"']+["'];?/g, + (match) => `/* ${match} */ // External dependency\n` ) // Replace @ogw_* imports code = code.replace( - /import\s+[^;]+from\s+["']@ogw_[^"']+["'];?/gs, + /import\s+[^;]+from\s*["']@ogw_[^"']+["'];?/gs, (match) => `/* ${match} */ // External dependency - resolved at runtime\n` ) From 9afa9d01d50a033e6ae976623e68550dd04aef6a Mon Sep 17 00:00:00 2001 From: SpliiT Date: Wed, 26 Nov 2025 17:39:58 +0100 Subject: [PATCH 06/25] rm app.js from stores out of /app --- app/stores/app.js | 4 +- stores/app.js | 256 ---------------------------------------------- 2 files changed, 2 insertions(+), 258 deletions(-) delete mode 100644 stores/app.js diff --git a/app/stores/app.js b/app/stores/app.js index 227c6b8b..adb843c9 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -164,8 +164,8 @@ export const useAppStore = defineStore("app", () => { ext => ext.metadata?.name === extensionName ) if (alreadyLoaded) { - console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) - throw new Error(`Extension "${extensionName}" is already loaded. Please unload it first.`) + console.warn(`[AppStore]"${extensionName}" is already loaded`) + throw new Error(`"${extensionName}" is already loaded.`) } } diff --git a/stores/app.js b/stores/app.js deleted file mode 100644 index c5e4f868..00000000 --- a/stores/app.js +++ /dev/null @@ -1,256 +0,0 @@ -export const useAppStore = defineStore("app", () => { - const stores = [] - - function registerStore(store) { - const isAlreadyRegistered = stores.some( - (registeredStore) => registeredStore.$id === store.$id, - ) - if (isAlreadyRegistered) { - console.log( - `[AppStore] Store "${store.$id}" already registered, skipping`, - ) - return - } - console.log("[AppStore] Registering store", store.$id) - stores.push(store) - } - - function exportStores() { - const snapshot = {} - let exportCount = 0 - - for (const store of stores) { - if (!store.exportStores) continue - const storeId = store.$id - try { - snapshot[storeId] = store.exportStores() - exportCount++ - } catch (error) { - console.error(`[AppStore] Error exporting store "${storeId}":`, error) - } - } - console.log( - `[AppStore] Exported ${exportCount} stores; snapshot keys:`, - Object.keys(snapshot), - ) - return snapshot - } - - async function importStores(snapshot) { - if (!snapshot) { - console.warn("[AppStore] import called with invalid snapshot") - return - } - console.log("[AppStore] Import snapshot keys:", Object.keys(snapshot || {})) - - let importedCount = 0 - const notFoundStores = [] - for (const store of stores) { - if (!store.importStores) continue - const storeId = store.$id - if (!snapshot[storeId]) { - notFoundStores.push(storeId) - continue - } - try { - await store.importStores(snapshot[storeId]) - importedCount++ - } catch (error) { - console.error(`[AppStore] Error importing store "${storeId}":`, error) - } - } - if (notFoundStores.length > 0) { - console.warn( - `[AppStore] Stores not found in snapshot: ${notFoundStores.join(", ")}`, - ) - } - console.log(`[AppStore] Imported ${importedCount} stores`) - } - - // Extension loading system - const loadedExtensions = ref(new Map()) - const extensionAPI = ref(null) - - function setExtensionAPI(api) { - extensionAPI.value = api - } - - async function loadExtension(path) { - try { - // Check if already loaded by path - if (loadedExtensions.value.has(path)) { - console.warn(`[AppStore] Extension already loaded from this path: ${path}`) - throw new Error('This extension file is already loaded') - } - - if (!extensionAPI.value) { - throw new Error("Extension API not initialized") - } - - let finalURL = path - - // For blob URLs, we need to rewrite imports to use available modules - if (path.startsWith('blob:')) { - const response = await fetch(path) - let code = await response.text() - - // Replace Vue imports - handle all patterns including multiline and minified - code = code.replace( - /import\s*(?:{([^}]+)}|\*\s*as\s+(\w+)|(\w+))\s*from\s*["']vue["'];?/gs, - (match, namedImports, namespaceImport, defaultImport) => { - if (namedImports) { - // Named imports: import { ref, computed } from 'vue' or import{ref}from"vue" - // Convert 'as' to ':' for object destructuring - const converted = namedImports.replace(/\s+as\s+/g, ': ') - return `const {${converted}} = window.__VUE_RUNTIME__;` - } else if (namespaceImport) { - // Namespace import: import * as Vue from 'vue' - return `const ${namespaceImport} = window.__VUE_RUNTIME__;` - } else if (defaultImport) { - // Default import: import Vue from 'vue' - return `const ${defaultImport} = window.__VUE_RUNTIME__;` - } - return match - } - ) - - // Replace Pinia imports - code = code.replace( - /import\s*(?:{([^}]+)}|\*\s*as\s+(\w+)|(\w+))\s*from\s*["']pinia["'];?/gs, - (match, namedImports, namespaceImport, defaultImport) => { - if (namedImports) { - const converted = namedImports.replace(/\s+as\s+/g, ': ') - return `const {${converted}} = window.__PINIA__;` - } else if (namespaceImport) { - return `const ${namespaceImport} = window.__PINIA__;` - } else if (defaultImport) { - return `const ${defaultImport} = window.__PINIA__;` - } - return match - } - ) - - // Replace back schemas import FIRST (before other @geode imports) - let schemasReplaced = false - code = code.replace( - /import\s+(\w+)\s*from\s*["']@geode\/opengeodeweb-back\/opengeodeweb_back_schemas\.json["'];?/g, - (match, defaultImport) => { - console.log('[AppStore] ✓ Replacing back schemas:', match) - schemasReplaced = true - return `const ${defaultImport} = window.__GEODE_BACK_SCHEMAS__;` - } - ) - - if (!schemasReplaced) { - console.warn('[AppStore] ⚠️ Back schemas import NOT found!') - console.log('[AppStore] First 300 chars after Vue/Pinia replacement:', code.substring(0, 300)) - } - - // Replace other @geode/* imports - comment them out - code = code.replace( - /import\s+[^;]+from\s*["']@geode\/[^"']+["'];?/g, - (match) => `/* ${match} */ // External dependency\n` - ) - - // Replace @ogw_* imports - code = code.replace( - /import\s+[^;]+from\s*["']@ogw_[^"']+["'];?/gs, - (match) => `/* ${match} */ // External dependency - resolved at runtime\n` - ) - - console.log('[AppStore] Rewritten extension code preview:', code.substring(0, 800)) - - // Create new blob with rewritten code - const newBlob = new Blob([code], { type: 'application/javascript' }) - finalURL = URL.createObjectURL(newBlob) - } - - // Dynamic import of the extension module - const extensionModule = await import(/* @vite-ignore */ finalURL) - - // Clean up temporary blob URL - if (finalURL !== path && finalURL.startsWith('blob:')) { - URL.revokeObjectURL(finalURL) - } - - // Check for duplicate extension by name - const extensionName = extensionModule.metadata?.name - if (extensionName) { - const alreadyLoaded = Array.from(loadedExtensions.value.values()).find( - ext => ext.metadata?.name === extensionName - ) - if (alreadyLoaded) { - console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) - throw new Error(`Extension "${extensionName}" is already loaded. Please unload it first.`) - } - } - - // Check if extension has an install function - if (typeof extensionModule.install === 'function') { - // Call install with the Extension API and the extension path - await extensionModule.install(extensionAPI.value, path) - - // Store the loaded extension - const extensionData = { - module: extensionModule, - path, - loadedAt: new Date().toISOString(), - metadata: extensionModule.metadata || {}, - } - loadedExtensions.value.set(path, extensionData) - - console.log(`[AppStore] Extension loaded successfully: ${path}`) - - return extensionModule - } else { - throw new Error('Extension must export an install function') - } - } catch (error) { - console.error(`[AppStore] Failed to load extension from ${path}:`, error) - throw error - } - } - - function getLoadedExtensions() { - return Array.from(loadedExtensions.value.values()) - } - - function unloadExtension(path) { - if (loadedExtensions.value.has(path)) { - const extensionData = loadedExtensions.value.get(path) - - // Call uninstall function if it exists - if (extensionData.module && typeof extensionData.module.uninstall === 'function') { - try { - extensionData.module.uninstall(extensionAPI.value, path) - console.log(`[AppStore] Extension uninstall called: ${path}`) - } catch (error) { - console.error(`[AppStore] Error calling uninstall for ${path}:`, error) - } - } - - // Clean up all tools registered by this extension - if (extensionAPI.value) { - extensionAPI.value.unregisterToolsByExtension(path) - } - - // Remove from loaded extensions - loadedExtensions.value.delete(path) - console.log(`[AppStore] Extension unloaded: ${path}`) - return true - } - return false - } - - return { - stores, - registerStore, - exportStores, - importStores, - loadedExtensions, - setExtensionAPI, - loadExtension, - getLoadedExtensions, - unloadExtension, - } -}) From 76e949b541481b7f216f205846f61777ba102216 Mon Sep 17 00:00:00 2001 From: SpliiT Date: Thu, 27 Nov 2025 10:08:54 +0100 Subject: [PATCH 07/25] change log --- app/stores/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index adb843c9..ddfd1a68 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -164,8 +164,8 @@ export const useAppStore = defineStore("app", () => { ext => ext.metadata?.name === extensionName ) if (alreadyLoaded) { - console.warn(`[AppStore]"${extensionName}" is already loaded`) - throw new Error(`"${extensionName}" is already loaded.`) + console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) + throw new Error(`Extension "${extensionName}" is already loaded.`) } } From 68c5a44103cfcd8d1e70bb2bd618dd4b540bcc08 Mon Sep 17 00:00:00 2001 From: SpliiT Date: Thu, 27 Nov 2025 10:51:44 +0100 Subject: [PATCH 08/25] rm comments --- app/stores/app.js | 54 ++++++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index ddfd1a68..6cee03a9 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -67,7 +67,6 @@ export const useAppStore = defineStore("app", () => { console.log(`[AppStore] Imported ${importedCount} stores`) } - // Extension loading system const loadedExtensions = ref(new Map()) const extensionAPI = ref(null) @@ -77,7 +76,6 @@ export const useAppStore = defineStore("app", () => { async function loadExtension(path) { try { - // Check if already loaded by path if (loadedExtensions.value.has(path)) { console.warn(`[AppStore] Extension already loaded from this path: ${path}`) throw new Error('This extension file is already loaded') @@ -89,32 +87,25 @@ export const useAppStore = defineStore("app", () => { let finalURL = path - // For blob URLs, we need to rewrite imports to use available modules if (path.startsWith('blob:')) { const response = await fetch(path) let code = await response.text() - // Replace Vue imports - handle all patterns including multiline code = code.replace( /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']vue["'];?/gs, (match, namedImports, namespaceImport, defaultImport) => { if (namedImports) { - // Named imports: import { ref, computed } from 'vue' - // Convert 'as' to ':' for object destructuring const converted = namedImports.replace(/\s+as\s+/g, ': ') return `const {${converted}} = window.__VUE_RUNTIME__;` } else if (namespaceImport) { - // Namespace import: import * as Vue from 'vue' return `const ${namespaceImport} = window.__VUE_RUNTIME__;` } else if (defaultImport) { - // Default import: import Vue from 'vue' return `const ${defaultImport} = window.__VUE_RUNTIME__;` } return match } ) - // Replace Pinia imports code = code.replace( /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']pinia["'];?/gs, (match, namedImports, namespaceImport, defaultImport) => { @@ -130,13 +121,11 @@ export const useAppStore = defineStore("app", () => { } ) - // Replace @geode/* imports - just comment them out for now code = code.replace( /import\s+[^;]+from\s+["']@geode\/[^"']+["'];?/gs, (match) => `/* ${match} */ // External dependency - resolved at runtime\n` ) - // Replace @ogw_* imports code = code.replace( /import\s+[^;]+from\s+["']@ogw_[^"']+["'];?/gs, (match) => `/* ${match} */ // External dependency - resolved at runtime\n` @@ -144,20 +133,16 @@ export const useAppStore = defineStore("app", () => { console.log('[AppStore] Rewritten extension code preview:', code.substring(0, 800)) - // Create new blob with rewritten code const newBlob = new Blob([code], { type: 'application/javascript' }) finalURL = URL.createObjectURL(newBlob) } - // Dynamic import of the extension module - const extensionModule = await import(/* @vite-ignore */ finalURL) + const extensionModule = await import(finalURL) - // Clean up temporary blob URL if (finalURL !== path && finalURL.startsWith('blob:')) { URL.revokeObjectURL(finalURL) } - // Check for duplicate extension by name const extensionName = extensionModule.metadata?.name if (extensionName) { const alreadyLoaded = Array.from(loadedExtensions.value.values()).find( @@ -169,17 +154,15 @@ export const useAppStore = defineStore("app", () => { } } - // Check if extension has an install function if (typeof extensionModule.install === 'function') { - // Call install with the Extension API and the extension path await extensionModule.install(extensionAPI.value, path) - // Store the loaded extension const extensionData = { module: extensionModule, path, loadedAt: new Date().toISOString(), metadata: extensionModule.metadata || {}, + enabled: true, } loadedExtensions.value.set(path, extensionData) @@ -203,7 +186,6 @@ export const useAppStore = defineStore("app", () => { if (loadedExtensions.value.has(path)) { const extensionData = loadedExtensions.value.get(path) - // Call uninstall function if it exists if (extensionData.module && typeof extensionData.module.uninstall === 'function') { try { extensionData.module.uninstall(extensionAPI.value, path) @@ -213,12 +195,10 @@ export const useAppStore = defineStore("app", () => { } } - // Clean up all tools registered by this extension if (extensionAPI.value) { extensionAPI.value.unregisterToolsByExtension(path) } - // Remove from loaded extensions loadedExtensions.value.delete(path) console.log(`[AppStore] Extension unloaded: ${path}`) return true @@ -226,6 +206,33 @@ export const useAppStore = defineStore("app", () => { return false } + function toggleExtension(path) { + if (loadedExtensions.value.has(path)) { + const extensionData = loadedExtensions.value.get(path) + extensionData.enabled = !extensionData.enabled + console.log(`[AppStore] Extension ${extensionData.enabled ? 'enabled' : 'disabled'}: ${path}`) + return extensionData.enabled + } + return false + } + + function setExtensionEnabled(path, enabled) { + if (loadedExtensions.value.has(path)) { + const extensionData = loadedExtensions.value.get(path) + extensionData.enabled = enabled + console.log(`[AppStore] Extension ${enabled ? 'enabled' : 'disabled'}: ${path}`) + return true + } + return false + } + + function getExtensionEnabled(path) { + if (loadedExtensions.value.has(path)) { + return loadedExtensions.value.get(path).enabled + } + return false + } + return { stores, registerStore, @@ -236,5 +243,8 @@ export const useAppStore = defineStore("app", () => { loadExtension, getLoadedExtensions, unloadExtension, + toggleExtension, + setExtensionEnabled, + getExtensionEnabled, } }) From 374a4f6b2c6e9415e5977c770e142c893bd54587 Mon Sep 17 00:00:00 2001 From: SpliiT Date: Thu, 27 Nov 2025 16:37:48 +0100 Subject: [PATCH 09/25] transform code --- app/stores/app.js | 49 +++------------------------ app/utils/extensionCodeTransformer.js | 21 ++++++++++++ 2 files changed, 26 insertions(+), 44 deletions(-) create mode 100644 app/utils/extensionCodeTransformer.js diff --git a/app/stores/app.js b/app/stores/app.js index 6cee03a9..37291a36 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -1,3 +1,5 @@ +import { transformExtensionCode } from '../utils/extensionCodeTransformer.js' + export const useAppStore = defineStore("app", () => { const stores = [] @@ -89,51 +91,10 @@ export const useAppStore = defineStore("app", () => { if (path.startsWith('blob:')) { const response = await fetch(path) - let code = await response.text() - - code = code.replace( - /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']vue["'];?/gs, - (match, namedImports, namespaceImport, defaultImport) => { - if (namedImports) { - const converted = namedImports.replace(/\s+as\s+/g, ': ') - return `const {${converted}} = window.__VUE_RUNTIME__;` - } else if (namespaceImport) { - return `const ${namespaceImport} = window.__VUE_RUNTIME__;` - } else if (defaultImport) { - return `const ${defaultImport} = window.__VUE_RUNTIME__;` - } - return match - } - ) - - code = code.replace( - /import\s+(?:{([^}]+)}|\*\s+as\s+(\w+)|(\w+))\s+from\s+["']pinia["'];?/gs, - (match, namedImports, namespaceImport, defaultImport) => { - if (namedImports) { - const converted = namedImports.replace(/\s+as\s+/g, ': ') - return `const {${converted}} = window.__PINIA__;` - } else if (namespaceImport) { - return `const ${namespaceImport} = window.__PINIA__;` - } else if (defaultImport) { - return `const ${defaultImport} = window.__PINIA__;` - } - return match - } - ) - - code = code.replace( - /import\s+[^;]+from\s+["']@geode\/[^"']+["'];?/gs, - (match) => `/* ${match} */ // External dependency - resolved at runtime\n` - ) - - code = code.replace( - /import\s+[^;]+from\s+["']@ogw_[^"']+["'];?/gs, - (match) => `/* ${match} */ // External dependency - resolved at runtime\n` - ) - - console.log('[AppStore] Rewritten extension code preview:', code.substring(0, 800)) + const code = await response.text() + const transformedCode = transformExtensionCode(code) - const newBlob = new Blob([code], { type: 'application/javascript' }) + const newBlob = new Blob([transformedCode], { type: 'application/javascript' }) finalURL = URL.createObjectURL(newBlob) } diff --git a/app/utils/extensionCodeTransformer.js b/app/utils/extensionCodeTransformer.js new file mode 100644 index 00000000..b73da879 --- /dev/null +++ b/app/utils/extensionCodeTransformer.js @@ -0,0 +1,21 @@ +export function transformExtensionCode(code) { + code = code.replace( + /from\s+["']vue["']/g, + 'from "data:text/javascript,' + encodeURIComponent(` + const Vue = window.Vue; + export default Vue; + ${Object.keys(window.Vue || {}).map(key => `export const ${key} = Vue.${key};`).join('')} + `) + '"' + ) + + code = code.replace( + /from\s+["']pinia["']/g, + 'from "data:text/javascript,' + encodeURIComponent(` + const Pinia = window.Pinia; + export default Pinia; + ${Object.keys(window.Pinia || {}).map(key => `export const ${key} = Pinia.${key};`).join('')} + `) + '"' + ) + + return code +} From f7d45e92b0203a4cd023dca79ba8279c793be318 Mon Sep 17 00:00:00 2001 From: SpliiT Date: Fri, 28 Nov 2025 16:15:15 +0100 Subject: [PATCH 10/25] move logic & refacto --- app/stores/app.js | 135 -------------------------- app/utils/extensionCodeTransformer.js | 21 ---- 2 files changed, 156 deletions(-) delete mode 100644 app/utils/extensionCodeTransformer.js diff --git a/app/stores/app.js b/app/stores/app.js index 37291a36..4fb94817 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -1,5 +1,3 @@ -import { transformExtensionCode } from '../utils/extensionCodeTransformer.js' - export const useAppStore = defineStore("app", () => { const stores = [] @@ -69,143 +67,10 @@ export const useAppStore = defineStore("app", () => { console.log(`[AppStore] Imported ${importedCount} stores`) } - const loadedExtensions = ref(new Map()) - const extensionAPI = ref(null) - - function setExtensionAPI(api) { - extensionAPI.value = api - } - - async function loadExtension(path) { - try { - if (loadedExtensions.value.has(path)) { - console.warn(`[AppStore] Extension already loaded from this path: ${path}`) - throw new Error('This extension file is already loaded') - } - - if (!extensionAPI.value) { - throw new Error("Extension API not initialized") - } - - let finalURL = path - - if (path.startsWith('blob:')) { - const response = await fetch(path) - const code = await response.text() - const transformedCode = transformExtensionCode(code) - - const newBlob = new Blob([transformedCode], { type: 'application/javascript' }) - finalURL = URL.createObjectURL(newBlob) - } - - const extensionModule = await import(finalURL) - - if (finalURL !== path && finalURL.startsWith('blob:')) { - URL.revokeObjectURL(finalURL) - } - - const extensionName = extensionModule.metadata?.name - if (extensionName) { - const alreadyLoaded = Array.from(loadedExtensions.value.values()).find( - ext => ext.metadata?.name === extensionName - ) - if (alreadyLoaded) { - console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) - throw new Error(`Extension "${extensionName}" is already loaded.`) - } - } - - if (typeof extensionModule.install === 'function') { - await extensionModule.install(extensionAPI.value, path) - - const extensionData = { - module: extensionModule, - path, - loadedAt: new Date().toISOString(), - metadata: extensionModule.metadata || {}, - enabled: true, - } - loadedExtensions.value.set(path, extensionData) - - console.log(`[AppStore] Extension loaded successfully: ${path}`) - - return extensionModule - } else { - throw new Error('Extension must export an install function') - } - } catch (error) { - console.error(`[AppStore] Failed to load extension from ${path}:`, error) - throw error - } - } - - function getLoadedExtensions() { - return Array.from(loadedExtensions.value.values()) - } - - function unloadExtension(path) { - if (loadedExtensions.value.has(path)) { - const extensionData = loadedExtensions.value.get(path) - - if (extensionData.module && typeof extensionData.module.uninstall === 'function') { - try { - extensionData.module.uninstall(extensionAPI.value, path) - console.log(`[AppStore] Extension uninstall called: ${path}`) - } catch (error) { - console.error(`[AppStore] Error calling uninstall for ${path}:`, error) - } - } - - if (extensionAPI.value) { - extensionAPI.value.unregisterToolsByExtension(path) - } - - loadedExtensions.value.delete(path) - console.log(`[AppStore] Extension unloaded: ${path}`) - return true - } - return false - } - - function toggleExtension(path) { - if (loadedExtensions.value.has(path)) { - const extensionData = loadedExtensions.value.get(path) - extensionData.enabled = !extensionData.enabled - console.log(`[AppStore] Extension ${extensionData.enabled ? 'enabled' : 'disabled'}: ${path}`) - return extensionData.enabled - } - return false - } - - function setExtensionEnabled(path, enabled) { - if (loadedExtensions.value.has(path)) { - const extensionData = loadedExtensions.value.get(path) - extensionData.enabled = enabled - console.log(`[AppStore] Extension ${enabled ? 'enabled' : 'disabled'}: ${path}`) - return true - } - return false - } - - function getExtensionEnabled(path) { - if (loadedExtensions.value.has(path)) { - return loadedExtensions.value.get(path).enabled - } - return false - } - return { stores, registerStore, exportStores, importStores, - loadedExtensions, - setExtensionAPI, - loadExtension, - getLoadedExtensions, - unloadExtension, - toggleExtension, - setExtensionEnabled, - getExtensionEnabled, } }) diff --git a/app/utils/extensionCodeTransformer.js b/app/utils/extensionCodeTransformer.js deleted file mode 100644 index b73da879..00000000 --- a/app/utils/extensionCodeTransformer.js +++ /dev/null @@ -1,21 +0,0 @@ -export function transformExtensionCode(code) { - code = code.replace( - /from\s+["']vue["']/g, - 'from "data:text/javascript,' + encodeURIComponent(` - const Vue = window.Vue; - export default Vue; - ${Object.keys(window.Vue || {}).map(key => `export const ${key} = Vue.${key};`).join('')} - `) + '"' - ) - - code = code.replace( - /from\s+["']pinia["']/g, - 'from "data:text/javascript,' + encodeURIComponent(` - const Pinia = window.Pinia; - export default Pinia; - ${Object.keys(window.Pinia || {}).map(key => `export const ${key} = Pinia.${key};`).join('')} - `) + '"' - ) - - return code -} From c66dc70dd6153408671d84035f770aa0e296b7d4 Mon Sep 17 00:00:00 2001 From: SpliiT Date: Mon, 1 Dec 2025 11:17:03 +0100 Subject: [PATCH 11/25] move feature --- app/stores/app.js | 130 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 130 insertions(+) diff --git a/app/stores/app.js b/app/stores/app.js index 4fb94817..7e8ce449 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -67,10 +67,140 @@ export const useAppStore = defineStore("app", () => { console.log(`[AppStore] Imported ${importedCount} stores`) } + const loadedExtensions = ref(new Map()) + const extensionAPI = ref(null) + + function setExtensionAPI(api) { + extensionAPI.value = api + } + + function getExtension(path) { + return loadedExtensions.value.get(path) + } + + async function loadExtension(path, codeTransformer = null) { + try { + if (loadedExtensions.value.has(path)) { + console.warn(`[AppStore] Extension already loaded from this path: ${path}`) + throw new Error('This extension file is already loaded') + } + + if (!extensionAPI.value) { + throw new Error("Extension API not initialized") + } + + let finalURL = path + + if (codeTransformer && path.startsWith('blob:')) { + const response = await fetch(path) + const code = await response.text() + const transformedCode = codeTransformer(code) + + const newBlob = new Blob([transformedCode], { type: 'application/javascript' }) + finalURL = URL.createObjectURL(newBlob) + } + + const extensionModule = await import(finalURL) + + if (finalURL !== path && finalURL.startsWith('blob:')) { + URL.revokeObjectURL(finalURL) + } + + const extensionName = extensionModule.metadata?.name + if (extensionName) { + const alreadyLoaded = Array.from(loadedExtensions.value.values()).find( + ext => ext.metadata?.name === extensionName + ) + if (alreadyLoaded) { + console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) + throw new Error(`Extension "${extensionName}" is already loaded.`) + } + } + + if (typeof extensionModule.install === 'function') { + await extensionModule.install(extensionAPI.value, path) + + const extensionData = { + module: extensionModule, + path, + loadedAt: new Date().toISOString(), + metadata: extensionModule.metadata || {}, + enabled: true, + } + loadedExtensions.value.set(path, extensionData) + + console.log(`[AppStore] Extension loaded successfully: ${path}`) + + return extensionModule + } else { + throw new Error('Extension must export an install function') + } + } catch (error) { + console.error(`[AppStore] Failed to load extension from ${path}:`, error) + throw error + } + } + + function getLoadedExtensions() { + return Array.from(loadedExtensions.value.values()) + } + + function unloadExtension(path) { + const extensionData = getExtension(path) + if (!extensionData) return false + + if (extensionData.module && typeof extensionData.module.uninstall === 'function') { + try { + extensionData.module.uninstall(extensionAPI.value, path) + console.log(`[AppStore] Extension uninstall called: ${path}`) + } catch (error) { + console.error(`[AppStore] Error calling uninstall for ${path}:`, error) + } + } + + if (extensionAPI.value && typeof extensionAPI.value.unregisterToolsByExtension === 'function') { + extensionAPI.value.unregisterToolsByExtension(path) + } + + loadedExtensions.value.delete(path) + console.log(`[AppStore] Extension unloaded: ${path}`) + return true + } + + function toggleExtension(path) { + const extensionData = getExtension(path) + if (!extensionData) return false + + extensionData.enabled = !extensionData.enabled + console.log(`[AppStore] Extension ${extensionData.enabled ? 'enabled' : 'disabled'}: ${path}`) + return extensionData.enabled + } + + function setExtensionEnabled(path, enabled) { + const extensionData = getExtension(path) + if (!extensionData) return false + + extensionData.enabled = enabled + console.log(`[AppStore] Extension ${enabled ? 'enabled' : 'disabled'}: ${path}`) + return true + } + + function getExtensionEnabled(path) { + return getExtension(path)?.enabled ?? false + } + return { stores, registerStore, exportStores, importStores, + loadedExtensions, + setExtensionAPI, + loadExtension, + getLoadedExtensions, + unloadExtension, + toggleExtension, + setExtensionEnabled, + getExtensionEnabled, } }) From 7a8393e3c53a4cc87601b40b6b4a4308878a4f46 Mon Sep 17 00:00:00 2001 From: SpliiT Date: Mon, 1 Dec 2025 14:37:49 +0100 Subject: [PATCH 12/25] transformer edit --- app/stores/app.js | 90 +++++++++++++++++++++++++---------------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 7e8ce449..6d5411ba 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -69,32 +69,28 @@ export const useAppStore = defineStore("app", () => { const loadedExtensions = ref(new Map()) const extensionAPI = ref(null) + const codeTransformer = ref(null) function setExtensionAPI(api) { extensionAPI.value = api } - function getExtension(path) { - return loadedExtensions.value.get(path) + function setCodeTransformer(transformer) { + codeTransformer.value = transformer } - async function loadExtension(path, codeTransformer = null) { - try { - if (loadedExtensions.value.has(path)) { - console.warn(`[AppStore] Extension already loaded from this path: ${path}`) - throw new Error('This extension file is already loaded') - } - - if (!extensionAPI.value) { - throw new Error("Extension API not initialized") - } + function getExtension(id) { + return loadedExtensions.value.get(id) + } + async function loadExtension(path) { + try { let finalURL = path - if (codeTransformer && path.startsWith('blob:')) { + if (codeTransformer.value && path.startsWith('blob:')) { const response = await fetch(path) const code = await response.text() - const transformedCode = codeTransformer(code) + const transformedCode = codeTransformer.value(code) const newBlob = new Blob([transformedCode], { type: 'application/javascript' }) finalURL = URL.createObjectURL(newBlob) @@ -106,30 +102,37 @@ export const useAppStore = defineStore("app", () => { URL.revokeObjectURL(finalURL) } - const extensionName = extensionModule.metadata?.name - if (extensionName) { - const alreadyLoaded = Array.from(loadedExtensions.value.values()).find( - ext => ext.metadata?.name === extensionName - ) - if (alreadyLoaded) { - console.warn(`[AppStore] Extension "${extensionName}" is already loaded`) - throw new Error(`Extension "${extensionName}" is already loaded.`) - } + if (!extensionModule.metadata?.id) { + throw new Error('Extension must have metadata.id') + } + + const extensionId = extensionModule.metadata.id + + if (loadedExtensions.value.has(extensionId)) { + console.warn(`[AppStore] Extension "${extensionId}" is already loaded`) + throw new Error(`Extension "${extensionId}" is already loaded.`) + } + + if (!extensionAPI.value) { + throw new Error("Extension API not initialized") } if (typeof extensionModule.install === 'function') { - await extensionModule.install(extensionAPI.value, path) + extensionAPI.value.setCurrentExtensionId(extensionId) + await extensionModule.install(extensionAPI.value) + extensionAPI.value.clearCurrentExtensionId() const extensionData = { module: extensionModule, + id: extensionId, path, loadedAt: new Date().toISOString(), - metadata: extensionModule.metadata || {}, + metadata: extensionModule.metadata, enabled: true, } - loadedExtensions.value.set(path, extensionData) + loadedExtensions.value.set(extensionId, extensionData) - console.log(`[AppStore] Extension loaded successfully: ${path}`) + console.log(`[AppStore] Extension loaded successfully: ${extensionId}`) return extensionModule } else { @@ -145,48 +148,48 @@ export const useAppStore = defineStore("app", () => { return Array.from(loadedExtensions.value.values()) } - function unloadExtension(path) { - const extensionData = getExtension(path) + function unloadExtension(id) { + const extensionData = getExtension(id) if (!extensionData) return false if (extensionData.module && typeof extensionData.module.uninstall === 'function') { try { - extensionData.module.uninstall(extensionAPI.value, path) - console.log(`[AppStore] Extension uninstall called: ${path}`) + extensionData.module.uninstall(extensionAPI.value) + console.log(`[AppStore] Extension uninstall called: ${id}`) } catch (error) { - console.error(`[AppStore] Error calling uninstall for ${path}:`, error) + console.error(`[AppStore] Error calling uninstall for ${id}:`, error) } } if (extensionAPI.value && typeof extensionAPI.value.unregisterToolsByExtension === 'function') { - extensionAPI.value.unregisterToolsByExtension(path) + extensionAPI.value.unregisterToolsByExtension(id) } - loadedExtensions.value.delete(path) - console.log(`[AppStore] Extension unloaded: ${path}`) + loadedExtensions.value.delete(id) + console.log(`[AppStore] Extension unloaded: ${id}`) return true } - function toggleExtension(path) { - const extensionData = getExtension(path) + function toggleExtension(id) { + const extensionData = getExtension(id) if (!extensionData) return false extensionData.enabled = !extensionData.enabled - console.log(`[AppStore] Extension ${extensionData.enabled ? 'enabled' : 'disabled'}: ${path}`) + console.log(`[AppStore] Extension ${extensionData.enabled ? 'enabled' : 'disabled'}: ${id}`) return extensionData.enabled } - function setExtensionEnabled(path, enabled) { - const extensionData = getExtension(path) + function setExtensionEnabled(id, enabled) { + const extensionData = getExtension(id) if (!extensionData) return false extensionData.enabled = enabled - console.log(`[AppStore] Extension ${enabled ? 'enabled' : 'disabled'}: ${path}`) + console.log(`[AppStore] Extension ${enabled ? 'enabled' : 'disabled'}: ${id}`) return true } - function getExtensionEnabled(path) { - return getExtension(path)?.enabled ?? false + function getExtensionEnabled(id) { + return getExtension(id)?.enabled ?? false } return { @@ -196,6 +199,7 @@ export const useAppStore = defineStore("app", () => { importStores, loadedExtensions, setExtensionAPI, + setCodeTransformer, loadExtension, getLoadedExtensions, unloadExtension, From 4302d900998f0c225cf1c685fa91b1e039b4815a Mon Sep 17 00:00:00 2001 From: SpliiT Date: Mon, 1 Dec 2025 16:10:43 +0100 Subject: [PATCH 13/25] add extensionID --- app/stores/app.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 6d5411ba..515f4edc 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -118,9 +118,7 @@ export const useAppStore = defineStore("app", () => { } if (typeof extensionModule.install === 'function') { - extensionAPI.value.setCurrentExtensionId(extensionId) - await extensionModule.install(extensionAPI.value) - extensionAPI.value.clearCurrentExtensionId() + await extensionModule.install(extensionAPI.value, extensionId) const extensionData = { module: extensionModule, From e2a93e1d62f1f9a438f458995dfb6ea2c4b31f4e Mon Sep 17 00:00:00 2001 From: SpliiT Date: Tue, 2 Dec 2025 10:03:22 +0100 Subject: [PATCH 14/25] rm useless extensionID --- app/stores/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/stores/app.js b/app/stores/app.js index 515f4edc..38d1c55d 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -118,7 +118,7 @@ export const useAppStore = defineStore("app", () => { } if (typeof extensionModule.install === 'function') { - await extensionModule.install(extensionAPI.value, extensionId) + await extensionModule.install(extensionAPI.value) const extensionData = { module: extensionModule, From 63727d5acf8e83e66eb57e1c4accb79a59df22e6 Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:33:32 +0000 Subject: [PATCH 15/25] Apply prepare changes --- app/stores/app.js | 44 ++++++++++++------- .../microservices/back/requirements.txt | 1 - .../microservices/viewer/requirements.txt | 1 - 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 38d1c55d..d19da3e7 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -87,23 +87,25 @@ export const useAppStore = defineStore("app", () => { try { let finalURL = path - if (codeTransformer.value && path.startsWith('blob:')) { + if (codeTransformer.value && path.startsWith("blob:")) { const response = await fetch(path) const code = await response.text() const transformedCode = codeTransformer.value(code) - const newBlob = new Blob([transformedCode], { type: 'application/javascript' }) + const newBlob = new Blob([transformedCode], { + type: "application/javascript", + }) finalURL = URL.createObjectURL(newBlob) } const extensionModule = await import(finalURL) - if (finalURL !== path && finalURL.startsWith('blob:')) { + if (finalURL !== path && finalURL.startsWith("blob:")) { URL.revokeObjectURL(finalURL) } if (!extensionModule.metadata?.id) { - throw new Error('Extension must have metadata.id') + throw new Error("Extension must have metadata.id") } const extensionId = extensionModule.metadata.id @@ -117,9 +119,9 @@ export const useAppStore = defineStore("app", () => { throw new Error("Extension API not initialized") } - if (typeof extensionModule.install === 'function') { + if (typeof extensionModule.install === "function") { await extensionModule.install(extensionAPI.value) - + const extensionData = { module: extensionModule, id: extensionId, @@ -134,7 +136,7 @@ export const useAppStore = defineStore("app", () => { return extensionModule } else { - throw new Error('Extension must export an install function') + throw new Error("Extension must export an install function") } } catch (error) { console.error(`[AppStore] Failed to load extension from ${path}:`, error) @@ -149,8 +151,11 @@ export const useAppStore = defineStore("app", () => { function unloadExtension(id) { const extensionData = getExtension(id) if (!extensionData) return false - - if (extensionData.module && typeof extensionData.module.uninstall === 'function') { + + if ( + extensionData.module && + typeof extensionData.module.uninstall === "function" + ) { try { extensionData.module.uninstall(extensionAPI.value) console.log(`[AppStore] Extension uninstall called: ${id}`) @@ -158,11 +163,14 @@ export const useAppStore = defineStore("app", () => { console.error(`[AppStore] Error calling uninstall for ${id}:`, error) } } - - if (extensionAPI.value && typeof extensionAPI.value.unregisterToolsByExtension === 'function') { + + if ( + extensionAPI.value && + typeof extensionAPI.value.unregisterToolsByExtension === "function" + ) { extensionAPI.value.unregisterToolsByExtension(id) } - + loadedExtensions.value.delete(id) console.log(`[AppStore] Extension unloaded: ${id}`) return true @@ -171,18 +179,22 @@ export const useAppStore = defineStore("app", () => { function toggleExtension(id) { const extensionData = getExtension(id) if (!extensionData) return false - + extensionData.enabled = !extensionData.enabled - console.log(`[AppStore] Extension ${extensionData.enabled ? 'enabled' : 'disabled'}: ${id}`) + console.log( + `[AppStore] Extension ${extensionData.enabled ? "enabled" : "disabled"}: ${id}`, + ) return extensionData.enabled } function setExtensionEnabled(id, enabled) { const extensionData = getExtension(id) if (!extensionData) return false - + extensionData.enabled = enabled - console.log(`[AppStore] Extension ${enabled ? 'enabled' : 'disabled'}: ${id}`) + console.log( + `[AppStore] Extension ${enabled ? "enabled" : "disabled"}: ${id}`, + ) return true } diff --git a/tests/integration/microservices/back/requirements.txt b/tests/integration/microservices/back/requirements.txt index 077aee27..bd3a3ef5 100644 --- a/tests/integration/microservices/back/requirements.txt +++ b/tests/integration/microservices/back/requirements.txt @@ -5,4 +5,3 @@ # pip-compile --output-file=tests/integration/microservices/back/requirements.txt tests/integration/microservices/back/requirements.in # -opengeodeweb-back==5.*,>=5.14.0rc1 diff --git a/tests/integration/microservices/viewer/requirements.txt b/tests/integration/microservices/viewer/requirements.txt index c33316e7..4d097394 100644 --- a/tests/integration/microservices/viewer/requirements.txt +++ b/tests/integration/microservices/viewer/requirements.txt @@ -5,4 +5,3 @@ # pip-compile --output-file=tests/integration/microservices/viewer/requirements.txt tests/integration/microservices/viewer/requirements.in # -opengeodeweb-viewer==1.*,>=1.13.0rc1 From 45afffd254f2a966e785816fb72ccb19d2447dba Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Fri, 5 Dec 2025 14:55:33 +0000 Subject: [PATCH 16/25] Apply prepare changes --- tests/integration/microservices/back/requirements.txt | 1 - tests/integration/microservices/viewer/requirements.txt | 4 ---- 2 files changed, 5 deletions(-) diff --git a/tests/integration/microservices/back/requirements.txt b/tests/integration/microservices/back/requirements.txt index 0c3a99e8..bd3a3ef5 100644 --- a/tests/integration/microservices/back/requirements.txt +++ b/tests/integration/microservices/back/requirements.txt @@ -5,4 +5,3 @@ # pip-compile --output-file=tests/integration/microservices/back/requirements.txt tests/integration/microservices/back/requirements.in # -opengeodeweb-back==5.*,>=5.14.0 diff --git a/tests/integration/microservices/viewer/requirements.txt b/tests/integration/microservices/viewer/requirements.txt index 143828a9..4d097394 100644 --- a/tests/integration/microservices/viewer/requirements.txt +++ b/tests/integration/microservices/viewer/requirements.txt @@ -5,7 +5,3 @@ # pip-compile --output-file=tests/integration/microservices/viewer/requirements.txt tests/integration/microservices/viewer/requirements.in # -<<<<<<< HEAD -======= -opengeodeweb-viewer==1.*,>=1.13.1rc1 ->>>>>>> f25a27343384d206ade11a2cd8b0659a964ba7dd From 9bf35d285e995adaaceeb314aa7ed4396f6228f5 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Mon, 8 Dec 2025 12:00:10 +0100 Subject: [PATCH 17/25] backendPath added --- app/stores/app.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/stores/app.js b/app/stores/app.js index d19da3e7..7ac9a531 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -83,7 +83,7 @@ export const useAppStore = defineStore("app", () => { return loadedExtensions.value.get(id) } - async function loadExtension(path) { + async function loadExtension(path, backendPath = null) { try { let finalURL = path @@ -126,6 +126,7 @@ export const useAppStore = defineStore("app", () => { module: extensionModule, id: extensionId, path, + backendPath, loadedAt: new Date().toISOString(), metadata: extensionModule.metadata, enabled: true, From 64288184fc671f4492f30ab1f16782eb020addd0 Mon Sep 17 00:00:00 2001 From: SpliiT Date: Mon, 8 Dec 2025 13:24:53 +0100 Subject: [PATCH 18/25] feat: dynamically adjust chat input textarea rows, character limit, and placeholder based on focus state --- app/utils/file_import_workflow.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/utils/file_import_workflow.js b/app/utils/file_import_workflow.js index 923cb61b..71cf9cff 100644 --- a/app/utils/file_import_workflow.js +++ b/app/utils/file_import_workflow.js @@ -30,7 +30,11 @@ async function importItem(item) { const dataStyleStore = useDataStyleStore() const hybridViewerStore = useHybridViewerStore() const treeviewStore = useTreeviewStore() - await dataBaseStore.registerObject(item.id) + try { + await dataBaseStore.registerObject(item.id) + } catch (error) { + console.warn(`[Import] Failed to register object ${item.id} in backend viewer:`, error) + } await dataBaseStore.addItem(item.id, { ...item, }) From b145f336b92ce2fad2e3b499e3c4a2e22ed9a5df Mon Sep 17 00:00:00 2001 From: SpliiT <106495600+SpliiT@users.noreply.github.com> Date: Mon, 8 Dec 2025 12:25:40 +0000 Subject: [PATCH 19/25] Apply prepare changes --- app/utils/file_import_workflow.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/utils/file_import_workflow.js b/app/utils/file_import_workflow.js index 71cf9cff..28727962 100644 --- a/app/utils/file_import_workflow.js +++ b/app/utils/file_import_workflow.js @@ -33,7 +33,10 @@ async function importItem(item) { try { await dataBaseStore.registerObject(item.id) } catch (error) { - console.warn(`[Import] Failed to register object ${item.id} in backend viewer:`, error) + console.warn( + `[Import] Failed to register object ${item.id} in backend viewer:`, + error, + ) } await dataBaseStore.addItem(item.id, { ...item, From f8e328775cced3063153c4eea4f48994b7867e06 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Mon, 8 Dec 2025 17:18:26 +0100 Subject: [PATCH 20/25] lauchExtensionMicroservice with backendPath --- app/stores/app.js | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/app/stores/app.js b/app/stores/app.js index 7ac9a531..05609c23 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -79,6 +79,40 @@ export const useAppStore = defineStore("app", () => { codeTransformer.value = transformer } + async function launchExtensionMicroservice(extensionId, backendPath) { + console.log( + `[AppStore] Launching microservice for extension: ${extensionId}`, + ) + console.log(`[AppStore] Backend path: ${backendPath}`) + + if (!backendPath) { + throw new Error(`No backend path provided for extension: ${extensionId}`) + } + + // Use the Electron IPC to launch the microservice + if (window.electronAPI && window.electronAPI.launchMicroservice) { + try { + const result = await window.electronAPI.launchMicroservice({ + name: extensionId, + executablePath: backendPath, + }) + console.log( + `[AppStore] Microservice launched for ${extensionId}:`, + result, + ) + return result + } catch (error) { + console.error( + `[AppStore] Failed to launch microservice for ${extensionId}:`, + error, + ) + throw error + } + } else { + throw new Error("Electron API not available for launching microservices") + } + } + function getExtension(id) { return loadedExtensions.value.get(id) } @@ -120,7 +154,7 @@ export const useAppStore = defineStore("app", () => { } if (typeof extensionModule.install === "function") { - await extensionModule.install(extensionAPI.value) + await extensionModule.install(extensionAPI.value, backendPath) const extensionData = { module: extensionModule, @@ -209,13 +243,16 @@ export const useAppStore = defineStore("app", () => { exportStores, importStores, loadedExtensions, + extensionAPI, setExtensionAPI, setCodeTransformer, loadExtension, getLoadedExtensions, + getExtension, unloadExtension, toggleExtension, setExtensionEnabled, getExtensionEnabled, + launchExtensionMicroservice, } }) From a9468f9029b6938fd100449dc461c225b9523932 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Mon, 8 Dec 2025 19:33:23 +0100 Subject: [PATCH 21/25] test --- app/stores/app.js | 28 ++++++---------------------- app/stores/infra.js | 31 +++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 22 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 05609c23..5739c0b2 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -89,28 +89,12 @@ export const useAppStore = defineStore("app", () => { throw new Error(`No backend path provided for extension: ${extensionId}`) } - // Use the Electron IPC to launch the microservice - if (window.electronAPI && window.electronAPI.launchMicroservice) { - try { - const result = await window.electronAPI.launchMicroservice({ - name: extensionId, - executablePath: backendPath, - }) - console.log( - `[AppStore] Microservice launched for ${extensionId}:`, - result, - ) - return result - } catch (error) { - console.error( - `[AppStore] Failed to launch microservice for ${extensionId}:`, - error, - ) - throw error - } - } else { - throw new Error("Electron API not available for launching microservices") - } + // Use infra store to launch the extension microservice + const infraStore = useInfraStore() + return await infraStore.launch_extension_microservice( + extensionId, + backendPath, + ) } function getExtension(id) { diff --git a/app/stores/infra.js b/app/stores/infra.js index ebf5c69c..451087c6 100644 --- a/app/stores/infra.js +++ b/app/stores/infra.js @@ -91,6 +91,37 @@ export const useInfraStore = defineStore("infra", { console.log("[INFRA] All microservices connected") return }, + async launch_extension_microservice(extensionId, backendPath) { + console.log(`[INFRA] Launching extension microservice: ${extensionId}`) + + if (this.app_mode === appMode.DESKTOP) { + // In DESKTOP mode, use Electron API + if (window.electronAPI && window.electronAPI.run_extension) { + return await window.electronAPI.run_extension( + extensionId, + backendPath, + ) + } + throw new Error("Electron API not available") + } else if (this.app_mode === appMode.BROWSER) { + // In BROWSER mode, use Nuxt server API + const response = await $fetch("/api/extension-launch", { + method: "POST", + body: { + extensionId, + executablePath: backendPath, + }, + }) + console.log(`[INFRA] Extension microservice launched: ${extensionId}`) + return response.port + } else { + // CLOUD mode - extensions not supported yet + console.warn( + `[INFRA] Extension microservices not supported in ${this.app_mode} mode`, + ) + return null + } + }, }, share: { omit: ["microservices"], From ed498905e3dc7a26e000915e640c158cefbca4b5 Mon Sep 17 00:00:00 2001 From: MaxNumerique Date: Tue, 9 Dec 2025 15:02:10 +0100 Subject: [PATCH 22/25] demo mode and debug --- app/stores/app.js | 19 ------------------- app/stores/infra.js | 31 ------------------------------- app/utils/file_import_workflow.js | 1 + 3 files changed, 1 insertion(+), 50 deletions(-) diff --git a/app/stores/app.js b/app/stores/app.js index 5739c0b2..1670d53e 100644 --- a/app/stores/app.js +++ b/app/stores/app.js @@ -79,24 +79,6 @@ export const useAppStore = defineStore("app", () => { codeTransformer.value = transformer } - async function launchExtensionMicroservice(extensionId, backendPath) { - console.log( - `[AppStore] Launching microservice for extension: ${extensionId}`, - ) - console.log(`[AppStore] Backend path: ${backendPath}`) - - if (!backendPath) { - throw new Error(`No backend path provided for extension: ${extensionId}`) - } - - // Use infra store to launch the extension microservice - const infraStore = useInfraStore() - return await infraStore.launch_extension_microservice( - extensionId, - backendPath, - ) - } - function getExtension(id) { return loadedExtensions.value.get(id) } @@ -237,6 +219,5 @@ export const useAppStore = defineStore("app", () => { toggleExtension, setExtensionEnabled, getExtensionEnabled, - launchExtensionMicroservice, } }) diff --git a/app/stores/infra.js b/app/stores/infra.js index 451087c6..ebf5c69c 100644 --- a/app/stores/infra.js +++ b/app/stores/infra.js @@ -91,37 +91,6 @@ export const useInfraStore = defineStore("infra", { console.log("[INFRA] All microservices connected") return }, - async launch_extension_microservice(extensionId, backendPath) { - console.log(`[INFRA] Launching extension microservice: ${extensionId}`) - - if (this.app_mode === appMode.DESKTOP) { - // In DESKTOP mode, use Electron API - if (window.electronAPI && window.electronAPI.run_extension) { - return await window.electronAPI.run_extension( - extensionId, - backendPath, - ) - } - throw new Error("Electron API not available") - } else if (this.app_mode === appMode.BROWSER) { - // In BROWSER mode, use Nuxt server API - const response = await $fetch("/api/extension-launch", { - method: "POST", - body: { - extensionId, - executablePath: backendPath, - }, - }) - console.log(`[INFRA] Extension microservice launched: ${extensionId}`) - return response.port - } else { - // CLOUD mode - extensions not supported yet - console.warn( - `[INFRA] Extension microservices not supported in ${this.app_mode} mode`, - ) - return null - } - }, }, share: { omit: ["microservices"], diff --git a/app/utils/file_import_workflow.js b/app/utils/file_import_workflow.js index 28727962..46766f4c 100644 --- a/app/utils/file_import_workflow.js +++ b/app/utils/file_import_workflow.js @@ -30,6 +30,7 @@ async function importItem(item) { const dataStyleStore = useDataStyleStore() const hybridViewerStore = useHybridViewerStore() const treeviewStore = useTreeviewStore() + console.log("importItem", { item }) try { await dataBaseStore.registerObject(item.id) } catch (error) { From f2f5355e86dcbd39cfcb393b76210c45604c38df Mon Sep 17 00:00:00 2001 From: JulienChampagnol <91873154+JulienChampagnol@users.noreply.github.com> Date: Mon, 15 Dec 2025 14:44:24 +0000 Subject: [PATCH 23/25] Apply prepare changes --- tests/integration/microservices/back/requirements.txt | 1 - tests/integration/microservices/viewer/requirements.txt | 1 - 2 files changed, 2 deletions(-) diff --git a/tests/integration/microservices/back/requirements.txt b/tests/integration/microservices/back/requirements.txt index 642f9cb6..bd3a3ef5 100644 --- a/tests/integration/microservices/back/requirements.txt +++ b/tests/integration/microservices/back/requirements.txt @@ -5,4 +5,3 @@ # pip-compile --output-file=tests/integration/microservices/back/requirements.txt tests/integration/microservices/back/requirements.in # -opengeodeweb-back==5.*,>=5.14.1 diff --git a/tests/integration/microservices/viewer/requirements.txt b/tests/integration/microservices/viewer/requirements.txt index 147e1750..4d097394 100644 --- a/tests/integration/microservices/viewer/requirements.txt +++ b/tests/integration/microservices/viewer/requirements.txt @@ -5,4 +5,3 @@ # pip-compile --output-file=tests/integration/microservices/viewer/requirements.txt tests/integration/microservices/viewer/requirements.in # -opengeodeweb-viewer==1.*,>=1.13.2 From 809d5972abab28ad647eddb64ce1ae16a4be55bb Mon Sep 17 00:00:00 2001 From: JulienChampagnol Date: Wed, 31 Dec 2025 13:53:50 +0100 Subject: [PATCH 24/25] merge --- tests/integration/microservices/back/requirements.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/integration/microservices/back/requirements.txt b/tests/integration/microservices/back/requirements.txt index 09e56325..c8f45967 100644 --- a/tests/integration/microservices/back/requirements.txt +++ b/tests/integration/microservices/back/requirements.txt @@ -5,7 +5,4 @@ # pip-compile --output-file=tests/integration/microservices/back/requirements.txt tests/integration/microservices/back/requirements.in # -<<<<<<< HEAD -======= opengeodeweb-back==5.*,>=5.14.3 ->>>>>>> 2fa9b2a0210e12b897fbcc5cea94e9ecc9b86d45 From d2776ab81599ece6401060aa01735efcdbed4b1d Mon Sep 17 00:00:00 2001 From: JulienChampagnol <91873154+JulienChampagnol@users.noreply.github.com> Date: Wed, 31 Dec 2025 12:54:32 +0000 Subject: [PATCH 25/25] Apply prepare changes --- tests/integration/microservices/back/requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/microservices/back/requirements.txt b/tests/integration/microservices/back/requirements.txt index c8f45967..bd3a3ef5 100644 --- a/tests/integration/microservices/back/requirements.txt +++ b/tests/integration/microservices/back/requirements.txt @@ -5,4 +5,3 @@ # pip-compile --output-file=tests/integration/microservices/back/requirements.txt tests/integration/microservices/back/requirements.in # -opengeodeweb-back==5.*,>=5.14.3