@paroicms/server
Version:
The ParoiCMS server
73 lines • 3.03 kB
JavaScript
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