From de763ceb0f69c994006fef74273b1bdea55e05f9 Mon Sep 17 00:00:00 2001 From: Alitzel Mendez <6895254+AlitzelMendez@users.noreply.github.com> Date: Mon, 14 Oct 2024 14:12:29 -0700 Subject: [PATCH] Mark discriminator properties consistently as requiered (#4663) Co-authored-by: Timothee Guerin --- ...r-should-be-requiered-2024-9-9-17-24-19.md | 7 ++++++ packages/openapi3/src/schema-emitter.ts | 7 ++++++ packages/openapi3/test/discriminator.test.ts | 22 +++++++++++++++---- .../@typespec/openapi3/openapi.yaml | 1 + .../@typespec/openapi3/openapi.v1.yaml | 1 + .../@typespec/openapi3/openapi.v2.yaml | 1 + 6 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 .chronus/changes/fix-discriminator-should-be-requiered-2024-9-9-17-24-19.md diff --git a/.chronus/changes/fix-discriminator-should-be-requiered-2024-9-9-17-24-19.md b/.chronus/changes/fix-discriminator-should-be-requiered-2024-9-9-17-24-19.md new file mode 100644 index 0000000000..d854fd90d3 --- /dev/null +++ b/.chronus/changes/fix-discriminator-should-be-requiered-2024-9-9-17-24-19.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/openapi3" +--- + +Discriminator properties are marked as required regardless if they are in TypeSpec to match OpenAPI3 spec. diff --git a/packages/openapi3/src/schema-emitter.ts b/packages/openapi3/src/schema-emitter.ts index 71c34c3fe9..90446bf0df 100644 --- a/packages/openapi3/src/schema-emitter.ts +++ b/packages/openapi3/src/schema-emitter.ts @@ -295,6 +295,13 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter< } } + const discriminator = getDiscriminator(this.emitter.getProgram(), model); + if (discriminator) { + if (!requiredProps.includes(discriminator.propertyName)) { + requiredProps.push(discriminator.propertyName); + } + } + return requiredProps.length > 0 ? requiredProps : undefined; } diff --git a/packages/openapi3/test/discriminator.test.ts b/packages/openapi3/test/discriminator.test.ts index 0d2bb8f4aa..88192cd26f 100644 --- a/packages/openapi3/test/discriminator.test.ts +++ b/packages/openapi3/test/discriminator.test.ts @@ -103,7 +103,7 @@ describe("openapi3: polymorphic model inheritance with discriminator", () => { name: { type: "string" }, weight: { type: "number", format: "float" }, }, - required: ["name"], + required: ["name", "kind"], discriminator: { propertyName: "kind", mapping: { @@ -154,7 +154,7 @@ describe("openapi3: polymorphic model inheritance with discriminator", () => { }, weight: { type: "number", format: "float" }, }, - required: ["name"], + required: ["name", "kind"], discriminator: { propertyName: "kind", mapping: { @@ -215,7 +215,7 @@ describe("openapi3: polymorphic model inheritance with discriminator", () => { name: { type: "string" }, weight: { type: "number", format: "float" }, }, - required: ["name"], + required: ["name", "kind"], discriminator: { propertyName: "kind", mapping: { @@ -234,7 +234,7 @@ describe("openapi3: polymorphic model inheritance with discriminator", () => { }, bark: { type: "string" }, }, - required: ["kind", "bark"], + required: ["kind", "bark", "breed"], allOf: [{ $ref: "#/components/schemas/Pet" }], discriminator: { propertyName: "breed", @@ -344,4 +344,18 @@ describe("openapi3: polymorphic model inheritance with discriminator", () => { }, ]); }); + + it("discriminator always needs to be marked as required", async () => { + const openApi = await openApiFor(` + @discriminator("kind") + model Animal { + id: string; + kind?: string; + }`); + + deepStrictEqual(openApi.components.schemas.Animal.required, ["id", "kind"]); + deepStrictEqual(openApi.components.schemas.Animal.discriminator, { + propertyName: "kind", + }); + }); }); diff --git a/packages/samples/test/output/polymorphism/@typespec/openapi3/openapi.yaml b/packages/samples/test/output/polymorphism/@typespec/openapi3/openapi.yaml index 6e9172b3a2..b8a536d4cc 100644 --- a/packages/samples/test/output/polymorphism/@typespec/openapi3/openapi.yaml +++ b/packages/samples/test/output/polymorphism/@typespec/openapi3/openapi.yaml @@ -50,6 +50,7 @@ components: type: object required: - name + - kind properties: name: type: string diff --git a/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v1.yaml b/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v1.yaml index 8befefdcfb..48b989550b 100644 --- a/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v1.yaml +++ b/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v1.yaml @@ -63,6 +63,7 @@ components: required: - name - favoriteToys + - type properties: name: type: string diff --git a/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v2.yaml b/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v2.yaml index 10b519e5f0..01e3552978 100644 --- a/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v2.yaml +++ b/packages/samples/test/output/versioning/@typespec/openapi3/openapi.v2.yaml @@ -85,6 +85,7 @@ components: required: - name - favoriteToys + - type properties: name: type: string