mobile-cli-lib
Version:
common lib used by different CLI
336 lines (335 loc) • 16.8 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var path = require("path");
var os = require("os");
var constants = require("../../constants");
var helpers_1 = require("../../helpers");
var decorators_1 = require("../../decorators");
var url = require("url");
var NpmService = (function () {
function NpmService($childProcess, $errors, $fs, $hostInfo, $httpClient, $logger, $projectConstants) {
this.$childProcess = $childProcess;
this.$errors = $errors;
this.$fs = $fs;
this.$hostInfo = $hostInfo;
this.$httpClient = $httpClient;
this.$logger = $logger;
this.$projectConstants = $projectConstants;
this._hasCheckedNpmProxy = false;
}
Object.defineProperty(NpmService.prototype, "npmExecutableName", {
get: function () {
if (!this._npmExecutableName) {
this._npmExecutableName = "npm";
if (this.$hostInfo.isWindows) {
this._npmExecutableName += ".cmd";
}
}
return this._npmExecutableName;
},
enumerable: true,
configurable: true
});
NpmService.prototype.install = function (projectDir, dependencyToInstall) {
var _this = this;
return (function () {
var npmInstallResult = {};
if (dependencyToInstall) {
npmInstallResult.result = {
isInstalled: false,
isTypesInstalled: false
};
try {
_this.npmInstall(projectDir, dependencyToInstall.name, dependencyToInstall.version, ["--save", "--save-exact"]).wait();
npmInstallResult.result.isInstalled = true;
}
catch (err) {
npmInstallResult.error = err;
}
if (dependencyToInstall.installTypes && npmInstallResult.result.isInstalled && _this.hasTypesForDependency(dependencyToInstall.name).wait()) {
try {
_this.installTypingsForDependency(projectDir, dependencyToInstall.name).wait();
npmInstallResult.result.isTypesInstalled = true;
}
catch (err) {
npmInstallResult.error = err;
}
}
}
else {
try {
_this.npmPrune(projectDir).wait();
_this.npmInstall(projectDir).wait();
}
catch (err) {
npmInstallResult.error = err;
}
}
_this.generateReferencesFile(projectDir).wait();
return npmInstallResult;
}).future()();
};
NpmService.prototype.uninstall = function (projectDir, dependency) {
var _this = this;
return (function () {
var packageJsonContent = _this.getPackageJsonContent(projectDir).wait();
if (packageJsonContent && packageJsonContent.dependencies && packageJsonContent.dependencies[dependency]) {
_this.npmUninstall(projectDir, dependency, ["--save"]).wait();
}
if (packageJsonContent && packageJsonContent.devDependencies && packageJsonContent.devDependencies[("" + NpmService.TYPES_DIRECTORY + dependency)]) {
_this.npmUninstall(projectDir, "" + NpmService.TYPES_DIRECTORY + dependency, ["--save-dev"]).wait();
}
_this.generateReferencesFile(projectDir).wait();
}).future()();
};
NpmService.prototype.search = function (projectDir, keywords, args) {
var _this = this;
if (args === void 0) { args = []; }
return (function () {
var result = [];
var commandArguments = _.concat(["search"], args, keywords);
var spawnResult = _this.executeNpmCommandCore(projectDir, commandArguments).wait();
if (spawnResult.stderr) {
var splitError = spawnResult.stderr.trim().split("\n");
if (splitError.length > 1 || splitError[0].indexOf("Building the local index for the first time") === -1) {
_this.$errors.failWithoutHelp(spawnResult.stderr);
}
}
var pluginsRows = spawnResult.stdout.split("\n");
pluginsRows.shift();
var npmNameGroup = "(\\S+)";
var npmDateGroup = "(\\d+-\\d+-\\d+)\\s";
var npmFreeTextGroup = "([^=]+)";
var npmAuthorsGroup = "((?:=\\S+\\s?)+)\\s+";
var pluginRowRegExp = new RegExp(npmNameGroup + "\\s+" + npmFreeTextGroup + npmAuthorsGroup + npmDateGroup + npmNameGroup + "(\\s+" + npmFreeTextGroup + ")?");
_.each(pluginsRows, function (pluginRow) {
var matches = pluginRowRegExp.exec(pluginRow.trim());
if (!matches || !matches[0]) {
return;
}
result.push({
name: matches[1],
description: matches[2],
author: matches[3],
version: matches[5]
});
});
return result;
}).future()();
};
NpmService.prototype.getPackageJsonFromNpmRegistry = function (packageName, version) {
var _this = this;
return (function () {
var timeout = 6000;
var packageJsonContent;
version = version || "latest";
try {
var url_1 = _this.buildNpmRegistryUrl(packageName, version).wait(), proxySettings = _this.getNpmProxySettings().wait();
var result = _this.$httpClient.httpRequest({ url: url_1, timeout: timeout }, proxySettings).wait().body;
packageJsonContent = JSON.parse(result);
}
catch (err) {
_this.$logger.trace("Error caught while checking the NPM Registry for plugin with id: %s", packageName);
_this.$logger.trace(err.message);
}
return packageJsonContent;
}).future()();
};
NpmService.prototype.isScopedDependency = function (dependency) {
var matches = dependency.match(NpmService.SCOPED_DEPENDENCY_REGEXP);
return !!(matches && matches[0]);
};
NpmService.prototype.getDependencyInformation = function (dependency) {
var regExp = this.isScopedDependency(dependency) ? NpmService.SCOPED_DEPENDENCY_REGEXP : NpmService.DEPENDENCY_REGEXP;
var matches = dependency.match(regExp);
return {
name: matches[1],
version: matches[2]
};
};
NpmService.prototype.hasTypesForDependency = function (packageName) {
var _this = this;
return (function () {
return !!_this.getPackageJsonFromNpmRegistry("" + NpmService.TYPES_DIRECTORY + packageName).wait();
}).future()();
};
NpmService.prototype.buildNpmRegistryUrl = function (packageName, version) {
var _this = this;
return (function () {
var registryUrl = _this.getNpmRegistryUrl().wait();
if (!_.endsWith(registryUrl, "/")) {
registryUrl += "/";
}
return "" + registryUrl + packageName.replace("/", "%2F") + "?version=" + encodeURIComponent(version);
}).future()();
};
NpmService.prototype.getNpmRegistryUrl = function () {
var _this = this;
return (function () {
if (!_this._npmRegistryUrl) {
var currentNpmRegistry = void 0;
try {
currentNpmRegistry = (_this.$childProcess.exec("npm config get registry").wait() || "").toString().trim();
}
catch (err) {
_this.$logger.trace("Unable to get registry from npm config. Error is " + err.message + ".");
}
_this._npmRegistryUrl = currentNpmRegistry || NpmService.NPM_REGISTRY_URL;
_this.$logger.trace("Npm registry is: " + _this._npmRegistryUrl + ".");
}
return _this._npmRegistryUrl;
}).future()();
};
NpmService.prototype.getPackageJsonContent = function (projectDir) {
var _this = this;
return (function () {
var pathToPackageJson = _this.getPathToPackageJson(projectDir);
try {
return _this.$fs.readJson(pathToPackageJson).wait();
}
catch (err) {
if (err.code === "ENOENT") {
_this.$errors.failWithoutHelp("Unable to find " + _this.$projectConstants.PACKAGE_JSON_NAME + " in " + projectDir + ".");
}
throw err;
}
}).future()();
};
NpmService.prototype.getPathToPackageJson = function (projectDir) {
return path.join(projectDir, this.$projectConstants.PACKAGE_JSON_NAME);
};
NpmService.prototype.getPathToReferencesFile = function (projectDir) {
return path.join(projectDir, this.$projectConstants.REFERENCES_FILE_NAME);
};
NpmService.prototype.installTypingsForDependency = function (projectDir, dependency) {
return this.npmInstall(projectDir, "" + NpmService.TYPES_DIRECTORY + dependency, null, ["--save-dev", "--save-exact"]);
};
NpmService.prototype.generateReferencesFile = function (projectDir) {
var _this = this;
return (function () {
var packageJsonContent = _this.getPackageJsonContent(projectDir).wait();
var pathToReferenceFile = _this.getPathToReferencesFile(projectDir), lines = [];
if (packageJsonContent && packageJsonContent.dependencies && packageJsonContent.dependencies[constants.TNS_CORE_MODULES]) {
var relativePathToTnsCoreModulesDts = "./" + constants.NODE_MODULES_DIR_NAME + "/" + constants.TNS_CORE_MODULES + "/" + NpmService.TNS_CORE_MODULES_DEFINITION_FILE_NAME;
if (_this.$fs.exists(path.join(projectDir, relativePathToTnsCoreModulesDts)).wait()) {
lines.push(_this.getReferenceLine(relativePathToTnsCoreModulesDts));
}
}
_(packageJsonContent.devDependencies)
.keys()
.each(function (devDependency) {
if (_this.isFromTypesRepo(devDependency)) {
var nodeModulesDirectory = path.join(projectDir, constants.NODE_MODULES_DIR_NAME);
var definitionFiles = _this.$fs.enumerateFilesInDirectorySync(path.join(nodeModulesDirectory, devDependency), function (file, stat) { return _.endsWith(file, constants.FileExtensions.TYPESCRIPT_DEFINITION_FILE) || stat.isDirectory(); }, { enumerateDirectories: false });
var defs = _.map(definitionFiles, function (def) { return _this.getReferenceLine(helpers_1.fromWindowsRelativePathToUnix(path.relative(projectDir, def))); });
_this.$logger.trace("Adding lines for definition files: " + definitionFiles.join(", "));
lines.push.apply(lines, defs);
}
});
if (lines.length) {
_this.$logger.trace("Updating reference file with new entries...");
_this.$fs.writeFile(pathToReferenceFile, lines.join(os.EOL), "utf8").wait();
_this.removeOldAbReferencesFile(projectDir).wait();
}
else {
_this.$logger.trace("Could not find any .d.ts files for " + _this.$projectConstants.REFERENCES_FILE_NAME + " file. Deleting the old file.");
_this.$fs.deleteFile(pathToReferenceFile).wait();
}
}).future()();
};
NpmService.prototype.removeOldAbReferencesFile = function (projectDir) {
var _this = this;
return (function () {
var pathToOldReferencesFile = path.join(projectDir, _this.$projectConstants.OLD_REFERENCES_FILE_NAME);
if (_this.$fs.exists(pathToOldReferencesFile).wait()) {
_this.$fs.deleteFile(pathToOldReferencesFile).wait();
}
}).future()();
};
NpmService.prototype.isFromTypesRepo = function (dependency) {
return !!dependency.match(/^\//);
};
NpmService.prototype.getReferenceLine = function (pathToReferencedFile) {
return "/// <reference path=\"" + pathToReferencedFile + "\" />";
};
NpmService.prototype.getNpmArguments = function (command, npmArguments) {
if (npmArguments === void 0) { npmArguments = []; }
return npmArguments.concat([command]);
};
NpmService.prototype.npmInstall = function (projectDir, dependency, version, npmArguments) {
return this.executeNpmCommand(projectDir, this.getNpmArguments("install", npmArguments), dependency, version);
};
NpmService.prototype.npmUninstall = function (projectDir, dependency, npmArguments) {
return this.executeNpmCommand(projectDir, this.getNpmArguments("uninstall", npmArguments), dependency, null);
};
NpmService.prototype.npmPrune = function (projectDir, dependency, version) {
return this.executeNpmCommand(projectDir, this.getNpmArguments("prune"), dependency, version);
};
NpmService.prototype.executeNpmCommand = function (projectDir, npmArguments, dependency, version) {
var _this = this;
return (function () {
if (dependency) {
var dependencyToInstall = dependency;
if (version) {
dependencyToInstall += "@" + version;
}
npmArguments.push(dependencyToInstall);
}
return _this.executeNpmCommandCore(projectDir, npmArguments).wait();
}).future()();
};
NpmService.prototype.executeNpmCommandCore = function (projectDir, npmArguments) {
return this.$childProcess.spawnFromEvent(this.npmExecutableName, npmArguments, "close", { cwd: projectDir, stdio: "inherit" });
};
NpmService.prototype.getNpmProxySettings = function () {
var _this = this;
return (function () {
if (!_this._hasCheckedNpmProxy) {
try {
var npmProxy = (_this.$childProcess.exec("npm config get proxy").wait() || "").toString().trim();
if (npmProxy && npmProxy !== "null") {
var uri = url.parse(npmProxy);
_this._proxySettings = {
hostname: uri.hostname,
port: uri.port
};
}
}
catch (err) {
_this.$logger.trace("Unable to get npm proxy configuration. Error is: " + err.message + ".");
}
_this.$logger.trace("Npm proxy is: ", _this._proxySettings);
_this._hasCheckedNpmProxy = true;
}
return _this._proxySettings;
}).future()();
};
NpmService.TYPES_DIRECTORY = "@types/";
NpmService.TNS_CORE_MODULES_DEFINITION_FILE_NAME = "" + constants.TNS_CORE_MODULES + constants.FileExtensions.TYPESCRIPT_DEFINITION_FILE;
NpmService.NPM_REGISTRY_URL = "http://registry.npmjs.org";
NpmService.SCOPED_DEPENDENCY_REGEXP = /^(@.+?)(?:@(.+?))?$/;
NpmService.DEPENDENCY_REGEXP = /^(.+?)(?:@(.+?))?$/;
__decorate([
decorators_1.exportedPromise("npmService"),
__metadata('design:type', Function),
__metadata('design:paramtypes', [String, Object]),
__metadata('design:returntype', Object)
], NpmService.prototype, "install", null);
__decorate([
decorators_1.exportedPromise("npmService"),
__metadata('design:type', Function),
__metadata('design:paramtypes', [String, String]),
__metadata('design:returntype', Object)
], NpmService.prototype, "uninstall", null);
return NpmService;
}());
exports.NpmService = NpmService;
$injector.register("npmService", NpmService);