|
import { NextRequest, NextResponse } from "next/server"; |
|
import { RepoDesignation, spaceInfo, uploadFile } from "@huggingface/hub"; |
|
|
|
import { isAuthenticated } from "@/lib/auth"; |
|
import Project from "@/models/Project"; |
|
import dbConnect from "@/lib/mongodb"; |
|
import { getPTag } from "@/lib/utils"; |
|
|
|
export async function GET( |
|
req: NextRequest, |
|
{ params }: { params: Promise<{ namespace: string; repoId: string }> } |
|
) { |
|
const user = await isAuthenticated(); |
|
|
|
if (user instanceof NextResponse || !user) { |
|
return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); |
|
} |
|
|
|
await dbConnect(); |
|
const param = await params; |
|
const { namespace, repoId } = param; |
|
|
|
const project = await Project.findOne({ |
|
user_id: user.id, |
|
space_id: `${namespace}/${repoId}`, |
|
}).lean(); |
|
if (!project) { |
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Project not found", |
|
}, |
|
{ status: 404 } |
|
); |
|
} |
|
const space_url = `https://huggingface.co/spaces/${namespace}/${repoId}/raw/main/index.html`; |
|
try { |
|
const space = await spaceInfo({ |
|
name: namespace + "/" + repoId, |
|
accessToken: user.token as string, |
|
additionalFields: ["author"], |
|
}); |
|
|
|
if (!space || space.sdk !== "static") { |
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Space is not a static space", |
|
}, |
|
{ status: 404 } |
|
); |
|
} |
|
if (space.author !== user.name) { |
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Space does not belong to the authenticated user", |
|
}, |
|
{ status: 403 } |
|
); |
|
} |
|
|
|
const response = await fetch(space_url); |
|
if (!response.ok) { |
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Failed to fetch space HTML", |
|
}, |
|
{ status: 404 } |
|
); |
|
} |
|
let html = await response.text(); |
|
|
|
html = html.replace(getPTag(namespace + "/" + repoId), ""); |
|
|
|
return NextResponse.json( |
|
{ |
|
project: { |
|
...project, |
|
html, |
|
}, |
|
ok: true, |
|
}, |
|
{ status: 200 } |
|
); |
|
|
|
|
|
} catch (error: any) { |
|
if (error.statusCode === 404) { |
|
await Project.deleteOne({ |
|
user_id: user.id, |
|
space_id: `${namespace}/${repoId}`, |
|
}); |
|
return NextResponse.json( |
|
{ error: "Space not found", ok: false }, |
|
{ status: 404 } |
|
); |
|
} |
|
return NextResponse.json( |
|
{ error: error.message, ok: false }, |
|
{ status: 500 } |
|
); |
|
} |
|
} |
|
|
|
export async function PUT( |
|
req: NextRequest, |
|
{ params }: { params: Promise<{ namespace: string; repoId: string }> } |
|
) { |
|
const user = await isAuthenticated(); |
|
|
|
if (user instanceof NextResponse || !user) { |
|
return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); |
|
} |
|
|
|
await dbConnect(); |
|
const param = await params; |
|
const { namespace, repoId } = param; |
|
const { html, prompts } = await req.json(); |
|
|
|
const project = await Project.findOne({ |
|
user_id: user.id, |
|
space_id: `${namespace}/${repoId}`, |
|
}).lean(); |
|
if (!project) { |
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Project not found", |
|
}, |
|
{ status: 404 } |
|
); |
|
} |
|
|
|
const repo: RepoDesignation = { |
|
type: "space", |
|
name: `${namespace}/${repoId}`, |
|
}; |
|
|
|
const newHtml = html.replace(/<\/body>/, `${getPTag(repo.name)}</body>`); |
|
const file = new File([newHtml], "index.html", { type: "text/html" }); |
|
await uploadFile({ |
|
repo, |
|
file, |
|
accessToken: user.token as string, |
|
commitTitle: `${prompts[prompts.length - 1]} - Follow Up Deployment`, |
|
}); |
|
|
|
await Project.updateOne( |
|
{ user_id: user.id, space_id: `${namespace}/${repoId}` }, |
|
{ |
|
$set: { |
|
prompts: [ |
|
...(project && "prompts" in project ? project.prompts : []), |
|
...prompts, |
|
], |
|
}, |
|
} |
|
); |
|
return NextResponse.json({ ok: true }, { status: 200 }); |
|
} |
|
|
|
export async function POST( |
|
req: NextRequest, |
|
{ params }: { params: Promise<{ namespace: string; repoId: string }> } |
|
) { |
|
const user = await isAuthenticated(); |
|
|
|
if (user instanceof NextResponse || !user) { |
|
return NextResponse.json({ message: "Unauthorized" }, { status: 401 }); |
|
} |
|
|
|
await dbConnect(); |
|
const param = await params; |
|
const { namespace, repoId } = param; |
|
|
|
const space = await spaceInfo({ |
|
name: namespace + "/" + repoId, |
|
accessToken: user.token as string, |
|
additionalFields: ["author"], |
|
}); |
|
|
|
if (!space || space.sdk !== "static") { |
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Space is not a static space", |
|
}, |
|
{ status: 404 } |
|
); |
|
} |
|
if (space.author !== user.name) { |
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Space does not belong to the authenticated user", |
|
}, |
|
{ status: 403 } |
|
); |
|
} |
|
|
|
const project = await Project.findOne({ |
|
user_id: user.id, |
|
space_id: `${namespace}/${repoId}`, |
|
}).lean(); |
|
if (project) { |
|
|
|
return NextResponse.json( |
|
{ |
|
ok: false, |
|
error: "Project already exists", |
|
redirect: `/projects/${namespace}/${repoId}`, |
|
}, |
|
{ status: 400 } |
|
); |
|
} |
|
|
|
const newProject = new Project({ |
|
user_id: user.id, |
|
space_id: `${namespace}/${repoId}`, |
|
prompts: [], |
|
}); |
|
|
|
await newProject.save(); |
|
return NextResponse.json( |
|
{ |
|
ok: true, |
|
project: { |
|
id: newProject._id, |
|
space_id: newProject.space_id, |
|
prompts: newProject.prompts, |
|
}, |
|
}, |
|
{ status: 201 } |
|
); |
|
} |
|
|