backup-data.js (1917B)
1 const fs = require("fs"); 2 const path = require("path"); 3 4 const ROOT_DIR = path.join(__dirname, ".."); 5 const DATA_DIR = path.resolve(process.env.DATA_DIR || path.join(ROOT_DIR, "data")); 6 const BACKUP_ROOT = path.resolve(process.env.BACKUP_DIR || path.join(DATA_DIR, "backups")); 7 const TARGETS = ["users.json", "posts.json", "reports.json", "mod-log.json", "sessions.json", "uploads"]; 8 9 function pad2(value) { 10 return String(value).padStart(2, "0"); 11 } 12 13 function timestamp() { 14 const d = new Date(); 15 return [ 16 d.getFullYear(), 17 pad2(d.getMonth() + 1), 18 pad2(d.getDate()), 19 "-", 20 pad2(d.getHours()), 21 pad2(d.getMinutes()), 22 pad2(d.getSeconds()) 23 ].join(""); 24 } 25 26 function copyIfExists(srcPath, destPath) { 27 if (!fs.existsSync(srcPath)) return false; 28 fs.cpSync(srcPath, destPath, { recursive: true, force: true }); 29 return true; 30 } 31 32 function main() { 33 fs.mkdirSync(DATA_DIR, { recursive: true }); 34 fs.mkdirSync(BACKUP_ROOT, { recursive: true }); 35 36 const name = `backup-${timestamp()}`; 37 const targetDir = path.join(BACKUP_ROOT, name); 38 fs.mkdirSync(targetDir, { recursive: false }); 39 40 const copied = []; 41 for (const rel of TARGETS) { 42 const src = path.join(DATA_DIR, rel); 43 const dest = path.join(targetDir, rel); 44 if (copyIfExists(src, dest)) copied.push(rel); 45 } 46 47 const manifest = { 48 version: 1, 49 createdAt: Date.now(), 50 createdAtIso: new Date().toISOString(), 51 dataDir: DATA_DIR, 52 backupRoot: BACKUP_ROOT, 53 backupName: name, 54 copied 55 }; 56 fs.writeFileSync(path.join(targetDir, "manifest.json"), JSON.stringify(manifest, null, 2) + "\n", "utf8"); 57 58 console.log(`Created backup: ${targetDir}`); 59 if (!copied.length) console.log("No runtime files existed yet; backup contains only manifest."); 60 else console.log(`Copied: ${copied.join(", ")}`); 61 } 62 63 try { 64 main(); 65 } catch (e) { 66 console.error("Backup failed:", e?.message || e); 67 process.exit(1); 68 }