Commit | Line | Data |
---|---|---|
a4624c96 | 1 | import Configuration from './Configuration'; |
32a1eb7a | 2 | import { WebSocketCloseEventStatusString } from '../types/WebSocket'; |
a4624c96 | 3 | import { WorkerProcessType } from '../types/Worker'; |
6af9012e | 4 | import { v4 as uuid } from 'uuid'; |
7dde0b73 | 5 | |
3f40bc9c | 6 | export default class Utils { |
147d0e0f JB |
7 | static logPrefix(prefixString = ''): string { |
8 | return new Date().toLocaleString() + prefixString; | |
9 | } | |
10 | ||
6af9012e | 11 | static generateUUID(): string { |
2e3ac96d | 12 | return uuid(); |
7dde0b73 JB |
13 | } |
14 | ||
9ac86a7e JB |
15 | static async sleep(milliSeconds: number): Promise<NodeJS.Timeout> { |
16 | return new Promise((resolve) => setTimeout(resolve, milliSeconds)); | |
7dde0b73 JB |
17 | } |
18 | ||
9ac86a7e | 19 | static secondsToHHMMSS(seconds: number): string { |
a9dc13ad | 20 | return Utils.milliSecondsToHHMMSS(seconds * 1000); |
9ac86a7e JB |
21 | } |
22 | ||
23 | static milliSecondsToHHMMSS(milliSeconds: number): string { | |
24 | return new Date(milliSeconds).toISOString().substr(11, 8); | |
7dde0b73 JB |
25 | } |
26 | ||
ca64a820 | 27 | static removeExtraEmptyLines(tab: string[]): void { |
7dde0b73 JB |
28 | // Start from the end |
29 | for (let i = tab.length - 1; i > 0; i--) { | |
30 | // Two consecutive empty lines? | |
31 | if (tab[i].length === 0 && tab[i - 1].length === 0) { | |
32 | // Remove the last one | |
33 | tab.splice(i, 1); | |
34 | } | |
35 | // Check last line | |
36 | if (i === 1 && tab[i - 1].length === 0) { | |
37 | // Remove the first one | |
38 | tab.splice(i - 1, 1); | |
39 | } | |
40 | } | |
41 | } | |
42 | ||
6e0964c8 | 43 | static convertToDate(value: any): Date { |
560bcf5b | 44 | // Check |
6af9012e JB |
45 | if (!value) { |
46 | return value; | |
560bcf5b JB |
47 | } |
48 | // Check Type | |
6af9012e JB |
49 | if (!(value instanceof Date)) { |
50 | return new Date(value); | |
7dde0b73 | 51 | } |
6af9012e | 52 | return value; |
7dde0b73 JB |
53 | } |
54 | ||
6e0964c8 | 55 | static convertToInt(value: any): number { |
72766a82 JB |
56 | let changedValue = value; |
57 | if (!value) { | |
7dde0b73 JB |
58 | return 0; |
59 | } | |
72766a82 JB |
60 | if (Number.isSafeInteger(value)) { |
61 | return value; | |
62 | } | |
7dde0b73 | 63 | // Check |
087a502d | 64 | if (Utils.isString(value)) { |
7dde0b73 | 65 | // Create Object |
72766a82 | 66 | changedValue = parseInt(value); |
7dde0b73 | 67 | } |
72766a82 | 68 | return changedValue; |
7dde0b73 JB |
69 | } |
70 | ||
6e0964c8 | 71 | static convertToFloat(value: any): number { |
72766a82 JB |
72 | let changedValue = value; |
73 | if (!value) { | |
7dde0b73 JB |
74 | return 0; |
75 | } | |
76 | // Check | |
087a502d | 77 | if (Utils.isString(value)) { |
7dde0b73 | 78 | // Create Object |
72766a82 | 79 | changedValue = parseFloat(value); |
7dde0b73 | 80 | } |
72766a82 | 81 | return changedValue; |
7dde0b73 JB |
82 | } |
83 | ||
6e0964c8 | 84 | static convertToBoolean(value: any): boolean { |
a6e68f34 JB |
85 | let result = false; |
86 | // Check boolean | |
87 | if (value) { | |
88 | // Check the type | |
89 | if (typeof value === 'boolean') { | |
90 | // Already a boolean | |
91 | result = value; | |
92 | } else { | |
93 | // Convert | |
94 | result = (value === 'true'); | |
95 | } | |
96 | } | |
97 | return result; | |
98 | } | |
99 | ||
6af9012e | 100 | static getRandomFloat(max: number, min = 0): number { |
fee83021 | 101 | return Math.random() < 0.5 ? (1 - Math.random()) * (max - min) + min : Math.random() * (max - min) + min; |
560bcf5b JB |
102 | } |
103 | ||
6af9012e | 104 | static getRandomInt(max: number, min = 0): number { |
7dde0b73 | 105 | if (min) { |
fee83021 | 106 | return Math.floor(Math.random() * (max - min + 1) + min); |
7dde0b73 | 107 | } |
fee83021 | 108 | return Math.floor(Math.random() * max + 1); |
560bcf5b JB |
109 | } |
110 | ||
035742f7 | 111 | static roundTo(numberValue: number, scale: number): number { |
ad3de6c4 | 112 | const roundPower = Math.pow(10, scale); |
035742f7 | 113 | return Math.round(numberValue * roundPower) / roundPower; |
560bcf5b JB |
114 | } |
115 | ||
035742f7 | 116 | static truncTo(numberValue: number, scale: number): number { |
6d3a11a0 | 117 | const truncPower = Math.pow(10, scale); |
035742f7 | 118 | return Math.trunc(numberValue * truncPower) / truncPower; |
6d3a11a0 JB |
119 | } |
120 | ||
6af9012e | 121 | static getRandomFloatRounded(max: number, min = 0, scale = 2): number { |
560bcf5b JB |
122 | if (min) { |
123 | return Utils.roundTo(Utils.getRandomFloat(max, min), scale); | |
124 | } | |
125 | return Utils.roundTo(Utils.getRandomFloat(max), scale); | |
7dde0b73 JB |
126 | } |
127 | ||
9ccca265 JB |
128 | static getRandomFloatFluctuatedRounded(staticValue: number, fluctuationPercent: number, scale = 2): number { |
129 | if (fluctuationPercent === 0) { | |
130 | return Utils.roundTo(staticValue, scale); | |
131 | } | |
97ef739c JB |
132 | const fluctuationRatio = fluctuationPercent / 100; |
133 | return Utils.getRandomFloatRounded(staticValue * (1 + fluctuationRatio), staticValue * (1 - fluctuationRatio), scale); | |
9ccca265 JB |
134 | } |
135 | ||
e56aa9a4 JB |
136 | static cloneObject<T>(object: T): T { |
137 | return JSON.parse(JSON.stringify(object)) as T; | |
2e6f5966 | 138 | } |
facd8ebd | 139 | |
81696bd5 | 140 | static isIterable<T>(obj: T): boolean { |
67e9cccf JB |
141 | if (obj) { |
142 | return typeof obj[Symbol.iterator] === 'function'; | |
143 | } | |
144 | return false; | |
145 | } | |
146 | ||
6e0964c8 | 147 | static isEmptyJSon(document: any): boolean { |
67e9cccf JB |
148 | // Empty? |
149 | if (!document) { | |
150 | return true; | |
151 | } | |
152 | // Check type | |
153 | if (typeof document !== 'object') { | |
154 | return true; | |
155 | } | |
156 | // Check | |
157 | return Object.keys(document).length === 0; | |
158 | } | |
159 | ||
6e0964c8 | 160 | static isString(value: any): boolean { |
560bcf5b JB |
161 | return typeof value === 'string'; |
162 | } | |
163 | ||
6e0964c8 | 164 | static isUndefined(value: any): boolean { |
ead548f2 JB |
165 | return typeof value === 'undefined'; |
166 | } | |
167 | ||
6e0964c8 | 168 | static isNullOrUndefined(value: any): boolean { |
32a1eb7a | 169 | // eslint-disable-next-line no-eq-null, eqeqeq |
ead548f2 | 170 | if (value == null) { |
facd8ebd JB |
171 | return true; |
172 | } | |
173 | return false; | |
174 | } | |
4a56deef | 175 | |
6e0964c8 | 176 | static isEmptyArray(object: any): boolean { |
fd1ee77c JB |
177 | if (!object) { |
178 | return true; | |
179 | } | |
4a56deef JB |
180 | if (Array.isArray(object) && object.length > 0) { |
181 | return false; | |
182 | } | |
183 | return true; | |
184 | } | |
7abfea5f | 185 | |
6e0964c8 | 186 | static isEmptyObject(obj: any): boolean { |
7abfea5f JB |
187 | return !Object.keys(obj).length; |
188 | } | |
7ec46a9a JB |
189 | |
190 | static insertAt = (str: string, subStr: string, pos: number): string => `${str.slice(0, pos)}${subStr}${str.slice(pos)}`; | |
032d6efc JB |
191 | |
192 | /** | |
e71cccf3 JB |
193 | * @param {number} [retryNumber=0] |
194 | * @returns {number} delay in milliseconds | |
032d6efc JB |
195 | */ |
196 | static exponentialDelay(retryNumber = 0): number { | |
197 | const delay = Math.pow(2, retryNumber) * 100; | |
198 | const randomSum = delay * 0.2 * Math.random(); // 0-20% of the delay | |
199 | return delay + randomSum; | |
200 | } | |
32a1eb7a | 201 | |
e71cccf3 JB |
202 | /** |
203 | * Convert websocket error code to human readable string message | |
204 | * | |
205 | * @param {number} code websocket error code | |
206 | * @returns {string} human readable string message | |
207 | */ | |
32a1eb7a JB |
208 | static getWebSocketCloseEventStatusString(code: number): string { |
209 | if (code >= 0 && code <= 999) { | |
210 | return '(Unused)'; | |
211 | } else if (code >= 1016) { | |
212 | if (code <= 1999) { | |
213 | return '(For WebSocket standard)'; | |
214 | } else if (code <= 2999) { | |
215 | return '(For WebSocket extensions)'; | |
216 | } else if (code <= 3999) { | |
217 | return '(For libraries and frameworks)'; | |
218 | } else if (code <= 4999) { | |
219 | return '(For applications)'; | |
220 | } | |
221 | } | |
222 | if (!Utils.isUndefined(WebSocketCloseEventStatusString[code])) { | |
17991e8c | 223 | return WebSocketCloseEventStatusString[code] as string; |
32a1eb7a JB |
224 | } |
225 | return '(Unknown)'; | |
226 | } | |
a4624c96 JB |
227 | |
228 | static workerPoolInUse(): boolean { | |
9ab7950c | 229 | return [WorkerProcessType.DYNAMIC_POOL, WorkerProcessType.STATIC_POOL].includes(Configuration.getWorkerProcess()); |
a4624c96 | 230 | } |
059f35a5 JB |
231 | |
232 | static workerDynamicPoolInUse(): boolean { | |
233 | return Configuration.getWorkerProcess() === WorkerProcessType.DYNAMIC_POOL; | |
234 | } | |
7dde0b73 | 235 | } |