@pnpm/installing.env-installer 1101.1.8 → 1102.0.1
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/lib/assertValidConfigDepVersion.d.ts +1 -0
- package/lib/assertValidConfigDepVersion.js +11 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/installConfigDeps.js +3 -0
- package/lib/migrateConfigDeps.js +13 -12
- package/lib/resolveAndInstallConfigDeps.js +4 -3
- package/lib/resolveConfigDeps.js +11 -12
- package/lib/resolvePackageManagerIntegrities.js +3 -2
- package/lib/verifyEnvLockfile.d.ts +2 -0
- package/lib/verifyEnvLockfile.js +24 -0
- package/lib/writeVerifiedEnvLockfile.d.ts +2 -0
- package/lib/writeVerifiedEnvLockfile.js +9 -0
- package/package.json +27 -27
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function assertValidConfigDepVersion(name: string, version: string): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { PnpmError } from '@pnpm/error';
|
|
2
|
+
import semver from 'semver';
|
|
3
|
+
// A config-dep version becomes a store path segment (`<name>/<version>/<hash>`),
|
|
4
|
+
// so reject non-semver values to keep a traversal-shaped version from escaping
|
|
5
|
+
// the store root.
|
|
6
|
+
export function assertValidConfigDepVersion(name, version) {
|
|
7
|
+
if (semver.valid(version) == null) {
|
|
8
|
+
throw new PnpmError('INVALID_CONFIG_DEP_VERSION', `The config dependency "${name}" has an invalid version "${version}"`, { hint: 'A config dependency version must be an exact semver version.' });
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=assertValidConfigDepVersion.js.map
|
package/lib/index.d.ts
CHANGED
|
@@ -2,3 +2,4 @@ export { installConfigDeps, type InstallConfigDepsOpts } from './installConfigDe
|
|
|
2
2
|
export { resolveAndInstallConfigDeps, type ResolveAndInstallConfigDepsOpts } from './resolveAndInstallConfigDeps.js';
|
|
3
3
|
export { resolveConfigDeps, type ResolveConfigDepsOpts } from './resolveConfigDeps.js';
|
|
4
4
|
export { isPackageManagerResolved, resolvePackageManagerIntegrities, type ResolvePackageManagerIntegritiesOpts } from './resolvePackageManagerIntegrities.js';
|
|
5
|
+
export { verifyEnvLockfile } from './verifyEnvLockfile.js';
|
package/lib/index.js
CHANGED
|
@@ -2,4 +2,5 @@ export { installConfigDeps } from './installConfigDeps.js';
|
|
|
2
2
|
export { resolveAndInstallConfigDeps } from './resolveAndInstallConfigDeps.js';
|
|
3
3
|
export { resolveConfigDeps } from './resolveConfigDeps.js';
|
|
4
4
|
export { isPackageManagerResolved, resolvePackageManagerIntegrities } from './resolvePackageManagerIntegrities.js';
|
|
5
|
+
export { verifyEnvLockfile } from './verifyEnvLockfile.js';
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/lib/installConfigDeps.js
CHANGED
|
@@ -11,6 +11,7 @@ import { rimraf } from '@zkochan/rimraf';
|
|
|
11
11
|
import getNpmTarballUrl from 'get-npm-tarball-url';
|
|
12
12
|
import { symlinkDir } from 'symlink-dir';
|
|
13
13
|
import { migrateConfigDepsToLockfile } from './migrateConfigDeps.js';
|
|
14
|
+
import { verifyEnvLockfile } from './verifyEnvLockfile.js';
|
|
14
15
|
/**
|
|
15
16
|
* Install config dependencies using the env lockfile.
|
|
16
17
|
* Accepts either a EnvLockfile directly (from resolveConfigDeps) or
|
|
@@ -109,12 +110,14 @@ export async function installConfigDeps(configDepsOrLockfile, opts) {
|
|
|
109
110
|
async function normalizeForInstall(configDepsOrLockfile, opts) {
|
|
110
111
|
// If it's a EnvLockfile object (has lockfileVersion), use it directly
|
|
111
112
|
if (isEnvLockfile(configDepsOrLockfile)) {
|
|
113
|
+
verifyEnvLockfile(configDepsOrLockfile);
|
|
112
114
|
return normalizeFromLockfile(configDepsOrLockfile, opts.registries);
|
|
113
115
|
}
|
|
114
116
|
// It's ConfigDependencies from workspace manifest.
|
|
115
117
|
// Try to read the env lockfile first.
|
|
116
118
|
const envLockfile = await readEnvLockfile(opts.rootDir);
|
|
117
119
|
if (envLockfile) {
|
|
120
|
+
verifyEnvLockfile(envLockfile);
|
|
118
121
|
return normalizeFromLockfile(envLockfile, opts.registries);
|
|
119
122
|
}
|
|
120
123
|
// No env lockfile yet — migrate from old inline integrity format
|
package/lib/migrateConfigDeps.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
2
2
|
import { writeSettings } from '@pnpm/config.writer';
|
|
3
3
|
import { PnpmError } from '@pnpm/error';
|
|
4
|
-
import { createEnvLockfile
|
|
4
|
+
import { createEnvLockfile } from '@pnpm/lockfile.fs';
|
|
5
5
|
import { toLockfileResolution } from '@pnpm/lockfile.utils';
|
|
6
6
|
import getNpmTarballUrl from 'get-npm-tarball-url';
|
|
7
7
|
import { parseIntegrity } from './parseIntegrity.js';
|
|
8
|
+
import { writeVerifiedEnvLockfile } from './writeVerifiedEnvLockfile.js';
|
|
8
9
|
/**
|
|
9
10
|
* Migrates old-format configDependencies (with inline integrity in pnpm-workspace.yaml)
|
|
10
11
|
* to the new pnpm-lock.yaml format.
|
|
@@ -14,6 +15,9 @@ import { parseIntegrity } from './parseIntegrity.js';
|
|
|
14
15
|
*/
|
|
15
16
|
export async function migrateConfigDepsToLockfile(configDeps, opts) {
|
|
16
17
|
const envLockfile = createEnvLockfile();
|
|
18
|
+
// Null-prototype so a `__proto__` name lands as an own key verifyEnvLockfile
|
|
19
|
+
// sees, not a silent prototype mutation.
|
|
20
|
+
envLockfile.importers['.'].configDependencies = Object.create(null);
|
|
17
21
|
const cleanSpecifiers = {};
|
|
18
22
|
const normalizedDeps = {};
|
|
19
23
|
for (const [pkgName, pkgSpec] of Object.entries(configDeps)) {
|
|
@@ -64,17 +68,14 @@ export async function migrateConfigDepsToLockfile(configDeps, opts) {
|
|
|
64
68
|
};
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
|
-
|
|
68
|
-
await
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
},
|
|
76
|
-
}),
|
|
77
|
-
]);
|
|
71
|
+
await writeVerifiedEnvLockfile(opts.rootDir, envLockfile);
|
|
72
|
+
await writeSettings({
|
|
73
|
+
rootProjectManifestDir: opts.rootDir,
|
|
74
|
+
workspaceDir: opts.rootDir,
|
|
75
|
+
updatedSettings: {
|
|
76
|
+
configDependencies: cleanSpecifiers,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
78
79
|
return normalizedDeps;
|
|
79
80
|
}
|
|
80
81
|
//# sourceMappingURL=migrateConfigDeps.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
2
2
|
import { PnpmError } from '@pnpm/error';
|
|
3
|
-
import { createEnvLockfile, readEnvLockfile,
|
|
3
|
+
import { createEnvLockfile, readEnvLockfile, } from '@pnpm/lockfile.fs';
|
|
4
4
|
import { toLockfileResolution } from '@pnpm/lockfile.utils';
|
|
5
5
|
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
6
6
|
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
@@ -10,6 +10,7 @@ import { installConfigDeps } from './installConfigDeps.js';
|
|
|
10
10
|
import { parseIntegrity } from './parseIntegrity.js';
|
|
11
11
|
import { pruneEnvLockfile } from './pruneEnvLockfile.js';
|
|
12
12
|
import { resolveOptionalSubdeps } from './resolveOptionalSubdeps.js';
|
|
13
|
+
import { writeVerifiedEnvLockfile } from './writeVerifiedEnvLockfile.js';
|
|
13
14
|
/**
|
|
14
15
|
* Resolves any config dependencies that are missing from the env lockfile,
|
|
15
16
|
* then installs all config dependencies.
|
|
@@ -71,7 +72,7 @@ export async function resolveAndInstallConfigDeps(configDeps, opts) {
|
|
|
71
72
|
}
|
|
72
73
|
if (depsToResolve.length === 0) {
|
|
73
74
|
if (lockfileChanged) {
|
|
74
|
-
await
|
|
75
|
+
await writeVerifiedEnvLockfile(opts.rootDir, envLockfile);
|
|
75
76
|
}
|
|
76
77
|
await installConfigDeps(envLockfile, opts);
|
|
77
78
|
return;
|
|
@@ -111,7 +112,7 @@ export async function resolveAndInstallConfigDeps(configDeps, opts) {
|
|
|
111
112
|
envLockfile.snapshots[pkgKey] = optionalSubdeps ? { optionalDependencies: optionalSubdeps } : {};
|
|
112
113
|
}));
|
|
113
114
|
pruneEnvLockfile(envLockfile);
|
|
114
|
-
await
|
|
115
|
+
await writeVerifiedEnvLockfile(opts.rootDir, envLockfile);
|
|
115
116
|
await installConfigDeps(envLockfile, opts);
|
|
116
117
|
}
|
|
117
118
|
//# sourceMappingURL=resolveAndInstallConfigDeps.js.map
|
package/lib/resolveConfigDeps.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
2
2
|
import { writeSettings } from '@pnpm/config.writer';
|
|
3
3
|
import { PnpmError } from '@pnpm/error';
|
|
4
|
-
import { createEnvLockfile, readEnvLockfile,
|
|
4
|
+
import { createEnvLockfile, readEnvLockfile, } from '@pnpm/lockfile.fs';
|
|
5
5
|
import { toLockfileResolution } from '@pnpm/lockfile.utils';
|
|
6
6
|
import { createGetAuthHeaderByURI } from '@pnpm/network.auth-header';
|
|
7
7
|
import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
@@ -10,6 +10,7 @@ import { parseWantedDependency } from '@pnpm/resolving.parse-wanted-dependency';
|
|
|
10
10
|
import { installConfigDeps } from './installConfigDeps.js';
|
|
11
11
|
import { pruneEnvLockfile } from './pruneEnvLockfile.js';
|
|
12
12
|
import { resolveOptionalSubdeps } from './resolveOptionalSubdeps.js';
|
|
13
|
+
import { writeVerifiedEnvLockfile } from './writeVerifiedEnvLockfile.js';
|
|
13
14
|
export async function resolveConfigDeps(configDeps, opts) {
|
|
14
15
|
if (opts.frozenLockfile) {
|
|
15
16
|
throw new PnpmError('FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE', 'Cannot resolve configDependencies with "frozen-lockfile" because the lockfile is not up to date');
|
|
@@ -56,17 +57,15 @@ export async function resolveConfigDeps(configDeps, opts) {
|
|
|
56
57
|
envLockfile.snapshots[pkgKey] = optionalSubdeps ? { optionalDependencies: optionalSubdeps } : {};
|
|
57
58
|
}));
|
|
58
59
|
pruneEnvLockfile(envLockfile);
|
|
59
|
-
await
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
writeEnvLockfile(opts.rootDir, envLockfile),
|
|
69
|
-
]);
|
|
60
|
+
await writeVerifiedEnvLockfile(opts.rootDir, envLockfile);
|
|
61
|
+
await writeSettings({
|
|
62
|
+
...opts,
|
|
63
|
+
rootProjectManifestDir: opts.rootDir,
|
|
64
|
+
workspaceDir: opts.rootDir,
|
|
65
|
+
updatedSettings: {
|
|
66
|
+
configDependencies: configDependencySpecifiers,
|
|
67
|
+
},
|
|
68
|
+
});
|
|
70
69
|
await installConfigDeps(envLockfile, opts);
|
|
71
70
|
}
|
|
72
71
|
/**
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { convertToLockfileFile, createEnvLockfile, readEnvLockfile
|
|
1
|
+
import { convertToLockfileFile, createEnvLockfile, readEnvLockfile } from '@pnpm/lockfile.fs';
|
|
2
2
|
import { pruneSharedLockfile } from '@pnpm/lockfile.pruner';
|
|
3
3
|
import { convertToLockfileEnvObject } from './pruneEnvLockfile.js';
|
|
4
4
|
import { resolveManifestDependencies } from './resolveManifestDependencies.js';
|
|
5
|
+
import { writeVerifiedEnvLockfile } from './writeVerifiedEnvLockfile.js';
|
|
5
6
|
/**
|
|
6
7
|
* Checks if the wanted pnpm version integrities are already fully resolved in the env lockfile.
|
|
7
8
|
*/
|
|
@@ -58,7 +59,7 @@ export async function resolvePackageManagerIntegrities(pnpmVersion, opts) {
|
|
|
58
59
|
envLockfile.packages = prunedFile.packages ?? {};
|
|
59
60
|
envLockfile.snapshots = prunedFile.snapshots ?? {};
|
|
60
61
|
if (save) {
|
|
61
|
-
await
|
|
62
|
+
await writeVerifiedEnvLockfile(opts.rootDir, envLockfile);
|
|
62
63
|
}
|
|
63
64
|
}
|
|
64
65
|
return envLockfile;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { assertValidDependencyAliases } from '@pnpm/installing.deps-resolver';
|
|
2
|
+
import { assertValidConfigDepVersion } from './assertValidConfigDepVersion.js';
|
|
3
|
+
// Offline structural gate for the env lockfile, mirroring the alias/shape
|
|
4
|
+
// checks `verifyLockfileResolutions` runs over the main lockfile. Config
|
|
5
|
+
// dependency and optional-subdependency names and versions become store path
|
|
6
|
+
// segments, so reject any that isn't a valid npm name / exact semver before a
|
|
7
|
+
// path is built from them.
|
|
8
|
+
export function verifyEnvLockfile(envLockfile) {
|
|
9
|
+
const configDeps = envLockfile.importers['.']?.configDependencies;
|
|
10
|
+
assertValidDependencyAliases(configDeps, 'The configDependencies in pnpm-lock.yaml');
|
|
11
|
+
if (configDeps == null)
|
|
12
|
+
return;
|
|
13
|
+
for (const [name, { version }] of Object.entries(configDeps)) {
|
|
14
|
+
assertValidConfigDepVersion(name, version);
|
|
15
|
+
const optionalDeps = envLockfile.snapshots[`${name}@${version}`]?.optionalDependencies;
|
|
16
|
+
if (optionalDeps == null)
|
|
17
|
+
continue;
|
|
18
|
+
assertValidDependencyAliases(optionalDeps, `The optionalDependencies of config dependency "${name}" in pnpm-lock.yaml`);
|
|
19
|
+
for (const [subdepName, subdepVersion] of Object.entries(optionalDeps)) {
|
|
20
|
+
assertValidConfigDepVersion(subdepName, subdepVersion);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=verifyEnvLockfile.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { writeEnvLockfile } from '@pnpm/lockfile.fs';
|
|
2
|
+
import { verifyEnvLockfile } from './verifyEnvLockfile.js';
|
|
3
|
+
// Persist an env lockfile only after verifying it, so no code path can write
|
|
4
|
+
// one carrying an invalid config-dependency name or version.
|
|
5
|
+
export async function writeVerifiedEnvLockfile(rootDir, envLockfile) {
|
|
6
|
+
verifyEnvLockfile(envLockfile);
|
|
7
|
+
await writeEnvLockfile(rootDir, envLockfile);
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=writeVerifiedEnvLockfile.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/installing.env-installer",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1102.0.1",
|
|
4
4
|
"description": "Installer for configurational dependencies",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -30,43 +30,43 @@
|
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"@zkochan/rimraf": "^4.0.0",
|
|
32
32
|
"get-npm-tarball-url": "^2.1.0",
|
|
33
|
-
"semver": "^7.8.
|
|
33
|
+
"semver": "^7.8.4",
|
|
34
34
|
"symlink-dir": "^10.0.1",
|
|
35
|
+
"@pnpm/config.package-is-installable": "1100.0.11",
|
|
36
|
+
"@pnpm/config.writer": "1100.0.13",
|
|
35
37
|
"@pnpm/constants": "1100.0.0",
|
|
36
|
-
"@pnpm/
|
|
37
|
-
"@pnpm/
|
|
38
|
-
"@pnpm/error": "1100.0.0",
|
|
39
|
-
"@pnpm/installing.deps-resolver": "1100.2.2",
|
|
38
|
+
"@pnpm/core-loggers": "1100.2.1",
|
|
39
|
+
"@pnpm/deps.graph-hasher": "1100.2.5",
|
|
40
40
|
"@pnpm/fs.read-modules-dir": "1100.0.1",
|
|
41
|
-
"@pnpm/
|
|
42
|
-
"@pnpm/
|
|
43
|
-
"@pnpm/
|
|
44
|
-
"@pnpm/lockfile.utils": "1100.0.
|
|
45
|
-
"@pnpm/lockfile.
|
|
46
|
-
"@pnpm/
|
|
47
|
-
"@pnpm/
|
|
41
|
+
"@pnpm/installing.deps-resolver": "1100.2.4",
|
|
42
|
+
"@pnpm/lockfile.fs": "1100.1.6",
|
|
43
|
+
"@pnpm/lockfile.pruner": "1100.0.11",
|
|
44
|
+
"@pnpm/lockfile.utils": "1100.0.13",
|
|
45
|
+
"@pnpm/lockfile.types": "1100.0.11",
|
|
46
|
+
"@pnpm/network.auth-header": "1101.1.2",
|
|
47
|
+
"@pnpm/pkg-manifest.reader": "1100.0.8",
|
|
48
|
+
"@pnpm/resolving.npm-resolver": "1102.0.1",
|
|
49
|
+
"@pnpm/network.fetch": "1100.1.3",
|
|
48
50
|
"@pnpm/resolving.parse-wanted-dependency": "1100.0.1",
|
|
49
|
-
"@pnpm/
|
|
50
|
-
"@pnpm/
|
|
51
|
-
"@pnpm/
|
|
52
|
-
"@pnpm/
|
|
53
|
-
"@pnpm/
|
|
54
|
-
"@pnpm/deps.graph-hasher": "1100.2.4",
|
|
55
|
-
"@pnpm/resolving.npm-resolver": "1101.5.2"
|
|
51
|
+
"@pnpm/store.controller-types": "1100.1.5",
|
|
52
|
+
"@pnpm/types": "1101.3.2",
|
|
53
|
+
"@pnpm/store.controller": "1102.0.1",
|
|
54
|
+
"@pnpm/error": "1100.0.0",
|
|
55
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.9"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@pnpm/logger": "^
|
|
59
|
-
"@pnpm/worker": "^1100.1
|
|
58
|
+
"@pnpm/logger": "^1100.0.0",
|
|
59
|
+
"@pnpm/worker": "^1100.2.1"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
-
"@jest/globals": "30.
|
|
62
|
+
"@jest/globals": "30.4.1",
|
|
63
63
|
"@types/semver": "7.7.1",
|
|
64
64
|
"load-json-file": "^7.0.1",
|
|
65
65
|
"read-yaml-file": "^3.0.0",
|
|
66
|
-
"@pnpm/installing.env-installer": "
|
|
67
|
-
"@pnpm/prepare": "1100.0.
|
|
68
|
-
"@pnpm/testing.temp-store": "1100.1.
|
|
69
|
-
"@pnpm/testing.registry-mock": "1100.0.
|
|
66
|
+
"@pnpm/installing.env-installer": "1102.0.1",
|
|
67
|
+
"@pnpm/prepare": "1100.0.16",
|
|
68
|
+
"@pnpm/testing.temp-store": "1100.1.10",
|
|
69
|
+
"@pnpm/testing.registry-mock": "1100.0.6"
|
|
70
70
|
},
|
|
71
71
|
"engines": {
|
|
72
72
|
"node": ">=22.13"
|