1 | 'use strict';
|
2 |
|
3 | const inspectFunction = require('inspect-function');
|
4 |
|
5 | const isArrayLike = p => p.match(/^\[+/) || null;
|
6 | const isObjectLike = p => p.match(/^{+/) || null;
|
7 | const matchObjectProperty = p => p.match(/^([^{]+):(.*)/) || null;
|
8 | const unpackArrayOrObject = p => p.replace(/^[\[{]|[\]}]$/g, '');
|
9 |
|
10 | const unpackParameter = (param, options) => {
|
11 | let unpacked = getParametersArray(unpackArrayOrObject(param));
|
12 |
|
13 | if (isArrayLike(param)) {
|
14 | return unpacked.map(unpackedParam => getParameterValue(unpackedParam, options));
|
15 | }
|
16 |
|
17 | if (isObjectLike(param)) {
|
18 | return unpacked.reduce((paramValue, unpackedParam) => {
|
19 | let objectProperty = matchObjectProperty(unpackedParam);
|
20 | if(objectProperty){
|
21 | let [, key, value] = objectProperty.map(v => v.trim());
|
22 | paramValue[key] = getParameterValue(value, options);
|
23 | } else {
|
24 | paramValue[unpackedParam] = getParameterValue(unpackedParam, options);
|
25 | }
|
26 |
|
27 | return paramValue;
|
28 | }, {});
|
29 | }
|
30 | };
|
31 |
|
32 | const getParameterValue = (param, options) => {
|
33 | if(isArrayLike(param) || isObjectLike(param)){
|
34 | return unpackParameter(param, options);
|
35 | }
|
36 |
|
37 | return options[param];
|
38 | }
|
39 |
|
40 | function getParametersArray(paramsString) {
|
41 | let startIndex = 0;
|
42 | let skipComma;
|
43 |
|
44 | const paramsFound = paramsString.split('').reduce((paramsFound, chr, i, arr) => {
|
45 | if (chr.match(/\[|\{|\(/)) {
|
46 | skipComma = true;
|
47 | }
|
48 |
|
49 | if (chr.match(/\]|\}|\)/)) {
|
50 | skipComma = false;
|
51 | }
|
52 |
|
53 | if (!skipComma && (chr === ',' || i === arr.length - 1)) {
|
54 | const lastIndex = i === arr.length - 1 ? i + 1 : i;
|
55 | const paramFound = paramsString.substring(startIndex, lastIndex);
|
56 | startIndex = lastIndex + 1;
|
57 | paramsFound.push(paramFound);
|
58 | }
|
59 | return paramsFound;
|
60 | }, []);
|
61 |
|
62 | return paramsFound.map(p => p.trim());
|
63 | }
|
64 |
|
65 | const optionsToParameters = (parameters, options) => {
|
66 | return parameters.map(param => getParameterValue(param, options));
|
67 | };
|
68 |
|
69 | const fnParametersFromOptions = (fn, object) => {
|
70 | const fnParams = inspectFunction(fn).parameters.expected;
|
71 | return optionsToParameters(fnParams, object);
|
72 | };
|
73 |
|
74 | const callWithObject = (fn, object) => {
|
75 | const fnParams = inspectFunction(fn).parameters.expected;
|
76 | const objectParameters = optionsToParameters(fnParams, object);
|
77 | return fn(...objectParameters);
|
78 | };
|
79 |
|
80 | module.exports = { callWithObject, fnParametersFromOptions }; |
\ | No newline at end of file |