dot-object 1.5.3 → 1.7.1

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/CHANGELOG.md CHANGED
@@ -1,7 +1,19 @@
1
1
  # ChangeLog
2
2
 
3
+ ## 2018-10-26 Version 1.7.1
4
+ * [[`e1bb99c83e`](https://github.com/rhalff/dot-object/commit/e1bb99c83e)] - Fix isIndex numeric key matching. (Fixed by mrdivyansh #31)
5
+
6
+ ## 2017-09-20 Version 1.7.0
7
+ * let .dot and .object understand empty objects / arrays
8
+
9
+ ## 2017-07-27 Version 1.6.0
10
+ * implemented keepArray
11
+
12
+ ## 2016-09-29 Version 1.5.4
13
+ * update dist
14
+
3
15
  ## 2016-09-29, Version 1.5.3
4
- * Fix override bug in str()
16
+ * Fix override bug in str()
5
17
 
6
18
  ## 2016-08-04, Version 1.5.0
7
19
  * [[`a7e948f2fa`](https://github.com/rhalff/dot-object/commit/a7e948f2fa)] - Ensure we only process true Arrays and Objects. (Fixed by MechJosh0 #15)
package/README.md CHANGED
@@ -166,7 +166,7 @@ console.log(tgt);
166
166
  ```
167
167
 
168
168
  #### Pick/remove a value using dot notation:
169
- ```
169
+ ```js
170
170
  var dot = require('dot-object');
171
171
 
172
172
  var obj = {
@@ -327,9 +327,9 @@ Result:
327
327
  }
328
328
  ```
329
329
 
330
- ## Using a different seperator
330
+ ## Using a different separator
331
331
 
332
- If you do not like dot notation, you are free to specify a different seperator.
332
+ If you do not like dot notation, you are free to specify a different separator.
333
333
 
334
334
  ```javascript
335
335
  var Dot = require('dot-object');
package/bower.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "type": "git",
26
26
  "url": "git://github.com/rhalff/dot-object.git"
27
27
  },
28
- "version": "1.5.3",
28
+ "version": "1.7.0",
29
29
  "homepage": "https://github.com/rhalff/dot-object",
30
30
  "moduleType": [
31
31
  "amd",
@@ -31,7 +31,19 @@
31
31
  }
32
32
 
33
33
  function isIndex(k) {
34
- return /^\d+/.test(k)
34
+ return /^\d+$/.test(k)
35
+ }
36
+
37
+ function isObject(val) {
38
+ return Object.prototype.toString.call(val) === '[object Object]'
39
+ }
40
+
41
+ function isArrayOrObject(val) {
42
+ return Object(val) === val
43
+ }
44
+
45
+ function isEmptyObject(val) {
46
+ return Object.keys(val).length === 0
35
47
  }
36
48
 
37
49
  function parsePath(path, sep) {
@@ -41,17 +53,17 @@
41
53
  return path.split(sep)
42
54
  }
43
55
 
44
- function DotObject(seperator, override, useArray) {
56
+ function DotObject(separator, override, useArray) {
45
57
  if (!(this instanceof DotObject)) {
46
- return new DotObject(seperator, override, useArray)
58
+ return new DotObject(separator, override, useArray)
47
59
  }
48
60
 
49
- if (typeof seperator === 'undefined') seperator = '.'
50
61
  if (typeof override === 'undefined') override = false
51
62
  if (typeof useArray === 'undefined') useArray = true
52
- this.seperator = seperator
63
+ this.separator = separator || '.'
53
64
  this.override = override
54
65
  this.useArray = useArray
66
+ this.keepArray = false
55
67
 
56
68
  // contains touched arrays
57
69
  this.cleanup = []
@@ -72,21 +84,29 @@
72
84
  obj[k] = obj[k] ||
73
85
  (this.useArray && isIndex(a[0]) ? [] : {})
74
86
 
75
- if (obj[k] !== Object(obj[k])) {
87
+ if (!isArrayOrObject(obj[k])) {
76
88
  if (this.override) {
77
89
  obj[k] = {}
78
90
  } else {
79
- throw new Error(
80
- 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
81
- )
91
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
92
+ throw new Error(
93
+ 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
94
+ )
95
+ }
96
+
97
+ return
82
98
  }
83
99
  }
84
100
 
85
101
  this._fill(a, obj[k], v, mod)
86
102
  } else {
87
103
  if (!this.override &&
88
- obj[k] === Object(obj[k]) && Object.keys(obj[k]).length) {
89
- throw new Error("Trying to redefine non-empty obj['" + k + "']")
104
+ isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
105
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
106
+ throw new Error("Trying to redefine non-empty obj['" + k + "']")
107
+ }
108
+
109
+ return
90
110
  }
91
111
 
92
112
  obj[k] = _process(v, mod)
@@ -120,11 +140,11 @@
120
140
 
121
141
  Object.keys(obj).forEach(function(k) {
122
142
  var mod = mods === undefined ? null : mods[k]
123
- // normalize array notation.
124
- var ok = parsePath(k, self.seperator).join(self.seperator)
143
+ // normalize array notation.
144
+ var ok = parsePath(k, self.separator).join(self.separator)
125
145
 
126
- if (ok.indexOf(self.seperator) !== -1) {
127
- self._fill(ok.split(self.seperator), obj, obj[k], mod)
146
+ if (ok.indexOf(self.separator) !== -1) {
147
+ self._fill(ok.split(self.separator), obj, obj[k], mod)
128
148
  delete obj[k]
129
149
  } else if (self.override) {
130
150
  obj[k] = _process(obj[k], mod)
@@ -141,9 +161,9 @@
141
161
  * @param {Function|Array} mod optional modifier
142
162
  */
143
163
  DotObject.prototype.str = function(path, v, obj, mod) {
144
- if (path.indexOf(this.seperator) !== -1) {
145
- this._fill(path.split(this.seperator), obj, v, mod)
146
- } else if (this.override) {
164
+ if (path.indexOf(this.separator) !== -1) {
165
+ this._fill(path.split(this.separator), obj, v, mod)
166
+ } else if (!obj.hasOwnProperty(path) || this.override) {
147
167
  obj[path] = _process(v, mod)
148
168
  }
149
169
 
@@ -167,7 +187,7 @@
167
187
  var key
168
188
  var cp
169
189
 
170
- keys = parsePath(path, this.seperator)
190
+ keys = parsePath(path, this.separator)
171
191
  for (i = 0; i < keys.length; i++) {
172
192
  key = parseKey(keys[i], obj)
173
193
  if (obj && typeof obj === 'object' && key in obj) {
@@ -332,10 +352,6 @@
332
352
  return obj2
333
353
  }
334
354
 
335
- function isObject(val) {
336
- return Object.prototype.toString.call(val) === '[object Object]'
337
- }
338
-
339
355
  /**
340
356
  *
341
357
  * Set a property on an object using dot notation.
@@ -355,7 +371,7 @@
355
371
  if (typeof val === 'undefined') {
356
372
  return obj
357
373
  }
358
- keys = parsePath(path, this.seperator)
374
+ keys = parsePath(path, this.separator)
359
375
 
360
376
  for (i = 0; i < keys.length; i++) {
361
377
  key = keys[i]
@@ -444,10 +460,18 @@
444
460
  tgt = tgt || {}
445
461
  path = path || []
446
462
  Object.keys(obj).forEach(function(key) {
447
- if (Object(obj[key]) === obj[key] && (Object.prototype.toString.call(obj[key]) === '[object Object]') || Object.prototype.toString.call(obj[key]) === '[object Array]') {
463
+ if (
464
+ (
465
+ isArrayOrObject(obj[key]) &&
466
+ (
467
+ (isObject(obj[key]) && !isEmptyObject(obj[key])) ||
468
+ (Array.isArray(obj[key]) && (!this.keepArray && (obj[key].length !== 0)))
469
+ )
470
+ )
471
+ ) {
448
472
  return this.dot(obj[key], tgt, path.concat(key))
449
473
  } else {
450
- tgt[path.concat(key).join(this.seperator)] = obj[key]
474
+ tgt[path.concat(key).join(this.separator)] = obj[key]
451
475
  }
452
476
  }.bind(this))
453
477
  return tgt
@@ -476,13 +500,16 @@
476
500
  })
477
501
  })
478
502
 
479
- Object.defineProperty(DotObject, 'useArray', {
480
- get: function() {
481
- return dotDefault.useArray
482
- },
483
- set: function(val) {
484
- dotDefault.useArray = val
485
- }
503
+ ;
504
+ ['useArray', 'keepArray'].forEach(function(prop) {
505
+ Object.defineProperty(DotObject, prop, {
506
+ get: function() {
507
+ return dotDefault[prop]
508
+ },
509
+ set: function(val) {
510
+ dotDefault[prop] = val
511
+ }
512
+ })
486
513
  })
487
514
 
488
515
  DotObject._process = _process
@@ -490,12 +517,12 @@
490
517
 
491
518
  if (typeof define === 'function' && define.amd) {
492
519
  define(function() {
493
- return DotObject;
494
- });
520
+ return DotObject
521
+ })
495
522
  } else if (typeof module != 'undefined' && module.exports) {
496
- module.exports = DotObject;
523
+ module.exports = DotObject
497
524
  } else {
498
- global[exportName] = DotObject;
525
+ global[exportName] = DotObject
499
526
  }
500
527
 
501
- })(this, 'DotObject');
528
+ })(this, 'DotObject')
@@ -1 +1 @@
1
- !function(t,e){"use strict";function r(t,e){var r,i;if("function"==typeof e)i=e(t),void 0!==i&&(t=i);else if(Array.isArray(e))for(r=0;r<e.length;r++)i=e[r](t),void 0!==i&&(t=i);return t}function i(t,e){return"-"===t[0]&&Array.isArray(e)&&/^-\d+$/.test(t)?e.length+parseInt(t,10):t}function n(t){return/^\d+/.test(t)}function o(t,e){return t.indexOf("[")>=0&&(t=t.replace(/\[/g,".").replace(/]/g,"")),t.split(e)}function s(t,e,r){return this instanceof s?("undefined"==typeof t&&(t="."),"undefined"==typeof e&&(e=!1),"undefined"==typeof r&&(r=!0),this.seperator=t,this.override=e,this.useArray=r,void(this.cleanup=[])):new s(t,e,r)}function c(t){return function(){return p[t].apply(p,arguments)}}function f(t){return"[object Object]"===Object.prototype.toString.call(t)}var p=new s(".",(!1),(!0));s.prototype._fill=function(t,e,i,o){var s=t.shift();if(t.length>0){if(e[s]=e[s]||(this.useArray&&n(t[0])?[]:{}),e[s]!==Object(e[s])){if(!this.override)throw new Error("Trying to redefine `"+s+"` which is a "+typeof e[s]);e[s]={}}this._fill(t,e[s],i,o)}else{if(!this.override&&e[s]===Object(e[s])&&Object.keys(e[s]).length)throw new Error("Trying to redefine non-empty obj['"+s+"']");e[s]=r(i,o)}},s.prototype.object=function(t,e){var i=this;return Object.keys(t).forEach(function(n){var s=void 0===e?null:e[n],c=o(n,i.seperator).join(i.seperator);c.indexOf(i.seperator)!==-1?(i._fill(c.split(i.seperator),t,t[n],s),delete t[n]):i.override&&(t[n]=r(t[n],s))}),t},s.prototype.str=function(t,e,i,n){return t.indexOf(this.seperator)!==-1?this._fill(t.split(this.seperator),i,e,n):this.override&&(i[t]=r(e,n)),i},s.prototype.pick=function(t,e,r){var n,s,c,f,p;for(s=o(t,this.seperator),n=0;n<s.length;n++){if(f=i(s[n],e),!(e&&"object"==typeof e&&f in e))return;if(n===s.length-1)return r?(c=e[f],delete e[f],Array.isArray(e)&&(p=s.slice(0,-1).join("."),this.cleanup.indexOf(p)===-1&&this.cleanup.push(p)),c):e[f];e=e[f]}return r&&Array.isArray(e)&&(e=e.filter(function(t){return void 0!==t})),e},s.prototype.remove=function(t,e){var r;if(this.cleanup=[],Array.isArray(t)){for(r=0;r<t.length;r++)this.pick(t[r],e,!0);return this._cleanup(e),e}return this.pick(t,e,!0)},s.prototype._cleanup=function(t){var e,r,i,n;if(this.cleanup.length){for(r=0;r<this.cleanup.length;r++)i=this.cleanup[r].split("."),n=i.splice(0,-1).join("."),e=n?this.pick(n,t):t,e=e[i[0]].filter(function(t){return void 0!==t}),this.set(this.cleanup[r],e,t);this.cleanup=[]}},s.prototype.del=s.prototype.remove,s.prototype.move=function(t,e,i,n,o){return"function"==typeof n||Array.isArray(n)?this.set(e,r(this.pick(t,i,!0),n),i,o):(o=n,this.set(e,this.pick(t,i,!0),i,o)),i},s.prototype.transfer=function(t,e,i,n,o,s){return"function"==typeof o||Array.isArray(o)?this.set(e,r(this.pick(t,i,!0),o),n,s):(s=o,this.set(e,this.pick(t,i,!0),n,s)),n},s.prototype.copy=function(t,e,i,n,o,s){return"function"==typeof o||Array.isArray(o)?this.set(e,r(JSON.parse(JSON.stringify(this.pick(t,i,!1))),o),n,s):(s=o,this.set(e,this.pick(t,i,!1),n,s)),n},s.prototype.set=function(t,e,r,i){var n,s,c,p;if("undefined"==typeof e)return r;for(c=o(t,this.seperator),n=0;n<c.length;n++){if(p=c[n],n===c.length-1)if(i&&f(e)&&f(r[p]))for(s in e)e.hasOwnProperty(s)&&(r[p][s]=e[s]);else if(i&&Array.isArray(r[p])&&Array.isArray(e))for(var u=0;u<e.length;u++)r[c[n]].push(e[u]);else r[p]=e;else r.hasOwnProperty(p)&&(f(r[p])||Array.isArray(r[p]))||(/^\d+$/.test(c[n+1])?r[p]=[]:r[p]={});r=r[p]}return r},s.prototype.transform=function(t,e,r){return e=e||{},r=r||{},Object.keys(t).forEach(function(i){this.set(t[i],this.pick(i,e),r)}.bind(this)),r},s.prototype.dot=function(t,e,r){return e=e||{},r=r||[],Object.keys(t).forEach(function(i){return Object(t[i])===t[i]&&"[object Object]"===Object.prototype.toString.call(t[i])||"[object Array]"===Object.prototype.toString.call(t[i])?this.dot(t[i],e,r.concat(i)):void(e[r.concat(i).join(this.seperator)]=t[i])}.bind(this)),e},s.pick=c("pick"),s.move=c("move"),s.transfer=c("transfer"),s.transform=c("transform"),s.copy=c("copy"),s.object=c("object"),s.str=c("str"),s.set=c("set"),s.del=s.remove=c("remove"),s.dot=c("dot"),["override","overwrite"].forEach(function(t){Object.defineProperty(s,t,{get:function(){return p.override},set:function(t){p.override=!!t}})}),Object.defineProperty(s,"useArray",{get:function(){return p.useArray},set:function(t){p.useArray=t}}),s._process=r,"function"==typeof define&&define.amd?define(function(){return s}):"undefined"!=typeof module&&module.exports?module.exports=s:t[e]=s}(this,"DotObject");
1
+ !function(t,r){"use strict";function s(t,r){var e,i;if("function"==typeof r)void 0!==(i=r(t))&&(t=i);else if(Array.isArray(r))for(e=0;e<r.length;e++)void 0!==(i=r[e](t))&&(t=i);return t}function c(t){return"[object Object]"===Object.prototype.toString.call(t)}function f(t){return Object(t)===t}function p(t){return 0===Object.keys(t).length}function a(t,r){return 0<=t.indexOf("[")&&(t=t.replace(/\[/g,".").replace(/]/g,"")),t.split(r)}function i(t,r,e){if(!(this instanceof i))return new i(t,r,e);void 0===r&&(r=!1),void 0===e&&(e=!0),this.separator=t||".",this.override=r,this.useArray=e,this.keepArray=!1,this.cleanup=[]}var e=new i(".",!1,!0);function n(t){return function(){return e[t].apply(e,arguments)}}i.prototype._fill=function(t,r,e,i){var n,o=t.shift();if(0<t.length){if(r[o]=r[o]||(this.useArray&&(n=t[0],/^\d+$/.test(n))?[]:{}),!f(r[o])){if(!this.override){if(!f(e)||!p(e))throw new Error("Trying to redefine `"+o+"` which is a "+typeof r[o]);return}r[o]={}}this._fill(t,r[o],e,i)}else{if(!this.override&&f(r[o])&&!p(r[o])){if(!f(e)||!p(e))throw new Error("Trying to redefine non-empty obj['"+o+"']");return}r[o]=s(e,i)}},i.prototype.object=function(i,n){var o=this;return Object.keys(i).forEach(function(t){var r=void 0===n?null:n[t],e=a(t,o.separator).join(o.separator);-1!==e.indexOf(o.separator)?(o._fill(e.split(o.separator),i,i[t],r),delete i[t]):o.override&&(i[t]=s(i[t],r))}),i},i.prototype.str=function(t,r,e,i){return-1!==t.indexOf(this.separator)?this._fill(t.split(this.separator),e,r,i):e.hasOwnProperty(t)&&!this.override||(e[t]=s(r,i)),e},i.prototype.pick=function(t,r,e){var i,n,o,s,f,p,c;for(n=a(t,this.separator),i=0;i<n.length;i++){if(p=n[i],c=r,s="-"===p[0]&&Array.isArray(c)&&/^-\d+$/.test(p)?c.length+parseInt(p,10):p,!(r&&"object"==typeof r&&s in r))return;if(i===n.length-1)return e?(o=r[s],delete r[s],Array.isArray(r)&&(f=n.slice(0,-1).join("."),-1===this.cleanup.indexOf(f)&&this.cleanup.push(f)),o):r[s];r=r[s]}return e&&Array.isArray(r)&&(r=r.filter(function(t){return void 0!==t})),r},i.prototype.remove=function(t,r){var e;if(this.cleanup=[],Array.isArray(t)){for(e=0;e<t.length;e++)this.pick(t[e],r,!0);return this._cleanup(r),r}return this.pick(t,r,!0)},i.prototype._cleanup=function(t){var r,e,i,n;if(this.cleanup.length){for(e=0;e<this.cleanup.length;e++)r=(r=(n=(i=this.cleanup[e].split(".")).splice(0,-1).join("."))?this.pick(n,t):t)[i[0]].filter(function(t){return void 0!==t}),this.set(this.cleanup[e],r,t);this.cleanup=[]}},i.prototype.del=i.prototype.remove,i.prototype.move=function(t,r,e,i,n){return"function"==typeof i||Array.isArray(i)?this.set(r,s(this.pick(t,e,!0),i),e,n):(n=i,this.set(r,this.pick(t,e,!0),e,n)),e},i.prototype.transfer=function(t,r,e,i,n,o){return"function"==typeof n||Array.isArray(n)?this.set(r,s(this.pick(t,e,!0),n),i,o):(o=n,this.set(r,this.pick(t,e,!0),i,o)),i},i.prototype.copy=function(t,r,e,i,n,o){return"function"==typeof n||Array.isArray(n)?this.set(r,s(JSON.parse(JSON.stringify(this.pick(t,e,!1))),n),i,o):(o=n,this.set(r,this.pick(t,e,!1),i,o)),i},i.prototype.set=function(t,r,e,i){var n,o,s,f;if(void 0===r)return e;for(s=a(t,this.separator),n=0;n<s.length;n++){if(f=s[n],n===s.length-1)if(i&&c(r)&&c(e[f]))for(o in r)r.hasOwnProperty(o)&&(e[f][o]=r[o]);else if(i&&Array.isArray(e[f])&&Array.isArray(r))for(var p=0;p<r.length;p++)e[s[n]].push(r[p]);else e[f]=r;else e.hasOwnProperty(f)&&(c(e[f])||Array.isArray(e[f]))||(/^\d+$/.test(s[n+1])?e[f]=[]:e[f]={});e=e[f]}return e},i.prototype.transform=function(r,e,i){return e=e||{},i=i||{},Object.keys(r).forEach(function(t){this.set(r[t],this.pick(t,e),i)}.bind(this)),i},i.prototype.dot=function(r,e,i){return e=e||{},i=i||[],Object.keys(r).forEach(function(t){if(f(r[t])&&(c(r[t])&&!p(r[t])||Array.isArray(r[t])&&!this.keepArray&&0!==r[t].length))return this.dot(r[t],e,i.concat(t));e[i.concat(t).join(this.separator)]=r[t]}.bind(this)),e},i.pick=n("pick"),i.move=n("move"),i.transfer=n("transfer"),i.transform=n("transform"),i.copy=n("copy"),i.object=n("object"),i.str=n("str"),i.set=n("set"),i.del=i.remove=n("remove"),i.dot=n("dot"),["override","overwrite"].forEach(function(t){Object.defineProperty(i,t,{get:function(){return e.override},set:function(t){e.override=!!t}})}),["useArray","keepArray"].forEach(function(r){Object.defineProperty(i,r,{get:function(){return e[r]},set:function(t){e[r]=t}})}),i._process=s,"function"==typeof define&&define.amd?define(function(){return i}):"undefined"!=typeof module&&module.exports?module.exports=i:t.DotObject=i}(this);
package/gulpfile.js CHANGED
@@ -33,8 +33,8 @@ gulp.task('watch', function () {
33
33
 
34
34
  gulp.task('build-node', function () {
35
35
  gulp.src('src/dot-object.js')
36
- .pipe(hf.footer('\nmodule.exports = DotObject;\n'))
37
- .pipe(rename({basename: 'index'}))
36
+ .pipe(hf.footer('\nmodule.exports = DotObject\n'))
37
+ .pipe(rename({ basename: 'index' }))
38
38
  .pipe(gulp.dest('./'))
39
39
  })
40
40
 
@@ -42,10 +42,10 @@ gulp.task('build-bower', function () {
42
42
  gulp.src('src/dot-object.js')
43
43
  .pipe(hf.header('src/header.tpl'))
44
44
  .pipe(hf.footer('src/footer.tpl'))
45
- .pipe(beautify({indentSize: 2}))
45
+ .pipe(beautify({ indentSize: 2 }))
46
46
  .pipe(gulp.dest(DEST))
47
47
  .pipe(uglify())
48
- .pipe(rename({extname: '.min.js'}))
48
+ .pipe(rename({ extname: '.min.js' }))
49
49
  .pipe(gulp.dest(DEST))
50
50
  })
51
51
 
package/index.js CHANGED
@@ -30,7 +30,19 @@ function parseKey (key, val) {
30
30
  }
31
31
 
32
32
  function isIndex (k) {
33
- return /^\d+/.test(k)
33
+ return /^\d+$/.test(k)
34
+ }
35
+
36
+ function isObject (val) {
37
+ return Object.prototype.toString.call(val) === '[object Object]'
38
+ }
39
+
40
+ function isArrayOrObject (val) {
41
+ return Object(val) === val
42
+ }
43
+
44
+ function isEmptyObject (val) {
45
+ return Object.keys(val).length === 0
34
46
  }
35
47
 
36
48
  function parsePath (path, sep) {
@@ -40,17 +52,17 @@ function parsePath (path, sep) {
40
52
  return path.split(sep)
41
53
  }
42
54
 
43
- function DotObject (seperator, override, useArray) {
55
+ function DotObject (separator, override, useArray) {
44
56
  if (!(this instanceof DotObject)) {
45
- return new DotObject(seperator, override, useArray)
57
+ return new DotObject(separator, override, useArray)
46
58
  }
47
59
 
48
- if (typeof seperator === 'undefined') seperator = '.'
49
60
  if (typeof override === 'undefined') override = false
50
61
  if (typeof useArray === 'undefined') useArray = true
51
- this.seperator = seperator
62
+ this.separator = separator || '.'
52
63
  this.override = override
53
64
  this.useArray = useArray
65
+ this.keepArray = false
54
66
 
55
67
  // contains touched arrays
56
68
  this.cleanup = []
@@ -70,21 +82,29 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
70
82
  obj[k] = obj[k] ||
71
83
  (this.useArray && isIndex(a[0]) ? [] : {})
72
84
 
73
- if (obj[k] !== Object(obj[k])) {
85
+ if (!isArrayOrObject(obj[k])) {
74
86
  if (this.override) {
75
87
  obj[k] = {}
76
88
  } else {
77
- throw new Error(
78
- 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
79
- )
89
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
90
+ throw new Error(
91
+ 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
92
+ )
93
+ }
94
+
95
+ return
80
96
  }
81
97
  }
82
98
 
83
99
  this._fill(a, obj[k], v, mod)
84
100
  } else {
85
101
  if (!this.override &&
86
- obj[k] === Object(obj[k]) && Object.keys(obj[k]).length) {
87
- throw new Error("Trying to redefine non-empty obj['" + k + "']")
102
+ isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
103
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
104
+ throw new Error("Trying to redefine non-empty obj['" + k + "']")
105
+ }
106
+
107
+ return
88
108
  }
89
109
 
90
110
  obj[k] = _process(v, mod)
@@ -119,10 +139,10 @@ DotObject.prototype.object = function (obj, mods) {
119
139
  Object.keys(obj).forEach(function (k) {
120
140
  var mod = mods === undefined ? null : mods[k]
121
141
  // normalize array notation.
122
- var ok = parsePath(k, self.seperator).join(self.seperator)
142
+ var ok = parsePath(k, self.separator).join(self.separator)
123
143
 
124
- if (ok.indexOf(self.seperator) !== -1) {
125
- self._fill(ok.split(self.seperator), obj, obj[k], mod)
144
+ if (ok.indexOf(self.separator) !== -1) {
145
+ self._fill(ok.split(self.separator), obj, obj[k], mod)
126
146
  delete obj[k]
127
147
  } else if (self.override) {
128
148
  obj[k] = _process(obj[k], mod)
@@ -139,8 +159,8 @@ DotObject.prototype.object = function (obj, mods) {
139
159
  * @param {Function|Array} mod optional modifier
140
160
  */
141
161
  DotObject.prototype.str = function (path, v, obj, mod) {
142
- if (path.indexOf(this.seperator) !== -1) {
143
- this._fill(path.split(this.seperator), obj, v, mod)
162
+ if (path.indexOf(this.separator) !== -1) {
163
+ this._fill(path.split(this.separator), obj, v, mod)
144
164
  } else if (!obj.hasOwnProperty(path) || this.override) {
145
165
  obj[path] = _process(v, mod)
146
166
  }
@@ -165,7 +185,7 @@ DotObject.prototype.pick = function (path, obj, remove) {
165
185
  var key
166
186
  var cp
167
187
 
168
- keys = parsePath(path, this.seperator)
188
+ keys = parsePath(path, this.separator)
169
189
  for (i = 0; i < keys.length; i++) {
170
190
  key = parseKey(keys[i], obj)
171
191
  if (obj && typeof obj === 'object' && key in obj) {
@@ -326,10 +346,6 @@ DotObject.prototype.copy = function (source, target, obj1, obj2, mods, merge) {
326
346
  return obj2
327
347
  }
328
348
 
329
- function isObject (val) {
330
- return Object.prototype.toString.call(val) === '[object Object]'
331
- }
332
-
333
349
  /**
334
350
  *
335
351
  * Set a property on an object using dot notation.
@@ -349,7 +365,7 @@ DotObject.prototype.set = function (path, val, obj, merge) {
349
365
  if (typeof val === 'undefined') {
350
366
  return obj
351
367
  }
352
- keys = parsePath(path, this.seperator)
368
+ keys = parsePath(path, this.separator)
353
369
 
354
370
  for (i = 0; i < keys.length; i++) {
355
371
  key = keys[i]
@@ -438,10 +454,18 @@ DotObject.prototype.dot = function (obj, tgt, path) {
438
454
  tgt = tgt || {}
439
455
  path = path || []
440
456
  Object.keys(obj).forEach(function (key) {
441
- if (Object(obj[key]) === obj[key] && (Object.prototype.toString.call(obj[key]) === '[object Object]') || Object.prototype.toString.call(obj[key]) === '[object Array]') {
457
+ if (
458
+ (
459
+ isArrayOrObject(obj[key]) &&
460
+ (
461
+ (isObject(obj[key]) && !isEmptyObject(obj[key])) ||
462
+ (Array.isArray(obj[key]) && (!this.keepArray && (obj[key].length !== 0)))
463
+ )
464
+ )
465
+ ) {
442
466
  return this.dot(obj[key], tgt, path.concat(key))
443
467
  } else {
444
- tgt[path.concat(key).join(this.seperator)] = obj[key]
468
+ tgt[path.concat(key).join(this.separator)] = obj[key]
445
469
  }
446
470
  }.bind(this))
447
471
  return tgt
@@ -469,15 +493,17 @@ DotObject.dot = wrap('dot')
469
493
  })
470
494
  })
471
495
 
472
- Object.defineProperty(DotObject, 'useArray', {
473
- get: function () {
474
- return dotDefault.useArray
475
- },
476
- set: function (val) {
477
- dotDefault.useArray = val
478
- }
496
+ ;['useArray', 'keepArray'].forEach(function (prop) {
497
+ Object.defineProperty(DotObject, prop, {
498
+ get: function () {
499
+ return dotDefault[prop]
500
+ },
501
+ set: function (val) {
502
+ dotDefault[prop] = val
503
+ }
504
+ })
479
505
  })
480
506
 
481
507
  DotObject._process = _process
482
508
 
483
- module.exports = DotObject;
509
+ module.exports = DotObject
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "dot-object",
3
3
  "description": "dot-object makes it possible to transform and read (JSON) objects using dot notation.",
4
- "version": "1.5.3",
4
+ "version": "1.7.1",
5
5
  "author": {
6
6
  "name": "Rob Halff",
7
7
  "email": "rob.halff@gmail.com"
@@ -30,15 +30,15 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "gulp": "^3.9.1",
33
- "gulp-beautify": "^2.0.0",
33
+ "gulp-beautify": "^2.0.1",
34
34
  "gulp-headerfooter": "^1.0.3",
35
- "gulp-mocha": "^3.0.0",
36
- "gulp-rename": "^1.2.2",
37
- "gulp-standard": "^7.0.1",
38
- "gulp-uglify": "^2.0.0",
39
- "gulp-util": "^3.0.7",
40
- "mocha": "3.x.x",
41
- "should": "10.x.x",
35
+ "gulp-mocha": "^6.0.0",
36
+ "gulp-rename": "^1.4.0",
37
+ "gulp-standard": "^12.0.0",
38
+ "gulp-uglify": "^3.0.1",
39
+ "gulp-util": "^3.0.8",
40
+ "mocha": "5.x.x",
41
+ "should": "13.x.x",
42
42
  "underscore.string": "latest"
43
43
  },
44
44
  "keywords": [
@@ -49,7 +49,7 @@
49
49
  "dot"
50
50
  ],
51
51
  "dependencies": {
52
- "commander": "^2.9.0",
53
- "glob": "^7.0.5"
52
+ "commander": "^2.19.0",
53
+ "glob": "^7.1.3"
54
54
  }
55
55
  }
package/src/dot-object.js CHANGED
@@ -30,7 +30,19 @@ function parseKey (key, val) {
30
30
  }
31
31
 
32
32
  function isIndex (k) {
33
- return /^\d+/.test(k)
33
+ return /^\d+$/.test(k)
34
+ }
35
+
36
+ function isObject (val) {
37
+ return Object.prototype.toString.call(val) === '[object Object]'
38
+ }
39
+
40
+ function isArrayOrObject (val) {
41
+ return Object(val) === val
42
+ }
43
+
44
+ function isEmptyObject (val) {
45
+ return Object.keys(val).length === 0
34
46
  }
35
47
 
36
48
  function parsePath (path, sep) {
@@ -40,17 +52,17 @@ function parsePath (path, sep) {
40
52
  return path.split(sep)
41
53
  }
42
54
 
43
- function DotObject (seperator, override, useArray) {
55
+ function DotObject (separator, override, useArray) {
44
56
  if (!(this instanceof DotObject)) {
45
- return new DotObject(seperator, override, useArray)
57
+ return new DotObject(separator, override, useArray)
46
58
  }
47
59
 
48
- if (typeof seperator === 'undefined') seperator = '.'
49
60
  if (typeof override === 'undefined') override = false
50
61
  if (typeof useArray === 'undefined') useArray = true
51
- this.seperator = seperator
62
+ this.separator = separator || '.'
52
63
  this.override = override
53
64
  this.useArray = useArray
65
+ this.keepArray = false
54
66
 
55
67
  // contains touched arrays
56
68
  this.cleanup = []
@@ -70,21 +82,29 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
70
82
  obj[k] = obj[k] ||
71
83
  (this.useArray && isIndex(a[0]) ? [] : {})
72
84
 
73
- if (obj[k] !== Object(obj[k])) {
85
+ if (!isArrayOrObject(obj[k])) {
74
86
  if (this.override) {
75
87
  obj[k] = {}
76
88
  } else {
77
- throw new Error(
78
- 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
79
- )
89
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
90
+ throw new Error(
91
+ 'Trying to redefine `' + k + '` which is a ' + typeof obj[k]
92
+ )
93
+ }
94
+
95
+ return
80
96
  }
81
97
  }
82
98
 
83
99
  this._fill(a, obj[k], v, mod)
84
100
  } else {
85
101
  if (!this.override &&
86
- obj[k] === Object(obj[k]) && Object.keys(obj[k]).length) {
87
- throw new Error("Trying to redefine non-empty obj['" + k + "']")
102
+ isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
103
+ if (!(isArrayOrObject(v) && isEmptyObject(v))) {
104
+ throw new Error("Trying to redefine non-empty obj['" + k + "']")
105
+ }
106
+
107
+ return
88
108
  }
89
109
 
90
110
  obj[k] = _process(v, mod)
@@ -119,10 +139,10 @@ DotObject.prototype.object = function (obj, mods) {
119
139
  Object.keys(obj).forEach(function (k) {
120
140
  var mod = mods === undefined ? null : mods[k]
121
141
  // normalize array notation.
122
- var ok = parsePath(k, self.seperator).join(self.seperator)
142
+ var ok = parsePath(k, self.separator).join(self.separator)
123
143
 
124
- if (ok.indexOf(self.seperator) !== -1) {
125
- self._fill(ok.split(self.seperator), obj, obj[k], mod)
144
+ if (ok.indexOf(self.separator) !== -1) {
145
+ self._fill(ok.split(self.separator), obj, obj[k], mod)
126
146
  delete obj[k]
127
147
  } else if (self.override) {
128
148
  obj[k] = _process(obj[k], mod)
@@ -139,8 +159,8 @@ DotObject.prototype.object = function (obj, mods) {
139
159
  * @param {Function|Array} mod optional modifier
140
160
  */
141
161
  DotObject.prototype.str = function (path, v, obj, mod) {
142
- if (path.indexOf(this.seperator) !== -1) {
143
- this._fill(path.split(this.seperator), obj, v, mod)
162
+ if (path.indexOf(this.separator) !== -1) {
163
+ this._fill(path.split(this.separator), obj, v, mod)
144
164
  } else if (!obj.hasOwnProperty(path) || this.override) {
145
165
  obj[path] = _process(v, mod)
146
166
  }
@@ -165,7 +185,7 @@ DotObject.prototype.pick = function (path, obj, remove) {
165
185
  var key
166
186
  var cp
167
187
 
168
- keys = parsePath(path, this.seperator)
188
+ keys = parsePath(path, this.separator)
169
189
  for (i = 0; i < keys.length; i++) {
170
190
  key = parseKey(keys[i], obj)
171
191
  if (obj && typeof obj === 'object' && key in obj) {
@@ -326,10 +346,6 @@ DotObject.prototype.copy = function (source, target, obj1, obj2, mods, merge) {
326
346
  return obj2
327
347
  }
328
348
 
329
- function isObject (val) {
330
- return Object.prototype.toString.call(val) === '[object Object]'
331
- }
332
-
333
349
  /**
334
350
  *
335
351
  * Set a property on an object using dot notation.
@@ -349,7 +365,7 @@ DotObject.prototype.set = function (path, val, obj, merge) {
349
365
  if (typeof val === 'undefined') {
350
366
  return obj
351
367
  }
352
- keys = parsePath(path, this.seperator)
368
+ keys = parsePath(path, this.separator)
353
369
 
354
370
  for (i = 0; i < keys.length; i++) {
355
371
  key = keys[i]
@@ -438,10 +454,18 @@ DotObject.prototype.dot = function (obj, tgt, path) {
438
454
  tgt = tgt || {}
439
455
  path = path || []
440
456
  Object.keys(obj).forEach(function (key) {
441
- if (Object(obj[key]) === obj[key] && (Object.prototype.toString.call(obj[key]) === '[object Object]') || Object.prototype.toString.call(obj[key]) === '[object Array]') {
457
+ if (
458
+ (
459
+ isArrayOrObject(obj[key]) &&
460
+ (
461
+ (isObject(obj[key]) && !isEmptyObject(obj[key])) ||
462
+ (Array.isArray(obj[key]) && (!this.keepArray && (obj[key].length !== 0)))
463
+ )
464
+ )
465
+ ) {
442
466
  return this.dot(obj[key], tgt, path.concat(key))
443
467
  } else {
444
- tgt[path.concat(key).join(this.seperator)] = obj[key]
468
+ tgt[path.concat(key).join(this.separator)] = obj[key]
445
469
  }
446
470
  }.bind(this))
447
471
  return tgt
@@ -469,13 +493,15 @@ DotObject.dot = wrap('dot')
469
493
  })
470
494
  })
471
495
 
472
- Object.defineProperty(DotObject, 'useArray', {
473
- get: function () {
474
- return dotDefault.useArray
475
- },
476
- set: function (val) {
477
- dotDefault.useArray = val
478
- }
496
+ ;['useArray', 'keepArray'].forEach(function (prop) {
497
+ Object.defineProperty(DotObject, prop, {
498
+ get: function () {
499
+ return dotDefault[prop]
500
+ },
501
+ set: function (val) {
502
+ dotDefault[prop] = val
503
+ }
504
+ })
479
505
  })
480
506
 
481
507
  DotObject._process = _process
package/src/footer.tpl CHANGED
@@ -2,12 +2,12 @@
2
2
 
3
3
  if (typeof define === 'function' && define.amd) {
4
4
  define(function() {
5
- return DotObject;
6
- });
5
+ return DotObject
6
+ })
7
7
  } else if (typeof module != 'undefined' && module.exports) {
8
- module.exports = DotObject;
8
+ module.exports = DotObject
9
9
  } else {
10
- global[exportName] = DotObject;
10
+ global[exportName] = DotObject
11
11
  }
12
12
 
13
- })(this, 'DotObject');
13
+ })(this, 'DotObject')
@@ -66,8 +66,8 @@ describe('Dotted Array notation', function () {
66
66
  it('multiple indexes', function () {
67
67
  var src = {
68
68
  I: [
69
- {am: [{nes: ['ted']}]},
70
- {me: 'too'}
69
+ { am: [{ nes: ['ted'] }] },
70
+ { me: 'too' }
71
71
  ]
72
72
  }
73
73
 
@@ -82,47 +82,47 @@ describe('Dotted Array notation', function () {
82
82
 
83
83
  describe('can set', function () {
84
84
  it('index at target', function () {
85
- var obj = {path: []}
85
+ var obj = { path: [] }
86
86
 
87
87
  Dot.set(v('path.0'), 'test', obj)
88
88
  Dot.set(v('path.1'), 'test2', obj)
89
89
 
90
- obj.path.should.be.an.Array
91
- obj.should.eql({path: ['test', 'test2']})
90
+ obj.path.should.be.instanceOf(Array)
91
+ obj.should.eql({ path: ['test', 'test2'] })
92
92
  })
93
93
 
94
94
  it('index and set undefined for empty indices', function () {
95
- var obj = {path: []}
95
+ var obj = { path: [] }
96
96
 
97
97
  Dot.set(v('path.0'), 'test', obj)
98
98
  Dot.set(v('path.2'), 'test2', obj)
99
99
 
100
- obj.path.should.be.an.Array
100
+ obj.path.should.be.instanceOf(Array)
101
101
 
102
102
  // array will have an undefined index.
103
103
  JSON.stringify(obj)
104
104
  .should.eql(
105
- JSON.stringify({path: ['test', undefined, 'test2']})
106
- )
105
+ JSON.stringify({ path: ['test', undefined, 'test2'] })
106
+ )
107
107
 
108
108
  // to json will converted it to null
109
109
  JSON.stringify(obj).should.eql('{"path":["test",null,"test2"]}')
110
110
  })
111
111
 
112
112
  it('index and overwrite existing values', function () {
113
- var obj = {path: ['still', 'shall', 'be', 'gone', 'here']}
113
+ var obj = { path: ['still', 'shall', 'be', 'gone', 'here'] }
114
114
 
115
115
  Dot.set(v('path.1'), 'x', obj)
116
116
  Dot.set(v('path.2'), 'xx', obj)
117
117
  Dot.set(v('path.3'), 'xxx', obj)
118
118
 
119
- obj.should.eql({path: ['still', 'x', 'xx', 'xxx', 'here']})
119
+ obj.should.eql({ path: ['still', 'x', 'xx', 'xxx', 'here'] })
120
120
  })
121
121
  })
122
122
 
123
123
  describe('can remove', function () {
124
124
  it('indexes one by one leaving traces', function () {
125
- var obj = {path: ['still', 'shall', 'really', 'be', 'gone', 'here']}
125
+ var obj = { path: ['still', 'shall', 'really', 'be', 'gone', 'here'] }
126
126
 
127
127
  Dot.remove(v('path.1'), obj)
128
128
  Dot.remove(v('path.2'), obj)
@@ -132,12 +132,12 @@ describe('Dotted Array notation', function () {
132
132
  // array will have an undefined index.
133
133
  JSON.stringify(obj)
134
134
  .should.eql(
135
- JSON.stringify({
136
- path: [
137
- 'still', undefined, undefined, undefined, undefined, 'here'
138
- ]
139
- })
140
- )
135
+ JSON.stringify({
136
+ path: [
137
+ 'still', undefined, undefined, undefined, undefined, 'here'
138
+ ]
139
+ })
140
+ )
141
141
 
142
142
  // to json will converted it to null
143
143
  JSON.stringify(obj).should.eql(
@@ -146,7 +146,7 @@ describe('Dotted Array notation', function () {
146
146
  })
147
147
 
148
148
  it('array of indexes leaving no traces', function () {
149
- var obj = {path: ['still', 'shall', 'really', 'be', 'gone', 'here']}
149
+ var obj = { path: ['still', 'shall', 'really', 'be', 'gone', 'here'] }
150
150
 
151
151
  Dot.remove([
152
152
  v('path.1'),
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "empty array",
3
+ "input": [
4
+ {
5
+ "a": []
6
+ },
7
+ {
8
+ "a.0": 1,
9
+ "a": []
10
+ },
11
+ {
12
+ "a": [],
13
+ "a.0": 2
14
+ },
15
+ {
16
+ "a.0.b": []
17
+ },
18
+ {
19
+ "b.a.0": "b",
20
+ "b.a": [],
21
+ "b.a.1": "c"
22
+ }
23
+ ],
24
+ "expected": [
25
+ {
26
+ "a": []
27
+ },
28
+ {
29
+ "a": [1]
30
+ },
31
+ {
32
+ "a": [2]
33
+ },
34
+ {
35
+ "a" : [ {"b" : [] } ]
36
+ },
37
+ {
38
+ "b" : {
39
+ "a": [ "b", "c" ]
40
+ }
41
+ }
42
+ ]
43
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "empty object",
3
+ "input": [
4
+ {
5
+ "a.b": {}
6
+ },
7
+ {
8
+ "a.b.c": 1,
9
+ "a.b": {} ,
10
+ "a.b.d": 2
11
+ }
12
+ ],
13
+ "expected": [
14
+ {
15
+ "a" : {"b" : {} }
16
+ },
17
+ {
18
+ "a" : {
19
+ "b": { "c": 1, "d": 2 }
20
+ }
21
+ }
22
+ ]
23
+ }
@@ -0,0 +1,8 @@
1
+ module.exports = [
2
+ require('./array_deep_bug'),
3
+ require('./array_deep_bug2'),
4
+ require('./empty_array'),
5
+ require('./empty_object'),
6
+ require('./object_deep_numeric_keys'),
7
+ require('./object_deep_numeric_keys2')
8
+ ]
package/test/dot-json.js CHANGED
@@ -55,6 +55,28 @@ describe('Object test:', function () {
55
55
  })
56
56
  })
57
57
 
58
+ it('Should allow keys with numbers', function () {
59
+ var row = {
60
+ 'id': 2,
61
+ '0A': 'a',
62
+ '0A9': 'b',
63
+ '0B.1AB.A34C9': 'c'
64
+ }
65
+
66
+ Dot.object(row)
67
+
68
+ row.should.eql({
69
+ 'id': 2,
70
+ '0A': 'a',
71
+ '0A9': 'b',
72
+ '0B': {
73
+ '1AB': {
74
+ 'A34C9': 'c'
75
+ }
76
+ }
77
+ })
78
+ })
79
+
58
80
  it('Should expand dotted string', function () {
59
81
  var tgt = {}
60
82
 
@@ -130,39 +152,39 @@ describe('Object test:', function () {
130
152
 
131
153
  Dot.object(row, mods)
132
154
 
133
- row.should.eql({'page': {'title': 'My Page', 'slug': 'my-page'}})
155
+ row.should.eql({ 'page': { 'title': 'My Page', 'slug': 'my-page' } })
134
156
  })
135
157
 
136
158
  it('should not process non dot value with modifier when override is false',
137
159
  function () {
138
- var row = {'title': 'my page', 'slug': 'My Page'}
160
+ var row = { 'title': 'my page', 'slug': 'My Page' }
139
161
 
140
- var mods = {'title': _s.titleize, 'slug': _s.slugify}
162
+ var mods = { 'title': _s.titleize, 'slug': _s.slugify }
141
163
 
142
164
  Dot.object(row, mods)
143
165
 
144
- row.should.eql({'title': 'my page', 'slug': 'My Page'})
166
+ row.should.eql({ 'title': 'my page', 'slug': 'My Page' })
145
167
  }
146
168
  )
147
169
 
148
170
  it('Dot.object should process multiple modifiers', function () {
149
- var row = {'page.name': ' My Page '}
171
+ var row = { 'page.name': ' My Page ' }
150
172
 
151
- var mods = {'page.name': [_s.trim, _s.underscored]}
173
+ var mods = { 'page.name': [_s.trim, _s.underscored] }
152
174
 
153
175
  Dot.object(row, mods)
154
176
 
155
- row.should.eql({'page': {'name': 'my_page'}})
177
+ row.should.eql({ 'page': { 'name': 'my_page' } })
156
178
  })
157
179
 
158
- it('Dot.object should work with a different seperator', function () {
159
- var row = {'page=>name': ' My Page '}
180
+ it('Dot.object should work with a different separator', function () {
181
+ var row = { 'page=>name': ' My Page ' }
160
182
 
161
- var mods = {'page=>name': [_s.trim, _s.underscored]}
183
+ var mods = { 'page=>name': [_s.trim, _s.underscored] }
162
184
 
163
185
  var dot = new Dot('=>', false)
164
186
  dot.object(row, mods)
165
187
 
166
- row.should.eql({'page': {'name': 'my_page'}})
188
+ row.should.eql({ 'page': { 'name': 'my_page' } })
167
189
  })
168
190
  })
package/test/dot.js CHANGED
@@ -2,10 +2,10 @@
2
2
 
3
3
  require('should')
4
4
  var Dot = require('../index')
5
+ var pkg = require('./fixtures/package.json')
5
6
 
6
- describe('dotted-key/value pairs:', function () {
7
+ describe('dot():', function () {
7
8
  var obj
8
- var expected
9
9
 
10
10
  beforeEach(function () {
11
11
  obj = {
@@ -28,8 +28,10 @@ describe('dotted-key/value pairs:', function () {
28
28
  first: new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
29
29
  }
30
30
  }
31
+ })
31
32
 
32
- expected = {
33
+ it('Should be able to convert to dotted-key/value pairs', function () {
34
+ var expected = {
33
35
  id: 'my-id',
34
36
  'nes.ted.value': true,
35
37
  'other.nested.stuff': 5,
@@ -38,14 +40,38 @@ describe('dotted-key/value pairs:', function () {
38
40
  ehrm: 123,
39
41
  'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
40
42
  }
41
- })
42
43
 
43
- it('Should be able to convert to dotted-key/value pairs', function () {
44
44
  Dot.dot(obj).should.eql(expected)
45
45
  })
46
46
 
47
47
  it('dot() should equal object()', function () {
48
- var pkg = require('./fixtures/package.json')
49
48
  Dot.object(Dot.dot(pkg)).should.eql(pkg)
50
49
  })
50
+
51
+ it('keepArray prevents arrays from being dotted', function () {
52
+ var expected = {
53
+ id: 'my-id',
54
+ 'nes.ted.value': true,
55
+ 'other.nested.stuff': 5,
56
+ 'some.array': ['A', 'B'],
57
+ ehrm: 123,
58
+ 'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
59
+ }
60
+
61
+ Dot.keepArray = true
62
+
63
+ Dot.dot(obj).should.eql(expected)
64
+
65
+ Dot.keepArray = false
66
+ })
67
+
68
+ it('Always keeps empty arrays', function () {
69
+ Dot.dot({ hello: [] }).should.eql({ 'hello': [] })
70
+ Dot.dot({ hello: { world: [] } }).should.eql({ 'hello.world': [] })
71
+ })
72
+
73
+ it('Always keeps empty objects', function () {
74
+ Dot.dot({ hello: {} }).should.eql({ 'hello': {} })
75
+ Dot.dot({ hello: { world: {} } }).should.eql({ 'hello.world': {} })
76
+ })
51
77
  })
package/test/move.js CHANGED
@@ -15,8 +15,8 @@ describe('Move test:', function () {
15
15
 
16
16
  var expected = {
17
17
  id: '527423a65e380f0000588e47',
18
- source: {id: '526dd5c6b4c4aa8770000001', port: 'github'},
19
- target: {id: '527402d6b15d1800008755cf', port: 'in'}
18
+ source: { id: '526dd5c6b4c4aa8770000001', port: 'github' },
19
+ target: { id: '527402d6b15d1800008755cf', port: 'in' }
20
20
  }
21
21
 
22
22
  Dot.move('source', 'source.id', link)
@@ -36,8 +36,8 @@ describe('Move test:', function () {
36
36
  }
37
37
 
38
38
  var expected = {
39
- source: {id: '526dd5c6b4c4aa8770000001'},
40
- target: {port: 'in'},
39
+ source: { id: '526dd5c6b4c4aa8770000001' },
40
+ target: { port: 'in' },
41
41
  out: 'github'
42
42
  }
43
43
 
@@ -56,8 +56,8 @@ describe('Move test:', function () {
56
56
  }
57
57
 
58
58
  var expected = {
59
- source: {id: 'ONE'},
60
- target: {port: 'TWO'}
59
+ source: { id: 'ONE' },
60
+ target: { port: 'TWO' }
61
61
  }
62
62
 
63
63
  function up (val) { return val.toUpperCase() }
package/test/override.js CHANGED
@@ -17,7 +17,7 @@ describe('Override test:', function () {
17
17
 
18
18
  obj.should.eql({
19
19
  'some': 'value',
20
- 'already': {'new': 'value'}
20
+ 'already': { 'new': 'value' }
21
21
  })
22
22
  })
23
23
 
@@ -34,7 +34,7 @@ describe('Override test:', function () {
34
34
 
35
35
  obj.should.eql({
36
36
  'some': 'new_value',
37
- 'already': {'new': 'value'}
37
+ 'already': { 'new': 'value' }
38
38
  })
39
39
  })
40
40
 
@@ -52,7 +52,7 @@ describe('Override test:', function () {
52
52
 
53
53
  Dot.override = true
54
54
 
55
- Dot.str('sample.dotted.bar', {baz: 'boom'}, obj)
55
+ Dot.str('sample.dotted.bar', { baz: 'boom' }, obj)
56
56
 
57
57
  Dot.override = false
58
58
 
package/test/pick.js CHANGED
@@ -36,7 +36,7 @@ describe('Pick:', function () {
36
36
 
37
37
  var val = Dot.pick('some', obj)
38
38
 
39
- ;(val === null).should.be.true
39
+ ;(val === null).should.equal(true)
40
40
  })
41
41
 
42
42
  it('Should return undefined when picking an non-existing value', function () {
@@ -46,7 +46,7 @@ describe('Pick:', function () {
46
46
 
47
47
  var val = Dot.pick('other', obj)
48
48
 
49
- ;(val === undefined).should.be.true
49
+ ;(val === undefined).should.equal(true)
50
50
  })
51
51
 
52
52
  it('Should return undefined when picking an non-existing dotted value',
@@ -57,7 +57,7 @@ describe('Pick:', function () {
57
57
 
58
58
  var val = Dot.pick('some.other', obj)
59
59
 
60
- ;(val === undefined).should.be.true
60
+ ;(val === undefined).should.equal(true)
61
61
  }
62
62
  )
63
63
 
@@ -73,6 +73,6 @@ describe('Pick:', function () {
73
73
  objIns.should.have.property('some')
74
74
 
75
75
  var val = Dot.pick('some.other', objIns)
76
- val.should.be.a.String
76
+ val.should.be.instanceOf(String)
77
77
  })
78
78
  })
package/test/test_data.js CHANGED
@@ -3,12 +3,12 @@
3
3
  require('should')
4
4
  var Dot = require('../index')
5
5
 
6
- var testData = [
7
- require('./data/array_deep_bug'),
8
- require('./data/array_deep_bug2'),
9
- require('./data/object_deep_numeric_keys'),
10
- require('./data/object_deep_numeric_keys2')
11
- ]
6
+ var testData = require('./data')
7
+
8
+ function singleTest (dot, input, expected) {
9
+ dot.object(input)
10
+ JSON.stringify(input).should.eql(JSON.stringify(expected))
11
+ }
12
12
 
13
13
  describe('Test Data:', function () {
14
14
  var dot = new Dot()
@@ -19,8 +19,20 @@ describe('Test Data:', function () {
19
19
  dot[name] = test.options[name]
20
20
  })
21
21
  }
22
- dot.object(test.input)
23
- JSON.stringify(test.input).should.eql(JSON.stringify(test.expected))
22
+
23
+ if (Array.isArray(test.input)) {
24
+ if (
25
+ !Array.isArray(test.expected) ||
26
+ test.input.length !== test.expected.length
27
+ ) {
28
+ throw Error('Input and Expected tests length must be the same')
29
+ }
30
+ test.expected.forEach((expected, i) => {
31
+ singleTest(dot, test.input[i], expected)
32
+ })
33
+ } else {
34
+ singleTest(dot, test.input, test.expected)
35
+ }
24
36
  })
25
37
  }
26
38
 
package/test/transfer.js CHANGED
@@ -19,7 +19,7 @@ describe('Transfer:', function () {
19
19
  name: 'Brandon'
20
20
  }
21
21
 
22
- var srcExpected = {name: 'John', stuff: {}}
22
+ var srcExpected = { name: 'John', stuff: {} }
23
23
 
24
24
  var tgtExpected = {
25
25
  name: 'Brandon',
@@ -59,7 +59,7 @@ describe('Transfer:', function () {
59
59
  name: 'Brandon'
60
60
  }
61
61
 
62
- var srcExpected = {name: 'John', stuff: {}}
62
+ var srcExpected = { name: 'John', stuff: {} }
63
63
 
64
64
  var tgtExpected = {
65
65
  name: 'Brandon',