This repository has been archived by the owner on Sep 25, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
/
config-wrapper.js
127 lines (102 loc) · 2.93 KB
/
config-wrapper.js
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
var getPath = require('dotty').get;
var putPath = require('dotty').put;
var deepExtend = require('deep-extend');
var errors = require('./errors.js');
var safeCloneInto = {value: null};
var safeCloneFrom = {value: null};
module.exports = ConfigWrapper;
function ConfigWrapper(configObject, loose) {
var frozen = false;
var deepFrozen = false;
// default `loose` to true.
loose = typeof loose === 'boolean' ? loose : true;
return {
get: configuredGet,
set: setKey,
freeze: freeze,
deepFreeze: deepFreeze
};
function getKey(keyPath) {
if (!keyPath) {
return safe(configObject);
}
return safe(getPath(configObject, keyPath));
}
function configuredGet(keyPath) {
if (!keyPath) {
return getKey();
}
var value = getKey(keyPath);
var strictMode = !loose;
if (value === undefined && strictMode) {
throw errors.NonexistantKeyPath(({
keyPath: keyPath
}));
}
return value;
}
function setKey(keyPath, value) {
if (frozen) {
throw errors.SetFrozenObject({
keyPath: keyPath,
valueStr: JSON.stringify(value),
value: value
});
}
if (arguments.length === 1) {
return multiSet(keyPath);
}
if (!isValidKeyPath(keyPath)) {
throw errors.InvalidKeyPath({
keyPath: keyPath
});
}
var v = getKey(keyPath);
v = deepExtend({keyPath: v}, {keyPath: value});
return putPath(configObject, keyPath, v.keyPath);
}
function freeze() {
frozen = true;
}
function deepFreeze() {
frozen = true;
deepFrozen = true;
deepFreezeObject(configObject);
}
function multiSet(obj) {
if (obj === null || typeof obj !== 'object') {
throw errors.InvalidMultiSetArgument({
objStr: JSON.stringify(obj),
obj: obj
});
}
Object.keys(obj).forEach(setEachKey);
function setEachKey(key) {
setKey([key], obj[key]);
}
}
function safe(value) {
if (deepFrozen === true) {
return value;
}
safeCloneInto.value = null;
safeCloneFrom.value = value;
return deepExtend(safeCloneInto, safeCloneFrom).value;
}
}
function isValidKeyPath(keyPath) {
return typeof keyPath === 'string' ||
Array.isArray(keyPath);
}
function deepFreezeObject(o) {
Object.freeze(o);
Object.keys(o).forEach(function eachProp(prop) {
if (Object.hasOwnProperty.call(o, prop) &&
o[prop] !== null &&
(typeof o[prop] === 'object' || typeof o[prop] === 'function') &&
!Object.isFrozen(o[prop])) {
deepFreezeObject(o[prop]);
}
});
return o;
}