fokan's picture
Initial commit
fedfb56
raw
history blame
6.96 kB
import { NextRequest, NextResponse } from "next/server";
import { RepoDesignation, spaceInfo, uploadFiles, listFiles } from "@huggingface/hub";
import { isAuthenticated } from "@/lib/auth";
// Import local storage functions instead of MongoDB
import { findProject, saveProject } from "@/lib/local-storage";
import { Page } from "@/types";
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 });
}
// Use local storage instead of MongoDB
const param = await params;
const { namespace, repoId } = param;
const result = await findProject(user.id, namespace, repoId);
if (!result.success) {
return NextResponse.json(
{
ok: false,
error: "Project not found",
},
{ status: 404 }
);
}
const project = result.data;
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 repo: RepoDesignation = {
type: "space",
name: `${namespace}/${repoId}`,
};
const htmlFiles: Page[] = [];
const images: string[] = [];
const allowedImagesExtensions = ["jpg", "jpeg", "png", "gif", "svg", "webp", "avif", "heic", "heif", "ico", "bmp", "tiff", "tif"];
for await (const fileInfo of listFiles({repo, accessToken: user.token as string})) {
if (fileInfo.path.endsWith(".html")) {
const res = await fetch(`https://huggingface.co/spaces/${namespace}/${repoId}/raw/main/${fileInfo.path}`);
if (res.ok) {
const html = await res.text();
if (fileInfo.path === "index.html") {
htmlFiles.unshift({
path: fileInfo.path,
html,
});
} else {
htmlFiles.push({
path: fileInfo.path,
html,
});
}
}
}
if (fileInfo.type === "directory" && fileInfo.path === "images") {
for await (const imageInfo of listFiles({repo, accessToken: user.token as string, path: fileInfo.path})) {
if (allowedImagesExtensions.includes(imageInfo.path.split(".").pop() || "")) {
images.push(`https://huggingface.co/spaces/${namespace}/${repoId}/resolve/main/${imageInfo.path}`);
}
}
}
}
if (htmlFiles.length === 0) {
return NextResponse.json(
{
ok: false,
error: "No HTML files found",
},
{ status: 404 }
);
}
return NextResponse.json(
{
project: {
...project,
pages: htmlFiles,
images,
},
ok: true,
},
{ status: 200 }
);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (error: any) {
// We can't delete projects from local storage in the same way as MongoDB
// This would require implementing a deleteProject function
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 });
}
// Use local storage instead of MongoDB
const param = await params;
const { namespace, repoId } = param;
const { pages, prompts } = await req.json();
const result = await findProject(user.id, namespace, repoId);
if (!result.success) {
return NextResponse.json(
{
ok: false,
error: "Project not found",
},
{ status: 404 }
);
}
const repo: RepoDesignation = {
type: "space",
name: `${namespace}/${repoId}`,
};
const files: File[] = [];
const promptsFile = new File([prompts.join("\n")], "prompts.txt", {
type: "text/plain",
});
files.push(promptsFile);
pages.forEach((page: Page) => {
const file = new File([page.html], page.path, { type: "text/html" });
files.push(file);
});
await uploadFiles({
repo,
files,
accessToken: user.token as string,
commitTitle: `${prompts[prompts.length - 1]} - Follow Up Deployment`,
});
// Update project in local storage
const projectId = `${namespace}/${repoId}`;
const updatedProject = {
...result.data,
prompts: [
...prompts,
],
_updatedAt: new Date(),
};
await saveProject(projectId, updatedProject);
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 });
}
// Use local storage instead of MongoDB
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 result = await findProject(user.id, namespace, repoId);
if (result.success) {
// redirect to the project page if it already exists
return NextResponse.json(
{
ok: false,
error: "Project already exists",
redirect: `/projects/${namespace}/${repoId}`,
},
{ status: 400 }
);
}
// Create new project in local storage
const projectId = `${namespace}/${repoId}`;
const newProject = {
space_id: projectId,
user_id: user.id,
prompts: [],
_createdAt: new Date(),
_updatedAt: new Date(),
};
await saveProject(projectId, newProject);
return NextResponse.json(
{
ok: true,
project: {
id: projectId,
space_id: projectId,
prompts: [],
},
},
{ status: 201 }
);
}