UNPKG

sussudio

Version:

An unofficial VS Code Internal API

554 lines (553 loc) 35 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; import { Promises } from "../../../base/common/async.mjs"; import { CancellationToken } from "../../../base/common/cancellation.mjs"; import { getErrorMessage } from "../../../base/common/errors.mjs"; import { Event } from "../../../base/common/event.mjs"; import { toFormattedString } from "../../../base/common/jsonFormatter.mjs"; import { DisposableStore } from "../../../base/common/lifecycle.mjs"; import { compare } from "../../../base/common/strings.mjs"; import { IConfigurationService } from "../../configuration/common/configuration.mjs"; import { IEnvironmentService } from "../../environment/common/environment.mjs"; import { GlobalExtensionEnablementService } from "../../extensionManagement/common/extensionEnablementService.mjs"; import { IExtensionGalleryService, IExtensionManagementService, ExtensionManagementError, ExtensionManagementErrorCode, DISABLED_EXTENSIONS_STORAGE_PATH } from "../../extensionManagement/common/extensionManagement.mjs"; import { areSameExtensions } from "../../extensionManagement/common/extensionManagementUtil.mjs"; import { ExtensionStorageService, IExtensionStorageService } from "../../extensionManagement/common/extensionStorage.mjs"; import { IFileService } from "../../files/common/files.mjs"; import { IInstantiationService } from "../../instantiation/common/instantiation.mjs"; import { ServiceCollection } from "../../instantiation/common/serviceCollection.mjs"; import { ILogService } from "../../log/common/log.mjs"; import { IStorageService } from "../../storage/common/storage.mjs"; import { ITelemetryService } from "../../telemetry/common/telemetry.mjs"; import { IUriIdentityService } from "../../uriIdentity/common/uriIdentity.mjs"; import { IUserDataProfilesService } from "../../userDataProfile/common/userDataProfile.mjs"; import { AbstractInitializer, AbstractSynchroniser, getSyncResourceLogLabel } from "./abstractSynchronizer.mjs"; import { merge } from "./extensionsMerge.mjs"; import { IIgnoredExtensionsManagementService } from "./ignoredExtensions.mjs"; import { IUserDataSyncBackupStoreService, IUserDataSyncLogService, IUserDataSyncEnablementService, IUserDataSyncStoreService, USER_DATA_SYNC_SCHEME, EXTENSIONS_SYNC_CONTEXT_KEY } from "./userDataSync.mjs"; import { IUserDataProfileStorageService } from "../../userDataProfile/common/userDataProfileStorageService.mjs"; async function parseAndMigrateExtensions(syncData, extensionManagementService) { const extensions = JSON.parse(syncData.content); if (syncData.version === 1 || syncData.version === 2) { const builtinExtensions = (await extensionManagementService.getInstalled(0 /* ExtensionType.System */)).filter(e => e.isBuiltin); for (const extension of extensions) { // #region Migration from v1 (enabled -> disabled) if (syncData.version === 1) { if (extension.enabled === false) { extension.disabled = true; } delete extension.enabled; } // #endregion // #region Migration from v2 (set installed property on extension) if (syncData.version === 2) { if (builtinExtensions.every(installed => !areSameExtensions(installed.identifier, extension.identifier))) { extension.installed = true; } } // #endregion } } return extensions; } export function parseExtensions(syncData) { return JSON.parse(syncData.content); } export function stringify(extensions, format) { extensions.sort((e1, e2) => { if (!e1.identifier.uuid && e2.identifier.uuid) { return -1; } if (e1.identifier.uuid && !e2.identifier.uuid) { return 1; } return compare(e1.identifier.id, e2.identifier.id); }); return format ? toFormattedString(extensions, {}) : JSON.stringify(extensions); } let ExtensionsSynchroniser = class ExtensionsSynchroniser extends AbstractSynchroniser { extensionManagementService; ignoredExtensionsManagementService; instantiationService; /* Version 3 - Introduce installed property to skip installing built in extensions protected readonly version: number = 3; */ /* Version 4: Change settings from `sync.${setting}` to `settingsSync.{setting}` */ /* Version 5: Introduce extension state */ version = 5; previewResource = this.extUri.joinPath(this.syncPreviewFolder, 'extensions.json'); baseResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'base' }); localResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'local' }); remoteResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'remote' }); acceptedResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'accepted' }); localExtensionsProvider; constructor( // profileLocation changes for default profile profile, collection, environmentService, fileService, storageService, userDataSyncStoreService, userDataSyncBackupStoreService, extensionManagementService, ignoredExtensionsManagementService, logService, configurationService, userDataSyncEnablementService, telemetryService, extensionStorageService, uriIdentityService, userDataProfileStorageService, instantiationService) { super({ syncResource: "extensions" /* SyncResource.Extensions */, profile }, collection, fileService, environmentService, storageService, userDataSyncStoreService, userDataSyncBackupStoreService, userDataSyncEnablementService, telemetryService, logService, configurationService, uriIdentityService); this.extensionManagementService = extensionManagementService; this.ignoredExtensionsManagementService = ignoredExtensionsManagementService; this.instantiationService = instantiationService; this.localExtensionsProvider = this.instantiationService.createInstance(LocalExtensionsProvider); this._register(Event.any(Event.filter(this.extensionManagementService.onDidInstallExtensions, (e => e.some(({ local }) => !!local))), Event.filter(this.extensionManagementService.onDidUninstallExtension, (e => !e.error)), Event.filter(userDataProfileStorageService.onDidChange, e => e.valueChanges.some(({ profile, changes }) => this.syncResource.profile.id === profile.id && changes.some(change => change.key === DISABLED_EXTENSIONS_STORAGE_PATH))), extensionStorageService.onDidChangeExtensionStorageToSync)(() => this.triggerLocalChange())); } async generateSyncPreview(remoteUserData, lastSyncUserData) { const remoteExtensions = remoteUserData.syncData ? await parseAndMigrateExtensions(remoteUserData.syncData, this.extensionManagementService) : null; const skippedExtensions = lastSyncUserData?.skippedExtensions || []; const builtinExtensions = lastSyncUserData?.builtinExtensions || []; const lastSyncExtensions = lastSyncUserData?.syncData ? await parseAndMigrateExtensions(lastSyncUserData.syncData, this.extensionManagementService) : null; const { localExtensions, ignoredExtensions } = await this.localExtensionsProvider.getLocalExtensions(this.syncResource.profile); if (remoteExtensions) { this.logService.trace(`${this.syncResourceLogLabel}: Merging remote extensions with local extensions...`); } else { this.logService.trace(`${this.syncResourceLogLabel}: Remote extensions does not exist. Synchronizing extensions for the first time.`); } const { local, remote } = merge(localExtensions, remoteExtensions, lastSyncExtensions, skippedExtensions, ignoredExtensions, builtinExtensions); const previewResult = { local, remote, content: this.getPreviewContent(localExtensions, local.added, local.updated, local.removed), localChange: local.added.length > 0 || local.removed.length > 0 || local.updated.length > 0 ? 2 /* Change.Modified */ : 0 /* Change.None */, remoteChange: remote !== null ? 2 /* Change.Modified */ : 0 /* Change.None */, }; const localContent = this.stringify(localExtensions, false); return [{ skippedExtensions, builtinExtensions, baseResource: this.baseResource, baseContent: lastSyncExtensions ? this.stringify(lastSyncExtensions, false) : localContent, localResource: this.localResource, localContent, localExtensions, remoteResource: this.remoteResource, remoteExtensions, remoteContent: remoteExtensions ? this.stringify(remoteExtensions, false) : null, previewResource: this.previewResource, previewResult, localChange: previewResult.localChange, remoteChange: previewResult.remoteChange, acceptedResource: this.acceptedResource, }]; } async hasRemoteChanged(lastSyncUserData) { const lastSyncExtensions = lastSyncUserData.syncData ? await parseAndMigrateExtensions(lastSyncUserData.syncData, this.extensionManagementService) : null; const { localExtensions, ignoredExtensions } = await this.localExtensionsProvider.getLocalExtensions(this.syncResource.profile); const { remote } = merge(localExtensions, lastSyncExtensions, lastSyncExtensions, lastSyncUserData.skippedExtensions || [], ignoredExtensions, lastSyncUserData.builtinExtensions || []); return remote !== null; } getPreviewContent(localExtensions, added, updated, removed) { const preview = [...added, ...updated]; const idsOrUUIDs = new Set(); const addIdentifier = (identifier) => { idsOrUUIDs.add(identifier.id.toLowerCase()); if (identifier.uuid) { idsOrUUIDs.add(identifier.uuid); } }; preview.forEach(({ identifier }) => addIdentifier(identifier)); removed.forEach(addIdentifier); for (const localExtension of localExtensions) { if (idsOrUUIDs.has(localExtension.identifier.id.toLowerCase()) || (localExtension.identifier.uuid && idsOrUUIDs.has(localExtension.identifier.uuid))) { // skip continue; } preview.push(localExtension); } return this.stringify(preview, false); } async getMergeResult(resourcePreview, token) { return { ...resourcePreview.previewResult, hasConflicts: false }; } async getAcceptResult(resourcePreview, resource, content, token) { /* Accept local resource */ if (this.extUri.isEqual(resource, this.localResource)) { return this.acceptLocal(resourcePreview); } /* Accept remote resource */ if (this.extUri.isEqual(resource, this.remoteResource)) { return this.acceptRemote(resourcePreview); } /* Accept preview resource */ if (this.extUri.isEqual(resource, this.previewResource)) { return resourcePreview.previewResult; } throw new Error(`Invalid Resource: ${resource.toString()}`); } async acceptLocal(resourcePreview) { const installedExtensions = await this.extensionManagementService.getInstalled(undefined, this.syncResource.profile.extensionsResource); const ignoredExtensions = this.ignoredExtensionsManagementService.getIgnoredExtensions(installedExtensions); const mergeResult = merge(resourcePreview.localExtensions, null, null, resourcePreview.skippedExtensions, ignoredExtensions, resourcePreview.builtinExtensions); const { local, remote } = mergeResult; return { content: resourcePreview.localContent, local, remote, localChange: local.added.length > 0 || local.removed.length > 0 || local.updated.length > 0 ? 2 /* Change.Modified */ : 0 /* Change.None */, remoteChange: remote !== null ? 2 /* Change.Modified */ : 0 /* Change.None */, }; } async acceptRemote(resourcePreview) { const installedExtensions = await this.extensionManagementService.getInstalled(undefined, this.syncResource.profile.extensionsResource); const ignoredExtensions = this.ignoredExtensionsManagementService.getIgnoredExtensions(installedExtensions); const remoteExtensions = resourcePreview.remoteContent ? JSON.parse(resourcePreview.remoteContent) : null; if (remoteExtensions !== null) { const mergeResult = merge(resourcePreview.localExtensions, remoteExtensions, resourcePreview.localExtensions, [], ignoredExtensions, resourcePreview.builtinExtensions); const { local, remote } = mergeResult; return { content: resourcePreview.remoteContent, local, remote, localChange: local.added.length > 0 || local.removed.length > 0 || local.updated.length > 0 ? 2 /* Change.Modified */ : 0 /* Change.None */, remoteChange: remote !== null ? 2 /* Change.Modified */ : 0 /* Change.None */, }; } else { return { content: resourcePreview.remoteContent, local: { added: [], removed: [], updated: [] }, remote: null, localChange: 0 /* Change.None */, remoteChange: 0 /* Change.None */, }; } } async applyResult(remoteUserData, lastSyncUserData, resourcePreviews, force) { let { skippedExtensions, localExtensions } = resourcePreviews[0][0]; const { local, remote, localChange, remoteChange } = resourcePreviews[0][1]; if (localChange === 0 /* Change.None */ && remoteChange === 0 /* Change.None */) { this.logService.info(`${this.syncResourceLogLabel}: No changes found during synchronizing extensions.`); } if (localChange !== 0 /* Change.None */) { await this.backupLocal(JSON.stringify(localExtensions)); skippedExtensions = await this.localExtensionsProvider.updateLocalExtensions(local.added, local.removed, local.updated, skippedExtensions, this.syncResource.profile); } if (remote) { // update remote this.logService.trace(`${this.syncResourceLogLabel}: Updating remote extensions...`); const content = JSON.stringify(remote.all); remoteUserData = await this.updateRemoteUserData(content, force ? null : remoteUserData.ref); this.logService.info(`${this.syncResourceLogLabel}: Updated remote extensions.${remote.added.length ? ` Added: ${JSON.stringify(remote.added.map(e => e.identifier.id))}.` : ''}${remote.updated.length ? ` Updated: ${JSON.stringify(remote.updated.map(e => e.identifier.id))}.` : ''}${remote.removed.length ? ` Removed: ${JSON.stringify(remote.removed.map(e => e.identifier.id))}.` : ''}`); } if (lastSyncUserData?.ref !== remoteUserData.ref) { // update last sync this.logService.trace(`${this.syncResourceLogLabel}: Updating last synchronized extensions...`); const builtinExtensions = localExtensions.filter(e => !e.installed).map(e => e.identifier); await this.updateLastSyncUserData(remoteUserData, { skippedExtensions, builtinExtensions }); this.logService.info(`${this.syncResourceLogLabel}: Updated last synchronized extensions.${skippedExtensions.length ? ` Skipped: ${JSON.stringify(skippedExtensions.map(e => e.identifier.id))}.` : ''}`); } } async resolveContent(uri) { if (this.extUri.isEqual(this.remoteResource, uri) || this.extUri.isEqual(this.baseResource, uri) || this.extUri.isEqual(this.localResource, uri) || this.extUri.isEqual(this.acceptedResource, uri)) { const content = await this.resolvePreviewContent(uri); return content ? this.stringify(JSON.parse(content), true) : content; } return null; } stringify(extensions, format) { return stringify(extensions, format); } async hasLocalData() { try { const { localExtensions } = await this.localExtensionsProvider.getLocalExtensions(this.syncResource.profile); if (localExtensions.some(e => e.installed || e.disabled)) { return true; } } catch (error) { /* ignore error */ } return false; } }; ExtensionsSynchroniser = __decorate([ __param(2, IEnvironmentService), __param(3, IFileService), __param(4, IStorageService), __param(5, IUserDataSyncStoreService), __param(6, IUserDataSyncBackupStoreService), __param(7, IExtensionManagementService), __param(8, IIgnoredExtensionsManagementService), __param(9, IUserDataSyncLogService), __param(10, IConfigurationService), __param(11, IUserDataSyncEnablementService), __param(12, ITelemetryService), __param(13, IExtensionStorageService), __param(14, IUriIdentityService), __param(15, IUserDataProfileStorageService), __param(16, IInstantiationService) ], ExtensionsSynchroniser); export { ExtensionsSynchroniser }; let LocalExtensionsProvider = class LocalExtensionsProvider { extensionManagementService; userDataProfileStorageService; extensionGalleryService; ignoredExtensionsManagementService; instantiationService; logService; constructor(extensionManagementService, userDataProfileStorageService, extensionGalleryService, ignoredExtensionsManagementService, instantiationService, logService) { this.extensionManagementService = extensionManagementService; this.userDataProfileStorageService = userDataProfileStorageService; this.extensionGalleryService = extensionGalleryService; this.ignoredExtensionsManagementService = ignoredExtensionsManagementService; this.instantiationService = instantiationService; this.logService = logService; } async getLocalExtensions(profile) { const installedExtensions = await this.extensionManagementService.getInstalled(undefined, profile.extensionsResource); const ignoredExtensions = this.ignoredExtensionsManagementService.getIgnoredExtensions(installedExtensions); const localExtensions = await this.withProfileScopedServices(profile, async (extensionEnablementService, extensionStorageService) => { const disabledExtensions = extensionEnablementService.getDisabledExtensions(); return installedExtensions .map(extension => { const { identifier, isBuiltin, manifest, preRelease } = extension; const syncExntesion = { identifier, preRelease, version: manifest.version }; if (disabledExtensions.some(disabledExtension => areSameExtensions(disabledExtension, identifier))) { syncExntesion.disabled = true; } if (!isBuiltin) { syncExntesion.installed = true; } try { const keys = extensionStorageService.getKeysForSync({ id: identifier.id, version: manifest.version }); if (keys) { const extensionStorageState = extensionStorageService.getExtensionState(extension, true) || {}; syncExntesion.state = Object.keys(extensionStorageState).reduce((state, key) => { if (keys.includes(key)) { state[key] = extensionStorageState[key]; } return state; }, {}); } } catch (error) { this.logService.info(`${getSyncResourceLogLabel("extensions" /* SyncResource.Extensions */, profile)}: Error while parsing extension state`, getErrorMessage(error)); } return syncExntesion; }); }); return { localExtensions, ignoredExtensions }; } async updateLocalExtensions(added, removed, updated, skippedExtensions, profile) { const syncResourceLogLabel = getSyncResourceLogLabel("extensions" /* SyncResource.Extensions */, profile); const extensionsToInstall = []; const removeFromSkipped = []; const addToSkipped = []; const installedExtensions = await this.extensionManagementService.getInstalled(undefined, profile.extensionsResource); // 1. Sync extensions state first so that the storage is flushed and updated in all opened windows if (added.length || updated.length) { await this.withProfileScopedServices(profile, async (extensionEnablementService, extensionStorageService) => { await Promises.settled([...added, ...updated].map(async (e) => { const installedExtension = installedExtensions.find(installed => areSameExtensions(installed.identifier, e.identifier)); // Builtin Extension Sync: Enablement & State if (installedExtension && installedExtension.isBuiltin) { if (e.state && installedExtension.manifest.version === e.version) { this.updateExtensionState(e.state, installedExtension, installedExtension.manifest.version, extensionStorageService); } const isDisabled = extensionEnablementService.getDisabledExtensions().some(disabledExtension => areSameExtensions(disabledExtension, e.identifier)); if (isDisabled !== !!e.disabled) { if (e.disabled) { this.logService.trace(`${syncResourceLogLabel}: Disabling extension...`, e.identifier.id); await extensionEnablementService.disableExtension(e.identifier); this.logService.info(`${syncResourceLogLabel}: Disabled extension`, e.identifier.id); } else { this.logService.trace(`${syncResourceLogLabel}: Enabling extension...`, e.identifier.id); await extensionEnablementService.enableExtension(e.identifier); this.logService.info(`${syncResourceLogLabel}: Enabled extension`, e.identifier.id); } } removeFromSkipped.push(e.identifier); return; } // User Extension Sync: Install/Update, Enablement & State const extension = (await this.extensionGalleryService.getExtensions([{ ...e.identifier, preRelease: e.preRelease }], CancellationToken.None))[0]; /* Update extension state only if * extension is installed and version is same as synced version or * extension is not installed and installable */ if (e.state && (installedExtension ? installedExtension.manifest.version === e.version /* Installed and has same version */ : !!extension /* Installable */)) { this.updateExtensionState(e.state, installedExtension || extension, installedExtension?.manifest.version, extensionStorageService); } if (extension) { try { const isDisabled = extensionEnablementService.getDisabledExtensions().some(disabledExtension => areSameExtensions(disabledExtension, e.identifier)); if (isDisabled !== !!e.disabled) { if (e.disabled) { this.logService.trace(`${syncResourceLogLabel}: Disabling extension...`, e.identifier.id, extension.version); await extensionEnablementService.disableExtension(extension.identifier); this.logService.info(`${syncResourceLogLabel}: Disabled extension`, e.identifier.id, extension.version); } else { this.logService.trace(`${syncResourceLogLabel}: Enabling extension...`, e.identifier.id, extension.version); await extensionEnablementService.enableExtension(extension.identifier); this.logService.info(`${syncResourceLogLabel}: Enabled extension`, e.identifier.id, extension.version); } } if (!installedExtension // Install if the extension does not exist || installedExtension.preRelease !== e.preRelease // Install if the extension pre-release preference has changed ) { if (await this.extensionManagementService.canInstall(extension)) { extensionsToInstall.push([e, extension]); } else { this.logService.info(`${syncResourceLogLabel}: Skipped synchronizing extension because it cannot be installed.`, extension.displayName || extension.identifier.id); addToSkipped.push(e); } } } catch (error) { addToSkipped.push(e); this.logService.error(error); this.logService.info(`${syncResourceLogLabel}: Skipped synchronizing extension`, extension.displayName || extension.identifier.id); } } else { addToSkipped.push(e); this.logService.info(`${syncResourceLogLabel}: Skipped synchronizing extension because the extension is not found.`, e.identifier.id); } })); }); } // 2. Next uninstall the removed extensions if (removed.length) { const extensionsToRemove = installedExtensions.filter(({ identifier, isBuiltin }) => !isBuiltin && removed.some(r => areSameExtensions(identifier, r))); await Promises.settled(extensionsToRemove.map(async (extensionToRemove) => { this.logService.trace(`${syncResourceLogLabel}: Uninstalling local extension...`, extensionToRemove.identifier.id); await this.extensionManagementService.uninstall(extensionToRemove, { donotIncludePack: true, donotCheckDependents: true, profileLocation: profile.extensionsResource }); this.logService.info(`${syncResourceLogLabel}: Uninstalled local extension.`, extensionToRemove.identifier.id); removeFromSkipped.push(extensionToRemove.identifier); })); } // 3. Install extensions at the end for (const [e, extension] of extensionsToInstall) { try { this.logService.trace(`${syncResourceLogLabel}: Installing extension...`, extension.identifier.id, extension.version); await this.extensionManagementService.installFromGallery(extension, { isMachineScoped: false /* set isMachineScoped value to prevent install and sync dialog in web */, donotIncludePackAndDependencies: true, installPreReleaseVersion: e.preRelease, profileLocation: profile.extensionsResource, context: { [EXTENSIONS_SYNC_CONTEXT_KEY]: true } }); this.logService.info(`${syncResourceLogLabel}: Installed extension.`, extension.identifier.id, extension.version); removeFromSkipped.push(extension.identifier); } catch (error) { addToSkipped.push(e); if (error instanceof ExtensionManagementError && [ExtensionManagementErrorCode.Incompatible, ExtensionManagementErrorCode.IncompatiblePreRelease, ExtensionManagementErrorCode.IncompatibleTargetPlatform].includes(error.code)) { this.logService.info(`${syncResourceLogLabel}: Skipped synchronizing extension because the compatible extension is not found.`, extension.displayName || extension.identifier.id); } else { this.logService.error(error); this.logService.info(`${syncResourceLogLabel}: Skipped synchronizing extension`, extension.displayName || extension.identifier.id); } } } const newSkippedExtensions = []; for (const skippedExtension of skippedExtensions) { if (!removeFromSkipped.some(e => areSameExtensions(e, skippedExtension.identifier))) { newSkippedExtensions.push(skippedExtension); } } for (const skippedExtension of addToSkipped) { if (!newSkippedExtensions.some(e => areSameExtensions(e.identifier, skippedExtension.identifier))) { newSkippedExtensions.push(skippedExtension); } } return newSkippedExtensions; } updateExtensionState(state, extension, version, extensionStorageService) { const extensionState = extensionStorageService.getExtensionState(extension, true) || {}; const keys = version ? extensionStorageService.getKeysForSync({ id: extension.identifier.id, version }) : undefined; if (keys) { keys.forEach(key => { extensionState[key] = state[key]; }); } else { Object.keys(state).forEach(key => extensionState[key] = state[key]); } extensionStorageService.setExtensionState(extension, extensionState, true); } async withProfileScopedServices(profile, fn) { return this.userDataProfileStorageService.withProfileScopedStorageService(profile, async (storageService) => { const disposables = new DisposableStore(); const instantiationService = this.instantiationService.createChild(new ServiceCollection([IStorageService, storageService])); const extensionEnablementService = disposables.add(instantiationService.createInstance(GlobalExtensionEnablementService)); const extensionStorageService = disposables.add(instantiationService.createInstance(ExtensionStorageService)); try { return await fn(extensionEnablementService, extensionStorageService); } finally { disposables.dispose(); } }); } }; LocalExtensionsProvider = __decorate([ __param(0, IExtensionManagementService), __param(1, IUserDataProfileStorageService), __param(2, IExtensionGalleryService), __param(3, IIgnoredExtensionsManagementService), __param(4, IInstantiationService), __param(5, IUserDataSyncLogService) ], LocalExtensionsProvider); export { LocalExtensionsProvider }; let AbstractExtensionsInitializer = class AbstractExtensionsInitializer extends AbstractInitializer { extensionManagementService; ignoredExtensionsManagementService; constructor(extensionManagementService, ignoredExtensionsManagementService, fileService, userDataProfilesService, environmentService, logService, storageService, uriIdentityService) { super("extensions" /* SyncResource.Extensions */, userDataProfilesService, environmentService, logService, fileService, storageService, uriIdentityService); this.extensionManagementService = extensionManagementService; this.ignoredExtensionsManagementService = ignoredExtensionsManagementService; } async parseExtensions(remoteUserData) { return remoteUserData.syncData ? await parseAndMigrateExtensions(remoteUserData.syncData, this.extensionManagementService) : null; } generatePreview(remoteExtensions, localExtensions) { const installedExtensions = []; const newExtensions = []; const disabledExtensions = []; for (const extension of remoteExtensions) { if (this.ignoredExtensionsManagementService.hasToNeverSyncExtension(extension.identifier.id)) { // Skip extension ignored to sync continue; } const installedExtension = localExtensions.find(i => areSameExtensions(i.identifier, extension.identifier)); if (installedExtension) { installedExtensions.push(installedExtension); if (extension.disabled) { disabledExtensions.push(extension.identifier); } } else if (extension.installed) { newExtensions.push({ ...extension.identifier, preRelease: !!extension.preRelease }); if (extension.disabled) { disabledExtensions.push(extension.identifier); } } } return { installedExtensions, newExtensions, disabledExtensions, remoteExtensions }; } }; AbstractExtensionsInitializer = __decorate([ __param(0, IExtensionManagementService), __param(1, IIgnoredExtensionsManagementService), __param(2, IFileService), __param(3, IUserDataProfilesService), __param(4, IEnvironmentService), __param(5, ILogService), __param(6, IStorageService), __param(7, IUriIdentityService) ], AbstractExtensionsInitializer); export { AbstractExtensionsInitializer };