diff --git a/.changeset/proud-pugs-clean.md b/.changeset/proud-pugs-clean.md new file mode 100644 index 000000000..4d27faecb --- /dev/null +++ b/.changeset/proud-pugs-clean.md @@ -0,0 +1,5 @@ +--- +"openapi-typescript": patch +--- + +fix: keyedParameters use unique key diff --git a/packages/openapi-typescript/src/transform/path-item-object.ts b/packages/openapi-typescript/src/transform/path-item-object.ts index 04aca3cd3..c57129893 100644 --- a/packages/openapi-typescript/src/transform/path-item-object.ts +++ b/packages/openapi-typescript/src/transform/path-item-object.ts @@ -53,7 +53,11 @@ export default function transformPathItemObject(pathItem: PathItemObject, option if (!("$ref" in operationObject)) { // important: OperationObject parameters come last, and will override any conflicts with PathItem parameters for (const parameter of [...(pathItem.parameters ?? []), ...(operationObject.parameters ?? [])]) { - const name = "$ref" in parameter ? options.ctx.resolve(parameter.$ref)?.name : parameter.name; + // fix: #1798, use unique key + const name = + "$ref" in parameter + ? `${options.ctx.resolve(parameter.$ref)?.in}-${options.ctx.resolve(parameter.$ref)?.name}` + : `${parameter.in}-${parameter.name}`; if (name) { keyedParameters[name] = parameter; } diff --git a/packages/openapi-typescript/test/transform/path-item-object.test.ts b/packages/openapi-typescript/test/transform/path-item-object.test.ts index ed0e697e3..1b3efea95 100644 --- a/packages/openapi-typescript/test/transform/path-item-object.test.ts +++ b/packages/openapi-typescript/test/transform/path-item-object.test.ts @@ -359,6 +359,66 @@ describe("transformPathItemObject", () => { }, }, ], + [ + "parameters > header and cookie have same name param1", + { + given: { + get: { + parameters: [ + { + name: "param1", + in: "header", + required: true, + schema: { + type: "string", + }, + description: "param1", + }, + { + name: "param1", + in: "cookie", + required: true, + schema: { + type: "string", + }, + description: "param1", + }, + ], + }, + }, + want: `{ + parameters: { + query?: never; + header?: never; + path?: never; + cookie?: never; + }; + get: { + parameters: { + query?: never; + header: { + /** @description param1 */ + param1: string; + }; + path?: never; + cookie: { + /** @description param1 */ + param1: string; + }; + }; + requestBody?: never; + responses: never; + }; + put?: never; + post?: never; + delete?: never; + options?: never; + head?: never; + patch?: never; + trace?: never; +}`, + }, + ], ]; for (const [testName, { given, want, options = DEFAULT_OPTIONS, ci }] of tests) {