sardines-service-driver-http
Version:
This is a built-in service driver for sardines.js
466 lines (465 loc) • 23.7 kB
JavaScript
;
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;