@jaypie/express 1.2.4-rc13 → 1.2.4-rc15
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/cjs/adapter/LambdaResponseBuffered.d.ts +1 -0
- package/dist/cjs/adapter/__tests__/debug-harness.d.ts +1 -0
- package/dist/cjs/index.cjs +83 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/adapter/LambdaResponseBuffered.d.ts +1 -0
- package/dist/esm/adapter/__tests__/debug-harness.d.ts +1 -0
- package/dist/esm/index.js +83 -1
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,6 +12,7 @@ export declare class LambdaResponseBuffered extends Writable {
|
|
|
12
12
|
remoteAddress: string;
|
|
13
13
|
};
|
|
14
14
|
_chunks: Buffer[];
|
|
15
|
+
_ended: boolean;
|
|
15
16
|
_headers: Map<string, string | string[]>;
|
|
16
17
|
_headersSent: boolean;
|
|
17
18
|
_resolve: ((result: LambdaResponse) => void) | null;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/esm/index.js
CHANGED
|
@@ -32,6 +32,15 @@ class LambdaRequest extends Readable {
|
|
|
32
32
|
this.path = options.url.split("?")[0];
|
|
33
33
|
this.headers = this.normalizeHeaders(options.headers);
|
|
34
34
|
this.bodyBuffer = options.body ?? null;
|
|
35
|
+
// Parse query string from URL
|
|
36
|
+
const queryIndex = options.url.indexOf("?");
|
|
37
|
+
if (queryIndex !== -1) {
|
|
38
|
+
const queryString = options.url.slice(queryIndex + 1);
|
|
39
|
+
const params = new URLSearchParams(queryString);
|
|
40
|
+
for (const [key, value] of params) {
|
|
41
|
+
this.query[key] = value;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
35
44
|
// Store Lambda context
|
|
36
45
|
this._lambdaContext = options.lambdaContext;
|
|
37
46
|
this._lambdaEvent = options.lambdaEvent;
|
|
@@ -42,6 +51,18 @@ class LambdaRequest extends Readable {
|
|
|
42
51
|
remoteAddress: options.remoteAddress,
|
|
43
52
|
};
|
|
44
53
|
this.connection = this.socket;
|
|
54
|
+
// Schedule body push for next tick to ensure stream is ready
|
|
55
|
+
// This is needed for body parsers that consume the stream
|
|
56
|
+
if (this.bodyBuffer && this.bodyBuffer.length > 0) {
|
|
57
|
+
process.nextTick(() => {
|
|
58
|
+
if (!this.bodyPushed) {
|
|
59
|
+
this.push(this.bodyBuffer);
|
|
60
|
+
this.push(null);
|
|
61
|
+
this.bodyPushed = true;
|
|
62
|
+
this.complete = true;
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
45
66
|
}
|
|
46
67
|
//
|
|
47
68
|
// Readable stream implementation
|
|
@@ -143,6 +164,11 @@ function createLambdaRequest(event, context) {
|
|
|
143
164
|
body = event.isBase64Encoded
|
|
144
165
|
? Buffer.from(event.body, "base64")
|
|
145
166
|
: Buffer.from(event.body, "utf8");
|
|
167
|
+
// Add content-length header if not present (required for body parsers)
|
|
168
|
+
const hasContentLength = Object.keys(headers).some((k) => k.toLowerCase() === "content-length");
|
|
169
|
+
if (!hasContentLength) {
|
|
170
|
+
headers["content-length"] = String(body.length);
|
|
171
|
+
}
|
|
146
172
|
}
|
|
147
173
|
return new LambdaRequest({
|
|
148
174
|
body,
|
|
@@ -193,6 +219,7 @@ class LambdaResponseBuffered extends Writable {
|
|
|
193
219
|
// Internal state exposed for direct manipulation by safe response methods
|
|
194
220
|
// that need to bypass dd-trace interception of stream methods
|
|
195
221
|
this._chunks = [];
|
|
222
|
+
this._ended = false; // Track ended state since writableEnded is lost after prototype change
|
|
196
223
|
this._headers = new Map();
|
|
197
224
|
this._headersSent = false;
|
|
198
225
|
this._resolve = null;
|
|
@@ -201,6 +228,32 @@ class LambdaResponseBuffered extends Writable {
|
|
|
201
228
|
if (kOutHeaders$1) {
|
|
202
229
|
this[kOutHeaders$1] = Object.create(null);
|
|
203
230
|
}
|
|
231
|
+
// CRITICAL: Define key methods as instance properties to survive Express's
|
|
232
|
+
// setPrototypeOf(res, app.response) in middleware/init.js which would
|
|
233
|
+
// otherwise replace our prototype with ServerResponse.prototype.
|
|
234
|
+
// Instance properties take precedence over prototype properties.
|
|
235
|
+
this.getHeader = this.getHeader.bind(this);
|
|
236
|
+
this.setHeader = this.setHeader.bind(this);
|
|
237
|
+
this.removeHeader = this.removeHeader.bind(this);
|
|
238
|
+
this.hasHeader = this.hasHeader.bind(this);
|
|
239
|
+
this.getHeaders = this.getHeaders.bind(this);
|
|
240
|
+
this.getHeaderNames = this.getHeaderNames.bind(this);
|
|
241
|
+
this.writeHead = this.writeHead.bind(this);
|
|
242
|
+
this.get = this.get.bind(this);
|
|
243
|
+
this.set = this.set.bind(this);
|
|
244
|
+
this.status = this.status.bind(this);
|
|
245
|
+
this.json = this.json.bind(this);
|
|
246
|
+
this.send = this.send.bind(this);
|
|
247
|
+
this.vary = this.vary.bind(this);
|
|
248
|
+
this.end = this.end.bind(this);
|
|
249
|
+
this.write = this.write.bind(this);
|
|
250
|
+
// Also bind internal Writable methods that are called via prototype chain
|
|
251
|
+
this._write = this._write.bind(this);
|
|
252
|
+
this._final = this._final.bind(this);
|
|
253
|
+
// Bind result-building methods
|
|
254
|
+
this.getResult = this.getResult.bind(this);
|
|
255
|
+
this.buildResult = this.buildResult.bind(this);
|
|
256
|
+
this.isBinaryContentType = this.isBinaryContentType.bind(this);
|
|
204
257
|
}
|
|
205
258
|
//
|
|
206
259
|
// Internal bypass methods - completely avoid prototype chain lookup
|
|
@@ -243,7 +296,8 @@ class LambdaResponseBuffered extends Writable {
|
|
|
243
296
|
//
|
|
244
297
|
getResult() {
|
|
245
298
|
return new Promise((resolve) => {
|
|
246
|
-
|
|
299
|
+
// Use _ended instead of writableEnded since Express's setPrototypeOf breaks the getter
|
|
300
|
+
if (this._ended) {
|
|
247
301
|
resolve(this.buildResult());
|
|
248
302
|
}
|
|
249
303
|
else {
|
|
@@ -437,6 +491,7 @@ class LambdaResponseBuffered extends Writable {
|
|
|
437
491
|
callback();
|
|
438
492
|
}
|
|
439
493
|
_final(callback) {
|
|
494
|
+
this._ended = true;
|
|
440
495
|
if (this._resolve) {
|
|
441
496
|
this._resolve(this.buildResult());
|
|
442
497
|
}
|
|
@@ -522,6 +577,29 @@ class LambdaResponseStreaming extends Writable {
|
|
|
522
577
|
if (kOutHeaders) {
|
|
523
578
|
this[kOutHeaders] = Object.create(null);
|
|
524
579
|
}
|
|
580
|
+
// CRITICAL: Define key methods as instance properties to survive Express's
|
|
581
|
+
// setPrototypeOf(res, app.response) in middleware/init.js which would
|
|
582
|
+
// otherwise replace our prototype with ServerResponse.prototype.
|
|
583
|
+
// Instance properties take precedence over prototype properties.
|
|
584
|
+
this.getHeader = this.getHeader.bind(this);
|
|
585
|
+
this.setHeader = this.setHeader.bind(this);
|
|
586
|
+
this.removeHeader = this.removeHeader.bind(this);
|
|
587
|
+
this.hasHeader = this.hasHeader.bind(this);
|
|
588
|
+
this.getHeaders = this.getHeaders.bind(this);
|
|
589
|
+
this.getHeaderNames = this.getHeaderNames.bind(this);
|
|
590
|
+
this.writeHead = this.writeHead.bind(this);
|
|
591
|
+
this.flushHeaders = this.flushHeaders.bind(this);
|
|
592
|
+
this.get = this.get.bind(this);
|
|
593
|
+
this.set = this.set.bind(this);
|
|
594
|
+
this.status = this.status.bind(this);
|
|
595
|
+
this.json = this.json.bind(this);
|
|
596
|
+
this.send = this.send.bind(this);
|
|
597
|
+
this.vary = this.vary.bind(this);
|
|
598
|
+
this.end = this.end.bind(this);
|
|
599
|
+
this.write = this.write.bind(this);
|
|
600
|
+
// Also bind internal Writable methods that are called via prototype chain
|
|
601
|
+
this._write = this._write.bind(this);
|
|
602
|
+
this._final = this._final.bind(this);
|
|
525
603
|
}
|
|
526
604
|
//
|
|
527
605
|
// Internal bypass methods - completely avoid prototype chain lookup
|
|
@@ -1718,6 +1796,10 @@ function expressHandler(handlerOrOptions, optionsOrHandler) {
|
|
|
1718
1796
|
catch (error) {
|
|
1719
1797
|
log.fatal("Express encountered an error while sending the response");
|
|
1720
1798
|
log.var({ responseError: error });
|
|
1799
|
+
// Log full stack trace for debugging
|
|
1800
|
+
if (error instanceof Error && error.stack) {
|
|
1801
|
+
log.error(error.stack);
|
|
1802
|
+
}
|
|
1721
1803
|
}
|
|
1722
1804
|
// Log response
|
|
1723
1805
|
const extras = {};
|