@jaypie/express 1.2.31 → 1.2.33
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/headers.helper.d.ts +15 -0
- package/dist/cjs/adapter/types.d.ts +1 -0
- package/dist/cjs/index.cjs +62 -31
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/adapter/headers.helper.d.ts +15 -0
- package/dist/esm/adapter/types.d.ts +1 -0
- package/dist/esm/index.js +62 -31
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export declare const SET_COOKIE = "set-cookie";
|
|
2
|
+
/**
|
|
3
|
+
* Normalize a header value for storage, preserving arrays.
|
|
4
|
+
* Node's ServerResponse keeps multi-value headers as arrays; stringifying
|
|
5
|
+
* here would fold them into a single comma-separated value.
|
|
6
|
+
*/
|
|
7
|
+
export declare function normalizeHeaderValue(value: number | string | string[]): string | string[];
|
|
8
|
+
/**
|
|
9
|
+
* Split stored headers into a single-value header record and a cookies
|
|
10
|
+
* array, matching the Lambda Function URL (v2) response shape.
|
|
11
|
+
*/
|
|
12
|
+
export declare function splitCookieHeaders(source: Map<string, string | string[]>): {
|
|
13
|
+
cookies: string[];
|
|
14
|
+
headers: Record<string, string>;
|
|
15
|
+
};
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -278,6 +278,50 @@ function createLambdaRequest(event, context) {
|
|
|
278
278
|
});
|
|
279
279
|
}
|
|
280
280
|
|
|
281
|
+
//
|
|
282
|
+
//
|
|
283
|
+
// Constants
|
|
284
|
+
//
|
|
285
|
+
// Set-Cookie is the one header that must never be comma-folded: cookie
|
|
286
|
+
// expiry dates contain commas, so a folded value is unparseable. Lambda
|
|
287
|
+
// carries these out-of-band in the `cookies` field of the v2 response
|
|
288
|
+
// payload and of the response-streaming metadata prelude.
|
|
289
|
+
const SET_COOKIE = "set-cookie";
|
|
290
|
+
//
|
|
291
|
+
//
|
|
292
|
+
// Functions
|
|
293
|
+
//
|
|
294
|
+
/**
|
|
295
|
+
* Normalize a header value for storage, preserving arrays.
|
|
296
|
+
* Node's ServerResponse keeps multi-value headers as arrays; stringifying
|
|
297
|
+
* here would fold them into a single comma-separated value.
|
|
298
|
+
*/
|
|
299
|
+
function normalizeHeaderValue(value) {
|
|
300
|
+
return Array.isArray(value) ? value.map(String) : String(value);
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Split stored headers into a single-value header record and a cookies
|
|
304
|
+
* array, matching the Lambda Function URL (v2) response shape.
|
|
305
|
+
*/
|
|
306
|
+
function splitCookieHeaders(source) {
|
|
307
|
+
const cookies = [];
|
|
308
|
+
const headers = {};
|
|
309
|
+
for (const [key, value] of source) {
|
|
310
|
+
if (key === SET_COOKIE) {
|
|
311
|
+
if (Array.isArray(value)) {
|
|
312
|
+
cookies.push(...value);
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
cookies.push(value);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
headers[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
return { cookies, headers };
|
|
323
|
+
}
|
|
324
|
+
|
|
281
325
|
//
|
|
282
326
|
//
|
|
283
327
|
// Constants
|
|
@@ -415,13 +459,14 @@ class LambdaResponseBuffered extends node_stream.Writable {
|
|
|
415
459
|
return this;
|
|
416
460
|
}
|
|
417
461
|
const lowerName = name.toLowerCase();
|
|
418
|
-
|
|
462
|
+
const normalized = normalizeHeaderValue(value);
|
|
463
|
+
this._headers.set(lowerName, normalized);
|
|
419
464
|
// Sync with kOutHeaders for dd-trace compatibility
|
|
420
465
|
// Node stores as { 'header-name': ['Header-Name', value] }
|
|
421
466
|
if (kOutHeaders$1) {
|
|
422
467
|
const outHeaders = this[kOutHeaders$1];
|
|
423
468
|
if (outHeaders) {
|
|
424
|
-
outHeaders[lowerName] = [name,
|
|
469
|
+
outHeaders[lowerName] = [name, normalized];
|
|
425
470
|
}
|
|
426
471
|
}
|
|
427
472
|
return this;
|
|
@@ -509,7 +554,7 @@ class LambdaResponseBuffered extends node_stream.Writable {
|
|
|
509
554
|
// Use direct _headers access to bypass dd-trace interception
|
|
510
555
|
for (const [key, value] of Object.entries(headersToSet)) {
|
|
511
556
|
if (value !== undefined) {
|
|
512
|
-
this._headers.set(key.toLowerCase(),
|
|
557
|
+
this._headers.set(key.toLowerCase(), normalizeHeaderValue(value));
|
|
513
558
|
}
|
|
514
559
|
}
|
|
515
560
|
}
|
|
@@ -537,7 +582,7 @@ class LambdaResponseBuffered extends node_stream.Writable {
|
|
|
537
582
|
*/
|
|
538
583
|
set(name, value) {
|
|
539
584
|
if (!this._headersSent) {
|
|
540
|
-
this._headers.set(name.toLowerCase(),
|
|
585
|
+
this._headers.set(name.toLowerCase(), normalizeHeaderValue(value));
|
|
541
586
|
}
|
|
542
587
|
return this;
|
|
543
588
|
}
|
|
@@ -607,23 +652,8 @@ class LambdaResponseBuffered extends node_stream.Writable {
|
|
|
607
652
|
const contentType = this._headers.get("content-type") || "";
|
|
608
653
|
// Determine if response should be base64 encoded
|
|
609
654
|
const isBase64Encoded = this.isBinaryContentType(contentType);
|
|
610
|
-
// Build headers object
|
|
611
|
-
const headers =
|
|
612
|
-
const cookies = [];
|
|
613
|
-
for (const [key, value] of this._headers) {
|
|
614
|
-
if (key === "set-cookie") {
|
|
615
|
-
// Collect Set-Cookie headers for v2 response format
|
|
616
|
-
if (Array.isArray(value)) {
|
|
617
|
-
cookies.push(...value);
|
|
618
|
-
}
|
|
619
|
-
else {
|
|
620
|
-
cookies.push(value);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
else {
|
|
624
|
-
headers[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
625
|
-
}
|
|
626
|
-
}
|
|
655
|
+
// Build headers object, carrying Set-Cookie out-of-band (v2 format)
|
|
656
|
+
const { cookies, headers } = splitCookieHeaders(this._headers);
|
|
627
657
|
const result = {
|
|
628
658
|
body: isBase64Encoded ? body.toString("base64") : body.toString("utf8"),
|
|
629
659
|
headers,
|
|
@@ -756,13 +786,14 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
756
786
|
return this;
|
|
757
787
|
}
|
|
758
788
|
const lowerName = name.toLowerCase();
|
|
759
|
-
|
|
789
|
+
const normalized = normalizeHeaderValue(value);
|
|
790
|
+
this._headers.set(lowerName, normalized);
|
|
760
791
|
// Sync with kOutHeaders for dd-trace compatibility
|
|
761
792
|
// Node stores as { 'header-name': ['Header-Name', value] }
|
|
762
793
|
if (kOutHeaders) {
|
|
763
794
|
const outHeaders = this[kOutHeaders];
|
|
764
795
|
if (outHeaders) {
|
|
765
|
-
outHeaders[lowerName] = [name,
|
|
796
|
+
outHeaders[lowerName] = [name, normalized];
|
|
766
797
|
}
|
|
767
798
|
}
|
|
768
799
|
return this;
|
|
@@ -857,7 +888,7 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
857
888
|
// Use direct _headers access to bypass dd-trace interception
|
|
858
889
|
for (const [key, value] of Object.entries(headersToSet)) {
|
|
859
890
|
if (value !== undefined) {
|
|
860
|
-
this._headers.set(key.toLowerCase(),
|
|
891
|
+
this._headers.set(key.toLowerCase(), normalizeHeaderValue(value));
|
|
861
892
|
}
|
|
862
893
|
}
|
|
863
894
|
}
|
|
@@ -871,10 +902,8 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
871
902
|
if (this._headersSent) {
|
|
872
903
|
return;
|
|
873
904
|
}
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
headers[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
877
|
-
}
|
|
905
|
+
// Set-Cookie travels in metadata.cookies, never folded into headers
|
|
906
|
+
const { cookies, headers } = splitCookieHeaders(this._headers);
|
|
878
907
|
// Lambda streaming requires body content for metadata to be transmitted.
|
|
879
908
|
// Convert 204 No Content to 200 OK with empty JSON body as workaround.
|
|
880
909
|
// See: https://github.com/finlaysonstudio/jaypie/issues/178
|
|
@@ -889,6 +918,10 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
889
918
|
headers,
|
|
890
919
|
statusCode,
|
|
891
920
|
};
|
|
921
|
+
// Only include cookies if present (v2 format)
|
|
922
|
+
if (cookies.length > 0) {
|
|
923
|
+
metadata.cookies = cookies;
|
|
924
|
+
}
|
|
892
925
|
// Create wrapped stream with metadata
|
|
893
926
|
this._wrappedStream = awslambda.HttpResponseStream.from(this._responseStream, metadata);
|
|
894
927
|
this._headersSent = true;
|
|
@@ -917,7 +950,7 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
917
950
|
*/
|
|
918
951
|
set(name, value) {
|
|
919
952
|
if (!this._headersSent) {
|
|
920
|
-
this._headers.set(name.toLowerCase(),
|
|
953
|
+
this._headers.set(name.toLowerCase(), normalizeHeaderValue(value));
|
|
921
954
|
}
|
|
922
955
|
return this;
|
|
923
956
|
}
|
|
@@ -1757,7 +1790,6 @@ function safeSend(res, statusCode, body) {
|
|
|
1757
1790
|
}
|
|
1758
1791
|
}
|
|
1759
1792
|
function expressHandler(handlerOrOptions, optionsOrHandler) {
|
|
1760
|
-
/* eslint-enable no-redeclare */
|
|
1761
1793
|
let handler;
|
|
1762
1794
|
let options;
|
|
1763
1795
|
// If handler is an object and options is a function, swap them
|
|
@@ -2174,7 +2206,6 @@ function getErrorBody(error) {
|
|
|
2174
2206
|
: new errors.UnhandledError().body();
|
|
2175
2207
|
}
|
|
2176
2208
|
function expressStreamHandler(handlerOrOptions, optionsOrHandler) {
|
|
2177
|
-
/* eslint-enable no-redeclare */
|
|
2178
2209
|
let handler;
|
|
2179
2210
|
let options;
|
|
2180
2211
|
// If handler is an object and options is a function, swap them
|