@zenfs/core 2.4.1 → 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.
- package/COPYING.md +18 -0
- package/{readme.md → README.md} +16 -74
- package/dist/backends/fetch.js +1 -1
- package/dist/backends/memory.js +1 -1
- package/dist/backends/passthrough.d.ts +1 -2
- package/dist/backends/single_buffer.js +1 -1
- package/dist/backends/store/fs.js +4 -4
- package/dist/config.js +15 -15
- package/dist/context.js +3 -2
- package/dist/index.d.ts +9 -3
- package/dist/index.js +9 -4
- package/dist/internal/contexts.d.ts +5 -4
- package/dist/internal/devices.js +1 -1
- package/dist/internal/error.d.ts +11 -2
- package/dist/internal/error.js +38 -2
- package/dist/internal/file_index.js +1 -1
- package/dist/internal/index.d.ts +1 -0
- package/dist/internal/index.js +2 -1
- package/dist/internal/index_fs.js +1 -1
- package/dist/internal/inode.d.ts +51 -2
- package/dist/internal/inode.js +18 -2
- package/dist/mixins/shared.js +1 -1
- package/dist/node/async.d.ts +278 -0
- package/dist/node/async.js +518 -0
- package/dist/node/compat.d.ts +4 -0
- package/dist/node/compat.js +6 -0
- package/dist/node/dir.d.ts +78 -0
- package/dist/node/dir.js +150 -0
- package/dist/node/index.d.ts +8 -0
- package/dist/node/index.js +8 -0
- package/dist/{vfs → node}/promises.d.ts +10 -66
- package/dist/{vfs → node}/promises.js +141 -478
- package/dist/{vfs → node}/stats.d.ts +0 -4
- package/dist/{vfs → node}/stats.js +1 -16
- package/dist/{vfs → node}/streams.js +2 -2
- package/dist/node/sync.d.ts +252 -0
- package/dist/node/sync.js +682 -0
- package/dist/node/types.d.ts +21 -0
- package/dist/utils.d.ts +1 -7
- package/dist/utils.js +0 -6
- package/dist/vfs/acl.js +1 -1
- package/dist/vfs/async.d.ts +22 -278
- package/dist/vfs/async.js +212 -501
- package/dist/vfs/dir.d.ts +5 -82
- package/dist/vfs/dir.js +5 -233
- package/dist/vfs/file.d.ts +52 -13
- package/dist/vfs/file.js +167 -25
- package/dist/vfs/flags.js +1 -1
- package/dist/vfs/index.d.ts +2 -5
- package/dist/vfs/index.js +2 -5
- package/dist/vfs/shared.d.ts +25 -1
- package/dist/vfs/shared.js +6 -4
- package/dist/vfs/sync.d.ts +17 -245
- package/dist/vfs/sync.js +129 -773
- package/dist/vfs/watchers.d.ts +1 -1
- package/dist/vfs/watchers.js +2 -2
- package/dist/vfs/xattr.js +1 -1
- package/eslint.shared.js +1 -0
- package/package.json +7 -5
- package/scripts/make-index.js +5 -29
- package/scripts/test.js +59 -51
- package/tests/backend/fetch.test.ts +2 -2
- package/tests/backend/port.test.ts +2 -3
- package/tests/backend/single-buffer.test.ts +1 -1
- package/tests/common/casefold.test.ts +1 -1
- package/tests/common/context.test.ts +11 -4
- package/tests/common/devices.test.ts +3 -3
- package/tests/common/handle.test.ts +4 -3
- package/tests/common/inode.test.ts +2 -2
- package/tests/common/mounts.test.ts +1 -3
- package/tests/common/mutex.test.ts +1 -3
- package/tests/common/path.test.ts +2 -2
- package/tests/common/readline.test.ts +1 -1
- package/tests/common.ts +5 -4
- package/tests/fetch/fetch.ts +1 -1
- package/tests/fs/dir.test.ts +3 -43
- package/tests/fs/directory.test.ts +4 -4
- package/tests/fs/errors.test.ts +2 -2
- package/tests/fs/links.test.ts +1 -1
- package/tests/fs/permissions.test.ts +3 -3
- package/tests/fs/read.test.ts +1 -1
- package/tests/fs/scaling.test.ts +1 -1
- package/tests/fs/stat.test.ts +1 -2
- package/tests/fs/times.test.ts +1 -1
- package/tests/fs/watch.test.ts +3 -2
- package/tests/setup/context.ts +1 -2
- package/tests/setup/cow.ts +1 -1
- package/tests/setup/index.ts +2 -2
- package/tests/setup/port.ts +1 -1
- package/tests/setup/single-buffer.ts +1 -1
- package/tests/setup.ts +4 -3
- package/dist/vfs/types.d.ts +0 -24
- package/tests/assignment.ts +0 -21
- /package/dist/{vfs/constants.d.ts → constants.d.ts} +0 -0
- /package/dist/{vfs/constants.js → constants.js} +0 -0
- /package/dist/{readline.d.ts → node/readline.d.ts} +0 -0
- /package/dist/{readline.js → node/readline.js} +0 -0
- /package/dist/{vfs → node}/streams.d.ts +0 -0
- /package/dist/{vfs → node}/types.js +0 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
2
|
+
import { UV, withErrno } from 'kerium';
|
|
3
|
+
import { R_OK } from '../constants.js';
|
|
4
|
+
import { normalizeMode, normalizePath } from '../utils.js';
|
|
5
|
+
import { FSWatcher, StatWatcher } from '../vfs/watchers.js';
|
|
6
|
+
import * as promises from './promises.js';
|
|
7
|
+
import { BigIntStats } from './stats.js';
|
|
8
|
+
import { ReadStream, WriteStream } from './streams.js';
|
|
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
|
+
/**
|
|
21
|
+
* Asynchronous rename. No arguments other than a possible exception are given to the completion callback.
|
|
22
|
+
*/
|
|
23
|
+
export function rename(oldPath, newPath, cb = nop) {
|
|
24
|
+
promises.rename
|
|
25
|
+
.call(this, oldPath, newPath)
|
|
26
|
+
.then(() => cb(null))
|
|
27
|
+
.catch(cb);
|
|
28
|
+
}
|
|
29
|
+
rename;
|
|
30
|
+
/**
|
|
31
|
+
* Test whether or not `path` exists by checking with the file system.
|
|
32
|
+
* Then call the callback argument with either true or false.
|
|
33
|
+
* According to Node.js: deprecated Use {@link stat} or {@link access} instead.
|
|
34
|
+
*/
|
|
35
|
+
export function exists(path, cb = nop) {
|
|
36
|
+
promises.exists
|
|
37
|
+
.call(this, path)
|
|
38
|
+
.then(cb)
|
|
39
|
+
.catch(() => cb(false));
|
|
40
|
+
}
|
|
41
|
+
exists;
|
|
42
|
+
export function stat(path, options, callback = nop) {
|
|
43
|
+
callback = typeof options == 'function' ? options : callback;
|
|
44
|
+
promises.stat
|
|
45
|
+
.call(this, path, typeof options != 'function' ? options : {})
|
|
46
|
+
.then(stats => callback(null, stats))
|
|
47
|
+
.catch(callback);
|
|
48
|
+
}
|
|
49
|
+
stat;
|
|
50
|
+
export function lstat(path, options, callback = nop) {
|
|
51
|
+
callback = typeof options == 'function' ? options : callback;
|
|
52
|
+
promises.lstat
|
|
53
|
+
.call(this, path, typeof options != 'function' ? options : {})
|
|
54
|
+
.then(stats => callback(null, stats))
|
|
55
|
+
.catch(callback);
|
|
56
|
+
}
|
|
57
|
+
lstat;
|
|
58
|
+
export function truncate(path, cbLen = 0, cb = nop) {
|
|
59
|
+
cb = typeof cbLen === 'function' ? cbLen : cb;
|
|
60
|
+
const len = typeof cbLen === 'number' ? cbLen : 0;
|
|
61
|
+
promises.truncate
|
|
62
|
+
.call(this, path, len)
|
|
63
|
+
.then(() => cb(null))
|
|
64
|
+
.catch(cb);
|
|
65
|
+
}
|
|
66
|
+
truncate;
|
|
67
|
+
export function unlink(path, cb = nop) {
|
|
68
|
+
promises.unlink
|
|
69
|
+
.call(this, path)
|
|
70
|
+
.then(() => cb(null))
|
|
71
|
+
.catch(cb);
|
|
72
|
+
}
|
|
73
|
+
unlink;
|
|
74
|
+
export function open(path, flag, cbMode, cb = nop) {
|
|
75
|
+
const mode = normalizeMode(cbMode, 0o644);
|
|
76
|
+
cb = typeof cbMode === 'function' ? cbMode : cb;
|
|
77
|
+
promises.open
|
|
78
|
+
.call(this, path, flag, mode)
|
|
79
|
+
.then(handle => cb(null, handle.fd))
|
|
80
|
+
.catch(cb);
|
|
81
|
+
}
|
|
82
|
+
open;
|
|
83
|
+
export function readFile(filename, options, cb = nop) {
|
|
84
|
+
cb = typeof options === 'function' ? options : cb;
|
|
85
|
+
promises.readFile
|
|
86
|
+
.call(this, filename, typeof options === 'function' ? null : options)
|
|
87
|
+
.then(data => cb(null, data))
|
|
88
|
+
.catch(cb);
|
|
89
|
+
}
|
|
90
|
+
readFile;
|
|
91
|
+
export function writeFile(filename, data, cbEncOpts, cb = nop) {
|
|
92
|
+
cb = typeof cbEncOpts === 'function' ? cbEncOpts : cb;
|
|
93
|
+
promises.writeFile
|
|
94
|
+
.call(this, filename, data, typeof cbEncOpts != 'function' ? cbEncOpts : null)
|
|
95
|
+
.then(() => cb(null))
|
|
96
|
+
.catch(cb);
|
|
97
|
+
}
|
|
98
|
+
writeFile;
|
|
99
|
+
export function appendFile(filename, data, cbEncOpts, cb = nop) {
|
|
100
|
+
const optionsOrEncoding = typeof cbEncOpts != 'function' ? cbEncOpts : undefined;
|
|
101
|
+
cb = typeof cbEncOpts === 'function' ? cbEncOpts : cb;
|
|
102
|
+
promises.appendFile
|
|
103
|
+
.call(this, filename, data, optionsOrEncoding)
|
|
104
|
+
.then(() => cb(null))
|
|
105
|
+
.catch(cb);
|
|
106
|
+
}
|
|
107
|
+
appendFile;
|
|
108
|
+
export function fstat(fd, options, cb = nop) {
|
|
109
|
+
cb = typeof options == 'function' ? options : cb;
|
|
110
|
+
new promises.FileHandle(this, fd)
|
|
111
|
+
.stat()
|
|
112
|
+
.then(stats => cb(null, typeof options == 'object' && options?.bigint ? new BigIntStats(stats) : stats))
|
|
113
|
+
.catch(cb);
|
|
114
|
+
}
|
|
115
|
+
fstat;
|
|
116
|
+
export function close(fd, cb = nop) {
|
|
117
|
+
new promises.FileHandle(this, fd)
|
|
118
|
+
.close()
|
|
119
|
+
.then(() => cb(null))
|
|
120
|
+
.catch(cb);
|
|
121
|
+
}
|
|
122
|
+
close;
|
|
123
|
+
export function ftruncate(fd, lenOrCB, cb = nop) {
|
|
124
|
+
const length = typeof lenOrCB === 'number' ? lenOrCB : 0;
|
|
125
|
+
cb = typeof lenOrCB === 'function' ? lenOrCB : cb;
|
|
126
|
+
const file = new promises.FileHandle(this, fd);
|
|
127
|
+
if (length < 0)
|
|
128
|
+
throw withErrno('EINVAL');
|
|
129
|
+
file.truncate(length)
|
|
130
|
+
.then(() => cb(null))
|
|
131
|
+
.catch(cb);
|
|
132
|
+
}
|
|
133
|
+
ftruncate;
|
|
134
|
+
export function fsync(fd, cb = nop) {
|
|
135
|
+
new promises.FileHandle(this, fd)
|
|
136
|
+
.sync()
|
|
137
|
+
.then(() => cb(null))
|
|
138
|
+
.catch(cb);
|
|
139
|
+
}
|
|
140
|
+
fsync;
|
|
141
|
+
export function fdatasync(fd, cb = nop) {
|
|
142
|
+
new promises.FileHandle(this, fd)
|
|
143
|
+
.datasync()
|
|
144
|
+
.then(() => cb(null))
|
|
145
|
+
.catch(cb);
|
|
146
|
+
}
|
|
147
|
+
fdatasync;
|
|
148
|
+
export function write(fd, data, cbPosOff, cbLenEnc, cbPosEnc, cb = nop) {
|
|
149
|
+
let buffer, offset, length, position, encoding;
|
|
150
|
+
const handle = new promises.FileHandle(this, fd);
|
|
151
|
+
if (typeof data === 'string') {
|
|
152
|
+
// Signature 1: (fd, string, [position?, [encoding?]], cb?)
|
|
153
|
+
encoding = 'utf8';
|
|
154
|
+
switch (typeof cbPosOff) {
|
|
155
|
+
case 'function':
|
|
156
|
+
// (fd, string, cb)
|
|
157
|
+
cb = cbPosOff;
|
|
158
|
+
break;
|
|
159
|
+
case 'number':
|
|
160
|
+
// (fd, string, position, encoding?, cb?)
|
|
161
|
+
position = cbPosOff;
|
|
162
|
+
encoding = typeof cbLenEnc === 'string' ? cbLenEnc : 'utf8';
|
|
163
|
+
cb = typeof cbPosEnc === 'function' ? cbPosEnc : cb;
|
|
164
|
+
break;
|
|
165
|
+
default:
|
|
166
|
+
// ...try to find the callback and get out of here!
|
|
167
|
+
cb = (typeof cbLenEnc === 'function' ? cbLenEnc : typeof cbPosEnc === 'function' ? cbPosEnc : cb);
|
|
168
|
+
cb(withErrno('EINVAL'));
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
buffer = Buffer.from(data);
|
|
172
|
+
offset = 0;
|
|
173
|
+
length = buffer.length;
|
|
174
|
+
const _cb = cb;
|
|
175
|
+
handle
|
|
176
|
+
.write(buffer, offset, length, position)
|
|
177
|
+
.then(({ bytesWritten }) => _cb(null, bytesWritten, buffer.toString(encoding)))
|
|
178
|
+
.catch(_cb);
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
// Signature 2: (fd, buffer, offset, length, position?, cb?)
|
|
182
|
+
buffer = Buffer.from(data.buffer);
|
|
183
|
+
offset = cbPosOff;
|
|
184
|
+
length = cbLenEnc;
|
|
185
|
+
position = typeof cbPosEnc === 'number' ? cbPosEnc : null;
|
|
186
|
+
const _cb = (typeof cbPosEnc === 'function' ? cbPosEnc : cb);
|
|
187
|
+
void handle
|
|
188
|
+
.write(buffer, offset, length, position)
|
|
189
|
+
.then(({ bytesWritten }) => _cb(null, bytesWritten, buffer))
|
|
190
|
+
.catch(_cb);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
write;
|
|
194
|
+
/**
|
|
195
|
+
* Read data from the file specified by `fd`.
|
|
196
|
+
* @param buffer The buffer that the data will be written to.
|
|
197
|
+
* @param offset The offset within the buffer where writing will start.
|
|
198
|
+
* @param length An integer specifying the number of bytes to read.
|
|
199
|
+
* @param position An integer specifying where to begin reading from in the file.
|
|
200
|
+
* If position is null, data will be read from the current file position.
|
|
201
|
+
* @param cb The number is the number of bytes read
|
|
202
|
+
*/
|
|
203
|
+
export function read(fd, buffer, offset, length, position, cb = nop) {
|
|
204
|
+
new promises.FileHandle(this, fd)
|
|
205
|
+
.read(buffer, offset, length, position)
|
|
206
|
+
.then(({ bytesRead, buffer }) => cb(null, bytesRead, buffer))
|
|
207
|
+
.catch(cb);
|
|
208
|
+
}
|
|
209
|
+
read;
|
|
210
|
+
export function fchown(fd, uid, gid, cb = nop) {
|
|
211
|
+
new promises.FileHandle(this, fd)
|
|
212
|
+
.chown(uid, gid)
|
|
213
|
+
.then(() => cb(null))
|
|
214
|
+
.catch(cb);
|
|
215
|
+
}
|
|
216
|
+
fchown;
|
|
217
|
+
export function fchmod(fd, mode, cb) {
|
|
218
|
+
new promises.FileHandle(this, fd)
|
|
219
|
+
.chmod(mode)
|
|
220
|
+
.then(() => cb(null))
|
|
221
|
+
.catch(cb);
|
|
222
|
+
}
|
|
223
|
+
fchmod;
|
|
224
|
+
/**
|
|
225
|
+
* Change the file timestamps of a file referenced by the supplied file descriptor.
|
|
226
|
+
*/
|
|
227
|
+
export function futimes(fd, atime, mtime, cb = nop) {
|
|
228
|
+
new promises.FileHandle(this, fd)
|
|
229
|
+
.utimes(atime, mtime)
|
|
230
|
+
.then(() => cb(null))
|
|
231
|
+
.catch(cb);
|
|
232
|
+
}
|
|
233
|
+
futimes;
|
|
234
|
+
export function rmdir(path, cb = nop) {
|
|
235
|
+
promises.rmdir
|
|
236
|
+
.call(this, path)
|
|
237
|
+
.then(() => cb(null))
|
|
238
|
+
.catch(cb);
|
|
239
|
+
}
|
|
240
|
+
rmdir;
|
|
241
|
+
/**
|
|
242
|
+
* Asynchronous `mkdir`.
|
|
243
|
+
* @param mode defaults to `0777`
|
|
244
|
+
*/
|
|
245
|
+
export function mkdir(path, mode, cb = nop) {
|
|
246
|
+
promises.mkdir
|
|
247
|
+
.call(this, path, mode)
|
|
248
|
+
.then(() => cb(null))
|
|
249
|
+
.catch(cb);
|
|
250
|
+
}
|
|
251
|
+
mkdir;
|
|
252
|
+
export function readdir(path, _options, cb = nop) {
|
|
253
|
+
cb = typeof _options == 'function' ? _options : cb;
|
|
254
|
+
const options = typeof _options != 'function' ? _options : {};
|
|
255
|
+
promises.readdir
|
|
256
|
+
.call(this, path, options)
|
|
257
|
+
.then(entries => cb(null, entries))
|
|
258
|
+
.catch(cb);
|
|
259
|
+
}
|
|
260
|
+
readdir;
|
|
261
|
+
export function link(existing, newpath, cb = nop) {
|
|
262
|
+
promises.link
|
|
263
|
+
.call(this, existing, newpath)
|
|
264
|
+
.then(() => cb(null))
|
|
265
|
+
.catch(cb);
|
|
266
|
+
}
|
|
267
|
+
link;
|
|
268
|
+
export function symlink(target, path, typeOrCB, cb = nop) {
|
|
269
|
+
const type = typeof typeOrCB === 'string' ? typeOrCB : 'file';
|
|
270
|
+
cb = typeof typeOrCB === 'function' ? typeOrCB : cb;
|
|
271
|
+
promises.symlink
|
|
272
|
+
.call(this, target, path, type)
|
|
273
|
+
.then(() => cb(null))
|
|
274
|
+
.catch(cb);
|
|
275
|
+
}
|
|
276
|
+
symlink;
|
|
277
|
+
export function readlink(path, options, callback = nop) {
|
|
278
|
+
callback = typeof options == 'function' ? options : callback;
|
|
279
|
+
promises.readlink
|
|
280
|
+
.call(this, path)
|
|
281
|
+
.then(result => callback(null, result))
|
|
282
|
+
.catch(callback);
|
|
283
|
+
}
|
|
284
|
+
readlink;
|
|
285
|
+
export function chown(path, uid, gid, cb = nop) {
|
|
286
|
+
promises.chown
|
|
287
|
+
.call(this, path, uid, gid)
|
|
288
|
+
.then(() => cb(null))
|
|
289
|
+
.catch(cb);
|
|
290
|
+
}
|
|
291
|
+
chown;
|
|
292
|
+
export function lchown(path, uid, gid, cb = nop) {
|
|
293
|
+
promises.lchown
|
|
294
|
+
.call(this, path, uid, gid)
|
|
295
|
+
.then(() => cb(null))
|
|
296
|
+
.catch(cb);
|
|
297
|
+
}
|
|
298
|
+
lchown;
|
|
299
|
+
export function chmod(path, mode, cb = nop) {
|
|
300
|
+
promises.chmod
|
|
301
|
+
.call(this, path, mode)
|
|
302
|
+
.then(() => cb(null))
|
|
303
|
+
.catch(cb);
|
|
304
|
+
}
|
|
305
|
+
chmod;
|
|
306
|
+
export function lchmod(path, mode, cb = nop) {
|
|
307
|
+
promises.lchmod
|
|
308
|
+
.call(this, path, mode)
|
|
309
|
+
.then(() => cb(null))
|
|
310
|
+
.catch(cb);
|
|
311
|
+
}
|
|
312
|
+
lchmod;
|
|
313
|
+
/**
|
|
314
|
+
* Change file timestamps of the file referenced by the supplied path.
|
|
315
|
+
*/
|
|
316
|
+
export function utimes(path, atime, mtime, cb = nop) {
|
|
317
|
+
promises.utimes
|
|
318
|
+
.call(this, path, atime, mtime)
|
|
319
|
+
.then(() => cb(null))
|
|
320
|
+
.catch(cb);
|
|
321
|
+
}
|
|
322
|
+
utimes;
|
|
323
|
+
/**
|
|
324
|
+
* Change file timestamps of the file referenced by the supplied path.
|
|
325
|
+
*/
|
|
326
|
+
export function lutimes(path, atime, mtime, cb = nop) {
|
|
327
|
+
promises.lutimes
|
|
328
|
+
.call(this, path, atime, mtime)
|
|
329
|
+
.then(() => cb(null))
|
|
330
|
+
.catch(cb);
|
|
331
|
+
}
|
|
332
|
+
lutimes;
|
|
333
|
+
export function realpath(path, arg2, cb = nop) {
|
|
334
|
+
cb = typeof arg2 === 'function' ? arg2 : cb;
|
|
335
|
+
promises.realpath
|
|
336
|
+
.call(this, path, typeof arg2 === 'function' ? null : arg2)
|
|
337
|
+
.then(result => cb(null, result))
|
|
338
|
+
.catch(cb);
|
|
339
|
+
}
|
|
340
|
+
realpath;
|
|
341
|
+
export function access(path, cbMode, cb = nop) {
|
|
342
|
+
const mode = typeof cbMode === 'number' ? cbMode : R_OK;
|
|
343
|
+
cb = typeof cbMode === 'function' ? cbMode : cb;
|
|
344
|
+
promises.access
|
|
345
|
+
.call(this, path, mode)
|
|
346
|
+
.then(() => cb(null))
|
|
347
|
+
.catch(cb);
|
|
348
|
+
}
|
|
349
|
+
access;
|
|
350
|
+
const statWatchers = new Map();
|
|
351
|
+
export function watchFile(path, options, listener) {
|
|
352
|
+
const normalizedPath = normalizePath(path);
|
|
353
|
+
const opts = typeof options != 'function' ? options : {};
|
|
354
|
+
if (typeof options == 'function') {
|
|
355
|
+
listener = options;
|
|
356
|
+
}
|
|
357
|
+
if (!listener)
|
|
358
|
+
throw UV('EINVAL', 'watch', path.toString());
|
|
359
|
+
if (statWatchers.has(normalizedPath)) {
|
|
360
|
+
const entry = statWatchers.get(normalizedPath);
|
|
361
|
+
if (entry) {
|
|
362
|
+
entry.listeners.add(listener);
|
|
363
|
+
}
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
const watcher = new StatWatcher(this, normalizedPath, opts);
|
|
367
|
+
watcher.on('change', (curr, prev) => {
|
|
368
|
+
const entry = statWatchers.get(normalizedPath);
|
|
369
|
+
if (!entry) {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
for (const listener of entry.listeners) {
|
|
373
|
+
listener(curr, prev);
|
|
374
|
+
}
|
|
375
|
+
});
|
|
376
|
+
statWatchers.set(normalizedPath, { watcher, listeners: new Set() });
|
|
377
|
+
}
|
|
378
|
+
watchFile;
|
|
379
|
+
/**
|
|
380
|
+
* Stop watching for changes on a file.
|
|
381
|
+
*
|
|
382
|
+
* If the `listener` is specified, only that particular listener is removed.
|
|
383
|
+
* If no `listener` is specified, all listeners are removed, and the file is no longer watched.
|
|
384
|
+
*
|
|
385
|
+
* @param path The path to the file to stop watching.
|
|
386
|
+
* @param listener Optional listener to remove.
|
|
387
|
+
*/
|
|
388
|
+
export function unwatchFile(path, listener = nop) {
|
|
389
|
+
const normalizedPath = normalizePath(path);
|
|
390
|
+
const entry = statWatchers.get(normalizedPath);
|
|
391
|
+
if (entry) {
|
|
392
|
+
if (listener && listener !== nop) {
|
|
393
|
+
entry.listeners.delete(listener);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
// If no listener is specified, remove all listeners
|
|
397
|
+
entry.listeners.clear();
|
|
398
|
+
}
|
|
399
|
+
if (entry.listeners.size === 0) {
|
|
400
|
+
// No more listeners, stop the watcher
|
|
401
|
+
entry.watcher.stop();
|
|
402
|
+
statWatchers.delete(normalizedPath);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
unwatchFile;
|
|
407
|
+
export function watch(path, options, listener) {
|
|
408
|
+
const watcher = new FSWatcher(this, normalizePath(path), typeof options == 'object' ? options : {});
|
|
409
|
+
listener = typeof options == 'function' ? options : listener;
|
|
410
|
+
watcher.on('change', listener || nop);
|
|
411
|
+
return watcher;
|
|
412
|
+
}
|
|
413
|
+
watch;
|
|
414
|
+
/**
|
|
415
|
+
* Opens a file in read mode and creates a Node.js-like ReadStream.
|
|
416
|
+
*
|
|
417
|
+
* @param path The path to the file to be opened.
|
|
418
|
+
* @param options Options for the ReadStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
|
|
419
|
+
* @returns A ReadStream object for interacting with the file's contents.
|
|
420
|
+
*/
|
|
421
|
+
export function createReadStream(path, options) {
|
|
422
|
+
options = typeof options == 'object' ? options : { encoding: options };
|
|
423
|
+
const _handle = promises.open.call(this, path, 'r', options?.mode);
|
|
424
|
+
return new ReadStream({ ...options, autoClose: true }, _handle);
|
|
425
|
+
}
|
|
426
|
+
createReadStream;
|
|
427
|
+
/**
|
|
428
|
+
* Opens a file in write mode and creates a Node.js-like WriteStream.
|
|
429
|
+
*
|
|
430
|
+
* @param path The path to the file to be opened.
|
|
431
|
+
* @param options Options for the WriteStream and file opening (e.g., `encoding`, `highWaterMark`, `mode`).
|
|
432
|
+
* @returns A WriteStream object for writing to the file.
|
|
433
|
+
*/
|
|
434
|
+
export function createWriteStream(path, options) {
|
|
435
|
+
options = typeof options == 'object' ? options : { encoding: options };
|
|
436
|
+
const _handle = promises.open.call(this, path, 'w', options?.mode);
|
|
437
|
+
return new WriteStream(options, _handle);
|
|
438
|
+
}
|
|
439
|
+
createWriteStream;
|
|
440
|
+
export function rm(path, options, callback = nop) {
|
|
441
|
+
callback = typeof options === 'function' ? options : callback;
|
|
442
|
+
promises.rm
|
|
443
|
+
.call(this, path, typeof options === 'function' ? undefined : options)
|
|
444
|
+
.then(() => callback(null))
|
|
445
|
+
.catch(callback);
|
|
446
|
+
}
|
|
447
|
+
rm;
|
|
448
|
+
export function mkdtemp(prefix, options, callback = nop) {
|
|
449
|
+
callback = typeof options === 'function' ? options : callback;
|
|
450
|
+
promises.mkdtemp
|
|
451
|
+
.call(this, prefix, typeof options != 'function' ? options : null)
|
|
452
|
+
.then(result => callback(null, result))
|
|
453
|
+
.catch(callback);
|
|
454
|
+
}
|
|
455
|
+
mkdtemp;
|
|
456
|
+
export function copyFile(src, dest, flags, callback = nop) {
|
|
457
|
+
callback = typeof flags === 'function' ? flags : callback;
|
|
458
|
+
promises.copyFile
|
|
459
|
+
.call(this, src, dest, typeof flags === 'function' ? undefined : flags)
|
|
460
|
+
.then(() => callback(null))
|
|
461
|
+
.catch(callback);
|
|
462
|
+
}
|
|
463
|
+
copyFile;
|
|
464
|
+
export function readv(fd, buffers, position, cb = nop) {
|
|
465
|
+
cb = typeof position === 'function' ? position : cb;
|
|
466
|
+
new promises.FileHandle(this, fd)
|
|
467
|
+
.readv(buffers, typeof position === 'function' ? undefined : position)
|
|
468
|
+
.then(({ buffers, bytesRead }) => cb(null, bytesRead, buffers))
|
|
469
|
+
.catch(cb);
|
|
470
|
+
}
|
|
471
|
+
readv;
|
|
472
|
+
export function writev(fd, buffers, position, cb = nop) {
|
|
473
|
+
cb = typeof position === 'function' ? position : cb;
|
|
474
|
+
new promises.FileHandle(this, fd)
|
|
475
|
+
.writev(buffers, typeof position === 'function' ? undefined : position)
|
|
476
|
+
.then(({ buffers, bytesWritten }) => cb(null, bytesWritten, buffers))
|
|
477
|
+
.catch(cb);
|
|
478
|
+
}
|
|
479
|
+
writev;
|
|
480
|
+
export function opendir(path, options, cb = nop) {
|
|
481
|
+
cb = typeof options === 'function' ? options : cb;
|
|
482
|
+
promises.opendir
|
|
483
|
+
.call(this, path, typeof options === 'function' ? undefined : options)
|
|
484
|
+
.then(result => cb(null, result))
|
|
485
|
+
.catch(cb);
|
|
486
|
+
}
|
|
487
|
+
opendir;
|
|
488
|
+
export function cp(source, destination, opts, callback = nop) {
|
|
489
|
+
callback = typeof opts === 'function' ? opts : callback;
|
|
490
|
+
promises.cp
|
|
491
|
+
.call(this, source, destination, typeof opts === 'function' ? undefined : opts)
|
|
492
|
+
.then(() => callback(null))
|
|
493
|
+
.catch(callback);
|
|
494
|
+
}
|
|
495
|
+
cp;
|
|
496
|
+
export function statfs(path, options, callback = nop) {
|
|
497
|
+
callback = typeof options === 'function' ? options : callback;
|
|
498
|
+
promises.statfs
|
|
499
|
+
.call(this, path, typeof options === 'function' ? undefined : options)
|
|
500
|
+
.then(result => callback(null, result))
|
|
501
|
+
.catch(callback);
|
|
502
|
+
}
|
|
503
|
+
statfs;
|
|
504
|
+
export async function openAsBlob(path, options) {
|
|
505
|
+
const handle = await promises.open.call(this, path.toString(), 'r');
|
|
506
|
+
const buffer = await handle.readFile();
|
|
507
|
+
await handle.close();
|
|
508
|
+
return new Blob([buffer], options);
|
|
509
|
+
}
|
|
510
|
+
openAsBlob;
|
|
511
|
+
export function glob(pattern, options, callback = nop) {
|
|
512
|
+
callback = typeof options == 'function' ? options : callback;
|
|
513
|
+
const it = promises.glob.call(this, pattern, typeof options === 'function' ? undefined : options);
|
|
514
|
+
collectAsyncIterator(it)
|
|
515
|
+
.then(results => callback(null, results ?? []))
|
|
516
|
+
.catch((e) => callback(e));
|
|
517
|
+
}
|
|
518
|
+
glob;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Dir as _Dir, Dirent as _Dirent } from 'node:fs';
|
|
2
|
+
import type { V_Context } from '../context.js';
|
|
3
|
+
import type { Callback } from '../utils.js';
|
|
4
|
+
import { Buffer } from 'buffer';
|
|
5
|
+
import { DirType, type Dirent as VFSDirent } from '../vfs/dir.js';
|
|
6
|
+
export declare class Dirent<Name extends string | Buffer = string> implements _Dirent<Name> {
|
|
7
|
+
ino: number;
|
|
8
|
+
type: DirType;
|
|
9
|
+
protected _name: string;
|
|
10
|
+
get name(): Name;
|
|
11
|
+
/**
|
|
12
|
+
* @internal @protected
|
|
13
|
+
*/
|
|
14
|
+
_encoding?: BufferEncoding | 'buffer' | null;
|
|
15
|
+
/**
|
|
16
|
+
* @internal @protected
|
|
17
|
+
*/
|
|
18
|
+
_parentPath: string;
|
|
19
|
+
get parentPath(): string;
|
|
20
|
+
/**
|
|
21
|
+
* @deprecated Removed in Node v24, use `parentPath` instead.
|
|
22
|
+
*/
|
|
23
|
+
get path(): string;
|
|
24
|
+
/**
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
static from(vfs: VFSDirent, encoding?: BufferEncoding | 'buffer' | null): Dirent<string>;
|
|
28
|
+
isFile(): boolean;
|
|
29
|
+
isDirectory(): boolean;
|
|
30
|
+
isBlockDevice(): boolean;
|
|
31
|
+
isCharacterDevice(): boolean;
|
|
32
|
+
isSymbolicLink(): boolean;
|
|
33
|
+
isFIFO(): boolean;
|
|
34
|
+
isSocket(): boolean;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* A class representing a directory stream.
|
|
38
|
+
*/
|
|
39
|
+
export declare class Dir implements _Dir, AsyncIterator<Dirent> {
|
|
40
|
+
readonly path: string;
|
|
41
|
+
protected readonly context: V_Context;
|
|
42
|
+
protected closed: boolean;
|
|
43
|
+
protected checkClosed(): void;
|
|
44
|
+
protected _entries?: Dirent[];
|
|
45
|
+
constructor(path: string, context: V_Context);
|
|
46
|
+
/**
|
|
47
|
+
* Asynchronously close the directory's underlying resource handle.
|
|
48
|
+
* Subsequent reads will result in errors.
|
|
49
|
+
*/
|
|
50
|
+
close(): Promise<void>;
|
|
51
|
+
close(cb: Callback): void;
|
|
52
|
+
/**
|
|
53
|
+
* Synchronously close the directory's underlying resource handle.
|
|
54
|
+
* Subsequent reads will result in errors.
|
|
55
|
+
*/
|
|
56
|
+
closeSync(): void;
|
|
57
|
+
protected _read(): Promise<Dirent | null>;
|
|
58
|
+
/**
|
|
59
|
+
* Asynchronously read the next directory entry via `readdir(3)` as an `Dirent`.
|
|
60
|
+
* After the read is completed, a value is returned that will be resolved with an `Dirent`, or `null` if there are no more directory entries to read.
|
|
61
|
+
* Directory entries returned by this function are in no particular order as provided by the operating system's underlying directory mechanisms.
|
|
62
|
+
*/
|
|
63
|
+
read(): Promise<Dirent | null>;
|
|
64
|
+
read(cb: Callback<[Dirent | null]>): void;
|
|
65
|
+
/**
|
|
66
|
+
* Synchronously read the next directory entry via `readdir(3)` as a `Dirent`.
|
|
67
|
+
* If there are no more directory entries to read, null will be returned.
|
|
68
|
+
* Directory entries returned by this function are in no particular order as provided by the operating system's underlying directory mechanisms.
|
|
69
|
+
*/
|
|
70
|
+
readSync(): Dirent | null;
|
|
71
|
+
next(): Promise<IteratorResult<Dirent>>;
|
|
72
|
+
/**
|
|
73
|
+
* Asynchronously iterates over the directory via `readdir(3)` until all entries have been read.
|
|
74
|
+
*/
|
|
75
|
+
[Symbol.asyncIterator](): this;
|
|
76
|
+
[Symbol.dispose](): void;
|
|
77
|
+
[Symbol.asyncDispose](): Promise<void>;
|
|
78
|
+
}
|