dot-object 2.1.0 → 2.1.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
})
|