@codingame/monaco-vscode-extension-gallery-service-override 2.0.3 → 2.1.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 (17) hide show
  1. package/package.json +2 -2
  2. package/vscode/src/vs/base/common/paging.js +5 -5
  3. package/vscode/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.js +11 -14
  4. package/vscode/src/vs/platform/extensionManagement/common/extensionGalleryService.js +12 -8
  5. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionEditor.js +23 -45
  6. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService.js +17 -8
  7. package/vscode/src/vs/workbench/contrib/extensions/browser/extensions.contribution.js +126 -118
  8. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsList.js +1 -3
  9. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.js +20 -9
  10. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViews.js +85 -72
  11. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.js +10 -22
  12. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.js +26 -6
  13. package/vscode/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.js +3 -0
  14. package/vscode/src/vs/workbench/contrib/extensions/common/extensionQuery.js +2 -11
  15. package/vscode/src/vs/workbench/contrib/extensions/common/runtimeExtensionsInput.js +10 -0
  16. package/vscode/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.js +9 -5
  17. package/vscode/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.js +5 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codingame/monaco-vscode-extension-gallery-service-override",
3
- "version": "2.0.3",
3
+ "version": "2.1.0",
4
4
  "keywords": [],
5
5
  "author": {
6
6
  "name": "CodinGame",
@@ -18,7 +18,7 @@
18
18
  "module": "index.js",
19
19
  "types": "index.d.ts",
20
20
  "dependencies": {
21
- "vscode": "npm:@codingame/monaco-vscode-api@2.0.3",
21
+ "vscode": "npm:@codingame/monaco-vscode-api@2.1.0",
22
22
  "vscode-marked": "npm:marked@=3.0.2",
23
23
  "vscode-semver": "npm:semver@=5.5.0"
24
24
  }
@@ -1,6 +1,6 @@
1
1
  import { range } from 'vscode/vscode/vs/base/common/arrays';
2
2
  import { CancellationTokenSource } from 'vscode/vscode/vs/base/common/cancellation';
3
- import { canceled } from 'vscode/vscode/vs/base/common/errors';
3
+ import { CancellationError } from 'vscode/vscode/vs/base/common/errors';
4
4
 
5
5
  function createPage(elements) {
6
6
  return {
@@ -45,7 +45,7 @@ class PagedModel {
45
45
  }
46
46
  resolve(index, cancellationToken) {
47
47
  if (cancellationToken.isCancellationRequested) {
48
- return Promise.reject(canceled());
48
+ return Promise.reject(( new CancellationError()));
49
49
  }
50
50
  const pageIndex = Math.floor(index / this.pager.pageSize);
51
51
  const indexInPage = index % this.pager.pageSize;
@@ -97,11 +97,11 @@ class DelayedPagedModel {
97
97
  resolve(index, cancellationToken) {
98
98
  return ( new Promise((c, e) => {
99
99
  if (cancellationToken.isCancellationRequested) {
100
- return e(canceled());
100
+ return e(( new CancellationError()));
101
101
  }
102
102
  const timer = setTimeout(() => {
103
103
  if (cancellationToken.isCancellationRequested) {
104
- return e(canceled());
104
+ return e(( new CancellationError()));
105
105
  }
106
106
  timeoutCancellation.dispose();
107
107
  this.model.resolve(index, cancellationToken).then(c, e);
@@ -109,7 +109,7 @@ class DelayedPagedModel {
109
109
  const timeoutCancellation = cancellationToken.onCancellationRequested(() => {
110
110
  clearTimeout(timer);
111
111
  timeoutCancellation.dispose();
112
- e(canceled());
112
+ e(( new CancellationError()));
113
113
  });
114
114
  }));
115
115
  }
@@ -9,7 +9,7 @@ import { isWeb } from 'vscode/vscode/vs/base/common/platform';
9
9
  import { isDefined } from 'vscode/vscode/vs/base/common/types';
10
10
  import { URI } from 'vscode/vscode/vs/base/common/uri';
11
11
  import { localizeWithPath } from 'vscode/vscode/vs/nls';
12
- import { isTargetPlatformCompatible, ExtensionManagementError, ExtensionManagementErrorCode, EXTENSION_INSTALL_DEP_PACK_CONTEXT, TargetPlatformToString, IExtensionGalleryService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement';
12
+ import { isTargetPlatformCompatible, ExtensionManagementError, ExtensionManagementErrorCode, EXTENSION_INSTALL_DEP_PACK_CONTEXT, TargetPlatformToString, IExtensionGalleryService, ExtensionGalleryError } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement';
13
13
  import { areSameExtensions, getGalleryExtensionTelemetryData, adoptToGalleryExtensionId, getGalleryExtensionId, ExtensionKey, getLocalExtensionTelemetryData } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagementUtil';
14
14
  import { isApplicationScopedExtension } from 'vscode/vscode/vs/platform/extensions/common/extensions';
15
15
  import { ILogService } from 'vscode/vscode/vs/platform/log/common/log';
@@ -64,7 +64,7 @@ let AbstractExtensionManagementService = class AbstractExtensionManagementServic
64
64
  if (result?.error) {
65
65
  throw result.error;
66
66
  }
67
- throw toExtensionManagementError(new Error(`Unknown error while installing extension ${extension.identifier.id}`));
67
+ throw new ExtensionManagementError(`Unknown error while installing extension ${extension.identifier.id}`, ExtensionManagementErrorCode.Unknown);
68
68
  }
69
69
  catch (error) {
70
70
  throw toExtensionManagementError(error);
@@ -72,7 +72,7 @@ let AbstractExtensionManagementService = class AbstractExtensionManagementServic
72
72
  }
73
73
  async installGalleryExtensions(extensions) {
74
74
  if (!this.galleryService.isEnabled()) {
75
- throw new ExtensionManagementError(localizeWithPath('vs/platform/extensionManagement/common/abstractExtensionManagementService', 'MarketPlaceDisabled', "Marketplace is not enabled"), ExtensionManagementErrorCode.Internal);
75
+ throw new ExtensionManagementError(localizeWithPath('vs/platform/extensionManagement/common/abstractExtensionManagementService', 'MarketPlaceDisabled', "Marketplace is not enabled"), ExtensionManagementErrorCode.NotAllowed);
76
76
  }
77
77
  const results = [];
78
78
  const installableExtensions = [];
@@ -284,15 +284,7 @@ let AbstractExtensionManagementService = class AbstractExtensionManagementServic
284
284
  installResults.push({ local, identifier: task.identifier, operation: task.operation, source: task.source, context: task.options.context, profileLocation: task.profileLocation, applicationScoped: local.isApplicationScoped });
285
285
  }
286
286
  catch (error) {
287
- if (!URI.isUri(task.source)) {
288
- reportTelemetry(this.telemetryService, task.operation === 3 ? 'extensionGallery:update' : 'extensionGallery:install', {
289
- extensionData: getGalleryExtensionTelemetryData(task.source),
290
- verificationStatus: task.verificationStatus,
291
- duration: ( new Date()).getTime() - startTime,
292
- error
293
- });
294
- }
295
- this.logService.error('Error while installing the extension:', task.identifier.id);
287
+ this.logService.error('Error while installing the extension', task.identifier.id, getErrorMessage(error));
296
288
  throw error;
297
289
  }
298
290
  finally {
@@ -447,7 +439,7 @@ let AbstractExtensionManagementService = class AbstractExtensionManagementServic
447
439
  compatibleExtension = await this.getCompatibleVersion(extension, sameVersion, installPreRelease);
448
440
  if (!compatibleExtension) {
449
441
  if (!installPreRelease && extension.properties.isPreReleaseVersion && (await this.galleryService.getExtensions([extension.identifier], CancellationToken.None))[0]) {
450
- throw new ExtensionManagementError(localizeWithPath('vs/platform/extensionManagement/common/abstractExtensionManagementService', 'notFoundReleaseExtension', "Can't install release version of '{0}' extension because it has no release version.", extension.identifier.id), ExtensionManagementErrorCode.ReleaseVersionNotFound);
442
+ throw new ExtensionManagementError(localizeWithPath('vs/platform/extensionManagement/common/abstractExtensionManagementService', 'notFoundReleaseExtension', "Can't install release version of '{0}' extension because it has no release version.", extension.displayName ?? extension.identifier.id), ExtensionManagementErrorCode.ReleaseVersionNotFound);
451
443
  }
452
444
  throw new ExtensionManagementError(localizeWithPath('vs/platform/extensionManagement/common/abstractExtensionManagementService', 'notFoundCompatibleDependency', "Can't install '{0}' extension because it is not compatible with the current version of {1} (version {2}).", extension.identifier.id, this.productService.nameLong, this.productService.version), ExtensionManagementErrorCode.Incompatible);
453
445
  }
@@ -724,6 +716,11 @@ function toExtensionManagementError(error) {
724
716
  if (error instanceof ExtensionManagementError) {
725
717
  return error;
726
718
  }
719
+ if (error instanceof ExtensionGalleryError) {
720
+ const e = ( new ExtensionManagementError(error.message, ExtensionManagementErrorCode.Gallery));
721
+ e.stack = error.stack;
722
+ return e;
723
+ }
727
724
  const e = ( new ExtensionManagementError(error.message, ExtensionManagementErrorCode.Internal));
728
725
  e.stack = error.stack;
729
726
  return e;
@@ -745,7 +742,7 @@ function reportTelemetry(telemetryService, eventName, { extensionData, verificat
745
742
  }
746
743
  }
747
744
  if (error) {
748
- if (error instanceof ExtensionManagementError) {
745
+ if (error instanceof ExtensionManagementError || error instanceof ExtensionGalleryError) {
749
746
  errorcode = error.code;
750
747
  if (error.code === ExtensionManagementErrorCode.Signature) {
751
748
  errorcodeDetail = error.message;
@@ -8,7 +8,7 @@ import { isBoolean } from 'vscode/vscode/vs/base/common/types';
8
8
  import { URI } from 'vscode/vscode/vs/base/common/uri';
9
9
  import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration';
10
10
  import { IEnvironmentService } from 'vscode/vscode/vs/platform/environment/common/environment';
11
- import { getTargetPlatform, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, toTargetPlatform, WEB_EXTENSION_TAG } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement';
11
+ import { getTargetPlatform, isNotWebExtensionInWebTargetPlatform, isTargetPlatformCompatible, ExtensionGalleryErrorCode, ExtensionGalleryError, toTargetPlatform, WEB_EXTENSION_TAG } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement';
12
12
  import { getGalleryExtensionId, areSameExtensions, getGalleryExtensionTelemetryData, adoptToGalleryExtensionId } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagementUtil';
13
13
  import { isEngineValid } from 'vscode/vscode/vs/platform/extensions/common/extensionValidator';
14
14
  import { IFileService } from 'vscode/vscode/vs/platform/files/common/files';
@@ -69,7 +69,8 @@ const PropertyType = {
69
69
  PreRelease: 'Microsoft.VisualStudio.Code.PreRelease',
70
70
  LocalizedLanguages: 'Microsoft.VisualStudio.Code.LocalizedLanguages',
71
71
  WebExtension: 'Microsoft.VisualStudio.Code.WebExtension',
72
- SponsorLink: 'Microsoft.VisualStudio.Code.SponsorLink'
72
+ SponsorLink: 'Microsoft.VisualStudio.Code.SponsorLink',
73
+ SupportLink: 'Microsoft.VisualStudio.Services.Links.Support',
73
74
  };
74
75
  const DefaultPageSize = 10;
75
76
  const DefaultQueryState = {
@@ -195,6 +196,9 @@ function getLocalizedLanguages(version) {
195
196
  function getSponsorLink(version) {
196
197
  return version.properties?.find(p => p.key === PropertyType.SponsorLink)?.value;
197
198
  }
199
+ function getSupportLink(version) {
200
+ return version.properties?.find(p => p.key === PropertyType.SupportLink)?.value;
201
+ }
198
202
  function getIsPreview(flags) {
199
203
  return flags.indexOf('preview') !== -1;
200
204
  }
@@ -287,7 +291,8 @@ function toExtension(galleryExtension, version, allTargetPlatforms, queryContext
287
291
  hasReleaseVersion: true,
288
292
  preview: getIsPreview(galleryExtension.flags),
289
293
  isSigned: !!assets.signature,
290
- queryContext
294
+ queryContext,
295
+ supportLink: getSupportLink(latestVersion)
291
296
  };
292
297
  }
293
298
  let AbstractExtensionGalleryService = class AbstractExtensionGalleryService {
@@ -597,8 +602,9 @@ let AbstractExtensionGalleryService = class AbstractExtensionGalleryService {
597
602
  return { galleryExtensions: [], total };
598
603
  }
599
604
  catch (e) {
600
- error = e;
601
- throw e;
605
+ const errorCode = isCancellationError(e) ? ExtensionGalleryErrorCode.Cancelled : getErrorMessage(e).startsWith('XHR timeout') ? ExtensionGalleryErrorCode.Timeout : ExtensionGalleryErrorCode.Failed;
606
+ error = ( new ExtensionGalleryError(getErrorMessage(e), errorCode));
607
+ throw error;
602
608
  }
603
609
  finally {
604
610
  this.telemetryService.publicLog2('galleryService:query', {
@@ -608,9 +614,7 @@ let AbstractExtensionGalleryService = class AbstractExtensionGalleryService {
608
614
  success: !!context && isSuccess(context),
609
615
  responseBodySize: context?.res.headers['Content-Length'],
610
616
  statusCode: context ? String(context.res.statusCode) : undefined,
611
- errorCode: error
612
- ? isCancellationError(error) ? 'canceled' : getErrorMessage(error).startsWith('XHR timeout') ? 'timeout' : 'failed'
613
- : undefined,
617
+ errorCode: error?.code,
614
618
  count: String(total)
615
619
  });
616
620
  }
@@ -44,8 +44,8 @@ import { defaultCheckboxStyles, defaultKeybindingLabelStyles } from 'vscode/vsco
44
44
  import { editorBackground, textLinkForeground, textLinkActiveForeground, buttonHoverBackground, buttonForeground } from 'vscode/vscode/vs/platform/theme/common/colorRegistry';
45
45
  import { registerThemingParticipant, IThemeService } from 'vscode/vscode/vs/platform/theme/common/themeService';
46
46
  import { EditorPane } from 'vscode/vscode/vs/workbench/browser/parts/editor/editorPane';
47
- import { InstallDropdownAction, ReloadAction, ExtensionStatusLabelAction, ActionWithDropDownAction, UpdateAction, ToggleAutoUpdateForExtensionAction, SetColorThemeAction, SetFileIconThemeAction, SetProductIconThemeAction, SetLanguageAction, ClearLanguageAction, EnableDropDownAction, DisableDropDownAction, RemoteInstallAction, LocalInstallAction, WebInstallAction, InstallingLabelAction, UninstallAction, MigrateDeprecatedExtensionAction, InstallAnotherVersionAction, SwitchToPreReleaseVersionAction, SwitchToReleasedVersionAction, ExtensionEditorManageExtensionAction, ExtensionDropDownAction, ExtensionActionWithDropdownActionViewItem, ExtensionStatusAction } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsActions';
48
- import { errorIcon, warningIcon, infoIcon, preReleaseIcon } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsIcons';
47
+ import { InstallDropdownAction, ReloadAction, ExtensionStatusLabelAction, ActionWithDropDownAction, UpdateAction, ToggleAutoUpdateForExtensionAction, SetColorThemeAction, SetFileIconThemeAction, SetProductIconThemeAction, SetLanguageAction, ClearLanguageAction, EnableDropDownAction, DisableDropDownAction, RemoteInstallAction, LocalInstallAction, WebInstallAction, InstallingLabelAction, UninstallAction, MigrateDeprecatedExtensionAction, InstallAnotherVersionAction, TogglePreReleaseExtensionAction, ExtensionEditorManageExtensionAction, ExtensionDropDownAction, ExtensionActionWithDropdownActionViewItem, ExtensionStatusAction } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsActions';
48
+ import { errorIcon, warningIcon, infoIcon } from 'vscode/vscode/vs/workbench/contrib/extensions/browser/extensionsIcons';
49
49
  import { Delegate } from './extensionsList.js';
50
50
  import { ExtensionsTree, ExtensionData, ExtensionsGridView, getExtensions } from './extensionsViewer.js';
51
51
  import { RemoteBadgeWidget, VerifiedPublisherWidget, InstallCountWidget, RatingsWidget, SponsorWidget, ExtensionStatusWidget, ExtensionWidget, ExtensionRecommendationWidget, onClick } from './extensionsWidgets.js';
@@ -126,33 +126,7 @@ class VersionWidget extends ExtensionWithDifferentGalleryVersionWidget {
126
126
  if (!this.extension || !valid(this.extension.version)) {
127
127
  return;
128
128
  }
129
- this.element.textContent = `v${this.gallery?.version ?? this.extension.version}`;
130
- }
131
- }
132
- class PreReleaseTextWidget extends ExtensionWithDifferentGalleryVersionWidget {
133
- constructor(container) {
134
- super();
135
- this.element = append(container, $('span.pre-release'));
136
- append(this.element, $('span' + ThemeIcon.asCSSSelector(preReleaseIcon)));
137
- const textElement = append(this.element, $('span.pre-release-text'));
138
- textElement.textContent = ( localizeWithPath(
139
- 'vs/workbench/contrib/extensions/browser/extensionEditor',
140
- 'preRelease',
141
- "Pre-Release"
142
- ));
143
- this.render();
144
- }
145
- render() {
146
- this.element.style.display = this.isPreReleaseVersion() ? 'inherit' : 'none';
147
- }
148
- isPreReleaseVersion() {
149
- if (!this.extension) {
150
- return false;
151
- }
152
- if (this.gallery) {
153
- return this.gallery.properties.isPreReleaseVersion;
154
- }
155
- return !!(this.extension.state === 1 ? this.extension.local?.isPreReleaseVersion : this.extension.gallery?.properties.isPreReleaseVersion);
129
+ this.element.textContent = `v${this.gallery?.version ?? this.extension.version}${this.extension.isPreReleaseVersion ? ' (pre-release)' : ''}`;
156
130
  }
157
131
  }
158
132
  let ExtensionEditor = class ExtensionEditor extends EditorPane {
@@ -207,7 +181,6 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
207
181
  "Extension name"
208
182
  )), role: 'heading', tabIndex: 0 }));
209
183
  const versionWidget = ( new VersionWidget(title));
210
- const preReleaseWidget = ( new PreReleaseTextWidget(title));
211
184
  const preview = append(title, $('span.preview', { title: ( localizeWithPath(
212
185
  'vs/workbench/contrib/extensions/browser/extensionEditor',
213
186
  'preview',
@@ -250,7 +223,6 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
250
223
  const widgets = [
251
224
  remoteBadge,
252
225
  versionWidget,
253
- preReleaseWidget,
254
226
  verifiedPublisherWidget,
255
227
  installCountWidget,
256
228
  ratingsWidget,
@@ -281,8 +253,7 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
281
253
  this.instantiationService.createInstance(InstallAnotherVersionAction),
282
254
  ]
283
255
  ]),
284
- this.instantiationService.createInstance(SwitchToPreReleaseVersionAction, false),
285
- this.instantiationService.createInstance(SwitchToReleasedVersionAction, false),
256
+ this.instantiationService.createInstance(TogglePreReleaseExtensionAction),
286
257
  this.instantiationService.createInstance(ToggleAutoUpdateForExtensionAction, false, [false, 'onlySelectedExtensions']),
287
258
  ( new ExtensionEditorManageExtensionAction(
288
259
  this.scopedContextKeyService || this.contextKeyService,
@@ -367,7 +338,6 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
367
338
  },
368
339
  set gallery(gallery) {
369
340
  versionWidget.gallery = gallery;
370
- preReleaseWidget.gallery = gallery;
371
341
  },
372
342
  set manifest(manifest) {
373
343
  installAction.manifest = manifest;
@@ -486,17 +456,15 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
486
456
  this.initialScrollProgress.clear();
487
457
  this.currentIdentifier = extension.identifier.id;
488
458
  }
489
- if (extension.hasReadme()) {
490
- template.navbar.push("readme" , ( localizeWithPath(
491
- 'vs/workbench/contrib/extensions/browser/extensionEditor',
492
- 'details',
493
- "Details"
494
- )), ( localizeWithPath(
495
- 'vs/workbench/contrib/extensions/browser/extensionEditor',
496
- 'detailstooltip',
497
- "Extension details, rendered from the extension's 'README.md' file"
498
- )));
499
- }
459
+ template.navbar.push("readme" , ( localizeWithPath(
460
+ 'vs/workbench/contrib/extensions/browser/extensionEditor',
461
+ 'details',
462
+ "Details"
463
+ )), ( localizeWithPath(
464
+ 'vs/workbench/contrib/extensions/browser/extensionEditor',
465
+ 'detailstooltip',
466
+ "Extension details, rendered from the extension's 'README.md' file"
467
+ )));
500
468
  if (manifest && manifest.contributes) {
501
469
  template.navbar.push("contributions" , ( localizeWithPath(
502
470
  'vs/workbench/contrib/extensions/browser/extensionEditor',
@@ -865,6 +833,16 @@ let ExtensionEditor = class ExtensionEditor extends EditorPane {
865
833
  "Marketplace"
866
834
  )), ( URI.parse(extension.url))]);
867
835
  }
836
+ if (extension.url && extension.supportUrl) {
837
+ try {
838
+ resources.push([( localizeWithPath(
839
+ 'vs/workbench/contrib/extensions/browser/extensionEditor',
840
+ 'issues',
841
+ "Issues"
842
+ )), ( URI.parse(extension.supportUrl))]);
843
+ }
844
+ catch (error) { }
845
+ }
868
846
  if (extension.repository) {
869
847
  try {
870
848
  resources.push([( localizeWithPath(
@@ -22,11 +22,6 @@ import { IExtensionIgnoredRecommendationsService } from 'vscode/vscode/vs/workbe
22
22
 
23
23
  const ignoreImportantExtensionRecommendationStorageKey = 'extensionsAssistant/importantRecommendationsIgnore';
24
24
  const donotShowWorkspaceRecommendationsStorageKey = 'extensionsAssistant/workspaceRecommendationsIgnore';
25
- const choiceNever = ( localizeWithPath(
26
- 'vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService',
27
- 'neverShowAgain',
28
- "Don't Show Again"
29
- ));
30
25
  class RecommendationsNotification extends Disposable {
31
26
  constructor(severity, message, choices, notificationService) {
32
27
  super();
@@ -235,12 +230,26 @@ let ExtensionRecommendationNotificationService = class ExtensionRecommendationNo
235
230
  if (!searchValue) {
236
231
  searchValue = source === 2 ? '@recommended' : ( extensions.map(extensionId => `@id:${extensionId.identifier.id}`)).join(' ');
237
232
  }
233
+ const donotShowAgainLabel = source === 2 ? ( localizeWithPath(
234
+ 'vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService',
235
+ 'donotShowAgain',
236
+ "Don't Show Again for this Repository"
237
+ ))
238
+ : extensions.length > 1 ? ( localizeWithPath(
239
+ 'vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService',
240
+ 'donotShowAgainExtension',
241
+ "Don't Show Again for these Extensions"
242
+ )) : ( localizeWithPath(
243
+ 'vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService',
244
+ 'donotShowAgainExtensionSingle',
245
+ "Don't Show Again for this Extension"
246
+ ));
238
247
  return raceCancellablePromises([
239
- this._registerP(this.showRecommendationsNotification(extensions, message, searchValue, source, recommendationsNotificationActions)),
248
+ this._registerP(this.showRecommendationsNotification(extensions, message, searchValue, donotShowAgainLabel, source, recommendationsNotificationActions)),
240
249
  this._registerP(this.waitUntilRecommendationsAreInstalled(extensions))
241
250
  ]);
242
251
  }
243
- showRecommendationsNotification(extensions, message, searchValue, source, { onDidInstallRecommendedExtensions, onDidShowRecommendedExtensions, onDidCancelRecommendedExtensions, onDidNeverShowRecommendedExtensionsAgain }) {
252
+ showRecommendationsNotification(extensions, message, searchValue, donotShowAgainLabel, source, { onDidInstallRecommendedExtensions, onDidShowRecommendedExtensions, onDidCancelRecommendedExtensions, onDidNeverShowRecommendedExtensionsAgain }) {
244
253
  return createCancelablePromise(async (token) => {
245
254
  let accepted = false;
246
255
  const choices = [];
@@ -284,7 +293,7 @@ let ExtensionRecommendationNotificationService = class ExtensionRecommendationNo
284
293
  this.runAction(this.instantiationService.createInstance(SearchExtensionsAction, searchValue));
285
294
  }
286
295
  }, {
287
- label: choiceNever,
296
+ label: donotShowAgainLabel,
288
297
  isSecondary: true,
289
298
  run: () => {
290
299
  onDidNeverShowRecommendedExtensionsAgain(extensions);