2022-11-15 14:33:43 +00:00
|
|
|
import type { FetchError, FetchOptions } from 'ofetch'
|
2022-05-11 12:32:05 +00:00
|
|
|
import type { TypedInternalResponse, NitroFetchRequest } from 'nitropack'
|
2022-12-11 21:44:52 +00:00
|
|
|
import type { Ref } from 'vue'
|
|
|
|
import { computed, unref, reactive } from 'vue'
|
2022-11-15 16:47:41 +00:00
|
|
|
import { hash } from 'ohash'
|
2022-07-07 16:26:04 +00:00
|
|
|
import type { AsyncDataOptions, _Transform, KeyOfRes, AsyncData, PickFrom } from './asyncData'
|
2021-10-11 22:36:50 +00:00
|
|
|
import { useAsyncData } from './asyncData'
|
|
|
|
|
2022-05-11 12:32:05 +00:00
|
|
|
export type FetchResult<ReqT extends NitroFetchRequest> = TypedInternalResponse<ReqT, unknown>
|
2021-10-11 22:36:50 +00:00
|
|
|
|
2022-10-21 08:13:14 +00:00
|
|
|
type ComputedOptions<T extends Record<string, any>> = {
|
|
|
|
[K in keyof T]: T[K] extends Function ? T[K] : T[K] extends Record<string, any> ? ComputedOptions<T[K]> | Ref<T[K]> | T[K] : Ref<T[K]> | T[K]
|
|
|
|
}
|
|
|
|
|
|
|
|
type ComputedFetchOptions = ComputedOptions<FetchOptions>
|
|
|
|
|
2022-03-31 10:24:28 +00:00
|
|
|
export interface UseFetchOptions<
|
2021-10-11 22:36:50 +00:00
|
|
|
DataT,
|
|
|
|
Transform extends _Transform<DataT, any> = _Transform<DataT, DataT>,
|
|
|
|
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
2022-10-21 08:13:14 +00:00
|
|
|
> extends AsyncDataOptions<DataT, Transform, PickKeys>, ComputedFetchOptions {
|
2022-03-31 10:24:28 +00:00
|
|
|
key?: string
|
2022-04-29 18:42:22 +00:00
|
|
|
}
|
2021-10-11 22:36:50 +00:00
|
|
|
|
|
|
|
export function useFetch<
|
2022-02-16 20:50:19 +00:00
|
|
|
ResT = void,
|
2022-09-12 09:23:19 +00:00
|
|
|
ErrorT = FetchError,
|
2022-05-11 12:32:05 +00:00
|
|
|
ReqT extends NitroFetchRequest = NitroFetchRequest,
|
2022-02-16 20:50:19 +00:00
|
|
|
_ResT = ResT extends void ? FetchResult<ReqT> : ResT,
|
|
|
|
Transform extends (res: _ResT) => any = (res: _ResT) => _ResT,
|
2021-11-15 12:09:07 +00:00
|
|
|
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
|
|
|
> (
|
2022-03-17 10:47:41 +00:00
|
|
|
request: Ref<ReqT> | ReqT | (() => ReqT),
|
2022-07-07 16:26:04 +00:00
|
|
|
opts?: UseFetchOptions<_ResT, Transform, PickKeys>
|
2022-11-02 09:07:28 +00:00
|
|
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>
|
2022-07-07 16:26:04 +00:00
|
|
|
export function useFetch<
|
|
|
|
ResT = void,
|
2022-09-12 09:23:19 +00:00
|
|
|
ErrorT = FetchError,
|
2022-07-07 16:26:04 +00:00
|
|
|
ReqT extends NitroFetchRequest = NitroFetchRequest,
|
|
|
|
_ResT = ResT extends void ? FetchResult<ReqT> : ResT,
|
|
|
|
Transform extends (res: _ResT) => any = (res: _ResT) => _ResT,
|
|
|
|
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
|
|
|
> (
|
|
|
|
request: Ref<ReqT> | ReqT | (() => ReqT),
|
|
|
|
arg1?: string | UseFetchOptions<_ResT, Transform, PickKeys>,
|
|
|
|
arg2?: string
|
2021-10-11 22:36:50 +00:00
|
|
|
) {
|
2022-08-12 17:47:58 +00:00
|
|
|
const [opts = {}, autoKey] = typeof arg1 === 'string' ? [{}, arg1] : [arg1, arg2]
|
2022-11-15 16:47:41 +00:00
|
|
|
const _key = opts.key || hash([autoKey, unref(opts.baseURL), typeof request === 'string' ? request : '', unref(opts.params)])
|
2022-07-07 16:26:04 +00:00
|
|
|
if (!_key || typeof _key !== 'string') {
|
|
|
|
throw new TypeError('[nuxt] [useFetch] key must be a string: ' + _key)
|
2022-04-27 16:19:10 +00:00
|
|
|
}
|
2022-07-07 16:26:04 +00:00
|
|
|
if (!request) {
|
|
|
|
throw new Error('[nuxt] [useFetch] request is missing.')
|
|
|
|
}
|
2022-11-10 08:39:49 +00:00
|
|
|
const key = _key === autoKey ? '$f' + _key : _key
|
2022-07-07 16:26:04 +00:00
|
|
|
|
2022-05-11 12:32:05 +00:00
|
|
|
const _request = computed(() => {
|
2022-07-25 12:37:39 +00:00
|
|
|
let r = request
|
2022-03-17 10:47:41 +00:00
|
|
|
if (typeof r === 'function') {
|
|
|
|
r = r()
|
2021-10-11 22:36:50 +00:00
|
|
|
}
|
2022-09-26 09:13:30 +00:00
|
|
|
return unref(r)
|
2022-03-17 10:47:41 +00:00
|
|
|
})
|
2021-10-11 22:36:50 +00:00
|
|
|
|
2022-07-06 19:17:59 +00:00
|
|
|
const {
|
|
|
|
server,
|
|
|
|
lazy,
|
|
|
|
default: defaultFn,
|
|
|
|
transform,
|
|
|
|
pick,
|
|
|
|
watch,
|
2022-09-22 13:55:29 +00:00
|
|
|
immediate,
|
2022-07-06 19:17:59 +00:00
|
|
|
...fetchOptions
|
|
|
|
} = opts
|
|
|
|
|
2022-10-21 08:13:14 +00:00
|
|
|
const _fetchOptions = reactive({
|
2022-07-06 19:17:59 +00:00
|
|
|
...fetchOptions,
|
2022-03-31 10:24:28 +00:00
|
|
|
cache: typeof opts.cache === 'boolean' ? undefined : opts.cache
|
2022-10-21 08:13:14 +00:00
|
|
|
})
|
2022-03-31 10:24:28 +00:00
|
|
|
|
2022-04-04 10:56:41 +00:00
|
|
|
const _asyncDataOptions: AsyncDataOptions<_ResT, Transform, PickKeys> = {
|
2022-07-06 19:17:59 +00:00
|
|
|
server,
|
|
|
|
lazy,
|
|
|
|
default: defaultFn,
|
|
|
|
transform,
|
|
|
|
pick,
|
2022-09-22 13:55:29 +00:00
|
|
|
immediate,
|
2022-03-17 10:47:41 +00:00
|
|
|
watch: [
|
2022-10-21 08:13:14 +00:00
|
|
|
_fetchOptions,
|
2022-03-17 10:47:41 +00:00
|
|
|
_request,
|
2022-07-06 19:17:59 +00:00
|
|
|
...(watch || [])
|
2022-03-17 10:47:41 +00:00
|
|
|
]
|
2022-03-31 10:24:28 +00:00
|
|
|
}
|
|
|
|
|
2022-10-10 10:33:16 +00:00
|
|
|
let controller: AbortController
|
|
|
|
|
2022-04-29 18:42:22 +00:00
|
|
|
const asyncData = useAsyncData<_ResT, ErrorT, Transform, PickKeys>(key, () => {
|
2022-10-10 10:33:16 +00:00
|
|
|
controller?.abort?.()
|
|
|
|
controller = typeof AbortController !== 'undefined' ? new AbortController() : {} as AbortController
|
|
|
|
return $fetch(_request.value, { signal: controller.signal, ..._fetchOptions }) as Promise<_ResT>
|
2022-03-31 10:24:28 +00:00
|
|
|
}, _asyncDataOptions)
|
2022-03-17 10:47:41 +00:00
|
|
|
|
|
|
|
return asyncData
|
2021-10-11 22:36:50 +00:00
|
|
|
}
|
|
|
|
|
2021-11-15 12:09:07 +00:00
|
|
|
export function useLazyFetch<
|
2022-02-16 20:50:19 +00:00
|
|
|
ResT = void,
|
2022-09-12 09:23:19 +00:00
|
|
|
ErrorT = FetchError,
|
2022-05-11 12:32:05 +00:00
|
|
|
ReqT extends NitroFetchRequest = NitroFetchRequest,
|
2022-02-16 20:50:19 +00:00
|
|
|
_ResT = ResT extends void ? FetchResult<ReqT> : ResT,
|
|
|
|
Transform extends (res: _ResT) => any = (res: _ResT) => _ResT,
|
2021-11-15 12:09:07 +00:00
|
|
|
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
|
|
|
> (
|
2022-03-17 21:35:07 +00:00
|
|
|
request: Ref<ReqT> | ReqT | (() => ReqT),
|
2022-07-07 16:26:04 +00:00
|
|
|
opts?: Omit<UseFetchOptions<_ResT, Transform, PickKeys>, 'lazy'>
|
2022-11-02 09:07:28 +00:00
|
|
|
): AsyncData<PickFrom<ReturnType<Transform>, PickKeys>, ErrorT | null>
|
2022-07-07 16:26:04 +00:00
|
|
|
export function useLazyFetch<
|
|
|
|
ResT = void,
|
2022-09-12 09:23:19 +00:00
|
|
|
ErrorT = FetchError,
|
2022-07-07 16:26:04 +00:00
|
|
|
ReqT extends NitroFetchRequest = NitroFetchRequest,
|
|
|
|
_ResT = ResT extends void ? FetchResult<ReqT> : ResT,
|
|
|
|
Transform extends (res: _ResT) => any = (res: _ResT) => _ResT,
|
|
|
|
PickKeys extends KeyOfRes<Transform> = KeyOfRes<Transform>
|
|
|
|
> (
|
|
|
|
request: Ref<ReqT> | ReqT | (() => ReqT),
|
|
|
|
arg1?: string | Omit<UseFetchOptions<_ResT, Transform, PickKeys>, 'lazy'>,
|
|
|
|
arg2?: string
|
2021-11-15 12:09:07 +00:00
|
|
|
) {
|
2022-07-07 16:26:04 +00:00
|
|
|
const [opts, autoKey] = typeof arg1 === 'string' ? [{}, arg1] : [arg1, arg2]
|
|
|
|
|
2022-04-29 18:42:22 +00:00
|
|
|
return useFetch<ResT, ErrorT, ReqT, _ResT, Transform, PickKeys>(request, {
|
|
|
|
...opts,
|
|
|
|
lazy: true
|
2022-07-07 16:26:04 +00:00
|
|
|
},
|
|
|
|
// @ts-ignore
|
|
|
|
autoKey)
|
2021-11-15 12:09:07 +00:00
|
|
|
}
|