@hono/zod-openapi 0.1.0 → 0.1.1
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.
- package/README.md +31 -23
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# Zod OpenAPI Hono
|
|
2
2
|
|
|
3
|
-
**Zod OpenAPI Hono** is
|
|
4
|
-
With it, you can validate values and types using [**Zod**](https://zod.dev/) and generate OpenAPI Swagger documentation.
|
|
5
|
-
This is based on [**Zod to OpenAPI**](https://github.com/asteasolutions/zod-to-openapi).
|
|
6
|
-
For details on creating schemas and defining routes, please refer to this resource.
|
|
3
|
+
**Zod OpenAPI Hono** is an extended Hono class that supports OpenAPI. With it, you can validate values and types using [**Zod**](https://zod.dev/) and generate OpenAPI Swagger documentation. This is based on [**Zod to OpenAPI**](https://github.com/asteasolutions/zod-to-openapi) (thanks a lot!). For details on creating schemas and defining routes, please refer to [the "Zod to OpenAPI" resource](https://github.com/asteasolutions/zod-to-openapi).
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
_Note: This is not standalone middleware but is hosted on the monorepo "[github.com/honojs/middleware](https://github.com/honojs/middleware)"._
|
|
6
|
+
|
|
7
|
+
## Limitations
|
|
8
|
+
|
|
9
|
+
- Currently, it does not support validation of _headers_ and _cookies_.
|
|
10
|
+
- An instance of Zod OpenAPI Hono cannot be used as a "subApp" in conjunction with `rootApp.route('/api', subApp)`.
|
|
9
11
|
|
|
10
12
|
## Usage
|
|
11
13
|
|
|
12
14
|
### Installation
|
|
13
15
|
|
|
14
|
-
You can install it via
|
|
16
|
+
You can install it via npm. It should be installed alongside `hono` and `zod`.
|
|
15
17
|
|
|
16
18
|
```sh
|
|
17
19
|
npm i hono zod @hono/zod-openapi
|
|
@@ -19,9 +21,9 @@ npm i hono zod @hono/zod-openapi
|
|
|
19
21
|
|
|
20
22
|
### Basic Usage
|
|
21
23
|
|
|
22
|
-
####
|
|
24
|
+
#### Setting up your application
|
|
23
25
|
|
|
24
|
-
First, define schemas with Zod
|
|
26
|
+
First, define your schemas with Zod. The `z` object should be imported from `@hono/zod-openapi`:
|
|
25
27
|
|
|
26
28
|
```ts
|
|
27
29
|
import { z } from '@hono/zod-openapi'
|
|
@@ -42,7 +44,7 @@ const ParamsSchema = z.object({
|
|
|
42
44
|
const UserSchema = z
|
|
43
45
|
.object({
|
|
44
46
|
id: z.string().openapi({
|
|
45
|
-
example: 123,
|
|
47
|
+
example: '123',
|
|
46
48
|
}),
|
|
47
49
|
name: z.string().openapi({
|
|
48
50
|
example: 'John Doe',
|
|
@@ -54,7 +56,7 @@ const UserSchema = z
|
|
|
54
56
|
.openapi('User')
|
|
55
57
|
```
|
|
56
58
|
|
|
57
|
-
Next, create
|
|
59
|
+
Next, create a route:
|
|
58
60
|
|
|
59
61
|
```ts
|
|
60
62
|
import { createRoute } from '@hono/zod-openapi'
|
|
@@ -72,13 +74,13 @@ const route = createRoute({
|
|
|
72
74
|
schema: UserSchema,
|
|
73
75
|
},
|
|
74
76
|
},
|
|
75
|
-
description: '
|
|
77
|
+
description: 'Retrieve the user',
|
|
76
78
|
},
|
|
77
79
|
},
|
|
78
80
|
})
|
|
79
81
|
```
|
|
80
82
|
|
|
81
|
-
Finally,
|
|
83
|
+
Finally, set up the app:
|
|
82
84
|
|
|
83
85
|
```ts
|
|
84
86
|
import { OpenAPIHono } from '@hono/zod-openapi'
|
|
@@ -94,7 +96,7 @@ app.openapi(route, (c) => {
|
|
|
94
96
|
})
|
|
95
97
|
})
|
|
96
98
|
|
|
97
|
-
// OpenAPI
|
|
99
|
+
// The OpenAPI documentation will be available at /doc
|
|
98
100
|
app.doc('/doc', {
|
|
99
101
|
openapi: '3.0.0',
|
|
100
102
|
info: {
|
|
@@ -104,11 +106,17 @@ app.doc('/doc', {
|
|
|
104
106
|
})
|
|
105
107
|
```
|
|
106
108
|
|
|
107
|
-
|
|
109
|
+
You can start your app just like you would with Hono. For Cloudflare Workers and Bun, use this entry point:
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
export default app
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Handling Validation Errors
|
|
108
116
|
|
|
109
|
-
|
|
117
|
+
Validation errors can be handled as follows:
|
|
110
118
|
|
|
111
|
-
|
|
119
|
+
First, define the error schema:
|
|
112
120
|
|
|
113
121
|
```ts
|
|
114
122
|
const ErrorSchema = z.object({
|
|
@@ -121,7 +129,7 @@ const ErrorSchema = z.object({
|
|
|
121
129
|
})
|
|
122
130
|
```
|
|
123
131
|
|
|
124
|
-
|
|
132
|
+
Then, add the error response:
|
|
125
133
|
|
|
126
134
|
```ts
|
|
127
135
|
const route = createRoute({
|
|
@@ -137,13 +145,13 @@ const route = createRoute({
|
|
|
137
145
|
schema: ErrorSchema,
|
|
138
146
|
},
|
|
139
147
|
},
|
|
140
|
-
description: '
|
|
148
|
+
description: 'Returns an error',
|
|
141
149
|
},
|
|
142
150
|
},
|
|
143
151
|
})
|
|
144
152
|
```
|
|
145
153
|
|
|
146
|
-
|
|
154
|
+
Finally, add the hook:
|
|
147
155
|
|
|
148
156
|
```ts
|
|
149
157
|
app.openapi(
|
|
@@ -162,7 +170,7 @@ app.openapi(
|
|
|
162
170
|
return c.jsonT(
|
|
163
171
|
{
|
|
164
172
|
code: 400,
|
|
165
|
-
message: 'Validation Error
|
|
173
|
+
message: 'Validation Error',
|
|
166
174
|
},
|
|
167
175
|
400
|
|
168
176
|
)
|
|
@@ -173,7 +181,7 @@ app.openapi(
|
|
|
173
181
|
|
|
174
182
|
### Middleware
|
|
175
183
|
|
|
176
|
-
|
|
184
|
+
Zod OpenAPI Hono is an extension of Hono, so you can use Hono's middleware in the same way:
|
|
177
185
|
|
|
178
186
|
```ts
|
|
179
187
|
import { prettyJSON } from 'hono/pretty-json'
|
|
@@ -183,9 +191,9 @@ import { prettyJSON } from 'hono/pretty-json'
|
|
|
183
191
|
app.use('/doc/*', prettyJSON())
|
|
184
192
|
```
|
|
185
193
|
|
|
186
|
-
### RPC
|
|
194
|
+
### RPC Mode
|
|
187
195
|
|
|
188
|
-
Zod OpenAPI Hono supports Hono's RPC
|
|
196
|
+
Zod OpenAPI Hono supports Hono's RPC mode. You can define types for the Hono Client as follows:
|
|
189
197
|
|
|
190
198
|
```ts
|
|
191
199
|
import { hc } from 'hono/client'
|
package/dist/index.cjs
CHANGED
|
@@ -83,7 +83,7 @@ var OpenAPIHono = class extends import_hono.Hono {
|
|
|
83
83
|
}
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
|
-
this.on([route.method], route.path, ...validators, handler);
|
|
86
|
+
this.on([route.method], route.path.replace(/\/{(.+)}/, "/:$1"), ...validators, handler);
|
|
87
87
|
return this;
|
|
88
88
|
};
|
|
89
89
|
this.getOpenAPIDocument = (config) => {
|
package/dist/index.d.cts
CHANGED
|
@@ -47,10 +47,11 @@ type Hook<T, E extends Env, P extends string, O> = (result: {
|
|
|
47
47
|
success: false;
|
|
48
48
|
error: ZodError;
|
|
49
49
|
}, c: Context<E, P>) => TypedResponse<O> | Promise<TypedResponse<T>> | void;
|
|
50
|
+
type ConvertPathType<T extends string> = T extends `${infer _}/{${infer Param}}${infer _}` ? `/:${Param}` : T;
|
|
50
51
|
declare class OpenAPIHono<E extends Env = Env, S = {}, BasePath extends string = '/'> extends Hono<E, S, BasePath> {
|
|
51
52
|
#private;
|
|
52
53
|
constructor();
|
|
53
|
-
openapi: <R extends RouteConfig, I extends Input = InputTypeBase<R, "params", "param"> & InputTypeBase<R, "query", "query"> & InputTypeForm<R> & InputTypeJson<R>>(route: R, handler: Handler<E,
|
|
54
|
+
openapi: <R extends RouteConfig, I extends Input = InputTypeBase<R, "params", "param"> & InputTypeBase<R, "query", "query"> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R["path"]>>(route: R, handler: Handler<E, P, I, OutputType<R>>, hook?: Hook<I, E, P, OutputType<R>> | undefined) => Hono<E, Schema<R["method"], P, I["in"], OutputType<R>>, BasePath>;
|
|
54
55
|
getOpenAPIDocument: (config: OpenAPIObjectConfig) => openapi3_ts_oas30.OpenAPIObject;
|
|
55
56
|
doc: (path: string, config: OpenAPIObjectConfig) => void;
|
|
56
57
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -47,10 +47,11 @@ type Hook<T, E extends Env, P extends string, O> = (result: {
|
|
|
47
47
|
success: false;
|
|
48
48
|
error: ZodError;
|
|
49
49
|
}, c: Context<E, P>) => TypedResponse<O> | Promise<TypedResponse<T>> | void;
|
|
50
|
+
type ConvertPathType<T extends string> = T extends `${infer _}/{${infer Param}}${infer _}` ? `/:${Param}` : T;
|
|
50
51
|
declare class OpenAPIHono<E extends Env = Env, S = {}, BasePath extends string = '/'> extends Hono<E, S, BasePath> {
|
|
51
52
|
#private;
|
|
52
53
|
constructor();
|
|
53
|
-
openapi: <R extends RouteConfig, I extends Input = InputTypeBase<R, "params", "param"> & InputTypeBase<R, "query", "query"> & InputTypeForm<R> & InputTypeJson<R>>(route: R, handler: Handler<E,
|
|
54
|
+
openapi: <R extends RouteConfig, I extends Input = InputTypeBase<R, "params", "param"> & InputTypeBase<R, "query", "query"> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R["path"]>>(route: R, handler: Handler<E, P, I, OutputType<R>>, hook?: Hook<I, E, P, OutputType<R>> | undefined) => Hono<E, Schema<R["method"], P, I["in"], OutputType<R>>, BasePath>;
|
|
54
55
|
getOpenAPIDocument: (config: OpenAPIObjectConfig) => openapi3_ts_oas30.OpenAPIObject;
|
|
55
56
|
doc: (path: string, config: OpenAPIObjectConfig) => void;
|
|
56
57
|
}
|
package/dist/index.js
CHANGED
|
@@ -58,7 +58,7 @@ var OpenAPIHono = class extends Hono {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
this.on([route.method], route.path, ...validators, handler);
|
|
61
|
+
this.on([route.method], route.path.replace(/\/{(.+)}/, "/:$1"), ...validators, handler);
|
|
62
62
|
return this;
|
|
63
63
|
};
|
|
64
64
|
this.getOpenAPIDocument = (config) => {
|