aboutsummaryrefslogtreecommitdiff
path: root/web/pw-server/src/lib/api_client.ts
blob: 706d958b316dda893870f238dbb82367d1b6274a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
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);
    }
  }
}