apitally 0.21.5 → 0.22.1

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.
Files changed (49) hide show
  1. package/dist/common/requestLogger.cjs +23 -12
  2. package/dist/common/requestLogger.cjs.map +1 -1
  3. package/dist/common/requestLogger.d.cts +1 -1
  4. package/dist/common/requestLogger.d.ts +1 -1
  5. package/dist/common/requestLogger.js +23 -12
  6. package/dist/common/requestLogger.js.map +1 -1
  7. package/dist/common/response.cjs +63 -105
  8. package/dist/common/response.cjs.map +1 -1
  9. package/dist/common/response.d.cts +14 -6
  10. package/dist/common/response.d.ts +14 -6
  11. package/dist/common/response.js +61 -100
  12. package/dist/common/response.js.map +1 -1
  13. package/dist/common/sentry.cjs +4 -1
  14. package/dist/common/sentry.cjs.map +1 -1
  15. package/dist/common/sentry.js +4 -1
  16. package/dist/common/sentry.js.map +1 -1
  17. package/dist/elysia/index.d.cts +6 -0
  18. package/dist/elysia/index.d.ts +6 -0
  19. package/dist/elysia/plugin.cjs +104 -76
  20. package/dist/elysia/plugin.cjs.map +1 -1
  21. package/dist/elysia/plugin.d.cts +10 -0
  22. package/dist/elysia/plugin.d.ts +10 -0
  23. package/dist/elysia/plugin.js +105 -77
  24. package/dist/elysia/plugin.js.map +1 -1
  25. package/dist/h3/plugin.cjs +59 -59
  26. package/dist/h3/plugin.cjs.map +1 -1
  27. package/dist/h3/plugin.js +60 -60
  28. package/dist/h3/plugin.js.map +1 -1
  29. package/dist/h3/utils.cjs +1 -1
  30. package/dist/h3/utils.cjs.map +1 -1
  31. package/dist/h3/utils.js +1 -1
  32. package/dist/h3/utils.js.map +1 -1
  33. package/dist/hono/middleware.cjs +63 -64
  34. package/dist/hono/middleware.cjs.map +1 -1
  35. package/dist/hono/middleware.js +64 -65
  36. package/dist/hono/middleware.js.map +1 -1
  37. package/dist/loggers/nestjs.cjs +4 -1
  38. package/dist/loggers/nestjs.cjs.map +1 -1
  39. package/dist/loggers/nestjs.js +4 -1
  40. package/dist/loggers/nestjs.js.map +1 -1
  41. package/dist/loggers/pino.cjs +4 -1
  42. package/dist/loggers/pino.cjs.map +1 -1
  43. package/dist/loggers/pino.js +4 -1
  44. package/dist/loggers/pino.js.map +1 -1
  45. package/dist/loggers/winston.cjs +5 -1
  46. package/dist/loggers/winston.cjs.map +1 -1
  47. package/dist/loggers/winston.js +5 -1
  48. package/dist/loggers/winston.js.map +1 -1
  49. package/package.json +7 -3
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/common/response.ts"],"sourcesContent":["export async function measureResponseSize(\n response: Response,\n tee: boolean = true,\n): Promise<[number, Response]> {\n const [newResponse1, newResponse2] = tee\n ? teeResponse(response)\n : [response, response];\n let size = 0;\n if (newResponse2.body) {\n try {\n let done = false;\n const reader = newResponse2.body.getReader();\n while (!done) {\n const result = await reader.read();\n done = result.done;\n if (!done && result.value) {\n size += result.value.byteLength;\n }\n }\n } catch (error) {\n // ignore\n }\n }\n return [size, newResponse1];\n}\n\nexport async function getResponseBody(\n response: Response,\n tee: boolean = true,\n): Promise<[Buffer, Response]> {\n const [newResponse1, newResponse2] = tee\n ? teeResponse(response)\n : [response, response];\n try {\n const responseBuffer = Buffer.from(await newResponse2.arrayBuffer());\n return [responseBuffer, newResponse1];\n } catch (error) {\n return [Buffer.from([]), newResponse1];\n }\n}\n\nexport async function getResponseJson(\n response: Response,\n): Promise<[any, Response]> {\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n const [newResponse1, newResponse2] = teeResponse(response);\n try {\n const responseJson = await newResponse2.json();\n return [responseJson, newResponse1];\n } catch (error) {\n return [null, newResponse1];\n }\n }\n return [null, response];\n}\n\nexport function teeResponse(response: Response): [Response, Response] {\n if (!response.body) {\n return [response, response];\n }\n const [stream1, stream2] = response.body.tee();\n const newResponse1 = new Response(stream1, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n const newResponse2 = new Response(stream2, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n return [newResponse1, newResponse2];\n}\n\nexport function teeResponseBlob(\n response: Response,\n blob: string | Blob,\n): [Response, Response] {\n const newResponse1 = new Response(blob, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n const newResponse2 = new Response(blob, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n return [newResponse1, newResponse2];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;AAAA,eAAsBA,oBACpBC,UACAC,MAAe,MAAI;AAEnB,QAAM,CAACC,cAAcC,YAAAA,IAAgBF,MACjCG,YAAYJ,QAAAA,IACZ;IAACA;IAAUA;;AACf,MAAIK,OAAO;AACX,MAAIF,aAAaG,MAAM;AACrB,QAAI;AACF,UAAIC,OAAO;AACX,YAAMC,SAASL,aAAaG,KAAKG,UAAS;AAC1C,aAAO,CAACF,MAAM;AACZ,cAAMG,SAAS,MAAMF,OAAOG,KAAI;AAChCJ,eAAOG,OAAOH;AACd,YAAI,CAACA,QAAQG,OAAOE,OAAO;AACzBP,kBAAQK,OAAOE,MAAMC;QACvB;MACF;IACF,SAASC,OAAO;IAEhB;EACF;AACA,SAAO;IAACT;IAAMH;;AAChB;AAxBsBH;AA0BtB,eAAsBgB,gBACpBf,UACAC,MAAe,MAAI;AAEnB,QAAM,CAACC,cAAcC,YAAAA,IAAgBF,MACjCG,YAAYJ,QAAAA,IACZ;IAACA;IAAUA;;AACf,MAAI;AACF,UAAMgB,iBAAiBC,OAAOC,KAAK,MAAMf,aAAagB,YAAW,CAAA;AACjE,WAAO;MAACH;MAAgBd;;EAC1B,SAASY,OAAO;AACd,WAAO;MAACG,OAAOC,KAAK,CAAA,CAAE;MAAGhB;;EAC3B;AACF;AAbsBa;AAetB,eAAsBK,gBACpBpB,UAAkB;AAElB,QAAMqB,cAAcrB,SAASsB,QAAQC,IAAI,cAAA;AACzC,MAAIF,2CAAaG,SAAS,qBAAqB;AAC7C,UAAM,CAACtB,cAAcC,YAAAA,IAAgBC,YAAYJ,QAAAA;AACjD,QAAI;AACF,YAAMyB,eAAe,MAAMtB,aAAauB,KAAI;AAC5C,aAAO;QAACD;QAAcvB;;IACxB,SAASY,OAAO;AACd,aAAO;QAAC;QAAMZ;;IAChB;EACF;AACA,SAAO;IAAC;IAAMF;;AAChB;AAdsBoB;AAgBf,SAAShB,YAAYJ,UAAkB;AAC5C,MAAI,CAACA,SAASM,MAAM;AAClB,WAAO;MAACN;MAAUA;;EACpB;AACA,QAAM,CAAC2B,SAASC,OAAAA,IAAW5B,SAASM,KAAKL,IAAG;AAC5C,QAAMC,eAAe,IAAI2B,SAASF,SAAS;IACzCG,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,QAAMnB,eAAe,IAAI0B,SAASD,SAAS;IACzCE,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,SAAO;IAACpB;IAAcC;;AACxB;AAhBgBC;AAkBT,SAAS4B,gBACdhC,UACAiC,MAAmB;AAEnB,QAAM/B,eAAe,IAAI2B,SAASI,MAAM;IACtCH,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,QAAMnB,eAAe,IAAI0B,SAASI,MAAM;IACtCH,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,SAAO;IAACpB;IAAcC;;AACxB;AAfgB6B;","names":["measureResponseSize","response","tee","newResponse1","newResponse2","teeResponse","size","body","done","reader","getReader","result","read","value","byteLength","error","getResponseBody","responseBuffer","Buffer","from","arrayBuffer","getResponseJson","contentType","headers","get","includes","responseJson","json","stream1","stream2","Response","status","statusText","teeResponseBlob","blob"]}
1
+ {"version":3,"sources":["../../src/common/response.ts"],"sourcesContent":["type CaptureResponseOptions = {\n captureBody: boolean;\n maxBodySize: number;\n readTimeout: number;\n};\n\nexport type CapturedResponse = {\n body?: Buffer;\n size: number;\n completed: boolean;\n error?: Error;\n};\n\nexport function captureResponse(\n response: Response,\n {\n captureBody = false,\n maxBodySize = 0,\n readTimeout = 5000,\n }: Partial<CaptureResponseOptions> = {},\n): [Response, Promise<CapturedResponse>] {\n if (!response.body) {\n return [\n response,\n Promise.resolve({\n size: 0,\n completed: true,\n }),\n ];\n }\n\n let size = 0;\n let bodySizeLimitExceeded = false;\n let readStarted = false;\n const chunks: Uint8Array[] = [];\n\n const { readable, writable } = new TransformStream({\n transform: (chunk, controller) => {\n readStarted = true;\n size += chunk.byteLength;\n if (captureBody && !bodySizeLimitExceeded) {\n if (size > maxBodySize) {\n bodySizeLimitExceeded = true;\n chunks.length = 0;\n } else {\n chunks.push(chunk);\n }\n }\n controller.enqueue(chunk);\n },\n });\n\n const pipePromise = response.body\n .pipeTo(writable)\n .then(() => ({\n body: chunks.length > 0 ? Buffer.concat(chunks) : undefined,\n size,\n completed: true,\n }))\n .catch((error) => ({\n size,\n completed: false,\n error,\n }));\n const timeoutPromise = new Promise<CapturedResponse>((resolve) =>\n setTimeout(() => {\n if (!readStarted) {\n resolve({\n size: 0,\n completed: false,\n });\n }\n }, readTimeout),\n );\n const racePromise = Promise.race([pipePromise, timeoutPromise]);\n\n const newResponse = new Response(readable, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n\n // Force Bun to initialize the headers (workaround for lazy evaluation in Bun's Response implementation)\n void newResponse.headers;\n\n return [newResponse, racePromise];\n}\n\nexport function getResponseJson(body: Buffer) {\n if (body.length === 0) {\n return null;\n }\n try {\n return JSON.parse(body.toString());\n } catch (error) {\n return null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAaA;;;;;;AAAO,SAASA,gBACdC,UACA,EACEC,cAAc,OACdC,cAAc,GACdC,cAAc,IAAI,IACiB,CAAC,GAAC;AAEvC,MAAI,CAACH,SAASI,MAAM;AAClB,WAAO;MACLJ;MACAK,QAAQC,QAAQ;QACdC,MAAM;QACNC,WAAW;MACb,CAAA;;EAEJ;AAEA,MAAID,OAAO;AACX,MAAIE,wBAAwB;AAC5B,MAAIC,cAAc;AAClB,QAAMC,SAAuB,CAAA;AAE7B,QAAM,EAAEC,UAAUC,SAAQ,IAAK,IAAIC,gBAAgB;IACjDC,WAAW,wBAACC,OAAOC,eAAAA;AACjBP,oBAAc;AACdH,cAAQS,MAAME;AACd,UAAIjB,eAAe,CAACQ,uBAAuB;AACzC,YAAIF,OAAOL,aAAa;AACtBO,kCAAwB;AACxBE,iBAAOQ,SAAS;QAClB,OAAO;AACLR,iBAAOS,KAAKJ,KAAAA;QACd;MACF;AACAC,iBAAWI,QAAQL,KAAAA;IACrB,GAZW;EAab,CAAA;AAEA,QAAMM,cAActB,SAASI,KAC1BmB,OAAOV,QAAAA,EACPW,KAAK,OAAO;IACXpB,MAAMO,OAAOQ,SAAS,IAAIM,OAAOC,OAAOf,MAAAA,IAAUgB;IAClDpB;IACAC,WAAW;EACb,EAAA,EACCoB,MAAM,CAACC,WAAW;IACjBtB;IACAC,WAAW;IACXqB;EACF,EAAA;AACF,QAAMC,iBAAiB,IAAIzB,QAA0B,CAACC,YACpDyB,WAAW,MAAA;AACT,QAAI,CAACrB,aAAa;AAChBJ,cAAQ;QACNC,MAAM;QACNC,WAAW;MACb,CAAA;IACF;EACF,GAAGL,WAAAA,CAAAA;AAEL,QAAM6B,cAAc3B,QAAQ4B,KAAK;IAACX;IAAaQ;GAAe;AAE9D,QAAMI,cAAc,IAAIC,SAASvB,UAAU;IACzCwB,QAAQpC,SAASoC;IACjBC,YAAYrC,SAASqC;IACrBC,SAAStC,SAASsC;EACpB,CAAA;AAGA,OAAKJ,YAAYI;AAEjB,SAAO;IAACJ;IAAaF;;AACvB;AAzEgBjC;AA2ET,SAASwC,gBAAgBnC,MAAY;AAC1C,MAAIA,KAAKe,WAAW,GAAG;AACrB,WAAO;EACT;AACA,MAAI;AACF,WAAOqB,KAAKC,MAAMrC,KAAKsC,SAAQ,CAAA;EACjC,SAASb,OAAO;AACd,WAAO;EACT;AACF;AATgBU;","names":["captureResponse","response","captureBody","maxBodySize","readTimeout","body","Promise","resolve","size","completed","bodySizeLimitExceeded","readStarted","chunks","readable","writable","TransformStream","transform","chunk","controller","byteLength","length","push","enqueue","pipePromise","pipeTo","then","Buffer","concat","undefined","catch","error","timeoutPromise","setTimeout","racePromise","race","newResponse","Response","status","statusText","headers","getResponseJson","JSON","parse","toString"]}
@@ -1,7 +1,15 @@
1
- declare function measureResponseSize(response: Response, tee?: boolean): Promise<[number, Response]>;
2
- declare function getResponseBody(response: Response, tee?: boolean): Promise<[Buffer, Response]>;
3
- declare function getResponseJson(response: Response): Promise<[any, Response]>;
4
- declare function teeResponse(response: Response): [Response, Response];
5
- declare function teeResponseBlob(response: Response, blob: string | Blob): [Response, Response];
1
+ type CaptureResponseOptions = {
2
+ captureBody: boolean;
3
+ maxBodySize: number;
4
+ readTimeout: number;
5
+ };
6
+ type CapturedResponse = {
7
+ body?: Buffer;
8
+ size: number;
9
+ completed: boolean;
10
+ error?: Error;
11
+ };
12
+ declare function captureResponse(response: Response, { captureBody, maxBodySize, readTimeout, }?: Partial<CaptureResponseOptions>): [Response, Promise<CapturedResponse>];
13
+ declare function getResponseJson(body: Buffer): any;
6
14
 
7
- export { getResponseBody, getResponseJson, measureResponseSize, teeResponse, teeResponseBlob };
15
+ export { type CapturedResponse, captureResponse, getResponseJson };
@@ -1,7 +1,15 @@
1
- declare function measureResponseSize(response: Response, tee?: boolean): Promise<[number, Response]>;
2
- declare function getResponseBody(response: Response, tee?: boolean): Promise<[Buffer, Response]>;
3
- declare function getResponseJson(response: Response): Promise<[any, Response]>;
4
- declare function teeResponse(response: Response): [Response, Response];
5
- declare function teeResponseBlob(response: Response, blob: string | Blob): [Response, Response];
1
+ type CaptureResponseOptions = {
2
+ captureBody: boolean;
3
+ maxBodySize: number;
4
+ readTimeout: number;
5
+ };
6
+ type CapturedResponse = {
7
+ body?: Buffer;
8
+ size: number;
9
+ completed: boolean;
10
+ error?: Error;
11
+ };
12
+ declare function captureResponse(response: Response, { captureBody, maxBodySize, readTimeout, }?: Partial<CaptureResponseOptions>): [Response, Promise<CapturedResponse>];
13
+ declare function getResponseJson(body: Buffer): any;
6
14
 
7
- export { getResponseBody, getResponseJson, measureResponseSize, teeResponse, teeResponseBlob };
15
+ export { type CapturedResponse, captureResponse, getResponseJson };
@@ -1,119 +1,80 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
- async function measureResponseSize(response, tee = true) {
4
- const [newResponse1, newResponse2] = tee ? teeResponse(response) : [
5
- response,
6
- response
7
- ];
8
- let size = 0;
9
- if (newResponse2.body) {
10
- try {
11
- let done = false;
12
- const reader = newResponse2.body.getReader();
13
- while (!done) {
14
- const result = await reader.read();
15
- done = result.done;
16
- if (!done && result.value) {
17
- size += result.value.byteLength;
18
- }
19
- }
20
- } catch (error) {
21
- }
22
- }
23
- return [
24
- size,
25
- newResponse1
26
- ];
27
- }
28
- __name(measureResponseSize, "measureResponseSize");
29
- async function getResponseBody(response, tee = true) {
30
- const [newResponse1, newResponse2] = tee ? teeResponse(response) : [
31
- response,
32
- response
33
- ];
34
- try {
35
- const responseBuffer = Buffer.from(await newResponse2.arrayBuffer());
36
- return [
37
- responseBuffer,
38
- newResponse1
39
- ];
40
- } catch (error) {
41
- return [
42
- Buffer.from([]),
43
- newResponse1
44
- ];
45
- }
46
- }
47
- __name(getResponseBody, "getResponseBody");
48
- async function getResponseJson(response) {
49
- const contentType = response.headers.get("content-type");
50
- if (contentType == null ? void 0 : contentType.includes("application/json")) {
51
- const [newResponse1, newResponse2] = teeResponse(response);
52
- try {
53
- const responseJson = await newResponse2.json();
54
- return [
55
- responseJson,
56
- newResponse1
57
- ];
58
- } catch (error) {
59
- return [
60
- null,
61
- newResponse1
62
- ];
63
- }
64
- }
65
- return [
66
- null,
67
- response
68
- ];
69
- }
70
- __name(getResponseJson, "getResponseJson");
71
- function teeResponse(response) {
3
+ function captureResponse(response, { captureBody = false, maxBodySize = 0, readTimeout = 5e3 } = {}) {
72
4
  if (!response.body) {
73
5
  return [
74
6
  response,
75
- response
7
+ Promise.resolve({
8
+ size: 0,
9
+ completed: true
10
+ })
76
11
  ];
77
12
  }
78
- const [stream1, stream2] = response.body.tee();
79
- const newResponse1 = new Response(stream1, {
80
- status: response.status,
81
- statusText: response.statusText,
82
- headers: response.headers
13
+ let size = 0;
14
+ let bodySizeLimitExceeded = false;
15
+ let readStarted = false;
16
+ const chunks = [];
17
+ const { readable, writable } = new TransformStream({
18
+ transform: /* @__PURE__ */ __name((chunk, controller) => {
19
+ readStarted = true;
20
+ size += chunk.byteLength;
21
+ if (captureBody && !bodySizeLimitExceeded) {
22
+ if (size > maxBodySize) {
23
+ bodySizeLimitExceeded = true;
24
+ chunks.length = 0;
25
+ } else {
26
+ chunks.push(chunk);
27
+ }
28
+ }
29
+ controller.enqueue(chunk);
30
+ }, "transform")
83
31
  });
84
- const newResponse2 = new Response(stream2, {
32
+ const pipePromise = response.body.pipeTo(writable).then(() => ({
33
+ body: chunks.length > 0 ? Buffer.concat(chunks) : void 0,
34
+ size,
35
+ completed: true
36
+ })).catch((error) => ({
37
+ size,
38
+ completed: false,
39
+ error
40
+ }));
41
+ const timeoutPromise = new Promise((resolve) => setTimeout(() => {
42
+ if (!readStarted) {
43
+ resolve({
44
+ size: 0,
45
+ completed: false
46
+ });
47
+ }
48
+ }, readTimeout));
49
+ const racePromise = Promise.race([
50
+ pipePromise,
51
+ timeoutPromise
52
+ ]);
53
+ const newResponse = new Response(readable, {
85
54
  status: response.status,
86
55
  statusText: response.statusText,
87
56
  headers: response.headers
88
57
  });
58
+ void newResponse.headers;
89
59
  return [
90
- newResponse1,
91
- newResponse2
60
+ newResponse,
61
+ racePromise
92
62
  ];
93
63
  }
94
- __name(teeResponse, "teeResponse");
95
- function teeResponseBlob(response, blob) {
96
- const newResponse1 = new Response(blob, {
97
- status: response.status,
98
- statusText: response.statusText,
99
- headers: response.headers
100
- });
101
- const newResponse2 = new Response(blob, {
102
- status: response.status,
103
- statusText: response.statusText,
104
- headers: response.headers
105
- });
106
- return [
107
- newResponse1,
108
- newResponse2
109
- ];
64
+ __name(captureResponse, "captureResponse");
65
+ function getResponseJson(body) {
66
+ if (body.length === 0) {
67
+ return null;
68
+ }
69
+ try {
70
+ return JSON.parse(body.toString());
71
+ } catch (error) {
72
+ return null;
73
+ }
110
74
  }
111
- __name(teeResponseBlob, "teeResponseBlob");
75
+ __name(getResponseJson, "getResponseJson");
112
76
  export {
113
- getResponseBody,
114
- getResponseJson,
115
- measureResponseSize,
116
- teeResponse,
117
- teeResponseBlob
77
+ captureResponse,
78
+ getResponseJson
118
79
  };
119
80
  //# sourceMappingURL=response.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/common/response.ts"],"sourcesContent":["export async function measureResponseSize(\n response: Response,\n tee: boolean = true,\n): Promise<[number, Response]> {\n const [newResponse1, newResponse2] = tee\n ? teeResponse(response)\n : [response, response];\n let size = 0;\n if (newResponse2.body) {\n try {\n let done = false;\n const reader = newResponse2.body.getReader();\n while (!done) {\n const result = await reader.read();\n done = result.done;\n if (!done && result.value) {\n size += result.value.byteLength;\n }\n }\n } catch (error) {\n // ignore\n }\n }\n return [size, newResponse1];\n}\n\nexport async function getResponseBody(\n response: Response,\n tee: boolean = true,\n): Promise<[Buffer, Response]> {\n const [newResponse1, newResponse2] = tee\n ? teeResponse(response)\n : [response, response];\n try {\n const responseBuffer = Buffer.from(await newResponse2.arrayBuffer());\n return [responseBuffer, newResponse1];\n } catch (error) {\n return [Buffer.from([]), newResponse1];\n }\n}\n\nexport async function getResponseJson(\n response: Response,\n): Promise<[any, Response]> {\n const contentType = response.headers.get(\"content-type\");\n if (contentType?.includes(\"application/json\")) {\n const [newResponse1, newResponse2] = teeResponse(response);\n try {\n const responseJson = await newResponse2.json();\n return [responseJson, newResponse1];\n } catch (error) {\n return [null, newResponse1];\n }\n }\n return [null, response];\n}\n\nexport function teeResponse(response: Response): [Response, Response] {\n if (!response.body) {\n return [response, response];\n }\n const [stream1, stream2] = response.body.tee();\n const newResponse1 = new Response(stream1, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n const newResponse2 = new Response(stream2, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n return [newResponse1, newResponse2];\n}\n\nexport function teeResponseBlob(\n response: Response,\n blob: string | Blob,\n): [Response, Response] {\n const newResponse1 = new Response(blob, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n const newResponse2 = new Response(blob, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n return [newResponse1, newResponse2];\n}\n"],"mappings":";;AAAA,eAAsBA,oBACpBC,UACAC,MAAe,MAAI;AAEnB,QAAM,CAACC,cAAcC,YAAAA,IAAgBF,MACjCG,YAAYJ,QAAAA,IACZ;IAACA;IAAUA;;AACf,MAAIK,OAAO;AACX,MAAIF,aAAaG,MAAM;AACrB,QAAI;AACF,UAAIC,OAAO;AACX,YAAMC,SAASL,aAAaG,KAAKG,UAAS;AAC1C,aAAO,CAACF,MAAM;AACZ,cAAMG,SAAS,MAAMF,OAAOG,KAAI;AAChCJ,eAAOG,OAAOH;AACd,YAAI,CAACA,QAAQG,OAAOE,OAAO;AACzBP,kBAAQK,OAAOE,MAAMC;QACvB;MACF;IACF,SAASC,OAAO;IAEhB;EACF;AACA,SAAO;IAACT;IAAMH;;AAChB;AAxBsBH;AA0BtB,eAAsBgB,gBACpBf,UACAC,MAAe,MAAI;AAEnB,QAAM,CAACC,cAAcC,YAAAA,IAAgBF,MACjCG,YAAYJ,QAAAA,IACZ;IAACA;IAAUA;;AACf,MAAI;AACF,UAAMgB,iBAAiBC,OAAOC,KAAK,MAAMf,aAAagB,YAAW,CAAA;AACjE,WAAO;MAACH;MAAgBd;;EAC1B,SAASY,OAAO;AACd,WAAO;MAACG,OAAOC,KAAK,CAAA,CAAE;MAAGhB;;EAC3B;AACF;AAbsBa;AAetB,eAAsBK,gBACpBpB,UAAkB;AAElB,QAAMqB,cAAcrB,SAASsB,QAAQC,IAAI,cAAA;AACzC,MAAIF,2CAAaG,SAAS,qBAAqB;AAC7C,UAAM,CAACtB,cAAcC,YAAAA,IAAgBC,YAAYJ,QAAAA;AACjD,QAAI;AACF,YAAMyB,eAAe,MAAMtB,aAAauB,KAAI;AAC5C,aAAO;QAACD;QAAcvB;;IACxB,SAASY,OAAO;AACd,aAAO;QAAC;QAAMZ;;IAChB;EACF;AACA,SAAO;IAAC;IAAMF;;AAChB;AAdsBoB;AAgBf,SAAShB,YAAYJ,UAAkB;AAC5C,MAAI,CAACA,SAASM,MAAM;AAClB,WAAO;MAACN;MAAUA;;EACpB;AACA,QAAM,CAAC2B,SAASC,OAAAA,IAAW5B,SAASM,KAAKL,IAAG;AAC5C,QAAMC,eAAe,IAAI2B,SAASF,SAAS;IACzCG,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,QAAMnB,eAAe,IAAI0B,SAASD,SAAS;IACzCE,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,SAAO;IAACpB;IAAcC;;AACxB;AAhBgBC;AAkBT,SAAS4B,gBACdhC,UACAiC,MAAmB;AAEnB,QAAM/B,eAAe,IAAI2B,SAASI,MAAM;IACtCH,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,QAAMnB,eAAe,IAAI0B,SAASI,MAAM;IACtCH,QAAQ9B,SAAS8B;IACjBC,YAAY/B,SAAS+B;IACrBT,SAAStB,SAASsB;EACpB,CAAA;AACA,SAAO;IAACpB;IAAcC;;AACxB;AAfgB6B;","names":["measureResponseSize","response","tee","newResponse1","newResponse2","teeResponse","size","body","done","reader","getReader","result","read","value","byteLength","error","getResponseBody","responseBuffer","Buffer","from","arrayBuffer","getResponseJson","contentType","headers","get","includes","responseJson","json","stream1","stream2","Response","status","statusText","teeResponseBlob","blob"]}
1
+ {"version":3,"sources":["../../src/common/response.ts"],"sourcesContent":["type CaptureResponseOptions = {\n captureBody: boolean;\n maxBodySize: number;\n readTimeout: number;\n};\n\nexport type CapturedResponse = {\n body?: Buffer;\n size: number;\n completed: boolean;\n error?: Error;\n};\n\nexport function captureResponse(\n response: Response,\n {\n captureBody = false,\n maxBodySize = 0,\n readTimeout = 5000,\n }: Partial<CaptureResponseOptions> = {},\n): [Response, Promise<CapturedResponse>] {\n if (!response.body) {\n return [\n response,\n Promise.resolve({\n size: 0,\n completed: true,\n }),\n ];\n }\n\n let size = 0;\n let bodySizeLimitExceeded = false;\n let readStarted = false;\n const chunks: Uint8Array[] = [];\n\n const { readable, writable } = new TransformStream({\n transform: (chunk, controller) => {\n readStarted = true;\n size += chunk.byteLength;\n if (captureBody && !bodySizeLimitExceeded) {\n if (size > maxBodySize) {\n bodySizeLimitExceeded = true;\n chunks.length = 0;\n } else {\n chunks.push(chunk);\n }\n }\n controller.enqueue(chunk);\n },\n });\n\n const pipePromise = response.body\n .pipeTo(writable)\n .then(() => ({\n body: chunks.length > 0 ? Buffer.concat(chunks) : undefined,\n size,\n completed: true,\n }))\n .catch((error) => ({\n size,\n completed: false,\n error,\n }));\n const timeoutPromise = new Promise<CapturedResponse>((resolve) =>\n setTimeout(() => {\n if (!readStarted) {\n resolve({\n size: 0,\n completed: false,\n });\n }\n }, readTimeout),\n );\n const racePromise = Promise.race([pipePromise, timeoutPromise]);\n\n const newResponse = new Response(readable, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n\n // Force Bun to initialize the headers (workaround for lazy evaluation in Bun's Response implementation)\n void newResponse.headers;\n\n return [newResponse, racePromise];\n}\n\nexport function getResponseJson(body: Buffer) {\n if (body.length === 0) {\n return null;\n }\n try {\n return JSON.parse(body.toString());\n } catch (error) {\n return null;\n }\n}\n"],"mappings":";;AAaO,SAASA,gBACdC,UACA,EACEC,cAAc,OACdC,cAAc,GACdC,cAAc,IAAI,IACiB,CAAC,GAAC;AAEvC,MAAI,CAACH,SAASI,MAAM;AAClB,WAAO;MACLJ;MACAK,QAAQC,QAAQ;QACdC,MAAM;QACNC,WAAW;MACb,CAAA;;EAEJ;AAEA,MAAID,OAAO;AACX,MAAIE,wBAAwB;AAC5B,MAAIC,cAAc;AAClB,QAAMC,SAAuB,CAAA;AAE7B,QAAM,EAAEC,UAAUC,SAAQ,IAAK,IAAIC,gBAAgB;IACjDC,WAAW,wBAACC,OAAOC,eAAAA;AACjBP,oBAAc;AACdH,cAAQS,MAAME;AACd,UAAIjB,eAAe,CAACQ,uBAAuB;AACzC,YAAIF,OAAOL,aAAa;AACtBO,kCAAwB;AACxBE,iBAAOQ,SAAS;QAClB,OAAO;AACLR,iBAAOS,KAAKJ,KAAAA;QACd;MACF;AACAC,iBAAWI,QAAQL,KAAAA;IACrB,GAZW;EAab,CAAA;AAEA,QAAMM,cAActB,SAASI,KAC1BmB,OAAOV,QAAAA,EACPW,KAAK,OAAO;IACXpB,MAAMO,OAAOQ,SAAS,IAAIM,OAAOC,OAAOf,MAAAA,IAAUgB;IAClDpB;IACAC,WAAW;EACb,EAAA,EACCoB,MAAM,CAACC,WAAW;IACjBtB;IACAC,WAAW;IACXqB;EACF,EAAA;AACF,QAAMC,iBAAiB,IAAIzB,QAA0B,CAACC,YACpDyB,WAAW,MAAA;AACT,QAAI,CAACrB,aAAa;AAChBJ,cAAQ;QACNC,MAAM;QACNC,WAAW;MACb,CAAA;IACF;EACF,GAAGL,WAAAA,CAAAA;AAEL,QAAM6B,cAAc3B,QAAQ4B,KAAK;IAACX;IAAaQ;GAAe;AAE9D,QAAMI,cAAc,IAAIC,SAASvB,UAAU;IACzCwB,QAAQpC,SAASoC;IACjBC,YAAYrC,SAASqC;IACrBC,SAAStC,SAASsC;EACpB,CAAA;AAGA,OAAKJ,YAAYI;AAEjB,SAAO;IAACJ;IAAaF;;AACvB;AAzEgBjC;AA2ET,SAASwC,gBAAgBnC,MAAY;AAC1C,MAAIA,KAAKe,WAAW,GAAG;AACrB,WAAO;EACT;AACA,MAAI;AACF,WAAOqB,KAAKC,MAAMrC,KAAKsC,SAAQ,CAAA;EACjC,SAASb,OAAO;AACd,WAAO;EACT;AACF;AATgBU;","names":["captureResponse","response","captureBody","maxBodySize","readTimeout","body","Promise","resolve","size","completed","bodySizeLimitExceeded","readStarted","chunks","readable","writable","TransformStream","transform","chunk","controller","byteLength","length","push","enqueue","pipePromise","pipeTo","then","Buffer","concat","undefined","catch","error","timeoutPromise","setTimeout","racePromise","race","newResponse","Response","status","statusText","headers","getResponseJson","JSON","parse","toString"]}
@@ -35,7 +35,10 @@ module.exports = __toCommonJS(sentry_exports);
35
35
  let sentry;
36
36
  (async () => {
37
37
  try {
38
- sentry = await import("@sentry/node");
38
+ sentry = await import(
39
+ /* webpackIgnore: true */
40
+ "@sentry/node"
41
+ );
39
42
  } catch (e) {
40
43
  }
41
44
  })();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/common/sentry.ts"],"sourcesContent":["import type * as Sentry from \"@sentry/node\";\n\nlet sentry: typeof Sentry | undefined;\n\n// Initialize Sentry when the module is loaded\n(async () => {\n try {\n sentry = await import(\"@sentry/node\");\n } catch (e) {\n // Sentry SDK is not installed, ignore\n }\n})();\n\n/**\n * Returns the last Sentry event ID if available\n */\nexport function getSentryEventId(): string | undefined {\n if (sentry && sentry.lastEventId) {\n return sentry.lastEventId();\n }\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;;;;;AAAA,IAAIA;CAGH,YAAA;AACC,MAAI;AACFA,aAAS,MAAM,OAAO,cAAA;EACxB,SAASC,GAAG;EAEZ;AACF,GAAA;AAKO,SAASC,mBAAAA;AACd,MAAIF,UAAUA,OAAOG,aAAa;AAChC,WAAOH,OAAOG,YAAW;EAC3B;AACA,SAAOC;AACT;AALgBF;","names":["sentry","e","getSentryEventId","lastEventId","undefined"]}
1
+ {"version":3,"sources":["../../src/common/sentry.ts"],"sourcesContent":["import type * as Sentry from \"@sentry/node\";\n\nlet sentry: typeof Sentry | undefined;\n\n// Initialize Sentry when the module is loaded\n(async () => {\n try {\n sentry = await import(/* webpackIgnore: true */ \"@sentry/node\");\n } catch (e) {\n // Sentry SDK is not installed, ignore\n }\n})();\n\n/**\n * Returns the last Sentry event ID if available\n */\nexport function getSentryEventId(): string | undefined {\n if (sentry && sentry.lastEventId) {\n return sentry.lastEventId();\n }\n return undefined;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA;;;;;AAAA,IAAIA;CAGH,YAAA;AACC,MAAI;AACFA,aAAS,MAAM;;MAAiC;IAAA;EAClD,SAASC,GAAG;EAEZ;AACF,GAAA;AAKO,SAASC,mBAAAA;AACd,MAAIF,UAAUA,OAAOG,aAAa;AAChC,WAAOH,OAAOG,YAAW;EAC3B;AACA,SAAOC;AACT;AALgBF;","names":["sentry","e","getSentryEventId","lastEventId","undefined"]}
@@ -3,7 +3,10 @@ var __name = (target, value) => __defProp(target, "name", { value, configurable:
3
3
  let sentry;
4
4
  (async () => {
5
5
  try {
6
- sentry = await import("@sentry/node");
6
+ sentry = await import(
7
+ /* webpackIgnore: true */
8
+ "@sentry/node"
9
+ );
7
10
  } catch (e) {
8
11
  }
9
12
  })();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/common/sentry.ts"],"sourcesContent":["import type * as Sentry from \"@sentry/node\";\n\nlet sentry: typeof Sentry | undefined;\n\n// Initialize Sentry when the module is loaded\n(async () => {\n try {\n sentry = await import(\"@sentry/node\");\n } catch (e) {\n // Sentry SDK is not installed, ignore\n }\n})();\n\n/**\n * Returns the last Sentry event ID if available\n */\nexport function getSentryEventId(): string | undefined {\n if (sentry && sentry.lastEventId) {\n return sentry.lastEventId();\n }\n return undefined;\n}\n"],"mappings":";;AAEA,IAAIA;CAGH,YAAA;AACC,MAAI;AACFA,aAAS,MAAM,OAAO,cAAA;EACxB,SAASC,GAAG;EAEZ;AACF,GAAA;AAKO,SAASC,mBAAAA;AACd,MAAIF,UAAUA,OAAOG,aAAa;AAChC,WAAOH,OAAOG,YAAW;EAC3B;AACA,SAAOC;AACT;AALgBF;","names":["sentry","e","getSentryEventId","lastEventId","undefined"]}
1
+ {"version":3,"sources":["../../src/common/sentry.ts"],"sourcesContent":["import type * as Sentry from \"@sentry/node\";\n\nlet sentry: typeof Sentry | undefined;\n\n// Initialize Sentry when the module is loaded\n(async () => {\n try {\n sentry = await import(/* webpackIgnore: true */ \"@sentry/node\");\n } catch (e) {\n // Sentry SDK is not installed, ignore\n }\n})();\n\n/**\n * Returns the last Sentry event ID if available\n */\nexport function getSentryEventId(): string | undefined {\n if (sentry && sentry.lastEventId) {\n return sentry.lastEventId();\n }\n return undefined;\n}\n"],"mappings":";;AAEA,IAAIA;CAGH,YAAA;AACC,MAAI;AACFA,aAAS,MAAM;;MAAiC;IAAA;EAClD,SAASC,GAAG;EAEZ;AACF,GAAA;AAKO,SAASC,mBAAAA;AACd,MAAIF,UAAUA,OAAOG,aAAa;AAChC,WAAOH,OAAOG,YAAW;EAC3B;AACA,SAAOC;AACT;AALgBF;","names":["sentry","e","getSentryEventId","lastEventId","undefined"]}
@@ -7,3 +7,9 @@ import 'node:buffer';
7
7
  import 'node:http';
8
8
  import '../common/tempGzipFile.cjs';
9
9
  import 'elysia';
10
+ import '../common/client.cjs';
11
+ import '../common/consumerRegistry.cjs';
12
+ import '../common/requestCounter.cjs';
13
+ import '../common/serverErrorCounter.cjs';
14
+ import '../common/validationErrorCounter.cjs';
15
+ import '../common/response.cjs';
@@ -7,3 +7,9 @@ import 'node:buffer';
7
7
  import 'node:http';
8
8
  import '../common/tempGzipFile.js';
9
9
  import 'elysia';
10
+ import '../common/client.js';
11
+ import '../common/consumerRegistry.js';
12
+ import '../common/requestCounter.js';
13
+ import '../common/serverErrorCounter.js';
14
+ import '../common/validationErrorCounter.js';
15
+ import '../common/response.js';
@@ -35,7 +35,9 @@ var import_utils = require("./utils.js");
35
35
  const START_TIME_SYMBOL = Symbol("apitally.startTime");
36
36
  const REQUEST_BODY_SYMBOL = Symbol("apitally.requestBody");
37
37
  const RESPONSE_SYMBOL = Symbol("apitally.response");
38
+ const RESPONSE_PROMISE_SYMBOL = Symbol("apitally.responsePromise");
38
39
  const ERROR_SYMBOL = Symbol("apitally.error");
40
+ const CLIENT_SYMBOL = Symbol("apitally.client");
39
41
  function apitallyPlugin(config) {
40
42
  const client = new import_client.ApitallyClient(config);
41
43
  const logsContext = new import_node_async_hooks.AsyncLocalStorage();
@@ -45,34 +47,49 @@ function apitallyPlugin(config) {
45
47
  }
46
48
  return (app) => {
47
49
  const handler = app["~adapter"].handler;
48
- const originalMapResponse = handler.mapResponse;
49
- const originalMapCompactResponse = handler.mapCompactResponse;
50
- const originalMapEarlyResponse = handler.mapEarlyResponse;
51
- const captureResponse = /* @__PURE__ */ __name((originalResponse, mappedResponse, request) => {
52
- var _a;
53
- if (request instanceof Request && mappedResponse instanceof Response && !(RESPONSE_SYMBOL in request)) {
54
- const [newResponse1, newResponse2] = ((_a = originalResponse == null ? void 0 : originalResponse.constructor) == null ? void 0 : _a.name) === "String" ? (0, import_response.teeResponseBlob)(mappedResponse, originalResponse) : (0, import_response.teeResponse)(mappedResponse);
55
- request[RESPONSE_SYMBOL] = newResponse2;
56
- return newResponse1;
57
- } else {
50
+ if (!handler.mapResponse.name.startsWith("wrapped")) {
51
+ const originalMapResponse = handler.mapResponse;
52
+ const originalMapCompactResponse = handler.mapCompactResponse;
53
+ const originalMapEarlyResponse = handler.mapEarlyResponse;
54
+ const captureMappedResponse = /* @__PURE__ */ __name((originalResponse, mappedResponse, request) => {
55
+ if (request instanceof Request && mappedResponse instanceof Response && !(RESPONSE_SYMBOL in request) && CLIENT_SYMBOL in request) {
56
+ if (typeof originalResponse === "string") {
57
+ const responseBody = Buffer.from(originalResponse);
58
+ request[RESPONSE_SYMBOL] = mappedResponse;
59
+ request[RESPONSE_PROMISE_SYMBOL] = Promise.resolve({
60
+ body: responseBody,
61
+ size: responseBody.length,
62
+ completed: true
63
+ });
64
+ } else {
65
+ const client2 = request[CLIENT_SYMBOL];
66
+ const [newResponse, responsePromise] = (0, import_response.captureResponse)(mappedResponse, {
67
+ captureBody: client2.requestLogger.enabled && client2.requestLogger.config.logResponseBody,
68
+ maxBodySize: client2.requestLogger.maxBodySize
69
+ });
70
+ request[RESPONSE_SYMBOL] = newResponse;
71
+ request[RESPONSE_PROMISE_SYMBOL] = responsePromise;
72
+ return newResponse;
73
+ }
74
+ }
58
75
  return mappedResponse;
59
- }
60
- }, "captureResponse");
61
- handler.mapResponse = /* @__PURE__ */ __name(function wrappedMapResponse(response, set, request) {
62
- const mappedResponse = originalMapResponse(response, set, request);
63
- const newResponse = captureResponse(response, mappedResponse, request);
64
- return newResponse;
65
- }, "wrappedMapResponse");
66
- handler.mapCompactResponse = /* @__PURE__ */ __name(function wrappedMapCompactResponse(response, request) {
67
- const mappedResponse = originalMapCompactResponse(response, request);
68
- const newResponse = captureResponse(response, mappedResponse, request);
69
- return newResponse;
70
- }, "wrappedMapCompactResponse");
71
- handler.mapEarlyResponse = /* @__PURE__ */ __name(function wrappedMapEarlyResponse(response, set, request) {
72
- const mappedResponse = originalMapEarlyResponse(response, set, request);
73
- const newResponse = captureResponse(response, mappedResponse, request);
74
- return newResponse;
75
- }, "wrappedMapEarlyResponse");
76
+ }, "captureMappedResponse");
77
+ handler.mapResponse = /* @__PURE__ */ __name(function wrappedMapResponse(response, set, request) {
78
+ const mappedResponse = originalMapResponse(response, set, request);
79
+ const newResponse = captureMappedResponse(response, mappedResponse, request);
80
+ return newResponse;
81
+ }, "wrappedMapResponse");
82
+ handler.mapCompactResponse = /* @__PURE__ */ __name(function wrappedMapCompactResponse(response, request) {
83
+ const mappedResponse = originalMapCompactResponse(response, request);
84
+ const newResponse = captureMappedResponse(response, mappedResponse, request);
85
+ return newResponse;
86
+ }, "wrappedMapCompactResponse");
87
+ handler.mapEarlyResponse = /* @__PURE__ */ __name(function wrappedMapEarlyResponse(response, set, request) {
88
+ const mappedResponse = originalMapEarlyResponse(response, set, request);
89
+ const newResponse = captureMappedResponse(response, mappedResponse, request);
90
+ return newResponse;
91
+ }, "wrappedMapEarlyResponse");
92
+ }
76
93
  return app.decorate("apitally", {}).onStart(() => {
77
94
  const appInfo = (0, import_utils.getAppInfo)(app, config.appVersion);
78
95
  client.setStartupData(appInfo);
@@ -83,8 +100,9 @@ function apitallyPlugin(config) {
83
100
  if (!client.isEnabled() || request.method.toUpperCase() === "OPTIONS") {
84
101
  return;
85
102
  }
86
- logsContext.enterWith([]);
103
+ request[CLIENT_SYMBOL] = client;
87
104
  request[START_TIME_SYMBOL] = import_node_perf_hooks.performance.now();
105
+ logsContext.enterWith([]);
88
106
  if (client.requestLogger.enabled && client.requestLogger.config.logRequestBody) {
89
107
  const contentType = request.headers.get("content-type");
90
108
  const requestSize = (0, import_headers.parseContentLength)(request.headers.get("content-length")) ?? 0;
@@ -103,29 +121,39 @@ function apitallyPlugin(config) {
103
121
  const responseTime = startTime ? import_node_perf_hooks.performance.now() - startTime : 0;
104
122
  const requestBody = request[REQUEST_BODY_SYMBOL];
105
123
  const requestSize = (0, import_headers.parseContentLength)(request.headers.get("content-length")) ?? (requestBody == null ? void 0 : requestBody.length);
106
- const error = request[ERROR_SYMBOL];
124
+ let responsePromise = request[RESPONSE_PROMISE_SYMBOL];
107
125
  let response = request[RESPONSE_SYMBOL];
108
- let responseBody;
109
- let responseSize;
126
+ const error = request[ERROR_SYMBOL];
110
127
  if (!response && error && "toResponse" in error && typeof error.toResponse === "function") {
111
128
  try {
112
129
  response = error.toResponse();
130
+ const errorResponseBody = Buffer.from(await response.arrayBuffer());
131
+ responsePromise = Promise.resolve({
132
+ body: errorResponseBody,
133
+ size: errorResponseBody.length,
134
+ completed: true
135
+ });
113
136
  } catch (error2) {
114
137
  }
115
138
  }
116
- if (response instanceof Response) {
117
- if (client.requestLogger.enabled && client.requestLogger.config.logResponseBody && client.requestLogger.isSupportedContentType(response.headers.get("content-type"))) {
118
- responseBody = (await (0, import_response.getResponseBody)(response, false))[0];
119
- responseSize = responseBody.length;
120
- } else {
121
- responseSize = (await (0, import_response.measureResponseSize)(response, false))[0];
122
- }
123
- }
124
139
  const statusCode = (response == null ? void 0 : response.status) ?? getStatusCode(set) ?? 200;
125
- const responseHeaders = (response == null ? void 0 : response.headers) ?? set.headers;
140
+ if (!response) {
141
+ response = new Response(null, {
142
+ status: statusCode,
143
+ statusText: "",
144
+ headers: new Headers()
145
+ });
146
+ responsePromise = Promise.resolve({
147
+ body: void 0,
148
+ size: 0,
149
+ completed: true
150
+ });
151
+ }
126
152
  const consumer = apitally.consumer ? (0, import_consumerRegistry.consumerFromStringOrObject)(apitally.consumer) : null;
127
153
  client.consumerRegistry.addOrUpdateConsumer(consumer);
128
- if (route) {
154
+ responsePromise == null ? void 0 : responsePromise.then(async (capturedResponse) => {
155
+ const responseHeaders = (response == null ? void 0 : response.headers) ?? set.headers;
156
+ const responseSize = capturedResponse.completed ? capturedResponse.size : void 0;
129
157
  client.requestCounter.addRequest({
130
158
  consumer: consumer == null ? void 0 : consumer.identifier,
131
159
  method: request.method,
@@ -135,49 +163,49 @@ function apitallyPlugin(config) {
135
163
  requestSize,
136
164
  responseSize
137
165
  });
138
- if (statusCode === 500 && error) {
139
- client.serverErrorCounter.addServerError({
166
+ if (client.requestLogger.enabled) {
167
+ const logs = logsContext.getStore();
168
+ client.requestLogger.logRequest({
169
+ timestamp: (Date.now() - responseTime) / 1e3,
170
+ method: request.method,
171
+ path: route,
172
+ url: request.url,
173
+ headers: (0, import_requestLogger.convertHeaders)(Object.fromEntries(request.headers.entries())),
174
+ size: requestSize,
175
+ consumer: consumer == null ? void 0 : consumer.identifier,
176
+ body: requestBody
177
+ }, {
178
+ statusCode,
179
+ responseTime: responseTime / 1e3,
180
+ headers: (0, import_requestLogger.convertHeaders)(responseHeaders),
181
+ size: responseSize,
182
+ body: capturedResponse.body
183
+ }, error, logs);
184
+ }
185
+ });
186
+ if ((statusCode === 400 || statusCode === 422) && error instanceof import_elysia.ValidationError) {
187
+ try {
188
+ const parsedMessage = JSON.parse(error.message);
189
+ client.validationErrorCounter.addValidationError({
140
190
  consumer: consumer == null ? void 0 : consumer.identifier,
141
191
  method: request.method,
142
192
  path: route,
143
- type: error.name,
144
- msg: error.message,
145
- traceback: error.stack || ""
193
+ loc: (parsedMessage.on ?? "") + "." + (parsedMessage.property ?? ""),
194
+ msg: parsedMessage.message,
195
+ type: ""
146
196
  });
147
- }
148
- if ((statusCode === 400 || statusCode === 422) && error instanceof import_elysia.ValidationError) {
149
- try {
150
- const parsedMessage = JSON.parse(error.message);
151
- client.validationErrorCounter.addValidationError({
152
- consumer: consumer == null ? void 0 : consumer.identifier,
153
- method: request.method,
154
- path: route,
155
- loc: (parsedMessage.on ?? "") + "." + (parsedMessage.property ?? ""),
156
- msg: parsedMessage.message,
157
- type: ""
158
- });
159
- } catch (error2) {
160
- }
197
+ } catch (error2) {
161
198
  }
162
199
  }
163
- if (client.requestLogger.enabled) {
164
- const logs = logsContext.getStore();
165
- client.requestLogger.logRequest({
166
- timestamp: (Date.now() - responseTime) / 1e3,
200
+ if (statusCode === 500 && error) {
201
+ client.serverErrorCounter.addServerError({
202
+ consumer: consumer == null ? void 0 : consumer.identifier,
167
203
  method: request.method,
168
204
  path: route,
169
- url: request.url,
170
- headers: (0, import_requestLogger.convertHeaders)(Object.fromEntries(request.headers.entries())),
171
- size: requestSize,
172
- consumer: consumer == null ? void 0 : consumer.identifier,
173
- body: requestBody
174
- }, {
175
- statusCode,
176
- responseTime: responseTime / 1e3,
177
- headers: (0, import_requestLogger.convertHeaders)(responseHeaders),
178
- size: responseSize,
179
- body: responseBody
180
- }, error, logs);
205
+ type: error.name,
206
+ msg: error.message,
207
+ traceback: error.stack || ""
208
+ });
181
209
  }
182
210
  }).onError(({ request, error }) => {
183
211
  if (client.isEnabled() && error instanceof Error) {