UNPKG

apitally

Version:

Simple API monitoring & analytics for REST APIs built with Express, Fastify, NestJS, AdonisJS, Hono, H3, Elysia, Hapi, and Koa.

1 lines 21.3 kB
{"version":3,"sources":["../../src/express/middleware.ts"],"sourcesContent":["import type { Express, NextFunction, Request, Response, Router } from \"express\";\nimport { AsyncLocalStorage } from \"node:async_hooks\";\nimport { performance } from \"node:perf_hooks\";\n\nimport { ApitallyClient } from \"../common/client.js\";\nimport { consumerFromStringOrObject } from \"../common/consumerRegistry.js\";\nimport { parseContentLength } from \"../common/headers.js\";\nimport { getPackageVersion } from \"../common/packageVersions.js\";\nimport type { LogRecord } from \"../common/requestLogger.js\";\nimport { convertBody, convertHeaders } from \"../common/requestLogger.js\";\nimport {\n ApitallyConfig,\n ApitallyConsumer,\n StartupData,\n ValidationError,\n} from \"../common/types.js\";\nimport {\n patchConsole,\n patchNestLogger,\n patchPinoLogger,\n patchWinston,\n} from \"../loggers/index.js\";\nimport {\n getEndpoints,\n getRouterInfo,\n parseExpressPath,\n parseExpressPathRegExp,\n} from \"./utils.js\";\n\ndeclare module \"express\" {\n interface Request {\n apitallyConsumer?: ApitallyConsumer | string | null;\n consumerIdentifier?: ApitallyConsumer | string | null; // For backwards compatibility\n }\n}\n\nexport function useApitally(\n app: Express | Router,\n config: ApitallyConfig & { basePath?: string },\n) {\n const client = new ApitallyClient(config);\n const middleware = getMiddleware(app, client);\n app.use(middleware);\n\n const setStartupData = (attempt: number = 1) => {\n const appInfo = getAppInfo(app, config.basePath, config.appVersion);\n if (appInfo.paths.length > 0 || attempt >= 10) {\n client.setStartupData(appInfo);\n client.startSync();\n } else {\n setTimeout(() => setStartupData(attempt + 1), 500);\n }\n };\n setTimeout(() => setStartupData(), 500);\n}\n\nfunction getMiddleware(app: Express | Router, client: ApitallyClient) {\n let errorHandlerConfigured = false;\n const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n if (client.requestLogger.config.captureLogs) {\n patchConsole(logsContext);\n patchWinston(logsContext);\n patchNestLogger(logsContext);\n }\n\n return async (req: Request, res: Response, next: NextFunction) => {\n if (!client.isEnabled() || req.method.toUpperCase() === \"OPTIONS\") {\n next();\n return;\n }\n\n if (!errorHandlerConfigured) {\n // Add error handling middleware to the bottom of the stack when handling the first request\n app.use((err: Error, req: Request, res: Response, next: NextFunction) => {\n res.locals.serverError = err;\n next(err);\n });\n errorHandlerConfigured = true;\n }\n\n if (client.requestLogger.config.captureLogs && \"log\" in req) {\n await patchPinoLogger((req as any).log, logsContext);\n }\n\n logsContext.run([], () => {\n try {\n const startTime = performance.now();\n const originalSend = res.send;\n res.send = (body) => {\n const contentType = res.get(\"content-type\");\n if (client.requestLogger.isSupportedContentType(contentType)) {\n res.locals.body = body;\n }\n return originalSend.call(res, body);\n };\n\n res.once(\"finish\", () => {\n try {\n const responseTime = performance.now() - startTime;\n const path = getRoutePath(req);\n const consumer = getConsumer(req);\n client.consumerRegistry.addOrUpdateConsumer(consumer);\n\n const requestSize = parseContentLength(req.get(\"content-length\"));\n const responseSize = parseContentLength(res.get(\"content-length\"));\n\n if (path) {\n client.requestCounter.addRequest({\n consumer: consumer?.identifier,\n method: req.method,\n path,\n statusCode: res.statusCode,\n responseTime: responseTime,\n requestSize,\n responseSize,\n });\n\n if (\n (res.statusCode === 400 || res.statusCode === 422) &&\n res.locals.body\n ) {\n let jsonBody: any;\n try {\n jsonBody = JSON.parse(res.locals.body);\n } catch {\n // Ignore\n }\n if (jsonBody) {\n const validationErrors: ValidationError[] = [];\n if (validationErrors.length === 0) {\n validationErrors.push(\n ...extractExpressValidatorErrors(jsonBody),\n );\n }\n if (validationErrors.length === 0) {\n validationErrors.push(...extractCelebrateErrors(jsonBody));\n }\n if (validationErrors.length === 0) {\n validationErrors.push(\n ...extractNestValidationErrors(jsonBody),\n );\n }\n validationErrors.forEach((error) => {\n client.validationErrorCounter.addValidationError({\n consumer: consumer?.identifier,\n method: req.method,\n path,\n ...error,\n });\n });\n }\n }\n\n if (res.statusCode === 500 && res.locals.serverError) {\n const serverError = res.locals.serverError as Error;\n client.serverErrorCounter.addServerError({\n consumer: consumer?.identifier,\n method: req.method,\n path,\n type: serverError.name,\n msg: serverError.message,\n traceback: serverError.stack || \"\",\n });\n }\n }\n\n if (client.requestLogger.enabled) {\n const logs = logsContext.getStore();\n client.requestLogger.logRequest(\n {\n timestamp: Date.now() / 1000,\n method: req.method,\n path,\n url: `${req.protocol}://${req.host}${req.originalUrl}`,\n headers: convertHeaders(req.headers),\n size: requestSize,\n consumer: consumer?.identifier,\n body: convertBody(req.body, req.get(\"content-type\")),\n },\n {\n statusCode: res.statusCode,\n responseTime: responseTime / 1000,\n headers: convertHeaders(res.getHeaders()),\n size: responseSize,\n body: convertBody(res.locals.body, res.get(\"content-type\")),\n },\n res.locals.serverError,\n logs,\n );\n }\n } catch (error) {\n client.logger.error(\n \"Error while logging request in Apitally middleware.\",\n { request: req, response: res, error },\n );\n }\n });\n } catch (error) {\n client.logger.error(\"Error in Apitally middleware.\", {\n request: req,\n response: res,\n error,\n });\n } finally {\n next();\n }\n });\n };\n}\n\nfunction getRoutePath(req: Request) {\n if (!req.route) {\n return;\n }\n if (req.baseUrl) {\n const routerInfo = getRouterInfo(req.app);\n if (routerInfo.stack) {\n const routerPath = getRouterPath(routerInfo.stack, req.baseUrl);\n return req.route.path === \"/\" ? routerPath : routerPath + req.route.path;\n }\n }\n return req.route.path;\n}\n\nfunction getRouterPath(stack: any[], baseUrl: string) {\n const routerPaths: string[] = [];\n while (stack && stack.length > 0) {\n const routerLayer = stack.find(\n (layer) =>\n layer.name === \"router\" &&\n layer.path &&\n (baseUrl.startsWith(layer.path) || layer.regexp?.test(baseUrl)),\n );\n if (routerLayer) {\n if (\n routerLayer.regexp &&\n routerLayer.keys &&\n routerLayer.keys.length > 0\n ) {\n const parsedPath = parseExpressPathRegExp(\n routerLayer.regexp,\n routerLayer.keys,\n );\n routerPaths.push(\"/\" + parsedPath);\n } else if (\n routerLayer.params &&\n Object.keys(routerLayer.params).length > 0\n ) {\n const parsedPath = parseExpressPath(\n routerLayer.path,\n routerLayer.params,\n );\n routerPaths.push(parsedPath);\n } else {\n routerPaths.push(routerLayer.path);\n }\n stack = routerLayer.handle?.stack;\n baseUrl = baseUrl.slice(routerLayer.path.length);\n } else {\n break;\n }\n }\n return routerPaths.filter((path) => path !== \"/\").join(\"\");\n}\n\nexport function setConsumer(\n req: Request,\n consumer: ApitallyConsumer | string | null | undefined,\n) {\n req.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(req: Request) {\n if (req.apitallyConsumer) {\n return consumerFromStringOrObject(req.apitallyConsumer);\n } else if (req.consumerIdentifier) {\n // For backwards compatibility\n process.emitWarning(\n \"The consumerIdentifier property on the request object is deprecated. Use apitallyConsumer instead.\",\n \"DeprecationWarning\",\n );\n return consumerFromStringOrObject(req.consumerIdentifier);\n }\n return null;\n}\n\nfunction extractExpressValidatorErrors(responseBody: any) {\n try {\n const errors: ValidationError[] = [];\n if (\n responseBody &&\n responseBody.errors &&\n Array.isArray(responseBody.errors)\n ) {\n responseBody.errors.forEach((error: any) => {\n if (error.location && error.path && error.msg && error.type) {\n errors.push({\n loc: `${error.location}.${error.path}`,\n msg: error.msg,\n type: error.type,\n });\n }\n });\n }\n return errors;\n } catch (error) {\n return [];\n }\n}\n\nfunction extractCelebrateErrors(responseBody: any) {\n try {\n const errors: ValidationError[] = [];\n if (responseBody && responseBody.validation) {\n Object.values(responseBody.validation).forEach((error: any) => {\n if (\n error.source &&\n error.keys &&\n Array.isArray(error.keys) &&\n error.message\n ) {\n error.keys.forEach((key: string) => {\n errors.push({\n loc: `${error.source}.${key}`,\n msg: subsetJoiMessage(error.message, key),\n type: \"\",\n });\n });\n }\n });\n }\n return errors;\n } catch (error) {\n return [];\n }\n}\n\nfunction extractNestValidationErrors(responseBody: any) {\n try {\n const errors: ValidationError[] = [];\n if (responseBody && Array.isArray(responseBody.message)) {\n responseBody.message.forEach((message: any) => {\n errors.push({\n loc: \"\",\n msg: message,\n type: \"\",\n });\n });\n }\n return errors;\n } catch (error) {\n return [];\n }\n}\n\nfunction subsetJoiMessage(message: string, key: string) {\n const messageWithKey = message\n .split(\". \")\n .find((message) => message.includes(`\"${key}\"`));\n return messageWithKey ? messageWithKey : message;\n}\n\nfunction getAppInfo(\n app: Express | Router,\n basePath?: string,\n appVersion?: string,\n): StartupData {\n const versions: Array<[string, string]> = [\n [\"nodejs\", process.version.replace(/^v/, \"\")],\n ];\n const expressVersion = getPackageVersion(\"express\");\n const nestjsVersion = getPackageVersion(\"@nestjs/core\");\n const apitallyVersion = getPackageVersion(\"../..\");\n if (expressVersion) {\n versions.push([\"express\", expressVersion]);\n }\n if (nestjsVersion) {\n versions.push([\"nestjs\", nestjsVersion]);\n }\n if (apitallyVersion) {\n versions.push([\"apitally\", apitallyVersion]);\n }\n if (appVersion) {\n versions.push([\"app\", appVersion]);\n }\n return {\n paths: getEndpoints(app, basePath || \"\"),\n versions: Object.fromEntries(versions),\n client: \"js:express\",\n };\n}\n"],"mappings":"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","names":["useApitally","app","config","client","ApitallyClient","middleware","getMiddleware","use","setStartupData","attempt","appInfo","getAppInfo","basePath","appVersion","paths","length","startSync","setTimeout","errorHandlerConfigured","logsContext","AsyncLocalStorage","requestLogger","captureLogs","patchConsole","patchWinston","patchNestLogger","req","res","next","isEnabled","method","toUpperCase","err","locals","serverError","patchPinoLogger","log","run","startTime","performance","now","originalSend","send","body","contentType","get","isSupportedContentType","call","once","responseTime","path","getRoutePath","consumer","getConsumer","consumerRegistry","addOrUpdateConsumer","requestSize","parseContentLength","responseSize","requestCounter","addRequest","identifier","statusCode","jsonBody","JSON","parse","validationErrors","push","extractExpressValidatorErrors","extractCelebrateErrors","extractNestValidationErrors","forEach","error","validationErrorCounter","addValidationError","serverErrorCounter","addServerError","type","name","msg","message","traceback","stack","enabled","logs","getStore","logRequest","timestamp","Date","url","protocol","host","originalUrl","headers","convertHeaders","size","convertBody","getHeaders","logger","request","response","route","baseUrl","routerInfo","getRouterInfo","routerPath","getRouterPath","routerPaths","routerLayer","find","layer","_a","startsWith","regexp","test","keys","parsedPath","parseExpressPathRegExp","params","Object","parseExpressPath","handle","slice","filter","join","setConsumer","apitallyConsumer","undefined","consumerFromStringOrObject","consumerIdentifier","process","emitWarning","responseBody","errors","Array","isArray","location","loc","validation","values","source","key","subsetJoiMessage","messageWithKey","split","includes","versions","version","replace","expressVersion","getPackageVersion","nestjsVersion","apitallyVersion","getEndpoints","fromEntries"]}