@updating-secrets/aws-secrets-manager-adapter
Version:
AWS Secrets Manager adapter for the updating-secrets package.
72 lines (71 loc) • 3.34 kB
JavaScript
import { assert } from '@augment-vir/assert';
import { ensureError, ensureErrorAndPrependMessage, getOrSet, mapObjectValuesSync, parseWithJson5, wrapInTry, } from '@augment-vir/common';
import { BaseSecretsAdapter } from 'updating-secrets';
/**
* Loads secrets from AWS Secrets Manager. A `SecretsManagerClient` instance must be provided.
*
* @category Adapters
*/
export class AwsSecretsManagerAdapter extends BaseSecretsAdapter {
awsSecretsManager;
constructor(awsSecretsManager) {
super('AwsSecretsManagerAdapter');
this.awsSecretsManager = awsSecretsManager;
}
/** Loads secrets from the provided `SecretsManagerClient`. */
async loadSecrets(secrets) {
/* node:coverage ignore next 1: dynamic imports are not branches */
const { GetSecretValueCommand } = await import('@aws-sdk/client-secrets-manager');
const cachedSecrets = {};
return mapObjectValuesSync(secrets, (secretName, secretDefinition) => {
const awsConfig = secretDefinition.adapterConfig.aws;
if (!awsConfig) {
return new Error(`No AWS adapter config (required for using AwsSecretsManagerAdapter) defined for secret '${secretDefinition.secretName}'.`);
}
const awsSecretName = awsConfig.keyIn || awsConfig.rootOf;
if (!awsSecretName) {
return new Error(`Invalid AWS adapter key config for '${secretDefinition.secretName}'.`);
}
const secretValue = getOrSet(cachedSecrets, awsSecretName, () => {
const sendCommand = new GetSecretValueCommand({
SecretId: awsSecretName,
});
return this.awsSecretsManager.send(sendCommand).then((result) => {
try {
const secretValue = result.SecretString;
if (secretValue) {
return wrapInTry(() => parseWithJson5(secretValue), {
fallbackValue: secretValue,
});
}
else {
throw new Error(`AWS SecretsManager secret '${awsSecretName}' has no string value.`);
}
}
catch (error) {
return ensureError(error);
}
});
});
return secretValue
.then((awsSecretValue) => {
if (awsSecretValue instanceof Error) {
throw awsSecretValue;
}
else if (awsConfig.keyIn) {
assert.isObject(awsSecretValue, `AWS secret at '${awsSecretName}' is not an object.`);
return awsSecretValue[secretDefinition.secretName];
}
else if (secretDefinition.shapeDefinition) {
return wrapInTry(() => parseWithJson5(awsSecretValue), {
fallbackValue: awsSecretValue,
});
}
else {
return awsSecretValue;
}
})
.catch((reason) => ensureErrorAndPrependMessage(reason, `Failed to load AWS secret '${awsSecretName}'`));
});
}
}