aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2024-10-20 15:54:34 +0000
committerMohamed Bassem <me@mbassem.com>2024-10-20 15:54:34 +0000
commite89a38680532c3ab72ef26dfe88bb64476b709ab (patch)
tree2ec336dc4bd8cd18043739bd603677d60ad70da1
parent20e5225e0547978cab656e94a3519cd590a16d8a (diff)
downloadkarakeep-e89a38680532c3ab72ef26dfe88bb64476b709ab.tar.zst
feature(api): Add REST APIs to update bookmarks, tags and lists
-rw-r--r--apps/web/app/api/v1/bookmarks/[bookmarkId]/route.ts18
-rw-r--r--apps/web/app/api/v1/lists/[listId]/route.ts18
-rw-r--r--apps/web/app/api/v1/tags/[tagId]/route.ts18
-rw-r--r--packages/shared/types/tags.ts5
-rw-r--r--packages/trpc/routers/tags.ts12
5 files changed, 64 insertions, 7 deletions
diff --git a/apps/web/app/api/v1/bookmarks/[bookmarkId]/route.ts b/apps/web/app/api/v1/bookmarks/[bookmarkId]/route.ts
index 0315ff8c..8fe4d9fe 100644
--- a/apps/web/app/api/v1/bookmarks/[bookmarkId]/route.ts
+++ b/apps/web/app/api/v1/bookmarks/[bookmarkId]/route.ts
@@ -1,6 +1,8 @@
import { NextRequest } from "next/server";
import { buildHandler } from "@/app/api/v1/utils/handler";
+import { zUpdateBookmarksRequestSchema } from "@hoarder/shared/types/bookmarks";
+
export const dynamic = "force-dynamic";
export const GET = (
@@ -17,6 +19,22 @@ export const GET = (
},
});
+export const PATCH = (
+ req: NextRequest,
+ { params }: { params: { bookmarkId: string } },
+) =>
+ buildHandler({
+ req,
+ bodySchema: zUpdateBookmarksRequestSchema.omit({ bookmarkId: true }),
+ handler: async ({ api, body }) => {
+ const bookmark = await api.bookmarks.updateBookmark({
+ bookmarkId: params.bookmarkId,
+ ...body!,
+ });
+ return { status: 200, resp: bookmark };
+ },
+ });
+
export const DELETE = (
req: NextRequest,
{ params }: { params: { bookmarkId: string } },
diff --git a/apps/web/app/api/v1/lists/[listId]/route.ts b/apps/web/app/api/v1/lists/[listId]/route.ts
index f5af286d..69c99fda 100644
--- a/apps/web/app/api/v1/lists/[listId]/route.ts
+++ b/apps/web/app/api/v1/lists/[listId]/route.ts
@@ -1,6 +1,8 @@
import { NextRequest } from "next/server";
import { buildHandler } from "@/app/api/v1/utils/handler";
+import { zNewBookmarkListSchema } from "@hoarder/shared/types/lists";
+
export const dynamic = "force-dynamic";
export const GET = (
@@ -20,6 +22,22 @@ export const GET = (
},
});
+export const PATCH = (
+ req: NextRequest,
+ { params }: { params: { listId: string } },
+) =>
+ buildHandler({
+ req,
+ bodySchema: zNewBookmarkListSchema.partial(),
+ handler: async ({ api, body }) => {
+ const list = await api.lists.edit({
+ listId: params.listId,
+ ...body!,
+ });
+ return { status: 200, resp: list };
+ },
+ });
+
export const DELETE = (
req: NextRequest,
{ params }: { params: { listId: string } },
diff --git a/apps/web/app/api/v1/tags/[tagId]/route.ts b/apps/web/app/api/v1/tags/[tagId]/route.ts
index 439b6149..29b27218 100644
--- a/apps/web/app/api/v1/tags/[tagId]/route.ts
+++ b/apps/web/app/api/v1/tags/[tagId]/route.ts
@@ -1,6 +1,8 @@
import { NextRequest } from "next/server";
import { buildHandler } from "@/app/api/v1/utils/handler";
+import { zUpdateTagRequestSchema } from "@hoarder/shared/types/tags";
+
export const dynamic = "force-dynamic";
export const GET = (
@@ -20,6 +22,22 @@ export const GET = (
},
});
+export const PATCH = (
+ req: NextRequest,
+ { params }: { params: { tagId: string } },
+) =>
+ buildHandler({
+ req,
+ bodySchema: zUpdateTagRequestSchema.omit({ tagId: true }),
+ handler: async ({ api, body }) => {
+ const tag = await api.tags.update({
+ tagId: params.tagId,
+ ...body!,
+ });
+ return { status: 200, resp: tag };
+ },
+ });
+
export const DELETE = (
req: NextRequest,
{ params }: { params: { tagId: string } },
diff --git a/packages/shared/types/tags.ts b/packages/shared/types/tags.ts
index c9fe2a93..7828c645 100644
--- a/packages/shared/types/tags.ts
+++ b/packages/shared/types/tags.ts
@@ -16,3 +16,8 @@ export const zGetTagResponseSchema = z.object({
countAttachedBy: z.record(zAttachedByEnumSchema, z.number()),
});
export type ZGetTagResponse = z.infer<typeof zGetTagResponseSchema>;
+
+export const zUpdateTagRequestSchema = z.object({
+ tagId: z.string(),
+ name: z.string().optional(),
+});
diff --git a/packages/trpc/routers/tags.ts b/packages/trpc/routers/tags.ts
index a5d93213..c04593c9 100644
--- a/packages/trpc/routers/tags.ts
+++ b/packages/trpc/routers/tags.ts
@@ -6,7 +6,10 @@ import type { ZAttachedByEnum } from "@hoarder/shared/types/tags";
import { SqliteError } from "@hoarder/db";
import { bookmarkTags, tagsOnBookmarks } from "@hoarder/db/schema";
import { triggerSearchReindex } from "@hoarder/shared/queues";
-import { zGetTagResponseSchema } from "@hoarder/shared/types/tags";
+import {
+ zGetTagResponseSchema,
+ zUpdateTagRequestSchema,
+} from "@hoarder/shared/types/tags";
import type { Context } from "../index";
import { authedProcedure, router } from "../index";
@@ -150,12 +153,7 @@ export const tagsAppRouter = router({
return { deletedTags: res.changes };
}),
update: authedProcedure
- .input(
- z.object({
- tagId: z.string(),
- name: z.string().optional(),
- }),
- )
+ .input(zUpdateTagRequestSchema)
.output(
z.object({
id: z.string(),