evlog 2.4.1 → 2.5.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 (137) hide show
  1. package/dist/{_http-DVDwNag0.mjs → _http-DHpGetLZ.mjs} +2 -6
  2. package/dist/{_http-DVDwNag0.mjs.map → _http-DHpGetLZ.mjs.map} +1 -1
  3. package/dist/{_severity-78FkT5MD.mjs → _severity-CLNgC2HU.mjs} +2 -2
  4. package/dist/{_severity-78FkT5MD.mjs.map → _severity-CLNgC2HU.mjs.map} +1 -1
  5. package/dist/adapters/axiom.d.mts +1 -1
  6. package/dist/adapters/axiom.d.mts.map +1 -1
  7. package/dist/adapters/axiom.mjs +2 -3
  8. package/dist/adapters/axiom.mjs.map +1 -1
  9. package/dist/adapters/better-stack.d.mts +1 -1
  10. package/dist/adapters/better-stack.d.mts.map +1 -1
  11. package/dist/adapters/better-stack.mjs +2 -3
  12. package/dist/adapters/better-stack.mjs.map +1 -1
  13. package/dist/adapters/otlp.d.mts +1 -1
  14. package/dist/adapters/otlp.d.mts.map +1 -1
  15. package/dist/adapters/otlp.mjs +14 -11
  16. package/dist/adapters/otlp.mjs.map +1 -1
  17. package/dist/adapters/posthog.d.mts +1 -1
  18. package/dist/adapters/posthog.d.mts.map +1 -1
  19. package/dist/adapters/posthog.mjs +2 -3
  20. package/dist/adapters/posthog.mjs.map +1 -1
  21. package/dist/adapters/sentry.d.mts +1 -1
  22. package/dist/adapters/sentry.d.mts.map +1 -1
  23. package/dist/adapters/sentry.mjs +3 -4
  24. package/dist/adapters/sentry.mjs.map +1 -1
  25. package/dist/browser.d.mts +1 -1
  26. package/dist/browser.mjs +1 -2
  27. package/dist/browser.mjs.map +1 -1
  28. package/dist/{dist-By0jiJRA.mjs → dist-Dalk68oO.mjs} +3 -4
  29. package/dist/{dist-By0jiJRA.mjs.map → dist-Dalk68oO.mjs.map} +1 -1
  30. package/dist/elysia/index.d.mts +2 -2
  31. package/dist/elysia/index.mjs +2 -3
  32. package/dist/elysia/index.mjs.map +1 -1
  33. package/dist/enrichers.d.mts +1 -1
  34. package/dist/enrichers.mjs +1 -1
  35. package/dist/enrichers.mjs.map +1 -1
  36. package/dist/error-Bu4fv0NO.d.mts +65 -0
  37. package/dist/error-Bu4fv0NO.d.mts.map +1 -0
  38. package/dist/error.d.mts +2 -65
  39. package/dist/error.mjs +1 -2
  40. package/dist/error.mjs.map +1 -1
  41. package/dist/express/index.d.mts +2 -2
  42. package/dist/express/index.mjs +3 -4
  43. package/dist/express/index.mjs.map +1 -1
  44. package/dist/fastify/index.d.mts +2 -2
  45. package/dist/fastify/index.d.mts.map +1 -1
  46. package/dist/fastify/index.mjs +3 -4
  47. package/dist/fastify/index.mjs.map +1 -1
  48. package/dist/{headers-CXOd5EyZ.mjs → headers-C95MOQ4w.mjs} +4 -6
  49. package/dist/{headers-CXOd5EyZ.mjs.map → headers-C95MOQ4w.mjs.map} +1 -1
  50. package/dist/hono/index.d.mts +2 -2
  51. package/dist/hono/index.mjs +2 -3
  52. package/dist/hono/index.mjs.map +1 -1
  53. package/dist/index.d.mts +5 -5
  54. package/dist/index.mjs +1 -2
  55. package/dist/logger-BNxG5Kyd.d.mts +59 -0
  56. package/dist/logger-BNxG5Kyd.d.mts.map +1 -0
  57. package/dist/logger.d.mts +2 -59
  58. package/dist/logger.mjs +1 -2
  59. package/dist/logger.mjs.map +1 -1
  60. package/dist/{middleware-BoVCgsfQ.d.mts → middleware-gCuB0w7F.d.mts} +2 -2
  61. package/dist/{middleware-BoVCgsfQ.d.mts.map → middleware-gCuB0w7F.d.mts.map} +1 -1
  62. package/dist/nestjs/index.d.mts +2 -2
  63. package/dist/nestjs/index.mjs +3 -4
  64. package/dist/nestjs/index.mjs.map +1 -1
  65. package/dist/next/client.d.mts +1 -1
  66. package/dist/next/client.mjs +2 -4
  67. package/dist/next/client.mjs.map +1 -1
  68. package/dist/next/index.d.mts +4 -4
  69. package/dist/next/index.d.mts.map +1 -1
  70. package/dist/next/index.mjs +2 -6
  71. package/dist/next/index.mjs.map +1 -1
  72. package/dist/nitro/errorHandler.mjs +2 -3
  73. package/dist/nitro/errorHandler.mjs.map +1 -1
  74. package/dist/nitro/module.d.mts +2 -2
  75. package/dist/nitro/module.mjs +1 -2
  76. package/dist/nitro/module.mjs.map +1 -1
  77. package/dist/nitro/plugin.mjs +3 -4
  78. package/dist/nitro/plugin.mjs.map +1 -1
  79. package/dist/nitro/v3/errorHandler.mjs +3 -4
  80. package/dist/nitro/v3/errorHandler.mjs.map +1 -1
  81. package/dist/nitro/v3/index.mjs +1 -2
  82. package/dist/nitro/v3/middleware.mjs +1 -2
  83. package/dist/nitro/v3/middleware.mjs.map +1 -1
  84. package/dist/nitro/v3/module.d.mts +1 -1
  85. package/dist/nitro/v3/module.mjs +1 -2
  86. package/dist/nitro/v3/module.mjs.map +1 -1
  87. package/dist/nitro/v3/plugin.mjs +4 -5
  88. package/dist/nitro/v3/plugin.mjs.map +1 -1
  89. package/dist/nitro/v3/useLogger.d.mts +1 -1
  90. package/dist/nitro/v3/useLogger.mjs +1 -1
  91. package/dist/nitro/v3/useLogger.mjs.map +1 -1
  92. package/dist/{nitro-Da8tEfJ3.mjs → nitro-B3vZrLGI.mjs} +2 -2
  93. package/dist/{nitro-Da8tEfJ3.mjs.map → nitro-B3vZrLGI.mjs.map} +1 -1
  94. package/dist/{nitro-BRisWfGy.d.mts → nitro-wZ05H2wx.d.mts} +2 -2
  95. package/dist/{nitro-BRisWfGy.d.mts.map → nitro-wZ05H2wx.d.mts.map} +1 -1
  96. package/dist/nuxt/module.d.mts +1 -1
  97. package/dist/nuxt/module.mjs +2 -5
  98. package/dist/nuxt/module.mjs.map +1 -1
  99. package/dist/parseError-BeVEVQBh.d.mts +7 -0
  100. package/dist/parseError-BeVEVQBh.d.mts.map +1 -0
  101. package/dist/pipeline.mjs +1 -1
  102. package/dist/{routes-BNbrnm14.mjs → routes-DdmLpEnG.mjs} +2 -3
  103. package/dist/{routes-BNbrnm14.mjs.map → routes-DdmLpEnG.mjs.map} +1 -1
  104. package/dist/runtime/client/log.d.mts +1 -1
  105. package/dist/runtime/client/log.mjs +1 -2
  106. package/dist/runtime/client/log.mjs.map +1 -1
  107. package/dist/runtime/client/plugin.mjs +1 -2
  108. package/dist/runtime/client/plugin.mjs.map +1 -1
  109. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +1 -2
  110. package/dist/runtime/server/routes/_evlog/ingest.post.mjs.map +1 -1
  111. package/dist/runtime/server/useLogger.d.mts +2 -39
  112. package/dist/runtime/server/useLogger.mjs +1 -1
  113. package/dist/runtime/server/useLogger.mjs.map +1 -1
  114. package/dist/runtime/utils/parseError.d.mts +3 -7
  115. package/dist/runtime/utils/parseError.mjs +1 -1
  116. package/dist/{storage-CejtuV76.mjs → storage-CRSAAEiG.mjs} +2 -3
  117. package/dist/{storage-CejtuV76.mjs.map → storage-CRSAAEiG.mjs.map} +1 -1
  118. package/dist/sveltekit/index.d.mts +2 -2
  119. package/dist/sveltekit/index.mjs +4 -5
  120. package/dist/sveltekit/index.mjs.map +1 -1
  121. package/dist/types-CRj5tGVA.d.mts +496 -0
  122. package/dist/types-CRj5tGVA.d.mts.map +1 -0
  123. package/dist/types.d.mts +2 -496
  124. package/dist/types.mjs +1 -1
  125. package/dist/useLogger-w7MZjqW_.d.mts +39 -0
  126. package/dist/useLogger-w7MZjqW_.d.mts.map +1 -0
  127. package/dist/utils.d.mts +1 -1
  128. package/dist/utils.mjs +1 -1
  129. package/dist/workers.d.mts +1 -1
  130. package/dist/workers.mjs +1 -2
  131. package/dist/workers.mjs.map +1 -1
  132. package/package.json +55 -34
  133. package/dist/error.d.mts.map +0 -1
  134. package/dist/logger.d.mts.map +0 -1
  135. package/dist/runtime/server/useLogger.d.mts.map +0 -1
  136. package/dist/runtime/utils/parseError.d.mts.map +0 -1
  137. package/dist/types.d.mts.map +0 -1
@@ -2,7 +2,6 @@ import { filterSafeHeaders } from "../../../../utils.mjs";
2
2
  import { getEnvironment } from "../../../../logger.mjs";
3
3
  import { createError, defineEventHandler, getHeader, getHeaders, getRequestHost, readBody, setResponseStatus } from "h3";
4
4
  import { useNitroApp } from "nitropack/runtime";
5
-
6
5
  //#region src/runtime/server/routes/_evlog/ingest.post.ts
7
6
  const VALID_LEVELS = [
8
7
  "info",
@@ -117,7 +116,7 @@ var ingest_post_default = defineEventHandler(async (event) => {
117
116
  setResponseStatus(event, 204);
118
117
  return null;
119
118
  });
120
-
121
119
  //#endregion
122
120
  export { ingest_post_default as default };
121
+
123
122
  //# sourceMappingURL=ingest.post.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ingest.post.mjs","names":[],"sources":["../../../../../src/runtime/server/routes/_evlog/ingest.post.ts"],"sourcesContent":["import { createError, defineEventHandler, getHeader, getHeaders, getRequestHost, readBody, setResponseStatus } from 'h3'\nimport { useNitroApp } from 'nitropack/runtime'\nimport type { IngestPayload, WideEvent } from '../../../../types'\nimport { getEnvironment } from '../../../../logger'\nimport { filterSafeHeaders } from '../../../../utils'\n\nconst VALID_LEVELS = ['info', 'error', 'warn', 'debug'] as const\n\nfunction validateOrigin(event: Parameters<typeof defineEventHandler>[0] extends (e: infer E) => unknown ? E : never): void {\n const origin = getHeader(event, 'origin')\n const referer = getHeader(event, 'referer')\n const host = getRequestHost(event)\n\n const requestOrigin = origin || (referer ? new URL(referer).origin : null)\n\n if (!requestOrigin) {\n throw createError({ statusCode: 403, message: 'Missing origin header' })\n }\n\n const originHost = new URL(requestOrigin).host\n\n if (originHost !== host) {\n throw createError({ statusCode: 403, message: 'Invalid origin' })\n }\n}\n\n// ISO 8601 datetime pattern (e.g., 2024-01-31T14:00:00.000Z)\nconst ISO_8601_REGEX = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/\n\nfunction isValidISOTimestamp(value: string): boolean {\n if (!ISO_8601_REGEX.test(value)) return false\n const date = new Date(value)\n return !Number.isNaN(date.getTime())\n}\n\nfunction validatePayload(body: unknown): IngestPayload {\n if (!body || typeof body !== 'object' || Array.isArray(body)) {\n throw createError({ statusCode: 400, message: 'Invalid request body' })\n }\n\n const payload = body as Record<string, unknown>\n\n if (payload.timestamp === undefined || payload.timestamp === null) {\n throw createError({ statusCode: 400, message: 'Missing required field: timestamp' })\n }\n\n const { timestamp: rawTimestamp } = payload\n let timestamp: string\n if (typeof rawTimestamp === 'number') {\n const minTimestamp = new Date('2000-01-01').getTime()\n const maxTimestamp = Date.now() + 24 * 60 * 60 * 1000 // 1 day in the future\n if (rawTimestamp < minTimestamp || rawTimestamp > maxTimestamp) {\n throw createError({ statusCode: 400, message: 'Invalid timestamp: value out of reasonable range' })\n }\n timestamp = new Date(rawTimestamp).toISOString()\n } else if (typeof rawTimestamp === 'string') {\n if (!isValidISOTimestamp(rawTimestamp)) {\n throw createError({ statusCode: 400, message: 'Invalid timestamp: must be a valid ISO 8601 datetime string' })\n }\n timestamp = rawTimestamp\n } else {\n throw createError({ statusCode: 400, message: 'Invalid timestamp: must be string or number' })\n }\n\n if (!payload.level || typeof payload.level !== 'string') {\n throw createError({ statusCode: 400, message: 'Missing required field: level' })\n }\n\n if (!VALID_LEVELS.includes(payload.level as typeof VALID_LEVELS[number])) {\n throw createError({ statusCode: 400, message: `Invalid level: must be one of ${VALID_LEVELS.join(', ')}` })\n }\n\n return {\n ...payload,\n timestamp,\n level: payload.level as IngestPayload['level'],\n }\n}\n\nfunction getSafeHeaders(event: Parameters<typeof defineEventHandler>[0] extends (e: infer E) => unknown ? E : never): Record<string, string> {\n const allHeaders = getHeaders(event as Parameters<typeof getHeaders>[0])\n return filterSafeHeaders(allHeaders)\n}\n\nexport default defineEventHandler(async (event) => {\n validateOrigin(event)\n\n const body = await readBody(event)\n const payload = validatePayload(body)\n const nitroApp = useNitroApp()\n const env = getEnvironment()\n\n const { service: _clientService, ...sanitizedPayload } = payload as IngestPayload & { service?: unknown }\n\n const wideEvent: WideEvent = {\n ...sanitizedPayload,\n ...env,\n source: 'client',\n }\n\n const headers = getSafeHeaders(event)\n const request = { method: 'POST' as const, path: event.path }\n\n try {\n await nitroApp.hooks.callHook('evlog:enrich', {\n event: wideEvent,\n request,\n headers,\n response: { status: 204 },\n })\n } catch (err) {\n console.error('[evlog] enrich failed:', err)\n }\n\n const drainPromise = nitroApp.hooks.callHook('evlog:drain', {\n event: wideEvent,\n request,\n headers,\n }).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n\n // Use waitUntil if available (Cloudflare Workers, Vercel Edge)\n // Otherwise, await the drain to prevent lost logs in serverless environments\n const waitUntilCtx = (event as unknown as { context: Record<string, unknown> }).context\n const cfCtx = (waitUntilCtx as { cloudflare?: { context?: { waitUntil?: (p: Promise<unknown>) => void } } }).cloudflare?.context ?? waitUntilCtx\n if (typeof (cfCtx as { waitUntil?: unknown }).waitUntil === 'function') {\n (cfCtx as { waitUntil: (p: Promise<unknown>) => void }).waitUntil(drainPromise)\n } else {\n await drainPromise\n }\n\n setResponseStatus(event, 204)\n return null\n})\n"],"mappings":"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"}
1
+ {"version":3,"file":"ingest.post.mjs","names":[],"sources":["../../../../../src/runtime/server/routes/_evlog/ingest.post.ts"],"sourcesContent":["import { createError, defineEventHandler, getHeader, getHeaders, getRequestHost, readBody, setResponseStatus } from 'h3'\nimport { useNitroApp } from 'nitropack/runtime'\nimport type { IngestPayload, WideEvent } from '../../../../types'\nimport { getEnvironment } from '../../../../logger'\nimport { filterSafeHeaders } from '../../../../utils'\n\nconst VALID_LEVELS = ['info', 'error', 'warn', 'debug'] as const\n\nfunction validateOrigin(event: Parameters<typeof defineEventHandler>[0] extends (e: infer E) => unknown ? E : never): void {\n const origin = getHeader(event, 'origin')\n const referer = getHeader(event, 'referer')\n const host = getRequestHost(event)\n\n const requestOrigin = origin || (referer ? new URL(referer).origin : null)\n\n if (!requestOrigin) {\n throw createError({ statusCode: 403, message: 'Missing origin header' })\n }\n\n const originHost = new URL(requestOrigin).host\n\n if (originHost !== host) {\n throw createError({ statusCode: 403, message: 'Invalid origin' })\n }\n}\n\n// ISO 8601 datetime pattern (e.g., 2024-01-31T14:00:00.000Z)\nconst ISO_8601_REGEX = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$/\n\nfunction isValidISOTimestamp(value: string): boolean {\n if (!ISO_8601_REGEX.test(value)) return false\n const date = new Date(value)\n return !Number.isNaN(date.getTime())\n}\n\nfunction validatePayload(body: unknown): IngestPayload {\n if (!body || typeof body !== 'object' || Array.isArray(body)) {\n throw createError({ statusCode: 400, message: 'Invalid request body' })\n }\n\n const payload = body as Record<string, unknown>\n\n if (payload.timestamp === undefined || payload.timestamp === null) {\n throw createError({ statusCode: 400, message: 'Missing required field: timestamp' })\n }\n\n const { timestamp: rawTimestamp } = payload\n let timestamp: string\n if (typeof rawTimestamp === 'number') {\n const minTimestamp = new Date('2000-01-01').getTime()\n const maxTimestamp = Date.now() + 24 * 60 * 60 * 1000 // 1 day in the future\n if (rawTimestamp < minTimestamp || rawTimestamp > maxTimestamp) {\n throw createError({ statusCode: 400, message: 'Invalid timestamp: value out of reasonable range' })\n }\n timestamp = new Date(rawTimestamp).toISOString()\n } else if (typeof rawTimestamp === 'string') {\n if (!isValidISOTimestamp(rawTimestamp)) {\n throw createError({ statusCode: 400, message: 'Invalid timestamp: must be a valid ISO 8601 datetime string' })\n }\n timestamp = rawTimestamp\n } else {\n throw createError({ statusCode: 400, message: 'Invalid timestamp: must be string or number' })\n }\n\n if (!payload.level || typeof payload.level !== 'string') {\n throw createError({ statusCode: 400, message: 'Missing required field: level' })\n }\n\n if (!VALID_LEVELS.includes(payload.level as typeof VALID_LEVELS[number])) {\n throw createError({ statusCode: 400, message: `Invalid level: must be one of ${VALID_LEVELS.join(', ')}` })\n }\n\n return {\n ...payload,\n timestamp,\n level: payload.level as IngestPayload['level'],\n }\n}\n\nfunction getSafeHeaders(event: Parameters<typeof defineEventHandler>[0] extends (e: infer E) => unknown ? E : never): Record<string, string> {\n const allHeaders = getHeaders(event as Parameters<typeof getHeaders>[0])\n return filterSafeHeaders(allHeaders)\n}\n\nexport default defineEventHandler(async (event) => {\n validateOrigin(event)\n\n const body = await readBody(event)\n const payload = validatePayload(body)\n const nitroApp = useNitroApp()\n const env = getEnvironment()\n\n const { service: _clientService, ...sanitizedPayload } = payload as IngestPayload & { service?: unknown }\n\n const wideEvent: WideEvent = {\n ...sanitizedPayload,\n ...env,\n source: 'client',\n }\n\n const headers = getSafeHeaders(event)\n const request = { method: 'POST' as const, path: event.path }\n\n try {\n await nitroApp.hooks.callHook('evlog:enrich', {\n event: wideEvent,\n request,\n headers,\n response: { status: 204 },\n })\n } catch (err) {\n console.error('[evlog] enrich failed:', err)\n }\n\n const drainPromise = nitroApp.hooks.callHook('evlog:drain', {\n event: wideEvent,\n request,\n headers,\n }).catch((err) => {\n console.error('[evlog] drain failed:', err)\n })\n\n // Use waitUntil if available (Cloudflare Workers, Vercel Edge)\n // Otherwise, await the drain to prevent lost logs in serverless environments\n const waitUntilCtx = (event as unknown as { context: Record<string, unknown> }).context\n const cfCtx = (waitUntilCtx as { cloudflare?: { context?: { waitUntil?: (p: Promise<unknown>) => void } } }).cloudflare?.context ?? waitUntilCtx\n if (typeof (cfCtx as { waitUntil?: unknown }).waitUntil === 'function') {\n (cfCtx as { waitUntil: (p: Promise<unknown>) => void }).waitUntil(drainPromise)\n } else {\n await drainPromise\n }\n\n setResponseStatus(event, 204)\n return null\n})\n"],"mappings":"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"}
@@ -1,39 +1,2 @@
1
- import { RequestLogger, ServerEvent } from "../../types.mjs";
2
-
3
- //#region src/runtime/server/useLogger.d.ts
4
- /**
5
- * Returns the request logger attached to the given server event.
6
- *
7
- * @param event - The current server event containing the context with the logger.
8
- * @param service - Optional service name to override the default service.
9
- * @returns The request-scoped logger.
10
- * @throws Error if the logger is not initialized on the event context.
11
- *
12
- * @example
13
- * export default defineEventHandler((event) => {
14
- * const log = useLogger(event)
15
- * log.set({ foo: 'bar' })
16
- * // ...
17
- * })
18
- *
19
- * @example
20
- * // Override service name for specific routes
21
- * export default defineEventHandler((event) => {
22
- * const log = useLogger(event, 'payment-service')
23
- * log.set({ foo: 'bar' })
24
- * // ...
25
- * })
26
- *
27
- * @example
28
- * // Typed fields — must use explicit import for type checking to work
29
- * import { useLogger } from 'evlog'
30
- *
31
- * interface MyFields { user: { id: string; plan: string } }
32
- * const log = useLogger<MyFields>(event)
33
- * log.set({ user: { id: '123', plan: 'pro' } }) // OK
34
- * log.set({ foo: 'bar' }) // TS error
35
- */
36
- declare function useLogger<T extends object = Record<string, unknown>>(event: ServerEvent, service?: string): RequestLogger<T>;
37
- //#endregion
38
- export { useLogger };
39
- //# sourceMappingURL=useLogger.d.mts.map
1
+ import { t as useLogger } from "../../useLogger-w7MZjqW_.mjs";
2
+ export { useLogger };
@@ -37,7 +37,7 @@ function useLogger(event, service) {
37
37
  if (service) log.set({ service });
38
38
  return log;
39
39
  }
40
-
41
40
  //#endregion
42
41
  export { useLogger };
42
+
43
43
  //# sourceMappingURL=useLogger.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"useLogger.mjs","names":[],"sources":["../../../src/runtime/server/useLogger.ts"],"sourcesContent":["import type { RequestLogger, ServerEvent } from '../../types'\n\n/**\n * Returns the request logger attached to the given server event.\n *\n * @param event - The current server event containing the context with the logger.\n * @param service - Optional service name to override the default service.\n * @returns The request-scoped logger.\n * @throws Error if the logger is not initialized on the event context.\n *\n * @example\n * export default defineEventHandler((event) => {\n * const log = useLogger(event)\n * log.set({ foo: 'bar' })\n * // ...\n * })\n *\n * @example\n * // Override service name for specific routes\n * export default defineEventHandler((event) => {\n * const log = useLogger(event, 'payment-service')\n * log.set({ foo: 'bar' })\n * // ...\n * })\n *\n * @example\n * // Typed fields — must use explicit import for type checking to work\n * import { useLogger } from 'evlog'\n *\n * interface MyFields { user: { id: string; plan: string } }\n * const log = useLogger<MyFields>(event)\n * log.set({ user: { id: '123', plan: 'pro' } }) // OK\n * log.set({ foo: 'bar' }) // TS error\n */\nexport function useLogger<T extends object = Record<string, unknown>>(event: ServerEvent, service?: string): RequestLogger<T> {\n const log = event.context.log as RequestLogger<T> | undefined\n\n if (!log) {\n throw new Error(\n '[evlog] Logger not initialized. Make sure the evlog Nitro plugin is registered. '\n + 'If using Nuxt, add \"evlog\" to your modules.',\n )\n }\n\n if (service) {\n const untyped = log as unknown as RequestLogger\n untyped.set({ service })\n }\n\n return log\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,UAAsD,OAAoB,SAAoC;CAC5H,MAAM,MAAM,MAAM,QAAQ;AAE1B,KAAI,CAAC,IACH,OAAM,IAAI,MACR,gIAED;AAGH,KAAI,QAEF,CADgB,IACR,IAAI,EAAE,SAAS,CAAC;AAG1B,QAAO"}
1
+ {"version":3,"file":"useLogger.mjs","names":[],"sources":["../../../src/runtime/server/useLogger.ts"],"sourcesContent":["import type { RequestLogger, ServerEvent } from '../../types'\n\n/**\n * Returns the request logger attached to the given server event.\n *\n * @param event - The current server event containing the context with the logger.\n * @param service - Optional service name to override the default service.\n * @returns The request-scoped logger.\n * @throws Error if the logger is not initialized on the event context.\n *\n * @example\n * export default defineEventHandler((event) => {\n * const log = useLogger(event)\n * log.set({ foo: 'bar' })\n * // ...\n * })\n *\n * @example\n * // Override service name for specific routes\n * export default defineEventHandler((event) => {\n * const log = useLogger(event, 'payment-service')\n * log.set({ foo: 'bar' })\n * // ...\n * })\n *\n * @example\n * // Typed fields — must use explicit import for type checking to work\n * import { useLogger } from 'evlog'\n *\n * interface MyFields { user: { id: string; plan: string } }\n * const log = useLogger<MyFields>(event)\n * log.set({ user: { id: '123', plan: 'pro' } }) // OK\n * log.set({ foo: 'bar' }) // TS error\n */\nexport function useLogger<T extends object = Record<string, unknown>>(event: ServerEvent, service?: string): RequestLogger<T> {\n const log = event.context.log as RequestLogger<T> | undefined\n\n if (!log) {\n throw new Error(\n '[evlog] Logger not initialized. Make sure the evlog Nitro plugin is registered. '\n + 'If using Nuxt, add \"evlog\" to your modules.',\n )\n }\n\n if (service) {\n const untyped = log as unknown as RequestLogger\n untyped.set({ service })\n }\n\n return log\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,UAAsD,OAAoB,SAAoC;CAC5H,MAAM,MAAM,MAAM,QAAQ;AAE1B,KAAI,CAAC,IACH,OAAM,IAAI,MACR,gIAED;AAGH,KAAI,QACc,KACR,IAAI,EAAE,SAAS,CAAC;AAG1B,QAAO"}
@@ -1,7 +1,3 @@
1
- import { ParsedError } from "../../types.mjs";
2
-
3
- //#region src/runtime/utils/parseError.d.ts
4
- declare function parseError(error: unknown): ParsedError;
5
- //#endregion
6
- export { type ParsedError, parseError };
7
- //# sourceMappingURL=parseError.d.mts.map
1
+ import { m as ParsedError } from "../../types-CRj5tGVA.mjs";
2
+ import { t as parseError } from "../../parseError-BeVEVQBh.mjs";
3
+ export { ParsedError, parseError };
@@ -23,7 +23,7 @@ function parseError(error) {
23
23
  raw: error
24
24
  };
25
25
  }
26
-
27
26
  //#endregion
28
27
  export { parseError };
28
+
29
29
  //# sourceMappingURL=parseError.mjs.map
@@ -1,5 +1,4 @@
1
1
  import { AsyncLocalStorage } from "node:async_hooks";
2
-
3
2
  //#region src/shared/storage.ts
4
3
  /**
5
4
  * Create a request-scoped `AsyncLocalStorage` and a matching `useLogger` accessor.
@@ -39,7 +38,7 @@ function createLoggerStorage(contextHint) {
39
38
  useLogger
40
39
  };
41
40
  }
42
-
43
41
  //#endregion
44
42
  export { createLoggerStorage as t };
45
- //# sourceMappingURL=storage-CejtuV76.mjs.map
43
+
44
+ //# sourceMappingURL=storage-CRSAAEiG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage-CejtuV76.mjs","names":[],"sources":["../src/shared/storage.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RequestLogger } from '../types'\n\n/**\n * Create a request-scoped `AsyncLocalStorage` and a matching `useLogger` accessor.\n *\n * Every framework that needs `useLogger()` (Express, Fastify, NestJS, SvelteKit)\n * calls this once at module level to get its own isolated storage + accessor pair.\n *\n * @param contextHint - Human-readable hint appended to the error message when\n * `useLogger()` is called outside of a request (e.g.\n * `\"middleware context. Make sure app.use(evlog()) is registered before your routes.\"`).\n */\nexport function createLoggerStorage(contextHint: string) {\n const storage = new AsyncLocalStorage<RequestLogger>()\n\n /**\n * Access the request-scoped logger created by the evlog middleware.\n *\n * Must be called inside a request that is handled by the evlog middleware.\n * Throws if called outside of a request context.\n *\n * @example\n * ```ts\n * import { useLogger } from 'evlog/express' // or /fastify, /nestjs, /sveltekit, /elysia\n *\n * function myService() {\n * const log = useLogger()\n * log.set({ users: { count: 42 } })\n * }\n * ```\n */\n function useLogger<T extends object = Record<string, unknown>>(): RequestLogger<T> {\n const logger = storage.getStore()\n if (!logger) {\n throw new Error(\n `[evlog] useLogger() was called outside of an evlog ${contextHint}`,\n )\n }\n return logger as RequestLogger<T>\n }\n\n return { storage, useLogger }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,oBAAoB,aAAqB;CACvD,MAAM,UAAU,IAAI,mBAAkC;;;;;;;;;;;;;;;;;CAkBtD,SAAS,YAA0E;EACjF,MAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,CAAC,OACH,OAAM,IAAI,MACR,sDAAsD,cACvD;AAEH,SAAO;;AAGT,QAAO;EAAE;EAAS;EAAW"}
1
+ {"version":3,"file":"storage-CRSAAEiG.mjs","names":[],"sources":["../src/shared/storage.ts"],"sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks'\nimport type { RequestLogger } from '../types'\n\n/**\n * Create a request-scoped `AsyncLocalStorage` and a matching `useLogger` accessor.\n *\n * Every framework that needs `useLogger()` (Express, Fastify, NestJS, SvelteKit)\n * calls this once at module level to get its own isolated storage + accessor pair.\n *\n * @param contextHint - Human-readable hint appended to the error message when\n * `useLogger()` is called outside of a request (e.g.\n * `\"middleware context. Make sure app.use(evlog()) is registered before your routes.\"`).\n */\nexport function createLoggerStorage(contextHint: string) {\n const storage = new AsyncLocalStorage<RequestLogger>()\n\n /**\n * Access the request-scoped logger created by the evlog middleware.\n *\n * Must be called inside a request that is handled by the evlog middleware.\n * Throws if called outside of a request context.\n *\n * @example\n * ```ts\n * import { useLogger } from 'evlog/express' // or /fastify, /nestjs, /sveltekit, /elysia\n *\n * function myService() {\n * const log = useLogger()\n * log.set({ users: { count: 42 } })\n * }\n * ```\n */\n function useLogger<T extends object = Record<string, unknown>>(): RequestLogger<T> {\n const logger = storage.getStore()\n if (!logger) {\n throw new Error(\n `[evlog] useLogger() was called outside of an evlog ${contextHint}`,\n )\n }\n return logger as RequestLogger<T>\n }\n\n return { storage, useLogger }\n}\n"],"mappings":";;;;;;;;;;;;AAaA,SAAgB,oBAAoB,aAAqB;CACvD,MAAM,UAAU,IAAI,mBAAkC;;;;;;;;;;;;;;;;;CAkBtD,SAAS,YAA0E;EACjF,MAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,CAAC,OACH,OAAM,IAAI,MACR,sDAAsD,cACvD;AAEH,SAAO;;AAGT,QAAO;EAAE;EAAS;EAAW"}
@@ -1,5 +1,5 @@
1
- import { RequestLogger } from "../types.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-BoVCgsfQ.mjs";
1
+ import { g as RequestLogger } from "../types-CRj5tGVA.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-gCuB0w7F.mjs";
3
3
 
4
4
  //#region src/sveltekit/index.d.ts
5
5
  declare const useLogger: <T extends object = Record<string, unknown>>() => RequestLogger<T>;
@@ -1,8 +1,7 @@
1
1
  import { EvlogError } from "../error.mjs";
2
- import { n as resolveEvlogError, r as serializeEvlogErrorResponse, t as extractErrorStatus } from "../nitro-Da8tEfJ3.mjs";
3
- import { r as createMiddlewareLogger, t as extractSafeHeaders } from "../headers-CXOd5EyZ.mjs";
4
- import { t as createLoggerStorage } from "../storage-CejtuV76.mjs";
5
-
2
+ import { n as resolveEvlogError, r as serializeEvlogErrorResponse, t as extractErrorStatus } from "../nitro-B3vZrLGI.mjs";
3
+ import { r as createMiddlewareLogger, t as extractSafeHeaders } from "../headers-C95MOQ4w.mjs";
4
+ import { t as createLoggerStorage } from "../storage-CRSAAEiG.mjs";
6
5
  //#region src/sveltekit/index.ts
7
6
  const { storage, useLogger } = createLoggerStorage("handle context. Make sure evlog() handle is added to your hooks.server.ts.");
8
7
  /**
@@ -157,7 +156,7 @@ function createEvlogHooks(options = {}) {
157
156
  handleError: evlogHandleError()
158
157
  };
159
158
  }
160
-
161
159
  //#endregion
162
160
  export { createEvlogHooks, evlog, evlogHandleError, useLogger };
161
+
163
162
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/sveltekit/index.ts"],"sourcesContent":["import type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\nimport { resolveEvlogError, extractErrorStatus, serializeEvlogErrorResponse } from '../nitro'\nimport { EvlogError } from '../error'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'handle context. Make sure evlog() handle is added to your hooks.server.ts.',\n)\n\nexport type EvlogSvelteKitOptions = BaseEvlogOptions\n\nexport { useLogger }\n\n/**\n * SvelteKit `Handle` function signature — avoids a hard dependency on `@sveltejs/kit`.\n */\ntype SvelteKitHandle = (input: {\n event: { request: Request; url: URL; locals: Record<string, any> }\n resolve: (event: any) => Promise<Response>\n}) => Promise<Response>\n\n/**\n * SvelteKit `HandleServerError` signature — avoids a hard dependency on `@sveltejs/kit`.\n */\ntype SvelteKitHandleServerError = (input: {\n error: unknown\n event: { request: Request; url: URL; locals: Record<string, any> }\n status: number\n message: string\n}) => MaybePromise<void | AppError>\n\ntype MaybePromise<T> = T | Promise<T>\n\n/** Minimal SvelteKit `App.Error` shape */\ninterface AppError {\n message: string\n [key: string]: unknown\n}\n\n/**\n * Create an evlog handle hook for SvelteKit.\n *\n * Add it to your `src/hooks.server.ts` using SvelteKit's `sequence` helper\n * or as the sole handle export.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { initLogger } from 'evlog'\n * import { evlog } from 'evlog/sveltekit'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'my-sveltekit-app' } })\n *\n * export const handle = evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n *\n * @example\n * ```ts\n * // Compose with other hooks using sequence\n * import { sequence } from '@sveltejs/kit/hooks'\n * import { evlog } from 'evlog/sveltekit'\n *\n * export const handle = sequence(evlog(), yourOtherHook)\n * ```\n */\nexport function evlog(options: EvlogSvelteKitOptions = {}): SvelteKitHandle {\n return async ({ event, resolve }) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: event.request.method,\n path: event.url.pathname,\n requestId: event.request.headers.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(event.request.headers),\n ...options,\n })\n\n if (skipped) {\n return await resolve(event)\n }\n\n event.locals.log = logger\n\n return storage.run(logger, async () => {\n try {\n const response = await resolve(event)\n\n // SvelteKit catches route errors internally and returns 500.\n // If handleError already logged an EvlogError with a specific status,\n // return a structured JSON response instead of SvelteKit's generic 500.\n const ctx = logger.getContext()\n const errorData = ctx.error as { name?: string; status?: number; message?: string; data?: unknown } | undefined\n if (response.status >= 500 && errorData?.name === 'EvlogError' && errorData.status) {\n const { status } = errorData\n await finish({ status })\n const body = serializeEvlogErrorResponse(errorData as EvlogError, event.url.pathname)\n return new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n }\n\n await finish({ status: response.status })\n return response\n } catch (error) {\n await finish({ error: error as Error })\n\n // Return structured JSON for EvlogError (like NextJS withEvlog / Nuxt errorHandler)\n if (error instanceof EvlogError) {\n const status = error.status ?? 500\n const body = serializeEvlogErrorResponse(error, event.url.pathname)\n return new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n }\n\n throw error\n }\n })\n }\n}\n\n/**\n * Create an evlog error handler for SvelteKit.\n *\n * Logs unhandled errors via `event.locals.log` (if available) and returns\n * structured error responses for `EvlogError` instances. For non-evlog errors,\n * returns a generic error response with sanitized messages in production.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { evlog, evlogHandleError } from 'evlog/sveltekit'\n *\n * export const handle = evlog()\n * export const handleError = evlogHandleError()\n * ```\n */\nexport function evlogHandleError(): SvelteKitHandleServerError {\n return ({ error, event, status, message }) => {\n const logger = event.locals.log as RequestLogger | undefined\n\n if (logger && error instanceof Error) {\n logger.error(error)\n }\n\n const evlogError = error instanceof Error ? resolveEvlogError(error) : null\n\n if (evlogError) {\n const errorStatus = extractErrorStatus(evlogError)\n const response = serializeEvlogErrorResponse(evlogError, event.url.pathname)\n return {\n message: response.message as string,\n status: errorStatus,\n why: (response.data as { why?: string })?.why,\n fix: (response.data as { fix?: string })?.fix,\n link: (response.data as { link?: string })?.link,\n } as AppError\n }\n\n return { message, status } as AppError\n }\n}\n\n/**\n * Create both `handle` and `handleError` hooks in a single call.\n *\n * This is the recommended setup for SvelteKit — it returns both hooks\n * pre-configured and ready to export from `hooks.server.ts`.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { initLogger } from 'evlog'\n * import { createEvlogHooks } from 'evlog/sveltekit'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'my-app' } })\n *\n * export const { handle, handleError } = createEvlogHooks({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n *\n * @example\n * ```ts\n * // Compose with other hooks using sequence\n * import { sequence } from '@sveltejs/kit/hooks'\n * import { createEvlogHooks } from 'evlog/sveltekit'\n *\n * const evlogHooks = createEvlogHooks()\n *\n * export const handle = sequence(evlogHooks.handle, yourOtherHook)\n * export const handleError = evlogHooks.handleError\n * ```\n */\nexport function createEvlogHooks(options: EvlogSvelteKitOptions = {}) {\n return {\n handle: evlog(options),\n handleError: evlogHandleError(),\n }\n}\n"],"mappings":";;;;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,6EACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgED,SAAgB,MAAM,UAAiC,EAAE,EAAmB;AAC1E,QAAO,OAAO,EAAE,OAAO,cAAc;EACnC,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,MAAM,QAAQ;GACtB,MAAM,MAAM,IAAI;GAChB,WAAW,MAAM,QAAQ,QAAQ,IAAI,eAAe,IAAI,OAAO,YAAY;GAC3E,SAAS,mBAAmB,MAAM,QAAQ,QAAQ;GAClD,GAAG;GACJ,CAAC;AAEF,MAAI,QACF,QAAO,MAAM,QAAQ,MAAM;AAG7B,QAAM,OAAO,MAAM;AAEnB,SAAO,QAAQ,IAAI,QAAQ,YAAY;AACrC,OAAI;IACF,MAAM,WAAW,MAAM,QAAQ,MAAM;IAMrC,MAAM,YADM,OAAO,YAAY,CACT;AACtB,QAAI,SAAS,UAAU,OAAO,WAAW,SAAS,gBAAgB,UAAU,QAAQ;KAClF,MAAM,EAAE,WAAW;AACnB,WAAM,OAAO,EAAE,QAAQ,CAAC;KACxB,MAAM,OAAO,4BAA4B,WAAyB,MAAM,IAAI,SAAS;AACrF,YAAO,IAAI,SAAS,KAAK,UAAU,KAAK,EAAE;MACxC;MACA,SAAS,EAAE,gBAAgB,oBAAoB;MAChD,CAAC;;AAGJ,UAAM,OAAO,EAAE,QAAQ,SAAS,QAAQ,CAAC;AACzC,WAAO;YACA,OAAO;AACd,UAAM,OAAO,EAAS,OAAgB,CAAC;AAGvC,QAAI,iBAAiB,YAAY;KAC/B,MAAM,SAAS,MAAM,UAAU;KAC/B,MAAM,OAAO,4BAA4B,OAAO,MAAM,IAAI,SAAS;AACnE,YAAO,IAAI,SAAS,KAAK,UAAU,KAAK,EAAE;MACxC;MACA,SAAS,EAAE,gBAAgB,oBAAoB;MAChD,CAAC;;AAGJ,UAAM;;IAER;;;;;;;;;;;;;;;;;;;AAoBN,SAAgB,mBAA+C;AAC7D,SAAQ,EAAE,OAAO,OAAO,QAAQ,cAAc;EAC5C,MAAM,SAAS,MAAM,OAAO;AAE5B,MAAI,UAAU,iBAAiB,MAC7B,QAAO,MAAM,MAAM;EAGrB,MAAM,aAAa,iBAAiB,QAAQ,kBAAkB,MAAM,GAAG;AAEvE,MAAI,YAAY;GACd,MAAM,cAAc,mBAAmB,WAAW;GAClD,MAAM,WAAW,4BAA4B,YAAY,MAAM,IAAI,SAAS;AAC5E,UAAO;IACL,SAAS,SAAS;IAClB,QAAQ;IACR,KAAM,SAAS,MAA2B;IAC1C,KAAM,SAAS,MAA2B;IAC1C,MAAO,SAAS,MAA4B;IAC7C;;AAGH,SAAO;GAAE;GAAS;GAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuC9B,SAAgB,iBAAiB,UAAiC,EAAE,EAAE;AACpE,QAAO;EACL,QAAQ,MAAM,QAAQ;EACtB,aAAa,kBAAkB;EAChC"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/sveltekit/index.ts"],"sourcesContent":["import type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\nimport { resolveEvlogError, extractErrorStatus, serializeEvlogErrorResponse } from '../nitro'\nimport { EvlogError } from '../error'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'handle context. Make sure evlog() handle is added to your hooks.server.ts.',\n)\n\nexport type EvlogSvelteKitOptions = BaseEvlogOptions\n\nexport { useLogger }\n\n/**\n * SvelteKit `Handle` function signature — avoids a hard dependency on `@sveltejs/kit`.\n */\ntype SvelteKitHandle = (input: {\n event: { request: Request; url: URL; locals: Record<string, any> }\n resolve: (event: any) => Promise<Response>\n}) => Promise<Response>\n\n/**\n * SvelteKit `HandleServerError` signature — avoids a hard dependency on `@sveltejs/kit`.\n */\ntype SvelteKitHandleServerError = (input: {\n error: unknown\n event: { request: Request; url: URL; locals: Record<string, any> }\n status: number\n message: string\n}) => MaybePromise<void | AppError>\n\ntype MaybePromise<T> = T | Promise<T>\n\n/** Minimal SvelteKit `App.Error` shape */\ninterface AppError {\n message: string\n [key: string]: unknown\n}\n\n/**\n * Create an evlog handle hook for SvelteKit.\n *\n * Add it to your `src/hooks.server.ts` using SvelteKit's `sequence` helper\n * or as the sole handle export.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { initLogger } from 'evlog'\n * import { evlog } from 'evlog/sveltekit'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'my-sveltekit-app' } })\n *\n * export const handle = evlog({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n *\n * @example\n * ```ts\n * // Compose with other hooks using sequence\n * import { sequence } from '@sveltejs/kit/hooks'\n * import { evlog } from 'evlog/sveltekit'\n *\n * export const handle = sequence(evlog(), yourOtherHook)\n * ```\n */\nexport function evlog(options: EvlogSvelteKitOptions = {}): SvelteKitHandle {\n return async ({ event, resolve }) => {\n const { logger, finish, skipped } = createMiddlewareLogger({\n method: event.request.method,\n path: event.url.pathname,\n requestId: event.request.headers.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(event.request.headers),\n ...options,\n })\n\n if (skipped) {\n return await resolve(event)\n }\n\n event.locals.log = logger\n\n return storage.run(logger, async () => {\n try {\n const response = await resolve(event)\n\n // SvelteKit catches route errors internally and returns 500.\n // If handleError already logged an EvlogError with a specific status,\n // return a structured JSON response instead of SvelteKit's generic 500.\n const ctx = logger.getContext()\n const errorData = ctx.error as { name?: string; status?: number; message?: string; data?: unknown } | undefined\n if (response.status >= 500 && errorData?.name === 'EvlogError' && errorData.status) {\n const { status } = errorData\n await finish({ status })\n const body = serializeEvlogErrorResponse(errorData as EvlogError, event.url.pathname)\n return new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n }\n\n await finish({ status: response.status })\n return response\n } catch (error) {\n await finish({ error: error as Error })\n\n // Return structured JSON for EvlogError (like NextJS withEvlog / Nuxt errorHandler)\n if (error instanceof EvlogError) {\n const status = error.status ?? 500\n const body = serializeEvlogErrorResponse(error, event.url.pathname)\n return new Response(JSON.stringify(body), {\n status,\n headers: { 'content-type': 'application/json' },\n })\n }\n\n throw error\n }\n })\n }\n}\n\n/**\n * Create an evlog error handler for SvelteKit.\n *\n * Logs unhandled errors via `event.locals.log` (if available) and returns\n * structured error responses for `EvlogError` instances. For non-evlog errors,\n * returns a generic error response with sanitized messages in production.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { evlog, evlogHandleError } from 'evlog/sveltekit'\n *\n * export const handle = evlog()\n * export const handleError = evlogHandleError()\n * ```\n */\nexport function evlogHandleError(): SvelteKitHandleServerError {\n return ({ error, event, status, message }) => {\n const logger = event.locals.log as RequestLogger | undefined\n\n if (logger && error instanceof Error) {\n logger.error(error)\n }\n\n const evlogError = error instanceof Error ? resolveEvlogError(error) : null\n\n if (evlogError) {\n const errorStatus = extractErrorStatus(evlogError)\n const response = serializeEvlogErrorResponse(evlogError, event.url.pathname)\n return {\n message: response.message as string,\n status: errorStatus,\n why: (response.data as { why?: string })?.why,\n fix: (response.data as { fix?: string })?.fix,\n link: (response.data as { link?: string })?.link,\n } as AppError\n }\n\n return { message, status } as AppError\n }\n}\n\n/**\n * Create both `handle` and `handleError` hooks in a single call.\n *\n * This is the recommended setup for SvelteKit — it returns both hooks\n * pre-configured and ready to export from `hooks.server.ts`.\n *\n * @example\n * ```ts\n * // src/hooks.server.ts\n * import { initLogger } from 'evlog'\n * import { createEvlogHooks } from 'evlog/sveltekit'\n * import { createAxiomDrain } from 'evlog/axiom'\n *\n * initLogger({ env: { service: 'my-app' } })\n *\n * export const { handle, handleError } = createEvlogHooks({\n * drain: createAxiomDrain(),\n * enrich: (ctx) => {\n * ctx.event.region = process.env.FLY_REGION\n * },\n * })\n * ```\n *\n * @example\n * ```ts\n * // Compose with other hooks using sequence\n * import { sequence } from '@sveltejs/kit/hooks'\n * import { createEvlogHooks } from 'evlog/sveltekit'\n *\n * const evlogHooks = createEvlogHooks()\n *\n * export const handle = sequence(evlogHooks.handle, yourOtherHook)\n * export const handleError = evlogHooks.handleError\n * ```\n */\nexport function createEvlogHooks(options: EvlogSvelteKitOptions = {}) {\n return {\n handle: evlog(options),\n handleError: evlogHandleError(),\n }\n}\n"],"mappings":";;;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,6EACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgED,SAAgB,MAAM,UAAiC,EAAE,EAAmB;AAC1E,QAAO,OAAO,EAAE,OAAO,cAAc;EACnC,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB;GACzD,QAAQ,MAAM,QAAQ;GACtB,MAAM,MAAM,IAAI;GAChB,WAAW,MAAM,QAAQ,QAAQ,IAAI,eAAe,IAAI,OAAO,YAAY;GAC3E,SAAS,mBAAmB,MAAM,QAAQ,QAAQ;GAClD,GAAG;GACJ,CAAC;AAEF,MAAI,QACF,QAAO,MAAM,QAAQ,MAAM;AAG7B,QAAM,OAAO,MAAM;AAEnB,SAAO,QAAQ,IAAI,QAAQ,YAAY;AACrC,OAAI;IACF,MAAM,WAAW,MAAM,QAAQ,MAAM;IAMrC,MAAM,YADM,OAAO,YAAY,CACT;AACtB,QAAI,SAAS,UAAU,OAAO,WAAW,SAAS,gBAAgB,UAAU,QAAQ;KAClF,MAAM,EAAE,WAAW;AACnB,WAAM,OAAO,EAAE,QAAQ,CAAC;KACxB,MAAM,OAAO,4BAA4B,WAAyB,MAAM,IAAI,SAAS;AACrF,YAAO,IAAI,SAAS,KAAK,UAAU,KAAK,EAAE;MACxC;MACA,SAAS,EAAE,gBAAgB,oBAAoB;MAChD,CAAC;;AAGJ,UAAM,OAAO,EAAE,QAAQ,SAAS,QAAQ,CAAC;AACzC,WAAO;YACA,OAAO;AACd,UAAM,OAAO,EAAS,OAAgB,CAAC;AAGvC,QAAI,iBAAiB,YAAY;KAC/B,MAAM,SAAS,MAAM,UAAU;KAC/B,MAAM,OAAO,4BAA4B,OAAO,MAAM,IAAI,SAAS;AACnE,YAAO,IAAI,SAAS,KAAK,UAAU,KAAK,EAAE;MACxC;MACA,SAAS,EAAE,gBAAgB,oBAAoB;MAChD,CAAC;;AAGJ,UAAM;;IAER;;;;;;;;;;;;;;;;;;;AAoBN,SAAgB,mBAA+C;AAC7D,SAAQ,EAAE,OAAO,OAAO,QAAQ,cAAc;EAC5C,MAAM,SAAS,MAAM,OAAO;AAE5B,MAAI,UAAU,iBAAiB,MAC7B,QAAO,MAAM,MAAM;EAGrB,MAAM,aAAa,iBAAiB,QAAQ,kBAAkB,MAAM,GAAG;AAEvE,MAAI,YAAY;GACd,MAAM,cAAc,mBAAmB,WAAW;GAClD,MAAM,WAAW,4BAA4B,YAAY,MAAM,IAAI,SAAS;AAC5E,UAAO;IACL,SAAS,SAAS;IAClB,QAAQ;IACR,KAAM,SAAS,MAA2B;IAC1C,KAAM,SAAS,MAA2B;IAC1C,MAAO,SAAS,MAA4B;IAC7C;;AAGH,SAAO;GAAE;GAAS;GAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuC9B,SAAgB,iBAAiB,UAAiC,EAAE,EAAE;AACpE,QAAO;EACL,QAAQ,MAAM,QAAQ;EACtB,aAAa,kBAAkB;EAChC"}