All files / src/cli/infrastructure EnvFileManager.ts

100% Statements 37/37
100% Branches 9/9
100% Functions 4/4
100% Lines 37/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 431x 1x     1x 1x 8x 8x 8x 8x 1x 1x 1x 8x   1x 6x 6x 6x 6x 4x 4x 2x 2x 2x 2x 6x   1x 10x 10x 10x 10x 10x 10x 10x 10x   1x 13x 13x 1x  
import * as fs from 'node:fs/promises';
import * as dotenv from 'dotenv';
import type { IEnvFileManager } from '../domain/ports/IEnvFileManager';
 
export class EnvFileManager implements IEnvFileManager {
  async loadMapFile(mapPath: string): Promise<Record<string, string>> {
    const content = await fs.readFile(mapPath, 'utf-8');
    try {
      return JSON.parse(content);
    } catch (err: unknown) {
      console.error(`Error parsing JSON from ${mapPath}`);
      throw new Error(`Invalid JSON in parameter map file: ${mapPath}`);
    }
  }
 
  async loadEnvFile(envFilePath: string): Promise<Record<string, string>> {
    const envVariables: Record<string, string> = {};
    try {
      await fs.access(envFilePath);
    } catch {
      return envVariables;
    }
    const existingEnvContent = await fs.readFile(envFilePath, 'utf-8');
    const parsedEnv = dotenv.parse(existingEnvContent);
    Object.assign(envVariables, parsedEnv);
    return envVariables;
  }
 
  async saveEnvFile(
    envFilePath: string,
    envVariables: Record<string, string>,
  ): Promise<void> {
    const envContent = Object.entries(envVariables)
      .map(([key, value]) => `${key}=${this.escapeEnvValue(value)}`)
      .join('\n');
    await fs.writeFile(envFilePath, envContent);
  }
 
  private escapeEnvValue(value: string): string {
    return value.replace(/(\r\n|\n|\r)/g, '\\n');
  }
}