or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-mimic-response

Mimic a Node.js HTTP response stream by copying properties and event handlers between streams

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/mimic-response@4.0.x

To install, run

npx @tessl/cli install tessl/npm-mimic-response@4.0.0

index.mddocs/

Mimic Response

Mimic Response is a Node.js utility that copies HTTP response properties and event handlers from one stream to another, enabling the creation of proxy streams that behave like the original HTTP response stream. It preserves all HTTP-related properties (statusCode, headers, httpVersion, etc.) and forwards abort and close events appropriately.

Package Information

  • Package Name: mimic-response
  • Package Type: npm
  • Language: JavaScript (ES Module)
  • Installation: npm install mimic-response

Core Imports

import mimicResponse from "mimic-response";

For CommonJS:

const mimicResponse = require("mimic-response");

For TypeScript:

import mimicResponse from "mimic-response";
import type { IncomingMessage } from "node:http";

Basic Usage

import { PassThrough as PassThroughStream } from "node:stream";
import mimicResponse from "mimic-response";

// Get an HTTP response stream from a request
const responseStream = getHttpResponseStream();

// Create a new stream that will mimic the response
const myStream = new PassThroughStream({ autoDestroy: false });

// Copy all HTTP properties and event handlers
mimicResponse(responseStream, myStream);

// Now myStream has all the HTTP response properties
console.log(myStream.statusCode); // 200
console.log(myStream.headers);    // Response headers object
console.log(myStream.complete);   // Boolean indicating response completion

Capabilities

Stream Mimicking

Copies all HTTP response properties from a source stream to a target stream, making the target stream behave like an HTTP response.

/**
 * Mimic a Node.js HTTP response stream by copying properties and event handlers
 * @param fromStream - The HTTP response stream to copy properties from
 * @param toStream - The target stream to copy properties to (must have autoDestroy: false)
 * @returns The enhanced toStream with HTTP response properties
 * @throws Error if toStream has autoDestroy: true
 */
function mimicResponse<T extends NodeJS.ReadableStream>(
  fromStream: IncomingMessage,
  toStream: T
): T & IncomingMessage;

Parameters:

  • fromStream (IncomingMessage): The source HTTP response stream containing properties to copy
  • toStream (NodeJS.ReadableStream): The target stream that will receive the copied properties. Must have autoDestroy: false

Returns: The toStream parameter enhanced with all HTTP response properties from fromStream

Throws: Error with message "The second stream must have the autoDestroy option set to false" if toStream._readableState.autoDestroy is true

Copied Properties: The function copies all enumerable properties from the source stream plus these known HTTP response properties:

const knownProperties = [
  'aborted',           // Boolean indicating if request was aborted
  'complete',          // Boolean indicating if response is complete  
  'headers',           // Response headers object
  'httpVersion',       // HTTP version string (e.g., "1.1")
  'httpVersionMinor',  // HTTP version minor number
  'httpVersionMajor',  // HTTP version major number
  'method',            // HTTP method string
  'rawHeaders',        // Raw headers array
  'rawTrailers',       // Raw trailers array
  'setTimeout',        // Timeout method function
  'socket',            // Underlying socket object
  'statusCode',        // HTTP status code number
  'statusMessage',     // HTTP status message string  
  'trailers',          // Response trailers object
  'url'                // Request URL string
];

Event Forwarding:

  • aborted: When source stream emits 'aborted', destroys target stream and re-emits 'aborted'
  • close: When source stream emits 'close', re-emits 'close' on target stream with proper timing based on response completion

Usage Examples:

Basic stream proxy:

import { PassThrough as PassThroughStream } from "node:stream";
import mimicResponse from "mimic-response";

const responseStream = getHttpResponseStream();
const proxyStream = new PassThroughStream({ autoDestroy: false });

mimicResponse(responseStream, proxyStream);

// Access HTTP properties on the proxy stream
console.log(proxyStream.statusCode);  // Same as responseStream.statusCode
console.log(proxyStream.headers);     // Same as responseStream.headers

Custom stream with manual destroy handling:

import { PassThrough as PassThroughStream } from "node:stream";
import mimicResponse from "mimic-response";

const responseStream = getHttpResponseStream();

const myStream = new PassThroughStream({
  autoDestroy: false,
  destroy(error, callback) {
    // Manually destroy the source stream
    responseStream.destroy();
    callback(error);
  }
});

mimicResponse(responseStream, myStream);

// The streams are now linked for destruction
myStream.destroy();

Stream transformation pipeline:

import { Transform } from "node:stream";
import mimicResponse from "mimic-response";

const responseStream = getHttpResponseStream();

const transformStream = new Transform({
  autoDestroy: false,
  transform(chunk, encoding, callback) {
    // Transform the data while preserving HTTP properties
    const transformed = chunk.toString().toUpperCase();
    callback(null, transformed);
  }
});

mimicResponse(responseStream, transformStream);

// Transform stream now has HTTP properties and transforms data
responseStream.pipe(transformStream);

Types

interface IncomingMessage extends NodeJS.ReadableStream {
  aborted: boolean;
  complete: boolean;
  headers: { [key: string]: string | string[] | undefined };
  httpVersion: string;
  httpVersionMajor: number;
  httpVersionMinor: number;
  method?: string;
  rawHeaders: string[];
  rawTrailers: string[];
  setTimeout(msecs: number, callback?: () => void): this;
  socket: any;
  statusCode?: number;
  statusMessage?: string;
  trailers: { [key: string]: string | undefined };
  url?: string;
}

Error Handling

The function validates that the target stream is properly configured:

  • Validation Error: Throws an Error if toStream._readableState.autoDestroy is true
  • Error Message: "The second stream must have the autoDestroy option set to false"

This validation ensures that the target stream won't be automatically destroyed, which is necessary for proper event forwarding and property access.

Important Notes

  1. AutoDestroy Requirement: The target stream must have autoDestroy: false to prevent automatic cleanup that would interfere with property access and event handling.

  2. Property Binding: Function properties from the source stream are bound to maintain the correct this context when called on the target stream.

  3. Non-Overwriting: Existing properties on the target stream are never overwritten, preserving the target stream's original functionality.

  4. Manual Destroy Handling: The destroy() method is not automatically proxied. You must manually handle destruction if needed.

  5. Event Timing: The 'close' event forwarding handles different timing scenarios based on whether the response is complete and whether the target stream is still readable.