feat(cms): improve admin content editing
This commit is contained in:
parent
12d31f5468
commit
a284bbc188
26 changed files with 362 additions and 147 deletions
|
|
@ -4,11 +4,11 @@ import path from "path";
|
|||
import { storageDirectory } from "@/lib/runtime/config";
|
||||
import { listMediaFiles } from "@/lib/admin/media";
|
||||
import { contentFileNames, defaultContent } from "./defaults";
|
||||
import type { ContentDocuments, ContentKey, ContentSummary } from "./types";
|
||||
import type { ContentBackup, ContentDocuments, ContentKey, ContentSummary } from "./types";
|
||||
|
||||
export const contentDirectory = path.join(storageDirectory, "content");
|
||||
export const contentBackupDirectory = path.join(contentDirectory, "backups");
|
||||
export const contentVersion = "0.4.0";
|
||||
export const contentVersion = "0.4.1";
|
||||
|
||||
const contentKeys = Object.keys(contentFileNames) as ContentKey[];
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ function filePathFor(key: ContentKey) {
|
|||
function backupStamp() {
|
||||
const date = new Date();
|
||||
const pad = (value: number) => String(value).padStart(2, "0");
|
||||
return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}-${pad(date.getHours())}${pad(date.getMinutes())}`;
|
||||
return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}-${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`;
|
||||
}
|
||||
|
||||
async function pruneBackups(key: ContentKey) {
|
||||
|
|
@ -144,10 +144,33 @@ export async function getContentSummary(): Promise<ContentSummary> {
|
|||
};
|
||||
}
|
||||
|
||||
export async function listContentBackups(limit = 20): Promise<ContentBackup[]> {
|
||||
await ensureContentStorage();
|
||||
const entries = await readdir(contentBackupDirectory).catch(() => []);
|
||||
const backups = await Promise.all(entries
|
||||
.filter((entry) => entry.endsWith(".json"))
|
||||
.map(async (entry) => {
|
||||
const page = entry.split(".")[0] as ContentKey;
|
||||
const fullPath = path.join(contentBackupDirectory, entry);
|
||||
const fileStat = await stat(fullPath);
|
||||
return {
|
||||
page,
|
||||
fileName: entry,
|
||||
createdAt: fileStat.mtime.toISOString(),
|
||||
};
|
||||
}));
|
||||
|
||||
return backups
|
||||
.filter((backup) => contentKeys.includes(backup.page))
|
||||
.sort((left, right) => right.createdAt.localeCompare(left.createdAt))
|
||||
.slice(0, limit);
|
||||
}
|
||||
|
||||
export async function getContentSystemStatus() {
|
||||
const [summary, media] = await Promise.all([getContentSummary(), listMediaFiles()]);
|
||||
const [summary, media, backups] = await Promise.all([getContentSummary(), listMediaFiles(), listContentBackups()]);
|
||||
return {
|
||||
...summary,
|
||||
mediaCount: media.length,
|
||||
backups,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue