cyrilchapon/typera-zod(opens in a new tab)
Language: TypeScript
- stars
- 3
- watchers
- 1
- forks
- 0
- open issues
- 0
- Last updated
- 05/04/2023
Language: TypeScript
— Just like native Parser, but with Zod (instead of io-ts).
The plugin is declined in its Express flavour only for now.
yarn add @chimanos/typera-express-zod
# or
npm install @chimanos/typera-express-zodimport { Parser, Response, Route, URL, route } from 'typera-express' import { z, ZodSchema, ZodFormattedError } from 'zod' import { ZodParser } from '@chimanos/typera-express-zod' interface User { id: number name: string age: number } // Partial User schema { name: string, age: number } const userBodySchema = z.object({ name: z.string(), age: z.number() }).strict() const updateUser: Route< | Response.Ok<User> | Response.NotFound | Response.BadRequest<ZodFormattedError<User>> > = route .put('/user/:id(int)') // Use userBodySchema to parse request body .use(ZodParser.body(userBodySchema)) .handler(async (request) => { const user = await updateUserInDatabase( request.routeParams.id, // Fully typed from userBodySchema output ! request.body ) if (user === null) { return Response.notFound() } return Response.ok(user) })
Just like your usual native Typera.Parser, but with a Zod schema — instead of io-ts codec.
ZodParser is compatible with most Zod features, including coerce and extended methods (like min(n) or email() for example).
— Particularly useful when decoding query strings
const querySchema = z.object({ limit: z.coerce.number().min(0).max(50) skip: z.coerce.number().min(0).optional() }) route // ... .use(ZodParser.query(querySchema)) // ...
If you want to extract your payloads typings for external usage, just use Zod [z.infer] method.
const userBodySchema = z.object({ name: z.string(), age: z.number() }).strict() type UserBodyPayload = z.infer<typeof userBodySchema> // ...
By default, when encountering an validation error, ZodParser produces a response of type :
Response.BadRequest<ZodFormattedError<T>>
— with T being the the underlying type of the given schema (ZodSchema<T>) and ZodFormattedError being the return type of zodError.format().
If you'd prefer to zodError.flatten() errors, you can do so by instanciating a custom parser, like so :
// FlattenedError Type import { typeToFlattenedError } from 'zod' const userBodySchema = z.object({ name: z.string(), age: z.number() }).strict() const updateUser: Route< // ... | Response.BadRequest<typeToFlattenedError<User>> > = route // ... .use(ZodParser.bodyP( userBodySchema, // Flatten error and return it into 400 (err) => Response.BadRequest(err.flatten()) )) // ...
ZodParser provides the 4 methods
query(schema)body(schema)headers(schema)cookies(schema)Each of them will
request.XXXX key;400 Bad Request error responseZodParser.query(schema)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |
The input for this parser will be the query string parsed as Record<string, string>, i.e. all parameter values will be strings. If you want to convert them to other types, you will probably find the coerce method from Zod useful (e.g. z.coerce.number(), etc.)
ZodParser.body(schema)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |
The input for this parser will be the request body, parsed with the body parser of your choice. With Express you probably want to use body-parser, and with Koa the most common choice is koa-bodyparser. Note that these are native Express or Koa middleware, so you must attach them directly to the Express or Koa app rather than use them as typera middleware.
⚠️ You must use a Express or Koa body parsing middleware for
`Parser.body` to work.
ZodParser.headers(schema)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |
Header matching is case-insensitive, so using e.g. X-API-KEY, x-api-key and
X-Api-Key in the codec will all read the same header. However, the parse
result will of course be case sensitive. That is, the field in
request.headers will have the name you specify in the [io-ts] codec you pass
to Parser.headers, with case preserved.
The input for this parser will be the headers parsed as Record<string, string>, i.e. all parameter values will be strings. If you want to convert them to other types, you will probably find the coerce method from Zod useful (e.g. z.coerce.number(), etc.)
ZodParser.cookies(schema)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |
The input for this parser will be the cookies parsed as Record<string, string>, i.e. all parameter values will be strings. If you want to convert them to other types, you will probably find the coerce method from Zod useful (e.g. z.coerce.number(), etc.)
Each of the above functions also have a P flavor that allows the user to override error handling. In addition to a zod schema, these functions take an error handler function that receives a ZodError and produces an ErrorResponse.
ZodParser.queryP(schema, errorHandler)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
ErrorT |
Generic Type |
Optional(inferred). The generated error type |
errorHandler |
(ZodError) => Response<number, ErrorT> |
Required. Error handler |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |
ZodParser.bodyP(schema, errorHandler)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
ErrorT |
Generic Type |
Optional(inferred). The generated error type |
errorHandler |
(ZodError) => Response<number, ErrorT> |
Required. Error handler |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |
ZodParser.headersP(schema, errorHandler)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
ErrorT |
Generic Type |
Optional(inferred). The generated error type |
errorHandler |
(ZodError) => Response<number, ErrorT> |
Required. Error handler |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |
ZodParser.cookiesP(schema, errorHandler)
| Parameter | Type | Description |
|---|---|---|
T |
Generic Type |
Optional(inferred). The return type |
ErrorT |
Generic Type |
Optional(inferred). The generated error type |
errorHandler |
(ZodError) => Response<number, ErrorT> |
Required. Error handler |
schema |
ZodSchema<T> |
Required. The zod schema to validate against |