Comparing version 0.1.1 to 0.2.0
87
etc.js
@@ -1,9 +0,11 @@ | ||
var util = require('util'); | ||
var ProtoListDeep = require('proto-list-deep'); | ||
var optimist = require('optimist'); | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
var existsSync = fs.existsSync ? fs.existsSync : path.existsSync; | ||
var glob = require('glob'); | ||
var findPackage = require('witwip'); | ||
var util = require('util') | ||
, optimist = require('optimist') | ||
, fs = require('fs') | ||
, path = require('path') | ||
, existsSync = fs.existsSync ? fs.existsSync : path.existsSync | ||
, glob = require('glob') | ||
, findPackage = require('witwip') | ||
, eventflow = require('eventflow') | ||
, merge = require('tea-merge') | ||
, clone = require('clone'); | ||
@@ -21,5 +23,5 @@ module.exports = function(delim) { | ||
this.mode = 'push'; | ||
ProtoListDeep.call(this, this.delim); | ||
this.conf = {}; | ||
eventflow(this); | ||
} | ||
util.inherits(Etc, ProtoListDeep); | ||
@@ -31,29 +33,33 @@ Etc.prototype.reverse = function() { | ||
Etc.prototype.push = function (obj) { | ||
this.conf = merge({}, clone(obj), this.conf); | ||
return this; | ||
}; | ||
Etc.prototype.unshift = function (obj) { | ||
merge(this.conf, clone(obj)); | ||
return this; | ||
}; | ||
Etc.prototype.get = function(key) { | ||
var conf = this.deepSnapshot; | ||
if (typeof key === 'undefined') return conf; | ||
return key.split(this.delim).reduce(function(prev, part) { | ||
if (typeof key === 'undefined') return clone(this.conf); | ||
return clone(key.split(this.delim).reduce(function(prev, part) { | ||
return prev !== undefined && typeof prev[part] !== 'undefined' ? prev[part] : undefined; | ||
}, conf); | ||
}, this.conf)); | ||
}; | ||
Etc.prototype.set = function(key, value) { | ||
var full = {}; | ||
var level = full; | ||
var parts = key.split(this.delim); | ||
var last = parts.pop(); | ||
return this.unshift(this.unflattenKey({}, key, value)); | ||
}; | ||
parts.forEach(function(part) { | ||
if (!level[part]) level[part] = {}; | ||
level = level[part]; | ||
}); | ||
level[last] = value; | ||
this.unshift(full); | ||
return this; | ||
Etc.prototype.unflattenKey = function (dest, key, value) { | ||
key.split(this.delim).reduce(function (obj, part, i, arr) { | ||
obj[part] = (i === (arr.length - 1)) ? value : (obj[part] || {}); | ||
return obj[part]; | ||
}, dest); | ||
return dest; | ||
}; | ||
Etc.prototype.toJSON = function(callback) { | ||
return this.deepSnapshot; | ||
return clone(this.conf); | ||
}; | ||
@@ -69,10 +75,12 @@ | ||
Etc.prototype.all = function() { | ||
this.argv().env().etc().pkg(); | ||
return this; | ||
return this.argv().env().etc().pkg(); | ||
}; | ||
Etc.prototype.argv = function() { | ||
var self = this; | ||
var self = this, args = {}; | ||
if (optimist.argv) { | ||
this[this.mode](optimist.argv); | ||
Object.keys(optimist.argv).forEach(function (key) { | ||
self.unflattenKey(args, key, optimist.argv[key]); | ||
}); | ||
this[this.mode](args); | ||
} | ||
@@ -92,3 +100,3 @@ return this; | ||
if (key.indexOf(prefix) === 0) { | ||
env[key.substr(len)] = process.env[key]; | ||
self.unflattenKey(env, key.substr(len), process.env[key]); | ||
} | ||
@@ -103,4 +111,3 @@ }); | ||
Etc.prototype.add = function(obj) { | ||
this[this.mode](obj); | ||
return this; | ||
return this[this.mode](obj); | ||
}; | ||
@@ -193,1 +200,11 @@ | ||
}; | ||
Etc.prototype.load = function (cb) { | ||
this.series('load', cb); | ||
return this; | ||
}; | ||
Etc.prototype.save = function (cb) { | ||
this.series('save', cb); | ||
return this; | ||
}; |
{ | ||
"name": "etc", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Configuration loader for node.js applications", | ||
@@ -14,9 +14,12 @@ "main": "etc.js", | ||
"dependencies": { | ||
"proto-list-deep": "*", | ||
"optimist": "~0.3.4", | ||
"glob": "~3.1.12", | ||
"witwip": "~0.0.2" | ||
"witwip": "~0.0.2", | ||
"eventflow": "~0.0.11", | ||
"tea-merge": "~0.1.0", | ||
"clone": "~0.1.6" | ||
}, | ||
"devDependencies": { | ||
"mocha": "*" | ||
"mocha": "*", | ||
"bench": "*" | ||
}, | ||
@@ -23,0 +26,0 @@ "keywords": [ |
@@ -19,2 +19,58 @@ node-etc | ||
Etc 0.2.x Changes | ||
----------------- | ||
**Attention Etc 0.1.x Users** - Etc 0.1.x used `proto-list-deep` as its primary | ||
internal configuration store. This was *probably* fast for writes, but as it | ||
turns out the deep-merging going on in `proto-list-deep` (for `conf.get()`) is | ||
pretty slow. I hit a personal use-case where I need reasonably fast `conf.get()` | ||
calls. I tried a few different iterations and came up with 0.2.x, which uses | ||
an object literal to store the conf and uses a combination of `clone` and | ||
`tea-merge` to handle sets and gets. | ||
The API has not changed, however, depending on your specific configuration | ||
**the values of your conf may have changed**. `tea-merge` is much more | ||
intelligent about merging than `proto-list-deep` was, specifically when | ||
dealing with arrays. If you upgrade, please check that your conf is | ||
still merging how you think it should. Thanks! | ||
Here is an idea of the speed-up from 0.1.x: | ||
``` | ||
$ node bench/bench.js | ||
benchmarking /Users/cpsubrian/projects/node/brian/etc/bench/bench.js | ||
Please be patient. | ||
{ http_parser: '1.0', | ||
node: '0.8.19', | ||
v8: '3.11.10.25', | ||
ares: '1.7.5-DEV', | ||
uv: '0.8', | ||
zlib: '1.2.3', | ||
openssl: '1.0.0f' } | ||
Scores: (bigger is better) | ||
merge | ||
Raw: | ||
> 2187.812187812188 | ||
> 2200.7992007992007 | ||
> 2195.804195804196 | ||
> 2194.805194805195 | ||
Average (mean) 2194.805194805195 | ||
proto | ||
Raw: | ||
> 14.381591562799617 | ||
> 14.619883040935672 | ||
> 14.45086705202312 | ||
> 14.409221902017292 | ||
Average (mean) 14.465390889443926 | ||
Winner: merge | ||
Compared with next highest (proto), it's: | ||
99.34% faster | ||
151.73 times as fast | ||
2.18 order(s) of magnitude faster | ||
A LOT FASTER | ||
``` | ||
Examples | ||
@@ -21,0 +77,0 @@ -------- |
@@ -1,2 +0,2 @@ | ||
var etc = require('../'), | ||
var etc = require('../etc'), | ||
assert = require('assert'); | ||
@@ -48,2 +48,14 @@ | ||
it('can read conf from environment', function () { | ||
process.env['test_lang'] = 'en'; | ||
process.env['test_user:name'] = 'Brian'; | ||
process.env['test_user:handle'] = 'cpsubrian'; | ||
conf.env('test'); | ||
assert.deepEqual(conf.get('lang'), 'en'); | ||
assert.deepEqual(conf.get('user'), {name: 'Brian', handle: 'cpsubrian'}); | ||
delete process.env['test_lang']; | ||
delete process.env['test_user:name']; | ||
delete process.env['test_user:handle']; | ||
}); | ||
it('can add conf using the `all` alias', function() { | ||
@@ -50,0 +62,0 @@ conf.all(); |
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 3 instances in 1 package
Wildcard dependency
QualityPackage has a dependency with a floating version range. This can cause issues if the dependency publishes a new major version.
Found 1 instance in 1 package
17687
284
1
307
6
2
11
+ Addedclone@~0.1.6
+ Addedeventflow@~0.0.11
+ Addedtea-merge@~0.1.0
+ Addedasync@0.1.22(transitive)
+ Addedclone@0.1.19(transitive)
+ Addedeventflow@0.0.12(transitive)
+ Addedtea-merge@0.1.0(transitive)
+ Addedtea-type@0.1.0(transitive)
- Removedproto-list-deep@*
- Removedproto-list@1.2.4(transitive)
- Removedproto-list-deep@0.0.1(transitive)