@orval/hono 7.14.0 → 7.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/zValidator.ts +92 -94
  2. package/package.json +9 -8
@@ -1,139 +1,137 @@
1
1
  // based on https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts
2
- import type { z, ZodSchema, ZodError } from 'zod';
3
- import type {
4
- Context,
5
- Env,
6
- Input,
7
- MiddlewareHandler,
8
- TypedResponse,
9
- ValidationTargets,
10
- } from 'hono';
2
+ import type { ZodSafeParseResult as ZodSafeParseResult$1 } from 'zod/v4'
3
+ import type { Context, Env, Input, MiddlewareHandler, TypedResponse, ValidationTargets } from 'hono'
4
+ import { zValidator as zValidatorBase } from '@hono/zod-validator'
5
+ import * as v3 from 'zod/v3'
6
+ import * as v4 from 'zod/v4/core'
11
7
 
12
- type HasUndefined<T> = undefined extends T ? true : false;
8
+ type Awaitable<T> = T | Promise<T>
9
+ type HasUndefined<T> = undefined extends T ? true : false
13
10
 
14
- type Hook<T, E extends Env, P extends string, O = {}> = (
15
- result:
16
- | { success: true; data: T }
17
- | { success: false; error: ZodError; data: T },
18
- c: Context<E, P>,
19
- ) =>
20
- | Response
21
- | Promise<Response>
22
- | void
23
- | Promise<Response | void>
24
- | TypedResponse<O>;
25
- import { zValidator as zValidatorBase } from '@hono/zod-validator';
11
+ type ZodSchema = v3.ZodType | v4.$ZodType
12
+ type ZodError<T extends ZodSchema> = T extends v4.$ZodType ? v4.$ZodError<v4.output<T>> : v3.ZodError
13
+ type ZodSafeParseResult<T, T2, T3 extends ZodSchema> = T3 extends v4.$ZodType ? ZodSafeParseResult$1<T> : v3.SafeParseReturnType<T, T2>
14
+ type zInput<T> = T extends v3.ZodType ? v3.input<T> : T extends v4.$ZodType ? v4.input<T> : never
15
+ type zOutput<T> = T extends v3.ZodType ? v3.output<T> : T extends v4.$ZodType ? v4.output<T> : never
16
+ type zInfer<T> = T extends v3.ZodType ? v3.infer<T> : T extends v4.$ZodType ? v4.infer<T> : never
17
+ type Hook<T, E extends Env, P extends string, Target extends keyof ValidationTargetsWithResponse = keyof ValidationTargetsWithResponse, O = {}, Schema extends ZodSchema = any> = (result: ({
18
+ success: true
19
+ data: T
20
+ } | {
21
+ success: false
22
+ error: ZodError<Schema>
23
+ data: T
24
+ }) & {
25
+ target: Target
26
+ }, c: Context<E, P>) => Awaitable<Response | void | TypedResponse<O>>
26
27
 
27
- type ValidationTargetsWithResponse = ValidationTargets & { response: any };
28
+ type ValidationTargetsWithResponse = ValidationTargets & { response: any }
28
29
 
30
+ /**
31
+ * zValidator wraps `zValidator` from `@hono/zod-validator` and extends it to support response validation. It forwards
32
+ * query parameter, path parameter, and request body validation to `@hono/zod-validator`.
33
+ */
29
34
  export const zValidator =
30
35
  <
31
36
  T extends ZodSchema,
32
37
  Target extends keyof ValidationTargetsWithResponse,
33
38
  E extends Env,
34
39
  P extends string,
35
- In = z.input<T>,
36
- Out = z.output<T>,
40
+ In = zInput<T>,
41
+ Out = zOutput<T>,
37
42
  I extends Input = {
38
43
  in: HasUndefined<In> extends true
39
44
  ? {
40
- [K in Target]?: K extends 'json'
41
- ? In
42
- : HasUndefined<
43
- keyof ValidationTargetsWithResponse[K]
44
- > extends true
45
- ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }
46
- : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };
47
- }
45
+ [K in Target]?: In extends ValidationTargetsWithResponse[K]
46
+ ? In
47
+ : {
48
+ [K2 in keyof In]?: In[K2] extends ValidationTargetsWithResponse[K][K2]
49
+ ? In[K2]
50
+ : ValidationTargetsWithResponse[K][K2]
51
+ }
52
+ }
48
53
  : {
49
- [K in Target]: K extends 'json'
50
- ? In
51
- : HasUndefined<
52
- keyof ValidationTargetsWithResponse[K]
53
- > extends true
54
- ? { [K2 in keyof In]?: ValidationTargetsWithResponse[K][K2] }
55
- : { [K2 in keyof In]: ValidationTargetsWithResponse[K][K2] };
56
- };
57
- out: { [K in Target]: Out };
54
+ [K in Target]: In extends ValidationTargetsWithResponse[K]
55
+ ? In
56
+ : {
57
+ [K2 in keyof In]: In[K2] extends ValidationTargetsWithResponse[K][K2]
58
+ ? In[K2]
59
+ : ValidationTargetsWithResponse[K][K2]
60
+ }
61
+ }
62
+ out: { [K in Target]: Out }
58
63
  },
59
64
  V extends I = I,
60
- >(
65
+ InferredValue = zInfer<T>
66
+ > (
61
67
  target: Target,
62
68
  schema: T,
63
- hook?: Hook<z.infer<T>, E, P>,
69
+ hook?: Hook<InferredValue, E, P, Target, {}, T>
64
70
  ): MiddlewareHandler<E, P, V> =>
65
- async (c, next) => {
66
- if (target !== 'response') {
67
- const value = await zValidatorBase<
68
- T,
69
- keyof ValidationTargets,
70
- E,
71
- P,
72
- In,
73
- Out,
74
- I,
75
- V
76
- >(
77
- target,
78
- schema,
79
- hook,
80
- )(c, next);
81
-
82
- if (value instanceof Response) {
83
- return value;
71
+ async (c, next) => {
72
+ if (target !== 'response'){
73
+ return zValidatorBase<
74
+ T,
75
+ keyof ValidationTargets,
76
+ E,
77
+ P,
78
+ In,
79
+ Out,
80
+ I,
81
+ V,
82
+ InferredValue
83
+ >(
84
+ target,
85
+ schema,
86
+ hook as Hook<InferredValue, E, P, keyof ValidationTargets, {}, T>
87
+ )(c, next)
84
88
  }
85
- } else {
86
- await next();
89
+
90
+ await next()
87
91
 
88
92
  if (
89
93
  c.res.status !== 200 ||
90
94
  !c.res.headers.get('Content-Type')?.includes('application/json')
91
95
  ) {
92
- return;
96
+ return
93
97
  }
94
98
 
95
- let value: unknown;
99
+ let value: unknown
96
100
  try {
97
- value = await c.res.json();
101
+ value = await c.res.json()
98
102
  } catch {
99
- const message = 'Malformed JSON in response';
100
- c.res = new Response(message, { status: 400 });
103
+ const message = 'Malformed JSON in response'
104
+ c.res = new Response(message, { status: 400 })
101
105
 
102
- return;
106
+ return
103
107
  }
104
108
 
105
- const result = await schema.safeParseAsync(value);
109
+ const { success, data, error } = await (schema as v3.ZodType).safeParseAsync(value) as ZodSafeParseResult<InferredValue, Out, T>
106
110
 
107
111
  if (hook) {
108
- const hookResult = hook({ data: value, ...result }, c);
109
- if (hookResult) {
110
- if (hookResult instanceof Response || hookResult instanceof Promise) {
111
- const hookResponse = await hookResult;
112
+ const hookResult = await hook({
113
+ target, success,
114
+ data: data as InferredValue,
115
+ error: error as ZodError<T>
116
+ }, c)
112
117
 
113
- if (hookResponse instanceof Response) {
114
- c.res = new Response(hookResponse.body, hookResponse);
115
- }
116
- }
117
- if (
118
- 'response' in hookResult &&
119
- hookResult.response instanceof Response
120
- ) {
121
- c.res = new Response(hookResult.response.body, hookResult.response);
118
+ if (typeof hookResult === 'object' && hookResult != null) {
119
+ if (hookResult instanceof Response) {
120
+ c.res = new Response(hookResult.body, hookResult)
121
+ } else if ('response' in hookResult && hookResult.response instanceof Response) {
122
+ c.res = new Response(hookResult.response.body, hookResult.response)
122
123
  }
123
124
  }
124
125
  }
125
126
 
126
- if (!result.success) {
127
- c.res = new Response(JSON.stringify(result), {
127
+ if (!success) {
128
+ c.res = new Response(JSON.stringify({ success, data, error }), {
128
129
  status: 400,
129
130
  headers: {
130
- 'Content-Type': 'application/json',
131
- },
132
- });
131
+ 'Content-Type': 'application/json'
132
+ }
133
+ })
133
134
  } else {
134
- c.res = new Response(JSON.stringify(result.data), c.res);
135
+ c.res = new Response(JSON.stringify(data), c.res)
135
136
  }
136
137
  }
137
-
138
- return;
139
- };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orval/hono",
3
- "version": "7.14.0",
3
+ "version": "7.15.0",
4
4
  "license": "MIT",
5
5
  "exports": {
6
6
  ".": {
@@ -15,23 +15,24 @@
15
15
  "scripts": {
16
16
  "build": "tsdown --config-loader unconfig",
17
17
  "dev": "tsdown --config-loader unconfig --watch src",
18
- "lint": "eslint .",
18
+ "lint": "tsc --noEmit src/zValidator.ts && eslint .",
19
19
  "clean": "rimraf .turbo dist",
20
20
  "nuke": "rimraf .turbo dist node_modules"
21
21
  },
22
22
  "dependencies": {
23
- "@orval/core": "7.14.0",
24
- "@orval/zod": "7.14.0",
25
- "fs-extra": "^11.3.1",
23
+ "@orval/core": "7.15.0",
24
+ "@orval/zod": "7.15.0",
25
+ "fs-extra": "^11.3.2",
26
26
  "lodash.uniq": "^4.5.0",
27
27
  "openapi3-ts": "4.5.0"
28
28
  },
29
29
  "devDependencies": {
30
+ "@hono/zod-validator": "^0.7.4",
30
31
  "@types/fs-extra": "^11.0.4",
31
32
  "@types/lodash.uniq": "^4.5.9",
32
- "eslint": "^9.35.0",
33
+ "eslint": "^9.38.0",
33
34
  "rimraf": "^6.0.1",
34
- "tsdown": "^0.15.2",
35
- "typescript": "^5.9.2"
35
+ "tsdown": "^0.15.8",
36
+ "typescript": "^5.9.3"
36
37
  }
37
38
  }