@pnpm/global.commands 1100.0.31 → 1100.0.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  import type { CommandHandlerMap } from '@pnpm/cli.command';
2
+ import { type GlobalPackageInfo } from '@pnpm/global.packages';
2
3
  import type { CreateStoreControllerOptions } from '@pnpm/store.connection-manager';
3
4
  import { type ResolutionPolicyViolation } from './installGlobalPackages.js';
4
5
  export type GlobalAddOptions = CreateStoreControllerOptions & {
@@ -17,3 +18,5 @@ export type GlobalAddOptions = CreateStoreControllerOptions & {
17
18
  updateResolutionPolicyManifest?: (violations: readonly ResolutionPolicyViolation[], dir: string) => Promise<void>;
18
19
  };
19
20
  export declare function handleGlobalAdd(opts: GlobalAddOptions, params: string[], commands: CommandHandlerMap): Promise<void>;
21
+ export declare function getReplacementAliases(aliases: string[]): string[];
22
+ export declare function shouldReplaceExistingGlobalInstall(pkg: GlobalPackageInfo, aliases: string[], replacementAliases: string[]): boolean;
package/lib/globalAdd.js CHANGED
@@ -88,6 +88,7 @@ async function installGroup(ctx, commands) {
88
88
  // Read resolved aliases from the installed package.json
89
89
  const pkgJson = readPackageJsonFromDirRawSync(installDir);
90
90
  const aliases = Object.keys(pkgJson.dependencies ?? {});
91
+ const replacementAliases = getReplacementAliases(aliases);
91
92
  // Check for bin name conflicts with other global packages
92
93
  // (must happen before removeExistingGlobalInstalls so we don't lose existing packages on failure)
93
94
  const pkgs = await readInstalledPackages(installDir);
@@ -97,7 +98,7 @@ async function installGroup(ctx, commands) {
97
98
  globalDir,
98
99
  globalBinDir,
99
100
  newPkgs: pkgs,
100
- shouldSkip: (pkg) => aliases.some((alias) => alias in pkg.dependencies),
101
+ shouldSkip: (pkg) => shouldReplaceExistingGlobalInstall(pkg, aliases, replacementAliases),
101
102
  });
102
103
  }
103
104
  catch (err) {
@@ -105,7 +106,7 @@ async function installGroup(ctx, commands) {
105
106
  throw err;
106
107
  }
107
108
  // Remove any existing global installations of these aliases
108
- await removeExistingGlobalInstalls(globalDir, globalBinDir, aliases);
109
+ await removeExistingGlobalInstalls({ globalDir, globalBinDir, aliases, replacementAliases });
109
110
  // Compute cache key and create hash symlink pointing to install dir
110
111
  const cacheHash = createGlobalCacheKey({
111
112
  aliases,
@@ -117,6 +118,21 @@ async function installGroup(ctx, commands) {
117
118
  await linkBinsOfPackages(pkgs, globalBinDir, { excludeBins: binsToSkip });
118
119
  await opts.updateResolutionPolicyManifest?.(resolutionPolicyViolations, globalDir);
119
120
  }
121
+ const PNPM_CLI_PACKAGE_ALIASES = ['pnpm', '@pnpm/exe'];
122
+ export function getReplacementAliases(aliases) {
123
+ if (!aliases.some((alias) => PNPM_CLI_PACKAGE_ALIASES.includes(alias)))
124
+ return aliases;
125
+ return [...new Set([...aliases, ...PNPM_CLI_PACKAGE_ALIASES])];
126
+ }
127
+ export function shouldReplaceExistingGlobalInstall(pkg, aliases, replacementAliases) {
128
+ if (aliases.some((alias) => alias in pkg.dependencies))
129
+ return true;
130
+ return isPnpmCliOnlyGroup(pkg) && replacementAliases.some((alias) => alias in pkg.dependencies);
131
+ }
132
+ function isPnpmCliOnlyGroup(pkg) {
133
+ const aliases = Object.keys(pkg.dependencies);
134
+ return aliases.length > 0 && aliases.every((alias) => PNPM_CLI_PACKAGE_ALIASES.includes(alias));
135
+ }
120
136
  function splitCommaSeparated(param, baseDir) {
121
137
  if (!param.includes(','))
122
138
  return [param];
@@ -173,12 +189,15 @@ function resolveLocalParam(param, baseDir) {
173
189
  }
174
190
  return param;
175
191
  }
176
- async function removeExistingGlobalInstalls(globalDir, globalBinDir, aliases) {
192
+ async function removeExistingGlobalInstalls(opts) {
193
+ const { globalDir, globalBinDir, aliases, replacementAliases } = opts;
177
194
  // Collect unique groups to remove (dedup by hash)
178
195
  const groupsToRemove = new Map();
179
- for (const alias of aliases) {
196
+ for (const alias of replacementAliases) {
180
197
  const existing = findGlobalPackage(globalDir, alias);
181
- if (existing && !groupsToRemove.has(existing.hash)) {
198
+ if (existing &&
199
+ shouldReplaceExistingGlobalInstall(existing, aliases, replacementAliases) &&
200
+ !groupsToRemove.has(existing.hash)) {
182
201
  groupsToRemove.set(existing.hash, getInstalledBinNames(existing));
183
202
  }
184
203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pnpm/global.commands",
3
- "version": "1100.0.31",
3
+ "version": "1100.0.32",
4
4
  "description": "Global package command handlers for pnpm",
5
5
  "keywords": [
6
6
  "pnpm",
@@ -31,25 +31,25 @@
31
31
  "@pnpm/util.lex-comparator": "^4.0.1",
32
32
  "is-subdir": "^2.0.0",
33
33
  "symlink-dir": "^10.0.1",
34
- "@pnpm/bins.remover": "1100.0.12",
35
34
  "@pnpm/bins.linker": "1100.0.16",
36
- "@pnpm/bins.resolver": "1100.0.8",
35
+ "@pnpm/bins.remover": "1100.0.12",
37
36
  "@pnpm/cli.command": "1100.0.1",
38
- "@pnpm/cli.utils": "1101.0.13",
39
- "@pnpm/config.matcher": "1100.0.1",
40
- "@pnpm/config.reader": "1101.11.0",
37
+ "@pnpm/config.reader": "1101.11.1",
41
38
  "@pnpm/core-loggers": "1100.2.1",
42
- "@pnpm/error": "1100.0.1",
39
+ "@pnpm/deps.inspection.list": "1100.0.22",
40
+ "@pnpm/config.matcher": "1100.0.1",
43
41
  "@pnpm/global.packages": "1100.0.10",
44
- "@pnpm/deps.inspection.list": "1100.0.21",
45
- "@pnpm/installing.deps-installer": "1102.2.0",
46
- "@pnpm/store.connection-manager": "1100.3.3",
42
+ "@pnpm/error": "1100.0.1",
47
43
  "@pnpm/pkg-manifest.reader": "1100.0.9",
48
- "@pnpm/types": "1101.3.2"
44
+ "@pnpm/cli.utils": "1101.0.13",
45
+ "@pnpm/installing.deps-installer": "1102.2.1",
46
+ "@pnpm/types": "1101.3.2",
47
+ "@pnpm/store.connection-manager": "1100.3.4",
48
+ "@pnpm/bins.resolver": "1100.0.8"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@jest/globals": "30.4.1",
52
- "@pnpm/global.commands": "1100.0.31"
52
+ "@pnpm/global.commands": "1100.0.32"
53
53
  },
54
54
  "engines": {
55
55
  "node": ">=22.13"