Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
changeKind: feature
packages:
- "@typespec/openapi3"
---

Add support for defining enums with multiple types in Open API 3.1
6 changes: 2 additions & 4 deletions packages/openapi3/src/schema-emitter-3-1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,10 @@ export class OpenAPI31SchemaEmitter extends OpenAPI3SchemaEmitterBase<OpenAPISch
enumValues.add(member.value ?? member.name);
}

if (enumTypes.size > 1) {
reportDiagnostic(program, { code: "enum-unique-type", target: en });
}
const enumTypesArray = [...enumTypes];

const schema: OpenAPISchema3_1 = {
type: enumTypes.values().next().value!,
type: enumTypesArray.length === 1 ? enumTypesArray[0] : enumTypesArray,
enum: [...enumValues],
};

Expand Down
39 changes: 26 additions & 13 deletions packages/openapi3/test/enums.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { expectDiagnostics } from "@typespec/compiler/testing";
import { strictEqual } from "assert";
import { describe, it } from "vitest";
import { diagnoseOpenApiFor, oapiForModel } from "./test-host.js";
import { deepStrictEqual, strictEqual } from "assert";
import { it } from "vitest";
import { worksFor } from "./works-for.js";

describe("openapi3: enums", () => {
worksFor(["3.0.0", "3.1.0"], ({ diagnoseOpenApiFor, oapiForModel }) => {
it("throws diagnostics for empty enum definitions", async () => {
const diagnostics = await diagnoseOpenApiFor(`enum PetType {}`);

Expand All @@ -13,15 +13,6 @@ describe("openapi3: enums", () => {
});
});

it("throws diagnostics for enum with different types", async () => {
const diagnostics = await diagnoseOpenApiFor(`enum PetType {asString: "dog", asNumber: 1}`);

expectDiagnostics(diagnostics, {
code: "@typespec/openapi3/enum-unique-type",
message: "Enums are not supported unless all options are literals of the same type.",
});
});

it("supports summary on enums", async () => {
const res = await oapiForModel(
"Foo",
Expand All @@ -35,3 +26,25 @@ describe("openapi3: enums", () => {
strictEqual(res.schemas.Foo.title, "FooEnum");
});
});

worksFor(["3.0.0"], ({ diagnoseOpenApiFor }) => {
it("throws diagnostics for enum with different types", async () => {
const diagnostics = await diagnoseOpenApiFor(`enum PetType {asString: "dog", asNumber: 1}`);

expectDiagnostics(diagnostics, {
code: "@typespec/openapi3/enum-unique-type",
message: "Enums are not supported unless all options are literals of the same type.",
});
});
});

worksFor(["3.1.0"], ({ oapiForModel }) => {
it("supports enum with different types", async () => {
const res = await oapiForModel("PetType", `enum PetType {asString: "dog", asNumber: 1}`);

deepStrictEqual(res.schemas.PetType, {
type: ["string", "number"],
enum: ["dog", 1],
});
});
});