You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.4 KiB
52 lines
1.4 KiB
import { createUseFetch } from '#imports'
|
|
import type { NitroFetchRequest } from 'nitropack/types'
|
|
import type { $Fetch } from 'ofetch'
|
|
import type { NuxtApp } from '#app'
|
|
|
|
/** 与 `R.success` / `R.error` 返回结构对齐 */
|
|
export type ApiResponse<T = unknown> = {
|
|
code: number
|
|
message: string
|
|
data: T
|
|
}
|
|
|
|
|
|
/** 从 Nitro 推断的响应体上剥离一层 `ApiResponse`,得到 `data` 字段类型 */
|
|
export type UnwrapApiResponse<T> = T extends ApiResponse<infer D> ? D : T
|
|
|
|
export function unwrapApiBody<T>(payload: ApiResponse<T>): T {
|
|
if (payload.code !== 0) {
|
|
throw new Error(payload.message)
|
|
}
|
|
return payload.data
|
|
}
|
|
|
|
|
|
export const request = $fetch.create({
|
|
credentials: 'include',
|
|
})
|
|
|
|
interface AsyncDataRequestContext {
|
|
cause: 'initial' | 'refresh:manual' | 'refresh:hook' | 'watch'
|
|
}
|
|
|
|
function ssrFriendlyCache<DataT>(key: string, nuxtApp: NuxtApp, ctx: AsyncDataRequestContext): DataT | undefined {
|
|
// SSR 首次水合用 payload 缓存(零闪烁),refresh 时跳过缓存走真实请求
|
|
if (ctx.cause === 'initial') {
|
|
return nuxtApp.payload.data[key] as DataT | undefined
|
|
}
|
|
return undefined
|
|
}
|
|
|
|
const httpFetchDefaults = {
|
|
retry: 0,
|
|
$fetch: import.meta.server ? undefined : request,
|
|
transform: unwrapApiBody,
|
|
getCachedData: ssrFriendlyCache,
|
|
}
|
|
|
|
export const _useHttpFetch = createUseFetch(httpFetchDefaults)
|
|
export const _useLazyHttpFetch = createUseFetch({
|
|
...httpFetchDefaults,
|
|
lazy: true,
|
|
})
|