fix: try not to make network requests with prefer offline (#10334)

This commit is contained in:
Sam Chung
2025-12-22 05:04:11 +11:00
committed by Zoltan Kochan
parent 7f4ff92602
commit 080857a3b9
3 changed files with 48 additions and 2 deletions

View File

@@ -0,0 +1,6 @@
---
"@pnpm/npm-resolver": patch
pnpm: patch
---
Try to avoid making network calls with preferOffline [#10334](https://github.com/pnpm/pnpm/pull/10334).

View File

@@ -141,13 +141,14 @@ export async function pickPackage (
if (ctx.offline === true || ctx.preferOffline === true || opts.pickLowestVersion) {
metaCachedInStore = await limit(async () => loadMeta(pkgMirror))
if (ctx.offline) {
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
if (ctx.offline || ctx.preferOffline) {
if (metaCachedInStore != null) return {
meta: metaCachedInStore,
pickedPackage: _pickPackageFromMeta(metaCachedInStore),
}
throw new PnpmError('NO_OFFLINE_META', `Failed to resolve ${toRaw(spec)} in package mirror ${pkgMirror}`)
if (ctx.offline) throw new PnpmError('NO_OFFLINE_META', `Failed to resolve ${toRaw(spec)} in package mirror ${pkgMirror}`)
}
if (metaCachedInStore != null) {

View File

@@ -761,6 +761,45 @@ test('when prefer offline is used, meta from store is used, where latest might b
nock.cleanAll()
})
test('prefer offline does not make network requests when cached metadata exists', async () => {
nock(registries.default)
.get('/is-positive')
.reply(200, isPositiveMeta)
const cacheDir = temporaryDirectory()
{
const { resolveFromNpm } = createResolveFromNpm({
cacheDir,
registries,
})
await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
}
// Wait for the cache file to be written
await retryLoadJsonFile<any>(path.join(cacheDir, ABBREVIATED_META_DIR, 'registry.npmjs.org/is-positive.v8')) // eslint-disable-line @typescript-eslint/no-explicit-any
// Clear all mocks - if a network request is made, nock will throw an error
nock.cleanAll()
nock.disableNetConnect()
{
const { resolveFromNpm } = createResolveFromNpm({
preferOffline: true,
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
expect(resolveResult!.id).toBe('is-positive@1.0.0')
expect(resolveResult!.resolution).toStrictEqual({
integrity: 'sha512-9cI+DmhNhA8ioT/3EJFnt0s1yehnAECyIOXdT+2uQGzcEEBaj8oNmVWj33+ZjPndMIFRQh8JeJlEu1uv5/J7pQ==',
tarball: 'https://registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz',
})
}
})
test('error is thrown when package is not found in the registry', async () => {
const notExistingPackage = 'foo'