@zenfs/core 0.5.4 → 0.5.6
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/dist/ApiError.d.ts +5 -12
- package/dist/ApiError.js +6 -27
- package/dist/FileIndex.js +10 -10
- package/dist/backends/AsyncMirror.d.ts +1 -1
- package/dist/backends/AsyncMirror.js +2 -0
- package/dist/backends/AsyncStore.js +24 -24
- package/dist/backends/InMemory.d.ts +2 -2
- package/dist/backends/InMemory.js +1 -0
- package/dist/backends/Overlay.d.ts +1 -1
- package/dist/backends/Overlay.js +17 -17
- package/dist/backends/SyncStore.js +23 -23
- package/dist/backends/backend.d.ts +4 -4
- package/dist/browser.min.js +4 -4
- package/dist/browser.min.js.map +4 -4
- package/dist/emulation/{callbacks.d.ts → async.d.ts} +52 -15
- package/dist/emulation/{callbacks.js → async.js} +99 -35
- package/dist/emulation/constants.d.ts +5 -0
- package/dist/emulation/constants.js +5 -0
- package/dist/emulation/dir.d.ts +3 -2
- package/dist/emulation/dir.js +6 -2
- package/dist/emulation/index.d.ts +2 -2
- package/dist/emulation/index.js +2 -2
- package/dist/emulation/promises.d.ts +88 -115
- package/dist/emulation/promises.js +112 -110
- package/dist/emulation/shared.d.ts +9 -10
- package/dist/emulation/shared.js +28 -40
- package/dist/emulation/streams.d.ts +5 -0
- package/dist/emulation/sync.d.ts +50 -18
- package/dist/emulation/sync.js +65 -29
- package/dist/file.d.ts +11 -7
- package/dist/file.js +11 -15
- package/dist/stats.d.ts +34 -19
- package/dist/stats.js +8 -51
- package/dist/utils.d.ts +2 -3
- package/dist/utils.js +6 -88
- package/package.json +3 -2
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import { Buffer } from 'buffer';
|
|
1
2
|
import { ApiError, ErrorCode } from '../ApiError.js';
|
|
2
|
-
|
|
3
|
-
import { ActionType, isReadable, isWriteable, isAppendable, parseFlag, pathExistsAction, pathNotExistsAction } from '../file.js';
|
|
4
|
-
import { normalizePath, normalizeMode, getFdForFile, normalizeOptions, fd2file, fdMap, normalizeTime, cred, nop, resolveFS, fixError, mounts } from './shared.js';
|
|
3
|
+
import { ActionType, isAppendable, isReadable, isWriteable, parseFlag, pathExistsAction, pathNotExistsAction } from '../file.js';
|
|
5
4
|
import { BigIntStats, FileType } from '../stats.js';
|
|
6
|
-
import {
|
|
5
|
+
import { F_OK } from './constants.js';
|
|
7
6
|
import { Dirent } from './dir.js';
|
|
8
7
|
import { dirname, join } from './path.js';
|
|
8
|
+
import { cred, fd2file, fdMap, fixError, getFdForFile, mounts, normalizeMode, normalizeOptions, normalizePath, normalizeTime, resolveFS } from './shared.js';
|
|
9
|
+
export * as constants from './constants.js';
|
|
9
10
|
export class FileHandle {
|
|
10
11
|
constructor(
|
|
11
12
|
/**
|
|
@@ -14,11 +15,17 @@ export class FileHandle {
|
|
|
14
15
|
fd) {
|
|
15
16
|
this.fd = fd;
|
|
16
17
|
}
|
|
18
|
+
get file() {
|
|
19
|
+
return fd2file(this.fd);
|
|
20
|
+
}
|
|
21
|
+
get path() {
|
|
22
|
+
return this.file.path;
|
|
23
|
+
}
|
|
17
24
|
/**
|
|
18
25
|
* Asynchronous fchown(2) - Change ownership of a file.
|
|
19
26
|
*/
|
|
20
27
|
chown(uid, gid) {
|
|
21
|
-
return
|
|
28
|
+
return this.file.chown(uid, gid);
|
|
22
29
|
}
|
|
23
30
|
/**
|
|
24
31
|
* Asynchronous fchmod(2) - Change permissions of a file.
|
|
@@ -29,19 +36,19 @@ export class FileHandle {
|
|
|
29
36
|
if (numMode < 0) {
|
|
30
37
|
throw new ApiError(ErrorCode.EINVAL, 'Invalid mode.');
|
|
31
38
|
}
|
|
32
|
-
return
|
|
39
|
+
return this.file.chmod(numMode);
|
|
33
40
|
}
|
|
34
41
|
/**
|
|
35
42
|
* Asynchronous fdatasync(2) - synchronize a file's in-core state with storage device.
|
|
36
43
|
*/
|
|
37
44
|
datasync() {
|
|
38
|
-
return
|
|
45
|
+
return this.file.datasync();
|
|
39
46
|
}
|
|
40
47
|
/**
|
|
41
48
|
* Asynchronous fsync(2) - synchronize a file's in-core state with the underlying storage device.
|
|
42
49
|
*/
|
|
43
50
|
sync() {
|
|
44
|
-
return
|
|
51
|
+
return this.file.sync();
|
|
45
52
|
}
|
|
46
53
|
/**
|
|
47
54
|
* Asynchronous ftruncate(2) - Truncate a file to a specified length.
|
|
@@ -51,7 +58,7 @@ export class FileHandle {
|
|
|
51
58
|
if (len < 0) {
|
|
52
59
|
throw new ApiError(ErrorCode.EINVAL);
|
|
53
60
|
}
|
|
54
|
-
return
|
|
61
|
+
return this.file.truncate(len);
|
|
55
62
|
}
|
|
56
63
|
/**
|
|
57
64
|
* Asynchronously change file timestamps of the file.
|
|
@@ -59,7 +66,7 @@ export class FileHandle {
|
|
|
59
66
|
* @param mtime The last modified time. If a string is provided, it will be coerced to number.
|
|
60
67
|
*/
|
|
61
68
|
utimes(atime, mtime) {
|
|
62
|
-
return
|
|
69
|
+
return this.file.utimes(normalizeTime(atime), normalizeTime(mtime));
|
|
63
70
|
}
|
|
64
71
|
/**
|
|
65
72
|
* Asynchronously append data to a file, creating the file if it does not exist. The underlying file will _not_ be closed automatically.
|
|
@@ -80,8 +87,8 @@ export class FileHandle {
|
|
|
80
87
|
if (typeof data != 'string' && !options.encoding) {
|
|
81
88
|
throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
|
|
82
89
|
}
|
|
83
|
-
const encodedData = typeof data == 'string' ?
|
|
84
|
-
await
|
|
90
|
+
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
91
|
+
await this.file.write(encodedData, 0, encodedData.length, null);
|
|
85
92
|
}
|
|
86
93
|
/**
|
|
87
94
|
* Asynchronously reads data from the file.
|
|
@@ -93,23 +100,44 @@ export class FileHandle {
|
|
|
93
100
|
*/
|
|
94
101
|
read(buffer, offset, length, position) {
|
|
95
102
|
if (isNaN(+position)) {
|
|
96
|
-
position =
|
|
103
|
+
position = this.file.position;
|
|
97
104
|
}
|
|
98
|
-
return
|
|
105
|
+
return this.file.read(buffer, offset, length, position);
|
|
99
106
|
}
|
|
100
107
|
async readFile(_options) {
|
|
101
|
-
const options = normalizeOptions(_options, null, 'r',
|
|
108
|
+
const options = normalizeOptions(_options, null, 'r', 0o444);
|
|
102
109
|
const flag = parseFlag(options.flag);
|
|
103
110
|
if (!isReadable(flag)) {
|
|
104
111
|
throw new ApiError(ErrorCode.EINVAL, 'Flag passed must allow for reading.');
|
|
105
112
|
}
|
|
106
113
|
const { size } = await this.stat();
|
|
107
114
|
const data = new Uint8Array(size);
|
|
108
|
-
await
|
|
109
|
-
|
|
115
|
+
await this.file.read(data, 0, size, 0);
|
|
116
|
+
const buffer = Buffer.from(data);
|
|
117
|
+
return options.encoding ? buffer.toString(options.encoding) : buffer;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Returns a `ReadableStream` that may be used to read the files data.
|
|
121
|
+
*
|
|
122
|
+
* An error will be thrown if this method is called more than once or is called after the `FileHandle` is closed
|
|
123
|
+
* or closing.
|
|
124
|
+
*
|
|
125
|
+
* While the `ReadableStream` will read the file to completion, it will not close the `FileHandle` automatically. User code must still call the `fileHandle.close()` method.
|
|
126
|
+
*
|
|
127
|
+
* @since v17.0.0
|
|
128
|
+
* @experimental
|
|
129
|
+
*/
|
|
130
|
+
readableWebStream(options) {
|
|
131
|
+
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.readableWebStream');
|
|
132
|
+
}
|
|
133
|
+
readLines(options) {
|
|
134
|
+
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.readLines');
|
|
135
|
+
}
|
|
136
|
+
[Symbol.asyncDispose]() {
|
|
137
|
+
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.@@asyncDispose');
|
|
110
138
|
}
|
|
111
139
|
async stat(opts) {
|
|
112
|
-
const stats = await
|
|
140
|
+
const stats = await this.file.stat();
|
|
113
141
|
return opts?.bigint ? new BigIntStats(stats) : stats;
|
|
114
142
|
}
|
|
115
143
|
async write(data, posOrOff, lenOrEnc, position) {
|
|
@@ -119,7 +147,7 @@ export class FileHandle {
|
|
|
119
147
|
position = typeof posOrOff === 'number' ? posOrOff : null;
|
|
120
148
|
const encoding = (typeof lenOrEnc === 'string' ? lenOrEnc : 'utf8');
|
|
121
149
|
offset = 0;
|
|
122
|
-
buffer =
|
|
150
|
+
buffer = Buffer.from(data, encoding);
|
|
123
151
|
length = buffer.length;
|
|
124
152
|
}
|
|
125
153
|
else {
|
|
@@ -129,8 +157,8 @@ export class FileHandle {
|
|
|
129
157
|
length = lenOrEnc;
|
|
130
158
|
position = typeof position === 'number' ? position : null;
|
|
131
159
|
}
|
|
132
|
-
position ?? (position =
|
|
133
|
-
const bytesWritten = await
|
|
160
|
+
position ?? (position = this.file.position);
|
|
161
|
+
const bytesWritten = await this.file.write(buffer, offset, length, position);
|
|
134
162
|
return { buffer, bytesWritten };
|
|
135
163
|
}
|
|
136
164
|
/**
|
|
@@ -153,28 +181,36 @@ export class FileHandle {
|
|
|
153
181
|
if (typeof data != 'string' && !options.encoding) {
|
|
154
182
|
throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
|
|
155
183
|
}
|
|
156
|
-
const encodedData = typeof data == 'string' ?
|
|
157
|
-
await
|
|
184
|
+
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
185
|
+
await this.file.write(encodedData, 0, encodedData.length, 0);
|
|
158
186
|
}
|
|
159
187
|
/**
|
|
160
188
|
* See `fs.writev` promisified version.
|
|
189
|
+
* @todo Implement
|
|
161
190
|
*/
|
|
162
191
|
writev(buffers, position) {
|
|
163
|
-
throw
|
|
192
|
+
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.writev');
|
|
164
193
|
}
|
|
165
194
|
/**
|
|
166
195
|
* See `fs.readv` promisified version.
|
|
196
|
+
* @todo Implement
|
|
167
197
|
*/
|
|
168
198
|
readv(buffers, position) {
|
|
169
|
-
throw
|
|
199
|
+
throw ApiError.With('ENOTSUP', this.path, 'FileHandle.readv');
|
|
170
200
|
}
|
|
171
201
|
/**
|
|
172
202
|
* Asynchronous close(2) - close a `FileHandle`.
|
|
173
203
|
*/
|
|
174
204
|
async close() {
|
|
175
|
-
await
|
|
205
|
+
await this.file.close();
|
|
176
206
|
fdMap.delete(this.fd);
|
|
177
207
|
}
|
|
208
|
+
createReadStream(options) {
|
|
209
|
+
throw ApiError.With('ENOTSUP', this.path, 'createReadStream');
|
|
210
|
+
}
|
|
211
|
+
createWriteStream(options) {
|
|
212
|
+
throw ApiError.With('ENOTSUP', this.path, 'createWriteStream');
|
|
213
|
+
}
|
|
178
214
|
}
|
|
179
215
|
/**
|
|
180
216
|
* Utility for FS ops. It handles
|
|
@@ -208,15 +244,18 @@ async function doOp(...[name, resolveSymlinks, rawPath, ...args]) {
|
|
|
208
244
|
export async function rename(oldPath, newPath) {
|
|
209
245
|
oldPath = normalizePath(oldPath);
|
|
210
246
|
newPath = normalizePath(newPath);
|
|
211
|
-
const
|
|
212
|
-
const
|
|
247
|
+
const src = resolveFS(oldPath);
|
|
248
|
+
const dst = resolveFS(newPath);
|
|
213
249
|
try {
|
|
214
|
-
|
|
215
|
-
|
|
250
|
+
if (src.mountPoint == dst.mountPoint) {
|
|
251
|
+
await src.fs.rename(src.path, dst.path, cred);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
await writeFile(newPath, await readFile(oldPath));
|
|
216
255
|
await unlink(oldPath);
|
|
217
256
|
}
|
|
218
257
|
catch (e) {
|
|
219
|
-
throw fixError(e, { [
|
|
258
|
+
throw fixError(e, { [src.path]: oldPath, [dst.path]: newPath });
|
|
220
259
|
}
|
|
221
260
|
}
|
|
222
261
|
rename;
|
|
@@ -279,7 +318,7 @@ async function _open(_path, _flag, _mode = 0o644, resolveSymlinks) {
|
|
|
279
318
|
try {
|
|
280
319
|
switch (pathExistsAction(flag)) {
|
|
281
320
|
case ActionType.THROW:
|
|
282
|
-
throw ApiError.EEXIST
|
|
321
|
+
throw ApiError.With('EEXIST', path, '_open');
|
|
283
322
|
case ActionType.TRUNCATE:
|
|
284
323
|
/*
|
|
285
324
|
In a previous implementation, we deleted the file and
|
|
@@ -307,11 +346,11 @@ async function _open(_path, _flag, _mode = 0o644, resolveSymlinks) {
|
|
|
307
346
|
// Ensure parent exists.
|
|
308
347
|
const parentStats = await doOp('stat', resolveSymlinks, dirname(path), cred);
|
|
309
348
|
if (parentStats && !parentStats.isDirectory()) {
|
|
310
|
-
throw ApiError.ENOTDIR
|
|
349
|
+
throw ApiError.With('ENOTDIR', dirname(path), '_open');
|
|
311
350
|
}
|
|
312
351
|
return await doOp('createFile', resolveSymlinks, path, flag, mode, cred);
|
|
313
352
|
case ActionType.THROW:
|
|
314
|
-
throw ApiError.ENOENT
|
|
353
|
+
throw ApiError.With('ENOENT', path, '_open');
|
|
315
354
|
default:
|
|
316
355
|
throw new ApiError(ErrorCode.EINVAL, 'Invalid file flag');
|
|
317
356
|
}
|
|
@@ -359,8 +398,8 @@ export async function readFile(filename, _options) {
|
|
|
359
398
|
if (!isReadable(flag)) {
|
|
360
399
|
throw new ApiError(ErrorCode.EINVAL, 'Flag passed must allow for reading.');
|
|
361
400
|
}
|
|
362
|
-
const data = await _readFile(filename, options.flag, true);
|
|
363
|
-
return options.encoding ?
|
|
401
|
+
const data = Buffer.from(await _readFile(filename, options.flag, true));
|
|
402
|
+
return options.encoding ? data.toString(options.encoding) : data;
|
|
364
403
|
}
|
|
365
404
|
readFile;
|
|
366
405
|
/**
|
|
@@ -417,60 +456,10 @@ export async function appendFile(filename, data, _options) {
|
|
|
417
456
|
if (typeof data != 'string' && !options.encoding) {
|
|
418
457
|
throw new ApiError(ErrorCode.EINVAL, 'Encoding not specified');
|
|
419
458
|
}
|
|
420
|
-
const encodedData = typeof data == 'string' ?
|
|
459
|
+
const encodedData = typeof data == 'string' ? Buffer.from(data, options.encoding) : data;
|
|
421
460
|
await _appendFile(filename, encodedData, options.flag, options.mode, true);
|
|
422
461
|
}
|
|
423
462
|
appendFile;
|
|
424
|
-
export function write(handle, data, posOrOff, lenOrEnc, position) {
|
|
425
|
-
return handle.write(data, posOrOff, lenOrEnc, position);
|
|
426
|
-
}
|
|
427
|
-
write;
|
|
428
|
-
/**
|
|
429
|
-
* Read data from the file specified by `fd`.
|
|
430
|
-
* @param handle
|
|
431
|
-
* @param buffer The buffer that the data will be
|
|
432
|
-
* written to.
|
|
433
|
-
* @param offset The offset within the buffer where writing will
|
|
434
|
-
* start.
|
|
435
|
-
* @param length An integer specifying the number of bytes to read.
|
|
436
|
-
* @param position An integer specifying where to begin reading from
|
|
437
|
-
* in the file. If position is null, data will be read from the current file
|
|
438
|
-
* position.
|
|
439
|
-
*/
|
|
440
|
-
export function read(handle, buffer, offset, length, position) {
|
|
441
|
-
return handle.read(buffer, offset, length, position);
|
|
442
|
-
}
|
|
443
|
-
read;
|
|
444
|
-
/**
|
|
445
|
-
* `fchown`.
|
|
446
|
-
* @param handle
|
|
447
|
-
* @param uid
|
|
448
|
-
* @param gid
|
|
449
|
-
*/
|
|
450
|
-
export function fchown(handle, uid, gid) {
|
|
451
|
-
return handle.chown(uid, gid);
|
|
452
|
-
}
|
|
453
|
-
fchown;
|
|
454
|
-
/**
|
|
455
|
-
* `fchmod`.
|
|
456
|
-
* @param handle
|
|
457
|
-
* @param mode
|
|
458
|
-
*/
|
|
459
|
-
export function fchmod(handle, mode) {
|
|
460
|
-
return handle.chmod(mode);
|
|
461
|
-
}
|
|
462
|
-
fchmod;
|
|
463
|
-
/**
|
|
464
|
-
* Change the file timestamps of a file referenced by the supplied file
|
|
465
|
-
* descriptor.
|
|
466
|
-
* @param handle
|
|
467
|
-
* @param atime
|
|
468
|
-
* @param mtime
|
|
469
|
-
*/
|
|
470
|
-
export function futimes(handle, atime, mtime) {
|
|
471
|
-
return handle.utimes(atime, mtime);
|
|
472
|
-
}
|
|
473
|
-
futimes;
|
|
474
463
|
// DIRECTORY-ONLY METHODS
|
|
475
464
|
/**
|
|
476
465
|
* `rmdir`.
|
|
@@ -527,7 +516,7 @@ export async function symlink(target, path, type = 'file') {
|
|
|
527
516
|
throw new ApiError(ErrorCode.EINVAL, 'Invalid symlink type: ' + type);
|
|
528
517
|
}
|
|
529
518
|
if (await exists(path)) {
|
|
530
|
-
throw ApiError.EEXIST
|
|
519
|
+
throw ApiError.With('EEXIST', path, 'symlink');
|
|
531
520
|
}
|
|
532
521
|
await writeFile(path, target);
|
|
533
522
|
const file = await _open(path, 'r+', 0o644, false);
|
|
@@ -535,12 +524,12 @@ export async function symlink(target, path, type = 'file') {
|
|
|
535
524
|
}
|
|
536
525
|
symlink;
|
|
537
526
|
export async function readlink(path, options) {
|
|
538
|
-
const value = await _readFile(path, 'r', false);
|
|
527
|
+
const value = Buffer.from(await _readFile(path, 'r', false));
|
|
539
528
|
const encoding = typeof options == 'object' ? options.encoding : options;
|
|
540
529
|
if (encoding == 'buffer') {
|
|
541
530
|
return value;
|
|
542
531
|
}
|
|
543
|
-
return
|
|
532
|
+
return value.toString(encoding);
|
|
544
533
|
}
|
|
545
534
|
readlink;
|
|
546
535
|
// PROPERTY OPERATIONS
|
|
@@ -646,7 +635,7 @@ export async function realpath(path, options) {
|
|
|
646
635
|
if (!stats.isSymbolicLink()) {
|
|
647
636
|
return path;
|
|
648
637
|
}
|
|
649
|
-
const dst = mountPoint + normalizePath(
|
|
638
|
+
const dst = mountPoint + normalizePath(Buffer.from(await _readFile(resolvedPath, 'r+', false)).toString());
|
|
650
639
|
return realpath(dst);
|
|
651
640
|
}
|
|
652
641
|
catch (e) {
|
|
@@ -654,38 +643,51 @@ export async function realpath(path, options) {
|
|
|
654
643
|
}
|
|
655
644
|
}
|
|
656
645
|
realpath;
|
|
657
|
-
export
|
|
658
|
-
throw
|
|
659
|
-
}
|
|
660
|
-
export async function unwatchFile(filename, listener = nop) {
|
|
661
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
662
|
-
}
|
|
663
|
-
export async function watch(filename, arg2, listener = nop) {
|
|
664
|
-
throw new ApiError(ErrorCode.ENOTSUP);
|
|
646
|
+
export function watch(filename, options) {
|
|
647
|
+
throw ApiError.With('ENOTSUP', filename, 'watch');
|
|
665
648
|
}
|
|
649
|
+
watch;
|
|
666
650
|
/**
|
|
667
651
|
* `access`.
|
|
668
652
|
* @param path
|
|
669
653
|
* @param mode
|
|
670
654
|
*/
|
|
671
|
-
export async function access(path, mode =
|
|
655
|
+
export async function access(path, mode = F_OK) {
|
|
672
656
|
const stats = await stat(path);
|
|
673
657
|
if (!stats.hasAccess(mode, cred)) {
|
|
674
658
|
throw new ApiError(ErrorCode.EACCES);
|
|
675
659
|
}
|
|
676
660
|
}
|
|
677
|
-
|
|
678
|
-
|
|
661
|
+
access;
|
|
662
|
+
/**
|
|
663
|
+
* @todo Implement
|
|
664
|
+
*/
|
|
665
|
+
export async function rm(path, options) {
|
|
666
|
+
throw ApiError.With('ENOTSUP', path, 'rm');
|
|
679
667
|
}
|
|
680
|
-
|
|
681
|
-
|
|
668
|
+
rm;
|
|
669
|
+
export async function mkdtemp(prefix, options) {
|
|
670
|
+
throw ApiError.With('ENOTSUP', prefix, 'mkdtemp');
|
|
682
671
|
}
|
|
683
|
-
|
|
684
|
-
|
|
672
|
+
mkdtemp;
|
|
673
|
+
/**
|
|
674
|
+
* @todo Implement
|
|
675
|
+
*/
|
|
676
|
+
export async function copyFile(src, dest, mode) {
|
|
677
|
+
throw ApiError.With('ENOTSUP', src, 'copyFile');
|
|
678
|
+
}
|
|
679
|
+
copyFile;
|
|
680
|
+
/**
|
|
681
|
+
* @todo Implement
|
|
682
|
+
*/
|
|
683
|
+
export async function opendir(path, options) {
|
|
684
|
+
throw ApiError.With('ENOTSUP', path, 'opendir');
|
|
685
685
|
}
|
|
686
|
-
|
|
687
|
-
|
|
686
|
+
opendir;
|
|
687
|
+
export async function cp(source, destination, opts) {
|
|
688
|
+
throw ApiError.With('ENOTSUP', source, 'cp');
|
|
688
689
|
}
|
|
689
|
-
|
|
690
|
-
|
|
690
|
+
cp;
|
|
691
|
+
export async function statfs(path, opts) {
|
|
692
|
+
throw ApiError.With('ENOTSUP', path, 'statfs');
|
|
691
693
|
}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
/// <reference types="node" resolution-mode="require"/>
|
|
2
|
+
/// <reference types="node" resolution-mode="require"/>
|
|
2
3
|
import { Cred } from '../cred.js';
|
|
3
4
|
import { FileSystem } from '../filesystem.js';
|
|
4
5
|
import type { File } from '../file.js';
|
|
6
|
+
import type { EncodingOption, OpenMode, WriteFileOptions } from 'node:fs';
|
|
5
7
|
/**
|
|
6
8
|
* converts Date or number to a integer UNIX timestamp
|
|
7
9
|
* Grabbed from NodeJS sources (lib/fs.js)
|
|
@@ -26,9 +28,15 @@ export declare function normalizeTime(time: string | number | Date): Date;
|
|
|
26
28
|
export declare function normalizePath(p: string): string;
|
|
27
29
|
/**
|
|
28
30
|
* Normalizes options
|
|
31
|
+
* @param options options to normalize
|
|
32
|
+
* @param encoding default encoding
|
|
33
|
+
* @param flag default flag
|
|
34
|
+
* @param mode default mode
|
|
29
35
|
* @internal
|
|
30
36
|
*/
|
|
31
|
-
export declare function normalizeOptions(options
|
|
37
|
+
export declare function normalizeOptions(options?: WriteFileOptions | (EncodingOption & {
|
|
38
|
+
flag?: OpenMode;
|
|
39
|
+
}), encoding?: BufferEncoding, flag?: string, mode?: number): {
|
|
32
40
|
encoding: BufferEncoding;
|
|
33
41
|
flag: string;
|
|
34
42
|
mode: number;
|
|
@@ -83,12 +91,3 @@ export declare function initialize(mountMapping: MountMapping): void;
|
|
|
83
91
|
* In the future, maybe support URL?
|
|
84
92
|
*/
|
|
85
93
|
export type PathLike = string;
|
|
86
|
-
/**
|
|
87
|
-
* @internal
|
|
88
|
-
*
|
|
89
|
-
* Recursivly converts `From` in `Target` to `To`
|
|
90
|
-
*/
|
|
91
|
-
export type Convert<Target, From, To> = Target extends From ? To : Target extends (...args: any[]) => unknown ? (...args: Convert<Parameters<Target>, From, To> & Array<unknown>) => Convert<ReturnType<Target>, From, To> : Target extends object ? {
|
|
92
|
-
[K in keyof Target]: Convert<Target[K], From, To>;
|
|
93
|
-
} : Target;
|
|
94
|
-
export type BufferToUint8Array<T> = Convert<T, Buffer, Uint8Array>;
|
package/dist/emulation/shared.js
CHANGED
|
@@ -23,16 +23,14 @@ export function _toUnixTimestamp(time) {
|
|
|
23
23
|
* @internal
|
|
24
24
|
*/
|
|
25
25
|
export function normalizeMode(mode, def) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
return trueMode;
|
|
35
|
-
}
|
|
26
|
+
if (typeof mode == 'number') {
|
|
27
|
+
return mode;
|
|
28
|
+
}
|
|
29
|
+
if (typeof mode == 'string') {
|
|
30
|
+
const parsed = parseInt(mode, 8);
|
|
31
|
+
if (!isNaN(parsed)) {
|
|
32
|
+
return parsed;
|
|
33
|
+
}
|
|
36
34
|
}
|
|
37
35
|
if (typeof def == 'number') {
|
|
38
36
|
return def;
|
|
@@ -61,45 +59,35 @@ export function normalizeTime(time) {
|
|
|
61
59
|
*/
|
|
62
60
|
export function normalizePath(p) {
|
|
63
61
|
// Node doesn't allow null characters in paths.
|
|
64
|
-
if (p.
|
|
62
|
+
if (p.includes('\x00')) {
|
|
65
63
|
throw new ApiError(ErrorCode.EINVAL, 'Path must be a string without null bytes.');
|
|
66
64
|
}
|
|
67
|
-
if (p
|
|
65
|
+
if (p.length == 0) {
|
|
68
66
|
throw new ApiError(ErrorCode.EINVAL, 'Path must not be empty.');
|
|
69
67
|
}
|
|
70
|
-
|
|
71
|
-
return resolve(p);
|
|
68
|
+
return resolve(p.replaceAll(/[/\\]+/g, '/'));
|
|
72
69
|
}
|
|
73
70
|
/**
|
|
74
71
|
* Normalizes options
|
|
72
|
+
* @param options options to normalize
|
|
73
|
+
* @param encoding default encoding
|
|
74
|
+
* @param flag default flag
|
|
75
|
+
* @param mode default mode
|
|
75
76
|
* @internal
|
|
76
77
|
*/
|
|
77
|
-
export function normalizeOptions(options,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
mode: defMode,
|
|
91
|
-
};
|
|
92
|
-
case 'null':
|
|
93
|
-
case 'undefined':
|
|
94
|
-
case 'function':
|
|
95
|
-
return {
|
|
96
|
-
encoding: defEnc,
|
|
97
|
-
flag: defFlag,
|
|
98
|
-
mode: defMode,
|
|
99
|
-
};
|
|
100
|
-
default:
|
|
101
|
-
throw new TypeError(`"options" must be a string or an object, got ${typeof options} instead.`);
|
|
102
|
-
}
|
|
78
|
+
export function normalizeOptions(options, encoding = 'utf8', flag, mode = 0) {
|
|
79
|
+
if (typeof options != 'object' || options === null) {
|
|
80
|
+
return {
|
|
81
|
+
encoding: typeof options == 'string' ? options : encoding,
|
|
82
|
+
flag,
|
|
83
|
+
mode,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
encoding: typeof options?.encoding == 'string' ? options.encoding : encoding,
|
|
88
|
+
flag: typeof options?.flag == 'string' ? options.flag : flag,
|
|
89
|
+
mode: normalizeMode('mode' in options ? options?.mode : null, mode),
|
|
90
|
+
};
|
|
103
91
|
}
|
|
104
92
|
/**
|
|
105
93
|
* Do nothing
|
|
@@ -67,6 +67,7 @@ export declare class WriteStream extends Writable implements Node.WriteStream {
|
|
|
67
67
|
addListener(event: 'pipe', listener: (src: Readable) => void): this;
|
|
68
68
|
addListener(event: 'ready', listener: () => void): this;
|
|
69
69
|
addListener(event: 'unpipe', listener: (src: Readable) => void): this;
|
|
70
|
+
addListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
70
71
|
on(event: 'close', listener: () => void): this;
|
|
71
72
|
on(event: 'drain', listener: () => void): this;
|
|
72
73
|
on(event: 'error', listener: (err: Error) => void): this;
|
|
@@ -75,6 +76,7 @@ export declare class WriteStream extends Writable implements Node.WriteStream {
|
|
|
75
76
|
on(event: 'pipe', listener: (src: Readable) => void): this;
|
|
76
77
|
on(event: 'ready', listener: () => void): this;
|
|
77
78
|
on(event: 'unpipe', listener: (src: Readable) => void): this;
|
|
79
|
+
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
78
80
|
once(event: 'close', listener: () => void): this;
|
|
79
81
|
once(event: 'drain', listener: () => void): this;
|
|
80
82
|
once(event: 'error', listener: (err: Error) => void): this;
|
|
@@ -83,6 +85,7 @@ export declare class WriteStream extends Writable implements Node.WriteStream {
|
|
|
83
85
|
once(event: 'pipe', listener: (src: Readable) => void): this;
|
|
84
86
|
once(event: 'ready', listener: () => void): this;
|
|
85
87
|
once(event: 'unpipe', listener: (src: Readable) => void): this;
|
|
88
|
+
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
86
89
|
prependListener(event: 'close', listener: () => void): this;
|
|
87
90
|
prependListener(event: 'drain', listener: () => void): this;
|
|
88
91
|
prependListener(event: 'error', listener: (err: Error) => void): this;
|
|
@@ -91,6 +94,7 @@ export declare class WriteStream extends Writable implements Node.WriteStream {
|
|
|
91
94
|
prependListener(event: 'pipe', listener: (src: Readable) => void): this;
|
|
92
95
|
prependListener(event: 'ready', listener: () => void): this;
|
|
93
96
|
prependListener(event: 'unpipe', listener: (src: Readable) => void): this;
|
|
97
|
+
prependListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
94
98
|
prependOnceListener(event: 'close', listener: () => void): this;
|
|
95
99
|
prependOnceListener(event: 'drain', listener: () => void): this;
|
|
96
100
|
prependOnceListener(event: 'error', listener: (err: Error) => void): this;
|
|
@@ -99,4 +103,5 @@ export declare class WriteStream extends Writable implements Node.WriteStream {
|
|
|
99
103
|
prependOnceListener(event: 'pipe', listener: (src: Readable) => void): this;
|
|
100
104
|
prependOnceListener(event: 'ready', listener: () => void): this;
|
|
101
105
|
prependOnceListener(event: 'unpipe', listener: (src: Readable) => void): this;
|
|
106
|
+
prependOnceListener(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
102
107
|
}
|