/** * API Configuration Utility * Centralized configuration for API endpoints with environment-based routing */ export interface ApiConfig { baseUrl: string; socketUrl: string; siteUrl: string; domainUrl: string; } /** * Gets the API base URL from environment variables with fallback * Supports both client-side (Vite) and server-side (Node.js) environments */ export function getApiBaseUrl(): string { // Client-side: Check for Vite injected env vars if (typeof window !== "undefined") { // Check for globally injected ENV (from Remix) const windowEnv = (window as any).ENV && (window as any).ENV.VITE_API_BASE_URL; if (windowEnv) return windowEnv; } // Server-side: Check Node.js process.env if ( typeof process !== "undefined" && process.env && process.env.VITE_API_BASE_URL ) { return process.env.VITE_API_BASE_URL; } // Environment-specific fallbacks const nodeEnv = (typeof process !== "undefined" && process.env ? process.env.NODE_ENV : undefined) || "development"; switch (nodeEnv) { case "production": return "https://api.vitrown.com"; case "development": return "https://api.vitrown.abrino.cloud"; default: return "https://api.vitrown.com"; } } /** * Gets the internal API URL for server-side requests (SSR) * Uses Kubernetes internal service URL to avoid hairpin NAT issues * Falls back to external URL if INTERNAL_API_URL is not set */ export function getInternalApiUrl(): string { // Only use internal URL on server-side if (typeof window === "undefined") { if ( typeof process !== "undefined" && process.env && process.env.INTERNAL_API_URL ) { return process.env.INTERNAL_API_URL; } } // Fallback to regular API URL return getApiBaseUrl(); } /** * Gets the WebSocket URL from environment variables with fallback */ export function getSocketBaseUrl(): string { if (typeof window !== "undefined") { const windowEnv = (window as any).ENV && (window as any).ENV.VITE_API_SOCKET_BASE_URL; if (windowEnv) return windowEnv; } if ( typeof process !== "undefined" && process.env && process.env.VITE_API_SOCKET_BASE_URL ) { return process.env.VITE_API_SOCKET_BASE_URL; } // Convert HTTP to WebSocket protocol return getApiBaseUrl().replace(/^https?:\/\//, "wss://"); } /** * Gets the site URL from environment variables with fallback */ export function getSiteUrl(): string { if (typeof window !== "undefined") { const windowEnv = (window as any).ENV && (window as any).ENV.VITE_SITE_URL; if (windowEnv) return windowEnv; } if ( typeof process !== "undefined" && process.env && process.env.VITE_SITE_URL ) { return process.env.VITE_SITE_URL; } const nodeEnv = (typeof process !== "undefined" && process.env ? process.env.NODE_ENV : undefined) || "development"; switch (nodeEnv) { case "production": return "https://vitrown.com"; case "development": return "https://vitrown.abrino.cloud"; default: return "https://vitrown.com"; } } /** * Gets the domain URL from environment variables with fallback */ export function getDomainUrl(): string { if (typeof window !== "undefined") { const windowEnv = (window as any).ENV && (window as any).ENV.VITE_DOMAIN_URL; if (windowEnv) return windowEnv; } if ( typeof process !== "undefined" && process.env && process.env.VITE_DOMAIN_URL ) { return process.env.VITE_DOMAIN_URL; } // Fallback to site URL return getSiteUrl(); } /** * Gets complete API configuration object */ export function getApiConfig(): ApiConfig { return { baseUrl: getApiBaseUrl(), socketUrl: getSocketBaseUrl(), siteUrl: getSiteUrl(), domainUrl: getDomainUrl(), }; } /** * Environment detection utilities */ export const isProduction = (): boolean => { const nodeEnv = typeof process !== "undefined" && process.env ? process.env.NODE_ENV : undefined; return nodeEnv === "production"; }; export const isDevelopment = (): boolean => !isProduction(); /** * Clean URL helper - removes trailing slashes */ export function cleanUrl(url: string): string { return (url && url.replace(/\/+$/, "")) || ""; }