diff --git a/packages/commons/src/config/EnvironmentVariablesService.ts b/packages/commons/src/config/EnvironmentVariablesService.ts deleted file mode 100644 index a4bfaa2bc4..0000000000 --- a/packages/commons/src/config/EnvironmentVariablesService.ts +++ /dev/null @@ -1,110 +0,0 @@ -import { - getServiceName, - getXRayTraceIdFromEnv, - isDevMode, - isRequestXRaySampled, -} from '../envUtils.js'; -import type { ConfigServiceInterface } from '../types/ConfigServiceInterface.js'; - -/** - * This class is used to fetch environment variables that are available in the execution environment. - * - * These variables can be a mix of runtime environment variables set by AWS and - * other environment variables that are set by the developer to configure Powertools for AWS Lambda. - * - * @example - * ```typescript - * import { EnvironmentVariablesService } from '@aws-lambda-powertools/commons/'; - * - * const config = new EnvironmentVariablesService(); - * const serviceName = config.getServiceName(); - * ``` - * - * @see https://docs.powertools.aws.dev/lambda/typescript/latest/#environment-variables - * - * @class - */ -class EnvironmentVariablesService implements ConfigServiceInterface { - /** - * Increase JSON indentation for Logger to ease debugging when running functions locally or in a non-production environment - */ - protected devModeVariable = 'POWERTOOLS_DEV'; - /** - * Set service name used for tracing namespace, metrics dimension and structured logging - */ - protected serviceNameVariable = 'POWERTOOLS_SERVICE_NAME'; - /** - * AWS X-Ray Trace ID environment variable - * @private - */ - private xRayTraceIdVariable = '_X_AMZN_TRACE_ID'; - - /** - * Get the value of an environment variable by name. - * - * @param {string} name The name of the environment variable to fetch. - */ - public get(name: string): string { - return process.env[name]?.trim() || ''; - } - - /** - * Get the value of the `POWERTOOLS_SERVICE_NAME` environment variable. - */ - public getServiceName(): string { - return getServiceName(); - } - - /** - * Get the value of the `_X_AMZN_TRACE_ID` environment variable. - * - * The AWS X-Ray Trace data available in the environment variable has this format: - * `Root=1-5759e988-bd862e3fe1be46a994272793;Parent=557abcec3ee5a047;Sampled=1`, - * - * The actual Trace ID is: `1-5759e988-bd862e3fe1be46a994272793`. - */ - public getXrayTraceId(): string | undefined { - return getXRayTraceIdFromEnv(); - } - - /** - * Determine if the current invocation is part of a sampled X-Ray trace. - * - * The AWS X-Ray Trace data available in the environment variable has this format: - * `Root=1-5759e988-bd862e3fe1be46a994272793;Parent=557abcec3ee5a047;Sampled=1`, - */ - public getXrayTraceSampled(): boolean { - return isRequestXRaySampled(); - } - - /** - * Determine if the current invocation is running in a development environment. - */ - public isDevMode(): boolean { - return isDevMode(); - } - - /** - * Helper function to determine if a value is considered thruthy. - * - * @param value The value to check for truthiness. - */ - public isValueTrue(value: string): boolean { - const truthyValues: string[] = ['1', 'y', 'yes', 't', 'true', 'on']; - - return truthyValues.includes(value.toLowerCase()); - } - - /** - * Helper function to determine if a value is considered falsy. - * - * @param value The value to check for falsiness. - */ - public isValueFalse(value: string): boolean { - const falsyValues: string[] = ['0', 'n', 'no', 'f', 'false', 'off']; - - return falsyValues.includes(value.toLowerCase()); - } -} - -export { EnvironmentVariablesService }; diff --git a/packages/commons/src/index.ts b/packages/commons/src/index.ts index 4c559c40bb..be11255615 100644 --- a/packages/commons/src/index.ts +++ b/packages/commons/src/index.ts @@ -5,7 +5,6 @@ if (!process.env.AWS_SDK_UA_APP_ID) { } export { addUserAgentMiddleware, isSdkClient } from './awsSdkUtils.js'; -export { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js'; export { cleanupMiddlewares } from './middleware/cleanupMiddlewares.js'; export { IDEMPOTENCY_KEY, diff --git a/packages/commons/tests/unit/EnvironmentVariablesService.test.ts b/packages/commons/tests/unit/EnvironmentVariablesService.test.ts deleted file mode 100644 index 6f0c50dca0..0000000000 --- a/packages/commons/tests/unit/EnvironmentVariablesService.test.ts +++ /dev/null @@ -1,193 +0,0 @@ -import { afterAll, beforeEach, describe, expect, it, vi } from 'vitest'; -import { EnvironmentVariablesService } from '../../src/index.js'; - -describe('Class: EnvironmentVariablesService', () => { - const ENVIRONMENT_VARIABLES = process.env; - - beforeEach(() => { - vi.resetModules(); - process.env = { ...ENVIRONMENT_VARIABLES }; - }); - - afterAll(() => { - process.env = ENVIRONMENT_VARIABLES; - }); - - describe('Method: get', () => { - it('returns the value of a runtime variable', () => { - // Prepare - process.env.CUSTOM_VARIABLE = 'my custom value'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.get('CUSTOM_VARIABLE'); - - // Assess - expect(value).toEqual('my custom value'); - }); - - it('returns an empty string when the env variable is not present', () => { - // Prepare - process.env.CUSTOM_VARIABLE = undefined; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.get('CUSTOM_VARIABLE'); - - // Assess - expect(value).toEqual(''); - }); - }); - - describe('Method: getServiceName', () => { - it('returns the value of the environment variable POWERTOOLS_SERVICE_NAME', () => { - // Prepare - process.env.POWERTOOLS_SERVICE_NAME = 'shopping-cart-api'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getServiceName(); - - // Assess - expect(value).toEqual('shopping-cart-api'); - }); - }); - - describe('Method: getXrayTraceId', () => { - it('returns the value of the environment variable _X_AMZN_TRACE_ID', () => { - // Prepare - process.env._X_AMZN_TRACE_ID = 'abcd123456789'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getXrayTraceId(); - - // Assess - expect(value).toEqual('abcd123456789'); - }); - }); - - describe('Method: getXrayTraceSampled', () => { - it('returns true if the Sampled flag is set in the _X_AMZN_TRACE_ID environment variable', () => { - // Prepare - process.env._X_AMZN_TRACE_ID = - 'Root=1-5759e988-bd862e3fe1be46a994272793;Parent=557abcec3ee5a047;Sampled=1'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.getXrayTraceSampled(); - - // Assess - expect(value).toEqual(true); - }); - }); - - describe('Method: isValueTrue', () => { - const valuesToTest: Array> = [ - ['1', true], - ['y', true], - ['yes', true], - ['t', true], - ['TRUE', true], - ['on', true], - ['', false], - ['false', false], - ['fasle', false], - ['somethingsilly', false], - ['0', false], - ]; - - it.each(valuesToTest)( - 'takes string "%s" and returns %s', - (input, output) => { - // Prepare - const service = new EnvironmentVariablesService(); - // Act - const value = service.isValueTrue(input as string); - // Assess - expect(value).toBe(output); - } - ); - }); - - describe('Method: isValueFalse', () => { - const valuesToTest: Array> = [ - ['0', true], - ['n', true], - ['no', true], - ['f', true], - ['FALSE', true], - ['off', true], - ['1', false], - ['y', false], - ['yes', false], - ['t', false], - ['TRUE', false], - ['on', false], - ['', false], - ['somethingsilly', false], - ]; - - it.each(valuesToTest)( - 'takes string "%s" and returns %s', - (input, output) => { - // Prepare - const service = new EnvironmentVariablesService(); - // Act - const value = service.isValueFalse(input as string); - // Assess - expect(value).toBe(output); - } - ); - }); - - describe('Method: isDevMode', () => { - it('returns true if the environment variable POWERTOOLS_DEV is "true"', () => { - // Prepare - process.env.POWERTOOLS_DEV = 'true'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.isDevMode(); - - // Assess - expect(value).toEqual(true); - }); - - it('returns false if the environment variable POWERTOOLS_DEV is "false"', () => { - // Prepare - process.env.POWERTOOLS_DEV = 'false'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.isDevMode(); - - // Assess - expect(value).toEqual(false); - }); - - it('returns false if the environment variable POWERTOOLS_DEV is NOT set', () => { - // Prepare - process.env.POWERTOOLS_DEV = 'somethingsilly'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.isDevMode(); - - // Assess - expect(value).toEqual(false); - }); - - it('returns false if the environment variable POWERTOOLS_DEV is "somethingsilly"', () => { - // Prepare - process.env.POWERTOOLS_DEV = 'somethingsilly'; - const service = new EnvironmentVariablesService(); - - // Act - const value = service.isDevMode(); - - // Assess - expect(value).toEqual(false); - }); - }); -}); diff --git a/packages/idempotency/src/IdempotencyConfig.ts b/packages/idempotency/src/IdempotencyConfig.ts index b93a14e5be..c26318aa60 100644 --- a/packages/idempotency/src/IdempotencyConfig.ts +++ b/packages/idempotency/src/IdempotencyConfig.ts @@ -1,7 +1,7 @@ +import { getBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env'; import { PowertoolsFunctions } from '@aws-lambda-powertools/jmespath/functions'; import type { JMESPathParsingOptions } from '@aws-lambda-powertools/jmespath/types'; import type { Context } from 'aws-lambda'; -import { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js'; import type { IdempotencyConfigOptions, ResponseHook, @@ -64,7 +64,6 @@ class IdempotencyConfig { * Use the local cache to store idempotency keys. */ public useLocalCache: boolean; - readonly #envVarsService: EnvironmentVariablesService; readonly #enabled: boolean = true; public constructor(config: IdempotencyConfigOptions) { @@ -80,8 +79,11 @@ class IdempotencyConfig { this.hashFunction = config.hashFunction ?? 'md5'; this.lambdaContext = config.lambdaContext; this.responseHook = config.responseHook; - this.#envVarsService = new EnvironmentVariablesService(); - this.#enabled = this.#envVarsService.getIdempotencyEnabled(); + this.#enabled = !getBooleanFromEnv({ + key: 'POWERTOOLS_IDEMPOTENCY_DISABLED', + defaultValue: false, + extendedParsing: true, + }); } /** diff --git a/packages/idempotency/src/config/EnvironmentVariablesService.ts b/packages/idempotency/src/config/EnvironmentVariablesService.ts deleted file mode 100644 index 36af2c4b4a..0000000000 --- a/packages/idempotency/src/config/EnvironmentVariablesService.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { EnvironmentVariablesService as CommonEnvironmentVariablesService } from '@aws-lambda-powertools/commons'; -import type { ConfigServiceInterface } from '../types/ConfigServiceInterface.js'; - -/** - * Class EnvironmentVariablesService - * - * This class is used to return environment variables that are available in the runtime of - * the current Lambda invocation. - * These variables can be a mix of runtime environment variables set by AWS and - * variables that can be set by the developer additionally. - * - * @class - * @extends {CommonEnvironmentVariablesService} - * @see https://docs.aws.amazon.com/lambda/latest/dg/configuration-envvars.html#configuration-envvars-runtime - * @see https://docs.powertools.aws.dev/lambda/typescript/latest/#environment-variables - */ -class EnvironmentVariablesService - extends CommonEnvironmentVariablesService - implements ConfigServiceInterface -{ - // Reserved environment variables - private readonly functionNameVariable = 'AWS_LAMBDA_FUNCTION_NAME'; - private readonly idempotencyDisabledVariable = - 'POWERTOOLS_IDEMPOTENCY_DISABLED'; - - /** - * It returns the value of the AWS_LAMBDA_FUNCTION_NAME environment variable. - * - * @returns {string} - */ - public getFunctionName(): string { - return this.get(this.functionNameVariable); - } - - /** - * It returns whether the idempotency feature is enabled or not. - * - * Reads the value of the POWERTOOLS_IDEMPOTENCY_DISABLED environment variable. - * - * @returns {boolean} - */ - public getIdempotencyEnabled(): boolean { - return !this.isValueTrue(this.get(this.idempotencyDisabledVariable)); - } -} - -export { EnvironmentVariablesService }; diff --git a/packages/idempotency/src/persistence/BasePersistenceLayer.ts b/packages/idempotency/src/persistence/BasePersistenceLayer.ts index 2ca6690336..55c9e34418 100644 --- a/packages/idempotency/src/persistence/BasePersistenceLayer.ts +++ b/packages/idempotency/src/persistence/BasePersistenceLayer.ts @@ -1,9 +1,9 @@ import { createHash, type Hash } from 'node:crypto'; import type { JSONValue } from '@aws-lambda-powertools/commons/types'; import { LRUCache } from '@aws-lambda-powertools/commons/utils/lru-cache'; +import { getStringFromEnv } from '@aws-lambda-powertools/commons/utils/env'; import { search } from '@aws-lambda-powertools/jmespath'; import type { JMESPathParsingOptions } from '@aws-lambda-powertools/jmespath/types'; -import { EnvironmentVariablesService } from '../config/EnvironmentVariablesService.js'; import { IdempotencyRecordStatus } from '../constants.js'; import { deepSort } from '../deepSort.js'; import { @@ -27,8 +27,6 @@ abstract class BasePersistenceLayer implements BasePersistenceLayerInterface { public idempotencyKeyPrefix: string; private cache?: LRUCache; private configured = false; - // envVarsService is always initialized in the constructor - private readonly envVarsService!: EnvironmentVariablesService; private eventKeyJmesPath?: string; protected expiresAfterSeconds: number = 60 * 60; // 1 hour default private hashFunction = 'md5'; @@ -39,8 +37,10 @@ abstract class BasePersistenceLayer implements BasePersistenceLayerInterface { #jmesPathOptions?: JMESPathParsingOptions; public constructor() { - this.envVarsService = new EnvironmentVariablesService(); - this.idempotencyKeyPrefix = this.getEnvVarsService().getFunctionName(); + this.idempotencyKeyPrefix = getStringFromEnv({ + key: 'AWS_LAMBDA_FUNCTION_NAME', + errorMessage: 'AWS_LAMBDA_FUNCTION_NAME environment variable is required', + }); } /** @@ -244,14 +244,6 @@ abstract class BasePersistenceLayer implements BasePersistenceLayerInterface { return hash.digest('base64'); } - /** - * Getter for `envVarsService`. - * Used internally during initialization. - */ - private getEnvVarsService(): EnvironmentVariablesService { - return this.envVarsService; - } - /** * Creates the expiry timestamp for the idempotency record * diff --git a/packages/idempotency/tests/unit/EnvironmentVariableService.test.ts b/packages/idempotency/tests/unit/EnvironmentVariableService.test.ts deleted file mode 100644 index 86ac2cc68a..0000000000 --- a/packages/idempotency/tests/unit/EnvironmentVariableService.test.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { afterEach, beforeEach, describe, expect, it } from 'vitest'; -import { EnvironmentVariablesService } from '../../src/config/EnvironmentVariablesService.js'; - -describe('Class: EnvironmentVariableService', () => { - const ENVIRONMENT_VARIABLES = process.env; - - beforeEach(() => { - process.env = { ...ENVIRONMENT_VARIABLES }; - }); - - afterEach(() => { - process.env = ENVIRONMENT_VARIABLES; - }); - - describe('Method: getFunctionName', () => { - it('gets the Lambda function name from the environment variable', () => { - // Prepare - const expectedName = 'test-function'; - process.env.AWS_LAMBDA_FUNCTION_NAME = expectedName; - - // Act - const lambdaName = new EnvironmentVariablesService().getFunctionName(); - - // Assess - expect(lambdaName).toEqual(expectedName); - }); - - it('it returns an empty string when the Lambda function name is not set', () => { - // Prepare - process.env.AWS_LAMBDA_FUNCTION_NAME = undefined; - - // Act - const lambdaName = new EnvironmentVariablesService().getFunctionName(); - - // Assess - expect(lambdaName).toEqual(''); - }); - }); -});