diff --git a/packages/commons/src/envUtils.ts b/packages/commons/src/envUtils.ts index 3c561187a..fe1c459b6 100644 --- a/packages/commons/src/envUtils.ts +++ b/packages/commons/src/envUtils.ts @@ -113,6 +113,9 @@ const getNumberFromEnv = ({ return parsedValue; }; +const truthyValues = new Set(['1', 'y', 'yes', 't', 'true', 'on']); +const falsyValues = new Set(['0', 'n', 'no', 'f', 'false', 'off']); + /** * Get a boolean from the environment variables. * @@ -140,71 +143,44 @@ const getNumberFromEnv = ({ * }); * ``` * - * @param options - The options for getting the boolean. - * @param options.key - The key of the environment variable. - * @param options.defaultValue - The default value to return if the environment variable is not set. - * @param options.errorMessage - Optional error message to throw if the environment variable is not set and no default value is provided. Defaults to `"Environment variable is required"`. - */ -const getBooleanFromEnv = ({ - key, - defaultValue, - errorMessage, -}: GetBooleanFromEnvOptions): boolean => { - const value = getStringFromEnv({ - key, - defaultValue: String(defaultValue), - errorMessage, - }); - - const parsedValue = value.toLowerCase(); - - if (parsedValue !== 'true' && parsedValue !== 'false') { - throw new Error(`Environment variable ${key} must be a boolean`); - } - - return parsedValue === 'true'; -}; - -const truthyValues = new Set(['1', 'y', 'yes', 't', 'true', 'on']); - -/** - * Get a truthy boolean from the environment variables. - * - * Truthy values are: `1`, `y`, `yes`, `t`, `true`, `on`. + * By default, the value is parsed as a boolean. You can also provide an option to extend the parsing of the boolean value to include common string representations. * * @example * ```ts - * import { getTruthyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env'; + * import { getBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env'; * - * const myEnvVar = getTruthyBooleanFromEnv({ + * const myEnvVar = getBooleanFromEnv({ * key: 'MY_ENV_VAR', - * errorMessage: 'MY_ENV_VAR is required for this function', + * defaultValue: true, + * extendedParsing: true, * }); * ``` * - * By default, the value is trimmed before being converted to a boolean and always required. - * - * You can also provide a default value, which will be returned if the environment variable is not set instead of throwing an error. - * - * @example - * ```ts - * import { getTruthyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env'; + * The following values are considered `true`: + * - `"true"` + * - `"1"` + * - `"yes"` + * - `"on"` + * - `"y"` * - * const myEnvVar = getTruthyBooleanFromEnv({ - * key: 'MY_ENV_VAR', - * defaultValue: true, - * }); - * ``` + * The following values are considered `false`: + * - `"false"` + * - `"0"` + * - `"no"` + * - `"off"` + * - `"n"` * - * @param options - The options for getting the truthy boolean. + * @param options - The options for getting the boolean. * @param options.key - The key of the environment variable. * @param options.defaultValue - The default value to return if the environment variable is not set. * @param options.errorMessage - Optional error message to throw if the environment variable is not set and no default value is provided. Defaults to `"Environment variable is required"`. + * @param options.extendedParsing - Whether to extend the parsing of the boolean value to include common string representations like `'1'`, `'y'`, `'yes'`, `'t'`, `'true'`, `'on'` for `true` and `'0'`, `'n'`, `'no'`, `'f'`, `'false'`, `'off'` for `false`. */ -const getTruthyBooleanFromEnv = ({ +const getBooleanFromEnv = ({ key, defaultValue, errorMessage, + extendedParsing, }: GetBooleanFromEnvOptions): boolean => { const value = getStringFromEnv({ key, @@ -212,56 +188,22 @@ const getTruthyBooleanFromEnv = ({ errorMessage, }); - return truthyValues.has(value.toLowerCase()); -}; + const parsedValue = value.toLowerCase(); -const falsyValues = new Set(['0', 'n', 'no', 'f', 'false', 'off']); + if (extendedParsing) { + if (truthyValues.has(parsedValue)) { + return true; + } + if (falsyValues.has(parsedValue)) { + return false; + } + } -/** - * Get a falsy boolean from the environment variables. - * - * Falsy values are: `0`, `n`, `no`, `f`, `false`, `off`. - * - * @example - * ```ts - * import { getFalsyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env'; - * - * const myEnvVar = getFalsyBooleanFromEnv({ - * key: 'MY_ENV_VAR', - * errorMessage: 'MY_ENV_VAR is required for this function', - * }); - * ``` - * - * By default, the value is trimmed before being converted to a boolean and always required. - * - * You can also provide a default value, which will be returned if the environment variable is not set instead of throwing an error. - * - * @example - * ```ts - * import { getFalsyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env'; - * - * const myEnvVar = getFalsyBooleanFromEnv({ - * key: 'MY_ENV_VAR', - * defaultValue: false, - * }); - * ``` - * - * @param options - The options for getting the falsy boolean. - * @param options.key - The key of the environment variable. - * @param options.defaultValue - The default value to return if the environment variable is not set. - * @param options.errorMessage - Optional error message to throw if the environment variable is not set and no default value is provided. Defaults to `"Environment variable is required"`. - */ -const getFalsyBooleanFromEnv = ({ - key, - defaultValue, - errorMessage, -}: GetBooleanFromEnvOptions): boolean => { - const value = getStringFromEnv({ - key, - defaultValue: String(defaultValue), - errorMessage, - }); - return falsyValues.has(value.toLowerCase()); + if (parsedValue !== 'true' && parsedValue !== 'false') { + throw new Error(`Environment variable ${key} must be a boolean`); + } + + return parsedValue === 'true'; }; /** @@ -277,10 +219,14 @@ const getFalsyBooleanFromEnv = ({ * ``` */ const isDevMode = (): boolean => { - return getTruthyBooleanFromEnv({ - key: POWERTOOLS_DEV_ENV_VAR, - defaultValue: false, - }); + try { + return getBooleanFromEnv({ + key: POWERTOOLS_DEV_ENV_VAR, + extendedParsing: true, + }); + } catch (error) { + return false; + } }; /** @@ -359,8 +305,6 @@ export { getStringFromEnv, getNumberFromEnv, getBooleanFromEnv, - getTruthyBooleanFromEnv, - getFalsyBooleanFromEnv, isDevMode, getServiceName, getXrayTraceDataFromEnv, diff --git a/packages/commons/src/types/envUtils.ts b/packages/commons/src/types/envUtils.ts index b7ab42c3a..3e611fc83 100644 --- a/packages/commons/src/types/envUtils.ts +++ b/packages/commons/src/types/envUtils.ts @@ -47,6 +47,26 @@ type GetBooleanFromEnvOptions = { * @default "Environment variable is required" */ errorMessage?: string; + /** + * Whether to extend the parsing of the boolean value to include common string representations. + * + * The following values are considered `true`: + * - `"true"` + * - `"1"` + * - `"yes"` + * - `"on"` + * - `"y"` + * + * The following values are considered `false`: + * - `"false"` + * - `"0"` + * - `"no"` + * - `"off"` + * - `"n"` + * + * @default false + */ + extendedParsing?: boolean; }; export type { diff --git a/packages/commons/tests/unit/envUtils.test.ts b/packages/commons/tests/unit/envUtils.test.ts index a58fd8e61..1c32bceb3 100644 --- a/packages/commons/tests/unit/envUtils.test.ts +++ b/packages/commons/tests/unit/envUtils.test.ts @@ -1,11 +1,9 @@ import { beforeEach, describe, expect, it } from 'vitest'; import { getBooleanFromEnv, - getFalsyBooleanFromEnv, getNumberFromEnv, getServiceName, getStringFromEnv, - getTruthyBooleanFromEnv, getXRayTraceIdFromEnv, isDevMode, isRequestXRaySampled, @@ -162,9 +160,7 @@ describe('Functions: envUtils', () => { 'Environment variable TEST_ENV must be a boolean' ); }); - }); - describe('Function: getTruthyBooleanFromEnv', () => { it.each([ ['1', true], ['y', true], @@ -179,7 +175,10 @@ describe('Functions: envUtils', () => { process.env.TEST_ENV = value; // Act - const result = getTruthyBooleanFromEnv({ key: 'TEST_ENV' }); + const result = getBooleanFromEnv({ + key: 'TEST_ENV', + extendedParsing: true, + }); // Assess expect(result).toBe(expected); @@ -187,11 +186,12 @@ describe('Functions: envUtils', () => { ); it.each([ - ['', false], - ['false', false], - ['fasle', false], - ['somethingsilly', false], ['0', false], + ['n', false], + ['no', false], + ['f', false], + ['FALSE', false], + ['off', false], ])( 'returns false if the environment variable is set to a falsy value: %s', (value, expected) => { @@ -199,86 +199,15 @@ describe('Functions: envUtils', () => { process.env.TEST_ENV = value; // Act - const result = getTruthyBooleanFromEnv({ key: 'TEST_ENV' }); - - // Assess - expect(result).toBe(expected); - } - ); - - it('returns the default value if the environment variable is not set', () => { - // Prepare - process.env.TEST_ENV = undefined; - - // Act - const result = getTruthyBooleanFromEnv({ - key: 'TEST_ENV', - defaultValue: true, - }); - - // Assess - expect(result).toBe(true); - }); - }); - - describe('Function: getFalsyBooleanFromEnv', () => { - it.each([ - ['0', true], - ['n', true], - ['no', true], - ['f', true], - ['FALSE', true], - ['off', true], - ])( - 'returns true if the environment variable is set to a truthy value: %s', - (value, expected) => { - // Prepare - process.env.TEST_ENV = value; - - // Act - const result = getFalsyBooleanFromEnv({ key: 'TEST_ENV' }); - - // Assess - expect(result).toBe(expected); - } - ); - - it.each([ - ['1', false], - ['y', false], - ['yes', false], - ['t', false], - ['TRUE', false], - ['on', false], - ['', false], - ['somethingsilly', false], - ])( - 'returns false if the environment variable is set to a falsy value: %s', - (value, expected) => { - // Prepare - process.env.TEST_ENV = value; - - // Act - const result = getFalsyBooleanFromEnv({ key: 'TEST_ENV' }); + const result = getBooleanFromEnv({ + key: 'TEST_ENV', + extendedParsing: true, + }); // Assess expect(result).toBe(expected); } ); - - it('returns the default value if the environment variable is not set', () => { - // Prepare - process.env.TEST_ENV = undefined; - - // Act - const result = getFalsyBooleanFromEnv({ - key: 'TEST_ENV', - defaultValue: false, - }); - - // Assess - expect(result).toBe(true); - }); }); describe('Function: isDevMode', () => {