const parse = require('meriyah').parseScript;
/**
* @module pete/lib/fn-params
*/
module.exports = getParams;
/**
* List names of function arguments.
*
* @alias module:pete/lib/fn-params
* @throws {Error} when code or function cannot be parsed
* @param {string|Function} fn
* @return {string[]}
*/
function getParams (fn) {
const code = typeof fn === 'string' ? fn : fn.toString();
// "wrap" it so function without a name will not trigger an error
const parsed = parse(`var temp = ${code};`);
return getParamsNames(parsed.body[0].declarations[0].init.params);
}
/**
* @private
* @param {object} params found by Acorn parser
*/
function getParamsNames (params) {
return params
.map(param => {
if (param.type === 'Identifier') {
return param.name;
}
if (param.type === 'AssignmentPattern') {
return getParamsNames([param.left]);
}
if (param.type === 'ArrayPattern') {
return getParamsNames(param.elements);
}
if (param.type === 'ObjectPattern') {
return getParamsNames(param.properties);
}
if (param.type === 'Property' && param.kind === 'init') {
return getParamsNames([param.value]);
}
if (param.type === 'RestElement') {
return param.argument.name;
}
return null;
})
.flat()
.filter(Boolean);
}