@zenfs/core 2.7.5 → 2.7.7

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 (72) hide show
  1. package/dist/backends/backend.js +0 -2
  2. package/dist/backends/cow.d.ts +2 -2
  3. package/dist/backends/cow.js +6 -14
  4. package/dist/backends/passthrough.d.ts +0 -54
  5. package/dist/backends/passthrough.js +0 -54
  6. package/dist/backends/port.d.ts +2 -6
  7. package/dist/backends/port.js +3 -11
  8. package/dist/backends/store/fs.d.ts +0 -9
  9. package/dist/backends/store/fs.js +2 -24
  10. package/dist/backends/store/store.d.ts +1 -1
  11. package/dist/backends/store/store.js +2 -8
  12. package/dist/config.d.ts +7 -0
  13. package/dist/config.js +9 -3
  14. package/dist/internal/contexts.d.ts +1 -2
  15. package/dist/internal/credentials.d.ts +0 -3
  16. package/dist/internal/error.d.ts +5 -0
  17. package/dist/internal/error.js +10 -0
  18. package/dist/internal/file_index.js +0 -1
  19. package/dist/internal/index_fs.d.ts +2 -2
  20. package/dist/internal/index_fs.js +2 -2
  21. package/dist/internal/inode.d.ts +46 -43
  22. package/dist/internal/inode.js +75 -10
  23. package/dist/internal/rpc.d.ts +16 -7
  24. package/dist/internal/rpc.js +2 -11
  25. package/dist/mixins/async.js +22 -24
  26. package/dist/mixins/mutexed.d.ts +6 -41
  27. package/dist/mixins/mutexed.js +36 -109
  28. package/dist/mixins/sync.js +0 -2
  29. package/dist/node/async.js +2 -12
  30. package/dist/node/index.d.ts +1 -1
  31. package/dist/node/promises.d.ts +1 -6
  32. package/dist/node/promises.js +18 -22
  33. package/dist/node/stats.d.ts +25 -99
  34. package/dist/node/stats.js +22 -56
  35. package/dist/node/streams.d.ts +1 -37
  36. package/dist/node/sync.d.ts +1 -6
  37. package/dist/node/sync.js +16 -20
  38. package/dist/polyfills.js +25 -0
  39. package/dist/utils.d.ts +0 -4
  40. package/dist/vfs/acl.d.ts +1 -3
  41. package/dist/vfs/acl.js +1 -3
  42. package/dist/vfs/async.js +77 -69
  43. package/dist/vfs/config.d.ts +10 -1
  44. package/dist/vfs/config.js +5 -2
  45. package/dist/vfs/dir.d.ts +3 -0
  46. package/dist/vfs/dir.js +4 -1
  47. package/dist/vfs/file.d.ts +1 -8
  48. package/dist/vfs/file.js +11 -7
  49. package/dist/vfs/ioctl.js +2 -2
  50. package/dist/vfs/shared.d.ts +2 -0
  51. package/dist/vfs/shared.js +3 -4
  52. package/dist/vfs/sync.js +77 -61
  53. package/dist/vfs/vcache.d.ts +14 -14
  54. package/dist/vfs/vcache.js +65 -58
  55. package/dist/vfs/watchers.d.ts +1 -0
  56. package/dist/vfs/watchers.js +2 -4
  57. package/dist/vfs/xattr.js +18 -17
  58. package/package.json +2 -4
  59. package/scripts/make-index.js +1 -1
  60. package/tests/common/async.test.ts +35 -0
  61. package/tests/common/config.test.ts +1 -1
  62. package/tests/common/context.test.ts +1 -1
  63. package/tests/common/file_index.test.ts +1 -1
  64. package/tests/common/mounts.test.ts +12 -0
  65. package/tests/common/vcache.test.ts +13 -0
  66. package/tests/fs/concurrency.test.ts +3 -3
  67. package/tests/fs/links.test.ts +76 -0
  68. package/tests/fs/permissions.test.ts +232 -0
  69. package/tests/fs/stat.test.ts +1 -1
  70. package/tests/fs/streams.test.ts +1 -1
  71. package/tests/fs/xattr.test.ts +10 -0
  72. package/tests/common/mutex.test.ts +0 -61
@@ -51,40 +51,15 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
51
51
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
52
  });
53
53
  // SPDX-License-Identifier: LGPL-3.0-or-later
54
- import { withErrno } from 'kerium';
55
- import { err } from 'kerium/log';
54
+ import { RwLockable } from 'kerium/locks';
56
55
  import '../polyfills.js';
57
- /**
58
- * @category Internals
59
- * @internal
60
- */
61
- export class MutexLock {
62
- previous;
63
- current = Promise.withResolvers();
64
- _isLocked = true;
65
- get isLocked() {
66
- return this._isLocked;
67
- }
68
- constructor(previous) {
69
- this.previous = previous;
70
- }
71
- async done() {
72
- await this.previous?.done();
73
- await this.current.promise;
74
- }
75
- unlock() {
76
- this.current.resolve();
77
- this._isLocked = false;
78
- }
79
- [Symbol.dispose]() {
80
- this.unlock();
81
- }
82
- }
83
56
  /**
84
57
  * @hidden
85
58
  * @category Internals
59
+ * @deprecated This is no longer needed and will be removed
60
+ * @todo [breaking] Remove
86
61
  */
87
- export class _MutexedFS {
62
+ export class _MutexedFS extends RwLockable {
88
63
  /**
89
64
  * @internal
90
65
  */
@@ -122,59 +97,10 @@ export class _MutexedFS {
122
97
  usage() {
123
98
  return this._fs.usage();
124
99
  }
125
- /**
126
- * The current locks
127
- */
128
- currentLock;
129
- /**
130
- * Adds a lock for a path
131
- */
132
- addLock() {
133
- const lock = new MutexLock(this.currentLock);
134
- this.currentLock = lock;
135
- return lock;
136
- }
137
- /**
138
- * Locks `path` asynchronously.
139
- * If the path is currently locked, waits for it to be unlocked.
140
- * @internal
141
- */
142
- async lock(timeout = 5000) {
143
- const previous = this.currentLock;
144
- const lock = this.addLock();
145
- const stack = new Error().stack;
146
- setTimeout(() => {
147
- if (lock.isLocked) {
148
- const error = withErrno('EDEADLK');
149
- error.stack += stack?.slice('Error'.length);
150
- throw err(error);
151
- }
152
- }, timeout);
153
- await previous?.done();
154
- return lock;
155
- }
156
- /**
157
- * Locks `path` asynchronously.
158
- * If the path is currently locked, an error will be thrown
159
- * @internal
160
- */
161
- lockSync() {
162
- if (this.currentLock?.isLocked) {
163
- throw err(withErrno('EBUSY'));
164
- }
165
- return this.addLock();
166
- }
167
- /**
168
- * Whether `path` is locked
169
- * @internal
170
- */
171
- get isLocked() {
172
- return !!this.currentLock?.isLocked;
173
- }
174
100
  async rename(oldPath, newPath) {
175
101
  const env_1 = { stack: [], error: void 0, hasError: false };
176
102
  try {
177
- const _ = __addDisposableResource(env_1, await this.lock(), false);
103
+ const _ = __addDisposableResource(env_1, await this.lock('rw'), false);
178
104
  await this._fs.rename(oldPath, newPath);
179
105
  }
180
106
  catch (e_1) {
@@ -188,7 +114,7 @@ export class _MutexedFS {
188
114
  renameSync(oldPath, newPath) {
189
115
  const env_2 = { stack: [], error: void 0, hasError: false };
190
116
  try {
191
- const _ = __addDisposableResource(env_2, this.lockSync(), false);
117
+ const _ = __addDisposableResource(env_2, this.lockSync('rw'), false);
192
118
  return this._fs.renameSync(oldPath, newPath);
193
119
  }
194
120
  catch (e_2) {
@@ -202,7 +128,7 @@ export class _MutexedFS {
202
128
  async stat(path) {
203
129
  const env_3 = { stack: [], error: void 0, hasError: false };
204
130
  try {
205
- const _ = __addDisposableResource(env_3, await this.lock(), false);
131
+ const _ = __addDisposableResource(env_3, await this.lock('ro'), false);
206
132
  return await this._fs.stat(path);
207
133
  }
208
134
  catch (e_3) {
@@ -216,7 +142,7 @@ export class _MutexedFS {
216
142
  statSync(path) {
217
143
  const env_4 = { stack: [], error: void 0, hasError: false };
218
144
  try {
219
- const _ = __addDisposableResource(env_4, this.lockSync(), false);
145
+ const _ = __addDisposableResource(env_4, this.lockSync('ro'), false);
220
146
  return this._fs.statSync(path);
221
147
  }
222
148
  catch (e_4) {
@@ -230,7 +156,7 @@ export class _MutexedFS {
230
156
  async touch(path, metadata) {
231
157
  const env_5 = { stack: [], error: void 0, hasError: false };
232
158
  try {
233
- const _ = __addDisposableResource(env_5, await this.lock(), false);
159
+ const _ = __addDisposableResource(env_5, await this.lock('rw'), false);
234
160
  await this._fs.touch(path, metadata);
235
161
  }
236
162
  catch (e_5) {
@@ -244,7 +170,7 @@ export class _MutexedFS {
244
170
  touchSync(path, metadata) {
245
171
  const env_6 = { stack: [], error: void 0, hasError: false };
246
172
  try {
247
- const _ = __addDisposableResource(env_6, this.lockSync(), false);
173
+ const _ = __addDisposableResource(env_6, this.lockSync('rw'), false);
248
174
  this._fs.touchSync(path, metadata);
249
175
  }
250
176
  catch (e_6) {
@@ -258,7 +184,7 @@ export class _MutexedFS {
258
184
  async createFile(path, options) {
259
185
  const env_7 = { stack: [], error: void 0, hasError: false };
260
186
  try {
261
- const _ = __addDisposableResource(env_7, await this.lock(), false);
187
+ const _ = __addDisposableResource(env_7, await this.lock('rw'), false);
262
188
  return await this._fs.createFile(path, options);
263
189
  }
264
190
  catch (e_7) {
@@ -272,7 +198,7 @@ export class _MutexedFS {
272
198
  createFileSync(path, options) {
273
199
  const env_8 = { stack: [], error: void 0, hasError: false };
274
200
  try {
275
- const _ = __addDisposableResource(env_8, this.lockSync(), false);
201
+ const _ = __addDisposableResource(env_8, this.lockSync('rw'), false);
276
202
  return this._fs.createFileSync(path, options);
277
203
  }
278
204
  catch (e_8) {
@@ -286,7 +212,7 @@ export class _MutexedFS {
286
212
  async unlink(path) {
287
213
  const env_9 = { stack: [], error: void 0, hasError: false };
288
214
  try {
289
- const _ = __addDisposableResource(env_9, await this.lock(), false);
215
+ const _ = __addDisposableResource(env_9, await this.lock('rw'), false);
290
216
  await this._fs.unlink(path);
291
217
  }
292
218
  catch (e_9) {
@@ -300,7 +226,7 @@ export class _MutexedFS {
300
226
  unlinkSync(path) {
301
227
  const env_10 = { stack: [], error: void 0, hasError: false };
302
228
  try {
303
- const _ = __addDisposableResource(env_10, this.lockSync(), false);
229
+ const _ = __addDisposableResource(env_10, this.lockSync('rw'), false);
304
230
  return this._fs.unlinkSync(path);
305
231
  }
306
232
  catch (e_10) {
@@ -314,7 +240,7 @@ export class _MutexedFS {
314
240
  async rmdir(path) {
315
241
  const env_11 = { stack: [], error: void 0, hasError: false };
316
242
  try {
317
- const _ = __addDisposableResource(env_11, await this.lock(), false);
243
+ const _ = __addDisposableResource(env_11, await this.lock('rw'), false);
318
244
  await this._fs.rmdir(path);
319
245
  }
320
246
  catch (e_11) {
@@ -328,7 +254,7 @@ export class _MutexedFS {
328
254
  rmdirSync(path) {
329
255
  const env_12 = { stack: [], error: void 0, hasError: false };
330
256
  try {
331
- const _ = __addDisposableResource(env_12, this.lockSync(), false);
257
+ const _ = __addDisposableResource(env_12, this.lockSync('rw'), false);
332
258
  return this._fs.rmdirSync(path);
333
259
  }
334
260
  catch (e_12) {
@@ -342,7 +268,7 @@ export class _MutexedFS {
342
268
  async mkdir(path, options) {
343
269
  const env_13 = { stack: [], error: void 0, hasError: false };
344
270
  try {
345
- const _ = __addDisposableResource(env_13, await this.lock(), false);
271
+ const _ = __addDisposableResource(env_13, await this.lock('rw'), false);
346
272
  return await this._fs.mkdir(path, options);
347
273
  }
348
274
  catch (e_13) {
@@ -356,7 +282,7 @@ export class _MutexedFS {
356
282
  mkdirSync(path, options) {
357
283
  const env_14 = { stack: [], error: void 0, hasError: false };
358
284
  try {
359
- const _ = __addDisposableResource(env_14, this.lockSync(), false);
285
+ const _ = __addDisposableResource(env_14, this.lockSync('rw'), false);
360
286
  return this._fs.mkdirSync(path, options);
361
287
  }
362
288
  catch (e_14) {
@@ -370,7 +296,7 @@ export class _MutexedFS {
370
296
  async readdir(path) {
371
297
  const env_15 = { stack: [], error: void 0, hasError: false };
372
298
  try {
373
- const _ = __addDisposableResource(env_15, await this.lock(), false);
299
+ const _ = __addDisposableResource(env_15, await this.lock('ro'), false);
374
300
  return await this._fs.readdir(path);
375
301
  }
376
302
  catch (e_15) {
@@ -384,7 +310,7 @@ export class _MutexedFS {
384
310
  readdirSync(path) {
385
311
  const env_16 = { stack: [], error: void 0, hasError: false };
386
312
  try {
387
- const _ = __addDisposableResource(env_16, this.lockSync(), false);
313
+ const _ = __addDisposableResource(env_16, this.lockSync('ro'), false);
388
314
  return this._fs.readdirSync(path);
389
315
  }
390
316
  catch (e_16) {
@@ -398,7 +324,7 @@ export class _MutexedFS {
398
324
  async exists(path) {
399
325
  const env_17 = { stack: [], error: void 0, hasError: false };
400
326
  try {
401
- const _ = __addDisposableResource(env_17, await this.lock(), false);
327
+ const _ = __addDisposableResource(env_17, await this.lock('ro'), false);
402
328
  return await this._fs.exists(path);
403
329
  }
404
330
  catch (e_17) {
@@ -412,7 +338,7 @@ export class _MutexedFS {
412
338
  existsSync(path) {
413
339
  const env_18 = { stack: [], error: void 0, hasError: false };
414
340
  try {
415
- const _ = __addDisposableResource(env_18, this.lockSync(), false);
341
+ const _ = __addDisposableResource(env_18, this.lockSync('ro'), false);
416
342
  return this._fs.existsSync(path);
417
343
  }
418
344
  catch (e_18) {
@@ -426,7 +352,7 @@ export class _MutexedFS {
426
352
  async link(srcpath, dstpath) {
427
353
  const env_19 = { stack: [], error: void 0, hasError: false };
428
354
  try {
429
- const _ = __addDisposableResource(env_19, await this.lock(), false);
355
+ const _ = __addDisposableResource(env_19, await this.lock('rw'), false);
430
356
  await this._fs.link(srcpath, dstpath);
431
357
  }
432
358
  catch (e_19) {
@@ -440,7 +366,7 @@ export class _MutexedFS {
440
366
  linkSync(srcpath, dstpath) {
441
367
  const env_20 = { stack: [], error: void 0, hasError: false };
442
368
  try {
443
- const _ = __addDisposableResource(env_20, this.lockSync(), false);
369
+ const _ = __addDisposableResource(env_20, this.lockSync('rw'), false);
444
370
  return this._fs.linkSync(srcpath, dstpath);
445
371
  }
446
372
  catch (e_20) {
@@ -454,7 +380,7 @@ export class _MutexedFS {
454
380
  async sync() {
455
381
  const env_21 = { stack: [], error: void 0, hasError: false };
456
382
  try {
457
- const _ = __addDisposableResource(env_21, await this.lock(), false);
383
+ const _ = __addDisposableResource(env_21, await this.lock('rw'), false);
458
384
  await this._fs.sync();
459
385
  }
460
386
  catch (e_21) {
@@ -468,7 +394,7 @@ export class _MutexedFS {
468
394
  syncSync() {
469
395
  const env_22 = { stack: [], error: void 0, hasError: false };
470
396
  try {
471
- const _ = __addDisposableResource(env_22, this.lockSync(), false);
397
+ const _ = __addDisposableResource(env_22, this.lockSync('rw'), false);
472
398
  return this._fs.syncSync();
473
399
  }
474
400
  catch (e_22) {
@@ -482,7 +408,7 @@ export class _MutexedFS {
482
408
  async read(path, buffer, offset, end) {
483
409
  const env_23 = { stack: [], error: void 0, hasError: false };
484
410
  try {
485
- const _ = __addDisposableResource(env_23, await this.lock(), false);
411
+ const _ = __addDisposableResource(env_23, await this.lock('ro'), false);
486
412
  return await this._fs.read(path, buffer, offset, end);
487
413
  }
488
414
  catch (e_23) {
@@ -496,7 +422,7 @@ export class _MutexedFS {
496
422
  readSync(path, buffer, offset, end) {
497
423
  const env_24 = { stack: [], error: void 0, hasError: false };
498
424
  try {
499
- const _ = __addDisposableResource(env_24, this.lockSync(), false);
425
+ const _ = __addDisposableResource(env_24, this.lockSync('ro'), false);
500
426
  return this._fs.readSync(path, buffer, offset, end);
501
427
  }
502
428
  catch (e_24) {
@@ -510,7 +436,7 @@ export class _MutexedFS {
510
436
  async write(path, buffer, offset) {
511
437
  const env_25 = { stack: [], error: void 0, hasError: false };
512
438
  try {
513
- const _ = __addDisposableResource(env_25, await this.lock(), false);
439
+ const _ = __addDisposableResource(env_25, await this.lock('rw'), false);
514
440
  return await this._fs.write(path, buffer, offset);
515
441
  }
516
442
  catch (e_25) {
@@ -524,7 +450,7 @@ export class _MutexedFS {
524
450
  writeSync(path, buffer, offset) {
525
451
  const env_26 = { stack: [], error: void 0, hasError: false };
526
452
  try {
527
- const _ = __addDisposableResource(env_26, this.lockSync(), false);
453
+ const _ = __addDisposableResource(env_26, this.lockSync('rw'), false);
528
454
  return this._fs.writeSync(path, buffer, offset);
529
455
  }
530
456
  catch (e_26) {
@@ -538,7 +464,7 @@ export class _MutexedFS {
538
464
  streamRead(path, options) {
539
465
  const env_27 = { stack: [], error: void 0, hasError: false };
540
466
  try {
541
- const _ = __addDisposableResource(env_27, this.lockSync(), false);
467
+ const _ = __addDisposableResource(env_27, this.lockSync('ro'), false);
542
468
  return this._fs.streamRead(path, options);
543
469
  }
544
470
  catch (e_27) {
@@ -552,7 +478,7 @@ export class _MutexedFS {
552
478
  streamWrite(path, options) {
553
479
  const env_28 = { stack: [], error: void 0, hasError: false };
554
480
  try {
555
- const _ = __addDisposableResource(env_28, this.lockSync(), false);
481
+ const _ = __addDisposableResource(env_28, this.lockSync('rw'), false);
556
482
  return this._fs.streamWrite(path, options);
557
483
  }
558
484
  catch (e_28) {
@@ -566,7 +492,7 @@ export class _MutexedFS {
566
492
  async ioctl(context, command, ...args) {
567
493
  const env_29 = { stack: [], error: void 0, hasError: false };
568
494
  try {
569
- const _ = __addDisposableResource(env_29, await this.lock(), false);
495
+ const _ = __addDisposableResource(env_29, await this.lock('rw'), false);
570
496
  return await this._fs.ioctl({ ...context, fs: this._fs }, command, ...args);
571
497
  }
572
498
  catch (e_29) {
@@ -580,7 +506,7 @@ export class _MutexedFS {
580
506
  ioctlSync(context, command, ...args) {
581
507
  const env_30 = { stack: [], error: void 0, hasError: false };
582
508
  try {
583
- const _ = __addDisposableResource(env_30, this.lockSync(), false);
509
+ const _ = __addDisposableResource(env_30, this.lockSync('rw'), false);
584
510
  return this._fs.ioctlSync({ ...context, fs: this._fs }, command, ...args);
585
511
  }
586
512
  catch (e_30) {
@@ -608,9 +534,10 @@ export class _MutexedFS {
608
534
  * Instead of extending `FileSystem`,
609
535
  * `MutexedFS` implements it in order to make sure all of the methods are passed through
610
536
  *
611
- * @todo Change `using _` to `using void` pending https://github.com/tc39/proposal-discard-binding
612
537
  * @category Internals
613
538
  * @internal
539
+ * @deprecated This is no longer needed and will be removed
540
+ * @todo [breaking] Remove
614
541
  */
615
542
  export function Mutexed(FS) {
616
543
  class MutexedFS extends _MutexedFS {
@@ -2,7 +2,6 @@
2
2
  * Implements the asynchronous API in terms of the synchronous API.
3
3
  * @category Internals
4
4
  */
5
- /* eslint-disable @typescript-eslint/require-await */
6
5
  export function Sync(FS) {
7
6
  class SyncFS extends FS {
8
7
  async exists(path) {
@@ -50,4 +49,3 @@ export function Sync(FS) {
50
49
  }
51
50
  return SyncFS;
52
51
  }
53
- /* eslint-enable @typescript-eslint/require-await */
@@ -7,16 +7,6 @@ import * as promises from './promises.js';
7
7
  import { BigIntStats } from './stats.js';
8
8
  import { ReadStream, WriteStream } from './streams.js';
9
9
  const nop = () => { };
10
- /**
11
- * Helper to collect an async iterator into an array
12
- */
13
- async function collectAsyncIterator(it) {
14
- const results = [];
15
- for await (const result of it) {
16
- results.push(result);
17
- }
18
- return results;
19
- }
20
10
  /**
21
11
  * Asynchronous rename. No arguments other than a possible exception are given to the completion callback.
22
12
  */
@@ -400,7 +390,7 @@ watch;
400
390
  export function createReadStream(path, options) {
401
391
  options = typeof options == 'object' ? options : { encoding: options };
402
392
  const _handle = promises.open.call(this, path, 'r', options?.mode);
403
- return new ReadStream({ ...options, autoClose: true }, _handle);
393
+ return new ReadStream({ ...options, autoClose: true, signal: options?.signal ?? undefined }, _handle);
404
394
  }
405
395
  createReadStream;
406
396
  /**
@@ -490,7 +480,7 @@ openAsBlob;
490
480
  export function glob(pattern, options, callback = nop) {
491
481
  callback = typeof options == 'function' ? options : callback;
492
482
  const it = promises.glob.call(this, pattern, typeof options === 'function' ? undefined : options);
493
- collectAsyncIterator(it)
483
+ Array.fromAsync(it)
494
484
  .then(results => callback(null, results ?? []))
495
485
  .catch((e) => callback(e));
496
486
  }
@@ -3,7 +3,7 @@ export * from './async.js';
3
3
  export * from './dir.js';
4
4
  export * as promises from './promises.js';
5
5
  export { BigIntStatsFs, Stats, StatsFs } from './stats.js';
6
- export type { StatsLike } from './stats.js';
6
+ export type { StatsLike } from '../internal/inode.js';
7
7
  export * from './streams.js';
8
8
  export * from './sync.js';
9
9
  export { Utf8Stream } from './utf8stream.js';
@@ -356,13 +356,8 @@ export declare function mkdtemp(this: V_Context, prefix: string, options?: fs.Bu
356
356
  * When the object is disposed, the directory and its contents will be removed asynchronously if it still exists.
357
357
  * If the directory cannot be deleted, disposal will throw an error.
358
358
  * The object has an async `remove()` method which will perform the same task.
359
- * @todo Add `satisfies` and maybe change return type once @types/node adds this.
360
359
  */
361
- export declare function mkdtempDisposable(this: V_Context, prefix: fs.PathLike, options?: fs.EncodingOption | fs.BufferEncodingOption): Promise<{
362
- path: string;
363
- remove(): Promise<void>;
364
- [Symbol.asyncDispose](): Promise<void>;
365
- }>;
360
+ export declare function mkdtempDisposable(this: V_Context, prefix: fs.PathLike, options?: fs.EncodingOption | fs.BufferEncodingOption): Promise<promises.DisposableTempDir>;
366
361
  /**
367
362
  * Asynchronous `copyFile`. Copies a file.
368
363
  * @param src The source file.
@@ -55,7 +55,7 @@ import { Exception, rethrow, UV } from 'kerium';
55
55
  import { encodeUTF8 } from 'utilium';
56
56
  import * as constants from '../constants.js';
57
57
  import { contextOf } from '../internal/contexts.js';
58
- import { hasAccess, InodeFlags, isDirectory } from '../internal/inode.js';
58
+ import { assertRemovable, hasAccess, InodeFlags, isDirectory } from '../internal/inode.js';
59
59
  import { dirname, join, matchesGlob, relative, resolve } from '../path.js';
60
60
  import '../polyfills.js';
61
61
  import { _isNoEntry, _tempDirName, globToRegex, normalizeMode, normalizeOptions, normalizePath, normalizeTime, validateFD } from '../utils.js';
@@ -63,8 +63,7 @@ import * as _async from '../vfs/async.js';
63
63
  import { checkAccess } from '../vfs/config.js';
64
64
  import { deleteFD, fromFD, toFD } from '../vfs/file.js';
65
65
  import * as flags from '../vfs/flags.js';
66
- import { _statfs, resolveMount } from '../vfs/shared.js';
67
- import { cacheOf, lockPath } from '../vfs/vcache.js';
66
+ import { _statfs } from '../vfs/shared.js';
68
67
  import { emitChange, FSWatcher } from '../vfs/watchers.js';
69
68
  import { Dir, Dirent } from './dir.js';
70
69
  import { createInterface } from './readline.js';
@@ -535,7 +534,7 @@ export async function exists(path) {
535
534
  return await fs.exists(resolved);
536
535
  }
537
536
  catch (e) {
538
- if (e instanceof Exception && e.code == 'ENOENT') {
537
+ if (e instanceof Exception && (e.code == 'ENOENT' || e.code == 'ENOTDIR' || e.code == 'EACCES')) {
539
538
  return false;
540
539
  }
541
540
  throw e;
@@ -580,14 +579,13 @@ export async function unlink(path) {
580
579
  const env_2 = { stack: [], error: void 0, hasError: false };
581
580
  try {
582
581
  path = normalizePath.call(this, path);
583
- const { fs, path: resolved } = resolveMount(path, this);
584
582
  const $ex = { syscall: 'unlink', path };
585
- const stats = await fs.stat(resolved).catch(rethrow($ex));
586
- if (checkAccess && !hasAccess(this, stats, constants.W_OK))
587
- throw UV('EACCES', $ex);
588
- const _ = __addDisposableResource(env_2, await lockPath(fs, dirname(resolved), 'rw'), false);
583
+ const { fs, cache, path: resolved } = await _async.resolve(this, path, true, $ex);
584
+ const stats = await cache.stat(resolved).catch(rethrow($ex));
585
+ assertRemovable(this, await cache.stat(dirname(resolved)).catch(rethrow($ex)), stats, $ex);
586
+ const _ = __addDisposableResource(env_2, await cache.lock(dirname(resolved), 'rw'), false);
589
587
  await fs.unlink(resolved).catch(rethrow($ex));
590
- cacheOf(fs).remove(resolved);
588
+ cache.remove(resolved);
591
589
  emitChange(this, 'rename', path.toString());
592
590
  }
593
591
  catch (e_2) {
@@ -692,18 +690,17 @@ export async function rmdir(path) {
692
690
  const env_6 = { stack: [], error: void 0, hasError: false };
693
691
  try {
694
692
  path = normalizePath.call(this, path);
695
- const { fs, path: resolved } = await _async.resolve(this, path);
693
+ const { fs, cache, path: resolved } = await _async.resolve(this, path, true);
696
694
  const $ex = { syscall: 'rmdir', path };
697
- const stats = await fs.stat(resolved).catch(rethrow($ex));
695
+ const stats = await cache.stat(resolved).catch(rethrow($ex));
698
696
  if (!stats)
699
697
  throw UV('ENOENT', $ex);
700
698
  if (!isDirectory(stats))
701
699
  throw UV('ENOTDIR', $ex);
702
- if (checkAccess && !hasAccess(this, stats, constants.W_OK))
703
- throw UV('EACCES', $ex);
704
- const _ = __addDisposableResource(env_6, await lockPath(fs, dirname(resolved), 'rw'), false);
700
+ assertRemovable(this, await cache.stat(dirname(resolved)).catch(rethrow($ex)), stats, $ex);
701
+ const _ = __addDisposableResource(env_6, await cache.lock(dirname(resolved), 'rw'), false);
705
702
  await fs.rmdir(resolved).catch(rethrow($ex));
706
- cacheOf(fs).remove(resolved);
703
+ cache.remove(resolved);
707
704
  emitChange(this, 'rename', path.toString());
708
705
  }
709
706
  catch (e_6) {
@@ -761,7 +758,7 @@ export async function symlink(dest, path, type = 'file') {
761
758
  const handle = __addDisposableResource(env_7, await _async.open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
762
759
  const encoded = encodeUTF8(normalizePath.call(this, dest, true));
763
760
  await handle.write(encoded, 0, encoded.length, 0);
764
- await handle.chmod(constants.S_IFLNK);
761
+ await handle.chmod(constants.S_IFLNK | 0o777);
765
762
  }
766
763
  catch (e_7) {
767
764
  env_7.error = e_7;
@@ -1018,7 +1015,6 @@ mkdtemp;
1018
1015
  * When the object is disposed, the directory and its contents will be removed asynchronously if it still exists.
1019
1016
  * If the directory cannot be deleted, disposal will throw an error.
1020
1017
  * The object has an async `remove()` method which will perform the same task.
1021
- * @todo Add `satisfies` and maybe change return type once @types/node adds this.
1022
1018
  */
1023
1019
  export async function mkdtempDisposable(prefix, options) {
1024
1020
  const path = _tempDirName(prefix);
@@ -1026,6 +1022,7 @@ export async function mkdtempDisposable(prefix, options) {
1026
1022
  const remove = () => rm(path, { recursive: true, force: true });
1027
1023
  return { path, remove, [Symbol.asyncDispose]: remove };
1028
1024
  }
1025
+ mkdtempDisposable;
1029
1026
  /**
1030
1027
  * Asynchronous `copyFile`. Copies a file.
1031
1028
  * @param src The source file.
@@ -1079,8 +1076,7 @@ export async function cp(source, destination, opts) {
1079
1076
  const [entries] = await Promise.all([
1080
1077
  readdir.call(this, source, { withFileTypes: true }),
1081
1078
  mkdir.call(this, destination, { recursive: true }),
1082
- ] // Ensure the destination directory exists
1083
- );
1079
+ ]);
1084
1080
  const _cp = async (dirent) => {
1085
1081
  if (opts.filter && !opts.filter(join(source, dirent.name), join(destination, dirent.name))) {
1086
1082
  return; // Skip if the filter returns false
@@ -1117,8 +1113,8 @@ export async function cp(source, destination, opts) {
1117
1113
  cp;
1118
1114
  export async function statfs(path, opts) {
1119
1115
  path = normalizePath.call(this, path);
1120
- const { fs } = resolveMount(path, this);
1121
- return Promise.resolve(_statfs(fs, opts?.bigint));
1116
+ const { fs } = await _async.resolve(this, path);
1117
+ return _statfs(fs, opts?.bigint);
1122
1118
  }
1123
1119
  export function glob(pattern, opt) {
1124
1120
  pattern = Array.isArray(pattern) ? pattern : [pattern];