const fs = require('fs/promises'); const path = require('path'); const { randomUUID } = require('crypto'); async function ensureDir(dirPath) { await fs.mkdir(dirPath, { recursive: true }); } async function readJson(filePath) { const raw = await fs.readFile(filePath, 'utf8'); return JSON.parse(raw); } async function readJsonIfExists(filePath) { if (!(await fileExists(filePath))) { return null; } return readJson(filePath); } async function writeJson(filePath, value) { await ensureDir(path.dirname(filePath)); const tempPath = `${filePath}.${randomUUID()}.tmp`; await fs.writeFile(tempPath, JSON.stringify(value, null, 2)); await fs.rename(tempPath, filePath); } async function fileExists(filePath) { try { await fs.access(filePath); return true; } catch (error) { return false; } } async function listJsonFiles(dirPath) { await ensureDir(dirPath); const entries = await fs.readdir(dirPath, { withFileTypes: true }); return entries .filter((entry) => entry.isFile() && entry.name.endsWith('.json')) .map((entry) => path.join(dirPath, entry.name)) .sort(); } async function appendJsonLine(filePath, value) { await ensureDir(path.dirname(filePath)); await fs.appendFile(filePath, `${JSON.stringify(value)}\n`); } async function moveFile(fromPath, toPath) { await ensureDir(path.dirname(toPath)); await fs.rename(fromPath, toPath); } async function removeFile(filePath) { await fs.rm(filePath, { force: true }); } module.exports = { ensureDir, readJson, readJsonIfExists, writeJson, fileExists, listJsonFiles, appendJsonLine, moveFile, removeFile, };