@teambit/pnpm 1.0.1124 → 1.0.1125
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/.npmignore +18 -0
- package/dist/get-proxy-config.d.ts +2 -7
- package/dist/get-proxy-config.js +4 -7
- package/dist/get-proxy-config.js.map +1 -1
- package/dist/get-registries.d.ts +2 -2
- package/dist/get-registries.js +23 -93
- package/dist/get-registries.js.map +1 -1
- package/dist/load-pnpm-esm.cjs +19 -0
- package/dist/lockfile-deps-graph-converter.d.ts +17 -1
- package/dist/lockfile-deps-graph-converter.js +101 -32
- package/dist/lockfile-deps-graph-converter.js.map +1 -1
- package/dist/lockfile-deps-graph-converter.spec.js +200 -5
- package/dist/lockfile-deps-graph-converter.spec.js.map +1 -1
- package/dist/lynx.d.ts +53 -5
- package/dist/lynx.js +378 -322
- package/dist/lynx.js.map +1 -1
- package/dist/lynx.spec.d.ts +1 -0
- package/dist/lynx.spec.js +55 -0
- package/dist/lynx.spec.js.map +1 -0
- package/dist/pnpm-error-to-bit-error.d.ts +17 -2
- package/dist/pnpm-error-to-bit-error.js +7 -0
- package/dist/pnpm-error-to-bit-error.js.map +1 -1
- package/dist/pnpm-error-to-bit-error.spec.js +10 -11
- package/dist/pnpm-error-to-bit-error.spec.js.map +1 -1
- package/dist/pnpm-prune-modules.js +18 -8
- package/dist/pnpm-prune-modules.js.map +1 -1
- package/dist/pnpm.package-manager.d.ts +3 -4
- package/dist/pnpm.package-manager.js +168 -60
- package/dist/pnpm.package-manager.js.map +1 -1
- package/dist/pnpm.package-manager.spec.d.ts +1 -0
- package/dist/pnpm.package-manager.spec.js +48 -0
- package/dist/pnpm.package-manager.spec.js.map +1 -0
- package/dist/{preview-1785466791445.js → preview-1785493814568.js} +2 -2
- package/dist/read-config.d.ts +7 -1
- package/dist/read-config.js +22 -14
- package/dist/read-config.js.map +1 -1
- package/load-pnpm-esm.cjs +19 -0
- package/package.json +21 -33
package/dist/lynx.js
CHANGED
|
@@ -8,6 +8,21 @@ exports.generateResolverAndFetcher = generateResolverAndFetcher;
|
|
|
8
8
|
exports.getPeerDependencyIssues = getPeerDependencyIssues;
|
|
9
9
|
exports.install = install;
|
|
10
10
|
exports.resolveRemoteVersion = resolveRemoteVersion;
|
|
11
|
+
exports.resolveScriptPolicies = resolveScriptPolicies;
|
|
12
|
+
function _path() {
|
|
13
|
+
const data = require("path");
|
|
14
|
+
_path = function () {
|
|
15
|
+
return data;
|
|
16
|
+
};
|
|
17
|
+
return data;
|
|
18
|
+
}
|
|
19
|
+
function _fs() {
|
|
20
|
+
const data = require("fs");
|
|
21
|
+
_fs = function () {
|
|
22
|
+
return data;
|
|
23
|
+
};
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
11
26
|
function _semver() {
|
|
12
27
|
const data = _interopRequireDefault(require("semver"));
|
|
13
28
|
_semver = function () {
|
|
@@ -22,9 +37,9 @@ function _parsePackageName() {
|
|
|
22
37
|
};
|
|
23
38
|
return data;
|
|
24
39
|
}
|
|
25
|
-
function
|
|
26
|
-
const data = require("@pnpm/default-reporter");
|
|
27
|
-
|
|
40
|
+
function _cli() {
|
|
41
|
+
const data = require("@pnpm/cli.default-reporter");
|
|
42
|
+
_cli = function () {
|
|
28
43
|
return data;
|
|
29
44
|
};
|
|
30
45
|
return data;
|
|
@@ -43,30 +58,16 @@ function _pluginTrustedDeps() {
|
|
|
43
58
|
};
|
|
44
59
|
return data;
|
|
45
60
|
}
|
|
46
|
-
function
|
|
47
|
-
const data = require("@pnpm/
|
|
48
|
-
|
|
61
|
+
function nodeApi() {
|
|
62
|
+
const data = _interopRequireWildcard(require("@pnpm/napi"));
|
|
63
|
+
nodeApi = function () {
|
|
49
64
|
return data;
|
|
50
65
|
};
|
|
51
66
|
return data;
|
|
52
67
|
}
|
|
53
|
-
function
|
|
54
|
-
const data = require("
|
|
55
|
-
|
|
56
|
-
return data;
|
|
57
|
-
};
|
|
58
|
-
return data;
|
|
59
|
-
}
|
|
60
|
-
function _sortPackages() {
|
|
61
|
-
const data = require("@pnpm/sort-packages");
|
|
62
|
-
_sortPackages = function () {
|
|
63
|
-
return data;
|
|
64
|
-
};
|
|
65
|
-
return data;
|
|
66
|
-
}
|
|
67
|
-
function _pkgConfig() {
|
|
68
|
-
const data = require("@teambit/pkg.config.auth");
|
|
69
|
-
_pkgConfig = function () {
|
|
68
|
+
function _nerfDart() {
|
|
69
|
+
const data = _interopRequireDefault(require("nerf-dart"));
|
|
70
|
+
_nerfDart = function () {
|
|
70
71
|
return data;
|
|
71
72
|
};
|
|
72
73
|
return data;
|
|
@@ -85,42 +86,6 @@ function _legacy() {
|
|
|
85
86
|
};
|
|
86
87
|
return data;
|
|
87
88
|
}
|
|
88
|
-
function _core() {
|
|
89
|
-
const data = _interopRequireWildcard(require("@pnpm/core"));
|
|
90
|
-
_core = function () {
|
|
91
|
-
return data;
|
|
92
|
-
};
|
|
93
|
-
return data;
|
|
94
|
-
}
|
|
95
|
-
var pnpm = _core;
|
|
96
|
-
function _client() {
|
|
97
|
-
const data = require("@pnpm/client");
|
|
98
|
-
_client = function () {
|
|
99
|
-
return data;
|
|
100
|
-
};
|
|
101
|
-
return data;
|
|
102
|
-
}
|
|
103
|
-
function _worker() {
|
|
104
|
-
const data = require("@pnpm/worker");
|
|
105
|
-
_worker = function () {
|
|
106
|
-
return data;
|
|
107
|
-
};
|
|
108
|
-
return data;
|
|
109
|
-
}
|
|
110
|
-
function _workspace() {
|
|
111
|
-
const data = require("@pnpm/workspace.pkgs-graph");
|
|
112
|
-
_workspace = function () {
|
|
113
|
-
return data;
|
|
114
|
-
};
|
|
115
|
-
return data;
|
|
116
|
-
}
|
|
117
|
-
function _lockfile() {
|
|
118
|
-
const data = require("@pnpm/lockfile.fs");
|
|
119
|
-
_lockfile = function () {
|
|
120
|
-
return data;
|
|
121
|
-
};
|
|
122
|
-
return data;
|
|
123
|
-
}
|
|
124
89
|
function _dependenciesPnpm() {
|
|
125
90
|
const data = require("@teambit/dependencies.pnpm.dep-path");
|
|
126
91
|
_dependenciesPnpm = function () {
|
|
@@ -163,42 +128,95 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
163
128
|
*/
|
|
164
129
|
const UNTRUSTED_PACKAGE_NAMES = ['es5-ext', 'less', 'protobufjs', 'ssh', 'core-js-pure', 'core-js'];
|
|
165
130
|
const installsRunning = {};
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
131
|
+
let lockfileFsPromise;
|
|
132
|
+
function loadLockfileFs() {
|
|
133
|
+
lockfileFsPromise ??= (async () => {
|
|
134
|
+
const {
|
|
135
|
+
loadEsm
|
|
136
|
+
} = require('./load-pnpm-esm.cjs');
|
|
137
|
+
const {
|
|
138
|
+
lockfileFs
|
|
139
|
+
} = await loadEsm();
|
|
140
|
+
return lockfileFs;
|
|
141
|
+
})();
|
|
142
|
+
return lockfileFsPromise;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Minimal structural signature of the `resolve` function returned by
|
|
147
|
+
* `generateResolverAndFetcher`. It mirrors what the old
|
|
148
|
+
* `@pnpm/installing.client` `ResolveFunction` exposed, but is backed by
|
|
149
|
+
* `@pnpm/napi`'s `resolveDependency`.
|
|
150
|
+
*/
|
|
151
|
+
|
|
152
|
+
function toNodeApiProxyConfig(proxyConfig) {
|
|
153
|
+
return {
|
|
154
|
+
httpProxy: proxyConfig.httpProxy,
|
|
155
|
+
httpsProxy: proxyConfig.httpsProxy,
|
|
156
|
+
noProxy: proxyConfig.noProxy
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function toNodeApiNetworkConfig(networkConfig) {
|
|
160
|
+
return {
|
|
161
|
+
ca: networkConfig.ca,
|
|
162
|
+
cert: networkConfig.cert,
|
|
163
|
+
key: networkConfig.key,
|
|
164
|
+
localAddress: networkConfig.localAddress,
|
|
165
|
+
strictSsl: networkConfig.strictSSL,
|
|
166
|
+
maxSockets: networkConfig.maxSockets,
|
|
167
|
+
networkConcurrency: networkConfig.networkConcurrency,
|
|
168
|
+
fetchRetries: networkConfig.fetchRetries,
|
|
169
|
+
fetchRetryFactor: networkConfig.fetchRetryFactor,
|
|
170
|
+
fetchRetryMintimeout: networkConfig.fetchRetryMintimeout,
|
|
171
|
+
fetchRetryMaxtimeout: networkConfig.fetchRetryMaxtimeout,
|
|
172
|
+
fetchTimeout: networkConfig.fetchTimeout,
|
|
173
|
+
userAgent: networkConfig.userAgent
|
|
200
174
|
};
|
|
201
|
-
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/**
|
|
178
|
+
* Pre-computed `Authorization` headers keyed by nerf-darted registry URI
|
|
179
|
+
* (plus `''` for the default registry) — the shape `@pnpm/napi` applies
|
|
180
|
+
* directly. Bit's registries model already carries ready-to-send header
|
|
181
|
+
* values (from the engine's `readConfig` plus Bit's own cloud token), so no
|
|
182
|
+
* npmrc-style credential round-trip is needed.
|
|
183
|
+
*/
|
|
184
|
+
function buildAuthHeaderByUri(registries) {
|
|
185
|
+
const result = {};
|
|
186
|
+
for (const registry of Object.values(registries.scopes)) {
|
|
187
|
+
if (registry.uri && registry.authHeaderValue) {
|
|
188
|
+
result[(0, _nerfDart().default)(registry.uri)] = registry.authHeaderValue;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
const {
|
|
192
|
+
defaultRegistry
|
|
193
|
+
} = registries;
|
|
194
|
+
if (defaultRegistry?.authHeaderValue) {
|
|
195
|
+
if (defaultRegistry.uri) {
|
|
196
|
+
result[(0, _nerfDart().default)(defaultRegistry.uri)] = defaultRegistry.authHeaderValue;
|
|
197
|
+
}
|
|
198
|
+
result[''] = defaultRegistry.authHeaderValue;
|
|
199
|
+
}
|
|
200
|
+
return result;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Compose the list of read-package hooks into a single synchronous transform.
|
|
205
|
+
* The Bit hooks are all synchronous, so the accumulator stays synchronous even
|
|
206
|
+
* though the pnpm `ReadPackageHook` type allows returning a promise.
|
|
207
|
+
*/
|
|
208
|
+
function applyReadPackageHooks(hooks, manifest, workspaceDir) {
|
|
209
|
+
return hooks.reduce((m, hook) => hook(m, workspaceDir), manifest);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Feed a wire-compatible pnpm log event into the default reporter. The engine
|
|
214
|
+
* emits bunyan-shaped events; the reporter subscribes to `streamParser` via
|
|
215
|
+
* `.on('data', ...)`, so emitting a `data` event on the underlying stream
|
|
216
|
+
* delivers the event straight to the reporter.
|
|
217
|
+
*/
|
|
218
|
+
function emitLogEvent(event) {
|
|
219
|
+
_logger().streamParser.emit('data', event);
|
|
202
220
|
}
|
|
203
221
|
async function generateResolverAndFetcher({
|
|
204
222
|
cacheDir,
|
|
@@ -208,66 +226,49 @@ async function generateResolverAndFetcher({
|
|
|
208
226
|
fullMetadata
|
|
209
227
|
}) {
|
|
210
228
|
const pnpmConfig = await (0, _readConfig().readConfig)();
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const
|
|
215
|
-
|
|
229
|
+
// The engine-resolved `.npmrc` headers first; Bit's own registries model
|
|
230
|
+
// (which carries the cloud token) wins on conflict.
|
|
231
|
+
const authHeaderByUri = _objectSpread(_objectSpread({}, pnpmConfig.config.authHeaderByUri), buildAuthHeaderByUri(registries));
|
|
232
|
+
const registriesMap = registries.toMap();
|
|
233
|
+
const resolve = (wantedDep, resolveOpts) => nodeApi().resolveDependency(wantedDep, {
|
|
234
|
+
dir: resolveOpts.projectDir || resolveOpts.lockfileDir || process.cwd(),
|
|
216
235
|
cacheDir,
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
timeout: networkConfig.fetchTimeout,
|
|
226
|
-
rawConfig: pnpmConfig.config.rawConfig,
|
|
227
|
-
userAgent: networkConfig.userAgent,
|
|
228
|
-
retry: {
|
|
229
|
-
factor: networkConfig.fetchRetryFactor,
|
|
230
|
-
maxTimeout: networkConfig.fetchRetryMaxtimeout,
|
|
231
|
-
minTimeout: networkConfig.fetchRetryMintimeout,
|
|
232
|
-
retries: networkConfig.fetchRetries
|
|
233
|
-
},
|
|
234
|
-
registries: registries.toMap(),
|
|
235
|
-
fullMetadata,
|
|
236
|
-
fetchWarnTimeoutMs: networkConfig?.fetchWarnTimeoutMs,
|
|
237
|
-
fetchMinSpeedKiBps: networkConfig?.fetchMinSpeedKiBps
|
|
236
|
+
registries: registriesMap,
|
|
237
|
+
authHeaderByUri,
|
|
238
|
+
proxyConfig: proxyConfig ? toNodeApiProxyConfig(proxyConfig) : undefined,
|
|
239
|
+
networkConfig: networkConfig ? toNodeApiNetworkConfig(networkConfig) : undefined,
|
|
240
|
+
fullMetadata
|
|
241
|
+
});
|
|
242
|
+
return {
|
|
243
|
+
resolve
|
|
238
244
|
};
|
|
239
|
-
const result = (0, _client().createClient)(opts);
|
|
240
|
-
return result;
|
|
241
245
|
}
|
|
242
246
|
async function getPeerDependencyIssues(manifestsByPaths, opts) {
|
|
243
|
-
const projects = []
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
247
|
+
const projects = Object.entries(manifestsByPaths).map(([rootDir, manifest]) => ({
|
|
248
|
+
rootDir,
|
|
249
|
+
manifest: manifest
|
|
250
|
+
}));
|
|
251
|
+
try {
|
|
252
|
+
return await nodeApi().getPeerDependencyIssues({
|
|
253
|
+
dir: opts.rootDir,
|
|
254
|
+
projects,
|
|
255
|
+
storeDir: opts.storeDir,
|
|
256
|
+
cacheDir: opts.cacheDir,
|
|
257
|
+
overrides: opts.overrides,
|
|
258
|
+
peersSuffixMaxLength: 1000,
|
|
259
|
+
registries: opts.registries.toMap(),
|
|
260
|
+
authHeaderByUri: buildAuthHeaderByUri(opts.registries),
|
|
261
|
+
proxyConfig: toNodeApiProxyConfig(opts.proxyConfig),
|
|
262
|
+
networkConfig: toNodeApiNetworkConfig(opts.networkConfig),
|
|
263
|
+
virtualStoreDirMaxLength: _dependenciesPnpm().VIRTUAL_STORE_DIR_MAX_LENGTH
|
|
250
264
|
});
|
|
265
|
+
} catch (err) {
|
|
266
|
+
throw (0, _pnpmErrorToBitError().pnpmErrorToBitError)(err);
|
|
251
267
|
}
|
|
252
|
-
const storeController = await createStoreController(_objectSpread(_objectSpread({}, opts), {}, {
|
|
253
|
-
rootDir: opts.rootDir
|
|
254
|
-
}));
|
|
255
|
-
return pnpm().getPeerDependencyIssues(projects, {
|
|
256
|
-
autoInstallPeers: false,
|
|
257
|
-
excludeLinksFromLockfile: true,
|
|
258
|
-
storeController: storeController.ctrl,
|
|
259
|
-
storeDir: storeController.dir,
|
|
260
|
-
overrides: opts.overrides,
|
|
261
|
-
peersSuffixMaxLength: 1000,
|
|
262
|
-
registries: opts.registries.toMap(),
|
|
263
|
-
virtualStoreDirMaxLength: _dependenciesPnpm().VIRTUAL_STORE_DIR_MAX_LENGTH
|
|
264
|
-
});
|
|
265
268
|
}
|
|
266
|
-
async function install(rootDir, manifestsByPaths, storeDir, cacheDir, registries, proxyConfig = {}, networkConfig = {}, options,
|
|
267
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
268
|
-
logger) {
|
|
269
|
+
async function install(rootDir, manifestsByPaths, storeDir, cacheDir, registries, proxyConfig = {}, networkConfig = {}, options, logger) {
|
|
269
270
|
const externalDependencies = new Set();
|
|
270
|
-
const
|
|
271
|
+
const hooks = createReadPackageHooks(options);
|
|
271
272
|
if (options?.rootComponents && !options?.rootComponentsForCapsules) {
|
|
272
273
|
for (const [dir, {
|
|
273
274
|
name
|
|
@@ -290,85 +291,118 @@ logger) {
|
|
|
290
291
|
})
|
|
291
292
|
});
|
|
292
293
|
}
|
|
293
|
-
const {
|
|
294
|
-
allProjects,
|
|
295
|
-
packagesToBuild
|
|
296
|
-
} = groupPkgs(manifestsByPaths, {
|
|
297
|
-
update: options?.updateAll
|
|
298
|
-
});
|
|
299
|
-
const authConfig = (0, _pkgConfig().getAuthConfig)(registries);
|
|
300
|
-
const storeController = await createStoreController({
|
|
301
|
-
rootDir,
|
|
302
|
-
storeDir,
|
|
303
|
-
cacheDir,
|
|
304
|
-
registries,
|
|
305
|
-
preferOffline: options?.preferOffline,
|
|
306
|
-
proxyConfig,
|
|
307
|
-
networkConfig,
|
|
308
|
-
packageImportMethod: options?.packageImportMethod,
|
|
309
|
-
pnpmHomeDir: options?.pnpmHomeDir
|
|
310
|
-
});
|
|
311
294
|
const hoistPattern = options.hoistPattern ?? ['*'];
|
|
312
295
|
if (hoistPattern.length > 0 && externalDependencies.size > 0 && !options.hoistInjectedDependencies) {
|
|
313
296
|
for (const pkgName of externalDependencies) {
|
|
314
297
|
hoistPattern.push(`!${pkgName}`);
|
|
315
298
|
}
|
|
316
299
|
}
|
|
317
|
-
const
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
300
|
+
const scriptPolicies = resolveScriptPolicies({
|
|
301
|
+
allowScripts: options.allowScripts,
|
|
302
|
+
dangerouslyAllowAllScripts: options.dangerouslyAllowAllScripts,
|
|
303
|
+
neverBuiltDependencies: options.neverBuiltDependencies
|
|
304
|
+
});
|
|
305
|
+
|
|
306
|
+
// The in-memory importer manifests are transformed up front (with each
|
|
307
|
+
// importer's own directory as workspaceDir). The dependency manifests are
|
|
308
|
+
// transformed lazily by the engine through the readPackageHook (which has no
|
|
309
|
+
// workspaceDir).
|
|
310
|
+
const projects = Object.entries(manifestsByPaths).map(([dir, manifest]) => ({
|
|
311
|
+
rootDir: dir,
|
|
312
|
+
manifest: applyReadPackageHooks(hooks, manifest, dir)
|
|
313
|
+
}));
|
|
314
|
+
// When the engine resolves a workspace project as a dependency (an injected
|
|
315
|
+
// "file:" instance), it hands the hook that project's importer manifest —
|
|
316
|
+
// which the up-front transform above already stripped of workspace-sibling
|
|
317
|
+
// deps. The instance must keep those deps (they become the component's graph
|
|
318
|
+
// edges), so substitute the project's raw manifest, identified by the
|
|
319
|
+
// lockfile-root-relative directory the engine passes for directory
|
|
320
|
+
// resolutions. pnpm's TS engine reaches the same split by keeping raw
|
|
321
|
+
// project manifests and applying the hook chain contextually.
|
|
322
|
+
const readPackageHookForDeps = (manifest, resolvedDir) => {
|
|
323
|
+
const rawManifest = resolvedDir ? manifestsByPaths[(0, _path().join)(rootDir, resolvedDir)] : undefined;
|
|
324
|
+
const resolvedManifest = applyReadPackageHooks(hooks, rawManifest ?? manifest);
|
|
325
|
+
return removeScriptsFromNeverBuiltPackages(resolvedManifest, scriptPolicies.neverBuildPackageNames);
|
|
326
|
+
};
|
|
327
|
+
const onLog = event => {
|
|
328
|
+
emitLogEvent(event);
|
|
329
|
+
};
|
|
330
|
+
const installOptions = {
|
|
324
331
|
dir: rootDir,
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
lockfileOnly: options.lockfileOnly ?? false,
|
|
329
|
-
modulesCacheMaxAge: Infinity,
|
|
330
|
-
// pnpm should never prune the virtual store. Bit does it on its own.
|
|
332
|
+
projects,
|
|
333
|
+
storeDir,
|
|
334
|
+
cacheDir,
|
|
331
335
|
registries: registries.toMap(),
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
dedupeDirectDeps: true,
|
|
343
|
-
include: {
|
|
344
|
-
dependencies: true,
|
|
345
|
-
devDependencies: true,
|
|
346
|
-
optionalDependencies: options?.includeOptionalDeps !== false
|
|
347
|
-
},
|
|
348
|
-
userAgent: networkConfig.userAgent
|
|
349
|
-
}, options), {}, {
|
|
350
|
-
injectWorkspacePackages: true
|
|
351
|
-
}, resolveScriptPolicies({
|
|
352
|
-
allowScripts: options.allowScripts,
|
|
353
|
-
neverBuiltDependencies: options.neverBuiltDependencies,
|
|
354
|
-
dangerouslyAllowAllScripts: options.dangerouslyAllowAllScripts
|
|
355
|
-
})), {}, {
|
|
356
|
-
returnListOfDepsRequiringBuild: true,
|
|
357
|
-
excludeLinksFromLockfile: options.excludeLinksFromLockfile ?? true,
|
|
358
|
-
depth: options.updateAll ? Infinity : 0,
|
|
359
|
-
disableRelinkLocalDirDeps: true,
|
|
336
|
+
authHeaderByUri: buildAuthHeaderByUri(registries),
|
|
337
|
+
proxyConfig: toNodeApiProxyConfig(proxyConfig),
|
|
338
|
+
networkConfig: toNodeApiNetworkConfig(networkConfig),
|
|
339
|
+
overrides,
|
|
340
|
+
nodeLinker: options.nodeLinker,
|
|
341
|
+
// Resolve bare-semver deps on workspace components (incl. auto-installed
|
|
342
|
+
// peers naming a sibling component) from the workspace instead of the
|
|
343
|
+
// registry — otherwise an unpublished component peer 404s. `'deep'` so
|
|
344
|
+
// transitive component deps link locally too.
|
|
345
|
+
linkWorkspacePackages: 'deep',
|
|
360
346
|
hoistPattern,
|
|
347
|
+
publicHoistPattern: options.publicHoistPattern,
|
|
348
|
+
externalDependencies: [...externalDependencies],
|
|
349
|
+
allowBuilds: scriptPolicies.allowBuilds,
|
|
350
|
+
dangerouslyAllowAllBuilds: scriptPolicies.dangerouslyAllowAllBuilds,
|
|
351
|
+
// `neverBuiltDependencies` is already folded into `allowBuilds` above by
|
|
352
|
+
// `resolveScriptPolicies`; the binding rejects a non-empty pass-through.
|
|
353
|
+
autoInstallPeers: options.autoInstallPeers,
|
|
354
|
+
excludeLinksFromLockfile: options.excludeLinksFromLockfile ?? true,
|
|
355
|
+
lockfileOnly: options.lockfileOnly ?? false,
|
|
356
|
+
packageImportMethod: options.packageImportMethod,
|
|
357
|
+
preferOffline: options.preferOffline,
|
|
361
358
|
virtualStoreDirMaxLength: _dependenciesPnpm().VIRTUAL_STORE_DIR_MAX_LENGTH,
|
|
362
|
-
|
|
359
|
+
peersSuffixMaxLength: 1000,
|
|
360
|
+
dedupePeerDependents: true,
|
|
361
|
+
dedupePeers: options.dedupePeers,
|
|
362
|
+
dedupeDirectDeps: true,
|
|
363
|
+
dedupeInjectedDeps: options.dedupeInjectedDeps,
|
|
364
|
+
injectWorkspacePackages: true,
|
|
365
|
+
includeOptionalDeps: options.includeOptionalDeps !== false,
|
|
366
|
+
// `update` re-resolves the whole graph; the binding ignores `depth` (there
|
|
367
|
+
// are no package selectors), but pass a finite full-depth value for parity
|
|
368
|
+
// with the old engine's `depth: Infinity` update-all call.
|
|
369
|
+
update: options.updateAll,
|
|
370
|
+
depth: options.updateAll ? 1000 : undefined,
|
|
371
|
+
nodeVersion: options.nodeVersion,
|
|
372
|
+
engineStrict: options.engineStrict,
|
|
373
|
+
// pnpm v12 defaults minimumReleaseAge to 1440 when the option is absent.
|
|
374
|
+
// bit.cloud packuments are huge (a version per snap) and their abbreviated
|
|
375
|
+
// form carries no `time` field, so the maturity cutoff forces a full-
|
|
376
|
+
// packument upgrade fetch for every component on a cold resolve. Disable
|
|
377
|
+
// the policy unless the workspace opts in.
|
|
378
|
+
minimumReleaseAge: options.minimumReleaseAge ?? 0,
|
|
379
|
+
minimumReleaseAgeExclude: options.minimumReleaseAgeExclude,
|
|
380
|
+
// Bit lockfiles are trusted workspace input. Keep installs compatible with
|
|
381
|
+
// lockfiles generated before pnpm v12 added registry resolution verification.
|
|
382
|
+
trustLockfile: true,
|
|
383
|
+
ignorePackageManifest: options.ignorePackageManifest,
|
|
384
|
+
hoistWorkspacePackages: options.hoistWorkspacePackages,
|
|
385
|
+
enableModulesDir: options.enableModulesDir,
|
|
386
|
+
resolvePeersFromWorkspaceRoot: true,
|
|
387
|
+
frozenLockfile: options.updateAll ? false : undefined,
|
|
388
|
+
preferFrozenLockfile: !options.updateAll,
|
|
389
|
+
// Suppress peer-dependency warnings by default (allow any version, ignore
|
|
390
|
+
// missing), letting the workspace's own rules override.
|
|
363
391
|
peerDependencyRules: _objectSpread({
|
|
364
392
|
allowAny: ['*'],
|
|
365
393
|
ignoreMissing: ['*']
|
|
366
|
-
}, options.reportOptions?.peerDependencyRules)
|
|
367
|
-
|
|
394
|
+
}, options.reportOptions?.peerDependencyRules),
|
|
395
|
+
// Bit reports the deps requiring a build in the lockfile instead of failing.
|
|
396
|
+
strictDepBuilds: false,
|
|
397
|
+
pnpmHomeDir: options.pnpmHomeDir
|
|
398
|
+
};
|
|
368
399
|
let dependenciesChanged = false;
|
|
369
400
|
let depsRequiringBuild;
|
|
401
|
+
let resolvedStoreDir = storeDir;
|
|
370
402
|
if (!options.dryRun) {
|
|
371
403
|
let stopReporting;
|
|
404
|
+
let installPromise;
|
|
405
|
+
let restoreWantedLockfile;
|
|
372
406
|
if (!options.hidePackageManagerOutput) {
|
|
373
407
|
stopReporting = initReporter(_objectSpread(_objectSpread({}, options.reportOptions), {}, {
|
|
374
408
|
hideAddedPkgsProgress: options.lockfileOnly
|
|
@@ -376,100 +410,134 @@ logger) {
|
|
|
376
410
|
}
|
|
377
411
|
try {
|
|
378
412
|
await installsRunning[rootDir];
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
413
|
+
// The engine rewrites pnpm-lock.yaml from its typed model, which
|
|
414
|
+
// does not round-trip Bit's `bit:` extension block (the v11 TS
|
|
415
|
+
// engine mutated the loaded object in place, so the block
|
|
416
|
+
// survived). Capture it up front and re-assert it after the
|
|
417
|
+
// install alongside `depsRequiringBuild`.
|
|
418
|
+
const preInstallBitAttrs = await readBitLockfileAttrs(rootDir);
|
|
419
|
+
restoreWantedLockfile = await removeWantedLockfileForUpdate(rootDir, options.updateAll);
|
|
420
|
+
// The extra `resolvedDir` param lands in `@pnpm/napi`'s ReadPackageHook
|
|
421
|
+
// type in the release that ships the directory-resolution context; the
|
|
422
|
+
// cast bridges the older published typing.
|
|
423
|
+
installPromise = nodeApi().install(installOptions, onLog, readPackageHookForDeps);
|
|
424
|
+
installsRunning[rootDir] = installPromise;
|
|
425
|
+
const installResult = await installPromise;
|
|
426
|
+
resolvedStoreDir = installResult.storeDir;
|
|
427
|
+
const sortedDepsRequiringBuild = [...(installResult.depsRequiringBuild ?? [])].sort();
|
|
428
|
+
if (sortedDepsRequiringBuild.length > 0 || preInstallBitAttrs != null) {
|
|
429
|
+
await addBitAttributesToLockfile(rootDir, _objectSpread(_objectSpread({}, preInstallBitAttrs), {}, {
|
|
430
|
+
depsRequiringBuild: sortedDepsRequiringBuild
|
|
431
|
+
}));
|
|
432
|
+
}
|
|
433
|
+
if (sortedDepsRequiringBuild.length > 0) {
|
|
434
|
+
depsRequiringBuild = sortedDepsRequiringBuild;
|
|
385
435
|
}
|
|
386
436
|
dependenciesChanged = installResult.stats.added + installResult.stats.removed + installResult.stats.linkedToRoot > 0;
|
|
387
|
-
delete installsRunning[rootDir];
|
|
388
437
|
} catch (err) {
|
|
438
|
+
await restoreWantedLockfile?.();
|
|
389
439
|
if (logger) {
|
|
390
|
-
logger.warn('got an error from pnpm
|
|
440
|
+
logger.warn('got an error from the pnpm install function', err);
|
|
391
441
|
}
|
|
392
442
|
throw (0, _pnpmErrorToBitError().pnpmErrorToBitError)(err);
|
|
393
443
|
} finally {
|
|
444
|
+
if (installPromise && installsRunning[rootDir] === installPromise) {
|
|
445
|
+
delete installsRunning[rootDir];
|
|
446
|
+
}
|
|
394
447
|
stopReporting?.();
|
|
395
|
-
await (0, _worker().finishWorkers)();
|
|
396
448
|
}
|
|
397
449
|
}
|
|
398
450
|
return {
|
|
399
451
|
dependenciesChanged,
|
|
400
|
-
rebuild
|
|
452
|
+
// The Rust engine's rebuild rebuilds every build-needing package and does not
|
|
453
|
+
// support the pending / skipIfHasSideEffectsCache selectors of the old engine.
|
|
454
|
+
rebuild: async () => {
|
|
401
455
|
let stopReporting;
|
|
402
|
-
|
|
403
|
-
cacheDir
|
|
404
|
-
}); // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
405
|
-
if (!_opts.hidePackageManagerOutput) {
|
|
456
|
+
if (!options.hidePackageManagerOutput) {
|
|
406
457
|
stopReporting = initReporter({
|
|
407
458
|
appendOnly: true,
|
|
408
459
|
hideLifecycleOutput: true
|
|
409
460
|
});
|
|
410
461
|
}
|
|
411
462
|
try {
|
|
412
|
-
await
|
|
463
|
+
await nodeApi().rebuild(_objectSpread(_objectSpread({}, installOptions), {}, {
|
|
464
|
+
storeDir: resolvedStoreDir
|
|
465
|
+
}), onLog, undefined);
|
|
413
466
|
} finally {
|
|
414
467
|
stopReporting?.();
|
|
415
468
|
}
|
|
416
469
|
},
|
|
417
|
-
storeDir:
|
|
470
|
+
storeDir: resolvedStoreDir ?? '',
|
|
418
471
|
depsRequiringBuild
|
|
419
472
|
};
|
|
420
473
|
}
|
|
474
|
+
async function removeWantedLockfileForUpdate(rootDir, updateAll) {
|
|
475
|
+
if (!updateAll) return undefined;
|
|
476
|
+
const lockfilePath = (0, _path().join)(rootDir, 'pnpm-lock.yaml');
|
|
477
|
+
let lockfileContent;
|
|
478
|
+
try {
|
|
479
|
+
lockfileContent = await _fs().promises.readFile(lockfilePath);
|
|
480
|
+
} catch (err) {
|
|
481
|
+
if (err?.code === 'ENOENT') return undefined;
|
|
482
|
+
throw err;
|
|
483
|
+
}
|
|
484
|
+
await _fs().promises.unlink(lockfilePath);
|
|
485
|
+
return async () => {
|
|
486
|
+
await _fs().promises.writeFile(lockfilePath, lockfileContent);
|
|
487
|
+
};
|
|
488
|
+
}
|
|
421
489
|
function resolveScriptPolicies({
|
|
422
490
|
allowScripts,
|
|
423
|
-
|
|
424
|
-
|
|
491
|
+
dangerouslyAllowAllScripts,
|
|
492
|
+
neverBuiltDependencies
|
|
425
493
|
}) {
|
|
426
|
-
|
|
427
|
-
let onlyBuiltDependencies;
|
|
428
|
-
let ignoredBuiltDependencies;
|
|
494
|
+
const allowBuilds = {};
|
|
429
495
|
if (dangerouslyAllowAllScripts) {
|
|
430
|
-
if (
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
496
|
+
if (!neverBuiltDependencies?.length) {
|
|
497
|
+
return {
|
|
498
|
+
allowBuilds,
|
|
499
|
+
dangerouslyAllowAllBuilds: true
|
|
500
|
+
};
|
|
434
501
|
}
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
ignoredBuiltDependencies = [];
|
|
438
|
-
for (const [packageDescriptor, allowedScript] of Object.entries(allowScripts ?? {})) {
|
|
439
|
-
switch (allowedScript) {
|
|
440
|
-
case true:
|
|
441
|
-
onlyBuiltDependencies.push(packageDescriptor);
|
|
442
|
-
break;
|
|
443
|
-
case false:
|
|
444
|
-
ignoredBuiltDependencies.push(packageDescriptor);
|
|
445
|
-
break;
|
|
446
|
-
default:
|
|
447
|
-
// Ignore any non-boolean values. String values are placeholders that the user
|
|
448
|
-
// should replace with booleans.
|
|
449
|
-
// pnpm will print a warning about these during installation.
|
|
450
|
-
break;
|
|
451
|
-
}
|
|
502
|
+
for (const pkg of neverBuiltDependencies) {
|
|
503
|
+
allowBuilds[pkg] = false;
|
|
452
504
|
}
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
505
|
+
return {
|
|
506
|
+
allowBuilds,
|
|
507
|
+
neverBuildPackageNames: neverBuiltDependencies
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
for (const [packageDescriptor, allowedScript] of Object.entries(allowScripts ?? {})) {
|
|
511
|
+
if (allowedScript === true || allowedScript === false) {
|
|
512
|
+
allowBuilds[packageDescriptor] = allowedScript;
|
|
457
513
|
}
|
|
458
|
-
//
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
514
|
+
// String values (e.g. 'warn') are placeholders — ignore them; pnpm warns about these.
|
|
515
|
+
}
|
|
516
|
+
for (const trustedPkgName of _pluginTrustedDeps().TRUSTED_PACKAGE_NAMES) {
|
|
517
|
+
if (allowScripts?.[trustedPkgName] == null) {
|
|
518
|
+
allowBuilds[trustedPkgName] = true;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
for (const untrustedPkgName of UNTRUSTED_PACKAGE_NAMES) {
|
|
522
|
+
if (allowScripts?.[untrustedPkgName] !== true) {
|
|
523
|
+
allowBuilds[untrustedPkgName] = false;
|
|
463
524
|
}
|
|
464
525
|
}
|
|
526
|
+
for (const pkg of neverBuiltDependencies ?? []) {
|
|
527
|
+
allowBuilds[pkg] = false;
|
|
528
|
+
}
|
|
465
529
|
return {
|
|
466
|
-
|
|
467
|
-
onlyBuiltDependencies,
|
|
468
|
-
ignoredBuiltDependencies
|
|
530
|
+
allowBuilds
|
|
469
531
|
};
|
|
470
532
|
}
|
|
533
|
+
function removeScriptsFromNeverBuiltPackages(manifest, neverBuildPackageNames) {
|
|
534
|
+
if (!manifest.name || !manifest.scripts || !neverBuildPackageNames?.includes(manifest.name)) return manifest;
|
|
535
|
+
return _objectSpread(_objectSpread({}, manifest), {}, {
|
|
536
|
+
scripts: undefined
|
|
537
|
+
});
|
|
538
|
+
}
|
|
471
539
|
function initReporter(opts) {
|
|
472
|
-
return (0,
|
|
540
|
+
return (0, _cli().initDefaultReporter)({
|
|
473
541
|
context: {
|
|
474
542
|
argv: [],
|
|
475
543
|
process: opts?.process
|
|
@@ -565,9 +633,6 @@ function removeHarmonyFromDeps(pkg) {
|
|
|
565
633
|
* For direct dependencies, Bit's linking is used.
|
|
566
634
|
*/
|
|
567
635
|
function readPackageHook(pkg, workspaceDir) {
|
|
568
|
-
if (!pkg.dependencies) {
|
|
569
|
-
return pkg;
|
|
570
|
-
}
|
|
571
636
|
// workspaceDir is set only for workspace packages
|
|
572
637
|
if (workspaceDir && !workspaceDir.includes(_legacy().BIT_ROOTS_DIR)) {
|
|
573
638
|
return readWorkspacePackageHook(pkg);
|
|
@@ -593,49 +658,6 @@ function readWorkspacePackageHook(pkg) {
|
|
|
593
658
|
dependencies: _objectSpread(_objectSpread({}, pkg.peerDependencies), newDeps)
|
|
594
659
|
});
|
|
595
660
|
}
|
|
596
|
-
function groupPkgs(manifestsByPaths, opts) {
|
|
597
|
-
const pkgs = Object.entries(manifestsByPaths).map(([rootDir, manifest]) => ({
|
|
598
|
-
rootDir: rootDir,
|
|
599
|
-
manifest
|
|
600
|
-
}));
|
|
601
|
-
const {
|
|
602
|
-
graph
|
|
603
|
-
} = (0, _workspace().createPkgGraph)(pkgs);
|
|
604
|
-
const chunks = (0, _sortPackages().sortPackages)(graph);
|
|
605
|
-
|
|
606
|
-
// This will create local link by pnpm to a component exists in the ws.
|
|
607
|
-
// it will later deleted by the link process
|
|
608
|
-
// we keep it here to better support case like this:
|
|
609
|
-
// compA@1.0.0 uses compB@1.0.0
|
|
610
|
-
// I have compB@2.0.0 in my workspace
|
|
611
|
-
// now I install compA@1.0.0
|
|
612
|
-
// compA is hoisted to the root and install B@1.0.0 hoisted to the root as well
|
|
613
|
-
// now we will make link to B@2.0.0 and A will break
|
|
614
|
-
// with this we will have a link to the local B by pnpm so it will install B@1.0.0 inside A
|
|
615
|
-
// then when overriding the link, A will still works
|
|
616
|
-
// This is the rational behind not deleting this completely, but need further check that it really works
|
|
617
|
-
const packagesToBuild = []; // @pnpm/core will use this to install the packages
|
|
618
|
-
const allProjects = [];
|
|
619
|
-
chunks.forEach((dirs, buildIndex) => {
|
|
620
|
-
for (const rootDir of dirs) {
|
|
621
|
-
const manifest = manifestsByPaths[rootDir];
|
|
622
|
-
allProjects.push({
|
|
623
|
-
buildIndex,
|
|
624
|
-
manifest,
|
|
625
|
-
rootDir
|
|
626
|
-
});
|
|
627
|
-
packagesToBuild.push({
|
|
628
|
-
rootDir,
|
|
629
|
-
mutation: 'install',
|
|
630
|
-
update: opts.update
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
});
|
|
634
|
-
return {
|
|
635
|
-
packagesToBuild,
|
|
636
|
-
allProjects
|
|
637
|
-
};
|
|
638
|
-
}
|
|
639
661
|
async function resolveRemoteVersion(packageName, {
|
|
640
662
|
rootDir,
|
|
641
663
|
cacheDir,
|
|
@@ -663,20 +685,23 @@ async function resolveRemoteVersion(packageName, {
|
|
|
663
685
|
const parsedPackage = (0, _parsePackageName().default)(packageName);
|
|
664
686
|
const wantedDep = {
|
|
665
687
|
alias: parsedPackage.name,
|
|
666
|
-
|
|
688
|
+
// parse-package-name returns an empty string when no version is present,
|
|
689
|
+
// but the engine resolves only undefined (or an explicit range) as "latest".
|
|
690
|
+
bareSpecifier: parsedPackage.version || undefined
|
|
667
691
|
};
|
|
668
692
|
const val = await resolve(wantedDep, resolveOpts);
|
|
669
693
|
if (!val.manifest) {
|
|
670
694
|
throw new (_bitError().BitError)('The resolved package has no manifest');
|
|
671
695
|
}
|
|
696
|
+
const manifest = val.manifest;
|
|
672
697
|
const wantedRange = parsedPackage.version && _semver().default.validRange(parsedPackage.version) ? parsedPackage.version : undefined;
|
|
673
698
|
return {
|
|
674
|
-
packageName:
|
|
675
|
-
version:
|
|
699
|
+
packageName: manifest.name,
|
|
700
|
+
version: manifest.version,
|
|
676
701
|
wantedRange,
|
|
677
702
|
isSemver: true,
|
|
678
703
|
resolvedVia: val.resolvedVia,
|
|
679
|
-
manifest
|
|
704
|
+
manifest
|
|
680
705
|
};
|
|
681
706
|
} catch (e) {
|
|
682
707
|
if (!e.message?.includes('is not a valid string')) {
|
|
@@ -694,25 +719,56 @@ async function resolveRemoteVersion(packageName, {
|
|
|
694
719
|
if (!val.normalizedBareSpecifier) {
|
|
695
720
|
throw new (_bitError().BitError)('The resolved package has no version');
|
|
696
721
|
}
|
|
722
|
+
const manifest = val.manifest;
|
|
697
723
|
return {
|
|
698
|
-
packageName:
|
|
724
|
+
packageName: manifest.name,
|
|
699
725
|
version: val.normalizedBareSpecifier,
|
|
700
726
|
isSemver: false,
|
|
701
727
|
resolvedVia: val.resolvedVia,
|
|
702
|
-
manifest
|
|
728
|
+
manifest
|
|
703
729
|
};
|
|
704
730
|
}
|
|
705
731
|
}
|
|
706
|
-
|
|
707
|
-
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Read the `bit:` extension block of the workspace's wanted lockfile,
|
|
735
|
+
* or undefined when there is no lockfile or no block.
|
|
736
|
+
*/
|
|
737
|
+
async function readBitLockfileAttrs(rootDir) {
|
|
738
|
+
try {
|
|
739
|
+
const {
|
|
740
|
+
readWantedLockfile
|
|
741
|
+
} = await loadLockfileFs();
|
|
742
|
+
const lockfile = await readWantedLockfile(rootDir, {
|
|
743
|
+
ignoreIncompatible: true
|
|
744
|
+
});
|
|
745
|
+
return lockfile?.bit;
|
|
746
|
+
} catch {
|
|
747
|
+
// A malformed lockfile fails the install itself later with a proper
|
|
748
|
+
// error; there is nothing to preserve here.
|
|
749
|
+
return undefined;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
/**
|
|
754
|
+
* Re-assert Bit's `bit:` extension block on the wanted lockfile after
|
|
755
|
+
* an engine install rewrote it. Merges over whatever the file has, so
|
|
756
|
+
* an attribute captured before the install (e.g. `restoredFromModel`)
|
|
757
|
+
* survives the rewrite.
|
|
758
|
+
*/
|
|
759
|
+
async function addBitAttributesToLockfile(rootDir, attrs) {
|
|
760
|
+
const {
|
|
761
|
+
readWantedLockfile,
|
|
762
|
+
writeWantedLockfile
|
|
763
|
+
} = await loadLockfileFs();
|
|
764
|
+
const lockfile = await readWantedLockfile(rootDir, {
|
|
708
765
|
ignoreIncompatible: true
|
|
709
766
|
});
|
|
710
767
|
if (lockfile == null) return;
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
await (0, _lockfile().writeWantedLockfile)(rootDir, lockfile);
|
|
768
|
+
const merged = _objectSpread(_objectSpread({}, lockfile.bit), attrs);
|
|
769
|
+
if ((0, _lodash().isEqual)(lockfile.bit, merged)) return;
|
|
770
|
+
lockfile.bit = merged;
|
|
771
|
+
await writeWantedLockfile(rootDir, lockfile);
|
|
716
772
|
}
|
|
717
773
|
|
|
718
774
|
//# sourceMappingURL=lynx.js.map
|