-
Notifications
You must be signed in to change notification settings - Fork 2.9k
fix(spec-panel): normalize OpenAPI 3.2+ versions for Swagger preview #9300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Tyagiquamar
wants to merge
1
commit into
usebruno:main
from
Tyagiquamar:fix/openapi-32-spec-viewer-support
+71
−1
Closed
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
24 changes: 24 additions & 0 deletions
24
packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/normalizeSpec.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| /** | ||
| * SwaggerUI (swagger-ui-react) supports Swagger 2.0 and OpenAPI 3.0.x / 3.1.x. | ||
| * When an OpenAPI specification specifies a newer 3.x version (such as 3.2.0, 3.2.1), | ||
| * SwaggerUI rejects it as an unsupported version. Normalizing the version field to 3.1.0 | ||
| * allows SwaggerUI to parse and render the document seamlessly. | ||
| */ | ||
| export const normalizeSpecForSwagger = (spec) => { | ||
| if (!spec) return spec; | ||
|
|
||
| if (typeof spec === 'string') { | ||
| return spec.replace(/(["']?openapi["']?\s*:\s*["']?)3\.[2-9]\d*(?:\.\d+)?([^"'\n\r]*["']?)/i, '$13.1.0$2'); | ||
| } | ||
|
|
||
| if (typeof spec === 'object' && spec !== null) { | ||
| if (typeof spec.openapi === 'string' && /^3\.([2-9]|\d{2,})(\.|$)/.test(spec.openapi)) { | ||
| return { | ||
| ...spec, | ||
| openapi: '3.1.0' | ||
| }; | ||
| } | ||
| } | ||
|
|
||
| return spec; | ||
| }; | ||
44 changes: 44 additions & 0 deletions
44
packages/bruno-app/src/components/ApiSpecPanel/Renderers/Swagger/normalizeSpec.spec.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import { normalizeSpecForSwagger } from './normalizeSpec'; | ||
|
|
||
| describe('normalizeSpecForSwagger', () => { | ||
| it('returns falsy or non-object/string inputs unchanged', () => { | ||
| expect(normalizeSpecForSwagger(null)).toBeNull(); | ||
| expect(normalizeSpecForSwagger(undefined)).toBeUndefined(); | ||
| expect(normalizeSpecForSwagger(123)).toBe(123); | ||
| }); | ||
|
|
||
| it('leaves OpenAPI 3.0.x and 3.1.x specs unchanged in string format', () => { | ||
| const yaml30 = 'openapi: 3.0.3\ninfo:\n title: Test'; | ||
| const yaml31 = 'openapi: "3.1.0"\ninfo:\n title: Test'; | ||
| const json30 = '{"openapi": "3.0.0", "info": {}}'; | ||
| expect(normalizeSpecForSwagger(yaml30)).toBe(yaml30); | ||
| expect(normalizeSpecForSwagger(yaml31)).toBe(yaml31); | ||
| expect(normalizeSpecForSwagger(json30)).toBe(json30); | ||
| }); | ||
|
|
||
| it('normalizes OpenAPI 3.2.0 and 3.2.1 string specs to 3.1.0', () => { | ||
| const yaml32 = 'openapi: 3.2.0\ninfo:\n title: Test'; | ||
| const yaml321 = 'openapi: 3.2.1\ninfo:\n title: Test'; | ||
| const yamlQuotes = 'openapi: "3.2.1"\ninfo:\n title: Test'; | ||
| const json32 = '{"openapi": "3.2.0", "info": {}}'; | ||
|
|
||
| expect(normalizeSpecForSwagger(yaml32)).toBe('openapi: 3.1.0\ninfo:\n title: Test'); | ||
| expect(normalizeSpecForSwagger(yaml321)).toBe('openapi: 3.1.0\ninfo:\n title: Test'); | ||
| expect(normalizeSpecForSwagger(yamlQuotes)).toBe('openapi: "3.1.0"\ninfo:\n title: Test'); | ||
| expect(normalizeSpecForSwagger(json32)).toBe('{"openapi": "3.1.0", "info": {}}'); | ||
| }); | ||
|
|
||
| it('normalizes OpenAPI 3.2.x object specs to 3.1.0', () => { | ||
| const obj32 = { openapi: '3.2.1', info: { title: 'Test' } }; | ||
| const result = normalizeSpecForSwagger(obj32); | ||
| expect(result.openapi).toBe('3.1.0'); | ||
| expect(result.info.title).toBe('Test'); | ||
| }); | ||
|
|
||
| it('leaves OpenAPI 3.0.x and 3.1.x object specs unchanged', () => { | ||
| const obj30 = { openapi: '3.0.0', info: { title: 'Test' } }; | ||
| const obj31 = { openapi: '3.1.0', info: { title: 'Test' } }; | ||
| expect(normalizeSpecForSwagger(obj30)).toEqual(obj30); | ||
| expect(normalizeSpecForSwagger(obj31)).toEqual(obj31); | ||
| }); | ||
| }); |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Normalize the root
openapifield.replace()changes only the first match. A valid YAML spec can containopenapi: 3.2.0in aninfo.descriptionblock before the rootopenapifield. This code then changes the description and leaves the root field unchanged, so SwaggerUI still receives an unsupported version. Identify the root field structurally and add a regression test with a preceding block-scalar match.🤖 Prompt for AI Agents
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Normalize all numeric minor versions from 3.2 onward.
The string matcher does not match
3.10.0because[2-9]excludes a minor version that starts with1. The object path accepts this version through\d{2,}, but the string path passes it to SwaggerUI unchanged. Match all numeric minor versions greater than or equal to 2. Add a string-spec regression test foropenapi: 3.10.0.Proposed fix
Based on learnings, version components must be compared numerically rather than lexicographically.
📝 Committable suggestion
🤖 Prompt for AI Agents
Source: Learnings