Added support for cli options via args and config file

This commit is contained in:
Vishal Shingala
2020-09-20 21:13:21 +05:30
parent b64d91025e
commit 02ee2642a1
5 changed files with 132 additions and 14 deletions

18
OPTIONS.md Normal file
View File

@@ -0,0 +1,18 @@
id|type|available options|default|description|usage
|---|---|---|---|---|---|
requestNameSource|enum|URL, Fallback|Fallback|Determines how the requests inside the generated collection will be named. If “Fallback” is selected, the request will be named after one of the following schema values: `description`, `operationid`, `url`.|CONVERSION, VALIDATION
indentCharacter|enum|Space, Tab|Space|Option for setting indentation character|CONVERSION
collapseFolders|boolean|-|true|Importing will collapse all folders that have only one child element and lack persistent folder-level data.|CONVERSION
optimizeConversion|boolean|-|true|Optimizes conversion for large specification, disabling this option might affect the performance of conversion.|CONVERSION
requestParametersResolution|enum|Example, Schema|Schema|Select whether to generate the request parameters based on the [schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#schemaObject) or the [example](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#exampleObject) in the schema.|CONVERSION
exampleParametersResolution|enum|Example, Schema|Example|Select whether to generate the response parameters based on the [schema](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#schemaObject) or the [example](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#exampleObject) in the schema.|CONVERSION
folderStrategy|enum|Paths, Tags|Paths|Select whether to create folders according to the specs paths or tags.|CONVERSION
includeAuthInfoInExample|boolean|-|true|Select whether to include authentication parameters in the example request|CONVERSION
shortValidationErrors|boolean|-|false|Whether detailed error messages are required for request <> schema validation operations.|VALIDATION
validationPropertiesToIgnore|array|-|[]|Specific properties (parts of a request/response pair) to ignore during validation. Must be sent as an array of strings. Valid inputs in the array: PATHVARIABLE, QUERYPARAM, HEADER, BODY, RESPONSE_HEADER, RESPONSE_BODY|VALIDATION
showMissingInSchemaErrors|boolean|-|false|MISSING_IN_SCHEMA indicates that an extra parameter was included in the request. For most use cases, this need not be considered an error.|VALIDATION
detailedBlobValidation|boolean|-|false|Determines whether to show detailed mismatch information for application/json content in the request/response body.|VALIDATION
suggestAvailableFixes|boolean|-|false|Whether to provide fixes for patching corresponding mismatches.|VALIDATION
validateMetadata|boolean|-|false|Whether to show mismatches for incorrect name and description of request|VALIDATION
ignoreUnresolvedVariables|boolean|-|false|Whether to ignore mismatches resulting from unresolved variables in the Postman request|VALIDATION
strictRequestMatching|boolean|-|false|Whether requests should be strictly matched with schema operations. Setting to true will not include any matches where the URL path segments don't match exactly.|VALIDATION

View File

@@ -89,9 +89,8 @@ function (err, result) {
```
### Options:
* `'schemaFaker'(boolean)`: whether to use json-schema-faker for schema conversion. Default: `true`
* `'requestNameSource'(string)`: The strategy to use to generate request names. url: use the request's URL as the name, fallback: Use the summary/operationId/URL (in that order) Default: `fallback`
* `'indentCharacter' (string)`: The character to use per level of indentation for JSON/XML data. Default: `' '(space)`
Check out complete list of options and their usage at [OPTIONS.md](/OPTIONS.md)
### ConversionResult
@@ -169,6 +168,12 @@ The converter can be used as a CLI tool as well. The following [command line opt
- `-p`, `--pretty`
Used to pretty print the collection object while writing to a file
- `-O`, `--options`
Used to supply options to the converter, for complete options details see [here](/OPTIONS.md)
- `-c`, `--options-config`
Used to supply options to the converter through config file, for complete options details see [here](/OPTIONS.md)
- `-h`, `--help`
Specifies all the options along with a few usage examples on the terminal
@@ -178,9 +183,9 @@ The converter can be used as a CLI tool as well. The following [command line opt
**Sample usage examples of the converter CLI**
- Takes a specification (spec.yaml) as an input and writes to a file (collection.json) with pretty printing
- Takes a specification (spec.yaml) as an input and writes to a file (collection.json) with pretty printing and using provided options
```terminal
$ openapi2postmanv2 -s spec.yaml -o collection.json -p
$ openapi2postmanv2 -s spec.yaml -o collection.json -p -O folderStrategy=Tags,includeAuthInfoInExample=false
```
- Testing the converter

View File

@@ -1,22 +1,57 @@
#!/usr/bin/env node
var program = require('commander'),
var _ = require('lodash'),
program = require('commander'),
Converter = require('../index.js'),
fs = require('fs'),
path = require('path'),
availableOptions = require('../lib/options').getOptions('use', { usage: ['CONVERSION'] }),
inputFile,
outputFile,
prettyPrintFlag,
configFile,
definedOptions,
testFlag,
swaggerInput,
swaggerData;
/**
* Parses comma separated options mentioned in command args and generates JSON object
*
* @param {String} value - User defined options value
* @returns {Object} - Parsed option in format of JSON object
*/
function parseOptions (value) {
let definedOptions = value.split(','),
parsedOptions = {};
_.forEach(definedOptions, (definedOption) => {
let option = definedOption.split('=');
if (option.length === 2 && _.includes(_.keys(availableOptions), option[0])) {
try {
// parse parsable data types (e.g. boolean, integer etc)
parsedOptions[option[0]] = JSON.parse(option[1]);
}
catch (e) {
// treat value as string if can not be parsed
parsedOptions[option[0]] = option[1];
}
}
else {
console.warn('\x1b[33m%s\x1b[0m', 'Warning: Invalid defined option ', option[0]);
}
});
return parsedOptions;
}
program
.version(require('../package.json').version, '-v, --version')
.option('-s, --spec <spec>', 'Convert given OPENAPI 3.0.0 spec to Postman Collection v2.0')
.option('-o, --output <output>', 'Write the collection to an output file')
.option('-t, --test', 'Test the OPENAPI converter')
.option('-p, --pretty', 'Pretty print the JSON file');
.option('-p, --pretty', 'Pretty print the JSON file')
.option('-c, --options-config <optionsConfig>', 'JSON file containing Converter options')
.option('-O, --options <options>', 'comma separated list of options', parseOptions);
program.on('--help', function() {
/* eslint-disable */
@@ -41,6 +76,8 @@ inputFile = program.spec;
outputFile = program.output || false;
testFlag = program.test || false;
prettyPrintFlag = program.pretty || false;
configFile = program.config || false;
definedOptions = program.options || {};
swaggerInput;
swaggerData;
@@ -55,14 +92,16 @@ swaggerData;
function writetoFile(prettyPrintFlag, file, collection) {
if (prettyPrintFlag) {
fs.writeFile(file, JSON.stringify(collection, null, 4), (err) => {
if (err) { console.log('Could not write to file', err); }
console.log('Conversion successful', 'Collection written to file');
if (err) { console.log('Could not write to file', err); } // eslint-disable-line no-console
// eslint-disable-next-line no-console
console.log('\x1b[32m%s\x1b[0m', 'Conversion successful, collection written to file');
});
}
else {
fs.writeFile(file, JSON.stringify(collection), (err) => {
if (err) { console.log('Could not write to file', err); }
console.log('Conversion successful', 'Collection written to file');
if (err) { console.log('Could not write to file', err); } // eslint-disable-line no-console
// eslint-disable-next-line no-console
console.log('\x1b[32m%s\x1b[0m', 'Conversion successful, collection written to file');
});
}
}
@@ -73,10 +112,24 @@ function writetoFile(prettyPrintFlag, file, collection) {
* @returns {void}
*/
function convert(swaggerData) {
let options = {};
// apply options from config file if present
if (configFile) {
configFile = path.resolve(configFile);
console.log('Options Config file: ', configFile); // eslint-disable-line no-console
options = JSON.parse(fs.readFileSync(configFile, 'utf8'));
}
// override options provided via cli
if (definedOptions) {
options = definedOptions;
}
Converter.convert({
type: 'string',
data: swaggerData
}, {}, (err, status) => {
}, options, (err, status) => {
if (err) {
return console.error(err);
}

View File

@@ -0,0 +1,8 @@
{
"folderStrategy": "Paths",
"requestNameSource": "Fallback",
"indentCharacter": "Space",
"collapseFolders": true,
"requestParametersResolution": "Example",
"exampleParametersResolution": "Example"
}

View File

@@ -1,4 +1,6 @@
let expect = require('chai').expect,
let fs = require('fs'),
_ = require('lodash'),
expect = require('chai').expect,
getOptions = require('../../index').getOptions;
const optionIds = [
@@ -140,6 +142,32 @@ const optionIds = [
}
};
/**
* Generates markdown table documentation of options from getOptions()
*
* @param {Object} options - options from getOptions()
* @returns {String} - markdown table consisting documetation for options
*/
function generateOptionsDoc (options) {
var doc = 'id|type|available options|default|description|usage\n|---|---|---|---|---|---|\n';
_.forEach(options, (option) => {
var convertArrayToDoc = (array) => {
return _.reduce(array, (acc, ele) => {
return (_.isEmpty(acc) ? acc : acc + ', ') + ele;
}, '') || '-';
},
defaultOption = option.default;
// override empty values with stringified equivalent to represent correctly in README
(_.isEmpty(defaultOption)) && (defaultOption = JSON.stringify(defaultOption));
doc += `${option.id}|${option.type}|${convertArrayToDoc(option.availableOptions, true)}|` +
`${defaultOption}|${option.description}|${convertArrayToDoc(option.usage)}\n`;
});
return doc;
}
describe('getOptions', function() {
let options = getOptions();
@@ -187,3 +215,9 @@ describe('getOptions', function() {
});
});
describe('OPTIONS.md', function() {
it('must contain all details of options', function () {
const optionsDoc = fs.readFileSync('OPTIONS.md', 'utf-8');
expect(optionsDoc).to.eql(generateOptionsDoc(getOptions()));
});
});