From d5f7e5d23ac0a6ec264a28d100019b5cd1c9df7b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 8 Oct 2025 14:53:19 +0530 Subject: [PATCH 1/2] Release version v5.3.2 (#886) * [AB-1493], [AB-1504] Added changes for 2-way-sync (#884) - Added extra formats to be supported for spec to collection - Take description from Path Level parameter if not available in Path+Method level * Prepare release v5.3.2 --------- Co-authored-by: Avishek Saha Co-authored-by: Ayush Shrivastav <42120573+AyushShri@users.noreply.github.com> Co-authored-by: GitHub Actions --- CHANGELOG.md | 6 ++- lib/schemaUtils.js | 11 ++++- libV2/schemaUtils.js | 23 +++++++-- libV2/validationUtils.js | 11 ++++- package-lock.json | 4 +- package.json | 2 +- test/unit/convertV2WithTypes.test.js | 71 ++++++++++++++++++++++++++-- 7 files changed, 111 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 54fa3d212..5469b6804 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [v5.3.2] - 2025-10-08 + ## [v5.3.1] - 2025-09-26 ## [v5.3.0] - 2025-09-24 @@ -667,7 +669,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/v5.3.1...HEAD +[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.2...HEAD + +[v5.3.2]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.1...v5.3.2 [v5.3.1]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.0...v5.3.1 diff --git a/lib/schemaUtils.js b/lib/schemaUtils.js index 2a6f7ad0a..ffce858f0 100644 --- a/lib/schemaUtils.js +++ b/lib/schemaUtils.js @@ -577,18 +577,25 @@ module.exports = { // will get precedence var reqParam = operationParam.slice(); pathParam.forEach((param) => { - var dupParam = operationParam.find(function(element) { + var dupParamIndex = operationParam.findIndex(function(element) { return element.name === param.name && element.in === param.in && // the below two conditions because undefined === undefined returns true element.name && param.name && element.in && param.in; }); - if (!dupParam) { + if (dupParamIndex === -1) { // if there's no duplicate param in operationParam, // use the one from the common pathParam list // this ensures that operationParam is given precedence reqParam.push(param); } + else { + // duplicate exists; prefer operation-level param but fallback description from path-level + var opParam = reqParam[dupParamIndex]; + if (!_.get(opParam, 'description') && _.get(param, 'description')) { + opParam.description = param.description; + } + } }); return reqParam; }, diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index 0e75a4964..ee3424b39 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -44,12 +44,17 @@ const schemaFaker = require('../assets/json-schema-faker'), 'hostname', 'ipv4', 'ipv6', 'regex', - 'uuid', + 'uuid', 'uid', 'binary', 'json-pointer', - 'int64', + 'base64', + 'int64', 'int32', 'float', - 'double' + 'double', + 'url', + 'http-status-code', + 'byte', + 'password' ], typesMap = { @@ -2114,18 +2119,26 @@ let QUERYPARAM = 'query', // will get precedence var reqParam = operationParam.slice(); pathParam.forEach((param) => { - var dupParam = operationParam.find(function(element) { + var dupParamIndex = operationParam.findIndex(function(element) { return element.name === param.name && element.in === param.in && // the below two conditions because undefined === undefined returns true element.name && param.name && element.in && param.in; }); - if (!dupParam) { + if (dupParamIndex === -1) { // if there's no duplicate param in operationParam, // use the one from the common pathParam list // this ensures that operationParam is given precedence reqParam.push(param); } + else { + // duplicate exists; prefer operation-level param but fallback description from path-level + var opParam = reqParam[dupParamIndex]; + // If operation-level description not present, copy from path-level parameter + if (!_.get(opParam, 'description') && _.get(param, 'description')) { + opParam.description = param.description; + } + } }); return reqParam; }, diff --git a/libV2/validationUtils.js b/libV2/validationUtils.js index ceabf1d57..1ee7e38c9 100644 --- a/libV2/validationUtils.js +++ b/libV2/validationUtils.js @@ -1082,18 +1082,25 @@ function getRequestParams (context, operationParam, pathParam) { // will get precedence var reqParam = operationParam.slice(); pathParam.forEach((param) => { - var dupParam = operationParam.find(function(element) { + var dupParamIndex = operationParam.findIndex(function(element) { return element.name === param.name && element.in === param.in && // the below two conditions because undefined === undefined returns true element.name && param.name && element.in && param.in; }); - if (!dupParam) { + if (dupParamIndex === -1) { // if there's no duplicate param in operationParam, // use the one from the common pathParam list // this ensures that operationParam is given precedence reqParam.push(param); } + else { + // duplicate exists; prefer operation-level param but fallback description from path-level + const opParam = reqParam[dupParamIndex]; + if (!_.get(opParam, 'description') && _.get(param, 'description')) { + opParam.description = param.description; + } + } }); return reqParam; } diff --git a/package-lock.json b/package-lock.json index 9b14697b6..c14632b11 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openapi-to-postmanv2", - "version": "5.3.1", + "version": "5.3.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openapi-to-postmanv2", - "version": "5.3.1", + "version": "5.3.2", "license": "Apache-2.0", "dependencies": { "ajv": "^8.11.0", diff --git a/package.json b/package.json index 6d2fa1ada..3229f2a9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openapi-to-postmanv2", - "version": "5.3.1", + "version": "5.3.2", "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", diff --git a/test/unit/convertV2WithTypes.test.js b/test/unit/convertV2WithTypes.test.js index 7157ff6b7..339db552a 100644 --- a/test/unit/convertV2WithTypes.test.js +++ b/test/unit/convertV2WithTypes.test.js @@ -224,7 +224,7 @@ describe('convertV2WithTypes', function() { 'headers': '[\n {\n "keyName": "x-next",\n "properties": {\n "type": "string",\n "default": ""\n }\n }\n]' }, '500': { - 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', + 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer",\n "format": "int32"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', 'headers': '[]' } } @@ -240,7 +240,7 @@ describe('convertV2WithTypes', function() { 'headers': '[]' }, '500': { - 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', + 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer",\n "format": "int32"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', 'headers': '[]' } } @@ -257,7 +257,7 @@ describe('convertV2WithTypes', function() { 'headers': '[]' }, '500': { - 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', + 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer",\n "format": "int32"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', 'headers': '[]' } } @@ -274,7 +274,7 @@ describe('convertV2WithTypes', function() { 'headers': '[]' }, '500': { - 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', + 'body': '{\n "type": "object",\n "properties": {\n "code": {\n "type": "integer",\n "format": "int32"\n },\n "message": {\n "type": "string"\n }\n },\n "required": [\n "code",\n "message"\n ]\n}', 'headers': '[]' } } @@ -1099,5 +1099,68 @@ describe('convertV2WithTypes', function() { done(); }); }); + + it('should fallback parameter description from path-level to operation-level duplicates', function(done) { + const openApiWithParamFallback = { + openapi: '3.0.0', + info: { title: 'Param Fallback API', version: '1.0.0' }, + paths: { + '/pets/{id}': { + parameters: [ + { name: 'id', in: 'path', required: true, description: 'Path id description', schema: { type: 'string' } }, + { name: 'q', in: 'query', description: 'Path-level query description', schema: { type: 'string' } } + ], + get: { + // Duplicate params at operation-level without description; should inherit from path-level + parameters: [ + { name: 'id', in: 'path', required: true, schema: { type: 'string' } }, + { name: 'q', in: 'query', schema: { type: 'string' } } + ], + responses: { + '200': { + description: 'OK', + content: { 'application/json': { schema: { type: 'string' } } } + } + } + } + } + } + }; + + Converter.convertV2WithTypes({ type: 'json', data: openApiWithParamFallback }, {}, (err, conversionResult) => { + expect(err).to.be.null; + expect(conversionResult.result).to.equal(true); + + const rootItems = conversionResult.output[0].data.item; + const findFirstRequest = (nodes) => { + if (!Array.isArray(nodes)) { return null; } + for (let i = 0; i < nodes.length; i++) { + const node = nodes[i]; + if (node && node.request) { return node; } + if (node && Array.isArray(node.item)) { + const found = findFirstRequest(node.item); + if (found) { return found; } + } + } + return null; + }; + const item = findFirstRequest(rootItems); + expect(item, 'No request item found in generated collection').to.not.be.null; + + // Path variable description should come from path-level param + const pathVars = item.request.url.variable; + expect(pathVars).to.be.an('array').with.length(1); + expect(pathVars[0]).to.have.property('key', 'id'); + expect(pathVars[0]).to.have.nested.property('description.content', 'Path id description'); + + // Query param description should come from path-level param + const queryParams = item.request.url.query; + const qParam = queryParams.find((p) => { return p.key === 'q'; }); + expect(qParam).to.not.be.undefined; + expect(qParam).to.have.nested.property('description.content', 'Path-level query description'); + + done(); + }); + }); }); From 5fed2c32f6b85f3690f5200454fa59a36a6c9982 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 14 Oct 2025 13:22:35 +0000 Subject: [PATCH 2/2] Prepare release v5.3.3 --- CHANGELOG.md | 6 +++++- package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5469b6804..10222c95c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased] +## [v5.3.3] - 2025-10-14 + ## [v5.3.2] - 2025-10-08 ## [v5.3.1] - 2025-09-26 @@ -669,7 +671,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/v5.3.2...HEAD +[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.3...HEAD + +[v5.3.3]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.2...v5.3.3 [v5.3.2]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.1...v5.3.2 diff --git a/package-lock.json b/package-lock.json index c14632b11..2f99cd120 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "openapi-to-postmanv2", - "version": "5.3.2", + "version": "5.3.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "openapi-to-postmanv2", - "version": "5.3.2", + "version": "5.3.3", "license": "Apache-2.0", "dependencies": { "ajv": "^8.11.0", diff --git a/package.json b/package.json index 3229f2a9a..6df1aa563 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openapi-to-postmanv2", - "version": "5.3.2", + "version": "5.3.3", "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",