refactor: syntax check in worker configuration section
[e-mobility-charging-stations-simulator.git] / src / utils / Configuration.ts
CommitLineData
d972af76
JB
1import { type FSWatcher, readFileSync, watch } from 'node:fs';
2import { dirname, join, resolve } from 'node:path';
130783a7 3import { fileURLToPath } from 'node:url';
8114d10e
JB
4
5import chalk from 'chalk';
088ee3c1 6import merge from 'just-merge';
8114d10e 7
878e026c 8import { Constants } from './Constants';
9bf0ef23 9import { hasOwnProp, isCFEnvironment, isNotEmptyString, isUndefined } from './Utils';
83e00df1 10import {
268a74bb 11 ApplicationProtocol,
83e00df1 12 type ConfigurationData,
268a74bb 13 FileType,
3d48c1c1 14 type LogConfiguration,
83e00df1
JB
15 type StationTemplateUrl,
16 type StorageConfiguration,
268a74bb 17 StorageType,
e7aeea18 18 SupervisionUrlDistribution,
83e00df1
JB
19 type UIServerConfiguration,
20 type WorkerConfiguration,
268a74bb
JB
21} from '../types';
22import { WorkerConstants, WorkerProcessType } from '../worker';
7dde0b73 23
268a74bb 24export class Configuration {
d972af76
JB
25 private static configurationFile = join(
26 dirname(fileURLToPath(import.meta.url)),
e7aeea18 27 'assets',
5edd8ba0 28 'config.json',
e7aeea18 29 );
10068088 30
d972af76 31 private static configurationFileWatcher: FSWatcher | undefined;
6e0964c8 32 private static configuration: ConfigurationData | null = null;
e57acf6a
JB
33 private static configurationChangeCallback: () => Promise<void>;
34
d5bd1c00
JB
35 private constructor() {
36 // This is intentional
37 }
38
aa7d6d95 39 public static setConfigurationChangeCallback(cb: () => Promise<void>): void {
e57acf6a
JB
40 Configuration.configurationChangeCallback = cb;
41 }
7dde0b73 42
aa7d6d95 43 public static getUIServer(): UIServerConfiguration {
9bf0ef23 44 if (hasOwnProp(Configuration.getConfig(), 'uiWebSocketServer')) {
66271092 45 console.error(
c5e52a07 46 `${chalk.green(Configuration.logPrefix())} ${chalk.red(
5edd8ba0
JB
47 "Deprecated configuration section 'uiWebSocketServer' usage. Use 'uiServer' instead",
48 )}`,
66271092
JB
49 );
50 }
675fa8e3 51 let uiServerConfiguration: UIServerConfiguration = {
b803eefa 52 enabled: false,
1f7fa4de 53 type: ApplicationProtocol.WS,
c127bd64 54 options: {
adbddcb4
JB
55 host: Constants.DEFAULT_UI_SERVER_HOST,
56 port: Constants.DEFAULT_UI_SERVER_PORT,
c127bd64 57 },
6a49ad23 58 };
9bf0ef23 59 if (hasOwnProp(Configuration.getConfig(), 'uiServer')) {
598c886d
JB
60 uiServerConfiguration = merge<UIServerConfiguration>(
61 uiServerConfiguration,
e1d9a0f4 62 Configuration.getConfig()!.uiServer!,
598c886d 63 );
6a49ad23 64 }
9bf0ef23 65 if (isCFEnvironment() === true) {
72092cfc 66 delete uiServerConfiguration.options?.host;
e1d9a0f4 67 uiServerConfiguration.options!.port = parseInt(process.env.PORT!);
b803eefa 68 }
675fa8e3 69 return uiServerConfiguration;
6a49ad23
JB
70 }
71
aa7d6d95 72 public static getPerformanceStorage(): StorageConfiguration {
e7aeea18 73 Configuration.warnDeprecatedConfigurationKey('URI', 'performanceStorage', "Use 'uri' instead");
6a49ad23
JB
74 let storageConfiguration: StorageConfiguration = {
75 enabled: false,
76 type: StorageType.JSON_FILE,
e7aeea18 77 uri: this.getDefaultPerformanceStorageUri(StorageType.JSON_FILE),
6a49ad23 78 };
9bf0ef23 79 if (hasOwnProp(Configuration.getConfig(), 'performanceStorage')) {
e7aeea18 80 storageConfiguration = {
1ba1e8fb 81 ...storageConfiguration,
1895299d 82 ...Configuration.getConfig()?.performanceStorage,
f682b2dc
JB
83 ...(Configuration.getConfig()?.performanceStorage?.type === StorageType.JSON_FILE &&
84 Configuration.getConfig()?.performanceStorage?.uri && {
e8044a69 85 uri: Configuration.buildPerformanceUriFilePath(
e1d9a0f4 86 new URL(Configuration.getConfig()!.performanceStorage!.uri!).pathname,
e8044a69 87 ),
f682b2dc 88 }),
72f041bd 89 };
72f041bd
JB
90 }
91 return storageConfiguration;
7dde0b73
JB
92 }
93
aa7d6d95 94 public static getAutoReconnectMaxRetries(): number | undefined {
e7aeea18
JB
95 Configuration.warnDeprecatedConfigurationKey(
96 'autoReconnectTimeout',
1895299d 97 undefined,
5edd8ba0 98 "Use 'ConnectionTimeOut' OCPP parameter in charging station template instead",
e7aeea18
JB
99 );
100 Configuration.warnDeprecatedConfigurationKey(
101 'connectionTimeout',
1895299d 102 undefined,
5edd8ba0 103 "Use 'ConnectionTimeOut' OCPP parameter in charging station template instead",
e7aeea18
JB
104 );
105 Configuration.warnDeprecatedConfigurationKey(
106 'autoReconnectMaxRetries',
1895299d 107 undefined,
5edd8ba0 108 'Use it in charging station template instead',
e7aeea18 109 );
7dde0b73 110 // Read conf
9bf0ef23 111 if (hasOwnProp(Configuration.getConfig(), 'autoReconnectMaxRetries')) {
1895299d 112 return Configuration.getConfig()?.autoReconnectMaxRetries;
3574dfd3 113 }
7dde0b73
JB
114 }
115
aa7d6d95 116 public static getStationTemplateUrls(): StationTemplateUrl[] | undefined {
e7aeea18
JB
117 Configuration.warnDeprecatedConfigurationKey(
118 'stationTemplateURLs',
1895299d 119 undefined,
5edd8ba0 120 "Use 'stationTemplateUrls' instead",
e7aeea18 121 );
e1d9a0f4
JB
122 // eslint-disable-next-line @typescript-eslint/dot-notation
123 !isUndefined(Configuration.getConfig()!['stationTemplateURLs']) &&
124 (Configuration.getConfig()!.stationTemplateUrls = Configuration.getConfig()![
125 // eslint-disable-next-line @typescript-eslint/dot-notation
e7aeea18 126 'stationTemplateURLs'
617cad0c 127 ] as StationTemplateUrl[]);
e1d9a0f4 128 Configuration.getConfig()!.stationTemplateUrls.forEach(
7436ee0d 129 (stationTemplateUrl: StationTemplateUrl) => {
e1d9a0f4 130 // eslint-disable-next-line @typescript-eslint/dot-notation
9bf0ef23 131 if (!isUndefined(stationTemplateUrl['numberOfStation'])) {
7436ee0d 132 console.error(
c5e52a07 133 `${chalk.green(Configuration.logPrefix())} ${chalk.red(
5edd8ba0
JB
134 `Deprecated configuration key 'numberOfStation' usage for template file '${stationTemplateUrl.file}' in 'stationTemplateUrls'. Use 'numberOfStations' instead`,
135 )}`,
7436ee0d
JB
136 );
137 }
5edd8ba0 138 },
7436ee0d 139 );
7dde0b73 140 // Read conf
1895299d 141 return Configuration.getConfig()?.stationTemplateUrls;
7dde0b73
JB
142 }
143
3d48c1c1
JB
144 public static getLog(): LogConfiguration {
145 Configuration.warnDeprecatedConfigurationKey(
146 'logEnabled',
147 undefined,
5edd8ba0 148 "Use 'log' section to define the logging enablement instead",
3d48c1c1
JB
149 );
150 Configuration.warnDeprecatedConfigurationKey(
151 'logFile',
152 undefined,
5edd8ba0 153 "Use 'log' section to define the log file instead",
3d48c1c1
JB
154 );
155 Configuration.warnDeprecatedConfigurationKey(
156 'logErrorFile',
157 undefined,
5edd8ba0 158 "Use 'log' section to define the log error file instead",
3d48c1c1
JB
159 );
160 Configuration.warnDeprecatedConfigurationKey(
161 'logConsole',
162 undefined,
5edd8ba0 163 "Use 'log' section to define the console logging enablement instead",
3d48c1c1
JB
164 );
165 Configuration.warnDeprecatedConfigurationKey(
166 'logStatisticsInterval',
167 undefined,
5edd8ba0 168 "Use 'log' section to define the log statistics interval instead",
3d48c1c1
JB
169 );
170 Configuration.warnDeprecatedConfigurationKey(
171 'logLevel',
172 undefined,
5edd8ba0 173 "Use 'log' section to define the log level instead",
3d48c1c1
JB
174 );
175 Configuration.warnDeprecatedConfigurationKey(
176 'logFormat',
177 undefined,
5edd8ba0 178 "Use 'log' section to define the log format instead",
3d48c1c1
JB
179 );
180 Configuration.warnDeprecatedConfigurationKey(
181 'logRotate',
182 undefined,
5edd8ba0 183 "Use 'log' section to define the log rotation enablement instead",
3d48c1c1
JB
184 );
185 Configuration.warnDeprecatedConfigurationKey(
186 'logMaxFiles',
187 undefined,
5edd8ba0 188 "Use 'log' section to define the log maximum files instead",
3d48c1c1
JB
189 );
190 Configuration.warnDeprecatedConfigurationKey(
191 'logMaxSize',
192 undefined,
5edd8ba0 193 "Use 'log' section to define the log maximum size instead",
3d48c1c1
JB
194 );
195 const defaultLogConfiguration: LogConfiguration = {
196 enabled: true,
197 file: 'logs/combined.log',
198 errorFile: 'logs/error.log',
199 statisticsInterval: Constants.DEFAULT_LOG_STATISTICS_INTERVAL,
200 level: 'info',
201 format: 'simple',
202 rotate: true,
203 };
204 const deprecatedLogConfiguration: LogConfiguration = {
9bf0ef23 205 ...(hasOwnProp(Configuration.getConfig(), 'logEnabled') && {
3d48c1c1
JB
206 enabled: Configuration.getConfig()?.logEnabled,
207 }),
9bf0ef23 208 ...(hasOwnProp(Configuration.getConfig(), 'logFile') && {
3d48c1c1
JB
209 file: Configuration.getConfig()?.logFile,
210 }),
9bf0ef23 211 ...(hasOwnProp(Configuration.getConfig(), 'logErrorFile') && {
3d48c1c1
JB
212 errorFile: Configuration.getConfig()?.logErrorFile,
213 }),
9bf0ef23 214 ...(hasOwnProp(Configuration.getConfig(), 'logStatisticsInterval') && {
3d48c1c1
JB
215 statisticsInterval: Configuration.getConfig()?.logStatisticsInterval,
216 }),
9bf0ef23 217 ...(hasOwnProp(Configuration.getConfig(), 'logLevel') && {
3d48c1c1
JB
218 level: Configuration.getConfig()?.logLevel,
219 }),
9bf0ef23 220 ...(hasOwnProp(Configuration.getConfig(), 'logConsole') && {
3d48c1c1
JB
221 console: Configuration.getConfig()?.logConsole,
222 }),
9bf0ef23 223 ...(hasOwnProp(Configuration.getConfig(), 'logFormat') && {
3d48c1c1
JB
224 format: Configuration.getConfig()?.logFormat,
225 }),
9bf0ef23 226 ...(hasOwnProp(Configuration.getConfig(), 'logRotate') && {
3d48c1c1
JB
227 rotate: Configuration.getConfig()?.logRotate,
228 }),
9bf0ef23 229 ...(hasOwnProp(Configuration.getConfig(), 'logMaxFiles') && {
3d48c1c1
JB
230 maxFiles: Configuration.getConfig()?.logMaxFiles,
231 }),
9bf0ef23 232 ...(hasOwnProp(Configuration.getConfig(), 'logMaxSize') && {
3d48c1c1
JB
233 maxSize: Configuration.getConfig()?.logMaxSize,
234 }),
235 };
236 const logConfiguration: LogConfiguration = {
237 ...defaultLogConfiguration,
238 ...deprecatedLogConfiguration,
9bf0ef23 239 ...(hasOwnProp(Configuration.getConfig(), 'log') && Configuration.getConfig()?.log),
3d48c1c1
JB
240 };
241 return logConfiguration;
242 }
243
aa7d6d95 244 public static getWorker(): WorkerConfiguration {
e7aeea18 245 Configuration.warnDeprecatedConfigurationKey(
e80bc579 246 'useWorkerPool',
1895299d 247 undefined,
5edd8ba0 248 "Use 'worker' section to define the type of worker process model instead",
cf2a5d9b
JB
249 );
250 Configuration.warnDeprecatedConfigurationKey(
251 'workerProcess',
1895299d 252 undefined,
5edd8ba0 253 "Use 'worker' section to define the type of worker process model instead",
cf2a5d9b
JB
254 );
255 Configuration.warnDeprecatedConfigurationKey(
256 'workerStartDelay',
1895299d 257 undefined,
5edd8ba0 258 "Use 'worker' section to define the worker start delay instead",
cf2a5d9b
JB
259 );
260 Configuration.warnDeprecatedConfigurationKey(
261 'chargingStationsPerWorker',
1895299d 262 undefined,
5edd8ba0 263 "Use 'worker' section to define the number of element(s) per worker instead",
cf2a5d9b
JB
264 );
265 Configuration.warnDeprecatedConfigurationKey(
266 'elementStartDelay',
1895299d 267 undefined,
5edd8ba0 268 "Use 'worker' section to define the worker's element start delay instead",
cf2a5d9b
JB
269 );
270 Configuration.warnDeprecatedConfigurationKey(
271 'workerPoolMinSize',
1895299d 272 undefined,
5edd8ba0 273 "Use 'worker' section to define the worker pool minimum size instead",
e7aeea18 274 );
e7aeea18
JB
275 Configuration.warnDeprecatedConfigurationKey(
276 'workerPoolSize;',
1895299d 277 undefined,
5edd8ba0 278 "Use 'worker' section to define the worker pool maximum size instead",
e7aeea18 279 );
cf2a5d9b
JB
280 Configuration.warnDeprecatedConfigurationKey(
281 'workerPoolMaxSize;',
1895299d 282 undefined,
5edd8ba0 283 "Use 'worker' section to define the worker pool maximum size instead",
cf2a5d9b
JB
284 );
285 Configuration.warnDeprecatedConfigurationKey(
286 'workerPoolStrategy;',
1895299d 287 undefined,
5edd8ba0 288 "Use 'worker' section to define the worker pool strategy instead",
cf2a5d9b 289 );
3d48c1c1
JB
290 const defaultWorkerConfiguration: WorkerConfiguration = {
291 processType: WorkerProcessType.workerSet,
292 startDelay: WorkerConstants.DEFAULT_WORKER_START_DELAY,
8603c1ca 293 elementsPerWorker: 'auto',
3d48c1c1
JB
294 elementStartDelay: WorkerConstants.DEFAULT_ELEMENT_START_DELAY,
295 poolMinSize: WorkerConstants.DEFAULT_POOL_MIN_SIZE,
296 poolMaxSize: WorkerConstants.DEFAULT_POOL_MAX_SIZE,
3d48c1c1 297 };
eda9c451
JB
298 hasOwnProp(Configuration.getConfig(), 'workerPoolStrategy') &&
299 delete Configuration.getConfig()?.workerPoolStrategy;
3d48c1c1 300 const deprecatedWorkerConfiguration: WorkerConfiguration = {
9bf0ef23 301 ...(hasOwnProp(Configuration.getConfig(), 'workerProcess') && {
3d48c1c1
JB
302 processType: Configuration.getConfig()?.workerProcess,
303 }),
9bf0ef23 304 ...(hasOwnProp(Configuration.getConfig(), 'workerStartDelay') && {
3d48c1c1
JB
305 startDelay: Configuration.getConfig()?.workerStartDelay,
306 }),
9bf0ef23 307 ...(hasOwnProp(Configuration.getConfig(), 'chargingStationsPerWorker') && {
3d48c1c1
JB
308 elementsPerWorker: Configuration.getConfig()?.chargingStationsPerWorker,
309 }),
9bf0ef23 310 ...(hasOwnProp(Configuration.getConfig(), 'elementStartDelay') && {
3d48c1c1
JB
311 elementStartDelay: Configuration.getConfig()?.elementStartDelay,
312 }),
9bf0ef23 313 ...(hasOwnProp(Configuration.getConfig(), 'workerPoolMinSize') && {
3d48c1c1
JB
314 poolMinSize: Configuration.getConfig()?.workerPoolMinSize,
315 }),
9bf0ef23 316 ...(hasOwnProp(Configuration.getConfig(), 'workerPoolMaxSize') && {
3d48c1c1
JB
317 poolMaxSize: Configuration.getConfig()?.workerPoolMaxSize,
318 }),
3d48c1c1 319 };
eda9c451
JB
320 Configuration.warnDeprecatedConfigurationKey(
321 'poolStrategy',
322 'worker',
323 'Not publicly exposed to end users',
324 );
3d48c1c1
JB
325 const workerConfiguration: WorkerConfiguration = {
326 ...defaultWorkerConfiguration,
327 ...deprecatedWorkerConfiguration,
9bf0ef23 328 ...(hasOwnProp(Configuration.getConfig(), 'worker') && Configuration.getConfig()?.worker),
cf2a5d9b 329 };
b5b2c3e8
JB
330 if (!Object.values(WorkerProcessType).includes(workerConfiguration.processType!)) {
331 throw new SyntaxError(
332 `Invalid worker process type '${workerConfiguration.processType}' defined in configuration`,
333 );
334 }
cf2a5d9b 335 return workerConfiguration;
3d2ff9e4
J
336 }
337
aa7d6d95
JB
338 public static workerPoolInUse(): boolean {
339 return [WorkerProcessType.dynamicPool, WorkerProcessType.staticPool].includes(
e1d9a0f4 340 Configuration.getWorker().processType!,
aa7d6d95
JB
341 );
342 }
343
344 public static workerDynamicPoolInUse(): boolean {
345 return Configuration.getWorker().processType === WorkerProcessType.dynamicPool;
346 }
347
aa7d6d95 348 public static getSupervisionUrls(): string | string[] | undefined {
e7aeea18
JB
349 Configuration.warnDeprecatedConfigurationKey(
350 'supervisionURLs',
1895299d 351 undefined,
5edd8ba0 352 "Use 'supervisionUrls' instead",
e7aeea18 353 );
e1d9a0f4
JB
354 // eslint-disable-next-line @typescript-eslint/dot-notation
355 if (!isUndefined(Configuration.getConfig()!['supervisionURLs'])) {
356 // eslint-disable-next-line @typescript-eslint/dot-notation
357 Configuration.getConfig()!.supervisionUrls = Configuration.getConfig()!['supervisionURLs'] as
1895299d 358 | string
e1d9a0f4
JB
359 | string[];
360 }
7dde0b73 361 // Read conf
1895299d 362 return Configuration.getConfig()?.supervisionUrls;
7dde0b73
JB
363 }
364
aa7d6d95 365 public static getSupervisionUrlDistribution(): SupervisionUrlDistribution | undefined {
e7aeea18
JB
366 Configuration.warnDeprecatedConfigurationKey(
367 'distributeStationToTenantEqually',
1895299d 368 undefined,
5edd8ba0 369 "Use 'supervisionUrlDistribution' instead",
e7aeea18
JB
370 );
371 Configuration.warnDeprecatedConfigurationKey(
372 'distributeStationsToTenantsEqually',
1895299d 373 undefined,
5edd8ba0 374 "Use 'supervisionUrlDistribution' instead",
e7aeea18 375 );
9bf0ef23 376 return hasOwnProp(Configuration.getConfig(), 'supervisionUrlDistribution')
1895299d 377 ? Configuration.getConfig()?.supervisionUrlDistribution
e7aeea18 378 : SupervisionUrlDistribution.ROUND_ROBIN;
7dde0b73 379 }
eb3937cb 380
8b7072dc 381 private static logPrefix = (): string => {
14ecae6a 382 return `${new Date().toLocaleString()} Simulator configuration |`;
8b7072dc 383 };
23132a44 384
e7aeea18
JB
385 private static warnDeprecatedConfigurationKey(
386 key: string,
387 sectionName?: string,
5edd8ba0 388 logMsgToAppend = '',
e7aeea18 389 ) {
e7aeea18
JB
390 if (
391 sectionName &&
e1d9a0f4 392 !isUndefined(Configuration.getConfig()![sectionName]) &&
d149310f 393 !isUndefined((Configuration.getConfig()![sectionName] as Record<string, unknown>)[key])
e7aeea18
JB
394 ) {
395 console.error(
c5e52a07
JB
396 `${chalk.green(Configuration.logPrefix())} ${chalk.red(
397 `Deprecated configuration key '${key}' usage in section '${sectionName}'${
398 logMsgToAppend.trim().length > 0 ? `. ${logMsgToAppend}` : ''
5edd8ba0
JB
399 }`,
400 )}`,
e7aeea18 401 );
e1d9a0f4 402 } else if (!isUndefined(Configuration.getConfig()![key])) {
e7aeea18 403 console.error(
c5e52a07
JB
404 `${chalk.green(Configuration.logPrefix())} ${chalk.red(
405 `Deprecated configuration key '${key}' usage${
406 logMsgToAppend.trim().length > 0 ? `. ${logMsgToAppend}` : ''
5edd8ba0
JB
407 }`,
408 )}`,
e7aeea18 409 );
eb3937cb
JB
410 }
411 }
412
413 // Read the config file
1895299d 414 private static getConfig(): ConfigurationData | null {
eb3937cb 415 if (!Configuration.configuration) {
23132a44 416 try {
e7aeea18 417 Configuration.configuration = JSON.parse(
5edd8ba0 418 readFileSync(Configuration.configurationFile, 'utf8'),
e7aeea18 419 ) as ConfigurationData;
23132a44 420 } catch (error) {
69074173 421 Configuration.handleFileException(
a95873d8 422 Configuration.configurationFile,
7164966d
JB
423 FileType.Configuration,
424 error as NodeJS.ErrnoException,
5edd8ba0 425 Configuration.logPrefix(),
e7aeea18 426 );
23132a44 427 }
ded13d97
JB
428 if (!Configuration.configurationFileWatcher) {
429 Configuration.configurationFileWatcher = Configuration.getConfigurationFileWatcher();
430 }
eb3937cb
JB
431 }
432 return Configuration.configuration;
433 }
963ee397 434
d972af76 435 private static getConfigurationFileWatcher(): FSWatcher | undefined {
23132a44 436 try {
d972af76 437 return watch(Configuration.configurationFile, (event, filename): void => {
e1d9a0f4 438 if (filename!.trim()!.length > 0 && event === 'change') {
3ec10737
JB
439 // Nullify to force configuration file reading
440 Configuration.configuration = null;
9bf0ef23 441 if (!isUndefined(Configuration.configurationChangeCallback)) {
72092cfc 442 Configuration.configurationChangeCallback().catch((error) => {
dcaf96dc
JB
443 throw typeof error === 'string' ? new Error(error) : error;
444 });
3ec10737 445 }
23132a44
JB
446 }
447 });
448 } catch (error) {
69074173 449 Configuration.handleFileException(
a95873d8 450 Configuration.configurationFile,
7164966d
JB
451 FileType.Configuration,
452 error as NodeJS.ErrnoException,
5edd8ba0 453 Configuration.logPrefix(),
e7aeea18 454 );
23132a44 455 }
ded13d97
JB
456 }
457
69074173
JB
458 private static handleFileException(
459 file: string,
460 fileType: FileType,
461 error: NodeJS.ErrnoException,
5edd8ba0 462 logPrefix: string,
69074173 463 ): void {
9bf0ef23 464 const prefix = isNotEmptyString(logPrefix) ? `${logPrefix} ` : '';
69074173
JB
465 let logMsg: string;
466 switch (error.code) {
467 case 'ENOENT':
468 logMsg = `${fileType} file ${file} not found:`;
469 break;
470 case 'EEXIST':
471 logMsg = `${fileType} file ${file} already exists:`;
472 break;
473 case 'EACCES':
474 logMsg = `${fileType} file ${file} access denied:`;
475 break;
7b5dbe91
JB
476 case 'EPERM':
477 logMsg = `${fileType} file ${file} permission denied:`;
478 break;
69074173
JB
479 default:
480 logMsg = `${fileType} file ${file} error:`;
481 }
7b5dbe91
JB
482 console.error(`${chalk.green(prefix)}${chalk.red(`${logMsg} `)}`, error);
483 throw error;
69074173
JB
484 }
485
1f5df42a 486 private static getDefaultPerformanceStorageUri(storageType: StorageType) {
d5603918
JB
487 switch (storageType) {
488 case StorageType.JSON_FILE:
e8044a69 489 return Configuration.buildPerformanceUriFilePath(
5edd8ba0 490 `${Constants.DEFAULT_PERFORMANCE_DIRECTORY}/${Constants.DEFAULT_PERFORMANCE_RECORDS_FILENAME}`,
e8044a69 491 );
d5603918 492 case StorageType.SQLITE:
e8044a69 493 return Configuration.buildPerformanceUriFilePath(
5edd8ba0 494 `${Constants.DEFAULT_PERFORMANCE_DIRECTORY}/${Constants.DEFAULT_PERFORMANCE_RECORDS_DB_NAME}.db`,
e8044a69 495 );
d5603918
JB
496 default:
497 throw new Error(`Performance storage URI is mandatory with storage type '${storageType}'`);
498 }
499 }
e8044a69
JB
500
501 private static buildPerformanceUriFilePath(file: string) {
d972af76 502 return `file://${join(resolve(dirname(fileURLToPath(import.meta.url)), '../'), file)}`;
e8044a69 503 }
7dde0b73 504}