119 lines
4.0 KiB
TypeScript
119 lines
4.0 KiB
TypeScript
import type { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse, CreateAxiosDefaults, InternalAxiosRequestConfig } from 'axios';
|
|
|
|
import axios from 'axios';
|
|
|
|
import type { Result } from '@/axios';
|
|
|
|
export type Response<T> = [err: AxiosError | null, data: T | null, resp: Result<T> | null];
|
|
|
|
export interface RequestOptions extends CreateAxiosDefaults {
|
|
requestInterceptor?: (config: InternalAxiosRequestConfig) => InternalAxiosRequestConfig | Promise<InternalAxiosRequestConfig>;
|
|
responseInterceptor?: (resp: AxiosResponse) => AxiosResponse | Promise<AxiosResponse>;
|
|
responseErrorInterceptor?: (error: any) => any;
|
|
}
|
|
|
|
export class RequestClient {
|
|
private instance: AxiosInstance;
|
|
|
|
constructor(config?: RequestOptions) {
|
|
this.instance = axios.create(config);
|
|
|
|
const requestInterceptor = config?.requestInterceptor ?? RequestClient.defaultRequestInterceptor;
|
|
const responseInterceptor = config?.responseInterceptor ?? RequestClient.defaultResponseInterceptor;
|
|
const responseErrorInterceptor = config?.responseErrorInterceptor ?? RequestClient.defaultResponseErrorInterceptor;
|
|
|
|
this.instance.interceptors.request.use(requestInterceptor);
|
|
|
|
this.instance.interceptors.response.use(responseInterceptor, responseErrorInterceptor);
|
|
}
|
|
|
|
private static defaultRequestInterceptor(config: InternalAxiosRequestConfig) {
|
|
return config;
|
|
}
|
|
|
|
private static defaultResponseInterceptor(response: AxiosResponse) {
|
|
return response;
|
|
}
|
|
|
|
private static defaultResponseErrorInterceptor(error: any) {
|
|
const err = error as AxiosError;
|
|
if (err.status === 401) {
|
|
}
|
|
if (err.status === 404) {
|
|
}
|
|
return Promise.reject(error);
|
|
}
|
|
|
|
public get requestInstance(): AxiosInstance {
|
|
return this.instance;
|
|
}
|
|
|
|
get<T>(url: string, option?: AxiosRequestConfig & { retRaw?: boolean }): Promise<Response<T>> {
|
|
const { retRaw, ...reqConfig } = option ?? {};
|
|
return new Promise((resolve) => {
|
|
this.instance
|
|
.get(url, {
|
|
...reqConfig,
|
|
})
|
|
.then((res) => {
|
|
if (retRaw) {
|
|
resolve([null, res.data as T, null]);
|
|
} else {
|
|
const resData = res.data as Result<T>;
|
|
resolve([null, resData.data, resData]);
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
resolve([err as AxiosError, null, null]);
|
|
});
|
|
});
|
|
}
|
|
|
|
post<T>(url: string, data?: AxiosRequestConfig['data'], option?: Partial<Omit<AxiosRequestConfig, 'data'>> & { retRaw?: boolean; upload?: boolean }): Promise<Response<T>> {
|
|
const { retRaw, upload, ...reqConfig } = option ?? {};
|
|
return new Promise((resolve) => {
|
|
this.instance
|
|
.post(url, data, { headers: { 'content-type': upload ? 'multipart/form-data' : 'application/json' }, ...reqConfig })
|
|
.then((res) => {
|
|
const resData = res.data;
|
|
if (retRaw) {
|
|
resolve([null, resData as T, null]);
|
|
} else {
|
|
resolve([null, resData.data as T, resData as Result<T>]);
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
resolve([err as AxiosError, null, null]);
|
|
});
|
|
});
|
|
}
|
|
|
|
put<T>(url: string, data?: AxiosRequestConfig['data'], option?: Partial<Omit<AxiosRequestConfig, 'data'>>): Promise<Response<T>> {
|
|
const reqConfig = option ?? {};
|
|
return new Promise((resolve) => {
|
|
this.instance
|
|
.put<Result<T>>(url, data, { ...reqConfig })
|
|
.then((res) => {
|
|
resolve([null, res.data.data, res.data]);
|
|
})
|
|
.catch((err) => {
|
|
resolve([err as AxiosError, null, null]);
|
|
});
|
|
});
|
|
}
|
|
|
|
delete<T>(url: string, idList: string[], option?: Partial<Omit<AxiosRequestConfig, 'data'>>): Promise<Response<T>> {
|
|
const reqConfig = option ?? {};
|
|
return new Promise((resolve) => {
|
|
this.instance
|
|
.delete<Result<T>>(url, { ...reqConfig, data: idList })
|
|
.then((res) => {
|
|
resolve([null, res.data.data, res.data]);
|
|
})
|
|
.catch((err) => {
|
|
resolve([err as AxiosError, null, null]);
|
|
});
|
|
});
|
|
}
|
|
}
|