< Summary - Envilder Node.js SDK

Information
Class: src/sdks/nodejs/src/infrastructure/aws/aws-ssm-secret-provider.ts
Assembly: Default
File(s): src/sdks/nodejs/src/infrastructure/aws/aws-ssm-secret-provider.ts
Tag: 427_29134414720
Line coverage
100%
Covered lines: 24
Uncovered lines: 0
Coverable lines: 24
Total lines: 75
Line coverage: 100%
Branch coverage
87%
Covered branches: 14
Total branches: 16
Branch coverage: 87.5%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

File(s)

src/sdks/nodejs/src/infrastructure/aws/aws-ssm-secret-provider.ts

#LineLine coverage
 1import { GetParametersCommand, type SSMClient } from '@aws-sdk/client-ssm';
 2import {
 3  ExpiredCredentialsError,
 4  isExpiredCredentialsError,
 5} from '../../domain/expired-credentials-error.js';
 6import type { ISecretProvider } from '../../domain/ports/secret-provider.js';
 7import {
 8  isSsoSessionExpiredError,
 9  SsoSessionExpiredError,
 10} from '../../domain/sso-session-expired-error.js';
 11
 412const SSM_BATCH_SIZE = 10;
 13
 14/**
 15 * {@link ISecretProvider} backed by AWS SSM Parameter Store.
 16 *
 17 * Parameters are retrieved with decryption enabled so that
 18 * SecureString values are returned in plain text.
 19 *
 20 * SSM supports fetching up to 10 parameters per request,
 21 * so names are chunked into batches automatically.
 22 */
 23export class AwsSsmSecretProvider implements ISecretProvider {
 24  private readonly ssmClient: SSMClient;
 25  private readonly profile?: string;
 26
 27  constructor(ssmClient: SSMClient, profile?: string) {
 1328    if (!ssmClient) {
 129      throw new Error('ssmClient cannot be null');
 30    }
 1231    this.ssmClient = ssmClient;
 1232    this.profile = profile;
 33  }
 34
 35  async getSecrets(names: string[]): Promise<Map<string, string>> {
 1336    const result = new Map<string, string>();
 1337    if (names.length === 0) {
 138      return result;
 39    }
 40
 1241    for (const name of names) {
 2642      if (!name?.trim()) {
 143        throw new Error('Secret name cannot be null or whitespace');
 44      }
 45    }
 46
 1147    for (let i = 0; i < names.length; i += SSM_BATCH_SIZE) {
 1248      const batch = names.slice(i, i + SSM_BATCH_SIZE);
 1249      try {
 1250        const response = await this.ssmClient.send(
 51          new GetParametersCommand({
 52            Names: batch,
 53            WithDecryption: true,
 54          }),
 55        );
 56
 757        for (const param of response.Parameters ?? []) {
 558          if (param.Name && param.Value != null) {
 559            result.set(param.Name, param.Value);
 60          }
 61        }
 62      } catch (error) {
 563        if (isSsoSessionExpiredError(error)) {
 164          throw new SsoSessionExpiredError(this.profile, error);
 65        }
 466        if (isExpiredCredentialsError(error)) {
 167          throw new ExpiredCredentialsError(error);
 68        }
 369        throw error;
 70      }
 71    }
 72
 673    return result;
 74  }
 75}

Methods/Properties

constructor
getSecrets