@jaypie/express 1.2.4-rc4 → 1.2.4-rc6

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.
@@ -33,11 +33,13 @@ export declare class LambdaResponseBuffered extends Writable {
33
33
  /**
34
34
  * Express-style alias for getHeader().
35
35
  * Used by middleware like decorateResponse that use res.get().
36
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
36
37
  */
37
38
  get(name: string): number | string | string[] | undefined;
38
39
  /**
39
40
  * Express-style alias for setHeader().
40
41
  * Used by middleware like decorateResponse that use res.set().
42
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
41
43
  */
42
44
  set(name: string, value: number | string | string[]): this;
43
45
  status(code: number): this;
@@ -34,11 +34,13 @@ export declare class LambdaResponseStreaming extends Writable {
34
34
  /**
35
35
  * Express-style alias for getHeader().
36
36
  * Used by middleware like decorateResponse that use res.get().
37
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
37
38
  */
38
39
  get(name: string): number | string | string[] | undefined;
39
40
  /**
40
41
  * Express-style alias for setHeader().
41
42
  * Used by middleware like decorateResponse that use res.set().
43
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
42
44
  */
43
45
  set(name: string, value: number | string | string[]): this;
44
46
  status(code: number): this;
package/dist/esm/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Readable, Writable } from 'node:stream';
2
+ import { ServerResponse } from 'node:http';
2
3
  import { CorsError, BadRequestError, UnhandledError, GatewayTimeoutError, UnavailableError, BadGatewayError, InternalError, TeapotError, GoneError, MethodNotAllowedError, NotFoundError, ForbiddenError, UnauthorizedError, NotImplementedError } from '@jaypie/errors';
3
4
  import { force, envBoolean, JAYPIE, HTTP, getHeaderFrom, jaypieHandler } from '@jaypie/kit';
4
5
  import expressCors from 'cors';
@@ -159,6 +160,10 @@ function createLambdaRequest(event, context) {
159
160
  //
160
161
  // Constants
161
162
  //
163
+ // Get Node's internal kOutHeaders symbol from ServerResponse prototype.
164
+ // This is needed for compatibility with Datadog dd-trace instrumentation,
165
+ // which patches HTTP methods and expects this internal state to exist.
166
+ const kOutHeaders$1 = Object.getOwnPropertySymbols(ServerResponse.prototype).find((s) => s.toString() === "Symbol(kOutHeaders)");
162
167
  const BINARY_CONTENT_TYPE_PATTERNS = [
163
168
  /^application\/octet-stream$/,
164
169
  /^application\/pdf$/,
@@ -189,6 +194,11 @@ class LambdaResponseBuffered extends Writable {
189
194
  this._headers = new Map();
190
195
  this._headersSent = false;
191
196
  this._resolve = null;
197
+ // Initialize Node's internal kOutHeaders for dd-trace compatibility.
198
+ // dd-trace patches HTTP methods and expects this internal state.
199
+ if (kOutHeaders$1) {
200
+ this[kOutHeaders$1] = Object.create(null);
201
+ }
192
202
  }
193
203
  //
194
204
  // Promise-based API for getting final result
@@ -211,14 +221,31 @@ class LambdaResponseBuffered extends Writable {
211
221
  // In production, log warning but don't throw to match Express behavior
212
222
  return this;
213
223
  }
214
- this._headers.set(name.toLowerCase(), String(value));
224
+ const lowerName = name.toLowerCase();
225
+ this._headers.set(lowerName, String(value));
226
+ // Sync with kOutHeaders for dd-trace compatibility
227
+ // Node stores as { 'header-name': ['Header-Name', value] }
228
+ if (kOutHeaders$1) {
229
+ const outHeaders = this[kOutHeaders$1];
230
+ if (outHeaders) {
231
+ outHeaders[lowerName] = [name, String(value)];
232
+ }
233
+ }
215
234
  return this;
216
235
  }
217
236
  getHeader(name) {
218
237
  return this._headers.get(name.toLowerCase());
219
238
  }
220
239
  removeHeader(name) {
221
- this._headers.delete(name.toLowerCase());
240
+ const lowerName = name.toLowerCase();
241
+ this._headers.delete(lowerName);
242
+ // Sync with kOutHeaders for dd-trace compatibility
243
+ if (kOutHeaders$1) {
244
+ const outHeaders = this[kOutHeaders$1];
245
+ if (outHeaders) {
246
+ delete outHeaders[lowerName];
247
+ }
248
+ }
222
249
  }
223
250
  getHeaders() {
224
251
  const headers = {};
@@ -300,16 +327,21 @@ class LambdaResponseBuffered extends Writable {
300
327
  /**
301
328
  * Express-style alias for getHeader().
302
329
  * Used by middleware like decorateResponse that use res.get().
330
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
303
331
  */
304
332
  get(name) {
305
- return this.getHeader(name);
333
+ return this._headers.get(name.toLowerCase());
306
334
  }
307
335
  /**
308
336
  * Express-style alias for setHeader().
309
337
  * Used by middleware like decorateResponse that use res.set().
338
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
310
339
  */
311
340
  set(name, value) {
312
- return this.setHeader(name, value);
341
+ if (!this._headersSent) {
342
+ this._headers.set(name.toLowerCase(), String(value));
343
+ }
344
+ return this;
313
345
  }
314
346
  status(code) {
315
347
  this.statusCode = code;
@@ -407,6 +439,14 @@ class LambdaResponseBuffered extends Writable {
407
439
  }
408
440
  }
409
441
 
442
+ //
443
+ //
444
+ // Constants
445
+ //
446
+ // Get Node's internal kOutHeaders symbol from ServerResponse prototype.
447
+ // This is needed for compatibility with Datadog dd-trace instrumentation,
448
+ // which patches HTTP methods and expects this internal state to exist.
449
+ const kOutHeaders = Object.getOwnPropertySymbols(ServerResponse.prototype).find((s) => s.toString() === "Symbol(kOutHeaders)");
410
450
  //
411
451
  //
412
452
  // LambdaResponseStreaming Class
@@ -429,6 +469,11 @@ class LambdaResponseStreaming extends Writable {
429
469
  this._pendingWrites = [];
430
470
  this._wrappedStream = null;
431
471
  this._responseStream = responseStream;
472
+ // Initialize Node's internal kOutHeaders for dd-trace compatibility.
473
+ // dd-trace patches HTTP methods and expects this internal state.
474
+ if (kOutHeaders) {
475
+ this[kOutHeaders] = Object.create(null);
476
+ }
432
477
  }
433
478
  //
434
479
  // Header management
@@ -439,7 +484,16 @@ class LambdaResponseStreaming extends Writable {
439
484
  // Headers cannot be changed after body starts
440
485
  return this;
441
486
  }
442
- this._headers.set(name.toLowerCase(), String(value));
487
+ const lowerName = name.toLowerCase();
488
+ this._headers.set(lowerName, String(value));
489
+ // Sync with kOutHeaders for dd-trace compatibility
490
+ // Node stores as { 'header-name': ['Header-Name', value] }
491
+ if (kOutHeaders) {
492
+ const outHeaders = this[kOutHeaders];
493
+ if (outHeaders) {
494
+ outHeaders[lowerName] = [name, String(value)];
495
+ }
496
+ }
443
497
  return this;
444
498
  }
445
499
  getHeader(name) {
@@ -447,7 +501,15 @@ class LambdaResponseStreaming extends Writable {
447
501
  }
448
502
  removeHeader(name) {
449
503
  if (!this._headersSent) {
450
- this._headers.delete(name.toLowerCase());
504
+ const lowerName = name.toLowerCase();
505
+ this._headers.delete(lowerName);
506
+ // Sync with kOutHeaders for dd-trace compatibility
507
+ if (kOutHeaders) {
508
+ const outHeaders = this[kOutHeaders];
509
+ if (outHeaders) {
510
+ delete outHeaders[lowerName];
511
+ }
512
+ }
451
513
  }
452
514
  }
453
515
  getHeaders() {
@@ -554,16 +616,21 @@ class LambdaResponseStreaming extends Writable {
554
616
  /**
555
617
  * Express-style alias for getHeader().
556
618
  * Used by middleware like decorateResponse that use res.get().
619
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
557
620
  */
558
621
  get(name) {
559
- return this.getHeader(name);
622
+ return this._headers.get(name.toLowerCase());
560
623
  }
561
624
  /**
562
625
  * Express-style alias for setHeader().
563
626
  * Used by middleware like decorateResponse that use res.set().
627
+ * Note: Directly accesses _headers to avoid prototype chain issues with bundled code.
564
628
  */
565
629
  set(name, value) {
566
- return this.setHeader(name, value);
630
+ if (!this._headersSent) {
631
+ this._headers.set(name.toLowerCase(), String(value));
632
+ }
633
+ return this;
567
634
  }
568
635
  status(code) {
569
636
  this.statusCode = code;