All files / apps/cli Startup.ts

100% Statements 68/68
100% Branches 10/10
100% Functions 8/8
100% Lines 68/68

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 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 981x 1x 1x   1x 1x 1x 1x           1x 1x 1x 1x   1x     1x 17x 17x   1x 17x 17x   1x 13x 13x 13x               1x 12x 12x 12x   1x 12x 12x   1x 2x 2x   1x 12x 12x 12x 12x   12x 12x 12x 12x   12x 2x 10x   12x   12x 12x 12x 12x   1x 13x 13x 13x 13x   13x 13x 13x 13x   13x 13x 13x 13x   13x 13x 13x 13x 13x 1x  
import { SSM } from '@aws-sdk/client-ssm';
import { fromIni } from '@aws-sdk/credential-providers';
import { Container } from 'inversify';
 
import { DispatchActionCommandHandler } from '../../envilder/application/dispatch/DispatchActionCommandHandler.js';
import { PullSsmToEnvCommandHandler } from '../../envilder/application/pullSsmToEnv/PullSsmToEnvCommandHandler.js';
import { PushEnvToSsmCommandHandler } from '../../envilder/application/pushEnvToSsm/PushEnvToSsmCommandHandler.js';
import { PushSingleCommandHandler } from '../../envilder/application/pushSingle/PushSingleCommandHandler.js';
 
import type { ILogger } from '../../envilder/domain/ports/ILogger.js';
import type { ISecretProvider } from '../../envilder/domain/ports/ISecretProvider.js';
import type { IVariableStore } from '../../envilder/domain/ports/IVariableStore.js';
 
import { AwsSsmSecretProvider } from '../../envilder/infrastructure/aws/AwsSsmSecretProvider.js';
import { ConsoleLogger } from '../../envilder/infrastructure/logger/ConsoleLogger.js';
import { FileVariableStore } from '../../envilder/infrastructure/variableStore/FileVariableStore.js';
import { TYPES } from '../../envilder/types.js';
 
export class Startup {
  private readonly container: Container;
 
  constructor() {
    this.container = new Container();
  }
 
  static build(): Startup {
    return new Startup();
  }
 
  configureServices(): this {
    this.configureApplicationServices();
    return this;
  }
 
  /**
   * Configures infrastructure services for the application.
   * Optionally accepts an AWS profile to use for service configuration.
   * @param awsProfile - The AWS profile to use for configuring infrastructure services.
   * @returns The current instance for method chaining.
   */
  configureInfrastructure(awsProfile?: string): this {
    this.configureInfrastructureServices(awsProfile);
    return this;
  }
 
  create(): Container {
    return this.container;
  }
 
  getServiceProvider(): Container {
    return this.container;
  }
 
  private configureInfrastructureServices(awsProfile?: string): void {
    this.container
      .bind<ILogger>(TYPES.ILogger)
      .to(ConsoleLogger)
      .inSingletonScope();
 
    this.container
      .bind<IVariableStore>(TYPES.IVariableStore)
      .to(FileVariableStore)
      .inSingletonScope();
 
    const ssm = awsProfile
      ? new SSM({ credentials: fromIni({ profile: awsProfile }) })
      : new SSM();
 
    const secretProvider = new AwsSsmSecretProvider(ssm);
 
    this.container
      .bind<ISecretProvider>(TYPES.ISecretProvider)
      .toConstantValue(secretProvider);
  }
 
  private configureApplicationServices(): void {
    this.container
      .bind<PullSsmToEnvCommandHandler>(TYPES.PullSsmToEnvCommandHandler)
      .to(PullSsmToEnvCommandHandler)
      .inTransientScope();
 
    this.container
      .bind<PushEnvToSsmCommandHandler>(TYPES.PushEnvToSsmCommandHandler)
      .to(PushEnvToSsmCommandHandler)
      .inTransientScope();
 
    this.container
      .bind<PushSingleCommandHandler>(TYPES.PushSingleCommandHandler)
      .to(PushSingleCommandHandler)
      .inTransientScope();
 
    this.container
      .bind<DispatchActionCommandHandler>(TYPES.DispatchActionCommandHandler)
      .to(DispatchActionCommandHandler)
      .inTransientScope();
  }
}