From afb16188b33794b19a6c0b9da0d229aa63a4bad4 Mon Sep 17 00:00:00 2001 From: Kyle Campbell Date: Sat, 22 Oct 2016 14:55:57 -0700 Subject: [PATCH] implement node-config (#27) --- README.md | 35 ++++++++++++------- example/app.js | 5 ++- .../config/custom-environment-variables.json | 4 +++ package.json | 4 +-- src/index.js | 33 +++++++---------- test/config/custom-environment-variables.json | 4 +++ test/index.test.js | 2 +- 7 files changed, 51 insertions(+), 36 deletions(-) create mode 100644 example/config/custom-environment-variables.json create mode 100644 test/config/custom-environment-variables.json diff --git a/README.md b/README.md index 0273863..bb99567 100644 --- a/README.md +++ b/README.md @@ -6,15 +6,13 @@ ## About -`feathers-configuration` allows you to load default and environment specific JSON configuration files and environment variables and set them on your application. Here is what it does: +This release of `feathers-configuration` simply acts as a wrapped around [node-config](https://github.com/lorenwest/node-config). -- Given a root and configuration path load a `default.json` in that path -- When the `NODE_ENV` is not `development`, also try to load `.json` in that path and merge both configurations -- Go through each configuration value and sets it on the application (via `app.set(name, value)`). - - If the value is a valid environment variable (e.v. `NODE_ENV`), use its value instead - - If the value start with `./` or `../` turn it it an absolute path relative to the configuration file path -- Both `default` and `` configurations can be modules which provide their computed settings with `module.exports = {...}` and a `.js` file suffix. See `test/config/testing.js` for an example. -All rules listed above apply for `.js` modules. +By default this implementation will look in `config/*` for `default.json`. + +As per the [config docs](https://github.com/lorenwest/node-config/wiki/Configuration-Files) this is highly configurable. + +Future releases will also include adapters for external configuration storage. ## Usage @@ -25,7 +23,7 @@ import feathers from 'feathers'; import configuration from 'feathers-configuration'; // Use the current folder as the root and look configuration up in `settings` -let app = feathers().configure(configuration(__dirname, 'settings')) +let app = feathers().configure() ``` ## Example @@ -55,18 +53,22 @@ In `config/production.js` we are going to use environment variables (e.g. set by Now it can be used in our `app.js` like this: -``` +```js import feathers from 'feathers'; import configuration from 'feathers-configuration'; +let conf = configuration(); + let app = feathers() - .configure(configuration(__dirname)); + .configure(conf); console.log(app.get('frontend')); console.log(app.get('host')); console.log(app.get('port')); console.log(app.get('mongodb')); console.log(app.get('templates')); +console.log(conf()); + ``` If you now run @@ -80,7 +82,14 @@ node app // -> path/to/templates ``` -Or with a different environment and variables: +Or via custom environment variables by setting them in `config/custom-environment-variables.json`: + +```js +{ + "port": "PORT", + "mongodb": "MONGOHQ_URL" +} +``` ``` PORT=8080 MONGOHQ_URL=mongodb://localhost:27017/production NODE_ENV=production node app @@ -91,6 +100,8 @@ PORT=8080 MONGOHQ_URL=mongodb://localhost:27017/production NODE_ENV=production n // -> path/to/templates ``` +You can also override these variables with arguments. Read more about how with [node-config](https://github.com/lorenwest/node-config) + ## License Copyright (c) 2015 diff --git a/example/app.js b/example/app.js index f1fe609..f3b7324 100644 --- a/example/app.js +++ b/example/app.js @@ -1,11 +1,14 @@ import feathers from 'feathers'; import configuration from '../src'; +let conf = configuration(); + let app = feathers() - .configure(configuration(__dirname)); + .configure(conf); console.log(app.get('frontend')); console.log(app.get('host')); console.log(app.get('port')); console.log(app.get('mongodb')); console.log(app.get('templates')); +console.log(conf()); diff --git a/example/config/custom-environment-variables.json b/example/config/custom-environment-variables.json new file mode 100644 index 0000000..80c1764 --- /dev/null +++ b/example/config/custom-environment-variables.json @@ -0,0 +1,4 @@ +{ + "port": "PORT", + "mongodb": "MONGOHQ_URL" +} diff --git a/package.json b/package.json index e64f4f5..16f10d5 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "compile": "rm -rf lib/ && babel -d lib/ src/", "watch": "babel --watch -d lib/ src/", "jshint": "jshint src/. test/. --config", - "mocha": "NODE_ENV=testing mocha test/ --compilers js:babel-core/register", + "mocha": "NODE_CONFIG_DIR=./test/config/ NODE_ENV=testing mocha test/ --compilers js:babel-core/register", "test": "npm run jshint && npm run mocha && nsp check" }, "directories": { @@ -43,7 +43,7 @@ }, "dependencies": { "debug": "^2.2.0", - "deep-assign": "^2.0.0" + "config": "^1.21.0" }, "devDependencies": { "babel-cli": "^6.1.4", diff --git a/src/index.js b/src/index.js index 0ddb5c1..540d42e 100644 --- a/src/index.js +++ b/src/index.js @@ -1,15 +1,15 @@ -import fs from 'fs'; -import path from 'path'; import makeDebug from 'debug'; -import deepAssign from 'deep-assign'; +import path from 'path'; const debug = makeDebug('feathers:configuration'); +const config = require('config'); const separator = path.sep; -export default module.exports = function (root, configFolder = 'config', deep = true) { +export default module.exports = function () { return function() { - const app = this; - const env = app.settings.env; + + let app = this; + const convert = current => { const result = Array.isArray(current) ? [] : {}; @@ -29,7 +29,7 @@ export default module.exports = function (root, configFolder = 'config', deep = } else if(value.indexOf('.') === 0 || value.indexOf('..') === 0) { // Make relative paths absolute value = path.resolve( - path.join(root, configFolder), + path.join(config.util.getEnv('NODE_CONFIG_DIR')), value.replace(/\//g, separator) ); } @@ -42,24 +42,17 @@ export default module.exports = function (root, configFolder = 'config', deep = return result; }; - let config = convert(require(path.join(root, configFolder, 'default'))); - + const env = config.util.getEnv('NODE_ENV'); debug(`Initializing configuration for ${env} environment`); + const conf = convert(config); - const envConfig = path.join(root, configFolder, env); - // We can use sync here since configuration only happens once at startup - if(fs.existsSync(`${envConfig}.js`) || fs.existsSync(`${envConfig}.json`)) { - config = deep ? deepAssign(config, convert(require(envConfig))) : - Object.assign(config, convert(require(envConfig))); - } else { - debug(`Configuration file for ${env} environment not found at ${envConfig}`); + if(!app) { + return conf; } - Object.keys(config).forEach(name => { - let value = config[name]; - + Object.keys(conf).forEach(name => { + let value = conf[name]; debug(`Setting ${name} configuration value to`, value); - app.set(name, value); }); }; diff --git a/test/config/custom-environment-variables.json b/test/config/custom-environment-variables.json new file mode 100644 index 0000000..80c1764 --- /dev/null +++ b/test/config/custom-environment-variables.json @@ -0,0 +1,4 @@ +{ + "port": "PORT", + "mongodb": "MONGOHQ_URL" +} diff --git a/test/index.test.js b/test/index.test.js index 27c5524..a98df40 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -4,7 +4,7 @@ import { join } from 'path'; import plugin from '../src'; describe('feathers-configuration', () => { - const app = feathers().configure(plugin(__dirname)); + const app = feathers().configure(plugin()); it('initialized app with default data', () => assert.equal(app.get('port'), 3030)