< Summary - Envilder Core (TypeScript)

Information
Class: src/envilder/core/application/pullSecretsToEnv/PullSecretsToEnvCommandHandler.ts
Assembly: Default
File(s): src/envilder/core/application/pullSecretsToEnv/PullSecretsToEnvCommandHandler.ts
Tag: 151_24479375065
Line coverage
100%
Covered lines: 36
Uncovered lines: 0
Coverable lines: 36
Total lines: 126
Line coverage: 100%
Branch coverage
83%
Covered branches: 5
Total branches: 6
Branch coverage: 83.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

File(s)

src/envilder/core/application/pullSecretsToEnv/PullSecretsToEnvCommandHandler.ts

#LineLine coverage
 1import { inject, injectable } from 'inversify';
 2import { EnvironmentVariable } from '../../domain/EnvironmentVariable.js';
 3import type { ILogger } from '../../domain/ports/ILogger.js';
 4import type { ISecretProvider } from '../../domain/ports/ISecretProvider.js';
 5import type { IVariableStore } from '../../domain/ports/IVariableStore.js';
 6import { TYPES } from '../../types.js';
 7import type { PullSecretsToEnvCommand } from './PullSecretsToEnvCommand.js';
 8
 9@injectable()
 810export class PullSecretsToEnvCommandHandler {
 811  private static readonly ERROR_MESSAGES = {
 12    FETCH_FAILED: 'Failed to generate environment file: ',
 13    PARAM_NOT_FOUND: 'Some secrets could not be fetched:\n',
 14    NO_VALUE_FOUND: 'Warning: No value found for: ',
 15    ERROR_FETCHING: 'Error fetching secret: ',
 16  };
 17
 818  private static readonly SUCCESS_MESSAGES = {
 19    ENV_GENERATED: 'Environment File generated at ',
 20  };
 21
 22  constructor(
 23    @inject(TYPES.ISecretProvider)
 2324    private readonly secretProvider: ISecretProvider,
 25    @inject(TYPES.IVariableStore)
 2326    private readonly variableStore: IVariableStore,
 2327    @inject(TYPES.ILogger) private readonly logger: ILogger,
 28  ) {}
 29
 30  /**
 31   * Handles the PullSecretsToEnvCommand which orchestrates the process of fetching
 32   * environment variable values from a secret store and writing them to a local environment file.
 33   *
 34   * @param command - The PullSecretsToEnvCommand containing mapPath and envFilePath
 35   */
 36  async handle(command: PullSecretsToEnvCommand): Promise<void> {
 737    try {
 38      const { requestVariables, currentVariables } =
 739        await this.loadVariables(command);
 740      const envilded = await this.envild(requestVariables, currentVariables);
 641      await this.saveEnvFile(command.envFilePath, envilded);
 42
 643      this.logger.info(
 44        `${PullSecretsToEnvCommandHandler.SUCCESS_MESSAGES.ENV_GENERATED}'${command.envFilePath}'`,
 45      );
 46    } catch (_error) {
 47      const errorMessage =
 148        _error instanceof Error ? _error.message : String(_error);
 149      this.logger.error(
 50        `${PullSecretsToEnvCommandHandler.ERROR_MESSAGES.FETCH_FAILED}${errorMessage}`,
 51      );
 152      throw _error;
 53    }
 54  }
 55
 56  private async loadVariables(command: PullSecretsToEnvCommand): Promise<{
 57    requestVariables: Record<string, string>;
 58    currentVariables: Record<string, string>;
 59  }> {
 760    const requestVariables = await this.variableStore.getMapping(
 61      command.mapPath,
 62    );
 763    const currentVariables = await this.variableStore.getEnvironment(
 64      command.envFilePath,
 65    );
 66
 767    return { requestVariables, currentVariables };
 68  }
 69
 70  private async saveEnvFile(
 71    envFilePath: string,
 72    variables: Record<string, string>,
 73  ): Promise<void> {
 674    await this.variableStore.saveEnvironment(envFilePath, variables);
 75  }
 76
 77  private async envild(
 78    paramMap: Record<string, string>,
 79    existingEnvVariables: Record<string, string>,
 80  ): Promise<Record<string, string>> {
 781    const secretProcessingPromises = Object.entries(paramMap).map(
 82      async ([envVar, secretName]) => {
 983        return this.processSecret(envVar, secretName, existingEnvVariables);
 84      },
 85    );
 86
 787    const results = await Promise.all(secretProcessingPromises);
 88
 989    const errors = results.filter((error) => error !== null) as string[];
 90
 791    if (errors.length > 0) {
 192      throw new Error(
 93        `${PullSecretsToEnvCommandHandler.ERROR_MESSAGES.PARAM_NOT_FOUND}${errors.join('\n')}`,
 94      );
 95    }
 696    return existingEnvVariables;
 97  }
 98
 99  private async processSecret(
 100    envVar: string,
 101    secretName: string,
 102    existingEnvVariables: Record<string, string>,
 103  ): Promise<string | null> {
 9104    try {
 9105      const value = await this.secretProvider.getSecret(secretName);
 8106      if (!value) {
 1107        this.logger.warn(
 108          `${PullSecretsToEnvCommandHandler.ERROR_MESSAGES.NO_VALUE_FOUND}'${secretName}'`,
 109        );
 1110        return null;
 111      }
 112
 7113      existingEnvVariables[envVar] = value;
 114
 7115      const envVariable = new EnvironmentVariable(envVar, value, true);
 7116      this.logger.info(`${envVariable.name}=${envVariable.maskedValue}`);
 117
 7118      return null;
 119    } catch (_error) {
 1120      this.logger.error(
 121        `${PullSecretsToEnvCommandHandler.ERROR_MESSAGES.ERROR_FETCHING}'${secretName}'`,
 122      );
 1123      return `ParameterNotFound: ${secretName}`;
 124    }
 125  }
 126}