67 lines
2.2 KiB
JavaScript
67 lines
2.2 KiB
JavaScript
import { Elysia, t } from "elysia";
|
|
import { join } from "path";
|
|
import { mkdir } from "fs/promises";
|
|
import { randomUUID } from "crypto";
|
|
import prisma from "../lib/prisma";
|
|
export const uploadRoute = new Elysia({ prefix: "/upload" })
|
|
.post("/", async ({ body, set }) => {
|
|
const { file } = body;
|
|
if (!file) {
|
|
set.status = 400;
|
|
return { error: "No file uploaded" };
|
|
}
|
|
// Validate file type
|
|
if (!file.type.startsWith("image/") && !file.type.startsWith("video/")) {
|
|
set.status = 400;
|
|
return { error: "Only image and video files are allowed" };
|
|
}
|
|
console.log(`[Upload] Processing: ${file.name} (${(file.size / 1024).toFixed(2)} KB, ${file.type})`);
|
|
// Generate unique filename
|
|
const ext = file.name.split(".").pop();
|
|
const filename = `${randomUUID()}.${ext}`;
|
|
const uploadDir = join(process.cwd(), "public", "uploads");
|
|
const filePath = join(uploadDir, filename);
|
|
try {
|
|
// Ensure directory exists
|
|
await mkdir(uploadDir, { recursive: true });
|
|
// Write file using Bun.write
|
|
await Bun.write(filePath, await file.arrayBuffer());
|
|
const relativePath = `/uploads/${filename}`;
|
|
const mimeType = file.type;
|
|
const sizeBytes = file.size;
|
|
await prisma.media.create({
|
|
data: {
|
|
filename,
|
|
path: relativePath,
|
|
mimeType,
|
|
sizeBytes,
|
|
}
|
|
});
|
|
const BACKEND_PUBLIC_URL = process.env.BACKEND_PUBLIC_URL || "http://localhost:3051";
|
|
const publicUrl = `${BACKEND_PUBLIC_URL}${relativePath}`;
|
|
console.log(`[Upload] Success: ${filename} -> ${publicUrl}`);
|
|
return {
|
|
success: true,
|
|
url: publicUrl,
|
|
filename,
|
|
path: relativePath
|
|
};
|
|
}
|
|
catch (err) {
|
|
console.error("[Upload] Error:", err);
|
|
set.status = 500;
|
|
return { error: "Failed to save file" };
|
|
}
|
|
}, {
|
|
body: t.Object({
|
|
file: t.File({
|
|
maxSize: '5m',
|
|
type: ['image/jpeg', 'image/png', 'image/webp', 'image/gif']
|
|
})
|
|
}),
|
|
detail: {
|
|
summary: "Upload product image",
|
|
tags: ["upload"]
|
|
}
|
|
});
|
|
//# sourceMappingURL=upload.js.map
|