From daebbf0154a290fb690ed94fca23377e0f739f53 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Wed, 7 Feb 2024 02:48:38 +0000 Subject: [ui] Very first draft of the link grid --- web/lib/api.ts | 87 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 web/lib/api.ts (limited to 'web/lib/api.ts') diff --git a/web/lib/api.ts b/web/lib/api.ts new file mode 100644 index 00000000..193d9bb7 --- /dev/null +++ b/web/lib/api.ts @@ -0,0 +1,87 @@ +"use client"; + +import { ZodTypeAny, z } from "zod"; +import { + ZNewBookmarkedLinkRequest, + zGetLinksResponseSchema, +} from "./types/api/links"; + +import serverConfig from "./config"; + +const BASE_URL = `${serverConfig.api_url}/api/v1`; + +export type FetchError = { + status?: number; + message?: string; +}; + +async function doRequest( + _path: string, + respSchema: Schema, + _opts: RequestInit | undefined, +): Promise<[z.infer, undefined] | [undefined, FetchError]>; + +async function doRequest<_Schema>( + _path: string, + _respSchema: undefined, + _opts: RequestInit | undefined, +): Promise<[undefined, undefined] | [undefined, FetchError]>; + +type InputSchema = T extends ZodTypeAny ? T : undefined; + +async function doRequest( + path: string, + respSchema?: InputSchema, + opts?: RequestInit, +): Promise< + | (InputSchema extends ZodTypeAny + ? [z.infer>, 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; + } + + let 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: any) { + return [ + undefined, + { message: `Failed to execute fetch request: ${error}` }, + ] as const; + } +} + +export default class APIClient { + static async getLinks() { + return await doRequest(`/links`, zGetLinksResponseSchema, { + next: { tags: ["links"] }, + }); + } + + static async bookmarkLink(url: string) { + const body: ZNewBookmarkedLinkRequest = { + url, + }; + return await doRequest(`/links`, undefined, { + method: "POST", + body: JSON.stringify(body), + }); + } +} -- cgit v1.2.3-70-g09d2