1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 | function pick(obj, keys) {
|
15 | return keys.reduce((acc, k) => {
|
16 | acc[k] = obj[k];
|
17 | return acc;
|
18 | }, {});
|
19 | }
|
20 |
|
21 | function isObject(_) {
|
22 | return !!_ && typeof _ === 'object';
|
23 |
|
24 | }
|
25 |
|
26 | const substitute = (template, data) => {
|
27 | const start = '{{';
|
28 | const end = '}}';
|
29 | const path = '[a-z0-9_$][\\.a-z0-9_]*';
|
30 | const pattern = new RegExp(start + '\\s*(' + path + ')\\s*' + end, 'gi');
|
31 |
|
32 | return template.replace(pattern, (tag, token) => {
|
33 | let path = token.split('.');
|
34 | let len = path.length;
|
35 | let lookup = data;
|
36 | let i = 0;
|
37 |
|
38 | for (; i < len; i++) {
|
39 | lookup = lookup[path[i]];
|
40 |
|
41 | if (lookup === undefined) {
|
42 | throw new Error(`substitue: '${path[i]}' not found in '${tag}'`);
|
43 | }
|
44 |
|
45 | if (i === len - 1) {
|
46 | return lookup;
|
47 | }
|
48 | }
|
49 | });
|
50 | };
|
51 |
|
52 | const compose = (...functions) => args => functions.reduceRight((arg, fn) => fn(arg), args);
|
53 |
|
54 | module.exports = { pick, isObject, substitute, compose };
|