b975d0a46b30007b1212f0fc4299130284c183df
[e-mobility-charging-stations-simulator.git] / src / utils / Utils.ts
1 import Configuration from './Configuration';
2 import { WebSocketCloseEventStatusString } from '../types/WebSocket';
3 import { WorkerProcessType } from '../types/Worker';
4 import { v4 as uuid } from 'uuid';
5
6 export default class Utils {
7 static generateUUID(): string {
8 return uuid();
9 }
10
11 static async sleep(milliSeconds: number): Promise<NodeJS.Timeout> {
12 return new Promise((resolve) => setTimeout(resolve, milliSeconds));
13 }
14
15 static secondsToHHMMSS(seconds: number): string {
16 return Utils.milliSecondsToHHMMSS(seconds * 1000);
17 }
18
19 static milliSecondsToHHMMSS(milliSeconds: number): string {
20 return new Date(milliSeconds).toISOString().substr(11, 8);
21 }
22
23 static removeExtraEmptyLines(tab: string[]): void {
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
39 static convertToDate(value): Date {
40 // Check
41 if (!value) {
42 return value;
43 }
44 // Check Type
45 if (!(value instanceof Date)) {
46 return new Date(value);
47 }
48 return value;
49 }
50
51 static convertToInt(value): number {
52 let changedValue = value;
53 if (!value) {
54 return 0;
55 }
56 if (Number.isSafeInteger(value)) {
57 return value;
58 }
59 // Check
60 if (typeof value === 'string') {
61 // Create Object
62 changedValue = parseInt(value);
63 }
64 return changedValue;
65 }
66
67 static convertToFloat(value): number {
68 let changedValue = value;
69 if (!value) {
70 return 0;
71 }
72 // Check
73 if (typeof value === 'string') {
74 // Create Object
75 changedValue = parseFloat(value);
76 }
77 return changedValue;
78 }
79
80 static convertToBoolean(value): boolean {
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
96 static getRandomFloat(max: number, min = 0): number {
97 return Math.random() < 0.5 ? (1 - Math.random()) * (max - min) + min : Math.random() * (max - min) + min;
98 }
99
100 static getRandomInt(max: number, min = 0): number {
101 if (min) {
102 return Math.floor(Math.random() * (max - min + 1) + min);
103 }
104 return Math.floor(Math.random() * max + 1);
105 }
106
107 static roundTo(numberValue: number, scale: number): number {
108 const roundPower = Math.pow(10, scale);
109 return Math.round(numberValue * roundPower) / roundPower;
110 }
111
112 static truncTo(numberValue: number, scale: number): number {
113 const truncPower = Math.pow(10, scale);
114 return Math.trunc(numberValue * truncPower) / truncPower;
115 }
116
117 static getRandomFloatRounded(max: number, min = 0, scale = 2): number {
118 if (min) {
119 return Utils.roundTo(Utils.getRandomFloat(max, min), scale);
120 }
121 return Utils.roundTo(Utils.getRandomFloat(max), scale);
122 }
123
124 static logPrefix(prefixString = ''): string {
125 const date = new Date();
126 return date.toLocaleString() + prefixString;
127 }
128
129 static cloneObject<T>(object: T): T {
130 return JSON.parse(JSON.stringify(object)) as T;
131 }
132
133 static isIterable<T>(obj: T): boolean {
134 if (obj) {
135 return typeof obj[Symbol.iterator] === 'function';
136 }
137 return false;
138 }
139
140 static isEmptyJSon(document): boolean {
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
153 static isString(value): boolean {
154 return typeof value === 'string';
155 }
156
157 static isUndefined(value): boolean {
158 return typeof value === 'undefined';
159 }
160
161 static isNullOrUndefined(value): boolean {
162 // eslint-disable-next-line no-eq-null, eqeqeq
163 if (value == null) {
164 return true;
165 }
166 return false;
167 }
168
169 static isEmptyArray(object): boolean {
170 if (!object) {
171 return true;
172 }
173 if (Array.isArray(object) && object.length > 0) {
174 return false;
175 }
176 return true;
177 }
178
179 static isEmptyObject(obj): boolean {
180 return !Object.keys(obj).length;
181 }
182
183 static insertAt = (str: string, subStr: string, pos: number): string => `${str.slice(0, pos)}${subStr}${str.slice(pos)}`;
184
185 /**
186 * @param {number} [retryNumber=0]
187 * @returns {number} delay in milliseconds
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 }
194
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 */
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])) {
216 return WebSocketCloseEventStatusString[code] as string;
217 }
218 return '(Unknown)';
219 }
220
221 static workerPoolInUse(): boolean {
222 return [WorkerProcessType.DYNAMIC_POOL, WorkerProcessType.STATIC_POOL].includes(Configuration.getWorkerProcess());
223 }
224
225 static workerDynamicPoolInUse(): boolean {
226 return Configuration.getWorkerProcess() === WorkerProcessType.DYNAMIC_POOL;
227 }
228 }