introduce ApiClient
This commit is contained in:
parent
70c79646ae
commit
4672a08462
3 changed files with 90 additions and 54 deletions
70
web/pw-server/src/lib/api_client.ts
Normal file
70
web/pw-server/src/lib/api_client.ts
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
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 {
|
||||||
|
this.fetch_fn = fetch;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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 headers = { "Content-Type": "application/json" };
|
||||||
|
|
||||||
|
if (this.sessionToken) {
|
||||||
|
headers["Authorization"] = `Bearer ${this.sessionToken}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (params) {
|
||||||
|
let searchParams = new URLSearchParams(params);
|
||||||
|
url = `${url}?${searchParams}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const response = await this.fetch_fn(url, {
|
||||||
|
method: "GET",
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
return await this.getJsonResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
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),
|
||||||
|
});
|
||||||
|
|
||||||
|
return await this.getJsonResponse(response);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async getJsonResponse(response: Response): Promise<any> {
|
||||||
|
if (response.ok) {
|
||||||
|
return await response.json();
|
||||||
|
} else {
|
||||||
|
throw new ApiError(response.status, response.statusText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { get_session_token } from "./auth";
|
import { ApiClient, FetchFn } from "./api_client";
|
||||||
|
|
||||||
export function debounce(func: Function, timeout: number = 300) {
|
export function debounce(func: Function, timeout: number = 300) {
|
||||||
let timer: ReturnType<typeof setTimeout>;
|
let timer: ReturnType<typeof setTimeout>;
|
||||||
|
@ -10,35 +10,12 @@ export function debounce(func: Function, timeout: number = 300) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function get(url: string, fetch_fn: Function = fetch) {
|
export async function get(url: string, params?: Record<string, string>, fetch_fn: FetchFn = fetch) {
|
||||||
const headers = { "Content-Type": "application/json" };
|
const client = new ApiClient(fetch_fn);
|
||||||
|
return await client.get(url, params);
|
||||||
const token = get_session_token();
|
|
||||||
if (token) {
|
|
||||||
headers["Authorization"] = `Bearer ${token}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch_fn(url, {
|
|
||||||
method: "GET",
|
|
||||||
headers,
|
|
||||||
});
|
|
||||||
|
|
||||||
return JSON.parse(response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function post(url: string, data: any, fetch_fn: Function = fetch) {
|
export async function post(url: string, data: any, fetch_fn: FetchFn = fetch) {
|
||||||
const headers = { "Content-Type": "application/json" };
|
const client = new ApiClient(fetch_fn);
|
||||||
|
return await client.post(url, data);
|
||||||
const token = get_session_token();
|
|
||||||
if (token) {
|
|
||||||
headers["Authorization"] = `Bearer ${token}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const response = await fetch_fn(url, {
|
|
||||||
method: "POST",
|
|
||||||
headers,
|
|
||||||
body: JSON.stringify(data),
|
|
||||||
});
|
|
||||||
|
|
||||||
return JSON.parse(response);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,16 @@
|
||||||
<script lang="ts" context="module">
|
<script lang="ts" context="module">
|
||||||
import { get_session_token } from "$lib/auth";
|
import { ApiClient } from "$lib/api_client";
|
||||||
|
|
||||||
export async function load({ params, fetch }) {
|
export async function load({ params, fetch }) {
|
||||||
const token = get_session_token();
|
const apiClient = new ApiClient(fetch);
|
||||||
const res = await fetch(`/api/bots/${params["bot_name"]}`, {
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const matches_res = await fetch(`/api/matches?bot=${params["bot_name"]}`, {
|
try {
|
||||||
headers: {
|
const [botData, matches] = await Promise.all([
|
||||||
"Content-Type": "application/json",
|
apiClient.get(`/api/bots/${params["bot_name"]}`),
|
||||||
Authorization: `Bearer ${token}`,
|
apiClient.get("/api/matches", { bot: params["bot_name"] }),
|
||||||
},
|
]);
|
||||||
});
|
|
||||||
|
|
||||||
|
const { bot, owner, versions } = botData;
|
||||||
if (res.ok && matches_res.ok) {
|
|
||||||
const { bot, owner, versions } = await res.json();
|
|
||||||
const matches = await matches_res.json();
|
|
||||||
// sort most recent first
|
|
||||||
versions.sort((a: string, b: string) =>
|
versions.sort((a: string, b: string) =>
|
||||||
dayjs(a["created_at"]).isAfter(b["created_at"]) ? -1 : 1
|
dayjs(a["created_at"]).isAfter(b["created_at"]) ? -1 : 1
|
||||||
);
|
);
|
||||||
|
@ -33,12 +22,12 @@
|
||||||
matches,
|
matches,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
} catch (error) {
|
||||||
|
return {
|
||||||
|
status: error.status,
|
||||||
|
error: error,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
|
||||||
status: res.status,
|
|
||||||
error: new Error("Could not find bot"),
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue