| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- import { QueryClient } from "@tanstack/react-query";
- import { camelizeKeys, decamelize, decamelizeKeys } from "humps";
- import queryString, { type StringifiableRecord } from "query-string";
- import AuthStore from "src/modules/AuthStore";
- const queryClient = new QueryClient();
- const contentTypeHeader = "Content-Type";
- interface BuildUrlArgs {
- url: string;
- params?: StringifiableRecord;
- }
- function decamelizeParams(params?: StringifiableRecord): StringifiableRecord | undefined {
- if (!params) {
- return undefined;
- }
- const result: StringifiableRecord = {};
- for (const [key, value] of Object.entries(params)) {
- result[decamelize(key)] = value;
- }
- return result;
- }
- function buildUrl({ url, params }: BuildUrlArgs) {
- const endpoint = url.replace(/^\/|\/$/g, "");
- const baseUrl = `/api/${endpoint}`;
- const apiUrl = queryString.stringifyUrl({
- url: baseUrl,
- query: decamelizeParams(params),
- });
- return apiUrl;
- }
- function buildAuthHeader(): Record<string, string> | undefined {
- if (AuthStore.token) {
- return { Authorization: `Bearer ${AuthStore.token.token}` };
- }
- return {};
- }
- function buildBody(data?: Record<string, any>): string | undefined {
- if (data) {
- return JSON.stringify(decamelizeKeys(data));
- }
- }
- async function processResponse(response: Response) {
- const payload = await response.json();
- if (!response.ok) {
- if (response.status === 401) {
- // Force logout user and reload the page if Unauthorized
- AuthStore.clear();
- queryClient.clear();
- window.location.reload();
- }
- throw new Error(
- typeof payload.error.messageI18n !== "undefined" ? payload.error.messageI18n : payload.error.message,
- );
- }
- return camelizeKeys(payload) as any;
- }
- interface GetArgs {
- url: string;
- params?: queryString.StringifiableRecord;
- }
- async function baseGet({ url, params }: GetArgs, abortController?: AbortController) {
- const apiUrl = buildUrl({ url, params });
- const method = "GET";
- const headers = buildAuthHeader();
- const signal = abortController?.signal;
- const response = await fetch(apiUrl, { method, headers, signal });
- return response;
- }
- export async function get(args: GetArgs, abortController?: AbortController) {
- return processResponse(await baseGet(args, abortController));
- }
- export async function download(args: GetArgs, abortController?: AbortController) {
- return (await baseGet(args, abortController)).text();
- }
- interface PostArgs {
- url: string;
- params?: queryString.StringifiableRecord;
- data?: any;
- noAuth?: boolean;
- }
- export async function post({ url, params, data, noAuth }: PostArgs, abortController?: AbortController) {
- const apiUrl = buildUrl({ url, params });
- const method = "POST";
- let headers: Record<string, string> = {};
- if (!noAuth) {
- headers = {
- ...buildAuthHeader(),
- };
- }
- let body: string | FormData | undefined;
- // Check if the data is an instance of FormData
- // If data is FormData, let the browser set the Content-Type header
- if (data instanceof FormData) {
- body = data;
- } else {
- // If data is JSON, set the Content-Type header to 'application/json'
- headers = {
- ...headers,
- [contentTypeHeader]: "application/json",
- };
- body = buildBody(data);
- }
- const signal = abortController?.signal;
- const response = await fetch(apiUrl, { method, headers, body, signal });
- return processResponse(response);
- }
- interface PutArgs {
- url: string;
- params?: queryString.StringifiableRecord;
- data?: Record<string, unknown>;
- }
- export async function put({ url, params, data }: PutArgs, abortController?: AbortController) {
- const apiUrl = buildUrl({ url, params });
- const method = "PUT";
- const headers = {
- ...buildAuthHeader(),
- [contentTypeHeader]: "application/json",
- };
- const signal = abortController?.signal;
- const body = buildBody(data);
- const response = await fetch(apiUrl, { method, headers, body, signal });
- return processResponse(response);
- }
- interface DeleteArgs {
- url: string;
- params?: queryString.StringifiableRecord;
- }
- export async function del({ url, params }: DeleteArgs, abortController?: AbortController) {
- const apiUrl = buildUrl({ url, params });
- const method = "DELETE";
- const headers = {
- ...buildAuthHeader(),
- [contentTypeHeader]: "application/json",
- };
- const signal = abortController?.signal;
- const response = await fetch(apiUrl, { method, headers, signal });
- return processResponse(response);
- }
|