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