@codingame/monaco-vscode-files-service-override 11.1.2 → 12.0.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 +230 -2
- package/index.js +860 -4
- package/package.json +31 -7
- package/vscode/src/vs/platform/files/browser/indexedDBFileSystemProvider.d.ts +68 -0
- package/vscode/src/vs/platform/files/browser/indexedDBFileSystemProvider.js +43 -44
- package/vscode/src/vs/platform/files/common/fileService.d.ts +113 -0
- package/vscode/src/vs/platform/files/common/fileService.js +157 -176
- package/vscode/src/vs/platform/files/common/io.d.ts +10 -0
- package/vscode/src/vs/platform/files/common/io.js +2 -1
- package/vscode/src/vs/workbench/services/files/browser/elevatedFileService.d.ts +9 -0
- package/vscode/src/vs/workbench/services/files/browser/elevatedFileService.js +2 -0
- package/vscode/src/vs/workbench/services/textfile/browser/browserTextFileService.d.ts +24 -0
- package/vscode/src/vs/workbench/services/textfile/browser/browserTextFileService.js +5 -2
- package/vscode/src/vs/workbench/services/textfile/browser/textFileService.d.ts +111 -0
- package/vscode/src/vs/workbench/services/textfile/browser/textFileService.js +55 -57
- package/vscode/src/vs/workbench/services/textfile/common/textFileEditorModelManager.d.ts +76 -0
- package/vscode/src/vs/workbench/services/textfile/common/textFileEditorModelManager.js +45 -45
- package/vscode/src/vs/workbench/services/textfile/common/textFileSaveParticipant.d.ts +15 -0
- package/vscode/src/vs/workbench/services/textfile/common/textFileSaveParticipant.js +13 -11
- package/files.js +0 -859
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
|
|
2
|
+
import { __decorate, __param } from 'vscode/external/tslib/tslib.es6';
|
|
2
3
|
import { coalesce } from 'vscode/vscode/vs/base/common/arrays';
|
|
3
4
|
import { ResourceQueue, Promises } from 'vscode/vscode/vs/base/common/async';
|
|
4
5
|
import { VSBuffer, bufferToReadable, streamToBuffer, newWriteableBufferStream, bufferedStreamToBuffer, readableToBuffer } from 'vscode/vscode/vs/base/common/buffer';
|
|
@@ -13,7 +14,7 @@ import { mark } from 'vscode/vscode/vs/base/common/performance';
|
|
|
13
14
|
import { isAbsolutePath, extUri, extUriIgnorePathCase } from 'vscode/vscode/vs/base/common/resources';
|
|
14
15
|
import { isReadableStream, peekStream, peekReadable, consumeStream, transform, newWriteableStream, isReadableBufferedStream, listenStream } from 'vscode/vscode/vs/base/common/stream';
|
|
15
16
|
import { localize } from 'vscode/vscode/vs/nls';
|
|
16
|
-
import { FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, FileChangesEvent, FileOperationError, hasOpenReadWriteCloseCapability, hasReadWriteCapability, hasFileReadStreamCapability, ensureFileSystemProviderError, FilePermission, etag, FileOperationEvent, hasFileAtomicWriteCapability, toFileOperationResult, ETAG_DISABLED, hasFileAtomicReadCapability, NotModifiedSinceFileOperationError, TooLargeFileOperationError, hasFileFolderCopyCapability, hasFileAtomicDeleteCapability, hasFileCloneCapability } from 'vscode/vscode/vs/platform/files/common/files';
|
|
17
|
+
import { FileType, toFileSystemProviderErrorCode, FileSystemProviderErrorCode, FileChangesEvent, FileOperationError, FileOperationResult, hasOpenReadWriteCloseCapability, hasReadWriteCapability, hasFileReadStreamCapability, ensureFileSystemProviderError, FilePermission, FileSystemProviderCapabilities, etag, FileOperationEvent, FileOperation, hasFileAtomicWriteCapability, toFileOperationResult, ETAG_DISABLED, hasFileAtomicReadCapability, NotModifiedSinceFileOperationError, TooLargeFileOperationError, hasFileFolderCopyCapability, hasFileAtomicDeleteCapability, hasFileCloneCapability } from 'vscode/vscode/vs/platform/files/common/files';
|
|
17
18
|
import { readFileIntoStream } from './io.js';
|
|
18
19
|
import { ILogService } from 'vscode/vscode/vs/platform/log/common/log.service';
|
|
19
20
|
import { ErrorNoTelemetry } from 'vscode/vscode/vs/base/common/errors';
|
|
@@ -23,9 +24,7 @@ function resourceForError(resource) {
|
|
|
23
24
|
if (resource.scheme === Schemas.file) {
|
|
24
25
|
return resource.fsPath;
|
|
25
26
|
}
|
|
26
|
-
return (
|
|
27
|
-
(resource.toString(true))
|
|
28
|
-
);
|
|
27
|
+
return ( resource.toString(true));
|
|
29
28
|
}
|
|
30
29
|
async function mkdirp(providerExtUri, provider, directory) {
|
|
31
30
|
const directoriesToCreate = [];
|
|
@@ -33,8 +32,8 @@ async function mkdirp(providerExtUri, provider, directory) {
|
|
|
33
32
|
try {
|
|
34
33
|
const stat = await provider.stat(directory);
|
|
35
34
|
if ((stat.type & FileType.Directory) === 0) {
|
|
36
|
-
throw (
|
|
37
|
-
|
|
35
|
+
throw ( new Error(( localize(
|
|
36
|
+
1747,
|
|
38
37
|
"Unable to create folder '{0}' that already exists but is not a directory",
|
|
39
38
|
resourceForError(directory)
|
|
40
39
|
))));
|
|
@@ -67,40 +66,40 @@ let FileService = class FileService extends Disposable {
|
|
|
67
66
|
super();
|
|
68
67
|
this.logService = logService;
|
|
69
68
|
this.BUFFER_SIZE = 256 * 1024;
|
|
70
|
-
this._onDidChangeFileSystemProviderRegistrations = this._register((
|
|
69
|
+
this._onDidChangeFileSystemProviderRegistrations = this._register(( new Emitter()));
|
|
71
70
|
this.onDidChangeFileSystemProviderRegistrations = this._onDidChangeFileSystemProviderRegistrations.event;
|
|
72
|
-
this._onWillActivateFileSystemProvider = this._register((
|
|
71
|
+
this._onWillActivateFileSystemProvider = this._register(( new Emitter()));
|
|
73
72
|
this.onWillActivateFileSystemProvider = this._onWillActivateFileSystemProvider.event;
|
|
74
|
-
this._onDidChangeFileSystemProviderCapabilities = this._register((
|
|
73
|
+
this._onDidChangeFileSystemProviderCapabilities = this._register(( new Emitter()));
|
|
75
74
|
this.onDidChangeFileSystemProviderCapabilities = this._onDidChangeFileSystemProviderCapabilities.event;
|
|
76
|
-
this.provider = (
|
|
77
|
-
this._onDidRunOperation = this._register((
|
|
75
|
+
this.provider = ( new Map());
|
|
76
|
+
this._onDidRunOperation = this._register(( new Emitter()));
|
|
78
77
|
this.onDidRunOperation = this._onDidRunOperation.event;
|
|
79
|
-
this.internalOnDidFilesChange = this._register((
|
|
80
|
-
this._onDidUncorrelatedFilesChange = this._register((
|
|
78
|
+
this.internalOnDidFilesChange = this._register(( new Emitter()));
|
|
79
|
+
this._onDidUncorrelatedFilesChange = this._register(( new Emitter()));
|
|
81
80
|
this.onDidFilesChange = this._onDidUncorrelatedFilesChange.event;
|
|
82
|
-
this._onDidWatchError = this._register((
|
|
81
|
+
this._onDidWatchError = this._register(( new Emitter()));
|
|
83
82
|
this.onDidWatchError = this._onDidWatchError.event;
|
|
84
|
-
this.activeWatchers = (
|
|
85
|
-
this.writeQueue = this._register((
|
|
83
|
+
this.activeWatchers = ( new Map());
|
|
84
|
+
this.writeQueue = this._register(( new ResourceQueue()));
|
|
86
85
|
}
|
|
87
86
|
registerProvider(scheme, provider) {
|
|
88
|
-
if ((
|
|
89
|
-
throw (
|
|
87
|
+
if (( this.provider.has(scheme))) {
|
|
88
|
+
throw ( new Error(`A filesystem provider for the scheme '${scheme}' is already registered.`));
|
|
90
89
|
}
|
|
91
90
|
mark(`code/registerFilesystem/${scheme}`);
|
|
92
|
-
const providerDisposables = (
|
|
91
|
+
const providerDisposables = ( new DisposableStore());
|
|
93
92
|
this.provider.set(scheme, provider);
|
|
94
93
|
this._onDidChangeFileSystemProviderRegistrations.fire({ added: true, scheme, provider });
|
|
95
94
|
providerDisposables.add(provider.onDidChangeFile(changes => {
|
|
96
|
-
const event = (
|
|
95
|
+
const event = ( new FileChangesEvent(changes, !this.isPathCaseSensitive(provider)));
|
|
97
96
|
this.internalOnDidFilesChange.fire(event);
|
|
98
97
|
if (!event.hasCorrelation()) {
|
|
99
98
|
this._onDidUncorrelatedFilesChange.fire(event);
|
|
100
99
|
}
|
|
101
100
|
}));
|
|
102
101
|
if (typeof provider.onDidWatchError === 'function') {
|
|
103
|
-
providerDisposables.add(provider.onDidWatchError(error => this._onDidWatchError.fire((
|
|
102
|
+
providerDisposables.add(provider.onDidWatchError(error => this._onDidWatchError.fire(( new Error(error)))));
|
|
104
103
|
}
|
|
105
104
|
providerDisposables.add(provider.onDidChangeCapabilities(() => this._onDidChangeFileSystemProviderCapabilities.fire({ provider, scheme })));
|
|
106
105
|
return toDisposable(() => {
|
|
@@ -120,7 +119,7 @@ let FileService = class FileService extends Disposable {
|
|
|
120
119
|
joiners.push(promise);
|
|
121
120
|
},
|
|
122
121
|
});
|
|
123
|
-
if ((
|
|
122
|
+
if (( this.provider.has(scheme))) {
|
|
124
123
|
return;
|
|
125
124
|
}
|
|
126
125
|
await Promises.settled(joiners);
|
|
@@ -130,38 +129,34 @@ let FileService = class FileService extends Disposable {
|
|
|
130
129
|
return this.hasProvider(resource);
|
|
131
130
|
}
|
|
132
131
|
hasProvider(resource) {
|
|
133
|
-
return (
|
|
134
|
-
(this.provider.has(resource.scheme))
|
|
135
|
-
);
|
|
132
|
+
return ( this.provider.has(resource.scheme));
|
|
136
133
|
}
|
|
137
134
|
hasCapability(resource, capability) {
|
|
138
135
|
const provider = this.provider.get(resource.scheme);
|
|
139
136
|
return !!(provider && (provider.capabilities & capability));
|
|
140
137
|
}
|
|
141
138
|
listCapabilities() {
|
|
142
|
-
return (
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
))
|
|
147
|
-
);
|
|
139
|
+
return ( Iterable.map(
|
|
140
|
+
this.provider,
|
|
141
|
+
([scheme, provider]) => ({ scheme, capabilities: provider.capabilities })
|
|
142
|
+
));
|
|
148
143
|
}
|
|
149
144
|
async withProvider(resource) {
|
|
150
145
|
if (!isAbsolutePath(resource)) {
|
|
151
|
-
throw (
|
|
152
|
-
|
|
146
|
+
throw ( new FileOperationError(( localize(
|
|
147
|
+
1748,
|
|
153
148
|
"Unable to resolve filesystem provider with relative file path '{0}'",
|
|
154
149
|
this.resourceForError(resource)
|
|
155
|
-
),
|
|
150
|
+
)), FileOperationResult.FILE_INVALID_PATH));
|
|
156
151
|
}
|
|
157
152
|
await this.activateProvider(resource.scheme);
|
|
158
153
|
const provider = this.provider.get(resource.scheme);
|
|
159
154
|
if (!provider) {
|
|
160
|
-
const error = (
|
|
155
|
+
const error = ( new ErrorNoTelemetry());
|
|
161
156
|
error.message = ( localize(
|
|
162
|
-
|
|
157
|
+
1749,
|
|
163
158
|
"ENOPRO: No file system provider found for resource '{0}'",
|
|
164
|
-
|
|
159
|
+
(resource.toString())
|
|
165
160
|
));
|
|
166
161
|
throw error;
|
|
167
162
|
}
|
|
@@ -172,18 +167,18 @@ let FileService = class FileService extends Disposable {
|
|
|
172
167
|
if (hasOpenReadWriteCloseCapability(provider) || hasReadWriteCapability(provider) || hasFileReadStreamCapability(provider)) {
|
|
173
168
|
return provider;
|
|
174
169
|
}
|
|
175
|
-
throw (
|
|
170
|
+
throw ( new Error(
|
|
176
171
|
`Filesystem provider for scheme '${resource.scheme}' neither has FileReadWrite, FileReadStream nor FileOpenReadWriteClose capability which is needed for the read operation.`
|
|
177
|
-
))
|
|
172
|
+
));
|
|
178
173
|
}
|
|
179
174
|
async withWriteProvider(resource) {
|
|
180
175
|
const provider = await this.withProvider(resource);
|
|
181
176
|
if (hasOpenReadWriteCloseCapability(provider) || hasReadWriteCapability(provider)) {
|
|
182
177
|
return provider;
|
|
183
178
|
}
|
|
184
|
-
throw (
|
|
179
|
+
throw ( new Error(
|
|
185
180
|
`Filesystem provider for scheme '${resource.scheme}' neither has FileReadWrite nor FileOpenReadWriteClose capability which is needed for the write operation.`
|
|
186
|
-
))
|
|
181
|
+
));
|
|
187
182
|
}
|
|
188
183
|
async resolve(resource, options) {
|
|
189
184
|
try {
|
|
@@ -191,11 +186,11 @@ let FileService = class FileService extends Disposable {
|
|
|
191
186
|
}
|
|
192
187
|
catch (error) {
|
|
193
188
|
if (toFileSystemProviderErrorCode(error) === FileSystemProviderErrorCode.FileNotFound) {
|
|
194
|
-
throw (
|
|
195
|
-
|
|
189
|
+
throw ( new FileOperationError(( localize(
|
|
190
|
+
1750,
|
|
196
191
|
"Unable to resolve nonexistent file '{0}'",
|
|
197
192
|
this.resourceForError(resource)
|
|
198
|
-
),
|
|
193
|
+
)), FileOperationResult.FILE_NOT_FOUND));
|
|
199
194
|
}
|
|
200
195
|
throw ensureFileSystemProviderError(error);
|
|
201
196
|
}
|
|
@@ -236,7 +231,7 @@ let FileService = class FileService extends Disposable {
|
|
|
236
231
|
mtime: stat.mtime,
|
|
237
232
|
ctime: stat.ctime,
|
|
238
233
|
size: stat.size,
|
|
239
|
-
readonly: Boolean((stat.permissions ?? 0) & FilePermission.Readonly) || Boolean(provider.capabilities &
|
|
234
|
+
readonly: Boolean((stat.permissions ?? 0) & FilePermission.Readonly) || Boolean(provider.capabilities & FileSystemProviderCapabilities.Readonly),
|
|
240
235
|
locked: Boolean((stat.permissions ?? 0) & FilePermission.Locked),
|
|
241
236
|
etag: etag({ mtime: stat.mtime, size: stat.size }),
|
|
242
237
|
children: undefined
|
|
@@ -244,7 +239,7 @@ let FileService = class FileService extends Disposable {
|
|
|
244
239
|
if (fileStat.isDirectory && recurse(fileStat, siblings)) {
|
|
245
240
|
try {
|
|
246
241
|
const entries = await provider.readdir(resource);
|
|
247
|
-
const resolvedEntries = await Promises.settled((
|
|
242
|
+
const resolvedEntries = await Promises.settled(( entries.map(async ([name, type]) => {
|
|
248
243
|
try {
|
|
249
244
|
const childResource = providerExtUri.joinPath(resource, name);
|
|
250
245
|
const childStat = resolveMetadata ? await provider.stat(childResource) : { type };
|
|
@@ -254,7 +249,7 @@ let FileService = class FileService extends Disposable {
|
|
|
254
249
|
this.logService.trace(error);
|
|
255
250
|
return null;
|
|
256
251
|
}
|
|
257
|
-
})))
|
|
252
|
+
})));
|
|
258
253
|
fileStat.children = coalesce(resolvedEntries);
|
|
259
254
|
}
|
|
260
255
|
catch (error) {
|
|
@@ -266,7 +261,7 @@ let FileService = class FileService extends Disposable {
|
|
|
266
261
|
return fileStat;
|
|
267
262
|
}
|
|
268
263
|
async resolveAll(toResolve) {
|
|
269
|
-
return Promises.settled((
|
|
264
|
+
return Promises.settled(( toResolve.map(async (entry) => {
|
|
270
265
|
try {
|
|
271
266
|
return { stat: await this.doResolveFile(entry.resource, entry.options), success: true };
|
|
272
267
|
}
|
|
@@ -274,7 +269,7 @@ let FileService = class FileService extends Disposable {
|
|
|
274
269
|
this.logService.trace(error);
|
|
275
270
|
return { stat: undefined, success: false };
|
|
276
271
|
}
|
|
277
|
-
})))
|
|
272
|
+
})));
|
|
278
273
|
}
|
|
279
274
|
async stat(resource) {
|
|
280
275
|
const provider = await this.withProvider(resource);
|
|
@@ -302,17 +297,17 @@ let FileService = class FileService extends Disposable {
|
|
|
302
297
|
}
|
|
303
298
|
async doValidateCreateFile(resource, options) {
|
|
304
299
|
if (!options?.overwrite && (await this.exists(resource))) {
|
|
305
|
-
throw (
|
|
306
|
-
|
|
300
|
+
throw ( new FileOperationError(( localize(
|
|
301
|
+
1751,
|
|
307
302
|
"Unable to create file '{0}' that already exists when overwrite flag is not set",
|
|
308
303
|
this.resourceForError(resource)
|
|
309
|
-
),
|
|
304
|
+
)), FileOperationResult.FILE_MODIFIED_SINCE, options));
|
|
310
305
|
}
|
|
311
306
|
}
|
|
312
307
|
async createFile(resource, bufferOrReadableOrStream = VSBuffer.fromString(''), options) {
|
|
313
308
|
await this.doValidateCreateFile(resource, options);
|
|
314
309
|
const fileStat = await this.writeFile(resource, bufferOrReadableOrStream);
|
|
315
|
-
this._onDidRunOperation.fire((
|
|
310
|
+
this._onDidRunOperation.fire(( new FileOperationEvent(resource, FileOperation.CREATE, fileStat)));
|
|
316
311
|
return fileStat;
|
|
317
312
|
}
|
|
318
313
|
async writeFile(resource, bufferOrReadableOrStream, options) {
|
|
@@ -357,46 +352,46 @@ let FileService = class FileService extends Disposable {
|
|
|
357
352
|
else {
|
|
358
353
|
await this.doWriteBuffered(provider, resource, writeFileOptions, bufferOrReadableOrStreamOrBufferedStream instanceof VSBuffer ? bufferToReadable(bufferOrReadableOrStreamOrBufferedStream) : bufferOrReadableOrStreamOrBufferedStream);
|
|
359
354
|
}
|
|
360
|
-
this._onDidRunOperation.fire((
|
|
355
|
+
this._onDidRunOperation.fire(( new FileOperationEvent(resource, FileOperation.WRITE)));
|
|
361
356
|
}
|
|
362
357
|
catch (error) {
|
|
363
|
-
throw (
|
|
364
|
-
|
|
358
|
+
throw ( new FileOperationError(( localize(
|
|
359
|
+
1752,
|
|
365
360
|
"Unable to write file '{0}' ({1})",
|
|
366
361
|
this.resourceForError(resource),
|
|
367
|
-
(
|
|
368
|
-
), toFileOperationResult(error), writeFileOptions))
|
|
362
|
+
(ensureFileSystemProviderError(error).toString())
|
|
363
|
+
)), toFileOperationResult(error), writeFileOptions));
|
|
369
364
|
}
|
|
370
365
|
return this.resolve(resource, { resolveMetadata: true });
|
|
371
366
|
}
|
|
372
367
|
async validateWriteFile(provider, resource, options) {
|
|
373
368
|
const unlock = !!options?.unlock;
|
|
374
|
-
if (unlock && !(
|
|
375
|
-
throw (
|
|
376
|
-
|
|
369
|
+
if (unlock && !(provider.capabilities & FileSystemProviderCapabilities.FileWriteUnlock)) {
|
|
370
|
+
throw ( new Error(( localize(
|
|
371
|
+
1753,
|
|
377
372
|
"Unable to unlock file '{0}' because provider does not support it.",
|
|
378
373
|
this.resourceForError(resource)
|
|
379
374
|
))));
|
|
380
375
|
}
|
|
381
376
|
const atomic = !!options?.atomic;
|
|
382
377
|
if (atomic) {
|
|
383
|
-
if (!(
|
|
384
|
-
throw (
|
|
385
|
-
|
|
378
|
+
if (!(provider.capabilities & FileSystemProviderCapabilities.FileAtomicWrite)) {
|
|
379
|
+
throw ( new Error(( localize(
|
|
380
|
+
1754,
|
|
386
381
|
"Unable to atomically write file '{0}' because provider does not support it.",
|
|
387
382
|
this.resourceForError(resource)
|
|
388
383
|
))));
|
|
389
384
|
}
|
|
390
|
-
if (!(
|
|
391
|
-
throw (
|
|
392
|
-
|
|
385
|
+
if (!(provider.capabilities & FileSystemProviderCapabilities.FileReadWrite)) {
|
|
386
|
+
throw ( new Error(( localize(
|
|
387
|
+
1755,
|
|
393
388
|
"Unable to atomically write file '{0}' because provider does not support unbuffered writes.",
|
|
394
389
|
this.resourceForError(resource)
|
|
395
390
|
))));
|
|
396
391
|
}
|
|
397
392
|
if (unlock) {
|
|
398
|
-
throw (
|
|
399
|
-
|
|
393
|
+
throw ( new Error(( localize(
|
|
394
|
+
1756,
|
|
400
395
|
"Unable to unlock file '{0}' because atomic write is enabled.",
|
|
401
396
|
this.resourceForError(resource)
|
|
402
397
|
))));
|
|
@@ -410,21 +405,17 @@ let FileService = class FileService extends Disposable {
|
|
|
410
405
|
return undefined;
|
|
411
406
|
}
|
|
412
407
|
if ((stat.type & FileType.Directory) !== 0) {
|
|
413
|
-
throw (
|
|
414
|
-
|
|
408
|
+
throw ( new FileOperationError(( localize(
|
|
409
|
+
1757,
|
|
415
410
|
"Unable to write file '{0}' that is actually a directory",
|
|
416
411
|
this.resourceForError(resource)
|
|
417
|
-
),
|
|
412
|
+
)), FileOperationResult.FILE_IS_DIRECTORY, options));
|
|
418
413
|
}
|
|
419
414
|
this.throwIfFileIsReadonly(resource, stat);
|
|
420
415
|
if (typeof options?.mtime === 'number' && typeof options.etag === 'string' && options.etag !== ETAG_DISABLED &&
|
|
421
416
|
typeof stat.mtime === 'number' && typeof stat.size === 'number' &&
|
|
422
417
|
options.mtime < stat.mtime && options.etag !== etag({ mtime: options.mtime , size: stat.size })) {
|
|
423
|
-
throw (
|
|
424
|
-
localize(600, "File Modified Since"),
|
|
425
|
-
3 ,
|
|
426
|
-
options
|
|
427
|
-
)));
|
|
418
|
+
throw ( new FileOperationError(( localize(1758, "File Modified Since")), FileOperationResult.FILE_MODIFIED_SINCE, options));
|
|
428
419
|
}
|
|
429
420
|
return stat;
|
|
430
421
|
}
|
|
@@ -436,19 +427,17 @@ let FileService = class FileService extends Disposable {
|
|
|
436
427
|
return this.doReadFile(provider, resource, options, token);
|
|
437
428
|
}
|
|
438
429
|
async doReadFileAtomic(provider, resource, options, token) {
|
|
439
|
-
return (
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
}))
|
|
451
|
-
);
|
|
430
|
+
return ( new Promise((resolve, reject) => {
|
|
431
|
+
this.writeQueue.queueFor(resource, async () => {
|
|
432
|
+
try {
|
|
433
|
+
const content = await this.doReadFile(provider, resource, options, token);
|
|
434
|
+
resolve(content);
|
|
435
|
+
}
|
|
436
|
+
catch (error) {
|
|
437
|
+
reject(error);
|
|
438
|
+
}
|
|
439
|
+
}, this.getExtUri(provider).providerExtUri);
|
|
440
|
+
}));
|
|
452
441
|
}
|
|
453
442
|
async doReadFile(provider, resource, options, token) {
|
|
454
443
|
const stream = await this.doReadFileStream(provider, resource, {
|
|
@@ -465,7 +454,7 @@ let FileService = class FileService extends Disposable {
|
|
|
465
454
|
return this.doReadFileStream(provider, resource, options, token);
|
|
466
455
|
}
|
|
467
456
|
async doReadFileStream(provider, resource, options, token) {
|
|
468
|
-
const cancellableSource = (
|
|
457
|
+
const cancellableSource = ( new CancellationTokenSource(token));
|
|
469
458
|
let readFileOptions = options;
|
|
470
459
|
if (hasFileAtomicReadCapability(provider) && provider.enforceAtomicReadFile?.(resource)) {
|
|
471
460
|
readFileOptions = { ...options, atomic: true };
|
|
@@ -508,24 +497,18 @@ let FileService = class FileService extends Disposable {
|
|
|
508
497
|
}
|
|
509
498
|
restoreReadError(error, resource, options) {
|
|
510
499
|
const message = ( localize(
|
|
511
|
-
|
|
500
|
+
1759,
|
|
512
501
|
"Unable to read file '{0}' ({1})",
|
|
513
502
|
this.resourceForError(resource),
|
|
514
|
-
|
|
503
|
+
(ensureFileSystemProviderError(error).toString())
|
|
515
504
|
));
|
|
516
505
|
if (error instanceof NotModifiedSinceFileOperationError) {
|
|
517
|
-
return (
|
|
518
|
-
(new NotModifiedSinceFileOperationError(message, error.stat, options))
|
|
519
|
-
);
|
|
506
|
+
return ( new NotModifiedSinceFileOperationError(message, error.stat, options));
|
|
520
507
|
}
|
|
521
508
|
if (error instanceof TooLargeFileOperationError) {
|
|
522
|
-
return (
|
|
523
|
-
(new TooLargeFileOperationError(message, error.fileOperationResult, error.size, error.options))
|
|
524
|
-
);
|
|
509
|
+
return ( new TooLargeFileOperationError(message, error.fileOperationResult, error.size, error.options));
|
|
525
510
|
}
|
|
526
|
-
return (
|
|
527
|
-
(new FileOperationError(message, toFileOperationResult(error), options))
|
|
528
|
-
);
|
|
511
|
+
return ( new FileOperationError(message, toFileOperationResult(error), options));
|
|
529
512
|
}
|
|
530
513
|
readFileStreamed(provider, resource, token, options = Object.create(null)) {
|
|
531
514
|
const fileStream = provider.readFileStream(resource, options, token);
|
|
@@ -573,25 +556,25 @@ let FileService = class FileService extends Disposable {
|
|
|
573
556
|
async validateReadFile(resource, options) {
|
|
574
557
|
const stat = await this.resolve(resource, { resolveMetadata: true });
|
|
575
558
|
if (stat.isDirectory) {
|
|
576
|
-
throw (
|
|
577
|
-
|
|
559
|
+
throw ( new FileOperationError(( localize(
|
|
560
|
+
1760,
|
|
578
561
|
"Unable to read file '{0}' that is actually a directory",
|
|
579
562
|
this.resourceForError(resource)
|
|
580
|
-
),
|
|
563
|
+
)), FileOperationResult.FILE_IS_DIRECTORY, options));
|
|
581
564
|
}
|
|
582
565
|
if (typeof options?.etag === 'string' && options.etag !== ETAG_DISABLED && options.etag === stat.etag) {
|
|
583
|
-
throw (
|
|
566
|
+
throw ( new NotModifiedSinceFileOperationError(( localize(1761, "File not modified since")), stat, options));
|
|
584
567
|
}
|
|
585
568
|
this.validateReadFileLimits(resource, stat.size, options);
|
|
586
569
|
return stat;
|
|
587
570
|
}
|
|
588
571
|
validateReadFileLimits(resource, size, options) {
|
|
589
572
|
if (typeof options?.limits?.size === 'number' && size > options.limits.size) {
|
|
590
|
-
throw (
|
|
591
|
-
|
|
573
|
+
throw ( new TooLargeFileOperationError(( localize(
|
|
574
|
+
1762,
|
|
592
575
|
"Unable to read file '{0}' that is too large to open",
|
|
593
576
|
this.resourceForError(resource)
|
|
594
|
-
),
|
|
577
|
+
)), FileOperationResult.FILE_TOO_LARGE, size, options));
|
|
595
578
|
}
|
|
596
579
|
}
|
|
597
580
|
async canMove(source, target, overwrite) {
|
|
@@ -601,7 +584,7 @@ let FileService = class FileService extends Disposable {
|
|
|
601
584
|
return this.doCanMoveCopy(source, target, 'copy', overwrite);
|
|
602
585
|
}
|
|
603
586
|
async doCanMoveCopy(source, target, mode, overwrite) {
|
|
604
|
-
if ((
|
|
587
|
+
if (( source.toString()) !== ( target.toString())) {
|
|
605
588
|
try {
|
|
606
589
|
const sourceProvider = mode === 'move' ? this.throwIfFileSystemIsReadonly(await this.withWriteProvider(source), source) : await this.withReadProvider(source);
|
|
607
590
|
const targetProvider = this.throwIfFileSystemIsReadonly(await this.withWriteProvider(target), target);
|
|
@@ -618,11 +601,11 @@ let FileService = class FileService extends Disposable {
|
|
|
618
601
|
const targetProvider = this.throwIfFileSystemIsReadonly(await this.withWriteProvider(target), target);
|
|
619
602
|
const mode = await this.doMoveCopy(sourceProvider, source, targetProvider, target, 'move', !!overwrite);
|
|
620
603
|
const fileStat = await this.resolve(target, { resolveMetadata: true });
|
|
621
|
-
this._onDidRunOperation.fire((
|
|
604
|
+
this._onDidRunOperation.fire(( new FileOperationEvent(
|
|
622
605
|
source,
|
|
623
|
-
mode === 'move' ?
|
|
606
|
+
mode === 'move' ? FileOperation.MOVE : FileOperation.COPY,
|
|
624
607
|
fileStat
|
|
625
|
-
)))
|
|
608
|
+
)));
|
|
626
609
|
return fileStat;
|
|
627
610
|
}
|
|
628
611
|
async copy(source, target, overwrite) {
|
|
@@ -630,15 +613,15 @@ let FileService = class FileService extends Disposable {
|
|
|
630
613
|
const targetProvider = this.throwIfFileSystemIsReadonly(await this.withWriteProvider(target), target);
|
|
631
614
|
const mode = await this.doMoveCopy(sourceProvider, source, targetProvider, target, 'copy', !!overwrite);
|
|
632
615
|
const fileStat = await this.resolve(target, { resolveMetadata: true });
|
|
633
|
-
this._onDidRunOperation.fire((
|
|
616
|
+
this._onDidRunOperation.fire(( new FileOperationEvent(
|
|
634
617
|
source,
|
|
635
|
-
mode === 'copy' ?
|
|
618
|
+
mode === 'copy' ? FileOperation.COPY : FileOperation.MOVE,
|
|
636
619
|
fileStat
|
|
637
|
-
)))
|
|
620
|
+
)));
|
|
638
621
|
return fileStat;
|
|
639
622
|
}
|
|
640
623
|
async doMoveCopy(sourceProvider, source, targetProvider, target, mode, overwrite) {
|
|
641
|
-
if ((
|
|
624
|
+
if (( source.toString()) === ( target.toString())) {
|
|
642
625
|
return mode;
|
|
643
626
|
}
|
|
644
627
|
const { exists, isSameResourceWithDifferentPathCase } = await this.doValidateMoveCopy(sourceProvider, source, targetProvider, target, mode, overwrite);
|
|
@@ -690,7 +673,7 @@ let FileService = class FileService extends Disposable {
|
|
|
690
673
|
async doCopyFolder(sourceProvider, sourceFolder, targetProvider, targetFolder) {
|
|
691
674
|
await targetProvider.mkdir(targetFolder);
|
|
692
675
|
if (Array.isArray(sourceFolder.children)) {
|
|
693
|
-
await Promises.settled((
|
|
676
|
+
await Promises.settled(( sourceFolder.children.map(async (sourceChild) => {
|
|
694
677
|
const targetChild = this.getExtUri(targetProvider).providerExtUri.joinPath(targetFolder, sourceChild.name);
|
|
695
678
|
if (sourceChild.isDirectory) {
|
|
696
679
|
return this.doCopyFolder(sourceProvider, await this.resolve(sourceChild.resource), targetProvider, targetChild);
|
|
@@ -698,7 +681,7 @@ let FileService = class FileService extends Disposable {
|
|
|
698
681
|
else {
|
|
699
682
|
return this.doCopyFile(sourceProvider, sourceChild.resource, targetProvider, targetChild);
|
|
700
683
|
}
|
|
701
|
-
})))
|
|
684
|
+
})));
|
|
702
685
|
}
|
|
703
686
|
}
|
|
704
687
|
async doValidateMoveCopy(sourceProvider, source, targetProvider, target, mode, overwrite) {
|
|
@@ -709,16 +692,16 @@ let FileService = class FileService extends Disposable {
|
|
|
709
692
|
isSameResourceWithDifferentPathCase = providerExtUri.isEqual(source, target);
|
|
710
693
|
}
|
|
711
694
|
if (isSameResourceWithDifferentPathCase && mode === 'copy') {
|
|
712
|
-
throw (
|
|
713
|
-
|
|
695
|
+
throw ( new Error(( localize(
|
|
696
|
+
1763,
|
|
714
697
|
"Unable to copy when source '{0}' is same as target '{1}' with different path case on a case insensitive file system",
|
|
715
698
|
this.resourceForError(source),
|
|
716
699
|
this.resourceForError(target)
|
|
717
700
|
))));
|
|
718
701
|
}
|
|
719
702
|
if (!isSameResourceWithDifferentPathCase && providerExtUri.isEqualOrParent(target, source)) {
|
|
720
|
-
throw (
|
|
721
|
-
|
|
703
|
+
throw ( new Error(( localize(
|
|
704
|
+
1764,
|
|
722
705
|
"Unable to move/copy when source '{0}' is parent of target '{1}'.",
|
|
723
706
|
this.resourceForError(source),
|
|
724
707
|
this.resourceForError(target)
|
|
@@ -728,18 +711,18 @@ let FileService = class FileService extends Disposable {
|
|
|
728
711
|
const exists = await this.exists(target);
|
|
729
712
|
if (exists && !isSameResourceWithDifferentPathCase) {
|
|
730
713
|
if (!overwrite) {
|
|
731
|
-
throw (
|
|
732
|
-
|
|
714
|
+
throw ( new FileOperationError(( localize(
|
|
715
|
+
1765,
|
|
733
716
|
"Unable to move/copy '{0}' because target '{1}' already exists at destination.",
|
|
734
717
|
this.resourceForError(source),
|
|
735
718
|
this.resourceForError(target)
|
|
736
|
-
),
|
|
719
|
+
)), FileOperationResult.FILE_MOVE_CONFLICT));
|
|
737
720
|
}
|
|
738
721
|
if (sourceProvider === targetProvider) {
|
|
739
722
|
const { providerExtUri } = this.getExtUri(sourceProvider);
|
|
740
723
|
if (providerExtUri.isEqualOrParent(source, target)) {
|
|
741
|
-
throw (
|
|
742
|
-
|
|
724
|
+
throw ( new Error(( localize(
|
|
725
|
+
1766,
|
|
743
726
|
"Unable to move/copy '{0}' into '{1}' since a file would replace the folder it is contained in.",
|
|
744
727
|
this.resourceForError(source),
|
|
745
728
|
this.resourceForError(target)
|
|
@@ -757,13 +740,13 @@ let FileService = class FileService extends Disposable {
|
|
|
757
740
|
};
|
|
758
741
|
}
|
|
759
742
|
isPathCaseSensitive(provider) {
|
|
760
|
-
return !!(
|
|
743
|
+
return !!(provider.capabilities & FileSystemProviderCapabilities.PathCaseSensitive);
|
|
761
744
|
}
|
|
762
745
|
async createFolder(resource) {
|
|
763
746
|
const provider = this.throwIfFileSystemIsReadonly(await this.withProvider(resource), resource);
|
|
764
747
|
await this.mkdirp(provider, resource);
|
|
765
748
|
const fileStat = await this.resolve(resource, { resolveMetadata: true });
|
|
766
|
-
this._onDidRunOperation.fire((
|
|
749
|
+
this._onDidRunOperation.fire(( new FileOperationEvent(resource, FileOperation.CREATE, fileStat)));
|
|
767
750
|
return fileStat;
|
|
768
751
|
}
|
|
769
752
|
async mkdirp(provider, directory) {
|
|
@@ -782,24 +765,24 @@ let FileService = class FileService extends Disposable {
|
|
|
782
765
|
async doValidateDelete(resource, options) {
|
|
783
766
|
const provider = this.throwIfFileSystemIsReadonly(await this.withProvider(resource), resource);
|
|
784
767
|
const useTrash = !!options?.useTrash;
|
|
785
|
-
if (useTrash && !(
|
|
786
|
-
throw (
|
|
787
|
-
|
|
768
|
+
if (useTrash && !(provider.capabilities & FileSystemProviderCapabilities.Trash)) {
|
|
769
|
+
throw ( new Error(( localize(
|
|
770
|
+
1767,
|
|
788
771
|
"Unable to delete file '{0}' via trash because provider does not support it.",
|
|
789
772
|
this.resourceForError(resource)
|
|
790
773
|
))));
|
|
791
774
|
}
|
|
792
775
|
const atomic = options?.atomic;
|
|
793
|
-
if (atomic && !(
|
|
794
|
-
throw (
|
|
795
|
-
|
|
776
|
+
if (atomic && !(provider.capabilities & FileSystemProviderCapabilities.FileAtomicDelete)) {
|
|
777
|
+
throw ( new Error(( localize(
|
|
778
|
+
1768,
|
|
796
779
|
"Unable to delete file '{0}' atomically because provider does not support it.",
|
|
797
780
|
this.resourceForError(resource)
|
|
798
781
|
))));
|
|
799
782
|
}
|
|
800
783
|
if (useTrash && atomic) {
|
|
801
|
-
throw (
|
|
802
|
-
|
|
784
|
+
throw ( new Error(( localize(
|
|
785
|
+
1769,
|
|
803
786
|
"Unable to atomically delete file '{0}' because using trash is enabled.",
|
|
804
787
|
this.resourceForError(resource)
|
|
805
788
|
))));
|
|
@@ -814,18 +797,18 @@ let FileService = class FileService extends Disposable {
|
|
|
814
797
|
this.throwIfFileIsReadonly(resource, stat);
|
|
815
798
|
}
|
|
816
799
|
else {
|
|
817
|
-
throw (
|
|
818
|
-
|
|
800
|
+
throw ( new FileOperationError(( localize(
|
|
801
|
+
1770,
|
|
819
802
|
"Unable to delete nonexistent file '{0}'",
|
|
820
803
|
this.resourceForError(resource)
|
|
821
|
-
),
|
|
804
|
+
)), FileOperationResult.FILE_NOT_FOUND));
|
|
822
805
|
}
|
|
823
806
|
const recursive = !!options?.recursive;
|
|
824
807
|
if (!recursive) {
|
|
825
808
|
const stat = await this.resolve(resource);
|
|
826
809
|
if (stat.isDirectory && Array.isArray(stat.children) && stat.children.length > 0) {
|
|
827
|
-
throw (
|
|
828
|
-
|
|
810
|
+
throw ( new Error(( localize(
|
|
811
|
+
1771,
|
|
829
812
|
"Unable to delete non-empty folder '{0}'.",
|
|
830
813
|
this.resourceForError(resource)
|
|
831
814
|
))));
|
|
@@ -846,7 +829,7 @@ let FileService = class FileService extends Disposable {
|
|
|
846
829
|
const recursive = !!deleteFileOptions?.recursive;
|
|
847
830
|
const atomic = deleteFileOptions?.atomic ?? false;
|
|
848
831
|
await provider.delete(resource, { recursive, useTrash, atomic });
|
|
849
|
-
this._onDidRunOperation.fire((
|
|
832
|
+
this._onDidRunOperation.fire(( new FileOperationEvent(resource, FileOperation.DELETE)));
|
|
850
833
|
}
|
|
851
834
|
async cloneFile(source, target) {
|
|
852
835
|
const sourceProvider = await this.withProvider(source);
|
|
@@ -871,7 +854,7 @@ let FileService = class FileService extends Disposable {
|
|
|
871
854
|
});
|
|
872
855
|
}
|
|
873
856
|
watch(resource, options = { recursive: false, excludes: [] }) {
|
|
874
|
-
const disposables = (
|
|
857
|
+
const disposables = ( new DisposableStore());
|
|
875
858
|
let watchDisposed = false;
|
|
876
859
|
let disposeWatch = () => { watchDisposed = true; };
|
|
877
860
|
disposables.add(toDisposable(() => disposeWatch()));
|
|
@@ -891,7 +874,7 @@ let FileService = class FileService extends Disposable {
|
|
|
891
874
|
})();
|
|
892
875
|
const correlationId = options.correlationId;
|
|
893
876
|
if (typeof correlationId === 'number') {
|
|
894
|
-
const fileChangeEmitter = disposables.add((
|
|
877
|
+
const fileChangeEmitter = disposables.add(( new Emitter()));
|
|
895
878
|
disposables.add(this.internalOnDidFilesChange.event(e => {
|
|
896
879
|
if (e.correlates(correlationId)) {
|
|
897
880
|
fileChangeEmitter.fire(e);
|
|
@@ -970,25 +953,23 @@ let FileService = class FileService extends Disposable {
|
|
|
970
953
|
else {
|
|
971
954
|
stream = streamOrBufferedStream;
|
|
972
955
|
}
|
|
973
|
-
return (
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
}))
|
|
991
|
-
);
|
|
956
|
+
return ( new Promise((resolve, reject) => {
|
|
957
|
+
listenStream(stream, {
|
|
958
|
+
onData: async (chunk) => {
|
|
959
|
+
stream.pause();
|
|
960
|
+
try {
|
|
961
|
+
await this.doWriteBuffer(provider, handle, chunk, chunk.byteLength, posInFile, 0);
|
|
962
|
+
}
|
|
963
|
+
catch (error) {
|
|
964
|
+
return reject(error);
|
|
965
|
+
}
|
|
966
|
+
posInFile += chunk.byteLength;
|
|
967
|
+
setTimeout(() => stream.resume());
|
|
968
|
+
},
|
|
969
|
+
onError: error => reject(error),
|
|
970
|
+
onEnd: () => resolve()
|
|
971
|
+
});
|
|
972
|
+
}));
|
|
992
973
|
}
|
|
993
974
|
async doWriteReadableBufferedQueued(provider, handle, readable) {
|
|
994
975
|
let posInFile = 0;
|
|
@@ -1084,30 +1065,30 @@ let FileService = class FileService extends Disposable {
|
|
|
1084
1065
|
await this.doWriteUnbuffered(targetProvider, target, undefined, buffer);
|
|
1085
1066
|
}
|
|
1086
1067
|
throwIfFileSystemIsReadonly(provider, resource) {
|
|
1087
|
-
if (provider.capabilities &
|
|
1088
|
-
throw (
|
|
1089
|
-
|
|
1068
|
+
if (provider.capabilities & FileSystemProviderCapabilities.Readonly) {
|
|
1069
|
+
throw ( new FileOperationError(( localize(
|
|
1070
|
+
1772,
|
|
1090
1071
|
"Unable to modify read-only file '{0}'",
|
|
1091
1072
|
this.resourceForError(resource)
|
|
1092
|
-
),
|
|
1073
|
+
)), FileOperationResult.FILE_PERMISSION_DENIED));
|
|
1093
1074
|
}
|
|
1094
1075
|
return provider;
|
|
1095
1076
|
}
|
|
1096
1077
|
throwIfFileIsReadonly(resource, stat) {
|
|
1097
1078
|
if ((stat.permissions ?? 0) & FilePermission.Readonly) {
|
|
1098
|
-
throw (
|
|
1099
|
-
|
|
1079
|
+
throw ( new FileOperationError(( localize(
|
|
1080
|
+
1772,
|
|
1100
1081
|
"Unable to modify read-only file '{0}'",
|
|
1101
1082
|
this.resourceForError(resource)
|
|
1102
|
-
),
|
|
1083
|
+
)), FileOperationResult.FILE_PERMISSION_DENIED));
|
|
1103
1084
|
}
|
|
1104
1085
|
}
|
|
1105
1086
|
resourceForError(resource) {
|
|
1106
1087
|
return resourceForError(resource);
|
|
1107
1088
|
}
|
|
1108
1089
|
};
|
|
1109
|
-
FileService = FileService_1 = (
|
|
1110
|
-
(
|
|
1111
|
-
], FileService))
|
|
1090
|
+
FileService = FileService_1 = ( __decorate([
|
|
1091
|
+
( __param(0, ILogService))
|
|
1092
|
+
], FileService));
|
|
1112
1093
|
|
|
1113
1094
|
export { FileService, mkdirp };
|