aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMohamed Bassem <me@mbassem.com>2024-10-20 14:58:16 +0000
committerMohamed Bassem <me@mbassem.com>2024-10-20 14:58:16 +0000
commit10dcf2e7429601fcbde42e3d10c46c074dc9a28a (patch)
treefcbdbc9abc596fc4e82b26a76294c522394ae448
parentf5fd3c48b7f3de18bcacd584c8d816250fbcad19 (diff)
downloadkarakeep-10dcf2e7429601fcbde42e3d10c46c074dc9a28a.tar.zst
feature: Add APIs to create new lists and bookmarks
-rw-r--r--apps/web/app/api/v1/bookmarks/route.ts12
-rw-r--r--apps/web/app/api/v1/lists/route.ts12
-rw-r--r--packages/shared/types/lists.ts9
-rw-r--r--packages/trpc/routers/lists.ts14
4 files changed, 37 insertions, 10 deletions
diff --git a/apps/web/app/api/v1/bookmarks/route.ts b/apps/web/app/api/v1/bookmarks/route.ts
index 0d58901d..1342f070 100644
--- a/apps/web/app/api/v1/bookmarks/route.ts
+++ b/apps/web/app/api/v1/bookmarks/route.ts
@@ -1,6 +1,8 @@
import { NextRequest } from "next/server";
import { z } from "zod";
+import { zNewBookmarkRequestSchema } from "@hoarder/shared/types/bookmarks";
+
import { buildHandler } from "../utils/handler";
import { adaptPagination, zPagination } from "../utils/pagination";
import { zStringBool } from "../utils/types";
@@ -23,3 +25,13 @@ export const GET = (req: NextRequest) =>
return { status: 200, resp: adaptPagination(bookmarks) };
},
});
+
+export const POST = (req: NextRequest) =>
+ buildHandler({
+ req,
+ bodySchema: zNewBookmarkRequestSchema,
+ handler: async ({ api, body }) => {
+ const bookmark = await api.bookmarks.createBookmark(body!);
+ return { status: 201, resp: bookmark };
+ },
+ });
diff --git a/apps/web/app/api/v1/lists/route.ts b/apps/web/app/api/v1/lists/route.ts
index f2816219..724fadf2 100644
--- a/apps/web/app/api/v1/lists/route.ts
+++ b/apps/web/app/api/v1/lists/route.ts
@@ -1,5 +1,7 @@
import { NextRequest } from "next/server";
+import { zNewBookmarkListSchema } from "@hoarder/shared/types/lists";
+
import { buildHandler } from "../utils/handler";
export const dynamic = "force-dynamic";
@@ -12,3 +14,13 @@ export const GET = (req: NextRequest) =>
return { status: 200, resp: lists };
},
});
+
+export const POST = (req: NextRequest) =>
+ buildHandler({
+ req,
+ bodySchema: zNewBookmarkListSchema,
+ handler: async ({ api, body }) => {
+ const list = await api.lists.create(body!);
+ return { status: 201, resp: list };
+ },
+ });
diff --git a/packages/shared/types/lists.ts b/packages/shared/types/lists.ts
index e9d7eca0..d2041907 100644
--- a/packages/shared/types/lists.ts
+++ b/packages/shared/types/lists.ts
@@ -1,5 +1,14 @@
import { z } from "zod";
+export const zNewBookmarkListSchema = z.object({
+ name: z
+ .string()
+ .min(1, "List name can't be empty")
+ .max(40, "List name is at most 40 chars"),
+ icon: z.string(),
+ parentId: z.string().nullish(),
+});
+
export const zBookmarkListSchema = z.object({
id: z.string(),
name: z.string(),
diff --git a/packages/trpc/routers/lists.ts b/packages/trpc/routers/lists.ts
index a69d1f24..0cc937b1 100644
--- a/packages/trpc/routers/lists.ts
+++ b/packages/trpc/routers/lists.ts
@@ -5,21 +5,15 @@ import { z } from "zod";
import { SqliteError } from "@hoarder/db";
import { bookmarkLists, bookmarksInLists } from "@hoarder/db/schema";
-import { zBookmarkListSchema } from "@hoarder/shared/types/lists";
+import {
+ zBookmarkListSchema,
+ zNewBookmarkListSchema,
+} from "@hoarder/shared/types/lists";
import type { Context } from "../index";
import { authedProcedure, router } from "../index";
import { ensureBookmarkOwnership } from "./bookmarks";
-const zNewBookmarkListSchema = z.object({
- name: z
- .string()
- .min(1, "List name can't be empty")
- .max(40, "List name is at most 40 chars"),
- icon: z.string(),
- parentId: z.string().nullish(),
-});
-
export const ensureListOwnership = experimental_trpcMiddleware<{
ctx: Context;
input: { listId: string };