From e04387c7a8162f805feaa265652d964954579b2b Mon Sep 17 00:00:00 2001 From: Konstantin Ershov Date: Wed, 24 Dec 2025 10:04:27 +0100 Subject: [PATCH 1/3] fix: examples for operations with unions and nested enums for versioned services --- packages/openapi3/src/examples.ts | 5 ++- packages/openapi3/test/examples.test.ts | 46 ++++++++++++++++++++++ packages/openapi3/test/versioning.test.ts | 48 +++++++++++++++++++++++ 3 files changed, 98 insertions(+), 1 deletion(-) diff --git a/packages/openapi3/src/examples.ts b/packages/openapi3/src/examples.ts index fdc7ced5ab8..90dfbcc45c4 100644 --- a/packages/openapi3/src/examples.ts +++ b/packages/openapi3/src/examples.ts @@ -266,7 +266,10 @@ export function getExampleOrExamples( ) { const [example, type] = examples[0]; const encodeAs = getEncodeAs(program, type); - return { example: serializeValueAsJson(program, example.value, type, encodeAs) }; + const exactValueType = program.checker.getValueExactType(example.value); + return { + example: serializeValueAsJson(program, example.value, exactValueType ?? type, encodeAs), + }; } else { const exampleObj: Record = {}; for (const [index, [example, type]] of examples.entries()) { diff --git a/packages/openapi3/test/examples.test.ts b/packages/openapi3/test/examples.test.ts index b31fc32b01d..34e14428b30 100644 --- a/packages/openapi3/test/examples.test.ts +++ b/packages/openapi3/test/examples.test.ts @@ -962,4 +962,50 @@ worksFor(supportedVersions, ({ openApiFor }) => { "2021-01-01T00:00:00Z", ); }); + + it("supports example generation for union that contains enums", async () => { + const res = await openApiFor( + ` + namespace MyService { + enum Versions { + v1 + } + } + + @versioned(Versions) + @service + namespace MyService { + enum Enum { + a: "a", + b: "b", + } + + model Foo { + entityType: "foo"; + } + + model Bar { + entityType: "bar"; + enumValue: Enum; + } + + @opExample(#{ returnType: #[#{ entityType: "bar", enumValue: Enum.a }] }) + op testOp(): (Foo | Bar)[]; + } + `, + ); + + ok(res.components?.schemas); + ok(res.paths["/"].get); + ok(res.paths["/"].get.responses); + ok("200" in res.paths["/"].get.responses); + ok("content" in res.paths["/"].get.responses["200"]); + ok(res.paths["/"].get.responses["200"].content); + expect(res.paths["/"].get?.responses["200"].content["application/json"].example).toEqual([ + { + entityType: "bar", + enumValue: "a", + }, + ]); + }); }); diff --git a/packages/openapi3/test/versioning.test.ts b/packages/openapi3/test/versioning.test.ts index e1f4108390d..ff7e9afdcaf 100644 --- a/packages/openapi3/test/versioning.test.ts +++ b/packages/openapi3/test/versioning.test.ts @@ -217,5 +217,53 @@ worksFor(supportedVersions, ({ openApiFor, version: specVersion }) => { `, ); }); + + it("supports example generation for union that contains enums", async () => { + const { v1 } = await openApiForVersions( + ` + namespace MyService { + enum Versions { + v1 + } + } + + @versioned(Versions) + @service + namespace MyService { + enum Enum { + a: "a", + b: "b", + } + + model Foo { + entityType: "foo"; + } + + model Bar { + entityType: "bar"; + enumValue: Enum; + } + + @opExample(#{ returnType: #[#{ entityType: "bar", enumValue: Enum.a }] }) + op testOp(): (Foo | Bar)[]; + } + `, + ["v1"], + ); + + strictEqual(v1.info.version, "v1"); + ok(v1.components?.schemas); + ok(v1.paths["/"].get); + ok(v1.paths["/"].get.responses); + ok("200" in v1.paths["/"].get.responses); + ok("content" in v1.paths["/"].get.responses["200"]); + ok(v1.paths["/"].get.responses["200"].content); + deepStrictEqual(v1.paths["/"].get?.responses["200"].content["application/json"].example, [ + { + entityType: "bar", + enumValue: "a", + }, + ]); + }); }); }); From 06583f0fc9311824c8c1d0e642ff43d534d50432 Mon Sep 17 00:00:00 2001 From: Konstantin Ershov Date: Wed, 24 Dec 2025 10:49:16 +0100 Subject: [PATCH 2/3] docs: changelog --- ...xes-opeanapi3-versioned-examples-2025-11-24-10-46-23.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .chronus/changes/fixes-opeanapi3-versioned-examples-2025-11-24-10-46-23.md diff --git a/.chronus/changes/fixes-opeanapi3-versioned-examples-2025-11-24-10-46-23.md b/.chronus/changes/fixes-opeanapi3-versioned-examples-2025-11-24-10-46-23.md new file mode 100644 index 00000000000..073bc39d9d5 --- /dev/null +++ b/.chronus/changes/fixes-opeanapi3-versioned-examples-2025-11-24-10-46-23.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/openapi3" +--- + +Fixed examples generation for operations with unions and nested enums for versioned services \ No newline at end of file From bfb7971676a34dbfd3a0e7517a3675dfb8b02536 Mon Sep 17 00:00:00 2001 From: Konstantin Ershov Date: Wed, 24 Dec 2025 12:07:22 +0100 Subject: [PATCH 3/3] fix: tests --- packages/openapi3/test/examples.test.ts | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/packages/openapi3/test/examples.test.ts b/packages/openapi3/test/examples.test.ts index 34e14428b30..b09bf17d367 100644 --- a/packages/openapi3/test/examples.test.ts +++ b/packages/openapi3/test/examples.test.ts @@ -965,14 +965,7 @@ worksFor(supportedVersions, ({ openApiFor }) => { it("supports example generation for union that contains enums", async () => { const res = await openApiFor( - ` - namespace MyService { - enum Versions { - v1 - } - } - - @versioned(Versions) + ` @service namespace MyService { enum Enum {