diff --git a/.chronus/changes/fix-openapi3-union-names-2024-7-8-8-5-28.md b/.chronus/changes/fix-openapi3-union-names-2024-7-8-8-5-28.md new file mode 100644 index 0000000000..1e12651d04 --- /dev/null +++ b/.chronus/changes/fix-openapi3-union-names-2024-7-8-8-5-28.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/openapi3" +--- + +Fix OpenAPI3 union names when declared within a namespace diff --git a/packages/openapi3/src/schema-emitter.ts b/packages/openapi3/src/schema-emitter.ts index 04b276afbd..36a2993220 100644 --- a/packages/openapi3/src/schema-emitter.ts +++ b/packages/openapi3/src/schema-emitter.ts @@ -475,7 +475,8 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter< unionDeclaration(union: Union, name: string): EmitterOutput { const schema = this.#unionSchema(union); - return this.#createDeclaration(union, name, schema); + const baseName = getOpenAPITypeName(this.emitter.getProgram(), union, this.#typeNameOptions()); + return this.#createDeclaration(union, baseName, schema); } #unionSchema(union: Union): ObjectBuilder { diff --git a/packages/openapi3/test/union-schema.test.ts b/packages/openapi3/test/union-schema.test.ts index a30fec1637..3354a6ccf7 100644 --- a/packages/openapi3/test/union-schema.test.ts +++ b/packages/openapi3/test/union-schema.test.ts @@ -396,6 +396,63 @@ describe("openapi3: union type", () => { }); }); + it("handles unions defined in a namespace", async () => { + const res = await openApiFor(` + namespace Foo { + model A { + foo: string; + } + } + + namespace Bar { + model A { + bar: string; + } + } + + namespace Baz { + union A { + foo: Foo.A, + bar: Bar.A + } + } + + @get + op getFoo(data: Baz.A): {}; + `); + + deepStrictEqual(res.components.schemas["Foo.A"], { + properties: { + foo: { + type: "string", + }, + }, + required: ["foo"], + type: "object", + }); + + deepStrictEqual(res.components.schemas["Bar.A"], { + properties: { + bar: { + type: "string", + }, + }, + required: ["bar"], + type: "object", + }); + + deepStrictEqual(res.components.schemas["Baz.A"], { + anyOf: [ + { + $ref: "#/components/schemas/Foo.A", + }, + { + $ref: "#/components/schemas/Bar.A", + }, + ], + }); + }); + it("throws diagnostics for empty enum definitions", async () => { const diagnostics = await diagnoseOpenApiFor(`union Pet {}`);