@pnpm/core
Version:
Fast, disk space efficient installation engine
125 lines • 6.23 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PeerDependencyIssuesError = void 0;
exports.reportPeerDependencyIssues = reportPeerDependencyIssues;
exports.filterPeerDependencyIssues = filterPeerDependencyIssues;
const error_1 = require("@pnpm/error");
const matcher_1 = require("@pnpm/matcher");
const core_loggers_1 = require("@pnpm/core-loggers");
const semver_1 = __importDefault(require("semver"));
const isEmpty_1 = __importDefault(require("ramda/src/isEmpty"));
const parse_overrides_1 = require("@pnpm/parse-overrides");
function reportPeerDependencyIssues(peerDependencyIssuesByProjects, opts) {
const newPeerDependencyIssuesByProjects = filterPeerDependencyIssues(peerDependencyIssuesByProjects, opts.rules);
if (Object.values(newPeerDependencyIssuesByProjects).every((peerIssuesOfProject) => (0, isEmpty_1.default)(peerIssuesOfProject.bad) && ((0, isEmpty_1.default)(peerIssuesOfProject.missing) ||
peerIssuesOfProject.conflicts.length === 0 && Object.keys(peerIssuesOfProject.intersections).length === 0)))
return;
if (opts.strictPeerDependencies) {
throw new PeerDependencyIssuesError(newPeerDependencyIssuesByProjects);
}
core_loggers_1.peerDependencyIssuesLogger.debug({
issuesByProjects: newPeerDependencyIssuesByProjects,
});
}
function filterPeerDependencyIssues(peerDependencyIssuesByProjects, rules) {
if (!rules)
return peerDependencyIssuesByProjects;
const ignoreMissingPatterns = [...new Set(rules?.ignoreMissing ?? [])];
const ignoreMissingMatcher = (0, matcher_1.createMatcher)(ignoreMissingPatterns);
const allowAnyPatterns = [...new Set(rules?.allowAny ?? [])];
const allowAnyMatcher = (0, matcher_1.createMatcher)(allowAnyPatterns);
const { allowedVersionsMatchAll, allowedVersionsByParentPkgName } = parseAllowedVersions(rules?.allowedVersions ?? {});
const newPeerDependencyIssuesByProjects = {};
for (const [projectId, { bad, missing, conflicts, intersections }] of Object.entries(peerDependencyIssuesByProjects)) {
newPeerDependencyIssuesByProjects[projectId] = { bad: {}, missing: {}, conflicts, intersections };
for (const [peerName, issues] of Object.entries(missing)) {
if (ignoreMissingMatcher(peerName) || issues.every(({ optional }) => optional)) {
continue;
}
newPeerDependencyIssuesByProjects[projectId].missing[peerName] = issues;
}
for (const [peerName, issues] of Object.entries(bad)) {
if (allowAnyMatcher(peerName))
continue;
const filteredIssues = [];
for (const issue of issues) {
if (allowedVersionsMatchAll[peerName]?.some((range) => semver_1.default.satisfies(issue.foundVersion, range)))
continue;
const currentParentPkg = issue.parents.at(-1);
if (currentParentPkg && allowedVersionsByParentPkgName[peerName]?.[currentParentPkg.name]) {
const allowedVersionsByParent = {};
for (const { targetPkg, parentPkg, ranges } of allowedVersionsByParentPkgName[peerName][currentParentPkg.name]) {
if (!parentPkg.bareSpecifier || currentParentPkg.version &&
(isSubRange(parentPkg.bareSpecifier, currentParentPkg.version) || semver_1.default.satisfies(currentParentPkg.version, parentPkg.bareSpecifier))) {
allowedVersionsByParent[targetPkg.name] = ranges;
}
}
if (allowedVersionsByParent[peerName]?.some((range) => semver_1.default.satisfies(issue.foundVersion, range)))
continue;
}
filteredIssues.push(issue);
}
if (filteredIssues.length) {
newPeerDependencyIssuesByProjects[projectId].bad[peerName] = filteredIssues;
}
}
}
return newPeerDependencyIssuesByProjects;
}
function isSubRange(superRange, subRange) {
return !superRange ||
subRange === superRange ||
semver_1.default.validRange(subRange) != null &&
semver_1.default.validRange(superRange) != null &&
semver_1.default.subset(subRange, superRange);
}
function tryParseAllowedVersions(allowedVersions) {
try {
return (0, parse_overrides_1.parseOverrides)(allowedVersions ?? {});
}
catch (err) {
throw new error_1.PnpmError('INVALID_ALLOWED_VERSION_SELECTOR', `${err.message} in pnpm.peerDependencyRules.allowedVersions`);
}
}
function parseAllowedVersions(allowedVersions) {
const overrides = tryParseAllowedVersions(allowedVersions);
const allowedVersionsMatchAll = {};
const allowedVersionsByParentPkgName = {};
for (const { parentPkg, targetPkg, newBareSpecifier } of overrides) {
const ranges = parseVersions(newBareSpecifier);
if (!parentPkg) {
allowedVersionsMatchAll[targetPkg.name] = ranges;
continue;
}
if (!allowedVersionsByParentPkgName[targetPkg.name]) {
allowedVersionsByParentPkgName[targetPkg.name] = {};
}
if (!allowedVersionsByParentPkgName[targetPkg.name][parentPkg.name]) {
allowedVersionsByParentPkgName[targetPkg.name][parentPkg.name] = [];
}
allowedVersionsByParentPkgName[targetPkg.name][parentPkg.name].push({
parentPkg,
targetPkg,
ranges,
});
}
return {
allowedVersionsMatchAll,
allowedVersionsByParentPkgName,
};
}
function parseVersions(versions) {
return versions.split('||').map(v => v.trim());
}
class PeerDependencyIssuesError extends error_1.PnpmError {
issuesByProjects;
constructor(issues) {
super('PEER_DEP_ISSUES', 'Unmet peer dependencies');
this.issuesByProjects = issues;
}
}
exports.PeerDependencyIssuesError = PeerDependencyIssuesError;
//# sourceMappingURL=reportPeerDependencyIssues.js.map