60 lines
1.9 KiB
JavaScript
60 lines
1.9 KiB
JavaScript
|
|
import { copyFile, mkdir, readdir, readFile, writeFile } from "node:fs/promises";
|
|||
|
|
import path from "node:path";
|
|||
|
|
|
|||
|
|
const sourceRoot = process.argv[2];
|
|||
|
|
const targetRoot = process.env.UPLOAD_DIR || process.argv[3];
|
|||
|
|
if (!sourceRoot || !targetRoot) {
|
|||
|
|
throw new Error(
|
|||
|
|
"用法:UPLOAD_DIR=/data/koc/uploads npm run storage:import -- /path/to/r2-export",
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
const contentTypes = {
|
|||
|
|
".avif": "image/avif",
|
|||
|
|
".gif": "image/gif",
|
|||
|
|
".jpeg": "image/jpeg",
|
|||
|
|
".jpg": "image/jpeg",
|
|||
|
|
".png": "image/png",
|
|||
|
|
".webp": "image/webp",
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
let copied = 0;
|
|||
|
|
async function walk(directory) {
|
|||
|
|
const entries = await readdir(directory, { withFileTypes: true });
|
|||
|
|
for (const entry of entries) {
|
|||
|
|
const absolute = path.join(directory, entry.name);
|
|||
|
|
if (entry.isDirectory()) {
|
|||
|
|
await walk(absolute);
|
|||
|
|
continue;
|
|||
|
|
}
|
|||
|
|
if (entry.name.endsWith(".metadata.json")) continue;
|
|||
|
|
const relative = path.relative(sourceRoot, absolute);
|
|||
|
|
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|||
|
|
throw new Error("导入目录越界");
|
|||
|
|
}
|
|||
|
|
const destination = path.join(targetRoot, relative);
|
|||
|
|
await mkdir(path.dirname(destination), { recursive: true });
|
|||
|
|
await copyFile(absolute, destination);
|
|||
|
|
const sourceMetadata = `${absolute}.metadata.json`;
|
|||
|
|
const metadataDestination = `${destination}.metadata.json`;
|
|||
|
|
let metadata;
|
|||
|
|
try {
|
|||
|
|
metadata = JSON.parse(await readFile(sourceMetadata, "utf8"));
|
|||
|
|
} catch {
|
|||
|
|
metadata = {
|
|||
|
|
contentType:
|
|||
|
|
contentTypes[path.extname(entry.name).toLowerCase()] ||
|
|||
|
|
"application/octet-stream",
|
|||
|
|
customMetadata: { source: "r2-export" },
|
|||
|
|
uploadedAt: new Date().toISOString(),
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
await writeFile(metadataDestination, JSON.stringify(metadata), "utf8");
|
|||
|
|
copied += 1;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
await mkdir(targetRoot, { recursive: true });
|
|||
|
|
await walk(sourceRoot);
|
|||
|
|
console.info(`imported objects: ${copied}`);
|