Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/solid-regions-ring.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@pnpm/npm-resolver": patch
"pnpm": patch
---

Normalize the tarball URLs before saving them to the lockfile. URLs should not contain default ports, like :80 for http and :443 for https [#10273](https://github.com/pnpm/pnpm/pull/10273).
5 changes: 3 additions & 2 deletions resolving/npm-resolver/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import { workspacePrefToNpm } from './workspacePrefToNpm.js'
import { whichVersionIsPinned } from './whichVersionIsPinned.js'
import { pickVersionByVersionRange } from './pickPackageFromMeta.js'
import { failIfTrustDowngraded } from './trustChecks.js'
import { normalizeRegistryUrl } from './normalizeRegistryUrl.js'

export interface NoMatchingVersionErrorOptions {
wantedDependency: WantedDependency
Expand Down Expand Up @@ -348,7 +349,7 @@ async function resolveNpm (
const id = `${pickedPackage.name}@${pickedPackage.version}` as PkgResolutionId
const resolution = {
integrity: getIntegrity(pickedPackage.dist),
tarball: pickedPackage.dist.tarball,
tarball: normalizeRegistryUrl(pickedPackage.dist.tarball),
}
let normalizedBareSpecifier: string | undefined
if (opts.calcSpecifier) {
Expand Down Expand Up @@ -400,7 +401,7 @@ async function resolveJsr (
const id = `${pickedPackage.name}@${pickedPackage.version}` as PkgResolutionId
const resolution = {
integrity: getIntegrity(pickedPackage.dist),
tarball: pickedPackage.dist.tarball,
tarball: normalizeRegistryUrl(pickedPackage.dist.tarball),
}
return {
id,
Expand Down
10 changes: 10 additions & 0 deletions resolving/npm-resolver/src/normalizeRegistryUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Remove default ports (80 for HTTP, 443 for HTTPS) to ensure consistency
*/
export function normalizeRegistryUrl (urlString: string): string {
try {
return new URL(urlString).toString()
} catch {
return urlString
}
}
29 changes: 29 additions & 0 deletions resolving/npm-resolver/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,35 @@ test('resolveFromNpm()', async () => {
expect(meta['dist-tags']).toBeTruthy()
})

test('resolveFromNpm() strips port 80 from http tarball URLs', async () => {
nock(registries.default)
.get('/is-positive')
.reply(200, {
...isPositiveMeta,
versions: {
'1.0.0': {
...isPositiveMeta.versions['1.0.0'],
dist: {
...isPositiveMeta.versions['1.0.0'].dist,
tarball: 'http://registry.npmjs.org:80/is-positive/-/is-positive-1.0.0.tgz',
},
},
},
})

const cacheDir = temporaryDirectory()
const { resolveFromNpm } = createResolveFromNpm({
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, { calcSpecifier: true })

expect(resolveResult!.resolution).toStrictEqual({
integrity: 'sha512-9cI+DmhNhA8ioT/3EJFnt0s1yehnAECyIOXdT+2uQGzcEEBaj8oNmVWj33+ZjPndMIFRQh8JeJlEu1uv5/J7pQ==',
tarball: 'http://registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz',
})
})

test('resolveFromNpm() does not save mutated meta to the cache', async () => {
nock(registries.default)
.get('/is-positive')
Expand Down
14 changes: 14 additions & 0 deletions resolving/npm-resolver/test/normalizeRegistryUrl.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { normalizeRegistryUrl } from '../lib/normalizeRegistryUrl.js'

test.each([
['https://registry.example.com:443/package.tgz', 'https://registry.example.com/package.tgz'],
['http://registry.example.com:80/package.tgz', 'http://registry.example.com/package.tgz'],
['https://registry.example.com:8443/package.tgz', 'https://registry.example.com:8443/package.tgz'],
['http://registry.example.com:8080/package.tgz', 'http://registry.example.com:8080/package.tgz'],
['https://registry.example.com/package.tgz', 'https://registry.example.com/package.tgz'],
['http://registry.example.com/package.tgz', 'http://registry.example.com/package.tgz'],
['https://artifactory:443/api/npm/npm-virtual/uuid/-/uuid-9.0.1.tgz', 'https://artifactory/api/npm/npm-virtual/uuid/-/uuid-9.0.1.tgz'],
['invalid-url', 'invalid-url'],
])('normalizeRegistryUrl(%s) should return %s', (input, expected) => {
expect(normalizeRegistryUrl(input)).toBe(expected)
})
Loading