From b5ad0ce1e52ae6e78e40d6412791a2dc5ff83bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Greg=20Berg=C3=A9?= Date: Wed, 23 Jul 2025 17:21:05 +0200 Subject: [PATCH] Fix OpenAPI v2 parsing (#3498) --- .changeset/witty-eyes-relax.md | 5 +++++ packages/openapi-parser/src/parse.test.ts | 12 +++++++++++- packages/openapi-parser/src/v2.ts | 2 +- packages/openapi-parser/src/v3.ts | 14 +++++++------- 4 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 .changeset/witty-eyes-relax.md diff --git a/.changeset/witty-eyes-relax.md b/.changeset/witty-eyes-relax.md new file mode 100644 index 000000000..bc3b36977 --- /dev/null +++ b/.changeset/witty-eyes-relax.md @@ -0,0 +1,5 @@ +--- +"@gitbook/openapi-parser": patch +--- + +Fix OpenAPI v2 parsing diff --git a/packages/openapi-parser/src/parse.test.ts b/packages/openapi-parser/src/parse.test.ts index eec97658b..7a40f054e 100644 --- a/packages/openapi-parser/src/parse.test.ts +++ b/packages/openapi-parser/src/parse.test.ts @@ -3,11 +3,12 @@ import { OpenAPIParseError } from './error'; import { parseOpenAPI } from './parse'; const spec = await Bun.file(new URL('./fixtures/recursive-spec.json', import.meta.url)).text(); +const specV2 = await Bun.file(new URL('./fixtures/spec-v2.json', import.meta.url)).text(); const html = ` API Documentation `; describe('#parseOpenAPI', () => { - it('parses an OpenAPI document', async () => { + it('parses a recursive OpenAPI document', async () => { const schema = await parseOpenAPI({ value: spec, rootURL: null, @@ -16,6 +17,15 @@ describe('#parseOpenAPI', () => { JSON.stringify(schema); }); + it('parses a swagger v2', async () => { + const schema = await parseOpenAPI({ + value: specV2, + rootURL: null, + }); + // Ensure the structure returned is not recursive (not dereferenced). + JSON.stringify(schema); + }); + it('throws an error for invalid OpenAPI document', async () => { expect.assertions(1); try { diff --git a/packages/openapi-parser/src/v2.ts b/packages/openapi-parser/src/v2.ts index 434d854b0..f73d5088a 100644 --- a/packages/openapi-parser/src/v2.ts +++ b/packages/openapi-parser/src/v2.ts @@ -28,5 +28,5 @@ export async function convertOpenAPIV2ToOpenAPIV3( } })(); - return parseOpenAPIV3({ ...input, rootURL, value: upgradeResult.specification }); + return parseOpenAPIV3({ ...input, rootURL, value: upgradeResult.specification, trust: true }); } diff --git a/packages/openapi-parser/src/v3.ts b/packages/openapi-parser/src/v3.ts index 68f8ab237..e686ef0bc 100644 --- a/packages/openapi-parser/src/v3.ts +++ b/packages/openapi-parser/src/v3.ts @@ -35,6 +35,13 @@ async function untrustedValidate(input: ValidateOpenAPIV3Input) { const { value, rootURL } = input; const result = await validate(value); + if (result.version === '2.0') { + throw new OpenAPIParseError('Only OpenAPI v3 is supported', { + code: 'parse-v2-in-v3', + rootURL, + }); + } + // Spec is invalid, we stop here. if (!result.valid) { throw new OpenAPIParseError('Invalid OpenAPI document', { @@ -44,13 +51,6 @@ async function untrustedValidate(input: ValidateOpenAPIV3Input) { }); } - if (result.version === '2.0') { - throw new OpenAPIParseError('Only OpenAPI v3 is supported', { - code: 'parse-v2-in-v3', - rootURL, - }); - } - return result.specification; }