@teambit/install 0.0.0-019dfe796cb827647fea4f5ea377789618005504

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 (77) hide show
  1. package/dist/esm.mjs +7 -0
  2. package/dist/exceptions/dependency-type-not-supported-in-policy.d.ts +4 -0
  3. package/dist/exceptions/dependency-type-not-supported-in-policy.js +21 -0
  4. package/dist/exceptions/dependency-type-not-supported-in-policy.js.map +1 -0
  5. package/dist/exceptions/index.d.ts +1 -0
  6. package/dist/exceptions/index.js +20 -0
  7. package/dist/exceptions/index.js.map +1 -0
  8. package/dist/index.d.ts +5 -0
  9. package/dist/index.js +35 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/install.aspect.d.ts +2 -0
  12. package/dist/install.aspect.js +18 -0
  13. package/dist/install.aspect.js.map +1 -0
  14. package/dist/install.cmd.d.ts +55 -0
  15. package/dist/install.cmd.js +170 -0
  16. package/dist/install.cmd.js.map +1 -0
  17. package/dist/install.main.runtime.d.ts +248 -0
  18. package/dist/install.main.runtime.js +1400 -0
  19. package/dist/install.main.runtime.js.map +1 -0
  20. package/dist/link/component-list-links.d.ts +10 -0
  21. package/dist/link/component-list-links.js +102 -0
  22. package/dist/link/component-list-links.js.map +1 -0
  23. package/dist/link/core-aspects-links.d.ts +7 -0
  24. package/dist/link/core-aspects-links.js +83 -0
  25. package/dist/link/core-aspects-links.js.map +1 -0
  26. package/dist/link/get-package-name-from-target.d.ts +1 -0
  27. package/dist/link/get-package-name-from-target.js +13 -0
  28. package/dist/link/get-package-name-from-target.js.map +1 -0
  29. package/dist/link/index.d.ts +1 -0
  30. package/dist/link/index.js +20 -0
  31. package/dist/link/index.js.map +1 -0
  32. package/dist/link/link-row.d.ts +12 -0
  33. package/dist/link/link-row.js +32 -0
  34. package/dist/link/link-row.js.map +1 -0
  35. package/dist/link/link-to-dir.d.ts +2 -0
  36. package/dist/link/link-to-dir.js +35 -0
  37. package/dist/link/link-to-dir.js.map +1 -0
  38. package/dist/link/link.cmd.d.ts +47 -0
  39. package/dist/link/link.cmd.js +145 -0
  40. package/dist/link/link.cmd.js.map +1 -0
  41. package/dist/link/nested-deps-in-nm-links.d.ts +7 -0
  42. package/dist/link/nested-deps-in-nm-links.js +59 -0
  43. package/dist/link/nested-deps-in-nm-links.js.map +1 -0
  44. package/dist/link/rewire-row.d.ts +6 -0
  45. package/dist/link/rewire-row.js +26 -0
  46. package/dist/link/rewire-row.js.map +1 -0
  47. package/dist/pick-outdated-pkgs.d.ts +12 -0
  48. package/dist/pick-outdated-pkgs.js +180 -0
  49. package/dist/pick-outdated-pkgs.js.map +1 -0
  50. package/dist/pick-outdated-pkgs.spec.d.ts +1 -0
  51. package/dist/pick-outdated-pkgs.spec.js +169 -0
  52. package/dist/pick-outdated-pkgs.spec.js.map +1 -0
  53. package/dist/preview-1756139709945.js +7 -0
  54. package/dist/uninstall.cmd.d.ts +12 -0
  55. package/dist/uninstall.cmd.js +26 -0
  56. package/dist/uninstall.cmd.js.map +1 -0
  57. package/dist/update.cmd.d.ts +26 -0
  58. package/dist/update.cmd.js +52 -0
  59. package/dist/update.cmd.js.map +1 -0
  60. package/esm.mjs +7 -0
  61. package/exceptions/dependency-type-not-supported-in-policy.ts +7 -0
  62. package/exceptions/index.ts +1 -0
  63. package/install.cmd.tsx +208 -0
  64. package/link/component-list-links.ts +79 -0
  65. package/link/core-aspects-links.ts +57 -0
  66. package/link/get-package-name-from-target.ts +5 -0
  67. package/link/index.ts +1 -0
  68. package/link/link-row.ts +20 -0
  69. package/link/link-to-dir.ts +13 -0
  70. package/link/link.cmd.ts +118 -0
  71. package/link/nested-deps-in-nm-links.ts +47 -0
  72. package/link/rewire-row.ts +17 -0
  73. package/package.json +96 -0
  74. package/types/asset.d.ts +41 -0
  75. package/types/style.d.ts +42 -0
  76. package/uninstall.cmd.tsx +18 -0
  77. package/update.cmd.tsx +67 -0
@@ -0,0 +1,1400 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.InstallMain = void 0;
7
+ function _pFilter() {
8
+ const data = _interopRequireDefault(require("p-filter"));
9
+ _pFilter = function () {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ function _fsExtra() {
15
+ const data = _interopRequireWildcard(require("fs-extra"));
16
+ _fsExtra = function () {
17
+ return data;
18
+ };
19
+ return data;
20
+ }
21
+ function _path() {
22
+ const data = _interopRequireDefault(require("path"));
23
+ _path = function () {
24
+ return data;
25
+ };
26
+ return data;
27
+ }
28
+ function _workspace() {
29
+ const data = require("@teambit/workspace.root-components");
30
+ _workspace = function () {
31
+ return data;
32
+ };
33
+ return data;
34
+ }
35
+ function _compiler() {
36
+ const data = require("@teambit/compiler");
37
+ _compiler = function () {
38
+ return data;
39
+ };
40
+ return data;
41
+ }
42
+ function _cli() {
43
+ const data = require("@teambit/cli");
44
+ _cli = function () {
45
+ return data;
46
+ };
47
+ return data;
48
+ }
49
+ function _chalk() {
50
+ const data = _interopRequireDefault(require("chalk"));
51
+ _chalk = function () {
52
+ return data;
53
+ };
54
+ return data;
55
+ }
56
+ function _yesno() {
57
+ const data = _interopRequireDefault(require("yesno"));
58
+ _yesno = function () {
59
+ return data;
60
+ };
61
+ return data;
62
+ }
63
+ function _workspace2() {
64
+ const data = require("@teambit/workspace");
65
+ _workspace2 = function () {
66
+ return data;
67
+ };
68
+ return data;
69
+ }
70
+ function _lodash() {
71
+ const data = require("lodash");
72
+ _lodash = function () {
73
+ return data;
74
+ };
75
+ return data;
76
+ }
77
+ function _generator() {
78
+ const data = require("@teambit/generator");
79
+ _generator = function () {
80
+ return data;
81
+ };
82
+ return data;
83
+ }
84
+ function _pkgModules() {
85
+ const data = require("@teambit/pkg.modules.component-package-name");
86
+ _pkgModules = function () {
87
+ return data;
88
+ };
89
+ return data;
90
+ }
91
+ function _application() {
92
+ const data = require("@teambit/application");
93
+ _application = function () {
94
+ return data;
95
+ };
96
+ return data;
97
+ }
98
+ function _variants() {
99
+ const data = require("@teambit/variants");
100
+ _variants = function () {
101
+ return data;
102
+ };
103
+ return data;
104
+ }
105
+ function _component() {
106
+ const data = require("@teambit/component");
107
+ _component = function () {
108
+ return data;
109
+ };
110
+ return data;
111
+ }
112
+ function _component2() {
113
+ const data = require("@teambit/component.sources");
114
+ _component2 = function () {
115
+ return data;
116
+ };
117
+ return data;
118
+ }
119
+ function _dependenciesFs() {
120
+ const data = require("@teambit/dependencies.fs.linked-dependencies");
121
+ _dependenciesFs = function () {
122
+ return data;
123
+ };
124
+ return data;
125
+ }
126
+ function _pMapSeries() {
127
+ const data = _interopRequireDefault(require("p-map-series"));
128
+ _pMapSeries = function () {
129
+ return data;
130
+ };
131
+ return data;
132
+ }
133
+ function _harmony() {
134
+ const data = require("@teambit/harmony");
135
+ _harmony = function () {
136
+ return data;
137
+ };
138
+ return data;
139
+ }
140
+ function _workspaceModules() {
141
+ const data = require("@teambit/workspace.modules.node-modules-linker");
142
+ _workspaceModules = function () {
143
+ return data;
144
+ };
145
+ return data;
146
+ }
147
+ function _envs() {
148
+ const data = require("@teambit/envs");
149
+ _envs = function () {
150
+ return data;
151
+ };
152
+ return data;
153
+ }
154
+ function _ipcEvents() {
155
+ const data = require("@teambit/ipc-events");
156
+ _ipcEvents = function () {
157
+ return data;
158
+ };
159
+ return data;
160
+ }
161
+ function _componentIssues() {
162
+ const data = require("@teambit/component-issues");
163
+ _componentIssues = function () {
164
+ return data;
165
+ };
166
+ return data;
167
+ }
168
+ function _dependencyResolver() {
169
+ const data = require("@teambit/dependency-resolver");
170
+ _dependencyResolver = function () {
171
+ return data;
172
+ };
173
+ return data;
174
+ }
175
+ function _workspaceConfigFiles() {
176
+ const data = require("@teambit/workspace-config-files");
177
+ _workspaceConfigFiles = function () {
178
+ return data;
179
+ };
180
+ return data;
181
+ }
182
+ function _logger() {
183
+ const data = require("@teambit/logger");
184
+ _logger = function () {
185
+ return data;
186
+ };
187
+ return data;
188
+ }
189
+ function _issues() {
190
+ const data = require("@teambit/issues");
191
+ _issues = function () {
192
+ return data;
193
+ };
194
+ return data;
195
+ }
196
+ function _componentPackageVersion() {
197
+ const data = require("@teambit/component-package-version");
198
+ _componentPackageVersion = function () {
199
+ return data;
200
+ };
201
+ return data;
202
+ }
203
+ function _aspectLoader() {
204
+ const data = require("@teambit/aspect-loader");
205
+ _aspectLoader = function () {
206
+ return data;
207
+ };
208
+ return data;
209
+ }
210
+ function _objectHash() {
211
+ const data = _interopRequireDefault(require("object-hash"));
212
+ _objectHash = function () {
213
+ return data;
214
+ };
215
+ return data;
216
+ }
217
+ function _bundler() {
218
+ const data = require("@teambit/bundler");
219
+ _bundler = function () {
220
+ return data;
221
+ };
222
+ return data;
223
+ }
224
+ function _ui() {
225
+ const data = require("@teambit/ui");
226
+ _ui = function () {
227
+ return data;
228
+ };
229
+ return data;
230
+ }
231
+ function _exceptions() {
232
+ const data = require("./exceptions");
233
+ _exceptions = function () {
234
+ return data;
235
+ };
236
+ return data;
237
+ }
238
+ function _install() {
239
+ const data = require("./install.aspect");
240
+ _install = function () {
241
+ return data;
242
+ };
243
+ return data;
244
+ }
245
+ function _pickOutdatedPkgs() {
246
+ const data = require("./pick-outdated-pkgs");
247
+ _pickOutdatedPkgs = function () {
248
+ return data;
249
+ };
250
+ return data;
251
+ }
252
+ function _link() {
253
+ const data = require("./link");
254
+ _link = function () {
255
+ return data;
256
+ };
257
+ return data;
258
+ }
259
+ function _install2() {
260
+ const data = _interopRequireDefault(require("./install.cmd"));
261
+ _install2 = function () {
262
+ return data;
263
+ };
264
+ return data;
265
+ }
266
+ function _uninstall() {
267
+ const data = _interopRequireDefault(require("./uninstall.cmd"));
268
+ _uninstall = function () {
269
+ return data;
270
+ };
271
+ return data;
272
+ }
273
+ function _update() {
274
+ const data = _interopRequireDefault(require("./update.cmd"));
275
+ _update = function () {
276
+ return data;
277
+ };
278
+ return data;
279
+ }
280
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
281
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
282
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
283
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
284
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
285
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
286
+ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
287
+ class InstallMain {
288
+ constructor(dependencyResolver, logger, workspace, variants, compiler, envs, wsConfigFiles, aspectLoader, app, generator, preLinkSlot, preInstallSlot, postInstallSlot, ipcEvents, harmony) {
289
+ this.dependencyResolver = dependencyResolver;
290
+ this.logger = logger;
291
+ this.workspace = workspace;
292
+ this.variants = variants;
293
+ this.compiler = compiler;
294
+ this.envs = envs;
295
+ this.wsConfigFiles = wsConfigFiles;
296
+ this.aspectLoader = aspectLoader;
297
+ this.app = app;
298
+ this.generator = generator;
299
+ this.preLinkSlot = preLinkSlot;
300
+ this.preInstallSlot = preInstallSlot;
301
+ this.postInstallSlot = postInstallSlot;
302
+ this.ipcEvents = ipcEvents;
303
+ this.harmony = harmony;
304
+ _defineProperty(this, "visitedAspects", new Set());
305
+ _defineProperty(this, "oldNonLoadedEnvs", []);
306
+ }
307
+ /**
308
+ * Install dependencies for all components in the workspace
309
+ *
310
+ * @returns
311
+ * @memberof Workspace
312
+ */
313
+ async install(packages, options) {
314
+ // Check if external package manager mode is enabled
315
+ const workspaceConfig = this.workspace.getWorkspaceConfig();
316
+ const depResolverExtConfig = workspaceConfig.extensions.findExtension('teambit.dependencies/dependency-resolver');
317
+ if (depResolverExtConfig?.config.externalPackageManager) {
318
+ if (options?.showExternalPackageManagerPrompt) {
319
+ // For explicit "bit install" commands, show the prompt
320
+ await this.handleExternalPackageManagerPrompt();
321
+ } else {
322
+ this.logger.console(_chalk().default.yellow('Installation was skipped due to external package manager configuration. Please run your package manager to install dependencies.'));
323
+ return new (_component().ComponentMap)(new Map());
324
+ }
325
+ }
326
+
327
+ // set workspace in install context
328
+ this.workspace.inInstallContext = true;
329
+ this.workspace.inInstallAfterPmContext = false;
330
+ if (packages && packages.length) {
331
+ await this._addPackages(packages, options);
332
+ }
333
+ if (options?.addMissingPeers) {
334
+ const compDirMap = await this.getComponentsDirectory([]);
335
+ const mergedRootPolicy = this.dependencyResolver.getWorkspacePolicy();
336
+ const depsFilterFn = await this.generateFilterFnForDepsFromLocalRemote();
337
+ const pmInstallOptions = {
338
+ dedupe: options?.dedupe,
339
+ copyPeerToRuntimeOnRoot: options?.copyPeerToRuntimeOnRoot ?? true,
340
+ copyPeerToRuntimeOnComponents: options?.copyPeerToRuntimeOnComponents ?? false,
341
+ dependencyFilterFn: depsFilterFn,
342
+ overrides: this.dependencyResolver.config.overrides,
343
+ hoistPatterns: this.dependencyResolver.config.hoistPatterns,
344
+ packageImportMethod: this.dependencyResolver.config.packageImportMethod
345
+ };
346
+ const missingPeers = await this.dependencyResolver.getMissingPeerDependencies(this.workspace.path, mergedRootPolicy, compDirMap, pmInstallOptions);
347
+ if (missingPeers) {
348
+ const missingPeerPackages = Object.entries(missingPeers).map(([peerName, range]) => `${peerName}@${range}`);
349
+ await this._addPackages(missingPeerPackages, options);
350
+ } else {
351
+ this.logger.console('No missing peer dependencies found.');
352
+ }
353
+ }
354
+ await (0, _pMapSeries().default)(this.preInstallSlot.values(), fn => fn(options)); // import objects if not disabled in options
355
+ const res = await this._installModules(options);
356
+ this.workspace.inInstallContext = false;
357
+ await this.ipcEvents.publishIpcEvent('onPostInstall');
358
+ return res;
359
+ }
360
+ registerPreLink(fn) {
361
+ this.preLinkSlot.register(fn);
362
+ }
363
+ registerPreInstall(fn) {
364
+ this.preInstallSlot.register(fn);
365
+ }
366
+ registerPostInstall(fn) {
367
+ this.postInstallSlot.register(fn);
368
+ }
369
+ async onComponentCreate(generateResults, installOptions) {
370
+ this.workspace.inInstallContext = true;
371
+ let runInstall = false;
372
+ let packages = [];
373
+ let installMissing = false;
374
+ const ids = generateResults.map(generateResult => {
375
+ if (generateResult.dependencies && generateResult.dependencies.length) {
376
+ packages = packages.concat(generateResult.dependencies);
377
+ runInstall = true;
378
+ }
379
+ if (generateResult.installMissingDependencies) {
380
+ installMissing = true;
381
+ runInstall = true;
382
+ }
383
+ if (generateResult.isApp || generateResult.isEnv) {
384
+ runInstall = true;
385
+ }
386
+ return generateResult.id;
387
+ });
388
+ const nonLoadedEnvs = [];
389
+ ids.map(id => this.workspace.clearComponentCache(id));
390
+ await (0, _pMapSeries().default)(ids, async id => {
391
+ const component = await this.workspace.get(id);
392
+ // const envId = await this.envs.getEnvId(component);
393
+ const envId = (await this.envs.calculateEnvId(component)).toString();
394
+ const isLoaded = this.envs.isEnvRegistered(envId);
395
+ if (!isLoaded) {
396
+ nonLoadedEnvs.push(envId);
397
+ }
398
+ return component;
399
+ });
400
+ if (nonLoadedEnvs.length) {
401
+ runInstall = true;
402
+ }
403
+ if (!runInstall) {
404
+ this.workspace.inInstallContext = false;
405
+ return;
406
+ }
407
+ // this.logger.console(
408
+ // `the following environments are not installed yet: ${nonLoadedEnvs.join(', ')}. installing them now...`
409
+ // );
410
+ await this.install(packages, _objectSpread(_objectSpread({}, installOptions), {}, {
411
+ addMissingDeps: installMissing,
412
+ skipIfExisting: true,
413
+ writeConfigFiles: false
414
+ // skipPrune: true,
415
+ }));
416
+ }
417
+ async _addPackages(packages, options) {
418
+ if (options?.lifecycleType === 'dev') {
419
+ throw new (_exceptions().DependencyTypeNotSupportedInPolicy)(options?.lifecycleType);
420
+ }
421
+ this.logger.debug(`installing the following packages: ${packages.join()}`);
422
+ const resolver = await this.dependencyResolver.getVersionResolver();
423
+ const resolvedPackagesP = packages.map(async packageName => {
424
+ try {
425
+ return await resolver.resolveRemoteVersion(packageName, {
426
+ rootDir: this.workspace.path
427
+ });
428
+ } catch (error) {
429
+ if (options?.skipUnavailable) {
430
+ return;
431
+ }
432
+ throw error;
433
+ }
434
+ });
435
+ const resolvedPackages = await Promise.all(resolvedPackagesP);
436
+ const newWorkspacePolicyEntries = [];
437
+ resolvedPackages.forEach(resolvedPackage => {
438
+ if (resolvedPackage?.version) {
439
+ const versionWithPrefix = this.dependencyResolver.getVersionWithSavePrefix({
440
+ version: resolvedPackage.version,
441
+ overridePrefix: options?.savePrefix,
442
+ wantedRange: resolvedPackage.wantedRange
443
+ });
444
+ newWorkspacePolicyEntries.push({
445
+ dependencyId: resolvedPackage.packageName,
446
+ value: {
447
+ version: versionWithPrefix
448
+ },
449
+ lifecycleType: options?.lifecycleType || 'runtime'
450
+ });
451
+ }
452
+ });
453
+ this.dependencyResolver.addToRootPolicy(newWorkspacePolicyEntries, {
454
+ updateExisting: options?.updateExisting ?? false,
455
+ skipIfExisting: options?.skipIfExisting ?? false
456
+ });
457
+ await this.dependencyResolver.persistConfig('install');
458
+ }
459
+ async _installModules(options) {
460
+ const pm = this.dependencyResolver.getPackageManager();
461
+ this.logger.console(`installing dependencies in workspace using ${pm?.name} (${_chalk().default.cyan(this.dependencyResolver.packageManagerName)})`);
462
+ this.logger.debug(`installing dependencies in workspace with options`, options);
463
+ const depsFilterFn = await this.generateFilterFnForDepsFromLocalRemote();
464
+ const hasRootComponents = this.dependencyResolver.hasRootComponents();
465
+ // TODO: pass get install options
466
+ const installer = this.dependencyResolver.getInstaller({});
467
+ const calcManifestsOpts = {
468
+ copyPeerToRuntimeOnComponents: options?.copyPeerToRuntimeOnComponents ?? false,
469
+ copyPeerToRuntimeOnRoot: options?.copyPeerToRuntimeOnRoot ?? true,
470
+ dedupe: !hasRootComponents && options?.dedupe,
471
+ dependencyFilterFn: depsFilterFn,
472
+ nodeLinker: this.dependencyResolver.nodeLinker()
473
+ };
474
+ const linkOpts = {
475
+ linkTeambitBit: true,
476
+ linkCoreAspects: this.dependencyResolver.linkCoreAspects(),
477
+ linkDepsResolvedFromEnv: !hasRootComponents,
478
+ linkNestedDepsInNM: !this.workspace.isLegacy && !hasRootComponents
479
+ };
480
+ const {
481
+ linkedRootDeps
482
+ } = await this.calculateLinks(linkOpts);
483
+ // eslint-disable-next-line prefer-const
484
+ let {
485
+ mergedRootPolicy,
486
+ componentsAndManifests: current
487
+ } = await this._getComponentsManifestsAndRootPolicy(installer, _objectSpread(_objectSpread({}, calcManifestsOpts), {}, {
488
+ addMissingDeps: options?.addMissingDeps,
489
+ skipUnavailable: options?.skipUnavailable,
490
+ linkedRootDeps
491
+ }));
492
+ const pmInstallOptions = _objectSpread(_objectSpread({}, calcManifestsOpts), {}, {
493
+ autoInstallPeers: this.dependencyResolver.config.autoInstallPeers,
494
+ dependenciesGraph: options?.dependenciesGraph,
495
+ includeOptionalDeps: options?.includeOptionalDeps,
496
+ neverBuiltDependencies: this.dependencyResolver.config.neverBuiltDependencies,
497
+ overrides: this.dependencyResolver.config.overrides,
498
+ hoistPatterns: this.dependencyResolver.config.hoistPatterns,
499
+ hoistInjectedDependencies: this.dependencyResolver.config.hoistInjectedDependencies,
500
+ packageImportMethod: this.dependencyResolver.config.packageImportMethod,
501
+ rootComponents: hasRootComponents,
502
+ updateAll: options?.updateAll,
503
+ optimizeReportForNonTerminal: options?.optimizeReportForNonTerminal,
504
+ lockfileOnly: options?.lockfileOnly
505
+ });
506
+ const prevManifests = new Set();
507
+ // TODO: this make duplicate
508
+ // this.logger.consoleSuccess();
509
+ const linkedDependencies = {
510
+ [this.workspace.path]: linkedRootDeps
511
+ };
512
+ const compDirMap = await this.getComponentsDirectory([]);
513
+ let installCycle = 0;
514
+ let hasMissingLocalComponents = true;
515
+ const forcedHarmonyVersion = this.dependencyResolver.harmonyVersionInRootPolicy();
516
+ /* eslint-disable no-await-in-loop */
517
+ do {
518
+ // In case there are missing local components,
519
+ // we'll need to make another round of installation as on the first round the missing local components
520
+ // are not added to the manifests.
521
+ // This is an issue when installation is done using root components.
522
+ hasMissingLocalComponents = hasRootComponents && hasComponentsFromWorkspaceInMissingDeps(current);
523
+ const {
524
+ dependenciesChanged
525
+ } = await installer.installComponents(this.workspace.path, current.manifests, mergedRootPolicy, current.componentDirectoryMap, {
526
+ linkedDependencies,
527
+ installTeambitBit: false,
528
+ forcedHarmonyVersion
529
+ }, pmInstallOptions);
530
+ this.workspace.inInstallAfterPmContext = true;
531
+ let cacheCleared = false;
532
+ await this.linkCodemods(compDirMap);
533
+ const oldNonLoadedEnvs = this.setOldNonLoadedEnvs();
534
+ await this.reloadMovedEnvs();
535
+ await this.reloadNonLoadedEnvs();
536
+ const shouldClearCacheOnInstall = this.shouldClearCacheOnInstall();
537
+ if (options?.compile ?? true) {
538
+ const compileStartTime = process.hrtime();
539
+ const compileOutputMessage = `compiling components`;
540
+ this.logger.setStatusLine(compileOutputMessage);
541
+ if (shouldClearCacheOnInstall) {
542
+ // We need to clear cache before compiling the components or it might compile them with the default env
543
+ // incorrectly in case the env was not loaded correctly before the installation.
544
+ // We don't want to clear the failed to load envs because we want to show the warning at the end
545
+ // await this.workspace.clearCache({ skipClearFailedToLoadEnvs: true });
546
+ await this.workspace.clearCache();
547
+ cacheCleared = true;
548
+ }
549
+ await this.compiler.compileOnWorkspace([], {
550
+ initiator: _compiler().CompilationInitiator.Install
551
+ });
552
+
553
+ // Right now we don't need to load extensions/execute load slot at this point
554
+ // await this.compiler.compileOnWorkspace([], { initiator: CompilationInitiator.Install }, undefined, {
555
+ // executeLoadSlot: true,
556
+ // loadExtensions: true,
557
+ // });
558
+ this.logger.consoleSuccess(compileOutputMessage, compileStartTime);
559
+ }
560
+ if (options?.writeConfigFiles ?? true) {
561
+ await this.tryWriteConfigFiles(!cacheCleared && shouldClearCacheOnInstall);
562
+ }
563
+ if (!dependenciesChanged) break;
564
+ if (!options?.recurringInstall) break;
565
+ if (!oldNonLoadedEnvs.length) break;
566
+ prevManifests.add(manifestsHash(current.manifests));
567
+ // If we run compile we do the clear cache before the compilation so no need to clean it again (it's an expensive
568
+ // operation)
569
+ if (!cacheCleared && shouldClearCacheOnInstall) {
570
+ // We need to clear cache before creating the new component manifests.
571
+ // this.workspace.consumer.componentLoader.clearComponentsCache();
572
+ // We don't want to clear the failed to load envs because we want to show the warning at the end
573
+ await this.workspace.clearCache({
574
+ skipClearFailedToLoadEnvs: true
575
+ });
576
+ }
577
+ current = await this._getComponentsManifests(installer, mergedRootPolicy, calcManifestsOpts);
578
+ installCycle += 1;
579
+ } while ((!prevManifests.has(manifestsHash(current.manifests)) || hasMissingLocalComponents) && installCycle < 5);
580
+ if (!options?.lockfileOnly && !options?.skipPrune) {
581
+ // We clean node_modules only after the last install.
582
+ // Otherwise, we might load an env from a location that we later remove.
583
+ try {
584
+ await installer.pruneModules(this.workspace.path);
585
+ // Ignoring the error here as it's not critical and we don't want to fail the install process
586
+ } catch (err) {
587
+ this.logger.error(`failed running pnpm prune with error`, err);
588
+ }
589
+ // After pruning we need reload moved envs, as during the pruning the old location might be deleted
590
+ await this.reloadMovedEnvs();
591
+ }
592
+ // this is now commented out because we assume we don't need it anymore.
593
+ // even when the env was not loaded before and it is loaded now, it should be fine because the dependencies-data
594
+ // is only about the auto-detect-deps. there are two more steps: version-resolution and apply-overrides that
595
+ // disregard the dependencies-cache.
596
+ // await this.workspace.consumer.componentFsCache.deleteAllDependenciesDataCache();
597
+ /* eslint-enable no-await-in-loop */
598
+ return current.componentDirectoryMap;
599
+ }
600
+ shouldClearCacheOnInstall() {
601
+ const nonLoadedEnvs = this.envs.getFailedToLoadEnvs();
602
+ return nonLoadedEnvs.length > 0;
603
+ }
604
+
605
+ /**
606
+ * This function is very important to fix some issues that might happen during the installation process.
607
+ * The case is the following:
608
+ * during/before the installation process we load some envs from their bit.env files
609
+ * this contains code like:
610
+ * protected tsconfigPath = require.resolve('./config/tsconfig.json');
611
+ * protected eslintConfigPath = require.resolve('./config/eslintrc.cjs');
612
+ * When we load that file, we calculated the resolved path, and it's stored in the env
613
+ * object instance.
614
+ * then later on during the install we move the env to another location (like bit roots)
615
+ * which points to a .pnpm folder with some peers, that changed during the install
616
+ * then when we take this env object and call write ws config for example
617
+ * or compile
618
+ * we use that resolved path to calculate the final tsconfig
619
+ * however that file is no longer exists which result in an error
620
+ * This function will check if an env folder doesn't exist anymore, and will re-load it
621
+ * from its new location.
622
+ * This usually happen when we have install running in the middle of the process followed
623
+ * by other bit ops.
624
+ * examples:
625
+ * bit new - which might run few installs then other ops.
626
+ * bit switch - which might run few installs then other ops, and potentially change the
627
+ * peer deps during the install.
628
+ * bit server (vscode plugin) - which keep the process always live, so any install ops
629
+ * that change the location, will cause the vscode plugin/bit server to crash later.
630
+ * @returns
631
+ */
632
+ async reloadMovedEnvs() {
633
+ this.logger.debug('reloadMovedEnvs');
634
+ const allEnvs = this.envs.getAllRegisteredEnvs();
635
+ const movedEnvs = await (0, _pFilter().default)(allEnvs, async env => {
636
+ if (!env.__path) return false;
637
+ const regularPathExists = await (0, _fsExtra().pathExists)(env.__path);
638
+ const resolvedPathExists = await (0, _fsExtra().pathExists)(env.__resolvedPath);
639
+ return !regularPathExists || !resolvedPathExists;
640
+ });
641
+ const idsToLoad = movedEnvs.map(env => env.id);
642
+ const componentIdsToLoad = idsToLoad.map(id => _component().ComponentID.fromString(id));
643
+ await this.reloadEnvs(componentIdsToLoad);
644
+ }
645
+ async reloadRegisteredEnvs() {
646
+ const allEnvs = this.envs.getAllRegisteredEnvs();
647
+ const idsToLoad = (0, _lodash().compact)(allEnvs.map(env => env.id));
648
+ const componentIdsToLoad = idsToLoad.map(id => _component().ComponentID.fromString(id));
649
+ await this.reloadEnvs(componentIdsToLoad);
650
+ }
651
+ async reloadNonLoadedEnvs() {
652
+ const nonLoadedEnvs = this.envs.getFailedToLoadEnvs();
653
+ const componentIdsToLoad = nonLoadedEnvs.map(id => _component().ComponentID.fromString(id));
654
+ await this.reloadEnvs(componentIdsToLoad);
655
+ }
656
+ async reloadEnvs(componentIdsToLoad) {
657
+ if (componentIdsToLoad.length && this.workspace) {
658
+ const aspects = await this.workspace.resolveAspects(undefined, componentIdsToLoad, {
659
+ requestedOnly: true,
660
+ excludeCore: true,
661
+ throwOnError: false
662
+ // Theoretically we should use skipDeps here, but according to implementation at the moment
663
+ // it will lead to plugins not load, and we need them to be loaded.
664
+ // This is a bug in the flow and should be fixed.
665
+ // skipDeps: true,
666
+ });
667
+ await Promise.all(aspects.map(async aspectDef => {
668
+ const id = aspectDef.component?.id;
669
+ if (!id) return;
670
+ await this.workspace.clearComponentCache(id);
671
+ }));
672
+ await this.reloadAspects(aspects || []);
673
+
674
+ // Keeping this here for now, it was removed as part of #9138 as now that we load envs of envs
675
+ // correctly first it seems to be not needed anymore.
676
+ // But there might be cases where it will be needed. So keeping it here for now.
677
+
678
+ // This is a very special case which we need to compile our envs before loading them correctly.
679
+ // const grouped = groupBy(aspects, (aspectDef) => {
680
+ // return aspectDef.component?.id.toStringWithoutVersion() === 'bitdev.general/envs/bit-env';
681
+ // });
682
+ // await this.reloadAspects(grouped.true || []);
683
+ // const otherEnvs = grouped.false || [];
684
+ // await Promise.all(
685
+ // otherEnvs.map(async (aspectDef) => {
686
+ // const id = aspectDef.component?.id;
687
+ // if (!id) return;
688
+ // await this.workspace.clearComponentCache(id);
689
+ // })
690
+ // );
691
+ // await this.reloadAspects(grouped.false || []);
692
+ }
693
+ }
694
+ async reloadAspects(aspects) {
695
+ const groups = await this.groupAspectsToLoad(aspects);
696
+ // We need to make sure we load group by group and not in parallel
697
+ await (0, _pMapSeries().default)(groups, async group => {
698
+ await this.reloadOneAspectsGroup(group);
699
+ });
700
+ }
701
+ async reloadOneAspectsGroup(group) {
702
+ const aspects = group.aspects || [];
703
+ if (group.workspace && !group.envOfAspect) {
704
+ aspects.forEach(aspectDef => {
705
+ if (aspectDef.component?.id) {
706
+ this.workspace.clearComponentCache(aspectDef.component.id);
707
+ }
708
+ });
709
+ }
710
+ const loadedPlugins = (0, _lodash().compact)(await Promise.all(aspects.map(aspectDef => {
711
+ const localPath = aspectDef.aspectPath;
712
+ const component = aspectDef.component;
713
+ if (!component) return undefined;
714
+ const plugins = this.aspectLoader.getPlugins(component, localPath);
715
+ if (plugins.has()) {
716
+ return plugins.load(_cli().MainRuntime.name);
717
+ }
718
+ })));
719
+ await Promise.all(loadedPlugins.map(plugin => {
720
+ const runtime = plugin.getRuntime(_cli().MainRuntime);
721
+ return runtime?.provider(undefined, undefined, undefined, this.harmony);
722
+ }));
723
+ }
724
+
725
+ /**
726
+ * This function groups the components to aspects to load into groups.
727
+ * The order of the groups is important, the first group should be loaded first.
728
+ * The order inside the group is not important.
729
+ * The groups are:
730
+ * 1. aspects definitions without components (this should be an empty group, if it's not, we should check why).
731
+ * 2. aspects which are not in the workspace but in the scope / node modules.
732
+ * 3. envs of aspects (which are also aspects)
733
+ * 4. other aspects (the rest)
734
+ * @param aspects
735
+ * @returns
736
+ */
737
+ async groupAspectsToLoad(aspects) {
738
+ const groups = (0, _lodash().groupBy)(aspects, aspectDef => {
739
+ if (!aspectDef.component) return 'no-comp';
740
+ if (!this.workspace.hasId(aspectDef.component.id)) return 'scope';
741
+ return 'workspace';
742
+ });
743
+ const workspaceSubGroups = await this.regroupEnvsIdsFromTheList(groups.workspace || []);
744
+ return [{
745
+ comps: false,
746
+ workspace: false,
747
+ aspects: groups.noComp || []
748
+ }, {
749
+ comps: true,
750
+ workspace: false,
751
+ aspects: groups.scope || []
752
+ }, {
753
+ comps: true,
754
+ workspace: true,
755
+ envOfAspect: true,
756
+ aspects: workspaceSubGroups.envOfAspect
757
+ }, {
758
+ comps: true,
759
+ workspace: true,
760
+ aspects: workspaceSubGroups.otherAspects
761
+ }];
762
+ }
763
+ async regroupEnvsIdsFromTheList(aspects) {
764
+ const envsOfAspects = new Set();
765
+ await Promise.all(aspects.map(async aspectDef => {
766
+ if (!aspectDef.component) return;
767
+ const envId = aspectDef.component ? await this.envs.calculateEnvId(aspectDef.component) : undefined;
768
+ if (envId) {
769
+ envsOfAspects.add(envId.toString());
770
+ }
771
+ }));
772
+ const groups = (0, _lodash().groupBy)(aspects, aspectDef => {
773
+ const id = aspectDef.component?.id.toString();
774
+ const idWithoutVersion = aspectDef.component?.id.toStringWithoutVersion();
775
+ if (id && envsOfAspects.has(id) || idWithoutVersion && envsOfAspects.has(idWithoutVersion)) {
776
+ return 'envOfAspect';
777
+ }
778
+ return 'otherAspects';
779
+ });
780
+ return groups;
781
+ }
782
+ async _getComponentsManifestsAndRootPolicy(installer, options) {
783
+ const mergedRootPolicy = await this.addConfiguredAspectsToWorkspacePolicy();
784
+ await this.addConfiguredGeneratorEnvsToWorkspacePolicy(mergedRootPolicy);
785
+ const componentsAndManifests = await this._getComponentsManifests(installer, mergedRootPolicy, options);
786
+ if (!options?.addMissingDeps) {
787
+ return {
788
+ componentsAndManifests,
789
+ mergedRootPolicy
790
+ };
791
+ }
792
+ const rootDeps = new Set(Object.keys(_objectSpread(_objectSpread(_objectSpread({}, componentsAndManifests.manifests[this.workspace.path].devDependencies), componentsAndManifests.manifests[this.workspace.path].dependencies), options.linkedRootDeps)));
793
+ Object.values((0, _lodash().omit)(componentsAndManifests.manifests, [this.workspace.path])).forEach(manifest => {
794
+ if (manifest.name) {
795
+ rootDeps.add(manifest.name); // eslint-disable-line @typescript-eslint/no-non-null-assertion
796
+ }
797
+ });
798
+ const addedNewPkgs = await this._addMissingPackagesToRootPolicy(rootDeps, {
799
+ skipUnavailable: options?.skipUnavailable
800
+ });
801
+ if (!addedNewPkgs) {
802
+ return {
803
+ componentsAndManifests,
804
+ mergedRootPolicy
805
+ };
806
+ }
807
+ const mergedRootPolicyWithMissingDeps = await this.addConfiguredAspectsToWorkspacePolicy();
808
+ await this.addConfiguredGeneratorEnvsToWorkspacePolicy(mergedRootPolicyWithMissingDeps);
809
+ return {
810
+ mergedRootPolicy: mergedRootPolicyWithMissingDeps,
811
+ componentsAndManifests: await this._getComponentsManifests(installer, mergedRootPolicyWithMissingDeps, options)
812
+ };
813
+ }
814
+
815
+ /**
816
+ * The function `tryWriteConfigFiles` attempts to write workspace config files, and if it fails, it logs an error
817
+ * message.
818
+ * @returns If the condition `!shouldWrite` is true, then nothing is being returned. Otherwise, if the `writeConfigFiles`
819
+ * function is successfully executed, nothing is being returned. If an error occurs during the execution of
820
+ * `writeConfigFiles`, an error message is being returned.
821
+ */
822
+ async tryWriteConfigFiles(clearCache) {
823
+ const shouldWrite = this.wsConfigFiles.isWorkspaceConfigWriteEnabled();
824
+ if (!shouldWrite) return;
825
+ if (clearCache) {
826
+ await this.workspace.clearCache({
827
+ skipClearFailedToLoadEnvs: true
828
+ });
829
+ }
830
+ const {
831
+ err
832
+ } = await this.wsConfigFiles.writeConfigFiles({
833
+ clean: true,
834
+ silent: true,
835
+ dedupe: true,
836
+ throw: false
837
+ });
838
+ if (err) {
839
+ this.logger.consoleFailure(`failed generating workspace config files, please run "bit ws-config write" manually. error: ${err.message}`);
840
+ }
841
+ }
842
+ async addConfiguredAspectsToWorkspacePolicy() {
843
+ const rootPolicy = this.dependencyResolver.getWorkspacePolicy();
844
+ const aspectsPackages = await this.workspace.getConfiguredUserAspectsPackages({
845
+ externalsOnly: true
846
+ });
847
+ aspectsPackages.forEach(aspectsPackage => {
848
+ rootPolicy.add({
849
+ dependencyId: aspectsPackage.packageName,
850
+ value: {
851
+ version: aspectsPackage.version
852
+ },
853
+ lifecycleType: 'runtime'
854
+ },
855
+ // If it's already exist from the root, take the version from the root policy
856
+ {
857
+ skipIfExisting: true
858
+ });
859
+ });
860
+ return rootPolicy;
861
+ }
862
+ async addConfiguredGeneratorEnvsToWorkspacePolicy(rootPolicy) {
863
+ const configuredEnvs = this.generator.getConfiguredEnvs();
864
+ const resolvedEnvs = (0, _lodash().compact)(await Promise.all(configuredEnvs.map(async envIdStr => {
865
+ if (this.envs.isCoreEnv(envIdStr)) {
866
+ return undefined;
867
+ }
868
+ const parsedId = await this.workspace.resolveComponentId(envIdStr);
869
+ // If we have the env in the workspace, we don't want to install it
870
+ const inWs = await this.workspace.hasId(parsedId);
871
+ if (inWs) {
872
+ return undefined;
873
+ }
874
+ const comps = await this.workspace.importAndGetMany([parsedId], `to get the env ${parsedId.toString()} for installation`);
875
+ const idWithVersion = await this.workspace.resolveEnvIdWithPotentialVersionForConfig(parsedId);
876
+ const version = idWithVersion.split('@')[1] || '*';
877
+ const packageName = this.dependencyResolver.getPackageName(comps[0]);
878
+ return {
879
+ packageName,
880
+ version
881
+ };
882
+ })));
883
+ resolvedEnvs.forEach(env => {
884
+ rootPolicy.add({
885
+ dependencyId: env.packageName,
886
+ value: {
887
+ version: env.version
888
+ },
889
+ lifecycleType: 'runtime'
890
+ },
891
+ // If it's already exist from the root, take the version from the root policy
892
+ {
893
+ skipIfExisting: true
894
+ });
895
+ });
896
+ }
897
+ async _addMissingPackagesToRootPolicy(rootDeps, options) {
898
+ const packages = await this._getMissingPackagesWithoutRootDeps(rootDeps);
899
+ if (packages && packages.length) {
900
+ await this._addPackages(packages, options);
901
+ }
902
+ return packages.length > 0;
903
+ }
904
+ async _getMissingPackagesWithoutRootDeps(rootDeps) {
905
+ const packages = await this._getAllMissingPackages();
906
+ return packages.filter(pkg => !rootDeps.has(pkg));
907
+ }
908
+ async _getAllMissingPackages() {
909
+ const comps = await this.workspace.list();
910
+ return (0, _lodash().uniq)(comps.map(comp => {
911
+ const data = comp.state.issues.getIssue(_componentIssues().IssuesClasses.MissingPackagesDependenciesOnFs)?.data || [];
912
+ return data.map(d => d.missingPackages).flat();
913
+ }).flat());
914
+ }
915
+ async _getComponentsManifests(dependencyInstaller, rootPolicy, installOptions) {
916
+ const componentDirectoryMap = await this.getComponentsDirectory([]);
917
+ let manifests = await dependencyInstaller.getComponentManifests(_objectSpread(_objectSpread({}, installOptions), {}, {
918
+ componentDirectoryMap,
919
+ rootPolicy,
920
+ rootDir: this.workspace.path,
921
+ referenceLocalPackages: this.dependencyResolver.hasRootComponents() && installOptions.nodeLinker === 'isolated'
922
+ }));
923
+ if (this.dependencyResolver.hasRootComponents()) {
924
+ const rootManifests = await this._getRootManifests(manifests);
925
+ await this._updateRootDirs(Object.keys(rootManifests));
926
+ manifests = _objectSpread(_objectSpread({}, manifests), rootManifests);
927
+ }
928
+ return {
929
+ componentDirectoryMap,
930
+ manifests
931
+ };
932
+ }
933
+ setOldNonLoadedEnvs() {
934
+ const nonLoadedEnvs = this.envs.getFailedToLoadEnvs();
935
+ const envsWithoutManifest = Array.from(this.dependencyResolver.envsWithoutManifest);
936
+ const oldNonLoadedEnvs = (0, _lodash().intersection)(nonLoadedEnvs, envsWithoutManifest);
937
+ this.oldNonLoadedEnvs = oldNonLoadedEnvs;
938
+ return oldNonLoadedEnvs;
939
+ }
940
+
941
+ /**
942
+ * This function returns a list of old non-loaded environments names.
943
+ * @returns an array of strings called `oldNonLoadedEnvs`. This array contains the names of environment variables that
944
+ * failed to load as extensions and are also don't have an env.jsonc file.
945
+ * If this list is not empty, then the user might need to run another install to make sure all dependencies resolved
946
+ * correctly
947
+ */
948
+ getOldNonLoadedEnvs() {
949
+ return this.oldNonLoadedEnvs;
950
+ }
951
+ async _updateRootDirs(rootDirs) {
952
+ try {
953
+ const existingDirs = await _fsExtra().default.readdir(this.workspace.rootComponentsPath);
954
+ await Promise.all(existingDirs.map(async dirName => {
955
+ const dirPath = _path().default.join(this.workspace.rootComponentsPath, dirName);
956
+ if (!rootDirs.includes(dirPath)) {
957
+ await _fsExtra().default.remove(dirPath);
958
+ }
959
+ }));
960
+ } catch (err) {
961
+ if (err.code !== 'ENOENT') throw err;
962
+ }
963
+ await Promise.all(rootDirs.map(dirPath => _fsExtra().default.mkdir(dirPath, {
964
+ recursive: true
965
+ })));
966
+ }
967
+ async _getRootManifests(manifests) {
968
+ const nonRootManifests = Object.values(manifests).filter(({
969
+ name
970
+ }) => name !== 'workspace');
971
+ const workspaceDeps = this.dependencyResolver.getWorkspaceDepsOfBitRoots(nonRootManifests);
972
+ const envManifests = await this._getEnvManifests(workspaceDeps);
973
+ const appManifests = await this._getAppManifests(manifests, workspaceDeps);
974
+ return _objectSpread(_objectSpread({}, envManifests), appManifests);
975
+ }
976
+ async _getEnvManifests(workspaceDeps) {
977
+ const envs = await this._getAllUsedEnvIds();
978
+ return Object.fromEntries(await Promise.all(envs.map(async envId => {
979
+ return [await this.getRootComponentDirByRootId(this.workspace.rootComponentsPath, envId), {
980
+ dependencies: _objectSpread(_objectSpread(_objectSpread({}, await this._getEnvDependencies(envId)), workspaceDeps), await this._getEnvPackage(envId)),
981
+ installConfig: {
982
+ hoistingLimits: 'workspaces'
983
+ }
984
+ }];
985
+ })));
986
+ }
987
+ async _getEnvDependencies(envId) {
988
+ const policy = await this.dependencyResolver.getEnvPolicyFromEnvId(envId);
989
+ if (!policy) return {};
990
+ return Object.fromEntries(policy.selfPolicy.entries.filter(({
991
+ force,
992
+ value
993
+ }) => force && value.version !== '-').map(({
994
+ dependencyId,
995
+ value
996
+ }) => [dependencyId, value.version]));
997
+ }
998
+
999
+ /**
1000
+ * Return the package name of the env with its version.
1001
+ * (only if the env is not a core env and is not in the workspace)
1002
+ * @param envId
1003
+ * @returns
1004
+ */
1005
+ async _getEnvPackage(envId) {
1006
+ if (this.envs.isCoreEnv(envId.toStringWithoutVersion())) return undefined;
1007
+ const inWs = await this.workspace.hasId(envId);
1008
+ if (inWs) return undefined;
1009
+ const envComponent = await this.envs.getEnvComponentByEnvId(envId.toString(), envId.toString());
1010
+ if (!envComponent) return undefined;
1011
+ const packageName = this.dependencyResolver.getPackageName(envComponent);
1012
+ const version = envId.version;
1013
+ const finalVersion = (0, _componentPackageVersion().snapToSemver)(version);
1014
+ return {
1015
+ [packageName]: finalVersion
1016
+ };
1017
+ }
1018
+ async _getAppManifests(manifests, workspaceDeps) {
1019
+ return Object.fromEntries((0, _lodash().compact)(await Promise.all((await this.app.listAppsComponents()).map(async app => {
1020
+ const appPkgName = this.dependencyResolver.getPackageName(app);
1021
+ const appManifest = Object.values(manifests).find(({
1022
+ name
1023
+ }) => name === appPkgName);
1024
+ if (!appManifest) return null;
1025
+ const envId = await this.envs.calculateEnvId(app);
1026
+ return [await this.getRootComponentDirByRootId(this.workspace.rootComponentsPath, app.id), _objectSpread(_objectSpread({}, (0, _lodash().omit)(appManifest, ['name', 'version'])), {}, {
1027
+ dependencies: _objectSpread(_objectSpread(_objectSpread({}, await this._getEnvDependencies(envId)), appManifest.dependencies), workspaceDeps),
1028
+ installConfig: {
1029
+ hoistingLimits: 'workspaces'
1030
+ }
1031
+ })];
1032
+ }))));
1033
+ }
1034
+ async _getAllUsedEnvIds() {
1035
+ const envs = new Map();
1036
+ const components = await this.workspace.list();
1037
+ await (0, _pMapSeries().default)(components, async component => {
1038
+ const envId = await this.envs.calculateEnvId(component);
1039
+ envs.set(envId.toString(), envId);
1040
+ });
1041
+ return Array.from(envs.values());
1042
+ }
1043
+
1044
+ /**
1045
+ * Updates out-of-date dependencies in the workspace.
1046
+ *
1047
+ * @param options.all {Boolean} updates all outdated dependencies without showing a prompt.
1048
+ */
1049
+ async updateDependencies(options) {
1050
+ const componentPolicies = await this.workspace.getComponentsWithDependencyPolicies();
1051
+ const variantPoliciesByPatterns = this.workspace.variantPatternsToDepPolicesDict();
1052
+ const components = await this.workspace.list();
1053
+ const outdatedPkgs = await this.dependencyResolver.getOutdatedPkgsFromPolicies({
1054
+ rootDir: this.workspace.path,
1055
+ variantPoliciesByPatterns,
1056
+ componentPolicies,
1057
+ components,
1058
+ patterns: options.patterns,
1059
+ forceVersionBump: options.forceVersionBump
1060
+ });
1061
+ if (outdatedPkgs == null) {
1062
+ this.logger.consoleFailure('No dependencies found that match the patterns');
1063
+ return null;
1064
+ }
1065
+ let outdatedPkgsToUpdate;
1066
+ if (options.all) {
1067
+ outdatedPkgsToUpdate = outdatedPkgs;
1068
+ } else {
1069
+ this.logger.off();
1070
+ outdatedPkgsToUpdate = await (0, _pickOutdatedPkgs().pickOutdatedPkgs)(outdatedPkgs);
1071
+ this.logger.on();
1072
+ }
1073
+ if (outdatedPkgsToUpdate.length === 0) {
1074
+ this.logger.consoleSuccess('No outdated dependencies found');
1075
+ if (options.forceVersionBump === 'compatible') {
1076
+ this.logger.console("If you want to find new versions that don't match the current version ranges, retry with the --latest flag");
1077
+ }
1078
+ return null;
1079
+ }
1080
+ const {
1081
+ updatedVariants,
1082
+ updatedComponents
1083
+ } = this.dependencyResolver.applyUpdates(outdatedPkgsToUpdate, {
1084
+ variantPoliciesByPatterns
1085
+ });
1086
+ await this._updateVariantsPolicies(updatedVariants);
1087
+ await this._updateComponentsConfig(updatedComponents);
1088
+ await this.workspace._reloadConsumer();
1089
+ return this._installModules({
1090
+ dedupe: true
1091
+ });
1092
+ }
1093
+ async addDuplicateComponentAndPackageIssue(components) {
1094
+ const workspacePolicy = this.dependencyResolver.getWorkspacePolicy();
1095
+ components.forEach(component => {
1096
+ if (component.state._consumer.removed) return;
1097
+ const pkgName = (0, _pkgModules().componentIdToPackageName)(component.state._consumer);
1098
+ const found = workspacePolicy.find(pkgName);
1099
+ if (found) {
1100
+ component.state.issues.getOrCreate(_componentIssues().IssuesClasses.DuplicateComponentAndPackage).data = found.dependencyId;
1101
+ }
1102
+ });
1103
+ }
1104
+ async _updateComponentsConfig(updatedComponents) {
1105
+ if (updatedComponents.length === 0) return;
1106
+ await Promise.all(updatedComponents.map(({
1107
+ componentId,
1108
+ config
1109
+ }) => {
1110
+ return this.workspace.addSpecificComponentConfig(componentId, _dependencyResolver().DependencyResolverAspect.id, config, {
1111
+ shouldMergeWithExisting: true,
1112
+ shouldMergeWithPrevious: true
1113
+ });
1114
+ }));
1115
+ await this.workspace.bitMap.write('update (dependencies)');
1116
+ }
1117
+ async _updateVariantsPolicies(updateVariantPolicies) {
1118
+ const variantPatterns = this.variants.raw();
1119
+ for (const variantPattern of updateVariantPolicies) {
1120
+ this.variants.setExtension(variantPattern, _dependencyResolver().DependencyResolverAspect.id, variantPatterns[variantPattern][_dependencyResolver().DependencyResolverAspect.id], {
1121
+ overrideExisting: true
1122
+ });
1123
+ }
1124
+ await this.dependencyResolver.persistConfig('update dependencies');
1125
+ }
1126
+
1127
+ /**
1128
+ * Uninstall the specified packages from dependencies.
1129
+ *
1130
+ * @param {string[]} the list of packages that should be removed from dependencies.
1131
+ */
1132
+ async uninstallDependencies(packages) {
1133
+ this.dependencyResolver.removeFromRootPolicy(packages);
1134
+ await this.dependencyResolver.persistConfig('uninstall dependencies');
1135
+ return this._installModules({
1136
+ dedupe: true
1137
+ });
1138
+ }
1139
+
1140
+ /**
1141
+ * This function returns all the locations of the external links that should be created inside node_modules.
1142
+ * This information may then be passed to the package manager, which will create the links on its own.
1143
+ */
1144
+ async calculateLinks(options = {}) {
1145
+ await (0, _pMapSeries().default)(this.preLinkSlot.values(), fn => fn(options)); // import objects if not disabled in options
1146
+ const compDirMap = await this.getComponentsDirectory([]);
1147
+ const linker = this.dependencyResolver.getLinker({
1148
+ rootDir: this.workspace.path,
1149
+ linkingOptions: options
1150
+ });
1151
+ const {
1152
+ linkResults: res,
1153
+ linkedRootDeps
1154
+ } = await linker.calculateLinkedDeps(this.workspace.path, compDirMap, options);
1155
+ const workspaceRes = res;
1156
+ const legacyResults = await this.linkCodemods(compDirMap, options);
1157
+ workspaceRes.legacyLinkResults = legacyResults.linksResults;
1158
+ workspaceRes.legacyLinkCodemodResults = legacyResults.codemodResults;
1159
+ if (this.dependencyResolver.hasRootComponents() && options.linkToBitRoots) {
1160
+ await this._linkAllComponentsToBitRoots(compDirMap);
1161
+ }
1162
+ return {
1163
+ linkResults: res,
1164
+ linkedRootDeps
1165
+ };
1166
+ }
1167
+ async linkCodemods(compDirMap, options) {
1168
+ const bitIds = compDirMap.toArray().map(([component]) => component.id);
1169
+ return (0, _workspaceModules().linkToNodeModulesWithCodemod)(this.workspace, bitIds, options?.rewire ?? false);
1170
+ }
1171
+ async link(options = {}) {
1172
+ const {
1173
+ linkResults,
1174
+ linkedRootDeps
1175
+ } = await this.calculateLinks(options);
1176
+ await (0, _dependenciesFs().createLinks)(options.linkToDir ?? this.workspace.path, linkedRootDeps, {
1177
+ avoidHardLink: true,
1178
+ skipIfSymlinkValid: true
1179
+ });
1180
+ return linkResults;
1181
+ }
1182
+ async _linkAllComponentsToBitRoots(compDirMap) {
1183
+ const envs = await this._getAllUsedEnvIds();
1184
+ const apps = (await this.app.listAppsComponents()).map(component => component.id);
1185
+ await Promise.all([...envs, ...apps].map(async id => {
1186
+ const dir = await this.getRootComponentDirByRootId(this.workspace.rootComponentsPath, id);
1187
+ await _fsExtra().default.mkdirp(dir);
1188
+ }));
1189
+ await (0, _workspace().linkPkgsToRootComponents)({
1190
+ rootComponentsPath: this.workspace.rootComponentsPath,
1191
+ workspacePath: this.workspace.path
1192
+ }, compDirMap.components.map(component => this.dependencyResolver.getPackageName(component)));
1193
+ }
1194
+ async getRootComponentDirByRootId(rootComponentsPath, rootComponentId) {
1195
+ // Root directories for local envs and apps are created without their version number.
1196
+ // This is done in order to avoid changes to the lockfile after such components are tagged.
1197
+ const id = this.workspace.hasId(rootComponentId) ? rootComponentId.toStringWithoutVersion() : rootComponentId.toString();
1198
+ return (0, _workspace().getRootComponentDir)(rootComponentsPath, id);
1199
+ }
1200
+
1201
+ /**
1202
+ * Generate a filter to pass to the installer
1203
+ * This will filter deps which are come from remotes which defined in scope.json
1204
+ * those components comes from local remotes, usually doesn't have a package in a registry
1205
+ * so no reason to try to install them (it will fail)
1206
+ */
1207
+ async generateFilterFnForDepsFromLocalRemote() {
1208
+ const remotes = await this.workspace.scope.getRemoteScopes();
1209
+ const reg = await this.dependencyResolver.getRegistries();
1210
+ const packageScopes = Object.keys(reg.scopes);
1211
+ return dependencyList => {
1212
+ const filtered = dependencyList.filter(dep => {
1213
+ if (!(dep instanceof _dependencyResolver().ComponentDependency)) {
1214
+ return true;
1215
+ }
1216
+ if (remotes.isHub(dep.componentId.scope)) {
1217
+ return true;
1218
+ }
1219
+ if (packageScopes.some(scope => dep.packageName.startsWith(`@${scope}/`))) {
1220
+ return true;
1221
+ }
1222
+ return false;
1223
+ });
1224
+ return filtered;
1225
+ };
1226
+ }
1227
+ async getComponentsDirectory(ids) {
1228
+ const components = ids.length ? await this.workspace.getMany(ids) : await this.workspace.list(undefined, {
1229
+ loadSeedersAsAspects: false
1230
+ });
1231
+ return _component().ComponentMap.as(components, component => this.workspace.componentDir(component.id));
1232
+ }
1233
+ async onRootAspectAddedSubscriber(_aspectId, inWs) {
1234
+ if (!inWs) {
1235
+ await this.install();
1236
+ }
1237
+ }
1238
+ async onAspectsResolveSubscriber(aspectComponents) {
1239
+ let needLink = false;
1240
+ let needInstall = false;
1241
+ const promises = aspectComponents.map(async aspectComponent => {
1242
+ const aspectIdStr = aspectComponent.id.toString();
1243
+ if (this.visitedAspects.has(aspectIdStr)) return;
1244
+ this.visitedAspects.add(aspectIdStr);
1245
+ const packagePath = await this.workspace.getComponentPackagePath(aspectComponent);
1246
+ const exists = await (0, _fsExtra().pathExists)(packagePath);
1247
+ if (!exists) {
1248
+ const inWs = await this.workspace.hasId(aspectComponent.id);
1249
+ if (inWs) {
1250
+ needLink = true;
1251
+ } else {
1252
+ needInstall = true;
1253
+ }
1254
+ }
1255
+ });
1256
+ await Promise.all(promises);
1257
+ if (needInstall) {
1258
+ await this.install();
1259
+ return;
1260
+ }
1261
+ if (needLink) {
1262
+ await this.link();
1263
+ }
1264
+ }
1265
+ async onComponentChange(component) {
1266
+ const isEnv = this.envs.isEnv(component);
1267
+ if (isEnv) {
1268
+ await this.reloadEnvs([component.id]);
1269
+ }
1270
+ }
1271
+ static async provider([dependencyResolver, workspace, loggerExt, variants, cli, compiler, issues, envs, app, ipcEvents, generator, wsConfigFiles, aspectLoader, bundler, ui], _, [preLinkSlot, preInstallSlot, postInstallSlot], harmony) {
1272
+ const logger = loggerExt.createLogger(_install().InstallAspect.id);
1273
+ const installExt = new InstallMain(dependencyResolver, logger, workspace, variants, compiler, envs, wsConfigFiles, aspectLoader, app, generator, preLinkSlot, preInstallSlot, postInstallSlot, ipcEvents, harmony);
1274
+ ipcEvents.registerGotEventSlot(async eventName => {
1275
+ if (eventName !== 'onPostInstall') return;
1276
+ logger.debug('got onPostInstall event, clear workspace and all components cache');
1277
+ await workspace.clearCache();
1278
+ await installExt.reloadMovedEnvs();
1279
+ await (0, _pMapSeries().default)(postInstallSlot.values(), fn => fn());
1280
+ });
1281
+ if (issues) {
1282
+ issues.registerAddComponentsIssues(installExt.addDuplicateComponentAndPackageIssue.bind(installExt));
1283
+ }
1284
+ generator.registerOnComponentCreate(installExt.onComponentCreate.bind(installExt));
1285
+ const commands = [new (_install2().default)(installExt, workspace, logger), new (_uninstall().default)(installExt), new (_update().default)(installExt), new (_link().LinkCommand)(installExt, workspace, logger)];
1286
+ // For now do not automate installation during aspect resolving
1287
+ // workspace.registerOnAspectsResolve(installExt.onAspectsResolveSubscriber.bind(installExt));
1288
+ if (workspace) {
1289
+ workspace.registerOnRootAspectAdded(installExt.onRootAspectAddedSubscriber.bind(installExt));
1290
+ workspace.registerOnComponentChange(installExt.onComponentChange.bind(installExt));
1291
+ }
1292
+ installExt.registerPostInstall(async () => {
1293
+ if (!ui.getUIServer()) {
1294
+ return;
1295
+ }
1296
+ const components = await workspace.list();
1297
+ await bundler.addNewDevServers(components);
1298
+ });
1299
+ cli.register(...commands);
1300
+ return installExt;
1301
+ }
1302
+ async handleExternalPackageManagerPrompt() {
1303
+ this.logger.clearStatusLine();
1304
+
1305
+ // Display a colorful and informative message
1306
+ this.logger.console(_chalk().default.cyan('\nšŸ“¦ External Package Manager Mode Detected'));
1307
+ this.logger.console(_chalk().default.gray('Your workspace is configured to use external package managers (npm, yarn, pnpm).'));
1308
+ this.logger.console(_chalk().default.gray('Running "bit install" is not available in this mode.\n'));
1309
+ const question = _chalk().default.bold("Would you like to switch to Bit's package manager for dependency management? [yes(y)/no(n)]");
1310
+ const shouldSwitchToBitPM = await (0, _yesno().default)({
1311
+ question
1312
+ });
1313
+ if (!shouldSwitchToBitPM) {
1314
+ throw new Error('External package manager mode is enabled. Please use your preferred package manager (npm, yarn, pnpm) to install dependencies instead of "bit install".');
1315
+ }
1316
+
1317
+ // User chose to switch to Bit's package manager
1318
+ await this.disableExternalPackageManagerMode();
1319
+ }
1320
+ async disableExternalPackageManagerMode() {
1321
+ try {
1322
+ // Get the workspace config
1323
+ const workspaceConfig = this.workspace.getWorkspaceConfig();
1324
+
1325
+ // Remove externalPackageManager property and restore default settings
1326
+ const depResolverExt = workspaceConfig.extensions.findExtension('teambit.dependencies/dependency-resolver');
1327
+ if (depResolverExt?.config.externalPackageManager) {
1328
+ delete depResolverExt.config.externalPackageManager;
1329
+ }
1330
+ if (depResolverExt) {
1331
+ depResolverExt.config.rootComponent = true;
1332
+ }
1333
+
1334
+ // Enable workspace config write
1335
+ const workspaceConfigFilesExt = workspaceConfig.extensions.findExtension('teambit.workspace/workspace-config-files');
1336
+ if (workspaceConfigFilesExt) {
1337
+ workspaceConfigFilesExt.config.enableWorkspaceConfigWrite = true;
1338
+ }
1339
+
1340
+ // Remove postInstall script from package.json (preserve user's existing scripts)
1341
+ await this.removePostInstallScript();
1342
+
1343
+ // Write the updated config
1344
+ await workspaceConfig.write();
1345
+ this.logger.console(_chalk().default.green('āœ“ Successfully switched to Bit package manager mode'));
1346
+ } catch (error) {
1347
+ this.logger.console(_chalk().default.red('āœ— Failed to switch to Bit package manager mode'));
1348
+ throw error;
1349
+ }
1350
+ }
1351
+ async removePostInstallScript() {
1352
+ try {
1353
+ const packageJsonFile = await _component2().PackageJsonFile.load(this.workspace.path);
1354
+ if (!packageJsonFile.fileExist) {
1355
+ return;
1356
+ }
1357
+
1358
+ // Only remove our specific postInstall script, preserve user's custom scripts
1359
+ if (packageJsonFile.packageJsonObject.scripts?.postinstall === 'bit link && bit compile') {
1360
+ delete packageJsonFile.packageJsonObject.scripts.postinstall;
1361
+
1362
+ // Clean up empty scripts object
1363
+ if (Object.keys(packageJsonFile.packageJsonObject.scripts).length === 0) {
1364
+ delete packageJsonFile.packageJsonObject.scripts;
1365
+ }
1366
+ await packageJsonFile.write();
1367
+ }
1368
+ } catch {
1369
+ this.logger.console(_chalk().default.yellow('⚠ Warning: Could not remove postInstall script from package.json'));
1370
+ }
1371
+ }
1372
+ }
1373
+ exports.InstallMain = InstallMain;
1374
+ _defineProperty(InstallMain, "slots", [_harmony().Slot.withType(), _harmony().Slot.withType(), _harmony().Slot.withType()]);
1375
+ _defineProperty(InstallMain, "dependencies", [_dependencyResolver().DependencyResolverAspect, _workspace2().WorkspaceAspect, _logger().LoggerAspect, _variants().VariantsAspect, _cli().CLIAspect, _compiler().CompilerAspect, _issues().IssuesAspect, _envs().EnvsAspect, _application().ApplicationAspect, _ipcEvents().IpcEventsAspect, _generator().GeneratorAspect, _workspaceConfigFiles().WorkspaceConfigFilesAspect, _aspectLoader().AspectLoaderAspect, _bundler().BundlerAspect, _ui().UIAspect]);
1376
+ _defineProperty(InstallMain, "runtime", _cli().MainRuntime);
1377
+ function hasComponentsFromWorkspaceInMissingDeps({
1378
+ componentDirectoryMap,
1379
+ manifests
1380
+ }) {
1381
+ const missingDeps = new Set(componentDirectoryMap.toArray().map(([{
1382
+ state
1383
+ }]) => {
1384
+ const issue = state.issues.getIssue(_componentIssues().IssuesClasses.MissingPackagesDependenciesOnFs);
1385
+ if (!issue) return [];
1386
+ return issue.data.map(d => d.missingPackages).flat();
1387
+ }).flat());
1388
+ return Object.values(manifests).some(({
1389
+ name
1390
+ }) => name && missingDeps.has(name));
1391
+ }
1392
+ _install().InstallAspect.addRuntime(InstallMain);
1393
+ var _default = exports.default = InstallMain;
1394
+ function manifestsHash(manifests) {
1395
+ // We don't care if the type of the dependency changes as it doesn't change the node_modules structure
1396
+ const depsByProjectPaths = (0, _lodash().mapValues)(manifests, manifest => _objectSpread(_objectSpread({}, manifest.devDependencies), manifest.dependencies));
1397
+ return (0, _objectHash().default)(depsByProjectPaths);
1398
+ }
1399
+
1400
+ //# sourceMappingURL=install.main.runtime.js.map