feat: dedupe packages that have peers when dedupe-peer-dependents is true (#6153)

This commit is contained in:
Zoltan Kochan
2023-03-03 08:31:41 +02:00
committed by GitHub
parent 62d1cb8f1e
commit 5c31fa8be6
25 changed files with 280 additions and 83 deletions

View File

@@ -0,0 +1,41 @@
---
"@pnpm/resolve-dependencies": minor
"@pnpm/core": minor
"@pnpm/config": minor
"pnpm": minor
---
A new setting is now supported: `dedupe-peer-dependents`.
When this setting is set to `true`, packages with peer dependencies will be deduplicated after peers resolution.
For instance, let's say we have a workspace with two projects and both of them have `webpack` in their dependencies. `webpack` has `esbuild` in its optional peer dependencies, and one of the projects has `esbuild` in its dependencies. In this case, pnpm will link two instances of `webpack` to the `node_modules/.pnpm` directory: one with `esbuild` and another one without it:
```
node_modules
.pnpm
webpack@1.0.0_esbuild@1.0.0
webpack@1.0.0
project1
node_modules
webpack -> ../../node_modules/.pnpm/webpack@1.0.0/node_modules/webpack
project2
node_modules
webpack -> ../../node_modules/.pnpm/webpack@1.0.0_esbuild@1.0.0/node_modules/webpack
esbuild
```
This makes sense because `webpack` is used in two projects, and one of the projects doesn't have `esbuild`, so the two projects cannot share the same instance of `webpack`. However, this is not what most developers expect, especially since in a hoisted `node_modules`, there would only be one instance of `webpack`. Therefore, you may now use the `dedupe-peer-dependents` setting to deduplicate `webpack` when it has no conflicting peer dependencies. In this case, if we set `dedupe-peer-dependents` to `true`, both projects will use the same `webpack` instance, which is the one that has `esbuild` resolved:
```
node_modules
.pnpm
webpack@1.0.0_esbuild@1.0.0
project1
node_modules
webpack -> ../../node_modules/.pnpm/webpack@1.0.0_esbuild@1.0.0/node_modules/webpack
project2
node_modules
webpack -> ../../node_modules/.pnpm/webpack@1.0.0_esbuild@1.0.0/node_modules/webpack
esbuild
```

View File

@@ -44,7 +44,7 @@
"@pnpm/constants": "workspace:*",
"@pnpm/lockfile-types": "workspace:*",
"@pnpm/modules-yaml": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/types": "workspace:*",
"is-windows": "^1.0.2",
"isexe": "2.0.0",

View File

@@ -41,7 +41,7 @@
},
"dependencies": {
"@pnpm/cafs": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"path-exists": "^4.0.0"
},
"devDependencies": {

View File

@@ -156,6 +156,7 @@ export interface Config {
gitShallowHosts?: string[]
legacyDirFiltering?: boolean
onlyBuiltDependencies?: string[]
dedupePeerDependents?: boolean
registries: Registries
ignoreWorkspaceRootCheck: boolean

View File

@@ -39,6 +39,7 @@ export const types = Object.assign({
'merge-git-branch-lockfiles-branch-pattern': Array,
color: ['always', 'auto', 'never'],
'config-dir': String,
'dedupe-peer-dependents': Boolean,
dev: [null, true],
dir: String,
'enable-modules-dir': Boolean,
@@ -183,6 +184,7 @@ export async function getConfig (
'auto-install-peers': false,
bail: true,
color: 'auto',
'dedupe-peer-dependents': false,
'enable-modules-dir': true,
'extend-node-path': true,
'fetch-retries': 2,

View File

@@ -38,7 +38,7 @@
"@pnpm/filter-workspace-packages": "workspace:*",
"@pnpm/plugin-commands-rebuild": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/test-fixtures": "workspace:*",
"@types/ramda": "0.28.20",
"@types/semver": "7.3.13",

View File

@@ -37,7 +37,7 @@
"@pnpm/filter-workspace-packages": "workspace:*",
"@pnpm/plugin-commands-script-runners": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@types/is-windows": "^1.0.0",
"@types/ramda": "0.28.20",
"is-windows": "^1.0.2",

View File

@@ -33,10 +33,10 @@
},
"homepage": "https://github.com/pnpm/pnpm/blob/main/patching/plugin-commands-patching#readme",
"devDependencies": {
"@pnpm/plugin-commands-patching": "workspace:*",
"@pnpm/filter-workspace-packages": "workspace:*",
"@pnpm/plugin-commands-patching": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@types/ramda": "0.28.20",
"write-yaml-file": "^4.2.0"
},

View File

@@ -77,7 +77,7 @@
"@pnpm/git-utils": "workspace:*",
"@pnpm/package-store": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/store-path": "workspace:*",
"@pnpm/test-fixtures": "workspace:*",
"@types/fs-extra": "^9.0.13",

View File

@@ -121,6 +121,7 @@ export interface StrictInstallOptions {
allProjects: ProjectOptions[]
resolveSymlinksInInjectedDirs: boolean
dedupeDirectDeps: boolean
dedupePeerDependents: boolean
useLockfileV6?: boolean
extendNodePath: boolean
}
@@ -208,6 +209,7 @@ const defaults = async (opts: InstallOptions) => {
modulesCacheMaxAge: 7 * 24 * 60,
resolveSymlinksInInjectedDirs: false,
dedupeDirectDeps: false,
dedupePeerDependents: false,
resolvePeersFromWorkspaceRoot: false,
extendNodePath: true,
} as StrictInstallOptions

View File

@@ -807,7 +807,8 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
!opts.currentLockfileIsUpToDate ||
opts.force ||
opts.needsFullResolution ||
ctx.lockfileHadConflicts
ctx.lockfileHadConflicts ||
opts.dedupePeerDependents
// Ignore some fields when fixing lockfile, so these fields can be regenerated
// and make sure it's up to date
@@ -853,6 +854,7 @@ const _installInContext: InstallFunction = async (projects, ctx, opts) => {
autoInstallPeers: opts.autoInstallPeers,
currentLockfile: ctx.currentLockfile,
defaultUpdateDepth: (opts.update || (opts.updateMatching != null)) ? opts.depth : -1,
dedupePeerDependents: opts.dedupePeerDependents,
dryRun: opts.lockfileOnly,
engineStrict: opts.engineStrict,
force: opts.force,

View File

@@ -1225,3 +1225,102 @@ test('peer dependency is grouped with dependency when peer is resolved not from
const lockfile = await readYamlFile<Lockfile>(path.resolve(WANTED_LOCKFILE))
expect(lockfile.packages?.['/ajv-keywords/1.5.0_ajv@ajv'].dependencies?.['ajv']).toBe('link:ajv')
})
test('deduplicate packages that have optional and non-optional peers', async () => {
await addDistTag({ package: '@pnpm.e2e/peer-a', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-b', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
prepareEmpty()
await addDependenciesToPackage({},
['@pnpm.e2e/abc-optional-peers', '@pnpm.e2e/abc-optional-peers-parent'],
await testDefaults({ autoInstallPeers: false, dedupePeerDependents: true })
)
const lockfile = await readYamlFile<Lockfile>(path.resolve(WANTED_LOCKFILE))
const depPaths = Object.keys(lockfile.packages ?? {})
expect(depPaths.length).toBe(5)
expect(depPaths).toContain(`/@pnpm.e2e/abc-optional-peers/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' }])}`)
})
test('deduplicate packages that have peers', async () => {
await addDistTag({ package: '@pnpm.e2e/abc-parent-with-ab', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-a', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-b', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
prepareEmpty()
await addDependenciesToPackage({},
['@pnpm.e2e/abc-grand-parent-with-c@1.0.0', '@pnpm.e2e/abc-parent-with-ab@1.0.0', '@pnpm.e2e/abc@1.0.0'],
await testDefaults({ autoInstallPeers: false, dedupePeerDependents: true })
)
const lockfile = await readYamlFile<Lockfile>(path.resolve(WANTED_LOCKFILE))
const depPaths = Object.keys(lockfile.packages ?? {})
expect(depPaths.length).toBe(8)
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('deduplicate packages that have peers, when adding new dependency in a workspace', async () => {
await addDistTag({ package: '@pnpm.e2e/abc-parent-with-ab', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-a', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-b', version: '1.0.0', distTag: 'latest' })
await addDistTag({ package: '@pnpm.e2e/peer-c', version: '1.0.0', distTag: 'latest' })
const manifest1 = {
name: 'project-1',
dependencies: {
'@pnpm.e2e/abc-grand-parent-with-c': '1.0.0',
},
}
const manifest2 = {
name: 'project-2',
}
preparePackages([
{
location: 'project-1',
package: manifest1,
},
{
location: 'project-2',
package: manifest2,
},
])
const importers: MutatedProject[] = [
{
mutation: 'install',
rootDir: path.resolve('project-1'),
},
{
mutation: 'install',
rootDir: path.resolve('project-2'),
},
]
const allProjects = [
{
buildIndex: 0,
manifest: manifest1,
rootDir: path.resolve('project-1'),
},
{
buildIndex: 0,
manifest: manifest2,
rootDir: path.resolve('project-2'),
},
]
await mutateModules(importers, await testDefaults({ allProjects, autoInstallPeers: false, dedupePeerDependents: true }))
importers[1] = {
dependencySelectors: ['@pnpm.e2e/abc@1.0.0'],
mutation: 'installSome',
rootDir: path.resolve('project-2'),
}
await mutateModules(importers, await testDefaults({ allProjects, autoInstallPeers: false, dedupePeerDependents: true }))
const lockfile = await readYamlFile<Lockfile>(path.resolve(WANTED_LOCKFILE))
const depPaths = Object.keys(lockfile.packages ?? {})
expect(depPaths.length).toBe(8)
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' }])}`)
})

View File

@@ -22,7 +22,7 @@
"@pnpm/package-store": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/read-projects-context": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/store-path": "workspace:*",
"@pnpm/test-fixtures": "workspace:*",
"@types/fs-extra": "^9.0.13",

View File

@@ -68,7 +68,7 @@
"@pnpm/client": "workspace:*",
"@pnpm/create-cafs-store": "workspace:*",
"@pnpm/package-requester": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/test-fixtures": "workspace:*",
"@types/normalize-path": "^3.0.0",
"@types/ramda": "0.28.20",

View File

@@ -38,7 +38,7 @@
"@pnpm/modules-yaml": "workspace:*",
"@pnpm/plugin-commands-installation": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/test-fixtures": "workspace:*",
"@types/proxyquire": "^1.3.28",
"@types/ramda": "0.28.20",

View File

@@ -89,6 +89,7 @@ export async function resolveDependencies (
importers: ImporterToResolve[],
opts: ResolveDependenciesOptions & {
defaultUpdateDepth: number
dedupePeerDependents?: boolean
preserveWorkspaceProtocol: boolean
saveWorkspaceProtocol: 'rolling' | boolean
lockfileIncludeTarballUrl?: boolean
@@ -209,6 +210,7 @@ export async function resolveDependencies (
peerDependencyIssuesByProjects,
} = resolvePeers({
dependenciesTree,
dedupePeerDependents: opts.dedupePeerDependents,
lockfileDir: opts.lockfileDir,
projects: projectsToLink,
virtualStoreDir: opts.virtualStoreDir,

View File

@@ -32,6 +32,7 @@ export interface GenericDependenciesGraphNode {
installable: boolean
isBuilt?: boolean
isPure: boolean
resolvedPeerNames: string[]
}
export type PartialResolvedPackage = Pick<ResolvedPackage,
@@ -63,6 +64,7 @@ export function resolvePeers<T extends PartialResolvedPackage> (
lockfileDir: string
resolvePeersFromWorkspaceRoot?: boolean
useLockfileV6?: boolean
dedupePeerDependents?: boolean
}
): {
dependenciesGraph: GenericDependenciesGraph<T>
@@ -71,6 +73,7 @@ export function resolvePeers<T extends PartialResolvedPackage> (
} {
const depGraph: GenericDependenciesGraph<T> = {}
const pathsByNodeId: Record<string, string> = {}
const depPathsByPkgId: Record<string, string[]> = {}
const _createPkgsByName = createPkgsByName.bind(null, opts.dependenciesTree)
const rootPkgsByName = opts.resolvePeersFromWorkspaceRoot ? getRootPkgsByName(opts.dependenciesTree, opts.projects) : {}
const peerDependencyIssuesByProjects: PeerDependencyIssuesByProjects = {}
@@ -87,6 +90,7 @@ export function resolvePeers<T extends PartialResolvedPackage> (
depGraph,
lockfileDir: opts.lockfileDir,
pathsByNodeId,
depPathsByPkgId,
peersCache: new Map(),
peerDependencyIssues,
purePkgs: new Set(),
@@ -110,6 +114,15 @@ export function resolvePeers<T extends PartialResolvedPackage> (
for (const { directNodeIdsByAlias, id } of opts.projects) {
dependenciesByProjectId[id] = mapValues((nodeId) => pathsByNodeId[nodeId], directNodeIdsByAlias)
}
if (opts.dedupePeerDependents) {
const depPathsMap = deduplicateDepPaths(depPathsByPkgId, depGraph)
Object.values(depGraph).forEach((node) => {
node.children = mapValues((childDepPath) => depPathsMap[childDepPath] ?? childDepPath, node.children)
})
for (const { id } of opts.projects) {
dependenciesByProjectId[id] = mapValues((depPath) => depPathsMap[depPath] ?? depPath, dependenciesByProjectId[id])
}
}
return {
dependenciesGraph: depGraph,
dependenciesByProjectId,
@@ -117,6 +130,51 @@ export function resolvePeers<T extends PartialResolvedPackage> (
}
}
function nodeDepsCount (node: GenericDependenciesGraphNode) {
return Object.keys(node.children).length + node.resolvedPeerNames.length
}
function deduplicateDepPaths<T extends PartialResolvedPackage> (
depPathsByPkgId: Record<string, string[]>,
depGraph: GenericDependenciesGraph<T>
) {
const depPathsMap: Record<string, string> = {}
for (let depPaths of Object.values(depPathsByPkgId)) {
if (depPaths.length === 1) continue
depPaths = depPaths.sort((depPath1, depPath2) => nodeDepsCount(depGraph[depPath1]) - nodeDepsCount(depGraph[depPath2]))
let currentDepPaths = depPaths
while (currentDepPaths.length) {
const depPath1 = currentDepPaths.pop()!
const nextDepPaths = []
while (currentDepPaths.length) {
const depPath2 = currentDepPaths.pop()!
if (isCompatibleAndHasMoreDeps(depGraph, depPath1, depPath2)) {
depPathsMap[depPath2] = depPath1
} else {
nextDepPaths.push(depPath2)
}
}
nextDepPaths.push(...currentDepPaths)
currentDepPaths = nextDepPaths
}
}
return depPathsMap
}
function isCompatibleAndHasMoreDeps<T extends PartialResolvedPackage> (
depGraph: GenericDependenciesGraph<T>,
depPath1: string,
depPath2: string
) {
const node1 = depGraph[depPath1]
const node2 = depGraph[depPath2]
const node1DepPaths = Object.keys(node1.children)
const node2DepPaths = Object.keys(node2.children)
return nodeDepsCount(node1) > nodeDepsCount(node2) &&
node2DepPaths.every((depPath) => node1DepPaths.includes(depPath)) &&
node2.resolvedPeerNames.every((depPath) => node1.resolvedPeerNames.includes(depPath))
}
function getRootPkgsByName<T extends PartialResolvedPackage> (dependenciesTree: DependenciesTree<T>, projects: ProjectToResolve[]) {
const rootProject = projects.length > 1 ? projects.find(({ id }) => id === '.') : null
return rootProject == null ? {} : createPkgsByName(dependenciesTree, rootProject)
@@ -165,12 +223,16 @@ interface PeersResolution {
resolvedPeers: Record<string, string>
}
interface ResolvePeersContext {
pathsByNodeId: { [nodeId: string]: string }
depPathsByPkgId?: Record<string, string[]>
}
function resolvePeersOfNode<T extends PartialResolvedPackage> (
nodeId: string,
parentParentPkgs: ParentRefs,
ctx: {
ctx: ResolvePeersContext & {
dependenciesTree: DependenciesTree<T>
pathsByNodeId: { [nodeId: string]: string }
depGraph: GenericDependenciesGraph<T>
virtualStoreDir: string
peerDependencyIssues: Pick<PeerDependencyIssues, 'bad' | 'missing'>
@@ -294,6 +356,14 @@ function resolvePeersOfNode<T extends PartialResolvedPackage> (
}
ctx.pathsByNodeId[nodeId] = depPath
if (ctx.depPathsByPkgId != null) {
if (!ctx.depPathsByPkgId[resolvedPackage.depPath]) {
ctx.depPathsByPkgId[resolvedPackage.depPath] = []
}
if (!ctx.depPathsByPkgId[resolvedPackage.depPath].includes(depPath)) {
ctx.depPathsByPkgId[resolvedPackage.depPath].push(depPath)
}
}
const peerDependencies = { ...resolvedPackage.peerDependencies }
if (!ctx.depGraph[depPath] || ctx.depGraph[depPath].depth > node.depth) {
const dir = path.join(modules, resolvedPackage.name)
@@ -325,6 +395,7 @@ function resolvePeersOfNode<T extends PartialResolvedPackage> (
modules,
peerDependencies,
transitivePeerDependencies,
resolvedPeerNames: Object.keys(allResolvedPeers),
}
}
return { resolvedPeers: allResolvedPeers, missingPeers: allMissingPeers }
@@ -365,8 +436,7 @@ function resolvePeersOfChildren<T extends PartialResolvedPackage> (
[alias: string]: string
},
parentPkgs: ParentRefs,
ctx: {
pathsByNodeId: { [nodeId: string]: string }
ctx: ResolvePeersContext & {
peerDependencyIssues: Pick<PeerDependencyIssues, 'bad' | 'missing'>
peersCache: PeersCache
virtualStoreDir: string

100
pnpm-lock.yaml generated
View File

@@ -174,8 +174,8 @@ importers:
specifier: workspace:*
version: link:../../pkg-manager/modules-yaml
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/types':
specifier: workspace:*
version: link:../../packages/types
@@ -214,8 +214,8 @@ importers:
specifier: workspace:*
version: link:../../store/cafs
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
path-exists:
specifier: ^4.0.0
version: 4.0.0
@@ -1099,8 +1099,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/test-fixtures':
specifier: workspace:*
version: link:../../__utils__/test-fixtures
@@ -1208,8 +1208,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@types/is-windows':
specifier: ^1.0.0
version: 1.0.0
@@ -2532,8 +2532,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@types/ramda':
specifier: 0.28.20
version: 0.28.20
@@ -2768,8 +2768,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/store-path':
specifier: workspace:*
version: link:../../store/store-path
@@ -3032,8 +3032,8 @@ importers:
specifier: workspace:*
version: link:../read-projects-context
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/store-path':
specifier: workspace:*
version: link:../../store/store-path
@@ -3395,8 +3395,8 @@ importers:
specifier: workspace:*
version: 'link:'
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/test-fixtures':
specifier: workspace:*
version: link:../../__utils__/test-fixtures
@@ -3579,8 +3579,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/test-fixtures':
specifier: workspace:*
version: link:../../__utils__/test-fixtures
@@ -4120,8 +4120,8 @@ importers:
specifier: workspace:*
version: link:../pkg-manifest/read-project-manifest
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/run-npm':
specifier: workspace:*
version: link:../exec/run-npm
@@ -4371,8 +4371,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
releasing/plugin-commands-publishing:
dependencies:
@@ -4468,8 +4468,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@types/cross-spawn':
specifier: ^6.0.2
version: 6.0.2
@@ -5016,8 +5016,8 @@ importers:
specifier: workspace:*
version: link:../../pkg-manifest/read-package-json
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@types/ramda':
specifier: 0.28.20
version: 0.28.20
@@ -5080,8 +5080,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@types/ramda':
specifier: 0.28.20
version: 0.28.20
@@ -5177,8 +5177,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@pnpm/test-fixtures':
specifier: workspace:*
version: link:../../__utils__/test-fixtures
@@ -5524,8 +5524,8 @@ importers:
specifier: workspace:*
version: link:../../__utils__/prepare
'@pnpm/registry-mock':
specifier: 3.4.0
version: 3.4.0(typanion@3.12.1)
specifier: 3.5.0
version: 3.5.0(typanion@3.12.1)
'@types/archy':
specifier: 0.0.32
version: 0.0.32
@@ -7993,7 +7993,7 @@ packages:
'@pnpm/find-workspace-dir': 5.0.1
'@pnpm/find-workspace-packages': 5.0.36(@pnpm/logger@5.0.0)(@yarnpkg/core@4.0.0-rc.14)(typanion@3.12.1)
'@pnpm/logger': 5.0.0
'@pnpm/types': 8.10.0
'@pnpm/types': 8.9.0
'@yarnpkg/core': 4.0.0-rc.14(typanion@3.12.1)
load-json-file: 7.0.1
meow: 10.1.5
@@ -8381,24 +8381,6 @@ packages:
- typanion
dev: true
/@pnpm/registry-mock@3.4.0(typanion@3.12.1):
resolution: {integrity: sha512-M61ULPZS0ByO0gokTFmJCLvlb6W/idHp7Z6lIDQjKBII2z8DpFjI5D895F2MsNVxYLu3ZfZ3c3GISNtIbSFuPA==}
engines: {node: '>=10.13'}
hasBin: true
dependencies:
anonymous-npm-registry-client: 0.2.0
cpr: 3.0.1
execa: 5.1.1
read-yaml-file: 2.1.0
rimraf: 3.0.2
tempy: 1.0.1
verdaccio: 5.21.2(typanion@3.12.1)
write-yaml-file: 4.2.0
transitivePeerDependencies:
- encoding
- supports-color
- typanion
/@pnpm/registry-mock@3.5.0(typanion@3.12.1):
resolution: {integrity: sha512-llz2BE8GB3vc/hFAQmKJtSrFoVnI0E2Nx+TPeIdn7zXTia+J03UYI6K3TPJMWcB37895BSMaFxDZh5abGASDgQ==}
engines: {node: '>=10.13'}
@@ -8416,7 +8398,6 @@ packages:
- encoding
- supports-color
- typanion
dev: true
/@pnpm/remove-bins@4.0.5(@pnpm/logger@5.0.0):
resolution: {integrity: sha512-XQLCrLW4C80CZfMsTUIQhD1t4D21SIB9R1+9sP4CMXbOMxakIzctl/XKBVyYZCkAgNLgiII6S7rdBISYtsqx3A==}
@@ -8561,7 +8542,6 @@ packages:
/@pnpm/types@8.9.0:
resolution: {integrity: sha512-3MYHYm8epnciApn6w5Fzx6sepawmsNU7l6lvIq+ER22/DPSrr83YMhU/EQWnf4lORn2YyiXFj0FJSyJzEtIGmw==}
engines: {node: '>=14.6'}
dev: false
/@pnpm/util.lex-comparator@1.0.0:
resolution: {integrity: sha512-3aBQPHntVgk5AweBWZn+1I/fqZ9krK/w01197aYVkAJQGftb+BVWgEepxY5GChjSW12j52XX+CmfynYZ/p0DFQ==}
@@ -8694,7 +8674,7 @@ packages:
/@types/byline@4.2.33:
resolution: {integrity: sha512-LJYez7wrWcJQQDknqZtrZuExMGP0IXmPl1rOOGDqLbu+H7UNNRfKNuSxCBcQMLH1EfjeWidLedC/hCc5dDfBog==}
dependencies:
'@types/node': 18.14.3
'@types/node': 14.18.37
dev: true
/@types/cacheable-request@6.0.3:
@@ -8702,7 +8682,7 @@ packages:
dependencies:
'@types/http-cache-semantics': 4.0.1
'@types/keyv': 3.1.4
'@types/node': 18.14.3
'@types/node': 14.18.37
'@types/responselike': 1.0.0
/@types/concat-stream@2.0.0:
@@ -8730,7 +8710,7 @@ packages:
resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==}
dependencies:
'@types/minimatch': 5.1.2
'@types/node': 18.14.3
'@types/node': 14.18.37
dev: true
/@types/graceful-fs@4.1.6:
@@ -8804,7 +8784,7 @@ packages:
/@types/keyv@3.1.4:
resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
dependencies:
'@types/node': 18.14.3
'@types/node': 14.18.37
/@types/lodash@4.14.181:
resolution: {integrity: sha512-n3tyKthHJbkiWhDZs3DkhkCzt2MexYHXlX0td5iMplyfwketaOeKboEVBqzceH7juqvEg3q5oUoBFxSLu7zFag==}
@@ -8847,7 +8827,6 @@ packages:
/@types/node@14.18.37:
resolution: {integrity: sha512-7GgtHCs/QZrBrDzgIJnQtuSvhFSwhyYSI2uafSwZoNt1iOGhEN5fwNrQMjtONyHm9+/LoA4453jH0CMYcr06Pg==}
dev: true
/@types/node@18.14.3:
resolution: {integrity: sha512-1y36CC5iL5CMyKALzwX9cwwxcWIxvIBe3gzs4GrXWXEQ8klQnCZ2U/WDGiNrXHmQcUhnaun17XG9TEIDlGj2RA==}
@@ -8884,7 +8863,7 @@ packages:
/@types/responselike@1.0.0:
resolution: {integrity: sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==}
dependencies:
'@types/node': 18.14.3
'@types/node': 14.18.37
/@types/retry@0.12.2:
resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==}
@@ -17357,7 +17336,7 @@ packages:
/wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
dependencies:
string-width: 1.0.2
string-width: 4.2.3
/widest-line@3.1.0:
resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==}
@@ -17670,7 +17649,6 @@ time:
/@pnpm/npm-package-arg@1.0.0: '2022-06-28T12:48:31.287Z'
/@pnpm/os.env.path-extender@0.2.10: '2023-02-28T01:46:02.862Z'
/@pnpm/ramda@0.28.1: '2022-08-03T13:56:59.597Z'
/@pnpm/registry-mock@3.4.0: '2023-02-08T00:47:00.662Z'
/@pnpm/registry-mock@3.5.0: '2023-03-02T17:51:20.657Z'
/@pnpm/semver-diff@1.1.0: '2021-11-16T12:40:59.941Z'
/@pnpm/tabtab@0.1.2: '2021-03-05T17:31:19.932Z'

View File

@@ -60,7 +60,7 @@
"@pnpm/prepare": "workspace:*",
"@pnpm/read-package-json": "workspace:*",
"@pnpm/read-project-manifest": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/run-npm": "workspace:*",
"@pnpm/tabtab": "^0.1.2",
"@pnpm/test-fixtures": "workspace:*",

View File

@@ -42,7 +42,7 @@
"@pnpm/lockfile-types": "workspace:*",
"@pnpm/plugin-commands-deploy": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0"
"@pnpm/registry-mock": "3.5.0"
},
"dependencies": {
"@pnpm/cli-utils": "workspace:*",

View File

@@ -38,7 +38,7 @@
"@pnpm/filter-workspace-packages": "workspace:*",
"@pnpm/plugin-commands-publishing": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@types/cross-spawn": "^6.0.2",
"@types/is-windows": "^1.0.0",
"@types/npm-packlist": "^3.0.0",

View File

@@ -38,7 +38,7 @@
"@pnpm/plugin-commands-installation": "workspace:*",
"@pnpm/plugin-commands-licenses": "workspace:*",
"@pnpm/read-package-json": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@types/ramda": "0.28.20",
"@types/wrap-ansi": "^8.0.1",
"@types/zkochan__table": "npm:@types/table@6.0.0",

View File

@@ -37,7 +37,7 @@
"@pnpm/plugin-commands-installation": "workspace:*",
"@pnpm/plugin-commands-listing": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@types/ramda": "0.28.20",
"execa": "npm:safe-execa@0.1.2",
"strip-ansi": "^6.0.1",

View File

@@ -38,7 +38,7 @@
"@pnpm/plugin-commands-installation": "workspace:*",
"@pnpm/plugin-commands-outdated": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@pnpm/test-fixtures": "workspace:*",
"@types/ramda": "0.28.20",
"@types/wrap-ansi": "^8.0.1",

View File

@@ -37,7 +37,7 @@
"@pnpm/lockfile-file": "workspace:*",
"@pnpm/plugin-commands-store": "workspace:*",
"@pnpm/prepare": "workspace:*",
"@pnpm/registry-mock": "3.4.0",
"@pnpm/registry-mock": "3.5.0",
"@types/archy": "0.0.32",
"@types/ramda": "0.28.20",
"@types/ssri": "^7.1.1",