import { NextResponse } from "next/server" import { z } from "zod" import { db } from "@/lib/db" import { utapi } from "uploadthing/server" /** * @swagger * /api/gweets: * get: * description: Gives back a List of Gweets * content: * application/json: * schema: * responses: * 200: * description: fetched gweets! * 500: * description: Error * * post: * description: Creates Gweet * responses: * 200: * description: Gweet created! * 401: * description: Unauthorized * 500: * description: Error * * delete: * description: Deletes Gweet * responses: * 200: * description: deleted! * 401: * description: Unauthorized * 500: * description: Error */ export async function GET(request: Request) { const { searchParams } = new URL(request.url) const type = searchParams.get("type") || undefined const id = searchParams.get("id") || undefined const cursorQuery = searchParams.get("cursor") || undefined const take = Number(searchParams.get("limit")) || 20 const skip = cursorQuery ? 1 : 0 const cursor = cursorQuery ? { id: cursorQuery } : undefined try { // if (type === "threads") { // const gweet = await db.gweet.findUnique({ // where: { // id, // }, // }) // let thread = [] // if (cursorQuery === undefined) { // if (gweet && gweet.replyToGweetId) thread = await fetchThread(gweet.replyToGweetId) // } // // logic correct TODO get all gweets above comment // const prevId = thread.length < 4 ? undefined : thread[thread.length - 1].id // return NextResponse.json({ gweets: thread, prevId }, { status: 200 }) // } const gweets = await db.gweet.findMany({ skip, take, cursor, where: { ...(type === "comments" && { replyToGweetId: id, }), ...(type === "search" && { content: { contains: id, mode: "insensitive", }, }), ...(type === "user_gweets" && { author: { username: id, }, }), ...(type === "user_replies" && { author: { username: id, }, NOT: { replyToGweetId: null, }, }), ...(type === "user_media" && { author: { username: id, }, media: { some: {}, }, }), ...(type === "user_likes" && { likes: { some: { user: { username: id, }, }, }, }), }, include: { author: { select: { id: true, username: true, name: true, image: true, }, }, likes: true, media: true, regweets: true, quote: { include: { author: true, media: true, }, }, comment: { include: { author: { select: { id: true, username: true, }, }, }, }, allComments: true, allQuotes: true, }, orderBy: { createdAt: "desc", }, }) const nextId = gweets.length < take ? undefined : gweets[gweets.length - 1]?.id return NextResponse.json({ gweets, nextId }, { status: 200 }) } catch (error) { return NextResponse.json(error, { status: 500 }) } } export async function POST(request: Request) { const { gweet, fileprops } = await request.json() const gweetSchema = z .object({ content: z.string().min(1).max(280), authorId: z.string().cuid(), replyToGweetId: z.string().cuid().optional(), quoteGweetId: z.string().cuid().optional(), }) .strict() const zodGweet = gweetSchema.safeParse(gweet) const mediaSchema = z.array( z.object({ gweetId: z.string().nullable().optional(), url: z.string(), key: z.string(), type: z.string(), }).strict() ) if (!zodGweet.success) { return NextResponse.json({ message: "Invalid request body", error: zodGweet.error.formErrors, }, { status: 400 }) } try { const created_gweet = await db.gweet.create({ data: { ...gweet, }, }) if (fileprops.length > 0) { const mediaArray = fileprops.map((fileprop: { fileUrl: string; fileKey: string }) => { const media = { gweetId: created_gweet.id, url: fileprop.fileUrl, key: fileprop.fileKey, type: "IMAGE", } return media }) const zodMedia = mediaSchema.safeParse(mediaArray) if (!zodMedia.success) { return NextResponse.json({ message: "Invalid media body", error: zodMedia.error.formErrors, }, { status: 400 }) } await db.media.createMany({ data: mediaArray, }) } return NextResponse.json(created_gweet, { status: 201 }) } catch (error: any) { return NextResponse.json({ message: "Something went wrong", error: error.message, }, { status: error.errorCode || 500 }) } } export async function DELETE(request: Request) { const { searchParams } = new URL(request.url) const id = searchParams.get("id") as string const idSchema = z.string().cuid() const zod = idSchema.safeParse(id) if (!zod.success) { return NextResponse.json( { message: "Invalid request body", error: zod.error.formErrors, }, { status: 400 }, ) } try { const checkMedia = await db.media.findMany({ where: { gweetId: id, }, }) if (checkMedia.length > 0) { await utapi.deleteFiles(checkMedia.map((media) => media.key)) } await db.gweet.delete({ where: { id, }, }) return NextResponse.json({ message: "Gweet deleted" }, { status: 200 }) } catch (error: any) { return NextResponse.json({ message: "Something went wrong", error: error.message, }, { status: error.errorCode || 500 }) } } // function to get gweet thread from comment // async function fetchThread(gweetId: string): Promise<any[]> { // let thread = [] // const gweet = await db.gweet.findUnique({ // where: { // id: gweetId, // }, // include: { // author: { // select: { // id: true, // username: true, // name: true, // image: true, // }, // }, // likes: true, // media: true, // regweets: true, // quote: { // include: { // author: true, // media: true, // }, // }, // allComments: true, // allQuotes: true, // }, // }) // thread.push(gweet) // if (gweet?.replyToGweetId) { // const replyToGweet = await fetchThread(gweet.replyToGweetId) // thread.unshift(...replyToGweet) // } // return thread // }