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
209 lines • 7.01 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 {
/**
* An optional instance of the application.
* Required to scan the application
*/
container;
/**
* A Map holding group commands by name
*/
commands = new Map();
/**
* The root cli
*/
cli;
responseListener = new stream_1.EventEmitter();
constructor(cli) {
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 async (...args) => {
const command = args.find((c) => c instanceof commander.Command);
if (!command) {
throw new Error('Command instance not found in arguments');
}
let data;
if (typeof action === 'object' &&
'instance' in action &&
'methodName' in action) {
const instance = action.instance;
const method = instance[action.methodName];
// Bind the method to the instance to preserve 'this' context
data = method.call(instance, ...args);
}
else if (typeof action === 'function') {
data = action(...args);
}
else {
throw new Error('Invalid action handler type');
}
if (data instanceof Promise) {
data = await data;
}
return { data, command };
};
}
/**
* Execute the cli
*/
async init(argv) {
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) {
const method = opt.required === true ? 'requiredOption' : 'option';
command[method](opt.flags, opt.description, opt.fn || opt.defaultValue, opt.defaultValue);
}
}
command.action(async (...args) => {
try {
const res = await ConsoleService_1.createHandler(handler)(...args);
this.responseListener.emit('response', res);
}
catch (error) {
this.responseListener.emit('error', error);
}
});
parent.addCommand(command, commanderOptions);
this.commands.set(this.getCommandFullName(command), command);
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) {
const parentCommand = parent;
if (parentCommand._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) {
const method = opt.required === true ? 'requiredOption' : 'option';
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;
}
};
exports.ConsoleService = ConsoleService;
exports.ConsoleService = 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);
//# sourceMappingURL=service.js.map