import { NextResponse } from 'next/server'; import { WhiskClient } from '@/lib/whisk-client'; export async function POST(req: Request) { try { const { imageBase64, mimeType, category, cookies } = await req.json(); if (!imageBase64 || !mimeType || !category || !cookies) { const missing = []; if (!imageBase64) missing.push('imageBase64'); if (!mimeType) missing.push('mimeType'); if (!category) missing.push('category'); if (!cookies) missing.push('cookies'); return NextResponse.json({ error: `Missing required fields: ${missing.join(', ')}` }, { status: 400 }); } // 1. Validate MIME Type const allowedTypes = ['image/jpeg', 'image/png', 'image/webp', 'image/gif']; if (!allowedTypes.includes(mimeType)) { return NextResponse.json({ error: `Unsupported file type: ${mimeType}. Please use JPG, PNG, or WEBP.` }, { status: 400 }); } // 2. Normalize and Validate Cookies let validCookies = cookies.trim(); let isJson = false; let parsedCookies = ""; // Auto-fix: Handle JSON array (e.g. from Cookie-Editor export) if (validCookies.startsWith('[') || validCookies.startsWith('{')) { isJson = true; try { const cookieArray = JSON.parse(validCookies); if (Array.isArray(cookieArray)) { // Convert ALL cookies to a string, not just 1PSID parsedCookies = cookieArray .map((c: any) => `${c.name}=${c.value}`) .join('; '); console.log(`[API] Successfully parsed ${cookieArray.length} cookies from JSON.`); validCookies = parsedCookies; } else if (cookieArray.name && cookieArray.value) { validCookies = `${cookieArray.name}=${cookieArray.value}`; } } catch (e) { console.warn("[API] Failed to parse cookie JSON, falling back to raw value:", e); // If parsing fails, just use the raw string, maybe it's not JSON after all. } } // Auto-fix: If user pasted just a raw value (heuristic) if (!isJson && !validCookies.includes('=')) { // If it's a long string without =, it might be a raw token. // We can't know the key, so we might guess `__Secure-1PSID` but that failed before. // Let's assume if it's raw, it's garbage unless we know for sure. // But actually, we previously tried prepending. Let's keep that only if we are desperate. // For now, let's just use what we have. if (validCookies.length > 50) { validCookies = `__Secure-1PSID=${validCookies}`; // Last resort guess } } // 3. Relaxed Validation: Don't error if 1PSID is missing, just try. // Some users might have different cookie names (e.g. __Secure-3PSID). if (!validCookies.includes('=')) { return NextResponse.json({ error: 'Invalid Cookie Format', details: 'Cookies must be in "name=value" format or a JSON list.' }, { status: 400 }); } console.log(`[API] Uploading reference image (${category}, ${mimeType})...`); console.log(`[API] Using cookies (first 50 chars): ${validCookies.substring(0, 50)}...`); const client = new WhiskClient(validCookies); // Remove header if present for WhiskClient (it expects clean base64 sometimes, or maybe not? // whisk-client.ts uploadReferenceImage constructs dataUri itself: `data:${mimeType};base64,${fileBase64}` // So we should pass RAW base64 without header. const rawBase64 = imageBase64.replace(/^data:image\/\w+;base64,/, ""); const mediaId = await client.uploadReferenceImage(rawBase64, mimeType, category); if (!mediaId) { return NextResponse.json({ error: 'Upload returned no ID' }, { status: 500 }); } return NextResponse.json({ success: true, id: mediaId }); } catch (error: any) { console.error("Reference Upload API failed:", error); return NextResponse.json({ error: error.message || 'Upload failed', details: error.toString() }, { status: 500 }); } }