import { NextRequest, NextResponse } from "next/server"; import { auth } from "@clerk/nextjs/server"; import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3"; import { v4 as uuidv4 } from "uuid"; const s3Client = new S3Client({ endpoint: process.env.S3_ENDPOINT, region: process.env.S3_REGION || "eu-2", credentials: { accessKeyId: process.env.S3_ACCESS_KEY_ID!, secretAccessKey: process.env.S3_SECRET_ACCESS_KEY!, }, forcePathStyle: true, }); const S3_BUCKET = process.env.S3_BUCKET_NAME || "monuments-images"; const MAX_FILE_SIZE = 5 * 1024 * 1024; const ALLOWED_TYPES = ["image/jpeg", "image/png", "image/webp", "image/gif"]; function getPublicUrl(key: string): string { return `/api/image?key=${encodeURIComponent(key)}`; } export async function POST(req: NextRequest) { const { userId } = await auth(); if (!userId) { return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); } try { const formData = await req.formData(); const file = formData.get("file") as File | null; if (!file) { return NextResponse.json({ error: "No file provided" }, { status: 400 }); } if (!ALLOWED_TYPES.includes(file.type)) { return NextResponse.json({ error: "Invalid file type" }, { status: 400 }); } if (file.size > MAX_FILE_SIZE) { return NextResponse.json({ error: "File too large (max 5MB)" }, { status: 400 }); } const ext = file.type.split("/")[1]; const key = `uploads/${userId}/${uuidv4()}.${ext}`; const buffer = Buffer.from(await file.arrayBuffer()); await s3Client.send( new PutObjectCommand({ Bucket: S3_BUCKET, Key: key, Body: buffer, ContentType: file.type, }) ); const publicUrl = getPublicUrl(key); return NextResponse.json({ key, url: publicUrl }); } catch (error) { console.error("Upload error:", error); return NextResponse.json({ error: "Upload failed" }, { status: 500 }); } }