UNPKG

@ardatan/openapi-to-graphql

Version:

Generates a GraphQL schema for a given OpenAPI Specification (OAS)

194 lines 7.64 kB
"use strict"; // Copyright IBM Corp. 2018. All Rights Reserved. // Node module: openapi-to-graphql // This file is licensed under the MIT License. // License text available at https://opensource.org/licenses/MIT Object.defineProperty(exports, "__esModule", { value: true }); /** * Functions to create viewers that allow users to pass credentials to resolve * functions used by OpenAPI-to-GraphQL. */ // Type imports: const graphql_1 = require("graphql"); // Imports: const schema_builder_1 = require("./schema_builder"); const Oas3Tools = require("./oas_3_tools"); const debug_1 = require("debug"); const utils_1 = require("./utils"); const preprocessor_1 = require("./preprocessor"); const translationLog = debug_1.default('translation'); /** * Load the field object in the appropriate root object * * i.e. inside either rootQueryFields/rootMutationFields or inside * rootQueryFields/rootMutationFields for further processing */ function createAndLoadViewer(queryFields, data, isMutation = false) { let results = {}; /** * To ensure that viewers have unique names, we add a numerical postfix. * * This object keeps track of what the postfix should be. * * The key is the security scheme type and the value is * the current highest postfix used for viewers of that security scheme type. */ const viewerNamePostfix = {}; /** * Used to collect all fields in the given querFields object, no matter which * protocol. Used to populate anyAuthViewer. */ const anyAuthFields = {}; for (let protocolName in queryFields) { Object.assign(anyAuthFields, queryFields[protocolName]); /** * Check if the name has already been used (i.e. in the list) * if so, create a new name and add it to the list */ const securityType = data.security[protocolName].def.type; let viewerType; /** * HTTP is not an authentication protocol * HTTP covers a number of different authentication type * change the typeName to match the exact authentication type (e.g. basic * authentication) */ if (securityType === 'http') { let scheme = data.security[protocolName].def.scheme; switch (scheme) { case 'basic': viewerType = 'basicAuth'; break; default: utils_1.handleWarning({ typeKey: 'UNSUPPORTED_HTTP_SECURITY_SCHEME', message: `Currently unsupported HTTP authentication protocol ` + `type 'http' and scheme '${scheme}'`, data, log: translationLog }); continue; } } else { viewerType = securityType; } // Create name for the viewer let viewerName = !isMutation ? Oas3Tools.sanitize(`viewer ${viewerType}`, Oas3Tools.CaseStyle.camelCase) : Oas3Tools.sanitize(`mutation viewer ${viewerType}`, Oas3Tools.CaseStyle.camelCase); // Ensure unique viewer name // If name already exists, append a number at the end of the name if (!(viewerType in viewerNamePostfix)) { viewerNamePostfix[viewerType] = 1; } else { viewerName += ++viewerNamePostfix[viewerType]; } // Add the viewer object type to the specified root query object type results[viewerName] = getViewerOT(viewerName, protocolName, securityType, queryFields[protocolName], data); } // Create name for the AnyAuth viewer const anyAuthObjectName = !isMutation ? 'viewerAnyAuth' : 'mutationViewerAnyAuth'; // Add the AnyAuth object type to the specified root query object type results[anyAuthObjectName] = getViewerAnyAuthOT(anyAuthObjectName, anyAuthFields, data); return results; } exports.createAndLoadViewer = createAndLoadViewer; /** * Gets the viewer Object, resolve function, and arguments */ const getViewerOT = (name, protocolName, securityType, queryFields, data) => { const scheme = data.security[protocolName]; // Resolve function: const resolve = (root, args, ctx) => { const security = {}; const saneProtocolName = Oas3Tools.sanitize(protocolName, Oas3Tools.CaseStyle.camelCase); security[Oas3Tools.storeSaneName(saneProtocolName, protocolName, data.saneMap)] = args; /** * Viewers are always root, so we can instantiate _openAPIToGraphQL here without * previously checking for its existence */ return { _openAPIToGraphQL: { security } }; }; // Arguments: /** * Do not sort because they are already "sorted" in preprocessing. * Otherwise, for basic auth, "password" will appear before "username" */ const args = {}; if (typeof scheme === 'object') { for (let parameterName in scheme.parameters) { args[parameterName] = { type: new graphql_1.GraphQLNonNull(graphql_1.GraphQLString) }; } } let typeDescription = `A viewer for security scheme '${protocolName}'`; /** * HTTP authentication uses different schemes. It is not sufficient to name * only the security type */ let description = securityType === 'http' ? `A viewer that wraps all operations authenticated via security scheme ` + `'${protocolName}', which is of type 'http' '${scheme.def.scheme}'` : `A viewer that wraps all operations authenticated via security scheme ` + `'${protocolName}', which is of type '${securityType}'`; if (data.oass.length !== 1) { typeDescription += ` in OAS '${scheme.oas.info.title}'`; description = `, in OAS '${scheme.oas.info.title}`; } return { type: new graphql_1.GraphQLObjectType({ name: Oas3Tools.capitalize(name), description: typeDescription, fields: () => queryFields }), resolve, args, description }; }; /** * Create an object containing an AnyAuth viewer, its resolve function, * and its args. */ const getViewerAnyAuthOT = (name, queryFields, data) => { let args = {}; for (let protocolName in data.security) { // Create input object types for the viewer arguments const def = preprocessor_1.createDataDef({ fromRef: protocolName }, data.security[protocolName].schema, true, data); const type = schema_builder_1.getGraphQLType({ def, data, isInputObjectType: true }); const saneProtocolName = Oas3Tools.sanitize(protocolName, Oas3Tools.CaseStyle.camelCase); args[Oas3Tools.storeSaneName(saneProtocolName, protocolName, data.saneMap)] = { type }; } args = utils_1.sortObject(args); // Pass object containing security information to fields const resolve = (root, args, ctx) => { return { _openAPIToGraphQL: { security: args } }; }; return { type: new graphql_1.GraphQLObjectType({ name: Oas3Tools.capitalize(name), description: 'Warning: Not every request will work with this viewer type', fields: () => queryFields }), resolve, args, description: `A viewer that wraps operations for all available ` + `authentication mechanisms` }; }; //# sourceMappingURL=auth_builder.js.map