-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
110 lines (89 loc) · 2.34 KB
/
index.js
File metadata and controls
110 lines (89 loc) · 2.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/*!
* set-value <https://github.com/jonschlinkert/set-value>
*
* Copyright (c) 2014-2018, Jon Schlinkert.
* Released under the MIT License.
*/
'use strict';
const isPlain = require('is-plain-object');
function set(target, path, value, options) {
if (!isObject(target)) {
return target;
}
let opts = options || {};
const isArray = Array.isArray(path);
if (!isArray && typeof path !== 'string') {
return target;
}
let merge = opts.merge;
if (merge && typeof merge !== 'function') {
merge = Object.assign;
}
const keys = (isArray ? path : split(path, opts)).filter(isValidKey);
const len = keys.length;
const orig = target;
if (!options && keys.length === 1) {
result(target, keys[0], value, merge);
return target;
}
for (let i = 0; i < len; i++) {
let prop = keys[i];
if (!isObject(target[prop])) {
target[prop] = {};
}
if (i === len - 1) {
result(target, prop, value, merge);
break;
}
target = target[prop];
}
return orig;
}
function result(target, path, value, merge) {
if (merge && isPlain(target[path]) && isPlain(value)) {
target[path] = merge({}, target[path], value);
} else {
target[path] = value;
}
}
function split(path, options) {
const id = createKey(path, options);
if (set.memo[id]) return set.memo[id];
const char = (options && options.separator) ? options.separator : '.';
let keys = [];
let res = [];
if (options && typeof options.split === 'function') {
keys = options.split(path);
} else {
keys = path.split(char);
}
for (let i = 0; i < keys.length; i++) {
let prop = keys[i];
while (prop && prop.slice(-1) === '\\' && keys[i + 1] != null) {
prop = prop.slice(0, -1) + char + keys[++i];
}
res.push(prop);
}
set.memo[id] = res;
return res;
}
function createKey(pattern, options) {
let id = pattern;
if (typeof options === 'undefined') {
return id + '';
}
const keys = Object.keys(options);
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
id += ';' + key + '=' + String(options[key]);
}
return id;
}
function isValidKey(key) {
return key !== '__proto__' && key !== 'constructor' && key !== 'prototype';
}
function isObject(val) {
return val !== null && (typeof val === 'object' || typeof val === 'function');
}
set.memo = {};
module.exports = set;