dot-object 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of dot-object might be problematic. Click here for more details.

package/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Rob Halff
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,219 @@
1
+ [![Build Status](https://travis-ci.org/rhalff/dot-object.png)](https://travis-ci.org/rhalff/dot-object)
2
+
3
+ Dot-Object
4
+ ========
5
+
6
+ Dot-Object makes it possible to transform javascript objects using dot notation.
7
+
8
+
9
+ #### Move a property within one object to another location
10
+ ```javascript
11
+ var DJ = require('dot-object');
12
+
13
+ var dj = new DJ();
14
+
15
+ var obj = {
16
+ 'first_name': 'John',
17
+ 'last_name': 'Doe'
18
+ };
19
+
20
+ dj.move('first_name', 'contact.firstname', obj);
21
+ dj.move('last_name', 'contact.lastname', obj);
22
+
23
+ console.log(obj);
24
+
25
+ {
26
+ contact: {
27
+ firstname: 'John',
28
+ lastname: 'Doe'
29
+ }
30
+ }
31
+
32
+ ```
33
+
34
+ #### Transform an object
35
+
36
+ ```javascript
37
+ var DJ = require('dot-object');
38
+
39
+ var dj = new DJ();
40
+
41
+ var row = {
42
+ 'id': 2,
43
+ 'contact.name.first': 'John',
44
+ 'contact.name.last': 'Doe',
45
+ 'contact.email': 'example@gmail.com',
46
+ 'contact.info.about.me': 'classified'
47
+ };
48
+
49
+ dj.object(row);
50
+
51
+ console.log(row);
52
+
53
+ {
54
+ "id": 2,
55
+ "contact": {
56
+ "name": {
57
+ "first": "John",
58
+ "last": "Doe"
59
+ },
60
+ "email": "example@gmail.com",
61
+ "info": {
62
+ "about": {
63
+ "me": "classified"
64
+ }
65
+ }
66
+ }
67
+ }
68
+ ```
69
+
70
+ To convert manually per string use:
71
+ ```javascript
72
+ var DJ = require('dot-object');
73
+
74
+ var dj = new DJ();
75
+
76
+ var obj = { val: 'test' };
77
+ dj.str('this.is.my.string', 'value', obj);
78
+
79
+ console.log(obj);
80
+
81
+ {
82
+ "val": "test",
83
+ "this": {
84
+ "is": {
85
+ "my": {
86
+ "string": "value"
87
+ }
88
+ }
89
+ }
90
+ }
91
+ ```
92
+
93
+ #### Pick a value using dot notation:
94
+ ```
95
+ var obj = {
96
+ some: {
97
+ nested: {
98
+ value: 'Hi there!'
99
+ }
100
+ }
101
+ };
102
+
103
+ var val = dj.pick('some.nested.key', obj);
104
+ console.log(val);
105
+
106
+ Hi there!
107
+ ```
108
+
109
+ ### Using modifiers
110
+
111
+ You can use modifiers to translate values on the fly.
112
+
113
+ This example uses the [underscore.string](https://github.com/epeli/underscore.string) library.
114
+
115
+
116
+
117
+ ```javascript
118
+ var DJ = require('dot-object');
119
+
120
+ var dj = new DJ();
121
+
122
+ var _s = require('underscore.string');
123
+
124
+ var row = {
125
+ 'nr': 200,
126
+ 'doc.name': ' My Document '
127
+ };
128
+
129
+ var mods = {
130
+ "doc.name": [_s.trim, _s.underscored],
131
+ };
132
+
133
+ dj.object(row, mods);
134
+
135
+ console.log(row);
136
+ ```
137
+
138
+ ```
139
+ {
140
+ "nr": 200,
141
+ "doc": {
142
+ "name": "my_document"
143
+ }
144
+ }
145
+ ```
146
+
147
+ Or using .str() directy:
148
+
149
+ ```javascript
150
+
151
+ var DJ = require('dot-object');
152
+ var _s = require('underscore.string');
153
+ var obj = { id: 100 };
154
+
155
+ var dj = new DJ();
156
+
157
+ // use one modifier
158
+ dj.str('my.title', 'this is my title', obj, _s.slugify);
159
+
160
+ // multiple modifiers
161
+ dj.str('my.title', ' this is my title ', obj, [_s.trim, _s.slugify]);
162
+
163
+ console.log(obj);
164
+ ```
165
+ Result:
166
+ ```json
167
+ {
168
+ "id": 100,
169
+ "my": {
170
+ "title": "this-is-my-title"
171
+ }
172
+ }
173
+ ```
174
+
175
+ ## Using a different seperator
176
+
177
+ If you do not like dot notation, you are free to specify a different seperator.
178
+
179
+ ```javascript
180
+ var DJ = require('dot-object');
181
+
182
+ var dj = new DJ('->');
183
+
184
+ var _s = require('underscore.string');
185
+
186
+ var row = {
187
+ 'nr': 200,
188
+ 'doc->name': ' My Document '
189
+ };
190
+
191
+ var mods = {
192
+ "doc->name": [_s.trim, _s.underscored],
193
+ };
194
+
195
+ dj.object(row, mods);
196
+
197
+ console.log(row);
198
+ ```
199
+
200
+ ```
201
+ {
202
+ "nr": 200,
203
+ "doc": {
204
+ "name": "my_document"
205
+ }
206
+ }
207
+ ```
208
+
209
+ ## Transforming SQL results to JSON
210
+
211
+ SQL translation on the fly:
212
+
213
+ ```javascript
214
+ // TODO
215
+
216
+ ```
217
+
218
+
219
+ > Copyright © 2013 Rob Halff, released under the MIT license
package/index.js ADDED
@@ -0,0 +1,189 @@
1
+ 'use strict';
2
+
3
+ function DotObject(seperator, override) {
4
+
5
+ if(!(this instanceof DotObject)) return new DotObject(seperator, override);
6
+
7
+ if (typeof seperator === 'undefined') { seperator = '.'; }
8
+ if (typeof override === 'undefined') { override = false; }
9
+ this.seperator = seperator;
10
+ this.override = override;
11
+ }
12
+
13
+ DotObject.prototype._fill = function (a, obj, v, mod) {
14
+ var k = a.shift();
15
+
16
+ if (a.length > 0) {
17
+ obj[k] = obj[k] || {};
18
+
19
+ if (obj[k] !== Object(obj[k])) {
20
+ if (this.override) {
21
+ obj[k] = {};
22
+ } else {
23
+ throw new Error('Trying to redefine \'' + k + '\' which is a ' + typeof obj[k]);
24
+ }
25
+ }
26
+
27
+ this._fill(a, obj[k], v, mod);
28
+ } else {
29
+ if (obj[k] === Object(obj[k]) && Object.keys(obj[k]).length) {
30
+ throw new Error('Trying to redefine non-empty obj[\'' + k + '\']');
31
+ }
32
+
33
+ obj[k] = this.process(v, mod);
34
+ }
35
+ };
36
+
37
+ DotObject.prototype.process = function (v, mod) {
38
+ var i;
39
+
40
+ if (typeof mod === 'function') {
41
+ v = mod(v);
42
+ } else if (mod instanceof Array) {
43
+ for (i = 0; i < mod.length; i++) {
44
+ v = mod[i](v);
45
+ }
46
+ }
47
+
48
+ return v;
49
+ };
50
+
51
+ DotObject.prototype.object = function (obj, mods) {
52
+ var self = this;
53
+
54
+ Object.keys(obj).forEach(function (k, i) {
55
+ var mod = mods === undefined ? null : mods[k];
56
+
57
+ if (k.indexOf(self.seperator) !== -1) {
58
+ self._fill(k.split(self.seperator), obj, obj[k], mod);
59
+ delete obj[k];
60
+ } else if (self.override) {
61
+ obj[k] = self.process(obj[k], mod);
62
+ }
63
+ });
64
+ };
65
+
66
+ DotObject.prototype.str = function (str, v, obj, mod) {
67
+ if (str.indexOf(this.seperator) !== -1) {
68
+ this._fill(str.split(this.seperator), obj, v, mod);
69
+ } else if (this.override) {
70
+ obj[str] = this.process(v, mod);
71
+ }
72
+ };
73
+
74
+ /**
75
+ *
76
+ * Pick a value from an object using dot notation.
77
+ *
78
+ * Optionally remove the value
79
+ *
80
+ * @param {String} path
81
+ * @param {Object} obj
82
+ * @param {Boolean} remove
83
+ */
84
+ DotObject.prototype.pick = function (path, obj, remove) {
85
+ var i, keys, val;
86
+
87
+ if (path.indexOf(this.seperator) !== -1) {
88
+ keys = path.split(this.seperator);
89
+ for (i = 0; i < keys.length; i++) {
90
+ if(obj.hasOwnProperty(keys[i])) {
91
+ if(i === (keys.length - 1)) {
92
+ if(remove) {
93
+ val = obj[keys[i]];
94
+ delete obj[keys[i]];
95
+ return val;
96
+ } else {
97
+ return obj[keys[i]];
98
+ }
99
+ } else {
100
+ obj = obj[keys[i]];
101
+ }
102
+ } else {
103
+ return undefined;
104
+ }
105
+ }
106
+ return obj;
107
+ } else {
108
+ if(remove) {
109
+ val = obj[path];
110
+ delete obj[path];
111
+ return val;
112
+ } else {
113
+ return obj[path];
114
+ }
115
+ }
116
+ };
117
+
118
+ /**
119
+ *
120
+ * Move a property from one place to the other.
121
+ *
122
+ * If the source path does not exist (undefined)
123
+ * the target property will not be set.
124
+ *
125
+ * @param {String} source
126
+ * @param {String} target
127
+ * @param {Object} obj
128
+ *
129
+ */
130
+ DotObject.prototype.move = function (source, target, obj) {
131
+
132
+ this.set(target, this.pick(source, obj, true), obj);
133
+
134
+ return obj;
135
+
136
+ };
137
+
138
+ /**
139
+ *
140
+ * Transfer a property from one object to another object.
141
+ *
142
+ * If the source path does not exist (undefined)
143
+ * the property on the other object will not be set.
144
+ *
145
+ * @param {String} source
146
+ * @param {String} target
147
+ * @param {Object} obj
148
+ *
149
+ */
150
+ DotObject.prototype.transfer = function (source, target, obj1, obj2) {
151
+
152
+ this.set(target, this.pick(source, obj1, true), obj2);
153
+
154
+ return obj2;
155
+
156
+ };
157
+
158
+ /**
159
+ *
160
+ * Set a property on an object using dot notation.
161
+ *
162
+ */
163
+ DotObject.prototype.set = function (path, val, obj) {
164
+ var i, keys;
165
+
166
+ // Do not operate if the value is undefined.
167
+ if(typeof val === 'undefined') return obj;
168
+
169
+ if (path.indexOf(this.seperator) !== -1) {
170
+ keys = path.split(this.seperator);
171
+ for (i = 0; i < keys.length; i++) {
172
+ if(i === (keys.length - 1)) {
173
+ obj[keys[i]] = val;
174
+ } else if(
175
+ // force the value to be an object
176
+ !obj.hasOwnProperty(keys[i]) ||
177
+ Object.prototype.toString.call(obj[keys[i]]) !== '[object Object]') {
178
+ obj[keys[i]] = {};
179
+ }
180
+ obj = obj[keys[i]];
181
+ }
182
+ return obj;
183
+ } else {
184
+ obj[path] = val;
185
+ return obj;
186
+ }
187
+ };
188
+
189
+ module.exports = DotObject;
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "dot-object",
3
+ "description": "dot-object makes it possible to transform and read (JSON) objects using dot notation.",
4
+ "version": "0.3.0",
5
+ "author": {
6
+ "name": "Rob Halff",
7
+ "email": "rob.halff@gmail.com"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git://github.com/rhalff/dot-object.git"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/rhalff/dot-object/issues"
15
+ },
16
+ "main": "index",
17
+ "scripts": {
18
+ "test": "mocha"
19
+ },
20
+ "devDependencies": {
21
+ "underscore.string": "latest",
22
+ "mocha": "1.x.x",
23
+ "should": "1.x.x",
24
+ "grunt": "0.x.x",
25
+ "grunt-release": "0.x.x",
26
+ "grunt-contrib-watch": "0.x.x",
27
+ "grunt-shell": "0.x.x"
28
+ },
29
+ "keywords": [
30
+ "json",
31
+ "filter",
32
+ "transform",
33
+ "dot notation",
34
+ "dot"
35
+ ]
36
+ }
@@ -0,0 +1,222 @@
1
+ require('should');
2
+ var _s = require('underscore.string');
3
+ var DJ = require('../index.js');
4
+
5
+ describe("Dot Object test:", function () {
6
+
7
+ it("Should Dot object keys", function (done) {
8
+
9
+ var dj = new DJ();
10
+
11
+ var row = {
12
+ 'id': 2,
13
+ 'contact.name.first': 'John',
14
+ 'contact.name.last': 'Doe',
15
+ 'contact.email': 'example@gmail.com',
16
+ 'contact.info.about.me': 'classified'
17
+ };
18
+
19
+ dj.object(row);
20
+
21
+ row.should.eql({
22
+ "id": 2,
23
+ "contact": {
24
+ "name": {
25
+ "first": "John",
26
+ "last": "Doe"
27
+ },
28
+ "email": "example@gmail.com",
29
+ "info": {
30
+ "about": {
31
+ "me": "classified"
32
+ }
33
+ }
34
+ }
35
+ });
36
+
37
+ done();
38
+
39
+ });
40
+
41
+ it("Should Dot Object a string", function (done) {
42
+
43
+ var obj = {};
44
+
45
+ var dj = new DJ();
46
+
47
+ dj.str('this.is.my.string', 'value', obj);
48
+
49
+ obj.should.eql({
50
+ "this": {
51
+ "is": {
52
+ "my": {
53
+ "string": "value"
54
+ }
55
+ }
56
+ }
57
+ });
58
+
59
+ done();
60
+
61
+ });
62
+
63
+ it("DJ.str Redefinition should fail", function (done) {
64
+
65
+ var obj = {
66
+ 'already': 'set'
67
+ };
68
+
69
+ (function () {
70
+
71
+ var dj = new DJ();
72
+
73
+ dj.str('already.new', 'value', obj);
74
+
75
+ }).should.throw("Trying to redefine 'already' which is a string");
76
+
77
+ done();
78
+
79
+ });
80
+
81
+ it("DJ.str should process a modifier", function (done) {
82
+
83
+ var obj = {};
84
+
85
+ var dj = new DJ();
86
+
87
+ dj.str('this.is.my.string', 'value', obj, _s.capitalize);
88
+
89
+ obj.should.eql({
90
+ "this": {
91
+ "is": {
92
+ "my": {
93
+ "string": "Value"
94
+ }
95
+ }
96
+ }
97
+ });
98
+
99
+ done();
100
+
101
+ });
102
+
103
+ it("DOT.str should process multiple modifiers", function (done) {
104
+
105
+ var obj = {};
106
+
107
+ var dj = new DJ();
108
+
109
+ dj.str('this.is.my.string', ' this is a test ', obj, [_s.trim, _s.underscored]);
110
+
111
+ obj.should.eql({
112
+ "this": {
113
+ "is": {
114
+ "my": {
115
+ "string": "this_is_a_test"
116
+ }
117
+ }
118
+ }
119
+ });
120
+
121
+ done();
122
+
123
+ });
124
+
125
+ it("DJ.object should process a modifier", function (done) {
126
+
127
+ var row = {
128
+ 'page.title': 'my page',
129
+ 'page.slug': 'My Page'
130
+ };
131
+
132
+ var mods = {
133
+ "page.title": _s.titleize,
134
+ "page.slug": _s.slugify
135
+ };
136
+
137
+ var dj = new DJ();
138
+
139
+ dj.object(row, mods);
140
+
141
+ row.should.eql({
142
+ "page": {
143
+ "title": "My Page",
144
+ "slug": "my-page"
145
+ }
146
+ });
147
+
148
+ done();
149
+
150
+ });
151
+
152
+ it("DJ.object should not process non dot notation value with modifier when DJ.override is false", function (done) {
153
+
154
+ var row = {
155
+ 'title': 'my page',
156
+ 'slug': 'My Page'
157
+ };
158
+
159
+ var mods = {
160
+ "title": _s.titleize,
161
+ "slug": _s.slugify
162
+ };
163
+
164
+ var dj = new DJ();
165
+ dj.object(row, mods);
166
+
167
+ row.should.eql({
168
+ "title": "my page",
169
+ "slug": "My Page"
170
+ });
171
+
172
+ done();
173
+
174
+ });
175
+
176
+ it("DJ.object should process multiple modifiers", function (done) {
177
+
178
+ var row = {
179
+ 'page.name': ' My Page '
180
+ };
181
+
182
+ var mods = {
183
+ "page.name": [_s.trim, _s.underscored]
184
+ };
185
+
186
+ var dj = new DJ();
187
+ dj.object(row, mods);
188
+
189
+ row.should.eql({
190
+ "page": {
191
+ "name": "my_page"
192
+ }
193
+ });
194
+
195
+ done();
196
+
197
+ });
198
+
199
+ it("DJ.object should work with a different seperator", function (done) {
200
+
201
+ var row = {
202
+ 'page=>name': ' My Page '
203
+ };
204
+
205
+ var mods = {
206
+ "page=>name": [_s.trim, _s.underscored]
207
+ };
208
+
209
+ var dj = new DJ("=>", false);
210
+ dj.object(row, mods);
211
+
212
+ row.should.eql({
213
+ "page": {
214
+ "name": "my_page"
215
+ }
216
+ });
217
+
218
+ done();
219
+
220
+ });
221
+
222
+ });
File without changes
package/test/move.js ADDED
@@ -0,0 +1,60 @@
1
+ require('should');
2
+ var _s = require('underscore.string');
3
+ var dj = require('../index.js')();
4
+
5
+ describe("DJ value picker:", function () {
6
+
7
+ it("Should be able to move properties", function (done) {
8
+
9
+ var link = {
10
+ id: '527423a65e380f0000588e47',
11
+ source: '526dd5c6b4c4aa8770000001',
12
+ target: '527402d6b15d1800008755cf',
13
+ out: 'github',
14
+ in: 'in'
15
+ };
16
+
17
+ var expected = {
18
+ id: '527423a65e380f0000588e47',
19
+ source: { id: '526dd5c6b4c4aa8770000001', port: 'github' },
20
+ target: { id: '527402d6b15d1800008755cf', port: 'in' }
21
+ };
22
+
23
+ dj.move('source', 'source.id', link);
24
+ dj.move('out', 'source.port', link);
25
+ dj.move('target', 'target.id', link);
26
+ dj.move('in', 'target.port', link);
27
+
28
+ link.should.eql(expected);
29
+
30
+ done();
31
+
32
+ });
33
+
34
+ it("Undefined properties should be ignored", function (done) {
35
+
36
+ var link = {
37
+ source: '526dd5c6b4c4aa8770000001',
38
+ target: '527402d6b15d1800008755cf',
39
+ out: 'github',
40
+ in: 'in'
41
+ };
42
+
43
+ var expected = {
44
+ source: { id: '526dd5c6b4c4aa8770000001' },
45
+ target: { port: 'in' },
46
+ out: 'github'
47
+ };
48
+
49
+ dj.move('source', 'source.id', link);
50
+ dj.move('out.er.nope', 'source.port', link);
51
+ dj.move('target.bla.di.bla', 'target.id', link);
52
+ dj.move('in', 'target.port', link);
53
+
54
+ link.should.eql(expected);
55
+
56
+ done();
57
+
58
+ });
59
+
60
+ });
@@ -0,0 +1,74 @@
1
+ require('should');
2
+ var _s = require('underscore.string');
3
+ var DJ = require('../index.js');
4
+
5
+ describe("DJ test:", function () {
6
+
7
+
8
+ it("Redefinition should _not_ fail if override is true", function (done) {
9
+
10
+ var dj = new DJ('.', true);
11
+
12
+ var obj = {
13
+ 'some': 'value',
14
+ 'already': 'set'
15
+ };
16
+
17
+ dj.str('already.new', 'value', obj);
18
+
19
+ obj.should.eql({
20
+ "some": "value",
21
+ "already": { "new": "value" }
22
+ });
23
+
24
+ done();
25
+
26
+ });
27
+
28
+ it("Redefinition should _not_ fail if override is true", function (done) {
29
+
30
+ var dj = new DJ('.', true);
31
+
32
+ var obj = {
33
+ 'some': 'value',
34
+ 'already': 'set'
35
+ };
36
+
37
+ dj.str('already.new', 'value', obj);
38
+ dj.str('some', 'new_value', obj);
39
+
40
+ obj.should.eql({
41
+ "some": "new_value",
42
+ "already": { "new": "value" }
43
+ });
44
+
45
+ done();
46
+
47
+ });
48
+
49
+ it("DJ.object _should_ process non dot notation value with modifier when DJ.override is true", function (done) {
50
+
51
+ var dj = new DJ('.', true);
52
+
53
+ var row = {
54
+ 'title': 'my page',
55
+ 'slug': 'My Page'
56
+ };
57
+
58
+ var mods = {
59
+ "title": _s.titleize,
60
+ "slug": _s.slugify
61
+ };
62
+
63
+ dj.object(row, mods);
64
+
65
+ row.should.eql({
66
+ "title": "My Page",
67
+ "slug": "my-page"
68
+ });
69
+
70
+ done();
71
+
72
+ });
73
+
74
+ });
package/test/pick.js ADDED
@@ -0,0 +1,42 @@
1
+ require('should');
2
+ var _s = require('underscore.string');
3
+ var DJ = require('../index.js');
4
+
5
+ describe("DJ value picker:", function () {
6
+
7
+ it("Should be able to pick a value", function (done) {
8
+
9
+ var dj = new DJ('.', true);
10
+
11
+ var obj = {
12
+ 'some': 'value',
13
+ 'already': 'set'
14
+ };
15
+
16
+ var val = dj.pick('some', obj);
17
+
18
+ val.should.eql('value');
19
+
20
+ done();
21
+
22
+ });
23
+
24
+ it("Should be able to pick dotted value", function (done) {
25
+
26
+ var dj = new DJ();
27
+
28
+ var obj = {
29
+ 'some': {
30
+ 'other': 'value'
31
+ }
32
+ };
33
+
34
+ var val = dj.pick('some.other', obj);
35
+
36
+ val.should.eql('value');
37
+
38
+ done();
39
+
40
+ });
41
+
42
+ });