UNPKG

@aquaori/deplens

Version:

A precise dependency analysis tool for npm and pnpm projects

105 lines 4.72 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.parsePnpmLockfile = parsePnpmLockfile; const fs_1 = __importDefault(require("fs")); const js_yaml_1 = __importDefault(require("js-yaml")); /** * 解析 pnpm lockfile * @param manifestPath lockfile 路径 * @returns 依赖列表和检查计数 */ function parsePnpmLockfile(manifestPath, ignoreList) { // 读取并解析 lockfile const rootManifest = js_yaml_1.default.load(fs_1.default.readFileSync(manifestPath, 'utf-8')); let lockVersion = 0; lockVersion = rootManifest.lockfileVersion; // 获取不同类型的依赖 const rootProd = lockVersion == 6 ? rootManifest.dependencies || {} : rootManifest['importers']['.']?.dependencies || {}; const rootPeer = lockVersion == 6 ? rootManifest.peerDependencies || {} : rootManifest['importers']['.']?.peerDependencies || {}; const rootOpt = lockVersion == 6 ? rootManifest.optionalDependencies || {} : rootManifest['importers']['.']?.optionalDependencies || {}; const rootDev = lockVersion == 6 ? rootManifest.devDependencies || {} : rootManifest['importers']['.']?.devDependencies || {}; const depSource = lockVersion == 6 ? rootManifest.packages || {} : rootManifest.snapshots || {}; // 收集被其他包使用的依赖 const usedByOthers = new Map(); let checkCount = 0; for (const [key, pkg] of Object.entries(depSource)) { if (key === '' || !pkg || typeof pkg !== 'object') continue; const p = pkg; [ p.dependencies || {}, p.peerDependencies || {}, p.optionalDependencies || {} ].forEach(obj => { Object.entries(obj).forEach(([depName, depRange]) => { if (typeof depRange !== 'string') return; const ver = depRange.replace(/\(.+?\)+/g, ''); if (!usedByOthers.has(depName)) usedByOthers.set(depName, new Set()); usedByOthers.get(depName).add(ver); checkCount++; }); }); } // 构建锁文件中的依赖包列表 const lockFilePkg = []; const rootDeclared = new Map(); Object.entries({ ...rootProd, ...rootPeer, ...rootOpt, ...rootDev }) .forEach(([name, ver]) => rootDeclared.set(name, ver)); for (const [name, version] of rootDeclared) { if (ignoreList.includes(name)) continue; let pureVersion; if (typeof version == "object") { pureVersion = version.version.replace(/\(.+?\)+/g, ''); } else { pureVersion = version.replace(/[\^\*\~\=\>\<]/g, ''); } let usedVersions = usedByOthers.get(name); let usedVersionsList = usedVersions || new Set(); let isUsed = usedVersionsList ? usedVersionsList.has(pureVersion) : false; if (!isUsed) { let preciseVersion = "0"; if (typeof version == "string") preciseVersion = version.replace(/\(.+?\)+/g, ''); else if (typeof version == "object") preciseVersion = version.version.replace(/\(.+?\)+/g, ''); const previousPkgIndex = lockFilePkg.findIndex(dep => dep.name == name); const previousPkg = previousPkgIndex >= 0 ? lockFilePkg[previousPkgIndex] : null; let previousVersion = previousPkg?.version ?? []; if (previousPkg !== null && previousVersion !== "") { if (previousVersion.length != 0 && !previousPkg?.usage) previousVersion = [...previousVersion, preciseVersion]; else previousVersion = [preciseVersion]; } else { previousVersion = [preciseVersion]; } ; if (previousVersion.length != 1) previousVersion = [previousVersion.join(" & @")]; if (previousPkgIndex >= 0 && previousPkg !== null) { lockFilePkg[previousPkgIndex].version = previousVersion; } else { lockFilePkg.push({ name, type: '', version: previousVersion, usage: isUsed, isDev: Object.prototype.hasOwnProperty.call(rootDev, name) }); } } } // 按名称排序 lockFilePkg.sort((a, b) => a.name.localeCompare(b.name)); return { dependencies: lockFilePkg, checkCount }; } //# sourceMappingURL=pnpm.js.map