@teambit/envs 0.0.0-3e44e878fae3f5f31fce2dc240a57a798e67137e

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 (108) hide show
  1. package/context/context.ts +55 -0
  2. package/context/index.ts +1 -0
  3. package/dist/context/context.d.ts +44 -0
  4. package/dist/context/context.js +61 -0
  5. package/dist/context/context.js.map +1 -0
  6. package/dist/context/index.d.ts +1 -0
  7. package/dist/context/index.js +20 -0
  8. package/dist/context/index.js.map +1 -0
  9. package/dist/env-definition.d.ts +41 -0
  10. package/dist/env-definition.js +57 -0
  11. package/dist/env-definition.js.map +1 -0
  12. package/dist/env-interface.d.ts +4 -0
  13. package/dist/env-interface.js +3 -0
  14. package/dist/env-interface.js.map +1 -0
  15. package/dist/env-jsonc.detector.d.ts +5 -0
  16. package/dist/env-jsonc.detector.js +26 -0
  17. package/dist/env-jsonc.detector.js.map +1 -0
  18. package/dist/env-service-list.d.ts +35 -0
  19. package/dist/env-service-list.js +37 -0
  20. package/dist/env-service-list.js.map +1 -0
  21. package/dist/env.composition.d.ts +1 -0
  22. package/dist/env.composition.js +29 -0
  23. package/dist/env.composition.js.map +1 -0
  24. package/dist/env.fragment.d.ts +17 -0
  25. package/dist/env.fragment.js +48 -0
  26. package/dist/env.fragment.js.map +1 -0
  27. package/dist/env.plugin.d.ts +20 -0
  28. package/dist/env.plugin.js +92 -0
  29. package/dist/env.plugin.js.map +1 -0
  30. package/dist/environment.d.ts +201 -0
  31. package/dist/environment.js +17 -0
  32. package/dist/environment.js.map +1 -0
  33. package/dist/environments.aspect.d.ts +2 -0
  34. package/dist/environments.aspect.js +18 -0
  35. package/dist/environments.aspect.js.map +1 -0
  36. package/dist/environments.graphql.d.ts +3 -0
  37. package/dist/environments.graphql.js +36 -0
  38. package/dist/environments.graphql.js.map +1 -0
  39. package/dist/environments.main.runtime.d.ts +366 -0
  40. package/dist/environments.main.runtime.js +1160 -0
  41. package/dist/environments.main.runtime.js.map +1 -0
  42. package/dist/envs.cmd.d.ts +51 -0
  43. package/dist/envs.cmd.js +153 -0
  44. package/dist/envs.cmd.js.map +1 -0
  45. package/dist/envs.docs.mdx +8 -0
  46. package/dist/esm.mjs +13 -0
  47. package/dist/exceptions/env-not-configured-for-component.d.ts +4 -0
  48. package/dist/exceptions/env-not-configured-for-component.js +24 -0
  49. package/dist/exceptions/env-not-configured-for-component.js.map +1 -0
  50. package/dist/exceptions/env-not-found-in-runtime.d.ts +5 -0
  51. package/dist/exceptions/env-not-found-in-runtime.js +22 -0
  52. package/dist/exceptions/env-not-found-in-runtime.js.map +1 -0
  53. package/dist/exceptions/env-not-found.d.ts +6 -0
  54. package/dist/exceptions/env-not-found.js +27 -0
  55. package/dist/exceptions/env-not-found.js.map +1 -0
  56. package/dist/exceptions/index.d.ts +3 -0
  57. package/dist/exceptions/index.js +46 -0
  58. package/dist/exceptions/index.js.map +1 -0
  59. package/dist/index.d.ts +16 -0
  60. package/dist/index.js +128 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/preview-1752254355761.js +7 -0
  63. package/dist/runtime/env-runtime.d.ts +41 -0
  64. package/dist/runtime/env-runtime.js +36 -0
  65. package/dist/runtime/env-runtime.js.map +1 -0
  66. package/dist/runtime/envs-execution-result.d.ts +18 -0
  67. package/dist/runtime/envs-execution-result.js +56 -0
  68. package/dist/runtime/envs-execution-result.js.map +1 -0
  69. package/dist/runtime/index.d.ts +2 -0
  70. package/dist/runtime/index.js +33 -0
  71. package/dist/runtime/index.js.map +1 -0
  72. package/dist/runtime/runtime.d.ts +49 -0
  73. package/dist/runtime/runtime.js +117 -0
  74. package/dist/runtime/runtime.js.map +1 -0
  75. package/dist/services/concrete-service.d.ts +8 -0
  76. package/dist/services/concrete-service.js +3 -0
  77. package/dist/services/concrete-service.js.map +1 -0
  78. package/dist/services/index.d.ts +4 -0
  79. package/dist/services/index.js +89 -0
  80. package/dist/services/index.js.map +1 -0
  81. package/dist/services/service-handler-context.d.ts +30 -0
  82. package/dist/services/service-handler-context.js +44 -0
  83. package/dist/services/service-handler-context.js.map +1 -0
  84. package/dist/services/service-handler.d.ts +18 -0
  85. package/dist/services/service-handler.js +25 -0
  86. package/dist/services/service-handler.js.map +1 -0
  87. package/dist/services/service.d.ts +66 -0
  88. package/dist/services/service.js +3 -0
  89. package/dist/services/service.js.map +1 -0
  90. package/env.composition.tsx +7 -0
  91. package/envs.docs.mdx +8 -0
  92. package/esm.mjs +13 -0
  93. package/exceptions/env-not-configured-for-component.ts +10 -0
  94. package/exceptions/env-not-found-in-runtime.ts +7 -0
  95. package/exceptions/env-not-found.ts +15 -0
  96. package/exceptions/index.ts +3 -0
  97. package/package.json +90 -0
  98. package/runtime/env-runtime.ts +31 -0
  99. package/runtime/envs-execution-result.ts +46 -0
  100. package/runtime/index.ts +2 -0
  101. package/runtime/runtime.ts +100 -0
  102. package/services/concrete-service.ts +8 -0
  103. package/services/index.ts +13 -0
  104. package/services/service-handler-context.ts +40 -0
  105. package/services/service-handler.ts +41 -0
  106. package/services/service.ts +79 -0
  107. package/types/asset.d.ts +41 -0
  108. package/types/style.d.ts +42 -0
@@ -0,0 +1,1160 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.EnvsMain = exports.DEFAULT_ENV = void 0;
7
+ function _pLocate() {
8
+ const data = _interopRequireDefault(require("p-locate"));
9
+ _pLocate = function () {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ function _commentJson() {
15
+ const data = require("comment-json");
16
+ _commentJson = function () {
17
+ return data;
18
+ };
19
+ return data;
20
+ }
21
+ function _cli() {
22
+ const data = require("@teambit/cli");
23
+ _cli = function () {
24
+ return data;
25
+ };
26
+ return data;
27
+ }
28
+ function _component() {
29
+ const data = require("@teambit/component");
30
+ _component = function () {
31
+ return data;
32
+ };
33
+ return data;
34
+ }
35
+ function _graphql() {
36
+ const data = require("@teambit/graphql");
37
+ _graphql = function () {
38
+ return data;
39
+ };
40
+ return data;
41
+ }
42
+ function _issues() {
43
+ const data = require("@teambit/issues");
44
+ _issues = function () {
45
+ return data;
46
+ };
47
+ return data;
48
+ }
49
+ function _pMapSeries() {
50
+ const data = _interopRequireDefault(require("p-map-series"));
51
+ _pMapSeries = function () {
52
+ return data;
53
+ };
54
+ return data;
55
+ }
56
+ function _componentIssues() {
57
+ const data = require("@teambit/component-issues");
58
+ _componentIssues = function () {
59
+ return data;
60
+ };
61
+ return data;
62
+ }
63
+ function _harmony() {
64
+ const data = require("@teambit/harmony");
65
+ _harmony = function () {
66
+ return data;
67
+ };
68
+ return data;
69
+ }
70
+ function _logger() {
71
+ const data = require("@teambit/logger");
72
+ _logger = function () {
73
+ return data;
74
+ };
75
+ return data;
76
+ }
77
+ function _bitError() {
78
+ const data = require("@teambit/bit-error");
79
+ _bitError = function () {
80
+ return data;
81
+ };
82
+ return data;
83
+ }
84
+ function _toolboxArray() {
85
+ const data = require("@teambit/toolbox.array.duplications-finder");
86
+ _toolboxArray = function () {
87
+ return data;
88
+ };
89
+ return data;
90
+ }
91
+ function _lodash() {
92
+ const data = require("lodash");
93
+ _lodash = function () {
94
+ return data;
95
+ };
96
+ return data;
97
+ }
98
+ function _worker() {
99
+ const data = require("@teambit/worker");
100
+ _worker = function () {
101
+ return data;
102
+ };
103
+ return data;
104
+ }
105
+ function _componentId() {
106
+ const data = require("@teambit/component-id");
107
+ _componentId = function () {
108
+ return data;
109
+ };
110
+ return data;
111
+ }
112
+ function _environments() {
113
+ const data = require("./environments.aspect");
114
+ _environments = function () {
115
+ return data;
116
+ };
117
+ return data;
118
+ }
119
+ function _environments2() {
120
+ const data = require("./environments.graphql");
121
+ _environments2 = function () {
122
+ return data;
123
+ };
124
+ return data;
125
+ }
126
+ function _runtime() {
127
+ const data = require("./runtime");
128
+ _runtime = function () {
129
+ return data;
130
+ };
131
+ return data;
132
+ }
133
+ function _envDefinition() {
134
+ const data = require("./env-definition");
135
+ _envDefinition = function () {
136
+ return data;
137
+ };
138
+ return data;
139
+ }
140
+ function _envServiceList() {
141
+ const data = require("./env-service-list");
142
+ _envServiceList = function () {
143
+ return data;
144
+ };
145
+ return data;
146
+ }
147
+ function _envs() {
148
+ const data = require("./envs.cmd");
149
+ _envs = function () {
150
+ return data;
151
+ };
152
+ return data;
153
+ }
154
+ function _env() {
155
+ const data = require("./env.fragment");
156
+ _env = function () {
157
+ return data;
158
+ };
159
+ return data;
160
+ }
161
+ function _exceptions() {
162
+ const data = require("./exceptions");
163
+ _exceptions = function () {
164
+ return data;
165
+ };
166
+ return data;
167
+ }
168
+ function _env2() {
169
+ const data = require("./env.plugin");
170
+ _env2 = function () {
171
+ return data;
172
+ };
173
+ return data;
174
+ }
175
+ function _envJsonc() {
176
+ const data = require("./env-jsonc.detector");
177
+ _envJsonc = function () {
178
+ return data;
179
+ };
180
+ return data;
181
+ }
182
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
183
+ 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; }
184
+ 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; }
185
+ 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; }
186
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
187
+ 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); }
188
+ /**
189
+ * The resolved env jsonc is the env jsonc after it was resolved from all the parent envs
190
+ */
191
+
192
+ const DEFAULT_ENV = exports.DEFAULT_ENV = 'teambit.harmony/node';
193
+ class EnvsMain {
194
+ /**
195
+ * icon of the extension.
196
+ */
197
+ icon() {
198
+ return `<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
199
+ <circle cx="25" cy="25" r="20"/>
200
+ </svg>`;
201
+ }
202
+ constructor(
203
+ /**
204
+ * environments extension configuration.
205
+ */
206
+ config,
207
+ /**
208
+ * harmony context.
209
+ */
210
+ harmony,
211
+ /**
212
+ * slot for allowing extensions to register new environment.
213
+ */
214
+ envSlot, logger, servicesRegistry, componentMain, loggerMain, workerMain, envJsoncMergeCustomizerSlot, envJsoncResolverSlot) {
215
+ this.config = config;
216
+ this.harmony = harmony;
217
+ this.envSlot = envSlot;
218
+ this.logger = logger;
219
+ this.servicesRegistry = servicesRegistry;
220
+ this.componentMain = componentMain;
221
+ this.loggerMain = loggerMain;
222
+ this.workerMain = workerMain;
223
+ this.envJsoncMergeCustomizerSlot = envJsoncMergeCustomizerSlot;
224
+ this.envJsoncResolverSlot = envJsoncResolverSlot;
225
+ /**
226
+ * Envs that are failed to load
227
+ */
228
+ _defineProperty(this, "failedToLoadEnvs", new Set());
229
+ /**
230
+ * Extensions that are failed to load
231
+ * We use this as sometime when we couldn't load an extension we don't know if it's an env or not
232
+ * We should ideally take it from the aspect loader aspect, but right now the aspect loader is using envs
233
+ */
234
+ _defineProperty(this, "failedToLoadExt", new Set());
235
+ /**
236
+ * Ids of envs (not neccesrraly loaded successfully)
237
+ */
238
+ _defineProperty(this, "envIds", new Set());
239
+ _defineProperty(this, "alreadyShownWarning", {});
240
+ _defineProperty(this, "coreAspectIds", []);
241
+ }
242
+
243
+ /**
244
+ * creates a new runtime environments for a set of components.
245
+ */
246
+ async createEnvironment(components) {
247
+ return this.createRuntime(components);
248
+ }
249
+ setCoreAspectIds(ids) {
250
+ this.coreAspectIds = ids;
251
+ }
252
+ isCoreAspect(id) {
253
+ return this.coreAspectIds.includes(id);
254
+ }
255
+
256
+ /**
257
+ *
258
+ * @param id
259
+ */
260
+ /**
261
+ * This function adds an extension ID to a set of failed to load extensions.
262
+ * This mostly used by the aspect loader to add such issues
263
+ * Then it is used to hide different errors that are caused by the same issue.
264
+ * @param {string} id - string - represents the unique identifier of an extension that failed to load.
265
+ */
266
+ addFailedToLoadEnvs(id) {
267
+ this.failedToLoadEnvs.add(id);
268
+ this.envIds.add(id);
269
+ }
270
+ addFailedToLoadExt(id) {
271
+ this.failedToLoadExt.add(id);
272
+ if (this.envIds.has(id)) {
273
+ this.addFailedToLoadEnvs(id);
274
+ }
275
+ }
276
+ resetFailedToLoadEnvs() {
277
+ this.failedToLoadEnvs.clear();
278
+ this.failedToLoadExt.clear();
279
+ }
280
+ getFailedToLoadEnvs() {
281
+ const failedToLoadEnvs = Array.from(this.failedToLoadEnvs);
282
+ // Add all extensions which are also envs
283
+ for (const extId of this.failedToLoadExt) {
284
+ if (this.envIds.has(extId)) {
285
+ failedToLoadEnvs.push(extId);
286
+ }
287
+ }
288
+ return (0, _lodash().uniq)(failedToLoadEnvs);
289
+ }
290
+
291
+ /**
292
+ * get the configured default env.
293
+ */
294
+ getDefaultEnv() {
295
+ const defaultEnv = this.envSlot.get(DEFAULT_ENV);
296
+ if (!defaultEnv) throw new Error('default env must be set.');
297
+ return new (_envDefinition().EnvDefinition)(DEFAULT_ENV, defaultEnv);
298
+ }
299
+ getCoreEnvsIds() {
300
+ return ['teambit.harmony/aspect', 'teambit.react/react', 'teambit.harmony/node', 'teambit.react/react-native', 'teambit.html/html', 'teambit.mdx/mdx', 'teambit.envs/env', 'teambit.mdx/readme', 'teambit.harmony/bit-custom-aspect'];
301
+ }
302
+
303
+ /**
304
+ * compose a new environment from a list of environment transformers.
305
+ */
306
+ compose(targetEnv, envTransformers) {
307
+ const a = envTransformers.reduce((acc, transformer) => {
308
+ acc = transformer(acc);
309
+ return acc;
310
+ }, targetEnv);
311
+ return a;
312
+ }
313
+
314
+ /**
315
+ * create an env transformer which overrides specific env properties.
316
+ */
317
+ override(propsToOverride) {
318
+ return env => {
319
+ return this.merge(propsToOverride, env);
320
+ };
321
+ }
322
+
323
+ /**
324
+ * compose two environments into one.
325
+ */
326
+ merge(targetEnv, sourceEnv) {
327
+ const allNames = new Set();
328
+ const keys = ['icon', 'name', 'description'];
329
+ for (let o = sourceEnv; o !== Object.prototype; o = Object.getPrototypeOf(o)) {
330
+ for (const name of Object.getOwnPropertyNames(o)) {
331
+ allNames.add(name);
332
+ }
333
+ }
334
+ allNames.forEach(key => {
335
+ const fn = sourceEnv[key];
336
+ if (targetEnv[key]) return;
337
+ if (keys.includes(key)) targetEnv[key] = fn;
338
+ if (!fn || !fn.bind) {
339
+ return;
340
+ }
341
+ targetEnv[key] = fn.bind(sourceEnv);
342
+ });
343
+ return targetEnv;
344
+ }
345
+
346
+ /**
347
+ * This function checks if an environment manifest file exists in a given component or set of legacy files.
348
+ * @param {Component} [envComponent] - A component object that represents an environment. It contains information about
349
+ * the files and directories that make up the environment.
350
+ * @param {SourceFile[]} [legacyFiles] - An optional array of SourceFile objects representing the files in the legacy
351
+ * file system. If this parameter is not provided, the function will attempt to retrieve the files from the envComponent
352
+ * parameter.
353
+ * @returns a boolean value indicating whether an `env.jsonc` or `env.json` file exists in the `files` array of either
354
+ * the `envComponent` object or the `legacyFiles` array. If neither `envComponent` nor `legacyFiles` are provided, the
355
+ * function returns `undefined`.
356
+ */
357
+ hasEnvManifest(envComponent, legacyFiles) {
358
+ if (!envComponent && !legacyFiles) return undefined;
359
+ // @ts-ignore
360
+ const files = legacyFiles || envComponent.filesystem.files;
361
+ const envJson = files.find(file => {
362
+ return file.relative === 'env.jsonc' || file.relative === 'env.json';
363
+ });
364
+ if (!envJson) return false;
365
+ return true;
366
+ }
367
+ getEnvManifest(envComponent) {
368
+ const data = this.getEnvData(envComponent);
369
+ if (!data) return undefined;
370
+ return data.resolvedEnvJsonc;
371
+ }
372
+ async getOrCalculateEnvManifest(component, legacyFiles, envExtendsDeps) {
373
+ try {
374
+ return this.getEnvManifest(component) || (await this.calculateEnvManifest(component, legacyFiles, envExtendsDeps));
375
+ } catch {
376
+ return this.calculateEnvManifest(component);
377
+ }
378
+ }
379
+ async calculateEnvManifest(envComponent, legacyFiles, envExtendsDeps) {
380
+ // TODO: maybe throw an error here?
381
+ if (!envComponent && !legacyFiles) return undefined;
382
+ // @ts-ignore
383
+ const files = legacyFiles || envComponent.filesystem.files;
384
+ const envJson = files.find(file => {
385
+ return file.relative === 'env.jsonc' || file.relative === 'env.json';
386
+ });
387
+ if (!envJson) return undefined;
388
+ const object = (0, _commentJson().parse)(envJson.contents.toString('utf8'), undefined, true);
389
+ if (!object.extends) return object;
390
+ const resolvedObject = await this.recursivelyMergeWithParentManifest(object, envExtendsDeps);
391
+ return resolvedObject;
392
+ }
393
+ async recursivelyMergeWithParentManifest(object, envExtendsDeps) {
394
+ if (!object.extends) return object;
395
+ const parentEnvId = object.extends;
396
+ const resolver = this.getAllRegisteredEnvJsoncResolvers()[0];
397
+ const parentObject = await resolver(parentEnvId, envExtendsDeps);
398
+ const mergedObject = this.mergeEnvManifests(parentObject, object);
399
+ if (mergedObject.extends) {
400
+ return this.recursivelyMergeWithParentManifest(mergedObject);
401
+ }
402
+ return mergedObject;
403
+ }
404
+ mergeEnvManifests(parent, child) {
405
+ let merged = {};
406
+ const mergeCustomizer = this.getAllRegisteredEnvJsoncCustomizers();
407
+ for (const customizer of mergeCustomizer) {
408
+ const oneMerged = customizer(parent, child);
409
+ merged = _objectSpread(_objectSpread({}, merged), oneMerged);
410
+ }
411
+ // This is important to make sure we won't keep the extends from the child
412
+ delete child.extends;
413
+ // Take extends specifically from the parent so we can propagate it to the next parent
414
+ if (parent.extends) {
415
+ merged.extends = parent.extends;
416
+ }
417
+ return merged;
418
+ }
419
+ async hasEnvManifestById(envId, requesting) {
420
+ const component = await this.getEnvComponentByEnvId(envId, requesting);
421
+ return this.hasEnvManifest(component);
422
+ }
423
+ getEnvData(component) {
424
+ let envsData = component.state.aspects.get(_environments().EnvsAspect.id);
425
+ if (!envsData) {
426
+ // TODO: remove this once we re-export old components used to store the data here
427
+ envsData = component.state.aspects.get('teambit.workspace/workspace');
428
+ }
429
+ if (!envsData) throw new Error(`env was not configured on component ${component.id.toString()}`);
430
+ return envsData.data;
431
+ }
432
+
433
+ /**
434
+ * Return the id of the env as configured in the envs data (without version by default)
435
+ * The reason it's not contain version by default is that we want to take the version from the aspect defined on the component itself
436
+ * As this version is stay up to date during tagging the env along with the component
437
+ * @param component
438
+ * @param ignoreVersion
439
+ */
440
+ getEnvIdFromEnvsData(component, ignoreVersion = true) {
441
+ const envsData = this.getEnvData(component);
442
+ if (!envsData) return undefined;
443
+ const rawEnvId = envsData.id;
444
+ if (!rawEnvId) return undefined;
445
+ if (!ignoreVersion) return rawEnvId;
446
+ const envIdWithoutVersion = _componentId().ComponentID.fromString(rawEnvId).toStringWithoutVersion();
447
+ return envIdWithoutVersion;
448
+ }
449
+
450
+ /**
451
+ * get the env id of the given component.
452
+ */
453
+ getEnvId(component) {
454
+ const envIdFromEnvData = this.getEnvIdFromEnvsData(component);
455
+ if (!envIdFromEnvData) {
456
+ // This should never happen
457
+ throw new Error(`no env found for ${component.id.toString()}`);
458
+ }
459
+ const withVersion = this.resolveEnv(component, envIdFromEnvData);
460
+ const withVersionMatch = this.envSlot.toArray().find(([envId]) => {
461
+ return withVersion?.toString() === envId;
462
+ });
463
+ const withVersionMatchId = withVersionMatch?.[0];
464
+ if (withVersionMatchId) return withVersionMatchId;
465
+
466
+ // Handle core envs
467
+ const exactMatch = this.envSlot.toArray().find(([envId]) => {
468
+ return envIdFromEnvData === envId;
469
+ });
470
+ const exactMatchId = exactMatch?.[0];
471
+ if (exactMatchId) return exactMatchId;
472
+ if (!withVersion) throw new (_exceptions().EnvNotConfiguredForComponent)(envIdFromEnvData, component.id.toString());
473
+ return withVersion.toString();
474
+ }
475
+ isUsingCoreEnv(component) {
476
+ const envId = this.getEnvId(component);
477
+ return this.isCoreEnv(envId);
478
+ }
479
+ isCoreEnv(envId) {
480
+ return this.getCoreEnvsIds().includes(envId);
481
+ }
482
+
483
+ /**
484
+ * get the env of the given component.
485
+ * In case you are asking for the env during on load you should use calculateEnv instead
486
+ */
487
+ getEnv(component) {
488
+ const id = this.getEnvId(component);
489
+ const envDef = this.getEnvDefinitionByStringId(id);
490
+ if (envDef) {
491
+ return envDef;
492
+ }
493
+ // Do not allow a non existing env
494
+ throw new (_exceptions().EnvNotFound)(id, component.id.toString());
495
+ }
496
+
497
+ /**
498
+ * get the env component of the given component.
499
+ */
500
+ async getEnvComponent(component) {
501
+ const envId = this.getEnvId(component);
502
+ return this.getEnvComponentByEnvId(envId, component.id.toString());
503
+ }
504
+
505
+ /**
506
+ * get the env component by the env id.
507
+ */
508
+ async getEnvComponentByEnvId(envId, requesting) {
509
+ const host = this.componentMain.getHost();
510
+ const newId = await host.resolveComponentId(envId);
511
+ const envComponent = await host.get(newId);
512
+ if (!envComponent) {
513
+ throw new (_bitError().BitError)(`can't load env. env id is ${envId} used by component ${requesting || 'unknown'}`);
514
+ }
515
+ return envComponent;
516
+ }
517
+
518
+ /**
519
+ * get the env of the given component.
520
+ * This will try to use the regular getEnv but fallback to the calculate env (in case you are using it during on load)
521
+ * This is safe to be used on onLoad as well
522
+ */
523
+ getOrCalculateEnv(component) {
524
+ try {
525
+ return this.getEnv(component);
526
+ } catch {
527
+ return this.calculateEnv(component);
528
+ }
529
+ }
530
+ getOrCalculateEnvId(component) {
531
+ try {
532
+ const idStr = this.getEnvId(component);
533
+ return Promise.resolve(_componentId().ComponentID.fromString(idStr));
534
+ } catch {
535
+ return this.calculateEnvId(component);
536
+ }
537
+ }
538
+
539
+ /**
540
+ * get an environment Descriptor.
541
+ */
542
+ getDescriptor(component) {
543
+ const envsData = this.getEnvData(component);
544
+ envsData.id = this.resolveEnv(component, envsData.id)?.toString() || envsData.id;
545
+ return envsData;
546
+ }
547
+ async calcDescriptor(component, opts = {}) {
548
+ const componentDescriptor = await this.getComponentEnvDescriptor(component, opts);
549
+ if (!componentDescriptor) return undefined;
550
+ const envComponentSelfDescriptor = await this.getEnvSelfDescriptor(component);
551
+ // const resolvedEnvJsonc = await this.calculateEnvManifest(component);
552
+ const result = componentDescriptor;
553
+ if (envComponentSelfDescriptor) {
554
+ // @ts-ignore
555
+ result.self = envComponentSelfDescriptor;
556
+ }
557
+ // if (resolvedEnvJsonc) {
558
+ // // @ts-ignore
559
+ // result.resolvedEnvJsonc = resolvedEnvJsonc;
560
+ // }
561
+ return result;
562
+ }
563
+
564
+ /**
565
+ * Get env descriptor from the env itself if the component is an env
566
+ * This will be empty for regular component, and will only contain data for env themself
567
+ */
568
+ async getEnvSelfDescriptor(envComponent) {
569
+ // !important calculate only on the env itself.
570
+ if (!this.isEnvRegistered(envComponent.id.toString())) {
571
+ return undefined;
572
+ }
573
+ const envDef = this.getEnvFromComponent(envComponent);
574
+ if (!envDef) return undefined;
575
+ const rawServices = this.getServices(envDef);
576
+ const services = rawServices.toObject();
577
+ // const selfDescriptor = (await this.getEnvDescriptorFromEnvDef(envDef)) || {};
578
+ const selfDescriptor = await this.getEnvDescriptorFromEnvDef(envDef);
579
+ if (!selfDescriptor) return undefined;
580
+ return _objectSpread(_objectSpread({}, selfDescriptor), {}, {
581
+ services
582
+ });
583
+ }
584
+
585
+ /**
586
+ * Get env descriptor from the env that a given component is using
587
+ */
588
+ async getComponentEnvDescriptor(component, opts = {}) {
589
+ const envDef = this.calculateEnv(component, opts);
590
+ return this.getEnvDescriptorFromEnvDef(envDef);
591
+ }
592
+ async getEnvDescriptorFromEnvDef(envDef) {
593
+ if (!envDef.env.__getDescriptor || typeof envDef.env.__getDescriptor !== 'function') {
594
+ return undefined;
595
+ }
596
+ const systemDescriptor = await envDef.env.__getDescriptor();
597
+ return {
598
+ type: systemDescriptor.type,
599
+ // Make sure to store the env id in the data without the version
600
+ // The version should always come from the aspect id configured on the component
601
+ id: envDef.id.split('@')[0],
602
+ name: envDef.name,
603
+ icon: envDef.env.icon,
604
+ description: envDef.description
605
+ };
606
+ }
607
+ resolveEnv(component, id) {
608
+ const matchedEntry = component.state.aspects.entries.find(aspectEntry => {
609
+ return id === aspectEntry.id.toString() || id === aspectEntry.id.toString({
610
+ ignoreVersion: true
611
+ });
612
+ });
613
+ return matchedEntry?.id;
614
+ }
615
+
616
+ /**
617
+ * This used to calculate the actual env during the component load.
618
+ * Do not use it to get the env (use getEnv instead)
619
+ * This should be used only during on load
620
+ */
621
+ async calculateEnvId(component) {
622
+ // Search first for env configured via envs aspect itself
623
+ const envIdFromEnvsConfig = this.getEnvIdFromEnvsConfig(component);
624
+ // if (!envIdFromEnvsConfig) return this.getDefaultEnv();
625
+ const envIdFromEnvsConfigWithoutVersion = envIdFromEnvsConfig ? _componentId().ComponentID.fromString(envIdFromEnvsConfig).toStringWithoutVersion() : undefined;
626
+ if (envIdFromEnvsConfig && this.isCoreEnv(envIdFromEnvsConfig)) {
627
+ return _componentId().ComponentID.fromString(envIdFromEnvsConfig);
628
+ }
629
+
630
+ // in some cases we have the id configured in the teambit.envs/envs but without the version
631
+ // in such cases we won't find it in the slot
632
+ // we search in the component aspect list a matching aspect which is match the id from the teambit.envs/envs
633
+ if (envIdFromEnvsConfigWithoutVersion) {
634
+ const matchedEntry = component.state.aspects.entries.find(aspectEntry => {
635
+ return envIdFromEnvsConfigWithoutVersion === aspectEntry.id.toString() || envIdFromEnvsConfigWithoutVersion === aspectEntry.id.toString({
636
+ ignoreVersion: true
637
+ });
638
+ });
639
+ if (matchedEntry?.id) return matchedEntry?.id;
640
+ }
641
+
642
+ // in case there is no config in teambit.envs/envs search the aspects for the first env that registered as env
643
+ let ids = [];
644
+ component.state.aspects.entries.forEach(aspectEntry => {
645
+ ids.push(aspectEntry.id.toString());
646
+ // ids.push(aspectEntry.id.toString({ ignoreVersion: true }));
647
+ });
648
+ ids = (0, _lodash().uniq)(ids);
649
+ const envId = await this.findFirstEnv(ids);
650
+ const finalId = envId || this.getDefaultEnv().id;
651
+ return _componentId().ComponentID.fromString(finalId);
652
+ }
653
+
654
+ /**
655
+ * This used to calculate the actual env during the component load.
656
+ * Do not use it to get the env (use getEnv instead)
657
+ * This should be used only during on load
658
+ */
659
+ calculateEnv(component, opts = {}) {
660
+ // Search first for env configured via envs aspect itself
661
+ const envIdFromEnvsConfig = this.getEnvIdFromEnvsConfig(component);
662
+ let envIdFromEnvsConfigWithoutVersion;
663
+ if (envIdFromEnvsConfig) {
664
+ envIdFromEnvsConfigWithoutVersion = _componentId().ComponentID.fromString(envIdFromEnvsConfig).toStringWithoutVersion();
665
+ const envDef = this.getEnvDefinitionByStringId(envIdFromEnvsConfigWithoutVersion);
666
+ if (envDef) {
667
+ this.envIds.add(envDef.id);
668
+ return envDef;
669
+ }
670
+ }
671
+
672
+ // in some cases we have the id configured in the teambit.envs/envs but without the version
673
+ // in such cases we won't find it in the slot
674
+ // we search in the component aspect list a matching aspect which is match the id from the teambit.envs/envs
675
+ if (envIdFromEnvsConfigWithoutVersion) {
676
+ const matchedEntry = component.state.aspects.entries.find(aspectEntry => {
677
+ return envIdFromEnvsConfigWithoutVersion === aspectEntry.id.toString() || envIdFromEnvsConfigWithoutVersion === aspectEntry.id.toString({
678
+ ignoreVersion: true
679
+ });
680
+ });
681
+ if (matchedEntry) {
682
+ // during the tag process, the version in the aspect-entry-id is changed and is not the
683
+ // same as it was when it registered to the slot.
684
+ const envDef = this.getEnvDefinitionById(matchedEntry.id);
685
+ if (envDef) {
686
+ this.envIds.add(envDef.id);
687
+ return envDef;
688
+ }
689
+ if (!opts.skipWarnings) {
690
+ // Do not allow a non existing env
691
+ this.printWarningIfFirstTime(matchedEntry.id.toString(), `environment with ID: ${matchedEntry.id.toString()} configured on component ${component.id.toString()} was not loaded (run "bit install")`);
692
+ }
693
+ }
694
+ // Do not allow configure teambit.envs/envs on the component without configure the env aspect itself
695
+ // const errMsg = new EnvNotConfiguredForComponent(envIdFromEnvsConfig as string, component.id.toString()).message;
696
+ // this.printWarningIfFirstTime(envIdFromEnvsConfig as string, errMsg);
697
+ }
698
+
699
+ // in case there is no config in teambit.envs/envs search the aspects for the first env that registered as env
700
+ let envDefFromList;
701
+ component.state.aspects.entries.find(aspectEntry => {
702
+ const envDef = this.getEnvDefinitionById(aspectEntry.id);
703
+ if (envDef) {
704
+ envDefFromList = envDef;
705
+ }
706
+ return !!envDef;
707
+ });
708
+ if (envDefFromList) {
709
+ this.envIds.add(envDefFromList.id);
710
+ return envDefFromList;
711
+ }
712
+ return this.getDefaultEnv();
713
+ }
714
+
715
+ /**
716
+ * an env can be configured on a component in two ways:
717
+ * 1) explicitly inside "teambit.envs/envs". `{ "teambit.envs/envs": { "env": "my-env" } }`
718
+ * 2) the env aspect is set on the variant as any other aspect, e.g. `{ "my-env": {} }`
719
+ *
720
+ * this method returns #1 if exists, otherwise, #2.
721
+ */
722
+ getAllEnvsConfiguredOnComponent(component) {
723
+ // if a component has "envs" config, use it and ignore other components that are set up
724
+ // in this components which happen to be envs.
725
+ const envDef = this.getEnvFromEnvsConfig(component);
726
+ if (envDef) {
727
+ return [envDef];
728
+ }
729
+ return this.getEnvsNotFromEnvsConfig(component);
730
+ }
731
+
732
+ /**
733
+ * whether a component has an env configured (either by variant or .bitmap).
734
+ */
735
+ hasEnvConfigured(component) {
736
+ return Boolean(this.getAllEnvsConfiguredOnComponent(component).length);
737
+ }
738
+ getAllRegisteredEnvsIds() {
739
+ return this.envSlot.toArray().map(envData => envData[0]);
740
+ }
741
+ getAllRegisteredEnvs() {
742
+ return this.envSlot.toArray().map(envData => envData[1]);
743
+ }
744
+ getAllRegisteredEnvJsoncCustomizers() {
745
+ return this.envJsoncMergeCustomizerSlot.toArray().map(customizerEntry => customizerEntry[1]);
746
+ }
747
+ getAllRegisteredEnvJsoncResolvers() {
748
+ return this.envJsoncResolverSlot.toArray().map(resolver => resolver[1]);
749
+ }
750
+ getEnvPlugin() {
751
+ return new (_env2().EnvPlugin)(this.envSlot, this.servicesRegistry, this.loggerMain, this.workerMain, this.harmony);
752
+ }
753
+
754
+ /**
755
+ * an env can be configured on a component in two ways:
756
+ * 1) explicitly inside "teambit.envs/envs". `{ "teambit.envs/envs": { "env": "my-env" } }`
757
+ * 2) the env aspect is set on the variant as any other aspect, e.g. `{ "my-env": {} }`
758
+ *
759
+ * this method returns only #1
760
+ */
761
+ getEnvFromEnvsConfig(component) {
762
+ const envIdFromEnvsConfig = this.getEnvIdFromEnvsConfig(component);
763
+ if (!envIdFromEnvsConfig) {
764
+ return undefined;
765
+ }
766
+ const envIdFromEnvsConfigWithoutVersion = _componentId().ComponentID.fromString(envIdFromEnvsConfig).toStringWithoutVersion();
767
+ const envDef = this.getEnvDefinitionByStringId(envIdFromEnvsConfigWithoutVersion);
768
+ return envDef;
769
+ }
770
+
771
+ /**
772
+ * an env can be configured on a component in two ways:
773
+ * 1) explicitly inside "teambit.envs/envs". `{ "teambit.envs/envs": { "env": "my-env" } }`
774
+ * 2) the env aspect is set on the variant as any other aspect, e.g. `{ "my-env": {} }`
775
+ *
776
+ * this method returns only #2
777
+ */
778
+ getEnvsNotFromEnvsConfig(component) {
779
+ return component.state.aspects.entries.reduce((acc, aspectEntry) => {
780
+ const envDef = this.getEnvDefinitionById(aspectEntry.id);
781
+ if (envDef) acc.push(envDef);
782
+ return acc;
783
+ }, []);
784
+ }
785
+ getEnvIdFromEnvsLegacyExtensions(extensions) {
786
+ const envsAspect = extensions.findCoreExtension(_environments().EnvsAspect.id);
787
+ const envIdFromEnvsConfig = envsAspect?.data.id;
788
+ return envIdFromEnvsConfig;
789
+ }
790
+
791
+ /**
792
+ * @deprecated DO NOT USE THIS METHOD ANYMORE!!! (PLEASE USE .calculateEnvId() instead!)
793
+ */
794
+ async calculateEnvIdFromExtensions(extensions) {
795
+ // Search first for env configured via envs aspect itself
796
+ const envsAspect = extensions.findCoreExtension(_environments().EnvsAspect.id);
797
+ const envIdFromEnvsConfig = envsAspect?.config.env;
798
+ const envIdFromEnvsConfigWithoutVersion = envIdFromEnvsConfig ? _componentId().ComponentID.fromString(envIdFromEnvsConfig).toStringWithoutVersion() : undefined;
799
+ if (envIdFromEnvsConfig && this.isCoreEnv(envIdFromEnvsConfig)) {
800
+ return envIdFromEnvsConfig;
801
+ }
802
+
803
+ // in some cases we have the id configured in the teambit.envs/envs but without the version
804
+ // in such cases we won't find it in the slot
805
+ // we search in the component aspect list a matching aspect which is match the id from the teambit.envs/envs
806
+ if (envIdFromEnvsConfigWithoutVersion) {
807
+ const matchedEntry = extensions.find(extension => {
808
+ if (extension.extensionId) {
809
+ return envIdFromEnvsConfigWithoutVersion === extension.extensionId.toString() || envIdFromEnvsConfigWithoutVersion === extension.extensionId.toString({
810
+ ignoreVersion: true
811
+ });
812
+ }
813
+ return envIdFromEnvsConfigWithoutVersion === extension.stringId;
814
+ });
815
+ if (matchedEntry?.id) return matchedEntry?.stringId;
816
+ }
817
+
818
+ // in case there is no config in teambit.envs/envs search the aspects for the first env that registered as env
819
+ const ids = [];
820
+ extensions.forEach(extension => {
821
+ if (extension.extensionId) {
822
+ ids.push(extension.extensionId.toString());
823
+ } else {
824
+ ids.push(extension.stringId);
825
+ }
826
+ });
827
+ const envId = await this.findFirstEnv(ids);
828
+ const finalId = envId || this.getDefaultEnv().id;
829
+ return finalId;
830
+ }
831
+ validateEnvId(ext) {
832
+ if (!ext.config?.env || !ext.data?.id || ext.config.env === ext.data.id) return;
833
+ let errorMsg;
834
+ if (ext.data.id === DEFAULT_ENV) {
835
+ errorMsg = `the env id "${ext.data.id}" is set to the default env (${DEFAULT_ENV}) in the aspect data, but it is set to "${ext.config.env}" in the aspect config.
836
+ this may indicate that the env was not loaded properly. try running "bit install" to ensure the env is correctly loaded.
837
+ to explicitly set the default env, use "bit env set" command.`;
838
+ } else {
839
+ errorMsg = `env id "${ext.data.id}" is different from the id in the envs aspect config "${ext.config.env}".
840
+ if needed, use "bit env set" command to align the env id`;
841
+ }
842
+ return {
843
+ errorMsg,
844
+ minBitVersion: '1.9.82'
845
+ };
846
+ }
847
+
848
+ /**
849
+ * @deprecated DO NOT USE THIS METHOD ANYMORE!!! (PLEASE USE .calculateEnv() instead!)
850
+ */
851
+ async calculateEnvFromExtensions(extensions) {
852
+ // Search first for env configured via envs aspect itself
853
+ const envsAspect = extensions.findCoreExtension(_environments().EnvsAspect.id);
854
+ const envIdFromEnvsConfig = envsAspect?.config.env;
855
+ let envIdFromEnvsConfigWithoutVersion;
856
+ if (envIdFromEnvsConfig) {
857
+ envIdFromEnvsConfigWithoutVersion = _componentId().ComponentID.fromString(envIdFromEnvsConfig).toStringWithoutVersion();
858
+ const envDef = this.getEnvDefinitionByStringId(envIdFromEnvsConfigWithoutVersion);
859
+ if (envDef) {
860
+ this.envIds.add(envDef.id);
861
+ return envDef;
862
+ }
863
+ }
864
+
865
+ // in some cases we have the id configured in the teambit.envs/envs but without the version
866
+ // in such cases we won't find it in the slot
867
+ // we search in the component aspect list a matching aspect which is match the id from the teambit.envs/envs
868
+ if (envIdFromEnvsConfigWithoutVersion) {
869
+ const matchedEntry = extensions.find(extension => {
870
+ if (extension.extensionId) {
871
+ return envIdFromEnvsConfigWithoutVersion === extension.extensionId.toString() || envIdFromEnvsConfigWithoutVersion === extension.extensionId.toString({
872
+ ignoreVersion: true
873
+ });
874
+ }
875
+ return envIdFromEnvsConfigWithoutVersion === extension.stringId;
876
+ });
877
+ if (matchedEntry) {
878
+ // during the tag process, the version in the aspect-entry-id is changed and is not the
879
+ // same as it was when it registered to the slot.
880
+ const envDef = this.getEnvDefinitionByLegacyExtension(matchedEntry);
881
+ if (envDef) {
882
+ this.envIds.add(envDef.id);
883
+ return envDef;
884
+ }
885
+ // Do not allow a non existing env
886
+ // this.printWarningIfFirstTime(
887
+ // matchedEntry.id.toString(),
888
+ // `environment with ID: ${matchedEntry.id.toString()} was not found`
889
+ // );
890
+ }
891
+ // Do not allow configure teambit.envs/envs on the component without configure the env aspect itself
892
+ // const errMsg = new EnvNotConfiguredForComponent(envIdFromEnvsConfig).message;
893
+ // this.printWarningIfFirstTime(envIdFromEnvsConfig, errMsg);
894
+ }
895
+
896
+ // in case there is no config in teambit.envs/envs search the aspects for the first env that registered as env
897
+ const ids = [];
898
+ extensions.forEach(extension => {
899
+ if (extension.extensionId) {
900
+ ids.push(extension.extensionId.toString());
901
+ } else {
902
+ ids.push(extension.stringId);
903
+ }
904
+ });
905
+ const envId = await this.findFirstEnv(ids);
906
+ const envDef = envId ? this.getEnvDefinitionByStringId(envId) : undefined;
907
+ return envDef || this.getDefaultEnv();
908
+ }
909
+
910
+ /**
911
+ * This function finds the first environment ID from a list of IDs by checking if it is register as env (to the slot).
912
+ * or contains env.jsonc file
913
+ * @param {string[]} ids - `ids` is an array of string values representing environment IDs. The function `findFirstEnv`
914
+ * takes this array as input and returns a Promise that resolves to a string value representing the first environment ID
915
+ * that matches certain conditions.
916
+ * @returns The `findFirstEnv` function returns a Promise that resolves to a string or undefined. The string represents
917
+ * the ID of the first environment that matches the conditions specified in the function, or undefined if no environment
918
+ * is found.
919
+ */
920
+ async findFirstEnv(ids) {
921
+ let isFoundWithoutVersion = false;
922
+ const envId = await (0, _pLocate().default)(ids, async id => {
923
+ const idWithoutVersion = id.split('@')[0];
924
+ if (this.isCoreEnv(idWithoutVersion)) return true;
925
+ if (this.isCoreAspect(idWithoutVersion)) return false;
926
+ const envDef = this.getEnvDefinitionByStringId(id);
927
+ if (envDef) return true;
928
+ const envDefWithoutVersion = this.getEnvDefinitionByStringId(idWithoutVersion);
929
+ if (envDefWithoutVersion) {
930
+ isFoundWithoutVersion = true;
931
+ return true;
932
+ }
933
+ const envComponent = await this.getEnvComponentByEnvId(id);
934
+ const hasManifest = this.hasEnvManifest(envComponent);
935
+ if (hasManifest) return true;
936
+ const isUsingEnvEnv = this.isUsingEnvEnv(envComponent);
937
+ return !!isUsingEnvEnv;
938
+ });
939
+ let finalEnvId;
940
+ if (envId) {
941
+ finalEnvId = isFoundWithoutVersion ? envId?.split('@')[0] : envId;
942
+ this.envIds.add(envId);
943
+ }
944
+ return finalEnvId;
945
+ }
946
+ getEnvDefinitionByLegacyExtension(extension) {
947
+ const envDef = extension.extensionId ? this.getEnvDefinitionById(extension.extensionId) : this.getEnvDefinitionByStringId(extension.stringId);
948
+ return envDef;
949
+ }
950
+ getEnvIdFromEnvsConfig(component) {
951
+ const envsAspect = component.state.aspects.get(_environments().EnvsAspect.id);
952
+ return envsAspect?.config.env;
953
+ }
954
+ getEnvDefinition(id) {
955
+ const allVersions = this.envSlot.toArray();
956
+ const all = allVersions.filter(([envId]) => envId.includes(id.toStringWithoutVersion()));
957
+ const first = (0, _lodash().head)(all);
958
+ if (!first) return undefined;
959
+ const [envId, env] = first;
960
+ return new (_envDefinition().EnvDefinition)(envId, env);
961
+ }
962
+ getEnvDefinitionById(id) {
963
+ const envDef = this.getEnvDefinitionByStringId(id.toString()) || this.getEnvDefinitionByStringId(id.toString({
964
+ ignoreVersion: true
965
+ }));
966
+ return envDef;
967
+ }
968
+ getEnvDefinitionByStringId(envId) {
969
+ const env = this.envSlot.get(envId);
970
+ if (env) {
971
+ return new (_envDefinition().EnvDefinition)(envId, env);
972
+ }
973
+ return undefined;
974
+ }
975
+ getEnvFromComponent(envComponent) {
976
+ const env = this.getEnvDefinitionById(envComponent.id);
977
+ return env;
978
+ }
979
+
980
+ /**
981
+ * Return the env definition of teambit.envs/env
982
+ */
983
+ getEnvsEnvDefinition() {
984
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
985
+ return this.getEnvDefinitionByStringId('teambit.envs/env');
986
+ }
987
+ printWarningIfFirstTime(envId, message) {
988
+ if (!this.alreadyShownWarning[envId] && !this.failedToLoadEnvs.has(envId)) {
989
+ this.alreadyShownWarning[envId] = true;
990
+ this.logger.consoleWarning(message);
991
+ this.addFailedToLoadEnvs(envId);
992
+ }
993
+ }
994
+
995
+ /**
996
+ * determines whether an env is registered.
997
+ */
998
+ isEnvRegistered(id) {
999
+ return Boolean(this.envSlot.get(id));
1000
+ }
1001
+ isUsingAspectEnv(component) {
1002
+ const data = this.getEnvData(component);
1003
+ if (!data) return false;
1004
+ return data.type === 'aspect';
1005
+ }
1006
+ isUsingEnvEnv(component) {
1007
+ const data = this.getEnvData(component);
1008
+ if (!data) return false;
1009
+ return data.type === 'env';
1010
+ }
1011
+
1012
+ /**
1013
+ * Check if the given component is an env component.
1014
+ * @param component
1015
+ * @returns
1016
+ */
1017
+ isEnv(component) {
1018
+ return this.isUsingEnvEnv(component) || this.isEnvRegistered(component.id.toString()) || this.isEnvRegistered(component.id.toStringWithoutVersion());
1019
+ }
1020
+
1021
+ /**
1022
+ * register a new environment service.
1023
+ */
1024
+ registerService(...envServices) {
1025
+ this.servicesRegistry.register(envServices);
1026
+ return this;
1027
+ }
1028
+
1029
+ /**
1030
+ * get list of services enabled on an env.
1031
+ */
1032
+ getServices(env) {
1033
+ const allServices = this.servicesRegistry.toArray();
1034
+ const services = [];
1035
+ allServices.forEach(([id, currentServices]) => {
1036
+ currentServices.forEach(service => {
1037
+ try {
1038
+ if (this.implements(env, service)) {
1039
+ services.push([id, service]);
1040
+ }
1041
+ } catch {
1042
+ this.logger.warn(`failed loading service ${id} for env ${env.id}`);
1043
+ }
1044
+ });
1045
+ });
1046
+ return new (_envServiceList().EnvServiceList)(env, services);
1047
+ }
1048
+ implements(env, service) {
1049
+ // TODO: remove this after refactoring everything and remove getDescriptor from being optional.
1050
+ if (!service.getDescriptor) return false;
1051
+ return !!service.getDescriptor(env);
1052
+ }
1053
+
1054
+ /**
1055
+ * register an environment.
1056
+ */
1057
+ registerEnv(env) {
1058
+ return this.envSlot.register(env);
1059
+ }
1060
+
1061
+ /**
1062
+ * register an env.jsonc merge customizer.
1063
+ */
1064
+ registerEnvJsoncMergeCustomizer(customizer) {
1065
+ return this.envJsoncMergeCustomizerSlot.register(customizer);
1066
+ }
1067
+ registerEnvJsoncResolver(resolver) {
1068
+ return this.envJsoncResolverSlot.register(resolver);
1069
+ }
1070
+ getEnvJsoncDetector() {
1071
+ return new (_envJsonc().EnvJsoncDetector)();
1072
+ }
1073
+ async addNonLoadedEnvAsComponentIssues(components) {
1074
+ await (0, _pMapSeries().default)(components, async component => {
1075
+ const envId = await this.calculateEnvId(component);
1076
+ const envIdStr = envId.toString();
1077
+ if (!this.isEnvRegistered(envIdStr)) {
1078
+ this.addFailedToLoadEnvs(envIdStr);
1079
+ // If there is no version and the env is not in the workspace this is not valid
1080
+ // you can't set external env without version
1081
+ if (!envIdStr.includes('@')) {
1082
+ const foundComp = components.find(c => c.id.toStringWithoutVersion() === envIdStr);
1083
+ if (!foundComp) {
1084
+ component.state.issues.getOrCreate(_componentIssues().IssuesClasses.ExternalEnvWithoutVersion).data = {
1085
+ envId: envIdStr,
1086
+ componentId: component.id.toString()
1087
+ };
1088
+ } else {
1089
+ component.state.issues.getOrCreate(_componentIssues().IssuesClasses.NonLoadedEnv).data = envIdStr;
1090
+ }
1091
+ } else {
1092
+ component.state.issues.getOrCreate(_componentIssues().IssuesClasses.NonLoadedEnv).data = envIdStr;
1093
+ }
1094
+ }
1095
+ });
1096
+ }
1097
+
1098
+ // refactor here
1099
+ async createRuntime(components) {
1100
+ return new (_runtime().Runtime)(await this.aggregateByDefs(components), this.logger);
1101
+ }
1102
+
1103
+ // :TODO can be refactored to few utilities who will make repeating this very easy.
1104
+ async aggregateByDefs(components) {
1105
+ this.throwForDuplicateComponents(components);
1106
+ const envsMap = {};
1107
+ components.forEach(component => {
1108
+ const envDef = this.getEnv(component);
1109
+ const envId = envDef.id;
1110
+ const env = envDef.env;
1111
+ // handle config as well when aggregating envs.
1112
+ if (envsMap[envId]) envsMap[envId].components.push(component);else envsMap[envId] = {
1113
+ components: [component],
1114
+ env
1115
+ };
1116
+ });
1117
+ return Promise.all(Object.keys(envsMap).map(async key => {
1118
+ const envAspectDef = await this.getEnvAspectDef(key);
1119
+ return new (_runtime().EnvRuntime)(key, envsMap[key].env, envsMap[key].components, envAspectDef);
1120
+ }));
1121
+ }
1122
+ async getEnvAspectDef(envId) {
1123
+ const host = this.componentMain.getHost();
1124
+ const id = await host.resolveComponentId(envId);
1125
+ // We don't want to filter by runtime here as we want to also get envs that configured as plugins. so they don't
1126
+ // contain the runtime path.
1127
+ const resolvedAspects = await host.resolveAspects(_cli().MainRuntime.name, [id], {
1128
+ requestedOnly: true,
1129
+ filterByRuntime: false,
1130
+ useScopeAspectsCapsule: true
1131
+ });
1132
+ const def = resolvedAspects[0];
1133
+ return def;
1134
+ }
1135
+ throwForDuplicateComponents(components) {
1136
+ const idsStr = components.map(c => c.id.toString());
1137
+ const duplications = (0, _toolboxArray().findDuplications)(idsStr);
1138
+ if (duplications.length) {
1139
+ throw new Error(`found duplicated components: ${duplications.join(', ')}`);
1140
+ }
1141
+ }
1142
+ static async provider([graphql, loggerAspect, component, cli, worker, issues], config, [envSlot, servicesRegistry, envJsoncMergeCustomizerSlot, envJsoncResolverSlot], context) {
1143
+ const logger = loggerAspect.createLogger(_environments().EnvsAspect.id);
1144
+ const envs = new EnvsMain(config, context, envSlot, logger, servicesRegistry, component, loggerAspect, worker, envJsoncMergeCustomizerSlot, envJsoncResolverSlot);
1145
+ component.registerShowFragments([new (_env().EnvFragment)(envs)]);
1146
+ if (issues) issues.registerAddComponentsIssues(envs.addNonLoadedEnvAsComponentIssues.bind(envs));
1147
+ const envsCmd = new (_envs().EnvsCmd)(envs, component);
1148
+ envsCmd.commands = [new (_envs().ListEnvsCmd)(envs, component), new (_envs().GetEnvCmd)(envs, component)];
1149
+ cli.register(envsCmd);
1150
+ graphql.register(() => (0, _environments2().environmentsSchema)(envs));
1151
+ return envs;
1152
+ }
1153
+ }
1154
+ exports.EnvsMain = EnvsMain;
1155
+ _defineProperty(EnvsMain, "runtime", _cli().MainRuntime);
1156
+ _defineProperty(EnvsMain, "slots", [_harmony().Slot.withType(), _harmony().Slot.withType(), _harmony().Slot.withType(), _harmony().Slot.withType()]);
1157
+ _defineProperty(EnvsMain, "dependencies", [_graphql().GraphqlAspect, _logger().LoggerAspect, _component().ComponentAspect, _cli().CLIAspect, _worker().WorkerAspect, _issues().IssuesAspect]);
1158
+ _environments().EnvsAspect.addRuntime(EnvsMain);
1159
+
1160
+ //# sourceMappingURL=environments.main.runtime.js.map