import { writeFileSync, existsSync } from 'fs'; import { join } from 'path'; import logger from './logger.js'; import config from './config.js'; /** * Generates the runtime configuration file (env.js) for the frontend * This allows the frontend to receive runtime configuration without rebuilding */ export function generateRuntimeConfig( frontendPath: string, basePath: string ): void { try { // In dev mode, write to public/env.js (source) // In production, write to env.js (dist) const isDev = process.env.NODE_ENV !== 'production'; const envJsPath = isDev ? join(frontendPath, 'public', 'env.js') : join(frontendPath, 'env.js'); // Check if frontend directory exists if (!existsSync(frontendPath)) { logger.warn( 'Frontend directory not found, skipping runtime config generation', { frontendPath, } ); return; } // Generate env.js content const envConfig = { basePath: basePath || '/', FRONTEND_API_KEY: config.apiKeys.frontend, }; // eslint-disable-next-line @typescript-eslint/no-unused-vars const envJsContent = `// Runtime configuration generated at container startup // DO NOT EDIT - This file is automatically generated // eslint-disable-next-line no-undef window.env = ${JSON.stringify(envConfig, null, 2)}; `; // Write env.js file writeFileSync(envJsPath, envJsContent, 'utf8'); logger.info('Runtime configuration generated successfully', { envJsPath, config: envConfig, }); } catch (error) { logger.error('Failed to generate runtime configuration', error as Error, { frontendPath, basePath, }); // Don't throw - allow server to start even if config generation fails } }