r2-upload/scripts/upload.ts

69 lines
2.5 KiB
TypeScript
Raw Permalink Normal View History

2026-03-16 12:43:37 +00:00
import { existsSync, readFileSync } from "fs";
import { join, dirname, basename } from "path";
import { fileURLToPath } from "url";
import { loadR2Config, uploadFile } from "../src/index.js";
function loadEnvLocal(): void {
const scriptDir = dirname(fileURLToPath(import.meta.url));
const envPath = join(scriptDir, "../.env.local");
if (!existsSync(envPath)) return;
for (const line of readFileSync(envPath, "utf-8").split("\n")) {
const trimmed = line.trim();
if (!trimmed || trimmed.startsWith("#")) continue;
const eq = trimmed.indexOf("=");
if (eq <= 0) continue;
const key = trimmed.slice(0, eq).trim();
let val = trimmed.slice(eq + 1).trim();
if ((val.startsWith('"') && val.endsWith('"')) || (val.startsWith("'") && val.endsWith("'"))) {
val = val.slice(1, -1);
}
if (!process.env[key]) process.env[key] = val;
}
}
function parseArgs(args: string[]): { file: string; key: string; contentType: string; dryRun: boolean } {
let file = "";
let key = "";
let contentType = "";
let dryRun = false;
for (const arg of args) {
if (arg === "--dry-run") { dryRun = true; continue; }
if (arg === "-h" || arg === "--help") {
console.error("Usage: bun run upload -- --file=<path> [--key=<r2-key>] [--content-type=<mime>] [--dry-run]");
process.exit(0);
}
if (arg.startsWith("--file=")) { file = arg.slice("--file=".length).trim(); continue; }
if (arg.startsWith("--key=")) { key = arg.slice("--key=".length).trim(); continue; }
if (arg.startsWith("--content-type=")) { contentType = arg.slice("--content-type=".length).trim(); continue; }
}
return { file, key, contentType, dryRun };
}
async function main(): Promise<void> {
loadEnvLocal();
const args = parseArgs(process.argv.slice(2));
if (!args.file) {
console.error(JSON.stringify({ status: "failed", error: "missing --file" }));
process.exit(1);
}
const key = args.key || `uploads/${Date.now()}/${basename(args.file)}`;
if (args.dryRun) {
console.log(JSON.stringify({ status: "success", error: null, key, url: `(dry-run) ${key}`, size: 0, contentType: args.contentType || "auto" }, null, 2));
return;
}
const config = loadR2Config();
const result = await uploadFile(config, args.file, key, args.contentType || undefined);
console.log(JSON.stringify(result, null, 2));
if (result.status === "failed") process.exit(1);
}
main().catch((err) => {
console.error(JSON.stringify({ status: "failed", error: err instanceof Error ? err.message : String(err) }));
process.exit(1);
});