@pnpm/installing.env-installer 1101.0.10 → 1101.1.0
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/installConfigDeps.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
+
import { checkPackage } from '@pnpm/config.package-is-installable';
|
|
3
4
|
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
4
|
-
import { installingConfigDepsLogger } from '@pnpm/core-loggers';
|
|
5
|
-
import { calcLeafGlobalVirtualStorePath } from '@pnpm/deps.graph-hasher';
|
|
5
|
+
import { installingConfigDepsLogger, skippedOptionalDependencyLogger } from '@pnpm/core-loggers';
|
|
6
|
+
import { calcGlobalVirtualStorePathWithSubdeps, calcLeafGlobalVirtualStorePath } from '@pnpm/deps.graph-hasher';
|
|
6
7
|
import { PnpmError } from '@pnpm/error';
|
|
7
8
|
import { readModulesDir } from '@pnpm/fs.read-modules-dir';
|
|
8
9
|
import { readEnvLockfile } from '@pnpm/lockfile.fs';
|
|
9
|
-
import { safeReadPackageJsonFromDir } from '@pnpm/pkg-manifest.reader';
|
|
10
10
|
import { rimraf } from '@zkochan/rimraf';
|
|
11
11
|
import getNpmTarballUrl from 'get-npm-tarball-url';
|
|
12
12
|
import { symlinkDir } from 'symlink-dir';
|
|
@@ -29,16 +29,27 @@ export async function installConfigDeps(configDepsOrLockfile, opts) {
|
|
|
29
29
|
const installedConfigDeps = [];
|
|
30
30
|
await Promise.all(Object.entries(normalizedDeps).map(async ([pkgName, pkg]) => {
|
|
31
31
|
const configDepPath = path.join(configModulesDir, pkgName);
|
|
32
|
-
const existingPkgJson = existingConfigDeps.includes(pkgName)
|
|
33
|
-
? await safeReadPackageJsonFromDir(configDepPath)
|
|
34
|
-
: null;
|
|
35
|
-
if (existingPkgJson != null && existingPkgJson.name === pkgName && existingPkgJson.version === pkg.version) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
installingConfigDepsLogger.debug({ status: 'started' });
|
|
39
32
|
const fullPkgId = `${pkgName}@${pkg.version}:${pkg.resolution.integrity}`;
|
|
40
|
-
|
|
33
|
+
// The parent's GVS hash must incorporate its optional subdeps; otherwise
|
|
34
|
+
// changing a subdep version while keeping the parent pinned would collide
|
|
35
|
+
// on the same leaf and silently overwrite the previous sibling symlinks.
|
|
36
|
+
const optionalSubdepIds = {};
|
|
37
|
+
for (const subdep of pkg.optionalSubdeps ?? []) {
|
|
38
|
+
optionalSubdepIds[subdep.name] = `${subdep.name}@${subdep.version}:${subdep.resolution.integrity}`;
|
|
39
|
+
}
|
|
40
|
+
const relPath = calcGlobalVirtualStorePathWithSubdeps(fullPkgId, pkgName, pkg.version, optionalSubdepIds);
|
|
41
41
|
const pkgDirInGlobalVirtualStore = path.join(globalVirtualStoreDir, relPath, 'node_modules', pkgName);
|
|
42
|
+
// The leaf hash captures parent+subdep identities from the lockfile but
|
|
43
|
+
// not the host's `process.arch`/`process.platform` selection. So even if
|
|
44
|
+
// the symlink target is already the expected leaf, the sibling links
|
|
45
|
+
// inside that leaf may target the wrong platform binary if the host's
|
|
46
|
+
// effective arch changed between runs (e.g. Rosetta x64 vs arm64 on
|
|
47
|
+
// macOS). Short-circuit only the parent's re-import/re-symlink in that
|
|
48
|
+
// case; always run installOptionalSubdeps so platform-specific siblings
|
|
49
|
+
// get pruned and relinked.
|
|
50
|
+
const parentSymlinkAlreadyCorrect = existingConfigDeps.includes(pkgName) &&
|
|
51
|
+
await symlinkPointsTo(configDepPath, pkgDirInGlobalVirtualStore);
|
|
52
|
+
installingConfigDepsLogger.debug({ status: 'started' });
|
|
42
53
|
if (!fs.existsSync(path.join(pkgDirInGlobalVirtualStore, 'package.json'))) {
|
|
43
54
|
const { fetching } = await opts.store.fetchPackage({
|
|
44
55
|
force: true,
|
|
@@ -55,6 +66,22 @@ export async function installConfigDeps(configDepsOrLockfile, opts) {
|
|
|
55
66
|
filesResponse,
|
|
56
67
|
});
|
|
57
68
|
}
|
|
69
|
+
if (pkg.optionalSubdeps?.length) {
|
|
70
|
+
await installOptionalSubdeps({
|
|
71
|
+
parentName: pkgName,
|
|
72
|
+
parentVersion: pkg.version,
|
|
73
|
+
subdeps: pkg.optionalSubdeps,
|
|
74
|
+
// path.dirname would land in the scope subdir for scoped parents; use
|
|
75
|
+
// the leaf's node_modules root so sibling symlinks resolve correctly.
|
|
76
|
+
parentNodeModulesDir: path.join(globalVirtualStoreDir, relPath, 'node_modules'),
|
|
77
|
+
globalVirtualStoreDir,
|
|
78
|
+
rootDir: opts.rootDir,
|
|
79
|
+
store: opts.store,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
if (parentSymlinkAlreadyCorrect) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
58
85
|
if (existingConfigDeps.includes(pkgName)) {
|
|
59
86
|
await rimraf(configDepPath);
|
|
60
87
|
}
|
|
@@ -113,14 +140,114 @@ function normalizeFromLockfile(lockfile, registries) {
|
|
|
113
140
|
throw new PnpmError('ENV_LOCKFILE_CORRUPTED', `pnpm-lock.yaml is corrupted or incomplete: missing integrity for "${pkgKey}"`);
|
|
114
141
|
}
|
|
115
142
|
const registry = pickRegistryForPackage(registries, pkgName);
|
|
143
|
+
const snapshot = lockfile.snapshots[pkgKey];
|
|
144
|
+
const optionalSubdeps = snapshot?.optionalDependencies
|
|
145
|
+
? readOptionalSubdepsFromLockfile(pkgName, snapshot.optionalDependencies, lockfile, registries)
|
|
146
|
+
: undefined;
|
|
116
147
|
deps[pkgName] = {
|
|
117
148
|
version,
|
|
118
149
|
resolution: {
|
|
119
150
|
integrity: resolution.integrity,
|
|
120
151
|
tarball: resolution.tarball ?? getNpmTarballUrl(pkgName, version, { registry }),
|
|
121
152
|
},
|
|
153
|
+
optionalSubdeps,
|
|
122
154
|
};
|
|
123
155
|
}
|
|
124
156
|
return deps;
|
|
125
157
|
}
|
|
158
|
+
function readOptionalSubdepsFromLockfile(parentName, optionalDeps, lockfile, registries) {
|
|
159
|
+
const subdeps = [];
|
|
160
|
+
for (const [subdepName, subdepVersion] of Object.entries(optionalDeps)) {
|
|
161
|
+
const subdepKey = `${subdepName}@${subdepVersion}`;
|
|
162
|
+
const subdepInfo = lockfile.packages[subdepKey];
|
|
163
|
+
if (!subdepInfo) {
|
|
164
|
+
throw new PnpmError('ENV_LOCKFILE_CORRUPTED', `pnpm-lock.yaml is corrupted or incomplete: missing packages entry for "${subdepKey}" ` +
|
|
165
|
+
`referenced from optionalDependencies of config dependency "${parentName}"`);
|
|
166
|
+
}
|
|
167
|
+
const subdepResolution = subdepInfo.resolution;
|
|
168
|
+
if (!subdepResolution.integrity) {
|
|
169
|
+
throw new PnpmError('ENV_LOCKFILE_CORRUPTED', `pnpm-lock.yaml is corrupted or incomplete: missing integrity for "${subdepKey}"`);
|
|
170
|
+
}
|
|
171
|
+
const registry = pickRegistryForPackage(registries, subdepName);
|
|
172
|
+
subdeps.push({
|
|
173
|
+
name: subdepName,
|
|
174
|
+
version: subdepVersion,
|
|
175
|
+
resolution: {
|
|
176
|
+
integrity: subdepResolution.integrity,
|
|
177
|
+
tarball: subdepResolution.tarball ?? getNpmTarballUrl(subdepName, subdepVersion, { registry }),
|
|
178
|
+
},
|
|
179
|
+
os: subdepInfo.os,
|
|
180
|
+
cpu: subdepInfo.cpu,
|
|
181
|
+
libc: subdepInfo.libc,
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
return subdeps;
|
|
185
|
+
}
|
|
186
|
+
async function installOptionalSubdeps(opts) {
|
|
187
|
+
const parentLogInfo = { id: `${opts.parentName}@${opts.parentVersion}`, name: opts.parentName, version: opts.parentVersion };
|
|
188
|
+
const compatibleSubdeps = opts.subdeps.filter((subdep) => {
|
|
189
|
+
if (!subdep.os && !subdep.cpu && !subdep.libc)
|
|
190
|
+
return true;
|
|
191
|
+
// Use checkPackage rather than packageIsInstallable: the latter emits a
|
|
192
|
+
// user-visible warn for every incompatible variant, which would fire on
|
|
193
|
+
// every install since the env lockfile records all platform variants for
|
|
194
|
+
// portability. We log skipped subdeps at debug instead.
|
|
195
|
+
const error = checkPackage(`${subdep.name}@${subdep.version}`, { os: subdep.os, cpu: subdep.cpu, libc: subdep.libc }, {});
|
|
196
|
+
if (error == null)
|
|
197
|
+
return true;
|
|
198
|
+
skippedOptionalDependencyLogger.debug({
|
|
199
|
+
details: error.toString(),
|
|
200
|
+
package: { id: `${subdep.name}@${subdep.version}`, name: subdep.name, version: subdep.version },
|
|
201
|
+
parents: [parentLogInfo],
|
|
202
|
+
prefix: opts.rootDir,
|
|
203
|
+
reason: error.code === 'ERR_PNPM_UNSUPPORTED_ENGINE' ? 'unsupported_engine' : 'unsupported_platform',
|
|
204
|
+
});
|
|
205
|
+
return false;
|
|
206
|
+
});
|
|
207
|
+
const expectedSiblings = new Set([opts.parentName, ...compatibleSubdeps.map((s) => s.name)]);
|
|
208
|
+
const existingSiblings = await readModulesDir(opts.parentNodeModulesDir) ?? [];
|
|
209
|
+
await Promise.all(existingSiblings
|
|
210
|
+
.filter((name) => !expectedSiblings.has(name))
|
|
211
|
+
.map((name) => rimraf(path.join(opts.parentNodeModulesDir, name))));
|
|
212
|
+
await Promise.all(compatibleSubdeps.map(async (subdep) => {
|
|
213
|
+
const subdepFullPkgId = `${subdep.name}@${subdep.version}:${subdep.resolution.integrity}`;
|
|
214
|
+
const subdepRelPath = calcLeafGlobalVirtualStorePath(subdepFullPkgId, subdep.name, subdep.version);
|
|
215
|
+
const subdepDirInGlobalVirtualStore = path.join(opts.globalVirtualStoreDir, subdepRelPath, 'node_modules', subdep.name);
|
|
216
|
+
if (!fs.existsSync(path.join(subdepDirInGlobalVirtualStore, 'package.json'))) {
|
|
217
|
+
const { fetching } = await opts.store.fetchPackage({
|
|
218
|
+
force: true,
|
|
219
|
+
lockfileDir: opts.rootDir,
|
|
220
|
+
pkg: {
|
|
221
|
+
id: `${subdep.name}@${subdep.version}`,
|
|
222
|
+
resolution: subdep.resolution,
|
|
223
|
+
},
|
|
224
|
+
});
|
|
225
|
+
const { files: filesResponse } = await fetching();
|
|
226
|
+
await opts.store.importPackage(subdepDirInGlobalVirtualStore, {
|
|
227
|
+
force: true,
|
|
228
|
+
requiresBuild: false,
|
|
229
|
+
filesResponse,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
const linkPath = path.join(opts.parentNodeModulesDir, subdep.name);
|
|
233
|
+
await fs.promises.mkdir(path.dirname(linkPath), { recursive: true });
|
|
234
|
+
await symlinkDir(subdepDirInGlobalVirtualStore, linkPath);
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
async function symlinkPointsTo(linkPath, expectedTarget) {
|
|
238
|
+
try {
|
|
239
|
+
// Realpath both sides: the expected target itself may live under a
|
|
240
|
+
// symlinked storeDir, and on case-insensitive filesystems the literal
|
|
241
|
+
// string forms can disagree about casing even when they refer to the
|
|
242
|
+
// same inode.
|
|
243
|
+
const [linkReal, targetReal] = await Promise.all([
|
|
244
|
+
fs.promises.realpath(linkPath),
|
|
245
|
+
fs.promises.realpath(expectedTarget),
|
|
246
|
+
]);
|
|
247
|
+
return linkReal === targetReal;
|
|
248
|
+
}
|
|
249
|
+
catch {
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
126
253
|
//# sourceMappingURL=installConfigDeps.js.map
|
package/lib/parseIntegrity.d.ts
CHANGED
|
@@ -4,6 +4,18 @@ export interface NormalizedConfigDep {
|
|
|
4
4
|
integrity: string;
|
|
5
5
|
tarball: string;
|
|
6
6
|
};
|
|
7
|
+
optionalSubdeps?: NormalizedSubdep[];
|
|
8
|
+
}
|
|
9
|
+
export interface NormalizedSubdep {
|
|
10
|
+
name: string;
|
|
11
|
+
version: string;
|
|
12
|
+
resolution: {
|
|
13
|
+
integrity: string;
|
|
14
|
+
tarball: string;
|
|
15
|
+
};
|
|
16
|
+
os?: string[];
|
|
17
|
+
cpu?: string[];
|
|
18
|
+
libc?: string[];
|
|
7
19
|
}
|
|
8
20
|
export declare function parseIntegrity(pkgName: string, pkgSpec: string): {
|
|
9
21
|
version: string;
|
|
@@ -9,6 +9,7 @@ import getNpmTarballUrl from 'get-npm-tarball-url';
|
|
|
9
9
|
import { installConfigDeps } from './installConfigDeps.js';
|
|
10
10
|
import { parseIntegrity } from './parseIntegrity.js';
|
|
11
11
|
import { pruneEnvLockfile } from './pruneEnvLockfile.js';
|
|
12
|
+
import { resolveOptionalSubdeps } from './resolveOptionalSubdeps.js';
|
|
12
13
|
/**
|
|
13
14
|
* Resolves any config dependencies that are missing from the env lockfile,
|
|
14
15
|
* then installs all config dependencies.
|
|
@@ -101,7 +102,13 @@ export async function resolveAndInstallConfigDeps(configDeps, opts) {
|
|
|
101
102
|
envLockfile.packages[pkgKey] = {
|
|
102
103
|
resolution: toLockfileResolution({ name, version }, resolution.resolution, registry),
|
|
103
104
|
};
|
|
104
|
-
|
|
105
|
+
const optionalSubdeps = await resolveOptionalSubdeps(name, resolution.manifest, {
|
|
106
|
+
envLockfile,
|
|
107
|
+
lockfileDir: opts.rootDir,
|
|
108
|
+
registries: opts.registries,
|
|
109
|
+
resolveFromNpm,
|
|
110
|
+
});
|
|
111
|
+
envLockfile.snapshots[pkgKey] = optionalSubdeps ? { optionalDependencies: optionalSubdeps } : {};
|
|
105
112
|
}));
|
|
106
113
|
pruneEnvLockfile(envLockfile);
|
|
107
114
|
await writeEnvLockfile(opts.rootDir, envLockfile);
|
package/lib/resolveConfigDeps.js
CHANGED
|
@@ -8,6 +8,7 @@ import { createFetchFromRegistry } from '@pnpm/network.fetch';
|
|
|
8
8
|
import { createNpmResolver } from '@pnpm/resolving.npm-resolver';
|
|
9
9
|
import { parseWantedDependency } from '@pnpm/resolving.parse-wanted-dependency';
|
|
10
10
|
import { installConfigDeps } from './installConfigDeps.js';
|
|
11
|
+
import { resolveOptionalSubdeps } from './resolveOptionalSubdeps.js';
|
|
11
12
|
export async function resolveConfigDeps(configDeps, opts) {
|
|
12
13
|
if (opts.frozenLockfile) {
|
|
13
14
|
throw new PnpmError('FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE', 'Cannot resolve configDependencies with "frozen-lockfile" because the lockfile is not up to date');
|
|
@@ -45,7 +46,13 @@ export async function resolveConfigDeps(configDeps, opts) {
|
|
|
45
46
|
envLockfile.packages[pkgKey] = {
|
|
46
47
|
resolution: toLockfileResolution({ name: pkgName, version }, resolution.resolution, registry),
|
|
47
48
|
};
|
|
48
|
-
|
|
49
|
+
const optionalSubdeps = await resolveOptionalSubdeps(pkgName, resolution.manifest, {
|
|
50
|
+
envLockfile,
|
|
51
|
+
lockfileDir: opts.rootDir,
|
|
52
|
+
registries: opts.registries,
|
|
53
|
+
resolveFromNpm,
|
|
54
|
+
});
|
|
55
|
+
envLockfile.snapshots[pkgKey] = optionalSubdeps ? { optionalDependencies: optionalSubdeps } : {};
|
|
49
56
|
}));
|
|
50
57
|
await Promise.all([
|
|
51
58
|
writeSettings({
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EnvLockfile } from '@pnpm/lockfile.fs';
|
|
2
|
+
import type { ResolvedDependencies } from '@pnpm/lockfile.types';
|
|
3
|
+
import type { createNpmResolver } from '@pnpm/resolving.npm-resolver';
|
|
4
|
+
import type { DependencyManifest, Registries } from '@pnpm/types';
|
|
5
|
+
type ResolveFromNpm = ReturnType<typeof createNpmResolver>['resolveFromNpm'];
|
|
6
|
+
export interface ResolveOptionalSubdepsOpts {
|
|
7
|
+
envLockfile: EnvLockfile;
|
|
8
|
+
lockfileDir: string;
|
|
9
|
+
registries: Registries;
|
|
10
|
+
resolveFromNpm: ResolveFromNpm;
|
|
11
|
+
}
|
|
12
|
+
export declare function resolveOptionalSubdeps(parentName: string, parentManifest: DependencyManifest, opts: ResolveOptionalSubdepsOpts): Promise<ResolvedDependencies | undefined>;
|
|
13
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import util from 'node:util';
|
|
2
|
+
import { pickRegistryForPackage } from '@pnpm/config.pick-registry-for-package';
|
|
3
|
+
import { skippedOptionalDependencyLogger } from '@pnpm/core-loggers';
|
|
4
|
+
import { PnpmError } from '@pnpm/error';
|
|
5
|
+
import { toLockfileResolution } from '@pnpm/lockfile.utils';
|
|
6
|
+
import semver from 'semver';
|
|
7
|
+
export async function resolveOptionalSubdeps(parentName, parentManifest, opts) {
|
|
8
|
+
const optionalDeps = parentManifest.optionalDependencies;
|
|
9
|
+
if (!optionalDeps || Object.keys(optionalDeps).length === 0) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
const resolved = {};
|
|
13
|
+
await Promise.all(Object.entries(optionalDeps).map(async ([subdepName, subdepSpec]) => {
|
|
14
|
+
if (semver.valid(subdepSpec) == null) {
|
|
15
|
+
// Ranges and tags would let the resolved version drift between machines
|
|
16
|
+
// even with a stable parent integrity, breaking the lockfile's promise
|
|
17
|
+
// of reproducible config-dep installs.
|
|
18
|
+
throw new PnpmError('CONFIG_DEP_OPTIONAL_NOT_EXACT', `Cannot install "${subdepName}@${subdepSpec}" as an optionalDependency of config dependency "${parentName}": only exact versions are supported (got "${subdepSpec}")`);
|
|
19
|
+
}
|
|
20
|
+
let resolution;
|
|
21
|
+
try {
|
|
22
|
+
// `optional: true` opts into full registry metadata so the resolver
|
|
23
|
+
// returns `libc` (and any other fields the abbreviated metadata strips).
|
|
24
|
+
// See pnpm/pnpm#9950.
|
|
25
|
+
resolution = await opts.resolveFromNpm({ alias: subdepName, bareSpecifier: subdepSpec, optional: true }, {
|
|
26
|
+
lockfileDir: opts.lockfileDir,
|
|
27
|
+
preferredVersions: {},
|
|
28
|
+
projectDir: opts.lockfileDir,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
// Trust-downgrade is a security signal that must fail the install even
|
|
33
|
+
// for optional deps; everything else mirrors npm's optionalDependencies
|
|
34
|
+
// semantics — log and skip.
|
|
35
|
+
if (util.types.isNativeError(err) && 'code' in err && err.code === 'ERR_PNPM_TRUST_DOWNGRADE') {
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
skippedOptionalDependencyLogger.debug({
|
|
39
|
+
details: util.types.isNativeError(err) ? err.toString() : String(err),
|
|
40
|
+
package: {
|
|
41
|
+
name: subdepName,
|
|
42
|
+
// No resolved version yet; surface the requested specifier so log
|
|
43
|
+
// consumers that format `${name}@${version}` don't render `@undefined`.
|
|
44
|
+
version: subdepSpec,
|
|
45
|
+
bareSpecifier: subdepSpec,
|
|
46
|
+
},
|
|
47
|
+
parents: [{ id: `${parentName}@${parentManifest.version}`, name: parentName, version: parentManifest.version }],
|
|
48
|
+
prefix: opts.lockfileDir,
|
|
49
|
+
reason: 'resolution_failure',
|
|
50
|
+
});
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (resolution?.resolution == null ||
|
|
54
|
+
!('integrity' in resolution.resolution) ||
|
|
55
|
+
typeof resolution.resolution.integrity !== 'string' ||
|
|
56
|
+
!resolution.resolution.integrity ||
|
|
57
|
+
resolution.manifest == null) {
|
|
58
|
+
throw new PnpmError('BAD_CONFIG_DEP', `Cannot resolve optionalDependency "${subdepName}" of config dependency "${parentName}" because it has no integrity`);
|
|
59
|
+
}
|
|
60
|
+
const subdepVersion = resolution.manifest.version;
|
|
61
|
+
const registry = pickRegistryForPackage(opts.registries, subdepName);
|
|
62
|
+
const subdepKey = `${subdepName}@${subdepVersion}`;
|
|
63
|
+
opts.envLockfile.packages[subdepKey] = {
|
|
64
|
+
resolution: toLockfileResolution({ name: subdepName, version: subdepVersion }, resolution.resolution, registry),
|
|
65
|
+
...pickPlatformFields(resolution.manifest),
|
|
66
|
+
};
|
|
67
|
+
if (opts.envLockfile.snapshots[subdepKey] == null) {
|
|
68
|
+
opts.envLockfile.snapshots[subdepKey] = {};
|
|
69
|
+
}
|
|
70
|
+
resolved[subdepName] = subdepVersion;
|
|
71
|
+
}));
|
|
72
|
+
return Object.keys(resolved).length > 0 ? resolved : undefined;
|
|
73
|
+
}
|
|
74
|
+
function pickPlatformFields(manifest) {
|
|
75
|
+
const out = {};
|
|
76
|
+
if (manifest.os?.length)
|
|
77
|
+
out.os = manifest.os;
|
|
78
|
+
if (manifest.cpu?.length)
|
|
79
|
+
out.cpu = manifest.cpu;
|
|
80
|
+
if (manifest.libc?.length)
|
|
81
|
+
out.libc = manifest.libc;
|
|
82
|
+
return out;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=resolveOptionalSubdeps.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/installing.env-installer",
|
|
3
|
-
"version": "1101.0
|
|
3
|
+
"version": "1101.1.0",
|
|
4
4
|
"description": "Installer for configurational dependencies",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -27,40 +27,43 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@zkochan/rimraf": "^4.0.0",
|
|
29
29
|
"get-npm-tarball-url": "^2.1.0",
|
|
30
|
+
"semver": "^7.7.2",
|
|
30
31
|
"symlink-dir": "^10.0.1",
|
|
31
|
-
"@pnpm/config.
|
|
32
|
+
"@pnpm/config.package-is-installable": "1100.0.6",
|
|
33
|
+
"@pnpm/config.writer": "1100.0.9",
|
|
34
|
+
"@pnpm/config.pick-registry-for-package": "1100.0.4",
|
|
32
35
|
"@pnpm/constants": "1100.0.0",
|
|
33
|
-
"@pnpm/
|
|
34
|
-
"@pnpm/config.writer": "1100.0.8",
|
|
35
|
-
"@pnpm/deps.graph-hasher": "1100.2.0",
|
|
36
|
+
"@pnpm/deps.graph-hasher": "1100.2.1",
|
|
36
37
|
"@pnpm/error": "1100.0.0",
|
|
38
|
+
"@pnpm/installing.deps-resolver": "1100.1.1",
|
|
37
39
|
"@pnpm/fs.read-modules-dir": "1100.0.1",
|
|
38
|
-
"@pnpm/
|
|
39
|
-
"@pnpm/lockfile.
|
|
40
|
-
"@pnpm/lockfile.
|
|
41
|
-
"@pnpm/lockfile.
|
|
42
|
-
"@pnpm/
|
|
43
|
-
"@pnpm/network.
|
|
44
|
-
"@pnpm/
|
|
45
|
-
"@pnpm/pkg-manifest.reader": "1100.0.3",
|
|
40
|
+
"@pnpm/lockfile.fs": "1100.1.1",
|
|
41
|
+
"@pnpm/lockfile.utils": "1100.0.9",
|
|
42
|
+
"@pnpm/lockfile.types": "1100.0.7",
|
|
43
|
+
"@pnpm/lockfile.pruner": "1100.0.7",
|
|
44
|
+
"@pnpm/network.auth-header": "1100.0.3",
|
|
45
|
+
"@pnpm/network.fetch": "1100.0.6",
|
|
46
|
+
"@pnpm/pkg-manifest.reader": "1100.0.4",
|
|
46
47
|
"@pnpm/resolving.parse-wanted-dependency": "1100.0.1",
|
|
47
|
-
"@pnpm/
|
|
48
|
-
"@pnpm/store.controller": "1101.0.
|
|
49
|
-
"@pnpm/
|
|
50
|
-
"@pnpm/
|
|
48
|
+
"@pnpm/store.controller-types": "1100.1.1",
|
|
49
|
+
"@pnpm/store.controller": "1101.0.8",
|
|
50
|
+
"@pnpm/types": "1101.1.1",
|
|
51
|
+
"@pnpm/resolving.npm-resolver": "1101.3.0",
|
|
52
|
+
"@pnpm/core-loggers": "1100.1.1"
|
|
51
53
|
},
|
|
52
54
|
"peerDependencies": {
|
|
53
55
|
"@pnpm/logger": ">=1001.0.0 <1002.0.0",
|
|
54
|
-
"@pnpm/worker": "^1100.1.
|
|
56
|
+
"@pnpm/worker": "^1100.1.7"
|
|
55
57
|
},
|
|
56
58
|
"devDependencies": {
|
|
57
59
|
"@jest/globals": "30.3.0",
|
|
58
60
|
"@pnpm/registry-mock": "6.0.0",
|
|
61
|
+
"@types/semver": "7.7.1",
|
|
59
62
|
"load-json-file": "^7.0.1",
|
|
60
63
|
"read-yaml-file": "^3.0.0",
|
|
61
|
-
"@pnpm/installing.env-installer": "1101.0
|
|
62
|
-
"@pnpm/prepare": "1100.0.
|
|
63
|
-
"@pnpm/testing.temp-store": "1100.1.
|
|
64
|
+
"@pnpm/installing.env-installer": "1101.1.0",
|
|
65
|
+
"@pnpm/prepare": "1100.0.10",
|
|
66
|
+
"@pnpm/testing.temp-store": "1100.1.1"
|
|
64
67
|
},
|
|
65
68
|
"engines": {
|
|
66
69
|
"node": ">=22.13"
|