Desktop app dynamic config of API Port (#40)
* added dynamic configuration of Port in Desktop app * added dynamic configuration of API_URL to docker deployments. Now it works with editing only .env file.
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Runtime configuration for BaMoRT frontend
|
||||
*
|
||||
* For desktop builds (Wails), reads the API base URL from the Go backend
|
||||
* to allow runtime configuration via .env without rebuilding.
|
||||
*
|
||||
* For web builds, uses runtime config.json or auto-detection:
|
||||
* 1. Try to load /config.json (can be modified at deployment without rebuild)
|
||||
* 2. Try to detect backend at same origin (production reverse proxy setup)
|
||||
* 3. Fall back to VITE_API_URL (development) or same origin
|
||||
*/
|
||||
|
||||
let cachedAPIBaseURL = null
|
||||
|
||||
/**
|
||||
* Try to load configuration from /config.json
|
||||
*/
|
||||
async function loadConfigFile() {
|
||||
try {
|
||||
const response = await fetch('/config.json', {
|
||||
cache: 'no-cache',
|
||||
headers: { 'Accept': 'application/json' }
|
||||
})
|
||||
if (response.ok) {
|
||||
// Check if response is actually JSON (not HTML from SPA fallback)
|
||||
const contentType = response.headers.get('content-type')
|
||||
if (contentType && contentType.includes('application/json')) {
|
||||
const config = await response.json()
|
||||
if (config.apiBaseURL) {
|
||||
console.log('Loaded API URL from config.json:', config.apiBaseURL)
|
||||
return config.apiBaseURL
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// config.json doesn't exist or is invalid, that's okay
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Try to detect backend at same origin (production setup)
|
||||
*/
|
||||
async function detectBackendAtOrigin() {
|
||||
try {
|
||||
const origin = window.location.origin
|
||||
const response = await fetch(`${origin}/api/public/version`, {
|
||||
method: 'GET',
|
||||
cache: 'no-cache',
|
||||
signal: AbortSignal.timeout(2000) // 2 second timeout
|
||||
})
|
||||
if (response.ok) {
|
||||
console.log('Detected backend at same origin:', origin)
|
||||
return origin
|
||||
}
|
||||
} catch (error) {
|
||||
// Backend not at same origin, that's okay
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the API base URL dynamically
|
||||
* - In Wails desktop app: calls Go backend to get configured URL
|
||||
* - In web app: tries config.json, auto-detection, or VITE_API_URL
|
||||
*/
|
||||
export async function getAPIBaseURL() {
|
||||
// Return cached value if available
|
||||
if (cachedAPIBaseURL) {
|
||||
return cachedAPIBaseURL
|
||||
}
|
||||
|
||||
// Try Wails desktop app first (with timeout)
|
||||
if (typeof window !== 'undefined' && window['go']) {
|
||||
// Wait up to 3 seconds for Wails bindings to be ready
|
||||
for (let i = 0; i < 30; i++) {
|
||||
try {
|
||||
if (window['go']?.['main']?.['App']?.['GetAPIBaseURL']) {
|
||||
const url = await window['go']['main']['App']['GetAPIBaseURL']()
|
||||
cachedAPIBaseURL = url
|
||||
console.log('Desktop app using API URL from config:', url)
|
||||
return url
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to get API URL from Wails:', error)
|
||||
break
|
||||
}
|
||||
await new Promise(resolve => setTimeout(resolve, 100))
|
||||
}
|
||||
|
||||
// Wails detected but binding failed - use desktop fallback
|
||||
cachedAPIBaseURL = 'http://localhost:8185'
|
||||
console.log('Desktop app using fallback:', cachedAPIBaseURL)
|
||||
return cachedAPIBaseURL
|
||||
}
|
||||
|
||||
// Web app - try multiple strategies
|
||||
|
||||
// Strategy 1: Load from config.json (can be modified at deployment)
|
||||
const configFileURL = await loadConfigFile()
|
||||
if (configFileURL) {
|
||||
cachedAPIBaseURL = configFileURL
|
||||
return cachedAPIBaseURL
|
||||
}
|
||||
|
||||
// Strategy 2: Check if backend is at same origin (production reverse proxy)
|
||||
if (window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1') {
|
||||
const sameOriginURL = await detectBackendAtOrigin()
|
||||
if (sameOriginURL) {
|
||||
cachedAPIBaseURL = sameOriginURL
|
||||
return cachedAPIBaseURL
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy 3: Use VITE_API_URL (development) or fallback to same origin
|
||||
if (import.meta.env.VITE_API_URL) {
|
||||
cachedAPIBaseURL = import.meta.env.VITE_API_URL
|
||||
console.log('Web app using VITE_API_URL:', cachedAPIBaseURL)
|
||||
} else {
|
||||
// Final fallback: assume same origin for production
|
||||
cachedAPIBaseURL = window.location.origin
|
||||
console.log('Web app using same origin:', cachedAPIBaseURL)
|
||||
}
|
||||
|
||||
return cachedAPIBaseURL
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if running in desktop mode (Wails)
|
||||
*/
|
||||
export function isDesktopMode() {
|
||||
return isWailsApp()
|
||||
}typeof window !== 'undefined' &&
|
||||
window['go']?.['main']?.['App'] !== undefined
|
||||
Reference in New Issue
Block a user