apitally 0.11.4 → 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.
- package/README.md +27 -14
- package/dist/common/client.cjs +130 -110
- 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 +125 -105
- 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 +63 -7
- package/dist/common/requestLogger.cjs.map +1 -1
- package/dist/common/requestLogger.d.cts +3 -1
- package/dist/common/requestLogger.d.ts +3 -1
- package/dist/common/requestLogger.js +63 -7
- package/dist/common/requestLogger.js.map +1 -1
- package/dist/common/sentry.cjs +55 -0
- package/dist/common/sentry.cjs.map +1 -0
- package/dist/common/sentry.d.cts +6 -0
- package/dist/common/sentry.d.ts +6 -0
- package/dist/common/sentry.js +22 -0
- package/dist/common/sentry.js.map +1 -0
- package/dist/common/serverErrorCounter.cjs +58 -45
- package/dist/common/serverErrorCounter.cjs.map +1 -1
- package/dist/common/serverErrorCounter.d.cts +3 -6
- package/dist/common/serverErrorCounter.d.ts +3 -6
- package/dist/common/serverErrorCounter.js +53 -45
- 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/validationErrorCounter.cjs.map +1 -1
- package/dist/common/validationErrorCounter.js.map +1 -1
- package/dist/express/index.cjs +139 -112
- package/dist/express/index.cjs.map +1 -1
- package/dist/express/index.js +134 -107
- package/dist/express/index.js.map +1 -1
- package/dist/express/middleware.cjs +139 -112
- package/dist/express/middleware.cjs.map +1 -1
- package/dist/express/middleware.js +134 -107
- 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 +136 -113
- package/dist/fastify/index.cjs.map +1 -1
- package/dist/fastify/index.js +131 -108
- package/dist/fastify/index.js.map +1 -1
- package/dist/fastify/plugin.cjs +136 -113
- package/dist/fastify/plugin.cjs.map +1 -1
- package/dist/fastify/plugin.js +131 -108
- package/dist/fastify/plugin.js.map +1 -1
- package/dist/hono/index.cjs +137 -112
- package/dist/hono/index.cjs.map +1 -1
- package/dist/hono/index.js +132 -107
- package/dist/hono/index.js.map +1 -1
- package/dist/hono/middleware.cjs +137 -112
- package/dist/hono/middleware.cjs.map +1 -1
- package/dist/hono/middleware.js +132 -107
- package/dist/hono/middleware.js.map +1 -1
- package/dist/koa/index.cjs +137 -111
- package/dist/koa/index.cjs.map +1 -1
- package/dist/koa/index.js +132 -106
- package/dist/koa/index.js.map +1 -1
- package/dist/koa/middleware.cjs +137 -111
- package/dist/koa/middleware.cjs.map +1 -1
- package/dist/koa/middleware.js +132 -106
- package/dist/koa/middleware.js.map +1 -1
- package/dist/nestjs/index.cjs +139 -112
- package/dist/nestjs/index.cjs.map +1 -1
- package/dist/nestjs/index.js +134 -107
- package/dist/nestjs/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -45,9 +45,9 @@ var _TempGzipFile = class _TempGzipFile {
|
|
|
45
45
|
this.writeStream.once("ready", resolve);
|
|
46
46
|
this.writeStream.once("error", reject);
|
|
47
47
|
});
|
|
48
|
-
this.closedPromise = new Promise((resolve) => {
|
|
48
|
+
this.closedPromise = new Promise((resolve, reject) => {
|
|
49
49
|
this.writeStream.once("close", resolve);
|
|
50
|
-
this.writeStream.once("error",
|
|
50
|
+
this.writeStream.once("error", reject);
|
|
51
51
|
});
|
|
52
52
|
this.gzip = (0, import_zlib.createGzip)();
|
|
53
53
|
this.gzip.pipe(this.writeStream);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["tempGzipFile.ts"],"sourcesContent":["import { Buffer } from \"buffer\";\nimport { randomUUID } from \"crypto\";\nimport { createWriteStream, readFile, unlinkSync, WriteStream } from \"fs\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nimport { createGzip, Gzip } from \"zlib\";\n\nexport default class TempGzipFile {\n public uuid: string;\n private filePath: string;\n private gzip: Gzip;\n private writeStream: WriteStream;\n private readyPromise: Promise<void>;\n private closedPromise: Promise<void>;\n\n constructor() {\n this.uuid = randomUUID();\n this.filePath = join(tmpdir(), `apitally-${this.uuid}.gz`);\n this.writeStream = createWriteStream(this.filePath);\n this.readyPromise = new Promise<void>((resolve, reject) => {\n this.writeStream.once(\"ready\", resolve);\n this.writeStream.once(\"error\", reject);\n });\n this.closedPromise = new Promise<void>((resolve, reject) => {\n this.writeStream.once(\"close\", resolve);\n this.writeStream.once(\"error\", reject);\n });\n this.gzip = createGzip();\n this.gzip.pipe(this.writeStream);\n }\n\n get size() {\n return this.writeStream.bytesWritten;\n }\n\n async writeLine(data: Buffer) {\n await this.readyPromise;\n return new Promise<void>((resolve, reject) => {\n this.gzip.write(Buffer.concat([data, Buffer.from(\"\\n\")]), (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n async getContent() {\n return new Promise<Buffer>((resolve, reject) => {\n readFile(this.filePath, (error, data) => {\n if (error) {\n reject(error);\n } else {\n resolve(data);\n }\n });\n });\n }\n\n async close() {\n await new Promise<void>((resolve) => {\n this.gzip.end(() => {\n resolve();\n });\n });\n await this.closedPromise;\n }\n\n async delete() {\n await this.close();\n unlinkSync(this.filePath);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;oBAAuB;AACvB,oBAA2B;AAC3B,gBAAqE;AACrE,gBAAuB;AACvB,kBAAqB;AACrB,kBAAiC;AAEjC,IAAqBA,gBAArB,MAAqBA,cAAAA;EACZC;EACCC;EACAC;EACAC;EACAC;EACAC;EAERC,cAAc;AACZ,SAAKN,WAAOO,0BAAAA;AACZ,SAAKN,eAAWO,sBAAKC,kBAAAA,GAAU,YAAY,KAAKT,IAAI,KAAK;AACzD,SAAKG,kBAAcO,6BAAkB,KAAKT,QAAQ;AAClD,SAAKG,eAAe,IAAIO,QAAc,CAACC,SAASC,WAAAA;AAC9C,WAAKV,YAAYW,KAAK,SAASF,OAAAA;AAC/B,WAAKT,YAAYW,KAAK,SAASD,MAAAA;IACjC,CAAA;AACA,SAAKR,gBAAgB,IAAIM,QAAc,CAACC,SAASC,WAAAA;AAC/C,WAAKV,YAAYW,KAAK,SAASF,OAAAA;AAC/B,WAAKT,YAAYW,KAAK,SAASD,MAAAA;IACjC,CAAA;AACA,SAAKX,WAAOa,wBAAAA;AACZ,SAAKb,KAAKc,KAAK,KAAKb,WAAW;EACjC;EAEA,IAAIc,OAAO;AACT,WAAO,KAAKd,YAAYe;EAC1B;EAEA,MAAMC,UAAUC,MAAc;AAC5B,UAAM,KAAKhB;AACX,WAAO,IAAIO,QAAc,CAACC,SAASC,WAAAA;AACjC,WAAKX,KAAKmB,MAAMC,qBAAOC,OAAO;QAACH;QAAME,qBAAOE,KAAK,IAAA;OAAM,GAAG,CAACC,UAAAA;AACzD,YAAIA,OAAO;AACTZ,iBAAOY,KAAAA;QACT,OAAO;AACLb,kBAAAA;QACF;MACF,CAAA;IACF,CAAA;EACF;EAEA,MAAMc,aAAa;AACjB,WAAO,IAAIf,QAAgB,CAACC,SAASC,WAAAA;AACnCc,8BAAS,KAAK1B,UAAU,CAACwB,OAAOL,SAAAA;AAC9B,YAAIK,OAAO;AACTZ,iBAAOY,KAAAA;QACT,OAAO;AACLb,kBAAQQ,IAAAA;QACV;MACF,CAAA;IACF,CAAA;EACF;EAEA,MAAMQ,QAAQ;AACZ,UAAM,IAAIjB,QAAc,CAACC,YAAAA;AACvB,WAAKV,KAAK2B,IAAI,MAAA;AACZjB,gBAAAA;MACF,CAAA;IACF,CAAA;AACA,UAAM,KAAKP;EACb;EAEA,MAAMyB,SAAS;AACb,UAAM,KAAKF,MAAK;AAChBG,8BAAW,KAAK9B,QAAQ;EAC1B;AACF;AAlEqBF;AAArB,IAAqBA,eAArB;","names":["TempGzipFile","uuid","filePath","gzip","writeStream","readyPromise","closedPromise","constructor","randomUUID","join","tmpdir","createWriteStream","Promise","resolve","reject","once","createGzip","pipe","size","bytesWritten","writeLine","data","write","Buffer","concat","from","error","getContent","readFile","close","end","delete","unlinkSync"]}
|
|
@@ -23,9 +23,9 @@ var _TempGzipFile = class _TempGzipFile {
|
|
|
23
23
|
this.writeStream.once("ready", resolve);
|
|
24
24
|
this.writeStream.once("error", reject);
|
|
25
25
|
});
|
|
26
|
-
this.closedPromise = new Promise((resolve) => {
|
|
26
|
+
this.closedPromise = new Promise((resolve, reject) => {
|
|
27
27
|
this.writeStream.once("close", resolve);
|
|
28
|
-
this.writeStream.once("error",
|
|
28
|
+
this.writeStream.once("error", reject);
|
|
29
29
|
});
|
|
30
30
|
this.gzip = createGzip();
|
|
31
31
|
this.gzip.pipe(this.writeStream);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["tempGzipFile.ts"],"sourcesContent":["import { Buffer } from \"buffer\";\nimport { randomUUID } from \"crypto\";\nimport { createWriteStream, readFile, unlinkSync, WriteStream } from \"fs\";\nimport { tmpdir } from \"os\";\nimport { join } from \"path\";\nimport { createGzip, Gzip } from \"zlib\";\n\nexport default class TempGzipFile {\n public uuid: string;\n private filePath: string;\n private gzip: Gzip;\n private writeStream: WriteStream;\n private readyPromise: Promise<void>;\n private closedPromise: Promise<void>;\n\n constructor() {\n this.uuid = randomUUID();\n this.filePath = join(tmpdir(), `apitally-${this.uuid}.gz`);\n this.writeStream = createWriteStream(this.filePath);\n this.readyPromise = new Promise<void>((resolve, reject) => {\n this.writeStream.once(\"ready\", resolve);\n this.writeStream.once(\"error\", reject);\n });\n this.closedPromise = new Promise<void>((resolve, reject) => {\n this.writeStream.once(\"close\", resolve);\n this.writeStream.once(\"error\", reject);\n });\n this.gzip = createGzip();\n this.gzip.pipe(this.writeStream);\n }\n\n get size() {\n return this.writeStream.bytesWritten;\n }\n\n async writeLine(data: Buffer) {\n await this.readyPromise;\n return new Promise<void>((resolve, reject) => {\n this.gzip.write(Buffer.concat([data, Buffer.from(\"\\n\")]), (error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n }\n\n async getContent() {\n return new Promise<Buffer>((resolve, reject) => {\n readFile(this.filePath, (error, data) => {\n if (error) {\n reject(error);\n } else {\n resolve(data);\n }\n });\n });\n }\n\n async close() {\n await new Promise<void>((resolve) => {\n this.gzip.end(() => {\n resolve();\n });\n });\n await this.closedPromise;\n }\n\n async delete() {\n await this.close();\n unlinkSync(this.filePath);\n }\n}\n"],"mappings":";;;;AAAA,SAASA,UAAAA,eAAc;AACvB,SAASC,kBAAkB;AAC3B,SAASC,mBAAmBC,UAAUC,kBAA+B;AACrE,SAASC,cAAc;AACvB,SAASC,YAAY;AACrB,SAASC,kBAAwB;AAEjC,IAAqBC,gBAArB,MAAqBA,cAAAA;EACZC;EACCC;EACAC;EACAC;EACAC;EACAC;EAERC,cAAc;AACZ,SAAKN,OAAOO,WAAAA;AACZ,SAAKN,WAAWO,KAAKC,OAAAA,GAAU,YAAY,KAAKT,IAAI,KAAK;AACzD,SAAKG,cAAcO,kBAAkB,KAAKT,QAAQ;AAClD,SAAKG,eAAe,IAAIO,QAAc,CAACC,SAASC,WAAAA;AAC9C,WAAKV,YAAYW,KAAK,SAASF,OAAAA;AAC/B,WAAKT,YAAYW,KAAK,SAASD,MAAAA;IACjC,CAAA;AACA,SAAKR,gBAAgB,IAAIM,QAAc,CAACC,SAASC,WAAAA;AAC/C,WAAKV,YAAYW,KAAK,SAASF,OAAAA;AAC/B,WAAKT,YAAYW,KAAK,SAASD,MAAAA;IACjC,CAAA;AACA,SAAKX,OAAOa,WAAAA;AACZ,SAAKb,KAAKc,KAAK,KAAKb,WAAW;EACjC;EAEA,IAAIc,OAAO;AACT,WAAO,KAAKd,YAAYe;EAC1B;EAEA,MAAMC,UAAUC,MAAc;AAC5B,UAAM,KAAKhB;AACX,WAAO,IAAIO,QAAc,CAACC,SAASC,WAAAA;AACjC,WAAKX,KAAKmB,MAAMC,QAAOC,OAAO;QAACH;QAAME,QAAOE,KAAK,IAAA;OAAM,GAAG,CAACC,UAAAA;AACzD,YAAIA,OAAO;AACTZ,iBAAOY,KAAAA;QACT,OAAO;AACLb,kBAAAA;QACF;MACF,CAAA;IACF,CAAA;EACF;EAEA,MAAMc,aAAa;AACjB,WAAO,IAAIf,QAAgB,CAACC,SAASC,WAAAA;AACnCc,eAAS,KAAK1B,UAAU,CAACwB,OAAOL,SAAAA;AAC9B,YAAIK,OAAO;AACTZ,iBAAOY,KAAAA;QACT,OAAO;AACLb,kBAAQQ,IAAAA;QACV;MACF,CAAA;IACF,CAAA;EACF;EAEA,MAAMQ,QAAQ;AACZ,UAAM,IAAIjB,QAAc,CAACC,YAAAA;AACvB,WAAKV,KAAK2B,IAAI,MAAA;AACZjB,gBAAAA;MACF,CAAA;IACF,CAAA;AACA,UAAM,KAAKP;EACb;EAEA,MAAMyB,SAAS;AACb,UAAM,KAAKF,MAAK;AAChBG,eAAW,KAAK9B,QAAQ;EAC1B;AACF;AAlEqBF;AAArB,IAAqBA,eAArB;","names":["Buffer","randomUUID","createWriteStream","readFile","unlinkSync","tmpdir","join","createGzip","TempGzipFile","uuid","filePath","gzip","writeStream","readyPromise","closedPromise","constructor","randomUUID","join","tmpdir","createWriteStream","Promise","resolve","reject","once","createGzip","pipe","size","bytesWritten","writeLine","data","write","Buffer","concat","from","error","getContent","readFile","close","end","delete","unlinkSync"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["
|
|
1
|
+
{"version":3,"sources":["types.ts"],"sourcesContent":["import { Logger } from \"./logging.js\";\nimport { RequestLoggingConfig } from \"./requestLogger.js\";\n\nexport type ApitallyConfig = {\n clientId: string;\n env?: string;\n requestLoggingConfig?: Partial<RequestLoggingConfig>;\n openApiUrl?: string;\n appVersion?: string;\n logger?: Logger;\n};\n\nexport type ApitallyConsumer = {\n identifier: string;\n name?: string | null;\n group?: string | null;\n};\n\nexport type PathInfo = {\n method: string;\n path: string;\n};\n\nexport type StartupData = {\n paths: PathInfo[];\n versions: Record<string, string>;\n client: string;\n};\n\nexport type StartupPayload = {\n instance_uuid: string;\n message_uuid: string;\n} & StartupData;\n\nexport type ConsumerMethodPath = {\n consumer?: string | null;\n method: string;\n path: string;\n};\n\nexport type RequestInfo = ConsumerMethodPath & {\n statusCode: number;\n responseTime: number;\n requestSize?: string | number | null;\n responseSize?: string | number | null;\n};\n\nexport type RequestsItem = ConsumerMethodPath & {\n status_code: number;\n request_count: number;\n request_size_sum: number;\n response_size_sum: number;\n response_times: Record<number, number>;\n request_sizes: Record<number, number>;\n response_sizes: Record<number, number>;\n};\n\nexport type ValidationError = {\n loc: string;\n msg: string;\n type: string;\n};\n\nexport type ValidationErrorsItem = ConsumerMethodPath & {\n loc: Array<string>;\n msg: string;\n type: string;\n error_count: number;\n};\n\nexport type ServerError = {\n type: string;\n msg: string;\n traceback: string;\n};\n\nexport type ServerErrorsItem = ConsumerMethodPath & {\n type: string;\n msg: string;\n traceback: string;\n sentry_event_id: string | null;\n error_count: number;\n};\n\nexport type ConsumerItem = ApitallyConsumer;\n\nexport type SyncPayload = {\n timestamp: number;\n instance_uuid: string;\n message_uuid: string;\n requests: Array<RequestsItem>;\n validation_errors: Array<ValidationErrorsItem>;\n server_errors: Array<ServerErrorsItem>;\n consumers: Array<ConsumerItem>;\n};\n"],"mappings":";;;;;;;;;;;;;;;;AAsFA;;","names":[]}
|
|
@@ -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;;;;;oBAA2B;AAQ3B,IAAqBA,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,eAAOC,0BAAW,KAAA,EAAOC,OAAOL,SAAAA,EAAWM,OAAO,KAAA;EACpD;AACF;AAnDqBhC;AAArB,IAAqBA,yBAArB;","names":["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"]}
|
|
@@ -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
|
@@ -213,14 +213,116 @@ var RequestCounter = _RequestCounter;
|
|
|
213
213
|
// src/common/requestLogger.ts
|
|
214
214
|
var import_async_lock = __toESM(require("async-lock"), 1);
|
|
215
215
|
var import_buffer2 = require("buffer");
|
|
216
|
-
var
|
|
216
|
+
var import_crypto3 = require("crypto");
|
|
217
217
|
var import_fs2 = require("fs");
|
|
218
218
|
var import_os2 = require("os");
|
|
219
219
|
var import_path2 = require("path");
|
|
220
220
|
|
|
221
|
+
// src/common/sentry.ts
|
|
222
|
+
var sentry;
|
|
223
|
+
(async () => {
|
|
224
|
+
try {
|
|
225
|
+
sentry = await import("@sentry/node");
|
|
226
|
+
} catch (e) {
|
|
227
|
+
}
|
|
228
|
+
})();
|
|
229
|
+
function getSentryEventId() {
|
|
230
|
+
if (sentry && sentry.lastEventId) {
|
|
231
|
+
return sentry.lastEventId();
|
|
232
|
+
}
|
|
233
|
+
return void 0;
|
|
234
|
+
}
|
|
235
|
+
__name(getSentryEventId, "getSentryEventId");
|
|
236
|
+
|
|
237
|
+
// src/common/serverErrorCounter.ts
|
|
238
|
+
var import_crypto = require("crypto");
|
|
239
|
+
var MAX_MSG_LENGTH = 2048;
|
|
240
|
+
var MAX_STACKTRACE_LENGTH = 65536;
|
|
241
|
+
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
242
|
+
errorCounts;
|
|
243
|
+
errorDetails;
|
|
244
|
+
sentryEventIds;
|
|
245
|
+
constructor() {
|
|
246
|
+
this.errorCounts = /* @__PURE__ */ new Map();
|
|
247
|
+
this.errorDetails = /* @__PURE__ */ new Map();
|
|
248
|
+
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
249
|
+
}
|
|
250
|
+
addServerError(serverError) {
|
|
251
|
+
const key = this.getKey(serverError);
|
|
252
|
+
if (!this.errorDetails.has(key)) {
|
|
253
|
+
this.errorDetails.set(key, serverError);
|
|
254
|
+
}
|
|
255
|
+
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
256
|
+
const sentryEventId = getSentryEventId();
|
|
257
|
+
if (sentryEventId) {
|
|
258
|
+
this.sentryEventIds.set(key, sentryEventId);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
getAndResetServerErrors() {
|
|
262
|
+
const data = [];
|
|
263
|
+
this.errorCounts.forEach((count, key) => {
|
|
264
|
+
const serverError = this.errorDetails.get(key);
|
|
265
|
+
if (serverError) {
|
|
266
|
+
data.push({
|
|
267
|
+
consumer: serverError.consumer || null,
|
|
268
|
+
method: serverError.method,
|
|
269
|
+
path: serverError.path,
|
|
270
|
+
type: serverError.type,
|
|
271
|
+
msg: truncateExceptionMessage(serverError.msg),
|
|
272
|
+
traceback: truncateExceptionStackTrace(serverError.traceback),
|
|
273
|
+
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
274
|
+
error_count: count
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
this.errorCounts.clear();
|
|
279
|
+
this.errorDetails.clear();
|
|
280
|
+
return data;
|
|
281
|
+
}
|
|
282
|
+
getKey(serverError) {
|
|
283
|
+
const hashInput = [
|
|
284
|
+
serverError.consumer || "",
|
|
285
|
+
serverError.method.toUpperCase(),
|
|
286
|
+
serverError.path,
|
|
287
|
+
serverError.type,
|
|
288
|
+
serverError.msg.trim(),
|
|
289
|
+
serverError.traceback.trim()
|
|
290
|
+
].join("|");
|
|
291
|
+
return (0, import_crypto.createHash)("md5").update(hashInput).digest("hex");
|
|
292
|
+
}
|
|
293
|
+
};
|
|
294
|
+
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
295
|
+
var ServerErrorCounter = _ServerErrorCounter;
|
|
296
|
+
function truncateExceptionMessage(msg) {
|
|
297
|
+
if (msg.length <= MAX_MSG_LENGTH) {
|
|
298
|
+
return msg;
|
|
299
|
+
}
|
|
300
|
+
const suffix = "... (truncated)";
|
|
301
|
+
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
302
|
+
return msg.substring(0, cutoff) + suffix;
|
|
303
|
+
}
|
|
304
|
+
__name(truncateExceptionMessage, "truncateExceptionMessage");
|
|
305
|
+
function truncateExceptionStackTrace(stack) {
|
|
306
|
+
const suffix = "... (truncated) ...";
|
|
307
|
+
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
308
|
+
const lines = stack.trim().split("\n");
|
|
309
|
+
const truncatedLines = [];
|
|
310
|
+
let length = 0;
|
|
311
|
+
for (const line of lines) {
|
|
312
|
+
if (length + line.length + 1 > cutoff) {
|
|
313
|
+
truncatedLines.push(suffix);
|
|
314
|
+
break;
|
|
315
|
+
}
|
|
316
|
+
truncatedLines.push(line);
|
|
317
|
+
length += line.length + 1;
|
|
318
|
+
}
|
|
319
|
+
return truncatedLines.join("\n");
|
|
320
|
+
}
|
|
321
|
+
__name(truncateExceptionStackTrace, "truncateExceptionStackTrace");
|
|
322
|
+
|
|
221
323
|
// src/common/tempGzipFile.ts
|
|
222
324
|
var import_buffer = require("buffer");
|
|
223
|
-
var
|
|
325
|
+
var import_crypto2 = require("crypto");
|
|
224
326
|
var import_fs = require("fs");
|
|
225
327
|
var import_os = require("os");
|
|
226
328
|
var import_path = require("path");
|
|
@@ -233,16 +335,16 @@ var _TempGzipFile = class _TempGzipFile {
|
|
|
233
335
|
readyPromise;
|
|
234
336
|
closedPromise;
|
|
235
337
|
constructor() {
|
|
236
|
-
this.uuid = (0,
|
|
338
|
+
this.uuid = (0, import_crypto2.randomUUID)();
|
|
237
339
|
this.filePath = (0, import_path.join)((0, import_os.tmpdir)(), `apitally-${this.uuid}.gz`);
|
|
238
340
|
this.writeStream = (0, import_fs.createWriteStream)(this.filePath);
|
|
239
341
|
this.readyPromise = new Promise((resolve, reject) => {
|
|
240
342
|
this.writeStream.once("ready", resolve);
|
|
241
343
|
this.writeStream.once("error", reject);
|
|
242
344
|
});
|
|
243
|
-
this.closedPromise = new Promise((resolve) => {
|
|
345
|
+
this.closedPromise = new Promise((resolve, reject) => {
|
|
244
346
|
this.writeStream.once("close", resolve);
|
|
245
|
-
this.writeStream.once("error",
|
|
347
|
+
this.writeStream.once("error", reject);
|
|
246
348
|
});
|
|
247
349
|
this.gzip = (0, import_zlib.createGzip)();
|
|
248
350
|
this.gzip.pipe(this.writeStream);
|
|
@@ -340,6 +442,7 @@ var DEFAULT_CONFIG = {
|
|
|
340
442
|
logRequestBody: false,
|
|
341
443
|
logResponseHeaders: true,
|
|
342
444
|
logResponseBody: false,
|
|
445
|
+
logException: true,
|
|
343
446
|
maskQueryParams: [],
|
|
344
447
|
maskHeaders: [],
|
|
345
448
|
excludePaths: []
|
|
@@ -392,7 +495,10 @@ var _RequestLogger = class _RequestLogger {
|
|
|
392
495
|
hasSupportedContentType(headers) {
|
|
393
496
|
var _a2;
|
|
394
497
|
const contentType = (_a2 = headers.find(([k]) => k.toLowerCase() === "content-type")) == null ? void 0 : _a2[1];
|
|
395
|
-
return
|
|
498
|
+
return this.isSupportedContentType(contentType);
|
|
499
|
+
}
|
|
500
|
+
isSupportedContentType(contentType) {
|
|
501
|
+
return typeof contentType === "string" && ALLOWED_CONTENT_TYPES.some((t) => contentType.startsWith(t));
|
|
396
502
|
}
|
|
397
503
|
maskQueryParams(search) {
|
|
398
504
|
const params = new URLSearchParams(search);
|
|
@@ -409,7 +515,7 @@ var _RequestLogger = class _RequestLogger {
|
|
|
409
515
|
this.shouldMaskHeader(k) ? MASKED : v
|
|
410
516
|
]);
|
|
411
517
|
}
|
|
412
|
-
logRequest(request, response) {
|
|
518
|
+
logRequest(request, response, error) {
|
|
413
519
|
var _a2, _b, _c;
|
|
414
520
|
if (!this.enabled || this.suspendUntil !== null) return;
|
|
415
521
|
const url = new URL(request.url);
|
|
@@ -420,8 +526,6 @@ var _RequestLogger = class _RequestLogger {
|
|
|
420
526
|
}
|
|
421
527
|
url.search = this.config.logQueryParams ? this.maskQueryParams(url.search) : "";
|
|
422
528
|
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
529
|
if (!this.config.logRequestBody || !this.hasSupportedContentType(request.headers)) {
|
|
426
530
|
request.body = void 0;
|
|
427
531
|
} else if (request.body) {
|
|
@@ -454,10 +558,18 @@ var _RequestLogger = class _RequestLogger {
|
|
|
454
558
|
}
|
|
455
559
|
}
|
|
456
560
|
}
|
|
561
|
+
request.headers = this.config.logRequestHeaders ? this.maskHeaders(request.headers) : [];
|
|
562
|
+
response.headers = this.config.logResponseHeaders ? this.maskHeaders(response.headers) : [];
|
|
457
563
|
const item = {
|
|
458
|
-
uuid: (0,
|
|
564
|
+
uuid: (0, import_crypto3.randomUUID)(),
|
|
459
565
|
request: skipEmptyValues(request),
|
|
460
|
-
response: skipEmptyValues(response)
|
|
566
|
+
response: skipEmptyValues(response),
|
|
567
|
+
exception: error && this.config.logException ? {
|
|
568
|
+
type: error.name,
|
|
569
|
+
message: truncateExceptionMessage(error.message),
|
|
570
|
+
stacktrace: truncateExceptionStackTrace(error.stack || ""),
|
|
571
|
+
sentryEventId: getSentryEventId()
|
|
572
|
+
} : null
|
|
461
573
|
};
|
|
462
574
|
[
|
|
463
575
|
item.request.body,
|
|
@@ -609,7 +721,7 @@ function skipEmptyValues(data) {
|
|
|
609
721
|
__name(skipEmptyValues, "skipEmptyValues");
|
|
610
722
|
function checkWritableFs() {
|
|
611
723
|
try {
|
|
612
|
-
const testPath = (0, import_path2.join)((0, import_os2.tmpdir)(), `apitally-${(0,
|
|
724
|
+
const testPath = (0, import_path2.join)((0, import_os2.tmpdir)(), `apitally-${(0, import_crypto3.randomUUID)()}`);
|
|
613
725
|
(0, import_fs2.writeFileSync)(testPath, "test");
|
|
614
726
|
(0, import_fs2.unlinkSync)(testPath);
|
|
615
727
|
return true;
|
|
@@ -619,104 +731,6 @@ function checkWritableFs() {
|
|
|
619
731
|
}
|
|
620
732
|
__name(checkWritableFs, "checkWritableFs");
|
|
621
733
|
|
|
622
|
-
// src/common/serverErrorCounter.ts
|
|
623
|
-
var import_crypto3 = require("crypto");
|
|
624
|
-
var MAX_MSG_LENGTH = 2048;
|
|
625
|
-
var MAX_STACKTRACE_LENGTH = 65536;
|
|
626
|
-
var _ServerErrorCounter = class _ServerErrorCounter {
|
|
627
|
-
errorCounts;
|
|
628
|
-
errorDetails;
|
|
629
|
-
sentryEventIds;
|
|
630
|
-
sentry;
|
|
631
|
-
constructor() {
|
|
632
|
-
this.errorCounts = /* @__PURE__ */ new Map();
|
|
633
|
-
this.errorDetails = /* @__PURE__ */ new Map();
|
|
634
|
-
this.sentryEventIds = /* @__PURE__ */ new Map();
|
|
635
|
-
this.tryImportSentry();
|
|
636
|
-
}
|
|
637
|
-
addServerError(serverError) {
|
|
638
|
-
const key = this.getKey(serverError);
|
|
639
|
-
if (!this.errorDetails.has(key)) {
|
|
640
|
-
this.errorDetails.set(key, serverError);
|
|
641
|
-
}
|
|
642
|
-
this.errorCounts.set(key, (this.errorCounts.get(key) || 0) + 1);
|
|
643
|
-
this.captureSentryEventId(key);
|
|
644
|
-
}
|
|
645
|
-
getAndResetServerErrors() {
|
|
646
|
-
const data = [];
|
|
647
|
-
this.errorCounts.forEach((count, key) => {
|
|
648
|
-
const serverError = this.errorDetails.get(key);
|
|
649
|
-
if (serverError) {
|
|
650
|
-
data.push({
|
|
651
|
-
consumer: serverError.consumer || null,
|
|
652
|
-
method: serverError.method,
|
|
653
|
-
path: serverError.path,
|
|
654
|
-
type: serverError.type,
|
|
655
|
-
msg: this.getTruncatedMessage(serverError.msg),
|
|
656
|
-
traceback: this.getTruncatedStack(serverError.traceback),
|
|
657
|
-
sentry_event_id: this.sentryEventIds.get(key) || null,
|
|
658
|
-
error_count: count
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
});
|
|
662
|
-
this.errorCounts.clear();
|
|
663
|
-
this.errorDetails.clear();
|
|
664
|
-
return data;
|
|
665
|
-
}
|
|
666
|
-
getKey(serverError) {
|
|
667
|
-
const hashInput = [
|
|
668
|
-
serverError.consumer || "",
|
|
669
|
-
serverError.method.toUpperCase(),
|
|
670
|
-
serverError.path,
|
|
671
|
-
serverError.type,
|
|
672
|
-
serverError.msg.trim(),
|
|
673
|
-
serverError.traceback.trim()
|
|
674
|
-
].join("|");
|
|
675
|
-
return (0, import_crypto3.createHash)("md5").update(hashInput).digest("hex");
|
|
676
|
-
}
|
|
677
|
-
getTruncatedMessage(msg) {
|
|
678
|
-
msg = msg.trim();
|
|
679
|
-
if (msg.length <= MAX_MSG_LENGTH) {
|
|
680
|
-
return msg;
|
|
681
|
-
}
|
|
682
|
-
const suffix = "... (truncated)";
|
|
683
|
-
const cutoff = MAX_MSG_LENGTH - suffix.length;
|
|
684
|
-
return msg.substring(0, cutoff) + suffix;
|
|
685
|
-
}
|
|
686
|
-
getTruncatedStack(stack) {
|
|
687
|
-
const suffix = "... (truncated) ...";
|
|
688
|
-
const cutoff = MAX_STACKTRACE_LENGTH - suffix.length;
|
|
689
|
-
const lines = stack.trim().split("\n");
|
|
690
|
-
const truncatedLines = [];
|
|
691
|
-
let length = 0;
|
|
692
|
-
for (const line of lines) {
|
|
693
|
-
if (length + line.length + 1 > cutoff) {
|
|
694
|
-
truncatedLines.push(suffix);
|
|
695
|
-
break;
|
|
696
|
-
}
|
|
697
|
-
truncatedLines.push(line);
|
|
698
|
-
length += line.length + 1;
|
|
699
|
-
}
|
|
700
|
-
return truncatedLines.join("\n");
|
|
701
|
-
}
|
|
702
|
-
captureSentryEventId(serverErrorKey) {
|
|
703
|
-
if (this.sentry && this.sentry.lastEventId) {
|
|
704
|
-
const eventId = this.sentry.lastEventId();
|
|
705
|
-
if (eventId) {
|
|
706
|
-
this.sentryEventIds.set(serverErrorKey, eventId);
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
async tryImportSentry() {
|
|
711
|
-
try {
|
|
712
|
-
this.sentry = await import("@sentry/node");
|
|
713
|
-
} catch (e) {
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
|
-
__name(_ServerErrorCounter, "ServerErrorCounter");
|
|
718
|
-
var ServerErrorCounter = _ServerErrorCounter;
|
|
719
|
-
|
|
720
734
|
// src/common/validationErrorCounter.ts
|
|
721
735
|
var import_crypto4 = require("crypto");
|
|
722
736
|
var _ValidationErrorCounter = class _ValidationErrorCounter {
|
|
@@ -790,6 +804,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
790
804
|
syncIntervalId;
|
|
791
805
|
startupData;
|
|
792
806
|
startupDataSent = false;
|
|
807
|
+
enabled = true;
|
|
793
808
|
requestCounter;
|
|
794
809
|
requestLogger;
|
|
795
810
|
validationErrorCounter;
|
|
@@ -826,12 +841,16 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
826
841
|
}
|
|
827
842
|
return _ApitallyClient.instance;
|
|
828
843
|
}
|
|
844
|
+
isEnabled() {
|
|
845
|
+
return this.enabled;
|
|
846
|
+
}
|
|
829
847
|
static async shutdown() {
|
|
830
848
|
if (_ApitallyClient.instance) {
|
|
831
849
|
await _ApitallyClient.instance.handleShutdown();
|
|
832
850
|
}
|
|
833
851
|
}
|
|
834
852
|
async handleShutdown() {
|
|
853
|
+
this.enabled = false;
|
|
835
854
|
this.stopSync();
|
|
836
855
|
await this.sendSyncData();
|
|
837
856
|
await this.sendLogData();
|
|
@@ -1015,6 +1034,7 @@ var _ApitallyClient = class _ApitallyClient {
|
|
|
1015
1034
|
if (error instanceof HTTPError) {
|
|
1016
1035
|
if (error.response.status === 404) {
|
|
1017
1036
|
this.logger.error(`Invalid Apitally client ID: '${this.clientId}'`);
|
|
1037
|
+
this.enabled = false;
|
|
1018
1038
|
this.stopSync();
|
|
1019
1039
|
return true;
|
|
1020
1040
|
}
|
|
@@ -1190,6 +1210,10 @@ var useApitally = /* @__PURE__ */ __name((app, config) => {
|
|
|
1190
1210
|
var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
1191
1211
|
let errorHandlerConfigured = false;
|
|
1192
1212
|
return (req, res, next) => {
|
|
1213
|
+
if (!client.isEnabled()) {
|
|
1214
|
+
next();
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1193
1217
|
if (!errorHandlerConfigured) {
|
|
1194
1218
|
app.use((err, req2, res2, next2) => {
|
|
1195
1219
|
res2.locals.serverError = err;
|
|
@@ -1201,7 +1225,10 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
1201
1225
|
const startTime = import_perf_hooks.performance.now();
|
|
1202
1226
|
const originalSend = res.send;
|
|
1203
1227
|
res.send = (body) => {
|
|
1204
|
-
|
|
1228
|
+
const contentType = res.get("content-type");
|
|
1229
|
+
if (client.requestLogger.isSupportedContentType(contentType)) {
|
|
1230
|
+
res.locals.body = body;
|
|
1231
|
+
}
|
|
1205
1232
|
return originalSend.call(res, body);
|
|
1206
1233
|
};
|
|
1207
1234
|
res.on("finish", () => {
|
|
@@ -1275,7 +1302,7 @@ var getMiddleware = /* @__PURE__ */ __name((app, client) => {
|
|
|
1275
1302
|
headers: convertHeaders(res.getHeaders()),
|
|
1276
1303
|
size: Number(res.get("content-length")),
|
|
1277
1304
|
body: convertBody(res.locals.body, res.get("content-type"))
|
|
1278
|
-
});
|
|
1305
|
+
}, res.locals.serverError);
|
|
1279
1306
|
}
|
|
1280
1307
|
} catch (error) {
|
|
1281
1308
|
client.logger.error("Error while logging request in Apitally middleware.", {
|