"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getLockedVersions = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const semver_1 = tslib_1.__importDefault(require("semver"));
const upath_1 = require("upath");
const logger_1 = require("../../../../logger");
const npm_1 = require("./npm");
const pnpm_1 = require("./pnpm");
const yarn_1 = require("./yarn");
async function getLockedVersions(packageFiles) {
    const lockFileCache = {};
    logger_1.logger.debug('Finding locked versions');
    for (const packageFile of packageFiles) {
        const { managerData = {} } = packageFile;
        const { yarnLock, npmLock, pnpmShrinkwrap } = managerData;
        const lockFiles = [];
        if (yarnLock) {
            logger_1.logger.trace('Found yarnLock');
            lockFiles.push(yarnLock);
            if (!lockFileCache[yarnLock]) {
                logger_1.logger.trace(`Retrieving/parsing ${yarnLock}`);
                lockFileCache[yarnLock] = await (0, yarn_1.getYarnLock)(yarnLock);
            }
            const { lockfileVersion, isYarn1 } = lockFileCache[yarnLock];
            let yarn;
            if (!isYarn1 && !packageFile.extractedConstraints?.yarn) {
                if (lockfileVersion && lockfileVersion >= 8) {
                    // https://github.com/yarnpkg/berry/commit/9bcd27ae34aee77a567dd104947407532fa179b3
                    yarn = '^3.0.0';
                }
                else if (lockfileVersion && lockfileVersion >= 6) {
                    // https://github.com/yarnpkg/berry/commit/f753790380cbda5b55d028ea84b199445129f9ba
                    yarn = '^2.2.0';
                }
                else {
                    yarn = '^2.0.0';
                }
            }
            if (yarn) {
                packageFile.extractedConstraints ??= {};
                packageFile.extractedConstraints.yarn = yarn;
            }
            for (const dep of packageFile.deps) {
                dep.lockedVersion =
                    lockFileCache[yarnLock].lockedVersions?.[
                    // TODO: types (#7154)
                    `${dep.depName}@${dep.currentValue}`];
                if ((dep.depType === 'engines' || dep.depType === 'packageManager') &&
                    dep.depName === 'yarn' &&
                    !isYarn1) {
                    dep.packageName = '@yarnpkg/cli';
                }
            }
        }
        else if (npmLock) {
            logger_1.logger.debug(`Found ${npmLock} for ${packageFile.packageFile}`);
            lockFiles.push(npmLock);
            if (!lockFileCache[npmLock]) {
                logger_1.logger.trace('Retrieving/parsing ' + npmLock);
                const cache = await (0, npm_1.getNpmLock)(npmLock);
                // istanbul ignore if
                if (!cache) {
                    logger_1.logger.warn({ npmLock }, 'Npm: unable to get lockfile');
                    return;
                }
                lockFileCache[npmLock] = cache;
            }
            const { lockfileVersion } = lockFileCache[npmLock];
            let npm;
            if (lockfileVersion === 1) {
                if (packageFile.extractedConstraints?.npm) {
                    // Add a <7 constraint if it's not already a fixed version
                    if (semver_1.default.satisfies('6.14.18', packageFile.extractedConstraints.npm)) {
                        npm = packageFile.extractedConstraints.npm + ' <7';
                    }
                }
                else {
                    npm = '<7';
                }
            }
            else if (lockfileVersion === 2) {
                if (packageFile.extractedConstraints?.npm) {
                    // Add a <9 constraint if the latest 8.x is compatible
                    if (semver_1.default.satisfies('8.19.3', packageFile.extractedConstraints.npm)) {
                        npm = packageFile.extractedConstraints.npm + ' <9';
                    }
                }
                else {
                    npm = '<9';
                }
            }
            else if (lockfileVersion === 3) {
                if (!packageFile.extractedConstraints?.npm) {
                    npm = '>=7';
                }
            }
            else {
                logger_1.logger.warn({ lockfileVersion, npmLock }, 'Found unsupported npm lockfile version');
                return;
            }
            if (npm) {
                packageFile.extractedConstraints ??= {};
                packageFile.extractedConstraints.npm = npm;
            }
            for (const dep of packageFile.deps) {
                // TODO: types (#7154)
                dep.lockedVersion = semver_1.default.valid(lockFileCache[npmLock].lockedVersions?.[dep.depName]);
            }
        }
        else if (pnpmShrinkwrap) {
            logger_1.logger.debug('Found pnpm lock-file');
            lockFiles.push(pnpmShrinkwrap);
            if (!lockFileCache[pnpmShrinkwrap]) {
                logger_1.logger.trace(`Retrieving/parsing ${pnpmShrinkwrap}`);
                lockFileCache[pnpmShrinkwrap] = await (0, pnpm_1.getPnpmLock)(pnpmShrinkwrap);
            }
            const packageDir = (0, upath_1.dirname)(packageFile.packageFile);
            const pnpmRootDir = (0, upath_1.dirname)(pnpmShrinkwrap);
            const relativeDir = (0, upath_1.relative)(pnpmRootDir, packageDir) || '.';
            for (const dep of packageFile.deps) {
                const { depName, depType } = dep;
                // TODO: types (#7154)
                const lockedVersion = semver_1.default.valid(lockFileCache[pnpmShrinkwrap].lockedVersionsWithPath?.[relativeDir]?.[depType]?.[depName]);
                if (is_1.default.string(lockedVersion)) {
                    dep.lockedVersion = lockedVersion;
                }
            }
        }
        if (lockFiles.length) {
            packageFile.lockFiles = lockFiles;
        }
    }
}
exports.getLockedVersions = getLockedVersions;
//# sourceMappingURL=locked-versions.js.map