evlog 2.10.0 → 2.11.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 (122) hide show
  1. package/README.md +27 -1
  2. package/dist/{_drain-CJDuM0ua.mjs → _drain-YH8ERc5l.mjs} +1 -1
  3. package/dist/{_drain-CJDuM0ua.mjs.map → _drain-YH8ERc5l.mjs.map} +1 -1
  4. package/dist/{_http-rRIz2Q0L.mjs → _http-C_2wbJw3.mjs} +7 -21
  5. package/dist/_http-C_2wbJw3.mjs.map +1 -0
  6. package/dist/{_severity-BLiOKoxh.mjs → _severity-BZhz3f9e.mjs} +1 -1
  7. package/dist/{_severity-BLiOKoxh.mjs.map → _severity-BZhz3f9e.mjs.map} +1 -1
  8. package/dist/adapters/axiom.d.mts +1 -1
  9. package/dist/adapters/axiom.d.mts.map +1 -1
  10. package/dist/adapters/axiom.mjs +2 -2
  11. package/dist/adapters/better-stack.d.mts +1 -1
  12. package/dist/adapters/better-stack.d.mts.map +1 -1
  13. package/dist/adapters/better-stack.mjs +2 -2
  14. package/dist/adapters/datadog.d.mts +86 -0
  15. package/dist/adapters/datadog.d.mts.map +1 -0
  16. package/dist/adapters/datadog.mjs +172 -0
  17. package/dist/adapters/datadog.mjs.map +1 -0
  18. package/dist/adapters/fs.d.mts +1 -1
  19. package/dist/adapters/fs.d.mts.map +1 -1
  20. package/dist/adapters/fs.mjs +1 -1
  21. package/dist/adapters/hyperdx.d.mts +1 -1
  22. package/dist/adapters/hyperdx.d.mts.map +1 -1
  23. package/dist/adapters/hyperdx.mjs +2 -2
  24. package/dist/adapters/otlp.d.mts +1 -1
  25. package/dist/adapters/otlp.d.mts.map +1 -1
  26. package/dist/adapters/otlp.mjs +3 -3
  27. package/dist/adapters/posthog.d.mts +1 -1
  28. package/dist/adapters/posthog.d.mts.map +1 -1
  29. package/dist/adapters/posthog.mjs +2 -2
  30. package/dist/adapters/sentry.d.mts +1 -1
  31. package/dist/adapters/sentry.d.mts.map +1 -1
  32. package/dist/adapters/sentry.mjs +3 -3
  33. package/dist/ai/index.d.mts +1 -1
  34. package/dist/browser.d.mts +1 -1
  35. package/dist/{dist-BsWcv7B8.mjs → dist-BFn8qsRC.mjs} +1 -1
  36. package/dist/{dist-BsWcv7B8.mjs.map → dist-BFn8qsRC.mjs.map} +1 -1
  37. package/dist/elysia/index.d.mts +2 -2
  38. package/dist/elysia/index.mjs +1 -1
  39. package/dist/enrichers.d.mts +1 -1
  40. package/dist/{error-BJ-I4sim.d.mts → error-plrBYLQk.d.mts} +7 -2
  41. package/dist/error-plrBYLQk.d.mts.map +1 -0
  42. package/dist/error.d.mts +1 -1
  43. package/dist/error.mjs +15 -0
  44. package/dist/error.mjs.map +1 -1
  45. package/dist/{errors-DBIBK0Bt.d.mts → errors-bPoj9UZk.d.mts} +2 -2
  46. package/dist/{errors-DBIBK0Bt.d.mts.map → errors-bPoj9UZk.d.mts.map} +1 -1
  47. package/dist/express/index.d.mts +2 -2
  48. package/dist/express/index.mjs +2 -2
  49. package/dist/fastify/index.d.mts +2 -2
  50. package/dist/fastify/index.d.mts.map +1 -1
  51. package/dist/fastify/index.mjs +2 -2
  52. package/dist/{headers-DrdQ6uG5.mjs → headers-BSi3UHKL.mjs} +1 -1
  53. package/dist/{headers-DrdQ6uG5.mjs.map → headers-BSi3UHKL.mjs.map} +1 -1
  54. package/dist/hono/index.d.mts +2 -2
  55. package/dist/hono/index.mjs +1 -1
  56. package/dist/index.d.mts +5 -5
  57. package/dist/{logger-DU3aQIUk.d.mts → logger-CG1eop2_.d.mts} +2 -2
  58. package/dist/{logger-DU3aQIUk.d.mts.map → logger-CG1eop2_.d.mts.map} +1 -1
  59. package/dist/logger.d.mts +1 -1
  60. package/dist/logger.mjs +2 -1
  61. package/dist/logger.mjs.map +1 -1
  62. package/dist/{middleware-BjERCCEd.d.mts → middleware-DojmTj9Y.d.mts} +2 -2
  63. package/dist/{middleware-BjERCCEd.d.mts.map → middleware-DojmTj9Y.d.mts.map} +1 -1
  64. package/dist/nestjs/index.d.mts +2 -2
  65. package/dist/nestjs/index.mjs +2 -2
  66. package/dist/next/client.d.mts +3 -3
  67. package/dist/next/client.d.mts.map +1 -1
  68. package/dist/next/index.d.mts +4 -4
  69. package/dist/next/index.d.mts.map +1 -1
  70. package/dist/next/instrumentation.d.mts +1 -1
  71. package/dist/nitro/errorHandler.d.mts +2 -2
  72. package/dist/nitro/module.d.mts +2 -2
  73. package/dist/nitro/plugin.d.mts +2 -2
  74. package/dist/nitro/plugin.mjs +2 -6
  75. package/dist/nitro/plugin.mjs.map +1 -1
  76. package/dist/nitro/v3/errorHandler.d.mts +2 -2
  77. package/dist/nitro/v3/errorHandler.mjs +1 -1
  78. package/dist/nitro/v3/index.d.mts +3 -1
  79. package/dist/nitro/v3/index.mjs +3 -1
  80. package/dist/nitro/v3/middleware.d.mts +11 -3
  81. package/dist/nitro/v3/middleware.d.mts.map +1 -1
  82. package/dist/nitro/v3/middleware.mjs +1 -21
  83. package/dist/nitro/v3/middleware.mjs.map +1 -1
  84. package/dist/nitro/v3/module.d.mts +1 -1
  85. package/dist/nitro/v3/plugin.d.mts +2 -2
  86. package/dist/nitro/v3/plugin.mjs +4 -4
  87. package/dist/nitro/v3/plugin.mjs.map +1 -1
  88. package/dist/nitro/v3/useLogger.d.mts +1 -1
  89. package/dist/{nitro-BXmkH7BD.d.mts → nitro-CfGx0wDJ.d.mts} +2 -3
  90. package/dist/nitro-CfGx0wDJ.d.mts.map +1 -0
  91. package/dist/nitroConfigBridge-fidbf-Y_.mjs +92 -0
  92. package/dist/nitroConfigBridge-fidbf-Y_.mjs.map +1 -0
  93. package/dist/nuxt/module.d.mts +3 -3
  94. package/dist/nuxt/module.mjs +1 -1
  95. package/dist/{parseError-CcvBYsbl.d.mts → parseError-B_qXj8x4.d.mts} +2 -2
  96. package/dist/parseError-B_qXj8x4.d.mts.map +1 -0
  97. package/dist/react-router/index.d.mts +4 -4
  98. package/dist/react-router/index.d.mts.map +1 -1
  99. package/dist/react-router/index.mjs +2 -2
  100. package/dist/runtime/client/log.d.mts +1 -1
  101. package/dist/runtime/server/routes/_evlog/ingest.post.d.mts +2 -2
  102. package/dist/runtime/server/useLogger.d.mts +1 -1
  103. package/dist/runtime/utils/parseError.d.mts +2 -2
  104. package/dist/{storage-DsueXspk.mjs → storage-B6NPh8rV.mjs} +1 -1
  105. package/dist/{storage-DsueXspk.mjs.map → storage-B6NPh8rV.mjs.map} +1 -1
  106. package/dist/sveltekit/index.d.mts +2 -2
  107. package/dist/sveltekit/index.mjs +2 -2
  108. package/dist/toolkit.d.mts +3 -3
  109. package/dist/toolkit.mjs +2 -2
  110. package/dist/{types-DbVDS9eu.d.mts → types-v_JkG_D7.d.mts} +6 -1
  111. package/dist/{types-DbVDS9eu.d.mts.map → types-v_JkG_D7.d.mts.map} +1 -1
  112. package/dist/types.d.mts +1 -1
  113. package/dist/{useLogger-DY9IByDJ.d.mts → useLogger-TjKH37BO.d.mts} +2 -2
  114. package/dist/{useLogger-DY9IByDJ.d.mts.map → useLogger-TjKH37BO.d.mts.map} +1 -1
  115. package/dist/utils.d.mts +1 -1
  116. package/dist/vite/index.d.mts +1 -1
  117. package/dist/workers.d.mts +1 -1
  118. package/package.json +21 -7
  119. package/dist/_http-rRIz2Q0L.mjs.map +0 -1
  120. package/dist/error-BJ-I4sim.d.mts.map +0 -1
  121. package/dist/nitro-BXmkH7BD.d.mts.map +0 -1
  122. package/dist/parseError-CcvBYsbl.d.mts.map +0 -1
@@ -1,6 +1,6 @@
1
- import { w as TransportConfig } from "../types-DbVDS9eu.mjs";
1
+ import { w as TransportConfig } from "../types-v_JkG_D7.mjs";
2
2
  import { clearIdentity, log as _clientLog, setIdentity } from "../runtime/client/log.mjs";
3
- import * as react from "react";
3
+ import * as _$react from "react";
4
4
 
5
5
  //#region src/next/client.d.ts
6
6
  interface EvlogProviderProps {
@@ -57,7 +57,7 @@ declare function EvlogProvider({
57
57
  enabled,
58
58
  console: consoleOutput,
59
59
  children
60
- }: EvlogProviderProps): react.ReactNode;
60
+ }: EvlogProviderProps): _$react.ReactNode;
61
61
  //#endregion
62
62
  export { EvlogProvider, EvlogProviderProps, clearIdentity, _clientLog as log, setIdentity };
63
63
  //# sourceMappingURL=client.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.mts","names":[],"sources":["../../src/next/client.ts"],"mappings":";;;;;UAQiB,kBAAA;;;AAAjB;;EAKE,OAAA;EA2ByB;;;;EArBzB,MAAA;EAWA;;;EANA,SAAA,GAAY,eAAA;EAgBI;;;AAsBlB;EAhCE,OAAA;;;;;;;EAQA,OAAA;EAEA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAsBF,aAAA,CAAA;EAAgB,OAAA;EAAS,MAAA;EAAQ,SAAA;EAAW,OAAA;EAAS,OAAA,EAAS,aAAA;EAAe;AAAA,GAAY,kBAAA,GAAkB,KAAA,CAAA,SAAA"}
1
+ {"version":3,"file":"client.d.mts","names":[],"sources":["../../src/next/client.ts"],"mappings":";;;;;UAQiB,kBAAA;;;AAAjB;;EAKE,OAAA;EA2ByB;;;;EArBzB,MAAA;EAWA;;;EANA,SAAA,GAAY,eAAA;EAgBI;;;AAsBlB;EAhCE,OAAA;;;;;;;EAQA,OAAA;EAEA,QAAA,EAAU,KAAA,CAAM,SAAA;AAAA;;;;;;;;;;;;;;;;;;;iBAsBF,aAAA,CAAA;EAAgB,OAAA;EAAS,MAAA;EAAQ,SAAA;EAAW,OAAA;EAAS,OAAA,EAAS,aAAA;EAAe;AAAA,GAAY,kBAAA,GAAkB,OAAA,CAAA,SAAA"}
@@ -1,7 +1,7 @@
1
- import { a as EnvironmentContext, d as Log, g as RequestLogger, y as SamplingConfig } from "../types-DbVDS9eu.mjs";
2
- import { n as createError } from "../error-BJ-I4sim.mjs";
3
- import { t as _log } from "../logger-DU3aQIUk.mjs";
4
- import { t as BaseEvlogOptions } from "../middleware-BjERCCEd.mjs";
1
+ import { a as EnvironmentContext, d as Log, g as RequestLogger, y as SamplingConfig } from "../types-v_JkG_D7.mjs";
2
+ import { n as createError } from "../error-plrBYLQk.mjs";
3
+ import { t as _log } from "../logger-CG1eop2_.mjs";
4
+ import { t as BaseEvlogOptions } from "../middleware-DojmTj9Y.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;;;AALF;EAUE,GAAA,GAAM,OAAA,CAAQ,kBAAA;;;;;EAMd,MAAA;EAhBwD;;;;EAsBxD,OAAA;EAZM;;;EAiBN,QAAA,GAAW,cAAA;EAAX;;;;EAMA,SAAA;EAOM;AAGR;;;;EAHE,MAAA;AAAA;AAAA,UAGe,qBAAA;;AC1BjB;;;ED+BE,OAAA;EC/BqF;;;;EDqCrF,OAAA;AAAA;;;;;;;;;;AAtDF;;;;;;;;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;;;;;;;;;;;;;;;;;;;;;;AA2CA;;;;;iBGJgB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAWuuE,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;EAhBwC;;;;EAsBxC,OAAA;EANA;;;EAWA,QAAA,GAAW,cAAA;EAMX;;;;EAAA,SAAA;EAUoC;;;;;EAHpC,MAAA;AAAA;AAAA,UAGe,qBAAA;EC1BQ;;;;ED+BvB,OAAA;EC/BoF;;;;EDqCpF,OAAA;AAAA;;;;;;;;AAtDF;;;;;;;;;;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;;;;;;;;;;;;;;;;;;;;;;AA2CA;;;;;;;AA3CA,iBGuCgB,WAAA,CAAY,OAAA,GAAS,gBAAA;6DAWuuE,IAAA,EAAA,KAAA,KAAA,OAAA,SAAkC,IAAA,EAAA,KAAA,KAAA,OAAA,CAAA,OAAA,CAAA,OAAA"}
@@ -1,4 +1,4 @@
1
- import { a as EnvironmentContext, r as DrainContext, y as SamplingConfig } from "../types-DbVDS9eu.mjs";
1
+ import { a as EnvironmentContext, r as DrainContext, y as SamplingConfig } from "../types-v_JkG_D7.mjs";
2
2
 
3
3
  //#region src/next/instrumentation.d.ts
4
4
  /** Request payload passed to Next.js `onRequestError` (App Router). */
@@ -1,4 +1,4 @@
1
- import * as nitropack from "nitropack";
1
+ import * as _$nitropack from "nitropack";
2
2
 
3
3
  //#region src/nitro/errorHandler.d.ts
4
4
  /**
@@ -9,7 +9,7 @@ import * as nitropack from "nitropack";
9
9
  * For non-EvlogError, it preserves Nitro's default response shape while
10
10
  * sanitizing internal error details in production for 5xx errors.
11
11
  */
12
- declare const _default: nitropack.NitroErrorHandler;
12
+ declare const _default: _$nitropack.NitroErrorHandler;
13
13
  //#endregion
14
14
  export { _default as default };
15
15
  //# sourceMappingURL=errorHandler.d.mts.map
@@ -1,5 +1,5 @@
1
- import { t as useLogger } from "../useLogger-DY9IByDJ.mjs";
2
- import { t as NitroModuleOptions } from "../nitro-BXmkH7BD.mjs";
1
+ import { t as useLogger } from "../useLogger-TjKH37BO.mjs";
2
+ import { t as NitroModuleOptions } from "../nitro-CfGx0wDJ.mjs";
3
3
  import { Nitro } from "nitropack";
4
4
 
5
5
  //#region src/nitro/module.d.ts
@@ -1,7 +1,7 @@
1
- import * as nitropack from "nitropack";
1
+ import * as _$nitropack from "nitropack";
2
2
 
3
3
  //#region src/nitro/plugin.d.ts
4
- declare const _default: nitropack.NitroAppPlugin;
4
+ declare const _default: _$nitropack.NitroAppPlugin;
5
5
  //#endregion
6
6
  export { _default as default };
7
7
  //# sourceMappingURL=plugin.d.mts.map
@@ -2,6 +2,7 @@ import { filterSafeHeaders } from "../utils.mjs";
2
2
  import { createRequestLogger, initLogger, isEnabled } from "../logger.mjs";
3
3
  import { t as extractErrorStatus } from "../errors-gH4C9KSC.mjs";
4
4
  import { n as shouldLog, t as getServiceForPath } from "../routes-CE3_c-iZ.mjs";
5
+ import { n as resolveEvlogConfigForNitroPlugin } from "../nitroConfigBridge-fidbf-Y_.mjs";
5
6
  import { defineNitroPlugin } from "nitropack/runtime/internal/plugin";
6
7
  import { getHeaders } from "h3";
7
8
  //#region src/nitro/plugin.ts
@@ -64,12 +65,7 @@ async function callEnrichAndDrain(nitroApp, emittedEvent, event) {
64
65
  else await drainPromise;
65
66
  }
66
67
  var plugin_default = defineNitroPlugin(async (nitroApp) => {
67
- let evlogConfig;
68
- if (process.env.__EVLOG_CONFIG) evlogConfig = JSON.parse(process.env.__EVLOG_CONFIG);
69
- else try {
70
- const { useRuntimeConfig } = await import("nitropack/runtime/internal/config");
71
- evlogConfig = useRuntimeConfig().evlog;
72
- } catch {}
68
+ const evlogConfig = await resolveEvlogConfigForNitroPlugin();
73
69
  initLogger({
74
70
  enabled: evlogConfig?.enabled,
75
71
  env: evlogConfig?.env,
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","names":[],"sources":["../../src/nitro/plugin.ts"],"sourcesContent":["import type { NitroApp } from 'nitropack/types'\n// Import from specific subpaths to avoid the barrel 'nitropack/runtime' which\n// re-exports from internal/app.mjs — that file imports #nitro-internal-virtual/*\n// modules that only exist inside rollup builds and crash when loaded externally\n// (nitropack dev loads plugins outside the bundle via Worker threads).\nimport { defineNitroPlugin } from 'nitropack/runtime/internal/plugin'\nimport { getHeaders } from 'h3'\nimport { createRequestLogger, initLogger, isEnabled } from '../logger'\nimport { shouldLog, getServiceForPath, extractErrorStatus } from '../nitro'\nimport type { EvlogConfig } from '../nitro'\nimport type { EnrichContext, RequestLogger, ServerEvent, TailSamplingContext, WideEvent } from '../types'\nimport { filterSafeHeaders } from '../utils'\n\nfunction getSafeHeaders(event: ServerEvent): Record<string, string> {\n const allHeaders = getHeaders(event as Parameters<typeof getHeaders>[0])\n return filterSafeHeaders(allHeaders)\n}\n\nfunction getSafeResponseHeaders(event: ServerEvent): Record<string, string> | undefined {\n const headers: Record<string, string> = {}\n const nodeRes = event.node?.res as { getHeaders?: () => Record<string, unknown> } | undefined\n\n if (nodeRes?.getHeaders) {\n for (const [key, value] of Object.entries(nodeRes.getHeaders())) {\n if (value === undefined) continue\n headers[key] = Array.isArray(value) ? value.join(', ') : String(value)\n }\n }\n\n if (event.response?.headers) {\n event.response.headers.forEach((value, key) => {\n headers[key] = value\n })\n }\n\n if (Object.keys(headers).length === 0) return undefined\n return filterSafeHeaders(headers)\n}\n\nfunction getResponseStatus(event: ServerEvent): number {\n // Node.js style\n if (event.node?.res?.statusCode) {\n return event.node.res.statusCode\n }\n\n // Web Standard\n if (event.response?.status) {\n return event.response.status\n }\n\n // Context-based\n if (typeof event.context.status === 'number') {\n return event.context.status\n }\n\n return 200\n}\n\nfunction buildHookContext(event: ServerEvent): Omit<EnrichContext, 'event'> {\n const responseHeaders = getSafeResponseHeaders(event)\n return {\n request: { method: event.method, path: event.path },\n headers: getSafeHeaders(event),\n response: {\n status: getResponseStatus(event),\n headers: responseHeaders,\n },\n }\n}\n\nasync function callEnrichAndDrain(\n nitroApp: NitroApp,\n emittedEvent: WideEvent | null,\n event: ServerEvent,\n): Promise<void> {\n if (!emittedEvent) return\n\n const hookContext = buildHookContext(event)\n\n try {\n await nitroApp.hooks.callHook('evlog:enrich', { event: emittedEvent, ...hookContext })\n } catch (err) {\n console.error('[evlog] enrich failed:', err)\n }\n\n const drainPromise = nitroApp.hooks.callHook('evlog:drain', {\n event: emittedEvent,\n request: hookContext.request,\n headers: hookContext.headers,\n }).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n\n // Use waitUntil if available (Cloudflare Workers, Vercel Edge, etc.)\n // This keeps the runtime alive for background work without blocking the response\n const waitUntilCtx = event.context.cloudflare?.context ?? event.context\n if (typeof waitUntilCtx?.waitUntil === 'function') {\n waitUntilCtx.waitUntil(drainPromise)\n } else {\n // Fallback: await drain to prevent lost logs in serverless environments\n // (e.g. Vercel Fluid Compute). On the normal path this runs from\n // afterResponse (response already sent); on the error path it may run\n // before the error response is finalized.\n await drainPromise\n }\n}\n\nexport default defineNitroPlugin(async (nitroApp) => {\n // Config resolution: process.env bridge first (always set by the module),\n // then lazy useRuntimeConfig() for production builds where env may not persist.\n let evlogConfig: EvlogConfig | undefined\n if (process.env.__EVLOG_CONFIG) {\n evlogConfig = JSON.parse(process.env.__EVLOG_CONFIG)\n } else {\n try {\n // nitropack/runtime/internal/config imports virtual modules —\n // only works inside rollup-bundled output (production builds).\n const { useRuntimeConfig } = await import('nitropack/runtime/internal/config')\n evlogConfig = (useRuntimeConfig() as Record<string, any>).evlog\n } catch {\n // Expected in dev mode — virtual modules unavailable outside rollup\n }\n }\n\n initLogger({\n enabled: evlogConfig?.enabled,\n env: evlogConfig?.env,\n pretty: evlogConfig?.pretty,\n silent: evlogConfig?.silent,\n sampling: evlogConfig?.sampling,\n _suppressDrainWarning: true,\n })\n\n if (!isEnabled()) return\n\n nitroApp.hooks.hook('request', (event) => {\n const e = event as ServerEvent\n\n // Evaluate route filtering but always create the logger so that server\n // middleware (which runs for every request) can call useLogger(event)\n // without throwing. Filtering is enforced at emit time instead.\n e.context._evlogShouldEmit = shouldLog(e.path, evlogConfig?.include, evlogConfig?.exclude)\n\n // Store start time for duration calculation in tail sampling\n e.context._evlogStartTime = Date.now()\n\n let requestIdOverride: string | undefined = undefined\n if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') {\n const cfRay = getSafeHeaders(e)?.['cf-ray']\n if (cfRay) requestIdOverride = cfRay\n }\n\n const requestLog = createRequestLogger({\n method: e.method,\n path: e.path,\n requestId: requestIdOverride || e.context.requestId || crypto.randomUUID(),\n }, { _deferDrain: true })\n\n // Apply route-based service configuration if a matching route is found\n const routeService = getServiceForPath(e.path, evlogConfig?.routes)\n if (routeService) {\n requestLog.set({ service: routeService })\n }\n\n e.context.log = requestLog\n })\n\n nitroApp.hooks.hook('error', async (error, { event }) => {\n const e = event as ServerEvent | undefined\n if (!e) return\n if (!e.context._evlogShouldEmit) return\n\n const requestLog = e.context.log as RequestLogger | undefined\n if (requestLog) {\n requestLog.error(error as Error)\n\n const errorStatus = extractErrorStatus(error)\n requestLog.set({ status: errorStatus })\n\n // Build tail sampling context\n const startTime = e.context._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const tailCtx: TailSamplingContext = {\n status: errorStatus,\n duration: durationMs,\n path: e.path,\n method: e.method,\n context: requestLog.getContext(),\n shouldKeep: false,\n }\n\n // Call evlog:emit:keep hook\n await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx)\n\n e.context._evlogEmitted = true\n\n const emittedEvent = requestLog.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(nitroApp, emittedEvent, e)\n }\n })\n\n nitroApp.hooks.hook('afterResponse', async (event) => {\n const e = event as ServerEvent\n // Skip if already emitted by error hook or route was filtered out\n if (e.context._evlogEmitted || !e.context._evlogShouldEmit) return\n\n const requestLog = e.context.log as RequestLogger | undefined\n if (requestLog) {\n const status = getResponseStatus(e)\n requestLog.set({ status })\n\n const startTime = e.context._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const tailCtx: TailSamplingContext = {\n status,\n duration: durationMs,\n path: e.path,\n method: e.method,\n context: requestLog.getContext(),\n shouldKeep: false,\n }\n\n await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx)\n\n const emittedEvent = requestLog.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(nitroApp, emittedEvent, e)\n }\n })\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../../src/nitro/plugin.ts"],"sourcesContent":["import type { NitroApp } from 'nitropack/types'\n// Import from specific subpaths to avoid the barrel 'nitropack/runtime' which\n// re-exports from internal/app.mjs — that file imports #nitro-internal-virtual/*\n// modules that only exist inside rollup builds and crash when loaded externally\n// (nitropack dev loads plugins outside the bundle via Worker threads).\nimport { defineNitroPlugin } from 'nitropack/runtime/internal/plugin'\nimport { getHeaders } from 'h3'\nimport { createRequestLogger, initLogger, isEnabled } from '../logger'\nimport { shouldLog, getServiceForPath, extractErrorStatus } from '../nitro'\nimport { resolveEvlogConfigForNitroPlugin } from '../shared/nitroConfigBridge'\nimport type { EnrichContext, RequestLogger, ServerEvent, TailSamplingContext, WideEvent } from '../types'\nimport { filterSafeHeaders } from '../utils'\n\nfunction getSafeHeaders(event: ServerEvent): Record<string, string> {\n const allHeaders = getHeaders(event as Parameters<typeof getHeaders>[0])\n return filterSafeHeaders(allHeaders)\n}\n\nfunction getSafeResponseHeaders(event: ServerEvent): Record<string, string> | undefined {\n const headers: Record<string, string> = {}\n const nodeRes = event.node?.res as { getHeaders?: () => Record<string, unknown> } | undefined\n\n if (nodeRes?.getHeaders) {\n for (const [key, value] of Object.entries(nodeRes.getHeaders())) {\n if (value === undefined) continue\n headers[key] = Array.isArray(value) ? value.join(', ') : String(value)\n }\n }\n\n if (event.response?.headers) {\n event.response.headers.forEach((value, key) => {\n headers[key] = value\n })\n }\n\n if (Object.keys(headers).length === 0) return undefined\n return filterSafeHeaders(headers)\n}\n\nfunction getResponseStatus(event: ServerEvent): number {\n // Node.js style\n if (event.node?.res?.statusCode) {\n return event.node.res.statusCode\n }\n\n // Web Standard\n if (event.response?.status) {\n return event.response.status\n }\n\n // Context-based\n if (typeof event.context.status === 'number') {\n return event.context.status\n }\n\n return 200\n}\n\nfunction buildHookContext(event: ServerEvent): Omit<EnrichContext, 'event'> {\n const responseHeaders = getSafeResponseHeaders(event)\n return {\n request: { method: event.method, path: event.path },\n headers: getSafeHeaders(event),\n response: {\n status: getResponseStatus(event),\n headers: responseHeaders,\n },\n }\n}\n\nasync function callEnrichAndDrain(\n nitroApp: NitroApp,\n emittedEvent: WideEvent | null,\n event: ServerEvent,\n): Promise<void> {\n if (!emittedEvent) return\n\n const hookContext = buildHookContext(event)\n\n try {\n await nitroApp.hooks.callHook('evlog:enrich', { event: emittedEvent, ...hookContext })\n } catch (err) {\n console.error('[evlog] enrich failed:', err)\n }\n\n const drainPromise = nitroApp.hooks.callHook('evlog:drain', {\n event: emittedEvent,\n request: hookContext.request,\n headers: hookContext.headers,\n }).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n\n // Use waitUntil if available (Cloudflare Workers, Vercel Edge, etc.)\n // This keeps the runtime alive for background work without blocking the response\n const waitUntilCtx = event.context.cloudflare?.context ?? event.context\n if (typeof waitUntilCtx?.waitUntil === 'function') {\n waitUntilCtx.waitUntil(drainPromise)\n } else {\n // Fallback: await drain to prevent lost logs in serverless environments\n // (e.g. Vercel Fluid Compute). On the normal path this runs from\n // afterResponse (response already sent); on the error path it may run\n // before the error response is finalized.\n await drainPromise\n }\n}\n\nexport default defineNitroPlugin(async (nitroApp) => {\n const evlogConfig = await resolveEvlogConfigForNitroPlugin()\n\n initLogger({\n enabled: evlogConfig?.enabled,\n env: evlogConfig?.env,\n pretty: evlogConfig?.pretty,\n silent: evlogConfig?.silent,\n sampling: evlogConfig?.sampling,\n _suppressDrainWarning: true,\n })\n\n if (!isEnabled()) return\n\n nitroApp.hooks.hook('request', (event) => {\n const e = event as ServerEvent\n\n // Evaluate route filtering but always create the logger so that server\n // middleware (which runs for every request) can call useLogger(event)\n // without throwing. Filtering is enforced at emit time instead.\n e.context._evlogShouldEmit = shouldLog(e.path, evlogConfig?.include, evlogConfig?.exclude)\n\n // Store start time for duration calculation in tail sampling\n e.context._evlogStartTime = Date.now()\n\n let requestIdOverride: string | undefined = undefined\n if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') {\n const cfRay = getSafeHeaders(e)?.['cf-ray']\n if (cfRay) requestIdOverride = cfRay\n }\n\n const requestLog = createRequestLogger({\n method: e.method,\n path: e.path,\n requestId: requestIdOverride || e.context.requestId || crypto.randomUUID(),\n }, { _deferDrain: true })\n\n // Apply route-based service configuration if a matching route is found\n const routeService = getServiceForPath(e.path, evlogConfig?.routes)\n if (routeService) {\n requestLog.set({ service: routeService })\n }\n\n e.context.log = requestLog\n })\n\n nitroApp.hooks.hook('error', async (error, { event }) => {\n const e = event as ServerEvent | undefined\n if (!e) return\n if (!e.context._evlogShouldEmit) return\n\n const requestLog = e.context.log as RequestLogger | undefined\n if (requestLog) {\n requestLog.error(error as Error)\n\n const errorStatus = extractErrorStatus(error)\n requestLog.set({ status: errorStatus })\n\n // Build tail sampling context\n const startTime = e.context._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const tailCtx: TailSamplingContext = {\n status: errorStatus,\n duration: durationMs,\n path: e.path,\n method: e.method,\n context: requestLog.getContext(),\n shouldKeep: false,\n }\n\n // Call evlog:emit:keep hook\n await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx)\n\n e.context._evlogEmitted = true\n\n const emittedEvent = requestLog.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(nitroApp, emittedEvent, e)\n }\n })\n\n nitroApp.hooks.hook('afterResponse', async (event) => {\n const e = event as ServerEvent\n // Skip if already emitted by error hook or route was filtered out\n if (e.context._evlogEmitted || !e.context._evlogShouldEmit) return\n\n const requestLog = e.context.log as RequestLogger | undefined\n if (requestLog) {\n const status = getResponseStatus(e)\n requestLog.set({ status })\n\n const startTime = e.context._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const tailCtx: TailSamplingContext = {\n status,\n duration: durationMs,\n path: e.path,\n method: e.method,\n context: requestLog.getContext(),\n shouldKeep: false,\n }\n\n await nitroApp.hooks.callHook('evlog:emit:keep', tailCtx)\n\n const emittedEvent = requestLog.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(nitroApp, emittedEvent, e)\n }\n })\n})\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import * as nitro_types0 from "nitro/types";
1
+ import * as _$nitro_types0 from "nitro/types";
2
2
 
3
3
  //#region src/nitro-v3/errorHandler.d.ts
4
4
  /**
@@ -18,7 +18,7 @@ import * as nitro_types0 from "nitro/types";
18
18
  * })
19
19
  * ```
20
20
  */
21
- declare const _default: nitro_types0.NitroErrorHandler;
21
+ declare const _default: _$nitro_types0.NitroErrorHandler;
22
22
  //#endregion
23
23
  export { _default as default };
24
24
  //# sourceMappingURL=errorHandler.d.mts.map
@@ -1,6 +1,6 @@
1
1
  import { t as extractErrorStatus } from "../../errors-gH4C9KSC.mjs";
2
2
  import { n as serializeEvlogErrorResponse, t as resolveEvlogError } from "../../nitro-Dpq5ZmcM.mjs";
3
- import { t as parseURL } from "../../dist-BsWcv7B8.mjs";
3
+ import { t as parseURL } from "../../dist-BFn8qsRC.mjs";
4
4
  import { defineErrorHandler } from "nitro";
5
5
  //#region src/nitro-v3/errorHandler.ts
6
6
  /**
@@ -1,4 +1,6 @@
1
+ import { n as createError, t as EvlogError } from "../../error-plrBYLQk.mjs";
2
+ import { t as parseError } from "../../parseError-B_qXj8x4.mjs";
1
3
  import evlog from "./module.mjs";
2
4
  import { useLogger } from "./useLogger.mjs";
3
5
  import { evlogErrorHandler } from "./middleware.mjs";
4
- export { evlog as default, evlogErrorHandler, useLogger };
6
+ export { EvlogError, createError, createError as createEvlogError, evlog as default, evlogErrorHandler, parseError, useLogger };
@@ -1,4 +1,6 @@
1
+ import { EvlogError, createError } from "../../error.mjs";
2
+ import { parseError } from "../../runtime/utils/parseError.mjs";
1
3
  import evlog from "./module.mjs";
2
4
  import { useLogger } from "./useLogger.mjs";
3
5
  import { evlogErrorHandler } from "./middleware.mjs";
4
- export { evlog as default, evlogErrorHandler, useLogger };
6
+ export { EvlogError, createError, createError as createEvlogError, evlog as default, evlogErrorHandler, parseError, useLogger };
@@ -1,3 +1,5 @@
1
+ import { RequestServerResult } from "@tanstack/start-client-core";
2
+
1
3
  //#region src/nitro-v3/middleware.d.ts
2
4
  /**
3
5
  * Server middleware handler that catches EvlogError and returns a structured JSON response.
@@ -19,9 +21,15 @@
19
21
  * })
20
22
  * ```
21
23
  */
22
- declare function evlogErrorHandler<T>(nextOrOptions: ((...args: any[]) => Promise<T>) | {
23
- next: (...args: any[]) => Promise<T>;
24
- }): Promise<T>;
24
+ /**
25
+ * TanStack's `RequestServerNextFn` may return synchronously or as a `Promise`, and uses a
26
+ * typed `options` argument. A rest-args `any[]` signature keeps `RequestServerNextFn`
27
+ * assignable under `strictFunctionTypes`. The return type matches `createMiddleware().server()`.
28
+ */
29
+ type EvlogServerMiddlewareNext = (...args: any[]) => unknown | Promise<unknown>;
30
+ declare function evlogErrorHandler(nextOrOptions: EvlogServerMiddlewareNext | {
31
+ next: EvlogServerMiddlewareNext;
32
+ }): Promise<RequestServerResult<any, any, any> | Response>;
25
33
  //#endregion
26
34
  export { evlogErrorHandler };
27
35
  //# sourceMappingURL=middleware.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.d.mts","names":[],"sources":["../../../src/nitro-v3/middleware.ts"],"mappings":";;AAyBA;;;;;;;;;;;;;;;;;;;iBAAsB,iBAAA,GAAA,CAAqB,aAAA,OAAoB,IAAA,YAAgB,OAAA,CAAQ,CAAA;EAAQ,IAAA,MAAU,IAAA,YAAgB,OAAA,CAAQ,CAAA;AAAA,IAAO,OAAA,CAAQ,CAAA"}
1
+ {"version":3,"file":"middleware.d.mts","names":[],"sources":["../../../src/nitro-v3/middleware.ts"],"mappings":";;;;;AAAsE;;;;;AAgCtE;;;;;;;;;;;;;;;;;;KAFK,yBAAA,OAAgC,IAAA,sBAA0B,OAAA;AAAA,iBAEzC,iBAAA,CACpB,aAAA,EAAe,yBAAA;EAA8B,IAAA,EAAM,yBAAA;AAAA,IAClD,OAAA,CAAQ,mBAAA,kBAAqC,QAAA"}
@@ -1,29 +1,9 @@
1
1
  import { EvlogError } from "../../error.mjs";
2
2
  //#region src/nitro-v3/middleware.ts
3
- /**
4
- * Server middleware handler that catches EvlogError and returns a structured JSON response.
5
- *
6
- * Frameworks like TanStack Start catch thrown errors before Nitro's error handler,
7
- * stripping the `data` field (containing `why`, `fix`, `link`). This middleware
8
- * intercepts EvlogErrors first, attaches them to the wide event, and throws a
9
- * `Response` that the framework passes through directly.
10
- *
11
- * @example TanStack Start
12
- * ```ts
13
- * import { createMiddleware } from '@tanstack/react-start'
14
- * import { evlogErrorHandler } from 'evlog/nitro/v3'
15
- *
16
- * const evlogMiddleware = createMiddleware().server(evlogErrorHandler)
17
- *
18
- * export const Route = createRootRoute({
19
- * server: { middleware: [evlogMiddleware] },
20
- * })
21
- * ```
22
- */
23
3
  async function evlogErrorHandler(nextOrOptions) {
24
4
  const next = typeof nextOrOptions === "function" ? nextOrOptions : nextOrOptions.next;
25
5
  try {
26
- return await next();
6
+ return await Promise.resolve(next());
27
7
  } catch (error) {
28
8
  if (error instanceof EvlogError || error && typeof error === "object" && error.name === "EvlogError") {
29
9
  const evlogError = error;
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.mjs","names":[],"sources":["../../../src/nitro-v3/middleware.ts"],"sourcesContent":["import type { RequestLogger } from '../types'\nimport { EvlogError } from '../error'\nimport { serializeEvlogErrorResponse } from '../nitro'\n\n/**\n * Server middleware handler that catches EvlogError and returns a structured JSON response.\n *\n * Frameworks like TanStack Start catch thrown errors before Nitro's error handler,\n * stripping the `data` field (containing `why`, `fix`, `link`). This middleware\n * intercepts EvlogErrors first, attaches them to the wide event, and throws a\n * `Response` that the framework passes through directly.\n *\n * @example TanStack Start\n * ```ts\n * import { createMiddleware } from '@tanstack/react-start'\n * import { evlogErrorHandler } from 'evlog/nitro/v3'\n *\n * const evlogMiddleware = createMiddleware().server(evlogErrorHandler)\n *\n * export const Route = createRootRoute({\n * server: { middleware: [evlogMiddleware] },\n * })\n * ```\n */\n\nexport async function evlogErrorHandler<T>(nextOrOptions: ((...args: any[]) => Promise<T>) | { next: (...args: any[]) => Promise<T> }): Promise<T> {\n const next = typeof nextOrOptions === 'function' ? nextOrOptions : nextOrOptions.next\n try {\n return await next()\n } catch (error: unknown) {\n if (error instanceof EvlogError || (error && typeof error === 'object' && (error as Error).name === 'EvlogError')) {\n const evlogError = error as EvlogError\n\n try {\n const { useRequest } = await import('nitro/context')\n const req = useRequest()\n const log = req.context?.log as RequestLogger | undefined\n log?.error(evlogError)\n } catch {\n // ignore\n }\n\n // Throw as Response so frameworks (TanStack Start, SolidStart, etc.) pass it through\n throw new Response(JSON.stringify(evlogError.toJSON()), {\n status: evlogError.status || 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n throw error\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAyBA,eAAsB,kBAAqB,eAAwG;CACjJ,MAAM,OAAO,OAAO,kBAAkB,aAAa,gBAAgB,cAAc;AACjF,KAAI;AACF,SAAO,MAAM,MAAM;UACZ,OAAgB;AACvB,MAAI,iBAAiB,cAAe,SAAS,OAAO,UAAU,YAAa,MAAgB,SAAS,cAAe;GACjH,MAAM,aAAa;AAEnB,OAAI;IACF,MAAM,EAAE,eAAe,MAAM,OAAO;AAGpC,KAFY,YAAY,CACR,SAAS,MACpB,MAAM,WAAW;WAChB;AAKR,SAAM,IAAI,SAAS,KAAK,UAAU,WAAW,QAAQ,CAAC,EAAE;IACtD,QAAQ,WAAW,UAAU;IAC7B,SAAS,EAAE,gBAAgB,oBAAoB;IAChD,CAAC;;AAEJ,QAAM"}
1
+ {"version":3,"file":"middleware.mjs","names":[],"sources":["../../../src/nitro-v3/middleware.ts"],"sourcesContent":["import type { RequestServerResult } from '@tanstack/start-client-core'\nimport type { RequestLogger } from '../types'\nimport { EvlogError } from '../error'\n\n/**\n * Server middleware handler that catches EvlogError and returns a structured JSON response.\n *\n * Frameworks like TanStack Start catch thrown errors before Nitro's error handler,\n * stripping the `data` field (containing `why`, `fix`, `link`). This middleware\n * intercepts EvlogErrors first, attaches them to the wide event, and throws a\n * `Response` that the framework passes through directly.\n *\n * @example TanStack Start\n * ```ts\n * import { createMiddleware } from '@tanstack/react-start'\n * import { evlogErrorHandler } from 'evlog/nitro/v3'\n *\n * const evlogMiddleware = createMiddleware().server(evlogErrorHandler)\n *\n * export const Route = createRootRoute({\n * server: { middleware: [evlogMiddleware] },\n * })\n * ```\n */\n\n/**\n * TanStack's `RequestServerNextFn` may return synchronously or as a `Promise`, and uses a\n * typed `options` argument. A rest-args `any[]` signature keeps `RequestServerNextFn`\n * assignable under `strictFunctionTypes`. The return type matches `createMiddleware().server()`.\n */\ntype EvlogServerMiddlewareNext = (...args: any[]) => unknown | Promise<unknown>\n\nexport async function evlogErrorHandler(\n nextOrOptions: EvlogServerMiddlewareNext | { next: EvlogServerMiddlewareNext },\n): Promise<RequestServerResult<any, any, any> | Response> {\n const next = typeof nextOrOptions === 'function' ? nextOrOptions : nextOrOptions.next\n try {\n return (await Promise.resolve(next())) as RequestServerResult<any, any, any>\n } catch (error: unknown) {\n if (error instanceof EvlogError || (error && typeof error === 'object' && (error as Error).name === 'EvlogError')) {\n const evlogError = error as EvlogError\n\n try {\n const { useRequest } = await import('nitro/context')\n const req = useRequest()\n const log = req.context?.log as RequestLogger | undefined\n log?.error(evlogError)\n } catch {\n // ignore\n }\n\n // Throw as Response so frameworks (TanStack Start, SolidStart, etc.) pass it through\n throw new Response(JSON.stringify(evlogError.toJSON()), {\n status: evlogError.status || 500,\n headers: { 'Content-Type': 'application/json' },\n })\n }\n throw error\n }\n}\n"],"mappings":";;AAgCA,eAAsB,kBACpB,eACwD;CACxD,MAAM,OAAO,OAAO,kBAAkB,aAAa,gBAAgB,cAAc;AACjF,KAAI;AACF,SAAQ,MAAM,QAAQ,QAAQ,MAAM,CAAC;UAC9B,OAAgB;AACvB,MAAI,iBAAiB,cAAe,SAAS,OAAO,UAAU,YAAa,MAAgB,SAAS,cAAe;GACjH,MAAM,aAAa;AAEnB,OAAI;IACF,MAAM,EAAE,eAAe,MAAM,OAAO;AAGpC,KAFY,YAAY,CACR,SAAS,MACpB,MAAM,WAAW;WAChB;AAKR,SAAM,IAAI,SAAS,KAAK,UAAU,WAAW,QAAQ,CAAC,EAAE;IACtD,QAAQ,WAAW,UAAU;IAC7B,SAAS,EAAE,gBAAgB,oBAAoB;IAChD,CAAC;;AAEJ,QAAM"}
@@ -1,4 +1,4 @@
1
- import { t as NitroModuleOptions } from "../../nitro-BXmkH7BD.mjs";
1
+ import { t as NitroModuleOptions } from "../../nitro-CfGx0wDJ.mjs";
2
2
  import { Nitro } from "nitro/types";
3
3
 
4
4
  //#region src/nitro-v3/module.d.ts
@@ -1,4 +1,4 @@
1
- import * as nitro_types0 from "nitro/types";
1
+ import * as _$nitro_types0 from "nitro/types";
2
2
 
3
3
  //#region src/nitro-v3/plugin.d.ts
4
4
  /**
@@ -10,7 +10,7 @@ import * as nitro_types0 from "nitro/types";
10
10
  * export { default } from 'evlog/nitro/v3'
11
11
  * ```
12
12
  */
13
- declare const _default: nitro_types0.NitroAppPlugin;
13
+ declare const _default: _$nitro_types0.NitroAppPlugin;
14
14
  //#endregion
15
15
  export { _default as default };
16
16
  //# sourceMappingURL=plugin.d.mts.map
@@ -2,9 +2,9 @@ import { filterSafeHeaders } from "../../utils.mjs";
2
2
  import { createRequestLogger, initLogger, isEnabled } from "../../logger.mjs";
3
3
  import { t as extractErrorStatus } from "../../errors-gH4C9KSC.mjs";
4
4
  import { n as shouldLog, t as getServiceForPath } from "../../routes-CE3_c-iZ.mjs";
5
- import { t as parseURL } from "../../dist-BsWcv7B8.mjs";
5
+ import { n as resolveEvlogConfigForNitroPlugin } from "../../nitroConfigBridge-fidbf-Y_.mjs";
6
+ import { t as parseURL } from "../../dist-BFn8qsRC.mjs";
6
7
  import { definePlugin } from "nitro";
7
- import { useRuntimeConfig } from "nitro/runtime-config";
8
8
  //#region src/nitro-v3/plugin.ts
9
9
  function getContext(event) {
10
10
  if (!event.req.context) event.req.context = {};
@@ -80,8 +80,8 @@ async function callEnrichAndDrain(hooks, emittedEvent, event, res) {
80
80
  * export { default } from 'evlog/nitro/v3'
81
81
  * ```
82
82
  */
83
- var plugin_default = definePlugin((nitroApp) => {
84
- const evlogConfig = useRuntimeConfig().evlog ?? (process.env.__EVLOG_CONFIG ? JSON.parse(process.env.__EVLOG_CONFIG) : void 0);
83
+ var plugin_default = definePlugin(async (nitroApp) => {
84
+ const evlogConfig = await resolveEvlogConfigForNitroPlugin();
85
85
  initLogger({
86
86
  enabled: evlogConfig?.enabled,
87
87
  env: evlogConfig?.env,
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/nitro-v3/plugin.ts"],"sourcesContent":["import { definePlugin } from 'nitro'\nimport { useRuntimeConfig } from 'nitro/runtime-config'\nimport type { CaptureError } from 'nitro/types'\nimport type { HTTPEvent } from 'nitro/h3'\nimport { parseURL } from 'ufo'\nimport { createRequestLogger, initLogger, isEnabled } from '../logger'\nimport { shouldLog, getServiceForPath, extractErrorStatus } from '../nitro'\nimport type { EvlogConfig } from '../nitro'\nimport type { EnrichContext, RequestLogger, TailSamplingContext, WideEvent } from '../types'\nimport { filterSafeHeaders } from '../utils'\n\n// Nitro v3 doesn't fully export hook types yet\n// https://github.com/nitrojs/nitro/blob/8882bc9e1dbf2d342e73097f22a2156f70f50575/src/types/runtime/nitro.ts#L48-L53\ninterface NitroV3Hooks {\n close: () => void\n error: CaptureError\n request: (event: HTTPEvent) => void | Promise<void>\n response: (res: Response, event: HTTPEvent) => void | Promise<void>\n 'evlog:emit:keep': (ctx: TailSamplingContext) => void | Promise<void>\n 'evlog:enrich': (ctx: EnrichContext) => void | Promise<void>\n 'evlog:drain': (ctx: { event: WideEvent; request?: { method?: string; path: string; requestId?: string }; headers?: Record<string, string> }) => void | Promise<void>\n}\n\ntype Hooks = {\n hook: <T extends keyof NitroV3Hooks>(name: T, listener: NitroV3Hooks[T]) => void\n callHook: <T extends keyof NitroV3Hooks>(name: T, ...args: Parameters<NitroV3Hooks[T]>) => Promise<void>\n}\n\nfunction getContext(event: HTTPEvent): Record<string, unknown> {\n if (!event.req.context) {\n event.req.context = {}\n }\n return event.req.context\n}\n\nfunction getSafeRequestHeaders(event: HTTPEvent): Record<string, string> {\n const headers: Record<string, string> = {}\n event.req.headers.forEach((value, key) => {\n headers[key] = value\n })\n return filterSafeHeaders(headers)\n}\n\nfunction getSafeResponseHeaders(res: Response): Record<string, string> | undefined {\n const headers: Record<string, string> = {}\n res.headers.forEach((value, key) => {\n headers[key] = value\n })\n if (Object.keys(headers).length === 0) return undefined\n return filterSafeHeaders(headers)\n}\n\nfunction buildHookContext(\n event: HTTPEvent,\n res?: Response,\n): Omit<EnrichContext, 'event'> {\n const { pathname } = parseURL(event.req.url)\n const responseHeaders = res ? getSafeResponseHeaders(res) : undefined\n return {\n request: { method: event.req.method, path: pathname },\n headers: getSafeRequestHeaders(event),\n response: {\n status: res?.status ?? 200,\n headers: responseHeaders,\n },\n }\n}\n\nasync function callDrainHook(\n hooks: Hooks,\n emittedEvent: WideEvent | null,\n event: HTTPEvent,\n hookContext: Omit<EnrichContext, 'event'>,\n): Promise<void> {\n if (!emittedEvent) return\n\n let drainPromise: Promise<unknown> | undefined\n try {\n const result = hooks.callHook('evlog:drain', {\n event: emittedEvent,\n request: hookContext.request,\n headers: hookContext.headers,\n })\n drainPromise = result?.catch?.((err: unknown) => {\n console.error('[evlog] drain failed:', err)\n })\n } catch (err) {\n console.error('[evlog] drain failed:', err)\n }\n\n if (!drainPromise) return\n\n // Use waitUntil if available (srvx native — Cloudflare Workers, Vercel Edge, etc.)\n // This keeps the runtime alive for background work without blocking the response\n if (typeof event.req.waitUntil === 'function') {\n event.req.waitUntil(drainPromise)\n } else {\n // Fallback: await drain to prevent lost logs in serverless environments\n // (e.g. Vercel Fluid Compute). On the normal path this runs from the\n // response hook (response already sent); on the error path it may run\n // before the error response is finalized.\n await drainPromise\n }\n}\n\nasync function callEnrichAndDrain(\n hooks: Hooks,\n emittedEvent: WideEvent | null,\n event: HTTPEvent,\n res?: Response,\n): Promise<void> {\n if (!emittedEvent) return\n\n const hookContext = buildHookContext(event, res)\n\n try {\n await hooks.callHook('evlog:enrich', { event: emittedEvent, ...hookContext })\n } catch (err) {\n console.error('[evlog] enrich failed:', err)\n }\n\n await callDrainHook(hooks, emittedEvent, event, hookContext)\n}\n\n/**\n * Nitro v3 plugin entry point.\n *\n * Usage in Nitro v3:\n * ```ts\n * // plugins/evlog.ts\n * export { default } from 'evlog/nitro/v3'\n * ```\n */\nexport default definePlugin((nitroApp) => {\n // In production builds the plugin is bundled and useRuntimeConfig()\n // resolves the virtual module correctly. In dev mode the plugin is\n // loaded externally so useRuntimeConfig() returns a stub — fall back\n // to the env var bridge set by the module.\n const evlogConfig = (useRuntimeConfig().evlog ?? (process.env.__EVLOG_CONFIG ? JSON.parse(process.env.__EVLOG_CONFIG) : undefined)) as EvlogConfig | undefined\n\n initLogger({\n enabled: evlogConfig?.enabled,\n env: evlogConfig?.env,\n pretty: evlogConfig?.pretty,\n silent: evlogConfig?.silent,\n sampling: evlogConfig?.sampling,\n _suppressDrainWarning: true,\n })\n\n if (!isEnabled()) return\n\n const hooks = nitroApp.hooks as unknown as Hooks\n\n hooks.hook('request', (event) => {\n const { pathname } = parseURL(event.req.url)\n const ctx = getContext(event)\n\n // Evaluate route filtering but always create the logger so that server\n // middleware (which runs for every request) can call useLogger(event)\n // without throwing. Filtering is enforced at emit time instead.\n ctx._evlogShouldEmit = shouldLog(pathname, evlogConfig?.include, evlogConfig?.exclude)\n\n // Store start time for duration calculation in tail sampling\n ctx._evlogStartTime = Date.now()\n\n let requestIdOverride: string | undefined = undefined\n if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') {\n const cfRay = event.req.headers.get('cf-ray')\n if (cfRay) requestIdOverride = cfRay\n }\n\n const log = createRequestLogger({\n method: event.req.method,\n path: pathname,\n requestId: requestIdOverride || ctx.requestId as string | undefined || crypto.randomUUID(),\n }, { _deferDrain: true })\n\n // Apply route-based service configuration if a matching route is found\n const routeService = getServiceForPath(pathname, evlogConfig?.routes)\n if (routeService) {\n log.set({ service: routeService })\n }\n\n ctx.log = log\n })\n\n hooks.hook('response', async (res, event) => {\n const ctx = event.req.context\n // Skip if already emitted by error hook or route was filtered out\n if (ctx?._evlogEmitted || !ctx?._evlogShouldEmit) return\n\n const log = ctx?.log as RequestLogger | undefined\n if (!log || !ctx) return\n\n const { status } = res\n log.set({ status })\n\n const startTime = ctx._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const { pathname } = parseURL(event.req.url)\n\n const tailCtx: TailSamplingContext = {\n status,\n duration: durationMs,\n path: pathname,\n method: event.req.method,\n context: log.getContext(),\n shouldKeep: false,\n }\n\n await hooks.callHook('evlog:emit:keep', tailCtx)\n\n const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(hooks, emittedEvent, event, res)\n })\n\n hooks.hook('error', async (error, { event }) => {\n if (!event) return\n const e = event as HTTPEvent\n\n const ctx = e.req.context\n if (!ctx?._evlogShouldEmit) return\n const log = ctx.log as RequestLogger | undefined\n if (!log) return\n\n // Check if error.cause is an EvlogError (thrown errors get wrapped in HTTPError by nitro)\n const actualError = (error.cause as Error)?.name === 'EvlogError' \n ? error.cause as Error \n : error as Error\n\n log.error(actualError)\n\n const errorStatus = extractErrorStatus(actualError)\n log.set({ status: errorStatus })\n\n const { pathname } = parseURL(e.req.url)\n const startTime = ctx._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const tailCtx: TailSamplingContext = {\n status: errorStatus,\n duration: durationMs,\n path: pathname,\n method: e.req.method,\n context: log.getContext(),\n shouldKeep: false,\n }\n\n await hooks.callHook('evlog:emit:keep', tailCtx)\n\n ctx._evlogEmitted = true\n\n const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(hooks, emittedEvent, e)\n })\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/nitro-v3/plugin.ts"],"sourcesContent":["import { definePlugin } from 'nitro'\nimport type { CaptureError } from 'nitro/types'\nimport type { HTTPEvent } from 'nitro/h3'\nimport { parseURL } from 'ufo'\nimport { createRequestLogger, initLogger, isEnabled } from '../logger'\nimport { shouldLog, getServiceForPath, extractErrorStatus } from '../nitro'\nimport { resolveEvlogConfigForNitroPlugin } from '../shared/nitroConfigBridge'\nimport type { EnrichContext, RequestLogger, TailSamplingContext, WideEvent } from '../types'\nimport { filterSafeHeaders } from '../utils'\n\n// Nitro v3 doesn't fully export hook types yet\n// https://github.com/nitrojs/nitro/blob/8882bc9e1dbf2d342e73097f22a2156f70f50575/src/types/runtime/nitro.ts#L48-L53\ninterface NitroV3Hooks {\n close: () => void\n error: CaptureError\n request: (event: HTTPEvent) => void | Promise<void>\n response: (res: Response, event: HTTPEvent) => void | Promise<void>\n 'evlog:emit:keep': (ctx: TailSamplingContext) => void | Promise<void>\n 'evlog:enrich': (ctx: EnrichContext) => void | Promise<void>\n 'evlog:drain': (ctx: { event: WideEvent; request?: { method?: string; path: string; requestId?: string }; headers?: Record<string, string> }) => void | Promise<void>\n}\n\ntype Hooks = {\n hook: <T extends keyof NitroV3Hooks>(name: T, listener: NitroV3Hooks[T]) => void\n callHook: <T extends keyof NitroV3Hooks>(name: T, ...args: Parameters<NitroV3Hooks[T]>) => Promise<void>\n}\n\nfunction getContext(event: HTTPEvent): Record<string, unknown> {\n if (!event.req.context) {\n event.req.context = {}\n }\n return event.req.context\n}\n\nfunction getSafeRequestHeaders(event: HTTPEvent): Record<string, string> {\n const headers: Record<string, string> = {}\n event.req.headers.forEach((value, key) => {\n headers[key] = value\n })\n return filterSafeHeaders(headers)\n}\n\nfunction getSafeResponseHeaders(res: Response): Record<string, string> | undefined {\n const headers: Record<string, string> = {}\n res.headers.forEach((value, key) => {\n headers[key] = value\n })\n if (Object.keys(headers).length === 0) return undefined\n return filterSafeHeaders(headers)\n}\n\nfunction buildHookContext(\n event: HTTPEvent,\n res?: Response,\n): Omit<EnrichContext, 'event'> {\n const { pathname } = parseURL(event.req.url)\n const responseHeaders = res ? getSafeResponseHeaders(res) : undefined\n return {\n request: { method: event.req.method, path: pathname },\n headers: getSafeRequestHeaders(event),\n response: {\n status: res?.status ?? 200,\n headers: responseHeaders,\n },\n }\n}\n\nasync function callDrainHook(\n hooks: Hooks,\n emittedEvent: WideEvent | null,\n event: HTTPEvent,\n hookContext: Omit<EnrichContext, 'event'>,\n): Promise<void> {\n if (!emittedEvent) return\n\n let drainPromise: Promise<unknown> | undefined\n try {\n const result = hooks.callHook('evlog:drain', {\n event: emittedEvent,\n request: hookContext.request,\n headers: hookContext.headers,\n })\n drainPromise = result?.catch?.((err: unknown) => {\n console.error('[evlog] drain failed:', err)\n })\n } catch (err) {\n console.error('[evlog] drain failed:', err)\n }\n\n if (!drainPromise) return\n\n // Use waitUntil if available (srvx native — Cloudflare Workers, Vercel Edge, etc.)\n // This keeps the runtime alive for background work without blocking the response\n if (typeof event.req.waitUntil === 'function') {\n event.req.waitUntil(drainPromise)\n } else {\n // Fallback: await drain to prevent lost logs in serverless environments\n // (e.g. Vercel Fluid Compute). On the normal path this runs from the\n // response hook (response already sent); on the error path it may run\n // before the error response is finalized.\n await drainPromise\n }\n}\n\nasync function callEnrichAndDrain(\n hooks: Hooks,\n emittedEvent: WideEvent | null,\n event: HTTPEvent,\n res?: Response,\n): Promise<void> {\n if (!emittedEvent) return\n\n const hookContext = buildHookContext(event, res)\n\n try {\n await hooks.callHook('evlog:enrich', { event: emittedEvent, ...hookContext })\n } catch (err) {\n console.error('[evlog] enrich failed:', err)\n }\n\n await callDrainHook(hooks, emittedEvent, event, hookContext)\n}\n\n/**\n * Nitro v3 plugin entry point.\n *\n * Usage in Nitro v3:\n * ```ts\n * // plugins/evlog.ts\n * export { default } from 'evlog/nitro/v3'\n * ```\n */\nexport default definePlugin(async (nitroApp) => {\n const evlogConfig = await resolveEvlogConfigForNitroPlugin()\n\n initLogger({\n enabled: evlogConfig?.enabled,\n env: evlogConfig?.env,\n pretty: evlogConfig?.pretty,\n silent: evlogConfig?.silent,\n sampling: evlogConfig?.sampling,\n _suppressDrainWarning: true,\n })\n\n if (!isEnabled()) return\n\n const hooks = nitroApp.hooks as unknown as Hooks\n\n hooks.hook('request', (event) => {\n const { pathname } = parseURL(event.req.url)\n const ctx = getContext(event)\n\n // Evaluate route filtering but always create the logger so that server\n // middleware (which runs for every request) can call useLogger(event)\n // without throwing. Filtering is enforced at emit time instead.\n ctx._evlogShouldEmit = shouldLog(pathname, evlogConfig?.include, evlogConfig?.exclude)\n\n // Store start time for duration calculation in tail sampling\n ctx._evlogStartTime = Date.now()\n\n let requestIdOverride: string | undefined = undefined\n if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') {\n const cfRay = event.req.headers.get('cf-ray')\n if (cfRay) requestIdOverride = cfRay\n }\n\n const log = createRequestLogger({\n method: event.req.method,\n path: pathname,\n requestId: requestIdOverride || ctx.requestId as string | undefined || crypto.randomUUID(),\n }, { _deferDrain: true })\n\n // Apply route-based service configuration if a matching route is found\n const routeService = getServiceForPath(pathname, evlogConfig?.routes)\n if (routeService) {\n log.set({ service: routeService })\n }\n\n ctx.log = log\n })\n\n hooks.hook('response', async (res, event) => {\n const ctx = event.req.context\n // Skip if already emitted by error hook or route was filtered out\n if (ctx?._evlogEmitted || !ctx?._evlogShouldEmit) return\n\n const log = ctx?.log as RequestLogger | undefined\n if (!log || !ctx) return\n\n const { status } = res\n log.set({ status })\n\n const startTime = ctx._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const { pathname } = parseURL(event.req.url)\n\n const tailCtx: TailSamplingContext = {\n status,\n duration: durationMs,\n path: pathname,\n method: event.req.method,\n context: log.getContext(),\n shouldKeep: false,\n }\n\n await hooks.callHook('evlog:emit:keep', tailCtx)\n\n const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(hooks, emittedEvent, event, res)\n })\n\n hooks.hook('error', async (error, { event }) => {\n if (!event) return\n const e = event as HTTPEvent\n\n const ctx = e.req.context\n if (!ctx?._evlogShouldEmit) return\n const log = ctx.log as RequestLogger | undefined\n if (!log) return\n\n // Check if error.cause is an EvlogError (thrown errors get wrapped in HTTPError by nitro)\n const actualError = (error.cause as Error)?.name === 'EvlogError' \n ? error.cause as Error \n : error as Error\n\n log.error(actualError)\n\n const errorStatus = extractErrorStatus(actualError)\n log.set({ status: errorStatus })\n\n const { pathname } = parseURL(e.req.url)\n const startTime = ctx._evlogStartTime as number | undefined\n const durationMs = startTime ? Date.now() - startTime : undefined\n\n const tailCtx: TailSamplingContext = {\n status: errorStatus,\n duration: durationMs,\n path: pathname,\n method: e.req.method,\n context: log.getContext(),\n shouldKeep: false,\n }\n\n await hooks.callHook('evlog:emit:keep', tailCtx)\n\n ctx._evlogEmitted = true\n\n const emittedEvent = log.emit({ _forceKeep: tailCtx.shouldKeep })\n await callEnrichAndDrain(hooks, emittedEvent, e)\n })\n})\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { g as RequestLogger } from "../../types-DbVDS9eu.mjs";
1
+ import { g as RequestLogger } from "../../types-v_JkG_D7.mjs";
2
2
  import { HTTPEvent } from "nitro/h3";
3
3
 
4
4
  //#region src/nitro-v3/useLogger.d.ts
@@ -1,5 +1,4 @@
1
- import { a as EnvironmentContext, v as RouteConfig, y as SamplingConfig } from "./types-DbVDS9eu.mjs";
2
-
1
+ import { a as EnvironmentContext, v as RouteConfig, y as SamplingConfig } from "./types-v_JkG_D7.mjs";
3
2
  //#region src/nitro.d.ts
4
3
  interface NitroModuleOptions {
5
4
  /**
@@ -47,4 +46,4 @@ interface NitroModuleOptions {
47
46
  }
48
47
  //#endregion
49
48
  export { NitroModuleOptions as t };
50
- //# sourceMappingURL=nitro-BXmkH7BD.d.mts.map
49
+ //# sourceMappingURL=nitro-CfGx0wDJ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nitro-CfGx0wDJ.d.mts","names":[],"sources":["../src/nitro.ts"],"mappings":";;UAKiB,kBAAA;;AAAjB;;;EAKE,OAAA;EAKM;;;EAAN,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAuCW;;;;EAjCzB,MAAA;EANc;;;;;;;EAed,MAAA;EAwBA;;;;;EAjBA,OAAA;;;;;;EAOA,OAAA;;;;EAKA,MAAA,GAAS,MAAA,SAAe,WAAA;;;;EAKxB,QAAA,GAAW,cAAA;AAAA"}
@@ -0,0 +1,92 @@
1
+ //#region src/shared/nitroConfigBridge.ts
2
+ const EVLOG_NITRO_ENV = "__EVLOG_CONFIG";
3
+ function nitroV3RuntimeConfigSpecifier() {
4
+ return ["nitro", "runtime-config"].join("/");
5
+ }
6
+ function nitropackRuntimeSpecifier() {
7
+ return ["nitropack", "runtime"].join("/");
8
+ }
9
+ function nitropackInternalRuntimeConfigSpecifier() {
10
+ return [
11
+ "nitropack",
12
+ "runtime",
13
+ "internal",
14
+ "config"
15
+ ].join("/");
16
+ }
17
+ async function importOrNull(specifier) {
18
+ try {
19
+ return await import(specifier);
20
+ } catch {
21
+ return null;
22
+ }
23
+ }
24
+ function isRuntimeConfigModule(mod) {
25
+ return typeof mod === "object" && mod !== null && "useRuntimeConfig" in mod && typeof mod.useRuntimeConfig === "function";
26
+ }
27
+ /** Snapshot from env, or `undefined` if unset / invalid JSON. */
28
+ function readEvlogConfigFromNitroEnv() {
29
+ const raw = process.env[EVLOG_NITRO_ENV];
30
+ if (raw === void 0 || raw === "") return void 0;
31
+ try {
32
+ return JSON.parse(raw);
33
+ } catch {
34
+ return;
35
+ }
36
+ }
37
+ let cachedNitropackRuntime;
38
+ let cachedNitroV3Runtime;
39
+ let cachedNitropackInternalConfig;
40
+ async function getNitropackRuntime() {
41
+ if (cachedNitropackRuntime !== void 0) return cachedNitropackRuntime;
42
+ const mod = await importOrNull(nitropackRuntimeSpecifier());
43
+ cachedNitropackRuntime = isRuntimeConfigModule(mod) ? mod : null;
44
+ return cachedNitropackRuntime;
45
+ }
46
+ async function getNitroV3Runtime() {
47
+ if (cachedNitroV3Runtime !== void 0) return cachedNitroV3Runtime;
48
+ const mod = await importOrNull(nitroV3RuntimeConfigSpecifier());
49
+ cachedNitroV3Runtime = isRuntimeConfigModule(mod) ? mod : null;
50
+ return cachedNitroV3Runtime;
51
+ }
52
+ async function getNitropackInternalRuntimeConfig() {
53
+ if (cachedNitropackInternalConfig !== void 0) return cachedNitropackInternalConfig;
54
+ const mod = await importOrNull(nitropackInternalRuntimeConfigSpecifier());
55
+ cachedNitropackInternalConfig = isRuntimeConfigModule(mod) ? mod : null;
56
+ return cachedNitropackInternalConfig;
57
+ }
58
+ function evlogSlice(config) {
59
+ const { evlog } = config;
60
+ if (evlog && typeof evlog === "object") return evlog;
61
+ }
62
+ /**
63
+ * Options for evlog Nitro plugins (nitropack v2 and Nitro v3).
64
+ * Env bridge first; then Nitro v3 `runtime-config`; then nitropack internal config.
65
+ */
66
+ async function resolveEvlogConfigForNitroPlugin() {
67
+ const fromEnv = readEvlogConfigFromNitroEnv();
68
+ if (fromEnv !== void 0) return fromEnv;
69
+ const v3 = await getNitroV3Runtime();
70
+ if (v3) {
71
+ const slice = evlogSlice(v3.useRuntimeConfig());
72
+ if (slice !== void 0) return slice;
73
+ }
74
+ const internal = await getNitropackInternalRuntimeConfig();
75
+ if (internal) {
76
+ const slice = evlogSlice(internal.useRuntimeConfig());
77
+ if (slice !== void 0) return slice;
78
+ }
79
+ }
80
+ /**
81
+ * Full `useRuntimeConfig()` object for drain adapters (nitropack first, then v3).
82
+ */
83
+ async function getNitroRuntimeConfigRecord() {
84
+ const nitropack = await getNitropackRuntime();
85
+ if (nitropack) return nitropack.useRuntimeConfig();
86
+ const v3 = await getNitroV3Runtime();
87
+ if (v3) return v3.useRuntimeConfig();
88
+ }
89
+ //#endregion
90
+ export { resolveEvlogConfigForNitroPlugin as n, getNitroRuntimeConfigRecord as t };
91
+
92
+ //# sourceMappingURL=nitroConfigBridge-fidbf-Y_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nitroConfigBridge-fidbf-Y_.mjs","names":[],"sources":["../src/shared/nitroConfigBridge.ts"],"sourcesContent":["/**\n * How evlog reads Nitro runtime config from **published** ESM.\n *\n * **Why not** `import('nitro/runtime-config')` as a string literal in source?\n * Those subpaths are virtual or specially resolved. App Rollup can resolve them\n * for first-party code; for dependency chunks (`node_modules/evlog/dist/...`),\n * strict presets (e.g. `cloudflare-durable`) may fail with “externals are not\n * allowed”. A literal dynamic import is enough for Rollup to pre-resolve.\n *\n * **Strategy**\n *\n * 1. `process.env.__EVLOG_CONFIG` — JSON set by evlog Nitro modules (no virtual\n * modules; preferred in production Workers builds).\n * 2. Computed module IDs — `['a','b'].join('/')` passed to `import()` so emitted\n * JS does not contain a static `import(\"a/b\")`.\n * 3. Plugin resolution tries Nitro v3 first, then nitropack internal config (v2).\n * 4. Adapter resolution keeps historical order: nitropack runtime barrel, then v3.\n *\n * Not exported from `evlog/toolkit` — package-internal only.\n */\n\nimport type { EvlogConfig } from '../nitro'\n\nconst EVLOG_NITRO_ENV = '__EVLOG_CONFIG' as const\n\ntype NitroRuntimeConfigModule = {\n useRuntimeConfig: () => Record<string, any>\n}\n\nfunction nitroV3RuntimeConfigSpecifier(): string {\n return ['nitro', 'runtime-config'].join('/')\n}\n\nfunction nitropackRuntimeSpecifier(): string {\n return ['nitropack', 'runtime'].join('/')\n}\n\nfunction nitropackInternalRuntimeConfigSpecifier(): string {\n return ['nitropack', 'runtime', 'internal', 'config'].join('/')\n}\n\nasync function importOrNull(specifier: string): Promise<unknown> {\n try {\n return await import(specifier)\n } catch {\n return null\n }\n}\n\nfunction isRuntimeConfigModule(mod: unknown): mod is NitroRuntimeConfigModule {\n return (\n typeof mod === 'object'\n && mod !== null\n && 'useRuntimeConfig' in mod\n && typeof (mod as NitroRuntimeConfigModule).useRuntimeConfig === 'function'\n )\n}\n\n/** Snapshot from env, or `undefined` if unset / invalid JSON. */\nexport function readEvlogConfigFromNitroEnv(): EvlogConfig | undefined {\n const raw = process.env[EVLOG_NITRO_ENV]\n if (raw === undefined || raw === '') return undefined\n try {\n return JSON.parse(raw) as EvlogConfig\n } catch {\n return undefined\n }\n}\n\nlet cachedNitropackRuntime: NitroRuntimeConfigModule | null | undefined\nlet cachedNitroV3Runtime: NitroRuntimeConfigModule | null | undefined\nlet cachedNitropackInternalConfig: NitroRuntimeConfigModule | null | undefined\n\nasync function getNitropackRuntime(): Promise<NitroRuntimeConfigModule | null> {\n if (cachedNitropackRuntime !== undefined) return cachedNitropackRuntime\n const mod = await importOrNull(nitropackRuntimeSpecifier())\n cachedNitropackRuntime = isRuntimeConfigModule(mod) ? mod : null\n return cachedNitropackRuntime\n}\n\nasync function getNitroV3Runtime(): Promise<NitroRuntimeConfigModule | null> {\n if (cachedNitroV3Runtime !== undefined) return cachedNitroV3Runtime\n const mod = await importOrNull(nitroV3RuntimeConfigSpecifier())\n cachedNitroV3Runtime = isRuntimeConfigModule(mod) ? mod : null\n return cachedNitroV3Runtime\n}\n\nasync function getNitropackInternalRuntimeConfig(): Promise<NitroRuntimeConfigModule | null> {\n if (cachedNitropackInternalConfig !== undefined) return cachedNitropackInternalConfig\n const mod = await importOrNull(nitropackInternalRuntimeConfigSpecifier())\n cachedNitropackInternalConfig = isRuntimeConfigModule(mod) ? mod : null\n return cachedNitropackInternalConfig\n}\n\nfunction evlogSlice(config: Record<string, any>): EvlogConfig | undefined {\n const { evlog } = config\n if (evlog && typeof evlog === 'object') return evlog as EvlogConfig\n return undefined\n}\n\n/**\n * Options for evlog Nitro plugins (nitropack v2 and Nitro v3).\n * Env bridge first; then Nitro v3 `runtime-config`; then nitropack internal config.\n */\nexport async function resolveEvlogConfigForNitroPlugin(): Promise<EvlogConfig | undefined> {\n const fromEnv = readEvlogConfigFromNitroEnv()\n if (fromEnv !== undefined) return fromEnv\n\n const v3 = await getNitroV3Runtime()\n if (v3) {\n const slice = evlogSlice(v3.useRuntimeConfig())\n if (slice !== undefined) return slice\n }\n\n const internal = await getNitropackInternalRuntimeConfig()\n if (internal) {\n const slice = evlogSlice(internal.useRuntimeConfig())\n if (slice !== undefined) return slice\n }\n\n return undefined\n}\n\n/**\n * Full `useRuntimeConfig()` object for drain adapters (nitropack first, then v3).\n */\nexport async function getNitroRuntimeConfigRecord(): Promise<Record<string, any> | undefined> {\n const nitropack = await getNitropackRuntime()\n if (nitropack) return nitropack.useRuntimeConfig()\n\n const v3 = await getNitroV3Runtime()\n if (v3) return v3.useRuntimeConfig()\n\n return undefined\n}\n"],"mappings":";AAuBA,MAAM,kBAAkB;AAMxB,SAAS,gCAAwC;AAC/C,QAAO,CAAC,SAAS,iBAAiB,CAAC,KAAK,IAAI;;AAG9C,SAAS,4BAAoC;AAC3C,QAAO,CAAC,aAAa,UAAU,CAAC,KAAK,IAAI;;AAG3C,SAAS,0CAAkD;AACzD,QAAO;EAAC;EAAa;EAAW;EAAY;EAAS,CAAC,KAAK,IAAI;;AAGjE,eAAe,aAAa,WAAqC;AAC/D,KAAI;AACF,SAAO,MAAM,OAAO;SACd;AACN,SAAO;;;AAIX,SAAS,sBAAsB,KAA+C;AAC5E,QACE,OAAO,QAAQ,YACZ,QAAQ,QACR,sBAAsB,OACtB,OAAQ,IAAiC,qBAAqB;;;AAKrE,SAAgB,8BAAuD;CACrE,MAAM,MAAM,QAAQ,IAAI;AACxB,KAAI,QAAQ,KAAA,KAAa,QAAQ,GAAI,QAAO,KAAA;AAC5C,KAAI;AACF,SAAO,KAAK,MAAM,IAAI;SAChB;AACN;;;AAIJ,IAAI;AACJ,IAAI;AACJ,IAAI;AAEJ,eAAe,sBAAgE;AAC7E,KAAI,2BAA2B,KAAA,EAAW,QAAO;CACjD,MAAM,MAAM,MAAM,aAAa,2BAA2B,CAAC;AAC3D,0BAAyB,sBAAsB,IAAI,GAAG,MAAM;AAC5D,QAAO;;AAGT,eAAe,oBAA8D;AAC3E,KAAI,yBAAyB,KAAA,EAAW,QAAO;CAC/C,MAAM,MAAM,MAAM,aAAa,+BAA+B,CAAC;AAC/D,wBAAuB,sBAAsB,IAAI,GAAG,MAAM;AAC1D,QAAO;;AAGT,eAAe,oCAA8E;AAC3F,KAAI,kCAAkC,KAAA,EAAW,QAAO;CACxD,MAAM,MAAM,MAAM,aAAa,yCAAyC,CAAC;AACzE,iCAAgC,sBAAsB,IAAI,GAAG,MAAM;AACnE,QAAO;;AAGT,SAAS,WAAW,QAAsD;CACxE,MAAM,EAAE,UAAU;AAClB,KAAI,SAAS,OAAO,UAAU,SAAU,QAAO;;;;;;AAQjD,eAAsB,mCAAqE;CACzF,MAAM,UAAU,6BAA6B;AAC7C,KAAI,YAAY,KAAA,EAAW,QAAO;CAElC,MAAM,KAAK,MAAM,mBAAmB;AACpC,KAAI,IAAI;EACN,MAAM,QAAQ,WAAW,GAAG,kBAAkB,CAAC;AAC/C,MAAI,UAAU,KAAA,EAAW,QAAO;;CAGlC,MAAM,WAAW,MAAM,mCAAmC;AAC1D,KAAI,UAAU;EACZ,MAAM,QAAQ,WAAW,SAAS,kBAAkB,CAAC;AACrD,MAAI,UAAU,KAAA,EAAW,QAAO;;;;;;AASpC,eAAsB,8BAAwE;CAC5F,MAAM,YAAY,MAAM,qBAAqB;AAC7C,KAAI,UAAW,QAAO,UAAU,kBAAkB;CAElD,MAAM,KAAK,MAAM,mBAAmB;AACpC,KAAI,GAAI,QAAO,GAAG,kBAAkB"}
@@ -1,5 +1,5 @@
1
- import { a as EnvironmentContext, f as LogLevel, v as RouteConfig, w as TransportConfig, y as SamplingConfig } from "../types-DbVDS9eu.mjs";
2
- import * as _nuxt_schema0 from "@nuxt/schema";
1
+ import { a as EnvironmentContext, f as LogLevel, v as RouteConfig, w as TransportConfig, y as SamplingConfig } from "../types-v_JkG_D7.mjs";
2
+ import * as _$_nuxt_schema0 from "@nuxt/schema";
3
3
 
4
4
  //#region src/nuxt/module.d.ts
5
5
  interface ModuleAxiomBaseConfig {
@@ -206,7 +206,7 @@ interface ModuleOptions {
206
206
  */
207
207
  retention?: string;
208
208
  }
209
- declare const _default: _nuxt_schema0.NuxtModule<ModuleOptions, ModuleOptions, false>;
209
+ declare const _default: _$_nuxt_schema0.NuxtModule<ModuleOptions, ModuleOptions, false>;
210
210
  //#endregion
211
211
  export { ModuleOptions, _default as default };
212
212
  //# sourceMappingURL=module.d.mts.map
@@ -7,7 +7,7 @@ var name = "evlog";
7
7
  var module_default = defineNuxtModule({
8
8
  meta: {
9
9
  name,
10
- version: "2.10.0",
10
+ version: "2.11.0",
11
11
  configKey: name,
12
12
  docs: "https://evlog.dev"
13
13
  },
@@ -1,7 +1,7 @@
1
- import { m as ParsedError } from "./types-DbVDS9eu.mjs";
1
+ import { m as ParsedError } from "./types-v_JkG_D7.mjs";
2
2
 
3
3
  //#region src/runtime/utils/parseError.d.ts
4
4
  declare function parseError(error: unknown): ParsedError;
5
5
  //#endregion
6
6
  export { parseError as t };
7
- //# sourceMappingURL=parseError-CcvBYsbl.d.mts.map
7
+ //# sourceMappingURL=parseError-B_qXj8x4.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseError-B_qXj8x4.d.mts","names":[],"sources":["../src/runtime/utils/parseError.ts"],"mappings":";;;iBAMgB,UAAA,CAAW,KAAA,YAAiB,WAAA"}
@@ -1,6 +1,6 @@
1
- import { g as RequestLogger } from "../types-DbVDS9eu.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-BjERCCEd.mjs";
3
- import * as react_router0 from "react-router";
1
+ import { g as RequestLogger } from "../types-v_JkG_D7.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-DojmTj9Y.mjs";
3
+ import * as _$react_router0 from "react-router";
4
4
 
5
5
  //#region src/react-router/index.d.ts
6
6
  declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
@@ -18,7 +18,7 @@ declare const useLogger: <T extends object = Record<string, unknown>>() => Reque
18
18
  * }
19
19
  * ```
20
20
  */
21
- declare const loggerContext: react_router0.RouterContext<RequestLogger<Record<string, unknown>>>;
21
+ declare const loggerContext: _$react_router0.RouterContext<RequestLogger<Record<string, unknown>>>;
22
22
  type EvlogReactRouterOptions = BaseEvlogOptions;
23
23
  /**
24
24
  * Create an evlog middleware for React Router.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react-router/index.ts"],"mappings":";;;;;cAMiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;;;AAJ0D;;;;;;;;;;;;cAsBvE,aAAA,EAAa,aAAA,CAAA,aAAA,CAAA,aAAA,CAAA,MAAA;AAAA,KAEd,uBAAA,GAA0B,gBAAA;;;;;;;;;;;;;AAAtC;iBAiBgB,KAAA,CAAM,OAAA,GAAS,uBAAA;EAE3B,OAAA;EAAA;AAAA;EAAwB,OAAA,EAAS,OAAA;EAAS,OAAA;IAAW,GAAA,CAAI,GAAA,WAAc,KAAA;EAAA;AAAA,GACvE,IAAA,QAAY,OAAA,CAAQ,QAAA,MACnB,OAAA,CAAQ,QAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react-router/index.ts"],"mappings":";;;;;cAMiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;;;AAJ0D;;;;;;;;;;;;cAsBvE,aAAA,EAAa,eAAA,CAAA,aAAA,CAAA,aAAA,CAAA,MAAA;AAAA,KAEd,uBAAA,GAA0B,gBAAA;;;;;;;;;;;;;AAAtC;iBAiBgB,KAAA,CAAM,OAAA,GAAS,uBAAA;EAE3B,OAAA;EAAA;AAAA;EAAwB,OAAA,EAAS,OAAA;EAAS,OAAA;IAAW,GAAA,CAAI,GAAA,WAAc,KAAA;EAAA;AAAA,GACvE,IAAA,QAAY,OAAA,CAAQ,QAAA,MACnB,OAAA,CAAQ,QAAA"}
@@ -1,5 +1,5 @@
1
- import { r as createMiddlewareLogger, t as extractSafeHeaders } from "../headers-DrdQ6uG5.mjs";
2
- import { t as createLoggerStorage } from "../storage-DsueXspk.mjs";
1
+ import { r as createMiddlewareLogger, t as extractSafeHeaders } from "../headers-BSi3UHKL.mjs";
2
+ import { t as createLoggerStorage } from "../storage-B6NPh8rV.mjs";
3
3
  import { createContext } from "react-router";
4
4
  //#region src/react-router/index.ts
5
5
  const { storage, useLogger } = createLoggerStorage("middleware context. Make sure the evlog middleware is added to your route.");