lemon-engine
Version:
Lemon Engine Module to Synchronize Node over DynamoDB + ElastiCache + Elasticsearch by [lemoncloud](https://lemoncloud.io)
535 lines • 18.8 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
var NS = 'util';
var Utilities = /** @class */ (function () {
function Utilities(_$) {
this._$ = _$;
this.log = _$.log;
this.err = _$.err;
this.name = NS + "-utils";
}
Utilities.prototype.lodash = function () {
// use underscore util.
var $_ = this._$._;
if (!$_)
throw new Error('$_(lodash) is required!');
return $_;
};
//! some helper function.s
Utilities.prototype.get_env = function (name, def_val) {
if (typeof this._$.environ === 'function')
return this._$.environ(name, def_val);
// as default, load from proces.env.
var val = (process && process.env[name]) || undefined;
return val === undefined ? def_val : val;
};
Utilities.prototype.env = function (name, def_val) {
return this.get_env(name, def_val);
};
Utilities.prototype.is_dev = function () {
var env = this.get_env('ENV') || this.get_env('NODE_ENV') || this.get_env('STAGE');
return env === 'production' || env === 'op' ? false : true;
};
/**
* Load CSV File in data folder.
*
* @param name
* @returns {Promise}
* @private
*/
Utilities.prototype.load_data_csv = function (name) {
if (!name)
throw new Error('param:name is required!');
var fs = require('fs');
var parse = require('csv-parse');
var path = require('path');
//! calculate the target data file.
var fname = path.resolve(__dirname, '../data/' + name + (name.endsWith('.csv') ? '' : '.csv'));
//! prepare promised.
var chain = new Promise(function (resolve, reject) {
//! read file-stream.
fs.readFile(fname, 'UTF-8', function (err, data) {
if (err)
return reject(err);
//! call parse.
parse(data, { columns: true, trim: true }, function (err, rows) {
if (err)
return reject(err);
return resolve(rows);
});
});
});
return chain;
};
Utilities.prototype.load_data_yaml = function (name) {
if (!name)
throw new Error('param:name is required!');
var fs = require('fs');
var path = require('path');
var yaml = require('js-yaml');
//! calculate the target data file.
var fname = path.resolve(__dirname, '../data/' + name + (name.endsWith('.yml') ? '' : '.yml'));
this.log(NS, 'load file =', fname);
//! prepare promised.
var chain = new Promise(function (resolve, reject) {
// Get document, or throw exception on error
try {
var doc = yaml.safeLoad(fs.readFileSync(fname, 'utf8'));
resolve(doc);
}
catch (e) {
reject(e);
}
});
return chain;
};
Utilities.prototype.load_sync_yaml = function (name) {
if (!name)
throw new Error('param:name is required!');
var fs = require('fs');
var path = require('path');
var yaml = require('js-yaml');
//! calculate the target data file.
var fname = path.resolve(__dirname, '../data/' + name + (name.endsWith('.yml') ? '' : '.yml'));
// Get document, or throw exception on error
try {
this.log(NS, 'load-sync-file =', fname);
var doc = yaml.safeLoad(fs.readFileSync(fname, 'utf8'));
return doc;
}
catch (e) {
this.err(NS, "error:load-sync-yaml(" + name + ")=", e);
}
return {};
};
Utilities.prototype.extend = function (a, b) {
for (var x in b)
a[x] = b[x];
return a;
};
Utilities.prototype.isset = function (x) {
return x === undefined ? false : true;
};
Utilities.prototype.empty = function (x) {
return x ? false : true;
};
Utilities.prototype.min = function (a, b) {
return a < b ? a : b;
};
Utilities.prototype.max = function (a, b) {
return a > b ? a : b;
};
Utilities.prototype.round = function (a) {
return Math.round(a);
};
Utilities.prototype.json = function (o, isSorted) {
if (isSorted) {
var output = {};
Object.keys(o)
.sort()
.forEach(function (key) {
output[key] = o[key];
});
o = output;
}
return (o && JSON.stringify(o)) || o;
};
// timestamp value.
Utilities.timestamp = function (date, timeZone) {
var dt = date && typeof date === 'object' ? date : date ? new Date(date) : new Date();
var now = new Date();
var tzo = now.getTimezoneOffset(); // Asia/Seoul => -540
var diff = timeZone * 60 + tzo;
if (diff)
dt.setSeconds(dt.getSeconds() + 1 * diff * 60);
var y = dt.getFullYear();
var m = dt.getMonth() + 1; //Months are zero based
var d = dt.getDate();
var h = dt.getHours();
var i = dt.getMinutes();
var s = dt.getSeconds();
var d2 = function (x) { return "" + (x < 10 ? '0' : '') + x; };
var ret = d2(y) +
'-' +
d2(m) +
'-' +
d2(d) +
' ' +
d2(h) +
':' +
d2(i) +
':' +
d2(s);
return ret;
};
// parse timestamp to date.
Utilities.datetime = function (dt, timeZone) {
var ret = null;
if (typeof dt == 'string') {
var now = new Date();
var tzo = now.getTimezoneOffset();
var diff = timeZone * 60 + tzo;
var tstr = '';
if (/^[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/.test(dt)) {
// like 1978-12-01
tstr = dt + ' 12:00:00';
}
else if (/^[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]) ([01]?[0-9]|2[0-3]):[0-5][0-9]$/.test(dt)) {
// like 1978-12-01 12:34
tstr = dt + ':00';
}
else if (/^[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]) ([01]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/.test(dt)) {
// like 1978-12-01 12:34:20
tstr = dt + '';
}
else if (/^[12]\d{3}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])$/.test(dt)) {
// like 19781201
tstr = dt.substr(0, 4) + '-' + dt.substr(4, 2) + '-' + dt.substr(6, 2) + ' 12:00:00';
}
else if (/^[12]\d{3}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01]) ([01]?[0-9]|2[0-3])[0-5][0-9]$/.test(dt)) {
// like 19781201 1234
tstr =
dt.substr(0, 4) +
'-' +
dt.substr(4, 2) +
'-' +
dt.substr(6, 2) +
' ' +
dt.substr(9, 2) +
':' +
dt.substr(11, 2) +
':00';
}
ret = (function (ts) {
if (!ts)
return null;
var aa = ts.split(' ');
var dd = aa[0].split('-');
var hh = aa[1].split(':');
var y = parseInt(dd[0]);
var m = parseInt(dd[1]) - 1;
var d = parseInt(dd[2]);
var h = parseInt(hh[0]);
var i = parseInt(hh[1]);
var s = parseInt(hh[2]);
return new Date(y, m, d, h, i, s, 0);
})(tstr);
if (ret && diff)
ret.setSeconds(ret.getSeconds() + -1 * diff * 60);
return ret;
}
else if (typeof dt == 'number') {
ret = new Date(dt);
}
else if (typeof dt == 'object' && dt instanceof Date) {
ret = dt;
}
else if (dt === undefined) {
ret = new Date();
}
else {
throw new Error('Invalid type of dt: ' + typeof dt);
}
return ret;
};
Utilities.prototype.ts = function (d, timeZone) {
return Utilities.timestamp(d, timeZone);
};
Utilities.prototype.dt = function (dt, timeZone) {
return Utilities.datetime(dt, timeZone);
};
Utilities.prototype.now = function () {
return this.dt();
};
/**
* 현재 시간값 (number of milliseconds since midnight of January 1, 1970.)
*
*
* @returns {number}
*/
Utilities.prototype.current_time_ms = function () {
//TODO:XENI - 서버와 시간 동기화를 위해서, 디비서버에등에서 일체화된 시간 동기값을 환산하여 준다.
var time_shift = 0;
var ret = new Date().getTime();
ret += time_shift;
return ret;
};
/**
* NameSpace Maker.
*
* @returns {string}
*/
Utilities.prototype.NS = function (ns, color, len) {
if (!ns)
return ns;
len = len || 4;
len = len - ns.length;
len = len < 0 ? 0 : len;
var SPACE = ' ';
ns = SPACE.substr(0, len) + ns + ':';
if (color) {
var COLORS = {
red: '\x1b[31m',
green: '\x1b[32m',
yellow: '\x1b[33m',
blue: '\x1b[34m',
magenta: '\x1b[35m',
cyan: '\x1b[36m',
white: '\x1b[37m',
};
ns = COLORS[color] + ns + '\x1b[0m';
}
return ns;
};
// escape string for mysql.
Utilities.prototype.escape = function (str, urldecode) {
if (str === undefined)
return 'NULL';
if (this.isInteger(str))
return str;
str = str || '';
if (typeof str == 'object') {
str = JSON.stringify(str);
}
str = str
.replace(/\\/g, '\\\\')
.replace(/\$/g, '\\$')
.replace(/'/g, "\\'")
.replace(/"/g, '\\"');
if (urldecode) {
// url-decode
str = decodeURI(str);
}
return "'" + str + "'";
};
// convert to integer.
Utilities.prototype.isInteger = function (x) {
return typeof x === 'number' && x % 1 === 0;
};
Utilities.prototype.N = function (x, def) {
try {
if (x === '' || x === undefined || x === null)
return def;
if (typeof x === 'number' && x % 1 === 0)
return x;
if (typeof x == 'number')
return parseInt('' + x);
x = '0' + x;
x = x.startsWith('0-') ? x.substr(1) : x; // minus
return parseInt(x.replace(/,/gi, '').trim());
}
catch (e) {
this.err('err at _N: x=' + x + ';' + typeof x + ';' + (e.message || ''), e);
return def;
}
};
//! parse float number (like 1.01)
Utilities.prototype.F = function (x, def) {
try {
if (x === '' || x === undefined || x === null)
return def;
if (typeof x === 'number' && x % 1 === 0)
return x;
if (typeof x == 'number')
return parseFloat('' + x);
x = '0' + x;
x = x.startsWith('0-') ? x.substr(1) : x; // minus
return parseFloat(x.replace(/,/gi, '').trim());
}
catch (e) {
this.err('err at _N: x=' + x + ';' + typeof x + ';' + (e.message || ''), e);
return def;
}
};
//! remove underscore variables.
Utilities.prototype.cleanup = function ($N) {
return Object.keys($N).reduce(function ($N, key) {
if (key.startsWith('_'))
delete $N[key];
if (key.startsWith('$'))
delete $N[key];
return $N;
}, $N);
};
//! remove underscore variables.
Utilities.prototype.updated = function (that, that2) {
var updated = Object.keys(that2).reduce(function (self, key) {
if (that[key] !== that2[key]) {
if (that[key] === null && that2[key] === '') {
// both same.
return self;
}
self[key] = that2[key];
}
return self;
}, {});
return updated;
};
Utilities.prototype.copy = function ($N) {
return Object.keys($N).reduce(function ($n, key) {
$n[key] = $N[key];
return $n;
}, {});
};
Utilities.prototype.copy_node = function ($N, isClear) {
isClear = isClear === undefined ? false : isClear;
return Object.keys($N).reduce(function ($n, key) {
if (key.startsWith('_'))
return $n;
if (key.startsWith('$'))
return $n;
$n[key] = isClear ? null : $N[key];
return $n;
}, {});
};
//! clean up all member without only KEY member.
Utilities.prototype.bare_node = function ($N, opts) {
// return Object.keys($N).reduce(function($n, key) {
// if(key.startsWith('_')) return $n;
// if(key.startsWith('$')) return $n;
// $n[key] = $N[key]
// return $n;
// }, {})
var $n = {};
$n._id = $N._id;
$n._current_time = $N._current_time;
if (opts)
$n = this.extend($n, opts);
return $n;
};
Utilities.prototype.diff = function (obj1, obj2) {
var $_ = this.lodash();
var diff = Object.keys(obj1).reduce(function (result, key) {
if (!obj2.hasOwnProperty(key)) {
result.push(key);
}
else if ($_.isEqual(obj1[key], obj2[key])) {
var resultKeyIndex = result.indexOf(key);
result.splice(resultKeyIndex, 1);
}
return result;
}, Object.keys(obj2));
return diff;
};
Utilities.prototype.diff_node = function (obj1, obj2) {
var keys1 = [], keys2 = [];
var $_ = this.lodash();
Object.keys(obj1).forEach(function (key) {
if (key.startsWith('_'))
return;
if (key.startsWith('$'))
return;
keys1.push(key);
});
Object.keys(obj2).forEach(function (key) {
if (key.startsWith('_'))
return;
if (key.startsWith('$'))
return;
keys2.push(key);
});
var diff = keys1.reduce(function (result, key) {
if (!obj2.hasOwnProperty(key)) {
result.push(key);
}
else if ($_.isEqual(obj1[key], obj2[key])) {
var resultKeyIndex = result.indexOf(key);
result.splice(resultKeyIndex, 1);
}
return result;
}, keys2);
return diff;
};
Utilities.prototype.hash = function (data) {
data = data || '';
data = typeof data === 'object' ? this.json(data, true) : data; //WARN! it must be sorted json.
data = typeof data !== 'string' ? String(data) : data;
/**
* Calculate a 32 bit FNV-1a hash
* Found here: https://gist.github.com/vaiorabbit/5657561
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
*
* @param {string} str the input value
* @param {boolean} [asString=false] set to true to return the hash value as
* 8-digit hex string instead of an integer
* @param {integer} [seed] optionally pass the hash of the previous chunk
* @returns {integer | string}
*/
var hashFnv32a = function (str, asString, seed) {
/*jshint bitwise:false */
var i, l;
var hval = seed === undefined ? 0x811c9dc5 : seed;
for (i = 0, l = str.length; i < l; i++) {
hval ^= str.charCodeAt(i);
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
}
if (asString) {
// Convert to 8 digit hex string
return ('0000000' + (hval >>> 0).toString(16)).substr(-8);
}
return hval >>> 0;
};
return hashFnv32a(data);
};
//! start promise chain.
Utilities.prototype.promise = function (param) {
return new Promise(function (resolve, reject) {
resolve(param);
});
};
//! promise in sequence.
// example) promise_sequence([1,2,3], item => item+1);
Utilities.prototype.promise_sequence = function (array, func) {
var chain = this.promise(array.shift());
chain = array.reduce(function (chain, item) {
return chain.then(function () { return func(item); });
}, chain.then(function (item) { return func(item); }));
return chain;
};
Utilities.prototype.md5 = function (data, digest) {
var crypto = require('crypto');
digest = digest === undefined ? 'hex' : digest;
return crypto
.createHash('md5')
.update(data)
.digest(digest);
};
Utilities.prototype.hmac = function (data, KEY, algorithm, encoding) {
var crypto = require('crypto');
KEY = KEY || 'XENI';
encoding = encoding || 'base64';
algorithm = algorithm || 'sha256';
return crypto
.createHmac(algorithm, KEY)
.update(data)
.digest(encoding);
};
Utilities.prototype.qs_parse = function (query) {
var _this = this;
var QUERY_STRING = require('query-string');
var param = QUERY_STRING.parse(query);
Object.keys(param).forEach(function (key) {
if (false) {
}
//! 빈 파라미터의 값을 빈 문자열로 치환
else if (param[key] === null) {
param[key] = '';
}
//! 숫자로 된 문자열이 오면 숫자로 변환
else if (/^[1-9][0-9]*$/.test(param[key])) {
param[key] = _this.N(param[key]);
}
});
return param;
};
Utilities.prototype.qs_stringify = function (query) {
var QUERY_STRING = require('query-string');
var param = QUERY_STRING.stringify(query);
return param;
};
return Utilities;
}());
exports.Utilities = Utilities;
;
exports.default = Utilities;
//# sourceMappingURL=utilities.js.map
;