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.
Files changed (102) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.d.ts +34 -0
  3. package/dist/index.js +56 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/src/array-utils.d.ts +56 -0
  6. package/dist/src/array-utils.js +138 -0
  7. package/dist/src/array-utils.js.map +1 -0
  8. package/dist/src/date-utils.d.ts +100 -0
  9. package/dist/src/date-utils.js +357 -0
  10. package/dist/src/date-utils.js.map +1 -0
  11. package/dist/src/env-utils.d.ts +8 -0
  12. package/dist/src/env-utils.js +38 -0
  13. package/dist/src/env-utils.js.map +1 -0
  14. package/dist/src/error-utils.d.ts +8 -0
  15. package/dist/src/error-utils.js +99 -0
  16. package/dist/src/error-utils.js.map +1 -0
  17. package/dist/src/is-empty.d.ts +1 -0
  18. package/dist/src/is-empty.js +13 -0
  19. package/dist/src/is-empty.js.map +1 -0
  20. package/dist/src/is-object.d.ts +2 -0
  21. package/dist/src/is-object.js +7 -0
  22. package/dist/src/is-object.js.map +1 -0
  23. package/dist/src/isset.d.ts +1 -0
  24. package/dist/src/isset.js +8 -0
  25. package/dist/src/isset.js.map +1 -0
  26. package/dist/src/logger-utils.d.ts +76 -0
  27. package/dist/src/logger-utils.js +355 -0
  28. package/dist/src/logger-utils.js.map +1 -0
  29. package/dist/src/loop-utils.d.ts +37 -0
  30. package/dist/src/loop-utils.js +105 -0
  31. package/dist/src/loop-utils.js.map +1 -0
  32. package/dist/src/math-utils.d.ts +23 -0
  33. package/dist/src/math-utils.js +43 -0
  34. package/dist/src/math-utils.js.map +1 -0
  35. package/dist/src/mongo-utils.d.ts +11 -0
  36. package/dist/src/mongo-utils.js +49 -0
  37. package/dist/src/mongo-utils.js.map +1 -0
  38. package/dist/src/object-utils.d.ts +96 -0
  39. package/dist/src/object-utils.js +369 -0
  40. package/dist/src/object-utils.js.map +1 -0
  41. package/dist/src/private/config.d.ts +44 -0
  42. package/dist/src/private/config.js +55 -0
  43. package/dist/src/private/config.js.map +1 -0
  44. package/dist/src/private/error-handler.d.ts +10 -0
  45. package/dist/src/private/error-handler.js +18 -0
  46. package/dist/src/private/error-handler.js.map +1 -0
  47. package/dist/src/private/types.d.ts +4 -0
  48. package/dist/src/private/types.js +3 -0
  49. package/dist/src/private/types.js.map +1 -0
  50. package/dist/src/regexp-utils.d.ts +12 -0
  51. package/dist/src/regexp-utils.js +44 -0
  52. package/dist/src/regexp-utils.js.map +1 -0
  53. package/dist/src/remove-circular-json-stringify.d.ts +1 -0
  54. package/dist/src/remove-circular-json-stringify.js +20 -0
  55. package/dist/src/remove-circular-json-stringify.js.map +1 -0
  56. package/dist/src/string-utils.d.ts +77 -0
  57. package/dist/src/string-utils.js +209 -0
  58. package/dist/src/string-utils.js.map +1 -0
  59. package/dist/src/tests-utils.js +77 -0
  60. package/dist/src/tests-utils.js.map +1 -0
  61. package/dist/src/timer-utils.d.ts +16 -0
  62. package/dist/src/timer-utils.js +79 -0
  63. package/dist/src/timer-utils.js.map +1 -0
  64. package/dist/src/transaction-utils.d.ts +14 -0
  65. package/dist/src/transaction-utils.js +87 -0
  66. package/dist/src/transaction-utils.js.map +1 -0
  67. package/dist/src/validation-utils.d.ts +89 -0
  68. package/dist/src/validation-utils.js +192 -0
  69. package/dist/src/validation-utils.js.map +1 -0
  70. package/dist/src/wtf-utils.d.ts +7 -0
  71. package/dist/src/wtf-utils.js +83 -0
  72. package/dist/src/wtf-utils.js.map +1 -0
  73. package/index.ts +38 -0
  74. package/package.json +2 -2
  75. package/src/array-utils.ts +128 -0
  76. package/src/date-utils.ts +377 -0
  77. package/src/env-utils.ts +29 -0
  78. package/src/error-utils.ts +77 -0
  79. package/src/is-empty.ts +5 -0
  80. package/src/is-object.ts +3 -0
  81. package/src/isset.ts +3 -0
  82. package/src/logger-utils.ts +349 -0
  83. package/src/loop-utils.ts +101 -0
  84. package/src/math-utils.ts +38 -0
  85. package/src/mongo-utils.ts +38 -0
  86. package/src/object-utils.ts +356 -0
  87. package/src/private/config.ts +85 -0
  88. package/src/private/error-handler.ts +21 -0
  89. package/src/private/types.ts +6 -0
  90. package/src/regexp-utils.ts +37 -0
  91. package/src/remove-circular-json-stringify.ts +17 -0
  92. package/src/string-utils.ts +212 -0
  93. package/src/tests-utils.ts +70 -0
  94. package/src/timer-utils.ts +58 -0
  95. package/src/transaction-utils.ts +63 -0
  96. package/src/validation-utils.ts +253 -0
  97. package/src/wtf-utils.ts +88 -0
  98. package/tsconfig.json +11 -4
  99. package/utils.d.ts +0 -694
  100. package/utils.js +0 -2227
  101. package/utils.js.map +0 -1
  102. 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.0.60",
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": "./utils.js",
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
+ }
@@ -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
+ }
@@ -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
+ }
@@ -0,0 +1,3 @@
1
+
2
+ /** test if object but not array and not null (null is an object in Js) */
3
+ export function isObject(o: any): boolean { return o instanceof Object && [Object, Error].includes(o.constructor) }