lemon-engine
Version:
Lemon Engine Module to Synchronize Node over DynamoDB + ElastiCache + Elasticsearch by [lemoncloud](https://lemoncloud.io)
306 lines • 15 kB
JavaScript
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
* Protocol Proxy Service Exports
* - proxy call to lemon-protocol-api service.
*
*
* @see lemon-protocol-api/api/protocol-api.js
*
* @author steve@lemoncloud.io
* @date 2019-05-23
* @copyright (C) lemoncloud.io 2019 - All Rights Reserved.
*/
var query_string_1 = __importDefault(require("query-string"));
var url_1 = __importDefault(require("url"));
var http_proxy_1 = __importDefault(require("./http-proxy"));
var maker = function (_$, name, options) {
name = name || 'PR';
var $U = _$.U; // re-use global instance (utils).
var $_ = _$._; // re-use global instance (_ lodash).
if (!$U)
throw new Error('$U is required!');
if (!$_)
throw new Error('$_ is required!');
var NS = $U.NS(name, 'yellow'); // NAMESPACE TO BE PRINTED.
//! load common functions
var _log = _$.log;
var _inf = _$.inf;
var _err = _$.err;
/** ****************************************************************************************************************
* Internal Proxy Function
** ****************************************************************************************************************/
var PROXY = { type: '', host: '' };
var ENDPOINT = $U.env('PROTOCOL_PROXY_API', typeof options == 'string' ? options : '');
var $proxy = function () {
var NAME = 'X' + name; // service name.
var $SVC = _$(NAME, null);
if ($SVC)
return $SVC;
//! make instance.
if (!ENDPOINT)
throw new Error('env:PROTOCOL_PROXY_API is required!');
var aa = ENDPOINT.split('/'); // split 'http://localhost:8092/protocol'
PROXY.type = aa.pop();
PROXY.host = aa.join('/');
_log(NS, 'proxy:' + name + ' config. host=', PROXY.host, ', type=', PROXY.type);
return http_proxy_1.default(_$, NAME, PROXY.host); // re-use proxy by name
};
/** ****************************************************************************************************************
* Main Implementation.
** ****************************************************************************************************************/
var thiz = new (/** @class */ (function () {
function class_1() {
var _this = this;
this.name = function () { return "protocol-proxy:" + name; };
this.endpoint = function () { return ENDPOINT; };
/**
* Prepare URL string.
*/
this.chain_prepare_url = function (url, body, callback) {
if (!url)
return Promise.reject(new Error('url is required!'));
var url_str = url && typeof url === 'object' ? _this.build_url(url) : url;
var that = { url: url_str };
if (body !== undefined)
that.body = body; // data body to post.
if (callback !== undefined)
that.callback = typeof callback === 'object' ? _this.build_url(callback) : callback; // callback url (ONLY for SNS)
return Promise.resolve(that);
};
/**
* Validate URL.
*
* @param url (string/object)
*/
this.chain_validate_url = function (that) {
//! parse URL string if required!.
var $url = (function (url) {
if (typeof url == 'object')
return url;
else if (typeof url == 'string')
return url_1.default.parse(url, false);
else
throw new Error('Unknown data-type of url. type:' + typeof url);
})(that.url || '');
// parse url
var protocol = $url.protocol || '';
var service = $url.hostname || '';
//1-1. FALSE: protocol is not lemon:
if (protocol != 'lemon:')
return Promise.reject(new Error('protocol should be lemon:. but ' + protocol));
//1-2. FALSE: service not exist
if (!service)
return Promise.reject(new Error('.service is required!'));
//! returns.
return that;
};
}
/**
* Synchronized Call to URL.
* - 동기화 실행으로, 내부적으로 Http/Lambda 호출로 Promise() 된 실행 결과를 얻을 수 있음.
*
* example:
* - do_execute('lemon://imweb-pools/goods/0/next-id') => GET 'lemon-imweb-pools-api/goods/0/next-id'
* - do_execute('lemon://imweb-pools/goods/0/next-id#') => POST 'lemon-imweb-pools-api/goods/0/next-id'
*
* @param {string|object} url
*/
class_1.prototype.do_execute = function (url) {
_log(NS, "do_execute()....");
if (!url)
return Promise.reject(new Error('url is required!'));
// // validate url
// if (!chain_validate_url(url)) return Promise.reject(url);
// // force url to be 'string' type before sending it
// const url_str = typeof url === 'object' ? build_url(url) : url;
// http-proxy.do_get (TYPE, ID, CMD, $param, $body)
// return $proxy().do_get(PROXY.type, '!', 'execute', {url:url_str});
return this.chain_prepare_url(url)
.then(this.chain_validate_url)
.then(function (_) {
var url = _.url || '';
return $proxy().do_get(PROXY.type, '!', 'execute', { url: url });
});
};
/**
* Synchronized Call to URL for post
* - 동기화 실행으로, 내부적으로 Http/Lambda 호출로 Promise() 된 실행 결과를 얻을 수 있음.
*
* @param {string|object} url
* @param {string|object} body
* @returns {Promised}
*/
class_1.prototype.do_post_execute = function (url, body) {
_log(NS, "do_post_execute()....");
if (!url)
return Promise.reject(new Error('url is required!'));
// // validate url
// if (!chain_validate_url(url)) return Promise.reject(url);
// // force url to be 'string' type before sending it
// const url_str = typeof url === 'object' ? build_url(url) : url;
// // http-proxy.do_get (TYPE, ID, CMD, $param, $body)
// return $proxy().do_post(PROXY.type, '!', 'execute', {url:url_str}, body);
return this.chain_prepare_url(url, body)
.then(this.chain_validate_url)
.then(function (_) {
var url = _.url || '';
var body = _.body || '';
return $proxy().do_post(PROXY.type, '!', 'execute', { url: url }, body);
});
};
/**
* Asynchronized Call to URL.
* - 비동기식 실행으로, 내부적으로 SNS를 활용하기도 한다.
*
* @param {string|object} url
* @param {string|object} callback SNS Notification 실행후, 결과 처리를 받기 위해서 추가됨 @181125
* @returns {Promised}
*/
class_1.prototype.do_notify = function (url, callback) {
_log(NS, "do_notify()....");
if (!url)
return Promise.reject(new Error('url is required!'));
// // validate url
// if (!chain_validate_url(url)) return Promise.reject(url);
// // force url to be 'string' type before sending it
// const url_str = typeof url === 'object' ? build_url(url) : url;
// // http-proxy.do_get (TYPE, ID, CMD, $param, $body)
// return $proxy().do_get(PROXY.type, '!', 'notify', {url:url_str});
return this.chain_prepare_url(url, '', callback)
.then(this.chain_validate_url)
.then(function (_) {
var url = _.url || '';
// const body = _.body||'';
var callback = _.callback || '';
return $proxy().do_get(PROXY.type, '!', 'notify', { url: url, callback: callback });
});
};
/**
* Asynchronized Call to URL for post
* - 비동기식 실행으로, 내부적으로 SNS를 활용하기도 한다.
*
* @param {string|object} url
* @param {string|object} body
* @param {string|object} callback SNS Notification 실행후, 결과 처리를 받기 위해서 추가됨 @181125
* @returns {Promised}
*/
class_1.prototype.do_post_notify = function (url, body, callback) {
_log(NS, "do_post_notify()....");
if (!url)
return Promise.reject(new Error('url is required!'));
// // validate url
// if (!chain_validate_url(url)) return Promise.reject(url);
// // force url to be 'string' type before sending it
// const url_str = typeof url === 'object' ? build_url(url) : url;
// // http-proxy.do_post (TYPE, ID, CMD, $param, $body)
// return $proxy().do_post(PROXY.type, '!', 'notify', {url:url_str}, body);
return this.chain_prepare_url(url, body, callback)
.then(this.chain_validate_url)
.then(function (_) {
var url = _.url || '';
var body = _.body || '';
var callback = _.callback || '';
// return $proxy().do_post(PROXY.type, '!', 'notify', {url}, body); //! original code.
// ! 기존의 호환성 유지를 위해서, 변경된 규칙은 body에 {url, body, callback} 구조체로 보낸다.
return $proxy().do_post(PROXY.type, '!', 'notify', '', _); //! support callback @181125.
});
};
/**
* Asynchronized Call to URL via SQS
* - 비동기식 실행으로, 내부적으로 SQS를 활용하기도 한다.
*
* @param {string|object} url
* @returns {Promised}
*/
class_1.prototype.do_queue = function (url) {
_log(NS, "do_queue()....");
if (!url)
return Promise.reject(new Error('url is required!'));
// // validate url
// if (!chain_validate_url(url)) return Promise.reject(url);
// // force url to be 'string' type before sending it
// const url_str = typeof url === 'object' ? build_url(url) : url;
// // http-proxy.do_get (TYPE, ID, CMD, $param, $body)
// return $proxy().do_get(PROXY.type, '!', 'notify', {url:url_str});
return this.chain_prepare_url(url)
.then(this.chain_validate_url)
.then(function (_) {
var url = _.url || '';
// const body = _.body||'';
return $proxy().do_get(PROXY.type, '!', 'queue', { url: url });
});
};
/**
* Asynchronized Call to URL for post via SQS
* - 비동기식 실행으로, 내부적으로 SQS를 활용하기도 한다.
*
* @param {string|object} url
* @param {string|object} body
* @returns {Promised}
*/
class_1.prototype.do_post_queue = function (url, body) {
_log(NS, "do_post_queue()....");
if (!url)
return Promise.reject(new Error('url is required!'));
// // validate url
// if (!chain_validate_url(url)) return Promise.reject(url);
// // force url to be 'string' type before sending it
// const url_str = typeof url === 'object' ? build_url(url) : url;
// // http-proxy.do_post (TYPE, ID, CMD, $param, $body)
// return $proxy().do_post(PROXY.type, '!', 'notify', {url:url_str}, body);
return this.chain_prepare_url(url, body)
.then(this.chain_validate_url)
.then(function (_) {
var url = _.url || '';
var body = _.body || '';
// return $proxy().do_post(PROXY.type, '!', 'notify', {url}, body); //! original code.
// ! 기존의 호환성 유지를 위해서, 변경된 규칙은 body에 {url, body} 구조체로 보낸다.
return $proxy().do_post(PROXY.type, '!', 'queue', '', { url: url, body: body });
});
};
/**
* 프로토콜 형식 다음과 같음.
* `lemon://<sid?>@<service-name>/<type>/<id?>/<cmd?>?<param>#<body>`
*
* sid : site/session-id 로 서비스를 실행할 계정
* service-name : 실행할 서비스의 이름 (예: `messages` => `lemon-messages-api`)
* type : 서비스내 API의 이름 (예: `user`)
* id : 선택) 서비스 API의 ID 값.
* cmd : 선택) 서비스 API의 CMD 값.
* param : QueryString 형태의 전달 파라미터.
* body : QueryString (또는 json 형식) 형태의 body 파라미터. (json 일때는 '{[,]}'으로 감쌈)
*/
class_1.prototype.build_url = function ($url) {
$url = $url || {};
var PROTOCOL = 'lemon://';
var sid = $url.sid || $url.SID;
var service = $url.service || $url.SERVICE;
var type = $url.type || $url.TYPE;
var id = $url.id || $url.ID;
var cmd = $url.cmd || $url.CMD;
var $param = $url.param || $url.$param || $url.PARAM;
var param = typeof $param === 'object' ? query_string_1.default.stringify($param) : $param;
var $body = $url.body || $url.$body || $url.BODY;
var body = typeof $body === 'object' ? query_string_1.default.stringify($body) : $body;
//! as URL string.
var url = PROTOCOL + // Madatory => lemon://
(sid ? encodeURIComponent(sid) + '@' : '') + // Optional => sid@
service + // Madatory => service
(type ? '/' + encodeURIComponent(type) : '/') + // Partial Madatory => /type
(id ? '/' + encodeURIComponent(id) : '') + // Optional => /id
(cmd ? '/' + encodeURIComponent(cmd) : '') + // Optional => /cmd
(param ? '?' + param : '') + // Optional => ?param
(body ? '#' + body : ''); // Optional => #body
return url;
};
return class_1;
}()))();
//! create & register service.
return _$(name, thiz);
};
exports.default = maker;
//# sourceMappingURL=protocol-proxy.js.map
;