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);
}
}
}
|