@nextage/nx-frame-be 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/README.md.old +45 -0
- package/build/app.d.ts +0 -0
- package/build/app.js +1 -0
- package/build/aws/aws-cluster-manager.d.ts +28 -0
- package/build/aws/aws-cluster-manager.js +105 -0
- package/build/aws/aws-email-manager.d.ts +24 -0
- package/build/aws/aws-email-manager.js +57 -0
- package/build/aws/aws-queue-manager.d.ts +37 -0
- package/build/aws/aws-queue-manager.js +100 -0
- package/build/aws/aws.interfaces.d.ts +39 -0
- package/build/aws/aws.interfaces.js +2 -0
- package/build/aws/index.d.ts +4 -0
- package/build/aws/index.js +20 -0
- package/build/common/base/__test__/base.model.test.d.ts +1 -0
- package/build/common/base/__test__/base.model.test.js +283 -0
- package/build/common/base/base.controller.d.ts +124 -0
- package/build/common/base/base.controller.js +134 -0
- package/build/common/base/base.interfaces.d.ts +81 -0
- package/build/common/base/base.interfaces.js +2 -0
- package/build/common/base/base.model.d.ts +384 -0
- package/build/common/base/base.model.js +730 -0
- package/build/common/base/folded.model.d.ts +41 -0
- package/build/common/base/folded.model.js +215 -0
- package/build/common/base/mongo-utils.d.ts +122 -0
- package/build/common/base/mongo-utils.js +242 -0
- package/build/common/base/mongo.types.d.ts +20 -0
- package/build/common/base/mongo.types.js +2 -0
- package/build/common/base/sql-utils.d.ts +20 -0
- package/build/common/base/sql-utils.js +69 -0
- package/build/common/constants.d.ts +27 -0
- package/build/common/constants.js +70 -0
- package/build/common/crypto/crypto.classes.d.ts +100 -0
- package/build/common/crypto/crypto.classes.js +146 -0
- package/build/common/crypto/crypto.constants.d.ts +68 -0
- package/build/common/crypto/crypto.constants.js +57 -0
- package/build/common/crypto/crypto.error.d.ts +4 -0
- package/build/common/crypto/crypto.error.js +10 -0
- package/build/common/crypto/crypto.interfaces.d.ts +46 -0
- package/build/common/crypto/crypto.interfaces.js +2 -0
- package/build/common/crypto/crypto.utils.d.ts +139 -0
- package/build/common/crypto/crypto.utils.js +380 -0
- package/build/common/crypto/index.d.ts +3 -0
- package/build/common/crypto/index.js +19 -0
- package/build/common/enums.d.ts +61 -0
- package/build/common/enums.js +75 -0
- package/build/common/errors.d.ts +13 -0
- package/build/common/errors.js +24 -0
- package/build/common/express/express.interfaces.d.ts +20 -0
- package/build/common/express/express.interfaces.js +2 -0
- package/build/common/express/express.utils.d.ts +31 -0
- package/build/common/express/express.utils.js +85 -0
- package/build/common/express/index.d.ts +2 -0
- package/build/common/express/index.js +18 -0
- package/build/common/graphql/__test__/generator.schema.test.d.ts +1 -0
- package/build/common/graphql/__test__/generator.schema.test.js +391 -0
- package/build/common/graphql/directives.d.ts +18 -0
- package/build/common/graphql/directives.js +56 -0
- package/build/common/graphql/generator copy.d.ts +41 -0
- package/build/common/graphql/generator copy.js +385 -0
- package/build/common/graphql/generator.d.ts +42 -0
- package/build/common/graphql/generator.js +385 -0
- package/build/common/graphql/index.d.ts +4 -0
- package/build/common/graphql/index.js +21 -0
- package/build/common/graphql/interfaces.d.ts +67 -0
- package/build/common/graphql/interfaces.js +2 -0
- package/build/common/graphql/loader.d.ts +22 -0
- package/build/common/graphql/loader.js +186 -0
- package/build/common/graphql/scalars/index.d.ts +10 -0
- package/build/common/graphql/scalars/index.js +6 -0
- package/build/common/graphql/scalars/resolvers.d.ts +8 -0
- package/build/common/graphql/scalars/resolvers.js +71 -0
- package/build/common/graphql/scalars/schema.d.ts +1 -0
- package/build/common/graphql/scalars/schema.js +12 -0
- package/build/common/graphql/types/index.d.ts +3 -0
- package/build/common/graphql/types/index.js +6 -0
- package/build/common/graphql/types/schema.d.ts +1 -0
- package/build/common/graphql/types/schema.js +98 -0
- package/build/common/graphql/utils.d.ts +18 -0
- package/build/common/graphql/utils.js +40 -0
- package/build/common/grid-fs/gridfs-base.model.d.ts +53 -0
- package/build/common/grid-fs/gridfs-base.model.js +95 -0
- package/build/common/grid-fs/gridfs.interfaces.d.ts +41 -0
- package/build/common/grid-fs/gridfs.interfaces.js +2 -0
- package/build/common/index.d.ts +10 -0
- package/build/common/index.js +32 -0
- package/build/common/interfaces.d.ts +26 -0
- package/build/common/interfaces.js +10 -0
- package/build/common/manager/bulk-manager.d.ts +59 -0
- package/build/common/manager/bulk-manager.js +103 -0
- package/build/common/manager/crypto-manager.d.ts +88 -0
- package/build/common/manager/crypto-manager.js +200 -0
- package/build/common/manager/index.d.ts +5 -0
- package/build/common/manager/index.js +21 -0
- package/build/common/manager/pubsub-manager.d.ts +20 -0
- package/build/common/manager/pubsub-manager.js +38 -0
- package/build/common/manager/shutdown-manager.d.ts +27 -0
- package/build/common/manager/shutdown-manager.js +118 -0
- package/build/common/manager/socket-io-cli-manager.d.ts +53 -0
- package/build/common/manager/socket-io-cli-manager.js +91 -0
- package/build/common/manager/tunnel-manager.d.ts +28 -0
- package/build/common/manager/tunnel-manager.js +49 -0
- package/build/common/models/coded-entity.controller.d.ts +5 -0
- package/build/common/models/coded-entity.controller.js +9 -0
- package/build/common/models/coded-entity.model.d.ts +25 -0
- package/build/common/models/coded-entity.model.js +51 -0
- package/build/common/models/user.model.d.ts +56 -0
- package/build/common/models/user.model.js +72 -0
- package/build/common/types.d.ts +136 -0
- package/build/common/types.js +16 -0
- package/build/common/utils.d.ts +552 -0
- package/build/common/utils.js +1100 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +18 -0
- package/build/test/env.d.ts +0 -0
- package/build/test/env.js +5 -0
- package/build/test/setup.d.ts +6 -0
- package/build/test/setup.js +59 -0
- package/package.json +90 -0
|
@@ -0,0 +1,1100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.readFileSync = exports.sortBy = exports.deleteKey = exports.flattenArray = exports.getCtxUser = exports.forceGC = exports.logMemory = exports.logClassCtx = exports.uuid = exports.getDatePeriod = exports.getTimeValues = exports.getDateValues = exports.getDateDiff = exports.dateFormat = exports.toMoment = exports.toDate = exports.isValidDateStr = exports.toFilterDatePeriod = exports.parseTypedString = exports.capitalize = exports.jsonToStr = exports.strToJson = exports.dotObj = exports.dottedKeys = exports.percentDiff = exports.findDeep = exports.mergeArraysByKey = exports.hasKeys = exports.isEmpty = exports.containsArrayValue = exports.contains = exports.isEmail = exports.isBase64 = exports.isDefined = exports.isUndefined = exports.isNil = exports.isNotNull = exports.isNumber = exports.isString = exports.isBoolean = exports.isDate = exports.isFunction = exports.isObject = exports.baseComparatorReverse = exports.baseComparator = exports.randomString = exports.validateJwt = exports.generateJwt = exports.prodMode = exports.devMode = void 0;
|
|
16
|
+
exports.validDataUrl = exports.getLastChildren = exports.getLastChild = exports.intersectArraysBy = exports.intersectArrays = exports.arrayToggle = exports.arrayPushUniq = exports.arrayPushRef = exports.addDirectoryToZip = exports.zipFolderStream = exports.zipFolder = exports.checkCommonPassword = exports.checkPasswordComplexity = exports.scheduleJobs = exports.scheduleJob = exports.parseUserAgent = exports.filterObject = exports.generateRandomBuffer = exports.generateRandomHex = exports.resizeBuffer = exports.initObjectWithProperty = exports.initObjectFromDotNotation = exports.chunkString = exports.encodeString = exports.isEqual = exports.hasAttr = exports.setAttr = exports.getAttr = exports.clone = exports.merge = exports.uniqBy = exports.union = void 0;
|
|
17
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
18
|
+
const moment_1 = __importDefault(require("moment"));
|
|
19
|
+
const fs_1 = __importDefault(require("fs"));
|
|
20
|
+
const jszip_1 = __importDefault(require("jszip"));
|
|
21
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
22
|
+
const node_schedule_1 = __importDefault(require("node-schedule"));
|
|
23
|
+
const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
|
|
24
|
+
const ua_parser_js_1 = __importDefault(require("ua-parser-js"));
|
|
25
|
+
const uuid_1 = require("uuid");
|
|
26
|
+
const uuid_2 = require("uuid");
|
|
27
|
+
const constants_1 = require("./constants");
|
|
28
|
+
const enums_1 = require("./enums");
|
|
29
|
+
const mongo_utils_1 = require("./base/mongo-utils");
|
|
30
|
+
// import COMMON_PWD from '../assets/common-pwd-100k.json';
|
|
31
|
+
function devMode() {
|
|
32
|
+
return process.env.NODE_ENV === enums_1.AppMode.DEV;
|
|
33
|
+
}
|
|
34
|
+
exports.devMode = devMode;
|
|
35
|
+
function prodMode() {
|
|
36
|
+
return process.env.NODE_ENV === enums_1.AppMode.PROD;
|
|
37
|
+
}
|
|
38
|
+
exports.prodMode = prodMode;
|
|
39
|
+
/**
|
|
40
|
+
*
|
|
41
|
+
* @param {*} jti
|
|
42
|
+
*/
|
|
43
|
+
function generateJwt(sub, jti, iss, signOpts = {}, secret) {
|
|
44
|
+
if (!secret)
|
|
45
|
+
secret = process.env.JWT_SECRET;
|
|
46
|
+
if (!signOpts)
|
|
47
|
+
signOpts = {};
|
|
48
|
+
if (!signOpts.expiresIn)
|
|
49
|
+
signOpts.expiresIn = process.env.TOKEN_VALIDITY_DAYS ? `${process.env.TOKEN_VALIDITY_DAYS}d` : `${process.env.JWT_VALIDITY || '8h'}`;
|
|
50
|
+
if (!signOpts.algorithm && process.env.JWT_ALGORITHM)
|
|
51
|
+
signOpts.algorithm = process.env.JWT_ALGORITHM;
|
|
52
|
+
if (!signOpts.algorithm)
|
|
53
|
+
throw new Error('JWT Algorithm is not defined');
|
|
54
|
+
if (!secret)
|
|
55
|
+
throw new Error('Missing JWT secret');
|
|
56
|
+
return jsonwebtoken_1.default.sign({
|
|
57
|
+
sub, jti, iss
|
|
58
|
+
}, secret, signOpts);
|
|
59
|
+
}
|
|
60
|
+
exports.generateJwt = generateJwt;
|
|
61
|
+
/**
|
|
62
|
+
*
|
|
63
|
+
* @param {*} token
|
|
64
|
+
*/
|
|
65
|
+
function validateJwt(token, options = {}, secret) {
|
|
66
|
+
if (!secret)
|
|
67
|
+
secret = process.env.JWT_SECRET;
|
|
68
|
+
return jsonwebtoken_1.default.verify(token, secret, options);
|
|
69
|
+
}
|
|
70
|
+
exports.validateJwt = validateJwt;
|
|
71
|
+
/**
|
|
72
|
+
*
|
|
73
|
+
* @param {*} size
|
|
74
|
+
*/
|
|
75
|
+
function randomString(size = 21) {
|
|
76
|
+
return crypto_1.default.randomBytes(size)
|
|
77
|
+
.toString('base64')
|
|
78
|
+
.slice(0, size);
|
|
79
|
+
}
|
|
80
|
+
exports.randomString = randomString;
|
|
81
|
+
/**
|
|
82
|
+
*
|
|
83
|
+
* @param {*} a
|
|
84
|
+
* @param {*} b
|
|
85
|
+
* @param {*} key
|
|
86
|
+
*/
|
|
87
|
+
function baseComparator(a, b, key) {
|
|
88
|
+
let value1 = key ? key.split('.').reduce((o, i) => o[i] || '', a) : a;
|
|
89
|
+
let value2 = key ? key.split('.').reduce((o, i) => o[i] || '', b) : b;
|
|
90
|
+
if (value1 < value2)
|
|
91
|
+
return -1;
|
|
92
|
+
if (value1 > value2)
|
|
93
|
+
return 1;
|
|
94
|
+
return 0;
|
|
95
|
+
}
|
|
96
|
+
exports.baseComparator = baseComparator;
|
|
97
|
+
/**
|
|
98
|
+
*
|
|
99
|
+
* @param {*} a
|
|
100
|
+
* @param {*} b
|
|
101
|
+
* @param {*} key
|
|
102
|
+
*/
|
|
103
|
+
function baseComparatorReverse(a, b, key) {
|
|
104
|
+
let value1 = key ? key.split('.').reduce((o, i) => o[i] || '', a) : a;
|
|
105
|
+
let value2 = key ? key.split('.').reduce((o, i) => o[i] || '', b) : b;
|
|
106
|
+
if (value1 < value2)
|
|
107
|
+
return 1;
|
|
108
|
+
if (value1 > value2)
|
|
109
|
+
return -1;
|
|
110
|
+
return 0;
|
|
111
|
+
}
|
|
112
|
+
exports.baseComparatorReverse = baseComparatorReverse;
|
|
113
|
+
/**
|
|
114
|
+
* Returns if a value is an object
|
|
115
|
+
*
|
|
116
|
+
* @param {*} value
|
|
117
|
+
*/
|
|
118
|
+
function isObject(value) {
|
|
119
|
+
return lodash_1.default.isObject(value);
|
|
120
|
+
}
|
|
121
|
+
exports.isObject = isObject;
|
|
122
|
+
/**
|
|
123
|
+
* Returns if a value is a function
|
|
124
|
+
*
|
|
125
|
+
* @param {*} value
|
|
126
|
+
*/
|
|
127
|
+
function isFunction(value) {
|
|
128
|
+
return lodash_1.default.isFunction(value);
|
|
129
|
+
}
|
|
130
|
+
exports.isFunction = isFunction;
|
|
131
|
+
/**
|
|
132
|
+
* Returns if a value is a date
|
|
133
|
+
*
|
|
134
|
+
* @param {*} value
|
|
135
|
+
*/
|
|
136
|
+
function isDate(value) {
|
|
137
|
+
return lodash_1.default.isDate(value);
|
|
138
|
+
}
|
|
139
|
+
exports.isDate = isDate;
|
|
140
|
+
/**
|
|
141
|
+
* Returns if a value is a boolean
|
|
142
|
+
*
|
|
143
|
+
* @param {*} value
|
|
144
|
+
*/
|
|
145
|
+
function isBoolean(value) {
|
|
146
|
+
return lodash_1.default.isBoolean(value);
|
|
147
|
+
}
|
|
148
|
+
exports.isBoolean = isBoolean;
|
|
149
|
+
/**
|
|
150
|
+
* Returns if a value is a string
|
|
151
|
+
*
|
|
152
|
+
* @param {*} value
|
|
153
|
+
*/
|
|
154
|
+
function isString(value) {
|
|
155
|
+
return lodash_1.default.isString(typeof value === 'string');
|
|
156
|
+
}
|
|
157
|
+
exports.isString = isString;
|
|
158
|
+
/**
|
|
159
|
+
* Returns if a value is a number
|
|
160
|
+
*
|
|
161
|
+
* @param value
|
|
162
|
+
*/
|
|
163
|
+
function isNumber(value) {
|
|
164
|
+
return lodash_1.default.isNumber(value);
|
|
165
|
+
}
|
|
166
|
+
exports.isNumber = isNumber;
|
|
167
|
+
/**
|
|
168
|
+
* Returns if a value is not null and not undefined
|
|
169
|
+
*
|
|
170
|
+
* @param {*} value
|
|
171
|
+
*/
|
|
172
|
+
function isNotNull(value) {
|
|
173
|
+
return !lodash_1.default.isNil(value);
|
|
174
|
+
}
|
|
175
|
+
exports.isNotNull = isNotNull;
|
|
176
|
+
/**
|
|
177
|
+
*
|
|
178
|
+
* @param value
|
|
179
|
+
* @returns
|
|
180
|
+
*/
|
|
181
|
+
function isNil(value) {
|
|
182
|
+
return lodash_1.default.isNil(value);
|
|
183
|
+
}
|
|
184
|
+
exports.isNil = isNil;
|
|
185
|
+
/**
|
|
186
|
+
* Returns if a value is null or undefined
|
|
187
|
+
*
|
|
188
|
+
* @param {*} value
|
|
189
|
+
*/
|
|
190
|
+
function isUndefined(value) {
|
|
191
|
+
return lodash_1.default.isUndefined(value);
|
|
192
|
+
}
|
|
193
|
+
exports.isUndefined = isUndefined;
|
|
194
|
+
/**
|
|
195
|
+
* Returns if a value is defined
|
|
196
|
+
*
|
|
197
|
+
* @param {*} value
|
|
198
|
+
*/
|
|
199
|
+
function isDefined(value) {
|
|
200
|
+
return !isUndefined(value);
|
|
201
|
+
}
|
|
202
|
+
exports.isDefined = isDefined;
|
|
203
|
+
/**
|
|
204
|
+
*
|
|
205
|
+
* @param {*} v
|
|
206
|
+
* @param {*} opts
|
|
207
|
+
* @returns
|
|
208
|
+
*/
|
|
209
|
+
function isBase64(value, opts = {}) {
|
|
210
|
+
if (!isString(value))
|
|
211
|
+
return false;
|
|
212
|
+
// if (value instanceof Boolean || typeof value === 'boolean')
|
|
213
|
+
// return false;
|
|
214
|
+
if (!opts.allowEmpty && value === '')
|
|
215
|
+
return false;
|
|
216
|
+
var regex = '(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}==|[A-Za-z0-9+\/]{3}=)?';
|
|
217
|
+
var mimeRegex = '(data:\\w+\\/[a-zA-Z\\+\\-\\.]+;base64,)';
|
|
218
|
+
if (opts.mimeRequired === true)
|
|
219
|
+
regex = `${mimeRegex}${regex}`;
|
|
220
|
+
else if (opts.allowMime === true)
|
|
221
|
+
regex = `${mimeRegex}?${regex}`;
|
|
222
|
+
if (opts.paddingRequired === false)
|
|
223
|
+
regex = '(?:[A-Za-z0-9+\\/]{4})*(?:[A-Za-z0-9+\\/]{2}(==)?|[A-Za-z0-9+\\/]{3}=?)?';
|
|
224
|
+
return new RegExp('^' + regex + '$', 'gi').test(value);
|
|
225
|
+
}
|
|
226
|
+
exports.isBase64 = isBase64;
|
|
227
|
+
/**
|
|
228
|
+
* Returns if value is a valid email
|
|
229
|
+
*
|
|
230
|
+
* @param {*} value
|
|
231
|
+
* @returns
|
|
232
|
+
*/
|
|
233
|
+
function isEmail(value) {
|
|
234
|
+
return isString(value) && constants_1.REGEX.email.test(value);
|
|
235
|
+
}
|
|
236
|
+
exports.isEmail = isEmail;
|
|
237
|
+
/**
|
|
238
|
+
* Returns true if array contains value
|
|
239
|
+
*
|
|
240
|
+
* @param {*} value
|
|
241
|
+
*/
|
|
242
|
+
function contains(arr, value) {
|
|
243
|
+
return Array.isArray(arr) && arr.indexOf(value) !== -1;
|
|
244
|
+
}
|
|
245
|
+
exports.contains = contains;
|
|
246
|
+
/**
|
|
247
|
+
* Returns true if array contains value
|
|
248
|
+
*
|
|
249
|
+
* @param {*} value
|
|
250
|
+
*/
|
|
251
|
+
function containsArrayValue(arr, value) {
|
|
252
|
+
if (!Array.isArray(value))
|
|
253
|
+
return contains(arr, value);
|
|
254
|
+
return value.some(v => contains(arr, v));
|
|
255
|
+
}
|
|
256
|
+
exports.containsArrayValue = containsArrayValue;
|
|
257
|
+
/**
|
|
258
|
+
* Returns true if empty object or array
|
|
259
|
+
*
|
|
260
|
+
* @param {*} item
|
|
261
|
+
*/
|
|
262
|
+
function isEmpty(item) {
|
|
263
|
+
if (Array.isArray(item))
|
|
264
|
+
return !item.length;
|
|
265
|
+
return !hasKeys(item);
|
|
266
|
+
}
|
|
267
|
+
exports.isEmpty = isEmpty;
|
|
268
|
+
/**
|
|
269
|
+
* Returns true if obj is not empty
|
|
270
|
+
*
|
|
271
|
+
* @param {*} value
|
|
272
|
+
*/
|
|
273
|
+
function hasKeys(obj) {
|
|
274
|
+
return !!(obj && Object.keys(obj).length);
|
|
275
|
+
}
|
|
276
|
+
exports.hasKeys = hasKeys;
|
|
277
|
+
/**
|
|
278
|
+
*
|
|
279
|
+
* @param {*} key
|
|
280
|
+
* @param {*} arrays
|
|
281
|
+
*/
|
|
282
|
+
function mergeArraysByKey(key, arrays) {
|
|
283
|
+
let flat = arrays.reduce((acc, it) => [...acc, ...it], []);
|
|
284
|
+
return flat.reduce((acc, curr) => {
|
|
285
|
+
let existing = acc.find((elem) => isEqual(getAttr(elem, key), getAttr(curr, key)));
|
|
286
|
+
if (existing)
|
|
287
|
+
Object.assign(existing, curr);
|
|
288
|
+
else
|
|
289
|
+
acc.push(curr);
|
|
290
|
+
return acc;
|
|
291
|
+
}, []);
|
|
292
|
+
}
|
|
293
|
+
exports.mergeArraysByKey = mergeArraysByKey;
|
|
294
|
+
/**
|
|
295
|
+
*
|
|
296
|
+
* @param data
|
|
297
|
+
* @param obj
|
|
298
|
+
*/
|
|
299
|
+
function findDeep(data, attr, obj) {
|
|
300
|
+
return data.find((e) => {
|
|
301
|
+
for (let k in obj) {
|
|
302
|
+
if (e[k] !== obj[k])
|
|
303
|
+
return (e[attr]) ? findDeep(e[attr], attr, obj) : false;
|
|
304
|
+
}
|
|
305
|
+
return true;
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
exports.findDeep = findDeep;
|
|
309
|
+
/**
|
|
310
|
+
* Percentage Difference between two numbers
|
|
311
|
+
*
|
|
312
|
+
* @param {int} base First and original number
|
|
313
|
+
* @param {int} peak Second new number to differentiate
|
|
314
|
+
* @param {boolean} round Round return value to nearest whole numer?
|
|
315
|
+
* @return {int} Percentage difference between lowest and highest number
|
|
316
|
+
*/
|
|
317
|
+
function percentDiff(base, peak, round = false) {
|
|
318
|
+
const diff = (peak - base) / base * 100;
|
|
319
|
+
return round ? Math.round(diff) : diff;
|
|
320
|
+
}
|
|
321
|
+
exports.percentDiff = percentDiff;
|
|
322
|
+
;
|
|
323
|
+
/**
|
|
324
|
+
*
|
|
325
|
+
* @param {*} obj
|
|
326
|
+
*/
|
|
327
|
+
function dottedKeys(obj) {
|
|
328
|
+
if (!isObject(obj) || Array.isArray(obj))
|
|
329
|
+
return [];
|
|
330
|
+
let keys = Object.keys(obj);
|
|
331
|
+
//let key = keys.reduce((acc, v) => acc.concat(obj[v]), '');
|
|
332
|
+
keys.forEach((key, index) => {
|
|
333
|
+
let subKeys = dottedKeys(obj[key]);
|
|
334
|
+
if (Array.isArray(subKeys)) {
|
|
335
|
+
subKeys = subKeys.map(subKey => subKey = `${key}.${subKey}`);
|
|
336
|
+
keys.splice(index, 1, ...subKeys);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
return keys;
|
|
340
|
+
}
|
|
341
|
+
exports.dottedKeys = dottedKeys;
|
|
342
|
+
/**
|
|
343
|
+
*
|
|
344
|
+
* @param {*} obj
|
|
345
|
+
*/
|
|
346
|
+
function dotObj(obj) {
|
|
347
|
+
let dotted = {};
|
|
348
|
+
let keys = dottedKeys(obj).reduce((acc, value) => acc.concat(value), []);
|
|
349
|
+
keys.forEach(key => {
|
|
350
|
+
dotted[key.replace(/\'/g, '')] = key.split('.').reduce((o, i) => {
|
|
351
|
+
return o[i] || null;
|
|
352
|
+
}, obj);
|
|
353
|
+
});
|
|
354
|
+
return dotted;
|
|
355
|
+
}
|
|
356
|
+
exports.dotObj = dotObj;
|
|
357
|
+
/**
|
|
358
|
+
* json string parsed to object with regex values management
|
|
359
|
+
*
|
|
360
|
+
* @param {*} objStr
|
|
361
|
+
*/
|
|
362
|
+
function strToJson(str) {
|
|
363
|
+
return JSON.parse(str, (k, v) => parseTypedString(v));
|
|
364
|
+
}
|
|
365
|
+
exports.strToJson = strToJson;
|
|
366
|
+
/**
|
|
367
|
+
* json object parsed to string with regex values management
|
|
368
|
+
*
|
|
369
|
+
* @param {*} obj
|
|
370
|
+
*/
|
|
371
|
+
function jsonToStr(obj) {
|
|
372
|
+
return JSON.stringify(obj, (k, v) => v instanceof RegExp ? `__REXP__${v.toString()}` : v);
|
|
373
|
+
}
|
|
374
|
+
exports.jsonToStr = jsonToStr;
|
|
375
|
+
/**
|
|
376
|
+
* Capitalize first char of string
|
|
377
|
+
* @param text
|
|
378
|
+
*/
|
|
379
|
+
function capitalize(text) {
|
|
380
|
+
if (!text)
|
|
381
|
+
return '';
|
|
382
|
+
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
383
|
+
}
|
|
384
|
+
exports.capitalize = capitalize;
|
|
385
|
+
/**
|
|
386
|
+
* Parse string value type coded
|
|
387
|
+
*/
|
|
388
|
+
function parseTypedString(value) {
|
|
389
|
+
if (!isString(value))
|
|
390
|
+
return value;
|
|
391
|
+
let match = value.match(new RegExp('^__REXP__/(.*?)/([gimy]*)$'));
|
|
392
|
+
if (match)
|
|
393
|
+
return new RegExp(match[1]);
|
|
394
|
+
match = value.match(new RegExp('^__UNDEFINED__([gimy]*)$'));
|
|
395
|
+
if (match)
|
|
396
|
+
return undefined;
|
|
397
|
+
match = value.match(new RegExp('^__OID__/(.*?)/([gimy]*)$'));
|
|
398
|
+
if (match)
|
|
399
|
+
return (0, mongo_utils_1.toObjectId)(match[1]);
|
|
400
|
+
match = value.match(new RegExp('^__PERIOD__/(.*?)/([gimy]*)$'));
|
|
401
|
+
if (match) {
|
|
402
|
+
let period = JSON.parse(match[1]);
|
|
403
|
+
return toFilterDatePeriod(period[0], period[1]);
|
|
404
|
+
}
|
|
405
|
+
match = value.match(new RegExp('^__DATE__/(.*?)/([gimy]*)$'));
|
|
406
|
+
return match ? toDate(match[1]) : value;
|
|
407
|
+
}
|
|
408
|
+
exports.parseTypedString = parseTypedString;
|
|
409
|
+
/**
|
|
410
|
+
*
|
|
411
|
+
* @param {*} period
|
|
412
|
+
* @param {*} year
|
|
413
|
+
*/
|
|
414
|
+
function toFilterDatePeriod(period, year) {
|
|
415
|
+
let values = getDatePeriod(period, year);
|
|
416
|
+
return values ? { $gte: values[0], $lt: values[1] } : {};
|
|
417
|
+
}
|
|
418
|
+
exports.toFilterDatePeriod = toFilterDatePeriod;
|
|
419
|
+
/**
|
|
420
|
+
* Returns if string is valid date
|
|
421
|
+
*
|
|
422
|
+
* @param {*} value
|
|
423
|
+
*/
|
|
424
|
+
function isValidDateStr(value, format = 'YYYY-MM-DD') {
|
|
425
|
+
const date = toMoment(value);
|
|
426
|
+
return date.isValid() && value === date.format('YYYY-MM-DD');
|
|
427
|
+
}
|
|
428
|
+
exports.isValidDateStr = isValidDateStr;
|
|
429
|
+
/**
|
|
430
|
+
*
|
|
431
|
+
* @param {*} value
|
|
432
|
+
*/
|
|
433
|
+
function toDate(value, format = 'YYYY-MM-DD') {
|
|
434
|
+
if (!value)
|
|
435
|
+
return new Date();
|
|
436
|
+
if (Array.isArray(value))
|
|
437
|
+
return value.map(v => toDate(v, format));
|
|
438
|
+
return (value instanceof Date) ? value : toMoment(value, format, true).toDate();
|
|
439
|
+
}
|
|
440
|
+
exports.toDate = toDate;
|
|
441
|
+
/**
|
|
442
|
+
*
|
|
443
|
+
* @param {*} value
|
|
444
|
+
* @param {*} format
|
|
445
|
+
*/
|
|
446
|
+
function toMoment(value, format, utc = false) {
|
|
447
|
+
if (utc)
|
|
448
|
+
return moment_1.default.utc(value, format);
|
|
449
|
+
return (0, moment_1.default)(value, format);
|
|
450
|
+
}
|
|
451
|
+
exports.toMoment = toMoment;
|
|
452
|
+
/**
|
|
453
|
+
*
|
|
454
|
+
* @param {*} value
|
|
455
|
+
* @param {*} format
|
|
456
|
+
*/
|
|
457
|
+
function dateFormat(value, format) {
|
|
458
|
+
return toMoment(value).format(format);
|
|
459
|
+
}
|
|
460
|
+
exports.dateFormat = dateFormat;
|
|
461
|
+
/**
|
|
462
|
+
*
|
|
463
|
+
* @param {*} d1
|
|
464
|
+
* @param {*} d2
|
|
465
|
+
* @param {*} period
|
|
466
|
+
*/
|
|
467
|
+
function getDateDiff(d1, d2, period = 'days') {
|
|
468
|
+
return toMoment(d2).diff(d1, period);
|
|
469
|
+
}
|
|
470
|
+
exports.getDateDiff = getDateDiff;
|
|
471
|
+
/**
|
|
472
|
+
*
|
|
473
|
+
* @param {*} date
|
|
474
|
+
* @param {*} utc
|
|
475
|
+
*/
|
|
476
|
+
function getDateValues(date, utc = true) {
|
|
477
|
+
if (!date)
|
|
478
|
+
return {};
|
|
479
|
+
date = toMoment(date, undefined, utc);
|
|
480
|
+
return { day: date.date(), month: date.month(), year: date.year() };
|
|
481
|
+
}
|
|
482
|
+
exports.getDateValues = getDateValues;
|
|
483
|
+
/**
|
|
484
|
+
*
|
|
485
|
+
* @param {*} date
|
|
486
|
+
* @param {*} utc
|
|
487
|
+
*/
|
|
488
|
+
function getTimeValues(date, utc = true) {
|
|
489
|
+
if (!date)
|
|
490
|
+
return {};
|
|
491
|
+
date = toMoment(date, undefined, utc);
|
|
492
|
+
return { hour: date.hour(), minute: date.minute(), seconds: date.seconds() };
|
|
493
|
+
}
|
|
494
|
+
exports.getTimeValues = getTimeValues;
|
|
495
|
+
/**
|
|
496
|
+
*
|
|
497
|
+
* @param {*} period
|
|
498
|
+
* @param {*} year
|
|
499
|
+
* @param {*} momentValue
|
|
500
|
+
*/
|
|
501
|
+
function getDatePeriod(period, year, momentValue = false) {
|
|
502
|
+
if (!year)
|
|
503
|
+
year = (0, moment_1.default)().year();
|
|
504
|
+
let values = [], modq;
|
|
505
|
+
switch (period) {
|
|
506
|
+
case enums_1.DatePeriod.CURR_WEEK:
|
|
507
|
+
values = [moment_1.default.utc().startOf('isoWeek'), moment_1.default.utc().endOf('isoWeek')];
|
|
508
|
+
break;
|
|
509
|
+
case enums_1.DatePeriod.LAST_WEEK:
|
|
510
|
+
values = [moment_1.default.utc().subtract(1, 'week').startOf('isoWeek'), moment_1.default.utc().subtract(1, 'week').endOf('isoWeek')];
|
|
511
|
+
break;
|
|
512
|
+
case enums_1.DatePeriod.CURR_MONTH:
|
|
513
|
+
values = [moment_1.default.utc().startOf('month'), moment_1.default.utc().endOf('month')];
|
|
514
|
+
break;
|
|
515
|
+
case enums_1.DatePeriod.LAST_MONTH:
|
|
516
|
+
values = [moment_1.default.utc().subtract(1, 'month').startOf('month'), moment_1.default.utc().subtract(1, 'month').endOf('month')];
|
|
517
|
+
break;
|
|
518
|
+
case enums_1.DatePeriod.CURR_QUARTER:
|
|
519
|
+
values = [moment_1.default.utc().startOf('quarter'), moment_1.default.utc().endOf('quarter')];
|
|
520
|
+
break;
|
|
521
|
+
case enums_1.DatePeriod.LAST_QUARTER:
|
|
522
|
+
values = [moment_1.default.utc().subtract(1, 'quarter').startOf('quarter'), moment_1.default.utc().subtract(1, 'quarter').endOf('quarter')];
|
|
523
|
+
break;
|
|
524
|
+
case enums_1.DatePeriod.QUARTER_1:
|
|
525
|
+
values = [moment_1.default.utc().year(year).quarter(1).startOf('quarter'), moment_1.default.utc().year(year).quarter(1).endOf('quarter')];
|
|
526
|
+
break;
|
|
527
|
+
case enums_1.DatePeriod.QUARTER_2:
|
|
528
|
+
values = [moment_1.default.utc().year(year).quarter(2).startOf('quarter'), moment_1.default.utc().year(year).quarter(2).endOf('quarter')];
|
|
529
|
+
break;
|
|
530
|
+
case enums_1.DatePeriod.QUARTER_3:
|
|
531
|
+
values = [moment_1.default.utc().year(year).quarter(3).startOf('quarter'), moment_1.default.utc().year(year).quarter(3).endOf('quarter')];
|
|
532
|
+
break;
|
|
533
|
+
case enums_1.DatePeriod.QUARTER_4:
|
|
534
|
+
values = [moment_1.default.utc().year(year).quarter(4).startOf('quarter'), moment_1.default.utc().year(year).quarter(4).endOf('quarter')];
|
|
535
|
+
break;
|
|
536
|
+
case enums_1.DatePeriod.CURR_SEMESTER:
|
|
537
|
+
modq = (0, moment_1.default)().quarter() % 2;
|
|
538
|
+
values = [moment_1.default.utc().subtract(1 - modq, 'quarter').startOf('quarter'), moment_1.default.utc().add(modq, 'quarter').endOf('quarter')];
|
|
539
|
+
break;
|
|
540
|
+
case enums_1.DatePeriod.LAST_SEMESTER:
|
|
541
|
+
modq = 3 - ((0, moment_1.default)().quarter() % 2); // 4-(moment().quarter()%2+1)
|
|
542
|
+
values = [moment_1.default.utc().subtract(modq, 'quarter').startOf('quarter'), moment_1.default.utc().subtract(modq + 1, 'quarter').endOf('quarter')];
|
|
543
|
+
break;
|
|
544
|
+
case enums_1.DatePeriod.SEMESTER_1:
|
|
545
|
+
values = [moment_1.default.utc().year(year).startOf('year'), moment_1.default.utc().year(year).quarter(2).endOf('quarter')];
|
|
546
|
+
break;
|
|
547
|
+
case enums_1.DatePeriod.SEMESTER_2:
|
|
548
|
+
values = [moment_1.default.utc().year(year).quarter(3).startOf('quarter'), moment_1.default.utc().year(year).endOf('year')];
|
|
549
|
+
break;
|
|
550
|
+
case enums_1.DatePeriod.CURR_YEAR:
|
|
551
|
+
values = [moment_1.default.utc().startOf('year'), moment_1.default.utc().endOf('year')];
|
|
552
|
+
break;
|
|
553
|
+
case enums_1.DatePeriod.LAST_YEAR:
|
|
554
|
+
values = [moment_1.default.utc().subtract(1, 'year').startOf('year'), moment_1.default.utc().subtract(1, 'year').endOf('year')];
|
|
555
|
+
break;
|
|
556
|
+
case enums_1.DatePeriod.YEAR:
|
|
557
|
+
values = [moment_1.default.utc().year(year).startOf('year'), moment_1.default.utc().year(year).endOf('year')];
|
|
558
|
+
break;
|
|
559
|
+
default:
|
|
560
|
+
break;
|
|
561
|
+
}
|
|
562
|
+
if (momentValue)
|
|
563
|
+
return values;
|
|
564
|
+
return [values[0].toDate(), values[1].toDate()];
|
|
565
|
+
}
|
|
566
|
+
exports.getDatePeriod = getDatePeriod;
|
|
567
|
+
/**
|
|
568
|
+
*
|
|
569
|
+
* @param {*} value value to be checked
|
|
570
|
+
*/
|
|
571
|
+
function uuid(value) {
|
|
572
|
+
return value && (0, uuid_2.validate)(value) ? value : (0, uuid_1.v4)();
|
|
573
|
+
}
|
|
574
|
+
exports.uuid = uuid;
|
|
575
|
+
/**
|
|
576
|
+
*
|
|
577
|
+
* @param {*} obj
|
|
578
|
+
*/
|
|
579
|
+
function logClassCtx(obj, method) {
|
|
580
|
+
var _a;
|
|
581
|
+
if (!((_a = obj === null || obj === void 0 ? void 0 : obj.constructor) === null || _a === void 0 ? void 0 : _a.name))
|
|
582
|
+
return {};
|
|
583
|
+
return { context: obj.constructor.name, method };
|
|
584
|
+
}
|
|
585
|
+
exports.logClassCtx = logClassCtx;
|
|
586
|
+
/**
|
|
587
|
+
*
|
|
588
|
+
* @param obj
|
|
589
|
+
* @param logger
|
|
590
|
+
*/
|
|
591
|
+
function logMemory(obj, logger = constants_1.APP.logger) {
|
|
592
|
+
let used = process.memoryUsage();
|
|
593
|
+
let memStr = [];
|
|
594
|
+
for (let key in used)
|
|
595
|
+
memStr.push(`${key}: ${Math.round(used[key] / 1024 / 1024 * 100) / 100} MB`);
|
|
596
|
+
logger.debug(`Memory usage %s`, memStr.join(', '), logClassCtx(obj));
|
|
597
|
+
}
|
|
598
|
+
exports.logMemory = logMemory;
|
|
599
|
+
/**
|
|
600
|
+
*
|
|
601
|
+
* @param logger
|
|
602
|
+
*/
|
|
603
|
+
function forceGC(logger = constants_1.APP.logger) {
|
|
604
|
+
if (global.gc)
|
|
605
|
+
global.gc();
|
|
606
|
+
else
|
|
607
|
+
logger.warn('No GC hook! Start your program as `node --expose-gc app.js`.');
|
|
608
|
+
}
|
|
609
|
+
exports.forceGC = forceGC;
|
|
610
|
+
/**
|
|
611
|
+
*
|
|
612
|
+
* @param {*} ctx
|
|
613
|
+
*/
|
|
614
|
+
function getCtxUser(ctx) {
|
|
615
|
+
return (ctx && ctx.user) ? ctx.user : null;
|
|
616
|
+
}
|
|
617
|
+
exports.getCtxUser = getCtxUser;
|
|
618
|
+
/**
|
|
619
|
+
*
|
|
620
|
+
*/
|
|
621
|
+
function flattenArray(arr, parseMethod) {
|
|
622
|
+
return arr.reduce((flat, toFlatten) => {
|
|
623
|
+
if (Array.isArray(toFlatten))
|
|
624
|
+
return flat.concat(flattenArray(toFlatten, parseMethod));
|
|
625
|
+
return flat.concat(parseMethod ? parseMethod(toFlatten) : toFlatten);
|
|
626
|
+
}, []);
|
|
627
|
+
}
|
|
628
|
+
exports.flattenArray = flattenArray;
|
|
629
|
+
/**
|
|
630
|
+
*
|
|
631
|
+
* @param {*} obj
|
|
632
|
+
* @param {*} path
|
|
633
|
+
* @param {*} cloneKey
|
|
634
|
+
*/
|
|
635
|
+
function deleteKey(obj, path, cloneKey) {
|
|
636
|
+
const _obj = cloneKey ? clone(obj) : obj;
|
|
637
|
+
const keys = path.split('.');
|
|
638
|
+
keys.reduce((acc, key, index) => {
|
|
639
|
+
if (index === keys.length - 1) {
|
|
640
|
+
delete acc[key];
|
|
641
|
+
return true;
|
|
642
|
+
}
|
|
643
|
+
return acc[key];
|
|
644
|
+
}, _obj);
|
|
645
|
+
return _obj;
|
|
646
|
+
}
|
|
647
|
+
exports.deleteKey = deleteKey;
|
|
648
|
+
/**
|
|
649
|
+
*
|
|
650
|
+
* @param array
|
|
651
|
+
* @param properties
|
|
652
|
+
*/
|
|
653
|
+
function sortBy(array, properties) {
|
|
654
|
+
if (properties && !Array.isArray(properties))
|
|
655
|
+
properties = [properties];
|
|
656
|
+
return array.sort((a, b) => {
|
|
657
|
+
if (!properties) {
|
|
658
|
+
if (a > b)
|
|
659
|
+
return 1;
|
|
660
|
+
if (a < b)
|
|
661
|
+
return -1;
|
|
662
|
+
}
|
|
663
|
+
for (let i = 0; i < properties.length; i++) {
|
|
664
|
+
let valueA = getAttr(a, properties[i]);
|
|
665
|
+
let valueB = getAttr(b, properties[i]);
|
|
666
|
+
if (valueA > valueB)
|
|
667
|
+
return 1;
|
|
668
|
+
else if (valueA < valueB)
|
|
669
|
+
return -1;
|
|
670
|
+
}
|
|
671
|
+
return 0;
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
exports.sortBy = sortBy;
|
|
675
|
+
/**
|
|
676
|
+
*
|
|
677
|
+
* @param {*} path
|
|
678
|
+
* @returns
|
|
679
|
+
*/
|
|
680
|
+
function readFileSync(path) {
|
|
681
|
+
if (!path || path.indexOf('/') === -1)
|
|
682
|
+
return path;
|
|
683
|
+
return fs_1.default.existsSync(path) ? fs_1.default.readFileSync(path).toString().trim() : '';
|
|
684
|
+
}
|
|
685
|
+
exports.readFileSync = readFileSync;
|
|
686
|
+
/**
|
|
687
|
+
*
|
|
688
|
+
* @param {*} arr1
|
|
689
|
+
* @param {*} arr2
|
|
690
|
+
* @returns
|
|
691
|
+
*/
|
|
692
|
+
function union(arr1, arr2) {
|
|
693
|
+
return lodash_1.default.union(arr1, arr2);
|
|
694
|
+
}
|
|
695
|
+
exports.union = union;
|
|
696
|
+
/**
|
|
697
|
+
*
|
|
698
|
+
* @param {*} arr
|
|
699
|
+
* @param {*} iteratee
|
|
700
|
+
* @returns
|
|
701
|
+
*/
|
|
702
|
+
function uniqBy(arr, iteratee) {
|
|
703
|
+
return lodash_1.default.uniqBy(arr, iteratee);
|
|
704
|
+
}
|
|
705
|
+
exports.uniqBy = uniqBy;
|
|
706
|
+
/**
|
|
707
|
+
*
|
|
708
|
+
* @param {*} obj1
|
|
709
|
+
* @param {*} obj2
|
|
710
|
+
* @returns
|
|
711
|
+
*/
|
|
712
|
+
function merge(obj1, obj2) {
|
|
713
|
+
if (!isObject(obj1) || !isObject(obj2))
|
|
714
|
+
return;
|
|
715
|
+
return lodash_1.default.merge(obj1, obj2);
|
|
716
|
+
}
|
|
717
|
+
exports.merge = merge;
|
|
718
|
+
/**
|
|
719
|
+
*
|
|
720
|
+
* @param data
|
|
721
|
+
*/
|
|
722
|
+
function clone(data) {
|
|
723
|
+
if (!data)
|
|
724
|
+
return;
|
|
725
|
+
return lodash_1.default.cloneDeep(data);
|
|
726
|
+
}
|
|
727
|
+
exports.clone = clone;
|
|
728
|
+
/**
|
|
729
|
+
*
|
|
730
|
+
* @param object
|
|
731
|
+
* @param path
|
|
732
|
+
*/
|
|
733
|
+
function getAttr(object, path) {
|
|
734
|
+
return lodash_1.default.get(object, path);
|
|
735
|
+
}
|
|
736
|
+
exports.getAttr = getAttr;
|
|
737
|
+
/**
|
|
738
|
+
*
|
|
739
|
+
* @param object
|
|
740
|
+
* @param path
|
|
741
|
+
* @param value
|
|
742
|
+
*/
|
|
743
|
+
function setAttr(object, path, value) {
|
|
744
|
+
return lodash_1.default.set(object, path, value);
|
|
745
|
+
}
|
|
746
|
+
exports.setAttr = setAttr;
|
|
747
|
+
/**
|
|
748
|
+
*
|
|
749
|
+
* @param object
|
|
750
|
+
* @param path
|
|
751
|
+
*/
|
|
752
|
+
function hasAttr(object, path) {
|
|
753
|
+
return lodash_1.default.has(object, path);
|
|
754
|
+
}
|
|
755
|
+
exports.hasAttr = hasAttr;
|
|
756
|
+
/**
|
|
757
|
+
*
|
|
758
|
+
* @param value1
|
|
759
|
+
* @param value2
|
|
760
|
+
*/
|
|
761
|
+
function isEqual(value1, value2) {
|
|
762
|
+
return lodash_1.default.isEqual(value1, value2);
|
|
763
|
+
}
|
|
764
|
+
exports.isEqual = isEqual;
|
|
765
|
+
/**
|
|
766
|
+
*
|
|
767
|
+
* @param {*} value
|
|
768
|
+
* @param {*} from
|
|
769
|
+
* @param {*} to
|
|
770
|
+
*/
|
|
771
|
+
function encodeString(value, from = 'base64', to = 'utf8') {
|
|
772
|
+
return value ? Buffer.from(value, from).toString(to) : value;
|
|
773
|
+
}
|
|
774
|
+
exports.encodeString = encodeString;
|
|
775
|
+
/**
|
|
776
|
+
* Split a string into chunks by specified size
|
|
777
|
+
* @param {String} stringToChunk The string to split
|
|
778
|
+
* @param {number} size the size of character to use to split the string
|
|
779
|
+
*/
|
|
780
|
+
function chunkString(stringToChunk, size) {
|
|
781
|
+
let result = [];
|
|
782
|
+
let chars = String(stringToChunk).split('');
|
|
783
|
+
for (let i = 0; i < (String(stringToChunk).length / size); i++)
|
|
784
|
+
result = result.concat(chars.slice(i * size, (i + 1) * size).join(''));
|
|
785
|
+
return result;
|
|
786
|
+
}
|
|
787
|
+
exports.chunkString = chunkString;
|
|
788
|
+
/**
|
|
789
|
+
* Initialize an object by a given dot notation structure
|
|
790
|
+
* eg.
|
|
791
|
+
* 'service.url' -> { service: { url: value } }
|
|
792
|
+
* @param {String} path the dot notation string representation of property
|
|
793
|
+
* @param {*} value the value to be used
|
|
794
|
+
*/
|
|
795
|
+
function initObjectFromDotNotation(path, value) {
|
|
796
|
+
return setAttr({}, path, value);
|
|
797
|
+
}
|
|
798
|
+
exports.initObjectFromDotNotation = initObjectFromDotNotation;
|
|
799
|
+
/**
|
|
800
|
+
* Initialize an object with a dot notation property name
|
|
801
|
+
* eg.
|
|
802
|
+
* 'service.url' -> { "service.url": value }
|
|
803
|
+
* @param {String} path
|
|
804
|
+
* @param {*} value
|
|
805
|
+
*/
|
|
806
|
+
function initObjectWithProperty(path, value) {
|
|
807
|
+
const obj = {};
|
|
808
|
+
obj[path] = value;
|
|
809
|
+
return obj;
|
|
810
|
+
}
|
|
811
|
+
exports.initObjectWithProperty = initObjectWithProperty;
|
|
812
|
+
/**
|
|
813
|
+
* Resize phrase Buffer by given size
|
|
814
|
+
* @param { Buffer } phrase
|
|
815
|
+
* @param { number } size
|
|
816
|
+
* @returns { Buffer } Given size buffer based on given phrase buffer
|
|
817
|
+
*/
|
|
818
|
+
function resizeBuffer(buffer, size) {
|
|
819
|
+
const resizedBuffer = Buffer.allocUnsafe(size);
|
|
820
|
+
buffer.copy(resizedBuffer);
|
|
821
|
+
return resizedBuffer;
|
|
822
|
+
}
|
|
823
|
+
exports.resizeBuffer = resizeBuffer;
|
|
824
|
+
/**
|
|
825
|
+
* Generate a random Hex string (using sha256 HASH Algorithm)
|
|
826
|
+
* @returns { Buffer } Buffer representation of hash
|
|
827
|
+
*/
|
|
828
|
+
function generateRandomHex() {
|
|
829
|
+
return crypto_1.default.createHash("sha256").update((0, uuid_1.v4)()).digest();
|
|
830
|
+
}
|
|
831
|
+
exports.generateRandomHex = generateRandomHex;
|
|
832
|
+
/**
|
|
833
|
+
* Generate random buffer of specified size
|
|
834
|
+
* @param { number } bitSize bit size of the buffer
|
|
835
|
+
* @returns { Buffer } Given size random Buffer
|
|
836
|
+
*/
|
|
837
|
+
function generateRandomBuffer(bitSize) {
|
|
838
|
+
const size = bitSize / 8;
|
|
839
|
+
const phrase = generateRandomHex();
|
|
840
|
+
return resizeBuffer(phrase, size);
|
|
841
|
+
}
|
|
842
|
+
exports.generateRandomBuffer = generateRandomBuffer;
|
|
843
|
+
/**
|
|
844
|
+
* Use object to filter another object
|
|
845
|
+
* @param {*} obj
|
|
846
|
+
* @param {*} filterObj
|
|
847
|
+
*/
|
|
848
|
+
function filterObject(obj, filterObj) {
|
|
849
|
+
if (!isObject(filterObj) || !isObject(obj))
|
|
850
|
+
return obj;
|
|
851
|
+
filterObj = dotObj(filterObj);
|
|
852
|
+
for (let k in filterObj) {
|
|
853
|
+
let value = getAttr(obj, k);
|
|
854
|
+
if (lodash_1.default.isObject(value))
|
|
855
|
+
value = value.toString();
|
|
856
|
+
if (value !== filterObj[k])
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
return obj;
|
|
860
|
+
}
|
|
861
|
+
exports.filterObject = filterObject;
|
|
862
|
+
/**
|
|
863
|
+
*
|
|
864
|
+
* @param {*} request
|
|
865
|
+
*/
|
|
866
|
+
function parseUserAgent(req) {
|
|
867
|
+
const ua = new ua_parser_js_1.default(getAttr(req, 'headers.user-agent'));
|
|
868
|
+
return ua.getResult();
|
|
869
|
+
}
|
|
870
|
+
exports.parseUserAgent = parseUserAgent;
|
|
871
|
+
/**
|
|
872
|
+
*
|
|
873
|
+
* @param {*} rule
|
|
874
|
+
* @param {*} options
|
|
875
|
+
* @param {*} method
|
|
876
|
+
*/
|
|
877
|
+
function scheduleJob(rule, { recurrence, startTime, endTime }, method = () => console.log('Scheduled job', new Date())) {
|
|
878
|
+
if (!rule)
|
|
879
|
+
return null;
|
|
880
|
+
if (recurrence && isObject(rule) && !isDate(rule)) {
|
|
881
|
+
console.log('recurrence job');
|
|
882
|
+
rule = Object.assign(new node_schedule_1.default.RecurrenceRule(), rule);
|
|
883
|
+
}
|
|
884
|
+
// set up job start/end time
|
|
885
|
+
if (startTime || endTime) {
|
|
886
|
+
rule = { rule };
|
|
887
|
+
if (startTime)
|
|
888
|
+
rule.start = (0, moment_1.default)(startTime, 'HH:mm').toDate();
|
|
889
|
+
if (endTime)
|
|
890
|
+
rule.end = (0, moment_1.default)(endTime, 'HH:mm').toDate();
|
|
891
|
+
}
|
|
892
|
+
return node_schedule_1.default.scheduleJob(rule, method);
|
|
893
|
+
}
|
|
894
|
+
exports.scheduleJob = scheduleJob;
|
|
895
|
+
/**
|
|
896
|
+
* Schedule multiple jobs.
|
|
897
|
+
* Input rules have following format:
|
|
898
|
+
* { rule (string/obj), recurrence (bool), method (function) }
|
|
899
|
+
*
|
|
900
|
+
* Example:
|
|
901
|
+
* let jobs = scheduleJobs([
|
|
902
|
+
* { rule: { minute: 56 }, options: { recurrence: true }, method: () => { console.log('JOB AT MIN 56!') } },
|
|
903
|
+
* { rule: '* * * * *', options: { recurrence: true }, method: () => { console.log('JOB EVERY MINUTE!') } },
|
|
904
|
+
* { rule: '* * * * *', options: { recurrence: true, startTime: '10:55' }, method: () => { console.log('JOB EVERY MINUTE after 10:53!') } }
|
|
905
|
+
* ]);
|
|
906
|
+
*
|
|
907
|
+
* @param {*} rules array of rules objects
|
|
908
|
+
*/
|
|
909
|
+
function scheduleJobs(rules = []) {
|
|
910
|
+
let jobs = [];
|
|
911
|
+
rules.forEach(({ rule, options, method }) => {
|
|
912
|
+
const job = scheduleJob(rule, options, method);
|
|
913
|
+
if (job)
|
|
914
|
+
jobs.push(job);
|
|
915
|
+
});
|
|
916
|
+
return jobs;
|
|
917
|
+
}
|
|
918
|
+
exports.scheduleJobs = scheduleJobs;
|
|
919
|
+
/**
|
|
920
|
+
* Test password security / complexity criteria
|
|
921
|
+
*
|
|
922
|
+
* @param {*} pwd
|
|
923
|
+
* @returns
|
|
924
|
+
*/
|
|
925
|
+
function checkPasswordComplexity(pwd) {
|
|
926
|
+
return constants_1.REGEX.pwd.test(pwd);
|
|
927
|
+
}
|
|
928
|
+
exports.checkPasswordComplexity = checkPasswordComplexity;
|
|
929
|
+
/**
|
|
930
|
+
* Test password security / complexity criteria
|
|
931
|
+
*
|
|
932
|
+
* @param {*} pwd
|
|
933
|
+
* @returns
|
|
934
|
+
*/
|
|
935
|
+
function checkCommonPassword(commonPwds, pwd) {
|
|
936
|
+
return !commonPwds.some(p => p === pwd);
|
|
937
|
+
}
|
|
938
|
+
exports.checkCommonPassword = checkCommonPassword;
|
|
939
|
+
/**
|
|
940
|
+
* Zip and save a folder
|
|
941
|
+
*
|
|
942
|
+
* @param {*} path
|
|
943
|
+
* @param {*} name
|
|
944
|
+
* @param {*} callback
|
|
945
|
+
*/
|
|
946
|
+
function zipFolder(path, name) {
|
|
947
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
948
|
+
const stream = zipFolderStream(path, name);
|
|
949
|
+
return new Promise((resolve, reject) => {
|
|
950
|
+
stream.pipe(fs_1.default.createWriteStream(`${path}/${name}.zip`))
|
|
951
|
+
.on('finish', resolve);
|
|
952
|
+
});
|
|
953
|
+
});
|
|
954
|
+
}
|
|
955
|
+
exports.zipFolder = zipFolder;
|
|
956
|
+
/**
|
|
957
|
+
*
|
|
958
|
+
* @param {*} path
|
|
959
|
+
* @param {*} name
|
|
960
|
+
* @param {*} stream
|
|
961
|
+
* @param {*} callback
|
|
962
|
+
*/
|
|
963
|
+
function zipFolderStream(path, name) {
|
|
964
|
+
// https://cheatcode.co/tutorials/how-to-create-and-download-a-zip-file-with-node-js-and-javascript#creating-a-zip-archive-with-jszip
|
|
965
|
+
const zip = addDirectoryToZip(path, name, new jszip_1.default());
|
|
966
|
+
return zip.generateNodeStream({ type: 'nodebuffer', streamFiles: true });
|
|
967
|
+
}
|
|
968
|
+
exports.zipFolderStream = zipFolderStream;
|
|
969
|
+
/**
|
|
970
|
+
* Add files to zip object
|
|
971
|
+
*
|
|
972
|
+
* @param {*} dir
|
|
973
|
+
* @param {*} zip
|
|
974
|
+
* @param {*} callback
|
|
975
|
+
*/
|
|
976
|
+
function addDirectoryToZip(path, dir, zip) {
|
|
977
|
+
if (!dir || !zip)
|
|
978
|
+
return zip; //callback();
|
|
979
|
+
const dirPath = `${path}/${dir}`;
|
|
980
|
+
const content = fs_1.default.readdirSync(dirPath, { withFileTypes: true });
|
|
981
|
+
for (let { name } of content) {
|
|
982
|
+
const file = `${dirPath}/${name}`;
|
|
983
|
+
if (fs_1.default.statSync(file).isFile()) {
|
|
984
|
+
const data = fs_1.default.readFileSync(file, { encoding: 'utf-8' });
|
|
985
|
+
zip.file(`${dir}/${name}`, data);
|
|
986
|
+
}
|
|
987
|
+
else if (fs_1.default.statSync(file).isDirectory())
|
|
988
|
+
addDirectoryToZip(path, `${dir}/${name}`, zip);
|
|
989
|
+
}
|
|
990
|
+
return zip;
|
|
991
|
+
}
|
|
992
|
+
exports.addDirectoryToZip = addDirectoryToZip;
|
|
993
|
+
/**
|
|
994
|
+
* Push in array and return value
|
|
995
|
+
*
|
|
996
|
+
* @param {*} arr
|
|
997
|
+
* @param {*} value
|
|
998
|
+
* @returns
|
|
999
|
+
*/
|
|
1000
|
+
function arrayPushRef(arr = [], value) {
|
|
1001
|
+
if (!value || !Array.isArray(arr))
|
|
1002
|
+
return;
|
|
1003
|
+
arr.push(value);
|
|
1004
|
+
return value;
|
|
1005
|
+
}
|
|
1006
|
+
exports.arrayPushRef = arrayPushRef;
|
|
1007
|
+
/**
|
|
1008
|
+
*
|
|
1009
|
+
* @param {*} arr
|
|
1010
|
+
* @param {*} item
|
|
1011
|
+
* @param {*} attr
|
|
1012
|
+
* @returns
|
|
1013
|
+
*/
|
|
1014
|
+
function arrayPushUniq(arr = [], item, attr) {
|
|
1015
|
+
if (!item || !Array.isArray(arr) || !attr)
|
|
1016
|
+
return;
|
|
1017
|
+
if (!arr.some(ai => getAttr(ai, attr) === getAttr(item, attr)))
|
|
1018
|
+
arr.push(item);
|
|
1019
|
+
}
|
|
1020
|
+
exports.arrayPushUniq = arrayPushUniq;
|
|
1021
|
+
/**
|
|
1022
|
+
*
|
|
1023
|
+
* @param {*} arr
|
|
1024
|
+
* @param {*} item
|
|
1025
|
+
* @param {*} attr
|
|
1026
|
+
* @returns
|
|
1027
|
+
*/
|
|
1028
|
+
function arrayToggle(arr = [], item, attr) {
|
|
1029
|
+
if (!item || !Array.isArray(arr) || !attr)
|
|
1030
|
+
return;
|
|
1031
|
+
const idx = arr.findIndex(ai => getAttr(ai, attr) === getAttr(item, attr));
|
|
1032
|
+
if (idx !== -1)
|
|
1033
|
+
arr.splice(idx, 1);
|
|
1034
|
+
else
|
|
1035
|
+
arr.push(item);
|
|
1036
|
+
}
|
|
1037
|
+
exports.arrayToggle = arrayToggle;
|
|
1038
|
+
/**
|
|
1039
|
+
*
|
|
1040
|
+
* @param {*} arrays
|
|
1041
|
+
* @returns
|
|
1042
|
+
*/
|
|
1043
|
+
function intersectArrays(arrays = []) {
|
|
1044
|
+
return lodash_1.default.intersection(...arrays);
|
|
1045
|
+
}
|
|
1046
|
+
exports.intersectArrays = intersectArrays;
|
|
1047
|
+
/**
|
|
1048
|
+
*
|
|
1049
|
+
* @param {*} arrays
|
|
1050
|
+
* @returns
|
|
1051
|
+
*/
|
|
1052
|
+
function intersectArraysBy(arr = [], iteratee) {
|
|
1053
|
+
return lodash_1.default.intersectionWith(...arr, iteratee);
|
|
1054
|
+
}
|
|
1055
|
+
exports.intersectArraysBy = intersectArraysBy;
|
|
1056
|
+
/**
|
|
1057
|
+
* Get last child in a tree like structure array
|
|
1058
|
+
* { _id: '', children: [{ _id: '', parent: '', children: [...] }]}
|
|
1059
|
+
*
|
|
1060
|
+
* @param {*} item
|
|
1061
|
+
* @param {*} attr
|
|
1062
|
+
* @param {*} arr
|
|
1063
|
+
* @returns
|
|
1064
|
+
*/
|
|
1065
|
+
function getLastChild(item, attr = 'id', arr = []) {
|
|
1066
|
+
if (!item)
|
|
1067
|
+
return;
|
|
1068
|
+
const child = arr.find(ai => ai.parent === item[attr]);
|
|
1069
|
+
return child ? getLastChild(child, attr, arr) : item;
|
|
1070
|
+
}
|
|
1071
|
+
exports.getLastChild = getLastChild;
|
|
1072
|
+
/**
|
|
1073
|
+
* * Get an array with last childern in a tree like structure array
|
|
1074
|
+
* { _id: '', children: [{ _id: '', parent: '', children: [...] }]}
|
|
1075
|
+
*
|
|
1076
|
+
* @param {*} item
|
|
1077
|
+
* @param {*} attr
|
|
1078
|
+
* @param {*} arr
|
|
1079
|
+
* @returns
|
|
1080
|
+
*/
|
|
1081
|
+
function getLastChildren(items, attr = 'id', arr = []) {
|
|
1082
|
+
if (!items || !items.length)
|
|
1083
|
+
return [];
|
|
1084
|
+
const children = [];
|
|
1085
|
+
items.forEach(item => {
|
|
1086
|
+
children.push(...getLastChildren(arr.filter(ai => ai.parent === item[attr]), attr, arr));
|
|
1087
|
+
});
|
|
1088
|
+
// const child = arr.filter(ai => ai.parent === item[attr]);
|
|
1089
|
+
return children.length ? children : items;
|
|
1090
|
+
}
|
|
1091
|
+
exports.getLastChildren = getLastChildren;
|
|
1092
|
+
/**
|
|
1093
|
+
*
|
|
1094
|
+
* @param {*} str
|
|
1095
|
+
* @returns
|
|
1096
|
+
*/
|
|
1097
|
+
function validDataUrl(str) {
|
|
1098
|
+
return constants_1.REGEX.dataurl.test((str || '').trim());
|
|
1099
|
+
}
|
|
1100
|
+
exports.validDataUrl = validDataUrl;
|