UNPKG

soap-graphql

Version:

Create a GraphQL schema from a WSDL-defined SOAP endpoint.

392 lines 17.5 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [0, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var name_resolver_1 = require("./name-resolver"); var custom_type_resolver_1 = require("./custom-type-resolver"); var scalars_1 = require("graphql/type/scalars"); var util_1 = require("util"); var graphql_1 = require("graphql"); var SchemaResolver = /** @class */ (function () { function SchemaResolver(soapEndpoint, soapCaller, options, logger) { this.soapEndpoint = soapEndpoint; this.soapCaller = soapCaller; this.logger = logger; this.outputResolver = null; this.inputResolver = null; this.options = this.defaultOptions(options); } SchemaResolver.prototype.defaultOptions = function (options) { options = !options ? {} : Object.assign({}, options); if (!options.outputNameResolver) { options.outputNameResolver = name_resolver_1.defaultOutputNameResolver; } if (!options.interfaceNameResolver) { options.interfaceNameResolver = name_resolver_1.defaultInterfaceNameResolver; } if (!options.inputNameResolver) { options.inputNameResolver = name_resolver_1.defaultInputNameResolver; } if (!options.customResolver) { options.customResolver = new custom_type_resolver_1.DefaultTypeResolver(); } return options; }; SchemaResolver.prototype.resolve = function () { this.outputResolver = new GraphqlOutputFieldResolver(this.options, this.logger); this.inputResolver = new GraphqlInputFieldResolver(this.options, this.logger); return { query: this.createQueryObject(), mutation: this.createMutationObject(), }; }; SchemaResolver.prototype.createQueryObject = function () { var _this = this; return new graphql_1.GraphQLObjectType({ name: 'Query', fields: { 'description': { type: scalars_1.GraphQLString, resolve: function () { return _this.soapEndpoint.description(); } } } }); }; SchemaResolver.prototype.createMutationObject = function () { var _this = this; var fieldsThunk = function () { var fields = {}; _this.soapEndpoint.services().forEach(function (service) { if (!!_this.options.includeServices) { fields[service.name()] = _this.createSoapServiceField(service); } else if (!!_this.options.includePorts) { service.ports().forEach(function (port) { fields[port.name()] = _this.createSoapPortField(service, port); }); } else { service.ports().forEach(function (port) { port.operations().forEach(function (operation) { fields[operation.name()] = _this.createSoapOperationField(operation); }); }); } }); return fields; }; return new graphql_1.GraphQLObjectType({ name: 'Mutation', fields: fieldsThunk, }); }; SchemaResolver.prototype.createSoapServiceField = function (service) { var _this = this; var fieldsThunk = function () { var fields = {}; service.ports().forEach(function (port) { if (!!_this.options.includePorts) { fields[port.name()] = _this.createSoapPortField(service, port); } else { port.operations().forEach(function (operation) { fields[operation.name()] = _this.createSoapOperationField(operation); }); } }); return fields; }; var returnType = new graphql_1.GraphQLObjectType({ name: service.name() + 'Service', description: "Service " + service.name(), fields: fieldsThunk, }); return { type: returnType, description: "Service " + service.name(), resolve: function () { return {}; } }; }; SchemaResolver.prototype.createSoapPortField = function (service, port) { var _this = this; var fieldsThunk = function () { var fields = {}; port.operations().forEach(function (operation) { fields[operation.name()] = _this.createSoapOperationField(operation); }); return fields; }; var returnType = new graphql_1.GraphQLObjectType({ name: port.name() + 'Port', description: "Port " + port.name() + ", service " + service.name(), fields: fieldsThunk, }); return { type: returnType, description: "Port " + port.name() + ", service " + service.name(), resolve: function () { return {}; } }; }; SchemaResolver.prototype.createSoapOperationField = function (operation) { var args = this.createSoapOperationFieldArgs(operation); var returnType = this.resolveSoapOperationReturnType(operation); var resolver = this.createSoapOperationFieldResolver(operation); return { type: returnType, description: "Operation " + operation.name() + ", port " + operation.port().name() + ", service " + operation.service().name(), args: args, resolve: resolver }; }; SchemaResolver.prototype.createSoapOperationFieldArgs = function (operation) { var _this = this; var args = {}; operation.args().forEach(function (soapField) { args[soapField.name] = { type: _this.inputResolver.resolve(soapField), }; }); return args; }; SchemaResolver.prototype.resolveSoapOperationReturnType = function (operation) { return this.outputResolver.resolve(operation.output()); }; SchemaResolver.prototype.createSoapOperationFieldResolver = function (operation) { var _this = this; return function (graphqlSource, graphqlArgs, graphqlContext, graphqlInfo) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.soapCaller.call({ operation: operation, graphqlSource: graphqlSource, graphqlArgs: graphqlArgs, graphqlContext: graphqlContext, graphqlInfo: graphqlInfo, })]; case 1: return [2 /*return*/, _a.sent()]; } }); }); }; }; return SchemaResolver; }()); exports.SchemaResolver = SchemaResolver; var GraphqlOutputFieldResolver = /** @class */ (function () { function GraphqlOutputFieldResolver(options, logger) { this.options = options; this.logger = logger; this.alreadyResolvedOutputTypes = new Map(); this.alreadyResolvedInterfaceTypes = new Map(); } GraphqlOutputFieldResolver.prototype.resolve = function (input) { try { var type = this.resolveOutputType(input.type); return input.isList ? new graphql_1.GraphQLList(type) : type; } catch (err) { var errStacked = new Error("could not resolve output type for " + util_1.inspect(input, false, 4)); errStacked.stack += '\nCaused by: ' + err.stack; throw errStacked; } }; GraphqlOutputFieldResolver.prototype.resolveOutputType = function (soapType) { if (this.alreadyResolvedOutputTypes.has(soapType)) { return this.alreadyResolvedOutputTypes.get(soapType); } if (typeof soapType === 'string') { var customType = this.options.customResolver.outputType(soapType); if (!!customType) { this.alreadyResolvedOutputTypes.set(soapType, customType); return customType; } } else { var objectType = this.createObjectType(soapType); if (!!objectType) { this.alreadyResolvedOutputTypes.set(soapType, objectType); return objectType; } } this.logger.warn(function () { return "could not resolve output type '" + soapType + "'; using GraphQLString instead"; }); this.alreadyResolvedOutputTypes.set(soapType, scalars_1.GraphQLString); return scalars_1.GraphQLString; }; GraphqlOutputFieldResolver.prototype.createObjectType = function (soapType) { return new graphql_1.GraphQLObjectType(this.createObjectTypeConfig(soapType)); }; GraphqlOutputFieldResolver.prototype.createObjectTypeConfig = function (soapType) { var _this = this; var fields = function () { var fieldMap = {}; _this.appendObjectTypeFields(fieldMap, soapType); return fieldMap; }; var interfaces = function () { var interfaces = []; _this.appendInterfaces(interfaces, soapType); return interfaces; }; return { name: this.options.outputNameResolver(soapType), fields: fields, interfaces: interfaces, }; }; GraphqlOutputFieldResolver.prototype.appendObjectTypeFields = function (fieldMap, soapType) { var _this = this; soapType.fields.forEach(function (soapField) { fieldMap[soapField.name] = { type: _this.resolve(soapField), }; }); if (!!soapType.base) { this.appendObjectTypeFields(fieldMap, soapType.base); } }; GraphqlOutputFieldResolver.prototype.appendInterfaces = function (interfaces, soapType) { if (!!soapType.base) { interfaces.push(this.resolveInterfaceType(soapType.base)); this.appendInterfaces(interfaces, soapType.base); } }; GraphqlOutputFieldResolver.prototype.resolveInterfaceType = function (soapType) { if (this.alreadyResolvedInterfaceTypes.has(soapType)) { return this.alreadyResolvedInterfaceTypes.get(soapType); } var interfaceType = this.createInterfaceType(soapType); this.alreadyResolvedInterfaceTypes.set(soapType, interfaceType); return interfaceType; }; GraphqlOutputFieldResolver.prototype.createInterfaceType = function (soapType) { return new graphql_1.GraphQLInterfaceType(this.createInterfaceTypeConfig(soapType)); }; GraphqlOutputFieldResolver.prototype.createInterfaceTypeConfig = function (soapType) { var _this = this; var fields = function () { var fieldMap = {}; _this.appendInterfaceTypeFields(fieldMap, soapType); return fieldMap; }; return { name: this.options.interfaceNameResolver(soapType), fields: fields, // should never be called, since the schema will not contain ambigous return types resolveType: function (value, context, info) { throw Error('no interface resolving available'); }, }; }; GraphqlOutputFieldResolver.prototype.appendInterfaceTypeFields = function (fieldMap, soapType) { var _this = this; soapType.fields.forEach(function (soapField) { fieldMap[soapField.name] = { type: _this.resolve(soapField), }; }); if (!!soapType.base) { this.appendObjectTypeFields(fieldMap, soapType.base); } }; return GraphqlOutputFieldResolver; }()); var GraphqlInputFieldResolver = /** @class */ (function () { function GraphqlInputFieldResolver(options, logger) { this.options = options; this.logger = logger; this.alreadyResolved = new Map(); } GraphqlInputFieldResolver.prototype.resolve = function (input) { try { var type = this.resolveInputType(input.type); return input.isList ? new graphql_1.GraphQLList(type) : type; } catch (err) { var errStacked = new Error("could not resolve output type for " + util_1.inspect(input, false, 4)); errStacked.stack += '\nCaused by: ' + err.stack; throw errStacked; } }; GraphqlInputFieldResolver.prototype.resolveInputType = function (soapType) { if (this.alreadyResolved.has(soapType)) { return this.alreadyResolved.get(soapType); } if (typeof soapType === 'string') { var customType = this.options.customResolver.inputType(soapType); if (!!customType) { this.alreadyResolved.set(soapType, customType); return customType; } } else { var objectType = this.createObjectType(soapType); if (!!objectType) { this.alreadyResolved.set(soapType, objectType); return objectType; } } this.logger.warn(function () { return "could not resolve input type '" + soapType + "'; using GraphQLString"; }); this.alreadyResolved.set(soapType, scalars_1.GraphQLString); return scalars_1.GraphQLString; }; GraphqlInputFieldResolver.prototype.createObjectType = function (soapType) { return new graphql_1.GraphQLInputObjectType(this.createObjectTypeConfig(soapType)); }; GraphqlInputFieldResolver.prototype.createObjectTypeConfig = function (soapType) { var _this = this; var fields = function () { var fieldMap = {}; _this.appendObjectTypeFields(fieldMap, soapType); return fieldMap; }; return { name: this.options.inputNameResolver(soapType), fields: fields, }; }; GraphqlInputFieldResolver.prototype.appendObjectTypeFields = function (fieldMap, soapType) { var _this = this; soapType.fields.forEach(function (soapField) { fieldMap[soapField.name] = { type: _this.resolve(soapField), }; }); if (!!soapType.base) { this.appendObjectTypeFields(fieldMap, soapType.base); } }; return GraphqlInputFieldResolver; }()); //# sourceMappingURL=schema-resolver.js.map