Files
koc-loop/scripts/import-object-directory.mjs
2026-08-11 23:07:26 +08:00

60 lines
1.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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}`);