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
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 HugoRCD
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -11,11 +11,11 @@
11
11
  [![Documentation](https://img.shields.io/badge/Documentation-black?logo=readme&logoColor=white)](https://evlog.dev)
12
12
  [![license](https://img.shields.io/github/license/HugoRCD/evlog?color=black)](https://github.com/HugoRCD/evlog/blob/main/LICENSE)
13
13
 
14
- **Your logs are lying to you.**
14
+ **Digging through logs is not observability. It's hope.**
15
15
 
16
- A single request generates 10+ log lines. When production breaks at 3am, you're grep-ing through noise, praying you'll find signal. Your errors say "Something went wrong" -- thanks, very helpful.
16
+ A single request generates 10+ log lines. When production breaks at 3am, you're sifting scattered lines for a needle of signal. Your errors say "Something went wrong" thanks, very helpful.
17
17
 
18
- **evlog fixes this.** One log per request. All context included. Errors that explain themselves.
18
+ **evlog is different.** One wide event per operation. All the context. Errors that explain *why* and what to do next.
19
19
 
20
20
  ## Why evlog?
21
21
 
@@ -336,30 +336,40 @@ async function processSyncJob(job: Job) {
336
336
 
337
337
  ## Cloudflare Workers
338
338
 
339
- Use the Workers adapter for structured logs and correct platform severity.
339
+ Use the Workers adapter for structured logs and correct platform severity. With `initWorkersLogger({ drain })`, use **`defineWorkerFetch`** so async drains are registered with `waitUntil` automatically (Cloudflare only passes `ExecutionContext` as the third `fetch` argument — there is no global).
340
340
 
341
341
  ```typescript
342
342
  // src/index.ts
343
- import { initWorkersLogger, createWorkersLogger } from 'evlog/workers'
343
+ import { defineWorkerFetch, initWorkersLogger } from 'evlog/workers'
344
344
 
345
345
  initWorkersLogger({
346
346
  env: { service: 'edge-api' },
347
347
  })
348
348
 
349
+ export default defineWorkerFetch(async (request, _env, _ctx, log) => {
350
+ try {
351
+ log.set({ route: 'health' })
352
+ const response = new Response('ok', { status: 200 })
353
+ log.emit({ status: response.status })
354
+ return response
355
+ } catch (error) {
356
+ log.error(error as Error)
357
+ log.emit({ status: 500 })
358
+ throw error
359
+ }
360
+ })
361
+ ```
362
+
363
+ If you keep a raw `export default { fetch }`, pass `{ executionCtx: ctx }` to `createWorkersLogger` or `waitUntil` on `createRequestLogger`.
364
+
365
+ ```typescript
366
+ // Lower-level (equivalent)
367
+ import { createWorkersLogger } from 'evlog/workers'
368
+
349
369
  export default {
350
- async fetch(request: Request) {
351
- const log = createWorkersLogger(request)
352
-
353
- try {
354
- log.set({ route: 'health' })
355
- const response = new Response('ok', { status: 200 })
356
- log.emit({ status: response.status })
357
- return response
358
- } catch (error) {
359
- log.error(error as Error)
360
- log.emit({ status: 500 })
361
- throw error
362
- }
370
+ async fetch(request: Request, _env: unknown, ctx: ExecutionContext) {
371
+ const log = createWorkersLogger(request, { executionCtx: ctx })
372
+ // ...
363
373
  },
364
374
  }
365
375
  ```
@@ -373,6 +383,7 @@ invocation_logs = false
373
383
  ```
374
384
 
375
385
  Notes:
386
+ - Prefer **`defineWorkerFetch`** so you do not have to pass `executionCtx` yourself when using a drain
376
387
  - `requestId` defaults to `cf-ray` when available
377
388
  - `request.cf` is included (colo, country, asn) unless disabled
378
389
  - Use `headerAllowlist` to avoid logging sensitive headers
@@ -747,7 +758,7 @@ export default defineEventHandler(async (event) => {
747
758
 
748
759
  `AuditFields` is exported and merges with `BaseWideEvent` — augment it with `declare module` if you need extra typed fields. Audit events are always force-kept by tail sampling and get a deterministic `idempotencyKey` so retries are safe across drains.
749
760
 
750
- See [the Audit Logs guide](https://evlog.dev/logging/audit) for compliance, GDPR, and recipe details.
761
+ See [the Audit Logs guide](https://evlog.dev/logging/audit/overview) for compliance, GDPR, and recipe details.
751
762
 
752
763
  ## AI SDK Integration
753
764
 
@@ -1185,6 +1196,21 @@ initWorkersLogger({
1185
1196
  })
1186
1197
  ```
1187
1198
 
1199
+ ### `defineWorkerFetch(handler)`
1200
+
1201
+ Recommended for Workers when using **`initWorkersLogger({ drain })`**. Wraps your handler so `createWorkersLogger` always receives `executionCtx` — you do not pass `ctx` into the factory yourself. Cloudflare does not expose `ExecutionContext` globally (only as `fetch`’s third argument), so this is the “automatic” option for plain Workers scripts.
1202
+
1203
+ ```typescript
1204
+ import { defineWorkerFetch, initWorkersLogger } from 'evlog/workers'
1205
+
1206
+ initWorkersLogger({ env: { service: 'edge-api' }, drain })
1207
+
1208
+ export default defineWorkerFetch(async (request, env, ctx, log) => {
1209
+ log.emit({ status: 200 })
1210
+ return new Response('ok')
1211
+ })
1212
+ ```
1213
+
1188
1214
  ### `createWorkersLogger(request, options?)`
1189
1215
 
1190
1216
  Create a request-scoped logger for Workers. Auto-extracts `cf-ray`, `request.cf`, method, and path.
@@ -1192,11 +1218,15 @@ Create a request-scoped logger for Workers. Auto-extracts `cf-ray`, `request.cf`
1192
1218
  ```typescript
1193
1219
  import { createWorkersLogger } from 'evlog/workers'
1194
1220
 
1221
+ // ctx is the third argument to fetch(request, env, ctx)
1195
1222
  const log = createWorkersLogger(request, {
1196
1223
  requestId: 'custom-id', // Override cf-ray (default: cf-ray header)
1197
1224
  headers: ['x-request-id'], // Headers to include (default: none)
1225
+ executionCtx: ctx, // With initWorkersLogger({ drain }), registers async drain via waitUntil
1198
1226
  })
1199
1227
 
1228
+ // Or pass waitUntil directly: waitUntil: ctx.waitUntil.bind(ctx)
1229
+
1200
1230
  log.set({ user: { id: '123' } })
1201
1231
  log.emit({ status: 200 })
1202
1232
  ```
@@ -1,11 +1,20 @@
1
- import { F as DrainContext, it as WideEvent } from "../audit-mUutdf6A.mjs";
1
+ import { F as DrainContext, it as WideEvent } from "../audit-CJl-wZ10.mjs";
2
2
  //#region src/adapters/axiom.d.ts
3
3
  interface BaseAxiomConfig {
4
- /** Axiom dataset name */
4
+ /** Axiom dataset name. */
5
5
  dataset: string;
6
- /** Axiom API token */
7
- token: string;
8
- /** Organization ID (required for Personal Access Tokens) */
6
+ /**
7
+ * Axiom API key.
8
+ *
9
+ * @example `xaat-...`
10
+ */
11
+ apiKey: string;
12
+ /**
13
+ * @deprecated Renamed to {@link BaseAxiomConfig.apiKey}. Will be removed in
14
+ * the next major version. Pass `apiKey` instead.
15
+ */
16
+ token?: string;
17
+ /** Organization ID (required for Personal Access Tokens). */
9
18
  orgId?: string;
10
19
  /** Request timeout in milliseconds. Default: 5000 */
11
20
  timeout?: number;
@@ -36,42 +45,24 @@ type AxiomConfig = BaseAxiomConfig & (EdgeAxiomConfig | EndpointAxiomConfig);
36
45
  * 1. Overrides passed to createAxiomDrain()
37
46
  * 2. runtimeConfig.evlog.axiom
38
47
  * 3. runtimeConfig.axiom
39
- * 4. Environment variables: NUXT_AXIOM_*, AXIOM_*
48
+ * 4. Environment variables: NUXT_AXIOM_API_KEY, AXIOM_API_KEY (or legacy `*_TOKEN`)
40
49
  *
41
50
  * @example
42
51
  * ```ts
43
- * // Zero config - just set NUXT_AXIOM_TOKEN and NUXT_AXIOM_DATASET env vars
44
- * nitroApp.hooks.hook('evlog:drain', createAxiomDrain())
52
+ * // Zero config set NUXT_AXIOM_API_KEY and NUXT_AXIOM_DATASET
53
+ * initLogger({ drain: createAxiomDrain() })
45
54
  *
46
55
  * // With overrides
47
- * nitroApp.hooks.hook('evlog:drain', createAxiomDrain({
48
- * dataset: 'my-dataset',
49
- * }))
56
+ * initLogger({ drain: createAxiomDrain({ dataset: 'my-dataset' }) })
50
57
  * ```
51
58
  */
52
59
  declare function createAxiomDrain(overrides?: Partial<AxiomConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
53
60
  /**
54
61
  * Send a single event to Axiom.
55
- *
56
- * @example
57
- * ```ts
58
- * await sendToAxiom(event, {
59
- * dataset: 'my-logs',
60
- * token: process.env.AXIOM_TOKEN!,
61
- * })
62
- * ```
63
62
  */
64
63
  declare function sendToAxiom(event: WideEvent, config: AxiomConfig): Promise<void>;
65
64
  /**
66
65
  * Send a batch of events to Axiom.
67
- *
68
- * @example
69
- * ```ts
70
- * await sendBatchToAxiom(events, {
71
- * dataset: 'my-logs',
72
- * token: process.env.AXIOM_TOKEN!,
73
- * })
74
- * ```
75
66
  */
76
67
  declare function sendBatchToAxiom(events: WideEvent[], config: AxiomConfig): Promise<void>;
77
68
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"axiom.d.mts","names":[],"sources":["../../src/adapters/axiom.ts"],"mappings":";;UAMU,eAAA;;EAER,OAAA;EAFQ;EAIR,KAAA;;EAEA,KAAA;EAJA;EAMA,OAAA;EAFA;EAIA,OAAA;AAAA;AAAA,UAGQ,eAAA;EAHD;AAAA;;;;EASP,OAAA;EAKQ;EAHR,OAAA;AAAA;AAAA,UAGQ,mBAAA;EAID;EAFP,OAAA;EAKqB;EAHrB,OAAA;AAAA;AAAA,KAGU,WAAA,GAAc,eAAA,IAAmB,eAAA,GAAkB,mBAAA;;;;;;;;;AAqC/D;;;;;;;;;;;;iBAAgB,gBAAA,CAAiB,SAAA,GAAY,OAAA,CAAQ,WAAA,KAAY,GAAA,EAAb,YAAA,GAAa,YAAA,OAAA,OAAA;;;;;;;AAoCjE;;;;;iBAAsB,WAAA,CAAY,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,WAAA,GAAc,OAAA;;;;;;;;;;AAe1E;;iBAAsB,gBAAA,CAAiB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,WAAA,GAAc,OAAA"}
1
+ {"version":3,"file":"axiom.d.mts","names":[],"sources":["../../src/adapters/axiom.ts"],"mappings":";;UAMU,eAAA;;EAER,OAAA;EAFQ;;;;;EAQR,MAAA;EAKA;;;;EAAA,KAAA;EAMO;EAJP,KAAA;EAOuB;EALvB,OAAA;EAWA;EATA,OAAA;AAAA;AAAA,UAGQ,eAAA;;;;AAkBV;;EAZE,OAAA;EAYwB;EAVxB,OAAA;AAAA;AAAA,UAGQ,mBAAA;EAOwE;EALhF,OAAA;EAK2C;EAH3C,OAAA;AAAA;AAAA,KAGU,WAAA,GAAc,eAAA,IAAmB,eAAA,GAAkB,mBAAA;AAkD/D;;;;;;;;;;;;;;;;;;AAAA,iBAAgB,gBAAA,CAAiB,SAAA,GAAY,OAAA,CAAQ,WAAA,KAAY,GAAA,EAAb,YAAA,GAAa,YAAA,OAAA,OAAA;AAmCjE;;;AAAA,iBAAsB,WAAA,CAAY,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,WAAA,GAAc,OAAA;;;;iBAOpD,gBAAA,CAAiB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,WAAA,GAAc,OAAA"}
@@ -1,11 +1,14 @@
1
- import { n as resolveAdapterConfig, t as httpPost } from "../_http-CHSsrWDJ.mjs";
2
- import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
1
+ import { a as resolveAdapterConfig, n as defineHttpDrain, r as httpPost } from "../drain-ByWUeOQC.mjs";
3
2
  //#region src/adapters/axiom.ts
4
3
  const AXIOM_FIELDS = [
5
4
  {
6
5
  key: "dataset",
7
6
  env: ["NUXT_AXIOM_DATASET", "AXIOM_DATASET"]
8
7
  },
8
+ {
9
+ key: "apiKey",
10
+ env: ["NUXT_AXIOM_API_KEY", "AXIOM_API_KEY"]
11
+ },
9
12
  {
10
13
  key: "token",
11
14
  env: ["NUXT_AXIOM_TOKEN", "AXIOM_TOKEN"]
@@ -25,6 +28,17 @@ const AXIOM_FIELDS = [
25
28
  { key: "timeout" },
26
29
  { key: "retries" }
27
30
  ];
31
+ let warnedAboutToken = false;
32
+ function applyApiKeyAlias(config) {
33
+ if (!config.apiKey && config.token) {
34
+ if (!warnedAboutToken) {
35
+ warnedAboutToken = true;
36
+ console.warn("[evlog/axiom] `token` is deprecated, use `apiKey` instead. (Env: NUXT_AXIOM_TOKEN/AXIOM_TOKEN → NUXT_AXIOM_API_KEY/AXIOM_API_KEY.)");
37
+ }
38
+ config.apiKey = config.token;
39
+ }
40
+ return config;
41
+ }
28
42
  /**
29
43
  * Create a drain function for sending logs to Axiom.
30
44
  *
@@ -32,26 +46,24 @@ const AXIOM_FIELDS = [
32
46
  * 1. Overrides passed to createAxiomDrain()
33
47
  * 2. runtimeConfig.evlog.axiom
34
48
  * 3. runtimeConfig.axiom
35
- * 4. Environment variables: NUXT_AXIOM_*, AXIOM_*
49
+ * 4. Environment variables: NUXT_AXIOM_API_KEY, AXIOM_API_KEY (or legacy `*_TOKEN`)
36
50
  *
37
51
  * @example
38
52
  * ```ts
39
- * // Zero config - just set NUXT_AXIOM_TOKEN and NUXT_AXIOM_DATASET env vars
40
- * nitroApp.hooks.hook('evlog:drain', createAxiomDrain())
53
+ * // Zero config set NUXT_AXIOM_API_KEY and NUXT_AXIOM_DATASET
54
+ * initLogger({ drain: createAxiomDrain() })
41
55
  *
42
56
  * // With overrides
43
- * nitroApp.hooks.hook('evlog:drain', createAxiomDrain({
44
- * dataset: 'my-dataset',
45
- * }))
57
+ * initLogger({ drain: createAxiomDrain({ dataset: 'my-dataset' }) })
46
58
  * ```
47
59
  */
48
60
  function createAxiomDrain(overrides) {
49
- return defineDrain({
61
+ return defineHttpDrain({
50
62
  name: "axiom",
51
63
  resolve: async () => {
52
- const config = await resolveAdapterConfig("axiom", AXIOM_FIELDS, overrides);
53
- if (!config.dataset || !config.token) {
54
- console.error("[evlog/axiom] Missing dataset or token. Set NUXT_AXIOM_TOKEN/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()");
64
+ const config = applyApiKeyAlias(await resolveAdapterConfig("axiom", AXIOM_FIELDS, overrides));
65
+ if (!config.dataset || !config.apiKey) {
66
+ console.error("[evlog/axiom] Missing dataset or apiKey. Set NUXT_AXIOM_API_KEY/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()");
55
67
  return null;
56
68
  }
57
69
  if (config.edgeUrl && config.baseUrl) {
@@ -60,39 +72,37 @@ function createAxiomDrain(overrides) {
60
72
  }
61
73
  return config;
62
74
  },
63
- send: sendBatchToAxiom
75
+ encode: (events, config) => {
76
+ const url = resolveIngestUrl(config);
77
+ const headers = {
78
+ "Content-Type": "application/json",
79
+ "Authorization": `Bearer ${config.apiKey}`
80
+ };
81
+ if (config.orgId) headers["X-Axiom-Org-Id"] = config.orgId;
82
+ return {
83
+ url,
84
+ headers,
85
+ body: JSON.stringify(events)
86
+ };
87
+ }
64
88
  });
65
89
  }
66
90
  /**
67
91
  * Send a single event to Axiom.
68
- *
69
- * @example
70
- * ```ts
71
- * await sendToAxiom(event, {
72
- * dataset: 'my-logs',
73
- * token: process.env.AXIOM_TOKEN!,
74
- * })
75
- * ```
76
92
  */
77
93
  async function sendToAxiom(event, config) {
78
94
  await sendBatchToAxiom([event], config);
79
95
  }
80
96
  /**
81
97
  * Send a batch of events to Axiom.
82
- *
83
- * @example
84
- * ```ts
85
- * await sendBatchToAxiom(events, {
86
- * dataset: 'my-logs',
87
- * token: process.env.AXIOM_TOKEN!,
88
- * })
89
- * ```
90
98
  */
91
99
  async function sendBatchToAxiom(events, config) {
100
+ const apiKey = config.apiKey ?? config.token;
101
+ if (!apiKey) throw new Error("[evlog/axiom] Missing apiKey");
92
102
  const url = resolveIngestUrl(config);
93
103
  const headers = {
94
104
  "Content-Type": "application/json",
95
- "Authorization": `Bearer ${config.token}`
105
+ "Authorization": `Bearer ${apiKey}`
96
106
  };
97
107
  if (config.orgId) headers["X-Axiom-Org-Id"] = config.orgId;
98
108
  await httpPost({
@@ -1 +1 @@
1
- {"version":3,"file":"axiom.mjs","names":[],"sources":["../../src/adapters/axiom.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from './_config'\nimport { resolveAdapterConfig } from './_config'\nimport { defineDrain } from './_drain'\nimport { httpPost } from './_http'\n\ninterface BaseAxiomConfig {\n /** Axiom dataset name */\n dataset: string\n /** Axiom API token */\n token: string\n /** Organization ID (required for Personal Access Tokens) */\n orgId?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\ninterface EdgeAxiomConfig {\n /**\n * Edge URL for Axiom ingest/query endpoints.\n * If no path is provided, uses /v1/ingest/{dataset}.\n * If a custom path is provided, it is used as-is (trailing slash trimmed).\n */\n edgeUrl: string\n /** Mutually exclusive with edgeUrl. */\n baseUrl?: never\n}\n\ninterface EndpointAxiomConfig {\n /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n baseUrl?: string\n /** Mutually exclusive with baseUrl. */\n edgeUrl?: never\n}\n\nexport type AxiomConfig = BaseAxiomConfig & (EdgeAxiomConfig | EndpointAxiomConfig)\n\ntype ResolvedAxiomConfig = BaseAxiomConfig & {\n edgeUrl?: string\n baseUrl?: string\n}\n\nconst AXIOM_FIELDS: ConfigField<ResolvedAxiomConfig>[] = [\n { key: 'dataset', env: ['NUXT_AXIOM_DATASET', 'AXIOM_DATASET'] },\n { key: 'token', env: ['NUXT_AXIOM_TOKEN', 'AXIOM_TOKEN'] },\n { key: 'orgId', env: ['NUXT_AXIOM_ORG_ID', 'AXIOM_ORG_ID'] },\n { key: 'edgeUrl', env: ['NUXT_AXIOM_EDGE_URL', 'AXIOM_EDGE_URL'] },\n { key: 'baseUrl', env: ['NUXT_AXIOM_URL', 'AXIOM_URL'] },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\n/**\n * Create a drain function for sending logs to Axiom.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createAxiomDrain()\n * 2. runtimeConfig.evlog.axiom\n * 3. runtimeConfig.axiom\n * 4. Environment variables: NUXT_AXIOM_*, AXIOM_*\n *\n * @example\n * ```ts\n * // Zero config - just set NUXT_AXIOM_TOKEN and NUXT_AXIOM_DATASET env vars\n * nitroApp.hooks.hook('evlog:drain', createAxiomDrain())\n *\n * // With overrides\n * nitroApp.hooks.hook('evlog:drain', createAxiomDrain({\n * dataset: 'my-dataset',\n * }))\n * ```\n */\nexport function createAxiomDrain(overrides?: Partial<AxiomConfig>) {\n return defineDrain<AxiomConfig>({\n name: 'axiom',\n resolve: async () => {\n const config = await resolveAdapterConfig<ResolvedAxiomConfig>(\n 'axiom',\n AXIOM_FIELDS,\n overrides as Partial<ResolvedAxiomConfig>,\n )\n if (!config.dataset || !config.token) {\n console.error('[evlog/axiom] Missing dataset or token. Set NUXT_AXIOM_TOKEN/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()')\n return null\n }\n\n if (config.edgeUrl && config.baseUrl) {\n console.warn('[evlog/axiom] Both edgeUrl and baseUrl are set. edgeUrl takes precedence for ingest.')\n delete config.baseUrl\n }\n\n return config as AxiomConfig\n },\n send: sendBatchToAxiom,\n })\n}\n\n/**\n * Send a single event to Axiom.\n *\n * @example\n * ```ts\n * await sendToAxiom(event, {\n * dataset: 'my-logs',\n * token: process.env.AXIOM_TOKEN!,\n * })\n * ```\n */\nexport async function sendToAxiom(event: WideEvent, config: AxiomConfig): Promise<void> {\n await sendBatchToAxiom([event], config)\n}\n\n/**\n * Send a batch of events to Axiom.\n *\n * @example\n * ```ts\n * await sendBatchToAxiom(events, {\n * dataset: 'my-logs',\n * token: process.env.AXIOM_TOKEN!,\n * })\n * ```\n */\nexport async function sendBatchToAxiom(events: WideEvent[], config: AxiomConfig): Promise<void> {\n const url = resolveIngestUrl(config)\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.token}`,\n }\n\n if (config.orgId) {\n headers['X-Axiom-Org-Id'] = config.orgId\n }\n\n await httpPost({\n url,\n headers,\n body: JSON.stringify(events),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'Axiom',\n })\n}\n\nfunction resolveIngestUrl(config: AxiomConfig): string {\n const encodedDataset = encodeURIComponent(config.dataset)\n\n if (!config.edgeUrl) {\n const baseUrl = config.baseUrl ?? 'https://api.axiom.co'\n return `${baseUrl}/v1/datasets/${encodedDataset}/ingest`\n }\n\n try {\n const parsed = new URL(config.edgeUrl)\n\n if (parsed.pathname === '' || parsed.pathname === '/') {\n parsed.pathname = `/v1/ingest/${encodedDataset}`\n return parsed.toString()\n }\n\n parsed.pathname = parsed.pathname.replace(/\\/+$/, '')\n return parsed.toString()\n } catch {\n console.warn(`[evlog/axiom] edgeUrl \"${config.edgeUrl}\" is not a valid URL, falling back to string concatenation.`)\n const trimmed = config.edgeUrl.replace(/\\/+$/, '')\n return `${trimmed}/v1/ingest/${encodedDataset}`\n }\n}\n"],"mappings":";;;AA4CA,MAAM,eAAmD;CACvD;EAAE,KAAK;EAAW,KAAK,CAAC,sBAAsB,gBAAgB;EAAE;CAChE;EAAE,KAAK;EAAS,KAAK,CAAC,oBAAoB,cAAc;EAAE;CAC1D;EAAE,KAAK;EAAS,KAAK,CAAC,qBAAqB,eAAe;EAAE;CAC5D;EAAE,KAAK;EAAW,KAAK,CAAC,uBAAuB,iBAAiB;EAAE;CAClE;EAAE,KAAK;EAAW,KAAK,CAAC,kBAAkB,YAAY;EAAE;CACxD,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;;;;;;;;;;;;;;;;;;;;;AAsBD,SAAgB,iBAAiB,WAAkC;AACjE,QAAO,YAAyB;EAC9B,MAAM;EACN,SAAS,YAAY;GACnB,MAAM,SAAS,MAAM,qBACnB,SACA,cACA,UACD;AACD,OAAI,CAAC,OAAO,WAAW,CAAC,OAAO,OAAO;AACpC,YAAQ,MAAM,yHAAyH;AACvI,WAAO;;AAGT,OAAI,OAAO,WAAW,OAAO,SAAS;AACpC,YAAQ,KAAK,uFAAuF;AACpG,WAAO,OAAO;;AAGhB,UAAO;;EAET,MAAM;EACP,CAAC;;;;;;;;;;;;;AAcJ,eAAsB,YAAY,OAAkB,QAAoC;AACtF,OAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO;;;;;;;;;;;;;AAczC,eAAsB,iBAAiB,QAAqB,QAAoC;CAC9F,MAAM,MAAM,iBAAiB,OAAO;CAEpC,MAAM,UAAkC;EACtC,gBAAgB;EAChB,iBAAiB,UAAU,OAAO;EACnC;AAED,KAAI,OAAO,MACT,SAAQ,oBAAoB,OAAO;AAGrC,OAAM,SAAS;EACb;EACA;EACA,MAAM,KAAK,UAAU,OAAO;EAC5B,SAAS,OAAO,WAAW;EAC3B,SAAS,OAAO;EAChB,OAAO;EACR,CAAC;;AAGJ,SAAS,iBAAiB,QAA6B;CACrD,MAAM,iBAAiB,mBAAmB,OAAO,QAAQ;AAEzD,KAAI,CAAC,OAAO,QAEV,QAAO,GADS,OAAO,WAAW,uBAChB,eAAe,eAAe;AAGlD,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,OAAO,QAAQ;AAEtC,MAAI,OAAO,aAAa,MAAM,OAAO,aAAa,KAAK;AACrD,UAAO,WAAW,cAAc;AAChC,UAAO,OAAO,UAAU;;AAG1B,SAAO,WAAW,OAAO,SAAS,QAAQ,QAAQ,GAAG;AACrD,SAAO,OAAO,UAAU;SAClB;AACN,UAAQ,KAAK,0BAA0B,OAAO,QAAQ,6DAA6D;AAEnH,SAAO,GADS,OAAO,QAAQ,QAAQ,QAAQ,GAAG,CAChC,aAAa"}
1
+ {"version":3,"file":"axiom.mjs","names":[],"sources":["../../src/adapters/axiom.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineHttpDrain } from '../shared/drain'\nimport { httpPost } from '../shared/http'\n\ninterface BaseAxiomConfig {\n /** Axiom dataset name. */\n dataset: string\n /**\n * Axiom API key.\n *\n * @example `xaat-...`\n */\n apiKey: string\n /**\n * @deprecated Renamed to {@link BaseAxiomConfig.apiKey}. Will be removed in\n * the next major version. Pass `apiKey` instead.\n */\n token?: string\n /** Organization ID (required for Personal Access Tokens). */\n orgId?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\ninterface EdgeAxiomConfig {\n /**\n * Edge URL for Axiom ingest/query endpoints.\n * If no path is provided, uses /v1/ingest/{dataset}.\n * If a custom path is provided, it is used as-is (trailing slash trimmed).\n */\n edgeUrl: string\n /** Mutually exclusive with edgeUrl. */\n baseUrl?: never\n}\n\ninterface EndpointAxiomConfig {\n /** Base URL for Axiom API. Uses /v1/datasets/{dataset}/ingest. */\n baseUrl?: string\n /** Mutually exclusive with baseUrl. */\n edgeUrl?: never\n}\n\nexport type AxiomConfig = BaseAxiomConfig & (EdgeAxiomConfig | EndpointAxiomConfig)\n\ntype ResolvedAxiomConfig = BaseAxiomConfig & {\n edgeUrl?: string\n baseUrl?: string\n}\n\nconst AXIOM_FIELDS: ConfigField<ResolvedAxiomConfig>[] = [\n { key: 'dataset', env: ['NUXT_AXIOM_DATASET', 'AXIOM_DATASET'] },\n { key: 'apiKey', env: ['NUXT_AXIOM_API_KEY', 'AXIOM_API_KEY'] },\n // Deprecated env var names — resolved as a fallback for `apiKey` below.\n { key: 'token', env: ['NUXT_AXIOM_TOKEN', 'AXIOM_TOKEN'] },\n { key: 'orgId', env: ['NUXT_AXIOM_ORG_ID', 'AXIOM_ORG_ID'] },\n { key: 'edgeUrl', env: ['NUXT_AXIOM_EDGE_URL', 'AXIOM_EDGE_URL'] },\n { key: 'baseUrl', env: ['NUXT_AXIOM_URL', 'AXIOM_URL'] },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\nlet warnedAboutToken = false\n\nfunction applyApiKeyAlias(config: ResolvedAxiomConfig): ResolvedAxiomConfig {\n if (!config.apiKey && config.token) {\n if (!warnedAboutToken) {\n warnedAboutToken = true\n console.warn('[evlog/axiom] `token` is deprecated, use `apiKey` instead. (Env: NUXT_AXIOM_TOKEN/AXIOM_TOKEN → NUXT_AXIOM_API_KEY/AXIOM_API_KEY.)')\n }\n config.apiKey = config.token\n }\n return config\n}\n\n/**\n * Create a drain function for sending logs to Axiom.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createAxiomDrain()\n * 2. runtimeConfig.evlog.axiom\n * 3. runtimeConfig.axiom\n * 4. Environment variables: NUXT_AXIOM_API_KEY, AXIOM_API_KEY (or legacy `*_TOKEN`)\n *\n * @example\n * ```ts\n * // Zero config set NUXT_AXIOM_API_KEY and NUXT_AXIOM_DATASET\n * initLogger({ drain: createAxiomDrain() })\n *\n * // With overrides\n * initLogger({ drain: createAxiomDrain({ dataset: 'my-dataset' }) })\n * ```\n */\nexport function createAxiomDrain(overrides?: Partial<AxiomConfig>) {\n return defineHttpDrain<AxiomConfig>({\n name: 'axiom',\n resolve: async () => {\n const resolved = await resolveAdapterConfig<ResolvedAxiomConfig>(\n 'axiom',\n AXIOM_FIELDS,\n overrides as Partial<ResolvedAxiomConfig>,\n )\n const config = applyApiKeyAlias(resolved)\n if (!config.dataset || !config.apiKey) {\n console.error('[evlog/axiom] Missing dataset or apiKey. Set NUXT_AXIOM_API_KEY/NUXT_AXIOM_DATASET env vars or pass to createAxiomDrain()')\n return null\n }\n if (config.edgeUrl && config.baseUrl) {\n console.warn('[evlog/axiom] Both edgeUrl and baseUrl are set. edgeUrl takes precedence for ingest.')\n delete config.baseUrl\n }\n return config as AxiomConfig\n },\n encode: (events, config) => {\n const url = resolveIngestUrl(config)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n }\n if (config.orgId) headers['X-Axiom-Org-Id'] = config.orgId\n return { url, headers, body: JSON.stringify(events) }\n },\n })\n}\n\n/**\n * Send a single event to Axiom.\n */\nexport async function sendToAxiom(event: WideEvent, config: AxiomConfig): Promise<void> {\n await sendBatchToAxiom([event], config)\n}\n\n/**\n * Send a batch of events to Axiom.\n */\nexport async function sendBatchToAxiom(events: WideEvent[], config: AxiomConfig): Promise<void> {\n const apiKey = config.apiKey ?? config.token\n if (!apiKey) {\n throw new Error('[evlog/axiom] Missing apiKey')\n }\n const url = resolveIngestUrl(config)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n }\n if (config.orgId) headers['X-Axiom-Org-Id'] = config.orgId\n await httpPost({\n url,\n headers,\n body: JSON.stringify(events),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'Axiom',\n })\n}\n\nfunction resolveIngestUrl(config: AxiomConfig): string {\n const encodedDataset = encodeURIComponent(config.dataset)\n\n if (!config.edgeUrl) {\n const baseUrl = config.baseUrl ?? 'https://api.axiom.co'\n return `${baseUrl}/v1/datasets/${encodedDataset}/ingest`\n }\n\n try {\n const parsed = new URL(config.edgeUrl)\n if (parsed.pathname === '' || parsed.pathname === '/') {\n parsed.pathname = `/v1/ingest/${encodedDataset}`\n return parsed.toString()\n }\n parsed.pathname = parsed.pathname.replace(/\\/+$/, '')\n return parsed.toString()\n } catch {\n console.warn(`[evlog/axiom] edgeUrl \"${config.edgeUrl}\" is not a valid URL, falling back to string concatenation.`)\n const trimmed = config.edgeUrl.replace(/\\/+$/, '')\n return `${trimmed}/v1/ingest/${encodedDataset}`\n }\n}\n"],"mappings":";;AAqDA,MAAM,eAAmD;CACvD;EAAE,KAAK;EAAW,KAAK,CAAC,sBAAsB,gBAAgB;EAAE;CAChE;EAAE,KAAK;EAAU,KAAK,CAAC,sBAAsB,gBAAgB;EAAE;CAE/D;EAAE,KAAK;EAAS,KAAK,CAAC,oBAAoB,cAAc;EAAE;CAC1D;EAAE,KAAK;EAAS,KAAK,CAAC,qBAAqB,eAAe;EAAE;CAC5D;EAAE,KAAK;EAAW,KAAK,CAAC,uBAAuB,iBAAiB;EAAE;CAClE;EAAE,KAAK;EAAW,KAAK,CAAC,kBAAkB,YAAY;EAAE;CACxD,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;AAED,IAAI,mBAAmB;AAEvB,SAAS,iBAAiB,QAAkD;AAC1E,KAAI,CAAC,OAAO,UAAU,OAAO,OAAO;AAClC,MAAI,CAAC,kBAAkB;AACrB,sBAAmB;AACnB,WAAQ,KAAK,qIAAqI;;AAEpJ,SAAO,SAAS,OAAO;;AAEzB,QAAO;;;;;;;;;;;;;;;;;;;;AAqBT,SAAgB,iBAAiB,WAAkC;AACjE,QAAO,gBAA6B;EAClC,MAAM;EACN,SAAS,YAAY;GAMnB,MAAM,SAAS,iBAAiB,MALT,qBACrB,SACA,cACA,UACD,CACwC;AACzC,OAAI,CAAC,OAAO,WAAW,CAAC,OAAO,QAAQ;AACrC,YAAQ,MAAM,4HAA4H;AAC1I,WAAO;;AAET,OAAI,OAAO,WAAW,OAAO,SAAS;AACpC,YAAQ,KAAK,uFAAuF;AACpG,WAAO,OAAO;;AAEhB,UAAO;;EAET,SAAS,QAAQ,WAAW;GAC1B,MAAM,MAAM,iBAAiB,OAAO;GACpC,MAAM,UAAkC;IACtC,gBAAgB;IAChB,iBAAiB,UAAU,OAAO;IACnC;AACD,OAAI,OAAO,MAAO,SAAQ,oBAAoB,OAAO;AACrD,UAAO;IAAE;IAAK;IAAS,MAAM,KAAK,UAAU,OAAO;IAAE;;EAExD,CAAC;;;;;AAMJ,eAAsB,YAAY,OAAkB,QAAoC;AACtF,OAAM,iBAAiB,CAAC,MAAM,EAAE,OAAO;;;;;AAMzC,eAAsB,iBAAiB,QAAqB,QAAoC;CAC9F,MAAM,SAAS,OAAO,UAAU,OAAO;AACvC,KAAI,CAAC,OACH,OAAM,IAAI,MAAM,+BAA+B;CAEjD,MAAM,MAAM,iBAAiB,OAAO;CACpC,MAAM,UAAkC;EACtC,gBAAgB;EAChB,iBAAiB,UAAU;EAC5B;AACD,KAAI,OAAO,MAAO,SAAQ,oBAAoB,OAAO;AACrD,OAAM,SAAS;EACb;EACA;EACA,MAAM,KAAK,UAAU,OAAO;EAC5B,SAAS,OAAO,WAAW;EAC3B,SAAS,OAAO;EAChB,OAAO;EACR,CAAC;;AAGJ,SAAS,iBAAiB,QAA6B;CACrD,MAAM,iBAAiB,mBAAmB,OAAO,QAAQ;AAEzD,KAAI,CAAC,OAAO,QAEV,QAAO,GADS,OAAO,WAAW,uBAChB,eAAe,eAAe;AAGlD,KAAI;EACF,MAAM,SAAS,IAAI,IAAI,OAAO,QAAQ;AACtC,MAAI,OAAO,aAAa,MAAM,OAAO,aAAa,KAAK;AACrD,UAAO,WAAW,cAAc;AAChC,UAAO,OAAO,UAAU;;AAE1B,SAAO,WAAW,OAAO,SAAS,QAAQ,QAAQ,GAAG;AACrD,SAAO,OAAO,UAAU;SAClB;AACN,UAAQ,KAAK,0BAA0B,OAAO,QAAQ,6DAA6D;AAEnH,SAAO,GADS,OAAO,QAAQ,QAAQ,QAAQ,GAC9B,CAAC,aAAa"}
@@ -1,8 +1,13 @@
1
- import { F as DrainContext, it as WideEvent } from "../audit-mUutdf6A.mjs";
1
+ import { F as DrainContext, it as WideEvent } from "../audit-CJl-wZ10.mjs";
2
2
  //#region src/adapters/better-stack.d.ts
3
3
  interface BetterStackConfig {
4
- /** Better Stack source token */
5
- sourceToken: string;
4
+ /** Better Stack API key (replaces deprecated `sourceToken`). */
5
+ apiKey: string;
6
+ /**
7
+ * @deprecated Renamed to {@link BetterStackConfig.apiKey}. Will be removed
8
+ * in the next major version. Pass `apiKey` instead.
9
+ */
10
+ sourceToken?: string;
6
11
  /** Logtail ingestion endpoint. Default: https://in.logs.betterstack.com */
7
12
  endpoint?: string;
8
13
  /** Request timeout in milliseconds. Default: 5000 */
@@ -22,40 +27,22 @@ declare function toBetterStackEvent(event: WideEvent): Record<string, unknown>;
22
27
  * 1. Overrides passed to createBetterStackDrain()
23
28
  * 2. runtimeConfig.evlog.betterStack
24
29
  * 3. runtimeConfig.betterStack
25
- * 4. Environment variables: NUXT_BETTER_STACK_*, BETTER_STACK_*
30
+ * 4. Environment variables: NUXT_BETTER_STACK_API_KEY, BETTER_STACK_API_KEY (or legacy `*_SOURCE_TOKEN`)
26
31
  *
27
32
  * @example
28
33
  * ```ts
29
- * // Zero config - just set NUXT_BETTER_STACK_SOURCE_TOKEN env var
30
- * nitroApp.hooks.hook('evlog:drain', createBetterStackDrain())
34
+ * initLogger({ drain: createBetterStackDrain() })
31
35
  *
32
- * // With overrides
33
- * nitroApp.hooks.hook('evlog:drain', createBetterStackDrain({
34
- * sourceToken: 'my-token',
35
- * }))
36
+ * initLogger({ drain: createBetterStackDrain({ apiKey: 'my-key' }) })
36
37
  * ```
37
38
  */
38
39
  declare function createBetterStackDrain(overrides?: Partial<BetterStackConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
39
40
  /**
40
41
  * Send a single event to Better Stack.
41
- *
42
- * @example
43
- * ```ts
44
- * await sendToBetterStack(event, {
45
- * sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
46
- * })
47
- * ```
48
42
  */
49
43
  declare function sendToBetterStack(event: WideEvent, config: BetterStackConfig): Promise<void>;
50
44
  /**
51
45
  * Send a batch of events to Better Stack.
52
- *
53
- * @example
54
- * ```ts
55
- * await sendBatchToBetterStack(events, {
56
- * sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
57
- * })
58
- * ```
59
46
  */
60
47
  declare function sendBatchToBetterStack(events: WideEvent[], config: BetterStackConfig): Promise<void>;
61
48
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"better-stack.d.mts","names":[],"sources":["../../src/adapters/better-stack.ts"],"mappings":";;UAMiB,iBAAA;;EAEf,WAAA;EAFe;EAIf,QAAA;;EAEA,OAAA;EAJA;EAMA,OAAA;AAAA;;;;AAcF;iBAAgB,kBAAA,CAAmB,KAAA,EAAO,SAAA,GAAY,MAAA;;;;;;;;AAyBtD;;;;;;;;;;;;;iBAAgB,sBAAA,CAAuB,SAAA,GAAY,OAAA,CAAQ,iBAAA,KAAkB,GAAA,EAAnB,YAAA,GAAmB,YAAA,OAAA,OAAA;;;;;;AAyB7E;;;;;iBAAsB,iBAAA,CAAkB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,iBAAA,GAAoB,OAAA;;;;;;;;;;AActF;iBAAsB,sBAAA,CAAuB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,iBAAA,GAAoB,OAAA"}
1
+ {"version":3,"file":"better-stack.d.mts","names":[],"sources":["../../src/adapters/better-stack.ts"],"mappings":";;UAMiB,iBAAA;;EAEf,MAAA;EAFe;;;;EAOf,WAAA;EAAA;EAEA,QAAA;EAEA;EAAA,OAAA;EAEO;EAAP,OAAA;AAAA;;;;;iBA6Bc,kBAAA,CAAmB,KAAA,EAAO,SAAA,GAAY,MAAA;;;;AAqBtD;;;;;;;;;;;;;iBAAgB,sBAAA,CAAuB,SAAA,GAAY,OAAA,CAAQ,iBAAA,KAAkB,GAAA,EAAnB,YAAA,GAAmB,YAAA,OAAA,OAAA;;;;iBA0BvD,iBAAA,CAAkB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,iBAAA,GAAoB,OAAA;;AAAtF;;iBAOsB,sBAAA,CAAuB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,iBAAA,GAAoB,OAAA"}
@@ -1,7 +1,10 @@
1
- import { n as resolveAdapterConfig, t as httpPost } from "../_http-CHSsrWDJ.mjs";
2
- import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
1
+ import { a as resolveAdapterConfig, n as defineHttpDrain, r as httpPost } from "../drain-ByWUeOQC.mjs";
3
2
  //#region src/adapters/better-stack.ts
4
3
  const BETTER_STACK_FIELDS = [
4
+ {
5
+ key: "apiKey",
6
+ env: ["NUXT_BETTER_STACK_API_KEY", "BETTER_STACK_API_KEY"]
7
+ },
5
8
  {
6
9
  key: "sourceToken",
7
10
  env: ["NUXT_BETTER_STACK_SOURCE_TOKEN", "BETTER_STACK_SOURCE_TOKEN"]
@@ -13,6 +16,17 @@ const BETTER_STACK_FIELDS = [
13
16
  { key: "timeout" },
14
17
  { key: "retries" }
15
18
  ];
19
+ let warnedAboutSourceToken = false;
20
+ function applyApiKeyAlias(config) {
21
+ if (!config.apiKey && config.sourceToken) {
22
+ if (!warnedAboutSourceToken) {
23
+ warnedAboutSourceToken = true;
24
+ console.warn("[evlog/better-stack] `sourceToken` is deprecated, use `apiKey` instead. (Env: NUXT_BETTER_STACK_SOURCE_TOKEN → NUXT_BETTER_STACK_API_KEY.)");
25
+ }
26
+ config.apiKey = config.sourceToken;
27
+ }
28
+ return config;
29
+ }
16
30
  /**
17
31
  * Transform an evlog wide event into a Better Stack event.
18
32
  * Maps `timestamp` to `dt` (Better Stack's expected field).
@@ -31,62 +45,53 @@ function toBetterStackEvent(event) {
31
45
  * 1. Overrides passed to createBetterStackDrain()
32
46
  * 2. runtimeConfig.evlog.betterStack
33
47
  * 3. runtimeConfig.betterStack
34
- * 4. Environment variables: NUXT_BETTER_STACK_*, BETTER_STACK_*
48
+ * 4. Environment variables: NUXT_BETTER_STACK_API_KEY, BETTER_STACK_API_KEY (or legacy `*_SOURCE_TOKEN`)
35
49
  *
36
50
  * @example
37
51
  * ```ts
38
- * // Zero config - just set NUXT_BETTER_STACK_SOURCE_TOKEN env var
39
- * nitroApp.hooks.hook('evlog:drain', createBetterStackDrain())
52
+ * initLogger({ drain: createBetterStackDrain() })
40
53
  *
41
- * // With overrides
42
- * nitroApp.hooks.hook('evlog:drain', createBetterStackDrain({
43
- * sourceToken: 'my-token',
44
- * }))
54
+ * initLogger({ drain: createBetterStackDrain({ apiKey: 'my-key' }) })
45
55
  * ```
46
56
  */
47
57
  function createBetterStackDrain(overrides) {
48
- return defineDrain({
58
+ return defineHttpDrain({
49
59
  name: "better-stack",
50
60
  resolve: async () => {
51
- const config = await resolveAdapterConfig("betterStack", BETTER_STACK_FIELDS, overrides);
52
- if (!config.sourceToken) {
53
- console.error("[evlog/better-stack] Missing source token. Set NUXT_BETTER_STACK_SOURCE_TOKEN env var or pass to createBetterStackDrain()");
61
+ const config = applyApiKeyAlias(await resolveAdapterConfig("betterStack", BETTER_STACK_FIELDS, overrides));
62
+ if (!config.apiKey) {
63
+ console.error("[evlog/better-stack] Missing apiKey. Set NUXT_BETTER_STACK_API_KEY env var or pass to createBetterStackDrain()");
54
64
  return null;
55
65
  }
56
66
  return config;
57
67
  },
58
- send: sendBatchToBetterStack
68
+ encode: (events, config) => ({
69
+ url: (config.endpoint ?? "https://in.logs.betterstack.com").replace(/\/+$/, ""),
70
+ headers: {
71
+ "Content-Type": "application/json",
72
+ "Authorization": `Bearer ${config.apiKey}`
73
+ },
74
+ body: JSON.stringify(events.map(toBetterStackEvent))
75
+ })
59
76
  });
60
77
  }
61
78
  /**
62
79
  * Send a single event to Better Stack.
63
- *
64
- * @example
65
- * ```ts
66
- * await sendToBetterStack(event, {
67
- * sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
68
- * })
69
- * ```
70
80
  */
71
81
  async function sendToBetterStack(event, config) {
72
82
  await sendBatchToBetterStack([event], config);
73
83
  }
74
84
  /**
75
85
  * Send a batch of events to Better Stack.
76
- *
77
- * @example
78
- * ```ts
79
- * await sendBatchToBetterStack(events, {
80
- * sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,
81
- * })
82
- * ```
83
86
  */
84
87
  async function sendBatchToBetterStack(events, config) {
88
+ const apiKey = config.apiKey ?? config.sourceToken;
89
+ if (!apiKey) throw new Error("[evlog/better-stack] Missing apiKey");
85
90
  await httpPost({
86
91
  url: (config.endpoint ?? "https://in.logs.betterstack.com").replace(/\/+$/, ""),
87
92
  headers: {
88
93
  "Content-Type": "application/json",
89
- "Authorization": `Bearer ${config.sourceToken}`
94
+ "Authorization": `Bearer ${apiKey}`
90
95
  },
91
96
  body: JSON.stringify(events.map(toBetterStackEvent)),
92
97
  timeout: config.timeout ?? 5e3,
@@ -1 +1 @@
1
- {"version":3,"file":"better-stack.mjs","names":[],"sources":["../../src/adapters/better-stack.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from './_config'\nimport { resolveAdapterConfig } from './_config'\nimport { defineDrain } from './_drain'\nimport { httpPost } from './_http'\n\nexport interface BetterStackConfig {\n /** Better Stack source token */\n sourceToken: string\n /** Logtail ingestion endpoint. Default: https://in.logs.betterstack.com */\n endpoint?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\nconst BETTER_STACK_FIELDS: ConfigField<BetterStackConfig>[] = [\n { key: 'sourceToken', env: ['NUXT_BETTER_STACK_SOURCE_TOKEN', 'BETTER_STACK_SOURCE_TOKEN'] },\n { key: 'endpoint', env: ['NUXT_BETTER_STACK_ENDPOINT', 'BETTER_STACK_ENDPOINT'] },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\n/**\n * Transform an evlog wide event into a Better Stack event.\n * Maps `timestamp` to `dt` (Better Stack's expected field).\n */\nexport function toBetterStackEvent(event: WideEvent): Record<string, unknown> {\n const { timestamp, ...rest } = event\n return { ...rest, dt: timestamp }\n}\n\n/**\n * Create a drain function for sending logs to Better Stack.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createBetterStackDrain()\n * 2. runtimeConfig.evlog.betterStack\n * 3. runtimeConfig.betterStack\n * 4. Environment variables: NUXT_BETTER_STACK_*, BETTER_STACK_*\n *\n * @example\n * ```ts\n * // Zero config - just set NUXT_BETTER_STACK_SOURCE_TOKEN env var\n * nitroApp.hooks.hook('evlog:drain', createBetterStackDrain())\n *\n * // With overrides\n * nitroApp.hooks.hook('evlog:drain', createBetterStackDrain({\n * sourceToken: 'my-token',\n * }))\n * ```\n */\nexport function createBetterStackDrain(overrides?: Partial<BetterStackConfig>) {\n return defineDrain<BetterStackConfig>({\n name: 'better-stack',\n resolve: async () => {\n const config = await resolveAdapterConfig<BetterStackConfig>('betterStack', BETTER_STACK_FIELDS, overrides)\n if (!config.sourceToken) {\n console.error('[evlog/better-stack] Missing source token. Set NUXT_BETTER_STACK_SOURCE_TOKEN env var or pass to createBetterStackDrain()')\n return null\n }\n return config as BetterStackConfig\n },\n send: sendBatchToBetterStack,\n })\n}\n\n/**\n * Send a single event to Better Stack.\n *\n * @example\n * ```ts\n * await sendToBetterStack(event, {\n * sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,\n * })\n * ```\n */\nexport async function sendToBetterStack(event: WideEvent, config: BetterStackConfig): Promise<void> {\n await sendBatchToBetterStack([event], config)\n}\n\n/**\n * Send a batch of events to Better Stack.\n *\n * @example\n * ```ts\n * await sendBatchToBetterStack(events, {\n * sourceToken: process.env.BETTER_STACK_SOURCE_TOKEN!,\n * })\n * ```\n */\nexport async function sendBatchToBetterStack(events: WideEvent[], config: BetterStackConfig): Promise<void> {\n const endpoint = (config.endpoint ?? 'https://in.logs.betterstack.com').replace(/\\/+$/, '')\n\n await httpPost({\n url: endpoint,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.sourceToken}`,\n },\n body: JSON.stringify(events.map(toBetterStackEvent)),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'Better Stack',\n })\n}\n"],"mappings":";;;AAiBA,MAAM,sBAAwD;CAC5D;EAAE,KAAK;EAAe,KAAK,CAAC,kCAAkC,4BAA4B;EAAE;CAC5F;EAAE,KAAK;EAAY,KAAK,CAAC,8BAA8B,wBAAwB;EAAE;CACjF,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;;;;;AAMD,SAAgB,mBAAmB,OAA2C;CAC5E,MAAM,EAAE,WAAW,GAAG,SAAS;AAC/B,QAAO;EAAE,GAAG;EAAM,IAAI;EAAW;;;;;;;;;;;;;;;;;;;;;;AAuBnC,SAAgB,uBAAuB,WAAwC;AAC7E,QAAO,YAA+B;EACpC,MAAM;EACN,SAAS,YAAY;GACnB,MAAM,SAAS,MAAM,qBAAwC,eAAe,qBAAqB,UAAU;AAC3G,OAAI,CAAC,OAAO,aAAa;AACvB,YAAQ,MAAM,4HAA4H;AAC1I,WAAO;;AAET,UAAO;;EAET,MAAM;EACP,CAAC;;;;;;;;;;;;AAaJ,eAAsB,kBAAkB,OAAkB,QAA0C;AAClG,OAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO;;;;;;;;;;;;AAa/C,eAAsB,uBAAuB,QAAqB,QAA0C;AAG1G,OAAM,SAAS;EACb,MAHgB,OAAO,YAAY,mCAAmC,QAAQ,QAAQ,GAAG;EAIzF,SAAS;GACP,gBAAgB;GAChB,iBAAiB,UAAU,OAAO;GACnC;EACD,MAAM,KAAK,UAAU,OAAO,IAAI,mBAAmB,CAAC;EACpD,SAAS,OAAO,WAAW;EAC3B,SAAS,OAAO;EAChB,OAAO;EACR,CAAC"}
1
+ {"version":3,"file":"better-stack.mjs","names":[],"sources":["../../src/adapters/better-stack.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineHttpDrain } from '../shared/drain'\nimport { httpPost } from '../shared/http'\n\nexport interface BetterStackConfig {\n /** Better Stack API key (replaces deprecated `sourceToken`). */\n apiKey: string\n /**\n * @deprecated Renamed to {@link BetterStackConfig.apiKey}. Will be removed\n * in the next major version. Pass `apiKey` instead.\n */\n sourceToken?: string\n /** Logtail ingestion endpoint. Default: https://in.logs.betterstack.com */\n endpoint?: string\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\nconst BETTER_STACK_FIELDS: ConfigField<BetterStackConfig>[] = [\n { key: 'apiKey', env: ['NUXT_BETTER_STACK_API_KEY', 'BETTER_STACK_API_KEY'] },\n // Deprecated env var names — resolved as a fallback for `apiKey` below.\n { key: 'sourceToken', env: ['NUXT_BETTER_STACK_SOURCE_TOKEN', 'BETTER_STACK_SOURCE_TOKEN'] },\n { key: 'endpoint', env: ['NUXT_BETTER_STACK_ENDPOINT', 'BETTER_STACK_ENDPOINT'] },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\nlet warnedAboutSourceToken = false\n\nfunction applyApiKeyAlias(config: BetterStackConfig): BetterStackConfig {\n if (!config.apiKey && config.sourceToken) {\n if (!warnedAboutSourceToken) {\n warnedAboutSourceToken = true\n console.warn('[evlog/better-stack] `sourceToken` is deprecated, use `apiKey` instead. (Env: NUXT_BETTER_STACK_SOURCE_TOKEN → NUXT_BETTER_STACK_API_KEY.)')\n }\n config.apiKey = config.sourceToken\n }\n return config\n}\n\n/**\n * Transform an evlog wide event into a Better Stack event.\n * Maps `timestamp` to `dt` (Better Stack's expected field).\n */\nexport function toBetterStackEvent(event: WideEvent): Record<string, unknown> {\n const { timestamp, ...rest } = event\n return { ...rest, dt: timestamp }\n}\n\n/**\n * Create a drain function for sending logs to Better Stack.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createBetterStackDrain()\n * 2. runtimeConfig.evlog.betterStack\n * 3. runtimeConfig.betterStack\n * 4. Environment variables: NUXT_BETTER_STACK_API_KEY, BETTER_STACK_API_KEY (or legacy `*_SOURCE_TOKEN`)\n *\n * @example\n * ```ts\n * initLogger({ drain: createBetterStackDrain() })\n *\n * initLogger({ drain: createBetterStackDrain({ apiKey: 'my-key' }) })\n * ```\n */\nexport function createBetterStackDrain(overrides?: Partial<BetterStackConfig>) {\n return defineHttpDrain<BetterStackConfig>({\n name: 'better-stack',\n resolve: async () => {\n const resolved = await resolveAdapterConfig<BetterStackConfig>('betterStack', BETTER_STACK_FIELDS, overrides)\n const config = applyApiKeyAlias(resolved as BetterStackConfig)\n if (!config.apiKey) {\n console.error('[evlog/better-stack] Missing apiKey. Set NUXT_BETTER_STACK_API_KEY env var or pass to createBetterStackDrain()')\n return null\n }\n return config\n },\n encode: (events, config) => ({\n url: (config.endpoint ?? 'https://in.logs.betterstack.com').replace(/\\/+$/, ''),\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(events.map(toBetterStackEvent)),\n }),\n })\n}\n\n/**\n * Send a single event to Better Stack.\n */\nexport async function sendToBetterStack(event: WideEvent, config: BetterStackConfig): Promise<void> {\n await sendBatchToBetterStack([event], config)\n}\n\n/**\n * Send a batch of events to Better Stack.\n */\nexport async function sendBatchToBetterStack(events: WideEvent[], config: BetterStackConfig): Promise<void> {\n const apiKey = config.apiKey ?? config.sourceToken\n if (!apiKey) throw new Error('[evlog/better-stack] Missing apiKey')\n const endpoint = (config.endpoint ?? 'https://in.logs.betterstack.com').replace(/\\/+$/, '')\n\n await httpPost({\n url: endpoint,\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${apiKey}`,\n },\n body: JSON.stringify(events.map(toBetterStackEvent)),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'Better Stack',\n })\n}\n"],"mappings":";;AAsBA,MAAM,sBAAwD;CAC5D;EAAE,KAAK;EAAU,KAAK,CAAC,6BAA6B,uBAAuB;EAAE;CAE7E;EAAE,KAAK;EAAe,KAAK,CAAC,kCAAkC,4BAA4B;EAAE;CAC5F;EAAE,KAAK;EAAY,KAAK,CAAC,8BAA8B,wBAAwB;EAAE;CACjF,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;AAED,IAAI,yBAAyB;AAE7B,SAAS,iBAAiB,QAA8C;AACtE,KAAI,CAAC,OAAO,UAAU,OAAO,aAAa;AACxC,MAAI,CAAC,wBAAwB;AAC3B,4BAAyB;AACzB,WAAQ,KAAK,6IAA6I;;AAE5J,SAAO,SAAS,OAAO;;AAEzB,QAAO;;;;;;AAOT,SAAgB,mBAAmB,OAA2C;CAC5E,MAAM,EAAE,WAAW,GAAG,SAAS;AAC/B,QAAO;EAAE,GAAG;EAAM,IAAI;EAAW;;;;;;;;;;;;;;;;;;AAmBnC,SAAgB,uBAAuB,WAAwC;AAC7E,QAAO,gBAAmC;EACxC,MAAM;EACN,SAAS,YAAY;GAEnB,MAAM,SAAS,iBAAiB,MADT,qBAAwC,eAAe,qBAAqB,UAAU,CAC/C;AAC9D,OAAI,CAAC,OAAO,QAAQ;AAClB,YAAQ,MAAM,iHAAiH;AAC/H,WAAO;;AAET,UAAO;;EAET,SAAS,QAAQ,YAAY;GAC3B,MAAM,OAAO,YAAY,mCAAmC,QAAQ,QAAQ,GAAG;GAC/E,SAAS;IACP,gBAAgB;IAChB,iBAAiB,UAAU,OAAO;IACnC;GACD,MAAM,KAAK,UAAU,OAAO,IAAI,mBAAmB,CAAC;GACrD;EACF,CAAC;;;;;AAMJ,eAAsB,kBAAkB,OAAkB,QAA0C;AAClG,OAAM,uBAAuB,CAAC,MAAM,EAAE,OAAO;;;;;AAM/C,eAAsB,uBAAuB,QAAqB,QAA0C;CAC1G,MAAM,SAAS,OAAO,UAAU,OAAO;AACvC,KAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,sCAAsC;AAGnE,OAAM,SAAS;EACb,MAHgB,OAAO,YAAY,mCAAmC,QAAQ,QAAQ,GAGzE;EACb,SAAS;GACP,gBAAgB;GAChB,iBAAiB,UAAU;GAC5B;EACD,MAAM,KAAK,UAAU,OAAO,IAAI,mBAAmB,CAAC;EACpD,SAAS,OAAO,WAAW;EAC3B,SAAS,OAAO;EAChB,OAAO;EACR,CAAC"}
@@ -1,4 +1,4 @@
1
- import { F as DrainContext, it as WideEvent } from "../audit-mUutdf6A.mjs";
1
+ import { F as DrainContext, it as WideEvent } from "../audit-CJl-wZ10.mjs";
2
2
  //#region src/adapters/datadog.d.ts
3
3
  interface DatadogConfig {
4
4
  /** Datadog API key with Logs intake permission */
@@ -1 +1 @@
1
- {"version":3,"file":"datadog.d.mts","names":[],"sources":["../../src/adapters/datadog.ts"],"mappings":";;UAMiB,aAAA;;EAEf,MAAA;EAFe;;;;EAOf,IAAA;EAAA;;;;EAKA,SAAA;EAIO;EAFP,OAAA;EAsByC;EApBzC,OAAA;AAAA;;;;;;AA2CF;;iBAvBgB,2BAAA,CAA4B,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAgD/D;;iBAzBgB,wBAAA,CAAyB,KAAA,EAAO,SAAA;;;AA2ChD;;;;;;iBAlBgB,uBAAA,CAAwB,KAAA,EAAO,SAAA;;;AAwC/C;;;;;;iBAtBgB,YAAA,CAAa,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAiDhD;iBA3BgB,uBAAA,CAAwB,MAAA,EAAQ,IAAA,CAAK,aAAA;;;;;;;;;;;;;;;;;;AA6CrD;;iBAlBgB,kBAAA,CAAmB,SAAA,GAAY,OAAA,CAAQ,aAAA,KAAc,GAAA,EAAf,YAAA,GAAe,YAAA,OAAA,OAAA;;;;iBAkB/C,aAAA,CAAc,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;iBAOxD,kBAAA,CAAmB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA"}
1
+ {"version":3,"file":"datadog.d.mts","names":[],"sources":["../../src/adapters/datadog.ts"],"mappings":";;UAMiB,aAAA;;EAEf,MAAA;EAFe;;;;EAOf,IAAA;EAAA;;;;EAKA,SAAA;EAIO;EAFP,OAAA;EAsByC;EApBzC,OAAA;AAAA;;;;;;AA2CF;;iBAvBgB,2BAAA,CAA4B,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAgD/D;;iBAzBgB,wBAAA,CAAyB,KAAA,EAAO,SAAA;;;AA2ChD;;;;;;iBAlBgB,uBAAA,CAAwB,KAAA,EAAO,SAAA;;;AAwC/C;;;;;;iBAtBgB,YAAA,CAAa,KAAA,EAAO,SAAA,GAAY,MAAA;;;AAiDhD;iBA3BgB,uBAAA,CAAwB,MAAA,EAAQ,IAAA,CAAK,aAAA;;;;;;;;;;;;;;;;;;AAoDrD;;iBAzBgB,kBAAA,CAAmB,SAAA,GAAY,OAAA,CAAQ,aAAA,KAAc,GAAA,EAAf,YAAA,GAAe,YAAA,OAAA,OAAA;;;;iBAyB/C,aAAA,CAAc,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;iBAOxD,kBAAA,CAAmB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA"}
@@ -1,5 +1,4 @@
1
- import { n as resolveAdapterConfig, t as httpPost } from "../_http-CHSsrWDJ.mjs";
2
- import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
1
+ import { a as resolveAdapterConfig, n as defineHttpDrain, r as httpPost } from "../drain-ByWUeOQC.mjs";
3
2
  //#region src/adapters/datadog.ts
4
3
  const DATADOG_FIELDS = [
5
4
  {
@@ -130,7 +129,7 @@ function resolveDatadogIntakeUrl(config) {
130
129
  * ```
131
130
  */
132
131
  function createDatadogDrain(overrides) {
133
- return defineDrain({
132
+ return defineHttpDrain({
134
133
  name: "datadog",
135
134
  resolve: async () => {
136
135
  const config = await resolveAdapterConfig("datadog", DATADOG_FIELDS, overrides);
@@ -140,7 +139,14 @@ function createDatadogDrain(overrides) {
140
139
  }
141
140
  return config;
142
141
  },
143
- send: sendBatchToDatadog
142
+ encode: (events, config) => ({
143
+ url: resolveDatadogIntakeUrl(config),
144
+ headers: {
145
+ "Content-Type": "application/json",
146
+ "DD-API-KEY": config.apiKey
147
+ },
148
+ body: JSON.stringify(events.map(toDatadogLog))
149
+ })
144
150
  });
145
151
  }
146
152
  /**