UNPKG

sardines-service-driver-http

Version:
466 lines (465 loc) 23.7 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } 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) : adopt(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 = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, 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 querystring = require("querystring"); var sardines_core_1 = require("sardines-core"); var cross_fetch_1 = require("cross-fetch"); var Middlewares = []; var GroupProcesses = []; var PostProcesses = []; var ParallelProcesses = []; var HttpServiceDriver = (function () { function HttpServiceDriver(providerInfo) { this.providerInfo = providerInfo; } Object.defineProperty(HttpServiceDriver.prototype, "logMesgHeader", { get: function () { return '[HTTP Service Driver]'; }, enumerable: false, configurable: true }); HttpServiceDriver.registerMiddleware = function (fn) { if (typeof fn === 'function') { Middlewares.push(fn); } }; HttpServiceDriver.registerGroupProcess = function (fn) { if (typeof fn === 'function') { GroupProcesses.push(fn); } }; HttpServiceDriver.registerPostProcess = function (fn) { if (typeof fn === 'function') { PostProcesses.push(fn); } }; HttpServiceDriver.registerParallelProcess = function (fn) { if (typeof fn === 'function') { ParallelProcesses.push(fn); } }; HttpServiceDriver.prototype.getDefaultHttpServiceSettings = function (serviceSettings) { if (!serviceSettings.identity || !serviceSettings.identity.application || !serviceSettings.identity.module || !serviceSettings.identity.name) { throw sardines_core_1.utils.unifyErrMesg("Invalid service settings", 'service driver', 'service settings'); } var serviceIdentity = serviceSettings.identity; var providerSettings = serviceSettings.entries && serviceSettings.entries.length ? serviceSettings.entries[0].settingsForProvider : null; var httpServiceSettings = {}; var additionalArgumentSettings = null; var root = '/'; var method = sardines_core_1.Http.Method.POST; var path = "/" + serviceIdentity.application + "/" + serviceIdentity.module + "/" + serviceIdentity.name; if (providerSettings) { Object.assign(httpServiceSettings, providerSettings); if (httpServiceSettings.arguments) { additionalArgumentSettings = httpServiceSettings.arguments; delete httpServiceSettings.arguments; } if (providerSettings.root) { root = providerSettings.root; } if (providerSettings.method) { method = providerSettings.method; } if (providerSettings.path) { path = providerSettings.path; } } httpServiceSettings.path = (root + "/" + path).replace(/\/+/g, '/'); httpServiceSettings.method = method; httpServiceSettings.response = { type: sardines_core_1.Http.ServiceResponseType.json }; if (serviceSettings.returnType) { switch (serviceSettings.returnType) { case 'string': httpServiceSettings.response = { type: sardines_core_1.Http.ServiceResponseType.string }; break; case 'number': httpServiceSettings.response = { type: sardines_core_1.Http.ServiceResponseType.number }; break; case 'boolean': httpServiceSettings.response = { type: sardines_core_1.Http.ServiceResponseType.boolean }; break; case 'any': default: httpServiceSettings.response = { type: sardines_core_1.Http.ServiceResponseType.json }; break; } } httpServiceSettings.inputParameters = []; var tmpArgs = []; if (serviceSettings.arguments && serviceSettings.arguments.length) { for (var _i = 0, _a = serviceSettings.arguments; _i < _a.length; _i++) { var serviceArg = _a[_i]; var arg = serviceArg; if (additionalArgumentSettings) { for (var _b = 0, additionalArgumentSettings_1 = additionalArgumentSettings; _b < additionalArgumentSettings_1.length; _b++) { var addArg = additionalArgumentSettings_1[_b]; if (addArg && addArg.name && arg.name && arg.name === addArg.name) { arg = addArg; } else if (addArg && arg && !arg.name && !addArg.name) { arg = addArg; } } } tmpArgs.push(arg); } } else if (additionalArgumentSettings) { tmpArgs = additionalArgumentSettings; } for (var _c = 0, tmpArgs_1 = tmpArgs; _c < tmpArgs_1.length; _c++) { var arg = tmpArgs_1[_c]; var param = { name: arg.name, position: arg.position || sardines_core_1.Http.ServiceInputParamPosition.body }; if (arg.type in ['string', 'number', 'boolean']) { param.type = sardines_core_1.Http.ServiceInputParamType[arg.type]; } else { param.type = sardines_core_1.Http.ServiceInputParamType.object; } httpServiceSettings.inputParameters.push(param); } return httpServiceSettings; }; HttpServiceDriver.prototype.invokeService = function (originalServiceSettings) { var _this = this; var parameters = []; for (var _i = 1; _i < arguments.length; _i++) { parameters[_i - 1] = arguments[_i]; } var serviceSettings = 'path' in originalServiceSettings ? originalServiceSettings : this.getDefaultHttpServiceSettings(originalServiceSettings); var addr = this.assembleAddress(serviceSettings); var params = this.assembleParameters(serviceSettings, parameters); if (params.query) { addr += '?' + querystring.stringify(params.query); delete params.query; } params.mode = 'cors'; params.credentials = 'include'; var response = Object.assign({}, { type: sardines_core_1.Http.ServiceResponseType.json, }, serviceSettings.response); if (ParallelProcesses.length > 0) { Promise.all(ParallelProcesses.map(function (fn) { return new Promise(function (resolve) { return __awaiter(_this, void 0, void 0, function () { var res, e_1; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4, fn({ service: serviceSettings, parameters: parameters, fetchOptions: params, address: addr })]; case 1: res = _a.sent(); return [2, resolve(res)]; case 2: e_1 = _a.sent(); sardines_core_1.utils.inspectedDebugLog(this.logMesgHeader + " error when executing parallel process", e_1); return [3, 3]; case 3: return [2]; } }); }); }); })) .then(function () { }) .catch(function () { }); } return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { var errMsg, middlewareHandler, e_2, execPostProcesses, jobs; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: errMsg = null; sardines_core_1.utils.inspectedDebugLog(this.logMesgHeader + " fetching address [" + addr + "] with parameters:", params); middlewareHandler = sardines_core_1.utils.chainFunctions(Middlewares, { service: serviceSettings, parameters: parameters, fetchOptions: params, address: addr }); if (!middlewareHandler) return [3, 4]; _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4, middlewareHandler()]; case 2: _a.sent(); return [3, 4]; case 3: e_2 = _a.sent(); throw sardines_core_1.utils.unifyErrMesg(e_2, 'service driver', 'middleware'); case 4: if (!addr || params.abort) { reject({ type: 'service driver', subType: 'request aborted', error: 'request aborted by middleware' }); } execPostProcesses = function (error, result) { return __awaiter(_this, void 0, void 0, function () { var postProcessHandler; return __generator(this, function (_a) { switch (_a.label) { case 0: postProcessHandler = sardines_core_1.utils.chainFunctions(PostProcesses, { service: serviceSettings, parameters: parameters, fetchOptions: params, address: addr, error: error, result: result, }); if (!postProcessHandler) return [3, 2]; return [4, postProcessHandler()]; case 1: _a.sent(); _a.label = 2; case 2: return [2]; } }); }); }; jobs = [ cross_fetch_1.default(addr, params) .then(function (res) { if (res.status >= 400) { errMsg = { status: res.status, message: res.statusText, address: addr, fetchParameters: params, response: res }; throw sardines_core_1.utils.unifyErrMesg(errMsg, 'service driver', 'request'); } try { var result = null; switch (response.type.toLocaleLowerCase()) { case sardines_core_1.Http.ServiceResponseType.json: result = res.json(); break; case sardines_core_1.Http.ServiceResponseType.text: case sardines_core_1.Http.ServiceResponseType.string: result = res.text(); break; default: result = res.formData(); break; } return result; } catch (e) { throw sardines_core_1.utils.unifyErrMesg({ error: e, msg: "Error when parsing response content according to service response type: [" + response.type + "]" }, 'service driver', 'parse result from response'); } }, function (err) { throw sardines_core_1.utils.unifyErrMesg(err, 'service driver', 'request'); }) .then(function (payload) { return __awaiter(_this, void 0, void 0, function () { var err, result, e_3; return __generator(this, function (_a) { switch (_a.label) { case 0: err = null; result = null; if (!errMsg) { if (typeof payload !== 'object') result = payload; if (payload.res) result = payload.res; else if (payload.error) { err = payload; } else result = payload; } else { err = Object.assign(errMsg, payload); } _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4, execPostProcesses(err, result)]; case 2: _a.sent(); return [3, 4]; case 3: e_3 = _a.sent(); err = sardines_core_1.utils.unifyErrMesg(e_3, 'service driver', 'post processes'); return [3, 4]; case 4: return [2, { err: err, result: result, }]; } }); }); }) ]; Array.prototype.push.apply(jobs, GroupProcesses.map(function (fn) { return new Promise(function (resolve, reject) { return __awaiter(_this, void 0, void 0, function () { var res, e_4; return __generator(this, function (_a) { switch (_a.label) { case 0: _a.trys.push([0, 2, , 3]); return [4, fn({ service: serviceSettings, parameters: parameters, fetchOptions: params, address: addr })]; case 1: res = _a.sent(); resolve(res); return [3, 3]; case 2: e_4 = _a.sent(); reject(e_4); return [3, 3]; case 3: return [2]; } }); }); }); })); Promise.all(jobs) .then(function (responses) { var res = responses[0]; if (res.err) { if (res.err.type === 'service provider' && res.err.subType === 'service handler') { reject(res.err.error); } else reject(res.err); } else resolve(res.result); }) .catch(function (e) { if (e && typeof e === 'object' && typeof e.error !== 'undefined' && typeof e.type === 'string') { reject(e); } else { reject(sardines_core_1.utils.unifyErrMesg(e, 'service driver', 'group process')); } }); return [2]; } }); }); }); }; HttpServiceDriver.prototype.assembleAddress = function (serviceSettings) { var addr = this.providerInfo.host || '127.0.0.1'; if (this.providerInfo.port) { addr += ":" + this.providerInfo.port; } if (this.providerInfo.root) { addr += this.providerInfo.root; } addr += serviceSettings.path; addr = addr.replace(/\/+/, '/'); addr = (this.providerInfo.protocol || 'http') + '://' + addr; return addr; }; HttpServiceDriver.prototype.assembleParameters = function (service, parameters) { var params = {}, headers = { 'Content-Type': 'application/json', }, query = null, body = null, cookie = null; var schema = service.inputParameters || []; params.method = (service.method || 'POST').toUpperCase(); if (Object.prototype.toString.call(schema) === '[object Array]') { parameters.forEach(function (item, i) { if (item !== null && schema.length > i) { var def = schema[i]; switch (def.position.toLocaleString()) { case 'body': if (!def.name && typeof item === 'object') { body = item; } else if (def.name) { if (body === null) body = {}; body[def.name] = item; } break; case 'header': case 'headers': if (!def.name && typeof item === 'object') { headers = item; } else if (def.name) { if (headers === null) headers = {}; headers[def.name] = item; } break; case 'query': case 'address': case 'addr': if (!def.name && typeof item === 'object') { query = item; } else if (def.name) { if (query === null) query = {}; query[def.name] = item; } break; case 'cookie': case 'cookies': if (!def.name && typeof item === 'object') { cookie = item; } else if (def.name) { if (cookie === null) cookie = {}; cookie[def.name] = item; } break; default: break; } } }); } if (cookie) { for (var c in cookie) { var cstr = c + '=' + cookie[c] + ' '; headers.cookie = headers.cookie ? headers.cookie + cstr : cstr; } } params.headers = headers; if (body) { params.body = JSON.stringify(body); } if (query) params.query = query; return params; }; return HttpServiceDriver; }()); exports.default = HttpServiceDriver;