@zenfs/core 1.11.4 → 2.1.0

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 (135) hide show
  1. package/dist/backends/backend.d.ts +19 -15
  2. package/dist/backends/backend.js +36 -19
  3. package/dist/backends/cow.d.ts +20 -30
  4. package/dist/backends/cow.js +83 -192
  5. package/dist/backends/fetch.d.ts +1 -0
  6. package/dist/backends/fetch.js +30 -30
  7. package/dist/backends/index.d.ts +1 -1
  8. package/dist/backends/index.js +1 -1
  9. package/dist/backends/memory.d.ts +5 -7
  10. package/dist/backends/memory.js +2 -3
  11. package/dist/backends/passthrough.d.ts +19 -23
  12. package/dist/backends/passthrough.js +98 -288
  13. package/dist/backends/port.d.ts +220 -0
  14. package/dist/backends/port.js +328 -0
  15. package/dist/backends/single_buffer.d.ts +59 -47
  16. package/dist/backends/single_buffer.js +468 -219
  17. package/dist/backends/store/fs.d.ts +25 -35
  18. package/dist/backends/store/fs.js +276 -315
  19. package/dist/backends/store/store.d.ts +10 -15
  20. package/dist/backends/store/store.js +11 -10
  21. package/dist/config.d.ts +3 -12
  22. package/dist/config.js +17 -19
  23. package/dist/context.d.ts +8 -21
  24. package/dist/context.js +33 -10
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +2 -1
  27. package/dist/internal/contexts.d.ts +63 -0
  28. package/dist/internal/contexts.js +15 -0
  29. package/dist/internal/credentials.d.ts +2 -11
  30. package/dist/internal/credentials.js +0 -19
  31. package/dist/internal/devices.d.ts +18 -80
  32. package/dist/internal/devices.js +103 -316
  33. package/dist/internal/error.d.ts +9 -204
  34. package/dist/internal/error.js +19 -288
  35. package/dist/internal/file_index.d.ts +1 -1
  36. package/dist/internal/file_index.js +11 -11
  37. package/dist/internal/filesystem.d.ts +51 -94
  38. package/dist/internal/filesystem.js +21 -20
  39. package/dist/internal/index.d.ts +1 -2
  40. package/dist/internal/index.js +1 -2
  41. package/dist/internal/index_fs.d.ts +12 -30
  42. package/dist/internal/index_fs.js +37 -69
  43. package/dist/internal/inode.d.ts +140 -24
  44. package/dist/internal/inode.js +515 -66
  45. package/dist/mixins/async.js +52 -112
  46. package/dist/mixins/mutexed.d.ts +19 -18
  47. package/dist/mixins/mutexed.js +62 -64
  48. package/dist/mixins/readonly.d.ts +7 -6
  49. package/dist/mixins/readonly.js +24 -18
  50. package/dist/mixins/sync.js +8 -8
  51. package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
  52. package/dist/{vfs/path.js → path.js} +6 -9
  53. package/dist/polyfills.js +1 -1
  54. package/dist/readline.d.ts +134 -0
  55. package/dist/readline.js +623 -0
  56. package/dist/utils.d.ts +9 -37
  57. package/dist/utils.js +17 -85
  58. package/dist/vfs/acl.d.ts +42 -0
  59. package/dist/vfs/acl.js +268 -0
  60. package/dist/vfs/async.d.ts +9 -23
  61. package/dist/vfs/async.js +25 -27
  62. package/dist/vfs/config.d.ts +6 -18
  63. package/dist/vfs/config.js +8 -18
  64. package/dist/vfs/dir.d.ts +3 -3
  65. package/dist/vfs/dir.js +12 -12
  66. package/dist/vfs/file.d.ts +106 -0
  67. package/dist/vfs/file.js +244 -0
  68. package/dist/vfs/flags.d.ts +19 -0
  69. package/dist/vfs/flags.js +62 -0
  70. package/dist/vfs/index.d.ts +4 -10
  71. package/dist/vfs/index.js +4 -13
  72. package/dist/vfs/ioctl.d.ts +88 -0
  73. package/dist/vfs/ioctl.js +409 -0
  74. package/dist/vfs/promises.d.ts +81 -19
  75. package/dist/vfs/promises.js +404 -288
  76. package/dist/vfs/shared.d.ts +7 -37
  77. package/dist/vfs/shared.js +29 -85
  78. package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
  79. package/dist/{stats.js → vfs/stats.js} +11 -66
  80. package/dist/vfs/streams.d.ts +1 -0
  81. package/dist/vfs/streams.js +32 -27
  82. package/dist/vfs/sync.d.ts +3 -3
  83. package/dist/vfs/sync.js +263 -260
  84. package/dist/vfs/watchers.d.ts +2 -2
  85. package/dist/vfs/watchers.js +12 -12
  86. package/dist/vfs/xattr.d.ts +116 -0
  87. package/dist/vfs/xattr.js +201 -0
  88. package/package.json +5 -3
  89. package/readme.md +1 -1
  90. package/scripts/test.js +2 -2
  91. package/tests/assignment.ts +1 -1
  92. package/tests/backend/config.worker.js +4 -1
  93. package/tests/backend/fetch.test.ts +3 -0
  94. package/tests/backend/port.test.ts +19 -33
  95. package/tests/backend/remote.worker.js +4 -1
  96. package/tests/backend/single-buffer.test.ts +53 -0
  97. package/tests/backend/single-buffer.worker.js +30 -0
  98. package/tests/common/context.test.ts +3 -3
  99. package/tests/common/handle.test.ts +17 -12
  100. package/tests/common/mutex.test.ts +9 -9
  101. package/tests/common/path.test.ts +1 -1
  102. package/tests/common/readline.test.ts +104 -0
  103. package/tests/common.ts +4 -19
  104. package/tests/fetch/fetch.ts +2 -2
  105. package/tests/fs/append.test.ts +4 -4
  106. package/tests/fs/directory.test.ts +25 -25
  107. package/tests/fs/errors.test.ts +15 -19
  108. package/tests/fs/links.test.ts +4 -3
  109. package/tests/fs/open.test.ts +4 -21
  110. package/tests/fs/permissions.test.ts +14 -18
  111. package/tests/fs/read.test.ts +10 -9
  112. package/tests/fs/readFile.test.ts +10 -26
  113. package/tests/fs/rename.test.ts +4 -9
  114. package/tests/fs/stat.test.ts +8 -8
  115. package/tests/fs/streams.test.ts +2 -11
  116. package/tests/fs/times.test.ts +7 -7
  117. package/tests/fs/truncate.test.ts +8 -36
  118. package/tests/fs/watch.test.ts +10 -10
  119. package/tests/fs/write.test.ts +77 -13
  120. package/tests/fs/xattr.test.ts +85 -0
  121. package/tests/logs.js +22 -0
  122. package/tests/setup/context.ts +1 -1
  123. package/tests/setup/index.ts +3 -3
  124. package/tests/setup/port.ts +7 -1
  125. package/dist/backends/port/fs.d.ts +0 -84
  126. package/dist/backends/port/fs.js +0 -151
  127. package/dist/backends/port/rpc.d.ts +0 -77
  128. package/dist/backends/port/rpc.js +0 -100
  129. package/dist/backends/store/simple.d.ts +0 -20
  130. package/dist/backends/store/simple.js +0 -13
  131. package/dist/internal/file.d.ts +0 -359
  132. package/dist/internal/file.js +0 -751
  133. package/dist/internal/log.d.ts +0 -133
  134. package/dist/internal/log.js +0 -218
  135. package/tests/fs/writeFile.test.ts +0 -70
package/dist/vfs/sync.js CHANGED
@@ -51,39 +51,59 @@ 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 { credentials } from '../internal/credentials.js';
55
- import { Errno, ErrnoError } from '../internal/error.js';
56
- import { flagToMode, isAppendable, isExclusive, isReadable, isTruncating, isWriteable, parseFlag } from '../internal/file.js';
57
- import { BigIntStats } from '../stats.js';
58
- import { decodeUTF8, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
59
- import { config } from './config.js';
54
+ import { Errno, Exception, setUVMessage, UV } from 'kerium';
55
+ import { decodeUTF8, encodeUTF8 } from 'utilium';
56
+ import { defaultContext } from '../internal/contexts.js';
57
+ import { wrap } from '../internal/error.js';
58
+ import { hasAccess, isDirectory, isSymbolicLink } from '../internal/inode.js';
59
+ import { dirname, join, parse, resolve } from '../path.js';
60
+ import { __assertType, normalizeMode, normalizeOptions, normalizePath, normalizeTime } from '../utils.js';
61
+ import { checkAccess } from './config.js';
60
62
  import * as constants from './constants.js';
61
63
  import { Dir, Dirent } from './dir.js';
62
- import { dirname, join, parse, resolve } from './path.js';
63
- import { _statfs, fd2file, fdMap, file2fd, fixError, resolveMount } from './shared.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 { BigIntStats, Stats } from './stats.js';
64
68
  import { emitChange } from './watchers.js';
65
69
  export function renameSync(oldPath, newPath) {
66
70
  oldPath = normalizePath(oldPath);
71
+ __assertType(oldPath);
67
72
  newPath = normalizePath(newPath);
68
- const oldMount = resolveMount(oldPath, this);
69
- const newMount = resolveMount(newPath, this);
70
- if (config.checkAccess && !statSync.call(this, dirname(oldPath)).hasAccess(constants.W_OK, this)) {
71
- throw ErrnoError.With('EACCES', oldPath, 'rename');
73
+ __assertType(newPath);
74
+ const src = resolveMount(oldPath, this);
75
+ const dst = resolveMount(newPath, this);
76
+ const $ex = { syscall: 'rename', path: oldPath, dest: newPath };
77
+ if (src.fs !== dst.fs)
78
+ throw UV('EXDEV', $ex);
79
+ if (dst.path.startsWith(src.path + '/'))
80
+ throw UV('EBUSY', $ex);
81
+ const oldStats = statSync.call(this, oldPath);
82
+ const oldParent = statSync.call(this, dirname(oldPath));
83
+ const newParent = statSync.call(this, dirname(newPath));
84
+ let newStats;
85
+ try {
86
+ newStats = statSync.call(this, newPath);
72
87
  }
88
+ catch (e) {
89
+ setUVMessage(Object.assign(e, $ex));
90
+ if (e.code != 'ENOENT')
91
+ throw e;
92
+ }
93
+ if (checkAccess && (!oldParent.hasAccess(constants.R_OK, this) || !newParent.hasAccess(constants.W_OK, this)))
94
+ throw UV('EACCES', $ex);
95
+ if (newStats && !isDirectory(oldStats) && isDirectory(newStats))
96
+ throw UV('EISDIR', $ex);
97
+ if (newStats && isDirectory(oldStats) && !isDirectory(newStats))
98
+ throw UV('ENOTDIR', $ex);
73
99
  try {
74
- if (oldMount === newMount) {
75
- oldMount.fs.renameSync(oldMount.path, newMount.path);
76
- emitChange(this, 'rename', oldPath.toString());
77
- emitChange(this, 'change', newPath.toString());
78
- return;
79
- }
80
- writeFileSync.call(this, newPath, readFileSync(oldPath));
81
- unlinkSync.call(this, oldPath);
82
- emitChange(this, 'rename', oldPath.toString());
100
+ src.fs.renameSync(src.path, dst.path);
83
101
  }
84
102
  catch (e) {
85
- throw fixError(e, { [oldMount.path]: oldPath, [newMount.path]: newPath });
103
+ throw setUVMessage(Object.assign(e, $ex));
86
104
  }
105
+ emitChange(this, 'rename', oldPath);
106
+ emitChange(this, 'change', newPath);
87
107
  }
88
108
  renameSync;
89
109
  /**
@@ -96,9 +116,8 @@ export function existsSync(path) {
96
116
  return fs.existsSync(resolvedPath);
97
117
  }
98
118
  catch (e) {
99
- if (e.errno == Errno.ENOENT) {
119
+ if (e.errno == Errno.ENOENT)
100
120
  return false;
101
- }
102
121
  throw e;
103
122
  }
104
123
  }
@@ -106,28 +125,25 @@ existsSync;
106
125
  export function statSync(path, options) {
107
126
  path = normalizePath(path);
108
127
  const { fs, path: resolved } = resolveMount(realpathSync.call(this, path), this);
128
+ let stats;
109
129
  try {
110
- const stats = fs.statSync(resolved);
111
- if (config.checkAccess && !stats.hasAccess(constants.R_OK, this)) {
112
- throw ErrnoError.With('EACCES', resolved, 'stat');
113
- }
114
- return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
130
+ stats = fs.statSync(resolved);
115
131
  }
116
132
  catch (e) {
117
- throw fixError(e, { [resolved]: path });
133
+ throw setUVMessage(Object.assign(e, { path }));
118
134
  }
135
+ if (checkAccess && !hasAccess(this, stats, constants.R_OK))
136
+ throw UV('EACCES', { syscall: 'stat', path });
137
+ return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
119
138
  }
120
139
  statSync;
121
140
  export function lstatSync(path, options) {
122
141
  path = normalizePath(path);
123
142
  const { fs, path: resolved } = resolveMount(path, this);
124
- try {
125
- const stats = fs.statSync(resolved);
126
- return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
127
- }
128
- catch (e) {
129
- throw fixError(e, { [resolved]: path });
130
- }
143
+ const stats = wrap(fs, 'statSync', path)(resolved);
144
+ if (checkAccess && !hasAccess(this, stats, constants.R_OK))
145
+ throw UV('EACCES', { syscall: 'lstat', path });
146
+ return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
131
147
  }
132
148
  lstatSync;
133
149
  export function truncateSync(path, len = 0) {
@@ -135,10 +151,9 @@ export function truncateSync(path, len = 0) {
135
151
  try {
136
152
  const file = __addDisposableResource(env_1, _openSync.call(this, path, { flag: 'r+' }), false);
137
153
  len || (len = 0);
138
- if (len < 0) {
139
- throw new ErrnoError(Errno.EINVAL);
140
- }
141
- file.truncateSync(len);
154
+ if (len < 0)
155
+ throw UV('EINVAL', 'truncate', path.toString());
156
+ file.truncate(len);
142
157
  }
143
158
  catch (e_1) {
144
159
  env_1.error = e_1;
@@ -153,31 +168,21 @@ export function unlinkSync(path) {
153
168
  path = normalizePath(path);
154
169
  const { fs, path: resolved } = resolveMount(path, this);
155
170
  try {
156
- if (config.checkAccess && !fs.statSync(resolved).hasAccess(constants.W_OK, this)) {
157
- throw ErrnoError.With('EACCES', resolved, 'unlink');
171
+ if (checkAccess && !hasAccess(this, fs.statSync(resolved), constants.W_OK)) {
172
+ throw UV('EACCES', 'unlink');
158
173
  }
159
174
  fs.unlinkSync(resolved);
160
- emitChange(this, 'rename', path.toString());
161
175
  }
162
176
  catch (e) {
163
- throw fixError(e, { [resolved]: path });
177
+ throw setUVMessage(Object.assign(e, { path }));
164
178
  }
179
+ emitChange(this, 'rename', path.toString());
165
180
  }
166
181
  unlinkSync;
167
- /**
168
- * Manually apply setuid/setgid.
169
- */
170
- function applySetId(file, uid, gid) {
171
- if (file.fs.attributes.has('setid'))
172
- return;
173
- const parent = file.fs.statSync(dirname(file.path));
174
- file.chownSync(parent.mode & constants.S_ISUID ? parent.uid : uid, // manually apply setuid/setgid
175
- parent.mode & constants.S_ISGID ? parent.gid : gid);
176
- }
177
182
  function _openSync(path, opt) {
178
183
  var _a;
179
184
  path = normalizePath(path);
180
- const mode = normalizeMode(opt.mode, 0o644), flag = parseFlag(opt.flag);
185
+ const mode = normalizeMode(opt.mode, 0o644), flag = flags.parse(opt.flag);
181
186
  path = opt.preserveSymlinks ? path : realpathSync.call(this, path);
182
187
  const { fs, path: resolved } = resolveMount(path, this);
183
188
  let stats;
@@ -188,44 +193,49 @@ function _openSync(path, opt) {
188
193
  // nothing
189
194
  }
190
195
  if (!stats) {
191
- if ((!isWriteable(flag) && !isAppendable(flag)) || flag == 'r+') {
192
- throw ErrnoError.With('ENOENT', path, '_open');
196
+ if (!(flag & constants.O_CREAT)) {
197
+ throw UV('ENOENT', 'open', path);
193
198
  }
194
199
  // Create the file
195
200
  const parentStats = fs.statSync(dirname(resolved));
196
- if (config.checkAccess && !parentStats.hasAccess(constants.W_OK, this)) {
197
- throw ErrnoError.With('EACCES', dirname(path), '_open');
201
+ if (checkAccess && !hasAccess(this, parentStats, constants.W_OK)) {
202
+ throw UV('EACCES', 'open', path);
198
203
  }
199
- if (!parentStats.isDirectory()) {
200
- throw ErrnoError.With('ENOTDIR', dirname(path), '_open');
204
+ if (!isDirectory(parentStats)) {
205
+ throw UV('ENOTDIR', 'open', path);
201
206
  }
202
- const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : credentials;
203
- const file = fs.createFileSync(resolved, flag, mode, { uid, gid });
204
207
  if (!opt.allowDirectory && mode & constants.S_IFDIR)
205
- throw ErrnoError.With('EISDIR', path, '_open');
206
- applySetId(file, uid, gid);
207
- return file;
208
- }
209
- if (config.checkAccess && (!stats.hasAccess(mode, this) || !stats.hasAccess(flagToMode(flag), this))) {
210
- throw ErrnoError.With('EACCES', path, '_open');
211
- }
212
- if (isExclusive(flag)) {
213
- throw ErrnoError.With('EEXIST', path, '_open');
214
- }
215
- const file = fs.openFileSync(resolved, flag);
216
- if (isTruncating(flag)) {
217
- file.truncateSync(0);
218
- }
208
+ throw UV('EISDIR', 'open', path);
209
+ if (checkAccess && !hasAccess(this, parentStats, constants.W_OK)) {
210
+ throw UV('EACCES', 'open', path);
211
+ }
212
+ const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
213
+ const inode = fs.createFileSync(resolved, {
214
+ mode,
215
+ uid: parentStats.mode & constants.S_ISUID ? parentStats.uid : uid,
216
+ gid: parentStats.mode & constants.S_ISGID ? parentStats.gid : gid,
217
+ });
218
+ return new SyncHandle(this, path, fs, resolved, flag, inode);
219
+ }
220
+ if (checkAccess && (!hasAccess(this, stats, mode) || !hasAccess(this, stats, flags.toMode(flag)))) {
221
+ throw UV('EACCES', 'open', path);
222
+ }
223
+ if (flag & constants.O_EXCL)
224
+ throw UV('EEXIST', 'open', path);
225
+ const file = new SyncHandle(this, path, fs, resolved, flag, stats);
219
226
  if (!opt.allowDirectory && stats.mode & constants.S_IFDIR)
220
- throw ErrnoError.With('EISDIR', path, '_open');
227
+ throw UV('EISDIR', 'open', path);
228
+ if (flag & constants.O_TRUNC)
229
+ file.truncate(0);
221
230
  return file;
222
231
  }
223
232
  /**
224
233
  * Synchronous file open.
225
- * @see http://www.manpagez.com/man/2/open/
234
+ * @see https://nodejs.org/api/fs.html#fsopensyncpath-flags-mode
235
+ * @param flag {@link https://nodejs.org/api/fs.html#file-system-flags}
226
236
  */
227
237
  export function openSync(path, flag, mode = constants.F_OK) {
228
- return file2fd(_openSync.call(this, path, { flag, mode }));
238
+ return toFD(_openSync.call(this, path, { flag, mode }));
229
239
  }
230
240
  openSync;
231
241
  /**
@@ -233,19 +243,22 @@ openSync;
233
243
  * @internal
234
244
  */
235
245
  export function lopenSync(path, flag, mode) {
236
- return file2fd(_openSync.call(this, path, { flag, mode, preserveSymlinks: true }));
246
+ return toFD(_openSync.call(this, path, { flag, mode, preserveSymlinks: true }));
237
247
  }
238
- function _readFileSync(path, flag, preserveSymlinks) {
248
+ export function readFileSync(path, _options = {}) {
239
249
  const env_2 = { stack: [], error: void 0, hasError: false };
240
250
  try {
241
- path = normalizePath(path);
242
- // Get file.
243
- const file = __addDisposableResource(env_2, _openSync.call(this, path, { flag, mode: 0o644, preserveSymlinks }), false);
244
- const stat = file.statSync();
245
- // Allocate buffer.
246
- const data = new Uint8Array(stat.size);
247
- file.readSync(data, 0, stat.size, 0);
248
- return data;
251
+ const options = normalizeOptions(_options, null, 'r', 0o644);
252
+ const flag = flags.parse(options.flag);
253
+ if (flag & constants.O_WRONLY)
254
+ throw UV('EBADF', 'read', path.toString());
255
+ const file = __addDisposableResource(env_2, typeof path == 'number'
256
+ ? fromFD(this, path)
257
+ : _openSync.call(this, path.toString(), { flag: options.flag, mode: 0o644, preserveSymlinks: false }), false);
258
+ const { size } = file.stat();
259
+ const data = Buffer.alloc(size);
260
+ file.read(data, 0, size, 0);
261
+ return options.encoding ? data.toString(options.encoding) : data;
249
262
  }
250
263
  catch (e_2) {
251
264
  env_2.error = e_2;
@@ -255,37 +268,30 @@ function _readFileSync(path, flag, preserveSymlinks) {
255
268
  __disposeResources(env_2);
256
269
  }
257
270
  }
258
- export function readFileSync(path, _options = {}) {
259
- const options = normalizeOptions(_options, null, 'r', 0o644);
260
- const flag = parseFlag(options.flag);
261
- if (!isReadable(flag)) {
262
- throw new ErrnoError(Errno.EINVAL, 'Flag passed to readFile must allow for reading');
263
- }
264
- const data = Buffer.from(_readFileSync.call(this, typeof path == 'number' ? fd2file(path).path : path, options.flag, false));
265
- return options.encoding ? data.toString(options.encoding) : data;
266
- }
267
271
  readFileSync;
268
272
  export function writeFileSync(path, data, _options = {}) {
269
273
  const env_3 = { stack: [], error: void 0, hasError: false };
270
274
  try {
271
275
  const options = normalizeOptions(_options, 'utf8', 'w+', 0o644);
272
- const flag = parseFlag(options.flag);
273
- if (!isWriteable(flag)) {
274
- throw new ErrnoError(Errno.EINVAL, 'Flag passed to writeFile must allow for writing');
276
+ const flag = flags.parse(options.flag);
277
+ if (!(flag & constants.O_WRONLY || flag & constants.O_RDWR)) {
278
+ throw new Exception(Errno.EINVAL, 'Flag passed to writeFile must allow for writing');
275
279
  }
276
280
  if (typeof data != 'string' && !options.encoding) {
277
- throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
281
+ throw new Exception(Errno.EINVAL, 'Encoding not specified');
278
282
  }
279
283
  const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
280
284
  if (!encodedData) {
281
- throw new ErrnoError(Errno.EINVAL, 'Data not specified');
282
- }
283
- const file = __addDisposableResource(env_3, _openSync.call(this, typeof path == 'number' ? fd2file(path).path : path.toString(), {
284
- flag,
285
- mode: options.mode,
286
- preserveSymlinks: true,
287
- }), false);
288
- file.writeSync(encodedData, 0, encodedData.byteLength, 0);
285
+ throw new Exception(Errno.EINVAL, 'Data not specified');
286
+ }
287
+ const file = __addDisposableResource(env_3, typeof path == 'number'
288
+ ? fromFD(this, path)
289
+ : _openSync.call(this, path.toString(), {
290
+ flag,
291
+ mode: options.mode,
292
+ preserveSymlinks: true,
293
+ }), false);
294
+ file.write(encodedData, 0, encodedData.byteLength, 0);
289
295
  emitChange(this, 'change', path.toString());
290
296
  }
291
297
  catch (e_3) {
@@ -307,20 +313,20 @@ export function appendFileSync(filename, data, _options = {}) {
307
313
  const env_4 = { stack: [], error: void 0, hasError: false };
308
314
  try {
309
315
  const options = normalizeOptions(_options, 'utf8', 'a+', 0o644);
310
- const flag = parseFlag(options.flag);
311
- if (!isAppendable(flag)) {
312
- throw new ErrnoError(Errno.EINVAL, 'Flag passed to appendFile must allow for appending');
316
+ const flag = flags.parse(options.flag);
317
+ if (!(flag & constants.O_APPEND)) {
318
+ throw new Exception(Errno.EINVAL, 'Flag passed to appendFile must allow for appending');
313
319
  }
314
320
  if (typeof data != 'string' && !options.encoding) {
315
- throw new ErrnoError(Errno.EINVAL, 'Encoding not specified');
321
+ throw new Exception(Errno.EINVAL, 'Encoding not specified');
316
322
  }
317
323
  const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
318
- const file = __addDisposableResource(env_4, _openSync.call(this, typeof filename == 'number' ? fd2file(filename).path : filename.toString(), {
324
+ const file = __addDisposableResource(env_4, _openSync.call(this, typeof filename == 'number' ? fromFD(this, filename).path : filename.toString(), {
319
325
  flag,
320
326
  mode: options.mode,
321
327
  preserveSymlinks: true,
322
328
  }), false);
323
- file.writeSync(encodedData, 0, encodedData.byteLength);
329
+ file.write(encodedData, 0, encodedData.byteLength);
324
330
  }
325
331
  catch (e_4) {
326
332
  env_4.error = e_4;
@@ -332,29 +338,29 @@ export function appendFileSync(filename, data, _options = {}) {
332
338
  }
333
339
  appendFileSync;
334
340
  export function fstatSync(fd, options) {
335
- const stats = fd2file(fd).statSync();
336
- return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : stats;
341
+ const stats = fromFD(this, fd).stat();
342
+ return (options === null || options === void 0 ? void 0 : options.bigint) ? new BigIntStats(stats) : new Stats(stats);
337
343
  }
338
344
  fstatSync;
339
345
  export function closeSync(fd) {
340
- fd2file(fd).closeSync();
341
- fdMap.delete(fd);
346
+ fromFD(this, fd).close();
347
+ deleteFD(this, fd);
342
348
  }
343
349
  closeSync;
344
350
  export function ftruncateSync(fd, len = 0) {
345
351
  len || (len = 0);
346
352
  if (len < 0) {
347
- throw new ErrnoError(Errno.EINVAL);
353
+ throw new Exception(Errno.EINVAL);
348
354
  }
349
- fd2file(fd).truncateSync(len);
355
+ fromFD(this, fd).truncate(len);
350
356
  }
351
357
  ftruncateSync;
352
358
  export function fsyncSync(fd) {
353
- fd2file(fd).syncSync();
359
+ fromFD(this, fd).sync();
354
360
  }
355
361
  fsyncSync;
356
362
  export function fdatasyncSync(fd) {
357
- fd2file(fd).datasyncSync();
363
+ fromFD(this, fd).datasync();
358
364
  }
359
365
  fdatasyncSync;
360
366
  export function writeSync(fd, data, posOrOff, lenOrEnc, pos) {
@@ -374,9 +380,9 @@ export function writeSync(fd, data, posOrOff, lenOrEnc, pos) {
374
380
  length = lenOrEnc;
375
381
  position = typeof pos === 'number' ? pos : null;
376
382
  }
377
- const file = fd2file(fd);
383
+ const file = fromFD(this, fd);
378
384
  position !== null && position !== void 0 ? position : (position = file.position);
379
- const bytesWritten = file.writeSync(buffer, offset, length, position);
385
+ const bytesWritten = file.write(buffer, offset, length, position);
380
386
  emitChange(this, 'change', file.path);
381
387
  return bytesWritten;
382
388
  }
@@ -390,7 +396,7 @@ writeSync;
390
396
  * If position is null, data will be read from the current file position.
391
397
  */
392
398
  export function readSync(fd, buffer, options, length, position) {
393
- const file = fd2file(fd);
399
+ const file = fromFD(this, fd);
394
400
  const offset = typeof options == 'object' ? options.offset : options;
395
401
  if (typeof options == 'object') {
396
402
  length = options.length;
@@ -400,102 +406,85 @@ export function readSync(fd, buffer, options, length, position) {
400
406
  if (isNaN(position)) {
401
407
  position = file.position;
402
408
  }
403
- return file.readSync(buffer, offset, length, position);
409
+ return file.read(buffer, offset, length, position);
404
410
  }
405
411
  readSync;
406
412
  export function fchownSync(fd, uid, gid) {
407
- fd2file(fd).chownSync(uid, gid);
413
+ fromFD(this, fd).chown(uid, gid);
408
414
  }
409
415
  fchownSync;
410
416
  export function fchmodSync(fd, mode) {
411
417
  const numMode = normalizeMode(mode, -1);
412
418
  if (numMode < 0) {
413
- throw new ErrnoError(Errno.EINVAL, `Invalid mode.`);
419
+ throw new Exception(Errno.EINVAL, `Invalid mode.`);
414
420
  }
415
- fd2file(fd).chmodSync(numMode);
421
+ fromFD(this, fd).chmod(numMode);
416
422
  }
417
423
  fchmodSync;
418
424
  /**
419
425
  * Change the file timestamps of a file referenced by the supplied file descriptor.
420
426
  */
421
427
  export function futimesSync(fd, atime, mtime) {
422
- fd2file(fd).utimesSync(normalizeTime(atime), normalizeTime(mtime));
428
+ fromFD(this, fd).utimes(normalizeTime(atime), normalizeTime(mtime));
423
429
  }
424
430
  futimesSync;
425
431
  export function rmdirSync(path) {
426
432
  path = normalizePath(path);
427
433
  const { fs, path: resolved } = resolveMount(realpathSync.call(this, path), this);
428
- try {
429
- const stats = fs.statSync(resolved);
430
- if (!stats.isDirectory()) {
431
- throw ErrnoError.With('ENOTDIR', resolved, 'rmdir');
432
- }
433
- if (config.checkAccess && !stats.hasAccess(constants.W_OK, this)) {
434
- throw ErrnoError.With('EACCES', resolved, 'rmdir');
435
- }
436
- fs.rmdirSync(resolved);
437
- emitChange(this, 'rename', path.toString());
438
- }
439
- catch (e) {
440
- throw fixError(e, { [resolved]: path });
441
- }
434
+ const stats = wrap(fs, 'statSync', path)(resolved);
435
+ if (!isDirectory(stats))
436
+ throw UV('ENOTDIR', 'rmdir', path);
437
+ if (checkAccess && !hasAccess(this, stats, constants.W_OK))
438
+ throw UV('EACCES', 'rmdir', path);
439
+ wrap(fs, 'rmdirSync', path)(resolved);
440
+ emitChange(this, 'rename', path.toString());
442
441
  }
443
442
  rmdirSync;
444
443
  export function mkdirSync(path, options) {
445
- var _a, _b;
446
- const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : credentials;
444
+ var _a;
445
+ const { euid: uid, egid: gid } = (_a = this === null || this === void 0 ? void 0 : this.credentials) !== null && _a !== void 0 ? _a : defaultContext.credentials;
447
446
  options = typeof options === 'object' ? options : { mode: options };
448
447
  const mode = normalizeMode(options === null || options === void 0 ? void 0 : options.mode, 0o777);
449
448
  path = realpathSync.call(this, path);
450
- const { fs, path: resolved, root } = resolveMount(path, this);
451
- const errorPaths = { [resolved]: path };
452
- try {
453
- if (!(options === null || options === void 0 ? void 0 : options.recursive)) {
454
- if (config.checkAccess && !fs.statSync(dirname(resolved)).hasAccess(constants.W_OK, this)) {
455
- throw ErrnoError.With('EACCES', dirname(resolved), 'mkdir');
456
- }
457
- fs.mkdirSync(resolved, mode, { uid, gid });
458
- applySetId(fs.openFileSync(resolved, 'r+'), uid, gid);
459
- return;
460
- }
461
- const dirs = [];
462
- for (let dir = resolved, original = path; !fs.existsSync(dir); dir = dirname(dir), original = dirname(original)) {
463
- dirs.unshift(dir);
464
- errorPaths[dir] = original;
465
- }
466
- for (const dir of dirs) {
467
- if (config.checkAccess && !fs.statSync(dirname(dir)).hasAccess(constants.W_OK, this)) {
468
- throw ErrnoError.With('EACCES', dirname(dir), 'mkdir');
469
- }
470
- fs.mkdirSync(dir, mode, { uid, gid });
471
- applySetId(fs.openFileSync(dir, 'r+'), uid, gid);
472
- emitChange(this, 'rename', dir);
473
- }
474
- return root.length == 1 ? dirs[0] : (_b = dirs[0]) === null || _b === void 0 ? void 0 : _b.slice(root.length);
449
+ const { fs, path: resolved } = resolveMount(path, this);
450
+ const __create = (path, resolved, parent) => {
451
+ if (checkAccess && !hasAccess(this, parent, constants.W_OK))
452
+ throw UV('EACCES', 'mkdir', dirname(path));
453
+ const inode = wrap(fs, 'mkdirSync', path)(resolved, {
454
+ mode,
455
+ uid: parent.mode & constants.S_ISUID ? parent.uid : uid,
456
+ gid: parent.mode & constants.S_ISGID ? parent.gid : gid,
457
+ });
458
+ emitChange(this, 'rename', path);
459
+ return inode;
460
+ };
461
+ if (!(options === null || options === void 0 ? void 0 : options.recursive)) {
462
+ __create(path, resolved, wrap(fs, 'statSync', dirname(path))(dirname(resolved)));
463
+ return;
475
464
  }
476
- catch (e) {
477
- throw fixError(e, errorPaths);
465
+ const dirs = [];
466
+ for (let dir = resolved, original = path; !wrap(fs, 'existsSync', original)(dir); dir = dirname(dir), original = dirname(original)) {
467
+ dirs.unshift({ resolved: dir, original });
478
468
  }
469
+ if (!dirs.length)
470
+ return;
471
+ const stats = [wrap(fs, 'statSync', dirname(dirs[0].original))(dirname(dirs[0].resolved))];
472
+ for (const [i, dir] of dirs.entries()) {
473
+ stats.push(__create(dir.original, dir.resolved, stats[i]));
474
+ }
475
+ return dirs[0].original;
479
476
  }
480
477
  mkdirSync;
481
478
  export function readdirSync(path, options) {
482
479
  options = typeof options === 'object' ? options : { encoding: options };
483
480
  path = normalizePath(path);
484
481
  const { fs, path: resolved } = resolveMount(realpathSync.call(this, path), this);
485
- let entries;
486
- try {
487
- const stats = fs.statSync(resolved);
488
- if (config.checkAccess && !stats.hasAccess(constants.R_OK, this)) {
489
- throw ErrnoError.With('EACCES', resolved, 'readdir');
490
- }
491
- if (!stats.isDirectory()) {
492
- throw ErrnoError.With('ENOTDIR', resolved, 'readdir');
493
- }
494
- entries = fs.readdirSync(resolved);
495
- }
496
- catch (e) {
497
- throw fixError(e, { [resolved]: path });
498
- }
482
+ const stats = wrap(fs, 'statSync', path)(resolved);
483
+ if (checkAccess && !hasAccess(this, stats, constants.R_OK))
484
+ throw UV('EACCES', 'readdir', path);
485
+ if (!isDirectory(stats))
486
+ throw UV('ENOTDIR', 'readdir', path);
487
+ const entries = wrap(fs, 'readdirSync', path)(resolved);
499
488
  // Iterate over entries and handle recursive case if needed
500
489
  const values = [];
501
490
  for (const entry of entries) {
@@ -515,7 +504,7 @@ export function readdirSync(path, options) {
515
504
  else {
516
505
  values.push(entry);
517
506
  }
518
- if (!entryStat.isDirectory() || !(options === null || options === void 0 ? void 0 : options.recursive))
507
+ if (!isDirectory(entryStat) || !(options === null || options === void 0 ? void 0 : options.recursive))
519
508
  continue;
520
509
  for (const subEntry of readdirSync.call(this, join(path, entry), options)) {
521
510
  if (subEntry instanceof Dirent) {
@@ -535,27 +524,22 @@ export function readdirSync(path, options) {
535
524
  readdirSync;
536
525
  export function linkSync(targetPath, linkPath) {
537
526
  targetPath = normalizePath(targetPath);
538
- if (config.checkAccess && !statSync(dirname(targetPath)).hasAccess(constants.R_OK, this)) {
539
- throw ErrnoError.With('EACCES', dirname(targetPath), 'link');
527
+ if (checkAccess && !statSync(dirname(targetPath)).hasAccess(constants.R_OK, this)) {
528
+ throw UV('EACCES', 'link', dirname(targetPath));
540
529
  }
541
530
  linkPath = normalizePath(linkPath);
542
- if (config.checkAccess && !statSync(dirname(linkPath)).hasAccess(constants.W_OK, this)) {
543
- throw ErrnoError.With('EACCES', dirname(linkPath), 'link');
531
+ if (checkAccess && !statSync(dirname(linkPath)).hasAccess(constants.W_OK, this)) {
532
+ throw UV('EACCES', 'link', dirname(linkPath));
544
533
  }
545
534
  const { fs, path } = resolveMount(targetPath, this);
546
535
  const link = resolveMount(linkPath, this);
547
536
  if (fs != link.fs) {
548
- throw ErrnoError.With('EXDEV', linkPath, 'link');
549
- }
550
- try {
551
- if (config.checkAccess && !fs.statSync(path).hasAccess(constants.R_OK, this)) {
552
- throw ErrnoError.With('EACCES', path, 'link');
553
- }
554
- return fs.linkSync(path, link.path);
555
- }
556
- catch (e) {
557
- throw fixError(e, { [path]: targetPath, [link.path]: linkPath });
537
+ throw UV('EXDEV', 'link', linkPath);
558
538
  }
539
+ const stats = wrap(fs, 'statSync', targetPath)(path);
540
+ if (checkAccess && !hasAccess(this, stats, constants.R_OK))
541
+ throw UV('EACCES', 'link', path);
542
+ return wrap(fs, 'linkSync', targetPath, linkPath)(path, link.path);
559
543
  }
560
544
  linkSync;
561
545
  /**
@@ -565,49 +549,71 @@ linkSync;
565
549
  * @param type can be either `'dir'` or `'file'` (default is `'file'`)
566
550
  */
567
551
  export function symlinkSync(target, path, type = 'file') {
568
- if (!['file', 'dir', 'junction'].includes(type)) {
569
- throw new ErrnoError(Errno.EINVAL, 'Invalid type: ' + type);
552
+ const env_5 = { stack: [], error: void 0, hasError: false };
553
+ try {
554
+ if (!['file', 'dir', 'junction'].includes(type))
555
+ throw new TypeError('Invalid symlink type: ' + type);
556
+ path = normalizePath(path);
557
+ const file = __addDisposableResource(env_5, _openSync.call(this, path, { flag: 'wx', mode: 0o644 }), false);
558
+ file.write(encodeUTF8(normalizePath(target, true)));
559
+ file.chmod(constants.S_IFLNK);
570
560
  }
571
- if (existsSync.call(this, path)) {
572
- throw ErrnoError.With('EEXIST', path.toString(), 'symlink');
561
+ catch (e_5) {
562
+ env_5.error = e_5;
563
+ env_5.hasError = true;
564
+ }
565
+ finally {
566
+ __disposeResources(env_5);
573
567
  }
574
- writeFileSync.call(this, path, normalizePath(target, true));
575
- const file = _openSync.call(this, path, { flag: 'r+', mode: 0o644, preserveSymlinks: true });
576
- file.chmodSync(constants.S_IFLNK);
577
568
  }
578
569
  symlinkSync;
579
570
  export function readlinkSync(path, options) {
580
- const value = Buffer.from(_readFileSync.call(this, path, 'r', true));
581
- const encoding = typeof options == 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options;
582
- if (encoding == 'buffer') {
583
- return value;
571
+ const env_6 = { stack: [], error: void 0, hasError: false };
572
+ try {
573
+ const handle = __addDisposableResource(env_6, _openSync.call(this, normalizePath(path), { flag: 'r', mode: 0o644, preserveSymlinks: true }), false);
574
+ if (!isSymbolicLink(handle.inode))
575
+ throw new Exception(Errno.EINVAL, 'Not a symbolic link: ' + path);
576
+ const size = handle.inode.size;
577
+ const data = Buffer.alloc(size);
578
+ handle.read(data, 0, size, 0);
579
+ const encoding = typeof options == 'object' ? options === null || options === void 0 ? void 0 : options.encoding : options;
580
+ if (encoding == 'buffer') {
581
+ return data;
582
+ }
583
+ // always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
584
+ return data.toString(encoding !== null && encoding !== void 0 ? encoding : 'utf-8');
585
+ }
586
+ catch (e_6) {
587
+ env_6.error = e_6;
588
+ env_6.hasError = true;
589
+ }
590
+ finally {
591
+ __disposeResources(env_6);
584
592
  }
585
- // always defaults to utf-8 to avoid wrangler (cloudflare) worker "unknown encoding" exception
586
- return value.toString(encoding !== null && encoding !== void 0 ? encoding : 'utf-8');
587
593
  }
588
594
  readlinkSync;
589
595
  export function chownSync(path, uid, gid) {
590
596
  const fd = openSync.call(this, path, 'r+');
591
- fchownSync(fd, uid, gid);
592
- closeSync(fd);
597
+ fchownSync.call(this, fd, uid, gid);
598
+ closeSync.call(this, fd);
593
599
  }
594
600
  chownSync;
595
601
  export function lchownSync(path, uid, gid) {
596
602
  const fd = lopenSync.call(this, path, 'r+');
597
- fchownSync(fd, uid, gid);
598
- closeSync(fd);
603
+ fchownSync.call(this, fd, uid, gid);
604
+ closeSync.call(this, fd);
599
605
  }
600
606
  lchownSync;
601
607
  export function chmodSync(path, mode) {
602
608
  const fd = openSync.call(this, path, 'r+');
603
- fchmodSync(fd, mode);
604
- closeSync(fd);
609
+ fchmodSync.call(this, fd, mode);
610
+ closeSync.call(this, fd);
605
611
  }
606
612
  chmodSync;
607
613
  export function lchmodSync(path, mode) {
608
614
  const fd = lopenSync.call(this, path, 'r+');
609
- fchmodSync(fd, mode);
610
- closeSync(fd);
615
+ fchmodSync.call(this, fd, mode);
616
+ closeSync.call(this, fd);
611
617
  }
612
618
  lchmodSync;
613
619
  /**
@@ -615,8 +621,8 @@ lchmodSync;
615
621
  */
616
622
  export function utimesSync(path, atime, mtime) {
617
623
  const fd = openSync.call(this, path, 'r+');
618
- futimesSync(fd, atime, mtime);
619
- closeSync(fd);
624
+ futimesSync.call(this, fd, atime, mtime);
625
+ closeSync.call(this, fd);
620
626
  }
621
627
  utimesSync;
622
628
  /**
@@ -624,8 +630,8 @@ utimesSync;
624
630
  */
625
631
  export function lutimesSync(path, atime, mtime) {
626
632
  const fd = lopenSync.call(this, path, 'r+');
627
- futimesSync(fd, atime, mtime);
628
- closeSync(fd);
633
+ futimesSync.call(this, fd, atime, mtime);
634
+ closeSync.call(this, fd);
629
635
  }
630
636
  lutimesSync;
631
637
  /**
@@ -645,10 +651,10 @@ function _resolveSync($, path, preserveSymlinks) {
645
651
  const resolved = resolveMount(path, $);
646
652
  // Stat it to make sure it exists
647
653
  const stats = resolved.fs.statSync(resolved.path);
648
- if (!stats.isSymbolicLink()) {
654
+ if (!isSymbolicLink(stats)) {
649
655
  return { ...resolved, fullPath: path, stats };
650
656
  }
651
- const target = resolve(dirname(path), readlinkSync.call($, path).toString());
657
+ const target = resolve.call($, dirname(path), readlinkSync.call($, path).toString());
652
658
  return _resolveSync($, target);
653
659
  }
654
660
  catch {
@@ -658,20 +664,20 @@ function _resolveSync($, path, preserveSymlinks) {
658
664
  const realDir = dir == '/' ? '/' : realpathSync.call($, dir);
659
665
  const maybePath = join(realDir, base);
660
666
  const resolved = resolveMount(maybePath, $);
667
+ let stats;
661
668
  try {
662
- const stats = resolved.fs.statSync(resolved.path);
663
- if (!stats.isSymbolicLink()) {
664
- return { ...resolved, fullPath: maybePath, stats };
665
- }
666
- const target = resolve(realDir, readlinkSync.call($, maybePath).toString());
667
- return _resolveSync($, target);
669
+ stats = resolved.fs.statSync(resolved.path);
668
670
  }
669
671
  catch (e) {
670
- if (e.code == 'ENOENT') {
672
+ if (e.code === 'ENOENT')
671
673
  return { ...resolved, fullPath: path };
672
- }
673
- throw fixError(e, { [resolved.path]: maybePath });
674
+ throw setUVMessage(Object.assign(e, { syscall: 'stat', path: maybePath }));
674
675
  }
676
+ if (!isSymbolicLink(stats)) {
677
+ return { ...resolved, fullPath: maybePath, stats };
678
+ }
679
+ const target = resolve.call($, realDir, readlinkSync.call($, maybePath).toString());
680
+ return _resolveSync($, target);
675
681
  }
676
682
  export function realpathSync(path, options) {
677
683
  var _a;
@@ -687,10 +693,10 @@ export function realpathSync(path, options) {
687
693
  }
688
694
  realpathSync;
689
695
  export function accessSync(path, mode = 0o600) {
690
- if (!config.checkAccess)
696
+ if (!checkAccess)
691
697
  return;
692
- if (!statSync.call(this, path).hasAccess(mode, this)) {
693
- throw new ErrnoError(Errno.EACCES);
698
+ if (!hasAccess(this, statSync.call(this, path), mode)) {
699
+ throw new Exception(Errno.EACCES);
694
700
  }
695
701
  }
696
702
  accessSync;
@@ -728,7 +734,7 @@ export function rmSync(path, options) {
728
734
  case constants.S_IFIFO:
729
735
  case constants.S_IFSOCK:
730
736
  default:
731
- throw new ErrnoError(Errno.EPERM, 'File type not supported', path, 'rm');
737
+ throw UV('ENOSYS', 'rm', path);
732
738
  }
733
739
  }
734
740
  rmSync;
@@ -748,9 +754,8 @@ mkdtempSync;
748
754
  export function copyFileSync(source, destination, flags) {
749
755
  source = normalizePath(source);
750
756
  destination = normalizePath(destination);
751
- if (flags && flags & constants.COPYFILE_EXCL && existsSync(destination)) {
752
- throw new ErrnoError(Errno.EEXIST, 'Destination file already exists', destination, 'copyFile');
753
- }
757
+ if (flags && flags & constants.COPYFILE_EXCL && existsSync(destination))
758
+ throw UV('EEXIST', 'copyFile', destination);
754
759
  writeFileSync.call(this, destination, readFileSync(source));
755
760
  emitChange(this, 'rename', destination.toString());
756
761
  }
@@ -763,10 +768,10 @@ copyFileSync;
763
768
  * @returns The number of bytes read.
764
769
  */
765
770
  export function readvSync(fd, buffers, position) {
766
- const file = fd2file(fd);
771
+ const file = fromFD(this, fd);
767
772
  let bytesRead = 0;
768
773
  for (const buffer of buffers) {
769
- bytesRead += file.readSync(buffer, 0, buffer.byteLength, position + bytesRead);
774
+ bytesRead += file.read(buffer, 0, buffer.byteLength, position + bytesRead);
770
775
  }
771
776
  return bytesRead;
772
777
  }
@@ -779,10 +784,10 @@ readvSync;
779
784
  * @returns The number of bytes written.
780
785
  */
781
786
  export function writevSync(fd, buffers, position) {
782
- const file = fd2file(fd);
787
+ const file = fromFD(this, fd);
783
788
  let bytesWritten = 0;
784
789
  for (const buffer of buffers) {
785
- bytesWritten += file.writeSync(new Uint8Array(buffer.buffer), 0, buffer.byteLength, position + bytesWritten);
790
+ bytesWritten += file.write(new Uint8Array(buffer.buffer), 0, buffer.byteLength, position + bytesWritten);
786
791
  }
787
792
  return bytesWritten;
788
793
  }
@@ -815,14 +820,12 @@ export function cpSync(source, destination, opts) {
815
820
  source = normalizePath(source);
816
821
  destination = normalizePath(destination);
817
822
  const srcStats = lstatSync.call(this, source); // Use lstat to follow symlinks if not dereferencing
818
- if ((opts === null || opts === void 0 ? void 0 : opts.errorOnExist) && existsSync.call(this, destination)) {
819
- throw new ErrnoError(Errno.EEXIST, 'Destination file or directory already exists', destination, 'cp');
820
- }
823
+ if ((opts === null || opts === void 0 ? void 0 : opts.errorOnExist) && existsSync.call(this, destination))
824
+ throw UV('EEXIST', 'cp', destination);
821
825
  switch (srcStats.mode & constants.S_IFMT) {
822
826
  case constants.S_IFDIR:
823
- if (!(opts === null || opts === void 0 ? void 0 : opts.recursive)) {
824
- throw new ErrnoError(Errno.EISDIR, source + ' is a directory (not copied)', source, 'cp');
825
- }
827
+ if (!(opts === null || opts === void 0 ? void 0 : opts.recursive))
828
+ throw UV('EISDIR', 'cp', source);
826
829
  mkdirSync.call(this, destination, { recursive: true }); // Ensure the destination directory exists
827
830
  for (const dirent of readdirSync.call(this, source, { withFileTypes: true })) {
828
831
  if (opts.filter && !opts.filter(join(source, dirent.name), join(destination, dirent.name))) {
@@ -840,7 +843,7 @@ export function cpSync(source, destination, opts) {
840
843
  case constants.S_IFIFO:
841
844
  case constants.S_IFSOCK:
842
845
  default:
843
- throw new ErrnoError(Errno.EPERM, 'File type not supported', source, 'rm');
846
+ throw UV('ENOSYS', 'cp', source);
844
847
  }
845
848
  // Optionally preserve timestamps
846
849
  if (opts === null || opts === void 0 ? void 0 : opts.preserveTimestamps) {