// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. // deno-lint-ignore-file no-explicit-any // Forked from https://github.com/DefinitelyTyped/DefinitelyTyped/blob/4f538975138678878fed5b2555c0672aa578ab7d/types/node/stream.d.ts import { Buffer } from "node:buffer"; import { Abortable, EventEmitter } from "ext:deno_node/_events.d.ts"; import { Buffered, BufferEncoding, ErrnoException, ReadableStream, ReadWriteStream, WritableStream, } from "ext:deno_node/_global.d.ts"; export class Stream extends EventEmitter { pipe<T extends WritableStream>( destination: T, options?: { end?: boolean | undefined; }, ): T; constructor(opts?: ReadableOptions); } interface StreamOptions<T extends Stream> extends Abortable { emitClose?: boolean | undefined; highWaterMark?: number | undefined; objectMode?: boolean | undefined; construct?(this: T, callback: (error?: Error | null) => void): void; destroy?( this: T, error: Error | null, callback: (error: Error | null) => void, ): void; autoDestroy?: boolean | undefined; } export interface ReadableOptions extends StreamOptions<Readable> { encoding?: BufferEncoding | undefined; read?(this: Readable, size: number): void; } /** * @since v0.9.4 */ export class Readable extends Stream implements ReadableStream { /** * A utility method for creating Readable Streams out of iterators. */ static from( iterable: Iterable<any> | AsyncIterable<any>, options?: ReadableOptions, ): Readable; /** * A utility method for creating `Readable` from a `ReadableStream`. * @since v17.0.0 * @experimental */ static fromWeb( readableStream: globalThis.ReadableStream, options?: Pick< ReadableOptions, "encoding" | "highWaterMark" | "objectMode" | "signal" >, ): Readable; /** * Returns whether the stream has been read from or cancelled. * @since v16.8.0 */ static isDisturbed(stream: Readable | ReadableStream): boolean; /** * Returns whether the stream was destroyed or errored before emitting `'end'`. * @since v16.8.0 * @experimental */ readonly readableAborted: boolean; /** * Is `true` if it is safe to call `readable.read()`, which means * the stream has not been destroyed or emitted `'error'` or `'end'`. * @since v11.4.0 */ readable: boolean; /** * Returns whether `'data'` has been emitted. * @since v16.7.0 * @experimental */ readonly readableDidRead: boolean; /** * Getter for the property `encoding` of a given `Readable` stream. The `encoding`property can be set using the `readable.setEncoding()` method. * @since v12.7.0 */ readonly readableEncoding: BufferEncoding | null; /** * Becomes `true` when `'end'` event is emitted. * @since v12.9.0 */ readonly readableEnded: boolean; /** * This property reflects the current state of a `Readable` stream as described * in the `Three states` section. * @since v9.4.0 */ readonly readableFlowing: boolean | null; /** * Returns the value of `highWaterMark` passed when creating this `Readable`. * @since v9.3.0 */ readonly readableHighWaterMark: number; /** * This property contains the number of bytes (or objects) in the queue * ready to be read. The value provides introspection data regarding * the status of the `highWaterMark`. * @since v9.4.0 */ readonly readableLength: number; /** * Getter for the property `objectMode` of a given `Readable` stream. * @since v12.3.0 */ readonly readableObjectMode: boolean; /** * Is `true` after `readable.destroy()` has been called. * @since v8.0.0 */ destroyed: boolean; constructor(opts?: ReadableOptions); _construct?(callback: (error?: Error | null) => void): void; _read(size: number): void; _undestroy(): void; /** * The `readable.read()` method pulls some data out of the internal buffer and * returns it. If no data available to be read, `null` is returned. By default, * the data will be returned as a `Buffer` object unless an encoding has been * specified using the `readable.setEncoding()` method or the stream is operating * in object mode. * * The optional `size` argument specifies a specific number of bytes to read. If`size` bytes are not available to be read, `null` will be returned _unless_the stream has ended, in which * case all of the data remaining in the internal * buffer will be returned. * * If the `size` argument is not specified, all of the data contained in the * internal buffer will be returned. * * The `size` argument must be less than or equal to 1 GiB. * * The `readable.read()` method should only be called on `Readable` streams * operating in paused mode. In flowing mode, `readable.read()` is called * automatically until the internal buffer is fully drained. * * ```js * const readable = getReadableStreamSomehow(); * * // 'readable' may be triggered multiple times as data is buffered in * readable.on('readable', () => { * let chunk; * console.log('Stream is readable (new data received in buffer)'); * // Use a loop to make sure we read all currently available data * while (null !== (chunk = readable.read())) { * console.log(`Read ${chunk.length} bytes of data...`); * } * }); * * // 'end' will be triggered once when there is no more data available * readable.on('end', () => { * console.log('Reached end of stream.'); * }); * ``` * * Each call to `readable.read()` returns a chunk of data, or `null`. The chunks * are not concatenated. A `while` loop is necessary to consume all data * currently in the buffer. When reading a large file `.read()` may return `null`, * having consumed all buffered content so far, but there is still more data to * come not yet buffered. In this case a new `'readable'` event will be emitted * when there is more data in the buffer. Finally the `'end'` event will be * emitted when there is no more data to come. * * Therefore to read a file's whole contents from a `readable`, it is necessary * to collect chunks across multiple `'readable'` events: * * ```js * const chunks = []; * * readable.on('readable', () => { * let chunk; * while (null !== (chunk = readable.read())) { * chunks.push(chunk); * } * }); * * readable.on('end', () => { * const content = chunks.join(''); * }); * ``` * * A `Readable` stream in object mode will always return a single item from * a call to `readable.read(size)`, regardless of the value of the`size` argument. * * If the `readable.read()` method returns a chunk of data, a `'data'` event will * also be emitted. * * Calling {@link read} after the `'end'` event has * been emitted will return `null`. No runtime error will be raised. * @since v0.9.4 * @param size Optional argument to specify how much data to read. */ read(size?: number): any; /** * The `readable.setEncoding()` method sets the character encoding for * data read from the `Readable` stream. * * By default, no encoding is assigned and stream data will be returned as`Buffer` objects. Setting an encoding causes the stream data * to be returned as strings of the specified encoding rather than as `Buffer`objects. For instance, calling `readable.setEncoding('utf8')` will cause the * output data to be interpreted as UTF-8 data, and passed as strings. Calling`readable.setEncoding('hex')` will cause the data to be encoded in hexadecimal * string format. * * The `Readable` stream will properly handle multi-byte characters delivered * through the stream that would otherwise become improperly decoded if simply * pulled from the stream as `Buffer` objects. * * ```js * const readable = getReadableStreamSomehow(); * readable.setEncoding('utf8'); * readable.on('data', (chunk) => { * assert.equal(typeof chunk, 'string'); * console.log('Got %d characters of string data:', chunk.length); * }); * ``` * @since v0.9.4 * @param encoding The encoding to use. */ setEncoding(encoding: BufferEncoding): this; /** * The `readable.pause()` method will cause a stream in flowing mode to stop * emitting `'data'` events, switching out of flowing mode. Any data that * becomes available will remain in the internal buffer. * * ```js * const readable = getReadableStreamSomehow(); * readable.on('data', (chunk) => { * console.log(`Received ${chunk.length} bytes of data.`); * readable.pause(); * console.log('There will be no additional data for 1 second.'); * setTimeout(() => { * console.log('Now data will start flowing again.'); * readable.resume(); * }, 1000); * }); * ``` * * The `readable.pause()` method has no effect if there is a `'readable'`event listener. * @since v0.9.4 */ pause(): this; /** * The `readable.resume()` method causes an explicitly paused `Readable` stream to * resume emitting `'data'` events, switching the stream into flowing mode. * * The `readable.resume()` method can be used to fully consume the data from a * stream without actually processing any of that data: * * ```js * getReadableStreamSomehow() * .resume() * .on('end', () => { * console.log('Reached the end, but did not read anything.'); * }); * ``` * * The `readable.resume()` method has no effect if there is a `'readable'`event listener. * @since v0.9.4 */ resume(): this; /** * The `readable.isPaused()` method returns the current operating state of the`Readable`. This is used primarily by the mechanism that underlies the`readable.pipe()` method. In most * typical cases, there will be no reason to * use this method directly. * * ```js * const readable = new stream.Readable(); * * readable.isPaused(); // === false * readable.pause(); * readable.isPaused(); // === true * readable.resume(); * readable.isPaused(); // === false * ``` * @since v0.11.14 */ isPaused(): boolean; /** * The `readable.unpipe()` method detaches a `Writable` stream previously attached * using the {@link pipe} method. * * If the `destination` is not specified, then _all_ pipes are detached. * * If the `destination` is specified, but no pipe is set up for it, then * the method does nothing. * * ```js * const fs = require('fs'); * const readable = getReadableStreamSomehow(); * const writable = fs.createWriteStream('file.txt'); * // All the data from readable goes into 'file.txt', * // but only for the first second. * readable.pipe(writable); * setTimeout(() => { * console.log('Stop writing to file.txt.'); * readable.unpipe(writable); * console.log('Manually close the file stream.'); * writable.end(); * }, 1000); * ``` * @since v0.9.4 * @param destination Optional specific stream to unpipe */ unpipe(destination?: WritableStream): this; /** * Passing `chunk` as `null` signals the end of the stream (EOF) and behaves the * same as `readable.push(null)`, after which no more data can be written. The EOF * signal is put at the end of the buffer and any buffered data will still be * flushed. * * The `readable.unshift()` method pushes a chunk of data back into the internal * buffer. This is useful in certain situations where a stream is being consumed by * code that needs to "un-consume" some amount of data that it has optimistically * pulled out of the source, so that the data can be passed on to some other party. * * The `stream.unshift(chunk)` method cannot be called after the `'end'` event * has been emitted or a runtime error will be thrown. * * Developers using `stream.unshift()` often should consider switching to * use of a `Transform` stream instead. See the `API for stream implementers` section for more information. * * ```js * // Pull off a header delimited by \n\n. * // Use unshift() if we get too much. * // Call the callback with (error, header, stream). * const { StringDecoder } = require('string_decoder'); * function parseHeader(stream, callback) { * stream.on('error', callback); * stream.on('readable', onReadable); * const decoder = new StringDecoder('utf8'); * let header = ''; * function onReadable() { * let chunk; * while (null !== (chunk = stream.read())) { * const str = decoder.write(chunk); * if (str.match(/\n\n/)) { * // Found the header boundary. * const split = str.split(/\n\n/); * header += split.shift(); * const remaining = split.join('\n\n'); * const buf = Buffer.from(remaining, 'utf8'); * stream.removeListener('error', callback); * // Remove the 'readable' listener before unshifting. * stream.removeListener('readable', onReadable); * if (buf.length) * stream.unshift(buf); * // Now the body of the message can be read from the stream. * callback(null, header, stream); * } else { * // Still reading the header. * header += str; * } * } * } * } * ``` * * Unlike {@link push}, `stream.unshift(chunk)` will not * end the reading process by resetting the internal reading state of the stream. * This can cause unexpected results if `readable.unshift()` is called during a * read (i.e. from within a {@link _read} implementation on a * custom stream). Following the call to `readable.unshift()` with an immediate {@link push} will reset the reading state appropriately, * however it is best to simply avoid calling `readable.unshift()` while in the * process of performing a read. * @since v0.9.11 * @param chunk Chunk of data to unshift onto the read queue. For streams not operating in object mode, `chunk` must be a string, `Buffer`, `Uint8Array` or `null`. For object mode * streams, `chunk` may be any JavaScript value. * @param encoding Encoding of string chunks. Must be a valid `Buffer` encoding, such as `'utf8'` or `'ascii'`. */ unshift(chunk: any, encoding?: BufferEncoding): void; /** * Prior to Node.js 0.10, streams did not implement the entire `stream` module API * as it is currently defined. (See `Compatibility` for more information.) * * When using an older Node.js library that emits `'data'` events and has a {@link pause} method that is advisory only, the`readable.wrap()` method can be used to create a `Readable` * stream that uses * the old stream as its data source. * * It will rarely be necessary to use `readable.wrap()` but the method has been * provided as a convenience for interacting with older Node.js applications and * libraries. * * ```js * const { OldReader } = require('./old-api-module.js'); * const { Readable } = require('stream'); * const oreader = new OldReader(); * const myReader = new Readable().wrap(oreader); * * myReader.on('readable', () => { * myReader.read(); // etc. * }); * ``` * @since v0.9.4 * @param stream An "old style" readable stream */ wrap(stream: ReadableStream): this; push(chunk: any, encoding?: BufferEncoding): boolean; _destroy( error: Error | null, callback: (error?: Error | null) => void, ): void; /** * Destroy the stream. Optionally emit an `'error'` event, and emit a `'close'`event (unless `emitClose` is set to `false`). After this call, the readable * stream will release any internal resources and subsequent calls to `push()`will be ignored. * * Once `destroy()` has been called any further calls will be a no-op and no * further errors except from `_destroy()` may be emitted as `'error'`. * * Implementors should not override this method, but instead implement `readable._destroy()`. * @since v8.0.0 * @param error Error which will be passed as payload in `'error'` event */ destroy(error?: Error): void; /** * Event emitter * The defined events on documents including: * 1. close * 2. data * 3. end * 4. error * 5. pause * 6. readable * 7. resume */ addListener(event: "close", listener: () => void): this; addListener(event: "data", listener: (chunk: any) => void): this; addListener(event: "end", listener: () => void): this; addListener(event: "error", listener: (err: Error) => void): this; addListener(event: "pause", listener: () => void): this; addListener(event: "readable", listener: () => void): this; addListener(event: "resume", listener: () => void): this; addListener( event: string | symbol, listener: (...args: any[]) => void, ): this; emit(event: "close"): boolean; emit(event: "data", chunk: any): boolean; emit(event: "end"): boolean; emit(event: "error", err: Error): boolean; emit(event: "pause"): boolean; emit(event: "readable"): boolean; emit(event: "resume"): boolean; emit(event: string | symbol, ...args: any[]): boolean; on(event: "close", listener: () => void): this; on(event: "data", listener: (chunk: any) => void): this; on(event: "end", listener: () => void): this; on(event: "error", listener: (err: Error) => void): this; on(event: "pause", listener: () => void): this; on(event: "readable", listener: () => void): this; on(event: "resume", listener: () => void): this; on(event: string | symbol, listener: (...args: any[]) => void): this; once(event: "close", listener: () => void): this; once(event: "data", listener: (chunk: any) => void): this; once(event: "end", listener: () => void): this; once(event: "error", listener: (err: Error) => void): this; once(event: "pause", listener: () => void): this; once(event: "readable", listener: () => void): this; once(event: "resume", listener: () => void): this; once(event: string | symbol, listener: (...args: any[]) => void): this; prependListener(event: "close", listener: () => void): this; prependListener(event: "data", listener: (chunk: any) => void): this; prependListener(event: "end", listener: () => void): this; prependListener(event: "error", listener: (err: Error) => void): this; prependListener(event: "pause", listener: () => void): this; prependListener(event: "readable", listener: () => void): this; prependListener(event: "resume", listener: () => void): this; prependListener( event: string | symbol, listener: (...args: any[]) => void, ): this; prependOnceListener(event: "close", listener: () => void): this; prependOnceListener(event: "data", listener: (chunk: any) => void): this; prependOnceListener(event: "end", listener: () => void): this; prependOnceListener(event: "error", listener: (err: Error) => void): this; prependOnceListener(event: "pause", listener: () => void): this; prependOnceListener(event: "readable", listener: () => void): this; prependOnceListener(event: "resume", listener: () => void): this; prependOnceListener( event: string | symbol, listener: (...args: any[]) => void, ): this; removeListener(event: "close", listener: () => void): this; removeListener(event: "data", listener: (chunk: any) => void): this; removeListener(event: "end", listener: () => void): this; removeListener(event: "error", listener: (err: Error) => void): this; removeListener(event: "pause", listener: () => void): this; removeListener(event: "readable", listener: () => void): this; removeListener(event: "resume", listener: () => void): this; removeListener( event: string | symbol, listener: (...args: any[]) => void, ): this; [Symbol.asyncIterator](): AsyncIterableIterator<any>; } export interface WritableOptions extends StreamOptions<Writable> { decodeStrings?: boolean | undefined; defaultEncoding?: BufferEncoding | undefined; write?( this: Writable, chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void, ): void; writev?( this: Writable, chunks: Array<{ chunk: any; encoding: BufferEncoding; }>, callback: (error?: Error | null) => void, ): void; final?(this: Writable, callback: (error?: Error | null) => void): void; } /** * @since v0.9.4 */ export class Writable extends Stream implements WritableStream { /** * A utility method for creating `Writable` from a `WritableStream`. * @since v17.0.0 * @experimental */ static fromWeb( writableStream: globalThis.WritableStream, options?: Pick< WritableOptions, "decodeStrings" | "highWaterMark" | "objectMode" | "signal" >, ): Writable; /** * Is `true` if it is safe to call `writable.write()`, which means * the stream has not been destroyed, errored or ended. * @since v11.4.0 */ readonly writable: boolean; readonly writableBuffer?: Buffered[]; /** * Is `true` after `writable.end()` has been called. This property * does not indicate whether the data has been flushed, for this use `writable.writableFinished` instead. * @since v12.9.0 */ readonly writableEnded: boolean; /** * Is set to `true` immediately before the `'finish'` event is emitted. * @since v12.6.0 */ readonly writableFinished: boolean; /** * Return the value of `highWaterMark` passed when creating this `Writable`. * @since v9.3.0 */ readonly writableHighWaterMark: number; /** * This property contains the number of bytes (or objects) in the queue * ready to be written. The value provides introspection data regarding * the status of the `highWaterMark`. * @since v9.4.0 */ readonly writableLength: number; /** * Getter for the property `objectMode` of a given `Writable` stream. * @since v12.3.0 */ readonly writableObjectMode: boolean; /** * Number of times `writable.uncork()` needs to be * called in order to fully uncork the stream. * @since v13.2.0, v12.16.0 */ readonly writableCorked: number; /** * Is `true` after `writable.destroy()` has been called. * @since v8.0.0 */ destroyed: boolean; /** * Is true after 'close' has been emitted. * @since v8.0.0 */ readonly closed: boolean; constructor(opts?: WritableOptions); _write( chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void, ): void; _writev?( chunks: Array<{ chunk: any; encoding: BufferEncoding; }>, callback: (error?: Error | null) => void, ): void; _construct?(callback: (error?: Error | null) => void): void; _destroy( error: Error | null, callback: (error?: Error | null) => void, ): void; _final(callback: (error?: Error | null) => void): void; /** * The `writable.write()` method writes some data to the stream, and calls the * supplied `callback` once the data has been fully handled. If an error * occurs, the `callback` will be called with the error as its * first argument. The `callback` is called asynchronously and before `'error'` is * emitted. * * The return value is `true` if the internal buffer is less than the`highWaterMark` configured when the stream was created after admitting `chunk`. * If `false` is returned, further attempts to write data to the stream should * stop until the `'drain'` event is emitted. * * While a stream is not draining, calls to `write()` will buffer `chunk`, and * return false. Once all currently buffered chunks are drained (accepted for * delivery by the operating system), the `'drain'` event will be emitted. * It is recommended that once `write()` returns false, no more chunks be written * until the `'drain'` event is emitted. While calling `write()` on a stream that * is not draining is allowed, Node.js will buffer all written chunks until * maximum memory usage occurs, at which point it will abort unconditionally. * Even before it aborts, high memory usage will cause poor garbage collector * performance and high RSS (which is not typically released back to the system, * even after the memory is no longer required). Since TCP sockets may never * drain if the remote peer does not read the data, writing a socket that is * not draining may lead to a remotely exploitable vulnerability. * * Writing data while the stream is not draining is particularly * problematic for a `Transform`, because the `Transform` streams are paused * by default until they are piped or a `'data'` or `'readable'` event handler * is added. * * If the data to be written can be generated or fetched on demand, it is * recommended to encapsulate the logic into a `Readable` and use {@link pipe}. However, if calling `write()` is preferred, it is * possible to respect backpressure and avoid memory issues using the `'drain'` event: * * ```js * function write(data, cb) { * if (!stream.write(data)) { * stream.once('drain', cb); * } else { * process.nextTick(cb); * } * } * * // Wait for cb to be called before doing any other write. * write('hello', () => { * console.log('Write completed, do more writes now.'); * }); * ``` * * A `Writable` stream in object mode will always ignore the `encoding` argument. * @since v0.9.4 * @param chunk Optional data to write. For streams not operating in object mode, `chunk` must be a string, `Buffer` or `Uint8Array`. For object mode streams, `chunk` may be any * JavaScript value other than `null`. * @param [encoding='utf8'] The encoding, if `chunk` is a string. * @param callback Callback for when this chunk of data is flushed. * @return `false` if the stream wishes for the calling code to wait for the `'drain'` event to be emitted before continuing to write additional data; otherwise `true`. */ write( chunk: any, callback?: (error: Error | null | undefined) => void, ): boolean; write( chunk: any, encoding: BufferEncoding, callback?: (error: Error | null | undefined) => void, ): boolean; /** * The `writable.setDefaultEncoding()` method sets the default `encoding` for a `Writable` stream. * @since v0.11.15 * @param encoding The new default encoding */ setDefaultEncoding(encoding: BufferEncoding): this; /** * Calling the `writable.end()` method signals that no more data will be written * to the `Writable`. The optional `chunk` and `encoding` arguments allow one * final additional chunk of data to be written immediately before closing the * stream. * * Calling the {@link write} method after calling {@link end} will raise an error. * * ```js * // Write 'hello, ' and then end with 'world!'. * const fs = require('fs'); * const file = fs.createWriteStream('example.txt'); * file.write('hello, '); * file.end('world!'); * // Writing more now is not allowed! * ``` * @since v0.9.4 * @param chunk Optional data to write. For streams not operating in object mode, `chunk` must be a string, `Buffer` or `Uint8Array`. For object mode streams, `chunk` may be any * JavaScript value other than `null`. * @param encoding The encoding if `chunk` is a string * @param callback Callback for when the stream is finished. */ end(cb?: () => void): void; end(chunk: any, cb?: () => void): void; end(chunk: any, encoding: BufferEncoding, cb?: () => void): void; /** * The `writable.cork()` method forces all written data to be buffered in memory. * The buffered data will be flushed when either the {@link uncork} or {@link end} methods are called. * * The primary intent of `writable.cork()` is to accommodate a situation in which * several small chunks are written to the stream in rapid succession. Instead of * immediately forwarding them to the underlying destination, `writable.cork()`buffers all the chunks until `writable.uncork()` is called, which will pass them * all to `writable._writev()`, if present. This prevents a head-of-line blocking * situation where data is being buffered while waiting for the first small chunk * to be processed. However, use of `writable.cork()` without implementing`writable._writev()` may have an adverse effect on throughput. * * See also: `writable.uncork()`, `writable._writev()`. * @since v0.11.2 */ cork(): void; /** * The `writable.uncork()` method flushes all data buffered since {@link cork} was called. * * When using `writable.cork()` and `writable.uncork()` to manage the buffering * of writes to a stream, it is recommended that calls to `writable.uncork()` be * deferred using `process.nextTick()`. Doing so allows batching of all`writable.write()` calls that occur within a given Node.js event loop phase. * * ```js * stream.cork(); * stream.write('some '); * stream.write('data '); * process.nextTick(() => stream.uncork()); * ``` * * If the `writable.cork()` method is called multiple times on a stream, the * same number of calls to `writable.uncork()` must be called to flush the buffered * data. * * ```js * stream.cork(); * stream.write('some '); * stream.cork(); * stream.write('data '); * process.nextTick(() => { * stream.uncork(); * // The data will not be flushed until uncork() is called a second time. * stream.uncork(); * }); * ``` * * See also: `writable.cork()`. * @since v0.11.2 */ uncork(): void; /** * Destroy the stream. Optionally emit an `'error'` event, and emit a `'close'`event (unless `emitClose` is set to `false`). After this call, the writable * stream has ended and subsequent calls to `write()` or `end()` will result in * an `ERR_STREAM_DESTROYED` error. * This is a destructive and immediate way to destroy a stream. Previous calls to`write()` may not have drained, and may trigger an `ERR_STREAM_DESTROYED` error. * Use `end()` instead of destroy if data should flush before close, or wait for * the `'drain'` event before destroying the stream. * * Once `destroy()` has been called any further calls will be a no-op and no * further errors except from `_destroy()` may be emitted as `'error'`. * * Implementors should not override this method, * but instead implement `writable._destroy()`. * @since v8.0.0 * @param error Optional, an error to emit with `'error'` event. */ destroy(error?: Error): void; /** * Event emitter * The defined events on documents including: * 1. close * 2. drain * 3. error * 4. finish * 5. pipe * 6. unpipe */ addListener(event: "close", listener: () => void): this; addListener(event: "drain", listener: () => void): this; addListener(event: "error", listener: (err: Error) => void): this; addListener(event: "finish", listener: () => void): this; addListener(event: "pipe", listener: (src: Readable) => void): this; addListener(event: "unpipe", listener: (src: Readable) => void): this; addListener( event: string | symbol, listener: (...args: any[]) => void, ): this; emit(event: "close"): boolean; emit(event: "drain"): boolean; emit(event: "error", err: Error): boolean; emit(event: "finish"): boolean; emit(event: "pipe", src: Readable): boolean; emit(event: "unpipe", src: Readable): boolean; emit(event: string | symbol, ...args: any[]): boolean; on(event: "close", listener: () => void): this; on(event: "drain", listener: () => void): this; on(event: "error", listener: (err: Error) => void): this; on(event: "finish", listener: () => void): this; on(event: "pipe", listener: (src: Readable) => void): this; on(event: "unpipe", listener: (src: Readable) => void): this; on(event: string | symbol, listener: (...args: any[]) => void): this; once(event: "close", listener: () => void): this; once(event: "drain", listener: () => void): this; once(event: "error", listener: (err: Error) => void): this; once(event: "finish", listener: () => void): this; once(event: "pipe", listener: (src: Readable) => void): this; once(event: "unpipe", listener: (src: Readable) => void): this; once(event: string | symbol, listener: (...args: any[]) => void): this; prependListener(event: "close", listener: () => void): this; prependListener(event: "drain", listener: () => void): this; prependListener(event: "error", listener: (err: Error) => void): this; prependListener(event: "finish", listener: () => void): this; prependListener(event: "pipe", listener: (src: Readable) => void): this; prependListener(event: "unpipe", listener: (src: Readable) => void): this; prependListener( event: string | symbol, listener: (...args: any[]) => void, ): this; prependOnceListener(event: "close", listener: () => void): this; prependOnceListener(event: "drain", listener: () => void): this; prependOnceListener(event: "error", listener: (err: Error) => void): this; prependOnceListener(event: "finish", listener: () => void): this; prependOnceListener(event: "pipe", listener: (src: Readable) => void): this; prependOnceListener( event: "unpipe", listener: (src: Readable) => void, ): this; prependOnceListener( event: string | symbol, listener: (...args: any[]) => void, ): this; removeListener(event: "close", listener: () => void): this; removeListener(event: "drain", listener: () => void): this; removeListener(event: "error", listener: (err: Error) => void): this; removeListener(event: "finish", listener: () => void): this; removeListener(event: "pipe", listener: (src: Readable) => void): this; removeListener(event: "unpipe", listener: (src: Readable) => void): this; removeListener( event: string | symbol, listener: (...args: any[]) => void, ): this; } export interface DuplexOptions extends ReadableOptions, WritableOptions { allowHalfOpen?: boolean | undefined; readableObjectMode?: boolean | undefined; writableObjectMode?: boolean | undefined; readableHighWaterMark?: number | undefined; writableHighWaterMark?: number | undefined; writableCorked?: number | undefined; construct?(this: Duplex, callback: (error?: Error | null) => void): void; read?(this: Duplex, size: number): void; write?( this: Duplex, chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void, ): void; writev?( this: Duplex, chunks: Array<{ chunk: any; encoding: BufferEncoding; }>, callback: (error?: Error | null) => void, ): void; final?(this: Duplex, callback: (error?: Error | null) => void): void; destroy?( this: Duplex, error: Error | null, callback: (error: Error | null) => void, ): void; } /** * Duplex streams are streams that implement both the `Readable` and `Writable` interfaces. * * Examples of `Duplex` streams include: * * * `TCP sockets` * * `zlib streams` * * `crypto streams` * @since v0.9.4 */ export class Duplex extends Readable implements Writable { readonly writable: boolean; readonly writableBuffer?: Buffered[]; readonly writableEnded: boolean; readonly writableFinished: boolean; readonly writableHighWaterMark: number; readonly writableLength: number; readonly writableObjectMode: boolean; readonly writableCorked: number; readonly closed: boolean; /** * If `false` then the stream will automatically end the writable side when the * readable side ends. Set initially by the `allowHalfOpen` constructor option, * which defaults to `false`. * * This can be changed manually to change the half-open behavior of an existing`Duplex` stream instance, but must be changed before the `'end'` event is * emitted. * @since v0.9.4 */ allowHalfOpen: boolean; constructor(opts?: DuplexOptions); /** * A utility method for creating duplex streams. * * - `Stream` converts writable stream into writable `Duplex` and readable stream * to `Duplex`. * - `Blob` converts into readable `Duplex`. * - `string` converts into readable `Duplex`. * - `ArrayBuffer` converts into readable `Duplex`. * - `AsyncIterable` converts into a readable `Duplex`. Cannot yield `null`. * - `AsyncGeneratorFunction` converts into a readable/writable transform * `Duplex`. Must take a source `AsyncIterable` as first parameter. Cannot yield * `null`. * - `AsyncFunction` converts into a writable `Duplex`. Must return * either `null` or `undefined` * - `Object ({ writable, readable })` converts `readable` and * `writable` into `Stream` and then combines them into `Duplex` where the * `Duplex` will write to the `writable` and read from the `readable`. * - `Promise` converts into readable `Duplex`. Value `null` is ignored. * * @since v16.8.0 */ static from( src: | Stream | Blob | ArrayBuffer | string | Iterable<any> | AsyncIterable<any> | AsyncGeneratorFunction | Promise<any> // deno-lint-ignore ban-types | Object, ): Duplex; _write( chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void, ): void; _writev?( chunks: Array<{ chunk: any; encoding: BufferEncoding; }>, callback: (error?: Error | null) => void, ): void; _destroy( error: Error | null, callback: (error: Error | null) => void, ): void; _final(callback: (error?: Error | null) => void): void; write( chunk: any, encoding?: BufferEncoding, cb?: (error: Error | null | undefined) => void, ): boolean; write(chunk: any, cb?: (error: Error | null | undefined) => void): boolean; setDefaultEncoding(encoding: BufferEncoding): this; end(cb?: () => void): void; end(chunk: any, cb?: () => void): void; end(chunk: any, encoding?: BufferEncoding, cb?: () => void): void; cork(): void; uncork(): void; } type TransformCallback = (error?: Error | null, data?: any) => void; export interface TransformOptions extends DuplexOptions { construct?(this: Transform, callback: (error?: Error | null) => void): void; read?(this: Transform, size: number): void; write?( this: Transform, chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void, ): void; writev?( this: Transform, chunks: Array<{ chunk: any; encoding: BufferEncoding; }>, callback: (error?: Error | null) => void, ): void; final?(this: Transform, callback: (error?: Error | null) => void): void; destroy?( this: Transform, error: Error | null, callback: (error: Error | null) => void, ): void; transform?( this: Transform, chunk: any, encoding: BufferEncoding, callback: TransformCallback, ): void; flush?(this: Transform, callback: TransformCallback): void; } /** * Transform streams are `Duplex` streams where the output is in some way * related to the input. Like all `Duplex` streams, `Transform` streams * implement both the `Readable` and `Writable` interfaces. * * Examples of `Transform` streams include: * * * `zlib streams` * * `crypto streams` * @since v0.9.4 */ export class Transform extends Duplex { constructor(opts?: TransformOptions); _transform( chunk: any, encoding: BufferEncoding, callback: TransformCallback, ): void; _flush(callback: TransformCallback): void; } /** * The `stream.PassThrough` class is a trivial implementation of a `Transform` stream that simply passes the input bytes across to the output. Its purpose is * primarily for examples and testing, but there are some use cases where `stream.PassThrough` is useful as a building block for novel sorts of streams. */ export class PassThrough extends Transform {} /** * Attaches an AbortSignal to a readable or writeable stream. This lets code * control stream destruction using an `AbortController`. * * Calling `abort` on the `AbortController` corresponding to the passed`AbortSignal` will behave the same way as calling `.destroy(new AbortError())`on the stream. * * ```js * const fs = require('fs'); * * const controller = new AbortController(); * const read = addAbortSignal( * controller.signal, * fs.createReadStream(('object.json')) * ); * // Later, abort the operation closing the stream * controller.abort(); * ``` * * Or using an `AbortSignal` with a readable stream as an async iterable: * * ```js * const controller = new AbortController(); * setTimeout(() => controller.abort(), 10_000); // set a timeout * const stream = addAbortSignal( * controller.signal, * fs.createReadStream(('object.json')) * ); * (async () => { * try { * for await (const chunk of stream) { * await process(chunk); * } * } catch (e) { * if (e.name === 'AbortError') { * // The operation was cancelled * } else { * throw e; * } * } * })(); * ``` * @since v15.4.0 * @param signal A signal representing possible cancellation * @param stream a stream to attach a signal to */ export function addAbortSignal<T extends Stream>( signal: AbortSignal, stream: T, ): T; interface FinishedOptions extends Abortable { error?: boolean | undefined; readable?: boolean | undefined; writable?: boolean | undefined; } /** * A function to get notified when a stream is no longer readable, writable * or has experienced an error or a premature close event. * * ```js * const { finished } = require('stream'); * * const rs = fs.createReadStream('archive.tar'); * * finished(rs, (err) => { * if (err) { * console.error('Stream failed.', err); * } else { * console.log('Stream is done reading.'); * } * }); * * rs.resume(); // Drain the stream. * ``` * * Especially useful in error handling scenarios where a stream is destroyed * prematurely (like an aborted HTTP request), and will not emit `'end'`or `'finish'`. * * The `finished` API provides promise version: * * ```js * const { finished } = require('stream/promises'); * * const rs = fs.createReadStream('archive.tar'); * * async function run() { * await finished(rs); * console.log('Stream is done reading.'); * } * * run().catch(console.error); * rs.resume(); // Drain the stream. * ``` * * `stream.finished()` leaves dangling event listeners (in particular`'error'`, `'end'`, `'finish'` and `'close'`) after `callback` has been * invoked. The reason for this is so that unexpected `'error'` events (due to * incorrect stream implementations) do not cause unexpected crashes. * If this is unwanted behavior then the returned cleanup function needs to be * invoked in the callback: * * ```js * const cleanup = finished(rs, (err) => { * cleanup(); * // ... * }); * ``` * @since v10.0.0 * @param stream A readable and/or writable stream. * @param callback A callback function that takes an optional error argument. * @return A cleanup function which removes all registered listeners. */ export function finished( stream: | ReadableStream | WritableStream | ReadWriteStream, options: FinishedOptions, callback: (err?: ErrnoException | null) => void, ): () => void; export function finished( stream: | ReadableStream | WritableStream | ReadWriteStream, callback: (err?: ErrnoException | null) => void, ): () => void; export namespace finished { function __promisify__( stream: | ReadableStream | WritableStream | ReadWriteStream, options?: FinishedOptions, ): Promise<void>; } type PipelineSourceFunction<T> = () => Iterable<T> | AsyncIterable<T>; type PipelineSource<T> = | Iterable<T> | AsyncIterable<T> | ReadableStream | PipelineSourceFunction<T>; type PipelineTransform<S extends PipelineTransformSource<any>, U> = | ReadWriteStream | (( source: S extends (...args: any[]) => Iterable<infer ST> | AsyncIterable<infer ST> ? AsyncIterable<ST> : S, ) => AsyncIterable<U>); type PipelineTransformSource<T> = | PipelineSource<T> | PipelineTransform<any, T>; type PipelineDestinationIterableFunction<T> = ( source: AsyncIterable<T>, ) => AsyncIterable<any>; type PipelineDestinationPromiseFunction<T, P> = ( source: AsyncIterable<T>, ) => Promise<P>; type PipelineDestination<S extends PipelineTransformSource<any>, P> = S extends PipelineTransformSource<infer ST> ? | WritableStream | PipelineDestinationIterableFunction<ST> | PipelineDestinationPromiseFunction<ST, P> : never; type PipelineCallback<S extends PipelineDestination<any, any>> = S extends PipelineDestinationPromiseFunction<any, infer P> ? (err: ErrnoException | null, value: P) => void : (err: ErrnoException | null) => void; type PipelinePromise<S extends PipelineDestination<any, any>> = S extends PipelineDestinationPromiseFunction<any, infer P> ? Promise<P> : Promise<void>; interface PipelineOptions { signal: AbortSignal; } /** * A module method to pipe between streams and generators forwarding errors and * properly cleaning up and provide a callback when the pipeline is complete. * * ```js * const { pipeline } = require('stream'); * const fs = require('fs'); * const zlib = require('zlib'); * * // Use the pipeline API to easily pipe a series of streams * // together and get notified when the pipeline is fully done. * * // A pipeline to gzip a potentially huge tar file efficiently: * * pipeline( * fs.createReadStream('archive.tar'), * zlib.createGzip(), * fs.createWriteStream('archive.tar.gz'), * (err) => { * if (err) { * console.error('Pipeline failed.', err); * } else { * console.log('Pipeline succeeded.'); * } * } * ); * ``` * * The `pipeline` API provides a promise version, which can also * receive an options argument as the last parameter with a`signal` `AbortSignal` property. When the signal is aborted,`destroy` will be called on the underlying pipeline, with * an`AbortError`. * * ```js * const { pipeline } = require('stream/promises'); * * async function run() { * await pipeline( * fs.createReadStream('archive.tar'), * zlib.createGzip(), * fs.createWriteStream('archive.tar.gz') * ); * console.log('Pipeline succeeded.'); * } * * run().catch(console.error); * ``` * * To use an `AbortSignal`, pass it inside an options object, * as the last argument: * * ```js * const { pipeline } = require('stream/promises'); * * async function run() { * const ac = new AbortController(); * const signal = ac.signal; * * setTimeout(() => ac.abort(), 1); * await pipeline( * fs.createReadStream('archive.tar'), * zlib.createGzip(), * fs.createWriteStream('archive.tar.gz'), * { signal }, * ); * } * * run().catch(console.error); // AbortError * ``` * * The `pipeline` API also supports async generators: * * ```js * const { pipeline } = require('stream/promises'); * const fs = require('fs'); * * async function run() { * await pipeline( * fs.createReadStream('lowercase.txt'), * async function* (source, signal) { * source.setEncoding('utf8'); // Work with strings rather than `Buffer`s. * for await (const chunk of source) { * yield await processChunk(chunk, { signal }); * } * }, * fs.createWriteStream('uppercase.txt') * ); * console.log('Pipeline succeeded.'); * } * * run().catch(console.error); * ``` * * Remember to handle the `signal` argument passed into the async generator. * Especially in the case where the async generator is the source for the * pipeline (i.e. first argument) or the pipeline will never complete. * * ```js * const { pipeline } = require('stream/promises'); * const fs = require('fs'); * * async function run() { * await pipeline( * async function * (signal) { * await someLongRunningfn({ signal }); * yield 'asd'; * }, * fs.createWriteStream('uppercase.txt') * ); * console.log('Pipeline succeeded.'); * } * * run().catch(console.error); * ``` * * `stream.pipeline()` will call `stream.destroy(err)` on all streams except: * * * `Readable` streams which have emitted `'end'` or `'close'`. * * `Writable` streams which have emitted `'finish'` or `'close'`. * * `stream.pipeline()` leaves dangling event listeners on the streams * after the `callback` has been invoked. In the case of reuse of streams after * failure, this can cause event listener leaks and swallowed errors. * @since v10.0.0 * @param callback Called when the pipeline is fully done. */ export function pipeline< A extends PipelineSource<any>, B extends PipelineDestination<A, any>, >( source: A, destination: B, callback?: PipelineCallback<B>, ): B extends WritableStream ? B : WritableStream; export function pipeline< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, B extends PipelineDestination<T1, any>, >( source: A, transform1: T1, destination: B, callback?: PipelineCallback<B>, ): B extends WritableStream ? B : WritableStream; export function pipeline< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, T2 extends PipelineTransform<T1, any>, B extends PipelineDestination<T2, any>, >( source: A, transform1: T1, transform2: T2, destination: B, callback?: PipelineCallback<B>, ): B extends WritableStream ? B : WritableStream; export function pipeline< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, T2 extends PipelineTransform<T1, any>, T3 extends PipelineTransform<T2, any>, B extends PipelineDestination<T3, any>, >( source: A, transform1: T1, transform2: T2, transform3: T3, destination: B, callback?: PipelineCallback<B>, ): B extends WritableStream ? B : WritableStream; export function pipeline< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, T2 extends PipelineTransform<T1, any>, T3 extends PipelineTransform<T2, any>, T4 extends PipelineTransform<T3, any>, B extends PipelineDestination<T4, any>, >( source: A, transform1: T1, transform2: T2, transform3: T3, transform4: T4, destination: B, callback?: PipelineCallback<B>, ): B extends WritableStream ? B : WritableStream; export function pipeline( streams: ReadonlyArray< ReadableStream | WritableStream | ReadWriteStream >, callback?: (err: ErrnoException | null) => void, ): WritableStream; export function pipeline( stream1: ReadableStream, stream2: ReadWriteStream | WritableStream, ...streams: Array< | ReadWriteStream | WritableStream | ((err: ErrnoException | null) => void) > ): WritableStream; export namespace pipeline { function __promisify__< A extends PipelineSource<any>, B extends PipelineDestination<A, any>, >(source: A, destination: B, options?: PipelineOptions): PipelinePromise<B>; function __promisify__< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, B extends PipelineDestination<T1, any>, >( source: A, transform1: T1, destination: B, options?: PipelineOptions, ): PipelinePromise<B>; function __promisify__< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, T2 extends PipelineTransform<T1, any>, B extends PipelineDestination<T2, any>, >( source: A, transform1: T1, transform2: T2, destination: B, options?: PipelineOptions, ): PipelinePromise<B>; function __promisify__< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, T2 extends PipelineTransform<T1, any>, T3 extends PipelineTransform<T2, any>, B extends PipelineDestination<T3, any>, >( source: A, transform1: T1, transform2: T2, transform3: T3, destination: B, options?: PipelineOptions, ): PipelinePromise<B>; function __promisify__< A extends PipelineSource<any>, T1 extends PipelineTransform<A, any>, T2 extends PipelineTransform<T1, any>, T3 extends PipelineTransform<T2, any>, T4 extends PipelineTransform<T3, any>, B extends PipelineDestination<T4, any>, >( source: A, transform1: T1, transform2: T2, transform3: T3, transform4: T4, destination: B, options?: PipelineOptions, ): PipelinePromise<B>; function __promisify__( streams: ReadonlyArray< ReadableStream | WritableStream | ReadWriteStream >, options?: PipelineOptions, ): Promise<void>; function __promisify__( stream1: ReadableStream, stream2: ReadWriteStream | WritableStream, ...streams: Array< ReadWriteStream | WritableStream | PipelineOptions > ): Promise<void>; } interface Pipe { close(): void; hasRef(): boolean; ref(): void; unref(): void; } // These have to be at the bottom of the file to work correctly, for some reason export function _uint8ArrayToBuffer(chunk: Uint8Array): Buffer; export function _isUint8Array(value: unknown): value is Uint8Array;