diff options
| author | Dhravya <[email protected]> | 2024-05-25 23:38:48 -0500 |
|---|---|---|
| committer | Dhravya <[email protected]> | 2024-05-25 23:38:48 -0500 |
| commit | c12ecfc4316a6f37d2d07c57e4dfefa231783c0d (patch) | |
| tree | c04612a8db2b06060e1e1087ef298fa124aa71e4 /apps/web/app/api | |
| parent | fix global file stuff (diff) | |
| download | supermemory-c12ecfc4316a6f37d2d07c57e4dfefa231783c0d.tar.xz supermemory-c12ecfc4316a6f37d2d07c57e4dfefa231783c0d.zip | |
brought all the APIs back
Diffstat (limited to 'apps/web/app/api')
| -rw-r--r-- | apps/web/app/api/chat/route.ts | 73 | ||||
| -rw-r--r-- | apps/web/app/api/getCount/route.ts | 47 | ||||
| -rw-r--r-- | apps/web/app/api/me/route.ts | 47 | ||||
| -rw-r--r-- | apps/web/app/api/spaces/route.ts | 29 | ||||
| -rw-r--r-- | apps/web/app/api/store/route.ts | 121 |
5 files changed, 317 insertions, 0 deletions
diff --git a/apps/web/app/api/chat/route.ts b/apps/web/app/api/chat/route.ts new file mode 100644 index 00000000..34099848 --- /dev/null +++ b/apps/web/app/api/chat/route.ts @@ -0,0 +1,73 @@ +import { type NextRequest } from "next/server"; +import { ChatHistory } from "@repo/shared-types"; +import { ensureAuth } from "../ensureAuth"; + +export const runtime = "edge"; + +export async function POST(req: NextRequest) { + const session = await ensureAuth(req); + + if (!session) { + return new Response("Unauthorized", { status: 401 }); + } + + if (!process.env.BACKEND_SECURITY_KEY) { + return new Response("Missing BACKEND_SECURITY_KEY", { status: 500 }); + } + + const query = new URL(req.url).searchParams.get("q"); + const spaces = new URL(req.url).searchParams.get("spaces"); + + const sourcesOnly = + new URL(req.url).searchParams.get("sourcesOnly") ?? "false"; + + const chatHistory = (await req.json()) as { + chatHistory: ChatHistory[]; + }; + + console.log("CHathistory", chatHistory); + + if (!query) { + return new Response(JSON.stringify({ message: "Invalid query" }), { + status: 400, + }); + } + + try { + const resp = await fetch( + `https://cf-ai-backend.dhravya.workers.dev/chat?q=${query}&user=${session.user.email ?? session.user.name}&sourcesOnly=${sourcesOnly}&spaces=${spaces}`, + { + headers: { + "X-Custom-Auth-Key": process.env.BACKEND_SECURITY_KEY!, + }, + method: "POST", + body: JSON.stringify({ + chatHistory: chatHistory.chatHistory ?? [], + }), + }, + ); + + console.log("sourcesOnly", sourcesOnly); + + if (sourcesOnly == "true") { + const data = await resp.json(); + console.log("data", data); + return new Response(JSON.stringify(data), { status: 200 }); + } + + if (resp.status !== 200 || !resp.ok) { + const errorData = await resp.json(); + console.log(errorData); + return new Response( + JSON.stringify({ message: "Error in CF function", error: errorData }), + { status: resp.status }, + ); + } + + // Stream the response back to the client + const { readable, writable } = new TransformStream(); + resp && resp.body!.pipeTo(writable); + + return new Response(readable, { status: 200 }); + } catch {} +} diff --git a/apps/web/app/api/getCount/route.ts b/apps/web/app/api/getCount/route.ts new file mode 100644 index 00000000..f760c145 --- /dev/null +++ b/apps/web/app/api/getCount/route.ts @@ -0,0 +1,47 @@ +import { db } from "@/app/helpers/server/db"; +import { and, eq, ne, sql } from "drizzle-orm"; +import { sessions, storedContent, users } from "@/app/helpers/server/db/schema"; +import { type NextRequest, NextResponse } from "next/server"; +import { ensureAuth } from "../ensureAuth"; + +export const runtime = "edge"; + +export async function GET(req: NextRequest) { + const session = await ensureAuth(req); + + if (!session) { + return new Response("Unauthorized", { status: 401 }); + } + + const tweetsCount = await db + .select({ + count: sql<number>`count(*)`.mapWith(Number), + }) + .from(storedContent) + .where( + and( + eq(storedContent.user, session.user.id), + eq(storedContent.type, "twitter-bookmark"), + ), + ); + + const pageCount = await db + .select({ + count: sql<number>`count(*)`.mapWith(Number), + }) + .from(storedContent) + .where( + and( + eq(storedContent.user, session.user.id), + ne(storedContent.type, "twitter-bookmark"), + ), + ); + + return NextResponse.json({ + tweetsCount: tweetsCount[0]!.count, + tweetsLimit: 1000, + pageCount: pageCount[0]!.count, + pageLimit: 100, + user: session.user.email, + }); +} diff --git a/apps/web/app/api/me/route.ts b/apps/web/app/api/me/route.ts new file mode 100644 index 00000000..20b6aece --- /dev/null +++ b/apps/web/app/api/me/route.ts @@ -0,0 +1,47 @@ +import { db } from "@/app/helpers/server/db"; +import { eq } from "drizzle-orm"; +import { sessions, users } from "@/app/helpers/server/db/schema"; +import { type NextRequest, NextResponse } from "next/server"; + +export const runtime = "edge"; + +export async function GET(req: NextRequest) { + const token = + req.cookies.get("next-auth.session-token")?.value ?? + req.cookies.get("__Secure-authjs.session-token")?.value ?? + req.cookies.get("authjs.session-token")?.value ?? + req.headers.get("Authorization")?.replace("Bearer ", ""); + + const session = await db + .select() + .from(sessions) + .where(eq(sessions.sessionToken, token!)); + + if (!session || session.length === 0) { + return new Response( + JSON.stringify({ message: "Invalid Key, session not found." }), + { status: 404 }, + ); + } + + const user = await db + .select() + .from(users) + .where(eq(users.id, session[0]!.userId)) + .limit(1); + + if (!user || user.length === 0) { + return NextResponse.json( + { message: "Invalid Key, session not found." }, + { status: 404 }, + ); + } + + return new Response( + JSON.stringify({ + message: "OK", + data: { session: session[0], user: user[0] }, + }), + { status: 200 }, + ); +} diff --git a/apps/web/app/api/spaces/route.ts b/apps/web/app/api/spaces/route.ts new file mode 100644 index 00000000..c46b02fc --- /dev/null +++ b/apps/web/app/api/spaces/route.ts @@ -0,0 +1,29 @@ +import { db } from "@/app/helpers/server/db"; +import { sessions, space, users } from "@/app/helpers/server/db/schema"; +import { eq } from "drizzle-orm"; +import { NextRequest, NextResponse } from "next/server"; +import { ensureAuth } from "../ensureAuth"; + +export const runtime = "edge"; + +export async function GET(req: NextRequest) { + const session = await ensureAuth(req); + + if (!session) { + return new Response("Unauthorized", { status: 401 }); + } + + const spaces = await db + .select() + .from(space) + .where(eq(space.user, session.user.id)) + .all(); + + return NextResponse.json( + { + message: "OK", + data: spaces, + }, + { status: 200 }, + ); +} diff --git a/apps/web/app/api/store/route.ts b/apps/web/app/api/store/route.ts new file mode 100644 index 00000000..f96f90cf --- /dev/null +++ b/apps/web/app/api/store/route.ts @@ -0,0 +1,121 @@ +import { db } from "@/app/helpers/server/db"; +import { and, eq, sql, inArray } from "drizzle-orm"; +import { + contentToSpace, + sessions, + storedContent, + users, + space, +} from "@/app/helpers/server/db/schema"; +import { type NextRequest, NextResponse } from "next/server"; +import { getMetaData } from "@/app/helpers/lib/get-metadata"; +import { ensureAuth } from "../ensureAuth"; + +export const runtime = "edge"; + +export async function POST(req: NextRequest) { + const session = await ensureAuth(req); + + if (!session) { + return new Response("Unauthorized", { status: 401 }); + } + + const data = (await req.json()) as { + pageContent: string; + url: string; + spaces?: string[]; + }; + + const metadata = await getMetaData(data.url); + let storeToSpaces = data.spaces; + + if (!storeToSpaces) { + storeToSpaces = []; + } + + const count = await db + .select({ + count: sql<number>`count(*)`.mapWith(Number), + }) + .from(storedContent) + .where( + and( + eq(storedContent.user, session.user.id), + eq(storedContent.type, "page"), + ), + ); + + if (count[0]!.count > 100) { + return NextResponse.json( + { message: "Error", error: "Limit exceeded" }, + { status: 499 }, + ); + } + + const rep = await db + .insert(storedContent) + .values({ + content: data.pageContent, + title: metadata.title, + description: metadata.description, + url: data.url, + baseUrl: metadata.baseUrl, + image: metadata.image, + savedAt: new Date(), + user: session.user.id, + }) + .returning({ id: storedContent.id }); + + const id = rep[0]?.id; + + if (!id) { + return NextResponse.json( + { message: "Error", error: "Error in CF function" }, + { status: 500 }, + ); + } + + if (storeToSpaces.length > 0) { + const spaceData = await db + .select() + .from(space) + .where( + and( + inArray(space.name, storeToSpaces ?? []), + eq(space.user, session.user.id), + ), + ) + .all(); + + await Promise.all([ + spaceData.forEach(async (space) => { + await db + .insert(contentToSpace) + .values({ contentId: id, spaceId: space.id }); + }), + ]); + } + + const res = (await Promise.race([ + fetch("https://cf-ai-backend.dhravya.workers.dev/add", { + method: "POST", + headers: { + "X-Custom-Auth-Key": process.env.BACKEND_SECURITY_KEY, + }, + body: JSON.stringify({ ...data, user: session.user.email }), + }), + new Promise((_, reject) => + setTimeout(() => reject(new Error("Request timed out")), 40000), + ), + ])) as Response; + + if (res.status !== 200) { + console.log(res.status, res.statusText); + return NextResponse.json( + { message: "Error", error: "Error in CF function" }, + { status: 500 }, + ); + } + + return NextResponse.json({ message: "OK", data: "Success" }, { status: 200 }); +} |