rucken
Version:
Console tools and scripts for nx and not only that I (EndyKaufman) use to automate the workflow and speed up the development process
201 lines (200 loc) • 6.88 kB
JavaScript
;
var ConsoleService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ConsoleService = void 0;
const tslib_1 = require("tslib");
/**
* @module ConsoleService
*/
const common_1 = require("@nestjs/common");
const commander = tslib_1.__importStar(require("commander"));
const decorators_1 = require("./decorators");
const stream_1 = require("stream");
let ConsoleService = ConsoleService_1 = class ConsoleService {
constructor(cli) {
/**
* A Map holding group commands by name
*/
this.commands = new Map();
this.responseListener = new stream_1.EventEmitter();
this.cli = cli;
}
static createCli(name) {
const cli = new commander.Command(name);
cli.storeOptionsAsProperties(false);
cli.allowUnknownOption(false);
return cli;
}
/**
* Reset the cli stack (for testing purpose only)
*/
resetCli() {
this.cli = ConsoleService_1.createCli();
}
/**
* Get the root cli
*/
getRootCli() {
return this.cli;
}
/**
* Get a cli
* @param name Get a cli by name, if not set, the root cli is used
*/
getCli(name) {
let cli;
if (typeof name === 'string') {
cli = this.commands.get(name);
}
else {
cli = this.cli;
}
return cli;
}
/**
* Set the container
*/
setContainer(container) {
this.container = container;
return this;
}
/**
* Get the container
*/
getContainer() {
return this.container;
}
/**
* Wrap an action handler to work with promise.
*/
static createHandler(action) {
return (...args) => tslib_1.__awaiter(this, void 0, void 0, function* () {
const command = args.find((c) => c instanceof commander.Command);
let data;
if (typeof action === 'object') {
data = action.instance[action.methodName](...args);
}
else {
data = action(...args);
}
if (data instanceof Promise) {
data = yield data;
}
return { data, command };
});
}
/**
* Execute the cli
*/
init(argv) {
return tslib_1.__awaiter(this, void 0, void 0, function* () {
const userArgs = this.cli._prepareUserArgs(argv);
return new Promise((resolve, reject) => {
this.responseListener.once('response', (res) => {
resolve(res);
});
this.responseListener.once('error', (error) => {
reject(error);
});
this.cli._parseCommand([], userArgs);
});
});
}
/**
* Create a Command
*
* @param options The options to create the commands
* @param handler The handler of the command
* @param parent The command to use as a parent
*/
createCommand(options, handler, parent, commanderOptions) {
const args = options.command.split(' ');
const commandNames = args[0].split('.');
const command = ConsoleService_1.createCli(commandNames[commandNames.length - 1]);
if (args.length > 1) {
command.arguments(args.slice(1).join(' '));
}
if (options.description !== undefined) {
command.description(options.description);
}
if (options.alias !== undefined) {
command.alias(options.alias);
}
if (Array.isArray(options.options)) {
for (const opt of options.options) {
let method = 'option';
if (opt.required === true) {
method = 'requiredOption';
}
command[method](opt.flags, opt.description, opt.fn || opt.defaultValue, opt.defaultValue);
}
}
// here as any is required cause commander bad typing on action for promise
command.action((...args) => tslib_1.__awaiter(this, void 0, void 0, function* () {
try {
const res = yield ConsoleService_1.createHandler(handler)(...args);
this.responseListener.emit('response', res);
}
catch (e) {
this.responseListener.emit('error', e);
}
}));
// add the command to the parent
parent.addCommand(command, commanderOptions);
// add the command to cli stack
this.commands.set(this.getCommandFullName(command), command);
// eslint-disable-next-line @typescript-eslint/no-empty-function
command.on('response', (res) => { });
return command;
}
/**
* Create a group of command.
* @param options The options to create the grouped command
* @param parent The command to use as a parent
* @throws an error if the parent command contains explicit arguments, only simple commands are allowed (no spaces)
*/
createGroupCommand(options, parent) {
if (parent._args.length > 0) {
throw new Error('Sub commands cannot be applied to command with explicit args');
}
const commandNames = options.command.split('.');
const command = ConsoleService_1.createCli(commandNames[commandNames.length - 1]);
if (options.description !== undefined) {
command.description(options.description);
}
if (options.alias !== undefined) {
command.alias(options.alias);
}
if (Array.isArray(options.options)) {
for (const opt of options.options) {
let method = 'option';
if (opt.required === true) {
method = 'requiredOption';
}
command[method](opt.flags, opt.description, opt.fn || opt.defaultValue, opt.defaultValue);
}
}
parent.addCommand(command);
this.commands.set(this.getCommandFullName(command), command);
return command;
}
/**
* Get the full name of a command (parents names + command names separated by dot)
*/
getCommandFullName(command) {
let fullName = command.name();
let commandParent = command.parent;
while (commandParent instanceof commander.Command &&
commandParent.name() !== '') {
fullName = `${commandParent.name()}.${fullName}`;
commandParent = commandParent.parent;
}
return fullName;
}
};
ConsoleService = ConsoleService_1 = tslib_1.__decorate([
(0, common_1.Injectable)(),
tslib_1.__param(0, (0, decorators_1.InjectCli)()),
tslib_1.__metadata("design:paramtypes", [commander.Command])
], ConsoleService);
exports.ConsoleService = ConsoleService;