Avoid strings concatenation
[e-mobility-charging-stations-simulator.git] / src / utils / FileUtils.ts
index b3940b718e2a2c0240808b0ee8aaf807b5707bfe..ccee788bb99c5ac5d46623bceca00b53bb651fd2 100644 (file)
@@ -1,32 +1,79 @@
+import fs from 'fs';
+
+import chalk from 'chalk';
+
 import logger from './Logger';
+import Utils from './Utils';
+import type { EmptyObject } from '../types/EmptyObject';
+import type { HandleErrorParams } from '../types/Error';
+import type { FileType } from '../types/FileType';
+import type { JsonType } from '../types/JsonType';
 
 export default class FileUtils {
-  static handleFileException(logPrefix: string, fileType: string, filePath: string, error: NodeJS.ErrnoException, consoleOut = false): void {
-    const prefix = logPrefix.length !== 0 ? logPrefix + ' ' : '';
-    if (error.code === 'ENOENT') {
-      if (consoleOut) {
-        console.warn(prefix + fileType + ' file ' + filePath + ' not found: ', error);
-      } else {
-        logger.warn(prefix + fileType + ' file ' + filePath + ' not found: %j', error);
-      }
-    } else if (error.code === 'EEXIST') {
-      if (consoleOut) {
-        console.warn(prefix + fileType + ' file ' + filePath + ' already exists: ', error);
-      } else {
-        logger.warn(prefix + fileType + ' file ' + filePath + ' already exists: %j', error);
+  private constructor() {
+    // This is intentional
+  }
+
+  public static watchJsonFile<T extends JsonType>(
+    logPrefix: string,
+    fileType: FileType,
+    file: string,
+    refreshedVariable?: T,
+    listener: fs.WatchListener<string> = (event, filename) => {
+      if (filename && event === 'change') {
+        try {
+          logger.debug(`${logPrefix} ${fileType} file ${file} have changed, reload`);
+          refreshedVariable && (refreshedVariable = JSON.parse(fs.readFileSync(file, 'utf8')) as T);
+        } catch (error) {
+          FileUtils.handleFileException(logPrefix, fileType, file, error as NodeJS.ErrnoException, {
+            throwError: false,
+          });
+        }
       }
-    } else if (error.code === 'EACCES') {
-      if (consoleOut) {
-        console.warn(prefix + fileType + ' file ' + filePath + ' access denied: ', error);
-      } else {
-        logger.warn(prefix + fileType + ' file ' + filePath + ' access denied: %j', error);
+    }
+  ): fs.FSWatcher {
+    if (file) {
+      try {
+        return fs.watch(file, listener);
+      } catch (error) {
+        FileUtils.handleFileException(logPrefix, fileType, file, error as NodeJS.ErrnoException, {
+          throwError: false,
+        });
       }
     } else {
-      if (consoleOut) {
-        console.error(prefix + fileType + ' file ' + filePath + ' error: ', error);
-      } else {
-        logger.error(prefix + fileType + ' file ' + filePath + ' error: %j', error);
-      }
+      logger.info(`${logPrefix} No ${fileType} file to watch given. Not monitoring its changes`);
+    }
+  }
+
+  public static handleFileException(
+    logPrefix: string,
+    fileType: FileType,
+    file: string,
+    error: NodeJS.ErrnoException,
+    params: HandleErrorParams<EmptyObject> = { throwError: true, consoleOut: false }
+  ): void {
+    const prefix = !Utils.isEmptyString(logPrefix) ? `${logPrefix} ` : '';
+    let logMsg: string;
+    switch (error.code) {
+      case 'ENOENT':
+        logMsg = `${fileType} file ${file} not found:`;
+        break;
+      case 'EEXIST':
+        logMsg = `${fileType} file ${file} already exists:`;
+        break;
+      case 'EACCES':
+        logMsg = `${fileType} file ${file} access denied:`;
+        break;
+      default:
+        logMsg = `${fileType} file ${file} error:`;
+    }
+    if (params?.consoleOut) {
+      logMsg = `${logMsg} `;
+      console.warn(`${chalk.green(prefix)}${chalk.yellow(logMsg)}`, error);
+    } else {
+      logger.warn(`${prefix}${logMsg}`, error);
+    }
+    if (params?.throwError) {
       throw error;
     }
   }