/** * 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