apitally 0.11.5 → 0.12.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.
Files changed (60) hide show
  1. package/README.md +2 -2
  2. package/dist/common/client.cjs +116 -105
  3. package/dist/common/client.cjs.map +1 -1
  4. package/dist/common/client.js +111 -100
  5. package/dist/common/client.js.map +1 -1
  6. package/dist/common/requestLogger.cjs +55 -2
  7. package/dist/common/requestLogger.cjs.map +1 -1
  8. package/dist/common/requestLogger.d.cts +2 -1
  9. package/dist/common/requestLogger.d.ts +2 -1
  10. package/dist/common/requestLogger.js +55 -2
  11. package/dist/common/requestLogger.js.map +1 -1
  12. package/dist/common/sentry.cjs +55 -0
  13. package/dist/common/sentry.cjs.map +1 -0
  14. package/dist/common/sentry.d.cts +6 -0
  15. package/dist/common/sentry.d.ts +6 -0
  16. package/dist/common/sentry.js +22 -0
  17. package/dist/common/sentry.js.map +1 -0
  18. package/dist/common/serverErrorCounter.cjs +58 -45
  19. package/dist/common/serverErrorCounter.cjs.map +1 -1
  20. package/dist/common/serverErrorCounter.d.cts +3 -6
  21. package/dist/common/serverErrorCounter.d.ts +3 -6
  22. package/dist/common/serverErrorCounter.js +53 -45
  23. package/dist/common/serverErrorCounter.js.map +1 -1
  24. package/dist/express/index.cjs +117 -106
  25. package/dist/express/index.cjs.map +1 -1
  26. package/dist/express/index.js +112 -101
  27. package/dist/express/index.js.map +1 -1
  28. package/dist/express/middleware.cjs +117 -106
  29. package/dist/express/middleware.cjs.map +1 -1
  30. package/dist/express/middleware.js +112 -101
  31. package/dist/express/middleware.js.map +1 -1
  32. package/dist/fastify/index.cjs +117 -106
  33. package/dist/fastify/index.cjs.map +1 -1
  34. package/dist/fastify/index.js +112 -101
  35. package/dist/fastify/index.js.map +1 -1
  36. package/dist/fastify/plugin.cjs +117 -106
  37. package/dist/fastify/plugin.cjs.map +1 -1
  38. package/dist/fastify/plugin.js +112 -101
  39. package/dist/fastify/plugin.js.map +1 -1
  40. package/dist/hono/index.cjs +117 -106
  41. package/dist/hono/index.cjs.map +1 -1
  42. package/dist/hono/index.js +112 -101
  43. package/dist/hono/index.js.map +1 -1
  44. package/dist/hono/middleware.cjs +117 -106
  45. package/dist/hono/middleware.cjs.map +1 -1
  46. package/dist/hono/middleware.js +112 -101
  47. package/dist/hono/middleware.js.map +1 -1
  48. package/dist/koa/index.cjs +119 -106
  49. package/dist/koa/index.cjs.map +1 -1
  50. package/dist/koa/index.js +114 -101
  51. package/dist/koa/index.js.map +1 -1
  52. package/dist/koa/middleware.cjs +119 -106
  53. package/dist/koa/middleware.cjs.map +1 -1
  54. package/dist/koa/middleware.js +114 -101
  55. package/dist/koa/middleware.js.map +1 -1
  56. package/dist/nestjs/index.cjs +117 -106
  57. package/dist/nestjs/index.cjs.map +1 -1
  58. package/dist/nestjs/index.js +112 -101
  59. package/dist/nestjs/index.js.map +1 -1
  60. package/package.json +1 -1
package/dist/koa/index.js CHANGED
@@ -187,6 +187,108 @@ import { unlinkSync as unlinkSync2, writeFileSync } from "fs";
187
187
  import { tmpdir as tmpdir2 } from "os";
188
188
  import { join as join2 } from "path";
189
189
 
190
+ // src/common/sentry.ts
191
+ var sentry;
192
+ (async () => {
193
+ try {
194
+ sentry = await import("@sentry/node");
195
+ } catch (e) {
196
+ }
197
+ })();
198
+ function getSentryEventId() {
199
+ if (sentry && sentry.lastEventId) {
200
+ return sentry.lastEventId();
201
+ }
202
+ return void 0;
203
+ }
204
+ __name(getSentryEventId, "getSentryEventId");
205
+
206
+ // src/common/serverErrorCounter.ts
207
+ import { createHash } from "crypto";
208
+ var MAX_MSG_LENGTH = 2048;
209
+ var MAX_STACKTRACE_LENGTH = 65536;
210
+ var _ServerErrorCounter = class _ServerErrorCounter {
211
+ errorCounts;
212
+ errorDetails;
213
+ sentryEventIds;
214
+ constructor() {
215
+ this.errorCounts = /* @__PURE__ */ new Map();
216
+ this.errorDetails = /* @__PURE__ */ new Map();
217
+ this.sentryEventIds = /* @__PURE__ */ new Map();
218
+ }
219
+ addServerError(serverError) {
220
+ const key = this.getKey(serverError);
221
+ if (!this.errorDetails.has(key)) {
222
+ this.errorDetails.set(key, serverError);
223
+ }
224
+ this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
225
+ const sentryEventId = getSentryEventId();
226
+ if (sentryEventId) {
227
+ this.sentryEventIds.set(key, sentryEventId);
228
+ }
229
+ }
230
+ getAndResetServerErrors() {
231
+ const data = [];
232
+ this.errorCounts.forEach((count, key) => {
233
+ const serverError = this.errorDetails.get(key);
234
+ if (serverError) {
235
+ data.push({
236
+ consumer: serverError.consumer || null,
237
+ method: serverError.method,
238
+ path: serverError.path,
239
+ type: serverError.type,
240
+ msg: truncateExceptionMessage(serverError.msg),
241
+ traceback: truncateExceptionStackTrace(serverError.traceback),
242
+ sentry_event_id: this.sentryEventIds.get(key) || null,
243
+ error_count: count
244
+ });
245
+ }
246
+ });
247
+ this.errorCounts.clear();
248
+ this.errorDetails.clear();
249
+ return data;
250
+ }
251
+ getKey(serverError) {
252
+ const hashInput = [
253
+ serverError.consumer || "",
254
+ serverError.method.toUpperCase(),
255
+ serverError.path,
256
+ serverError.type,
257
+ serverError.msg.trim(),
258
+ serverError.traceback.trim()
259
+ ].join("|");
260
+ return createHash("md5").update(hashInput).digest("hex");
261
+ }
262
+ };
263
+ __name(_ServerErrorCounter, "ServerErrorCounter");
264
+ var ServerErrorCounter = _ServerErrorCounter;
265
+ function truncateExceptionMessage(msg) {
266
+ if (msg.length <= MAX_MSG_LENGTH) {
267
+ return msg;
268
+ }
269
+ const suffix = "... (truncated)";
270
+ const cutoff = MAX_MSG_LENGTH - suffix.length;
271
+ return msg.substring(0, cutoff) + suffix;
272
+ }
273
+ __name(truncateExceptionMessage, "truncateExceptionMessage");
274
+ function truncateExceptionStackTrace(stack) {
275
+ const suffix = "... (truncated) ...";
276
+ const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
277
+ const lines = stack.trim().split("\n");
278
+ const truncatedLines = [];
279
+ let length = 0;
280
+ for (const line of lines) {
281
+ if (length + line.length + 1 > cutoff) {
282
+ truncatedLines.push(suffix);
283
+ break;
284
+ }
285
+ truncatedLines.push(line);
286
+ length += line.length + 1;
287
+ }
288
+ return truncatedLines.join("\n");
289
+ }
290
+ __name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
291
+
190
292
  // src/common/tempGzipFile.ts
191
293
  import { Buffer as Buffer2 } from "buffer";
192
294
  import { randomUUID } from "crypto";
@@ -309,6 +411,7 @@ var DEFAULT_CONFIG = {
309
411
  logRequestBody: false,
310
412
  logResponseHeaders: true,
311
413
  logResponseBody: false,
414
+ logException: true,
312
415
  maskQueryParams: [],
313
416
  maskHeaders: [],
314
417
  excludePaths: []
@@ -381,7 +484,7 @@ var _RequestLogger = class _RequestLogger {
381
484
  this.shouldMaskHeader(k) ? MASKED : v
382
485
  ]);
383
486
  }
384
- logRequest(request, response) {
487
+ logRequest(request, response, error) {
385
488
  var _a2, _b, _c;
386
489
  if (!this.enabled || this.suspendUntil !== null) return;
387
490
  const url = new URL(request.url);
@@ -429,7 +532,13 @@ var _RequestLogger = class _RequestLogger {
429
532
  const item = {
430
533
  uuid: randomUUID2(),
431
534
  request: skipEmptyValues(request),
432
- response: skipEmptyValues(response)
535
+ response: skipEmptyValues(response),
536
+ exception: error && this.config.logException ? {
537
+ type: error.name,
538
+ message: truncateExceptionMessage(error.message),
539
+ stacktrace: truncateExceptionStackTrace(error.stack || ""),
540
+ sentryEventId: getSentryEventId()
541
+ } : null
433
542
  };
434
543
  [
435
544
  item.request.body,
@@ -591,104 +700,6 @@ function checkWritableFs() {
591
700
  }
592
701
  __name(checkWritableFs, "checkWritableFs");
593
702
 
594
- // src/common/serverErrorCounter.ts
595
- import { createHash } from "crypto";
596
- var MAX_MSG_LENGTH = 2048;
597
- var MAX_STACKTRACE_LENGTH = 65536;
598
- var _ServerErrorCounter = class _ServerErrorCounter {
599
- errorCounts;
600
- errorDetails;
601
- sentryEventIds;
602
- sentry;
603
- constructor() {
604
- this.errorCounts = /* @__PURE__ */ new Map();
605
- this.errorDetails = /* @__PURE__ */ new Map();
606
- this.sentryEventIds = /* @__PURE__ */ new Map();
607
- this.tryImportSentry();
608
- }
609
- addServerError(serverError) {
610
- const key = this.getKey(serverError);
611
- if (!this.errorDetails.has(key)) {
612
- this.errorDetails.set(key, serverError);
613
- }
614
- this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
615
- this.captureSentryEventId(key);
616
- }
617
- getAndResetServerErrors() {
618
- const data = [];
619
- this.errorCounts.forEach((count, key) => {
620
- const serverError = this.errorDetails.get(key);
621
- if (serverError) {
622
- data.push({
623
- consumer: serverError.consumer || null,
624
- method: serverError.method,
625
- path: serverError.path,
626
- type: serverError.type,
627
- msg: this.getTruncatedMessage(serverError.msg),
628
- traceback: this.getTruncatedStack(serverError.traceback),
629
- sentry_event_id: this.sentryEventIds.get(key) || null,
630
- error_count: count
631
- });
632
- }
633
- });
634
- this.errorCounts.clear();
635
- this.errorDetails.clear();
636
- return data;
637
- }
638
- getKey(serverError) {
639
- const hashInput = [
640
- serverError.consumer || "",
641
- serverError.method.toUpperCase(),
642
- serverError.path,
643
- serverError.type,
644
- serverError.msg.trim(),
645
- serverError.traceback.trim()
646
- ].join("|");
647
- return createHash("md5").update(hashInput).digest("hex");
648
- }
649
- getTruncatedMessage(msg) {
650
- msg = msg.trim();
651
- if (msg.length <= MAX_MSG_LENGTH) {
652
- return msg;
653
- }
654
- const suffix = "... (truncated)";
655
- const cutoff = MAX_MSG_LENGTH - suffix.length;
656
- return msg.substring(0, cutoff) + suffix;
657
- }
658
- getTruncatedStack(stack) {
659
- const suffix = "... (truncated) ...";
660
- const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
661
- const lines = stack.trim().split("\n");
662
- const truncatedLines = [];
663
- let length = 0;
664
- for (const line of lines) {
665
- if (length + line.length + 1 > cutoff) {
666
- truncatedLines.push(suffix);
667
- break;
668
- }
669
- truncatedLines.push(line);
670
- length += line.length + 1;
671
- }
672
- return truncatedLines.join("\n");
673
- }
674
- captureSentryEventId(serverErrorKey) {
675
- if (this.sentry && this.sentry.lastEventId) {
676
- const eventId = this.sentry.lastEventId();
677
- if (eventId) {
678
- this.sentryEventIds.set(serverErrorKey, eventId);
679
- }
680
- }
681
- }
682
- async tryImportSentry() {
683
- try {
684
- this.sentry = await import("@sentry/node");
685
- } catch (e) {
686
- }
687
- }
688
- };
689
- __name(_ServerErrorCounter, "ServerErrorCounter");
690
- var ServerErrorCounter = _ServerErrorCounter;
691
-
692
703
  // src/common/validationErrorCounter.ts
693
704
  import { createHash as createHash2 } from "crypto";
694
705
  var _ValidationErrorCounter = class _ValidationErrorCounter {
@@ -1047,6 +1058,7 @@ var getMiddleware = /* @__PURE__ */ __name((client) => {
1047
1058
  }
1048
1059
  let path;
1049
1060
  let statusCode;
1061
+ let serverError;
1050
1062
  const startTime = performance.now();
1051
1063
  try {
1052
1064
  await next();
@@ -1054,6 +1066,7 @@ var getMiddleware = /* @__PURE__ */ __name((client) => {
1054
1066
  path = getPath(ctx);
1055
1067
  statusCode = error.statusCode || error.status || 500;
1056
1068
  if (path && statusCode === 500 && error instanceof Error) {
1069
+ serverError = error;
1057
1070
  client.serverErrorCounter.addServerError({
1058
1071
  consumer: (_a2 = getConsumer(ctx)) == null ? void 0 : _a2.identifier,
1059
1072
  method: ctx.request.method,
@@ -1105,7 +1118,7 @@ var getMiddleware = /* @__PURE__ */ __name((client) => {
1105
1118
  headers: convertHeaders(ctx.response.headers),
1106
1119
  size: Number(ctx.response.headers["content-length"]),
1107
1120
  body: convertBody(ctx.response.body, ctx.response.get("content-type"))
1108
- });
1121
+ }, serverError);
1109
1122
  }
1110
1123
  }
1111
1124
  };