@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.
Files changed (119) hide show
  1. package/README.md +1 -0
  2. package/README.md.old +45 -0
  3. package/build/app.d.ts +0 -0
  4. package/build/app.js +1 -0
  5. package/build/aws/aws-cluster-manager.d.ts +28 -0
  6. package/build/aws/aws-cluster-manager.js +105 -0
  7. package/build/aws/aws-email-manager.d.ts +24 -0
  8. package/build/aws/aws-email-manager.js +57 -0
  9. package/build/aws/aws-queue-manager.d.ts +37 -0
  10. package/build/aws/aws-queue-manager.js +100 -0
  11. package/build/aws/aws.interfaces.d.ts +39 -0
  12. package/build/aws/aws.interfaces.js +2 -0
  13. package/build/aws/index.d.ts +4 -0
  14. package/build/aws/index.js +20 -0
  15. package/build/common/base/__test__/base.model.test.d.ts +1 -0
  16. package/build/common/base/__test__/base.model.test.js +283 -0
  17. package/build/common/base/base.controller.d.ts +124 -0
  18. package/build/common/base/base.controller.js +134 -0
  19. package/build/common/base/base.interfaces.d.ts +81 -0
  20. package/build/common/base/base.interfaces.js +2 -0
  21. package/build/common/base/base.model.d.ts +384 -0
  22. package/build/common/base/base.model.js +730 -0
  23. package/build/common/base/folded.model.d.ts +41 -0
  24. package/build/common/base/folded.model.js +215 -0
  25. package/build/common/base/mongo-utils.d.ts +122 -0
  26. package/build/common/base/mongo-utils.js +242 -0
  27. package/build/common/base/mongo.types.d.ts +20 -0
  28. package/build/common/base/mongo.types.js +2 -0
  29. package/build/common/base/sql-utils.d.ts +20 -0
  30. package/build/common/base/sql-utils.js +69 -0
  31. package/build/common/constants.d.ts +27 -0
  32. package/build/common/constants.js +70 -0
  33. package/build/common/crypto/crypto.classes.d.ts +100 -0
  34. package/build/common/crypto/crypto.classes.js +146 -0
  35. package/build/common/crypto/crypto.constants.d.ts +68 -0
  36. package/build/common/crypto/crypto.constants.js +57 -0
  37. package/build/common/crypto/crypto.error.d.ts +4 -0
  38. package/build/common/crypto/crypto.error.js +10 -0
  39. package/build/common/crypto/crypto.interfaces.d.ts +46 -0
  40. package/build/common/crypto/crypto.interfaces.js +2 -0
  41. package/build/common/crypto/crypto.utils.d.ts +139 -0
  42. package/build/common/crypto/crypto.utils.js +380 -0
  43. package/build/common/crypto/index.d.ts +3 -0
  44. package/build/common/crypto/index.js +19 -0
  45. package/build/common/enums.d.ts +61 -0
  46. package/build/common/enums.js +75 -0
  47. package/build/common/errors.d.ts +13 -0
  48. package/build/common/errors.js +24 -0
  49. package/build/common/express/express.interfaces.d.ts +20 -0
  50. package/build/common/express/express.interfaces.js +2 -0
  51. package/build/common/express/express.utils.d.ts +31 -0
  52. package/build/common/express/express.utils.js +85 -0
  53. package/build/common/express/index.d.ts +2 -0
  54. package/build/common/express/index.js +18 -0
  55. package/build/common/graphql/__test__/generator.schema.test.d.ts +1 -0
  56. package/build/common/graphql/__test__/generator.schema.test.js +391 -0
  57. package/build/common/graphql/directives.d.ts +18 -0
  58. package/build/common/graphql/directives.js +56 -0
  59. package/build/common/graphql/generator copy.d.ts +41 -0
  60. package/build/common/graphql/generator copy.js +385 -0
  61. package/build/common/graphql/generator.d.ts +42 -0
  62. package/build/common/graphql/generator.js +385 -0
  63. package/build/common/graphql/index.d.ts +4 -0
  64. package/build/common/graphql/index.js +21 -0
  65. package/build/common/graphql/interfaces.d.ts +67 -0
  66. package/build/common/graphql/interfaces.js +2 -0
  67. package/build/common/graphql/loader.d.ts +22 -0
  68. package/build/common/graphql/loader.js +186 -0
  69. package/build/common/graphql/scalars/index.d.ts +10 -0
  70. package/build/common/graphql/scalars/index.js +6 -0
  71. package/build/common/graphql/scalars/resolvers.d.ts +8 -0
  72. package/build/common/graphql/scalars/resolvers.js +71 -0
  73. package/build/common/graphql/scalars/schema.d.ts +1 -0
  74. package/build/common/graphql/scalars/schema.js +12 -0
  75. package/build/common/graphql/types/index.d.ts +3 -0
  76. package/build/common/graphql/types/index.js +6 -0
  77. package/build/common/graphql/types/schema.d.ts +1 -0
  78. package/build/common/graphql/types/schema.js +98 -0
  79. package/build/common/graphql/utils.d.ts +18 -0
  80. package/build/common/graphql/utils.js +40 -0
  81. package/build/common/grid-fs/gridfs-base.model.d.ts +53 -0
  82. package/build/common/grid-fs/gridfs-base.model.js +95 -0
  83. package/build/common/grid-fs/gridfs.interfaces.d.ts +41 -0
  84. package/build/common/grid-fs/gridfs.interfaces.js +2 -0
  85. package/build/common/index.d.ts +10 -0
  86. package/build/common/index.js +32 -0
  87. package/build/common/interfaces.d.ts +26 -0
  88. package/build/common/interfaces.js +10 -0
  89. package/build/common/manager/bulk-manager.d.ts +59 -0
  90. package/build/common/manager/bulk-manager.js +103 -0
  91. package/build/common/manager/crypto-manager.d.ts +88 -0
  92. package/build/common/manager/crypto-manager.js +200 -0
  93. package/build/common/manager/index.d.ts +5 -0
  94. package/build/common/manager/index.js +21 -0
  95. package/build/common/manager/pubsub-manager.d.ts +20 -0
  96. package/build/common/manager/pubsub-manager.js +38 -0
  97. package/build/common/manager/shutdown-manager.d.ts +27 -0
  98. package/build/common/manager/shutdown-manager.js +118 -0
  99. package/build/common/manager/socket-io-cli-manager.d.ts +53 -0
  100. package/build/common/manager/socket-io-cli-manager.js +91 -0
  101. package/build/common/manager/tunnel-manager.d.ts +28 -0
  102. package/build/common/manager/tunnel-manager.js +49 -0
  103. package/build/common/models/coded-entity.controller.d.ts +5 -0
  104. package/build/common/models/coded-entity.controller.js +9 -0
  105. package/build/common/models/coded-entity.model.d.ts +25 -0
  106. package/build/common/models/coded-entity.model.js +51 -0
  107. package/build/common/models/user.model.d.ts +56 -0
  108. package/build/common/models/user.model.js +72 -0
  109. package/build/common/types.d.ts +136 -0
  110. package/build/common/types.js +16 -0
  111. package/build/common/utils.d.ts +552 -0
  112. package/build/common/utils.js +1100 -0
  113. package/build/index.d.ts +2 -0
  114. package/build/index.js +18 -0
  115. package/build/test/env.d.ts +0 -0
  116. package/build/test/env.js +5 -0
  117. package/build/test/setup.d.ts +6 -0
  118. package/build/test/setup.js +59 -0
  119. 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;