mirror of
https://github.com/pnpm/pnpm.git
synced 2026-02-02 19:22:52 -05:00
refactor: improve resolver types (#9544)
This commit is contained in:
10
.changeset/dull-carrots-matter.md
Normal file
10
.changeset/dull-carrots-matter.md
Normal file
@@ -0,0 +1,10 @@
|
||||
---
|
||||
"@pnpm/default-resolver": minor
|
||||
"@pnpm/tarball-resolver": minor
|
||||
"@pnpm/local-resolver": major
|
||||
"@pnpm/resolver-base": major
|
||||
"@pnpm/git-resolver": minor
|
||||
"@pnpm/npm-resolver": minor
|
||||
---
|
||||
|
||||
Create different resolver result types which provide more information.
|
||||
@@ -1,16 +1,23 @@
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { type FetchFromRegistry, type GetAuthHeader } from '@pnpm/fetching-types'
|
||||
import { createGitResolver } from '@pnpm/git-resolver'
|
||||
import { resolveFromLocal } from '@pnpm/local-resolver'
|
||||
import { type GitResolveResult, createGitResolver } from '@pnpm/git-resolver'
|
||||
import { type LocalResolveResult, resolveFromLocal } from '@pnpm/local-resolver'
|
||||
import {
|
||||
createNpmResolver,
|
||||
type JsrResolveResult,
|
||||
type NpmResolveResult,
|
||||
type WorkspaceResolveResult,
|
||||
type PackageMeta,
|
||||
type PackageMetaCache,
|
||||
type ResolveFromNpmOptions,
|
||||
type ResolverFactoryOptions,
|
||||
} from '@pnpm/npm-resolver'
|
||||
import { type ResolveFunction } from '@pnpm/resolver-base'
|
||||
import { resolveFromTarball } from '@pnpm/tarball-resolver'
|
||||
import {
|
||||
type ResolveFunction,
|
||||
type ResolveOptions,
|
||||
type WantedDependency,
|
||||
} from '@pnpm/resolver-base'
|
||||
import { type TarballResolveResult, resolveFromTarball } from '@pnpm/tarball-resolver'
|
||||
|
||||
export type {
|
||||
PackageMeta,
|
||||
@@ -19,11 +26,21 @@ export type {
|
||||
ResolverFactoryOptions,
|
||||
}
|
||||
|
||||
export type DefaultResolveResult =
|
||||
| NpmResolveResult
|
||||
| JsrResolveResult
|
||||
| GitResolveResult
|
||||
| LocalResolveResult
|
||||
| TarballResolveResult
|
||||
| WorkspaceResolveResult
|
||||
|
||||
export type DefaultResolver = (wantedDependency: WantedDependency, opts: ResolveOptions) => Promise<DefaultResolveResult>
|
||||
|
||||
export function createResolver (
|
||||
fetchFromRegistry: FetchFromRegistry,
|
||||
getAuthHeader: GetAuthHeader,
|
||||
pnpmOpts: ResolverFactoryOptions
|
||||
): { resolve: ResolveFunction, clearCache: () => void } {
|
||||
): { resolve: DefaultResolver, clearCache: () => void } {
|
||||
const { resolveFromNpm, resolveFromJsr, clearCache } = createNpmResolver(fetchFromRegistry, getAuthHeader, pnpmOpts)
|
||||
const resolveFromGit = createGitResolver(pnpmOpts)
|
||||
return {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { type TarballResolution, type GitResolution, type ResolveResult, type PkgResolutionId } from '@pnpm/resolver-base'
|
||||
import { type TarballResolution, type GitResolution, type PkgResolutionId, type ResolveResult } from '@pnpm/resolver-base'
|
||||
import git from 'graceful-git'
|
||||
import semver from 'semver'
|
||||
import { parseBareSpecifier, type HostedPackageSpec } from './parseBareSpecifier'
|
||||
@@ -9,14 +9,20 @@ export { createGitHostedPkgId }
|
||||
|
||||
export type { HostedPackageSpec }
|
||||
|
||||
export interface GitResolveResult extends ResolveResult {
|
||||
normalizedBareSpecifier: string
|
||||
resolution: GitResolution | TarballResolution
|
||||
resolvedVia: 'git-repository'
|
||||
}
|
||||
|
||||
export type GitResolver = (wantedDependency: {
|
||||
bareSpecifier: string
|
||||
}) => Promise<ResolveResult | null>
|
||||
}) => Promise<GitResolveResult | null>
|
||||
|
||||
export function createGitResolver (
|
||||
opts: AgentOptions
|
||||
): GitResolver {
|
||||
return async function resolveGit (wantedDependency): Promise<ResolveResult | null> {
|
||||
return async function resolveGit (wantedDependency): Promise<GitResolveResult | null> {
|
||||
const parsedSpec = await parseBareSpecifier(wantedDependency.bareSpecifier, opts)
|
||||
|
||||
if (parsedSpec == null) return null
|
||||
@@ -25,7 +31,7 @@ export function createGitResolver (
|
||||
? 'HEAD'
|
||||
: parsedSpec.gitCommittish
|
||||
const commit = await resolveRef(parsedSpec.fetchSpec, bareSpecifier, parsedSpec.gitRange)
|
||||
let resolution
|
||||
let resolution: GitResolution | TarballResolution | undefined
|
||||
|
||||
if ((parsedSpec.hosted != null) && !isSsh(parsedSpec.fetchSpec)) {
|
||||
// don't use tarball for ssh url, they are likely private repo
|
||||
@@ -35,7 +41,7 @@ export function createGitResolver (
|
||||
const tarball = hosted.tarball?.()
|
||||
|
||||
if (tarball) {
|
||||
resolution = { tarball } as TarballResolution
|
||||
resolution = { tarball }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +50,7 @@ export function createGitResolver (
|
||||
commit,
|
||||
repo: parsedSpec.fetchSpec,
|
||||
type: 'git',
|
||||
} as GitResolution
|
||||
}
|
||||
}
|
||||
|
||||
if (parsedSpec.path) {
|
||||
|
||||
@@ -3,21 +3,18 @@ import path from 'path'
|
||||
import { getTarballIntegrity } from '@pnpm/crypto.hash'
|
||||
import { PnpmError } from '@pnpm/error'
|
||||
import { readProjectManifestOnly } from '@pnpm/read-project-manifest'
|
||||
import {
|
||||
type DirectoryResolution,
|
||||
type ResolveResult,
|
||||
type TarballResolution,
|
||||
} from '@pnpm/resolver-base'
|
||||
import { type DirectoryResolution, type ResolveResult, type TarballResolution } from '@pnpm/resolver-base'
|
||||
import { type DependencyManifest } from '@pnpm/types'
|
||||
import { logger } from '@pnpm/logger'
|
||||
import { parseBareSpecifier, type WantedLocalDependency } from './parseBareSpecifier'
|
||||
|
||||
export type { WantedLocalDependency }
|
||||
export { type WantedLocalDependency }
|
||||
|
||||
export interface ResolveFromLocalResult extends ResolveResult {
|
||||
normalizedBareSpecifier: string
|
||||
resolution: TarballResolution | DirectoryResolution
|
||||
export interface LocalResolveResult extends ResolveResult {
|
||||
manifest?: DependencyManifest
|
||||
normalizedBareSpecifier: string
|
||||
resolution: DirectoryResolution | TarballResolution
|
||||
resolvedVia: 'local-filesystem'
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,7 +26,7 @@ export async function resolveFromLocal (
|
||||
lockfileDir?: string
|
||||
projectDir: string
|
||||
}
|
||||
): Promise<ResolveFromLocalResult | null> {
|
||||
): Promise<LocalResolveResult | null> {
|
||||
const spec = parseBareSpecifier(wantedDependency, opts.projectDir, opts.lockfileDir ?? opts.projectDir)
|
||||
if (spec == null) return null
|
||||
if (spec.type === 'file') {
|
||||
|
||||
@@ -9,16 +9,17 @@ import {
|
||||
import { pickRegistryForPackage } from '@pnpm/pick-registry-for-package'
|
||||
import { resolveWorkspaceRange } from '@pnpm/resolve-workspace-range'
|
||||
import {
|
||||
type DirectoryResolution,
|
||||
type PkgResolutionId,
|
||||
type PreferredVersions,
|
||||
type ResolveResult,
|
||||
type TarballResolution,
|
||||
type WantedDependency,
|
||||
type WorkspacePackage,
|
||||
type WorkspacePackages,
|
||||
type WorkspacePackagesByVersion,
|
||||
type WorkspaceResolveResult,
|
||||
} from '@pnpm/resolver-base'
|
||||
import { type Registries, type PinnedVersion } from '@pnpm/types'
|
||||
import { type DependencyManifest, type Registries, type PinnedVersion } from '@pnpm/types'
|
||||
import { LRUCache } from 'lru-cache'
|
||||
import normalize from 'normalize-path'
|
||||
import pMemoize from 'p-memoize'
|
||||
@@ -75,7 +76,30 @@ export interface ResolverFactoryOptions {
|
||||
saveWorkspaceProtocol?: boolean | 'rolling'
|
||||
}
|
||||
|
||||
export type NpmResolver = (wantedDependency: WantedDependency, opts: ResolveFromNpmOptions) => Promise<ResolveResult | null>
|
||||
export interface NpmResolveResult extends ResolveResult {
|
||||
latest: string
|
||||
manifest: DependencyManifest
|
||||
resolution: TarballResolution
|
||||
resolvedVia: 'npm-registry'
|
||||
}
|
||||
|
||||
export interface JsrResolveResult extends ResolveResult {
|
||||
alias: string
|
||||
manifest: DependencyManifest
|
||||
resolution: TarballResolution
|
||||
resolvedVia: 'jsr-registry'
|
||||
}
|
||||
|
||||
export interface WorkspaceResolveResult extends ResolveResult {
|
||||
manifest: DependencyManifest
|
||||
resolution: DirectoryResolution
|
||||
resolvedVia: 'workspace'
|
||||
}
|
||||
|
||||
export type NpmResolver = (
|
||||
wantedDependency: WantedDependency,
|
||||
opts: ResolveFromNpmOptions
|
||||
) => Promise<NpmResolveResult | JsrResolveResult | WorkspaceResolveResult | null>
|
||||
|
||||
export function createNpmResolver (
|
||||
fetchFromRegistry: FetchFromRegistry,
|
||||
@@ -152,7 +176,7 @@ async function resolveNpm (
|
||||
ctx: ResolveFromNpmContext,
|
||||
wantedDependency: WantedDependency,
|
||||
opts: ResolveFromNpmOptions
|
||||
): Promise<ResolveResult | null> {
|
||||
): Promise<NpmResolveResult | WorkspaceResolveResult | null> {
|
||||
const defaultTag = opts.defaultTag ?? 'latest'
|
||||
const registry = wantedDependency.alias
|
||||
? pickRegistryForPackage(ctx.registries, wantedDependency.alias, wantedDependency.bareSpecifier)
|
||||
@@ -297,7 +321,7 @@ async function resolveJsr (
|
||||
ctx: ResolveFromNpmContext,
|
||||
wantedDependency: WantedDependency,
|
||||
opts: Omit<ResolveFromNpmOptions, 'registry'>
|
||||
): Promise<ResolveResult | null> {
|
||||
): Promise<JsrResolveResult | null> {
|
||||
if (!wantedDependency.bareSpecifier) return null
|
||||
const defaultTag = opts.defaultTag ?? 'latest'
|
||||
|
||||
|
||||
@@ -44,23 +44,11 @@ export interface ResolveResult {
|
||||
publishedAt?: string
|
||||
manifest?: DependencyManifest
|
||||
resolution: Resolution
|
||||
resolvedVia: 'npm-registry' | 'git-repository' | 'local-filesystem' | 'workspace' | 'url' | string
|
||||
resolvedVia: string
|
||||
normalizedBareSpecifier?: string
|
||||
alias?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* A dependency on a workspace package.
|
||||
*/
|
||||
export interface WorkspaceResolveResult extends ResolveResult {
|
||||
/**
|
||||
* 'workspace' will be returned for workspace: protocol dependencies or a
|
||||
* package in the workspace that matches the wanted dependency's name and
|
||||
* version range.
|
||||
*/
|
||||
resolvedVia: 'workspace'
|
||||
}
|
||||
|
||||
export interface WorkspacePackage {
|
||||
rootDir: ProjectRootDir
|
||||
manifest: DependencyManifest
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
import { type PkgResolutionId, type ResolveResult } from '@pnpm/resolver-base'
|
||||
import { type PkgResolutionId, type ResolveResult, type TarballResolution } from '@pnpm/resolver-base'
|
||||
import { type FetchFromRegistry } from '@pnpm/fetching-types'
|
||||
|
||||
export interface TarballResolveResult extends ResolveResult {
|
||||
normalizedBareSpecifier: string
|
||||
resolution: TarballResolution
|
||||
resolvedVia: 'url'
|
||||
}
|
||||
|
||||
export async function resolveFromTarball (
|
||||
fetchFromRegistry: FetchFromRegistry,
|
||||
wantedDependency: { bareSpecifier: string }
|
||||
): Promise<ResolveResult | null> {
|
||||
): Promise<TarballResolveResult | null> {
|
||||
if (!wantedDependency.bareSpecifier.startsWith('http:') && !wantedDependency.bareSpecifier.startsWith('https:')) {
|
||||
return null
|
||||
}
|
||||
|
||||
if (isRepository(wantedDependency.bareSpecifier)) return null
|
||||
|
||||
let resolvedUrl
|
||||
let resolvedUrl: string
|
||||
|
||||
// If there are redirects and the response is immutable, we want to get the final URL address
|
||||
const response = await fetchFromRegistry(wantedDependency.bareSpecifier, { method: 'HEAD' })
|
||||
|
||||
Reference in New Issue
Block a user