[![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard)
[![npm version](https://badge.fury.io/js/vigour-config.svg)](https://badge.fury.io/js/vigour-config)

# vigour-config

`vigour-config` allows you to easily make highly configurable services that are easy to test and launch in a variety of ways. Let's make an example service to understand how it works:

## Requirements: Design your service as a class receiving a config object in the constructor

**lib/index.js**
```javascript
'use strict'
var Config = require('vigour-config')
module.exports = exports = Service

function Service (config) {
  var myIP = ip.address()
  // If the object received is not a `vigour-config` observable
  if (!(config instanceof Config)) {
    // Make the config object a `vigour-config` observable
    config = new Config(config)
  }
  this.config = config // an observable
  console.log('someProperty', this.config.someProperty.val) // Get property values with `.val`
  var plainConfig = this.config.plain() // Turn observable into a regular object with `.plain()`
  console.log('someProperty', plainConfig.someProperty) // Now you don't need the `.val`
}
Service.prototype.start = function () { /* ... */ }
```

see [observable](https://github.com/vigour-io/observable#readme)

## Making a binary executable for your service
**bin/executable.js**
```javascript
#!/usr/bin/env node
'use strict'

var Service = require('../')
var service = new Service()
service.start()
```

## Provide default configuration values, command-line argument descriptions and environment variable names
You can configure the configurations options for your service in its package.json
**package.json**
```json
{
  "vigour": {
    "someProperty": {
      "val": "default value",
      "description": "Printing during the Service instance creation",
      "_env": "MY_SERVICE_SOME_PROPERTY"
    },
    "deeper": {
      "property": {
        "val": "default",
        "description": "Currently not used",
        "_env": "MY_SERVICE_DEEP_PROPERTY"
      }
    }
  }
}
```

## Configure and launch your service

### Using the binary executable

#### Using only default values
```sh
./bin/executable.js
```

#### Environment variables

```sh
export MY_SERVICE_SOME_PROPERTY='Configured via env var'
export MY_SERVICE_DEEP_PROPERTY='ENV'
./bin/executable.js
```

#### Command line arguments
```sh
./bin/executable.js --someProperty 'Configured via CLI arg' --deeper.property 'CLI ARG'
```

##### JSON
```sh
./bin/executable.js --deeper '{"property":"CLI ARG"}'
```

#### Config file(s)
```sh
./bin/executable.js --mergeFiles config.json
```

**config.json**
```json
{
  "someProperty": "Configured via a config file"
}
```

#### Multiple config files
```sh
./bin/executable.js --mergeFiles '["config.json","moreConfig.js"]'
```

### Requiring your module

#### Using only default values
```javascript
var Service = require('./lib/')
var service = new Service()
service.start()
```

#### Passing in configuration
```javascript
var Service = require('./lib/')
var config = {
  someProperty: 'via params',
  deeper: {
    property: 'via params!'
  }
}
var service = new Service(config)
service.start()
```
