@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.
@@ -1,11 +1,12 @@
1
+ import { Buffer } from 'buffer';
1
2
  import { ApiError, ErrorCode } from '../ApiError.js';
2
- export * as constants from './constants.js';
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 { decode, encode } from '../utils.js';
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 fd2file(this.fd).chown(uid, gid);
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 fd2file(this.fd).chmod(numMode);
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 fd2file(this.fd).datasync();
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 fd2file(this.fd).sync();
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 fd2file(this.fd).truncate(len);
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 fd2file(this.fd).utimes(normalizeTime(atime), normalizeTime(mtime));
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' ? encode(data) : data;
84
- await fd2file(this.fd).write(encodedData, 0, encodedData.length, null);
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 = fd2file(this.fd).position;
103
+ position = this.file.position;
97
104
  }
98
- return fd2file(this.fd).read(buffer, offset, length, position);
105
+ return this.file.read(buffer, offset, length, position);
99
106
  }
100
107
  async readFile(_options) {
101
- const options = normalizeOptions(_options, null, 'r', null);
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 fd2file(this.fd).read(data, 0, size, 0);
109
- return options.encoding ? decode(data, options.encoding) : data;
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 fd2file(this.fd).stat();
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 = encode(data, encoding);
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 = fd2file(this.fd).position);
133
- const bytesWritten = await fd2file(this.fd).write(buffer, offset, length, position);
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' ? encode(data, options.encoding) : data;
157
- await fd2file(this.fd).write(encodedData, 0, encodedData.length, 0);
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 new ApiError(ErrorCode.ENOTSUP);
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 new ApiError(ErrorCode.ENOTSUP);
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 fd2file(this.fd).close();
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 { path: old } = resolveFS(oldPath);
212
- const { fs, path } = resolveFS(newPath);
247
+ const src = resolveFS(oldPath);
248
+ const dst = resolveFS(newPath);
213
249
  try {
214
- const data = await readFile(oldPath);
215
- await writeFile(newPath, data);
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, { [old]: oldPath, [path]: newPath });
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(path);
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(dirname(path));
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(path);
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 ? decode(data, options.encoding) : data;
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' ? encode(data) : data;
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(path);
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 decode(value, encoding);
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(decode(await _readFile(resolvedPath, 'r+', false)));
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 async function watchFile(filename, arg2, listener = nop) {
658
- throw new ApiError(ErrorCode.ENOTSUP);
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 = 0o600) {
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
- export async function createReadStream(path, options) {
678
- throw new ApiError(ErrorCode.ENOTSUP);
661
+ access;
662
+ /**
663
+ * @todo Implement
664
+ */
665
+ export async function rm(path, options) {
666
+ throw ApiError.With('ENOTSUP', path, 'rm');
679
667
  }
680
- export async function createWriteStream(path, options) {
681
- throw new ApiError(ErrorCode.ENOTSUP);
668
+ rm;
669
+ export async function mkdtemp(prefix, options) {
670
+ throw ApiError.With('ENOTSUP', prefix, 'mkdtemp');
682
671
  }
683
- export async function rm(path) {
684
- throw new ApiError(ErrorCode.ENOTSUP);
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
- export async function mkdtemp(path) {
687
- throw new ApiError(ErrorCode.ENOTSUP);
686
+ opendir;
687
+ export async function cp(source, destination, opts) {
688
+ throw ApiError.With('ENOTSUP', source, 'cp');
688
689
  }
689
- export async function copyFile(path) {
690
- throw new ApiError(ErrorCode.ENOTSUP);
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: unknown, defEnc: string | null, defFlag: string, defMode: number | null): {
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>;
@@ -23,16 +23,14 @@ export function _toUnixTimestamp(time) {
23
23
  * @internal
24
24
  */
25
25
  export function normalizeMode(mode, def) {
26
- switch (typeof mode) {
27
- case 'number':
28
- // (path, flag, mode, cb?)
29
- return mode;
30
- case 'string':
31
- // (path, flag, modeString, cb?)
32
- const trueMode = parseInt(mode, 8);
33
- if (!isNaN(trueMode)) {
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.indexOf('\u0000') >= 0) {
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
- p = p.replaceAll(/\/+/g, '/');
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, defEnc, defFlag, defMode) {
78
- // typeof null === 'object' so special-case handing is needed.
79
- switch (options === null ? 'null' : typeof options) {
80
- case 'object':
81
- return {
82
- encoding: typeof options['encoding'] !== 'undefined' ? options['encoding'] : defEnc,
83
- flag: typeof options['flag'] !== 'undefined' ? options['flag'] : defFlag,
84
- mode: normalizeMode(options['mode'], defMode),
85
- };
86
- case 'string':
87
- return {
88
- encoding: options,
89
- flag: defFlag,
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
  }