xenv-config v1.3.1
xenv-config
Load config from env, user config, or default spec.
Install
$ npm i xenv-config --saveUsage
const xenvConfig = require("xenv-config");
const spec = {
fooOption: { env: "FOO_OPTION", default: false },
barOption: { env: "BAR_OPTION", type: "number" },
zooOption: { default: false, type: "truthy" },
jsonOption: { env: "JSON_OPTION", type: "json" }
};
process.env.BAR_OPTION = "900";
process.env.JSON_OPTION = "{b:90}";
const config = xenvConfig(spec, { zooOption: true, jsonOption: { a: 50 } });
expect(config).to.deep.equal({
fooOption: false,
barOption: 900,
zooOption: true,
jsonOption: { a: 50, b: 90 }
});
expect(config.__$trace__).to.deep.equal({
fooOption: { src: "default" },
barOption: { src: "env", name: "BAR_OPTION" },
zooOption: { src: "option" },
jsonOption: { src: "env,option" }
});API
xenvConfig(spec, userConfig, options);spec- specification of the configsuserConfig- configuration from the user (use if not declared in env)options- options
Returns config object.
- Each key that exist has the value that's determined
- A hidden field
__$trace__that contains data to indicate where each config key's value was determined from
options:
_env- Object that represents environment instead ofprocess.envmerge- function to mergejsonobject instead of usingObject.assign
Spec
The spec is a JSON object with the following format:
{
"<optionKey>": {
env: "ENV_VAR_NAME",
envMap: {},
default: <default_value>,
type: "<type>",
post: (val, trace) => {}
}
}- Each
optionKeyspecifies the name of the option - Its value should be an object with the following fields:
env: the name (or array of names) of the environment varialbe(s) to check first. If it'strue, then useoptionKeyas the env variable name.envMap: an object of mapping env value to another value.default: the default value or a function to return the default value.type: indicate how to interpret and convert the string fromprocess.env.post: callback to post process value
All fields are
optional, if they are all skipped, then the config option will be determined fromuserConfigonly.Without either
defaultortype, the value fromenvwill remain as a string.If
defaultis a function, thentypemust be defined or it will bestring.If
envis an array, then the first one that finds a value inprocess.envwill be used.If
envistrue, then useoptionKeyas the name to look up fromprocess.env.
Types
When loading from env, in order to indicate what value to convert the string into, the type can be one of.
string- no conversionnumber- (integer) convert withparseInt(x,10)float- (float) convert withparseFloat(x)boolean- (boolean) convert withx === "true" || x === "yes" || x === "1" || x === "on"truthy- (boolean from truthy check) convert with!!xjson- (JSON) parsed withJSON.parse
If
typeis not specified, anddefaultexist and not a function, thentypeof defaultwill be used.
Trace
The hidden field __$trace__ contain data for each key to indicate where its value was determined from.
- If the value's from env, then it's
{src: "env", name: "ENV_OPTION_NAME"} - If the value's from user config, then it's
{src: "option"} - If the value's from default, then it's
{src: "default"}
json Type
json type is slightly different.
- If
defaultis an object like{}, then type is detected to bejson, unless spec hastypeexplicitly. - Values from all three sources are combined in the following order
env,option,default. - It uses
Object.assignto combine values unless you pass in amergefunction in options. For example, merge fromlodash. trace.srcwould be a comma separate list of them. For example,"env,option","env,option,default", or"option,default"
Option Orders
The order of source to check are:
- The
envif it's defined in the spec andprocess.envcontains the variable - The value from
userConfigdirectly if it contains theoptionKey - The default value from spec if it's declared
- Nothing