1 | const _map = require('lodash.map');
|
2 | const _compact = require('lodash.compact');
|
3 |
|
4 | const NEWLINE = /\n/g;
|
5 | const AT = /_at_/g;
|
6 | const ARROW_ARG = /^([^(]+?)=>/;
|
7 | const FN_ARGS = /^[^(]*\(\s*([^)]*)\)/m;
|
8 | const FN_ARG_SPLIT = /,/;
|
9 | const FN_ARG = /^\s*(_?)(\S+?)\1\s*$/;
|
10 | const STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
|
11 |
|
12 | class FunctionArgumentsParser {
|
13 |
|
14 | parse(fn) {
|
15 | if (typeof fn !== 'function') {
|
16 | throw new Error('A valid function was no provided as a function wrapper.');
|
17 | }
|
18 |
|
19 | const args = [];
|
20 | const argsDeclaration = this.extractArgs(fn);
|
21 |
|
22 | argsDeclaration[1].split(FN_ARG_SPLIT).forEach(function (arg) {
|
23 | arg.replace(FN_ARG, function(name) {
|
24 | args.push(name);
|
25 | });
|
26 | });
|
27 |
|
28 | return _compact(_map(args, (p) => p.trim()));
|
29 | }
|
30 |
|
31 | extractArgs(fn) {
|
32 | const fnText = this.stringifyFn(fn)
|
33 | .replace(STRIP_COMMENTS, '')
|
34 | .replace(NEWLINE, ' ')
|
35 | .replace(AT, '');
|
36 |
|
37 | const args = fnText.match(ARROW_ARG) || fnText.match(FN_ARGS);
|
38 | return args;
|
39 | }
|
40 |
|
41 | stringifyFn(fn) {
|
42 | return Function.prototype.toString.call(fn);
|
43 | }
|
44 |
|
45 | }
|
46 |
|
47 | module.exports = new FunctionArgumentsParser();
|