@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.
- package/index.d.ts +1 -0
- package/index.js +1 -0
- package/package.json +31 -0
- package/userDataProfile.js +118 -0
- package/vscode/src/vs/platform/userDataProfile/browser/userDataProfile.js +95 -0
- package/vscode/src/vs/platform/userDataProfile/common/userDataProfileStorageService.js +84 -0
- package/vscode/src/vs/platform/userDataSync/common/extensionsMerge.js +331 -0
- package/vscode/src/vs/platform/userDataSync/common/extensionsSync.js +545 -0
- package/vscode/src/vs/platform/userDataSync/common/globalStateMerge.js +102 -0
- package/vscode/src/vs/platform/userDataSync/common/globalStateSync.js +431 -0
- package/vscode/src/vs/platform/userDataSync/common/keybindingsMerge.js +277 -0
- package/vscode/src/vs/platform/userDataSync/common/keybindingsSync.js +328 -0
- package/vscode/src/vs/platform/userDataSync/common/settingsSync.js +322 -0
- package/vscode/src/vs/platform/userDataSync/common/snippetsMerge.js +126 -0
- package/vscode/src/vs/platform/userDataSync/common/snippetsSync.js +478 -0
- package/vscode/src/vs/platform/userDataSync/common/tasksSync.js +245 -0
- package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.contribution.js +9 -0
- package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfile.js +495 -0
- package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfileActions.js +159 -0
- package/vscode/src/vs/workbench/contrib/userDataProfile/browser/userDataProfilePreview.js +24 -0
- package/vscode/src/vs/workbench/services/userData/browser/userDataInit.js +62 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/extensionsResource.js +328 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/globalStateResource.js +144 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/keybindingsResource.js +119 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/media/userDataProfileView.css.js +6 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/settingsResource.js +140 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/snippetsResource.js +155 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/tasksResource.js +118 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileImportExportService.js +1453 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileInit.js +151 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileManagement.js +180 -0
- package/vscode/src/vs/workbench/services/userDataProfile/browser/userDataProfileStorageService.js +39 -0
- package/vscode/src/vs/workbench/services/userDataSync/browser/userDataSyncInit.js +448 -0
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6.js';
|
|
2
|
+
import { VSBuffer } from 'vscode/vscode/vs/base/common/buffer';
|
|
3
|
+
import { Event } from 'vscode/vscode/vs/base/common/event';
|
|
4
|
+
import { localizeWithPath } from 'vscode/vscode/vs/nls';
|
|
5
|
+
import { IConfigurationService } from 'vscode/vscode/vs/platform/configuration/common/configuration.service';
|
|
6
|
+
import { ConfigurationModelParser } from 'vscode/vscode/vs/platform/configuration/common/configurationModels';
|
|
7
|
+
import { IEnvironmentService } from 'vscode/vscode/vs/platform/environment/common/environment.service';
|
|
8
|
+
import { IExtensionManagementService } from 'vscode/vscode/vs/platform/extensionManagement/common/extensionManagement.service';
|
|
9
|
+
import { IFileService } from 'vscode/vscode/vs/platform/files/common/files.service';
|
|
10
|
+
import { IStorageService } from 'vscode/vscode/vs/platform/storage/common/storage.service';
|
|
11
|
+
import { ITelemetryService } from 'vscode/vscode/vs/platform/telemetry/common/telemetry.service';
|
|
12
|
+
import { IUriIdentityService } from 'vscode/vscode/vs/platform/uriIdentity/common/uriIdentity.service';
|
|
13
|
+
import { IUserDataProfilesService } from 'vscode/vscode/vs/platform/userDataProfile/common/userDataProfile.service';
|
|
14
|
+
import { AbstractJsonFileSynchroniser, AbstractInitializer } from 'vscode/vscode/vs/platform/userDataSync/common/abstractSynchronizer';
|
|
15
|
+
import { merge, updateIgnoredSettings, isEmpty, getIgnoredSettings } from 'vscode/vscode/vs/platform/userDataSync/common/settingsMerge';
|
|
16
|
+
import { USER_DATA_SYNC_SCHEME, USER_DATA_SYNC_CONFIGURATION_SCOPE, UserDataSyncError } from 'vscode/vscode/vs/platform/userDataSync/common/userDataSync';
|
|
17
|
+
import { IUserDataSyncStoreService, IUserDataSyncLocalStoreService, IUserDataSyncLogService, IUserDataSyncUtilService, IUserDataSyncEnablementService } from 'vscode/vscode/vs/platform/userDataSync/common/userDataSync.service';
|
|
18
|
+
|
|
19
|
+
const _moduleId = "vs/platform/userDataSync/common/settingsSync";
|
|
20
|
+
function isSettingsSyncContent(thing) {
|
|
21
|
+
return thing
|
|
22
|
+
&& (thing.settings && typeof thing.settings === 'string')
|
|
23
|
+
&& ( Object.keys(thing)).length === 1;
|
|
24
|
+
}
|
|
25
|
+
function parseSettingsSyncContent(syncContent) {
|
|
26
|
+
const parsed = JSON.parse(syncContent);
|
|
27
|
+
return isSettingsSyncContent(parsed) ? parsed : { settings: syncContent };
|
|
28
|
+
}
|
|
29
|
+
let SettingsSynchroniser = class SettingsSynchroniser extends AbstractJsonFileSynchroniser {
|
|
30
|
+
constructor(profile, collection, fileService, environmentService, storageService, userDataSyncStoreService, userDataSyncLocalStoreService, logService, userDataSyncUtilService, configurationService, userDataSyncEnablementService, telemetryService, extensionManagementService, uriIdentityService) {
|
|
31
|
+
super(profile.settingsResource, { syncResource: "settings" , profile }, collection, fileService, environmentService, storageService, userDataSyncStoreService, userDataSyncLocalStoreService, userDataSyncEnablementService, telemetryService, logService, userDataSyncUtilService, configurationService, uriIdentityService);
|
|
32
|
+
this.extensionManagementService = extensionManagementService;
|
|
33
|
+
this.version = 2;
|
|
34
|
+
this.previewResource = this.extUri.joinPath(this.syncPreviewFolder, 'settings.json');
|
|
35
|
+
this.baseResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'base' });
|
|
36
|
+
this.localResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'local' });
|
|
37
|
+
this.remoteResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'remote' });
|
|
38
|
+
this.acceptedResource = this.previewResource.with({ scheme: USER_DATA_SYNC_SCHEME, authority: 'accepted' });
|
|
39
|
+
this._defaultIgnoredSettings = undefined;
|
|
40
|
+
}
|
|
41
|
+
async getRemoteUserDataSyncConfiguration(manifest) {
|
|
42
|
+
const lastSyncUserData = await this.getLastSyncUserData();
|
|
43
|
+
const remoteUserData = await this.getLatestRemoteUserData(manifest, lastSyncUserData);
|
|
44
|
+
const remoteSettingsSyncContent = this.getSettingsSyncContent(remoteUserData);
|
|
45
|
+
const parser = ( new ConfigurationModelParser(USER_DATA_SYNC_CONFIGURATION_SCOPE, this.logService));
|
|
46
|
+
if (remoteSettingsSyncContent?.settings) {
|
|
47
|
+
parser.parse(remoteSettingsSyncContent.settings);
|
|
48
|
+
}
|
|
49
|
+
return parser.configurationModel.getValue(USER_DATA_SYNC_CONFIGURATION_SCOPE) || {};
|
|
50
|
+
}
|
|
51
|
+
async generateSyncPreview(remoteUserData, lastSyncUserData, isRemoteDataFromCurrentMachine) {
|
|
52
|
+
const fileContent = await this.getLocalFileContent();
|
|
53
|
+
const formattingOptions = await this.getFormattingOptions();
|
|
54
|
+
const remoteSettingsSyncContent = this.getSettingsSyncContent(remoteUserData);
|
|
55
|
+
lastSyncUserData = lastSyncUserData === null && isRemoteDataFromCurrentMachine ? remoteUserData : lastSyncUserData;
|
|
56
|
+
const lastSettingsSyncContent = lastSyncUserData ? this.getSettingsSyncContent(lastSyncUserData) : null;
|
|
57
|
+
const ignoredSettings = await this.getIgnoredSettings();
|
|
58
|
+
let mergedContent = null;
|
|
59
|
+
let hasLocalChanged = false;
|
|
60
|
+
let hasRemoteChanged = false;
|
|
61
|
+
let hasConflicts = false;
|
|
62
|
+
if (remoteSettingsSyncContent) {
|
|
63
|
+
let localContent = fileContent ? ( fileContent.value.toString()).trim() : '{}';
|
|
64
|
+
localContent = localContent || '{}';
|
|
65
|
+
this.validateContent(localContent);
|
|
66
|
+
this.logService.trace(`${this.syncResourceLogLabel}: Merging remote settings with local settings...`);
|
|
67
|
+
const result = merge(localContent, remoteSettingsSyncContent.settings, lastSettingsSyncContent ? lastSettingsSyncContent.settings : null, ignoredSettings, [], formattingOptions);
|
|
68
|
+
mergedContent = result.localContent || result.remoteContent;
|
|
69
|
+
hasLocalChanged = result.localContent !== null;
|
|
70
|
+
hasRemoteChanged = result.remoteContent !== null;
|
|
71
|
+
hasConflicts = result.hasConflicts;
|
|
72
|
+
}
|
|
73
|
+
else if (fileContent) {
|
|
74
|
+
this.logService.trace(`${this.syncResourceLogLabel}: Remote settings does not exist. Synchronizing settings for the first time.`);
|
|
75
|
+
mergedContent = ( fileContent.value.toString()).trim() || '{}';
|
|
76
|
+
this.validateContent(mergedContent);
|
|
77
|
+
hasRemoteChanged = true;
|
|
78
|
+
}
|
|
79
|
+
const localContent = fileContent ? ( fileContent.value.toString()) : null;
|
|
80
|
+
const baseContent = lastSettingsSyncContent?.settings ?? null;
|
|
81
|
+
const previewResult = {
|
|
82
|
+
content: hasConflicts ? baseContent : mergedContent,
|
|
83
|
+
localChange: hasLocalChanged ? 2 : 0 ,
|
|
84
|
+
remoteChange: hasRemoteChanged ? 2 : 0 ,
|
|
85
|
+
hasConflicts
|
|
86
|
+
};
|
|
87
|
+
return [{
|
|
88
|
+
fileContent,
|
|
89
|
+
baseResource: this.baseResource,
|
|
90
|
+
baseContent,
|
|
91
|
+
localResource: this.localResource,
|
|
92
|
+
localContent,
|
|
93
|
+
localChange: previewResult.localChange,
|
|
94
|
+
remoteResource: this.remoteResource,
|
|
95
|
+
remoteContent: remoteSettingsSyncContent ? remoteSettingsSyncContent.settings : null,
|
|
96
|
+
remoteChange: previewResult.remoteChange,
|
|
97
|
+
previewResource: this.previewResource,
|
|
98
|
+
previewResult,
|
|
99
|
+
acceptedResource: this.acceptedResource,
|
|
100
|
+
}];
|
|
101
|
+
}
|
|
102
|
+
async hasRemoteChanged(lastSyncUserData) {
|
|
103
|
+
const lastSettingsSyncContent = this.getSettingsSyncContent(lastSyncUserData);
|
|
104
|
+
if (lastSettingsSyncContent === null) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
const fileContent = await this.getLocalFileContent();
|
|
108
|
+
const localContent = fileContent ? ( fileContent.value.toString()).trim() : '';
|
|
109
|
+
const ignoredSettings = await this.getIgnoredSettings();
|
|
110
|
+
const formattingOptions = await this.getFormattingOptions();
|
|
111
|
+
const result = merge(localContent || '{}', lastSettingsSyncContent.settings, lastSettingsSyncContent.settings, ignoredSettings, [], formattingOptions);
|
|
112
|
+
return result.remoteContent !== null;
|
|
113
|
+
}
|
|
114
|
+
async getMergeResult(resourcePreview, token) {
|
|
115
|
+
const formatUtils = await this.getFormattingOptions();
|
|
116
|
+
const ignoredSettings = await this.getIgnoredSettings();
|
|
117
|
+
return {
|
|
118
|
+
...resourcePreview.previewResult,
|
|
119
|
+
content: resourcePreview.previewResult.content ? updateIgnoredSettings(resourcePreview.previewResult.content, '{}', ignoredSettings, formatUtils) : null
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async getAcceptResult(resourcePreview, resource, content, token) {
|
|
123
|
+
const formattingOptions = await this.getFormattingOptions();
|
|
124
|
+
const ignoredSettings = await this.getIgnoredSettings();
|
|
125
|
+
if (this.extUri.isEqual(resource, this.localResource)) {
|
|
126
|
+
return {
|
|
127
|
+
content: resourcePreview.fileContent ? updateIgnoredSettings(( resourcePreview.fileContent.value.toString()), '{}', ignoredSettings, formattingOptions) : null,
|
|
128
|
+
localChange: 0 ,
|
|
129
|
+
remoteChange: 2 ,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (this.extUri.isEqual(resource, this.remoteResource)) {
|
|
133
|
+
return {
|
|
134
|
+
content: resourcePreview.remoteContent !== null ? updateIgnoredSettings(resourcePreview.remoteContent, resourcePreview.fileContent ? ( resourcePreview.fileContent.value.toString()) : '{}', ignoredSettings, formattingOptions) : null,
|
|
135
|
+
localChange: 2 ,
|
|
136
|
+
remoteChange: 0 ,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
if (this.extUri.isEqual(resource, this.previewResource)) {
|
|
140
|
+
if (content === undefined) {
|
|
141
|
+
return {
|
|
142
|
+
content: resourcePreview.previewResult.content,
|
|
143
|
+
localChange: resourcePreview.previewResult.localChange,
|
|
144
|
+
remoteChange: resourcePreview.previewResult.remoteChange,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
return {
|
|
149
|
+
content: content !== null ? updateIgnoredSettings(content, resourcePreview.fileContent ? ( resourcePreview.fileContent.value.toString()) : '{}', ignoredSettings, formattingOptions) : null,
|
|
150
|
+
localChange: 2 ,
|
|
151
|
+
remoteChange: 2 ,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
throw ( new Error(`Invalid Resource: ${( resource.toString())}`));
|
|
156
|
+
}
|
|
157
|
+
async applyResult(remoteUserData, lastSyncUserData, resourcePreviews, force) {
|
|
158
|
+
const { fileContent } = resourcePreviews[0][0];
|
|
159
|
+
let { content, localChange, remoteChange } = resourcePreviews[0][1];
|
|
160
|
+
if (localChange === 0 && remoteChange === 0 ) {
|
|
161
|
+
this.logService.info(`${this.syncResourceLogLabel}: No changes found during synchronizing settings.`);
|
|
162
|
+
}
|
|
163
|
+
content = content ? content.trim() : '{}';
|
|
164
|
+
content = content || '{}';
|
|
165
|
+
this.validateContent(content);
|
|
166
|
+
if (localChange !== 0 ) {
|
|
167
|
+
this.logService.trace(`${this.syncResourceLogLabel}: Updating local settings...`);
|
|
168
|
+
if (fileContent) {
|
|
169
|
+
await this.backupLocal(JSON.stringify(this.toSettingsSyncContent(( fileContent.value.toString()))));
|
|
170
|
+
}
|
|
171
|
+
await this.updateLocalFileContent(content, fileContent, force);
|
|
172
|
+
await this.configurationService.reloadConfiguration(3 );
|
|
173
|
+
this.logService.info(`${this.syncResourceLogLabel}: Updated local settings`);
|
|
174
|
+
}
|
|
175
|
+
if (remoteChange !== 0 ) {
|
|
176
|
+
const formatUtils = await this.getFormattingOptions();
|
|
177
|
+
const remoteSettingsSyncContent = this.getSettingsSyncContent(remoteUserData);
|
|
178
|
+
const ignoredSettings = await this.getIgnoredSettings(content);
|
|
179
|
+
content = updateIgnoredSettings(content, remoteSettingsSyncContent ? remoteSettingsSyncContent.settings : '{}', ignoredSettings, formatUtils);
|
|
180
|
+
this.logService.trace(`${this.syncResourceLogLabel}: Updating remote settings...`);
|
|
181
|
+
remoteUserData = await this.updateRemoteUserData(JSON.stringify(this.toSettingsSyncContent(content)), force ? null : remoteUserData.ref);
|
|
182
|
+
this.logService.info(`${this.syncResourceLogLabel}: Updated remote settings`);
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
await this.fileService.del(this.previewResource);
|
|
186
|
+
}
|
|
187
|
+
catch (e) { }
|
|
188
|
+
if (lastSyncUserData?.ref !== remoteUserData.ref) {
|
|
189
|
+
this.logService.trace(`${this.syncResourceLogLabel}: Updating last synchronized settings...`);
|
|
190
|
+
await this.updateLastSyncUserData(remoteUserData);
|
|
191
|
+
this.logService.info(`${this.syncResourceLogLabel}: Updated last synchronized settings`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async hasLocalData() {
|
|
195
|
+
try {
|
|
196
|
+
const localFileContent = await this.getLocalFileContent();
|
|
197
|
+
if (localFileContent) {
|
|
198
|
+
return !isEmpty(( localFileContent.value.toString()));
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
if (error.fileOperationResult !== 1 ) {
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return false;
|
|
207
|
+
}
|
|
208
|
+
async resolveContent(uri) {
|
|
209
|
+
if (this.extUri.isEqual(this.remoteResource, uri)
|
|
210
|
+
|| this.extUri.isEqual(this.localResource, uri)
|
|
211
|
+
|| this.extUri.isEqual(this.acceptedResource, uri)
|
|
212
|
+
|| this.extUri.isEqual(this.baseResource, uri)) {
|
|
213
|
+
return this.resolvePreviewContent(uri);
|
|
214
|
+
}
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
async resolvePreviewContent(resource) {
|
|
218
|
+
let content = await super.resolvePreviewContent(resource);
|
|
219
|
+
if (content) {
|
|
220
|
+
const formatUtils = await this.getFormattingOptions();
|
|
221
|
+
const ignoredSettings = await this.getIgnoredSettings();
|
|
222
|
+
content = updateIgnoredSettings(content, '{}', ignoredSettings, formatUtils);
|
|
223
|
+
}
|
|
224
|
+
return content;
|
|
225
|
+
}
|
|
226
|
+
getSettingsSyncContent(remoteUserData) {
|
|
227
|
+
return remoteUserData.syncData ? this.parseSettingsSyncContent(remoteUserData.syncData.content) : null;
|
|
228
|
+
}
|
|
229
|
+
parseSettingsSyncContent(syncContent) {
|
|
230
|
+
try {
|
|
231
|
+
return parseSettingsSyncContent(syncContent);
|
|
232
|
+
}
|
|
233
|
+
catch (e) {
|
|
234
|
+
this.logService.error(e);
|
|
235
|
+
}
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
toSettingsSyncContent(settings) {
|
|
239
|
+
return { settings };
|
|
240
|
+
}
|
|
241
|
+
async getIgnoredSettings(content) {
|
|
242
|
+
if (!this._defaultIgnoredSettings) {
|
|
243
|
+
this._defaultIgnoredSettings = this.userDataSyncUtilService.resolveDefaultIgnoredSettings();
|
|
244
|
+
const disposable = this._register(Event.any(Event.filter(this.extensionManagementService.onDidInstallExtensions, (e => ( e.some(({ local }) => !!local)))), Event.filter(this.extensionManagementService.onDidUninstallExtension, (e => !e.error)))(() => {
|
|
245
|
+
disposable.dispose();
|
|
246
|
+
this._defaultIgnoredSettings = undefined;
|
|
247
|
+
}));
|
|
248
|
+
}
|
|
249
|
+
const defaultIgnoredSettings = await this._defaultIgnoredSettings;
|
|
250
|
+
return getIgnoredSettings(defaultIgnoredSettings, this.configurationService, content);
|
|
251
|
+
}
|
|
252
|
+
validateContent(content) {
|
|
253
|
+
if (this.hasErrors(content, false)) {
|
|
254
|
+
throw ( new UserDataSyncError(localizeWithPath(
|
|
255
|
+
_moduleId,
|
|
256
|
+
0,
|
|
257
|
+
"Unable to sync settings as there are errors/warning in settings file."
|
|
258
|
+
), "LocalInvalidContent" , this.resource));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
SettingsSynchroniser = ( __decorate([
|
|
263
|
+
( __param(2, IFileService)),
|
|
264
|
+
( __param(3, IEnvironmentService)),
|
|
265
|
+
( __param(4, IStorageService)),
|
|
266
|
+
( __param(5, IUserDataSyncStoreService)),
|
|
267
|
+
( __param(6, IUserDataSyncLocalStoreService)),
|
|
268
|
+
( __param(7, IUserDataSyncLogService)),
|
|
269
|
+
( __param(8, IUserDataSyncUtilService)),
|
|
270
|
+
( __param(9, IConfigurationService)),
|
|
271
|
+
( __param(10, IUserDataSyncEnablementService)),
|
|
272
|
+
( __param(11, ITelemetryService)),
|
|
273
|
+
( __param(12, IExtensionManagementService)),
|
|
274
|
+
( __param(13, IUriIdentityService))
|
|
275
|
+
], SettingsSynchroniser));
|
|
276
|
+
let SettingsInitializer = class SettingsInitializer extends AbstractInitializer {
|
|
277
|
+
constructor(fileService, userDataProfilesService, environmentService, logService, storageService, uriIdentityService) {
|
|
278
|
+
super("settings" , userDataProfilesService, environmentService, logService, fileService, storageService, uriIdentityService);
|
|
279
|
+
}
|
|
280
|
+
async doInitialize(remoteUserData) {
|
|
281
|
+
const settingsSyncContent = remoteUserData.syncData ? this.parseSettingsSyncContent(remoteUserData.syncData.content) : null;
|
|
282
|
+
if (!settingsSyncContent) {
|
|
283
|
+
this.logService.info('Skipping initializing settings because remote settings does not exist.');
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const isEmpty = await this.isEmpty();
|
|
287
|
+
if (!isEmpty) {
|
|
288
|
+
this.logService.info('Skipping initializing settings because local settings exist.');
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
await this.fileService.writeFile(this.userDataProfilesService.defaultProfile.settingsResource, VSBuffer.fromString(settingsSyncContent.settings));
|
|
292
|
+
await this.updateLastSyncUserData(remoteUserData);
|
|
293
|
+
}
|
|
294
|
+
async isEmpty() {
|
|
295
|
+
try {
|
|
296
|
+
const fileContent = await this.fileService.readFile(this.userDataProfilesService.defaultProfile.settingsResource);
|
|
297
|
+
return isEmpty(( fileContent.value.toString()).trim());
|
|
298
|
+
}
|
|
299
|
+
catch (error) {
|
|
300
|
+
return error.fileOperationResult === 1 ;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
parseSettingsSyncContent(syncContent) {
|
|
304
|
+
try {
|
|
305
|
+
return parseSettingsSyncContent(syncContent);
|
|
306
|
+
}
|
|
307
|
+
catch (e) {
|
|
308
|
+
this.logService.error(e);
|
|
309
|
+
}
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
SettingsInitializer = ( __decorate([
|
|
314
|
+
( __param(0, IFileService)),
|
|
315
|
+
( __param(1, IUserDataProfilesService)),
|
|
316
|
+
( __param(2, IEnvironmentService)),
|
|
317
|
+
( __param(3, IUserDataSyncLogService)),
|
|
318
|
+
( __param(4, IStorageService)),
|
|
319
|
+
( __param(5, IUriIdentityService))
|
|
320
|
+
], SettingsInitializer));
|
|
321
|
+
|
|
322
|
+
export { SettingsInitializer, SettingsSynchroniser, parseSettingsSyncContent };
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
function merge(local, remote, base) {
|
|
2
|
+
const localAdded = {};
|
|
3
|
+
const localUpdated = {};
|
|
4
|
+
const localRemoved = ( new Set());
|
|
5
|
+
if (!remote) {
|
|
6
|
+
return {
|
|
7
|
+
local: { added: localAdded, updated: localUpdated, removed: [...( localRemoved.values())] },
|
|
8
|
+
remote: { added: local, updated: {}, removed: [] },
|
|
9
|
+
conflicts: []
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
const localToRemote = compare(local, remote);
|
|
13
|
+
if (localToRemote.added.size === 0 && localToRemote.removed.size === 0 && localToRemote.updated.size === 0) {
|
|
14
|
+
return {
|
|
15
|
+
local: { added: localAdded, updated: localUpdated, removed: [...( localRemoved.values())] },
|
|
16
|
+
remote: { added: {}, updated: {}, removed: [] },
|
|
17
|
+
conflicts: []
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
const baseToLocal = compare(base, local);
|
|
21
|
+
const baseToRemote = compare(base, remote);
|
|
22
|
+
const remoteAdded = {};
|
|
23
|
+
const remoteUpdated = {};
|
|
24
|
+
const remoteRemoved = ( new Set());
|
|
25
|
+
const conflicts = ( new Set());
|
|
26
|
+
for (const key of ( baseToLocal.removed.values())) {
|
|
27
|
+
if (( baseToRemote.updated.has(key))) {
|
|
28
|
+
localAdded[key] = remote[key];
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
remoteRemoved.add(key);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
for (const key of ( baseToRemote.removed.values())) {
|
|
35
|
+
if (( conflicts.has(key))) {
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (( baseToLocal.updated.has(key))) {
|
|
39
|
+
conflicts.add(key);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
localRemoved.add(key);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
for (const key of ( baseToLocal.updated.values())) {
|
|
46
|
+
if (( conflicts.has(key))) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (( baseToRemote.updated.has(key))) {
|
|
50
|
+
if (( localToRemote.updated.has(key))) {
|
|
51
|
+
conflicts.add(key);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
remoteUpdated[key] = local[key];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
for (const key of ( baseToRemote.updated.values())) {
|
|
59
|
+
if (( conflicts.has(key))) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
if (( baseToLocal.updated.has(key))) {
|
|
63
|
+
if (( localToRemote.updated.has(key))) {
|
|
64
|
+
conflicts.add(key);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else if (local[key] !== undefined) {
|
|
68
|
+
localUpdated[key] = remote[key];
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const key of ( baseToLocal.added.values())) {
|
|
72
|
+
if (( conflicts.has(key))) {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (( baseToRemote.added.has(key))) {
|
|
76
|
+
if (( localToRemote.updated.has(key))) {
|
|
77
|
+
conflicts.add(key);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
remoteAdded[key] = local[key];
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
for (const key of ( baseToRemote.added.values())) {
|
|
85
|
+
if (( conflicts.has(key))) {
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
88
|
+
if (( baseToLocal.added.has(key))) {
|
|
89
|
+
if (( localToRemote.updated.has(key))) {
|
|
90
|
+
conflicts.add(key);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
localAdded[key] = remote[key];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return {
|
|
98
|
+
local: { added: localAdded, removed: [...( localRemoved.values())], updated: localUpdated },
|
|
99
|
+
remote: { added: remoteAdded, removed: [...( remoteRemoved.values())], updated: remoteUpdated },
|
|
100
|
+
conflicts: [...( conflicts.values())],
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function compare(from, to) {
|
|
104
|
+
const fromKeys = from ? ( Object.keys(from)) : [];
|
|
105
|
+
const toKeys = to ? ( Object.keys(to)) : [];
|
|
106
|
+
const added = toKeys.filter(key => !fromKeys.includes(key)).reduce((r, key) => { r.add(key); return r; }, ( new Set()));
|
|
107
|
+
const removed = fromKeys.filter(key => !toKeys.includes(key)).reduce((r, key) => { r.add(key); return r; }, ( new Set()));
|
|
108
|
+
const updated = ( new Set());
|
|
109
|
+
for (const key of fromKeys) {
|
|
110
|
+
if (( removed.has(key))) {
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
const fromSnippet = from[key];
|
|
114
|
+
const toSnippet = to[key];
|
|
115
|
+
if (fromSnippet !== toSnippet) {
|
|
116
|
+
updated.add(key);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return { added, removed, updated };
|
|
120
|
+
}
|
|
121
|
+
function areSame(a, b) {
|
|
122
|
+
const { added, removed, updated } = compare(a, b);
|
|
123
|
+
return added.size === 0 && removed.size === 0 && updated.size === 0;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export { areSame, merge };
|