Skip to content

Commit

Permalink
Merge pull request #69 from saumitrab/feature/master/add-ref-support-…
Browse files Browse the repository at this point in the history
…in-params

Add support for refs in openapi parameters
  • Loading branch information
raxpost authored May 11, 2018
2 parents 7c57a7d + 379800f commit 8e5976e
Show file tree
Hide file tree
Showing 9 changed files with 1,176 additions and 52 deletions.
7 changes: 4 additions & 3 deletions bin/swagger2graphql
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ if (argv.help) {

if (!argv.swagger) {
console.log('\nPlease provide path to swagger schema. \n--help for usage example');
} else {
build(argv.swagger).then(schema => {
console.log(graphql.printSchema(schema));
}).catch(console.log);
}

build(argv.swagger).then(schema => {
console.log(graphql.printSchema(schema));
}).catch(console.log);
11 changes: 8 additions & 3 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ var build = function () {
var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(swaggerPath) {
var proxyUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null;
var headers = arguments[2];
var swaggerSchema, endpoints, schema;
var swaggerSchema, refs, endpoints, schema;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
Expand All @@ -126,11 +126,16 @@ var build = function () {

case 2:
swaggerSchema = _context2.sent;
endpoints = (0, _swagger.getAllEndPoints)(swaggerSchema);
_context2.next = 5;
return (0, _swagger.loadRefs)(swaggerPath);

case 5:
refs = _context2.sent;
endpoints = (0, _swagger.getAllEndPoints)(swaggerSchema, refs);
schema = schemaFromEndpoints(endpoints, proxyUrl, headers);
return _context2.abrupt('return', schema);

case 6:
case 9:
case 'end':
return _context2.stop();
}
Expand Down
84 changes: 73 additions & 11 deletions lib/swagger.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.getAllEndPoints = exports.loadSchema = exports.getSchema = undefined;
exports.getAllEndPoints = exports.loadRefs = exports.loadSchema = exports.getSchema = undefined;

var _typeof2 = require('babel-runtime/helpers/typeof');

var _typeof3 = _interopRequireDefault(_typeof2);

var _regenerator = require('babel-runtime/regenerator');

var _regenerator2 = _interopRequireDefault(_regenerator);

var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');

var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);

var _keys = require('babel-runtime/core-js/object/keys');

var _keys2 = _interopRequireDefault(_keys);
Expand Down Expand Up @@ -49,13 +57,56 @@ var getSuccessResponse = function getSuccessResponse(responses) {
return resp && resp.schema;
};

var loadSchema = exports.loadSchema = function loadSchema(pathToSchema) {
var schemaPromise = _jsonSchemaRefParser2.default.bundle(pathToSchema).then(function (schema) {
__schema = schema;
return schema;
});
return schemaPromise;
};
var loadSchema = exports.loadSchema = function () {
var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(pathToSchema) {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
_context.next = 2;
return _jsonSchemaRefParser2.default.bundle(pathToSchema);

case 2:
__schema = _context.sent;
return _context.abrupt('return', __schema);

case 4:
case 'end':
return _context.stop();
}
}
}, _callee, undefined);
}));

return function loadSchema(_x) {
return _ref.apply(this, arguments);
};
}();

var loadRefs = exports.loadRefs = function () {
var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(pathToSchema) {
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
_context2.next = 2;
return _jsonSchemaRefParser2.default.resolve(pathToSchema);

case 2:
return _context2.abrupt('return', _context2.sent);

case 3:
case 'end':
return _context2.stop();
}
}
}, _callee2, undefined);
}));

return function loadRefs(_x2) {
return _ref2.apply(this, arguments);
};
}();

var replaceOddChars = function replaceOddChars(str) {
return str.replace(/[^_a-zA-Z0-9]/g, '_');
Expand All @@ -81,10 +132,22 @@ var getServerPath = function getServerPath(schema) {
return url;
};

var getParamDetails = function getParamDetails(param, schema, refResolver) {
var _param = param;
if (param.$ref) {
_param = refResolver.get(param.$ref);
}
var name = _param.name;
var type = _param.type;
var jsonSchema = _param;

return { name: name, type: type, jsonSchema: jsonSchema };
};

/**
* Go through schema and grab routes
*/
var getAllEndPoints = exports.getAllEndPoints = function getAllEndPoints(schema) {
var getAllEndPoints = exports.getAllEndPoints = function getAllEndPoints(schema, refs) {
var allTypes = {};
var serverPath = getServerPath(schema);
(0, _keys2.default)(schema.paths).forEach(function (path) {
Expand All @@ -94,8 +157,7 @@ var getAllEndPoints = exports.getAllEndPoints = function getAllEndPoints(schema)
var isMutation = ['post', 'put', 'patch', 'delete'].indexOf(method) !== -1;
var typeName = obj.operationId || getGQLTypeNameFromURL(method, path);
var parameters = obj.parameters ? obj.parameters.map(function (param) {
var type = param.type;
return { name: replaceOddChars(param.name), type: type, jsonSchema: param };
return getParamDetails(param, schema, refs);
}) : [];
var endpoint = {
parameters: parameters,
Expand Down
5 changes: 3 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import type {GraphQLParameters, Endpoint, GraphQLType, RootGraphQLSchema, SwaggerToGraphQLOptions, GraphQLTypeMap} from './types';
import rp from 'request-promise';
import { GraphQLSchema, GraphQLObjectType } from 'graphql';
import { getAllEndPoints, loadSchema } from './swagger';
import { getAllEndPoints, loadSchema, loadRefs } from './swagger';
import { createGQLObject, mapParametersToFields } from './typeMap';

type Endpoints = {[string]: Endpoint};
Expand Down Expand Up @@ -63,7 +63,8 @@ const getFields = (endpoints, isMutation, gqlTypes, proxyUrl, headers): GraphQLT

const build = async (swaggerPath: string, proxyUrl: ?(Function | string) = null, headers: ?{[string]: string}) => {
const swaggerSchema = await loadSchema(swaggerPath);
const endpoints = getAllEndPoints(swaggerSchema);
const refs = await loadRefs(swaggerPath);
const endpoints = getAllEndPoints(swaggerSchema, refs);
const schema = schemaFromEndpoints(endpoints, proxyUrl, headers);
return schema;
};
Expand Down
35 changes: 22 additions & 13 deletions src/swagger.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// @flow
import type {SwaggerSchema, Endpoint, Responses} from './types';
import type {SwaggerSchema, Endpoint, Responses, RefType} from './types';
import refParser from 'json-schema-ref-parser';
import type {GraphQLParameters} from './types';
import getRequestOptions from 'node-request-by-swagger';
Expand Down Expand Up @@ -30,13 +30,13 @@ const getSuccessResponse = (responses: Responses) => {
return resp && resp.schema;
};

export const loadSchema = (pathToSchema: string) => {
const schemaPromise = refParser.bundle(pathToSchema)
.then((schema) => {
__schema = schema;
return schema;
});
return schemaPromise;
export const loadSchema = async (pathToSchema: string) => {
__schema = await refParser.bundle(pathToSchema);
return __schema;
};

export const loadRefs = async (pathToSchema: string) => {
return await refParser.resolve(pathToSchema);
};

const replaceOddChars = (str) => str.replace(/[^_a-zA-Z0-9]/g, '_');
Expand All @@ -61,10 +61,22 @@ const getServerPath = (schema) => {
return url;
};

const getParamDetails = (param, schema, refResolver) => {
let _param = param;
if (param.$ref) {
_param = refResolver.get(param.$ref);
}
const name = _param.name;
const type = _param.type;
const jsonSchema = _param;

return {name, type, jsonSchema};
};

/**
* Go through schema and grab routes
*/
export const getAllEndPoints = (schema: SwaggerSchema): {[string]: Endpoint} => {
export const getAllEndPoints = (schema: SwaggerSchema, refs: RefType): {[string]: Endpoint} => {
const allTypes = {};
const serverPath = getServerPath(schema);
Object.keys(schema.paths).forEach(path => {
Expand All @@ -73,10 +85,7 @@ export const getAllEndPoints = (schema: SwaggerSchema): {[string]: Endpoint} =>
const obj = route[method];
const isMutation = ['post', 'put', 'patch', 'delete'].indexOf(method) !== -1;
const typeName = obj.operationId || getGQLTypeNameFromURL(method, path);
const parameters = obj.parameters ? obj.parameters.map(param => {
const type = param.type;
return {name: replaceOddChars(param.name), type, jsonSchema: param};
}) : [];
const parameters = obj.parameters ? obj.parameters.map(param => getParamDetails(param, schema, refs)) : [];
const endpoint: Endpoint = {
parameters,
description: obj.description,
Expand Down
6 changes: 5 additions & 1 deletion src/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,8 @@ export type SwaggerSchema = {
responses: Responses
}
}
}
}

export type RefType = {
$Ref: SwaggerSchema
}
Loading

0 comments on commit 8e5976e

Please sign in to comment.