Skip to content

Commit

Permalink
feat: options support for factories
Browse files Browse the repository at this point in the history
  • Loading branch information
enkot committed Sep 23, 2023
1 parent d675692 commit 84521db
Showing 1 changed file with 37 additions and 11 deletions.
48 changes: 37 additions & 11 deletions src/runtime/clients.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import type { FetchOptions as _FetchOptions } from 'ofetch'
import type { ErrorResponse, HttpMethod, SuccessResponse, FilterKeys, MediaType, ResponseObjectMap } from "openapi-typescript-helpers"
import type { KeysOf, MultiWatchSources, AsyncDataOptions, AsyncData, PickFrom } from "#app/composables/asyncData"
import type { OpenFetchClientName } from '#build/module/nuxt-open-fetch'
import { toValue, computed, useNuxtApp, useFetch, useLazyFetch } from '#imports'
import { toValue, unref, computed, useNuxtApp, useFetch, useLazyFetch } from '#imports'
import { fillPath } from './utils'

const interceptors = ['onRequest', 'onResponse', 'onRequestError', 'onResponseError'] as const

type FetchResponseData<T> = FilterKeys<SuccessResponse<ResponseObjectMap<T>>, MediaType>
type FetchResponseError<T> = FilterKeys<ErrorResponse<ResponseObjectMap<T>>, MediaType>
type ComputedOptions<T extends Record<string, any>> = {
Expand All @@ -14,12 +16,12 @@ type ComputedOptions<T extends Record<string, any>> = {
type ParamsOption<T = void> = T extends { parameters: any } ? NonNullable<T["parameters"]> : { query: Record<string, unknown> }

export interface OpenFetchOptions extends Omit<_FetchOptions, 'method' | 'params'> { }
interface FetchOptions<M extends HttpMethod, P extends { path?: any, query?: any }> extends Omit<OpenFetchOptions, 'query'> {
interface FetchOptions<M extends HttpMethod, P extends { path?: unknown, query?: unknown }> extends Omit<OpenFetchOptions, 'query'> {
params?: P extends { path: any } ? P['path'] : never
query?: P['query']
method?: M
}
type ComputedFetchOptions<M extends HttpMethod, P extends { path?: any, query?: any }> = ComputedOptions<FetchOptions<M, P>>
type ComputedFetchOptions<M extends HttpMethod, P extends { path?: unknown, query?: unknown }> = ComputedOptions<FetchOptions<M, P>>

export interface UseFetchOptions<
Method extends HttpMethod,
Expand Down Expand Up @@ -72,39 +74,63 @@ export type UseLazyOpenFetchClient<Paths> = <
autoKey?: string
) => AsyncData<PickFrom<DataT, PickKeys> | DefaultT, ErrorT | null>

const getGlobalOptions = (name: OpenFetchClientName): OpenFetchOptions => {
const getOptions = (arg: any): OpenFetchOptions => {
const { $openFetch } = useNuxtApp()

return $openFetch[name]
return (typeof arg === 'string' ? $openFetch[arg as OpenFetchClientName] : arg)
}

const combineInterceptors = (...args: ComputedFetchOptions<any, any>[]) => {
return interceptors.reduce((acc, name) => ({
...acc,
[name]: async (ctx: any) => {
await Promise.all(args.map((options) => unref(options[name])?.(ctx)))
}
}), {} as OpenFetchOptions)
}

export const createOpenFetchClient = <Paths>(name: OpenFetchClientName): OpenFetchClient<Paths> => {
export function createOpenFetchClient <Paths>(options: OpenFetchOptions): OpenFetchClient<Paths>
export function createOpenFetchClient <Paths>(name: OpenFetchClientName): OpenFetchClient<Paths>
export function createOpenFetchClient <Paths>(arg: OpenFetchOptions | OpenFetchClientName): OpenFetchClient<Paths> {
return (path, { params, query, ...options } = {}) => {
const sharedOptions = getOptions(arg)

return $fetch(fillPath(path, params), {
...getGlobalOptions(name),
...sharedOptions,
...options,
...combineInterceptors(options, sharedOptions),
query: query as Record<string, unknown>
})
}
}

export const createUseOpenFetchClient = <Paths>(name: OpenFetchClientName): UseOpenFetchClient<Paths> => {
export function createUseOpenFetchClient <Paths>(options: OpenFetchOptions): UseOpenFetchClient<Paths>
export function createUseOpenFetchClient <Paths>(name: OpenFetchClientName): UseOpenFetchClient<Paths>
export function createUseOpenFetchClient <Paths>(arg: OpenFetchOptions | OpenFetchClientName): UseOpenFetchClient<Paths> {
return (path, { params, query, ...options } = {}, autoKey) => {
const sharedOptions = getOptions(arg)

return useFetch(() => fillPath(toValue(path), toValue(params)), {
...getGlobalOptions(name),
...sharedOptions,
key: autoKey,
...options,
...combineInterceptors(options, sharedOptions),
query: computed(() => toValue(query))
})
}
}

export const createUseLazyOpenFetchClient = <Paths>(name: OpenFetchClientName): UseLazyOpenFetchClient<Paths> => {
export function createUseLazyOpenFetchClient <Paths>(options: OpenFetchOptions): UseLazyOpenFetchClient<Paths>
export function createUseLazyOpenFetchClient <Paths>(name: OpenFetchClientName): UseLazyOpenFetchClient<Paths>
export function createUseLazyOpenFetchClient <Paths>(arg: OpenFetchOptions | OpenFetchClientName): UseLazyOpenFetchClient<Paths> {
return (path, { params, query, ...options } = {}, autoKey) => {
const sharedOptions = getOptions(arg)

return useLazyFetch(() => fillPath(toValue(path), toValue(params)), {
...getGlobalOptions(name),
...sharedOptions,
key: autoKey,
...options,
...combineInterceptors(options, sharedOptions),
query: computed(() => toValue(query))
})
}
Expand Down

0 comments on commit 84521db

Please sign in to comment.