UNPKG

lemon-engine

Version:

Lemon Engine Module to Synchronize Node over DynamoDB + ElastiCache + Elasticsearch by [lemoncloud](https://lemoncloud.io)

306 lines 15 kB
"use strict"; 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