magicli
Version:
Automagically generates command-line interfaces (CLI) for any module. Expected options and help sections are created automatically based on parameters names, with support to async. It can be installed globally, in order to *execute* any module, or .js fil
76 lines (60 loc) • 2.19 kB
JavaScript
const fs = require('fs');
const path = require('path');
const forEachProperty = require('for-each-property');
const inspectProperty = require('inspect-property');
const cliss = require('cliss');
const findUp = require('find-up');
function requireMainModule(currentPath) {
let packageJson = path.resolve(path.join(currentPath, '/package.json'));
if (!fs.existsSync(packageJson)) {
packageJson = findUp.sync('package.json', {
cwd: packageJson
});
}
const modulePath = path.dirname(packageJson);
return {
moduleRef: require(modulePath),
packageJson: require(packageJson)
};
}
function requireJsFile(currentPath) {
return {
moduleRef: require(currentPath),
packageJson: {}
};
}
function magicli({ commands = {}, validateRequiredParameters = false, help = {}, version = {}, pipe = {}, enumerability = 'enumerable', subcommandDelimiter = '-', modulePath } = {}) {
const { moduleRef, packageJson } = modulePath && path.extname(modulePath) === '.js' ? requireJsFile(modulePath) : requireMainModule(modulePath || require.main.filename);
const moduleName = packageJson.name;
const moduleVersion = packageJson.version;
const moduleDescription = packageJson.description;
const moduleApi = inspectProperty(moduleRef, null, { enumerability, delimiter: subcommandDelimiter, inspectProperties: true });
// CLIss cliSpec
const cliSpec = { name: moduleName, version: moduleVersion, description: moduleDescription };
// Main command
if (moduleApi.type === 'function') {
cliSpec.action = moduleApi.functionInspection.fn;
if (commands[moduleName]) {
Object.assign(cliSpec, commands[moduleName]);
}
}
// Subcommands
forEachProperty(moduleApi.properties, (value, key) => {
if (value.type !== 'function' || value.isClass) {
return;
}
cliSpec.commands = cliSpec.commands || [];
const subcommand = {
name: key,
action: value.functionInspection.fn
};
if (commands[subcommand.name]) {
Object.assign(subcommand, commands[subcommand.name]);
}
cliSpec.commands.push(subcommand);
});
cliss(cliSpec, { options: { validateRequiredParameters }, help, version, pipe });
}
module.exports = magicli;
;