@tauri-apps/plugin-fs 3.0.0-alpha.1 → 3.0.0-alpha.3

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/README.md CHANGED
@@ -12,7 +12,7 @@ Access the file system.
12
12
 
13
13
  ## Install
14
14
 
15
- _This plugin requires a Rust version of at least **1.77.2**_
15
+ _This plugin requires a Rust version of at least **1.95**_
16
16
 
17
17
  There are three general methods of installation that we can recommend.
18
18
 
package/dist-js/index.cjs CHANGED
@@ -88,10 +88,16 @@ var core = require('@tauri-apps/api/core');
88
88
  *
89
89
  * @module
90
90
  */
91
+ /**
92
+ * Defines how the offset given to {@linkcode FileHandle.seek} is interpreted.
93
+ */
91
94
  exports.SeekMode = void 0;
92
95
  (function (SeekMode) {
96
+ /** The offset is relative to the start of the file. */
93
97
  SeekMode[SeekMode["Start"] = 0] = "Start";
98
+ /** The offset is relative to the current cursor position. */
94
99
  SeekMode[SeekMode["Current"] = 1] = "Current";
100
+ /** The offset is relative to the end of the file. */
95
101
  SeekMode[SeekMode["End"] = 2] = "End";
96
102
  })(exports.SeekMode || (exports.SeekMode = {}));
97
103
  function parseFileInfo(r) {
@@ -165,6 +171,8 @@ class FileHandle extends core.Resource {
165
171
  * await file.close();
166
172
  * ```
167
173
  *
174
+ * @param buffer The buffer the file contents are read into.
175
+ * @returns A promise resolving to the number of bytes read, or `null` when the end of the file was reached.
168
176
  * @since 2.0.0
169
177
  */
170
178
  async read(buffer) {
@@ -215,6 +223,9 @@ class FileHandle extends core.Resource {
215
223
  * await file.close();
216
224
  * ```
217
225
  *
226
+ * @param offset The number of bytes the cursor is moved by.
227
+ * @param whence Defines the position the `offset` is relative to.
228
+ * @returns A promise resolving to the new cursor position, relative to the start of the file.
218
229
  * @since 2.0.0
219
230
  */
220
231
  async seek(offset, whence) {
@@ -236,6 +247,7 @@ class FileHandle extends core.Resource {
236
247
  * await file.close();
237
248
  * ```
238
249
  *
250
+ * @returns A promise resolving to the metadata of this file.
239
251
  * @since 2.0.0
240
252
  */
241
253
  async stat() {
@@ -266,6 +278,7 @@ class FileHandle extends core.Resource {
266
278
  * await file.close();
267
279
  * ```
268
280
  *
281
+ * @param len The length the file is truncated or extended to, in bytes. When not provided the entire file contents are truncated.
269
282
  * @since 2.0.0
270
283
  */
271
284
  async truncate(len) {
@@ -292,6 +305,8 @@ class FileHandle extends core.Resource {
292
305
  * await file.close();
293
306
  * ```
294
307
  *
308
+ * @param data The bytes written to the file.
309
+ * @returns A promise resolving to the number of bytes written.
295
310
  * @since 2.0.0
296
311
  */
297
312
  async write(data) {
@@ -313,6 +328,9 @@ class FileHandle extends core.Resource {
313
328
  * await file.close();
314
329
  * ```
315
330
  *
331
+ * @param path The path of the file, relative to `options.baseDir` when it is provided.
332
+ * @param options Options defining the base directory of `path`.
333
+ * @returns A promise resolving to the handle of the created file.
316
334
  * @since 2.0.0
317
335
  */
318
336
  async function create(path, options) {
@@ -339,6 +357,9 @@ async function create(path, options) {
339
357
  * await file.close();
340
358
  * ```
341
359
  *
360
+ * @param path The path of the file, relative to `options.baseDir` when it is provided.
361
+ * @param options Options defining the base directory of `path` and how the file is opened.
362
+ * @returns A promise resolving to the handle of the open file.
342
363
  * @since 2.0.0
343
364
  */
344
365
  async function open(path, options) {
@@ -359,6 +380,9 @@ async function open(path, options) {
359
380
  * await copyFile('app.conf', 'app.conf.bk', { fromPathBaseDir: BaseDirectory.AppConfig, toPathBaseDir: BaseDirectory.AppConfig });
360
381
  * ```
361
382
  *
383
+ * @param fromPath The path of the file to copy from.
384
+ * @param toPath The path of the file to copy to.
385
+ * @param options Options defining the base directory of each path.
362
386
  * @since 2.0.0
363
387
  */
364
388
  async function copyFile(fromPath, toPath, options) {
@@ -380,6 +404,8 @@ async function copyFile(fromPath, toPath, options) {
380
404
  * await mkdir('users', { baseDir: BaseDirectory.AppLocalData });
381
405
  * ```
382
406
  *
407
+ * @param path The path of the directory to create.
408
+ * @param options Options defining the base directory of `path`, the directory permissions and whether intermediate directories are created.
383
409
  * @since 2.0.0
384
410
  */
385
411
  async function mkdir(path, options) {
@@ -397,20 +423,23 @@ async function mkdir(path, options) {
397
423
  * ```typescript
398
424
  * import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs';
399
425
  * import { join } from '@tauri-apps/api/path';
400
- * const dir = "users"
401
- * const entries = await readDir('users', { baseDir: BaseDirectory.AppLocalData });
402
- * processEntriesRecursively(dir, entries);
426
+ * const dir = 'users';
427
+ * const entries = await readDir(dir, { baseDir: BaseDirectory.AppLocalData });
428
+ * await processEntriesRecursively(dir, entries);
403
429
  * async function processEntriesRecursively(parent, entries) {
404
430
  * for (const entry of entries) {
405
431
  * console.log(`Entry: ${entry.name}`);
406
432
  * if (entry.isDirectory) {
407
- * const dir = await join(parent, entry.name);
408
- * processEntriesRecursively(dir, await readDir(dir, { baseDir: BaseDirectory.AppLocalData }))
433
+ * const entryPath = await join(parent, entry.name);
434
+ * await processEntriesRecursively(entryPath, await readDir(entryPath, { baseDir: BaseDirectory.AppLocalData }));
409
435
  * }
410
436
  * }
411
437
  * }
412
438
  * ```
413
439
  *
440
+ * @param path The path of the directory to read.
441
+ * @param options Options defining the base directory of `path`.
442
+ * @returns A promise resolving to the list of entries in the directory.
414
443
  * @since 2.0.0
415
444
  */
416
445
  async function readDir(path, options) {
@@ -431,6 +460,9 @@ async function readDir(path, options) {
431
460
  * const contents = await readFile('avatar.png', { baseDir: BaseDirectory.Resource });
432
461
  * ```
433
462
  *
463
+ * @param path The path of the file to read.
464
+ * @param options Options defining the base directory of `path`.
465
+ * @returns A promise resolving to the contents of the file as bytes.
434
466
  * @since 2.0.0
435
467
  */
436
468
  async function readFile(path, options) {
@@ -451,17 +483,13 @@ async function readFile(path, options) {
451
483
  * const contents = await readTextFile('app.conf', { baseDir: BaseDirectory.AppConfig });
452
484
  * ```
453
485
  *
486
+ * @param path The path of the file to read.
487
+ * @param options Options defining the base directory of `path` and the text encoding.
488
+ * @returns A promise resolving to the contents of the file as a string.
454
489
  * @since 2.0.0
455
490
  */
456
491
  async function readTextFile(path, options) {
457
- if (path instanceof URL && path.protocol !== 'file:') {
458
- throw new TypeError('Must be a file URL.');
459
- }
460
- const arr = await core.invoke('plugin:fs|read_text_file', {
461
- path: path instanceof URL ? path.toString() : path,
462
- options
463
- });
464
- const bytes = arr instanceof ArrayBuffer ? arr : Uint8Array.from(arr);
492
+ const bytes = await readFile(path, options);
465
493
  return new TextDecoder(options?.encoding ?? 'utf-8').decode(bytes);
466
494
  }
467
495
  /**
@@ -477,6 +505,9 @@ async function readTextFile(path, options) {
477
505
  * You could also call {@linkcode AsyncIterableIterator.next} to advance the
478
506
  * iterator so you can lazily read the next line whenever you want.
479
507
  *
508
+ * @param path The path of the file to read.
509
+ * @param options Options defining the base directory of `path` and the text encoding.
510
+ * @returns A promise resolving to an iterator over the lines of the file.
480
511
  * @since 2.0.0
481
512
  */
482
513
  async function readTextFileLines(path, options) {
@@ -497,7 +528,15 @@ async function readTextFileLines(path, options) {
497
528
  options: options != null ? { ...options, encoding } : undefined
498
529
  });
499
530
  }
500
- const arr = await core.invoke('plugin:fs|read_text_file_lines_next', { rid: this.rid });
531
+ let arr;
532
+ try {
533
+ arr = await core.invoke('plugin:fs|read_text_file_lines_next', { rid: this.rid });
534
+ }
535
+ catch (error) {
536
+ // the resource is closed on errors, the next iteration starts over
537
+ this.rid = null;
538
+ throw error;
539
+ }
501
540
  const bytes = arr instanceof ArrayBuffer ? new Uint8Array(arr) : Uint8Array.from(arr);
502
541
  // Rust side will never return an empty array for this command and
503
542
  // ensure there is at least one elements there.
@@ -516,6 +555,16 @@ async function readTextFileLines(path, options) {
516
555
  done
517
556
  };
518
557
  },
558
+ // called when a `for await` loop exits early (`break`, `return` or `throw`)
559
+ async return() {
560
+ if (this.rid !== null) {
561
+ const rid = this.rid;
562
+ this.rid = null;
563
+ // close the file, otherwise it stays open until the webview is destroyed
564
+ await new core.Resource(rid).close();
565
+ }
566
+ return { value: null, done: true };
567
+ },
519
568
  [Symbol.asyncIterator]() {
520
569
  return this;
521
570
  }
@@ -531,6 +580,8 @@ async function readTextFileLines(path, options) {
531
580
  * await remove('users', { baseDir: BaseDirectory.AppLocalData });
532
581
  * ```
533
582
  *
583
+ * @param path The path of the file or directory to remove.
584
+ * @param options Options defining the base directory of `path` and whether directories are removed recursively.
534
585
  * @since 2.0.0
535
586
  */
536
587
  async function remove(path, options) {
@@ -555,6 +606,9 @@ async function remove(path, options) {
555
606
  * await rename('avatar.png', 'deleted.png', { oldPathBaseDir: BaseDirectory.App, newPathBaseDir: BaseDirectory.AppLocalData });
556
607
  * ```
557
608
  *
609
+ * @param oldPath The path of the file or directory to rename.
610
+ * @param newPath The path the file or directory is renamed to.
611
+ * @param options Options defining the base directory of each path.
558
612
  * @since 2.0.0
559
613
  */
560
614
  async function rename(oldPath, newPath, options) {
@@ -579,6 +633,9 @@ async function rename(oldPath, newPath, options) {
579
633
  * console.log(fileInfo.isFile); // true
580
634
  * ```
581
635
  *
636
+ * @param path The path of the file or directory to inspect.
637
+ * @param options Options defining the base directory of `path`.
638
+ * @returns A promise resolving to the metadata of the file or directory.
582
639
  * @since 2.0.0
583
640
  */
584
641
  async function stat(path, options) {
@@ -600,6 +657,9 @@ async function stat(path, options) {
600
657
  * console.log(fileInfo.isFile); // true
601
658
  * ```
602
659
  *
660
+ * @param path The path of the file, directory or symlink to inspect.
661
+ * @param options Options defining the base directory of `path`.
662
+ * @returns A promise resolving to the metadata of the path itself.
603
663
  * @since 2.0.0
604
664
  */
605
665
  async function lstat(path, options) {
@@ -627,6 +687,9 @@ async function lstat(path, options) {
627
687
  * console.log(data); // "Hello W"
628
688
  * ```
629
689
  *
690
+ * @param path The path of the file to truncate or extend.
691
+ * @param len The length the file is resized to, in bytes. Defaults to `0`.
692
+ * @param options Options defining the base directory of `path`.
630
693
  * @since 2.0.0
631
694
  */
632
695
  async function truncate(path, len, options) {
@@ -650,6 +713,9 @@ async function truncate(path, len, options) {
650
713
  * await writeFile('file.txt', data, { baseDir: BaseDirectory.AppLocalData });
651
714
  * ```
652
715
  *
716
+ * @param path The path of the file to write to.
717
+ * @param data The bytes written to the file, either as a buffer or as a stream of chunks.
718
+ * @param options Options defining the base directory of `path` and how the file is opened.
653
719
  * @since 2.0.0
654
720
  */
655
721
  async function writeFile(path, data, options) {
@@ -661,7 +727,9 @@ async function writeFile(path, data, options) {
661
727
  read: false,
662
728
  create: true,
663
729
  write: true,
664
- ...options
730
+ ...options,
731
+ // overwrite the previous contents, like when writing a buffer
732
+ truncate: !options?.append
665
733
  });
666
734
  const reader = data.getReader();
667
735
  try {
@@ -687,27 +755,22 @@ async function writeFile(path, data, options) {
687
755
  }
688
756
  }
689
757
  /**
690
- * Writes UTF-8 string `data` to the given `path`, by default creating a new file if needed, else overwriting.
691
- @example
692
- * ```typescript
693
- * import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
694
- *
695
- * await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
696
- * ```
697
- *
698
- * @since 2.0.0
699
- */
758
+ * Writes UTF-8 string `data` to the given `path`, by default creating a new file if needed, else overwriting.
759
+ *
760
+ * @example
761
+ * ```typescript
762
+ * import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
763
+ *
764
+ * await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
765
+ * ```
766
+ *
767
+ * @param path The path of the file to write to.
768
+ * @param data The UTF-8 string written to the file.
769
+ * @param options Options defining the base directory of `path` and how the file is opened.
770
+ * @since 2.0.0
771
+ */
700
772
  async function writeTextFile(path, data, options) {
701
- if (path instanceof URL && path.protocol !== 'file:') {
702
- throw new TypeError('Must be a file URL.');
703
- }
704
- const encoder = new TextEncoder();
705
- await core.invoke('plugin:fs|write_text_file', encoder.encode(data), {
706
- headers: {
707
- path: encodeURIComponent(path instanceof URL ? path.toString() : path),
708
- options: JSON.stringify(options)
709
- }
710
- });
773
+ await writeFile(path, new TextEncoder().encode(data), options);
711
774
  }
712
775
  /**
713
776
  * Check if a path exists.
@@ -718,6 +781,9 @@ async function writeTextFile(path, data, options) {
718
781
  * await exists('avatar.png', { baseDir: BaseDirectory.AppData });
719
782
  * ```
720
783
  *
784
+ * @param path The path to check.
785
+ * @param options Options defining the base directory of `path`.
786
+ * @returns A promise resolving to `true` when the path exists, `false` otherwise.
721
787
  * @since 2.0.0
722
788
  */
723
789
  async function exists(path, options) {
@@ -729,6 +795,11 @@ async function exists(path, options) {
729
795
  options
730
796
  });
731
797
  }
798
+ /**
799
+ * A file system watcher. Call {@linkcode Watcher.close} to stop watching.
800
+ *
801
+ * @since 3.0.0
802
+ */
732
803
  class Watcher extends core.Resource {
733
804
  }
734
805
  async function watchInternal(paths, cb, options) {
@@ -745,15 +816,19 @@ async function watchInternal(paths, cb, options) {
745
816
  options,
746
817
  onEvent
747
818
  });
748
- const watcher = new Watcher(rid);
749
- return () => {
750
- void watcher.close();
751
- };
819
+ return new Watcher(rid);
752
820
  }
753
- // TODO: Return `Watcher` instead in v3
754
821
  /**
755
822
  * Watch changes (after a delay) on files or directories.
756
823
  *
824
+ * @example
825
+ * ```typescript
826
+ * import { watch, BaseDirectory } from '@tauri-apps/plugin-fs';
827
+ * const watcher = await watch('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
828
+ * // when you're done watching:
829
+ * await watcher.close();
830
+ * ```
831
+ *
757
832
  * @since 2.0.0
758
833
  */
759
834
  async function watch(paths, cb, options) {
@@ -762,10 +837,17 @@ async function watch(paths, cb, options) {
762
837
  ...options
763
838
  });
764
839
  }
765
- // TODO: Return `Watcher` instead in v3
766
840
  /**
767
841
  * Watch changes on files or directories.
768
842
  *
843
+ * @example
844
+ * ```typescript
845
+ * import { watchImmediate, BaseDirectory } from '@tauri-apps/plugin-fs';
846
+ * const watcher = await watchImmediate('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
847
+ * // when you're done watching:
848
+ * await watcher.close();
849
+ * ```
850
+ *
769
851
  * @since 2.0.0
770
852
  */
771
853
  async function watchImmediate(paths, cb, options) {
@@ -787,14 +869,18 @@ async function watchImmediate(paths, cb, options) {
787
869
  * console.log(dirSize); // 1024
788
870
  * ```
789
871
  *
872
+ * @param path The path of the file or directory to measure.
873
+ * @param options Options defining the base directory of `path` (since 2.6.0).
874
+ * @returns A promise resolving to the size in bytes.
790
875
  * @since 2.1.0
791
876
  */
792
- async function size(path) {
877
+ async function size(path, options) {
793
878
  if (path instanceof URL && path.protocol !== 'file:') {
794
879
  throw new TypeError('Must be a file URL.');
795
880
  }
796
881
  return await core.invoke('plugin:fs|size', {
797
- path: path instanceof URL ? path.toString() : path
882
+ path: path instanceof URL ? path.toString() : path,
883
+ options
798
884
  });
799
885
  }
800
886
  /**
@@ -821,6 +907,7 @@ async function size(path) {
821
907
  * // ... use the resource ...
822
908
  * ```
823
909
  *
910
+ * @param path The path or `file://` URL of the resource to start accessing.
824
911
  * @since 2.5.0
825
912
  */
826
913
  async function startAccessingSecurityScopedResource(path) {
@@ -852,6 +939,7 @@ async function startAccessingSecurityScopedResource(path) {
852
939
  * await stopAccessingSecurityScopedResource(filePath);
853
940
  * ```
854
941
  *
942
+ * @param path The path or `file://` URL of the resource to stop accessing.
855
943
  * @since 2.5.0
856
944
  */
857
945
  async function stopAccessingSecurityScopedResource(path) {
@@ -864,10 +952,11 @@ async function stopAccessingSecurityScopedResource(path) {
864
952
  }
865
953
 
866
954
  Object.defineProperty(exports, "BaseDirectory", {
867
- enumerable: true,
868
- get: function () { return path.BaseDirectory; }
955
+ enumerable: true,
956
+ get: function () { return path.BaseDirectory; }
869
957
  });
870
958
  exports.FileHandle = FileHandle;
959
+ exports.Watcher = Watcher;
871
960
  exports.copyFile = copyFile;
872
961
  exports.create = create;
873
962
  exports.exists = exists;