From e8a45bc3bb822ab185f022f3948d7da387af7270 Mon Sep 17 00:00:00 2001 From: Ayush Shrivastav Date: Wed, 29 Oct 2025 19:30:56 +0530 Subject: [PATCH 1/7] omitted schema props --- libV2/schemaUtils.js | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index d35703b9..3b5d9219 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -1257,11 +1257,32 @@ let QUERYPARAM = 'query', switch (style) { case 'form': if (explode && _.isObject(paramValue)) { - const isArrayValue = _.isArray(paramValue); + const schemaProps = _.get(param, 'schema.properties', {}), + hasProps = _.isObject(schemaProps) && !_.isEmpty(schemaProps), + isArrayValue = _.isArray(paramValue); + + // Free-form object: do not emit individual keys + if (!hasProps && !isArrayValue) { + return pmParams; + } _.forEach(paramValue, (value, key) => { + if (isArrayValue) { + pmParams.push({ + key: paramName, + value: (value === undefined ? '' : _.toString(value)), + description, + disabled + }); + return; + } + + if (!_.has(schemaProps, key)) { + return; + } + pmParams.push({ - key: isArrayValue ? paramName : key, + key, value: (value === undefined ? '' : _.toString(value)), description, disabled From a8e0a693fd08b18fad8314e8d735f98a2e94b819 Mon Sep 17 00:00:00 2001 From: Ayush Shrivastav Date: Thu, 30 Oct 2025 11:51:04 +0530 Subject: [PATCH 2/7] bug fix --- libV2/schemaUtils.js | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index 3b5d9219..f19e4089 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -1257,30 +1257,26 @@ let QUERYPARAM = 'query', switch (style) { case 'form': if (explode && _.isObject(paramValue)) { - const schemaProps = _.get(param, 'schema.properties', {}), - hasProps = _.isObject(schemaProps) && !_.isEmpty(schemaProps), - isArrayValue = _.isArray(paramValue); - - // Free-form object: do not emit individual keys - if (!hasProps && !isArrayValue) { - return pmParams; - } - - _.forEach(paramValue, (value, key) => { - if (isArrayValue) { + const isArrayValue = _.isArray(paramValue); + // Arrays: emit one entry per item with the parameter name + if (isArrayValue) { + _.forEach(paramValue, (value) => { pmParams.push({ key: paramName, value: (value === undefined ? '' : _.toString(value)), description, disabled }); - return; - } + }); + return pmParams; + } - if (!_.has(schemaProps, key)) { + // Objects: emit all keys except those that are schema definition keys + const schemaKeys = Object.keys(_.get(param, 'schema', {})); + _.forEach(paramValue, (value, key) => { + if (schemaKeys.includes(key)) { return; } - pmParams.push({ key, value: (value === undefined ? '' : _.toString(value)), @@ -1288,7 +1284,6 @@ let QUERYPARAM = 'query', disabled }); }); - return pmParams; } @@ -1296,7 +1291,6 @@ let QUERYPARAM = 'query', case 'deepObject': if (_.isObject(paramValue) && !_.isArray(paramValue)) { let extractedParams = extractDeepObjectParams(paramValue, paramName); - _.forEach(extractedParams, (extractedParam) => { pmParams.push({ key: extractedParam.key, From 0dd29065e29ac963b752bbbb53caef11190e655e Mon Sep 17 00:00:00 2001 From: Ayush Shrivastav Date: Thu, 30 Oct 2025 13:05:51 +0530 Subject: [PATCH 3/7] fixed bug --- libV2/schemaUtils.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index f19e4089..8ef780b4 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -1284,7 +1284,9 @@ let QUERYPARAM = 'query', disabled }); }); - return pmParams; + if (pmParams.length) { + return pmParams; + } } break; @@ -1299,8 +1301,9 @@ let QUERYPARAM = 'query', disabled }); }); - - return pmParams; + if (pmParams.length) { + return pmParams; + } } else if (_.isArray(paramValue)) { isNotSerializable = true; From 4ca858ad5a304031d1d220f9dec41c4b1c725ae1 Mon Sep 17 00:00:00 2001 From: Ayush Shrivastav Date: Thu, 30 Oct 2025 13:43:25 +0530 Subject: [PATCH 4/7] fixed deepObject styled query params --- libV2/schemaUtils.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index 8ef780b4..f28cfae2 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -1258,7 +1258,7 @@ let QUERYPARAM = 'query', case 'form': if (explode && _.isObject(paramValue)) { const isArrayValue = _.isArray(paramValue); - // Arrays: emit one entry per item with the parameter name + // Arrays if (isArrayValue) { _.forEach(paramValue, (value) => { pmParams.push({ @@ -1292,7 +1292,12 @@ let QUERYPARAM = 'query', break; case 'deepObject': if (_.isObject(paramValue) && !_.isArray(paramValue)) { - let extractedParams = extractDeepObjectParams(paramValue, paramName); + // Remove schema keys from the value before extraction + const schemaKeys = Object.keys(_.get(param, 'schema', {})), + filteredValue = _.omit(paramValue, schemaKeys); + + let extractedParams = extractDeepObjectParams(filteredValue, paramName); + _.forEach(extractedParams, (extractedParam) => { pmParams.push({ key: extractedParam.key, From 2298612bd9d630af8c58d8265394058171d1930b Mon Sep 17 00:00:00 2001 From: Ayush Shrivastav Date: Thu, 30 Oct 2025 17:13:56 +0530 Subject: [PATCH 5/7] added test cases --- test/unit/convertV2WithTypes.test.js | 72 ++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/test/unit/convertV2WithTypes.test.js b/test/unit/convertV2WithTypes.test.js index 38610dd9..e47a81d3 100644 --- a/test/unit/convertV2WithTypes.test.js +++ b/test/unit/convertV2WithTypes.test.js @@ -174,6 +174,78 @@ describe('convertV2WithTypes', function() { }); }); + it('should not emit schema.deprecated as query param key for form+explode and keep original param', function(done) { + const oas = { + openapi: '3.0.0', + info: { title: 'Form Explode Deprecated Test', version: '1.0.0' }, + paths: { + '/pets': { + get: { + parameters: [ + { + name: 'qp', + in: 'query', + schema: { type: 'object', deprecated: true }, + example: { deprecated: true } + } + ], + responses: { '200': { description: 'ok' } } + } + } + } + }; + + Converter.convertV2WithTypes({ type: 'json', data: oas }, {}, (err, conversionResult) => { + expect(err).to.be.null; + expect(conversionResult.result).to.equal(true); + + const items = conversionResult.output[0].data.item; + const request = items[0].item ? items[0].item[0].request : items[0].request; + const query = request.url.query || []; + + expect(query.some((p) => { return p.key === 'deprecated'; })).to.equal(false); + expect(query.some((p) => { return p.key === 'qp'; })).to.equal(true); + done(); + }); + }); + + it('should not emit qp[deprecated] for deepObject and keep original param', function(done) { + const oas = { + openapi: '3.0.0', + info: { title: 'DeepObject Deprecated Test', version: '1.0.0' }, + paths: { + '/pets': { + get: { + parameters: [ + { + name: 'qp', + in: 'query', + style: 'deepObject', + explode: true, + schema: { type: 'object', deprecated: true }, + example: { deprecated: true } + } + ], + responses: { '200': { description: 'ok' } } + } + } + } + }; + + Converter.convertV2WithTypes({ type: 'json', data: oas }, {}, (err, conversionResult) => { + expect(err).to.be.null; + expect(conversionResult.result).to.equal(true); + + const items = conversionResult.output[0].data.item; + const request = items[0].item ? items[0].item[0].request : items[0].request; + const query = request.url.query || []; + + expect(query.some((p) => { return (/^qp\[deprecated\]/).test(p.key); })).to.equal(false); + expect(query.some((p) => { return p.key === 'qp'; })).to.equal(true); + done(); + }); + }); + it('should resolve nested array and object schema types correctly in extractedTypes', function(done) { const example = { name: 'Buddy', From dcf896cd6af7d786c4a98d0e03ffb2ffe6bedb70 Mon Sep 17 00:00:00 2001 From: Ayush Shrivastav Date: Fri, 31 Oct 2025 14:29:30 +0530 Subject: [PATCH 6/7] handling for schema properties --- libV2/schemaUtils.js | 50 ++++++++++++++++++++-------- test/unit/convertV2WithTypes.test.js | 48 +++++++++++++++++++++++--- 2 files changed, 80 insertions(+), 18 deletions(-) diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index f28cfae2..b7e77222 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -1271,19 +1271,34 @@ let QUERYPARAM = 'query', return pmParams; } - // Objects: emit all keys except those that are schema definition keys - const schemaKeys = Object.keys(_.get(param, 'schema', {})); - _.forEach(paramValue, (value, key) => { - if (schemaKeys.includes(key)) { - return; - } - pmParams.push({ - key, - value: (value === undefined ? '' : _.toString(value)), - description, - disabled + // Objects: + // If declared properties exist, include only declared properties. + // Else, exclude top-level schema keys. + const schemaProps = _.get(param, 'schema.properties'); + const hasProps = _.isObject(schemaProps) && !_.isEmpty(schemaProps); + if (hasProps) { + _.forEach(paramValue, (value, key) => { + if (!_.has(schemaProps, key)) { return; } + pmParams.push({ + key, + value: (value === undefined ? '' : _.toString(value)), + description, + disabled + }); }); - }); + } + else { + const schemaKeys = Object.keys(_.get(param, 'schema', {})); + _.forEach(paramValue, (value, key) => { + if (schemaKeys.includes(key)) { return; } + pmParams.push({ + key, + value: (value === undefined ? '' : _.toString(value)), + description, + disabled + }); + }); + } if (pmParams.length) { return pmParams; } @@ -1292,9 +1307,16 @@ let QUERYPARAM = 'query', break; case 'deepObject': if (_.isObject(paramValue) && !_.isArray(paramValue)) { - // Remove schema keys from the value before extraction - const schemaKeys = Object.keys(_.get(param, 'schema', {})), + let filteredValue; + const schemaProps = _.get(param, 'schema.properties'); + const hasProps = _.isObject(schemaProps) && !_.isEmpty(schemaProps); + if (hasProps) { + filteredValue = _.pick(paramValue, Object.keys(schemaProps)); + } + else { + const schemaKeys = Object.keys(_.get(param, 'schema', {})); filteredValue = _.omit(paramValue, schemaKeys); + } let extractedParams = extractDeepObjectParams(filteredValue, paramName); diff --git a/test/unit/convertV2WithTypes.test.js b/test/unit/convertV2WithTypes.test.js index e47a81d3..03707fb8 100644 --- a/test/unit/convertV2WithTypes.test.js +++ b/test/unit/convertV2WithTypes.test.js @@ -185,8 +185,7 @@ describe('convertV2WithTypes', function() { { name: 'qp', in: 'query', - schema: { type: 'object', deprecated: true }, - example: { deprecated: true } + schema: { deprecated: true } } ], responses: { '200': { description: 'ok' } } @@ -222,8 +221,7 @@ describe('convertV2WithTypes', function() { in: 'query', style: 'deepObject', explode: true, - schema: { type: 'object', deprecated: true }, - example: { deprecated: true } + schema: { deprecated: true } } ], responses: { '200': { description: 'ok' } } @@ -246,6 +244,48 @@ describe('convertV2WithTypes', function() { }); }); + it('should include declared schema.properties (including keys like type) for form+explode', function(done) { + const oas = { + openapi: '3.0.0', + info: { title: 'Declared Properties Test', version: '1.0.0' }, + paths: { + '/pets': { + get: { + parameters: [ + { + name: 'qp', + in: 'query', + schema: { + type: 'object', + deprecated: true, + properties: { + name: { type: 'string' }, + type: { type: 'string', deprecated: true } + } + } + } + ], + responses: { '200': { description: 'ok' } } + } + } + } + }; + + Converter.convertV2WithTypes({ type: 'json', data: oas }, {}, (err, conversionResult) => { + expect(err).to.be.null; + expect(conversionResult.result).to.equal(true); + + const items = conversionResult.output[0].data.item; + const request = items[0].item ? items[0].item[0].request : items[0].request; + const query = request.url.query || []; + + expect(query.some((p) => { return p.key === 'name'; })).to.equal(true); + expect(query.some((p) => { return p.key === 'type'; })).to.equal(true); + expect(query.some((p) => { return p.key === 'deprecated'; })).to.equal(false); + done(); + }); + }); + it('should resolve nested array and object schema types correctly in extractedTypes', function(done) { const example = { name: 'Buddy', From b36a4f2fe606b4ae24b436ea8fafb6b3a654bada Mon Sep 17 00:00:00 2001 From: Ayush Shrivastav Date: Fri, 31 Oct 2025 19:54:22 +0530 Subject: [PATCH 7/7] Added intersection for schema keys --- libV2/schemaUtils.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libV2/schemaUtils.js b/libV2/schemaUtils.js index b7e77222..57a2a3d4 100644 --- a/libV2/schemaUtils.js +++ b/libV2/schemaUtils.js @@ -1312,6 +1312,14 @@ let QUERYPARAM = 'query', const hasProps = _.isObject(schemaProps) && !_.isEmpty(schemaProps); if (hasProps) { filteredValue = _.pick(paramValue, Object.keys(schemaProps)); + // Strip each declared property's own schema keys from its value before extraction + _.forEach(filteredValue, (propValue, propName) => { + if (_.isObject(propValue)) { + // taking only the keys that are declared in the schema + const propSchemaKeys = Object.keys(_.get(schemaProps, propName, {})); + filteredValue[propName] = _.omit(propValue, propSchemaKeys); + } + }); } else { const schemaKeys = Object.keys(_.get(param, 'schema', {}));