UNPKG

@paroicms/server

Version:
73 lines 3.03 kB
import { ensureDirectory, fileStatsOrUndef } from "@paroicms/internal-server-lib"; import { createReadStream } from "node:fs"; import { copyFile, readdir, rm, stat } from "node:fs/promises"; import { join } from "node:path"; import { buildSiteBackup, makeBackupTempDir } from "./backup-tasks.js"; import { checkBackupFileName } from "./backup.helper.js"; export async function makeSiteBackup(siteContext, { serverVersion }) { const tmpPath = join(siteContext.cacheDir, "tmp"); await ensureDirectory(tmpPath); const { dirPath: backupTempDir, dirName: backupArchiveName } = await makeBackupTempDir(siteContext.fqdn, tmpPath); const { zipFilePath, zipFileWeight, zipFileName } = await buildSiteBackup(siteContext, { backupTempDir, archiveBaseName: backupArchiveName, serverVersion, }); await copyFile(zipFilePath, join(siteContext.backupDir, zipFileName)); await rm(zipFilePath); await rm(backupTempDir, { recursive: true }); return { zipFileName, zipFileWeight, }; } export async function getBackup(siteContext, backupName) { const backupPath = join(siteContext.backupDir, backupName); const fileStats = await fileStatsOrUndef(backupPath); if (!fileStats) throw new Error("[backup]: invalid backup path"); const stream = createReadStream(backupPath); return { fileWeight: fileStats.size, fileStream: stream, }; } export async function listBackups(siteContext, { offset = 0, limit = 10 }) { const { backupDir, fqdn } = siteContext; let files; try { files = await readdir(backupDir); } catch { return { items: [], total: 0 }; } const validFiles = files.filter((f) => checkBackupFileName({ fqdn }, f)); const parsed = validFiles.map((fileName) => { const dateStr = fileName.substring(0, 13); const year = dateStr.substring(0, 4); const month = dateStr.substring(4, 6); const day = dateStr.substring(6, 8); const hour = dateStr.substring(9, 11); const minute = dateStr.substring(11, 13); const createdAt = new Date(`${year}-${month}-${day}T${hour}:${minute}:00`).toISOString(); return { fileName, createdAt }; }); parsed.sort((a, b) => b.createdAt.localeCompare(a.createdAt)); const total = parsed.length; const paginated = parsed.slice(offset, offset + limit); const items = await Promise.all(paginated.map(async ({ fileName, createdAt }) => { const filePath = join(backupDir, fileName); const stats = await stat(filePath); return { fileName, fileWeight: stats.size, createdAt }; })); return { items, total }; } export async function deleteBackupFile(siteContext, fileName) { const { backupDir, fqdn } = siteContext; if (!checkBackupFileName({ fqdn }, fileName)) { throw new Error("Invalid backup filename"); } const filePath = join(backupDir, fileName); await rm(filePath); } //# sourceMappingURL=backup.js.map