Skip to content

Commit 27aa289

Browse files
dreamorosiam29d
andauthored
chore(commons): consolidate boolean parsing (#3970)
Co-authored-by: Alexander Schueren <sha@amazon.com>
1 parent ab0730f commit 27aa289

File tree

3 files changed

+79
-186
lines changed

3 files changed

+79
-186
lines changed

packages/commons/src/envUtils.ts

Lines changed: 46 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,9 @@ const getNumberFromEnv = ({
113113
return parsedValue;
114114
};
115115

116+
const truthyValues = new Set(['1', 'y', 'yes', 't', 'true', 'on']);
117+
const falsyValues = new Set(['0', 'n', 'no', 'f', 'false', 'off']);
118+
116119
/**
117120
* Get a boolean from the environment variables.
118121
*
@@ -140,128 +143,67 @@ const getNumberFromEnv = ({
140143
* });
141144
* ```
142145
*
143-
* @param options - The options for getting the boolean.
144-
* @param options.key - The key of the environment variable.
145-
* @param options.defaultValue - The default value to return if the environment variable is not set.
146-
* @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 <key> is required"`.
147-
*/
148-
const getBooleanFromEnv = ({
149-
key,
150-
defaultValue,
151-
errorMessage,
152-
}: GetBooleanFromEnvOptions): boolean => {
153-
const value = getStringFromEnv({
154-
key,
155-
defaultValue: String(defaultValue),
156-
errorMessage,
157-
});
158-
159-
const parsedValue = value.toLowerCase();
160-
161-
if (parsedValue !== 'true' && parsedValue !== 'false') {
162-
throw new Error(`Environment variable ${key} must be a boolean`);
163-
}
164-
165-
return parsedValue === 'true';
166-
};
167-
168-
const truthyValues = new Set(['1', 'y', 'yes', 't', 'true', 'on']);
169-
170-
/**
171-
* Get a truthy boolean from the environment variables.
172-
*
173-
* Truthy values are: `1`, `y`, `yes`, `t`, `true`, `on`.
146+
* 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.
174147
*
175148
* @example
176149
* ```ts
177-
* import { getTruthyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env';
150+
* import { getBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env';
178151
*
179-
* const myEnvVar = getTruthyBooleanFromEnv({
152+
* const myEnvVar = getBooleanFromEnv({
180153
* key: 'MY_ENV_VAR',
181-
* errorMessage: 'MY_ENV_VAR is required for this function',
154+
* defaultValue: true,
155+
* extendedParsing: true,
182156
* });
183157
* ```
184158
*
185-
* By default, the value is trimmed before being converted to a boolean and always required.
186-
*
187-
* You can also provide a default value, which will be returned if the environment variable is not set instead of throwing an error.
188-
*
189-
* @example
190-
* ```ts
191-
* import { getTruthyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env';
159+
* The following values are considered `true`:
160+
* - `"true"`
161+
* - `"1"`
162+
* - `"yes"`
163+
* - `"on"`
164+
* - `"y"`
192165
*
193-
* const myEnvVar = getTruthyBooleanFromEnv({
194-
* key: 'MY_ENV_VAR',
195-
* defaultValue: true,
196-
* });
197-
* ```
166+
* The following values are considered `false`:
167+
* - `"false"`
168+
* - `"0"`
169+
* - `"no"`
170+
* - `"off"`
171+
* - `"n"`
198172
*
199-
* @param options - The options for getting the truthy boolean.
173+
* @param options - The options for getting the boolean.
200174
* @param options.key - The key of the environment variable.
201175
* @param options.defaultValue - The default value to return if the environment variable is not set.
202176
* @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 <key> is required"`.
177+
* @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`.
203178
*/
204-
const getTruthyBooleanFromEnv = ({
179+
const getBooleanFromEnv = ({
205180
key,
206181
defaultValue,
207182
errorMessage,
183+
extendedParsing,
208184
}: GetBooleanFromEnvOptions): boolean => {
209185
const value = getStringFromEnv({
210186
key,
211187
defaultValue: String(defaultValue),
212188
errorMessage,
213189
});
214190

215-
return truthyValues.has(value.toLowerCase());
216-
};
191+
const parsedValue = value.toLowerCase();
217192

218-
const falsyValues = new Set(['0', 'n', 'no', 'f', 'false', 'off']);
193+
if (extendedParsing) {
194+
if (truthyValues.has(parsedValue)) {
195+
return true;
196+
}
197+
if (falsyValues.has(parsedValue)) {
198+
return false;
199+
}
200+
}
219201

220-
/**
221-
* Get a falsy boolean from the environment variables.
222-
*
223-
* Falsy values are: `0`, `n`, `no`, `f`, `false`, `off`.
224-
*
225-
* @example
226-
* ```ts
227-
* import { getFalsyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env';
228-
*
229-
* const myEnvVar = getFalsyBooleanFromEnv({
230-
* key: 'MY_ENV_VAR',
231-
* errorMessage: 'MY_ENV_VAR is required for this function',
232-
* });
233-
* ```
234-
*
235-
* By default, the value is trimmed before being converted to a boolean and always required.
236-
*
237-
* You can also provide a default value, which will be returned if the environment variable is not set instead of throwing an error.
238-
*
239-
* @example
240-
* ```ts
241-
* import { getFalsyBooleanFromEnv } from '@aws-lambda-powertools/commons/utils/env';
242-
*
243-
* const myEnvVar = getFalsyBooleanFromEnv({
244-
* key: 'MY_ENV_VAR',
245-
* defaultValue: false,
246-
* });
247-
* ```
248-
*
249-
* @param options - The options for getting the falsy boolean.
250-
* @param options.key - The key of the environment variable.
251-
* @param options.defaultValue - The default value to return if the environment variable is not set.
252-
* @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 <key> is required"`.
253-
*/
254-
const getFalsyBooleanFromEnv = ({
255-
key,
256-
defaultValue,
257-
errorMessage,
258-
}: GetBooleanFromEnvOptions): boolean => {
259-
const value = getStringFromEnv({
260-
key,
261-
defaultValue: String(defaultValue),
262-
errorMessage,
263-
});
264-
return falsyValues.has(value.toLowerCase());
202+
if (parsedValue !== 'true' && parsedValue !== 'false') {
203+
throw new Error(`Environment variable ${key} must be a boolean`);
204+
}
205+
206+
return parsedValue === 'true';
265207
};
266208

267209
/**
@@ -277,10 +219,14 @@ const getFalsyBooleanFromEnv = ({
277219
* ```
278220
*/
279221
const isDevMode = (): boolean => {
280-
return getTruthyBooleanFromEnv({
281-
key: POWERTOOLS_DEV_ENV_VAR,
282-
defaultValue: false,
283-
});
222+
try {
223+
return getBooleanFromEnv({
224+
key: POWERTOOLS_DEV_ENV_VAR,
225+
extendedParsing: true,
226+
});
227+
} catch (error) {
228+
return false;
229+
}
284230
};
285231

286232
/**
@@ -359,8 +305,6 @@ export {
359305
getStringFromEnv,
360306
getNumberFromEnv,
361307
getBooleanFromEnv,
362-
getTruthyBooleanFromEnv,
363-
getFalsyBooleanFromEnv,
364308
isDevMode,
365309
getServiceName,
366310
getXrayTraceDataFromEnv,

packages/commons/src/types/envUtils.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,26 @@ type GetBooleanFromEnvOptions = {
4747
* @default "Environment variable <key> is required"
4848
*/
4949
errorMessage?: string;
50+
/**
51+
* Whether to extend the parsing of the boolean value to include common string representations.
52+
*
53+
* The following values are considered `true`:
54+
* - `"true"`
55+
* - `"1"`
56+
* - `"yes"`
57+
* - `"on"`
58+
* - `"y"`
59+
*
60+
* The following values are considered `false`:
61+
* - `"false"`
62+
* - `"0"`
63+
* - `"no"`
64+
* - `"off"`
65+
* - `"n"`
66+
*
67+
* @default false
68+
*/
69+
extendedParsing?: boolean;
5070
};
5171

5272
export type {

packages/commons/tests/unit/envUtils.test.ts

Lines changed: 13 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
import { beforeEach, describe, expect, it } from 'vitest';
22
import {
33
getBooleanFromEnv,
4-
getFalsyBooleanFromEnv,
54
getNumberFromEnv,
65
getServiceName,
76
getStringFromEnv,
8-
getTruthyBooleanFromEnv,
97
getXRayTraceIdFromEnv,
108
isDevMode,
119
isRequestXRaySampled,
@@ -162,9 +160,7 @@ describe('Functions: envUtils', () => {
162160
'Environment variable TEST_ENV must be a boolean'
163161
);
164162
});
165-
});
166163

167-
describe('Function: getTruthyBooleanFromEnv', () => {
168164
it.each([
169165
['1', true],
170166
['y', true],
@@ -179,106 +175,39 @@ describe('Functions: envUtils', () => {
179175
process.env.TEST_ENV = value;
180176

181177
// Act
182-
const result = getTruthyBooleanFromEnv({ key: 'TEST_ENV' });
178+
const result = getBooleanFromEnv({
179+
key: 'TEST_ENV',
180+
extendedParsing: true,
181+
});
183182

184183
// Assess
185184
expect(result).toBe(expected);
186185
}
187186
);
188187

189188
it.each([
190-
['', false],
191-
['false', false],
192-
['fasle', false],
193-
['somethingsilly', false],
194189
['0', false],
190+
['n', false],
191+
['no', false],
192+
['f', false],
193+
['FALSE', false],
194+
['off', false],
195195
])(
196196
'returns false if the environment variable is set to a falsy value: %s',
197197
(value, expected) => {
198198
// Prepare
199199
process.env.TEST_ENV = value;
200200

201201
// Act
202-
const result = getTruthyBooleanFromEnv({ key: 'TEST_ENV' });
203-
204-
// Assess
205-
expect(result).toBe(expected);
206-
}
207-
);
208-
209-
it('returns the default value if the environment variable is not set', () => {
210-
// Prepare
211-
process.env.TEST_ENV = undefined;
212-
213-
// Act
214-
const result = getTruthyBooleanFromEnv({
215-
key: 'TEST_ENV',
216-
defaultValue: true,
217-
});
218-
219-
// Assess
220-
expect(result).toBe(true);
221-
});
222-
});
223-
224-
describe('Function: getFalsyBooleanFromEnv', () => {
225-
it.each([
226-
['0', true],
227-
['n', true],
228-
['no', true],
229-
['f', true],
230-
['FALSE', true],
231-
['off', true],
232-
])(
233-
'returns true if the environment variable is set to a truthy value: %s',
234-
(value, expected) => {
235-
// Prepare
236-
process.env.TEST_ENV = value;
237-
238-
// Act
239-
const result = getFalsyBooleanFromEnv({ key: 'TEST_ENV' });
240-
241-
// Assess
242-
expect(result).toBe(expected);
243-
}
244-
);
245-
246-
it.each([
247-
['1', false],
248-
['y', false],
249-
['yes', false],
250-
['t', false],
251-
['TRUE', false],
252-
['on', false],
253-
['', false],
254-
['somethingsilly', false],
255-
])(
256-
'returns false if the environment variable is set to a falsy value: %s',
257-
(value, expected) => {
258-
// Prepare
259-
process.env.TEST_ENV = value;
260-
261-
// Act
262-
const result = getFalsyBooleanFromEnv({ key: 'TEST_ENV' });
202+
const result = getBooleanFromEnv({
203+
key: 'TEST_ENV',
204+
extendedParsing: true,
205+
});
263206

264207
// Assess
265208
expect(result).toBe(expected);
266209
}
267210
);
268-
269-
it('returns the default value if the environment variable is not set', () => {
270-
// Prepare
271-
process.env.TEST_ENV = undefined;
272-
273-
// Act
274-
const result = getFalsyBooleanFromEnv({
275-
key: 'TEST_ENV',
276-
defaultValue: false,
277-
});
278-
279-
// Assess
280-
expect(result).toBe(true);
281-
});
282211
});
283212

284213
describe('Function: isDevMode', () => {

0 commit comments

Comments
 (0)