@teambit/workspace 1.0.106 → 1.0.108

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 (86) hide show
  1. package/aspects-merger.ts +319 -0
  2. package/bit-map.ts +277 -0
  3. package/build-graph-from-fs.ts +188 -0
  4. package/build-graph-ids-from-fs.ts +216 -0
  5. package/capsule.cmd.ts +217 -0
  6. package/constants.ts +1 -0
  7. package/dist/aspects-merger.js +13 -22
  8. package/dist/aspects-merger.js.map +1 -1
  9. package/dist/bit-map.d.ts +1 -1
  10. package/dist/build-graph-from-fs.d.ts +2 -2
  11. package/dist/build-graph-from-fs.js +1 -2
  12. package/dist/build-graph-from-fs.js.map +1 -1
  13. package/dist/build-graph-ids-from-fs.js +1 -1
  14. package/dist/build-graph-ids-from-fs.js.map +1 -1
  15. package/dist/capsule.cmd.d.ts +2 -2
  16. package/dist/capsule.cmd.js +1 -2
  17. package/dist/capsule.cmd.js.map +1 -1
  18. package/dist/component-config-file/component-config-file.d.ts +2 -2
  19. package/dist/component-tree.widget.d.ts +2 -2
  20. package/dist/eject-conf.cmd.d.ts +2 -2
  21. package/dist/envs-subcommands/envs-replace.cmd.d.ts +1 -1
  22. package/dist/envs-subcommands/envs-set.cmd.d.ts +1 -1
  23. package/dist/envs-subcommands/envs-unset.cmd.d.ts +1 -1
  24. package/dist/envs-subcommands/envs-update.cmd.d.ts +1 -1
  25. package/dist/filter.d.ts +1 -1
  26. package/dist/filter.js +1 -1
  27. package/dist/filter.js.map +1 -1
  28. package/dist/merge-conflict-file.d.ts +1 -1
  29. package/dist/merge-conflict-file.js +1 -2
  30. package/dist/merge-conflict-file.js.map +1 -1
  31. package/dist/on-component-events.d.ts +6 -6
  32. package/dist/{preview-1703505948637.js → preview-1703647408454.js} +2 -2
  33. package/dist/scope-subcommands/scope-set.cmd.d.ts +1 -1
  34. package/dist/ui/workspace/use-workspace.d.ts +8 -8
  35. package/dist/ui/workspace/use-workspace.js +7 -18
  36. package/dist/ui/workspace/use-workspace.js.map +1 -1
  37. package/dist/ui/workspace/workspace-model.d.ts +3 -3
  38. package/dist/ui/workspace/workspace-overview/workspace-overview.d.ts +2 -2
  39. package/dist/ui/workspace/workspace-overview/workspace-overview.js +1 -2
  40. package/dist/ui/workspace/workspace-overview/workspace-overview.js.map +1 -1
  41. package/dist/ui/workspace/workspace-provider.d.ts +3 -3
  42. package/dist/ui/workspace/workspace.d.ts +3 -3
  43. package/dist/workspace-aspects-loader.d.ts +3 -3
  44. package/dist/workspace-aspects-loader.js +7 -11
  45. package/dist/workspace-aspects-loader.js.map +1 -1
  46. package/dist/workspace-component/comp-files.d.ts +3 -3
  47. package/dist/workspace-component/component-status.d.ts +3 -3
  48. package/dist/workspace-component/workspace-component-loader.d.ts +5 -5
  49. package/dist/workspace-component/workspace-component-loader.js +31 -28
  50. package/dist/workspace-component/workspace-component-loader.js.map +1 -1
  51. package/dist/workspace.composition.d.ts +2 -2
  52. package/dist/workspace.d.ts +6 -6
  53. package/dist/workspace.graphql.d.ts +2 -2
  54. package/dist/workspace.graphql.js +2 -4
  55. package/dist/workspace.graphql.js.map +1 -1
  56. package/dist/workspace.js +16 -23
  57. package/dist/workspace.js.map +1 -1
  58. package/dist/workspace.provider.d.ts +12 -12
  59. package/dist/workspace.provider.js +8 -11
  60. package/dist/workspace.provider.js.map +1 -1
  61. package/dist/workspace.ui.drawer.d.ts +1 -1
  62. package/dist/workspace.ui.drawer.js +5 -6
  63. package/dist/workspace.ui.drawer.js.map +1 -1
  64. package/dist/workspace.ui.runtime.d.ts +1 -1
  65. package/dist/workspace.ui.runtime.js +2 -8
  66. package/dist/workspace.ui.runtime.js.map +1 -1
  67. package/eject-conf.cmd.ts +57 -0
  68. package/filter.ts +139 -0
  69. package/index.ts +22 -0
  70. package/merge-conflict-file.ts +129 -0
  71. package/on-component-events.ts +24 -0
  72. package/package.json +39 -46
  73. package/pattern.cmd.ts +53 -0
  74. package/tsconfig.json +16 -21
  75. package/types/asset.d.ts +15 -3
  76. package/types.ts +71 -0
  77. package/use.cmd.ts +25 -0
  78. package/workspace-aspects-loader.ts +885 -0
  79. package/workspace-component/workspace-component-loader.ts +25 -16
  80. package/workspace-section.ts +14 -0
  81. package/workspace.aspect.ts +9 -0
  82. package/workspace.graphql.ts +133 -0
  83. package/workspace.main.runtime.ts +56 -0
  84. package/workspace.provider.ts +282 -0
  85. package/workspace.ts +2014 -0
  86. package/workspace.ui-root.ts +65 -0
@@ -185,9 +185,10 @@ export class WorkspaceComponentLoader {
185
185
  const groupedByIsCoreEnvs = groupBy(allIds, (id) => {
186
186
  return this.envs.isCoreEnv(id.toStringWithoutVersion());
187
187
  });
188
- await this.populateScopeAndExtensionsCache(groupedByIsCoreEnvs.false || [], workspaceScopeIdsMap);
188
+ const nonCoreEnvs = groupedByIsCoreEnvs.false || [];
189
+ await this.populateScopeAndExtensionsCache(nonCoreEnvs, workspaceScopeIdsMap);
189
190
  const allExtIds: Map<string, ComponentID> = new Map();
190
- groupedByIsCoreEnvs.false.forEach((id) => {
191
+ nonCoreEnvs.forEach((id) => {
191
192
  const idStr = id.toString();
192
193
  const fromCache = this.componentsExtensionsCache.get(idStr);
193
194
  if (!fromCache || !fromCache.extensions) {
@@ -203,7 +204,7 @@ export class WorkspaceComponentLoader {
203
204
  await this.populateScopeAndExtensionsCache(allExtCompIds || [], workspaceScopeIdsMap);
204
205
 
205
206
  const allExtIdsStr = allExtCompIds.map((id) => id.toString());
206
- const groupedByIsExtOfAnother = groupBy(groupedByIsCoreEnvs.false, (id) => {
207
+ const groupedByIsExtOfAnother = groupBy(nonCoreEnvs, (id) => {
207
208
  return allExtIdsStr.includes(id.toString());
208
209
  });
209
210
  const extIdsFromTheList = (groupedByIsExtOfAnother.true || []).map((id) => id.toString());
@@ -228,7 +229,7 @@ export class WorkspaceComponentLoader {
228
229
 
229
230
  const groupsToHandle = [
230
231
  // Always load first core envs
231
- { ids: groupedByIsCoreEnvs.true || [], core: true, aspects: true, seeders: false },
232
+ { ids: groupedByIsCoreEnvs.true || [], core: true, aspects: true, seeders: true },
232
233
  { ids: extsNotFromTheList || [], core: false, aspects: true, seeders: false },
233
234
  ...layerdExtGroups,
234
235
  { ids: groupedByIsExtOfAnother.false || [], core: false, aspects: false, seeders: true },
@@ -281,20 +282,20 @@ export class WorkspaceComponentLoader {
281
282
  // We don't want to ignore version here, as we do want to load different extensions with same id but different versions here
282
283
  const mergedExtensions = ExtensionDataList.mergeConfigs(allExtensions, false);
283
284
  await this.workspace.loadComponentsExtensions(mergedExtensions);
284
- const withAspects = await pMap(components, (component) => this.executeLoadSlot(component), {
285
+ let wsComponentsWithAspects = workspaceComponents;
286
+ // if (loadOpts.seeders) {
287
+ wsComponentsWithAspects = await pMap(workspaceComponents, (component) => this.executeLoadSlot(component), {
285
288
  concurrency: concurrentComponentsLimit(),
286
289
  });
290
+ await this.warnAboutMisconfiguredEnvs(wsComponentsWithAspects);
291
+ // }
292
+
293
+ const withAspects = wsComponentsWithAspects.concat(scopeComponents);
287
294
 
288
- // const withAspects = await Promise.all(
289
- // components.map((component) => {
290
- // return this.executeLoadSlot(component);
291
- // })
292
- // );
293
- await this.warnAboutMisconfiguredEnvs(withAspects);
294
295
  // It's important to load the workspace components as aspects here
295
296
  // otherwise the envs from the workspace won't be loaded at time
296
297
  // so we will get wrong dependencies from component who uses envs from the workspace
297
- if (loadOpts.loadSeedersAsAspects) {
298
+ if (loadOpts.loadSeedersAsAspects || (loadOpts.core && loadOpts.aspects)) {
298
299
  await this.loadCompsAsAspects(workspaceComponents.concat(scopeComponents), {
299
300
  loadApps: true,
300
301
  loadEnvs: true,
@@ -625,11 +626,19 @@ export class WorkspaceComponentLoader {
625
626
 
626
627
  clearComponentCache(id: ComponentID) {
627
628
  const idStr = id.toString();
628
- for (const cacheKey of this.componentsCache.keys()) {
629
- if (cacheKey === idStr || cacheKey.startsWith(`${idStr}:`)) {
630
- this.componentsCache.delete(cacheKey);
629
+ const cachesToClear = [
630
+ this.componentsCache,
631
+ this.scopeComponentsCache,
632
+ this.componentsExtensionsCache,
633
+ this.componentLoadedSelfAsAspects,
634
+ ];
635
+ cachesToClear.forEach((cache) => {
636
+ for (const cacheKey of cache.keys()) {
637
+ if (cacheKey === idStr || cacheKey.startsWith(`${idStr}:`)) {
638
+ cache.delete(cacheKey);
639
+ }
631
640
  }
632
- }
641
+ });
633
642
  }
634
643
 
635
644
  private async loadOne(id: ComponentID, consumerComponent?: ConsumerComponent, loadOpts?: ComponentLoadOptions) {
@@ -0,0 +1,14 @@
1
+ // export class WorkspaceSection {
2
+ // constructor(
3
+ // readonly route: string
4
+ // ) {}
5
+
6
+ // toRoute() {
7
+ // return {
8
+ // path: this.toRoute
9
+ // children:
10
+ // };
11
+ // }
12
+ // };
13
+
14
+ // export interface WorkspaceSection {}
@@ -0,0 +1,9 @@
1
+ import { Aspect } from '@teambit/harmony';
2
+
3
+ export const WorkspaceAspect = Aspect.create({
4
+ id: 'teambit.workspace/workspace',
5
+ dependencies: [],
6
+ defaultConfig: {},
7
+ });
8
+
9
+ export default WorkspaceAspect;
@@ -0,0 +1,133 @@
1
+ import { GraphqlMain } from '@teambit/graphql';
2
+ import gql from 'graphql-tag';
3
+
4
+ import { ComponentAdded, ComponentChanged, ComponentRemoved, Workspace } from './workspace';
5
+ import { WorkspaceComponent } from './workspace-component';
6
+
7
+ export default (workspace: Workspace, graphql: GraphqlMain) => {
8
+ return {
9
+ typeDefs: gql`
10
+ type ModifyInfo {
11
+ # is the component modified.
12
+ hasModifiedFiles: Boolean
13
+
14
+ # the component has Modified Dependencies
15
+ hasModifiedDependencies: Boolean
16
+ }
17
+
18
+ type ComponentStatus {
19
+ # component is pending to be tagged automatically.
20
+ modifyInfo: ModifyInfo
21
+
22
+ # is the new component new.
23
+ isNew: Boolean
24
+
25
+ # is the component deleted from the workspace.
26
+ isDeleted: Boolean
27
+
28
+ # is the component staged.
29
+ isStaged: Boolean
30
+
31
+ # does the component exists in the workspace.
32
+ isInWorkspace: Boolean
33
+
34
+ # does the component exists in the scope.
35
+ isInScope: Boolean
36
+
37
+ # does the component is outdated (pending for update).
38
+ isOutdated: Boolean
39
+ }
40
+
41
+ extend type Component {
42
+ status: ComponentStatus
43
+ }
44
+
45
+ type Issue {
46
+ type: String!
47
+ description: String!
48
+ solution: String
49
+ data: String
50
+ }
51
+
52
+ extend type Component {
53
+ # the count of errors in component in workspace
54
+ issuesCount: Int
55
+ issues: [Issue]
56
+ }
57
+
58
+ type Workspace {
59
+ name: String
60
+ path: String
61
+ icon: String
62
+ components(offset: Int, limit: Int): [Component]
63
+ getComponent(id: String!): Component
64
+ }
65
+
66
+ type Subscription {
67
+ componentAdded: ComponentAdded
68
+ componentChanged: ComponentChanged
69
+ componentRemoved: ComponentRemoved
70
+ }
71
+
72
+ type ComponentAdded {
73
+ component: Component
74
+ }
75
+
76
+ type ComponentChanged {
77
+ component: Component
78
+ }
79
+
80
+ type ComponentRemoved {
81
+ componentIds: [ComponentID]
82
+ }
83
+
84
+ type Query {
85
+ workspace: Workspace
86
+ }
87
+ `,
88
+ resolvers: {
89
+ Subscription: {
90
+ componentAdded: {
91
+ subscribe: () => graphql.pubsub.asyncIterator(ComponentAdded),
92
+ },
93
+ componentChanged: {
94
+ subscribe: () => graphql.pubsub.asyncIterator(ComponentChanged),
95
+ },
96
+ componentRemoved: {
97
+ subscribe: () => graphql.pubsub.asyncIterator(ComponentRemoved),
98
+ },
99
+ },
100
+ Component: {
101
+ status: async (wsComponent: WorkspaceComponent) => {
102
+ return wsComponent.getStatus();
103
+ },
104
+ issuesCount: (wsComponent: WorkspaceComponent): number => {
105
+ return wsComponent.getIssues()?.count || 0;
106
+ },
107
+ issues: (wsComponent: WorkspaceComponent) => {
108
+ return wsComponent.getIssues()?.toObjectWithDataAsString();
109
+ },
110
+ },
111
+ Workspace: {
112
+ path: (ws) => ws.path,
113
+ name: (ws) => ws.name,
114
+ icon: (ws) => ws.icon,
115
+ components: async (ws: Workspace, { offset, limit }: { offset: number; limit: number }) => {
116
+ return ws.list({ offset, limit });
117
+ },
118
+ getComponent: async (ws: Workspace, { id }: { id: string }) => {
119
+ try {
120
+ const componentID = await ws.resolveComponentId(id);
121
+ const component = await ws.get(componentID);
122
+ return component;
123
+ } catch (error: any) {
124
+ return null;
125
+ }
126
+ },
127
+ },
128
+ Query: {
129
+ workspace: () => workspace,
130
+ },
131
+ },
132
+ };
133
+ };
@@ -0,0 +1,56 @@
1
+ import { PubsubAspect } from '@teambit/pubsub';
2
+ import { AspectLoaderAspect } from '@teambit/aspect-loader';
3
+ import { BundlerAspect } from '@teambit/bundler';
4
+ import { CLIAspect, MainRuntime } from '@teambit/cli';
5
+ import { ComponentAspect } from '@teambit/component';
6
+ import { DependencyResolverAspect } from '@teambit/dependency-resolver';
7
+ import { EnvsAspect } from '@teambit/envs';
8
+ import { GraphqlAspect } from '@teambit/graphql';
9
+ import { Slot } from '@teambit/harmony';
10
+ import { IsolatorAspect } from '@teambit/isolator';
11
+ import { LoggerAspect } from '@teambit/logger';
12
+ import { ScopeAspect } from '@teambit/scope';
13
+ import { UIAspect } from '@teambit/ui';
14
+ import { VariantsAspect } from '@teambit/variants';
15
+ import GlobalConfigAspect from '@teambit/global-config';
16
+
17
+ import { EXT_NAME } from './constants';
18
+ import { OnComponentAdd, OnComponentChange, OnComponentRemove, OnComponentLoad } from './on-component-events';
19
+ import { WorkspaceAspect } from './workspace.aspect';
20
+ import workspaceProvider, { OnAspectsResolve, OnBitmapChange, OnRootAspectAdded } from './workspace.provider';
21
+
22
+ export const WorkspaceMain = {
23
+ name: EXT_NAME,
24
+ runtime: MainRuntime,
25
+ dependencies: [
26
+ PubsubAspect,
27
+ CLIAspect,
28
+ ScopeAspect,
29
+ ComponentAspect,
30
+ IsolatorAspect,
31
+ DependencyResolverAspect,
32
+ VariantsAspect,
33
+ LoggerAspect,
34
+ GraphqlAspect,
35
+ UIAspect,
36
+ BundlerAspect,
37
+ AspectLoaderAspect,
38
+ EnvsAspect,
39
+ GlobalConfigAspect,
40
+ ],
41
+ slots: [
42
+ Slot.withType<OnComponentLoad>(),
43
+ Slot.withType<OnComponentChange>(),
44
+ Slot.withType<OnComponentAdd>(),
45
+ Slot.withType<OnComponentRemove>(),
46
+ Slot.withType<OnAspectsResolve>(),
47
+ Slot.withType<OnRootAspectAdded>(),
48
+ Slot.withType<OnBitmapChange>(),
49
+ ],
50
+ provider: workspaceProvider,
51
+ defineRuntime: 'browser',
52
+ };
53
+
54
+ WorkspaceAspect.addRuntime(WorkspaceMain);
55
+
56
+ export default WorkspaceMain;
@@ -0,0 +1,282 @@
1
+ import { PubsubMain } from '@teambit/pubsub';
2
+ import type { AspectLoaderMain } from '@teambit/aspect-loader';
3
+ import { BundlerMain } from '@teambit/bundler';
4
+ import { CLIMain, CommandList } from '@teambit/cli';
5
+ import { DependencyResolverAspect, DependencyResolverMain } from '@teambit/dependency-resolver';
6
+ import type { ComponentMain, Component } from '@teambit/component';
7
+ import { EnvsMain } from '@teambit/envs';
8
+ import { GraphqlMain } from '@teambit/graphql';
9
+ import { Harmony, SlotRegistry } from '@teambit/harmony';
10
+ import { IsolatorMain } from '@teambit/isolator';
11
+ import { LoggerMain } from '@teambit/logger';
12
+ import type { ScopeMain } from '@teambit/scope';
13
+ import { UiMain } from '@teambit/ui';
14
+ import type { VariantsMain } from '@teambit/variants';
15
+ import { Consumer, loadConsumerIfExist } from '@teambit/legacy/dist/consumer';
16
+ import ConsumerComponent from '@teambit/legacy/dist/consumer/component';
17
+ import type { ComponentConfigLoadOptions } from '@teambit/legacy/dist/consumer/config';
18
+ import { ExtensionDataList } from '@teambit/legacy/dist/consumer/config/extension-data';
19
+ import LegacyComponentLoader, { ComponentLoadOptions } from '@teambit/legacy/dist/consumer/component/component-loader';
20
+ import { ComponentID } from '@teambit/component-id';
21
+ import { GlobalConfigMain } from '@teambit/global-config';
22
+ import { EXT_NAME } from './constants';
23
+ import EjectConfCmd from './eject-conf.cmd';
24
+ import { OnComponentLoad, OnComponentAdd, OnComponentChange, OnComponentRemove } from './on-component-events';
25
+ import { WorkspaceExtConfig } from './types';
26
+ import { Workspace } from './workspace';
27
+ import getWorkspaceSchema from './workspace.graphql';
28
+ import { WorkspaceUIRoot } from './workspace.ui-root';
29
+ import { CapsuleCmd, CapsuleCreateCmd, CapsuleDeleteCmd, CapsuleListCmd } from './capsule.cmd';
30
+ import { EnvsSetCmd } from './envs-subcommands/envs-set.cmd';
31
+ import { EnvsUnsetCmd } from './envs-subcommands/envs-unset.cmd';
32
+ import { PatternCommand } from './pattern.cmd';
33
+ import { EnvsReplaceCmd } from './envs-subcommands/envs-replace.cmd';
34
+ import { ScopeSetCmd } from './scope-subcommands/scope-set.cmd';
35
+ import { UseCmd } from './use.cmd';
36
+ import { EnvsUpdateCmd } from './envs-subcommands/envs-update.cmd';
37
+
38
+ export type WorkspaceDeps = [
39
+ PubsubMain,
40
+ CLIMain,
41
+ ScopeMain,
42
+ ComponentMain,
43
+ IsolatorMain,
44
+ DependencyResolverMain,
45
+ VariantsMain,
46
+ LoggerMain,
47
+ GraphqlMain,
48
+ UiMain,
49
+ BundlerMain,
50
+ AspectLoaderMain,
51
+ EnvsMain,
52
+ GlobalConfigMain
53
+ ];
54
+
55
+ export type OnComponentLoadSlot = SlotRegistry<OnComponentLoad>;
56
+
57
+ export type OnComponentChangeSlot = SlotRegistry<OnComponentChange>;
58
+
59
+ export type OnComponentAddSlot = SlotRegistry<OnComponentAdd>;
60
+
61
+ export type OnComponentRemoveSlot = SlotRegistry<OnComponentRemove>;
62
+
63
+ export type OnBitmapChange = () => Promise<void>;
64
+ export type OnBitmapChangeSlot = SlotRegistry<OnBitmapChange>;
65
+
66
+ export type OnAspectsResolve = (aspectsComponents: Component[]) => Promise<void>;
67
+ export type OnAspectsResolveSlot = SlotRegistry<OnAspectsResolve>;
68
+
69
+ export type OnRootAspectAdded = (aspectsId: ComponentID, inWs: boolean) => Promise<void>;
70
+ export type OnRootAspectAddedSlot = SlotRegistry<OnRootAspectAdded>;
71
+
72
+ export default async function provideWorkspace(
73
+ [
74
+ pubsub,
75
+ cli,
76
+ scope,
77
+ component,
78
+ isolator,
79
+ dependencyResolver,
80
+ variants,
81
+ loggerExt,
82
+ graphql,
83
+ ui,
84
+ bundler,
85
+ aspectLoader,
86
+ envs,
87
+ globalConfig,
88
+ ]: WorkspaceDeps,
89
+ config: WorkspaceExtConfig,
90
+ [
91
+ onComponentLoadSlot,
92
+ onComponentChangeSlot,
93
+ onComponentAddSlot,
94
+ onComponentRemoveSlot,
95
+ onAspectsResolveSlot,
96
+ onRootAspectAddedSlot,
97
+ onBitmapChangeSlot,
98
+ ]: [
99
+ OnComponentLoadSlot,
100
+ OnComponentChangeSlot,
101
+ OnComponentAddSlot,
102
+ OnComponentRemoveSlot,
103
+ OnAspectsResolveSlot,
104
+ OnRootAspectAddedSlot,
105
+ OnBitmapChangeSlot
106
+ ],
107
+ harmony: Harmony
108
+ ) {
109
+ const bitConfig: any = harmony.config.get('teambit.harmony/bit');
110
+ const consumer = await getConsumer(bitConfig.cwd);
111
+ if (!consumer) {
112
+ const capsuleCmd = getCapsulesCommands(isolator, scope, undefined);
113
+ cli.register(capsuleCmd);
114
+ return undefined;
115
+ }
116
+ // TODO: get the 'workspace' name in a better way
117
+ const logger = loggerExt.createLogger(EXT_NAME);
118
+ const workspace = new Workspace(
119
+ pubsub,
120
+ config,
121
+ consumer,
122
+ scope,
123
+ component,
124
+ dependencyResolver,
125
+ variants,
126
+ aspectLoader,
127
+ logger,
128
+ undefined,
129
+ harmony,
130
+ onComponentLoadSlot,
131
+ onComponentChangeSlot,
132
+ envs,
133
+ globalConfig,
134
+ onComponentAddSlot,
135
+ onComponentRemoveSlot,
136
+ onAspectsResolveSlot,
137
+ onRootAspectAddedSlot,
138
+ graphql,
139
+ onBitmapChangeSlot
140
+ );
141
+
142
+ const configMergeFile = workspace.getConflictMergeFile();
143
+ await configMergeFile.loadIfNeeded();
144
+
145
+ const getWorkspacePolicyFromPackageJson = () => {
146
+ const packageJson = workspace.consumer.packageJson?.packageJsonObject || {};
147
+ const policyFromPackageJson = dependencyResolver.getWorkspacePolicyFromPackageJson(packageJson);
148
+ return policyFromPackageJson;
149
+ };
150
+
151
+ const getWorkspacePolicyFromMergeConfig = () => {
152
+ const wsConfigMerge = workspace.getWorkspaceJsonConflictFromMergeConfig();
153
+ const policy = wsConfigMerge.data?.[DependencyResolverAspect.id]?.policy || {};
154
+ ['dependencies', 'peerDependencies'].forEach((depField) => {
155
+ if (!policy[depField]) return;
156
+ policy[depField] = policy[depField].reduce((acc, current) => {
157
+ acc[current.name] = current.version;
158
+ return acc;
159
+ }, {});
160
+ });
161
+ const wsPolicy = dependencyResolver.getWorkspacePolicyFromConfigObject(policy);
162
+ return wsPolicy;
163
+ };
164
+
165
+ const getRootPolicy = () => {
166
+ const pkgJsonPolicy = getWorkspacePolicyFromPackageJson();
167
+ const configMergePolicy = getWorkspacePolicyFromMergeConfig();
168
+ return dependencyResolver.mergeWorkspacePolices([pkgJsonPolicy, configMergePolicy]);
169
+ };
170
+
171
+ dependencyResolver.registerRootPolicy(getRootPolicy());
172
+
173
+ consumer.onCacheClear.push(() => workspace.clearCache());
174
+
175
+ LegacyComponentLoader.registerOnComponentLoadSubscriber(
176
+ async (legacyComponent: ConsumerComponent, opts?: ComponentLoadOptions) => {
177
+ if (opts?.originatedFromHarmony) return legacyComponent;
178
+ const id = await workspace.resolveComponentId(legacyComponent.id);
179
+ const newComponent = await workspace.get(id, legacyComponent, true, true, opts);
180
+ return newComponent.state._consumer;
181
+ }
182
+ );
183
+
184
+ ConsumerComponent.registerOnComponentConfigLoading(EXT_NAME, async (id, loadOpts: ComponentConfigLoadOptions) => {
185
+ const componentId = await workspace.resolveComponentId(id);
186
+ // We call here directly workspace.scope.get instead of workspace.get because part of the workspace get is loading consumer component
187
+ // which in turn run this event, which will make an infinite loop
188
+ // This component from scope here are only used for merging the extensions with the workspace components
189
+ const componentFromScope = await workspace.scope.get(componentId);
190
+ const { extensions } = await workspace.componentExtensions(componentId, componentFromScope, undefined, loadOpts);
191
+ const defaultScope = await workspace.componentDefaultScope(componentId);
192
+
193
+ const extensionsWithLegacyIdsP = extensions.map(async (extension) => {
194
+ const legacyEntry = extension.clone();
195
+ if (legacyEntry.extensionId) {
196
+ legacyEntry.newExtensionId = legacyEntry.extensionId;
197
+ }
198
+
199
+ return legacyEntry;
200
+ });
201
+ const extensionsWithLegacyIds = await Promise.all(extensionsWithLegacyIdsP);
202
+
203
+ return {
204
+ defaultScope,
205
+ extensions: ExtensionDataList.fromArray(extensionsWithLegacyIds),
206
+ };
207
+ });
208
+
209
+ const workspaceSchema = getWorkspaceSchema(workspace, graphql);
210
+ ui.registerUiRoot(new WorkspaceUIRoot(workspace, bundler));
211
+ ui.registerPreStart(async () => {
212
+ return workspace.setComponentPathsRegExps();
213
+ });
214
+ graphql.register(workspaceSchema);
215
+ const capsuleCmd = getCapsulesCommands(isolator, scope, workspace);
216
+ const commands: CommandList = [new EjectConfCmd(workspace), capsuleCmd, new UseCmd(workspace)];
217
+
218
+ commands.push(new PatternCommand(workspace));
219
+ cli.register(...commands);
220
+ component.registerHost(workspace);
221
+
222
+ cli.registerOnStart(async (_hasWorkspace: boolean, currentCommand: string) => {
223
+ if (currentCommand === 'mini-status' || currentCommand === 'ms') {
224
+ return; // mini-status should be super fast.
225
+ }
226
+ if (currentCommand === 'install') {
227
+ workspace.inInstallContext = true;
228
+ }
229
+ await workspace.importCurrentLaneIfMissing();
230
+ const loadAspectsOpts = {
231
+ runSubscribers: false,
232
+ skipDeps: !config.autoLoadAspectsDeps,
233
+ };
234
+ const aspects = await workspace.loadAspects(
235
+ aspectLoader.getNotLoadedConfiguredExtensions(),
236
+ undefined,
237
+ 'teambit.workspace/workspace (cli.registerOnStart)',
238
+ loadAspectsOpts
239
+ );
240
+ // clear aspect cache.
241
+ const componentIds = await workspace.resolveMultipleComponentIds(aspects);
242
+ componentIds.forEach((id) => {
243
+ workspace.clearComponentCache(id);
244
+ });
245
+ });
246
+
247
+ // add sub-commands "set" and "unset" to envs command.
248
+ const envsCommand = cli.getCommand('envs');
249
+ envsCommand?.commands?.push(new EnvsSetCmd(workspace)); // bit envs set
250
+ envsCommand?.commands?.push(new EnvsUnsetCmd(workspace)); // bit envs unset
251
+ envsCommand?.commands?.push(new EnvsReplaceCmd(workspace)); // bit envs replace
252
+ envsCommand?.commands?.push(new EnvsUpdateCmd(workspace)); // bit envs replace
253
+
254
+ // add sub-command "set" to scope command.
255
+ const scopeCommand = cli.getCommand('scope');
256
+ scopeCommand?.commands?.push(new ScopeSetCmd(workspace));
257
+
258
+ return workspace;
259
+ }
260
+
261
+ function getCapsulesCommands(isolator: IsolatorMain, scope: ScopeMain, workspace?: Workspace) {
262
+ const capsuleCmd = new CapsuleCmd(isolator, workspace, scope);
263
+ capsuleCmd.commands = [
264
+ new CapsuleListCmd(isolator, workspace, scope),
265
+ new CapsuleCreateCmd(workspace, scope, isolator),
266
+ new CapsuleDeleteCmd(isolator, scope, workspace),
267
+ ];
268
+ return capsuleCmd;
269
+ }
270
+
271
+ /**
272
+ * don't use loadConsumer() here, which throws ConsumerNotFound because some commands don't require
273
+ * the consumer to be available. such as, `bit init` or `bit list --remote`.
274
+ * most of the commands do need the consumer. the legacy commands that need the consumer throw an
275
+ * error when is missing. in the new/Harmony commands, such as `bis compile`, the workspace object
276
+ * is passed to the provider, so before using it, make sure it exists.
277
+ * keep in mind that you can't verify it in the provider itself, because the provider is running
278
+ * always for all commands before anything else is happening.
279
+ */
280
+ async function getConsumer(path?: string): Promise<Consumer | undefined> {
281
+ return loadConsumerIfExist(path);
282
+ }