evlog 2.11.1 → 2.13.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 (173) hide show
  1. package/README.md +42 -2
  2. package/dist/{_drain-YH8ERc5l.mjs → _drain-CmCtsuF6.mjs} +1 -1
  3. package/dist/{_drain-YH8ERc5l.mjs.map → _drain-CmCtsuF6.mjs.map} +1 -1
  4. package/dist/{_http-C_2wbJw3.mjs → _http-CHSsrWDJ.mjs} +2 -2
  5. package/dist/{_http-C_2wbJw3.mjs.map → _http-CHSsrWDJ.mjs.map} +1 -1
  6. package/dist/{_severity-BZhz3f9e.mjs → _severity-CQijvfhU.mjs} +1 -1
  7. package/dist/{_severity-BZhz3f9e.mjs.map → _severity-CQijvfhU.mjs.map} +1 -1
  8. package/dist/adapters/axiom.d.mts +1 -1
  9. package/dist/adapters/axiom.mjs +2 -2
  10. package/dist/adapters/better-stack.d.mts +1 -1
  11. package/dist/adapters/better-stack.mjs +2 -2
  12. package/dist/adapters/datadog.d.mts +1 -1
  13. package/dist/adapters/datadog.mjs +2 -2
  14. package/dist/adapters/fs.d.mts +1 -1
  15. package/dist/adapters/fs.mjs +1 -1
  16. package/dist/adapters/hyperdx.d.mts +1 -1
  17. package/dist/adapters/hyperdx.mjs +2 -2
  18. package/dist/adapters/otlp.d.mts +1 -1
  19. package/dist/adapters/otlp.mjs +3 -3
  20. package/dist/adapters/posthog.d.mts +1 -1
  21. package/dist/adapters/posthog.mjs +2 -2
  22. package/dist/adapters/sentry.d.mts +1 -1
  23. package/dist/adapters/sentry.mjs +3 -3
  24. package/dist/ai/index.d.mts +144 -5
  25. package/dist/ai/index.d.mts.map +1 -1
  26. package/dist/ai/index.mjs +108 -5
  27. package/dist/ai/index.mjs.map +1 -1
  28. package/dist/better-auth/index.d.mts +220 -0
  29. package/dist/better-auth/index.d.mts.map +1 -0
  30. package/dist/better-auth/index.mjs +205 -0
  31. package/dist/better-auth/index.mjs.map +1 -0
  32. package/dist/browser.d.mts +13 -52
  33. package/dist/browser.d.mts.map +1 -1
  34. package/dist/browser.mjs +5 -81
  35. package/dist/browser.mjs.map +1 -1
  36. package/dist/client.d.mts +2 -2
  37. package/dist/client.mjs +2 -2
  38. package/dist/{dist-BFn8qsRC.mjs → dist-Do8P4zWd.mjs} +1 -1
  39. package/dist/{dist-BFn8qsRC.mjs.map → dist-Do8P4zWd.mjs.map} +1 -1
  40. package/dist/elysia/index.d.mts +2 -2
  41. package/dist/elysia/index.d.mts.map +1 -1
  42. package/dist/elysia/index.mjs +16 -4
  43. package/dist/elysia/index.mjs.map +1 -1
  44. package/dist/enrichers.d.mts +1 -1
  45. package/dist/{error-plrBYLQk.d.mts → error-B9CiGK_i.d.mts} +2 -2
  46. package/dist/{error-plrBYLQk.d.mts.map → error-B9CiGK_i.d.mts.map} +1 -1
  47. package/dist/error.d.mts +1 -1
  48. package/dist/{errors-gH4C9KSC.mjs → errors-BJRXUfMg.mjs} +1 -1
  49. package/dist/{errors-gH4C9KSC.mjs.map → errors-BJRXUfMg.mjs.map} +1 -1
  50. package/dist/{errors-bPoj9UZk.d.mts → errors-Dr0r4OpR.d.mts} +2 -2
  51. package/dist/{errors-bPoj9UZk.d.mts.map → errors-Dr0r4OpR.d.mts.map} +1 -1
  52. package/dist/express/index.d.mts +2 -2
  53. package/dist/express/index.d.mts.map +1 -1
  54. package/dist/express/index.mjs +8 -4
  55. package/dist/express/index.mjs.map +1 -1
  56. package/dist/fastify/index.d.mts +2 -2
  57. package/dist/fastify/index.d.mts.map +1 -1
  58. package/dist/fastify/index.mjs +8 -4
  59. package/dist/fastify/index.mjs.map +1 -1
  60. package/dist/fork-Y4z8iHti.mjs +72 -0
  61. package/dist/fork-Y4z8iHti.mjs.map +1 -0
  62. package/dist/headers-D74M0wsg.mjs +30 -0
  63. package/dist/headers-D74M0wsg.mjs.map +1 -0
  64. package/dist/hono/index.d.mts +2 -2
  65. package/dist/hono/index.mjs +2 -1
  66. package/dist/hono/index.mjs.map +1 -1
  67. package/dist/http.d.mts +65 -0
  68. package/dist/http.d.mts.map +1 -0
  69. package/dist/http.mjs +94 -0
  70. package/dist/http.mjs.map +1 -0
  71. package/dist/index.d.mts +7 -6
  72. package/dist/index.mjs +3 -2
  73. package/dist/logger-DnobymUQ.mjs +741 -0
  74. package/dist/logger-DnobymUQ.mjs.map +1 -0
  75. package/dist/{logger-CG1eop2_.d.mts → logger-Dp6nYWjH.d.mts} +6 -2
  76. package/dist/logger-Dp6nYWjH.d.mts.map +1 -0
  77. package/dist/logger.d.mts +1 -1
  78. package/dist/logger.mjs +1 -361
  79. package/dist/{headers-BSi3UHKL.mjs → middleware-BtBuosFV.mjs} +13 -32
  80. package/dist/middleware-BtBuosFV.mjs.map +1 -0
  81. package/dist/{middleware-DojmTj9Y.d.mts → middleware-FgC1OdOD.d.mts} +21 -3
  82. package/dist/middleware-FgC1OdOD.d.mts.map +1 -0
  83. package/dist/nestjs/index.d.mts +2 -2
  84. package/dist/nestjs/index.d.mts.map +1 -1
  85. package/dist/nestjs/index.mjs +8 -4
  86. package/dist/nestjs/index.mjs.map +1 -1
  87. package/dist/next/client.d.mts +9 -3
  88. package/dist/next/client.d.mts.map +1 -1
  89. package/dist/next/client.mjs +5 -3
  90. package/dist/next/client.mjs.map +1 -1
  91. package/dist/next/index.d.mts +9 -4
  92. package/dist/next/index.d.mts.map +1 -1
  93. package/dist/next/index.mjs +17 -2
  94. package/dist/next/index.mjs.map +1 -1
  95. package/dist/next/instrumentation.d.mts +3 -1
  96. package/dist/next/instrumentation.d.mts.map +1 -1
  97. package/dist/next/instrumentation.mjs +2 -1
  98. package/dist/next/instrumentation.mjs.map +1 -1
  99. package/dist/nitro/errorHandler.mjs +2 -2
  100. package/dist/nitro/module.d.mts +2 -2
  101. package/dist/nitro/plugin.mjs +7 -4
  102. package/dist/nitro/plugin.mjs.map +1 -1
  103. package/dist/nitro/v3/errorHandler.mjs +3 -3
  104. package/dist/nitro/v3/index.d.mts +2 -2
  105. package/dist/nitro/v3/module.d.mts +1 -1
  106. package/dist/nitro/v3/plugin.mjs +8 -5
  107. package/dist/nitro/v3/plugin.mjs.map +1 -1
  108. package/dist/nitro/v3/useLogger.d.mts +1 -1
  109. package/dist/{nitro-CfGx0wDJ.d.mts → nitro-CDHLfRdw.d.mts} +13 -2
  110. package/dist/nitro-CDHLfRdw.d.mts.map +1 -0
  111. package/dist/{nitro-Dpq5ZmcM.mjs → nitro-OmT_M4Pb.mjs} +2 -2
  112. package/dist/nitro-OmT_M4Pb.mjs.map +1 -0
  113. package/dist/{nitroConfigBridge-fidbf-Y_.mjs → nitroConfigBridge-C37lXaNm.mjs} +1 -1
  114. package/dist/{nitroConfigBridge-fidbf-Y_.mjs.map → nitroConfigBridge-C37lXaNm.mjs.map} +1 -1
  115. package/dist/nuxt/module.d.mts +26 -1
  116. package/dist/nuxt/module.d.mts.map +1 -1
  117. package/dist/nuxt/module.mjs +7 -2
  118. package/dist/nuxt/module.mjs.map +1 -1
  119. package/dist/{parseError-B_qXj8x4.d.mts → parseError-DM-lyezZ.d.mts} +2 -2
  120. package/dist/parseError-DM-lyezZ.d.mts.map +1 -0
  121. package/dist/react-router/index.d.mts +2 -2
  122. package/dist/react-router/index.d.mts.map +1 -1
  123. package/dist/react-router/index.mjs +8 -4
  124. package/dist/react-router/index.mjs.map +1 -1
  125. package/dist/{routes-CE3_c-iZ.mjs → routes-CGPmbzCZ.mjs} +1 -1
  126. package/dist/{routes-CE3_c-iZ.mjs.map → routes-CGPmbzCZ.mjs.map} +1 -1
  127. package/dist/runtime/client/log.d.mts +7 -2
  128. package/dist/runtime/client/log.d.mts.map +1 -1
  129. package/dist/runtime/client/log.mjs +24 -6
  130. package/dist/runtime/client/log.mjs.map +1 -1
  131. package/dist/runtime/client/plugin.mjs +1 -0
  132. package/dist/runtime/client/plugin.mjs.map +1 -1
  133. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +1 -1
  134. package/dist/runtime/server/useLogger.d.mts +1 -1
  135. package/dist/runtime/utils/parseError.d.mts +2 -2
  136. package/dist/runtime/utils/parseError.mjs +1 -1
  137. package/dist/{source-location-B1VVgXkh.mjs → source-location-DRvDDqfq.mjs} +1 -1
  138. package/dist/{source-location-B1VVgXkh.mjs.map → source-location-DRvDDqfq.mjs.map} +1 -1
  139. package/dist/{storage-B6NPh8rV.mjs → storage-CFGTn37X.mjs} +1 -1
  140. package/dist/{storage-B6NPh8rV.mjs.map → storage-CFGTn37X.mjs.map} +1 -1
  141. package/dist/sveltekit/index.d.mts +2 -2
  142. package/dist/sveltekit/index.d.mts.map +1 -1
  143. package/dist/sveltekit/index.mjs +10 -6
  144. package/dist/sveltekit/index.mjs.map +1 -1
  145. package/dist/toolkit.d.mts +41 -4
  146. package/dist/toolkit.d.mts.map +1 -1
  147. package/dist/toolkit.mjs +7 -5
  148. package/dist/{types-v_JkG_D7.d.mts → types-DbzDln7O.d.mts} +120 -4
  149. package/dist/types-DbzDln7O.d.mts.map +1 -0
  150. package/dist/types.d.mts +2 -2
  151. package/dist/{useLogger-TjKH37BO.d.mts → useLogger-N5A-d5l9.d.mts} +2 -2
  152. package/dist/{useLogger-TjKH37BO.d.mts.map → useLogger-N5A-d5l9.d.mts.map} +1 -1
  153. package/dist/utils-DnX6VMNi.d.mts +54 -0
  154. package/dist/utils-DnX6VMNi.d.mts.map +1 -0
  155. package/dist/utils.d.mts +2 -50
  156. package/dist/utils.mjs +13 -1
  157. package/dist/utils.mjs.map +1 -1
  158. package/dist/vite/index.d.mts +5 -1
  159. package/dist/vite/index.d.mts.map +1 -1
  160. package/dist/vite/index.mjs +3 -1
  161. package/dist/vite/index.mjs.map +1 -1
  162. package/dist/workers.d.mts +1 -1
  163. package/dist/workers.mjs +1 -1
  164. package/package.json +24 -3
  165. package/dist/headers-BSi3UHKL.mjs.map +0 -1
  166. package/dist/logger-CG1eop2_.d.mts.map +0 -1
  167. package/dist/logger.mjs.map +0 -1
  168. package/dist/middleware-DojmTj9Y.d.mts.map +0 -1
  169. package/dist/nitro-CfGx0wDJ.d.mts.map +0 -1
  170. package/dist/nitro-Dpq5ZmcM.mjs.map +0 -1
  171. package/dist/parseError-B_qXj8x4.d.mts.map +0 -1
  172. package/dist/types-v_JkG_D7.d.mts.map +0 -1
  173. package/dist/utils.d.mts.map +0 -1
@@ -1 +1 @@
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 const hooks = nitroApp.hooks as unknown as Hooks\n\n // When globally disabled, createRequestLogger returns a no-op logger — still\n // attach it so handlers can call useLogger without throwing.\n if (!isEnabled()) {\n hooks.hook('request', (event) => {\n const { pathname } = parseURL(event.req.url)\n const ctx = getContext(event)\n let requestIdOverride: string | undefined\n if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') {\n const cfRay = event.req.headers.get('cf-ray')\n if (cfRay) requestIdOverride = cfRay\n }\n ctx.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 return\n }\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 { normalizeRedactConfig } from '../redact'\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 const redact = normalizeRedactConfig(evlogConfig?.redact as boolean | Record<string, unknown> | 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 minLevel: evlogConfig?.minLevel,\n redact,\n _suppressDrainWarning: true,\n })\n\n const hooks = nitroApp.hooks as unknown as Hooks\n\n // When globally disabled, createRequestLogger returns a no-op logger — still\n // attach it so handlers can call useLogger without throwing.\n if (!isEnabled()) {\n hooks.hook('request', (event) => {\n const { pathname } = parseURL(event.req.url)\n const ctx = getContext(event)\n let requestIdOverride: string | undefined\n if (globalThis.navigator?.userAgent === 'Cloudflare-Workers') {\n const cfRay = event.req.headers.get('cf-ray')\n if (cfRay) requestIdOverride = cfRay\n }\n ctx.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 return\n }\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-v_JkG_D7.mjs";
1
+ import { _ as RequestLogger } from "../../types-DbzDln7O.mjs";
2
2
  import { HTTPEvent } from "nitro/h3";
3
3
 
4
4
  //#region src/nitro-v3/useLogger.d.ts
@@ -1,4 +1,4 @@
1
- import { a as EnvironmentContext, v as RouteConfig, y as SamplingConfig } from "./types-v_JkG_D7.mjs";
1
+ import { a as EnvironmentContext, b as SamplingConfig, f as LogLevel, h as RedactConfig, y as RouteConfig } from "./types-DbzDln7O.mjs";
2
2
  //#region src/nitro.d.ts
3
3
  interface NitroModuleOptions {
4
4
  /**
@@ -43,7 +43,18 @@ interface NitroModuleOptions {
43
43
  * Sampling configuration for filtering logs.
44
44
  */
45
45
  sampling?: SamplingConfig;
46
+ /**
47
+ * Minimum severity for the global `log` API (not request wide events).
48
+ * Order: debug < info < warn < error.
49
+ * @default 'debug'
50
+ */
51
+ minLevel?: LogLevel;
52
+ /**
53
+ * Auto-redaction configuration for PII protection.
54
+ * `true` enables all built-in PII patterns. Pass an object for fine-grained control.
55
+ */
56
+ redact?: boolean | RedactConfig;
46
57
  }
47
58
  //#endregion
48
59
  export { NitroModuleOptions as t };
49
- //# sourceMappingURL=nitro-CfGx0wDJ.d.mts.map
60
+ //# sourceMappingURL=nitro-CDHLfRdw.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nitro-CDHLfRdw.d.mts","names":[],"sources":["../src/nitro.ts"],"mappings":";;UAKiB,kBAAA;;AAAjB;;;EAKE,OAAA;EAKM;;;EAAN,GAAA,GAAM,OAAA,CAAQ,kBAAA;EA8CH;;;;EAxCX,MAAA;EANA;;;;;;;EAeA,MAAA;EAmBS;;;;;EAZT,OAAA;EA8BA;;;;;EAvBA,OAAA;;;;EAKA,MAAA,GAAS,MAAA,SAAe,WAAA;;;;EAKxB,QAAA,GAAW,cAAA;;;;;;EAOX,QAAA,GAAW,QAAA;;;;;EAMX,MAAA,aAAmB,YAAA;AAAA"}
@@ -1,4 +1,4 @@
1
- import { t as extractErrorStatus } from "./errors-gH4C9KSC.mjs";
1
+ import { t as extractErrorStatus } from "./errors-BJRXUfMg.mjs";
2
2
  //#region src/nitro.ts
3
3
  /**
4
4
  * Resolve an EvlogError from an error or its cause chain.
@@ -31,4 +31,4 @@ function serializeEvlogErrorResponse(error, url) {
31
31
  //#endregion
32
32
  export { serializeEvlogErrorResponse as n, resolveEvlogError as t };
33
33
 
34
- //# sourceMappingURL=nitro-Dpq5ZmcM.mjs.map
34
+ //# sourceMappingURL=nitro-OmT_M4Pb.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nitro-OmT_M4Pb.mjs","names":[],"sources":["../src/nitro.ts"],"sourcesContent":["import type { EnvironmentContext, LogLevel, RedactConfig, RouteConfig, SamplingConfig } from './types'\nimport { extractErrorStatus } from './shared/errors'\n\nexport { shouldLog, getServiceForPath } from './shared/routes'\n\nexport interface NitroModuleOptions {\n /**\n * Enable or disable all logging globally.\n * @default true\n */\n enabled?: boolean\n\n /**\n * Environment context overrides.\n */\n env?: Partial<EnvironmentContext>\n\n /**\n * Enable pretty printing.\n * @default true in development, false in production\n */\n pretty?: boolean\n\n /**\n * Suppress built-in console output.\n * When true, events are still built, sampled, and passed to drains,\n * but nothing is written to console. Use when drains own the output\n * channel (e.g., stdout-based platforms like GCP Cloud Run, AWS Lambda).\n * @default false\n */\n silent?: boolean\n\n /**\n * Route patterns to include in logging.\n * Supports glob patterns like '/api/**'.\n * If not set, all routes are logged.\n */\n include?: string[]\n\n /**\n * Route patterns to exclude from logging.\n * Supports glob patterns like '/_nitro/**'.\n * Exclusions take precedence over inclusions.\n */\n exclude?: string[]\n\n /**\n * Route-specific service configuration.\n */\n routes?: Record<string, RouteConfig>\n\n /**\n * Sampling configuration for filtering logs.\n */\n sampling?: SamplingConfig\n\n /**\n * Minimum severity for the global `log` API (not request wide events).\n * Order: debug < info < warn < error.\n * @default 'debug'\n */\n minLevel?: LogLevel\n\n /**\n * Auto-redaction configuration for PII protection.\n * `true` enables all built-in PII patterns. Pass an object for fine-grained control.\n */\n redact?: boolean | RedactConfig\n}\n\nexport interface EvlogConfig {\n enabled?: boolean\n env?: Record<string, unknown>\n pretty?: boolean\n silent?: boolean\n include?: string[]\n exclude?: string[]\n routes?: Record<string, RouteConfig>\n sampling?: SamplingConfig\n minLevel?: LogLevel\n redact?: boolean | RedactConfig | Record<string, unknown>\n}\n\n/**\n * Resolve an EvlogError from an error or its cause chain.\n * Both Nitro v2 (h3) and v3 wrap thrown errors — this unwraps them.\n */\nexport function resolveEvlogError(error: Error): Error | null {\n if (error.name === 'EvlogError') return error\n if ((error.cause as Error)?.name === 'EvlogError') return error.cause as Error\n return null\n}\n\nexport { extractErrorStatus } from './shared/errors'\n\n/**\n * Build a standard evlog error JSON response body.\n * Used by both v2 and v3 error handlers to ensure consistent shape.\n */\nexport function serializeEvlogErrorResponse(error: Error, url: string): Record<string, unknown> {\n const status = extractErrorStatus(error)\n const { data } = error as { data?: unknown }\n const statusMessage = (error as { statusMessage?: string }).statusMessage || error.message\n return {\n url,\n status,\n statusCode: status,\n statusText: statusMessage,\n statusMessage,\n message: error.message,\n error: true,\n ...(data !== undefined && { data }),\n }\n}\n\n"],"mappings":";;;;;;AAuFA,SAAgB,kBAAkB,OAA4B;AAC5D,KAAI,MAAM,SAAS,aAAc,QAAO;AACxC,KAAK,MAAM,OAAiB,SAAS,aAAc,QAAO,MAAM;AAChE,QAAO;;;;;;AAST,SAAgB,4BAA4B,OAAc,KAAsC;CAC9F,MAAM,SAAS,mBAAmB,MAAM;CACxC,MAAM,EAAE,SAAS;CACjB,MAAM,gBAAiB,MAAqC,iBAAiB,MAAM;AACnF,QAAO;EACL;EACA;EACA,YAAY;EACZ,YAAY;EACZ;EACA,SAAS,MAAM;EACf,OAAO;EACP,GAAI,SAAS,KAAA,KAAa,EAAE,MAAM;EACnC"}
@@ -89,4 +89,4 @@ async function getNitroRuntimeConfigRecord() {
89
89
  //#endregion
90
90
  export { resolveEvlogConfigForNitroPlugin as n, getNitroRuntimeConfigRecord as t };
91
91
 
92
- //# sourceMappingURL=nitroConfigBridge-fidbf-Y_.mjs.map
92
+ //# sourceMappingURL=nitroConfigBridge-C37lXaNm.mjs.map
@@ -1 +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
+ {"version":3,"file":"nitroConfigBridge-C37lXaNm.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,4 +1,4 @@
1
- import { a as EnvironmentContext, f as LogLevel, v as RouteConfig, w as TransportConfig, y as SamplingConfig } from "../types-v_JkG_D7.mjs";
1
+ import { T as TransportConfig, a as EnvironmentContext, b as SamplingConfig, f as LogLevel, h as RedactConfig, y as RouteConfig } from "../types-DbzDln7O.mjs";
2
2
  import * as _$_nuxt_schema0 from "@nuxt/schema";
3
3
 
4
4
  //#region src/nuxt/module.d.ts
@@ -105,6 +105,12 @@ interface ModuleOptions {
105
105
  * ```
106
106
  */
107
107
  sampling?: SamplingConfig;
108
+ /**
109
+ * Minimum severity for the global `log` API on server and client (not request wide events).
110
+ * Order: debug < info < warn < error.
111
+ * @default 'debug'
112
+ */
113
+ minLevel?: LogLevel;
108
114
  /**
109
115
  * Transport configuration for sending client logs to the server.
110
116
  *
@@ -187,6 +193,25 @@ interface ModuleOptions {
187
193
  tags?: Record<string, string>; /** Request timeout in milliseconds. Default: 5000 */
188
194
  timeout?: number;
189
195
  };
196
+ /**
197
+ * Auto-redaction configuration for PII protection.
198
+ * `true` enables all built-in PII patterns (email, credit card, IPv4, phone, SSN).
199
+ * Pass an object for fine-grained control.
200
+ *
201
+ * @example
202
+ * ```ts
203
+ * // Enable all built-in PII patterns
204
+ * evlog: { redact: true }
205
+ *
206
+ * // Add custom paths on top of built-ins
207
+ * evlog: {
208
+ * redact: {
209
+ * paths: ['user.password', 'headers.authorization'],
210
+ * }
211
+ * }
212
+ * ```
213
+ */
214
+ redact?: boolean | RedactConfig;
190
215
  /**
191
216
  * Log levels to strip from production builds. Set to [] to disable.
192
217
  * @default ['debug']
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.mts","names":[],"sources":["../../src/nuxt/module.ts"],"mappings":";;;;UAgBU,qBAAA;;EAER,OAAA;EAFQ;EAIR,KAAA;;EAEA,KAAA;EAJA;EAMA,OAAA;AAAA;AAAA,UAGQ,qBAAA;EAHD;;AAAA;;;EASP,OAAA;EAEO;EAAP,OAAA;AAAA;AAAA,UAGQ,yBAAA;EAER;EAAA,OAAA;EAKG;EAHH,OAAA;AAAA;AAAA,KAGG,iBAAA,GAAoB,qBAAA,IAAyB,qBAAA,GAAwB,yBAAA;AAAA,UAEzD,aAAA;EAFyD;;;;;EAQxE,OAAA;EARiG;;AAEnG;EAWE,GAAA,GAAM,OAAA,CAAQ,kBAAA;;;;;;;EAQd,OAAA;EA4FQ;;;;EAtFR,MAAA;EAoKgB;;;;;;;EA3JhB,MAAA;EAAA;;;;;;EAQA,OAAA;EAyCW;;;;;;EAjCX,OAAA;EAiFE;;;;;;;;;;;;;EAlEF,MAAA,GAAS,MAAA,SAAe,WAAA;EAmHtB;;;;;;;;;AAyBH;;;;;;;EA1HC,QAAA,GAAW,cAAA;;;;;;;;;;;;;EAcX,SAAA,GAAY,eAAA;;;;;;;;;;;;;EAcZ,KAAA,GAAQ,iBAAA;;;;;;;;;;;;;;;EAgBR,IAAA;2DAEE,QAAA;IAEA,WAAA;IAEA,kBAAA,GAAqB,MAAA;IAErB,OAAA,GAAU,MAAA;IAEV,OAAA;EAAA;;;;;;;;;;;;;EAeF,OAAA;kCAEE,MAAA;IAEA,IAAA;IAEA,OAAA;EAAA;;;;;;;;;;;;EAcF,MAAA;qBAEE,GAAA;IAEA,WAAA;IAEA,OAAA;IAEA,IAAA,GAAO,MAAA;IAEP,OAAA;EAAA;;;;;EAOF,KAAA,GAAQ,QAAA;;;;;;;EAQR,cAAA;;;;;;EAOA,SAAA;AAAA;AAAA,cACD,QAAA"}
1
+ {"version":3,"file":"module.d.mts","names":[],"sources":["../../src/nuxt/module.ts"],"mappings":";;;;UAgBU,qBAAA;;EAER,OAAA;EAFQ;EAIR,KAAA;;EAEA,KAAA;EAJA;EAMA,OAAA;AAAA;AAAA,UAGQ,qBAAA;EAHD;;AAAA;;;EASP,OAAA;EAEO;EAAP,OAAA;AAAA;AAAA,UAGQ,yBAAA;EAER;EAAA,OAAA;EAKG;EAHH,OAAA;AAAA;AAAA,KAGG,iBAAA,GAAoB,qBAAA,IAAyB,qBAAA,GAAwB,yBAAA;AAAA,UAEzD,aAAA;EAFyD;;;;;EAQxE,OAAA;EARiG;;AAEnG;EAWE,GAAA,GAAM,OAAA,CAAQ,kBAAA;;;;;;;EAQd,OAAA;EAqFY;;;;EA/EZ,MAAA;EAyLmB;;;;;;;EAhLnB,MAAA;EAfA;;;;;;EAuBA,OAAA;EAuBwB;;;;;;EAfxB,OAAA;EAoEA;;;;;;;;;;;;;EArDA,MAAA,GAAS,MAAA,SAAe,WAAA;EAkHxB;;;;;;;;;;;;;;;AAqDD;EArJC,QAAA,GAAW,cAAA;;;;;;EAOX,QAAA,GAAW,QAAA;;;;;;;;;;;;;EAcX,SAAA,GAAY,eAAA;;;;;;;;;;;;;EAcZ,KAAA,GAAQ,iBAAA;;;;;;;;;;;;;;;EAgBR,IAAA;2DAEE,QAAA;IAEA,WAAA;IAEA,kBAAA,GAAqB,MAAA;IAErB,OAAA,GAAU,MAAA;IAEV,OAAA;EAAA;;;;;;;;;;;;;EAeF,OAAA;kCAEE,MAAA;IAEA,IAAA;IAEA,OAAA;EAAA;;;;;;;;;;;;EAcF,MAAA;qBAEE,GAAA;IAEA,WAAA;IAEA,OAAA;IAEA,IAAA,GAAO,MAAA;IAEP,OAAA;EAAA;;;;;;;;;;;;;;;;;;;EAqBF,MAAA,aAAmB,YAAA;;;;;EAMnB,KAAA,GAAQ,QAAA;;;;;;;EAQR,cAAA;;;;;;EAOA,SAAA;AAAA;AAAA,cACD,QAAA"}
@@ -1,4 +1,4 @@
1
- import { n as createStripPlugin, t as createSourceLocationPlugin } from "../source-location-B1VVgXkh.mjs";
1
+ import { n as createStripPlugin, t as createSourceLocationPlugin } from "../source-location-DRvDDqfq.mjs";
2
2
  import { addImports, addPlugin, addServerHandler, addServerImports, addServerPlugin, addVitePlugin, createResolver, defineNuxtModule } from "@nuxt/kit";
3
3
  //#region package.json
4
4
  var name = "evlog";
@@ -7,7 +7,7 @@ var name = "evlog";
7
7
  var module_default = defineNuxtModule({
8
8
  meta: {
9
9
  name,
10
- version: "2.11.1",
10
+ version: "2.13.0",
11
11
  configKey: name,
12
12
  docs: "https://evlog.dev"
13
13
  },
@@ -27,6 +27,7 @@ var module_default = defineNuxtModule({
27
27
  enabled: options.enabled ?? true,
28
28
  console: options.console,
29
29
  pretty: options.pretty,
30
+ minLevel: options.minLevel,
30
31
  transport: {
31
32
  enabled: transportEnabled,
32
33
  endpoint: transportEndpoint,
@@ -56,6 +57,10 @@ var module_default = defineNuxtModule({
56
57
  name: "clearIdentity",
57
58
  from: resolver.resolve("../runtime/client/log")
58
59
  },
60
+ {
61
+ name: "setMinLevel",
62
+ from: resolver.resolve("../runtime/client/log")
63
+ },
59
64
  {
60
65
  name: "createEvlogError",
61
66
  from: resolver.resolve("../error")
@@ -1 +1 @@
1
- {"version":3,"file":"module.mjs","names":[],"sources":["../../package.json","../../src/nuxt/module.ts"],"sourcesContent":["","import {\n addImports,\n addPlugin,\n addServerHandler,\n addServerImports,\n addServerPlugin,\n addVitePlugin,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit'\nimport type { NitroConfig } from 'nitropack'\nimport type { EnvironmentContext, LogLevel, RouteConfig, SamplingConfig, TransportConfig } from '../types'\nimport { createStripPlugin } from '../vite/strip'\nimport { createSourceLocationPlugin } from '../vite/source-location'\nimport { name, version } from '../../package.json'\n\ninterface ModuleAxiomBaseConfig {\n /** Axiom dataset name */\n dataset: string\n /** Axiom API token */\n token: string\n /** Organization ID (required for Personal Access Tokens) */\n orgId?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n}\n\ninterface ModuleAxiomEdgeConfig {\n /**\n * Edge URL for Axiom ingest/query endpoints.\n * If no path is provided, uses /v1/ingest/{dataset}.\n * If a custom path is provided, it is used as-is (trailing slash trimmed).\n */\n edgeUrl: string\n /** Mutually exclusive with edgeUrl. */\n baseUrl?: never\n}\n\ninterface ModuleAxiomEndpointConfig {\n /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n baseUrl?: string\n /** Mutually exclusive with baseUrl. */\n edgeUrl?: never\n}\n\ntype ModuleAxiomConfig = ModuleAxiomBaseConfig & (ModuleAxiomEdgeConfig | ModuleAxiomEndpointConfig)\n\nexport interface ModuleOptions {\n /**\n * Enable or disable all logging globally.\n * When false, all emits, tagged logs, and request logger operations become no-ops.\n * @default true\n */\n enabled?: boolean\n\n /**\n * Environment context overrides.\n */\n env?: Partial<EnvironmentContext>\n\n /**\n * Enable or disable browser console output.\n * When false, client-side logs are suppressed in the browser DevTools console\n * but still sent to the server via transport (if enabled).\n * @default true\n */\n console?: boolean\n\n /**\n * Enable pretty printing.\n * @default true in development, false in production\n */\n pretty?: boolean\n\n /**\n * Suppress built-in console output.\n * When true, events are still built, sampled, and passed to drains,\n * but nothing is written to console. Use when drains own the output\n * channel (e.g., stdout-based platforms like GCP Cloud Run, AWS Lambda).\n * @default false\n */\n silent?: boolean\n\n /**\n * Route patterns to include in logging.\n * Supports glob patterns like '/api/**'.\n * If not set, all routes are logged.\n * @example ['/api/**', '/auth/**']\n */\n include?: string[]\n\n /**\n * Route patterns to exclude from logging.\n * Supports glob patterns like '/api/_nuxt_icon/**'.\n * Exclusions take precedence over inclusions.\n * @example ['/api/_nuxt_icon/**', '/health']\n */\n exclude?: string[]\n\n /**\n * Route-specific service configuration.\n * Allows setting different service names for different routes.\n * Patterns are matched using glob syntax.\n *\n * @example\n * ```ts\n * routes: {\n * '/api/foo/**': { service: 'service1' },\n * '/api/bar/**': { service: 'service2' }\n * }\n * ```\n */\n routes?: Record<string, RouteConfig>\n\n /**\n * Sampling configuration for filtering logs.\n * Allows configuring what percentage of logs to keep per level.\n *\n * @example\n * ```ts\n * sampling: {\n * rates: {\n * info: 10, // Keep 10% of info logs\n * warn: 50, // Keep 50% of warning logs\n * debug: 5, // Keep 5% of debug logs\n * error: 100, // Always keep errors (default)\n * }\n * }\n * ```\n */\n sampling?: SamplingConfig\n\n /**\n * Transport configuration for sending client logs to the server.\n *\n * @example\n * ```ts\n * transport: {\n * enabled: true, // send client logs to server via API endpoint\n * endpoint: '/api/_evlog/ingest', // default endpoint (or custom endpoint)\n * credentials: 'include', // optional: cross-origin ingest\n * }\n * ```\n */\n transport?: TransportConfig\n\n /**\n * Axiom adapter configuration.\n * When configured, use `createAxiomDrain()` from `evlog/axiom` to send logs.\n *\n * @example\n * ```ts\n * axiom: {\n * dataset: 'my-app-logs',\n * token: process.env.AXIOM_TOKEN,\n * }\n * ```\n */\n axiom?: ModuleAxiomConfig\n\n /**\n * OTLP adapter configuration.\n * When configured, use `createOTLPDrain()` from `evlog/otlp` to send logs.\n *\n * @example\n * ```ts\n * otlp: {\n * endpoint: 'http://localhost:4318',\n * headers: {\n * 'Authorization': `Basic ${process.env.GRAFANA_TOKEN}`,\n * },\n * }\n * ```\n */\n otlp?: {\n /** OTLP HTTP endpoint (e.g., http://localhost:4318) */\n endpoint: string\n /** Override service name (defaults to event.service) */\n serviceName?: string\n /** Additional resource attributes */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Custom headers (e.g., for authentication) */\n headers?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * PostHog adapter configuration.\n * When configured, use `createPostHogDrain()` from `evlog/posthog` to send logs\n * via PostHog Logs (OTLP).\n *\n * @example\n * ```ts\n * posthog: {\n * apiKey: process.env.POSTHOG_API_KEY,\n * }\n * ```\n */\n posthog?: {\n /** PostHog project API key */\n apiKey: string\n /** PostHog host URL. Default: https://us.i.posthog.com */\n host?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * Sentry adapter configuration.\n * When configured, use `createSentryDrain()` from `evlog/sentry` to send logs.\n *\n * @example\n * ```ts\n * sentry: {\n * dsn: process.env.SENTRY_DSN,\n * }\n * ```\n */\n sentry?: {\n /** Sentry DSN */\n dsn: string\n /** Environment override (defaults to event.environment) */\n environment?: string\n /** Release version override (defaults to event.version) */\n release?: string\n /** Additional tags to attach as attributes */\n tags?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * Log levels to strip from production builds. Set to [] to disable.\n * @default ['debug']\n */\n strip?: LogLevel[]\n\n /**\n * Inject source file:line into log calls.\n * When true, active in both dev and prod.\n * When 'dev', active only in development.\n * @default 'dev'\n */\n sourceLocation?: boolean | 'dev'\n\n /**\n * How long to retain events before cleanup (used by @evlog/nuxthub).\n * Supports \"30d\" (days), \"24h\" (hours), \"60m\" (minutes).\n * @default '30d'\n */\n retention?: string\n}\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name,\n version,\n configKey: name,\n docs: 'https://evlog.dev',\n },\n defaults: {},\n setup(options, nuxt) {\n const resolver = createResolver(import.meta.url)\n\n const transportEnabled = options.transport?.enabled ?? false\n const transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n const transportCredentials = options.transport?.credentials ?? 'same-origin'\n\n nuxt.options.runtimeConfig.evlog = options\n\n // Register custom error handler for proper EvlogError serialization\n // Only set if not already configured to avoid overwriting user's custom handler\n // Mirror standalone Nitro modules: serialize evlog options into __EVLOG_CONFIG so\n // resolveEvlogConfigForNitroPlugin() picks them up in dev (Nitro worker threads\n // often cannot resolve useRuntimeConfig().evlog via dynamic import reliably).\n // @ts-expect-error nitro:config hook exists but is not in NuxtHooks type\n nuxt.hook('nitro:config', (nitroConfig: NitroConfig) => {\n nitroConfig.errorHandler = nitroConfig.errorHandler || resolver.resolve('../nitro/errorHandler')\n\n const evlogForNitro = nuxt.options.runtimeConfig.evlog ?? options\n if (evlogForNitro !== undefined && typeof evlogForNitro === 'object') {\n process.env.__EVLOG_CONFIG = JSON.stringify(evlogForNitro)\n }\n })\n nuxt.options.runtimeConfig.public.evlog = {\n enabled: options.enabled ?? true,\n console: options.console,\n pretty: options.pretty,\n transport: {\n enabled: transportEnabled,\n endpoint: transportEndpoint,\n credentials: transportCredentials,\n },\n }\n\n if (transportEnabled) {\n addServerHandler({\n route: transportEndpoint,\n method: 'post',\n handler: resolver.resolve('../runtime/server/routes/_evlog/ingest.post'),\n })\n }\n\n addServerPlugin(resolver.resolve('../nitro/plugin'))\n\n addPlugin({\n src: resolver.resolve('../runtime/client/plugin'),\n mode: 'client',\n })\n\n addImports([\n {\n name: 'log',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'setIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'clearIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n {\n name: 'parseError',\n from: resolver.resolve('../runtime/utils/parseError'),\n },\n ])\n\n addServerImports([\n {\n name: 'useLogger',\n from: resolver.resolve('../runtime/server/useLogger'),\n },\n {\n name: 'log',\n from: resolver.resolve('../logger'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n ])\n\n const stripLevels = options.strip ?? ['debug']\n if (stripLevels.length > 0) {\n addVitePlugin(createStripPlugin(stripLevels))\n }\n\n const srcLoc = options.sourceLocation ?? 'dev'\n if (srcLoc === true || (srcLoc === 'dev' && nuxt.options.dev)) {\n addVitePlugin(createSourceLocationPlugin(true))\n }\n },\n})\n"],"mappings":";;;;;;AC8PA,IAAA,iBAAe,iBAAgC;CAC7C,MAAM;EACJ;EACA;EACA,WAAW;EACX,MAAM;EACP;CACD,UAAU,EAAE;CACZ,MAAM,SAAS,MAAM;EACnB,MAAM,WAAW,eAAe,OAAO,KAAK,IAAI;EAEhD,MAAM,mBAAmB,QAAQ,WAAW,WAAW;EACvD,MAAM,oBAAoB,QAAQ,WAAW,YAAY;EACzD,MAAM,uBAAuB,QAAQ,WAAW,eAAe;AAE/D,OAAK,QAAQ,cAAc,QAAQ;AAQnC,OAAK,KAAK,iBAAiB,gBAA6B;AACtD,eAAY,eAAe,YAAY,gBAAgB,SAAS,QAAQ,wBAAwB;GAEhG,MAAM,gBAAgB,KAAK,QAAQ,cAAc,SAAS;AAC1D,OAAI,kBAAkB,KAAA,KAAa,OAAO,kBAAkB,SAC1D,SAAQ,IAAI,iBAAiB,KAAK,UAAU,cAAc;IAE5D;AACF,OAAK,QAAQ,cAAc,OAAO,QAAQ;GACxC,SAAS,QAAQ,WAAW;GAC5B,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,WAAW;IACT,SAAS;IACT,UAAU;IACV,aAAa;IACd;GACF;AAED,MAAI,iBACF,kBAAiB;GACf,OAAO;GACP,QAAQ;GACR,SAAS,SAAS,QAAQ,8CAA8C;GACzE,CAAC;AAGJ,kBAAgB,SAAS,QAAQ,kBAAkB,CAAC;AAEpD,YAAU;GACR,KAAK,SAAS,QAAQ,2BAA2B;GACjD,MAAM;GACP,CAAC;AAEF,aAAW;GACT;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACF,CAAC;AAEF,mBAAiB;GACf;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,YAAY;IACpC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACF,CAAC;EAEF,MAAM,cAAc,QAAQ,SAAS,CAAC,QAAQ;AAC9C,MAAI,YAAY,SAAS,EACvB,eAAc,kBAAkB,YAAY,CAAC;EAG/C,MAAM,SAAS,QAAQ,kBAAkB;AACzC,MAAI,WAAW,QAAS,WAAW,SAAS,KAAK,QAAQ,IACvD,eAAc,2BAA2B,KAAK,CAAC;;CAGpD,CAAC"}
1
+ {"version":3,"file":"module.mjs","names":[],"sources":["../../package.json","../../src/nuxt/module.ts"],"sourcesContent":["","import {\n addImports,\n addPlugin,\n addServerHandler,\n addServerImports,\n addServerPlugin,\n addVitePlugin,\n createResolver,\n defineNuxtModule,\n} from '@nuxt/kit'\nimport type { NitroConfig } from 'nitropack'\nimport type { EnvironmentContext, LogLevel, RedactConfig, RouteConfig, SamplingConfig, TransportConfig } from '../types'\nimport { createStripPlugin } from '../vite/strip'\nimport { createSourceLocationPlugin } from '../vite/source-location'\nimport { name, version } from '../../package.json'\n\ninterface ModuleAxiomBaseConfig {\n /** Axiom dataset name */\n dataset: string\n /** Axiom API token */\n token: string\n /** Organization ID (required for Personal Access Tokens) */\n orgId?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n}\n\ninterface ModuleAxiomEdgeConfig {\n /**\n * Edge URL for Axiom ingest/query endpoints.\n * If no path is provided, uses /v1/ingest/{dataset}.\n * If a custom path is provided, it is used as-is (trailing slash trimmed).\n */\n edgeUrl: string\n /** Mutually exclusive with edgeUrl. */\n baseUrl?: never\n}\n\ninterface ModuleAxiomEndpointConfig {\n /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n baseUrl?: string\n /** Mutually exclusive with baseUrl. */\n edgeUrl?: never\n}\n\ntype ModuleAxiomConfig = ModuleAxiomBaseConfig & (ModuleAxiomEdgeConfig | ModuleAxiomEndpointConfig)\n\nexport interface ModuleOptions {\n /**\n * Enable or disable all logging globally.\n * When false, all emits, tagged logs, and request logger operations become no-ops.\n * @default true\n */\n enabled?: boolean\n\n /**\n * Environment context overrides.\n */\n env?: Partial<EnvironmentContext>\n\n /**\n * Enable or disable browser console output.\n * When false, client-side logs are suppressed in the browser DevTools console\n * but still sent to the server via transport (if enabled).\n * @default true\n */\n console?: boolean\n\n /**\n * Enable pretty printing.\n * @default true in development, false in production\n */\n pretty?: boolean\n\n /**\n * Suppress built-in console output.\n * When true, events are still built, sampled, and passed to drains,\n * but nothing is written to console. Use when drains own the output\n * channel (e.g., stdout-based platforms like GCP Cloud Run, AWS Lambda).\n * @default false\n */\n silent?: boolean\n\n /**\n * Route patterns to include in logging.\n * Supports glob patterns like '/api/**'.\n * If not set, all routes are logged.\n * @example ['/api/**', '/auth/**']\n */\n include?: string[]\n\n /**\n * Route patterns to exclude from logging.\n * Supports glob patterns like '/api/_nuxt_icon/**'.\n * Exclusions take precedence over inclusions.\n * @example ['/api/_nuxt_icon/**', '/health']\n */\n exclude?: string[]\n\n /**\n * Route-specific service configuration.\n * Allows setting different service names for different routes.\n * Patterns are matched using glob syntax.\n *\n * @example\n * ```ts\n * routes: {\n * '/api/foo/**': { service: 'service1' },\n * '/api/bar/**': { service: 'service2' }\n * }\n * ```\n */\n routes?: Record<string, RouteConfig>\n\n /**\n * Sampling configuration for filtering logs.\n * Allows configuring what percentage of logs to keep per level.\n *\n * @example\n * ```ts\n * sampling: {\n * rates: {\n * info: 10, // Keep 10% of info logs\n * warn: 50, // Keep 50% of warning logs\n * debug: 5, // Keep 5% of debug logs\n * error: 100, // Always keep errors (default)\n * }\n * }\n * ```\n */\n sampling?: SamplingConfig\n\n /**\n * Minimum severity for the global `log` API on server and client (not request wide events).\n * Order: debug < info < warn < error.\n * @default 'debug'\n */\n minLevel?: LogLevel\n\n /**\n * Transport configuration for sending client logs to the server.\n *\n * @example\n * ```ts\n * transport: {\n * enabled: true, // send client logs to server via API endpoint\n * endpoint: '/api/_evlog/ingest', // default endpoint (or custom endpoint)\n * credentials: 'include', // optional: cross-origin ingest\n * }\n * ```\n */\n transport?: TransportConfig\n\n /**\n * Axiom adapter configuration.\n * When configured, use `createAxiomDrain()` from `evlog/axiom` to send logs.\n *\n * @example\n * ```ts\n * axiom: {\n * dataset: 'my-app-logs',\n * token: process.env.AXIOM_TOKEN,\n * }\n * ```\n */\n axiom?: ModuleAxiomConfig\n\n /**\n * OTLP adapter configuration.\n * When configured, use `createOTLPDrain()` from `evlog/otlp` to send logs.\n *\n * @example\n * ```ts\n * otlp: {\n * endpoint: 'http://localhost:4318',\n * headers: {\n * 'Authorization': `Basic ${process.env.GRAFANA_TOKEN}`,\n * },\n * }\n * ```\n */\n otlp?: {\n /** OTLP HTTP endpoint (e.g., http://localhost:4318) */\n endpoint: string\n /** Override service name (defaults to event.service) */\n serviceName?: string\n /** Additional resource attributes */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Custom headers (e.g., for authentication) */\n headers?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * PostHog adapter configuration.\n * When configured, use `createPostHogDrain()` from `evlog/posthog` to send logs\n * via PostHog Logs (OTLP).\n *\n * @example\n * ```ts\n * posthog: {\n * apiKey: process.env.POSTHOG_API_KEY,\n * }\n * ```\n */\n posthog?: {\n /** PostHog project API key */\n apiKey: string\n /** PostHog host URL. Default: https://us.i.posthog.com */\n host?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * Sentry adapter configuration.\n * When configured, use `createSentryDrain()` from `evlog/sentry` to send logs.\n *\n * @example\n * ```ts\n * sentry: {\n * dsn: process.env.SENTRY_DSN,\n * }\n * ```\n */\n sentry?: {\n /** Sentry DSN */\n dsn: string\n /** Environment override (defaults to event.environment) */\n environment?: string\n /** Release version override (defaults to event.version) */\n release?: string\n /** Additional tags to attach as attributes */\n tags?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n }\n\n /**\n * Auto-redaction configuration for PII protection.\n * `true` enables all built-in PII patterns (email, credit card, IPv4, phone, SSN).\n * Pass an object for fine-grained control.\n *\n * @example\n * ```ts\n * // Enable all built-in PII patterns\n * evlog: { redact: true }\n *\n * // Add custom paths on top of built-ins\n * evlog: {\n * redact: {\n * paths: ['user.password', 'headers.authorization'],\n * }\n * }\n * ```\n */\n redact?: boolean | RedactConfig\n\n /**\n * Log levels to strip from production builds. Set to [] to disable.\n * @default ['debug']\n */\n strip?: LogLevel[]\n\n /**\n * Inject source file:line into log calls.\n * When true, active in both dev and prod.\n * When 'dev', active only in development.\n * @default 'dev'\n */\n sourceLocation?: boolean | 'dev'\n\n /**\n * How long to retain events before cleanup (used by @evlog/nuxthub).\n * Supports \"30d\" (days), \"24h\" (hours), \"60m\" (minutes).\n * @default '30d'\n */\n retention?: string\n}\n\nexport default defineNuxtModule<ModuleOptions>({\n meta: {\n name,\n version,\n configKey: name,\n docs: 'https://evlog.dev',\n },\n defaults: {},\n setup(options, nuxt) {\n const resolver = createResolver(import.meta.url)\n\n const transportEnabled = options.transport?.enabled ?? false\n const transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n const transportCredentials = options.transport?.credentials ?? 'same-origin'\n\n nuxt.options.runtimeConfig.evlog = options\n\n // Register custom error handler for proper EvlogError serialization\n // Only set if not already configured to avoid overwriting user's custom handler\n // Mirror standalone Nitro modules: serialize evlog options into __EVLOG_CONFIG so\n // resolveEvlogConfigForNitroPlugin() picks them up in dev (Nitro worker threads\n // often cannot resolve useRuntimeConfig().evlog via dynamic import reliably).\n // @ts-expect-error nitro:config hook exists but is not in NuxtHooks type\n nuxt.hook('nitro:config', (nitroConfig: NitroConfig) => {\n nitroConfig.errorHandler = nitroConfig.errorHandler || resolver.resolve('../nitro/errorHandler')\n\n const evlogForNitro = nuxt.options.runtimeConfig.evlog ?? options\n if (evlogForNitro !== undefined && typeof evlogForNitro === 'object') {\n process.env.__EVLOG_CONFIG = JSON.stringify(evlogForNitro)\n }\n })\n nuxt.options.runtimeConfig.public.evlog = {\n enabled: options.enabled ?? true,\n console: options.console,\n pretty: options.pretty,\n minLevel: options.minLevel,\n transport: {\n enabled: transportEnabled,\n endpoint: transportEndpoint,\n credentials: transportCredentials,\n },\n }\n\n if (transportEnabled) {\n addServerHandler({\n route: transportEndpoint,\n method: 'post',\n handler: resolver.resolve('../runtime/server/routes/_evlog/ingest.post'),\n })\n }\n\n addServerPlugin(resolver.resolve('../nitro/plugin'))\n\n addPlugin({\n src: resolver.resolve('../runtime/client/plugin'),\n mode: 'client',\n })\n\n addImports([\n {\n name: 'log',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'setIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'clearIdentity',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'setMinLevel',\n from: resolver.resolve('../runtime/client/log'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n {\n name: 'parseError',\n from: resolver.resolve('../runtime/utils/parseError'),\n },\n ])\n\n addServerImports([\n {\n name: 'useLogger',\n from: resolver.resolve('../runtime/server/useLogger'),\n },\n {\n name: 'log',\n from: resolver.resolve('../logger'),\n },\n {\n name: 'createEvlogError',\n from: resolver.resolve('../error'),\n },\n ])\n\n const stripLevels = options.strip ?? ['debug']\n if (stripLevels.length > 0) {\n addVitePlugin(createStripPlugin(stripLevels))\n }\n\n const srcLoc = options.sourceLocation ?? 'dev'\n if (srcLoc === true || (srcLoc === 'dev' && nuxt.options.dev)) {\n addVitePlugin(createSourceLocationPlugin(true))\n }\n },\n})\n"],"mappings":";;;;;;ACyRA,IAAA,iBAAe,iBAAgC;CAC7C,MAAM;EACJ;EACA;EACA,WAAW;EACX,MAAM;EACP;CACD,UAAU,EAAE;CACZ,MAAM,SAAS,MAAM;EACnB,MAAM,WAAW,eAAe,OAAO,KAAK,IAAI;EAEhD,MAAM,mBAAmB,QAAQ,WAAW,WAAW;EACvD,MAAM,oBAAoB,QAAQ,WAAW,YAAY;EACzD,MAAM,uBAAuB,QAAQ,WAAW,eAAe;AAE/D,OAAK,QAAQ,cAAc,QAAQ;AAQnC,OAAK,KAAK,iBAAiB,gBAA6B;AACtD,eAAY,eAAe,YAAY,gBAAgB,SAAS,QAAQ,wBAAwB;GAEhG,MAAM,gBAAgB,KAAK,QAAQ,cAAc,SAAS;AAC1D,OAAI,kBAAkB,KAAA,KAAa,OAAO,kBAAkB,SAC1D,SAAQ,IAAI,iBAAiB,KAAK,UAAU,cAAc;IAE5D;AACF,OAAK,QAAQ,cAAc,OAAO,QAAQ;GACxC,SAAS,QAAQ,WAAW;GAC5B,SAAS,QAAQ;GACjB,QAAQ,QAAQ;GAChB,UAAU,QAAQ;GAClB,WAAW;IACT,SAAS;IACT,UAAU;IACV,aAAa;IACd;GACF;AAED,MAAI,iBACF,kBAAiB;GACf,OAAO;GACP,QAAQ;GACR,SAAS,SAAS,QAAQ,8CAA8C;GACzE,CAAC;AAGJ,kBAAgB,SAAS,QAAQ,kBAAkB,CAAC;AAEpD,YAAU;GACR,KAAK,SAAS,QAAQ,2BAA2B;GACjD,MAAM;GACP,CAAC;AAEF,aAAW;GACT;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,wBAAwB;IAChD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACF,CAAC;AAEF,mBAAiB;GACf;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,8BAA8B;IACtD;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,YAAY;IACpC;GACD;IACE,MAAM;IACN,MAAM,SAAS,QAAQ,WAAW;IACnC;GACF,CAAC;EAEF,MAAM,cAAc,QAAQ,SAAS,CAAC,QAAQ;AAC9C,MAAI,YAAY,SAAS,EACvB,eAAc,kBAAkB,YAAY,CAAC;EAG/C,MAAM,SAAS,QAAQ,kBAAkB;AACzC,MAAI,WAAW,QAAS,WAAW,SAAS,KAAK,QAAQ,IACvD,eAAc,2BAA2B,KAAK,CAAC;;CAGpD,CAAC"}
@@ -1,7 +1,7 @@
1
- import { m as ParsedError } from "./types-v_JkG_D7.mjs";
1
+ import { m as ParsedError } from "./types-DbzDln7O.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-B_qXj8x4.d.mts.map
7
+ //# sourceMappingURL=parseError-DM-lyezZ.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseError-DM-lyezZ.d.mts","names":[],"sources":["../src/runtime/utils/parseError.ts"],"mappings":";;;iBAMgB,UAAA,CAAW,KAAA,YAAiB,WAAA"}
@@ -1,5 +1,5 @@
1
- import { g as RequestLogger } from "../types-v_JkG_D7.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-DojmTj9Y.mjs";
1
+ import { _ as RequestLogger } from "../types-DbzDln7O.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-FgC1OdOD.mjs";
3
3
  import * as _$react_router0 from "react-router";
4
4
 
5
5
  //#region src/react-router/index.d.ts
@@ -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,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
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/react-router/index.ts"],"mappings":";;;;;cAOiB,SAAA,sBAAS,MAAA,wBAAA,aAAA,CAAA,CAAA;;;AAL0D;;;;;;;;;;;;cAuBvE,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,7 @@
1
- import { r as createMiddlewareLogger, t as extractSafeHeaders } from "../headers-BSi3UHKL.mjs";
2
- import { t as createLoggerStorage } from "../storage-B6NPh8rV.mjs";
1
+ import { t as createMiddlewareLogger } from "../middleware-BtBuosFV.mjs";
2
+ import { t as attachForkToLogger } from "../fork-Y4z8iHti.mjs";
3
+ import { t as extractSafeHeaders } from "../headers-D74M0wsg.mjs";
4
+ import { t as createLoggerStorage } from "../storage-CFGTn37X.mjs";
3
5
  import { createContext } from "react-router";
4
6
  //#region src/react-router/index.ts
5
7
  const { storage, useLogger } = createLoggerStorage("middleware context. Make sure the evlog middleware is added to your route.");
@@ -34,14 +36,16 @@ const loggerContext = createContext();
34
36
  function evlog(options = {}) {
35
37
  return async ({ request, context }, next) => {
36
38
  const url = new URL(request.url);
37
- const { logger, finish, skipped } = createMiddlewareLogger({
39
+ const middlewareOpts = {
38
40
  method: request.method,
39
41
  path: url.pathname,
40
42
  requestId: request.headers.get("x-request-id") || crypto.randomUUID(),
41
43
  headers: extractSafeHeaders(request.headers),
42
44
  ...options
43
- });
45
+ };
46
+ const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts);
44
47
  if (skipped) return next();
48
+ attachForkToLogger(storage, logger, middlewareOpts);
45
49
  context.set(loggerContext, logger);
46
50
  try {
47
51
  const response = await storage.run(logger, () => next());
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react-router/index.ts"],"sourcesContent":["import { createContext } from 'react-router'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure the evlog middleware is added to your route.',\n)\n\n/**\n * Typed context key for accessing the evlog logger in loaders and actions.\n *\n * @example\n * ```ts\n * import { loggerContext } from 'evlog/react-router'\n *\n * export async function loader({ context }: Route.LoaderArgs) {\n * const log = context.get(loggerContext)\n * log.set({ user: { id: 'u-1' } })\n * return { ok: true }\n * }\n * ```\n */\nexport const loggerContext = createContext<RequestLogger>()\n\nexport type EvlogReactRouterOptions = BaseEvlogOptions\n\nexport { useLogger }\n\n/**\n * Create an evlog middleware for React Router.\n *\n * @example\n * ```ts\n * // app/root.tsx\n * import { evlog } from 'evlog/react-router'\n *\n * export const middleware: Route.MiddlewareFunction[] = [\n * evlog({ drain: createAxiomDrain() }),\n * ]\n * ```\n */\nexport function evlog(options: EvlogReactRouterOptions = {}) {\n return async (\n { request, context }: { request: Request; context: { set(ctx: unknown, value: unknown): void } },\n next: () => Promise<Response>,\n ): Promise<Response> => {\n const url = new URL(request.url)\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: request.method,\n path: url.pathname,\n requestId: request.headers.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(request.headers),\n ...options,\n })\n\n if (skipped) {\n return next()\n }\n\n context.set(loggerContext, logger)\n\n try {\n const response = await storage.run(logger, () => next())\n await finish({ status: response.status })\n return response\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;AAMA,MAAM,EAAE,SAAS,cAAc,oBAC7B,6EACD;;;;;;;;;;;;;;;AAgBD,MAAa,gBAAgB,eAA8B;;;;;;;;;;;;;;AAmB3D,SAAgB,MAAM,UAAmC,EAAE,EAAE;AAC3D,QAAO,OACL,EAAE,SAAS,WACX,SACsB;EACtB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,QAAQ;GAChB,MAAM,IAAI;GACV,WAAW,QAAQ,QAAQ,IAAI,eAAe,IAAI,OAAO,YAAY;GACrE,SAAS,mBAAmB,QAAQ,QAAQ;GAC5C,GAAG;GACJ,CAAC;AAEF,MAAI,QACF,QAAO,MAAM;AAGf,UAAQ,IAAI,eAAe,OAAO;AAElC,MAAI;GACF,MAAM,WAAW,MAAM,QAAQ,IAAI,cAAc,MAAM,CAAC;AACxD,SAAM,OAAO,EAAE,QAAQ,SAAS,QAAQ,CAAC;AACzC,UAAO;WACA,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react-router/index.ts"],"sourcesContent":["import { createContext } from 'react-router'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { attachForkToLogger } from '../shared/fork'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure the evlog middleware is added to your route.',\n)\n\n/**\n * Typed context key for accessing the evlog logger in loaders and actions.\n *\n * @example\n * ```ts\n * import { loggerContext } from 'evlog/react-router'\n *\n * export async function loader({ context }: Route.LoaderArgs) {\n * const log = context.get(loggerContext)\n * log.set({ user: { id: 'u-1' } })\n * return { ok: true }\n * }\n * ```\n */\nexport const loggerContext = createContext<RequestLogger>()\n\nexport type EvlogReactRouterOptions = BaseEvlogOptions\n\nexport { useLogger }\n\n/**\n * Create an evlog middleware for React Router.\n *\n * @example\n * ```ts\n * // app/root.tsx\n * import { evlog } from 'evlog/react-router'\n *\n * export const middleware: Route.MiddlewareFunction[] = [\n * evlog({ drain: createAxiomDrain() }),\n * ]\n * ```\n */\nexport function evlog(options: EvlogReactRouterOptions = {}) {\n return async (\n { request, context }: { request: Request; context: { set(ctx: unknown, value: unknown): void } },\n next: () => Promise<Response>,\n ): Promise<Response> => {\n const url = new URL(request.url)\n const middlewareOpts = {\n method: request.method,\n path: url.pathname,\n requestId: request.headers.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(request.headers),\n ...options,\n }\n const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts)\n\n if (skipped) {\n return next()\n }\n\n attachForkToLogger(storage, logger, middlewareOpts)\n context.set(loggerContext, logger)\n\n try {\n const response = await storage.run(logger, () => next())\n await finish({ status: response.status })\n return response\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,6EACD;;;;;;;;;;;;;;;AAgBD,MAAa,gBAAgB,eAA8B;;;;;;;;;;;;;;AAmB3D,SAAgB,MAAM,UAAmC,EAAE,EAAE;AAC3D,QAAO,OACL,EAAE,SAAS,WACX,SACsB;EACtB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,iBAAiB;GACrB,QAAQ,QAAQ;GAChB,MAAM,IAAI;GACV,WAAW,QAAQ,QAAQ,IAAI,eAAe,IAAI,OAAO,YAAY;GACrE,SAAS,mBAAmB,QAAQ,QAAQ;GAC5C,GAAG;GACJ;EACD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB,eAAe;AAE1E,MAAI,QACF,QAAO,MAAM;AAGf,qBAAmB,SAAS,QAAQ,eAAe;AACnD,UAAQ,IAAI,eAAe,OAAO;AAElC,MAAI;GACF,MAAM,WAAW,MAAM,QAAQ,IAAI,cAAc,MAAM,CAAC;AACxD,SAAM,OAAO,EAAE,QAAQ,SAAS,QAAQ,CAAC;AACzC,UAAO;WACA,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
@@ -35,4 +35,4 @@ function getServiceForPath(path, routes) {
35
35
  //#endregion
36
36
  export { shouldLog as n, getServiceForPath as t };
37
37
 
38
- //# sourceMappingURL=routes-CE3_c-iZ.mjs.map
38
+ //# sourceMappingURL=routes-CGPmbzCZ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes-CE3_c-iZ.mjs","names":[],"sources":["../src/shared/routes.ts"],"sourcesContent":["import type { RouteConfig } from '../types'\nimport { matchesPattern } from '../utils'\n\nexport function shouldLog(path: string, include?: string[], exclude?: string[]): boolean {\n // Check exclusions first (they take precedence)\n if (exclude && exclude.length > 0) {\n if (exclude.some(pattern => matchesPattern(path, pattern))) {\n return false\n }\n }\n\n // If no include patterns, log everything (that wasn't excluded)\n if (!include || include.length === 0) {\n return true\n }\n\n // Log only if path matches at least one include pattern\n return include.some(pattern => matchesPattern(path, pattern))\n}\n\n/**\n * Find the service name for a given path based on route patterns.\n *\n * When multiple patterns match the same path, the first matching pattern wins\n * based on object iteration order. To ensure predictable behavior, order your\n * route patterns from most specific to most general.\n *\n * @param path - The request path to match\n * @param routes - Route configuration mapping patterns to service names\n * @returns The service name for the matching route, or undefined if no match\n *\n * @example\n * ```ts\n * // Good: specific patterns first, general patterns last\n * routes: {\n * '/api/auth/admin/**': { service: 'admin-service' },\n * '/api/auth/**': { service: 'auth-service' },\n * '/api/**': { service: 'api-service' },\n * }\n * ```\n */\nexport function getServiceForPath(path: string, routes?: Record<string, RouteConfig>): string | undefined {\n if (!routes) return undefined\n\n for (const [pattern, config] of Object.entries(routes)) {\n if (matchesPattern(path, pattern)) {\n return config.service\n }\n }\n\n return undefined\n}\n"],"mappings":";;AAGA,SAAgB,UAAU,MAAc,SAAoB,SAA6B;AAEvF,KAAI,WAAW,QAAQ,SAAS;MAC1B,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC,CACxD,QAAO;;AAKX,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,QAAO;AAIT,QAAO,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;AAwB/D,SAAgB,kBAAkB,MAAc,QAA0D;AACxG,KAAI,CAAC,OAAQ,QAAO,KAAA;AAEpB,MAAK,MAAM,CAAC,SAAS,WAAW,OAAO,QAAQ,OAAO,CACpD,KAAI,eAAe,MAAM,QAAQ,CAC/B,QAAO,OAAO"}
1
+ {"version":3,"file":"routes-CGPmbzCZ.mjs","names":[],"sources":["../src/shared/routes.ts"],"sourcesContent":["import type { RouteConfig } from '../types'\nimport { matchesPattern } from '../utils'\n\nexport function shouldLog(path: string, include?: string[], exclude?: string[]): boolean {\n // Check exclusions first (they take precedence)\n if (exclude && exclude.length > 0) {\n if (exclude.some(pattern => matchesPattern(path, pattern))) {\n return false\n }\n }\n\n // If no include patterns, log everything (that wasn't excluded)\n if (!include || include.length === 0) {\n return true\n }\n\n // Log only if path matches at least one include pattern\n return include.some(pattern => matchesPattern(path, pattern))\n}\n\n/**\n * Find the service name for a given path based on route patterns.\n *\n * When multiple patterns match the same path, the first matching pattern wins\n * based on object iteration order. To ensure predictable behavior, order your\n * route patterns from most specific to most general.\n *\n * @param path - The request path to match\n * @param routes - Route configuration mapping patterns to service names\n * @returns The service name for the matching route, or undefined if no match\n *\n * @example\n * ```ts\n * // Good: specific patterns first, general patterns last\n * routes: {\n * '/api/auth/admin/**': { service: 'admin-service' },\n * '/api/auth/**': { service: 'auth-service' },\n * '/api/**': { service: 'api-service' },\n * }\n * ```\n */\nexport function getServiceForPath(path: string, routes?: Record<string, RouteConfig>): string | undefined {\n if (!routes) return undefined\n\n for (const [pattern, config] of Object.entries(routes)) {\n if (matchesPattern(path, pattern)) {\n return config.service\n }\n }\n\n return undefined\n}\n"],"mappings":";;AAGA,SAAgB,UAAU,MAAc,SAAoB,SAA6B;AAEvF,KAAI,WAAW,QAAQ,SAAS;MAC1B,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC,CACxD,QAAO;;AAKX,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,QAAO;AAIT,QAAO,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;AAwB/D,SAAgB,kBAAkB,MAAc,QAA0D;AACxG,KAAI,CAAC,OAAQ,QAAO,KAAA;AAEpB,MAAK,MAAM,CAAC,SAAS,WAAW,OAAO,QAAQ,OAAO,CACpD,KAAI,eAAe,MAAM,QAAQ,CAC/B,QAAO,OAAO"}
@@ -1,4 +1,4 @@
1
- import { d as Log, w as TransportConfig } from "../../types-v_JkG_D7.mjs";
1
+ import { T as TransportConfig, d as Log, f as LogLevel } from "../../types-DbzDln7O.mjs";
2
2
 
3
3
  //#region src/runtime/client/log.d.ts
4
4
  declare function setIdentity(identity: Record<string, unknown>): void;
@@ -7,10 +7,15 @@ declare function initLog(options?: {
7
7
  enabled?: boolean;
8
8
  console?: boolean;
9
9
  pretty?: boolean;
10
+ minLevel?: LogLevel;
10
11
  service?: string;
11
12
  transport?: TransportConfig;
12
13
  }): void;
14
+ /**
15
+ * Update the minimum log level at runtime (e.g. enable verbose client logs from a debug toggle).
16
+ */
17
+ declare function setMinLevel(level: LogLevel): void;
13
18
  declare const _clientLog: Log;
14
19
  //#endregion
15
- export { clearIdentity, initLog, _clientLog as log, setIdentity };
20
+ export { clearIdentity, initLog, _clientLog as log, setIdentity, setMinLevel };
16
21
  //# sourceMappingURL=log.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"log.d.mts","names":[],"sources":["../../../src/runtime/client/log.ts"],"mappings":";;;iBAcgB,WAAA,CAAY,QAAA,EAAU,MAAA;AAAA,iBAItB,aAAA,CAAA;AAAA,iBAKA,OAAA,CAAQ,OAAA;EAAW,OAAA;EAAmB,OAAA;EAAmB,MAAA;EAAkB,OAAA;EAAkB,SAAA,GAAY,eAAA;AAAA;AAAA,cAqFnH,UAAA,EAAY,GAAA"}
1
+ {"version":3,"file":"log.d.mts","names":[],"sources":["../../../src/runtime/client/log.ts"],"mappings":";;;iBAuBgB,WAAA,CAAY,QAAA,EAAU,MAAA;AAAA,iBAItB,aAAA,CAAA;AAAA,iBAKA,OAAA,CAAQ,OAAA;EAAW,OAAA;EAAmB,OAAA;EAAmB,MAAA;EAAkB,QAAA,GAAW,QAAA;EAAU,OAAA;EAAkB,SAAA,GAAY,eAAA;AAAA;;;AAA9I;iBAcgB,WAAA,CAAY,KAAA,EAAO,QAAA;AAAA,cAkF7B,UAAA,EAAY,GAAA"}
@@ -1,9 +1,18 @@
1
- import { cssColors, escapeFormatString, getConsoleMethod, getCssLevelColor } from "../../utils.mjs";
1
+ import { cssColors, escapeFormatString, getCssLevelColor, isLevelEnabled } from "../../utils.mjs";
2
2
  //#region src/runtime/client/log.ts
3
- const isClient = typeof window !== "undefined";
3
+ /**
4
+ * Browser DevTools often hide or bucket `console.debug` under "Verbose" in a way that looks like
5
+ * nothing happened. Use `console.log` for debug-level client output so it shows with the default
6
+ * Info filter; the structured payload still has `level: 'debug'`.
7
+ */
8
+ function browserConsoleMethod(level) {
9
+ if (level === "debug") return "log";
10
+ return level;
11
+ }
4
12
  let clientEnabled = true;
5
13
  let clientConsole = true;
6
14
  let clientPretty = true;
15
+ let clientMinLevel = "debug";
7
16
  let clientService = "client";
8
17
  let transportEnabled = false;
9
18
  let transportEndpoint = "/api/_evlog/ingest";
@@ -19,11 +28,18 @@ function initLog(options = {}) {
19
28
  clientEnabled = typeof options.enabled === "boolean" ? options.enabled : true;
20
29
  clientConsole = typeof options.console === "boolean" ? options.console : true;
21
30
  clientPretty = typeof options.pretty === "boolean" ? options.pretty : true;
31
+ clientMinLevel = options.minLevel ?? "debug";
22
32
  clientService = options.service ?? "client";
23
33
  transportEnabled = options.transport?.enabled ?? false;
24
34
  transportEndpoint = options.transport?.endpoint ?? "/api/_evlog/ingest";
25
35
  transportCredentials = options.transport?.credentials ?? "same-origin";
26
36
  }
37
+ /**
38
+ * Update the minimum log level at runtime (e.g. enable verbose client logs from a debug toggle).
39
+ */
40
+ function setMinLevel(level) {
41
+ clientMinLevel = level;
42
+ }
27
43
  async function sendToServer(event) {
28
44
  if (!transportEnabled) return;
29
45
  try {
@@ -38,6 +54,7 @@ async function sendToServer(event) {
38
54
  }
39
55
  function emitLog(level, event) {
40
56
  if (!clientEnabled) return;
57
+ if (!isLevelEnabled(level, clientMinLevel)) return;
41
58
  const formatted = {
42
59
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
43
60
  level,
@@ -46,7 +63,7 @@ function emitLog(level, event) {
46
63
  ...event
47
64
  };
48
65
  if (clientConsole) {
49
- const method = getConsoleMethod(level);
66
+ const method = browserConsoleMethod(level);
50
67
  if (clientPretty) {
51
68
  const { level: lvl, service, ...rest } = formatted;
52
69
  console[method](`%c[${escapeFormatString(String(service))}]%c ${lvl}`, getCssLevelColor(lvl), cssColors.reset, rest);
@@ -56,8 +73,9 @@ function emitLog(level, event) {
56
73
  }
57
74
  function emitTaggedLog(level, tag, message) {
58
75
  if (!clientEnabled) return;
76
+ if (!isLevelEnabled(level, clientMinLevel)) return;
59
77
  if (clientPretty) {
60
- if (clientConsole) console[getConsoleMethod(level)](`%c[${escapeFormatString(tag)}]%c ${escapeFormatString(message)}`, getCssLevelColor(level), cssColors.reset);
78
+ if (clientConsole) console[browserConsoleMethod(level)](`%c[${escapeFormatString(tag)}]%c ${escapeFormatString(message)}`, getCssLevelColor(level), cssColors.reset);
61
79
  sendToServer({
62
80
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
63
81
  level,
@@ -73,7 +91,7 @@ function emitTaggedLog(level, tag, message) {
73
91
  }
74
92
  function createLogMethod(level) {
75
93
  return function logMethod(tagOrEvent, message) {
76
- if (!(import.meta.client ?? isClient)) return;
94
+ if (typeof window === "undefined") return;
77
95
  if (typeof tagOrEvent === "string" && message !== void 0) emitTaggedLog(level, tagOrEvent, message);
78
96
  else if (typeof tagOrEvent === "object") emitLog(level, tagOrEvent);
79
97
  else emitTaggedLog(level, "log", String(tagOrEvent));
@@ -86,6 +104,6 @@ const _clientLog = {
86
104
  debug: createLogMethod("debug")
87
105
  };
88
106
  //#endregion
89
- export { clearIdentity, initLog, _clientLog as log, setIdentity };
107
+ export { clearIdentity, initLog, _clientLog as log, setIdentity, setMinLevel };
90
108
 
91
109
  //# sourceMappingURL=log.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"log.mjs","names":[],"sources":["../../../src/runtime/client/log.ts"],"sourcesContent":["import type { Log, LogLevel, TransportConfig } from '../../types'\nimport { cssColors, escapeFormatString, getConsoleMethod, getCssLevelColor } from '../../utils'\n\nconst isClient = typeof window !== 'undefined'\n\nlet clientEnabled = true\nlet clientConsole = true\nlet clientPretty = true\nlet clientService = 'client'\nlet transportEnabled = false\nlet transportEndpoint = '/api/_evlog/ingest'\nlet transportCredentials: RequestCredentials = 'same-origin'\nlet identityContext: Record<string, unknown> = {}\n\nexport function setIdentity(identity: Record<string, unknown>): void {\n identityContext = { ...identity }\n}\n\nexport function clearIdentity(): void {\n identityContext = {}\n}\n\n\nexport function initLog(options: { enabled?: boolean, console?: boolean, pretty?: boolean, service?: string, transport?: TransportConfig } = {}): void {\n clientEnabled = typeof options.enabled === 'boolean' ? options.enabled : true\n clientConsole = typeof options.console === 'boolean' ? options.console : true\n clientPretty = typeof options.pretty === 'boolean' ? options.pretty : true\n clientService = options.service ?? 'client'\n transportEnabled = options.transport?.enabled ?? false\n transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n transportCredentials = options.transport?.credentials ?? 'same-origin'\n}\n\nasync function sendToServer(event: Record<string, unknown>): Promise<void> {\n if (!transportEnabled) return\n\n try {\n await fetch(transportEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(event),\n keepalive: true,\n credentials: transportCredentials,\n })\n } catch {\n // Silently fail - don't break the app\n }\n}\n\nfunction emitLog(level: LogLevel, event: Record<string, unknown>): void {\n if (!clientEnabled) return\n\n const formatted = {\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n ...event,\n }\n\n if (clientConsole) {\n const method = getConsoleMethod(level)\n if (clientPretty) {\n const { level: lvl, service, ...rest } = formatted\n console[method](`%c[${escapeFormatString(String(service))}]%c ${lvl}`, getCssLevelColor(lvl), cssColors.reset, rest)\n } else {\n console[method](JSON.stringify(formatted))\n }\n }\n\n sendToServer(formatted)\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!clientEnabled) return\n if (clientPretty) {\n if (clientConsole) {\n console[getConsoleMethod(level)](`%c[${escapeFormatString(tag)}]%c ${escapeFormatString(message)}`, getCssLevelColor(level), cssColors.reset)\n }\n sendToServer({\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n tag,\n message,\n })\n } else {\n emitLog(level, { tag, message })\n }\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n if (!(import.meta.client ?? isClient)) {\n return\n }\n\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitLog(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\nconst _clientLog: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _clientLog as log }\n"],"mappings":";;AAGA,MAAM,WAAW,OAAO,WAAW;AAEnC,IAAI,gBAAgB;AACpB,IAAI,gBAAgB;AACpB,IAAI,eAAe;AACnB,IAAI,gBAAgB;AACpB,IAAI,mBAAmB;AACvB,IAAI,oBAAoB;AACxB,IAAI,uBAA2C;AAC/C,IAAI,kBAA2C,EAAE;AAEjD,SAAgB,YAAY,UAAyC;AACnE,mBAAkB,EAAE,GAAG,UAAU;;AAGnC,SAAgB,gBAAsB;AACpC,mBAAkB,EAAE;;AAItB,SAAgB,QAAQ,UAAqH,EAAE,EAAQ;AACrJ,iBAAgB,OAAO,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACzE,iBAAgB,OAAO,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACzE,gBAAe,OAAO,QAAQ,WAAW,YAAY,QAAQ,SAAS;AACtE,iBAAgB,QAAQ,WAAW;AACnC,oBAAmB,QAAQ,WAAW,WAAW;AACjD,qBAAoB,QAAQ,WAAW,YAAY;AACnD,wBAAuB,QAAQ,WAAW,eAAe;;AAG3D,eAAe,aAAa,OAA+C;AACzE,KAAI,CAAC,iBAAkB;AAEvB,KAAI;AACF,QAAM,MAAM,mBAAmB;GAC7B,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,MAAM;GAC3B,WAAW;GACX,aAAa;GACd,CAAC;SACI;;AAKV,SAAS,QAAQ,OAAiB,OAAsC;AACtE,KAAI,CAAC,cAAe;CAEpB,MAAM,YAAY;EAChB,4BAAW,IAAI,MAAM,EAAC,aAAa;EACnC;EACA,SAAS;EACT,GAAG;EACH,GAAG;EACJ;AAED,KAAI,eAAe;EACjB,MAAM,SAAS,iBAAiB,MAAM;AACtC,MAAI,cAAc;GAChB,MAAM,EAAE,OAAO,KAAK,SAAS,GAAG,SAAS;AACzC,WAAQ,QAAQ,MAAM,mBAAmB,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,iBAAiB,IAAI,EAAE,UAAU,OAAO,KAAK;QAEpH,SAAQ,QAAQ,KAAK,UAAU,UAAU,CAAC;;AAI9C,cAAa,UAAU;;AAGzB,SAAS,cAAc,OAAiB,KAAa,SAAuB;AAC1E,KAAI,CAAC,cAAe;AACpB,KAAI,cAAc;AAChB,MAAI,cACF,SAAQ,iBAAiB,MAAM,EAAE,MAAM,mBAAmB,IAAI,CAAC,MAAM,mBAAmB,QAAQ,IAAI,iBAAiB,MAAM,EAAE,UAAU,MAAM;AAE/I,eAAa;GACX,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC;GACA,SAAS;GACT,GAAG;GACH;GACA;GACD,CAAC;OAEF,SAAQ,OAAO;EAAE;EAAK;EAAS,CAAC;;AAIpC,SAAS,gBAAgB,OAAiB;AACxC,QAAO,SAAS,UAAU,YAA8C,SAAwB;AAC9F,MAAI,EAAE,OAAO,KAAK,UAAU,UAC1B;AAGF,MAAI,OAAO,eAAe,YAAY,YAAY,KAAA,EAChD,eAAc,OAAO,YAAY,QAAQ;WAChC,OAAO,eAAe,SAC/B,SAAQ,OAAO,WAAW;MAE1B,eAAc,OAAO,OAAO,OAAO,WAAW,CAAC;;;AAKrD,MAAM,aAAkB;CACtB,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAC/B,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAChC"}
1
+ {"version":3,"file":"log.mjs","names":[],"sources":["../../../src/runtime/client/log.ts"],"sourcesContent":["import type { Log, LogLevel, TransportConfig } from '../../types'\nimport { cssColors, escapeFormatString, getCssLevelColor, isLevelEnabled } from '../../utils'\n\n/**\n * Browser DevTools often hide or bucket `console.debug` under \"Verbose\" in a way that looks like\n * nothing happened. Use `console.log` for debug-level client output so it shows with the default\n * Info filter; the structured payload still has `level: 'debug'`.\n */\nfunction browserConsoleMethod(level: LogLevel): 'log' | 'info' | 'warn' | 'error' {\n if (level === 'debug') return 'log'\n return level as 'info' | 'warn' | 'error'\n}\n\nlet clientEnabled = true\nlet clientConsole = true\nlet clientPretty = true\nlet clientMinLevel: LogLevel = 'debug'\nlet clientService = 'client'\nlet transportEnabled = false\nlet transportEndpoint = '/api/_evlog/ingest'\nlet transportCredentials: RequestCredentials = 'same-origin'\nlet identityContext: Record<string, unknown> = {}\n\nexport function setIdentity(identity: Record<string, unknown>): void {\n identityContext = { ...identity }\n}\n\nexport function clearIdentity(): void {\n identityContext = {}\n}\n\n\nexport function initLog(options: { enabled?: boolean, console?: boolean, pretty?: boolean, minLevel?: LogLevel, service?: string, transport?: TransportConfig } = {}): void {\n clientEnabled = typeof options.enabled === 'boolean' ? options.enabled : true\n clientConsole = typeof options.console === 'boolean' ? options.console : true\n clientPretty = typeof options.pretty === 'boolean' ? options.pretty : true\n clientMinLevel = options.minLevel ?? 'debug'\n clientService = options.service ?? 'client'\n transportEnabled = options.transport?.enabled ?? false\n transportEndpoint = options.transport?.endpoint ?? '/api/_evlog/ingest'\n transportCredentials = options.transport?.credentials ?? 'same-origin'\n}\n\n/**\n * Update the minimum log level at runtime (e.g. enable verbose client logs from a debug toggle).\n */\nexport function setMinLevel(level: LogLevel): void {\n clientMinLevel = level\n}\n\nasync function sendToServer(event: Record<string, unknown>): Promise<void> {\n if (!transportEnabled) return\n\n try {\n await fetch(transportEndpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(event),\n keepalive: true,\n credentials: transportCredentials,\n })\n } catch {\n // Silently fail - don't break the app\n }\n}\n\nfunction emitLog(level: LogLevel, event: Record<string, unknown>): void {\n if (!clientEnabled) return\n if (!isLevelEnabled(level, clientMinLevel)) return\n\n const formatted = {\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n ...event,\n }\n\n if (clientConsole) {\n const method = browserConsoleMethod(level)\n if (clientPretty) {\n const { level: lvl, service, ...rest } = formatted\n console[method](`%c[${escapeFormatString(String(service))}]%c ${lvl}`, getCssLevelColor(lvl), cssColors.reset, rest)\n } else {\n console[method](JSON.stringify(formatted))\n }\n }\n\n sendToServer(formatted)\n}\n\nfunction emitTaggedLog(level: LogLevel, tag: string, message: string): void {\n if (!clientEnabled) return\n if (!isLevelEnabled(level, clientMinLevel)) return\n if (clientPretty) {\n if (clientConsole) {\n console[browserConsoleMethod(level)](`%c[${escapeFormatString(tag)}]%c ${escapeFormatString(message)}`, getCssLevelColor(level), cssColors.reset)\n }\n sendToServer({\n timestamp: new Date().toISOString(),\n level,\n service: clientService,\n ...identityContext,\n tag,\n message,\n })\n } else {\n emitLog(level, { tag, message })\n }\n}\n\nfunction createLogMethod(level: LogLevel) {\n return function logMethod(tagOrEvent: string | Record<string, unknown>, message?: string): void {\n // Call-time check: avoid relying on import.meta.client (can be false in some mixed bundles).\n if (typeof window === 'undefined') {\n return\n }\n\n if (typeof tagOrEvent === 'string' && message !== undefined) {\n emitTaggedLog(level, tagOrEvent, message)\n } else if (typeof tagOrEvent === 'object') {\n emitLog(level, tagOrEvent)\n } else {\n emitTaggedLog(level, 'log', String(tagOrEvent))\n }\n }\n}\n\nconst _clientLog: Log = {\n info: createLogMethod('info'),\n error: createLogMethod('error'),\n warn: createLogMethod('warn'),\n debug: createLogMethod('debug'),\n}\n\nexport { _clientLog as log }\n"],"mappings":";;;;;;;AAQA,SAAS,qBAAqB,OAAoD;AAChF,KAAI,UAAU,QAAS,QAAO;AAC9B,QAAO;;AAGT,IAAI,gBAAgB;AACpB,IAAI,gBAAgB;AACpB,IAAI,eAAe;AACnB,IAAI,iBAA2B;AAC/B,IAAI,gBAAgB;AACpB,IAAI,mBAAmB;AACvB,IAAI,oBAAoB;AACxB,IAAI,uBAA2C;AAC/C,IAAI,kBAA2C,EAAE;AAEjD,SAAgB,YAAY,UAAyC;AACnE,mBAAkB,EAAE,GAAG,UAAU;;AAGnC,SAAgB,gBAAsB;AACpC,mBAAkB,EAAE;;AAItB,SAAgB,QAAQ,UAA0I,EAAE,EAAQ;AAC1K,iBAAgB,OAAO,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACzE,iBAAgB,OAAO,QAAQ,YAAY,YAAY,QAAQ,UAAU;AACzE,gBAAe,OAAO,QAAQ,WAAW,YAAY,QAAQ,SAAS;AACtE,kBAAiB,QAAQ,YAAY;AACrC,iBAAgB,QAAQ,WAAW;AACnC,oBAAmB,QAAQ,WAAW,WAAW;AACjD,qBAAoB,QAAQ,WAAW,YAAY;AACnD,wBAAuB,QAAQ,WAAW,eAAe;;;;;AAM3D,SAAgB,YAAY,OAAuB;AACjD,kBAAiB;;AAGnB,eAAe,aAAa,OAA+C;AACzE,KAAI,CAAC,iBAAkB;AAEvB,KAAI;AACF,QAAM,MAAM,mBAAmB;GAC7B,QAAQ;GACR,SAAS,EAAE,gBAAgB,oBAAoB;GAC/C,MAAM,KAAK,UAAU,MAAM;GAC3B,WAAW;GACX,aAAa;GACd,CAAC;SACI;;AAKV,SAAS,QAAQ,OAAiB,OAAsC;AACtE,KAAI,CAAC,cAAe;AACpB,KAAI,CAAC,eAAe,OAAO,eAAe,CAAE;CAE5C,MAAM,YAAY;EAChB,4BAAW,IAAI,MAAM,EAAC,aAAa;EACnC;EACA,SAAS;EACT,GAAG;EACH,GAAG;EACJ;AAED,KAAI,eAAe;EACjB,MAAM,SAAS,qBAAqB,MAAM;AAC1C,MAAI,cAAc;GAChB,MAAM,EAAE,OAAO,KAAK,SAAS,GAAG,SAAS;AACzC,WAAQ,QAAQ,MAAM,mBAAmB,OAAO,QAAQ,CAAC,CAAC,MAAM,OAAO,iBAAiB,IAAI,EAAE,UAAU,OAAO,KAAK;QAEpH,SAAQ,QAAQ,KAAK,UAAU,UAAU,CAAC;;AAI9C,cAAa,UAAU;;AAGzB,SAAS,cAAc,OAAiB,KAAa,SAAuB;AAC1E,KAAI,CAAC,cAAe;AACpB,KAAI,CAAC,eAAe,OAAO,eAAe,CAAE;AAC5C,KAAI,cAAc;AAChB,MAAI,cACF,SAAQ,qBAAqB,MAAM,EAAE,MAAM,mBAAmB,IAAI,CAAC,MAAM,mBAAmB,QAAQ,IAAI,iBAAiB,MAAM,EAAE,UAAU,MAAM;AAEnJ,eAAa;GACX,4BAAW,IAAI,MAAM,EAAC,aAAa;GACnC;GACA,SAAS;GACT,GAAG;GACH;GACA;GACD,CAAC;OAEF,SAAQ,OAAO;EAAE;EAAK;EAAS,CAAC;;AAIpC,SAAS,gBAAgB,OAAiB;AACxC,QAAO,SAAS,UAAU,YAA8C,SAAwB;AAE9F,MAAI,OAAO,WAAW,YACpB;AAGF,MAAI,OAAO,eAAe,YAAY,YAAY,KAAA,EAChD,eAAc,OAAO,YAAY,QAAQ;WAChC,OAAO,eAAe,SAC/B,SAAQ,OAAO,WAAW;MAE1B,eAAc,OAAO,OAAO,OAAO,WAAW,CAAC;;;AAKrD,MAAM,aAAkB;CACtB,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAC/B,MAAM,gBAAgB,OAAO;CAC7B,OAAO,gBAAgB,QAAQ;CAChC"}
@@ -7,6 +7,7 @@ var plugin_default = defineNuxtPlugin(() => {
7
7
  enabled: evlogConfig?.enabled,
8
8
  console: evlogConfig?.console,
9
9
  pretty: evlogConfig?.pretty ?? import.meta.dev,
10
+ minLevel: evlogConfig?.minLevel,
10
11
  service: "client",
11
12
  transport: evlogConfig?.transport
12
13
  });
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/runtime/client/plugin.ts"],"sourcesContent":["import type { TransportConfig } from '../../types'\nimport { initLog } from './log'\nimport { defineNuxtPlugin, useRuntimeConfig } from '#app'\n\ninterface EvlogPublicConfig {\n enabled?: boolean\n console?: boolean\n pretty?: boolean\n transport?: TransportConfig\n}\n\nexport default defineNuxtPlugin(() => {\n const config = useRuntimeConfig()\n const evlogConfig = config.public?.evlog as EvlogPublicConfig | undefined\n\n initLog({\n enabled: evlogConfig?.enabled,\n console: evlogConfig?.console,\n pretty: evlogConfig?.pretty ?? import.meta.dev,\n service: 'client',\n transport: evlogConfig?.transport,\n })\n})\n"],"mappings":";;;AAWA,IAAA,iBAAe,uBAAuB;CAEpC,MAAM,cADS,kBAAkB,CACN,QAAQ;AAEnC,SAAQ;EACN,SAAS,aAAa;EACtB,SAAS,aAAa;EACtB,QAAQ,aAAa,UAAU,OAAO,KAAK;EAC3C,SAAS;EACT,WAAW,aAAa;EACzB,CAAC;EACF"}
1
+ {"version":3,"file":"plugin.mjs","names":[],"sources":["../../../src/runtime/client/plugin.ts"],"sourcesContent":["import type { LogLevel, TransportConfig } from '../../types'\nimport { initLog } from './log'\nimport { defineNuxtPlugin, useRuntimeConfig } from '#app'\n\ninterface EvlogPublicConfig {\n enabled?: boolean\n console?: boolean\n pretty?: boolean\n minLevel?: LogLevel\n transport?: TransportConfig\n}\n\nexport default defineNuxtPlugin(() => {\n const config = useRuntimeConfig()\n const evlogConfig = config.public?.evlog as EvlogPublicConfig | undefined\n\n initLog({\n enabled: evlogConfig?.enabled,\n console: evlogConfig?.console,\n pretty: evlogConfig?.pretty ?? import.meta.dev,\n minLevel: evlogConfig?.minLevel,\n service: 'client',\n transport: evlogConfig?.transport,\n })\n})\n"],"mappings":";;;AAYA,IAAA,iBAAe,uBAAuB;CAEpC,MAAM,cADS,kBAAkB,CACN,QAAQ;AAEnC,SAAQ;EACN,SAAS,aAAa;EACtB,SAAS,aAAa;EACtB,QAAQ,aAAa,UAAU,OAAO,KAAK;EAC3C,UAAU,aAAa;EACvB,SAAS;EACT,WAAW,aAAa;EACzB,CAAC;EACF"}
@@ -1,5 +1,5 @@
1
1
  import { filterSafeHeaders } from "../../../../utils.mjs";
2
- import { getEnvironment } from "../../../../logger.mjs";
2
+ import { i as getEnvironment } from "../../../../logger-DnobymUQ.mjs";
3
3
  import { createError, defineEventHandler, getHeader, getHeaders, getRequestHost, readBody, setResponseStatus } from "h3";
4
4
  import { useNitroApp } from "nitropack/runtime";
5
5
  //#region src/runtime/server/routes/_evlog/ingest.post.ts
@@ -1,2 +1,2 @@
1
- import { t as useLogger } from "../../useLogger-TjKH37BO.mjs";
1
+ import { t as useLogger } from "../../useLogger-N5A-d5l9.mjs";
2
2
  export { useLogger };