diff options
| author | MohamedBassem <me@mbassem.com> | 2024-02-11 14:54:52 +0000 |
|---|---|---|
| committer | MohamedBassem <me@mbassem.com> | 2024-02-11 14:55:09 +0000 |
| commit | 2c2d05fd0a2c3c26d765f8a6beb88d907a097c1d (patch) | |
| tree | c4738ba0bc011d60361f89aca9be3293474ab9e9 /packages/web/lib | |
| parent | c2f1d6d8b8a0f09820153fc736806b147d46abfe (diff) | |
| download | karakeep-2c2d05fd0a2c3c26d765f8a6beb88d907a097c1d.tar.zst | |
refactor: Migrating to trpc instead of next's route handers
Diffstat (limited to 'packages/web/lib')
| -rw-r--r-- | packages/web/lib/api.ts | 91 | ||||
| -rw-r--r-- | packages/web/lib/auth.ts | 25 | ||||
| -rw-r--r-- | packages/web/lib/config.ts | 22 | ||||
| -rw-r--r-- | packages/web/lib/services/bookmarks.ts | 121 | ||||
| -rw-r--r-- | packages/web/lib/trpc.tsx | 20 | ||||
| -rw-r--r-- | packages/web/lib/types/api/bookmarks.ts | 1 | ||||
| -rw-r--r-- | packages/web/lib/types/next-auth.d.ts | 12 |
7 files changed, 21 insertions, 271 deletions
diff --git a/packages/web/lib/api.ts b/packages/web/lib/api.ts deleted file mode 100644 index 3978dcb6..00000000 --- a/packages/web/lib/api.ts +++ /dev/null @@ -1,91 +0,0 @@ -"use client"; - -import { ZodTypeAny, z } from "zod"; -import { - ZNewBookmarkRequest, - ZUpdateBookmarksRequest, - zBookmarkSchema, - zGetBookmarksResponseSchema, -} from "./types/api/bookmarks"; - -import serverConfig from "./config"; - -const BASE_URL = `${serverConfig.api_url}/api/v1`; - -export type FetchError = { - status?: number; - message?: string; -}; - -type InputSchema<T> = T extends ZodTypeAny ? T : undefined; - -async function doRequest<T>( - path: string, - respSchema?: InputSchema<T>, - opts?: RequestInit, -): Promise< - | (InputSchema<T> extends ZodTypeAny - ? [z.infer<InputSchema<T>>, undefined] - : [undefined, undefined]) - | [undefined, FetchError] -> { - try { - const res = await fetch(`${BASE_URL}${path}`, opts); - if (!res.ok) { - return [ - undefined, - { status: res.status, message: await res.text() }, - ] as const; - } - if (!respSchema) { - return [undefined, undefined] as const; - } - - const parsed = respSchema.safeParse(await res.json()); - if (!parsed.success) { - return [ - undefined, - { message: `Failed to parse response: ${parsed.error.toString()}` }, - ] as const; - } - - return [parsed.data, undefined] as const; - } catch (error) { - return [ - undefined, - { message: `Failed to execute fetch request: ${error}` }, - ] as const; - } -} - -export default class APIClient { - static async getBookmarks() { - return await doRequest(`/bookmarks`, zGetBookmarksResponseSchema, { - next: { tags: ["links"] }, - }); - } - - static async bookmarkLink(url: string) { - const body: ZNewBookmarkRequest = { - type: "link", - url, - }; - return await doRequest(`/bookmarks`, undefined, { - method: "POST", - body: JSON.stringify(body), - }); - } - - static async deleteBookmark(id: string) { - return await doRequest(`/bookmarks/${id}`, undefined, { - method: "DELETE", - }); - } - - static async updateBookmark(id: string, update: ZUpdateBookmarksRequest) { - return await doRequest(`/bookmarks/${id}`, zBookmarkSchema, { - method: "PATCH", - body: JSON.stringify(update), - }); - } -} diff --git a/packages/web/lib/auth.ts b/packages/web/lib/auth.ts deleted file mode 100644 index df98e6b8..00000000 --- a/packages/web/lib/auth.ts +++ /dev/null @@ -1,25 +0,0 @@ -import NextAuth, { NextAuthOptions } from "next-auth"; -import { PrismaAdapter } from "@next-auth/prisma-adapter"; -import AuthentikProvider from "next-auth/providers/authentik"; -import serverConfig from "@/lib/config"; -import prisma from "@remember/db"; - -const providers = []; - -if (serverConfig.auth.authentik) { - providers.push(AuthentikProvider(serverConfig.auth.authentik)); -} - -export const authOptions: NextAuthOptions = { - // Configure one or more authentication providers - adapter: PrismaAdapter(prisma), - providers: providers, - callbacks: { - session({ session, user }) { - session.user = { ...user }; - return session; - }, - }, -}; - -export const authHandler = NextAuth(authOptions); diff --git a/packages/web/lib/config.ts b/packages/web/lib/config.ts deleted file mode 100644 index dbf6620e..00000000 --- a/packages/web/lib/config.ts +++ /dev/null @@ -1,22 +0,0 @@ -function buildAuthentikConfig() { - const { AUTHENTIK_ID, AUTHENTIK_SECRET, AUTHENTIK_ISSUER } = process.env; - - if (!AUTHENTIK_ID || !AUTHENTIK_SECRET || !AUTHENTIK_ISSUER) { - return undefined; - } - - return { - clientId: AUTHENTIK_ID, - clientSecret: AUTHENTIK_SECRET, - issuer: AUTHENTIK_ISSUER, - }; -} - -const serverConfig = { - api_url: process.env.API_URL || "http://localhost:3000", - auth: { - authentik: buildAuthentikConfig(), - }, -}; - -export default serverConfig; diff --git a/packages/web/lib/services/bookmarks.ts b/packages/web/lib/services/bookmarks.ts deleted file mode 100644 index 82bfec49..00000000 --- a/packages/web/lib/services/bookmarks.ts +++ /dev/null @@ -1,121 +0,0 @@ -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); -} diff --git a/packages/web/lib/trpc.tsx b/packages/web/lib/trpc.tsx new file mode 100644 index 00000000..540c6ab5 --- /dev/null +++ b/packages/web/lib/trpc.tsx @@ -0,0 +1,20 @@ +"use client"; +import { httpBatchLink } from "@trpc/client"; +import type { AppRouter } from "@/server/api/routers/_app"; + +import { loggerLink } from "@trpc/client"; +import { createTRPCClient } from "@trpc/client"; + +export const api = createTRPCClient<AppRouter>({ + links: [ + loggerLink({ + enabled: (op) => + process.env.NODE_ENV === "development" || + (op.direction === "down" && op.result instanceof Error), + }), + httpBatchLink({ + // TODO: Change this to be a full URL exposed as a client side setting + url: `/api/trpc`, + }), + ], +}); diff --git a/packages/web/lib/types/api/bookmarks.ts b/packages/web/lib/types/api/bookmarks.ts index e37d14fb..3d70f868 100644 --- a/packages/web/lib/types/api/bookmarks.ts +++ b/packages/web/lib/types/api/bookmarks.ts @@ -45,6 +45,7 @@ export type ZGetBookmarksResponse = z.infer<typeof zGetBookmarksResponseSchema>; // PATCH /v1/bookmarks/[bookmarkId] export const zUpdateBookmarksRequestSchema = z.object({ + bookmarkId: z.string(), archived: z.boolean().optional(), favourited: z.boolean().optional(), }); diff --git a/packages/web/lib/types/next-auth.d.ts b/packages/web/lib/types/next-auth.d.ts deleted file mode 100644 index cd47dfce..00000000 --- a/packages/web/lib/types/next-auth.d.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { DefaultSession } from "next-auth"; - -declare module "next-auth" { - /** - * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context - */ - export interface Session { - user: { - id: string; - } & DefaultSession["user"]; - } -} |
