@codingame/monaco-vscode-extension-gallery-service-override 1.83.9

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 (66) hide show
  1. package/extensionGallery.d.ts +12 -0
  2. package/extensionGallery.js +76 -0
  3. package/external/rollup-plugin-styles/dist/runtime/inject-css.js +3 -0
  4. package/external/tslib/tslib.es6.js +11 -0
  5. package/index.d.ts +1 -0
  6. package/index.js +1 -0
  7. package/override/vs/platform/dialogs/common/dialogs.js +8 -0
  8. package/package.json +30 -0
  9. package/vscode/src/vs/platform/extensionManagement/common/abstractExtensionManagementService.js +784 -0
  10. package/vscode/src/vs/platform/extensionManagement/common/extensionEnablementService.js +142 -0
  11. package/vscode/src/vs/platform/extensionManagement/common/extensionGalleryService.js +855 -0
  12. package/vscode/src/vs/platform/extensionManagement/common/extensionManagementIpc.js +119 -0
  13. package/vscode/src/vs/platform/extensionManagement/common/extensionTipsService.js +57 -0
  14. package/vscode/src/vs/platform/extensionManagement/common/unsupportedExtensionsMigration.js +58 -0
  15. package/vscode/src/vs/platform/externalServices/common/marketplace.js +17 -0
  16. package/vscode/src/vs/workbench/contrib/extensions/browser/abstractRuntimeExtensionsEditor.js +492 -0
  17. package/vscode/src/vs/workbench/contrib/extensions/browser/browserRuntimeExtensionsEditor.js +28 -0
  18. package/vscode/src/vs/workbench/contrib/extensions/browser/configBasedRecommendations.js +78 -0
  19. package/vscode/src/vs/workbench/contrib/extensions/browser/deprecatedExtensionsChecker.js +87 -0
  20. package/vscode/src/vs/workbench/contrib/extensions/browser/exeBasedRecommendations.js +60 -0
  21. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionEditor.js +1868 -0
  22. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionEnablementWorkspaceTrustTransitionParticipant.js +52 -0
  23. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationNotificationService.js +437 -0
  24. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendations.js +17 -0
  25. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionRecommendationsService.js +221 -0
  26. package/vscode/src/vs/workbench/contrib/extensions/browser/extensions.contribution.js +2063 -0
  27. package/vscode/src/vs/workbench/contrib/extensions/browser/extensions.web.contribution.js +13 -0
  28. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsActivationProgress.js +46 -0
  29. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsCompletionItemsProvider.js +65 -0
  30. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsDependencyChecker.js +98 -0
  31. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsList.js +224 -0
  32. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsQuickAccess.js +121 -0
  33. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewer.js +285 -0
  34. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViewlet.js +912 -0
  35. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsViews.js +1270 -0
  36. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWidgets.js +824 -0
  37. package/vscode/src/vs/workbench/contrib/extensions/browser/extensionsWorkbenchService.js +1730 -0
  38. package/vscode/src/vs/workbench/contrib/extensions/browser/fileBasedRecommendations.js +324 -0
  39. package/vscode/src/vs/workbench/contrib/extensions/browser/keymapRecommendations.js +28 -0
  40. package/vscode/src/vs/workbench/contrib/extensions/browser/languageRecommendations.js +28 -0
  41. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extension.css.js +6 -0
  42. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionEditor.css.js +6 -0
  43. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionsViewlet.css.js +6 -0
  44. package/vscode/src/vs/workbench/contrib/extensions/browser/media/extensionsWidgets.css.js +6 -0
  45. package/vscode/src/vs/workbench/contrib/extensions/browser/media/runtimeExtensionsEditor.css.js +6 -0
  46. package/vscode/src/vs/workbench/contrib/extensions/browser/remoteRecommendations.js +29 -0
  47. package/vscode/src/vs/workbench/contrib/extensions/browser/unsupportedExtensionsMigrationContribution.js +26 -0
  48. package/vscode/src/vs/workbench/contrib/extensions/browser/webRecommendations.js +38 -0
  49. package/vscode/src/vs/workbench/contrib/extensions/browser/workspaceRecommendations.js +88 -0
  50. package/vscode/src/vs/workbench/contrib/extensions/common/extensionQuery.js +67 -0
  51. package/vscode/src/vs/workbench/contrib/extensions/common/extensionsInput.js +43 -0
  52. package/vscode/src/vs/workbench/contrib/extensions/common/extensionsUtils.js +104 -0
  53. package/vscode/src/vs/workbench/contrib/extensions/common/reportExtensionIssueAction.js +31 -0
  54. package/vscode/src/vs/workbench/contrib/extensions/common/runtimeExtensionsInput.js +41 -0
  55. package/vscode/src/vs/workbench/contrib/markdown/browser/markdownDocumentRenderer.js +207 -0
  56. package/vscode/src/vs/workbench/contrib/update/common/update.js +3 -0
  57. package/vscode/src/vs/workbench/services/extensionManagement/browser/builtinExtensionsScannerService.js +84 -0
  58. package/vscode/src/vs/workbench/services/extensionManagement/browser/extensionEnablementService.js +634 -0
  59. package/vscode/src/vs/workbench/services/extensionManagement/browser/webExtensionsScannerService.js +883 -0
  60. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementChannelClient.js +109 -0
  61. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementServerService.js +62 -0
  62. package/vscode/src/vs/workbench/services/extensionManagement/common/extensionManagementService.js +633 -0
  63. package/vscode/src/vs/workbench/services/extensionManagement/common/remoteExtensionManagementService.js +58 -0
  64. package/vscode/src/vs/workbench/services/extensionManagement/common/webExtensionManagementService.js +269 -0
  65. package/vscode/src/vs/workbench/services/extensionRecommendations/common/extensionIgnoredRecommendationsService.js +83 -0
  66. package/vscode/src/vs/workbench/services/remote/common/remoteExtensionsScanner.js +73 -0
@@ -0,0 +1,883 @@
1
+ import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
2
+ import { IBuiltinExtensionsScannerService } from 'monaco-editor/esm/vs/platform/extensions/common/extensions.js';
3
+ import { IBrowserWorkbenchEnvironmentService } from 'vscode/vscode/vs/workbench/services/environment/browser/environmentService';
4
+ import { isWeb, Language } from 'monaco-editor/esm/vs/base/common/platform.js';
5
+ import { joinPath } from 'monaco-editor/esm/vs/base/common/resources.js';
6
+ import { URI } from 'monaco-editor/esm/vs/base/common/uri.js';
7
+ import { IFileService } from 'monaco-editor/esm/vs/platform/files/common/files.js';
8
+ import { Queue } from 'monaco-editor/esm/vs/base/common/async.js';
9
+ import { VSBuffer } from 'monaco-editor/esm/vs/base/common/buffer.js';
10
+ import { ILogService } from 'monaco-editor/esm/vs/platform/log/common/log.js';
11
+ import { CancellationToken } from 'monaco-editor/esm/vs/base/common/cancellation.js';
12
+ import { IExtensionGalleryService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement';
13
+ import { areSameExtensions, getExtensionId, getGalleryExtensionId } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagementUtil';
14
+ import { Disposable } from 'monaco-editor/esm/vs/base/common/lifecycle.js';
15
+ import { localizeManifest } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionNls';
16
+ import { localizeWithPath } from 'monaco-editor/esm/vs/nls.js';
17
+ import { gt, rcompare } from 'vscode-semver';
18
+ import { isString, isUndefined } from 'monaco-editor/esm/vs/base/common/types.js';
19
+ import { getErrorMessage } from 'monaco-editor/esm/vs/base/common/errors.js';
20
+ import { ResourceMap } from 'monaco-editor/esm/vs/base/common/map.js';
21
+ import { IExtensionManifestPropertiesService } from 'vscode/vscode/vs/workbench/services/extensions/common/extensionManifestPropertiesService';
22
+ import { migratePlatformSpecificExtensionGalleryResourceURL, IExtensionResourceLoaderService } from 'vscode/vscode/vs/platform/extensionResourceLoader/common/extensionResourceLoader';
23
+ import { registerAction2, Action2 } from 'monaco-editor/esm/vs/platform/actions/common/actions.js';
24
+ import { Categories } from 'monaco-editor/esm/vs/platform/action/common/actionCommonCategories.js';
25
+ import { IsWebContext } from 'monaco-editor/esm/vs/platform/contextkey/common/contextkeys.js';
26
+ import { IEditorService } from 'vscode/vscode/vs/workbench/services/editor/common/editorService';
27
+ import { basename } from 'monaco-editor/esm/vs/base/common/path.js';
28
+ import { IExtensionStorageService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionStorage';
29
+ import { isNonEmptyArray } from 'monaco-editor/esm/vs/base/common/arrays.js';
30
+ import { ILifecycleService } from 'vscode/vscode/vs/workbench/services/lifecycle/common/lifecycle';
31
+ import { IStorageService } from 'monaco-editor/esm/vs/platform/storage/common/storage.js';
32
+ import { IProductService } from 'monaco-editor/esm/vs/platform/product/common/productService.js';
33
+ import { validateExtensionManifest } from 'vscode/vscode/vs/platform/extensions/common/extensionValidator';
34
+ import Severity from 'monaco-editor/esm/vs/base/common/severity.js';
35
+ import { IUserDataProfileService } from 'vscode/vscode/vs/workbench/services/userDataProfile/common/userDataProfile';
36
+ import { IUserDataProfilesService } from 'monaco-editor/esm/vs/platform/userDataProfile/common/userDataProfile.js';
37
+ import { IUriIdentityService } from 'monaco-editor/esm/vs/platform/uriIdentity/common/uriIdentity.js';
38
+
39
+ function isGalleryExtensionInfo(obj) {
40
+ const galleryExtensionInfo = obj;
41
+ return typeof galleryExtensionInfo?.id === 'string'
42
+ && (galleryExtensionInfo.preRelease === undefined || typeof galleryExtensionInfo.preRelease === 'boolean')
43
+ && (galleryExtensionInfo.migrateStorageFrom === undefined || typeof galleryExtensionInfo.migrateStorageFrom === 'string');
44
+ }
45
+ function isUriComponents(thing) {
46
+ if (!thing) {
47
+ return false;
48
+ }
49
+ return isString(thing.path) &&
50
+ isString(thing.scheme);
51
+ }
52
+ let WebExtensionsScannerService = class WebExtensionsScannerService extends Disposable {
53
+ constructor(environmentService, builtinExtensionsScannerService, fileService, logService, galleryService, extensionManifestPropertiesService, extensionResourceLoaderService, extensionStorageService, storageService, productService, userDataProfilesService, uriIdentityService, lifecycleService) {
54
+ super();
55
+ this.environmentService = environmentService;
56
+ this.builtinExtensionsScannerService = builtinExtensionsScannerService;
57
+ this.fileService = fileService;
58
+ this.logService = logService;
59
+ this.galleryService = galleryService;
60
+ this.extensionManifestPropertiesService = extensionManifestPropertiesService;
61
+ this.extensionResourceLoaderService = extensionResourceLoaderService;
62
+ this.extensionStorageService = extensionStorageService;
63
+ this.storageService = storageService;
64
+ this.productService = productService;
65
+ this.userDataProfilesService = userDataProfilesService;
66
+ this.uriIdentityService = uriIdentityService;
67
+ this.systemExtensionsCacheResource = undefined;
68
+ this.customBuiltinExtensionsCacheResource = undefined;
69
+ this.resourcesAccessQueueMap = ( new ResourceMap());
70
+ if (isWeb) {
71
+ this.systemExtensionsCacheResource = joinPath(environmentService.userRoamingDataHome, 'systemExtensionsCache.json');
72
+ this.customBuiltinExtensionsCacheResource = joinPath(environmentService.userRoamingDataHome, 'customBuiltinExtensionsCache.json');
73
+ lifecycleService.when(4 ).then(() => this.updateCaches());
74
+ }
75
+ }
76
+ readCustomBuiltinExtensionsInfoFromEnv() {
77
+ if (!this._customBuiltinExtensionsInfoPromise) {
78
+ this._customBuiltinExtensionsInfoPromise = (async () => {
79
+ let extensions = [];
80
+ const extensionLocations = [];
81
+ const extensionGalleryResources = [];
82
+ const extensionsToMigrate = [];
83
+ const customBuiltinExtensionsInfo = this.environmentService.options && Array.isArray(this.environmentService.options.additionalBuiltinExtensions)
84
+ ? ( this.environmentService.options.additionalBuiltinExtensions.map(
85
+ additionalBuiltinExtension => isString(additionalBuiltinExtension) ? { id: additionalBuiltinExtension } : additionalBuiltinExtension
86
+ ))
87
+ : [];
88
+ for (const e of customBuiltinExtensionsInfo) {
89
+ if (isGalleryExtensionInfo(e)) {
90
+ extensions.push({ id: e.id, preRelease: !!e.preRelease });
91
+ if (e.migrateStorageFrom) {
92
+ extensionsToMigrate.push([e.migrateStorageFrom, e.id]);
93
+ }
94
+ }
95
+ else if (isUriComponents(e)) {
96
+ const extensionLocation = URI.revive(e);
97
+ if (this.extensionResourceLoaderService.isExtensionGalleryResource(extensionLocation)) {
98
+ extensionGalleryResources.push(extensionLocation);
99
+ }
100
+ else {
101
+ extensionLocations.push(extensionLocation);
102
+ }
103
+ }
104
+ }
105
+ if (extensions.length) {
106
+ extensions = await this.checkAdditionalBuiltinExtensions(extensions);
107
+ }
108
+ if (extensions.length) {
109
+ this.logService.info('Found additional builtin gallery extensions in env', extensions);
110
+ }
111
+ if (extensionLocations.length) {
112
+ this.logService.info('Found additional builtin location extensions in env', ( extensionLocations.map(e => ( e.toString()))));
113
+ }
114
+ if (extensionGalleryResources.length) {
115
+ this.logService.info('Found additional builtin extension gallery resources in env', ( extensionGalleryResources.map(e => ( e.toString()))));
116
+ }
117
+ return { extensions, extensionsToMigrate, extensionLocations, extensionGalleryResources };
118
+ })();
119
+ }
120
+ return this._customBuiltinExtensionsInfoPromise;
121
+ }
122
+ async checkAdditionalBuiltinExtensions(extensions) {
123
+ const extensionsControlManifest = await this.galleryService.getExtensionsControlManifest();
124
+ const result = [];
125
+ for (const extension of extensions) {
126
+ if (( extensionsControlManifest.malicious.some(e => areSameExtensions(e, { id: extension.id })))) {
127
+ this.logService.info(`Checking additional builtin extensions: Ignoring '${extension.id}' because it is reported to be malicious.`);
128
+ continue;
129
+ }
130
+ const deprecationInfo = extensionsControlManifest.deprecated[extension.id.toLowerCase()];
131
+ if (deprecationInfo?.extension?.autoMigrate) {
132
+ const preReleaseExtensionId = deprecationInfo.extension.id;
133
+ this.logService.info(`Checking additional builtin extensions: '${extension.id}' is deprecated, instead using '${preReleaseExtensionId}'`);
134
+ result.push({ id: preReleaseExtensionId, preRelease: !!extension.preRelease });
135
+ }
136
+ else {
137
+ result.push(extension);
138
+ }
139
+ }
140
+ return result;
141
+ }
142
+ async readSystemExtensions() {
143
+ const systemExtensions = await this.builtinExtensionsScannerService.scanBuiltinExtensions();
144
+ const cachedSystemExtensions = await Promise.all(( (await this.readSystemExtensionsCache()).map(e => this.toScannedExtension(e, true, 0 ))));
145
+ const result = ( new Map());
146
+ for (const extension of [...systemExtensions, ...cachedSystemExtensions]) {
147
+ const existing = result.get(extension.identifier.id.toLowerCase());
148
+ if (existing) {
149
+ if (gt(existing.manifest.version, extension.manifest.version)) {
150
+ continue;
151
+ }
152
+ }
153
+ result.set(extension.identifier.id.toLowerCase(), extension);
154
+ }
155
+ return [...( result.values())];
156
+ }
157
+ async readCustomBuiltinExtensions(scanOptions) {
158
+ const [customBuiltinExtensionsFromLocations, customBuiltinExtensionsFromGallery] = await Promise.all([
159
+ this.getCustomBuiltinExtensionsFromLocations(scanOptions),
160
+ this.getCustomBuiltinExtensionsFromGallery(scanOptions),
161
+ ]);
162
+ const customBuiltinExtensions = [...customBuiltinExtensionsFromLocations, ...customBuiltinExtensionsFromGallery];
163
+ await this.migrateExtensionsStorage(customBuiltinExtensions);
164
+ return customBuiltinExtensions;
165
+ }
166
+ async getCustomBuiltinExtensionsFromLocations(scanOptions) {
167
+ const { extensionLocations } = await this.readCustomBuiltinExtensionsInfoFromEnv();
168
+ if (!extensionLocations.length) {
169
+ return [];
170
+ }
171
+ const result = [];
172
+ await Promise.allSettled(( extensionLocations.map(async (extensionLocation) => {
173
+ try {
174
+ const webExtension = await this.toWebExtension(extensionLocation);
175
+ const extension = await this.toScannedExtension(webExtension, true);
176
+ if (extension.isValid || !scanOptions?.skipInvalidExtensions) {
177
+ result.push(extension);
178
+ }
179
+ else {
180
+ this.logService.info(`Skipping invalid additional builtin extension ${webExtension.identifier.id}`);
181
+ }
182
+ }
183
+ catch (error) {
184
+ this.logService.info(`Error while fetching the additional builtin extension ${( location.toString())}.`, getErrorMessage(error));
185
+ }
186
+ })));
187
+ return result;
188
+ }
189
+ async getCustomBuiltinExtensionsFromGallery(scanOptions) {
190
+ if (!this.galleryService.isEnabled()) {
191
+ this.logService.info('Ignoring fetching additional builtin extensions from gallery as it is disabled.');
192
+ return [];
193
+ }
194
+ const result = [];
195
+ const { extensions, extensionGalleryResources } = await this.readCustomBuiltinExtensionsInfoFromEnv();
196
+ try {
197
+ const cacheValue = JSON.stringify({
198
+ extensions: extensions.sort((a, b) => a.id.localeCompare(b.id)),
199
+ extensionGalleryResources: ( extensionGalleryResources.map(e => ( e.toString()))).sort()
200
+ });
201
+ const useCache = this.storageService.get('additionalBuiltinExtensions', -1 , '{}') === cacheValue;
202
+ const webExtensions = await (useCache ? this.getCustomBuiltinExtensionsFromCache() : this.updateCustomBuiltinExtensionsCache());
203
+ if (webExtensions.length) {
204
+ await Promise.all(( webExtensions.map(async (webExtension) => {
205
+ try {
206
+ const extension = await this.toScannedExtension(webExtension, true);
207
+ if (extension.isValid || !scanOptions?.skipInvalidExtensions) {
208
+ result.push(extension);
209
+ }
210
+ else {
211
+ this.logService.info(`Skipping invalid additional builtin gallery extension ${webExtension.identifier.id}`);
212
+ }
213
+ }
214
+ catch (error) {
215
+ this.logService.info(`Ignoring additional builtin extension ${webExtension.identifier.id} because there is an error while converting it into scanned extension`, getErrorMessage(error));
216
+ }
217
+ })));
218
+ }
219
+ this.storageService.store('additionalBuiltinExtensions', cacheValue, -1 , 1 );
220
+ }
221
+ catch (error) {
222
+ this.logService.info('Ignoring following additional builtin extensions as there is an error while fetching them from gallery', ( extensions.map(({ id }) => id)), getErrorMessage(error));
223
+ }
224
+ return result;
225
+ }
226
+ async getCustomBuiltinExtensionsFromCache() {
227
+ const cachedCustomBuiltinExtensions = await this.readCustomBuiltinExtensionsCache();
228
+ const webExtensionsMap = ( new Map());
229
+ for (const webExtension of cachedCustomBuiltinExtensions) {
230
+ const existing = webExtensionsMap.get(webExtension.identifier.id.toLowerCase());
231
+ if (existing) {
232
+ if (gt(existing.version, webExtension.version)) {
233
+ continue;
234
+ }
235
+ }
236
+ if (webExtension.metadata?.isPreReleaseVersion && !webExtension.metadata?.preRelease) {
237
+ webExtension.metadata.preRelease = true;
238
+ }
239
+ webExtensionsMap.set(webExtension.identifier.id.toLowerCase(), webExtension);
240
+ }
241
+ return [...( webExtensionsMap.values())];
242
+ }
243
+ async migrateExtensionsStorage(customBuiltinExtensions) {
244
+ if (!this._migrateExtensionsStoragePromise) {
245
+ this._migrateExtensionsStoragePromise = (async () => {
246
+ const { extensionsToMigrate } = await this.readCustomBuiltinExtensionsInfoFromEnv();
247
+ if (!extensionsToMigrate.length) {
248
+ return;
249
+ }
250
+ const fromExtensions = await this.galleryService.getExtensions(( extensionsToMigrate.map(([id]) => ({ id }))), CancellationToken.None);
251
+ try {
252
+ await Promise.allSettled(( extensionsToMigrate.map(async ([from, to]) => {
253
+ const toExtension = customBuiltinExtensions.find(extension => areSameExtensions(extension.identifier, { id: to }));
254
+ if (toExtension) {
255
+ const fromExtension = fromExtensions.find(extension => areSameExtensions(extension.identifier, { id: from }));
256
+ const fromExtensionManifest = fromExtension ? await this.galleryService.getManifest(fromExtension, CancellationToken.None) : null;
257
+ const fromExtensionId = fromExtensionManifest ? getExtensionId(fromExtensionManifest.publisher, fromExtensionManifest.name) : from;
258
+ const toExtensionId = getExtensionId(toExtension.manifest.publisher, toExtension.manifest.name);
259
+ this.extensionStorageService.addToMigrationList(fromExtensionId, toExtensionId);
260
+ }
261
+ else {
262
+ this.logService.info(`Skipped migrating extension storage from '${from}' to '${to}', because the '${to}' extension is not found.`);
263
+ }
264
+ })));
265
+ }
266
+ catch (error) {
267
+ this.logService.error(error);
268
+ }
269
+ })();
270
+ }
271
+ return this._migrateExtensionsStoragePromise;
272
+ }
273
+ async updateCaches() {
274
+ await this.updateSystemExtensionsCache();
275
+ await this.updateCustomBuiltinExtensionsCache();
276
+ }
277
+ async updateSystemExtensionsCache() {
278
+ const systemExtensions = await this.builtinExtensionsScannerService.scanBuiltinExtensions();
279
+ const cachedSystemExtensions = (await this.readSystemExtensionsCache())
280
+ .filter(cached => {
281
+ const systemExtension = systemExtensions.find(e => areSameExtensions(e.identifier, cached.identifier));
282
+ return systemExtension && gt(cached.version, systemExtension.manifest.version);
283
+ });
284
+ await this.writeSystemExtensionsCache(() => cachedSystemExtensions);
285
+ }
286
+ async updateCustomBuiltinExtensionsCache() {
287
+ if (!this._updateCustomBuiltinExtensionsCachePromise) {
288
+ this._updateCustomBuiltinExtensionsCachePromise = (async () => {
289
+ this.logService.info('Updating additional builtin extensions cache');
290
+ const { extensions, extensionGalleryResources } = await this.readCustomBuiltinExtensionsInfoFromEnv();
291
+ const [galleryWebExtensions, extensionGalleryResourceWebExtensions] = await Promise.all([
292
+ this.resolveBuiltinGalleryExtensions(extensions),
293
+ this.resolveBuiltinExtensionGalleryResources(extensionGalleryResources)
294
+ ]);
295
+ const webExtensionsMap = ( new Map());
296
+ for (const webExtension of [...galleryWebExtensions, ...extensionGalleryResourceWebExtensions]) {
297
+ webExtensionsMap.set(webExtension.identifier.id.toLowerCase(), webExtension);
298
+ }
299
+ await this.resolveDependenciesAndPackedExtensions(extensionGalleryResourceWebExtensions, webExtensionsMap);
300
+ const webExtensions = [...( webExtensionsMap.values())];
301
+ await this.writeCustomBuiltinExtensionsCache(() => webExtensions);
302
+ return webExtensions;
303
+ })();
304
+ }
305
+ return this._updateCustomBuiltinExtensionsCachePromise;
306
+ }
307
+ async resolveBuiltinExtensionGalleryResources(extensionGalleryResources) {
308
+ if (extensionGalleryResources.length === 0) {
309
+ return [];
310
+ }
311
+ const result = ( new Map());
312
+ const extensionInfos = [];
313
+ await Promise.all(( extensionGalleryResources.map(async (extensionGalleryResource) => {
314
+ const webExtension = await this.toWebExtensionFromExtensionGalleryResource(extensionGalleryResource);
315
+ result.set(webExtension.identifier.id.toLowerCase(), webExtension);
316
+ extensionInfos.push({ id: webExtension.identifier.id, version: webExtension.version });
317
+ })));
318
+ const galleryExtensions = await this.galleryService.getExtensions(extensionInfos, CancellationToken.None);
319
+ for (const galleryExtension of galleryExtensions) {
320
+ const webExtension = result.get(galleryExtension.identifier.id.toLowerCase());
321
+ if (webExtension) {
322
+ result.set(galleryExtension.identifier.id.toLowerCase(), {
323
+ ...webExtension,
324
+ identifier: { id: webExtension.identifier.id, uuid: galleryExtension.identifier.uuid },
325
+ readmeUri: galleryExtension.assets.readme ? ( URI.parse(galleryExtension.assets.readme.uri)) : undefined,
326
+ changelogUri: galleryExtension.assets.changelog ? ( URI.parse(galleryExtension.assets.changelog.uri)) : undefined,
327
+ metadata: { isPreReleaseVersion: galleryExtension.properties.isPreReleaseVersion, preRelease: galleryExtension.properties.isPreReleaseVersion, isBuiltin: true, pinned: true }
328
+ });
329
+ }
330
+ }
331
+ return [...( result.values())];
332
+ }
333
+ async resolveBuiltinGalleryExtensions(extensions) {
334
+ if (extensions.length === 0) {
335
+ return [];
336
+ }
337
+ const webExtensions = [];
338
+ const galleryExtensionsMap = await this.getExtensionsWithDependenciesAndPackedExtensions(extensions);
339
+ const missingExtensions = extensions.filter(({ id }) => !( galleryExtensionsMap.has(id.toLowerCase())));
340
+ if (missingExtensions.length) {
341
+ this.logService.info('Skipping the additional builtin extensions because their compatible versions are not found.', missingExtensions);
342
+ }
343
+ await Promise.all(( [...( galleryExtensionsMap.values())].map(async (gallery) => {
344
+ try {
345
+ const webExtension = await this.toWebExtensionFromGallery(gallery, { isPreReleaseVersion: gallery.properties.isPreReleaseVersion, preRelease: gallery.properties.isPreReleaseVersion, isBuiltin: true });
346
+ webExtensions.push(webExtension);
347
+ }
348
+ catch (error) {
349
+ this.logService.info(`Ignoring additional builtin extension ${gallery.identifier.id} because there is an error while converting it into web extension`, getErrorMessage(error));
350
+ }
351
+ })));
352
+ return webExtensions;
353
+ }
354
+ async resolveDependenciesAndPackedExtensions(webExtensions, result) {
355
+ const extensionInfos = [];
356
+ for (const webExtension of webExtensions) {
357
+ for (const e of [...(webExtension.manifest?.extensionDependencies ?? []), ...(webExtension.manifest?.extensionPack ?? [])]) {
358
+ if (!( result.has(e.toLowerCase()))) {
359
+ extensionInfos.push({ id: e, version: webExtension.version });
360
+ }
361
+ }
362
+ }
363
+ if (extensionInfos.length === 0) {
364
+ return;
365
+ }
366
+ const galleryExtensions = await this.getExtensionsWithDependenciesAndPackedExtensions(extensionInfos, ( new Set([...( result.keys())])));
367
+ await Promise.all(( [...( galleryExtensions.values())].map(async (gallery) => {
368
+ try {
369
+ const webExtension = await this.toWebExtensionFromGallery(gallery, { isPreReleaseVersion: gallery.properties.isPreReleaseVersion, preRelease: gallery.properties.isPreReleaseVersion, isBuiltin: true });
370
+ result.set(webExtension.identifier.id.toLowerCase(), webExtension);
371
+ }
372
+ catch (error) {
373
+ this.logService.info(`Ignoring additional builtin extension ${gallery.identifier.id} because there is an error while converting it into web extension`, getErrorMessage(error));
374
+ }
375
+ })));
376
+ }
377
+ async getExtensionsWithDependenciesAndPackedExtensions(toGet, seen = ( new Set()), result = ( new Map())) {
378
+ if (toGet.length === 0) {
379
+ return result;
380
+ }
381
+ const extensions = await this.galleryService.getExtensions(toGet, { compatible: true, targetPlatform: "web" }, CancellationToken.None);
382
+ const packsAndDependencies = ( new Map());
383
+ for (const extension of extensions) {
384
+ result.set(extension.identifier.id.toLowerCase(), extension);
385
+ for (const id of [...(isNonEmptyArray(extension.properties.dependencies) ? extension.properties.dependencies : []), ...(isNonEmptyArray(extension.properties.extensionPack) ? extension.properties.extensionPack : [])]) {
386
+ if (!( result.has(id.toLowerCase())) && !( packsAndDependencies.has(id.toLowerCase())) && !( seen.has(id.toLowerCase()))) {
387
+ const extensionInfo = toGet.find(e => areSameExtensions(e, extension.identifier));
388
+ packsAndDependencies.set(id.toLowerCase(), { id, preRelease: extensionInfo?.preRelease });
389
+ }
390
+ }
391
+ }
392
+ return this.getExtensionsWithDependenciesAndPackedExtensions([...( packsAndDependencies.values())].filter(({ id }) => !( result.has(id.toLowerCase()))), seen, result);
393
+ }
394
+ async scanSystemExtensions() {
395
+ return this.readSystemExtensions();
396
+ }
397
+ async scanUserExtensions(profileLocation, scanOptions) {
398
+ const extensions = ( new Map());
399
+ const customBuiltinExtensions = await this.readCustomBuiltinExtensions(scanOptions);
400
+ for (const extension of customBuiltinExtensions) {
401
+ extensions.set(extension.identifier.id.toLowerCase(), extension);
402
+ }
403
+ const installedExtensions = await this.scanInstalledExtensions(profileLocation, scanOptions);
404
+ for (const extension of installedExtensions) {
405
+ extensions.set(extension.identifier.id.toLowerCase(), extension);
406
+ }
407
+ return [...( extensions.values())];
408
+ }
409
+ async scanExtensionsUnderDevelopment() {
410
+ const devExtensions = this.environmentService.options?.developmentOptions?.extensions;
411
+ const result = [];
412
+ if (Array.isArray(devExtensions)) {
413
+ await Promise.allSettled(( devExtensions.map(async (devExtension) => {
414
+ try {
415
+ const location = URI.revive(devExtension);
416
+ if (URI.isUri(location)) {
417
+ const webExtension = await this.toWebExtension(location);
418
+ result.push(await this.toScannedExtension(webExtension, false));
419
+ }
420
+ else {
421
+ this.logService.info(`Skipping the extension under development ${devExtension} as it is not URI type.`);
422
+ }
423
+ }
424
+ catch (error) {
425
+ this.logService.info(`Error while fetching the extension under development ${( devExtension.toString())}.`, getErrorMessage(error));
426
+ }
427
+ })));
428
+ }
429
+ return result;
430
+ }
431
+ async scanExistingExtension(extensionLocation, extensionType, profileLocation) {
432
+ if (extensionType === 0 ) {
433
+ const systemExtensions = await this.scanSystemExtensions();
434
+ return systemExtensions.find(e => ( e.location.toString()) === ( extensionLocation.toString())) || null;
435
+ }
436
+ const userExtensions = await this.scanUserExtensions(profileLocation);
437
+ return userExtensions.find(e => ( e.location.toString()) === ( extensionLocation.toString())) || null;
438
+ }
439
+ async scanExtensionManifest(extensionLocation) {
440
+ try {
441
+ return await this.getExtensionManifest(extensionLocation);
442
+ }
443
+ catch (error) {
444
+ this.logService.warn(`Error while fetching manifest from ${( extensionLocation.toString())}`, getErrorMessage(error));
445
+ return null;
446
+ }
447
+ }
448
+ async addExtensionFromGallery(galleryExtension, metadata, profileLocation) {
449
+ const webExtension = await this.toWebExtensionFromGallery(galleryExtension, metadata);
450
+ return this.addWebExtension(webExtension, profileLocation);
451
+ }
452
+ async addExtension(location, metadata, profileLocation) {
453
+ const webExtension = await this.toWebExtension(location, undefined, undefined, undefined, undefined, undefined, undefined, metadata);
454
+ const extension = await this.toScannedExtension(webExtension, false);
455
+ await this.addToInstalledExtensions([webExtension], profileLocation);
456
+ return extension;
457
+ }
458
+ async removeExtension(extension, profileLocation) {
459
+ await this.writeInstalledExtensions(profileLocation, installedExtensions => installedExtensions.filter(installedExtension => !areSameExtensions(installedExtension.identifier, extension.identifier)));
460
+ }
461
+ async updateMetadata(extension, metadata, profileLocation) {
462
+ let updatedExtension = undefined;
463
+ await this.writeInstalledExtensions(profileLocation, installedExtensions => {
464
+ const result = [];
465
+ for (const installedExtension of installedExtensions) {
466
+ if (areSameExtensions(extension.identifier, installedExtension.identifier)) {
467
+ installedExtension.metadata = { ...installedExtension.metadata, ...metadata };
468
+ updatedExtension = installedExtension;
469
+ result.push(installedExtension);
470
+ }
471
+ else {
472
+ result.push(installedExtension);
473
+ }
474
+ }
475
+ return result;
476
+ });
477
+ if (!updatedExtension) {
478
+ throw new Error('Extension not found');
479
+ }
480
+ return this.toScannedExtension(updatedExtension, extension.isBuiltin);
481
+ }
482
+ async copyExtensions(fromProfileLocation, toProfileLocation, filter) {
483
+ const extensionsToCopy = [];
484
+ const fromWebExtensions = await this.readInstalledExtensions(fromProfileLocation);
485
+ await Promise.all(( fromWebExtensions.map(async (webExtension) => {
486
+ const scannedExtension = await this.toScannedExtension(webExtension, false);
487
+ if (filter(scannedExtension)) {
488
+ extensionsToCopy.push(webExtension);
489
+ }
490
+ })));
491
+ if (extensionsToCopy.length) {
492
+ await this.addToInstalledExtensions(extensionsToCopy, toProfileLocation);
493
+ }
494
+ }
495
+ async addWebExtension(webExtension, profileLocation) {
496
+ const isSystem = !!(await this.scanSystemExtensions()).find(e => areSameExtensions(e.identifier, webExtension.identifier));
497
+ const isBuiltin = !!webExtension.metadata?.isBuiltin;
498
+ const extension = await this.toScannedExtension(webExtension, isBuiltin);
499
+ if (isSystem) {
500
+ await this.writeSystemExtensionsCache(systemExtensions => {
501
+ systemExtensions = systemExtensions.filter(extension => !areSameExtensions(extension.identifier, webExtension.identifier));
502
+ systemExtensions.push(webExtension);
503
+ return systemExtensions;
504
+ });
505
+ return extension;
506
+ }
507
+ if (isBuiltin) {
508
+ await this.writeCustomBuiltinExtensionsCache(customBuiltinExtensions => {
509
+ customBuiltinExtensions = customBuiltinExtensions.filter(extension => !areSameExtensions(extension.identifier, webExtension.identifier));
510
+ customBuiltinExtensions.push(webExtension);
511
+ return customBuiltinExtensions;
512
+ });
513
+ const installedExtensions = await this.readInstalledExtensions(profileLocation);
514
+ if (( installedExtensions.some(e => areSameExtensions(e.identifier, webExtension.identifier)))) {
515
+ await this.addToInstalledExtensions([webExtension], profileLocation);
516
+ }
517
+ return extension;
518
+ }
519
+ await this.addToInstalledExtensions([webExtension], profileLocation);
520
+ return extension;
521
+ }
522
+ async addToInstalledExtensions(webExtensions, profileLocation) {
523
+ await this.writeInstalledExtensions(profileLocation, installedExtensions => {
524
+ installedExtensions = installedExtensions.filter(installedExtension => ( webExtensions.some(
525
+ extension => !areSameExtensions(installedExtension.identifier, extension.identifier)
526
+ )));
527
+ installedExtensions.push(...webExtensions);
528
+ return installedExtensions;
529
+ });
530
+ }
531
+ async scanInstalledExtensions(profileLocation, scanOptions) {
532
+ let installedExtensions = await this.readInstalledExtensions(profileLocation);
533
+ if (!this.uriIdentityService.extUri.isEqual(profileLocation, this.userDataProfilesService.defaultProfile.extensionsResource)) {
534
+ installedExtensions = installedExtensions.filter(i => !i.metadata?.isApplicationScoped);
535
+ const defaultProfileExtensions = await this.readInstalledExtensions(this.userDataProfilesService.defaultProfile.extensionsResource);
536
+ installedExtensions.push(...defaultProfileExtensions.filter(i => i.metadata?.isApplicationScoped));
537
+ }
538
+ installedExtensions.sort((a, b) => a.identifier.id < b.identifier.id ? -1 : a.identifier.id > b.identifier.id ? 1 : rcompare(a.version, b.version));
539
+ const result = ( new Map());
540
+ for (const webExtension of installedExtensions) {
541
+ const existing = result.get(webExtension.identifier.id.toLowerCase());
542
+ if (existing && gt(existing.manifest.version, webExtension.version)) {
543
+ continue;
544
+ }
545
+ const extension = await this.toScannedExtension(webExtension, false);
546
+ if (extension.isValid || !scanOptions?.skipInvalidExtensions) {
547
+ result.set(extension.identifier.id.toLowerCase(), extension);
548
+ }
549
+ else {
550
+ this.logService.info(`Skipping invalid installed extension ${webExtension.identifier.id}`);
551
+ }
552
+ }
553
+ return [...( result.values())];
554
+ }
555
+ async toWebExtensionFromGallery(galleryExtension, metadata) {
556
+ const extensionLocation = this.extensionResourceLoaderService.getExtensionGalleryResourceURL({
557
+ publisher: galleryExtension.publisher,
558
+ name: galleryExtension.name,
559
+ version: galleryExtension.version,
560
+ targetPlatform: galleryExtension.properties.targetPlatform === "web" ? "web" : undefined
561
+ }, 'extension');
562
+ if (!extensionLocation) {
563
+ throw new Error('No extension gallery service configured.');
564
+ }
565
+ return this.toWebExtensionFromExtensionGalleryResource(extensionLocation, galleryExtension.identifier, galleryExtension.assets.readme ? ( URI.parse(galleryExtension.assets.readme.uri)) : undefined, galleryExtension.assets.changelog ? ( URI.parse(galleryExtension.assets.changelog.uri)) : undefined, metadata);
566
+ }
567
+ async toWebExtensionFromExtensionGalleryResource(extensionLocation, identifier, readmeUri, changelogUri, metadata) {
568
+ const extensionResources = await this.listExtensionResources(extensionLocation);
569
+ const packageNLSResources = this.getPackageNLSResourceMapFromResources(extensionResources);
570
+ const fallbackPackageNLSResource = extensionResources.find(e => basename(e) === 'package.nls.json');
571
+ return this.toWebExtension(extensionLocation, identifier, undefined, packageNLSResources, fallbackPackageNLSResource ? ( URI.parse(fallbackPackageNLSResource)) : null, readmeUri, changelogUri, metadata);
572
+ }
573
+ getPackageNLSResourceMapFromResources(extensionResources) {
574
+ const packageNLSResources = ( new Map());
575
+ extensionResources.forEach(e => {
576
+ const regexResult = /package\.nls\.([\w-]+)\.json/.exec(basename(e));
577
+ if (regexResult?.[1]) {
578
+ packageNLSResources.set(regexResult[1], ( URI.parse(e)));
579
+ }
580
+ });
581
+ return packageNLSResources;
582
+ }
583
+ async toWebExtension(extensionLocation, identifier, manifest, packageNLSUris, fallbackPackageNLSUri, readmeUri, changelogUri, metadata) {
584
+ if (!manifest) {
585
+ try {
586
+ manifest = await this.getExtensionManifest(extensionLocation);
587
+ }
588
+ catch (error) {
589
+ throw new Error(`Error while fetching manifest from the location '${extensionLocation.toString()}'. ${getErrorMessage(error)}`);
590
+ }
591
+ }
592
+ if (!this.extensionManifestPropertiesService.canExecuteOnWeb(manifest)) {
593
+ throw new Error(localizeWithPath('vs/workbench/services/extensionManagement/browser/webExtensionsScannerService', 'not a web extension', "Cannot add '{0}' because this extension is not a web extension.", manifest.displayName || manifest.name));
594
+ }
595
+ if (fallbackPackageNLSUri === undefined) {
596
+ try {
597
+ fallbackPackageNLSUri = joinPath(extensionLocation, 'package.nls.json');
598
+ await this.extensionResourceLoaderService.readExtensionResource(fallbackPackageNLSUri);
599
+ }
600
+ catch (error) {
601
+ fallbackPackageNLSUri = undefined;
602
+ }
603
+ }
604
+ const defaultManifestTranslations = fallbackPackageNLSUri ? URI.isUri(fallbackPackageNLSUri) ? await this.getTranslations(fallbackPackageNLSUri) : fallbackPackageNLSUri : null;
605
+ return {
606
+ identifier: { id: getGalleryExtensionId(manifest.publisher, manifest.name), uuid: identifier?.uuid },
607
+ version: manifest.version,
608
+ location: extensionLocation,
609
+ manifest,
610
+ readmeUri,
611
+ changelogUri,
612
+ packageNLSUris,
613
+ fallbackPackageNLSUri: URI.isUri(fallbackPackageNLSUri) ? fallbackPackageNLSUri : undefined,
614
+ defaultManifestTranslations,
615
+ metadata,
616
+ };
617
+ }
618
+ async toScannedExtension(webExtension, isBuiltin, type = 1 ) {
619
+ const validations = [];
620
+ let manifest = webExtension.manifest;
621
+ if (!manifest) {
622
+ try {
623
+ manifest = await this.getExtensionManifest(webExtension.location);
624
+ }
625
+ catch (error) {
626
+ validations.push([Severity.Error, `Error while fetching manifest from the location '${webExtension.location}'. ${getErrorMessage(error)}`]);
627
+ }
628
+ }
629
+ if (!manifest) {
630
+ const [publisher, name] = webExtension.identifier.id.split('.');
631
+ manifest = {
632
+ name,
633
+ publisher,
634
+ version: webExtension.version,
635
+ engines: { vscode: '*' },
636
+ };
637
+ }
638
+ const packageNLSUri = webExtension.packageNLSUris?.get(Language.value().toLowerCase());
639
+ const fallbackPackageNLS = webExtension.defaultManifestTranslations ?? webExtension.fallbackPackageNLSUri;
640
+ if (packageNLSUri) {
641
+ manifest = await this.translateManifest(manifest, packageNLSUri, fallbackPackageNLS);
642
+ }
643
+ else if (fallbackPackageNLS) {
644
+ manifest = await this.translateManifest(manifest, fallbackPackageNLS);
645
+ }
646
+ const uuid = webExtension.metadata?.id;
647
+ validations.push(...validateExtensionManifest(this.productService.version, this.productService.date, webExtension.location, manifest, false));
648
+ let isValid = true;
649
+ for (const [severity, message] of validations) {
650
+ if (severity === Severity.Error) {
651
+ isValid = false;
652
+ this.logService.error(message);
653
+ }
654
+ }
655
+ return {
656
+ identifier: { id: webExtension.identifier.id, uuid: webExtension.identifier.uuid || uuid },
657
+ location: webExtension.location,
658
+ manifest,
659
+ type,
660
+ isBuiltin,
661
+ readmeUrl: webExtension.readmeUri,
662
+ changelogUrl: webExtension.changelogUri,
663
+ metadata: webExtension.metadata,
664
+ targetPlatform: "web" ,
665
+ validations,
666
+ isValid
667
+ };
668
+ }
669
+ async listExtensionResources(extensionLocation) {
670
+ try {
671
+ const result = await this.extensionResourceLoaderService.readExtensionResource(extensionLocation);
672
+ return JSON.parse(result);
673
+ }
674
+ catch (error) {
675
+ this.logService.warn('Error while fetching extension resources list', getErrorMessage(error));
676
+ }
677
+ return [];
678
+ }
679
+ async translateManifest(manifest, nlsURL, fallbackNLS) {
680
+ try {
681
+ const translations = URI.isUri(nlsURL) ? await this.getTranslations(nlsURL) : nlsURL;
682
+ const fallbackTranslations = URI.isUri(fallbackNLS) ? await this.getTranslations(fallbackNLS) : fallbackNLS;
683
+ if (translations) {
684
+ manifest = localizeManifest(this.logService, manifest, translations, fallbackTranslations);
685
+ }
686
+ }
687
+ catch (error) { }
688
+ return manifest;
689
+ }
690
+ async getExtensionManifest(location) {
691
+ const url = joinPath(location, 'package.json');
692
+ const content = await this.extensionResourceLoaderService.readExtensionResource(url);
693
+ return JSON.parse(content);
694
+ }
695
+ async getTranslations(nlsUrl) {
696
+ try {
697
+ const content = await this.extensionResourceLoaderService.readExtensionResource(nlsUrl);
698
+ return JSON.parse(content);
699
+ }
700
+ catch (error) {
701
+ this.logService.error(`Error while fetching translations of an extension`, ( nlsUrl.toString()), getErrorMessage(error));
702
+ }
703
+ return undefined;
704
+ }
705
+ async readInstalledExtensions(profileLocation) {
706
+ return this.withWebExtensions(profileLocation);
707
+ }
708
+ writeInstalledExtensions(profileLocation, updateFn) {
709
+ return this.withWebExtensions(profileLocation, updateFn);
710
+ }
711
+ readCustomBuiltinExtensionsCache() {
712
+ return this.withWebExtensions(this.customBuiltinExtensionsCacheResource);
713
+ }
714
+ writeCustomBuiltinExtensionsCache(updateFn) {
715
+ return this.withWebExtensions(this.customBuiltinExtensionsCacheResource, updateFn);
716
+ }
717
+ readSystemExtensionsCache() {
718
+ return this.withWebExtensions(this.systemExtensionsCacheResource);
719
+ }
720
+ writeSystemExtensionsCache(updateFn) {
721
+ return this.withWebExtensions(this.systemExtensionsCacheResource, updateFn);
722
+ }
723
+ async withWebExtensions(file, updateFn) {
724
+ if (!file) {
725
+ return [];
726
+ }
727
+ return this.getResourceAccessQueue(file).queue(async () => {
728
+ let webExtensions = [];
729
+ try {
730
+ const content = await this.fileService.readFile(file);
731
+ const storedWebExtensions = JSON.parse(( content.value.toString()));
732
+ for (const e of storedWebExtensions) {
733
+ if (!e.location || !e.identifier || !e.version) {
734
+ this.logService.info('Ignoring invalid extension while scanning', storedWebExtensions);
735
+ continue;
736
+ }
737
+ let packageNLSUris;
738
+ if (e.packageNLSUris) {
739
+ packageNLSUris = ( new Map());
740
+ Object.entries(e.packageNLSUris).forEach(([key, value]) => packageNLSUris.set(key, URI.revive(value)));
741
+ }
742
+ webExtensions.push({
743
+ identifier: e.identifier,
744
+ version: e.version,
745
+ location: URI.revive(e.location),
746
+ manifest: e.manifest,
747
+ readmeUri: URI.revive(e.readmeUri),
748
+ changelogUri: URI.revive(e.changelogUri),
749
+ packageNLSUris,
750
+ fallbackPackageNLSUri: URI.revive(e.fallbackPackageNLSUri),
751
+ defaultManifestTranslations: e.defaultManifestTranslations,
752
+ packageNLSUri: URI.revive(e.packageNLSUri),
753
+ metadata: e.metadata,
754
+ });
755
+ }
756
+ try {
757
+ webExtensions = await this.migrateWebExtensions(webExtensions, file);
758
+ }
759
+ catch (error) {
760
+ this.logService.error(`Error while migrating scanned extensions in ${( file.toString())}`, getErrorMessage(error));
761
+ }
762
+ }
763
+ catch (error) {
764
+ if (error.fileOperationResult !== 1 ) {
765
+ this.logService.error(error);
766
+ }
767
+ }
768
+ if (updateFn) {
769
+ await this.storeWebExtensions(webExtensions = updateFn(webExtensions), file);
770
+ }
771
+ return webExtensions;
772
+ });
773
+ }
774
+ async migrateWebExtensions(webExtensions, file) {
775
+ let update = false;
776
+ webExtensions = await Promise.all(( webExtensions.map(async (webExtension) => {
777
+ if (!webExtension.manifest) {
778
+ try {
779
+ webExtension.manifest = await this.getExtensionManifest(webExtension.location);
780
+ update = true;
781
+ }
782
+ catch (error) {
783
+ this.logService.error(`Error while updating manifest of an extension in ${( file.toString())}`, webExtension.identifier.id, getErrorMessage(error));
784
+ }
785
+ }
786
+ if (isUndefined(webExtension.defaultManifestTranslations)) {
787
+ if (webExtension.fallbackPackageNLSUri) {
788
+ try {
789
+ const content = await this.extensionResourceLoaderService.readExtensionResource(webExtension.fallbackPackageNLSUri);
790
+ webExtension.defaultManifestTranslations = JSON.parse(content);
791
+ update = true;
792
+ }
793
+ catch (error) {
794
+ this.logService.error(`Error while fetching default manifest translations of an extension`, webExtension.identifier.id, getErrorMessage(error));
795
+ }
796
+ }
797
+ else {
798
+ update = true;
799
+ webExtension.defaultManifestTranslations = null;
800
+ }
801
+ }
802
+ const migratedLocation = migratePlatformSpecificExtensionGalleryResourceURL(webExtension.location, "web" );
803
+ if (migratedLocation) {
804
+ update = true;
805
+ webExtension.location = migratedLocation;
806
+ }
807
+ return webExtension;
808
+ })));
809
+ if (update) {
810
+ await this.storeWebExtensions(webExtensions, file);
811
+ }
812
+ return webExtensions;
813
+ }
814
+ async storeWebExtensions(webExtensions, file) {
815
+ function toStringDictionary(dictionary) {
816
+ if (!dictionary) {
817
+ return undefined;
818
+ }
819
+ const result = Object.create(null);
820
+ dictionary.forEach((value, key) => result[key] = value.toJSON());
821
+ return result;
822
+ }
823
+ const storedWebExtensions = ( webExtensions.map(e => ({
824
+ identifier: e.identifier,
825
+ version: e.version,
826
+ manifest: e.manifest,
827
+ location: e.location.toJSON(),
828
+ readmeUri: e.readmeUri?.toJSON(),
829
+ changelogUri: e.changelogUri?.toJSON(),
830
+ packageNLSUris: toStringDictionary(e.packageNLSUris),
831
+ defaultManifestTranslations: e.defaultManifestTranslations,
832
+ fallbackPackageNLSUri: e.fallbackPackageNLSUri?.toJSON(),
833
+ metadata: e.metadata
834
+ })));
835
+ await this.fileService.writeFile(file, VSBuffer.fromString(JSON.stringify(storedWebExtensions)));
836
+ }
837
+ getResourceAccessQueue(file) {
838
+ let resourceQueue = this.resourcesAccessQueueMap.get(file);
839
+ if (!resourceQueue) {
840
+ this.resourcesAccessQueueMap.set(file, resourceQueue = ( new Queue()));
841
+ }
842
+ return resourceQueue;
843
+ }
844
+ };
845
+ WebExtensionsScannerService = ( __decorate([
846
+ ( __param(0, IBrowserWorkbenchEnvironmentService)),
847
+ ( __param(1, IBuiltinExtensionsScannerService)),
848
+ ( __param(2, IFileService)),
849
+ ( __param(3, ILogService)),
850
+ ( __param(4, IExtensionGalleryService)),
851
+ ( __param(5, IExtensionManifestPropertiesService)),
852
+ ( __param(6, IExtensionResourceLoaderService)),
853
+ ( __param(7, IExtensionStorageService)),
854
+ ( __param(8, IStorageService)),
855
+ ( __param(9, IProductService)),
856
+ ( __param(10, IUserDataProfilesService)),
857
+ ( __param(11, IUriIdentityService)),
858
+ ( __param(12, ILifecycleService))
859
+ ], WebExtensionsScannerService));
860
+ if (isWeb) {
861
+ registerAction2(class extends Action2 {
862
+ constructor() {
863
+ super({
864
+ id: 'workbench.extensions.action.openInstalledWebExtensionsResource',
865
+ title: { value: ( localizeWithPath(
866
+ 'vs/workbench/services/extensionManagement/browser/webExtensionsScannerService',
867
+ 'openInstalledWebExtensionsResource',
868
+ "Open Installed Web Extensions Resource"
869
+ )), original: 'Open Installed Web Extensions Resource' },
870
+ category: Categories.Developer,
871
+ f1: true,
872
+ precondition: IsWebContext
873
+ });
874
+ }
875
+ run(serviceAccessor) {
876
+ const editorService = serviceAccessor.get(IEditorService);
877
+ const userDataProfileService = serviceAccessor.get(IUserDataProfileService);
878
+ editorService.openEditor({ resource: userDataProfileService.currentProfile.extensionsResource });
879
+ }
880
+ });
881
+ }
882
+
883
+ export { WebExtensionsScannerService };