Files
lti-web-client/src/services/http/client.ts
T

79 lines
2.1 KiB
TypeScript

import axios from 'axios';
import type { AxiosError, AxiosRequestConfig } from 'axios';
import { RequestOptions } from '@/services/http/base';
const BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? '';
const axiosClient = axios.create({ baseURL: BASE_URL, timeout: 10_000 });
axiosClient.interceptors.response.use(
(response) => response,
(error: AxiosError) => {
if (error.response?.status === 401) {
const ssoLoginUrl = `${process.env.NEXT_PUBLIC_SSO_LOGIN_URL as string}?redirect_url=${window.location.href}`;
window.location.href = ssoLoginUrl;
}
return Promise.reject(error);
}
);
export async function httpClient<T, B = unknown>(
path: string,
opts: RequestOptions<B> = {}
): Promise<T> {
const isCookieAuth =
opts.auth === 'cookie' ||
(!opts.auth && opts.auth !== 'none' && opts.auth !== 'bearer');
const isBearerAuth = opts.auth === 'bearer' && !!opts.token;
const isFormData =
typeof FormData !== 'undefined' && opts.body instanceof FormData;
const config: AxiosRequestConfig = {
url: path,
method: opts.method ?? 'GET',
params: opts.query,
data: opts.body,
timeout: opts.timeoutMs ?? 10_000,
withCredentials: isCookieAuth && !isBearerAuth,
headers: {
...(isFormData ? {} : { 'Content-Type': 'application/json' }),
...(opts.headers ?? {}),
...(isBearerAuth && !isCookieAuth
? { Authorization: `Bearer ${opts.token}` }
: {}),
},
};
try {
const res = await axiosClient.request<T>(config);
return res.data;
} catch (e: unknown) {
throw e;
}
}
export type SWRHttpKey<B = unknown> =
| string
| [path: string, opts?: RequestOptions<B>]
| { path: string; opts?: RequestOptions<B> };
export async function httpClientFetcher<T = unknown, B = unknown>(
key: SWRHttpKey<B>
): Promise<T> {
if (!key) throw new Error('Invalid SWR key');
let path: string;
let opts: RequestOptions<B> | undefined;
if (typeof key === 'string') {
path = key;
} else if (Array.isArray(key)) {
[path, opts] = key;
} else {
({ path, opts } = key);
}
return httpClient<T, B>(path, opts);
}