Skip to content

Commit c14e40d

Browse files
Merge branch 'main' into fix/operationid-pascalcase
2 parents a83140a + 780d234 commit c14e40d

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

src/__tests__/zodv4.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,42 @@ describe("zod v4", () => {
148148

149149
expect(specs).toMatchSnapshot();
150150
});
151+
152+
it("defaultOptions should not cause parameter pollution between routes", async () => {
153+
const app = new Hono()
154+
.get(
155+
"/hello",
156+
describeRoute({}),
157+
validator("query", z.object({ name: z.string() })),
158+
(c) => {
159+
const { name } = c.req.valid("query");
160+
return c.text(`Hello, ${name}!`);
161+
},
162+
)
163+
.get(
164+
"/world",
165+
describeRoute({}),
166+
validator("query", z.object({ greeting: z.string() })),
167+
(c) => {
168+
const { greeting } = c.req.valid("query");
169+
return c.text(`${greeting}, world!`);
170+
},
171+
);
172+
173+
const specs = await generateSpecs(app, {
174+
defaultOptions: {
175+
GET: {},
176+
},
177+
});
178+
179+
// Verify /hello only has 'name' parameter
180+
const helloParams = specs.paths["/hello"]?.get?.parameters;
181+
expect(helloParams).toHaveLength(1);
182+
expect(helloParams?.[0]).toMatchObject({ name: "name", in: "query" });
183+
184+
// Verify /world only has 'greeting' parameter (not 'name' from /hello)
185+
const worldParams = specs.paths["/world"]?.get?.parameters;
186+
expect(worldParams).toHaveLength(1);
187+
expect(worldParams?.[0]).toMatchObject({ name: "greeting", in: "query" });
188+
});
151189
});

src/handler.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,8 +166,9 @@ async function generatePaths<
166166
}
167167
}
168168

169-
const defaultOptionsForThisMethod =
170-
ctx.options.defaultOptions?.[routeMethod];
169+
const defaultOptionsForThisMethod = ctx.options.defaultOptions?.[
170+
routeMethod
171+
] && { ...ctx.options.defaultOptions[routeMethod] };
171172

172173
const { schema: routeSpecs, components = {} } = await getSpec(
173174
middlewareHandler,
@@ -253,7 +254,7 @@ async function getSpec(
253254

254255
const result = await middlewareHandler.toOpenAPISchema();
255256
const docs: Pick<OpenAPIV3_1.OperationObject, "parameters" | "requestBody"> =
256-
defaultOptions ?? {};
257+
{ ...defaultOptions };
257258

258259
if (
259260
middlewareHandler.target === "form" ||

0 commit comments

Comments
 (0)