Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
id|type|available options|default|description|usage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

|---|---|---|---|---|---|
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 spec’s 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
15 changes: 10 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down
69 changes: 61 additions & 8 deletions bin/openapi2postmanv2.js
Original file line number Diff line number Diff line change
@@ -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 option supplied ', 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 */
Expand All @@ -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;

Expand All @@ -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');
});
}
}
Expand All @@ -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);
}
Expand Down
8 changes: 8 additions & 0 deletions examples/cli-options-config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this used?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just an example of how option config can be used. Not used anywhere.

"folderStrategy": "Paths",
"requestNameSource": "Fallback",
"indentCharacter": "Space",
"collapseFolders": true,
"requestParametersResolution": "Example",
"exampleParametersResolution": "Example"
}
36 changes: 35 additions & 1 deletion test/system/structure.test.js
Original file line number Diff line number Diff line change
@@ -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 = [
Expand Down Expand Up @@ -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();

Expand Down Expand Up @@ -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()));
});
});