Add a way to access the `ctx` in the `input` parsers
See original GitHub issueI want to transform a slug or id before passing it to the resolve
function. Currently you cannot access the router ctx
inside the input
function which has the downside that you have to do transformations inside the resolve
function (if the transformation requires the ctx
object).
For example: You have a user profile page (profile/{userId}) that uses trpc to get the profile data of a user. You pass this userId to trpc and want to convert the userId into a user object by utilizing some kind of UserRepository
that is available on your ctx
object. The UserRepository
is an instance of a service, and cannot be accessed without the ctx
object as you do not allow singletons.
By allowing the input
to access the ctx
we can utilize Zod’s transform to convert a slug or id before it is passed to the resolve
function. This way we can keep our resolve
functions as clean as possible and keep any sort of input validation & transformation inside our input
function.
According to the docs we can currently pass a Zod, Yup or superstruct object as input. I am not aware how this type is checked internally but if they all provide an object
instead of a function
we could allow a function
as input with the ctx
as an argument.
The end-result could look like:
.query('profile', {
input: ({ ctx }) =>
yup.object({
user: yup.number().required(),
})
.transform((userId) => ctx.userRepository.findById(userId))
.refine((user) => !!user, {
message: 'User could not be found.',
}),
resolve({ input }) {
return {
username: input.user.username,
};
},
});
Issue Analytics
- State:
- Created a year ago
- Reactions:6
- Comments:14 (8 by maintainers)
Top GitHub Comments
It actually is part of the middleware chain, so this could work but seems very hard with the inference of the type being correct.
Thanks for providing the use-case & does seem very valid.
Unsure what an API would look like to support this. We’ll try to address it somehow within the next month or so.
Could this be a rare case where a second arg would be helpful?
Alternatively, if the input parser is called “late” (i.e. inside any middleware callback), potentially there could just be a recipe involving
async_hooks
and people could just do