@codingame/monaco-vscode-extension-gallery-service-override 3.2.2 → 4.0.0

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 (39) hide show
  1. package/extensionGallery.js +7 -1
  2. package/override/vs/platform/dialogs/common/dialogs.js +2 -0
  3. package/package.json +9 -9
  4. package/vscode/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.js +18 -16
  5. package/vscode/src/vs/platform/extensionManagement/common/extensionGalleryService.js +24 -23
  6. package/vscode/src/vs/platform/extensionManagement/common/extensionManagementIpc.js +5 -2
  7. package/vscode/src/vs/platform/extensionManagement/common/extensionTipsService.js +10 -0
  8. package/vscode/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.js +33 -19
  9. package/vscode/src/vs/workbench/contrib/extensions/browser/configBasedRecommendations.js +1 -1
  10. package/vscode/src/vs/workbench/contrib/extensions/browser/deprecatedExtensionsChecker.js +8 -5
  11. package/vscode/src/vs/workbench/contrib/extensions/browser/exeBasedRecommendations.js +1 -1
  12. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionEditor.js +109 -40
  13. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionFeaturesTab.js +11 -8
  14. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService.js +31 -11
  15. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationsService.js +35 -21
  16. package/vscode/src/vs/workbench/contrib/extensions/browser/extensions.contribution.js +54 -29
  17. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsList.js +6 -6
  18. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewer.js +11 -1
  19. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.js +18 -17
  20. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViews.js +71 -31
  21. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.js +63 -20
  22. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.js +551 -134
  23. package/vscode/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.js +3 -3
  24. package/vscode/src/vs/workbench/contrib/extensions/browser/keymapRecommendations.js +1 -1
  25. package/vscode/src/vs/workbench/contrib/extensions/browser/languageRecommendations.js +1 -1
  26. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extension.css.js +1 -1
  27. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css.js +1 -1
  28. package/vscode/src/vs/workbench/contrib/extensions/browser/remoteRecommendations.js +1 -1
  29. package/vscode/src/vs/workbench/contrib/extensions/browser/webRecommendations.js +1 -1
  30. package/vscode/src/vs/workbench/contrib/extensions/browser/workspaceRecommendations.js +78 -4
  31. package/vscode/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.js +7 -1
  32. package/vscode/src/vs/workbench/services/extensionManagement/browser/extensionsProfileScannerService.js +24 -0
  33. package/vscode/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.js +15 -8
  34. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.js +2 -2
  35. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.js +3 -2
  36. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementService.js +469 -57
  37. package/vscode/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.js +5 -2
  38. package/vscode/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.js +1 -0
  39. package/vscode/src/vs/workbench/services/extensions/browser/extensionsScannerService.js +33 -0
@@ -1,9 +1,10 @@
1
1
  import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
- import { Event, EventMultiplexer } from 'vscode/vscode/vs/base/common/event';
2
+ import { Emitter, Event, EventMultiplexer } from 'vscode/vscode/vs/base/common/event';
3
3
  import { ExtensionManagementErrorCode, EXTENSION_INSTALL_SYNC_CONTEXT, ExtensionManagementError, IExtensionGalleryService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement';
4
- import { IExtensionManagementServerService } from 'vscode/vscode/vs/workbench/services/extensionManagement/common/extensionManagement';
4
+ import { extensionsConfigurationNodeBase, IExtensionManagementServerService } from 'vscode/vscode/vs/workbench/services/extensionManagement/common/extensionManagement';
5
5
  import { isLanguagePackExtension, getWorkspaceSupportTypeMessage } from 'vscode/vscode/vs/platform/extensions/common/extensions';
6
- import { Disposable } from 'vscode/vscode/vs/base/common/lifecycle';
6
+ import { URI } from 'vscode/vscode/vs/base/common/uri';
7
+ import { Disposable, DisposableStore } from 'vscode/vscode/vs/base/common/lifecycle';
7
8
  import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
8
9
  import { CancellationToken } from 'vscode/vscode/vs/base/common/cancellation';
9
10
  import { areSameExtensions, computeTargetPlatform } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagementUtil';
@@ -11,24 +12,32 @@ import { localizeWithPath } from 'vscode/vscode/vs/nls';
11
12
  import { IProductService } from 'vscode/vscode/vs/platform/product/common/productService';
12
13
  import { Schemas } from 'vscode/vscode/vs/base/common/network';
13
14
  import { IDownloadService } from 'vscode/vscode/vs/platform/download/common/download';
14
- import { flatten } from 'vscode/vscode/vs/base/common/arrays';
15
+ import { coalesce } from 'vscode/vscode/vs/base/common/arrays';
15
16
  import '../../../../../../../override/vs/platform/dialogs/common/dialogs.js';
16
- import Severity from 'vscode/vscode/vs/base/common/severity';
17
+ import Severity$1 from 'vscode/vscode/vs/base/common/severity';
17
18
  import { IUserDataSyncEnablementService } from 'vscode/vscode/vs/platform/userDataSync/common/userDataSync';
18
19
  import { Promises } from 'vscode/vscode/vs/base/common/async';
19
20
  import { IWorkspaceTrustRequestService } from 'vscode/vscode/vs/platform/workspace/common/workspaceTrust';
20
21
  import { IExtensionManifestPropertiesService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionManifestPropertiesService';
21
22
  import { IInstantiationService } from 'vscode/vscode/vs/platform/instantiation/common/instantiation';
22
23
  import { ICommandService } from 'vscode/vscode/vs/platform/commands/common/commands';
23
- import { isUndefined } from 'vscode/vscode/vs/base/common/types';
24
+ import { isString, isUndefined } from 'vscode/vscode/vs/base/common/types';
24
25
  import { IFileService } from 'vscode/vscode/vs/platform/files/common/files';
25
26
  import { ILogService } from 'vscode/vscode/vs/platform/log/common/log';
26
- import { CancellationError } from 'vscode/vscode/vs/base/common/errors';
27
+ import { getErrorMessage, CancellationError } from 'vscode/vscode/vs/base/common/errors';
27
28
  import { IUserDataProfileService } from 'vscode/vscode/vs/workbench/services/userDataProfile/common/userDataProfile';
29
+ import { IWorkspaceContextService } from 'vscode/vscode/vs/platform/workspace/common/workspace';
30
+ import { IExtensionsScannerService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionsScannerService';
31
+ import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage';
32
+ import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
33
+ import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry';
34
+ import { Registry } from 'vscode/vscode/vs/platform/registry/common/platform';
35
+ import { Extensions } from 'vscode/vscode/vs/platform/configuration/common/configurationRegistry';
28
36
  import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs';
29
37
 
38
+ var WorkspaceExtensionsManagementService_1;
30
39
  let ExtensionManagementService = class ExtensionManagementService extends Disposable {
31
- constructor(extensionManagementServerService, extensionGalleryService, userDataProfileService, configurationService, productService, downloadService, userDataSyncEnablementService, dialogService, workspaceTrustRequestService, extensionManifestPropertiesService, fileService, logService, instantiationService) {
40
+ constructor(extensionManagementServerService, extensionGalleryService, userDataProfileService, configurationService, productService, downloadService, userDataSyncEnablementService, dialogService, workspaceTrustRequestService, extensionManifestPropertiesService, fileService, logService, instantiationService, extensionsScannerService, telemetryService) {
32
41
  super();
33
42
  this.extensionManagementServerService = extensionManagementServerService;
34
43
  this.extensionGalleryService = extensionGalleryService;
@@ -43,7 +52,38 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
43
52
  this.fileService = fileService;
44
53
  this.logService = logService;
45
54
  this.instantiationService = instantiationService;
55
+ this.extensionsScannerService = extensionsScannerService;
56
+ this.telemetryService = telemetryService;
57
+ this._onInstallExtension = this._register(( new Emitter()));
58
+ this._onDidInstallExtensions = this._register(( new Emitter()));
59
+ this._onUninstallExtension = this._register(( new Emitter()));
60
+ this._onDidUninstallExtension = this._register(( new Emitter()));
46
61
  this.servers = [];
62
+ if (productService.quality !== 'stable') {
63
+ ( Registry.as(Extensions.Configuration))
64
+ .registerConfiguration({
65
+ ...extensionsConfigurationNodeBase,
66
+ properties: {
67
+ 'extensions.experimental.supportWorkspaceExtensions': {
68
+ type: 'boolean',
69
+ description: ( localizeWithPath(
70
+ 'vs/workbench/services/extensionManagement/common/extensionManagementService',
71
+ 'extensions.experimental.supportWorkspaceExtensions',
72
+ "Enables support for workspace specific local extensions."
73
+ )),
74
+ default: false,
75
+ scope: 1
76
+ }
77
+ }
78
+ });
79
+ }
80
+ if (this.productService.quality !== 'stable' && this.configurationService.getValue('extensions.experimental.supportWorkspaceExtensions') === true) {
81
+ this.workspaceExtensionManagementService = this._register(this.instantiationService.createInstance(WorkspaceExtensionsManagementService));
82
+ this.onDidEnableExtensions = this.workspaceExtensionManagementService.onDidChangeInvalidExtensions;
83
+ }
84
+ else {
85
+ this.onDidEnableExtensions = Event.None;
86
+ }
47
87
  if (this.extensionManagementServerService.localExtensionManagementServer) {
48
88
  this.servers.push(this.extensionManagementServerService.localExtensionManagementServer);
49
89
  }
@@ -53,32 +93,62 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
53
93
  if (this.extensionManagementServerService.webExtensionManagementServer) {
54
94
  this.servers.push(this.extensionManagementServerService.webExtensionManagementServer);
55
95
  }
56
- this.onInstallExtension = this._register(this.servers.reduce((emitter, server) => { this._register(emitter.add(( Event.map(
57
- server.extensionManagementService.onInstallExtension,
58
- e => ({ ...e, server })
59
- )))); return emitter; }, this._register(( new EventMultiplexer())))).event;
60
- this.onDidInstallExtensions = this._register(this.servers.reduce((emitter, server) => { this._register(emitter.add(server.extensionManagementService.onDidInstallExtensions)); return emitter; }, this._register(( new EventMultiplexer())))).event;
61
- this.onUninstallExtension = this._register(this.servers.reduce((emitter, server) => { this._register(emitter.add(( Event.map(
62
- server.extensionManagementService.onUninstallExtension,
63
- e => ({ ...e, server })
64
- )))); return emitter; }, this._register(( new EventMultiplexer())))).event;
65
- this.onDidUninstallExtension = this._register(this.servers.reduce((emitter, server) => { this._register(emitter.add(( Event.map(
66
- server.extensionManagementService.onDidUninstallExtension,
67
- e => ({ ...e, server })
68
- )))); return emitter; }, this._register(( new EventMultiplexer())))).event;
69
- this.onDidUpdateExtensionMetadata = this._register(this.servers.reduce((emitter, server) => { this._register(emitter.add(server.extensionManagementService.onDidUpdateExtensionMetadata)); return emitter; }, this._register(( new EventMultiplexer())))).event;
70
- this.onDidChangeProfile = this._register(this.servers.reduce((emitter, server) => { this._register(emitter.add(( Event.map(
71
- server.extensionManagementService.onDidChangeProfile,
72
- e => ({ ...e, server })
73
- )))); return emitter; }, this._register(( new EventMultiplexer())))).event;
74
- }
75
- async getInstalled(type, profileLocation) {
76
- const result = await Promise.all(( this.servers.map(
77
- ({ extensionManagementService }) => extensionManagementService.getInstalled(type, profileLocation)
78
- )));
79
- return flatten(result);
96
+ const onInstallExtensionEventMultiplexer = this._register(( new EventMultiplexer()));
97
+ this._register(onInstallExtensionEventMultiplexer.add(this._onInstallExtension.event));
98
+ this.onInstallExtension = onInstallExtensionEventMultiplexer.event;
99
+ const onDidInstallExtensionsEventMultiplexer = this._register(( new EventMultiplexer()));
100
+ this._register(onDidInstallExtensionsEventMultiplexer.add(this._onDidInstallExtensions.event));
101
+ this.onDidInstallExtensions = onDidInstallExtensionsEventMultiplexer.event;
102
+ const onUninstallExtensionEventMultiplexer = this._register(( new EventMultiplexer()));
103
+ this._register(onUninstallExtensionEventMultiplexer.add(this._onUninstallExtension.event));
104
+ this.onUninstallExtension = onUninstallExtensionEventMultiplexer.event;
105
+ const onDidUninstallExtensionEventMultiplexer = this._register(( new EventMultiplexer()));
106
+ this._register(onDidUninstallExtensionEventMultiplexer.add(this._onDidUninstallExtension.event));
107
+ this.onDidUninstallExtension = onDidUninstallExtensionEventMultiplexer.event;
108
+ const onDidUpdateExtensionMetadaEventMultiplexer = this._register(( new EventMultiplexer()));
109
+ this.onDidUpdateExtensionMetadata = onDidUpdateExtensionMetadaEventMultiplexer.event;
110
+ const onDidChangeProfileEventMultiplexer = this._register(( new EventMultiplexer()));
111
+ this.onDidChangeProfile = onDidChangeProfileEventMultiplexer.event;
112
+ for (const server of this.servers) {
113
+ this._register(onInstallExtensionEventMultiplexer.add(( Event.map(
114
+ server.extensionManagementService.onInstallExtension,
115
+ e => ({ ...e, server })
116
+ ))));
117
+ this._register(onDidInstallExtensionsEventMultiplexer.add(server.extensionManagementService.onDidInstallExtensions));
118
+ this._register(onUninstallExtensionEventMultiplexer.add(( Event.map(
119
+ server.extensionManagementService.onUninstallExtension,
120
+ e => ({ ...e, server })
121
+ ))));
122
+ this._register(onDidUninstallExtensionEventMultiplexer.add(( Event.map(
123
+ server.extensionManagementService.onDidUninstallExtension,
124
+ e => ({ ...e, server })
125
+ ))));
126
+ this._register(onDidUpdateExtensionMetadaEventMultiplexer.add(server.extensionManagementService.onDidUpdateExtensionMetadata));
127
+ this._register(onDidChangeProfileEventMultiplexer.add(( Event.map(
128
+ server.extensionManagementService.onDidChangeProfile,
129
+ e => ({ ...e, server })
130
+ ))));
131
+ }
132
+ }
133
+ isWorkspaceExtensionsSupported() {
134
+ return !!this.workspaceExtensionManagementService;
135
+ }
136
+ async getInstalled(type, profileLocation, productVersion) {
137
+ const result = [];
138
+ await Promise.all(( this.servers.map(async (server) => {
139
+ const installed = await server.extensionManagementService.getInstalled(type, profileLocation, productVersion);
140
+ if (server === this.getWorkspaceExtensionsServer()) {
141
+ const workspaceExtensions = await this.getInstalledWorkspaceExtensions(true);
142
+ installed.push(...workspaceExtensions);
143
+ }
144
+ result.push(...installed);
145
+ })));
146
+ return result;
80
147
  }
81
148
  async uninstall(extension, options) {
149
+ if (extension.isWorkspaceScoped) {
150
+ return this.uninstallExtensionFromWorkspace(extension);
151
+ }
82
152
  const server = this.getServer(extension);
83
153
  if (!server) {
84
154
  return Promise.reject(`Invalid location ${( extension.location.toString())}`);
@@ -152,7 +222,7 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
152
222
  async reinstallFromGallery(extension) {
153
223
  const server = this.getServer(extension);
154
224
  if (server) {
155
- await this.checkForWorkspaceTrust(extension.manifest);
225
+ await this.checkForWorkspaceTrust(extension.manifest, false);
156
226
  return server.extensionManagementService.reinstallFromGallery(extension);
157
227
  }
158
228
  return Promise.reject(`Invalid location ${( extension.location.toString())}`);
@@ -191,7 +261,7 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
191
261
  async installVSIX(vsix, manifest, options) {
192
262
  const serversToInstall = this.getServersToInstall(manifest);
193
263
  if (serversToInstall?.length) {
194
- await this.checkForWorkspaceTrust(manifest);
264
+ await this.checkForWorkspaceTrust(manifest, false);
195
265
  const [local] = await Promises.settled(( serversToInstall.map(server => this.installVSIXInServer(vsix, server, options))));
196
266
  return local;
197
267
  }
@@ -331,6 +401,113 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
331
401
  server => server.extensionManagementService.installFromGallery(gallery, installOptions)
332
402
  ))).then(([local]) => local);
333
403
  }
404
+ async getExtensions(locations) {
405
+ if (!this.workspaceExtensionManagementService) {
406
+ return [];
407
+ }
408
+ const scannedExtensions = await this.extensionsScannerService.scanMultipleExtensions(locations, 1 , { includeInvalid: true });
409
+ const result = [];
410
+ await Promise.all(( scannedExtensions.map(async (scannedExtension) => {
411
+ const workspaceExtension = await this.workspaceExtensionManagementService?.toLocalWorkspaceExtension(scannedExtension);
412
+ if (workspaceExtension) {
413
+ result.push({
414
+ identifier: workspaceExtension.identifier,
415
+ location: workspaceExtension.location,
416
+ manifest: workspaceExtension.manifest,
417
+ changelogUri: workspaceExtension.changelogUrl,
418
+ readmeUri: workspaceExtension.readmeUrl,
419
+ });
420
+ }
421
+ })));
422
+ return result;
423
+ }
424
+ async getInstalledWorkspaceExtensions(includeInvalid) {
425
+ return this.workspaceExtensionManagementService?.getInstalled(includeInvalid) ?? [];
426
+ }
427
+ async installResourceExtension(extension, installOptions) {
428
+ if (!installOptions.isWorkspaceScoped) {
429
+ return this.installFromLocation(extension.location);
430
+ }
431
+ if (!this.workspaceExtensionManagementService) {
432
+ throw new Error('Workspace Extensions are not supported');
433
+ }
434
+ this.logService.info(`Installing the extension ${extension.identifier.id} from ${( extension.location.toString())} in workspace`);
435
+ const server = this.getWorkspaceExtensionsServer();
436
+ this._onInstallExtension.fire({
437
+ identifier: extension.identifier,
438
+ source: extension.location,
439
+ server,
440
+ applicationScoped: false,
441
+ profileLocation: this.userDataProfileService.currentProfile.extensionsResource,
442
+ workspaceScoped: true
443
+ });
444
+ try {
445
+ await this.checkForWorkspaceTrust(extension.manifest, true);
446
+ const workspaceExtension = await this.workspaceExtensionManagementService.install(extension);
447
+ this.logService.info(`Successfully installed the extension ${workspaceExtension.identifier.id} from ${( extension.location.toString())} in the workspace`);
448
+ this._onDidInstallExtensions.fire([{
449
+ identifier: workspaceExtension.identifier,
450
+ source: extension.location,
451
+ operation: 2 ,
452
+ applicationScoped: false,
453
+ profileLocation: this.userDataProfileService.currentProfile.extensionsResource,
454
+ local: workspaceExtension,
455
+ workspaceScoped: true
456
+ }]);
457
+ return workspaceExtension;
458
+ }
459
+ catch (error) {
460
+ this.logService.error(`Failed to install the extension ${extension.identifier.id} from ${( extension.location.toString())} in the workspace`, getErrorMessage(error));
461
+ this._onDidInstallExtensions.fire([{
462
+ identifier: extension.identifier,
463
+ source: extension.location,
464
+ operation: 2 ,
465
+ applicationScoped: false,
466
+ profileLocation: this.userDataProfileService.currentProfile.extensionsResource,
467
+ error,
468
+ workspaceScoped: true
469
+ }]);
470
+ throw error;
471
+ }
472
+ }
473
+ async uninstallExtensionFromWorkspace(extension) {
474
+ if (!extension.isWorkspaceScoped) {
475
+ throw new Error('The extension is not a workspace extension');
476
+ }
477
+ if (!this.workspaceExtensionManagementService) {
478
+ throw new Error('Workspace Extensions are not supported');
479
+ }
480
+ this.logService.info(`Uninstalling the workspace extension ${extension.identifier.id} from ${( extension.location.toString())}`);
481
+ const server = this.getWorkspaceExtensionsServer();
482
+ this._onUninstallExtension.fire({
483
+ identifier: extension.identifier,
484
+ server,
485
+ applicationScoped: false,
486
+ workspaceScoped: true
487
+ });
488
+ try {
489
+ await this.workspaceExtensionManagementService.uninstall(extension);
490
+ this.logService.info(`Successfully uninstalled the workspace extension ${extension.identifier.id} from ${( extension.location.toString())}`);
491
+ this.telemetryService.publicLog2('workspaceextension:uninstall');
492
+ this._onDidUninstallExtension.fire({
493
+ identifier: extension.identifier,
494
+ server,
495
+ applicationScoped: false,
496
+ workspaceScoped: true
497
+ });
498
+ }
499
+ catch (error) {
500
+ this.logService.error(`Failed to uninstall the workspace extension ${extension.identifier.id} from ${( extension.location.toString())}`, getErrorMessage(error));
501
+ this._onDidUninstallExtension.fire({
502
+ identifier: extension.identifier,
503
+ server,
504
+ error,
505
+ applicationScoped: false,
506
+ workspaceScoped: true
507
+ });
508
+ throw error;
509
+ }
510
+ }
334
511
  async validateAndGetExtensionManagementServersToInstall(gallery, installOptions) {
335
512
  const manifest = await this.extensionGalleryService.getManifest(gallery, CancellationToken.None);
336
513
  if (!manifest) {
@@ -362,7 +539,7 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
362
539
  throw error;
363
540
  }
364
541
  if (!installOptions?.context?.[EXTENSION_INSTALL_SYNC_CONTEXT]) {
365
- await this.checkForWorkspaceTrust(manifest);
542
+ await this.checkForWorkspaceTrust(manifest, false);
366
543
  }
367
544
  if (!installOptions?.donotIncludePackAndDependencies) {
368
545
  await this.checkInstallingExtensionOnWeb(gallery, manifest);
@@ -393,7 +570,7 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
393
570
  async hasToFlagExtensionsMachineScoped(extensions) {
394
571
  if (this.isExtensionsSyncEnabled()) {
395
572
  const { result } = await this.dialogService.prompt({
396
- type: Severity.Info,
573
+ type: Severity$1.Info,
397
574
  message: extensions.length === 1 ? ( localizeWithPath(
398
575
  'vs/workbench/services/extensionManagement/common/extensionManagementService',
399
576
  'install extension',
@@ -456,33 +633,50 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
456
633
  return Promise.resolve({ malicious: [], deprecated: {}, search: [] });
457
634
  }
458
635
  getServer(extension) {
636
+ if (extension.isWorkspaceScoped) {
637
+ return this.getWorkspaceExtensionsServer();
638
+ }
459
639
  return this.extensionManagementServerService.getExtensionManagementServer(extension);
460
640
  }
461
- async checkForWorkspaceTrust(manifest) {
462
- if (this.extensionManifestPropertiesService.getExtensionUntrustedWorkspaceSupportType(manifest) === false) {
641
+ getWorkspaceExtensionsServer() {
642
+ if (this.extensionManagementServerService.remoteExtensionManagementServer) {
643
+ return this.extensionManagementServerService.remoteExtensionManagementServer;
644
+ }
645
+ if (this.extensionManagementServerService.localExtensionManagementServer) {
646
+ return this.extensionManagementServerService.localExtensionManagementServer;
647
+ }
648
+ if (this.extensionManagementServerService.webExtensionManagementServer) {
649
+ return this.extensionManagementServerService.webExtensionManagementServer;
650
+ }
651
+ throw new Error('No extension server found');
652
+ }
653
+ async checkForWorkspaceTrust(manifest, requireTrust) {
654
+ if (requireTrust || this.extensionManifestPropertiesService.getExtensionUntrustedWorkspaceSupportType(manifest) === false) {
655
+ const buttons = [];
656
+ buttons.push({ label: ( localizeWithPath(
657
+ 'vs/workbench/services/extensionManagement/common/extensionManagementService',
658
+ 'extensionInstallWorkspaceTrustButton',
659
+ "Trust Workspace & Install"
660
+ )), type: 'ContinueWithTrust' });
661
+ if (!requireTrust) {
662
+ buttons.push({ label: ( localizeWithPath(
663
+ 'vs/workbench/services/extensionManagement/common/extensionManagementService',
664
+ 'extensionInstallWorkspaceTrustContinueButton',
665
+ "Install"
666
+ )), type: 'ContinueWithoutTrust' });
667
+ }
668
+ buttons.push({ label: ( localizeWithPath(
669
+ 'vs/workbench/services/extensionManagement/common/extensionManagementService',
670
+ 'extensionInstallWorkspaceTrustManageButton',
671
+ "Learn More"
672
+ )), type: 'Manage' });
463
673
  const trustState = await this.workspaceTrustRequestService.requestWorkspaceTrust({
464
674
  message: ( localizeWithPath(
465
675
  'vs/workbench/services/extensionManagement/common/extensionManagementService',
466
676
  'extensionInstallWorkspaceTrustMessage',
467
677
  "Enabling this extension requires a trusted workspace."
468
678
  )),
469
- buttons: [
470
- { label: ( localizeWithPath(
471
- 'vs/workbench/services/extensionManagement/common/extensionManagementService',
472
- 'extensionInstallWorkspaceTrustButton',
473
- "Trust Workspace & Install"
474
- )), type: 'ContinueWithTrust' },
475
- { label: ( localizeWithPath(
476
- 'vs/workbench/services/extensionManagement/common/extensionManagementService',
477
- 'extensionInstallWorkspaceTrustContinueButton',
478
- "Install"
479
- )), type: 'ContinueWithoutTrust' },
480
- { label: ( localizeWithPath(
481
- 'vs/workbench/services/extensionManagement/common/extensionManagementService',
482
- 'extensionInstallWorkspaceTrustManageButton',
483
- "Learn More"
484
- )), type: 'Manage' }
485
- ]
679
+ buttons
486
680
  });
487
681
  if (trustState === undefined) {
488
682
  throw new CancellationError();
@@ -574,7 +768,7 @@ let ExtensionManagementService = class ExtensionManagementService extends Dispos
574
768
  ];
575
769
  }
576
770
  await this.dialogService.prompt({
577
- type: Severity.Info,
771
+ type: Severity$1.Info,
578
772
  message,
579
773
  detail,
580
774
  buttons,
@@ -627,7 +821,225 @@ ExtensionManagementService = ( __decorate([
627
821
  ( __param(9, IExtensionManifestPropertiesService)),
628
822
  ( __param(10, IFileService)),
629
823
  ( __param(11, ILogService)),
630
- ( __param(12, IInstantiationService))
824
+ ( __param(12, IInstantiationService)),
825
+ ( __param(13, IExtensionsScannerService)),
826
+ ( __param(14, ITelemetryService))
631
827
  ], ExtensionManagementService));
828
+ let WorkspaceExtensionsManagementService = class WorkspaceExtensionsManagementService extends Disposable {
829
+ static { WorkspaceExtensionsManagementService_1 = this; }
830
+ static { this.WORKSPACE_EXTENSIONS_KEY = 'workspaceExtensions.locations'; }
831
+ constructor(fileService, logService, workspaceService, extensionsScannerService, storageService, uriIdentityService, telemetryService) {
832
+ super();
833
+ this.fileService = fileService;
834
+ this.logService = logService;
835
+ this.workspaceService = workspaceService;
836
+ this.extensionsScannerService = extensionsScannerService;
837
+ this.storageService = storageService;
838
+ this.uriIdentityService = uriIdentityService;
839
+ this.telemetryService = telemetryService;
840
+ this._onDidChangeInvalidExtensions = this._register(( new Emitter()));
841
+ this.onDidChangeInvalidExtensions = this._onDidChangeInvalidExtensions.event;
842
+ this.extensions = [];
843
+ this.invalidExtensionWatchers = this._register(( new DisposableStore()));
844
+ this._register(Event.debounce(this.fileService.onDidFilesChange, (last, e) => {
845
+ (last = last ?? []).push(e);
846
+ return last;
847
+ }, 1000)(events => {
848
+ const changedInvalidExtensions = this.extensions.filter(extension => !extension.isValid && ( events.some(e => e.affects(extension.location))));
849
+ if (changedInvalidExtensions.length) {
850
+ this.checkExtensionsValidity(changedInvalidExtensions);
851
+ }
852
+ }));
853
+ this.initializePromise = this.initialize();
854
+ }
855
+ async initialize() {
856
+ const existingLocations = this.getWorkspaceExtensionsLocations();
857
+ if (!existingLocations.length) {
858
+ return;
859
+ }
860
+ await Promise.allSettled(( existingLocations.map(async (location) => {
861
+ if (!this.workspaceService.isInsideWorkspace(location)) {
862
+ this.logService.info(`Removing the workspace extension ${( location.toString())} as it is not inside the workspace`);
863
+ return;
864
+ }
865
+ if (!(await this.fileService.exists(location))) {
866
+ this.logService.info(`Removing the workspace extension ${( location.toString())} as it does not exist`);
867
+ return;
868
+ }
869
+ try {
870
+ const extension = await this.scanWorkspaceExtension(location);
871
+ if (extension) {
872
+ this.extensions.push(extension);
873
+ }
874
+ else {
875
+ this.logService.info(`Skipping workspace extension ${( location.toString())} as it does not exist`);
876
+ }
877
+ }
878
+ catch (error) {
879
+ this.logService.error('Skipping the workspace extension', ( location.toString()), error);
880
+ }
881
+ })));
882
+ this.saveWorkspaceExtensions();
883
+ }
884
+ watchInvalidExtensions() {
885
+ this.invalidExtensionWatchers.clear();
886
+ for (const extension of this.extensions) {
887
+ if (!extension.isValid) {
888
+ this.invalidExtensionWatchers.add(this.fileService.watch(extension.location));
889
+ }
890
+ }
891
+ }
892
+ async checkExtensionsValidity(extensions) {
893
+ const validExtensions = [];
894
+ await Promise.all(( extensions.map(async (extension) => {
895
+ const newExtension = await this.scanWorkspaceExtension(extension.location);
896
+ if (newExtension?.isValid) {
897
+ validExtensions.push(newExtension);
898
+ }
899
+ })));
900
+ let changed = false;
901
+ for (const extension of validExtensions) {
902
+ const index = this.extensions.findIndex(e => this.uriIdentityService.extUri.isEqual(e.location, extension.location));
903
+ if (index !== -1) {
904
+ changed = true;
905
+ this.extensions.splice(index, 1, extension);
906
+ }
907
+ }
908
+ if (changed) {
909
+ this.saveWorkspaceExtensions();
910
+ this._onDidChangeInvalidExtensions.fire(validExtensions);
911
+ }
912
+ }
913
+ async getInstalled(includeInvalid) {
914
+ await this.initializePromise;
915
+ return this.extensions.filter(e => includeInvalid || e.isValid);
916
+ }
917
+ async install(extension) {
918
+ await this.initializePromise;
919
+ const workspaceExtension = await this.scanWorkspaceExtension(extension.location);
920
+ if (!workspaceExtension) {
921
+ throw new Error('Cannot install the extension as it does not exist.');
922
+ }
923
+ const existingExtensionIndex = this.extensions.findIndex(e => areSameExtensions(e.identifier, extension.identifier));
924
+ if (existingExtensionIndex === -1) {
925
+ this.extensions.push(workspaceExtension);
926
+ }
927
+ else {
928
+ this.extensions.splice(existingExtensionIndex, 1, workspaceExtension);
929
+ }
930
+ this.saveWorkspaceExtensions();
931
+ this.telemetryService.publicLog2('workspaceextension:install');
932
+ return workspaceExtension;
933
+ }
934
+ async uninstall(extension) {
935
+ await this.initializePromise;
936
+ const existingExtensionIndex = this.extensions.findIndex(e => areSameExtensions(e.identifier, extension.identifier));
937
+ if (existingExtensionIndex !== -1) {
938
+ this.extensions.splice(existingExtensionIndex, 1);
939
+ this.saveWorkspaceExtensions();
940
+ }
941
+ this.telemetryService.publicLog2('workspaceextension:uninstall');
942
+ }
943
+ getWorkspaceExtensionsLocations() {
944
+ const locations = [];
945
+ try {
946
+ const parsed = JSON.parse(this.storageService.get(WorkspaceExtensionsManagementService_1.WORKSPACE_EXTENSIONS_KEY, 1 , '[]'));
947
+ if (Array.isArray(locations)) {
948
+ for (const location of parsed) {
949
+ if (isString(location)) {
950
+ if (this.workspaceService.getWorkbenchState() === 2 ) {
951
+ locations.push(this.workspaceService.getWorkspace().folders[0].toResource(location));
952
+ }
953
+ else {
954
+ this.logService.warn(`Invalid value for 'extensions' in workspace storage: ${location}`);
955
+ }
956
+ }
957
+ else {
958
+ locations.push(URI.revive(location));
959
+ }
960
+ }
961
+ }
962
+ else {
963
+ this.logService.warn(`Invalid value for 'extensions' in workspace storage: ${locations}`);
964
+ }
965
+ }
966
+ catch (error) {
967
+ this.logService.warn(`Error parsing workspace extensions locations: ${getErrorMessage(error)}`);
968
+ }
969
+ return locations;
970
+ }
971
+ saveWorkspaceExtensions() {
972
+ const locations = ( this.extensions.map(extension => extension.location));
973
+ if (this.workspaceService.getWorkbenchState() === 2 ) {
974
+ this.storageService.store(WorkspaceExtensionsManagementService_1.WORKSPACE_EXTENSIONS_KEY, JSON.stringify(coalesce(( locations
975
+ .map(
976
+ location => this.uriIdentityService.extUri.relativePath(this.workspaceService.getWorkspace().folders[0].uri, location)
977
+ )))), 1 , 1 );
978
+ }
979
+ else {
980
+ this.storageService.store(WorkspaceExtensionsManagementService_1.WORKSPACE_EXTENSIONS_KEY, JSON.stringify(locations), 1 , 1 );
981
+ }
982
+ this.watchInvalidExtensions();
983
+ }
984
+ async scanWorkspaceExtension(location) {
985
+ const scannedExtension = await this.extensionsScannerService.scanExistingExtension(location, 1 , { includeInvalid: true });
986
+ return scannedExtension ? this.toLocalWorkspaceExtension(scannedExtension) : null;
987
+ }
988
+ async toLocalWorkspaceExtension(extension) {
989
+ const stat = await this.fileService.resolve(extension.location);
990
+ let readmeUrl;
991
+ let changelogUrl;
992
+ if (stat.children) {
993
+ readmeUrl = stat.children.find(({ name }) => /^readme(\.txt|\.md|)$/i.test(name))?.resource;
994
+ changelogUrl = stat.children.find(({ name }) => /^changelog(\.txt|\.md|)$/i.test(name))?.resource;
995
+ }
996
+ const validations = [...extension.validations];
997
+ let isValid = extension.isValid;
998
+ if (extension.manifest.main) {
999
+ if (!(await this.fileService.exists(this.uriIdentityService.extUri.joinPath(extension.location, extension.manifest.main)))) {
1000
+ isValid = false;
1001
+ validations.push([Severity$1.Error, ( localizeWithPath(
1002
+ 'vs/workbench/services/extensionManagement/common/extensionManagementService',
1003
+ 'main.notFound',
1004
+ "Cannot activate, becase {0} not found",
1005
+ extension.manifest.main
1006
+ ))]);
1007
+ }
1008
+ }
1009
+ return {
1010
+ identifier: extension.identifier,
1011
+ type: extension.type,
1012
+ isBuiltin: extension.isBuiltin || !!extension.metadata?.isBuiltin,
1013
+ location: extension.location,
1014
+ manifest: extension.manifest,
1015
+ targetPlatform: extension.targetPlatform,
1016
+ validations,
1017
+ isValid,
1018
+ readmeUrl,
1019
+ changelogUrl,
1020
+ publisherDisplayName: extension.metadata?.publisherDisplayName || null,
1021
+ publisherId: extension.metadata?.publisherId || null,
1022
+ isApplicationScoped: !!extension.metadata?.isApplicationScoped,
1023
+ isMachineScoped: !!extension.metadata?.isMachineScoped,
1024
+ isPreReleaseVersion: !!extension.metadata?.isPreReleaseVersion,
1025
+ hasPreReleaseVersion: !!extension.metadata?.hasPreReleaseVersion,
1026
+ preRelease: !!extension.metadata?.preRelease,
1027
+ installedTimestamp: extension.metadata?.installedTimestamp,
1028
+ updated: !!extension.metadata?.updated,
1029
+ pinned: !!extension.metadata?.pinned,
1030
+ isWorkspaceScoped: true,
1031
+ source: 'resource'
1032
+ };
1033
+ }
1034
+ };
1035
+ WorkspaceExtensionsManagementService = WorkspaceExtensionsManagementService_1 = ( __decorate([
1036
+ ( __param(0, IFileService)),
1037
+ ( __param(1, ILogService)),
1038
+ ( __param(2, IWorkspaceContextService)),
1039
+ ( __param(3, IExtensionsScannerService)),
1040
+ ( __param(4, IStorageService)),
1041
+ ( __param(5, IUriIdentityService)),
1042
+ ( __param(6, ITelemetryService))
1043
+ ], WorkspaceExtensionsManagementService));
632
1044
 
633
1045
  export { ExtensionManagementService };
@@ -139,8 +139,8 @@ let WebExtensionManagementService = class WebExtensionManagementService extends
139
139
  async copyExtensions(fromProfileLocation, toProfileLocation) {
140
140
  await this.webExtensionsScannerService.copyExtensions(fromProfileLocation, toProfileLocation, e => !e.metadata?.isApplicationScoped);
141
141
  }
142
- async getCompatibleVersion(extension, sameVersion, includePreRelease) {
143
- const compatibleExtension = await super.getCompatibleVersion(extension, sameVersion, includePreRelease);
142
+ async getCompatibleVersion(extension, sameVersion, includePreRelease, productVersion) {
143
+ const compatibleExtension = await super.getCompatibleVersion(extension, sameVersion, includePreRelease, productVersion);
144
144
  if (compatibleExtension) {
145
145
  return compatibleExtension;
146
146
  }
@@ -213,6 +213,8 @@ function toLocalExtension(extension) {
213
213
  targetPlatform: "web" ,
214
214
  updated: !!metadata.updated,
215
215
  pinned: !!metadata?.pinned,
216
+ isWorkspaceScoped: false,
217
+ source: metadata?.source ?? (extension.identifier.uuid ? 'gallery' : 'resource')
216
218
  };
217
219
  }
218
220
  function getMetadata(options, existingExtension) {
@@ -255,6 +257,7 @@ class InstallExtensionTask extends AbstractExtensionTask {
255
257
  metadata.preRelease = isBoolean(this.options.preRelease)
256
258
  ? this.options.preRelease
257
259
  : this.options.installPreReleaseVersion || this.extension.properties.isPreReleaseVersion || metadata.preRelease;
260
+ metadata.source = URI.isUri(this.extension) ? 'resource' : 'gallery';
258
261
  }
259
262
  metadata.pinned = this.options.installGivenVersion ? true : (this.options.pinned ?? metadata.pinned);
260
263
  this._profileLocation = metadata.isApplicationScoped ? this.userDataProfilesService.defaultProfile.extensionsResource : this.options.profileLocation;