-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinterpolate_and_prepare.js
More file actions
104 lines (98 loc) · 3.73 KB
/
interpolate_and_prepare.js
File metadata and controls
104 lines (98 loc) · 3.73 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
// supporting constants and functions
const re = /\${(.*?)}/g;
const array_re = /^([a-zA-Z0-9]*)\[(.*)\]$/;
const re_ef = /([^(]+)\((.*)\)/;
// unused, replaceKey performs better
function _get(object, path,defval) {
if (typeof path === "string") path = path.split(".");
return path.reduce((xs, x) => (xs && xs[x]?xs[x]:x.replace(/\]$/,'').split(/\]?\[/).reduce( (axs, ax) =>(axs && axs[ax]? axs[ax]:defval),xs)), object);
}
const replaceKey = (key, data) => {
let ret = data;
for (const prop of key.split('.')) {
if(!ret) break;
if (prop.match(array_re)) {
const matching = array_re.exec(prop);
ret = ret[matching[1]] [matching[2]];
} else {
ret = ret ? ret[prop] : undefined;
}
}
return ret;
}
const ef_and_arg = (chainPart) => {
if (chainPart.match(re_ef)) {
const matching = re_ef.exec(chainPart);
return [ matching[1], matching[2]];
let funName = matching[1];
let funArgs = matching[2];
}
return [ undefined, undefined]
}
export const interpolate_and_prepare = (tpl, data) => {
if (typeof tpl !== 'string') {
throw new TypeError(`Expected a string in the first argument, got ${typeof tpl}`);
}
if (typeof data !== 'object') {
throw new TypeError(`Expected an Object/Array in the second argument, got ${typeof data}`);
}
let params = [];
let prepared = tpl.replace(re, (_,key) => {
let ret = replaceKey(key, data);
//let ret = _get(data, key, '');
if(ret!==undefined) {
params.push(ret);
return '?';
} else {
// now interpolate functions
let funChain = key.split('.');
let funPart = funChain[0];
let [funName, funArgs] = ef_and_arg(funPart);
if (funName === '_swallog') {
let arg = replaceKey(funArgs, data);
let restOfChain = funChain.slice(1);
let quePart;
let valuePart = restOfChain.reduce((acc, chMethod) => {
let [mName, mArg] = ef_and_arg(chMethod);
switch(mName) {
case 'pluck':
return acc.map(o=>o[mArg]);
case 'dqJoin':
quePart = acc.map(x=>'"?"').join(mArg.replace(/'/g,''));
return acc;
case 'qJoin':
quePart = acc.map(x=>"'?'").join(mArg.replace(/'/g,''));
return acc;
case 'join':
quePart = acc.map(x=>'?').join(mArg.replace(/'/g,''));
return acc;
case 'first':
quePart = '?';
return [acc[0]];
case 'last':
quePart = '?';
return [acc[acc.length-1]];
case 'at':
quePart = '?';
return [acc[mArg]];
case 'slice':
quePart = '?';
let sliceArgs = mArg.split(',');
return acc.slice(sliceArgs[0], sliceArgs[1]);
case 'array':
quePart = '?';
return [acc];
default:
console.log('is last');
return acc;
}
}, arg);
valuePart.forEach(p=>params.push(p))
return quePart
}
return '';
}
})
//console.log(`PREPARED/KEYS: "${prepared}"`,params)
return {prepared,params}
};