Skip to content

Commit c964fac

Browse files
committed
CLI: convert to OpenAPI 3.2
1 parent fe448b3 commit c964fac

File tree

20 files changed

+727
-23
lines changed

20 files changed

+727
-23
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
## unreleased
22

3+
- CLI: convert an OpenAPI 3.0 document to an OpenAPI version 3.2
4+
- CLI: convert an OpenAPI 3.1 document to an OpenAPI version 3.1
5+
36
## [1.28.0] - 2025-09-12
47

58
- Overlay: Support "extends" for referencing OpenAPI documents (#176)

bin/__snapshots__/cli.test.js.snap

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,31 @@ OpenAPI-Format CLI settings:
1010
"
1111
`;
1212

13+
exports[`openapi-format CLI command should convert 3.1 to OpenAPI 3.2 1`] = `
14+
"================================================================================
15+
OpenAPI-Format CLI settings:
16+
- Input file: test/yaml-convert-3.1-3.2/input.yaml
17+
- OAS version converted to: "3.2"
18+
================================================================================
19+
20+
OpenAPI-Format CLI options:
21+
|---------------------|-------|
22+
| sort | false |
23+
| keepComments | false |
24+
| sortComponentsProps | false |
25+
| lineWidth | -1 |
26+
| bundle | true |
27+
| split | false |
28+
| convertTo | 3.2 |
29+
| verbose | 3 |
30+
|---------------------|-------|
31+
32+
================================================================================
33+
✅ OpenAPI formatted successfully
34+
================================================================================
35+
"
36+
`;
37+
1338
exports[`openapi-format CLI command should keep the comments for YAML 1`] = `
1439
"================================================================================
1540
OpenAPI-Format CLI settings:
@@ -95,7 +120,7 @@ Options:
95120
--sortComponentsProps sort properties within schema components alphabetically (default: false)
96121
--lineWidth <lineWidth> max line width of YAML output (default: -1)
97122
--rename <oaTitle> overwrite the title in the OpenAPI document
98-
--convertTo <oaVersion> convert the OpenAPI document to OpenAPI version 3.1
123+
--convertTo <oaVersion> convert the OpenAPI document to OpenAPI version 3.1 or 3.2
99124
--no-bundle don't bundle the local and remote $ref in the OpenAPI document
100125
--split split the OpenAPI document into a multi-file structure (default: false)
101126
--json print the file to stdout as JSON
@@ -225,7 +250,7 @@ OpenAPI-Format CLI settings:
225250
exports[`openapi-format CLI command should use the convert version 1`] = `
226251
"================================================================================
227252
OpenAPI-Format CLI settings:
228-
- Input file: test/yaml-convert-3.1/input.yaml
253+
- Input file: test/yaml-convert-3.0-3.1/input.yaml
229254
- OAS version converted to: "3.1"
230255
================================================================================
231256

bin/cli.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const openapiFormat = require('../openapi-format');
44
const program = require('commander');
55
const {infoTable, infoOut, logOut, debugOut} = require('../utils/logging');
66
const {stringify} = require('../openapi-format');
7+
const {resolveConvertTargetVersion} = require('../utils/convert');
78
const fs = require('fs');
89
const path = require('path');
910

@@ -29,7 +30,7 @@ program
2930
.option('--sortComponentsProps', 'sort properties within schema components alphabetically', false)
3031
.option('--lineWidth <lineWidth>', 'max line width of YAML output', -1)
3132
.option('--rename <oaTitle>', 'overwrite the title in the OpenAPI document')
32-
.option('--convertTo <oaVersion>', 'convert the OpenAPI document to OpenAPI version 3.1')
33+
.option('--convertTo <oaVersion>', 'convert the OpenAPI document to OpenAPI version 3.1 or 3.2')
3334
.option('--no-bundle', `don't bundle the local and remote $ref in the OpenAPI document`, false)
3435
.option('--split', 'split the OpenAPI document into a multi-file structure', false)
3536
.option('--json', 'print the file to stdout as JSON')
@@ -324,14 +325,12 @@ async function run(oaFile, options) {
324325
if (resFormat.data) resObj = resFormat.data;
325326
}
326327

327-
// Convert the OpenAPI document to OpenAPI 3.1
328-
if (
329-
(options.convertTo && options.convertTo.toString() === '3.1') ||
330-
(options.convertToVersion && options.convertToVersion === 3.1)
331-
) {
328+
// Convert the OpenAPI document to a supported OpenAPI version
329+
const convertVersionInfo = resolveConvertTargetVersion(options);
330+
if (convertVersionInfo) {
332331
const resVersion = await openapiFormat.openapiConvertVersion(resObj, options);
333332
if (resVersion.data) resObj = resVersion.data;
334-
debugOut(`- OAS version converted to: "${options.convertTo}"`, options.verbose); // LOG - Conversion title
333+
debugOut(`- OAS version converted to: "${convertVersionInfo.label}"`, options.verbose); // LOG - Conversion title
335334
}
336335

337336
// Rename title OpenAPI document

bin/cli.test.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ describe('openapi-format CLI command', () => {
381381
});
382382

383383
it('should use the convert version', async () => {
384-
const path = `test/yaml-convert-3.1`;
384+
const path = `test/yaml-convert-3.0-3.1`;
385385
const inputFile = `${path}/input.yaml`;
386386
const outputFile = `${path}/output.yaml`;
387387
const output = await getLocalFile(outputFile);
@@ -395,6 +395,20 @@ describe('openapi-format CLI command', () => {
395395
expect(sanitize(result.stderr)).toStrictEqual(sanitize(output));
396396
});
397397

398+
it('should convert 3.1 to OpenAPI 3.2', async () => {
399+
const path = `test/yaml-convert-3.1-3.2`;
400+
const inputFile = `${path}/input.yaml`;
401+
const outputFile = `${path}/output.yaml`;
402+
const output = await getLocalFile(outputFile);
403+
404+
let result = await testUtils.cli([inputFile, `--convertTo "3.2"`, `--no-sort`, `-vvv`], '.');
405+
expect(result.code).toBe(0);
406+
expect(result.stdout).toContain('formatted successfully');
407+
expect(result.stdout).toContain('OAS version converted to: "3.2"');
408+
expect(result.stdout).toMatchSnapshot();
409+
expect(sanitize(result.stderr)).toStrictEqual(sanitize(output));
410+
});
411+
398412
it('should use the sortComponentsProps option', async () => {
399413
const path = `test/yaml-sort-component-props`;
400414
const inputFile = `${path}/input.yaml`;

openapi-format.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ const {
2626
convertConst,
2727
convertExclusiveMinimum,
2828
convertExclusiveMaximum,
29-
setInObject
29+
setInObject,
30+
resolveConvertTargetVersion
3031
} = require('./utils/convert');
3132
const {parseFile, writeFile, stringify, detectFormat, parseString, analyzeOpenApi, readFile} = require('./utils/file');
3233
const {parseTpl, getOperation} = require('./utils/parseTpl');
@@ -1107,7 +1108,8 @@ async function openapiConvertVersion(oaObj, options) {
11071108
// let debugConvertVersionStep = '' // uncomment // debugConvertVersionStep below to see which sort part is triggered
11081109

11091110
// Change OpenAPI version
1110-
jsonObj.openapi = '3.1.0';
1111+
const targetVersionInfo = resolveConvertTargetVersion(options) || {normalized: '3.1.0'};
1112+
jsonObj.openapi = targetVersionInfo.normalized;
11111113

11121114
// Change x-webhooks to webhooks
11131115
if (jsonObj['x-webhooks']) {

readme.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Additional features include powerful filtering options based on flags, tags, met
1414
To quickly standardize OpenAPI documents there is support for generating the operationIds and apply casing rules for consistency.
1515

1616
The CLI can split large OpenAPI documents into modular, multi-file structures for easier management.
17-
For upgrades, the openapi-format CLI offers the option to convert an OpenAPI 3.0 document to OpenAPI 3.1.
17+
For upgrades, the openapi-format CLI offers the option to convert an OpenAPI 3.0 or 3.1 document to OpenAPI 3.1 or 3.2.
1818

1919
With the newly added OpenAPI Overlay support, users can overlay changes onto existing OpenAPI documents, to extend and customize the OpenAPI document.
2020

@@ -79,7 +79,8 @@ Postman collections, test suites, ...
7979
- [x] Generate OpenAPI elements for consistency
8080
- [x] Bundle local and remote references in the OpenAPI document
8181
- [x] Split the OpenAPI document into a multi-file structure
82-
- [x] Convert OpenAPI 3.0 documents to OpenAPI 3.1
82+
- [x] Convert OpenAPI 3.0 documents to OpenAPI 3.1 or 3.2
83+
- [x] Convert OpenAPI 3.1 documents to OpenAPI 3.2
8384
- [x] Rename the OpenAPI title
8485
- [x] Support OpenAPI documents in JSON format
8586
- [x] Support OpenAPI documents in YAML format
@@ -165,7 +166,7 @@ Options:
165166
166167
--rename Rename the OpenAPI title [string]
167168
168-
--convertTo convert the OpenAPI document to OpenAPI version 3.1 [string]
169+
--convertTo convert the OpenAPI document to OpenAPI version 3.1 or 3.2 [string]
169170
170171
--configFile The file with the OpenAPI-format CLI options [path]
171172
@@ -198,7 +199,7 @@ Options:
198199
| --no-bundle | | don't bundle the local and remote $ref in the OpenAPI document | boolean | FALSE | optional |
199200
| --split | | split the OpenAPI document into a multi-file structure | boolean | FALSE | optional |
200201
| --rename | | rename the OpenAPI title | string | | optional |
201-
| --convertTo | | convert the OpenAPI document to OpenAPI version 3.1 | string | | optional |
202+
| --convertTo | | convert the OpenAPI document to OpenAPI version 3.1 or 3.2 | string | | optional |
202203
| --configFile | -c | the file with all the format config options | path to file | | optional |
203204
| --lineWidth | | max line width of YAML output | number | -1 (Infinity) | optional |
204205
| --json | | prints the file to stdout as JSON | | FALSE | optional |
@@ -1424,15 +1425,16 @@ which results in
14241425

14251426
> 🏗 BETA NOTICE: This feature is considered BETA since we are investigating the configuration syntax and extra formatting/casing capabilities.
14261427

1427-
- Format & convert the OpenAPI document to OpenAPI version 3.1
1428+
- Format & convert the OpenAPI document to OpenAPI version 3.1 or 3.2
14281429

1429-
openapi-format can help you to upgrade your current OpenAPI 3.0.x document to the latest version OpenAPI 3.1.
1430+
openapi-format can help you to upgrade your current OpenAPI 3.0.x document to OpenAPI 3.1 or 3.2.
14301431

14311432
```shell
14321433
$ openapi-format openapi.json -o openapi-3.1.json --convertTo "3.1"
1434+
$ openapi-format openapi.json -o openapi-3.2.json --convertTo "3.2"
14331435
```
14341436

1435-
which results in all the changes described in the [migration guide from Phil Sturgeon](https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0)
1437+
Using `3.1` results in all the changes described in the [migration guide from Phil Sturgeon](https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0), while the `3.2` target aligns with the new capabilities highlighted in [OpenAPI 3.2 is here](https://quobix.com/articles/openapi-3.2/).
14361438

14371439
**before**
14381440

@@ -1452,6 +1454,8 @@ which results in all the changes described in the [migration guide from Phil Stu
14521454
"title": "OpenAPI Petstore - OpenAPI",
14531455
```
14541456

1457+
When converting to 3.2 the `openapi` field will be set to `3.2.0`, preparing the document for features like hierarchical tags, the `QUERY` HTTP method, and reusable media types introduced in the 3.2 release.
1458+
14551459
## CLI configuration usage
14561460

14571461
The openapi-format CLI supports bundling all options in a single configuration file. This can simplify management, especially for CI/CD pipelines where configurations are stored in version control systems.

test/converting.test.js

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,9 @@ const {
1414
const {describe, it, expect} = require('@jest/globals');
1515

1616
describe('openapi-format CLI converting tests', () => {
17-
describe('yaml-convert to 3.1', () => {
18-
it('yaml-convert-3.1 - should match expected output', async () => {
19-
const testName = 'yaml-convert-3.1';
17+
describe('yaml-convert 3.0 to 3.1', () => {
18+
it('yaml-convert-3.0-3.1 - should match expected output', async () => {
19+
const testName = 'yaml-convert-3.0-3.1';
2020
const {result, input, outputBefore, outputAfter} = await testUtils.loadTest(testName);
2121
// console.log('result',result)
2222
expect(result.code).toBe(0);
@@ -25,6 +25,26 @@ describe('openapi-format CLI converting tests', () => {
2525
});
2626
});
2727

28+
describe('yaml-convert 3.0 to 3.2', () => {
29+
it('yaml-convert-3.0-3.2 - should match expected output', async () => {
30+
const testName = 'yaml-convert-3.0-3.2';
31+
const {result, input, outputBefore, outputAfter} = await testUtils.loadTest(testName);
32+
expect(result.code).toBe(0);
33+
expect(result.stdout).toContain('formatted successfully');
34+
expect(outputAfter).toStrictEqual(outputBefore);
35+
});
36+
});
37+
38+
describe('yaml-convert 3.1 to 3.2', () => {
39+
it('yaml-convert-3.1-3.2 - should match expected output', async () => {
40+
const testName = 'yaml-convert-3.1-3.2';
41+
const {result, input, outputBefore, outputAfter} = await testUtils.loadTest(testName);
42+
expect(result.code).toBe(0);
43+
expect(result.stdout).toContain('formatted successfully');
44+
expect(outputAfter).toStrictEqual(outputBefore);
45+
});
46+
});
47+
2848
describe('util-convert', () => {
2949
it('convertNullable - should convert nullable into a type', async () => {
3050
const obj = {
File renamed without changes.
File renamed without changes.
File renamed without changes.

0 commit comments

Comments
 (0)