refactor: create a separate type for NodeId (#8092)

This commit is contained in:
Zoltan Kochan
2024-05-17 11:23:52 +02:00
committed by GitHub
parent ef73c19f15
commit 45f4262f03
25 changed files with 210 additions and 185 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/types": minor
---
Add PkgResolutionId.

View File

@@ -1,11 +1,12 @@
import { type PackageSnapshot } from '@pnpm/lockfile-types'
import * as dp from '@pnpm/dependency-path'
import { type PkgResolutionId } from '@pnpm/types'
export interface NameVer {
name: string
peersSuffix: string | undefined
version: string
nonSemverVersion?: string
nonSemverVersion?: PkgResolutionId
}
export function nameVerFromPkgSnapshot (

View File

@@ -1,5 +1,5 @@
import { createBase32Hash } from '@pnpm/crypto.base32-hash'
import { type Registries } from '@pnpm/types'
import { type PkgResolutionId, type Registries } from '@pnpm/types'
import semver from 'semver'
export function isAbsolute (dependencyPath: string): boolean {
@@ -85,7 +85,7 @@ export interface DependencyPath {
name?: string
peersSuffix?: string
version?: string
nonSemverVersion?: string
nonSemverVersion?: PkgResolutionId
}
export function parse (dependencyPath: string): DependencyPath {
@@ -121,7 +121,7 @@ export function parse (dependencyPath: string): DependencyPath {
}
return {
name,
nonSemverVersion: version,
nonSemverVersion: version as PkgResolutionId,
peersSuffix,
}
}

View File

@@ -31,3 +31,5 @@ export interface PatchFile {
path: string
hash: string
}
export type PkgResolutionId = string & { __brand: 'PkgResolutionId' }

View File

@@ -209,7 +209,7 @@ async function resolveAndFetch (
normalizedPref = resolveResult.normalizedPref
}
const id = pkgId as string
const id = pkgId!
if (resolution.type === 'directory' && !id.startsWith('file:')) {
if (manifest == null) {

View File

@@ -15,7 +15,7 @@ import loadJsonFile from 'load-json-file'
import nock from 'nock'
import normalize from 'normalize-path'
import tempy from 'tempy'
import { type PkgRequestFetchResult } from '@pnpm/store-controller-types'
import { type PkgResolutionId, type PkgRequestFetchResult } from '@pnpm/store-controller-types'
const registry = `http://localhost:${REGISTRY_MOCK_PORT}`
const f = fixtures(__dirname)
@@ -128,7 +128,7 @@ test('request package but skip fetching, when resolution is already available',
const projectDir = tempy.directory()
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
currentPkg: {
id: 'is-positive@1.0.0',
id: 'is-positive@1.0.0' as PkgResolutionId,
resolution: {
integrity: 'sha512-xxzPGZ4P2uN6rROUa5N9Z7zTX6ERuE0hs6GUOc/cKBLF2NqKc16UwqHMt3tFg4CO6EBTE5UecUasg+3jZx3Ckg==',
tarball: `http://localhost:${REGISTRY_MOCK_PORT}/is-positive/-/is-positive-1.0.0.tgz`,
@@ -197,7 +197,7 @@ test('refetch local tarball if its integrity has changed', async () => {
const response = await requestPackage(wantedPackage, {
...requestPackageOpts,
currentPkg: {
id: pkgId,
id: pkgId as PkgResolutionId,
resolution: {
integrity: 'sha512-lqODmYcc/FKOGROEUByd5Sbugqhzgkv+Hij9PXH0sZVQsU2npTQ0x3L81GCtHilFKme8lhBtD31Vxg/AKYrAvg==',
tarball,
@@ -229,7 +229,7 @@ test('refetch local tarball if its integrity has changed', async () => {
const response = await requestPackage(wantedPackage, {
...requestPackageOpts,
currentPkg: {
id: pkgId,
id: pkgId as PkgResolutionId,
resolution: {
integrity: 'sha512-lqODmYcc/FKOGROEUByd5Sbugqhzgkv+Hij9PXH0sZVQsU2npTQ0x3L81GCtHilFKme8lhBtD31Vxg/AKYrAvg==',
tarball,
@@ -256,7 +256,7 @@ test('refetch local tarball if its integrity has changed', async () => {
const response = await requestPackage(wantedPackage, {
...requestPackageOpts,
currentPkg: {
id: pkgId,
id: pkgId as PkgResolutionId,
resolution: {
integrity: 'sha512-v3uhYkN+Eh3Nus4EZmegjQhrfpdPIH+2FjrkeBc6ueqZJWWRaLnSYIkD0An6m16D3v+6HCE18ox6t95eGxj5Pw==',
tarball,
@@ -588,7 +588,7 @@ test('always return a package manifest in the response', async () => {
{
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
currentPkg: {
id: 'is-positive@1.0.0',
id: 'is-positive@1.0.0' as PkgResolutionId,
resolution: {
integrity: 'sha512-xxzPGZ4P2uN6rROUa5N9Z7zTX6ERuE0hs6GUOc/cKBLF2NqKc16UwqHMt3tFg4CO6EBTE5UecUasg+3jZx3Ckg==',
tarball: `http://localhost:${REGISTRY_MOCK_PORT}/is-positive/-/is-positive-1.0.0.tgz`,

View File

@@ -1,6 +0,0 @@
// The only reason package IDs are encoded is to avoid '>' signs.
// Otherwise, it would be impossible to split the node ID back to package IDs reliably.
// See issue https://github.com/pnpm/pnpm/issues/986
export function encodePkgId (pkgId: string): string {
return pkgId.replaceAll('%', '%25').replaceAll('>', '%3E')
}

View File

@@ -26,6 +26,7 @@ import zipWith from 'ramda/src/zipWith'
import isSubdir from 'is-subdir'
import { getWantedDependencies, type WantedDependency } from './getWantedDependencies'
import { depPathToRef } from './depPathToRef'
import { type NodeId } from './nextNodeId'
import { createNodeIdForLinkedLocalPkg, type UpdateMatchingFunction } from './resolveDependencies'
import {
type Importer,
@@ -60,7 +61,7 @@ export {
interface ProjectToLink {
binsDir: string
directNodeIdsByAlias: { [alias: string]: string }
directNodeIdsByAlias: { [alias: string]: NodeId }
id: string
linkedDependencies: LinkedDependency[]
manifest: ProjectManifest

View File

@@ -1,5 +1,9 @@
let nodeIdCounter = 0
export function nextNodeId (): string {
return (++nodeIdCounter).toString()
type Brand<K, T> = K & { __brand: T }
export type NodeId = Brand<string, 'nodeId'>
export function nextNodeId (): NodeId {
return (++nodeIdCounter).toString() as NodeId
}

View File

@@ -22,6 +22,7 @@ import {
type PreferredVersions,
type Resolution,
type WorkspacePackages,
type PkgResolutionId,
} from '@pnpm/resolver-base'
import {
type PkgRequestFetchResult,
@@ -47,10 +48,9 @@ import pickBy from 'ramda/src/pickBy'
import omit from 'ramda/src/omit'
import zipWith from 'ramda/src/zipWith'
import semver from 'semver'
import { encodePkgId } from './encodePkgId'
import { getNonDevWantedDependencies, type WantedDependency } from './getNonDevWantedDependencies'
import { safeIntersect } from './mergePeers'
import { nextNodeId } from './nextNodeId'
import { type NodeId, nextNodeId } from './nextNodeId'
import { parentIdsContainSequence } from './parentIdsContainSequence'
import { hoistPeers, getHoistableOptionalPeers } from './hoistPeers'
import { wantedDepIsLocallyAvailable } from './wantedDepIsLocallyAvailable'
@@ -74,7 +74,7 @@ export function getPkgsInfoFromIds (
// child nodeId by child alias name in case of non-linked deps
export interface ChildrenMap {
[alias: string]: string
[alias: string]: NodeId
}
export type DependenciesTreeNode<T> = {
@@ -92,7 +92,7 @@ export type DependenciesTree<T> = Map<
// a node ID is the join of the package's keypath with a colon
// E.g., a subdeps node ID which parent is `foo` will be
// registry.npmjs.org/foo/1.0.0:registry.npmjs.org/bar/1.0.0
string,
NodeId,
DependenciesTreeNode<T>
>
@@ -113,7 +113,7 @@ export interface LinkedDependency {
export interface PendingNode {
alias: string
nodeId: string
nodeId: NodeId
resolvedPackage: ResolvedPackage
depth: number
installable: boolean
@@ -185,7 +185,7 @@ export type PkgAddress = {
depPath: string
isNew: boolean
isLinkedDependency?: false
nodeId: string
nodeId: NodeId
pkgId: string
normalizedPref?: string // is returned only for root dependencies
installable: boolean
@@ -795,8 +795,8 @@ async function resolveDependenciesOfDependency (
}
}
export function createNodeIdForLinkedLocalPkg (lockfileDir: string, pkgDir: string): string {
return `link:${normalizePath(path.relative(lockfileDir, pkgDir))}`
export function createNodeIdForLinkedLocalPkg (lockfileDir: string, pkgDir: string): NodeId {
return `link:${normalizePath(path.relative(lockfileDir, pkgDir))}` as NodeId
}
function filterMissingPeers (
@@ -895,9 +895,9 @@ async function resolveChildren (
}))
ctx.dependenciesTree.set(parentPkg.nodeId, {
children: pkgAddresses.reduce((chn, child) => {
chn[child.alias] = (child as PkgAddress).nodeId ?? child.pkgId
chn[child.alias] = (child as PkgAddress).nodeId ?? (child.pkgId as NodeId)
return chn
}, {} as Record<string, string>),
}, {} as Record<string, NodeId>),
depth: parentDepth,
installable: parentPkg.installable,
resolvedPackage: ctx.resolvedPkgsById[parentPkg.pkgId],
@@ -1007,7 +1007,7 @@ function referenceSatisfiesWantedSpec (
type InfoFromLockfile = {
depPath: string
pkgId: string
pkgId: PkgResolutionId
dependencyLockfile?: PackageSnapshot
name?: string
version?: string
@@ -1059,7 +1059,7 @@ function getInfoFromLockfile (
version,
dependencyLockfile,
depPath,
pkgId: nonSemverVersion ?? `${name}@${version}`,
pkgId: nonSemverVersion ?? (`${name}@${version}` as PkgResolutionId),
// resolution may not exist if lockfile is broken, and an unexpected error will be thrown
// if resolution does not exist, return undefined so it can be autofixed later
resolution: dependencyLockfile.resolution && pkgSnapshotToResolution(depPath, dependencyLockfile, registries),
@@ -1068,7 +1068,7 @@ function getInfoFromLockfile (
const parsed = dp.parse(depPath)
return {
depPath,
pkgId: parsed.nonSemverVersion ?? (parsed.name && parsed.version ? `${parsed.name}@${parsed.version}` : depPath), // Does it make sense to set pkgId when we're not sure?
pkgId: parsed.nonSemverVersion ?? (parsed.name && parsed.version ? `${parsed.name}@${parsed.version}` : depPath) as PkgResolutionId, // Does it make sense to set pkgId when we're not sure?
}
}
}
@@ -1079,7 +1079,7 @@ interface ResolveDependencyOptions {
depPath?: string
name?: string
version?: string
pkgId?: string
pkgId?: PkgResolutionId
resolution?: Resolution
dependencyLockfile?: PackageSnapshot
}
@@ -1207,8 +1207,6 @@ async function resolveDependency (
},
})
pkgResponse.body.id = encodePkgId(pkgResponse.body.id)
if (ctx.allPreferredVersions && pkgResponse.body.manifest?.version) {
if (!ctx.allPreferredVersions[pkgResponse.body.manifest.name]) {
ctx.allPreferredVersions[pkgResponse.body.manifest.name] = {}
@@ -1349,7 +1347,7 @@ async function resolveDependency (
}
// In case of leaf dependencies (dependencies that have no prod deps or peer deps),
// we only ever need to analyze one leaf dep in a graph, so the nodeId can be short and stateless.
const nodeId = pkgIsLeaf(pkg) ? pkgResponse.body.id : nextNodeId()
const nodeId = pkgIsLeaf(pkg) ? pkgResponse.body.id as unknown as NodeId : nextNodeId()
const parentIsInstallable = options.parentPkg.installable === undefined || options.parentPkg.installable
const installable = parentIsInstallable && pkgResponse.body.isInstallable !== false

View File

@@ -11,7 +11,7 @@ import {
import partition from 'ramda/src/partition'
import zipObj from 'ramda/src/zipObj'
import { type WantedDependency } from './getNonDevWantedDependencies'
import { nextNodeId } from './nextNodeId'
import { type NodeId, nextNodeId } from './nextNodeId'
import { parentIdsContainSequence } from './parentIdsContainSequence'
import {
type ChildrenByParentId,
@@ -34,7 +34,7 @@ export interface ResolvedImporters {
[id: string]: {
directDependencies: ResolvedDirectDependency[]
directNodeIdsByAlias: {
[alias: string]: string
[alias: string]: NodeId
}
linkedDependencies: LinkedDependency[]
}
@@ -172,7 +172,7 @@ export async function resolveDependencyTree<T> (
currentDepth: 0,
parentPkg: {
installable: true,
nodeId: `>${importer.id}>`,
nodeId: `>${importer.id}>` as NodeId,
optional: false,
pkgId: importer.id,
rootDir: importer.rootDir,
@@ -241,7 +241,7 @@ export async function resolveDependencyTree<T> (
.reduce((acc, { alias, nodeId }) => {
acc[alias] = nodeId
return acc
}, {} as Record<string, string>),
}, {} as Record<string, NodeId>),
linkedDependencies,
}
}
@@ -270,11 +270,11 @@ function buildTree (
children: Array<{ alias: string, id: string }>,
depth: number,
installable: boolean
): Record<string, string> {
const childrenNodeIds: Record<string, string> = {}
): Record<string, NodeId> {
const childrenNodeIds: Record<string, NodeId> = {}
for (const child of children) {
if (child.id.startsWith('link:')) {
childrenNodeIds[child.alias] = child.id
childrenNodeIds[child.alias] = child.id as NodeId
continue
}
if (parentIdsContainSequence(parentIds, parentId, child.id) || parentId === child.id) {

View File

@@ -13,6 +13,7 @@ import { depPathToFilename, createPeersDirSuffix, type PeerId } from '@pnpm/depe
import mapValues from 'ramda/src/map'
import partition from 'ramda/src/partition'
import pick from 'ramda/src/pick'
import { type NodeId } from './nextNodeId'
import {
type ChildrenMap,
type PeerDependencies,
@@ -52,7 +53,7 @@ export interface GenericDependenciesGraph<T extends PartialResolvedPackage> {
}
export interface ProjectToResolve {
directNodeIdsByAlias: { [alias: string]: string }
directNodeIdsByAlias: { [alias: string]: NodeId }
// only the top dependencies that were already installed
// to avoid warnings about unresolved peer dependencies
topParents: Array<{ name: string, version: string, alias?: string }>
@@ -259,7 +260,7 @@ function getRootPkgsByName<T extends PartialResolvedPackage> (dependenciesTree:
function createPkgsByName<T extends PartialResolvedPackage> (
dependenciesTree: DependenciesTree<T>,
{ directNodeIdsByAlias, topParents }: {
directNodeIdsByAlias: { [alias: string]: string }
directNodeIdsByAlias: { [alias: string]: NodeId }
topParents: Array<{ name: string, version: string, alias?: string, linkedDir?: string }>
}
): ParentRefs {
@@ -280,7 +281,7 @@ function createPkgsByName<T extends PartialResolvedPackage> (
alias,
depth: 0,
version,
nodeId: linkedDir,
nodeId: linkedDir as NodeId,
parentNodeIds: [],
}
_updateParentRefs(name, pkg)
@@ -293,7 +294,7 @@ function createPkgsByName<T extends PartialResolvedPackage> (
interface PeersCacheItem {
depPath: pDefer.DeferredPromise<string>
resolvedPeers: Map<string, string>
resolvedPeers: Map<string, NodeId>
missingPeers: Set<string>
}
@@ -301,7 +302,7 @@ type PeersCache = Map<string, PeersCacheItem[]>
interface PeersResolution {
missingPeers: Set<string>
resolvedPeers: Map<string, string>
resolvedPeers: Map<string, NodeId>
}
interface ResolvePeersContext {
@@ -323,12 +324,12 @@ interface ParentPkgInfo {
type ParentPkgsOfNode = Map<string, Record<string, ParentPkgInfo>>
async function resolvePeersOfNode<T extends PartialResolvedPackage> (
nodeId: string,
nodeId: NodeId,
parentParentPkgs: ParentRefs,
ctx: ResolvePeersContext & {
allPeerDepNames: Set<string>
parentPkgsOfNode: ParentPkgsOfNode
parentNodeIds: string[]
parentNodeIds: NodeId[]
parentDepPathsChain: string[]
dependenciesTree: DependenciesTree<T>
depGraph: GenericDependenciesGraph<T>
@@ -342,7 +343,7 @@ async function resolvePeersOfNode<T extends PartialResolvedPackage> (
}
): Promise<PeersResolution & { finishing?: FinishingResolutionPromise, calculateDepPath?: CalculateDepPath }> {
const node = ctx.dependenciesTree.get(nodeId)!
if (node.depth === -1) return { resolvedPeers: new Map<string, string>(), missingPeers: new Set<string>() }
if (node.depth === -1) return { resolvedPeers: new Map<string, NodeId>(), missingPeers: new Set<string>() }
const resolvedPackage = node.resolvedPackage as T
if (
ctx.purePkgs.has(resolvedPackage.depPath) &&
@@ -351,7 +352,7 @@ async function resolvePeersOfNode<T extends PartialResolvedPackage> (
) {
ctx.pathsByNodeId.set(nodeId, resolvedPackage.depPath)
ctx.pathsByNodeIdPromises.get(nodeId)!.resolve(resolvedPackage.depPath)
return { resolvedPeers: new Map<string, string>(), missingPeers: new Set<string>() }
return { resolvedPeers: new Map<string, NodeId>(), missingPeers: new Set<string>() }
}
if (typeof node.children === 'function') {
node.children = node.children()
@@ -411,7 +412,7 @@ async function resolvePeersOfNode<T extends PartialResolvedPackage> (
})
const { resolvedPeers, missingPeers } = Object.keys(resolvedPackage.peerDependencies).length === 0
? { resolvedPeers: new Map<string, string>(), missingPeers: new Set<string>() }
? { resolvedPeers: new Map<string, NodeId>(), missingPeers: new Set<string>() }
: _resolvePeers({
currentDepth: node.depth,
dependenciesTree: ctx.dependenciesTree,
@@ -460,7 +461,7 @@ async function resolvePeersOfNode<T extends PartialResolvedPackage> (
addDepPathToGraph(resolvedPackage.depPath)
} else {
const peerIds: PeerId[] = []
const pendingPeerNodeIds: string[] = []
const pendingPeerNodeIds: NodeId[] = []
for (const [alias, peerNodeId] of allResolvedPeers.entries()) {
if (peerNodeId.startsWith('link:')) {
const linkedDir = peerNodeId.slice(5)
@@ -494,7 +495,7 @@ async function resolvePeersOfNode<T extends PartialResolvedPackage> (
async function calculateDepPath (
peerIds: PeerId[],
pendingPeerNodeIds: string[],
pendingPeerNodeIds: NodeId[],
cycles: string[][]
): Promise<void> {
const cyclicPeerNodeIds = new Set()
@@ -657,7 +658,7 @@ function getPreviouslyResolvedChildren<T extends PartialResolvedPackage> (
parentDepPathsChain,
dependenciesTree,
}: {
parentNodeIds: string[]
parentNodeIds: NodeId[]
parentDepPathsChain: string[]
dependenciesTree: DependenciesTree<T>
},
@@ -684,13 +685,13 @@ function getPreviouslyResolvedChildren<T extends PartialResolvedPackage> (
async function resolvePeersOfChildren<T extends PartialResolvedPackage> (
children: {
[alias: string]: string
[alias: string]: NodeId
},
parentPkgs: ParentRefs,
ctx: ResolvePeersContext & {
allPeerDepNames: Set<string>
parentPkgsOfNode: ParentPkgsOfNode
parentNodeIds: string[]
parentNodeIds: NodeId[]
parentDepPathsChain: string[]
peerDependencyIssues: Pick<PeerDependencyIssues, 'bad' | 'missing'>
peersCache: PeersCache
@@ -703,7 +704,7 @@ async function resolvePeersOfChildren<T extends PartialResolvedPackage> (
lockfileDir: string
}
): Promise<PeersResolution & { finishing: Promise<void> }> {
const allResolvedPeers = new Map<string, string>()
const allResolvedPeers = new Map<string, NodeId>()
const allMissingPeers = new Set<string>()
// Partition children based on whether they're repeated in parentPkgs.
@@ -766,7 +767,7 @@ async function resolvePeersOfChildren<T extends PartialResolvedPackage> (
}
const finishing = Promise.all(finishingList).then(() => {})
const unknownResolvedPeersOfChildren = new Map<string, string>()
const unknownResolvedPeersOfChildren = new Map<string, NodeId>()
for (const [alias, v] of allResolvedPeers) {
if (!children[alias]) {
unknownResolvedPeersOfChildren.set(alias, v)
@@ -782,14 +783,14 @@ function _resolvePeers<T extends PartialResolvedPackage> (
lockfileDir: string
nodeId: string
parentPkgs: ParentRefs
parentNodeIds: string[]
parentNodeIds: NodeId[]
resolvedPackage: T
dependenciesTree: DependenciesTree<T>
rootDir: string
peerDependencyIssues: Pick<PeerDependencyIssues, 'bad' | 'missing'>
}
): PeersResolution {
const resolvedPeers = new Map<string, string>()
const resolvedPeers = new Map<string, NodeId>()
const missingPeers = new Set<string>()
for (const [peerName, { version, optional }] of Object.entries(ctx.resolvedPackage.peerDependencies)) {
const peerVersionRange = version.replace(/^workspace:/, '')
@@ -847,7 +848,7 @@ function getLocationFromParentNodeIds<T> (
parentNodeIds,
}: {
dependenciesTree: DependenciesTree<T>
parentNodeIds: string[]
parentNodeIds: NodeId[]
}
): Location {
const parents = parentNodeIds
@@ -866,17 +867,17 @@ interface ParentRef {
version: string
depth: number
// this is null only for already installed top dependencies
nodeId?: string
nodeId?: NodeId
alias?: string
occurrence: number
parentNodeIds: string[]
parentNodeIds: NodeId[]
}
interface ParentPkgNode<T> {
alias: string
nodeId: string
nodeId: NodeId
node: DependenciesTreeNode<T>
parentNodeIds: string[]
parentNodeIds: NodeId[]
}
function toPkgByName<T extends PartialResolvedPackage> (nodes: Array<ParentPkgNode<T>>): ParentRefs {

View File

@@ -1,5 +1,6 @@
import { type PartialResolvedPackage, resolvePeers } from '../lib/resolvePeers'
import { type DependenciesTreeNode } from '../lib/resolveDependencies'
import { type NodeId } from '../lib/nextNodeId'
test('packages are not deduplicated when versions do not match', async () => {
const fooPkg: PartialResolvedPackage = {
@@ -36,8 +37,8 @@ test('packages are not deduplicated when versions do not match', async () => {
projects: [
{
directNodeIdsByAlias: {
foo: '>project1>foo/1.0.0>',
bar: '>project1>bar/1.0.0>',
foo: '>project1>foo/1.0.0>' as NodeId,
bar: '>project1>bar/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -45,9 +46,9 @@ test('packages are not deduplicated when versions do not match', async () => {
},
{
directNodeIdsByAlias: {
foo: '>project2>foo/1.0.0>',
bar: '>project2>bar/1.0.0>',
baz: '>project2>baz/1.0.0>',
foo: '>project2>foo/1.0.0>' as NodeId,
bar: '>project2>bar/1.0.0>' as NodeId,
baz: '>project2>baz/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -55,8 +56,8 @@ test('packages are not deduplicated when versions do not match', async () => {
},
{
directNodeIdsByAlias: {
foo: '>project3>foo/1.0.0>',
bar: '>project3>bar/2.0.0>',
foo: '>project3>foo/1.0.0>' as NodeId,
bar: '>project3>bar/2.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -64,9 +65,9 @@ test('packages are not deduplicated when versions do not match', async () => {
},
{
directNodeIdsByAlias: {
foo: '>project4>foo/1.0.0>',
bar: '>project4>bar/2.0.0>',
baz: '>project4>baz/2.0.0>',
foo: '>project4>foo/1.0.0>' as NodeId,
bar: '>project4>bar/2.0.0>' as NodeId,
baz: '>project4>baz/2.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -74,20 +75,20 @@ test('packages are not deduplicated when versions do not match', async () => {
},
],
resolvedImporters: {},
dependenciesTree: new Map<string, DependenciesTreeNode<PartialResolvedPackage>>(([
['>project1>foo/1.0.0>', fooPkg],
['>project1>bar/1.0.0>', peers.bar_1_0_0],
dependenciesTree: new Map<NodeId, DependenciesTreeNode<PartialResolvedPackage>>(([
['>project1>foo/1.0.0>' as NodeId, fooPkg],
['>project1>bar/1.0.0>' as NodeId, peers.bar_1_0_0],
['>project2>foo/1.0.0>', fooPkg],
['>project2>bar/1.0.0>', peers.bar_1_0_0],
['>project2>baz/1.0.0>', peers.baz_1_0_0],
['>project2>foo/1.0.0>' as NodeId, fooPkg],
['>project2>bar/1.0.0>' as NodeId, peers.bar_1_0_0],
['>project2>baz/1.0.0>' as NodeId, peers.baz_1_0_0],
['>project3>foo/1.0.0>', fooPkg],
['>project3>bar/2.0.0>', peers.bar_2_0_0],
['>project3>foo/1.0.0>' as NodeId, fooPkg],
['>project3>bar/2.0.0>' as NodeId, peers.bar_2_0_0],
['>project4>foo/1.0.0>', fooPkg],
['>project4>bar/2.0.0>', peers.bar_2_0_0],
['>project4>baz/2.0.0>', peers.baz_2_0_0],
['>project4>foo/1.0.0>' as NodeId, fooPkg],
['>project4>bar/2.0.0>' as NodeId, peers.bar_2_0_0],
['>project4>baz/2.0.0>' as NodeId, peers.baz_2_0_0],
] satisfies Array<[string, PartialResolvedPackage]>).map(([path, resolvedPackage]) => [path, {
children: {},

View File

@@ -2,6 +2,7 @@
import { type PeerDependencyIssuesByProjects } from '@pnpm/types'
import { type PartialResolvedPackage, resolvePeers } from '../lib/resolvePeers'
import { type DependenciesTreeNode, type PeerDependencies } from '../lib/resolveDependencies'
import { type NodeId } from '../lib/nextNodeId'
test('resolve peer dependencies of cyclic dependencies', async () => {
const fooPkg = {
@@ -29,7 +30,7 @@ test('resolve peer dependencies of cyclic dependencies', async () => {
projects: [
{
directNodeIdsByAlias: {
foo: '>foo/1.0.0>',
foo: '>foo/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -37,26 +38,26 @@ test('resolve peer dependencies of cyclic dependencies', async () => {
},
],
resolvedImporters: {},
dependenciesTree: new Map<string, DependenciesTreeNode<PartialResolvedPackage>>([
['>foo/1.0.0>', {
dependenciesTree: new Map<NodeId, DependenciesTreeNode<PartialResolvedPackage>>([
['>foo/1.0.0>' as NodeId, {
children: {
bar: '>foo/1.0.0>bar/1.0.0>',
bar: '>foo/1.0.0>bar/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: fooPkg,
depth: 0,
}],
['>foo/1.0.0>bar/1.0.0>', {
['>foo/1.0.0>bar/1.0.0>' as NodeId, {
children: {
qar: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>',
qar: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: barPkg,
depth: 1,
}],
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>', {
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>' as NodeId, {
children: {
zoo: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>',
zoo: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: {
@@ -71,10 +72,10 @@ test('resolve peer dependencies of cyclic dependencies', async () => {
},
depth: 2,
}],
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>', {
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>' as NodeId, {
children: {
foo: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>foo/1.0.0>',
bar: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>bar/1.0.0>',
foo: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>foo/1.0.0>' as NodeId,
bar: '>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>bar/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: {
@@ -88,13 +89,13 @@ test('resolve peer dependencies of cyclic dependencies', async () => {
},
depth: 3,
}],
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>foo/1.0.0>', {
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>foo/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: fooPkg,
depth: 4,
}],
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>bar/1.0.0>', {
['>foo/1.0.0>bar/1.0.0>qar/1.0.0>zoo/1.0.0>bar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barPkg,
@@ -144,8 +145,8 @@ test('when a package is referenced twice in the dependencies graph and one of th
projects: [
{
directNodeIdsByAlias: {
zoo: '>zoo/1.0.0>',
bar: '>bar/1.0.0>',
zoo: '>zoo/1.0.0>' as NodeId,
bar: '>bar/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -153,45 +154,45 @@ test('when a package is referenced twice in the dependencies graph and one of th
},
],
resolvedImporters: {},
dependenciesTree: new Map<string, DependenciesTreeNode<PartialResolvedPackage>>([
['>zoo/1.0.0>', {
dependenciesTree: new Map<NodeId, DependenciesTreeNode<PartialResolvedPackage>>([
['>zoo/1.0.0>' as NodeId, {
children: {
foo: '>zoo/1.0.0>foo/1.0.0>',
foo: '>zoo/1.0.0>foo/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: zooPkg,
depth: 0,
}],
['>zoo/1.0.0>foo/1.0.0>', {
['>zoo/1.0.0>foo/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: fooPkg,
depth: 1,
}],
['>bar/1.0.0>', {
['>bar/1.0.0>' as NodeId, {
children: {
zoo: '>bar/1.0.0>zoo/1.0.0>',
qar: '>bar/1.0.0>qar/1.0.0>',
zoo: '>bar/1.0.0>zoo/1.0.0>' as NodeId,
qar: '>bar/1.0.0>qar/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: barPkg,
depth: 0,
}],
['>bar/1.0.0>zoo/1.0.0>', {
['>bar/1.0.0>zoo/1.0.0>' as NodeId, {
children: {
foo: '>bar/1.0.0>zoo/1.0.0>foo/1.0.0>',
foo: '>bar/1.0.0>zoo/1.0.0>foo/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: zooPkg,
depth: 1,
}],
['>bar/1.0.0>zoo/1.0.0>foo/1.0.0>', {
['>bar/1.0.0>zoo/1.0.0>foo/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: fooPkg,
depth: 2,
}],
['>bar/1.0.0>qar/1.0.0>', {
['>bar/1.0.0>qar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: {
@@ -271,7 +272,7 @@ describe('peer dependency issues', () => {
projects: [
{
directNodeIdsByAlias: {
foo: '>project1>foo/1.0.0>',
foo: '>project1>foo/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -279,7 +280,7 @@ describe('peer dependency issues', () => {
},
{
directNodeIdsByAlias: {
bar: '>project2>bar/1.0.0>',
bar: '>project2>bar/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -287,8 +288,8 @@ describe('peer dependency issues', () => {
},
{
directNodeIdsByAlias: {
foo: '>project3>foo/1.0.0>',
bar: '>project3>bar/1.0.0>',
foo: '>project3>foo/1.0.0>' as NodeId,
bar: '>project3>bar/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -296,8 +297,8 @@ describe('peer dependency issues', () => {
},
{
directNodeIdsByAlias: {
bar: '>project4>bar/1.0.0>',
qar: '>project4>qar/1.0.0>',
bar: '>project4>bar/1.0.0>' as NodeId,
qar: '>project4>qar/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -305,8 +306,8 @@ describe('peer dependency issues', () => {
},
{
directNodeIdsByAlias: {
foo: '>project5>foo/1.0.0>',
bar: '>project5>bar/2.0.0>',
foo: '>project5>foo/1.0.0>' as NodeId,
bar: '>project5>bar/2.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -314,8 +315,8 @@ describe('peer dependency issues', () => {
},
{
directNodeIdsByAlias: {
foo: '>project6>foo/2.0.0>',
bar: '>project6>bar/2.0.0>',
foo: '>project6>foo/2.0.0>' as NodeId,
bar: '>project6>bar/2.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -323,62 +324,62 @@ describe('peer dependency issues', () => {
},
],
resolvedImporters: {},
dependenciesTree: new Map<string, DependenciesTreeNode<PartialResolvedPackage>>([
['>project1>foo/1.0.0>', {
dependenciesTree: new Map<NodeId, DependenciesTreeNode<PartialResolvedPackage>>([
['>project1>foo/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: fooPkg,
depth: 0,
}],
['>project2>bar/1.0.0>', {
['>project2>bar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barPkg,
depth: 0,
}],
['>project3>foo/1.0.0>', {
['>project3>foo/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: fooPkg,
depth: 0,
}],
['>project3>bar/1.0.0>', {
['>project3>bar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barPkg,
depth: 0,
}],
['>project4>bar/1.0.0>', {
['>project4>bar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barPkg,
depth: 0,
}],
['>project4>qar/1.0.0>', {
['>project4>qar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: qarPkg,
depth: 0,
}],
['>project5>foo/1.0.0>', {
['>project5>foo/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: fooPkg,
depth: 0,
}],
['>project5>bar/2.0.0>', {
['>project5>bar/2.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barWithOptionalPeer,
depth: 0,
}],
['>project6>foo/2.0.0>', {
['>project6>foo/2.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: fooWithOptionalPeer,
depth: 0,
}],
['>project6>bar/2.0.0>', {
['>project6>bar/2.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barWithOptionalPeer,
@@ -419,9 +420,9 @@ describe('unmet peer dependency issues', () => {
projects: [
{
directNodeIdsByAlias: {
foo: '>project1>foo/1.0.0>',
peer1: '>project1>peer1/1.0.0-rc.0>',
peer2: '>project1>peer2/1.1.0-rc.0>',
foo: '>project1>foo/1.0.0>' as NodeId,
peer1: '>project1>peer1/1.0.0-rc.0>' as NodeId,
peer2: '>project1>peer2/1.1.0-rc.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -429,8 +430,8 @@ describe('unmet peer dependency issues', () => {
},
],
resolvedImporters: {},
dependenciesTree: new Map<string, DependenciesTreeNode<PartialResolvedPackage>>([
['>project1>foo/1.0.0>', {
dependenciesTree: new Map<NodeId, DependenciesTreeNode<PartialResolvedPackage>>([
['>project1>foo/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: {
@@ -445,7 +446,7 @@ describe('unmet peer dependency issues', () => {
},
depth: 0,
}],
['>project1>peer1/1.0.0-rc.0>', {
['>project1>peer1/1.0.0-rc.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: {
@@ -457,7 +458,7 @@ describe('unmet peer dependency issues', () => {
},
depth: 0,
}],
['>project1>peer2/1.1.0-rc.0>', {
['>project1>peer2/1.1.0-rc.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: {
@@ -491,7 +492,7 @@ describe('unmet peer dependency issue resolved from subdependency', () => {
projects: [
{
directNodeIdsByAlias: {
foo: '>project>foo/1.0.0>',
foo: '>project>foo/1.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -499,11 +500,11 @@ describe('unmet peer dependency issue resolved from subdependency', () => {
},
],
resolvedImporters: {},
dependenciesTree: new Map<string, DependenciesTreeNode<PartialResolvedPackage>>([
['>project>foo/1.0.0>', {
dependenciesTree: new Map<NodeId, DependenciesTreeNode<PartialResolvedPackage>>([
['>project>foo/1.0.0>' as NodeId, {
children: {
dep: '>project>foo/1.0.0>dep/1.0.0>',
bar: '>project>foo/1.0.0>bar/1.0.0>',
dep: '>project>foo/1.0.0>dep/1.0.0>' as NodeId,
bar: '>project>foo/1.0.0>bar/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: {
@@ -515,7 +516,7 @@ describe('unmet peer dependency issue resolved from subdependency', () => {
},
depth: 0,
}],
['>project>foo/1.0.0>dep/1.0.0>', {
['>project>foo/1.0.0>dep/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: {
@@ -527,7 +528,7 @@ describe('unmet peer dependency issue resolved from subdependency', () => {
},
depth: 1,
}],
['>project>foo/1.0.0>bar/1.0.0>', {
['>project>foo/1.0.0>bar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: {
@@ -590,10 +591,10 @@ test('resolve peer dependencies with npm aliases', async () => {
projects: [
{
directNodeIdsByAlias: {
foo: '>foo/1.0.0>',
bar: '>bar/1.0.0>',
'foo-next': '>foo/2.0.0>',
'bar-next': '>bar/2.0.0>',
foo: '>foo/1.0.0>' as NodeId,
bar: '>bar/1.0.0>' as NodeId,
'foo-next': '>foo/2.0.0>' as NodeId,
'bar-next': '>bar/2.0.0>' as NodeId,
},
topParents: [],
rootDir: '',
@@ -601,42 +602,42 @@ test('resolve peer dependencies with npm aliases', async () => {
},
],
resolvedImporters: {},
dependenciesTree: new Map<string, DependenciesTreeNode<PartialResolvedPackage>>([
['>foo/1.0.0>', {
dependenciesTree: new Map<NodeId, DependenciesTreeNode<PartialResolvedPackage>>([
['>foo/1.0.0>' as NodeId, {
children: {
bar: '>foo/1.0.0>bar/1.0.0>',
bar: '>foo/1.0.0>bar/1.0.0>' as NodeId,
},
installable: true,
resolvedPackage: fooPkg,
depth: 0,
}],
['>foo/1.0.0>bar/1.0.0>', {
['>foo/1.0.0>bar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barPkg,
depth: 1,
}],
['>foo/2.0.0>', {
['>foo/2.0.0>' as NodeId, {
children: {
bar: '>foo/2.0.0>bar/2.0.0>',
bar: '>foo/2.0.0>bar/2.0.0>' as NodeId,
},
installable: true,
resolvedPackage: fooAliasPkg,
depth: 0,
}],
['>foo/2.0.0>bar/2.0.0>', {
['>foo/2.0.0>bar/2.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barAliasPkg,
depth: 1,
}],
['>bar/1.0.0>', {
['>bar/1.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barPkg,
depth: 0,
}],
['>bar/2.0.0>', {
['>bar/2.0.0>' as NodeId, {
children: {},
installable: true,
resolvedPackage: barAliasPkg,

3
pnpm-lock.yaml generated
View File

@@ -5519,6 +5519,9 @@ importers:
'@pnpm/outdated':
specifier: workspace:*
version: 'link:'
'@pnpm/resolver-base':
specifier: workspace:*
version: link:../../resolving/resolver-base
'@types/ramda':
specifier: 0.29.12
version: 0.29.12

View File

@@ -1,8 +1,10 @@
export function createGitHostedPkgId ({ repo, commit, path }: { repo: string, commit: string, path?: string }): string {
import { type PkgResolutionId } from '@pnpm/resolver-base'
export function createGitHostedPkgId ({ repo, commit, path }: { repo: string, commit: string, path?: string }): PkgResolutionId {
let id = `${repo.includes('://') ? '' : 'https://'}${repo}#${commit}`
if (!id.startsWith('git+')) id = `git+${id}`
if (path) {
id += `&path:${path}`
}
return id
return id as PkgResolutionId
}

View File

@@ -1,4 +1,4 @@
import { type TarballResolution, type GitResolution, type ResolveResult } from '@pnpm/resolver-base'
import { type TarballResolution, type GitResolution, type ResolveResult, type PkgResolutionId } from '@pnpm/resolver-base'
import git from 'graceful-git'
import semver from 'semver'
import { parsePref, type HostedPackageSpec } from './parsePref'
@@ -50,11 +50,11 @@ export function createGitResolver (
resolution.path = parsedSpec.path
}
let id: string
let id: PkgResolutionId
if ('tarball' in resolution) {
id = resolution.tarball
id = resolution.tarball as PkgResolutionId
if (resolution.path) {
id += `#path:${resolution.path}`
id = `${id}#path:${resolution.path}` as PkgResolutionId
}
} else {
id = createGitHostedPkgId(resolution)

View File

@@ -2,6 +2,7 @@ import os from 'os'
import path from 'path'
import { PnpmError } from '@pnpm/error'
import normalize from 'normalize-path'
import { type PkgResolutionId } from '@pnpm/resolver-base'
// @ts-expect-error
const isWindows = process.platform === 'win32' || global['FAKE_WINDOWS']
@@ -12,7 +13,7 @@ const isAbsolutePath = /^[/]|^[A-Za-z]:/
export interface LocalPackageSpec {
dependencyPath: string
fetchSpec: string
id: string
id: PkgResolutionId
type: 'directory' | 'file'
normalizedPref: string
}
@@ -90,9 +91,11 @@ function fromLocal (
const dependencyPath = injected
? normalize(path.relative(lockfileDir, fetchSpec))
: normalize(path.resolve(fetchSpec))
const id = !injected && (type === 'directory' || projectDir === lockfileDir)
? `${protocol}${normalize(path.relative(projectDir, fetchSpec))}`
: `${protocol}${normalize(path.relative(lockfileDir, fetchSpec))}`
const id = (
!injected && (type === 'directory' || projectDir === lockfileDir)
? `${protocol}${normalize(path.relative(projectDir, fetchSpec))}`
: `${protocol}${normalize(path.relative(lockfileDir, fetchSpec))}`
) as PkgResolutionId
return {
dependencyPath,

View File

@@ -7,6 +7,7 @@ import {
} from '@pnpm/fetching-types'
import { resolveWorkspaceRange } from '@pnpm/resolve-workspace-range'
import {
type PkgResolutionId,
type PreferredVersions,
type ResolveResult,
type WantedDependency,
@@ -222,7 +223,7 @@ async function resolveNpm (
}
}
const id = `${pickedPackage.name}@${pickedPackage.version}`
const id = `${pickedPackage.name}@${pickedPackage.version}` as PkgResolutionId
const resolution = {
integrity: getIntegrity(pickedPackage.dist),
tarball: pickedPackage.dist.tarball,
@@ -336,15 +337,15 @@ function resolveFromLocalPackage (
lockfileDir?: string
}
): ResolveResult {
let id!: string
let id!: PkgResolutionId
let directory!: string
const localPackageDir = resolveLocalPackageDir(localPackage)
if (opts.hardLinkLocalPackages) {
directory = normalize(path.relative(opts.lockfileDir!, localPackageDir))
id = `file:${directory}`
id = `file:${directory}` as PkgResolutionId
} else {
directory = localPackageDir
id = `link:${normalize(path.relative(opts.projectDir, localPackageDir))}`
id = `link:${normalize(path.relative(opts.projectDir, localPackageDir))}` as PkgResolutionId
}
return {
id,

View File

@@ -1,4 +1,6 @@
import { type DependencyManifest } from '@pnpm/types'
import { type DependencyManifest, type PkgResolutionId } from '@pnpm/types'
export { type PkgResolutionId }
/**
* tarball hosted remotely
@@ -32,7 +34,7 @@ export type Resolution =
({ type: string } & object)
export interface ResolveResult {
id: string
id: PkgResolutionId
latest?: string
publishedAt?: string
manifest?: DependencyManifest

View File

@@ -1,4 +1,4 @@
import { type ResolveResult } from '@pnpm/resolver-base'
import { type PkgResolutionId, type ResolveResult } from '@pnpm/resolver-base'
export async function resolveFromTarball (
wantedDependency: { pref: string }
@@ -10,7 +10,7 @@ export async function resolveFromTarball (
if (isRepository(wantedDependency.pref)) return null
return {
id: wantedDependency.pref,
id: wantedDependency.pref as PkgResolutionId,
normalizedPref: wantedDependency.pref,
resolution: {
tarball: wantedDependency.pref,

View File

@@ -52,6 +52,7 @@
"devDependencies": {
"@pnpm/outdated": "workspace:*",
"@types/ramda": "0.29.12",
"@pnpm/resolver-base": "workspace:*",
"@types/semver": "7.5.3"
},
"funding": "https://opencollective.com/pnpm",

View File

@@ -1,4 +1,5 @@
import { type ResolveFunction } from '@pnpm/client'
import { type PkgResolutionId } from '@pnpm/resolver-base'
import { getManifest } from '../lib/createManifestGetter'
test('getManifest()', async () => {
@@ -15,7 +16,7 @@ test('getManifest()', async () => {
const resolve: ResolveFunction = async function (wantedPackage, opts) {
expect(opts.registry).toEqual('https://registry.npmjs.org/')
return {
id: 'foo/1.0.0',
id: 'foo/1.0.0' as PkgResolutionId,
latest: '1.0.0',
manifest: {
name: 'foo',
@@ -36,7 +37,7 @@ test('getManifest()', async () => {
const resolve2: ResolveFunction = async function (wantedPackage, opts) {
expect(opts.registry).toEqual('https://pnpm.io/')
return {
id: 'foo/2.0.0',
id: 'foo/2.0.0' as PkgResolutionId,
latest: '2.0.0',
manifest: {
name: 'foo',

View File

@@ -47,6 +47,9 @@
},
{
"path": "../../resolving/npm-resolver"
},
{
"path": "../../resolving/resolver-base"
}
],
"composite": true

View File

@@ -1,4 +1,5 @@
import {
type PkgResolutionId,
type DirectoryResolution,
type PreferredVersions,
type Resolution,
@@ -110,7 +111,7 @@ export type RequestPackageFunction = (
export interface RequestPackageOptions {
alwaysTryWorkspacePackages?: boolean
currentPkg?: {
id?: string
id?: PkgResolutionId
resolution?: Resolution
}
/**
@@ -147,7 +148,7 @@ export interface PackageResponse {
isInstallable?: boolean
resolution: Resolution
manifest?: PackageManifest
id: string
id: PkgResolutionId
normalizedPref?: string
updated: boolean
publishedAt?: string