mirror of
https://github.com/hay-kot/homebox.git
synced 2024-12-27 09:16:30 +00:00
31b34241e0
* change /content/ -> /homebox/ * add cache to code generators * update env variables to set data storage * update env variables * set env variables in prod container * implement attachment post route (WIP) * get attachment endpoint * attachment download * implement string utilities lib * implement generic drop zone * use explicit truncate * remove clean dir * drop strings composable for lib * update item types and add attachments * add attachment API * implement service context * consolidate API code * implement editing attachments * implement upload limit configuration * improve error handling * add docs for max upload size * fix test cases
118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
export enum Method {
|
|
GET = "GET",
|
|
POST = "POST",
|
|
PUT = "PUT",
|
|
DELETE = "DELETE",
|
|
}
|
|
|
|
export type RequestInterceptor = (r: Response) => void;
|
|
export type ResponseInterceptor = (r: Response) => void;
|
|
|
|
export interface TResponse<T> {
|
|
status: number;
|
|
error: boolean;
|
|
data: T;
|
|
response: Response;
|
|
}
|
|
|
|
export type RequestArgs<T> = {
|
|
url: string;
|
|
body?: T;
|
|
data?: FormData;
|
|
headers?: Record<string, string>;
|
|
};
|
|
|
|
export class Requests {
|
|
private baseUrl: string;
|
|
private token: () => string;
|
|
private headers: Record<string, string> = {};
|
|
private responseInterceptors: ResponseInterceptor[] = [];
|
|
|
|
addResponseInterceptor(interceptor: ResponseInterceptor) {
|
|
this.responseInterceptors.push(interceptor);
|
|
}
|
|
|
|
private callResponseInterceptors(response: Response) {
|
|
this.responseInterceptors.forEach(i => i(response));
|
|
}
|
|
|
|
private url(rest: string): string {
|
|
return this.baseUrl + rest;
|
|
}
|
|
|
|
constructor(baseUrl: string, token: string | (() => string) = "", headers: Record<string, string> = {}) {
|
|
this.baseUrl = baseUrl;
|
|
this.token = typeof token === "string" ? () => token : token;
|
|
this.headers = headers;
|
|
}
|
|
|
|
public get<T>(args: RequestArgs<T>): Promise<TResponse<T>> {
|
|
return this.do<T>(Method.GET, args);
|
|
}
|
|
|
|
public post<T, U>(args: RequestArgs<T>): Promise<TResponse<U>> {
|
|
return this.do<U>(Method.POST, args);
|
|
}
|
|
|
|
public put<T, U>(args: RequestArgs<T>): Promise<TResponse<U>> {
|
|
return this.do<U>(Method.PUT, args);
|
|
}
|
|
|
|
public delete<T>(args: RequestArgs<T>): Promise<TResponse<T>> {
|
|
return this.do<T>(Method.DELETE, args);
|
|
}
|
|
|
|
private methodSupportsBody(method: Method): boolean {
|
|
return method === Method.POST || method === Method.PUT;
|
|
}
|
|
|
|
private async do<T>(method: Method, rargs: RequestArgs<unknown>): Promise<TResponse<T>> {
|
|
const payload: RequestInit = {
|
|
method,
|
|
headers: {
|
|
...rargs.headers,
|
|
...this.headers,
|
|
} as Record<string, string>,
|
|
};
|
|
|
|
const token = this.token();
|
|
if (token !== "" && payload.headers !== undefined) {
|
|
payload.headers["Authorization"] = token; // eslint-disable-line dot-notation
|
|
}
|
|
|
|
if (this.methodSupportsBody(method)) {
|
|
if (rargs.data) {
|
|
payload.body = rargs.data;
|
|
} else {
|
|
payload.headers["Content-Type"] = "application/json";
|
|
payload.body = JSON.stringify(rargs.body);
|
|
}
|
|
}
|
|
|
|
const response = await fetch(this.url(rargs.url), payload);
|
|
this.callResponseInterceptors(response);
|
|
|
|
const data: T = await (async () => {
|
|
if (response.status === 204) {
|
|
return {} as T;
|
|
}
|
|
|
|
if (response.headers.get("Content-Type")?.startsWith("application/json")) {
|
|
try {
|
|
return await response.json();
|
|
} catch (e) {
|
|
return {} as T;
|
|
}
|
|
}
|
|
|
|
return response.body as unknown as T;
|
|
})();
|
|
|
|
return {
|
|
status: response.status,
|
|
error: !response.ok,
|
|
data,
|
|
response,
|
|
};
|
|
}
|
|
}
|