#!/usr/bin/env node
"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());
    });
};
process
    .once('SIGINT', () => process.exit(1))
    .once('SIGTERM', () => process.exit(1));
// Patch the global fs module here at the app level
const fs = require("fs");
const gfs = require("graceful-fs");
gfs.gracefulify(fs);
const loudRejection = require("loud-rejection");
loudRejection();
const logger_1 = require("@pnpm/logger");
const camelcase = require("camelcase");
const isCI = require("is-ci");
const nopt = require("nopt");
const npm = require("not-bundled-npm");
const npmDefaults = require("not-bundled-npm/lib/config/defaults");
const path = require("path");
const R = require("ramda");
const checkForUpdates_1 = require("../checkForUpdates");
const pnpmCmds = require("../cmd");
const runNpm_1 = require("../cmd/runNpm");
const getCommandFullName_1 = require("../getCommandFullName");
require("../logging/fileLogger");
const pnpmPkgJson_1 = require("../pnpmPkgJson");
const reporter_1 = require("../reporter");
pnpmCmds['install-test'] = pnpmCmds.installTest;
const supportedCmds = new Set([
    'add',
    'install',
    'uninstall',
    'update',
    'link',
    'prune',
    'install-test',
    'run',
    'server',
    'store',
    'list',
    'dislink',
    'help',
    'root',
    'outdated',
    'rebuild',
    'recursive',
]);
const passedThroughCmds = new Set([
    'access',
    'adduser',
    'bin',
    'bugs',
    'c',
    'config',
    'deprecate',
    'dist-tag',
    'docs',
    'edit',
    'get',
    'info',
    'init',
    'login',
    'logout',
    'owner',
    'pack',
    'ping',
    'prefix',
    'profile',
    'publish',
    'repo',
    'restart',
    's',
    'se',
    'search',
    'set',
    'star',
    'stars',
    'start',
    'stop',
    'team',
    't',
    'tst',
    'test',
    'token',
    'unpublish',
    'unstar',
    'v',
    'version',
    'view',
    'whoami',
    'xmas',
]);
function run(argv) {
    return __awaiter(this, void 0, void 0, function* () {
        if (argv.indexOf('--help') !== -1 || argv.indexOf('-h') !== -1 || argv.indexOf('--h') !== -1) {
            argv = ['help'].concat(argv);
        }
        const pnpmTypes = {
            'background': Boolean,
            'child-concurrency': Number,
            'fetching-concurrency': Number,
            'global-path': path,
            'ignore-pnpmfile': Boolean,
            'ignore-stop-requests': Boolean,
            'ignore-upload-requests': Boolean,
            'independent-leaves': Boolean,
            'lock': Boolean,
            'lock-stale-duration': Number,
            'network-concurrency': Number,
            'offline': Boolean,
            'package-import-method': ['auto', 'hardlink', 'reflink', 'copy'],
            'pending': Boolean,
            'port': Number,
            'prefer-offline': Boolean,
            'protocol': ['auto', 'tcp', 'ipc'],
            'reporter': String,
            'shrinkwrap-only': Boolean,
            'side-effects-cache': Boolean,
            'side-effects-cache-readonly': Boolean,
            'store': path,
            'store-path': path,
            'use-store-server': Boolean,
            'verify-store-integrity': Boolean,
        };
        const types = R.merge(npmDefaults.types, pnpmTypes);
        const cliConf = nopt(types, npmDefaults.shorthands, argv, 0);
        if (cliConf.version) {
            console.log(pnpmPkgJson_1.default.version);
            return;
        }
        if (!isCI) {
            checkForUpdates_1.default();
        }
        let cmd = getCommandFullName_1.default(cliConf.argv.remain[0]) || 'help';
        if (!supportedCmds.has(cmd)) {
            if (passedThroughCmds.has(cmd)) {
                runNpm_1.default(argv);
                return Promise.resolve();
            }
            cmd = 'help';
        }
        if (cliConf['dry-run']) {
            console.error(`Error: 'dry-run' is not supported yet, sorry!`);
            process.exit(1);
        }
        cliConf.save = cliConf.save || !cliConf.saveDev && !cliConf.saveOptional;
        if (!cliConf['user-agent']) {
            cliConf['user-agent'] = `${pnpmPkgJson_1.default.name}/${pnpmPkgJson_1.default.version} npm/? node/${process.version} ${process.platform} ${process.arch}`;
        }
        const force = cliConf.force === true;
        // removing force to avoid redundant logs from npm
        // see issue #878 and #877
        delete cliConf.force;
        yield new Promise((resolve, reject) => {
            npm.load(cliConf, (err) => {
                if (err) {
                    reject(err);
                    return;
                }
                resolve();
            });
        });
        const opts = R.fromPairs(R.keys(types).map(configKey => [camelcase(configKey), npm.config.get(configKey)])); // tslint:disable-line
        opts.rawNpmConfig = Object.assign.apply(Object, npm.config.list.reverse());
        opts.bin = npm.bin;
        opts.globalBin = npm.globalBin;
        opts.globalPrefix = path.join(npm.globalPrefix, 'pnpm-global');
        opts.prefix = opts.global ? opts.globalPrefix : npm.prefix;
        opts.packageManager = pnpmPkgJson_1.default;
        opts.force = force;
        if (opts.only === 'prod' || opts.only === 'production' || !opts.only && opts.production) {
            opts.production = true;
            opts.development = false;
        }
        else if (opts.only === 'dev' || opts.only === 'development') {
            opts.production = false;
            opts.development = true;
            opts.optional = false;
        }
        else {
            opts.production = true;
            opts.development = true;
        }
        if (!opts.packageLock && opts.shrinkwrap) {
            opts.shrinkwrap = false;
        }
        const reporterType = (() => {
            if (npm.config.get('loglevel') === 'silent')
                return 'silent';
            if (opts.reporter)
                return opts.reporter;
            if (isCI || !process.stdout.isTTY)
                return 'append-only';
            return 'default';
        })();
        reporter_1.default(reporterType, cmd); // tslint:disable-line
        delete opts.reporter; // This is a silly workaround because supi expects a function as opts.reporter
        // NOTE: we defer the next stage, otherwise reporter might not catch all the logs
        yield new Promise((resolve, reject) => {
            setTimeout(() => {
                if (opts.storePath && !opts.store) {
                    logger_1.default.warn('the `store-path` config is deprecated. Use `store` instead.');
                    opts.store = opts.storePath;
                }
                // `pnpm install ""` is going to be just `pnpm install`
                const cliArgs = cliConf.argv.remain.slice(1).filter(Boolean);
                try {
                    const result = pnpmCmds[cmd](cliArgs, opts, cliConf.argv.remain[0]);
                    if (result instanceof Promise) {
                        result
                            .then(resolve)
                            .catch(reject);
                    }
                    else {
                        resolve();
                    }
                }
                catch (err) {
                    reject(err);
                }
            }, 0);
        });
        logger_1.default('cli').debug('command_done');
    });
}
const err_1 = require("../err");
if (!module.parent)
    run(process.argv.slice(2)).catch(err_1.default);
module.exports = run;
//# sourceMappingURL=pnpm.js.map