hugging-c-ai / src /app /api /upload /route.js
NeoPy's picture
feat: Hugging-c-ai v2 — HF OAuth + multi-provider AI + HF bucket storage + Gradio
60faa09
Raw History Blame Contribute Delete
2.73 kB
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 });
}
}