Compare commits

...

25 Commits

Author SHA1 Message Date
25e09b2e30 Update example and playground dependencies 2023-08-31 14:11:23 +02:00
0612716187 Update dependencies 2023-08-31 13:56:19 +02:00
wobsoriano
55712e3027 chore(release): v0.10.12 2023-08-23 14:18:33 -07:00
wobsoriano
0fec55a3ae refactor: explicitly copy headers to custom fetcher 2023-08-23 14:18:12 -07:00
wobsoriano
8f9e398ae2 fix: expect ofetch missing error response type 2023-08-23 14:12:29 -07:00
wobsoriano
092e3495fd build(deps): bump ofetch to 1.3.2 2023-08-23 13:44:22 -07:00
wobsoriano
230422bb16 docs: fix incorrect syntax 2023-08-23 12:49:09 -07:00
wobsoriano
057c8f8d3a docs: fix missing title 2023-08-23 12:48:32 -07:00
wobsoriano
9808375f31 docs: add response caching page 2023-08-23 12:46:22 -07:00
wobsoriano
8e893a2e30 chore(release): v0.10.11 2023-08-22 10:52:53 -07:00
wobsoriano
f74273190f bump local deps 2023-08-22 10:52:41 -07:00
wobsoriano
283400d41a chore(deps): bump ohash to 1.1.3 2023-08-22 10:51:54 -07:00
wobsoriano
5221dc0515 chore(deps): bump ofetch to 1.2.0 2023-08-22 10:51:29 -07:00
wobsoriano
299ae558ab fix: add missing useLazyQuery type 2023-08-22 10:48:44 -07:00
wobsoriano
f7eeb104b3 docs: bump @nuxt-themes/docus to 1.14.6 2023-08-22 10:36:36 -07:00
wobsoriano
c5c762190b chore(release): v0.10.10 2023-08-20 22:57:35 -07:00
wobsoriano
93cb44288c feat: add useLazyQuery composable 2023-08-20 22:57:31 -07:00
wobsoriano
ede749414d chore(release): v0.10.9 2023-08-20 22:51:01 -07:00
wobsoriano
f2bcf9b68b feat: add custom query key option 2023-08-20 22:50:48 -07:00
wobsoriano
4289dcbfab chore(release): v0.10.8 2023-08-20 22:30:24 -07:00
wobsoriano
dc317c2ded build: bump local deps 2023-08-20 21:57:59 -07:00
wobsoriano
3db0b31d31 refactor: use stand-alone getErrorShape 2023-08-20 21:55:25 -07:00
wobsoriano
f86ebcd6d6 docs: add handler param description 2023-08-20 21:48:39 -07:00
wobsoriano
252f6108cf refactor: use built-in getRequestURL from h3 instead of ufo 2023-08-20 21:41:57 -07:00
wobsoriano
3a395a7d4a build(deps): bump h3 to 1.8.0 2023-08-20 21:36:23 -07:00
15 changed files with 3015 additions and 1009 deletions

View File

@@ -1,6 +1,94 @@
# Changelog
## v0.10.12
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.11...v0.10.12)
### 🩹 Fixes
- Expect ofetch missing error response type ([8f9e398](https://github.com/wobsoriano/trpc-nuxt/commit/8f9e398))
### 💅 Refactors
- Explicitly copy headers to custom fetcher ([0fec55a](https://github.com/wobsoriano/trpc-nuxt/commit/0fec55a))
### 📖 Documentation
- Add response caching page ([9808375](https://github.com/wobsoriano/trpc-nuxt/commit/9808375))
- Fix missing title ([057c8f8](https://github.com/wobsoriano/trpc-nuxt/commit/057c8f8))
- Fix incorrect syntax ([230422b](https://github.com/wobsoriano/trpc-nuxt/commit/230422b))
### 📦 Build
- **deps:** Bump ofetch to 1.3.2 ([092e349](https://github.com/wobsoriano/trpc-nuxt/commit/092e349))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.11
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.10...v0.10.11)
### 🩹 Fixes
- Add missing useLazyQuery type ([299ae55](https://github.com/wobsoriano/trpc-nuxt/commit/299ae55))
### 📖 Documentation
- Bump @nuxt-themes/docus to 1.14.6 ([f7eeb10](https://github.com/wobsoriano/trpc-nuxt/commit/f7eeb10))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.10
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.9...v0.10.10)
### 🚀 Enhancements
- Add useLazyQuery composable ([93cb442](https://github.com/wobsoriano/trpc-nuxt/commit/93cb442))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.9
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.8...v0.10.9)
### 🚀 Enhancements
- Add custom query key option ([f2bcf9b](https://github.com/wobsoriano/trpc-nuxt/commit/f2bcf9b))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.8
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.7...v0.10.8)
### 💅 Refactors
- Use built-in getRequestURL from h3 instead of ufo ([252f610](https://github.com/wobsoriano/trpc-nuxt/commit/252f610))
- Use stand-alone getErrorShape ([3db0b31](https://github.com/wobsoriano/trpc-nuxt/commit/3db0b31))
### 📖 Documentation
- Add handler param description ([f86ebcd](https://github.com/wobsoriano/trpc-nuxt/commit/f86ebcd))
### 📦 Build
- **deps:** Bump h3 to 1.8.0 ([3a395a7](https://github.com/wobsoriano/trpc-nuxt/commit/3a395a7))
- Bump local deps ([dc317c2](https://github.com/wobsoriano/trpc-nuxt/commit/dc317c2))
### ❤️ Contributors
- Wobsoriano ([@wobsoriano](http://github.com/wobsoriano))
## v0.10.7
[compare changes](https://github.com/wobsoriano/trpc-nuxt/compare/v0.10.6...v0.10.7)

View File

@@ -0,0 +1,51 @@
---
title: Response Caching
---
## Response Caching
Your server responses must [satisfy some criteria](https://vercel.com/docs/concepts/functions/serverless-functions/edge-caching) in order for them to be cached (i.e. by Vercel's Edge Network). Please refer to [this section of the tRPC.io documentation](https://trpc.io/docs/caching) for more information.
The `createNuxtApiHandler` function conveniently allows you to specify a `responseMeta` function.
```ts [server/api/trpc/[trpc].ts]
import { createNuxtApiHandler } from 'trpc-nuxt'
import { appRouter } from '~/server/trpc/routers'
export default createNuxtApiHandler({
router: appRouter,
/**
* @link https://trpc.io/docs/caching#api-response-caching
*/
responseMeta(opts) {
// cache request for 1 day + revalidate once every second
const ONE_DAY_IN_SECONDS = 60 * 60 * 24;
return {
headers: {
'cache-control': `s-maxage=1, stale-while-revalidate=${ONE_DAY_IN_SECONDS}`,
},
};
},
})
```
You can also take advantage of Nitro's [Cache API](https://nitro.unjs.io/guide/cache#cache-api) if doing server-side calls:
```ts
import { appRouter } from '@/server/trpc/routers'
const caller = appRouter.createCaller({})
export default cachedEventHandler(async (event) => {
const { name } = getQuery(event)
const greeting = await caller.greeting({ name })
return {
greeting
}
}, {
swr: true, maxAge: 10
})
```

View File

@@ -8,7 +8,7 @@
"preview": "nuxi preview"
},
"devDependencies": {
"@nuxt-themes/docus": "^1.14.3",
"@nuxt-themes/docus": "^1.14.6",
"@nuxtlabs/github-module": "^1.6.3",
"nuxt": "3.6.5"
}

View File

@@ -2,21 +2,21 @@
"name": "nuxt-app",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
"build": "nuxi build",
"dev": "nuxi dev",
"generate": "nuxi generate",
"preview": "nuxi preview",
"postinstall": "nuxi prepare"
},
"devDependencies": {
"@nuxt/devtools": "latest",
"@types/node": "^20.4.2",
"nuxt": "^3.6.5"
"@types/node": "20.5.7",
"nuxt": "^3.7.0"
},
"dependencies": {
"@trpc/client": "^10.35.0",
"@trpc/server": "^10.35.0",
"@trpc/client": "^10.38.1",
"@trpc/server": "^10.38.1",
"trpc-nuxt": "workspace:*",
"zod": "^3.21.4"
"zod": "^3.22.2"
}
}

View File

@@ -3,7 +3,7 @@
"description": "End-to-end typesafe APIs in Nuxt applications.",
"type": "module",
"packageManager": "pnpm@8.6.9",
"version": "0.10.7",
"version": "0.10.12",
"license": "MIT",
"sideEffects": false,
"exports": {
@@ -35,24 +35,23 @@
"update-deps": "taze -w && pnpm i"
},
"peerDependencies": {
"@trpc/client": "^10.26.0",
"@trpc/server": "^10.26.0"
"@trpc/client": "^10.38.1",
"@trpc/server": "^10.38.1"
},
"dependencies": {
"h3": "^1.7.1",
"ofetch": "^1.1.1",
"ohash": "^1.1.2",
"ufo": "^1.1.2"
"h3": "^1.8.1",
"ofetch": "^1.3.3",
"ohash": "^1.1.3"
},
"devDependencies": {
"@nuxt/eslint-config": "^0.1.1",
"@trpc/client": "^10.35.0",
"@trpc/server": "^10.35.0",
"changelogen": "^0.5.4",
"eslint": "^8.45.0",
"@nuxt/eslint-config": "^0.2.0",
"@trpc/client": "^10.38.1",
"@trpc/server": "^10.38.1",
"changelogen": "^0.5.5",
"eslint": "^8.48.0",
"taze": "^0.11.2",
"tsup": "7.1.0",
"typescript": "^5.1.6"
"tsup": "7.2.0",
"typescript": "^5.2.2"
},
"eslintConfig": {
"extends": [
@@ -75,7 +74,9 @@
],
"pnpm": {
"overrides": {
"nuxt": "3.6.5"
"nuxt": "3.7.0",
"@trpc/client": "10.38.1",
"@trpc/server": "10.38.1"
}
}
}
}

View File

@@ -2,21 +2,21 @@
"name": "playground",
"private": true,
"scripts": {
"build": "nuxt build",
"dev": "nuxt dev",
"generate": "nuxt generate",
"preview": "nuxt preview",
"postinstall": "nuxt prepare"
"build": "nuxi build",
"dev": "nuxi dev",
"generate": "nuxi generate",
"preview": "nuxi preview",
"postinstall": "nuxi prepare"
},
"dependencies": {
"@trpc/client": "^10.35.0",
"@trpc/server": "^10.35.0",
"@trpc/client": "10.38.1",
"@trpc/server": "10.38.1",
"superjson": "^1.13.1",
"trpc-nuxt": "workspace:*",
"zod": "^3.21.4"
"zod": "^3.22.2"
},
"devDependencies": {
"@types/node": "^20.4.2",
"nuxt": "3.6.5"
"@types/node": "20.5.7",
"nuxt": "3.7.0"
}
}

View File

@@ -17,7 +17,7 @@ const addTodo = async () => {
}
}
const { data: todos, pending, error, refresh } = await $client.todo.getTodos.useQuery()
const { data: todos, pending, error, refresh } = await $client.todo.getTodos.useLazyQuery()
</script>
<template>

View File

@@ -1,6 +1,6 @@
import { createNuxtApiHandler } from 'trpc-nuxt'
import { appRouter } from '@/server/trpc/routers'
import { createContext } from '@/server/trpc/context'
import { appRouter } from '../../trpc/routers'
import { createContext } from '../../trpc/context'
export default createNuxtApiHandler({
router: appRouter,

View File

@@ -1,5 +1,6 @@
import { z } from 'zod'
import { publicProcedure, router } from '../trpc'
import { $fetch } from 'ofetch'
const baseURL = 'https://jsonplaceholder.typicode.com'

View File

@@ -0,0 +1,3 @@
{
"extends": "../.nuxt/tsconfig.server.json"
}

3727
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -40,8 +40,8 @@ export function createNuxtProxyDecoration<TRouter extends AnyRouter> (name: stri
const [input, otherOptions] = args
if (lastArg === 'useQuery') {
const { trpc, ...asyncDataOptions } = otherOptions || {} as any
if (['useQuery', 'useLazyQuery'].includes(lastArg)) {
const { trpc, queryKey: customQueryKey, ...asyncDataOptions } = otherOptions || {} as any
let controller: AbortController
@@ -54,13 +54,17 @@ export function createNuxtProxyDecoration<TRouter extends AnyRouter> (name: stri
controller = typeof AbortController !== 'undefined' ? new AbortController() : {} as AbortController
}
const queryKey = getQueryKey(path, unref(input))
const queryKey = customQueryKey || getQueryKey(path, unref(input))
const watch = isRef(input) ? [...(asyncDataOptions.watch || []), input] : asyncDataOptions.watch
const isLazy = lastArg === 'useLazyQuery' ? true : (asyncDataOptions.lazy || false)
return useAsyncData(queryKey, () => (client as any)[path].query(unref(input), {
signal: controller?.signal,
...trpc
}), {
...asyncDataOptions,
watch: isRef(input) ? [...(asyncDataOptions.watch || []), input] : asyncDataOptions.watch
watch,
lazy: isLazy
})
}

View File

@@ -14,6 +14,7 @@ function customFetch(input: RequestInfo | URL, init?: RequestInit & { method: 'G
})
.then(response => ({
...response,
headers: response.headers,
json: () => Promise.resolve(response._data)
}))
}

View File

@@ -53,13 +53,36 @@ type DecorateProcedure<
> = TProcedure extends AnyQueryProcedure
? {
useQuery: <
ResT = inferTransformedProcedureOutput<TProcedure>,
DataE = TRPCClientErrorLike<TProcedure>,
DataT = ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
ResT = inferTransformedProcedureOutput<TProcedure>,
DataE = TRPCClientErrorLike<TProcedure>,
DataT = ResT,
PickKeys extends KeysOf<DataT> = KeysOf<DataT>,
>(
input: MaybeRef<inferProcedureInput<TProcedure>>,
opts?: AsyncDataOptions<ResT, DataT, PickKeys> & { trpc?: TRPCRequestOptions },
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<TProcedure>,
DataE = TRPCClientErrorLike<TProcedure>,
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>
} : TProcedure extends AnyMutationProcedure ? {

View File

@@ -9,10 +9,10 @@ import type {
import {
TRPCError
} from '@trpc/server'
import { createURL } from 'ufo'
import type { H3Event } from 'h3'
import { createError, defineEventHandler, isMethod, readBody } from 'h3'
import { createError, defineEventHandler, getRequestURL, isMethod, readBody } from 'h3'
import type { TRPCResponse } from '@trpc/server/rpc'
import { getErrorShape } from '@trpc/server/shared'
type MaybePromise<T> = T | Promise<T>
@@ -40,9 +40,25 @@ export interface OnErrorPayload<TRouter extends AnyRouter> {
export type OnErrorFn<TRouter extends AnyRouter> = (opts: OnErrorPayload<TRouter>) => void
export interface ResolveHTTPRequestOptions<TRouter extends AnyRouter> {
/**
* The tRPC router to use.
* @see https://trpc.io/docs/router
*/
router: TRouter
/**
* An async function that returns the tRPC context.
* @see https://trpc.io/docs/context
*/
createContext?: CreateContextFn<TRouter>
/**
* A function that returns the response meta.
* @see https://trpc.io/docs/caching#using-responsemeta-to-cache-responses
*/
responseMeta?: ResponseMetaFn<TRouter>
/**
* A function that is called when an error occurs.
* @see https://trpc.io/docs/error-handling#handling-errors
*/
onError?: OnErrorFn<TRouter>
batching?: {
enabled: boolean
@@ -74,15 +90,16 @@ export function createNuxtApiHandler<TRouter extends AnyRouter> ({
res
} = event.node
const $url = createURL(req.url!)
const $url = getRequestURL(event)
const path = getPath(event)
if (path === null) {
const error = router.getErrorShape({
const error = getErrorShape({
config: router._def._config,
error: new TRPCError({
message:
'Param "trpc" not found - is the file named `[trpc]`.ts or `[...trpc].ts`?',
'Query "trpc" not found - is the file named `[trpc]`.ts or `[...trpc].ts`?',
code: 'INTERNAL_SERVER_ERROR'
}),
type: 'unknown',