"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.nodeIdToParents = void 0;
const core_loggers_1 = require("@pnpm/core-loggers");
const error_1 = __importDefault(require("@pnpm/error"));
const lockfile_utils_1 = require("@pnpm/lockfile-utils");
const logger_1 = __importDefault(require("@pnpm/logger"));
const package_is_installable_1 = __importDefault(require("@pnpm/package-is-installable"));
const pick_registry_for_package_1 = __importDefault(require("@pnpm/pick-registry-for-package"));
const pkgid_to_filename_1 = __importDefault(require("@pnpm/pkgid-to-filename"));
const dp = __importStar(require("dependency-path"));
const encodePkgId_1 = __importDefault(require("./encodePkgId"));
const getNonDevWantedDependencies_1 = __importDefault(require("./getNonDevWantedDependencies"));
const nodeIdUtils_1 = require("./nodeIdUtils");
const wantedDepIsLocallyAvailable_1 = __importDefault(require("./wantedDepIsLocallyAvailable"));
const path = require("path");
const exists = require("path-exists");
const R = require("ramda");
const semver = require("semver");
const dependencyResolvedLogger = logger_1.default('_dependency_resolved');
function nodeIdToParents(nodeId, resolvedPackagesByDepPath) {
    return nodeIdUtils_1.splitNodeId(nodeId).slice(1)
        .map((depPath) => {
        const { id, name, version } = resolvedPackagesByDepPath[depPath];
        return { id, name, version };
    });
}
exports.nodeIdToParents = nodeIdToParents;
async function resolveDependencies(ctx, preferredVersions, wantedDependencies, options) {
    const extendedWantedDeps = getDepsToResolve(wantedDependencies, ctx.wantedLockfile, {
        preferredDependencies: options.preferredDependencies,
        prefix: ctx.prefix,
        proceed: options.proceed || ctx.forceFullResolution,
        registries: ctx.registries,
        resolvedDependencies: options.resolvedDependencies,
    });
    const postponedResolutionsQueue = [];
    const pkgAddresses = (await Promise.all(extendedWantedDeps.map((extendedWantedDep) => resolveDependenciesOfDependency(postponedResolutionsQueue, ctx, preferredVersions, options, extendedWantedDep))))
        .filter(Boolean);
    const newPreferredVersions = { ...preferredVersions };
    for (const { depPath } of pkgAddresses) {
        const resolvedPackage = ctx.resolvedPackagesByDepPath[depPath];
        if (!resolvedPackage)
            continue; // This will happen only with linked dependencies
        if (!newPreferredVersions[resolvedPackage.name]) {
            newPreferredVersions[resolvedPackage.name] = {};
        }
        newPreferredVersions[resolvedPackage.name][resolvedPackage.version] = 'version';
    }
    await Promise.all(postponedResolutionsQueue.map((postponedResolution) => postponedResolution(newPreferredVersions)));
    return pkgAddresses;
}
exports.default = resolveDependencies;
async function resolveDependenciesOfDependency(postponedResolutionsQueue, ctx, preferredVersions, options, extendedWantedDep) {
    var _a, _b, _c;
    const updateDepth = typeof extendedWantedDep.wantedDependency.updateDepth === 'number'
        ? extendedWantedDep.wantedDependency.updateDepth : options.updateDepth;
    const updateShouldContinue = options.currentDepth <= updateDepth;
    const update = (updateShouldContinue && (!ctx.updateMatching ||
        !((_a = extendedWantedDep.infoFromLockfile) === null || _a === void 0 ? void 0 : _a.dependencyLockfile) ||
        ctx.updateMatching((_b = extendedWantedDep.infoFromLockfile.dependencyLockfile.name) !== null && _b !== void 0 ? _b : extendedWantedDep.wantedDependency.alias))) || Boolean(options.workspacePackages &&
        wantedDepIsLocallyAvailable_1.default(options.workspacePackages, extendedWantedDep.wantedDependency, { defaultTag: ctx.defaultTag, registry: ctx.registries.default }));
    const resolveDependencyOpts = {
        currentDepth: options.currentDepth,
        parentPkg: options.parentPkg,
        preferredVersions,
        workspacePackages: options.workspacePackages,
        currentPkg: (_c = extendedWantedDep.infoFromLockfile) !== null && _c !== void 0 ? _c : undefined,
        proceed: extendedWantedDep.proceed || updateShouldContinue,
        update,
        updateDepth,
    };
    const resolveDependencyResult = await resolveDependency(extendedWantedDep.wantedDependency, ctx, resolveDependencyOpts);
    if (!resolveDependencyResult)
        return null;
    if (resolveDependencyResult.isLinkedDependency) {
        ctx.dependenciesTree[resolveDependencyResult.pkgId] = {
            children: {},
            depth: -1,
            installable: true,
            resolvedPackage: {
                name: resolveDependencyResult.name,
                version: resolveDependencyResult.version,
            },
        };
        return resolveDependencyResult;
    }
    if (!resolveDependencyResult.isNew)
        return resolveDependencyResult;
    postponedResolutionsQueue.push(async (preferredVersions) => {
        var _a;
        return resolveChildren(ctx, resolveDependencyResult, (_a = extendedWantedDep.infoFromLockfile) === null || _a === void 0 ? void 0 : _a.dependencyLockfile, options.workspacePackages, options.currentDepth, updateDepth, preferredVersions);
    });
    return resolveDependencyResult;
}
async function resolveChildren(ctx, parentPkg, dependencyLockfile, workspacePackages, parentDepth, updateDepth, preferredVersions) {
    var _a, _b;
    const currentResolvedDependencies = dependencyLockfile ? {
        ...dependencyLockfile.dependencies,
        ...dependencyLockfile.optionalDependencies,
    } : undefined;
    const resolvedDependencies = parentPkg.updated
        ? undefined
        : currentResolvedDependencies;
    const parentDependsOnPeer = Boolean(Object.keys((_b = (_a = dependencyLockfile === null || dependencyLockfile === void 0 ? void 0 : dependencyLockfile.peerDependencies) !== null && _a !== void 0 ? _a : parentPkg.pkg.peerDependencies) !== null && _b !== void 0 ? _b : {}).length);
    const wantedDependencies = getNonDevWantedDependencies_1.default(parentPkg.pkg);
    workspacePackages = workspacePackages && ctx.linkWorkspacePackagesDepth > parentDepth
        ? workspacePackages : undefined;
    const children = await resolveDependencies(ctx, preferredVersions, wantedDependencies, {
        currentDepth: parentDepth + 1,
        parentPkg,
        preferredDependencies: currentResolvedDependencies,
        // If the package is not linked, we should also gather information about its dependencies.
        // After linking the package we'll need to symlink its dependencies.
        proceed: !parentPkg.depIsLinked || parentDependsOnPeer,
        resolvedDependencies,
        updateDepth,
        workspacePackages,
    });
    ctx.childrenByParentDepPath[parentPkg.depPath] = children.map((child) => ({
        alias: child.alias,
        depPath: child.depPath,
    }));
    ctx.dependenciesTree[parentPkg.nodeId] = {
        children: children.reduce((chn, child) => {
            var _a;
            chn[child.alias] = (_a = child['nodeId']) !== null && _a !== void 0 ? _a : child.pkgId;
            return chn;
        }, {}),
        depth: parentDepth,
        installable: parentPkg.installable,
        resolvedPackage: ctx.resolvedPackagesByDepPath[parentPkg.depPath],
    };
}
function getDepsToResolve(wantedDependencies, wantedLockfile, options) {
    var _a, _b, _c;
    const resolvedDependencies = (_a = options.resolvedDependencies) !== null && _a !== void 0 ? _a : {};
    const preferredDependencies = (_b = options.preferredDependencies) !== null && _b !== void 0 ? _b : {};
    const extendedWantedDeps = [];
    // The only reason we resolve children in case the package depends on peers
    // is to get information about the existing dependencies, so that they can
    // be merged with the resolved peers.
    let proceedAll = options.proceed;
    const allPeers = new Set();
    const satisfiesWanted2Args = referenceSatisfiesWantedSpec.bind(null, {
        lockfile: wantedLockfile,
        prefix: options.prefix,
    });
    for (const wantedDependency of wantedDependencies) {
        let reference = undefined;
        let proceed = proceedAll;
        if (wantedDependency.alias) {
            const satisfiesWanted = satisfiesWanted2Args.bind(null, wantedDependency);
            if (resolvedDependencies[wantedDependency.alias] &&
                satisfiesWanted(resolvedDependencies[wantedDependency.alias])) {
                reference = resolvedDependencies[wantedDependency.alias];
            }
            else if (
            // If dependencies that were used by the previous version of the package
            // satisfy the newer version's requirements, then pnpm tries to keep
            // the previous dependency.
            // So for example, if foo@1.0.0 had bar@1.0.0 as a dependency
            // and foo was updated to 1.1.0 which depends on bar ^1.0.0
            // then bar@1.0.0 can be reused for foo@1.1.0
            semver.validRange(wantedDependency.pref) !== null && // eslint-disable-line
                preferredDependencies[wantedDependency.alias] &&
                satisfiesWanted(preferredDependencies[wantedDependency.alias])) {
                proceed = true;
                reference = preferredDependencies[wantedDependency.alias];
            }
        }
        const infoFromLockfile = getInfoFromLockfile(wantedLockfile, options.registries, reference, wantedDependency.alias);
        if (!proceedAll && ((_c = infoFromLockfile === null || infoFromLockfile === void 0 ? void 0 : infoFromLockfile.dependencyLockfile) === null || _c === void 0 ? void 0 : _c.peerDependencies)) {
            proceed = true;
            Object.keys(infoFromLockfile.dependencyLockfile.peerDependencies).forEach((peerName) => {
                allPeers.add(peerName);
            });
        }
        if (!infoFromLockfile && !proceedAll) {
            // In this case we don't know if the package depends on peer dependencies, so we proceed all.
            proceedAll = true;
            for (const extendedWantedDep of extendedWantedDeps) {
                if (!extendedWantedDep.proceed) {
                    extendedWantedDep.proceed = true;
                }
            }
        }
        extendedWantedDeps.push({
            infoFromLockfile,
            proceed,
            wantedDependency,
        });
    }
    if (!proceedAll && allPeers.size) {
        for (const extendedWantedDep of extendedWantedDeps) {
            if (!extendedWantedDep.proceed && allPeers.has(extendedWantedDep.wantedDependency.alias)) {
                extendedWantedDep.proceed = true;
            }
        }
    }
    return extendedWantedDeps;
}
function referenceSatisfiesWantedSpec(opts, wantedDep, preferredRef) {
    var _a;
    const depPath = dp.refToRelative(preferredRef, wantedDep.alias);
    if (depPath === null)
        return false;
    const pkgSnapshot = (_a = opts.lockfile.packages) === null || _a === void 0 ? void 0 : _a[depPath];
    if (!pkgSnapshot) {
        logger_1.default.warn({
            message: `Could not find preferred package ${depPath} in lockfile`,
            prefix: opts.prefix,
        });
        return false;
    }
    const { version } = lockfile_utils_1.nameVerFromPkgSnapshot(depPath, pkgSnapshot);
    return semver.satisfies(version, wantedDep.pref, true);
}
function getInfoFromLockfile(lockfile, registries, reference, alias) {
    var _a, _b, _c;
    if (!reference || !alias) {
        return undefined;
    }
    const depPath = dp.refToRelative(reference, alias);
    if (!depPath) {
        return undefined;
    }
    let dependencyLockfile = (_a = lockfile.packages) === null || _a === void 0 ? void 0 : _a[depPath];
    if (dependencyLockfile) {
        if (dependencyLockfile.peerDependencies && dependencyLockfile.dependencies) {
            // This is done to guarantee that the dependency will be relinked with the
            // up-to-date peer dependencies
            // Covered by test: "peer dependency is grouped with dependency when peer is resolved not from a top dependency"
            const dependencies = {};
            for (const [depName, ref] of Object.entries((_b = dependencyLockfile.dependencies) !== null && _b !== void 0 ? _b : {})) {
                if (dependencyLockfile.peerDependencies[depName])
                    continue;
                dependencies[depName] = ref;
            }
            dependencyLockfile = {
                ...dependencyLockfile,
                dependencies,
            };
        }
        return {
            dependencyLockfile,
            depPath,
            pkgId: lockfile_utils_1.packageIdFromSnapshot(depPath, dependencyLockfile, registries),
            resolution: lockfile_utils_1.pkgSnapshotToResolution(depPath, dependencyLockfile, registries),
        };
    }
    else {
        return {
            depPath,
            pkgId: (_c = dp.tryGetPackageId(registries, depPath)) !== null && _c !== void 0 ? _c : depPath,
        };
    }
}
async function resolveDependency(wantedDependency, ctx, options) {
    var _a, _b, _c, _d, _e, _f, _g, _h, _j;
    const currentPkg = (_a = options.currentPkg) !== null && _a !== void 0 ? _a : {};
    const currentLockfileContainsTheDep = currentPkg.depPath
        ? Boolean((_b = ctx.currentLockfile.packages) === null || _b === void 0 ? void 0 : _b[currentPkg.depPath]) : undefined;
    const depIsLinked = Boolean(
    // if package is not in `node_modules/.pnpm-lock.yaml`
    // we can safely assume that it doesn't exist in `node_modules`
    currentLockfileContainsTheDep &&
        currentPkg.depPath &&
        currentPkg.dependencyLockfile &&
        await exists(path.join(ctx.virtualStoreDir, pkgid_to_filename_1.default(currentPkg.depPath, ctx.prefix), 'node_modules', lockfile_utils_1.nameVerFromPkgSnapshot(currentPkg.depPath, currentPkg.dependencyLockfile).name, 'package.json')));
    if (!options.update && !options.proceed && currentPkg.resolution && depIsLinked) {
        return null;
    }
    let pkgResponse;
    try {
        pkgResponse = await ctx.storeController.requestPackage(wantedDependency, {
            alwaysTryWorkspacePackages: ctx.alwaysTryWorkspacePackages,
            currentPackageId: currentPkg.pkgId,
            currentResolution: currentPkg.resolution,
            defaultTag: ctx.defaultTag,
            downloadPriority: -options.currentDepth,
            lockfileDir: ctx.lockfileDir,
            preferredVersions: options.preferredVersions,
            projectDir: options.currentDepth > 0 ? ctx.lockfileDir : ctx.prefix,
            registry: wantedDependency.alias && pick_registry_for_package_1.default(ctx.registries, wantedDependency.alias) || ctx.registries.default,
            // Unfortunately, even when run with --lockfile-only, we need the *real* package.json
            // so fetching of the tarball cannot be ever avoided. Related issue: https://github.com/pnpm/pnpm/issues/1176
            skipFetch: false,
            update: options.update,
            workspacePackages: options.workspacePackages,
        });
    }
    catch (err) {
        if (wantedDependency.optional) {
            core_loggers_1.skippedOptionalDependencyLogger.debug({
                details: err.toString(),
                package: {
                    name: wantedDependency.alias,
                    pref: wantedDependency.pref,
                    version: wantedDependency.alias ? wantedDependency.pref : undefined,
                },
                parents: nodeIdToParents(options.parentPkg.nodeId, ctx.resolvedPackagesByDepPath),
                prefix: ctx.prefix,
                reason: 'resolution_failure',
            });
            return null;
        }
        err.pkgsStack = nodeIdToParents(options.parentPkg.nodeId, ctx.resolvedPackagesByDepPath);
        throw err;
    }
    dependencyResolvedLogger.debug({
        resolution: pkgResponse.body.id,
        wanted: {
            dependentId: options.parentPkg.depPath,
            name: wantedDependency.alias,
            rawSpec: wantedDependency.pref,
        },
    });
    pkgResponse.body.id = encodePkgId_1.default(pkgResponse.body.id);
    if (!pkgResponse.body.updated &&
        options.currentDepth === Math.max(0, options.updateDepth) &&
        depIsLinked && !ctx.force && !options.proceed) {
        return null;
    }
    if (pkgResponse.body.isLocal) {
        const manifest = (_c = pkgResponse.body.manifest) !== null && _c !== void 0 ? _c : await pkgResponse.bundledManifest(); // eslint-disable-line @typescript-eslint/dot-notation
        return {
            alias: wantedDependency.alias || manifest.name,
            depPath: pkgResponse.body.id,
            dev: wantedDependency.dev,
            isLinkedDependency: true,
            name: manifest.name,
            normalizedPref: pkgResponse.body.normalizedPref,
            optional: wantedDependency.optional,
            pkgId: pkgResponse.body.id,
            resolution: pkgResponse.body.resolution,
            version: manifest.version,
        };
    }
    let pkg;
    let prepare;
    let hasBin;
    pkg = ctx.readPackageHook
        ? ctx.readPackageHook((_d = pkgResponse.body.manifest) !== null && _d !== void 0 ? _d : await pkgResponse.bundledManifest())
        : (_e = pkgResponse.body.manifest) !== null && _e !== void 0 ? _e : await pkgResponse.bundledManifest();
    if (!pkg.name) { // TODO: don't fail on optional dependencies
        throw new error_1.default('MISSING_PACKAGE_NAME', `Can't install ${wantedDependency.pref}: Missing package name`);
    }
    const depPath = dp.relative(ctx.registries, pkg.name, pkgResponse.body.id);
    // We are building the dependency tree only until there are new packages
    // or the packages repeat in a unique order.
    // This is needed later during peer dependencies resolution.
    //
    // So we resolve foo > bar > qar > foo
    // But we stop on foo > bar > qar > foo > qar
    // In the second example, there's no reason to walk qar again
    // when qar is included the first time, the dependencies of foo
    // are already resolved and included as parent dependencies of qar.
    // So during peers resolution, qar cannot possibly get any new or different
    // peers resolved, after the first ocurrence.
    //
    // However, in the next example we would analyze the second qar as well,
    // because zoo is a new parent package:
    // foo > bar > qar > zoo > qar
    if (nodeIdUtils_1.nodeIdContainsSequence(options.parentPkg.nodeId, options.parentPkg.depPath, depPath)) {
        return null;
    }
    if (!options.update && currentPkg.dependencyLockfile && currentPkg.depPath &&
        !pkgResponse.body.updated &&
        // peerDependencies field is also used for transitive peer dependencies which should not be linked
        // That's why we cannot omit reading package.json of such dependencies.
        // This can be removed if we implement something like peerDependenciesMeta.transitive: true
        !currentPkg.dependencyLockfile.peerDependencies) {
        prepare = currentPkg.dependencyLockfile.prepare === true;
        hasBin = currentPkg.dependencyLockfile.hasBin === true;
        pkg = {
            ...lockfile_utils_1.nameVerFromPkgSnapshot(currentPkg.depPath, currentPkg.dependencyLockfile),
            ...currentPkg.dependencyLockfile,
            ...pkg,
        };
    }
    else {
        /* eslint-disable @typescript-eslint/dot-notation */
        prepare = Boolean(pkgResponse.body.resolvedVia === 'git-repository' &&
            typeof ((_f = pkg.scripts) === null || _f === void 0 ? void 0 : _f.prepare) === 'string');
        if (((_g = currentPkg.dependencyLockfile) === null || _g === void 0 ? void 0 : _g.deprecated) &&
            !pkgResponse.body.updated && !pkg.deprecated) {
            pkg.deprecated = currentPkg.dependencyLockfile.deprecated;
        }
        hasBin = Boolean((_h = (pkg.bin && !R.isEmpty(pkg.bin))) !== null && _h !== void 0 ? _h : (_j = pkg.directories) === null || _j === void 0 ? void 0 : _j.bin);
        /* eslint-enable @typescript-eslint/dot-notation */
    }
    if (options.currentDepth === 0 && pkgResponse.body.latest && pkgResponse.body.latest !== pkg.version) {
        ctx.outdatedDependencies[pkgResponse.body.id] = pkgResponse.body.latest;
    }
    if (pkg.deprecated) {
        core_loggers_1.deprecationLogger.debug({
            deprecated: pkg.deprecated,
            depth: options.currentDepth,
            pkgId: pkgResponse.body.id,
            pkgName: pkg.name,
            pkgVersion: pkg.version,
            prefix: ctx.prefix,
        });
    }
    // In case of leaf dependencies (dependencies that have no prod deps or peer deps),
    // we only ever need to analyze one leaf dep in a graph, so the nodeId can be short and stateless.
    const nodeId = pkgIsLeaf(pkg)
        ? pkgResponse.body.id
        : nodeIdUtils_1.createNodeId(options.parentPkg.nodeId, depPath);
    const currentIsInstallable = (ctx.force ||
        package_is_installable_1.default(pkgResponse.body.id, pkg, {
            engineStrict: ctx.engineStrict,
            lockfileDir: ctx.lockfileDir,
            nodeVersion: ctx.nodeVersion,
            optional: wantedDependency.optional,
            pnpmVersion: ctx.pnpmVersion,
        }));
    const parentIsInstallable = options.parentPkg.installable === undefined || options.parentPkg.installable;
    const installable = parentIsInstallable && currentIsInstallable !== false;
    const isNew = !ctx.resolvedPackagesByDepPath[depPath];
    if (isNew) {
        if (currentIsInstallable !== true || !parentIsInstallable) {
            ctx.skipped.add(pkgResponse.body.id);
        }
        core_loggers_1.progressLogger.debug({
            packageId: pkgResponse.body.id,
            requester: ctx.lockfileDir,
            status: 'resolved',
        });
        if (pkgResponse.files) {
            pkgResponse.files()
                .then((fetchResult) => {
                core_loggers_1.progressLogger.debug({
                    packageId: pkgResponse.body.id,
                    requester: ctx.lockfileDir,
                    status: fetchResult.fromStore
                        ? 'found_in_store' : 'fetched',
                });
            })
                .catch(() => {
                // Ignore
            });
        }
        ctx.resolvedPackagesByDepPath[depPath] = getResolvedPackage({
            dependencyLockfile: currentPkg.dependencyLockfile,
            depPath,
            force: ctx.force,
            hasBin,
            pkg,
            pkgResponse,
            prepare,
            wantedDependency,
        });
    }
    else {
        ctx.resolvedPackagesByDepPath[depPath].prod = ctx.resolvedPackagesByDepPath[depPath].prod || !wantedDependency.dev && !wantedDependency.optional;
        ctx.resolvedPackagesByDepPath[depPath].dev = ctx.resolvedPackagesByDepPath[depPath].dev || wantedDependency.dev;
        ctx.resolvedPackagesByDepPath[depPath].optional = ctx.resolvedPackagesByDepPath[depPath].optional && wantedDependency.optional;
        if (ctx.dependenciesTree[nodeId]) {
            ctx.dependenciesTree[nodeId].depth = Math.min(ctx.dependenciesTree[nodeId].depth, options.currentDepth);
        }
        else {
            ctx.pendingNodes.push({
                alias: wantedDependency.alias || pkg.name,
                depth: options.currentDepth,
                installable,
                nodeId,
                resolvedPackage: ctx.resolvedPackagesByDepPath[depPath],
            });
        }
    }
    return {
        alias: wantedDependency.alias || pkg.name,
        depIsLinked,
        depPath,
        isNew,
        nodeId,
        normalizedPref: options.currentDepth === 0 ? pkgResponse.body.normalizedPref : undefined,
        pkgId: pkgResponse.body.id,
        // Next fields are actually only needed when isNew = true
        installable,
        isLinkedDependency: undefined,
        pkg,
        updated: pkgResponse.body.updated,
    };
}
function pkgIsLeaf(pkg) {
    var _a, _b, _c;
    return R.isEmpty((_a = pkg.dependencies) !== null && _a !== void 0 ? _a : {}) &&
        R.isEmpty((_b = pkg.optionalDependencies) !== null && _b !== void 0 ? _b : {}) &&
        R.isEmpty((_c = pkg.peerDependencies) !== null && _c !== void 0 ? _c : {});
}
function getResolvedPackage(options) {
    var _a;
    const peerDependencies = peerDependenciesWithoutOwn(options.pkg);
    return {
        additionalInfo: {
            bundledDependencies: options.pkg.bundledDependencies,
            bundleDependencies: options.pkg.bundleDependencies,
            cpu: options.pkg.cpu,
            deprecated: options.pkg.deprecated,
            engines: options.pkg.engines,
            os: options.pkg.os,
        },
        depPath: options.depPath,
        dev: options.wantedDependency.dev,
        fetchingBundledManifest: options.pkgResponse.bundledManifest,
        fetchingFiles: options.pkgResponse.files,
        filesIndexFile: options.pkgResponse.filesIndexFile,
        finishing: options.pkgResponse.finishing,
        hasBin: options.hasBin,
        hasBundledDependencies: !!((_a = options.pkg.bundledDependencies) !== null && _a !== void 0 ? _a : options.pkg.bundleDependencies),
        id: options.pkgResponse.body.id,
        name: options.pkg.name,
        optional: options.wantedDependency.optional,
        optionalDependencies: new Set(R.keys(options.pkg.optionalDependencies)),
        peerDependencies: peerDependencies !== null && peerDependencies !== void 0 ? peerDependencies : {},
        peerDependenciesMeta: options.pkg.peerDependenciesMeta,
        prepare: options.prepare,
        prod: !options.wantedDependency.dev && !options.wantedDependency.optional,
        requiresBuild: options.dependencyLockfile && Boolean(options.dependencyLockfile.requiresBuild),
        resolution: options.pkgResponse.body.resolution,
        version: options.pkg.version,
    };
}
function peerDependenciesWithoutOwn(pkg) {
    var _a, _b;
    if (!pkg.peerDependencies && !pkg.peerDependenciesMeta)
        return pkg.peerDependencies;
    const ownDeps = new Set([
        ...Object.keys((_a = pkg.dependencies) !== null && _a !== void 0 ? _a : {}),
        ...Object.keys((_b = pkg.optionalDependencies) !== null && _b !== void 0 ? _b : {}),
    ]);
    const result = {};
    if (pkg.peerDependencies) {
        for (const [peerName, peerRange] of Object.entries(pkg.peerDependencies)) {
            if (ownDeps.has(peerName))
                continue;
            result[peerName] = peerRange;
        }
    }
    if (pkg.peerDependenciesMeta) {
        for (const [peerName, peerMeta] of Object.entries(pkg.peerDependenciesMeta)) {
            if (ownDeps.has(peerName) || result[peerName] || peerMeta.optional !== true)
                continue;
            result[peerName] = '*';
        }
    }
    if (R.isEmpty(result))
        return undefined;
    return result;
}
//# sourceMappingURL=resolveDependencies.js.map