From 51782b519123c42a3cf2c596dafdcf30016b23f1 Mon Sep 17 00:00:00 2001 From: Timothee Guerin Date: Thu, 31 Oct 2024 12:22:57 -0700 Subject: [PATCH] Use allof when building nullable enum (#4727) fix [#4398](https://github.com/microsoft/typespec/issues/4398) --- ...-nullable-enum-allof-2024-9-14-20-57-59.md | 8 ++++++++ packages/openapi3/src/schema-emitter.ts | 2 +- .../openapi3/test/nullable-properties.test.ts | 2 +- packages/openapi3/test/union-schema.test.ts | 19 ++++++++++++++++++- 4 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 .chronus/changes/fix-openapi3-nullable-enum-allof-2024-9-14-20-57-59.md diff --git a/.chronus/changes/fix-openapi3-nullable-enum-allof-2024-9-14-20-57-59.md b/.chronus/changes/fix-openapi3-nullable-enum-allof-2024-9-14-20-57-59.md new file mode 100644 index 0000000000..618e1116b8 --- /dev/null +++ b/.chronus/changes/fix-openapi3-nullable-enum-allof-2024-9-14-20-57-59.md @@ -0,0 +1,8 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: fix +packages: + - "@typespec/openapi3" +--- + +Nullable enum use `allOf` instead of `oneOf` diff --git a/packages/openapi3/src/schema-emitter.ts b/packages/openapi3/src/schema-emitter.ts index 2341314e47..4ecf08b542 100644 --- a/packages/openapi3/src/schema-emitter.ts +++ b/packages/openapi3/src/schema-emitter.ts @@ -576,7 +576,7 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter< ...additionalProps, }); } else { - return new ObjectBuilder({ oneOf: B.array([schema]), ...additionalProps }); + return new ObjectBuilder({ allOf: B.array([schema]), ...additionalProps }); } } else { const merged = new ObjectBuilder(schema); diff --git a/packages/openapi3/test/nullable-properties.test.ts b/packages/openapi3/test/nullable-properties.test.ts index c7400bcb41..e5dc42ed12 100644 --- a/packages/openapi3/test/nullable-properties.test.ts +++ b/packages/openapi3/test/nullable-properties.test.ts @@ -34,7 +34,7 @@ describe("openapi3: nullable properties", () => { } `, ); - deepStrictEqual(res.schemas.X.properties.prop.oneOf, [ + deepStrictEqual(res.schemas.X.properties.prop.allOf, [ { $ref: "#/components/schemas/A", }, diff --git a/packages/openapi3/test/union-schema.test.ts b/packages/openapi3/test/union-schema.test.ts index 0271a34bc1..7af9f0136d 100644 --- a/packages/openapi3/test/union-schema.test.ts +++ b/packages/openapi3/test/union-schema.test.ts @@ -1,6 +1,6 @@ import { expectDiagnostics } from "@typespec/compiler/testing"; import { deepStrictEqual, ok, strictEqual } from "assert"; -import { describe, it } from "vitest"; +import { describe, expect, it } from "vitest"; import { diagnoseOpenApiFor, oapiForModel, openApiFor } from "./test-host.js"; describe("openapi3: union type", () => { @@ -577,4 +577,21 @@ describe("openapi3: union type", () => { }, }); }); + + describe("null and another single variant produce allOf", () => { + it.each([ + ["model", "model Other {}"], + ["enum", "enum Other {a, b}"], + ])("%s variant", async (_, code) => { + const openApi = await openApiFor(` + union Test { Other, null } + ${code} + `); + + expect(openApi.components.schemas.Test).toMatchObject({ + allOf: [{ $ref: "#/components/schemas/Other" }], + nullable: true, + }); + }); + }); });