@theia/filesystem 1.45.1 → 1.46.0-next.137

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 (143) hide show
  1. package/lib/browser/breadcrumbs/filepath-breadcrumbs-container.js +8 -19
  2. package/lib/browser/breadcrumbs/filepath-breadcrumbs-container.js.map +1 -1
  3. package/lib/browser/breadcrumbs/filepath-breadcrumbs-contribution.js +8 -16
  4. package/lib/browser/breadcrumbs/filepath-breadcrumbs-contribution.js.map +1 -1
  5. package/lib/browser/download/file-download-command-contribution.js +6 -14
  6. package/lib/browser/download/file-download-command-contribution.js.map +1 -1
  7. package/lib/browser/download/file-download-service.js +6 -14
  8. package/lib/browser/download/file-download-service.js.map +1 -1
  9. package/lib/browser/file-dialog/file-dialog-hidden-files-renderer.js +7 -15
  10. package/lib/browser/file-dialog/file-dialog-hidden-files-renderer.js.map +1 -1
  11. package/lib/browser/file-dialog/file-dialog-model.js +8 -16
  12. package/lib/browser/file-dialog/file-dialog-model.js.map +1 -1
  13. package/lib/browser/file-dialog/file-dialog-service.js +14 -22
  14. package/lib/browser/file-dialog/file-dialog-service.js.map +1 -1
  15. package/lib/browser/file-dialog/file-dialog-tree-filters-renderer.js +4 -15
  16. package/lib/browser/file-dialog/file-dialog-tree-filters-renderer.js.map +1 -1
  17. package/lib/browser/file-dialog/file-dialog-tree.js +2 -7
  18. package/lib/browser/file-dialog/file-dialog-tree.js.map +1 -1
  19. package/lib/browser/file-dialog/file-dialog-widget.js +6 -17
  20. package/lib/browser/file-dialog/file-dialog-widget.js.map +1 -1
  21. package/lib/browser/file-dialog/file-dialog.js +34 -45
  22. package/lib/browser/file-dialog/file-dialog.js.map +1 -1
  23. package/lib/browser/file-dialog/index.js +5 -14
  24. package/lib/browser/file-dialog/index.js.map +1 -1
  25. package/lib/browser/file-resource.d.ts +6 -2
  26. package/lib/browser/file-resource.d.ts.map +1 -1
  27. package/lib/browser/file-resource.js +39 -22
  28. package/lib/browser/file-resource.js.map +1 -1
  29. package/lib/browser/file-service.d.ts +13 -0
  30. package/lib/browser/file-service.d.ts.map +1 -1
  31. package/lib/browser/file-service.js +46 -40
  32. package/lib/browser/file-service.js.map +1 -1
  33. package/lib/browser/file-tree/file-tree-decorator-adapter.js +10 -18
  34. package/lib/browser/file-tree/file-tree-decorator-adapter.js.map +1 -1
  35. package/lib/browser/file-tree/file-tree-label-provider.js +6 -14
  36. package/lib/browser/file-tree/file-tree-label-provider.js.map +1 -1
  37. package/lib/browser/file-tree/file-tree-model.js +14 -22
  38. package/lib/browser/file-tree/file-tree-model.js.map +1 -1
  39. package/lib/browser/file-tree/file-tree-widget.js +10 -21
  40. package/lib/browser/file-tree/file-tree-widget.js.map +1 -1
  41. package/lib/browser/file-tree/file-tree.js +6 -14
  42. package/lib/browser/file-tree/file-tree.js.map +1 -1
  43. package/lib/browser/file-tree/index.js +7 -16
  44. package/lib/browser/file-tree/index.js.map +1 -1
  45. package/lib/browser/file-upload-service.d.ts +2 -4
  46. package/lib/browser/file-upload-service.d.ts.map +1 -1
  47. package/lib/browser/file-upload-service.js +14 -22
  48. package/lib/browser/file-upload-service.js.map +1 -1
  49. package/lib/browser/filesystem-frontend-contribution.d.ts +20 -9
  50. package/lib/browser/filesystem-frontend-contribution.d.ts.map +1 -1
  51. package/lib/browser/filesystem-frontend-contribution.js +63 -34
  52. package/lib/browser/filesystem-frontend-contribution.js.map +1 -1
  53. package/lib/browser/filesystem-save-resource-service.d.ts +1 -1
  54. package/lib/browser/filesystem-save-resource-service.d.ts.map +1 -1
  55. package/lib/browser/filesystem-save-resource-service.js +10 -17
  56. package/lib/browser/filesystem-save-resource-service.js.map +1 -1
  57. package/lib/browser/filesystem-watcher-error-handler.js +6 -14
  58. package/lib/browser/filesystem-watcher-error-handler.js.map +1 -1
  59. package/lib/browser/index.js +6 -15
  60. package/lib/browser/index.js.map +1 -1
  61. package/lib/browser/location/index.js +3 -12
  62. package/lib/browser/location/index.js.map +1 -1
  63. package/lib/browser/location/location-renderer.js +12 -23
  64. package/lib/browser/location/location-renderer.js.map +1 -1
  65. package/lib/browser/remote-file-service-contribution.js +4 -12
  66. package/lib/browser/remote-file-service-contribution.js.map +1 -1
  67. package/lib/browser-only/browser-only-filesystem-frontend-module.d.ts +4 -0
  68. package/lib/browser-only/browser-only-filesystem-frontend-module.d.ts.map +1 -0
  69. package/lib/browser-only/browser-only-filesystem-frontend-module.js +41 -0
  70. package/lib/browser-only/browser-only-filesystem-frontend-module.js.map +1 -0
  71. package/lib/browser-only/browser-only-filesystem-provider-server.d.ts +12 -0
  72. package/lib/browser-only/browser-only-filesystem-provider-server.d.ts.map +1 -0
  73. package/lib/browser-only/browser-only-filesystem-provider-server.js +40 -0
  74. package/lib/browser-only/browser-only-filesystem-provider-server.js.map +1 -0
  75. package/lib/browser-only/browserfs-filesystem-initialization.d.ts +13 -0
  76. package/lib/browser-only/browserfs-filesystem-initialization.d.ts.map +1 -0
  77. package/lib/browser-only/browserfs-filesystem-initialization.js +55 -0
  78. package/lib/browser-only/browserfs-filesystem-initialization.js.map +1 -0
  79. package/lib/browser-only/browserfs-filesystem-provider.d.ts +46 -0
  80. package/lib/browser-only/browserfs-filesystem-provider.d.ts.map +1 -0
  81. package/lib/browser-only/browserfs-filesystem-provider.js +440 -0
  82. package/lib/browser-only/browserfs-filesystem-provider.js.map +1 -0
  83. package/lib/common/files.d.ts +8 -0
  84. package/lib/common/files.d.ts.map +1 -1
  85. package/lib/common/files.js +9 -1
  86. package/lib/common/files.js.map +1 -1
  87. package/lib/common/index.js +3 -12
  88. package/lib/common/index.js.map +1 -1
  89. package/lib/common/remote-file-system-provider.d.ts +11 -2
  90. package/lib/common/remote-file-system-provider.d.ts.map +1 -1
  91. package/lib/common/remote-file-system-provider.js +46 -24
  92. package/lib/common/remote-file-system-provider.js.map +1 -1
  93. package/lib/electron-browser/file-dialog/electron-file-dialog-service.js +5 -13
  94. package/lib/electron-browser/file-dialog/electron-file-dialog-service.js.map +1 -1
  95. package/lib/electron-main/electron-api-main.js +2 -7
  96. package/lib/electron-main/electron-api-main.js.map +1 -1
  97. package/lib/node/disk-file-system-provider.d.ts.map +1 -1
  98. package/lib/node/disk-file-system-provider.js +20 -22
  99. package/lib/node/disk-file-system-provider.js.map +1 -1
  100. package/lib/node/disk-file-system-provider.spec.js +35 -4
  101. package/lib/node/disk-file-system-provider.spec.js.map +1 -1
  102. package/lib/node/download/directory-archiver.js +3 -8
  103. package/lib/node/download/directory-archiver.js.map +1 -1
  104. package/lib/node/download/directory-archiver.spec.js +1 -1
  105. package/lib/node/download/directory-archiver.spec.js.map +1 -1
  106. package/lib/node/download/file-download-cache.js +4 -12
  107. package/lib/node/download/file-download-cache.js.map +1 -1
  108. package/lib/node/download/file-download-endpoint.js +9 -17
  109. package/lib/node/download/file-download-endpoint.js.map +1 -1
  110. package/lib/node/download/file-download-handler.d.ts.map +1 -1
  111. package/lib/node/download/file-download-handler.js +17 -25
  112. package/lib/node/download/file-download-handler.js.map +1 -1
  113. package/lib/node/file-change-collection.spec.js +1 -1
  114. package/lib/node/file-change-collection.spec.js.map +1 -1
  115. package/lib/node/filesystem-watcher-client.js +6 -14
  116. package/lib/node/filesystem-watcher-client.js.map +1 -1
  117. package/lib/node/filesystem-watcher-dispatcher.js +2 -7
  118. package/lib/node/filesystem-watcher-dispatcher.js.map +1 -1
  119. package/lib/node/node-file-upload-service.js +2 -7
  120. package/lib/node/node-file-upload-service.js.map +1 -1
  121. package/lib/node/nsfw-watcher/nsfw-filesystem-service.js +1 -1
  122. package/lib/node/nsfw-watcher/nsfw-filesystem-service.js.map +1 -1
  123. package/package.json +9 -6
  124. package/src/browser/file-resource.ts +36 -7
  125. package/src/browser/file-service.ts +40 -13
  126. package/src/browser/file-upload-service.ts +4 -6
  127. package/src/browser/filesystem-frontend-contribution.ts +57 -14
  128. package/src/browser/filesystem-save-resource-service.ts +3 -2
  129. package/src/browser-only/browser-only-filesystem-frontend-module.ts +38 -0
  130. package/src/browser-only/browser-only-filesystem-provider-server.ts +32 -0
  131. package/src/browser-only/browserfs-filesystem-initialization.ts +61 -0
  132. package/src/browser-only/browserfs-filesystem-provider.ts +462 -0
  133. package/src/common/files.ts +13 -0
  134. package/src/common/remote-file-system-provider.ts +40 -2
  135. package/src/electron-browser/file-dialog/electron-file-dialog-service.ts +1 -1
  136. package/src/node/disk-file-system-provider.spec.ts +38 -5
  137. package/src/node/disk-file-system-provider.ts +9 -4
  138. package/src/node/download/directory-archiver.spec.ts +1 -1
  139. package/src/node/download/directory-archiver.ts +1 -1
  140. package/src/node/download/file-download-endpoint.ts +1 -1
  141. package/src/node/download/file-download-handler.ts +6 -6
  142. package/src/node/file-change-collection.spec.ts +1 -1
  143. package/src/node/nsfw-watcher/nsfw-filesystem-service.ts +1 -1
@@ -51,7 +51,7 @@ import {
51
51
  toFileOperationResult, toFileSystemProviderErrorCode,
52
52
  ResolveFileResult, ResolveFileResultWithMetadata,
53
53
  MoveFileOptions, CopyFileOptions, BaseStatWithMetadata, FileDeleteOptions, FileOperationOptions, hasAccessCapability, hasUpdateCapability,
54
- hasFileReadStreamCapability, FileSystemProviderWithFileReadStreamCapability
54
+ hasFileReadStreamCapability, FileSystemProviderWithFileReadStreamCapability, ReadOnlyMessageFileSystemProvider
55
55
  } from '../common/files';
56
56
  import { BinaryBuffer, BinaryBufferReadable, BinaryBufferReadableStream, BinaryBufferReadableBufferedStream, BinaryBufferWriteableStream } from '@theia/core/lib/common/buffer';
57
57
  import { ReadableStream, isReadableStream, isReadableBufferedStream, transform, consumeStream, peekStream, peekReadable, Readable } from '@theia/core/lib/common/stream';
@@ -68,6 +68,7 @@ import { readFileIntoStream } from '../common/io';
68
68
  import { FileSystemWatcherErrorHandler } from './filesystem-watcher-error-handler';
69
69
  import { FileSystemUtils } from '../common/filesystem-utils';
70
70
  import { nls } from '@theia/core';
71
+ import { MarkdownString } from '@theia/core/lib/common/markdown-rendering';
71
72
 
72
73
  export interface FileOperationParticipant {
73
74
 
@@ -235,6 +236,15 @@ export interface FileSystemProviderCapabilitiesChangeEvent {
235
236
  scheme: string;
236
237
  }
237
238
 
239
+ export interface FileSystemProviderReadOnlyMessageChangeEvent {
240
+ /** The affected file system provider for which this event was fired. */
241
+ provider: FileSystemProvider;
242
+ /** The uri for which the provider is registered */
243
+ scheme: string;
244
+ /** The new read only message */
245
+ message: MarkdownString | undefined;
246
+ }
247
+
238
248
  /**
239
249
  * Represents the `FileSystemProviderActivation` event.
240
250
  * This event is fired by the {@link FileService} if it wants to activate the
@@ -342,6 +352,9 @@ export class FileService {
342
352
  private onDidChangeFileSystemProviderCapabilitiesEmitter = new Emitter<FileSystemProviderCapabilitiesChangeEvent>();
343
353
  readonly onDidChangeFileSystemProviderCapabilities = this.onDidChangeFileSystemProviderCapabilitiesEmitter.event;
344
354
 
355
+ private onDidChangeFileSystemProviderReadOnlyMessageEmitter = new Emitter<FileSystemProviderReadOnlyMessageChangeEvent>();
356
+ readonly onDidChangeFileSystemProviderReadOnlyMessage = this.onDidChangeFileSystemProviderReadOnlyMessageEmitter.event;
357
+
345
358
  private readonly providers = new Map<string, FileSystemProvider>();
346
359
  private readonly activations = new Map<string, Promise<FileSystemProvider>>();
347
360
 
@@ -364,6 +377,9 @@ export class FileService {
364
377
  providerDisposables.push(provider.onDidChangeFile(changes => this.onDidFilesChangeEmitter.fire(new FileChangesEvent(changes))));
365
378
  providerDisposables.push(provider.onFileWatchError(() => this.handleFileWatchError()));
366
379
  providerDisposables.push(provider.onDidChangeCapabilities(() => this.onDidChangeFileSystemProviderCapabilitiesEmitter.fire({ provider, scheme })));
380
+ if (ReadOnlyMessageFileSystemProvider.is(provider)) {
381
+ providerDisposables.push(provider.onDidChangeReadOnlyMessage(message => this.onDidChangeFileSystemProviderReadOnlyMessageEmitter.fire({ provider, scheme, message })));
382
+ }
367
383
 
368
384
  return Disposable.create(() => {
369
385
  this.onDidChangeFileSystemProviderRegistrationsEmitter.fire({ added: false, scheme, provider });
@@ -413,6 +429,14 @@ export class FileService {
413
429
  return this.providers.has(resource.scheme);
414
430
  }
415
431
 
432
+ getReadOnlyMessage(resource: URI): MarkdownString | undefined {
433
+ const provider = this.providers.get(resource.scheme);
434
+ if (ReadOnlyMessageFileSystemProvider.is(provider)) {
435
+ return provider.readOnlyMessage;
436
+ }
437
+ return undefined;
438
+ }
439
+
416
440
  /**
417
441
  * Tests if the service (i.e the {@link FileSystemProvider} registered for the given uri scheme) provides the given capability.
418
442
  * @param resource `URI` of the resource to test.
@@ -694,12 +718,7 @@ export class FileService {
694
718
  async read(resource: URI, options?: ReadTextFileOptions): Promise<TextFileContent> {
695
719
  const [bufferStream, decoder] = await this.doRead(resource, {
696
720
  ...options,
697
- // optimization: since we know that the caller does not
698
- // care about buffering, we indicate this to the reader.
699
- // this reduces all the overhead the buffered reading
700
- // has (open, read, close) if the provider supports
701
- // unbuffered reading.
702
- preferUnbuffered: true
721
+ preferUnbuffered: this.shouldReadUnbuffered(options)
703
722
  });
704
723
 
705
724
  return {
@@ -888,17 +907,25 @@ export class FileService {
888
907
  options.mtime < stat.mtime && options.etag !== etag({ mtime: options.mtime /* not using stat.mtime for a reason, see above */, size: stat.size });
889
908
  }
890
909
 
910
+ protected shouldReadUnbuffered(options?: ReadFileOptions): boolean {
911
+ // optimization: since we know that the caller does not
912
+ // care about buffering, we indicate this to the reader.
913
+ // this reduces all the overhead the buffered reading
914
+ // has (open, read, close) if the provider supports
915
+ // unbuffered reading.
916
+ //
917
+ // However, if we read only part of the file we still
918
+ // want buffered reading as otherwise we need to read
919
+ // the whole file and cut out the specified part later.
920
+ return options?.position === undefined && options?.length === undefined;
921
+ }
922
+
891
923
  async readFile(resource: URI, options?: ReadFileOptions): Promise<FileContent> {
892
924
  const provider = await this.withReadProvider(resource);
893
925
 
894
926
  const stream = await this.doReadAsFileStream(provider, resource, {
895
927
  ...options,
896
- // optimization: since we know that the caller does not
897
- // care about buffering, we indicate this to the reader.
898
- // this reduces all the overhead the buffered reading
899
- // has (open, read, close) if the provider supports
900
- // unbuffered reading.
901
- preferUnbuffered: true
928
+ preferUnbuffered: this.shouldReadUnbuffered(options)
902
929
  });
903
930
 
904
931
  return {
@@ -33,13 +33,11 @@ import { nls } from '@theia/core/lib/common/nls';
33
33
 
34
34
  export const HTTP_UPLOAD_URL: string = new Endpoint({ path: HTTP_FILE_UPLOAD_PATH }).getRestUrl().toString(true);
35
35
 
36
- export interface CustomDataTransfer {
37
- values(): Iterable<CustomDataTransferItem>
38
- }
36
+ export type CustomDataTransfer = Iterable<readonly [string, CustomDataTransferItem]>;
39
37
 
40
38
  export interface CustomDataTransferItem {
41
- readonly id: string;
42
39
  asFile(): {
40
+ readonly id: string;
43
41
  readonly name: string;
44
42
  data(): Promise<Uint8Array>;
45
43
  } | undefined
@@ -420,10 +418,10 @@ export class FileUploadService {
420
418
  }
421
419
 
422
420
  protected async indexCustomDataTransfer(targetUri: URI, dataTransfer: CustomDataTransfer, context: FileUploadService.Context): Promise<void> {
423
- for (const item of dataTransfer.values()) {
421
+ for (const [_, item] of dataTransfer) {
424
422
  const fileInfo = item.asFile();
425
423
  if (fileInfo) {
426
- await this.indexFile(targetUri, new File([await fileInfo.data()], item.id), context);
424
+ await this.indexFile(targetUri, new File([await fileInfo.data()], fileInfo.id), context);
427
425
  }
428
426
  }
429
427
  }
@@ -14,27 +14,36 @@
14
14
  // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
15
  // *****************************************************************************
16
16
 
17
- import { injectable, inject } from '@theia/core/shared/inversify';
18
- import URI from '@theia/core/lib/common/uri';
19
- import { environment } from '@theia/core/shared/@theia/application-package/lib/environment';
20
- import { MaybePromise, SelectionService, isCancelled, Emitter } from '@theia/core/lib/common';
21
- import { Command, CommandContribution, CommandRegistry } from '@theia/core/lib/common/command';
17
+ import { nls } from '@theia/core';
22
18
  import {
23
- FrontendApplicationContribution, ApplicationShell,
24
- NavigatableWidget, NavigatableWidgetOptions,
25
- Saveable, WidgetManager, StatefulWidget, FrontendApplication, ExpandableTreeNode,
26
- CorePreferences,
19
+ ApplicationShell,
27
20
  CommonCommands,
21
+ CorePreferences,
22
+ ExpandableTreeNode,
23
+ FrontendApplication,
24
+ FrontendApplicationContribution,
25
+ NavigatableWidget, NavigatableWidgetOptions,
26
+ OpenerService,
27
+ Saveable,
28
+ StatefulWidget,
29
+ WidgetManager,
30
+ open
28
31
  } from '@theia/core/lib/browser';
29
32
  import { MimeService } from '@theia/core/lib/browser/mime-service';
30
33
  import { TreeWidgetSelection } from '@theia/core/lib/browser/tree/tree-widget-selection';
31
- import { FileSystemPreferences } from './filesystem-preferences';
34
+ import { Emitter, MaybePromise, SelectionService, isCancelled } from '@theia/core/lib/common';
35
+ import { Command, CommandContribution, CommandRegistry } from '@theia/core/lib/common/command';
36
+ import { Deferred } from '@theia/core/lib/common/promise-util';
37
+ import URI from '@theia/core/lib/common/uri';
38
+ import { environment } from '@theia/core/shared/@theia/application-package/lib/environment';
39
+ import { inject, injectable } from '@theia/core/shared/inversify';
40
+ import { UserWorkingDirectoryProvider } from '@theia/core/lib/browser/user-working-directory-provider';
41
+ import { FileChangeType, FileChangesEvent, FileOperation } from '../common/files';
42
+ import { FileDialogService, SaveFileDialogProps } from './file-dialog';
32
43
  import { FileSelection } from './file-selection';
33
- import { FileUploadService, FileUploadResult } from './file-upload-service';
34
44
  import { FileService, UserFileOperationEvent } from './file-service';
35
- import { FileChangesEvent, FileChangeType, FileOperation } from '../common/files';
36
- import { Deferred } from '@theia/core/lib/common/promise-util';
37
- import { nls } from '@theia/core';
45
+ import { FileUploadResult, FileUploadService } from './file-upload-service';
46
+ import { FileSystemPreferences } from './filesystem-preferences';
38
47
 
39
48
  export namespace FileSystemCommands {
40
49
 
@@ -78,6 +87,15 @@ export class FileSystemFrontendContribution implements FrontendApplicationContri
78
87
  @inject(FileService)
79
88
  protected readonly fileService: FileService;
80
89
 
90
+ @inject(FileDialogService)
91
+ protected readonly fileDialogService: FileDialogService;
92
+
93
+ @inject(OpenerService)
94
+ protected readonly openerService: OpenerService;
95
+
96
+ @inject(UserWorkingDirectoryProvider)
97
+ protected readonly workingDirectory: UserWorkingDirectoryProvider;
98
+
81
99
  protected onDidChangeEditorFileEmitter = new Emitter<{ editor: NavigatableWidget, type: FileChangeType }>();
82
100
  readonly onDidChangeEditorFile = this.onDidChangeEditorFileEmitter.event;
83
101
 
@@ -134,6 +152,11 @@ export class FileSystemFrontendContribution implements FrontendApplicationContri
134
152
  }
135
153
  }
136
154
  });
155
+ commands.registerCommand(CommonCommands.NEW_FILE, {
156
+ execute: (...args: unknown[]) => {
157
+ this.handleNewFileCommand(args);
158
+ }
159
+ });
137
160
  }
138
161
 
139
162
  protected canUpload({ fileStat }: FileSelection): boolean {
@@ -155,6 +178,26 @@ export class FileSystemFrontendContribution implements FrontendApplicationContri
155
178
  }
156
179
  }
157
180
 
181
+ /**
182
+ * Opens a save dialog to create a new file.
183
+ *
184
+ * @param args The first argument is the name of the new file. The second argument is the parent directory URI.
185
+ */
186
+ protected async handleNewFileCommand(args: unknown[]): Promise<void> {
187
+ const fileName = (args !== undefined && typeof args[0] === 'string') ? args[0] : undefined;
188
+ const title = nls.localizeByDefault('Create File');
189
+ const props: SaveFileDialogProps = { title, saveLabel: title, inputValue: fileName };
190
+
191
+ const dirUri = (args[1] instanceof URI) ? args[1] : await this.workingDirectory.getUserWorkingDir();
192
+ const directory = await this.fileService.resolve(dirUri);
193
+
194
+ const filePath = await this.fileDialogService.showSaveDialog(props, directory.isDirectory ? directory : undefined);
195
+ if (filePath) {
196
+ const file = await this.fileService.createFile(filePath);
197
+ open(this.openerService, file.resource);
198
+ }
199
+ }
200
+
158
201
  protected getSelection(...args: unknown[]): FileSelection | undefined {
159
202
  const { selection } = this.selectionService;
160
203
  return this.toSelection(args[0]) ?? (Array.isArray(selection) ? selection.find(FileSelection.is) : this.toSelection(selection));
@@ -47,7 +47,7 @@ export class FilesystemSaveResourceService extends SaveResourceService {
47
47
  /**
48
48
  * Save `sourceWidget` to a new file picked by the user.
49
49
  */
50
- override async saveAs(sourceWidget: Widget & SaveableSource & Navigatable, options?: SaveOptions): Promise<void> {
50
+ override async saveAs(sourceWidget: Widget & SaveableSource & Navigatable, options?: SaveOptions): Promise<URI | undefined> {
51
51
  let exist: boolean = false;
52
52
  let overwrite: boolean = false;
53
53
  let selected: URI | undefined;
@@ -68,10 +68,11 @@ export class FilesystemSaveResourceService extends SaveResourceService {
68
68
  }
69
69
  } while ((selected && exist && !overwrite) || (selected?.isEqual(uri) && !canSave));
70
70
  if (selected && selected.isEqual(uri)) {
71
- await this.save(sourceWidget, options);
71
+ return this.save(sourceWidget, options);
72
72
  } else if (selected) {
73
73
  try {
74
74
  await this.copyAndSave(sourceWidget, selected, overwrite);
75
+ return selected;
75
76
  } catch (e) {
76
77
  console.warn(e);
77
78
  }
@@ -0,0 +1,38 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { ContainerModule } from '@theia/core/shared/inversify';
18
+ import { FileSystemProvider } from '../common/files';
19
+ import { BrowserFSFileSystemProvider } from './browserfs-filesystem-provider';
20
+ import { RemoteFileSystemProvider, RemoteFileSystemServer } from '../common/remote-file-system-provider';
21
+ import { BrowserFSInitialization, DefaultBrowserFSInitialization } from './browserfs-filesystem-initialization';
22
+ import { BrowserOnlyFileSystemProviderServer } from './browser-only-filesystem-provider-server';
23
+
24
+ export default new ContainerModule((bind, _unbind, isBound, rebind) => {
25
+ bind(DefaultBrowserFSInitialization).toSelf();
26
+ bind(BrowserFSFileSystemProvider).toSelf();
27
+ bind(BrowserFSInitialization).toService(DefaultBrowserFSInitialization);
28
+ if (isBound(FileSystemProvider)) {
29
+ rebind(FileSystemProvider).to(BrowserFSFileSystemProvider).inSingletonScope();
30
+ } else {
31
+ bind(FileSystemProvider).to(BrowserFSFileSystemProvider).inSingletonScope();
32
+ }
33
+ if (isBound(RemoteFileSystemProvider)) {
34
+ rebind(RemoteFileSystemServer).to(BrowserOnlyFileSystemProviderServer).inSingletonScope();
35
+ } else {
36
+ bind(RemoteFileSystemServer).to(BrowserOnlyFileSystemProviderServer).inSingletonScope();
37
+ }
38
+ });
@@ -0,0 +1,32 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import { injectable } from '@theia/core/shared/inversify';
18
+ import { FileSystemProviderServer } from '../common/remote-file-system-provider';
19
+ import { Event } from '@theia/core';
20
+
21
+ /**
22
+ * Backend component.
23
+ *
24
+ * JSON-RPC server exposing a wrapped file system provider remotely.
25
+ */
26
+ @injectable()
27
+ export class BrowserOnlyFileSystemProviderServer extends FileSystemProviderServer {
28
+
29
+ // needed because users expect implicitly the RemoteFileSystemServer to be a RemoteFileSystemProxyFactory
30
+ onDidOpenConnection = Event.None;
31
+ onDidCloseConnection = Event.None;
32
+ }
@@ -0,0 +1,61 @@
1
+ // *****************************************************************************
2
+ // Copyright (C) 2023 EclipseSource and others.
3
+ //
4
+ // This program and the accompanying materials are made available under the
5
+ // terms of the Eclipse Public License v. 2.0 which is available at
6
+ // http://www.eclipse.org/legal/epl-2.0.
7
+ //
8
+ // This Source Code may also be made available under the following Secondary
9
+ // Licenses when the conditions for such availability set forth in the Eclipse
10
+ // Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ // with the GNU Classpath Exception which is available at
12
+ // https://www.gnu.org/software/classpath/license.html.
13
+ //
14
+ // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
15
+ // *****************************************************************************
16
+
17
+ import type { FSModule } from 'browserfs/dist/node/core/FS';
18
+ import type { BrowserFSFileSystemProvider } from './browserfs-filesystem-provider';
19
+ import { injectable } from '@theia/core/shared/inversify';
20
+ import { FileSystem, initialize } from 'browserfs';
21
+ import MountableFileSystem from 'browserfs/dist/node/backend/MountableFileSystem';
22
+
23
+ export const BrowserFSInitialization = Symbol('BrowserFSInitialization');
24
+ export interface BrowserFSInitialization {
25
+ createMountableFileSystem(): Promise<MountableFileSystem>
26
+ initializeFS: (fs: FSModule, provider: BrowserFSFileSystemProvider) => Promise<void>;
27
+ }
28
+
29
+ @injectable()
30
+ export class DefaultBrowserFSInitialization implements BrowserFSInitialization {
31
+
32
+ createMountableFileSystem(): Promise<MountableFileSystem> {
33
+ return new Promise(resolve => {
34
+ FileSystem.IndexedDB.Create({}, (e, persistedFS) => {
35
+ if (e) {
36
+ throw e;
37
+ }
38
+ if (!persistedFS) {
39
+ throw Error('Could not create filesystem');
40
+ }
41
+ FileSystem.MountableFileSystem.Create({
42
+ '/home': persistedFS
43
+
44
+ }, (error, mountableFS) => {
45
+ if (error) {
46
+ throw error;
47
+ }
48
+ if (!mountableFS) {
49
+ throw Error('Could not create filesystem');
50
+ }
51
+ initialize(mountableFS);
52
+ resolve(mountableFS);
53
+ });
54
+ });
55
+ });
56
+ }
57
+
58
+ async initializeFS(fs: FSModule, provider: BrowserFSFileSystemProvider): Promise<void> {
59
+
60
+ }
61
+ }