Fix swagger to openapi convertion

Removing async await implementation and using callback implementation instead.
Fixin the related tests
This commit is contained in:
Erik Mendoza
2022-04-28 16:38:18 -05:00
parent bd33ad10b0
commit fa623d32c0
3 changed files with 123 additions and 122 deletions

View File

@@ -1,10 +1,9 @@
'use strict';
const { convertSwaggerToOpenapi } = require('./swaggerUtils/swaggerToOpenapi.js');
// This is the default collection name if one can't be inferred from the OpenAPI spec
const COLLECTION_NAME = 'Imported from OpenAPI 3.0',
{ getConcreteSchemaUtils, isSwagger } = require('./common/versionUtils.js'),
{ getConcreteSchemaUtils } = require('./common/versionUtils.js'),
{ convertSwaggerToOpenapi } = require('./swaggerUtils/swaggerToOpenapi.js'),
BROWSER = 'browser',
Ajv = require('ajv'),
addFormats = require('ajv-formats'),
@@ -239,7 +238,7 @@ class SchemaPack {
// convert method, this is called when you want to convert a schema that you've already loaded
// in the constructor
async convert (callback) {
convert (callback) {
let openapi,
options = this.computedOptions,
analysis,
@@ -256,122 +255,119 @@ class SchemaPack {
return callback(new OpenApiErr('The schema must be validated before attempting conversion'));
}
if (isSwagger(concreteUtils.version)) {
try {
let result = await convertSwaggerToOpenapi(this.openapi);
this.openapi = result.openapi;
}
catch (error) {
convertSwaggerToOpenapi(concreteUtils, this.openapi, (error, newOpenapi) => {
if (error) {
return callback(error);
}
}
// this cannot be attempted before validation
specComponentsAndUtils = { concreteUtils };
Object.assign(specComponentsAndUtils, concreteUtils.getRequiredData(this.openapi));
this.openapi = newOpenapi;
// this cannot be attempted before validation
specComponentsAndUtils = { concreteUtils };
Object.assign(specComponentsAndUtils, concreteUtils.getRequiredData(this.openapi));
// create and sanitize basic spec
openapi = this.openapi;
openapi.servers = _.isEmpty(openapi.servers) ? [{ url: '/' }] : openapi.servers;
openapi.securityDefs = _.get(openapi, 'components.securitySchemes', {});
openapi.baseUrl = _.get(openapi, 'servers.0.url', '{{baseURL}}');
// create and sanitize basic spec
openapi = this.openapi;
openapi.servers = _.isEmpty(openapi.servers) ? [{ url: '/' }] : openapi.servers;
openapi.securityDefs = _.get(openapi, 'components.securitySchemes', {});
openapi.baseUrl = _.get(openapi, 'servers.0.url', '{{baseURL}}');
// TODO: Multiple server variables need to be saved as environments
openapi.baseUrlVariables = _.get(openapi, 'servers.0.variables');
// TODO: Multiple server variables need to be saved as environments
openapi.baseUrlVariables = _.get(openapi, 'servers.0.variables');
// Fix {scheme} and {path} vars in the URL to :scheme and :path
openapi.baseUrl = schemaUtils.fixPathVariablesInUrl(openapi.baseUrl);
// Fix {scheme} and {path} vars in the URL to :scheme and :path
openapi.baseUrl = schemaUtils.fixPathVariablesInUrl(openapi.baseUrl);
// Creating a new instance of a Postman collection
// All generated folders and requests will go inside this
generatedStore.collection = new sdk.Collection({
info: {
name: _.isEmpty(_.get(openapi, 'info.title')) ? COLLECTION_NAME : _.get(openapi, 'info.title')
// Creating a new instance of a Postman collection
// All generated folders and requests will go inside this
generatedStore.collection = new sdk.Collection({
info: {
name: _.isEmpty(_.get(openapi, 'info.title')) ? COLLECTION_NAME : _.get(openapi, 'info.title')
}
});
if (openapi.security) {
authHelper = schemaUtils.getAuthHelper(openapi, openapi.security);
if (authHelper) {
generatedStore.collection.auth = authHelper;
}
}
});
// ---- Collection Variables ----
// adding the collection variables for all the necessary root level variables
// and adding them to the collection variables
schemaUtils.convertToPmCollectionVariables(
openapi.baseUrlVariables,
'baseUrl',
openapi.baseUrl
).forEach((element) => {
generatedStore.collection.variables.add(element);
});
if (openapi.security) {
authHelper = schemaUtils.getAuthHelper(openapi, openapi.security);
if (authHelper) {
generatedStore.collection.auth = authHelper;
}
}
// ---- Collection Variables ----
// adding the collection variables for all the necessary root level variables
// and adding them to the collection variables
schemaUtils.convertToPmCollectionVariables(
openapi.baseUrlVariables,
'baseUrl',
openapi.baseUrl
).forEach((element) => {
generatedStore.collection.variables.add(element);
});
generatedStore.collection.describe(schemaUtils.getCollectionDescription(openapi));
generatedStore.collection.describe(schemaUtils.getCollectionDescription(openapi));
// Only change the stack limit if the optimizeConversion option is true
if (options.optimizeConversion) {
// Deciding stack limit based on size of the schema, number of refs and number of paths.
analysis = schemaUtils.analyzeSpec(openapi);
// Only change the stack limit if the optimizeConversion option is true
if (options.optimizeConversion) {
// Deciding stack limit based on size of the schema, number of refs and number of paths.
analysis = schemaUtils.analyzeSpec(openapi);
// Update options on the basis of analysis.
options = schemaUtils.determineOptions(analysis, options);
}
// ---- Collection Items ----
// Adding the collection items from openapi spec based on folderStrategy option
// For tags, All operations are grouped based on respective tags object
// For paths, All operations are grouped based on corresponding paths
try {
if (options.folderStrategy === 'tags') {
schemaUtils.addCollectionItemsUsingTags(
openapi,
generatedStore,
specComponentsAndUtils,
options,
schemaCache,
concreteUtils
);
}
else {
schemaUtils.addCollectionItemsUsingPaths(
openapi,
generatedStore,
specComponentsAndUtils,
options,
schemaCache,
concreteUtils
);
// Update options on the basis of analysis.
options = schemaUtils.determineOptions(analysis, options);
}
if (options.includeWebhooks) {
schemaUtils.addCollectionItemsFromWebhooks(
openapi,
generatedStore,
specComponentsAndUtils,
options,
schemaCache,
concreteUtils
);
// ---- Collection Items ----
// Adding the collection items from openapi spec based on folderStrategy option
// For tags, All operations are grouped based on respective tags object
// For paths, All operations are grouped based on corresponding paths
try {
if (options.folderStrategy === 'tags') {
schemaUtils.addCollectionItemsUsingTags(
openapi,
generatedStore,
specComponentsAndUtils,
options,
schemaCache,
concreteUtils
);
}
else {
schemaUtils.addCollectionItemsUsingPaths(
openapi,
generatedStore,
specComponentsAndUtils,
options,
schemaCache,
concreteUtils
);
}
if (options.includeWebhooks) {
schemaUtils.addCollectionItemsFromWebhooks(
openapi,
generatedStore,
specComponentsAndUtils,
options,
schemaCache,
concreteUtils
);
}
}
catch (e) {
return callback(e);
}
}
catch (e) {
return callback(e);
}
collectionJSON = generatedStore.collection.toJSON();
collectionJSON = generatedStore.collection.toJSON();
// this needs to be deleted as even if version is not specified to sdk,
// it returns a version property with value set as undefined
// this fails validation against v2.1 collection schema definition.
delete collectionJSON.info.version;
// this needs to be deleted as even if version is not specified to sdk,
// it returns a version property with value set as undefined
// this fails validation against v2.1 collection schema definition.
delete collectionJSON.info.version;
return callback(null, {
result: true,
output: [{
type: 'collection',
data: collectionJSON
}]
return callback(null, {
result: true,
output: [{
type: 'collection',
data: collectionJSON
}]
});
});
}

View File

@@ -1,21 +1,27 @@
const Swagger2OpenAPI = require('swagger2openapi');
const Swagger2OpenAPI = require('swagger2openapi'),
{ isSwagger } = require('../common/versionUtils');
module.exports = {
convertSwaggerToOpenapi: function(parsedSwagger) {
try {
return Swagger2OpenAPI.convertObj(
convertSwaggerToOpenapi: function(concreteUtils, parsedSwagger, convertExecution) {
if (isSwagger(concreteUtils.version)) {
Swagger2OpenAPI.convertObj(
parsedSwagger,
{
fatal: false,
patch: true,
anchors: true,
warnOnly: true
},
(error, newOpenapi) => {
if (error) {
return convertExecution(error);
}
return convertExecution(null, newOpenapi.openapi);
}
);
}
catch (error) {
throw error;
else {
return convertExecution(null, parsedSwagger);
}
}
};

View File

@@ -6,25 +6,24 @@ const { convertSwaggerToOpenapi } = require('../../lib/swaggerUtils/swaggerToOpe
utils = require('../../lib/swaggerUtils/schemaUtilsSwagger'),
expect = require('chai').expect;
describe('Test swaggerToOpenapi method', async function() {
it('Should convert a swagger file to an openapi', async function() {
describe('Test swaggerToOpenapi method', function() {
it('Should convert a swagger file to an openapi', function() {
const fileSource = path.join(__dirname, SWAGGER_20_FOLDER_JSON + '/sampleswagger.json'),
fileData = fs.readFileSync(fileSource, 'utf8'),
parsedSpec = utils.parseSpec(fileData);
let result = await convertSwaggerToOpenapi(parsedSpec.openapi);
expect(result.openapi.openapi).to.be.equal('3.0.0');
convertSwaggerToOpenapi(utils, parsedSpec.openapi, (error, openapi) => {
expect(error).to.be.null;
expect(openapi.openapi).to.be.equal('3.0.0');
});
});
it('Should throw an error when swagger file is not complete', async function() {
it('Should throw an error when swagger file is not complete', function() {
const fileSource = path.join(__dirname, SWAGGER_20_INVALID_FOLDER_JSON + '/invalid_no_info.json'),
fileData = fs.readFileSync(fileSource, 'utf8'),
parsedSpec = utils.parseSpec(fileData);
try {
await convertSwaggerToOpenapi(parsedSpec.openapi);
expect.fail();
}
catch (error) {
convertSwaggerToOpenapi(utils, parsedSpec.openapi, (error, openapi) => {
expect(error.message).to.be.equal('Unsupported swagger/OpenAPI version: undefined');
}
expect(openapi).to.be.undefined;
});
});
});