Skip to content

Commit d72cea9

Browse files
authored
Merge pull request #895 from postmanlabs/release/v5.3.4
Release version v5.3.4
2 parents 11b04ff + dd3823b commit d72cea9

File tree

6 files changed

+246
-12
lines changed

6 files changed

+246
-12
lines changed

CHANGELOG.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
## [Unreleased]
44

5+
## [v5.3.4] - 2025-11-06
6+
57
## [v5.3.3] - 2025-10-14
68

79
## [v5.3.2] - 2025-10-08
@@ -671,7 +673,9 @@ Newer releases follow the [Keep a Changelog](https://keepachangelog.com/en/1.0.0
671673

672674
- Base release
673675

674-
[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.3...HEAD
676+
[Unreleased]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.4...HEAD
677+
678+
[v5.3.4]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.3...v5.3.4
675679

676680
[v5.3.3]: https://github.com/postmanlabs/openapi-to-postman/compare/v5.3.2...v5.3.3
677681

assets/json-schema-faker.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24820,6 +24820,18 @@ function extend() {
2482024820
}
2482124821
}
2482224822
}
24823+
24824+
if (!type && path[path.length - 1] !== 'properties' && path[path.length - 1] !== 'items') {
24825+
// This is needed to handle the <Circular reference to schema> and <Error too many levels of nesting> case
24826+
// As those error values needs to be returned as is
24827+
if (typeof _.get(schema, 'value') === 'string') {
24828+
return schema;
24829+
}
24830+
24831+
// We're not able to determine the type, return empty string
24832+
return '';
24833+
}
24834+
2482324835
var copy = {};
2482424836
if (Array.isArray(schema)) {
2482524837
copy = [];

libV2/schemaUtils.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -753,9 +753,16 @@ let QUERYPARAM = 'query',
753753
}
754754

755755
if (schema.hasOwnProperty('additionalProperties')) {
756-
schema.additionalProperties = _.isBoolean(schema.additionalProperties) ? schema.additionalProperties :
757-
_resolveSchema(context, schema.additionalProperties, stack, resolveFor, _.cloneDeep(seenRef),
758-
utils.addToJsonPath(currentPath, ['additionalProperties']));
756+
// _.isEmpty check is needed to handle the case where additional properties is set as empty object.
757+
// which is valid as per OAS and means that additional properties are allowed (i.e it is equivalent to true)
758+
if (_.isBoolean(schema.additionalProperties) || _.isEmpty(schema.additionalProperties)) {
759+
schema.additionalProperties = Boolean(schema.additionalProperties);
760+
}
761+
else {
762+
schema.additionalProperties = _resolveSchema(context, schema.additionalProperties, stack, resolveFor,
763+
_.cloneDeep(seenRef), utils.addToJsonPath(currentPath, ['additionalProperties']));
764+
}
765+
759766
schema.type = schema.type || SCHEMA_TYPES.object;
760767
}
761768

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "openapi-to-postmanv2",
3-
"version": "5.3.3",
3+
"version": "5.3.4",
44
"description": "Convert a given OpenAPI specification to Postman Collection v2.0",
55
"homepage": "https://github.com/postmanlabs/openapi-to-postman",
66
"bugs": "https://github.com/postmanlabs/openapi-to-postman/issues",

test/unit/convertV2WithTypes.test.js

Lines changed: 216 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe('convertV2WithTypes should generate collection conforming to collection
6969

7070
it('should validate parameters of the collection', function (done) {
7171
const openapi = fs.readFileSync(testSpec1, 'utf8'),
72-
options = { schemaFaker: true, exampleParametersResolution: 'schema' };
72+
options = { schemaFaker: true, parametersResolution: 'schema' };
7373

7474
Converter.convertV2WithTypes({ type: 'string', data: openapi }, options, (err, conversionResult) => {
7575
expect(err).to.be.null;
@@ -90,7 +90,7 @@ describe('convertV2WithTypes should generate collection conforming to collection
9090
expect(createPet.request.method).to.equal('POST');
9191
expect(idDescription).to.equal('The id of the pet to retrieve');
9292
expect(createPet.request.body.mode).to.equal('raw');
93-
expect(createPet.request.body.raw).to.include('request body comes here');
93+
expect(createPet.request.body.raw).to.equal('');
9494

9595
const queryParams = listAllPets.request.url.query;
9696
expect(queryParams).to.be.an('array').that.has.length(3);
@@ -114,6 +114,29 @@ describe('convertV2WithTypes should generate collection conforming to collection
114114
);
115115
});
116116

117+
it('should pick example value for request body parametersResolution=Example', function (done) {
118+
const openapi = fs.readFileSync(testSpec1, 'utf8'),
119+
options = { schemaFaker: true, parametersResolution: 'Example' };
120+
121+
Converter.convertV2WithTypes({ type: 'string', data: openapi }, options, (err, conversionResult) => {
122+
expect(err).to.be.null;
123+
expect(conversionResult.output).to.be.an('array').that.is.not.empty;
124+
125+
const firstFolder = conversionResult.output[0].data.item[0];
126+
expect(firstFolder).to.have.property('name', 'pets');
127+
128+
const listAllPets = firstFolder.item[0];
129+
expect(listAllPets).to.have.property('name', 'List all pets');
130+
expect(listAllPets.request.method).to.equal('GET');
131+
132+
const createPet = firstFolder.item[1];
133+
expect(createPet.request.body.mode).to.equal('raw');
134+
expect(createPet.request.body.raw).to.equal('request body comes here');
135+
136+
done();
137+
});
138+
});
139+
117140
it('Should generate collection conforming to schema for and fail if not valid ' +
118141
testSpec1, function(done) {
119142
Converter.convertV2WithTypes(
@@ -174,6 +197,194 @@ describe('convertV2WithTypes', function() {
174197
});
175198
});
176199

200+
it('should handle non existent type in parameter schema', function(done) {
201+
const oas = {
202+
openapi: '3.0.0',
203+
info: { title: 'Form Explode Deprecated Test', version: '1.0.0' },
204+
paths: {
205+
'/pets': {
206+
get: {
207+
parameters: [
208+
{
209+
name: 'qp',
210+
in: 'query',
211+
schema: { deprecated: true }
212+
}
213+
],
214+
responses: { '200': { description: 'ok' } }
215+
}
216+
}
217+
}
218+
};
219+
220+
Converter.convertV2WithTypes({ type: 'json', data: oas }, {
221+
parametersResolution: 'Example'
222+
}, (err, conversionResult) => {
223+
expect(err).to.be.null;
224+
expect(conversionResult.result).to.equal(true);
225+
226+
const items = conversionResult.output[0].data.item;
227+
const request = items[0].item[0].request;
228+
const query = request.url.query;
229+
230+
expect(query.length).to.be.equal(1);
231+
expect(query[0].key).to.equal('qp');
232+
expect(query[0].value).to.equal('');
233+
done();
234+
});
235+
});
236+
237+
it('should handle schemas with unavailable types properly with parametersResolution=Example', function(done) {
238+
const oas = {
239+
openapi: '3.0.0',
240+
info: { title: 'DeepObject Deprecated Test', version: '1.0.0' },
241+
paths: {
242+
'/pets': {
243+
post: {
244+
parameters: [
245+
{
246+
name: 'qp',
247+
in: 'query',
248+
style: 'deepObject',
249+
explode: true,
250+
schema: {
251+
type: 'object',
252+
deprecated: true,
253+
properties: {
254+
name: {
255+
description: 'Name of the pet'
256+
}
257+
}
258+
}
259+
}
260+
],
261+
requestBody: {
262+
content: {
263+
'application/json': {
264+
schema: {
265+
deprecated: false,
266+
description: 'Help',
267+
// Type is not defined here
268+
properties: {
269+
name: { type: 'string' },
270+
style: {
271+
type: 'array',
272+
items: {
273+
anyOf: [
274+
{ type: 'string' },
275+
{ type: 'number' }
276+
]
277+
}
278+
},
279+
age: {
280+
// type not defined here
281+
description: 'age'
282+
283+
}
284+
}
285+
}
286+
}
287+
}
288+
},
289+
responses: { '200': { description: 'ok' } }
290+
}
291+
}
292+
}
293+
};
294+
295+
Converter.convertV2WithTypes({ type: 'json', data: oas }, {
296+
parametersResolution: 'Example'
297+
}, (err, conversionResult) => {
298+
expect(err).to.be.null;
299+
expect(conversionResult.result).to.equal(true);
300+
301+
const items = conversionResult.output[0].data.item;
302+
const request = items[0].item[0].request;
303+
const query = request.url.query || [];
304+
305+
expect(query.length).to.be.equal(1);
306+
expect(query[0].key).to.equal('qp[name]');
307+
expect(query[0].value).to.equal('');
308+
309+
expect(request.body.raw).to.be.equal('{\n "name": "string",\n "style": [\n "string",\n "string"\n ],\n "age": ""\n}');
310+
311+
done();
312+
});
313+
});
314+
315+
it('should handle schemas with unavailable types properly with parametersResolution=Schema', function(done) {
316+
const oas = {
317+
openapi: '3.0.0',
318+
info: { title: 'DeepObject Deprecated Test', version: '1.0.0' },
319+
paths: {
320+
'/pets': {
321+
post: {
322+
parameters: [
323+
{
324+
name: 'qp',
325+
in: 'query',
326+
style: 'deepObject',
327+
explode: true,
328+
schema: {
329+
type: 'object',
330+
deprecated: true,
331+
properties: {
332+
name: {
333+
description: 'Name of the pet'
334+
}
335+
}
336+
}
337+
}
338+
],
339+
requestBody: {
340+
content: {
341+
'application/json': {
342+
schema: {
343+
deprecated: false,
344+
description: 'Help',
345+
properties: {
346+
name: { type: 'string' },
347+
style: {
348+
type: 'array',
349+
items: {
350+
anyOf: [
351+
{ type: 'string' },
352+
{ type: 'number' }
353+
]
354+
}
355+
},
356+
age: { description: 'age' }
357+
}
358+
}
359+
}
360+
}
361+
},
362+
responses: { '200': { description: 'ok' } }
363+
}
364+
}
365+
}
366+
};
367+
368+
Converter.convertV2WithTypes({ type: 'json', data: oas }, {
369+
parametersResolution: 'Schema'
370+
}, (err, conversionResult) => {
371+
expect(err).to.be.null;
372+
expect(conversionResult.result).to.equal(true);
373+
374+
const items = conversionResult.output[0].data.item;
375+
const request = items[0].item[0].request;
376+
const query = request.url.query || [];
377+
378+
expect(query.length).to.be.equal(1);
379+
expect(query[0].key).to.equal('qp[name]');
380+
expect(query[0].value).to.equal('');
381+
382+
expect(request.body.raw).to.be.equal('{\n "name": "<string>",\n "style": [\n "<string>",\n "<string>"\n ],\n "age": ""\n}');
383+
384+
done();
385+
});
386+
});
387+
177388
it('should resolve nested array and object schema types correctly in extractedTypes', function(done) {
178389
const example = {
179390
name: 'Buddy',
@@ -189,7 +400,7 @@ describe('convertV2WithTypes', function() {
189400
}
190401
},
191402
openapi = fs.readFileSync(readOnlyNestedSpec, 'utf8'),
192-
options = { schemaFaker: true, exampleParametersResolution: 'schema' };
403+
options = { schemaFaker: true, parametersResolution: 'schema' };
193404

194405
Converter.convertV2WithTypes({ type: 'string', data: openapi }, options, (err, conversionResult) => {
195406
expect(err).to.be.null;
@@ -281,7 +492,7 @@ describe('convertV2WithTypes', function() {
281492
}
282493
},
283494
openapi = fs.readFileSync(testSpec1, 'utf8'),
284-
options = { schemaFaker: true, exampleParametersResolution: 'schema' };
495+
options = { schemaFaker: true, parametersResolution: 'schema' };
285496

286497
Converter.convertV2WithTypes({ type: 'string', data: openapi }, options, (err, conversionResult) => {
287498
expect(err).to.be.null;
@@ -988,7 +1199,7 @@ describe('convertV2WithTypes', function() {
9881199

9891200
it('types should contain title and description', function(done) {
9901201
const openapi = fs.readFileSync(testSpec2, 'utf8'),
991-
options = { schemaFaker: true, exampleParametersResolution: 'schema' };
1202+
options = { schemaFaker: true, parametersResolution: 'schema' };
9921203

9931204
Converter.convertV2WithTypes({ type: 'string', data: openapi }, options, (err, conversionResult) => {
9941205
expect(err).to.be.null;

0 commit comments

Comments
 (0)