mirror of
https://github.com/pnpm/pnpm.git
synced 2026-04-28 02:53:15 -04:00
feat: support resolving peers with npm aliases (#6220)
close #4301 Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
6
.changeset/wild-dolphins-work.md
Normal file
6
.changeset/wild-dolphins-work.md
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
"@pnpm/resolve-dependencies": patch
|
||||
"pnpm": patch
|
||||
---
|
||||
|
||||
Aliased packages should be used to resolve peer dependencies too [#4301](https://github.com/pnpm/pnpm/issues/4301).
|
||||
@@ -44,7 +44,7 @@
|
||||
"@pnpm/constants": "workspace:*",
|
||||
"@pnpm/lockfile-types": "workspace:*",
|
||||
"@pnpm/modules-yaml": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/types": "workspace:*",
|
||||
"is-windows": "^1.0.2",
|
||||
"isexe": "2.0.0",
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@pnpm/cafs": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"path-exists": "^4.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"@pnpm/filter-workspace-packages": "workspace:*",
|
||||
"@pnpm/plugin-commands-rebuild": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/ramda": "0.28.20",
|
||||
"@types/semver": "7.3.13",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"@pnpm/filter-workspace-packages": "workspace:*",
|
||||
"@pnpm/plugin-commands-script-runners": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@types/is-windows": "^1.0.0",
|
||||
"@types/ramda": "0.28.20",
|
||||
"is-windows": "^1.0.2",
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"@commitlint/prompt-cli": "^17.4.4",
|
||||
"@pnpm/eslint-config": "workspace:*",
|
||||
"@pnpm/meta-updater": "0.2.2",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/tsconfig": "workspace:*",
|
||||
"@types/jest": "^29.4.0",
|
||||
"@types/node": "^14.18.37",
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"@pnpm/filter-workspace-packages": "workspace:*",
|
||||
"@pnpm/plugin-commands-patching": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/normalize-path": "^3.0.0",
|
||||
"@types/ramda": "0.28.20",
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
"@pnpm/lockfile-types": "workspace:*",
|
||||
"@pnpm/package-store": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/store-path": "workspace:*",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
|
||||
@@ -1388,3 +1388,66 @@ test('deduplicate packages that have peers, when adding new dependency in a work
|
||||
expect(depPaths).toContain(`/@pnpm.e2e/abc@1.0.0${createPeersFolderSuffix([{ name: '@pnpm.e2e/peer-a', version: '1.0.0' }, { name: '@pnpm.e2e/peer-b', version: '1.0.0' }, { name: '@pnpm.e2e/peer-c', version: '1.0.0' }])}`)
|
||||
expect(depPaths).toContain(`/@pnpm.e2e/abc-parent-with-ab@1.0.0${createPeersFolderSuffix([{ name: '@pnpm.e2e/peer-c', version: '1.0.0' }])}`)
|
||||
})
|
||||
|
||||
test('resolve peer dependencies from aliased subdependencies if they are dependencies of a parent package', async () => {
|
||||
prepareEmpty()
|
||||
await addDistTag({ package: '@pnpm.e2e/peer-a', version: '1.0.0', distTag: 'latest' })
|
||||
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
|
||||
|
||||
await addDependenciesToPackage(
|
||||
{},
|
||||
['@pnpm.e2e/abc-parent-with-aliases'],
|
||||
await testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
|
||||
)
|
||||
|
||||
const lockfile = await readYamlFile<any>(path.resolve(WANTED_LOCKFILE)) // eslint-disable-line
|
||||
expect(lockfile.packages['/@pnpm.e2e/abc@1.0.0(@pnpm.e2e/peer-a@1.0.0)(@pnpm.e2e/peer-b@1.0.0)(@pnpm.e2e/peer-c@1.0.0)']).toBeTruthy()
|
||||
})
|
||||
|
||||
test('resolve peer dependency from aliased direct dependency', async () => {
|
||||
prepareEmpty()
|
||||
|
||||
const opts = await testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
|
||||
const manifest = await addDependenciesToPackage({}, ['peer-a@npm:@pnpm.e2e/peer-a@1.0.0'], opts)
|
||||
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc@1.0.0'], opts)
|
||||
|
||||
const lockfile = await readYamlFile<any>(path.resolve(WANTED_LOCKFILE)) // eslint-disable-line
|
||||
expect(lockfile.packages['/@pnpm.e2e/abc@1.0.0(@pnpm.e2e/peer-a@1.0.0)']).toBeTruthy()
|
||||
})
|
||||
|
||||
test('resolve peer dependency using the alias that differs from the real name of the direct dependency', async () => {
|
||||
prepareEmpty()
|
||||
|
||||
const opts = await testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
|
||||
const manifest = await addDependenciesToPackage({}, ['@pnpm.e2e/peer-b@npm:@pnpm.e2e/peer-a@1.0.0'], opts)
|
||||
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc@1.0.0'], opts)
|
||||
|
||||
const lockfile = await readYamlFile<any>(path.resolve(WANTED_LOCKFILE)) // eslint-disable-line
|
||||
expect(lockfile.packages['/@pnpm.e2e/abc@1.0.0(@pnpm.e2e/peer-a@1.0.0)(@pnpm.e2e/peer-a@1.0.0)']).toBeTruthy()
|
||||
expect(lockfile.packages['/@pnpm.e2e/abc@1.0.0(@pnpm.e2e/peer-a@1.0.0)(@pnpm.e2e/peer-a@1.0.0)']?.dependencies['@pnpm.e2e/peer-a']).toBe('1.0.0')
|
||||
expect(lockfile.packages['/@pnpm.e2e/abc@1.0.0(@pnpm.e2e/peer-a@1.0.0)(@pnpm.e2e/peer-a@1.0.0)']?.dependencies['@pnpm.e2e/peer-b']).toBe('/@pnpm.e2e/peer-a@1.0.0')
|
||||
})
|
||||
|
||||
test('when there are several aliased dependencies of the same package, pick the one with the highest version to resolve peers', async () => {
|
||||
prepareEmpty()
|
||||
|
||||
const opts = await testDefaults({ autoInstallPeers: false, strictPeerDependencies: false })
|
||||
const manifest = await addDependenciesToPackage({}, [
|
||||
'peer-c3@npm:@pnpm.e2e/peer-c@1.0.0',
|
||||
'peer-c2@npm:@pnpm.e2e/peer-c@1.0.1',
|
||||
'peer-c1@npm:@pnpm.e2e/peer-c@2.0.0',
|
||||
], opts)
|
||||
await addDependenciesToPackage(manifest, ['@pnpm.e2e/abc@1.0.0'], opts)
|
||||
|
||||
const lockfile = await readYamlFile<any>(path.resolve(WANTED_LOCKFILE)) // eslint-disable-line
|
||||
expect(lockfile.packages['/@pnpm.e2e/abc@1.0.0(@pnpm.e2e/peer-c@2.0.0)']).toBeTruthy()
|
||||
})
|
||||
|
||||
test('in a subdependency, when there are several aliased dependencies of the same package, pick the one with the highest version to resolve peers', async () => {
|
||||
prepareEmpty()
|
||||
|
||||
await addDependenciesToPackage({}, ['@pnpm.e2e/abc-parent-with-aliases-of-same-pkg@1.0.0'], await testDefaults({ autoInstallPeers: false, strictPeerDependencies: false }))
|
||||
|
||||
const lockfile = await readYamlFile<any>(path.resolve(WANTED_LOCKFILE)) // eslint-disable-line
|
||||
expect(lockfile.packages['/@pnpm.e2e/abc@1.0.0(@pnpm.e2e/peer-c@2.0.0)']).toBeTruthy()
|
||||
})
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
"@pnpm/package-store": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/read-projects-context": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/store-path": "workspace:*",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/fs-extra": "^9.0.13",
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"@pnpm/client": "workspace:*",
|
||||
"@pnpm/create-cafs-store": "workspace:*",
|
||||
"@pnpm/package-requester": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/normalize-path": "^3.0.0",
|
||||
"@types/ramda": "0.28.20",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"@pnpm/modules-yaml": "workspace:*",
|
||||
"@pnpm/plugin-commands-installation": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/proxyquire": "^1.3.28",
|
||||
"@types/ramda": "0.28.20",
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
} from '@pnpm/types'
|
||||
import promiseShare from 'promise-share'
|
||||
import difference from 'ramda/src/difference'
|
||||
import zipWith from 'ramda/src/zipWith'
|
||||
import { getWantedDependencies, type WantedDependency } from './getWantedDependencies'
|
||||
import { depPathToRef } from './depPathToRef'
|
||||
import { createNodeIdForLinkedLocalPkg, type UpdateMatchingFunction } from './resolveDependencies'
|
||||
@@ -173,7 +174,7 @@ export async function resolveDependencies (
|
||||
)
|
||||
}
|
||||
|
||||
const topParents: Array<{ name: string, version: string, linkedDir?: string }> = project.manifest
|
||||
const topParents: Array<{ name: string, version: string, alias?: string, linkedDir?: string }> = project.manifest
|
||||
? await getTopParents(
|
||||
difference(
|
||||
Object.keys(getAllDependenciesFromManifest(project.manifest)),
|
||||
@@ -440,13 +441,17 @@ function getAliasToDependencyTypeMap (manifest: ProjectManifest): Record<string,
|
||||
return depTypesOfAliases
|
||||
}
|
||||
|
||||
async function getTopParents (pkgNames: string[], modules: string) {
|
||||
async function getTopParents (pkgAliases: string[], modulesDir: string) {
|
||||
const pkgs = await Promise.all(
|
||||
pkgNames.map((pkgName) => path.join(modules, pkgName)).map(safeReadPackageJsonFromDir)
|
||||
pkgAliases.map((alias) => path.join(modulesDir, alias)).map(safeReadPackageJsonFromDir)
|
||||
)
|
||||
return (
|
||||
pkgs
|
||||
.filter(Boolean) as DependencyManifest[]
|
||||
)
|
||||
.map(({ name, version }: DependencyManifest) => ({ name, version }))
|
||||
return zipWith((manifest, alias) => {
|
||||
if (!manifest) return null
|
||||
return {
|
||||
alias,
|
||||
name: manifest.name,
|
||||
version: manifest.version,
|
||||
}
|
||||
}, pkgs, pkgAliases)
|
||||
.filter(Boolean) as DependencyManifest[]
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import filenamify from 'filenamify'
|
||||
import path from 'path'
|
||||
import semver from 'semver'
|
||||
import { semverUtils } from '@yarnpkg/core'
|
||||
import {
|
||||
type Dependencies,
|
||||
type PeerDependencyIssues,
|
||||
type PeerDependencyIssuesByProjects,
|
||||
import type {
|
||||
Dependencies,
|
||||
PeerDependencyIssues,
|
||||
PeerDependencyIssuesByProjects,
|
||||
} from '@pnpm/types'
|
||||
import { depPathToFilename, createPeersFolderSuffixNewFormat } from '@pnpm/dependency-path'
|
||||
import { type KeyValuePair } from 'ramda'
|
||||
import isEmpty from 'ramda/src/isEmpty'
|
||||
import mapValues from 'ramda/src/map'
|
||||
import pick from 'ramda/src/pick'
|
||||
@@ -51,7 +51,7 @@ export interface ProjectToResolve {
|
||||
directNodeIdsByAlias: { [alias: string]: string }
|
||||
// only the top dependencies that were already installed
|
||||
// to avoid warnings about unresolved peer dependencies
|
||||
topParents: Array<{ name: string, version: string }>
|
||||
topParents: Array<{ name: string, version: string, alias?: string }>
|
||||
rootDir: string // is only needed for logging
|
||||
id: string
|
||||
}
|
||||
@@ -182,30 +182,32 @@ function createPkgsByName<T extends PartialResolvedPackage> (
|
||||
dependenciesTree: DependenciesTree<T>,
|
||||
{ directNodeIdsByAlias, topParents }: {
|
||||
directNodeIdsByAlias: { [alias: string]: string }
|
||||
topParents: Array<{ name: string, version: string, linkedDir?: string }>
|
||||
topParents: Array<{ name: string, version: string, alias?: string, linkedDir?: string }>
|
||||
}
|
||||
) {
|
||||
return Object.assign(
|
||||
Object.fromEntries(
|
||||
topParents.map(({ name, version, linkedDir }): KeyValuePair<string, ParentRef> => [
|
||||
name,
|
||||
{
|
||||
depth: 0,
|
||||
version,
|
||||
nodeId: linkedDir,
|
||||
},
|
||||
])
|
||||
),
|
||||
toPkgByName(
|
||||
Object
|
||||
.keys(directNodeIdsByAlias)
|
||||
.map((alias) => ({
|
||||
alias,
|
||||
node: dependenciesTree[directNodeIdsByAlias[alias]],
|
||||
nodeId: directNodeIdsByAlias[alias],
|
||||
}))
|
||||
)
|
||||
const parentRefs = toPkgByName(
|
||||
Object
|
||||
.keys(directNodeIdsByAlias)
|
||||
.map((alias) => ({
|
||||
alias,
|
||||
node: dependenciesTree[directNodeIdsByAlias[alias]],
|
||||
nodeId: directNodeIdsByAlias[alias],
|
||||
}))
|
||||
)
|
||||
const _updateParentRefs = updateParentRefs.bind(null, parentRefs)
|
||||
for (const { name, version, alias, linkedDir } of topParents) {
|
||||
const pkg = {
|
||||
alias,
|
||||
depth: 0,
|
||||
version,
|
||||
nodeId: linkedDir,
|
||||
}
|
||||
_updateParentRefs(name, pkg)
|
||||
if (alias && alias !== name) {
|
||||
_updateParentRefs(alias, pkg)
|
||||
}
|
||||
}
|
||||
return parentRefs
|
||||
}
|
||||
|
||||
interface PeersCacheItem {
|
||||
@@ -272,10 +274,10 @@ function resolvePeersOfNode<T extends PartialResolvedPackage> (
|
||||
.every(([name, cachedNodeId]) => {
|
||||
const parentPkgNodeId = parentPkgs[name]?.nodeId
|
||||
if (!parentPkgNodeId || !cachedNodeId) return false
|
||||
if (parentPkgs[name].nodeId === cachedNodeId) return true
|
||||
if (parentPkgNodeId === cachedNodeId) return true
|
||||
if (
|
||||
ctx.pathsByNodeId[cachedNodeId] &&
|
||||
ctx.pathsByNodeId[cachedNodeId] === ctx.pathsByNodeId[parentPkgs[name].nodeId!]
|
||||
ctx.pathsByNodeId[cachedNodeId] === ctx.pathsByNodeId[parentPkgNodeId]
|
||||
) return true
|
||||
const parentDepPath = (ctx.dependenciesTree[parentPkgNodeId].resolvedPackage as T).depPath
|
||||
if (!ctx.purePkgs.has(parentDepPath)) return false
|
||||
@@ -572,16 +574,34 @@ interface ParentRef {
|
||||
depth: number
|
||||
// this is null only for already installed top dependencies
|
||||
nodeId?: string
|
||||
alias?: string
|
||||
}
|
||||
|
||||
function toPkgByName<T extends PartialResolvedPackage> (nodes: Array<{ alias: string, nodeId: string, node: DependenciesTreeNode<T> }>): ParentRefs {
|
||||
const pkgsByName: ParentRefs = {}
|
||||
const _updateParentRefs = updateParentRefs.bind(null, pkgsByName)
|
||||
for (const { alias, node, nodeId } of nodes) {
|
||||
pkgsByName[alias] = {
|
||||
const pkg = {
|
||||
alias,
|
||||
depth: node.depth,
|
||||
nodeId,
|
||||
version: node.resolvedPackage.version,
|
||||
}
|
||||
_updateParentRefs(alias, pkg)
|
||||
if (alias !== node.resolvedPackage.name) {
|
||||
_updateParentRefs(node.resolvedPackage.name, pkg)
|
||||
}
|
||||
}
|
||||
return pkgsByName
|
||||
}
|
||||
|
||||
function updateParentRefs (parentRefs: ParentRefs, newAlias: string, pkg: ParentRef) {
|
||||
const existing = parentRefs[newAlias]
|
||||
if (existing) {
|
||||
const existingHasAlias = existing.alias != null || existing.alias !== newAlias
|
||||
if (!existingHasAlias) return
|
||||
const newHasAlias = pkg.alias != null || pkg.alias !== newAlias
|
||||
if (newHasAlias && semver.gte(existing.version, pkg.version)) return
|
||||
}
|
||||
parentRefs[newAlias] = pkg
|
||||
}
|
||||
|
||||
@@ -516,3 +516,99 @@ describe('unmet peer dependency issue resolved from subdependency', () => {
|
||||
expect(peerDependencyIssuesByProjects.project.bad.dep[0].resolvedFrom).toStrictEqual([{ name: 'foo', version: '1.0.0' }])
|
||||
})
|
||||
})
|
||||
|
||||
test('resolve peer dependencies with npm aliases', () => {
|
||||
const fooPkg = {
|
||||
name: 'foo',
|
||||
depPath: 'foo/1.0.0',
|
||||
version: '1.0.0',
|
||||
peerDependencies: {
|
||||
bar: '1.0.0',
|
||||
},
|
||||
}
|
||||
const fooAliasPkg = {
|
||||
name: 'foo',
|
||||
depPath: 'foo/2.0.0',
|
||||
version: '2.0.0',
|
||||
peerDependencies: {
|
||||
bar: '2.0.0',
|
||||
},
|
||||
}
|
||||
const barPkg = {
|
||||
name: 'bar',
|
||||
depPath: 'bar/1.0.0',
|
||||
version: '1.0.0',
|
||||
peerDependencies: {},
|
||||
}
|
||||
const barAliasPkg = {
|
||||
name: 'bar',
|
||||
depPath: 'bar/2.0.0',
|
||||
version: '2.0.0',
|
||||
peerDependencies: {},
|
||||
}
|
||||
const { dependenciesGraph } = resolvePeers({
|
||||
projects: [
|
||||
{
|
||||
directNodeIdsByAlias: {
|
||||
foo: '>foo/1.0.0>',
|
||||
bar: '>bar/1.0.0>',
|
||||
'foo-next': '>foo/2.0.0>',
|
||||
'bar-next': '>bar/2.0.0>',
|
||||
},
|
||||
topParents: [],
|
||||
rootDir: '',
|
||||
id: '',
|
||||
},
|
||||
],
|
||||
dependenciesTree: {
|
||||
'>foo/1.0.0>': {
|
||||
children: {
|
||||
bar: '>foo/1.0.0>bar/1.0.0>',
|
||||
},
|
||||
installable: true,
|
||||
resolvedPackage: fooPkg,
|
||||
depth: 0,
|
||||
},
|
||||
'>foo/1.0.0>bar/1.0.0>': {
|
||||
children: {},
|
||||
installable: true,
|
||||
resolvedPackage: barPkg,
|
||||
depth: 1,
|
||||
},
|
||||
'>foo/2.0.0>': {
|
||||
children: {
|
||||
bar: '>foo/2.0.0>bar/2.0.0>',
|
||||
},
|
||||
installable: true,
|
||||
resolvedPackage: fooAliasPkg,
|
||||
depth: 0,
|
||||
},
|
||||
'>foo/2.0.0>bar/2.0.0>': {
|
||||
children: {},
|
||||
installable: true,
|
||||
resolvedPackage: barAliasPkg,
|
||||
depth: 1,
|
||||
},
|
||||
'>bar/1.0.0>': {
|
||||
children: {},
|
||||
installable: true,
|
||||
resolvedPackage: barPkg,
|
||||
depth: 0,
|
||||
},
|
||||
'>bar/2.0.0>': {
|
||||
children: {},
|
||||
installable: true,
|
||||
resolvedPackage: barAliasPkg,
|
||||
depth: 0,
|
||||
},
|
||||
},
|
||||
virtualStoreDir: '',
|
||||
lockfileDir: '',
|
||||
})
|
||||
expect(Object.keys(dependenciesGraph)).toStrictEqual([
|
||||
'bar/1.0.0',
|
||||
'foo/1.0.0(bar@1.0.0)',
|
||||
'bar/2.0.0',
|
||||
'foo/2.0.0(bar@2.0.0)',
|
||||
])
|
||||
})
|
||||
|
||||
627
pnpm-lock.yaml
generated
627
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -60,7 +60,7 @@
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/read-package-json": "workspace:*",
|
||||
"@pnpm/read-project-manifest": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/run-npm": "workspace:*",
|
||||
"@pnpm/tabtab": "^0.1.2",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"@pnpm/lockfile-types": "workspace:*",
|
||||
"@pnpm/plugin-commands-deploy": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0"
|
||||
"@pnpm/registry-mock": "3.7.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@pnpm/cli-utils": "workspace:*",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"@pnpm/filter-workspace-packages": "workspace:*",
|
||||
"@pnpm/plugin-commands-publishing": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@types/cross-spawn": "^6.0.2",
|
||||
"@types/is-windows": "^1.0.0",
|
||||
"@types/npm-packlist": "^3.0.0",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"@pnpm/plugin-commands-installation": "workspace:*",
|
||||
"@pnpm/plugin-commands-licenses": "workspace:*",
|
||||
"@pnpm/read-package-json": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@types/ramda": "0.28.20",
|
||||
"@types/wrap-ansi": "^8.0.1",
|
||||
"@types/zkochan__table": "npm:@types/table@6.0.0",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"@pnpm/plugin-commands-installation": "workspace:*",
|
||||
"@pnpm/plugin-commands-listing": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@types/ramda": "0.28.20",
|
||||
"execa": "npm:safe-execa@0.1.2",
|
||||
"strip-ansi": "^6.0.1",
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
"@pnpm/plugin-commands-installation": "workspace:*",
|
||||
"@pnpm/plugin-commands-outdated": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@pnpm/test-fixtures": "workspace:*",
|
||||
"@types/ramda": "0.28.20",
|
||||
"@types/wrap-ansi": "^8.0.1",
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"@pnpm/lockfile-file": "workspace:*",
|
||||
"@pnpm/plugin-commands-store": "workspace:*",
|
||||
"@pnpm/prepare": "workspace:*",
|
||||
"@pnpm/registry-mock": "3.5.0",
|
||||
"@pnpm/registry-mock": "3.7.0",
|
||||
"@types/archy": "0.0.32",
|
||||
"@types/ramda": "0.28.20",
|
||||
"@types/ssri": "^7.1.1",
|
||||
|
||||
Reference in New Issue
Block a user