"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PnpmNodeModulesCollector = void 0;
const builder_util_1 = require("builder-util");
const path = require("path");
const nodeModulesCollector_1 = require("./nodeModulesCollector");
const packageManager_1 = require("./packageManager");
class PnpmNodeModulesCollector extends nodeModulesCollector_1.NodeModulesCollector {
    constructor() {
        super(...arguments);
        this.installOptions = {
            manager: packageManager_1.PM.PNPM,
            lockfile: "pnpm-lock.yaml",
        };
    }
    getArgs() {
        return ["list", "--prod", "--json", "--depth", "Infinity"];
    }
    async getProductionDependencies(depTree) {
        const packageName = depTree.name || depTree.from;
        if ((0, builder_util_1.isEmptyOrSpaces)(packageName)) {
            builder_util_1.log.error(depTree, `Cannot determine production dependencies for package with empty name`);
            throw new Error(`Cannot compute production dependencies for package with empty name: ${packageName}`);
        }
        const result = await this.cache.locatePackageVersion({ parentDir: depTree.path, pkgName: packageName, requiredRange: depTree.version });
        if (result == null) {
            return { path: path.resolve(depTree.path), dependencies: {}, optionalDependencies: {} };
        }
        const { dependencies, optionalDependencies } = result.packageJson;
        return { path: result.packageDir, dependencies: { ...dependencies }, optionalDependencies: { ...optionalDependencies } };
    }
    async extractProductionDependencyGraph(tree, dependencyId) {
        var _a, _b, _c, _d;
        if (this.productionGraph[dependencyId]) {
            return;
        }
        this.productionGraph[dependencyId] = { dependencies: [] };
        const packageName = tree.name || tree.from;
        const treeDep = { ...(tree.dependencies || {}), ...(tree.optionalDependencies || {}) };
        const json = packageName === dependencyId ? null : await this.getProductionDependencies(tree);
        const prodDependencies = json ? { ...json.dependencies, ...json.optionalDependencies } : treeDep;
        const collectedDependencies = [];
        for (const packageName in treeDep) {
            if (!prodDependencies[packageName]) {
                continue;
            }
            // Then check if optional dependency path exists (using actual resolved path)
            const version = ((_a = json === null || json === void 0 ? void 0 : json.optionalDependencies) === null || _a === void 0 ? void 0 : _a[packageName]) || ((_c = (_b = tree.optionalDependencies) === null || _b === void 0 ? void 0 : _b[packageName]) === null || _c === void 0 ? void 0 : _c.version) || "";
            const result = await this.locatePackageWithVersion({ name: packageName, version, path: (_d = json === null || json === void 0 ? void 0 : json.path) !== null && _d !== void 0 ? _d : tree.path });
            if (result == null || !(await this.cache.exists[result.packageDir])) {
                builder_util_1.log.debug({ packageName, version: version, searchPath: result === null || result === void 0 ? void 0 : result.packageDir }, `optional dependency not installed, skipping`);
                continue;
            }
            const dependency = treeDep[packageName];
            const childDependencyId = this.packageVersionString(dependency);
            await this.extractProductionDependencyGraph(dependency, childDependencyId);
            collectedDependencies.push(childDependencyId);
        }
        this.productionGraph[dependencyId] = { dependencies: collectedDependencies };
    }
    async collectAllDependencies(tree) {
        // Collect regular dependencies
        for (const [key, value] of Object.entries(tree.dependencies || {})) {
            const json = await this.getProductionDependencies({ ...value, name: key });
            this.allDependencies.set(`${key}@${value.version}`, { ...value, path: json.path });
            await this.collectAllDependencies(value);
        }
        // Collect optional dependencies if they exist
        for (const [key, value] of Object.entries(tree.optionalDependencies || {})) {
            const json = await this.getProductionDependencies(value);
            this.allDependencies.set(`${key}@${value.version}`, { ...value, path: json.path });
            await this.collectAllDependencies(value);
        }
    }
    packageVersionString(pkg) {
        // we use 'from' field because 'name' may be different in case of aliases
        return `${pkg.from}@${pkg.version}`;
    }
    async parseDependenciesTree(jsonBlob) {
        const dependencyTree = JSON.parse(jsonBlob);
        // pnpm returns an array of dependency trees
        return Promise.resolve(dependencyTree[0]);
    }
}
exports.PnpmNodeModulesCollector = PnpmNodeModulesCollector;
//# sourceMappingURL=pnpmNodeModulesCollector.js.map