Skip to content

Commit

Permalink
refactor: npm-resolver
Browse files Browse the repository at this point in the history
  • Loading branch information
zkochan committed Dec 31, 2022
1 parent de957c9 commit b40d5b3
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 26 deletions.
6 changes: 6 additions & 0 deletions .changeset/gorgeous-islands-shake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@pnpm/npm-resolver": patch
"pnpm": patch
---

Throw an accurate error message when trying to install a package that has no versions, or all of its versions are unpublished [#5849](https://github.com/pnpm/pnpm/issues/5849).
5 changes: 1 addition & 4 deletions resolving/npm-resolver/src/pickPackageFromMeta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function pickPackageFromMeta (
meta: PackageMeta,
publishedBy?: Date
): PackageInRegistry | null {
if (!meta.versions || Object.keys(meta.versions).length === 0) {
if ((!meta.versions || Object.keys(meta.versions).length === 0) && !publishedBy) {
// Unfortunately, the npm registry doesn't return the time field in the abbreviated metadata.
// So we won't always know if the package was unpublished.
if (meta.time?.unpublished?.versions?.length) {
Expand Down Expand Up @@ -51,9 +51,6 @@ export function pickPackageFromMeta (
}
return manifest
} catch (err: any) { // eslint-disable-line
// if (meta.unpublished) {
// throw new PnpmError('UNPUBLISHED_PKG', `Package ${spec.name} has been unpublished`)
// }
throw new PnpmError('MALFORMED_METADATA',
`Received malformed metadata for "${spec.name}"`,
{ hint: 'This might mean that the package was unpublished from the registry' }
Expand Down
64 changes: 42 additions & 22 deletions resolving/npm-resolver/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { fixtures } from '@pnpm/test-fixtures'
import loadJsonFile from 'load-json-file'
import nock from 'nock'
import exists from 'path-exists'
import omit from 'ramda/src/omit'
import tempy from 'tempy'

const f = fixtures(__dirname)
Expand Down Expand Up @@ -45,6 +46,15 @@ async function retryLoadJsonFile<T> (filePath: string) {
}
}

afterEach(() => {
nock.cleanAll()
nock.disableNetConnect()
})

beforeEach(() => {
nock.enableNetConnect()
})

test('resolveFromNpm()', async () => {
nock(registry)
.get('/is-positive')
Expand Down Expand Up @@ -1653,17 +1663,46 @@ test('request to metadata is retried if the received JSON is broken', async () =
expect(resolveResult?.id).toBe('registry.npmjs.org/is-positive/1.0.0')
})

test('request to a package with malformed metadata', async () => {
test('request to a package with unpublished versions', async () => {
nock(registry)
.get('/code-snippet')
.reply(200, loadJsonFile.sync(f.find('malformed.json')))
.reply(200, loadJsonFile.sync(f.find('unpublished.json')))

const cacheDir = tempy.directory()
const resolve = createResolveFromNpm({ cacheDir })

await expect(resolve({ alias: 'code-snippet' }, { registry })).rejects
.toThrow(
new PnpmError('MALFORMED_METADATA', 'Received malformed metadata for "code-snippet"')
new PnpmError('NO_VERSIONS', 'No versions available for code-snippet because it was unpublished')
)
})

test('request to a package with no versions', async () => {
nock(registry)
.get('/code-snippet')
.reply(200, { name: 'code-snippet' })

const cacheDir = tempy.directory()
const resolve = createResolveFromNpm({ cacheDir })

await expect(resolve({ alias: 'code-snippet' }, { registry })).rejects
.toThrow(
new PnpmError('NO_VERSIONS', 'No versions available for code-snippet. The package may be unpublished.')
)
})

test('request to a package with no dist-tags', async () => {
const isPositiveMeta = omit(['dist-tags'], loadJsonFile.sync(f.find('is-positive.json')))
nock(registry)
.get('/is-positive')
.reply(200, isPositiveMeta)

const cacheDir = tempy.directory()
const resolve = createResolveFromNpm({ cacheDir })

await expect(resolve({ alias: 'is-positive' }, { registry })).rejects
.toThrow(
new PnpmError('MALFORMED_METADATA', 'Received malformed metadata for "is-positive"')
)
})

Expand Down Expand Up @@ -1732,22 +1771,3 @@ test('resolveFromNpm() should normalize the registry', async () => {
expect(resolveResult!.manifest!.name).toBe('is-positive')
expect(resolveResult!.manifest!.version).toBe('1.0.0')
})

test('fail when the installed package has no versions', async () => {
nock(registry)
.get('/is-positive')
.reply(200, {
name: 'is-positive',
modified: '2021-09-28T14:21:36.303Z',
})

const cacheDir = tempy.directory()
const resolve = createResolveFromNpm({
cacheDir,
})

await expect(resolve({ alias: 'is-positive', pref: '1.0.0' }, { registry })).rejects
.toThrow(
new PnpmError('NO_VERSIONS', 'No versions available for is-positive. The package may be unpublished.')
)
})

0 comments on commit b40d5b3

Please sign in to comment.