aboutsummaryrefslogtreecommitdiff
path: root/web/pw-server/src/lib/api_client.ts
diff options
context:
space:
mode:
Diffstat (limited to 'web/pw-server/src/lib/api_client.ts')
-rw-r--r--web/pw-server/src/lib/api_client.ts80
1 files changed, 80 insertions, 0 deletions
diff --git a/web/pw-server/src/lib/api_client.ts b/web/pw-server/src/lib/api_client.ts
new file mode 100644
index 0000000..706d958
--- /dev/null
+++ b/web/pw-server/src/lib/api_client.ts
@@ -0,0 +1,80 @@
+import { browser } from "$app/env";
+import { get_session_token } from "./auth";
+
+export type FetchFn = (input: RequestInfo, init?: RequestInit) => Promise<Response>;
+
+export class ApiError extends Error {
+ constructor(public status: number, message?: string) {
+ super(message);
+ }
+}
+
+export class ApiClient {
+ private fetch_fn: FetchFn;
+ private sessionToken?: string;
+
+ constructor(fetch_fn?: FetchFn) {
+ if (fetch_fn) {
+ this.fetch_fn = fetch_fn;
+ } else if (browser) {
+ this.fetch_fn = fetch.bind(window);
+ }
+
+ // TODO: maybe it is cleaner to pass this as a parameter
+ this.sessionToken = get_session_token();
+ }
+
+ async get(url: string, params?: Record<string, string>): Promise<any> {
+ const response = await this.getRequest(url, params);
+ this.checkResponse(response);
+ return await response.json();
+ }
+
+ async getText(url: string, params?: Record<string, string>): Promise<any> {
+ const response = await this.getRequest(url, params);
+ this.checkResponse(response);
+ return await response.text();
+ }
+
+ async post(url: string, data: any): Promise<any> {
+ const headers = { "Content-Type": "application/json" };
+
+ const token = get_session_token();
+ if (token) {
+ headers["Authorization"] = `Bearer ${token}`;
+ }
+
+ const response = await this.fetch_fn(url, {
+ method: "POST",
+ headers,
+ body: JSON.stringify(data),
+ });
+
+ this.checkResponse(response);
+ return await response.json();
+ }
+
+ private async getRequest(url: string, params: Record<string, string>): Promise<Response> {
+ const headers = { "Content-Type": "application/json" };
+
+ if (this.sessionToken) {
+ headers["Authorization"] = `Bearer ${this.sessionToken}`;
+ }
+
+ if (params) {
+ let searchParams = new URLSearchParams(params);
+ url = `${url}?${searchParams}`;
+ }
+
+ return await this.fetch_fn(url, {
+ method: "GET",
+ headers,
+ });
+ }
+
+ private checkResponse(response: Response) {
+ if (!response.ok) {
+ throw new ApiError(response.status, response.statusText);
+ }
+ }
+}