fix(npm-resolver): avoid conflicts in metadata when pkg name is upper case

This commit is contained in:
Zoltan Kochan
2021-05-04 01:03:24 +03:00
parent ae36ac7d3c
commit bf322c7022
4 changed files with 129 additions and 1 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/npm-resolver": patch
---
Avoid conflicts in metadata, when a package name has upper case letters.

View File

@@ -1,3 +1,4 @@
import crypto from 'crypto'
import { promises as fs } from 'fs'
import path from 'path'
import PnpmError from '@pnpm/error'
@@ -76,7 +77,7 @@ export default async (
}
const registryName = getRegistryName(opts.registry)
const pkgMirror = path.join(ctx.storeDir, ctx.metaDir, registryName, `${spec.name}.json`)
const pkgMirror = path.join(ctx.storeDir, ctx.metaDir, registryName, `${encodePkgName(spec.name)}.json`)
const limit = metafileOperationLimits[pkgMirror] = metafileOperationLimits[pkgMirror] || pLimit(1)
let metaCachedInStore: PackageMeta | null | undefined
@@ -146,6 +147,13 @@ export default async (
}
}
function encodePkgName (pkgName: string) {
if (pkgName !== pkgName.toLowerCase()) {
return `${pkgName}_${crypto.createHash('md5').update(pkgName).digest('hex')}`
}
return pkgName
}
async function loadMeta (pkgMirror: string): Promise<PackageMeta | null> {
try {
return await loadJsonFile<PackageMeta>(pkgMirror)

View File

@@ -17,6 +17,7 @@ const isPositiveMetaWithDeprecated = loadJsonFile.sync<any>(path.join(__dirname,
const isPositiveMetaFull = loadJsonFile.sync<any>(path.join(__dirname, 'meta', 'is-positive-full.json'))
const isPositiveBrokenMeta = loadJsonFile.sync<any>(path.join(__dirname, 'meta', 'is-positive-broken.json'))
const sindresorhusIsMeta = loadJsonFile.sync<any>(path.join(__dirname, 'meta', 'sindresorhus-is.json'))
const jsonMeta = loadJsonFile.sync<any>(path.join(__dirname, 'meta', 'JSON.json'))
/* eslint-enable @typescript-eslint/no-explicit-any */
const registry = 'https://registry.npmjs.org/'
@@ -73,6 +74,30 @@ test('resolveFromNpm()', async () => {
expect(meta['dist-tags']).toBeTruthy()
})
test('resolveFromNpm() should save metadata to a unique file when the package name has upper case letters', async () => {
nock(registry)
.get('/JSON')
.reply(200, jsonMeta)
const storeDir = tempy.directory()
const resolve = createResolveFromNpm({
storeDir,
})
const resolveResult = await resolve({ alias: 'JSON', pref: '1.0.0' }, {
registry,
})
expect(resolveResult!.resolvedVia).toBe('npm-registry')
expect(resolveResult!.id).toBe('registry.npmjs.org/JSON/1.0.0')
// The resolve function does not wait for the package meta cache file to be saved
// so we must delay for a bit in order to read it
const meta = await retryLoadJsonFile<any>(path.join(storeDir, 'metadata/registry.npmjs.org/JSON_0ecd11c1d7a287401d148a23bbd7a2f8.json')) // eslint-disable-line @typescript-eslint/no-explicit-any
expect(meta.name).toBeTruthy()
expect(meta.versions).toBeTruthy()
expect(meta['dist-tags']).toBeTruthy()
})
test('relative workspace protocol is skipped', async () => {
const storeDir = tempy.directory()
const resolve = createResolveFromNpm({

View File

@@ -0,0 +1,90 @@
{
"_id": "JSON",
"_rev": "7-cfe2e7994a4dbbf6a471517f1bc1d264",
"name": "JSON",
"description": "Douglas Crockford's json2.js",
"dist-tags": {
"latest": "1.0.0"
},
"versions": {
"1.0.0": {
"author": {
"name": "Douglas Crockford",
"email": "douglas@crockford.com",
"url": "http://crockford.com"
},
"contributors": [
{
"name": "AJ ONeal",
"email": "coolaj86@gmail.com",
"url": "http://coolaj86.info"
}
],
"name": "JSON",
"description": "Douglas Crockford's json2.js",
"keywords": [
"ender"
],
"version": "1.0.0",
"homepage": "http://json.org",
"repository": {
"url": "git://github.com/douglascrockford/JSON-js.git"
},
"main": "json2.js",
"engines": {
"node": ">= 0.2.0"
},
"dependencies": {},
"devDependencies": {},
"_npmJsonOpts": {
"file": "/Users/coolaj86/.npm/JSON/1.0.0/package/package.json",
"wscript": false,
"contributors": false,
"serverjs": false
},
"_id": "JSON@1.0.0",
"_engineSupported": true,
"_npmVersion": "1.0.22",
"_nodeVersion": "v0.4.8",
"_defaultsLoaded": true,
"dist": {
"shasum": "8681531c28f8438a075589ff07248246ea960d8c",
"tarball": "https://registry.npmjs.org/JSON/-/JSON-1.0.0.tgz"
},
"scripts": {},
"maintainers": [
{
"name": "coolaj86",
"email": "coolaj86@gmail.com"
}
],
"directories": {}
}
},
"maintainers": [
{
"name": "coolaj86",
"email": "coolaj86@gmail.com"
}
],
"time": {
"modified": "2018-03-06T01:41:38.380Z",
"created": "2011-09-08T00:38:16.426Z",
"1.0.0": "2011-09-08T00:38:16.795Z"
},
"author": {
"name": "Douglas Crockford",
"email": "douglas@crockford.com",
"url": "http://crockford.com"
},
"repository": {
"url": "git://github.com/douglascrockford/JSON-js.git"
},
"users": {
"ukuli": true,
"zhnoah": true,
"spencermathews": true,
"d3ck": true
},
"_attachments": {}
}