Skip to content

Commit

Permalink
Merge branch 'feature/add-get-array-functions'
Browse files Browse the repository at this point in the history
  • Loading branch information
Korzun committed Apr 22, 2024
2 parents cf4c526 + a5d954a commit dae92f8
Show file tree
Hide file tree
Showing 5 changed files with 445 additions and 3 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"description": "Simple Node.js Application Configuration Utility",
"private": false,
"license": "MIT",
"version": "1.0.2",
"version": "1.0.3",
"keywords": [
"config",
"registry",
Expand Down
124 changes: 123 additions & 1 deletion src/number.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
NotDefinedConfigError,
RangeValueConfigError,
} from './error';
import { getNumber } from './number';
import { getNumber, getNumberArray } from './number';

describe('getNumber', () => {
let env: Record<string, string | undefined>;
Expand Down Expand Up @@ -122,3 +122,125 @@ describe('getNumber', () => {
});
});
});

describe('getNumberArray', () => {
let env: Record<string, string | undefined>;
beforeEach(() => {
env = Object.assign({}, process.env);
});
Object.assign({}, process.env);
afterEach(() => {
process.env = env;
});

describe('environment variable is set', () => {
it('returns the environment variable as an array of numbers', () => {
process.env.TEST_NUMBER = '10.33,20.33,30.33';
const value = getNumberArray('TEST_NUMBER');
expect(value).toEqual([10.33, 20.33, 30.33]);
});
describe('allow undefined', () => {
it('returns the environment variable as an array of numbers', () => {
process.env.TEST_NUMBER = '10.33,20.33,30.33';
const value = getNumberArray('TEST_NUMBER', { allowUndefined: true });
expect(value).toEqual([10.33, 20.33, 30.33]);
});
});
describe('default is set', () => {
it('returns the environment variable as an array of numbers', () => {
process.env.TEST_NUMBER = '10.33,20.33,30.33';
const value = getNumberArray('TEST_NUMBER', { default: [10, 20] });
expect(value).toEqual([10.33, 20.33, 30.33]);
});
});
describe('allow list is defined', () => {
describe('all environmental variables numbers are in allow list', () => {
it('return the environmental variable as an array of numbers', () => {
process.env.TEST_NUMBER = '10.33,20.33,30.33';
const value = getNumberArray('TEST_NUMBER', {
allowList: [10.33, 20.33, 30.33],
});
expect(value).toEqual([10.33, 20.33, 30.33]);
});
});
describe('one of the environmental variable numbers is NOT in allow list', () => {
it('throws an error', () => {
process.env.TEST_NUMBER = '10.33,20.33,30.33';
expect(() => {
getNumberArray('TEST_NUMBER', { allowList: [10.33, 20.33] });
}).toThrow(
new ListValueConfigError('TEST_NUMBER', 30.33, [10.33, 20.33]),
);
});
});
});
describe('allow range is defined', () => {
describe('all environmental variable numbers are within allowable range', () => {
it('return the environmental variables as an array of numbers', () => {
process.env.TEST_NUMBER = '10.33,20.33,30.33';
const value = getNumberArray('TEST_NUMBER', {
allowRange: [10, 40],
});
expect(value).toEqual([10.33, 20.33, 30.33]);
});
});
describe('one of the environmental variable numbers is NOT within allowable range', () => {
it('throws an error', () => {
process.env.TEST_NUMBER = '10.33,20.33,30.33';
expect(() => {
getNumberArray('TEST_NUMBER', { allowRange: [10, 30] });
}).toThrow(new RangeValueConfigError('TEST_NUMBER', 30.33, [10, 30]));
});
});
});
});
describe('environment variable is set to an empty string', () => {
it('throws an error', () => {
process.env.TEST_NUMBER = '';
expect(() => {
getNumberArray('TEST_NUMBER');
}).toThrow(new NotDefinedConfigError('TEST_NUMBER'));
});

describe('allow undefined', () => {
it('returns an empty array', () => {
process.env.TEST_NUMBER = '';
const value = getNumberArray('TEST_NUMBER', { allowUndefined: true });
expect(value).toEqual([]);
});
});

describe('default is set', () => {
it('returns the default', () => {
process.env.TEST_NUMBER = '';
const value = getNumberArray('TEST_NUMBER', {
default: [10.33, 20.33],
});
expect(value).toEqual([10.33, 20.33]);
});
});
});
describe('environment variable is not set', () => {
it('throws an error', () => {
expect(() => {
getNumberArray('TEST_NUMBER');
}).toThrow(new NotDefinedConfigError('TEST_NUMBER'));
});

describe('allow undefined', () => {
it('returns an empty array', () => {
const value = getNumberArray('TEST_NUMBER', { allowUndefined: true });
expect(value).toEqual([]);
});
});

describe('default is set', () => {
it('returns the default', () => {
const value = getNumberArray('TEST_NUMBER', {
default: [10.33, 20.33],
});
expect(value).toEqual([10.33, 20.33]);
});
});
});
});
131 changes: 131 additions & 0 deletions src/number.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,137 @@ export function getNumber(name: string, options: GetNumberOptions = {}) {
throw error;
}

type GetNumberArrayOptionsAllowList = {
allowList?: number[];
allowRange?: undefined;
};
type GetNumberArrayOptionsAllowRange = {
allowList?: undefined;
allowRange?: [number, number];
};
type GetNumberArrayOptionsAllow =
| GetNumberArrayOptionsAllowList
| GetNumberArrayOptionsAllowRange;

type GetNumberArrayOptionsAllowUndefined = {
allowUndefined: true;
default?: undefined;
} & GetNumberArrayOptionsAllow;
type GetNumberArrayOptionsNoDefault = {
allowUndefined?: false;
default?: undefined;
} & GetNumberArrayOptionsAllow;
type GetNumberArrayOptionsDefault = {
allowUndefined?: false;
default: number[];
} & GetNumberArrayOptionsAllow;

export type GetNumberArrayOptions =
| GetNumberArrayOptionsAllowUndefined
| GetNumberArrayOptionsNoDefault
| GetNumberArrayOptionsDefault;

/**
* Returns an environmental variable as a `number` array. Optionally the value
* can be validated by an `allowList` or `allowRange`.
*/
export function getNumberArray(
name: string,
options: {
allowUndefined: true;
default?: undefined;
} & (
| {
allowList?: undefined;
allowRange?: undefined;
}
| {
allowList: number[];
}
| {
allowRange: [number, number];
}
),
): number[];
/**
* Returns an environmental variable as a `number` array or, if undefined,
* throws an error. Optionally the value can be validated by an `allowList` or
* `allowRange`.
*/
export function getNumberArray(
name: string,
options?: {
allowUndefined?: false;
default?: undefined;
} & (
| {
allowList?: undefined;
allowRange?: undefined;
}
| {
allowList: number[];
}
| {
allowRange: [number, number];
}
),
): number[];
/**
* Returns an environmental variable as a `number` array or, if undefined, the
* provided default value. Optionally the value can be validated by an
* `allowList` or `allowRange`.
*/
export function getNumberArray(
name: string,
options: {
allowUndefined?: false;
default: number[];
} & (
| {
allowList?: undefined;
allowRange?: undefined;
}
| {
allowList: number[];
}
| {
allowRange: [number, number];
}
),
): number[];
export function getNumberArray(
name: string,
options: GetNumberArrayOptions = {},
) {
const {
allowList,
allowRange,
allowUndefined,
default: defaultValue,
} = options;
const stringValue = process.env[name];
if (stringValue !== undefined && stringValue !== '') {
const values = stringValue.split(',').map((value) => {
const numberValue = Number(value);
validateList(name, value, numberValue, allowList);
validateRange(name, value, numberValue, allowRange);
return numberValue;
});
return values;
}
if (defaultValue !== undefined) {
return defaultValue;
}
if (allowUndefined) {
return [];
}
const error = new NotDefinedConfigError(name);
if (Error.captureStackTrace) {
Error.captureStackTrace(error, getNumberArray);
}
throw error;
}

const validateList = (
name: string,
stringValue: string,
Expand Down
109 changes: 108 additions & 1 deletion src/string.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NotDefinedConfigError, ListValueConfigError } from './error';
import { getString } from './string';
import { getString, getStringArray } from './string';

describe('getString', () => {
let env: Record<string, string | undefined>;
Expand Down Expand Up @@ -99,3 +99,110 @@ describe('getString', () => {
});
});
});

describe('getStringArray', () => {
let env: Record<string, string | undefined>;
beforeEach(() => {
env = Object.assign({}, process.env);
});
Object.assign({}, process.env);
afterEach(() => {
process.env = env;
});
describe('environment variable is set', () => {
it('returns the environment variable as an array of strings', () => {
process.env.TEST_STRING_ARRAY = 'foo,bar,baz';
const value = getStringArray('TEST_STRING_ARRAY');
expect(value).toEqual(['foo', 'bar', 'baz']);
});
describe('allow undefined', () => {
it('returns the environment variable as an array of strings', () => {
process.env.TEST_STRING_ARRAY = 'foo,bar,baz';
const value = getStringArray('TEST_STRING_ARRAY', {
allowUndefined: true,
});
expect(value).toEqual(['foo', 'bar', 'baz']);
});
});
describe('default is set', () => {
it('returns the environment variable as an array of strings', () => {
process.env.TEST_STRING_ARRAY = 'foo,bar,baz';
const value = getStringArray('TEST_STRING_ARRAY', { default: ['bar'] });
expect(value).toEqual(['foo', 'bar', 'baz']);
});
});
describe('allow list is defined', () => {
describe('environmental variable is in allow list', () => {
it('return the environmental variable as an array of strings', () => {
process.env.TEST_STRING_ARRAY = 'foo,bar,baz';
const value = getStringArray('TEST_STRING_ARRAY', {
allowList: ['foo', 'bar', 'baz'],
});
expect(value).toEqual(['foo', 'bar', 'baz']);
});
});
describe('environmental variable is NOT in allow list', () => {
it('throws an error', () => {
process.env.TEST_STRING_ARRAY = 'foo,bar,baz';
expect(() => {
getStringArray('TEST_STRING_ARRAY', { allowList: ['foo', 'baz'] });
}).toThrow(
new ListValueConfigError('TEST_STRING_ARRAY', 'bar', [
'foo',
'baz',
]),
);
});
});
});
});
describe('environment variable is set to an empty string', () => {
it('throws an error', () => {
process.env.TEST_STRING_ARRAY = '';
expect(() => {
getStringArray('TEST_STRING_ARRAY');
}).toThrow(new NotDefinedConfigError('TEST_STRING_ARRAY'));
});

describe('allow undefined', () => {
it('returns an empty array', () => {
process.env.TEST_STRING_ARRAY = '';
const value = getStringArray('TEST_STRING_ARRAY', {
allowUndefined: true,
});
expect(value).toEqual([]);
});
});

describe('default is set', () => {
it('returns the default', () => {
process.env.TEST_STRING_ARRAY = '';
const value = getStringArray('TEST_STRING_ARRAY', { default: ['bar'] });
expect(value).toEqual(['bar']);
});
});
});
describe('environment variable is not set', () => {
it('throws an error', () => {
expect(() => {
getStringArray('TEST_STRING_ARRAY');
}).toThrow(new NotDefinedConfigError('TEST_STRING_ARRAY'));
});

describe('allow undefined', () => {
it('returns an empty array', () => {
const value = getStringArray('TEST_STRING_ARRAY', {
allowUndefined: true,
});
expect(value).toEqual([]);
});
});

describe('default is set', () => {
it('returns the default', () => {
const value = getStringArray('TEST_STRING_ARRAY', { default: ['bar'] });
expect(value).toEqual(['bar']);
});
});
});
});
Loading

0 comments on commit dae92f8

Please sign in to comment.