Skip to content

Commit 96e0d96

Browse files
feat: completed the response handler middleware
1 parent 381ccd7 commit 96e0d96

File tree

1 file changed

+46
-38
lines changed

1 file changed

+46
-38
lines changed

src/middlewares.ts

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,8 @@ import type {
1010
Next,
1111
ValidationTargets,
1212
} from "hono";
13-
import type { BlankInput, ResponseFormat } from "hono/types";
13+
import type { BlankInput, TypedResponse } from "hono/types";
1414
import type { StatusCode } from "hono/utils/http-status";
15-
import type { JSONValue } from "hono/utils/types";
1615
import type { OpenAPIV3_1 } from "openapi-types";
1716
import type { DescribeRouteOptions, PromiseOr } from "./types";
1817
import { uniqueSymbol } from "./utils";
@@ -50,17 +49,14 @@ export function validator<
5049
In = StandardSchemaV1.InferInput<Schema>,
5150
Out = StandardSchemaV1.InferOutput<Schema>,
5251
I extends Input = {
53-
in: HasUndefined<In> extends true
54-
? {
55-
[K in Target]?: In extends ValidationTargets[K]
56-
? In
57-
: { [K2 in keyof In]?: ValidationTargets[K][K2] };
58-
}
52+
in: HasUndefined<In> extends true ? {
53+
[K in Target]?: In extends ValidationTargets[K] ? In
54+
: { [K2 in keyof In]?: ValidationTargets[K][K2] };
55+
}
5956
: {
60-
[K in Target]: In extends ValidationTargets[K]
61-
? In
62-
: { [K2 in keyof In]: ValidationTargets[K][K2] };
63-
};
57+
[K in Target]: In extends ValidationTargets[K] ? In
58+
: { [K2 in keyof In]: ValidationTargets[K][K2] };
59+
};
6460
out: { [K in Target]: Out };
6561
},
6662
V extends I = I,
@@ -103,26 +99,12 @@ type ResponseObject<T extends Partial<Record<StatusCode, StandardSchemaV1>>> = {
10399
[K in keyof T]:
104100
| OpenAPIV3_1.ReferenceObject
105101
| (OpenAPIV3_1.ResponseObject & {
106-
content?: {
107-
[media: string]: OpenAPIV3_1.MediaTypeObject & {
108-
vSchema?: T[K];
109-
};
102+
content?: {
103+
[media: string]: OpenAPIV3_1.MediaTypeObject & {
104+
vSchema?: T[K];
110105
};
111-
});
112-
};
113-
114-
type TypedResponse<
115-
T = unknown,
116-
U extends StatusCode = StatusCode,
117-
F extends ResponseFormat = T extends string
118-
? "text"
119-
: T extends JSONValue
120-
? "json"
121-
: ResponseFormat,
122-
> = {
123-
_data: T;
124-
_status: U;
125-
_format: F;
106+
};
107+
});
126108
};
127109

128110
type Num<T> = T extends `${infer N extends number}` ? N : T;
@@ -132,13 +114,12 @@ type HandlerResponse<
132114
Record<StatusCode, StandardSchemaV1>
133115
>,
134116
> = {
135-
[K in keyof T]: T[K] extends StandardSchemaV1
136-
? PromiseOr<
137-
TypedResponse<
138-
StandardSchemaV1.InferOutput<T[K]>,
139-
Num<K> extends StatusCode ? Num<K> : never
140-
>
117+
[K in keyof T]: T[K] extends StandardSchemaV1 ? PromiseOr<
118+
TypedResponse<
119+
StandardSchemaV1.InferOutput<T[K]>,
120+
Num<K> extends StatusCode ? Num<K> : never
141121
>
122+
>
142123
: never;
143124
}[keyof T];
144125

@@ -162,9 +143,36 @@ export function describeResponse<
162143
handler: Handler<E, P, I, T>,
163144
responses: ResponseObject<T>,
164145
): Handler<E, P, I, T> {
146+
const _responses = Object.entries(responses).reduce(
147+
(acc, [statusCode, response]) => {
148+
if (response.content) {
149+
const content = Object.entries(response.content).reduce(
150+
(contentAcc, [mediaType, media]: [string, any]) => {
151+
if (media.vSchema) {
152+
contentAcc[mediaType] = {
153+
...media,
154+
schema: resolver(media.vSchema),
155+
};
156+
} else {
157+
contentAcc[mediaType] = media;
158+
}
159+
return contentAcc;
160+
},
161+
{},
162+
);
163+
acc[statusCode] = { ...response, content };
164+
} else {
165+
acc[statusCode] = response;
166+
}
167+
168+
return acc;
169+
},
170+
{} as NonNullable<DescribeRouteOptions["responses"]>,
171+
);
172+
165173
return Object.assign(handler, {
166174
[uniqueSymbol]: {
167-
spec: { responses },
175+
spec: { responses: _responses },
168176
},
169177
});
170178
}

0 commit comments

Comments
 (0)