confidence
Advanced tools
+44
-3
@@ -31,2 +31,9 @@ // Load modules | ||
| var node = this._get(key, criteria); | ||
| return internals.walk(node, criteria); | ||
| }; | ||
| internals.Store.prototype._get = function (key, criteria) { | ||
| var self = this; | ||
@@ -59,6 +66,15 @@ | ||
| return internals.walk(node, criteria); | ||
| return node; | ||
| }; | ||
| // Get a meta for node | ||
| internals.Store.prototype.meta = function (key, criteria) { | ||
| var node = this._get(key, criteria); | ||
| return (typeof node === 'object' ? node.$meta : undefined); | ||
| }; | ||
| // Return node or value if no filter, otherwise apply filters until node or value | ||
@@ -69,4 +85,4 @@ | ||
| if (!node || | ||
| typeof node !== 'object' || // Value | ||
| !node.$filter) { // Fork | ||
| typeof node !== 'object' || | ||
| (!node.$filter && !node.$value)) { | ||
@@ -76,2 +92,6 @@ return node; | ||
| if (node.$value) { | ||
| return internals.filter(node.$value, criteria); | ||
| } | ||
| // Filter | ||
@@ -119,2 +139,6 @@ | ||
| if (node.hasOwnProperty('$value')) { | ||
| return internals.walk(node.$value, criteria); | ||
| } | ||
| var parent = (node instanceof Array ? [] : {}); | ||
@@ -125,2 +149,5 @@ | ||
| var key = keys[i]; | ||
| if (key === '$meta') { | ||
| continue; | ||
| } | ||
| var child = internals.filter(node[key], criteria); | ||
@@ -237,2 +264,12 @@ var value = internals.walk(child, criteria); | ||
| } | ||
| else if (key === '$meta') { | ||
| found.meta = true; | ||
| } | ||
| else if (key === '$value') { | ||
| found.value = true; | ||
| var err = internals.Store.validate(node.$value, path + '/$value'); | ||
| if (err) { | ||
| return err; | ||
| } | ||
| } | ||
| else { | ||
@@ -274,2 +311,6 @@ return error('Unknown $ directive ' + key); | ||
| if (found.value && (found.key || found.range || found.default || found.filter)) { | ||
| return error('Value directive can only be used with meta or nothing'); | ||
| } | ||
| // Valid node | ||
@@ -276,0 +317,0 @@ |
+1
-1
| { | ||
| "name": "confidence", | ||
| "description": "Configuration API", | ||
| "version": "0.7.2", | ||
| "version": "0.8.0", | ||
| "author": "Eran Hammer <eran@hueniverse.com> (http://hueniverse.com)", | ||
@@ -6,0 +6,0 @@ "repository": "git://github.com/spumko/confidence", |
+74
-3
@@ -15,2 +15,3 @@ <a href="https://github.com/spumko"><img src="https://raw.github.com/spumko/spumko/master/images/from.png" align="right" /></a> | ||
| - [Ranges](#ranges) | ||
| - [Metadata](#metadata) | ||
| - [API](#api) | ||
@@ -26,3 +27,5 @@ | ||
| "production": { | ||
| "deeper": "value" | ||
| "deeper": { | ||
| "$value": "value" | ||
| } | ||
| }, | ||
@@ -50,2 +53,5 @@ "$default": { | ||
| "$default": 6 | ||
| }, | ||
| "$meta": { | ||
| "description": "example file" | ||
| } | ||
@@ -172,3 +178,2 @@ } | ||
| ```json | ||
@@ -197,2 +202,56 @@ { | ||
| ### Metadata | ||
| The configuration file can be annotated with metadata that is ignore (and removed) by the parser. Metadata is useful for human readabe information as well as to | ||
| enable other tools such as configuraiton editors and validators, going beyong the basic parsing specified here. | ||
| ```json | ||
| { | ||
| "key1": "abc", | ||
| "key2": { | ||
| "$filter": "system.env", | ||
| "production": 1, | ||
| "$default": 2 | ||
| }, | ||
| "key3": { | ||
| "$filter": "random.a", | ||
| "$range": [ | ||
| { "limit": 10, "value": 4 }, | ||
| { "limit": 20, "value": 5 } | ||
| ], | ||
| "$default": 6 | ||
| }, | ||
| "$meta": { | ||
| "anything": "really" | ||
| } | ||
| } | ||
| ``` | ||
| To annotate non object values, any value can be wrapped in an object and provided using the `$value` directive. | ||
| ```json | ||
| { | ||
| "key1": { | ||
| "$value": "abc", | ||
| "$meta": "whatever" | ||
| }, | ||
| "key2": { | ||
| "$filter": "system.env", | ||
| "production": 1, | ||
| "$default": 2 | ||
| }, | ||
| "key3": { | ||
| "$filter": "random.a", | ||
| "$range": [ | ||
| { "limit": 10, "value": 4 }, | ||
| { "limit": 20, "value": 5 } | ||
| ], | ||
| "$default": 6 | ||
| }, | ||
| "$meta": { | ||
| "anything": "really" | ||
| } | ||
| } | ||
| ``` | ||
| # API | ||
@@ -246,3 +305,3 @@ | ||
| Returns the value found after applying the criteria. If the key is invalid or not found, returns null. | ||
| Returns the value found after applying the criteria. If the key is invalid or not found, returns undefined. | ||
@@ -253,1 +312,13 @@ ```javascript | ||
| ### store.meta(key, [criteria]) | ||
| Retrieves the metadata (if any) from the configuration document after applying the provided criteria where: | ||
| - `key` - the requested key path. All keys must begin with '/'. '/' returns the the entire document. | ||
| - `criteria` - optional object used as criteria for applying filters in the configuration document. Defaults to `{}`. | ||
| Returns the metadata found after applying the criteria. If the key is invalid or not found, or if no metadata is available, returns undefined. | ||
| ```javascript | ||
| var value = store.meta('/c', { size: 'big' }); | ||
| ``` |
+54
-2
@@ -33,3 +33,6 @@ // Load modules | ||
| // Fork | ||
| deeper: 'value' // Value | ||
| deeper: { | ||
| // Value | ||
| $value: 'value' // Value | ||
| } | ||
| }, | ||
@@ -45,3 +48,6 @@ $default: { | ||
| // Fork | ||
| sub1: 0, | ||
| sub1: { | ||
| $value: 0, | ||
| $meta: 'something' | ||
| }, | ||
| sub2: { | ||
@@ -63,2 +69,5 @@ // Filter | ||
| $default: 6 | ||
| }, | ||
| $meta: { | ||
| something: 'else' | ||
| } | ||
@@ -105,2 +114,29 @@ }; | ||
| describe('#meta', function () { | ||
| it('returns root meta', function (done) { | ||
| var store = new Confidence.Store(); | ||
| store.load(tree); | ||
| expect(store.meta('/')).to.deep.equal(tree.$meta); | ||
| done(); | ||
| }); | ||
| it('returns nested meta', function (done) { | ||
| var store = new Confidence.Store(); | ||
| store.load(tree); | ||
| expect(store.meta('/key3/sub1')).to.equal('something'); | ||
| done(); | ||
| }); | ||
| it('returns undefined for missing meta', function (done) { | ||
| var store = new Confidence.Store(); | ||
| store.load(tree); | ||
| expect(store.meta('/key1')).to.equal(undefined); | ||
| done(); | ||
| }); | ||
| }); | ||
| describe('#load', function () { | ||
@@ -178,2 +214,18 @@ | ||
| it('fails on invalid value node', function (done) { | ||
| var err = Confidence.Store.validate({ key: { $value: { $b: 5 } } }); | ||
| expect(err.message).to.equal('Unknown $ directive $b'); | ||
| expect(err.path).to.equal('/key/$value'); | ||
| done(); | ||
| }); | ||
| it('fails on mix of value and filter', function (done) { | ||
| var err = Confidence.Store.validate({ key: { $value: 1, $filter: 'a', a: 1 } }); | ||
| expect(err.message).to.equal('Value directive can only be used with meta or nothing'); | ||
| expect(err.path).to.equal('/key'); | ||
| done(); | ||
| }); | ||
| it('fails on default value without a filter', function (done) { | ||
@@ -180,0 +232,0 @@ |
73593
6.93%641
12.65%318
28.74%