apitally 0.11.3 → 0.11.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -12
- package/dist/common/client.cjs +21 -18
- package/dist/common/client.cjs.map +1 -1
- package/dist/common/client.d.cts +2 -0
- package/dist/common/client.d.ts +2 -0
- package/dist/common/client.js +21 -18
- package/dist/common/client.js.map +1 -1
- package/dist/common/consumerRegistry.cjs.map +1 -1
- package/dist/common/consumerRegistry.js.map +1 -1
- package/dist/common/logging.cjs.map +1 -1
- package/dist/common/logging.js.map +1 -1
- package/dist/common/packageVersions.cjs.map +1 -1
- package/dist/common/packageVersions.js.map +1 -1
- package/dist/common/paramValidation.cjs.map +1 -1
- package/dist/common/paramValidation.js.map +1 -1
- package/dist/common/requestCounter.cjs.map +1 -1
- package/dist/common/requestCounter.js.map +1 -1
- package/dist/common/requestLogger.cjs +8 -5
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +1 -0
- package/dist/common/requestLogger.d.ts +1 -0
- package/dist/common/requestLogger.js +8 -5
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/serverErrorCounter.cjs.map +1 -1
- package/dist/common/serverErrorCounter.js.map +1 -1
- package/dist/common/tempGzipFile.cjs +2 -2
- package/dist/common/tempGzipFile.cjs.map +1 -1
- package/dist/common/tempGzipFile.js +2 -2
- package/dist/common/tempGzipFile.js.map +1 -1
- package/dist/common/types.cjs.map +1 -1
- package/dist/common/types.d.cts +1 -1
- package/dist/common/types.d.ts +1 -1
- package/dist/common/validationErrorCounter.cjs.map +1 -1
- package/dist/common/validationErrorCounter.js.map +1 -1
- package/dist/express/index.cjs +29 -19
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +29 -19
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +29 -19
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +29 -19
- package/dist/express/middleware.js.map +1 -1
- package/dist/express/utils.cjs.map +1 -1
- package/dist/express/utils.js.map +1 -1
- package/dist/fastify/index.cjs +26 -20
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +26 -20
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +26 -20
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +26 -20
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/hono/index.cjs +27 -19
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +27 -19
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +27 -19
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +27 -19
- package/dist/hono/middleware.js.map +1 -1
- package/dist/koa/index.cjs +25 -18
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +25 -18
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +25 -18
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +25 -18
- package/dist/koa/middleware.js.map +1 -1
- package/dist/nestjs/index.cjs +29 -19
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +29 -19
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["validationErrorCounter.ts"],"sourcesContent":["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":";;;;AAAA,SAASA,kBAAkB;AAQ3B,IAAqBC,0BAArB,MAAqBA,wBAAAA;EACXC;EACAC;EAERC,cAAc;AACZ,SAAKF,cAAc,oBAAIG,IAAAA;AACvB,SAAKF,eAAe,oBAAIE,IAAAA;EAC1B;EAEOC,mBACLC,iBACA;AACA,UAAMC,MAAM,KAAKC,OAAOF,eAAAA;AACxB,QAAI,CAAC,KAAKJ,aAAaO,IAAIF,GAAAA,GAAM;AAC/B,WAAKL,aAAaQ,IAAIH,KAAKD,eAAAA;IAC7B;AACA,SAAKL,YAAYS,IAAIH,MAAM,KAAKN,YAAYU,IAAIJ,GAAAA,KAAQ,KAAK,CAAA;EAC/D;EAEOK,8BAA8B;AACnC,UAAMC,OAAoC,CAAA;AAC1C,SAAKZ,YAAYa,QAAQ,CAACC,OAAOR,QAAAA;AAC/B,YAAMD,kBAAkB,KAAKJ,aAAaS,IAAIJ,GAAAA;AAC9C,UAAID,iBAAiB;AACnBO,aAAKG,KAAK;UACRC,UAAUX,gBAAgBW,YAAY;UACtCC,QAAQZ,gBAAgBY;UACxBC,MAAMb,gBAAgBa;UACtBC,KAAKd,gBAAgBc,IAAIC,MAAM,GAAA;UAC/BC,KAAKhB,gBAAgBgB;UACrBC,MAAMjB,gBAAgBiB;UACtBC,aAAaT;QACf,CAAA;MACF;IACF,CAAA;AACA,SAAKd,YAAYwB,MAAK;AACtB,SAAKvB,aAAauB,MAAK;AACvB,WAAOZ;EACT;EAEQL,OAAOF,iBAAuD;AACpE,UAAMoB,YAAY;MAChBpB,gBAAgBW,YAAY;MAC5BX,gBAAgBY,OAAOS,YAAW;MAClCrB,gBAAgBa;MAChBb,gBAAgBc;MAChBd,gBAAgBgB,IAAIM,KAAI;MACxBtB,gBAAgBiB;MAChBM,KAAK,GAAA;AACP,WAAOC,WAAW,KAAA,EAAOC,OAAOL,SAAAA,EAAWM,OAAO,KAAA;EACpD;AACF;AAnDqBhC;AAArB,IAAqBA,yBAArB;","names":["createHash","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"]}
|
package/dist/express/index.cjs
CHANGED
|
@@ -240,9 +240,9 @@ var _TempGzipFile = class _TempGzipFile {
|
|
|
240
240
|
this.writeStream.once("ready", resolve);
|
|
241
241
|
this.writeStream.once("error", reject);
|
|
242
242
|
});
|
|
243
|
-
this.closedPromise = new Promise((resolve) => {
|
|
243
|
+
this.closedPromise = new Promise((resolve, reject) => {
|
|
244
244
|
this.writeStream.once("close", resolve);
|
|
245
|
-
this.writeStream.once("error",
|
|
245
|
+
this.writeStream.once("error", reject);
|
|
246
246
|
});
|
|
247
247
|
this.gzip = (0, import_zlib.createGzip)();
|
|
248
248
|
this.gzip.pipe(this.writeStream);
|
|
@@ -392,7 +392,10 @@ var _RequestLogger = class _RequestLogger {
|
|
|
392
392
|
hasSupportedContentType(headers) {
|
|
393
393
|
var _a2;
|
|
394
394
|
const contentType = (_a2 = headers.find(([k]) => k.toLowerCase() === "content-type")) == null ? void 0 : _a2[1];
|
|
395
|
-
return
|
|
395
|
+
return this.isSupportedContentType(contentType);
|
|
396
|
+
}
|
|
397
|
+
isSupportedContentType(contentType) {
|
|
398
|
+
return typeof contentType === "string" && ALLOWED_CONTENT_TYPES.some((t) => contentType.startsWith(t));
|
|
396
399
|
}
|
|
397
400
|
maskQueryParams(search) {
|
|
398
401
|
const params = new URLSearchParams(search);
|
|
@@ -420,8 +423,6 @@ var _RequestLogger = class _RequestLogger {
|
|
|
420
423
|
}
|
|
421
424
|
url.search = this.config.logQueryParams ? this.maskQueryParams(url.search) : "";
|
|
422
425
|
request.url = url.toString();
|
|
423
|
-
request.headers = this.config.logRequestHeaders ? this.maskHeaders(request.headers) : [];
|
|
424
|
-
response.headers = this.config.logResponseHeaders ? this.maskHeaders(response.headers) : [];
|
|
425
426
|
if (!this.config.logRequestBody || !this.hasSupportedContentType(request.headers)) {
|
|
426
427
|
request.body = void 0;
|
|
427
428
|
} else if (request.body) {
|
|
@@ -454,6 +455,8 @@ var _RequestLogger = class _RequestLogger {
|
|
|
454
455
|
}
|
|
455
456
|
}
|
|
456
457
|
}
|
|
458
|
+
request.headers = this.config.logRequestHeaders ? this.maskHeaders(request.headers) : [];
|
|
459
|
+
response.headers = this.config.logResponseHeaders ? this.maskHeaders(response.headers) : [];
|
|
457
460
|
const item = {
|
|
458
461
|
uuid: (0, import_crypto2.randomUUID)(),
|
|
459
462
|
request: skipEmptyValues(request),
|
|
@@ -790,6 +793,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
790
793
|
syncIntervalId;
|
|
791
794
|
startupData;
|
|
792
795
|
startupDataSent = false;
|
|
796
|
+
enabled = true;
|
|
793
797
|
requestCounter;
|
|
794
798
|
requestLogger;
|
|
795
799
|
validationErrorCounter;
|
|
@@ -826,12 +830,16 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
826
830
|
}
|
|
827
831
|
return _ApitallyClient.instance;
|
|
828
832
|
}
|
|
833
|
+
isEnabled() {
|
|
834
|
+
return this.enabled;
|
|
835
|
+
}
|
|
829
836
|
static async shutdown() {
|
|
830
837
|
if (_ApitallyClient.instance) {
|
|
831
838
|
await _ApitallyClient.instance.handleShutdown();
|
|
832
839
|
}
|
|
833
840
|
}
|
|
834
841
|
async handleShutdown() {
|
|
842
|
+
this.enabled = false;
|
|
835
843
|
this.stopSync();
|
|
836
844
|
await this.sendSyncData();
|
|
837
845
|
await this.sendLogData();
|
|
@@ -931,7 +939,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
931
939
|
async sendSyncData() {
|
|
932
940
|
this.logger.debug("Synchronizing data with Apitally Hub");
|
|
933
941
|
const newPayload = {
|
|
934
|
-
|
|
942
|
+
timestamp: Date.now() / 1e3,
|
|
935
943
|
instance_uuid: this.instanceUuid,
|
|
936
944
|
message_uuid: (0, import_crypto5.randomUUID)(),
|
|
937
945
|
requests: this.requestCounter.getAndResetRequests(),
|
|
@@ -939,22 +947,16 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
939
947
|
server_errors: this.serverErrorCounter.getAndResetServerErrors(),
|
|
940
948
|
consumers: this.consumerRegistry.getAndResetUpdatedConsumers()
|
|
941
949
|
};
|
|
942
|
-
this.syncDataQueue.push(
|
|
943
|
-
Date.now(),
|
|
944
|
-
newPayload
|
|
945
|
-
]);
|
|
950
|
+
this.syncDataQueue.push(newPayload);
|
|
946
951
|
let i = 0;
|
|
947
952
|
while (this.syncDataQueue.length > 0) {
|
|
948
|
-
const
|
|
949
|
-
if (
|
|
950
|
-
const [time, payload] = queueItem;
|
|
953
|
+
const payload = this.syncDataQueue.shift();
|
|
954
|
+
if (payload) {
|
|
951
955
|
try {
|
|
952
|
-
|
|
953
|
-
if (timeOffset <= MAX_QUEUE_TIME) {
|
|
956
|
+
if (Date.now() - payload.timestamp * 1e3 <= MAX_QUEUE_TIME) {
|
|
954
957
|
if (i > 0) {
|
|
955
958
|
await this.randomDelay();
|
|
956
959
|
}
|
|
957
|
-
payload.time_offset = timeOffset / 1e3;
|
|
958
960
|
await this.sendData("sync", payload);
|
|
959
961
|
i += 1;
|
|
960
962
|
}
|
|
@@ -964,7 +966,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
964
966
|
this.logger.debug("Error while synchronizing data with Apitally Hub (will retry)", {
|
|
965
967
|
error
|
|
966
968
|
});
|
|
967
|
-
this.syncDataQueue.push(
|
|
969
|
+
this.syncDataQueue.push(payload);
|
|
968
970
|
break;
|
|
969
971
|
}
|
|
970
972
|
}
|
|
@@ -1021,6 +1023,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
1021
1023
|
if (error instanceof HTTPError) {
|
|
1022
1024
|
if (error.response.status === 404) {
|
|
1023
1025
|
this.logger.error(`Invalid Apitally client ID: '${this.clientId}'`);
|
|
1026
|
+
this.enabled = false;
|
|
1024
1027
|
this.stopSync();
|
|
1025
1028
|
return true;
|
|
1026
1029
|
}
|
|
@@ -1032,7 +1035,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
1032
1035
|
return false;
|
|
1033
1036
|
}
|
|
1034
1037
|
async randomDelay() {
|
|
1035
|
-
const delay = 100 + Math.random() *
|
|
1038
|
+
const delay = 100 + Math.random() * 400;
|
|
1036
1039
|
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
1037
1040
|
}
|
|
1038
1041
|
};
|
|
@@ -1196,6 +1199,10 @@ var useApitally = /* @__PURE__ */ __name((app, config) => {
|
|
|
1196
1199
|
var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
1197
1200
|
let errorHandlerConfigured = false;
|
|
1198
1201
|
return (req, res, next) => {
|
|
1202
|
+
if (!client.isEnabled()) {
|
|
1203
|
+
next();
|
|
1204
|
+
return;
|
|
1205
|
+
}
|
|
1199
1206
|
if (!errorHandlerConfigured) {
|
|
1200
1207
|
app.use((err, req2, res2, next2) => {
|
|
1201
1208
|
res2.locals.serverError = err;
|
|
@@ -1207,7 +1214,10 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
1207
1214
|
const startTime = import_perf_hooks.performance.now();
|
|
1208
1215
|
const originalSend = res.send;
|
|
1209
1216
|
res.send = (body) => {
|
|
1210
|
-
|
|
1217
|
+
const contentType = res.get("content-type");
|
|
1218
|
+
if (client.requestLogger.isSupportedContentType(contentType)) {
|
|
1219
|
+
res.locals.body = body;
|
|
1220
|
+
}
|
|
1211
1221
|
return originalSend.call(res, body);
|
|
1212
1222
|
};
|
|
1213
1223
|
res.on("finish", () => {
|