"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    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) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
const utils_1 = require("@pnpm/utils");
const supi_1 = require("supi");
const createStoreController_1 = require("../createStoreController");
const findWorkspacePackages_1 = require("../findWorkspacePackages");
const getPinnedVersion_1 = require("../getPinnedVersion");
const requireHooks_1 = require("../requireHooks");
const recursive_1 = require("./recursive");
const OVERWRITE_UPDATE_OPTIONS = {
    allowNew: true,
    update: false,
};
/**
 * Perform installation.
 * @example
 *     installCmd([ 'lodash', 'foo' ], { silent: true })
 */
function installCmd(input, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        // `pnpm install ""` is going to be just `pnpm install`
        input = input.filter(Boolean);
        const prefix = opts.prefix || process.cwd();
        const localPackages = opts.linkWorkspacePackages && opts.workspacePrefix
            ? findWorkspacePackages_1.arrayOfLocalPackagesToMap(yield findWorkspacePackages_1.default(opts.workspacePrefix))
            : undefined;
        if (!opts.ignorePnpmfile) {
            opts.hooks = requireHooks_1.default(prefix, opts);
        }
        const store = yield createStoreController_1.default(opts);
        const installOpts = Object.assign({}, opts, { 
            // In case installation is done in a multi-package repository
            // The dependencies should be built first,
            // so ignoring scripts for now
            ignoreScripts: !!localPackages || opts.ignoreScripts, localPackages, pinnedVersion: getPinnedVersion_1.default(opts), store: store.path, storeController: store.ctrl });
        if (!input || !input.length) {
            yield supi_1.install(installOpts);
        }
        else {
            yield supi_1.mutateModules([
                {
                    bin: installOpts.bin,
                    dependencySelectors: input,
                    mutation: 'installSome',
                    prefix: installOpts.prefix,
                    targetDependenciesField: utils_1.getSaveType(installOpts),
                },
            ], installOpts);
        }
        if (opts.linkWorkspacePackages && opts.workspacePrefix) {
            // TODO: reuse somehow the previous read of packages
            // this is not optimal
            const allWorkspacePkgs = yield findWorkspacePackages_1.default(opts.workspacePrefix);
            yield recursive_1.recursive(allWorkspacePkgs, [], Object.assign({}, opts, OVERWRITE_UPDATE_OPTIONS, { ignoredPackages: new Set([prefix]), packageSelectors: [
                    {
                        matcher: prefix,
                        scope: 'dependencies',
                        selectBy: 'location',
                    },
                ] }), 'install', 'install');
            if (opts.ignoreScripts)
                return;
            yield supi_1.rebuild(Object.assign({}, opts, { pending: true })); // tslint:disable-line:no-any
        }
    });
}
exports.default = installCmd;
//# sourceMappingURL=install.js.map