@theia/plugin-ext 1.27.0-next.77 → 1.27.0-next.78

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 (37) hide show
  1. package/lib/common/plugin-protocol.d.ts +9 -4
  2. package/lib/common/plugin-protocol.d.ts.map +1 -1
  3. package/lib/common/plugin-protocol.js.map +1 -1
  4. package/lib/hosted/browser/hosted-plugin.d.ts.map +1 -1
  5. package/lib/hosted/browser/hosted-plugin.js +7 -6
  6. package/lib/hosted/browser/hosted-plugin.js.map +1 -1
  7. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts +8 -5
  8. package/lib/hosted/node/hosted-plugin-deployer-handler.d.ts.map +1 -1
  9. package/lib/hosted/node/hosted-plugin-deployer-handler.js +55 -16
  10. package/lib/hosted/node/hosted-plugin-deployer-handler.js.map +1 -1
  11. package/lib/main/node/handlers/plugin-theia-file-handler.d.ts.map +1 -1
  12. package/lib/main/node/handlers/plugin-theia-file-handler.js +1 -0
  13. package/lib/main/node/handlers/plugin-theia-file-handler.js.map +1 -1
  14. package/lib/main/node/plugin-deployer-impl.d.ts +7 -7
  15. package/lib/main/node/plugin-deployer-impl.d.ts.map +1 -1
  16. package/lib/main/node/plugin-deployer-impl.js +15 -13
  17. package/lib/main/node/plugin-deployer-impl.js.map +1 -1
  18. package/lib/main/node/plugin-server-handler.d.ts +3 -3
  19. package/lib/main/node/plugin-server-handler.d.ts.map +1 -1
  20. package/lib/main/node/plugin-server-handler.js +9 -5
  21. package/lib/main/node/plugin-server-handler.js.map +1 -1
  22. package/lib/main/node/plugin-uninstallation-manager.d.ts +5 -2
  23. package/lib/main/node/plugin-uninstallation-manager.d.ts.map +1 -1
  24. package/lib/main/node/plugin-uninstallation-manager.js +25 -6
  25. package/lib/main/node/plugin-uninstallation-manager.js.map +1 -1
  26. package/lib/plugin/plugin-manager.d.ts.map +1 -1
  27. package/lib/plugin/plugin-manager.js +5 -9
  28. package/lib/plugin/plugin-manager.js.map +1 -1
  29. package/package.json +24 -24
  30. package/src/common/plugin-protocol.ts +10 -4
  31. package/src/hosted/browser/hosted-plugin.ts +7 -6
  32. package/src/hosted/node/hosted-plugin-deployer-handler.ts +55 -18
  33. package/src/main/node/handlers/plugin-theia-file-handler.ts +1 -0
  34. package/src/main/node/plugin-deployer-impl.ts +17 -15
  35. package/src/main/node/plugin-server-handler.ts +10 -6
  36. package/src/main/node/plugin-uninstallation-manager.ts +20 -6
  37. package/src/plugin/plugin-manager.ts +5 -9
@@ -46,7 +46,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
46
46
  protected readonly uninstallationManager: PluginUninstallationManager;
47
47
 
48
48
  private readonly deployedLocations = new Map<PluginIdentifiers.VersionedId, Set<string>>();
49
- protected readonly originalLocations = new Map<PluginIdentifiers.VersionedId, string>();
49
+ protected readonly sourceLocations = new Map<PluginIdentifiers.VersionedId, Set<string>>();
50
50
 
51
51
  /**
52
52
  * Managed plugin metadata backend entries.
@@ -80,7 +80,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
80
80
  const matches: DeployedPlugin[] = [];
81
81
  const handle = (plugins: Iterable<DeployedPlugin>): void => {
82
82
  for (const plugin of plugins) {
83
- if (PluginIdentifiers.componentsToVersionWithId(plugin.metadata.model).version === pluginId) {
83
+ if (PluginIdentifiers.componentsToVersionWithId(plugin.metadata.model).id === pluginId) {
84
84
  matches.push(plugin);
85
85
  }
86
86
  }
@@ -117,28 +117,33 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
117
117
  }
118
118
  }
119
119
 
120
- async deployFrontendPlugins(frontendPlugins: PluginDeployerEntry[]): Promise<void> {
120
+ async deployFrontendPlugins(frontendPlugins: PluginDeployerEntry[]): Promise<number> {
121
+ let successes = 0;
121
122
  for (const plugin of frontendPlugins) {
122
- await this.deployPlugin(plugin, 'frontend');
123
+ if (await this.deployPlugin(plugin, 'frontend')) { successes++; }
123
124
  }
124
125
  // resolve on first deploy
125
126
  this.frontendPluginsMetadataDeferred.resolve(undefined);
127
+ return successes;
126
128
  }
127
129
 
128
- async deployBackendPlugins(backendPlugins: PluginDeployerEntry[]): Promise<void> {
130
+ async deployBackendPlugins(backendPlugins: PluginDeployerEntry[]): Promise<number> {
131
+ let successes = 0;
129
132
  for (const plugin of backendPlugins) {
130
- await this.deployPlugin(plugin, 'backend');
133
+ if (await this.deployPlugin(plugin, 'backend')) { successes++; }
131
134
  }
132
135
  // rebuild translation config after deployment
133
136
  this.localizationService.buildTranslationConfig([...this.deployedBackendPlugins.values()]);
134
137
  // resolve on first deploy
135
138
  this.backendPluginsMetadataDeferred.resolve(undefined);
139
+ return successes;
136
140
  }
137
141
 
138
142
  /**
139
- * @throws never! in order to isolate plugin deployment
143
+ * @throws never! in order to isolate plugin deployment.
144
+ * @returns whether the plugin is deployed after running this function. If the plugin was already installed, will still return `true`.
140
145
  */
141
- protected async deployPlugin(entry: PluginDeployerEntry, entryPoint: keyof PluginEntryPoint): Promise<void> {
146
+ protected async deployPlugin(entry: PluginDeployerEntry, entryPoint: keyof PluginEntryPoint): Promise<boolean> {
142
147
  const pluginPath = entry.path();
143
148
  const deployPlugin = this.stopwatch.start('deployPlugin');
144
149
  let id;
@@ -147,7 +152,7 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
147
152
  const manifest = await this.reader.readPackage(pluginPath);
148
153
  if (!manifest) {
149
154
  deployPlugin.error(`Failed to read ${entryPoint} plugin manifest from '${pluginPath}''`);
150
- return;
155
+ return success = false;
151
156
  }
152
157
 
153
158
  const metadata = this.reader.readMetadata(manifest);
@@ -155,15 +160,15 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
155
160
 
156
161
  id = PluginIdentifiers.componentsToVersionedId(metadata.model);
157
162
 
158
- const deployedLocations = this.deployedLocations.get(id) || new Set<string>();
163
+ const deployedLocations = this.deployedLocations.get(id) ?? new Set<string>();
159
164
  deployedLocations.add(entry.rootPath);
160
165
  this.deployedLocations.set(id, deployedLocations);
161
- this.originalLocations.set(id, entry.originalPath());
166
+ this.setSourceLocationsForPlugin(id, entry);
162
167
 
163
168
  const deployedPlugins = entryPoint === 'backend' ? this.deployedBackendPlugins : this.deployedFrontendPlugins;
164
169
  if (deployedPlugins.has(id)) {
165
170
  deployPlugin.debug(`Skipped ${entryPoint} plugin ${metadata.model.name} already deployed`);
166
- return;
171
+ return true;
167
172
  }
168
173
 
169
174
  const { type } = entry;
@@ -173,23 +178,25 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
173
178
  deployedPlugins.set(id, deployed);
174
179
  deployPlugin.log(`Deployed ${entryPoint} plugin "${id}" from "${metadata.model.entryPoint[entryPoint] || pluginPath}"`);
175
180
  } catch (e) {
176
- success = false;
177
181
  deployPlugin.error(`Failed to deploy ${entryPoint} plugin from '${pluginPath}' path`, e);
182
+ return success = false;
178
183
  } finally {
179
184
  if (success && id) {
180
- this.uninstallationManager.markAsInstalled(id);
185
+ this.markAsInstalled(id);
181
186
  }
182
187
  }
188
+ return success;
183
189
  }
184
190
 
185
191
  async uninstallPlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
186
192
  try {
187
- const originalPath = this.originalLocations.get(pluginId);
188
- if (!originalPath) {
193
+ const sourceLocations = this.sourceLocations.get(pluginId);
194
+ if (!sourceLocations) {
189
195
  return false;
190
196
  }
191
- await fs.remove(originalPath);
192
- this.originalLocations.delete(pluginId);
197
+ await Promise.all(Array.from(sourceLocations,
198
+ location => fs.remove(location).catch(err => console.error(`Failed to remove source for ${pluginId} at ${location}`, err))));
199
+ this.sourceLocations.delete(pluginId);
193
200
  this.uninstallationManager.markAsUninstalled(pluginId);
194
201
  return true;
195
202
  } catch (e) {
@@ -198,6 +205,26 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
198
205
  }
199
206
  }
200
207
 
208
+ protected markAsInstalled(id: PluginIdentifiers.VersionedId): void {
209
+ const metadata = PluginIdentifiers.idAndVersionFromVersionedId(id);
210
+ if (metadata) {
211
+ const toMarkAsUninstalled: PluginIdentifiers.VersionedId[] = [];
212
+ const checkForDifferentVersions = (others: Iterable<PluginIdentifiers.VersionedId>) => {
213
+ for (const other of others) {
214
+ const otherMetadata = PluginIdentifiers.idAndVersionFromVersionedId(other);
215
+ if (metadata.id === otherMetadata?.id && metadata.version !== otherMetadata.version) {
216
+ toMarkAsUninstalled.push(other);
217
+ }
218
+ }
219
+ };
220
+ checkForDifferentVersions(this.deployedFrontendPlugins.keys());
221
+ checkForDifferentVersions(this.deployedBackendPlugins.keys());
222
+ this.uninstallationManager.markAsUninstalled(...toMarkAsUninstalled);
223
+ this.uninstallationManager.markAsInstalled(id);
224
+ toMarkAsUninstalled.forEach(pluginToUninstall => this.uninstallPlugin(pluginToUninstall));
225
+ }
226
+ }
227
+
201
228
  async undeployPlugin(pluginId: PluginIdentifiers.VersionedId): Promise<boolean> {
202
229
  this.deployedBackendPlugins.delete(pluginId);
203
230
  this.deployedFrontendPlugins.delete(pluginId);
@@ -220,4 +247,14 @@ export class HostedPluginDeployerHandler implements PluginDeployerHandler {
220
247
 
221
248
  return true;
222
249
  }
250
+
251
+ protected setSourceLocationsForPlugin(id: PluginIdentifiers.VersionedId, entry: PluginDeployerEntry): void {
252
+ const knownLocations = this.sourceLocations.get(id) ?? new Set();
253
+ const maybeStoredLocations = entry.getValue('sourceLocations');
254
+ const storedLocations = Array.isArray(maybeStoredLocations) && maybeStoredLocations.every(location => typeof location === 'string')
255
+ ? maybeStoredLocations.concat(entry.originalPath())
256
+ : [entry.originalPath()];
257
+ storedLocations.forEach(location => knownLocations.add(location));
258
+ this.sourceLocations.set(id, knownLocations);
259
+ }
223
260
  }
@@ -66,6 +66,7 @@ export class PluginTheiaFileHandler implements PluginDeployerFileHandler {
66
66
  fs.copyFile(currentPath, newPath, error => error ? reject(error) : resolve());
67
67
  });
68
68
  context.pluginEntry().updatePath(newPath);
69
+ context.pluginEntry().storeValue('sourceLocations', [newPath]);
69
70
  } catch (e) {
70
71
  console.error(`[${context.pluginEntry().id}]: Failed to copy to user directory. Future sessions may not have access to this plugin.`);
71
72
  }
@@ -22,7 +22,7 @@ import {
22
22
  PluginDeployerResolver, PluginDeployerFileHandler, PluginDeployerDirectoryHandler,
23
23
  PluginDeployerEntry, PluginDeployer, PluginDeployerParticipant, PluginDeployerStartContext,
24
24
  PluginDeployerResolverInit, PluginDeployerFileHandlerContext,
25
- PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry, PluginIdentifiers
25
+ PluginDeployerDirectoryHandlerContext, PluginDeployerEntryType, PluginDeployerHandler, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions
26
26
  } from '../../common/plugin-protocol';
27
27
  import { PluginDeployerEntryImpl } from './plugin-deployer-entry-impl';
28
28
  import {
@@ -146,15 +146,16 @@ export class PluginDeployerImpl implements PluginDeployer {
146
146
  }
147
147
  }
148
148
 
149
- async deploy(plugin: UnresolvedPluginEntry): Promise<void> {
149
+ async deploy(plugin: UnresolvedPluginEntry, options?: PluginDeployOptions): Promise<number> {
150
150
  const deploy = this.measure('deploy');
151
- await this.deployMultipleEntries([plugin]);
152
- deploy.log(`Deploy plugin ${plugin}`);
151
+ const numDeployedPlugins = await this.deployMultipleEntries([plugin], options);
152
+ deploy.log(`Deploy plugin ${plugin.id}`);
153
+ return numDeployedPlugins;
153
154
  }
154
155
 
155
- protected async deployMultipleEntries(plugins: UnresolvedPluginEntry[]): Promise<void> {
156
- const pluginsToDeploy = await this.resolvePlugins(plugins);
157
- await this.deployPlugins(pluginsToDeploy);
156
+ protected async deployMultipleEntries(plugins: UnresolvedPluginEntry[], options?: PluginDeployOptions): Promise<number> {
157
+ const pluginsToDeploy = await this.resolvePlugins(plugins, options);
158
+ return this.deployPlugins(pluginsToDeploy);
158
159
  }
159
160
 
160
161
  /**
@@ -166,7 +167,7 @@ export class PluginDeployerImpl implements PluginDeployer {
166
167
  * deployer.deployPlugins(await deployer.resolvePlugins(allPluginEntries));
167
168
  * ```
168
169
  */
169
- async resolvePlugins(plugins: UnresolvedPluginEntry[]): Promise<PluginDeployerEntry[]> {
170
+ async resolvePlugins(plugins: UnresolvedPluginEntry[], options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
170
171
  const visited = new Set<string>();
171
172
  const hasBeenVisited = (id: string) => visited.has(id) || (visited.add(id), false);
172
173
  const pluginsToDeploy = new Map<PluginIdentifiers.VersionedId, PluginDeployerEntry>();
@@ -184,7 +185,7 @@ export class PluginDeployerImpl implements PluginDeployer {
184
185
  }
185
186
  const type = entry.type ?? PluginType.System;
186
187
  try {
187
- const pluginDeployerEntries = await this.resolveAndHandle(entry.id, type);
188
+ const pluginDeployerEntries = await this.resolveAndHandle(entry.id, type, options);
188
189
  for (const deployerEntry of pluginDeployerEntries) {
189
190
  const pluginData = await this.pluginDeployerHandler.getPluginDependencies(deployerEntry);
190
191
  const versionedId = pluginData && PluginIdentifiers.componentsToVersionedId(pluginData.metadata.model);
@@ -222,8 +223,8 @@ export class PluginDeployerImpl implements PluginDeployer {
222
223
  return [...pluginsToDeploy.values()];
223
224
  }
224
225
 
225
- protected async resolveAndHandle(id: string, type: PluginType): Promise<PluginDeployerEntry[]> {
226
- const entries = await this.resolvePlugin(id, type);
226
+ protected async resolveAndHandle(id: string, type: PluginType, options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
227
+ const entries = await this.resolvePlugin(id, type, options);
227
228
  await this.applyFileHandlers(entries);
228
229
  await this.applyDirectoryFileHandlers(entries);
229
230
  return entries;
@@ -265,7 +266,7 @@ export class PluginDeployerImpl implements PluginDeployer {
265
266
  /**
266
267
  * deploy all plugins that have been accepted
267
268
  */
268
- async deployPlugins(pluginsToDeploy: PluginDeployerEntry[]): Promise<any> {
269
+ async deployPlugins(pluginsToDeploy: PluginDeployerEntry[]): Promise<number> {
269
270
  const acceptedPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted());
270
271
  const acceptedFrontendPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted(PluginDeployerEntryType.FRONTEND));
271
272
  const acceptedBackendPlugins = pluginsToDeploy.filter(pluginDeployerEntry => pluginDeployerEntry.isAccepted(PluginDeployerEntryType.BACKEND));
@@ -282,12 +283,13 @@ export class PluginDeployerImpl implements PluginDeployer {
282
283
  const pluginPaths = acceptedBackendPlugins.map(pluginEntry => pluginEntry.path());
283
284
  this.logger.debug('local path to deploy on remote instance', pluginPaths);
284
285
 
285
- await Promise.all([
286
+ const deployments = await Promise.all([
286
287
  // start the backend plugins
287
288
  this.pluginDeployerHandler.deployBackendPlugins(acceptedBackendPlugins),
288
289
  this.pluginDeployerHandler.deployFrontendPlugins(acceptedFrontendPlugins)
289
290
  ]);
290
291
  this.onDidDeployEmitter.fire(undefined);
292
+ return deployments.reduce<number>((accumulated, current) => accumulated += current ?? 0, 0);
291
293
  }
292
294
 
293
295
  /**
@@ -333,7 +335,7 @@ export class PluginDeployerImpl implements PluginDeployer {
333
335
  /**
334
336
  * Check a plugin ID see if there are some resolvers that can handle it. If there is a matching resolver, then we resolve the plugin
335
337
  */
336
- public async resolvePlugin(pluginId: string, type: PluginType = PluginType.System): Promise<PluginDeployerEntry[]> {
338
+ public async resolvePlugin(pluginId: string, type: PluginType = PluginType.System, options?: PluginDeployOptions): Promise<PluginDeployerEntry[]> {
337
339
  const pluginDeployerEntries: PluginDeployerEntry[] = [];
338
340
  const foundPluginResolver = this.pluginResolvers.find(pluginResolver => pluginResolver.accept(pluginId));
339
341
  // there is a resolver for the input
@@ -342,7 +344,7 @@ export class PluginDeployerImpl implements PluginDeployer {
342
344
  // create context object
343
345
  const context = new PluginDeployerResolverContextImpl(foundPluginResolver, pluginId);
344
346
 
345
- await foundPluginResolver.resolve(context);
347
+ await foundPluginResolver.resolve(context, options);
346
348
 
347
349
  context.getPlugins().forEach(entry => {
348
350
  entry.type = type;
@@ -18,7 +18,7 @@ import { injectable, inject } from '@theia/core/shared/inversify';
18
18
  import { CancellationToken } from '@theia/core/lib/common/cancellation';
19
19
  import { PluginDeployerImpl } from './plugin-deployer-impl';
20
20
  import { PluginsKeyValueStorage } from './plugins-key-value-storage';
21
- import { PluginServer, PluginDeployer, PluginStorageKind, PluginType, UnresolvedPluginEntry, PluginIdentifiers } from '../../common/plugin-protocol';
21
+ import { PluginServer, PluginDeployer, PluginStorageKind, PluginType, UnresolvedPluginEntry, PluginIdentifiers, PluginDeployOptions } from '../../common/plugin-protocol';
22
22
  import { KeysToAnyValues, KeysToKeysToAnyValue } from '../../common/types';
23
23
 
24
24
  @injectable()
@@ -30,16 +30,20 @@ export class PluginServerHandler implements PluginServer {
30
30
  @inject(PluginsKeyValueStorage)
31
31
  protected readonly pluginsKeyValueStorage: PluginsKeyValueStorage;
32
32
 
33
- deploy(pluginEntry: string, arg2?: PluginType | CancellationToken): Promise<void> {
33
+ async deploy(pluginEntry: string, arg2?: PluginType | CancellationToken, options?: PluginDeployOptions): Promise<void> {
34
34
  const type = typeof arg2 === 'number' ? arg2 as PluginType : undefined;
35
- return this.doDeploy({
35
+ const succesfulDeployments = await this.doDeploy({
36
36
  id: pluginEntry,
37
37
  type: type ?? PluginType.User
38
- });
38
+ }, options);
39
+ if (succesfulDeployments === 0) {
40
+ const optionText = options ? ` and options ${JSON.stringify(options)} ` : ' ';
41
+ throw new Error(`Deployment of extension with ID ${pluginEntry}${optionText}failed.`);
42
+ }
39
43
  }
40
44
 
41
- protected doDeploy(pluginEntry: UnresolvedPluginEntry): Promise<void> {
42
- return this.pluginDeployer.deploy(pluginEntry);
45
+ protected doDeploy(pluginEntry: UnresolvedPluginEntry, options?: PluginDeployOptions): Promise<number> {
46
+ return this.pluginDeployer.deploy(pluginEntry, options);
43
47
  }
44
48
 
45
49
  uninstall(pluginId: PluginIdentifiers.VersionedId): Promise<void> {
@@ -28,25 +28,39 @@ export class PluginUninstallationManager {
28
28
 
29
29
  protected uninstalledPlugins: PluginIdentifiers.VersionedId[] = [];
30
30
 
31
- markAsUninstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
31
+ protected fireDidChange(): void {
32
+ this.onDidChangeUninstalledPluginsEmitter.fire(Object.freeze(this.uninstalledPlugins.slice()));
33
+ }
34
+
35
+ markAsUninstalled(...pluginIds: PluginIdentifiers.VersionedId[]): boolean {
36
+ let didChange = false;
37
+ for (const id of pluginIds) { didChange = this.markOneAsUninstalled(id) || didChange; }
38
+ if (didChange) { this.fireDidChange(); }
39
+ return didChange;
40
+ }
41
+
42
+ protected markOneAsUninstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
32
43
  if (!this.uninstalledPlugins.includes(pluginId)) {
33
44
  this.uninstalledPlugins.push(pluginId);
34
- this.onDidChangeUninstalledPluginsEmitter.fire(Object.freeze(this.uninstalledPlugins.slice()));
35
45
  return true;
36
46
  }
37
47
  return false;
38
48
  }
39
49
 
40
- markAsInstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
50
+ markAsInstalled(...pluginIds: PluginIdentifiers.VersionedId[]): boolean {
51
+ let didChange = false;
52
+ for (const id of pluginIds) { didChange = this.markOneAsInstalled(id) || didChange; }
53
+ if (didChange) { this.fireDidChange(); }
54
+ return didChange;
55
+ }
56
+
57
+ protected markOneAsInstalled(pluginId: PluginIdentifiers.VersionedId): boolean {
41
58
  let index: number;
42
59
  let didChange = false;
43
60
  while ((index = this.uninstalledPlugins.indexOf(pluginId)) !== -1) {
44
61
  this.uninstalledPlugins.splice(index, 1);
45
62
  didChange = true;
46
63
  }
47
- if (didChange) {
48
- this.onDidChangeUninstalledPluginsEmitter.fire(Object.freeze(this.uninstalledPlugins.slice()));
49
- }
50
64
  return didChange;
51
65
  }
52
66
 
@@ -240,10 +240,10 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager {
240
240
 
241
241
  protected registerPlugin(plugin: Plugin): void {
242
242
  if (plugin.model.id === 'vscode.json-language-features' && this.jsonValidation.length) {
243
- // VS Code contribute all built-in validations via vscode.json-language-features
244
- // we enrich them with Theia validations registered on the startup
245
- // dynamic validations can be provided only via VS Code extensions
246
- // content is fetched by the extension later via vscode.workspace.openTextDocument
243
+ // VS Code contributes all built-in validations via vscode.json-language-features;
244
+ // we enrich them with Theia validations registered on startup.
245
+ // Dynamic validations can be provided only via VS Code extensions.
246
+ // Content is fetched by the extension later via vscode.workspace.openTextDocument.
247
247
  const contributes = plugin.rawModel.contributes = (plugin.rawModel.contributes || {});
248
248
  contributes.jsonValidation = (contributes.jsonValidation || []).concat(this.jsonValidation);
249
249
  }
@@ -337,11 +337,7 @@ export class PluginManagerExtImpl implements PluginManagerExt, PluginManager {
337
337
  }
338
338
 
339
339
  protected async activateByBaseEvent(baseEvent: string): Promise<void> {
340
- await Promise.all(Array.from(this.activations.keys(), activation => {
341
- if (activation.startsWith(baseEvent)) {
342
- return this.activateBySingleEvent(activation);
343
- }
344
- }));
340
+ await Promise.all(Array.from(this.activations.keys(), activation => activation.startsWith(baseEvent) && this.activateBySingleEvent(activation)));
345
341
  }
346
342
 
347
343
  protected async activateBySingleEvent(activationEvent: string): Promise<void> {