Skip to content

Commit 080e344

Browse files
authored
Module: Handle default sort sets (#186)
1 parent c75d0cd commit 080e344

5 files changed

Lines changed: 139 additions & 3 deletions

File tree

CHANGELOG.md

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

3+
- Doc: Added documentation for module usage
4+
- Module: Handle default sort sets
35
- Removed commander dependency
46
- Bumped dependencies
57

openapi-format.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,18 @@ const {parseTpl, getOperation} = require('./utils/parseTpl');
3636
const {writePaths, writeComponents, writeSplitOpenAPISpec} = require('./utils/split');
3737
const {dirname, extname} = require('path');
3838
const {openapiOverlay, resolveJsonPath, resolveJsonPathValue} = require('./utils/overlay');
39+
const defaultSortSetJson = require('./defaultSort.json');
40+
const defaultSortComponentsJson = require('./defaultSortComponents.json');
41+
42+
const cloneJson = obj => JSON.parse(JSON.stringify(obj));
43+
44+
async function getDefaultSortSet() {
45+
return cloneJson(defaultSortSetJson);
46+
}
47+
48+
async function getDefaultSortComponentsSet() {
49+
return cloneJson(defaultSortComponentsJson);
50+
}
3951

4052
/**
4153
* OpenAPI sort function
@@ -60,8 +72,8 @@ async function openapiSort(oaObj, options) {
6072
}
6173

6274
let jsonObj = JSON.parse(JSON.stringify(oaObj)); // Deep copy of the schema object
63-
let sortSet = options.sortSet || (await parseFile(__dirname + '/defaultSort.json'));
64-
let sortComponentsSet = options.sortComponentsSet || (await parseFile(__dirname + '/defaultSortComponents.json'));
75+
let sortSet = options.sortSet || (await getDefaultSortSet());
76+
let sortComponentsSet = options.sortComponentsSet || (await getDefaultSortComponentsSet());
6577
let debugStep = ''; // uncomment // debugStep below to see which sort part is triggered
6678

6779
// Recursive traverse through OpenAPI document
@@ -1191,6 +1203,8 @@ module.exports = {
11911203
openapiFilter: openapiFilter,
11921204
openapiGenerate: openapiGenerate,
11931205
openapiSort: openapiSort,
1206+
getDefaultSortSet,
1207+
getDefaultSortComponentsSet,
11941208
openapiChangeCase: openapiChangeCase,
11951209
openapiOverlay: openapiOverlay,
11961210
openapiSplit: openapiSplit,

readme.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ With the newly added OpenAPI Overlay support, users can overlay changes onto exi
4141
* [CLI rename usage](#cli-rename-usage)
4242
* [CLI convertTo usage](#cli-convertto-usage)
4343
* [CLI configuration usage](#cli-configuration-usage)
44+
* [Programmatic usage](#programmatic-usage)
4445
* [Credits](#credits)
4546

4647
## Use-cases
@@ -1563,6 +1564,92 @@ Example of a .openapiformatrc file:
15631564
}
15641565
```
15651566

1567+
## Programmatic usage
1568+
1569+
The CLI is the primary interface, but all formatting utilities are exposed as module functions as well:
1570+
1571+
```js
1572+
const {
1573+
openapiSort,
1574+
getDefaultSortSet,
1575+
getDefaultSortComponentsSet
1576+
} = require('openapi-format');
1577+
1578+
const document = /* your OpenAPI document */;
1579+
const sorted = await openapiSort(document, {
1580+
sortSet: await getDefaultSortSet(),
1581+
sortComponentsSet: await getDefaultSortComponentsSet()
1582+
});
1583+
```
1584+
1585+
Both `sortSet` and `sortComponentsSet` are optional when you call `openapiSort`. When omitted, openapi-format automatically applies the built-in defaults (the same ones the CLI uses). The helper functions `getDefaultSortSet` and `getDefaultSortComponentsSet` are provided in case you want to start from the defaults and tweak them before invoking `openapiSort` in your own scripts.
1586+
1587+
### Sorting with minimal setup
1588+
1589+
```js
1590+
const {openapiSort} = require('openapi-format');
1591+
const fs = require('fs');
1592+
1593+
const document = JSON.parse(fs.readFileSync('spec.json', 'utf8'));
1594+
const {data} = await openapiSort(document, {sort: true});
1595+
1596+
fs.writeFileSync('spec.sorted.json', JSON.stringify(data, null, 2));
1597+
```
1598+
1599+
### Sorting with custom tweaks
1600+
1601+
```js
1602+
const {
1603+
openapiSort,
1604+
getDefaultSortSet
1605+
} = require('openapi-format');
1606+
1607+
const sortSet = await getDefaultSortSet();
1608+
sortSet.get = ['summary', 'description', 'responses']; // override GET priority
1609+
1610+
const {data} = await openapiSort(document, {
1611+
sort: true,
1612+
sortSet,
1613+
sortComponentsSet: ['schemas', 'responses']
1614+
});
1615+
```
1616+
1617+
### Mixing in other utilities
1618+
1619+
```js
1620+
const {openapiFilter, openapiGenerate} = require('openapi-format');
1621+
1622+
let draft = /* load OpenAPI */;
1623+
draft = (await openapiFilter(draft, {
1624+
filterSet: {tags: ['public']}
1625+
})).data;
1626+
1627+
draft = (await openapiGenerate(draft, {
1628+
generateSet: {
1629+
operationIdTemplate: '<method>_<pathPart1>_<pathPart2>'
1630+
}
1631+
})).data;
1632+
```
1633+
1634+
### Using the file helpers for YAML/JSON OpenAPI documents
1635+
1636+
The module also exports the same helpers the CLI relies on for smart parsing/writing (large-number handling, YAML comments, remote loading, etc.) of OpenAPI documents:
1637+
1638+
```js
1639+
const {
1640+
parseFile,
1641+
stringify,
1642+
writeFile,
1643+
openapiSort
1644+
} = require('openapi-format');
1645+
1646+
const input = await parseFile('openapi.yaml'); // local path or remote URL
1647+
const {data} = await openapiSort(input, {sort: true});
1648+
1649+
const output = await stringify(data, {format: 'yaml', lineWidth: -1});
1650+
await writeFile('openapi.sorted.yaml', output, {format: 'yaml'});
1651+
```
1652+
15661653
## AsyncAPI documents
15671654

15681655
For handling AsyncAPI documents, we have created a separate

test/defaults.test.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const path = require('path');
2+
const fs = require('fs');
3+
const {getDefaultSortSet, getDefaultSortComponentsSet} = require('../openapi-format');
4+
5+
const loadJson = filename => JSON.parse(fs.readFileSync(path.join(__dirname, '..', filename), 'utf8'));
6+
7+
describe('default sort helpers', () => {
8+
it('returns default sort set clone', async () => {
9+
const defaults = loadJson('defaultSort.json');
10+
const result = await getDefaultSortSet();
11+
12+
expect(result).toEqual(defaults);
13+
expect(result).not.toBe(defaults);
14+
});
15+
16+
it('returns default sort components set clone', async () => {
17+
const defaults = loadJson('defaultSortComponents.json');
18+
const result = await getDefaultSortComponentsSet();
19+
20+
expect(result).toEqual(defaults);
21+
expect(result).not.toBe(defaults);
22+
});
23+
});

types/openapi-format.d.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ declare module 'openapi-format' {
5151
}
5252

5353
interface OpenAPISortOptions {
54-
sortSet: OpenAPISortSet
54+
sortSet?: OpenAPISortSet
5555
sortComponentsSet?: string[]
5656
}
5757

@@ -154,6 +154,16 @@ declare module 'openapi-format' {
154154
options: OpenAPISortOptions
155155
): Promise<OpenAPIResult>
156156

157+
/**
158+
* Returns the default sorting configuration used by openapi-format.
159+
*/
160+
export function getDefaultSortSet(): Promise<OpenAPISortSet>
161+
162+
/**
163+
* Returns the default components sorting configuration used by openapi-format.
164+
*/
165+
export function getDefaultSortComponentsSet(): Promise<string[]>
166+
157167
/**
158168
* Filters the properties of an OpenAPI document based on the specified filter configuration.
159169
* @param {OpenAPIV3.Document} oaObj - The OpenAPI document to be filtered.

0 commit comments

Comments
 (0)