-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmkenv.js
92 lines (75 loc) · 1.96 KB
/
mkenv.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
var mkenv = module.exports = function () {
var chain = [].slice.call(arguments, 0);
function eval(name, root, depth) {
root = root || eval;
depth = depth || 0;
try {
var value = null;
for ( var i = chain.length - 1; value === null && i >= 0; i-- ) {
var env = chain[i];
if ( typeof env === "function" && env !== eval ) {
value = env(name, root, depth);
} else if ( env && env.hasOwnProperty(name) ) {
value = env[name];
}
}
if ( value == null ) return null;
// Simple replacements
value = value.replace(/\$([a-zA-Z0-9_]+)/g, function (m, pkey) {
var v = root(pkey, root, depth + 1);
return v === null || v === undefined ? '' : v;
})
// Bracketed replacements
var numReplacements;
do {
numReplacements = 0;
value = value.replace(/\$\{([a-zA-Z0-9_\-\\\/]+)\}/g, function (m, pkey) {
numReplacements++;
var v = root(pkey, root, depth + 1);
return v === null || v === undefined ? '' : v;
})
} while (numReplacements > 0);
return value;
} catch (e) {
throw new Error("mkenv: evaluation of '" + name + "' failed: " + e.toString())
}
}
// Allow overriding variables by assignment
chain.push(eval);
Object.defineProperty(eval, '__mkenv_chain', {
enumerable: false,
value: chain
});
return eval;
}
function getKeys(env) {
var chain = env.__mkenv_chain;
if (!chain) return [];
var keys = {};
chain.forEach(function (item) {
if ( typeof item === "function" && item !== env ) {
getKeys(item).forEach(function (key) {
keys[key] = true;
})
} else if (item) {
Object.keys(item).forEach(function (key) {
keys[key] = true;
})
}
})
return Object.keys(keys);
}
mkenv.keys = getKeys;
mkenv.vars = function vars(env) {
var vars = {};
getKeys(env).forEach(function (key) {
vars[key] = env(key);
});
return vars;
}
mkenv.hidden = function hidden(env) {
env = mkenv(env);
return function (key, root, depth) {
return depth ? env(key, root) : null;
}
}