or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

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

0

# Mimic Response

1

2

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.

3

4

## Package Information

5

6

- **Package Name**: mimic-response

7

- **Package Type**: npm

8

- **Language**: JavaScript (ES Module)

9

- **Installation**: `npm install mimic-response`

10

11

## Core Imports

12

13

```javascript

14

import mimicResponse from "mimic-response";

15

```

16

17

For CommonJS:

18

19

```javascript

20

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

21

```

22

23

For TypeScript:

24

25

```typescript

26

import mimicResponse from "mimic-response";

27

import type { IncomingMessage } from "node:http";

28

```

29

30

## Basic Usage

31

32

```javascript

33

import { PassThrough as PassThroughStream } from "node:stream";

34

import mimicResponse from "mimic-response";

35

36

// Get an HTTP response stream from a request

37

const responseStream = getHttpResponseStream();

38

39

// Create a new stream that will mimic the response

40

const myStream = new PassThroughStream({ autoDestroy: false });

41

42

// Copy all HTTP properties and event handlers

43

mimicResponse(responseStream, myStream);

44

45

// Now myStream has all the HTTP response properties

46

console.log(myStream.statusCode); // 200

47

console.log(myStream.headers); // Response headers object

48

console.log(myStream.complete); // Boolean indicating response completion

49

```

50

51

## Capabilities

52

53

### Stream Mimicking

54

55

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

56

57

```javascript { .api }

58

/**

59

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

60

* @param fromStream - The HTTP response stream to copy properties from

61

* @param toStream - The target stream to copy properties to (must have autoDestroy: false)

62

* @returns The enhanced toStream with HTTP response properties

63

* @throws Error if toStream has autoDestroy: true

64

*/

65

function mimicResponse<T extends NodeJS.ReadableStream>(

66

fromStream: IncomingMessage,

67

toStream: T

68

): T & IncomingMessage;

69

```

70

71

**Parameters:**

72

- `fromStream` (IncomingMessage): The source HTTP response stream containing properties to copy

73

- `toStream` (NodeJS.ReadableStream): The target stream that will receive the copied properties. Must have `autoDestroy: false`

74

75

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

76

77

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

78

79

**Copied Properties:**

80

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

81

82

```javascript { .api }

83

const knownProperties = [

84

'aborted', // Boolean indicating if request was aborted

85

'complete', // Boolean indicating if response is complete

86

'headers', // Response headers object

87

'httpVersion', // HTTP version string (e.g., "1.1")

88

'httpVersionMinor', // HTTP version minor number

89

'httpVersionMajor', // HTTP version major number

90

'method', // HTTP method string

91

'rawHeaders', // Raw headers array

92

'rawTrailers', // Raw trailers array

93

'setTimeout', // Timeout method function

94

'socket', // Underlying socket object

95

'statusCode', // HTTP status code number

96

'statusMessage', // HTTP status message string

97

'trailers', // Response trailers object

98

'url' // Request URL string

99

];

100

```

101

102

**Event Forwarding:**

103

- **aborted**: When source stream emits 'aborted', destroys target stream and re-emits 'aborted'

104

- **close**: When source stream emits 'close', re-emits 'close' on target stream with proper timing based on response completion

105

106

**Usage Examples:**

107

108

Basic stream proxy:

109

```javascript

110

import { PassThrough as PassThroughStream } from "node:stream";

111

import mimicResponse from "mimic-response";

112

113

const responseStream = getHttpResponseStream();

114

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

115

116

mimicResponse(responseStream, proxyStream);

117

118

// Access HTTP properties on the proxy stream

119

console.log(proxyStream.statusCode); // Same as responseStream.statusCode

120

console.log(proxyStream.headers); // Same as responseStream.headers

121

```

122

123

Custom stream with manual destroy handling:

124

```javascript

125

import { PassThrough as PassThroughStream } from "node:stream";

126

import mimicResponse from "mimic-response";

127

128

const responseStream = getHttpResponseStream();

129

130

const myStream = new PassThroughStream({

131

autoDestroy: false,

132

destroy(error, callback) {

133

// Manually destroy the source stream

134

responseStream.destroy();

135

callback(error);

136

}

137

});

138

139

mimicResponse(responseStream, myStream);

140

141

// The streams are now linked for destruction

142

myStream.destroy();

143

```

144

145

Stream transformation pipeline:

146

```javascript

147

import { Transform } from "node:stream";

148

import mimicResponse from "mimic-response";

149

150

const responseStream = getHttpResponseStream();

151

152

const transformStream = new Transform({

153

autoDestroy: false,

154

transform(chunk, encoding, callback) {

155

// Transform the data while preserving HTTP properties

156

const transformed = chunk.toString().toUpperCase();

157

callback(null, transformed);

158

}

159

});

160

161

mimicResponse(responseStream, transformStream);

162

163

// Transform stream now has HTTP properties and transforms data

164

responseStream.pipe(transformStream);

165

```

166

167

## Types

168

169

```typescript { .api }

170

interface IncomingMessage extends NodeJS.ReadableStream {

171

aborted: boolean;

172

complete: boolean;

173

headers: { [key: string]: string | string[] | undefined };

174

httpVersion: string;

175

httpVersionMajor: number;

176

httpVersionMinor: number;

177

method?: string;

178

rawHeaders: string[];

179

rawTrailers: string[];

180

setTimeout(msecs: number, callback?: () => void): this;

181

socket: any;

182

statusCode?: number;

183

statusMessage?: string;

184

trailers: { [key: string]: string | undefined };

185

url?: string;

186

}

187

```

188

189

## Error Handling

190

191

The function validates that the target stream is properly configured:

192

193

- **Validation Error**: Throws an Error if `toStream._readableState.autoDestroy` is `true`

194

- **Error Message**: "The second stream must have the `autoDestroy` option set to `false`"

195

196

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

197

198

## Important Notes

199

200

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

201

202

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

203

204

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

205

206

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

207

208

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.