@thinkmill/devops-env-vars
Advanced tools
Comparing version 1.2.0 to 2.0.0
39
index.js
@@ -108,9 +108,10 @@ 'use strict'; | ||
const varRule = rules[varName]; | ||
let supplied; | ||
if (processEnv.hasOwnProperty(varName)) { | ||
debug(`${chalk.cyan(varName)} setting from processEnv: '${chalk.yellow(processEnv[varName])}'`); | ||
config[varName] = processEnv[varName]; | ||
supplied = processEnv[varName]; | ||
} | ||
if (varRule.required && !config.hasOwnProperty(varName)) { | ||
if (varRule.required && typeof supplied === 'undefined') { | ||
debug(`${chalk.cyan(varName)} not set and required; throwing error...`); | ||
@@ -120,6 +121,36 @@ throw new Error(`Environment var validation: The var '${varName}' is marked as required but has not been supplied.`); | ||
if (varRule.hasOwnProperty('default') && !config.hasOwnProperty(varName)) { | ||
if (varRule.hasOwnProperty('default') && typeof supplied === 'undefined') { | ||
debug(`${chalk.cyan(varName)} not set; defaulting to ${chalk.red(varRule.default)}`); | ||
config[varName] = varRule.default; | ||
supplied = varRule.default; | ||
} | ||
// Coerce the value to the type specifed (if specified) | ||
if (varRule.hasOwnProperty('type')) { | ||
const suppliedStr = supplied.toString().toLowerCase(); | ||
const suppliedNum = parseInt(suppliedStr); | ||
// Error if the value supplied can't be clearly interpreted as the correct type | ||
if (varRule.type === Boolean) { | ||
if (typeof supplied !== 'boolean' && !['yes', 'true', 'y', 't', 'false', 'no', 'f', 'n'].includes(suppliedStr) && isNaN(suppliedNum)) { | ||
throw new Error(`Environment var supplied for '${varName}' is defined as a Boolean but the value supplied can't be reliably interpreted as one`); | ||
} | ||
supplied = (supplied === true || ['yes', 'true', 'y', 't'].includes(suppliedStr) || suppliedNum > 0 || suppliedNum < 0); | ||
} | ||
else if (varRule.type === Number) { | ||
if (isNaN(suppliedNum)) { | ||
throw new Error(`Environment var supplied for '${varName}' is defined as a Number but the value supplied can't be reliably interpreted as one`); | ||
} | ||
supplied = suppliedNum; | ||
} | ||
else if (varRule.type === String) { | ||
if (supplied !== suppliedStr) { | ||
throw new Error(`Environment var supplied for '${varName}' is defined as a String but the value supplied can't be reliably interpreted as one`); | ||
} | ||
} | ||
else { | ||
throw new Error(`Environment var '${varName}' specifies an unrecognised type: '${varRule.type.name}'`); | ||
} | ||
} | ||
config[varName] = supplied; | ||
} | ||
@@ -126,0 +157,0 @@ |
{ | ||
"name": "@thinkmill/devops-env-vars", | ||
"version": "1.2.0", | ||
"version": "2.0.0", | ||
"description": "Helper functions that encapsulate our treatment of environment vars for KeystoneJS apps", | ||
@@ -5,0 +5,0 @@ "main": "index.js", |
Devops: Environment Variables | ||
============================= | ||
================================================================================ | ||
@@ -7,3 +7,4 @@ A set of helper functions that encapsulate our treatment of environment vars for KeystoneJS apps and help us build a useful `config` object. | ||
## Usage | ||
Usage | ||
-------------------------------------------------------------------------------- | ||
@@ -69,2 +70,8 @@ The code block below demonstrates how this library should be used in a modern KeystoneJS app. | ||
// Recreate the entire DB | ||
RESET_DATABASE: { required: false, default: false, type: Boolean }, | ||
// What port should the webserver bind to | ||
PORT: { required: flags.IN_PRODUCTION, default: 3000, type: Number }, | ||
}); | ||
@@ -85,3 +92,4 @@ | ||
## Client-side Inclusion | ||
Client-side Inclusion | ||
-------------------------------------------------------------------------------- | ||
@@ -99,3 +107,4 @@ Since some of the config variables are also often needed client side, there's a temptation to simply require `config.js` there too. | ||
## `envLib.determineAppEnv(process.env.APP_ENV)` | ||
`envLib.determineAppEnv(process.env.APP_ENV)` | ||
-------------------------------------------------------------------------------- | ||
@@ -132,3 +141,4 @@ First, we call `determineAppEnv()`, which determines the current `APP_ENV` by inspecting the servers IP address the `APP_ENV` value supplied by `process.env` (if present): | ||
## `envLib.buildAppFlags(APP_ENV)` | ||
`envLib.buildAppFlags(APP_ENV)` | ||
-------------------------------------------------------------------------------- | ||
@@ -155,3 +165,4 @@ Once we have the `APP_ENV` we can use this function to build out a set of flags representing the different environments: | ||
## `dotenv.config(..)` | ||
`dotenv.config(..)` | ||
-------------------------------------------------------------------------------- | ||
@@ -177,3 +188,4 @@ Next, standard practice is to seek out a `.env` file in the directory above the application root, named for the current `APP_ENV`: | ||
## `envLib.mergeConfig(APP_ENV, flags, process.env, rules)` | ||
`envLib.mergeConfig(APP_ENV, flags, process.env, rules)` | ||
-------------------------------------------------------------------------------- | ||
@@ -199,2 +211,6 @@ The values loaded are next verified and assembled into the `config` object: | ||
Variables definitions can optionally include a `type`, being either `Boolean`, `Number` or `String` (or unspecified). | ||
If supplied, the value given by the environment will be interpreted as this type. | ||
If an appropriate value can't be unambiguously determined (ie. a value of "coffee" suppled for a `Boolean` value) an error will be thrown. | ||
As noted above, **the `mergeConfig()` function does not modify the `process.env` scope**. | ||
@@ -204,3 +220,4 @@ Variables that are defaulted based on the validation rules supplied will only exist in the object returned by `mergeConfig()`. | ||
## Other Config Values | ||
Other Config Values | ||
-------------------------------------------------------------------------------- | ||
@@ -292,3 +309,4 @@ Most apps will also use a number of values that don't need to be set externally (ie. by `process.env` or the `.env` file). | ||
## Exporting the Values | ||
Exporting the Values | ||
-------------------------------------------------------------------------------- | ||
@@ -295,0 +313,0 @@ The final lines in our example export the `config` object we've created for use by the app after |
23354
254
312
5