{"version":3,"sources":["../src/index.ts","../src/plugin.ts"],"sourcesContent":["import fastifyPlugin from \"fastify-plugin\";\nimport { plugin } from \"./plugin\";\n\nexport type { FastifyRequestLoggerOptions } from \"./plugin\";\n\nexport default fastifyPlugin(plugin, {\n  fastify: \">=4\",\n  name: \"fastify-request-logger\",\n});\n","/* eslint-disable @typescript-eslint/require-await */\nimport type { FastifyPluginAsync, FastifyRequest } from \"fastify\";\nimport * as color from \"kolorist\";\nimport type pino from \"pino\";\n\nexport type FastifyRequestLoggerOptions = {\n  logBody?: boolean;\n  logResponseTime?: boolean;\n  logBindings?: Record<string, unknown>;\n  ignoredPaths?: (string | RegExp)[];\n  ignoredBindings?: Record<string, unknown>;\n  ignore?: (request: FastifyRequest) => boolean;\n  supportsArt?: boolean;\n};\n\nconst IS_WINDOWS = process.platform === \"win32\";\nconst IS_POWERSHELL = IS_WINDOWS && Boolean(process.env[\"PSModulePath\"] ?? process.env[\"PSHOME\"]);\n\nexport const plugin: FastifyPluginAsync<FastifyRequestLoggerOptions> = async (\n  fastify,\n  options = {},\n): Promise<void> => {\n  const {\n    logBody = true,\n    logResponseTime = true,\n    logBindings = { plugin: \"fastify-request-logger\" },\n    ignoredPaths = [],\n    ignore,\n    ignoredBindings,\n    // eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison\n    supportsArt = !IS_POWERSHELL && color.options.supportLevel >= 2 /* SupportLevel.ansi256 */,\n  } = options;\n\n  const icons = { req: supportsArt ? \"←\" : \"<\", res: supportsArt ? \"→\" : \">\" };\n\n  const isIgnoredRequest = (request: FastifyRequest): boolean => {\n    const { url } = request.routeOptions;\n    const isIgnoredPath = ignoredPaths.some((ignoredPath) => {\n      if (typeof ignoredPath === \"string\") {\n        return ignoredPath === url;\n      } else if (ignoredPath instanceof RegExp) {\n        return ignoredPath.test(url ?? \"\");\n      }\n      return false;\n    });\n    if (isIgnoredPath) {\n      return true;\n    }\n    return ignore ? ignore(request) : false;\n  };\n\n  fastify.addHook(\"onRequest\", async (request) => {\n    if (isIgnoredRequest(request)) {\n      if (ignoredBindings) {\n        (request.log as pino.Logger).setBindings(ignoredBindings);\n      }\n      return;\n    }\n    const contentLength = request.headers[\"content-length\"];\n    request.log.info(\n      logBindings,\n      `${color.bold(color.yellow(icons.req))}${color.yellow(request.method)}:${color.green(\n        request.url,\n      )} request from ip ${color.blue(request.ip)}${\n        contentLength ? ` with a ${color.yellow(contentLength)}-length body` : \"\"\n      }`,\n    );\n    request.log.trace({ ...logBindings, req: request }, `Request trace`);\n  });\n\n  fastify.addHook(\"preHandler\", async (request) => {\n    if (isIgnoredRequest(request)) {\n      return;\n    }\n    const isJson = request.headers[\"content-type\"]?.includes(\"application/json\");\n    if (request.body && logBody) {\n      if (Buffer.isBuffer(request.body)) {\n        request.log.debug({ ...logBindings, body: `<Buffer ${request.body.length} bytes>` }, `Request body`);\n      } else if (isJson) {\n        request.log.debug({ ...logBindings, body: request.body }, `Request body`);\n      }\n    }\n  });\n\n  fastify.addHook(\"onResponse\", async (request, reply) => {\n    if (isIgnoredRequest(request)) {\n      return;\n    }\n    const message = `${color.bold(color.yellow(icons.res))}${color.yellow(request.method)}:${color.green(\n      request.url,\n    )} response with a ${color.magenta(reply.statusCode)}-status${\n      logResponseTime ? ` took ${color.magenta(reply.elapsedTime.toFixed(3))}ms` : \"\"\n    }`;\n    if (reply.statusCode && reply.statusCode >= 500) {\n      request.log.error(logBindings, message);\n    } else if (reply.statusCode && reply.statusCode >= 400) {\n      request.log.warn(logBindings, message);\n    } else {\n      request.log.info(logBindings, message);\n    }\n  });\n\n  fastify.addHook(\"onError\", async (request, reply, error) => {\n    if (isIgnoredRequest(request)) {\n      return;\n    }\n\n    if (error.statusCode && error.statusCode >= 500) {\n      request.log.error({ ...logBindings, req: request, res: reply, err: error }, error?.message);\n    } else if (reply.statusCode && reply.statusCode >= 400) {\n      request.log.warn({ ...logBindings, res: reply, err: error }, error?.message);\n    } else {\n      request.log.info({ ...logBindings, res: reply, err: error }, error?.message);\n    }\n  });\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,4BAA0B;;;ACE1B,YAAuB;AAavB,IAAM,aAAa,QAAQ,aAAa;AACxC,IAAM,gBAAgB,cAAc,QAAQ,QAAQ,IAAI,cAAc,KAAK,QAAQ,IAAI,QAAQ,CAAC;AAEzF,IAAM,SAA0D,OACrE,SACAA,WAAU,CAAC,MACO;AAClB,QAAM;AAAA,IACJ,UAAU;AAAA,IACV,kBAAkB;AAAA,IAClB,cAAc,EAAE,QAAQ,yBAAyB;AAAA,IACjD,eAAe,CAAC;AAAA,IAChB;AAAA,IACA;AAAA;AAAA,IAEA,cAAc,CAAC,iBAAuB,cAAQ,gBAAgB;AAAA,EAChE,IAAIA;AAEJ,QAAM,QAAQ,EAAE,KAAK,cAAc,WAAM,KAAK,KAAK,cAAc,WAAM,IAAI;AAE3E,QAAM,mBAAmB,CAAC,YAAqC;AAC7D,UAAM,EAAE,IAAI,IAAI,QAAQ;AACxB,UAAM,gBAAgB,aAAa,KAAK,CAAC,gBAAgB;AACvD,UAAI,OAAO,gBAAgB,UAAU;AACnC,eAAO,gBAAgB;AAAA,MACzB,WAAW,uBAAuB,QAAQ;AACxC,eAAO,YAAY,KAAK,OAAO,EAAE;AAAA,MACnC;AACA,aAAO;AAAA,IACT,CAAC;AACD,QAAI,eAAe;AACjB,aAAO;AAAA,IACT;AACA,WAAO,SAAS,OAAO,OAAO,IAAI;AAAA,EACpC;AAEA,UAAQ,QAAQ,aAAa,OAAO,YAAY;AAC9C,QAAI,iBAAiB,OAAO,GAAG;AAC7B,UAAI,iBAAiB;AACnB,QAAC,QAAQ,IAAoB,YAAY,eAAe;AAAA,MAC1D;AACA;AAAA,IACF;AACA,UAAM,gBAAgB,QAAQ,QAAQ,gBAAgB;AACtD,YAAQ,IAAI;AAAA,MACV;AAAA,MACA,GAAS,WAAW,aAAO,MAAM,GAAG,CAAC,CAAC,GAAS,aAAO,QAAQ,MAAM,CAAC,IAAU;AAAA,QAC7E,QAAQ;AAAA,MACV,CAAC,oBAA0B,WAAK,QAAQ,EAAE,CAAC,GACzC,gBAAgB,WAAiB,aAAO,aAAa,CAAC,iBAAiB,EACzE;AAAA,IACF;AACA,YAAQ,IAAI,MAAM,EAAE,GAAG,aAAa,KAAK,QAAQ,GAAG,eAAe;AAAA,EACrE,CAAC;AAED,UAAQ,QAAQ,cAAc,OAAO,YAAY;AAC/C,QAAI,iBAAiB,OAAO,GAAG;AAC7B;AAAA,IACF;AACA,UAAM,SAAS,QAAQ,QAAQ,cAAc,GAAG,SAAS,kBAAkB;AAC3E,QAAI,QAAQ,QAAQ,SAAS;AAC3B,UAAI,OAAO,SAAS,QAAQ,IAAI,GAAG;AACjC,gBAAQ,IAAI,MAAM,EAAE,GAAG,aAAa,MAAM,WAAW,QAAQ,KAAK,MAAM,UAAU,GAAG,cAAc;AAAA,MACrG,WAAW,QAAQ;AACjB,gBAAQ,IAAI,MAAM,EAAE,GAAG,aAAa,MAAM,QAAQ,KAAK,GAAG,cAAc;AAAA,MAC1E;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,QAAQ,cAAc,OAAO,SAAS,UAAU;AACtD,QAAI,iBAAiB,OAAO,GAAG;AAC7B;AAAA,IACF;AACA,UAAM,UAAU,GAAS,WAAW,aAAO,MAAM,GAAG,CAAC,CAAC,GAAS,aAAO,QAAQ,MAAM,CAAC,IAAU;AAAA,MAC7F,QAAQ;AAAA,IACV,CAAC,oBAA0B,cAAQ,MAAM,UAAU,CAAC,UAClD,kBAAkB,SAAe,cAAQ,MAAM,YAAY,QAAQ,CAAC,CAAC,CAAC,OAAO,EAC/E;AACA,QAAI,MAAM,cAAc,MAAM,cAAc,KAAK;AAC/C,cAAQ,IAAI,MAAM,aAAa,OAAO;AAAA,IACxC,WAAW,MAAM,cAAc,MAAM,cAAc,KAAK;AACtD,cAAQ,IAAI,KAAK,aAAa,OAAO;AAAA,IACvC,OAAO;AACL,cAAQ,IAAI,KAAK,aAAa,OAAO;AAAA,IACvC;AAAA,EACF,CAAC;AAED,UAAQ,QAAQ,WAAW,OAAO,SAAS,OAAO,UAAU;AAC1D,QAAI,iBAAiB,OAAO,GAAG;AAC7B;AAAA,IACF;AAEA,QAAI,MAAM,cAAc,MAAM,cAAc,KAAK;AAC/C,cAAQ,IAAI,MAAM,EAAE,GAAG,aAAa,KAAK,SAAS,KAAK,OAAO,KAAK,MAAM,GAAG,OAAO,OAAO;AAAA,IAC5F,WAAW,MAAM,cAAc,MAAM,cAAc,KAAK;AACtD,cAAQ,IAAI,KAAK,EAAE,GAAG,aAAa,KAAK,OAAO,KAAK,MAAM,GAAG,OAAO,OAAO;AAAA,IAC7E,OAAO;AACL,cAAQ,IAAI,KAAK,EAAE,GAAG,aAAa,KAAK,OAAO,KAAK,MAAM,GAAG,OAAO,OAAO;AAAA,IAC7E;AAAA,EACF,CAAC;AACH;;;AD9GA,IAAO,kBAAQ,sBAAAC,SAAc,QAAQ;AAAA,EACnC,SAAS;AAAA,EACT,MAAM;AACR,CAAC;","names":["options","fastifyPlugin"]}