chore: init read-star monorepo
This commit is contained in:
1
packages/alova/src/client.ts
Normal file
1
packages/alova/src/client.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from 'alova/client'
|
||||
2
packages/alova/src/constant.ts
Normal file
2
packages/alova/src/constant.ts
Normal file
@ -0,0 +1,2 @@
|
||||
/** the backend error code key */
|
||||
export const BACKEND_ERROR_CODE = 'BACKEND_ERROR'
|
||||
3
packages/alova/src/fetch.ts
Normal file
3
packages/alova/src/fetch.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import adapterFetch from 'alova/fetch'
|
||||
|
||||
export default adapterFetch
|
||||
76
packages/alova/src/index.ts
Normal file
76
packages/alova/src/index.ts
Normal file
@ -0,0 +1,76 @@
|
||||
import type { AlovaDefaultCacheAdapter, AlovaGenerics, AlovaGlobalCacheAdapter, AlovaRequestAdapter } from 'alova'
|
||||
import type { FetchRequestInit } from 'alova/fetch'
|
||||
import type { VueHookType } from 'alova/vue'
|
||||
import type { CustomAlovaConfig, RequestOptions } from './type'
|
||||
import { createAlova } from 'alova'
|
||||
import { createServerTokenAuthentication } from 'alova/client'
|
||||
import adapterFetch from 'alova/fetch'
|
||||
import VueHook from 'alova/vue'
|
||||
import { BACKEND_ERROR_CODE } from './constant'
|
||||
|
||||
export function createAlovaRequest<
|
||||
RequestConfig = FetchRequestInit,
|
||||
ResponseType = Response,
|
||||
ResponseHeader = Headers,
|
||||
L1Cache extends AlovaGlobalCacheAdapter = AlovaDefaultCacheAdapter,
|
||||
L2Cache extends AlovaGlobalCacheAdapter = AlovaDefaultCacheAdapter,
|
||||
>(customConfig: CustomAlovaConfig<
|
||||
AlovaGenerics<any, any, RequestConfig, ResponseType, ResponseHeader, L1Cache, L2Cache, any>
|
||||
>, options: RequestOptions<AlovaGenerics<any, any, RequestConfig, ResponseType, ResponseHeader, L1Cache, L2Cache, any>>) {
|
||||
const { tokenRefresher } = options
|
||||
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication<
|
||||
VueHookType,
|
||||
AlovaRequestAdapter<RequestConfig, ResponseType, ResponseHeader>
|
||||
>({
|
||||
refreshTokenOnSuccess: {
|
||||
isExpired: (response, method) => tokenRefresher?.isExpired(response, method) || false,
|
||||
handler: async (response, method) => tokenRefresher?.handler(response, method),
|
||||
},
|
||||
refreshTokenOnError: {
|
||||
isExpired: (response, method) => tokenRefresher?.isExpired(response, method) || false,
|
||||
handler: async (response, method) => tokenRefresher?.handler(response, method),
|
||||
},
|
||||
})
|
||||
|
||||
const instance = createAlova({
|
||||
...customConfig,
|
||||
timeout: customConfig.timeout ?? 10 * 1000,
|
||||
requestAdapter: (customConfig.requestAdapter as any) ?? adapterFetch(),
|
||||
statesHook: VueHook,
|
||||
beforeRequest: onAuthRequired(options.onRequest as any),
|
||||
responded: onResponseRefreshToken({
|
||||
onSuccess: async (response, method) => {
|
||||
// check if http status is success
|
||||
let error: any = null
|
||||
let transformedData: any = null
|
||||
try {
|
||||
if (await options.isBackendSuccess(response)) {
|
||||
transformedData = await options.transformBackendResponse(response)
|
||||
}
|
||||
else {
|
||||
error = new Error('the backend request error')
|
||||
error.code = BACKEND_ERROR_CODE
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
error = err
|
||||
}
|
||||
|
||||
if (error) {
|
||||
await options.onError?.(error, response, method)
|
||||
throw error
|
||||
}
|
||||
|
||||
return transformedData
|
||||
},
|
||||
onComplete: options.onComplete,
|
||||
onError: (error, method) => options.onError?.(error, null, method),
|
||||
}),
|
||||
})
|
||||
|
||||
return instance
|
||||
}
|
||||
|
||||
export { BACKEND_ERROR_CODE }
|
||||
export type * from './type'
|
||||
export type * from 'alova'
|
||||
1
packages/alova/src/mock.ts
Normal file
1
packages/alova/src/mock.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from '@alova/mock'
|
||||
52
packages/alova/src/type.ts
Normal file
52
packages/alova/src/type.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import type { AlovaGenerics, AlovaOptions, AlovaRequestAdapter, Method, ResponseCompleteHandler } from 'alova'
|
||||
|
||||
export type CustomAlovaConfig<AG extends AlovaGenerics> = Omit<
|
||||
AlovaOptions<AG>,
|
||||
'statesHook' | 'beforeRequest' | 'responded' | 'requestAdapter'
|
||||
> & {
|
||||
/** 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?: AlovaOptions<AG>['beforeRequest']
|
||||
/**
|
||||
* The hook to check backend response is success or not
|
||||
*
|
||||
* @param response alova response
|
||||
*/
|
||||
isBackendSuccess: (response: AG['Response']) => Promise<boolean>
|
||||
|
||||
/** The config to refresh token */
|
||||
tokenRefresher?: {
|
||||
/** detect the token is expired */
|
||||
isExpired: (response: AG['Response'], Method: Method<AG>) => Promise<boolean> | boolean
|
||||
/** refresh token handler */
|
||||
handler: (response: AG['Response'], Method: Method<AG>) => Promise<void>
|
||||
}
|
||||
|
||||
/** The hook after backend request complete */
|
||||
onComplete?: ResponseCompleteHandler<AG>
|
||||
|
||||
/**
|
||||
* The hook to handle error
|
||||
*
|
||||
* For example: You can show error message in this hook
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
onError?: (error: any, response: AG['Response'] | null, methodInstance: Method<AG>) => any | Promise<any>
|
||||
/**
|
||||
* transform backend response when the responseType is json
|
||||
*
|
||||
* @param response alova response
|
||||
*/
|
||||
transformBackendResponse: (response: AG['Response']) => any
|
||||
}
|
||||
Reference in New Issue
Block a user