\r\n \u003C/ZodParser>\r\n \u003C/query>\r\n \u003Cquery name=\"getUser\">\r\n \u003CProtectedProcedure>\r\n \u003CGetUserProcedure />\r\n \u003C/ProtectedProcedure>\r\n \u003C/query>\r\n \u003C/router>\r\n \u003C/SessionContext.Provider>\r\n );\r\n});\r\n```\r\n\r\nLet's break this down.\r\n\r\n# Rendering\r\nEach request corresponds to a render. Only those procedures requested will be run on each render.\r\n```ts\r\nconst AppRouter = withTRPC(() => {\r\n // ...\r\n});\r\n```\r\nThe `withTRPC` function wrapper is necessary to get `req` and `res`.\r\n\r\n# Context\r\nAll context will be done like React:\r\n```tsx\r\nconst SessionContext = createContext();\r\n\r\nconst AppRouter = withTRPC(() => {\r\n const { req, res } = useTrpcRequestContext();\r\n const session = useMemo(() => getServerAuthSession(req, res), []);\r\n\r\n return (\r\n // session will be passed down to all procedures\r\n \u003CSessionContext.Provider value={session}>\r\n {/* ... */}\r\n \u003C/SessionContext.Provider>\r\n );\r\n});\r\n```\r\n\r\n# Middleware\r\nReact already has a composition pattern so we can just hook into that for middleware:\r\n```ts\r\nconst ProtectedProcedure = (props: { children: ReactNode }) => {\r\n // session passed down from `SessionContext.Provider`\r\n const session = useContext(UserContext);\r\n\r\n // bail out if no user\r\n if (!session || !session.user) {\r\n throw new TRPCError({ code: \"UNAUTHORIZED\" });\r\n }\r\n\r\n return (\r\n \u003CUserContext.Provider value={session.user}>\r\n {props.children}\r\n \u003C/UserContext.Provider>\r\n );\r\n};\r\n```\r\n\r\n# Procedures\r\nThere are a few internal JSX elements for declaring procedures: `query`, `mutation`, and `subscription`, all which require the procedure name.\r\n```ts\r\n// this is the actual resolver for the procedure\r\nconst GreetingProcedure = () => {\r\n // automatically typed (call it a gift from God)\r\n const { name } = useArgsContext\u003C{ name: string }>();\r\n\r\n return `Hello ${name}`;\r\n};\r\n\r\nconst AppRouter = withTRPC(() => {\r\n return (\r\n \u003Crouter>\r\n {/* this marks the procedure as a query in the router tree */}\r\n \u003Cquery name=\"greeting\">\r\n \u003CGreetingProcedure />\r\n \u003C/query>\r\n \u003C/router>\r\n );\r\n});\r\n```\r\n\r\n## Input Validation\r\n```ts\r\nconst GreetingProcedure = () => {\r\n const { name } = useArgsContext();\r\n\r\n return `Hello ${name}`;\r\n};\r\n\r\nconst AppRouter = withTRPC(() => {\r\n return (\r\n \u003Crouter>\r\n \u003Cquery name=\"greeting\">\r\n {/* this parses the input data from the request and passes it on using the internal ArgsContext */}\r\n \u003CZodParser schema={z.object({ name: z.string() })}>\r\n \u003CGreetingProcedure />\r\n \u003C/ZodParser>\r\n \u003C/query>\r\n \u003C/router>\r\n );\r\n});\r\n```\r\n\r\n\r\n# Router\r\nRouters and procedures can be nested like any other JSX element:\r\n```ts\r\nconst AppRouter = withTRPC(() => {\r\n return (\r\n \u003Crouter>\r\n \u003Cquery name=\"greeting\">\r\n \u003CGreetingProcedure />\r\n \u003C/query>\r\n {/* everything under this router will be mounted at user.* */}\r\n \u003Crouter name=\"user\">\r\n {/* this mutation is mounted at user.createUser */}\r\n \u003Cmutation name=\"createUser\">\r\n \u003CZodParser schema={z.object({ name: z.string(), age: z.number() })}>\r\n \u003CCreateUserMutation />\r\n \u003C/ZodParser>\r\n \u003C/mutation>\r\n \u003C/router>\r\n \u003C/router>\r\n );\r\n});\r\n```\r\n\r\n### Describe alternate solutions\r\n\r\nMaybe Svelte or Vue could offer better syntax and typesafety 🧐\r\n\r\n### Additional information\r\n\r\n_No response_\r\n\r\n### 👨👧👦 Contributing\r\n\r\n- [X] 🙋♂️ Yes, I'd be down to file a PR implementing this feature!",[3089],{"name":3090,"color":3091},"RFC","78B062",4124,"[RFC]: tRPC Server JSX API","2023-04-21T18:01:53Z","https://github.com/trpc/trpc/issues/4124",0.66607195,{"description":3098,"labels":3099,"number":33,"owner":3021,"repository":3021,"state":3034,"title":3101,"updated_at":3102,"url":3103,"score":3104},"How it is right now:\r\n\r\n```ts\r\nconst rootRouter = trpc.router().endpoint(\r\n 'hello',\r\n trpc.endpoint((ctx: Context) => (arg1: string, arg2: string) => {\r\n return {\r\n hello: `${data}`,\r\n path: ctx.req.path,\r\n };\r\n }),\r\n);\r\n```\r\n\r\n\r\nSuggestion:\r\n\r\n- 1 single input argument being a named options object\r\n\r\n```ts\r\nconst rootRouter = trpc.router().endpoint(\r\n 'hello',\r\n trpc.resolver((input: { name: string }, ctx) => {\r\n return {\r\n hello: input.name,\r\n };\r\n }),\r\n);\r\n```",[3100],{"name":3079,"color":3080},"Copy endpoint resolver format from GraphQL?","2022-10-05T06:10:55Z","https://github.com/trpc/trpc/issues/10",0.66764116,{"description":3106,"labels":3107,"number":3114,"owner":3021,"repository":3021,"state":3034,"title":3115,"updated_at":3116,"url":3117,"score":3118},"This is a super weird one. It may have been me who broke it, and I haven't been able to figure out how/why yet. My team's project hits this error trying to update to v9.6.0 (from v9.0.0-alpha.0, which was before #915 went in but after/somewhere in the middle of #718).\r\n\r\nWe're finding that *under certain conditions* `inferProcedureInput\u003C>` is returning `unknown` (in fact, it's the type inference of router definition - the procedure itself is `Procedure\u003CContext, Context, unknown, { ...result... }>`). Repro (note - this does _not_ repro in this repo, if you do `import * as trpc from '../src'` in a test, which is what I tried first. You can use this [playground link](https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAbzgUwB5mQYxgFQJ4YDyAZnAL5zFQQhwDkaG2AtDAcnQNwBQokscAFRwAhgGc4MKGEyVqtOgAEpMgPRjkUAG6a6vcNHgIAXhSo16xiABM93TBAB2Y+CLBgAShACuMTXABeSWlMADpqX00ACgBKUJBNAHNkKO44ehFrEGBHVToAGjTgmSL08J8-KFjSuHjfERhgJyi6PxcAWXrGpwLEGvScsF8ALjhjUIgAIwArLBgohH70yggIUfGXKBzE2MLl5bIYvf24KGQxCAAbHVHxPEdZBbhB33IYwIA+OAADABIEF4wULEVZkACE32O6UONXiwGs1kuyAA7iIzlE7g84E9HGh4IdPnBcah5jEjtwYjxuGwMHBOjAGk1nIFJOwIKQ3J4KppQgB9azIYh1BndZw8RhzfBEYgAHiKKjCOWImgACtRMMhrN4zgBJRxDGAy+mMpxiADadEy2VybRgxtFdAAuh9uB9YqEYBAAKIAR28IkuUuQJBlSBBazgm225DdlO4EuwQZD8pCoSVqvVmu1yD1BqNXSZ5stWRyqlt9qZTpdsdCjggQM9ACFkABVRwAazryMcsR4QA) to see it going wrong:\r\n\r\n```ts\r\nimport { expectTypeOf } from 'expect-type';\r\nimport * as trpc from '@trpc/server'\r\nimport {z} from 'zod'\r\n\r\nconst appRouter = trpc.router().merge(\r\n 'admin/',\r\n trpc\r\n .router()\r\n .mutation('testMutation', {\r\n input: z.object({\r\n foo: z.string(),\r\n }),\r\n resolve: async ({ input }) => `${input.foo}!`,\r\n })\r\n .middleware(async ({ next }) => next()),\r\n);\r\n\r\ntype Mutations = typeof appRouter._def.mutations;\r\n\r\nexpectTypeOf\u003C\r\n trpc.inferProcedureInput\u003CMutations['admin/testMutation']>\r\n>().toEqualTypeOf\u003C{ foo: string }>();\r\n\r\nexpectTypeOf\u003C\r\n trpc.inferProcedureInput\u003CMutations['admin/testMutation']>\r\n>().not.toBeUnknown();\r\n```\r\n\r\nThe two `expectTypeOf` tests fail. The second is just to show that the inferred type is `unknown` and that it isn't a typo/bad test setup.\r\n\r\nUpdate: The tests succeed if you remove the `.middleware(async ({ next }) => next())` line (in this case, the middleware is pointless - we are seeing it for a similar middleware that throws under certain circumstances)\r\n\r\nUpdate 2: It can also be repro'd by doing `import * as trpc from '../dist/trpc-server.cjs'` in this repo, which makes things much easier. Could there be some types that are being stripped at build time, maybe?",[3108,3111],{"name":3109,"color":3110},"🐛 bug","d73a4a",{"name":3112,"color":3113},"🧙🏻 typescript wizardry","391441",949,"`inferProcedureInput` broken in published package","2022-10-04T18:08:21Z","https://github.com/trpc/trpc/issues/949",0.67590064,["Reactive",3120],{},["Set"],["ShallowReactive",3123],{"$fTRc1wZytZ_XrK4EfJfei_Sz-An4H4Yy6syhVxH_PVJc":-1,"$f2JJLX1yX4SwiXAd0EugDokiXOIASOGU9xu_YOMGI5UQ":-1},"/trpc/v10-playground/25"]