diff --git a/lib/index.js b/lib/index.js index 26e0980..1b6bcae 100644 --- a/lib/index.js +++ b/lib/index.js @@ -62,7 +62,7 @@ var schemaFromEndpoints = function schemaFromEndpoints(endpoints, proxyUrl, head var resolver = function resolver(endpoint, proxyUrl) { var customHeaders = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; return function () { - var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(_, args, opts) { + var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(_, args, opts) { var proxy, req, res; return _regenerator2.default.wrap(function _callee$(_context) { while (1) { @@ -113,7 +113,7 @@ var getFields = function getFields(endpoints, isMutation, gqlTypes, proxyUrl, he }; var build = function () { - var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(swaggerPath) { + var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(swaggerPath) { var proxyUrl = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var headers = arguments[2]; var swaggerSchema, refs, endpoints, schema; diff --git a/lib/swagger.js b/lib/swagger.js index a14d647..fe4beaa 100644 --- a/lib/swagger.js +++ b/lib/swagger.js @@ -58,7 +58,7 @@ var getSuccessResponse = function getSuccessResponse(responses) { }; var loadSchema = exports.loadSchema = function () { - var _ref = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee(pathToSchema) { + var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee(pathToSchema) { return _regenerator2.default.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { @@ -84,7 +84,7 @@ var loadSchema = exports.loadSchema = function () { }(); var loadRefs = exports.loadRefs = function () { - var _ref2 = (0, _asyncToGenerator3.default)(_regenerator2.default.mark(function _callee2(pathToSchema) { + var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2(pathToSchema) { return _regenerator2.default.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { diff --git a/lib/typeMap.js b/lib/typeMap.js index fbc951a..8ed3c94 100644 --- a/lib/typeMap.js +++ b/lib/typeMap.js @@ -135,23 +135,28 @@ var getTypeFields = exports.getTypeFields = function getTypeFields(jsonSchema, t } return function () { return _lodash2.default.mapValues(jsonSchema.properties || {}, function (propertySchema, propertyName) { + var baseType = jsonSchemaTypeToGraphQL(title, propertySchema, propertyName, isInputType, gqlTypes); + var type = jsonSchema.required && jsonSchema.required.includes(propertyName) ? graphql.GraphQLNonNull(baseType) : baseType; return { description: propertySchema.description, - type: jsonSchemaTypeToGraphQL(title, propertySchema, propertyName, isInputType, gqlTypes) + type: type }; }); }; }; var jsonSchemaTypeToGraphQL = function jsonSchemaTypeToGraphQL(title, jsonSchema, schemaName, isInputType, gqlTypes) { - if (jsonSchema.$ref) { - return getExistingType(jsonSchema.$ref, isInputType, gqlTypes); - } else if (isObjectType(jsonSchema)) { - return createGQLObject(jsonSchema, title + '_' + schemaName, isInputType, gqlTypes); - } else if (jsonSchema.type) { - return getPrimitiveTypes(jsonSchema); - } - throw new Error("Don't know how to handle schema " + (0, _stringify2.default)(jsonSchema) + ' without type and schema'); + var baseType = function () { + if (jsonSchema.$ref) { + return getExistingType(jsonSchema.$ref, isInputType, gqlTypes); + } else if (isObjectType(jsonSchema)) { + return createGQLObject(jsonSchema, title + '_' + schemaName, isInputType, gqlTypes); + } else if (jsonSchema.type) { + return getPrimitiveTypes(jsonSchema); + } + throw new Error("Don't know how to handle schema " + (0, _stringify2.default)(jsonSchema) + ' without type and schema'); + }(); + return jsonSchema.required ? graphql.GraphQLNonNull(baseType) : baseType; }; var getPrimitiveTypes = function getPrimitiveTypes(jsonSchema) { diff --git a/src/typeMap.js b/src/typeMap.js index 6a9cb8e..1e06d38 100644 --- a/src/typeMap.js +++ b/src/typeMap.js @@ -112,22 +112,27 @@ export const getTypeFields = (jsonSchema: JSONSchemaType, title: string, isInput } return () => _.mapValues(jsonSchema.properties || {}, (propertySchema, propertyName) => { + const baseType = jsonSchemaTypeToGraphQL(title, propertySchema, propertyName, isInputType, gqlTypes); + const type = jsonSchema.required && jsonSchema.required.includes(propertyName) ? graphql.GraphQLNonNull(baseType) : baseType; return { description: propertySchema.description, - type: jsonSchemaTypeToGraphQL(title, propertySchema, propertyName, isInputType, gqlTypes) + type }; }); }; const jsonSchemaTypeToGraphQL = (title: string, jsonSchema: JSONSchemaType, schemaName: string, isInputType: boolean, gqlTypes: GraphQLTypeMap) => { - if (jsonSchema.$ref) { - return getExistingType(jsonSchema.$ref, isInputType, gqlTypes); - } else if (isObjectType(jsonSchema)) { - return createGQLObject(jsonSchema, title + '_' + schemaName, isInputType, gqlTypes); - } else if (jsonSchema.type) { - return getPrimitiveTypes(jsonSchema); - } - throw new Error("Don't know how to handle schema " + JSON.stringify(jsonSchema) + ' without type and schema'); + const baseType = (() => { + if (jsonSchema.$ref) { + return getExistingType(jsonSchema.$ref, isInputType, gqlTypes); + } else if (isObjectType(jsonSchema)) { + return createGQLObject(jsonSchema, title + '_' + schemaName, isInputType, gqlTypes); + } else if (jsonSchema.type) { + return getPrimitiveTypes(jsonSchema); + } + throw new Error("Don't know how to handle schema " + JSON.stringify(jsonSchema) + ' without type and schema'); + })(); + return jsonSchema.required ? graphql.GraphQLNonNull(baseType) : baseType; }; const getPrimitiveTypes = (jsonSchema: JSONSchemaType): GraphQLScalarType => { diff --git a/src/types.js b/src/types.js index 600e3ff..31f29f9 100644 --- a/src/types.js +++ b/src/types.js @@ -48,7 +48,8 @@ export type JSONSchemaType = { type?: string, properties?: Array, title?: string, - description?: string + description?: string, + required?: boolean | Array } export type SwaggerSchema = { diff --git a/test/fixtures/petstore.graphql b/test/fixtures/petstore.graphql index b557ce8..c689007 100644 --- a/test/fixtures/petstore.graphql +++ b/test/fixtures/petstore.graphql @@ -59,27 +59,27 @@ type logoutUser { } type Mutation { - addPet(body: PetInput): addPet - updatePet(body: PetInput): updatePet - updatePetWithForm(petId: String, name: String, status: String): updatePetWithForm - deletePet(api_key: String, petId: String): deletePet - placeOrder(body: OrderInput): Order + addPet(body: PetInput!): addPet + updatePet(body: PetInput!): updatePet + updatePetWithForm(petId: String!, name: String, status: String): updatePetWithForm + deletePet(api_key: String, petId: String!): deletePet + placeOrder(body: OrderInput!): Order """ For valid response try integer IDs with positive integer value. Negative or non-integer values will generate API errors """ - deleteOrder(orderId: String): deleteOrder + deleteOrder(orderId: String!): deleteOrder """This can only be done by the logged in user.""" - createUser(body: UserInput): createUser - createUsersWithArrayInput(body: param_createUsersWithArrayInput_bodyInput): createUsersWithArrayInput - createUsersWithListInput(body: param_createUsersWithListInput_bodyInput): createUsersWithListInput + createUser(body: UserInput!): createUser + createUsersWithArrayInput(body: param_createUsersWithArrayInput_bodyInput!): createUsersWithArrayInput + createUsersWithListInput(body: param_createUsersWithListInput_bodyInput!): createUsersWithListInput """This can only be done by the logged in user.""" - updateUser(username: String, body: UserInput): updateUser + updateUser(username: String!, body: UserInput!): updateUser """This can only be done by the logged in user.""" - deleteUser(username: String): deleteUser + deleteUser(username: String!): deleteUser } type Order { @@ -119,8 +119,8 @@ input param_createUsersWithListInput_bodyInput { type Pet { id: String category: Category - name: String - photoUrls: [String] + name: String! + photoUrls: [String]! tags: [Tag] """pet status in the store""" @@ -130,8 +130,8 @@ type Pet { input PetInput { id: String category: CategoryInput - name: String - photoUrls: [String] + name: String! + photoUrls: [String]! tags: [TagInput] """pet status in the store""" @@ -140,15 +140,15 @@ input PetInput { type Query { """Multiple status values can be provided with comma separated strings""" - findPetsByStatus(status: [String]): [Pet] + findPetsByStatus(status: [String]!): [Pet] """ Muliple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. """ - findPetsByTags(tags: [String]): [Pet] + findPetsByTags(tags: [String]!): [Pet] """Returns a single pet""" - getPetById(petId: String): Pet + getPetById(petId: String!): Pet """Returns a map of status codes to quantities""" getInventory: getInventory @@ -156,10 +156,10 @@ type Query { """ For valid response try integer IDs with value >= 1 and <= 10. Other values will generated exceptions """ - getOrderById(orderId: String): Order - loginUser(username: String, password: String): loginUser + getOrderById(orderId: String!): Order + loginUser(username: String!, password: String!): loginUser logoutUser: logoutUser - getUserByName(username: String): User + getUserByName(username: String!): User } type Tag {