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