UNPKG

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
#!/usr/bin/env node 'use strict'; 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;