const fs = require("fs-extra") const path = require("path") const { spawn } = require("child_process") const archiver = require("archiver") const { LoadConfig } = require("../../lib/config") const { serverDir } = require("./generate") const config = LoadConfig() const { server_location, backup_location, merge_pre_command, merge_post_command } = config const RunCommand = (command) => { return new Promise((resolve) => { console.log(` Running: ${command}`) const proc = spawn(command, [], { shell: true, stdio: "inherit" }) proc.on("close", (code) => { if (code === 0) console.log(" Command completed.") else console.log(` Command exited with code ${code}`) resolve(code) }) proc.on("error", (err) => { console.error(" Command failed:", err.message) resolve(1) }) }) } const CreateBackup = (sourceDir, backupDir) => { return new Promise(async (resolve, reject) => { const now = new Date() const timestamp = now.toISOString() .replace(/[:.]/g, "-") .replace("T", "_") .slice(0, 19) const zipName = `backup_${timestamp}.zip` const zipPath = path.join(backupDir, zipName) await fs.ensureDir(backupDir) const output = fs.createWriteStream(zipPath) const archive = archiver("zip", { zlib: { level: 9 } }) output.on("close", () => { console.log(` Created backup: ${zipName} (${archive.pointer()} bytes)`) resolve(zipPath) }) archive.on("error", err => reject(err)) archive.pipe(output) archive.directory(sourceDir, false) archive.finalize() }) } const Merge = async () => { if (!server_location || !backup_location) { console.log(" Error: server_location and backup_location must be set in config.") return } if (!await fs.pathExists(serverDir)) { console.log(" Error: No generated files found. Run 'generate' first.") return } // Run pre-command if (merge_pre_command) { console.log("\n Running pre-merge command...") await RunCommand(merge_pre_command) console.log("") } // Check if server location exists and back it up if (await fs.pathExists(server_location)) { console.log(` Backing up ${server_location}...`) try { await CreateBackup(server_location, backup_location) } catch (err) { console.error(" Failed to create backup:", err.message) return } } else { console.log(" Server location doesn't exist, creating it...") await fs.ensureDir(server_location) } // Move generated files to server location console.log(" Moving generated files to server location...") try { const items = await fs.readdir(serverDir) for (const item of items) { const src = path.join(serverDir, item) const dest = path.join(server_location, item) // Remove existing item at destination if (await fs.pathExists(dest)) await fs.remove(dest) await fs.move(src, dest) console.log(` Moved: ${item}`) } // Remove the now-empty server directory await fs.remove(serverDir) console.log(" Merge complete!") } catch (err) { console.error(" Failed to move files:", err.message) return } // Run post-command if (merge_post_command) { console.log("\n Running post-merge command...") await RunCommand(merge_post_command) } } module.exports = { Merge }