import { Command } from "commander"; import path from "path"; import fs from "fs"; import chalk from "chalk"; import grabDBDir from "../utils/grab-db-dir"; import grabDirNames from "../data/grab-dir-names"; import snapshotDb from "../utils/snapshot-db"; import { writeExportArchive } from "../utils/export-archive"; import trimExports from "../utils/trim-exports"; import { AppData } from "../data/app-data"; function defaultExportFileName(dbName, format) { return `${dbName}-${Date.now()}.${format}`; } export default function () { return new Command("export") .description("Export database file + schema into a portable archive") .option("-o, --output ", "Output archive path (.tar.gz or .zip). Defaults to db exports dir") .option("-f, --format ", "Archive format when --output is omitted: tar.gz | zip", "tar.gz") .action(async (opts) => { console.log(`Exporting database ...`); const config = global.CONFIG; const { export_dir } = grabDBDir({ config }); const { BUN_SQLITE_TEMP_DIR } = grabDirNames(); if (!fs.existsSync(export_dir)) { fs.mkdirSync(export_dir, { recursive: true }); } const formatRaw = String(opts.format || "tar.gz").toLowerCase(); const format = formatRaw === "zip" ? "zip" : "tar.gz"; let outPath; if (opts.output) { outPath = path.resolve(opts.output); fs.mkdirSync(path.dirname(outPath), { recursive: true }); } else { outPath = path.join(export_dir, defaultExportFileName(config.db_name, format)); } const snapshot_path = path.join(BUN_SQLITE_TEMP_DIR, `export-${Date.now()}.db`); /** Remove the temp database file before exiting */ const exit = (code) => { fs.rmSync(snapshot_path, { force: true }); process.exit(code); }; try { snapshotDb({ db: global.SQLITE_CLIENT, dst: snapshot_path }); /** * The schema is always stored as `schema.` so `import` * can find it, whatever `db_schema_file_name` is. */ const schemaFileName = `${AppData.DbSchemaFileName}${path.extname(global.SCHEMA_FILE_PATH)}`; await writeExportArchive({ contents: { db: new Uint8Array(fs.readFileSync(snapshot_path)), schema: fs.readFileSync(global.SCHEMA_FILE_PATH, "utf-8"), schemaFileName, }, outPath, }); if (path.dirname(outPath) === export_dir) { trimExports({ config }); } console.log(`${chalk.bold(chalk.green(`DB Export Success!`))} → ${outPath}`); console.log(chalk.dim(`Contains: database.sqlite + ${schemaFileName}`)); exit(0); } catch (error) { console.error(chalk.red(`Export ERROR => ${error.message}`)); exit(1); } }); }