@pnpm/hooks.pnpmfile 1100.0.31 → 1100.0.33
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 +30 -0
- package/lib/requireHooks.d.ts +1 -1
- package/lib/requireHooks.js +30 -33
- package/lib/requirePnpmfile.js +11 -1
- package/package.json +10 -10
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# @pnpm/pnpmfile
|
|
2
2
|
|
|
3
|
+
## 1100.0.33
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- `pnpm install` now applies changes to or removal of a global `readPackage` hook when an existing lockfile is present [pnpm/pnpm#15136](https://github.com/pnpm/pnpm/issues/15136).
|
|
8
|
+
|
|
9
|
+
- The project's `.pnpmfile.mjs` or `.pnpmfile.cjs` now runs after the pnpmfiles of config dependency plugins [#9891](https://github.com/pnpm/pnpm/issues/9891).
|
|
10
|
+
|
|
11
|
+
- A `readPackage` hook that sets a dependency range to a value other than a string, such as `undefined`, now fails the install with an error that names the dependency, the package, and the pnpmfile. Delete the property to remove a dependency [#5517](https://github.com/pnpm/pnpm/issues/5517).
|
|
12
|
+
|
|
13
|
+
- Updated dependencies:
|
|
14
|
+
- @pnpm/core-loggers@1101.0.1
|
|
15
|
+
- @pnpm/crypto.hash@1100.0.6
|
|
16
|
+
- @pnpm/error@1100.2.0
|
|
17
|
+
- @pnpm/hooks.types@1101.0.4
|
|
18
|
+
- @pnpm/lockfile.types@1100.1.3
|
|
19
|
+
- @pnpm/store.controller-types@1101.3.1
|
|
20
|
+
- @pnpm/types@1102.1.1
|
|
21
|
+
|
|
22
|
+
## 1100.0.32
|
|
23
|
+
|
|
24
|
+
### Patch Changes
|
|
25
|
+
|
|
26
|
+
- Updated dependencies:
|
|
27
|
+
- @pnpm/core-loggers@1101.0.0
|
|
28
|
+
- @pnpm/crypto.hash@1100.0.5
|
|
29
|
+
- @pnpm/hooks.types@1101.0.3
|
|
30
|
+
- @pnpm/lockfile.types@1100.1.2
|
|
31
|
+
- @pnpm/store.controller-types@1101.3.0
|
|
32
|
+
|
|
3
33
|
## 1100.0.31
|
|
4
34
|
|
|
5
35
|
### Patch Changes
|
package/lib/requireHooks.d.ts
CHANGED
|
@@ -22,7 +22,7 @@ export interface CookedHooks {
|
|
|
22
22
|
* `pnpmfileChecksum` comparisons, so nothing downstream may treat the
|
|
23
23
|
* checksum as proof the hooks are unchanged.
|
|
24
24
|
*/
|
|
25
|
-
|
|
25
|
+
untrackedPnpmfileReadPackageHook?: boolean;
|
|
26
26
|
}
|
|
27
27
|
export interface RequireHooksResult {
|
|
28
28
|
hooks: CookedHooks;
|
package/lib/requireHooks.js
CHANGED
|
@@ -12,31 +12,6 @@ export async function requireHooks(prefix, opts) {
|
|
|
12
12
|
includeInChecksum: false,
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
|
-
const entries = [];
|
|
16
|
-
const loadedFiles = [];
|
|
17
|
-
if (opts.tryLoadDefaultPnpmfile) {
|
|
18
|
-
// Prefer .pnpmfile.mjs over .pnpmfile.cjs. Only load one.
|
|
19
|
-
const mjsPath = pathAbsolute('.pnpmfile.mjs', prefix);
|
|
20
|
-
const mjsResult = await requirePnpmfile(mjsPath, prefix);
|
|
21
|
-
if (mjsResult != null) {
|
|
22
|
-
loadedFiles.push(mjsPath);
|
|
23
|
-
entries.push({
|
|
24
|
-
file: mjsPath,
|
|
25
|
-
includeInChecksum: true,
|
|
26
|
-
hooks: mjsResult.pnpmfileModule?.hooks,
|
|
27
|
-
finders: mjsResult.pnpmfileModule?.finders,
|
|
28
|
-
resolvers: mjsResult.pnpmfileModule?.resolvers,
|
|
29
|
-
fetchers: mjsResult.pnpmfileModule?.fetchers,
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
pnpmfiles.push({
|
|
34
|
-
path: '.pnpmfile.cjs',
|
|
35
|
-
includeInChecksum: true,
|
|
36
|
-
optional: true,
|
|
37
|
-
});
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
15
|
if (opts.pnpmfiles) {
|
|
41
16
|
for (const pnpmfile of opts.pnpmfiles) {
|
|
42
17
|
pnpmfiles.push({
|
|
@@ -45,11 +20,30 @@ export async function requireHooks(prefix, opts) {
|
|
|
45
20
|
});
|
|
46
21
|
}
|
|
47
22
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
23
|
+
// The default pnpmfile goes after the listed ones, which include the
|
|
24
|
+
// pnpmfiles of config dependency plugins, so that its hooks run last and can
|
|
25
|
+
// extend or override what the plugins set.
|
|
26
|
+
if (opts.tryLoadDefaultPnpmfile) {
|
|
27
|
+
// Prefer .pnpmfile.mjs over .pnpmfile.cjs. Only load one.
|
|
28
|
+
pnpmfiles.push({
|
|
29
|
+
path: '.pnpmfile.mjs',
|
|
30
|
+
fallbackPath: '.pnpmfile.cjs',
|
|
31
|
+
includeInChecksum: true,
|
|
32
|
+
optional: true,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
const entries = [];
|
|
36
|
+
// Must stay sequential: loading in parallel registers .mjs pnpmfiles in import
|
|
37
|
+
// completion order, not in the order listed above.
|
|
38
|
+
for (const { path, fallbackPath, includeInChecksum, optional } of pnpmfiles) {
|
|
39
|
+
for (const candidate of fallbackPath == null ? [path] : [path, fallbackPath]) {
|
|
40
|
+
const file = pathAbsolute(candidate, prefix);
|
|
41
|
+
const loadedEntry = entries.find((entry) => entry.file === file);
|
|
42
|
+
if (loadedEntry != null) {
|
|
43
|
+
loadedEntry.includeInChecksum ||= includeInChecksum;
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
const requirePnpmfileResult = await requirePnpmfile(file, prefix); // eslint-disable-line no-await-in-loop
|
|
53
47
|
if (requirePnpmfileResult != null) {
|
|
54
48
|
entries.push({
|
|
55
49
|
file,
|
|
@@ -59,12 +53,13 @@ export async function requireHooks(prefix, opts) {
|
|
|
59
53
|
resolvers: requirePnpmfileResult.pnpmfileModule?.resolvers,
|
|
60
54
|
fetchers: requirePnpmfileResult.pnpmfileModule?.fetchers,
|
|
61
55
|
});
|
|
56
|
+
break;
|
|
62
57
|
}
|
|
63
|
-
|
|
58
|
+
if (candidate === (fallbackPath ?? path) && !optional) {
|
|
64
59
|
throw new PnpmError('PNPMFILE_NOT_FOUND', `pnpmfile at "${file}" is not found`);
|
|
65
60
|
}
|
|
66
61
|
}
|
|
67
|
-
}
|
|
62
|
+
}
|
|
68
63
|
const mergedFinders = {};
|
|
69
64
|
const cookedHooks = {
|
|
70
65
|
readPackage: [],
|
|
@@ -74,7 +69,9 @@ export async function requireHooks(prefix, opts) {
|
|
|
74
69
|
filterLog: [],
|
|
75
70
|
updateConfig: [],
|
|
76
71
|
};
|
|
77
|
-
|
|
72
|
+
if (entries.some((entry) => !entry.includeInChecksum)) {
|
|
73
|
+
cookedHooks.untrackedPnpmfileReadPackageHook = entries.some((entry) => entry.hooks?.readPackage != null && !entry.includeInChecksum);
|
|
74
|
+
}
|
|
78
75
|
// calculate combined checksum for all included files
|
|
79
76
|
if (entries.some((entry) => entry.hooks != null)) {
|
|
80
77
|
cookedHooks.calculatePnpmfileChecksum = async () => {
|
package/lib/requirePnpmfile.js
CHANGED
|
@@ -53,7 +53,7 @@ export async function requirePnpmfile(pnpmFilePath, prefix) {
|
|
|
53
53
|
pkg.optionalDependencies = pkg.optionalDependencies ?? {};
|
|
54
54
|
pkg.peerDependencies = pkg.peerDependencies ?? {};
|
|
55
55
|
const newPkg = await readPackage(pkg, ...args);
|
|
56
|
-
if (!newPkg) {
|
|
56
|
+
if (!newPkg || typeof newPkg !== 'object' || Array.isArray(newPkg)) {
|
|
57
57
|
throw new BadReadPackageHookError(pnpmFilePath, 'readPackage hook did not return a package manifest object.');
|
|
58
58
|
}
|
|
59
59
|
const dependencies = ['dependencies', 'devDependencies', 'optionalDependencies', 'peerDependencies'];
|
|
@@ -61,6 +61,11 @@ export async function requirePnpmfile(pnpmFilePath, prefix) {
|
|
|
61
61
|
if (newPkg[dep] != null && (typeof newPkg[dep] !== 'object' || Array.isArray(newPkg[dep]))) {
|
|
62
62
|
throw new BadReadPackageHookError(pnpmFilePath, `readPackage hook returned package manifest object's property '${dep}' must be an object.`);
|
|
63
63
|
}
|
|
64
|
+
for (const [depName, range] of Object.entries(newPkg[dep] ?? {})) {
|
|
65
|
+
if (typeof range !== 'string') {
|
|
66
|
+
throw new BadReadPackageHookError(pnpmFilePath, `readPackage hook returned an invalid range for '${depName}' in the '${dep}' of ${describePackage(newPkg)}. Expected a string, got ${range === null ? 'null' : typeof range}. To remove the dependency, delete the property.`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
64
69
|
}
|
|
65
70
|
return newPkg;
|
|
66
71
|
};
|
|
@@ -82,6 +87,11 @@ export async function requirePnpmfile(pnpmFilePath, prefix) {
|
|
|
82
87
|
throw new PnpmFileFailError(pnpmFilePath, toError(err));
|
|
83
88
|
}
|
|
84
89
|
}
|
|
90
|
+
function describePackage(pkg) {
|
|
91
|
+
if (typeof pkg.name !== 'string' || !pkg.name)
|
|
92
|
+
return 'an unnamed package';
|
|
93
|
+
return typeof pkg.version === 'string' && pkg.version ? `${pkg.name}@${pkg.version}` : pkg.name;
|
|
94
|
+
}
|
|
85
95
|
/**
|
|
86
96
|
* Errors are matched by shape, not by class, because asynchronous module customization
|
|
87
97
|
* hooks forward them from their own realm, where `util.types.isNativeError()` returns false.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/hooks.pnpmfile",
|
|
3
|
-
"version": "1100.0.
|
|
3
|
+
"version": "1100.0.33",
|
|
4
4
|
"description": "Reading a .pnpmfile.cjs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
"!*.map"
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@pnpm/core-loggers": "
|
|
31
|
-
"@pnpm/crypto.hash": "1100.0.
|
|
32
|
-
"@pnpm/error": "1100.
|
|
33
|
-
"@pnpm/hooks.types": "1101.0.
|
|
34
|
-
"@pnpm/lockfile.types": "1100.1.
|
|
35
|
-
"@pnpm/store.controller-types": "1101.
|
|
36
|
-
"@pnpm/types": "1102.1.
|
|
30
|
+
"@pnpm/core-loggers": "1101.0.1",
|
|
31
|
+
"@pnpm/crypto.hash": "1100.0.6",
|
|
32
|
+
"@pnpm/error": "1100.2.0",
|
|
33
|
+
"@pnpm/hooks.types": "1101.0.4",
|
|
34
|
+
"@pnpm/lockfile.types": "1100.1.3",
|
|
35
|
+
"@pnpm/store.controller-types": "1101.3.1",
|
|
36
|
+
"@pnpm/types": "1102.1.1",
|
|
37
37
|
"chalk": "^6.0.0",
|
|
38
38
|
"path-absolute": "^2.0.0"
|
|
39
39
|
},
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@jest/globals": "30.4.1",
|
|
45
|
-
"@pnpm/fetching.fetcher-base": "1100.2.
|
|
46
|
-
"@pnpm/hooks.pnpmfile": "1100.0.
|
|
45
|
+
"@pnpm/fetching.fetcher-base": "1100.2.11",
|
|
46
|
+
"@pnpm/hooks.pnpmfile": "1100.0.33",
|
|
47
47
|
"@pnpm/logger": "1100.0.0",
|
|
48
48
|
"@pnpm/test-fixtures": "1100.0.1"
|
|
49
49
|
},
|