@jaypie/express 1.2.10 → 1.2.11-dev.0
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/index.cjs +86 -8
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +86 -8
- package/dist/esm/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cjs/index.cjs
CHANGED
|
@@ -661,6 +661,10 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
661
661
|
// Survives prototype manipulation from Express and dd-trace.
|
|
662
662
|
this[JAYPIE_LAMBDA_STREAMING] =
|
|
663
663
|
true;
|
|
664
|
+
// DIAGNOSTIC: Log symbol assignment
|
|
665
|
+
console.log("[DIAG:LambdaResponseStreaming:constructor] Symbol set", {
|
|
666
|
+
symbolValue: this[JAYPIE_LAMBDA_STREAMING],
|
|
667
|
+
});
|
|
664
668
|
// Initialize Node's internal kOutHeaders for dd-trace compatibility.
|
|
665
669
|
// dd-trace patches HTTP methods and expects this internal state.
|
|
666
670
|
if (kOutHeaders) {
|
|
@@ -848,8 +852,17 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
848
852
|
return this._headersSent;
|
|
849
853
|
}
|
|
850
854
|
flushHeaders() {
|
|
851
|
-
|
|
855
|
+
// DIAGNOSTIC: Log every flushHeaders call with stack trace
|
|
856
|
+
const caller = new Error().stack?.split("\n").slice(1, 5).join("\n");
|
|
857
|
+
console.log("[DIAG:LambdaResponseStreaming:flushHeaders] Called", {
|
|
858
|
+
statusCode: this.statusCode,
|
|
859
|
+
headersSent: this._headersSent,
|
|
860
|
+
caller,
|
|
861
|
+
});
|
|
862
|
+
if (this._headersSent) {
|
|
863
|
+
console.log("[DIAG:LambdaResponseStreaming:flushHeaders] Already sent, returning early");
|
|
852
864
|
return;
|
|
865
|
+
}
|
|
853
866
|
const headers = {};
|
|
854
867
|
for (const [key, value] of this._headers) {
|
|
855
868
|
headers[key] = Array.isArray(value) ? value.join(", ") : String(value);
|
|
@@ -858,6 +871,10 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
858
871
|
headers,
|
|
859
872
|
statusCode: this.statusCode,
|
|
860
873
|
};
|
|
874
|
+
// DIAGNOSTIC: Log what we're sending to Lambda
|
|
875
|
+
console.log("[DIAG:LambdaResponseStreaming:flushHeaders] Creating wrapped stream", {
|
|
876
|
+
metadata,
|
|
877
|
+
});
|
|
861
878
|
// Wrap the stream with metadata using awslambda global
|
|
862
879
|
this._wrappedStream = awslambda.HttpResponseStream.from(this._responseStream, metadata);
|
|
863
880
|
this._headersSent = true;
|
|
@@ -891,6 +908,14 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
891
908
|
return this;
|
|
892
909
|
}
|
|
893
910
|
status(code) {
|
|
911
|
+
// DIAGNOSTIC: Log status code changes
|
|
912
|
+
const caller = new Error().stack?.split("\n").slice(1, 4).join("\n");
|
|
913
|
+
console.log("[DIAG:LambdaResponseStreaming:status] Setting status", {
|
|
914
|
+
newCode: code,
|
|
915
|
+
previousCode: this.statusCode,
|
|
916
|
+
headersSent: this._headersSent,
|
|
917
|
+
caller,
|
|
918
|
+
});
|
|
894
919
|
this.statusCode = code;
|
|
895
920
|
return this;
|
|
896
921
|
}
|
|
@@ -936,10 +961,17 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
936
961
|
const buffer = Buffer.isBuffer(chunk)
|
|
937
962
|
? chunk
|
|
938
963
|
: Buffer.from(chunk, encoding);
|
|
964
|
+
// DIAGNOSTIC: Log every write
|
|
965
|
+
console.log("[DIAG:LambdaResponseStreaming:_write] Called", {
|
|
966
|
+
chunkLength: buffer.length,
|
|
967
|
+
headersSent: this._headersSent,
|
|
968
|
+
statusCode: this.statusCode,
|
|
969
|
+
});
|
|
939
970
|
if (!this._headersSent) {
|
|
940
971
|
// Buffer writes until headers are sent
|
|
941
972
|
this._pendingWrites.push({ callback: () => callback(), chunk: buffer });
|
|
942
973
|
// Auto-flush headers on first write
|
|
974
|
+
console.log("[DIAG:LambdaResponseStreaming:_write] Auto-flushing headers on first write");
|
|
943
975
|
this.flushHeaders();
|
|
944
976
|
}
|
|
945
977
|
else {
|
|
@@ -948,7 +980,14 @@ class LambdaResponseStreaming extends node_stream.Writable {
|
|
|
948
980
|
}
|
|
949
981
|
}
|
|
950
982
|
_final(callback) {
|
|
983
|
+
// DIAGNOSTIC: Log _final call
|
|
984
|
+
console.log("[DIAG:LambdaResponseStreaming:_final] Called", {
|
|
985
|
+
headersSent: this._headersSent,
|
|
986
|
+
statusCode: this.statusCode,
|
|
987
|
+
hasWrappedStream: !!this._wrappedStream,
|
|
988
|
+
});
|
|
951
989
|
if (!this._headersSent) {
|
|
990
|
+
console.log("[DIAG:LambdaResponseStreaming:_final] Headers not sent, flushing now");
|
|
952
991
|
this.flushHeaders();
|
|
953
992
|
}
|
|
954
993
|
this._wrappedStream?.end();
|
|
@@ -1461,7 +1500,8 @@ const decorateResponse = (res, { handler = "", version = process.env.PROJECT_VER
|
|
|
1461
1500
|
// X-Powered-By, override "Express" but nothing else
|
|
1462
1501
|
const currentPoweredBy = safeGetHeader(extRes, kit.HTTP.HEADER.POWERED_BY);
|
|
1463
1502
|
if (!currentPoweredBy || currentPoweredBy === "Express") {
|
|
1464
|
-
|
|
1503
|
+
// DIAGNOSTIC: Include dev marker to verify build deployment
|
|
1504
|
+
safeSetHeader(extRes, kit.HTTP.HEADER.POWERED_BY, `${kit.JAYPIE.LIB.EXPRESS}#dev-178`);
|
|
1465
1505
|
}
|
|
1466
1506
|
// X-Project-Environment
|
|
1467
1507
|
if (process.env.PROJECT_ENV) {
|
|
@@ -1558,8 +1598,16 @@ function isLambdaMockResponse(res) {
|
|
|
1558
1598
|
* Uses Symbol marker to survive prototype chain modifications from Express and dd-trace.
|
|
1559
1599
|
*/
|
|
1560
1600
|
function isLambdaStreamingResponse(res) {
|
|
1561
|
-
|
|
1562
|
-
|
|
1601
|
+
const symbolValue = res[JAYPIE_LAMBDA_STREAMING];
|
|
1602
|
+
const result = symbolValue === true;
|
|
1603
|
+
// DIAGNOSTIC: Log symbol check
|
|
1604
|
+
console.log("[DIAG:expressHandler:isLambdaStreamingResponse] Check", {
|
|
1605
|
+
symbolValue,
|
|
1606
|
+
result,
|
|
1607
|
+
resConstructorName: res?.constructor?.name,
|
|
1608
|
+
hasFlushHeaders: typeof res.flushHeaders === "function",
|
|
1609
|
+
});
|
|
1610
|
+
return result;
|
|
1563
1611
|
}
|
|
1564
1612
|
/**
|
|
1565
1613
|
* Safely send a JSON response, avoiding dd-trace interception.
|
|
@@ -1593,15 +1641,29 @@ function safeSendJson(res, statusCode, data) {
|
|
|
1593
1641
|
return;
|
|
1594
1642
|
}
|
|
1595
1643
|
// Fall back to standard Express methods for real responses
|
|
1644
|
+
// DIAGNOSTIC: Log before setting status
|
|
1645
|
+
console.log("[DIAG:expressHandler:safeSendJson] Before res.status()", {
|
|
1646
|
+
statusCode,
|
|
1647
|
+
currentStatusCode: res.statusCode,
|
|
1648
|
+
});
|
|
1596
1649
|
res.status(statusCode);
|
|
1650
|
+
console.log("[DIAG:expressHandler:safeSendJson] After res.status()", {
|
|
1651
|
+
statusCode,
|
|
1652
|
+
newStatusCode: res.statusCode,
|
|
1653
|
+
});
|
|
1597
1654
|
// CRITICAL: For Lambda streaming responses, flush headers before send to
|
|
1598
1655
|
// initialize the stream wrapper. This ensures the status code is captured
|
|
1599
1656
|
// before any writes occur (which would auto-flush with default 200).
|
|
1600
1657
|
// Uses Symbol marker for reliable detection that survives prototype manipulation.
|
|
1601
|
-
|
|
1602
|
-
|
|
1658
|
+
const isStreaming = isLambdaStreamingResponse(res);
|
|
1659
|
+
console.log("[DIAG:expressHandler:safeSendJson] Streaming check", {
|
|
1660
|
+
isStreaming,
|
|
1661
|
+
});
|
|
1662
|
+
if (isStreaming && typeof res.flushHeaders === "function") {
|
|
1663
|
+
console.log("[DIAG:expressHandler:safeSendJson] Calling flushHeaders explicitly");
|
|
1603
1664
|
res.flushHeaders();
|
|
1604
1665
|
}
|
|
1666
|
+
console.log("[DIAG:expressHandler:safeSendJson] Calling res.json()");
|
|
1605
1667
|
res.json(data);
|
|
1606
1668
|
}
|
|
1607
1669
|
/**
|
|
@@ -1630,19 +1692,35 @@ function safeSend(res, statusCode, body) {
|
|
|
1630
1692
|
return;
|
|
1631
1693
|
}
|
|
1632
1694
|
// Fall back to standard Express methods for real responses
|
|
1695
|
+
// DIAGNOSTIC: Log before setting status
|
|
1696
|
+
console.log("[DIAG:expressHandler:safeSend] Before res.status()", {
|
|
1697
|
+
statusCode,
|
|
1698
|
+
currentStatusCode: res.statusCode,
|
|
1699
|
+
hasBody: body !== undefined,
|
|
1700
|
+
});
|
|
1633
1701
|
res.status(statusCode);
|
|
1702
|
+
console.log("[DIAG:expressHandler:safeSend] After res.status()", {
|
|
1703
|
+
statusCode,
|
|
1704
|
+
newStatusCode: res.statusCode,
|
|
1705
|
+
});
|
|
1634
1706
|
// CRITICAL: For Lambda streaming responses, flush headers before send to
|
|
1635
1707
|
// initialize the stream wrapper. This ensures the status code is captured
|
|
1636
1708
|
// before any writes occur (which would auto-flush with default 200).
|
|
1637
1709
|
// Uses Symbol marker for reliable detection that survives prototype manipulation.
|
|
1638
|
-
|
|
1639
|
-
|
|
1710
|
+
const isStreaming = isLambdaStreamingResponse(res);
|
|
1711
|
+
console.log("[DIAG:expressHandler:safeSend] Streaming check", {
|
|
1712
|
+
isStreaming,
|
|
1713
|
+
});
|
|
1714
|
+
if (isStreaming && typeof res.flushHeaders === "function") {
|
|
1715
|
+
console.log("[DIAG:expressHandler:safeSend] Calling flushHeaders explicitly");
|
|
1640
1716
|
res.flushHeaders();
|
|
1641
1717
|
}
|
|
1642
1718
|
if (body !== undefined) {
|
|
1719
|
+
console.log("[DIAG:expressHandler:safeSend] Calling res.send(body)");
|
|
1643
1720
|
res.send(body);
|
|
1644
1721
|
}
|
|
1645
1722
|
else {
|
|
1723
|
+
console.log("[DIAG:expressHandler:safeSend] Calling res.send() (no body)");
|
|
1646
1724
|
res.send();
|
|
1647
1725
|
}
|
|
1648
1726
|
}
|