const fs = require("fs/promises"); const path = require("path"); const { loadEnv } = require("./env"); let cached = null; function parseNumber(value) { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : null; } function applyEnvOverrides(config = {}) { const merged = { ...config }; merged.rebrickable = { ...(config.rebrickable || {}) }; if (process.env.REBRICKABLE_API_KEY) { merged.rebrickable.apiKey = process.env.REBRICKABLE_API_KEY; } const weather = config.weather || {}; const providers = weather.providers || {}; merged.weather = { ...weather, providers: { ...providers } }; merged.weather.providers.influxdb = { ...(providers.influxdb || {}) }; merged.weather.providers.openMeteo = { ...(providers.openMeteo || {}) }; if (process.env.WEATHER_INFLUXDB_URL) { merged.weather.providers.influxdb.url = process.env.WEATHER_INFLUXDB_URL; } if (process.env.WEATHER_INFLUXDB_TOKEN) { merged.weather.providers.influxdb.token = process.env.WEATHER_INFLUXDB_TOKEN; } const envLatitude = parseNumber(process.env.WEATHER_OPEN_METEO_LATITUDE); if (envLatitude !== null) { merged.weather.providers.openMeteo.latitude = envLatitude; } const envLongitude = parseNumber(process.env.WEATHER_OPEN_METEO_LONGITUDE); if (envLongitude !== null) { merged.weather.providers.openMeteo.longitude = envLongitude; } merged.goaccess = { ...(config.goaccess || {}) }; if (process.env.GOACCESS_URL) { merged.goaccess.url = process.env.GOACCESS_URL; } return merged; } async function loadToolsConfig(configPath = "tools/config/config.json") { const resolved = path.resolve(configPath); if (cached && cached.path === resolved) { return cached.data; } loadEnv(); const raw = await fs.readFile(resolved, "utf8"); const data = applyEnvOverrides(JSON.parse(raw)); cached = { path: resolved, data }; return data; } module.exports = { applyEnvOverrides, loadToolsConfig, };