Comparing version 0.0.12 to 0.1.0
@@ -51,4 +51,2 @@ var fs = require('fs'); | ||
grunt.loadTasks("tasks"); | ||
// These plugins provide necessary tasks. | ||
@@ -60,3 +58,3 @@ grunt.loadNpmTasks('grunt-contrib-nodeunit'); | ||
// Default task. | ||
grunt.registerTask('default', ['jshint', 'nodeunit']); | ||
grunt.registerTask('default', ['jshint', 'nodeunit', 'watch']); | ||
}; |
@@ -6,17 +6,20 @@ var _ = require('lodash'); | ||
var globalOptions = { | ||
delimiter: ':' | ||
delimiter: ':', | ||
collections: { | ||
auto: true | ||
} | ||
}; | ||
this.getOptions = function(options) { | ||
return _.clone(globalOptions); | ||
}; | ||
this.options = this.setOptions = function(options) { | ||
if (options) { | ||
_.extend(globalOptions, options); | ||
this.setOptions = function(options) { | ||
_.extend(globalOptions, options); | ||
return this; | ||
return this; | ||
} else { | ||
return globalOptions; | ||
} | ||
}; | ||
this.grow = function(flatData, config) { | ||
var localOptions = _.extend(this.getOptions(), config || {}); | ||
var localOptions = _.extend(this.options(), config || {}); | ||
var translated = []; | ||
@@ -76,3 +79,17 @@ | ||
if (target.node) { // should skip root | ||
var isCollection = target.node === inflection.pluralize(target.node); | ||
var isCollection; | ||
// if collection auto detection is on, default to pluralization | ||
isCollection = globalOptions.collections.auto && target.node === inflection.pluralize(target.node); | ||
// manual overrides work both with and without collection auto detection | ||
// [nodename]- indicates non collection | ||
// [nodename]+ indicates collection | ||
if (target.node.match(/[\+\-]$/)) { | ||
isCollection = target.node.match(/\+$/) || isCollection; | ||
isCollection = isCollection && !target.node.match(/\-$/); | ||
target.node = target.node.replace(/[\+\-]$/, ''); | ||
} | ||
var node = trail[target.node] = (trail[target.node] || (isCollection ? [blueprint] : blueprint)); | ||
@@ -79,0 +96,0 @@ |
{ | ||
"name": "treeize", | ||
"version": "0.0.12", | ||
"version": "0.1.0", | ||
"description": "Converts tabular row data (as from SQL joins, flat JSON, etc) to deep object graphs based on simple column naming conventions - without the use of an ORM or models.", | ||
@@ -5,0 +5,0 @@ "main": "./lib/treeize.js", |
@@ -34,6 +34,22 @@ treeize | ||
- `treeize.grow(flatData, options)` - takes your results/rows of flat associative data and returns a full object graph. | ||
- `treeize.getOptions()` - returns global options for the lib. | ||
- `treeize.setOptions(options)` - sets global options for the lib. For example, to use a path delimiter of '>' instead of ':', call `treeize.setOptions({ delimiter: '>' })` | ||
- `treeize.grow(flatData, [options])` - takes your results/rows of flat associative data and returns a full object graph. | ||
#### Configuration (first value is default) | ||
```js | ||
treeize.options([options]); // universal getter/setter for options. Returns self. | ||
// default options are as follows: | ||
{ | ||
delimiter: ':', // Path delimiter, as in "foo:bar:baz" | ||
collections: { | ||
auto: true // Defaults to pluralized detection for collections. | ||
// Setting to false requires + operators for | ||
// every collection. | ||
} | ||
} | ||
``` | ||
### Usage | ||
@@ -62,2 +78,55 @@ | ||
##### How to manually override the default pluralization scheme for collection-detection | ||
In the rare (but possible) case that plural/singular node names are not enough to properly | ||
detect collections, you may add specific overrides to the node name, using the `+` and `-` | ||
indicators. | ||
```js | ||
{ | ||
"name": "Bird", | ||
"attributes:legs": 2, | ||
"attributes:hasWings": true | ||
} | ||
// would naturally return | ||
[ | ||
{ | ||
name: "Bird", | ||
attributes: [ | ||
{ | ||
legs: 2, | ||
hasWings: true | ||
} | ||
] | ||
} | ||
] | ||
// to tell treeize that the node (detected as a plural collection) | ||
// is NOT a collection, add a - to the path | ||
{ | ||
"name": "Bird", | ||
"attributes-:legs": 2, | ||
"attributes-:hasWings": true | ||
} | ||
// results in | ||
[ | ||
{ | ||
name: "Bird", | ||
attributes: { | ||
legs: 2, | ||
hasWings: true | ||
} | ||
} | ||
] | ||
// conversely, add a + to a path to force it into a collection | ||
``` | ||
##### Pathing example | ||
@@ -64,0 +133,0 @@ |
@@ -57,12 +57,104 @@ var treeize = require('../lib/treeize'); | ||
var flatDataNonPlural = [ | ||
{ | ||
"name": "Mittens", | ||
"age": 12, | ||
"toy+:name": "mouse", | ||
"toy+:owners:name": "Mittens" | ||
}, | ||
{ | ||
"name": "Mittens", | ||
"age": 12, | ||
"toy+:name": "yarn", | ||
"toy+:owners:name": "Ms. Threadz" | ||
}, | ||
{ | ||
"name": "Tiger", | ||
"age": 7, | ||
"toy+:name": "a stick", | ||
"toy+:owners:name": "Mother Nature" | ||
} | ||
]; | ||
var treeDataManual = [ | ||
{ | ||
"name": "Mittens", | ||
"age": 12, | ||
"toy": [ | ||
{ | ||
"name": "mouse", | ||
"owners": { | ||
"name": "Mittens" | ||
} | ||
}, | ||
{ | ||
"name": "yarn", | ||
"owners": { | ||
"name": "Ms. Threadz" | ||
} | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Tiger", | ||
"age": 7, | ||
"toy": [ | ||
{ | ||
"name": "a stick", | ||
"owners": { | ||
"name": "Mother Nature" | ||
} | ||
} | ||
] | ||
} | ||
]; | ||
var treeDataMixed = [ | ||
{ | ||
"name": "Mittens", | ||
"age": 12, | ||
"toy": [ | ||
{ | ||
"name": "mouse", | ||
"owners": [{ | ||
"name": "Mittens" | ||
}] | ||
}, | ||
{ | ||
"name": "yarn", | ||
"owners": [{ | ||
"name": "Ms. Threadz" | ||
}] | ||
} | ||
] | ||
}, | ||
{ | ||
"name": "Tiger", | ||
"age": 7, | ||
"toy": [ | ||
{ | ||
"name": "a stick", | ||
"owners": [{ | ||
"name": "Mother Nature" | ||
}] | ||
} | ||
] | ||
} | ||
]; | ||
module.exports = { | ||
'.defaultOptions() returns expected defaults': function (test) { | ||
'default .options() returns expected defaults': function (test) { | ||
test.expect(1); | ||
test.deepEqual(treeize.getOptions(), { delimiter: ':' }); | ||
test.deepEqual(treeize.options(), { | ||
delimiter: ':', | ||
collections: { | ||
auto: true | ||
} | ||
}); | ||
test.done(); | ||
}, | ||
'.setOptions() correctly sets options': function (test) { | ||
'.options() correctly sets options': function (test) { | ||
treeize.setOptions({ delimiter: '+' }); | ||
test.expect(1); | ||
test.equal(treeize.getOptions().delimiter, '+'); | ||
test.equal(treeize.options().delimiter, '+'); | ||
test.done(); | ||
@@ -72,8 +164,8 @@ }, | ||
test.expect(1); | ||
test.equal(treeize.getOptions().delimiter, '+'); | ||
test.equal(treeize.options().delimiter, '+'); | ||
test.done(); | ||
}, | ||
'.setOptions() returns self': function (test) { | ||
'.options() returns self': function (test) { | ||
test.expect(1); | ||
test.ok(treeize.setOptions({ delimiter: ':' }).grow); | ||
test.ok(treeize.options({ delimiter: ':' }).grow); | ||
test.done(); | ||
@@ -85,3 +177,14 @@ }, | ||
test.done(); | ||
}, | ||
'.grow expands auto+manual declarations correctly': function (test) { | ||
test.expect(1); | ||
test.deepEqual(treeize.grow(flatDataNonPlural), treeDataMixed); | ||
test.done(); | ||
}, | ||
'.grow expands manual collection declarations correctly': function (test) { | ||
test.expect(1); | ||
treeize.options({ collections: { auto: false }}); | ||
test.deepEqual(treeize.grow(flatDataNonPlural), treeDataManual); | ||
test.done(); | ||
} | ||
}; |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
21547
322
371