evlog 2.14.0 → 2.15.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 (200) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +49 -19
  3. package/dist/adapters/axiom.d.mts +18 -27
  4. package/dist/adapters/axiom.d.mts.map +1 -1
  5. package/dist/adapters/axiom.mjs +40 -30
  6. package/dist/adapters/axiom.mjs.map +1 -1
  7. package/dist/adapters/better-stack.d.mts +11 -24
  8. package/dist/adapters/better-stack.d.mts.map +1 -1
  9. package/dist/adapters/better-stack.mjs +34 -29
  10. package/dist/adapters/better-stack.mjs.map +1 -1
  11. package/dist/adapters/datadog.d.mts +1 -1
  12. package/dist/adapters/datadog.d.mts.map +1 -1
  13. package/dist/adapters/datadog.mjs +10 -4
  14. package/dist/adapters/datadog.mjs.map +1 -1
  15. package/dist/adapters/fs.d.mts +2 -2
  16. package/dist/adapters/fs.d.mts.map +1 -1
  17. package/dist/adapters/fs.mjs +19 -7
  18. package/dist/adapters/fs.mjs.map +1 -1
  19. package/dist/adapters/hyperdx.d.mts +1 -1
  20. package/dist/adapters/hyperdx.mjs +1 -2
  21. package/dist/adapters/hyperdx.mjs.map +1 -1
  22. package/dist/adapters/otlp.d.mts +1 -1
  23. package/dist/adapters/otlp.d.mts.map +1 -1
  24. package/dist/adapters/otlp.mjs +36 -31
  25. package/dist/adapters/otlp.mjs.map +1 -1
  26. package/dist/adapters/posthog.d.mts +50 -70
  27. package/dist/adapters/posthog.d.mts.map +1 -1
  28. package/dist/adapters/posthog.mjs +50 -85
  29. package/dist/adapters/posthog.mjs.map +1 -1
  30. package/dist/adapters/sentry.d.mts +1 -1
  31. package/dist/adapters/sentry.d.mts.map +1 -1
  32. package/dist/adapters/sentry.mjs +15 -5
  33. package/dist/adapters/sentry.mjs.map +1 -1
  34. package/dist/ai/index.d.mts +1 -1
  35. package/dist/{audit-d9esRZOK.mjs → audit--n0QRR2Y.mjs} +202 -20
  36. package/dist/audit--n0QRR2Y.mjs.map +1 -0
  37. package/dist/{audit-mUutdf6A.d.mts → audit-CJl-wZ10.d.mts} +144 -2
  38. package/dist/audit-CJl-wZ10.d.mts.map +1 -0
  39. package/dist/better-auth/index.d.mts +1 -1
  40. package/dist/better-auth/index.mjs.map +1 -1
  41. package/dist/browser.d.mts +1 -1
  42. package/dist/define-D6OJdSUH.mjs +63 -0
  43. package/dist/define-D6OJdSUH.mjs.map +1 -0
  44. package/dist/define-Fp8TrdEB.d.mts +57 -0
  45. package/dist/define-Fp8TrdEB.d.mts.map +1 -0
  46. package/dist/{dist-Do8P4zWd.mjs → dist-BIlS38vi.mjs} +1 -1
  47. package/dist/dist-BIlS38vi.mjs.map +1 -0
  48. package/dist/drain-ByWUeOQC.mjs +160 -0
  49. package/dist/drain-ByWUeOQC.mjs.map +1 -0
  50. package/dist/elysia/index.d.mts +25 -2
  51. package/dist/elysia/index.d.mts.map +1 -1
  52. package/dist/elysia/index.mjs +53 -20
  53. package/dist/elysia/index.mjs.map +1 -1
  54. package/dist/enricher-BA6viylF.mjs +95 -0
  55. package/dist/enricher-BA6viylF.mjs.map +1 -0
  56. package/dist/enricher-CLSnrzrr.d.mts +42 -0
  57. package/dist/enricher-CLSnrzrr.d.mts.map +1 -0
  58. package/dist/enrichers.d.mts +16 -9
  59. package/dist/enrichers.d.mts.map +1 -1
  60. package/dist/enrichers.mjs +81 -64
  61. package/dist/enrichers.mjs.map +1 -1
  62. package/dist/{error-D1FZI2Kd.d.mts → error-C-66_G2M.d.mts} +2 -2
  63. package/dist/{error-D1FZI2Kd.d.mts.map → error-C-66_G2M.d.mts.map} +1 -1
  64. package/dist/error.d.mts +1 -1
  65. package/dist/{errors-BJRXUfMg.mjs → errors-BQgyQ9xe.mjs} +1 -1
  66. package/dist/{errors-BJRXUfMg.mjs.map → errors-BQgyQ9xe.mjs.map} +1 -1
  67. package/dist/{errors-NIXCyk6I.d.mts → errors-DQoYsDW1.d.mts} +2 -2
  68. package/dist/{errors-NIXCyk6I.d.mts.map → errors-DQoYsDW1.d.mts.map} +1 -1
  69. package/dist/event-ef-5Dbxg.mjs +53 -0
  70. package/dist/event-ef-5Dbxg.mjs.map +1 -0
  71. package/dist/express/index.d.mts +2 -2
  72. package/dist/express/index.d.mts.map +1 -1
  73. package/dist/express/index.mjs +17 -15
  74. package/dist/express/index.mjs.map +1 -1
  75. package/dist/fastify/index.d.mts +2 -2
  76. package/dist/fastify/index.d.mts.map +1 -1
  77. package/dist/fastify/index.mjs +19 -20
  78. package/dist/fastify/index.mjs.map +1 -1
  79. package/dist/fork-D44V93-K.mjs +227 -0
  80. package/dist/fork-D44V93-K.mjs.map +1 -0
  81. package/dist/{headers-D74M0wsg.mjs → headers-CU-QqnYg.mjs} +19 -2
  82. package/dist/headers-CU-QqnYg.mjs.map +1 -0
  83. package/dist/hono/index.d.mts +2 -2
  84. package/dist/hono/index.d.mts.map +1 -1
  85. package/dist/hono/index.mjs +14 -10
  86. package/dist/hono/index.mjs.map +1 -1
  87. package/dist/http.d.mts +1 -1
  88. package/dist/http.d.mts.map +1 -1
  89. package/dist/http.mjs +3 -2
  90. package/dist/http.mjs.map +1 -1
  91. package/dist/index.d.mts +8 -7
  92. package/dist/index.mjs +3 -2
  93. package/dist/integration-Bz8X6_Lb.mjs +75 -0
  94. package/dist/integration-Bz8X6_Lb.mjs.map +1 -0
  95. package/dist/{logger-b3epPH0N.d.mts → logger-Brt5-WMK.d.mts} +28 -3
  96. package/dist/logger-Brt5-WMK.d.mts.map +1 -0
  97. package/dist/logger.d.mts +2 -2
  98. package/dist/logger.mjs +2 -2
  99. package/dist/middleware-CGM-bOvE.d.mts +72 -0
  100. package/dist/middleware-CGM-bOvE.d.mts.map +1 -0
  101. package/dist/nestjs/index.d.mts +2 -2
  102. package/dist/nestjs/index.mjs +3 -4
  103. package/dist/nestjs/index.mjs.map +1 -1
  104. package/dist/next/client.d.mts +1 -1
  105. package/dist/next/index.d.mts +4 -4
  106. package/dist/next/index.mjs +3 -3
  107. package/dist/next/index.mjs.map +1 -1
  108. package/dist/next/instrumentation.d.mts +1 -1
  109. package/dist/next/instrumentation.mjs +1 -1
  110. package/dist/next/instrumentation.mjs.map +1 -1
  111. package/dist/nitro/errorHandler.mjs +2 -2
  112. package/dist/nitro/errorHandler.mjs.map +1 -1
  113. package/dist/nitro/module.d.mts +2 -2
  114. package/dist/nitro/plugin.mjs +21 -11
  115. package/dist/nitro/plugin.mjs.map +1 -1
  116. package/dist/nitro/v3/errorHandler.mjs +3 -3
  117. package/dist/nitro/v3/index.d.mts +2 -2
  118. package/dist/nitro/v3/middleware.mjs.map +1 -1
  119. package/dist/nitro/v3/module.d.mts +1 -1
  120. package/dist/nitro/v3/plugin.mjs +29 -17
  121. package/dist/nitro/v3/plugin.mjs.map +1 -1
  122. package/dist/nitro/v3/useLogger.d.mts +1 -1
  123. package/dist/nitro/v3/useLogger.mjs.map +1 -1
  124. package/dist/{nitro-DenB86W6.d.mts → nitro-DHPb9dXG.d.mts} +2 -2
  125. package/dist/{nitro-DenB86W6.d.mts.map → nitro-DHPb9dXG.d.mts.map} +1 -1
  126. package/dist/{nitro-OmT_M4Pb.mjs → nitro-DavLelNz.mjs} +2 -2
  127. package/dist/nitro-DavLelNz.mjs.map +1 -0
  128. package/dist/{nitroConfigBridge-C37lXaNm.mjs → nitroConfigBridge-aZ1e5upQ.mjs} +1 -1
  129. package/dist/nitroConfigBridge-aZ1e5upQ.mjs.map +1 -0
  130. package/dist/nuxt/module.d.mts +1 -1
  131. package/dist/nuxt/module.mjs +2 -2
  132. package/dist/{parseError-BR9pocvY.d.mts → parseError-B1zJZvQ5.d.mts} +2 -2
  133. package/dist/parseError-B1zJZvQ5.d.mts.map +1 -0
  134. package/dist/pipeline.mjs.map +1 -1
  135. package/dist/react-router/index.d.mts +2 -2
  136. package/dist/react-router/index.mjs +3 -4
  137. package/dist/react-router/index.mjs.map +1 -1
  138. package/dist/{routes-CGPmbzCZ.mjs → routes-B48wm7Pb.mjs} +1 -1
  139. package/dist/{routes-CGPmbzCZ.mjs.map → routes-B48wm7Pb.mjs.map} +1 -1
  140. package/dist/runtime/client/log.d.mts +1 -1
  141. package/dist/runtime/client/log.mjs +2 -2
  142. package/dist/runtime/client/log.mjs.map +1 -1
  143. package/dist/runtime/client/plugin.mjs.map +1 -1
  144. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +21 -10
  145. package/dist/runtime/server/routes/_evlog/ingest.post.mjs.map +1 -1
  146. package/dist/runtime/server/useLogger.d.mts +1 -1
  147. package/dist/runtime/server/useLogger.mjs.map +1 -1
  148. package/dist/runtime/utils/parseError.d.mts +2 -2
  149. package/dist/runtime/utils/parseError.mjs +1 -1
  150. package/dist/{_severity-CQijvfhU.mjs → severity-BYWZ96Sb.mjs} +6 -2
  151. package/dist/severity-BYWZ96Sb.mjs.map +1 -0
  152. package/dist/{source-location-DRvDDqfq.mjs → source-location-Dco0cRTz.mjs} +3 -3
  153. package/dist/source-location-Dco0cRTz.mjs.map +1 -0
  154. package/dist/storage-BT-3fT1-.mjs +27 -0
  155. package/dist/storage-BT-3fT1-.mjs.map +1 -0
  156. package/dist/sveltekit/index.d.mts +2 -2
  157. package/dist/sveltekit/index.mjs +5 -6
  158. package/dist/sveltekit/index.mjs.map +1 -1
  159. package/dist/toolkit.d.mts +288 -12
  160. package/dist/toolkit.d.mts.map +1 -1
  161. package/dist/toolkit.mjs +13 -7
  162. package/dist/types.d.mts +1 -1
  163. package/dist/{useLogger-C56tDPwf.d.mts → useLogger-Cb1R6bQE.d.mts} +2 -2
  164. package/dist/{useLogger-C56tDPwf.d.mts.map → useLogger-Cb1R6bQE.d.mts.map} +1 -1
  165. package/dist/{utils-DzGCLRFe.d.mts → utils-gQCeZMbg.d.mts} +4 -3
  166. package/dist/utils-gQCeZMbg.d.mts.map +1 -0
  167. package/dist/utils.d.mts +2 -2
  168. package/dist/utils.mjs +7 -1
  169. package/dist/utils.mjs.map +1 -1
  170. package/dist/vite/index.d.mts +1 -1
  171. package/dist/vite/index.mjs +1 -1
  172. package/dist/vite/index.mjs.map +1 -1
  173. package/dist/workers.d.mts +48 -4
  174. package/dist/workers.d.mts.map +1 -1
  175. package/dist/workers.mjs +32 -5
  176. package/dist/workers.mjs.map +1 -1
  177. package/package.json +38 -39
  178. package/dist/_drain-CmCtsuF6.mjs +0 -23
  179. package/dist/_drain-CmCtsuF6.mjs.map +0 -1
  180. package/dist/_http-CHSsrWDJ.mjs +0 -71
  181. package/dist/_http-CHSsrWDJ.mjs.map +0 -1
  182. package/dist/_severity-CQijvfhU.mjs.map +0 -1
  183. package/dist/audit-d9esRZOK.mjs.map +0 -1
  184. package/dist/audit-mUutdf6A.d.mts.map +0 -1
  185. package/dist/dist-Do8P4zWd.mjs.map +0 -1
  186. package/dist/fork-CTJXnpl8.mjs +0 -72
  187. package/dist/fork-CTJXnpl8.mjs.map +0 -1
  188. package/dist/headers-D74M0wsg.mjs.map +0 -1
  189. package/dist/logger-b3epPH0N.d.mts.map +0 -1
  190. package/dist/middleware-BWOJ7JI0.mjs +0 -123
  191. package/dist/middleware-BWOJ7JI0.mjs.map +0 -1
  192. package/dist/middleware-BYf26Lfu.d.mts +0 -93
  193. package/dist/middleware-BYf26Lfu.d.mts.map +0 -1
  194. package/dist/nitro-OmT_M4Pb.mjs.map +0 -1
  195. package/dist/nitroConfigBridge-C37lXaNm.mjs.map +0 -1
  196. package/dist/parseError-BR9pocvY.d.mts.map +0 -1
  197. package/dist/source-location-DRvDDqfq.mjs.map +0 -1
  198. package/dist/storage-CFGTn37X.mjs +0 -46
  199. package/dist/storage-CFGTn37X.mjs.map +0 -1
  200. package/dist/utils-DzGCLRFe.d.mts.map +0 -1
@@ -1,3 +1,110 @@
1
+ //#region src/shared/plugin.d.ts
2
+ /** Context passed to {@link EvlogPlugin.setup} when the plugin is registered. */
3
+ interface PluginSetupContext {
4
+ env: EnvironmentContext;
5
+ }
6
+ /** Per-request context for `onRequestStart` / `onRequestFinish`. */
7
+ interface RequestLifecycleContext {
8
+ logger: RequestLogger;
9
+ request: {
10
+ method: string;
11
+ path: string;
12
+ requestId?: string;
13
+ };
14
+ /** Pre-filtered safe request headers (sensitive headers stripped). */
15
+ headers?: Record<string, string>;
16
+ }
17
+ interface RequestFinishContext extends RequestLifecycleContext {
18
+ /** `null` when the event was sampled out or disabled. */
19
+ event: WideEvent | null;
20
+ status?: number;
21
+ durationMs: number;
22
+ error?: Error;
23
+ }
24
+ /** Context passed to {@link EvlogPlugin.onClientLog} for client-submitted events. */
25
+ interface ClientLogContext {
26
+ /** Raw client payload, before normalization. */
27
+ payload: Record<string, unknown>;
28
+ request?: {
29
+ method?: string;
30
+ path?: string;
31
+ };
32
+ headers?: Record<string, string>;
33
+ }
34
+ /**
35
+ * Canonical extension point for evlog. A plugin can opt into any subset of
36
+ * hooks; drains and enrichers are special cases (see {@link drainPlugin} and
37
+ * {@link enricherPlugin}).
38
+ *
39
+ * @example
40
+ * ```ts
41
+ * export const tenantPlugin = definePlugin({
42
+ * name: 'tenant',
43
+ * onRequestStart({ logger, headers }) {
44
+ * const tenantId = headers?.['x-tenant-id']
45
+ * if (tenantId) logger.set({ tenant: { id: tenantId } })
46
+ * },
47
+ * enrich({ event }) {
48
+ * event.region = process.env.REGION
49
+ * },
50
+ * })
51
+ * ```
52
+ */
53
+ interface EvlogPlugin {
54
+ /** Stable identifier. Used for de-duplication and error messages. */
55
+ name: string;
56
+ /** Run-once when the plugin is registered. */
57
+ setup?: (ctx: PluginSetupContext) => void | Promise<void>;
58
+ /** Runs before drain. */
59
+ enrich?: (ctx: EnrichContext) => void | Promise<void>;
60
+ /** Called for every emitted event. */
61
+ drain?: (ctx: DrainContext) => void | Promise<void>;
62
+ /** Tail sampling hook. Set `ctx.shouldKeep = true` to force-keep. */
63
+ keep?: (ctx: TailSamplingContext) => void | Promise<void>;
64
+ onRequestStart?: (ctx: RequestLifecycleContext) => void;
65
+ onRequestFinish?: (ctx: RequestFinishContext) => void;
66
+ /** Observe events submitted from browser/edge clients. */
67
+ onClientLog?: (ctx: ClientLogContext) => void;
68
+ /**
69
+ * Decorate per-request loggers with extra methods. Augment `RequestLogger`
70
+ * in a `.d.ts` to expose them on `useLogger()`.
71
+ */
72
+ extendLogger?: (logger: RequestLogger) => void;
73
+ }
74
+ /** Identity helper preserving plugin type inference. */
75
+ declare function definePlugin(plugin: EvlogPlugin): EvlogPlugin;
76
+ /** Wrap a standalone drain callback as an {@link EvlogPlugin}. */
77
+ declare function drainPlugin(name: string, drain: NonNullable<EvlogPlugin['drain']>): EvlogPlugin;
78
+ /** Wrap a standalone enricher callback as an {@link EvlogPlugin}. */
79
+ declare function enricherPlugin(name: string, enrich: NonNullable<EvlogPlugin['enrich']>): EvlogPlugin;
80
+ /**
81
+ * Compiled view of a plugin set. Errors from individual hooks are caught and
82
+ * logged to `console.error` with the plugin name — they never break the request.
83
+ */
84
+ interface PluginRunner {
85
+ readonly plugins: readonly EvlogPlugin[];
86
+ /** `true` when at least one plugin implements the matching hook. */
87
+ readonly hasEnrich: boolean;
88
+ readonly hasDrain: boolean;
89
+ readonly hasKeep: boolean;
90
+ readonly hasRequestLifecycle: boolean;
91
+ readonly hasClientLog: boolean;
92
+ readonly hasExtendLogger: boolean;
93
+ applyExtendLogger: (logger: RequestLogger) => void;
94
+ runOnRequestStart: (ctx: RequestLifecycleContext) => void;
95
+ runOnRequestFinish: (ctx: RequestFinishContext) => void;
96
+ runEnrich: (ctx: EnrichContext) => Promise<void>;
97
+ /** Drains run concurrently (`Promise.allSettled`). */
98
+ runDrain: (ctx: DrainContext) => Promise<void>;
99
+ runKeep: (ctx: TailSamplingContext) => Promise<void>;
100
+ runOnClientLog: (ctx: ClientLogContext) => void;
101
+ runSetup: (ctx: PluginSetupContext) => Promise<void>;
102
+ }
103
+ /** De-duplicates by `name` — last registration wins. */
104
+ declare function createPluginRunner(plugins?: EvlogPlugin[]): PluginRunner;
105
+ /** Shared no-op runner used when no plugins are registered. */
106
+ declare function getEmptyPluginRunner(): PluginRunner;
107
+ //#endregion
1
108
  //#region src/types.d.ts
2
109
  declare module 'nitropack/types' {
3
110
  interface NitroRuntimeHooks {
@@ -359,6 +466,31 @@ interface LoggerConfig {
359
466
  * ```
360
467
  */
361
468
  drain?: (ctx: DrainContext) => void | Promise<void>;
469
+ /**
470
+ * Plugins registered globally with the logger.
471
+ *
472
+ * Plugins are the canonical extension contract for evlog: they can opt into
473
+ * `enrich`, `drain`, `keep`, lifecycle hooks (`onRequestStart`, `onRequestFinish`),
474
+ * client-log observation, and per-request logger decoration. See
475
+ * {@link import('./shared/plugin').EvlogPlugin} for the full surface.
476
+ *
477
+ * Plugin drains run alongside the standalone `drain` callback (composed with
478
+ * `Promise.allSettled`), so you can mix one-off drains and plugin-shaped
479
+ * extensions safely.
480
+ *
481
+ * @example
482
+ * ```ts
483
+ * import { initLogger, definePlugin } from 'evlog'
484
+ * import { createAxiomDrain } from 'evlog/axiom'
485
+ *
486
+ * initLogger({
487
+ * plugins: [
488
+ * definePlugin({ name: 'axiom', drain: createAxiomDrain() }),
489
+ * ],
490
+ * })
491
+ * ```
492
+ */
493
+ plugins?: Array<EvlogPlugin>;
362
494
  /** @internal Suppress the "silent without drain" warning (used by hook-based frameworks like Nitro/Nuxt) */
363
495
  _suppressDrainWarning?: boolean;
364
496
  }
@@ -700,6 +832,16 @@ interface RequestLoggerOptions {
700
832
  method?: string;
701
833
  path?: string;
702
834
  requestId?: string;
835
+ /**
836
+ * Registers async drain work with the host runtime so it can finish after the
837
+ * HTTP response is returned. Required on **Cloudflare Workers** (and similar
838
+ * edge runtimes): without this, `initLogger({ drain })` + `log.emit()` may
839
+ * never complete outbound HTTP to observability backends.
840
+ *
841
+ * Pass the same function you would pass to `ExecutionContext#waitUntil`, e.g.
842
+ * `context.waitUntil.bind(context)` from a Workers `fetch` handler.
843
+ */
844
+ waitUntil?: (promise: Promise<unknown>) => void;
703
845
  }
704
846
  /**
705
847
  * H3 event context with evlog logger attached
@@ -1126,5 +1268,5 @@ declare function signed(drain: DrainFn, options: SignedOptions): DrainFn;
1126
1268
  */
1127
1269
  declare const auditRedactPreset: RedactConfig;
1128
1270
  //#endregion
1129
- export { SamplingRates as $, AuditFields as A, H3EventContext as B, buildAuditFields as C, withAudit as D, signed as E, DrainContext as F, LoggerConfig as G, InternalFields as H, EnrichContext as I, RequestLogEntry as J, ParsedError as K, EnvironmentContext as L, AuditTarget as M, BaseWideEvent as N, withAuditMethods as O, DeepPartial as P, SamplingConfig as Q, ErrorOptions as R, auditRedactPreset as S, mockAudit as T, Log as U, IngestPayload as V, LogLevel as W, RequestLoggerOptions as X, RequestLogger as Y, RouteConfig as Z, WithAuditOptions as _, AuditInput as a, auditEnricher as b, AuditOnlyOptions as c, DefinedAuditAction as d, ServerEvent as et, DrainFn as f, WithAuditContext as g, SignedOptions as h, AuditEnricherOptions as i, WideEvent as it, AuditLoggerMethod as j, AuditActor as k, AuditPatchOp as l, SignedChainState as m, AuditDeniedError as n, TailSamplingContext as nt, AuditMatcher as o, MockAudit as p, RedactConfig as q, AuditDiffOptions as r, TransportConfig as rt, AuditMethod as s, AUDIT_SCHEMA_VERSION as t, TailSamplingCondition as tt, AuditableLogger as u, audit as v, defineAuditAction as w, auditOnly as x, auditDiff as y, FieldContext as z };
1130
- //# sourceMappingURL=audit-mUutdf6A.d.mts.map
1271
+ export { SamplingRates as $, AuditFields as A, H3EventContext as B, buildAuditFields as C, withAudit as D, signed as E, DrainContext as F, LoggerConfig as G, InternalFields as H, EnrichContext as I, RequestLogEntry as J, ParsedError as K, EnvironmentContext as L, AuditTarget as M, BaseWideEvent as N, withAuditMethods as O, DeepPartial as P, SamplingConfig as Q, ErrorOptions as R, auditRedactPreset as S, mockAudit as T, Log as U, IngestPayload as V, LogLevel as W, RequestLoggerOptions as X, RequestLogger as Y, RouteConfig as Z, WithAuditOptions as _, AuditInput as a, ClientLogContext as at, auditEnricher as b, AuditOnlyOptions as c, PluginSetupContext as ct, DefinedAuditAction as d, createPluginRunner as dt, ServerEvent as et, DrainFn as f, definePlugin as ft, WithAuditContext as g, SignedOptions as h, getEmptyPluginRunner as ht, AuditEnricherOptions as i, WideEvent as it, AuditLoggerMethod as j, AuditActor as k, AuditPatchOp as l, RequestFinishContext as lt, SignedChainState as m, enricherPlugin as mt, AuditDeniedError as n, TailSamplingContext as nt, AuditMatcher as o, EvlogPlugin as ot, MockAudit as p, drainPlugin as pt, RedactConfig as q, AuditDiffOptions as r, TransportConfig as rt, AuditMethod as s, PluginRunner as st, AUDIT_SCHEMA_VERSION as t, TailSamplingCondition as tt, AuditableLogger as u, RequestLifecycleContext as ut, audit as v, defineAuditAction as w, auditOnly as x, auditDiff as y, FieldContext as z };
1272
+ //# sourceMappingURL=audit-CJl-wZ10.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-CJl-wZ10.d.mts","names":[],"sources":["../src/shared/plugin.ts","../src/types.ts","../src/audit.ts"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { Y as RequestLogger } from "../audit-mUutdf6A.mjs";
1
+ import { Y as RequestLogger } from "../audit-CJl-wZ10.mjs";
2
2
 
3
3
  //#region src/better-auth/index.d.ts
4
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/better-auth/index.ts"],"sourcesContent":["import type { RequestLogger } from '../types'\nimport { matchesPattern } from '../utils'\n\n/**\n * Minimal type for the Better Auth instance.\n * Only requires `api.getSession` — compatible with any Better Auth configuration.\n */\nexport interface BetterAuthInstance {\n api: {\n getSession: (opts: {\n headers: Headers | Record<string, string | string[] | undefined>\n }) => Promise<{\n user: Record<string, unknown>\n session: Record<string, unknown>\n } | null>\n }\n}\n\n/**\n * User fields extracted from a Better Auth session.\n */\nexport interface AuthUserData {\n id: string\n name?: string\n email?: string\n image?: string\n emailVerified?: boolean\n createdAt?: string\n}\n\n/**\n * Session fields extracted from a Better Auth session.\n */\nexport interface AuthSessionData {\n id: string\n expiresAt?: string\n ipAddress?: string\n userAgent?: string\n createdAt?: string\n}\n\n/**\n * Options for `identifyUser`.\n */\nexport interface IdentifyOptions {\n /**\n * Whether to mask the user email (e.g. `h***@domain.com`).\n * @default false\n */\n maskEmail?: boolean\n /**\n * Whether to include session metadata on the wide event.\n * @default true\n */\n session?: boolean\n /**\n * Whitelist of user fields to include.\n * @default ['id', 'name', 'email', 'image', 'emailVerified', 'createdAt']\n */\n fields?: string[]\n /**\n * Extend the wide event with additional fields derived from the session.\n * Useful for Better Auth plugins (organizations, roles, etc.).\n *\n * @example\n * ```ts\n * identifyUser(log, session, {\n * extend: (session) => ({\n * organization: session.user.activeOrganization,\n * role: session.user.role,\n * }),\n * })\n * ```\n */\n extend?: (session: { user: Record<string, unknown>, session: Record<string, unknown> }) => Record<string, unknown> | undefined\n}\n\n/**\n * Options for `createAuthMiddleware`.\n */\nexport interface AuthMiddlewareOptions extends IdentifyOptions {\n /**\n * Route patterns to skip session resolution (glob).\n * @default ['/api/auth/**']\n */\n exclude?: string[]\n /**\n * Route patterns to apply session resolution (glob).\n * If set, only matching routes are resolved.\n */\n include?: string[]\n /**\n * Called after a user is successfully identified.\n * Use to add conditional logic based on user data (e.g. force-keep logs for premium users).\n */\n onIdentify?: (log: RequestLogger, session: { user: Record<string, unknown>, session: Record<string, unknown> }) => void | Promise<void>\n /**\n * Called when no session is found (anonymous request).\n */\n onAnonymous?: (log: RequestLogger) => void | Promise<void>\n}\n\n/**\n * Options for `createAuthIdentifier`.\n */\nexport type AuthIdentifierOptions = AuthMiddlewareOptions\n\nconst DEFAULT_USER_FIELDS = ['id', 'name', 'email', 'image', 'emailVerified', 'createdAt']\n\nconst isDev = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n\n/**\n * Mask an email address for safe logging: `hugo@example.com` -> `h***@example.com`.\n */\nexport function maskEmail(email: string): string {\n const atIndex = email.indexOf('@')\n if (atIndex <= 0) return '***'\n return `${email[0]}***${email.slice(atIndex)}`\n}\n\nfunction extractUserData(\n user: Record<string, unknown>,\n options?: IdentifyOptions,\n): AuthUserData {\n const fields = options?.fields ?? DEFAULT_USER_FIELDS\n const data: Record<string, unknown> = {}\n\n if (user.id !== undefined && user.id !== null) {\n data.id = user.id\n }\n\n for (const field of fields) {\n if (field === 'id') continue\n const value = user[field]\n if (value === undefined || value === null) continue\n\n if (field === 'email' && options?.maskEmail && typeof value === 'string') {\n data[field] = maskEmail(value)\n } else if (field === 'createdAt' && value instanceof Date) {\n data[field] = value.toISOString()\n } else {\n data[field] = value\n }\n }\n\n return data as unknown as AuthUserData\n}\n\nfunction extractSessionData(\n session: Record<string, unknown>,\n): AuthSessionData {\n const data: AuthSessionData = { id: String(session.id) }\n\n if (session.expiresAt) {\n data.expiresAt = session.expiresAt instanceof Date\n ? session.expiresAt.toISOString()\n : String(session.expiresAt)\n }\n if (typeof session.ipAddress === 'string') data.ipAddress = session.ipAddress\n if (typeof session.userAgent === 'string') data.userAgent = session.userAgent\n if (session.createdAt) {\n data.createdAt = session.createdAt instanceof Date\n ? session.createdAt.toISOString()\n : String(session.createdAt)\n }\n\n return data\n}\n\n/**\n * Identify a user on a wide event from a Better Auth session result.\n *\n * Sets `userId`, `user`, and optionally `session` fields on the logger.\n * Safe by default — only extracts whitelisted fields and never logs passwords or tokens.\n *\n * Returns `true` if the user was identified, `false` if session data was missing.\n *\n * @example\n * ```ts\n * import { identifyUser } from 'evlog/better-auth'\n *\n * const session = await auth.api.getSession({ headers: event.headers })\n * if (session) {\n * identifyUser(log, session)\n * }\n * ```\n *\n * @example With email masking\n * ```ts\n * identifyUser(log, session, { maskEmail: true })\n * // user.email → \"h***@example.com\"\n * ```\n *\n * @example With extend for Better Auth plugins\n * ```ts\n * identifyUser(log, session, {\n * extend: (s) => ({\n * organization: s.user.activeOrganization,\n * role: s.user.role,\n * }),\n * })\n * ```\n */\nexport function identifyUser(\n log: RequestLogger,\n session: { user: Record<string, unknown>, session: Record<string, unknown> },\n options?: IdentifyOptions,\n): boolean {\n const user = extractUserData(session.user, options)\n if (!user.id) return false\n\n const includeSession = options?.session !== false\n\n const data: Record<string, unknown> = {\n userId: user.id,\n user,\n }\n\n if (includeSession) {\n data.session = extractSessionData(session.session)\n }\n\n if (options?.extend) {\n const extra = options.extend(session)\n if (extra) Object.assign(data, extra)\n }\n\n log.set(data)\n return true\n}\n\nfunction shouldResolve(path: string, options?: { exclude?: string[], include?: string[] }): boolean {\n const exclude = options?.exclude ?? ['/api/auth/**']\n for (const pattern of exclude) {\n if (matchesPattern(path, pattern)) return false\n }\n\n if (options?.include) {\n for (const pattern of options.include) {\n if (matchesPattern(path, pattern)) return true\n }\n return false\n }\n\n return true\n}\n\n/**\n * Create an async function that resolves a Better Auth session from headers\n * and identifies the user on the logger.\n *\n * Works with any framework — just pass the auth instance and call the returned\n * function with a logger and headers. Supports `include`/`exclude` route patterns\n * and lifecycle hooks (`onIdentify`, `onAnonymous`).\n *\n * @example Nuxt server middleware\n * ```ts\n * import { createAuthMiddleware } from 'evlog/better-auth'\n *\n * const identify = createAuthMiddleware(auth, {\n * exclude: ['/api/auth/**', '/api/public/**'],\n * })\n *\n * export default defineEventHandler(async (event) => {\n * if (!event.context.log) return\n * await identify(event.context.log, event.headers, event.path)\n * })\n * ```\n *\n * @example Express\n * ```ts\n * const identify = createAuthMiddleware(auth, { maskEmail: true })\n *\n * app.use(async (req, res, next) => {\n * await identify(req.log, req.headers, req.path)\n * next()\n * })\n * ```\n */\nexport function createAuthMiddleware(\n auth: BetterAuthInstance,\n options?: AuthMiddlewareOptions,\n): (log: RequestLogger, headers: Headers | Record<string, string | string[] | undefined>, path?: string) => Promise<boolean> {\n return async (log, headers, path?) => {\n if (path && !shouldResolve(path, options)) return false\n\n const start = Date.now()\n try {\n const session = await auth.api.getSession({ headers })\n const resolvedIn = Date.now() - start\n\n if (session) {\n const identified = identifyUser(log, session, options)\n if (identified) {\n log.set({ auth: { resolvedIn, identified: true } } as Record<string, unknown>)\n if (options?.onIdentify) await options.onIdentify(log, session)\n return true\n }\n }\n\n log.set({ auth: { resolvedIn, identified: false } } as Record<string, unknown>)\n if (options?.onAnonymous) await options.onAnonymous(log)\n return false\n } catch (err) {\n const resolvedIn = Date.now() - start\n log.set({ auth: { resolvedIn, identified: false, error: true } } as Record<string, unknown>)\n if (isDev) console.warn('[evlog/better-auth] Session resolution failed:', err)\n if (options?.onAnonymous) await options.onAnonymous(log)\n return false\n }\n }\n}\n\n/**\n * Create a Nitro `request` hook that auto-identifies users from Better Auth sessions.\n *\n * Resolves the session from request cookies on every request and sets user/session\n * context on the evlog logger. Skips `/api/auth/**` by default to avoid resolving\n * sessions during auth flows.\n *\n * @example\n * ```ts\n * // server/plugins/evlog-auth.ts\n * import { createAuthIdentifier } from 'evlog/better-auth'\n * import { auth } from '~/lib/auth'\n *\n * export default defineNitroPlugin((nitroApp) => {\n * nitroApp.hooks.hook('request', createAuthIdentifier(auth))\n * })\n * ```\n *\n * @example With options\n * ```ts\n * nitroApp.hooks.hook('request', createAuthIdentifier(auth, {\n * maskEmail: true,\n * exclude: ['/api/auth/**', '/api/public/**'],\n * }))\n * ```\n */\nexport function createAuthIdentifier(\n auth: BetterAuthInstance,\n options?: AuthIdentifierOptions,\n): (event: { path: string, headers: Headers | { get(name: string): string | null }, context: { log?: RequestLogger } }) => Promise<void> {\n const middleware = createAuthMiddleware(auth, options)\n\n return async (event) => {\n if (!event.context.log) return\n await middleware(event.context.log, event.headers as Headers, event.path)\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/better-auth/index.ts"],"sourcesContent":["import type { RequestLogger } from '../types'\nimport { matchesPattern } from '../utils'\n\n/**\n * Minimal type for the Better Auth instance.\n * Only requires `api.getSession` — compatible with any Better Auth configuration.\n */\nexport interface BetterAuthInstance {\n api: {\n getSession: (opts: {\n headers: Headers | Record<string, string | string[] | undefined>\n }) => Promise<{\n user: Record<string, unknown>\n session: Record<string, unknown>\n } | null>\n }\n}\n\n/**\n * User fields extracted from a Better Auth session.\n */\nexport interface AuthUserData {\n id: string\n name?: string\n email?: string\n image?: string\n emailVerified?: boolean\n createdAt?: string\n}\n\n/**\n * Session fields extracted from a Better Auth session.\n */\nexport interface AuthSessionData {\n id: string\n expiresAt?: string\n ipAddress?: string\n userAgent?: string\n createdAt?: string\n}\n\n/**\n * Options for `identifyUser`.\n */\nexport interface IdentifyOptions {\n /**\n * Whether to mask the user email (e.g. `h***@domain.com`).\n * @default false\n */\n maskEmail?: boolean\n /**\n * Whether to include session metadata on the wide event.\n * @default true\n */\n session?: boolean\n /**\n * Whitelist of user fields to include.\n * @default ['id', 'name', 'email', 'image', 'emailVerified', 'createdAt']\n */\n fields?: string[]\n /**\n * Extend the wide event with additional fields derived from the session.\n * Useful for Better Auth plugins (organizations, roles, etc.).\n *\n * @example\n * ```ts\n * identifyUser(log, session, {\n * extend: (session) => ({\n * organization: session.user.activeOrganization,\n * role: session.user.role,\n * }),\n * })\n * ```\n */\n extend?: (session: { user: Record<string, unknown>, session: Record<string, unknown> }) => Record<string, unknown> | undefined\n}\n\n/**\n * Options for `createAuthMiddleware`.\n */\nexport interface AuthMiddlewareOptions extends IdentifyOptions {\n /**\n * Route patterns to skip session resolution (glob).\n * @default ['/api/auth/**']\n */\n exclude?: string[]\n /**\n * Route patterns to apply session resolution (glob).\n * If set, only matching routes are resolved.\n */\n include?: string[]\n /**\n * Called after a user is successfully identified.\n * Use to add conditional logic based on user data (e.g. force-keep logs for premium users).\n */\n onIdentify?: (log: RequestLogger, session: { user: Record<string, unknown>, session: Record<string, unknown> }) => void | Promise<void>\n /**\n * Called when no session is found (anonymous request).\n */\n onAnonymous?: (log: RequestLogger) => void | Promise<void>\n}\n\n/**\n * Options for `createAuthIdentifier`.\n */\nexport type AuthIdentifierOptions = AuthMiddlewareOptions\n\nconst DEFAULT_USER_FIELDS = ['id', 'name', 'email', 'image', 'emailVerified', 'createdAt']\n\nconst isDev = typeof process !== 'undefined' && process.env?.NODE_ENV !== 'production'\n\n/**\n * Mask an email address for safe logging: `hugo@example.com` -> `h***@example.com`.\n */\nexport function maskEmail(email: string): string {\n const atIndex = email.indexOf('@')\n if (atIndex <= 0) return '***'\n return `${email[0]}***${email.slice(atIndex)}`\n}\n\nfunction extractUserData(\n user: Record<string, unknown>,\n options?: IdentifyOptions,\n): AuthUserData {\n const fields = options?.fields ?? DEFAULT_USER_FIELDS\n const data: Record<string, unknown> = {}\n\n if (user.id !== undefined && user.id !== null) {\n data.id = user.id\n }\n\n for (const field of fields) {\n if (field === 'id') continue\n const value = user[field]\n if (value === undefined || value === null) continue\n\n if (field === 'email' && options?.maskEmail && typeof value === 'string') {\n data[field] = maskEmail(value)\n } else if (field === 'createdAt' && value instanceof Date) {\n data[field] = value.toISOString()\n } else {\n data[field] = value\n }\n }\n\n return data as unknown as AuthUserData\n}\n\nfunction extractSessionData(\n session: Record<string, unknown>,\n): AuthSessionData {\n const data: AuthSessionData = { id: String(session.id) }\n\n if (session.expiresAt) {\n data.expiresAt = session.expiresAt instanceof Date\n ? session.expiresAt.toISOString()\n : String(session.expiresAt)\n }\n if (typeof session.ipAddress === 'string') data.ipAddress = session.ipAddress\n if (typeof session.userAgent === 'string') data.userAgent = session.userAgent\n if (session.createdAt) {\n data.createdAt = session.createdAt instanceof Date\n ? session.createdAt.toISOString()\n : String(session.createdAt)\n }\n\n return data\n}\n\n/**\n * Identify a user on a wide event from a Better Auth session result.\n *\n * Sets `userId`, `user`, and optionally `session` fields on the logger.\n * Safe by default — only extracts whitelisted fields and never logs passwords or tokens.\n *\n * Returns `true` if the user was identified, `false` if session data was missing.\n *\n * @example\n * ```ts\n * import { identifyUser } from 'evlog/better-auth'\n *\n * const session = await auth.api.getSession({ headers: event.headers })\n * if (session) {\n * identifyUser(log, session)\n * }\n * ```\n *\n * @example With email masking\n * ```ts\n * identifyUser(log, session, { maskEmail: true })\n * // user.email → \"h***@example.com\"\n * ```\n *\n * @example With extend for Better Auth plugins\n * ```ts\n * identifyUser(log, session, {\n * extend: (s) => ({\n * organization: s.user.activeOrganization,\n * role: s.user.role,\n * }),\n * })\n * ```\n */\nexport function identifyUser(\n log: RequestLogger,\n session: { user: Record<string, unknown>, session: Record<string, unknown> },\n options?: IdentifyOptions,\n): boolean {\n const user = extractUserData(session.user, options)\n if (!user.id) return false\n\n const includeSession = options?.session !== false\n\n const data: Record<string, unknown> = {\n userId: user.id,\n user,\n }\n\n if (includeSession) {\n data.session = extractSessionData(session.session)\n }\n\n if (options?.extend) {\n const extra = options.extend(session)\n if (extra) Object.assign(data, extra)\n }\n\n log.set(data)\n return true\n}\n\nfunction shouldResolve(path: string, options?: { exclude?: string[], include?: string[] }): boolean {\n const exclude = options?.exclude ?? ['/api/auth/**']\n for (const pattern of exclude) {\n if (matchesPattern(path, pattern)) return false\n }\n\n if (options?.include) {\n for (const pattern of options.include) {\n if (matchesPattern(path, pattern)) return true\n }\n return false\n }\n\n return true\n}\n\n/**\n * Create an async function that resolves a Better Auth session from headers\n * and identifies the user on the logger.\n *\n * Works with any framework — just pass the auth instance and call the returned\n * function with a logger and headers. Supports `include`/`exclude` route patterns\n * and lifecycle hooks (`onIdentify`, `onAnonymous`).\n *\n * @example Nuxt server middleware\n * ```ts\n * import { createAuthMiddleware } from 'evlog/better-auth'\n *\n * const identify = createAuthMiddleware(auth, {\n * exclude: ['/api/auth/**', '/api/public/**'],\n * })\n *\n * export default defineEventHandler(async (event) => {\n * if (!event.context.log) return\n * await identify(event.context.log, event.headers, event.path)\n * })\n * ```\n *\n * @example Express\n * ```ts\n * const identify = createAuthMiddleware(auth, { maskEmail: true })\n *\n * app.use(async (req, res, next) => {\n * await identify(req.log, req.headers, req.path)\n * next()\n * })\n * ```\n */\nexport function createAuthMiddleware(\n auth: BetterAuthInstance,\n options?: AuthMiddlewareOptions,\n): (log: RequestLogger, headers: Headers | Record<string, string | string[] | undefined>, path?: string) => Promise<boolean> {\n return async (log, headers, path?) => {\n if (path && !shouldResolve(path, options)) return false\n\n const start = Date.now()\n try {\n const session = await auth.api.getSession({ headers })\n const resolvedIn = Date.now() - start\n\n if (session) {\n const identified = identifyUser(log, session, options)\n if (identified) {\n log.set({ auth: { resolvedIn, identified: true } } as Record<string, unknown>)\n if (options?.onIdentify) await options.onIdentify(log, session)\n return true\n }\n }\n\n log.set({ auth: { resolvedIn, identified: false } } as Record<string, unknown>)\n if (options?.onAnonymous) await options.onAnonymous(log)\n return false\n } catch (err) {\n const resolvedIn = Date.now() - start\n log.set({ auth: { resolvedIn, identified: false, error: true } } as Record<string, unknown>)\n if (isDev) console.warn('[evlog/better-auth] Session resolution failed:', err)\n if (options?.onAnonymous) await options.onAnonymous(log)\n return false\n }\n }\n}\n\n/**\n * Create a Nitro `request` hook that auto-identifies users from Better Auth sessions.\n *\n * Resolves the session from request cookies on every request and sets user/session\n * context on the evlog logger. Skips `/api/auth/**` by default to avoid resolving\n * sessions during auth flows.\n *\n * @example\n * ```ts\n * // server/plugins/evlog-auth.ts\n * import { createAuthIdentifier } from 'evlog/better-auth'\n * import { auth } from '~/lib/auth'\n *\n * export default defineNitroPlugin((nitroApp) => {\n * nitroApp.hooks.hook('request', createAuthIdentifier(auth))\n * })\n * ```\n *\n * @example With options\n * ```ts\n * nitroApp.hooks.hook('request', createAuthIdentifier(auth, {\n * maskEmail: true,\n * exclude: ['/api/auth/**', '/api/public/**'],\n * }))\n * ```\n */\nexport function createAuthIdentifier(\n auth: BetterAuthInstance,\n options?: AuthIdentifierOptions,\n): (event: { path: string, headers: Headers | { get(name: string): string | null }, context: { log?: RequestLogger } }) => Promise<void> {\n const middleware = createAuthMiddleware(auth, options)\n\n return async (event) => {\n if (!event.context.log) return\n await middleware(event.context.log, event.headers as Headers, event.path)\n }\n}\n"],"mappings":";;AA2GA,MAAM,sBAAsB;CAAC;CAAM;CAAQ;CAAS;CAAS;CAAiB;CAAY;AAE1F,MAAM,QAAQ,OAAO,YAAY,eAAe,QAAQ,KAAK,aAAa;;;;AAK1E,SAAgB,UAAU,OAAuB;CAC/C,MAAM,UAAU,MAAM,QAAQ,IAAI;AAClC,KAAI,WAAW,EAAG,QAAO;AACzB,QAAO,GAAG,MAAM,GAAG,KAAK,MAAM,MAAM,QAAQ;;AAG9C,SAAS,gBACP,MACA,SACc;CACd,MAAM,SAAS,SAAS,UAAU;CAClC,MAAM,OAAgC,EAAE;AAExC,KAAI,KAAK,OAAO,KAAA,KAAa,KAAK,OAAO,KACvC,MAAK,KAAK,KAAK;AAGjB,MAAK,MAAM,SAAS,QAAQ;AAC1B,MAAI,UAAU,KAAM;EACpB,MAAM,QAAQ,KAAK;AACnB,MAAI,UAAU,KAAA,KAAa,UAAU,KAAM;AAE3C,MAAI,UAAU,WAAW,SAAS,aAAa,OAAO,UAAU,SAC9D,MAAK,SAAS,UAAU,MAAM;WACrB,UAAU,eAAe,iBAAiB,KACnD,MAAK,SAAS,MAAM,aAAa;MAEjC,MAAK,SAAS;;AAIlB,QAAO;;AAGT,SAAS,mBACP,SACiB;CACjB,MAAM,OAAwB,EAAE,IAAI,OAAO,QAAQ,GAAG,EAAE;AAExD,KAAI,QAAQ,UACV,MAAK,YAAY,QAAQ,qBAAqB,OAC1C,QAAQ,UAAU,aAAa,GAC/B,OAAO,QAAQ,UAAU;AAE/B,KAAI,OAAO,QAAQ,cAAc,SAAU,MAAK,YAAY,QAAQ;AACpE,KAAI,OAAO,QAAQ,cAAc,SAAU,MAAK,YAAY,QAAQ;AACpE,KAAI,QAAQ,UACV,MAAK,YAAY,QAAQ,qBAAqB,OAC1C,QAAQ,UAAU,aAAa,GAC/B,OAAO,QAAQ,UAAU;AAG/B,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCT,SAAgB,aACd,KACA,SACA,SACS;CACT,MAAM,OAAO,gBAAgB,QAAQ,MAAM,QAAQ;AACnD,KAAI,CAAC,KAAK,GAAI,QAAO;CAErB,MAAM,iBAAiB,SAAS,YAAY;CAE5C,MAAM,OAAgC;EACpC,QAAQ,KAAK;EACb;EACD;AAED,KAAI,eACF,MAAK,UAAU,mBAAmB,QAAQ,QAAQ;AAGpD,KAAI,SAAS,QAAQ;EACnB,MAAM,QAAQ,QAAQ,OAAO,QAAQ;AACrC,MAAI,MAAO,QAAO,OAAO,MAAM,MAAM;;AAGvC,KAAI,IAAI,KAAK;AACb,QAAO;;AAGT,SAAS,cAAc,MAAc,SAA+D;CAClG,MAAM,UAAU,SAAS,WAAW,CAAC,eAAe;AACpD,MAAK,MAAM,WAAW,QACpB,KAAI,eAAe,MAAM,QAAQ,CAAE,QAAO;AAG5C,KAAI,SAAS,SAAS;AACpB,OAAK,MAAM,WAAW,QAAQ,QAC5B,KAAI,eAAe,MAAM,QAAQ,CAAE,QAAO;AAE5C,SAAO;;AAGT,QAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCT,SAAgB,qBACd,MACA,SAC2H;AAC3H,QAAO,OAAO,KAAK,SAAS,SAAU;AACpC,MAAI,QAAQ,CAAC,cAAc,MAAM,QAAQ,CAAE,QAAO;EAElD,MAAM,QAAQ,KAAK,KAAK;AACxB,MAAI;GACF,MAAM,UAAU,MAAM,KAAK,IAAI,WAAW,EAAE,SAAS,CAAC;GACtD,MAAM,aAAa,KAAK,KAAK,GAAG;AAEhC,OAAI;QACiB,aAAa,KAAK,SAAS,QAChC,EAAE;AACd,SAAI,IAAI,EAAE,MAAM;MAAE;MAAY,YAAY;MAAM,EAAE,CAA4B;AAC9E,SAAI,SAAS,WAAY,OAAM,QAAQ,WAAW,KAAK,QAAQ;AAC/D,YAAO;;;AAIX,OAAI,IAAI,EAAE,MAAM;IAAE;IAAY,YAAY;IAAO,EAAE,CAA4B;AAC/E,OAAI,SAAS,YAAa,OAAM,QAAQ,YAAY,IAAI;AACxD,UAAO;WACA,KAAK;GACZ,MAAM,aAAa,KAAK,KAAK,GAAG;AAChC,OAAI,IAAI,EAAE,MAAM;IAAE;IAAY,YAAY;IAAO,OAAO;IAAM,EAAE,CAA4B;AAC5F,OAAI,MAAO,SAAQ,KAAK,kDAAkD,IAAI;AAC9E,OAAI,SAAS,YAAa,OAAM,QAAQ,YAAY,IAAI;AACxD,UAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+Bb,SAAgB,qBACd,MACA,SACuI;CACvI,MAAM,aAAa,qBAAqB,MAAM,QAAQ;AAEtD,QAAO,OAAO,UAAU;AACtB,MAAI,CAAC,MAAM,QAAQ,IAAK;AACxB,QAAM,WAAW,MAAM,QAAQ,KAAK,MAAM,SAAoB,MAAM,KAAK"}
@@ -1,4 +1,4 @@
1
- import { F as DrainContext } from "./audit-mUutdf6A.mjs";
1
+ import { F as DrainContext } from "./audit-CJl-wZ10.mjs";
2
2
  import { PipelineDrainFn } from "./pipeline.mjs";
3
3
  import { HttpDrainConfig, HttpLogDrainOptions } from "./http.mjs";
4
4
 
@@ -0,0 +1,63 @@
1
+ //#region src/shared/define.ts
2
+ /**
3
+ * Identity helper for authoring an evlog configuration once and sharing it
4
+ * across `initLogger` and framework middleware.
5
+ *
6
+ * @example
7
+ * ```ts
8
+ * export const config = defineEvlog({
9
+ * service: 'checkout',
10
+ * redact: true,
11
+ * sampling: { rates: { info: 25 } },
12
+ * enrich: createDefaultEnrichers(),
13
+ * plugins: [drainPlugin('axiom', createAxiomDrain())],
14
+ * })
15
+ *
16
+ * initLogger(toLoggerConfig(config))
17
+ * app.use(evlogMiddleware(config))
18
+ * ```
19
+ */
20
+ function defineEvlog(config) {
21
+ return config;
22
+ }
23
+ /**
24
+ * Project an {@link EvlogConfig} onto the surface accepted by `initLogger`.
25
+ * Strips middleware-only fields (`include`, `exclude`, `routes`, `enrich`,
26
+ * `keep`); drains and plugins are preserved.
27
+ */
28
+ function toLoggerConfig(config) {
29
+ const env = config.env ? { ...config.env } : config.service || config.environment ? {} : void 0;
30
+ if (env) {
31
+ if (config.service) env.service = config.service;
32
+ if (config.environment) env.environment = config.environment;
33
+ }
34
+ const out = {};
35
+ if (env) out.env = env;
36
+ if (config.enabled !== void 0) out.enabled = config.enabled;
37
+ if (config.pretty !== void 0) out.pretty = config.pretty;
38
+ if (config.sampling !== void 0) out.sampling = config.sampling;
39
+ if (config.minLevel !== void 0) out.minLevel = config.minLevel;
40
+ if (config.stringify !== void 0) out.stringify = config.stringify;
41
+ if (config.silent !== void 0) out.silent = config.silent;
42
+ if (config.redact !== void 0) out.redact = config.redact;
43
+ if (config.drain) out.drain = config.drain;
44
+ if (config.plugins) out.plugins = config.plugins;
45
+ return out;
46
+ }
47
+ /** Project an {@link EvlogConfig} onto the surface accepted by framework middleware. */
48
+ function toMiddlewareOptions(config) {
49
+ const out = {};
50
+ if (config.include) out.include = config.include;
51
+ if (config.exclude) out.exclude = config.exclude;
52
+ if (config.routes) out.routes = config.routes;
53
+ if (config.drain) out.drain = config.drain;
54
+ if (config.enrich) out.enrich = config.enrich;
55
+ if (config.keep) out.keep = config.keep;
56
+ if (config.redact !== void 0) out.redact = config.redact;
57
+ if (config.plugins) out.plugins = config.plugins;
58
+ return out;
59
+ }
60
+ //#endregion
61
+ export { toLoggerConfig as n, toMiddlewareOptions as r, defineEvlog as t };
62
+
63
+ //# sourceMappingURL=define-D6OJdSUH.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-D6OJdSUH.mjs","names":[],"sources":["../src/shared/define.ts"],"sourcesContent":["import type { DrainContext, EnrichContext, EnvironmentContext, LoggerConfig, RedactConfig, SamplingConfig, TailSamplingContext } from '../types'\nimport type { BaseEvlogOptions } from './middleware'\nimport type { EvlogPlugin } from './plugin'\n\n/**\n * Single-config shape accepted everywhere evlog is bootstrapped: at\n * `initLogger`, in framework middleware, and in the Nuxt module. Authored\n * with {@link defineEvlog} and split via {@link toLoggerConfig} /\n * {@link toMiddlewareOptions}.\n */\nexport interface EvlogConfig extends BaseEvlogOptions {\n service?: string\n environment?: string\n /** Full environment context override (advanced). */\n env?: Partial<EnvironmentContext>\n /** Enable or disable all logging globally. */\n enabled?: boolean\n /** Auto-detected from `NODE_ENV` when omitted. */\n pretty?: boolean\n sampling?: SamplingConfig\n /** Suppress built-in console output (useful when drains own the channel). */\n silent?: boolean\n /** Emit JSON strings (default) or raw objects in non-pretty mode. */\n stringify?: boolean\n /** Minimum severity for the global `log` API. */\n minLevel?: LoggerConfig['minLevel']\n}\n\n/**\n * Identity helper for authoring an evlog configuration once and sharing it\n * across `initLogger` and framework middleware.\n *\n * @example\n * ```ts\n * export const config = defineEvlog({\n * service: 'checkout',\n * redact: true,\n * sampling: { rates: { info: 25 } },\n * enrich: createDefaultEnrichers(),\n * plugins: [drainPlugin('axiom', createAxiomDrain())],\n * })\n *\n * initLogger(toLoggerConfig(config))\n * app.use(evlogMiddleware(config))\n * ```\n */\nexport function defineEvlog<T extends EvlogConfig>(config: T): T {\n return config\n}\n\n/**\n * Project an {@link EvlogConfig} onto the surface accepted by `initLogger`.\n * Strips middleware-only fields (`include`, `exclude`, `routes`, `enrich`,\n * `keep`); drains and plugins are preserved.\n */\nexport function toLoggerConfig(config: EvlogConfig): LoggerConfig {\n const env: Partial<EnvironmentContext> | undefined = config.env\n ? { ...config.env }\n : config.service || config.environment\n ? {}\n : undefined\n if (env) {\n if (config.service) env.service = config.service\n if (config.environment) env.environment = config.environment\n }\n const out: LoggerConfig = {}\n if (env) out.env = env\n if (config.enabled !== undefined) out.enabled = config.enabled\n if (config.pretty !== undefined) out.pretty = config.pretty\n if (config.sampling !== undefined) out.sampling = config.sampling\n if (config.minLevel !== undefined) out.minLevel = config.minLevel\n if (config.stringify !== undefined) out.stringify = config.stringify\n if (config.silent !== undefined) out.silent = config.silent\n if (config.redact !== undefined) out.redact = config.redact as boolean | RedactConfig | undefined\n if (config.drain) out.drain = config.drain\n if (config.plugins) out.plugins = config.plugins\n return out\n}\n\n/** Project an {@link EvlogConfig} onto the surface accepted by framework middleware. */\nexport function toMiddlewareOptions<T extends BaseEvlogOptions>(config: EvlogConfig): T {\n const out: BaseEvlogOptions = {}\n if (config.include) out.include = config.include\n if (config.exclude) out.exclude = config.exclude\n if (config.routes) out.routes = config.routes\n if (config.drain) out.drain = config.drain as (ctx: DrainContext) => void | Promise<void>\n if (config.enrich) out.enrich = config.enrich as (ctx: EnrichContext) => void | Promise<void>\n if (config.keep) out.keep = config.keep as (ctx: TailSamplingContext) => void | Promise<void>\n if (config.redact !== undefined) out.redact = config.redact as boolean | RedactConfig | undefined\n if (config.plugins) out.plugins = config.plugins as EvlogPlugin[]\n return out as T\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA8CA,SAAgB,YAAmC,QAAc;AAC/D,QAAO;;;;;;;AAQT,SAAgB,eAAe,QAAmC;CAChE,MAAM,MAA+C,OAAO,MACxD,EAAE,GAAG,OAAO,KAAK,GACjB,OAAO,WAAW,OAAO,cACvB,EAAE,GACF,KAAA;AACN,KAAI,KAAK;AACP,MAAI,OAAO,QAAS,KAAI,UAAU,OAAO;AACzC,MAAI,OAAO,YAAa,KAAI,cAAc,OAAO;;CAEnD,MAAM,MAAoB,EAAE;AAC5B,KAAI,IAAK,KAAI,MAAM;AACnB,KAAI,OAAO,YAAY,KAAA,EAAW,KAAI,UAAU,OAAO;AACvD,KAAI,OAAO,WAAW,KAAA,EAAW,KAAI,SAAS,OAAO;AACrD,KAAI,OAAO,aAAa,KAAA,EAAW,KAAI,WAAW,OAAO;AACzD,KAAI,OAAO,aAAa,KAAA,EAAW,KAAI,WAAW,OAAO;AACzD,KAAI,OAAO,cAAc,KAAA,EAAW,KAAI,YAAY,OAAO;AAC3D,KAAI,OAAO,WAAW,KAAA,EAAW,KAAI,SAAS,OAAO;AACrD,KAAI,OAAO,WAAW,KAAA,EAAW,KAAI,SAAS,OAAO;AACrD,KAAI,OAAO,MAAO,KAAI,QAAQ,OAAO;AACrC,KAAI,OAAO,QAAS,KAAI,UAAU,OAAO;AACzC,QAAO;;;AAIT,SAAgB,oBAAgD,QAAwB;CACtF,MAAM,MAAwB,EAAE;AAChC,KAAI,OAAO,QAAS,KAAI,UAAU,OAAO;AACzC,KAAI,OAAO,QAAS,KAAI,UAAU,OAAO;AACzC,KAAI,OAAO,OAAQ,KAAI,SAAS,OAAO;AACvC,KAAI,OAAO,MAAO,KAAI,QAAQ,OAAO;AACrC,KAAI,OAAO,OAAQ,KAAI,SAAS,OAAO;AACvC,KAAI,OAAO,KAAM,KAAI,OAAO,OAAO;AACnC,KAAI,OAAO,WAAW,KAAA,EAAW,KAAI,SAAS,OAAO;AACrD,KAAI,OAAO,QAAS,KAAI,UAAU,OAAO;AACzC,QAAO"}
@@ -0,0 +1,57 @@
1
+ import { G as LoggerConfig, L as EnvironmentContext, Q as SamplingConfig } from "./audit-CJl-wZ10.mjs";
2
+ import { t as BaseEvlogOptions } from "./middleware-CGM-bOvE.mjs";
3
+
4
+ //#region src/shared/define.d.ts
5
+ /**
6
+ * Single-config shape accepted everywhere evlog is bootstrapped: at
7
+ * `initLogger`, in framework middleware, and in the Nuxt module. Authored
8
+ * with {@link defineEvlog} and split via {@link toLoggerConfig} /
9
+ * {@link toMiddlewareOptions}.
10
+ */
11
+ interface EvlogConfig extends BaseEvlogOptions {
12
+ service?: string;
13
+ environment?: string;
14
+ /** Full environment context override (advanced). */
15
+ env?: Partial<EnvironmentContext>;
16
+ /** Enable or disable all logging globally. */
17
+ enabled?: boolean;
18
+ /** Auto-detected from `NODE_ENV` when omitted. */
19
+ pretty?: boolean;
20
+ sampling?: SamplingConfig;
21
+ /** Suppress built-in console output (useful when drains own the channel). */
22
+ silent?: boolean;
23
+ /** Emit JSON strings (default) or raw objects in non-pretty mode. */
24
+ stringify?: boolean;
25
+ /** Minimum severity for the global `log` API. */
26
+ minLevel?: LoggerConfig['minLevel'];
27
+ }
28
+ /**
29
+ * Identity helper for authoring an evlog configuration once and sharing it
30
+ * across `initLogger` and framework middleware.
31
+ *
32
+ * @example
33
+ * ```ts
34
+ * export const config = defineEvlog({
35
+ * service: 'checkout',
36
+ * redact: true,
37
+ * sampling: { rates: { info: 25 } },
38
+ * enrich: createDefaultEnrichers(),
39
+ * plugins: [drainPlugin('axiom', createAxiomDrain())],
40
+ * })
41
+ *
42
+ * initLogger(toLoggerConfig(config))
43
+ * app.use(evlogMiddleware(config))
44
+ * ```
45
+ */
46
+ declare function defineEvlog<T extends EvlogConfig>(config: T): T;
47
+ /**
48
+ * Project an {@link EvlogConfig} onto the surface accepted by `initLogger`.
49
+ * Strips middleware-only fields (`include`, `exclude`, `routes`, `enrich`,
50
+ * `keep`); drains and plugins are preserved.
51
+ */
52
+ declare function toLoggerConfig(config: EvlogConfig): LoggerConfig;
53
+ /** Project an {@link EvlogConfig} onto the surface accepted by framework middleware. */
54
+ declare function toMiddlewareOptions<T extends BaseEvlogOptions>(config: EvlogConfig): T;
55
+ //#endregion
56
+ export { toMiddlewareOptions as i, defineEvlog as n, toLoggerConfig as r, EvlogConfig as t };
57
+ //# sourceMappingURL=define-Fp8TrdEB.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-Fp8TrdEB.d.mts","names":[],"sources":["../src/shared/define.ts"],"mappings":";;;;;;AAUA;;;;UAAiB,WAAA,SAAoB,gBAAA;EACnC,OAAA;EACA,WAAA;EAFmC;EAInC,GAAA,GAAM,OAAA,CAAQ,kBAAA;EAJqC;EAMnD,OAAA;EALA;EAOA,MAAA;EACA,QAAA,GAAW,cAAA;EALL;EAON,MAAA;EALA;EAOA,SAAA;EAJA;EAMA,QAAA,GAAW,YAAA;AAAA;;;;;;AAqBb;;;;;;;;;;;;;iBAAgB,WAAA,WAAsB,WAAA,CAAA,CAAa,MAAA,EAAQ,CAAA,GAAI,CAAA;;AAS/D;;;;iBAAgB,cAAA,CAAe,MAAA,EAAQ,WAAA,GAAc,YAAA;;iBAyBrC,mBAAA,WAA8B,gBAAA,CAAA,CAAkB,MAAA,EAAQ,WAAA,GAAc,CAAA"}
@@ -48,4 +48,4 @@ function parsePath(input = "") {
48
48
  //#endregion
49
49
  export { parseURL as t };
50
50
 
51
- //# sourceMappingURL=dist-Do8P4zWd.mjs.map
51
+ //# sourceMappingURL=dist-BIlS38vi.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dist-BIlS38vi.mjs","names":[],"sources":["../../../node_modules/.pnpm/ufo@1.6.4/node_modules/ufo/dist/index.mjs"],"sourcesContent":["const n = /[^\\0-\\x7E]/;\nconst t = /[\\x2E\\u3002\\uFF0E\\uFF61]/g;\nconst o = {\n overflow: \"Overflow Error\",\n \"not-basic\": \"Illegal Input\",\n \"invalid-input\": \"Invalid Input\"\n};\nconst e = Math.floor;\nconst r = String.fromCharCode;\nfunction s(n2) {\n throw new RangeError(o[n2]);\n}\nconst c = function(n2, t2) {\n return n2 + 22 + 75 * (n2 < 26) - ((t2 != 0) << 5);\n};\nconst u = function(n2, t2, o2) {\n let r2 = 0;\n for (n2 = o2 ? e(n2 / 700) : n2 >> 1, n2 += e(n2 / t2); n2 > 455; r2 += 36) {\n n2 = e(n2 / 35);\n }\n return e(r2 + 36 * n2 / (n2 + 38));\n};\nfunction toASCII(o2) {\n return (function(n2, o3) {\n const e2 = n2.split(\"@\");\n let r2 = \"\";\n e2.length > 1 && (r2 = e2[0] + \"@\", n2 = e2[1]);\n const s2 = (function(n3, t2) {\n const o4 = [];\n let e3 = n3.length;\n for (; e3--; ) {\n o4[e3] = t2(n3[e3]);\n }\n return o4;\n })((n2 = n2.replace(t, \".\")).split(\".\"), o3).join(\".\");\n return r2 + s2;\n })(o2, function(t2) {\n return n.test(t2) ? \"xn--\" + (function(n2) {\n const t3 = [];\n const o3 = (n2 = (function(n3) {\n const t4 = [];\n let o4 = 0;\n const e2 = n3.length;\n for (; o4 < e2; ) {\n const r2 = n3.charCodeAt(o4++);\n if (r2 >= 55296 && r2 <= 56319 && o4 < e2) {\n const e3 = n3.charCodeAt(o4++);\n (64512 & e3) == 56320 ? t4.push(((1023 & r2) << 10) + (1023 & e3) + 65536) : (t4.push(r2), o4--);\n } else {\n t4.push(r2);\n }\n }\n return t4;\n })(n2)).length;\n let f = 128;\n let i = 0;\n let l = 72;\n for (const o4 of n2) {\n o4 < 128 && t3.push(r(o4));\n }\n const h = t3.length;\n let p = h;\n for (h && t3.push(\"-\"); p < o3; ) {\n let o4 = 2147483647;\n for (const t4 of n2) {\n t4 >= f && t4 < o4 && (o4 = t4);\n }\n const a = p + 1;\n o4 - f > e((2147483647 - i) / a) && s(\"overflow\"), i += (o4 - f) * a, f = o4;\n for (const o5 of n2) {\n if (o5 < f && ++i > 2147483647 && s(\"overflow\"), o5 == f) {\n let n3 = i;\n for (let o6 = 36; ; o6 += 36) {\n const s2 = o6 <= l ? 1 : o6 >= l + 26 ? 26 : o6 - l;\n if (n3 < s2) {\n break;\n }\n const u2 = n3 - s2;\n const f2 = 36 - s2;\n t3.push(r(c(s2 + u2 % f2, 0))), n3 = e(u2 / f2);\n }\n t3.push(r(c(n3, 0))), l = u(i, a, p == h), i = 0, ++p;\n }\n }\n ++i, ++f;\n }\n return t3.join(\"\");\n })(t2) : t2;\n });\n}\n\nconst HASH_RE = /#/g;\nconst AMPERSAND_RE = /&/g;\nconst SLASH_RE = /\\//g;\nconst EQUAL_RE = /=/g;\nconst IM_RE = /\\?/g;\nconst PLUS_RE = /\\+/g;\nconst ENC_CARET_RE = /%5e/gi;\nconst ENC_BACKTICK_RE = /%60/gi;\nconst ENC_CURLY_OPEN_RE = /%7b/gi;\nconst ENC_PIPE_RE = /%7c/gi;\nconst ENC_CURLY_CLOSE_RE = /%7d/gi;\nconst ENC_SPACE_RE = /%20/gi;\nconst ENC_SLASH_RE = /%2f/gi;\nconst ENC_ENC_SLASH_RE = /%252f/gi;\nfunction encode(text) {\n return encodeURI(\"\" + text).replace(ENC_PIPE_RE, \"|\");\n}\nfunction encodeHash(text) {\n return encode(text).replace(ENC_CURLY_OPEN_RE, \"{\").replace(ENC_CURLY_CLOSE_RE, \"}\").replace(ENC_CARET_RE, \"^\");\n}\nfunction encodeQueryValue(input) {\n return encode(typeof input === \"string\" ? input : JSON.stringify(input)).replace(PLUS_RE, \"%2B\").replace(ENC_SPACE_RE, \"+\").replace(HASH_RE, \"%23\").replace(AMPERSAND_RE, \"%26\").replace(ENC_BACKTICK_RE, \"`\").replace(ENC_CARET_RE, \"^\").replace(SLASH_RE, \"%2F\");\n}\nfunction encodeQueryKey(text) {\n return encodeQueryValue(text).replace(EQUAL_RE, \"%3D\");\n}\nfunction encodePath(text) {\n return encode(text).replace(HASH_RE, \"%23\").replace(IM_RE, \"%3F\").replace(ENC_ENC_SLASH_RE, \"%2F\").replace(AMPERSAND_RE, \"%26\").replace(PLUS_RE, \"%2B\");\n}\nfunction encodeParam(text) {\n return encodePath(text).replace(SLASH_RE, \"%2F\");\n}\nfunction decode(text = \"\") {\n try {\n return decodeURIComponent(\"\" + text);\n } catch {\n return \"\" + text;\n }\n}\nfunction decodePath(text) {\n return decode(text.replace(ENC_SLASH_RE, \"%252F\"));\n}\nfunction decodeQueryKey(text) {\n return decode(text.replace(PLUS_RE, \" \"));\n}\nfunction decodeQueryValue(text) {\n return decode(text.replace(PLUS_RE, \" \"));\n}\nfunction encodeHost(name = \"\") {\n return toASCII(name);\n}\n\nfunction parseQuery(parametersString = \"\") {\n const object = /* @__PURE__ */ Object.create(null);\n if (parametersString[0] === \"?\") {\n parametersString = parametersString.slice(1);\n }\n for (const parameter of parametersString.split(\"&\")) {\n const s = parameter.match(/([^=]+)=?(.*)/) || [];\n if (s.length < 2) {\n continue;\n }\n const key = decodeQueryKey(s[1]);\n if (key === \"__proto__\" || key === \"constructor\") {\n continue;\n }\n const value = decodeQueryValue(s[2] || \"\");\n if (object[key] === void 0) {\n object[key] = value;\n } else if (Array.isArray(object[key])) {\n object[key].push(value);\n } else {\n object[key] = [object[key], value];\n }\n }\n return object;\n}\nfunction encodeQueryItem(key, value) {\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n value = String(value);\n }\n if (!value) {\n return encodeQueryKey(key);\n }\n if (Array.isArray(value)) {\n return value.map(\n (_value) => `${encodeQueryKey(key)}=${encodeQueryValue(_value)}`\n ).join(\"&\");\n }\n return `${encodeQueryKey(key)}=${encodeQueryValue(value)}`;\n}\nfunction stringifyQuery(query) {\n return Object.keys(query).filter((k) => query[k] !== void 0).map((k) => encodeQueryItem(k, query[k])).filter(Boolean).join(\"&\");\n}\n\nconst PROTOCOL_STRICT_REGEX = /^[\\s\\w\\0+.-]{2,}:([/\\\\]{1,2})/;\nconst PROTOCOL_REGEX = /^[\\s\\w\\0+.-]{2,}:([/\\\\]{2})?/;\nconst PROTOCOL_RELATIVE_REGEX = /^([/\\\\]\\s*){2,}[^/\\\\]/;\nconst PROTOCOL_SCRIPT_RE = /^[\\s\\0]*(blob|data|javascript|vbscript):$/i;\nconst TRAILING_SLASH_RE = /\\/$|\\/\\?|\\/#/;\nconst JOIN_LEADING_SLASH_RE = /^\\.?\\//;\nfunction isRelative(inputString) {\n return [\"./\", \"../\"].some((string_) => inputString.startsWith(string_));\n}\nfunction hasProtocol(inputString, opts = {}) {\n if (typeof opts === \"boolean\") {\n opts = { acceptRelative: opts };\n }\n if (opts.strict) {\n return PROTOCOL_STRICT_REGEX.test(inputString);\n }\n return PROTOCOL_REGEX.test(inputString) || (opts.acceptRelative ? PROTOCOL_RELATIVE_REGEX.test(inputString) : false);\n}\nfunction isScriptProtocol(protocol) {\n return !!protocol && PROTOCOL_SCRIPT_RE.test(protocol);\n}\nfunction hasTrailingSlash(input = \"\", respectQueryAndFragment) {\n if (!respectQueryAndFragment) {\n return input.endsWith(\"/\");\n }\n return TRAILING_SLASH_RE.test(input);\n}\nfunction withoutTrailingSlash(input = \"\", respectQueryAndFragment) {\n if (!respectQueryAndFragment) {\n return (hasTrailingSlash(input) ? input.slice(0, -1) : input) || \"/\";\n }\n if (!hasTrailingSlash(input, true)) {\n return input || \"/\";\n }\n let path = input;\n let fragment = \"\";\n const fragmentIndex = input.indexOf(\"#\");\n if (fragmentIndex !== -1) {\n path = input.slice(0, fragmentIndex);\n fragment = input.slice(fragmentIndex);\n }\n const [s0, ...s] = path.split(\"?\");\n const cleanPath = s0.endsWith(\"/\") ? s0.slice(0, -1) : s0;\n return (cleanPath || \"/\") + (s.length > 0 ? `?${s.join(\"?\")}` : \"\") + fragment;\n}\nfunction withTrailingSlash(input = \"\", respectQueryAndFragment) {\n if (!respectQueryAndFragment) {\n return input.endsWith(\"/\") ? input : input + \"/\";\n }\n if (hasTrailingSlash(input, true)) {\n return input || \"/\";\n }\n let path = input;\n let fragment = \"\";\n const fragmentIndex = input.indexOf(\"#\");\n if (fragmentIndex !== -1) {\n path = input.slice(0, fragmentIndex);\n fragment = input.slice(fragmentIndex);\n if (!path) {\n return fragment;\n }\n }\n const [s0, ...s] = path.split(\"?\");\n return s0 + \"/\" + (s.length > 0 ? `?${s.join(\"?\")}` : \"\") + fragment;\n}\nfunction hasLeadingSlash(input = \"\") {\n return input.startsWith(\"/\");\n}\nfunction withoutLeadingSlash(input = \"\") {\n return (hasLeadingSlash(input) ? input.slice(1) : input) || \"/\";\n}\nfunction withLeadingSlash(input = \"\") {\n return hasLeadingSlash(input) ? input : \"/\" + input;\n}\nfunction cleanDoubleSlashes(input = \"\") {\n return input.split(\"://\").map((string_) => string_.replace(/\\/{2,}/g, \"/\")).join(\"://\");\n}\nfunction withBase(input, base) {\n if (isEmptyURL(base) || hasProtocol(input)) {\n return input;\n }\n const _base = withoutTrailingSlash(base);\n if (input.startsWith(_base)) {\n const nextChar = input[_base.length];\n if (!nextChar || nextChar === \"/\" || nextChar === \"?\") {\n return input;\n }\n }\n return joinURL(_base, input);\n}\nfunction withoutBase(input, base) {\n if (isEmptyURL(base)) {\n return input;\n }\n const _base = withoutTrailingSlash(base);\n if (!input.startsWith(_base)) {\n return input;\n }\n const nextChar = input[_base.length];\n if (nextChar && nextChar !== \"/\" && nextChar !== \"?\") {\n return input;\n }\n const trimmed = input.slice(_base.length).replace(/^\\/+/, \"\");\n return \"/\" + trimmed;\n}\nfunction withQuery(input, query) {\n const parsed = parseURL(input);\n const mergedQuery = { ...parseQuery(parsed.search), ...query };\n parsed.search = stringifyQuery(mergedQuery);\n return stringifyParsedURL(parsed);\n}\nfunction filterQuery(input, predicate) {\n if (!input.includes(\"?\")) {\n return input;\n }\n const parsed = parseURL(input);\n const query = parseQuery(parsed.search);\n const filteredQuery = Object.fromEntries(\n Object.entries(query).filter(([key, value]) => predicate(key, value))\n );\n parsed.search = stringifyQuery(filteredQuery);\n return stringifyParsedURL(parsed);\n}\nfunction getQuery(input) {\n return parseQuery(parseURL(input).search);\n}\nfunction isEmptyURL(url) {\n return !url || url === \"/\";\n}\nfunction isNonEmptyURL(url) {\n return url && url !== \"/\";\n}\nfunction joinURL(base, ...input) {\n let url = base || \"\";\n for (const segment of input.filter((url2) => isNonEmptyURL(url2))) {\n if (url) {\n const _segment = segment.replace(JOIN_LEADING_SLASH_RE, \"\");\n url = withTrailingSlash(url) + _segment;\n } else {\n url = segment;\n }\n }\n return url;\n}\nfunction joinRelativeURL(..._input) {\n const JOIN_SEGMENT_SPLIT_RE = /\\/(?!\\/)/;\n const input = _input.filter(Boolean);\n const segments = [];\n let segmentsDepth = 0;\n for (const i of input) {\n if (!i || i === \"/\") {\n continue;\n }\n for (const [sindex, s] of i.split(JOIN_SEGMENT_SPLIT_RE).entries()) {\n if (!s || s === \".\") {\n continue;\n }\n if (s === \"..\") {\n if (segments.length === 1 && hasProtocol(segments[0])) {\n continue;\n }\n segments.pop();\n segmentsDepth--;\n continue;\n }\n if (sindex === 1 && segments[segments.length - 1]?.endsWith(\":/\")) {\n segments[segments.length - 1] += \"/\" + s;\n continue;\n }\n segments.push(s);\n segmentsDepth++;\n }\n }\n let url = segments.join(\"/\");\n if (segmentsDepth >= 0) {\n if (input[0]?.startsWith(\"/\") && !url.startsWith(\"/\")) {\n url = \"/\" + url;\n } else if (input[0]?.startsWith(\"./\") && !url.startsWith(\"./\")) {\n url = \"./\" + url;\n }\n } else {\n url = \"../\".repeat(-1 * segmentsDepth) + url;\n }\n if (input[input.length - 1]?.endsWith(\"/\") && !url.endsWith(\"/\")) {\n url += \"/\";\n }\n return url;\n}\nfunction withHttp(input) {\n return withProtocol(input, \"http://\");\n}\nfunction withHttps(input) {\n return withProtocol(input, \"https://\");\n}\nfunction withoutProtocol(input) {\n return withProtocol(input, \"\");\n}\nfunction withProtocol(input, protocol) {\n let match = input.match(PROTOCOL_REGEX);\n if (!match) {\n match = input.match(/^\\/{2,}/);\n }\n if (!match) {\n return protocol + input;\n }\n return protocol + input.slice(match[0].length);\n}\nfunction normalizeURL(input) {\n const parsed = parseURL(input);\n parsed.pathname = encodePath(decodePath(parsed.pathname));\n parsed.hash = encodeHash(decode(parsed.hash));\n parsed.host = encodeHost(decode(parsed.host));\n parsed.search = stringifyQuery(parseQuery(parsed.search));\n return stringifyParsedURL(parsed);\n}\nfunction resolveURL(base = \"\", ...inputs) {\n if (typeof base !== \"string\") {\n throw new TypeError(\n `URL input should be string received ${typeof base} (${base})`\n );\n }\n const filteredInputs = inputs.filter((input) => isNonEmptyURL(input));\n if (filteredInputs.length === 0) {\n return base;\n }\n const url = parseURL(base);\n for (const inputSegment of filteredInputs) {\n const urlSegment = parseURL(inputSegment);\n if (urlSegment.pathname) {\n url.pathname = withTrailingSlash(url.pathname) + withoutLeadingSlash(urlSegment.pathname);\n }\n if (urlSegment.hash && urlSegment.hash !== \"#\") {\n url.hash = urlSegment.hash;\n }\n if (urlSegment.search && urlSegment.search !== \"?\") {\n if (url.search && url.search !== \"?\") {\n const queryString = stringifyQuery({\n ...parseQuery(url.search),\n ...parseQuery(urlSegment.search)\n });\n url.search = queryString.length > 0 ? \"?\" + queryString : \"\";\n } else {\n url.search = urlSegment.search;\n }\n }\n }\n return stringifyParsedURL(url);\n}\nfunction isSamePath(p1, p2) {\n return decode(withoutTrailingSlash(p1)) === decode(withoutTrailingSlash(p2));\n}\nfunction isEqual(a, b, options = {}) {\n if (!options.trailingSlash) {\n a = withTrailingSlash(a);\n b = withTrailingSlash(b);\n }\n if (!options.leadingSlash) {\n a = withLeadingSlash(a);\n b = withLeadingSlash(b);\n }\n if (!options.encoding) {\n a = decode(a);\n b = decode(b);\n }\n return a === b;\n}\nfunction withFragment(input, hash) {\n if (!hash || hash === \"#\") {\n return input;\n }\n const parsed = parseURL(input);\n parsed.hash = hash === \"\" ? \"\" : \"#\" + encodeHash(hash);\n return stringifyParsedURL(parsed);\n}\nfunction withoutFragment(input) {\n return stringifyParsedURL({ ...parseURL(input), hash: \"\" });\n}\nfunction withoutHost(input) {\n const parsed = parseURL(input);\n return (parsed.pathname || \"/\") + parsed.search + parsed.hash;\n}\n\nconst protocolRelative = Symbol.for(\"ufo:protocolRelative\");\nfunction parseURL(input = \"\", defaultProto) {\n const _specialProtoMatch = input.match(\n /^[\\s\\0]*(blob:|data:|javascript:|vbscript:)(.*)/i\n );\n if (_specialProtoMatch) {\n const [, _proto, _pathname = \"\"] = _specialProtoMatch;\n return {\n protocol: _proto.toLowerCase(),\n pathname: _pathname,\n href: _proto + _pathname,\n auth: \"\",\n host: \"\",\n search: \"\",\n hash: \"\"\n };\n }\n if (!hasProtocol(input, { acceptRelative: true })) {\n return defaultProto ? parseURL(defaultProto + input) : parsePath(input);\n }\n const [, protocol = \"\", auth, hostAndPath = \"\"] = input.replace(/\\\\/g, \"/\").match(/^[\\s\\0]*([\\w+.-]{2,}:)?\\/\\/([^/@]+@)?(.*)/) || [];\n let [, host = \"\", path = \"\"] = hostAndPath.match(/([^#/?]*)(.*)?/) || [];\n if (protocol === \"file:\") {\n path = path.replace(/\\/(?=[A-Za-z]:)/, \"\");\n }\n const { pathname, search, hash } = parsePath(path);\n return {\n protocol: protocol.toLowerCase(),\n auth: auth ? auth.slice(0, Math.max(0, auth.length - 1)) : \"\",\n host,\n pathname,\n search,\n hash,\n [protocolRelative]: !protocol\n };\n}\nfunction parsePath(input = \"\") {\n const [pathname = \"\", search = \"\", hash = \"\"] = (input.match(/([^#?]*)(\\?[^#]*)?(#.*)?/) || []).splice(1);\n return {\n pathname,\n search,\n hash\n };\n}\nfunction parseAuth(input = \"\") {\n const [username, password] = input.split(\":\");\n return {\n username: decode(username),\n password: decode(password)\n };\n}\nfunction parseHost(input = \"\") {\n const [hostname, port] = (input.match(/([^/:]*):?(\\d+)?/) || []).splice(1);\n return {\n hostname: decode(hostname),\n port\n };\n}\nfunction stringifyParsedURL(parsed) {\n const pathname = parsed.pathname || \"\";\n const search = parsed.search ? (parsed.search.startsWith(\"?\") ? \"\" : \"?\") + parsed.search : \"\";\n const hash = parsed.hash || \"\";\n const auth = parsed.auth ? parsed.auth + \"@\" : \"\";\n const host = parsed.host || \"\";\n const proto = parsed.protocol || parsed[protocolRelative] ? (parsed.protocol || \"\") + \"//\" : \"\";\n return proto + auth + host + pathname + search + hash;\n}\nconst FILENAME_STRICT_REGEX = /\\/([^/]+\\.[^/]+)$/;\nconst FILENAME_REGEX = /\\/([^/]+)$/;\nfunction parseFilename(input = \"\", opts) {\n const { pathname } = parseURL(input);\n const matches = opts?.strict ? pathname.match(FILENAME_STRICT_REGEX) : pathname.match(FILENAME_REGEX);\n return matches ? matches[1] : void 0;\n}\n\nclass $URL {\n protocol;\n host;\n auth;\n pathname;\n query = {};\n hash;\n constructor(input = \"\") {\n if (typeof input !== \"string\") {\n throw new TypeError(\n `URL input should be string received ${typeof input} (${input})`\n );\n }\n const parsed = parseURL(input);\n this.protocol = decode(parsed.protocol);\n this.host = decode(parsed.host);\n this.auth = decode(parsed.auth);\n this.pathname = decodePath(parsed.pathname);\n this.query = parseQuery(parsed.search);\n this.hash = decode(parsed.hash);\n }\n get hostname() {\n return parseHost(this.host).hostname;\n }\n get port() {\n return parseHost(this.host).port || \"\";\n }\n get username() {\n return parseAuth(this.auth).username;\n }\n get password() {\n return parseAuth(this.auth).password || \"\";\n }\n get hasProtocol() {\n return this.protocol.length;\n }\n get isAbsolute() {\n return this.hasProtocol || this.pathname[0] === \"/\";\n }\n get search() {\n const q = stringifyQuery(this.query);\n return q.length > 0 ? \"?\" + q : \"\";\n }\n get searchParams() {\n const p = new URLSearchParams();\n for (const name in this.query) {\n const value = this.query[name];\n if (Array.isArray(value)) {\n for (const v of value) {\n p.append(name, v);\n }\n } else {\n p.append(\n name,\n typeof value === \"string\" ? value : JSON.stringify(value)\n );\n }\n }\n return p;\n }\n get origin() {\n return (this.protocol ? this.protocol + \"//\" : \"\") + encodeHost(this.host);\n }\n get fullpath() {\n return encodePath(this.pathname) + this.search + encodeHash(this.hash);\n }\n get encodedAuth() {\n if (!this.auth) {\n return \"\";\n }\n const { username, password } = parseAuth(this.auth);\n return encodeURIComponent(username) + (password ? \":\" + encodeURIComponent(password) : \"\");\n }\n get href() {\n const auth = this.encodedAuth;\n const originWithAuth = (this.protocol ? this.protocol + \"//\" : \"\") + (auth ? auth + \"@\" : \"\") + encodeHost(this.host);\n return this.hasProtocol && this.isAbsolute ? originWithAuth + this.fullpath : this.fullpath;\n }\n append(url) {\n if (url.hasProtocol) {\n throw new Error(\"Cannot append a URL with protocol\");\n }\n Object.assign(this.query, url.query);\n if (url.pathname) {\n this.pathname = withTrailingSlash(this.pathname) + withoutLeadingSlash(url.pathname);\n }\n if (url.hash) {\n this.hash = url.hash;\n }\n }\n toJSON() {\n return this.href;\n }\n toString() {\n return this.href;\n }\n}\nfunction createURL(input) {\n return new $URL(input);\n}\n\nexport { $URL, cleanDoubleSlashes, createURL, decode, decodePath, decodeQueryKey, decodeQueryValue, encode, encodeHash, encodeHost, encodeParam, encodePath, encodeQueryItem, encodeQueryKey, encodeQueryValue, filterQuery, getQuery, hasLeadingSlash, hasProtocol, hasTrailingSlash, isEmptyURL, isEqual, isNonEmptyURL, isRelative, isSamePath, isScriptProtocol, joinRelativeURL, joinURL, normalizeURL, parseAuth, parseFilename, parseHost, parsePath, parseQuery, parseURL, resolveURL, stringifyParsedURL, stringifyQuery, withBase, withFragment, withHttp, withHttps, withLeadingSlash, withProtocol, withQuery, withTrailingSlash, withoutBase, withoutFragment, withoutHost, withoutLeadingSlash, withoutProtocol, withoutTrailingSlash };\n"],"x_google_ignoreList":[0],"mappings":"AAQU,OAAO;AAkLjB,MAAM,wBAAwB;AAC9B,MAAM,iBAAiB;AACvB,MAAM,0BAA0B;AAOhC,SAAS,YAAY,aAAa,OAAO,EAAE,EAAE;AAC3C,KAAI,OAAO,SAAS,UAClB,QAAO,EAAE,gBAAgB,MAAM;AAEjC,KAAI,KAAK,OACP,QAAO,sBAAsB,KAAK,YAAY;AAEhD,QAAO,eAAe,KAAK,YAAY,KAAK,KAAK,iBAAiB,wBAAwB,KAAK,YAAY,GAAG;;AA0QhH,MAAM,mBAAmB,OAAO,IAAI,uBAAuB;AAC3D,SAAS,SAAS,QAAQ,IAAI,cAAc;CAC1C,MAAM,qBAAqB,MAAM,MAC/B,mDACD;AACD,KAAI,oBAAoB;EACtB,MAAM,GAAG,QAAQ,YAAY,MAAM;AACnC,SAAO;GACL,UAAU,OAAO,aAAa;GAC9B,UAAU;GACV,MAAM,SAAS;GACf,MAAM;GACN,MAAM;GACN,QAAQ;GACR,MAAM;GACP;;AAEH,KAAI,CAAC,YAAY,OAAO,EAAE,gBAAgB,MAAM,CAAC,CAC/C,QAAO,eAAe,SAAS,eAAe,MAAM,GAAG,UAAU,MAAM;CAEzE,MAAM,GAAG,WAAW,IAAI,MAAM,cAAc,MAAM,MAAM,QAAQ,OAAO,IAAI,CAAC,MAAM,4CAA4C,IAAI,EAAE;CACpI,IAAI,GAAG,OAAO,IAAI,OAAO,MAAM,YAAY,MAAM,iBAAiB,IAAI,EAAE;AACxE,KAAI,aAAa,QACf,QAAO,KAAK,QAAQ,mBAAmB,GAAG;CAE5C,MAAM,EAAE,UAAU,QAAQ,SAAS,UAAU,KAAK;AAClD,QAAO;EACL,UAAU,SAAS,aAAa;EAChC,MAAM,OAAO,KAAK,MAAM,GAAG,KAAK,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC,GAAG;EAC3D;EACA;EACA;EACA;GACC,mBAAmB,CAAC;EACtB;;AAEH,SAAS,UAAU,QAAQ,IAAI;CAC7B,MAAM,CAAC,WAAW,IAAI,SAAS,IAAI,OAAO,OAAO,MAAM,MAAM,2BAA2B,IAAI,EAAE,EAAE,OAAO,EAAE;AACzG,QAAO;EACL;EACA;EACA;EACD"}
@@ -0,0 +1,160 @@
1
+ import { t as getNitroRuntimeConfigRecord } from "./nitroConfigBridge-aZ1e5upQ.mjs";
2
+ //#region src/shared/config.ts
3
+ /** Read the full Nitro `useRuntimeConfig()` record (or `undefined` outside Nitro). */
4
+ function getRuntimeConfig() {
5
+ return getNitroRuntimeConfigRecord();
6
+ }
7
+ /**
8
+ * Resolve adapter configuration with the standard priority chain:
9
+ *
10
+ * 1. `overrides` passed to the drain factory
11
+ * 2. `runtimeConfig.evlog.{namespace}.{key}` (Nitro)
12
+ * 3. `runtimeConfig.{namespace}.{key}` (Nitro)
13
+ * 4. `process.env[envKey]` for each env in `field.env`
14
+ */
15
+ async function resolveAdapterConfig(namespace, fields, overrides) {
16
+ const runtimeConfig = shouldProbeRuntimeConfig(fields, overrides) ? await getRuntimeConfig() : void 0;
17
+ const evlogNs = runtimeConfig?.evlog?.[namespace];
18
+ const rootNs = runtimeConfig?.[namespace];
19
+ const config = {};
20
+ for (const { key, env } of fields) config[key] = overrides?.[key] ?? evlogNs?.[key] ?? rootNs?.[key] ?? resolveEnv(env);
21
+ return config;
22
+ }
23
+ function shouldProbeRuntimeConfig(fields, overrides) {
24
+ return fields.some(({ key, env }) => {
25
+ if (overrides?.[key] !== void 0) return false;
26
+ if (!env) return false;
27
+ return resolveEnv(env) === void 0;
28
+ });
29
+ }
30
+ function resolveEnv(envKeys) {
31
+ if (!envKeys) return void 0;
32
+ for (const key of envKeys) {
33
+ const val = process.env[key];
34
+ if (val) return val;
35
+ }
36
+ }
37
+ //#endregion
38
+ //#region src/shared/http.ts
39
+ function isRetryable(error) {
40
+ if (error instanceof DOMException && error.name === "AbortError") return true;
41
+ if (error instanceof TypeError) return true;
42
+ if (error instanceof Error) {
43
+ const match = error.message.match(/API error: (\d+)/);
44
+ if (match) return Number.parseInt(match[1]) >= 500;
45
+ }
46
+ return false;
47
+ }
48
+ /**
49
+ * POST a body with timeout + retry. Throws label-prefixed errors with a
50
+ * truncated response body. Safe to call from any drain `send()`.
51
+ */
52
+ async function httpPost({ url, headers, body, timeout, label, retries = 2 }) {
53
+ const normalizedRetries = Number.isFinite(retries) && retries >= 0 ? Math.floor(retries) : 2;
54
+ let lastError;
55
+ for (let attempt = 0; attempt <= normalizedRetries; attempt++) {
56
+ const controller = new AbortController();
57
+ const timeoutId = setTimeout(() => controller.abort(), timeout);
58
+ try {
59
+ const response = await fetch(url, {
60
+ method: "POST",
61
+ headers,
62
+ body,
63
+ signal: controller.signal
64
+ });
65
+ if (!response.ok) {
66
+ const text = await response.text().catch(() => "Unknown error");
67
+ const safeText = text.length > 200 ? `${text.slice(0, 200)}...[truncated]` : text;
68
+ throw new Error(`${label} API error: ${response.status} ${response.statusText} - ${safeText}`);
69
+ }
70
+ clearTimeout(timeoutId);
71
+ return;
72
+ } catch (error) {
73
+ clearTimeout(timeoutId);
74
+ if (error instanceof DOMException && error.name === "AbortError") lastError = /* @__PURE__ */ new Error(`${label} request timed out after ${timeout}ms`);
75
+ else lastError = error;
76
+ if (!isRetryable(error) || attempt === normalizedRetries) throw lastError;
77
+ await new Promise((r) => setTimeout(r, 200 * 2 ** attempt));
78
+ }
79
+ }
80
+ throw lastError;
81
+ }
82
+ //#endregion
83
+ //#region src/shared/drain.ts
84
+ /**
85
+ * Build a drain callback. Errors raised by `send` are logged with the drain
86
+ * name and swallowed, so a failing drain never breaks the request pipeline.
87
+ *
88
+ * @example
89
+ * ```ts
90
+ * export function createMyDrain(overrides?: Partial<MyConfig>) {
91
+ * return defineDrain<MyConfig>({
92
+ * name: 'my-drain',
93
+ * resolve: () => ({ url: process.env.MY_URL ?? null }),
94
+ * send: async (events, config) => { ... },
95
+ * })
96
+ * }
97
+ * ```
98
+ */
99
+ function defineDrain(options) {
100
+ return async (ctx) => {
101
+ const contexts = Array.isArray(ctx) ? ctx : [ctx];
102
+ if (contexts.length === 0) return;
103
+ const config = await options.resolve();
104
+ if (!config) return;
105
+ try {
106
+ await options.send(contexts.map((c) => c.event), config);
107
+ } catch (error) {
108
+ console.error(`[evlog/${options.name}] Failed to send events:`, error);
109
+ }
110
+ };
111
+ }
112
+ const DEFAULT_HTTP_TIMEOUT = 5e3;
113
+ /**
114
+ * Build an HTTP drain. Timeouts/retries are resolved from the config (with
115
+ * overrides via `resolveTimeout` / `resolveRetries`) and forwarded to
116
+ * {@link httpPost}.
117
+ *
118
+ * @example
119
+ * ```ts
120
+ * export function createMyDrain(overrides?: Partial<MyConfig>) {
121
+ * return defineHttpDrain<MyConfig>({
122
+ * name: 'my',
123
+ * resolve: async () => {
124
+ * const cfg = await resolveAdapterConfig<MyConfig>('my', FIELDS, overrides)
125
+ * return cfg.apiKey ? cfg as MyConfig : null
126
+ * },
127
+ * encode: (events, config) => ({
128
+ * url: `${config.endpoint ?? 'https://api.my.com'}/ingest`,
129
+ * headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${config.apiKey}` },
130
+ * body: JSON.stringify(events),
131
+ * }),
132
+ * })
133
+ * }
134
+ * ```
135
+ */
136
+ function defineHttpDrain(options) {
137
+ return defineDrain({
138
+ name: options.name,
139
+ resolve: options.resolve,
140
+ send: async (events, config) => {
141
+ if (events.length === 0) return;
142
+ const request = options.encode(events, config);
143
+ if (!request) return;
144
+ const timeout = options.resolveTimeout?.(config) ?? config.timeout ?? options.timeout ?? DEFAULT_HTTP_TIMEOUT;
145
+ const retries = options.resolveRetries?.(config) ?? config.retries ?? options.retries;
146
+ await httpPost({
147
+ url: request.url,
148
+ headers: request.headers,
149
+ body: request.body,
150
+ timeout,
151
+ retries,
152
+ label: options.name
153
+ });
154
+ }
155
+ });
156
+ }
157
+ //#endregion
158
+ export { resolveAdapterConfig as a, getRuntimeConfig as i, defineHttpDrain as n, httpPost as r, defineDrain as t };
159
+
160
+ //# sourceMappingURL=drain-ByWUeOQC.mjs.map