Add option to enable Zod type coercion for query params #1045
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Status
READY
Description
Fix #961 I expressed a desire to make the generated zod schema for endpoint query parameters more useful for parsing and validating
URLSearchParams
by making use of zod's type-coercion. It turns out that part of this problem isn't easily solvable within this library's generated code (more on that below), but the part that is ended up being relatively simple to add.This PR is one possible (relatively naive) approach to how that might work.
Key points:
override.coerceTypes
boolean flag to the output configzod.coerce.string()
instead ofzod.string()
zod.array(zod.coerce.number())
) - I expect this is useful in some casesAdditional considerations:
zod.coerce.<type>()
is a naive/opinionated approachzod.string().pipe(zod.coerce.date())
orzod.transform(v => new Date(v)).date()
(full example not shown here, but you get the idea - do something with input data before sending it to a parser/schema)Deeper dive on zod + URLSearchParams
It has been discussed before and there are some lingering challenges that aren't really in the scope of the zod package to solve.
Ref: colinhacks/zod#1763
Assumptions:
URLSearchParams
Problems:
URLSearchParams
, since it can contain multiple values for the same keyArray.from(urlSearchParams.entries())
because it will return multiple entries with the same key, whereas the zod schema will expect those to be grouped as an arrayURLSearchParams
first, only converting them to an array if there are multiple values for the same keyzod.transform()
before passing that data intozod.array()
or another schema)Closing thoughts:
I found it a bit challenging to figure out the best way to add test coverage for these changes. There are some reasonably well-defined boundaries among the source files here but still it felt heavy-handed to test at the
generateZod
level. Spinning up the necessary input data wasn't super straightforward.Right now the tests cover the main codegen emission which is conditional on
override.coerceTypes
but does not test the code that pipes the generator options through to the internal function (parseZodValidationSchemaDefinition
) that uses it.I know there has been some discussion in other places that touches on some of the overall design decisions within the library such as using string building vs ASTs for the codegen.
I simply wanted to share my perspective as a new contributor wishing it were easier to contribute test coverage to new features.
Todos
Steps to Test or Reproduce
Outline the steps to test or reproduce the PR here.
zod.coerce.number()
rather thanzod.number()