@hono/zod-openapi 0.19.1 → 0.19.3

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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # Zod OpenAPI Hono
2
2
 
3
+ [![codecov](https://codecov.io/github/honojs/middleware/graph/badge.svg?flag=zod-openapi)](https://codecov.io/github/honojs/middleware)
4
+
3
5
  **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).
4
6
 
5
7
  _Note: This is not standalone middleware but is hosted on the monorepo "[github.com/honojs/middleware](https://github.com/honojs/middleware)"._
@@ -470,6 +472,18 @@ Be careful when combining `OpenAPIHono` instances with plain `Hono` instances. `
470
472
 
471
473
  If you're migrating from plain `Hono` to `OpenAPIHono`, we recommend porting your top-level app, then working your way down the router tree.
472
474
 
475
+ When using the `.route()` method to mount a child OpenAPIHono app that uses path parameters, you should use the Hono *:param* syntax in the parent route path, rather than the OpenAPI *{param}* syntax:
476
+
477
+ ```
478
+ const bookActionsApp = new OpenAPIHono()
479
+ ...
480
+ // ❌ Incorrect: This will not match the route
481
+ app.route('/books/{bookId}', bookActionsApp)
482
+
483
+ // ✅ Using Hono parameter syntax
484
+ app.route('/books/:bookId', bookActionsApp)
485
+ ```
486
+
473
487
  ### Header keys
474
488
 
475
489
  Header keys that you define in your schema must be in lowercase.
@@ -1,20 +1,42 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ 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
+ 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;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
1
20
  // src/index.ts
2
- import {
3
- OpenAPIRegistry,
4
- OpenApiGeneratorV3,
5
- OpenApiGeneratorV31,
6
- extendZodWithOpenApi
7
- } from "@asteasolutions/zod-to-openapi";
8
- import { zValidator } from "@hono/zod-validator";
9
- import { Hono } from "hono";
10
- import { mergePath } from "hono/utils/url";
11
- import { ZodType, z } from "zod";
12
- var OpenAPIHono = class _OpenAPIHono extends Hono {
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");
34
+ var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
13
35
  openAPIRegistry;
14
36
  defaultHook;
15
37
  constructor(init) {
16
38
  super(init);
17
- this.openAPIRegistry = new OpenAPIRegistry();
39
+ this.openAPIRegistry = new import_zod_to_openapi.OpenAPIRegistry();
18
40
  this.defaultHook = init?.defaultHook;
19
41
  }
20
42
  /**
@@ -54,19 +76,19 @@ var OpenAPIHono = class _OpenAPIHono extends Hono {
54
76
  }
55
77
  const validators = [];
56
78
  if (route.request?.query) {
57
- const validator = zValidator("query", route.request.query, hook);
79
+ const validator = (0, import_zod_validator.zValidator)("query", route.request.query, hook);
58
80
  validators.push(validator);
59
81
  }
60
82
  if (route.request?.params) {
61
- const validator = zValidator("param", route.request.params, hook);
83
+ const validator = (0, import_zod_validator.zValidator)("param", route.request.params, hook);
62
84
  validators.push(validator);
63
85
  }
64
86
  if (route.request?.headers) {
65
- const validator = zValidator("header", route.request.headers, hook);
87
+ const validator = (0, import_zod_validator.zValidator)("header", route.request.headers, hook);
66
88
  validators.push(validator);
67
89
  }
68
90
  if (route.request?.cookies) {
69
- const validator = zValidator("cookie", route.request.cookies, hook);
91
+ const validator = (0, import_zod_validator.zValidator)("cookie", route.request.cookies, hook);
70
92
  validators.push(validator);
71
93
  }
72
94
  const bodyContent = route.request?.body?.content;
@@ -76,11 +98,11 @@ var OpenAPIHono = class _OpenAPIHono extends Hono {
76
98
  continue;
77
99
  }
78
100
  const schema = bodyContent[mediaType]["schema"];
79
- if (!(schema instanceof ZodType)) {
101
+ if (!(schema instanceof import_zod.ZodType)) {
80
102
  continue;
81
103
  }
82
104
  if (isJSONContentType(mediaType)) {
83
- const validator = zValidator("json", schema, hook);
105
+ const validator = (0, import_zod_validator.zValidator)("json", schema, hook);
84
106
  if (route.request?.body?.required) {
85
107
  validators.push(validator);
86
108
  } else {
@@ -97,7 +119,7 @@ var OpenAPIHono = class _OpenAPIHono extends Hono {
97
119
  }
98
120
  }
99
121
  if (isFormContentType(mediaType)) {
100
- const validator = zValidator("form", schema, hook);
122
+ const validator = (0, import_zod_validator.zValidator)("form", schema, hook);
101
123
  if (route.request?.body?.required) {
102
124
  validators.push(validator);
103
125
  } else {
@@ -126,12 +148,12 @@ var OpenAPIHono = class _OpenAPIHono extends Hono {
126
148
  return this;
127
149
  };
128
150
  getOpenAPIDocument = (config) => {
129
- const generator = new OpenApiGeneratorV3(this.openAPIRegistry.definitions);
151
+ const generator = new import_zod_to_openapi.OpenApiGeneratorV3(this.openAPIRegistry.definitions);
130
152
  const document = generator.generateDocument(config);
131
153
  return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
132
154
  };
133
155
  getOpenAPI31Document = (config) => {
134
- const generator = new OpenApiGeneratorV31(this.openAPIRegistry.definitions);
156
+ const generator = new import_zod_to_openapi.OpenApiGeneratorV31(this.openAPIRegistry.definitions);
135
157
  const document = generator.generateDocument(config);
136
158
  return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
137
159
  };
@@ -170,20 +192,20 @@ var OpenAPIHono = class _OpenAPIHono extends Hono {
170
192
  case "route":
171
193
  return this.openAPIRegistry.registerPath({
172
194
  ...def.route,
173
- path: mergePath(
195
+ path: (0, import_url.mergePath)(
174
196
  pathForOpenAPI,
175
197
  // @ts-expect-error _basePath is private
176
- app._basePath,
198
+ app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"),
177
199
  def.route.path
178
200
  )
179
201
  });
180
202
  case "webhook":
181
203
  return this.openAPIRegistry.registerWebhook({
182
204
  ...def.webhook,
183
- path: mergePath(
205
+ path: (0, import_url.mergePath)(
184
206
  pathForOpenAPI,
185
207
  // @ts-expect-error _basePath is private
186
- app._basePath,
208
+ app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"),
187
209
  def.webhook.path
188
210
  )
189
211
  });
@@ -215,11 +237,11 @@ var createRoute = (routeConfig) => {
215
237
  };
216
238
  return Object.defineProperty(route, "getRoutingPath", { enumerable: false });
217
239
  };
218
- extendZodWithOpenApi(z);
240
+ (0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod.z);
219
241
  function addBasePathToDocument(document, basePath) {
220
242
  const updatedPaths = {};
221
243
  Object.keys(document.paths).forEach((path) => {
222
- updatedPaths[mergePath(basePath.replaceAll(/:([^\/]+)/g, "{$1}"), path)] = document.paths[path];
244
+ updatedPaths[(0, import_url.mergePath)(basePath.replaceAll(/:([^\/]+)/g, "{$1}"), path)] = document.paths[path];
223
245
  });
224
246
  return {
225
247
  ...document,
@@ -232,9 +254,10 @@ function isJSONContentType(contentType) {
232
254
  function isFormContentType(contentType) {
233
255
  return contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded");
234
256
  }
235
- export {
257
+ // Annotate the CommonJS export names for ESM import in node:
258
+ 0 && (module.exports = {
236
259
  OpenAPIHono,
237
260
  createRoute,
238
261
  extendZodWithOpenApi,
239
262
  z
240
- };
263
+ });
@@ -1,12 +1,14 @@
1
1
  import * as openapi3_ts_oas31 from 'openapi3-ts/oas31';
2
+ import * as _asteasolutions_zod_to_openapi_dist_v3_1_openapi_generator from '@asteasolutions/zod-to-openapi/dist/v3.1/openapi-generator';
2
3
  import * as openapi3_ts_oas30 from 'openapi3-ts/oas30';
3
- import { RouteConfig as RouteConfig$1, ZodMediaTypeObject, OpenAPIRegistry, ZodRequestBody, ZodContentObject, OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi';
4
+ import * as _asteasolutions_zod_to_openapi_dist_v3_0_openapi_generator from '@asteasolutions/zod-to-openapi/dist/v3.0/openapi-generator';
5
+ import { RouteConfig as RouteConfig$1, ZodRequestBody, ZodContentObject, ZodMediaTypeObject, OpenApiGeneratorV3, OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
4
6
  export { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
5
7
  import { MiddlewareHandler, TypedResponse, Env, ValidationTargets, Context, Input, Handler, Schema, Hono, ToSchema } from 'hono';
6
8
  import { MergePath, MergeSchemaPath } from 'hono/types';
7
- import { StatusCode, InfoStatusCode, SuccessStatusCode, RedirectStatusCode, ClientErrorStatusCode, ServerErrorStatusCode } from 'hono/utils/http-status';
8
- import { RemoveBlankRecord, SimplifyDeepArray, JSONValue, JSONParsed } from 'hono/utils/types';
9
- import { ZodError, ZodType, z, ZodSchema } from 'zod';
9
+ import { InfoStatusCode, SuccessStatusCode, RedirectStatusCode, ClientErrorStatusCode, ServerErrorStatusCode, StatusCode } from 'hono/utils/http-status';
10
+ import { SimplifyDeepArray, JSONValue, JSONParsed, RemoveBlankRecord } from 'hono/utils/types';
11
+ import { ZodSchema, z, ZodError, ZodType } from 'zod';
10
12
  export { z } from 'zod';
11
13
 
12
14
  type MaybePromise<T> = Promise<T> | T;
@@ -72,8 +74,12 @@ type RouteConfigStatusCode = keyof StatusCodeRangeDefinitions | StatusCode;
72
74
  type ExtractStatusCode<T extends RouteConfigStatusCode> = T extends keyof StatusCodeRangeDefinitions ? StatusCodeRangeDefinitions[T] : T;
73
75
  type DefinedStatusCodes<R extends RouteConfig> = keyof R['responses'] & RouteConfigStatusCode;
74
76
  type RouteConfigToTypedResponse<R extends RouteConfig> = {
75
- [Status in DefinedStatusCodes<R>]: undefined extends R['responses'][Status]['content'] ? TypedResponse<{}, ExtractStatusCode<Status>, string> : ReturnJsonOrTextOrResponse<keyof R['responses'][Status]['content'], ExtractContent<R['responses'][Status]['content']>, Status>;
76
- }[DefinedStatusCodes<R>] | ('default' extends keyof R['responses'] ? undefined extends R['responses']['default']['content'] ? TypedResponse<{}, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>, string> : ReturnJsonOrTextOrResponse<keyof R['responses']['default']['content'], ExtractContent<R['responses']['default']['content']>, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>> : never);
77
+ [Status in DefinedStatusCodes<R>]: R['responses'][Status] extends {
78
+ content: infer Content;
79
+ } ? undefined extends Content ? never : ReturnJsonOrTextOrResponse<keyof R['responses'][Status]['content'], ExtractContent<R['responses'][Status]['content']>, Status> : TypedResponse<{}, ExtractStatusCode<Status>, string>;
80
+ }[DefinedStatusCodes<R>] | ('default' extends keyof R['responses'] ? R['responses']['default'] extends {
81
+ content: infer Content;
82
+ } ? undefined extends Content ? never : ReturnJsonOrTextOrResponse<keyof Content, ExtractContent<Content>, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>> : TypedResponse<{}, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>, string> : never);
77
83
  type Hook<T, E extends Env, P extends string, R> = (result: {
78
84
  target: keyof ValidationTargets;
79
85
  } & ({
@@ -120,7 +126,7 @@ type MiddlewareToHandlerType<M extends MiddlewareHandler<any, any, any>[]> = M e
120
126
  OfHandlerType<First>['path'], // Keep path from First
121
127
  OfHandlerType<First>['input']>,
122
128
  ...Rest
123
- ]> : never : never : never : M extends [infer Last] ? Last : never;
129
+ ]> : never : never : never : M extends [infer Last] ? Last : MiddlewareHandler<Env>;
124
130
  type RouteMiddlewareParams<R extends RouteConfig> = OfHandlerType<MiddlewareToHandlerType<AsArray<R['middleware']>>>;
125
131
  type RouteConfigToEnv<R extends RouteConfig> = RouteMiddlewareParams<R> extends never ? Env : RouteMiddlewareParams<R>['env'];
126
132
  type RouteHandler<R extends RouteConfig, E extends Env = RouteConfigToEnv<R>, I extends Input = InputTypeParam<R> & InputTypeQuery<R> & InputTypeHeader<R> & InputTypeCookie<R> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R['path']>> = Handler<E, P, I, R extends {
@@ -170,7 +176,7 @@ declare class OpenAPIHono<E extends Env = Env, S extends Schema = {}, BasePath e
170
176
  * }
171
177
  *)
172
178
  */
173
- openapi: <R extends RouteConfig, I extends Input = InputTypeBase<R, "params", "param"> & InputTypeBase<R, "query", "query"> & InputTypeBase<R, "headers", "header"> & InputTypeBase<R, "cookies", "cookie"> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R["path"]>>({ middleware: routeMiddleware, hide, ...route }: R, handler: Handler<R['middleware'] extends MiddlewareHandler[] | MiddlewareHandler ? RouteMiddlewareParams<R>['env'] & E : E, P, I, R extends {
179
+ openapi: <R extends RouteConfig, I extends Input = InputTypeParam<R> & InputTypeQuery<R> & InputTypeHeader<R> & InputTypeCookie<R> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R["path"]>>({ middleware: routeMiddleware, hide, ...route }: R, handler: Handler<R["middleware"] extends MiddlewareHandler[] | MiddlewareHandler ? RouteMiddlewareParams<R>["env"] & E : E, P, I, R extends {
174
180
  responses: {
175
181
  [statusCode: number]: {
176
182
  content: {
@@ -186,11 +192,11 @@ declare class OpenAPIHono<E extends Env = Env, S extends Schema = {}, BasePath e
186
192
  };
187
193
  };
188
194
  };
189
- } ? MaybePromise<RouteConfigToTypedResponse<R>> | undefined : MaybePromise<RouteConfigToTypedResponse<R>> | MaybePromise<Response> | undefined> | undefined) => OpenAPIHono<E, S & ToSchema<R['method'], MergePath<BasePath, P>, I, RouteConfigToTypedResponse<R>>, BasePath>;
190
- getOpenAPIDocument: (config: OpenAPIObjectConfig) => openapi3_ts_oas30.OpenAPIObject;
191
- getOpenAPI31Document: (config: OpenAPIObjectConfig) => openapi3_ts_oas31.OpenAPIObject;
192
- doc: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath>;
193
- doc31: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath>;
195
+ } ? MaybePromise<RouteConfigToTypedResponse<R>> | undefined : MaybePromise<RouteConfigToTypedResponse<R>> | MaybePromise<Response> | undefined> | undefined) => OpenAPIHono<E, S & ToSchema<R["method"], MergePath<BasePath, P>, I, RouteConfigToTypedResponse<R>>, BasePath>;
196
+ getOpenAPIDocument: (config: OpenAPIObjectConfig) => ReturnType<(config: _asteasolutions_zod_to_openapi_dist_v3_0_openapi_generator.OpenAPIObjectConfig) => openapi3_ts_oas30.OpenAPIObject>;
197
+ getOpenAPI31Document: (config: OpenAPIObjectConfig) => ReturnType<(config: _asteasolutions_zod_to_openapi_dist_v3_1_openapi_generator.OpenAPIObjectConfigV31) => openapi3_ts_oas31.OpenAPIObject>;
198
+ doc: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<"get", P, {}, {}>, BasePath>;
199
+ doc31: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<"get", P, {}, {}>, BasePath>;
194
200
  route<SubPath extends string, SubEnv extends Env, SubSchema extends Schema, SubBasePath extends string>(path: SubPath, app: Hono<SubEnv, SubSchema, SubBasePath>): OpenAPIHono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> & S, BasePath>;
195
201
  route<SubPath extends string>(path: SubPath): Hono<E, RemoveBlankRecord<S>, BasePath>;
196
202
  basePath<SubPath extends string>(path: SubPath): OpenAPIHono<E, S, MergePath<BasePath, SubPath>>;
@@ -199,7 +205,7 @@ type RoutingPath<P extends string> = P extends `${infer Head}/{${infer Param}}${
199
205
  declare const createRoute: <P extends string, R extends Omit<RouteConfig, "path"> & {
200
206
  path: P;
201
207
  }>(routeConfig: R) => R & {
202
- getRoutingPath(): RoutingPath<R['path']>;
208
+ getRoutingPath(): RoutingPath<R["path"]>;
203
209
  };
204
210
 
205
211
  export { type DeepSimplify, type Hook, type MiddlewareToHandlerType, type OfHandlerType, OpenAPIHono, type OpenAPIHonoOptions, type OpenAPIObjectConfigure, type RouteConfig, type RouteConfigToEnv, type RouteConfigToTypedResponse, type RouteHandler, type RouteHook, createRoute };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,14 @@
1
1
  import * as openapi3_ts_oas31 from 'openapi3-ts/oas31';
2
+ import * as _asteasolutions_zod_to_openapi_dist_v3_1_openapi_generator from '@asteasolutions/zod-to-openapi/dist/v3.1/openapi-generator';
2
3
  import * as openapi3_ts_oas30 from 'openapi3-ts/oas30';
3
- import { RouteConfig as RouteConfig$1, ZodMediaTypeObject, OpenAPIRegistry, ZodRequestBody, ZodContentObject, OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi';
4
+ import * as _asteasolutions_zod_to_openapi_dist_v3_0_openapi_generator from '@asteasolutions/zod-to-openapi/dist/v3.0/openapi-generator';
5
+ import { RouteConfig as RouteConfig$1, ZodRequestBody, ZodContentObject, ZodMediaTypeObject, OpenApiGeneratorV3, OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
4
6
  export { extendZodWithOpenApi } from '@asteasolutions/zod-to-openapi';
5
7
  import { MiddlewareHandler, TypedResponse, Env, ValidationTargets, Context, Input, Handler, Schema, Hono, ToSchema } from 'hono';
6
8
  import { MergePath, MergeSchemaPath } from 'hono/types';
7
- import { StatusCode, InfoStatusCode, SuccessStatusCode, RedirectStatusCode, ClientErrorStatusCode, ServerErrorStatusCode } from 'hono/utils/http-status';
8
- import { RemoveBlankRecord, SimplifyDeepArray, JSONValue, JSONParsed } from 'hono/utils/types';
9
- import { ZodError, ZodType, z, ZodSchema } from 'zod';
9
+ import { InfoStatusCode, SuccessStatusCode, RedirectStatusCode, ClientErrorStatusCode, ServerErrorStatusCode, StatusCode } from 'hono/utils/http-status';
10
+ import { SimplifyDeepArray, JSONValue, JSONParsed, RemoveBlankRecord } from 'hono/utils/types';
11
+ import { ZodSchema, z, ZodError, ZodType } from 'zod';
10
12
  export { z } from 'zod';
11
13
 
12
14
  type MaybePromise<T> = Promise<T> | T;
@@ -72,8 +74,12 @@ type RouteConfigStatusCode = keyof StatusCodeRangeDefinitions | StatusCode;
72
74
  type ExtractStatusCode<T extends RouteConfigStatusCode> = T extends keyof StatusCodeRangeDefinitions ? StatusCodeRangeDefinitions[T] : T;
73
75
  type DefinedStatusCodes<R extends RouteConfig> = keyof R['responses'] & RouteConfigStatusCode;
74
76
  type RouteConfigToTypedResponse<R extends RouteConfig> = {
75
- [Status in DefinedStatusCodes<R>]: undefined extends R['responses'][Status]['content'] ? TypedResponse<{}, ExtractStatusCode<Status>, string> : ReturnJsonOrTextOrResponse<keyof R['responses'][Status]['content'], ExtractContent<R['responses'][Status]['content']>, Status>;
76
- }[DefinedStatusCodes<R>] | ('default' extends keyof R['responses'] ? undefined extends R['responses']['default']['content'] ? TypedResponse<{}, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>, string> : ReturnJsonOrTextOrResponse<keyof R['responses']['default']['content'], ExtractContent<R['responses']['default']['content']>, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>> : never);
77
+ [Status in DefinedStatusCodes<R>]: R['responses'][Status] extends {
78
+ content: infer Content;
79
+ } ? undefined extends Content ? never : ReturnJsonOrTextOrResponse<keyof R['responses'][Status]['content'], ExtractContent<R['responses'][Status]['content']>, Status> : TypedResponse<{}, ExtractStatusCode<Status>, string>;
80
+ }[DefinedStatusCodes<R>] | ('default' extends keyof R['responses'] ? R['responses']['default'] extends {
81
+ content: infer Content;
82
+ } ? undefined extends Content ? never : ReturnJsonOrTextOrResponse<keyof Content, ExtractContent<Content>, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>> : TypedResponse<{}, Exclude<StatusCode, ExtractStatusCode<DefinedStatusCodes<R>>>, string> : never);
77
83
  type Hook<T, E extends Env, P extends string, R> = (result: {
78
84
  target: keyof ValidationTargets;
79
85
  } & ({
@@ -120,7 +126,7 @@ type MiddlewareToHandlerType<M extends MiddlewareHandler<any, any, any>[]> = M e
120
126
  OfHandlerType<First>['path'], // Keep path from First
121
127
  OfHandlerType<First>['input']>,
122
128
  ...Rest
123
- ]> : never : never : never : M extends [infer Last] ? Last : never;
129
+ ]> : never : never : never : M extends [infer Last] ? Last : MiddlewareHandler<Env>;
124
130
  type RouteMiddlewareParams<R extends RouteConfig> = OfHandlerType<MiddlewareToHandlerType<AsArray<R['middleware']>>>;
125
131
  type RouteConfigToEnv<R extends RouteConfig> = RouteMiddlewareParams<R> extends never ? Env : RouteMiddlewareParams<R>['env'];
126
132
  type RouteHandler<R extends RouteConfig, E extends Env = RouteConfigToEnv<R>, I extends Input = InputTypeParam<R> & InputTypeQuery<R> & InputTypeHeader<R> & InputTypeCookie<R> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R['path']>> = Handler<E, P, I, R extends {
@@ -170,7 +176,7 @@ declare class OpenAPIHono<E extends Env = Env, S extends Schema = {}, BasePath e
170
176
  * }
171
177
  *)
172
178
  */
173
- openapi: <R extends RouteConfig, I extends Input = InputTypeBase<R, "params", "param"> & InputTypeBase<R, "query", "query"> & InputTypeBase<R, "headers", "header"> & InputTypeBase<R, "cookies", "cookie"> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R["path"]>>({ middleware: routeMiddleware, hide, ...route }: R, handler: Handler<R['middleware'] extends MiddlewareHandler[] | MiddlewareHandler ? RouteMiddlewareParams<R>['env'] & E : E, P, I, R extends {
179
+ openapi: <R extends RouteConfig, I extends Input = InputTypeParam<R> & InputTypeQuery<R> & InputTypeHeader<R> & InputTypeCookie<R> & InputTypeForm<R> & InputTypeJson<R>, P extends string = ConvertPathType<R["path"]>>({ middleware: routeMiddleware, hide, ...route }: R, handler: Handler<R["middleware"] extends MiddlewareHandler[] | MiddlewareHandler ? RouteMiddlewareParams<R>["env"] & E : E, P, I, R extends {
174
180
  responses: {
175
181
  [statusCode: number]: {
176
182
  content: {
@@ -186,11 +192,11 @@ declare class OpenAPIHono<E extends Env = Env, S extends Schema = {}, BasePath e
186
192
  };
187
193
  };
188
194
  };
189
- } ? MaybePromise<RouteConfigToTypedResponse<R>> | undefined : MaybePromise<RouteConfigToTypedResponse<R>> | MaybePromise<Response> | undefined> | undefined) => OpenAPIHono<E, S & ToSchema<R['method'], MergePath<BasePath, P>, I, RouteConfigToTypedResponse<R>>, BasePath>;
190
- getOpenAPIDocument: (config: OpenAPIObjectConfig) => openapi3_ts_oas30.OpenAPIObject;
191
- getOpenAPI31Document: (config: OpenAPIObjectConfig) => openapi3_ts_oas31.OpenAPIObject;
192
- doc: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath>;
193
- doc31: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<'get', P, {}, {}>, BasePath>;
195
+ } ? MaybePromise<RouteConfigToTypedResponse<R>> | undefined : MaybePromise<RouteConfigToTypedResponse<R>> | MaybePromise<Response> | undefined> | undefined) => OpenAPIHono<E, S & ToSchema<R["method"], MergePath<BasePath, P>, I, RouteConfigToTypedResponse<R>>, BasePath>;
196
+ getOpenAPIDocument: (config: OpenAPIObjectConfig) => ReturnType<(config: _asteasolutions_zod_to_openapi_dist_v3_0_openapi_generator.OpenAPIObjectConfig) => openapi3_ts_oas30.OpenAPIObject>;
197
+ getOpenAPI31Document: (config: OpenAPIObjectConfig) => ReturnType<(config: _asteasolutions_zod_to_openapi_dist_v3_1_openapi_generator.OpenAPIObjectConfigV31) => openapi3_ts_oas31.OpenAPIObject>;
198
+ doc: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<"get", P, {}, {}>, BasePath>;
199
+ doc31: <P extends string>(path: P, configure: OpenAPIObjectConfigure<E, P>) => OpenAPIHono<E, S & ToSchema<"get", P, {}, {}>, BasePath>;
194
200
  route<SubPath extends string, SubEnv extends Env, SubSchema extends Schema, SubBasePath extends string>(path: SubPath, app: Hono<SubEnv, SubSchema, SubBasePath>): OpenAPIHono<E, MergeSchemaPath<SubSchema, MergePath<BasePath, SubPath>> & S, BasePath>;
195
201
  route<SubPath extends string>(path: SubPath): Hono<E, RemoveBlankRecord<S>, BasePath>;
196
202
  basePath<SubPath extends string>(path: SubPath): OpenAPIHono<E, S, MergePath<BasePath, SubPath>>;
@@ -199,7 +205,7 @@ type RoutingPath<P extends string> = P extends `${infer Head}/{${infer Param}}${
199
205
  declare const createRoute: <P extends string, R extends Omit<RouteConfig, "path"> & {
200
206
  path: P;
201
207
  }>(routeConfig: R) => R & {
202
- getRoutingPath(): RoutingPath<R['path']>;
208
+ getRoutingPath(): RoutingPath<R["path"]>;
203
209
  };
204
210
 
205
211
  export { type DeepSimplify, type Hook, type MiddlewareToHandlerType, type OfHandlerType, OpenAPIHono, type OpenAPIHonoOptions, type OpenAPIObjectConfigure, type RouteConfig, type RouteConfigToEnv, type RouteConfigToTypedResponse, type RouteHandler, type RouteHook, createRoute };
package/dist/index.js CHANGED
@@ -1,42 +1,20 @@
1
- "use strict";
2
- var __defProp = Object.defineProperty;
3
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
- var __getOwnPropNames = Object.getOwnPropertyNames;
5
- 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
- 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;
17
- };
18
- var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
-
20
1
  // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
23
- OpenAPIHono: () => OpenAPIHono,
24
- createRoute: () => createRoute,
25
- extendZodWithOpenApi: () => import_zod_to_openapi.extendZodWithOpenApi,
26
- z: () => import_zod.z
27
- });
28
- module.exports = __toCommonJS(src_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");
34
- var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
2
+ import {
3
+ OpenAPIRegistry,
4
+ OpenApiGeneratorV3,
5
+ OpenApiGeneratorV31,
6
+ extendZodWithOpenApi
7
+ } from "@asteasolutions/zod-to-openapi";
8
+ import { zValidator } from "@hono/zod-validator";
9
+ import { Hono } from "hono";
10
+ import { mergePath } from "hono/utils/url";
11
+ import { ZodType, z } from "zod";
12
+ var OpenAPIHono = class _OpenAPIHono extends Hono {
35
13
  openAPIRegistry;
36
14
  defaultHook;
37
15
  constructor(init) {
38
16
  super(init);
39
- this.openAPIRegistry = new import_zod_to_openapi.OpenAPIRegistry();
17
+ this.openAPIRegistry = new OpenAPIRegistry();
40
18
  this.defaultHook = init?.defaultHook;
41
19
  }
42
20
  /**
@@ -76,19 +54,19 @@ var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
76
54
  }
77
55
  const validators = [];
78
56
  if (route.request?.query) {
79
- const validator = (0, import_zod_validator.zValidator)("query", route.request.query, hook);
57
+ const validator = zValidator("query", route.request.query, hook);
80
58
  validators.push(validator);
81
59
  }
82
60
  if (route.request?.params) {
83
- const validator = (0, import_zod_validator.zValidator)("param", route.request.params, hook);
61
+ const validator = zValidator("param", route.request.params, hook);
84
62
  validators.push(validator);
85
63
  }
86
64
  if (route.request?.headers) {
87
- const validator = (0, import_zod_validator.zValidator)("header", route.request.headers, hook);
65
+ const validator = zValidator("header", route.request.headers, hook);
88
66
  validators.push(validator);
89
67
  }
90
68
  if (route.request?.cookies) {
91
- const validator = (0, import_zod_validator.zValidator)("cookie", route.request.cookies, hook);
69
+ const validator = zValidator("cookie", route.request.cookies, hook);
92
70
  validators.push(validator);
93
71
  }
94
72
  const bodyContent = route.request?.body?.content;
@@ -98,11 +76,11 @@ var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
98
76
  continue;
99
77
  }
100
78
  const schema = bodyContent[mediaType]["schema"];
101
- if (!(schema instanceof import_zod.ZodType)) {
79
+ if (!(schema instanceof ZodType)) {
102
80
  continue;
103
81
  }
104
82
  if (isJSONContentType(mediaType)) {
105
- const validator = (0, import_zod_validator.zValidator)("json", schema, hook);
83
+ const validator = zValidator("json", schema, hook);
106
84
  if (route.request?.body?.required) {
107
85
  validators.push(validator);
108
86
  } else {
@@ -119,7 +97,7 @@ var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
119
97
  }
120
98
  }
121
99
  if (isFormContentType(mediaType)) {
122
- const validator = (0, import_zod_validator.zValidator)("form", schema, hook);
100
+ const validator = zValidator("form", schema, hook);
123
101
  if (route.request?.body?.required) {
124
102
  validators.push(validator);
125
103
  } else {
@@ -148,12 +126,12 @@ var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
148
126
  return this;
149
127
  };
150
128
  getOpenAPIDocument = (config) => {
151
- const generator = new import_zod_to_openapi.OpenApiGeneratorV3(this.openAPIRegistry.definitions);
129
+ const generator = new OpenApiGeneratorV3(this.openAPIRegistry.definitions);
152
130
  const document = generator.generateDocument(config);
153
131
  return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
154
132
  };
155
133
  getOpenAPI31Document = (config) => {
156
- const generator = new import_zod_to_openapi.OpenApiGeneratorV31(this.openAPIRegistry.definitions);
134
+ const generator = new OpenApiGeneratorV31(this.openAPIRegistry.definitions);
157
135
  const document = generator.generateDocument(config);
158
136
  return this._basePath ? addBasePathToDocument(document, this._basePath) : document;
159
137
  };
@@ -192,20 +170,20 @@ var OpenAPIHono = class _OpenAPIHono extends import_hono.Hono {
192
170
  case "route":
193
171
  return this.openAPIRegistry.registerPath({
194
172
  ...def.route,
195
- path: (0, import_url.mergePath)(
173
+ path: mergePath(
196
174
  pathForOpenAPI,
197
175
  // @ts-expect-error _basePath is private
198
- app._basePath,
176
+ app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"),
199
177
  def.route.path
200
178
  )
201
179
  });
202
180
  case "webhook":
203
181
  return this.openAPIRegistry.registerWebhook({
204
182
  ...def.webhook,
205
- path: (0, import_url.mergePath)(
183
+ path: mergePath(
206
184
  pathForOpenAPI,
207
185
  // @ts-expect-error _basePath is private
208
- app._basePath,
186
+ app._basePath.replaceAll(/:([^\/]+)/g, "{$1}"),
209
187
  def.webhook.path
210
188
  )
211
189
  });
@@ -237,11 +215,11 @@ var createRoute = (routeConfig) => {
237
215
  };
238
216
  return Object.defineProperty(route, "getRoutingPath", { enumerable: false });
239
217
  };
240
- (0, import_zod_to_openapi.extendZodWithOpenApi)(import_zod.z);
218
+ extendZodWithOpenApi(z);
241
219
  function addBasePathToDocument(document, basePath) {
242
220
  const updatedPaths = {};
243
221
  Object.keys(document.paths).forEach((path) => {
244
- updatedPaths[(0, import_url.mergePath)(basePath.replaceAll(/:([^\/]+)/g, "{$1}"), path)] = document.paths[path];
222
+ updatedPaths[mergePath(basePath.replaceAll(/:([^\/]+)/g, "{$1}"), path)] = document.paths[path];
245
223
  });
246
224
  return {
247
225
  ...document,
@@ -254,10 +232,9 @@ function isJSONContentType(contentType) {
254
232
  function isFormContentType(contentType) {
255
233
  return contentType.startsWith("multipart/form-data") || contentType.startsWith("application/x-www-form-urlencoded");
256
234
  }
257
- // Annotate the CommonJS export names for ESM import in node:
258
- 0 && (module.exports = {
235
+ export {
259
236
  OpenAPIHono,
260
237
  createRoute,
261
238
  extendZodWithOpenApi,
262
239
  z
263
- });
240
+ };
package/package.json CHANGED
@@ -1,28 +1,29 @@
1
1
  {
2
2
  "name": "@hono/zod-openapi",
3
- "version": "0.19.1",
3
+ "version": "0.19.3",
4
4
  "description": "A wrapper class of Hono which supports OpenAPI.",
5
- "main": "dist/index.js",
6
- "module": "dist/index.mjs",
5
+ "type": "module",
6
+ "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "files": [
9
9
  "dist"
10
10
  ],
11
11
  "scripts": {
12
- "test": "vitest run && vitest --typecheck --run --passWithNoTests",
13
- "build": "tsup ./src/index.ts --format esm,cjs --dts",
14
- "publint": "publint",
15
- "release": "yarn build && yarn test && yarn publint && yarn publish"
12
+ "build": "tsup ./src/index.ts",
13
+ "prepack": "yarn build",
14
+ "publint": "attw --pack && publint",
15
+ "typecheck": "tsc -b tsconfig.json",
16
+ "test": "vitest"
16
17
  },
17
18
  "exports": {
18
19
  ".": {
19
20
  "import": {
20
- "types": "./dist/index.d.mts",
21
- "default": "./dist/index.mjs"
22
- },
23
- "require": {
24
21
  "types": "./dist/index.d.ts",
25
22
  "default": "./dist/index.js"
23
+ },
24
+ "require": {
25
+ "types": "./dist/index.d.cts",
26
+ "default": "./dist/index.cjs"
26
27
  }
27
28
  }
28
29
  },
@@ -33,7 +34,8 @@
33
34
  },
34
35
  "repository": {
35
36
  "type": "git",
36
- "url": "https://github.com/honojs/middleware.git"
37
+ "url": "git+https://github.com/honojs/middleware.git",
38
+ "directory": "packages/zod-openapi"
37
39
  },
38
40
  "homepage": "https://github.com/honojs/middleware",
39
41
  "peerDependencies": {
@@ -41,18 +43,17 @@
41
43
  "zod": "3.*"
42
44
  },
43
45
  "devDependencies": {
44
- "@cloudflare/workers-types": "^4.20240117.0",
45
- "hono": "^4.6.10",
46
- "jest": "^29.7.0",
47
- "tsup": "^8.0.1",
48
- "typescript": "^5.4.4",
49
- "vitest": "^1.4.0",
46
+ "@arethetypeswrong/cli": "^0.17.4",
47
+ "publint": "^0.3.9",
48
+ "tsup": "^8.4.0",
49
+ "typescript": "^5.8.2",
50
+ "vitest": "^3.0.8",
50
51
  "yaml": "^2.4.3",
51
52
  "zod": "^3.22.1"
52
53
  },
53
54
  "dependencies": {
54
55
  "@asteasolutions/zod-to-openapi": "^7.1.0",
55
- "@hono/zod-validator": "^0.4.1"
56
+ "@hono/zod-validator": "workspace:^"
56
57
  },
57
58
  "engines": {
58
59
  "node": ">=16.0.0"