mobile-cli-lib
Version:
common lib used by different CLI
310 lines (309 loc) • 16.7 kB
JavaScript
"use strict";
var jaroWinklerDistance = require("../vendor/jaro-winkler_distance");
var helpers = require("../helpers");
var os_1 = require("os");
var CommandArgumentsValidationHelper = (function () {
function CommandArgumentsValidationHelper(isValid, _remainingArguments) {
this.isValid = isValid;
this.remainingArguments = _remainingArguments.slice();
}
return CommandArgumentsValidationHelper;
}());
var CommandsService = (function () {
function CommandsService($commandsServiceProvider, $errors, $fs, $hooksService, $injector, $logger, $options, $resources, $staticConfig) {
this.$commandsServiceProvider = $commandsServiceProvider;
this.$errors = $errors;
this.$fs = $fs;
this.$hooksService = $hooksService;
this.$injector = $injector;
this.$logger = $logger;
this.$options = $options;
this.$resources = $resources;
this.$staticConfig = $staticConfig;
this.areDynamicSubcommandsRegistered = false;
this.cachedCommandHelp = null;
}
CommandsService.prototype.allCommands = function (opts) {
var commands = this.$injector.getRegisteredCommandsNames(opts.includeDevCommands);
return _.reject(commands, function (command) { return _.includes(command, '|'); });
};
CommandsService.prototype.executeCommandUnchecked = function (commandName, commandArguments) {
var _this = this;
return (function () {
var command = _this.$injector.resolveCommand(commandName);
if (command) {
if (!_this.$staticConfig.disableAnalytics && !command.disableAnalytics) {
var analyticsService = _this.$injector.resolve("analyticsService");
analyticsService.checkConsent().wait();
analyticsService.trackFeature(commandName).wait();
}
if (!_this.$staticConfig.disableCommandHooks && (command.enableHooks === undefined || command.enableHooks === true)) {
var hierarchicalCommandName = _this.$injector.buildHierarchicalCommand(commandName, commandArguments);
if (hierarchicalCommandName) {
commandName = helpers.stringReplaceAll(hierarchicalCommandName.commandName, CommandsService.HIERARCHICAL_COMMANDS_DEFAULT_COMMAND_DELIMITER, CommandsService.HOOKS_COMMANDS_DELIMITER);
commandName = helpers.stringReplaceAll(commandName, CommandsService.HIERARCHICAL_COMMANDS_DELIMITER, CommandsService.HOOKS_COMMANDS_DELIMITER);
}
_this.$hooksService.executeBeforeHooks(commandName).wait();
command.execute(commandArguments).wait();
_this.$hooksService.executeAfterHooks(commandName).wait();
}
else {
command.execute(commandArguments).wait();
}
var commandHelp = _this.getCommandHelp().wait();
if (!command.disableCommandHelpSuggestion && commandHelp && commandHelp[commandName]) {
var suggestionText = commandHelp[commandName];
_this.$logger.printMarkdown(~suggestionText.indexOf('%s') ? require('util').format(suggestionText, commandArguments) : suggestionText);
}
return true;
}
return false;
}).future()();
};
CommandsService.prototype.printHelp = function (commandName) {
this.$options.help = true;
return this.executeCommandUnchecked("help", [this.beautifyCommandName(commandName)]);
};
CommandsService.prototype.executeCommandAction = function (commandName, commandArguments, action) {
var _this = this;
return this.$errors.beginCommand(function () { return action.apply(_this, [commandName, commandArguments]); }, function () { return _this.printHelp(commandName); });
};
CommandsService.prototype.tryExecuteCommandAction = function (commandName, commandArguments) {
var command = this.$injector.resolveCommand(commandName);
this.$options.validateOptions(command ? command.dashedOptions : null);
if (!this.areDynamicSubcommandsRegistered) {
this.$commandsServiceProvider.registerDynamicSubCommands();
this.areDynamicSubcommandsRegistered = true;
}
return this.canExecuteCommand(commandName, commandArguments);
};
CommandsService.prototype.tryExecuteCommand = function (commandName, commandArguments) {
var _this = this;
return (function () {
if (_this.executeCommandAction(commandName, commandArguments, _this.tryExecuteCommandAction).wait()) {
_this.executeCommandAction(commandName, commandArguments, _this.executeCommandUnchecked).wait();
}
else {
var command = _this.$injector.resolveCommand(commandName);
if (command) {
_this.printHelp(commandName).wait();
}
}
}).future()();
};
CommandsService.prototype.canExecuteCommand = function (commandName, commandArguments, isDynamicCommand) {
var _this = this;
return (function () {
var command = _this.$injector.resolveCommand(commandName);
var beautifiedName = helpers.stringReplaceAll(commandName, "|", " ");
if (command) {
if (command.isDisabled) {
_this.$errors.failWithoutHelp("This command is not applicable to your environment.");
}
if (command.canExecute) {
return command.canExecute(commandArguments).wait();
}
if (_this.$injector.isValidHierarchicalCommand(commandName, commandArguments)) {
return true;
}
if (_this.validateCommandArguments(command, commandArguments).wait()) {
return true;
}
_this.$errors.fail("Unable to execute command '%s'. Use '$ %s %s --help' for help.", beautifiedName, _this.$staticConfig.CLIENT_NAME.toLowerCase(), beautifiedName);
return false;
}
else if (!isDynamicCommand && _.startsWith(commandName, _this.$commandsServiceProvider.dynamicCommandsPrefix)) {
if (_.some(_this.$commandsServiceProvider.getDynamicCommands().wait())) {
_this.$commandsServiceProvider.generateDynamicCommands().wait();
return _this.canExecuteCommand(commandName, commandArguments, true).wait();
}
}
_this.$logger.fatal("Unknown command '%s'. Use '%s help' for help.", beautifiedName, _this.$staticConfig.CLIENT_NAME.toLowerCase());
_this.tryMatchCommand(commandName);
return false;
}).future()();
};
CommandsService.prototype.validateMandatoryParams = function (commandArguments, mandatoryParams) {
var _this = this;
return (function () {
var commandArgsHelper = new CommandArgumentsValidationHelper(true, commandArguments);
if (mandatoryParams.length > 0) {
if (mandatoryParams.length > commandArguments.length) {
var customErrorMessages = _.map(mandatoryParams, function (mp) { return mp.errorMessage; });
customErrorMessages.splice(0, 0, "You need to provide all the required parameters.");
_this.$errors.fail(customErrorMessages.join(os_1.EOL));
}
_.each(mandatoryParams, function (mandatoryParam) {
var argument = _.find(commandArgsHelper.remainingArguments, function (c) { return mandatoryParam.validate(c).wait(); });
if (argument) {
helpers.remove(commandArgsHelper.remainingArguments, function (arg) { return arg === argument; });
}
else {
_this.$errors.fail("Missing mandatory parameter.");
}
});
}
return commandArgsHelper;
}).future()();
};
CommandsService.prototype.validateCommandArguments = function (command, commandArguments) {
var _this = this;
return (function () {
var mandatoryParams = _.filter(command.allowedParameters, function (param) { return param.mandatory; });
var commandArgsHelper = _this.validateMandatoryParams(commandArguments, mandatoryParams).wait();
if (!commandArgsHelper.isValid) {
return false;
}
if (!command.allowedParameters || command.allowedParameters.length === 0) {
if (commandArguments.length > 0) {
_this.$errors.fail("This command doesn't accept parameters.");
}
}
else {
var unverifiedAllowedParams_1 = command.allowedParameters.filter(function (param) { return !param.mandatory; });
_.each(commandArgsHelper.remainingArguments, function (argument) {
var parameter = _.find(unverifiedAllowedParams_1, function (c) { return c.validate(argument).wait(); });
if (parameter) {
var index = unverifiedAllowedParams_1.indexOf(parameter);
unverifiedAllowedParams_1.splice(index, 1);
}
else {
_this.$errors.fail("The parameter %s is not valid for this command.", argument);
}
});
}
return true;
}).future()();
};
CommandsService.prototype.tryMatchCommand = function (commandName) {
var _this = this;
var allCommands = this.allCommands({ includeDevCommands: false });
var similarCommands = [];
_.each(allCommands, function (command) {
if (!_this.$injector.isDefaultCommand(command)) {
command = helpers.stringReplaceAll(command, "|", " ");
var distance = jaroWinklerDistance(commandName, command);
if (commandName.length > 3 && command.indexOf(commandName) !== -1) {
similarCommands.push({ rating: 1, name: command });
}
else if (distance >= 0.65) {
similarCommands.push({ rating: distance, name: command });
}
}
});
similarCommands = _.sortBy(similarCommands, function (command) {
return -command.rating;
}).slice(0, 5);
if (similarCommands.length > 0) {
var message_1 = ["Did you mean?"];
_.each(similarCommands, function (command) {
message_1.push("\t" + command.name);
});
this.$logger.fatal(message_1.join("\n"));
}
};
CommandsService.prototype.completeCommand = function () {
var _this = this;
return (function () {
var tabtab = require("tabtab");
var completeCallback = function (err, data) {
if (err || !data) {
return;
}
var commands = _this.$injector.getRegisteredCommandsNames(false);
var splittedLine = data.line.split(/[ ]+/);
var line = _.filter(splittedLine, function (w) { return w !== ""; });
var commandName = (line[line.length - 2]);
var childrenCommands = _this.$injector.getChildrenCommandsNames(commandName);
if (data.last && _.startsWith(data.last, "--")) {
return tabtab.log(_.keys(_this.$options.options), data, "--");
}
if (data.last && _.startsWith(data.last, "-")) {
return tabtab.log(_this.$options.shorthands, data, "-");
}
if (data.words === 1) {
var allCommands = _this.allCommands({ includeDevCommands: false });
if (_.startsWith(data.last, _this.$commandsServiceProvider.dynamicCommandsPrefix)) {
allCommands = allCommands.concat(_this.$commandsServiceProvider.getDynamicCommands().wait());
}
return tabtab.log(allCommands, data);
}
if (data.words >= 2) {
if (data.words !== line.length) {
commandName = line[data.words - 2] + "|" + line[data.words - 1];
}
else {
commandName = "" + line[line.length - 1];
}
}
var command = _this.$injector.resolveCommand(commandName);
if (command) {
var completionData = command.completionData;
if (completionData) {
return tabtab.log(completionData, data);
}
else {
return _this.logChildrenCommandsNames(commandName, commands, tabtab, data);
}
}
else if (childrenCommands) {
var nonDefaultSubCommands = _.reject(childrenCommands, function (children) { return children[0] === '*'; });
var sanitizedChildrenCommands = [];
if (data.words !== line.length) {
sanitizedChildrenCommands = nonDefaultSubCommands.map(function (commandToMap) {
var pipePosition = commandToMap.indexOf("|");
return commandToMap.substring(0, pipePosition !== -1 ? pipePosition : commandToMap.length);
});
}
else {
nonDefaultSubCommands = nonDefaultSubCommands.filter(function (commandNameToFilter) { return commandNameToFilter.indexOf("|") !== -1; });
sanitizedChildrenCommands = nonDefaultSubCommands.map(function (commandToMap) {
var pipePosition = commandToMap.lastIndexOf("|");
return commandToMap.substring(pipePosition !== -1 ? pipePosition + 1 : 0, commandToMap.length);
});
}
return tabtab.log(sanitizedChildrenCommands, data);
}
else {
return _this.logChildrenCommandsNames(commandName, commands, tabtab, data);
}
};
tabtab.complete(_this.$staticConfig.CLIENT_NAME.toLowerCase(), completeCallback);
if (_this.$staticConfig.CLIENT_NAME_ALIAS) {
tabtab.complete(_this.$staticConfig.CLIENT_NAME_ALIAS.toLowerCase(), completeCallback);
}
return true;
}).future()();
};
CommandsService.prototype.getCommandHelp = function () {
var _this = this;
return (function () {
if (!_this.cachedCommandHelp && _this.$fs.exists(_this.$resources.resolvePath(_this.$staticConfig.COMMAND_HELP_FILE_NAME)).wait()) {
_this.cachedCommandHelp = _this.$resources.readJson(_this.$staticConfig.COMMAND_HELP_FILE_NAME).wait();
}
return _this.cachedCommandHelp;
}).future()();
};
CommandsService.prototype.beautifyCommandName = function (commandName) {
if (commandName.indexOf("*") > 0) {
return commandName.substr(0, commandName.indexOf("|"));
}
return commandName;
};
CommandsService.prototype.logChildrenCommandsNames = function (commandName, commands, tabtab, data) {
var matchingCommands = commands.filter(function (commandToFilter) {
return commandToFilter.indexOf(commandName + "|") !== -1 && commandToFilter !== commandName;
})
.map(function (commandToMap) {
var commandResult = commandToMap.replace(commandName + "|", "");
return commandResult.substring(0, commandResult.indexOf("|") !== -1 ? commandResult.indexOf("|") : commandResult.length);
});
return tabtab.log(matchingCommands, data);
};
CommandsService.HIERARCHICAL_COMMANDS_DELIMITER = "|";
CommandsService.HIERARCHICAL_COMMANDS_DEFAULT_COMMAND_DELIMITER = "|*";
CommandsService.HOOKS_COMMANDS_DELIMITER = "-";
return CommandsService;
}());
exports.CommandsService = CommandsService;
$injector.register("commandsService", CommandsService);