@codingame/monaco-vscode-user-data-profile-service-override 5.3.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 (33) hide show
  1. package/index.d.ts +1 -0
  2. package/index.js +1 -0
  3. package/package.json +31 -0
  4. package/userDataProfile.js +118 -0
  5. package/vscode/src/vs/platform/userDataProfile/browser/userDataProfile.js +95 -0
  6. package/vscode/src/vs/platform/userDataProfile/common/userDataProfileStorageService.js +84 -0
  7. package/vscode/src/vs/platform/userDataSync/common/extensionsMerge.js +331 -0
  8. package/vscode/src/vs/platform/userDataSync/common/extensionsSync.js +545 -0
  9. package/vscode/src/vs/platform/userDataSync/common/globalStateMerge.js +102 -0
  10. package/vscode/src/vs/platform/userDataSync/common/globalStateSync.js +431 -0
  11. package/vscode/src/vs/platform/userDataSync/common/keybindingsMerge.js +277 -0
  12. package/vscode/src/vs/platform/userDataSync/common/keybindingsSync.js +328 -0
  13. package/vscode/src/vs/platform/userDataSync/common/settingsSync.js +322 -0
  14. package/vscode/src/vs/platform/userDataSync/common/snippetsMerge.js +126 -0
  15. package/vscode/src/vs/platform/userDataSync/common/snippetsSync.js +478 -0
  16. package/vscode/src/vs/platform/userDataSync/common/tasksSync.js +245 -0
  17. package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.js +9 -0
  18. package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.js +495 -0
  19. package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfileActions.js +159 -0
  20. package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfilePreview.js +24 -0
  21. package/vscode/src/vs/workbench/services/userData/browser/userDataInit.js +62 -0
  22. package/vscode/src/vs/workbench/services/userDataProfile/browser/extensionsResource.js +328 -0
  23. package/vscode/src/vs/workbench/services/userDataProfile/browser/globalStateResource.js +144 -0
  24. package/vscode/src/vs/workbench/services/userDataProfile/browser/keybindingsResource.js +119 -0
  25. package/vscode/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css.js +6 -0
  26. package/vscode/src/vs/workbench/services/userDataProfile/browser/settingsResource.js +140 -0
  27. package/vscode/src/vs/workbench/services/userDataProfile/browser/snippetsResource.js +155 -0
  28. package/vscode/src/vs/workbench/services/userDataProfile/browser/tasksResource.js +118 -0
  29. package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.js +1453 -0
  30. package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.js +151 -0
  31. package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.js +180 -0
  32. package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileStorageService.js +39 -0
  33. package/vscode/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.js +448 -0
package/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from 'vscode/service-override/userDataProfile';
package/index.js ADDED
@@ -0,0 +1 @@
1
+ export { default } from './userDataProfile.js';
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@codingame/monaco-vscode-user-data-profile-service-override",
3
+ "version": "5.3.0",
4
+ "keywords": [],
5
+ "author": {
6
+ "name": "CodinGame",
7
+ "url": "http://www.codingame.com"
8
+ },
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git@github.com:CodinGame/monaco-vscode-api.git"
13
+ },
14
+ "type": "module",
15
+ "private": false,
16
+ "description": "VSCode public API plugged on the monaco editor - user-data-profile service-override",
17
+ "main": "index.js",
18
+ "module": "index.js",
19
+ "types": "index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "default": "./index.js"
23
+ },
24
+ "./vscode/*": {
25
+ "default": "./vscode/src/*.js"
26
+ }
27
+ },
28
+ "dependencies": {
29
+ "vscode": "npm:@codingame/monaco-vscode-api@5.3.0"
30
+ }
31
+ }
@@ -0,0 +1,118 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { SyncDescriptor } from 'vscode/vscode/vs/platform/instantiation/common/descriptors';
3
+ import { IUserDataSyncStoreManagementService } from 'vscode/vscode/vs/platform/userDataSync/common/userDataSync.service';
4
+ import { BrowserUserDataProfilesService } from './vscode/src/vs/platform/userDataProfile/browser/userDataProfile.js';
5
+ import { IUserDataProfilesService } from 'vscode/vscode/vs/platform/userDataProfile/common/userDataProfile.service';
6
+ import { UserDataInitializationService } from './vscode/src/vs/workbench/services/userData/browser/userDataInit.js';
7
+ import { IUserDataInitializationService } from 'vscode/vscode/vs/workbench/services/userData/browser/userDataInit.service';
8
+ import { UserDataSyncInitializer } from './vscode/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.js';
9
+ import { UserDataProfileInitializer } from './vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.js';
10
+ import { IBrowserWorkbenchEnvironmentService } from 'vscode/vscode/vs/workbench/services/environment/browser/environmentService.service';
11
+ import { ISecretStorageService } from 'vscode/vscode/vs/platform/secrets/common/secrets.service';
12
+ import { IFileService } from 'vscode/vscode/vs/platform/files/common/files.service';
13
+ import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage.service';
14
+ import { IProductService } from 'vscode/vscode/vs/platform/product/common/productService.service';
15
+ import { IRequestService } from 'vscode/vscode/vs/platform/request/common/request.service';
16
+ import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
17
+ import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity.service';
18
+ import { IUserDataProfileService, IUserDataProfileImportExportService, IUserDataProfileManagementService } from 'vscode/vscode/vs/workbench/services/userDataProfile/common/userDataProfile.service';
19
+ import { mark } from 'vscode/vscode/vs/base/common/performance';
20
+ import { timeout } from 'vscode/vscode/vs/base/common/async';
21
+ import { IWorkbenchConfigurationService } from 'vscode/vscode/vs/workbench/services/configuration/common/configuration.service';
22
+ import { UserDataProfileImportExportService } from './vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.js';
23
+ import { UserDataProfileManagementService } from './vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.js';
24
+ import { IUserDataProfileStorageService } from 'vscode/vscode/vs/platform/userDataProfile/common/userDataProfileStorageService.service';
25
+ import { UserDataProfileStorageService } from './vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileStorageService.js';
26
+ import { UserDataProfileService } from 'vscode/vscode/vs/workbench/services/userDataProfile/common/userDataProfileService';
27
+ import { registerServiceInitializePostParticipant } from 'vscode/lifecycle';
28
+ import { getWorkspaceIdentifier } from 'vscode/workbench';
29
+ import './vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.js';
30
+
31
+ function isWorkspaceService(configurationService) {
32
+ return 'reloadLocalUserConfiguration' in configurationService;
33
+ }
34
+ async function initializeUserData(userDataInitializationService, configurationService) {
35
+ if (await userDataInitializationService.requiresInitialization()) {
36
+ mark('code/willInitRequiredUserData');
37
+ await userDataInitializationService.initializeRequiredResources();
38
+ if (isWorkspaceService(configurationService)) {
39
+ await configurationService.reloadLocalUserConfiguration();
40
+ }
41
+ mark('code/didInitRequiredUserData');
42
+ }
43
+ }
44
+ registerServiceInitializePostParticipant(async (accessor) => {
45
+ try {
46
+ await Promise.race([
47
+ timeout(5000),
48
+ initializeUserData(accessor.get(IUserDataInitializationService), accessor.get(IWorkbenchConfigurationService))
49
+ ]);
50
+ }
51
+ catch (error) {
52
+ accessor.get(ILogService).error(error);
53
+ }
54
+ });
55
+ let InjectedUserDataInitializationService = class InjectedUserDataInitializationService extends UserDataInitializationService {
56
+ constructor(environmentService, secretStorageService, userDataSyncStoreManagementService, fileService, userDataProfilesService, storageService, productService, requestService, logService, uriIdentityService, userDataProfileService) {
57
+ const userDataInitializers = [];
58
+ userDataInitializers.push(new UserDataSyncInitializer(environmentService, secretStorageService, userDataSyncStoreManagementService, fileService, userDataProfilesService, storageService, productService, requestService, logService, uriIdentityService));
59
+ if (environmentService.options?.profile != null) {
60
+ userDataInitializers.push(new UserDataProfileInitializer(environmentService, fileService, userDataProfileService, storageService, logService, uriIdentityService, requestService));
61
+ }
62
+ super(userDataInitializers);
63
+ }
64
+ };
65
+ InjectedUserDataInitializationService = __decorate([
66
+ ( __param(0, IBrowserWorkbenchEnvironmentService)),
67
+ ( __param(1, ISecretStorageService)),
68
+ ( __param(2, IUserDataSyncStoreManagementService)),
69
+ ( __param(3, IFileService)),
70
+ ( __param(4, IUserDataProfilesService)),
71
+ ( __param(5, IStorageService)),
72
+ ( __param(6, IProductService)),
73
+ ( __param(7, IRequestService)),
74
+ ( __param(8, ILogService)),
75
+ ( __param(9, IUriIdentityService)),
76
+ ( __param(10, IUserDataProfileService))
77
+ ], InjectedUserDataInitializationService);
78
+ function getCurrentProfile(workspace, userDataProfilesService, environmentService) {
79
+ if (environmentService.options?.profile != null) {
80
+ const profile = userDataProfilesService.profiles.find(p => p.name === environmentService.options?.profile?.name);
81
+ if (profile != null) {
82
+ return profile;
83
+ }
84
+ return userDataProfilesService.defaultProfile;
85
+ }
86
+ return userDataProfilesService.getProfileForWorkspace(workspace) ?? userDataProfilesService.defaultProfile;
87
+ }
88
+ let InjectedUserDataProfileService = class InjectedUserDataProfileService extends UserDataProfileService {
89
+ constructor(environmentService, userDataProfilesService, logService) {
90
+ const workspace = getWorkspaceIdentifier();
91
+ const profile = getCurrentProfile(workspace, userDataProfilesService, environmentService);
92
+ super(profile);
93
+ if (profile === userDataProfilesService.defaultProfile && environmentService.options?.profile != null) {
94
+ userDataProfilesService.createNamedProfile(environmentService.options.profile.name, undefined, workspace).then(async (profile) => {
95
+ await this.updateCurrentProfile(profile);
96
+ }).catch(err => {
97
+ logService.error(err);
98
+ });
99
+ }
100
+ }
101
+ };
102
+ InjectedUserDataProfileService = __decorate([
103
+ ( __param(0, IBrowserWorkbenchEnvironmentService)),
104
+ ( __param(1, IUserDataProfilesService)),
105
+ ( __param(2, ILogService))
106
+ ], InjectedUserDataProfileService);
107
+ function getServiceOverride() {
108
+ return {
109
+ [( IUserDataProfileService.toString())]: new SyncDescriptor(InjectedUserDataProfileService, [], true),
110
+ [( IUserDataProfilesService.toString())]: new SyncDescriptor(BrowserUserDataProfilesService, [], true),
111
+ [( IUserDataInitializationService.toString())]: new SyncDescriptor(InjectedUserDataInitializationService, [], true),
112
+ [( IUserDataProfileImportExportService.toString())]: new SyncDescriptor(UserDataProfileImportExportService, [], true),
113
+ [( IUserDataProfileManagementService.toString())]: new SyncDescriptor(UserDataProfileManagementService, [], true),
114
+ [( IUserDataProfileStorageService.toString())]: new SyncDescriptor(UserDataProfileStorageService, [], true)
115
+ };
116
+ }
117
+
118
+ export { getServiceOverride as default };
@@ -0,0 +1,95 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { BroadcastDataChannel } from 'vscode/vscode/vs/base/browser/broadcast';
3
+ import { revive } from 'vscode/vscode/vs/base/common/marshalling';
4
+ import { IEnvironmentService } from 'vscode/vscode/vs/platform/environment/common/environment.service';
5
+ import { IFileService } from 'vscode/vscode/vs/platform/files/common/files.service';
6
+ import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
7
+ import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity.service';
8
+ import { UserDataProfilesService, reviveProfile } from 'vscode/vscode/vs/platform/userDataProfile/common/userDataProfile';
9
+
10
+ let BrowserUserDataProfilesService = class BrowserUserDataProfilesService extends UserDataProfilesService {
11
+ constructor(environmentService, fileService, uriIdentityService, logService) {
12
+ super(environmentService, fileService, uriIdentityService, logService);
13
+ this.changesBroadcastChannel = this._register(( new BroadcastDataChannel(`${UserDataProfilesService.PROFILES_KEY}.changes`)));
14
+ this._register(this.changesBroadcastChannel.onDidReceiveData(changes => {
15
+ try {
16
+ this._profilesObject = undefined;
17
+ const added = ( changes.added.map(p => reviveProfile(p, this.profilesHome.scheme)));
18
+ const removed = ( changes.removed.map(p => reviveProfile(p, this.profilesHome.scheme)));
19
+ const updated = ( changes.updated.map(p => reviveProfile(p, this.profilesHome.scheme)));
20
+ this.updateTransientProfiles(added.filter(a => a.isTransient), removed.filter(a => a.isTransient), updated.filter(a => a.isTransient));
21
+ this._onDidChangeProfiles.fire({
22
+ added,
23
+ removed,
24
+ updated,
25
+ all: this.profiles
26
+ });
27
+ }
28
+ catch (error) { }
29
+ }));
30
+ }
31
+ updateTransientProfiles(added, removed, updated) {
32
+ if (added.length) {
33
+ this.transientProfilesObject.profiles.push(...added);
34
+ }
35
+ if (removed.length || updated.length) {
36
+ const allTransientProfiles = this.transientProfilesObject.profiles;
37
+ this.transientProfilesObject.profiles = [];
38
+ for (const profile of allTransientProfiles) {
39
+ if (( removed.some(p => profile.id === p.id))) {
40
+ continue;
41
+ }
42
+ this.transientProfilesObject.profiles.push(updated.find(p => profile.id === p.id) ?? profile);
43
+ }
44
+ }
45
+ }
46
+ getStoredProfiles() {
47
+ try {
48
+ const value = localStorage.getItem(UserDataProfilesService.PROFILES_KEY);
49
+ if (value) {
50
+ return revive(JSON.parse(value));
51
+ }
52
+ }
53
+ catch (error) {
54
+ this.logService.error(error);
55
+ }
56
+ return [];
57
+ }
58
+ triggerProfilesChanges(added, removed, updated) {
59
+ super.triggerProfilesChanges(added, removed, updated);
60
+ this.changesBroadcastChannel.postData({ added, removed, updated });
61
+ }
62
+ saveStoredProfiles(storedProfiles) {
63
+ localStorage.setItem(UserDataProfilesService.PROFILES_KEY, JSON.stringify(storedProfiles));
64
+ }
65
+ getStoredProfileAssociations() {
66
+ const migrateKey = 'profileAssociationsMigration';
67
+ try {
68
+ const value = localStorage.getItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY);
69
+ if (value) {
70
+ let associations = JSON.parse(value);
71
+ if (!localStorage.getItem(migrateKey)) {
72
+ associations = this.migrateStoredProfileAssociations(associations);
73
+ this.saveStoredProfileAssociations(associations);
74
+ localStorage.setItem(migrateKey, 'true');
75
+ }
76
+ return associations;
77
+ }
78
+ }
79
+ catch (error) {
80
+ this.logService.error(error);
81
+ }
82
+ return {};
83
+ }
84
+ saveStoredProfileAssociations(storedProfileAssociations) {
85
+ localStorage.setItem(UserDataProfilesService.PROFILE_ASSOCIATIONS_KEY, JSON.stringify(storedProfileAssociations));
86
+ }
87
+ };
88
+ BrowserUserDataProfilesService = ( __decorate([
89
+ ( __param(0, IEnvironmentService)),
90
+ ( __param(1, IFileService)),
91
+ ( __param(2, IUriIdentityService)),
92
+ ( __param(3, ILogService))
93
+ ], BrowserUserDataProfilesService));
94
+
95
+ export { BrowserUserDataProfilesService };
@@ -0,0 +1,84 @@
1
+ import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
2
+ import { Disposable, isDisposable } from 'vscode/vscode/vs/base/common/lifecycle';
3
+ import { Storage } from 'vscode/vscode/vs/base/parts/storage/common/storage';
4
+ import { AbstractStorageService } from 'vscode/vscode/vs/platform/storage/common/storage';
5
+ import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage.service';
6
+ import 'vscode/vscode/vs/base/common/event';
7
+ import 'vscode/vscode/vs/platform/userDataProfile/common/userDataProfile';
8
+
9
+ let AbstractUserDataProfileStorageService = class AbstractUserDataProfileStorageService extends Disposable {
10
+ constructor(storageService) {
11
+ super();
12
+ this.storageService = storageService;
13
+ }
14
+ async readStorageData(profile) {
15
+ return this.withProfileScopedStorageService(profile, async (storageService) => this.getItems(storageService));
16
+ }
17
+ async updateStorageData(profile, data, target) {
18
+ return this.withProfileScopedStorageService(profile, async (storageService) => this.writeItems(storageService, data, target));
19
+ }
20
+ async withProfileScopedStorageService(profile, fn) {
21
+ if (this.storageService.hasScope(profile)) {
22
+ return fn(this.storageService);
23
+ }
24
+ const storageDatabase = await this.createStorageDatabase(profile);
25
+ const storageService = ( new StorageService(storageDatabase));
26
+ try {
27
+ await storageService.initialize();
28
+ const result = await fn(storageService);
29
+ await storageService.flush();
30
+ return result;
31
+ }
32
+ finally {
33
+ storageService.dispose();
34
+ await this.closeAndDispose(storageDatabase);
35
+ }
36
+ }
37
+ getItems(storageService) {
38
+ const result = ( new Map());
39
+ const populate = (target) => {
40
+ for (const key of ( storageService.keys(0, target))) {
41
+ result.set(key, { value: storageService.get(key, 0 ), target });
42
+ }
43
+ };
44
+ populate(0 );
45
+ populate(1 );
46
+ return result;
47
+ }
48
+ writeItems(storageService, items, target) {
49
+ storageService.storeAll(( Array.from(items.entries()).map(
50
+ ([key, value]) => ({ key, value, scope: 0 , target })
51
+ )), true);
52
+ }
53
+ async closeAndDispose(storageDatabase) {
54
+ try {
55
+ await storageDatabase.close();
56
+ }
57
+ finally {
58
+ if (isDisposable(storageDatabase)) {
59
+ storageDatabase.dispose();
60
+ }
61
+ }
62
+ }
63
+ };
64
+ AbstractUserDataProfileStorageService = ( __decorate([
65
+ ( __param(0, IStorageService))
66
+ ], AbstractUserDataProfileStorageService));
67
+ class StorageService extends AbstractStorageService {
68
+ constructor(profileStorageDatabase) {
69
+ super({ flushInterval: 100 });
70
+ this.profileStorage = this._register(( new Storage(profileStorageDatabase)));
71
+ }
72
+ doInitialize() {
73
+ return this.profileStorage.init();
74
+ }
75
+ getStorage(scope) {
76
+ return scope === 0 ? this.profileStorage : undefined;
77
+ }
78
+ getLogDetails() { return undefined; }
79
+ async switchToProfile() { }
80
+ async switchToWorkspace() { }
81
+ hasScope() { return false; }
82
+ }
83
+
84
+ export { AbstractUserDataProfileStorageService };
@@ -0,0 +1,331 @@
1
+ import { deepClone, equals } from 'vscode/vscode/vs/base/common/objects';
2
+ import { semverExports } from 'vscode/external/vscode-semver/semver.js';
3
+ import { assertIsDefined } from 'vscode/vscode/vs/base/common/types';
4
+
5
+ function merge(localExtensions, remoteExtensions, lastSyncExtensions, skippedExtensions, ignoredExtensions, lastSyncBuiltinExtensions) {
6
+ const added = [];
7
+ const removed = [];
8
+ const updated = [];
9
+ if (!remoteExtensions) {
10
+ const remote = localExtensions.filter(({ identifier }) => ignoredExtensions.every(id => id.toLowerCase() !== identifier.id.toLowerCase()));
11
+ return {
12
+ local: {
13
+ added,
14
+ removed,
15
+ updated,
16
+ },
17
+ remote: remote.length > 0 ? {
18
+ added: remote,
19
+ updated: [],
20
+ removed: [],
21
+ all: remote
22
+ } : null
23
+ };
24
+ }
25
+ localExtensions = ( localExtensions.map(massageIncomingExtension));
26
+ remoteExtensions = ( remoteExtensions.map(massageIncomingExtension));
27
+ lastSyncExtensions = lastSyncExtensions ? ( lastSyncExtensions.map(massageIncomingExtension)) : null;
28
+ const uuids = ( new Map());
29
+ const addUUID = (identifier) => { if (identifier.uuid) {
30
+ uuids.set(identifier.id.toLowerCase(), identifier.uuid);
31
+ } };
32
+ localExtensions.forEach(({ identifier }) => addUUID(identifier));
33
+ remoteExtensions.forEach(({ identifier }) => addUUID(identifier));
34
+ lastSyncExtensions?.forEach(({ identifier }) => addUUID(identifier));
35
+ skippedExtensions?.forEach(({ identifier }) => addUUID(identifier));
36
+ lastSyncBuiltinExtensions?.forEach(identifier => addUUID(identifier));
37
+ const getKey = (extension) => {
38
+ const uuid = extension.identifier.uuid || uuids.get(extension.identifier.id.toLowerCase());
39
+ return uuid ? `uuid:${uuid}` : `id:${extension.identifier.id.toLowerCase()}`;
40
+ };
41
+ const addExtensionToMap = (map, extension) => {
42
+ map.set(getKey(extension), extension);
43
+ return map;
44
+ };
45
+ const localExtensionsMap = localExtensions.reduce(addExtensionToMap, ( new Map()));
46
+ const remoteExtensionsMap = remoteExtensions.reduce(addExtensionToMap, ( new Map()));
47
+ const newRemoteExtensionsMap = remoteExtensions.reduce((map, extension) => addExtensionToMap(map, deepClone(extension)), ( new Map()));
48
+ const lastSyncExtensionsMap = lastSyncExtensions ? lastSyncExtensions.reduce(addExtensionToMap, ( new Map())) : null;
49
+ const skippedExtensionsMap = skippedExtensions.reduce(addExtensionToMap, ( new Map()));
50
+ const ignoredExtensionsSet = ignoredExtensions.reduce((set, id) => {
51
+ const uuid = uuids.get(id.toLowerCase());
52
+ return set.add(uuid ? `uuid:${uuid}` : `id:${id.toLowerCase()}`);
53
+ }, ( new Set()));
54
+ const lastSyncBuiltinExtensionsSet = lastSyncBuiltinExtensions ? lastSyncBuiltinExtensions.reduce((set, { id, uuid }) => {
55
+ uuid = uuid ?? uuids.get(id.toLowerCase());
56
+ return set.add(uuid ? `uuid:${uuid}` : `id:${id.toLowerCase()}`);
57
+ }, ( new Set())) : null;
58
+ const localToRemote = compare(localExtensionsMap, remoteExtensionsMap, ignoredExtensionsSet, false);
59
+ if (localToRemote.added.size > 0 || localToRemote.removed.size > 0 || localToRemote.updated.size > 0) {
60
+ const baseToLocal = compare(lastSyncExtensionsMap, localExtensionsMap, ignoredExtensionsSet, false);
61
+ const baseToRemote = compare(lastSyncExtensionsMap, remoteExtensionsMap, ignoredExtensionsSet, true);
62
+ const merge = (key, localExtension, remoteExtension, preferred) => {
63
+ let pinned, version, preRelease;
64
+ if (localExtension.installed) {
65
+ pinned = preferred.pinned;
66
+ preRelease = preferred.preRelease;
67
+ if (pinned) {
68
+ version = preferred.version;
69
+ }
70
+ }
71
+ else {
72
+ pinned = remoteExtension.pinned;
73
+ preRelease = remoteExtension.preRelease;
74
+ if (pinned) {
75
+ version = remoteExtension.version;
76
+ }
77
+ }
78
+ if (pinned === undefined ) {
79
+ pinned = localExtension.pinned;
80
+ if (pinned) {
81
+ version = localExtension.version;
82
+ }
83
+ }
84
+ if (preRelease === undefined ) {
85
+ preRelease = localExtension.preRelease;
86
+ }
87
+ return {
88
+ ...preferred,
89
+ installed: localExtension.installed || remoteExtension.installed,
90
+ pinned,
91
+ preRelease,
92
+ version: version ?? (remoteExtension.version && (!localExtension.installed || semverExports.gt(remoteExtension.version, localExtension.version)) ? remoteExtension.version : localExtension.version),
93
+ state: mergeExtensionState(localExtension, remoteExtension, lastSyncExtensionsMap?.get(key)),
94
+ };
95
+ };
96
+ for (const key of ( baseToRemote.removed.values())) {
97
+ const localExtension = localExtensionsMap.get(key);
98
+ if (!localExtension) {
99
+ continue;
100
+ }
101
+ const baseExtension = assertIsDefined(lastSyncExtensionsMap?.get(key));
102
+ const wasAnInstalledExtensionDuringLastSync = lastSyncBuiltinExtensionsSet && !( lastSyncBuiltinExtensionsSet.has(key)) && baseExtension.installed;
103
+ if (localExtension.installed && wasAnInstalledExtensionDuringLastSync ) {
104
+ removed.push(localExtension.identifier);
105
+ }
106
+ else {
107
+ newRemoteExtensionsMap.set(key, localExtension);
108
+ }
109
+ }
110
+ for (const key of ( baseToRemote.added.values())) {
111
+ const remoteExtension = assertIsDefined(remoteExtensionsMap.get(key));
112
+ const localExtension = localExtensionsMap.get(key);
113
+ if (localExtension) {
114
+ if (( localToRemote.updated.has(key))) {
115
+ const mergedExtension = merge(key, localExtension, remoteExtension, remoteExtension);
116
+ if (!areSame(localExtension, remoteExtension, false, false)) {
117
+ updated.push(massageOutgoingExtension(mergedExtension, key));
118
+ }
119
+ newRemoteExtensionsMap.set(key, mergedExtension);
120
+ }
121
+ }
122
+ else {
123
+ if (remoteExtension.installed) {
124
+ added.push(massageOutgoingExtension(remoteExtension, key));
125
+ }
126
+ }
127
+ }
128
+ for (const key of ( baseToRemote.updated.values())) {
129
+ const remoteExtension = assertIsDefined(remoteExtensionsMap.get(key));
130
+ const baseExtension = assertIsDefined(lastSyncExtensionsMap?.get(key));
131
+ const localExtension = localExtensionsMap.get(key);
132
+ if (localExtension) {
133
+ const wasAnInstalledExtensionDuringLastSync = lastSyncBuiltinExtensionsSet && !( lastSyncBuiltinExtensionsSet.has(key)) && baseExtension.installed;
134
+ if (wasAnInstalledExtensionDuringLastSync && localExtension.installed && !remoteExtension.installed) {
135
+ removed.push(localExtension.identifier);
136
+ }
137
+ else {
138
+ const mergedExtension = merge(key, localExtension, remoteExtension, remoteExtension);
139
+ updated.push(massageOutgoingExtension(mergedExtension, key));
140
+ newRemoteExtensionsMap.set(key, mergedExtension);
141
+ }
142
+ }
143
+ else if (remoteExtension.installed) {
144
+ added.push(massageOutgoingExtension(remoteExtension, key));
145
+ }
146
+ }
147
+ for (const key of ( baseToLocal.added.values())) {
148
+ if (( baseToRemote.added.has(key))) {
149
+ continue;
150
+ }
151
+ newRemoteExtensionsMap.set(key, assertIsDefined(localExtensionsMap.get(key)));
152
+ }
153
+ for (const key of ( baseToLocal.updated.values())) {
154
+ if (( baseToRemote.removed.has(key))) {
155
+ continue;
156
+ }
157
+ if (( baseToRemote.updated.has(key))) {
158
+ continue;
159
+ }
160
+ const localExtension = assertIsDefined(localExtensionsMap.get(key));
161
+ const remoteExtension = assertIsDefined(remoteExtensionsMap.get(key));
162
+ newRemoteExtensionsMap.set(key, merge(key, localExtension, remoteExtension, localExtension));
163
+ }
164
+ for (const key of ( baseToLocal.removed.values())) {
165
+ if (( baseToRemote.updated.has(key))) {
166
+ continue;
167
+ }
168
+ if (( baseToRemote.removed.has(key))) {
169
+ continue;
170
+ }
171
+ if (( skippedExtensionsMap.has(key))) {
172
+ continue;
173
+ }
174
+ if (!assertIsDefined(remoteExtensionsMap.get(key)).installed) {
175
+ continue;
176
+ }
177
+ if (!lastSyncBuiltinExtensionsSet) {
178
+ continue;
179
+ }
180
+ if (( lastSyncBuiltinExtensionsSet.has(key)) || !assertIsDefined(lastSyncExtensionsMap?.get(key)).installed) {
181
+ continue;
182
+ }
183
+ newRemoteExtensionsMap.delete(key);
184
+ }
185
+ }
186
+ const remote = [];
187
+ const remoteChanges = compare(remoteExtensionsMap, newRemoteExtensionsMap, ( new Set()), true);
188
+ const hasRemoteChanges = remoteChanges.added.size > 0 || remoteChanges.updated.size > 0 || remoteChanges.removed.size > 0;
189
+ if (hasRemoteChanges) {
190
+ newRemoteExtensionsMap.forEach((value, key) => remote.push(massageOutgoingExtension(value, key)));
191
+ }
192
+ return {
193
+ local: { added, removed, updated },
194
+ remote: hasRemoteChanges ? {
195
+ added: ( [...remoteChanges.added].map(id => newRemoteExtensionsMap.get(id))),
196
+ updated: ( [...remoteChanges.updated].map(id => newRemoteExtensionsMap.get(id))),
197
+ removed: ( [...remoteChanges.removed].map(id => remoteExtensionsMap.get(id))),
198
+ all: remote
199
+ } : null
200
+ };
201
+ }
202
+ function compare(from, to, ignoredExtensions, checkVersionProperty) {
203
+ const fromKeys = from ? [...( from.keys())].filter(key => !( ignoredExtensions.has(key))) : [];
204
+ const toKeys = [...( to.keys())].filter(key => !( ignoredExtensions.has(key)));
205
+ const added = toKeys.filter(key => !fromKeys.includes(key)).reduce((r, key) => { r.add(key); return r; }, ( new Set()));
206
+ const removed = fromKeys.filter(key => !toKeys.includes(key)).reduce((r, key) => { r.add(key); return r; }, ( new Set()));
207
+ const updated = ( new Set());
208
+ for (const key of fromKeys) {
209
+ if (( removed.has(key))) {
210
+ continue;
211
+ }
212
+ const fromExtension = from.get(key);
213
+ const toExtension = to.get(key);
214
+ if (!toExtension || !areSame(fromExtension, toExtension, checkVersionProperty, true)) {
215
+ updated.add(key);
216
+ }
217
+ }
218
+ return { added, removed, updated };
219
+ }
220
+ function areSame(fromExtension, toExtension, checkVersionProperty, checkInstalledProperty) {
221
+ if (fromExtension.disabled !== toExtension.disabled) {
222
+ return false;
223
+ }
224
+ if (!!fromExtension.isApplicationScoped !== !!toExtension.isApplicationScoped) {
225
+ return false;
226
+ }
227
+ if (checkInstalledProperty && fromExtension.installed !== toExtension.installed) {
228
+ return false;
229
+ }
230
+ if (fromExtension.installed && toExtension.installed) {
231
+ if (fromExtension.preRelease !== toExtension.preRelease) {
232
+ return false;
233
+ }
234
+ if (fromExtension.pinned !== toExtension.pinned) {
235
+ return false;
236
+ }
237
+ if (toExtension.pinned && fromExtension.version !== toExtension.version) {
238
+ return false;
239
+ }
240
+ }
241
+ if (!isSameExtensionState(fromExtension.state, toExtension.state)) {
242
+ return false;
243
+ }
244
+ if ((checkVersionProperty && fromExtension.version !== toExtension.version)) {
245
+ return false;
246
+ }
247
+ return true;
248
+ }
249
+ function mergeExtensionState(localExtension, remoteExtension, lastSyncExtension) {
250
+ const localState = localExtension.state;
251
+ const remoteState = remoteExtension.state;
252
+ const baseState = lastSyncExtension?.state;
253
+ if (!remoteExtension.version) {
254
+ return localState;
255
+ }
256
+ if (localState && semverExports.gt(localExtension.version, remoteExtension.version)) {
257
+ return localState;
258
+ }
259
+ if (remoteState && semverExports.gt(remoteExtension.version, localExtension.version)) {
260
+ return remoteState;
261
+ }
262
+ if (!localState) {
263
+ return remoteState;
264
+ }
265
+ if (!remoteState) {
266
+ return localState;
267
+ }
268
+ const mergedState = deepClone(localState);
269
+ const baseToRemote = baseState ? compareExtensionState(baseState, remoteState) : { added: ( Object.keys(remoteState)).reduce((r, k) => { r.add(k); return r; }, ( new Set())), removed: ( new Set()), updated: ( new Set()) };
270
+ const baseToLocal = baseState ? compareExtensionState(baseState, localState) : { added: ( Object.keys(localState)).reduce((r, k) => { r.add(k); return r; }, ( new Set())), removed: ( new Set()), updated: ( new Set()) };
271
+ for (const key of [...( baseToRemote.added.values()), ...( baseToRemote.updated.values())]) {
272
+ mergedState[key] = remoteState[key];
273
+ }
274
+ for (const key of ( baseToRemote.removed.values())) {
275
+ if (!( baseToLocal.updated.has(key))) {
276
+ delete mergedState[key];
277
+ }
278
+ }
279
+ return mergedState;
280
+ }
281
+ function compareExtensionState(from, to) {
282
+ const fromKeys = ( Object.keys(from));
283
+ const toKeys = ( Object.keys(to));
284
+ const added = toKeys.filter(key => !fromKeys.includes(key)).reduce((r, key) => { r.add(key); return r; }, ( new Set()));
285
+ const removed = fromKeys.filter(key => !toKeys.includes(key)).reduce((r, key) => { r.add(key); return r; }, ( new Set()));
286
+ const updated = ( new Set());
287
+ for (const key of fromKeys) {
288
+ if (( removed.has(key))) {
289
+ continue;
290
+ }
291
+ const value1 = from[key];
292
+ const value2 = to[key];
293
+ if (!equals(value1, value2)) {
294
+ updated.add(key);
295
+ }
296
+ }
297
+ return { added, removed, updated };
298
+ }
299
+ function isSameExtensionState(a = {}, b = {}) {
300
+ const { added, removed, updated } = compareExtensionState(a, b);
301
+ return added.size === 0 && removed.size === 0 && updated.size === 0;
302
+ }
303
+ function massageIncomingExtension(extension) {
304
+ return { ...extension, ...{ disabled: !!extension.disabled, installed: !!extension.installed } };
305
+ }
306
+ function massageOutgoingExtension(extension, key) {
307
+ const massagedExtension = {
308
+ ...extension,
309
+ identifier: {
310
+ id: extension.identifier.id,
311
+ uuid: key.startsWith('uuid:') ? key.substring('uuid:'.length) : undefined
312
+ },
313
+ preRelease: !!extension.preRelease,
314
+ pinned: !!extension.pinned,
315
+ };
316
+ if (!extension.disabled) {
317
+ delete massagedExtension.disabled;
318
+ }
319
+ if (!extension.installed) {
320
+ delete massagedExtension.installed;
321
+ }
322
+ if (!extension.state) {
323
+ delete massagedExtension.state;
324
+ }
325
+ if (!extension.isApplicationScoped) {
326
+ delete massagedExtension.isApplicationScoped;
327
+ }
328
+ return massagedExtension;
329
+ }
330
+
331
+ export { merge };