const fs = require('fs') const path = require('path') function loadJsonConfig(filePath) { try { const txt = fs.readFileSync(filePath, 'utf8') const obj = JSON.parse(txt) Object.keys(obj).forEach(k => { if (process.env[k] === undefined) process.env[k] = String(obj[k]) }) console.log('Loaded config from', filePath) return true } catch (e) { return false } } function loadDotEnv(filePath) { try { const txt = fs.readFileSync(filePath, 'utf8') const lines = txt.split(/\r?\n/) for (const line of lines) { const l = line.trim() if (!l || l.startsWith('#')) continue const idx = l.indexOf('=') if (idx === -1) continue const key = l.slice(0, idx).trim() let val = l.slice(idx + 1).trim() if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) { val = val.slice(1, -1) } if (process.env[key] === undefined) process.env[key] = val } console.log('Loaded .env from', filePath) return true } catch (e) { return false } } // Precedence (higher wins because we only fill undefined keys): // 1) real environment variables // 2) CONFIG_FILE / CONFIG_PATH (explicit) // 3) .env (local secrets) // 4) config.json (repo/local config) // 5) config.json.example (defaults) const explicitPath = process.env.CONFIG_FILE || process.env.CONFIG_PATH const candidates = [ explicitPath ? path.resolve(explicitPath) : null, path.join(__dirname, '.env'), path.join(__dirname, 'config.json'), path.join(__dirname, 'config.json.example') ].filter(Boolean) let loadedAny = false for (const p of candidates) { if (!fs.existsSync(p)) continue const ok = p.endsWith('.env') ? loadDotEnv(p) : p.endsWith('.json') ? loadJsonConfig(p) : false if (ok) loadedAny = true } if (!loadedAny) { // no config found; silent } module.exports = {}