mirror of
https://github.com/pnpm/pnpm.git
synced 2026-05-16 12:51:45 -04:00
feat!: remove old API for custom fetchers (#10464)
This commit is contained in:
5
.changeset/whole-jobs-return.md
Normal file
5
.changeset/whole-jobs-return.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"pnpm": major
|
||||
---
|
||||
|
||||
Removed support for `hooks.fetchers`. We now have a new API for custom fetchers and resolvers via the `fetchers` field of `pnpmfile`.
|
||||
@@ -77,17 +77,3 @@ export interface Fetchers {
|
||||
git: GitFetcher
|
||||
binary: BinaryFetcher
|
||||
}
|
||||
|
||||
interface CustomFetcherFactoryOptions {
|
||||
defaultFetchers: Fetchers
|
||||
}
|
||||
|
||||
export type CustomFetcherFactory<Fetcher> = (opts: CustomFetcherFactoryOptions) => Fetcher
|
||||
|
||||
export interface CustomFetchers {
|
||||
localTarball?: CustomFetcherFactory<FetchFunction>
|
||||
remoteTarball?: CustomFetcherFactory<FetchFunction>
|
||||
gitHostedTarball?: CustomFetcherFactory<FetchFunction>
|
||||
directory?: CustomFetcherFactory<DirectoryFetcher>
|
||||
git?: CustomFetcherFactory<GitFetcher>
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import { type PreResolutionHook } from '@pnpm/hooks.types'
|
||||
import { type LockfileObject } from '@pnpm/lockfile.types'
|
||||
import { type Log } from '@pnpm/core-loggers'
|
||||
import { type CustomFetchers } from '@pnpm/fetcher-base'
|
||||
import { type ImportIndexedPackageAsync } from '@pnpm/store-controller-types'
|
||||
|
||||
export interface HookContext {
|
||||
@@ -17,10 +16,6 @@ export interface Hooks {
|
||||
afterAllResolved?: (lockfile: LockfileObject, context: HookContext) => LockfileObject | Promise<LockfileObject>
|
||||
filterLog?: (log: Log) => boolean
|
||||
importPackage?: ImportIndexedPackageAsync
|
||||
/**
|
||||
* @deprecated Use top-level `fetchers` export instead. This will be removed in a future version.
|
||||
*/
|
||||
fetchers?: CustomFetchers
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Flexible hook signature for any config object
|
||||
updateConfig?: (config: any) => any
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import { PnpmError } from '@pnpm/error'
|
||||
import { hookLogger } from '@pnpm/core-loggers'
|
||||
import { createHashFromMultipleFiles } from '@pnpm/crypto.hash'
|
||||
import pathAbsolute from 'path-absolute'
|
||||
import type { CustomFetchers } from '@pnpm/fetcher-base'
|
||||
import { type ImportIndexedPackageAsync } from '@pnpm/store-controller-types'
|
||||
import { type ReadPackageHook, type BeforePackingHook, type BaseManifest } from '@pnpm/types'
|
||||
import { type LockfileObject } from '@pnpm/lockfile.types'
|
||||
@@ -40,7 +39,6 @@ export interface CookedHooks {
|
||||
filterLog?: Array<Cook<Required<Hooks>['filterLog']>>
|
||||
updateConfig?: Array<Cook<Required<Hooks>['updateConfig']>>
|
||||
importPackage?: ImportIndexedPackageAsync
|
||||
fetchers?: CustomFetchers
|
||||
customResolvers?: CustomResolver[]
|
||||
customFetchers?: CustomFetcher[]
|
||||
calculatePnpmfileChecksum?: () => Promise<string>
|
||||
@@ -129,7 +127,6 @@ export async function requireHooks (
|
||||
}
|
||||
|
||||
let importProvider: string | undefined
|
||||
let fetchersProvider: string | undefined
|
||||
const finderProviders: Record<string, string> = {}
|
||||
|
||||
// process hooks in order
|
||||
@@ -204,18 +201,6 @@ export async function requireHooks (
|
||||
importProvider = file
|
||||
cookedHooks.importPackage = fileHooks.importPackage
|
||||
}
|
||||
|
||||
// fetchers: only one allowed
|
||||
if (fileHooks.fetchers) {
|
||||
if (fetchersProvider) {
|
||||
throw new PnpmError(
|
||||
'MULTIPLE_FETCHERS',
|
||||
`fetchers hook defined in both ${fetchersProvider} and ${file}`
|
||||
)
|
||||
}
|
||||
fetchersProvider = file
|
||||
cookedHooks.fetchers = fileHooks.fetchers
|
||||
}
|
||||
}
|
||||
|
||||
// Process top-level resolvers and fetchers exports
|
||||
|
||||
@@ -7,19 +7,17 @@ import { type AgentOptions, createFetchFromRegistry } from '@pnpm/fetch'
|
||||
import { type SslConfig } from '@pnpm/types'
|
||||
import { type CustomResolver, type CustomFetcher as CustomFetcherHook } from '@pnpm/hooks.types'
|
||||
import { type FetchFromRegistry, type GetAuthHeader, type RetryTimeoutOptions } from '@pnpm/fetching-types'
|
||||
import type { CustomFetchers, GitFetcher, DirectoryFetcher, BinaryFetcher } from '@pnpm/fetcher-base'
|
||||
import type { GitFetcher, DirectoryFetcher, BinaryFetcher } from '@pnpm/fetcher-base'
|
||||
import { createDirectoryFetcher } from '@pnpm/directory-fetcher'
|
||||
import { createGitFetcher } from '@pnpm/git-fetcher'
|
||||
import { createTarballFetcher, type TarballFetchers } from '@pnpm/tarball-fetcher'
|
||||
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header'
|
||||
import { createBinaryFetcher } from '@pnpm/fetching.binary-fetcher'
|
||||
import { map as mapValues } from 'ramda'
|
||||
|
||||
export type { ResolveFunction }
|
||||
|
||||
export type ClientOptions = {
|
||||
authConfig: Record<string, string>
|
||||
customFetchers?: CustomFetchers
|
||||
customResolvers?: CustomResolver[]
|
||||
customFetcherHooks?: CustomFetcherHook[]
|
||||
ignoreScripts?: boolean
|
||||
@@ -49,7 +47,7 @@ export function createClient (opts: ClientOptions): Client {
|
||||
|
||||
const { resolve, clearCache: clearResolutionCache } = _createResolver(fetchFromRegistry, getAuthHeader, { ...opts, customResolvers: opts.customResolvers })
|
||||
return {
|
||||
fetchers: createFetchers(fetchFromRegistry, getAuthHeader, opts, opts.customFetchers),
|
||||
fetchers: createFetchers(fetchFromRegistry, getAuthHeader, opts),
|
||||
resolve,
|
||||
clearResolutionCache,
|
||||
}
|
||||
@@ -71,11 +69,10 @@ type Fetchers = {
|
||||
function createFetchers (
|
||||
fetchFromRegistry: FetchFromRegistry,
|
||||
getAuthHeader: GetAuthHeader,
|
||||
opts: Pick<ClientOptions, 'rawConfig' | 'retry' | 'gitShallowHosts' | 'resolveSymlinksInInjectedDirs' | 'unsafePerm' | 'includeOnlyPackageFiles' | 'offline' | 'fetchMinSpeedKiBps'>,
|
||||
customFetchers?: CustomFetchers
|
||||
opts: Pick<ClientOptions, 'rawConfig' | 'retry' | 'gitShallowHosts' | 'resolveSymlinksInInjectedDirs' | 'unsafePerm' | 'includeOnlyPackageFiles' | 'offline' | 'fetchMinSpeedKiBps'>
|
||||
): Fetchers {
|
||||
const tarballFetchers = createTarballFetcher(fetchFromRegistry, getAuthHeader, opts)
|
||||
const defaultFetchers = {
|
||||
return {
|
||||
...tarballFetchers,
|
||||
...createGitFetcher(opts),
|
||||
...createDirectoryFetcher({ resolveSymlinks: opts.resolveSymlinksInInjectedDirs, includeOnlyPackageFiles: opts.includeOnlyPackageFiles }),
|
||||
@@ -86,14 +83,4 @@ function createFetchers (
|
||||
rawConfig: opts.rawConfig,
|
||||
}),
|
||||
}
|
||||
|
||||
const overwrites = mapValues(
|
||||
(factory: any) => factory({ defaultFetchers }), // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
customFetchers ?? {} as any // eslint-disable-line @typescript-eslint/no-explicit-any
|
||||
)
|
||||
|
||||
return {
|
||||
...defaultFetchers,
|
||||
...overwrites,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import path from 'path'
|
||||
import { createHash } from '@pnpm/crypto.hash'
|
||||
import { type PackageManifest } from '@pnpm/types'
|
||||
import { prepare, preparePackages } from '@pnpm/prepare'
|
||||
import { REGISTRY_MOCK_PORT, getIntegrity } from '@pnpm/registry-mock'
|
||||
import { getIntegrity } from '@pnpm/registry-mock'
|
||||
import { loadJsonFileSync } from 'load-json-file'
|
||||
import { sync as writeYamlFile } from 'write-yaml-file'
|
||||
import { execPnpm, execPnpmSync } from './utils/index.js'
|
||||
@@ -158,70 +158,6 @@ test('importPackage hooks', async () => {
|
||||
])
|
||||
})
|
||||
|
||||
test('should use default fetchers if no custom fetchers are defined', async () => {
|
||||
const project = prepare()
|
||||
|
||||
const pnpmfile = `
|
||||
const fs = require('fs')
|
||||
|
||||
module.exports = {
|
||||
hooks: {
|
||||
fetchers: {}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
writeYamlFile('pnpm-workspace.yaml', {
|
||||
globalPnpmfile: '.pnpmfile.cjs',
|
||||
})
|
||||
|
||||
fs.writeFileSync('.pnpmfile.cjs', pnpmfile, 'utf8')
|
||||
|
||||
await execPnpm(['add', 'is-positive@1.0.0'])
|
||||
|
||||
project.cafsHas('is-positive', '1.0.0')
|
||||
})
|
||||
|
||||
test('custom fetcher can call default fetcher', async () => {
|
||||
const project = prepare()
|
||||
|
||||
const pnpmfile = `
|
||||
const fs = require('fs')
|
||||
|
||||
module.exports = {
|
||||
hooks: {
|
||||
fetchers: {
|
||||
remoteTarball: ({ defaultFetchers }) => {
|
||||
return (cafs, resolution, opts) => {
|
||||
fs.writeFileSync('args.json', JSON.stringify({ resolution, opts }), 'utf8')
|
||||
return defaultFetchers.remoteTarball(cafs, resolution, opts)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
writeYamlFile('pnpm-workspace.yaml', {
|
||||
globalPnpmfile: '.pnpmfile.cjs',
|
||||
})
|
||||
|
||||
fs.writeFileSync('.pnpmfile.cjs', pnpmfile, 'utf8')
|
||||
|
||||
await execPnpm(['add', 'is-positive@1.0.0'])
|
||||
|
||||
project.cafsHas('is-positive', '1.0.0')
|
||||
|
||||
const args = loadJsonFileSync<any>('args.json') // eslint-disable-line
|
||||
|
||||
expect(args.resolution).toEqual({
|
||||
integrity: 'sha512-xxzPGZ4P2uN6rROUa5N9Z7zTX6ERuE0hs6GUOc/cKBLF2NqKc16UwqHMt3tFg4CO6EBTE5UecUasg+3jZx3Ckg==',
|
||||
tarball: `http://localhost:${REGISTRY_MOCK_PORT}/is-positive/-/is-positive-1.0.0.tgz`,
|
||||
})
|
||||
|
||||
expect(args.opts).toBeDefined()
|
||||
})
|
||||
|
||||
test('adding or changing pnpmfile should change pnpmfileChecksum and module structure', async () => {
|
||||
const project = prepare({
|
||||
dependencies: {
|
||||
|
||||
@@ -65,7 +65,6 @@ export async function createNewStoreController (
|
||||
) && !opts.registrySupportsTimeField
|
||||
)
|
||||
const { resolve, fetchers, clearResolutionCache } = createClient({
|
||||
customFetchers: opts.hooks?.fetchers,
|
||||
customResolvers: opts.hooks?.customResolvers,
|
||||
customFetcherHooks: opts.hooks?.customFetchers,
|
||||
userConfig: opts.userConfig,
|
||||
|
||||
Reference in New Issue
Block a user