feat: add convenience link wrappers

This commit is contained in:
wobsoriano
2022-12-18 22:17:37 -08:00
parent f1ca99521e
commit ff88817168
4 changed files with 74 additions and 27 deletions

View File

@@ -39,6 +39,7 @@
}, },
"dependencies": { "dependencies": {
"h3": "^1.0.2", "h3": "^1.0.2",
"ofetch": "^1.0.0",
"ohash": "^1.0.0", "ohash": "^1.0.0",
"ufo": "^1.0.0" "ufo": "^1.0.0"
}, },

View File

@@ -1,36 +1,19 @@
import { httpBatchLink, loggerLink } from '@trpc/client' import { loggerLink } from '@trpc/client'
import superjson from 'superjson' import superjson from 'superjson'
import { FetchError } from 'ofetch' import { createTRPCNuxtClient, httpBatchLink } from 'trpc-nuxt/client'
import { createTRPCNuxtClient } from 'trpc-nuxt/client'
import type { AppRouter } from '~~/server/trpc/routers' import type { AppRouter } from '~~/server/trpc/routers'
export default defineNuxtPlugin(() => { export default defineNuxtPlugin(() => {
const headers = useRequestHeaders()
const client = createTRPCNuxtClient<AppRouter>({ const client = createTRPCNuxtClient<AppRouter>({
transformer: superjson, transformer: superjson,
links: [ links: [
// adds pretty logs to your console in development and logs errors in production // adds pretty logs to your console in development and logs errors in production
loggerLink({ // loggerLink({
enabled: opts => // enabled: opts =>
process.env.NODE_ENV === 'development' || // process.env.NODE_ENV === 'development' ||
(opts.direction === 'down' && opts.result instanceof Error) // (opts.direction === 'down' && opts.result instanceof Error)
}), // }),
httpBatchLink({ httpBatchLink()
url: '/api/trpc',
headers () {
return headers
},
fetch: (input, options) =>
globalThis.$fetch.raw(input.toString(), options)
.catch((e) => {
if (e instanceof FetchError && e.response) { return e.response }
throw e
})
.then(response => ({
...response,
json: () => Promise.resolve(response._data)
}))
})
] ]
}) })

2
pnpm-lock.yaml generated
View File

@@ -14,12 +14,14 @@ importers:
concurrently: ^7.5.0 concurrently: ^7.5.0
eslint: ^8.25.0 eslint: ^8.25.0
h3: ^1.0.2 h3: ^1.0.2
ofetch: ^1.0.0
ohash: ^1.0.0 ohash: ^1.0.0
tsup: 6.4.0 tsup: 6.4.0
typescript: ^4.7.4 typescript: ^4.7.4
ufo: ^1.0.0 ufo: ^1.0.0
dependencies: dependencies:
h3: 1.0.2 h3: 1.0.2
ofetch: 1.0.0
ohash: 1.0.0 ohash: 1.0.0
ufo: 1.0.0 ufo: 1.0.0
devDependencies: devDependencies:

View File

@@ -1,10 +1,12 @@
import { type CreateTRPCClientOptions, type inferRouterProxyClient, createTRPCProxyClient } from '@trpc/client' import { type CreateTRPCClientOptions, type inferRouterProxyClient, createTRPCProxyClient, httpLink as _httpLink, httpBatchLink as _httpBatchLink, HttpBatchLinkOptions } from '@trpc/client'
import { type AnyRouter } from '@trpc/server' import { type AnyRouter } from '@trpc/server'
import { createFlatProxy, createRecursiveProxy } from '@trpc/server/shared' import { createFlatProxy, createRecursiveProxy } from '@trpc/server/shared'
import { hash } from 'ohash' import { hash } from 'ohash'
import { FetchError } from 'ofetch'
import { type DecoratedProcedureRecord } from './types' import { type DecoratedProcedureRecord } from './types'
// @ts-expect-error: Nuxt auto-imports // @ts-expect-error: Nuxt auto-imports
import { getCurrentInstance, onScopeDispose, useAsyncData } from '#imports' import { getCurrentInstance, onScopeDispose, useAsyncData, useRequestHeaders } from '#imports'
import { HTTPLinkOptions } from '@trpc/client/dist/links/internals/httpUtils'
/** /**
* Calculates the key used for `useAsyncData` call * Calculates the key used for `useAsyncData` call
@@ -64,3 +66,62 @@ export function createTRPCNuxtClient<TRouter extends AnyRouter> (opts: CreateTRP
return decoratedClient return decoratedClient
} }
function customFetch(input: RequestInfo | URL, init?: RequestInit | undefined) {
return globalThis.$fetch.raw(input.toString(), init)
.catch((e) => {
if (e instanceof FetchError && e.response) { return e.response }
throw e
})
.then(response => ({
...response,
json: () => Promise.resolve(response._data)
}))
}
/**
* This is a convenience wrapper around the original httpLink
* that replaces regular `fetch` with a `$fetch` from Nuxt.
*
* 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()
return _httpLink<TRouter>({
url: '/api/trpc',
headers () {
return headers
},
fetch: customFetch,
...opts,
})
}
/**
* This is a convenience wrapper around the original httpBatchLink
* that replaces regular `fetch` with a `$fetch` from Nuxt.
*
* 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()
return _httpBatchLink<TRouter>({
url: '/api/trpc',
headers () {
return headers
},
fetch: customFetch,
...opts,
})
}