mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-28 20:11:48 -04:00
6
.changeset/four-adults-burn.md
Normal file
6
.changeset/four-adults-burn.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/resolve-dependencies": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Resolve peer dependencies correctly, when they have prerelease versions [#7977](https://github.com/pnpm/pnpm/issues/7977).
|
||||
29
pkg-manager/resolve-dependencies/src/hoistPeers.ts
Normal file
29
pkg-manager/resolve-dependencies/src/hoistPeers.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
import { type PreferredVersions } from '@pnpm/resolver-base'
|
||||
import semver from 'semver'
|
||||
|
||||
export function hoistPeers (
|
||||
missingRequiredPeers: Array<[string, { range: string }]>,
|
||||
opts: {
|
||||
autoInstallPeers: boolean
|
||||
allPreferredVersions?: PreferredVersions
|
||||
}
|
||||
): Record<string, string> {
|
||||
const dependencies: Record<string, string> = {}
|
||||
for (const [peerName, { range }] of missingRequiredPeers) {
|
||||
if (opts.allPreferredVersions![peerName]) {
|
||||
const versions: string[] = []
|
||||
const nonVersions: string[] = []
|
||||
for (const [spec, specType] of Object.entries(opts.allPreferredVersions![peerName])) {
|
||||
if (specType === 'version') {
|
||||
versions.push(spec)
|
||||
} else {
|
||||
nonVersions.push(spec)
|
||||
}
|
||||
}
|
||||
dependencies[peerName] = [semver.maxSatisfying(versions, '*', { includePrerelease: true }), ...nonVersions].join(' || ')
|
||||
} else if (opts.autoInstallPeers) {
|
||||
dependencies[peerName] = range
|
||||
}
|
||||
}
|
||||
return dependencies
|
||||
}
|
||||
@@ -57,6 +57,7 @@ import {
|
||||
nodeIdContains,
|
||||
splitNodeId,
|
||||
} from './nodeIdUtils'
|
||||
import { hoistPeers } from './hoistPeers'
|
||||
import { wantedDepIsLocallyAvailable } from './wantedDepIsLocallyAvailable'
|
||||
import { replaceVersionInPref } from './replaceVersionInPref'
|
||||
|
||||
@@ -329,23 +330,7 @@ export async function resolveRootDependencies (
|
||||
)
|
||||
)
|
||||
if (!missingRequiredPeers.length && !missingOptionalPeerNames.length) break
|
||||
const dependencies: Record<string, string> = {}
|
||||
for (const [peerName, { range }] of missingRequiredPeers) {
|
||||
if (ctx.allPreferredVersions![peerName]) {
|
||||
const versions: string[] = []
|
||||
const nonVersions: string[] = []
|
||||
for (const [spec, specType] of Object.entries(ctx.allPreferredVersions![peerName])) {
|
||||
if (specType === 'version') {
|
||||
versions.push(spec)
|
||||
} else {
|
||||
nonVersions.push(spec)
|
||||
}
|
||||
}
|
||||
dependencies[peerName] = [semver.maxSatisfying(versions, '*'), ...nonVersions].join(' || ')
|
||||
} else if (ctx.autoInstallPeers) {
|
||||
dependencies[peerName] = range
|
||||
}
|
||||
}
|
||||
const dependencies = hoistPeers(missingRequiredPeers, ctx)
|
||||
const nextMissingOptionalPeers: string[] = []
|
||||
const optionalDependencies: Record<string, string> = {}
|
||||
for (const missingOptionalPeerName of missingOptionalPeerNames) {
|
||||
|
||||
14
pkg-manager/resolve-dependencies/test/hoistPeers.test.ts
Normal file
14
pkg-manager/resolve-dependencies/test/hoistPeers.test.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { hoistPeers } from '../lib/hoistPeers'
|
||||
|
||||
test('hoistPeers picks an already available prerelease version', () => {
|
||||
expect(hoistPeers([['foo', { range: '*' }]], {
|
||||
autoInstallPeers: false,
|
||||
allPreferredVersions: {
|
||||
foo: {
|
||||
'1.0.0-beta.0': 'version',
|
||||
},
|
||||
},
|
||||
})).toStrictEqual({
|
||||
foo: '1.0.0-beta.0',
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user