From 4ebecc61420b6bd94b3a44b8ea58a85654f7ec5d Mon Sep 17 00:00:00 2001 From: Anthony Skorupskyy <50280805+askorupskyy@users.noreply.github.com> Date: Wed, 27 Nov 2024 19:54:26 -0600 Subject: [PATCH] fix(zod-openapi): multi-middleware complex type inference (#849) --- .changeset/stale-hairs-wonder.md | 5 +++ packages/zod-openapi/src/index.ts | 4 ++- packages/zod-openapi/test/handler.test-d.ts | 36 ++++++++++++++++++++- 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 .changeset/stale-hairs-wonder.md diff --git a/.changeset/stale-hairs-wonder.md b/.changeset/stale-hairs-wonder.md new file mode 100644 index 00000000..ac8bca03 --- /dev/null +++ b/.changeset/stale-hairs-wonder.md @@ -0,0 +1,5 @@ +--- +'@hono/zod-openapi': patch +--- + +Fix multi-middleware complex object type inference diff --git a/packages/zod-openapi/src/index.ts b/packages/zod-openapi/src/index.ts index 74a1562f..0318ef81 100644 --- a/packages/zod-openapi/src/index.ts +++ b/packages/zod-openapi/src/index.ts @@ -221,7 +221,9 @@ type AsArray = T extends undefined // TODO move to utils? */ export type DeepSimplify = { // TODO move to utils? - [KeyType in keyof T]: T[KeyType] extends object ? DeepSimplify : T[KeyType] + [KeyType in keyof T]: T[KeyType] extends Record + ? DeepSimplify + : T[KeyType] } & {} /** diff --git a/packages/zod-openapi/test/handler.test-d.ts b/packages/zod-openapi/test/handler.test-d.ts index 384e9cf6..9e1dea14 100644 --- a/packages/zod-openapi/test/handler.test-d.ts +++ b/packages/zod-openapi/test/handler.test-d.ts @@ -1,5 +1,7 @@ import type { MiddlewareHandler } from 'hono' -import type { RouteHandler } from '../src' +import type { Equal, Expect } from 'hono/utils/types' +import type { MiddlewareToHandlerType, OfHandlerType, RouteHandler } from '../src' + import { OpenAPIHono, createRoute, z } from '../src' describe('supports async handler', () => { @@ -89,4 +91,36 @@ describe('supports async handler', () => { const hono = new OpenAPIHono() hono.openapi(routeWithMiddleware, handler) }) + + test('RouteHandler infers complex objects from multiple middleware handlers', () => { + // https://github.com/honojs/middleware/issues/847 + type CustomEnv = { Variables: { session: { id: string; createdAt: Date } } } + + const setSessionMiddleware: MiddlewareHandler = (c, next) => { + c.set('session', { id: '8e760fe8-f064-4929-b632-737f88213e57', createdAt: new Date() }) + return next() + } + + const validateSessionMiddleware: MiddlewareHandler = async (c, next) => { + const session = c.get('session') + if ((new Date().getTime() - session.createdAt.getTime()) / 1000 / 60 / 60 > 1) { + return c.json({ message: 'Unauthorized' }, 401) + } + return await next() + } + + type Example = MiddlewareToHandlerType< + [typeof setSessionMiddleware, typeof validateSessionMiddleware] + > + + // ensure the first defined env does not lose its type in multi-middleware handler + type Verify = Expect< + Equal< + OfHandlerType['env'], + { + Variables: CustomEnv['Variables'] + } + > + > + }) })