evlog 2.14.1 → 2.16.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 (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +4 -4
  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 +15 -1
  35. package/dist/ai/index.d.mts.map +1 -1
  36. package/dist/ai/index.mjs +48 -16
  37. package/dist/ai/index.mjs.map +1 -1
  38. package/dist/{audit-CTIviX3P.d.mts → audit-X1uUukm3.d.mts} +145 -2
  39. package/dist/audit-X1uUukm3.d.mts.map +1 -0
  40. package/dist/{audit-DQoBo7Dl.mjs → audit-pV5aLGP0.mjs} +153 -13
  41. package/dist/audit-pV5aLGP0.mjs.map +1 -0
  42. package/dist/better-auth/index.d.mts +1 -1
  43. package/dist/browser.d.mts +1 -1
  44. package/dist/define-CuXOqecD.d.mts +57 -0
  45. package/dist/define-CuXOqecD.d.mts.map +1 -0
  46. package/dist/define-D6OJdSUH.mjs +63 -0
  47. package/dist/define-D6OJdSUH.mjs.map +1 -0
  48. package/dist/{dist-Do8P4zWd.mjs → dist-BIlS38vi.mjs} +1 -1
  49. package/dist/dist-BIlS38vi.mjs.map +1 -0
  50. package/dist/drain-ByWUeOQC.mjs +160 -0
  51. package/dist/drain-ByWUeOQC.mjs.map +1 -0
  52. package/dist/elysia/index.d.mts +25 -2
  53. package/dist/elysia/index.d.mts.map +1 -1
  54. package/dist/elysia/index.mjs +53 -20
  55. package/dist/elysia/index.mjs.map +1 -1
  56. package/dist/enricher-DYTr9I16.d.mts +42 -0
  57. package/dist/enricher-DYTr9I16.d.mts.map +1 -0
  58. package/dist/enricher-Dy06T17G.mjs +95 -0
  59. package/dist/enricher-Dy06T17G.mjs.map +1 -0
  60. package/dist/enrichers.d.mts +16 -9
  61. package/dist/enrichers.d.mts.map +1 -1
  62. package/dist/enrichers.mjs +81 -64
  63. package/dist/enrichers.mjs.map +1 -1
  64. package/dist/{error-C7gSQVqk.d.mts → error-Cpc7RVz6.d.mts} +7 -2
  65. package/dist/error-Cpc7RVz6.d.mts.map +1 -0
  66. package/dist/error.d.mts +1 -1
  67. package/dist/error.mjs +8 -1
  68. package/dist/error.mjs.map +1 -1
  69. package/dist/{errors-BJRXUfMg.mjs → errors-BQgyQ9xe.mjs} +1 -1
  70. package/dist/{errors-BJRXUfMg.mjs.map → errors-BQgyQ9xe.mjs.map} +1 -1
  71. package/dist/{errors-4MPmTzjY.d.mts → errors-prnQ3kES.d.mts} +2 -2
  72. package/dist/{errors-4MPmTzjY.d.mts.map → errors-prnQ3kES.d.mts.map} +1 -1
  73. package/dist/event-DcHmEm3O.mjs +55 -0
  74. package/dist/event-DcHmEm3O.mjs.map +1 -0
  75. package/dist/express/index.d.mts +2 -2
  76. package/dist/express/index.d.mts.map +1 -1
  77. package/dist/express/index.mjs +17 -15
  78. package/dist/express/index.mjs.map +1 -1
  79. package/dist/fastify/index.d.mts +2 -2
  80. package/dist/fastify/index.d.mts.map +1 -1
  81. package/dist/fastify/index.mjs +19 -20
  82. package/dist/fastify/index.mjs.map +1 -1
  83. package/dist/fork-DPN8aL8O.mjs +227 -0
  84. package/dist/fork-DPN8aL8O.mjs.map +1 -0
  85. package/dist/{headers-D74M0wsg.mjs → headers-CU-QqnYg.mjs} +19 -2
  86. package/dist/headers-CU-QqnYg.mjs.map +1 -0
  87. package/dist/hono/index.d.mts +2 -2
  88. package/dist/hono/index.d.mts.map +1 -1
  89. package/dist/hono/index.mjs +14 -10
  90. package/dist/hono/index.mjs.map +1 -1
  91. package/dist/http.d.mts +1 -1
  92. package/dist/index.d.mts +8 -7
  93. package/dist/index.mjs +3 -2
  94. package/dist/integration-DSZPbI9N.mjs +75 -0
  95. package/dist/integration-DSZPbI9N.mjs.map +1 -0
  96. package/dist/{logger-DttRJRGa.d.mts → logger-U8lgdc9x.d.mts} +9 -3
  97. package/dist/logger-U8lgdc9x.d.mts.map +1 -0
  98. package/dist/logger.d.mts +2 -2
  99. package/dist/logger.mjs +2 -2
  100. package/dist/middleware-CAQHJRN1.d.mts +72 -0
  101. package/dist/middleware-CAQHJRN1.d.mts.map +1 -0
  102. package/dist/nestjs/index.d.mts +2 -2
  103. package/dist/nestjs/index.mjs +3 -4
  104. package/dist/nestjs/index.mjs.map +1 -1
  105. package/dist/next/client.d.mts +1 -1
  106. package/dist/next/index.d.mts +4 -4
  107. package/dist/next/index.mjs +3 -3
  108. package/dist/next/instrumentation.d.mts +1 -1
  109. package/dist/next/instrumentation.mjs +1 -1
  110. package/dist/nitro/errorHandler.mjs +2 -2
  111. package/dist/nitro/module.d.mts +2 -2
  112. package/dist/nitro/plugin.mjs +21 -11
  113. package/dist/nitro/plugin.mjs.map +1 -1
  114. package/dist/nitro/v3/errorHandler.mjs +3 -3
  115. package/dist/nitro/v3/index.d.mts +2 -2
  116. package/dist/nitro/v3/module.d.mts +1 -1
  117. package/dist/nitro/v3/plugin.mjs +29 -17
  118. package/dist/nitro/v3/plugin.mjs.map +1 -1
  119. package/dist/nitro/v3/useLogger.d.mts +1 -1
  120. package/dist/{nitro-CPPRCPbG.d.mts → nitro-C6Bd682U.d.mts} +2 -2
  121. package/dist/{nitro-CPPRCPbG.d.mts.map → nitro-C6Bd682U.d.mts.map} +1 -1
  122. package/dist/{nitro-OmT_M4Pb.mjs → nitro-DavLelNz.mjs} +2 -2
  123. package/dist/nitro-DavLelNz.mjs.map +1 -0
  124. package/dist/{nitroConfigBridge-C37lXaNm.mjs → nitroConfigBridge-aZ1e5upQ.mjs} +1 -1
  125. package/dist/nitroConfigBridge-aZ1e5upQ.mjs.map +1 -0
  126. package/dist/nuxt/module.d.mts +1 -1
  127. package/dist/nuxt/module.mjs +2 -2
  128. package/dist/{parseError-o1GpZEOR.d.mts → parseError-B-dKF6Fd.d.mts} +2 -2
  129. package/dist/parseError-B-dKF6Fd.d.mts.map +1 -0
  130. package/dist/react-router/index.d.mts +2 -2
  131. package/dist/react-router/index.mjs +3 -4
  132. package/dist/react-router/index.mjs.map +1 -1
  133. package/dist/{routes-CGPmbzCZ.mjs → routes-B48wm7Pb.mjs} +1 -1
  134. package/dist/{routes-CGPmbzCZ.mjs.map → routes-B48wm7Pb.mjs.map} +1 -1
  135. package/dist/runtime/client/log.d.mts +1 -1
  136. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +21 -10
  137. package/dist/runtime/server/routes/_evlog/ingest.post.mjs.map +1 -1
  138. package/dist/runtime/server/useLogger.d.mts +1 -1
  139. package/dist/runtime/utils/parseError.d.mts +2 -2
  140. package/dist/runtime/utils/parseError.mjs +9 -1
  141. package/dist/runtime/utils/parseError.mjs.map +1 -1
  142. package/dist/{_severity-CQijvfhU.mjs → severity-BYWZ96Sb.mjs} +6 -2
  143. package/dist/severity-BYWZ96Sb.mjs.map +1 -0
  144. package/dist/{source-location-DRvDDqfq.mjs → source-location-Dco0cRTz.mjs} +3 -3
  145. package/dist/source-location-Dco0cRTz.mjs.map +1 -0
  146. package/dist/storage-BT-3fT1-.mjs +27 -0
  147. package/dist/storage-BT-3fT1-.mjs.map +1 -0
  148. package/dist/sveltekit/index.d.mts +2 -2
  149. package/dist/sveltekit/index.mjs +5 -6
  150. package/dist/sveltekit/index.mjs.map +1 -1
  151. package/dist/toolkit.d.mts +288 -12
  152. package/dist/toolkit.d.mts.map +1 -1
  153. package/dist/toolkit.mjs +13 -7
  154. package/dist/types.d.mts +1 -1
  155. package/dist/{useLogger-CyPP1sVB.d.mts → useLogger-CoNgTjp5.d.mts} +2 -2
  156. package/dist/{useLogger-CyPP1sVB.d.mts.map → useLogger-CoNgTjp5.d.mts.map} +1 -1
  157. package/dist/{utils-Dmin7wVL.d.mts → utils-Db4qhBWn.d.mts} +2 -2
  158. package/dist/{utils-Dmin7wVL.d.mts.map → utils-Db4qhBWn.d.mts.map} +1 -1
  159. package/dist/utils.d.mts +1 -1
  160. package/dist/vite/index.d.mts +1 -1
  161. package/dist/vite/index.mjs +1 -1
  162. package/dist/workers.d.mts +1 -1
  163. package/dist/workers.mjs +1 -1
  164. package/package.json +22 -19
  165. package/dist/_drain-CmCtsuF6.mjs +0 -23
  166. package/dist/_drain-CmCtsuF6.mjs.map +0 -1
  167. package/dist/_http-BY1e9pwC.mjs +0 -78
  168. package/dist/_http-BY1e9pwC.mjs.map +0 -1
  169. package/dist/_severity-CQijvfhU.mjs.map +0 -1
  170. package/dist/audit-CTIviX3P.d.mts.map +0 -1
  171. package/dist/audit-DQoBo7Dl.mjs.map +0 -1
  172. package/dist/dist-Do8P4zWd.mjs.map +0 -1
  173. package/dist/error-C7gSQVqk.d.mts.map +0 -1
  174. package/dist/fork-D1j1Fuzy.mjs +0 -72
  175. package/dist/fork-D1j1Fuzy.mjs.map +0 -1
  176. package/dist/headers-D74M0wsg.mjs.map +0 -1
  177. package/dist/logger-DttRJRGa.d.mts.map +0 -1
  178. package/dist/middleware-CTnDsST-.d.mts +0 -93
  179. package/dist/middleware-CTnDsST-.d.mts.map +0 -1
  180. package/dist/middleware-oAccqyPp.mjs +0 -123
  181. package/dist/middleware-oAccqyPp.mjs.map +0 -1
  182. package/dist/nitro-OmT_M4Pb.mjs.map +0 -1
  183. package/dist/nitroConfigBridge-C37lXaNm.mjs.map +0 -1
  184. package/dist/parseError-o1GpZEOR.d.mts.map +0 -1
  185. package/dist/source-location-DRvDDqfq.mjs.map +0 -1
  186. package/dist/storage-CFGTn37X.mjs +0 -46
  187. package/dist/storage-CFGTn37X.mjs.map +0 -1
@@ -1,7 +1,16 @@
1
- import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
1
+ import { a as resolveAdapterConfig, t as defineDrain } from "../drain-ByWUeOQC.mjs";
2
2
  import { join, sep } from "node:path";
3
3
  import { appendFile, mkdir, readdir, stat, unlink, writeFile } from "node:fs/promises";
4
4
  //#region src/adapters/fs.ts
5
+ const FS_FIELDS = [
6
+ {
7
+ key: "dir",
8
+ env: ["NUXT_EVLOG_FS_DIR", "EVLOG_FS_DIR"]
9
+ },
10
+ { key: "maxFiles" },
11
+ { key: "maxSizePerFile" },
12
+ { key: "pretty" }
13
+ ];
5
14
  const gitignoreWritten = /* @__PURE__ */ new Set();
6
15
  async function ensureGitignore(dir) {
7
16
  const segments = dir.replace(/[\\/]/g, sep).split(sep);
@@ -91,12 +100,15 @@ async function writeBatchToFs(events, config) {
91
100
  function createFsDrain(overrides) {
92
101
  return defineDrain({
93
102
  name: "fs",
94
- resolve: () => ({
95
- dir: overrides?.dir ?? ".evlog/logs",
96
- pretty: overrides?.pretty ?? false,
97
- maxFiles: overrides?.maxFiles,
98
- maxSizePerFile: overrides?.maxSizePerFile
99
- }),
103
+ resolve: async () => {
104
+ const resolved = await resolveAdapterConfig("fs", FS_FIELDS, overrides);
105
+ return {
106
+ dir: resolved.dir ?? ".evlog/logs",
107
+ pretty: resolved.pretty ?? false,
108
+ maxFiles: resolved.maxFiles,
109
+ maxSizePerFile: resolved.maxSizePerFile
110
+ };
111
+ },
100
112
  send: writeBatchToFs
101
113
  });
102
114
  }
@@ -1 +1 @@
1
- {"version":3,"file":"fs.mjs","names":[],"sources":["../../src/adapters/fs.ts"],"sourcesContent":["import { appendFile, mkdir, readdir, stat, unlink, writeFile } from 'node:fs/promises'\nimport { join, sep } from 'node:path'\nimport type { WideEvent } from '../types'\nimport { defineDrain } from './_drain'\n\nexport interface FsConfig {\n /** Directory for log files */\n dir: string\n /** Max number of log files to keep (auto-deletes oldest when exceeded) */\n maxFiles?: number\n /** Max bytes per file before rotating to a new suffixed file */\n maxSizePerFile?: number\n /** Pretty-print JSON instead of compact NDJSON */\n pretty: boolean\n}\n\nconst gitignoreWritten = new Set<string>()\n\nasync function ensureGitignore(dir: string): Promise<void> {\n const normalized = dir.replace(/[\\\\/]/g, sep)\n const segments = normalized.split(sep)\n const evlogIndex = segments.findIndex(s => s === '.evlog')\n const targetDir = evlogIndex !== -1 ? segments.slice(0, evlogIndex + 1).join(sep) : dir\n\n if (gitignoreWritten.has(targetDir)) return\n\n const gitignorePath = join(targetDir, '.gitignore')\n try {\n await stat(gitignorePath)\n } catch {\n await writeFile(gitignorePath, '*\\n', 'utf-8')\n }\n gitignoreWritten.add(targetDir)\n}\n\nfunction getDateString(): string {\n return new Date().toISOString().slice(0, 10)\n}\n\nasync function resolveFilePath(dir: string, maxSizePerFile?: number): Promise<string> {\n const date = getDateString()\n const basePath = join(dir, `${date}.jsonl`)\n\n if (!maxSizePerFile) return basePath\n\n try {\n const stats = await stat(basePath)\n if (stats.size < maxSizePerFile) return basePath\n } catch {\n return basePath\n }\n\n for (let i = 1; i < 1000; i++) {\n const rotatedPath = join(dir, `${date}.${i}.jsonl`)\n try {\n const stats = await stat(rotatedPath)\n if (stats.size < maxSizePerFile) return rotatedPath\n } catch {\n return rotatedPath\n }\n }\n\n return join(dir, `${date}.999.jsonl`)\n}\n\nfunction parseLogFilename(filename: string): { date: string; index: number } {\n const match = filename.match(/^(\\d{4}-\\d{2}-\\d{2})(?:\\.(\\d+))?\\.jsonl$/)\n if (!match) return { date: '', index: 0 }\n return { date: match[1], index: match[2] ? Number.parseInt(match[2], 10) : 0 }\n}\n\nasync function cleanupOldFiles(dir: string, maxFiles: number): Promise<void> {\n const files = await readdir(dir)\n const jsonlFiles = files.filter(f => f.endsWith('.jsonl')).sort((a, b) => {\n const pa = parseLogFilename(a)\n const pb = parseLogFilename(b)\n return pa.date.localeCompare(pb.date) || pa.index - pb.index\n })\n\n if (jsonlFiles.length <= maxFiles) return\n\n const toDelete = jsonlFiles.slice(0, jsonlFiles.length - maxFiles)\n await Promise.allSettled(toDelete.map(f => unlink(join(dir, f))))\n}\n\nexport async function writeToFs(event: WideEvent, config: FsConfig): Promise<void> {\n await writeBatchToFs([event], config)\n}\n\nexport async function writeBatchToFs(events: WideEvent[], config: FsConfig): Promise<void> {\n if (events.length === 0) return\n\n await mkdir(config.dir, { recursive: true })\n await ensureGitignore(config.dir)\n\n const filePath = await resolveFilePath(config.dir, config.maxSizePerFile)\n const lines = `${events\n .map(e => config.pretty ? JSON.stringify(e, null, 2) : JSON.stringify(e))\n .join('\\n') }\\n`\n\n await appendFile(filePath, lines, 'utf-8')\n\n if (config.maxFiles) {\n await cleanupOldFiles(config.dir, config.maxFiles)\n }\n}\n\n/**\n * Create a drain function that writes logs to the local file system as NDJSON.\n *\n * Files are organized by date (`2026-03-14.jsonl`) with optional size-based\n * rotation and automatic cleanup of old files.\n *\n * @example\n * ```ts\n * // Default: writes to .evlog/logs/\n * nitroApp.hooks.hook('evlog:drain', createFsDrain())\n *\n * // With options\n * nitroApp.hooks.hook('evlog:drain', createFsDrain({\n * dir: '.evlog/logs',\n * maxFiles: 7,\n * pretty: true,\n * }))\n * ```\n */\nexport function createFsDrain(overrides?: Partial<FsConfig>) {\n return defineDrain<FsConfig>({\n name: 'fs',\n resolve: () => ({\n dir: overrides?.dir ?? '.evlog/logs',\n pretty: overrides?.pretty ?? false,\n maxFiles: overrides?.maxFiles,\n maxSizePerFile: overrides?.maxSizePerFile,\n }),\n send: writeBatchToFs,\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"fs.mjs","names":[],"sources":["../../src/adapters/fs.ts"],"sourcesContent":["import { appendFile, mkdir, readdir, stat, unlink, writeFile } from 'node:fs/promises'\nimport { join, sep } from 'node:path'\nimport type { WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineDrain } from '../shared/drain'\n\nexport interface FsConfig {\n /** Directory for log files. Default: `.evlog/logs` */\n dir: string\n /** Max number of log files to keep (auto-deletes oldest when exceeded) */\n maxFiles?: number\n /** Max bytes per file before rotating to a new suffixed file */\n maxSizePerFile?: number\n /** Pretty-print JSON instead of compact NDJSON */\n pretty: boolean\n}\n\nconst FS_FIELDS: ConfigField<FsConfig>[] = [\n { key: 'dir', env: ['NUXT_EVLOG_FS_DIR', 'EVLOG_FS_DIR'] },\n { key: 'maxFiles' },\n { key: 'maxSizePerFile' },\n { key: 'pretty' },\n]\n\nconst gitignoreWritten = new Set<string>()\n\nasync function ensureGitignore(dir: string): Promise<void> {\n const normalized = dir.replace(/[\\\\/]/g, sep)\n const segments = normalized.split(sep)\n const evlogIndex = segments.findIndex(s => s === '.evlog')\n const targetDir = evlogIndex !== -1 ? segments.slice(0, evlogIndex + 1).join(sep) : dir\n\n if (gitignoreWritten.has(targetDir)) return\n\n const gitignorePath = join(targetDir, '.gitignore')\n try {\n await stat(gitignorePath)\n } catch {\n await writeFile(gitignorePath, '*\\n', 'utf-8')\n }\n gitignoreWritten.add(targetDir)\n}\n\nfunction getDateString(): string {\n return new Date().toISOString().slice(0, 10)\n}\n\nasync function resolveFilePath(dir: string, maxSizePerFile?: number): Promise<string> {\n const date = getDateString()\n const basePath = join(dir, `${date}.jsonl`)\n\n if (!maxSizePerFile) return basePath\n\n try {\n const stats = await stat(basePath)\n if (stats.size < maxSizePerFile) return basePath\n } catch {\n return basePath\n }\n\n for (let i = 1; i < 1000; i++) {\n const rotatedPath = join(dir, `${date}.${i}.jsonl`)\n try {\n const stats = await stat(rotatedPath)\n if (stats.size < maxSizePerFile) return rotatedPath\n } catch {\n return rotatedPath\n }\n }\n\n return join(dir, `${date}.999.jsonl`)\n}\n\nfunction parseLogFilename(filename: string): { date: string; index: number } {\n const match = filename.match(/^(\\d{4}-\\d{2}-\\d{2})(?:\\.(\\d+))?\\.jsonl$/)\n if (!match) return { date: '', index: 0 }\n return { date: match[1], index: match[2] ? Number.parseInt(match[2], 10) : 0 }\n}\n\nasync function cleanupOldFiles(dir: string, maxFiles: number): Promise<void> {\n const files = await readdir(dir)\n const jsonlFiles = files.filter(f => f.endsWith('.jsonl')).sort((a, b) => {\n const pa = parseLogFilename(a)\n const pb = parseLogFilename(b)\n return pa.date.localeCompare(pb.date) || pa.index - pb.index\n })\n\n if (jsonlFiles.length <= maxFiles) return\n\n const toDelete = jsonlFiles.slice(0, jsonlFiles.length - maxFiles)\n await Promise.allSettled(toDelete.map(f => unlink(join(dir, f))))\n}\n\nexport async function writeToFs(event: WideEvent, config: FsConfig): Promise<void> {\n await writeBatchToFs([event], config)\n}\n\nexport async function writeBatchToFs(events: WideEvent[], config: FsConfig): Promise<void> {\n if (events.length === 0) return\n\n await mkdir(config.dir, { recursive: true })\n await ensureGitignore(config.dir)\n\n const filePath = await resolveFilePath(config.dir, config.maxSizePerFile)\n const lines = `${events\n .map(e => config.pretty ? JSON.stringify(e, null, 2) : JSON.stringify(e))\n .join('\\n') }\\n`\n\n await appendFile(filePath, lines, 'utf-8')\n\n if (config.maxFiles) {\n await cleanupOldFiles(config.dir, config.maxFiles)\n }\n}\n\n/**\n * Create a drain function that writes logs to the local file system as NDJSON.\n *\n * Files are organized by date (`2026-03-14.jsonl`) with optional size-based\n * rotation and automatic cleanup of old files.\n *\n * @example\n * ```ts\n * // Default: writes to .evlog/logs/\n * nitroApp.hooks.hook('evlog:drain', createFsDrain())\n *\n * // With options\n * nitroApp.hooks.hook('evlog:drain', createFsDrain({\n * dir: '.evlog/logs',\n * maxFiles: 7,\n * pretty: true,\n * }))\n * ```\n */\nexport function createFsDrain(overrides?: Partial<FsConfig>) {\n return defineDrain<FsConfig>({\n name: 'fs',\n resolve: async () => {\n const resolved = await resolveAdapterConfig<FsConfig>('fs', FS_FIELDS, overrides)\n return {\n dir: resolved.dir ?? '.evlog/logs',\n pretty: resolved.pretty ?? false,\n maxFiles: resolved.maxFiles,\n maxSizePerFile: resolved.maxSizePerFile,\n }\n },\n send: writeBatchToFs,\n })\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { F as DrainContext, it as WideEvent } from "../audit-CTIviX3P.mjs";
1
+ import { F as DrainContext, it as WideEvent } from "../audit-X1uUukm3.mjs";
2
2
  import { OTLPConfig } from "./otlp.mjs";
3
3
 
4
4
  //#region src/adapters/hyperdx.d.ts
@@ -1,5 +1,4 @@
1
- import { n as resolveAdapterConfig } from "../_http-BY1e9pwC.mjs";
2
- import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
1
+ import { a as resolveAdapterConfig, t as defineDrain } from "../drain-ByWUeOQC.mjs";
3
2
  import { sendBatchToOTLP } from "./otlp.mjs";
4
3
  //#region src/adapters/hyperdx.ts
5
4
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"hyperdx.mjs","names":[],"sources":["../../src/adapters/hyperdx.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from './_config'\nimport { resolveAdapterConfig } from './_config'\nimport { defineDrain } from './_drain'\nimport type { OTLPConfig } from './otlp'\nimport { sendBatchToOTLP } from './otlp'\n\n/**\n * HyperDX cloud OTLP HTTP base URL.\n * @see https://hyperdx.io/docs/install/opentelemetry — “Our OpenTelemetry HTTP endpoint is hosted at `https://in-otel.hyperdx.io` …”\n */\nexport const HYPERDX_DEFAULT_OTLP_HTTP_ENDPOINT = 'https://in-otel.hyperdx.io'\n\nexport interface HyperDXConfig {\n /**\n * Ingestion API key. Sent as the `authorization` header value, matching HyperDX’s OpenTelemetry docs:\n * `authorization: <YOUR_HYPERDX_API_KEY_HERE>`\n * @see https://hyperdx.io/docs/install/opentelemetry\n */\n apiKey: string\n /**\n * OTLP HTTP base URL (evlog appends `/v1/logs`). Defaults to {@link HYPERDX_DEFAULT_OTLP_HTTP_ENDPOINT}.\n * Self-hosted: set to your OTLP HTTP endpoint (same shape as `otlphttp` `endpoint` in HyperDX’s collector example).\n */\n endpoint?: string\n /** Passed through to the OTLP encoder; maps to `service.name`. */\n serviceName?: string\n /** Additional OTLP resource attributes. */\n resourceAttributes?: Record<string, string | number | boolean>\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 HYPERDX_FIELDS: ConfigField<HyperDXConfig>[] = [\n { key: 'apiKey', env: ['NUXT_HYPERDX_API_KEY', 'HYPERDX_API_KEY'] },\n { key: 'endpoint', env: ['NUXT_HYPERDX_OTLP_ENDPOINT', 'HYPERDX_OTLP_ENDPOINT'] },\n { key: 'serviceName', env: ['NUXT_HYPERDX_SERVICE_NAME', 'HYPERDX_SERVICE_NAME', 'NUXT_OTLP_SERVICE_NAME', 'OTEL_SERVICE_NAME'] },\n { key: 'resourceAttributes' },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\n/**\n * Map HyperDX config to {@link OTLPConfig}: same wire format as HyperDX’s documented `otlphttp` exporter\n * (`endpoint` + `authorization` header).\n */\nexport function toHyperDXOTLPConfig(config: HyperDXConfig): OTLPConfig {\n return {\n endpoint: config.endpoint ?? HYPERDX_DEFAULT_OTLP_HTTP_ENDPOINT,\n headers: {\n // HyperDX docs (OpenTelemetry): headers.authorization = API key\n authorization: config.apiKey,\n },\n serviceName: config.serviceName,\n resourceAttributes: config.resourceAttributes,\n timeout: config.timeout,\n retries: config.retries,\n }\n}\n\n/**\n * Create a drain that sends wide events to HyperDX via OTLP/HTTP.\n *\n * Matches [HyperDX OpenTelemetry ingest](https://hyperdx.io/docs/install/opentelemetry):\n * HTTP base URL defaults to `https://in-otel.hyperdx.io`; requests use the `authorization` header set to your API key.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to `createHyperDXDrain()`\n * 2. `runtimeConfig.evlog.hyperdx`\n * 3. `runtimeConfig.hyperdx`\n * 4. Environment variables: `NUXT_HYPERDX_*`, `HYPERDX_*` (and `OTEL_SERVICE_NAME` for service name)\n *\n * @example\n * ```ts\n * nitroApp.hooks.hook('evlog:drain', createHyperDXDrain())\n * // HYPERDX_API_KEY in env\n * ```\n */\nexport function createHyperDXDrain(overrides?: Partial<HyperDXConfig>) {\n return defineDrain<HyperDXConfig>({\n name: 'hyperdx',\n resolve: async () => {\n const config = await resolveAdapterConfig<HyperDXConfig>('hyperdx', HYPERDX_FIELDS, overrides)\n if (!config.apiKey) {\n console.error('[evlog/hyperdx] Missing apiKey. Set HYPERDX_API_KEY or NUXT_HYPERDX_API_KEY, or pass to createHyperDXDrain()')\n return null\n }\n return config as HyperDXConfig\n },\n send: (events, config) => sendBatchToOTLP(events, toHyperDXOTLPConfig(config)),\n })\n}\n\n/**\n * Send a single wide event to HyperDX (OTLP/HTTP).\n */\nexport async function sendToHyperDX(event: WideEvent, config: HyperDXConfig): Promise<void> {\n await sendBatchToHyperDX([event], config)\n}\n\n/**\n * Send a batch of wide events to HyperDX (OTLP/HTTP).\n */\nexport async function sendBatchToHyperDX(events: WideEvent[], config: HyperDXConfig): Promise<void> {\n await sendBatchToOTLP(events, toHyperDXOTLPConfig(config))\n}\n"],"mappings":";;;;;;;;AAWA,MAAa,qCAAqC;AAwBlD,MAAM,iBAA+C;CACnD;EAAE,KAAK;EAAU,KAAK,CAAC,wBAAwB,kBAAkB;EAAE;CACnE;EAAE,KAAK;EAAY,KAAK,CAAC,8BAA8B,wBAAwB;EAAE;CACjF;EAAE,KAAK;EAAe,KAAK;GAAC;GAA6B;GAAwB;GAA0B;GAAoB;EAAE;CACjI,EAAE,KAAK,sBAAsB;CAC7B,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;;;;;AAMD,SAAgB,oBAAoB,QAAmC;AACrE,QAAO;EACL,UAAU,OAAO,YAAA;EACjB,SAAS,EAEP,eAAe,OAAO,QACvB;EACD,aAAa,OAAO;EACpB,oBAAoB,OAAO;EAC3B,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB;;;;;;;;;;;;;;;;;;;;AAqBH,SAAgB,mBAAmB,WAAoC;AACrE,QAAO,YAA2B;EAChC,MAAM;EACN,SAAS,YAAY;GACnB,MAAM,SAAS,MAAM,qBAAoC,WAAW,gBAAgB,UAAU;AAC9F,OAAI,CAAC,OAAO,QAAQ;AAClB,YAAQ,MAAM,+GAA+G;AAC7H,WAAO;;AAET,UAAO;;EAET,OAAO,QAAQ,WAAW,gBAAgB,QAAQ,oBAAoB,OAAO,CAAC;EAC/E,CAAC;;;;;AAMJ,eAAsB,cAAc,OAAkB,QAAsC;AAC1F,OAAM,mBAAmB,CAAC,MAAM,EAAE,OAAO;;;;;AAM3C,eAAsB,mBAAmB,QAAqB,QAAsC;AAClG,OAAM,gBAAgB,QAAQ,oBAAoB,OAAO,CAAC"}
1
+ {"version":3,"file":"hyperdx.mjs","names":[],"sources":["../../src/adapters/hyperdx.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineDrain } from '../shared/drain'\nimport type { OTLPConfig } from './otlp'\nimport { sendBatchToOTLP } from './otlp'\n\n/**\n * HyperDX cloud OTLP HTTP base URL.\n * @see https://hyperdx.io/docs/install/opentelemetry — “Our OpenTelemetry HTTP endpoint is hosted at `https://in-otel.hyperdx.io` …”\n */\nexport const HYPERDX_DEFAULT_OTLP_HTTP_ENDPOINT = 'https://in-otel.hyperdx.io'\n\nexport interface HyperDXConfig {\n /**\n * Ingestion API key. Sent as the `authorization` header value, matching HyperDX’s OpenTelemetry docs:\n * `authorization: <YOUR_HYPERDX_API_KEY_HERE>`\n * @see https://hyperdx.io/docs/install/opentelemetry\n */\n apiKey: string\n /**\n * OTLP HTTP base URL (evlog appends `/v1/logs`). Defaults to {@link HYPERDX_DEFAULT_OTLP_HTTP_ENDPOINT}.\n * Self-hosted: set to your OTLP HTTP endpoint (same shape as `otlphttp` `endpoint` in HyperDX’s collector example).\n */\n endpoint?: string\n /** Passed through to the OTLP encoder; maps to `service.name`. */\n serviceName?: string\n /** Additional OTLP resource attributes. */\n resourceAttributes?: Record<string, string | number | boolean>\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 HYPERDX_FIELDS: ConfigField<HyperDXConfig>[] = [\n { key: 'apiKey', env: ['NUXT_HYPERDX_API_KEY', 'HYPERDX_API_KEY'] },\n { key: 'endpoint', env: ['NUXT_HYPERDX_OTLP_ENDPOINT', 'HYPERDX_OTLP_ENDPOINT'] },\n { key: 'serviceName', env: ['NUXT_HYPERDX_SERVICE_NAME', 'HYPERDX_SERVICE_NAME', 'NUXT_OTLP_SERVICE_NAME', 'OTEL_SERVICE_NAME'] },\n { key: 'resourceAttributes' },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\n/**\n * Map HyperDX config to {@link OTLPConfig}: same wire format as HyperDX’s documented `otlphttp` exporter\n * (`endpoint` + `authorization` header).\n */\nexport function toHyperDXOTLPConfig(config: HyperDXConfig): OTLPConfig {\n return {\n endpoint: config.endpoint ?? HYPERDX_DEFAULT_OTLP_HTTP_ENDPOINT,\n headers: {\n // HyperDX docs (OpenTelemetry): headers.authorization = API key\n authorization: config.apiKey,\n },\n serviceName: config.serviceName,\n resourceAttributes: config.resourceAttributes,\n timeout: config.timeout,\n retries: config.retries,\n }\n}\n\n/**\n * Create a drain that sends wide events to HyperDX via OTLP/HTTP.\n *\n * Matches [HyperDX OpenTelemetry ingest](https://hyperdx.io/docs/install/opentelemetry):\n * HTTP base URL defaults to `https://in-otel.hyperdx.io`; requests use the `authorization` header set to your API key.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to `createHyperDXDrain()`\n * 2. `runtimeConfig.evlog.hyperdx`\n * 3. `runtimeConfig.hyperdx`\n * 4. Environment variables: `NUXT_HYPERDX_*`, `HYPERDX_*` (and `OTEL_SERVICE_NAME` for service name)\n *\n * @example\n * ```ts\n * nitroApp.hooks.hook('evlog:drain', createHyperDXDrain())\n * // HYPERDX_API_KEY in env\n * ```\n */\nexport function createHyperDXDrain(overrides?: Partial<HyperDXConfig>) {\n return defineDrain<HyperDXConfig>({\n name: 'hyperdx',\n resolve: async () => {\n const config = await resolveAdapterConfig<HyperDXConfig>('hyperdx', HYPERDX_FIELDS, overrides)\n if (!config.apiKey) {\n console.error('[evlog/hyperdx] Missing apiKey. Set HYPERDX_API_KEY or NUXT_HYPERDX_API_KEY, or pass to createHyperDXDrain()')\n return null\n }\n return config as HyperDXConfig\n },\n send: (events, config) => sendBatchToOTLP(events, toHyperDXOTLPConfig(config)),\n })\n}\n\n/**\n * Send a single wide event to HyperDX (OTLP/HTTP).\n */\nexport async function sendToHyperDX(event: WideEvent, config: HyperDXConfig): Promise<void> {\n await sendBatchToHyperDX([event], config)\n}\n\n/**\n * Send a batch of wide events to HyperDX (OTLP/HTTP).\n */\nexport async function sendBatchToHyperDX(events: WideEvent[], config: HyperDXConfig): Promise<void> {\n await sendBatchToOTLP(events, toHyperDXOTLPConfig(config))\n}\n"],"mappings":";;;;;;;AAWA,MAAa,qCAAqC;AAwBlD,MAAM,iBAA+C;CACnD;EAAE,KAAK;EAAU,KAAK,CAAC,wBAAwB,kBAAkB;EAAE;CACnE;EAAE,KAAK;EAAY,KAAK,CAAC,8BAA8B,wBAAwB;EAAE;CACjF;EAAE,KAAK;EAAe,KAAK;GAAC;GAA6B;GAAwB;GAA0B;GAAoB;EAAE;CACjI,EAAE,KAAK,sBAAsB;CAC7B,EAAE,KAAK,WAAW;CAClB,EAAE,KAAK,WAAW;CACnB;;;;;AAMD,SAAgB,oBAAoB,QAAmC;AACrE,QAAO;EACL,UAAU,OAAO,YAAA;EACjB,SAAS,EAEP,eAAe,OAAO,QACvB;EACD,aAAa,OAAO;EACpB,oBAAoB,OAAO;EAC3B,SAAS,OAAO;EAChB,SAAS,OAAO;EACjB;;;;;;;;;;;;;;;;;;;;AAqBH,SAAgB,mBAAmB,WAAoC;AACrE,QAAO,YAA2B;EAChC,MAAM;EACN,SAAS,YAAY;GACnB,MAAM,SAAS,MAAM,qBAAoC,WAAW,gBAAgB,UAAU;AAC9F,OAAI,CAAC,OAAO,QAAQ;AAClB,YAAQ,MAAM,+GAA+G;AAC7H,WAAO;;AAET,UAAO;;EAET,OAAO,QAAQ,WAAW,gBAAgB,QAAQ,oBAAoB,OAAO,CAAC;EAC/E,CAAC;;;;;AAMJ,eAAsB,cAAc,OAAkB,QAAsC;AAC1F,OAAM,mBAAmB,CAAC,MAAM,EAAE,OAAO;;;;;AAM3C,eAAsB,mBAAmB,QAAqB,QAAsC;AAClG,OAAM,gBAAgB,QAAQ,oBAAoB,OAAO,CAAC"}
@@ -1,4 +1,4 @@
1
- import { F as DrainContext, it as WideEvent } from "../audit-CTIviX3P.mjs";
1
+ import { F as DrainContext, it as WideEvent } from "../audit-X1uUukm3.mjs";
2
2
  //#region src/adapters/otlp.d.ts
3
3
  interface OTLPConfig {
4
4
  /** OTLP HTTP endpoint (e.g., http://localhost:4318) */
@@ -1 +1 @@
1
- {"version":3,"file":"otlp.d.mts","names":[],"sources":["../../src/adapters/otlp.ts"],"mappings":";;UAOiB,UAAA;;EAEf,QAAA;EAFe;EAIf,WAAA;;EAEA,kBAAA,GAAqB,MAAA;EAJrB;EAMA,OAAA,GAAU,MAAA;EAFV;EAIA,OAAA;EAFA;EAIA,OAAA;AAAA;;UAIe,aAAA;EACf,YAAA;EACA,cAAA;EACA,YAAA;EACA,IAAA;IAAQ,WAAA;EAAA;EACR,UAAA,EAAY,KAAA;IACV,GAAA;IACA,KAAA;MAAS,WAAA;MAAsB,QAAA;MAAmB,SAAA;IAAA;EAAA;EAEpD,OAAA;EACA,MAAA;AAAA;;;;iBAyDc,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAY,aAAA;AAAnD;;;;;;;;;AA0JA;;;;;;;;;;;AA1JA,iBA0JgB,eAAA,CAAgB,SAAA,GAAY,OAAA,CAAQ,UAAA,KAAW,GAAA,EAAZ,YAAA,GAAY,YAAA,OAAA,OAAA;;;;;;;;AA+B/D;;;iBAAsB,UAAA,CAAW,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,UAAA,GAAa,OAAA;;;;;;;;;;;iBAclD,eAAA,CAAgB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,UAAA,GAAa,OAAA"}
1
+ {"version":3,"file":"otlp.d.mts","names":[],"sources":["../../src/adapters/otlp.ts"],"mappings":";;UAQiB,UAAA;;EAEf,QAAA;EAFe;EAIf,WAAA;;EAEA,kBAAA,GAAqB,MAAA;EAJrB;EAMA,OAAA,GAAU,MAAA;EAFV;EAIA,OAAA;EAFA;EAIA,OAAA;AAAA;;UAIe,aAAA;EACf,YAAA;EACA,cAAA;EACA,YAAA;EACA,IAAA;IAAQ,WAAA;EAAA;EACR,UAAA,EAAY,KAAA;IACV,GAAA;IACA,KAAA;MAAS,WAAA;MAAsB,QAAA;MAAmB,SAAA;IAAA;EAAA;EAEpD,OAAA;EACA,MAAA;AAAA;;;;iBA4Cc,eAAA,CAAgB,KAAA,EAAO,SAAA,GAAY,aAAA;AAAnD;;;;;;;;;AA0JA;;;;;;;;;;;AA1JA,iBA0JgB,eAAA,CAAgB,SAAA,GAAY,OAAA,CAAQ,UAAA,KAAW,GAAA,EAAZ,YAAA,GAAY,YAAA,OAAA,OAAA;;;;;;;;AA8D/D;;;iBAAsB,UAAA,CAAW,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,UAAA,GAAa,OAAA;;;;;;;;;;;iBAclD,eAAA,CAAgB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,UAAA,GAAa,OAAA"}
@@ -1,6 +1,6 @@
1
- import { n as resolveAdapterConfig, t as httpPost } from "../_http-BY1e9pwC.mjs";
2
- import { t as defineDrain } from "../_drain-CmCtsuF6.mjs";
3
- import { n as OTEL_SEVERITY_TEXT, t as OTEL_SEVERITY_NUMBER } from "../_severity-CQijvfhU.mjs";
1
+ import { a as resolveAdapterConfig, n as defineHttpDrain, r as httpPost } from "../drain-ByWUeOQC.mjs";
2
+ import { n as toOtlpAttributeValue } from "../event-DcHmEm3O.mjs";
3
+ import { n as OTEL_SEVERITY_TEXT, t as OTEL_SEVERITY_NUMBER } from "../severity-BYWZ96Sb.mjs";
4
4
  //#region src/adapters/otlp.ts
5
5
  const OTLP_FIELDS = [
6
6
  {
@@ -16,15 +16,7 @@ const OTLP_FIELDS = [
16
16
  { key: "timeout" },
17
17
  { key: "retries" }
18
18
  ];
19
- /**
20
- * Convert a value to OTLP attribute value format.
21
- */
22
- function toAttributeValue(value) {
23
- if (typeof value === "boolean") return { boolValue: value };
24
- if (typeof value === "number" && Number.isInteger(value)) return { intValue: String(value) };
25
- if (typeof value === "string") return { stringValue: value };
26
- return { stringValue: JSON.stringify(value) };
27
- }
19
+ const toAttributeValue = toOtlpAttributeValue;
28
20
  /**
29
21
  * Convert an evlog WideEvent to an OTLP LogRecord.
30
22
  */
@@ -127,7 +119,7 @@ function getHeadersFromEnv() {
127
119
  * ```
128
120
  */
129
121
  function createOTLPDrain(overrides) {
130
- return defineDrain({
122
+ return defineHttpDrain({
131
123
  name: "otlp",
132
124
  resolve: async () => {
133
125
  const config = await resolveAdapterConfig("otlp", OTLP_FIELDS, overrides);
@@ -138,9 +130,38 @@ function createOTLPDrain(overrides) {
138
130
  }
139
131
  return config;
140
132
  },
141
- send: sendBatchToOTLP
133
+ encode: (events, config) => {
134
+ if (events.length === 0) return null;
135
+ return {
136
+ url: `${config.endpoint.replace(/\/$/, "")}/v1/logs`,
137
+ headers: {
138
+ "Content-Type": "application/json",
139
+ ...config.headers
140
+ },
141
+ body: JSON.stringify(buildOTLPPayload(events, config))
142
+ };
143
+ }
142
144
  });
143
145
  }
146
+ function buildOTLPPayload(events, config) {
147
+ const grouped = /* @__PURE__ */ new Map();
148
+ for (const event of events) {
149
+ const key = `${event.service}::${event.environment}`;
150
+ const group = grouped.get(key);
151
+ if (group) group.push(event);
152
+ else grouped.set(key, [event]);
153
+ }
154
+ return { resourceLogs: Array.from(grouped.values()).map((groupEvents) => ({
155
+ resource: { attributes: buildResourceAttributes(groupEvents[0], config) },
156
+ scopeLogs: [{
157
+ scope: {
158
+ name: "evlog",
159
+ version: "1.0.0"
160
+ },
161
+ logRecords: groupEvents.map(toOTLPLogRecord)
162
+ }]
163
+ })) };
164
+ }
144
165
  /**
145
166
  * Send a single event to an OTLP endpoint.
146
167
  *
@@ -167,23 +188,7 @@ async function sendToOTLP(event, config) {
167
188
  async function sendBatchToOTLP(events, config) {
168
189
  if (events.length === 0) return;
169
190
  const url = `${config.endpoint.replace(/\/$/, "")}/v1/logs`;
170
- const grouped = /* @__PURE__ */ new Map();
171
- for (const event of events) {
172
- const key = `${event.service}::${event.environment}`;
173
- const group = grouped.get(key);
174
- if (group) group.push(event);
175
- else grouped.set(key, [event]);
176
- }
177
- const payload = { resourceLogs: Array.from(grouped.values()).map((groupEvents) => ({
178
- resource: { attributes: buildResourceAttributes(groupEvents[0], config) },
179
- scopeLogs: [{
180
- scope: {
181
- name: "evlog",
182
- version: "1.0.0"
183
- },
184
- logRecords: groupEvents.map(toOTLPLogRecord)
185
- }]
186
- })) };
191
+ const payload = buildOTLPPayload(events, config);
187
192
  await httpPost({
188
193
  url,
189
194
  headers: {
@@ -1 +1 @@
1
- {"version":3,"file":"otlp.mjs","names":[],"sources":["../../src/adapters/otlp.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from './_config'\nimport { resolveAdapterConfig } from './_config'\nimport { defineDrain } from './_drain'\nimport { httpPost } from './_http'\nimport { OTEL_SEVERITY_NUMBER, OTEL_SEVERITY_TEXT } from './_severity'\n\nexport interface OTLPConfig {\n /** OTLP HTTP endpoint (e.g., http://localhost:4318) */\n endpoint: string\n /** Override service name (defaults to event.service) */\n serviceName?: string\n /** Additional resource attributes */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Custom headers (e.g., for authentication) */\n headers?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\n/** OTLP Log Record structure */\nexport interface OTLPLogRecord {\n timeUnixNano: string\n severityNumber: number\n severityText: string\n body: { stringValue: string }\n attributes: Array<{\n key: string\n value: { stringValue?: string, intValue?: string, boolValue?: boolean }\n }>\n traceId?: string\n spanId?: string\n}\n\n/** OTLP Resource structure */\ninterface OTLPResource {\n attributes: Array<{\n key: string\n value: { stringValue?: string, intValue?: string, boolValue?: boolean }\n }>\n}\n\n/** OTLP Scope structure */\ninterface OTLPScope {\n name: string\n version?: string\n}\n\n/** OTLP ExportLogsServiceRequest structure */\ninterface ExportLogsServiceRequest {\n resourceLogs: Array<{\n resource: OTLPResource\n scopeLogs: Array<{\n scope: OTLPScope\n logRecords: OTLPLogRecord[]\n }>\n }>\n}\n\nconst OTLP_FIELDS: ConfigField<OTLPConfig>[] = [\n { key: 'endpoint', env: ['NUXT_OTLP_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT'] },\n { key: 'serviceName', env: ['NUXT_OTLP_SERVICE_NAME', 'OTEL_SERVICE_NAME'] },\n { key: 'headers' },\n { key: 'resourceAttributes' },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\n/**\n * Convert a value to OTLP attribute value format.\n */\nfunction toAttributeValue(value: unknown): { stringValue?: string, intValue?: string, boolValue?: boolean } {\n if (typeof value === 'boolean') {\n return { boolValue: value }\n }\n if (typeof value === 'number' && Number.isInteger(value)) {\n return { intValue: String(value) }\n }\n if (typeof value === 'string') {\n return { stringValue: value }\n }\n // For complex types, serialize to JSON string\n return { stringValue: JSON.stringify(value) }\n}\n\n/**\n * Convert an evlog WideEvent to an OTLP LogRecord.\n */\nexport function toOTLPLogRecord(event: WideEvent): OTLPLogRecord {\n const timestamp = new Date(event.timestamp).getTime() * 1_000_000 // Convert to nanoseconds\n\n // Extract known fields, rest goes to attributes\n const { level, traceId, spanId, ...rest } = event\n // Remove base fields from rest (they're handled as resource attributes)\n delete (rest as Record<string, unknown>).timestamp\n delete (rest as Record<string, unknown>).service\n delete (rest as Record<string, unknown>).environment\n delete (rest as Record<string, unknown>).version\n delete (rest as Record<string, unknown>).commitHash\n delete (rest as Record<string, unknown>).region\n\n const attributes: OTLPLogRecord['attributes'] = []\n\n // Add all remaining event fields as attributes\n for (const [key, value] of Object.entries(rest)) {\n if (value !== undefined && value !== null) {\n attributes.push({\n key,\n value: toAttributeValue(value),\n })\n }\n }\n\n const record: OTLPLogRecord = {\n timeUnixNano: String(timestamp),\n severityNumber: OTEL_SEVERITY_NUMBER[level] ?? 9,\n severityText: OTEL_SEVERITY_TEXT[level] ?? 'INFO',\n body: { stringValue: JSON.stringify(event) },\n attributes,\n }\n\n // Add trace context if present\n if (typeof traceId === 'string') {\n record.traceId = traceId\n }\n if (typeof spanId === 'string') {\n record.spanId = spanId\n }\n\n return record\n}\n\n/**\n * Build OTLP resource attributes from event and config.\n */\nfunction buildResourceAttributes(\n event: WideEvent,\n config: OTLPConfig,\n): OTLPResource['attributes'] {\n const attributes: OTLPResource['attributes'] = []\n\n // Service name\n attributes.push({\n key: 'service.name',\n value: { stringValue: config.serviceName ?? event.service },\n })\n\n // Environment\n if (event.environment) {\n attributes.push({\n key: 'deployment.environment',\n value: { stringValue: event.environment },\n })\n }\n\n // Version\n if (event.version) {\n attributes.push({\n key: 'service.version',\n value: { stringValue: event.version },\n })\n }\n\n // Region\n if (event.region) {\n attributes.push({\n key: 'cloud.region',\n value: { stringValue: event.region },\n })\n }\n\n // Commit hash\n if (event.commitHash) {\n attributes.push({\n key: 'vcs.commit.id',\n value: { stringValue: event.commitHash },\n })\n }\n\n // Custom resource attributes from config\n if (config.resourceAttributes) {\n for (const [key, value] of Object.entries(config.resourceAttributes)) {\n attributes.push({\n key,\n value: toAttributeValue(value),\n })\n }\n }\n\n return attributes\n}\n\n/**\n * Build headers from OTEL env vars.\n * Kept inline as OTLP-specific (parses OTEL_EXPORTER_OTLP_HEADERS=key=val,key=val).\n */\nfunction getHeadersFromEnv(): Record<string, string> | undefined {\n const headersEnv = process.env.OTEL_EXPORTER_OTLP_HEADERS || process.env.NUXT_OTLP_HEADERS\n if (headersEnv) {\n const headers: Record<string, string> = {}\n const decoded = decodeURIComponent(headersEnv)\n for (const pair of decoded.split(',')) {\n const eqIndex = pair.indexOf('=')\n if (eqIndex > 0) {\n const key = pair.slice(0, eqIndex).trim()\n const value = pair.slice(eqIndex + 1).trim()\n if (key && value) {\n headers[key] = value\n }\n }\n }\n if (Object.keys(headers).length > 0) return headers\n }\n\n const auth = process.env.NUXT_OTLP_AUTH\n if (auth) {\n return { Authorization: auth }\n }\n\n return undefined\n}\n\n/**\n * Create a drain function for sending logs to an OTLP endpoint.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createOTLPDrain()\n * 2. runtimeConfig.evlog.otlp (NUXT_EVLOG_OTLP_*)\n * 3. runtimeConfig.otlp (NUXT_OTLP_*)\n * 4. Environment variables: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME\n *\n * @example\n * ```ts\n * // Zero config - reads from runtimeConfig or env vars\n * nitroApp.hooks.hook('evlog:drain', createOTLPDrain())\n *\n * // With overrides\n * nitroApp.hooks.hook('evlog:drain', createOTLPDrain({\n * endpoint: 'http://localhost:4318',\n * }))\n * ```\n */\nexport function createOTLPDrain(overrides?: Partial<OTLPConfig>) {\n return defineDrain<OTLPConfig>({\n name: 'otlp',\n resolve: async () => {\n const config = await resolveAdapterConfig<OTLPConfig>('otlp', OTLP_FIELDS, overrides)\n\n // OTLP-specific: resolve headers from env if not provided via config\n if (!config.headers) {\n config.headers = getHeadersFromEnv()\n }\n\n if (!config.endpoint) {\n console.error('[evlog/otlp] Missing endpoint. Set NUXT_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT env var, or pass to createOTLPDrain()')\n return null\n }\n return config as OTLPConfig\n },\n send: sendBatchToOTLP,\n })\n}\n\n/**\n * Send a single event to an OTLP endpoint.\n *\n * @example\n * ```ts\n * await sendToOTLP(event, {\n * endpoint: 'http://localhost:4318',\n * })\n * ```\n */\nexport async function sendToOTLP(event: WideEvent, config: OTLPConfig): Promise<void> {\n await sendBatchToOTLP([event], config)\n}\n\n/**\n * Send a batch of events to an OTLP endpoint.\n *\n * @example\n * ```ts\n * await sendBatchToOTLP(events, {\n * endpoint: 'http://localhost:4318',\n * })\n * ```\n */\nexport async function sendBatchToOTLP(events: WideEvent[], config: OTLPConfig): Promise<void> {\n if (events.length === 0) return\n\n const url = `${config.endpoint.replace(/\\/$/, '')}/v1/logs`\n\n // Group events by (service, environment) so each gets correct OTLP resource attributes\n const grouped = new Map<string, WideEvent[]>()\n for (const event of events) {\n const key = `${event.service}::${event.environment}`\n const group = grouped.get(key)\n if (group) {\n group.push(event)\n } else {\n grouped.set(key, [event])\n }\n }\n\n const payload: ExportLogsServiceRequest = {\n resourceLogs: Array.from(grouped.values()).map((groupEvents) => ({\n resource: { attributes: buildResourceAttributes(groupEvents[0]!, config) },\n scopeLogs: [\n {\n scope: { name: 'evlog', version: '1.0.0' },\n logRecords: groupEvents.map(toOTLPLogRecord),\n },\n ],\n })),\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...config.headers,\n }\n\n await httpPost({\n url,\n headers,\n body: JSON.stringify(payload),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'OTLP',\n })\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"otlp.mjs","names":[],"sources":["../../src/adapters/otlp.ts"],"sourcesContent":["import type { WideEvent } from '../types'\nimport type { ConfigField } from '../shared/config'\nimport { resolveAdapterConfig } from '../shared/config'\nimport { defineHttpDrain } from '../shared/drain'\nimport { toOtlpAttributeValue } from '../shared/event'\nimport { httpPost } from '../shared/http'\nimport { OTEL_SEVERITY_NUMBER, OTEL_SEVERITY_TEXT } from '../shared/severity'\n\nexport interface OTLPConfig {\n /** OTLP HTTP endpoint (e.g., http://localhost:4318) */\n endpoint: string\n /** Override service name (defaults to event.service) */\n serviceName?: string\n /** Additional resource attributes */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Custom headers (e.g., for authentication) */\n headers?: Record<string, string>\n /** Request timeout in milliseconds. Default: 5000 */\n timeout?: number\n /** Number of retry attempts on transient failures. Default: 2 */\n retries?: number\n}\n\n/** OTLP Log Record structure */\nexport interface OTLPLogRecord {\n timeUnixNano: string\n severityNumber: number\n severityText: string\n body: { stringValue: string }\n attributes: Array<{\n key: string\n value: { stringValue?: string, intValue?: string, boolValue?: boolean }\n }>\n traceId?: string\n spanId?: string\n}\n\n/** OTLP Resource structure */\ninterface OTLPResource {\n attributes: Array<{\n key: string\n value: { stringValue?: string, intValue?: string, boolValue?: boolean }\n }>\n}\n\n/** OTLP Scope structure */\ninterface OTLPScope {\n name: string\n version?: string\n}\n\n/** OTLP ExportLogsServiceRequest structure */\ninterface ExportLogsServiceRequest {\n resourceLogs: Array<{\n resource: OTLPResource\n scopeLogs: Array<{\n scope: OTLPScope\n logRecords: OTLPLogRecord[]\n }>\n }>\n}\n\nconst OTLP_FIELDS: ConfigField<OTLPConfig>[] = [\n { key: 'endpoint', env: ['NUXT_OTLP_ENDPOINT', 'OTEL_EXPORTER_OTLP_ENDPOINT'] },\n { key: 'serviceName', env: ['NUXT_OTLP_SERVICE_NAME', 'OTEL_SERVICE_NAME'] },\n { key: 'headers' },\n { key: 'resourceAttributes' },\n { key: 'timeout' },\n { key: 'retries' },\n]\n\n// Re-exposed under a local name to keep call-sites tight while delegating to\n// the shared OTLP attribute encoder in `evlog/toolkit`.\nconst toAttributeValue = toOtlpAttributeValue\n\n/**\n * Convert an evlog WideEvent to an OTLP LogRecord.\n */\nexport function toOTLPLogRecord(event: WideEvent): OTLPLogRecord {\n const timestamp = new Date(event.timestamp).getTime() * 1_000_000 // Convert to nanoseconds\n\n // Extract known fields, rest goes to attributes\n const { level, traceId, spanId, ...rest } = event\n // Remove base fields from rest (they're handled as resource attributes)\n delete (rest as Record<string, unknown>).timestamp\n delete (rest as Record<string, unknown>).service\n delete (rest as Record<string, unknown>).environment\n delete (rest as Record<string, unknown>).version\n delete (rest as Record<string, unknown>).commitHash\n delete (rest as Record<string, unknown>).region\n\n const attributes: OTLPLogRecord['attributes'] = []\n\n // Add all remaining event fields as attributes\n for (const [key, value] of Object.entries(rest)) {\n if (value !== undefined && value !== null) {\n attributes.push({\n key,\n value: toAttributeValue(value),\n })\n }\n }\n\n const record: OTLPLogRecord = {\n timeUnixNano: String(timestamp),\n severityNumber: OTEL_SEVERITY_NUMBER[level] ?? 9,\n severityText: OTEL_SEVERITY_TEXT[level] ?? 'INFO',\n body: { stringValue: JSON.stringify(event) },\n attributes,\n }\n\n // Add trace context if present\n if (typeof traceId === 'string') {\n record.traceId = traceId\n }\n if (typeof spanId === 'string') {\n record.spanId = spanId\n }\n\n return record\n}\n\n/**\n * Build OTLP resource attributes from event and config.\n */\nfunction buildResourceAttributes(\n event: WideEvent,\n config: OTLPConfig,\n): OTLPResource['attributes'] {\n const attributes: OTLPResource['attributes'] = []\n\n // Service name\n attributes.push({\n key: 'service.name',\n value: { stringValue: config.serviceName ?? event.service },\n })\n\n // Environment\n if (event.environment) {\n attributes.push({\n key: 'deployment.environment',\n value: { stringValue: event.environment },\n })\n }\n\n // Version\n if (event.version) {\n attributes.push({\n key: 'service.version',\n value: { stringValue: event.version },\n })\n }\n\n // Region\n if (event.region) {\n attributes.push({\n key: 'cloud.region',\n value: { stringValue: event.region },\n })\n }\n\n // Commit hash\n if (event.commitHash) {\n attributes.push({\n key: 'vcs.commit.id',\n value: { stringValue: event.commitHash },\n })\n }\n\n // Custom resource attributes from config\n if (config.resourceAttributes) {\n for (const [key, value] of Object.entries(config.resourceAttributes)) {\n attributes.push({\n key,\n value: toAttributeValue(value),\n })\n }\n }\n\n return attributes\n}\n\n/**\n * Build headers from OTEL env vars.\n * Kept inline as OTLP-specific (parses OTEL_EXPORTER_OTLP_HEADERS=key=val,key=val).\n */\nfunction getHeadersFromEnv(): Record<string, string> | undefined {\n const headersEnv = process.env.OTEL_EXPORTER_OTLP_HEADERS || process.env.NUXT_OTLP_HEADERS\n if (headersEnv) {\n const headers: Record<string, string> = {}\n const decoded = decodeURIComponent(headersEnv)\n for (const pair of decoded.split(',')) {\n const eqIndex = pair.indexOf('=')\n if (eqIndex > 0) {\n const key = pair.slice(0, eqIndex).trim()\n const value = pair.slice(eqIndex + 1).trim()\n if (key && value) {\n headers[key] = value\n }\n }\n }\n if (Object.keys(headers).length > 0) return headers\n }\n\n const auth = process.env.NUXT_OTLP_AUTH\n if (auth) {\n return { Authorization: auth }\n }\n\n return undefined\n}\n\n/**\n * Create a drain function for sending logs to an OTLP endpoint.\n *\n * Configuration priority (highest to lowest):\n * 1. Overrides passed to createOTLPDrain()\n * 2. runtimeConfig.evlog.otlp (NUXT_EVLOG_OTLP_*)\n * 3. runtimeConfig.otlp (NUXT_OTLP_*)\n * 4. Environment variables: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME\n *\n * @example\n * ```ts\n * // Zero config - reads from runtimeConfig or env vars\n * nitroApp.hooks.hook('evlog:drain', createOTLPDrain())\n *\n * // With overrides\n * nitroApp.hooks.hook('evlog:drain', createOTLPDrain({\n * endpoint: 'http://localhost:4318',\n * }))\n * ```\n */\nexport function createOTLPDrain(overrides?: Partial<OTLPConfig>) {\n return defineHttpDrain<OTLPConfig>({\n name: 'otlp',\n resolve: async () => {\n const config = await resolveAdapterConfig<OTLPConfig>('otlp', OTLP_FIELDS, overrides)\n\n // OTLP-specific: resolve headers from env if not provided via config\n if (!config.headers) {\n config.headers = getHeadersFromEnv()\n }\n\n if (!config.endpoint) {\n console.error('[evlog/otlp] Missing endpoint. Set NUXT_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT env var, or pass to createOTLPDrain()')\n return null\n }\n return config as OTLPConfig\n },\n encode: (events, config) => {\n if (events.length === 0) return null\n return {\n url: `${config.endpoint.replace(/\\/$/, '')}/v1/logs`,\n headers: {\n 'Content-Type': 'application/json',\n ...config.headers,\n },\n body: JSON.stringify(buildOTLPPayload(events, config)),\n }\n },\n })\n}\n\nfunction buildOTLPPayload(events: WideEvent[], config: OTLPConfig): ExportLogsServiceRequest {\n const grouped = new Map<string, WideEvent[]>()\n for (const event of events) {\n const key = `${event.service}::${event.environment}`\n const group = grouped.get(key)\n if (group) group.push(event)\n else grouped.set(key, [event])\n }\n return {\n resourceLogs: Array.from(grouped.values()).map(groupEvents => ({\n resource: { attributes: buildResourceAttributes(groupEvents[0]!, config) },\n scopeLogs: [\n {\n scope: { name: 'evlog', version: '1.0.0' },\n logRecords: groupEvents.map(toOTLPLogRecord),\n },\n ],\n })),\n }\n}\n\n/**\n * Send a single event to an OTLP endpoint.\n *\n * @example\n * ```ts\n * await sendToOTLP(event, {\n * endpoint: 'http://localhost:4318',\n * })\n * ```\n */\nexport async function sendToOTLP(event: WideEvent, config: OTLPConfig): Promise<void> {\n await sendBatchToOTLP([event], config)\n}\n\n/**\n * Send a batch of events to an OTLP endpoint.\n *\n * @example\n * ```ts\n * await sendBatchToOTLP(events, {\n * endpoint: 'http://localhost:4318',\n * })\n * ```\n */\nexport async function sendBatchToOTLP(events: WideEvent[], config: OTLPConfig): Promise<void> {\n if (events.length === 0) return\n\n const url = `${config.endpoint.replace(/\\/$/, '')}/v1/logs`\n const payload = buildOTLPPayload(events, config)\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n ...config.headers,\n }\n\n await httpPost({\n url,\n headers,\n body: JSON.stringify(payload),\n timeout: config.timeout ?? 5000,\n retries: config.retries,\n label: 'OTLP',\n })\n}\n"],"mappings":"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"}
@@ -1,21 +1,45 @@
1
- import { F as DrainContext, it as WideEvent } from "../audit-CTIviX3P.mjs";
1
+ import { F as DrainContext, it as WideEvent } from "../audit-X1uUukm3.mjs";
2
2
  //#region src/adapters/posthog.d.ts
3
+ /**
4
+ * Mode for {@link createPostHogDrain}.
5
+ *
6
+ * - `'logs'` (default) — sends events to PostHog Logs via OTLP. Cheapest path
7
+ * and recommended for most teams.
8
+ * - `'events'` — sends events to the `/batch/` API as custom PostHog events.
9
+ * Useful when you want events to appear in PostHog product analytics
10
+ * funnels/dashboards.
11
+ */
12
+ type PostHogMode = 'logs' | 'events';
3
13
  interface PostHogConfig {
4
14
  /** PostHog project API key */
5
15
  apiKey: string;
6
16
  /** PostHog host URL. Default: https://us.i.posthog.com */
7
17
  host?: string;
18
+ /**
19
+ * Send mode. `'logs'` (default) uses PostHog Logs (OTLP, cheapest);
20
+ * `'events'` uses the `/batch/` API for custom PostHog events.
21
+ * @default 'logs'
22
+ */
23
+ mode?: PostHogMode;
24
+ /**
25
+ * PostHog event name when `mode === 'events'`. Ignored otherwise.
26
+ * @default 'evlog_wide_event'
27
+ */
28
+ eventName?: string;
29
+ /**
30
+ * Override `distinct_id` when `mode === 'events'`. Ignored otherwise.
31
+ * Defaults to `event.userId` (when set) or `event.service`.
32
+ */
33
+ distinctId?: string;
8
34
  /** Request timeout in milliseconds. Default: 5000 */
9
35
  timeout?: number;
10
36
  /** Number of retry attempts on transient failures. Default: 2 */
11
37
  retries?: number;
12
38
  }
13
- interface PostHogEventsConfig extends PostHogConfig {
14
- /** PostHog event name. Default: evlog_wide_event */
15
- eventName?: string;
16
- /** Override distinct_id (defaults to event.service) */
17
- distinctId?: string;
18
- }
39
+ /**
40
+ * @deprecated Use {@link PostHogConfig} with `mode: 'events'` instead.
41
+ */
42
+ type PostHogEventsConfig = PostHogConfig;
19
43
  /** PostHog event structure for the batch API */
20
44
  interface PostHogEvent {
21
45
  event: string;
@@ -24,11 +48,14 @@ interface PostHogEvent {
24
48
  properties: Record<string, unknown>;
25
49
  }
26
50
  /**
27
- * Convert a WideEvent to a PostHog custom event format.
51
+ * Convert a WideEvent to a PostHog custom event.
28
52
  */
29
- declare function toPostHogEvent(event: WideEvent, config: PostHogEventsConfig): PostHogEvent;
53
+ declare function toPostHogEvent(event: WideEvent, config: PostHogConfig): PostHogEvent;
30
54
  /**
31
- * Create a drain function for sending logs to PostHog Logs via OTLP.
55
+ * Create a drain function for sending logs to PostHog.
56
+ *
57
+ * - Default `mode: 'logs'` — sends events to PostHog Logs via OTLP. Recommended.
58
+ * - `mode: 'events'` — sends events to the `/batch/` API as custom events.
32
59
  *
33
60
  * Configuration priority (highest to lowest):
34
61
  * 1. Overrides passed to createPostHogDrain()
@@ -38,81 +65,34 @@ declare function toPostHogEvent(event: WideEvent, config: PostHogEventsConfig):
38
65
  *
39
66
  * @example
40
67
  * ```ts
41
- * // Zero config - just set NUXT_POSTHOG_API_KEY env var
42
- * nitroApp.hooks.hook('evlog:drain', createPostHogDrain())
68
+ * // Default: PostHog Logs (OTLP)
69
+ * initLogger({ drain: createPostHogDrain() })
43
70
  *
44
- * // With overrides
45
- * nitroApp.hooks.hook('evlog:drain', createPostHogDrain({
46
- * apiKey: 'phc_...',
47
- * host: 'https://eu.i.posthog.com',
48
- * }))
71
+ * // Custom events
72
+ * initLogger({ drain: createPostHogDrain({ mode: 'events', eventName: 'server_request' }) })
49
73
  * ```
50
74
  */
51
75
  declare function createPostHogDrain(overrides?: Partial<PostHogConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
76
+ /**
77
+ * @deprecated Use {@link createPostHogDrain} with `mode: 'events'`.
78
+ */
79
+ declare function createPostHogEventsDrain(overrides?: Partial<PostHogConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
52
80
  /**
53
81
  * Send a single event to PostHog Logs via OTLP.
54
- *
55
- * @example
56
- * ```ts
57
- * await sendToPostHog(event, {
58
- * apiKey: process.env.POSTHOG_API_KEY!,
59
- * })
60
- * ```
61
82
  */
62
83
  declare function sendToPostHog(event: WideEvent, config: PostHogConfig): Promise<void>;
63
84
  /**
64
85
  * Send a batch of events to PostHog Logs via OTLP.
65
- *
66
- * @example
67
- * ```ts
68
- * await sendBatchToPostHog(events, {
69
- * apiKey: process.env.POSTHOG_API_KEY!,
70
- * })
71
- * ```
72
86
  */
73
87
  declare function sendBatchToPostHog(events: WideEvent[], config: PostHogConfig): Promise<void>;
74
88
  /**
75
- * Create a drain function for sending logs to PostHog as custom events.
76
- *
77
- * Uses PostHog's `/batch/` API. Consider using `createPostHogDrain()` instead
78
- * which uses PostHog Logs (OTLP) and is significantly cheaper.
79
- *
80
- * Configuration priority (highest to lowest):
81
- * 1. Overrides passed to createPostHogEventsDrain()
82
- * 2. runtimeConfig.evlog.posthog
83
- * 3. runtimeConfig.posthog
84
- * 4. Environment variables: NUXT_POSTHOG_API_KEY/POSTHOG_API_KEY, NUXT_POSTHOG_HOST/POSTHOG_HOST
85
- *
86
- * @example
87
- * ```ts
88
- * nitroApp.hooks.hook('evlog:drain', createPostHogEventsDrain({
89
- * eventName: 'server_request',
90
- * }))
91
- * ```
92
- */
93
- declare function createPostHogEventsDrain(overrides?: Partial<PostHogEventsConfig>): (ctx: DrainContext | DrainContext[]) => Promise<void>;
94
- /**
95
- * Send a single event to PostHog as a custom event.
96
- *
97
- * @example
98
- * ```ts
99
- * await sendToPostHogEvents(event, {
100
- * apiKey: process.env.POSTHOG_API_KEY!,
101
- * })
102
- * ```
89
+ * Send a single event to PostHog via the custom-events `/batch/` API.
103
90
  */
104
- declare function sendToPostHogEvents(event: WideEvent, config: PostHogEventsConfig): Promise<void>;
91
+ declare function sendToPostHogEvents(event: WideEvent, config: PostHogConfig): Promise<void>;
105
92
  /**
106
- * Send a batch of events to PostHog as custom events via the `/batch/` API.
107
- *
108
- * @example
109
- * ```ts
110
- * await sendBatchToPostHogEvents(events, {
111
- * apiKey: process.env.POSTHOG_API_KEY!,
112
- * })
113
- * ```
93
+ * Send a batch of events to PostHog via the custom-events `/batch/` API.
114
94
  */
115
- declare function sendBatchToPostHogEvents(events: WideEvent[], config: PostHogEventsConfig): Promise<void>;
95
+ declare function sendBatchToPostHogEvents(events: WideEvent[], config: PostHogConfig): Promise<void>;
116
96
  //#endregion
117
- export { PostHogConfig, PostHogEvent, PostHogEventsConfig, createPostHogDrain, createPostHogEventsDrain, sendBatchToPostHog, sendBatchToPostHogEvents, sendToPostHog, sendToPostHogEvents, toPostHogEvent };
97
+ export { PostHogConfig, PostHogEvent, PostHogEventsConfig, PostHogMode, createPostHogDrain, createPostHogEventsDrain, sendBatchToPostHog, sendBatchToPostHogEvents, sendToPostHog, sendToPostHogEvents, toPostHogEvent };
118
98
  //# sourceMappingURL=posthog.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"posthog.d.mts","names":[],"sources":["../../src/adapters/posthog.ts"],"mappings":";;UAQiB,aAAA;;EAEf,MAAA;EAFe;EAIf,IAAA;;EAEA,OAAA;EAJA;EAMA,OAAA;AAAA;AAAA,UAGe,mBAAA,SAA4B,aAAA;EAHpC;EAKP,SAAA;EAFe;EAIf,UAAA;AAAA;;UAIe,YAAA;EACf,KAAA;EACA,WAAA;EACA,SAAA;EACA,UAAA,EAAY,MAAA;AAAA;;;;iBAiCE,cAAA,CAAe,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,mBAAA,GAAsB,YAAA;;;;;;;AAA/E;;;;;;;;;;;;;;;iBAwCgB,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;;;;;;;;AAA9E;;;iBAcsB,kBAAA,CAAmB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;;;;;;;;;AAAtF;;;;;;;;iBA4BgB,wBAAA,CAAyB,SAAA,GAAY,OAAA,CAAQ,mBAAA,KAAoB,GAAA,EAArB,YAAA,GAAqB,YAAA,OAAA,OAAA;;;;;;;AAAjF;;;;iBAyBsB,mBAAA,CAAoB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,mBAAA,GAAsB,OAAA;;;;;;;;;;;iBAcpE,wBAAA,CAAyB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,mBAAA,GAAsB,OAAA"}
1
+ {"version":3,"file":"posthog.d.mts","names":[],"sources":["../../src/adapters/posthog.ts"],"mappings":";;;;;AAiBA;;;;;AAEA;KAFY,WAAA;AAAA,UAEK,aAAA;EAUG;EARlB,MAAA;EAEA;EAAA,IAAA;EAMO;;;;;EAAP,IAAA,GAAO,WAAA;EAcA;AAMT;;;EAfE,SAAA;EAe6C;AAG/C;;;EAbE,UAAA;EAcA;EAZA,OAAA;EAcA;EAZA,OAAA;AAAA;;;AA0CF;KApCY,mBAAA,GAAsB,aAAA;;UAGjB,YAAA;EACf,KAAA;EACA,WAAA;EACA,SAAA;EACA,UAAA,EAAY,MAAA;AAAA;;;;iBA6BE,cAAA,CAAe,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,YAAA;;;AAqCzE;;;;;;;;;;;;;;;;;;;iBAAgB,kBAAA,CAAmB,SAAA,GAAY,OAAA,CAAQ,aAAA,KAAc,GAAA,EAAf,YAAA,GAAe,YAAA,OAAA,OAAA;;;;iBA6CrD,wBAAA,CAAyB,SAAA,GAAY,OAAA,CAAQ,aAAA,KAAc,GAAA,EAAf,YAAA,GAAe,YAAA,OAAA,OAAA;;;;iBAOrD,aAAA,CAAc,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;iBAOxD,kBAAA,CAAmB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;;iBAQhE,mBAAA,CAAoB,KAAA,EAAO,SAAA,EAAW,MAAA,EAAQ,aAAA,GAAgB,OAAA;;;AAfpF;iBAsBsB,wBAAA,CAAyB,MAAA,EAAQ,SAAA,IAAa,MAAA,EAAQ,aAAA,GAAgB,OAAA"}