< Summary - Envilder Node.js SDK

Information
Class: src/sdks/nodejs/src/infrastructure/azure/azure-key-vault-secret-provider.ts
Assembly: Default
File(s): src/sdks/nodejs/src/infrastructure/azure/azure-key-vault-secret-provider.ts
Tag: 299_25910610327
Line coverage
100%
Covered lines: 23
Uncovered lines: 0
Coverable lines: 23
Total lines: 68
Line coverage: 100%
Branch coverage
93%
Covered branches: 15
Total branches: 16
Branch coverage: 93.7%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

File(s)

src/sdks/nodejs/src/infrastructure/azure/azure-key-vault-secret-provider.ts

#LineLine coverage
 1import type { SecretClient } from '@azure/keyvault-secrets';
 2import type { ISecretProvider } from '../../domain/ports/secret-provider.js';
 3
 4/**
 5 * {@link ISecretProvider} backed by Azure Key Vault.
 6 *
 7 * Secrets are fetched in parallel. Secrets that return HTTP 404
 8 * are treated as missing and silently omitted from the result.
 9 */
 10export class AzureKeyVaultSecretProvider implements ISecretProvider {
 11  private readonly secretClient: SecretClient;
 12
 13  constructor(secretClient: SecretClient) {
 814    if (!secretClient) {
 115      throw new Error('secretClient cannot be null');
 16    }
 717    this.secretClient = secretClient;
 18  }
 19
 20  async getSecrets(names: string[]): Promise<Map<string, string>> {
 821    const result = new Map<string, string>();
 822    if (names.length === 0) {
 123      return result;
 24    }
 25
 726    for (const name of names) {
 1227      if (!name?.trim()) {
 128        throw new Error('Secret name cannot be null or empty');
 29      }
 30    }
 31
 632    const entries = await Promise.all(
 33      names.map(async (name) => {
 1034        const value = await this.fetchSecret(name);
 935        return [name, value] as const;
 36      }),
 37    );
 38
 539    for (const [name, value] of entries) {
 940      if (value !== null) {
 741        result.set(name, value);
 42      }
 43    }
 44
 545    return result;
 46  }
 47
 48  private async fetchSecret(name: string): Promise<string | null> {
 1049    try {
 1050      const response = await this.secretClient.getSecret(name);
 751      return response.value ?? null;
 52    } catch (error: unknown) {
 353      if (isNotFound(error)) {
 254        return null;
 55      }
 156      throw error;
 57    }
 58  }
 59}
 60
 61function isNotFound(error: unknown): boolean {
 362  return (
 63    typeof error === 'object' &&
 64    error !== null &&
 65    'statusCode' in error &&
 66    (error as { statusCode: number }).statusCode === 404
 67  );
 68}