< Summary - Envilder CLI

Information
Class: src/envilder/core/application/dispatch/DispatchActionCommandHandler.ts
Assembly: Default
File(s): src/envilder/core/application/dispatch/DispatchActionCommandHandler.ts
Tag: 561_41292037308
Line coverage
97%
Covered lines: 40
Uncovered lines: 1
Coverable lines: 41
Total lines: 160
Line coverage: 97.5%
Branch coverage
96%
Covered branches: 24
Total branches: 25
Branch coverage: 96%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

File(s)

src/envilder/core/application/dispatch/DispatchActionCommandHandler.ts

#LineLine coverage
 1import { inject, injectable, optional } from 'inversify';
 2import { InvalidArgumentError } from '../../domain/errors/DomainErrors.js';
 3import { OperationMode } from '../../domain/OperationMode.js';
 4import type { ISecretProvider } from '../../domain/ports/ISecretProvider.js';
 5import { TYPES } from '../../types.js';
 6import { ExecWithSecretsCommand } from '../execWithSecrets/ExecWithSecretsCommand.js';
 7// Type-only: the GitHub Action bundle must not pull in exec mode.
 8import type { ExecWithSecretsCommandHandler } from '../execWithSecrets/ExecWithSecretsCommandHandler.js';
 9import { PullSecretsToEnvCommand } from '../pullSecretsToEnv/PullSecretsToEnvCommand.js';
 10import type { PullSecretsToEnvCommandHandler } from '../pullSecretsToEnv/PullSecretsToEnvCommandHandler.js';
 11import { PushEnvToSecretsCommand } from '../pushEnvToSecrets/PushEnvToSecretsCommand.js';
 12import type { PushEnvToSecretsCommandHandler } from '../pushEnvToSecrets/PushEnvToSecretsCommandHandler.js';
 13import { PushSingleCommand } from '../pushSingle/PushSingleCommand.js';
 14import type { PushSingleCommandHandler } from '../pushSingle/PushSingleCommandHandler.js';
 15import type { DispatchActionCommand } from './DispatchActionCommand.js';
 16
 17@injectable()
 1318export class DispatchActionCommandHandler {
 19  constructor(
 20    @inject(TYPES.PullSecretsToEnvCommandHandler)
 9021    private readonly pullHandler: PullSecretsToEnvCommandHandler,
 22    @inject(TYPES.PushEnvToSecretsCommandHandler)
 9023    private readonly pushHandler: PushEnvToSecretsCommandHandler,
 24    @inject(TYPES.PushSingleCommandHandler)
 9025    private readonly pushSingleHandler: PushSingleCommandHandler,
 26    @inject(TYPES.ISecretProvider)
 9027    private readonly secretProvider: ISecretProvider,
 28    // Bound only by the CLI exec startup; absent in the GitHub Action.
 29    @inject(TYPES.ExecWithSecretsCommandHandler)
 30    @optional()
 9031    private readonly execHandler?: ExecWithSecretsCommandHandler,
 32  ) {}
 33
 34  /**
 35   * Runs the command's mode. Returns the exit code of the child process in
 36   * exec mode, and `undefined` for every other mode.
 37   */
 38  async handleCommand(
 39    command: DispatchActionCommand,
 40  ): Promise<number | undefined> {
 6741    if (command.mode === OperationMode.EXEC) {
 42      // No identity banner: exec prints a single summary line.
 4843      return this.handleExec(command);
 44    }
 45
 1946    this.validateRequiredArguments(command);
 47
 1948    if (typeof this.secretProvider.logIdentity === 'function') {
 949      await this.secretProvider.logIdentity();
 50    }
 1551    switch (command.mode) {
 52      case OperationMode.PUSH_SINGLE:
 553        await this.handlePushSingle(command);
 554        break;
 55      case OperationMode.PUSH_ENV_TO_SECRETS:
 356        await this.handlePush(command);
 357        break;
 58      case OperationMode.PULL_SECRETS_TO_ENV:
 659        await this.handlePull(command);
 660        break;
 61      default:
 162        throw new InvalidArgumentError(
 63          `Unsupported operation mode: ${command.mode}`,
 64        );
 65    }
 66  }
 67
 68  private validateRequiredArguments(command: DispatchActionCommand): void {
 1969    if (command.mode === OperationMode.PUSH_SINGLE) {
 570      this.validatePushSingleOptions(command);
 571      return;
 72    }
 73
 1474    this.validateMapAndEnvFileOptions(command);
 75  }
 76
 77  private async handleExec(command: DispatchActionCommand): Promise<number> {
 4878    if (!command.map || !command.command) {
 279      throw new InvalidArgumentError(
 80        'Missing required arguments for exec: a map file and a command',
 81      );
 82    }
 4683    if (this.execHandler === undefined) {
 184      throw new InvalidArgumentError(
 85        'exec mode is not available in this entry point',
 86      );
 87    }
 88
 4589    return this.execHandler.handle(
 90      ExecWithSecretsCommand.create(
 91        command.map,
 92        command.command,
 93        command.args,
 94        command.sourceLabel,
 95      ),
 96    );
 97  }
 98
 99  private async handlePushSingle(
 100    command: DispatchActionCommand,
 101  ): Promise<void> {
 5102    this.validatePushSingleOptions(command);
 5103    const pushSingleCommand = PushSingleCommand.create(
 104      command.key,
 105      command.value,
 106      command.secretPath,
 107      command.map,
 108      command.mapTarget,
 109    );
 110
 5111    await this.pushSingleHandler.handle(pushSingleCommand);
 112  }
 113
 114  private async handlePush(command: DispatchActionCommand): Promise<void> {
 3115    this.validateMapAndEnvFileOptions(command);
 3116    const pushEnvToSecretsCommand = PushEnvToSecretsCommand.create(
 117      command.map,
 118      command.envfile,
 119    );
 120
 3121    await this.pushHandler.handle(pushEnvToSecretsCommand);
 122  }
 123
 124  private async handlePull(command: DispatchActionCommand): Promise<void> {
 6125    this.validateMapAndEnvFileOptions(command);
 6126    const pullSecretsToEnvCommand = PullSecretsToEnvCommand.create(
 127      command.map,
 128      command.envfile,
 129    );
 130
 6131    await this.pullHandler.handle(pullSecretsToEnvCommand);
 132  }
 133
 134  private validatePushSingleOptions(
 135    command: DispatchActionCommand,
 136  ): asserts command is DispatchActionCommand & {
 137    key: string;
 138    value: string;
 139    secretPath: string;
 140  } {
 10141    if (!command.key || !command.value || !command.secretPath) {
 0142      throw new InvalidArgumentError(
 143        'Missing required arguments: --key, --value, and --secret-path',
 144      );
 145    }
 146  }
 147
 148  private validateMapAndEnvFileOptions(
 149    command: DispatchActionCommand,
 150  ): asserts command is DispatchActionCommand & {
 151    map: string;
 152    envfile: string;
 153  } {
 23154    if (!command.map || !command.envfile) {
 4155      throw new InvalidArgumentError(
 156        'Missing required arguments: --map and --envfile',
 157      );
 158    }
 159  }
 160}