@zenfs/core 1.6.17 → 1.7.1

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 (73) hide show
  1. package/dist/backends/backend.js +1 -1
  2. package/dist/backends/fetch.d.ts +1 -1
  3. package/dist/backends/file_index.js +1 -1
  4. package/dist/backends/index.d.ts +11 -0
  5. package/dist/backends/index.js +11 -0
  6. package/dist/backends/overlay.d.ts +6 -6
  7. package/dist/backends/overlay.js +18 -17
  8. package/dist/backends/passthrough.d.ts +118 -0
  9. package/dist/backends/passthrough.js +337 -0
  10. package/dist/backends/port/fs.d.ts +7 -6
  11. package/dist/backends/port/fs.js +4 -4
  12. package/dist/backends/port/rpc.d.ts +2 -2
  13. package/dist/backends/port/rpc.js +0 -1
  14. package/dist/backends/store/fs.js +3 -2
  15. package/dist/config.d.ts +1 -1
  16. package/dist/config.js +5 -5
  17. package/dist/context.d.ts +2 -2
  18. package/dist/context.js +1 -1
  19. package/dist/devices.js +2 -2
  20. package/dist/file.js +32 -32
  21. package/dist/filesystem.d.ts +30 -7
  22. package/dist/filesystem.js +1 -0
  23. package/dist/index.d.ts +5 -14
  24. package/dist/index.js +4 -13
  25. package/dist/mixins/async.js +10 -11
  26. package/dist/mixins/mutexed.d.ts +6 -6
  27. package/dist/mixins/mutexed.js +8 -8
  28. package/dist/mixins/sync.js +4 -4
  29. package/dist/stats.d.ts +2 -2
  30. package/dist/stats.js +34 -34
  31. package/dist/utils.d.ts +2 -2
  32. package/dist/utils.js +1 -1
  33. package/dist/{emulation → vfs}/async.d.ts +7 -7
  34. package/dist/vfs/index.d.ts +16 -0
  35. package/dist/vfs/index.js +16 -0
  36. package/dist/{emulation → vfs}/promises.d.ts +4 -3
  37. package/dist/{emulation → vfs}/promises.js +24 -6
  38. package/dist/{emulation → vfs}/streams.js +1 -1
  39. package/dist/{emulation → vfs}/sync.d.ts +4 -3
  40. package/dist/{emulation → vfs}/sync.js +25 -5
  41. package/package.json +6 -7
  42. package/readme.md +7 -2
  43. package/scripts/test.js +13 -9
  44. package/tests/common/async.test.ts +1 -1
  45. package/tests/common/context.test.ts +30 -10
  46. package/tests/common/devices.test.ts +2 -2
  47. package/tests/common/handle.test.ts +1 -1
  48. package/tests/common/mounts.test.ts +3 -3
  49. package/tests/common/path.test.ts +1 -1
  50. package/tests/common.ts +1 -1
  51. package/tests/fs/links.test.ts +1 -1
  52. package/tests/fs/permissions.test.ts +2 -2
  53. package/tests/fs/truncate.test.ts +1 -1
  54. package/dist/emulation/index.d.ts +0 -9
  55. package/dist/emulation/index.js +0 -9
  56. package/dist/{emulation → vfs}/async.js +0 -0
  57. package/dist/{emulation → vfs}/cache.d.ts +0 -0
  58. package/dist/{emulation → vfs}/cache.js +0 -0
  59. package/dist/{emulation → vfs}/config.d.ts +0 -0
  60. package/dist/{emulation → vfs}/config.js +0 -0
  61. package/dist/{emulation → vfs}/constants.d.ts +0 -0
  62. package/dist/{emulation → vfs}/constants.js +0 -0
  63. package/dist/{emulation → vfs}/dir.d.ts +1 -1
  64. package/dist/{emulation → vfs}/dir.js +0 -0
  65. package/dist/{emulation → vfs}/path.d.ts +0 -0
  66. package/dist/{emulation → vfs}/path.js +0 -0
  67. package/dist/{emulation → vfs}/shared.d.ts +2 -2
  68. package/dist/{emulation → vfs}/shared.js +0 -0
  69. package/dist/{emulation → vfs}/streams.d.ts +1 -1
  70. package/dist/{emulation → vfs}/types.d.ts +0 -0
  71. package/dist/{emulation → vfs}/types.js +0 -0
  72. package/dist/{emulation → vfs}/watchers.d.ts +1 -1
  73. /package/dist/{emulation → vfs}/watchers.js +0 -0
@@ -1,4 +1,4 @@
1
- import { ErrnoError, Errno } from '../error.js';
1
+ import { Errno, ErrnoError } from '../error.js';
2
2
  /** @internal */
3
3
  export function isBackend(arg) {
4
4
  return arg != null && typeof arg == 'object' && 'create' in arg && typeof arg.create == 'function';
@@ -1,7 +1,7 @@
1
1
  import type { FileSystemMetadata } from '../filesystem.js';
2
2
  import type { Stats } from '../stats.js';
3
- import { IndexFS } from './file_index.js';
4
3
  import type { IndexData } from './file_index.js';
4
+ import { IndexFS } from './file_index.js';
5
5
  /**
6
6
  * Configuration options for FetchFS.
7
7
  */
@@ -1,12 +1,12 @@
1
1
  /* Note: this file is named file_index.ts because Typescript has special behavior regarding index.ts which can't be disabled. */
2
2
  import { isJSON } from 'utilium';
3
- import { basename, dirname } from '../emulation/path.js';
4
3
  import { Errno, ErrnoError } from '../error.js';
5
4
  import { NoSyncFile, isWriteable } from '../file.js';
6
5
  import { FileSystem } from '../filesystem.js';
7
6
  import { Readonly } from '../mixins/readonly.js';
8
7
  import { Stats } from '../stats.js';
9
8
  import { decodeUTF8, encodeUTF8 } from '../utils.js';
9
+ import { basename, dirname } from '../vfs/path.js';
10
10
  export const version = 1;
11
11
  /**
12
12
  * An index of files
@@ -0,0 +1,11 @@
1
+ export * from './backend.js';
2
+ export * from './fetch.js';
3
+ export * from './file_index.js';
4
+ export * from './memory.js';
5
+ export * from './overlay.js';
6
+ export * from './passthrough.js';
7
+ export * from './port/fs.js';
8
+ export * from './store/fs.js';
9
+ export * from './store/inode.js';
10
+ export * from './store/simple.js';
11
+ export * from './store/store.js';
@@ -0,0 +1,11 @@
1
+ export * from './backend.js';
2
+ export * from './fetch.js';
3
+ export * from './file_index.js';
4
+ export * from './memory.js';
5
+ export * from './overlay.js';
6
+ export * from './passthrough.js';
7
+ export * from './port/fs.js';
8
+ export * from './store/fs.js';
9
+ export * from './store/inode.js';
10
+ export * from './store/simple.js';
11
+ export * from './store/store.js';
@@ -1,7 +1,7 @@
1
1
  import type { File } from '../file.js';
2
- import type { FileSystemMetadata } from '../filesystem.js';
3
- import { FileSystem } from '../filesystem.js';
2
+ import type { CreationOptions, FileSystemMetadata } from '../filesystem.js';
4
3
  import type { Stats } from '../stats.js';
4
+ import { FileSystem } from '../filesystem.js';
5
5
  /**
6
6
  * Configuration options for OverlayFS instances.
7
7
  */
@@ -51,16 +51,16 @@ export declare class UnmutexedOverlayFS extends FileSystem {
51
51
  statSync(path: string): Stats;
52
52
  openFile(path: string, flag: string): Promise<File>;
53
53
  openFileSync(path: string, flag: string): File;
54
- createFile(path: string, flag: string, mode: number): Promise<File>;
55
- createFileSync(path: string, flag: string, mode: number): File;
54
+ createFile(path: string, flag: string, mode: number, options: CreationOptions): Promise<File>;
55
+ createFileSync(path: string, flag: string, mode: number, options: CreationOptions): File;
56
56
  link(srcpath: string, dstpath: string): Promise<void>;
57
57
  linkSync(srcpath: string, dstpath: string): void;
58
58
  unlink(path: string): Promise<void>;
59
59
  unlinkSync(path: string): void;
60
60
  rmdir(path: string): Promise<void>;
61
61
  rmdirSync(path: string): void;
62
- mkdir(path: string, mode: number): Promise<void>;
63
- mkdirSync(path: string, mode: number): void;
62
+ mkdir(path: string, mode: number, options: CreationOptions): Promise<void>;
63
+ mkdirSync(path: string, mode: number, options: CreationOptions): void;
64
64
  readdir(path: string): Promise<string[]>;
65
65
  readdirSync(path: string): string[];
66
66
  private deletePath;
@@ -50,12 +50,12 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
50
50
  var e = new Error(message);
51
51
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
52
  });
53
- import { dirname } from '../emulation/path.js';
54
53
  import { Errno, ErrnoError } from '../error.js';
55
54
  import { PreloadFile, parseFlag } from '../file.js';
56
55
  import { FileSystem } from '../filesystem.js';
57
56
  import { Mutexed } from '../mixins/mutexed.js';
58
57
  import { decodeUTF8, encodeUTF8 } from '../utils.js';
58
+ import { dirname } from '../vfs/path.js';
59
59
  /** @internal */
60
60
  const deletionLogPath = '/.deleted';
61
61
  /**
@@ -98,7 +98,7 @@ export class UnmutexedOverlayFS extends FileSystem {
98
98
  async sync(path, data, stats) {
99
99
  await this.copyForWrite(path);
100
100
  if (!(await this.writable.exists(path))) {
101
- await this.writable.createFile(path, 'w', 0o644);
101
+ await this.writable.createFile(path, 'w', 0o644, stats);
102
102
  }
103
103
  await this.writable.sync(path, data, stats);
104
104
  }
@@ -216,14 +216,14 @@ export class UnmutexedOverlayFS extends FileSystem {
216
216
  file.readSync(data);
217
217
  return new PreloadFile(this, path, flag, stats, data);
218
218
  }
219
- async createFile(path, flag, mode) {
219
+ async createFile(path, flag, mode, options) {
220
220
  this.checkInitialized();
221
- await this.writable.createFile(path, flag, mode);
221
+ await this.writable.createFile(path, flag, mode, options);
222
222
  return this.openFile(path, flag);
223
223
  }
224
- createFileSync(path, flag, mode) {
224
+ createFileSync(path, flag, mode, options) {
225
225
  this.checkInitialized();
226
- this.writable.createFileSync(path, flag, mode);
226
+ this.writable.createFileSync(path, flag, mode, options);
227
227
  return this.openFileSync(path, flag);
228
228
  }
229
229
  async link(srcpath, dstpath) {
@@ -298,23 +298,23 @@ export class UnmutexedOverlayFS extends FileSystem {
298
298
  }
299
299
  void this.deletePath(path);
300
300
  }
301
- async mkdir(path, mode) {
301
+ async mkdir(path, mode, options) {
302
302
  this.checkInitialized();
303
303
  if (await this.exists(path)) {
304
304
  throw ErrnoError.With('EEXIST', path, 'mkdir');
305
305
  }
306
306
  // The below will throw should any of the parent directories fail to exist on _writable.
307
307
  await this.createParentDirectories(path);
308
- await this.writable.mkdir(path, mode);
308
+ await this.writable.mkdir(path, mode, options);
309
309
  }
310
- mkdirSync(path, mode) {
310
+ mkdirSync(path, mode, options) {
311
311
  this.checkInitialized();
312
312
  if (this.existsSync(path)) {
313
313
  throw ErrnoError.With('EEXIST', path, 'mkdir');
314
314
  }
315
315
  // The below will throw should any of the parent directories fail to exist on _writable.
316
316
  this.createParentDirectoriesSync(path);
317
- this.writable.mkdirSync(path, mode);
317
+ this.writable.mkdirSync(path, mode, options);
318
318
  }
319
319
  async readdir(path) {
320
320
  this.checkInitialized();
@@ -426,7 +426,8 @@ export class UnmutexedOverlayFS extends FileSystem {
426
426
  parent = dirname(parent);
427
427
  }
428
428
  for (const path of toCreate.reverse()) {
429
- this.writable.mkdirSync(path, this.statSync(path).mode);
429
+ const { uid, gid, mode } = this.statSync(path);
430
+ this.writable.mkdirSync(path, mode, { uid, gid });
430
431
  }
431
432
  }
432
433
  /**
@@ -441,8 +442,8 @@ export class UnmutexedOverlayFS extends FileSystem {
441
442
  parent = dirname(parent);
442
443
  }
443
444
  for (const path of toCreate.reverse()) {
444
- const stats = await this.stat(path);
445
- await this.writable.mkdir(path, stats.mode);
445
+ const { uid, gid, mode } = await this.stat(path);
446
+ await this.writable.mkdir(path, mode, { uid, gid });
446
447
  }
447
448
  }
448
449
  /**
@@ -481,13 +482,13 @@ export class UnmutexedOverlayFS extends FileSystem {
481
482
  try {
482
483
  const stats = this.statSync(path);
483
484
  if (stats.isDirectory()) {
484
- this.writable.mkdirSync(path, stats.mode);
485
+ this.writable.mkdirSync(path, stats.mode, stats);
485
486
  return;
486
487
  }
487
488
  const data = new Uint8Array(stats.size);
488
489
  const readable = __addDisposableResource(env_1, this.readable.openFileSync(path, 'r'), false);
489
490
  readable.readSync(data);
490
- const writable = __addDisposableResource(env_1, this.writable.createFileSync(path, 'w', stats.mode | 0o222), false);
491
+ const writable = __addDisposableResource(env_1, this.writable.createFileSync(path, 'w', stats.mode | 0o222, stats), false);
491
492
  writable.writeSync(data);
492
493
  }
493
494
  catch (e_1) {
@@ -503,13 +504,13 @@ export class UnmutexedOverlayFS extends FileSystem {
503
504
  try {
504
505
  const stats = await this.stat(path);
505
506
  if (stats.isDirectory()) {
506
- await this.writable.mkdir(path, stats.mode);
507
+ await this.writable.mkdir(path, stats.mode, stats);
507
508
  return;
508
509
  }
509
510
  const data = new Uint8Array(stats.size);
510
511
  const readable = __addDisposableResource(env_2, await this.readable.openFile(path, 'r'), true);
511
512
  await readable.read(data);
512
- const writable = __addDisposableResource(env_2, await this.writable.createFile(path, 'w', stats.mode | 0o222), true);
513
+ const writable = __addDisposableResource(env_2, await this.writable.createFile(path, 'w', stats.mode | 0o222, stats), true);
513
514
  await writable.write(data);
514
515
  }
515
516
  catch (e_2) {
@@ -0,0 +1,118 @@
1
+ import type * as fs from 'node:fs';
2
+ import { FileSystem } from '../filesystem.js';
3
+ import { Stats } from '../stats.js';
4
+ import { File } from '../file.js';
5
+ export type NodeFS = typeof fs;
6
+ export interface PassthroughOptions {
7
+ fs: NodeFS;
8
+ prefix?: string;
9
+ }
10
+ export declare class PassthroughFS extends FileSystem {
11
+ readonly nodeFS: NodeFS;
12
+ readonly prefix: string;
13
+ constructor(nodeFS: NodeFS, prefix: string);
14
+ path(path: string): string;
15
+ error(err: unknown, path: string): never;
16
+ /**
17
+ * Rename a file or directory.
18
+ */
19
+ rename(oldPath: string, newPath: string): Promise<void>;
20
+ /**
21
+ * Rename a file or directory synchronously.
22
+ */
23
+ renameSync(oldPath: string, newPath: string): void;
24
+ /**
25
+ * Get file statistics.
26
+ */
27
+ stat(path: string): Promise<Stats>;
28
+ /**
29
+ * Get file statistics synchronously.
30
+ */
31
+ statSync(path: string): Stats;
32
+ /**
33
+ * Open a file.
34
+ */
35
+ openFile(path: string, flag: string): Promise<File>;
36
+ /**
37
+ * Open a file synchronously.
38
+ */
39
+ openFileSync(path: string, flag: string): File;
40
+ /**
41
+ * Unlink (delete) a file.
42
+ */
43
+ unlink(path: string): Promise<void>;
44
+ /**
45
+ * Unlink (delete) a file synchronously.
46
+ */
47
+ unlinkSync(path: string): void;
48
+ /**
49
+ * Create a directory.
50
+ */
51
+ mkdir(path: string, mode: number): Promise<void>;
52
+ /**
53
+ * Create a directory synchronously.
54
+ */
55
+ mkdirSync(path: string, mode: number): void;
56
+ /**
57
+ * Read the contents of a directory.
58
+ */
59
+ readdir(path: string): Promise<string[]>;
60
+ /**
61
+ * Read the contents of a directory synchronously.
62
+ */
63
+ readdirSync(path: string): string[];
64
+ /**
65
+ * Create a file.
66
+ */
67
+ createFile(path: string, flag: string, mode: number): Promise<File>;
68
+ /**
69
+ * Create a file synchronously.
70
+ */
71
+ createFileSync(path: string, flag: string, mode: number): File;
72
+ /**
73
+ * Remove a directory.
74
+ */
75
+ rmdir(path: string): Promise<void>;
76
+ /**
77
+ * Remove a directory synchronously.
78
+ */
79
+ rmdirSync(path: string): void;
80
+ /**
81
+ * Synchronize data to the file system.
82
+ */
83
+ sync(path: string, data: Uint8Array, stats: Stats): Promise<void>;
84
+ /**
85
+ * Synchronize data to the file system synchronously.
86
+ */
87
+ syncSync(path: string, data: Uint8Array, stats: Stats): void;
88
+ /**
89
+ * Create a hard link.
90
+ */
91
+ link(target: string, link: string): Promise<void>;
92
+ /**
93
+ * Create a hard link synchronously.
94
+ */
95
+ linkSync(target: string, link: string): void;
96
+ }
97
+ declare const _Passthrough: {
98
+ readonly name: "Passthrough";
99
+ readonly options: {
100
+ readonly fs: {
101
+ readonly type: "object";
102
+ readonly required: true;
103
+ };
104
+ readonly prefix: {
105
+ readonly type: "string";
106
+ readonly required: false;
107
+ };
108
+ };
109
+ readonly create: ({ fs, prefix }: PassthroughOptions) => PassthroughFS;
110
+ };
111
+ type _Passthrough = typeof _Passthrough;
112
+ export interface Passthrough extends _Passthrough {
113
+ }
114
+ /**
115
+ * A file system that passes through to another FS
116
+ */
117
+ export declare const Passthrough: Passthrough;
118
+ export {};
@@ -0,0 +1,337 @@
1
+ import { FileSystem } from '../filesystem.js';
2
+ import { ErrnoError } from '../error.js';
3
+ import { Stats } from '../stats.js';
4
+ import { File } from '../file.js';
5
+ import { join, resolve } from '../vfs/path.js';
6
+ class PassthroughFile extends File {
7
+ constructor(fs, path, fd) {
8
+ super(fs, path);
9
+ this.fd = fd;
10
+ this.node = fs.nodeFS;
11
+ this.nodePath = fs.path(path);
12
+ }
13
+ error(err) {
14
+ const error = err;
15
+ return ErrnoError.With(error.code, this.path, error.syscall);
16
+ }
17
+ get position() {
18
+ // Placeholder: Implement proper position tracking if needed.
19
+ return 0;
20
+ }
21
+ async stat() {
22
+ const { resolve, reject, promise } = Promise.withResolvers();
23
+ this.node.fstat(this.fd, (err, stats) => (err ? reject(this.error(err)) : resolve(new Stats(stats))));
24
+ return promise;
25
+ }
26
+ statSync() {
27
+ return new Stats(this.node.fstatSync(this.fd));
28
+ }
29
+ close() {
30
+ const { resolve, reject, promise } = Promise.withResolvers();
31
+ this.node.close(this.fd, err => (err ? reject(this.error(err)) : resolve()));
32
+ return promise;
33
+ }
34
+ closeSync() {
35
+ this.node.closeSync(this.fd);
36
+ }
37
+ async truncate(len) {
38
+ await this.node.promises.truncate(this.nodePath, len);
39
+ }
40
+ truncateSync(len) {
41
+ this.node.ftruncateSync(this.fd, len);
42
+ }
43
+ async sync() {
44
+ const { resolve, reject, promise } = Promise.withResolvers();
45
+ this.node.fsync(this.fd, err => (err ? reject(this.error(err)) : resolve()));
46
+ return promise;
47
+ }
48
+ syncSync() {
49
+ this.node.fsyncSync(this.fd);
50
+ }
51
+ async write(buffer, offset, length, position) {
52
+ const { resolve, reject, promise } = Promise.withResolvers();
53
+ this.node.write(this.fd, buffer, offset, length, position, (err, written) => (err ? reject(this.error(err)) : resolve(written)));
54
+ return promise;
55
+ }
56
+ writeSync(buffer, offset, length, position) {
57
+ return this.node.writeSync(this.fd, buffer, offset, length, position);
58
+ }
59
+ async read(buffer, offset = 0, length, position = null) {
60
+ const { resolve, reject, promise } = Promise.withResolvers();
61
+ this.node.read(this.fd, buffer, offset, length || (await this.stat()).size, position, (err, bytesRead, buffer) => err ? reject(this.error(err)) : resolve({ bytesRead, buffer }));
62
+ return promise;
63
+ }
64
+ readSync(buffer, offset = 0, length = this.statSync().size, position = null) {
65
+ return this.node.readSync(this.fd, buffer, offset, length, position);
66
+ }
67
+ async chmod(mode) {
68
+ await this.node.promises.chmod(this.nodePath, mode);
69
+ }
70
+ chmodSync(mode) {
71
+ this.node.fchmodSync(this.fd, mode);
72
+ }
73
+ async chown(uid, gid) {
74
+ await this.node.promises.chown(this.nodePath, uid, gid);
75
+ }
76
+ chownSync(uid, gid) {
77
+ this.node.fchownSync(this.fd, uid, gid);
78
+ }
79
+ async utimes(atime, mtime) {
80
+ await this.node.promises.utimes(this.nodePath, atime, mtime);
81
+ }
82
+ utimesSync(atime, mtime) {
83
+ this.node.futimesSync(this.fd, atime, mtime);
84
+ }
85
+ }
86
+ export class PassthroughFS extends FileSystem {
87
+ constructor(nodeFS, prefix) {
88
+ super();
89
+ this.nodeFS = nodeFS;
90
+ this.prefix = prefix;
91
+ }
92
+ path(path) {
93
+ return join(this.prefix, path.slice(1));
94
+ }
95
+ error(err, path) {
96
+ const error = err;
97
+ throw ErrnoError.With(error.code, path, error.syscall);
98
+ }
99
+ /**
100
+ * Rename a file or directory.
101
+ */
102
+ async rename(oldPath, newPath) {
103
+ try {
104
+ await this.nodeFS.promises.rename(this.path(oldPath), this.path(newPath));
105
+ }
106
+ catch (err) {
107
+ this.error(err, oldPath);
108
+ }
109
+ }
110
+ /**
111
+ * Rename a file or directory synchronously.
112
+ */
113
+ renameSync(oldPath, newPath) {
114
+ try {
115
+ this.nodeFS.renameSync(this.path(oldPath), this.path(newPath));
116
+ }
117
+ catch (err) {
118
+ this.error(err, oldPath);
119
+ }
120
+ }
121
+ /**
122
+ * Get file statistics.
123
+ */
124
+ async stat(path) {
125
+ try {
126
+ return new Stats(await this.nodeFS.promises.stat(this.path(path)));
127
+ }
128
+ catch (err) {
129
+ this.error(err, path);
130
+ }
131
+ }
132
+ /**
133
+ * Get file statistics synchronously.
134
+ */
135
+ statSync(path) {
136
+ try {
137
+ return new Stats(this.nodeFS.statSync(this.path(path)));
138
+ }
139
+ catch (err) {
140
+ this.error(err, path);
141
+ }
142
+ }
143
+ /**
144
+ * Open a file.
145
+ */
146
+ async openFile(path, flag) {
147
+ try {
148
+ const { fd } = await this.nodeFS.promises.open(this.path(path), flag);
149
+ return new PassthroughFile(this, path, fd);
150
+ }
151
+ catch (err) {
152
+ this.error(err, path);
153
+ }
154
+ }
155
+ /**
156
+ * Open a file synchronously.
157
+ */
158
+ openFileSync(path, flag) {
159
+ try {
160
+ const fd = this.nodeFS.openSync(this.path(path), flag);
161
+ return new PassthroughFile(this, path, fd);
162
+ }
163
+ catch (err) {
164
+ this.error(err, path);
165
+ }
166
+ }
167
+ /**
168
+ * Unlink (delete) a file.
169
+ */
170
+ async unlink(path) {
171
+ try {
172
+ await this.nodeFS.promises.unlink(this.path(path));
173
+ }
174
+ catch (err) {
175
+ this.error(err, path);
176
+ }
177
+ }
178
+ /**
179
+ * Unlink (delete) a file synchronously.
180
+ */
181
+ unlinkSync(path) {
182
+ try {
183
+ this.nodeFS.unlinkSync(this.path(path));
184
+ }
185
+ catch (err) {
186
+ this.error(err, path);
187
+ }
188
+ }
189
+ /**
190
+ * Create a directory.
191
+ */
192
+ async mkdir(path, mode) {
193
+ try {
194
+ await this.nodeFS.promises.mkdir(this.path(path), { mode });
195
+ }
196
+ catch (err) {
197
+ this.error(err, path);
198
+ }
199
+ }
200
+ /**
201
+ * Create a directory synchronously.
202
+ */
203
+ mkdirSync(path, mode) {
204
+ try {
205
+ this.nodeFS.mkdirSync(this.path(path), { mode });
206
+ }
207
+ catch (err) {
208
+ this.error(err, path);
209
+ }
210
+ }
211
+ /**
212
+ * Read the contents of a directory.
213
+ */
214
+ async readdir(path) {
215
+ try {
216
+ return await this.nodeFS.promises.readdir(this.path(path));
217
+ }
218
+ catch (err) {
219
+ this.error(err, path);
220
+ }
221
+ }
222
+ /**
223
+ * Read the contents of a directory synchronously.
224
+ */
225
+ readdirSync(path) {
226
+ try {
227
+ return this.nodeFS.readdirSync(this.path(path));
228
+ }
229
+ catch (err) {
230
+ this.error(err, path);
231
+ }
232
+ }
233
+ /**
234
+ * Create a file.
235
+ */
236
+ async createFile(path, flag, mode) {
237
+ try {
238
+ const { fd } = await this.nodeFS.promises.open(this.path(path), flag, mode);
239
+ return new PassthroughFile(this, path, fd);
240
+ }
241
+ catch (err) {
242
+ this.error(err, path);
243
+ }
244
+ }
245
+ /**
246
+ * Create a file synchronously.
247
+ */
248
+ createFileSync(path, flag, mode) {
249
+ try {
250
+ const fd = this.nodeFS.openSync(this.path(path), flag, mode);
251
+ return new PassthroughFile(this, path, fd);
252
+ }
253
+ catch (err) {
254
+ this.error(err, path);
255
+ }
256
+ }
257
+ /**
258
+ * Remove a directory.
259
+ */
260
+ async rmdir(path) {
261
+ try {
262
+ await this.nodeFS.promises.rmdir(this.path(path));
263
+ }
264
+ catch (err) {
265
+ this.error(err, path);
266
+ }
267
+ }
268
+ /**
269
+ * Remove a directory synchronously.
270
+ */
271
+ rmdirSync(path) {
272
+ try {
273
+ this.nodeFS.rmdirSync(this.path(path));
274
+ }
275
+ catch (err) {
276
+ this.error(err, path);
277
+ }
278
+ }
279
+ /**
280
+ * Synchronize data to the file system.
281
+ */
282
+ async sync(path, data, stats) {
283
+ try {
284
+ await this.nodeFS.promises.writeFile(this.path(path), data);
285
+ }
286
+ catch (err) {
287
+ this.error(err, path);
288
+ }
289
+ }
290
+ /**
291
+ * Synchronize data to the file system synchronously.
292
+ */
293
+ syncSync(path, data, stats) {
294
+ try {
295
+ this.nodeFS.writeFileSync(this.path(path), data);
296
+ }
297
+ catch (err) {
298
+ this.error(err, path);
299
+ }
300
+ }
301
+ /**
302
+ * Create a hard link.
303
+ */
304
+ async link(target, link) {
305
+ try {
306
+ await this.nodeFS.promises.link(this.path(target), this.path(link));
307
+ }
308
+ catch (err) {
309
+ this.error(err, target);
310
+ }
311
+ }
312
+ /**
313
+ * Create a hard link synchronously.
314
+ */
315
+ linkSync(target, link) {
316
+ try {
317
+ this.nodeFS.linkSync(this.path(target), this.path(link));
318
+ }
319
+ catch (err) {
320
+ this.error(err, target);
321
+ }
322
+ }
323
+ }
324
+ const _Passthrough = {
325
+ name: 'Passthrough',
326
+ options: {
327
+ fs: { type: 'object', required: true },
328
+ prefix: { type: 'string', required: false },
329
+ },
330
+ create({ fs, prefix = '/' }) {
331
+ return new PassthroughFS(fs, resolve(prefix));
332
+ },
333
+ };
334
+ /**
335
+ * A file system that passes through to another FS
336
+ */
337
+ export const Passthrough = _Passthrough;