-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbuild.js
123 lines (110 loc) · 3.39 KB
/
build.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
'use strict';
const flatten = require('./lib/flatten.js');
const plugins = {
$param(value, params) {
if (typeof value === 'string') {
return value in params ? params[value] : { $param: value };
}
if (value[0] in params) {
const result = params[value[0]];
return result === undefined ? resolve(value[1], params) : result;
}
return { $param: [ value[0], resolve(value[1], params) ] };
},
$template(value, params) {
let isResolved = true;
if (!(typeof value === 'string')) {
value = value.join('');
}
const result = value.replace(/\$\{([^}]+)\}/g, (match, path) => {
if (path in params) {
return params[path];
}
isResolved = false;
return match;
});
return isResolved ? result : { $template: result };
},
$guard(value, params) {
const items = [];
value.every((item) => {
if (item[0] in params) {
if (params[item[0]]) {
items.push([ '$default', resolve(item[1], params) ]);
return false;
}
} else {
items.push([ item[0], resolve(item[1], params) ]);
}
return true;
});
if (items.length === 0) {
return undefined;
}
if (items.length === 1 && items[0][0] === '$default') {
return items[0][1];
}
return { $guard: items };
},
$switch(value, params) {
if (value[0] in params) {
const test = params[value[0]];
const item = value[1].find((item) => {
const _case = item[0];
if (_case === test) {
return true;
}
if (Array.isArray(_case) && _case.indexOf(test) !== -1) {
return true;
}
return _case === '$default';
});
return item && resolve(item[1], params);
}
return {
$switch: [
value[0],
value[1].map((item) => [ item[0], resolve(item[1], params) ])
]
};
},
$function(value, params) {
return { $function: [ value, params ] };
}
};
const keywords = Object.keys(plugins);
/**
* Builds config with predefined params.
*
* @param {object} config - Config.
* @param {object} params - Predefined params.
* @returns {*} Built config.
*/
function build(config, params) {
return resolve(config, flatten(params));
}
/**
* Resolves config value with predefined settings.
*
* @param {*} value - Config value.
* @param {object} params - Flattened predefined params.
* @returns {*} Resolved value.
*/
function resolve(value, params) {
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) {
return value.map((value) => resolve(value, params));
} else {
const keyword = keywords.find((keyword) => value[keyword]);
if (keyword) {
return plugins[keyword](value[keyword], params);
}
return Object.keys(value).reduce((result, key) => {
result[key] = resolve(value[key], params);
return result;
}, {});
}
}
return value;
}
module.exports = build;