@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
@@ -2,7 +2,7 @@ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.e
2
2
  import { localizeWithPath } from 'vscode/vscode/vs/nls';
3
3
  import { semverExports } from '../../../../../../../external/vscode-semver/semver.js';
4
4
  import { Emitter, Event } from 'vscode/vscode/vs/base/common/event';
5
- import { index } from 'vscode/vscode/vs/base/common/arrays';
5
+ import { firstOrDefault, index } from 'vscode/vscode/vs/base/common/arrays';
6
6
  import { ThrottledDelayer, Promises, createCancelablePromise } from 'vscode/vscode/vs/base/common/async';
7
7
  import { CancellationError, isCancellationError } from 'vscode/vscode/vs/base/common/errors';
8
8
  import { Disposable, toDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
@@ -31,7 +31,7 @@ import { ILanguageService } from 'vscode/vscode/vs/editor/common/languages/langu
31
31
  import { IProductService } from 'vscode/vscode/vs/platform/product/common/productService';
32
32
  import { FileAccess } from 'vscode/vscode/vs/base/common/network';
33
33
  import { IIgnoredExtensionsManagementService } from 'vscode/vscode/vs/platform/userDataSync/common/ignoredExtensions';
34
- import { IUserDataAutoSyncService } from 'vscode/vscode/vs/platform/userDataSync/common/userDataSync';
34
+ import { IUserDataAutoSyncService, IUserDataSyncEnablementService } from 'vscode/vscode/vs/platform/userDataSync/common/userDataSync';
35
35
  import { IContextKeyService } from 'vscode/vscode/vs/platform/contextkey/common/contextkey';
36
36
  import { isUndefined, isBoolean, isString } from 'vscode/vscode/vs/base/common/types';
37
37
  import { IExtensionManifestPropertiesService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionManifestPropertiesService';
@@ -43,15 +43,21 @@ import { TelemetryTrustedValue } from 'vscode/vscode/vs/platform/telemetry/commo
43
43
  import { ILifecycleService } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
44
44
  import { IUserDataProfileService } from 'vscode/vscode/vs/workbench/services/userDataProfile/common/userDataProfile';
45
45
  import { mainWindow } from 'vscode/vscode/vs/base/browser/window';
46
+ import '../../../../../../../override/vs/platform/dialogs/common/dialogs.js';
47
+ import { IUpdateService } from 'vscode/vscode/vs/platform/update/common/update';
48
+ import { isEngineValid } from 'vscode/vscode/vs/platform/extensions/common/extensionValidator';
49
+ import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity';
50
+ import { IDialogService } from 'vscode/vscode/vs/platform/dialogs/common/dialogs';
46
51
 
47
52
  var Extensions_1, ExtensionsWorkbenchService_1;
48
53
  let Extension = class Extension {
49
- constructor(stateProvider, runtimeStateProvider, server, local, gallery, galleryService, telemetryService, logService, fileService, productService) {
54
+ constructor(stateProvider, runtimeStateProvider, server, local, gallery, resourceExtensionInfo, galleryService, telemetryService, logService, fileService, productService) {
50
55
  this.stateProvider = stateProvider;
51
56
  this.runtimeStateProvider = runtimeStateProvider;
52
57
  this.server = server;
53
58
  this.local = local;
54
59
  this.gallery = gallery;
60
+ this.resourceExtensionInfo = resourceExtensionInfo;
55
61
  this.galleryService = galleryService;
56
62
  this.telemetryService = telemetryService;
57
63
  this.logService = logService;
@@ -59,6 +65,7 @@ let Extension = class Extension {
59
65
  this.productService = productService;
60
66
  this.enablementState = 8 ;
61
67
  this.isMalicious = false;
68
+ this.resourceExtension = resourceExtensionInfo?.resourceExtension;
62
69
  }
63
70
  get type() {
64
71
  return this.local ? this.local.type : 1 ;
@@ -66,26 +73,44 @@ let Extension = class Extension {
66
73
  get isBuiltin() {
67
74
  return this.local ? this.local.isBuiltin : false;
68
75
  }
76
+ get isWorkspaceScoped() {
77
+ if (this.local) {
78
+ return this.local.isWorkspaceScoped;
79
+ }
80
+ if (this.resourceExtensionInfo) {
81
+ return this.resourceExtensionInfo.isWorkspaceScoped;
82
+ }
83
+ return false;
84
+ }
69
85
  get name() {
70
- return this.gallery ? this.gallery.name : this.local.manifest.name;
86
+ if (this.gallery) {
87
+ return this.gallery.name;
88
+ }
89
+ return this.getManifestFromLocalOrResource()?.name ?? '';
71
90
  }
72
91
  get displayName() {
73
92
  if (this.gallery) {
74
93
  return this.gallery.displayName || this.gallery.name;
75
94
  }
76
- return this.local.manifest.displayName || this.local.manifest.name;
95
+ return this.getManifestFromLocalOrResource()?.displayName ?? this.name;
77
96
  }
78
97
  get identifier() {
79
98
  if (this.gallery) {
80
99
  return this.gallery.identifier;
81
100
  }
101
+ if (this.resourceExtension) {
102
+ return this.resourceExtension.identifier;
103
+ }
82
104
  return this.local.identifier;
83
105
  }
84
106
  get uuid() {
85
- return this.gallery ? this.gallery.identifier.uuid : this.local.identifier.uuid;
107
+ return this.gallery ? this.gallery.identifier.uuid : this.local?.identifier.uuid;
86
108
  }
87
109
  get publisher() {
88
- return this.gallery ? this.gallery.publisher : this.local.manifest.publisher;
110
+ if (this.gallery) {
111
+ return this.gallery.publisher;
112
+ }
113
+ return this.getManifestFromLocalOrResource()?.publisher ?? '';
89
114
  }
90
115
  get publisherDisplayName() {
91
116
  if (this.gallery) {
@@ -94,7 +119,7 @@ let Extension = class Extension {
94
119
  if (this.local?.publisherDisplayName) {
95
120
  return this.local.publisherDisplayName;
96
121
  }
97
- return this.local.manifest.publisher;
122
+ return this.publisher;
98
123
  }
99
124
  get publisherUrl() {
100
125
  if (!this.productService.extensionsGallery || !this.gallery) {
@@ -115,10 +140,10 @@ let Extension = class Extension {
115
140
  return !!this.local?.pinned;
116
141
  }
117
142
  get latestVersion() {
118
- return this.gallery ? this.gallery.version : this.local.manifest.version;
143
+ return this.gallery ? this.gallery.version : this.getManifestFromLocalOrResource()?.version ?? '';
119
144
  }
120
145
  get description() {
121
- return this.gallery ? this.gallery.description : this.local.manifest.description || '';
146
+ return this.gallery ? this.gallery.description : this.getManifestFromLocalOrResource()?.description ?? '';
122
147
  }
123
148
  get url() {
124
149
  if (!this.productService.extensionsGallery || !this.gallery) {
@@ -127,10 +152,10 @@ let Extension = class Extension {
127
152
  return `${this.productService.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`;
128
153
  }
129
154
  get iconUrl() {
130
- return this.galleryIconUrl || this.localIconUrl || this.defaultIconUrl;
155
+ return this.galleryIconUrl || this.resourceExtensionIconUrl || this.localIconUrl || this.defaultIconUrl;
131
156
  }
132
157
  get iconUrlFallback() {
133
- return this.galleryIconUrlFallback || this.localIconUrl || this.defaultIconUrl;
158
+ return this.galleryIconUrlFallback || this.resourceExtensionIconUrl || this.localIconUrl || this.defaultIconUrl;
134
159
  }
135
160
  get localIconUrl() {
136
161
  if (this.local && this.local.manifest.icon) {
@@ -138,6 +163,12 @@ let Extension = class Extension {
138
163
  }
139
164
  return null;
140
165
  }
166
+ get resourceExtensionIconUrl() {
167
+ if (this.resourceExtension?.manifest.icon) {
168
+ return ( FileAccess.uriToBrowserUri(joinPath(this.resourceExtension.location, this.resourceExtension.manifest.icon)).toString(true));
169
+ }
170
+ return null;
171
+ }
141
172
  get galleryIconUrl() {
142
173
  return this.gallery?.assets.icon ? this.gallery.assets.icon.uri : null;
143
174
  }
@@ -207,7 +238,7 @@ let Extension = class Extension {
207
238
  && this.local.targetPlatform !== this.gallery.properties.targetPlatform
208
239
  && semverExports.eq(this.latestVersion, this.version);
209
240
  }
210
- get reloadRequiredStatus() {
241
+ get runtimeState() {
211
242
  return this.runtimeStateProvider(this);
212
243
  }
213
244
  get telemetryData() {
@@ -215,9 +246,12 @@ let Extension = class Extension {
215
246
  if (gallery) {
216
247
  return getGalleryExtensionTelemetryData(gallery);
217
248
  }
218
- else {
249
+ else if (local) {
219
250
  return getLocalExtensionTelemetryData(local);
220
251
  }
252
+ else {
253
+ return {};
254
+ }
221
255
  }
222
256
  get preview() {
223
257
  return this.local?.manifest.preview ?? this.gallery?.preview ?? false;
@@ -235,7 +269,7 @@ let Extension = class Extension {
235
269
  return !!this.gallery?.hasPreReleaseVersion || !!this.local?.hasPreReleaseVersion;
236
270
  }
237
271
  get hasReleaseVersion() {
238
- return !!this.gallery?.hasReleaseVersion;
272
+ return !!this.resourceExtension || !!this.gallery?.hasReleaseVersion;
239
273
  }
240
274
  getLocal() {
241
275
  return this.local && !this.outdated ? this.local : undefined;
@@ -256,6 +290,9 @@ let Extension = class Extension {
256
290
  )), this.identifier.id);
257
291
  return null;
258
292
  }
293
+ if (this.resourceExtension) {
294
+ return this.resourceExtension.manifest;
295
+ }
259
296
  return null;
260
297
  }
261
298
  hasReadme() {
@@ -265,6 +302,9 @@ let Extension = class Extension {
265
302
  if (this.gallery && this.gallery.assets.readme) {
266
303
  return true;
267
304
  }
305
+ if (this.resourceExtension?.readmeUri) {
306
+ return true;
307
+ }
268
308
  return this.type === 0 ;
269
309
  }
270
310
  async getReadme(token) {
@@ -286,6 +326,10 @@ let Extension = class Extension {
286
326
  ${this.description}
287
327
  `);
288
328
  }
329
+ if (this.resourceExtension?.readmeUri) {
330
+ const content = await this.fileService.readFile(this.resourceExtension?.readmeUri);
331
+ return ( content.value.toString());
332
+ }
289
333
  return Promise.reject(( new Error('not available')));
290
334
  }
291
335
  hasChangelog() {
@@ -312,13 +356,16 @@ ${this.description}
312
356
  return Promise.reject(( new Error('not available')));
313
357
  }
314
358
  get categories() {
315
- const { local, gallery } = this;
359
+ const { local, gallery, resourceExtension } = this;
316
360
  if (local && local.manifest.categories && !this.outdated) {
317
361
  return local.manifest.categories;
318
362
  }
319
363
  if (gallery) {
320
364
  return gallery.categories;
321
365
  }
366
+ if (resourceExtension) {
367
+ return resourceExtension.manifest.categories ?? [];
368
+ }
322
369
  return [];
323
370
  }
324
371
  get tags() {
@@ -329,32 +376,47 @@ ${this.description}
329
376
  return [];
330
377
  }
331
378
  get dependencies() {
332
- const { local, gallery } = this;
379
+ const { local, gallery, resourceExtension } = this;
333
380
  if (local && local.manifest.extensionDependencies && !this.outdated) {
334
381
  return local.manifest.extensionDependencies;
335
382
  }
336
383
  if (gallery) {
337
384
  return gallery.properties.dependencies || [];
338
385
  }
386
+ if (resourceExtension) {
387
+ return resourceExtension.manifest.extensionDependencies || [];
388
+ }
339
389
  return [];
340
390
  }
341
391
  get extensionPack() {
342
- const { local, gallery } = this;
392
+ const { local, gallery, resourceExtension } = this;
343
393
  if (local && local.manifest.extensionPack && !this.outdated) {
344
394
  return local.manifest.extensionPack;
345
395
  }
346
396
  if (gallery) {
347
397
  return gallery.properties.extensionPack || [];
348
398
  }
399
+ if (resourceExtension) {
400
+ return resourceExtension.manifest.extensionPack || [];
401
+ }
349
402
  return [];
350
403
  }
404
+ getManifestFromLocalOrResource() {
405
+ if (this.local) {
406
+ return this.local.manifest;
407
+ }
408
+ if (this.resourceExtension) {
409
+ return this.resourceExtension.manifest;
410
+ }
411
+ return null;
412
+ }
351
413
  };
352
414
  Extension = ( __decorate([
353
- ( __param(5, IExtensionGalleryService)),
354
- ( __param(6, ITelemetryService)),
355
- ( __param(7, ILogService)),
356
- ( __param(8, IFileService)),
357
- ( __param(9, IProductService))
415
+ ( __param(6, IExtensionGalleryService)),
416
+ ( __param(7, ITelemetryService)),
417
+ ( __param(8, ILogService)),
418
+ ( __param(9, IFileService)),
419
+ ( __param(10, IProductService))
358
420
  ], Extension));
359
421
  const EXTENSIONS_AUTO_UPDATE_KEY = 'extensions.autoUpdate';
360
422
  let Extensions = Extensions_1 = class Extensions extends Disposable {
@@ -364,13 +426,15 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
364
426
  }
365
427
  get onChange() { return this._onChange.event; }
366
428
  get onReset() { return this._onReset.event; }
367
- constructor(server, stateProvider, runtimeStateProvider, galleryService, extensionEnablementService, telemetryService, instantiationService) {
429
+ constructor(server, stateProvider, runtimeStateProvider, isWorkspaceServer, galleryService, extensionEnablementService, workbenchExtensionManagementService, telemetryService, instantiationService) {
368
430
  super();
369
431
  this.server = server;
370
432
  this.stateProvider = stateProvider;
371
433
  this.runtimeStateProvider = runtimeStateProvider;
434
+ this.isWorkspaceServer = isWorkspaceServer;
372
435
  this.galleryService = galleryService;
373
436
  this.extensionEnablementService = extensionEnablementService;
437
+ this.workbenchExtensionManagementService = workbenchExtensionManagementService;
374
438
  this.telemetryService = telemetryService;
375
439
  this.instantiationService = instantiationService;
376
440
  this._onChange = this._register(( new Emitter()));
@@ -386,6 +450,29 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
386
450
  this._register(server.extensionManagementService.onDidChangeProfile(() => this.reset()));
387
451
  this._register(extensionEnablementService.onEnablementChanged(e => this.onEnablementChanged(e)));
388
452
  this._register(Event.any(this.onChange, this.onReset)(() => this._local = undefined));
453
+ if (this.isWorkspaceServer) {
454
+ this._register(this.workbenchExtensionManagementService.onInstallExtension(e => {
455
+ if (e.workspaceScoped) {
456
+ this.onInstallExtension(e);
457
+ }
458
+ }));
459
+ this._register(this.workbenchExtensionManagementService.onDidInstallExtensions(e => {
460
+ const result = e.filter(e => e.workspaceScoped);
461
+ if (result.length) {
462
+ this.onDidInstallExtensions(result);
463
+ }
464
+ }));
465
+ this._register(this.workbenchExtensionManagementService.onUninstallExtension(e => {
466
+ if (e.workspaceScoped) {
467
+ this.onUninstallExtension(e.identifier);
468
+ }
469
+ }));
470
+ this._register(this.workbenchExtensionManagementService.onDidUninstallExtension(e => {
471
+ if (e.workspaceScoped) {
472
+ this.onDidUninstallExtension(e);
473
+ }
474
+ }));
475
+ }
389
476
  }
390
477
  get local() {
391
478
  if (!this._local) {
@@ -401,14 +488,13 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
401
488
  }
402
489
  return this._local;
403
490
  }
404
- async queryInstalled() {
405
- await this.fetchInstalledExtensions();
491
+ async queryInstalled(productVersion) {
492
+ await this.fetchInstalledExtensions(productVersion);
406
493
  this._onChange.fire(undefined);
407
494
  return this.local;
408
495
  }
409
- async syncInstalledExtensionsWithGallery(galleryExtensions) {
410
- let hasChanged = false;
411
- const extensions = await this.mapInstalledExtensionWithCompatibleGalleryExtension(galleryExtensions);
496
+ async syncInstalledExtensionsWithGallery(galleryExtensions, productVersion) {
497
+ const extensions = await this.mapInstalledExtensionWithCompatibleGalleryExtension(galleryExtensions, productVersion);
412
498
  for (const [extension, gallery] of extensions) {
413
499
  if (extension.local && !extension.local.identifier.uuid) {
414
500
  extension.local = await this.updateMetadata(extension.local, gallery);
@@ -416,19 +502,17 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
416
502
  if (!extension.gallery || extension.gallery.version !== gallery.version || extension.gallery.properties.targetPlatform !== gallery.properties.targetPlatform) {
417
503
  extension.gallery = gallery;
418
504
  this._onChange.fire({ extension });
419
- hasChanged = true;
420
505
  }
421
506
  }
422
- return hasChanged;
423
507
  }
424
- async mapInstalledExtensionWithCompatibleGalleryExtension(galleryExtensions) {
508
+ async mapInstalledExtensionWithCompatibleGalleryExtension(galleryExtensions, productVersion) {
425
509
  const mappedExtensions = this.mapInstalledExtensionWithGalleryExtension(galleryExtensions);
426
510
  const targetPlatform = await this.server.extensionManagementService.getTargetPlatform();
427
511
  const compatibleGalleryExtensions = [];
428
512
  const compatibleGalleryExtensionsToFetch = [];
429
513
  await Promise.allSettled(( mappedExtensions.map(async ([extension, gallery]) => {
430
514
  if (extension.local) {
431
- if (await this.galleryService.isExtensionCompatible(gallery, extension.local.preRelease, targetPlatform)) {
515
+ if (await this.galleryService.isExtensionCompatible(gallery, extension.local.preRelease, targetPlatform, productVersion)) {
432
516
  compatibleGalleryExtensions.push(gallery);
433
517
  }
434
518
  else {
@@ -437,7 +521,7 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
437
521
  }
438
522
  })));
439
523
  if (compatibleGalleryExtensionsToFetch.length) {
440
- const result = await this.galleryService.getExtensions(compatibleGalleryExtensionsToFetch, { targetPlatform, compatible: true, queryAllVersions: true }, CancellationToken.None);
524
+ const result = await this.galleryService.getExtensions(compatibleGalleryExtensionsToFetch, { targetPlatform, compatible: true, queryAllVersions: true, productVersion }, CancellationToken.None);
441
525
  compatibleGalleryExtensions.push(...result);
442
526
  }
443
527
  return this.mapInstalledExtensionWithGalleryExtension(compatibleGalleryExtensions);
@@ -457,9 +541,11 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
457
541
  continue;
458
542
  }
459
543
  }
460
- const gallery = byID.get(installed.identifier.id.toLowerCase());
461
- if (gallery) {
462
- mappedExtensions.push([installed, gallery]);
544
+ if (installed.local?.source !== 'resource') {
545
+ const gallery = byID.get(installed.identifier.id.toLowerCase());
546
+ if (gallery) {
547
+ mappedExtensions.push([installed, gallery]);
548
+ }
463
549
  }
464
550
  }
465
551
  return mappedExtensions;
@@ -479,15 +565,18 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
479
565
  onInstallExtension(event) {
480
566
  const { source } = event;
481
567
  if (source && !URI.isUri(source)) {
482
- const extension = this.installed.filter(e => areSameExtensions(e.identifier, source.identifier))[0]
483
- || this.instantiationService.createInstance(Extension, this.stateProvider, this.runtimeStateProvider, this.server, undefined, source);
568
+ const extension = this.installed.find(e => areSameExtensions(e.identifier, source.identifier))
569
+ ?? this.instantiationService.createInstance(Extension, this.stateProvider, this.runtimeStateProvider, this.server, undefined, source, undefined);
484
570
  this.installing.push(extension);
485
571
  this._onChange.fire({ extension });
486
572
  }
487
573
  }
488
- async fetchInstalledExtensions() {
574
+ async fetchInstalledExtensions(productVersion) {
489
575
  const extensionsControlManifest = await this.server.extensionManagementService.getExtensionsControlManifest();
490
- const all = await this.server.extensionManagementService.getInstalled();
576
+ const all = await this.server.extensionManagementService.getInstalled(undefined, undefined, productVersion);
577
+ if (this.isWorkspaceServer) {
578
+ all.push(...(await this.workbenchExtensionManagementService.getInstalledWorkspaceExtensions(true)));
579
+ }
491
580
  const installed = groupByExtension(all, r => r.identifier).reduce((result, extensions) => {
492
581
  const extension = extensions.length === 1 ? extensions[0]
493
582
  : extensions.find(e => e.type === 1 ) || extensions.find(e => e.type === 0 );
@@ -496,7 +585,7 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
496
585
  }, []);
497
586
  const byId = index(this.installed, e => e.local ? e.local.identifier.id : e.identifier.id);
498
587
  this.installed = ( installed.map(local => {
499
- const extension = byId[local.identifier.id] || this.instantiationService.createInstance(Extension, this.stateProvider, this.runtimeStateProvider, this.server, local, undefined);
588
+ const extension = byId[local.identifier.id] || this.instantiationService.createInstance(Extension, this.stateProvider, this.runtimeStateProvider, this.server, local, undefined, undefined);
500
589
  extension.local = local;
501
590
  extension.enablementState = this.extensionEnablementService.getEnablementState(local);
502
591
  Extensions_1.updateExtensionFromControlManifest(extension, extensionsControlManifest);
@@ -518,7 +607,7 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
518
607
  const installingExtension = gallery ? this.installing.filter(e => areSameExtensions(e.identifier, gallery.identifier))[0] : null;
519
608
  this.installing = installingExtension ? this.installing.filter(e => e !== installingExtension) : this.installing;
520
609
  let extension = installingExtension ? installingExtension
521
- : (location || local) ? this.instantiationService.createInstance(Extension, this.stateProvider, this.runtimeStateProvider, this.server, local, undefined)
610
+ : (location || local) ? this.instantiationService.createInstance(Extension, this.stateProvider, this.runtimeStateProvider, this.server, local, undefined, undefined)
522
611
  : undefined;
523
612
  if (extension) {
524
613
  if (local) {
@@ -538,7 +627,7 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
538
627
  }
539
628
  }
540
629
  this._onChange.fire(!local || !extension ? undefined : { extension, operation: event.operation });
541
- if (extension && extension.local && !extension.gallery) {
630
+ if (extension && extension.local && !extension.gallery && extension.local.source !== 'resource') {
542
631
  await this.syncInstalledExtensionWithGallery(extension);
543
632
  }
544
633
  }
@@ -609,17 +698,18 @@ let Extensions = Extensions_1 = class Extensions extends Disposable {
609
698
  }
610
699
  };
611
700
  Extensions = Extensions_1 = ( __decorate([
612
- ( __param(3, IExtensionGalleryService)),
613
- ( __param(4, IWorkbenchExtensionEnablementService)),
614
- ( __param(5, ITelemetryService)),
615
- ( __param(6, IInstantiationService))
701
+ ( __param(4, IExtensionGalleryService)),
702
+ ( __param(5, IWorkbenchExtensionEnablementService)),
703
+ ( __param(6, IWorkbenchExtensionManagementService)),
704
+ ( __param(7, ITelemetryService)),
705
+ ( __param(8, IInstantiationService))
616
706
  ], Extensions));
617
707
  let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Disposable {
618
708
  static { ExtensionsWorkbenchService_1 = this; }
619
709
  static { this.UpdatesCheckInterval = 1000 * 60 * 60 * 12; }
620
710
  get onChange() { return this._onChange.event; }
621
711
  get onReset() { return this._onReset.event; }
622
- constructor(instantiationService, editorService, extensionManagementService, galleryService, configurationService, telemetryService, notificationService, urlService, extensionEnablementService, hostService, progressService, extensionManagementServerService, languageService, extensionsSyncManagementService, userDataAutoSyncService, productService, contextKeyService, extensionManifestPropertiesService, logService, extensionService, localeService, lifecycleService, fileService, userDataProfileService, storageService) {
712
+ constructor(instantiationService, editorService, extensionManagementService, galleryService, configurationService, telemetryService, notificationService, urlService, extensionEnablementService, hostService, progressService, extensionManagementServerService, languageService, extensionsSyncManagementService, userDataAutoSyncService, productService, contextKeyService, extensionManifestPropertiesService, logService, extensionService, localeService, lifecycleService, fileService, userDataProfileService, storageService, dialogService, userDataSyncEnablementService, updateService, uriIdentityService) {
623
713
  super();
624
714
  this.instantiationService = instantiationService;
625
715
  this.editorService = editorService;
@@ -644,6 +734,10 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
644
734
  this.fileService = fileService;
645
735
  this.userDataProfileService = userDataProfileService;
646
736
  this.storageService = storageService;
737
+ this.dialogService = dialogService;
738
+ this.userDataSyncEnablementService = userDataSyncEnablementService;
739
+ this.updateService = updateService;
740
+ this.uriIdentityService = uriIdentityService;
647
741
  this.localExtensions = null;
648
742
  this.remoteExtensions = null;
649
743
  this.webExtensions = null;
@@ -659,19 +753,19 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
659
753
  }
660
754
  this.hasOutdatedExtensionsContextKey = HasOutdatedExtensionsContext.bindTo(contextKeyService);
661
755
  if (extensionManagementServerService.localExtensionManagementServer) {
662
- this.localExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.localExtensionManagementServer, ext => this.getExtensionState(ext), ext => this.getReloadStatus(ext)));
756
+ this.localExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.localExtensionManagementServer, ext => this.getExtensionState(ext), ext => this.getRuntimeState(ext), !extensionManagementServerService.remoteExtensionManagementServer));
663
757
  this._register(this.localExtensions.onChange(e => this.onDidChangeExtensions(e?.extension)));
664
758
  this._register(this.localExtensions.onReset(e => this.reset()));
665
759
  this.extensionsServers.push(this.localExtensions);
666
760
  }
667
761
  if (extensionManagementServerService.remoteExtensionManagementServer) {
668
- this.remoteExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.remoteExtensionManagementServer, ext => this.getExtensionState(ext), ext => this.getReloadStatus(ext)));
762
+ this.remoteExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.remoteExtensionManagementServer, ext => this.getExtensionState(ext), ext => this.getRuntimeState(ext), true));
669
763
  this._register(this.remoteExtensions.onChange(e => this.onDidChangeExtensions(e?.extension)));
670
764
  this._register(this.remoteExtensions.onReset(e => this.reset()));
671
765
  this.extensionsServers.push(this.remoteExtensions);
672
766
  }
673
767
  if (extensionManagementServerService.webExtensionManagementServer) {
674
- this.webExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.webExtensionManagementServer, ext => this.getExtensionState(ext), ext => this.getReloadStatus(ext)));
768
+ this.webExtensions = this._register(instantiationService.createInstance(Extensions, extensionManagementServerService.webExtensionManagementServer, ext => this.getExtensionState(ext), ext => this.getRuntimeState(ext), !(extensionManagementServerService.remoteExtensionManagementServer || extensionManagementServerService.localExtensionManagementServer)));
675
769
  this._register(this.webExtensions.onChange(e => this.onDidChangeExtensions(e?.extension)));
676
770
  this._register(this.webExtensions.onReset(e => this.reset()));
677
771
  this.extensionsServers.push(this.webExtensions);
@@ -718,6 +812,14 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
718
812
  }
719
813
  }));
720
814
  this._register(Event.debounce(this.onChange, () => undefined, 100)(() => this.hasOutdatedExtensionsContextKey.set(this.outdated.length > 0)));
815
+ this._register(this.updateService.onStateChange(e => {
816
+ if (!this.isAutoUpdateEnabled()) {
817
+ return;
818
+ }
819
+ if ((e.type === "checking for updates" && e.explicit) || e.type === "available for download" || e.type === "downloaded" ) {
820
+ this.eventuallyCheckForUpdates(true);
821
+ }
822
+ }));
721
823
  this.hasOutdatedExtensionsContextKey.set(this.outdated.length > 0);
722
824
  this.eventuallyCheckForUpdates(true);
723
825
  if (isWeb) {
@@ -801,18 +903,18 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
801
903
  async queryLocal(server) {
802
904
  if (server) {
803
905
  if (this.localExtensions && this.extensionManagementServerService.localExtensionManagementServer === server) {
804
- return this.localExtensions.queryInstalled();
906
+ return this.localExtensions.queryInstalled(this.getProductVersion());
805
907
  }
806
908
  if (this.remoteExtensions && this.extensionManagementServerService.remoteExtensionManagementServer === server) {
807
- return this.remoteExtensions.queryInstalled();
909
+ return this.remoteExtensions.queryInstalled(this.getProductVersion());
808
910
  }
809
911
  if (this.webExtensions && this.extensionManagementServerService.webExtensionManagementServer === server) {
810
- return this.webExtensions.queryInstalled();
912
+ return this.webExtensions.queryInstalled(this.getProductVersion());
811
913
  }
812
914
  }
813
915
  if (this.localExtensions) {
814
916
  try {
815
- await this.localExtensions.queryInstalled();
917
+ await this.localExtensions.queryInstalled(this.getProductVersion());
816
918
  }
817
919
  catch (error) {
818
920
  this.logService.error(error);
@@ -820,7 +922,7 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
820
922
  }
821
923
  if (this.remoteExtensions) {
822
924
  try {
823
- await this.remoteExtensions.queryInstalled();
925
+ await this.remoteExtensions.queryInstalled(this.getProductVersion());
824
926
  }
825
927
  catch (error) {
826
928
  this.logService.error(error);
@@ -828,7 +930,7 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
828
930
  }
829
931
  if (this.webExtensions) {
830
932
  try {
831
- await this.webExtensions.queryInstalled();
933
+ await this.webExtensions.queryInstalled(this.getProductVersion());
832
934
  }
833
935
  catch (error) {
834
936
  this.logService.error(error);
@@ -868,6 +970,13 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
868
970
  this.syncInstalledExtensionsWithGallery(galleryExtensions);
869
971
  return ( galleryExtensions.map(gallery => this.fromGallery(gallery, extensionsControlManifest)));
870
972
  }
973
+ async getResourceExtensions(locations, isWorkspaceScoped) {
974
+ const resourceExtensions = await this.extensionManagementService.getExtensions(locations);
975
+ return ( resourceExtensions.map(
976
+ resourceExtension => this.getInstalledExtensionMatchingLocation(resourceExtension.location)
977
+ ?? this.instantiationService.createInstance(Extension, ext => this.getExtensionState(ext), ext => this.getRuntimeState(ext), undefined, undefined, undefined, { resourceExtension, isWorkspaceScoped })
978
+ ));
979
+ }
871
980
  resolveQueryText(text) {
872
981
  text = text.replace(/@web/g, `tag:"${WEB_EXTENSION_TAG}"`);
873
982
  const extensionRegex = /\bext:([^\s]+)\b/g;
@@ -886,7 +995,7 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
886
995
  fromGallery(gallery, extensionsControlManifest) {
887
996
  let extension = this.getInstalledExtensionMatchingGallery(gallery);
888
997
  if (!extension) {
889
- extension = this.instantiationService.createInstance(Extension, ext => this.getExtensionState(ext), ext => this.getReloadStatus(ext), undefined, undefined, gallery);
998
+ extension = this.instantiationService.createInstance(Extension, ext => this.getExtensionState(ext), ext => this.getRuntimeState(ext), undefined, undefined, gallery, undefined);
890
999
  Extensions.updateExtensionFromControlManifest(extension, extensionsControlManifest);
891
1000
  }
892
1001
  return extension;
@@ -898,7 +1007,7 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
898
1007
  return installed;
899
1008
  }
900
1009
  }
901
- else {
1010
+ else if (installed.local?.source !== 'resource') {
902
1011
  if (areSameExtensions(installed.identifier, gallery.identifier)) {
903
1012
  return installed;
904
1013
  }
@@ -906,6 +1015,9 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
906
1015
  }
907
1016
  return null;
908
1017
  }
1018
+ getInstalledExtensionMatchingLocation(location) {
1019
+ return this.local.find(e => e.local && this.uriIdentityService.extUri.isEqualOrParent(location, e.local?.location)) ?? null;
1020
+ }
909
1021
  async open(extension, options) {
910
1022
  if (typeof extension === 'string') {
911
1023
  const id = extension;
@@ -925,18 +1037,74 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
925
1037
  }
926
1038
  return undefined;
927
1039
  }
928
- getReloadStatus(extension) {
1040
+ async updateRunningExtensions() {
1041
+ const toAdd = [];
1042
+ const toRemove = [];
1043
+ const extensionsToCheck = [...this.local];
1044
+ const notExistingRunningExtensions = this.extensionService.extensions.filter(e => !( this.local.some(
1045
+ local => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, local.identifier)
1046
+ )));
1047
+ if (notExistingRunningExtensions.length) {
1048
+ const extensions = await this.getExtensions(( notExistingRunningExtensions.map(e => ({ id: e.identifier.value }))), CancellationToken.None);
1049
+ extensionsToCheck.push(...extensions);
1050
+ }
1051
+ for (const extension of extensionsToCheck) {
1052
+ const runtimeState = extension.runtimeState;
1053
+ if (!runtimeState || runtimeState.action !== "restartExtensions" ) {
1054
+ continue;
1055
+ }
1056
+ if (extension.state === 3 ) {
1057
+ toRemove.push(extension.identifier.id);
1058
+ continue;
1059
+ }
1060
+ if (!extension.local) {
1061
+ continue;
1062
+ }
1063
+ const isEnabled = this.extensionEnablementService.isEnabled(extension.local);
1064
+ if (isEnabled) {
1065
+ const runningExtension = this.extensionService.extensions.find(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, extension.identifier));
1066
+ if (runningExtension) {
1067
+ toRemove.push(runningExtension.identifier.value);
1068
+ }
1069
+ toAdd.push(extension.local);
1070
+ }
1071
+ else {
1072
+ toRemove.push(extension.identifier.id);
1073
+ }
1074
+ }
1075
+ if (toAdd.length || toRemove.length) {
1076
+ if (await this.extensionService.stopExtensionHosts(( localizeWithPath(
1077
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1078
+ 'restart',
1079
+ "Enable or Disable extensions"
1080
+ )))) {
1081
+ await this.extensionService.startExtensionHosts({ toAdd, toRemove });
1082
+ }
1083
+ }
1084
+ }
1085
+ getRuntimeState(extension) {
929
1086
  const isUninstalled = extension.state === 3 ;
930
1087
  const runningExtension = this.extensionService.extensions.find(e => areSameExtensions({ id: e.identifier.value, uuid: e.uuid }, extension.identifier));
1088
+ const reloadAction = this.extensionManagementServerService.remoteExtensionManagementServer ? "reloadWindow" : "restartExtensions" ;
1089
+ const reloadActionLabel = reloadAction === "reloadWindow" ? ( localizeWithPath(
1090
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1091
+ 'reload',
1092
+ "reload window"
1093
+ )) : ( localizeWithPath(
1094
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1095
+ 'restart extensions',
1096
+ "restart extensions"
1097
+ ));
931
1098
  if (isUninstalled) {
932
1099
  const canRemoveRunningExtension = runningExtension && this.extensionService.canRemoveExtension(runningExtension);
933
1100
  const isSameExtensionRunning = runningExtension && (!extension.server || extension.server === this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension)));
934
1101
  if (!canRemoveRunningExtension && isSameExtensionRunning && !runningExtension.isUnderDevelopment) {
935
- return ( localizeWithPath(
1102
+ return { action: reloadAction, reason: ( localizeWithPath(
936
1103
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
937
1104
  'postUninstallTooltip',
938
- "Please reload Visual Studio Code to complete the uninstallation of this extension."
939
- ));
1105
+ "Please {0} to complete the uninstallation of this extension.",
1106
+ reloadActionLabel
1107
+ )) };
940
1108
  }
941
1109
  return undefined;
942
1110
  }
@@ -951,29 +1119,64 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
951
1119
  const runningExtensionServer = this.extensionManagementServerService.getExtensionManagementServer(toExtension(runningExtension));
952
1120
  if (isSameExtensionRunning) {
953
1121
  if (!runningExtension.isUnderDevelopment && (extension.version !== runningExtension.version || extension.local.targetPlatform !== runningExtension.targetPlatform)) {
954
- return ( localizeWithPath(
1122
+ const productCurrentVersion = this.getProductCurrentVersion();
1123
+ const productUpdateVersion = this.getProductUpdateVersion();
1124
+ if (productUpdateVersion
1125
+ && !isEngineValid(extension.local.manifest.engines.vscode, productCurrentVersion.version, productCurrentVersion.date)
1126
+ && isEngineValid(extension.local.manifest.engines.vscode, productUpdateVersion.version, productUpdateVersion.date)) {
1127
+ const state = this.updateService.state;
1128
+ if (state.type === "available for download" ) {
1129
+ return { action: "downloadUpdate" , reason: ( localizeWithPath(
1130
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1131
+ 'postUpdateDownloadTooltip',
1132
+ "Please update {0} to enable the updated extension.",
1133
+ this.productService.nameLong
1134
+ )) };
1135
+ }
1136
+ if (state.type === "downloaded" ) {
1137
+ return { action: "applyUpdate" , reason: ( localizeWithPath(
1138
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1139
+ 'postUpdateUpdateTooltip',
1140
+ "Please update {0} to enable the updated extension.",
1141
+ this.productService.nameLong
1142
+ )) };
1143
+ }
1144
+ if (state.type === "ready" ) {
1145
+ return { action: "quitAndInstall" , reason: ( localizeWithPath(
1146
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1147
+ 'postUpdateRestartTooltip',
1148
+ "Please restart {0} to enable the updated extension.",
1149
+ this.productService.nameLong
1150
+ )) };
1151
+ }
1152
+ return undefined;
1153
+ }
1154
+ return { action: reloadAction, reason: ( localizeWithPath(
955
1155
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
956
1156
  'postUpdateTooltip',
957
- "Please reload Visual Studio Code to enable the updated extension."
958
- ));
1157
+ "Please {0} to enable the updated extension.",
1158
+ reloadActionLabel
1159
+ )) };
959
1160
  }
960
1161
  if (this.extensionsServers.length > 1) {
961
1162
  const extensionInOtherServer = this.installed.filter(e => areSameExtensions(e.identifier, extension.identifier) && e.server !== extension.server)[0];
962
1163
  if (extensionInOtherServer) {
963
1164
  if (runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer && this.extensionManifestPropertiesService.prefersExecuteOnUI(extension.local.manifest) && extensionInOtherServer.server === this.extensionManagementServerService.localExtensionManagementServer) {
964
- return ( localizeWithPath(
1165
+ return { action: reloadAction, reason: ( localizeWithPath(
965
1166
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
966
1167
  'enable locally',
967
- "Please reload Visual Studio Code to enable this extension locally."
968
- ));
1168
+ "Please {0} to enable this extension locally.",
1169
+ reloadActionLabel
1170
+ )) };
969
1171
  }
970
1172
  if (runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer && this.extensionManifestPropertiesService.prefersExecuteOnWorkspace(extension.local.manifest) && extensionInOtherServer.server === this.extensionManagementServerService.remoteExtensionManagementServer) {
971
- return ( localizeWithPath(
1173
+ return { action: reloadAction, reason: ( localizeWithPath(
972
1174
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
973
1175
  'enable remote',
974
- "Please reload Visual Studio Code to enable this extension in {0}.",
1176
+ "Please {0} to enable this extension in {1}.",
1177
+ reloadActionLabel,
975
1178
  this.extensionManagementServerService.remoteExtensionManagementServer?.label
976
- ));
1179
+ )) };
977
1180
  }
978
1181
  }
979
1182
  }
@@ -981,20 +1184,22 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
981
1184
  else {
982
1185
  if (extension.server === this.extensionManagementServerService.localExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.remoteExtensionManagementServer) {
983
1186
  if (this.extensionManifestPropertiesService.prefersExecuteOnUI(extension.local.manifest)) {
984
- return ( localizeWithPath(
1187
+ return { action: reloadAction, reason: ( localizeWithPath(
985
1188
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
986
1189
  'postEnableTooltip',
987
- "Please reload Visual Studio Code to enable this extension."
988
- ));
1190
+ "Please {0} to enable this extension.",
1191
+ reloadActionLabel
1192
+ )) };
989
1193
  }
990
1194
  }
991
1195
  if (extension.server === this.extensionManagementServerService.remoteExtensionManagementServer && runningExtensionServer === this.extensionManagementServerService.localExtensionManagementServer) {
992
1196
  if (this.extensionManifestPropertiesService.prefersExecuteOnWorkspace(extension.local.manifest)) {
993
- return ( localizeWithPath(
1197
+ return { action: reloadAction, reason: ( localizeWithPath(
994
1198
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
995
1199
  'postEnableTooltip',
996
- "Please reload Visual Studio Code to enable this extension."
997
- ));
1200
+ "Please {0} to enable this extension.",
1201
+ reloadActionLabel
1202
+ )) };
998
1203
  }
999
1204
  }
1000
1205
  }
@@ -1002,32 +1207,35 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1002
1207
  }
1003
1208
  else {
1004
1209
  if (isSameExtensionRunning) {
1005
- return ( localizeWithPath(
1210
+ return { action: reloadAction, reason: ( localizeWithPath(
1006
1211
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1007
1212
  'postDisableTooltip',
1008
- "Please reload Visual Studio Code to disable this extension."
1009
- ));
1213
+ "Please {0} to disable this extension.",
1214
+ reloadActionLabel
1215
+ )) };
1010
1216
  }
1011
1217
  }
1012
1218
  return undefined;
1013
1219
  }
1014
1220
  else {
1015
1221
  if (isEnabled && !this.extensionService.canAddExtension(toExtensionDescription(extension.local))) {
1016
- return ( localizeWithPath(
1222
+ return { action: reloadAction, reason: ( localizeWithPath(
1017
1223
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1018
1224
  'postEnableTooltip',
1019
- "Please reload Visual Studio Code to enable this extension."
1020
- ));
1225
+ "Please {0} to enable this extension.",
1226
+ reloadActionLabel
1227
+ )) };
1021
1228
  }
1022
1229
  const otherServer = extension.server ? extension.server === this.extensionManagementServerService.localExtensionManagementServer ? this.extensionManagementServerService.remoteExtensionManagementServer : this.extensionManagementServerService.localExtensionManagementServer : null;
1023
1230
  if (otherServer && extension.enablementState === 1 ) {
1024
1231
  const extensionInOtherServer = this.local.filter(e => areSameExtensions(e.identifier, extension.identifier) && e.server === otherServer)[0];
1025
1232
  if (extensionInOtherServer && extensionInOtherServer.local && this.extensionEnablementService.isEnabled(extensionInOtherServer.local)) {
1026
- return ( localizeWithPath(
1233
+ return { action: reloadAction, reason: ( localizeWithPath(
1027
1234
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1028
1235
  'postEnableTooltip',
1029
- "Please reload Visual Studio Code to enable this extension."
1030
- ));
1236
+ "Please {0} to enable this extension.",
1237
+ reloadActionLabel
1238
+ )) };
1031
1239
  }
1032
1240
  }
1033
1241
  }
@@ -1176,6 +1384,9 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1176
1384
  if (installed.isBuiltin && !installed.local?.pinned && (installed.type === 0 || !installed.local?.identifier.uuid)) {
1177
1385
  continue;
1178
1386
  }
1387
+ if (installed.local?.source === 'resource') {
1388
+ continue;
1389
+ }
1179
1390
  infos.push({ ...installed.identifier, preRelease: !!installed.local?.preRelease });
1180
1391
  }
1181
1392
  if (infos.length) {
@@ -1183,7 +1394,7 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1183
1394
  this.telemetryService.publicLog2('galleryService:checkingForUpdates', {
1184
1395
  count: infos.length,
1185
1396
  });
1186
- const galleryExtensions = await this.galleryService.getExtensions(infos, { targetPlatform, compatible: true }, CancellationToken.None);
1397
+ const galleryExtensions = await this.galleryService.getExtensions(infos, { targetPlatform, compatible: true, productVersion: this.getProductVersion() }, CancellationToken.None);
1187
1398
  if (galleryExtensions.length) {
1188
1399
  await this.syncInstalledExtensionsWithGallery(galleryExtensions);
1189
1400
  }
@@ -1219,8 +1430,10 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1219
1430
  if (!extensions.length) {
1220
1431
  return;
1221
1432
  }
1222
- const result = await Promise.allSettled(( extensions.map(extensions => extensions.syncInstalledExtensionsWithGallery(gallery))));
1223
- if (this.isAutoUpdateEnabled() && ( result.some(r => r.status === 'fulfilled' && r.value))) {
1433
+ await Promise.allSettled(( extensions.map(
1434
+ extensions => extensions.syncInstalledExtensionsWithGallery(gallery, this.getProductVersion())
1435
+ )));
1436
+ if (this.isAutoUpdateEnabled()) {
1224
1437
  this.eventuallyAutoUpdateExtensions();
1225
1438
  }
1226
1439
  }
@@ -1235,12 +1448,19 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1235
1448
  return this.configurationService.getValue(AutoCheckUpdatesConfigurationKey);
1236
1449
  }
1237
1450
  eventuallyCheckForUpdates(immediate = false) {
1451
+ this.updatesCheckDelayer.cancel();
1238
1452
  this.updatesCheckDelayer.trigger(async () => {
1239
1453
  if (this.isAutoUpdateEnabled() || this.isAutoCheckUpdatesEnabled()) {
1240
1454
  await this.checkForUpdates();
1241
1455
  }
1242
1456
  this.eventuallyCheckForUpdates();
1243
- }, immediate ? 0 : ExtensionsWorkbenchService_1.UpdatesCheckInterval).then(undefined, err => null);
1457
+ }, immediate ? 0 : this.getUpdatesCheckInterval()).then(undefined, err => null);
1458
+ }
1459
+ getUpdatesCheckInterval() {
1460
+ if (this.productService.quality === 'insider' && this.getProductUpdateVersion()) {
1461
+ return 1000 * 60 * 60 * 1;
1462
+ }
1463
+ return ExtensionsWorkbenchService_1.UpdatesCheckInterval;
1244
1464
  }
1245
1465
  eventuallyAutoUpdateExtensions() {
1246
1466
  this.autoUpdateDelayer.trigger(() => this.autoUpdateExtensions())
@@ -1272,10 +1492,34 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1272
1492
  return;
1273
1493
  }
1274
1494
  const toUpdate = this.outdated.filter(e => !e.local?.pinned && this.shouldAutoUpdateExtension(e));
1495
+ if (!toUpdate.length) {
1496
+ return;
1497
+ }
1498
+ const productVersion = this.getProductVersion();
1275
1499
  await Promises.settled(( toUpdate.map(
1276
- e => this.install(e, e.local?.preRelease ? { installPreReleaseVersion: true } : undefined)
1500
+ e => this.install(e, e.local?.preRelease ? { installPreReleaseVersion: true, productVersion } : { productVersion })
1277
1501
  )));
1278
1502
  }
1503
+ getProductVersion() {
1504
+ return this.getProductUpdateVersion() ?? this.getProductCurrentVersion();
1505
+ }
1506
+ getProductCurrentVersion() {
1507
+ return { version: this.productService.version, date: this.productService.date };
1508
+ }
1509
+ getProductUpdateVersion() {
1510
+ switch (this.updateService.state.type) {
1511
+ case "available for download" :
1512
+ case "downloaded" :
1513
+ case "updating" :
1514
+ case "ready" : {
1515
+ const version = this.updateService.state.update.productVersion;
1516
+ if (version && semverExports.valid(version)) {
1517
+ return { version, date: this.updateService.state.update.timestamp ? ( new Date(this.updateService.state.update.timestamp)).toISOString() : undefined };
1518
+ }
1519
+ }
1520
+ }
1521
+ return undefined;
1522
+ }
1279
1523
  async updateExtensionsPinnedState() {
1280
1524
  await Promise.all(( this.installed.map(async (e) => {
1281
1525
  if (e.isBuiltin) {
@@ -1423,33 +1667,196 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1423
1667
  if (extension.deprecationInfo?.disallowInstall) {
1424
1668
  return false;
1425
1669
  }
1426
- if (!extension.gallery) {
1670
+ if (extension.gallery) {
1671
+ if (this.localExtensions && (await this.localExtensions.canInstall(extension.gallery))) {
1672
+ return true;
1673
+ }
1674
+ if (this.remoteExtensions && (await this.remoteExtensions.canInstall(extension.gallery))) {
1675
+ return true;
1676
+ }
1677
+ if (this.webExtensions && (await this.webExtensions.canInstall(extension.gallery))) {
1678
+ return true;
1679
+ }
1427
1680
  return false;
1428
1681
  }
1429
- if (this.localExtensions && (await this.localExtensions.canInstall(extension.gallery))) {
1430
- return true;
1431
- }
1432
- if (this.remoteExtensions && (await this.remoteExtensions.canInstall(extension.gallery))) {
1433
- return true;
1434
- }
1435
- if (this.webExtensions && (await this.webExtensions.canInstall(extension.gallery))) {
1682
+ if (extension.resourceExtension) {
1436
1683
  return true;
1437
1684
  }
1438
1685
  return false;
1439
1686
  }
1440
- install(extension, installOptions, progressLocation) {
1441
- return this.doInstall(extension, async () => {
1442
- if (extension instanceof URI) {
1443
- return this.installFromVSIX(extension, installOptions);
1687
+ async install(arg, installOptions = {}, progressLocation) {
1688
+ let installable;
1689
+ let extension;
1690
+ if (arg instanceof URI) {
1691
+ installable = arg;
1692
+ }
1693
+ else {
1694
+ let installableInfo;
1695
+ let gallery;
1696
+ if (isString(arg)) {
1697
+ extension = this.local.find(e => areSameExtensions(e.identifier, { id: arg }));
1698
+ if (!extension?.isBuiltin) {
1699
+ installableInfo = { id: arg, version: installOptions.version, preRelease: installOptions.installPreReleaseVersion ?? this.preferPreReleases };
1700
+ }
1701
+ }
1702
+ else if (arg.gallery) {
1703
+ extension = arg;
1704
+ gallery = arg.gallery;
1705
+ if (installOptions.version && installOptions.version !== gallery?.version) {
1706
+ installableInfo = { id: extension.identifier.id, version: installOptions.version };
1707
+ }
1708
+ }
1709
+ else if (arg.resourceExtension) {
1710
+ extension = arg;
1711
+ installable = arg.resourceExtension;
1444
1712
  }
1445
- if (extension.isMalicious) {
1713
+ if (installableInfo) {
1714
+ const targetPlatform = extension?.server ? await extension.server.extensionManagementService.getTargetPlatform() : undefined;
1715
+ gallery = firstOrDefault(await this.galleryService.getExtensions([installableInfo], { targetPlatform }, CancellationToken.None));
1716
+ }
1717
+ if (!extension && gallery) {
1718
+ extension = this.instantiationService.createInstance(Extension, ext => this.getExtensionState(ext), ext => this.getRuntimeState(ext), undefined, undefined, gallery, undefined);
1719
+ Extensions.updateExtensionFromControlManifest(extension, await this.extensionManagementService.getExtensionsControlManifest());
1720
+ }
1721
+ if (extension?.isMalicious) {
1446
1722
  throw new Error(localizeWithPath('vs/workbench/contrib/extensions/browser/extensionsWorkbenchService', 'malicious', "This extension is reported to be problematic."));
1447
1723
  }
1448
- if (!extension.gallery) {
1449
- throw new Error('Missing gallery');
1724
+ if (!(installOptions.enable && extension?.local)) {
1725
+ if (!installable) {
1726
+ if (!gallery) {
1727
+ const id = isString(arg) ? arg : arg.identifier.id;
1728
+ if (installOptions.version) {
1729
+ throw new Error(localizeWithPath('vs/workbench/contrib/extensions/browser/extensionsWorkbenchService', 'not found version', "Unable to install extension '{0}' because the requested version '{1}' is not found.", id, installOptions.version));
1730
+ }
1731
+ else {
1732
+ throw new Error(localizeWithPath('vs/workbench/contrib/extensions/browser/extensionsWorkbenchService', 'not found', "Unable to install extension '{0}' because it is not found.", id));
1733
+ }
1734
+ }
1735
+ installable = gallery;
1736
+ }
1737
+ if (installOptions.version) {
1738
+ installOptions.installGivenVersion = true;
1739
+ }
1740
+ if (extension?.isWorkspaceScoped) {
1741
+ installOptions.isWorkspaceScoped = true;
1742
+ }
1743
+ }
1744
+ }
1745
+ if (installable) {
1746
+ if (installOptions.justification) {
1747
+ const syncCheck = isUndefined(installOptions.isMachineScoped) && this.userDataSyncEnablementService.isEnabled() && this.userDataSyncEnablementService.isResourceEnabled("extensions" );
1748
+ const buttons = [];
1749
+ buttons.push({
1750
+ label: isString(installOptions.justification) || !installOptions.justification.action
1751
+ ? ( localizeWithPath(
1752
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1753
+ { key: 'installButtonLabel', comment: ['&& denotes a mnemonic'] },
1754
+ "&&Install Extension"
1755
+ ))
1756
+ : ( localizeWithPath(
1757
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1758
+ { key: 'installButtonLabelWithAction', comment: ['&& denotes a mnemonic'] },
1759
+ "&&Install Extension and {0}",
1760
+ installOptions.justification.action
1761
+ )), run: () => true
1762
+ });
1763
+ if (!extension) {
1764
+ buttons.push({ label: ( localizeWithPath(
1765
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1766
+ 'open',
1767
+ "Open Extension"
1768
+ )), run: () => { this.open(extension); return false; } });
1769
+ }
1770
+ const result = await this.dialogService.prompt({
1771
+ title: ( localizeWithPath(
1772
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1773
+ 'installExtensionTitle',
1774
+ "Install Extension"
1775
+ )),
1776
+ message: extension ? ( localizeWithPath(
1777
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1778
+ 'installExtensionMessage',
1779
+ "Would you like to install '{0}' extension from '{1}'?",
1780
+ extension.displayName,
1781
+ extension.publisherDisplayName
1782
+ )) : ( localizeWithPath(
1783
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1784
+ 'installVSIXMessage',
1785
+ "Would you like to install the extension?"
1786
+ )),
1787
+ detail: isString(installOptions.justification) ? installOptions.justification : installOptions.justification.reason,
1788
+ cancelButton: true,
1789
+ buttons,
1790
+ checkbox: syncCheck ? {
1791
+ label: ( localizeWithPath(
1792
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1793
+ 'sync extension',
1794
+ "Sync this extension"
1795
+ )),
1796
+ checked: true,
1797
+ } : undefined,
1798
+ });
1799
+ if (!result.result) {
1800
+ throw new CancellationError();
1801
+ }
1802
+ if (syncCheck) {
1803
+ installOptions.isMachineScoped = !result.checkboxChecked;
1804
+ }
1805
+ }
1806
+ if (installable instanceof URI) {
1807
+ extension = await this.doInstall(undefined, () => this.installFromVSIX(installable, installOptions), progressLocation);
1808
+ }
1809
+ else if (extension) {
1810
+ if (extension.resourceExtension) {
1811
+ extension = await this.doInstall(extension, () => this.extensionManagementService.installResourceExtension(installable, installOptions), progressLocation);
1812
+ }
1813
+ else {
1814
+ extension = await this.doInstall(extension, () => this.installFromGallery(extension, installable, installOptions), progressLocation);
1815
+ }
1450
1816
  }
1451
- return this.installFromGallery(extension, extension.gallery, installOptions);
1452
- }, progressLocation);
1817
+ }
1818
+ if (!extension) {
1819
+ throw new Error(localizeWithPath('vs/workbench/contrib/extensions/browser/extensionsWorkbenchService', 'unknown', "Unable to install extension"));
1820
+ }
1821
+ if (installOptions.version) {
1822
+ await this.updateAutoUpdateEnablementFor(extension, false);
1823
+ }
1824
+ if (installOptions.enable) {
1825
+ if (extension.enablementState === 7 || extension.enablementState === 6 ) {
1826
+ if (installOptions.justification) {
1827
+ const result = await this.dialogService.confirm({
1828
+ title: ( localizeWithPath(
1829
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1830
+ 'enableExtensionTitle',
1831
+ "Enable Extension"
1832
+ )),
1833
+ message: ( localizeWithPath(
1834
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1835
+ 'enableExtensionMessage',
1836
+ "Would you like to enable '{0}' extension?",
1837
+ extension.displayName
1838
+ )),
1839
+ detail: isString(installOptions.justification) ? installOptions.justification : installOptions.justification.reason,
1840
+ primaryButton: isString(installOptions.justification) ? ( localizeWithPath(
1841
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1842
+ { key: 'enableButtonLabel', comment: ['&& denotes a mnemonic'] },
1843
+ "&&Enable Extension"
1844
+ )) : ( localizeWithPath(
1845
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1846
+ { key: 'enableButtonLabelWithAction', comment: ['&& denotes a mnemonic'] },
1847
+ "&&Enable Extension and {0}",
1848
+ installOptions.justification.action
1849
+ )),
1850
+ });
1851
+ if (!result.confirmed) {
1852
+ throw new CancellationError();
1853
+ }
1854
+ }
1855
+ await this.setEnablement(extension, extension.enablementState === 7 ? 9 : 8 );
1856
+ }
1857
+ await this.waitUntilExtensionIsEnabled(extension);
1858
+ }
1859
+ return extension;
1453
1860
  }
1454
1861
  async installInServer(extension, server) {
1455
1862
  await this.doInstall(extension, async () => {
@@ -1525,22 +1932,6 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1525
1932
  source: `${toUninstall.identifier.id}`
1526
1933
  }, () => this.extensionManagementService.uninstall(toUninstall).then(() => undefined));
1527
1934
  }
1528
- async installVersion(extension, version, installOptions = {}) {
1529
- extension = await this.doInstall(extension, async () => {
1530
- if (!extension.gallery) {
1531
- throw new Error('Missing gallery');
1532
- }
1533
- const targetPlatform = extension.server ? await extension.server.extensionManagementService.getTargetPlatform() : undefined;
1534
- const [gallery] = await this.galleryService.getExtensions([{ id: extension.gallery.identifier.id, version }], { targetPlatform }, CancellationToken.None);
1535
- if (!gallery) {
1536
- throw new Error(localizeWithPath('vs/workbench/contrib/extensions/browser/extensionsWorkbenchService', 'not found', "Unable to install extension '{0}' because the requested version '{1}' is not found.", extension.gallery.identifier.id, version));
1537
- }
1538
- installOptions.installGivenVersion = true;
1539
- return this.installFromGallery(extension, gallery, installOptions);
1540
- });
1541
- await this.updateAutoUpdateEnablementFor(extension, false);
1542
- return extension;
1543
- }
1544
1935
  reinstall(extension) {
1545
1936
  return this.doInstall(extension, () => {
1546
1937
  const ext = extension.local ? extension : this.local.filter(e => areSameExtensions(e.identifier, extension.identifier))[0];
@@ -1602,22 +1993,22 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1602
1993
  return extension;
1603
1994
  }
1604
1995
  doInstall(extension, installTask, progressLocation) {
1605
- const title = extension instanceof URI ? ( localizeWithPath(
1606
- 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1607
- 'installing extension',
1608
- 'Installing extension....'
1609
- )) : ( localizeWithPath(
1996
+ const title = extension ? ( localizeWithPath(
1610
1997
  'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
1611
1998
  'installing named extension',
1612
1999
  "Installing '{0}' extension....",
1613
2000
  extension.displayName
2001
+ )) : ( localizeWithPath(
2002
+ 'vs/workbench/contrib/extensions/browser/extensionsWorkbenchService',
2003
+ 'installing extension',
2004
+ 'Installing extension....'
1614
2005
  ));
1615
2006
  return this.withProgress({
1616
2007
  location: progressLocation ?? 5 ,
1617
2008
  title
1618
2009
  }, async () => {
1619
2010
  try {
1620
- if (!(extension instanceof URI)) {
2011
+ if (extension) {
1621
2012
  this.installing.push(extension);
1622
2013
  this._onChange.fire(extension);
1623
2014
  }
@@ -1625,7 +2016,7 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1625
2016
  return await this.waitAndGetInstalledExtension(local.identifier);
1626
2017
  }
1627
2018
  finally {
1628
- if (!(extension instanceof URI)) {
2019
+ if (extension) {
1629
2020
  this.installing = this.installing.filter(e => e !== extension);
1630
2021
  this._onChange.fire(undefined);
1631
2022
  }
@@ -1650,6 +2041,7 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1650
2041
  installOptions = installOptions ?? {};
1651
2042
  installOptions.pinned = extension.local?.pinned || !this.shouldAutoUpdateExtension(extension);
1652
2043
  if (extension.local) {
2044
+ installOptions.productVersion = this.getProductVersion();
1653
2045
  return this.extensionManagementService.updateFromGallery(gallery, extension.local, installOptions);
1654
2046
  }
1655
2047
  else {
@@ -1667,6 +2059,27 @@ let ExtensionsWorkbenchService = class ExtensionsWorkbenchService extends Dispos
1667
2059
  }
1668
2060
  return installedExtension;
1669
2061
  }
2062
+ async waitUntilExtensionIsEnabled(extension) {
2063
+ if (this.extensionService.extensions.find(e => ExtensionIdentifier.equals(e.identifier, extension.identifier.id))) {
2064
+ return;
2065
+ }
2066
+ if (!extension.local || !this.extensionService.canAddExtension(toExtensionDescription(extension.local))) {
2067
+ return;
2068
+ }
2069
+ await ( new Promise((c, e) => {
2070
+ const disposable = this.extensionService.onDidChangeExtensions(() => {
2071
+ try {
2072
+ if (this.extensionService.extensions.find(e => ExtensionIdentifier.equals(e.identifier, extension.identifier.id))) {
2073
+ disposable.dispose();
2074
+ c();
2075
+ }
2076
+ }
2077
+ catch (error) {
2078
+ e(error);
2079
+ }
2080
+ });
2081
+ }));
2082
+ }
1670
2083
  promptAndSetEnablement(extensions, enablementState) {
1671
2084
  const enable = enablementState === 8 || enablementState === 9 ;
1672
2085
  if (enable) {
@@ -1928,7 +2341,11 @@ ExtensionsWorkbenchService = ExtensionsWorkbenchService_1 = ( __decorate([
1928
2341
  ( __param(21, ILifecycleService)),
1929
2342
  ( __param(22, IFileService)),
1930
2343
  ( __param(23, IUserDataProfileService)),
1931
- ( __param(24, IStorageService))
2344
+ ( __param(24, IStorageService)),
2345
+ ( __param(25, IDialogService)),
2346
+ ( __param(26, IUserDataSyncEnablementService)),
2347
+ ( __param(27, IUpdateService)),
2348
+ ( __param(28, IUriIdentityService))
1932
2349
  ], ExtensionsWorkbenchService));
1933
2350
 
1934
2351
  export { Extension, ExtensionsWorkbenchService };