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

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) {
@@ -687,27 +753,22 @@ async function writeFile(path, data, options) {
687
753
  }
688
754
  }
689
755
  /**
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
- */
756
+ * Writes UTF-8 string `data` to the given `path`, by default creating a new file if needed, else overwriting.
757
+ *
758
+ * @example
759
+ * ```typescript
760
+ * import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
761
+ *
762
+ * await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
763
+ * ```
764
+ *
765
+ * @param path The path of the file to write to.
766
+ * @param data The UTF-8 string written to the file.
767
+ * @param options Options defining the base directory of `path` and how the file is opened.
768
+ * @since 2.0.0
769
+ */
700
770
  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
- });
771
+ await writeFile(path, new TextEncoder().encode(data), options);
711
772
  }
712
773
  /**
713
774
  * Check if a path exists.
@@ -718,6 +779,9 @@ async function writeTextFile(path, data, options) {
718
779
  * await exists('avatar.png', { baseDir: BaseDirectory.AppData });
719
780
  * ```
720
781
  *
782
+ * @param path The path to check.
783
+ * @param options Options defining the base directory of `path`.
784
+ * @returns A promise resolving to `true` when the path exists, `false` otherwise.
721
785
  * @since 2.0.0
722
786
  */
723
787
  async function exists(path, options) {
@@ -729,6 +793,11 @@ async function exists(path, options) {
729
793
  options
730
794
  });
731
795
  }
796
+ /**
797
+ * A file system watcher. Call {@linkcode Watcher.close} to stop watching.
798
+ *
799
+ * @since 3.0.0
800
+ */
732
801
  class Watcher extends core.Resource {
733
802
  }
734
803
  async function watchInternal(paths, cb, options) {
@@ -745,15 +814,19 @@ async function watchInternal(paths, cb, options) {
745
814
  options,
746
815
  onEvent
747
816
  });
748
- const watcher = new Watcher(rid);
749
- return () => {
750
- void watcher.close();
751
- };
817
+ return new Watcher(rid);
752
818
  }
753
- // TODO: Return `Watcher` instead in v3
754
819
  /**
755
820
  * Watch changes (after a delay) on files or directories.
756
821
  *
822
+ * @example
823
+ * ```typescript
824
+ * import { watch, BaseDirectory } from '@tauri-apps/plugin-fs';
825
+ * const watcher = await watch('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
826
+ * // when you're done watching:
827
+ * await watcher.close();
828
+ * ```
829
+ *
757
830
  * @since 2.0.0
758
831
  */
759
832
  async function watch(paths, cb, options) {
@@ -762,10 +835,17 @@ async function watch(paths, cb, options) {
762
835
  ...options
763
836
  });
764
837
  }
765
- // TODO: Return `Watcher` instead in v3
766
838
  /**
767
839
  * Watch changes on files or directories.
768
840
  *
841
+ * @example
842
+ * ```typescript
843
+ * import { watchImmediate, BaseDirectory } from '@tauri-apps/plugin-fs';
844
+ * const watcher = await watchImmediate('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
845
+ * // when you're done watching:
846
+ * await watcher.close();
847
+ * ```
848
+ *
769
849
  * @since 2.0.0
770
850
  */
771
851
  async function watchImmediate(paths, cb, options) {
@@ -787,14 +867,18 @@ async function watchImmediate(paths, cb, options) {
787
867
  * console.log(dirSize); // 1024
788
868
  * ```
789
869
  *
870
+ * @param path The path of the file or directory to measure.
871
+ * @param options Options defining the base directory of `path` (since 2.6.0).
872
+ * @returns A promise resolving to the size in bytes.
790
873
  * @since 2.1.0
791
874
  */
792
- async function size(path) {
875
+ async function size(path, options) {
793
876
  if (path instanceof URL && path.protocol !== 'file:') {
794
877
  throw new TypeError('Must be a file URL.');
795
878
  }
796
879
  return await core.invoke('plugin:fs|size', {
797
- path: path instanceof URL ? path.toString() : path
880
+ path: path instanceof URL ? path.toString() : path,
881
+ options
798
882
  });
799
883
  }
800
884
  /**
@@ -821,6 +905,7 @@ async function size(path) {
821
905
  * // ... use the resource ...
822
906
  * ```
823
907
  *
908
+ * @param path The path or `file://` URL of the resource to start accessing.
824
909
  * @since 2.5.0
825
910
  */
826
911
  async function startAccessingSecurityScopedResource(path) {
@@ -852,6 +937,7 @@ async function startAccessingSecurityScopedResource(path) {
852
937
  * await stopAccessingSecurityScopedResource(filePath);
853
938
  * ```
854
939
  *
940
+ * @param path The path or `file://` URL of the resource to stop accessing.
855
941
  * @since 2.5.0
856
942
  */
857
943
  async function stopAccessingSecurityScopedResource(path) {
@@ -864,10 +950,11 @@ async function stopAccessingSecurityScopedResource(path) {
864
950
  }
865
951
 
866
952
  Object.defineProperty(exports, "BaseDirectory", {
867
- enumerable: true,
868
- get: function () { return path.BaseDirectory; }
953
+ enumerable: true,
954
+ get: function () { return path.BaseDirectory; }
869
955
  });
870
956
  exports.FileHandle = FileHandle;
957
+ exports.Watcher = Watcher;
871
958
  exports.copyFile = copyFile;
872
959
  exports.create = create;
873
960
  exports.exists = exists;
@@ -82,9 +82,15 @@
82
82
  */
83
83
  import { BaseDirectory } from '@tauri-apps/api/path';
84
84
  import { Resource } from '@tauri-apps/api/core';
85
+ /**
86
+ * Defines how the offset given to {@linkcode FileHandle.seek} is interpreted.
87
+ */
85
88
  declare enum SeekMode {
89
+ /** The offset is relative to the start of the file. */
86
90
  Start = 0,
91
+ /** The offset is relative to the current cursor position. */
87
92
  Current = 1,
93
+ /** The offset is relative to the end of the file. */
88
94
  End = 2
89
95
  }
90
96
  /**
@@ -251,6 +257,8 @@ declare class FileHandle extends Resource {
251
257
  * await file.close();
252
258
  * ```
253
259
  *
260
+ * @param buffer The buffer the file contents are read into.
261
+ * @returns A promise resolving to the number of bytes read, or `null` when the end of the file was reached.
254
262
  * @since 2.0.0
255
263
  */
256
264
  read(buffer: Uint8Array): Promise<number | null>;
@@ -284,6 +292,9 @@ declare class FileHandle extends Resource {
284
292
  * await file.close();
285
293
  * ```
286
294
  *
295
+ * @param offset The number of bytes the cursor is moved by.
296
+ * @param whence Defines the position the `offset` is relative to.
297
+ * @returns A promise resolving to the new cursor position, relative to the start of the file.
287
298
  * @since 2.0.0
288
299
  */
289
300
  seek(offset: number, whence: SeekMode): Promise<number>;
@@ -299,6 +310,7 @@ declare class FileHandle extends Resource {
299
310
  * await file.close();
300
311
  * ```
301
312
  *
313
+ * @returns A promise resolving to the metadata of this file.
302
314
  * @since 2.0.0
303
315
  */
304
316
  stat(): Promise<FileInfo>;
@@ -324,6 +336,7 @@ declare class FileHandle extends Resource {
324
336
  * await file.close();
325
337
  * ```
326
338
  *
339
+ * @param len The length the file is truncated or extended to, in bytes. When not provided the entire file contents are truncated.
327
340
  * @since 2.0.0
328
341
  */
329
342
  truncate(len?: number): Promise<void>;
@@ -345,11 +358,15 @@ declare class FileHandle extends Resource {
345
358
  * await file.close();
346
359
  * ```
347
360
  *
361
+ * @param data The bytes written to the file.
362
+ * @returns A promise resolving to the number of bytes written.
348
363
  * @since 2.0.0
349
364
  */
350
365
  write(data: Uint8Array): Promise<number>;
351
366
  }
352
367
  /**
368
+ * Options for the `create` function, which creates or truncates a file.
369
+ *
353
370
  * @since 2.0.0
354
371
  */
355
372
  interface CreateOptions {
@@ -368,10 +385,15 @@ interface CreateOptions {
368
385
  * await file.close();
369
386
  * ```
370
387
  *
388
+ * @param path The path of the file, relative to `options.baseDir` when it is provided.
389
+ * @param options Options defining the base directory of `path`.
390
+ * @returns A promise resolving to the handle of the created file.
371
391
  * @since 2.0.0
372
392
  */
373
393
  declare function create(path: string | URL, options?: CreateOptions): Promise<FileHandle>;
374
394
  /**
395
+ * Options for the `open` function, defining how the file is opened and which operations are allowed on it.
396
+ *
375
397
  * @since 2.0.0
376
398
  */
377
399
  interface OpenOptions {
@@ -437,10 +459,15 @@ interface OpenOptions {
437
459
  * await file.close();
438
460
  * ```
439
461
  *
462
+ * @param path The path of the file, relative to `options.baseDir` when it is provided.
463
+ * @param options Options defining the base directory of `path` and how the file is opened.
464
+ * @returns A promise resolving to the handle of the open file.
440
465
  * @since 2.0.0
441
466
  */
442
467
  declare function open(path: string | URL, options?: OpenOptions): Promise<FileHandle>;
443
468
  /**
469
+ * Options for the `copyFile` function, defining the base directory of each path.
470
+ *
444
471
  * @since 2.0.0
445
472
  */
446
473
  interface CopyFileOptions {
@@ -457,10 +484,15 @@ interface CopyFileOptions {
457
484
  * await copyFile('app.conf', 'app.conf.bk', { fromPathBaseDir: BaseDirectory.AppConfig, toPathBaseDir: BaseDirectory.AppConfig });
458
485
  * ```
459
486
  *
487
+ * @param fromPath The path of the file to copy from.
488
+ * @param toPath The path of the file to copy to.
489
+ * @param options Options defining the base directory of each path.
460
490
  * @since 2.0.0
461
491
  */
462
492
  declare function copyFile(fromPath: string | URL, toPath: string | URL, options?: CopyFileOptions): Promise<void>;
463
493
  /**
494
+ * Options for the `mkdir` function, which creates a directory.
495
+ *
464
496
  * @since 2.0.0
465
497
  */
466
498
  interface MkdirOptions {
@@ -481,10 +513,14 @@ interface MkdirOptions {
481
513
  * await mkdir('users', { baseDir: BaseDirectory.AppLocalData });
482
514
  * ```
483
515
  *
516
+ * @param path The path of the directory to create.
517
+ * @param options Options defining the base directory of `path`, the directory permissions and whether intermediate directories are created.
484
518
  * @since 2.0.0
485
519
  */
486
520
  declare function mkdir(path: string | URL, options?: MkdirOptions): Promise<void>;
487
521
  /**
522
+ * Options for the `readDir` function, which lists the entries of a directory.
523
+ *
488
524
  * @since 2.0.0
489
525
  */
490
526
  interface ReadDirOptions {
@@ -514,24 +550,29 @@ interface DirEntry {
514
550
  * ```typescript
515
551
  * import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs';
516
552
  * import { join } from '@tauri-apps/api/path';
517
- * const dir = "users"
518
- * const entries = await readDir('users', { baseDir: BaseDirectory.AppLocalData });
519
- * processEntriesRecursively(dir, entries);
553
+ * const dir = 'users';
554
+ * const entries = await readDir(dir, { baseDir: BaseDirectory.AppLocalData });
555
+ * await processEntriesRecursively(dir, entries);
520
556
  * async function processEntriesRecursively(parent, entries) {
521
557
  * for (const entry of entries) {
522
558
  * console.log(`Entry: ${entry.name}`);
523
559
  * if (entry.isDirectory) {
524
- * const dir = await join(parent, entry.name);
525
- * processEntriesRecursively(dir, await readDir(dir, { baseDir: BaseDirectory.AppLocalData }))
560
+ * const entryPath = await join(parent, entry.name);
561
+ * await processEntriesRecursively(entryPath, await readDir(entryPath, { baseDir: BaseDirectory.AppLocalData }));
526
562
  * }
527
563
  * }
528
564
  * }
529
565
  * ```
530
566
  *
567
+ * @param path The path of the directory to read.
568
+ * @param options Options defining the base directory of `path`.
569
+ * @returns A promise resolving to the list of entries in the directory.
531
570
  * @since 2.0.0
532
571
  */
533
572
  declare function readDir(path: string | URL, options?: ReadDirOptions): Promise<DirEntry[]>;
534
573
  /**
574
+ * Options for the functions that read a file, such as `readFile` and `readTextFile`.
575
+ *
535
576
  * @since 2.0.0
536
577
  */
537
578
  interface ReadFileOptions {
@@ -549,6 +590,9 @@ interface ReadFileOptions {
549
590
  * const contents = await readFile('avatar.png', { baseDir: BaseDirectory.Resource });
550
591
  * ```
551
592
  *
593
+ * @param path The path of the file to read.
594
+ * @param options Options defining the base directory of `path`.
595
+ * @returns A promise resolving to the contents of the file as bytes.
552
596
  * @since 2.0.0
553
597
  */
554
598
  declare function readFile(path: string | URL, options?: ReadFileOptions): Promise<Uint8Array<ArrayBuffer>>;
@@ -560,6 +604,9 @@ declare function readFile(path: string | URL, options?: ReadFileOptions): Promis
560
604
  * const contents = await readTextFile('app.conf', { baseDir: BaseDirectory.AppConfig });
561
605
  * ```
562
606
  *
607
+ * @param path The path of the file to read.
608
+ * @param options Options defining the base directory of `path` and the text encoding.
609
+ * @returns A promise resolving to the contents of the file as a string.
563
610
  * @since 2.0.0
564
611
  */
565
612
  declare function readTextFile(path: string | URL, options?: ReadFileOptions): Promise<string>;
@@ -576,10 +623,15 @@ declare function readTextFile(path: string | URL, options?: ReadFileOptions): Pr
576
623
  * You could also call {@linkcode AsyncIterableIterator.next} to advance the
577
624
  * iterator so you can lazily read the next line whenever you want.
578
625
  *
626
+ * @param path The path of the file to read.
627
+ * @param options Options defining the base directory of `path` and the text encoding.
628
+ * @returns A promise resolving to an iterator over the lines of the file.
579
629
  * @since 2.0.0
580
630
  */
581
631
  declare function readTextFileLines(path: string | URL, options?: ReadFileOptions): Promise<AsyncIterableIterator<string>>;
582
632
  /**
633
+ * Options for the `remove` function, which deletes a file or a directory.
634
+ *
583
635
  * @since 2.0.0
584
636
  */
585
637
  interface RemoveOptions {
@@ -598,10 +650,14 @@ interface RemoveOptions {
598
650
  * await remove('users', { baseDir: BaseDirectory.AppLocalData });
599
651
  * ```
600
652
  *
653
+ * @param path The path of the file or directory to remove.
654
+ * @param options Options defining the base directory of `path` and whether directories are removed recursively.
601
655
  * @since 2.0.0
602
656
  */
603
657
  declare function remove(path: string | URL, options?: RemoveOptions): Promise<void>;
604
658
  /**
659
+ * Options for the `rename` function, defining the base directory of each path.
660
+ *
605
661
  * @since 2.0.0
606
662
  */
607
663
  interface RenameOptions {
@@ -623,10 +679,15 @@ interface RenameOptions {
623
679
  * await rename('avatar.png', 'deleted.png', { oldPathBaseDir: BaseDirectory.App, newPathBaseDir: BaseDirectory.AppLocalData });
624
680
  * ```
625
681
  *
682
+ * @param oldPath The path of the file or directory to rename.
683
+ * @param newPath The path the file or directory is renamed to.
684
+ * @param options Options defining the base directory of each path.
626
685
  * @since 2.0.0
627
686
  */
628
687
  declare function rename(oldPath: string | URL, newPath: string | URL, options?: RenameOptions): Promise<void>;
629
688
  /**
689
+ * Options for the `stat` and `lstat` functions, which read the metadata of a path.
690
+ *
630
691
  * @since 2.0.0
631
692
  */
632
693
  interface StatOptions {
@@ -644,6 +705,9 @@ interface StatOptions {
644
705
  * console.log(fileInfo.isFile); // true
645
706
  * ```
646
707
  *
708
+ * @param path The path of the file or directory to inspect.
709
+ * @param options Options defining the base directory of `path`.
710
+ * @returns A promise resolving to the metadata of the file or directory.
647
711
  * @since 2.0.0
648
712
  */
649
713
  declare function stat(path: string | URL, options?: StatOptions): Promise<FileInfo>;
@@ -659,10 +723,15 @@ declare function stat(path: string | URL, options?: StatOptions): Promise<FileIn
659
723
  * console.log(fileInfo.isFile); // true
660
724
  * ```
661
725
  *
726
+ * @param path The path of the file, directory or symlink to inspect.
727
+ * @param options Options defining the base directory of `path`.
728
+ * @returns A promise resolving to the metadata of the path itself.
662
729
  * @since 2.0.0
663
730
  */
664
731
  declare function lstat(path: string | URL, options?: StatOptions): Promise<FileInfo>;
665
732
  /**
733
+ * Options for the `truncate` function, which truncates or extends a file.
734
+ *
666
735
  * @since 2.0.0
667
736
  */
668
737
  interface TruncateOptions {
@@ -687,10 +756,15 @@ interface TruncateOptions {
687
756
  * console.log(data); // "Hello W"
688
757
  * ```
689
758
  *
759
+ * @param path The path of the file to truncate or extend.
760
+ * @param len The length the file is resized to, in bytes. Defaults to `0`.
761
+ * @param options Options defining the base directory of `path`.
690
762
  * @since 2.0.0
691
763
  */
692
764
  declare function truncate(path: string | URL, len?: number, options?: TruncateOptions): Promise<void>;
693
765
  /**
766
+ * Options for the `writeFile` and `writeTextFile` functions, defining how the file is opened before writing to it.
767
+ *
694
768
  * @since 2.0.0
695
769
  */
696
770
  interface WriteFileOptions {
@@ -716,22 +790,31 @@ interface WriteFileOptions {
716
790
  * await writeFile('file.txt', data, { baseDir: BaseDirectory.AppLocalData });
717
791
  * ```
718
792
  *
793
+ * @param path The path of the file to write to.
794
+ * @param data The bytes written to the file, either as a buffer or as a stream of chunks.
795
+ * @param options Options defining the base directory of `path` and how the file is opened.
719
796
  * @since 2.0.0
720
797
  */
721
798
  declare function writeFile(path: string | URL, data: Uint8Array | ReadableStream<Uint8Array>, options?: WriteFileOptions): Promise<void>;
722
799
  /**
723
- * Writes UTF-8 string `data` to the given `path`, by default creating a new file if needed, else overwriting.
724
- @example
725
- * ```typescript
726
- * import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
727
- *
728
- * await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
729
- * ```
730
- *
731
- * @since 2.0.0
732
- */
800
+ * Writes UTF-8 string `data` to the given `path`, by default creating a new file if needed, else overwriting.
801
+ *
802
+ * @example
803
+ * ```typescript
804
+ * import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
805
+ *
806
+ * await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
807
+ * ```
808
+ *
809
+ * @param path The path of the file to write to.
810
+ * @param data The UTF-8 string written to the file.
811
+ * @param options Options defining the base directory of `path` and how the file is opened.
812
+ * @since 2.0.0
813
+ */
733
814
  declare function writeTextFile(path: string | URL, data: string, options?: WriteFileOptions): Promise<void>;
734
815
  /**
816
+ * Options for the `exists` function, which checks whether a path exists.
817
+ *
735
818
  * @since 2.0.0
736
819
  */
737
820
  interface ExistsOptions {
@@ -747,10 +830,15 @@ interface ExistsOptions {
747
830
  * await exists('avatar.png', { baseDir: BaseDirectory.AppData });
748
831
  * ```
749
832
  *
833
+ * @param path The path to check.
834
+ * @param options Options defining the base directory of `path`.
835
+ * @returns A promise resolving to `true` when the path exists, `false` otherwise.
750
836
  * @since 2.0.0
751
837
  */
752
838
  declare function exists(path: string | URL, options?: ExistsOptions): Promise<boolean>;
753
839
  /**
840
+ * Options for the `watchImmediate` function, which reports file system changes as they happen.
841
+ *
754
842
  * @since 2.0.0
755
843
  */
756
844
  interface WatchOptions {
@@ -760,33 +848,78 @@ interface WatchOptions {
760
848
  baseDir?: BaseDirectory;
761
849
  }
762
850
  /**
851
+ * Options for the `watch` function, which reports file system changes after a debounce delay.
852
+ *
763
853
  * @since 2.0.0
764
854
  */
765
855
  interface DebouncedWatchOptions extends WatchOptions {
766
- /** Debounce delay */
856
+ /**
857
+ * The debounce delay in milliseconds. Changes that happen within this
858
+ * window are grouped and reported together. Defaults to `2000`.
859
+ */
767
860
  delayMs?: number;
768
861
  }
769
862
  /**
863
+ * Additional attributes of a {@linkcode WatchEvent}.
864
+ *
865
+ * @since 3.0.0
866
+ */
867
+ interface WatchEventAttributes {
868
+ /** Tracker ID that groups related events, e.g. both sides of a rename. */
869
+ tracker?: number;
870
+ /**
871
+ * `rescan` means some events may have been missed, so any file or folder might have been modified.
872
+ */
873
+ flag?: 'rescan';
874
+ /** Short string identifying the details of an `other` event. */
875
+ info?: string;
876
+ /** Short string identifying the backend that generated the event. */
877
+ source?: string;
878
+ }
879
+ /**
880
+ * A file system event.
881
+ *
882
+ * The event kind is flattened into the event: `type` is the top-level kind and,
883
+ * for `access`, `create`, `modify` and `remove` events, `kind` (and `mode` when available)
884
+ * refines it.
885
+ *
886
+ * @example
887
+ * ```typescript
888
+ * import { watch } from '@tauri-apps/plugin-fs';
889
+ * await watch('/path/to/file', (event) => {
890
+ * if (event.type === 'modify' && event.kind === 'data') {
891
+ * console.log('data changed', event.paths, event.mode);
892
+ * }
893
+ * });
894
+ * ```
895
+ *
770
896
  * @since 2.0.0
771
897
  */
772
- interface WatchEvent {
773
- type: WatchEventKind;
898
+ type WatchEvent = WatchEventKind & {
774
899
  paths: string[];
775
- attrs: unknown;
776
- }
900
+ attrs: WatchEventAttributes;
901
+ };
777
902
  /**
903
+ * The kind of file system change described by a `WatchEvent`.
904
+ *
778
905
  * @since 2.0.0
779
906
  */
780
- type WatchEventKind = 'any' | {
781
- access: WatchEventKindAccess;
782
- } | {
783
- create: WatchEventKindCreate;
784
- } | {
785
- modify: WatchEventKindModify;
786
- } | {
787
- remove: WatchEventKindRemove;
788
- } | 'other';
907
+ type WatchEventKind = {
908
+ type: 'any';
909
+ } | ({
910
+ type: 'access';
911
+ } & WatchEventKindAccess) | ({
912
+ type: 'create';
913
+ } & WatchEventKindCreate) | ({
914
+ type: 'modify';
915
+ } & WatchEventKindModify) | ({
916
+ type: 'remove';
917
+ } & WatchEventKindRemove) | {
918
+ type: 'other';
919
+ };
789
920
  /**
921
+ * Describes how a file or directory was accessed.
922
+ *
790
923
  * @since 2.0.0
791
924
  */
792
925
  type WatchEventKindAccess = {
@@ -801,6 +934,8 @@ type WatchEventKindAccess = {
801
934
  kind: 'other';
802
935
  };
803
936
  /**
937
+ * Describes which kind of entry was created.
938
+ *
804
939
  * @since 2.0.0
805
940
  */
806
941
  type WatchEventKindCreate = {
@@ -813,6 +948,8 @@ type WatchEventKindCreate = {
813
948
  kind: 'other';
814
949
  };
815
950
  /**
951
+ * Describes what was modified on a file or directory.
952
+ *
816
953
  * @since 2.0.0
817
954
  */
818
955
  type WatchEventKindModify = {
@@ -830,6 +967,8 @@ type WatchEventKindModify = {
830
967
  kind: 'other';
831
968
  };
832
969
  /**
970
+ * Describes which kind of entry was removed.
971
+ *
833
972
  * @since 2.0.0
834
973
  */
835
974
  type WatchEventKindRemove = {
@@ -842,21 +981,49 @@ type WatchEventKindRemove = {
842
981
  kind: 'other';
843
982
  };
844
983
  /**
845
- * @since 2.0.0
984
+ * A file system watcher. Call {@linkcode Watcher.close} to stop watching.
985
+ *
986
+ * @since 3.0.0
846
987
  */
847
- type UnwatchFn = () => void;
988
+ declare class Watcher extends Resource {
989
+ }
848
990
  /**
849
991
  * Watch changes (after a delay) on files or directories.
850
992
  *
993
+ * @example
994
+ * ```typescript
995
+ * import { watch, BaseDirectory } from '@tauri-apps/plugin-fs';
996
+ * const watcher = await watch('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
997
+ * // when you're done watching:
998
+ * await watcher.close();
999
+ * ```
1000
+ *
851
1001
  * @since 2.0.0
852
1002
  */
853
- declare function watch(paths: string | string[] | URL | URL[], cb: (event: WatchEvent) => void, options?: DebouncedWatchOptions): Promise<UnwatchFn>;
1003
+ declare function watch(paths: string | string[] | URL | URL[], cb: (event: WatchEvent) => void, options?: DebouncedWatchOptions): Promise<Watcher>;
854
1004
  /**
855
1005
  * Watch changes on files or directories.
856
1006
  *
1007
+ * @example
1008
+ * ```typescript
1009
+ * import { watchImmediate, BaseDirectory } from '@tauri-apps/plugin-fs';
1010
+ * const watcher = await watchImmediate('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
1011
+ * // when you're done watching:
1012
+ * await watcher.close();
1013
+ * ```
1014
+ *
857
1015
  * @since 2.0.0
858
1016
  */
859
- declare function watchImmediate(paths: string | string[] | URL | URL[], cb: (event: WatchEvent) => void, options?: WatchOptions): Promise<UnwatchFn>;
1017
+ declare function watchImmediate(paths: string | string[] | URL | URL[], cb: (event: WatchEvent) => void, options?: WatchOptions): Promise<Watcher>;
1018
+ /**
1019
+ * Options for the `size` function.
1020
+ *
1021
+ * @since 2.6.0
1022
+ */
1023
+ interface SizeOptions {
1024
+ /** Base directory for `path`. */
1025
+ baseDir?: BaseDirectory;
1026
+ }
860
1027
  /**
861
1028
  * Get the size of a file or directory. For files, the `stat` functions can be used as well.
862
1029
  *
@@ -870,9 +1037,12 @@ declare function watchImmediate(paths: string | string[] | URL | URL[], cb: (eve
870
1037
  * console.log(dirSize); // 1024
871
1038
  * ```
872
1039
  *
1040
+ * @param path The path of the file or directory to measure.
1041
+ * @param options Options defining the base directory of `path` (since 2.6.0).
1042
+ * @returns A promise resolving to the size in bytes.
873
1043
  * @since 2.1.0
874
1044
  */
875
- declare function size(path: string | URL): Promise<number>;
1045
+ declare function size(path: string | URL, options?: SizeOptions): Promise<number>;
876
1046
  /**
877
1047
  * Starts accessing a security-scoped resource for the given file URL.
878
1048
  * This should be called when you're accessing a file that was opened
@@ -897,6 +1067,7 @@ declare function size(path: string | URL): Promise<number>;
897
1067
  * // ... use the resource ...
898
1068
  * ```
899
1069
  *
1070
+ * @param path The path or `file://` URL of the resource to start accessing.
900
1071
  * @since 2.5.0
901
1072
  */
902
1073
  declare function startAccessingSecurityScopedResource(path: string | URL): Promise<void>;
@@ -921,8 +1092,9 @@ declare function startAccessingSecurityScopedResource(path: string | URL): Promi
921
1092
  * await stopAccessingSecurityScopedResource(filePath);
922
1093
  * ```
923
1094
  *
1095
+ * @param path The path or `file://` URL of the resource to stop accessing.
924
1096
  * @since 2.5.0
925
1097
  */
926
1098
  declare function stopAccessingSecurityScopedResource(path: string | URL): Promise<void>;
927
- export type { CreateOptions, OpenOptions, CopyFileOptions, MkdirOptions, DirEntry, ReadDirOptions, ReadFileOptions, RemoveOptions, RenameOptions, StatOptions, TruncateOptions, WriteFileOptions, ExistsOptions, FileInfo, WatchOptions, DebouncedWatchOptions, WatchEvent, WatchEventKind, WatchEventKindAccess, WatchEventKindCreate, WatchEventKindModify, WatchEventKindRemove, UnwatchFn };
928
- export { BaseDirectory, FileHandle, create, open, copyFile, mkdir, readDir, readFile, readTextFile, readTextFileLines, remove, rename, SeekMode, stat, lstat, truncate, writeFile, writeTextFile, exists, watch, watchImmediate, size, startAccessingSecurityScopedResource, stopAccessingSecurityScopedResource };
1099
+ export type { CreateOptions, OpenOptions, CopyFileOptions, MkdirOptions, DirEntry, ReadDirOptions, ReadFileOptions, RemoveOptions, RenameOptions, StatOptions, TruncateOptions, WriteFileOptions, ExistsOptions, SizeOptions, FileInfo, WatchOptions, DebouncedWatchOptions, WatchEvent, WatchEventAttributes, WatchEventKind, WatchEventKindAccess, WatchEventKindCreate, WatchEventKindModify, WatchEventKindRemove };
1100
+ export { BaseDirectory, FileHandle, Watcher, create, open, copyFile, mkdir, readDir, readFile, readTextFile, readTextFileLines, remove, rename, SeekMode, stat, lstat, truncate, writeFile, writeTextFile, exists, watch, watchImmediate, size, startAccessingSecurityScopedResource, stopAccessingSecurityScopedResource };
package/dist-js/index.js CHANGED
@@ -86,10 +86,16 @@ import { Resource, invoke, Channel } from '@tauri-apps/api/core';
86
86
  *
87
87
  * @module
88
88
  */
89
+ /**
90
+ * Defines how the offset given to {@linkcode FileHandle.seek} is interpreted.
91
+ */
89
92
  var SeekMode;
90
93
  (function (SeekMode) {
94
+ /** The offset is relative to the start of the file. */
91
95
  SeekMode[SeekMode["Start"] = 0] = "Start";
96
+ /** The offset is relative to the current cursor position. */
92
97
  SeekMode[SeekMode["Current"] = 1] = "Current";
98
+ /** The offset is relative to the end of the file. */
93
99
  SeekMode[SeekMode["End"] = 2] = "End";
94
100
  })(SeekMode || (SeekMode = {}));
95
101
  function parseFileInfo(r) {
@@ -163,6 +169,8 @@ class FileHandle extends Resource {
163
169
  * await file.close();
164
170
  * ```
165
171
  *
172
+ * @param buffer The buffer the file contents are read into.
173
+ * @returns A promise resolving to the number of bytes read, or `null` when the end of the file was reached.
166
174
  * @since 2.0.0
167
175
  */
168
176
  async read(buffer) {
@@ -213,6 +221,9 @@ class FileHandle extends Resource {
213
221
  * await file.close();
214
222
  * ```
215
223
  *
224
+ * @param offset The number of bytes the cursor is moved by.
225
+ * @param whence Defines the position the `offset` is relative to.
226
+ * @returns A promise resolving to the new cursor position, relative to the start of the file.
216
227
  * @since 2.0.0
217
228
  */
218
229
  async seek(offset, whence) {
@@ -234,6 +245,7 @@ class FileHandle extends Resource {
234
245
  * await file.close();
235
246
  * ```
236
247
  *
248
+ * @returns A promise resolving to the metadata of this file.
237
249
  * @since 2.0.0
238
250
  */
239
251
  async stat() {
@@ -264,6 +276,7 @@ class FileHandle extends Resource {
264
276
  * await file.close();
265
277
  * ```
266
278
  *
279
+ * @param len The length the file is truncated or extended to, in bytes. When not provided the entire file contents are truncated.
267
280
  * @since 2.0.0
268
281
  */
269
282
  async truncate(len) {
@@ -290,6 +303,8 @@ class FileHandle extends Resource {
290
303
  * await file.close();
291
304
  * ```
292
305
  *
306
+ * @param data The bytes written to the file.
307
+ * @returns A promise resolving to the number of bytes written.
293
308
  * @since 2.0.0
294
309
  */
295
310
  async write(data) {
@@ -311,6 +326,9 @@ class FileHandle extends Resource {
311
326
  * await file.close();
312
327
  * ```
313
328
  *
329
+ * @param path The path of the file, relative to `options.baseDir` when it is provided.
330
+ * @param options Options defining the base directory of `path`.
331
+ * @returns A promise resolving to the handle of the created file.
314
332
  * @since 2.0.0
315
333
  */
316
334
  async function create(path, options) {
@@ -337,6 +355,9 @@ async function create(path, options) {
337
355
  * await file.close();
338
356
  * ```
339
357
  *
358
+ * @param path The path of the file, relative to `options.baseDir` when it is provided.
359
+ * @param options Options defining the base directory of `path` and how the file is opened.
360
+ * @returns A promise resolving to the handle of the open file.
340
361
  * @since 2.0.0
341
362
  */
342
363
  async function open(path, options) {
@@ -357,6 +378,9 @@ async function open(path, options) {
357
378
  * await copyFile('app.conf', 'app.conf.bk', { fromPathBaseDir: BaseDirectory.AppConfig, toPathBaseDir: BaseDirectory.AppConfig });
358
379
  * ```
359
380
  *
381
+ * @param fromPath The path of the file to copy from.
382
+ * @param toPath The path of the file to copy to.
383
+ * @param options Options defining the base directory of each path.
360
384
  * @since 2.0.0
361
385
  */
362
386
  async function copyFile(fromPath, toPath, options) {
@@ -378,6 +402,8 @@ async function copyFile(fromPath, toPath, options) {
378
402
  * await mkdir('users', { baseDir: BaseDirectory.AppLocalData });
379
403
  * ```
380
404
  *
405
+ * @param path The path of the directory to create.
406
+ * @param options Options defining the base directory of `path`, the directory permissions and whether intermediate directories are created.
381
407
  * @since 2.0.0
382
408
  */
383
409
  async function mkdir(path, options) {
@@ -395,20 +421,23 @@ async function mkdir(path, options) {
395
421
  * ```typescript
396
422
  * import { readDir, BaseDirectory } from '@tauri-apps/plugin-fs';
397
423
  * import { join } from '@tauri-apps/api/path';
398
- * const dir = "users"
399
- * const entries = await readDir('users', { baseDir: BaseDirectory.AppLocalData });
400
- * processEntriesRecursively(dir, entries);
424
+ * const dir = 'users';
425
+ * const entries = await readDir(dir, { baseDir: BaseDirectory.AppLocalData });
426
+ * await processEntriesRecursively(dir, entries);
401
427
  * async function processEntriesRecursively(parent, entries) {
402
428
  * for (const entry of entries) {
403
429
  * console.log(`Entry: ${entry.name}`);
404
430
  * if (entry.isDirectory) {
405
- * const dir = await join(parent, entry.name);
406
- * processEntriesRecursively(dir, await readDir(dir, { baseDir: BaseDirectory.AppLocalData }))
431
+ * const entryPath = await join(parent, entry.name);
432
+ * await processEntriesRecursively(entryPath, await readDir(entryPath, { baseDir: BaseDirectory.AppLocalData }));
407
433
  * }
408
434
  * }
409
435
  * }
410
436
  * ```
411
437
  *
438
+ * @param path The path of the directory to read.
439
+ * @param options Options defining the base directory of `path`.
440
+ * @returns A promise resolving to the list of entries in the directory.
412
441
  * @since 2.0.0
413
442
  */
414
443
  async function readDir(path, options) {
@@ -429,6 +458,9 @@ async function readDir(path, options) {
429
458
  * const contents = await readFile('avatar.png', { baseDir: BaseDirectory.Resource });
430
459
  * ```
431
460
  *
461
+ * @param path The path of the file to read.
462
+ * @param options Options defining the base directory of `path`.
463
+ * @returns A promise resolving to the contents of the file as bytes.
432
464
  * @since 2.0.0
433
465
  */
434
466
  async function readFile(path, options) {
@@ -449,17 +481,13 @@ async function readFile(path, options) {
449
481
  * const contents = await readTextFile('app.conf', { baseDir: BaseDirectory.AppConfig });
450
482
  * ```
451
483
  *
484
+ * @param path The path of the file to read.
485
+ * @param options Options defining the base directory of `path` and the text encoding.
486
+ * @returns A promise resolving to the contents of the file as a string.
452
487
  * @since 2.0.0
453
488
  */
454
489
  async function readTextFile(path, options) {
455
- if (path instanceof URL && path.protocol !== 'file:') {
456
- throw new TypeError('Must be a file URL.');
457
- }
458
- const arr = await invoke('plugin:fs|read_text_file', {
459
- path: path instanceof URL ? path.toString() : path,
460
- options
461
- });
462
- const bytes = arr instanceof ArrayBuffer ? arr : Uint8Array.from(arr);
490
+ const bytes = await readFile(path, options);
463
491
  return new TextDecoder(options?.encoding ?? 'utf-8').decode(bytes);
464
492
  }
465
493
  /**
@@ -475,6 +503,9 @@ async function readTextFile(path, options) {
475
503
  * You could also call {@linkcode AsyncIterableIterator.next} to advance the
476
504
  * iterator so you can lazily read the next line whenever you want.
477
505
  *
506
+ * @param path The path of the file to read.
507
+ * @param options Options defining the base directory of `path` and the text encoding.
508
+ * @returns A promise resolving to an iterator over the lines of the file.
478
509
  * @since 2.0.0
479
510
  */
480
511
  async function readTextFileLines(path, options) {
@@ -495,7 +526,15 @@ async function readTextFileLines(path, options) {
495
526
  options: options != null ? { ...options, encoding } : undefined
496
527
  });
497
528
  }
498
- const arr = await invoke('plugin:fs|read_text_file_lines_next', { rid: this.rid });
529
+ let arr;
530
+ try {
531
+ arr = await invoke('plugin:fs|read_text_file_lines_next', { rid: this.rid });
532
+ }
533
+ catch (error) {
534
+ // the resource is closed on errors, the next iteration starts over
535
+ this.rid = null;
536
+ throw error;
537
+ }
499
538
  const bytes = arr instanceof ArrayBuffer ? new Uint8Array(arr) : Uint8Array.from(arr);
500
539
  // Rust side will never return an empty array for this command and
501
540
  // ensure there is at least one elements there.
@@ -514,6 +553,16 @@ async function readTextFileLines(path, options) {
514
553
  done
515
554
  };
516
555
  },
556
+ // called when a `for await` loop exits early (`break`, `return` or `throw`)
557
+ async return() {
558
+ if (this.rid !== null) {
559
+ const rid = this.rid;
560
+ this.rid = null;
561
+ // close the file, otherwise it stays open until the webview is destroyed
562
+ await new Resource(rid).close();
563
+ }
564
+ return { value: null, done: true };
565
+ },
517
566
  [Symbol.asyncIterator]() {
518
567
  return this;
519
568
  }
@@ -529,6 +578,8 @@ async function readTextFileLines(path, options) {
529
578
  * await remove('users', { baseDir: BaseDirectory.AppLocalData });
530
579
  * ```
531
580
  *
581
+ * @param path The path of the file or directory to remove.
582
+ * @param options Options defining the base directory of `path` and whether directories are removed recursively.
532
583
  * @since 2.0.0
533
584
  */
534
585
  async function remove(path, options) {
@@ -553,6 +604,9 @@ async function remove(path, options) {
553
604
  * await rename('avatar.png', 'deleted.png', { oldPathBaseDir: BaseDirectory.App, newPathBaseDir: BaseDirectory.AppLocalData });
554
605
  * ```
555
606
  *
607
+ * @param oldPath The path of the file or directory to rename.
608
+ * @param newPath The path the file or directory is renamed to.
609
+ * @param options Options defining the base directory of each path.
556
610
  * @since 2.0.0
557
611
  */
558
612
  async function rename(oldPath, newPath, options) {
@@ -577,6 +631,9 @@ async function rename(oldPath, newPath, options) {
577
631
  * console.log(fileInfo.isFile); // true
578
632
  * ```
579
633
  *
634
+ * @param path The path of the file or directory to inspect.
635
+ * @param options Options defining the base directory of `path`.
636
+ * @returns A promise resolving to the metadata of the file or directory.
580
637
  * @since 2.0.0
581
638
  */
582
639
  async function stat(path, options) {
@@ -598,6 +655,9 @@ async function stat(path, options) {
598
655
  * console.log(fileInfo.isFile); // true
599
656
  * ```
600
657
  *
658
+ * @param path The path of the file, directory or symlink to inspect.
659
+ * @param options Options defining the base directory of `path`.
660
+ * @returns A promise resolving to the metadata of the path itself.
601
661
  * @since 2.0.0
602
662
  */
603
663
  async function lstat(path, options) {
@@ -625,6 +685,9 @@ async function lstat(path, options) {
625
685
  * console.log(data); // "Hello W"
626
686
  * ```
627
687
  *
688
+ * @param path The path of the file to truncate or extend.
689
+ * @param len The length the file is resized to, in bytes. Defaults to `0`.
690
+ * @param options Options defining the base directory of `path`.
628
691
  * @since 2.0.0
629
692
  */
630
693
  async function truncate(path, len, options) {
@@ -648,6 +711,9 @@ async function truncate(path, len, options) {
648
711
  * await writeFile('file.txt', data, { baseDir: BaseDirectory.AppLocalData });
649
712
  * ```
650
713
  *
714
+ * @param path The path of the file to write to.
715
+ * @param data The bytes written to the file, either as a buffer or as a stream of chunks.
716
+ * @param options Options defining the base directory of `path` and how the file is opened.
651
717
  * @since 2.0.0
652
718
  */
653
719
  async function writeFile(path, data, options) {
@@ -685,27 +751,22 @@ async function writeFile(path, data, options) {
685
751
  }
686
752
  }
687
753
  /**
688
- * Writes UTF-8 string `data` to the given `path`, by default creating a new file if needed, else overwriting.
689
- @example
690
- * ```typescript
691
- * import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
692
- *
693
- * await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
694
- * ```
695
- *
696
- * @since 2.0.0
697
- */
754
+ * Writes UTF-8 string `data` to the given `path`, by default creating a new file if needed, else overwriting.
755
+ *
756
+ * @example
757
+ * ```typescript
758
+ * import { writeTextFile, BaseDirectory } from '@tauri-apps/plugin-fs';
759
+ *
760
+ * await writeTextFile('file.txt', "Hello world", { baseDir: BaseDirectory.AppLocalData });
761
+ * ```
762
+ *
763
+ * @param path The path of the file to write to.
764
+ * @param data The UTF-8 string written to the file.
765
+ * @param options Options defining the base directory of `path` and how the file is opened.
766
+ * @since 2.0.0
767
+ */
698
768
  async function writeTextFile(path, data, options) {
699
- if (path instanceof URL && path.protocol !== 'file:') {
700
- throw new TypeError('Must be a file URL.');
701
- }
702
- const encoder = new TextEncoder();
703
- await invoke('plugin:fs|write_text_file', encoder.encode(data), {
704
- headers: {
705
- path: encodeURIComponent(path instanceof URL ? path.toString() : path),
706
- options: JSON.stringify(options)
707
- }
708
- });
769
+ await writeFile(path, new TextEncoder().encode(data), options);
709
770
  }
710
771
  /**
711
772
  * Check if a path exists.
@@ -716,6 +777,9 @@ async function writeTextFile(path, data, options) {
716
777
  * await exists('avatar.png', { baseDir: BaseDirectory.AppData });
717
778
  * ```
718
779
  *
780
+ * @param path The path to check.
781
+ * @param options Options defining the base directory of `path`.
782
+ * @returns A promise resolving to `true` when the path exists, `false` otherwise.
719
783
  * @since 2.0.0
720
784
  */
721
785
  async function exists(path, options) {
@@ -727,6 +791,11 @@ async function exists(path, options) {
727
791
  options
728
792
  });
729
793
  }
794
+ /**
795
+ * A file system watcher. Call {@linkcode Watcher.close} to stop watching.
796
+ *
797
+ * @since 3.0.0
798
+ */
730
799
  class Watcher extends Resource {
731
800
  }
732
801
  async function watchInternal(paths, cb, options) {
@@ -743,15 +812,19 @@ async function watchInternal(paths, cb, options) {
743
812
  options,
744
813
  onEvent
745
814
  });
746
- const watcher = new Watcher(rid);
747
- return () => {
748
- void watcher.close();
749
- };
815
+ return new Watcher(rid);
750
816
  }
751
- // TODO: Return `Watcher` instead in v3
752
817
  /**
753
818
  * Watch changes (after a delay) on files or directories.
754
819
  *
820
+ * @example
821
+ * ```typescript
822
+ * import { watch, BaseDirectory } from '@tauri-apps/plugin-fs';
823
+ * const watcher = await watch('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
824
+ * // when you're done watching:
825
+ * await watcher.close();
826
+ * ```
827
+ *
755
828
  * @since 2.0.0
756
829
  */
757
830
  async function watch(paths, cb, options) {
@@ -760,10 +833,17 @@ async function watch(paths, cb, options) {
760
833
  ...options
761
834
  });
762
835
  }
763
- // TODO: Return `Watcher` instead in v3
764
836
  /**
765
837
  * Watch changes on files or directories.
766
838
  *
839
+ * @example
840
+ * ```typescript
841
+ * import { watchImmediate, BaseDirectory } from '@tauri-apps/plugin-fs';
842
+ * const watcher = await watchImmediate('app.conf', (event) => console.log(event), { baseDir: BaseDirectory.AppConfig });
843
+ * // when you're done watching:
844
+ * await watcher.close();
845
+ * ```
846
+ *
767
847
  * @since 2.0.0
768
848
  */
769
849
  async function watchImmediate(paths, cb, options) {
@@ -785,14 +865,18 @@ async function watchImmediate(paths, cb, options) {
785
865
  * console.log(dirSize); // 1024
786
866
  * ```
787
867
  *
868
+ * @param path The path of the file or directory to measure.
869
+ * @param options Options defining the base directory of `path` (since 2.6.0).
870
+ * @returns A promise resolving to the size in bytes.
788
871
  * @since 2.1.0
789
872
  */
790
- async function size(path) {
873
+ async function size(path, options) {
791
874
  if (path instanceof URL && path.protocol !== 'file:') {
792
875
  throw new TypeError('Must be a file URL.');
793
876
  }
794
877
  return await invoke('plugin:fs|size', {
795
- path: path instanceof URL ? path.toString() : path
878
+ path: path instanceof URL ? path.toString() : path,
879
+ options
796
880
  });
797
881
  }
798
882
  /**
@@ -819,6 +903,7 @@ async function size(path) {
819
903
  * // ... use the resource ...
820
904
  * ```
821
905
  *
906
+ * @param path The path or `file://` URL of the resource to start accessing.
822
907
  * @since 2.5.0
823
908
  */
824
909
  async function startAccessingSecurityScopedResource(path) {
@@ -850,6 +935,7 @@ async function startAccessingSecurityScopedResource(path) {
850
935
  * await stopAccessingSecurityScopedResource(filePath);
851
936
  * ```
852
937
  *
938
+ * @param path The path or `file://` URL of the resource to stop accessing.
853
939
  * @since 2.5.0
854
940
  */
855
941
  async function stopAccessingSecurityScopedResource(path) {
@@ -861,4 +947,4 @@ async function stopAccessingSecurityScopedResource(path) {
861
947
  });
862
948
  }
863
949
 
864
- export { FileHandle, SeekMode, copyFile, create, exists, lstat, mkdir, open, readDir, readFile, readTextFile, readTextFileLines, remove, rename, size, startAccessingSecurityScopedResource, stat, stopAccessingSecurityScopedResource, truncate, watch, watchImmediate, writeFile, writeTextFile };
950
+ export { FileHandle, SeekMode, Watcher, copyFile, create, exists, lstat, mkdir, open, readDir, readFile, readTextFile, readTextFileLines, remove, rename, size, startAccessingSecurityScopedResource, stat, stopAccessingSecurityScopedResource, truncate, watch, watchImmediate, writeFile, writeTextFile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tauri-apps/plugin-fs",
3
- "version": "3.0.0-alpha.1",
3
+ "version": "3.0.0-alpha.2",
4
4
  "description": "Access the file system.",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "authors": [