"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 logger_1 = require("@pnpm/logger");
const npm_resolver_1 = require("@pnpm/npm-resolver");
const dp = require("dependency-path");
const package_store_1 = require("package-store");
const pnpm_shrinkwrap_1 = require("pnpm-shrinkwrap");
const depTypes = ['dependencies', 'devDependencies', 'optionalDependencies'];
function default_1(pkgPath, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        return _outdated([], pkgPath, opts);
    });
}
exports.default = default_1;
function forPackages(packages, pkgPath, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        return _outdated(packages, pkgPath, opts);
    });
}
exports.forPackages = forPackages;
function _outdated(forPkgs, pkgPath, opts) {
    return __awaiter(this, void 0, void 0, function* () {
        const wantedShrinkwrap = yield pnpm_shrinkwrap_1.readWanted(pkgPath, { ignoreIncompatible: false });
        if (!wantedShrinkwrap) {
            throw new Error('No shrinkwrapfile in this directory. Run `pnpm install` to generate one.');
        }
        const storePath = yield package_store_1.resolveStore(opts.store, pkgPath);
        const currentShrinkwrap = (yield pnpm_shrinkwrap_1.readCurrent(pkgPath, { ignoreIncompatible: false })) || {};
        const resolve = npm_resolver_1.default({
            fetchRetries: opts.fetchRetries,
            fetchRetryFactor: opts.fetchRetryFactor,
            fetchRetryMaxtimeout: opts.fetchRetryMaxtimeout,
            fetchRetryMintimeout: opts.fetchRetryMintimeout,
            metaCache: new Map(),
            offline: opts.offline,
            rawNpmConfig: opts.rawNpmConfig,
            store: storePath,
        });
        const outdated = [];
        yield Promise.all(depTypes.map((depType) => __awaiter(this, void 0, void 0, function* () {
            if (!wantedShrinkwrap[depType])
                return;
            let pkgs = Object.keys(wantedShrinkwrap[depType]);
            if (forPkgs.length) {
                pkgs = pkgs.filter((pkgName) => forPkgs.indexOf(pkgName) !== -1);
            }
            yield Promise.all(pkgs.map((packageName) => __awaiter(this, void 0, void 0, function* () {
                const ref = wantedShrinkwrap[depType][packageName];
                const relativeDepPath = dp.refToRelative(ref, packageName);
                const pkgSnapshot = wantedShrinkwrap.packages && wantedShrinkwrap.packages[relativeDepPath];
                if (!pkgSnapshot) {
                    throw new Error(`Invalid shrinkwrap.yaml file. ${relativeDepPath} not found in packages field`);
                }
                // It might be not the best solution to check for pkgSnapshot.name
                // TODO: add some other field to distinct packages not from the registry
                if (pkgSnapshot.resolution && (pkgSnapshot.resolution['type'] || pkgSnapshot.name)) {
                    if (currentShrinkwrap[depType][packageName] !== wantedShrinkwrap[depType][packageName]) {
                        outdated.push({
                            current: currentShrinkwrap[depType][packageName],
                            latest: undefined,
                            packageName,
                            wanted: wantedShrinkwrap[depType][packageName],
                        });
                    }
                    return;
                }
                // TODO: what about aliased dependencies?
                const resolution = yield resolve({ alias: packageName, pref: 'latest' }, {
                    registry: wantedShrinkwrap.registry,
                });
                if (!resolution || !resolution.latest)
                    return;
                const latest = resolution.latest;
                if (!currentShrinkwrap[depType][packageName]) {
                    outdated.push({
                        latest,
                        packageName,
                        wanted: wantedShrinkwrap[depType][packageName],
                    });
                    return;
                }
                if (currentShrinkwrap[depType][packageName] !== wantedShrinkwrap[depType][packageName] ||
                    latest !== currentShrinkwrap[depType][packageName]) {
                    outdated.push({
                        current: currentShrinkwrap[depType][packageName],
                        latest,
                        packageName,
                        wanted: wantedShrinkwrap[depType][packageName],
                    });
                }
            })));
        })));
        return outdated.sort((pkg1, pkg2) => pkg1.packageName.localeCompare(pkg2.packageName));
    });
}
function adaptConfig(opts) {
    const registryLog = logger_1.default('registry');
    return {
        defaultTag: opts.tag,
        log: Object.assign({}, registryLog, {
            http: registryLog.debug.bind(null, 'http'),
            verbose: registryLog.debug.bind(null, 'http'),
        }),
        proxy: {
            http: opts.proxy,
            https: opts.httpsProxy,
            localAddress: opts.localAddress,
        },
        retry: {
            count: opts.fetchRetries,
            factor: opts.fetchRetryFactor,
            maxTimeout: opts.fetchRetryMaxtimeout,
            minTimeout: opts.fetchRetryMintimeout,
        },
        ssl: {
            ca: opts.ca,
            certificate: opts.cert,
            key: opts.key,
            strict: opts.strictSsl,
        },
        userAgent: opts.userAgent,
    };
}
//# sourceMappingURL=index.js.map