@hono/zod-openapi 1.1.4 → 1.1.6

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @hono/zod-openapi
2
2
 
3
+ ## 1.1.6
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1637](https://github.com/honojs/middleware/pull/1637) [`64cc1d9b103194d826e8d559104c1191672741a1`](https://github.com/honojs/middleware/commit/64cc1d9b103194d826e8d559104c1191672741a1) Thanks [@yusukebe](https://github.com/yusukebe)! - fix: return `OpenAPIHono` from onError and onNotFound
8
+
9
+ ## 1.1.5
10
+
11
+ ### Patch Changes
12
+
13
+ - [#1564](https://github.com/honojs/middleware/pull/1564) [`08be39f7d3be7ab53542a35ca82e4af021de2b5e`](https://github.com/honojs/middleware/commit/08be39f7d3be7ab53542a35ca82e4af021de2b5e) Thanks [@yusukebe](https://github.com/yusukebe)! - fix: correct `basePath` typing for `doc` and `doc31`
14
+
3
15
  ## 1.1.4
4
16
 
5
17
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -1,284 +1,252 @@
1
- "use strict";
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
5
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
8
  var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
17
  };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
19
22
 
20
- // src/index.ts
21
- var index_exports = {};
22
- __export(index_exports, {
23
- OpenAPIHono: () => OpenAPIHono,
24
- createRoute: () => createRoute,
25
- extendZodWithOpenApi: () => import_zod_to_openapi.extendZodWithOpenApi,
26
- z: () => import_zod.z
27
- });
28
- module.exports = __toCommonJS(index_exports);
29
- var import_zod_to_openapi = require("@asteasolutions/zod-to-openapi");
30
- var import_zod_validator = require("@hono/zod-validator");
31
- var import_hono = require("hono");
32
- var import_url = require("hono/utils/url");
33
- var import_zod = require("zod");
23
+ //#endregion
24
+ let __asteasolutions_zod_to_openapi = require("@asteasolutions/zod-to-openapi");
25
+ __asteasolutions_zod_to_openapi = __toESM(__asteasolutions_zod_to_openapi);
26
+ let __hono_zod_validator = require("@hono/zod-validator");
27
+ __hono_zod_validator = __toESM(__hono_zod_validator);
28
+ let hono = require("hono");
29
+ hono = __toESM(hono);
30
+ let hono_utils_url = require("hono/utils/url");
31
+ hono_utils_url = __toESM(hono_utils_url);
32
+ let zod = require("zod");
33
+ zod = __toESM(zod);
34
34
 
35
- // src/zod-typeguard.ts
35
+ //#region src/zod-typeguard.ts
36
36
  function isObject(x) {
37
- return typeof x === "object" && x !== null;
37
+ return typeof x === "object" && x !== null;
38
38
  }
39
39
  function isZod(x) {
40
- if (!x) return false;
41
- if (!isObject(x)) return false;
42
- return typeof x.parse === "function" && typeof x.safeParse === "function" && typeof x.parseAsync === "function" && typeof x.safeParseAsync === "function";
40
+ if (!x) return false;
41
+ if (!isObject(x)) return false;
42
+ return typeof x.parse === "function" && typeof x.safeParse === "function" && typeof x.parseAsync === "function" && typeof x.safeParseAsync === "function";
43
43
  }
44
44
 
45
- // src/index.ts
46
- var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
47
- openAPIRegistry;
48
- defaultHook;
49
- constructor(init) {
50
- super(init);
51
- this.openAPIRegistry = new import_zod_to_openapi.OpenAPIRegistry();
52
- this.defaultHook = init?.defaultHook;
53
- }
54
- /**
55
- *
56
- * @param {RouteConfig} route - The route definition which you create with `createRoute()`.
57
- * @param {Handler} handler - The handler. If you want to return a JSON object, you should specify the status code with `c.json()`.
58
- * @param {Hook} hook - Optional. The hook method defines what it should do after validation.
59
- * @example
60
- * app.openapi(
61
- * route,
62
- * (c) => {
63
- * // ...
64
- * return c.json(
65
- * {
66
- * age: 20,
67
- * name: 'Young man',
68
- * },
69
- * 200 // You should specify the status code even if it's 200.
70
- * )
71
- * },
72
- * (result, c) => {
73
- * if (!result.success) {
74
- * return c.json(
75
- * {
76
- * code: 400,
77
- * message: 'Custom Message',
78
- * },
79
- * 400
80
- * )
81
- * }
82
- * }
83
- *)
84
- */
85
- openapi = ({ middleware: routeMiddleware, hide, ...route }, handler, hook = this.defaultHook) => {
86
- if (!hide) {
87
- this.openAPIRegistry.registerPath(route);
88
- }
89
- const validators = [];
90
- if (route.request?.query) {
91
- const validator = (0, import_zod_validator.zValidator)("query", route.request.query, hook);
92
- validators.push(validator);
93
- }
94
- if (route.request?.params) {
95
- const validator = (0, import_zod_validator.zValidator)("param", route.request.params, hook);
96
- validators.push(validator);
97
- }
98
- if (route.request?.headers) {
99
- const validator = (0, import_zod_validator.zValidator)("header", route.request.headers, hook);
100
- validators.push(validator);
101
- }
102
- if (route.request?.cookies) {
103
- const validator = (0, import_zod_validator.zValidator)("cookie", route.request.cookies, hook);
104
- validators.push(validator);
105
- }
106
- const bodyContent = route.request?.body?.content;
107
- if (bodyContent) {
108
- for (const mediaType of Object.keys(bodyContent)) {
109
- if (!bodyContent[mediaType]) {
110
- continue;
111
- }
112
- const schema = bodyContent[mediaType]["schema"];
113
- if (!isZod(schema)) {
114
- continue;
115
- }
116
- if (isJSONContentType(mediaType)) {
117
- const validator = (0, import_zod_validator.zValidator)("json", schema, hook);
118
- if (route.request?.body?.required) {
119
- validators.push(validator);
120
- } else {
121
- const mw = async (c, next) => {
122
- if (c.req.header("content-type")) {
123
- if (isJSONContentType(c.req.header("content-type"))) {
124
- return await validator(c, next);
125
- }
126
- }
127
- c.req.addValidatedData("json", {});
128
- await next();
129
- };
130
- validators.push(mw);
131
- }
132
- }
133
- if (isFormContentType(mediaType)) {
134
- const validator = (0, import_zod_validator.zValidator)("form", schema, hook);
135
- if (route.request?.body?.required) {
136
- validators.push(validator);
137
- } else {
138
- const mw = async (c, next) => {
139
- if (c.req.header("content-type")) {
140
- if (isFormContentType(c.req.header("content-type"))) {
141
- return await validator(c, next);
142
- }
143
- }
144
- c.req.addValidatedData("form", {});
145
- await next();
146
- };
147
- validators.push(mw);
148
- }
149
- }
150
- }
151
- }
152
- const middleware = routeMiddleware ? Array.isArray(routeMiddleware) ? routeMiddleware : [routeMiddleware] : [];
153
- this.on(
154
- [route.method],
155
- route.path.replaceAll(/\/{(.+?)}/g, "/:$1"),
156
- ...middleware,
157
- ...validators,
158
- handler
159
- );
160
- return this;
161
- };
162
- getOpenAPIDocument = (objectConfig, generatorConfig) => {
163
- const generator = new import_zod_to_openapi.OpenApiGeneratorV3(this.openAPIRegistry.definitions, generatorConfig);
164
- const document = generator.generateDocument(objectConfig);
165
- return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
166
- };
167
- getOpenAPI31Document = (objectConfig, generatorConfig) => {
168
- const generator = new import_zod_to_openapi.OpenApiGeneratorV31(this.openAPIRegistry.definitions, generatorConfig);
169
- const document = generator.generateDocument(objectConfig);
170
- return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
171
- };
172
- doc = (path, configureObject, configureGenerator) => {
173
- return this.get(path, (c) => {
174
- const objectConfig = typeof configureObject === "function" ? configureObject(c) : configureObject;
175
- const generatorConfig = typeof configureGenerator === "function" ? configureGenerator(c) : configureGenerator;
176
- try {
177
- const document = this.getOpenAPIDocument(objectConfig, generatorConfig);
178
- return c.json(document);
179
- } catch (e) {
180
- return c.json(e, 500);
181
- }
182
- });
183
- };
184
- doc31 = (path, configureObject, configureGenerator) => {
185
- return this.get(path, (c) => {
186
- const objectConfig = typeof configureObject === "function" ? configureObject(c) : configureObject;
187
- const generatorConfig = typeof configureGenerator === "function" ? configureGenerator(c) : configureGenerator;
188
- try {
189
- const document = this.getOpenAPI31Document(objectConfig, generatorConfig);
190
- return c.json(document);
191
- } catch (e) {
192
- return c.json(e, 500);
193
- }
194
- });
195
- };
196
- route(path, app) {
197
- const pathForOpenAPI = path.replaceAll(/:([^\/]+)/g, "{$1}");
198
- super.route(path, app);
199
- if (!(app instanceof _OpenAPIHono)) {
200
- return this;
201
- }
202
- app.openAPIRegistry.definitions.forEach((def) => {
203
- switch (def.type) {
204
- case "component":
205
- return this.openAPIRegistry.registerComponent(def.componentType, def.name, def.component);
206
- case "route": {
207
- this.openAPIRegistry.registerPath({
208
- ...def.route,
209
- path: (0, import_url.mergePath)(
210
- pathForOpenAPI,
211
- // @ts-expect-error _basePath is private
212
- app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"),
213
- def.route.path
214
- )
215
- });
216
- return;
217
- }
218
- case "webhook": {
219
- this.openAPIRegistry.registerWebhook({
220
- ...def.webhook,
221
- path: (0, import_url.mergePath)(
222
- pathForOpenAPI,
223
- // @ts-expect-error _basePath is private
224
- app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"),
225
- def.webhook.path
226
- )
227
- });
228
- return;
229
- }
230
- case "schema":
231
- return this.openAPIRegistry.register(
232
- (0, import_zod_to_openapi.getOpenApiMetadata)(def.schema)._internal?.refId,
233
- def.schema
234
- );
235
- case "parameter":
236
- return this.openAPIRegistry.registerParameter(
237
- (0, import_zod_to_openapi.getOpenApiMetadata)(def.schema)._internal?.refId,
238
- def.schema
239
- );
240
- default: {
241
- const errorIfNotExhaustive = def;
242
- throw new Error(`Unknown registry type: ${errorIfNotExhaustive}`);
243
- }
244
- }
245
- });
246
- return this;
247
- }
248
- basePath(path) {
249
- return new _OpenAPIHono({ ...super.basePath(path), defaultHook: this.defaultHook });
250
- }
45
+ //#endregion
46
+ //#region src/index.ts
47
+ var OpenAPIHono = class OpenAPIHono extends hono.Hono {
48
+ openAPIRegistry;
49
+ defaultHook;
50
+ constructor(init) {
51
+ super(init);
52
+ this.openAPIRegistry = new __asteasolutions_zod_to_openapi.OpenAPIRegistry();
53
+ this.defaultHook = init === null || init === void 0 ? void 0 : init.defaultHook;
54
+ }
55
+ /**
56
+ *
57
+ * @param {RouteConfig} route - The route definition which you create with `createRoute()`.
58
+ * @param {Handler} handler - The handler. If you want to return a JSON object, you should specify the status code with `c.json()`.
59
+ * @param {Hook} hook - Optional. The hook method defines what it should do after validation.
60
+ * @example
61
+ * app.openapi(
62
+ * route,
63
+ * (c) => {
64
+ * // ...
65
+ * return c.json(
66
+ * {
67
+ * age: 20,
68
+ * name: 'Young man',
69
+ * },
70
+ * 200 // You should specify the status code even if it's 200.
71
+ * )
72
+ * },
73
+ * (result, c) => {
74
+ * if (!result.success) {
75
+ * return c.json(
76
+ * {
77
+ * code: 400,
78
+ * message: 'Custom Message',
79
+ * },
80
+ * 400
81
+ * )
82
+ * }
83
+ * }
84
+ *)
85
+ */
86
+ openapi = ({ middleware: routeMiddleware, hide,...route }, handler, hook = this.defaultHook) => {
87
+ var _route$request, _route$request2, _route$request3, _route$request4, _route$request5;
88
+ if (!hide) this.openAPIRegistry.registerPath(route);
89
+ const validators = [];
90
+ if ((_route$request = route.request) === null || _route$request === void 0 ? void 0 : _route$request.query) {
91
+ const validator = (0, __hono_zod_validator.zValidator)("query", route.request.query, hook);
92
+ validators.push(validator);
93
+ }
94
+ if ((_route$request2 = route.request) === null || _route$request2 === void 0 ? void 0 : _route$request2.params) {
95
+ const validator = (0, __hono_zod_validator.zValidator)("param", route.request.params, hook);
96
+ validators.push(validator);
97
+ }
98
+ if ((_route$request3 = route.request) === null || _route$request3 === void 0 ? void 0 : _route$request3.headers) {
99
+ const validator = (0, __hono_zod_validator.zValidator)("header", route.request.headers, hook);
100
+ validators.push(validator);
101
+ }
102
+ if ((_route$request4 = route.request) === null || _route$request4 === void 0 ? void 0 : _route$request4.cookies) {
103
+ const validator = (0, __hono_zod_validator.zValidator)("cookie", route.request.cookies, hook);
104
+ validators.push(validator);
105
+ }
106
+ const bodyContent = (_route$request5 = route.request) === null || _route$request5 === void 0 || (_route$request5 = _route$request5.body) === null || _route$request5 === void 0 ? void 0 : _route$request5.content;
107
+ if (bodyContent) for (const mediaType of Object.keys(bodyContent)) {
108
+ if (!bodyContent[mediaType]) continue;
109
+ const schema = bodyContent[mediaType]["schema"];
110
+ if (!isZod(schema)) continue;
111
+ if (isJSONContentType(mediaType)) {
112
+ var _route$request6;
113
+ const validator = (0, __hono_zod_validator.zValidator)("json", schema, hook);
114
+ if ((_route$request6 = route.request) === null || _route$request6 === void 0 || (_route$request6 = _route$request6.body) === null || _route$request6 === void 0 ? void 0 : _route$request6.required) validators.push(validator);
115
+ else {
116
+ const mw = async (c, next) => {
117
+ if (c.req.header("content-type")) {
118
+ if (isJSONContentType(c.req.header("content-type"))) return await validator(c, next);
119
+ }
120
+ c.req.addValidatedData("json", {});
121
+ await next();
122
+ };
123
+ validators.push(mw);
124
+ }
125
+ }
126
+ if (isFormContentType(mediaType)) {
127
+ var _route$request7;
128
+ const validator = (0, __hono_zod_validator.zValidator)("form", schema, hook);
129
+ if ((_route$request7 = route.request) === null || _route$request7 === void 0 || (_route$request7 = _route$request7.body) === null || _route$request7 === void 0 ? void 0 : _route$request7.required) validators.push(validator);
130
+ else {
131
+ const mw = async (c, next) => {
132
+ if (c.req.header("content-type")) {
133
+ if (isFormContentType(c.req.header("content-type"))) {
134
+ await validator(c, next);
135
+ return;
136
+ }
137
+ }
138
+ c.req.addValidatedData("form", {});
139
+ await next();
140
+ };
141
+ validators.push(mw);
142
+ }
143
+ }
144
+ }
145
+ const middleware = routeMiddleware ? Array.isArray(routeMiddleware) ? routeMiddleware : [routeMiddleware] : [];
146
+ this.on([route.method], [route.path.replaceAll(/\/{(.+?)}/g, "/:$1")], ...middleware, ...validators, handler);
147
+ return this;
148
+ };
149
+ getOpenAPIDocument = (objectConfig, generatorConfig) => {
150
+ const document = new __asteasolutions_zod_to_openapi.OpenApiGeneratorV3(this.openAPIRegistry.definitions, generatorConfig).generateDocument(objectConfig);
151
+ return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
152
+ };
153
+ getOpenAPI31Document = (objectConfig, generatorConfig) => {
154
+ const document = new __asteasolutions_zod_to_openapi.OpenApiGeneratorV31(this.openAPIRegistry.definitions, generatorConfig).generateDocument(objectConfig);
155
+ return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
156
+ };
157
+ doc = (path, configureObject, configureGenerator) => {
158
+ return this.get(path, (c) => {
159
+ const objectConfig = typeof configureObject === "function" ? configureObject(c) : configureObject;
160
+ const generatorConfig = typeof configureGenerator === "function" ? configureGenerator(c) : configureGenerator;
161
+ try {
162
+ const document = this.getOpenAPIDocument(objectConfig, generatorConfig);
163
+ return c.json(document);
164
+ } catch (e) {
165
+ return c.json(e, 500);
166
+ }
167
+ });
168
+ };
169
+ doc31 = (path, configureObject, configureGenerator) => {
170
+ return this.get(path, (c) => {
171
+ const objectConfig = typeof configureObject === "function" ? configureObject(c) : configureObject;
172
+ const generatorConfig = typeof configureGenerator === "function" ? configureGenerator(c) : configureGenerator;
173
+ try {
174
+ const document = this.getOpenAPI31Document(objectConfig, generatorConfig);
175
+ return c.json(document);
176
+ } catch (e) {
177
+ return c.json(e, 500);
178
+ }
179
+ });
180
+ };
181
+ route(path, app) {
182
+ const pathForOpenAPI = path.replaceAll(/:([^\/]+)/g, "{$1}");
183
+ super.route(path, app);
184
+ if (!(app instanceof OpenAPIHono)) return this;
185
+ app.openAPIRegistry.definitions.forEach((def) => {
186
+ switch (def.type) {
187
+ case "component": return this.openAPIRegistry.registerComponent(def.componentType, def.name, def.component);
188
+ case "route":
189
+ this.openAPIRegistry.registerPath({
190
+ ...def.route,
191
+ path: (0, hono_utils_url.mergePath)(pathForOpenAPI, app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"), def.route.path)
192
+ });
193
+ return;
194
+ case "webhook":
195
+ this.openAPIRegistry.registerWebhook({
196
+ ...def.webhook,
197
+ path: (0, hono_utils_url.mergePath)(pathForOpenAPI, app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"), def.webhook.path)
198
+ });
199
+ return;
200
+ case "schema":
201
+ var _getOpenApiMetadata$_;
202
+ return this.openAPIRegistry.register((_getOpenApiMetadata$_ = (0, __asteasolutions_zod_to_openapi.getOpenApiMetadata)(def.schema)._internal) === null || _getOpenApiMetadata$_ === void 0 ? void 0 : _getOpenApiMetadata$_.refId, def.schema);
203
+ case "parameter":
204
+ var _getOpenApiMetadata$_2;
205
+ return this.openAPIRegistry.registerParameter((_getOpenApiMetadata$_2 = (0, __asteasolutions_zod_to_openapi.getOpenApiMetadata)(def.schema)._internal) === null || _getOpenApiMetadata$_2 === void 0 ? void 0 : _getOpenApiMetadata$_2.refId, def.schema);
206
+ default: {
207
+ const errorIfNotExhaustive = def;
208
+ throw new Error(`Unknown registry type: ${errorIfNotExhaustive}`);
209
+ }
210
+ }
211
+ });
212
+ return this;
213
+ }
214
+ basePath(path) {
215
+ return new OpenAPIHono({
216
+ ...super.basePath(path),
217
+ defaultHook: this.defaultHook
218
+ });
219
+ }
251
220
  };
252
- var createRoute = (routeConfig) => {
253
- const route = {
254
- ...routeConfig,
255
- getRoutingPath() {
256
- return routeConfig.path.replaceAll(/\/{(.+?)}/g, "/:$1");
257
- }
258
- };
259
- return Object.defineProperty(route, "getRoutingPath", { enumerable: false });
221
+ const createRoute = (routeConfig) => {
222
+ const route = {
223
+ ...routeConfig,
224
+ getRoutingPath() {
225
+ return routeConfig.path.replaceAll(/\/{(.+?)}/g, "/:$1");
226
+ }
227
+ };
228
+ return Object.defineProperty(route, "getRoutingPath", { enumerable: false });
260
229
  };
261
- (0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod.z);
230
+ (0, __asteasolutions_zod_to_openapi.extendZodWithOpenApi)(zod.z);
262
231
  function addBasePathToDocument(document, basePath) {
263
- const updatedPaths = {};
264
- Object.keys(document.paths).forEach((path) => {
265
- updatedPaths[(0, import_url.mergePath)(basePath.replaceAll(/:([^\/]+)/g, "{$1}"), path)] = document.paths[path];
266
- });
267
- return {
268
- ...document,
269
- paths: updatedPaths
270
- };
232
+ const updatedPaths = {};
233
+ Object.keys(document.paths).forEach((path) => {
234
+ updatedPaths[(0, hono_utils_url.mergePath)(basePath.replaceAll(/:([^\/]+)/g, "{$1}"), path)] = document.paths[path];
235
+ });
236
+ return {
237
+ ...document,
238
+ paths: updatedPaths
239
+ };
271
240
  }
272
241
  function isJSONContentType(contentType) {
273
- return /^application\/([a-z-\.]+\+)?json/.test(contentType);
242
+ return /^application\/([a-z-\.]+\+)?json/.test(contentType);
274
243
  }
275
244
  function isFormContentType(contentType) {
276
- return contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded");
245
+ return contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded");
277
246
  }
278
- // Annotate the CommonJS export names for ESM import in node:
279
- 0 && (module.exports = {
280
- OpenAPIHono,
281
- createRoute,
282
- extendZodWithOpenApi,
283
- z
284
- });
247
+
248
+ //#endregion
249
+ exports.OpenAPIHono = OpenAPIHono;
250
+ exports.createRoute = createRoute;
251
+ exports.extendZodWithOpenApi = __asteasolutions_zod_to_openapi.extendZodWithOpenApi;
252
+ exports.z = zod.z;