apitally 0.6.0 → 0.7.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 (198) hide show
  1. package/dist/common/client.cjs +514 -0
  2. package/dist/common/client.cjs.map +1 -0
  3. package/dist/common/client.d.cts +36 -0
  4. package/{lib/types → dist}/common/client.d.ts +13 -9
  5. package/dist/common/client.js +481 -0
  6. package/dist/common/client.js.map +1 -0
  7. package/dist/common/logging.cjs +41 -0
  8. package/dist/common/logging.cjs.map +1 -0
  9. package/dist/common/logging.d.cts +11 -0
  10. package/{lib/types → dist}/common/logging.d.ts +6 -3
  11. package/dist/common/logging.js +18 -0
  12. package/dist/common/logging.js.map +1 -0
  13. package/dist/common/packageVersions.cjs +42 -0
  14. package/dist/common/packageVersions.cjs.map +1 -0
  15. package/dist/common/packageVersions.d.cts +3 -0
  16. package/dist/common/packageVersions.d.ts +3 -0
  17. package/dist/common/packageVersions.js +18 -0
  18. package/dist/common/packageVersions.js.map +1 -0
  19. package/dist/common/paramValidation.cjs +43 -0
  20. package/dist/common/paramValidation.cjs.map +1 -0
  21. package/dist/common/paramValidation.d.cts +4 -0
  22. package/dist/common/paramValidation.d.ts +4 -0
  23. package/dist/common/paramValidation.js +19 -0
  24. package/dist/common/paramValidation.js.map +1 -0
  25. package/dist/common/requestCounter.cjs +111 -0
  26. package/dist/common/requestCounter.cjs.map +1 -0
  27. package/dist/common/requestCounter.d.cts +18 -0
  28. package/{lib/types → dist}/common/requestCounter.d.ts +7 -3
  29. package/dist/common/requestCounter.js +92 -0
  30. package/dist/common/requestCounter.js.map +1 -0
  31. package/dist/common/serverErrorCounter.cjs +133 -0
  32. package/dist/common/serverErrorCounter.cjs.map +1 -0
  33. package/dist/common/serverErrorCounter.d.cts +20 -0
  34. package/{lib/types → dist}/common/serverErrorCounter.d.ts +7 -3
  35. package/dist/common/serverErrorCounter.js +104 -0
  36. package/dist/common/serverErrorCounter.js.map +1 -0
  37. package/dist/common/types.cjs +19 -0
  38. package/dist/common/types.cjs.map +1 -0
  39. package/dist/common/types.d.cts +76 -0
  40. package/{lib/types → dist}/common/types.d.ts +17 -14
  41. package/dist/common/types.js +1 -0
  42. package/dist/common/types.js.map +1 -0
  43. package/dist/common/validationErrorCounter.cjs +76 -0
  44. package/dist/common/validationErrorCounter.cjs.map +1 -0
  45. package/dist/common/validationErrorCounter.d.cts +14 -0
  46. package/{lib/types → dist}/common/validationErrorCounter.d.ts +7 -3
  47. package/dist/common/validationErrorCounter.js +57 -0
  48. package/dist/common/validationErrorCounter.js.map +1 -0
  49. package/dist/express/index.cjs +837 -0
  50. package/dist/express/index.cjs.map +1 -0
  51. package/dist/express/index.d.cts +5 -0
  52. package/dist/express/index.d.ts +5 -0
  53. package/dist/express/index.js +801 -0
  54. package/dist/express/index.js.map +1 -0
  55. package/dist/express/listEndpoints.cjs +144 -0
  56. package/dist/express/listEndpoints.cjs.map +1 -0
  57. package/dist/express/listEndpoints.d.cts +3 -0
  58. package/dist/express/listEndpoints.d.ts +3 -0
  59. package/dist/express/listEndpoints.js +125 -0
  60. package/dist/express/listEndpoints.js.map +1 -0
  61. package/dist/express/middleware.cjs +835 -0
  62. package/dist/express/middleware.cjs.map +1 -0
  63. package/dist/express/middleware.d.cts +14 -0
  64. package/dist/express/middleware.d.ts +14 -0
  65. package/dist/express/middleware.js +801 -0
  66. package/dist/express/middleware.js.map +1 -0
  67. package/dist/fastify/index.cjs +685 -0
  68. package/dist/fastify/index.cjs.map +1 -0
  69. package/dist/fastify/index.d.cts +5 -0
  70. package/dist/fastify/index.d.ts +5 -0
  71. package/dist/fastify/index.js +649 -0
  72. package/dist/fastify/index.js.map +1 -0
  73. package/dist/fastify/plugin.cjs +679 -0
  74. package/dist/fastify/plugin.cjs.map +1 -0
  75. package/dist/fastify/plugin.d.cts +18 -0
  76. package/{lib/types → dist}/fastify/plugin.d.ts +7 -4
  77. package/dist/fastify/plugin.js +649 -0
  78. package/dist/fastify/plugin.js.map +1 -0
  79. package/dist/index.cjs +2 -0
  80. package/dist/index.cjs.map +1 -0
  81. package/dist/index.d.cts +2 -0
  82. package/dist/index.d.ts +2 -0
  83. package/dist/index.js +1 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/koa/index.cjs +655 -0
  86. package/dist/koa/index.cjs.map +1 -0
  87. package/dist/koa/index.d.cts +5 -0
  88. package/dist/koa/index.d.ts +5 -0
  89. package/dist/koa/index.js +619 -0
  90. package/dist/koa/index.js.map +1 -0
  91. package/dist/koa/middleware.cjs +655 -0
  92. package/dist/koa/middleware.cjs.map +1 -0
  93. package/dist/koa/middleware.d.cts +8 -0
  94. package/dist/koa/middleware.d.ts +8 -0
  95. package/dist/koa/middleware.js +619 -0
  96. package/dist/koa/middleware.js.map +1 -0
  97. package/dist/nestjs/index.cjs +837 -0
  98. package/dist/nestjs/index.cjs.map +1 -0
  99. package/dist/nestjs/index.d.cts +5 -0
  100. package/dist/nestjs/index.d.ts +5 -0
  101. package/dist/nestjs/index.js +801 -0
  102. package/dist/nestjs/index.js.map +1 -0
  103. package/package.json +55 -92
  104. package/lib/cjs/common/client.cjs +0 -323
  105. package/lib/cjs/common/client.cjs.map +0 -1
  106. package/lib/cjs/common/logging.cjs +0 -17
  107. package/lib/cjs/common/logging.cjs.map +0 -1
  108. package/lib/cjs/common/packageVersions.cjs +0 -16
  109. package/lib/cjs/common/packageVersions.cjs.map +0 -1
  110. package/lib/cjs/common/paramValidation.cjs +0 -16
  111. package/lib/cjs/common/paramValidation.cjs.map +0 -1
  112. package/lib/cjs/common/requestCounter.cjs +0 -108
  113. package/lib/cjs/common/requestCounter.cjs.map +0 -1
  114. package/lib/cjs/common/serverErrorCounter.cjs +0 -154
  115. package/lib/cjs/common/serverErrorCounter.cjs.map +0 -1
  116. package/lib/cjs/common/types.cjs +0 -6
  117. package/lib/cjs/common/types.cjs.map +0 -1
  118. package/lib/cjs/common/validationErrorCounter.cjs +0 -60
  119. package/lib/cjs/common/validationErrorCounter.cjs.map +0 -1
  120. package/lib/cjs/express/index.cjs +0 -13
  121. package/lib/cjs/express/index.cjs.map +0 -1
  122. package/lib/cjs/express/listEndpoints.cjs +0 -177
  123. package/lib/cjs/express/listEndpoints.cjs.map +0 -1
  124. package/lib/cjs/express/middleware.cjs +0 -189
  125. package/lib/cjs/express/middleware.cjs.map +0 -1
  126. package/lib/cjs/fastify/index.cjs +0 -14
  127. package/lib/cjs/fastify/index.cjs.map +0 -1
  128. package/lib/cjs/fastify/plugin.cjs +0 -171
  129. package/lib/cjs/fastify/plugin.cjs.map +0 -1
  130. package/lib/cjs/index.cjs +0 -6
  131. package/lib/cjs/index.cjs.map +0 -1
  132. package/lib/cjs/koa/index.cjs +0 -13
  133. package/lib/cjs/koa/index.cjs.map +0 -1
  134. package/lib/cjs/koa/middleware.cjs +0 -139
  135. package/lib/cjs/koa/middleware.cjs.map +0 -1
  136. package/lib/cjs/nestjs/index.cjs +0 -13
  137. package/lib/cjs/nestjs/index.cjs.map +0 -1
  138. package/lib/esm/common/client.js +0 -313
  139. package/lib/esm/common/client.js.map +0 -1
  140. package/lib/esm/common/logging.js +0 -11
  141. package/lib/esm/common/logging.js.map +0 -1
  142. package/lib/esm/common/packageVersions.js +0 -10
  143. package/lib/esm/common/packageVersions.js.map +0 -1
  144. package/lib/esm/common/paramValidation.js +0 -9
  145. package/lib/esm/common/paramValidation.js.map +0 -1
  146. package/lib/esm/common/requestCounter.js +0 -102
  147. package/lib/esm/common/requestCounter.js.map +0 -1
  148. package/lib/esm/common/serverErrorCounter.js +0 -143
  149. package/lib/esm/common/serverErrorCounter.js.map +0 -1
  150. package/lib/esm/common/types.js +0 -1
  151. package/lib/esm/common/types.js.map +0 -1
  152. package/lib/esm/common/validationErrorCounter.js +0 -54
  153. package/lib/esm/common/validationErrorCounter.js.map +0 -1
  154. package/lib/esm/express/index.js +0 -1
  155. package/lib/esm/express/index.js.map +0 -1
  156. package/lib/esm/express/listEndpoints.js +0 -170
  157. package/lib/esm/express/listEndpoints.js.map +0 -1
  158. package/lib/esm/express/middleware.js +0 -182
  159. package/lib/esm/express/middleware.js.map +0 -1
  160. package/lib/esm/fastify/index.js +0 -1
  161. package/lib/esm/fastify/index.js.map +0 -1
  162. package/lib/esm/fastify/plugin.js +0 -164
  163. package/lib/esm/fastify/plugin.js.map +0 -1
  164. package/lib/esm/index.js +0 -1
  165. package/lib/esm/index.js.map +0 -1
  166. package/lib/esm/koa/index.js +0 -1
  167. package/lib/esm/koa/index.js.map +0 -1
  168. package/lib/esm/koa/middleware.js +0 -132
  169. package/lib/esm/koa/middleware.js.map +0 -1
  170. package/lib/esm/nestjs/index.js +0 -1
  171. package/lib/esm/nestjs/index.js.map +0 -1
  172. package/lib/types/common/client.d.ts.map +0 -1
  173. package/lib/types/common/logging.d.ts.map +0 -1
  174. package/lib/types/common/packageVersions.d.ts +0 -2
  175. package/lib/types/common/packageVersions.d.ts.map +0 -1
  176. package/lib/types/common/paramValidation.d.ts +0 -3
  177. package/lib/types/common/paramValidation.d.ts.map +0 -1
  178. package/lib/types/common/requestCounter.d.ts.map +0 -1
  179. package/lib/types/common/serverErrorCounter.d.ts.map +0 -1
  180. package/lib/types/common/types.d.ts.map +0 -1
  181. package/lib/types/common/validationErrorCounter.d.ts.map +0 -1
  182. package/lib/types/express/index.d.ts +0 -2
  183. package/lib/types/express/index.d.ts.map +0 -1
  184. package/lib/types/express/listEndpoints.d.ts +0 -3
  185. package/lib/types/express/listEndpoints.d.ts.map +0 -1
  186. package/lib/types/express/middleware.d.ts +0 -10
  187. package/lib/types/express/middleware.d.ts.map +0 -1
  188. package/lib/types/fastify/index.d.ts +0 -2
  189. package/lib/types/fastify/index.d.ts.map +0 -1
  190. package/lib/types/fastify/plugin.d.ts.map +0 -1
  191. package/lib/types/index.d.ts +0 -2
  192. package/lib/types/index.d.ts.map +0 -1
  193. package/lib/types/koa/index.d.ts +0 -2
  194. package/lib/types/koa/index.d.ts.map +0 -1
  195. package/lib/types/koa/middleware.d.ts +0 -4
  196. package/lib/types/koa/middleware.d.ts.map +0 -1
  197. package/lib/types/nestjs/index.d.ts +0 -2
  198. package/lib/types/nestjs/index.d.ts.map +0 -1
@@ -0,0 +1,514 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
+ var __export = (target, all) => {
11
+ for (var name in all)
12
+ __defProp(target, name, { get: all[name], enumerable: true });
13
+ };
14
+ var __copyProps = (to, from, except, desc) => {
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from))
17
+ if (!__hasOwnProp.call(to, key) && key !== except)
18
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
19
+ }
20
+ return to;
21
+ };
22
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
+ // If the importer is in node compatibility mode or this is not an ESM
24
+ // file that has been converted to a CommonJS file using a Babel-
25
+ // compatible transform (i.e. "__esModule" has not been set), then set
26
+ // "default" to the CommonJS "module.exports" for node compatibility.
27
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
28
+ mod
29
+ ));
30
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
31
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
32
+
33
+ // src/common/client.ts
34
+ var client_exports = {};
35
+ __export(client_exports, {
36
+ ApitallyClient: () => ApitallyClient
37
+ });
38
+ module.exports = __toCommonJS(client_exports);
39
+ var import_crypto3 = require("crypto");
40
+ var import_fetch_retry = __toESM(require("fetch-retry"), 1);
41
+
42
+ // src/common/logging.ts
43
+ var import_winston = require("winston");
44
+ var getLogger = /* @__PURE__ */ __name(() => {
45
+ return (0, import_winston.createLogger)({
46
+ level: process.env.APITALLY_DEBUG ? "debug" : "warn",
47
+ format: import_winston.format.combine(import_winston.format.colorize(), import_winston.format.timestamp(), import_winston.format.printf((info) => `${info.timestamp} ${info.level}: ${info.message}`)),
48
+ transports: [
49
+ new import_winston.transports.Console()
50
+ ]
51
+ });
52
+ }, "getLogger");
53
+
54
+ // src/common/paramValidation.ts
55
+ function isValidClientId(clientId) {
56
+ const regexExp = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
57
+ return regexExp.test(clientId);
58
+ }
59
+ __name(isValidClientId, "isValidClientId");
60
+ function isValidEnv(env) {
61
+ const regexExp = /^[\w-]{1,32}$/;
62
+ return regexExp.test(env);
63
+ }
64
+ __name(isValidEnv, "isValidEnv");
65
+
66
+ // src/common/requestCounter.ts
67
+ var _RequestCounter = class _RequestCounter {
68
+ requestCounts;
69
+ requestSizeSums;
70
+ responseSizeSums;
71
+ responseTimes;
72
+ requestSizes;
73
+ responseSizes;
74
+ constructor() {
75
+ this.requestCounts = /* @__PURE__ */ new Map();
76
+ this.requestSizeSums = /* @__PURE__ */ new Map();
77
+ this.responseSizeSums = /* @__PURE__ */ new Map();
78
+ this.responseTimes = /* @__PURE__ */ new Map();
79
+ this.requestSizes = /* @__PURE__ */ new Map();
80
+ this.responseSizes = /* @__PURE__ */ new Map();
81
+ }
82
+ getKey(requestInfo) {
83
+ return [
84
+ requestInfo.consumer || "",
85
+ requestInfo.method.toUpperCase(),
86
+ requestInfo.path,
87
+ requestInfo.statusCode
88
+ ].join("|");
89
+ }
90
+ addRequest(requestInfo) {
91
+ const key = this.getKey(requestInfo);
92
+ this.requestCounts.set(key, (this.requestCounts.get(key) || 0) + 1);
93
+ if (!this.responseTimes.has(key)) {
94
+ this.responseTimes.set(key, /* @__PURE__ */ new Map());
95
+ }
96
+ const responseTimeMap = this.responseTimes.get(key);
97
+ const responseTimeMsBin = Math.floor(requestInfo.responseTime / 10) * 10;
98
+ responseTimeMap.set(responseTimeMsBin, (responseTimeMap.get(responseTimeMsBin) || 0) + 1);
99
+ if (requestInfo.requestSize !== void 0) {
100
+ requestInfo.requestSize = Number(requestInfo.requestSize);
101
+ this.requestSizeSums.set(key, (this.requestSizeSums.get(key) || 0) + requestInfo.requestSize);
102
+ if (!this.requestSizes.has(key)) {
103
+ this.requestSizes.set(key, /* @__PURE__ */ new Map());
104
+ }
105
+ const requestSizeMap = this.requestSizes.get(key);
106
+ const requestSizeKbBin = Math.floor(requestInfo.requestSize / 1e3);
107
+ requestSizeMap.set(requestSizeKbBin, (requestSizeMap.get(requestSizeKbBin) || 0) + 1);
108
+ }
109
+ if (requestInfo.responseSize !== void 0) {
110
+ requestInfo.responseSize = Number(requestInfo.responseSize);
111
+ this.responseSizeSums.set(key, (this.responseSizeSums.get(key) || 0) + requestInfo.responseSize);
112
+ if (!this.responseSizes.has(key)) {
113
+ this.responseSizes.set(key, /* @__PURE__ */ new Map());
114
+ }
115
+ const responseSizeMap = this.responseSizes.get(key);
116
+ const responseSizeKbBin = Math.floor(requestInfo.responseSize / 1e3);
117
+ responseSizeMap.set(responseSizeKbBin, (responseSizeMap.get(responseSizeKbBin) || 0) + 1);
118
+ }
119
+ }
120
+ getAndResetRequests() {
121
+ const data = [];
122
+ this.requestCounts.forEach((count, key) => {
123
+ const [consumer, method, path, statusCodeStr] = key.split("|");
124
+ const responseTimes = this.responseTimes.get(key) || /* @__PURE__ */ new Map();
125
+ const requestSizes = this.requestSizes.get(key) || /* @__PURE__ */ new Map();
126
+ const responseSizes = this.responseSizes.get(key) || /* @__PURE__ */ new Map();
127
+ data.push({
128
+ consumer: consumer || null,
129
+ method,
130
+ path,
131
+ status_code: parseInt(statusCodeStr),
132
+ request_count: count,
133
+ request_size_sum: this.requestSizeSums.get(key) || 0,
134
+ response_size_sum: this.responseSizeSums.get(key) || 0,
135
+ response_times: Object.fromEntries(responseTimes),
136
+ request_sizes: Object.fromEntries(requestSizes),
137
+ response_sizes: Object.fromEntries(responseSizes)
138
+ });
139
+ });
140
+ this.requestCounts.clear();
141
+ this.requestSizeSums.clear();
142
+ this.responseSizeSums.clear();
143
+ this.responseTimes.clear();
144
+ this.requestSizes.clear();
145
+ this.responseSizes.clear();
146
+ return data;
147
+ }
148
+ };
149
+ __name(_RequestCounter, "RequestCounter");
150
+ var RequestCounter = _RequestCounter;
151
+
152
+ // src/common/serverErrorCounter.ts
153
+ var import_crypto = require("crypto");
154
+ var MAX_MSG_LENGTH = 2048;
155
+ var MAX_STACKTRACE_LENGTH = 65536;
156
+ var _ServerErrorCounter = class _ServerErrorCounter {
157
+ errorCounts;
158
+ errorDetails;
159
+ sentryEventIds;
160
+ sentry;
161
+ constructor() {
162
+ this.errorCounts = /* @__PURE__ */ new Map();
163
+ this.errorDetails = /* @__PURE__ */ new Map();
164
+ this.sentryEventIds = /* @__PURE__ */ new Map();
165
+ this.tryImportSentry();
166
+ }
167
+ addServerError(serverError) {
168
+ const key = this.getKey(serverError);
169
+ if (!this.errorDetails.has(key)) {
170
+ this.errorDetails.set(key, serverError);
171
+ }
172
+ this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
173
+ this.captureSentryEventId(key);
174
+ }
175
+ getAndResetServerErrors() {
176
+ const data = [];
177
+ this.errorCounts.forEach((count, key) => {
178
+ const serverError = this.errorDetails.get(key);
179
+ if (serverError) {
180
+ data.push({
181
+ consumer: serverError.consumer || null,
182
+ method: serverError.method,
183
+ path: serverError.path,
184
+ type: serverError.type,
185
+ msg: this.getTruncatedMessage(serverError.msg),
186
+ traceback: this.getTruncatedStack(serverError.traceback),
187
+ sentry_event_id: this.sentryEventIds.get(key) || null,
188
+ error_count: count
189
+ });
190
+ }
191
+ });
192
+ this.errorCounts.clear();
193
+ this.errorDetails.clear();
194
+ return data;
195
+ }
196
+ getKey(serverError) {
197
+ const hashInput = [
198
+ serverError.consumer || "",
199
+ serverError.method.toUpperCase(),
200
+ serverError.path,
201
+ serverError.type,
202
+ serverError.msg.trim(),
203
+ serverError.traceback.trim()
204
+ ].join("|");
205
+ return (0, import_crypto.createHash)("md5").update(hashInput).digest("hex");
206
+ }
207
+ getTruncatedMessage(msg) {
208
+ msg = msg.trim();
209
+ if (msg.length <= MAX_MSG_LENGTH) {
210
+ return msg;
211
+ }
212
+ const suffix = "... (truncated)";
213
+ const cutoff = MAX_MSG_LENGTH - suffix.length;
214
+ return msg.substring(0, cutoff) + suffix;
215
+ }
216
+ getTruncatedStack(stack) {
217
+ const suffix = "... (truncated) ...";
218
+ const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
219
+ const lines = stack.trim().split("\n");
220
+ const truncatedLines = [];
221
+ let length = 0;
222
+ for (const line of lines) {
223
+ if (length + line.length + 1 > cutoff) {
224
+ truncatedLines.push(suffix);
225
+ break;
226
+ }
227
+ truncatedLines.push(line);
228
+ length += line.length + 1;
229
+ }
230
+ return truncatedLines.join("\n");
231
+ }
232
+ captureSentryEventId(serverErrorKey) {
233
+ if (this.sentry && this.sentry.lastEventId) {
234
+ const eventId = this.sentry.lastEventId();
235
+ if (eventId) {
236
+ this.sentryEventIds.set(serverErrorKey, eventId);
237
+ }
238
+ }
239
+ }
240
+ async tryImportSentry() {
241
+ try {
242
+ this.sentry = await import("@sentry/node");
243
+ } catch (e) {
244
+ }
245
+ }
246
+ };
247
+ __name(_ServerErrorCounter, "ServerErrorCounter");
248
+ var ServerErrorCounter = _ServerErrorCounter;
249
+
250
+ // src/common/validationErrorCounter.ts
251
+ var import_crypto2 = require("crypto");
252
+ var _ValidationErrorCounter = class _ValidationErrorCounter {
253
+ errorCounts;
254
+ errorDetails;
255
+ constructor() {
256
+ this.errorCounts = /* @__PURE__ */ new Map();
257
+ this.errorDetails = /* @__PURE__ */ new Map();
258
+ }
259
+ addValidationError(validationError) {
260
+ const key = this.getKey(validationError);
261
+ if (!this.errorDetails.has(key)) {
262
+ this.errorDetails.set(key, validationError);
263
+ }
264
+ this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
265
+ }
266
+ getAndResetValidationErrors() {
267
+ const data = [];
268
+ this.errorCounts.forEach((count, key) => {
269
+ const validationError = this.errorDetails.get(key);
270
+ if (validationError) {
271
+ data.push({
272
+ consumer: validationError.consumer || null,
273
+ method: validationError.method,
274
+ path: validationError.path,
275
+ loc: validationError.loc.split("."),
276
+ msg: validationError.msg,
277
+ type: validationError.type,
278
+ error_count: count
279
+ });
280
+ }
281
+ });
282
+ this.errorCounts.clear();
283
+ this.errorDetails.clear();
284
+ return data;
285
+ }
286
+ getKey(validationError) {
287
+ const hashInput = [
288
+ validationError.consumer || "",
289
+ validationError.method.toUpperCase(),
290
+ validationError.path,
291
+ validationError.loc,
292
+ validationError.msg.trim(),
293
+ validationError.type
294
+ ].join("|");
295
+ return (0, import_crypto2.createHash)("md5").update(hashInput).digest("hex");
296
+ }
297
+ };
298
+ __name(_ValidationErrorCounter, "ValidationErrorCounter");
299
+ var ValidationErrorCounter = _ValidationErrorCounter;
300
+
301
+ // src/common/client.ts
302
+ var SYNC_INTERVAL = 6e4;
303
+ var INITIAL_SYNC_INTERVAL = 1e4;
304
+ var INITIAL_SYNC_INTERVAL_DURATION = 36e5;
305
+ var MAX_QUEUE_TIME = 36e5;
306
+ var _a;
307
+ var HTTPError = (_a = class extends Error {
308
+ response;
309
+ constructor(response) {
310
+ const reason = response.status ? `status code ${response.status}` : "an unknown error";
311
+ super(`Request failed with ${reason}`);
312
+ this.response = response;
313
+ }
314
+ }, __name(_a, "HTTPError"), _a);
315
+ var _ApitallyClient = class _ApitallyClient {
316
+ clientId;
317
+ env;
318
+ instanceUuid;
319
+ requestsDataQueue;
320
+ syncIntervalId;
321
+ appInfo;
322
+ appInfoSent = false;
323
+ requestCounter;
324
+ validationErrorCounter;
325
+ serverErrorCounter;
326
+ logger;
327
+ constructor({ clientId, env = "dev", logger }) {
328
+ if (_ApitallyClient.instance) {
329
+ throw new Error("Apitally client is already initialized");
330
+ }
331
+ if (!isValidClientId(clientId)) {
332
+ throw new Error(`Invalid client ID '${clientId}' (expecting hexadeciaml UUID format)`);
333
+ }
334
+ if (!isValidEnv(env)) {
335
+ throw new Error(`Invalid env '${env}' (expecting 1-32 alphanumeric lowercase characters and hyphens only)`);
336
+ }
337
+ _ApitallyClient.instance = this;
338
+ this.clientId = clientId;
339
+ this.env = env;
340
+ this.instanceUuid = (0, import_crypto3.randomUUID)();
341
+ this.requestsDataQueue = [];
342
+ this.requestCounter = new RequestCounter();
343
+ this.validationErrorCounter = new ValidationErrorCounter();
344
+ this.serverErrorCounter = new ServerErrorCounter();
345
+ this.logger = logger || getLogger();
346
+ this.startSync();
347
+ this.handleShutdown = this.handleShutdown.bind(this);
348
+ }
349
+ static getInstance() {
350
+ if (!_ApitallyClient.instance) {
351
+ throw new Error("Apitally client is not initialized");
352
+ }
353
+ return _ApitallyClient.instance;
354
+ }
355
+ static async shutdown() {
356
+ if (_ApitallyClient.instance) {
357
+ await _ApitallyClient.instance.handleShutdown();
358
+ }
359
+ }
360
+ async handleShutdown() {
361
+ this.stopSync();
362
+ await this.sendRequestsData();
363
+ _ApitallyClient.instance = void 0;
364
+ }
365
+ getHubUrlPrefix() {
366
+ const baseURL = process.env.APITALLY_HUB_BASE_URL || "https://hub.apitally.io";
367
+ const version = "v1";
368
+ return `${baseURL}/${version}/${this.clientId}/${this.env}/`;
369
+ }
370
+ async makeHubRequest(url, payload) {
371
+ const fetchWithRetry = (0, import_fetch_retry.default)(fetch, {
372
+ retries: 3,
373
+ retryDelay: 1e3,
374
+ retryOn: [
375
+ 408,
376
+ 429,
377
+ 500,
378
+ 502,
379
+ 503,
380
+ 504
381
+ ]
382
+ });
383
+ const response = await fetchWithRetry(this.getHubUrlPrefix() + url, {
384
+ method: "POST",
385
+ body: JSON.stringify(payload),
386
+ headers: {
387
+ "Content-Type": "application/json"
388
+ }
389
+ });
390
+ if (!response.ok) {
391
+ throw new HTTPError(response);
392
+ }
393
+ }
394
+ startSync() {
395
+ this.sync();
396
+ this.syncIntervalId = setInterval(() => {
397
+ this.sync();
398
+ }, INITIAL_SYNC_INTERVAL);
399
+ setTimeout(() => {
400
+ clearInterval(this.syncIntervalId);
401
+ this.syncIntervalId = setInterval(() => {
402
+ this.sync();
403
+ }, SYNC_INTERVAL);
404
+ }, INITIAL_SYNC_INTERVAL_DURATION);
405
+ }
406
+ async sync() {
407
+ try {
408
+ const promises = [
409
+ this.sendRequestsData()
410
+ ];
411
+ if (!this.appInfoSent) {
412
+ promises.push(this.sendAppInfo());
413
+ }
414
+ await Promise.all(promises);
415
+ } catch (error) {
416
+ this.logger.error("Error while syncing with Apitally Hub", {
417
+ error
418
+ });
419
+ }
420
+ }
421
+ stopSync() {
422
+ if (this.syncIntervalId) {
423
+ clearInterval(this.syncIntervalId);
424
+ this.syncIntervalId = void 0;
425
+ }
426
+ }
427
+ setAppInfo(appInfo) {
428
+ this.appInfo = appInfo;
429
+ this.appInfoSent = false;
430
+ this.sendAppInfo();
431
+ }
432
+ async sendAppInfo() {
433
+ if (this.appInfo) {
434
+ this.logger.debug("Sending app info to Apitally Hub");
435
+ const payload = {
436
+ instance_uuid: this.instanceUuid,
437
+ message_uuid: (0, import_crypto3.randomUUID)(),
438
+ ...this.appInfo
439
+ };
440
+ try {
441
+ await this.makeHubRequest("info", payload);
442
+ this.appInfoSent = true;
443
+ } catch (error) {
444
+ const handled = this.handleHubError(error);
445
+ if (!handled) {
446
+ this.logger.error(error.message);
447
+ this.logger.debug("Error while sending app info to Apitally Hub (will retry)", {
448
+ error
449
+ });
450
+ }
451
+ }
452
+ }
453
+ }
454
+ async sendRequestsData() {
455
+ this.logger.debug("Sending requests data to Apitally Hub");
456
+ const newPayload = {
457
+ time_offset: 0,
458
+ instance_uuid: this.instanceUuid,
459
+ message_uuid: (0, import_crypto3.randomUUID)(),
460
+ requests: this.requestCounter.getAndResetRequests(),
461
+ validation_errors: this.validationErrorCounter.getAndResetValidationErrors(),
462
+ server_errors: this.serverErrorCounter.getAndResetServerErrors()
463
+ };
464
+ this.requestsDataQueue.push([
465
+ Date.now(),
466
+ newPayload
467
+ ]);
468
+ const failedItems = [];
469
+ while (this.requestsDataQueue.length > 0) {
470
+ const queueItem = this.requestsDataQueue.shift();
471
+ if (queueItem) {
472
+ const [time, payload] = queueItem;
473
+ try {
474
+ const timeOffset = Date.now() - time;
475
+ if (timeOffset <= MAX_QUEUE_TIME) {
476
+ payload.time_offset = timeOffset / 1e3;
477
+ await this.makeHubRequest("requests", payload);
478
+ }
479
+ } catch (error) {
480
+ const handled = this.handleHubError(error);
481
+ if (!handled) {
482
+ this.logger.debug("Error while sending requests data to Apitally Hub (will retry)", {
483
+ error
484
+ });
485
+ failedItems.push(queueItem);
486
+ }
487
+ }
488
+ }
489
+ }
490
+ this.requestsDataQueue = failedItems;
491
+ }
492
+ handleHubError(error) {
493
+ if (error instanceof HTTPError) {
494
+ if (error.response.status === 404) {
495
+ this.logger.error(`Invalid Apitally client ID: '${this.clientId}'`);
496
+ this.stopSync();
497
+ return true;
498
+ }
499
+ if (error.response.status === 422) {
500
+ this.logger.error("Received validation error from Apitally Hub");
501
+ return true;
502
+ }
503
+ }
504
+ return false;
505
+ }
506
+ };
507
+ __name(_ApitallyClient, "ApitallyClient");
508
+ __publicField(_ApitallyClient, "instance");
509
+ var ApitallyClient = _ApitallyClient;
510
+ // Annotate the CommonJS export names for ESM import in node:
511
+ 0 && (module.exports = {
512
+ ApitallyClient
513
+ });
514
+ //# sourceMappingURL=client.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/common/client.ts","../../src/common/logging.ts","../../src/common/paramValidation.ts","../../src/common/requestCounter.ts","../../src/common/serverErrorCounter.ts","../../src/common/validationErrorCounter.ts"],"sourcesContent":["import { randomUUID } from \"crypto\";\nimport fetchRetry from \"fetch-retry\";\nimport { Logger, getLogger } from \"./logging.js\";\nimport { isValidClientId, isValidEnv } from \"./paramValidation.js\";\nimport RequestCounter from \"./requestCounter.js\";\nimport ServerErrorCounter from \"./serverErrorCounter.js\";\nimport {\n ApitallyConfig,\n AppInfo,\n AppInfoPayload,\n RequestsDataPayload,\n} from \"./types.js\";\nimport ValidationErrorCounter from \"./validationErrorCounter.js\";\n\nconst SYNC_INTERVAL = 60000; // 60 seconds\nconst INITIAL_SYNC_INTERVAL = 10000; // 10 seconds\nconst INITIAL_SYNC_INTERVAL_DURATION = 3600000; // 1 hour\nconst MAX_QUEUE_TIME = 3.6e6; // 1 hour\n\nclass HTTPError extends Error {\n public response: Response;\n\n constructor(response: Response) {\n const reason = response.status\n ? `status code ${response.status}`\n : \"an unknown error\";\n super(`Request failed with ${reason}`);\n this.response = response;\n }\n}\n\nexport class ApitallyClient {\n private clientId: string;\n private env: string;\n\n private static instance?: ApitallyClient;\n private instanceUuid: string;\n private requestsDataQueue: Array<[number, RequestsDataPayload]>;\n private syncIntervalId?: NodeJS.Timeout;\n public appInfo?: AppInfo;\n private appInfoSent: boolean = false;\n\n public requestCounter: RequestCounter;\n public validationErrorCounter: ValidationErrorCounter;\n public serverErrorCounter: ServerErrorCounter;\n public logger: Logger;\n\n constructor({ clientId, env = \"dev\", logger }: ApitallyConfig) {\n if (ApitallyClient.instance) {\n throw new Error(\"Apitally client is already initialized\");\n }\n if (!isValidClientId(clientId)) {\n throw new Error(\n `Invalid client ID '${clientId}' (expecting hexadeciaml UUID format)`,\n );\n }\n if (!isValidEnv(env)) {\n throw new Error(\n `Invalid env '${env}' (expecting 1-32 alphanumeric lowercase characters and hyphens only)`,\n );\n }\n\n ApitallyClient.instance = this;\n this.clientId = clientId;\n this.env = env;\n this.instanceUuid = randomUUID();\n this.requestsDataQueue = [];\n this.requestCounter = new RequestCounter();\n this.validationErrorCounter = new ValidationErrorCounter();\n this.serverErrorCounter = new ServerErrorCounter();\n this.logger = logger || getLogger();\n\n this.startSync();\n this.handleShutdown = this.handleShutdown.bind(this);\n }\n\n public static getInstance() {\n if (!ApitallyClient.instance) {\n throw new Error(\"Apitally client is not initialized\");\n }\n return ApitallyClient.instance;\n }\n\n public static async shutdown() {\n if (ApitallyClient.instance) {\n await ApitallyClient.instance.handleShutdown();\n }\n }\n\n public async handleShutdown() {\n this.stopSync();\n await this.sendRequestsData();\n ApitallyClient.instance = undefined;\n }\n\n private getHubUrlPrefix() {\n const baseURL =\n process.env.APITALLY_HUB_BASE_URL || \"https://hub.apitally.io\";\n const version = \"v1\";\n return `${baseURL}/${version}/${this.clientId}/${this.env}/`;\n }\n\n private async makeHubRequest(url: string, payload: any) {\n const fetchWithRetry = fetchRetry(fetch, {\n retries: 3,\n retryDelay: 1000,\n retryOn: [408, 429, 500, 502, 503, 504],\n });\n const response = await fetchWithRetry(this.getHubUrlPrefix() + url, {\n method: \"POST\",\n body: JSON.stringify(payload),\n headers: { \"Content-Type\": \"application/json\" },\n });\n if (!response.ok) {\n throw new HTTPError(response);\n }\n }\n\n private startSync() {\n this.sync();\n this.syncIntervalId = setInterval(() => {\n this.sync();\n }, INITIAL_SYNC_INTERVAL);\n setTimeout(() => {\n clearInterval(this.syncIntervalId);\n this.syncIntervalId = setInterval(() => {\n this.sync();\n }, SYNC_INTERVAL);\n }, INITIAL_SYNC_INTERVAL_DURATION);\n }\n\n private async sync() {\n try {\n const promises = [this.sendRequestsData()];\n if (!this.appInfoSent) {\n promises.push(this.sendAppInfo());\n }\n await Promise.all(promises);\n } catch (error) {\n this.logger.error(\"Error while syncing with Apitally Hub\", {\n error,\n });\n }\n }\n\n private stopSync() {\n if (this.syncIntervalId) {\n clearInterval(this.syncIntervalId);\n this.syncIntervalId = undefined;\n }\n }\n\n public setAppInfo(appInfo: AppInfo) {\n this.appInfo = appInfo;\n this.appInfoSent = false;\n this.sendAppInfo();\n }\n\n private async sendAppInfo() {\n if (this.appInfo) {\n this.logger.debug(\"Sending app info to Apitally Hub\");\n const payload: AppInfoPayload = {\n instance_uuid: this.instanceUuid,\n message_uuid: randomUUID(),\n ...this.appInfo,\n };\n try {\n await this.makeHubRequest(\"info\", payload);\n this.appInfoSent = true;\n } catch (error) {\n const handled = this.handleHubError(error);\n if (!handled) {\n this.logger.error((error as Error).message);\n this.logger.debug(\n \"Error while sending app info to Apitally Hub (will retry)\",\n { error },\n );\n }\n }\n }\n }\n\n private async sendRequestsData() {\n this.logger.debug(\"Sending requests data to Apitally Hub\");\n const newPayload: RequestsDataPayload = {\n time_offset: 0,\n instance_uuid: this.instanceUuid,\n message_uuid: randomUUID(),\n requests: this.requestCounter.getAndResetRequests(),\n validation_errors:\n this.validationErrorCounter.getAndResetValidationErrors(),\n server_errors: this.serverErrorCounter.getAndResetServerErrors(),\n };\n this.requestsDataQueue.push([Date.now(), newPayload]);\n\n const failedItems: [number, RequestsDataPayload][] = [];\n while (this.requestsDataQueue.length > 0) {\n const queueItem = this.requestsDataQueue.shift();\n if (queueItem) {\n const [time, payload] = queueItem;\n try {\n const timeOffset = Date.now() - time;\n if (timeOffset <= MAX_QUEUE_TIME) {\n payload.time_offset = timeOffset / 1000.0; // In seconds\n await this.makeHubRequest(\"requests\", payload);\n }\n } catch (error) {\n const handled = this.handleHubError(error);\n if (!handled) {\n this.logger.debug(\n \"Error while sending requests data to Apitally Hub (will retry)\",\n { error },\n );\n failedItems.push(queueItem);\n }\n }\n }\n }\n this.requestsDataQueue = failedItems;\n }\n\n private handleHubError(error: unknown) {\n if (error instanceof HTTPError) {\n if (error.response.status === 404) {\n this.logger.error(`Invalid Apitally client ID: '${this.clientId}'`);\n this.stopSync();\n return true;\n }\n if (error.response.status === 422) {\n this.logger.error(\"Received validation error from Apitally Hub\");\n return true;\n }\n }\n return false;\n }\n}\n","import { createLogger, format, transports } from \"winston\";\n\nexport interface Logger {\n debug: (message: string, meta?: object) => void;\n info: (message: string, meta?: object) => void;\n warn: (message: string, meta?: object) => void;\n error: (message: string, meta?: object) => void;\n}\n\nexport const getLogger = () => {\n return createLogger({\n level: process.env.APITALLY_DEBUG ? \"debug\" : \"warn\",\n format: format.combine(\n format.colorize(),\n format.timestamp(),\n format.printf(\n (info) => `${info.timestamp} ${info.level}: ${info.message}`,\n ),\n ),\n transports: [new transports.Console()],\n });\n};\n","export function isValidClientId(clientId: string): boolean {\n const regexExp =\n /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n return regexExp.test(clientId);\n}\n\nexport function isValidEnv(env: string): boolean {\n const regexExp = /^[\\w-]{1,32}$/;\n return regexExp.test(env);\n}\n","import { RequestInfo, RequestsItem } from \"./types.js\";\n\nexport default class RequestCounter {\n private requestCounts: Map<string, number>;\n private requestSizeSums: Map<string, number>;\n private responseSizeSums: Map<string, number>;\n private responseTimes: Map<string, Map<number, number>>;\n private requestSizes: Map<string, Map<number, number>>;\n private responseSizes: Map<string, Map<number, number>>;\n\n constructor() {\n this.requestCounts = new Map<string, number>();\n this.requestSizeSums = new Map<string, number>();\n this.responseSizeSums = new Map<string, number>();\n this.responseTimes = new Map<string, Map<number, number>>();\n this.requestSizes = new Map<string, Map<number, number>>();\n this.responseSizes = new Map<string, Map<number, number>>();\n }\n\n private getKey(requestInfo: RequestInfo) {\n return [\n requestInfo.consumer || \"\",\n requestInfo.method.toUpperCase(),\n requestInfo.path,\n requestInfo.statusCode,\n ].join(\"|\");\n }\n\n addRequest(requestInfo: RequestInfo) {\n const key = this.getKey(requestInfo);\n\n // Increment request count\n this.requestCounts.set(key, (this.requestCounts.get(key) || 0) + 1);\n\n // Add response time\n if (!this.responseTimes.has(key)) {\n this.responseTimes.set(key, new Map<number, number>());\n }\n const responseTimeMap = this.responseTimes.get(key)!;\n const responseTimeMsBin = Math.floor(requestInfo.responseTime / 10) * 10; // Rounded to nearest 10ms\n responseTimeMap.set(\n responseTimeMsBin,\n (responseTimeMap.get(responseTimeMsBin) || 0) + 1,\n );\n\n // Add request size\n if (requestInfo.requestSize !== undefined) {\n requestInfo.requestSize = Number(requestInfo.requestSize);\n this.requestSizeSums.set(\n key,\n (this.requestSizeSums.get(key) || 0) + requestInfo.requestSize,\n );\n if (!this.requestSizes.has(key)) {\n this.requestSizes.set(key, new Map<number, number>());\n }\n const requestSizeMap = this.requestSizes.get(key)!;\n const requestSizeKbBin = Math.floor(requestInfo.requestSize / 1000); // Rounded down to nearest KB\n requestSizeMap.set(\n requestSizeKbBin,\n (requestSizeMap.get(requestSizeKbBin) || 0) + 1,\n );\n }\n\n // Add response size\n if (requestInfo.responseSize !== undefined) {\n requestInfo.responseSize = Number(requestInfo.responseSize);\n this.responseSizeSums.set(\n key,\n (this.responseSizeSums.get(key) || 0) + requestInfo.responseSize,\n );\n if (!this.responseSizes.has(key)) {\n this.responseSizes.set(key, new Map<number, number>());\n }\n const responseSizeMap = this.responseSizes.get(key)!;\n const responseSizeKbBin = Math.floor(requestInfo.responseSize / 1000); // Rounded down to nearest KB\n responseSizeMap.set(\n responseSizeKbBin,\n (responseSizeMap.get(responseSizeKbBin) || 0) + 1,\n );\n }\n }\n\n getAndResetRequests() {\n const data: Array<RequestsItem> = [];\n this.requestCounts.forEach((count, key) => {\n const [consumer, method, path, statusCodeStr] = key.split(\"|\");\n const responseTimes =\n this.responseTimes.get(key) || new Map<number, number>();\n const requestSizes =\n this.requestSizes.get(key) || new Map<number, number>();\n const responseSizes =\n this.responseSizes.get(key) || new Map<number, number>();\n data.push({\n consumer: consumer || null,\n method,\n path,\n status_code: parseInt(statusCodeStr),\n request_count: count,\n request_size_sum: this.requestSizeSums.get(key) || 0,\n response_size_sum: this.responseSizeSums.get(key) || 0,\n response_times: Object.fromEntries(responseTimes),\n request_sizes: Object.fromEntries(requestSizes),\n response_sizes: Object.fromEntries(responseSizes),\n });\n });\n\n // Reset the counts and times\n this.requestCounts.clear();\n this.requestSizeSums.clear();\n this.responseSizeSums.clear();\n this.responseTimes.clear();\n this.requestSizes.clear();\n this.responseSizes.clear();\n\n return data;\n }\n}\n","import type * as Sentry from \"@sentry/node\";\nimport { createHash } from \"crypto\";\n\nimport { ConsumerMethodPath, ServerError, ServerErrorsItem } from \"./types.js\";\n\nconst MAX_MSG_LENGTH = 2048;\nconst MAX_STACKTRACE_LENGTH = 65536;\n\nexport default class ServerErrorCounter {\n private errorCounts: Map<string, number>;\n private errorDetails: Map<string, ConsumerMethodPath & ServerError>;\n private sentryEventIds: Map<string, string>;\n private sentry: typeof Sentry | undefined;\n\n constructor() {\n this.errorCounts = new Map();\n this.errorDetails = new Map();\n this.sentryEventIds = new Map();\n this.tryImportSentry();\n }\n\n public addServerError(serverError: ConsumerMethodPath & ServerError) {\n const key = this.getKey(serverError);\n if (!this.errorDetails.has(key)) {\n this.errorDetails.set(key, serverError);\n }\n this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);\n this.captureSentryEventId(key);\n }\n\n public getAndResetServerErrors() {\n const data: Array<ServerErrorsItem> = [];\n this.errorCounts.forEach((count, key) => {\n const serverError = this.errorDetails.get(key);\n if (serverError) {\n data.push({\n consumer: serverError.consumer || null,\n method: serverError.method,\n path: serverError.path,\n type: serverError.type,\n msg: this.getTruncatedMessage(serverError.msg),\n traceback: this.getTruncatedStack(serverError.traceback),\n sentry_event_id: this.sentryEventIds.get(key) || null,\n error_count: count,\n });\n }\n });\n this.errorCounts.clear();\n this.errorDetails.clear();\n return data;\n }\n\n private getKey(serverError: ConsumerMethodPath & ServerError) {\n const hashInput = [\n serverError.consumer || \"\",\n serverError.method.toUpperCase(),\n serverError.path,\n serverError.type,\n serverError.msg.trim(),\n serverError.traceback.trim(),\n ].join(\"|\");\n return createHash(\"md5\").update(hashInput).digest(\"hex\");\n }\n\n private getTruncatedMessage(msg: string) {\n msg = msg.trim();\n if (msg.length <= MAX_MSG_LENGTH) {\n return msg;\n }\n const suffix = \"... (truncated)\";\n const cutoff = MAX_MSG_LENGTH - suffix.length;\n return msg.substring(0, cutoff) + suffix;\n }\n\n private getTruncatedStack(stack: string) {\n const suffix = \"... (truncated) ...\";\n const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;\n const lines = stack.trim().split(\"\\n\");\n const truncatedLines: string[] = [];\n let length = 0;\n for (const line of lines) {\n if (length + line.length + 1 > cutoff) {\n truncatedLines.push(suffix);\n break;\n }\n truncatedLines.push(line);\n length += line.length + 1;\n }\n return truncatedLines.join(\"\\n\");\n }\n\n private captureSentryEventId(serverErrorKey: string) {\n if (this.sentry && this.sentry.lastEventId) {\n const eventId = this.sentry.lastEventId();\n if (eventId) {\n this.sentryEventIds.set(serverErrorKey, eventId);\n }\n }\n }\n\n private async tryImportSentry() {\n try {\n this.sentry = await import(\"@sentry/node\");\n } catch (e) {\n // Sentry SDK is not installed, ignore\n }\n }\n}\n","import { createHash } from \"crypto\";\n\nimport {\n ConsumerMethodPath,\n ValidationError,\n ValidationErrorsItem,\n} from \"./types.js\";\n\nexport default class ValidationErrorCounter {\n private errorCounts: Map<string, number>;\n private errorDetails: Map<string, ConsumerMethodPath & ValidationError>;\n\n constructor() {\n this.errorCounts = new Map();\n this.errorDetails = new Map();\n }\n\n public addValidationError(\n validationError: ConsumerMethodPath & ValidationError,\n ) {\n const key = this.getKey(validationError);\n if (!this.errorDetails.has(key)) {\n this.errorDetails.set(key, validationError);\n }\n this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);\n }\n\n public getAndResetValidationErrors() {\n const data: Array<ValidationErrorsItem> = [];\n this.errorCounts.forEach((count, key) => {\n const validationError = this.errorDetails.get(key);\n if (validationError) {\n data.push({\n consumer: validationError.consumer || null,\n method: validationError.method,\n path: validationError.path,\n loc: validationError.loc.split(\".\"),\n msg: validationError.msg,\n type: validationError.type,\n error_count: count,\n });\n }\n });\n this.errorCounts.clear();\n this.errorDetails.clear();\n return data;\n }\n\n private getKey(validationError: ConsumerMethodPath & ValidationError) {\n const hashInput = [\n validationError.consumer || \"\",\n validationError.method.toUpperCase(),\n validationError.path,\n validationError.loc,\n validationError.msg.trim(),\n validationError.type,\n ].join(\"|\");\n return createHash(\"md5\").update(hashInput).digest(\"hex\");\n }\n}\n"],"mappings":"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","names":["import_crypto","getLogger","createLogger","level","process","env","APITALLY_DEBUG","format","combine","colorize","timestamp","printf","info","message","transports","Console","isValidClientId","clientId","regexExp","test","isValidEnv","env","RequestCounter","requestCounts","requestSizeSums","responseSizeSums","responseTimes","requestSizes","responseSizes","constructor","Map","getKey","requestInfo","consumer","method","toUpperCase","path","statusCode","join","addRequest","key","set","get","has","responseTimeMap","responseTimeMsBin","Math","floor","responseTime","requestSize","undefined","Number","requestSizeMap","requestSizeKbBin","responseSize","responseSizeMap","responseSizeKbBin","getAndResetRequests","data","forEach","count","statusCodeStr","split","push","status_code","parseInt","request_count","request_size_sum","response_size_sum","response_times","Object","fromEntries","request_sizes","response_sizes","clear","MAX_MSG_LENGTH","MAX_STACKTRACE_LENGTH","ServerErrorCounter","errorCounts","errorDetails","sentryEventIds","sentry","constructor","Map","tryImportSentry","addServerError","serverError","key","getKey","has","set","get","captureSentryEventId","getAndResetServerErrors","data","forEach","count","push","consumer","method","path","type","msg","getTruncatedMessage","traceback","getTruncatedStack","sentry_event_id","error_count","clear","hashInput","toUpperCase","trim","join","createHash","update","digest","length","suffix","cutoff","substring","stack","lines","split","truncatedLines","line","serverErrorKey","lastEventId","eventId","e","import_crypto","ValidationErrorCounter","errorCounts","errorDetails","constructor","Map","addValidationError","validationError","key","getKey","has","set","get","getAndResetValidationErrors","data","forEach","count","push","consumer","method","path","loc","split","msg","type","error_count","clear","hashInput","toUpperCase","trim","join","createHash","update","digest","SYNC_INTERVAL","INITIAL_SYNC_INTERVAL","INITIAL_SYNC_INTERVAL_DURATION","MAX_QUEUE_TIME","HTTPError","Error","response","constructor","reason","status","ApitallyClient","clientId","env","instanceUuid","requestsDataQueue","syncIntervalId","appInfo","appInfoSent","requestCounter","validationErrorCounter","serverErrorCounter","logger","instance","isValidClientId","isValidEnv","randomUUID","RequestCounter","ValidationErrorCounter","ServerErrorCounter","getLogger","startSync","handleShutdown","bind","getInstance","shutdown","stopSync","sendRequestsData","undefined","getHubUrlPrefix","baseURL","process","APITALLY_HUB_BASE_URL","version","makeHubRequest","url","payload","fetchWithRetry","fetchRetry","fetch","retries","retryDelay","retryOn","method","body","JSON","stringify","headers","ok","sync","setInterval","setTimeout","clearInterval","promises","push","sendAppInfo","Promise","all","error","setAppInfo","debug","instance_uuid","message_uuid","handled","handleHubError","message","newPayload","time_offset","requests","getAndResetRequests","validation_errors","getAndResetValidationErrors","server_errors","getAndResetServerErrors","Date","now","failedItems","length","queueItem","shift","time","timeOffset"]}
@@ -0,0 +1,36 @@
1
+ import { Logger } from './logging.cjs';
2
+ import RequestCounter from './requestCounter.cjs';
3
+ import ServerErrorCounter from './serverErrorCounter.cjs';
4
+ import { AppInfo, ApitallyConfig } from './types.cjs';
5
+ import ValidationErrorCounter from './validationErrorCounter.cjs';
6
+ import 'winston';
7
+
8
+ declare class ApitallyClient {
9
+ private clientId;
10
+ private env;
11
+ private static instance?;
12
+ private instanceUuid;
13
+ private requestsDataQueue;
14
+ private syncIntervalId?;
15
+ appInfo?: AppInfo;
16
+ private appInfoSent;
17
+ requestCounter: RequestCounter;
18
+ validationErrorCounter: ValidationErrorCounter;
19
+ serverErrorCounter: ServerErrorCounter;
20
+ logger: Logger;
21
+ constructor({ clientId, env, logger }: ApitallyConfig);
22
+ static getInstance(): ApitallyClient;
23
+ static shutdown(): Promise<void>;
24
+ handleShutdown(): Promise<void>;
25
+ private getHubUrlPrefix;
26
+ private makeHubRequest;
27
+ private startSync;
28
+ private sync;
29
+ private stopSync;
30
+ setAppInfo(appInfo: AppInfo): void;
31
+ private sendAppInfo;
32
+ private sendRequestsData;
33
+ private handleHubError;
34
+ }
35
+
36
+ export { ApitallyClient };
@@ -1,15 +1,16 @@
1
- import { Logger } from "./logging.js";
2
- import RequestCounter from "./requestCounter.js";
3
- import ServerErrorCounter from "./serverErrorCounter.js";
4
- import { ApitallyConfig, AppInfo } from "./types.js";
5
- import ValidationErrorCounter from "./validationErrorCounter.js";
6
- export declare class ApitallyClient {
1
+ import { Logger } from './logging.js';
2
+ import RequestCounter from './requestCounter.js';
3
+ import ServerErrorCounter from './serverErrorCounter.js';
4
+ import { AppInfo, ApitallyConfig } from './types.js';
5
+ import ValidationErrorCounter from './validationErrorCounter.js';
6
+ import 'winston';
7
+
8
+ declare class ApitallyClient {
7
9
  private clientId;
8
10
  private env;
9
11
  private static instance?;
10
12
  private instanceUuid;
11
13
  private requestsDataQueue;
12
- private axiosClient;
13
14
  private syncIntervalId?;
14
15
  appInfo?: AppInfo;
15
16
  private appInfoSent;
@@ -21,12 +22,15 @@ export declare class ApitallyClient {
21
22
  static getInstance(): ApitallyClient;
22
23
  static shutdown(): Promise<void>;
23
24
  handleShutdown(): Promise<void>;
24
- private getHubUrl;
25
+ private getHubUrlPrefix;
26
+ private makeHubRequest;
25
27
  private startSync;
26
28
  private sync;
27
29
  private stopSync;
28
30
  setAppInfo(appInfo: AppInfo): void;
29
31
  private sendAppInfo;
30
32
  private sendRequestsData;
33
+ private handleHubError;
31
34
  }
32
- //# sourceMappingURL=client.d.ts.map
35
+
36
+ export { ApitallyClient };