mirror of
https://github.com/pnpm/pnpm.git
synced 2026-02-02 19:22:52 -05:00
fix: get the final address by installing package through links (#8842)
close #8833 --------- Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
8
.changeset/lovely-candles-report.md
Normal file
8
.changeset/lovely-candles-report.md
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
"@pnpm/default-resolver": major
|
||||
"@pnpm/tarball-resolver": major
|
||||
"@pnpm/core": major
|
||||
"pnpm": major
|
||||
---
|
||||
|
||||
Dependencies specified via a URL are now recorded in the lockfile using their final resolved URL. Thus, if the original URL redirects, the final redirect target will be saved in the lockfile [#8833](https://github.com/pnpm/pnpm/issues/8833).
|
||||
6
.changeset/rare-singers-kneel.md
Normal file
6
.changeset/rare-singers-kneel.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/fetch": minor
|
||||
"@pnpm/fetching-types": minor
|
||||
---
|
||||
|
||||
The `fetch` function accepts a `method` option now.
|
||||
@@ -67,6 +67,7 @@ export function createFetchFromRegistry (
|
||||
},
|
||||
// if verifying integrity, node-fetch must not decompress
|
||||
compress: opts?.compress ?? false,
|
||||
method: opts?.method,
|
||||
headers,
|
||||
redirect: 'manual',
|
||||
retry: opts?.retry,
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import { type RetryTimeoutOptions } from '@zkochan/retry'
|
||||
import { type Response } from 'node-fetch'
|
||||
import { type Response, type RequestInit as NodeRequestInit } from 'node-fetch'
|
||||
|
||||
export type { RetryTimeoutOptions }
|
||||
|
||||
export interface RequestInit extends NodeRequestInit {
|
||||
retry?: RetryTimeoutOptions
|
||||
timeout?: number
|
||||
}
|
||||
|
||||
export type FetchFromRegistry = (
|
||||
url: string,
|
||||
opts?: {
|
||||
opts?: RequestInit & {
|
||||
authHeaderValue?: string
|
||||
compress?: boolean
|
||||
retry?: RetryTimeoutOptions
|
||||
|
||||
@@ -1118,6 +1118,9 @@ test('tarball domain differs from registry domain', async () => {
|
||||
})
|
||||
|
||||
test('tarball installed through non-standard URL endpoint from the registry domain', async () => {
|
||||
nock('https://registry.npmjs.org', { allowUnmocked: true })
|
||||
.head('/is-positive/download/is-positive-3.1.0.tgz')
|
||||
.reply(200, '')
|
||||
nock('https://registry.npmjs.org', { allowUnmocked: true })
|
||||
.get('/is-positive/download/is-positive-3.1.0.tgz')
|
||||
.replyWithFile(200, tarballPath)
|
||||
|
||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@@ -6517,10 +6517,16 @@ importers:
|
||||
|
||||
resolving/tarball-resolver:
|
||||
dependencies:
|
||||
'@pnpm/fetching-types':
|
||||
specifier: workspace:*
|
||||
version: link:../../network/fetching-types
|
||||
'@pnpm/resolver-base':
|
||||
specifier: workspace:*
|
||||
version: link:../resolver-base
|
||||
devDependencies:
|
||||
'@pnpm/fetch':
|
||||
specifier: workspace:*
|
||||
version: link:../../network/fetch
|
||||
'@pnpm/tarball-resolver':
|
||||
specifier: workspace:*
|
||||
version: 'link:'
|
||||
|
||||
@@ -30,7 +30,7 @@ export function createResolver (
|
||||
resolve: async (wantedDependency, opts) => {
|
||||
const resolution = await resolveFromNpm(wantedDependency, opts as ResolveFromNpmOptions) ??
|
||||
(wantedDependency.pref && (
|
||||
await resolveFromTarball(wantedDependency as { pref: string }) ??
|
||||
await resolveFromTarball(fetchFromRegistry, wantedDependency as { pref: string }) ??
|
||||
await resolveFromGit(wantedDependency as { pref: string }) ??
|
||||
await resolveFromLocal(wantedDependency as { pref: string }, opts)
|
||||
))
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
},
|
||||
"homepage": "https://github.com/pnpm/pnpm/blob/main/resolving/tarball-resolver#readme",
|
||||
"dependencies": {
|
||||
"@pnpm/fetching-types": "workspace:*",
|
||||
"@pnpm/resolver-base": "workspace:*"
|
||||
},
|
||||
"funding": "https://opencollective.com/pnpm",
|
||||
@@ -33,6 +34,7 @@
|
||||
"pnpm10"
|
||||
],
|
||||
"devDependencies": {
|
||||
"@pnpm/fetch": "workspace:*",
|
||||
"@pnpm/tarball-resolver": "workspace:*"
|
||||
},
|
||||
"exports": {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { type PkgResolutionId, type ResolveResult } from '@pnpm/resolver-base'
|
||||
import { type FetchFromRegistry } from '@pnpm/fetching-types'
|
||||
|
||||
export async function resolveFromTarball (
|
||||
fetchFromRegistry: FetchFromRegistry,
|
||||
wantedDependency: { pref: string }
|
||||
): Promise<ResolveResult | null> {
|
||||
if (!wantedDependency.pref.startsWith('http:') && !wantedDependency.pref.startsWith('https:')) {
|
||||
@@ -9,11 +11,14 @@ export async function resolveFromTarball (
|
||||
|
||||
if (isRepository(wantedDependency.pref)) return null
|
||||
|
||||
// If there are redirects, we want to get the final URL address
|
||||
const { url: resolvedUrl } = await fetchFromRegistry(wantedDependency.pref, { method: 'HEAD' })
|
||||
|
||||
return {
|
||||
id: wantedDependency.pref as PkgResolutionId,
|
||||
normalizedPref: wantedDependency.pref,
|
||||
id: resolvedUrl as PkgResolutionId,
|
||||
normalizedPref: resolvedUrl,
|
||||
resolution: {
|
||||
tarball: wantedDependency.pref,
|
||||
tarball: resolvedUrl,
|
||||
},
|
||||
resolvedVia: 'url',
|
||||
}
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
/// <reference path="../../../__typings__/index.d.ts"/>
|
||||
// cspell:ignore buildserver
|
||||
import { resolveFromTarball } from '@pnpm/tarball-resolver'
|
||||
import { resolveFromTarball as _resolveFromTarball } from '@pnpm/tarball-resolver'
|
||||
import { createFetchFromRegistry } from '@pnpm/fetch'
|
||||
|
||||
const fetch = createFetchFromRegistry({})
|
||||
const resolveFromTarball = _resolveFromTarball.bind(null, fetch)
|
||||
|
||||
test('tarball from npm registry', async () => {
|
||||
const resolutionResult = await resolveFromTarball({ pref: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz' })
|
||||
|
||||
expect(resolutionResult).toStrictEqual({
|
||||
id: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
|
||||
normalizedPref: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
|
||||
id: 'https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
|
||||
normalizedPref: 'https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
|
||||
resolution: {
|
||||
tarball: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
|
||||
tarball: 'https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
|
||||
},
|
||||
resolvedVia: 'url',
|
||||
})
|
||||
})
|
||||
|
||||
test('tarball from URL that contain port number', async () => {
|
||||
const resolutionResult = await resolveFromTarball({ pref: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz' })
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const fetch: any = async (url: string) => ({ url })
|
||||
const resolutionResult = await _resolveFromTarball(fetch, { pref: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz' })
|
||||
|
||||
expect(resolutionResult).toStrictEqual({
|
||||
id: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz',
|
||||
@@ -32,10 +38,10 @@ test('tarball not from npm registry', async () => {
|
||||
const resolutionResult = await resolveFromTarball({ pref: 'https://github.com/hegemonic/taffydb/tarball/master' })
|
||||
|
||||
expect(resolutionResult).toStrictEqual({
|
||||
id: 'https://github.com/hegemonic/taffydb/tarball/master',
|
||||
normalizedPref: 'https://github.com/hegemonic/taffydb/tarball/master',
|
||||
id: 'https://codeload.github.com/hegemonic/taffydb/legacy.tar.gz/refs/heads/master',
|
||||
normalizedPref: 'https://codeload.github.com/hegemonic/taffydb/legacy.tar.gz/refs/heads/master',
|
||||
resolution: {
|
||||
tarball: 'https://github.com/hegemonic/taffydb/tarball/master',
|
||||
tarball: 'https://codeload.github.com/hegemonic/taffydb/legacy.tar.gz/refs/heads/master',
|
||||
},
|
||||
resolvedVia: 'url',
|
||||
})
|
||||
@@ -45,10 +51,10 @@ test('tarballs from GitHub (is-negative)', async () => {
|
||||
const resolutionResult = await resolveFromTarball({ pref: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz' })
|
||||
|
||||
expect(resolutionResult).toStrictEqual({
|
||||
id: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz',
|
||||
normalizedPref: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz',
|
||||
id: 'https://codeload.github.com/kevva/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
|
||||
normalizedPref: 'https://codeload.github.com/kevva/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
|
||||
resolution: {
|
||||
tarball: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz',
|
||||
tarball: 'https://codeload.github.com/kevva/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
|
||||
},
|
||||
resolvedVia: 'url',
|
||||
})
|
||||
|
||||
@@ -9,6 +9,12 @@
|
||||
"../../__typings__/**/*.d.ts"
|
||||
],
|
||||
"references": [
|
||||
{
|
||||
"path": "../../network/fetch"
|
||||
},
|
||||
{
|
||||
"path": "../../network/fetching-types"
|
||||
},
|
||||
{
|
||||
"path": "../resolver-base"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user