feat(openapi3): add opt-in enum-style option for annotated enums - #10892
Conversation
Add a new `enum-style` emitter option to @typespec/openapi3 with values `default` (current behavior) and `annotated`. When set to `annotated`, TypeSpec enums are emitted as OpenAPI 3.1.1 annotated enumerations (a oneOf of const subschemas with per-member title/description sourced from @summary/@doc). Supported on OpenAPI 3.1.0 and 3.2.0; for 3.0.0 the option falls back to the default form and an `enum-style-not-supported` warning is reported. Closes microsoft#5721
commit: |
|
All changed packages have been documented.
Show changes
|
|
You can try these changes here
|
markcowl
left a comment
There was a problem hiding this comment.
I wonder if @summary exactly corresponds with title, but otherwise, this looks great
|
Yeah summary is title in openapi |
…yle-annotated # Conflicts: # .github/aw/actions-lock.json # .github/workflows/issue-triage.lock.yml
…om/timotheeguerin/typespec into feat/openapi3-enum-style-annotated
…style-annotated # Conflicts: # .github/aw/actions-lock.json # .github/workflows/issue-triage.lock.yml # website/src/content/docs/docs/emitters/openapi3/reference/emitter.md
…icrosoft#11154) Extends `enum-strategy: annotated` (microsoft#10892, which fixed microsoft#5721) to unions of literals. That option previously stopped at `enum` declarations, so unions of literals still collapsed to a flat `enum`, dropping variant names, `@summary`, and docs. ```typespec /** Set of known error types. */ union ErrorType { /** Common error for a bad request. */ @summary("CommonBadRequest") commonBadRequest: "https://example.com/errors/bad-request", } ``` Before: `{ type: string, enum: ["https://example.com/errors/bad-request"] }` After (with `enum-strategy: annotated`): ```yaml ErrorType: description: Set of known error types. anyOf: - const: https://example.com/errors/bad-request title: CommonBadRequest description: Common error for a bad request. ``` ## Behavior - Opt-in via the existing option; `default` output unchanged. - 3.1.0/3.2.0 only; 3.0.0 falls back and reports the existing `enum-strategy-not-supported` warning. - `oneOf` when the union has `@oneOf`, else `anyOf`. - `title` from `@summary`, `description` from `@doc`, both omitted when absent, matching the enum handling. - Non-literal variants (models/scalars) stay as their own members; discriminated unions untouched. ## Open question The option is named `enum-strategy` but now also covers unions of literals (both are "enumerated types" in OpenAPI terms). I broadened its description rather than renaming it. Happy to add an alias if preferred.
Fixes #5721
Adds a new opt-in
enum-styleemitter option to@typespec/openapi3. When set toannotated, TypeSpec enums are emitted as OpenAPI 3.1.1 annotated enumerations — aoneOfofconstsubschemas with per-membertitleanddescriptiontaken from@summaryand@docon each enum member. This preserves member-level documentation that otherwise gets dropped by the defaultenumkeyword form.Behavior
default; existing emitter output is unchanged.annotatedis supported on OpenAPI 3.1.0 and 3.2.0 (which supportconst).annotatedfalls back to the default form and a newenum-style-not-supportedwarning is reported.enumdeclarations; unions of literals are unchanged.@doc,@summary, etc.) are still applied to the wrapping schema viaapplyConstraints.Example
With
enum-style: annotatedand OpenAPI 3.1.0/3.2.0:Files changed
packages/openapi3/src/lib.ts—EnumStyletype,enum-styleoption (+ JSON schema), andenum-style-not-supportedwarning diagnostic.packages/openapi3/src/openapi.ts—enumStylepropagated intoResolvedOpenAPI3EmitterOptions; warning emitted inresolveOptionswhen paired with 3.0.0.packages/openapi3/src/schema-emitter-3-1.ts— annotated branch inenumSchema(3.2 inherits).packages/openapi3/test/enums.test.ts— 13 new tests covering 3.1/3.2 annotated form (string, number, mixed, with/without docs, default unchanged), 3.0.0 fallback, and warning emission..chronus/changes/openapi3-enum-style-annotated-*.md—featurechangelog entry.