aboutsummaryrefslogtreecommitdiffstats
path: root/packages/web/lib/services/bookmarks.ts
blob: 82bfec49e3888d9010813d01eac29c9bd7b73ba5 (plain) (blame)
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
import { LinkCrawlerQueue } from "@remember/shared/queues";
import prisma from "@remember/db";
import {
  ZBookmark,
  ZBookmarkContent,
  ZGetBookmarksRequest,
  ZUpdateBookmarksRequest,
} from "@/lib/types/api/bookmarks";

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 async function updateBookmark(
  bookmarkId: string,
  userId: string,
  req: ZUpdateBookmarksRequest,
) {
  const bookmark = await prisma.bookmark.update({
    where: {
      id: bookmarkId,
      userId,
    },
    data: req,
    select: defaultBookmarkFields,
  });
  return toZodSchema(bookmark);
}

export async function deleteBookmark(bookmarkId: string, userId: string) {
  await prisma.bookmark.delete({
    where: {
      id: bookmarkId,
      userId,
    },
  });
}

export async function bookmarkLink(url: string, userId: string) {
  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);
}

export async function getBookmarks(
  userId: string,
  { favourited, archived }: ZGetBookmarksRequest,
) {
  return (
    await prisma.bookmark.findMany({
      where: {
        userId,
        archived,
        favourited,
      },
      orderBy: {
        createdAt: 'desc',
      },
      select: defaultBookmarkFields,
    })
  ).map(toZodSchema);
}