src/services/cli/cli.js
const commander = require('commander');
const { provider } = require('jimple');
/**
* The main CLI program interface where all the commands are registered and that works as a bridge
* between the app and `commander`.
*/
class CLI {
/**
* Class constructor.
* @param {Object} info This app `package.json` information.
* @param {string} [name=''] The name of the program. If not specified, it will use the one on
* `info` object.
*/
constructor(info, name = '') {
/**
* This app `package.json` information.
* @type {Object}
*/
this.info = info;
/**
* The name of the CLI program.
* @type {string}
*/
this.name = name || this.info.name;
}
/**
* Start the interface with a list of commands.
* @param {Array<CLICommand>} commands A list of commands to register.
*/
start(commands) {
// Set the name, version and the description of the program.
commander.name(this.name);
commander.version(this.info.version, '-v, --version');
commander.description(this.info.description);
// Loop all the commands and register them.
commands.forEach((command) => {
command.register(commander, this);
});
// Tell commander to parse the arguments.
commander.parse(process.argv);
}
}
/**
* Generates a `Provider` with an already defined name for the program.
* @example
* // Generate the provider
* const provider = cliWithName('my-program');
* // Register it on the container
* container.register(provider);
* // Getting access to the service instance
* const cli = container.get('cli');
* @param {string} name The name of the program.
* @return {Provider}
*/
const cliWithName = (name) => provider((app) => {
app.set('cli', () => new CLI(
app.get('info'),
name
));
});
/**
* The service provider that once registered on the app container will set an instance of
* `CLI` as the `cli` service.
* @example
* // Register it on the container
* container.register(cli);
* // Getting access to the service instance
* const cli = container.get('cli');
* @type {Provider}
*/
const cli = cliWithName();
module.exports = {
CLI,
cliWithName,
cli,
};