diff --git a/.chronus/changes/wanl-fix-noway-yaml-2024-11-27-14-31-43.md b/.chronus/changes/wanl-fix-noway-yaml-2024-11-27-14-31-43.md new file mode 100644 index 0000000000..b71ee9dcbe --- /dev/null +++ b/.chronus/changes/wanl-fix-noway-yaml-2024-11-27-14-31-43.md @@ -0,0 +1,7 @@ +--- +changeKind: fix +packages: + - "@typespec/openapi3" +--- + +Fix: OpenAPI YAML converts strings to boolean diff --git a/packages/openapi3/src/openapi.ts b/packages/openapi3/src/openapi.ts index f70ef06230..b2f19c86dd 100644 --- a/packages/openapi3/src/openapi.ts +++ b/packages/openapi3/src/openapi.ts @@ -1844,6 +1844,7 @@ function serializeDocument(root: OpenAPI3Document, fileType: FileType): string { singleQuote: true, aliasDuplicateObjects: false, lineWidth: 0, + schema: "yaml-1.1", }); } } diff --git a/packages/openapi3/test/emit-openapi.test.ts b/packages/openapi3/test/emit-openapi.test.ts new file mode 100644 index 0000000000..6567704d7f --- /dev/null +++ b/packages/openapi3/test/emit-openapi.test.ts @@ -0,0 +1,79 @@ +import { describe, expect, it } from "vitest"; +import { emitOpenApiWithDiagnostics } from "./test-host.js"; + +describe("Scalar formats of serialized document in YAML", () => { + it("should add single quote for y|Y|yes|Yes|YES|n|N|no|No|NO|true|True|TRUE|false|False|FALSE|on|On|ON|off|Off|OFF", async () => { + const [_, __, content] = await emitOpenApiWithDiagnostics(` + enum TestEnum { + y: "y", + Y: "Y", + yes: "yes", + Yes: "Yes", + YES: "YES", + yEs: "yEs", + n: "n", + N: "N", + no: "no", + No: "No", + NO: "NO", + nO: "nO", + "true": "true", + True: "True", + TRUE: "TRUE", + tRUE: "tRUE", + "false": "false", + False: "False", + FALSE: "FALSE", + fALSE: "fALSE", + on: "on", + On: "On", + ON: "ON", + oN: "oN", + off: "off", + Off: "Off", + OFF: "OFF", + oFF: "oFF" + } + `); + expect(content).toBe(`openapi: 3.0.0 +info: + title: (title) + version: 0.0.0 +tags: [] +paths: {} +components: + schemas: + TestEnum: + type: string + enum: + - 'y' + - 'Y' + - 'yes' + - 'Yes' + - 'YES' + - yEs + - 'n' + - 'N' + - 'no' + - 'No' + - 'NO' + - nO + - 'true' + - 'True' + - 'TRUE' + - tRUE + - 'false' + - 'False' + - 'FALSE' + - fALSE + - 'on' + - 'On' + - 'ON' + - oN + - 'off' + - 'Off' + - 'OFF' + - oFF +`); + }); +}); diff --git a/packages/openapi3/test/test-host.ts b/packages/openapi3/test/test-host.ts index 2be1f42e0f..2aa902decb 100644 --- a/packages/openapi3/test/test-host.ts +++ b/packages/openapi3/test/test-host.ts @@ -11,6 +11,7 @@ import { RestTestLibrary } from "@typespec/rest/testing"; import { VersioningTestLibrary } from "@typespec/versioning/testing"; import { XmlTestLibrary } from "@typespec/xml/testing"; import { ok } from "assert"; +import { parse } from "yaml"; import { OpenAPI3EmitterOptions } from "../src/lib.js"; import { OpenAPI3TestLibrary } from "../src/testing/index.js"; import { OpenAPI3Document } from "../src/types.js"; @@ -56,9 +57,10 @@ export async function createOpenAPITestRunner({ export async function emitOpenApiWithDiagnostics( code: string, options: OpenAPI3EmitterOptions = {}, -): Promise<[OpenAPI3Document, readonly Diagnostic[]]> { +): Promise<[OpenAPI3Document, readonly Diagnostic[], string]> { const runner = await createOpenAPITestRunner(); - const outputFile = resolveVirtualPath("openapi.json"); + const fileType = options["file-type"] || "yaml"; + const outputFile = resolveVirtualPath("openapi" + fileType === "json" ? ".json" : ".yaml"); const diagnostics = await runner.diagnose(code, { noEmit: false, emit: ["@typespec/openapi3"], @@ -68,8 +70,8 @@ export async function emitOpenApiWithDiagnostics( }); const content = runner.fs.get(outputFile); ok(content, "Expected to have found openapi output"); - const doc = JSON.parse(content); - return [doc, diagnostics]; + const doc = fileType === "json" ? JSON.parse(content) : parse(content); + return [doc, diagnostics, content]; } export async function diagnoseOpenApiFor(code: string, options: OpenAPI3EmitterOptions = {}) {