milieu

A config loader in the spirit of rc with a few additional features

Usage no npm install needed!

<script type="module">
  import milieu from 'https://cdn.skypack.dev/milieu';
</script>

README

Milieu

One could say it is one's milieu that shapes their future

npm

Install with NPM

npm install milieu

Introduction

Milieu is a config loader in the spirit of rc It shares the same features as RC, but goes a few steps further.

Milieu loads config values from argv flags, environment variables, and config files. The values are compiled into a single config object which you can use in your application. You can trace the sources of these values using Milieu's explain feature.

Milieu can parse JSON config files out of the box. You can also use INI and YAML files by installing the optional dependencies ini and/or js-yaml modules.

The word milieu is defined as the physical or social setting in which people live or in which something happens or develops.

var milieu = require('milieu');

var config = milieu('application-name', {
  server: {
    port: 8001
  },
  mongo: {
    url: 'mongodb://localhost'
  }
});

Milieu Compile Order

Milieu looks in the following places and compiles a config by merging upward through the following sources. Items highest in the list get the highest priority, and override config values in the sources below.

  1. argv flags - Ex. --test--my-key val becomes config.test.myKey === 'val' in the config. Anything after -- is ignored.
  2. environment variables - Ex. APPLICATION_NAME__TEST__MY_KEY="val" becomes config.test.myKey === 'val'
  3. config files (replace {appname} with the name of your application) (Accepts JSON, INI, or YAML) (File extensions are optional)
  4. ~/.{appname}rc
  5. ~/.{appname}/config
  6. ~/.config/{appname}
  7. ~/.config/{appname}/config
  8. /etc/{appname}rc
  9. /etc/{appname}/config
  10. /usr/local/etc/{appname}rc
  11. /usr/local/etc/{appname}/config
  12. ./.{appname}rc
  13. ../.{appname}rc
  14. ../../.{appname}rc
  15. ../../../.{appname}rc
  16. ...

Milieu Templating and Type Casting

Milieu provides both file and environment variable templating. It also provides syntax for type casting. Below are a few examples.

To load values from a file use the $(path/to/file) syntax. If the path is not absolute, it will be relative to the current working directory. You can use these tokens as many times as you need within a single value.

var config = milieu('application-name', {
  specialFile: 'part1: $(path/to/specialFile-part-1.txt)\npart2: $(path/to/specialFile-part-2.txt)'
});

To load values from environment variables use the ${VAR_NAME} syntax. You can use these tokens as many times as you need within a single value.

var config = milieu('application-name', {
  secretTokens: '1:${SECRET_TOKEN_1}2:${SECRET_TOKEN_2}3:${SECRET_TOKEN_3}'
});

Type casting can be achieved with filters. To cast a value simply add the type name and a colon to the beginning of your string. Types supported are number and boolean. JSON can also be parsed using json as the type.

var config = milieu('application-name', {
  secretNumber: 'number:${SECRET_NUMBER}'
  secretBool  : 'boolean:${SECRET_BOOL}'
  secretObj   : 'json:${SECRET_JSON}'
});

Milieu Explain

Milieu has a feature called explain. There are explain two methods; config.explain() and config.printExplainTable(). config.explain() returns an object indicating the origin of each config value. config.printExplainTable() prints a table to stdout which can be used to inspect your config from the cli. This is great for understanding how your configuration was resolved, and can be helpful for debugging production systems.

example

Lets suppose we have a config for our server at /etc/application-name/config. In it we set the value of server.port and nothing else. We also execute our application below passing the flag --debug true. Our explanation object will contain the origin of each config key as shown below.

var milieu = require('milieu');

var explanation = milieu('application-name', {
  server: {
    port: 8001
  },
  mongo: {
    url: 'mongodb://localhost'
  },
  debug: false
}).explain();

explanation === {
  server: {
    port: '/etc/application-name/config'
  },
  mongo: {
    url: 'default'
  },
  debug: 'flag'
}

If you wish to generate a table on the command line instead of working with an explanation object, call config.printExplainTable.

var milieu = require('milieu');

// prints table to stdout
milieu('application-name', {
  server: {
    port: 8001
  },
  mongo: {
    url: 'mongodb://localhost'
  },
  debug: false
}).printExplainTable();

API Docs

milieuFactory

milieuFactory(applicationName String, defaultConfig Object, opts Object) -> config Object

Internally creates an instance of Milieu instance and returns it. Accepts a applicationName and a defaultConfig. It also optionally accepts an opts object to configure Milieu. See Milieu's load order to understand how the config object is resolved. These does refer to milieuFactory as milieuFactory but It is recommended that the name milieu be used instead as most users will not interact with Milieu constructor or it's instance directly.

Milieu Options

  • opts.argv Pass a custom argv array. Defaults to process.argv.
  • opts.env Pass a custom env object. Defaults to process.env.
  • opts.platform Pass a custom platform string. Defaults to process.platform.
  • opts.unsetEnvValues If true, deletes env values that belong to the config. Defaults to false.
  • opts.parseValues If true, parses strings 'null', 'true', 'false', and 'NaN' into null, true, false, and NaN. Defaults to true.
var milieuFactory = require('milieu');

var config = milieuFactory('application-name', {
  defaultKey: 'value'
});

Milieu

new Milieu(applicationName String, defaultConfig Object, opts Object) -> Milieu

The Milieu constructor. Accepts the same arguments as milieuFactory.

var Milieu = require('milieu').Milieu;

var milieu = new Milieu('application-name', {
  defaultKey: 'value'
});

Milieu#toObject

milieu.toObject() -> config Object

Resolves the config object. Use this method to retrieve your config if using a Milieu instance directly.

var Milieu = require('milieu').Milieu;

var milieu = new Milieu('application-name', {
  defaultKey: 'value'
});

var config = milieu.toObject();

Milieu#explain

milieu.explain() -> explanation Object

Returns an explanation object.

var Milieu = require('milieu').Milieu;

var milieu = new Milieu('application-name', {
  defaultKey: 'value'
});

var explanation = milieu.explain();

Milieu#printExplainTable

milieu.explain() -> explanation Object

Prints an explanation table to stdout.

var Milieu = require('milieu').Milieu;

var milieu = new Milieu('application-name', {
  defaultKey: 'value'
});

// prints to stdout
milieu.printExplainTable();