Simplify: just list bucket contents for debug
This commit is contained in:
parent
d4f617e159
commit
59ae046726
1 changed files with 37 additions and 120 deletions
|
|
@ -1,133 +1,50 @@
|
||||||
import { S3Client, PutObjectCommand, ListObjectsV2Command, ListBucketsCommand } from "@aws-sdk/client-s3";
|
import { S3Client, PutObjectCommand, ListObjectsV2Command } from "@aws-sdk/client-s3";
|
||||||
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";
|
||||||
|
|
||||||
function getR2() {
|
// Hardcoded R2 config - same as Cloudflare dashboard S3 API
|
||||||
// Debug: explicitly hardcode for now since env might not be passed to container
|
const R2 = {
|
||||||
const accountId = "e71f22a2f8614fb3ba6d9b28a264d8ce";
|
accountId: "e71f22a2f8614fb3ba6d9b28a264d8ce",
|
||||||
const accessKeyId = "6606d525c8e647d94e051b6d6565803b";
|
accessKeyId: "6606d525c8e647d94e051b6d6565803b",
|
||||||
const secretKey = "244fcc44041f452241cbc68374cd7a6ca651cb71f361bc36cc932407bbe37863";
|
secretKey: "244fcc44041f452241cbc68374cd7a6ca651cb71f361bc36cc932407bbe37863",
|
||||||
const bucket = "tia";
|
bucket: "tia",
|
||||||
|
};
|
||||||
|
|
||||||
// Try just account-level endpoint (no bucket in path)
|
const client = new S3Client({
|
||||||
const endpoint = `https://${accountId}.r2.cloudflarestorage.com`;
|
region: "auto",
|
||||||
|
endpoint: `https://${R2.accountId}.r2.cloudflarestorage.com`,
|
||||||
|
credentials: {
|
||||||
|
accessKeyId: R2.accessKeyId,
|
||||||
|
secretAccessKey: R2.secretKey,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
if (!accountId || !accessKeyId || !secretKey || !bucket) {
|
const baseUrl = `https://pub-37a76fd657c94d1dbc521a109c087a11.r2.dev/tia`;
|
||||||
throw new Error(`Missing R2 config`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// S3 API endpoint includes bucket name: https://<accountId>.r2.cloudflarestorage.com/<bucket>
|
// GET: List all memories
|
||||||
const endpoint = `https://${accountId}.r2.cloudflarestorage.com/${bucket}`;
|
export async function GET() {
|
||||||
|
|
||||||
return {
|
|
||||||
client: new S3Client({
|
|
||||||
region: "auto",
|
|
||||||
endpoint,
|
|
||||||
credentials: { accessKeyId, secretAccessKey: secretKey },
|
|
||||||
}),
|
|
||||||
bucket,
|
|
||||||
// Public URL uses pub- subdomain format
|
|
||||||
baseUrl: `https://pub-37a76fd657c94d1dbc521a109c087a11.r2.dev/tia`,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// GET: List memories
|
|
||||||
export async function GET(req: NextRequest) {
|
|
||||||
try {
|
try {
|
||||||
const { client, bucket, baseUrl } = getR2();
|
// List all objects in bucket
|
||||||
const childId = req.nextUrl.searchParams.get("childId") || "default";
|
const command = new ListObjectsV2Command({ Bucket: R2.bucket });
|
||||||
|
const response = await client.send(command);
|
||||||
// List ALL objects in bucket (no prefix filtering for debugging)
|
|
||||||
const command = new ListObjectsV2Command({
|
|
||||||
Bucket: bucket,
|
|
||||||
MaxKeys: 100
|
|
||||||
});
|
|
||||||
|
|
||||||
const res = await client.send(command);
|
|
||||||
|
|
||||||
const objects = (res.Contents || []).map((obj) => ({
|
|
||||||
key: obj.Key,
|
|
||||||
url: `${baseUrl}/${obj.Key}`,
|
|
||||||
size: obj.Size,
|
|
||||||
lastModified: obj.LastModified?.toISOString(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
return NextResponse.json({ memories: objects });
|
|
||||||
} catch (error) {
|
|
||||||
console.error("R2 list error:", error);
|
|
||||||
return NextResponse.json({ error: String(error) }, { status: 500 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const { filename, contentType, childId } = body;
|
|
||||||
if (!filename || !contentType) {
|
|
||||||
return NextResponse.json({ error: "Missing filename or contentType" }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const { client, bucket, baseUrl } = getR2();
|
|
||||||
|
|
||||||
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: bucket,
|
|
||||||
Key: key,
|
|
||||||
ContentType: contentType,
|
|
||||||
});
|
|
||||||
|
|
||||||
const url = await getSignedUrl(client, command, { expiresIn: 3600 });
|
|
||||||
|
|
||||||
return NextResponse.json({
|
|
||||||
uploadUrl: url,
|
|
||||||
key,
|
|
||||||
publicUrl: `${baseUrl}/${key}`,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("R2 error:", error);
|
|
||||||
return NextResponse.json({ error: String(error) }, { status: 500 });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// PUT: Direct upload
|
|
||||||
export async function PUT(req: NextRequest) {
|
|
||||||
try {
|
|
||||||
const { client, bucket, baseUrl } = getR2();
|
|
||||||
const key = req.nextUrl.searchParams.get("key");
|
|
||||||
const contentType = req.nextUrl.searchParams.get("contentType") || "image/jpeg";
|
|
||||||
|
|
||||||
if (!key) {
|
|
||||||
return NextResponse.json({ error: "Missing key" }, { status: 400 });
|
|
||||||
}
|
|
||||||
|
|
||||||
const arrayBuffer = await req.arrayBuffer();
|
|
||||||
const buffer = Buffer.from(arrayBuffer);
|
|
||||||
|
|
||||||
const command = new PutObjectCommand({
|
|
||||||
Bucket: bucket,
|
|
||||||
Key: key,
|
|
||||||
Body: buffer,
|
|
||||||
ContentType: contentType,
|
|
||||||
});
|
|
||||||
|
|
||||||
await client.send(command);
|
|
||||||
|
|
||||||
return NextResponse.json({
|
return NextResponse.json({
|
||||||
success: true,
|
success: true,
|
||||||
key,
|
bucket: R2.bucket,
|
||||||
url: `${baseUrl}/${key}`,
|
count: response.Contents?.length || 0,
|
||||||
|
items: response.Contents?.map((o) => ({
|
||||||
|
key: o.Key,
|
||||||
|
size: o.Size,
|
||||||
|
})),
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (e) {
|
||||||
console.error("R2 upload error:", error);
|
return NextResponse.json({ error: e.message, name: e.name, code: e.$metadata }, { status: 500 });
|
||||||
return NextResponse.json({ error: String(error) }, { status: 500 });
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export { GET as default };
|
||||||
|
|
||||||
|
// Also exportGET for explicit call
|
||||||
|
export async function handler(req: NextRequest) {
|
||||||
|
return GET();
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue