dot-object 2.1.0 → 2.1.4
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.
- package/CHANGELOG.md +12 -0
- package/README.md +27 -0
- package/bower.json +1 -1
- package/dist/dot-object.js +75 -52
- package/dist/dot-object.min.js +1 -1
- package/index.js +85 -58
- package/package.json +1 -1
- package/src/dot-object.js +85 -58
- package/test/array_notation.js +6 -0
- package/test/dot-json.js +29 -0
- package/test/dot.js +49 -4
- package/test/str.js +29 -0
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# ChangeLog
|
2
2
|
|
3
|
+
## 2020-09-10 Version 2.1.4
|
4
|
+
* [[`94b9eb8a2d`](https://github.com/rhalff/dot-object/commit/94b9eb8a2d)] - Fix parsing of array paths for non standard separators (Fixed by boidolr #58)
|
5
|
+
|
6
|
+
## 2020-02-16 Version 2.1.3
|
7
|
+
* fix possible pollution of prototype for paths containing __proto__
|
8
|
+
|
9
|
+
## 2019-11-02 Version 2.1.1
|
10
|
+
* fix undefined key with root level array.
|
11
|
+
|
12
|
+
## 2019-11-02 Version 2.1.1
|
13
|
+
* Wrong array conversion when brackets are used (Reported by vladshcherbin #27)
|
14
|
+
|
3
15
|
## 2019-11-02 Version 2.1.0
|
4
16
|
* fix delete function not being wrapped. (Reported by murphyke #40)
|
5
17
|
|
package/README.md
CHANGED
@@ -359,6 +359,33 @@ Result:
|
|
359
359
|
}
|
360
360
|
```
|
361
361
|
|
362
|
+
### Keep array
|
363
|
+
|
364
|
+
Set keepArray to true.
|
365
|
+
|
366
|
+
```javascript
|
367
|
+
var dot = require('dot-object');
|
368
|
+
|
369
|
+
var obj = {
|
370
|
+
id: 'my-id',
|
371
|
+
other: [1, 2, 3],
|
372
|
+
some: { array: ['A', 'B'] }
|
373
|
+
};
|
374
|
+
|
375
|
+
dot.keepArray = true;
|
376
|
+
var tgt = dot.dot(obj);
|
377
|
+
|
378
|
+
console.log(tgt);
|
379
|
+
```
|
380
|
+
Result:
|
381
|
+
```json
|
382
|
+
{
|
383
|
+
"id": "my-id",
|
384
|
+
"other": [1, 2, 3],
|
385
|
+
"some.array": ["A", "B"]
|
386
|
+
}
|
387
|
+
```
|
388
|
+
|
362
389
|
## Using a different separator
|
363
390
|
|
364
391
|
If you do not like dot notation, you are free to specify a different separator.
|
package/bower.json
CHANGED
package/dist/dot-object.js
CHANGED
@@ -46,11 +46,25 @@
|
|
46
46
|
return Object.keys(val).length === 0
|
47
47
|
}
|
48
48
|
|
49
|
+
var blacklist = ['__proto__', 'prototype', 'constructor']
|
50
|
+
var blacklistFilter = function(part) {
|
51
|
+
return blacklist.indexOf(part) === -1
|
52
|
+
}
|
53
|
+
|
49
54
|
function parsePath(path, sep) {
|
50
55
|
if (path.indexOf('[') >= 0) {
|
51
|
-
path = path.replace(/\[/g,
|
56
|
+
path = path.replace(/\[/g, sep).replace(/]/g, '')
|
57
|
+
}
|
58
|
+
|
59
|
+
var parts = path.split(sep)
|
60
|
+
|
61
|
+
var check = parts.filter(blacklistFilter)
|
62
|
+
|
63
|
+
if (check.length !== parts.length) {
|
64
|
+
throw Error('Refusing to update blacklisted property ' + path)
|
52
65
|
}
|
53
|
-
|
66
|
+
|
67
|
+
return parts
|
54
68
|
}
|
55
69
|
|
56
70
|
var hasOwnProperty = Object.prototype.hasOwnProperty
|
@@ -85,8 +99,7 @@
|
|
85
99
|
var k = a.shift()
|
86
100
|
|
87
101
|
if (a.length > 0) {
|
88
|
-
obj[k] = obj[k] ||
|
89
|
-
(this.useArray && isIndex(a[0]) ? [] : {})
|
102
|
+
obj[k] = obj[k] || (this.useArray && isIndex(a[0]) ? [] : {})
|
90
103
|
|
91
104
|
if (!isArrayOrObject(obj[k])) {
|
92
105
|
if (this.override) {
|
@@ -104,8 +117,7 @@
|
|
104
117
|
|
105
118
|
this._fill(a, obj[k], v, mod)
|
106
119
|
} else {
|
107
|
-
if (!this.override &&
|
108
|
-
isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
|
120
|
+
if (!this.override && isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
|
109
121
|
if (!(isArrayOrObject(v) && isEmptyObject(v))) {
|
110
122
|
throw new Error("Trying to redefine non-empty obj['" + k + "']")
|
111
123
|
}
|
@@ -165,8 +177,10 @@
|
|
165
177
|
* @param {Function|Array} mod optional modifier
|
166
178
|
*/
|
167
179
|
DotObject.prototype.str = function(path, v, obj, mod) {
|
180
|
+
var ok = parsePath(path, this.separator).join(this.separator)
|
181
|
+
|
168
182
|
if (path.indexOf(this.separator) !== -1) {
|
169
|
-
this._fill(
|
183
|
+
this._fill(ok.split(this.separator), obj, v, mod)
|
170
184
|
} else {
|
171
185
|
obj[path] = _process(v, mod)
|
172
186
|
}
|
@@ -195,7 +209,7 @@
|
|
195
209
|
for (i = 0; i < keys.length; i++) {
|
196
210
|
key = parseKey(keys[i], obj)
|
197
211
|
if (obj && typeof obj === 'object' && key in obj) {
|
198
|
-
if (i ===
|
212
|
+
if (i === keys.length - 1) {
|
199
213
|
if (remove) {
|
200
214
|
val = obj[key]
|
201
215
|
if (reindexArray && Array.isArray(obj)) {
|
@@ -340,13 +354,21 @@
|
|
340
354
|
* @param {Function|Array} mods
|
341
355
|
* @param {Boolean} merge
|
342
356
|
*/
|
343
|
-
DotObject.prototype.transfer = function(
|
357
|
+
DotObject.prototype.transfer = function(
|
358
|
+
source,
|
359
|
+
target,
|
360
|
+
obj1,
|
361
|
+
obj2,
|
362
|
+
mods,
|
363
|
+
merge
|
364
|
+
) {
|
344
365
|
if (typeof mods === 'function' || Array.isArray(mods)) {
|
345
|
-
this.set(
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
366
|
+
this.set(
|
367
|
+
target,
|
368
|
+
_process(this.pick(source, obj1, true), mods),
|
369
|
+
obj2,
|
370
|
+
merge
|
371
|
+
)
|
350
372
|
} else {
|
351
373
|
merge = mods
|
352
374
|
this.set(target, this.pick(source, obj1, true), obj2, merge)
|
@@ -371,16 +393,16 @@
|
|
371
393
|
*/
|
372
394
|
DotObject.prototype.copy = function(source, target, obj1, obj2, mods, merge) {
|
373
395
|
if (typeof mods === 'function' || Array.isArray(mods)) {
|
374
|
-
this.set(
|
396
|
+
this.set(
|
397
|
+
target,
|
375
398
|
_process(
|
376
399
|
// clone what is picked
|
377
|
-
JSON.parse(
|
378
|
-
JSON.stringify(
|
379
|
-
this.pick(source, obj1, false)
|
380
|
-
)
|
381
|
-
),
|
400
|
+
JSON.parse(JSON.stringify(this.pick(source, obj1, false))),
|
382
401
|
mods
|
383
|
-
),
|
402
|
+
),
|
403
|
+
obj2,
|
404
|
+
merge
|
405
|
+
)
|
384
406
|
} else {
|
385
407
|
merge = mods
|
386
408
|
this.set(target, this.pick(source, obj1, false), obj2, merge)
|
@@ -412,7 +434,7 @@
|
|
412
434
|
|
413
435
|
for (i = 0; i < keys.length; i++) {
|
414
436
|
key = keys[i]
|
415
|
-
if (i ===
|
437
|
+
if (i === keys.length - 1) {
|
416
438
|
if (merge && isObject(val) && isObject(obj[key])) {
|
417
439
|
for (k in val) {
|
418
440
|
if (hasOwnProperty.call(val, k)) {
|
@@ -470,9 +492,11 @@
|
|
470
492
|
DotObject.prototype.transform = function(recipe, obj, tgt) {
|
471
493
|
obj = obj || {}
|
472
494
|
tgt = tgt || {}
|
473
|
-
Object.keys(recipe).forEach(
|
474
|
-
|
475
|
-
|
495
|
+
Object.keys(recipe).forEach(
|
496
|
+
function(key) {
|
497
|
+
this.set(recipe[key], this.pick(key, obj), tgt)
|
498
|
+
}.bind(this)
|
499
|
+
)
|
476
500
|
return tgt
|
477
501
|
}
|
478
502
|
|
@@ -498,30 +522,33 @@
|
|
498
522
|
path = path || []
|
499
523
|
var isArray = Array.isArray(obj)
|
500
524
|
|
501
|
-
Object.keys(obj).forEach(
|
502
|
-
|
503
|
-
|
504
|
-
(
|
525
|
+
Object.keys(obj).forEach(
|
526
|
+
function(key) {
|
527
|
+
var index = isArray && this.useBrackets ? '[' + key + ']' : key
|
528
|
+
if (
|
505
529
|
isArrayOrObject(obj[key]) &&
|
506
|
-
(
|
507
|
-
(
|
508
|
-
|
509
|
-
)
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key]
|
530
|
+
((isObject(obj[key]) && !isEmptyObject(obj[key])) ||
|
531
|
+
(Array.isArray(obj[key]) && !this.keepArray && obj[key].length !== 0))
|
532
|
+
) {
|
533
|
+
if (isArray && this.useBrackets) {
|
534
|
+
var previousKey = path[path.length - 1] || ''
|
535
|
+
return this.dot(
|
536
|
+
obj[key],
|
537
|
+
tgt,
|
538
|
+
path.slice(0, -1).concat(previousKey + index)
|
539
|
+
)
|
540
|
+
} else {
|
541
|
+
return this.dot(obj[key], tgt, path.concat(index))
|
542
|
+
}
|
520
543
|
} else {
|
521
|
-
|
544
|
+
if (isArray && this.useBrackets) {
|
545
|
+
tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key]
|
546
|
+
} else {
|
547
|
+
tgt[path.concat(index).join(this.separator)] = obj[key]
|
548
|
+
}
|
522
549
|
}
|
523
|
-
}
|
524
|
-
|
550
|
+
}.bind(this)
|
551
|
+
)
|
525
552
|
return tgt
|
526
553
|
}
|
527
554
|
|
@@ -535,9 +562,7 @@
|
|
535
562
|
DotObject.set = wrap('set')
|
536
563
|
DotObject.delete = wrap('delete')
|
537
564
|
DotObject.del = DotObject.remove = wrap('remove')
|
538
|
-
DotObject.dot = wrap('dot')
|
539
|
-
|
540
|
-
;
|
565
|
+
DotObject.dot = wrap('dot');
|
541
566
|
['override', 'overwrite'].forEach(function(prop) {
|
542
567
|
Object.defineProperty(DotObject, prop, {
|
543
568
|
get: function() {
|
@@ -547,9 +572,7 @@
|
|
547
572
|
dotDefault.override = !!val
|
548
573
|
}
|
549
574
|
})
|
550
|
-
})
|
551
|
-
|
552
|
-
;
|
575
|
+
});
|
553
576
|
['useArray', 'keepArray', 'useBrackets'].forEach(function(prop) {
|
554
577
|
Object.defineProperty(DotObject, prop, {
|
555
578
|
get: function() {
|
package/dist/dot-object.min.js
CHANGED
@@ -1 +1 @@
|
|
1
|
-
!function(t){"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
|
1
|
+
!function(t){"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 p(t){return"[object Object]"===Object.prototype.toString.call(t)}function a(t){return Object(t)===t}function c(t){return 0===Object.keys(t).length}function i(t){return-1===r.indexOf(t)}var r=["__proto__","prototype","constructor"];function u(t,r){0<=t.indexOf("[")&&(t=t.replace(/\[/g,r).replace(/]/g,""));var e=t.split(r);if(e.filter(i).length!==e.length)throw Error("Refusing to update blacklisted property "+t);return e}var f=Object.prototype.hasOwnProperty;function n(t,r,e,i){if(!(this instanceof n))return new n(t,r,e,i);void 0===r&&(r=!1),void 0===e&&(e=!0),void 0===i&&(i=!0),this.separator=t||".",this.override=r,this.useArray=e,this.useBrackets=i,this.keepArray=!1,this.cleanup=[]}var e=new n(".",!1,!0,!0);function o(t){return function(){return e[t].apply(e,arguments)}}n.prototype._fill=function(t,r,e,i){var n=t.shift();if(0<t.length){if(r[n]=r[n]||(this.useArray&&function(t){return/^\d+$/.test(t)}(t[0])?[]:{}),!a(r[n])){if(!this.override){if(!a(e)||!c(e))throw new Error("Trying to redefine `"+n+"` which is a "+typeof r[n]);return}r[n]={}}this._fill(t,r[n],e,i)}else{if(!this.override&&a(r[n])&&!c(r[n])){if(!a(e)||!c(e))throw new Error("Trying to redefine non-empty obj['"+n+"']");return}r[n]=s(e,i)}},n.prototype.object=function(i,n){var o=this;return Object.keys(i).forEach(function(t){var r=void 0===n?null:n[t],e=u(t,o.separator).join(o.separator);-1!==e.indexOf(o.separator)?(o._fill(e.split(o.separator),i,i[t],r),delete i[t]):i[t]=s(i[t],r)}),i},n.prototype.str=function(t,r,e,i){var n=u(t,this.separator).join(this.separator);return-1!==t.indexOf(this.separator)?this._fill(n.split(this.separator),e,r,i):e[t]=s(r,i),e},n.prototype.pick=function(t,r,e,i){var n,o,s,a,c,p,f;for(o=u(t,this.separator),n=0;n<o.length;n++){if(p=o[n],f=r,a="-"===p[0]&&Array.isArray(f)&&/^-\d+$/.test(p)?f.length+parseInt(p,10):p,!(r&&"object"==typeof r&&a in r))return;if(n===o.length-1)return e?(s=r[a],i&&Array.isArray(r)?r.splice(a,1):delete r[a],Array.isArray(r)&&(c=o.slice(0,-1).join("."),-1===this.cleanup.indexOf(c)&&this.cleanup.push(c)),s):r[a];r=r[a]}return e&&Array.isArray(r)&&(r=r.filter(function(t){return void 0!==t})),r},n.prototype.delete=function(t,r){return this.remove(t,r,!0)},n.prototype.remove=function(t,r,e){var i;if(this.cleanup=[],Array.isArray(t)){for(i=0;i<t.length;i++)this.pick(t[i],r,!0,e);return e||this._cleanup(r),r}return this.pick(t,r,!0,e)},n.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=[]}},n.prototype.del=n.prototype.remove,n.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},n.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},n.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},n.prototype.set=function(t,r,e,i){var n,o,s,a;if(void 0===r)return e;for(s=u(t,this.separator),n=0;n<s.length;n++){if(a=s[n],n===s.length-1)if(i&&p(r)&&p(e[a]))for(o in r)f.call(r,o)&&(e[a][o]=r[o]);else if(i&&Array.isArray(e[a])&&Array.isArray(r))for(var c=0;c<r.length;c++)e[s[n]].push(r[c]);else e[a]=r;else f.call(e,a)&&(p(e[a])||Array.isArray(e[a]))||(/^\d+$/.test(s[n+1])?e[a]=[]:e[a]={});e=e[a]}return e},n.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},n.prototype.dot=function(i,n,o){n=n||{},o=o||[];var s=Array.isArray(i);return Object.keys(i).forEach(function(t){var r=s&&this.useBrackets?"["+t+"]":t;if(a(i[t])&&(p(i[t])&&!c(i[t])||Array.isArray(i[t])&&!this.keepArray&&0!==i[t].length)){if(s&&this.useBrackets){var e=o[o.length-1]||"";return this.dot(i[t],n,o.slice(0,-1).concat(e+r))}return this.dot(i[t],n,o.concat(r))}s&&this.useBrackets?n[o.join(this.separator).concat("["+t+"]")]=i[t]:n[o.concat(r).join(this.separator)]=i[t]}.bind(this)),n},n.pick=o("pick"),n.move=o("move"),n.transfer=o("transfer"),n.transform=o("transform"),n.copy=o("copy"),n.object=o("object"),n.str=o("str"),n.set=o("set"),n.delete=o("delete"),n.del=n.remove=o("remove"),n.dot=o("dot"),["override","overwrite"].forEach(function(t){Object.defineProperty(n,t,{get:function(){return e.override},set:function(t){e.override=!!t}})}),["useArray","keepArray","useBrackets"].forEach(function(r){Object.defineProperty(n,r,{get:function(){return e[r]},set:function(t){e[r]=t}})}),n._process=s,"function"==typeof define&&define.amd?define(function(){return n}):"undefined"!=typeof module&&module.exports?module.exports=n:t.DotObject=n}(this);
|
package/index.js
CHANGED
@@ -45,11 +45,23 @@ function isEmptyObject (val) {
|
|
45
45
|
return Object.keys(val).length === 0
|
46
46
|
}
|
47
47
|
|
48
|
+
var blacklist = ['__proto__', 'prototype', 'constructor']
|
49
|
+
var blacklistFilter = function (part) { return blacklist.indexOf(part) === -1 }
|
50
|
+
|
48
51
|
function parsePath (path, sep) {
|
49
52
|
if (path.indexOf('[') >= 0) {
|
50
|
-
path = path.replace(/\[/g,
|
53
|
+
path = path.replace(/\[/g, sep).replace(/]/g, '')
|
54
|
+
}
|
55
|
+
|
56
|
+
var parts = path.split(sep)
|
57
|
+
|
58
|
+
var check = parts.filter(blacklistFilter)
|
59
|
+
|
60
|
+
if (check.length !== parts.length) {
|
61
|
+
throw Error('Refusing to update blacklisted property ' + path)
|
51
62
|
}
|
52
|
-
|
63
|
+
|
64
|
+
return parts
|
53
65
|
}
|
54
66
|
|
55
67
|
var hasOwnProperty = Object.prototype.hasOwnProperty
|
@@ -83,8 +95,7 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
|
|
83
95
|
var k = a.shift()
|
84
96
|
|
85
97
|
if (a.length > 0) {
|
86
|
-
obj[k] = obj[k] ||
|
87
|
-
(this.useArray && isIndex(a[0]) ? [] : {})
|
98
|
+
obj[k] = obj[k] || (this.useArray && isIndex(a[0]) ? [] : {})
|
88
99
|
|
89
100
|
if (!isArrayOrObject(obj[k])) {
|
90
101
|
if (this.override) {
|
@@ -102,8 +113,7 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
|
|
102
113
|
|
103
114
|
this._fill(a, obj[k], v, mod)
|
104
115
|
} else {
|
105
|
-
if (!this.override &&
|
106
|
-
isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
|
116
|
+
if (!this.override && isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
|
107
117
|
if (!(isArrayOrObject(v) && isEmptyObject(v))) {
|
108
118
|
throw new Error("Trying to redefine non-empty obj['" + k + "']")
|
109
119
|
}
|
@@ -163,8 +173,10 @@ DotObject.prototype.object = function (obj, mods) {
|
|
163
173
|
* @param {Function|Array} mod optional modifier
|
164
174
|
*/
|
165
175
|
DotObject.prototype.str = function (path, v, obj, mod) {
|
176
|
+
var ok = parsePath(path, this.separator).join(this.separator)
|
177
|
+
|
166
178
|
if (path.indexOf(this.separator) !== -1) {
|
167
|
-
this._fill(
|
179
|
+
this._fill(ok.split(this.separator), obj, v, mod)
|
168
180
|
} else {
|
169
181
|
obj[path] = _process(v, mod)
|
170
182
|
}
|
@@ -193,7 +205,7 @@ DotObject.prototype.pick = function (path, obj, remove, reindexArray) {
|
|
193
205
|
for (i = 0; i < keys.length; i++) {
|
194
206
|
key = parseKey(keys[i], obj)
|
195
207
|
if (obj && typeof obj === 'object' && key in obj) {
|
196
|
-
if (i ===
|
208
|
+
if (i === keys.length - 1) {
|
197
209
|
if (remove) {
|
198
210
|
val = obj[key]
|
199
211
|
if (reindexArray && Array.isArray(obj)) {
|
@@ -219,7 +231,9 @@ DotObject.prototype.pick = function (path, obj, remove, reindexArray) {
|
|
219
231
|
}
|
220
232
|
}
|
221
233
|
if (remove && Array.isArray(obj)) {
|
222
|
-
obj = obj.filter(function (n) {
|
234
|
+
obj = obj.filter(function (n) {
|
235
|
+
return n !== undefined
|
236
|
+
})
|
223
237
|
}
|
224
238
|
return obj
|
225
239
|
}
|
@@ -277,7 +291,9 @@ DotObject.prototype._cleanup = function (obj) {
|
|
277
291
|
keys = this.cleanup[i].split('.')
|
278
292
|
root = keys.splice(0, -1).join('.')
|
279
293
|
ret = root ? this.pick(root, obj) : obj
|
280
|
-
ret = ret[keys[0]].filter(function (v) {
|
294
|
+
ret = ret[keys[0]].filter(function (v) {
|
295
|
+
return v !== undefined
|
296
|
+
})
|
281
297
|
this.set(this.cleanup[i], ret, obj)
|
282
298
|
}
|
283
299
|
this.cleanup = []
|
@@ -334,13 +350,21 @@ DotObject.prototype.move = function (source, target, obj, mods, merge) {
|
|
334
350
|
* @param {Function|Array} mods
|
335
351
|
* @param {Boolean} merge
|
336
352
|
*/
|
337
|
-
DotObject.prototype.transfer = function (
|
353
|
+
DotObject.prototype.transfer = function (
|
354
|
+
source,
|
355
|
+
target,
|
356
|
+
obj1,
|
357
|
+
obj2,
|
358
|
+
mods,
|
359
|
+
merge
|
360
|
+
) {
|
338
361
|
if (typeof mods === 'function' || Array.isArray(mods)) {
|
339
|
-
this.set(
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
362
|
+
this.set(
|
363
|
+
target,
|
364
|
+
_process(this.pick(source, obj1, true), mods),
|
365
|
+
obj2,
|
366
|
+
merge
|
367
|
+
)
|
344
368
|
} else {
|
345
369
|
merge = mods
|
346
370
|
this.set(target, this.pick(source, obj1, true), obj2, merge)
|
@@ -365,16 +389,16 @@ DotObject.prototype.transfer = function (source, target, obj1, obj2, mods, merge
|
|
365
389
|
*/
|
366
390
|
DotObject.prototype.copy = function (source, target, obj1, obj2, mods, merge) {
|
367
391
|
if (typeof mods === 'function' || Array.isArray(mods)) {
|
368
|
-
this.set(
|
392
|
+
this.set(
|
393
|
+
target,
|
369
394
|
_process(
|
370
395
|
// clone what is picked
|
371
|
-
JSON.parse(
|
372
|
-
JSON.stringify(
|
373
|
-
this.pick(source, obj1, false)
|
374
|
-
)
|
375
|
-
),
|
396
|
+
JSON.parse(JSON.stringify(this.pick(source, obj1, false))),
|
376
397
|
mods
|
377
|
-
),
|
398
|
+
),
|
399
|
+
obj2,
|
400
|
+
merge
|
401
|
+
)
|
378
402
|
} else {
|
379
403
|
merge = mods
|
380
404
|
this.set(target, this.pick(source, obj1, false), obj2, merge)
|
@@ -406,7 +430,7 @@ DotObject.prototype.set = function (path, val, obj, merge) {
|
|
406
430
|
|
407
431
|
for (i = 0; i < keys.length; i++) {
|
408
432
|
key = keys[i]
|
409
|
-
if (i ===
|
433
|
+
if (i === keys.length - 1) {
|
410
434
|
if (merge && isObject(val) && isObject(obj[key])) {
|
411
435
|
for (k in val) {
|
412
436
|
if (hasOwnProperty.call(val, k)) {
|
@@ -445,14 +469,14 @@ DotObject.prototype.set = function (path, val, obj, merge) {
|
|
445
469
|
*
|
446
470
|
* var obj = {
|
447
471
|
* "id": 1,
|
448
|
-
|
449
|
-
|
450
|
-
|
472
|
+
* "some": {
|
473
|
+
* "thing": "else"
|
474
|
+
* }
|
451
475
|
* }
|
452
476
|
*
|
453
477
|
* var transform = {
|
454
478
|
* "id": "nr",
|
455
|
-
|
479
|
+
* "some.thing": "name"
|
456
480
|
* }
|
457
481
|
*
|
458
482
|
* var tgt = dot.transform(transform, obj)
|
@@ -464,9 +488,11 @@ DotObject.prototype.set = function (path, val, obj, merge) {
|
|
464
488
|
DotObject.prototype.transform = function (recipe, obj, tgt) {
|
465
489
|
obj = obj || {}
|
466
490
|
tgt = tgt || {}
|
467
|
-
Object.keys(recipe).forEach(
|
468
|
-
|
469
|
-
|
491
|
+
Object.keys(recipe).forEach(
|
492
|
+
function (key) {
|
493
|
+
this.set(recipe[key], this.pick(key, obj), tgt)
|
494
|
+
}.bind(this)
|
495
|
+
)
|
470
496
|
return tgt
|
471
497
|
}
|
472
498
|
|
@@ -492,30 +518,33 @@ DotObject.prototype.dot = function (obj, tgt, path) {
|
|
492
518
|
path = path || []
|
493
519
|
var isArray = Array.isArray(obj)
|
494
520
|
|
495
|
-
Object.keys(obj).forEach(
|
496
|
-
|
497
|
-
|
498
|
-
(
|
521
|
+
Object.keys(obj).forEach(
|
522
|
+
function (key) {
|
523
|
+
var index = isArray && this.useBrackets ? '[' + key + ']' : key
|
524
|
+
if (
|
499
525
|
isArrayOrObject(obj[key]) &&
|
500
|
-
(
|
501
|
-
(
|
502
|
-
|
503
|
-
)
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key]
|
526
|
+
((isObject(obj[key]) && !isEmptyObject(obj[key])) ||
|
527
|
+
(Array.isArray(obj[key]) && !this.keepArray && obj[key].length !== 0))
|
528
|
+
) {
|
529
|
+
if (isArray && this.useBrackets) {
|
530
|
+
var previousKey = path[path.length - 1] || ''
|
531
|
+
return this.dot(
|
532
|
+
obj[key],
|
533
|
+
tgt,
|
534
|
+
path.slice(0, -1).concat(previousKey + index)
|
535
|
+
)
|
536
|
+
} else {
|
537
|
+
return this.dot(obj[key], tgt, path.concat(index))
|
538
|
+
}
|
514
539
|
} else {
|
515
|
-
|
540
|
+
if (isArray && this.useBrackets) {
|
541
|
+
tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key]
|
542
|
+
} else {
|
543
|
+
tgt[path.concat(index).join(this.separator)] = obj[key]
|
544
|
+
}
|
516
545
|
}
|
517
|
-
}
|
518
|
-
|
546
|
+
}.bind(this)
|
547
|
+
)
|
519
548
|
return tgt
|
520
549
|
}
|
521
550
|
|
@@ -529,9 +558,8 @@ DotObject.str = wrap('str')
|
|
529
558
|
DotObject.set = wrap('set')
|
530
559
|
DotObject.delete = wrap('delete')
|
531
560
|
DotObject.del = DotObject.remove = wrap('remove')
|
532
|
-
DotObject.dot = wrap('dot')
|
533
|
-
|
534
|
-
;['override', 'overwrite'].forEach(function (prop) {
|
561
|
+
DotObject.dot = wrap('dot');
|
562
|
+
['override', 'overwrite'].forEach(function (prop) {
|
535
563
|
Object.defineProperty(DotObject, prop, {
|
536
564
|
get: function () {
|
537
565
|
return dotDefault.override
|
@@ -540,9 +568,8 @@ DotObject.dot = wrap('dot')
|
|
540
568
|
dotDefault.override = !!val
|
541
569
|
}
|
542
570
|
})
|
543
|
-
})
|
544
|
-
|
545
|
-
;['useArray', 'keepArray', 'useBrackets'].forEach(function (prop) {
|
571
|
+
});
|
572
|
+
['useArray', 'keepArray', 'useBrackets'].forEach(function (prop) {
|
546
573
|
Object.defineProperty(DotObject, prop, {
|
547
574
|
get: function () {
|
548
575
|
return dotDefault[prop]
|
package/package.json
CHANGED
package/src/dot-object.js
CHANGED
@@ -45,11 +45,23 @@ function isEmptyObject (val) {
|
|
45
45
|
return Object.keys(val).length === 0
|
46
46
|
}
|
47
47
|
|
48
|
+
var blacklist = ['__proto__', 'prototype', 'constructor']
|
49
|
+
var blacklistFilter = function (part) { return blacklist.indexOf(part) === -1 }
|
50
|
+
|
48
51
|
function parsePath (path, sep) {
|
49
52
|
if (path.indexOf('[') >= 0) {
|
50
|
-
path = path.replace(/\[/g,
|
53
|
+
path = path.replace(/\[/g, sep).replace(/]/g, '')
|
54
|
+
}
|
55
|
+
|
56
|
+
var parts = path.split(sep)
|
57
|
+
|
58
|
+
var check = parts.filter(blacklistFilter)
|
59
|
+
|
60
|
+
if (check.length !== parts.length) {
|
61
|
+
throw Error('Refusing to update blacklisted property ' + path)
|
51
62
|
}
|
52
|
-
|
63
|
+
|
64
|
+
return parts
|
53
65
|
}
|
54
66
|
|
55
67
|
var hasOwnProperty = Object.prototype.hasOwnProperty
|
@@ -83,8 +95,7 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
|
|
83
95
|
var k = a.shift()
|
84
96
|
|
85
97
|
if (a.length > 0) {
|
86
|
-
obj[k] = obj[k] ||
|
87
|
-
(this.useArray && isIndex(a[0]) ? [] : {})
|
98
|
+
obj[k] = obj[k] || (this.useArray && isIndex(a[0]) ? [] : {})
|
88
99
|
|
89
100
|
if (!isArrayOrObject(obj[k])) {
|
90
101
|
if (this.override) {
|
@@ -102,8 +113,7 @@ DotObject.prototype._fill = function (a, obj, v, mod) {
|
|
102
113
|
|
103
114
|
this._fill(a, obj[k], v, mod)
|
104
115
|
} else {
|
105
|
-
if (!this.override &&
|
106
|
-
isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
|
116
|
+
if (!this.override && isArrayOrObject(obj[k]) && !isEmptyObject(obj[k])) {
|
107
117
|
if (!(isArrayOrObject(v) && isEmptyObject(v))) {
|
108
118
|
throw new Error("Trying to redefine non-empty obj['" + k + "']")
|
109
119
|
}
|
@@ -163,8 +173,10 @@ DotObject.prototype.object = function (obj, mods) {
|
|
163
173
|
* @param {Function|Array} mod optional modifier
|
164
174
|
*/
|
165
175
|
DotObject.prototype.str = function (path, v, obj, mod) {
|
176
|
+
var ok = parsePath(path, this.separator).join(this.separator)
|
177
|
+
|
166
178
|
if (path.indexOf(this.separator) !== -1) {
|
167
|
-
this._fill(
|
179
|
+
this._fill(ok.split(this.separator), obj, v, mod)
|
168
180
|
} else {
|
169
181
|
obj[path] = _process(v, mod)
|
170
182
|
}
|
@@ -193,7 +205,7 @@ DotObject.prototype.pick = function (path, obj, remove, reindexArray) {
|
|
193
205
|
for (i = 0; i < keys.length; i++) {
|
194
206
|
key = parseKey(keys[i], obj)
|
195
207
|
if (obj && typeof obj === 'object' && key in obj) {
|
196
|
-
if (i ===
|
208
|
+
if (i === keys.length - 1) {
|
197
209
|
if (remove) {
|
198
210
|
val = obj[key]
|
199
211
|
if (reindexArray && Array.isArray(obj)) {
|
@@ -219,7 +231,9 @@ DotObject.prototype.pick = function (path, obj, remove, reindexArray) {
|
|
219
231
|
}
|
220
232
|
}
|
221
233
|
if (remove && Array.isArray(obj)) {
|
222
|
-
obj = obj.filter(function (n) {
|
234
|
+
obj = obj.filter(function (n) {
|
235
|
+
return n !== undefined
|
236
|
+
})
|
223
237
|
}
|
224
238
|
return obj
|
225
239
|
}
|
@@ -277,7 +291,9 @@ DotObject.prototype._cleanup = function (obj) {
|
|
277
291
|
keys = this.cleanup[i].split('.')
|
278
292
|
root = keys.splice(0, -1).join('.')
|
279
293
|
ret = root ? this.pick(root, obj) : obj
|
280
|
-
ret = ret[keys[0]].filter(function (v) {
|
294
|
+
ret = ret[keys[0]].filter(function (v) {
|
295
|
+
return v !== undefined
|
296
|
+
})
|
281
297
|
this.set(this.cleanup[i], ret, obj)
|
282
298
|
}
|
283
299
|
this.cleanup = []
|
@@ -334,13 +350,21 @@ DotObject.prototype.move = function (source, target, obj, mods, merge) {
|
|
334
350
|
* @param {Function|Array} mods
|
335
351
|
* @param {Boolean} merge
|
336
352
|
*/
|
337
|
-
DotObject.prototype.transfer = function (
|
353
|
+
DotObject.prototype.transfer = function (
|
354
|
+
source,
|
355
|
+
target,
|
356
|
+
obj1,
|
357
|
+
obj2,
|
358
|
+
mods,
|
359
|
+
merge
|
360
|
+
) {
|
338
361
|
if (typeof mods === 'function' || Array.isArray(mods)) {
|
339
|
-
this.set(
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
362
|
+
this.set(
|
363
|
+
target,
|
364
|
+
_process(this.pick(source, obj1, true), mods),
|
365
|
+
obj2,
|
366
|
+
merge
|
367
|
+
)
|
344
368
|
} else {
|
345
369
|
merge = mods
|
346
370
|
this.set(target, this.pick(source, obj1, true), obj2, merge)
|
@@ -365,16 +389,16 @@ DotObject.prototype.transfer = function (source, target, obj1, obj2, mods, merge
|
|
365
389
|
*/
|
366
390
|
DotObject.prototype.copy = function (source, target, obj1, obj2, mods, merge) {
|
367
391
|
if (typeof mods === 'function' || Array.isArray(mods)) {
|
368
|
-
this.set(
|
392
|
+
this.set(
|
393
|
+
target,
|
369
394
|
_process(
|
370
395
|
// clone what is picked
|
371
|
-
JSON.parse(
|
372
|
-
JSON.stringify(
|
373
|
-
this.pick(source, obj1, false)
|
374
|
-
)
|
375
|
-
),
|
396
|
+
JSON.parse(JSON.stringify(this.pick(source, obj1, false))),
|
376
397
|
mods
|
377
|
-
),
|
398
|
+
),
|
399
|
+
obj2,
|
400
|
+
merge
|
401
|
+
)
|
378
402
|
} else {
|
379
403
|
merge = mods
|
380
404
|
this.set(target, this.pick(source, obj1, false), obj2, merge)
|
@@ -406,7 +430,7 @@ DotObject.prototype.set = function (path, val, obj, merge) {
|
|
406
430
|
|
407
431
|
for (i = 0; i < keys.length; i++) {
|
408
432
|
key = keys[i]
|
409
|
-
if (i ===
|
433
|
+
if (i === keys.length - 1) {
|
410
434
|
if (merge && isObject(val) && isObject(obj[key])) {
|
411
435
|
for (k in val) {
|
412
436
|
if (hasOwnProperty.call(val, k)) {
|
@@ -445,14 +469,14 @@ DotObject.prototype.set = function (path, val, obj, merge) {
|
|
445
469
|
*
|
446
470
|
* var obj = {
|
447
471
|
* "id": 1,
|
448
|
-
|
449
|
-
|
450
|
-
|
472
|
+
* "some": {
|
473
|
+
* "thing": "else"
|
474
|
+
* }
|
451
475
|
* }
|
452
476
|
*
|
453
477
|
* var transform = {
|
454
478
|
* "id": "nr",
|
455
|
-
|
479
|
+
* "some.thing": "name"
|
456
480
|
* }
|
457
481
|
*
|
458
482
|
* var tgt = dot.transform(transform, obj)
|
@@ -464,9 +488,11 @@ DotObject.prototype.set = function (path, val, obj, merge) {
|
|
464
488
|
DotObject.prototype.transform = function (recipe, obj, tgt) {
|
465
489
|
obj = obj || {}
|
466
490
|
tgt = tgt || {}
|
467
|
-
Object.keys(recipe).forEach(
|
468
|
-
|
469
|
-
|
491
|
+
Object.keys(recipe).forEach(
|
492
|
+
function (key) {
|
493
|
+
this.set(recipe[key], this.pick(key, obj), tgt)
|
494
|
+
}.bind(this)
|
495
|
+
)
|
470
496
|
return tgt
|
471
497
|
}
|
472
498
|
|
@@ -492,30 +518,33 @@ DotObject.prototype.dot = function (obj, tgt, path) {
|
|
492
518
|
path = path || []
|
493
519
|
var isArray = Array.isArray(obj)
|
494
520
|
|
495
|
-
Object.keys(obj).forEach(
|
496
|
-
|
497
|
-
|
498
|
-
(
|
521
|
+
Object.keys(obj).forEach(
|
522
|
+
function (key) {
|
523
|
+
var index = isArray && this.useBrackets ? '[' + key + ']' : key
|
524
|
+
if (
|
499
525
|
isArrayOrObject(obj[key]) &&
|
500
|
-
(
|
501
|
-
(
|
502
|
-
|
503
|
-
)
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
513
|
-
tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key]
|
526
|
+
((isObject(obj[key]) && !isEmptyObject(obj[key])) ||
|
527
|
+
(Array.isArray(obj[key]) && !this.keepArray && obj[key].length !== 0))
|
528
|
+
) {
|
529
|
+
if (isArray && this.useBrackets) {
|
530
|
+
var previousKey = path[path.length - 1] || ''
|
531
|
+
return this.dot(
|
532
|
+
obj[key],
|
533
|
+
tgt,
|
534
|
+
path.slice(0, -1).concat(previousKey + index)
|
535
|
+
)
|
536
|
+
} else {
|
537
|
+
return this.dot(obj[key], tgt, path.concat(index))
|
538
|
+
}
|
514
539
|
} else {
|
515
|
-
|
540
|
+
if (isArray && this.useBrackets) {
|
541
|
+
tgt[path.join(this.separator).concat('[' + key + ']')] = obj[key]
|
542
|
+
} else {
|
543
|
+
tgt[path.concat(index).join(this.separator)] = obj[key]
|
544
|
+
}
|
516
545
|
}
|
517
|
-
}
|
518
|
-
|
546
|
+
}.bind(this)
|
547
|
+
)
|
519
548
|
return tgt
|
520
549
|
}
|
521
550
|
|
@@ -529,9 +558,8 @@ DotObject.str = wrap('str')
|
|
529
558
|
DotObject.set = wrap('set')
|
530
559
|
DotObject.delete = wrap('delete')
|
531
560
|
DotObject.del = DotObject.remove = wrap('remove')
|
532
|
-
DotObject.dot = wrap('dot')
|
533
|
-
|
534
|
-
;['override', 'overwrite'].forEach(function (prop) {
|
561
|
+
DotObject.dot = wrap('dot');
|
562
|
+
['override', 'overwrite'].forEach(function (prop) {
|
535
563
|
Object.defineProperty(DotObject, prop, {
|
536
564
|
get: function () {
|
537
565
|
return dotDefault.override
|
@@ -540,9 +568,8 @@ DotObject.dot = wrap('dot')
|
|
540
568
|
dotDefault.override = !!val
|
541
569
|
}
|
542
570
|
})
|
543
|
-
})
|
544
|
-
|
545
|
-
;['useArray', 'keepArray', 'useBrackets'].forEach(function (prop) {
|
571
|
+
});
|
572
|
+
['useArray', 'keepArray', 'useBrackets'].forEach(function (prop) {
|
546
573
|
Object.defineProperty(DotObject, prop, {
|
547
574
|
get: function () {
|
548
575
|
return dotDefault[prop]
|
package/test/array_notation.js
CHANGED
@@ -167,4 +167,10 @@ describe('Dotted Array notation', function () {
|
|
167
167
|
describe('with bracket notation', function () {
|
168
168
|
runVariant('bracket')
|
169
169
|
})
|
170
|
+
|
171
|
+
describe('Refuse to update __proto__', function () {
|
172
|
+
var obj = { path: [] }
|
173
|
+
|
174
|
+
;(() => Dot.set('path[0].__proto__.toString', 'test', obj)).should.throw(/Refusing to update/)
|
175
|
+
})
|
170
176
|
})
|
package/test/dot-json.js
CHANGED
@@ -55,6 +55,28 @@ describe('Object test:', function () {
|
|
55
55
|
})
|
56
56
|
})
|
57
57
|
|
58
|
+
it('Should expand dotted keys with array notation with different separator', function () {
|
59
|
+
var row = {
|
60
|
+
id: 2,
|
61
|
+
my_arr_0: 'one',
|
62
|
+
my_arr_1: 'two',
|
63
|
+
my_arr_2: 'three',
|
64
|
+
'my_arr2[0]': 'one',
|
65
|
+
'my_arr2[1]': 'two',
|
66
|
+
'my_arr2[2]': 'three'
|
67
|
+
}
|
68
|
+
|
69
|
+
new Dot('_').object(row)
|
70
|
+
|
71
|
+
row.should.eql({
|
72
|
+
id: 2,
|
73
|
+
my: {
|
74
|
+
arr: ['one', 'two', 'three'],
|
75
|
+
arr2: ['one', 'two', 'three']
|
76
|
+
}
|
77
|
+
})
|
78
|
+
})
|
79
|
+
|
58
80
|
it('Should allow keys with numbers', function () {
|
59
81
|
var row = {
|
60
82
|
id: 2,
|
@@ -205,4 +227,11 @@ describe('Object test:', function () {
|
|
205
227
|
|
206
228
|
row.should.eql({ page: { name: 'my_page' } })
|
207
229
|
})
|
230
|
+
|
231
|
+
it('Dot.object should disallow to set __proto__', function () {
|
232
|
+
var row = { '__proto__.toString': 'hi' }
|
233
|
+
|
234
|
+
var dot = new Dot()
|
235
|
+
;(() => dot.object(row)).should.throw(/Refusing to update/)
|
236
|
+
})
|
208
237
|
})
|
package/test/dot.js
CHANGED
@@ -7,6 +7,8 @@ var pkg = require('./fixtures/package.json')
|
|
7
7
|
describe('dot():', function () {
|
8
8
|
var obj
|
9
9
|
|
10
|
+
// Dot.useBrackets = false;
|
11
|
+
|
10
12
|
beforeEach(function () {
|
11
13
|
obj = {
|
12
14
|
id: 'my-id',
|
@@ -36,7 +38,25 @@ describe('dot():', function () {
|
|
36
38
|
ehrm: 123,
|
37
39
|
dates: {
|
38
40
|
first: new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
|
39
|
-
}
|
41
|
+
},
|
42
|
+
arrays: [
|
43
|
+
[
|
44
|
+
[
|
45
|
+
{
|
46
|
+
all: [
|
47
|
+
[
|
48
|
+
{
|
49
|
+
the: [
|
50
|
+
'way',
|
51
|
+
['down']
|
52
|
+
]
|
53
|
+
}
|
54
|
+
]
|
55
|
+
]
|
56
|
+
}
|
57
|
+
]
|
58
|
+
]
|
59
|
+
]
|
40
60
|
}
|
41
61
|
})
|
42
62
|
|
@@ -50,7 +70,9 @@ describe('dot():', function () {
|
|
50
70
|
'some.array[0]': 'A',
|
51
71
|
'some.array[1]': 'B',
|
52
72
|
ehrm: 123,
|
53
|
-
'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
|
73
|
+
'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)'),
|
74
|
+
'arrays[0][0][0].all[0][0].the[0]': 'way',
|
75
|
+
'arrays[0][0][0].all[0][0].the[1][0]': 'down'
|
54
76
|
}
|
55
77
|
|
56
78
|
Dot.dot(obj).should.eql(expected)
|
@@ -72,7 +94,8 @@ describe('dot():', function () {
|
|
72
94
|
}],
|
73
95
|
'some.array': ['A', 'B'],
|
74
96
|
ehrm: 123,
|
75
|
-
'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
|
97
|
+
'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)'),
|
98
|
+
arrays: JSON.parse(JSON.stringify(obj.arrays))
|
76
99
|
}
|
77
100
|
|
78
101
|
Dot.keepArray = true
|
@@ -92,10 +115,32 @@ describe('dot():', function () {
|
|
92
115
|
'some.array[0]': 'A',
|
93
116
|
'some.array[1]': 'B',
|
94
117
|
ehrm: 123,
|
95
|
-
'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)')
|
118
|
+
'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)'),
|
119
|
+
'arrays[0][0][0].all[0][0].the[0]': 'way',
|
120
|
+
'arrays[0][0][0].all[0][0].the[1][0]': 'down'
|
121
|
+
}
|
122
|
+
|
123
|
+
Dot.dot(obj).should.eql(expected)
|
124
|
+
})
|
125
|
+
|
126
|
+
it('useBrackets wrap indexes without brackets', function () {
|
127
|
+
var expected = {
|
128
|
+
id: 'my-id',
|
129
|
+
'nes.ted.value': true,
|
130
|
+
'other.nested.stuff': 5,
|
131
|
+
'nested.array.0.with': 'object1',
|
132
|
+
'nested.array.1.and': 'object2',
|
133
|
+
'some.array.0': 'A',
|
134
|
+
'some.array.1': 'B',
|
135
|
+
ehrm: 123,
|
136
|
+
'dates.first': new Date('Mon Oct 13 2014 00:00:00 GMT+0100 (BST)'),
|
137
|
+
'arrays.0.0.0.all.0.0.the.0': 'way',
|
138
|
+
'arrays.0.0.0.all.0.0.the.1.0': 'down'
|
96
139
|
}
|
97
140
|
|
141
|
+
Dot.useBrackets = false
|
98
142
|
Dot.dot(obj).should.eql(expected)
|
143
|
+
Dot.useBrackets = true
|
99
144
|
})
|
100
145
|
|
101
146
|
it('Always keeps empty arrays', function () {
|
package/test/str.js
CHANGED
@@ -24,6 +24,28 @@ describe('str:', function () {
|
|
24
24
|
})
|
25
25
|
})
|
26
26
|
|
27
|
+
it('can set nested with array notation', function () {
|
28
|
+
var obj = {
|
29
|
+
a: 1
|
30
|
+
}
|
31
|
+
Dot.str('object.fields[0].subfield', 'value', obj)
|
32
|
+
Dot.str('object.fields[1].subfield', 'value1', obj)
|
33
|
+
|
34
|
+
obj.should.deepEqual({
|
35
|
+
a: 1,
|
36
|
+
object: {
|
37
|
+
fields: [
|
38
|
+
{
|
39
|
+
subfield: 'value'
|
40
|
+
},
|
41
|
+
{
|
42
|
+
subfield: 'value1'
|
43
|
+
}
|
44
|
+
]
|
45
|
+
}
|
46
|
+
})
|
47
|
+
})
|
48
|
+
|
27
49
|
it('can set root level property regardless whether override is set', function () {
|
28
50
|
Dot.str('a', 'b', {
|
29
51
|
a: 1
|
@@ -31,4 +53,11 @@ describe('str:', function () {
|
|
31
53
|
a: 'b'
|
32
54
|
})
|
33
55
|
})
|
56
|
+
|
57
|
+
it('cannot set __proto__ property', function () {
|
58
|
+
(() => Dot.str('__proto__.toString', 'hi', {})).should.throw(
|
59
|
+
/Refusing to update/
|
60
|
+
);
|
61
|
+
({}.toString().should.deepEqual('[object Object]'))
|
62
|
+
})
|
34
63
|
})
|