83 lines
2.4 KiB
TypeScript
83 lines
2.4 KiB
TypeScript
import type { Cookies, ServerLoadEvent } from "@sveltejs/kit";
|
|
|
|
export type FetchOptions = {
|
|
fetchFn?: typeof fetch;
|
|
token?: string;
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
data?: any;
|
|
version?: number;
|
|
extraHeaders?: Record<string, string>;
|
|
};
|
|
|
|
/**
|
|
* Fetch a path from the API and parse the response.
|
|
* To make sure the request is authenticated in load functions,
|
|
* pass `fetch` from the request object into opts.
|
|
*
|
|
* @param method The HTTP method, i.e. GET, POST, PATCH
|
|
* @param path The path to request, minus the leading `/api/v2`
|
|
* @param opts Extra options for this request
|
|
* @returns T
|
|
* @throws APIError
|
|
*/
|
|
export default async function request<T>(
|
|
method: string,
|
|
path: string,
|
|
opts: FetchOptions = {},
|
|
): Promise<T> {
|
|
const { token, data, version, extraHeaders } = opts;
|
|
const fetchFn = opts.fetchFn ?? fetch;
|
|
|
|
const resp = await fetchFn(`/api/v${version ?? 2}${path}`, {
|
|
method,
|
|
body: data ? JSON.stringify(data) : undefined,
|
|
headers: {
|
|
...extraHeaders,
|
|
...(token ? { Authorization: token } : {}),
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
if (resp.status < 200 || resp.status >= 400) throw await resp.json();
|
|
return (await resp.json()) as T;
|
|
}
|
|
|
|
/**
|
|
* Fetch a path from the API and discard the response.
|
|
* To make sure the request is authenticated in load functions,
|
|
* pass `fetch` from the request object into opts.
|
|
*
|
|
* @param method The HTTP method, i.e. GET, POST, PATCH
|
|
* @param path The path to request, minus the leading `/api/v2`
|
|
* @param opts Extra options for this request
|
|
* @throws APIError
|
|
*/
|
|
export async function fastRequest(
|
|
method: string,
|
|
path: string,
|
|
opts: FetchOptions = {},
|
|
): Promise<void> {
|
|
const { token, data, version, extraHeaders } = opts;
|
|
const fetchFn = opts.fetchFn ?? fetch;
|
|
|
|
const resp = await fetchFn(`/api/v2${version ?? 2}${path}`, {
|
|
method,
|
|
body: data ? JSON.stringify(data) : undefined,
|
|
headers: {
|
|
...extraHeaders,
|
|
...(token ? { Authorization: token } : {}),
|
|
"Content-Type": "application/json",
|
|
},
|
|
});
|
|
|
|
if (resp.status < 200 || resp.status >= 400) throw await resp.json();
|
|
}
|
|
|
|
/**
|
|
* Helper function to get a token from a request cookie.
|
|
* Accepts both a cookie object ({ cookies }) or a request object (req).
|
|
* @param s A Cookies or ServerLoadEvent object
|
|
* @returns A token, or `undefined` if no token is set.
|
|
*/
|
|
export const getToken = (s: Cookies | ServerLoadEvent) =>
|
|
"cookies" in s ? s.cookies.get("pronounscc-token") : s.get("pronounscc-token");
|