Files
broccolini-bot/services/configPersistence.js
indifferentketchup 69c247ed1b huge changes
2026-04-07 01:43:06 -05:00

106 lines
2.7 KiB
JavaScript

const fs = require('fs');
const path = require('path');
const { CONFIG } = require('../config');
const ENV_PATH = process.env.ENV_FILE
? path.resolve(process.env.ENV_FILE)
: path.resolve(process.cwd(), '.env');
/**
* Read the current .env file and parse into a key->value Map.
*/
function readEnvFile() {
if (!fs.existsSync(ENV_PATH)) return new Map();
const lines = fs.readFileSync(ENV_PATH, 'utf8').split('\n');
const map = new Map();
for (const line of lines) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) continue;
const idx = line.indexOf('=');
if (idx === -1) continue;
const key = line.slice(0, idx).trim();
const value = line.slice(idx + 1).trim();
map.set(key, value);
}
return map;
}
/**
* Write a Map of key->value back to the .env file,
* preserving comments and blank lines.
*/
function writeEnvFile(updates) {
if (!fs.existsSync(ENV_PATH)) {
const lines = [];
for (const [k, v] of updates) lines.push(`${k}=${v}`);
fs.writeFileSync(ENV_PATH, lines.join('\n') + '\n', 'utf8');
return;
}
const raw = fs.readFileSync(ENV_PATH, 'utf8');
const lines = raw.split('\n');
const written = new Set();
const result = lines.map(line => {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith('#')) return line;
const idx = line.indexOf('=');
if (idx === -1) return line;
const key = line.slice(0, idx).trim();
if (updates.has(key)) {
written.add(key);
return `${key}=${updates.get(key)}`;
}
return line;
});
// Append any new keys not already in the file
for (const [k, v] of updates) {
if (!written.has(k)) result.push(`${k}=${v}`);
}
fs.writeFileSync(ENV_PATH, result.join('\n'), 'utf8');
}
/**
* Apply a flat object of { KEY: value } to both CONFIG and .env.
* Returns { applied: string[], errors: string[] }
*/
function applyConfigUpdates(updates) {
const applied = [];
const errors = [];
for (const [key, rawValue] of Object.entries(updates)) {
try {
if (rawValue === 'true' || rawValue === 'false') {
CONFIG[key] = rawValue === 'true';
} else if (!isNaN(rawValue) && rawValue !== '') {
CONFIG[key] = Number(rawValue);
} else {
CONFIG[key] = rawValue;
}
applied.push(key);
} catch (err) {
errors.push(`${key}: ${err.message}`);
}
}
// Write to .env
const envMap = readEnvFile();
for (const [key, value] of Object.entries(updates)) {
envMap.set(key, String(value));
}
writeEnvFile(envMap);
return { applied, errors };
}
/**
* Read all current env values for the settings UI.
*/
function readAllConfig() {
return readEnvFile();
}
module.exports = { applyConfigUpdates, readAllConfig, readEnvFile, writeEnvFile };