UNPKG

mobile-cli-lib

Version:
391 lines (390 loc) 15.7 kB
"use strict"; var path = require("path"); var helpers_1 = require("./helpers"); var indent = ""; function trace(formatStr) { var args = []; for (var _i = 1; _i < arguments.length; _i++) { args[_i - 1] = arguments[_i]; } } function pushIndent() { indent += " "; } function popIndent() { indent = indent.slice(0, -2); } function forEachName(names, action) { if (_.isString(names)) { action(names); } else { names.forEach(action); } } function register() { var rest = []; for (var _i = 0; _i < arguments.length; _i++) { rest[_i - 0] = arguments[_i]; } return function (target) { $injector.register(rest[0], target); }; } exports.register = register; var Yok = (function () { function Yok() { this.COMMANDS_NAMESPACE = "commands"; this.modules = {}; this.resolutionProgress = {}; this.hierarchicalCommands = {}; this.publicApi = { __modules__: {} }; this.register("injector", this); } Yok.prototype.requireCommand = function (names, file) { var _this = this; forEachName(names, function (commandName) { var commands = commandName.split("|"); if (commands.length > 1) { if (_.startsWith(commands[1], '*') && _this.modules[_this.createCommandName(commands[0])]) { throw new Error("Default commands should be required before child commands"); } var parentCommandName = commands[0]; if (!_this.hierarchicalCommands[parentCommandName]) { _this.hierarchicalCommands[parentCommandName] = []; } _this.hierarchicalCommands[parentCommandName].push(_.tail(commands).join("|")); } if (commands.length > 1 && !_this.modules[_this.createCommandName(commands[0])]) { _this.require(_this.createCommandName(commands[0]), file); if (commands[1] && !commandName.match(/\|\*/)) { _this.require(_this.createCommandName(commandName), file); } } else { _this.require(_this.createCommandName(commandName), file); } }); }; Yok.prototype.require = function (names, file) { var _this = this; forEachName(names, function (name) { return _this.requireOne(name, file); }); }; Yok.prototype.requirePublic = function (names, file) { var _this = this; forEachName(names, function (name) { _this.requireOne(name, file); _this.resolvePublicApi(name, file); }); }; Yok.prototype.requirePublicClass = function (names, file) { var _this = this; forEachName(names, function (name) { _this.requireOne(name, file); _this.addClassToPublicApi(name, file); }); }; Yok.prototype.addClassToPublicApi = function (name, file) { var _this = this; Object.defineProperty(this.publicApi, name, { get: function () { return _this.tryCallInitializeMethod(name); } }); }; Yok.prototype.resolvePublicApi = function (name, file) { var _this = this; Object.defineProperty(this.publicApi, name, { get: function () { _this.tryCallInitializeMethod(name); return _this.publicApi.__modules__[name]; } }); }; Yok.prototype.tryCallInitializeMethod = function (name) { var classInstance = this.modules[name].instance; if (!classInstance) { classInstance = this.resolve(name); if (classInstance.initialize) { var result_1 = classInstance.initialize.apply(classInstance); if (helpers_1.isFuture(result_1)) { var fiberBootstrap = require("./fiber-bootstrap"); fiberBootstrap.run(function () { result_1.wait(); }); } } } return classInstance; }; Yok.prototype.requireOne = function (name, file) { var relativePath = path.join("../", file); var dependency = { require: require("fs").existsSync(path.join(__dirname, relativePath + ".js")) ? relativePath : file, shared: true }; if (!this.modules[name]) { this.modules[name] = dependency; } else { throw new Error("module '" + name + "' require'd twice."); } }; Yok.prototype.registerCommand = function (names, resolver) { var _this = this; forEachName(names, function (name) { var commands = name.split("|"); _this.register(_this.createCommandName(name), resolver); if (commands.length > 1) { _this.createHierarchicalCommand(commands[0]); } }); }; Yok.prototype.getDefaultCommand = function (name) { var subCommands = this.hierarchicalCommands[name]; var defaultCommand = _.find(subCommands, function (command) { return _.startsWith(command, "*"); }); return defaultCommand; }; Yok.prototype.buildHierarchicalCommand = function (parentCommandName, commandLineArguments) { var _this = this; var currentSubCommandName, finalSubCommandName, matchingSubCommandName; var subCommands = this.hierarchicalCommands[parentCommandName]; var remainingArguments = commandLineArguments; var finalRemainingArguments = commandLineArguments; var foundSubCommand = false; _.each(commandLineArguments, function (arg) { arg = arg.toLowerCase(); currentSubCommandName = currentSubCommandName ? _this.getHierarchicalCommandName(currentSubCommandName, arg) : arg; remainingArguments = _.tail(remainingArguments); if (matchingSubCommandName = _.find(subCommands, function (sc) { return sc === currentSubCommandName || sc === "*" + currentSubCommandName; })) { finalSubCommandName = matchingSubCommandName; finalRemainingArguments = remainingArguments; foundSubCommand = true; } }); if (foundSubCommand) { return { commandName: this.getHierarchicalCommandName(parentCommandName, finalSubCommandName), remainingArguments: finalRemainingArguments }; } return undefined; }; Yok.prototype.createHierarchicalCommand = function (name) { var _this = this; var factory = function () { return { execute: function (args) { return (function () { var commandsService = $injector.resolve("commandsService"); var commandName = null; var defaultCommand = _this.getDefaultCommand(name); var commandArguments = []; if (args.length > 0) { var hierarchicalCommand = _this.buildHierarchicalCommand(name, args); if (hierarchicalCommand) { commandName = hierarchicalCommand.commandName; commandArguments = hierarchicalCommand.remainingArguments; } else { commandName = defaultCommand ? _this.getHierarchicalCommandName(name, defaultCommand) : "help"; if (_.includes(_this.hierarchicalCommands[name], "*" + args[0])) { commandArguments = _.tail(args); } else { commandArguments = args; } } } else { if (defaultCommand) { commandName = _this.getHierarchicalCommandName(name, defaultCommand); } else { commandName = "help"; var options = _this.resolve("options"); options.help = true; } } commandsService.tryExecuteCommand(commandName, commandName === "help" ? [name] : commandArguments).wait(); }).future()(); } }; }; $injector.registerCommand(name, factory); }; Yok.prototype.getHierarchicalCommandName = function (parentCommandName, subCommandName) { return [parentCommandName, subCommandName].join("|"); }; Yok.prototype.isValidHierarchicalCommand = function (commandName, commandArguments) { if (_.includes(Object.keys(this.hierarchicalCommands), commandName)) { var defaultCommandName = this.getDefaultCommand(commandName); if (defaultCommandName && (!commandArguments || commandArguments.length === 0)) { return true; } var subCommands = this.hierarchicalCommands[commandName]; if (subCommands) { var fullCommandName = this.buildHierarchicalCommand(commandName, commandArguments); if (!fullCommandName) { var defaultCommand = this.resolveCommand(commandName + "|" + defaultCommandName); if (defaultCommand) { if (defaultCommand.canExecute) { return defaultCommand.canExecute(commandArguments).wait(); } if (defaultCommand.allowedParameters.length > 0) { return true; } } var errors = $injector.resolve("errors"); errors.fail("The input is not valid sub-command for '%s' command", commandName); } return true; } } return false; }; Yok.prototype.isDefaultCommand = function (commandName) { return commandName.indexOf("*") > 0 && commandName.indexOf("|") > 0; }; Yok.prototype.register = function (name, resolver, shared) { if (shared === void 0) { shared = true; } trace("registered '%s'", name); var dependency = this.modules[name] || {}; dependency.shared = shared; if (_.isFunction(resolver)) { dependency.resolver = resolver; } else { dependency.instance = resolver; } this.modules[name] = dependency; }; Yok.prototype.resolveCommand = function (name) { var command; var commandModuleName = this.createCommandName(name); if (!this.modules[commandModuleName]) { return null; } command = this.resolve(commandModuleName); return command; }; Yok.prototype.resolve = function (param, ctorArguments) { if (_.isFunction(param)) { return this.resolveConstructor(param, ctorArguments); } else { return this.resolveByName(param, ctorArguments); } }; Object.defineProperty(Yok.prototype, "dynamicCallRegex", { get: function () { return /#{([^.]+)\.([^}]+?)(\((.+)\))*}/; }, enumerable: true, configurable: true }); Yok.prototype.dynamicCall = function (call, args) { var _this = this; return (function () { var parsed = call.match(_this.dynamicCallRegex); var module = _this.resolve(parsed[1]); if (!args && parsed[3]) { args = _.map(parsed[4].split(","), function (arg) { return arg.trim(); }); } var data = module[parsed[2]].apply(module, args); if (helpers_1.isFuture(data)) { return data.wait(); } return data; }).future()(); }; Yok.prototype.resolveConstructor = function (ctor, ctorArguments) { var _this = this; helpers_1.annotate(ctor); var resolvedArgs = ctor.$inject.args.map(function (paramName) { if (ctorArguments && ctorArguments.hasOwnProperty(paramName)) { return ctorArguments[paramName]; } else { return _this.resolve(paramName); } }); var name = ctor.$inject.name; if (name && name[0] === name[0].toUpperCase()) { var EmptyCtor = function () { }; EmptyCtor.prototype = ctor.prototype; var obj = new EmptyCtor(); ctor.apply(obj, resolvedArgs); return obj; } else { return ctor.apply(null, resolvedArgs); } }; Yok.prototype.resolveByName = function (name, ctorArguments) { if (name[0] === "$") { name = name.substr(1); } if (this.resolutionProgress[name]) { throw new Error("Cyclic dependency detected on dependency '" + name + "'"); } this.resolutionProgress[name] = true; trace("resolving '%s'", name); pushIndent(); var dependency; try { dependency = this.resolveDependency(name); if (!dependency) { throw new Error("unable to resolve " + name); } if (!dependency.instance || !dependency.shared) { if (!dependency.resolver) { throw new Error("no resolver registered for " + name); } dependency.instance = this.resolveConstructor(dependency.resolver, ctorArguments); } } finally { popIndent(); delete this.resolutionProgress[name]; } return dependency.instance; }; Yok.prototype.resolveDependency = function (name) { var module = this.modules[name]; if (!module) { throw new Error("unable to resolve " + name); } if (module.require) { require(module.require); } return module; }; Yok.prototype.getRegisteredCommandsNames = function (includeDev) { var _this = this; var modulesNames = _.keys(this.modules); var commandsNames = _.filter(modulesNames, function (moduleName) { return _.startsWith(moduleName, _this.COMMANDS_NAMESPACE + "."); }); var commands = _.map(commandsNames, function (commandName) { return commandName.substr(_this.COMMANDS_NAMESPACE.length + 1); }); if (!includeDev) { commands = _.reject(commands, function (command) { return _.startsWith(command, "dev-"); }); } return commands; }; Yok.prototype.getChildrenCommandsNames = function (commandName) { return this.hierarchicalCommands[commandName]; }; Yok.prototype.createCommandName = function (name) { return this.COMMANDS_NAMESPACE + "." + name; }; Yok.prototype.dispose = function () { var _this = this; Object.keys(this.modules).forEach(function (moduleName) { var instance = _this.modules[moduleName].instance; if (instance && instance.dispose && instance !== _this) { instance.dispose(); } }); }; return Yok; }()); exports.Yok = Yok; exports.injector = new Yok();