aboutsummaryrefslogtreecommitdiffstats
path: root/packages/web/lib
diff options
context:
space:
mode:
authorMohamedBassem <me@mbassem.com>2024-02-11 14:54:52 +0000
committerMohamedBassem <me@mbassem.com>2024-02-11 14:55:09 +0000
commit2c2d05fd0a2c3c26d765f8a6beb88d907a097c1d (patch)
treec4738ba0bc011d60361f89aca9be3293474ab9e9 /packages/web/lib
parentc2f1d6d8b8a0f09820153fc736806b147d46abfe (diff)
downloadkarakeep-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.ts91
-rw-r--r--packages/web/lib/auth.ts25
-rw-r--r--packages/web/lib/config.ts22
-rw-r--r--packages/web/lib/services/bookmarks.ts121
-rw-r--r--packages/web/lib/trpc.tsx20
-rw-r--r--packages/web/lib/types/api/bookmarks.ts1
-rw-r--r--packages/web/lib/types/next-auth.d.ts12
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"];
- }
-}