diff options
| author | MohamedBassem <me@mbassem.com> | 2024-02-28 20:45:28 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-02-28 20:45:28 +0000 |
| commit | 3208dda3848ad739f54cebf44c423e2b68e85b2d (patch) | |
| tree | 25602c451354a296e8779197fdd42acab7526502 /packages/web/server | |
| parent | 7096fb3941579e5c045796361745d597e03ff7fc (diff) | |
| download | karakeep-3208dda3848ad739f54cebf44c423e2b68e85b2d.tar.zst | |
feature: Add support for storing and previewing raw notes
Diffstat (limited to 'packages/web/server')
| -rw-r--r-- | packages/web/server/api/routers/bookmarks.test.ts | 36 | ||||
| -rw-r--r-- | packages/web/server/api/routers/bookmarks.ts | 89 |
2 files changed, 95 insertions, 30 deletions
diff --git a/packages/web/server/api/routers/bookmarks.test.ts b/packages/web/server/api/routers/bookmarks.test.ts index 16f82992..603a173e 100644 --- a/packages/web/server/api/routers/bookmarks.test.ts +++ b/packages/web/server/api/routers/bookmarks.test.ts @@ -1,17 +1,18 @@ import { CustomTestContext, defaultBeforeEach } from "@/lib/testUtils"; -import { expect, describe, test, beforeEach } from "vitest"; +import { expect, describe, test, beforeEach, assert } from "vitest"; beforeEach<CustomTestContext>(defaultBeforeEach); describe("Bookmark Routes", () => { test<CustomTestContext>("create bookmark", async ({ apiCallers }) => { const api = apiCallers[0].bookmarks; - const bookmark = await api.bookmarkLink({ + const bookmark = await api.createBookmark({ url: "https://google.com", type: "link", }); const res = await api.getBookmark({ bookmarkId: bookmark.id }); + assert(res.content.type == "link"); expect(res.content.url).toEqual("https://google.com"); expect(res.favourited).toEqual(false); expect(res.archived).toEqual(false); @@ -22,7 +23,7 @@ describe("Bookmark Routes", () => { const api = apiCallers[0].bookmarks; // Create the bookmark - const bookmark = await api.bookmarkLink({ + const bookmark = await api.createBookmark({ url: "https://google.com", type: "link", }); @@ -43,7 +44,7 @@ describe("Bookmark Routes", () => { const api = apiCallers[0].bookmarks; // Create the bookmark - const bookmark = await api.bookmarkLink({ + const bookmark = await api.createBookmark({ url: "https://google.com", type: "link", }); @@ -64,12 +65,12 @@ describe("Bookmark Routes", () => { const emptyBookmarks = await api.getBookmarks({}); expect(emptyBookmarks.bookmarks.length).toEqual(0); - const bookmark1 = await api.bookmarkLink({ + const bookmark1 = await api.createBookmark({ url: "https://google.com", type: "link", }); - const bookmark2 = await api.bookmarkLink({ + const bookmark2 = await api.createBookmark({ url: "https://google2.com", type: "link", }); @@ -113,7 +114,7 @@ describe("Bookmark Routes", () => { test<CustomTestContext>("update tags", async ({ apiCallers }) => { const api = apiCallers[0].bookmarks; - let bookmark = await api.bookmarkLink({ + let bookmark = await api.createBookmark({ url: "https://google.com", type: "link", }); @@ -139,12 +140,29 @@ describe("Bookmark Routes", () => { expect(bookmark.tags.map((t) => t.name).sort()).toEqual(["tag2", "tag3"]); }); + test<CustomTestContext>("update bookmark text", async ({ apiCallers }) => { + const api = apiCallers[0].bookmarks; + let bookmark = await api.createBookmark({ + text: "HELLO WORLD", + type: "text", + }); + + await api.updateBookmarkText({ + bookmarkId: bookmark.id, + text: "WORLD HELLO", + }); + + bookmark = await api.getBookmark({ bookmarkId: bookmark.id }); + assert(bookmark.content.type == "text"); + expect(bookmark.content.text).toEqual("WORLD HELLO"); + }); + test<CustomTestContext>("privacy", async ({ apiCallers }) => { - const user1Bookmark = await apiCallers[0].bookmarks.bookmarkLink({ + const user1Bookmark = await apiCallers[0].bookmarks.createBookmark({ type: "link", url: "https://google.com", }); - const user2Bookmark = await apiCallers[1].bookmarks.bookmarkLink({ + const user2Bookmark = await apiCallers[1].bookmarks.createBookmark({ type: "link", url: "https://google.com", }); diff --git a/packages/web/server/api/routers/bookmarks.ts b/packages/web/server/api/routers/bookmarks.ts index 64755e4e..bfa0580f 100644 --- a/packages/web/server/api/routers/bookmarks.ts +++ b/packages/web/server/api/routers/bookmarks.ts @@ -13,6 +13,7 @@ import { import { bookmarkLinks, bookmarkTags, + bookmarkTexts, bookmarks, tagsOnBookmarks, } from "@hoarder/db/schema"; @@ -64,6 +65,7 @@ async function dummyDrizzleReturnType() { }, }, link: true, + text: true, }, }); if (!x) { @@ -75,11 +77,13 @@ async function dummyDrizzleReturnType() { function toZodSchema( bookmark: Awaited<ReturnType<typeof dummyDrizzleReturnType>>, ): ZBookmark { - const { tagsOnBookmarks, link, ...rest } = bookmark; + const { tagsOnBookmarks, link, text, ...rest } = bookmark; let content: ZBookmarkContent; if (link) { content = { type: "link", ...link }; + } else if (text) { + content = { type: "text", text: text.text || "" }; } else { throw new Error("Unknown content type"); } @@ -95,12 +99,10 @@ function toZodSchema( } export const bookmarksAppRouter = router({ - bookmarkLink: authedProcedure + createBookmark: authedProcedure .input(zNewBookmarkRequestSchema) .output(zBookmarkSchema) .mutation(async ({ input, ctx }) => { - const { url } = input; - const bookmark = await ctx.db.transaction( async (tx): Promise<ZBookmark> => { const bookmark = ( @@ -112,20 +114,39 @@ export const bookmarksAppRouter = router({ .returning() )[0]; - const link = ( - await tx - .insert(bookmarkLinks) - .values({ - id: bookmark.id, - url, - }) - .returning() - )[0]; + let content: ZBookmarkContent; - const content: ZBookmarkContent = { - type: "link", - ...link, - }; + switch (input.type) { + case "link": { + const link = ( + await tx + .insert(bookmarkLinks) + .values({ + id: bookmark.id, + url: input.url, + }) + .returning() + )[0]; + content = { + type: "link", + ...link, + }; + break; + } + case "text": { + const text = ( + await tx + .insert(bookmarkTexts) + .values({ id: bookmark.id, text: input.text }) + .returning() + )[0]; + content = { + type: "text", + text: text.text || "", + }; + break; + } + } return { tags: [] as ZBookmarkTags[], @@ -170,6 +191,30 @@ export const bookmarksAppRouter = router({ return res[0]; }), + updateBookmarkText: authedProcedure + .input( + z.object({ + bookmarkId: z.string(), + text: z.string().max(2000), + }), + ) + .use(ensureBookmarkOwnership) + .mutation(async ({ input, ctx }) => { + const res = await ctx.db + .update(bookmarkTexts) + .set({ + text: input.text, + }) + .where(and(eq(bookmarkTexts.id, input.bookmarkId))) + .returning(); + if (res.length == 0) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Bookmark not found", + }); + } + }), + deleteBookmark: authedProcedure .input(z.object({ bookmarkId: z.string() })) .use(ensureBookmarkOwnership) @@ -212,6 +257,7 @@ export const bookmarksAppRouter = router({ }, }, link: true, + text: true, }, }); if (!bookmark) { @@ -246,6 +292,7 @@ export const bookmarksAppRouter = router({ }, }, link: true, + text: true, }, }); @@ -271,7 +318,7 @@ export const bookmarksAppRouter = router({ await ctx.db.transaction(async (tx) => { // Detaches if (input.detach.length > 0) { - await ctx.db.delete(tagsOnBookmarks).where( + await tx.delete(tagsOnBookmarks).where( and( eq(tagsOnBookmarks.bookmarkId, input.bookmarkId), inArray( @@ -295,7 +342,7 @@ export const bookmarksAppRouter = router({ })); if (toBeCreatedTags.length > 0) { - await ctx.db + await tx .insert(bookmarkTags) .values(toBeCreatedTags) .onConflictDoNothing() @@ -303,7 +350,7 @@ export const bookmarksAppRouter = router({ } const allIds = ( - await ctx.db.query.bookmarkTags.findMany({ + await tx.query.bookmarkTags.findMany({ where: and( eq(bookmarkTags.userId, ctx.user.id), inArray( @@ -317,7 +364,7 @@ export const bookmarksAppRouter = router({ }) ).map((t) => t.id); - await ctx.db + await tx .insert(tagsOnBookmarks) .values( allIds.map((i) => ({ |
