Files
Pickup-Config/services/jsonFileStore.js
Meik bd41e8c079 chore: sync running docker state
Commit the app code currently running in Docker, including scheduler, store status, journal reminder, maintenance mode, and Foodsharing API check updates. Remove generated runtime logs from version control and ignore local runtime captures.
2026-06-14 21:21:07 +02:00

90 lines
2.2 KiB
JavaScript

const fs = require('fs');
const path = require('path');
function ensureDirForFile(filePath) {
const dir = path.dirname(filePath);
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir, { recursive: true });
}
}
function cloneDefault(defaultValue) {
return JSON.parse(JSON.stringify(defaultValue));
}
function fsyncPath(filePath) {
let fd = null;
try {
fd = fs.openSync(filePath, 'r');
fs.fsyncSync(fd);
} catch (error) {
if (error.code !== 'EINVAL' && error.code !== 'EBADF') {
throw error;
}
} finally {
if (fd !== null) {
fs.closeSync(fd);
}
}
}
function readJsonFile(filePath, defaultValue, validate = () => true) {
ensureDirForFile(filePath);
if (!fs.existsSync(filePath)) {
writeJsonFile(filePath, defaultValue, { backup: false });
return cloneDefault(defaultValue);
}
try {
const raw = fs.readFileSync(filePath, 'utf8');
const parsed = JSON.parse(raw);
if (validate(parsed)) {
return parsed;
}
throw new Error('JSON shape validation failed');
} catch (error) {
const backupPath = `${filePath}.bak`;
if (fs.existsSync(backupPath)) {
try {
const backup = JSON.parse(fs.readFileSync(backupPath, 'utf8'));
if (validate(backup)) {
console.warn(`[JSON-STORE] Nutze Backup fuer ${filePath}: ${error.message}`);
return backup;
}
} catch (backupError) {
console.warn(`[JSON-STORE] Backup fuer ${filePath} ist unbrauchbar: ${backupError.message}`);
}
}
throw error;
}
}
function writeJsonFile(filePath, payload, { backup = true } = {}) {
ensureDirForFile(filePath);
const dir = path.dirname(filePath);
const tmpPath = path.join(
dir,
`.${path.basename(filePath)}.${process.pid}.${Date.now()}.tmp`
);
const serialized = JSON.stringify(payload, null, 2);
fs.writeFileSync(tmpPath, serialized);
fsyncPath(tmpPath);
if (backup && fs.existsSync(filePath)) {
fs.copyFileSync(filePath, `${filePath}.bak`);
}
fs.renameSync(tmpPath, filePath);
try {
fsyncPath(dir);
} catch (error) {
console.warn(`[JSON-STORE] Directory fsync fuer ${dir} fehlgeschlagen: ${error.message}`);
}
}
module.exports = {
readJsonFile,
writeJsonFile
};