mirror of
https://github.com/pnpm/pnpm.git
synced 2026-03-31 13:32:18 -04:00
fix(npm-resolver): throw a meaningful error on malformed meta
close #3013 PR #3019
This commit is contained in:
5
.changeset/hip-clocks-share.md
Normal file
5
.changeset/hip-clocks-share.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/npm-resolver": patch
|
||||
---
|
||||
|
||||
Throw a meaningful error on malformed registry metadata.
|
||||
@@ -1,3 +1,4 @@
|
||||
import PnpmError from '@pnpm/error'
|
||||
import { VersionSelectors } from '@pnpm/resolver-base'
|
||||
import { RegistryPackageSpec } from './parsePref'
|
||||
import { PackageInRegistry, PackageMeta } from './pickPackage'
|
||||
@@ -8,28 +9,35 @@ export default function (
|
||||
preferredVersionSelectors: VersionSelectors | undefined,
|
||||
meta: PackageMeta
|
||||
): PackageInRegistry {
|
||||
let version!: string
|
||||
switch (spec.type) {
|
||||
case 'version':
|
||||
version = spec.fetchSpec
|
||||
break
|
||||
case 'tag':
|
||||
version = meta['dist-tags'][spec.fetchSpec]
|
||||
break
|
||||
case 'range':
|
||||
version = pickVersionByVersionRange(meta, spec.fetchSpec, preferredVersionSelectors)
|
||||
break
|
||||
try {
|
||||
let version!: string
|
||||
switch (spec.type) {
|
||||
case 'version':
|
||||
version = spec.fetchSpec
|
||||
break
|
||||
case 'tag':
|
||||
version = meta['dist-tags'][spec.fetchSpec]
|
||||
break
|
||||
case 'range':
|
||||
version = pickVersionByVersionRange(meta, spec.fetchSpec, preferredVersionSelectors)
|
||||
break
|
||||
}
|
||||
const manifest = meta.versions[version]
|
||||
if (manifest && meta['name']) {
|
||||
// Packages that are published to the GitHub registry are always published with a scope.
|
||||
// However, the name in the package.json for some reason may omit the scope.
|
||||
// So the package published to the GitHub registry will be published under @foo/bar
|
||||
// but the name in package.json will be just bar.
|
||||
// In order to avoid issues, we consider that the real name of the package is the one with the scope.
|
||||
manifest.name = meta['name']
|
||||
}
|
||||
return manifest
|
||||
} catch (err) {
|
||||
throw new PnpmError('MALFORMED_METADATA',
|
||||
`Received malformed metadata for "${spec.name}"`,
|
||||
{ hint: 'This might mean that the package was unpublished from the registry' }
|
||||
)
|
||||
}
|
||||
const manifest = meta.versions[version]
|
||||
if (manifest && meta['name']) {
|
||||
// Packages that are published to the GitHub registry are always published with a scope.
|
||||
// However, the name in the package.json for some reason may omit the scope.
|
||||
// So the package published to the GitHub registry will be published under @foo/bar
|
||||
// but the name in package.json will be just bar.
|
||||
// In order to avoid issues, we consider that the real name of the package is the one with the scope.
|
||||
manifest.name = meta['name']
|
||||
}
|
||||
return manifest
|
||||
}
|
||||
|
||||
function pickVersionByVersionRange (
|
||||
|
||||
@@ -1535,3 +1535,17 @@ 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 () => {
|
||||
nock(registry)
|
||||
.get('/code-snippet')
|
||||
.reply(200, loadJsonFile.sync(path.join(__dirname, 'meta/malformed.json')))
|
||||
|
||||
const storeDir = tempy.directory()
|
||||
const resolve = createResolveFromNpm({ storeDir })
|
||||
|
||||
await expect(resolve({ alias: 'code-snippet' }, { registry })).rejects
|
||||
.toThrow(
|
||||
new PnpmError('MALFORMED_METADATA', 'Received malformed metadata for "code-snippet"')
|
||||
)
|
||||
})
|
||||
|
||||
27
packages/npm-resolver/test/meta/malformed.json
Normal file
27
packages/npm-resolver/test/meta/malformed.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"_id": "code-snippet",
|
||||
"_rev": "2-b2defd889997bf20ca640c1a9b38d82c",
|
||||
"name": "code-snippet",
|
||||
"time": {
|
||||
"modified": "2015-07-31T03:43:17.076Z",
|
||||
"created": "2015-07-31T03:43:17.076Z",
|
||||
"1.0.4": "2015-07-31T03:43:17.076Z",
|
||||
"unpublished": {
|
||||
"name": "nhnent",
|
||||
"time": "2015-07-31T03:52:16.267Z",
|
||||
"tags": {
|
||||
"latest": "1.0.4"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "nhnent",
|
||||
"email": "dl_javascript@nhnent.com"
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
"1.0.4"
|
||||
]
|
||||
}
|
||||
},
|
||||
"_attachments": {}
|
||||
}
|
||||
Reference in New Issue
Block a user