@methodus/server
Version:
dynamic rpc components
191 lines • 10.2 kB
JavaScript
;
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const excludedProps = ['constructor'];
require("reflect-metadata");
const config_1 = require("../config");
const response_1 = require("../response");
const serversList_1 = require("../servers/serversList");
const fp_1 = require("../fp");
const log_1 = require("../log");
const rest_1 = require("../rest");
const class_container_1 = require("../class-container");
const configuration_1 = require("../decorators/configuration");
const correlator = require('correlation-id');
let methodMetadataKey = 'methodus';
let metadataKey = 'params';
function mergeMetadata(methodus) {
let config = config_1.MethodusConfigurations.get();
let methodinformation = config.classes.get(methodus.name);
return Object.assign({}, methodus, methodinformation);
}
/** the @Method decorator registers the model with the odm
* @param {Verbs} verb - the HTTP verb for the route.
* @param {string} route - express route string.
* @param {Function[]} middlewares - an array of middlewares to apply to this function}
*/
const METHODLOG = 'methodus::Method';
function Method(verb, route, middlewares) {
return (target, propertyKey, descriptor) => {
target.methodus = target.methodus || { _events: {}, _descriptors: {} };
let metaObject = Object.assign({}, { verb, route, propertyKey, middlewares, params: [] });
if (target.methodus._descriptors[propertyKey]) {
metaObject = Object.assign(metaObject, { params: target.methodus._descriptors[propertyKey].params });
}
Reflect.defineMetadata(methodMetadataKey, metaObject, target, propertyKey);
target.methodus._descriptors[propertyKey] = metaObject;
let paramsMap = metaObject.params;
paramsMap.sort((a, b) => {
return a.index - b.index;
});
// save a reference to the original method
let originalMethod = descriptor.value;
let classes = {};
descriptor.value = function (...args) {
return __awaiter(this, void 0, void 0, function* () {
validateServerIsRunning();
//extract metadata for class and method
let configName = target.name;
if (!configName && target.constructor)
configName = target.constructor.name;
let config = serversList_1.Servers.classes[configName];
//we will return a MethodResult or a MEthodError
let methodResult = null;
let proto = fp_1.fp.maybeProto(this);
//try to get the method metadata from the Relection API.
let methodus = target.methodus;
if (!methodus) {
methodus = Reflect.getOwnMetadata(methodMetadataKey, target, propertyKey) || {};
}
let existingClassMetadata = class_container_1.ClassContainer.get(methodus.name);
//merge the configuration object
Object.assign(methodus, methodus._descriptors[propertyKey], existingClassMetadata);
let functionArgs = [];
let sendFlag = false;
//rest paramters should be parsed differntly
const parser = new rest_1.RestParser(args, paramsMap, functionArgs);
let ParserResponse = parser.parse();
//acquire the method information from the config classes map
let completeConfiguration = Object.assign({}, methodus, config);
let methodType = "Local" /* Local */; //we default to local
if (methodus) {
let configurationKey = methodus.name.replace('@tmla-tiles/', '@tmla-contracts/');
let configurationBlock = configuration_1.ConfigHelper.get(configurationKey);
if (!configurationBlock) {
configurationBlock = configuration_1.ConfigHelper.get(methodus.name);
}
if (configurationBlock) {
Object.assign(completeConfiguration, {
methodType: configurationBlock.transport,
resolver: () => configurationBlock.resolver
});
}
}
if (completeConfiguration && completeConfiguration.methodType)
methodType = completeConfiguration.methodType;
// run and store the result
let restHeaders = null;
try {
let server = null;
let i = 0;
const mappedArgs = paramsMap.map((param) => {
return { [param.name || param.from]: ParserResponse.args[param.index] };
});
log_1.logger.info(`Method::call`, methodType, originalMethod.name, ...mappedArgs);
switch (methodType) {
case "Mock" /* Mock */:
methodResult = new response_1.MethodResult(methodus._mocks[propertyKey]);
break;
case "Local" /* Local */:
methodResult = yield originalMethod.apply(this, ParserResponse.args);
break;
case "Http" /* Http */:
server = "express" /* Express */;
break;
case "Socket" /* Socket */:
server = "socketio" /* Socket */;
break;
case "MQ" /* MQ */:
server = "amqp" /* RabbitMQ */;
break;
case "Redis" /* Redis */:
server = "redis" /* Redis */;
break;
case "Kafka" /* Kafka */:
server = "kafka" /* Kafka */;
break;
}
if (server === "express" /* Express */) {
methodResult = new response_1.MethodResult(serversList_1.Servers.send(server, ParserResponse.args, completeConfiguration, paramsMap, ParserResponse.securityContext));
}
else if (server) {
methodResult = yield serversList_1.Servers.send(server, ParserResponse.args, completeConfiguration, paramsMap, ParserResponse.securityContext);
}
}
catch (error) {
error.statusCode = error.statusCode || 500;
log_1.logger.error(this, error);
if (ParserResponse.isRest) {
new rest_1.RestResponse(args, error, restHeaders);
}
else {
throw (error);
}
}
if (methodResult && ParserResponse.isRest) {
new rest_1.RestResponse(args, methodResult, methodResult.headers);
return;
}
else {
if (methodResult !== null && methodResult !== undefined && methodResult.result !== null && methodResult.result !== undefined) {
const requestResult = yield methodResult.result;
try {
if (Buffer.isBuffer(requestResult)) {
const bufferedResult = new Buffer(requestResult).toString();
if (typeof bufferedResult === 'string') {
try {
methodResult = new response_1.MethodResult(JSON.parse(bufferedResult));
}
catch (error) {
//not json result
methodResult = bufferedResult;
}
}
}
else {
if (requestResult.result === undefined) {
methodResult = new response_1.MethodResult(requestResult);
}
else {
methodResult = requestResult;
}
}
}
catch (error) {
error.statusCode = error.statusCode || 500;
log_1.logger.error(this, error);
throw (error);
}
}
log_1.logger.info(`Method::OK`, '<==', methodType, originalMethod.name);
//log.trace(`Method::OK`, '<==', methodType, originalMethod.name);
return methodResult;
}
});
};
return descriptor;
};
}
exports.Method = Method;
function validateServerIsRunning() {
if (!serversList_1.Servers)
throw (new Error(`methodus server is not running, did you miss a 'run' statement?`));
}
//# sourceMappingURL=method.js.map