Skip to content

Commit

Permalink
Merge pull request #810 from postmanlabs/release/v4.23.0
Browse files Browse the repository at this point in the history
Release version v4.23.0
  • Loading branch information
VShingala authored Jul 22, 2024
2 parents 69a1509 + cde7edd commit 896c435
Show file tree
Hide file tree
Showing 16 changed files with 420 additions and 92 deletions.
19 changes: 18 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,21 @@

## [Unreleased]

## [v4.23.0] - 2024-07-22

### Added

- Conversion - Added option to set preferred request body content-type and use the first mentioned content-type as request body.

### Fixed

- Fixed issue with getOptions() API where default module version was still v1.
- Fix to convert "format:binary" to "type:file" for requests with formdata body.

### Chore

- Replace traverse with neotraverse to reduce related dependencies.

## [v4.22.0] - 2024-07-10

### Chore
Expand Down Expand Up @@ -626,7 +641,9 @@ Newer releases follow the [Keep a Changelog](https://keepachangelog.com/en/1.0.0

- Base release

[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.22.0...HEAD
[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.23.0...HEAD

[v4.23.0]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.22.0...v4.23.0

[v4.22.0]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.21.0...v4.22.0

Expand Down
6 changes: 6 additions & 0 deletions OPTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@ collapseFolders|boolean|-|true|Importing will collapse all folders that have onl
optimizeConversion|boolean|-|true|Optimizes conversion for large specification, disabling this option might affect the performance of conversion.|CONVERSION|v1
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|v1
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|v1
disabledParametersValidation|boolean|-|true|Whether disabled parameters of collection should be validated|VALIDATION|v2, v1
parametersResolution|enum|Example, Schema|Schema|Select whether to generate the request and 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|v2, v1
folderStrategy|enum|Paths, Tags|Paths|Select whether to create folders according to the spec’s paths or tags.|CONVERSION|v2, v1
schemaFaker|boolean|-|true|Whether or not schemas should be faked.|CONVERSION|v2, v1
stackLimit|integer|-|10|Number of nesting limit till which schema resolution will happen. Increasing this limit may result in more time to convert collection depending on complexity of specification. (To make sure this option works correctly "optimizeConversion" option needs to be disabled)|CONVERSION|v2, v1
includeAuthInfoInExample|boolean|-|true|Select whether to include authentication parameters in the example request.|CONVERSION|v2, v1
shortValidationErrors|boolean|-|false|Whether detailed error messages are required for request <> schema validation operations.|VALIDATION|v2, v1
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|v2, v1
Expand All @@ -20,5 +23,8 @@ strictRequestMatching|boolean|-|false|Whether requests should be strictly matche
allowUrlPathVarMatching|boolean|-|false|Whether to allow matching path variables that are available as part of URL itself in the collection request|VALIDATION|v2, v1
enableOptionalParameters|boolean|-|true|Optional parameters aren't selected in the collection. Once enabled they will be selected in the collection and request as well.|CONVERSION|v2, v1
keepImplicitHeaders|boolean|-|false|Whether to keep implicit headers from the OpenAPI specification, which are removed by default.|CONVERSION|v2, v1
includeWebhooks|boolean|-|false|Select whether to include Webhooks in the generated collection|CONVERSION|v2, v1
includeReferenceMap|boolean|-|false|Whether or not to include reference map or not as part of output|BUNDLE|v2, v1
includeDeprecated|boolean|-|true|Select whether to include deprecated operations, parameters, and properties in generated collection or not|CONVERSION, VALIDATION|v2, v1
alwaysInheritAuthentication|boolean|-|false|Whether authentication details should be included on every request, or always inherited from the collection.|CONVERSION|v2, v1
preferredRequestBodyType|enum|x-www-form-urlencoded, form-data, raw, first-listed|first-listed|When there are multiple content-types defined in the request body of OpenAPI, the conversion selects the preferred option content-type as request body.If "first-listed" is set, the first content-type defined in the OpenAPI spec will be selected.|CONVERSION|v2
2 changes: 1 addition & 1 deletion lib/bundle.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const _ = require('lodash'),
jsonPointerDecodeAndReplace,
generateObjectName
} = require('./jsonPointer'),
traverseUtility = require('traverse'),
traverseUtility = require('neotraverse/legacy'),
parse = require('./parse.js'),
{ ParseError } = require('./common/ParseError'),
Utils = require('./utils'),
Expand Down
2 changes: 1 addition & 1 deletion lib/deref.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const _ = require('lodash'),
isAllOf: false
},
DEFAULT_SCHEMA_UTILS = require('./30XUtils/schemaUtils30X'),
traverseUtility = require('traverse'),
traverseUtility = require('neotraverse/legacy'),
PROPERTIES_TO_ASSIGN_ON_CASCADE = ['type', 'nullable'];

/**
Expand Down
26 changes: 21 additions & 5 deletions lib/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,12 @@ module.exports = {
*
* @param {string} [mode='document'] Describes use-case. 'document' will return an array
* with all options being described. 'use' will return the default values of all options
* @param {Object} criteria Decribes required criteria for options to be returned. can have properties
* external: <boolean>
* usage: <array> (Array of supported usage type - CONVERSION, VALIDATION)
* version: <string> ('3.0' by default, supported values: '3.0', '3.1')
* @param {Object} criteria Decribes required criteria for options to be returned.
* @param {string} criteria.version The version of the OpenAPI spec to be converted
* (can be one of '2.0', '3.0', '3.1')
* @param {string} criteria.moduleVersion The version of the module (can be one of 'v1' or 'v2')
* @param {Array<string>} criteria.usage The usage of the option (values can be one of 'CONVERSION', 'VALIDATION')
* @param {boolean} criteria.external Whether the option is exposed to Postman App UI or not
* @returns {mixed} An array or object (depending on mode) that describes available options
*/
getOptions: function(mode = 'document', criteria = {}) {
Expand Down Expand Up @@ -386,6 +388,20 @@ module.exports = {
usage: ['CONVERSION'],
supportedIn: [VERSION20, VERSION30, VERSION31],
supportedModuleVersion: [MODULE_VERSION.V2, MODULE_VERSION.V1]
},
{
name: 'Select request body type',
id: 'preferredRequestBodyType',
type: 'enum',
default: 'first-listed',
availableOptions: ['x-www-form-urlencoded', 'form-data', 'raw', 'first-listed'],
description: 'When there are multiple content-types defined in the request body of OpenAPI, the conversion ' +
'selects the preferred option content-type as request body.If "first-listed" is set, the first ' +
'content-type defined in the OpenAPI spec will be selected.',
external: false,
usage: ['CONVERSION'],
supportedIn: [VERSION20, VERSION30, VERSION31],
supportedModuleVersion: [MODULE_VERSION.V2]
}
];

Expand All @@ -408,7 +424,7 @@ module.exports = {
}

// Setting default value
criteria.moduleVersion = _.has(criteria, 'moduleVersion') ? criteria.moduleVersion : MODULE_VERSION.V1;
criteria.moduleVersion = _.has(criteria, 'moduleVersion') ? criteria.moduleVersion : MODULE_VERSION.V2;

if (!_.includes(option.supportedModuleVersion, criteria.moduleVersion)) {
return false;
Expand Down
2 changes: 1 addition & 1 deletion lib/relatedFiles.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const parse = require('./parse.js'),
traverseUtility = require('traverse'),
traverseUtility = require('neotraverse/legacy'),
BROWSER = 'browser',
{ DFS } = require('./dfs'),
{ isExtRef, removeLocalReferenceFromPath } = require('./jsonPointer');
Expand Down
2 changes: 1 addition & 1 deletion lib/schemaUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const { formatDataPath, checkIsCorrectType, isKnownType } = require('./common/sc
{ Node, Trie } = require('./trie.js'),
{ validateSchema } = require('./ajValidation/ajvValidation'),
inputValidation = require('./30XUtils/inputValidation'),
traverseUtility = require('traverse'),
traverseUtility = require('neotraverse/legacy'),
{ ParseError } = require('./common/ParseError.js'),
SCHEMA_FORMATS = {
DEFAULT: 'default', // used for non-request-body data and json
Expand Down
52 changes: 40 additions & 12 deletions libV2/schemaUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const schemaFaker = require('../assets/json-schema-faker'),
'ipv4', 'ipv6',
'regex',
'uuid',
'binary',
'json-pointer',
'int64',
'float',
Expand Down Expand Up @@ -479,11 +480,11 @@ let QUERYPARAM = 'query',
* @param {Object} context - Global context
* @param {Object} schema - Schema that is to be resolved
* @param {Number} [stack] - Current recursion depth
* @param {String} resolveFor - For which action this resoltion is to be done
* @param {String} resolveFor - For which action this resolution is to be done
* @param {Object} seenRef - Map of all the references that have been resolved
* @todo: Explore using a directed graph/tree for maintaining seen ref
*
* @returns {Object} Returns the object that staisfies the schema
* @returns {Object} Returns the object that satisfies the schema
*/
resolveSchema = (context, schema, stack = 0, resolveFor = CONVERSION, seenRef = {}) => {
if (!schema) {
Expand Down Expand Up @@ -579,7 +580,6 @@ let QUERYPARAM = 'query',
if (
property.format === 'decimal' ||
property.format === 'byte' ||
property.format === 'binary' ||
property.format === 'password' ||
property.format === 'unix-time'
) {
Expand Down Expand Up @@ -843,7 +843,6 @@ let QUERYPARAM = 'query',
for (const prop in resolvedSchema.properties) {
if (resolvedSchema.properties.hasOwnProperty(prop)) {
if (
resolvedSchema.properties[prop].format === 'binary' ||
resolvedSchema.properties[prop].format === 'byte' ||
resolvedSchema.properties[prop].format === 'decimal'
) {
Expand Down Expand Up @@ -1358,7 +1357,6 @@ let QUERYPARAM = 'query',
}

if (
requestBodySchema.properties[prop].format === 'binary' ||
requestBodySchema.properties[prop].format === 'byte' ||
requestBodySchema.properties[prop].format === 'decimal'
) {
Expand Down Expand Up @@ -1518,7 +1516,7 @@ let QUERYPARAM = 'query',

// TODO: Add handling for headers from encoding

if (paramSchema && paramSchema.type === 'binary') {
if (paramSchema && paramSchema.type === 'string' && paramSchema.format === 'binary') {
param = {
key,
value: '',
Expand Down Expand Up @@ -1640,7 +1638,13 @@ let QUERYPARAM = 'query',

resolveRequestBodyForPostmanRequest = (context, operationItem) => {
let requestBody = operationItem.requestBody,
requestContent;
requestContent,
encodedRequestBody,
formDataRequestBody,
rawModeRequestBody;

const { preferredRequestBodyType: optionRequestBodyType } = context.computedOptions,
preferredRequestBodyType = optionRequestBodyType || 'first-listed';

if (!requestBody) {
return requestBody;
Expand All @@ -1659,15 +1663,38 @@ let QUERYPARAM = 'query',
};
}

if (requestContent[URLENCODED]) {
return resolveUrlEncodedRequestBodyForPostmanRequest(context, requestContent[URLENCODED]);
for (const contentType in requestContent) {
if (contentType === URLENCODED) {
encodedRequestBody = resolveUrlEncodedRequestBodyForPostmanRequest(context, requestContent[contentType]);
if (preferredRequestBodyType === 'first-listed') {
return encodedRequestBody;
}
}
else if (contentType === FORM_DATA) {
formDataRequestBody = resolveFormDataRequestBodyForPostmanRequest(context, requestContent[contentType]);
if (preferredRequestBodyType === 'first-listed') {
return formDataRequestBody;
}
}
else {
rawModeRequestBody = resolveRawModeRequestBodyForPostmanRequest(context, requestContent);
if (preferredRequestBodyType === 'first-listed') {
return rawModeRequestBody;
}
}
}

if (requestContent[FORM_DATA]) {
return resolveFormDataRequestBodyForPostmanRequest(context, requestContent[FORM_DATA]);
// Check if preferredRequestBodyType is provided and return the corresponding request body if available
if (preferredRequestBodyType) {
if (preferredRequestBodyType === 'x-www-form-urlencoded' && encodedRequestBody) {
return encodedRequestBody;
}
else if (preferredRequestBodyType === 'form-data' && formDataRequestBody) {
return formDataRequestBody;
}
}

return resolveRawModeRequestBodyForPostmanRequest(context, requestContent);
return rawModeRequestBody;
},

resolvePathItemParams = (context, operationParam, pathParam) => {
Expand Down Expand Up @@ -2236,6 +2263,7 @@ module.exports = {
},

resolveResponseForPostmanRequest,
resolveRequestBodyForPostmanRequest,
resolveRefFromSchema,
resolveSchema
};
3 changes: 2 additions & 1 deletion libV2/validationUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ schemaFaker.option({
maxItems: 20, // limit on maximum number of items faked for (type: array)
useDefaultValue: true,
ignoreMissingRefs: true,
avoidExampleItemsLength: true // option to avoid validating type array schema example's minItems and maxItems props.
avoidExampleItemsLength: true, // option to avoid validating type array schema example's minItems and maxItems props.
failOnInvalidFormat: false
});

/**
Expand Down
Loading

0 comments on commit 896c435

Please sign in to comment.