Browse Source

refactor(shared): factorize common helpers in shared package

Nicolas Meienberger 1 year ago
parent
commit
55e0cd155e

+ 8 - 0
packages/shared/src/helpers/fs-helpers/fs-helpers.ts

@@ -0,0 +1,8 @@
+import fs from 'fs';
+
+export const pathExists = async (path: string): Promise<boolean> => {
+  return fs.promises
+    .access(path)
+    .then(() => true)
+    .catch(() => false);
+};

+ 1 - 0
packages/shared/src/helpers/fs-helpers/index.ts

@@ -0,0 +1 @@
+export * from './fs-helpers';

+ 1 - 0
packages/shared/src/helpers/index.ts

@@ -1 +1,2 @@
 export * from './env-helpers';
+export * from './fs-helpers';

+ 2 - 0
packages/shared/src/index.ts

@@ -1,3 +1,5 @@
 export * from './schemas';
 export * from './helpers';
 export { createLogger } from './utils/logger';
+export { FileLogger } from './lib/FileLogger';
+export { execAsync } from './lib/exec-async';

+ 61 - 0
packages/shared/src/lib/FileLogger/FileLogger.ts

@@ -0,0 +1,61 @@
+import fs from 'fs';
+import path from 'path';
+import { createLogger } from '../../utils/logger';
+
+function streamLogToHistory(logsFolder: string, logFile: string) {
+  return new Promise((resolve, reject) => {
+    const appLogReadStream = fs.createReadStream(path.join(logsFolder, logFile), 'utf-8');
+    const appLogHistoryWriteStream = fs.createWriteStream(path.join(logsFolder, `${logFile}.history`), { flags: 'a' });
+
+    appLogReadStream
+      .pipe(appLogHistoryWriteStream)
+      .on('finish', () => {
+        fs.writeFileSync(path.join(logsFolder, logFile), '');
+        resolve(true);
+      })
+      .on('error', (error) => {
+        reject(error);
+      });
+  });
+}
+
+export class FileLogger {
+  private winstonLogger;
+
+  private logsFolder;
+
+  constructor(name: string, folder: string, console?: boolean) {
+    this.winstonLogger = createLogger(name, folder, console);
+    this.logsFolder = folder;
+  }
+
+  public flush = async () => {
+    try {
+      if (fs.existsSync(path.join(this.logsFolder, 'app.log'))) {
+        await streamLogToHistory(this.logsFolder, 'app.log');
+      }
+      if (fs.existsSync(path.join(this.logsFolder, 'error.log'))) {
+        await streamLogToHistory(this.logsFolder, 'error.log');
+      }
+      this.winstonLogger.info('Logs flushed');
+    } catch (error) {
+      this.winstonLogger.error('Error flushing logs', error);
+    }
+  };
+
+  public error = (...message: unknown[]) => {
+    this.winstonLogger.error(message.join(' '));
+  };
+
+  public info = (...message: unknown[]) => {
+    this.winstonLogger.info(message.join(' '));
+  };
+
+  public warn = (...message: unknown[]) => {
+    this.winstonLogger.warn(message.join(' '));
+  };
+
+  public debug = (...message: unknown[]) => {
+    this.winstonLogger.debug(message.join(' '));
+  };
+}

+ 1 - 0
packages/shared/src/lib/FileLogger/index.ts

@@ -0,0 +1 @@
+export { FileLogger } from './FileLogger';

+ 20 - 0
packages/shared/src/lib/exec-async/execAsync.tsx

@@ -0,0 +1,20 @@
+import { exec } from 'child_process';
+import { promisify } from 'util';
+
+type ExecAsyncParams = [command: string];
+
+type ExecResult = { stdout: string; stderr: string };
+
+export const execAsync = async (...args: ExecAsyncParams): Promise<ExecResult> => {
+  try {
+    const { stdout, stderr } = await promisify(exec)(...args);
+
+    return { stdout, stderr };
+  } catch (error) {
+    if (error instanceof Error) {
+      return { stderr: error.message, stdout: '' };
+    }
+
+    return { stderr: String(error), stdout: '' };
+  }
+};

+ 1 - 0
packages/shared/src/lib/exec-async/index.ts

@@ -0,0 +1 @@
+export { execAsync } from './execAsync';

+ 2 - 8
packages/shared/src/schemas/queue-schemas.ts

@@ -23,16 +23,10 @@ const repoCommandSchema = z.object({
 
 const systemCommandSchema = z.object({
   type: z.literal(EVENT_TYPES.SYSTEM),
-  command: z.union([z.literal('restart'), z.literal('system_info')]),
+  command: z.literal('system_info'),
 });
 
-const updateSchema = z.object({
-  type: z.literal(EVENT_TYPES.SYSTEM),
-  command: z.literal('update'),
-  version: z.string(),
-});
-
-export const eventSchema = appCommandSchema.or(repoCommandSchema).or(systemCommandSchema).or(updateSchema);
+export const eventSchema = appCommandSchema.or(repoCommandSchema).or(systemCommandSchema);
 
 export const eventResultSchema = z.object({
   success: z.boolean(),

+ 3 - 1
packages/shared/src/utils/logger/Logger.ts

@@ -12,7 +12,7 @@ type Transports = transports.ConsoleTransportInstance | transports.FileTransport
  * @param {string} id - The id of the logger, used to identify the logger in the logs
  * @param {string} logsFolder - The folder where the logs will be stored
  */
-export const newLogger = (id: string, logsFolder: string) => {
+export const newLogger = (id: string, logsFolder: string, console?: boolean) => {
   if (!fs.existsSync(logsFolder)) {
     fs.mkdirSync(logsFolder, { recursive: true });
   }
@@ -36,6 +36,8 @@ export const newLogger = (id: string, logsFolder: string) => {
 
   if (process.env.NODE_ENV === 'development') {
     tr.push(new transports.Console({ level: 'debug' }));
+  } else if (console) {
+    tr.push(new transports.Console({ level: 'info' }));
   }
 
   return createLogger({