diff --git a/CHANGELOG.md b/CHANGELOG.md index 0089c1e..df932b1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ## unreleased +- Doc: Added documentation for module usage +- Module: Handle default sort sets - Removed commander dependency - Bumped dependencies diff --git a/openapi-format.js b/openapi-format.js index fb9b959..f0f127c 100644 --- a/openapi-format.js +++ b/openapi-format.js @@ -36,6 +36,18 @@ const {parseTpl, getOperation} = require('./utils/parseTpl'); const {writePaths, writeComponents, writeSplitOpenAPISpec} = require('./utils/split'); const {dirname, extname} = require('path'); const {openapiOverlay, resolveJsonPath, resolveJsonPathValue} = require('./utils/overlay'); +const defaultSortSetJson = require('./defaultSort.json'); +const defaultSortComponentsJson = require('./defaultSortComponents.json'); + +const cloneJson = obj => JSON.parse(JSON.stringify(obj)); + +async function getDefaultSortSet() { + return cloneJson(defaultSortSetJson); +} + +async function getDefaultSortComponentsSet() { + return cloneJson(defaultSortComponentsJson); +} /** * OpenAPI sort function @@ -60,8 +72,8 @@ async function openapiSort(oaObj, options) { } let jsonObj = JSON.parse(JSON.stringify(oaObj)); // Deep copy of the schema object - let sortSet = options.sortSet || (await parseFile(__dirname + '/defaultSort.json')); - let sortComponentsSet = options.sortComponentsSet || (await parseFile(__dirname + '/defaultSortComponents.json')); + let sortSet = options.sortSet || (await getDefaultSortSet()); + let sortComponentsSet = options.sortComponentsSet || (await getDefaultSortComponentsSet()); let debugStep = ''; // uncomment // debugStep below to see which sort part is triggered // Recursive traverse through OpenAPI document @@ -1191,6 +1203,8 @@ module.exports = { openapiFilter: openapiFilter, openapiGenerate: openapiGenerate, openapiSort: openapiSort, + getDefaultSortSet, + getDefaultSortComponentsSet, openapiChangeCase: openapiChangeCase, openapiOverlay: openapiOverlay, openapiSplit: openapiSplit, diff --git a/readme.md b/readme.md index de50984..0b1b455 100644 --- a/readme.md +++ b/readme.md @@ -41,6 +41,7 @@ With the newly added OpenAPI Overlay support, users can overlay changes onto exi * [CLI rename usage](#cli-rename-usage) * [CLI convertTo usage](#cli-convertto-usage) * [CLI configuration usage](#cli-configuration-usage) +* [Programmatic usage](#programmatic-usage) * [Credits](#credits) ## Use-cases @@ -1563,6 +1564,92 @@ Example of a .openapiformatrc file: } ``` +## Programmatic usage + +The CLI is the primary interface, but all formatting utilities are exposed as module functions as well: + +```js +const { + openapiSort, + getDefaultSortSet, + getDefaultSortComponentsSet +} = require('openapi-format'); + +const document = /* your OpenAPI document */; +const sorted = await openapiSort(document, { + sortSet: await getDefaultSortSet(), + sortComponentsSet: await getDefaultSortComponentsSet() +}); +``` + +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. + +### Sorting with minimal setup + +```js +const {openapiSort} = require('openapi-format'); +const fs = require('fs'); + +const document = JSON.parse(fs.readFileSync('spec.json', 'utf8')); +const {data} = await openapiSort(document, {sort: true}); + +fs.writeFileSync('spec.sorted.json', JSON.stringify(data, null, 2)); +``` + +### Sorting with custom tweaks + +```js +const { + openapiSort, + getDefaultSortSet +} = require('openapi-format'); + +const sortSet = await getDefaultSortSet(); +sortSet.get = ['summary', 'description', 'responses']; // override GET priority + +const {data} = await openapiSort(document, { + sort: true, + sortSet, + sortComponentsSet: ['schemas', 'responses'] +}); +``` + +### Mixing in other utilities + +```js +const {openapiFilter, openapiGenerate} = require('openapi-format'); + +let draft = /* load OpenAPI */; +draft = (await openapiFilter(draft, { + filterSet: {tags: ['public']} +})).data; + +draft = (await openapiGenerate(draft, { + generateSet: { + operationIdTemplate: '__' + } +})).data; +``` + +### Using the file helpers for YAML/JSON OpenAPI documents + +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: + +```js +const { + parseFile, + stringify, + writeFile, + openapiSort +} = require('openapi-format'); + +const input = await parseFile('openapi.yaml'); // local path or remote URL +const {data} = await openapiSort(input, {sort: true}); + +const output = await stringify(data, {format: 'yaml', lineWidth: -1}); +await writeFile('openapi.sorted.yaml', output, {format: 'yaml'}); +``` + ## AsyncAPI documents For handling AsyncAPI documents, we have created a separate diff --git a/test/defaults.test.js b/test/defaults.test.js new file mode 100644 index 0000000..14cfac4 --- /dev/null +++ b/test/defaults.test.js @@ -0,0 +1,23 @@ +const path = require('path'); +const fs = require('fs'); +const {getDefaultSortSet, getDefaultSortComponentsSet} = require('../openapi-format'); + +const loadJson = filename => JSON.parse(fs.readFileSync(path.join(__dirname, '..', filename), 'utf8')); + +describe('default sort helpers', () => { + it('returns default sort set clone', async () => { + const defaults = loadJson('defaultSort.json'); + const result = await getDefaultSortSet(); + + expect(result).toEqual(defaults); + expect(result).not.toBe(defaults); + }); + + it('returns default sort components set clone', async () => { + const defaults = loadJson('defaultSortComponents.json'); + const result = await getDefaultSortComponentsSet(); + + expect(result).toEqual(defaults); + expect(result).not.toBe(defaults); + }); +}); diff --git a/types/openapi-format.d.ts b/types/openapi-format.d.ts index f9ca2f4..1578d47 100644 --- a/types/openapi-format.d.ts +++ b/types/openapi-format.d.ts @@ -51,7 +51,7 @@ declare module 'openapi-format' { } interface OpenAPISortOptions { - sortSet: OpenAPISortSet + sortSet?: OpenAPISortSet sortComponentsSet?: string[] } @@ -154,6 +154,16 @@ declare module 'openapi-format' { options: OpenAPISortOptions ): Promise + /** + * Returns the default sorting configuration used by openapi-format. + */ + export function getDefaultSortSet(): Promise + + /** + * Returns the default components sorting configuration used by openapi-format. + */ + export function getDefaultSortComponentsSet(): Promise + /** * Filters the properties of an OpenAPI document based on the specified filter configuration. * @param {OpenAPIV3.Document} oaObj - The OpenAPI document to be filtered.