import type { SimpleAlovaOptions } from './types'; import { useAppConfig } from '@vben/hooks'; import { useAccessStore } from '@vben/stores'; import { createServerTokenAuthentication } from 'alova/client'; import { createAlovaClient } from './alova'; const { requestBaseURL } = useAppConfig(import.meta.env, import.meta.env.PROD); export default function createRequestClient(options?: SimpleAlovaOptions) { const store = options?.tokenStore ?? useAccessStore(); const transform = options?.transform ?? ((body) => body); const interceptor = options?.interceptor ?? { async onSuccess(response, method) { if (response.status > 400) { const message = response.statusText; // eslint-disable-next-line no-throw-literal throw { message }; } /* prettier-ignore */ if (method.meta?.notParseResponse) return response.clone(); /* prettier-ignore */ const [contentType] = response.headers.get('content-type')?.split(';') ?? []; switch (contentType) { case 'application/json': { const body = transform(await response.json(), method); if (method.meta?.notParseResponseBody) return body; if (body.code === 0) return body.data; throw body; } case 'application/octet-stream': { /* prettier-ignore */ const disposition = response.headers.get('content-disposition') ?? method.url; /* prettier-ignore */ const fileName = disposition.match(/fileName=["']?([^"';]+)["']?/i)?.[1]; return fileName ? { fileName: decodeURIComponent(fileName), source: await response.blob(), } : response; } default: { return response; } } }, }; const instance = createAlovaClient({ id: options?.id, baseURL: options?.baseURL ?? requestBaseURL[options?.id?.toString().toLocaleLowerCase() ?? 'url'] ?? requestBaseURL.url, tokenAuthentication: createServerTokenAuthentication({ refreshTokenOnSuccess: { async isExpired(response) { return response.status === 401; }, async handler(response) { if (store.refreshToken) { console.log(response); } }, metaMatches: { authRole: 'refreshToken', refreshToken: true, }, }, login: { async handler(response, method) { const data = await interceptor.onSuccess?.(response.clone(), method); store.loginExpired = false; store.accessToken = data.accessToken; store.refreshToken = data.refreshToken; }, metaMatches: { authRole: 'login', login: true, }, }, logout: { async handler() { store.loginExpired = true; store.accessToken = null; store.refreshToken = null; }, metaMatches: { authRole: 'logout', logout: true, }, }, assignToken(method) { method.config.headers.Authorization ??= store.accessToken; }, visitorMeta: { authRole: 'none', visitor: true, }, }), cacheLogger: import.meta.env.DEV, }); for (const [type, _interceptor] of Object.entries(interceptor)) { instance.interceptor(type.slice(2).toLowerCase(), _interceptor); } return instance; } export * from './alova'; export * from './composables'; export * from './types'; export * from 'alova/client';