Clean upload API with proper types

This commit is contained in:
Manohar Gupta 2026-05-10 14:46:49 +05:30
parent 4bac63e065
commit 1fc52a0609

View file

@ -2,7 +2,6 @@ import { S3Client, PutObjectCommand, ListObjectsV2Command } from "@aws-sdk/clien
import { getSignedUrl } from "@aws-sdk/s3-request-presigner"; import { getSignedUrl } from "@aws-sdk/s3-request-presigner";
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
// Hardcoded R2 config - same as Cloudflare dashboard S3 API
const R2 = { const R2 = {
accountId: "e71f22a2f8614fb3ba6d9b28a264d8ce", accountId: "e71f22a2f8614fb3ba6d9b28a264d8ce",
accessKeyId: "6606d525c8e647d94e051b6d6565803b", accessKeyId: "6606d525c8e647d94e051b6d6565803b",
@ -21,30 +20,60 @@ const client = new S3Client({
const baseUrl = `https://pub-37a76fd657c94d1dbc521a109c087a11.r2.dev/tia`; const baseUrl = `https://pub-37a76fd657c94d1dbc521a109c087a11.r2.dev/tia`;
// GET: List all memories // GET memories
export async function GET() { export async function GET(req: NextRequest) {
try { try {
// List all objects in bucket const command = new ListObjectsV2Command({ Bucket: "tia" });
const command = new ListObjectsV2Command({ Bucket: R2.bucket });
const response = await client.send(command); const response = await client.send(command);
return NextResponse.json({ return NextResponse.json({
success: true, success: true,
bucket: R2.bucket,
count: response.Contents?.length || 0, count: response.Contents?.length || 0,
items: response.Contents?.map((o) => ({ items: response.Contents?.map((o) => ({
key: o.Key, key: o.Key,
url: `${baseUrl}/${o.Key}`,
size: o.Size, size: o.Size,
})), })),
}); });
} catch (e) { } catch (e: unknown) {
return NextResponse.json({ error: e.message, name: e.name, code: e.$metadata }, { status: 500 }); const err = e as Error;
return NextResponse.json({ error: err.message }, { status: 500 });
} }
} }
export { GET as default }; // POST get upload URL
export async function POST(req: NextRequest) {
let body;
try {
body = await req.json();
} catch {
return NextResponse.json({ error: "Invalid JSON" }, { status: 400 });
}
// Also exportGET for explicit call const { filename, contentType, childId } = body;
export async function handler(req: NextRequest) { if (!filename || !contentType) {
return GET(); return NextResponse.json({ error: "Missing filename or contentType" }, { status: 400 });
}
try {
const ext = filename.split(".").pop() || "jpg";
const key = `memories/${childId || "default"}/${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
const command = new PutObjectCommand({
Bucket: "tia",
Key: key,
ContentType: contentType,
});
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
return NextResponse.json({
uploadUrl: url,
key,
publicUrl: `${baseUrl}/${key}`,
});
} catch (e: unknown) {
const err = e as Error;
return NextResponse.json({ error: err.message }, { status: 500 });
}
} }