evlog 2.12.0 → 2.14.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.
Files changed (115) hide show
  1. package/README.md +111 -0
  2. package/dist/adapters/axiom.d.mts +1 -1
  3. package/dist/adapters/better-stack.d.mts +1 -1
  4. package/dist/adapters/datadog.d.mts +1 -1
  5. package/dist/adapters/fs.d.mts +1 -1
  6. package/dist/adapters/hyperdx.d.mts +1 -1
  7. package/dist/adapters/otlp.d.mts +1 -1
  8. package/dist/adapters/posthog.d.mts +1 -1
  9. package/dist/adapters/sentry.d.mts +1 -1
  10. package/dist/ai/index.d.mts +106 -5
  11. package/dist/ai/index.d.mts.map +1 -1
  12. package/dist/ai/index.mjs +28 -5
  13. package/dist/ai/index.mjs.map +1 -1
  14. package/dist/audit-d9esRZOK.mjs +1440 -0
  15. package/dist/audit-d9esRZOK.mjs.map +1 -0
  16. package/dist/audit-mUutdf6A.d.mts +1130 -0
  17. package/dist/audit-mUutdf6A.d.mts.map +1 -0
  18. package/dist/better-auth/index.d.mts +220 -0
  19. package/dist/better-auth/index.d.mts.map +1 -0
  20. package/dist/better-auth/index.mjs +205 -0
  21. package/dist/better-auth/index.mjs.map +1 -0
  22. package/dist/browser.d.mts +1 -1
  23. package/dist/elysia/index.d.mts +2 -2
  24. package/dist/elysia/index.d.mts.map +1 -1
  25. package/dist/elysia/index.mjs +16 -4
  26. package/dist/elysia/index.mjs.map +1 -1
  27. package/dist/enrichers.d.mts +1 -1
  28. package/dist/{error-WRz4_F3W.d.mts → error-D1FZI2Kd.d.mts} +2 -2
  29. package/dist/{error-WRz4_F3W.d.mts.map → error-D1FZI2Kd.d.mts.map} +1 -1
  30. package/dist/error.d.mts +1 -1
  31. package/dist/{errors-J2kt7mZh.d.mts → errors-NIXCyk6I.d.mts} +2 -2
  32. package/dist/{errors-J2kt7mZh.d.mts.map → errors-NIXCyk6I.d.mts.map} +1 -1
  33. package/dist/express/index.d.mts +2 -2
  34. package/dist/express/index.d.mts.map +1 -1
  35. package/dist/express/index.mjs +8 -4
  36. package/dist/express/index.mjs.map +1 -1
  37. package/dist/fastify/index.d.mts +2 -2
  38. package/dist/fastify/index.d.mts.map +1 -1
  39. package/dist/fastify/index.mjs +8 -4
  40. package/dist/fastify/index.mjs.map +1 -1
  41. package/dist/fork-CTJXnpl8.mjs +72 -0
  42. package/dist/fork-CTJXnpl8.mjs.map +1 -0
  43. package/dist/headers-D74M0wsg.mjs +30 -0
  44. package/dist/headers-D74M0wsg.mjs.map +1 -0
  45. package/dist/hono/index.d.mts +2 -2
  46. package/dist/hono/index.mjs +2 -1
  47. package/dist/hono/index.mjs.map +1 -1
  48. package/dist/http.d.mts +1 -1
  49. package/dist/index.d.mts +7 -7
  50. package/dist/index.mjs +2 -2
  51. package/dist/{logger-Bm0k3Hf3.d.mts → logger-b3epPH0N.d.mts} +8 -4
  52. package/dist/logger-b3epPH0N.d.mts.map +1 -0
  53. package/dist/logger.d.mts +1 -1
  54. package/dist/logger.mjs +1 -1
  55. package/dist/{headers-ht4yS2mx.mjs → middleware-BWOJ7JI0.mjs} +9 -30
  56. package/dist/middleware-BWOJ7JI0.mjs.map +1 -0
  57. package/dist/{middleware-D_igVy93.d.mts → middleware-BYf26Lfu.d.mts} +14 -3
  58. package/dist/{middleware-D_igVy93.d.mts.map → middleware-BYf26Lfu.d.mts.map} +1 -1
  59. package/dist/nestjs/index.d.mts +2 -2
  60. package/dist/nestjs/index.d.mts.map +1 -1
  61. package/dist/nestjs/index.mjs +8 -4
  62. package/dist/nestjs/index.mjs.map +1 -1
  63. package/dist/next/client.d.mts +1 -1
  64. package/dist/next/index.d.mts +4 -4
  65. package/dist/next/index.d.mts.map +1 -1
  66. package/dist/next/index.mjs +15 -1
  67. package/dist/next/index.mjs.map +1 -1
  68. package/dist/next/instrumentation.d.mts +1 -1
  69. package/dist/next/instrumentation.mjs +1 -1
  70. package/dist/nitro/module.d.mts +2 -2
  71. package/dist/nitro/plugin.mjs +1 -1
  72. package/dist/nitro/v3/index.d.mts +2 -2
  73. package/dist/nitro/v3/module.d.mts +1 -1
  74. package/dist/nitro/v3/plugin.mjs +1 -1
  75. package/dist/nitro/v3/useLogger.d.mts +1 -1
  76. package/dist/{nitro-BeRXZcBd.d.mts → nitro-DenB86W6.d.mts} +2 -2
  77. package/dist/{nitro-BeRXZcBd.d.mts.map → nitro-DenB86W6.d.mts.map} +1 -1
  78. package/dist/nuxt/module.d.mts +1 -1
  79. package/dist/nuxt/module.mjs +1 -1
  80. package/dist/{parseError-DhXS_vzM.d.mts → parseError-BR9pocvY.d.mts} +2 -2
  81. package/dist/parseError-BR9pocvY.d.mts.map +1 -0
  82. package/dist/react-router/index.d.mts +2 -2
  83. package/dist/react-router/index.d.mts.map +1 -1
  84. package/dist/react-router/index.mjs +8 -4
  85. package/dist/react-router/index.mjs.map +1 -1
  86. package/dist/runtime/client/log.d.mts +1 -1
  87. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +1 -1
  88. package/dist/runtime/server/useLogger.d.mts +1 -1
  89. package/dist/runtime/utils/parseError.d.mts +2 -2
  90. package/dist/{storage-DpLJYMoc.mjs → storage-CFGTn37X.mjs} +1 -1
  91. package/dist/{storage-DpLJYMoc.mjs.map → storage-CFGTn37X.mjs.map} +1 -1
  92. package/dist/sveltekit/index.d.mts +2 -2
  93. package/dist/sveltekit/index.d.mts.map +1 -1
  94. package/dist/sveltekit/index.mjs +8 -4
  95. package/dist/sveltekit/index.mjs.map +1 -1
  96. package/dist/toolkit.d.mts +41 -4
  97. package/dist/toolkit.d.mts.map +1 -1
  98. package/dist/toolkit.mjs +5 -3
  99. package/dist/types.d.mts +2 -2
  100. package/dist/{useLogger-Dcj1Nrsa.d.mts → useLogger-C56tDPwf.d.mts} +2 -2
  101. package/dist/{useLogger-Dcj1Nrsa.d.mts.map → useLogger-C56tDPwf.d.mts.map} +1 -1
  102. package/dist/{utils-Bnc95-VC.d.mts → utils-DzGCLRFe.d.mts} +2 -2
  103. package/dist/{utils-Bnc95-VC.d.mts.map → utils-DzGCLRFe.d.mts.map} +1 -1
  104. package/dist/utils.d.mts +1 -1
  105. package/dist/vite/index.d.mts +1 -1
  106. package/dist/workers.d.mts +1 -1
  107. package/dist/workers.mjs +1 -1
  108. package/package.json +16 -3
  109. package/dist/headers-ht4yS2mx.mjs.map +0 -1
  110. package/dist/logger-Bm0k3Hf3.d.mts.map +0 -1
  111. package/dist/logger-DY0X5oQd.mjs +0 -704
  112. package/dist/logger-DY0X5oQd.mjs.map +0 -1
  113. package/dist/parseError-DhXS_vzM.d.mts.map +0 -1
  114. package/dist/types-D5OwxZCw.d.mts +0 -587
  115. package/dist/types-D5OwxZCw.d.mts.map +0 -1
@@ -1,5 +1,7 @@
1
- import { n as extractSafeNodeHeaders, r as createMiddlewareLogger } from "../headers-ht4yS2mx.mjs";
2
- import { t as createLoggerStorage } from "../storage-DpLJYMoc.mjs";
1
+ import { t as createMiddlewareLogger } from "../middleware-BWOJ7JI0.mjs";
2
+ import { t as attachForkToLogger } from "../fork-CTJXnpl8.mjs";
3
+ import { n as extractSafeNodeHeaders } from "../headers-D74M0wsg.mjs";
4
+ import { t as createLoggerStorage } from "../storage-CFGTn37X.mjs";
3
5
  //#region src/express/index.ts
4
6
  const { storage, useLogger } = createLoggerStorage("middleware context. Make sure app.use(evlog()) is registered before your routes.");
5
7
  /**
@@ -22,17 +24,19 @@ const { storage, useLogger } = createLoggerStorage("middleware context. Make sur
22
24
  */
23
25
  function evlog(options = {}) {
24
26
  return (req, res, next) => {
25
- const { logger, finish, skipped } = createMiddlewareLogger({
27
+ const middlewareOpts = {
26
28
  method: req.method,
27
29
  path: new URL(req.originalUrl || req.url || "/", "http://localhost").pathname,
28
30
  requestId: req.get("x-request-id") || crypto.randomUUID(),
29
31
  headers: extractSafeNodeHeaders(req.headers),
30
32
  ...options
31
- });
33
+ };
34
+ const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts);
32
35
  if (skipped) {
33
36
  next();
34
37
  return;
35
38
  }
39
+ attachForkToLogger(storage, logger, middlewareOpts);
36
40
  req.log = logger;
37
41
  res.on("finish", () => {
38
42
  finish({ status: res.statusCode }).catch(() => {});
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/express/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction, RequestHandler } from 'express'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure app.use(evlog()) is registered before your routes.',\n)\n\nexport type EvlogExpressOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log: RequestLogger\n }\n}\n\n/**\n * Create an evlog middleware for Express.\n *\n * @example\n * ```ts\n * import express from 'express'\n * import { evlog } from 'evlog/express'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = express()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogExpressOptions = {}): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: req.method,\n path: new URL(req.originalUrl || req.url || '/', 'http://localhost').pathname,\n requestId: req.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeNodeHeaders(req.headers),\n ...options,\n })\n\n if (skipped) {\n next()\n return\n }\n\n req.log = logger\n\n res.on('finish', () => {\n finish({ status: res.statusCode }).catch(() => {})\n })\n\n storage.run(logger, () => next())\n }\n}\n"],"mappings":";;;AAMA,MAAM,EAAE,SAAS,cAAc,oBAC7B,mFACD;;;;;;;;;;;;;;;;;;;AA8BD,SAAgB,MAAM,UAA+B,EAAE,EAAkB;AACvE,SAAQ,KAAc,KAAe,SAAuB;EAC1D,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,IAAI;GACZ,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,KAAK,mBAAmB,CAAC;GACrE,WAAW,IAAI,IAAI,eAAe,IAAI,OAAO,YAAY;GACzD,SAAS,uBAAuB,IAAI,QAAQ;GAC5C,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,MAAI,MAAM;AAEV,MAAI,GAAG,gBAAgB;AACrB,UAAO,EAAE,QAAQ,IAAI,YAAY,CAAC,CAAC,YAAY,GAAG;IAClD;AAEF,UAAQ,IAAI,cAAc,MAAM,CAAC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/express/index.ts"],"sourcesContent":["import type { Request, Response, NextFunction, RequestHandler } from 'express'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { attachForkToLogger } from '../shared/fork'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure app.use(evlog()) is registered before your routes.',\n)\n\nexport type EvlogExpressOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log: RequestLogger\n }\n}\n\n/**\n * Create an evlog middleware for Express.\n *\n * @example\n * ```ts\n * import express from 'express'\n * import { evlog } from 'evlog/express'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = express()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogExpressOptions = {}): RequestHandler {\n return (req: Request, res: Response, next: NextFunction) => {\n const middlewareOpts = {\n method: req.method,\n path: new URL(req.originalUrl || req.url || '/', 'http://localhost').pathname,\n requestId: req.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeNodeHeaders(req.headers),\n ...options,\n }\n const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts)\n\n if (skipped) {\n next()\n return\n }\n\n attachForkToLogger(storage, logger, middlewareOpts)\n req.log = logger\n\n res.on('finish', () => {\n finish({ status: res.statusCode }).catch(() => {})\n })\n\n storage.run(logger, () => next())\n }\n}\n"],"mappings":";;;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,mFACD;;;;;;;;;;;;;;;;;;;AA8BD,SAAgB,MAAM,UAA+B,EAAE,EAAkB;AACvE,SAAQ,KAAc,KAAe,SAAuB;EAC1D,MAAM,iBAAiB;GACrB,QAAQ,IAAI;GACZ,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,KAAK,mBAAmB,CAAC;GACrE,WAAW,IAAI,IAAI,eAAe,IAAI,OAAO,YAAY;GACzD,SAAS,uBAAuB,IAAI,QAAQ;GAC5C,GAAG;GACJ;EACD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB,eAAe;AAE1E,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,qBAAmB,SAAS,QAAQ,eAAe;AACnD,MAAI,MAAM;AAEV,MAAI,GAAG,gBAAgB;AACrB,UAAO,EAAE,QAAQ,IAAI,YAAY,CAAC,CAAC,YAAY,GAAG;IAClD;AAEF,UAAQ,IAAI,cAAc,MAAM,CAAC"}
@@ -1,5 +1,5 @@
1
- import { _ as RequestLogger } from "../types-D5OwxZCw.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-D_igVy93.mjs";
1
+ import { Y as RequestLogger } from "../audit-mUutdf6A.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-BYf26Lfu.mjs";
3
3
  import { FastifyPluginCallback } from "fastify";
4
4
 
5
5
  //#region src/fastify/index.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/fastify/index.ts"],"mappings":";;;;;cAKiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,mBAAA,GAAsB,gBAAA;AAAA;EAAA,UAKtB,cAAA;IAER,GAAA;EAAA;AAAA;;;;;;;;;;;AAPJ;;;;;AAEoB;;;;;;cAyFP,KAAA,EAAK,qBAAA,CAAA,gBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/fastify/index.ts"],"mappings":";;;;;cAMiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,mBAAA,GAAsB,gBAAA;AAAA;EAAA,UAKtB,cAAA;IAER,GAAA;EAAA;AAAA;;;;;;;;;;;AAPJ;;;;;AAEoB;;;;;;cA4FP,KAAA,EAAK,qBAAA,CAAA,gBAAA"}
@@ -1,5 +1,7 @@
1
- import { n as extractSafeNodeHeaders, r as createMiddlewareLogger } from "../headers-ht4yS2mx.mjs";
2
- import { t as createLoggerStorage } from "../storage-DpLJYMoc.mjs";
1
+ import { t as createMiddlewareLogger } from "../middleware-BWOJ7JI0.mjs";
2
+ import { t as attachForkToLogger } from "../fork-CTJXnpl8.mjs";
3
+ import { n as extractSafeNodeHeaders } from "../headers-D74M0wsg.mjs";
4
+ import { t as createLoggerStorage } from "../storage-CFGTn37X.mjs";
3
5
  //#region src/fastify/index.ts
4
6
  const { storage, useLogger } = createLoggerStorage("plugin context. Make sure app.register(evlog) is called before your routes.");
5
7
  const evlogPlugin = (fastify, options, done) => {
@@ -8,17 +10,19 @@ const evlogPlugin = (fastify, options, done) => {
8
10
  fastify.addHook("onRequest", (request, _reply, done) => {
9
11
  const headers = extractSafeNodeHeaders(request.headers);
10
12
  const path = new URL(request.url, "http://localhost").pathname;
11
- const { logger, finish, skipped } = createMiddlewareLogger({
13
+ const middlewareOpts = {
12
14
  method: request.method,
13
15
  path,
14
16
  requestId: headers["x-request-id"] || crypto.randomUUID(),
15
17
  headers,
16
18
  ...options
17
- });
19
+ };
20
+ const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts);
18
21
  if (skipped) {
19
22
  done();
20
23
  return;
21
24
  }
25
+ attachForkToLogger(storage, logger, middlewareOpts);
22
26
  const req = request;
23
27
  req.log = logger;
24
28
  requestState.set(request, { finish });
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/fastify/index.ts"],"sourcesContent":["import type { FastifyPluginCallback } from 'fastify'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'plugin context. Make sure app.register(evlog) is called before your routes.',\n)\n\nexport type EvlogFastifyOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n // Overrides Fastify's built-in pino logger on the request with evlog's RequestLogger.\n log: any\n }\n}\n\ninterface RequestState {\n finish: (opts?: { status?: number; error?: Error }) => Promise<unknown>\n}\n\nconst evlogPlugin: FastifyPluginCallback<EvlogFastifyOptions> = (fastify, options, done) => {\n const emitted = new WeakSet<object>()\n const requestState = new WeakMap<object, RequestState>()\n\n fastify.addHook('onRequest', (request, _reply, done) => {\n const headers = extractSafeNodeHeaders(request.headers)\n const path = new URL(request.url, 'http://localhost').pathname\n\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: request.method,\n path,\n requestId: headers['x-request-id'] || crypto.randomUUID(),\n headers,\n ...options,\n })\n\n if (skipped) {\n done()\n return\n }\n\n // Shadow Fastify's built-in pino logger with evlog's request-scoped logger\n const req = request as any\n req.log = logger\n requestState.set(request, { finish })\n\n storage.run(logger, () => done())\n })\n\n fastify.addHook('onResponse', async (request, reply) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n await state.finish({ status: reply.statusCode })\n })\n\n fastify.addHook('onError', async (request, _reply, error) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n const logger = (request as any).log\n const err = error instanceof Error ? error : new Error(String(error))\n if (logger && typeof logger.error === 'function') logger.error(err)\n await state.finish({ error: err })\n })\n\n done()\n}\n\n// Break Fastify plugin encapsulation without a runtime dependency on fastify-plugin.\n// This is the same mechanism fastify-plugin uses internally.\nconst plugin = evlogPlugin as any\nplugin[Symbol.for('skip-override')] = true\nplugin[Symbol.for('fastify.display-name')] = 'evlog'\n\n/**\n * Create an evlog plugin for Fastify.\n *\n * @example\n * ```ts\n * import Fastify from 'fastify'\n * import { initLogger } from 'evlog'\n * import { evlog } from 'evlog/fastify'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'fastify-api' } })\n *\n * const app = Fastify()\n * await app.register(evlog, {\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n */\nexport const evlog = evlogPlugin\n"],"mappings":";;;AAKA,MAAM,EAAE,SAAS,cAAc,oBAC7B,8EACD;AAiBD,MAAM,eAA2D,SAAS,SAAS,SAAS;CAC1F,MAAM,0BAAU,IAAI,SAAiB;CACrC,MAAM,+BAAe,IAAI,SAA+B;AAExD,SAAQ,QAAQ,cAAc,SAAS,QAAQ,SAAS;EACtD,MAAM,UAAU,uBAAuB,QAAQ,QAAQ;EACvD,MAAM,OAAO,IAAI,IAAI,QAAQ,KAAK,mBAAmB,CAAC;EAEtD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,QAAQ;GAChB;GACA,WAAW,QAAQ,mBAAmB,OAAO,YAAY;GACzD;GACA,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM;AACN;;EAIF,MAAM,MAAM;AACZ,MAAI,MAAM;AACV,eAAa,IAAI,SAAS,EAAE,QAAQ,CAAC;AAErC,UAAQ,IAAI,cAAc,MAAM,CAAC;GACjC;AAEF,SAAQ,QAAQ,cAAc,OAAO,SAAS,UAAU;EACtD,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;AACpB,QAAM,MAAM,OAAO,EAAE,QAAQ,MAAM,YAAY,CAAC;GAChD;AAEF,SAAQ,QAAQ,WAAW,OAAO,SAAS,QAAQ,UAAU;EAC3D,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;EACpB,MAAM,SAAU,QAAgB;EAChC,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,MAAI,UAAU,OAAO,OAAO,UAAU,WAAY,QAAO,MAAM,IAAI;AACnE,QAAM,MAAM,OAAO,EAAE,OAAO,KAAK,CAAC;GAClC;AAEF,OAAM;;AAKR,MAAM,SAAS;AACf,OAAO,OAAO,IAAI,gBAAgB,IAAI;AACtC,OAAO,OAAO,IAAI,uBAAuB,IAAI;;;;;;;;;;;;;;;;;;;;;;AAuB7C,MAAa,QAAQ"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/fastify/index.ts"],"sourcesContent":["import type { FastifyPluginCallback } from 'fastify'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { attachForkToLogger } from '../shared/fork'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'plugin context. Make sure app.register(evlog) is called before your routes.',\n)\n\nexport type EvlogFastifyOptions = BaseEvlogOptions\n\nexport { useLogger }\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n // Overrides Fastify's built-in pino logger on the request with evlog's RequestLogger.\n log: any\n }\n}\n\ninterface RequestState {\n finish: (opts?: { status?: number; error?: Error }) => Promise<unknown>\n}\n\nconst evlogPlugin: FastifyPluginCallback<EvlogFastifyOptions> = (fastify, options, done) => {\n const emitted = new WeakSet<object>()\n const requestState = new WeakMap<object, RequestState>()\n\n fastify.addHook('onRequest', (request, _reply, done) => {\n const headers = extractSafeNodeHeaders(request.headers)\n const path = new URL(request.url, 'http://localhost').pathname\n\n const middlewareOpts = {\n method: request.method,\n path,\n requestId: headers['x-request-id'] || crypto.randomUUID(),\n headers,\n ...options,\n }\n const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts)\n\n if (skipped) {\n done()\n return\n }\n\n attachForkToLogger(storage, logger, middlewareOpts)\n\n // Shadow Fastify's built-in pino logger with evlog's request-scoped logger\n const req = request as any\n req.log = logger\n requestState.set(request, { finish })\n\n storage.run(logger, () => done())\n })\n\n fastify.addHook('onResponse', async (request, reply) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n await state.finish({ status: reply.statusCode })\n })\n\n fastify.addHook('onError', async (request, _reply, error) => {\n const state = requestState.get(request)\n if (!state || emitted.has(request)) return\n emitted.add(request)\n const logger = (request as any).log\n const err = error instanceof Error ? error : new Error(String(error))\n if (logger && typeof logger.error === 'function') logger.error(err)\n await state.finish({ error: err })\n })\n\n done()\n}\n\n// Break Fastify plugin encapsulation without a runtime dependency on fastify-plugin.\n// This is the same mechanism fastify-plugin uses internally.\nconst plugin = evlogPlugin as any\nplugin[Symbol.for('skip-override')] = true\nplugin[Symbol.for('fastify.display-name')] = 'evlog'\n\n/**\n * Create an evlog plugin for Fastify.\n *\n * @example\n * ```ts\n * import Fastify from 'fastify'\n * import { initLogger } from 'evlog'\n * import { evlog } from 'evlog/fastify'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'fastify-api' } })\n *\n * const app = Fastify()\n * await app.register(evlog, {\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n */\nexport const evlog = evlogPlugin\n"],"mappings":";;;;;AAMA,MAAM,EAAE,SAAS,cAAc,oBAC7B,8EACD;AAiBD,MAAM,eAA2D,SAAS,SAAS,SAAS;CAC1F,MAAM,0BAAU,IAAI,SAAiB;CACrC,MAAM,+BAAe,IAAI,SAA+B;AAExD,SAAQ,QAAQ,cAAc,SAAS,QAAQ,SAAS;EACtD,MAAM,UAAU,uBAAuB,QAAQ,QAAQ;EACvD,MAAM,OAAO,IAAI,IAAI,QAAQ,KAAK,mBAAmB,CAAC;EAEtD,MAAM,iBAAiB;GACrB,QAAQ,QAAQ;GAChB;GACA,WAAW,QAAQ,mBAAmB,OAAO,YAAY;GACzD;GACA,GAAG;GACJ;EACD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB,eAAe;AAE1E,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,qBAAmB,SAAS,QAAQ,eAAe;EAGnD,MAAM,MAAM;AACZ,MAAI,MAAM;AACV,eAAa,IAAI,SAAS,EAAE,QAAQ,CAAC;AAErC,UAAQ,IAAI,cAAc,MAAM,CAAC;GACjC;AAEF,SAAQ,QAAQ,cAAc,OAAO,SAAS,UAAU;EACtD,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;AACpB,QAAM,MAAM,OAAO,EAAE,QAAQ,MAAM,YAAY,CAAC;GAChD;AAEF,SAAQ,QAAQ,WAAW,OAAO,SAAS,QAAQ,UAAU;EAC3D,MAAM,QAAQ,aAAa,IAAI,QAAQ;AACvC,MAAI,CAAC,SAAS,QAAQ,IAAI,QAAQ,CAAE;AACpC,UAAQ,IAAI,QAAQ;EACpB,MAAM,SAAU,QAAgB;EAChC,MAAM,MAAM,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,MAAM,CAAC;AACrE,MAAI,UAAU,OAAO,OAAO,UAAU,WAAY,QAAO,MAAM,IAAI;AACnE,QAAM,MAAM,OAAO,EAAE,OAAO,KAAK,CAAC;GAClC;AAEF,OAAM;;AAKR,MAAM,SAAS;AACf,OAAO,OAAO,IAAI,gBAAgB,IAAI;AACtC,OAAO,OAAO,IAAI,uBAAuB,IAAI;;;;;;;;;;;;;;;;;;;;;;AAuB7C,MAAa,QAAQ"}
@@ -0,0 +1,72 @@
1
+ import { g as createRequestLogger, v as getGlobalDrain } from "./audit-d9esRZOK.mjs";
2
+ import { t as extractErrorStatus } from "./errors-BJRXUfMg.mjs";
3
+ import { n as runEnrichAndDrain } from "./middleware-BWOJ7JI0.mjs";
4
+ //#region src/shared/fork.ts
5
+ /**
6
+ * Attach {@link RequestLogger.fork} to a request logger. Replaces any existing `fork`.
7
+ */
8
+ function attachForkToLogger(storage, parent, middlewareOptions, lifecycle) {
9
+ const log = parent;
10
+ log.fork = (label, fn) => {
11
+ forkBackgroundLogger({
12
+ storage,
13
+ parent,
14
+ middlewareOptions,
15
+ label,
16
+ fn,
17
+ lifecycle
18
+ });
19
+ };
20
+ }
21
+ /**
22
+ * Run background work under a child request logger so `useLogger()` resolves to the
23
+ * child while `fn` runs. The child emits a separate wide event when `fn` settles,
24
+ * with `operation` and `_parentRequestId` set for correlation.
25
+ *
26
+ * @beta Part of `evlog/toolkit` — used by framework integrations; prefer `log.fork()`
27
+ * on the request logger when available.
28
+ */
29
+ function forkBackgroundLogger(options) {
30
+ const { storage, parent, middlewareOptions, label, fn, lifecycle } = options;
31
+ const parentCtx = parent.getContext();
32
+ const parentRequestId = parentCtx.requestId;
33
+ if (typeof parentRequestId !== "string" || parentRequestId.length === 0) throw new Error("[evlog] log.fork() requires the parent logger to have a requestId. Ensure the request was created by evlog middleware.");
34
+ const method = String(parentCtx.method ?? middlewareOptions.method);
35
+ const path = String(parentCtx.path ?? middlewareOptions.path);
36
+ const child = createRequestLogger({
37
+ method,
38
+ path,
39
+ requestId: crypto.randomUUID()
40
+ }, { _deferDrain: true });
41
+ child.set({
42
+ operation: label,
43
+ _parentRequestId: parentRequestId
44
+ });
45
+ const childRequestInfo = {
46
+ method,
47
+ path,
48
+ requestId: child.getContext().requestId
49
+ };
50
+ storage.run(child, () => {
51
+ lifecycle?.onChildEnter?.(child);
52
+ Promise.resolve().then(() => fn()).then(async () => {
53
+ const emittedEvent = child.emit();
54
+ const ctxStatus = child.getContext().status;
55
+ const status = emittedEvent?.status ?? (typeof ctxStatus === "number" ? ctxStatus : void 0);
56
+ if (emittedEvent && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())) await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status);
57
+ }).catch(async (err) => {
58
+ const error = err instanceof Error ? err : new Error(String(err));
59
+ child.error(error);
60
+ child.set({ status: extractErrorStatus(error) });
61
+ const emittedEvent = child.emit();
62
+ const status = extractErrorStatus(error);
63
+ if (emittedEvent && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())) await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status);
64
+ }).finally(() => {
65
+ lifecycle?.onChildExit?.(child);
66
+ });
67
+ });
68
+ }
69
+ //#endregion
70
+ export { forkBackgroundLogger as n, attachForkToLogger as t };
71
+
72
+ //# sourceMappingURL=fork-CTJXnpl8.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fork-CTJXnpl8.mjs","names":[],"sources":["../src/shared/fork.ts"],"sourcesContent":["import type { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RequestLogger } from '../types'\nimport { createRequestLogger, getGlobalDrain } from '../logger'\nimport { extractErrorStatus } from './errors'\nimport type { MiddlewareLoggerOptions } from './middleware'\nimport { runEnrichAndDrain } from './middleware'\n\n/**\n * Optional hooks for integrations that track active loggers (e.g. Elysia `activeLoggers`).\n */\nexport interface ForkLifecycle {\n /** Called after the child logger is installed in storage, before `fn` runs. */\n onChildEnter?: (child: RequestLogger) => void\n /** Called after the child has finished (emit + enrich/drain), success or failure. */\n onChildExit?: (child: RequestLogger) => void\n}\n\n/**\n * Options for {@link forkBackgroundLogger}.\n *\n * @beta Part of `evlog/toolkit`\n */\nexport interface ForkBackgroundLoggerOptions {\n storage: AsyncLocalStorage<RequestLogger>\n parent: RequestLogger\n middlewareOptions: MiddlewareLoggerOptions\n label: string\n fn: () => void | Promise<void>\n lifecycle?: ForkLifecycle\n}\n\n/**\n * Attach {@link RequestLogger.fork} to a request logger. Replaces any existing `fork`.\n */\nexport function attachForkToLogger(\n storage: AsyncLocalStorage<RequestLogger>,\n parent: RequestLogger,\n middlewareOptions: MiddlewareLoggerOptions,\n lifecycle?: ForkLifecycle,\n): void {\n const log = parent as RequestLogger & { fork?: (label: string, fn: () => void | Promise<void>) => void }\n log.fork = (label: string, fn: () => void | Promise<void>) => {\n forkBackgroundLogger({ storage, parent, middlewareOptions, label, fn, lifecycle })\n }\n}\n\n/**\n * Run background work under a child request logger so `useLogger()` resolves to the\n * child while `fn` runs. The child emits a separate wide event when `fn` settles,\n * with `operation` and `_parentRequestId` set for correlation.\n *\n * @beta Part of `evlog/toolkit` — used by framework integrations; prefer `log.fork()`\n * on the request logger when available.\n */\nexport function forkBackgroundLogger(options: ForkBackgroundLoggerOptions): void {\n const { storage, parent, middlewareOptions, label, fn, lifecycle } = options\n\n const parentCtx = parent.getContext() as Record<string, unknown>\n const parentRequestId = parentCtx.requestId\n if (typeof parentRequestId !== 'string' || parentRequestId.length === 0) {\n throw new Error(\n '[evlog] log.fork() requires the parent logger to have a requestId. '\n + 'Ensure the request was created by evlog middleware.',\n )\n }\n\n const method = String(parentCtx.method ?? middlewareOptions.method)\n const path = String(parentCtx.path ?? middlewareOptions.path)\n\n const child = createRequestLogger(\n {\n method,\n path,\n requestId: crypto.randomUUID(),\n },\n { _deferDrain: true },\n )\n\n child.set({\n operation: label,\n _parentRequestId: parentRequestId,\n })\n\n const childRequestInfo = {\n method,\n path,\n requestId: child.getContext().requestId as string,\n }\n\n storage.run(child, () => {\n lifecycle?.onChildEnter?.(child)\n void Promise.resolve()\n .then(() => fn())\n .then(async () => {\n const emittedEvent = child.emit()\n const ctxStatus = child.getContext().status\n const status = (emittedEvent?.status\n ?? (typeof ctxStatus === 'number' ? ctxStatus : undefined)) as number | undefined\n if (\n emittedEvent\n && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())\n ) {\n await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status)\n }\n })\n .catch(async (err: unknown) => {\n const error = err instanceof Error ? err : new Error(String(err))\n child.error(error)\n child.set({ status: extractErrorStatus(error) })\n const emittedEvent = child.emit()\n const status = extractErrorStatus(error)\n if (\n emittedEvent\n && (middlewareOptions.enrich || middlewareOptions.drain || getGlobalDrain())\n ) {\n await runEnrichAndDrain(emittedEvent, middlewareOptions, childRequestInfo, status)\n }\n })\n .finally(() => {\n lifecycle?.onChildExit?.(child)\n })\n })\n}\n"],"mappings":";;;;;;;AAkCA,SAAgB,mBACd,SACA,QACA,mBACA,WACM;CACN,MAAM,MAAM;AACZ,KAAI,QAAQ,OAAe,OAAmC;AAC5D,uBAAqB;GAAE;GAAS;GAAQ;GAAmB;GAAO;GAAI;GAAW,CAAC;;;;;;;;;;;AAYtF,SAAgB,qBAAqB,SAA4C;CAC/E,MAAM,EAAE,SAAS,QAAQ,mBAAmB,OAAO,IAAI,cAAc;CAErE,MAAM,YAAY,OAAO,YAAY;CACrC,MAAM,kBAAkB,UAAU;AAClC,KAAI,OAAO,oBAAoB,YAAY,gBAAgB,WAAW,EACpE,OAAM,IAAI,MACR,yHAED;CAGH,MAAM,SAAS,OAAO,UAAU,UAAU,kBAAkB,OAAO;CACnE,MAAM,OAAO,OAAO,UAAU,QAAQ,kBAAkB,KAAK;CAE7D,MAAM,QAAQ,oBACZ;EACE;EACA;EACA,WAAW,OAAO,YAAY;EAC/B,EACD,EAAE,aAAa,MAAM,CACtB;AAED,OAAM,IAAI;EACR,WAAW;EACX,kBAAkB;EACnB,CAAC;CAEF,MAAM,mBAAmB;EACvB;EACA;EACA,WAAW,MAAM,YAAY,CAAC;EAC/B;AAED,SAAQ,IAAI,aAAa;AACvB,aAAW,eAAe,MAAM;AAC3B,UAAQ,SAAS,CACnB,WAAW,IAAI,CAAC,CAChB,KAAK,YAAY;GAChB,MAAM,eAAe,MAAM,MAAM;GACjC,MAAM,YAAY,MAAM,YAAY,CAAC;GACrC,MAAM,SAAU,cAAc,WACxB,OAAO,cAAc,WAAW,YAAY,KAAA;AAClD,OACE,iBACI,kBAAkB,UAAU,kBAAkB,SAAS,gBAAgB,EAE3E,OAAM,kBAAkB,cAAc,mBAAmB,kBAAkB,OAAO;IAEpF,CACD,MAAM,OAAO,QAAiB;GAC7B,MAAM,QAAQ,eAAe,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAI,CAAC;AACjE,SAAM,MAAM,MAAM;AAClB,SAAM,IAAI,EAAE,QAAQ,mBAAmB,MAAM,EAAE,CAAC;GAChD,MAAM,eAAe,MAAM,MAAM;GACjC,MAAM,SAAS,mBAAmB,MAAM;AACxC,OACE,iBACI,kBAAkB,UAAU,kBAAkB,SAAS,gBAAgB,EAE3E,OAAM,kBAAkB,cAAc,mBAAmB,kBAAkB,OAAO;IAEpF,CACD,cAAc;AACb,cAAW,cAAc,MAAM;IAC/B;GACJ"}
@@ -0,0 +1,30 @@
1
+ import { filterSafeHeaders } from "./utils.mjs";
2
+ //#region src/shared/headers.ts
3
+ /**
4
+ * Extract headers from a Web API `Headers` object and filter out sensitive ones.
5
+ * Works with any runtime that supports the standard `Headers` API (Hono, Elysia,
6
+ * Nitro v3, Cloudflare Workers, Bun, Deno, etc.).
7
+ */
8
+ function extractSafeHeaders(headers) {
9
+ const raw = {};
10
+ headers.forEach((value, key) => {
11
+ raw[key] = value;
12
+ });
13
+ return filterSafeHeaders(raw);
14
+ }
15
+ /**
16
+ * Extract headers from Node.js `IncomingHttpHeaders` and filter out sensitive ones.
17
+ * Works with Express, Fastify, and any Node.js HTTP server using `req.headers`.
18
+ */
19
+ function extractSafeNodeHeaders(headers) {
20
+ const raw = {};
21
+ for (const [key, value] of Object.entries(headers)) {
22
+ if (value === void 0) continue;
23
+ raw[key] = Array.isArray(value) ? value.join(", ") : value;
24
+ }
25
+ return filterSafeHeaders(raw);
26
+ }
27
+ //#endregion
28
+ export { extractSafeNodeHeaders as n, extractSafeHeaders as t };
29
+
30
+ //# sourceMappingURL=headers-D74M0wsg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"headers-D74M0wsg.mjs","names":[],"sources":["../src/shared/headers.ts"],"sourcesContent":["import { filterSafeHeaders } from '../utils'\n\n/**\n * Extract headers from a Web API `Headers` object and filter out sensitive ones.\n * Works with any runtime that supports the standard `Headers` API (Hono, Elysia,\n * Nitro v3, Cloudflare Workers, Bun, Deno, etc.).\n */\nexport function extractSafeHeaders(headers: Headers): Record<string, string> {\n const raw: Record<string, string> = {}\n headers.forEach((value, key) => {\n raw[key] = value\n })\n return filterSafeHeaders(raw)\n}\n\n/**\n * Extract headers from Node.js `IncomingHttpHeaders` and filter out sensitive ones.\n * Works with Express, Fastify, and any Node.js HTTP server using `req.headers`.\n */\nexport function extractSafeNodeHeaders(headers: Record<string, string | string[] | undefined>): Record<string, string> {\n const raw: Record<string, string> = {}\n for (const [key, value] of Object.entries(headers)) {\n if (value === undefined) continue\n raw[key] = Array.isArray(value) ? value.join(', ') : value\n }\n return filterSafeHeaders(raw)\n}\n"],"mappings":";;;;;;;AAOA,SAAgB,mBAAmB,SAA0C;CAC3E,MAAM,MAA8B,EAAE;AACtC,SAAQ,SAAS,OAAO,QAAQ;AAC9B,MAAI,OAAO;GACX;AACF,QAAO,kBAAkB,IAAI;;;;;;AAO/B,SAAgB,uBAAuB,SAAgF;CACrH,MAAM,MAA8B,EAAE;AACtC,MAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,QAAQ,EAAE;AAClD,MAAI,UAAU,KAAA,EAAW;AACzB,MAAI,OAAO,MAAM,QAAQ,MAAM,GAAG,MAAM,KAAK,KAAK,GAAG;;AAEvD,QAAO,kBAAkB,IAAI"}
@@ -1,5 +1,5 @@
1
- import { _ as RequestLogger } from "../types-D5OwxZCw.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-D_igVy93.mjs";
1
+ import { Y as RequestLogger } from "../audit-mUutdf6A.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-BYf26Lfu.mjs";
3
3
  import { MiddlewareHandler } from "hono";
4
4
 
5
5
  //#region src/hono/index.d.ts
@@ -1,4 +1,5 @@
1
- import { r as createMiddlewareLogger, t as extractSafeHeaders } from "../headers-ht4yS2mx.mjs";
1
+ import { t as createMiddlewareLogger } from "../middleware-BWOJ7JI0.mjs";
2
+ import { t as extractSafeHeaders } from "../headers-D74M0wsg.mjs";
2
3
  //#region src/hono/index.ts
3
4
  /**
4
5
  * Create an evlog middleware for Hono.
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\n\nexport type EvlogHonoOptions = BaseEvlogOptions\n\n/**\n * Hono variables type for typed `c.get('log')` access.\n *\n * @example\n * ```ts\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog())\n * app.get('/api/users', (c) => {\n * const log = c.get('log')\n * log.set({ users: { count: 42 } })\n * return c.json({ users: [] })\n * })\n * ```\n */\nexport type EvlogVariables = { Variables: { log: RequestLogger } }\n\n/**\n * Create an evlog middleware for Hono.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono'\n * import { evlog, type EvlogVariables } from 'evlog/hono'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogHonoOptions = {}): MiddlewareHandler {\n return async (c, next) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: c.req.method,\n path: c.req.path,\n requestId: c.req.header('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(c.req.raw.headers),\n ...options,\n })\n\n if (skipped) {\n await next()\n return\n }\n\n c.set('log', logger)\n\n try {\n await next()\n await finish({ status: c.res.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,MAAM,UAA4B,EAAE,EAAqB;AACvE,QAAO,OAAO,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,EAAE,IAAI;GACd,MAAM,EAAE,IAAI;GACZ,WAAW,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,YAAY;GAC9D,SAAS,mBAAmB,EAAE,IAAI,IAAI,QAAQ;GAC9C,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM,MAAM;AACZ;;AAGF,IAAE,IAAI,OAAO,OAAO;AAEpB,MAAI;AACF,SAAM,MAAM;AACZ,SAAM,OAAO,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;WAC/B,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/hono/index.ts"],"sourcesContent":["import type { MiddlewareHandler } from 'hono'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\n\nexport type EvlogHonoOptions = BaseEvlogOptions\n\n/**\n * Hono variables type for typed `c.get('log')` access.\n *\n * @example\n * ```ts\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog())\n * app.get('/api/users', (c) => {\n * const log = c.get('log')\n * log.set({ users: { count: 42 } })\n * return c.json({ users: [] })\n * })\n * ```\n */\nexport type EvlogVariables = { Variables: { log: RequestLogger } }\n\n/**\n * Create an evlog middleware for Hono.\n *\n * @example\n * ```ts\n * import { Hono } from 'hono'\n * import { evlog, type EvlogVariables } from 'evlog/hono'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * const app = new Hono<EvlogVariables>()\n * app.use(evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * }))\n * ```\n */\nexport function evlog(options: EvlogHonoOptions = {}): MiddlewareHandler {\n return async (c, next) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: c.req.method,\n path: c.req.path,\n requestId: c.req.header('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(c.req.raw.headers),\n ...options,\n })\n\n if (skipped) {\n await next()\n return\n }\n\n c.set('log', logger)\n\n try {\n await next()\n await finish({ status: c.res.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAyCA,SAAgB,MAAM,UAA4B,EAAE,EAAqB;AACvE,QAAO,OAAO,GAAG,SAAS;EACxB,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,EAAE,IAAI;GACd,MAAM,EAAE,IAAI;GACZ,WAAW,EAAE,IAAI,OAAO,eAAe,IAAI,OAAO,YAAY;GAC9D,SAAS,mBAAmB,EAAE,IAAI,IAAI,QAAQ;GAC9C,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM,MAAM;AACZ;;AAGF,IAAE,IAAI,OAAO,OAAO;AAEpB,MAAI;AACF,SAAM,MAAM;AACZ,SAAM,OAAO,EAAE,QAAQ,EAAE,IAAI,QAAQ,CAAC;WAC/B,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
package/dist/http.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { r as DrainContext } from "./types-D5OwxZCw.mjs";
1
+ import { F as DrainContext } from "./audit-mUutdf6A.mjs";
2
2
  import { DrainPipelineOptions, PipelineDrainFn } from "./pipeline.mjs";
3
3
 
4
4
  //#region src/http.d.ts
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
- import { C as TailSamplingCondition, E as WideEvent, S as ServerEvent, T as TransportConfig, _ as RequestLogger, a as EnvironmentContext, b as SamplingConfig, c as H3EventContext, d as Log, f as LogLevel, h as RedactConfig, i as EnrichContext, l as IngestPayload, m as ParsedError, n as DeepPartial, o as ErrorOptions, p as LoggerConfig, r as DrainContext, s as FieldContext, t as BaseWideEvent, u as InternalFields, v as RequestLoggerOptions, w as TailSamplingContext, x as SamplingRates } from "./types-D5OwxZCw.mjs";
2
- import { n as createError, t as EvlogError } from "./error-WRz4_F3W.mjs";
3
- import { i as getEnvironment, n as createLogger, o as initLogger, r as createRequestLogger, s as isEnabled, t as _log, u as shouldKeep } from "./logger-Bm0k3Hf3.mjs";
4
- import { p as isLevelEnabled } from "./utils-Bnc95-VC.mjs";
5
- import { t as useLogger } from "./useLogger-Dcj1Nrsa.mjs";
6
- import { t as parseError } from "./parseError-DhXS_vzM.mjs";
7
- export { type BaseWideEvent, type DeepPartial, type DrainContext, type EnrichContext, type EnvironmentContext, type ErrorOptions, EvlogError, type FieldContext, type H3EventContext, type IngestPayload, type InternalFields, type Log, type LogLevel, type LoggerConfig, type ParsedError, type RedactConfig, type RequestLogger, type RequestLoggerOptions, type SamplingConfig, type SamplingRates, type ServerEvent, type TailSamplingCondition, type TailSamplingContext, type TransportConfig, type WideEvent, createError, createError as createEvlogError, createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, isLevelEnabled, _log as log, parseError, shouldKeep, useLogger };
1
+ import { $ as SamplingRates, A as AuditFields, B as H3EventContext, C as buildAuditFields, D as withAudit, E as signed, F as DrainContext, G as LoggerConfig, H as InternalFields, I as EnrichContext, K as ParsedError, L as EnvironmentContext, M as AuditTarget, N as BaseWideEvent, O as withAuditMethods, P as DeepPartial, Q as SamplingConfig, R as ErrorOptions, S as auditRedactPreset, T as mockAudit, U as Log, V as IngestPayload, W as LogLevel, X as RequestLoggerOptions, Y as RequestLogger, _ as WithAuditOptions, a as AuditInput, b as auditEnricher, c as AuditOnlyOptions, d as DefinedAuditAction, et as ServerEvent, f as DrainFn, g as WithAuditContext, h as SignedOptions, i as AuditEnricherOptions, it as WideEvent, j as AuditLoggerMethod, k as AuditActor, l as AuditPatchOp, m as SignedChainState, n as AuditDeniedError, nt as TailSamplingContext, o as AuditMatcher, p as MockAudit, q as RedactConfig, r as AuditDiffOptions, rt as TransportConfig, s as AuditMethod, t as AUDIT_SCHEMA_VERSION, tt as TailSamplingCondition, u as AuditableLogger, v as audit, w as defineAuditAction, x as auditOnly, y as auditDiff, z as FieldContext } from "./audit-mUutdf6A.mjs";
2
+ import { n as createError, t as EvlogError } from "./error-D1FZI2Kd.mjs";
3
+ import { i as getEnvironment, n as createLogger, o as initLogger, r as createRequestLogger, s as isEnabled, t as _log, u as shouldKeep } from "./logger-b3epPH0N.mjs";
4
+ import { p as isLevelEnabled } from "./utils-DzGCLRFe.mjs";
5
+ import { t as useLogger } from "./useLogger-C56tDPwf.mjs";
6
+ import { t as parseError } from "./parseError-BR9pocvY.mjs";
7
+ export { AUDIT_SCHEMA_VERSION, type AuditActor, AuditDeniedError, type AuditDiffOptions, type AuditEnricherOptions, type AuditFields, type AuditInput, type AuditLoggerMethod, type AuditMatcher, type AuditMethod, type AuditOnlyOptions, type AuditPatchOp, type AuditTarget, type AuditableLogger, type BaseWideEvent, type DeepPartial, type DefinedAuditAction, type DrainContext, type DrainFn, type EnrichContext, type EnvironmentContext, type ErrorOptions, EvlogError, type FieldContext, type H3EventContext, type IngestPayload, type InternalFields, type Log, type LogLevel, type LoggerConfig, type MockAudit, type ParsedError, type RedactConfig, type RequestLogger, type RequestLoggerOptions, type SamplingConfig, type SamplingRates, type ServerEvent, type SignedChainState, type SignedOptions, type TailSamplingCondition, type TailSamplingContext, type TransportConfig, type WideEvent, type WithAuditContext, type WithAuditOptions, audit, auditDiff, auditEnricher, auditOnly, auditRedactPreset, buildAuditFields, createError, createError as createEvlogError, createLogger, createRequestLogger, defineAuditAction, getEnvironment, initLogger, isEnabled, isLevelEnabled, _log as log, mockAudit, parseError, shouldKeep, signed, useLogger, withAudit, withAuditMethods };
package/dist/index.mjs CHANGED
@@ -1,6 +1,6 @@
1
+ import { C as shouldKeep, _ as getEnvironment, a as auditEnricher, b as isEnabled, c as buildAuditFields, d as signed, f as withAudit, g as createRequestLogger, h as createLogger, i as auditDiff, l as defineAuditAction, m as _log, n as AuditDeniedError, o as auditOnly, p as withAuditMethods, r as audit, s as auditRedactPreset, t as AUDIT_SCHEMA_VERSION, u as mockAudit, y as initLogger } from "./audit-d9esRZOK.mjs";
1
2
  import { isLevelEnabled } from "./utils.mjs";
2
3
  import { EvlogError, createError } from "./error.mjs";
3
- import { i as getEnvironment, n as createLogger, o as initLogger, r as createRequestLogger, s as isEnabled, t as _log, u as shouldKeep } from "./logger-DY0X5oQd.mjs";
4
4
  import { useLogger } from "./runtime/server/useLogger.mjs";
5
5
  import { parseError } from "./runtime/utils/parseError.mjs";
6
- export { EvlogError, createError, createError as createEvlogError, createLogger, createRequestLogger, getEnvironment, initLogger, isEnabled, isLevelEnabled, _log as log, parseError, shouldKeep, useLogger };
6
+ export { AUDIT_SCHEMA_VERSION, AuditDeniedError, EvlogError, audit, auditDiff, auditEnricher, auditOnly, auditRedactPreset, buildAuditFields, createError, createError as createEvlogError, createLogger, createRequestLogger, defineAuditAction, getEnvironment, initLogger, isEnabled, isLevelEnabled, _log as log, mockAudit, parseError, shouldKeep, signed, useLogger, withAudit, withAuditMethods };
@@ -1,4 +1,4 @@
1
- import { _ as RequestLogger, a as EnvironmentContext, d as Log, p as LoggerConfig, r as DrainContext, v as RequestLoggerOptions, w as TailSamplingContext } from "./types-D5OwxZCw.mjs";
1
+ import { F as DrainContext, G as LoggerConfig, L as EnvironmentContext, U as Log, X as RequestLoggerOptions, nt as TailSamplingContext, u as AuditableLogger } from "./audit-mUutdf6A.mjs";
2
2
 
3
3
  //#region src/logger.d.ts
4
4
  /**
@@ -55,6 +55,10 @@ interface CreateLoggerInternalOptions {
55
55
  * Create a scoped logger for building wide events.
56
56
  * Use this for any context: workflows, jobs, scripts, queues, etc.
57
57
  *
58
+ * After `emit()` (including when sampling returns `null`), the logger is sealed and
59
+ * further mutations log `[evlog]` warnings. Standalone loggers do not have `fork`;
60
+ * that method is only attached by supported framework integrations.
61
+ *
58
62
  * @example
59
63
  * ```ts
60
64
  * const log = createLogger({ jobId: job.id, queue: 'emails' })
@@ -62,7 +66,7 @@ interface CreateLoggerInternalOptions {
62
66
  * log.emit()
63
67
  * ```
64
68
  */
65
- declare function createLogger<T extends object = Record<string, unknown>>(initialContext?: Record<string, unknown>, internalOptions?: CreateLoggerInternalOptions): RequestLogger<T>;
69
+ declare function createLogger<T extends object = Record<string, unknown>>(initialContext?: Record<string, unknown>, internalOptions?: CreateLoggerInternalOptions): AuditableLogger<T>;
66
70
  /**
67
71
  * Create a request-scoped logger for building wide events.
68
72
  * Convenience wrapper around `createLogger` that pre-populates HTTP request fields.
@@ -75,11 +79,11 @@ declare function createLogger<T extends object = Record<string, unknown>>(initia
75
79
  * log.emit()
76
80
  * ```
77
81
  */
78
- declare function createRequestLogger<T extends object = Record<string, unknown>>(options?: RequestLoggerOptions, internalOptions?: CreateLoggerInternalOptions): RequestLogger<T>;
82
+ declare function createRequestLogger<T extends object = Record<string, unknown>>(options?: RequestLoggerOptions, internalOptions?: CreateLoggerInternalOptions): AuditableLogger<T>;
79
83
  /**
80
84
  * Get the current environment context.
81
85
  */
82
86
  declare function getEnvironment(): EnvironmentContext;
83
87
  //#endregion
84
88
  export { getGlobalDrain as a, isLoggerLocked as c, getEnvironment as i, lockLogger as l, createLogger as n, initLogger as o, createRequestLogger as r, isEnabled as s, _log as t, shouldKeep as u };
85
- //# sourceMappingURL=logger-Bm0k3Hf3.d.mts.map
89
+ //# sourceMappingURL=logger-b3epPH0N.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-b3epPH0N.d.mts","names":[],"sources":["../src/logger.ts"],"mappings":";;;;AA6DA;;;iBAAgB,UAAA,CAAW,MAAA,GAAQ,YAAA;;AA4BnC;;iBAAgB,SAAA,CAAA;;;AAShB;;;iBAAgB,UAAA,CAAA;;AAOhB;;iBAAgB,cAAA,CAAA;;;AAShB;;;iBAAgB,cAAA,CAAA,KAAoB,GAAA,EAAK,YAAA,YAAwB,OAAA;;;;;iBA8BjD,UAAA,CAAW,GAAA,EAAK,mBAAA;AAAhC;;;;;AAgBC;;;;AAhBD,cAgXM,IAAA,EAAM,GAAA;;;;UA2BF,2BAAA;EAuBM;;;;EAlBd,WAAA;AAAA;;;;;;;;;;;;;;;AAgMF;iBA9KgB,YAAA,oBAAgC,MAAA,kBAAA,CAAyB,cAAA,GAAgB,MAAA,mBAA8B,eAAA,GAAkB,2BAAA,GAA8B,eAAA,CAAgB,CAAA;;;;;;;;;;;;;iBA8KvK,mBAAA,oBAAuC,MAAA,kBAAA,CAAyB,OAAA,GAAS,oBAAA,EAA2B,eAAA,GAAkB,2BAAA,GAA8B,eAAA,CAAgB,CAAA;;;;iBAWpK,cAAA,CAAA,GAAkB,kBAAA"}
package/dist/logger.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as getGlobalDrain, c as isLoggerLocked, i as getEnvironment, l as lockLogger, n as createLogger, o as initLogger, r as createRequestLogger, s as isEnabled, t as _log, u as shouldKeep } from "./logger-Bm0k3Hf3.mjs";
1
+ import { a as getGlobalDrain, c as isLoggerLocked, i as getEnvironment, l as lockLogger, n as createLogger, o as initLogger, r as createRequestLogger, s as isEnabled, t as _log, u as shouldKeep } from "./logger-b3epPH0N.mjs";
2
2
  export { createLogger, createRequestLogger, getEnvironment, getGlobalDrain, initLogger, isEnabled, isLoggerLocked, lockLogger, _log as log, shouldKeep };
package/dist/logger.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as getGlobalDrain, c as isLoggerLocked, i as getEnvironment, l as lockLogger, n as createLogger, o as initLogger, r as createRequestLogger, s as isEnabled, t as _log, u as shouldKeep } from "./logger-DY0X5oQd.mjs";
1
+ import { C as shouldKeep, S as lockLogger, _ as getEnvironment, b as isEnabled, g as createRequestLogger, h as createLogger, m as _log, v as getGlobalDrain, x as isLoggerLocked, y as initLogger } from "./audit-d9esRZOK.mjs";
2
2
  export { createLogger, createRequestLogger, getEnvironment, getGlobalDrain, initLogger, isEnabled, isLoggerLocked, lockLogger, _log as log, shouldKeep };
@@ -1,5 +1,4 @@
1
- import { filterSafeHeaders } from "./utils.mjs";
2
- import { a as getGlobalDrain, f as redactEvent, p as resolveRedactConfig, r as createRequestLogger, s as isEnabled, u as shouldKeep } from "./logger-DY0X5oQd.mjs";
1
+ import { C as shouldKeep, E as resolveRedactConfig, T as redactEvent, b as isEnabled, g as createRequestLogger, v as getGlobalDrain } from "./audit-d9esRZOK.mjs";
3
2
  import { t as extractErrorStatus } from "./errors-BJRXUfMg.mjs";
4
3
  import { n as shouldLog, t as getServiceForPath } from "./routes-CGPmbzCZ.mjs";
5
4
  //#region src/shared/middleware.ts
@@ -19,6 +18,12 @@ const noopResult = {
19
18
  finish: () => Promise.resolve(null),
20
19
  skipped: true
21
20
  };
21
+ /**
22
+ * Apply redact, enrich, and drain to an emitted wide event — same pipeline as
23
+ * {@link createMiddlewareLogger}'s `finish`.
24
+ *
25
+ * @beta Part of `evlog/toolkit` — used by framework integrations and `fork()`.
26
+ */
22
27
  async function runEnrichAndDrain(emittedEvent, options, requestInfo, responseStatus) {
23
28
  const resolvedRedact = resolveRedactConfig(options.redact);
24
29
  if (resolvedRedact) redactEvent(emittedEvent, resolvedRedact);
@@ -113,32 +118,6 @@ function createMiddlewareLogger(options) {
113
118
  };
114
119
  }
115
120
  //#endregion
116
- //#region src/shared/headers.ts
117
- /**
118
- * Extract headers from a Web API `Headers` object and filter out sensitive ones.
119
- * Works with any runtime that supports the standard `Headers` API (Hono, Elysia,
120
- * Nitro v3, Cloudflare Workers, Bun, Deno, etc.).
121
- */
122
- function extractSafeHeaders(headers) {
123
- const raw = {};
124
- headers.forEach((value, key) => {
125
- raw[key] = value;
126
- });
127
- return filterSafeHeaders(raw);
128
- }
129
- /**
130
- * Extract headers from Node.js `IncomingHttpHeaders` and filter out sensitive ones.
131
- * Works with Express, Fastify, and any Node.js HTTP server using `req.headers`.
132
- */
133
- function extractSafeNodeHeaders(headers) {
134
- const raw = {};
135
- for (const [key, value] of Object.entries(headers)) {
136
- if (value === void 0) continue;
137
- raw[key] = Array.isArray(value) ? value.join(", ") : value;
138
- }
139
- return filterSafeHeaders(raw);
140
- }
141
- //#endregion
142
- export { extractSafeNodeHeaders as n, createMiddlewareLogger as r, extractSafeHeaders as t };
121
+ export { runEnrichAndDrain as n, createMiddlewareLogger as t };
143
122
 
144
- //# sourceMappingURL=headers-ht4yS2mx.mjs.map
123
+ //# sourceMappingURL=middleware-BWOJ7JI0.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"middleware-BWOJ7JI0.mjs","names":[],"sources":["../src/shared/middleware.ts"],"sourcesContent":["import type { DrainContext, EnrichContext, RedactConfig, RequestLogger, RouteConfig, TailSamplingContext, WideEvent } from '../types'\nimport { createRequestLogger, getGlobalDrain, isEnabled, shouldKeep } from '../logger'\nimport { redactEvent, resolveRedactConfig } from '../redact'\nimport { extractErrorStatus } from './errors'\nimport { shouldLog, getServiceForPath } from './routes'\n\n/**\n * Base options shared by all framework integrations.\n *\n * Every framework-specific options interface (e.g. `EvlogExpressOptions`)\n * extends this type. If a framework needs extra fields it can add them\n * on top; otherwise the base is used as-is.\n *\n * @beta Part of `evlog/toolkit` — the public API for building custom integrations.\n */\nexport interface BaseEvlogOptions {\n /** Route patterns to include in logging (glob). If not set, all routes are logged */\n include?: string[]\n /** Route patterns to exclude from logging. Exclusions take precedence over inclusions */\n exclude?: string[]\n /** Route-specific service configuration */\n routes?: Record<string, RouteConfig>\n /**\n * Drain callback called with every emitted event.\n * Use with drain adapters (Axiom, OTLP, Sentry, etc.) or custom endpoints.\n */\n drain?: (ctx: DrainContext) => void | Promise<void>\n /**\n * Enrich callback called after emit, before drain.\n * Use to add derived context (geo, deployment info, user agent, etc.).\n */\n enrich?: (ctx: EnrichContext) => void | Promise<void>\n /**\n * Custom tail sampling callback.\n * Set `ctx.shouldKeep = true` to force-keep the log regardless of head sampling.\n */\n keep?: (ctx: TailSamplingContext) => void | Promise<void>\n /**\n * Auto-redaction configuration for PII protection.\n * `true` enables all built-in PII patterns. Pass an object for fine-grained control.\n * Applied before enrich/drain. Also applied at the core `emitWideEvent` level\n * when configured via `initLogger()`.\n */\n redact?: boolean | RedactConfig\n}\n\n/**\n * Internal options consumed by `createMiddlewareLogger`.\n * Extends `BaseEvlogOptions` with the request-specific fields\n * that framework adapters must provide.\n */\nexport interface MiddlewareLoggerOptions extends BaseEvlogOptions {\n method: string\n path: string\n requestId?: string\n /** Pre-filtered safe request headers (used for enrich/drain context) */\n headers?: Record<string, string>\n}\n\nexport interface MiddlewareLoggerResult {\n logger: RequestLogger\n finish: (opts?: { status?: number; error?: Error }) => Promise<WideEvent | null>\n skipped: boolean\n}\n\nconst noopResult: MiddlewareLoggerResult = {\n logger: {\n set() {},\n error() {},\n info() {},\n warn() {},\n emit() {\n return null \n },\n getContext() {\n return {} \n },\n },\n finish: () => Promise.resolve(null),\n skipped: true,\n}\n\n/**\n * Apply redact, enrich, and drain to an emitted wide event — same pipeline as\n * {@link createMiddlewareLogger}'s `finish`.\n *\n * @beta Part of `evlog/toolkit` — used by framework integrations and `fork()`.\n */\nexport async function runEnrichAndDrain(\n emittedEvent: WideEvent,\n options: MiddlewareLoggerOptions,\n requestInfo: { method: string; path: string; requestId?: string },\n responseStatus?: number,\n): Promise<void> {\n const resolvedRedact = resolveRedactConfig(options.redact)\n if (resolvedRedact) {\n redactEvent(emittedEvent, resolvedRedact)\n }\n\n if (options.enrich) {\n const enrichCtx: EnrichContext = {\n event: emittedEvent,\n request: requestInfo,\n headers: options.headers,\n response: { status: responseStatus },\n }\n try {\n await options.enrich(enrichCtx)\n } catch (err) {\n console.error('[evlog] enrich failed:', err)\n }\n }\n\n const drain = options.drain ?? getGlobalDrain()\n if (drain) {\n const drainCtx: DrainContext = {\n event: emittedEvent,\n request: requestInfo,\n headers: options.headers,\n }\n try {\n await drain(drainCtx)\n } catch (err) {\n console.error('[evlog] drain failed:', err)\n }\n }\n}\n\n/**\n * Create a middleware-aware request logger with full lifecycle management.\n *\n * Handles the complete pipeline shared across all framework integrations:\n * route filtering, logger creation, service overrides, duration tracking,\n * tail sampling evaluation, event emission, enrichment, and draining.\n *\n * Framework adapters only need to:\n * 1. Extract method/path/requestId/headers from the framework request\n * 2. Call `createMiddlewareLogger()` with those + user options\n * 3. Check `skipped` — if true, skip to next middleware\n * 4. Store `logger` in framework-specific context (e.g., `c.set('log', logger)`)\n * 5. Call `finish({ status })` or `finish({ error })` at response end\n *\n * @beta Part of `evlog/toolkit` — the public API for building custom integrations.\n */\nexport function createMiddlewareLogger(options: MiddlewareLoggerOptions): MiddlewareLoggerResult {\n if (!isEnabled()) return noopResult\n\n const { method, path, requestId, include, exclude, routes, keep } = options\n\n if (!shouldLog(path, include, exclude)) {\n return noopResult\n }\n\n const resolvedRequestId = requestId || crypto.randomUUID()\n\n const logger = createRequestLogger({\n method,\n path,\n requestId: resolvedRequestId,\n }, { _deferDrain: true })\n\n const routeService = getServiceForPath(path, routes)\n if (routeService) {\n logger.set({ service: routeService })\n }\n\n const startTime = Date.now()\n const requestInfo = { method, path, requestId: resolvedRequestId }\n\n const finish = async (opts?: { status?: number; error?: Error }): Promise<WideEvent | null> => {\n const { status, error } = opts ?? {}\n\n if (error) {\n logger.error(error)\n const errorStatus = extractErrorStatus(error)\n logger.set({ status: errorStatus })\n } else if (status !== undefined) {\n logger.set({ status })\n }\n\n const durationMs = Date.now() - startTime\n\n const resolvedStatus = error\n ? extractErrorStatus(error)\n : status ?? (logger.getContext().status as number | undefined)\n\n const tailCtx: TailSamplingContext = {\n status: resolvedStatus,\n duration: durationMs,\n path,\n method,\n context: logger.getContext(),\n shouldKeep: false,\n }\n\n if (keep) {\n await keep(tailCtx)\n }\n\n const forceKeep = tailCtx.shouldKeep || shouldKeep(tailCtx)\n const emittedEvent = logger.emit({ _forceKeep: forceKeep })\n\n if (emittedEvent && (options.enrich || options.drain || getGlobalDrain())) {\n await runEnrichAndDrain(emittedEvent, options, requestInfo, resolvedStatus)\n }\n\n return emittedEvent\n }\n\n return { logger, finish, skipped: false }\n}\n"],"mappings":";;;;AAiEA,MAAM,aAAqC;CACzC,QAAQ;EACN,MAAM;EACN,QAAQ;EACR,OAAO;EACP,OAAO;EACP,OAAO;AACL,UAAO;;EAET,aAAa;AACX,UAAO,EAAE;;EAEZ;CACD,cAAc,QAAQ,QAAQ,KAAK;CACnC,SAAS;CACV;;;;;;;AAQD,eAAsB,kBACpB,cACA,SACA,aACA,gBACe;CACf,MAAM,iBAAiB,oBAAoB,QAAQ,OAAO;AAC1D,KAAI,eACF,aAAY,cAAc,eAAe;AAG3C,KAAI,QAAQ,QAAQ;EAClB,MAAM,YAA2B;GAC/B,OAAO;GACP,SAAS;GACT,SAAS,QAAQ;GACjB,UAAU,EAAE,QAAQ,gBAAgB;GACrC;AACD,MAAI;AACF,SAAM,QAAQ,OAAO,UAAU;WACxB,KAAK;AACZ,WAAQ,MAAM,0BAA0B,IAAI;;;CAIhD,MAAM,QAAQ,QAAQ,SAAS,gBAAgB;AAC/C,KAAI,OAAO;EACT,MAAM,WAAyB;GAC7B,OAAO;GACP,SAAS;GACT,SAAS,QAAQ;GAClB;AACD,MAAI;AACF,SAAM,MAAM,SAAS;WACd,KAAK;AACZ,WAAQ,MAAM,yBAAyB,IAAI;;;;;;;;;;;;;;;;;;;;AAqBjD,SAAgB,uBAAuB,SAA0D;AAC/F,KAAI,CAAC,WAAW,CAAE,QAAO;CAEzB,MAAM,EAAE,QAAQ,MAAM,WAAW,SAAS,SAAS,QAAQ,SAAS;AAEpE,KAAI,CAAC,UAAU,MAAM,SAAS,QAAQ,CACpC,QAAO;CAGT,MAAM,oBAAoB,aAAa,OAAO,YAAY;CAE1D,MAAM,SAAS,oBAAoB;EACjC;EACA;EACA,WAAW;EACZ,EAAE,EAAE,aAAa,MAAM,CAAC;CAEzB,MAAM,eAAe,kBAAkB,MAAM,OAAO;AACpD,KAAI,aACF,QAAO,IAAI,EAAE,SAAS,cAAc,CAAC;CAGvC,MAAM,YAAY,KAAK,KAAK;CAC5B,MAAM,cAAc;EAAE;EAAQ;EAAM,WAAW;EAAmB;CAElE,MAAM,SAAS,OAAO,SAAyE;EAC7F,MAAM,EAAE,QAAQ,UAAU,QAAQ,EAAE;AAEpC,MAAI,OAAO;AACT,UAAO,MAAM,MAAM;GACnB,MAAM,cAAc,mBAAmB,MAAM;AAC7C,UAAO,IAAI,EAAE,QAAQ,aAAa,CAAC;aAC1B,WAAW,KAAA,EACpB,QAAO,IAAI,EAAE,QAAQ,CAAC;EAGxB,MAAM,aAAa,KAAK,KAAK,GAAG;EAEhC,MAAM,iBAAiB,QACnB,mBAAmB,MAAM,GACzB,UAAW,OAAO,YAAY,CAAC;EAEnC,MAAM,UAA+B;GACnC,QAAQ;GACR,UAAU;GACV;GACA;GACA,SAAS,OAAO,YAAY;GAC5B,YAAY;GACb;AAED,MAAI,KACF,OAAM,KAAK,QAAQ;EAGrB,MAAM,YAAY,QAAQ,cAAc,WAAW,QAAQ;EAC3D,MAAM,eAAe,OAAO,KAAK,EAAE,YAAY,WAAW,CAAC;AAE3D,MAAI,iBAAiB,QAAQ,UAAU,QAAQ,SAAS,gBAAgB,EACtE,OAAM,kBAAkB,cAAc,SAAS,aAAa,eAAe;AAG7E,SAAO;;AAGT,QAAO;EAAE;EAAQ;EAAQ,SAAS;EAAO"}
@@ -1,4 +1,4 @@
1
- import { E as WideEvent, _ as RequestLogger, h as RedactConfig, i as EnrichContext, r as DrainContext, w as TailSamplingContext, y as RouteConfig } from "./types-D5OwxZCw.mjs";
1
+ import { F as DrainContext, I as EnrichContext, Y as RequestLogger, Z as RouteConfig, it as WideEvent, nt as TailSamplingContext, q as RedactConfig } from "./audit-mUutdf6A.mjs";
2
2
 
3
3
  //#region src/shared/middleware.d.ts
4
4
  /**
@@ -60,6 +60,17 @@ interface MiddlewareLoggerResult {
60
60
  }) => Promise<WideEvent | null>;
61
61
  skipped: boolean;
62
62
  }
63
+ /**
64
+ * Apply redact, enrich, and drain to an emitted wide event — same pipeline as
65
+ * {@link createMiddlewareLogger}'s `finish`.
66
+ *
67
+ * @beta Part of `evlog/toolkit` — used by framework integrations and `fork()`.
68
+ */
69
+ declare function runEnrichAndDrain(emittedEvent: WideEvent, options: MiddlewareLoggerOptions, requestInfo: {
70
+ method: string;
71
+ path: string;
72
+ requestId?: string;
73
+ }, responseStatus?: number): Promise<void>;
63
74
  /**
64
75
  * Create a middleware-aware request logger with full lifecycle management.
65
76
  *
@@ -78,5 +89,5 @@ interface MiddlewareLoggerResult {
78
89
  */
79
90
  declare function createMiddlewareLogger(options: MiddlewareLoggerOptions): MiddlewareLoggerResult;
80
91
  //#endregion
81
- export { createMiddlewareLogger as i, MiddlewareLoggerOptions as n, MiddlewareLoggerResult as r, BaseEvlogOptions as t };
82
- //# sourceMappingURL=middleware-D_igVy93.d.mts.map
92
+ export { runEnrichAndDrain as a, createMiddlewareLogger as i, MiddlewareLoggerOptions as n, MiddlewareLoggerResult as r, BaseEvlogOptions as t };
93
+ //# sourceMappingURL=middleware-BYf26Lfu.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware-D_igVy93.d.mts","names":[],"sources":["../src/shared/middleware.ts"],"mappings":";;;;;AAeA;;;;;;;UAAiB,gBAAA;EAgByB;EAdxC,OAAA;EAmB4C;EAjB5C,OAAA;EAwB+B;EAtB/B,MAAA,GAAS,MAAA,SAAe,WAAA;EAJxB;;;;EASA,KAAA,IAAS,GAAA,EAAK,YAAA,YAAwB,OAAA;EAAtC;;;;EAKA,MAAA,IAAU,GAAA,EAAK,aAAA,YAAyB,OAAA;EAAzB;;;;EAKf,IAAA,IAAQ,GAAA,EAAK,mBAAA,YAA+B,OAAA;EAApC;;;;;;EAOR,MAAA,aAAmB,YAAA;AAAA;;;;;;UAQJ,uBAAA,SAAgC,gBAAA;EAC/C,MAAA;EACA,IAAA;EACA,SAAA;EAEgB;EAAhB,OAAA,GAAU,MAAA;AAAA;AAAA,UAGK,sBAAA;EACf,MAAA,EAAQ,aAAA;EACR,MAAA,GAAS,IAAA;IAAS,MAAA;IAAiB,KAAA,GAAQ,KAAA;EAAA,MAAY,OAAA,CAAQ,SAAA;EAC/D,OAAA;AAAA;;;;;;;;;;;;AA4EF;;;;;iBAAgB,sBAAA,CAAuB,OAAA,EAAS,uBAAA,GAA0B,sBAAA"}
1
+ {"version":3,"file":"middleware-BYf26Lfu.d.mts","names":[],"sources":["../src/shared/middleware.ts"],"mappings":";;;;;AAeA;;;;;;;UAAiB,gBAAA;EAgByB;EAdxC,OAAA;EAmB4C;EAjB5C,OAAA;EAwB+B;EAtB/B,MAAA,GAAS,MAAA,SAAe,WAAA;EAJxB;;;;EASA,KAAA,IAAS,GAAA,EAAK,YAAA,YAAwB,OAAA;EAAtC;;;;EAKA,MAAA,IAAU,GAAA,EAAK,aAAA,YAAyB,OAAA;EAAzB;;;;EAKf,IAAA,IAAQ,GAAA,EAAK,mBAAA,YAA+B,OAAA;EAApC;;;;;;EAOR,MAAA,aAAmB,YAAA;AAAA;;;;;;UAQJ,uBAAA,SAAgC,gBAAA;EAC/C,MAAA;EACA,IAAA;EACA,SAAA;EAEgB;EAAhB,OAAA,GAAU,MAAA;AAAA;AAAA,UAGK,sBAAA;EACf,MAAA,EAAQ,aAAA;EACR,MAAA,GAAS,IAAA;IAAS,MAAA;IAAiB,KAAA,GAAQ,KAAA;EAAA,MAAY,OAAA,CAAQ,SAAA;EAC/D,OAAA;AAAA;;;;;;;iBA0BoB,iBAAA,CACpB,YAAA,EAAc,SAAA,EACd,OAAA,EAAS,uBAAA,EACT,WAAA;EAAe,MAAA;EAAgB,IAAA;EAAc,SAAA;AAAA,GAC7C,cAAA,YACC,OAAA;AALH;;;;;;;;;;;;;;;;AAAA,iBAwDgB,sBAAA,CAAuB,OAAA,EAAS,uBAAA,GAA0B,sBAAA"}
@@ -1,5 +1,5 @@
1
- import { _ as RequestLogger } from "../types-D5OwxZCw.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-D_igVy93.mjs";
1
+ import { Y as RequestLogger } from "../audit-mUutdf6A.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-BYf26Lfu.mjs";
3
3
  import { DynamicModule, MiddlewareConsumer, NestModule } from "@nestjs/common";
4
4
 
5
5
  //#region src/nestjs/index.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/nestjs/index.ts"],"mappings":";;;;;cAQiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,kBAAA,GAAqB,gBAAA;AAAA,UAIhB,uBAAA;EANhB;EAQC,OAAA;EAVwB;EAYxB,UAAA,MAAgB,IAAA,YAAgB,kBAAA,GAAqB,OAAA,CAAQ,kBAAA;EAZrC;EAcxB,MAAA;AAAA;AAAA;EAAA,UAIU,eAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAAA;EAAA,UAKE,OAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAjBV;;;;;;;;;;;;;;;;;AAOC;;;;;;;AAPD,cA0Ea,WAAA,YAAuB,UAAA;EAAA,eAEnB,OAAA;EAjEM;AAAA;;;;;;;;;;EAAA,OA8Ed,OAAA,CAAQ,OAAA,GAAS,kBAAA,GAA0B,aAAA;EAf3B;;;;;;;;;;;;;;EAAA,OAqChB,YAAA,CAAa,YAAA,EAAc,uBAAA,GAA0B,aAAA;EAkB5D,SAAA,CAAU,QAAA,EAAU,kBAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/nestjs/index.ts"],"mappings":";;;;;cASiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;AAAA,KAId,kBAAA,GAAqB,gBAAA;AAAA,UAIhB,uBAAA;EANhB;EAQC,OAAA;EAVwB;EAYxB,UAAA,MAAgB,IAAA,YAAgB,kBAAA,GAAqB,OAAA,CAAQ,kBAAA;EAZrC;EAcxB,MAAA;AAAA;AAAA;EAAA,UAIU,eAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAAA;EAAA,UAKE,OAAA;IACR,GAAA,GAAM,aAAA;EAAA;AAAA;AAjBV;;;;;;;;;;;;;;;;;AAOC;;;;;;;AAPD,cA4Ea,WAAA,YAAuB,UAAA;EAAA,eAEnB,OAAA;EAnEM;AAAA;;;;;;;;;;EAAA,OAgFd,OAAA,CAAQ,OAAA,GAAS,kBAAA,GAA0B,aAAA;EAf3B;;;;;;;;;;;;;;EAAA,OAqChB,YAAA,CAAa,YAAA,EAAc,uBAAA,GAA0B,aAAA;EAkB5D,SAAA,CAAU,QAAA,EAAU,kBAAA;AAAA"}
@@ -1,5 +1,7 @@
1
- import { n as extractSafeNodeHeaders, r as createMiddlewareLogger } from "../headers-ht4yS2mx.mjs";
2
- import { t as createLoggerStorage } from "../storage-DpLJYMoc.mjs";
1
+ import { t as createMiddlewareLogger } from "../middleware-BWOJ7JI0.mjs";
2
+ import { t as attachForkToLogger } from "../fork-CTJXnpl8.mjs";
3
+ import { n as extractSafeNodeHeaders } from "../headers-D74M0wsg.mjs";
4
+ import { t as createLoggerStorage } from "../storage-CFGTn37X.mjs";
3
5
  //#region src/nestjs/index.ts
4
6
  const { storage, useLogger } = createLoggerStorage("middleware context. Make sure EvlogModule.forRoot() is imported in your AppModule.");
5
7
  function createEvlogMiddleware(getOptions) {
@@ -7,17 +9,19 @@ function createEvlogMiddleware(getOptions) {
7
9
  const options = getOptions();
8
10
  const headers = extractSafeNodeHeaders(req.headers);
9
11
  const url = new URL(req.originalUrl || req.url || "/", "http://localhost");
10
- const { logger, finish, skipped } = createMiddlewareLogger({
12
+ const middlewareOpts = {
11
13
  method: req.method || "GET",
12
14
  path: url.pathname,
13
15
  requestId: headers["x-request-id"] || crypto.randomUUID(),
14
16
  headers,
15
17
  ...options
16
- });
18
+ };
19
+ const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts);
17
20
  if (skipped) {
18
21
  next();
19
22
  return;
20
23
  }
24
+ attachForkToLogger(storage, logger, middlewareOpts);
21
25
  req.log = logger;
22
26
  res.on("finish", () => {
23
27
  finish({ status: res.statusCode }).catch(() => {});
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import type { ServerResponse } from 'node:http'\nimport type { Request } from 'express'\nimport type { DynamicModule, MiddlewareConsumer, NestModule } from '@nestjs/common'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure EvlogModule.forRoot() is imported in your AppModule.',\n)\n\nexport type EvlogNestJSOptions = BaseEvlogOptions\n\nexport { useLogger }\n\nexport interface EvlogModuleAsyncOptions {\n /** Modules to import (for dependency injection into the factory) */\n imports?: any[]\n /** Factory function that returns evlog options. Can be async. */\n useFactory: (...args: any[]) => EvlogNestJSOptions | Promise<EvlogNestJSOptions>\n /** Injection tokens to resolve and pass to the factory */\n inject?: any[]\n}\n\ndeclare module 'http' {\n interface IncomingMessage {\n log?: RequestLogger\n }\n}\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log?: RequestLogger\n }\n}\n\nfunction createEvlogMiddleware(getOptions: () => EvlogNestJSOptions) {\n return (req: Request, res: ServerResponse, next: () => void) => {\n const options = getOptions()\n const headers = extractSafeNodeHeaders(req.headers)\n const url = new URL(req.originalUrl || req.url || '/', 'http://localhost')\n\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: req.method || 'GET',\n path: url.pathname,\n requestId: headers['x-request-id'] || crypto.randomUUID(),\n headers,\n ...options,\n })\n\n if (skipped) {\n next()\n return\n }\n\n req.log = logger\n\n res.on('finish', () => {\n finish({ status: res.statusCode }).catch(() => {})\n })\n\n storage.run(logger, () => next())\n }\n}\n\n/**\n * NestJS module for evlog wide event logging.\n *\n * Registers a global middleware that creates a request-scoped logger\n * for every incoming request. Use `useLogger()` to access it anywhere\n * in the call stack, or `req.log` directly in controllers.\n *\n * @example\n * ```ts\n * import { Module } from '@nestjs/common'\n * import { EvlogModule } from 'evlog/nestjs'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * @Module({\n * imports: [\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * exclude: ['/health'],\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\nexport class EvlogModule implements NestModule {\n\n private static options: EvlogNestJSOptions = {}\n\n /**\n * Register evlog with static configuration.\n *\n * @example\n * ```ts\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },\n * })\n * ```\n */\n static forRoot(options: EvlogNestJSOptions = {}): DynamicModule {\n EvlogModule.options = options\n return {\n module: EvlogModule,\n global: true,\n }\n }\n\n /**\n * Register evlog with async configuration (e.g. from `ConfigService`).\n *\n * @example\n * ```ts\n * EvlogModule.forRootAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),\n * }),\n * })\n * ```\n */\n static forRootAsync(asyncOptions: EvlogModuleAsyncOptions): DynamicModule {\n return {\n module: EvlogModule,\n imports: asyncOptions.imports || [],\n providers: [\n {\n provide: 'EVLOG_OPTIONS',\n useFactory: async (...args: any[]) => {\n EvlogModule.options = await asyncOptions.useFactory(...args)\n return EvlogModule.options\n },\n inject: asyncOptions.inject || [],\n },\n ],\n global: true,\n }\n }\n\n configure(consumer: MiddlewareConsumer): void {\n consumer\n .apply(createEvlogMiddleware(() => EvlogModule.options))\n .forRoutes('*')\n }\n\n}\n"],"mappings":";;;AAQA,MAAM,EAAE,SAAS,cAAc,oBAC7B,qFACD;AA2BD,SAAS,sBAAsB,YAAsC;AACnE,SAAQ,KAAc,KAAqB,SAAqB;EAC9D,MAAM,UAAU,YAAY;EAC5B,MAAM,UAAU,uBAAuB,IAAI,QAAQ;EACnD,MAAM,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,KAAK,mBAAmB;EAE1E,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,IAAI,UAAU;GACtB,MAAM,IAAI;GACV,WAAW,QAAQ,mBAAmB,OAAO,YAAY;GACzD;GACA,GAAG;GACJ,CAAC;AAEF,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,MAAI,MAAM;AAEV,MAAI,GAAG,gBAAgB;AACrB,UAAO,EAAE,QAAQ,IAAI,YAAY,CAAC,CAAC,YAAY,GAAG;IAClD;AAEF,UAAQ,IAAI,cAAc,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BrC,IAAa,cAAb,MAAa,YAAkC;CAE7C,OAAe,UAA8B,EAAE;;;;;;;;;;;;CAa/C,OAAO,QAAQ,UAA8B,EAAE,EAAiB;AAC9D,cAAY,UAAU;AACtB,SAAO;GACL,QAAQ;GACR,QAAQ;GACT;;;;;;;;;;;;;;;;CAiBH,OAAO,aAAa,cAAsD;AACxE,SAAO;GACL,QAAQ;GACR,SAAS,aAAa,WAAW,EAAE;GACnC,WAAW,CACT;IACE,SAAS;IACT,YAAY,OAAO,GAAG,SAAgB;AACpC,iBAAY,UAAU,MAAM,aAAa,WAAW,GAAG,KAAK;AAC5D,YAAO,YAAY;;IAErB,QAAQ,aAAa,UAAU,EAAE;IAClC,CACF;GACD,QAAQ;GACT;;CAGH,UAAU,UAAoC;AAC5C,WACG,MAAM,4BAA4B,YAAY,QAAQ,CAAC,CACvD,UAAU,IAAI"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/nestjs/index.ts"],"sourcesContent":["import type { ServerResponse } from 'node:http'\nimport type { Request } from 'express'\nimport type { DynamicModule, MiddlewareConsumer, NestModule } from '@nestjs/common'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { attachForkToLogger } from '../shared/fork'\nimport { extractSafeNodeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure EvlogModule.forRoot() is imported in your AppModule.',\n)\n\nexport type EvlogNestJSOptions = BaseEvlogOptions\n\nexport { useLogger }\n\nexport interface EvlogModuleAsyncOptions {\n /** Modules to import (for dependency injection into the factory) */\n imports?: any[]\n /** Factory function that returns evlog options. Can be async. */\n useFactory: (...args: any[]) => EvlogNestJSOptions | Promise<EvlogNestJSOptions>\n /** Injection tokens to resolve and pass to the factory */\n inject?: any[]\n}\n\ndeclare module 'http' {\n interface IncomingMessage {\n log?: RequestLogger\n }\n}\n\ndeclare module 'express-serve-static-core' {\n interface Request {\n log?: RequestLogger\n }\n}\n\nfunction createEvlogMiddleware(getOptions: () => EvlogNestJSOptions) {\n return (req: Request, res: ServerResponse, next: () => void) => {\n const options = getOptions()\n const headers = extractSafeNodeHeaders(req.headers)\n const url = new URL(req.originalUrl || req.url || '/', 'http://localhost')\n\n const middlewareOpts = {\n method: req.method || 'GET',\n path: url.pathname,\n requestId: headers['x-request-id'] || crypto.randomUUID(),\n headers,\n ...options,\n }\n const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts)\n\n if (skipped) {\n next()\n return\n }\n\n attachForkToLogger(storage, logger, middlewareOpts)\n req.log = logger\n\n res.on('finish', () => {\n finish({ status: res.statusCode }).catch(() => {})\n })\n\n storage.run(logger, () => next())\n }\n}\n\n/**\n * NestJS module for evlog wide event logging.\n *\n * Registers a global middleware that creates a request-scoped logger\n * for every incoming request. Use `useLogger()` to access it anywhere\n * in the call stack, or `req.log` directly in controllers.\n *\n * @example\n * ```ts\n * import { Module } from '@nestjs/common'\n * import { EvlogModule } from 'evlog/nestjs'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * @Module({\n * imports: [\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * exclude: ['/health'],\n * }),\n * ],\n * })\n * export class AppModule {}\n * ```\n */\nexport class EvlogModule implements NestModule {\n\n private static options: EvlogNestJSOptions = {}\n\n /**\n * Register evlog with static configuration.\n *\n * @example\n * ```ts\n * EvlogModule.forRoot({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => { ctx.event.region = process.env.FLY_REGION },\n * })\n * ```\n */\n static forRoot(options: EvlogNestJSOptions = {}): DynamicModule {\n EvlogModule.options = options\n return {\n module: EvlogModule,\n global: true,\n }\n }\n\n /**\n * Register evlog with async configuration (e.g. from `ConfigService`).\n *\n * @example\n * ```ts\n * EvlogModule.forRootAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (config: ConfigService) => ({\n * drain: createAxiomDrain({ token: config.get('AXIOM_TOKEN') }),\n * }),\n * })\n * ```\n */\n static forRootAsync(asyncOptions: EvlogModuleAsyncOptions): DynamicModule {\n return {\n module: EvlogModule,\n imports: asyncOptions.imports || [],\n providers: [\n {\n provide: 'EVLOG_OPTIONS',\n useFactory: async (...args: any[]) => {\n EvlogModule.options = await asyncOptions.useFactory(...args)\n return EvlogModule.options\n },\n inject: asyncOptions.inject || [],\n },\n ],\n global: true,\n }\n }\n\n configure(consumer: MiddlewareConsumer): void {\n consumer\n .apply(createEvlogMiddleware(() => EvlogModule.options))\n .forRoutes('*')\n }\n\n}\n"],"mappings":";;;;;AASA,MAAM,EAAE,SAAS,cAAc,oBAC7B,qFACD;AA2BD,SAAS,sBAAsB,YAAsC;AACnE,SAAQ,KAAc,KAAqB,SAAqB;EAC9D,MAAM,UAAU,YAAY;EAC5B,MAAM,UAAU,uBAAuB,IAAI,QAAQ;EACnD,MAAM,MAAM,IAAI,IAAI,IAAI,eAAe,IAAI,OAAO,KAAK,mBAAmB;EAE1E,MAAM,iBAAiB;GACrB,QAAQ,IAAI,UAAU;GACtB,MAAM,IAAI;GACV,WAAW,QAAQ,mBAAmB,OAAO,YAAY;GACzD;GACA,GAAG;GACJ;EACD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB,eAAe;AAE1E,MAAI,SAAS;AACX,SAAM;AACN;;AAGF,qBAAmB,SAAS,QAAQ,eAAe;AACnD,MAAI,MAAM;AAEV,MAAI,GAAG,gBAAgB;AACrB,UAAO,EAAE,QAAQ,IAAI,YAAY,CAAC,CAAC,YAAY,GAAG;IAClD;AAEF,UAAQ,IAAI,cAAc,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BrC,IAAa,cAAb,MAAa,YAAkC;CAE7C,OAAe,UAA8B,EAAE;;;;;;;;;;;;CAa/C,OAAO,QAAQ,UAA8B,EAAE,EAAiB;AAC9D,cAAY,UAAU;AACtB,SAAO;GACL,QAAQ;GACR,QAAQ;GACT;;;;;;;;;;;;;;;;CAiBH,OAAO,aAAa,cAAsD;AACxE,SAAO;GACL,QAAQ;GACR,SAAS,aAAa,WAAW,EAAE;GACnC,WAAW,CACT;IACE,SAAS;IACT,YAAY,OAAO,GAAG,SAAgB;AACpC,iBAAY,UAAU,MAAM,aAAa,WAAW,GAAG,KAAK;AAC5D,YAAO,YAAY;;IAErB,QAAQ,aAAa,UAAU,EAAE;IAClC,CACF;GACD,QAAQ;GACT;;CAGH,UAAU,UAAoC;AAC5C,WACG,MAAM,4BAA4B,YAAY,QAAQ,CAAC,CACvD,UAAU,IAAI"}
@@ -1,4 +1,4 @@
1
- import { T as TransportConfig, f as LogLevel } from "../types-D5OwxZCw.mjs";
1
+ import { W as LogLevel, rt as TransportConfig } from "../audit-mUutdf6A.mjs";
2
2
  import { clearIdentity, log as _clientLog, setIdentity, setMinLevel } from "../runtime/client/log.mjs";
3
3
  import * as _$react from "react";
4
4
 
@@ -1,7 +1,7 @@
1
- import { _ as RequestLogger, a as EnvironmentContext, b as SamplingConfig, d as Log, f as LogLevel } from "../types-D5OwxZCw.mjs";
2
- import { n as createError } from "../error-WRz4_F3W.mjs";
3
- import { t as _log } from "../logger-Bm0k3Hf3.mjs";
4
- import { t as BaseEvlogOptions } from "../middleware-D_igVy93.mjs";
1
+ import { L as EnvironmentContext, Q as SamplingConfig, U as Log, W as LogLevel, Y as RequestLogger } from "../audit-mUutdf6A.mjs";
2
+ import { n as createError } from "../error-D1FZI2Kd.mjs";
3
+ import { t as _log } from "../logger-b3epPH0N.mjs";
4
+ import { t as BaseEvlogOptions } from "../middleware-BYf26Lfu.mjs";
5
5
  import { AsyncLocalStorage } from "node:async_hooks";
6
6
 
7
7
  //#region src/next/types.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/types.ts","../../src/next/storage.ts","../../src/next/middleware.ts","../../src/next/index.ts"],"mappings":";;;;;;;UAGiB,gBAAA,SAAyB,gBAAA;;;;;EAKxC,OAAA;EALe;;;EAUf,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAAR;;;;EAMN,MAAA;EAhBwD;;;;EAsBxD,OAAA;EAZc;;;EAiBd,QAAA,GAAW,cAAA;EAAA;;;;EAMX,QAAA,GAAW,QAAA;EAaL;;AAGR;;EAVE,SAAA;EAeA;;;;;EARA,MAAA;AAAA;AAAA,UAGe,qBAAA;EChC4B;;;;EDqC3C,OAAA;ECrCwB;;;;ED2CxB,OAAA;AAAA;;;;;;;;AA5DF;;;;;;;;;;iBCiBgB,SAAA,oBAA6B,MAAA,kBAAA,CAAA,GAA4B,aAAA,CAAc,CAAA;;;KCjBlF,WAAA;EACH,OAAA;IAAW,QAAA;EAAA;EACX,OAAA;IAAW,GAAA,CAAI,IAAA;EAAA;AAAA;AAAA,KAGZ,YAAA;EACH,OAAA;IAAW,GAAA,CAAI,IAAA,UAAc,KAAA;EAAA;AAAA;;;;;;;;;;;;;;iBAoBf,eAAA,CAAgB,MAAA,GAAS,qBAAA,IACzB,OAAA,EAAS,WAAA,KAAW,OAAA,CAAA,YAAA;;;AF3BpC;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA;;;;AAjDA,iBGuCgB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAWuwE,IAAA,EAAA,KAAA,KAAA,OAAA,SAAkC,IAAA,EAAA,KAAA,KAAA,OAAA,CAAA,OAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/next/types.ts","../../src/next/storage.ts","../../src/next/middleware.ts","../../src/next/index.ts"],"mappings":";;;;;;;UAGiB,gBAAA,SAAyB,gBAAA;;;;;EAKxC,OAAA;EALe;;;EAUf,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAAR;;;;EAMN,MAAA;EAhBwD;;;;EAsBxD,OAAA;EAZc;;;EAiBd,QAAA,GAAW,cAAA;EAAA;;;;EAMX,QAAA,GAAW,QAAA;EAaL;;AAGR;;EAVE,SAAA;EAeA;;;;;EARA,MAAA;AAAA;AAAA,UAGe,qBAAA;EChC4B;;;;EDqC3C,OAAA;ECrCwB;;;;ED2CxB,OAAA;AAAA;;;;;;;;AA5DF;;;;;;;;;;iBCiBgB,SAAA,oBAA6B,MAAA,kBAAA,CAAA,GAA4B,aAAA,CAAc,CAAA;;;KCjBlF,WAAA;EACH,OAAA;IAAW,QAAA;EAAA;EACX,OAAA;IAAW,GAAA,CAAI,IAAA;EAAA;AAAA;AAAA,KAGZ,YAAA;EACH,OAAA;IAAW,GAAA,CAAI,IAAA,UAAc,KAAA;EAAA;AAAA;;;;;;;;;;;;;;iBAoBf,eAAA,CAAgB,MAAA,GAAS,qBAAA,IACzB,OAAA,EAAS,WAAA,KAAW,OAAA,CAAA,YAAA;;;AF3BpC;;;;;;;;;;;;;;;;;;;;;;;;;AAiDA;;;;AAjDA,iBGuCgB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAW+3E,IAAA,EAAA,KAAA,KAAA,OAAA,SAAkC,IAAA,EAAA,KAAA,KAAA,OAAA,CAAA,OAAA,CAAA,OAAA"}