|
1 |
| -import type { Context, MiddlewareHandler, Env, ValidationTargets, TypedResponse, Input } from 'hono' |
| 1 | +import type { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from 'hono' |
2 | 2 | import { validator } from 'hono/validator'
|
3 |
| -import type { z, ZodSchema, ZodError } from 'zod' |
| 3 | +import { ZodObject, type ZodError, type ZodSchema, type z } from 'zod' |
4 | 4 |
|
5 | 5 | export type Hook<
|
6 | 6 | T,
|
@@ -46,10 +46,26 @@ export const zValidator = <
|
46 | 46 | ): MiddlewareHandler<E, P, V> =>
|
47 | 47 | // @ts-expect-error not typed well
|
48 | 48 | validator(target, async (value, c) => {
|
49 |
| - const result = await schema.safeParseAsync(value) |
| 49 | + let validatorValue = value |
| 50 | + |
| 51 | + // in case where our `target` === `header`, Hono parses all of the headers into lowercase. |
| 52 | + // this might not match the Zod schema, so we want to make sure that we account for that when parsing the schema. |
| 53 | + if (target === 'header' && schema instanceof ZodObject) { |
| 54 | + // create an object that maps lowercase schema keys to lowercase |
| 55 | + const schemaKeys = Object.keys(schema.shape) |
| 56 | + const caseInsensitiveKeymap = Object.fromEntries( |
| 57 | + schemaKeys.map((key) => [key.toLowerCase(), key]) |
| 58 | + ) |
| 59 | + |
| 60 | + validatorValue = Object.fromEntries( |
| 61 | + Object.entries(value).map(([key, value]) => [caseInsensitiveKeymap[key] || key, value]) |
| 62 | + ) |
| 63 | + } |
| 64 | + |
| 65 | + const result = await schema.safeParseAsync(validatorValue) |
50 | 66 |
|
51 | 67 | if (hook) {
|
52 |
| - const hookResult = await hook({ data: value, ...result, target }, c) |
| 68 | + const hookResult = await hook({ data: validatorValue, ...result, target }, c) |
53 | 69 | if (hookResult) {
|
54 | 70 | if (hookResult instanceof Response) {
|
55 | 71 | return hookResult
|
|
0 commit comments