File size: 2,733 Bytes
60faa09
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { NextResponse } from "next/server";
import { getServerSession } from "next-auth/next";
import { authOptions } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { getHFStorageForUser } from "@/lib/storage/hf";
import crypto from "crypto";

export async function POST(req) {
  try {
    const session = await getServerSession(authOptions);
    if (!session?.user?.id) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

    const formData = await req.formData();
    const file = formData.get("file");
    if (!file) return NextResponse.json({ error: "No file uploaded" }, { status: 400 });

    const ext = (file.name || "").split(".").pop() || "bin";
    const randomName = `${crypto.randomUUID()}.${ext}`;
    const path = `uploads/${session.user.id}/${randomName}`;

    const storage = getHFStorageForUser({
      hfAccessToken: session.user.hfAccessToken,
      hfUsername: session.user.hfUsername,
    });

    if (storage) {
      try {
        const buffer = Buffer.from(await file.arrayBuffer());
        const { url, repo, path: storedPath } = await storage.uploadFile(buffer, path);
        const dbImage = await prisma.userImage.create({
          data: { userId: session.user.id, url, hfRepo: repo, hfPath: storedPath },
        });
        return NextResponse.json({ url, id: dbImage.id, location: "hf", repo, path: storedPath });
      } catch (hfErr) {
        console.warn("[HF_UPLOAD_FAILED]", hfErr.message, "— falling back to MuAPI");
      }
    }

    const muApiKey = process.env.MU_API_KEY;
    if (!muApiKey) {
      return NextResponse.json({
        error: "Upload failed: no HF storage configured and no MU_API_KEY fallback set.",
      }, { status: 500 });
    }

    const forwardData = new FormData();
    forwardData.append("file", file);
    const muRes = await fetch("https://api.muapi.ai/api/v1/upload_file", {
      method: "POST",
      headers: { "x-api-key": muApiKey },
      body: forwardData,
    });
    if (!muRes.ok) {
      const errText = await muRes.text();
      console.error("[MUAPI_UPLOAD_ERROR]", errText);
      return NextResponse.json({ error: "Failed to upload file" }, { status: muRes.status });
    }
    const data = await muRes.json();
    const uploadedUrl = data.url;
    if (!uploadedUrl) return NextResponse.json({ error: "Invalid upload response" }, { status: 502 });

    const dbImage = await prisma.userImage.create({
      data: { userId: session.user.id, url: uploadedUrl },
    });
    return NextResponse.json({ url: uploadedUrl, id: dbImage.id, location: "muapi" });
  } catch (error) {
    console.error("[UPLOAD_ROUTE_ERROR]", error);
    return NextResponse.json({ error: error.message }, { status: 500 });
  }
}