@teambit/snapping 1.0.1235 → 1.0.1237

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.
@@ -194,12 +194,19 @@ function _dependencyResolver() {
194
194
  return data;
195
195
  }
196
196
  function _legacy6() {
197
- const data = require("@teambit/legacy.extension-data");
197
+ const data = require("@teambit/legacy.consumer-config");
198
198
  _legacy6 = function () {
199
199
  return data;
200
200
  };
201
201
  return data;
202
202
  }
203
+ function _legacy7() {
204
+ const data = require("@teambit/legacy.extension-data");
205
+ _legacy7 = function () {
206
+ return data;
207
+ };
208
+ return data;
209
+ }
203
210
  function _builder() {
204
211
  const data = require("@teambit/builder");
205
212
  _builder = function () {
@@ -312,9 +319,9 @@ function _application() {
312
319
  };
313
320
  return data;
314
321
  }
315
- function _legacy7() {
322
+ function _legacy8() {
316
323
  const data = require("@teambit/legacy.scope-api");
317
- _legacy7 = function () {
324
+ _legacy8 = function () {
318
325
  return data;
319
326
  };
320
327
  return data;
@@ -501,10 +508,10 @@ class SnappingMain {
501
508
  }
502
509
  async addAspectsFromConfigObject(component, configObject) {
503
510
  if (!configObject) return;
504
- _legacy6().ExtensionDataList.adjustEnvsOnConfigObject(configObject);
505
- const extensionsFromConfigObject = _legacy6().ExtensionDataList.fromConfigObject(configObject);
511
+ _legacy7().ExtensionDataList.adjustEnvsOnConfigObject(configObject);
512
+ const extensionsFromConfigObject = _legacy7().ExtensionDataList.fromConfigObject(configObject);
506
513
  const consumerComponent = component.state._consumer;
507
- const extensionDataList = _legacy6().ExtensionDataList.mergeConfigs([extensionsFromConfigObject, consumerComponent.extensions]).filterRemovedExtensions();
514
+ const extensionDataList = _legacy7().ExtensionDataList.mergeConfigs([extensionsFromConfigObject, consumerComponent.extensions]).filterRemovedExtensions();
508
515
 
509
516
  // Restore data fields from the original extensions after merging configs.
510
517
  // configObject contains only config (from the merged config result), it has no data.
@@ -525,6 +532,49 @@ class SnappingMain {
525
532
  const autoDeps = extensionsFromConfigObject.extractAutoDepsFromConfig();
526
533
  return autoDeps;
527
534
  }
535
+
536
+ /**
537
+ * re-calculate the dependencies policy of the component and its overrides from its config and env, the same way a
538
+ * workspace calculates them when it loads a component, rather than keeping the ones of the version it was loaded from.
539
+ * returns the policy and the overrides of the auto-detected dependencies (versions only, see
540
+ * ApplyOverrides.autoDetectOverrides), which include the deps of the merge-config, same as
541
+ * workspace.getAutoDetectOverrides().
542
+ */
543
+ async recalcDependenciesPolicy(component, componentsInSnap, mergeConfigAutoDeps) {
544
+ const legacyComponent = component.state._consumer;
545
+ const {
546
+ extensions
547
+ } = legacyComponent;
548
+ const depResolverExt = extensions.findCoreExtension(_dependencyResolver().DependencyResolverAspect.id);
549
+ // an env that defines its policy in code is loaded only when it changed: a changed env is a changed (or missing)
550
+ // extension, which mergeExtensionsData() reports as a data conflict (see loadAspectOnlyForIds). when it's not
551
+ // loaded, it didn't change, so the env part of the stored policy is still valid. (the other parts, such as the
552
+ // policies of aspects and the config, are calculated by mergeVariantPolicies() from the current config)
553
+ const storedPolicy = _dependencyResolver().VariantPolicy.parse(depResolverExt?.data.policy || []);
554
+ const storedEnvPolicy = storedPolicy.filter(entry => entry.source === 'env');
555
+ // an env.jsonc env that is snapped along (e.g. merged as well) has its policy in its new files, like a workspace
556
+ // that loads the env from its files. otherwise, the policy is read from the stored version of the env.
557
+ const envPolicy = (await this.dependencyResolver.getEnvPolicyFromComponents(extensions, componentsInSnap)) ?? (await this.dependencyResolver.getComponentEnvPolicyFromExtension(extensions, storedEnvPolicy));
558
+ // when the component is an env, its own policy (its own peers) is calculated from its env.jsonc or from the loaded
559
+ // env. same as above, an env that defines it in code and is not loaded didn't change, so the stored one is valid.
560
+ const envExtendsDeps = legacyComponent.dependencies.get();
561
+ const storedEnvOwnPolicy = storedPolicy.filter(entry => entry.source === 'env-own');
562
+ const isEnvOwnPolicyMissing = storedEnvOwnPolicy.length > 0 && !(await this.dependencyResolver.getPoliciesFromEnvForItself(component.id, legacyComponent.files, envExtendsDeps));
563
+ const policy = await this.dependencyResolver.mergeVariantPolicies(extensions, component.id, legacyComponent.files, envExtendsDeps,
564
+ // merged right after the env policy, same as mergeVariantPolicies() merges a calculated own policy
565
+ isEnvOwnPolicyMissing ? _dependencyResolver().VariantPolicy.mergePolices([envPolicy, storedEnvOwnPolicy]) : envPolicy);
566
+ // the "source" of each dependency in the dependency-resolver data is determined by this policy
567
+ if (depResolverExt) depResolverExt.data.policy = policy.serialize();
568
+ legacyComponent.overrides = new (_legacy6().ComponentOverrides)((0, _lodash().pickBy)(policy.toLegacyDepsOverrides(), val => !(0, _lodash().isEmpty)(val)));
569
+ const mergeConfigPolicy = _dependencyResolver().VariantPolicy.fromConfigObject(mergeConfigAutoDeps || {}, {
570
+ source: 'auto'
571
+ });
572
+ const autoDetectOverrides = _dependencyResolver().VariantPolicy.mergePolices([policy, mergeConfigPolicy]).toLegacyAutoDetectOverrides();
573
+ return {
574
+ policy,
575
+ autoDetectOverrides
576
+ };
577
+ }
528
578
  async snapFromScope(snapDataPerCompRaw, params) {
529
579
  if (this.workspace) {
530
580
  throw new (_bitError().BitError)(`unable to run this command from a workspace, please create a new bare-scope and run it from there`);
@@ -536,7 +586,7 @@ class SnappingMain {
536
586
  try {
537
587
  lane = await this.importer.importLaneObject(laneId);
538
588
  } catch (err) {
539
- if (err.constructor.name !== _legacy7().LaneNotFound.name) throw err;
589
+ if (err.constructor.name !== _legacy8().LaneNotFound.name) throw err;
540
590
  // if the lane is not found, it's probably because it's new. create a new lane.
541
591
  lane = await (0, _lanesModules().createLaneInScope)(laneId.name, this.scope, laneId.scope);
542
592
  // it's important to set the lane as new in scope.json. otherwise, later, when importing and the lane is loaded
@@ -628,13 +678,20 @@ class SnappingMain {
628
678
  });
629
679
  }
630
680
  const components = [...existingComponents, ...newComponents];
631
-
681
+ const autoDepsPerComp = new Map();
682
+ const addDepsToComp = (component, autoDetectOverrides) => (0, _generateCompFromScope().addDeps)(component, getSnapData(component.id), this.scope, this.deps, this.dependencyResolver, this, autoDepsPerComp.get(component), autoDetectOverrides);
632
683
  // this must be done before we load component aspects later on, because this updated deps may update aspects.
633
684
  await (0, _pMapSeries().default)(components, async component => {
634
685
  const snapData = getSnapData(component.id);
635
- const autoDeps = await this.addAspectsFromConfigObject(component, snapData.aspects);
686
+ autoDepsPerComp.set(component, await this.addAspectsFromConfigObject(component, snapData.aspects));
687
+ if (params.recalcDependencies) {
688
+ // the dependencies are added once the aspects are loaded, see below. only update the versions of aspects that
689
+ // are part of the snap (e.g. an env merged into the lane), so the correct versions get loaded.
690
+ await this.updateAspectsVersions(component, snapData.dependencies);
691
+ return;
692
+ }
636
693
  // adds explicitly defined dependencies and dependencies from envs/aspects (overrides)
637
- await (0, _generateCompFromScope().addDeps)(component, snapData, this.scope, this.deps, this.dependencyResolver, this, autoDeps);
694
+ await addDepsToComp(component);
638
695
  });
639
696
 
640
697
  // for new components these are not needed. coz when generating them we already add the aspects and the files.
@@ -670,9 +727,22 @@ class SnappingMain {
670
727
  } = params;
671
728
  const compsToLoadAspects = loadAspectOnlyForIds ? components.filter(c => loadAspectOnlyForIds.hasWithoutVersion(c.id)) : components;
672
729
  await this.scope.loadManyCompsAspects(compsToLoadAspects);
730
+ const policyPerComp = new Map();
731
+ if (params.recalcDependencies) {
732
+ // the config (and with it, the env) may differ from the one stored in the version the components were loaded
733
+ // from. now that the env is loaded, the dependencies are calculated according to it.
734
+ await (0, _pMapSeries().default)(components, async component => {
735
+ const {
736
+ policy,
737
+ autoDetectOverrides
738
+ } = await this.recalcDependenciesPolicy(component, components, autoDepsPerComp.get(component));
739
+ policyPerComp.set(component, policy);
740
+ await addDepsToComp(component, autoDetectOverrides);
741
+ });
742
+ }
673
743
 
674
744
  // this is similar to what happens in the workspace. the "onLoad" is running and populating the "data" of the aspects.
675
- await (0, _pMapSeries().default)(compsToLoadAspects, async comp => this.scope.executeOnCompAspectReCalcSlot(comp));
745
+ await (0, _pMapSeries().default)(compsToLoadAspects, async comp => this.scope.executeOnCompAspectReCalcSlot(comp, policyPerComp.get(comp)));
676
746
  const ids = _componentId().ComponentIdList.fromArray(allCompIds);
677
747
  const shouldTag = Boolean(params.tag);
678
748
  const makeVersionParams = _objectSpread(_objectSpread({}, params), {}, {
@@ -1460,8 +1530,11 @@ another option, in case this dependency is not in main yet is to remove all refe
1460
1530
  const updatedIds = _componentId().ComponentIdList.fromArray([...currentBitIds, ...dependencies]);
1461
1531
  const componentIdStr = component.id.toString();
1462
1532
  const legacyComponent = component.state._consumer;
1463
- const deps = [...legacyComponent.dependencies.get(), ...legacyComponent.devDependencies.get()];
1464
- const dependenciesList = this.dependencyResolver.getDependencies(component);
1533
+ const deps = [...legacyComponent.dependencies.get(), ...legacyComponent.devDependencies.get(), ...legacyComponent.peerDependencies.get()];
1534
+ // peers can be hidden, and they're part of the legacy peers
1535
+ const dependenciesList = this.dependencyResolver.getDependencies(component, {
1536
+ includeHidden: true
1537
+ });
1465
1538
  deps.forEach(dep => {
1466
1539
  const updatedBitId = updatedIds.searchWithoutVersion(dep.id);
1467
1540
  if (updatedBitId) {
@@ -1484,6 +1557,22 @@ another option, in case this dependency is not in main yet is to remove all refe
1484
1557
  * 2. save all dependencies data from the legacy into DependencyResolver aspect.
1485
1558
  */
1486
1559
  async UpdateDepsAspectsSaveIntoDepsResolver(component, updatedIds) {
1560
+ await this.updateAspectsVersions(component, updatedIds);
1561
+ const dependenciesListSerialized = (await this.dependencyResolver.extractDepsFromLegacy(component)).serialize();
1562
+ const extId = _dependencyResolver().DependencyResolverAspect.id;
1563
+ const data = {
1564
+ dependencies: dependenciesListSerialized
1565
+ };
1566
+ const existingExtension = component.config.extensions.findExtension(extId);
1567
+ if (existingExtension) {
1568
+ // Only merge top level of extension data
1569
+ Object.assign(existingExtension.data, data);
1570
+ return;
1571
+ }
1572
+ const extension = new (_legacy7().ExtensionDataEntry)(undefined, undefined, extId, undefined, data);
1573
+ component.config.extensions.push(extension);
1574
+ }
1575
+ async updateAspectsVersions(component, updatedIds) {
1487
1576
  const legacyComponent = component.state._consumer;
1488
1577
  legacyComponent.extensions.forEach(ext => {
1489
1578
  const extId = ext.extensionId;
@@ -1497,19 +1586,6 @@ another option, in case this dependency is not in main yet is to remove all refe
1497
1586
  }
1498
1587
  });
1499
1588
  component.state.aspects = await this.scope.createAspectListFromExtensionDataList(legacyComponent.extensions);
1500
- const dependenciesListSerialized = (await this.dependencyResolver.extractDepsFromLegacy(component)).serialize();
1501
- const extId = _dependencyResolver().DependencyResolverAspect.id;
1502
- const data = {
1503
- dependencies: dependenciesListSerialized
1504
- };
1505
- const existingExtension = component.config.extensions.findExtension(extId);
1506
- if (existingExtension) {
1507
- // Only merge top level of extension data
1508
- Object.assign(existingExtension.data, data);
1509
- return;
1510
- }
1511
- const extension = new (_legacy6().ExtensionDataEntry)(undefined, undefined, extId, undefined, data);
1512
- component.config.extensions.push(extension);
1513
1589
  }
1514
1590
 
1515
1591
  /**