{"version":3,"sources":["../../src/fastify/plugin.ts"],"sourcesContent":["import type {\n  FastifyError,\n  FastifyPluginAsync,\n  FastifyReply,\n  FastifyRequest,\n} from \"fastify\";\nimport fp from \"fastify-plugin\";\nimport { AsyncLocalStorage, AsyncResource } from \"node:async_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 type { SpanHandle } from \"../common/spanCollector.js\";\nimport {\n  ApitallyConfig,\n  ApitallyConsumer,\n  PathInfo,\n  ValidationError,\n} from \"../common/types.js\";\nimport {\n  patchConsole,\n  patchNestLogger,\n  patchPinoLogger,\n  patchWinston,\n} from \"../loggers/index.js\";\n\nconst LOGS_SYMBOL = Symbol(\"apitally.logs\");\nconst ASYNC_RESOURCE_SYMBOL = Symbol(\"apitally.asyncResource\");\nconst SPAN_HANDLE_SYMBOL = Symbol(\"apitally.spanHandle\");\n\ndeclare module \"fastify\" {\n  interface FastifyReply {\n    payload: any;\n    serverError?: FastifyError;\n  }\n\n  interface FastifyRequest {\n    apitallyConsumer?: ApitallyConsumer | string | null;\n    consumerIdentifier?: ApitallyConsumer | string | null; // For backwards compatibility\n\n    [LOGS_SYMBOL]?: LogRecord[];\n    [ASYNC_RESOURCE_SYMBOL]?: AsyncResource;\n    [SPAN_HANDLE_SYMBOL]?: SpanHandle;\n  }\n}\n\nconst apitallyPlugin: FastifyPluginAsync<ApitallyConfig> = async (\n  fastify,\n  config,\n) => {\n  const client = new ApitallyClient(config);\n  const routes: PathInfo[] = [];\n  const logsContext = new AsyncLocalStorage<LogRecord[]>();\n\n  if (client.requestLogger.config.captureLogs) {\n    patchConsole(logsContext);\n    patchWinston(logsContext);\n    patchPinoLogger(fastify.log, logsContext);\n    patchNestLogger(logsContext);\n  }\n\n  fastify.decorateRequest(\"apitallyConsumer\", null);\n  fastify.decorateRequest(\"consumerIdentifier\", null); // For backwards compatibility\n  fastify.decorateReply(\"payload\", null);\n\n  fastify.addHook(\"onRoute\", (routeOptions) => {\n    const methods = Array.isArray(routeOptions.method)\n      ? routeOptions.method\n      : [routeOptions.method];\n    methods.forEach((method) => {\n      if (![\"HEAD\", \"OPTIONS\"].includes(method.toUpperCase())) {\n        routes.push({\n          method: method.toUpperCase(),\n          path: routeOptions.url,\n        });\n      }\n    });\n  });\n\n  fastify.addHook(\"onReady\", () => {\n    client.setStartupData(getAppInfo(routes, config.appVersion));\n    client.startSync();\n  });\n\n  fastify.addHook(\"onClose\", async () => {\n    await client.handleShutdown();\n  });\n\n  // Establish logs context and start span for each request\n  fastify.addHook(\"onRequest\", (request, reply, done) => {\n    if (client.isEnabled()) {\n      const logs: LogRecord[] = [];\n      request[LOGS_SYMBOL] = logs;\n      logsContext.run(logs, () => {\n        const spanHandle = client.spanCollector.startSpan();\n        request[SPAN_HANDLE_SYMBOL] = spanHandle;\n        spanHandle.runInContext(() => {\n          const asyncResource = new AsyncResource(\"ApitallyContext\");\n          request[ASYNC_RESOURCE_SYMBOL] = asyncResource;\n          asyncResource.runInAsyncScope(done, request.raw);\n        });\n      });\n    } else {\n      done();\n    }\n  });\n\n  // Restore async context for later hooks and route handlers\n  fastify.addHook(\"preValidation\", (request, reply, done) => {\n    if (client.isEnabled() && request[ASYNC_RESOURCE_SYMBOL]) {\n      const asyncResource = request[ASYNC_RESOURCE_SYMBOL];\n      asyncResource.runInAsyncScope(done, request.raw);\n    } else {\n      done();\n    }\n  });\n\n  fastify.addHook(\"onSend\", (request, reply, payload: any, done) => {\n    const contentType = reply.getHeader(\"content-type\") as string | undefined;\n    if (client.requestLogger.isSupportedContentType(contentType)) {\n      reply.payload = payload;\n    }\n    done();\n  });\n\n  fastify.addHook(\"onError\", (request, reply, error, done) => {\n    if (!error.statusCode || error.statusCode === 500) {\n      reply.serverError = error;\n    }\n    done();\n  });\n\n  fastify.addHook(\"onResponse\", (request, reply, done) => {\n    if (client.isEnabled() && request.method.toUpperCase() !== \"OPTIONS\") {\n      // Get path from routeOptions if available (from v4), otherwise fallback to deprecated routerPath\n      const consumer = getConsumer(request);\n      const path =\n        \"routeOptions\" in request\n          ? (request as any).routeOptions.url\n          : (request as any).routerPath;\n      const requestSize = parseContentLength(request.headers[\"content-length\"]);\n      const responseSize = parseContentLength(\n        reply.getHeader(\"content-length\"),\n      );\n      const responseTime = getResponseTime(reply);\n      client.consumerRegistry.addOrUpdateConsumer(consumer);\n      client.requestCounter.addRequest({\n        consumer: consumer?.identifier,\n        method: request.method,\n        path,\n        statusCode: reply.statusCode,\n        responseTime,\n        requestSize,\n        responseSize,\n      });\n\n      if (\n        (reply.statusCode === 400 || reply.statusCode === 422) &&\n        reply.payload\n      ) {\n        try {\n          const parsedPayload = JSON.parse(reply.payload);\n          const validationErrors: ValidationError[] = [];\n\n          if (\n            (!parsedPayload.code ||\n              parsedPayload.code === \"FST_ERR_VALIDATION\") &&\n            typeof parsedPayload.message === \"string\"\n          ) {\n            validationErrors.push(...extractAjvErrors(parsedPayload.message));\n          } else if (Array.isArray(parsedPayload.message)) {\n            validationErrors.push(\n              ...extractNestValidationErrors(parsedPayload.message),\n            );\n          }\n\n          validationErrors.forEach((error) => {\n            client.validationErrorCounter.addValidationError({\n              consumer: consumer?.identifier,\n              method: request.method,\n              path: path,\n              ...error,\n            });\n          });\n        } catch (error) {} // eslint-disable-line no-empty\n      }\n\n      if (reply.statusCode === 500 && reply.serverError) {\n        client.serverErrorCounter.addServerError({\n          consumer: consumer?.identifier,\n          method: request.method,\n          path: path,\n          type: reply.serverError.name,\n          msg: reply.serverError.message,\n          traceback: reply.serverError.stack || \"\",\n        });\n      }\n\n      const spanHandle = request[SPAN_HANDLE_SYMBOL];\n      spanHandle?.setName(`${request.method} ${path}`);\n      const spans = spanHandle?.end();\n      const traceId = spanHandle?.traceId;\n\n      if (client.requestLogger.enabled) {\n        const logs = request[LOGS_SYMBOL];\n        client.requestLogger.logRequest(\n          {\n            timestamp: Date.now() / 1000,\n            method: request.method,\n            path,\n            url: `${request.protocol}://${request.host ?? request.hostname}${request.originalUrl ?? request.url}`,\n            headers: convertHeaders(request.headers),\n            size: requestSize,\n            consumer: consumer?.identifier,\n            body: convertBody(request.body, request.headers[\"content-type\"]),\n          },\n          {\n            statusCode: reply.statusCode,\n            responseTime: responseTime / 1000,\n            headers: convertHeaders(reply.getHeaders()),\n            size: responseSize,\n            body: convertBody(\n              reply.payload,\n              reply.getHeader(\"content-type\")?.toString(),\n            ),\n          },\n          reply.serverError,\n          logs,\n          spans,\n          traceId,\n        );\n      }\n    }\n\n    done();\n  });\n};\n\nfunction getAppInfo(routes: PathInfo[], appVersion?: string) {\n  const versions = [[\"nodejs\", process.version.replace(/^v/, \"\")]];\n  const fastifyVersion = getPackageVersion(\"fastify\");\n  const pinoVersion = getPackageVersion(\"pino\");\n  const nestjsVersion = getPackageVersion(\"@nestjs/core\");\n  const apitallyVersion = getPackageVersion(\"../..\");\n  if (fastifyVersion) {\n    versions.push([\"fastify\", fastifyVersion]);\n  }\n  if (pinoVersion) {\n    versions.push([\"pino\", pinoVersion]);\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: routes,\n    versions: Object.fromEntries(versions),\n    client: \"js:fastify\",\n  };\n}\n\nexport function setConsumer(\n  request: FastifyRequest,\n  consumer: ApitallyConsumer | string | null | undefined,\n) {\n  request.apitallyConsumer = consumer || undefined;\n}\n\nfunction getConsumer(request: FastifyRequest) {\n  if (request.apitallyConsumer) {\n    return consumerFromStringOrObject(request.apitallyConsumer);\n  } else if (request.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(request.consumerIdentifier);\n  }\n  return null;\n}\n\nfunction getResponseTime(reply: FastifyReply) {\n  if (reply.elapsedTime !== undefined) {\n    return reply.elapsedTime;\n  } else if ((reply as any).getResponseTime !== undefined) {\n    return (reply as any).getResponseTime();\n  }\n  return 0;\n}\n\nfunction extractAjvErrors(message: string): ValidationError[] {\n  try {\n    const regex =\n      /(?<=^|, )((?:headers|params|query|querystring|body)[/.][^ ]+)(?= )/g;\n    const matches: { match: string; index: number }[] = [];\n    let match: RegExpExecArray | null;\n    while ((match = regex.exec(message)) !== null) {\n      matches.push({ match: match[0], index: match.index });\n    }\n\n    return matches.map((m, i) => {\n      const endIndex =\n        i + 1 < matches.length ? matches[i + 1].index - 2 : message.length;\n      const matchSplit = m.match.split(/[/.]/);\n      if (matchSplit[0] === \"querystring\") {\n        matchSplit[0] = \"query\";\n      }\n      return {\n        loc: matchSplit.join(\".\"),\n        msg: message.substring(m.index, endIndex),\n        type: \"\",\n      };\n    });\n  } catch (error) {\n    return [];\n  }\n}\n\nfunction extractNestValidationErrors(message: any[]): ValidationError[] {\n  try {\n    return message\n      .filter((msg: any) => typeof msg === \"string\")\n      .map((msg: any) => ({\n        loc: \"\",\n        msg,\n        type: \"\",\n      }));\n  } catch (error) {\n    return [];\n  }\n}\n\nexport { apitallyPlugin };\n\nexport default fp(apitallyPlugin, {\n  name: \"apitally\",\n});\n"],"mappings":"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","names":["LOGS_SYMBOL","Symbol","ASYNC_RESOURCE_SYMBOL","SPAN_HANDLE_SYMBOL","apitallyPlugin","fastify","config","client","ApitallyClient","routes","logsContext","AsyncLocalStorage","requestLogger","captureLogs","patchConsole","patchWinston","patchPinoLogger","log","patchNestLogger","decorateRequest","decorateReply","addHook","routeOptions","methods","Array","isArray","method","forEach","includes","toUpperCase","push","path","url","setStartupData","getAppInfo","appVersion","startSync","handleShutdown","request","reply","done","isEnabled","logs","run","spanHandle","spanCollector","startSpan","runInContext","asyncResource","AsyncResource","runInAsyncScope","raw","payload","contentType","getHeader","isSupportedContentType","error","statusCode","serverError","consumer","getConsumer","routerPath","requestSize","parseContentLength","headers","responseSize","responseTime","getResponseTime","consumerRegistry","addOrUpdateConsumer","requestCounter","addRequest","identifier","parsedPayload","JSON","parse","validationErrors","code","message","extractAjvErrors","extractNestValidationErrors","validationErrorCounter","addValidationError","serverErrorCounter","addServerError","type","name","msg","traceback","stack","setName","spans","end","traceId","enabled","logRequest","timestamp","Date","now","protocol","host","hostname","originalUrl","convertHeaders","size","body","convertBody","getHeaders","toString","versions","process","version","replace","fastifyVersion","getPackageVersion","pinoVersion","nestjsVersion","apitallyVersion","paths","Object","fromEntries","setConsumer","apitallyConsumer","undefined","consumerFromStringOrObject","consumerIdentifier","emitWarning","elapsedTime","regex","matches","match","exec","index","map","m","i","endIndex","length","matchSplit","split","loc","join","substring","filter","fp"]}