2026-07-22 15:03:32 +00:00
|
|
|
const path = require('node:path');
|
|
|
|
|
const os = require('node:os');
|
|
|
|
|
const fs = require('node:fs');
|
|
|
|
|
|
2026-07-22 15:16:42 +00:00
|
|
|
const CONFIG_DIR = process.env.STOKE_CONFIG_DIR
|
|
|
|
|
|| process.env.FORGEJO_CONFIG_DIR
|
|
|
|
|
|| path.join(process.env.XDG_CONFIG_HOME || os.homedir(), '.config', 'stoke');
|
|
|
|
|
const CONFIG_PATH = process.env.STOKE_CONFIG_FILE
|
|
|
|
|
|| process.env.FORGEJO_CONFIG_FILE
|
2026-07-22 15:03:32 +00:00
|
|
|
|| path.join(CONFIG_DIR, 'config.json');
|
|
|
|
|
const CONFIG_MODE = 0o600;
|
|
|
|
|
const DIR_MODE = 0o700;
|
|
|
|
|
|
|
|
|
|
function ensureConfigDir() {
|
|
|
|
|
fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: DIR_MODE });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function loadConfig() {
|
|
|
|
|
try {
|
|
|
|
|
const raw = fs.readFileSync(CONFIG_PATH, 'utf8');
|
|
|
|
|
return JSON.parse(raw);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
if (err.code === 'ENOENT') return null;
|
|
|
|
|
throw new Error(`Failed to read config at ${CONFIG_PATH}: ${err.message}`);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function saveConfig(config) {
|
|
|
|
|
ensureConfigDir();
|
|
|
|
|
const tmp = `${CONFIG_PATH}.tmp`;
|
|
|
|
|
fs.writeFileSync(tmp, JSON.stringify(config, null, 2), { mode: CONFIG_MODE });
|
|
|
|
|
fs.renameSync(tmp, CONFIG_PATH);
|
|
|
|
|
try {
|
|
|
|
|
fs.chmodSync(CONFIG_PATH, CONFIG_MODE);
|
|
|
|
|
} catch {
|
|
|
|
|
// ignore on platforms where chmod is unsupported
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function clearConfig() {
|
|
|
|
|
try {
|
|
|
|
|
fs.unlinkSync(CONFIG_PATH);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
if (err.code !== 'ENOENT') throw err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
|
CONFIG_DIR,
|
|
|
|
|
CONFIG_PATH,
|
|
|
|
|
loadConfig,
|
|
|
|
|
saveConfig,
|
|
|
|
|
clearConfig,
|
|
|
|
|
};
|