Skip to content

Commit

Permalink
Formatting - Change casing of OpenAPI elements
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim authored and thim81 committed Jan 19, 2022
1 parent 96d8c04 commit 9b384c5
Show file tree
Hide file tree
Showing 26 changed files with 2,609 additions and 159 deletions.
183 changes: 62 additions & 121 deletions asyncapi-format.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

const fs = require('fs');
const traverse = require('traverse');
const {isString} = require("./util-types");
const {isString, isObject, isArray} = require("./util-types");
const {
adaCase,
camelCase,
Expand Down Expand Up @@ -247,11 +247,6 @@ function asyncapiChangeCase(asObj, options) {

let debugCasingStep = '' // uncomment // debugFilterStep below to see which sort part is triggered

// Initiate components tracking
const comps = {
parameters: {},
}

// Recursive traverse through OpenAPI document to update components
traverse(jsonObj).forEach(function (node) {
// Focus only on the components
Expand All @@ -261,68 +256,25 @@ function asyncapiChangeCase(asObj, options) {
// debugCasingStep = 'Casing - components/schemas - names
this.update(changeObjKeysCase(node, casingSet.componentsSchemas));
}
// Change components/examples - names
if (this.path[1] === 'examples' && this.path.length === 2 && casingSet.componentsExamples) {
// debugCasingStep = 'Casing - components/examples - names
this.update(changeObjKeysCase(node, casingSet.componentsExamples));
// Change components/messages - names
if (this.path[1] === 'messages' && this.path.length === 2 && casingSet.componentsMessages) {
// debugCasingStep = 'Casing - components/messages - names
this.update(changeObjKeysCase(node, casingSet.componentsMessages));
}
// Change components/headers - names
if (this.path[1] === 'headers' && this.path.length === 2 && casingSet.componentsHeaders) {
// debugCasingStep = 'Casing - components/headers - names
this.update(changeObjKeysCase(node, casingSet.componentsHeaders));
// Change components/messageTraits - names
if (this.path[1] === 'messageTraits' && this.path.length === 2 && casingSet.componentsMessageTraits) {
// debugCasingStep = 'Casing - components/messageTraits - names
this.update(changeObjKeysCase(node, casingSet.componentsMessageTraits));
}
// Change components/parameters - in:query/in:headers/in:path - key
if (this.path[1] === 'parameters' && this.path.length === 2 && casingSet.componentsParametersHeader) {
const orgObj = JSON.parse(JSON.stringify(node));
let replacedItems = Object.keys(orgObj).map((key) => {
if (orgObj[key].in && orgObj[key].in === 'query' && casingSet.componentsParametersQuery) {
debugCasingStep = 'Casing - components/parameters - in:query - key'
const newKey = changeCase(key, casingSet.componentsParametersQuery);
comps.parameters[key] = newKey
return {[newKey]: orgObj[key]};
}
if (orgObj[key].in && orgObj[key].in === 'path' && casingSet.componentsParametersPath) {
debugCasingStep = 'Casing - components/parameters - in:path - key'
const newKey = changeCase(key, casingSet.componentsParametersPath);
comps.parameters[key] = newKey
return {[newKey]: orgObj[key]};
}
if (orgObj[key].in && orgObj[key].in === 'header' && casingSet.componentsParametersHeader) {
debugCasingStep = 'Casing - components/parameters - in:header - key'
const newKey = changeCase(key, casingSet.componentsParametersHeader);
comps.parameters[key] = newKey
return {[newKey]: orgObj[key]};
}
});
this.update(Object.assign({}, ...replacedItems));
// Change components/operationTraits - names
if (this.path[1] === 'operationTraits' && this.path.length === 2 && casingSet.componentsOperationTraits) {
// debugCasingStep = 'Casing - components/operationTraits - names
this.update(changeObjKeysCase(node, casingSet.componentsOperationTraits));
}
// Change components/parameters - query/header name
if (this.path[1] === 'parameters' && this.path.length === 3) {
if (node.in && node.in === 'query' && node.name && casingSet.parametersQuery) {
debugCasingStep = 'Casing - path > parameters/query - name'
node.name = changeCase(node.name, casingSet.parametersQuery);
this.update(node);
}
if (node.in && node.in === 'header' && node.name && casingSet.parametersHeader) {
debugCasingStep = 'Casing - path > parameters/headers - name'
node.name = changeCase(node.name, casingSet.parametersHeader);
this.update(node);
}
if (node.in && node.in === 'path' && node.name && casingSet.parametersPath) {
debugCasingStep = 'Casing - path > parameters/path - name'
node.name = changeCase(node.name, casingSet.parametersPath);
this.update(node);
}
}
// Change components/responses - names
if (this.path[1] === 'responses' && this.path.length === 2 && casingSet.componentsResponses) {
// debugCasingStep = 'Casing - components/responses - names
this.update(changeObjKeysCase(node, casingSet.componentsResponses));
}
// Change components/requestBodies - names
if (this.path[1] === 'requestBodies' && this.path.length === 2 && casingSet.componentsRequestBodies) {
// debugCasingStep = 'Casing - components/requestBodies - names
this.update(changeObjKeysCase(node, casingSet.componentsRequestBodies));
// Change components/parameters - names
if (this.path[1] === 'parameters' && this.path.length === 2 && casingSet.componentsParameters) {
// debugCasingStep = 'Casing - components/parameters - names
this.update(changeObjKeysCase(node, casingSet.componentsParameters));
}
// Change components/securitySchemes - names
if (this.path[1] === 'securitySchemes' && this.path.length === 2 && casingSet.componentsSecuritySchemes) {
Expand All @@ -332,35 +284,29 @@ function asyncapiChangeCase(asObj, options) {
}
});

// Recursive traverse through AsyncAPI document to non-components
// Recursive traverse through AsyncAPI document for non-components
traverse(jsonObj).forEach(function (node) {
// Change components $ref names
if (this.key === '$ref') {
if (node.startsWith('#/components/schemas/') && casingSet.componentsSchemas) {
const compName = node.replace('#/components/schemas/', '');
this.update(`#/components/schemas/${changeCase(compName, casingSet.componentsSchemas)}`);
}
if (node.startsWith('#/components/examples/') && casingSet.componentsExamples) {
const compName = node.replace('#/components/examples/', '');
this.update(`#/components/examples/${changeCase(compName, casingSet.componentsExamples)}`);
if (node.startsWith('#/components/messages/') && casingSet.componentsMessages) {
const compName = node.replace('#/components/messages/', '');
this.update(`#/components/messages/${changeCase(compName, casingSet.componentsMessages)}`);
}
if (node.startsWith('#/components/responses/') && casingSet.componentsResponses) {
const compName = node.replace('#/components/responses/', '');
this.update(`#/components/responses/${changeCase(compName, casingSet.componentsResponses)}`);
if (node.startsWith('#/components/messageTraits/') && casingSet.componentsMessageTraits) {
const compName = node.replace('#/components/messageTraits/', '');
this.update(`#/components/messageTraits/${changeCase(compName, casingSet.componentsMessageTraits)}`);
}
if (node.startsWith('#/components/parameters/')) {
const compName = node.replace('#/components/parameters/', '');
if (comps.parameters[compName]) {
this.update(`#/components/parameters/${comps.parameters[compName]}`);
}
if (node.startsWith('#/components/operationTraits/') && casingSet.componentsOperationTraits) {
const compName = node.replace('#/components/operationTraits/', '');
this.update(`#/components/operationTraits/${changeCase(compName, casingSet.componentsOperationTraits)}`);
}
if (node.startsWith('#/components/headers/') && casingSet.componentsHeaders) {
const compName = node.replace('#/components/headers/', '');
this.update(`#/components/headers/${changeCase(compName, casingSet.componentsHeaders)}`);
}
if (node.startsWith('#/components/requestBodies/') && casingSet.componentsRequestBodies) {
const compName = node.replace('#/components/requestBodies/', '');
this.update(`#/components/requestBodies/${changeCase(compName, casingSet.componentsRequestBodies)}`);
if (node.startsWith('#/components/parameters/') && casingSet.componentsParameters) {
const compName = node.replace('#/components/parameters/', '');
this.update(`#/components/parameters/${changeCase(compName, casingSet.componentsParameters)}`);
}
if (node.startsWith('#/components/securitySchemes/') && casingSet.componentsSecuritySchemes) {
const compName = node.replace('#/components/securitySchemes/', '');
Expand All @@ -369,10 +315,15 @@ function asyncapiChangeCase(asObj, options) {
}

// Change operationId
if (this.key === 'operationId' && casingSet.operationId && this.path[0] === 'paths' && this.path.length === 4) {
if (this.key === 'operationId' && casingSet.operationId && this.path[0] === 'channels' && this.path.length === 4) {
// debugCasingStep = 'Casing - Single field - OperationId'
this.update(changeCase(node, casingSet.operationId));
}
// Change channels - channel key
if (this.key === 'channels' && casingSet.channels && this.path[0] === 'channels') {
// debugCasingStep = 'Casing -Channels - channel key'
this.update(changeObjKeysCase(node, casingSet.channels));
}
// Change summary
if (this.key === 'summary' && casingSet.summary) {
// debugCasingStep = 'Casing - Single field - summary'
Expand All @@ -383,54 +334,44 @@ function asyncapiChangeCase(asObj, options) {
// debugCasingStep = 'Casing - Single field - description'
this.update(changeCase(node, casingSet.description));
}
// Change paths > examples - name
if (this.path[0] === 'paths' && this.key === 'examples' && casingSet.componentsExamples) {
// debugCasingStep = 'Casing - Single field - examples name'
this.update(changeObjKeysCase(node, casingSet.componentsExamples));
// Change channels > parameters - name
if (this.path[0] === 'channels' && this.key === 'parameters' && casingSet.componentsParameters) {
// debugCasingStep = 'Casing - Single field - parameters name'
this.update(changeObjKeysCase(node, casingSet.componentsParameters));
}
// Change components/schema - properties
// Change components/schemas - properties
if (this.path[1] === 'schemas' && this.key === 'properties' && casingSet.properties
&& (this.parent && this.parent.key !== 'properties' && this.parent.key !== 'value')
) {
// debugCasingStep = 'Casing - components/schema - properties name'
// debugCasingStep = 'Casing - components/schemas - properties name'
this.update(changeObjKeysCase(node, casingSet.properties));
}
// Change paths > schema - properties
if (this.path[0] === 'paths' && this.key === 'properties' && casingSet.properties
// Change components/messages - properties
if (this.path[1] === 'messages' && this.key === 'properties' && casingSet.properties
&& (this.parent && this.parent.key !== 'properties' && this.parent.key !== 'value')
) {
// debugCasingStep = 'Casing - paths>schema - properties name'
// debugCasingStep = 'Casing - components/messages - properties name'
this.update(changeObjKeysCase(node, casingSet.properties));
}
// Change security - keys
if (this.path[0] === 'paths' && this.key === 'security' && isArray(node) && casingSet.componentsSecuritySchemes) {
// debugCasingStep = 'Casing - path > - security'
this.update(changeArrayObjKeysCase(node, casingSet.componentsSecuritySchemes))
// Change components/messageTraits - properties
if (this.path[1] === 'messageTraits' && this.key === 'properties' && casingSet.properties
&& (this.parent && this.parent.key !== 'properties' && this.parent.key !== 'value')
) {
// debugCasingStep = 'Casing - components/messages - properties name'
this.update(changeObjKeysCase(node, casingSet.properties));
}
// Change parameters - name
if (this.path[0] === 'paths' && this.key === 'parameters'
&& (casingSet.parametersQuery || casingSet.parametersHeader || casingSet.parametersPath)) {
// debugCasingStep = 'Casing - components > parameters - name'

// Loop over parameters array
let params = JSON.parse(JSON.stringify(node)); // Deep copy of the schema object
for (let i = 0; i < params.length; i++) {
if (params[i].in && params[i].in === 'query' && params[i].name && casingSet.parametersQuery) {
// debugCasingStep = 'Casing - path > parameters/query- name'
params[i].name = changeCase(params[i].name, casingSet.parametersQuery)
}
if (params[i].in && params[i].in === 'header' && params[i].name && casingSet.parametersHeader) {
// debugCasingStep = 'Casing - path > parameters/headers - name'
params[i].name = changeCase(params[i].name, casingSet.parametersHeader)
}
if (params[i].in && params[i].in === 'path' && params[i].name && casingSet.parametersPath) {
// debugCasingStep = 'Casing - path > parameters/path - name'
params[i].name = changeCase(params[i].name, casingSet.parametersPath)
}
}
this.update(params);
// Change channels > message - properties
if (this.path[0] === 'channels' && this.key === 'properties' && casingSet.properties
&& (this.parent && this.parent.key !== 'properties' && this.parent.key !== 'value')
) {
// debugCasingStep = 'Casing - channels > message - properties name'
this.update(changeObjKeysCase(node, casingSet.properties));
}
// Change servers > - security - keys
if (this.path[0] === 'servers' && this.key === 'security' && isArray(node) && casingSet.componentsSecuritySchemes) {
// debugCasingStep = 'Casing - servers > - security'
this.update(changeArrayObjKeysCase(node, casingSet.componentsSecuritySchemes))
}

});

// Return result object
Expand Down
23 changes: 22 additions & 1 deletion bin/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ program
.description('Format a AsyncAPI document by ordering and filtering fields.')
.option('-o, --output <output>', 'write the formatted AsyncAPI to an output file path.')
.option('-s, --sortFile <sortFile>', 'The file to specify custom OpenAPI AsyncAPI ordering.', 'defaultSort.json')
.option('-c, --casingFile <filterFile>', 'The file to specify casing rules.')
.option('-c, --casingFile <casingFile>', 'The file to specify casing rules.')
.option('-f, --filterFile <filterFile>', 'The file to specify filter rules.')
.option('-c, --configFile <configFile>', 'The file with the AsyncAPI-format CLI options.')
.option('--no-sort', 'dont sort the AsyncAPI file')
Expand Down Expand Up @@ -109,6 +109,21 @@ async function run(asFile, options) {
}
}

// apply change casing by casing file if present
if (options && options.casingFile) {
infoOut(`- Casing file:\t\t${options.casingFile}`) // LOG - Casing file
try {
let casingOptions = {casingSet: {}}
casingOptions.casingSet = jy.load(fs.readFileSync(options.casingFile, 'utf8'));
options = Object.assign({}, options, casingOptions);
} catch (err) {
console.error('\x1b[31m', `Casing file error - no such file or directory "${options.casingFile}"`)
if (options.verbose >= 1) {
console.error(err)
}
}
}

infoOut(`- Input file:\t\t${asFile}`) // LOG - Input file

// Get
Expand All @@ -131,6 +146,12 @@ async function run(asFile, options) {
if (resFormat.data) res = resFormat.data
}

// Change case OpenAPI document
if (options.casingSet) {
const resFormat = await asyncapiFormat.asyncapiChangeCase(res, options);
if (resFormat.data) res = resFormat.data
}

// Rename title AsyncAPI document
if (options.rename) {
const resRename = await asyncapiFormat.asyncapiRename(res, options);
Expand Down
Loading

0 comments on commit 9b384c5

Please sign in to comment.