diff --git a/playground/app.vue b/playground/app.vue index 63de883..ede1f0a 100644 --- a/playground/app.vue +++ b/playground/app.vue @@ -1,12 +1,18 @@ diff --git a/playground/server/trpc/index.ts b/playground/server/trpc/index.ts new file mode 100644 index 0000000..e3e6e9f --- /dev/null +++ b/playground/server/trpc/index.ts @@ -0,0 +1,21 @@ +// ~/server/trpc/index.ts +import { z } from 'zod' +import * as trpc from '@trpc/server' + +const fakeUsers = [ + { id: 1, username: 'jcena', name: 'John Cena' }, + { id: 2, username: 'dbatista', name: 'Dave Batista' }, + { id: 3, username: 'jbiden', name: 'Joe Biden' }, +] + +export const router = trpc + .router() + .query('getUser', { + // validate input with Zod + input: z.object({ + username: z.string().min(5), + }), + resolve(req) { + return fakeUsers.find(i => i.username === req.input.username) + }, + }) diff --git a/recipes/authorization.md b/recipes/authorization.md index 7bd5acf..ab09f89 100644 --- a/recipes/authorization.md +++ b/recipes/authorization.md @@ -68,6 +68,8 @@ export const router = trpc import * as trpc from '@trpc/server' import { TRPCError } from '@trpc/server' +// Merging routers: https://trpc.io/docs/merging-routers + export const router = trpc .router() // this is accessible for everyone @@ -79,7 +81,7 @@ export const router = trpc }) .merge( 'admin.', - createRouter() + trpc.router() // this protects all procedures defined next in this router .middleware(async ({ ctx, next }) => { if (!ctx.user?.isAdmin) diff --git a/src/module.ts b/src/module.ts index 00b19cf..361279f 100644 --- a/src/module.ts +++ b/src/module.ts @@ -47,11 +47,7 @@ export default defineNuxtModule({ import { createTRPCHandler } from 'trpc-nuxt/api' import * as functions from '~/server/trpc' - export default createTRPCHandler({ - router: functions.router, - createContext: functions.createContext ?? undefined, - responseMeta: functions.responseMeta ?? undefined, - }) + export default createTRPCHandler(functions) `) }, }) diff --git a/src/runtime/api.ts b/src/runtime/api.ts index 99fe867..0792102 100644 --- a/src/runtime/api.ts +++ b/src/runtime/api.ts @@ -11,19 +11,31 @@ import { createURL } from 'ufo' import type { CompatibilityEvent } from 'h3' import { defineEventHandler, isMethod, useBody } from 'h3' import type { TRPCResponse } from '@trpc/server/dist/declarations/src/rpc' -import type { OnErrorFunction } from '@trpc/server/dist/declarations/src/internals/OnErrorFunction' type MaybePromise = T | Promise -type CreateContextFn = (event: CompatibilityEvent) => MaybePromise> +export type CreateContextFn = (event: CompatibilityEvent) => MaybePromise> -type ResponseMetaFn = (opts: { +export interface ResponseMetaFnPayload { data: TRPCResponse>[] ctx?: inferRouterContext paths?: string[] type: ProcedureType | 'unknown' errors: TRPCError[] -}) => ResponseMeta +} + +export type ResponseMetaFn = (opts: ResponseMetaFnPayload) => ResponseMeta + +export interface OnErrorPayload { + error: TRPCError + type: ProcedureType | 'unknown' + path: string | undefined + req: CompatibilityEvent['req'] + input: unknown + ctx: undefined | inferRouterContext +} + +export type OnErrorFn = (opts: OnErrorPayload) => void export function createTRPCHandler({ router, @@ -34,13 +46,14 @@ export function createTRPCHandler({ router: Router createContext?: CreateContextFn responseMeta?: ResponseMetaFn - onError?: OnErrorFunction + onError?: OnErrorFn }) { + const url = '/trpc' + return defineEventHandler(async (event) => { const { req, res, - context, } = event const $url = createURL(req.url) @@ -53,7 +66,7 @@ export function createTRPCHandler({ body: isMethod(event, 'GET') ? null : await useBody(event), query: $url.searchParams, }, - path: context.params.path, + path: $url.pathname.substring(url.length + 1), createContext: async () => createContext?.(event), responseMeta, onError: (o) => {