EnvVars
Type : class
The EnvVars class is a versatile utility designed for type-safe access to environment variables. It simplifies handling environment variables by offering features such as type parsing, retrieving values tailored to specific environments, reading from various sources, and marking variables as dynamic. Additionally, it ensures robust error handling, preventing your application from proceeding with unexpected behavior when issues arise.
envVarsCustomEventEmitterErrorScope app error scope array
is exported by this utility and can be used to filter thrown
AppError
by scope for this specific utility.
Imagine the following scenario:
let PORT = +(process.env.PORT || 3000);let HOST = process.env.HOST || 'localhost';if (process.env.NODE_ENV === 'production') {  PORT = +process.env.PRODUCTION_PORT || throw new Error('Missing production port');  HOST = process.env.PRODUCTION_HOST || throw new Error('Missing production host');}This code snippet can become cumbersome to write, maintain, and debug, especially when you have multiple environments and the same variable is used in different places throughout your app.
The EnvVars class makes this code much easier to read and maintain, while also providing additional features and robust error handling.
Let’s take a look at how it works:
- 
Imagine your process.env object looks like this: {PORT: 3000,PRODUCTION_PORT: 5000,}
- 
Create an envVars.tsfile:export const envVars = new EnvVars({mapObj: {port: {parseAs: 'number',whenNodeEnvIs: {production: 'PRODUCTION_PORT',anyEnv: 'PORT',}},}});
- 
EnvVarstakes care of everything by selecting the appropriate value for the current environment, converting it to the correct type, marking it as dynamic if specified, and handling any errors.
 Then you can use the previousenvVars.tsfile in your code as follows:import { envVars } from './envVars';console.log(envVars.port); // process.env.NODE_ENV === 'production' ? 5000 : 3000
- 
if the currentEnv is productionthe previous example will log the number5000else it will log the number3000
Full Example
SECRET_VALUES=1,2,3,4import { EnvVars } from '@mustib/utils/node';
export const fromObject = {  PORT: '3000',}
export const envVars = new EnvVars({  useDynamicValues: true,  enumerable: true,  sources: {    fromFile: 'path to .env file',    fromObject,    fromDynamicFunction: () => ({      HOST: 'localhost',    })  },  mapObj: {    port: {      parseAs: 'number',      whenNodeEnvIs: {          anyEnv: 'PORT',      }},    host: {      whenNodeEnvIs: {          anyEnv: 'HOST',      }},    secretValues: {      parseAs(data) {        return data.varValueForCurrentEnv.split(',')      },      whenNodeEnvIs: {        anyEnv: 'SECRET_VALUES',      }    }  }})import { envVars, fromObject } from './envVars';
console.log(envVars) // { port: 3000, host: 'localhost', secretValues: [ '1', '2', '3', '4' ] }
fromObject.PORT = '5000'console.log(envVars) // { port: 5000, host: 'localhost', secretValues: [ '1', '2', '3', '4' ] }
console.log(Object.keys(envVars)) // [ 'port', 'host', 'secretValues' ]Constructor()
type EnvVars = new (options: ConstructorParams<EnvVarsMapObj>): EnvVars- parametersan object with the following properties:- 
useDynamicValues:- A booleanindicates whether the generated env object should be dynamic or not.
- Defaults to false.
 
- A 
- 
sources: Used to define the source of environment variables, which can be one of the following:- A stringrepresenting the path to a.envfile
- A single EnvVarsSourcesObj object, or an array of such objects.
 
- A 
- 
mapObj:EnvVarsMapObj
- 
currentEnv:- a stringrepresenting the current env.
- defaults to process.env.NODE_ENV.
 
- a 
- 
enumerable:- a booleanindicates whether the generated env object should be enumerable or not.
- defaults to false.
 
- a 
 
- 
EnvVarsMapObj
type EnvVarsMapObj = {  [varName: string]: {    parseAs?: ParseAsString | ParseAsFunction    whenNodeEnvIs: {      [envName: string | 'anyEnv']: string    }    useDynamicValue?: boolean  }}An object with variable names as keys and their configuration as object with the following properties:
- 
parseAs:used to convert the value of the env-var from string to the specified type, possible values are:- A stringwith the value of"string","number","bool","date"where each value corresponds to a predefinedparseAsFunction.
- A user-defined function whose return value determines the value and type of the environment variable.
- see parseAsFunction for more details.
 
 
- A 
- 
whenNodeEnvIs:an object defining the environment variables that should be used for each environment.- see whenNodeEnvIs for more details.
 
- 
useDynamicValue:abooleanindicates if the value is dynamic and will be parsed again every time it is needed
EnvVarsSourcesObj
type EnvVarsSourcesObj = {  fromFile: string;  fromObject: Record<string, string>;  fromDynamicFunction(): Record<string, string>;};An object that represents a source of environment variables with the following properties:
- fromFile:A- stringrepresenting the path to a- .envfile.
- fromObject:An object with environment variables.
- fromDynamicFunction:A function that returns an object with environment variables.
parseAsFunction
type ParseAsFunction = (data: {  combinedEnvVars: Record<string, string>[];  varValueForCurrentEnv: string;  currentEnv: string;  assignedSource: Record<string, string>;  varNameForCurrentEnv: string;}) => anyA user-defined function whose return value determines the value and type of the environment variable.
It will be called with a data object with the following properties:
- 
combinedEnvVars:an array of objects, each representing a source defined in theEnvVarsconstructor’s sources.
- 
varValueForCurrentEnv:the value of the varNameForCurrentEnv in assignedSource object.
- 
currentEnv:the current environment (the keys of thewhenNodeEnvIsobject).
- 
assignedSource:the first object from combinedEnvVars that has the varNameForCurrentEnv
- 
varNameForCurrentEnv:the name of the environment variable for the current environment (the value of the currentEnv from thewhenNodeEnvIsobject).
 For example:
 ifwhenNodeEnvIshas this value:const whenNodeEnvIs = {production: 'Prod_VAR',anyEnv: 'ANY_VAR',};then the varNameForCurrentEnvwill beProd_VARforproductionandANY_VARforanyEnv
whenNodeEnvIs
type WhenNodeEnvIs = Record<string | 'anyEnv', string>An object where the keys are possible environment names and the values are any valid key from combined sources object passed to the EnvVars constructor.
For example, if the environment is production, the value of the key production will be used. If the environment is development, the value of the key development will be used, and so on. If sources has PORT and HOST as variables, then possible values for the whenNodeEnvIs object are PORT and HOST.
The special key anyEnv can be used to specify a fallback value for any environment. This is useful when you want to provide a default value for an environment variable that is not defined in the current environment.