File size: 3,252 Bytes
13ae717
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
import { NextRequest, NextResponse } from "next/server";
import { createRepo, RepoDesignation, uploadFiles } from "@huggingface/hub";

import { isAuthenticated } from "@/lib/auth";
import Project from "@/models/Project";
import dbConnect from "@/lib/mongodb";
import { COLORS, getPTag } from "@/lib/utils";
// import type user
export async function GET() {
  const user = await isAuthenticated();

  if (user instanceof NextResponse || !user) {
    return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
  }

  await dbConnect();

  const projects = await Project.find({
    user_id: user?.id,
  })
    .sort({ _createdAt: -1 })
    .limit(100)
    .lean();
  if (!projects) {
    return NextResponse.json(
      {
        ok: false,
        projects: [],
      },
      { status: 404 }
    );
  }
  return NextResponse.json(
    {
      ok: true,
      projects,
    },
    { status: 200 }
  );
}

/**
 * This API route creates a new project in Hugging Face Spaces.
 * It requires an Authorization header with a valid token and a JSON body with the project details.
 */
export async function POST(request: NextRequest) {
  const user = await isAuthenticated();

  if (user instanceof NextResponse || !user) {
    return NextResponse.json({ message: "Unauthorized" }, { status: 401 });
  }

  const { title, html, prompts } = await request.json();

  if (!title || !html) {
    return NextResponse.json(
      { message: "Title and HTML content are required.", ok: false },
      { status: 400 }
    );
  }

  await dbConnect();

  try {
    let readme = "";
    let newHtml = html;

    const newTitle = title
      .toLowerCase()
      .replace(/[^a-z0-9]+/g, "-")
      .split("-")
      .filter(Boolean)
      .join("-")
      .slice(0, 96);

    const repo: RepoDesignation = {
      type: "space",
      name: `${user.name}/${newTitle}`,
    };

    const { repoUrl } = await createRepo({
      repo,
      accessToken: user.token as string,
    });
    const colorFrom = COLORS[Math.floor(Math.random() * COLORS.length)];
    const colorTo = COLORS[Math.floor(Math.random() * COLORS.length)];
    readme = `---
title: ${newTitle}
emoji: 🐳
colorFrom: ${colorFrom}
colorTo: ${colorTo}
sdk: static
pinned: false
tags:
  - deepsite
---

Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference`;

    newHtml = html.replace(/<\/body>/, `${getPTag(repo.name)}</body>`);
    const file = new File([newHtml], "index.html", { type: "text/html" });
    const readmeFile = new File([readme], "README.md", {
      type: "text/markdown",
    });
    const files = [file, readmeFile];
    await uploadFiles({
      repo,
      files,
      accessToken: user.token as string,
      commitTitle: `${prompts[prompts.length - 1]} - Initial Deployment`,
    });
    const path = repoUrl.split("/").slice(-2).join("/");
    const project = await Project.create({
      user_id: user.id,
      space_id: path,
      prompts,
    });
    return NextResponse.json({ project, path, ok: true }, { status: 201 });
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
  } catch (err: any) {
    return NextResponse.json(
      { error: err.message, ok: false },
      { status: 500 }
    );
  }
}