@zenfs/core 2.4.0 → 2.4.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.
Files changed (100) hide show
  1. package/COPYING.md +18 -0
  2. package/{readme.md → README.md} +16 -74
  3. package/dist/backends/fetch.js +1 -1
  4. package/dist/backends/memory.js +1 -1
  5. package/dist/backends/passthrough.d.ts +1 -2
  6. package/dist/backends/single_buffer.js +1 -1
  7. package/dist/backends/store/fs.js +4 -4
  8. package/dist/config.js +15 -15
  9. package/dist/context.js +3 -2
  10. package/dist/index.d.ts +9 -3
  11. package/dist/index.js +9 -4
  12. package/dist/internal/contexts.d.ts +5 -4
  13. package/dist/internal/devices.js +1 -1
  14. package/dist/internal/error.d.ts +11 -2
  15. package/dist/internal/error.js +38 -2
  16. package/dist/internal/file_index.js +1 -1
  17. package/dist/internal/index.d.ts +1 -0
  18. package/dist/internal/index.js +2 -1
  19. package/dist/internal/index_fs.js +1 -1
  20. package/dist/internal/inode.d.ts +51 -2
  21. package/dist/internal/inode.js +18 -2
  22. package/dist/mixins/shared.js +1 -1
  23. package/dist/node/async.d.ts +278 -0
  24. package/dist/node/async.js +518 -0
  25. package/dist/node/compat.d.ts +4 -0
  26. package/dist/node/compat.js +6 -0
  27. package/dist/node/dir.d.ts +78 -0
  28. package/dist/node/dir.js +150 -0
  29. package/dist/node/index.d.ts +8 -0
  30. package/dist/node/index.js +8 -0
  31. package/dist/{vfs → node}/promises.d.ts +10 -66
  32. package/dist/{vfs → node}/promises.js +141 -478
  33. package/dist/{vfs → node}/stats.d.ts +0 -4
  34. package/dist/{vfs → node}/stats.js +1 -16
  35. package/dist/{vfs → node}/streams.js +2 -2
  36. package/dist/node/sync.d.ts +252 -0
  37. package/dist/node/sync.js +682 -0
  38. package/dist/node/types.d.ts +21 -0
  39. package/dist/path.js +3 -25
  40. package/dist/utils.d.ts +1 -7
  41. package/dist/utils.js +0 -6
  42. package/dist/vfs/acl.js +1 -1
  43. package/dist/vfs/async.d.ts +22 -278
  44. package/dist/vfs/async.js +212 -501
  45. package/dist/vfs/dir.d.ts +5 -82
  46. package/dist/vfs/dir.js +5 -233
  47. package/dist/vfs/file.d.ts +52 -13
  48. package/dist/vfs/file.js +167 -25
  49. package/dist/vfs/flags.js +1 -1
  50. package/dist/vfs/index.d.ts +2 -5
  51. package/dist/vfs/index.js +2 -5
  52. package/dist/vfs/shared.d.ts +25 -1
  53. package/dist/vfs/shared.js +6 -4
  54. package/dist/vfs/sync.d.ts +17 -245
  55. package/dist/vfs/sync.js +129 -773
  56. package/dist/vfs/watchers.d.ts +1 -1
  57. package/dist/vfs/watchers.js +2 -2
  58. package/dist/vfs/xattr.js +1 -1
  59. package/eslint.shared.js +1 -0
  60. package/package.json +7 -5
  61. package/scripts/make-index.js +5 -29
  62. package/scripts/test.js +59 -51
  63. package/tests/backend/fetch.test.ts +2 -2
  64. package/tests/backend/port.test.ts +2 -3
  65. package/tests/backend/single-buffer.test.ts +1 -1
  66. package/tests/common/casefold.test.ts +1 -1
  67. package/tests/common/context.test.ts +11 -4
  68. package/tests/common/devices.test.ts +3 -3
  69. package/tests/common/handle.test.ts +4 -3
  70. package/tests/common/inode.test.ts +2 -2
  71. package/tests/common/mounts.test.ts +1 -3
  72. package/tests/common/mutex.test.ts +1 -3
  73. package/tests/common/path.test.ts +2 -2
  74. package/tests/common/readline.test.ts +1 -1
  75. package/tests/common.ts +5 -4
  76. package/tests/fetch/fetch.ts +1 -1
  77. package/tests/fs/dir.test.ts +3 -43
  78. package/tests/fs/directory.test.ts +4 -4
  79. package/tests/fs/errors.test.ts +2 -2
  80. package/tests/fs/links.test.ts +1 -1
  81. package/tests/fs/permissions.test.ts +3 -3
  82. package/tests/fs/read.test.ts +1 -1
  83. package/tests/fs/scaling.test.ts +1 -1
  84. package/tests/fs/stat.test.ts +1 -2
  85. package/tests/fs/times.test.ts +1 -1
  86. package/tests/fs/watch.test.ts +3 -2
  87. package/tests/setup/context.ts +1 -2
  88. package/tests/setup/cow.ts +1 -1
  89. package/tests/setup/index.ts +2 -2
  90. package/tests/setup/port.ts +1 -1
  91. package/tests/setup/single-buffer.ts +1 -1
  92. package/tests/setup.ts +4 -3
  93. package/dist/vfs/types.d.ts +0 -24
  94. package/tests/assignment.ts +0 -21
  95. /package/dist/{vfs/constants.d.ts → constants.d.ts} +0 -0
  96. /package/dist/{vfs/constants.js → constants.js} +0 -0
  97. /package/dist/{readline.d.ts → node/readline.d.ts} +0 -0
  98. /package/dist/{readline.js → node/readline.js} +0 -0
  99. /package/dist/{vfs → node}/streams.d.ts +0 -0
  100. /package/dist/{vfs → node}/types.js +0 -0
@@ -51,92 +51,41 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
51
51
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
52
52
  });
53
53
  import { Buffer } from 'buffer';
54
- import { Exception, rethrow, setUVMessage, UV } from 'kerium';
55
- import { defaultContext } from '../internal/contexts.js';
56
- import { hasAccess, InodeFlags, isBlockDevice, isCharacterDevice, isDirectory, isSymbolicLink } from '../internal/inode.js';
57
- import { basename, dirname, join, matchesGlob, parse, resolve } from '../path.js';
54
+ import { Exception, rethrow, UV } from 'kerium';
55
+ import { encodeUTF8 } from 'utilium';
56
+ import * as constants from '../constants.js';
57
+ import { hasAccess, InodeFlags, isDirectory } from '../internal/inode.js';
58
+ import { join, matchesGlob, parse } from '../path.js';
58
59
  import '../polyfills.js';
59
- import { createInterface } from '../readline.js';
60
- import { __assertType, _tempDirName, globToRegex, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
61
- import { checkAccess } from './config.js';
62
- import * as constants from './constants.js';
60
+ import { _tempDirName, globToRegex, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
61
+ import * as _async from '../vfs/async.js';
62
+ import { checkAccess } from '../vfs/config.js';
63
+ import { deleteFD, fromFD, toFD } from '../vfs/file.js';
64
+ import * as flags from '../vfs/flags.js';
65
+ import { _statfs, resolveMount } from '../vfs/shared.js';
66
+ import { emitChange, FSWatcher } from '../vfs/watchers.js';
63
67
  import { Dir, Dirent } from './dir.js';
64
- import { deleteFD, fromFD, SyncHandle, toFD } from './file.js';
65
- import * as flags from './flags.js';
66
- import { _statfs, resolveMount } from './shared.js';
67
- import { _chown, BigIntStats, Stats } from './stats.js';
68
+ import { createInterface } from './readline.js';
69
+ import { BigIntStats, Stats } from './stats.js';
68
70
  import { ReadStream, WriteStream } from './streams.js';
69
- import { emitChange, FSWatcher } from './watchers.js';
70
- export * as constants from './constants.js';
71
+ export * as constants from '../constants.js';
71
72
  export class FileHandle {
72
73
  context;
73
74
  fd;
74
- _buffer;
75
- /**
76
- * Get the current file position.
77
- *
78
- * We emulate the following bug mentioned in the Node documentation:
79
- *
80
- * On Linux, positional writes don't work when the file is opened in append mode.
81
- * The kernel ignores the position argument and always appends the data to the end of the file.
82
- * @returns The current file position.
83
- */
84
- get position() {
85
- return this._sync.position;
86
- }
87
- set position(value) {
88
- this._sync.position = value;
89
- }
90
- /**
91
- * Whether the file has changes which have not been written to the FS
92
- */
93
- dirty = false;
94
- /**
95
- * Whether the file is open or closed
96
- */
97
- closed = false;
98
- /** The path relative to the context's root */
99
- get path() {
100
- return this._sync.path;
101
- }
102
- /** The internal FS associated with the handle */
103
- get fs() {
104
- return this._sync.fs;
105
- }
106
- /** The path relative to the `FileSystem`'s root */
107
- get internalPath() {
108
- return this._sync.internalPath;
109
- }
110
- /** The flag the handle was opened with */
111
- get flag() {
112
- return this._sync.flag;
113
- }
114
- /** Stats for the handle */
115
- get inode() {
116
- return this._sync.inode;
117
- }
118
- _sync;
75
+ vfs;
119
76
  constructor(context, fd) {
120
77
  this.context = context;
121
78
  this.fd = fd;
122
- this._sync = fromFD(context, fd);
123
- }
124
- get _isSync() {
125
- return !!(this.flag & constants.O_SYNC || this.inode.flags & InodeFlags.Sync);
79
+ this.vfs = fromFD(context, fd);
126
80
  }
127
81
  _emitChange() {
128
- emitChange(this.context, 'change', this.path);
82
+ emitChange(this.context, 'change', this.vfs.path);
129
83
  }
130
84
  /**
131
85
  * Asynchronous fchown(2) - Change ownership of a file.
132
86
  */
133
87
  async chown(uid, gid) {
134
- if (this.closed)
135
- throw UV('EBADF', 'chown', this.path);
136
- this.dirty = true;
137
- _chown(this.inode, uid, gid);
138
- if (this._isSync)
139
- await this.sync();
88
+ await this.vfs.chown(uid, gid);
140
89
  this._emitChange();
141
90
  }
142
91
  /**
@@ -146,13 +95,8 @@ export class FileHandle {
146
95
  async chmod(mode) {
147
96
  const numMode = normalizeMode(mode, -1);
148
97
  if (numMode < 0)
149
- throw UV('EINVAL', 'chmod', this.path);
150
- if (this.closed)
151
- throw UV('EBADF', 'chmod', this.path);
152
- this.dirty = true;
153
- this.inode.mode = (this.inode.mode & (numMode > constants.S_IFMT ? ~constants.S_IFMT : constants.S_IFMT)) | numMode;
154
- if (this._isSync || numMode > constants.S_IFMT)
155
- await this.sync();
98
+ throw UV('EINVAL', 'chmod', this.vfs.path);
99
+ await this.vfs.chmod(numMode);
156
100
  this._emitChange();
157
101
  }
158
102
  /**
@@ -165,36 +109,14 @@ export class FileHandle {
165
109
  * Asynchronous fsync(2) - synchronize a file's in-core state with the underlying storage device.
166
110
  */
167
111
  async sync() {
168
- if (this.closed)
169
- throw UV('EBADF', 'sync', this.path);
170
- if (!this.dirty)
171
- return;
172
- if (!this.fs.attributes.has('no_write'))
173
- await this.fs.touch(this.internalPath, this.inode);
174
- this.dirty = false;
112
+ await this.vfs.sync();
175
113
  }
176
114
  /**
177
115
  * Asynchronous ftruncate(2) - Truncate a file to a specified length.
178
116
  * @param length If not specified, defaults to `0`.
179
117
  */
180
118
  async truncate(length = 0) {
181
- if (this.closed)
182
- throw UV('EBADF', 'truncate', this.path);
183
- if (length < 0)
184
- throw UV('EINVAL', 'truncate', this.path);
185
- if (!(this.flag & constants.O_WRONLY || this.flag & constants.O_RDWR))
186
- throw UV('EBADF', 'truncate', this.path);
187
- if (this.fs.attributes.has('readonly'))
188
- throw UV('EROFS', 'truncate', this.path);
189
- if (this.inode.flags & InodeFlags.Immutable)
190
- throw UV('EPERM', 'truncate', this.path);
191
- this.dirty = true;
192
- if (!(this.flag & constants.O_WRONLY || this.flag & constants.O_RDWR))
193
- throw UV('EBADF', 'truncate', this.path);
194
- this.inode.mtimeMs = Date.now();
195
- this.inode.size = length;
196
- if (this._isSync)
197
- await this.sync();
119
+ await this.vfs.truncate(length);
198
120
  this._emitChange();
199
121
  }
200
122
  /**
@@ -203,13 +125,9 @@ export class FileHandle {
203
125
  * @param mtime The last modified time. If a string is provided, it will be coerced to number.
204
126
  */
205
127
  async utimes(atime, mtime) {
206
- if (this.closed)
207
- throw UV('EBADF', 'utimes', this.path);
208
- this.dirty = true;
209
- this.inode.atimeMs = normalizeTime(atime);
210
- this.inode.mtimeMs = normalizeTime(mtime);
211
- if (this._isSync)
212
- await this.sync();
128
+ atime = normalizeTime(atime);
129
+ mtime = normalizeTime(mtime);
130
+ await this.vfs.utimes(atime, mtime);
213
131
  this._emitChange();
214
132
  }
215
133
  /**
@@ -225,39 +143,11 @@ export class FileHandle {
225
143
  const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
226
144
  const flag = flags.parse(options.flag);
227
145
  if (!(flag & constants.O_APPEND))
228
- throw UV('EBADF', 'write', this.path);
146
+ throw UV('EBADF', 'write', this.vfs.path);
229
147
  const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
230
- await this._write(encodedData, 0, encodedData.length);
148
+ await this.vfs.write(encodedData, 0, encodedData.length);
231
149
  this._emitChange();
232
150
  }
233
- /**
234
- * Read data from the file.
235
- * @param buffer The buffer that the data will be written to.
236
- * @param offset The offset within the buffer where writing will start.
237
- * @param length An integer specifying the number of bytes to read.
238
- * @param position An integer specifying where to begin reading from in the file.
239
- * If position is unset, data will be read from the current file position.
240
- */
241
- async _read(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
242
- if (this.closed)
243
- throw UV('EBADF', 'read', this.path);
244
- if (this.flag & constants.O_WRONLY)
245
- throw UV('EBADF', 'read', this.path);
246
- if (!(this.inode.flags & InodeFlags.NoAtime) && !this.fs.attributes.has('no_atime')) {
247
- this.dirty = true;
248
- this.inode.atimeMs = Date.now();
249
- }
250
- let end = position + length;
251
- if (!isCharacterDevice(this.inode) && !isBlockDevice(this.inode) && end > this.inode.size) {
252
- end = position + Math.max(this.inode.size - position, 0);
253
- }
254
- this._sync.position = end;
255
- const uint8 = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
256
- await this.fs.read(this.internalPath, uint8.subarray(offset, offset + length), position, end);
257
- if (this._isSync)
258
- await this.sync();
259
- return { bytesRead: end - position, buffer };
260
- }
261
151
  async read(buffer, offset, length, position) {
262
152
  if (typeof offset == 'object' && offset != null) {
263
153
  position = offset.position;
@@ -270,19 +160,24 @@ export class FileHandle {
270
160
  offset = buffer.offset;
271
161
  buffer = buffer.buffer;
272
162
  }
273
- const pos = Number.isSafeInteger(position) ? position : this.position;
274
- buffer ||= new Uint8Array(this.inode.size);
163
+ if (position && position > Number.MAX_SAFE_INTEGER)
164
+ throw UV('EINVAL');
165
+ if (typeof position == 'bigint')
166
+ position = Number(position);
167
+ position = Number.isSafeInteger(position) ? position : this.vfs.position;
168
+ buffer ||= new Uint8Array(this.vfs.inode.size);
275
169
  offset ??= 0;
276
- return this._read(buffer, offset, length ?? buffer.byteLength - offset, pos ? Number(pos) : undefined);
170
+ const bytesRead = await this.vfs.read(buffer, offset, length ?? buffer.byteLength - offset, position);
171
+ return { bytesRead, buffer };
277
172
  }
278
173
  async readFile(_options) {
279
174
  const options = normalizeOptions(_options, null, 'r', 0o444);
280
175
  const flag = flags.parse(options.flag);
281
176
  if (flag & constants.O_WRONLY)
282
- throw UV('EBADF', 'read', this.path);
177
+ throw UV('EBADF', 'read', this.vfs.path);
283
178
  const { size } = await this.stat();
284
179
  const data = new Uint8Array(size);
285
- await this._read(data, 0, size, 0);
180
+ await this.vfs.read(data, 0, size, 0);
286
181
  const buffer = Buffer.from(data);
287
182
  return options.encoding ? buffer.toString(options.encoding) : buffer;
288
183
  }
@@ -291,9 +186,9 @@ export class FileHandle {
291
186
  * The handle will not be closed automatically.
292
187
  */
293
188
  readableWebStream(options = {}) {
294
- if (this.closed)
295
- throw UV('EBADF', 'readableWebStream', this.path);
296
- return this.fs.streamRead(this.internalPath, options);
189
+ if (this.vfs.isClosed)
190
+ throw UV('EBADF', 'readableWebStream', this.vfs.path);
191
+ return this.vfs.fs.streamRead(this.vfs.internalPath, options);
297
192
  }
298
193
  /**
299
194
  * Not part of the Node.js API!
@@ -303,11 +198,11 @@ export class FileHandle {
303
198
  * @internal
304
199
  */
305
200
  writableWebStream(options = {}) {
306
- if (this.closed)
307
- throw UV('EBADF', 'writableWebStream', this.path);
308
- if (this.inode.flags & InodeFlags.Immutable)
309
- throw UV('EPERM', 'writableWebStream', this.path);
310
- return this.fs.streamWrite(this.internalPath, options);
201
+ if (this.vfs.isClosed)
202
+ throw UV('EBADF', 'writableWebStream', this.vfs.path);
203
+ if (this.vfs.inode.flags & InodeFlags.Immutable)
204
+ throw UV('EPERM', 'writableWebStream', this.vfs.path);
205
+ return this.vfs.fs.streamWrite(this.vfs.internalPath, options);
311
206
  }
312
207
  /**
313
208
  * Creates a readline Interface object that allows reading the file line by line
@@ -315,49 +210,19 @@ export class FileHandle {
315
210
  * @returns A readline interface for reading the file line by line
316
211
  */
317
212
  readLines(options) {
318
- if (this.closed || this.flag & constants.O_WRONLY)
319
- throw UV('EBADF', 'read', this.path);
213
+ if (this.vfs.isClosed || this.vfs.flag & constants.O_WRONLY)
214
+ throw UV('EBADF', 'read', this.vfs.path);
320
215
  return createInterface({ input: this.createReadStream(options), crlfDelay: Infinity });
321
216
  }
322
217
  [Symbol.asyncDispose]() {
323
218
  return this.close();
324
219
  }
325
220
  async stat(opts) {
326
- if (this.closed)
327
- throw UV('EBADF', 'stat', this.path);
328
- if (checkAccess && !hasAccess(this.context, this.inode, constants.R_OK))
329
- throw UV('EACCES', 'stat', this.path);
330
- return opts?.bigint ? new BigIntStats(this.inode) : new Stats(this.inode);
331
- }
332
- /**
333
- * Write buffer to the file.
334
- * @param buffer Uint8Array containing the data to write to the file.
335
- * @param offset Offset in the buffer to start reading data from.
336
- * @param length The amount of bytes to write to the file.
337
- * @param position Offset from the beginning of the file where this data should be written.
338
- * If position is null, the data will be written at the current position.
339
- */
340
- async _write(buffer, offset = 0, length = buffer.byteLength - offset, position = this.position) {
341
- if (this.closed)
342
- throw UV('EBADF', 'write', this.path);
343
- if (this.inode.flags & InodeFlags.Immutable)
344
- throw UV('EPERM', 'write', this.path);
345
- if (!(this.flag & constants.O_WRONLY || this.flag & constants.O_RDWR))
346
- throw UV('EBADF', 'write', this.path);
347
- if (this.fs.attributes.has('readonly'))
348
- throw UV('EROFS', 'write', this.path);
349
- this.dirty = true;
350
- const end = position + length;
351
- const slice = buffer.subarray(offset, offset + length);
352
- if (!isCharacterDevice(this.inode) && !isBlockDevice(this.inode) && end > this.inode.size)
353
- this.inode.size = end;
354
- this.inode.mtimeMs = Date.now();
355
- this.inode.ctimeMs = Date.now();
356
- this._sync.position = position + slice.byteLength;
357
- await this.fs.write(this.internalPath, slice, position);
358
- if (this._isSync)
359
- await this.sync();
360
- return slice.byteLength;
221
+ if (this.vfs.isClosed)
222
+ throw UV('EBADF', 'stat', this.vfs.path);
223
+ if (checkAccess && !hasAccess(this.context, this.vfs.inode, constants.R_OK))
224
+ throw UV('EACCES', 'stat', this.vfs.path);
225
+ return opts?.bigint ? new BigIntStats(this.vfs.inode) : new Stats(this.vfs.inode);
361
226
  }
362
227
  /**
363
228
  * Asynchronously writes `string` to the file.
@@ -384,8 +249,8 @@ export class FileHandle {
384
249
  length = typeof lenOrEnc == 'number' ? lenOrEnc : buffer.byteLength;
385
250
  position = typeof position === 'number' ? position : null;
386
251
  }
387
- position ??= this.position;
388
- const bytesWritten = await this._write(buffer, offset, length, position);
252
+ position ??= this.vfs.position;
253
+ const bytesWritten = await this.vfs.write(buffer, offset, length, position);
389
254
  this._emitChange();
390
255
  return { buffer: data, bytesWritten };
391
256
  }
@@ -403,31 +268,18 @@ export class FileHandle {
403
268
  const options = normalizeOptions(_options, 'utf8', 'w', 0o644);
404
269
  const flag = flags.parse(options.flag);
405
270
  if (!(flag & constants.O_WRONLY || flag & constants.O_RDWR))
406
- throw UV('EBADF', 'writeFile', this.path);
271
+ throw UV('EBADF', 'writeFile', this.vfs.path);
407
272
  const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
408
- await this._write(encodedData, 0, encodedData.length, 0);
273
+ await this.vfs.write(encodedData, 0, encodedData.length, 0);
409
274
  this._emitChange();
410
275
  }
411
276
  /**
412
277
  * Asynchronous close(2) - close a `FileHandle`.
413
278
  */
414
279
  async close() {
415
- if (this.closed)
416
- throw UV('EBADF', 'close', this.path);
417
- await this.sync();
418
- this.dispose();
280
+ await this.vfs.close();
419
281
  deleteFD(this.context, this.fd);
420
282
  }
421
- /**
422
- * Cleans up. This will *not* sync the file data to the FS
423
- */
424
- dispose(force) {
425
- if (this.closed)
426
- throw UV('EBADF', 'close', this.path);
427
- if (this.dirty && !force)
428
- throw UV('EBUSY', 'close', this.path);
429
- this.closed = true;
430
- }
431
283
  /**
432
284
  * Asynchronous `writev`. Writes from multiple buffers.
433
285
  * @param buffers An array of Uint8Array buffers.
@@ -436,7 +288,7 @@ export class FileHandle {
436
288
  */
437
289
  async writev(buffers, position) {
438
290
  if (typeof position == 'number')
439
- this.position = position;
291
+ this.vfs.position = position;
440
292
  let bytesWritten = 0;
441
293
  for (const buffer of buffers) {
442
294
  bytesWritten += (await this.write(buffer)).bytesWritten;
@@ -451,7 +303,7 @@ export class FileHandle {
451
303
  */
452
304
  async readv(buffers, position) {
453
305
  if (typeof position == 'number')
454
- this.position = position;
306
+ this.vfs.position = position;
455
307
  let bytesRead = 0;
456
308
  for (const buffer of buffers) {
457
309
  bytesRead += (await this.read(buffer)).bytesRead;
@@ -463,8 +315,8 @@ export class FileHandle {
463
315
  * @param options Options for the readable stream
464
316
  */
465
317
  createReadStream(options = {}) {
466
- if (this.closed || this.flag & constants.O_WRONLY)
467
- throw UV('EBADF', 'createReadStream', this.path);
318
+ if (this.vfs.isClosed || this.vfs.flag & constants.O_WRONLY)
319
+ throw UV('EBADF', 'createReadStream', this.vfs.path);
468
320
  return new ReadStream(options, this);
469
321
  }
470
322
  /**
@@ -472,52 +324,26 @@ export class FileHandle {
472
324
  * @param options Options for the writeable stream.
473
325
  */
474
326
  createWriteStream(options = {}) {
475
- if (this.closed)
476
- throw UV('EBADF', 'createWriteStream', this.path);
477
- if (this.inode.flags & InodeFlags.Immutable)
478
- throw UV('EPERM', 'createWriteStream', this.path);
479
- if (this.fs.attributes.has('readonly'))
480
- throw UV('EROFS', 'createWriteStream', this.path);
327
+ if (this.vfs.isClosed)
328
+ throw UV('EBADF', 'createWriteStream', this.vfs.path);
329
+ if (this.vfs.inode.flags & InodeFlags.Immutable)
330
+ throw UV('EPERM', 'createWriteStream', this.vfs.path);
331
+ if (this.vfs.fs.attributes.has('readonly'))
332
+ throw UV('EROFS', 'createWriteStream', this.vfs.path);
481
333
  return new WriteStream(options, this);
482
334
  }
483
335
  }
484
336
  export async function rename(oldPath, newPath) {
485
- oldPath = normalizePath(oldPath);
486
- __assertType(oldPath);
487
- newPath = normalizePath(newPath);
488
- __assertType(newPath);
489
- const $ex = { syscall: 'rename', path: oldPath, dest: newPath };
490
- const src = resolveMount(oldPath, this);
491
- const dst = resolveMount(newPath, this);
492
- if (src.fs !== dst.fs)
493
- throw UV('EXDEV', $ex);
494
- if (dst.path.startsWith(src.path + '/'))
495
- throw UV('EBUSY', $ex);
496
- const parent = (await stat.call(this, dirname(oldPath)).catch(rethrow($ex)));
497
- const stats = (await stat.call(this, oldPath).catch(rethrow($ex)));
498
- const newParent = (await stat.call(this, dirname(newPath)).catch(rethrow($ex)));
499
- const newStats = (await stat.call(this, newPath).catch((e) => {
500
- if (e.code == 'ENOENT')
501
- return null;
502
- throw setUVMessage(Object.assign(e, $ex));
503
- }));
504
- if (checkAccess && (!parent.hasAccess(constants.R_OK, this) || !newParent.hasAccess(constants.W_OK, this)))
505
- throw UV('EACCES', $ex);
506
- if (newStats && !isDirectory(stats) && isDirectory(newStats))
507
- throw UV('EISDIR', $ex);
508
- if (newStats && isDirectory(stats) && !isDirectory(newStats))
509
- throw UV('ENOTDIR', $ex);
510
- await src.fs.rename(src.path, dst.path).catch(rethrow($ex));
511
- emitChange(this, 'rename', oldPath);
512
- emitChange(this, 'change', newPath);
337
+ await _async.rename.call(this, oldPath, newPath);
513
338
  }
514
339
  rename;
515
340
  /**
516
341
  * Test whether or not `path` exists by checking with the file system.
517
342
  */
518
343
  export async function exists(path) {
344
+ path = normalizePath(path);
519
345
  try {
520
- const { fs, path: resolved } = resolveMount(await realpath.call(this, path), this);
346
+ const { fs, path: resolved } = await _async.resolve(this, path);
521
347
  return await fs.exists(resolved);
522
348
  }
523
349
  catch (e) {
@@ -529,7 +355,7 @@ export async function exists(path) {
529
355
  }
530
356
  export async function stat(path, options) {
531
357
  path = normalizePath(path);
532
- const { fs, path: resolved } = resolveMount(await realpath.call(this, path), this);
358
+ const { fs, path: resolved } = await _async.resolve(this, path);
533
359
  const $ex = { syscall: 'stat', path };
534
360
  const stats = await fs.stat(resolved).catch(rethrow($ex));
535
361
  if (checkAccess && !hasAccess(this, stats, constants.R_OK))
@@ -540,9 +366,9 @@ stat;
540
366
  export async function lstat(path, options) {
541
367
  path = normalizePath(path);
542
368
  const $ex = { syscall: 'lstat', path };
543
- path = join(await realpath.call(this, dirname(path)), basename(path));
544
- const { fs, path: resolved } = resolveMount(path, this);
545
- const stats = await fs.stat(resolved).catch(rethrow($ex));
369
+ const { base, dir } = parse(path);
370
+ const { fs, path: parent } = await _async.resolve(this, dir);
371
+ const stats = await fs.stat(base ? join(parent, base) : parent).catch(rethrow($ex));
546
372
  if (checkAccess && !hasAccess(this, stats, constants.R_OK))
547
373
  throw UV('EACCES', $ex);
548
374
  return options?.bigint ? new BigIntStats(stats) : new Stats(stats);
@@ -576,45 +402,6 @@ export async function unlink(path) {
576
402
  emitChange(this, 'rename', path.toString());
577
403
  }
578
404
  unlink;
579
- /**
580
- * Opens a file. This helper handles the complexity of file flags.
581
- * @internal
582
- */
583
- async function _open($, path, opt) {
584
- path = normalizePath(path);
585
- const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
586
- const $ex = { syscall: 'open', path };
587
- const { fs, path: resolved, stats } = await _resolve($, path.toString(), opt.preserveSymlinks);
588
- if (!stats) {
589
- if (!(flag & constants.O_CREAT))
590
- throw UV('ENOENT', $ex);
591
- // Create the file
592
- const parentStats = await fs.stat(dirname(resolved));
593
- if (checkAccess && !hasAccess($, parentStats, constants.W_OK))
594
- throw UV('EACCES', 'open', dirname(path));
595
- if (!isDirectory(parentStats))
596
- throw UV('ENOTDIR', 'open', dirname(path));
597
- if (!opt.allowDirectory && mode & constants.S_IFDIR)
598
- throw UV('EISDIR', 'open', path);
599
- const { euid: uid, egid: gid } = $?.credentials ?? defaultContext.credentials;
600
- const inode = await fs.createFile(resolved, {
601
- mode,
602
- uid: parentStats.mode & constants.S_ISUID ? parentStats.uid : uid,
603
- gid: parentStats.mode & constants.S_ISGID ? parentStats.gid : gid,
604
- });
605
- return new FileHandle($, toFD(new SyncHandle($, path, fs, resolved, flag, inode)));
606
- }
607
- if (checkAccess && !hasAccess($, stats, flags.toMode(flag)))
608
- throw UV('EACCES', $ex);
609
- if (flag & constants.O_EXCL)
610
- throw UV('EEXIST', $ex);
611
- const handle = new FileHandle($, toFD(new SyncHandle($, path, fs, resolved, flag, stats)));
612
- if (!opt.allowDirectory && mode & constants.S_IFDIR)
613
- throw UV('EISDIR', 'open', path);
614
- if (flag & constants.O_TRUNC)
615
- await handle.truncate(0);
616
- return handle;
617
- }
618
405
  /**
619
406
  * Asynchronous file open.
620
407
  * @see https://nodejs.org/api/fs.html#fspromisesopenpath-flags-mode
@@ -622,7 +409,8 @@ async function _open($, path, opt) {
622
409
  * @param mode Mode to use to open the file. Can be ignored if the filesystem doesn't support permissions.
623
410
  */
624
411
  export async function open(path, flag = 'r', mode = 0o644) {
625
- return await _open(this, path, { flag, mode });
412
+ const handle = await _async.open(this, path, { flag, mode });
413
+ return new FileHandle(this, toFD(handle));
626
414
  }
627
415
  open;
628
416
  export async function readFile(path, _options) {
@@ -683,7 +471,7 @@ export async function appendFile(path, data, _options) {
683
471
  try {
684
472
  const options = normalizeOptions(_options, 'utf8', 'a', 0o644);
685
473
  const flag = flags.parse(options.flag);
686
- const $ex = { syscall: 'write', path: path instanceof FileHandle ? path.path : path.toString() };
474
+ const $ex = { syscall: 'write', path: path instanceof FileHandle ? path['vfs'].path : path.toString() };
687
475
  if (!(flag & constants.O_APPEND))
688
476
  throw UV('EBADF', $ex);
689
477
  const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
@@ -702,8 +490,8 @@ export async function appendFile(path, data, _options) {
702
490
  }
703
491
  appendFile;
704
492
  export async function rmdir(path) {
705
- path = await realpath.call(this, path);
706
- const { fs, path: resolved } = resolveMount(path, this);
493
+ path = normalizePath(path);
494
+ const { fs, path: resolved } = await _async.resolve(this, path);
707
495
  const $ex = { syscall: 'rmdir', path };
708
496
  const stats = await fs.stat(resolved).catch(rethrow($ex));
709
497
  if (!stats)
@@ -717,103 +505,32 @@ export async function rmdir(path) {
717
505
  }
718
506
  rmdir;
719
507
  export async function mkdir(path, options) {
720
- const { euid: uid, egid: gid } = this?.credentials ?? defaultContext.credentials;
721
508
  options = typeof options === 'object' ? options : { mode: options };
722
509
  const mode = normalizeMode(options?.mode, 0o777);
723
- path = await realpath.call(this, path);
724
- const { fs, path: resolved } = resolveMount(path, this);
725
- const __create = async (path, resolved, parent) => {
726
- if (checkAccess && !hasAccess(this, parent, constants.W_OK))
727
- throw UV('EACCES', 'mkdir', dirname(path));
728
- const inode = await fs
729
- .mkdir(resolved, {
730
- mode,
731
- uid: parent.mode & constants.S_ISUID ? parent.uid : uid,
732
- gid: parent.mode & constants.S_ISGID ? parent.gid : gid,
733
- })
734
- .catch(rethrow({ syscall: 'mkdir', path }));
735
- emitChange(this, 'rename', path);
736
- return inode;
737
- };
738
- if (!options?.recursive) {
739
- await __create(path, resolved, await fs.stat(dirname(resolved)).catch(rethrow({ path: dirname(path) })));
740
- return;
741
- }
742
- const dirs = [];
743
- let origDir = path;
744
- for (let dir = resolved; !(await fs.exists(dir).catch(rethrow({ syscall: 'exists', path: origDir }))); dir = dirname(dir), origDir = dirname(origDir)) {
745
- dirs.unshift([origDir, dir]);
746
- }
747
- if (!dirs.length)
748
- return;
749
- const stats = [await fs.stat(dirname(dirs[0][1])).catch(rethrow({ syscall: 'stat', path: dirname(dirs[0][0]) }))];
750
- for (const [i, [path, resolved]] of dirs.entries()) {
751
- stats.push(await __create(path, resolved, stats[i]));
752
- }
753
- return dirs[0][0];
510
+ return await _async.mkdir.call(this, path, { ...options, mode });
754
511
  }
755
512
  mkdir;
756
- export async function readdir(_path, options) {
513
+ export async function readdir(path, options) {
514
+ path = normalizePath(path);
757
515
  const opt = typeof options === 'object' && options != null ? options : { encoding: options, withFileTypes: false, recursive: false };
758
- const path = await realpath.call(this, _path);
759
- const { fs, path: resolved } = resolveMount(path, this);
760
- const $ex = { syscall: 'readdir', path };
761
- const stats = await fs.stat(resolved).catch(rethrow({ syscall: 'stat', path }));
762
- if (!stats)
763
- throw UV('ENOENT', $ex);
764
- if (checkAccess && !hasAccess(this, stats, constants.R_OK))
765
- throw UV('EACCES', $ex);
766
- if (!isDirectory(stats))
767
- throw UV('ENOTDIR', $ex);
768
- const entries = await fs.readdir(resolved).catch(rethrow($ex));
516
+ const rawEntries = await _async.readdir.call(this, path, opt);
769
517
  const values = [];
770
- const addEntry = async (entry) => {
771
- let entryStats;
772
- if (opt.recursive || opt.withFileTypes) {
773
- entryStats = await fs.stat(join(resolved, entry)).catch((e) => {
774
- if (e.code == 'ENOENT')
775
- return;
776
- throw setUVMessage(Object.assign(e, { syscall: 'stat', path: join(path, entry) }));
777
- });
778
- if (!entryStats)
779
- return;
780
- }
518
+ for (const entry of rawEntries) {
781
519
  if (opt.withFileTypes) {
782
- values.push(Dirent.from(join(_path.toString(), entry), entryStats, opt.encoding));
520
+ values.push(Dirent.from(entry, opt.encoding));
783
521
  }
784
522
  else if (opt.encoding == 'buffer') {
785
- values.push(Buffer.from(entry));
523
+ values.push(Buffer.from(entry.path));
786
524
  }
787
525
  else {
788
- values.push(entry);
526
+ values.push(entry.path);
789
527
  }
790
- if (!opt.recursive || !isDirectory(entryStats))
791
- return;
792
- const children = await fs.readdir(join(resolved, entry)).catch(rethrow({ syscall: 'readdir', path: join(path, entry) }));
793
- for (const child of children)
794
- await addEntry(join(entry, child));
795
- };
796
- await Promise.all(entries.map(addEntry));
528
+ }
797
529
  return values;
798
530
  }
799
531
  readdir;
800
532
  export async function link(path, dest) {
801
- path = normalizePath(path);
802
- dest = normalizePath(dest);
803
- const { fs, path: resolved } = resolveMount(path, this);
804
- const dst = resolveMount(dest, this);
805
- const $ex = { syscall: 'link', path };
806
- if (fs != dst.fs)
807
- throw UV('EXDEV', $ex);
808
- const stats = await fs.stat(dirname(resolved)).catch(rethrow({ syscall: 'stat', path: dirname(path) }));
809
- if (checkAccess && !hasAccess(this, stats, constants.R_OK))
810
- throw UV('EACCES', 'link', dirname(path));
811
- // We need to use the VFS here since the link path may be a mount point
812
- if (checkAccess && !(await stat.call(this, dirname(dest))).hasAccess(constants.W_OK, this))
813
- throw UV('EACCES', 'link', dirname(dest));
814
- if (checkAccess && !hasAccess(this, await fs.stat(resolved).catch(rethrow($ex)), constants.R_OK))
815
- throw UV('EACCES', $ex);
816
- return await fs.link(resolved, dst.path).catch(rethrow($ex));
533
+ return await _async.link.call(this, path, dest);
817
534
  }
818
535
  link;
819
536
  /**
@@ -830,8 +547,9 @@ export async function symlink(dest, path, type = 'file') {
830
547
  path = normalizePath(path);
831
548
  if (await exists.call(this, path))
832
549
  throw UV('EEXIST', 'symlink', path);
833
- const handle = __addDisposableResource(env_5, await _open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
834
- await handle.writeFile(normalizePath(dest, true));
550
+ const handle = __addDisposableResource(env_5, await _async.open(this, path, { flag: 'w+', mode: 0o644, preserveSymlinks: true }), true);
551
+ const encoded = encodeUTF8(normalizePath(dest, true));
552
+ await handle.write(encoded, 0, encoded.length, 0);
835
553
  await handle.chmod(constants.S_IFLNK);
836
554
  }
837
555
  catch (e_5) {
@@ -846,17 +564,18 @@ export async function symlink(dest, path, type = 'file') {
846
564
  }
847
565
  symlink;
848
566
  export async function readlink(path, options) {
567
+ path = normalizePath(path);
568
+ const buf = Buffer.from(await _async.readlink.call(this, path), 'utf-8');
569
+ const encoding = typeof options == 'object' ? options?.encoding : options;
570
+ // always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
571
+ return encoding == 'buffer' ? buf : buf.toString((encoding ?? 'utf-8'));
572
+ }
573
+ readlink;
574
+ export async function chown(path, uid, gid) {
849
575
  const env_6 = { stack: [], error: void 0, hasError: false };
850
576
  try {
851
- path = normalizePath(path);
852
- __assertType(path);
853
- const handle = __addDisposableResource(env_6, await _open(this, path, { flag: 'r', mode: 0o644, preserveSymlinks: true }), true);
854
- if (!isSymbolicLink(handle.inode))
855
- throw UV('EINVAL', 'readlink', path);
856
- const value = await handle.readFile();
857
- const encoding = typeof options == 'object' ? options?.encoding : options;
858
- // always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
859
- return encoding == 'buffer' ? value : value.toString((encoding ?? 'utf-8'));
577
+ const handle = __addDisposableResource(env_6, await open.call(this, path, 'r+'), true);
578
+ await handle.chown(uid, gid);
860
579
  }
861
580
  catch (e_6) {
862
581
  env_6.error = e_6;
@@ -868,11 +587,16 @@ export async function readlink(path, options) {
868
587
  await result_6;
869
588
  }
870
589
  }
871
- readlink;
872
- export async function chown(path, uid, gid) {
590
+ chown;
591
+ export async function lchown(path, uid, gid) {
873
592
  const env_7 = { stack: [], error: void 0, hasError: false };
874
593
  try {
875
- const handle = __addDisposableResource(env_7, await open.call(this, path, 'r+'), true);
594
+ const handle = __addDisposableResource(env_7, await _async.open(this, path, {
595
+ flag: 'r+',
596
+ mode: 0o644,
597
+ preserveSymlinks: true,
598
+ allowDirectory: true,
599
+ }), true);
876
600
  await handle.chown(uid, gid);
877
601
  }
878
602
  catch (e_7) {
@@ -885,17 +609,12 @@ export async function chown(path, uid, gid) {
885
609
  await result_7;
886
610
  }
887
611
  }
888
- chown;
889
- export async function lchown(path, uid, gid) {
612
+ lchown;
613
+ export async function chmod(path, mode) {
890
614
  const env_8 = { stack: [], error: void 0, hasError: false };
891
615
  try {
892
- const handle = __addDisposableResource(env_8, await _open(this, path, {
893
- flag: 'r+',
894
- mode: 0o644,
895
- preserveSymlinks: true,
896
- allowDirectory: true,
897
- }), true);
898
- await handle.chown(uid, gid);
616
+ const handle = __addDisposableResource(env_8, await open.call(this, path, 'r+'), true);
617
+ await handle.chmod(mode);
899
618
  }
900
619
  catch (e_8) {
901
620
  env_8.error = e_8;
@@ -907,11 +626,17 @@ export async function lchown(path, uid, gid) {
907
626
  await result_8;
908
627
  }
909
628
  }
910
- lchown;
911
- export async function chmod(path, mode) {
629
+ chmod;
630
+ export async function lchmod(path, mode) {
912
631
  const env_9 = { stack: [], error: void 0, hasError: false };
913
632
  try {
914
- const handle = __addDisposableResource(env_9, await open.call(this, path, 'r+'), true);
633
+ mode = normalizeMode(mode);
634
+ const handle = __addDisposableResource(env_9, await _async.open(this, path, {
635
+ flag: 'r+',
636
+ mode: 0o644,
637
+ preserveSymlinks: true,
638
+ allowDirectory: true,
639
+ }), true);
915
640
  await handle.chmod(mode);
916
641
  }
917
642
  catch (e_9) {
@@ -924,17 +649,18 @@ export async function chmod(path, mode) {
924
649
  await result_9;
925
650
  }
926
651
  }
927
- chmod;
928
- export async function lchmod(path, mode) {
652
+ lchmod;
653
+ /**
654
+ * Change file timestamps of the file referenced by the supplied path.
655
+ */
656
+ export async function utimes(path, atime, mtime) {
929
657
  const env_10 = { stack: [], error: void 0, hasError: false };
930
658
  try {
931
- const handle = __addDisposableResource(env_10, await _open(this, path, {
659
+ const handle = __addDisposableResource(env_10, await _async.open(this, path, {
932
660
  flag: 'r+',
933
- mode: 0o644,
934
- preserveSymlinks: true,
935
661
  allowDirectory: true,
936
662
  }), true);
937
- await handle.chmod(mode);
663
+ await handle.utimes(normalizeTime(atime), normalizeTime(mtime));
938
664
  }
939
665
  catch (e_10) {
940
666
  env_10.error = e_10;
@@ -946,99 +672,36 @@ export async function lchmod(path, mode) {
946
672
  await result_10;
947
673
  }
948
674
  }
949
- lchmod;
950
- /**
951
- * Change file timestamps of the file referenced by the supplied path.
952
- */
953
- export async function utimes(path, atime, mtime) {
954
- const env_11 = { stack: [], error: void 0, hasError: false };
955
- try {
956
- const handle = __addDisposableResource(env_11, await open.call(this, path, 'r+'), true);
957
- await handle.utimes(atime, mtime);
958
- }
959
- catch (e_11) {
960
- env_11.error = e_11;
961
- env_11.hasError = true;
962
- }
963
- finally {
964
- const result_11 = __disposeResources(env_11);
965
- if (result_11)
966
- await result_11;
967
- }
968
- }
969
675
  utimes;
970
676
  /**
971
677
  * Change file timestamps of the file referenced by the supplied path.
972
678
  */
973
679
  export async function lutimes(path, atime, mtime) {
974
- const env_12 = { stack: [], error: void 0, hasError: false };
680
+ const env_11 = { stack: [], error: void 0, hasError: false };
975
681
  try {
976
- const handle = __addDisposableResource(env_12, await _open(this, path, {
682
+ const handle = __addDisposableResource(env_11, await _async.open(this, path, {
977
683
  flag: 'r+',
978
684
  mode: 0o644,
979
685
  preserveSymlinks: true,
980
686
  allowDirectory: true,
981
687
  }), true);
982
- await handle.utimes(new Date(atime), new Date(mtime));
688
+ await handle.utimes(normalizeTime(atime), normalizeTime(mtime));
983
689
  }
984
- catch (e_12) {
985
- env_12.error = e_12;
986
- env_12.hasError = true;
690
+ catch (e_11) {
691
+ env_11.error = e_11;
692
+ env_11.hasError = true;
987
693
  }
988
694
  finally {
989
- const result_12 = __disposeResources(env_12);
990
- if (result_12)
991
- await result_12;
695
+ const result_11 = __disposeResources(env_11);
696
+ if (result_11)
697
+ await result_11;
992
698
  }
993
699
  }
994
700
  lutimes;
995
- /**
996
- * Resolves the mount and real path for a path.
997
- * Additionally, any stats fetched will be returned for de-duplication
998
- * @internal @hidden
999
- */
1000
- async function _resolve($, path, preserveSymlinks) {
1001
- if (preserveSymlinks) {
1002
- const resolved = resolveMount(path, $);
1003
- const stats = await resolved.fs.stat(resolved.path).catch(() => undefined);
1004
- return { ...resolved, fullPath: path, stats };
1005
- }
1006
- /* Try to resolve it directly. If this works,
1007
- that means we don't need to perform any resolution for parent directories. */
1008
- try {
1009
- const resolved = resolveMount(path, $);
1010
- // Stat it to make sure it exists
1011
- const stats = await resolved.fs.stat(resolved.path);
1012
- if (!isSymbolicLink(stats)) {
1013
- return { ...resolved, fullPath: path, stats };
1014
- }
1015
- const target = resolve.call($, dirname(path), (await readlink.call($, path)).toString());
1016
- return await _resolve($, target);
1017
- }
1018
- catch {
1019
- // Go the long way
1020
- }
1021
- const { base, dir } = parse(path);
1022
- const realDir = dir == '/' ? '/' : await realpath.call($, dir);
1023
- const maybePath = join(realDir, base);
1024
- const resolved = resolveMount(maybePath, $);
1025
- const stats = await resolved.fs.stat(resolved.path).catch((e) => {
1026
- if (e.code == 'ENOENT')
1027
- return;
1028
- throw setUVMessage(Object.assign(e, { syscall: 'stat', path: maybePath }));
1029
- });
1030
- if (!stats)
1031
- return { ...resolved, fullPath: path };
1032
- if (!isSymbolicLink(stats)) {
1033
- return { ...resolved, fullPath: maybePath, stats };
1034
- }
1035
- const target = resolve.call($, realDir, (await readlink.call($, maybePath)).toString());
1036
- return await _resolve($, target);
1037
- }
1038
701
  export async function realpath(path, options) {
1039
702
  const encoding = typeof options == 'string' ? options : (options?.encoding ?? 'utf8');
1040
703
  path = normalizePath(path);
1041
- const { fullPath } = await _resolve(this, path);
704
+ const { fullPath } = await _async.resolve(this, path);
1042
705
  if (encoding == 'utf8' || encoding == 'utf-8')
1043
706
  return fullPath;
1044
707
  const buf = Buffer.from(fullPath, 'utf-8');