"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.BasePackageManager = void 0;
const helpers_1 = require("./common/helpers");
class BasePackageManager {
    constructor($childProcess, $fs, $hostInfo, $pacoteService, packageManager) {
        this.$childProcess = $childProcess;
        this.$fs = $fs;
        this.$hostInfo = $hostInfo;
        this.$pacoteService = $pacoteService;
        this.packageManager = packageManager;
    }
    isRegistered(packageName) {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.isURL(packageName) ||
                this.$fs.exists(packageName) ||
                this.isTgz(packageName)) {
                return false;
            }
            try {
                const viewResult = yield this.view(packageName, { name: true });
                // `npm view nonExistingPackageName` will return `nativescript`
                // if executed in the root dir of the CLI (npm 6.4.1)
                const packageNameRegex = new RegExp(packageName, "i");
                const isProperResult = packageNameRegex.test(viewResult);
                return isProperResult;
            }
            catch (e) {
                return false;
            }
        });
    }
    getPackageNameParts(fullPackageName) {
        return __awaiter(this, void 0, void 0, function* () {
            // support <reserved_name>@<version> syntax, for example typescript@1.0.0
            // support <scoped_package_name>@<version> syntax, for example @nativescript/vue-template@1.0.0
            const lastIndexOfAtSign = fullPackageName.lastIndexOf("@");
            let version = "";
            let templateName = "";
            if (lastIndexOfAtSign > 0) {
                templateName = fullPackageName.substr(0, lastIndexOfAtSign).toLowerCase();
                version = fullPackageName.substr(lastIndexOfAtSign + 1);
            }
            return {
                name: templateName || fullPackageName,
                version: version,
            };
        });
    }
    getPackageFullName(packageNameParts) {
        return __awaiter(this, void 0, void 0, function* () {
            return packageNameParts.version
                ? `${packageNameParts.name}@${packageNameParts.version}`
                : packageNameParts.name;
        });
    }
    getPackageManagerExecutableName() {
        let npmExecutableName = this.packageManager;
        if (this.$hostInfo.isWindows) {
            npmExecutableName += ".cmd";
        }
        return npmExecutableName;
    }
    processPackageManagerInstall(packageName, params, opts) {
        return __awaiter(this, void 0, void 0, function* () {
            const npmExecutable = this.getPackageManagerExecutableName();
            const stdioValue = (0, helpers_1.isInteractive)() ? "inherit" : "pipe";
            const sanitizedNpmExecutable = this.$hostInfo.isWindows
                ? (0, helpers_1.quoteString)(npmExecutable)
                : npmExecutable;
            yield this.$childProcess.spawnFromEvent(sanitizedNpmExecutable, params, "close", {
                cwd: opts.cwd,
                stdio: stdioValue,
                shell: this.$hostInfo.isWindows,
            });
            // Whenever calling "npm install" or "yarn add" without any arguments (hence installing all dependencies) no output is emitted on stdout
            // Luckily, whenever you call "npm install" or "yarn add" to install all dependencies chances are you won't need the name/version of the package you're installing because there is none.
            const { isInstallingAllDependencies } = opts;
            if (isInstallingAllDependencies) {
                return null;
            }
            const packageMetadata = yield this.$pacoteService.manifest(packageName);
            return {
                name: packageMetadata.name,
                version: packageMetadata.version,
            };
        });
    }
    getFlagsString(config, asArray) {
        const array = [];
        for (const flag in config) {
            if (flag === "global" &&
                this.packageManager !== "yarn" &&
                this.packageManager !== "yarn2") {
                array.push(`--${flag}`);
                array.push(`${config[flag]}`);
            }
            else if (config[flag]) {
                if (flag === "dist-tags" ||
                    flag === "versions" ||
                    flag === "name" ||
                    flag === "gradle" ||
                    flag === "version_info") {
                    if (this.packageManager === "yarn2") {
                        array.push(`--fields ${flag}`);
                    }
                    else {
                        array.push(` ${flag}`);
                    }
                    continue;
                }
                array.push(`--${flag}`);
            }
        }
        if (asArray) {
            return array;
        }
        return array.join(" ");
    }
    isTgz(packageName) {
        return packageName.indexOf(".tgz") >= 0;
    }
    isURL(str) {
        const urlRegex = "^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$";
        const url = new RegExp(urlRegex, "i");
        return str.length < 2083 && url.test(str);
    }
}
exports.BasePackageManager = BasePackageManager;
//# sourceMappingURL=base-package-manager.js.map