@teambit/pnpm 1.0.1123 → 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.
Files changed (38) hide show
  1. package/.npmignore +18 -0
  2. package/dist/get-proxy-config.d.ts +2 -7
  3. package/dist/get-proxy-config.js +4 -7
  4. package/dist/get-proxy-config.js.map +1 -1
  5. package/dist/get-registries.d.ts +2 -2
  6. package/dist/get-registries.js +23 -93
  7. package/dist/get-registries.js.map +1 -1
  8. package/dist/load-pnpm-esm.cjs +19 -0
  9. package/dist/lockfile-deps-graph-converter.d.ts +17 -1
  10. package/dist/lockfile-deps-graph-converter.js +101 -32
  11. package/dist/lockfile-deps-graph-converter.js.map +1 -1
  12. package/dist/lockfile-deps-graph-converter.spec.js +200 -5
  13. package/dist/lockfile-deps-graph-converter.spec.js.map +1 -1
  14. package/dist/lynx.d.ts +53 -5
  15. package/dist/lynx.js +378 -322
  16. package/dist/lynx.js.map +1 -1
  17. package/dist/lynx.spec.d.ts +1 -0
  18. package/dist/lynx.spec.js +55 -0
  19. package/dist/lynx.spec.js.map +1 -0
  20. package/dist/pnpm-error-to-bit-error.d.ts +17 -2
  21. package/dist/pnpm-error-to-bit-error.js +7 -0
  22. package/dist/pnpm-error-to-bit-error.js.map +1 -1
  23. package/dist/pnpm-error-to-bit-error.spec.js +10 -11
  24. package/dist/pnpm-error-to-bit-error.spec.js.map +1 -1
  25. package/dist/pnpm-prune-modules.js +18 -8
  26. package/dist/pnpm-prune-modules.js.map +1 -1
  27. package/dist/pnpm.package-manager.d.ts +3 -4
  28. package/dist/pnpm.package-manager.js +168 -60
  29. package/dist/pnpm.package-manager.js.map +1 -1
  30. package/dist/pnpm.package-manager.spec.d.ts +1 -0
  31. package/dist/pnpm.package-manager.spec.js +48 -0
  32. package/dist/pnpm.package-manager.spec.js.map +1 -0
  33. package/dist/{preview-1785446962235.js → preview-1785493814568.js} +2 -2
  34. package/dist/read-config.d.ts +7 -1
  35. package/dist/read-config.js +22 -14
  36. package/dist/read-config.js.map +1 -1
  37. package/load-pnpm-esm.cjs +19 -0
  38. 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 _defaultReporter() {
26
- const data = require("@pnpm/default-reporter");
27
- _defaultReporter = function () {
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 _pluginCommandsRebuild() {
47
- const data = require("@pnpm/plugin-commands-rebuild");
48
- _pluginCommandsRebuild = function () {
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 _storeConnectionManager() {
54
- const data = require("@pnpm/store-connection-manager");
55
- _storeConnectionManager = function () {
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
- const cafsLocker = new Map();
167
- async function createStoreController(options) {
168
- const authConfig = (0, _pkgConfig().getAuthConfig)(options.registries);
169
- const opts = {
170
- dir: options.rootDir,
171
- cacheDir: options.cacheDir,
172
- cafsLocker,
173
- storeDir: options.storeDir,
174
- rawConfig: authConfig,
175
- verifyStoreIntegrity: true,
176
- httpProxy: options.proxyConfig?.httpProxy,
177
- httpsProxy: options.proxyConfig?.httpsProxy,
178
- ca: options.networkConfig?.ca,
179
- cert: options.networkConfig?.cert,
180
- key: options.networkConfig?.key,
181
- localAddress: options.networkConfig?.localAddress,
182
- noProxy: options.proxyConfig?.noProxy,
183
- strictSsl: options.networkConfig.strictSSL,
184
- maxSockets: options.networkConfig.maxSockets,
185
- networkConcurrency: options.networkConfig.networkConcurrency,
186
- packageImportMethod: options.packageImportMethod,
187
- preferOffline: options.preferOffline,
188
- resolveSymlinksInInjectedDirs: true,
189
- pnpmHomeDir: options.pnpmHomeDir,
190
- userAgent: options.networkConfig.userAgent,
191
- fetchRetries: options.networkConfig.fetchRetries,
192
- fetchRetryFactor: options.networkConfig.fetchRetryFactor,
193
- fetchRetryMaxtimeout: options.networkConfig.fetchRetryMaxtimeout,
194
- fetchRetryMintimeout: options.networkConfig.fetchRetryMintimeout,
195
- fetchTimeout: options.networkConfig.fetchTimeout,
196
- virtualStoreDirMaxLength: _dependenciesPnpm().VIRTUAL_STORE_DIR_MAX_LENGTH,
197
- registries: options.registries.toMap(),
198
- fetchWarnTimeoutMs: options.networkConfig.fetchWarnTimeoutMs,
199
- fetchMinSpeedKiBps: options.networkConfig.fetchMinSpeedKiBps
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
- return (0, _storeConnectionManager().createOrConnectStoreController)(opts);
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
- const authConfig = (0, _pkgConfig().getAuthConfig)(registries);
212
- proxyConfig ??= {};
213
- networkConfig ??= {};
214
- const opts = {
215
- authConfig: Object.assign({}, pnpmConfig.config.rawConfig, authConfig),
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
- httpProxy: proxyConfig?.httpProxy,
218
- httpsProxy: proxyConfig?.httpsProxy,
219
- ca: networkConfig?.ca,
220
- cert: networkConfig?.cert,
221
- key: networkConfig?.key,
222
- localAddress: networkConfig?.localAddress,
223
- noProxy: proxyConfig?.noProxy,
224
- strictSsl: networkConfig.strictSSL,
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
- for (const [rootDir, manifest] of Object.entries(manifestsByPaths)) {
245
- projects.push({
246
- buildIndex: 0,
247
- // this is not used while searching for peer issues anyway
248
- manifest,
249
- rootDir: rootDir
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 readPackage = createReadPackageHooks(options);
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 opts = _objectSpread(_objectSpread(_objectSpread({
318
- allProjects,
319
- autoInstallPeers: options.autoInstallPeers,
320
- autoInstallPeersFromHighestMatch: options.autoInstallPeers,
321
- confirmModulesPurge: false,
322
- storeDir: storeController.dir,
323
- dedupePeerDependents: true,
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
- storeController: storeController.ctrl,
326
- preferFrozenLockfile: true,
327
- pruneLockfileImporters: true,
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
- resolutionMode: 'highest',
333
- rawConfig: authConfig,
334
- hooks: {
335
- readPackage
336
- },
337
- externalDependencies,
338
- strictPeerDependencies: false,
339
- peersSuffixMaxLength: 1000,
340
- resolveSymlinksInInjectedDirs: true,
341
- resolvePeersFromWorkspaceRoot: true,
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
- overrides,
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
- await (0, _worker().restartWorkerPool)();
380
- installsRunning[rootDir] = (0, _core().mutateModules)(packagesToBuild, opts);
381
- const installResult = await installsRunning[rootDir];
382
- depsRequiringBuild = installResult.depsRequiringBuild?.sort();
383
- if (depsRequiringBuild != null) {
384
- await addDepsRequiringBuildToLockfile(rootDir, depsRequiringBuild);
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 mutateModules function', err);
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: async rebuildOpts => {
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
- const _opts = _objectSpread(_objectSpread(_objectSpread({}, opts), rebuildOpts), {}, {
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 _pluginCommandsRebuild().rebuild.handler(_opts, []);
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: storeController.dir,
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
- neverBuiltDependencies,
424
- dangerouslyAllowAllScripts
491
+ dangerouslyAllowAllScripts,
492
+ neverBuiltDependencies
425
493
  }) {
426
- let resolvedNeverBuilt = neverBuiltDependencies;
427
- let onlyBuiltDependencies;
428
- let ignoredBuiltDependencies;
494
+ const allowBuilds = {};
429
495
  if (dangerouslyAllowAllScripts) {
430
- if (resolvedNeverBuilt == null) {
431
- // If neverBuiltDependencies is not explicitly set, use a default list
432
- // we tell pnpm to allow all scripts to be executed, except the packages listed below.
433
- resolvedNeverBuilt = ['core-js'];
496
+ if (!neverBuiltDependencies?.length) {
497
+ return {
498
+ allowBuilds,
499
+ dangerouslyAllowAllBuilds: true
500
+ };
434
501
  }
435
- } else {
436
- onlyBuiltDependencies = [];
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
- for (const trustedPkgName of _pluginTrustedDeps().TRUSTED_PACKAGE_NAMES) {
454
- if (allowScripts?.[trustedPkgName] == null) {
455
- onlyBuiltDependencies.push(trustedPkgName);
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
- // Add untrusted packages to ignoredBuiltDependencies unless the user explicitly allows them
459
- for (const untrustedPkgName of UNTRUSTED_PACKAGE_NAMES) {
460
- if (allowScripts?.[untrustedPkgName] !== true) {
461
- ignoredBuiltDependencies.push(untrustedPkgName);
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
- neverBuiltDependencies: resolvedNeverBuilt,
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, _defaultReporter().initDefaultReporter)({
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
- bareSpecifier: parsedPackage.version
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: val.manifest.name,
675
- version: val.manifest.version,
699
+ packageName: manifest.name,
700
+ version: manifest.version,
676
701
  wantedRange,
677
702
  isSemver: true,
678
703
  resolvedVia: val.resolvedVia,
679
- manifest: val.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: val.manifest.name,
724
+ packageName: manifest.name,
699
725
  version: val.normalizedBareSpecifier,
700
726
  isSemver: false,
701
727
  resolvedVia: val.resolvedVia,
702
- manifest: val.manifest
728
+ manifest
703
729
  };
704
730
  }
705
731
  }
706
- async function addDepsRequiringBuildToLockfile(rootDir, depsRequiringBuild) {
707
- const lockfile = await (0, _lockfile().readWantedLockfile)(rootDir, {
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
- if ((0, _lodash().isEqual)(lockfile.bit?.depsRequiringBuild, depsRequiringBuild)) return;
712
- lockfile.bit = _objectSpread(_objectSpread({}, lockfile.bit), {}, {
713
- depsRequiringBuild
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