-
-
Notifications
You must be signed in to change notification settings - Fork 39
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
8161e72
commit d334312
Showing
1 changed file
with
79 additions
and
113 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,121 +1,87 @@ | ||
import type { TRPCClientErrorLike, TRPCRequestOptions as _TRPCRequestOptions } from '@trpc/client' | ||
import { type TRPCSubscriptionObserver } from '@trpc/client/dist/internals/TRPCUntypedClient' | ||
import type { | ||
AnyMutationProcedure, | ||
AnyProcedure, | ||
AnyQueryProcedure, | ||
AnyRouter, | ||
ProcedureRouterRecord, | ||
inferProcedureInput, | ||
inferProcedureOutput, | ||
ProcedureArgs, | ||
AnySubscriptionProcedure | ||
} from '@trpc/core' | ||
import { type inferObservableValue, type Unsubscribable } from '@trpc/server/observable' | ||
import { inferTransformedProcedureOutput } from '@trpc/core' | ||
import type { | ||
AsyncData, | ||
AsyncDataOptions, | ||
KeysOf, | ||
PickFrom, | ||
} from 'nuxt/dist/app/composables/asyncData' | ||
import type { Ref, UnwrapRef } from 'vue' | ||
import { | ||
httpLink as _httpLink, | ||
httpBatchLink as _httpBatchLink, | ||
type HTTPLinkOptions as _HTTPLinkOptions, | ||
type HTTPBatchLinkOptions as _HTTPBatchLinkOptions | ||
} from '@trpc/client' | ||
import { type AnyRouter } from '@trpc/core' | ||
import { FetchError } from 'ofetch' | ||
// @ts-expect-error: Nuxt auto-imports | ||
import { useRequestHeaders } from '#imports' | ||
import { type FetchEsque } from '@trpc/client/dist/internals/types' | ||
|
||
interface TRPCRequestOptions extends _TRPCRequestOptions { | ||
abortOnUnmount?: boolean | ||
function customFetch(input: RequestInfo | URL, init?: RequestInit & { method: 'GET' }) { | ||
return globalThis.$fetch.raw(input.toString(), init) | ||
.catch((e) => { | ||
if (e instanceof FetchError && e.response) { return e.response } | ||
throw e | ||
}) | ||
.then(response => ({ | ||
...response, | ||
headers: response.headers, | ||
json: () => Promise.resolve(response._data) | ||
})) | ||
} | ||
|
||
type Resolver<TProcedure extends AnyProcedure, TRouter extends AnyRouter,> = ( | ||
...args: ProcedureArgs<TProcedure['_def']> | ||
) => Promise<inferTransformedProcedureOutput<TRouter, TProcedure>>; | ||
export interface HTTPLinkOptions extends _HTTPLinkOptions { | ||
/** | ||
* Select headers to pass to `useRequestHeaders`. | ||
*/ | ||
pickHeaders?: string[] | ||
} | ||
|
||
type SubscriptionResolver< | ||
TProcedure extends AnyProcedure, | ||
TRouter extends AnyRouter, | ||
> = ( | ||
...args: [ | ||
input: ProcedureArgs<TProcedure['_def']>[0], | ||
opts: ProcedureArgs<TProcedure['_def']>[1] & | ||
Partial< | ||
TRPCSubscriptionObserver< | ||
inferObservableValue<inferProcedureOutput<TProcedure>>, | ||
TRPCClientErrorLike<TRouter> | ||
> | ||
>, | ||
] | ||
) => Unsubscribable | ||
/** | ||
* This is a convenience wrapper around the original httpLink | ||
* that replaces regular `fetch` with a `$fetch` from Nuxt. It | ||
* also sets the default headers based on `useRequestHeaders` values. | ||
* | ||
* During server-side rendering, calling $fetch to fetch your internal API routes | ||
* will directly call the relevant function (emulating the request), | ||
* saving an additional API call. | ||
* | ||
* @see https://nuxt.com/docs/api/utils/dollarfetch | ||
*/ | ||
export function httpLink<TRouter extends AnyRouter>(opts?: HTTPLinkOptions) { | ||
const headers = useRequestHeaders(opts?.pickHeaders) | ||
|
||
type MaybeRef<T> = T | Ref<T> | ||
return _httpLink<TRouter>({ | ||
url: '/api/trpc', | ||
headers () { | ||
return headers | ||
}, | ||
fetch: customFetch as FetchEsque, | ||
...opts, | ||
}) | ||
} | ||
|
||
export interface HttpBatchLinkOptions extends _HTTPBatchLinkOptions { | ||
/** | ||
* Select headers to pass to `useRequestHeaders`. | ||
*/ | ||
pickHeaders?: string[] | ||
} | ||
|
||
export type DecorateProcedure< | ||
TProcedure extends AnyProcedure, | ||
TRouter extends AnyRouter, | ||
> = TProcedure extends AnyQueryProcedure | ||
? { | ||
useQuery: < | ||
ResT = inferTransformedProcedureOutput<TRouter, TProcedure>, | ||
DataE = TRPCClientErrorLike<TRouter>, | ||
DataT = ResT, | ||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>, | ||
>( | ||
input: MaybeRef<inferProcedureInput<TProcedure>>, | ||
opts?: AsyncDataOptions<ResT, DataT, PickKeys> & { | ||
trpc?: TRPCRequestOptions | ||
/** | ||
* The custom unique key to use. | ||
* @see https://nuxt.com/docs/api/composables/use-async-data#params | ||
*/ | ||
queryKey?: string | ||
}, | ||
) => AsyncData<PickFrom<DataT, PickKeys> | null, DataE>, | ||
useLazyQuery: < | ||
ResT = inferTransformedProcedureOutput<TRouter,TProcedure>, | ||
DataE = TRPCClientErrorLike<TRouter>, | ||
DataT = ResT, | ||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>, | ||
>( | ||
input: MaybeRef<inferProcedureInput<TProcedure>>, | ||
opts?: Omit<AsyncDataOptions<ResT, DataT, PickKeys>, 'lazy'> & { | ||
trpc?: TRPCRequestOptions | ||
/** | ||
* The custom unique key to use. | ||
* @see https://nuxt.com/docs/api/composables/use-async-data#params | ||
*/ | ||
queryKey?: string | ||
}, | ||
) => AsyncData<PickFrom<DataT, PickKeys> | null, DataE>, | ||
query: Resolver<TProcedure, TRouter> | ||
} : TProcedure extends AnyMutationProcedure ? { | ||
mutate: Resolver<TProcedure, TRouter> | ||
useMutation: < | ||
ResT = inferTransformedProcedureOutput<TRouter, TProcedure>, | ||
DataE = TRPCClientErrorLike<TRouter>, | ||
DataT = ResT, | ||
PickKeys extends KeysOf<DataT> = KeysOf<DataT>, | ||
>( | ||
opts?: Omit<AsyncDataOptions<ResT, DataT, PickKeys>, 'lazy'> & { | ||
trpc?: TRPCRequestOptions | ||
}, | ||
) => AsyncData<PickFrom<DataT, PickKeys> | null, DataE> & { | ||
/** | ||
* The function to call to trigger the mutation. | ||
*/ | ||
mutate: (input: inferProcedureInput<TProcedure>) => Promise<UnwrapRef<AsyncData<PickFrom<DataT, PickKeys> | null, DataE>['data']>> | ||
}, | ||
} : TProcedure extends AnySubscriptionProcedure ? { | ||
subscribe: SubscriptionResolver<TProcedure, TRouter> | ||
} : never | ||
|
||
/** | ||
* @internal | ||
*/ | ||
export type DecoratedProcedureRecord< | ||
TProcedures extends ProcedureRouterRecord, | ||
TRouter extends AnyRouter, | ||
> = { | ||
[TKey in keyof TProcedures]: TProcedures[TKey] extends AnyRouter | ||
? DecoratedProcedureRecord<TProcedures[TKey]['_def']['record'], TRouter> | ||
: TProcedures[TKey] extends AnyProcedure | ||
? DecorateProcedure<TProcedures[TKey], TRouter> | ||
: never; | ||
} | ||
* This is a convenience wrapper around the original httpBatchLink | ||
* that replaces regular `fetch` with a `$fetch` from Nuxt. It | ||
* also sets the default headers based on `useRequestHeaders` values. | ||
* | ||
* During server-side rendering, calling $fetch to fetch your internal API routes | ||
* will directly call the relevant function (emulating the request), | ||
* saving an additional API call. | ||
* | ||
* @see https://nuxt.com/docs/api/utils/dollarfetch | ||
*/ | ||
export function httpBatchLink<TRouter extends AnyRouter>(opts?: HttpBatchLinkOptions) { | ||
const headers = useRequestHeaders(opts?.pickHeaders) | ||
|
||
return _httpBatchLink<TRouter>({ | ||
url: '/api/trpc', | ||
headers () { | ||
return headers | ||
}, | ||
fetch: customFetch as FetchEsque, | ||
...opts, | ||
}) | ||
} |
d334312
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Successfully deployed to the following URLs:
trpc-nuxt – ./
trpc-nuxt-git-main-wobsoriano.vercel.app
trpc-nuxt-wobsoriano.vercel.app
trpc-nuxt.vercel.app