diff --git a/CHANGELOG.md b/CHANGELOG.md index 93a7c02d..32a9c02c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,17 @@ ## [Unreleased] +## [v4.23.1] - 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. + ## [v4.22.0] - 2024-07-10 ### Chore @@ -626,7 +637,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.1...HEAD + +[v4.23.1]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.22.0...v4.23.1 [v4.22.0]: https://github.com/postmanlabs/openapi-to-postman/compare/v4.21.0...v4.22.0 diff --git a/lib/bundle.js b/lib/bundle.js index e97cc190..6a4cdf08 100644 --- a/lib/bundle.js +++ b/lib/bundle.js @@ -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'), diff --git a/lib/deref.js b/lib/deref.js index baa2e589..98cee435 100644 --- a/lib/deref.js +++ b/lib/deref.js @@ -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']; /** diff --git a/lib/relatedFiles.js b/lib/relatedFiles.js index 08563731..0d40c21b 100644 --- a/lib/relatedFiles.js +++ b/lib/relatedFiles.js @@ -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'); diff --git a/lib/schemaUtils.js b/lib/schemaUtils.js index 78a49461..2a6f7ad0 100644 --- a/lib/schemaUtils.js +++ b/lib/schemaUtils.js @@ -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 diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index ec9474b5..ea828681 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -45,6 +45,7 @@ const schemaFaker = require('../assets/json-schema-faker'), 'ipv4', 'ipv6', 'regex', 'uuid', + 'binary', 'json-pointer', 'int64', 'float', @@ -652,7 +653,6 @@ let QUERYPARAM = 'query', if ( property.format === 'decimal' || property.format === 'byte' || - property.format === 'binary' || property.format === 'password' || property.format === 'unix-time' ) { @@ -983,7 +983,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' ) { @@ -1508,7 +1507,6 @@ let QUERYPARAM = 'query', } if ( - requestBodySchema.properties[prop].format === 'binary' || requestBodySchema.properties[prop].format === 'byte' || requestBodySchema.properties[prop].format === 'decimal' ) { @@ -1668,7 +1666,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: '', diff --git a/libV2/validationUtils.js b/libV2/validationUtils.js index 7ac2a9aa..ceabf1d5 100644 --- a/libV2/validationUtils.js +++ b/libV2/validationUtils.js @@ -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 }); /** diff --git a/package-lock.json b/package-lock.json index fdc68c23..42d5658f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openapi-to-postmanv2", - "version": "4.22.0", + "version": "4.23.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openapi-to-postmanv2", - "version": "4.22.0", + "version": "4.23.1", "license": "Apache-2.0", "dependencies": { "ajv": "8.11.0", @@ -19,12 +19,12 @@ "json-pointer": "0.6.2", "json-schema-merge-allof": "0.8.1", "lodash": "4.17.21", + "neotraverse": "0.6.15", "oas-resolver-browser": "2.5.6", "object-hash": "3.0.0", "path-browserify": "1.0.1", "postman-collection": "^4.4.0", "swagger2openapi": "7.0.8", - "traverse": "0.6.6", "yaml": "1.10.2" }, "bin": { @@ -111,9 +111,9 @@ } }, "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -163,9 +163,9 @@ } }, "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -2710,9 +2710,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -3055,9 +3055,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true, "bin": { "semver": "bin/semver.js" @@ -3275,6 +3275,14 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "node_modules/neotraverse": { + "version": "0.6.15", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.15.tgz", + "integrity": "sha512-HZpdkco+JeXq0G+WWpMJ4NsX3pqb5O7eR9uGz3FfoFt+LYzU8iRWp49nJtud6hsDoywM8tIrDo3gjgmOqJA8LA==", + "engines": { + "node": ">= 10" + } + }, "node_modules/nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -4645,9 +4653,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true, "bin": { "semver": "bin/semver" @@ -5238,11 +5246,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, - "node_modules/traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" - }, "node_modules/tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -5479,9 +5482,9 @@ } }, "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true, "engines": { "node": ">=0.10.0" @@ -5714,9 +5717,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -5756,9 +5759,9 @@ } }, "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true }, "yallist": { @@ -7645,9 +7648,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -7917,9 +7920,9 @@ }, "dependencies": { "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "dev": true } } @@ -8093,6 +8096,11 @@ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", "dev": true }, + "neotraverse": { + "version": "0.6.15", + "resolved": "https://registry.npmjs.org/neotraverse/-/neotraverse-0.6.15.tgz", + "integrity": "sha512-HZpdkco+JeXq0G+WWpMJ4NsX3pqb5O7eR9uGz3FfoFt+LYzU8iRWp49nJtud6hsDoywM8tIrDo3gjgmOqJA8LA==" + }, "nice-try": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", @@ -9133,9 +9141,9 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", "dev": true }, "set-blocking": { @@ -9597,11 +9605,6 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, - "traverse": { - "version": "0.6.6", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", - "integrity": "sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw==" - }, "tslib": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", @@ -9788,9 +9791,9 @@ } }, "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", + "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==", "dev": true }, "wrap-ansi": { diff --git a/package.json b/package.json index 829e8bbf..450a3363 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openapi-to-postmanv2", - "version": "4.22.0", + "version": "4.23.1", "description": "Convert a given OpenAPI specification to Postman Collection v2.0", "homepage": "https://github.com/postmanlabs/openapi-to-postman", "bugs": "https://github.com/postmanlabs/openapi-to-postman/issues", @@ -125,13 +125,13 @@ "json-pointer": "0.6.2", "json-schema-merge-allof": "0.8.1", "lodash": "4.17.21", + "neotraverse": "0.6.15", "oas-resolver-browser": "2.5.6", "object-hash": "3.0.0", "graphlib": "2.1.8", "path-browserify": "1.0.1", "postman-collection": "^4.4.0", "swagger2openapi": "7.0.8", - "traverse": "0.6.6", "yaml": "1.10.2" }, "author": "Postman Labs ", diff --git a/test/data/valid_openapi/form-binary-file.json b/test/data/valid_openapi/form-binary-file.json new file mode 100644 index 00000000..9b674793 --- /dev/null +++ b/test/data/valid_openapi/form-binary-file.json @@ -0,0 +1,37 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Form Data - Binary - OpenAPI 3.0", + "version": "1.0.0" + }, + "paths": { + "/uploadImage": { + "post": { + "summary": "uploads an image", + "description": "", + "operationId": "uploadFile", + "requestBody": { + "required": true, + "content": { + "multipart/form-data": { + "schema": { + "properties": { + "inputfile": { + "type": "string", + "format": "binary", + "description": "The file to be uploaded." + } + } + } + } + } + }, + "responses": { + "200": { + "description": "successful operation" + } + } + } + } + } +} diff --git a/test/unit/convertV2.test.js b/test/unit/convertV2.test.js index b554203b..985e3499 100644 --- a/test/unit/convertV2.test.js +++ b/test/unit/convertV2.test.js @@ -120,7 +120,8 @@ const expect = require('chai').expect, readOnlyOneOfSpec = path.join(__dirname, VALID_OPENAPI_PATH, '/readOnlyOneOf.json'), readOnlyNestedSpec = - path.join(__dirname, VALID_OPENAPI_PATH, '/readOnlyNested.json'); + path.join(__dirname, VALID_OPENAPI_PATH, '/readOnlyNested.json'), + issue795 = path.join(__dirname, VALID_OPENAPI_PATH, '/form-binary-file.json'); describe('The convert v2 Function', function() { @@ -2928,4 +2929,25 @@ describe('The convert v2 Function', function() { }); }); }); + + it('[Github #795] Should properly convert format binary to form data', function (done) { + var openapi = fs.readFileSync(issue795, 'utf8'), + reqBody, formData; + Converter.convertV2({ type: 'string', data: openapi }, { + requestNameSource: 'Fallback', + indentCharacter: 'Space', + collapseFolders: true, + optimizeConversion: true, + parametersResolution: 'schema' + }, (err, conversionResult) => { + + reqBody = conversionResult.output[0].data.item[0].item[0].request.body; + formData = reqBody.formdata[0]; + + expect(err).to.be.null; + expect(conversionResult.result).to.equal(true); + expect(formData.type).to.equal('file'); + done(); + }); + }); }); diff --git a/test/unit/faker.test.js b/test/unit/faker.test.js index 465e4ae6..4e326c21 100644 --- a/test/unit/faker.test.js +++ b/test/unit/faker.test.js @@ -13,7 +13,8 @@ describe('JSON SCHEMA FAKER TESTS', function () { useDefaultValue: true, useExamplesValue: true, ignoreMissingRefs: true, - avoidExampleItemsLength: false + avoidExampleItemsLength: false, + failOnInvalidFormat: false }); }); @@ -27,7 +28,8 @@ describe('JSON SCHEMA FAKER TESTS', function () { maxItems: 20, useDefaultValue: true, ignoreMissingRefs: true, - avoidExampleItemsLength: true + avoidExampleItemsLength: true, + failOnInvalidFormat: false }); });