topkat-utils 1.0.60 → 1.1.2
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/CHANGELOG.md +4 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/src/array-utils.d.ts +56 -0
- package/dist/src/array-utils.js +138 -0
- package/dist/src/array-utils.js.map +1 -0
- package/dist/src/date-utils.d.ts +100 -0
- package/dist/src/date-utils.js +357 -0
- package/dist/src/date-utils.js.map +1 -0
- package/dist/src/env-utils.d.ts +8 -0
- package/dist/src/env-utils.js +38 -0
- package/dist/src/env-utils.js.map +1 -0
- package/dist/src/error-utils.d.ts +8 -0
- package/dist/src/error-utils.js +99 -0
- package/dist/src/error-utils.js.map +1 -0
- package/dist/src/is-empty.d.ts +1 -0
- package/dist/src/is-empty.js +13 -0
- package/dist/src/is-empty.js.map +1 -0
- package/dist/src/is-object.d.ts +2 -0
- package/dist/src/is-object.js +7 -0
- package/dist/src/is-object.js.map +1 -0
- package/dist/src/isset.d.ts +1 -0
- package/dist/src/isset.js +8 -0
- package/dist/src/isset.js.map +1 -0
- package/dist/src/logger-utils.d.ts +76 -0
- package/dist/src/logger-utils.js +355 -0
- package/dist/src/logger-utils.js.map +1 -0
- package/dist/src/loop-utils.d.ts +37 -0
- package/dist/src/loop-utils.js +105 -0
- package/dist/src/loop-utils.js.map +1 -0
- package/dist/src/math-utils.d.ts +23 -0
- package/dist/src/math-utils.js +43 -0
- package/dist/src/math-utils.js.map +1 -0
- package/dist/src/mongo-utils.d.ts +11 -0
- package/dist/src/mongo-utils.js +49 -0
- package/dist/src/mongo-utils.js.map +1 -0
- package/dist/src/object-utils.d.ts +96 -0
- package/dist/src/object-utils.js +369 -0
- package/dist/src/object-utils.js.map +1 -0
- package/dist/src/private/config.d.ts +44 -0
- package/dist/src/private/config.js +55 -0
- package/dist/src/private/config.js.map +1 -0
- package/dist/src/private/error-handler.d.ts +10 -0
- package/dist/src/private/error-handler.js +18 -0
- package/dist/src/private/error-handler.js.map +1 -0
- package/dist/src/private/types.d.ts +4 -0
- package/dist/src/private/types.js +3 -0
- package/dist/src/private/types.js.map +1 -0
- package/dist/src/regexp-utils.d.ts +12 -0
- package/dist/src/regexp-utils.js +44 -0
- package/dist/src/regexp-utils.js.map +1 -0
- package/dist/src/remove-circular-json-stringify.d.ts +1 -0
- package/dist/src/remove-circular-json-stringify.js +20 -0
- package/dist/src/remove-circular-json-stringify.js.map +1 -0
- package/dist/src/string-utils.d.ts +77 -0
- package/dist/src/string-utils.js +209 -0
- package/dist/src/string-utils.js.map +1 -0
- package/dist/src/tests-utils.js +77 -0
- package/dist/src/tests-utils.js.map +1 -0
- package/dist/src/timer-utils.d.ts +16 -0
- package/dist/src/timer-utils.js +79 -0
- package/dist/src/timer-utils.js.map +1 -0
- package/dist/src/transaction-utils.d.ts +14 -0
- package/dist/src/transaction-utils.js +87 -0
- package/dist/src/transaction-utils.js.map +1 -0
- package/dist/src/validation-utils.d.ts +89 -0
- package/dist/src/validation-utils.js +192 -0
- package/dist/src/validation-utils.js.map +1 -0
- package/dist/src/wtf-utils.d.ts +7 -0
- package/dist/src/wtf-utils.js +83 -0
- package/dist/src/wtf-utils.js.map +1 -0
- package/index.ts +38 -0
- package/package.json +2 -2
- package/src/array-utils.ts +128 -0
- package/src/date-utils.ts +377 -0
- package/src/env-utils.ts +29 -0
- package/src/error-utils.ts +77 -0
- package/src/is-empty.ts +5 -0
- package/src/is-object.ts +3 -0
- package/src/isset.ts +3 -0
- package/src/logger-utils.ts +349 -0
- package/src/loop-utils.ts +101 -0
- package/src/math-utils.ts +38 -0
- package/src/mongo-utils.ts +38 -0
- package/src/object-utils.ts +356 -0
- package/src/private/config.ts +85 -0
- package/src/private/error-handler.ts +21 -0
- package/src/private/types.ts +6 -0
- package/src/regexp-utils.ts +37 -0
- package/src/remove-circular-json-stringify.ts +17 -0
- package/src/string-utils.ts +212 -0
- package/src/tests-utils.ts +70 -0
- package/src/timer-utils.ts +58 -0
- package/src/transaction-utils.ts +63 -0
- package/src/validation-utils.ts +253 -0
- package/src/wtf-utils.ts +88 -0
- package/tsconfig.json +11 -4
- package/utils.d.ts +0 -694
- package/utils.js +0 -2227
- package/utils.js.map +0 -1
- package/utils.ts +0 -2304
package/index.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export * from './src/array-utils'
|
|
2
|
+
export * from './src/date-utils'
|
|
3
|
+
export * from './src/env-utils'
|
|
4
|
+
export * from './src/error-utils'
|
|
5
|
+
export * from './src/isset'
|
|
6
|
+
export * from './src/logger-utils'
|
|
7
|
+
export * from './src/loop-utils'
|
|
8
|
+
export * from './src/math-utils'
|
|
9
|
+
export * from './src/mongo-utils'
|
|
10
|
+
export * from './src/object-utils'
|
|
11
|
+
export * from './src/string-utils'
|
|
12
|
+
export * from './src/wtf-utils'
|
|
13
|
+
export * from './src/validation-utils'
|
|
14
|
+
export * from './src/transaction-utils'
|
|
15
|
+
export * from './src/timer-utils'
|
|
16
|
+
export * from './src/is-empty'
|
|
17
|
+
export * from './src/remove-circular-json-stringify'
|
|
18
|
+
export * from './src/is-object'
|
|
19
|
+
export { registerConfig } from './src/private/config'
|
|
20
|
+
|
|
21
|
+
import { moyenne } from './src/math-utils'
|
|
22
|
+
import { kebabCase, snakeCase } from './src/string-utils'
|
|
23
|
+
import { shuffleArray, noDuplicateFilter } from './src/array-utils'
|
|
24
|
+
import { issetOr, validator } from './src/validation-utils'
|
|
25
|
+
import { objFilterUndefinedRecursive } from './src/object-utils'
|
|
26
|
+
import { removeCircularJSONstringify } from './src/remove-circular-json-stringify'
|
|
27
|
+
|
|
28
|
+
// ALIASES
|
|
29
|
+
export const int = parseInt
|
|
30
|
+
export const average = moyenne
|
|
31
|
+
export const arrayUniqueValue = noDuplicateFilter
|
|
32
|
+
export const JSONstringyParse = o => JSON.parse(removeCircularJSONstringify(o))
|
|
33
|
+
export const removeUndefinedKeys = objFilterUndefinedRecursive
|
|
34
|
+
export const randomizeArray = shuffleArray
|
|
35
|
+
export const dashCase = kebabCase
|
|
36
|
+
export const underscoreCase = snakeCase
|
|
37
|
+
export const required = validator // alias for readability
|
|
38
|
+
export const orIsset = issetOr
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "topkat-utils",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.2",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"private": false,
|
|
6
6
|
"description": "UTILS BIG TIME",
|
|
7
7
|
"author": "538ROMEO",
|
|
8
8
|
"license": "ISC",
|
|
9
|
-
"main": "
|
|
9
|
+
"main": "dist/index.js",
|
|
10
10
|
"scripts": {
|
|
11
11
|
"build": "tsc",
|
|
12
12
|
"bump:major": "npm run build & node node_modules/bump-simple/bump-simple.js --major",
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
//----------------------------------------
|
|
2
|
+
// ARRAY UTILS
|
|
3
|
+
//----------------------------------------
|
|
4
|
+
import { ensureObjectProp, objForceWriteIfNotSet } from "./object-utils"
|
|
5
|
+
import { isset } from "./isset"
|
|
6
|
+
|
|
7
|
+
export function shuffleArray(array) {
|
|
8
|
+
for (let i = array.length - 1; i > 0; i--) {
|
|
9
|
+
const j = Math.floor(Math.random() * (i + 1));
|
|
10
|
+
[array[i], array[j]] = [array[j], array[i]]
|
|
11
|
+
}
|
|
12
|
+
return array
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Maye sure obj[addr] is an array and push a value to it
|
|
18
|
+
* @param {Object} obj parent object
|
|
19
|
+
* @param {String} addr field name in parent
|
|
20
|
+
* @param {Any} valToPush
|
|
21
|
+
* @param {Boolean} onlyUniqueValues default:false; may be true or a comparision function; (a,b) => return true if they are the same like (a, b) => a.name === b.name
|
|
22
|
+
* @return obj[addr] eventually processed by the callback
|
|
23
|
+
*/
|
|
24
|
+
export function ensureIsArrayAndPush(obj: object, addr: string, valToPush, onlyUniqueValues: Function) {
|
|
25
|
+
return ensureObjectProp(obj, addr, [], objValue => {
|
|
26
|
+
if (isset(onlyUniqueValues)) {
|
|
27
|
+
let duplicateFound = false
|
|
28
|
+
if (typeof onlyUniqueValues === 'function') duplicateFound = objValue.some(a => onlyUniqueValues(a, valToPush))
|
|
29
|
+
else duplicateFound = objValue.includes(valToPush)
|
|
30
|
+
if (!duplicateFound) objValue.push(valToPush)
|
|
31
|
+
} else objValue.push(valToPush)
|
|
32
|
+
})
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
/** If a string is provided, return it as array else return the value */
|
|
37
|
+
export function strAsArray(arrOrStr) {
|
|
38
|
+
return typeof arrOrStr === 'string' ? [arrOrStr] : arrOrStr
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** If not an array provided, return the array with the value
|
|
42
|
+
* /!\ NOTE /!\ In case the value is null or undefined, it will return that value
|
|
43
|
+
*/
|
|
44
|
+
export function asArray<T extends any[] | any>(item: T): T extends undefined ? undefined : T extends any[] ? T : T[] {
|
|
45
|
+
return ((typeof item === 'undefined' ? item : Array.isArray(item) ? item : [item]) as T extends undefined ? undefined : T extends any[] ? T : T[])
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Array comparison
|
|
49
|
+
* @return {object} { inCommon, notInB, notInA }
|
|
50
|
+
*/
|
|
51
|
+
export function compareArrays(arrayA: any[], arrayB: any[], compare = (a, b) => a === b) {
|
|
52
|
+
return {
|
|
53
|
+
inCommon: getArrayInCommon(arrayA, arrayB, compare),
|
|
54
|
+
notInB: getNotInArrayA(arrayB, arrayA, compare),
|
|
55
|
+
notInA: getNotInArrayA(arrayA, arrayB, compare),
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* @return [] only elements that are both in arrayA and arrayB
|
|
61
|
+
*/
|
|
62
|
+
export function getArrayInCommon(arrayA = [], arrayB = [], compare = (a, b) => a === b): any[] {
|
|
63
|
+
if (!Array.isArray(arrayA) || !Array.isArray(arrayB)) return []
|
|
64
|
+
else return arrayA.filter(a => arrayB.some(b => compare(a, b)))
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* @return [] only elements that are in arrayB and not in arrayA
|
|
69
|
+
*/
|
|
70
|
+
export function getNotInArrayA(arrayA = [], arrayB = [], compare = (a, b) => a === b): any[] {
|
|
71
|
+
if (!Array.isArray(arrayA) && Array.isArray(arrayB)) return arrayB
|
|
72
|
+
else if (!Array.isArray(arrayB)) return []
|
|
73
|
+
else return arrayB.filter(b => !arrayA.some(a => compare(a, b)))
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* @return [] only elements that are in neither arrayA and arrayB
|
|
78
|
+
*/
|
|
79
|
+
export function getArrayDiff(arrayA = [], arrayB = [], compare = (a, b) => a === b): any[] {
|
|
80
|
+
return [...getNotInArrayA(arrayA, arrayB, compare), ...getNotInArrayA(arrayB, arrayA, compare)]
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** filter duplicate values in an array
|
|
84
|
+
* @param {function} comparisonFn default:(a, b) => a === b. A function that shall return true if two values are considered equal
|
|
85
|
+
* @return {array|function}
|
|
86
|
+
*/
|
|
87
|
+
export function noDuplicateFilter(arr, comparisonFn = (a, b) => a === b): any[] {
|
|
88
|
+
return arr.filter((a, i, arr) => arr.findIndex(b => comparisonFn(a, b)) === i)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Count number of occurence of item in array */
|
|
92
|
+
export function arrayCount(item: any, arr: any[]): number {
|
|
93
|
+
return arr.reduce((total, item2) => item === item2 ? total + 1 : total, 0)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Sort an array in an object of subArrays, no duplicate.
|
|
98
|
+
* @param {Array} array
|
|
99
|
+
* @param {function} getFieldFromItem (itemOfArray) => field[String|Number]
|
|
100
|
+
* tell me how you want to sort your Array
|
|
101
|
+
*/
|
|
102
|
+
export function arrayToObjectSorted(array, getFieldFromItem) {
|
|
103
|
+
const res = {}
|
|
104
|
+
|
|
105
|
+
array.forEach(item => {
|
|
106
|
+
objForceWriteIfNotSet(res, getFieldFromItem(item), [])
|
|
107
|
+
res[getFieldFromItem(item)].push(item)
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
return res
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @param {Function} comparisonFunction default: (itemToPush, itemAlreadyInArray) => itemToPush === itemAlreadyInArray; comparison function to consider the added item duplicate
|
|
115
|
+
*/
|
|
116
|
+
export function pushIfNotExist(arrayToPushInto, valueOrArrayOfValuesToBePushed, comparisonFunction = (a, b) => a === b): any[] {
|
|
117
|
+
const valuesToPush = asArray(valueOrArrayOfValuesToBePushed).filter(a => !arrayToPushInto.some(b => comparisonFunction(a, b)))
|
|
118
|
+
arrayToPushInto.push(...valuesToPush)
|
|
119
|
+
return arrayToPushInto
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function isNotEmptyArray(arr): boolean {
|
|
123
|
+
return Array.isArray(arr) && !!arr.length
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function randomItemInArray<T>(array: T[]): T {
|
|
127
|
+
return array[Math.floor(Math.random() * array.length)]
|
|
128
|
+
}
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
//----------------------------------------
|
|
2
|
+
// DATE UTILS
|
|
3
|
+
//----------------------------------------
|
|
4
|
+
import { isset } from "./isset"
|
|
5
|
+
import { pad } from "./math-utils"
|
|
6
|
+
import { dataValidationUtilErrorHandler } from "./private/error-handler"
|
|
7
|
+
import { err422IfNotSet } from "./error-utils"
|
|
8
|
+
|
|
9
|
+
const int = parseInt
|
|
10
|
+
|
|
11
|
+
export function getDateAsInt12(dateAllFormat?: Date | string | number, errIfNotValid?): string { return getDateAsInt(dateAllFormat, errIfNotValid, true) } // alias
|
|
12
|
+
|
|
13
|
+
export function humanReadableTimestamp(dateAllFormat: any): number {
|
|
14
|
+
if (isset(dateAllFormat)) dateAllFormat = getDateAsObject(dateAllFormat)
|
|
15
|
+
return parseInt(getDateAsInt12(dateAllFormat) + pad((dateAllFormat || new Date()).getUTCSeconds()) + pad((dateAllFormat || new Date()).getUTCMilliseconds(), 3))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** format for 6/8/2018 => 20180806
|
|
19
|
+
* @param dateAllFormat multiple format allowed 2012, 20120101, 201201011200, new Date(), "2019-12-08T16:19:10.341Z" and all string that new Date() can parse
|
|
20
|
+
*/
|
|
21
|
+
export function getDateAsInt(dateAllFormat: Date | string | number = new Date(), errIfNotValid$ = false, withHoursAndMinutes$ = false): string { // optional
|
|
22
|
+
let dateInt
|
|
23
|
+
if (typeof dateAllFormat === 'string' && dateAllFormat.includes('/')) {
|
|
24
|
+
// 01/01/2020 format
|
|
25
|
+
const [d, m, y] = dateAllFormat.split('/')
|
|
26
|
+
return y + m.toString().padStart(2, '0') + d.toString().padStart(2, '0')
|
|
27
|
+
} else if (isDateIntOrStringValid(dateAllFormat)) {
|
|
28
|
+
// we can pass an int or string format (20180106)
|
|
29
|
+
dateInt = (dateAllFormat + '00000000').substr(0, 12) // add default 000000 for "month days minutes:sec" if not set
|
|
30
|
+
} else {
|
|
31
|
+
let date: any = dateAllFormat
|
|
32
|
+
if (typeof date === 'string') date = new Date(date)
|
|
33
|
+
const realDate: Date = date
|
|
34
|
+
//let dateArr = dateAllFormat.toString().split(); // we cannot use ISOString
|
|
35
|
+
dateInt = '' + realDate.getUTCFullYear() + pad(realDate.getUTCMonth() + 1) + pad(realDate.getUTCDate()) + pad(realDate.getUTCHours()) + pad(realDate.getUTCMinutes())
|
|
36
|
+
}
|
|
37
|
+
isDateIntOrStringValid(dateInt, errIfNotValid$)
|
|
38
|
+
return (withHoursAndMinutes$ ? dateInt : dateInt.substr(0, 8))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
export function getMonthAsInt(dateAllFormat: Date | string | number = new Date()): number {
|
|
43
|
+
let dateInt
|
|
44
|
+
if (isDateIntOrStringValid(dateAllFormat)) {
|
|
45
|
+
// we can pass an int or string format (20180106)
|
|
46
|
+
dateInt = (dateAllFormat + '').substr(0, 6)
|
|
47
|
+
} else {
|
|
48
|
+
let date: any = dateAllFormat
|
|
49
|
+
if (typeof date === 'string') date = new Date(date)
|
|
50
|
+
//let dateArr = dateAllFormat.toString().split(); // we cannot use ISOString
|
|
51
|
+
dateInt = '' + date.getUTCFullYear() + pad(date.getUTCMonth() + 1)
|
|
52
|
+
}
|
|
53
|
+
return int(dateInt)
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* @param dateAllFormat multiple format allowed 2012, 20120101, 201201011200, new Date(), "2019-12-08T16:19:10.341Z" and all string that new Date() can parse
|
|
57
|
+
*/
|
|
58
|
+
export function getDateAsObject(dateAllFormat: any = new Date(), errIfNotValid$ = true): Date {
|
|
59
|
+
let dateObj = dateAllFormat
|
|
60
|
+
if (isDateIntOrStringValid(dateAllFormat)) {
|
|
61
|
+
const [y, M, d, h, m] = dateStringToArray(dateAllFormat)
|
|
62
|
+
dateObj = new Date(`${y}-${M}-${d}T${h}:${m}`)
|
|
63
|
+
} else if (typeof dateAllFormat === 'string') {
|
|
64
|
+
dateObj = new Date(dateAllFormat)
|
|
65
|
+
} else {
|
|
66
|
+
dateObj = new Date(dateAllFormat.getTime()) // clone
|
|
67
|
+
}
|
|
68
|
+
isDateIsoOrObjectValid(dateObj, errIfNotValid$)
|
|
69
|
+
return dateObj
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** [2018,01,06] */
|
|
73
|
+
export function dateStringToArray(strOrInt) {
|
|
74
|
+
err422IfNotSet({ strOrInt })
|
|
75
|
+
|
|
76
|
+
const dateStr = strOrInt.toString()
|
|
77
|
+
return [
|
|
78
|
+
dateStr.substr(0, 4), // Y
|
|
79
|
+
dateStr.substr(4, 2) || '01', // M
|
|
80
|
+
dateStr.substr(6, 2) || '01', // D
|
|
81
|
+
dateStr.substr(8, 2) || '12', // H 12 default to avoid time shift when converting to dateObj
|
|
82
|
+
dateStr.substr(10, 2) || '00', // M
|
|
83
|
+
dateStr.substr(12, 2) || '00', // S
|
|
84
|
+
dateStr.substr(14, 3) || '000', // MS
|
|
85
|
+
]
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @param dateAllFormat default: actualDate
|
|
90
|
+
* @returns ['01', '01', '2019'] OR **string** if separator is provided */
|
|
91
|
+
export function dateArray(dateAllFormat: Date | string | number = getDateAsInt()): [string, string, string] {
|
|
92
|
+
const dateStr = getDateAsInt(dateAllFormat).toString()
|
|
93
|
+
return [
|
|
94
|
+
dateStr.substr(6, 2), // D
|
|
95
|
+
dateStr.substr(4, 2), // M
|
|
96
|
+
dateStr.substr(0, 4), // Y
|
|
97
|
+
]
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* @param dateAllFormat default: actualDate
|
|
102
|
+
* @returns ['01', '01', '2019'] OR **string** if separator is provided */
|
|
103
|
+
export function dateArrayInt(dateAllFormat: Date | string | number = getDateAsInt()): [number, number, number] {
|
|
104
|
+
const dateStr = getDateAsInt(dateAllFormat).toString()
|
|
105
|
+
return [
|
|
106
|
+
int(dateStr.substr(6, 2)), // D
|
|
107
|
+
int(dateStr.substr(4, 2)), // M
|
|
108
|
+
int(dateStr.substr(0, 4)), // Y
|
|
109
|
+
]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* @return 01/01/2012 (alias of dateArrayFormatted(date, '/'))
|
|
115
|
+
*/
|
|
116
|
+
export function dateFormatted(dateAllFormat: Date | string | number, separator = '/') { return dateArray(dateAllFormat).join(separator) }
|
|
117
|
+
|
|
118
|
+
/** Date with custom offset (Ex: +2 for France) */
|
|
119
|
+
export function dateOffset(offsetHours, dateObj = new Date()) {
|
|
120
|
+
|
|
121
|
+
var utc = Date.UTC(dateObj.getUTCFullYear(), dateObj.getUTCMonth(), dateObj.getUTCDate(),
|
|
122
|
+
dateObj.getUTCHours(), dateObj.getUTCMinutes(), dateObj.getUTCSeconds())
|
|
123
|
+
|
|
124
|
+
return new Date(utc + (3600000 * offsetHours))
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//----------------------------------------
|
|
128
|
+
// TIME UTILS
|
|
129
|
+
//----------------------------------------
|
|
130
|
+
|
|
131
|
+
/** */
|
|
132
|
+
export function getTimeAsInt(timeOrDateInt: any = getDateAsInt12()) {
|
|
133
|
+
if (isDateIntOrStringValid(timeOrDateInt)) {
|
|
134
|
+
const tl = timeOrDateInt.toString().length
|
|
135
|
+
return int(timeOrDateInt.toString().substring(tl - 4, tl))
|
|
136
|
+
} else if (typeof timeOrDateInt === 'string' && timeOrDateInt.length === 5 && timeOrDateInt.includes(':'))
|
|
137
|
+
return int(timeOrDateInt.replace(':', ''))
|
|
138
|
+
else return 'dateInvalid'
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @param {timeInt|dateInt12} Eg: 2222 OR 201201012222. Default, actual dateInt12
|
|
143
|
+
* @param {String} separator default: ":"
|
|
144
|
+
*/
|
|
145
|
+
export function getIntAsTime(intOrDateTimeInt = getDateAsInt12(), separator = ':') {
|
|
146
|
+
const time = intOrDateTimeInt.toString().padStart(4, '0')
|
|
147
|
+
const tl = time.length
|
|
148
|
+
return time.substring(tl - 4, tl - 2) + separator + time.substring(tl - 2, tl)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function isTimeStringValid(timeStr, outputAnError$ = false) {
|
|
152
|
+
let timeArr = timeStr.split(':')
|
|
153
|
+
let h = int(timeArr[0])
|
|
154
|
+
let m = int(timeArr[1])
|
|
155
|
+
let test1 = h >= 0 && h < 24
|
|
156
|
+
let test2 = m >= 0 && m < 60
|
|
157
|
+
if (outputAnError$ && !(test1 && test2)) throw new dataValidationUtilErrorHandler('timeStringOutOfRange', 422, { origin: 'Time validator' })
|
|
158
|
+
else return test1 && test2
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//----------------------------------------
|
|
162
|
+
// DURATIONS
|
|
163
|
+
//----------------------------------------
|
|
164
|
+
|
|
165
|
+
export function getDuration(startDate, endDate, inMinutes = false) {
|
|
166
|
+
const startDateO = getDateAsObject(startDate)
|
|
167
|
+
const endDateO = getDateAsObject(endDate)
|
|
168
|
+
let diffInSec = Math.floor(endDateO.getTime() / 1000) - Math.floor(startDateO.getTime() / 1000)
|
|
169
|
+
|
|
170
|
+
if (inMinutes) return Math.floor(diffInSec / 60)
|
|
171
|
+
else return [
|
|
172
|
+
Math.floor(diffInSec / (24 * 3600)), // D
|
|
173
|
+
Math.floor((diffInSec % (24 * 3600)) / 3600), // H
|
|
174
|
+
Math.floor(((diffInSec % (24 * 3600)) % 3600) / 60), // M
|
|
175
|
+
]
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** compare two object with DATE INT, if they overlap return true
|
|
179
|
+
* @param {Object} event1 {startDate, endDate}
|
|
180
|
+
* @param {Object} event2 {startDate, endDate}
|
|
181
|
+
* @param {String} fieldNameForStartDate$ replace startDate with this string
|
|
182
|
+
* @param {String} fieldNameForEndDate$ replace endDate with this string
|
|
183
|
+
* @param {Boolean} allowNull$ if false, retrun false if any of the startdates or enddates are not set
|
|
184
|
+
* @param {Boolean} strict$ if true,
|
|
185
|
+
*/
|
|
186
|
+
export function doDateOverlap(event1, event2, fieldNameForStartDate$ = 'startDate', fieldNameForEndDate$ = 'endDate', allowNull$ = true, strict$ = false) {
|
|
187
|
+
if (!allowNull$ && !isset(event1[fieldNameForStartDate$], event1[fieldNameForEndDate$], event2[fieldNameForStartDate$], event2[fieldNameForEndDate$])) return false
|
|
188
|
+
|
|
189
|
+
if (strict$)
|
|
190
|
+
return (!event2[fieldNameForEndDate$] || event1[fieldNameForStartDate$] < event2[fieldNameForEndDate$]) && (!event1[fieldNameForEndDate$] || event1[fieldNameForEndDate$] > event2[fieldNameForStartDate$])
|
|
191
|
+
|
|
192
|
+
return (!event2[fieldNameForEndDate$] || event1[fieldNameForStartDate$] <= event2[fieldNameForEndDate$]) && (!event1[fieldNameForEndDate$] || event1[fieldNameForEndDate$] >= event2[fieldNameForStartDate$])
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
type DateAllFormat = DateObjectFormat | DateStringFormats
|
|
196
|
+
type DateStringFormats = 'dateInt8' | 'dateInt12' | 'humanReadableTimestamp'
|
|
197
|
+
type DateObjectFormat = 'date'
|
|
198
|
+
|
|
199
|
+
export function nextWeekDay(fromDate, weekDayInt?: 0 | 1 | 2 | 3 | 4 | 5 | 6, outputFormat?: DateStringFormats, sameDayAllowed?: boolean): number
|
|
200
|
+
export function nextWeekDay(fromDate, weekDayInt?: 0 | 1 | 2 | 3 | 4 | 5 | 6, outputFormat?: DateObjectFormat, sameDayAllowed?: boolean): Date
|
|
201
|
+
export function nextWeekDay(fromDate, weekDayInt?: 0 | 1 | 2 | 3 | 4 | 5 | 6, outputFormat = 'date', sameDayAllowed = false): any {
|
|
202
|
+
const date = getDateAsObject(fromDate)
|
|
203
|
+
if (!isset(weekDayInt)) weekDayInt = (date.getDay() as 0 | 1 | 2 | 3 | 4 | 5 | 6)
|
|
204
|
+
const toAdd = !sameDayAllowed && date.getDay() === weekDayInt ? 7 : 0
|
|
205
|
+
date.setUTCDate(date.getUTCDate() + toAdd + (7 + weekDayInt - date.getUTCDay()) % 7)
|
|
206
|
+
return getDateAs(date, outputFormat as any)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
211
|
+
*/
|
|
212
|
+
export function addDays(dateAllFormat?: Date | string | number, numberOfDays?: number, outputFormat?: 'dateInt8' | 'dateInt12' | 'humanReadableTimestamp'): string
|
|
213
|
+
export function addDays(dateAllFormat?: Date | string | number, numberOfDays?: number, outputFormat?: 'date'): Date
|
|
214
|
+
export function addDays(dateAllFormat: Date | string | number = getDateAsInt(), numberOfDays = 1, outputFormat: DateAllFormat = 'date'): any {
|
|
215
|
+
let date = getDateAsObject(dateAllFormat)
|
|
216
|
+
date.setTime(date.getTime() + numberOfDays * 24 * 60 * 60 * 1000)
|
|
217
|
+
return getDateAs(date, outputFormat as any)
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
222
|
+
*/
|
|
223
|
+
export function addMinutes(dateAllFormat?: Date | string | number, numberOfMinutes?: number, outputFormat?: DateStringFormats): string
|
|
224
|
+
export function addMinutes(dateAllFormat?: Date | string | number, numberOfMinutes?: number, outputFormat?: DateObjectFormat): Date
|
|
225
|
+
export function addMinutes(dateAllFormat: Date | string | number = getDateAsInt(), numberOfMinutes = 1, outputFormat: DateAllFormat = 'date'): any {
|
|
226
|
+
let date = getDateAsObject(dateAllFormat)
|
|
227
|
+
date.setTime(date.getTime() + 1 * numberOfMinutes * 60 * 1000)
|
|
228
|
+
return getDateAs(date, outputFormat as any)
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
232
|
+
*/
|
|
233
|
+
export function addHours(dateAllFormat?: Date | string | number, numberOfHours?: number, outputFormat?: 'dateInt8' | 'dateInt12' | 'humanReadableTimestamp'): string
|
|
234
|
+
export function addHours(dateAllFormat?: Date | string | number, numberOfHours?: number, outputFormat?: 'date'): Date
|
|
235
|
+
export function addHours(dateAllFormat: Date | string | number = getDateAsInt(), numberOfHours = 1, outputFormat: DateAllFormat = 'date'): any {
|
|
236
|
+
let date = getDateAsObject(dateAllFormat)
|
|
237
|
+
date.setTime(date.getTime() + 1 * numberOfHours * 60 * 60 * 1000)
|
|
238
|
+
return getDateAs(date, outputFormat as any)
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
242
|
+
*/
|
|
243
|
+
export function addMonths(dateAllFormat?: Date | string | number, numberOfMonths?: number, outputFormat?: 'dateInt8' | 'dateInt12' | 'humanReadableTimestamp'): string
|
|
244
|
+
export function addMonths(dateAllFormat?: Date | string | number, numberOfMonths?: number, outputFormat?: 'date'): Date
|
|
245
|
+
export function addMonths(dateAllFormat: Date | string | number = getDateAsInt(), numberOfMonths = 1, outputFormat: DateAllFormat = 'date'): any {
|
|
246
|
+
let date = getDateAsObject(dateAllFormat)
|
|
247
|
+
date.setUTCMonth(date.getUTCMonth() + numberOfMonths)
|
|
248
|
+
return getDateAs(date, outputFormat as any)
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
252
|
+
*/
|
|
253
|
+
export function addYears(dateAllFormat: Date | string | number = getDateAsInt(), numberOfYears = 1, outputFormat: DateAllFormat = 'date') {
|
|
254
|
+
let date = getDateAsObject(dateAllFormat)
|
|
255
|
+
date.setUTCFullYear(date.getUTCFullYear() + numberOfYears)
|
|
256
|
+
return getDateAs(date, outputFormat as any)
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export function getDayOfMonth(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
260
|
+
let dateAsInt = getDateAsInt(dateAllFormat)
|
|
261
|
+
const [, , d] = dateStringToArray(dateAsInt)
|
|
262
|
+
return d
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
export function getYear(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
266
|
+
let dateAsInt = getDateAsInt(dateAllFormat)
|
|
267
|
+
const [y] = dateStringToArray(dateAsInt)
|
|
268
|
+
return y
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
export function getHours(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
273
|
+
let dateAsInt = getDateAsInt(dateAllFormat)
|
|
274
|
+
const [, , , h,] = dateStringToArray(dateAsInt)
|
|
275
|
+
return h
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
export function getMinutes(dateAllFormat: Date | string | number = getDateAsInt()) {
|
|
279
|
+
let dateAsInt = getDateAsInt(dateAllFormat)
|
|
280
|
+
const [, , , , m] = dateStringToArray(dateAsInt)
|
|
281
|
+
return m
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
286
|
+
*/
|
|
287
|
+
export function lastDayOfMonth(dateAllFormat: Date | string | number = getDateAsInt(), outputFormat: DateAllFormat = 'date') {
|
|
288
|
+
let date = getDateAsObject(dateAllFormat)
|
|
289
|
+
const lastDay = new Date(date.getUTCFullYear(), date.getUTCMonth() + 1, 0)
|
|
290
|
+
lastDay.setUTCHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds())
|
|
291
|
+
return getDateAs(lastDay, outputFormat as any)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* @param {String} outputFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
296
|
+
*/
|
|
297
|
+
export function firstDayOfMonth(dateAllFormat: Date | string | number = getDateAsInt(), outputFormat: DateAllFormat = 'date') {
|
|
298
|
+
let date = getDateAsObject(dateAllFormat)
|
|
299
|
+
const firstDay = new Date(date.getUTCFullYear(), date.getUTCMonth(), 1)
|
|
300
|
+
firstDay.setUTCHours(date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), date.getUTCMilliseconds())
|
|
301
|
+
return getDateAs(firstDay, outputFormat as any)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export function differenceInMilliseconds(startDateAllFormat, endDateAllFormat) {
|
|
305
|
+
const startDate = getDateAsObject(startDateAllFormat)
|
|
306
|
+
const endDate = getDateAsObject(endDateAllFormat)
|
|
307
|
+
return endDate.getTime() - startDate.getTime()
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export function differenceInSeconds(startDateAllFormat, endDateAllFormat) {
|
|
311
|
+
return differenceInMilliseconds(startDateAllFormat, endDateAllFormat) / 1000
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
export function differenceInMinutes(startDateAllFormat, endDateAllFormat) {
|
|
315
|
+
return differenceInSeconds(startDateAllFormat, endDateAllFormat) / 60
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export function differenceInHours(startDateAllFormat, endDateAllFormat) {
|
|
319
|
+
return differenceInMinutes(startDateAllFormat, endDateAllFormat) / 60
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
export function differenceInDays(startDateAllFormat, endDateAllFormat) {
|
|
323
|
+
return differenceInHours(startDateAllFormat, endDateAllFormat) / 24
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
export function differenceInWeeks(startDateAllFormat, endDateAllFormat) {
|
|
327
|
+
return differenceInDays(startDateAllFormat, endDateAllFormat) / 7
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* @param {String} outputDateFormat dateInt, dateInt8, dateInt12, date, humanReadableTimestamp, int (dateInt8)
|
|
332
|
+
*/
|
|
333
|
+
export function getDateAs(dateAllFormat?: Date | string | number, outputFormat?: 'dateInt8' | 'dateInt12' | 'humanReadableTimestamp'): string
|
|
334
|
+
export function getDateAs(dateAllFormat?: Date | string | number, outputFormat?: 'date'): Date
|
|
335
|
+
export function getDateAs(dateAllFormat: Date | string | number = new Date(), outputDateFormat: DateAllFormat = 'date') {
|
|
336
|
+
switch (outputDateFormat) {
|
|
337
|
+
case 'dateInt8':
|
|
338
|
+
return getDateAsInt(dateAllFormat)
|
|
339
|
+
case 'dateInt12':
|
|
340
|
+
return getDateAsInt12(dateAllFormat)
|
|
341
|
+
case 'humanReadableTimestamp':
|
|
342
|
+
return humanReadableTimestamp(dateAllFormat)
|
|
343
|
+
case 'date':
|
|
344
|
+
default:
|
|
345
|
+
return getDateAsObject(dateAllFormat)
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
export function isDateIntOrStringValid(dateStringOrInt, outputAnError = false, length?): boolean {
|
|
351
|
+
if (!isset(dateStringOrInt)) return false
|
|
352
|
+
const dateStr = dateStringOrInt.toString()
|
|
353
|
+
|
|
354
|
+
if (length && dateStr.length !== length) throw new dataValidationUtilErrorHandler(`wrongLengthForDateInt`, 422, { origin: 'Date Int validator', dateStringOrInt: dateStringOrInt, extraInfo: `${dateStringOrInt} length !== ${length}` })
|
|
355
|
+
|
|
356
|
+
if ((typeof dateStringOrInt === 'object' && isNaN(int(dateStr))) || ![4, 6, 8, 10, 12, 17].includes(dateStr.length)) return false
|
|
357
|
+
|
|
358
|
+
const dateArr = dateStringToArray(dateStringOrInt)
|
|
359
|
+
const [y, M, d, h, m] = dateArr
|
|
360
|
+
|
|
361
|
+
const test1 = dateArr.length >= 3 && int(y) >= 1000 // Y
|
|
362
|
+
const test2 = int(M) <= 12 && int(M) > 0 // M
|
|
363
|
+
const test3 = !isset(d) || int(d) <= 31 && int(d) > 0 // D
|
|
364
|
+
const test4 = !isset(h) || (int(h) <= 23 && int(h) >= 0) // H
|
|
365
|
+
const test5 = !isset(m) || (int(m) <= 59 && int(m) >= 0) // M
|
|
366
|
+
|
|
367
|
+
if (outputAnError && !(test1 && test2 && test3 && test4 && test5)) throw new dataValidationUtilErrorHandler(`dateStringOrIntFormatInvalid`, 422, { origin: 'Date Int validator', dateStringOrInt: dateStringOrInt, extraInfo: 'Needs YYYYMMDD[HHMM] between 100001010000 and 999912312359', dateArr, isYearValid: test1, isMonthValid: test2, isDayValid: test3, isHourValid: test4, isMinutesValid: test5 })
|
|
368
|
+
return true
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
export function isDateIsoOrObjectValid(dateIsoOrObj, outputAnError = false) {
|
|
372
|
+
let dateObj: Date | number | string = dateIsoOrObj
|
|
373
|
+
if (typeof dateIsoOrObj === 'string') dateObj = new Date(dateIsoOrObj)
|
|
374
|
+
let valid = dateObj instanceof Date
|
|
375
|
+
if (outputAnError && !valid) throw new dataValidationUtilErrorHandler('dateIsoStringOrObjectIsNotValid', 422, { origin: 'Date Object validator', isoDate: dateIsoOrObj })
|
|
376
|
+
return valid
|
|
377
|
+
}
|
package/src/env-utils.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
//----------------------------------------
|
|
2
|
+
// ENV UTILS
|
|
3
|
+
//----------------------------------------
|
|
4
|
+
|
|
5
|
+
/** Parse one dimention object undefined, true, false, null represented as string will be converted to primitives */
|
|
6
|
+
export function parseEnv(env) {
|
|
7
|
+
const newEnv = {}
|
|
8
|
+
for (const k in env) {
|
|
9
|
+
const val = env[k]
|
|
10
|
+
if (val === 'undefined') newEnv[k] = undefined
|
|
11
|
+
else if (val === 'true') newEnv[k] = true
|
|
12
|
+
else if (val === 'false') newEnv[k] = false
|
|
13
|
+
else if (val === 'null') newEnv[k] = null
|
|
14
|
+
else newEnv[k] = env[k]
|
|
15
|
+
}
|
|
16
|
+
return newEnv
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** READ ONLY, output a parsed version of process.env
|
|
20
|
+
* use it like ENV().myVar
|
|
21
|
+
*/
|
|
22
|
+
export function ENV(): { [key: string]: any } {
|
|
23
|
+
const throwErr = () => { throw new Error('Please use process.env to write to env') }
|
|
24
|
+
return new Proxy(parseEnv(process.env), {
|
|
25
|
+
set: throwErr,
|
|
26
|
+
defineProperty: throwErr,
|
|
27
|
+
deleteProperty: throwErr,
|
|
28
|
+
})
|
|
29
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
//----------------------------------------
|
|
2
|
+
// ERROR UTILS
|
|
3
|
+
//----------------------------------------
|
|
4
|
+
import { dataValidationUtilErrorHandler } from "./private/error-handler"
|
|
5
|
+
import { isset } from "./isset"
|
|
6
|
+
import { isEmpty } from "./is-empty"
|
|
7
|
+
|
|
8
|
+
export function errIfNotSet(objOfVarNamesWithValues, additionalMessage) { return errXXXIfNotSet(422, false, objOfVarNamesWithValues) }
|
|
9
|
+
|
|
10
|
+
export function err500IfNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(500, false, objOfVarNamesWithValues) }
|
|
11
|
+
|
|
12
|
+
export function errIfEmptyOrNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(422, true, objOfVarNamesWithValues) }
|
|
13
|
+
|
|
14
|
+
export function err500IfEmptyOrNotSet(objOfVarNamesWithValues) { return errXXXIfNotSet(500, true, objOfVarNamesWithValues) }
|
|
15
|
+
|
|
16
|
+
export function errXXXIfNotSet(errCode, checkEmpty, objOfVarNamesWithValues) {
|
|
17
|
+
let missingVars = []
|
|
18
|
+
for (let prop in objOfVarNamesWithValues) {
|
|
19
|
+
if (!isset(objOfVarNamesWithValues[prop]) || (checkEmpty && isEmpty(objOfVarNamesWithValues[prop]))) missingVars.push(prop)
|
|
20
|
+
}
|
|
21
|
+
if (missingVars.length) throw new dataValidationUtilErrorHandler(`requiredVariableEmptyOrNotSet`, errCode, { origin: 'Validator', varNames: missingVars.join(', ') })
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
export function err422IfNotSet(o) {
|
|
26
|
+
let m = []
|
|
27
|
+
for (let p in o) if (!isset(o[p])) m.push(p)
|
|
28
|
+
if (m.length) throw new dataValidationUtilErrorHandler(`requiredVariableEmptyOrNotSet`, 422, { origin: 'Validator', varNames: m.join(', ') })
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function cleanStackTrace(stack) {
|
|
32
|
+
if (typeof stack !== 'string') return ''
|
|
33
|
+
stack.replace(/home\/[^/]+\/[^/]+\//g, '')
|
|
34
|
+
const lines = stack.split('\n')
|
|
35
|
+
const removeIfContain = [
|
|
36
|
+
'logger-utils.js',
|
|
37
|
+
'TCP.onread',
|
|
38
|
+
'readableAddChunk',
|
|
39
|
+
'Socket.EventEmitter.emit (domain.js',
|
|
40
|
+
'Socket.emit (events.js',
|
|
41
|
+
'Connection.EventEmitter.emit (domain.js',
|
|
42
|
+
'Connection.emit (events.js',
|
|
43
|
+
'Socket.Readable.push (_stream_readable',
|
|
44
|
+
'model.Query',
|
|
45
|
+
'Object.promiseOrCallback',
|
|
46
|
+
'Connection.<anonymous>',
|
|
47
|
+
'process.topLevelDomainCallback',
|
|
48
|
+
// internal
|
|
49
|
+
'internal/process',
|
|
50
|
+
'internal/timers',
|
|
51
|
+
'internal/modules',
|
|
52
|
+
'internal/main',
|
|
53
|
+
'DefaultError.throw',
|
|
54
|
+
'Object.throw',
|
|
55
|
+
'mongoose/lib/utils',
|
|
56
|
+
'at Array.forEach (<anonymous>)',
|
|
57
|
+
]
|
|
58
|
+
const linesClean = lines
|
|
59
|
+
.filter(l => !removeIfContain.some(text => l.includes(text)))
|
|
60
|
+
.map((line, i) => {
|
|
61
|
+
if (i === 0) return ''
|
|
62
|
+
else {
|
|
63
|
+
const [, start, fileName, end] = line.match(/(^.+\/)([^/]+:\d+:\d+)(.{0,3})/) || []
|
|
64
|
+
return fileName ? `\x1b[2m${start}\x1b[0m${fileName}\x1b[2m${end}\x1b[0m` : `\x1b[2m${line}\x1b[0m`
|
|
65
|
+
}
|
|
66
|
+
})
|
|
67
|
+
.join('\n')
|
|
68
|
+
return linesClean
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export async function tryCatch(callback: Function, onErr: Function = () => { }) {
|
|
72
|
+
try {
|
|
73
|
+
return await callback()
|
|
74
|
+
} catch (err) {
|
|
75
|
+
return await onErr(err)
|
|
76
|
+
}
|
|
77
|
+
}
|
package/src/is-empty.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export function isEmpty(objOrArr: object | any[] | string | null | undefined) {
|
|
2
|
+
if (Array.isArray(objOrArr) || typeof objOrArr === 'string') return objOrArr.length === 0
|
|
3
|
+
else if (typeof objOrArr == 'object' && objOrArr !== null && !(objOrArr instanceof Date)) return Object.keys(objOrArr).length === 0
|
|
4
|
+
else false
|
|
5
|
+
}
|
package/src/is-object.ts
ADDED