openapi-format
Advanced tools
Comparing version 1.21.2 to 1.22.0
## unreleased | ||
## [1.22.0] - 2024-08-04 | ||
- Sort - Added option to sort paths alphabetically or by tag (#119) | ||
## [1.21.2] - 2024-08-02 | ||
@@ -4,0 +8,0 @@ |
@@ -8,3 +8,3 @@ #!/usr/bin/env node | ||
prioritySort, | ||
isMatchOperationItem, arraySort, | ||
isMatchOperationItem, arraySort, sortPathsByTags, sortPathsByAlphabet, | ||
} = require("./utils/sorting"); | ||
@@ -44,2 +44,11 @@ const { | ||
// Sort by options | ||
const sortPathsBy = options.sortSet?.sortPathsBy || "original"; | ||
// Cleanup sortSet | ||
if (options.sortSet) { | ||
delete options.sortSet.sortPathsBy; | ||
options.sortSet = Object.keys(options.sortSet).length ? options.sortSet : null; | ||
} | ||
let jsonObj = JSON.parse(JSON.stringify(oaObj)); // Deep copy of the schema object | ||
@@ -74,2 +83,17 @@ let sortSet = options.sortSet || await parseFile(__dirname + "/defaultSort.json"); | ||
// Path sorting | ||
if (this.key === 'paths' && sortPathsBy !== 'original') { | ||
let sortedObj = JSON.parse(JSON.stringify(node)); | ||
if (sortPathsBy === 'path') { | ||
// debugStep = 'Path sorting by alphabet' | ||
node = sortPathsByAlphabet(sortedObj); | ||
this.update(node); | ||
} | ||
if (sortPathsBy === 'tags') { | ||
// debugStep = 'Path sorting by first method, first tag' | ||
node = sortPathsByTags(sortedObj); | ||
this.update(node); | ||
} | ||
} | ||
// Generic sorting | ||
@@ -76,0 +100,0 @@ if (sortSet.hasOwnProperty(this.key) && Array.isArray(sortSet[this.key])) { |
{ | ||
"name": "openapi-format", | ||
"version": "1.21.2", | ||
"version": "1.22.0", | ||
"description": "Format an OpenAPI document by ordering, formatting and filtering fields.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -188,9 +188,11 @@ ![openapi-format icon](./assets/openapi-format-logo.svg) | ||
The CLI will sort the OpenAPI document in the defined order liked defined per OpenAPI key/element. The fields that are | ||
The CLI will sort the OpenAPI document in the defined order liked defined per OpenAPI key/field/property/element. The fields that are | ||
not specified will keep their order like it is in the original OpenAPI document, so only defined fields will be | ||
re-ordered. | ||
The default sorting based on the defined order (listed in the table below), which is stored in | ||
The default sorting of the different fields based on the defined order (listed in the table below), which is stored in | ||
the [defaultSort.json](https://github.com/thim81/openapi-format/blob/main/defaultSort.json) file. | ||
### OpenAPI sort fields | ||
You can easily modify this by specifying your own ordering per key, which can be passed on to the CLI (see below for an | ||
@@ -218,2 +220,18 @@ example on how to do this). | ||
### OpenAPI sort Paths | ||
You can change the order of the paths defined in the OpenAPI specification and sort them alphabetically (`path`) or by the first tag of the first method (`tags`). | ||
Options to sort by: | ||
- `original` (default): keep the order as defined in the OpenAPI specification | ||
- `path`: order the paths alphabetically by the path parts | ||
- `tags`: order by the first tag of the first method | ||
| Key | Options | OpenAPI reference | | ||
|-------------|------------------------------|------------------------------------------------------------------------| | ||
| sortPathsBy | 'original' / 'path' / 'tags' | [paths-object](https://spec.openapis.org/oas/v3.0.3.html#paths-object) | | ||
## OpenAPI filter options | ||
@@ -220,0 +238,0 @@ |
@@ -81,2 +81,69 @@ | ||
/** | ||
* Sort OpenAPI paths by alphabet | ||
* @param paths | ||
* @returns {{[p: string]: unknown}} | ||
*/ | ||
function sortPathsByAlphabet(paths) { // Convert the paths object to an array of entries | ||
const entries = Object.entries(paths); | ||
// Sort the entries alphabetically by their paths | ||
entries.sort((a, b) => { | ||
const pathA = a[0].split('/'); | ||
const pathB = b[0].split('/'); | ||
for (let i = 1; i < Math.max(pathA.length, pathB.length); i++) { | ||
if (!pathA[i]) return -1; | ||
if (!pathB[i]) return 1; | ||
if (pathA[i] < pathB[i]) return -1; | ||
if (pathA[i] > pathB[i]) return 1; | ||
} | ||
return 0; | ||
}); | ||
return Object.fromEntries(entries); | ||
} | ||
/** | ||
* Sort OpenAPI paths by tags | ||
* @param paths | ||
* @returns {{[p: string]: unknown}} | ||
*/ | ||
function sortPathsByTags(paths) { | ||
const entries = Object.entries(paths); | ||
// Sort the entries by the first tag in the available methods | ||
entries.sort((a, b) => { | ||
const methodsA = a[1]; | ||
const methodsB = b[1]; | ||
const tagsOrder = ["get", "post", "put", "delete", "patch", "options", "head"]; | ||
let tagA = ""; | ||
let tagB = ""; | ||
for (const method of tagsOrder) { | ||
if (methodsA[method] && methodsA[method].tags && methodsA[method].tags.length > 0) { | ||
tagA = methodsA[method].tags[0]; | ||
break; | ||
} | ||
} | ||
for (const method of tagsOrder) { | ||
if (methodsB[method] && methodsB[method].tags && methodsB[method].tags.length > 0) { | ||
tagB = methodsB[method].tags[0]; | ||
break; | ||
} | ||
} | ||
if (tagA < tagB) { | ||
return -1; | ||
} | ||
if (tagA > tagB) { | ||
return 1; | ||
} | ||
return 0; | ||
}); | ||
return Object.fromEntries(entries); | ||
} | ||
/** | ||
* A check if the OpenAPI operation item matches a target definition . | ||
@@ -155,9 +222,11 @@ * @param {object} operationPath the OpenAPI path item to match | ||
module.exports = { | ||
sortObjectByKeyNameList:sortObjectByKeyNameList, | ||
propComparator:propComparator, | ||
arraySort: arraySort, | ||
prioritySort:prioritySort, | ||
isMatchOperationItem:isMatchOperationItem, | ||
pathToRegExp:pathToRegExp, | ||
matchPath:matchPath, | ||
sortObjectByKeyNameList, | ||
propComparator, | ||
arraySort, | ||
prioritySort, | ||
sortPathsByAlphabet, | ||
sortPathsByTags, | ||
isMatchOperationItem, | ||
pathToRegExp, | ||
matchPath, | ||
}; |
147350
2146
1157