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

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,
})