aboutsummaryrefslogtreecommitdiffstats
path: root/packages/web/server/api/routers/bookmarks.ts
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-02-11 14:54:52 +0000
committerMohamedBassem <me@mbassem.com>2024-02-11 14:55:09 +0000
commit2c2d05fd0a2c3c26d765f8a6beb88d907a097c1d (patch)
treec4738ba0bc011d60361f89aca9be3293474ab9e9 /packages/web/server/api/routers/bookmarks.ts
parentc2f1d6d8b8a0f09820153fc736806b147d46abfe (diff)
downloadkarakeep-2c2d05fd0a2c3c26d765f8a6beb88d907a097c1d.tar.zst
refactor: Migrating to trpc instead of next's route handers
Diffstat (limited to 'packages/web/server/api/routers/bookmarks.ts')
-rw-r--r--packages/web/server/api/routers/bookmarks.ts139
1 files changed, 139 insertions, 0 deletions
diff --git a/packages/web/server/api/routers/bookmarks.ts b/packages/web/server/api/routers/bookmarks.ts
new file mode 100644
index 00000000..0b97563f
--- /dev/null
+++ b/packages/web/server/api/routers/bookmarks.ts
@@ -0,0 +1,139 @@
+import { z } from "zod";
+import { authedProcedure, router } from "../trpc";
+import {
+ ZBookmark,
+ ZBookmarkContent,
+ zBookmarkSchema,
+ zGetBookmarksRequestSchema,
+ zGetBookmarksResponseSchema,
+ zNewBookmarkRequestSchema,
+ zUpdateBookmarksRequestSchema,
+} from "@/lib/types/api/bookmarks";
+import { prisma } from "@remember/db";
+import { LinkCrawlerQueue } from "@remember/shared/queues";
+
+const defaultBookmarkFields = {
+ id: true,
+ favourited: true,
+ archived: true,
+ createdAt: true,
+ link: {
+ select: {
+ url: true,
+ title: true,
+ description: true,
+ imageUrl: true,
+ favicon: true,
+ },
+ },
+ tags: {
+ include: {
+ tag: true,
+ },
+ },
+};
+
+async function dummyPrismaReturnType() {
+ const x = await prisma.bookmark.findFirstOrThrow({
+ select: defaultBookmarkFields,
+ });
+ return x;
+}
+
+function toZodSchema(
+ bookmark: Awaited<ReturnType<typeof dummyPrismaReturnType>>,
+): ZBookmark {
+ const { tags, link, ...rest } = bookmark;
+
+ let content: ZBookmarkContent;
+ if (link) {
+ content = { type: "link", ...link };
+ } else {
+ throw new Error("Unknown content type");
+ }
+
+ return {
+ tags: tags.map((t) => t.tag),
+ content,
+ ...rest,
+ };
+}
+
+export const bookmarksAppRouter = router({
+ bookmarkLink: authedProcedure
+ .input(zNewBookmarkRequestSchema)
+ .output(zBookmarkSchema)
+ .mutation(async ({ input, ctx }) => {
+ const { url } = input;
+ const userId = ctx.user.id;
+
+ const bookmark = await prisma.bookmark.create({
+ data: {
+ link: {
+ create: {
+ url,
+ },
+ },
+ userId,
+ },
+ select: defaultBookmarkFields,
+ });
+
+ // Enqueue crawling request
+ await LinkCrawlerQueue.add("crawl", {
+ bookmarkId: bookmark.id,
+ url: url,
+ });
+
+ return toZodSchema(bookmark);
+ }),
+
+ updateBookmark: authedProcedure
+ .input(zUpdateBookmarksRequestSchema)
+ .output(zBookmarkSchema)
+ .mutation(async ({ input, ctx }) => {
+ const bookmark = await prisma.bookmark.update({
+ where: {
+ id: input.bookmarkId,
+ userId: ctx.user.id,
+ },
+ data: {
+ archived: input.archived,
+ favourited: input.favourited,
+ },
+ select: defaultBookmarkFields,
+ });
+ return toZodSchema(bookmark);
+ }),
+
+ deleteBookmark: authedProcedure
+ .input(z.object({ bookmarkId: z.string() }))
+ .mutation(async ({ input, ctx }) => {
+ await prisma.bookmark.delete({
+ where: {
+ id: input.bookmarkId,
+ userId: ctx.user.id,
+ },
+ });
+ }),
+ getBookmarks: authedProcedure
+ .input(zGetBookmarksRequestSchema)
+ .output(zGetBookmarksResponseSchema)
+ .query(async ({ input, ctx }) => {
+ const bookmarks = (
+ await prisma.bookmark.findMany({
+ where: {
+ userId: ctx.user.id,
+ archived: input.archived,
+ favourited: input.favourited,
+ },
+ orderBy: {
+ createdAt: "desc",
+ },
+ select: defaultBookmarkFields,
+ })
+ ).map(toZodSchema);
+
+ return { bookmarks };
+ }),
+});