mirror of
https://github.com/soybeanjs/soybean-admin.git
synced 2025-09-29 06:36:41 +08:00
typo(packages): add types & update code
This commit is contained in:
parent
494db95614
commit
e7799d2db1
@ -1,24 +1,12 @@
|
||||
import { createAlova } from 'alova';
|
||||
import VueHook from 'alova/vue';
|
||||
import adapterFetch from 'alova/fetch';
|
||||
import { nanoid } from '@sa/utils';
|
||||
import { createServerTokenAuthentication } from 'alova/client';
|
||||
import { BACKEND_ERROR_CODE, REQUEST_ID_KEY } from './constant';
|
||||
import { isJSON } from './shared';
|
||||
import type { CustomAlovaConfig, RequestOptions } from './type';
|
||||
|
||||
export interface CustomAlovaConfig {
|
||||
baseURL: string;
|
||||
headers?: Record<string, string>;
|
||||
timeout?: number;
|
||||
expiredTokenCodes: string[];
|
||||
}
|
||||
|
||||
export interface RequestOptions {
|
||||
refreshTokenHandler: () => Promise<boolean>;
|
||||
onBackendFail: (response: Response) => Promise<Response | null>;
|
||||
}
|
||||
|
||||
export const createAlovaRequest = (customConfig: CustomAlovaConfig, options: RequestOptions) => {
|
||||
export const createAlovaRequest = (customConfig: CustomAlovaConfig<any>, options: RequestOptions<any>) => {
|
||||
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication({
|
||||
refreshTokenOnSuccess: {
|
||||
isExpired: async response => {
|
||||
@ -34,46 +22,60 @@ export const createAlovaRequest = (customConfig: CustomAlovaConfig, options: Req
|
||||
return false;
|
||||
},
|
||||
handler: async () => {
|
||||
await options.refreshTokenHandler();
|
||||
if (options.refreshTokenHandler) {
|
||||
await options.refreshTokenHandler();
|
||||
}
|
||||
}
|
||||
},
|
||||
// 附加token
|
||||
assignToken: method => {
|
||||
const token = localStorage.getItem('SOY_token');
|
||||
method.config.headers.Authorization = token ? `Bearer ${JSON.parse(token)}` : null;
|
||||
refreshTokenOnError: {
|
||||
isExpired: async response => {
|
||||
const contentType = response.headers.get('Content-Type');
|
||||
if (isJSON(contentType ?? '')) {
|
||||
const resp = response.clone();
|
||||
const data = await resp.json();
|
||||
const responseCode = String(data.code);
|
||||
if (customConfig.expiredTokenCodes.includes(responseCode)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
handler: async () => {
|
||||
if (options.refreshTokenHandler) {
|
||||
await options.refreshTokenHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const instance = createAlova({
|
||||
baseURL: customConfig.baseURL,
|
||||
...customConfig,
|
||||
timeout: customConfig.timeout ?? 10 * 1000,
|
||||
requestAdapter: adapterFetch(),
|
||||
requestAdapter: customConfig.requestAdapter ?? adapterFetch(),
|
||||
statesHook: VueHook,
|
||||
beforeRequest: onAuthRequired(({ config }) => {
|
||||
// 添加配置headers
|
||||
config.headers = {
|
||||
...config.headers,
|
||||
...customConfig.headers
|
||||
};
|
||||
|
||||
// set request id
|
||||
const requestId = nanoid();
|
||||
config.headers[REQUEST_ID_KEY] = requestId;
|
||||
}),
|
||||
beforeRequest: onAuthRequired(options.onRequest),
|
||||
responded: onResponseRefreshToken({
|
||||
onSuccess: async resp => {
|
||||
// check if http status is success
|
||||
if (resp.ok || resp.status === 304) {
|
||||
if (isJSON(resp.headers.get('Content-Type') ?? '')) {
|
||||
if (
|
||||
!isJSON(resp.headers.get('Content-Type') ?? '') ||
|
||||
(options.isBackendSuccess && (await options.isBackendSuccess(resp)))
|
||||
) {
|
||||
return resp;
|
||||
}
|
||||
if (options.onBackendFail) {
|
||||
const fail = await options.onBackendFail(resp);
|
||||
if (fail) {
|
||||
return fail;
|
||||
}
|
||||
return await resp.json();
|
||||
}
|
||||
return resp;
|
||||
return options.transformBackendResponse ? await options.transformBackendResponse(resp) : resp;
|
||||
}
|
||||
return Promise.reject(resp);
|
||||
}
|
||||
throw new Error(resp.statusText);
|
||||
},
|
||||
onComplete: options.onComplete,
|
||||
onError: options.onError
|
||||
})
|
||||
});
|
||||
|
||||
@ -81,3 +83,4 @@ export const createAlovaRequest = (customConfig: CustomAlovaConfig, options: Req
|
||||
};
|
||||
|
||||
export { BACKEND_ERROR_CODE, REQUEST_ID_KEY };
|
||||
export type * from './type';
|
||||
|
64
packages/alova/src/type.ts
Normal file
64
packages/alova/src/type.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import type {
|
||||
AlovaGenerics,
|
||||
AlovaOptions,
|
||||
AlovaRequestAdapter,
|
||||
Method,
|
||||
ResponseCompleteHandler,
|
||||
ResponseErrorHandler
|
||||
} from 'alova';
|
||||
|
||||
export type CustomAlovaConfig<AG extends AlovaGenerics> = Omit<
|
||||
AlovaOptions<AG>,
|
||||
'statesHook' | 'beforeRequest' | 'responded' | 'requestAdapter'
|
||||
> & {
|
||||
/** expired token codes */
|
||||
expiredTokenCodes: string[];
|
||||
/** request adapter. all request of alova will be sent by it. */
|
||||
requestAdapter?: AlovaRequestAdapter<AG['RequestConfig'], AG['Response'], AG['ResponseHeader']>;
|
||||
};
|
||||
|
||||
export interface RequestOptions<AG extends AlovaGenerics> {
|
||||
/**
|
||||
* The hook before request
|
||||
*
|
||||
* For example: You can add header token in this hook
|
||||
*
|
||||
* @param method alova Method Instance
|
||||
*/
|
||||
onRequest?: (method: Method<AG>) => void | Promise<void>;
|
||||
/**
|
||||
* The hook to check backend response is success or not
|
||||
*
|
||||
* @param response Axios response
|
||||
*/
|
||||
isBackendSuccess?: (response: Response) => Promise<boolean>;
|
||||
|
||||
/** The hook to refresh token */
|
||||
refreshTokenHandler?: () => Promise<void>;
|
||||
/**
|
||||
* The hook after backend request fail
|
||||
*
|
||||
* For example: You can handle the expired token in this hook
|
||||
*
|
||||
* @param response Axios response
|
||||
* @param instance Axios instance
|
||||
*/
|
||||
onBackendFail?: (response: Response) => Promise<Response | null> | Promise<void>;
|
||||
|
||||
onComplete?: ResponseCompleteHandler<AG>;
|
||||
|
||||
/**
|
||||
* The hook to handle error
|
||||
*
|
||||
* For example: You can show error message in this hook
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
onError?: ResponseErrorHandler<AG>;
|
||||
/**
|
||||
* transform backend response when the responseType is json
|
||||
*
|
||||
* @param response Axios response
|
||||
*/
|
||||
transformBackendResponse?: (response: AG['Response']) => any | Promise<any>;
|
||||
}
|
Loading…
Reference in New Issue
Block a user