@pnpm/global.packages 1101.1.2 → 1101.1.4
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.
- package/CHANGELOG.md +19 -0
- package/lib/scanGlobalPackages.d.ts +11 -0
- package/lib/scanGlobalPackages.js +43 -3
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
# @pnpm/global.packages
|
|
2
2
|
|
|
3
|
+
## 1101.1.4
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `pnpm add -g`, `pnpm update -g`, and `pnpm remove -g` no longer fail with `ERR_PNPM_PACKAGE_MANIFEST_IO_ERROR` when another global package's link into the store dangles, for example after the store was pruned. The pnpm install script failed the same way on such a machine.
|
|
8
|
+
|
|
9
|
+
- Updated dependencies:
|
|
10
|
+
- @pnpm/bins.resolver@1100.0.17
|
|
11
|
+
- @pnpm/crypto.hash@1100.0.6
|
|
12
|
+
- @pnpm/pkg-manifest.reader@1100.0.20
|
|
13
|
+
- @pnpm/types@1102.1.1
|
|
14
|
+
|
|
15
|
+
## 1101.1.3
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- Updated dependencies:
|
|
20
|
+
- @pnpm/crypto.hash@1100.0.5
|
|
21
|
+
|
|
3
22
|
## 1101.1.2
|
|
4
23
|
|
|
5
24
|
### Patch Changes
|
|
@@ -18,4 +18,15 @@ export declare function scanGlobalPackages(globalDir: string): GlobalPackageInfo
|
|
|
18
18
|
export declare function findGlobalPackage(globalDir: string, alias: string): GlobalPackageInfo | null;
|
|
19
19
|
export declare function getGlobalPackageDetails(info: GlobalPackageInfo): Promise<InstalledGlobalPackage[]>;
|
|
20
20
|
export declare function cleanOrphanedInstallDirs(globalDir: string): void;
|
|
21
|
+
/**
|
|
22
|
+
* The bin names installed by a group (deduplicated).
|
|
23
|
+
*
|
|
24
|
+
* A group whose `node_modules` is wholly absent owns no bins, and neither
|
|
25
|
+
* does a declared dependency whose directory under `node_modules` is absent,
|
|
26
|
+
* a link left dangling by a pruned store included: no bin can resolve
|
|
27
|
+
* through a directory that is not there. Every dependency directory that
|
|
28
|
+
* does exist must hold a readable, valid manifest: returning a partial set
|
|
29
|
+
* would make destructive callers mistake unknown ownership for an unowned
|
|
30
|
+
* bin.
|
|
31
|
+
*/
|
|
21
32
|
export declare function getInstalledBinNames(info: GlobalPackageInfo): Promise<string[]>;
|
|
@@ -46,9 +46,8 @@ export function scanGlobalPackages(globalDir) {
|
|
|
46
46
|
entries = fs.readdirSync(globalDir, { withFileTypes: true });
|
|
47
47
|
}
|
|
48
48
|
catch (err) {
|
|
49
|
-
if (
|
|
49
|
+
if (isNotFound(err))
|
|
50
50
|
return [];
|
|
51
|
-
}
|
|
52
51
|
throw err;
|
|
53
52
|
}
|
|
54
53
|
const result = [];
|
|
@@ -139,13 +138,36 @@ export function cleanOrphanedInstallDirs(globalDir) {
|
|
|
139
138
|
fs.rmSync(dirPath, { recursive: true, force: true });
|
|
140
139
|
}
|
|
141
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* The bin names installed by a group (deduplicated).
|
|
143
|
+
*
|
|
144
|
+
* A group whose `node_modules` is wholly absent owns no bins, and neither
|
|
145
|
+
* does a declared dependency whose directory under `node_modules` is absent,
|
|
146
|
+
* a link left dangling by a pruned store included: no bin can resolve
|
|
147
|
+
* through a directory that is not there. Every dependency directory that
|
|
148
|
+
* does exist must hold a readable, valid manifest: returning a partial set
|
|
149
|
+
* would make destructive callers mistake unknown ownership for an unowned
|
|
150
|
+
* bin.
|
|
151
|
+
*/
|
|
142
152
|
export async function getInstalledBinNames(info) {
|
|
143
153
|
const bins = new Set();
|
|
144
154
|
const aliases = Object.keys(info.dependencies);
|
|
145
155
|
const modulesDir = path.join(info.installDir, 'node_modules');
|
|
156
|
+
if (!await dirExists(modulesDir))
|
|
157
|
+
return [];
|
|
146
158
|
await Promise.all(aliases.map(async (alias) => {
|
|
147
159
|
const depDir = path.join(modulesDir, alias);
|
|
148
|
-
|
|
160
|
+
let manifest;
|
|
161
|
+
try {
|
|
162
|
+
manifest = await readPackageJsonFromDir(depDir);
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
// Probing after the read rather than before also covers a link
|
|
166
|
+
// pruned while the scan runs.
|
|
167
|
+
if (isNotFound(err) && !await dirExists(depDir))
|
|
168
|
+
return;
|
|
169
|
+
throw err;
|
|
170
|
+
}
|
|
149
171
|
const binsOfPkg = await getBinsFromPackageManifest(manifest, depDir);
|
|
150
172
|
for (const bin of binsOfPkg) {
|
|
151
173
|
bins.add(bin.name);
|
|
@@ -153,4 +175,22 @@ export async function getInstalledBinNames(info) {
|
|
|
153
175
|
}));
|
|
154
176
|
return [...bins];
|
|
155
177
|
}
|
|
178
|
+
/**
|
|
179
|
+
* Only ENOENT reads as absent; every other error surfaces, so unreadable
|
|
180
|
+
* ownership is never mistaken for unowned.
|
|
181
|
+
*/
|
|
182
|
+
async function dirExists(dir) {
|
|
183
|
+
try {
|
|
184
|
+
await fs.promises.stat(dir);
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
catch (err) {
|
|
188
|
+
if (isNotFound(err))
|
|
189
|
+
return false;
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function isNotFound(err) {
|
|
194
|
+
return util.types.isNativeError(err) && 'code' in err && err.code === 'ENOENT';
|
|
195
|
+
}
|
|
156
196
|
//# sourceMappingURL=scanGlobalPackages.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/global.packages",
|
|
3
|
-
"version": "1101.1.
|
|
3
|
+
"version": "1101.1.4",
|
|
4
4
|
"description": "Utilities for managing isolated global packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -28,14 +28,14 @@
|
|
|
28
28
|
"!*.map"
|
|
29
29
|
],
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@pnpm/bins.resolver": "1100.0.
|
|
32
|
-
"@pnpm/crypto.hash": "1100.0.
|
|
33
|
-
"@pnpm/pkg-manifest.reader": "1100.0.
|
|
31
|
+
"@pnpm/bins.resolver": "1100.0.17",
|
|
32
|
+
"@pnpm/crypto.hash": "1100.0.6",
|
|
33
|
+
"@pnpm/pkg-manifest.reader": "1100.0.20",
|
|
34
34
|
"@pnpm/text.ordinal-comparator": "1100.0.0",
|
|
35
|
-
"@pnpm/types": "1102.1.
|
|
35
|
+
"@pnpm/types": "1102.1.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@pnpm/global.packages": "1101.1.
|
|
38
|
+
"@pnpm/global.packages": "1101.1.4"
|
|
39
39
|
},
|
|
40
40
|
"engines": {
|
|
41
41
|
"node": ">=22.13"
|