mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-30 20:16:38 -04:00
fix: validate that the version in the lockfile satisfies the range (#9832)
This commit is contained in:
5
.changeset/bumpy-cups-arrive.md
Normal file
5
.changeset/bumpy-cups-arrive.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/lockfile.verification": patch
|
||||
---
|
||||
|
||||
satisfiesPackageManifest also checks if the version in the importer satisfied the range in the `package.json`.
|
||||
@@ -1,3 +1,4 @@
|
||||
import * as dp from '@pnpm/dependency-path'
|
||||
import { type ProjectSnapshot } from '@pnpm/lockfile.types'
|
||||
import {
|
||||
DEPENDENCIES_FIELDS,
|
||||
@@ -6,6 +7,7 @@ import {
|
||||
import equals from 'ramda/src/equals'
|
||||
import pickBy from 'ramda/src/pickBy'
|
||||
import omit from 'ramda/src/omit'
|
||||
import semver from 'semver'
|
||||
import { type Diff, diffFlatRecords, isEqual } from './diffFlatRecords'
|
||||
|
||||
export function satisfiesPackageManifest (
|
||||
@@ -95,6 +97,14 @@ export function satisfiesPackageManifest (
|
||||
detailedReason: `importer ${depField}.${depName} specifier ${importer.specifiers[depName]} don't match package manifest specifier (${pkgDeps[depName]})`,
|
||||
}
|
||||
}
|
||||
if (importer?.specifiers[depName] == null || !semver.validRange(importer?.specifiers[depName])) continue
|
||||
const version = dp.removeSuffix(importerDeps[depName])
|
||||
if (semver.valid(version) && !semver.satisfies(version, importer.specifiers[depName])) {
|
||||
return {
|
||||
satisfies: false,
|
||||
detailedReason: `The importer resolution is broken at dependency "${depName}": version "${version}" doesn't satisfy range "${importer.specifiers[depName]}"`,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return { satisfies: true }
|
||||
|
||||
@@ -866,3 +866,37 @@ test('allProjectsAreUpToDate(): returns true if one of the importers is not pres
|
||||
lockfileDir: '',
|
||||
})).toBeTruthy()
|
||||
})
|
||||
|
||||
test('allProjectsAreUpToDate(): returns false if the lockfile is broken, the resolved versions do not satisfy the ranges', async () => {
|
||||
expect(await allProjectsAreUpToDate([
|
||||
{
|
||||
id: '.' as ProjectId,
|
||||
manifest: {
|
||||
dependencies: {
|
||||
'@apollo/client': '3.3.7',
|
||||
},
|
||||
},
|
||||
rootDir: '.' as ProjectRootDir,
|
||||
},
|
||||
], {
|
||||
autoInstallPeers: false,
|
||||
catalogs: {},
|
||||
excludeLinksFromLockfile: false,
|
||||
linkWorkspacePackages: true,
|
||||
wantedLockfile: {
|
||||
importers: {
|
||||
['.' as ProjectId]: {
|
||||
dependencies: {
|
||||
'@apollo/client': '3.13.8(@types/react@18.3.23)(graphql@15.8.0)(react-dom@17.0.2(react@17.0.2))(react@17.0.2)(subscriptions-transport-ws@0.11.0(graphql@15.8.0))',
|
||||
},
|
||||
specifiers: {
|
||||
'@apollo/client': '3.3.7',
|
||||
},
|
||||
},
|
||||
},
|
||||
lockfileVersion: LOCKFILE_VERSION,
|
||||
},
|
||||
workspacePackages,
|
||||
lockfileDir: '',
|
||||
})).toBeFalsy()
|
||||
})
|
||||
|
||||
@@ -378,4 +378,20 @@ test('satisfiesPackageManifest()', () => {
|
||||
},
|
||||
}
|
||||
)).toStrictEqual({ satisfies: true })
|
||||
|
||||
expect(satisfiesPackageManifest({}, {
|
||||
dependencies: {
|
||||
'@apollo/client': '3.13.8(@types/react@18.3.23)(graphql@15.8.0)(react-dom@17.0.2(react@17.0.2))(react@17.0.2)(subscriptions-transport-ws@0.11.0(graphql@15.8.0))',
|
||||
},
|
||||
specifiers: {
|
||||
'@apollo/client': '3.3.7',
|
||||
},
|
||||
}, {
|
||||
dependencies: {
|
||||
'@apollo/client': '3.3.7',
|
||||
},
|
||||
})).toStrictEqual({
|
||||
satisfies: false,
|
||||
detailedReason: 'The importer resolution is broken at dependency "@apollo/client": version "3.13.8" doesn\'t satisfy range "3.3.7"',
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user