evlog 2.18.1 → 2.19.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 (190) hide show
  1. package/dist/adapters/axiom.d.mts +1 -1
  2. package/dist/adapters/axiom.mjs +2 -2
  3. package/dist/adapters/better-stack.d.mts +1 -1
  4. package/dist/adapters/better-stack.mjs +2 -2
  5. package/dist/adapters/datadog.d.mts +1 -1
  6. package/dist/adapters/datadog.mjs +2 -2
  7. package/dist/adapters/fs.d.mts +1 -1
  8. package/dist/adapters/fs.mjs +2 -2
  9. package/dist/adapters/hyperdx.d.mts +1 -1
  10. package/dist/adapters/hyperdx.mjs +1 -1
  11. package/dist/adapters/memory.d.mts +1 -1
  12. package/dist/adapters/memory.mjs +1 -1
  13. package/dist/adapters/otlp.d.mts +1 -1
  14. package/dist/adapters/otlp.mjs +4 -4
  15. package/dist/adapters/posthog.d.mts +1 -1
  16. package/dist/adapters/posthog.mjs +2 -2
  17. package/dist/adapters/sentry.d.mts +1 -1
  18. package/dist/adapters/sentry.mjs +3 -3
  19. package/dist/ai/index.d.mts +1 -1
  20. package/dist/{audit-BUI3af4w.mjs → audit-BFwTUxBJ.mjs} +357 -101
  21. package/dist/audit-BFwTUxBJ.mjs.map +1 -0
  22. package/dist/{audit-DVdkntSO.d.mts → audit-BUAajsPU.d.mts} +106 -35
  23. package/dist/audit-BUAajsPU.d.mts.map +1 -0
  24. package/dist/better-auth/index.d.mts +1 -1
  25. package/dist/browser.d.mts +1 -1
  26. package/dist/{define-D6OJdSUH.mjs → define-Bpaymi-h.mjs} +2 -1
  27. package/dist/define-Bpaymi-h.mjs.map +1 -0
  28. package/dist/{define-D-BVMf2l.d.mts → define-DGwZkZ7x.d.mts} +8 -3
  29. package/dist/define-DGwZkZ7x.d.mts.map +1 -0
  30. package/dist/dev-terminal-D4UaEm17.mjs +54 -0
  31. package/dist/dev-terminal-D4UaEm17.mjs.map +1 -0
  32. package/dist/{dist-H3GIh-KK.mjs → dist-DdQWiZn8.mjs} +1 -1
  33. package/dist/{dist-H3GIh-KK.mjs.map → dist-DdQWiZn8.mjs.map} +1 -1
  34. package/dist/{drain-7n3K6kPe.mjs → drain-D_fy7m0n.mjs} +3 -3
  35. package/dist/{drain-7n3K6kPe.mjs.map → drain-D_fy7m0n.mjs.map} +1 -1
  36. package/dist/elysia/index.d.mts +3 -3
  37. package/dist/elysia/index.d.mts.map +1 -1
  38. package/dist/elysia/index.mjs +8 -5
  39. package/dist/elysia/index.mjs.map +1 -1
  40. package/dist/enrich-drain-CG_2Nix-.mjs +122 -0
  41. package/dist/enrich-drain-CG_2Nix-.mjs.map +1 -0
  42. package/dist/{enricher-UW9npoB2.d.mts → enricher-CuMbbdqp.d.mts} +2 -2
  43. package/dist/{enricher-UW9npoB2.d.mts.map → enricher-CuMbbdqp.d.mts.map} +1 -1
  44. package/dist/{enricher-N0erZS87.mjs → enricher-DAWf2-Fx.mjs} +2 -2
  45. package/dist/{enricher-N0erZS87.mjs.map → enricher-DAWf2-Fx.mjs.map} +1 -1
  46. package/dist/enrichers.d.mts +2 -2
  47. package/dist/enrichers.mjs +2 -2
  48. package/dist/{error-CVtn5U7b.d.mts → error-DwajXSKM.d.mts} +2 -2
  49. package/dist/{error-CVtn5U7b.d.mts.map → error-DwajXSKM.d.mts.map} +1 -1
  50. package/dist/error.d.mts +1 -1
  51. package/dist/{errors-dEMNQCiL.d.mts → errors-CAq8pYpW.d.mts} +2 -2
  52. package/dist/{errors-dEMNQCiL.d.mts.map → errors-CAq8pYpW.d.mts.map} +1 -1
  53. package/dist/{errors-BQgyQ9xe.mjs → errors-DA0cyr8q.mjs} +1 -1
  54. package/dist/{errors-BQgyQ9xe.mjs.map → errors-DA0cyr8q.mjs.map} +1 -1
  55. package/dist/{event-1BMl7o0k.mjs → event-qwAv-7AZ.mjs} +1 -1
  56. package/dist/{event-1BMl7o0k.mjs.map → event-qwAv-7AZ.mjs.map} +1 -1
  57. package/dist/express/index.d.mts +2 -2
  58. package/dist/express/index.mjs +3 -3
  59. package/dist/fastify/index.d.mts +2 -2
  60. package/dist/fastify/index.mjs +2 -2
  61. package/dist/{fork-Bga8x-X4.mjs → fork-CYm453dq.mjs} +39 -14
  62. package/dist/fork-CYm453dq.mjs.map +1 -0
  63. package/dist/{headers-CU-QqnYg.mjs → headers-VtmnWcfn.mjs} +1 -1
  64. package/dist/{headers-CU-QqnYg.mjs.map → headers-VtmnWcfn.mjs.map} +1 -1
  65. package/dist/hono/index.d.mts +2 -2
  66. package/dist/hono/index.d.mts.map +1 -1
  67. package/dist/hono/index.mjs +10 -2
  68. package/dist/hono/index.mjs.map +1 -1
  69. package/dist/{http-B6YgAhyN.mjs → http-Bept5EIC.mjs} +2 -2
  70. package/dist/{http-B6YgAhyN.mjs.map → http-Bept5EIC.mjs.map} +1 -1
  71. package/dist/http.d.mts +1 -1
  72. package/dist/{index-ZSRQP_BI.d.mts → index-CE7kH0II.d.mts} +15 -8
  73. package/dist/index-CE7kH0II.d.mts.map +1 -0
  74. package/dist/index.d.mts +9 -9
  75. package/dist/index.mjs +9 -15
  76. package/dist/index.mjs.map +1 -1
  77. package/dist/{integration-Dhig7ae6.mjs → integration-CR601uyW.mjs} +3 -3
  78. package/dist/{integration-Dhig7ae6.mjs.map → integration-CR601uyW.mjs.map} +1 -1
  79. package/dist/{logger-CTcvd5Cc.d.mts → logger-BccCJUyD.d.mts} +8 -4
  80. package/dist/logger-BccCJUyD.d.mts.map +1 -0
  81. package/dist/logger.d.mts +2 -2
  82. package/dist/logger.mjs +2 -2
  83. package/dist/{middleware-31KhtiEF.d.mts → middleware-DQ6-h8h0.d.mts} +9 -2
  84. package/dist/middleware-DQ6-h8h0.d.mts.map +1 -0
  85. package/dist/nestjs/index.d.mts +2 -2
  86. package/dist/nestjs/index.mjs +4 -4
  87. package/dist/next/client.d.mts +1 -1
  88. package/dist/next/index.d.mts +4 -4
  89. package/dist/next/index.d.mts.map +1 -1
  90. package/dist/next/index.mjs +35 -37
  91. package/dist/next/index.mjs.map +1 -1
  92. package/dist/next/instrumentation.d.mts +1 -1
  93. package/dist/next/instrumentation.mjs +1 -1
  94. package/dist/nitro/errorHandler.mjs +10 -16
  95. package/dist/nitro/errorHandler.mjs.map +1 -1
  96. package/dist/nitro/module.d.mts +2 -2
  97. package/dist/nitro/module.d.mts.map +1 -1
  98. package/dist/nitro/module.mjs +2 -1
  99. package/dist/nitro/module.mjs.map +1 -1
  100. package/dist/nitro/plugin.mjs +36 -65
  101. package/dist/nitro/plugin.mjs.map +1 -1
  102. package/dist/nitro/v3/errorHandler.d.mts +0 -7
  103. package/dist/nitro/v3/errorHandler.mjs +13 -15
  104. package/dist/nitro/v3/errorHandler.mjs.map +1 -1
  105. package/dist/nitro/v3/index.d.mts +2 -2
  106. package/dist/nitro/v3/module.d.mts +1 -1
  107. package/dist/nitro/v3/module.d.mts.map +1 -1
  108. package/dist/nitro/v3/module.mjs +3 -3
  109. package/dist/nitro/v3/module.mjs.map +1 -1
  110. package/dist/nitro/v3/plugin.mjs +76 -44
  111. package/dist/nitro/v3/plugin.mjs.map +1 -1
  112. package/dist/nitro/v3/useLogger.d.mts +1 -1
  113. package/dist/nitro-ClRZLD1g.mjs +96 -0
  114. package/dist/nitro-ClRZLD1g.mjs.map +1 -0
  115. package/dist/{nitro-BRddgqSb.d.mts → nitro-zCXTylj4.d.mts} +7 -2
  116. package/dist/nitro-zCXTylj4.d.mts.map +1 -0
  117. package/dist/{nitroConfigBridge-NbFn-sIK.mjs → nitroConfigBridge-BkVWnSV3.mjs} +9 -2
  118. package/dist/nitroConfigBridge-BkVWnSV3.mjs.map +1 -0
  119. package/dist/{nodeResponse-BkkionWl.mjs → nodeResponse-CIEEbrNE.mjs} +1 -1
  120. package/dist/{nodeResponse-BkkionWl.mjs.map → nodeResponse-CIEEbrNE.mjs.map} +1 -1
  121. package/dist/nuxt/module.d.mts +6 -1
  122. package/dist/nuxt/module.d.mts.map +1 -1
  123. package/dist/nuxt/module.mjs +11 -4
  124. package/dist/nuxt/module.mjs.map +1 -1
  125. package/dist/orpc/index.d.mts +2 -2
  126. package/dist/orpc/index.d.mts.map +1 -1
  127. package/dist/orpc/index.mjs +5 -4
  128. package/dist/orpc/index.mjs.map +1 -1
  129. package/dist/{package-B23bR3tK.mjs → package-CUhII9DA.mjs} +2 -2
  130. package/dist/package-CUhII9DA.mjs.map +1 -0
  131. package/dist/{parseError-D4PIxEWo.d.mts → parseError-Cagr-Ctc.d.mts} +2 -2
  132. package/dist/parseError-Cagr-Ctc.d.mts.map +1 -0
  133. package/dist/pretty-error-CVVgwlTn.mjs +278 -0
  134. package/dist/pretty-error-CVVgwlTn.mjs.map +1 -0
  135. package/dist/pretty-error-snippet.node-c_bzjg7g.mjs +47 -0
  136. package/dist/pretty-error-snippet.node-c_bzjg7g.mjs.map +1 -0
  137. package/dist/react-router/index.d.mts +2 -2
  138. package/dist/react-router/index.mjs +5 -6
  139. package/dist/react-router/index.mjs.map +1 -1
  140. package/dist/{routes-CnIgYWf8.mjs → routes-4rMzRyTk.mjs} +1 -1
  141. package/dist/{routes-CnIgYWf8.mjs.map → routes-4rMzRyTk.mjs.map} +1 -1
  142. package/dist/runtime/client/log.d.mts +1 -1
  143. package/dist/runtime/server/routes/_evlog/ingest.post.mjs +1 -1
  144. package/dist/runtime/server/useLogger.d.mts +1 -1
  145. package/dist/runtime/utils/parseError.d.mts +2 -2
  146. package/dist/runtime/utils/parseError.mjs +1 -1
  147. package/dist/{severity-R5Egq3qz.mjs → severity-CwXUSHt3.mjs} +1 -1
  148. package/dist/{severity-R5Egq3qz.mjs.map → severity-CwXUSHt3.mjs.map} +1 -1
  149. package/dist/{source-location-Dco0cRTz.mjs → source-location-xkDGiERl.mjs} +1 -1
  150. package/dist/{source-location-Dco0cRTz.mjs.map → source-location-xkDGiERl.mjs.map} +1 -1
  151. package/dist/{storage-BNubsWwz.mjs → storage-7X37OToT.mjs} +1 -1
  152. package/dist/{storage-BNubsWwz.mjs.map → storage-7X37OToT.mjs.map} +1 -1
  153. package/dist/stream.d.mts +1 -1
  154. package/dist/stream.mjs +1 -1
  155. package/dist/streamResponse-CmQ3qUbF.mjs +94 -0
  156. package/dist/streamResponse-CmQ3qUbF.mjs.map +1 -0
  157. package/dist/sveltekit/index.d.mts +2 -2
  158. package/dist/sveltekit/index.d.mts.map +1 -1
  159. package/dist/sveltekit/index.mjs +7 -8
  160. package/dist/sveltekit/index.mjs.map +1 -1
  161. package/dist/toolkit.d.mts +37 -6
  162. package/dist/toolkit.d.mts.map +1 -1
  163. package/dist/toolkit.mjs +15 -14
  164. package/dist/types.d.mts +2 -2
  165. package/dist/{useLogger-CqvH6qOf.d.mts → useLogger-Dv52PDpH.d.mts} +2 -2
  166. package/dist/{useLogger-CqvH6qOf.d.mts.map → useLogger-Dv52PDpH.d.mts.map} +1 -1
  167. package/dist/{utils-DxqvIOyR.d.mts → utils-DmNbZwBZ.d.mts} +11 -3
  168. package/dist/{utils-DxqvIOyR.d.mts.map → utils-DmNbZwBZ.d.mts.map} +1 -1
  169. package/dist/utils.d.mts +2 -2
  170. package/dist/utils.mjs +21 -8
  171. package/dist/utils.mjs.map +1 -1
  172. package/dist/vite/index.d.mts +1 -1
  173. package/dist/vite/index.mjs +1 -1
  174. package/dist/workers.d.mts +1 -1
  175. package/dist/workers.mjs +1 -1
  176. package/package.json +1 -1
  177. package/dist/audit-BUI3af4w.mjs.map +0 -1
  178. package/dist/audit-DVdkntSO.d.mts.map +0 -1
  179. package/dist/define-D-BVMf2l.d.mts.map +0 -1
  180. package/dist/define-D6OJdSUH.mjs.map +0 -1
  181. package/dist/fork-Bga8x-X4.mjs.map +0 -1
  182. package/dist/index-ZSRQP_BI.d.mts.map +0 -1
  183. package/dist/logger-CTcvd5Cc.d.mts.map +0 -1
  184. package/dist/middleware-31KhtiEF.d.mts.map +0 -1
  185. package/dist/nitro-BRddgqSb.d.mts.map +0 -1
  186. package/dist/nitro-DErMq_Zj.mjs +0 -34
  187. package/dist/nitro-DErMq_Zj.mjs.map +0 -1
  188. package/dist/nitroConfigBridge-NbFn-sIK.mjs.map +0 -1
  189. package/dist/package-B23bR3tK.mjs.map +0 -1
  190. package/dist/parseError-D4PIxEWo.d.mts.map +0 -1
@@ -0,0 +1,278 @@
1
+ import { colors, isBrowser, isDev } from "./utils.mjs";
2
+ //#region src/shared/pretty-error.ts
3
+ let snippetReader = null;
4
+ /**
5
+ * Register a disk-backed snippet reader (Node.js integrations only).
6
+ * @internal
7
+ */
8
+ function registerPrettyErrorSnippetReader(reader) {
9
+ snippetReader = reader;
10
+ }
11
+ /** Tree-only breathing line (connector without content). */
12
+ const PRETTY_ERROR_TREE_SPACER = "__EVLOG_TREE_SPACER__";
13
+ function pushTreeSpacer(children) {
14
+ children.push(PRETTY_ERROR_TREE_SPACER);
15
+ }
16
+ const SKIP_PATH_RE = /(?:^|[/\\])(?:node_modules|\.nuxt|\.output)(?:[/\\]|$)/;
17
+ const SKIP_FRAME_PATH_RE = /(?:^|[/\\])(?:packages[/\\]evlog|evlog[/\\](?:dist|src))(?:[/\\]|$)/;
18
+ const SKIP_FRAME_FN_RE = /^(?:createError|EvlogError|new EvlogError)$/;
19
+ function isPlainObject(val) {
20
+ return val !== null && typeof val === "object" && !Array.isArray(val);
21
+ }
22
+ function pickString(obj, key) {
23
+ const val = obj[key];
24
+ return typeof val === "string" && val.length > 0 ? val : void 0;
25
+ }
26
+ function pickNumber(obj, key) {
27
+ const val = obj[key];
28
+ return typeof val === "number" ? val : void 0;
29
+ }
30
+ function extractGuidance(data) {
31
+ return {
32
+ code: pickString(data, "code"),
33
+ why: pickString(data, "why"),
34
+ fix: pickString(data, "fix"),
35
+ link: pickString(data, "link")
36
+ };
37
+ }
38
+ /**
39
+ * Extract structured error fields from a wide-event `error` value.
40
+ */
41
+ function normalizeErrorContext(error) {
42
+ if (error === null || error === void 0) return null;
43
+ if (typeof error === "string") return { message: error };
44
+ if (!isPlainObject(error)) return { message: String(error) };
45
+ const result = {
46
+ message: pickString(error, "message") ?? pickString(error, "statusText") ?? pickString(error, "statusMessage") ?? "Unknown error",
47
+ name: pickString(error, "name"),
48
+ code: pickString(error, "code"),
49
+ why: pickString(error, "why"),
50
+ fix: pickString(error, "fix"),
51
+ link: pickString(error, "link"),
52
+ status: pickNumber(error, "status") ?? pickNumber(error, "statusCode"),
53
+ stack: pickString(error, "stack")
54
+ };
55
+ const { data, cause } = error;
56
+ if (isPlainObject(data)) {
57
+ const guidance = extractGuidance(data);
58
+ if (!result.code) result.code = guidance.code;
59
+ if (!result.why) result.why = guidance.why;
60
+ if (!result.fix) result.fix = guidance.fix;
61
+ if (!result.link) result.link = guidance.link;
62
+ }
63
+ if (cause instanceof Error) result.cause = cause.message;
64
+ else if (isPlainObject(cause) && pickString(cause, "message")) result.cause = pickString(cause, "message");
65
+ return result;
66
+ }
67
+ /** Decode a `file://` URL or path for display and snippet lookup. */
68
+ function decodeFileUrl(file) {
69
+ if (file.startsWith("file://")) try {
70
+ return decodeURIComponent(new URL(file).pathname);
71
+ } catch {
72
+ return file.slice(7);
73
+ }
74
+ return file;
75
+ }
76
+ function isAppPath(file) {
77
+ const normalized = file.replace(/\\/g, "/");
78
+ if (SKIP_PATH_RE.test(normalized)) return false;
79
+ if (normalized.includes("/node_modules/")) return false;
80
+ return true;
81
+ }
82
+ function formatDisplayPath(file, cwd) {
83
+ const decoded = decodeFileUrl(file).replace(/\\/g, "/");
84
+ const cwdNorm = cwd.replace(/\\/g, "/").replace(/\/$/, "");
85
+ if (cwdNorm && decoded.startsWith(`${cwdNorm}/`)) {
86
+ const rel = decoded.slice(cwdNorm.length + 1);
87
+ return rel.startsWith("./") ? rel.slice(2) : rel;
88
+ }
89
+ const serverIdx = decoded.indexOf("/server/");
90
+ if (serverIdx >= 0) return decoded.slice(serverIdx + 1);
91
+ const srcIdx = decoded.indexOf("/src/");
92
+ if (srcIdx >= 0) return decoded.slice(srcIdx + 1);
93
+ return decoded;
94
+ }
95
+ /**
96
+ * Parse a V8 stack trace string into frames.
97
+ */
98
+ function parseStackFrames(stack) {
99
+ if (!stack) return [];
100
+ const lines = stack.split("\n");
101
+ const frames = [];
102
+ for (const line of lines) {
103
+ const trimmed = line.trim();
104
+ if (!trimmed.startsWith("at ")) continue;
105
+ const withFn = trimmed.match(/^at (.+?) \((.+):(\d+):(\d+)\)$/);
106
+ if (withFn) {
107
+ const [, fn, file, lineStr, colStr] = withFn;
108
+ frames.push({
109
+ raw: trimmed,
110
+ fn,
111
+ file,
112
+ line: Number(lineStr),
113
+ column: Number(colStr),
114
+ isApp: isAppPath(file)
115
+ });
116
+ continue;
117
+ }
118
+ const withoutFn = trimmed.match(/^at (.+):(\d+):(\d+)$/);
119
+ if (withoutFn) {
120
+ const [, file, lineStr, colStr] = withoutFn;
121
+ frames.push({
122
+ raw: trimmed,
123
+ file,
124
+ line: Number(lineStr),
125
+ column: Number(colStr),
126
+ isApp: isAppPath(file)
127
+ });
128
+ continue;
129
+ }
130
+ const asyncFn = trimmed.match(/^at async (.+?) \((.+):(\d+):(\d+)\)$/);
131
+ if (asyncFn) {
132
+ const [, fn, file, lineStr, colStr] = asyncFn;
133
+ frames.push({
134
+ raw: trimmed,
135
+ fn: `async ${fn}`,
136
+ file,
137
+ line: Number(lineStr),
138
+ column: Number(colStr),
139
+ isApp: isAppPath(file)
140
+ });
141
+ }
142
+ }
143
+ return frames;
144
+ }
145
+ function isInternalErrorFrame(frame) {
146
+ if (frame.fn) {
147
+ const fn = frame.fn.replace(/^async /, "");
148
+ if (SKIP_FRAME_FN_RE.test(fn)) return true;
149
+ }
150
+ if (!frame.file) return true;
151
+ const path = decodeFileUrl(frame.file).replace(/\\/g, "/");
152
+ if (SKIP_FRAME_PATH_RE.test(path)) return true;
153
+ if (path.includes(".nuxt/")) return true;
154
+ return false;
155
+ }
156
+ /**
157
+ * Pick the most useful frame for code snippets (prefer app source over bundles).
158
+ */
159
+ function pickPrimaryFrame(frames) {
160
+ const appFrames = frames.filter((f) => f.isApp && f.file && f.line && !isInternalErrorFrame(f));
161
+ if (appFrames.length === 0) return void 0;
162
+ const scored = appFrames.map((frame) => {
163
+ const path = decodeFileUrl(frame.file).replace(/\\/g, "/");
164
+ let score = 0;
165
+ if (path.includes("/server/")) score += 8;
166
+ if (/\.(?:ts|tsx|vue)$/.test(path)) score += 6;
167
+ if (path.includes("/src/")) score += 3;
168
+ if (path.startsWith("./")) score += 2;
169
+ if (/\.(?:js|jsx|mjs)$/.test(path)) score += 1;
170
+ if (path.includes(".nuxt/")) score -= 20;
171
+ if (path.includes("/packages/evlog/")) score -= 20;
172
+ return {
173
+ frame,
174
+ score
175
+ };
176
+ });
177
+ scored.sort((a, b) => b.score - a.score);
178
+ return scored[0]?.frame ?? appFrames[0];
179
+ }
180
+ /**
181
+ * Read source lines around a stack frame when a server snippet reader is registered.
182
+ */
183
+ function readCodeSnippet(file, line, contextLines = 2) {
184
+ if (!isDev() || isBrowser() || !snippetReader) return null;
185
+ return snippetReader(file, line, contextLines);
186
+ }
187
+ function formatSnippetLines(snippet) {
188
+ const width = String(snippet[snippet.length - 1]?.line ?? 0).length;
189
+ return snippet.map(({ line, content, isErrorLine }) => {
190
+ const marker = isErrorLine ? `${colors.red}❯${colors.reset}` : `${colors.dim} ${colors.reset}`;
191
+ const numColor = isErrorLine ? colors.red : colors.gray;
192
+ const trimmed = content.length > 120 ? `${content.slice(0, 117)}…` : content;
193
+ return `${marker} ${numColor}${String(line).padStart(width, " ")}${colors.reset} ${colors.dim}┃${colors.reset} ${colors.dim}${trimmed}${colors.reset}`;
194
+ });
195
+ }
196
+ function formatFrameLocation(frame, cwd) {
197
+ const file = frame.file ? formatDisplayPath(frame.file, cwd) : "unknown";
198
+ const loc = frame.line ? `${file}:${frame.line}` : file;
199
+ return frame.fn ? `at ${frame.fn} (${loc})` : `at ${loc}`;
200
+ }
201
+ function formatCollapsedFrame(frame, cwd) {
202
+ const file = frame.file ? formatDisplayPath(frame.file, cwd) : "unknown";
203
+ const loc = frame.line ? `${file}:${frame.line}` : file;
204
+ const prefix = frame.fn?.startsWith("async") ? "at async " : "at ";
205
+ const fn = frame.fn?.replace(/^async /, "") ?? loc;
206
+ if (frame.fn && frame.fn !== loc) return `${prefix}${fn} (${loc})`;
207
+ return `${prefix}${loc}`;
208
+ }
209
+ const GUIDANCE_WRAP_WIDTH = 76;
210
+ const GUIDANCE_CONTINUATION = " ";
211
+ /** Wrap guidance text with hanging indent for long Why/Fix lines. */
212
+ function formatGuidanceLine(label, text, labelColor) {
213
+ const prefix = `${labelColor}${label}:${colors.reset} `;
214
+ const lines = [];
215
+ let remaining = text.trim();
216
+ let first = true;
217
+ while (remaining.length > 0) {
218
+ const budget = first ? Math.max(24, GUIDANCE_WRAP_WIDTH - prefix.length) : Math.max(24, GUIDANCE_WRAP_WIDTH - 5);
219
+ if (remaining.length <= budget) {
220
+ lines.push(first ? `${prefix}${remaining}` : `${GUIDANCE_CONTINUATION}${remaining}`);
221
+ break;
222
+ }
223
+ let split = remaining.lastIndexOf(" ", budget);
224
+ if (split <= 0) split = budget;
225
+ const chunk = remaining.slice(0, split).trimEnd();
226
+ lines.push(first ? `${prefix}${chunk}` : `${GUIDANCE_CONTINUATION}${chunk}`);
227
+ remaining = remaining.slice(split).trimStart();
228
+ first = false;
229
+ }
230
+ return lines;
231
+ }
232
+ /**
233
+ * Build pretty-print tree entries for a wide-event `error` field.
234
+ */
235
+ function buildErrorEntries(error, options = {}) {
236
+ const normalized = normalizeErrorContext(error);
237
+ if (!normalized) return [];
238
+ const cwd = options.cwd ?? (typeof process !== "undefined" && typeof process.cwd === "function" ? process.cwd() : ".");
239
+ const compact = options.compact ?? isDev();
240
+ const guidanceOnly = (options.detail ?? "full") === "guidance";
241
+ const showFrames = !guidanceOnly && !isBrowser() && (options.snippet ?? isDev());
242
+ const stackDepth = guidanceOnly ? 0 : options.stackDepth ?? (compact ? 2 : 3);
243
+ const snippetContextLines = compact ? 1 : 2;
244
+ const children = [];
245
+ const frames = guidanceOnly ? [] : parseStackFrames(normalized.stack);
246
+ const primary = guidanceOnly ? void 0 : pickPrimaryFrame(frames);
247
+ if (!guidanceOnly && primary?.file && primary.line) {
248
+ pushTreeSpacer(children);
249
+ if (showFrames) {
250
+ const snippet = readCodeSnippet(primary.file, primary.line, snippetContextLines);
251
+ children.push(`${colors.dim} ${formatFrameLocation(primary, cwd)}${colors.reset}`);
252
+ if (snippet) children.push(...formatSnippetLines(snippet));
253
+ } else children.push(`${colors.dim} ${formatFrameLocation(primary, cwd)}${colors.reset}`);
254
+ }
255
+ if (normalized.code) children.push(`${colors.dim}Code:${colors.reset} ${normalized.code}`);
256
+ if (Boolean(normalized.why || normalized.fix || normalized.link)) pushTreeSpacer(children);
257
+ if (normalized.why) children.push(...formatGuidanceLine("Why", normalized.why, colors.yellow));
258
+ if (normalized.fix) children.push(...formatGuidanceLine("Fix", normalized.fix, colors.cyan));
259
+ if (normalized.link) children.push(`${colors.dim}More:${colors.reset} ${normalized.link}`);
260
+ if (normalized.cause && normalized.cause !== normalized.message) children.push(`${colors.dim}Caused by:${colors.reset} ${normalized.cause}`);
261
+ const hiddenCount = guidanceOnly ? 0 : frames.filter((f) => !f.isApp || isInternalErrorFrame(f)).length;
262
+ const tailFrames = stackDepth > 0 ? frames.filter((f) => f !== primary && !isInternalErrorFrame(f)).slice(0, stackDepth) : [];
263
+ if (!guidanceOnly && (hiddenCount > 0 || tailFrames.length > 0)) {
264
+ pushTreeSpacer(children);
265
+ if (hiddenCount > 0) children.push(`${colors.gray}stack (${hiddenCount} frame${hiddenCount === 1 ? "" : "s"} hidden in node_modules)${colors.reset}`);
266
+ else children.push(`${colors.gray}stack${colors.reset}`);
267
+ for (const frame of tailFrames) children.push(`${colors.gray} ${formatCollapsedFrame(frame, cwd)}${colors.reset}`);
268
+ }
269
+ return [{
270
+ key: "error",
271
+ value: `${colors.red}${colors.bold}${normalized.message}${colors.reset}`,
272
+ children: children.length > 0 ? children : void 0
273
+ }];
274
+ }
275
+ //#endregion
276
+ export { registerPrettyErrorSnippetReader as i, buildErrorEntries as n, decodeFileUrl as r, PRETTY_ERROR_TREE_SPACER as t };
277
+
278
+ //# sourceMappingURL=pretty-error-CVVgwlTn.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pretty-error-CVVgwlTn.mjs","names":[],"sources":["../src/shared/pretty-error.ts"],"sourcesContent":["import { colors, isBrowser, isDev } from '../utils'\nimport type { ResolvedPrettyError } from './dev-terminal'\n\n/** @internal Server-only snippet reader registered by Nitro plugin or initLogger. */\ntype SnippetReader = (file: string, line: number, contextLines?: number) => CodeSnippetLine[] | null\n\nlet snippetReader: SnippetReader | null = null\n\n/**\n * Register a disk-backed snippet reader (Node.js integrations only).\n * @internal\n */\nexport function registerPrettyErrorSnippetReader(reader: SnippetReader | null): void {\n snippetReader = reader\n}\n\n/** Tree-only breathing line (connector without content). */\nexport const PRETTY_ERROR_TREE_SPACER = '__EVLOG_TREE_SPACER__'\n\nfunction pushTreeSpacer(children: string[]) {\n children.push(PRETTY_ERROR_TREE_SPACER)\n}\n\n/** Pretty-print tree node for error sections. */\nexport interface PrettyErrorTreeEntry {\n key: string\n value: string\n /** Optional ANSI color for the value (server only). */\n valueColor?: string\n children?: string[]\n}\n\n/** Normalized error fields extracted from wide-event `error` context. */\nexport interface NormalizedErrorContext {\n message: string\n name?: string\n code?: string\n why?: string\n fix?: string\n link?: string\n status?: number\n stack?: string\n cause?: string\n}\n\n/** Parsed V8 stack frame. */\nexport interface StackFrame {\n raw: string\n file?: string\n line?: number\n column?: number\n fn?: string\n /** True for application source (not node_modules / build output). */\n isApp: boolean\n}\n\n/** Options for {@link buildErrorEntries}. */\nexport type PrettyErrorOptions = Partial<ResolvedPrettyError> & {\n /** Project root for relative paths in snippets. @default process.cwd() */\n cwd?: string\n}\n\nexport interface CodeSnippetLine {\n line: number\n content: string\n isErrorLine: boolean\n}\n\nconst SKIP_PATH_RE = /(?:^|[/\\\\])(?:node_modules|\\.nuxt|\\.output)(?:[/\\\\]|$)/\nconst SKIP_FRAME_PATH_RE = /(?:^|[/\\\\])(?:packages[/\\\\]evlog|evlog[/\\\\](?:dist|src))(?:[/\\\\]|$)/\nconst SKIP_FRAME_FN_RE = /^(?:createError|EvlogError|new EvlogError)$/\n\nfunction isPlainObject(val: unknown): val is Record<string, unknown> {\n return val !== null && typeof val === 'object' && !Array.isArray(val)\n}\n\nfunction pickString(obj: Record<string, unknown>, key: string): string | undefined {\n const val = obj[key]\n return typeof val === 'string' && val.length > 0 ? val : undefined\n}\n\nfunction pickNumber(obj: Record<string, unknown>, key: string): number | undefined {\n const val = obj[key]\n return typeof val === 'number' ? val : undefined\n}\n\nfunction extractGuidance(data: Record<string, unknown>): Pick<NormalizedErrorContext, 'code' | 'why' | 'fix' | 'link'> {\n return {\n code: pickString(data, 'code'),\n why: pickString(data, 'why'),\n fix: pickString(data, 'fix'),\n link: pickString(data, 'link'),\n }\n}\n\n/**\n * Extract structured error fields from a wide-event `error` value.\n */\nexport function normalizeErrorContext(error: unknown): NormalizedErrorContext | null {\n if (error === null || error === undefined) return null\n\n if (typeof error === 'string') {\n return { message: error }\n }\n\n if (!isPlainObject(error)) {\n return { message: String(error) }\n }\n\n const message = pickString(error, 'message')\n ?? pickString(error, 'statusText')\n ?? pickString(error, 'statusMessage')\n ?? 'Unknown error'\n\n const result: NormalizedErrorContext = {\n message,\n name: pickString(error, 'name'),\n code: pickString(error, 'code'),\n why: pickString(error, 'why'),\n fix: pickString(error, 'fix'),\n link: pickString(error, 'link'),\n status: pickNumber(error, 'status') ?? pickNumber(error, 'statusCode'),\n stack: pickString(error, 'stack'),\n }\n\n const { data, cause } = error\n if (isPlainObject(data)) {\n const guidance = extractGuidance(data)\n if (!result.code) result.code = guidance.code\n if (!result.why) result.why = guidance.why\n if (!result.fix) result.fix = guidance.fix\n if (!result.link) result.link = guidance.link\n }\n\n if (cause instanceof Error) {\n result.cause = cause.message\n } else if (isPlainObject(cause) && pickString(cause, 'message')) {\n result.cause = pickString(cause, 'message')\n }\n\n return result\n}\n\n/** Decode a `file://` URL or path for display and snippet lookup. */\nexport function decodeFileUrl(file: string): string {\n if (file.startsWith('file://')) {\n try {\n return decodeURIComponent(new URL(file).pathname)\n } catch {\n return file.slice('file://'.length)\n }\n }\n return file\n}\n\nfunction isAppPath(file: string): boolean {\n const normalized = file.replace(/\\\\/g, '/')\n if (SKIP_PATH_RE.test(normalized)) return false\n if (normalized.includes('/node_modules/')) return false\n return true\n}\n\nfunction formatDisplayPath(file: string, cwd: string): string {\n const decoded = decodeFileUrl(file).replace(/\\\\/g, '/')\n const cwdNorm = cwd.replace(/\\\\/g, '/').replace(/\\/$/, '')\n if (cwdNorm && decoded.startsWith(`${cwdNorm}/`)) {\n const rel = decoded.slice(cwdNorm.length + 1)\n return rel.startsWith('./') ? rel.slice(2) : rel\n }\n const serverIdx = decoded.indexOf('/server/')\n if (serverIdx >= 0) return decoded.slice(serverIdx + 1)\n const srcIdx = decoded.indexOf('/src/')\n if (srcIdx >= 0) return decoded.slice(srcIdx + 1)\n return decoded\n}\n\n/**\n * Parse a V8 stack trace string into frames.\n */\nexport function parseStackFrames(stack: string | undefined): StackFrame[] {\n if (!stack) return []\n\n const lines = stack.split('\\n')\n const frames: StackFrame[] = []\n\n for (const line of lines) {\n const trimmed = line.trim()\n if (!trimmed.startsWith('at ')) continue\n\n const withFn = trimmed.match(/^at (.+?) \\((.+):(\\d+):(\\d+)\\)$/)\n if (withFn) {\n const [, fn, file, lineStr, colStr] = withFn\n frames.push({\n raw: trimmed,\n fn,\n file,\n line: Number(lineStr),\n column: Number(colStr),\n isApp: isAppPath(file!),\n })\n continue\n }\n\n const withoutFn = trimmed.match(/^at (.+):(\\d+):(\\d+)$/)\n if (withoutFn) {\n const [, file, lineStr, colStr] = withoutFn\n frames.push({\n raw: trimmed,\n file,\n line: Number(lineStr),\n column: Number(colStr),\n isApp: isAppPath(file!),\n })\n continue\n }\n\n const asyncFn = trimmed.match(/^at async (.+?) \\((.+):(\\d+):(\\d+)\\)$/)\n if (asyncFn) {\n const [, fn, file, lineStr, colStr] = asyncFn\n frames.push({\n raw: trimmed,\n fn: `async ${fn}`,\n file,\n line: Number(lineStr),\n column: Number(colStr),\n isApp: isAppPath(file!),\n })\n }\n }\n\n return frames\n}\n\nfunction isInternalErrorFrame(frame: StackFrame): boolean {\n if (frame.fn) {\n const fn = frame.fn.replace(/^async /, '')\n if (SKIP_FRAME_FN_RE.test(fn)) return true\n }\n if (!frame.file) return true\n const path = decodeFileUrl(frame.file).replace(/\\\\/g, '/')\n if (SKIP_FRAME_PATH_RE.test(path)) return true\n if (path.includes('.nuxt/')) return true\n return false\n}\n\n/**\n * Pick the most useful frame for code snippets (prefer app source over bundles).\n */\nexport function pickPrimaryFrame(frames: StackFrame[]): StackFrame | undefined {\n const appFrames = frames.filter(f => f.isApp && f.file && f.line && !isInternalErrorFrame(f))\n if (appFrames.length === 0) return undefined\n\n const scored = appFrames.map((frame) => {\n const path = decodeFileUrl(frame.file!).replace(/\\\\/g, '/')\n let score = 0\n if (path.includes('/server/')) score += 8\n if (/\\.(?:ts|tsx|vue)$/.test(path)) score += 6\n if (path.includes('/src/')) score += 3\n if (path.startsWith('./')) score += 2\n if (/\\.(?:js|jsx|mjs)$/.test(path)) score += 1\n if (path.includes('.nuxt/')) score -= 20\n if (path.includes('/packages/evlog/')) score -= 20\n return { frame, score }\n })\n\n scored.sort((a, b) => b.score - a.score)\n return scored[0]?.frame ?? appFrames[0]\n}\n\n/**\n * Read source lines around a stack frame when a server snippet reader is registered.\n */\nexport function readCodeSnippet(\n file: string,\n line: number,\n contextLines = 2,\n): CodeSnippetLine[] | null {\n if (!isDev() || isBrowser() || !snippetReader) return null\n return snippetReader(file, line, contextLines)\n}\n\nfunction formatSnippetLines(snippet: CodeSnippetLine[]): string[] {\n const width = String(snippet[snippet.length - 1]?.line ?? 0).length\n return snippet.map(({ line, content, isErrorLine }) => {\n const marker = isErrorLine ? `${colors.red}❯${colors.reset}` : `${colors.dim} ${colors.reset}`\n const numColor = isErrorLine ? colors.red : colors.gray\n const trimmed = content.length > 120 ? `${content.slice(0, 117)}…` : content\n return `${marker} ${numColor}${String(line).padStart(width, ' ')}${colors.reset} ${colors.dim}┃${colors.reset} ${colors.dim}${trimmed}${colors.reset}`\n })\n}\n\nfunction formatFrameLocation(frame: StackFrame, cwd: string): string {\n const file = frame.file ? formatDisplayPath(frame.file, cwd) : 'unknown'\n const loc = frame.line ? `${file}:${frame.line}` : file\n return frame.fn ? `at ${frame.fn} (${loc})` : `at ${loc}`\n}\n\nfunction formatCollapsedFrame(frame: StackFrame, cwd: string): string {\n const file = frame.file ? formatDisplayPath(frame.file, cwd) : 'unknown'\n const loc = frame.line ? `${file}:${frame.line}` : file\n const prefix = frame.fn?.startsWith('async') ? 'at async ' : 'at '\n const fn = frame.fn?.replace(/^async /, '') ?? loc\n if (frame.fn && frame.fn !== loc) {\n return `${prefix}${fn} (${loc})`\n }\n return `${prefix}${loc}`\n}\n\nconst GUIDANCE_WRAP_WIDTH = 76\nconst GUIDANCE_CONTINUATION = ' '\n\n/** Wrap guidance text with hanging indent for long Why/Fix lines. */\nfunction formatGuidanceLine(label: string, text: string, labelColor: string): string[] {\n const prefix = `${labelColor}${label}:${colors.reset} `\n const lines: string[] = []\n let remaining = text.trim()\n let first = true\n\n while (remaining.length > 0) {\n const budget = first\n ? Math.max(24, GUIDANCE_WRAP_WIDTH - prefix.length)\n : Math.max(24, GUIDANCE_WRAP_WIDTH - GUIDANCE_CONTINUATION.length)\n if (remaining.length <= budget) {\n lines.push(first ? `${prefix}${remaining}` : `${GUIDANCE_CONTINUATION}${remaining}`)\n break\n }\n let split = remaining.lastIndexOf(' ', budget)\n if (split <= 0) split = budget\n const chunk = remaining.slice(0, split).trimEnd()\n lines.push(first ? `${prefix}${chunk}` : `${GUIDANCE_CONTINUATION}${chunk}`)\n remaining = remaining.slice(split).trimStart()\n first = false\n }\n\n return lines\n}\n\n/**\n * Build pretty-print tree entries for a wide-event `error` field.\n */\nexport function buildErrorEntries(\n error: unknown,\n options: PrettyErrorOptions = {},\n): PrettyErrorTreeEntry[] {\n const normalized = normalizeErrorContext(error)\n if (!normalized) return []\n\n const cwd = options.cwd ?? (typeof process !== 'undefined' && typeof process.cwd === 'function' ? process.cwd() : '.')\n const compact = options.compact ?? isDev()\n const detail = options.detail ?? 'full'\n const guidanceOnly = detail === 'guidance'\n const showFrames = !guidanceOnly && !isBrowser() && (options.snippet ?? isDev())\n const stackDepth = guidanceOnly\n ? 0\n : (options.stackDepth ?? (compact ? 2 : 3))\n const snippetContextLines = compact ? 1 : 2\n\n const children: string[] = []\n const frames = guidanceOnly ? [] : parseStackFrames(normalized.stack)\n const primary = guidanceOnly ? undefined : pickPrimaryFrame(frames)\n\n if (!guidanceOnly && primary?.file && primary.line) {\n pushTreeSpacer(children)\n if (showFrames) {\n const snippet = readCodeSnippet(primary.file, primary.line, snippetContextLines)\n children.push(`${colors.dim} ${formatFrameLocation(primary, cwd)}${colors.reset}`)\n if (snippet) {\n children.push(...formatSnippetLines(snippet))\n }\n } else {\n children.push(`${colors.dim} ${formatFrameLocation(primary, cwd)}${colors.reset}`)\n }\n }\n\n if (normalized.code) {\n children.push(`${colors.dim}Code:${colors.reset} ${normalized.code}`)\n }\n\n const hasGuidance = Boolean(normalized.why || normalized.fix || normalized.link)\n if (hasGuidance) {\n pushTreeSpacer(children)\n }\n\n if (normalized.why) {\n children.push(...formatGuidanceLine('Why', normalized.why, colors.yellow))\n }\n if (normalized.fix) {\n children.push(...formatGuidanceLine('Fix', normalized.fix, colors.cyan))\n }\n if (normalized.link) {\n children.push(`${colors.dim}More:${colors.reset} ${normalized.link}`)\n }\n\n if (normalized.cause && normalized.cause !== normalized.message) {\n children.push(`${colors.dim}Caused by:${colors.reset} ${normalized.cause}`)\n }\n\n const hiddenCount = guidanceOnly ? 0 : frames.filter(f => !f.isApp || isInternalErrorFrame(f)).length\n const tailFrames = stackDepth > 0\n ? frames.filter(f => f !== primary && !isInternalErrorFrame(f)).slice(0, stackDepth)\n : []\n\n if (!guidanceOnly && (hiddenCount > 0 || tailFrames.length > 0)) {\n pushTreeSpacer(children)\n if (hiddenCount > 0) {\n children.push(`${colors.gray}stack (${hiddenCount} frame${hiddenCount === 1 ? '' : 's'} hidden in node_modules)${colors.reset}`)\n } else {\n children.push(`${colors.gray}stack${colors.reset}`)\n }\n for (const frame of tailFrames) {\n children.push(`${colors.gray} ${formatCollapsedFrame(frame, cwd)}${colors.reset}`)\n }\n }\n\n return [\n {\n key: 'error',\n value: `${colors.red}${colors.bold}${normalized.message}${colors.reset}`,\n children: children.length > 0 ? children : undefined,\n },\n ]\n}\n"],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ import { r as decodeFileUrl } from "./pretty-error-CVVgwlTn.mjs";
2
+ import { resolve } from "node:path";
3
+ import { readFileSync } from "node:fs";
4
+ //#region \0rolldown/runtime.js
5
+ var __defProp = Object.defineProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ return target;
14
+ };
15
+ //#endregion
16
+ //#region src/shared/pretty-error-snippet.node.ts
17
+ var pretty_error_snippet_node_exports = /* @__PURE__ */ __exportAll({ readCodeSnippetFromDisk: () => readCodeSnippetFromDisk });
18
+ /**
19
+ * Read source lines around a stack frame from disk (Node.js only).
20
+ */
21
+ function readCodeSnippetFromDisk(file, line, contextLines = 2) {
22
+ const decoded = decodeFileUrl(file);
23
+ let content;
24
+ try {
25
+ content = readFileSync(decoded, "utf8");
26
+ } catch {
27
+ try {
28
+ content = readFileSync(resolve(process.cwd(), decoded), "utf8");
29
+ } catch {
30
+ return null;
31
+ }
32
+ }
33
+ const lines = content.split("\n");
34
+ const start = Math.max(0, line - contextLines - 1);
35
+ const end = Math.min(lines.length, line + contextLines);
36
+ const snippet = [];
37
+ for (let i = start; i < end; i++) snippet.push({
38
+ line: i + 1,
39
+ content: lines[i] ?? "",
40
+ isErrorLine: i + 1 === line
41
+ });
42
+ return snippet.length > 0 ? snippet : null;
43
+ }
44
+ //#endregion
45
+ export { readCodeSnippetFromDisk as n, pretty_error_snippet_node_exports as t };
46
+
47
+ //# sourceMappingURL=pretty-error-snippet.node-c_bzjg7g.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pretty-error-snippet.node-c_bzjg7g.mjs","names":[],"sources":["../src/shared/pretty-error-snippet.node.ts"],"sourcesContent":["import { readFileSync } from 'node:fs'\nimport { resolve } from 'node:path'\nimport type { CodeSnippetLine } from './pretty-error'\nimport { decodeFileUrl } from './pretty-error'\n\n/**\n * Read source lines around a stack frame from disk (Node.js only).\n */\nexport function readCodeSnippetFromDisk(\n file: string,\n line: number,\n contextLines = 2,\n): CodeSnippetLine[] | null {\n const decoded = decodeFileUrl(file)\n let content: string\n try {\n content = readFileSync(decoded, 'utf8')\n } catch {\n try {\n content = readFileSync(resolve(process.cwd(), decoded), 'utf8')\n } catch {\n return null\n }\n }\n\n const lines = content.split('\\n')\n const start = Math.max(0, line - contextLines - 1)\n const end = Math.min(lines.length, line + contextLines)\n const snippet: CodeSnippetLine[] = []\n\n for (let i = start; i < end; i++) {\n snippet.push({\n line: i + 1,\n content: lines[i] ?? '',\n isErrorLine: i + 1 === line,\n })\n }\n\n return snippet.length > 0 ? snippet : null\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAQA,SAAgB,wBACd,MACA,MACA,eAAe,GACW;CAC1B,MAAM,UAAU,cAAc,KAAK;CACnC,IAAI;AACJ,KAAI;AACF,YAAU,aAAa,SAAS,OAAO;SACjC;AACN,MAAI;AACF,aAAU,aAAa,QAAQ,QAAQ,KAAK,EAAE,QAAQ,EAAE,OAAO;UACzD;AACN,UAAO;;;CAIX,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,eAAe,EAAE;CAClD,MAAM,MAAM,KAAK,IAAI,MAAM,QAAQ,OAAO,aAAa;CACvD,MAAM,UAA6B,EAAE;AAErC,MAAK,IAAI,IAAI,OAAO,IAAI,KAAK,IAC3B,SAAQ,KAAK;EACX,MAAM,IAAI;EACV,SAAS,MAAM,MAAM;EACrB,aAAa,IAAI,MAAM;EACxB,CAAC;AAGJ,QAAO,QAAQ,SAAS,IAAI,UAAU"}
@@ -1,5 +1,5 @@
1
- import { $ as RequestLogger } from "../audit-DVdkntSO.mjs";
2
- import { t as BaseEvlogOptions } from "../middleware-31KhtiEF.mjs";
1
+ import { rt as RequestLogger } from "../audit-BUAajsPU.mjs";
2
+ import { t as BaseEvlogOptions } from "../middleware-DQ6-h8h0.mjs";
3
3
  import * as _$react_router0 from "react-router";
4
4
 
5
5
  //#region src/react-router/index.d.ts
@@ -1,6 +1,6 @@
1
- import { t as extractSafeHeaders } from "../headers-CU-QqnYg.mjs";
2
- import { r as createMiddlewareLogger, t as attachForkToLogger } from "../fork-Bga8x-X4.mjs";
3
- import { t as createLoggerStorage } from "../storage-BNubsWwz.mjs";
1
+ import { t as extractSafeHeaders } from "../headers-VtmnWcfn.mjs";
2
+ import { r as createMiddlewareLogger, t as attachForkToLogger } from "../fork-CYm453dq.mjs";
3
+ import { t as createLoggerStorage } from "../storage-7X37OToT.mjs";
4
4
  import { createContext } from "react-router";
5
5
  //#region src/react-router/index.ts
6
6
  const { storage, useLogger } = createLoggerStorage("middleware context. Make sure the evlog middleware is added to your route.");
@@ -42,14 +42,13 @@ function evlog(options = {}) {
42
42
  headers: extractSafeHeaders(request.headers),
43
43
  ...options
44
44
  };
45
- const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts);
45
+ const { logger, finish, finishResponse, skipped } = createMiddlewareLogger(middlewareOpts);
46
46
  if (skipped) return next();
47
47
  attachForkToLogger(storage, logger, middlewareOpts);
48
48
  context.set(loggerContext, logger);
49
49
  try {
50
50
  const response = await storage.run(logger, () => next());
51
- await finish({ status: response.status });
52
- return response;
51
+ return finishResponse(response, { status: response.status });
53
52
  } catch (error) {
54
53
  await finish({ error });
55
54
  throw error;
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react-router/index.ts"],"sourcesContent":["import { createContext } from 'react-router'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { attachForkToLogger } from '../shared/fork'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure the evlog middleware is added to your route.',\n)\n\n/**\n * Typed context key for accessing the evlog logger in loaders and actions.\n *\n * @example\n * ```ts\n * import { loggerContext } from 'evlog/react-router'\n *\n * export async function loader({ context }: Route.LoaderArgs) {\n * const log = context.get(loggerContext)\n * log.set({ user: { id: 'u-1' } })\n * return { ok: true }\n * }\n * ```\n */\nexport const loggerContext = createContext<RequestLogger>()\n\nexport type EvlogReactRouterOptions = BaseEvlogOptions\n\nexport { useLogger }\n\n/**\n * Create an evlog middleware for React Router.\n *\n * @example\n * ```ts\n * // app/root.tsx\n * import { evlog } from 'evlog/react-router'\n *\n * export const middleware: Route.MiddlewareFunction[] = [\n * evlog({ drain: createAxiomDrain() }),\n * ]\n * ```\n */\nexport function evlog(options: EvlogReactRouterOptions = {}) {\n return async (\n { request, context }: { request: Request; context: { set(ctx: unknown, value: unknown): void } },\n next: () => Promise<Response>,\n ): Promise<Response> => {\n const url = new URL(request.url)\n const middlewareOpts = {\n method: request.method,\n path: url.pathname,\n requestId: request.headers.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(request.headers),\n ...options,\n }\n const { logger, finish, skipped } = createMiddlewareLogger(middlewareOpts)\n\n if (skipped) {\n return next()\n }\n\n attachForkToLogger(storage, logger, middlewareOpts)\n context.set(loggerContext, logger)\n\n try {\n const response = await storage.run(logger, () => next())\n await finish({ status: response.status })\n return response\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,6EACD;;;;;;;;;;;;;;;AAgBD,MAAa,gBAAgB,eAA8B;;;;;;;;;;;;;;AAmB3D,SAAgB,MAAM,UAAmC,EAAE,EAAE;AAC3D,QAAO,OACL,EAAE,SAAS,WACX,SACsB;EACtB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,iBAAiB;GACrB,QAAQ,QAAQ;GAChB,MAAM,IAAI;GACV,WAAW,QAAQ,QAAQ,IAAI,eAAe,IAAI,OAAO,YAAY;GACrE,SAAS,mBAAmB,QAAQ,QAAQ;GAC5C,GAAG;GACJ;EACD,MAAM,EAAE,QAAQ,QAAQ,YAAY,uBAAuB,eAAe;AAE1E,MAAI,QACF,QAAO,MAAM;AAGf,qBAAmB,SAAS,QAAQ,eAAe;AACnD,UAAQ,IAAI,eAAe,OAAO;AAElC,MAAI;GACF,MAAM,WAAW,MAAM,QAAQ,IAAI,cAAc,MAAM,CAAC;AACxD,SAAM,OAAO,EAAE,QAAQ,SAAS,QAAQ,CAAC;AACzC,UAAO;WACA,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../../src/react-router/index.ts"],"sourcesContent":["import { createContext } from 'react-router'\nimport type { RequestLogger } from '../types'\nimport { createMiddlewareLogger, type BaseEvlogOptions } from '../shared/middleware'\nimport { attachForkToLogger } from '../shared/fork'\nimport { extractSafeHeaders } from '../shared/headers'\nimport { createLoggerStorage } from '../shared/storage'\n\nconst { storage, useLogger } = createLoggerStorage(\n 'middleware context. Make sure the evlog middleware is added to your route.',\n)\n\n/**\n * Typed context key for accessing the evlog logger in loaders and actions.\n *\n * @example\n * ```ts\n * import { loggerContext } from 'evlog/react-router'\n *\n * export async function loader({ context }: Route.LoaderArgs) {\n * const log = context.get(loggerContext)\n * log.set({ user: { id: 'u-1' } })\n * return { ok: true }\n * }\n * ```\n */\nexport const loggerContext = createContext<RequestLogger>()\n\nexport type EvlogReactRouterOptions = BaseEvlogOptions\n\nexport { useLogger }\n\n/**\n * Create an evlog middleware for React Router.\n *\n * @example\n * ```ts\n * // app/root.tsx\n * import { evlog } from 'evlog/react-router'\n *\n * export const middleware: Route.MiddlewareFunction[] = [\n * evlog({ drain: createAxiomDrain() }),\n * ]\n * ```\n */\nexport function evlog(options: EvlogReactRouterOptions = {}) {\n return async (\n { request, context }: { request: Request; context: { set(ctx: unknown, value: unknown): void } },\n next: () => Promise<Response>,\n ): Promise<Response> => {\n const url = new URL(request.url)\n const middlewareOpts = {\n method: request.method,\n path: url.pathname,\n requestId: request.headers.get('x-request-id') || crypto.randomUUID(),\n headers: extractSafeHeaders(request.headers),\n ...options,\n }\n const { logger, finish, finishResponse, skipped } = createMiddlewareLogger(middlewareOpts)\n\n if (skipped) {\n return next()\n }\n\n attachForkToLogger(storage, logger, middlewareOpts)\n context.set(loggerContext, logger)\n\n try {\n const response = await storage.run(logger, () => next())\n return finishResponse(response, { status: response.status })\n } catch (error) {\n await finish({ error: error as Error })\n throw error\n }\n }\n}\n"],"mappings":";;;;;AAOA,MAAM,EAAE,SAAS,cAAc,oBAC7B,6EACD;;;;;;;;;;;;;;;AAgBD,MAAa,gBAAgB,eAA8B;;;;;;;;;;;;;;AAmB3D,SAAgB,MAAM,UAAmC,EAAE,EAAE;AAC3D,QAAO,OACL,EAAE,SAAS,WACX,SACsB;EACtB,MAAM,MAAM,IAAI,IAAI,QAAQ,IAAI;EAChC,MAAM,iBAAiB;GACrB,QAAQ,QAAQ;GAChB,MAAM,IAAI;GACV,WAAW,QAAQ,QAAQ,IAAI,eAAe,IAAI,OAAO,YAAY;GACrE,SAAS,mBAAmB,QAAQ,QAAQ;GAC5C,GAAG;GACJ;EACD,MAAM,EAAE,QAAQ,QAAQ,gBAAgB,YAAY,uBAAuB,eAAe;AAE1F,MAAI,QACF,QAAO,MAAM;AAGf,qBAAmB,SAAS,QAAQ,eAAe;AACnD,UAAQ,IAAI,eAAe,OAAO;AAElC,MAAI;GACF,MAAM,WAAW,MAAM,QAAQ,IAAI,cAAc,MAAM,CAAC;AACxD,UAAO,eAAe,UAAU,EAAE,QAAQ,SAAS,QAAQ,CAAC;WACrD,OAAO;AACd,SAAM,OAAO,EAAS,OAAgB,CAAC;AACvC,SAAM"}
@@ -35,4 +35,4 @@ function getServiceForPath(path, routes) {
35
35
  //#endregion
36
36
  export { shouldLog as n, getServiceForPath as t };
37
37
 
38
- //# sourceMappingURL=routes-CnIgYWf8.mjs.map
38
+ //# sourceMappingURL=routes-4rMzRyTk.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes-CnIgYWf8.mjs","names":[],"sources":["../src/shared/routes.ts"],"sourcesContent":["import type { RouteConfig } from '../types'\nimport { matchesPattern } from '../utils'\n\nexport function shouldLog(path: string, include?: string[], exclude?: string[]): boolean {\n // Check exclusions first (they take precedence)\n if (exclude && exclude.length > 0) {\n if (exclude.some(pattern => matchesPattern(path, pattern))) {\n return false\n }\n }\n\n // If no include patterns, log everything (that wasn't excluded)\n if (!include || include.length === 0) {\n return true\n }\n\n // Log only if path matches at least one include pattern\n return include.some(pattern => matchesPattern(path, pattern))\n}\n\n/**\n * Find the service name for a given path based on route patterns.\n *\n * When multiple patterns match the same path, the first matching pattern wins\n * based on object iteration order. To ensure predictable behavior, order your\n * route patterns from most specific to most general.\n *\n * @param path - The request path to match\n * @param routes - Route configuration mapping patterns to service names\n * @returns The service name for the matching route, or undefined if no match\n *\n * @example\n * ```ts\n * // Good: specific patterns first, general patterns last\n * routes: {\n * '/api/auth/admin/**': { service: 'admin-service' },\n * '/api/auth/**': { service: 'auth-service' },\n * '/api/**': { service: 'api-service' },\n * }\n * ```\n */\nexport function getServiceForPath(path: string, routes?: Record<string, RouteConfig>): string | undefined {\n if (!routes) return undefined\n\n for (const [pattern, config] of Object.entries(routes)) {\n if (matchesPattern(path, pattern)) {\n return config.service\n }\n }\n\n return undefined\n}\n"],"mappings":";;AAGA,SAAgB,UAAU,MAAc,SAAoB,SAA6B;AAEvF,KAAI,WAAW,QAAQ,SAAS;MAC1B,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC,CACxD,QAAO;;AAKX,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,QAAO;AAIT,QAAO,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;AAwB/D,SAAgB,kBAAkB,MAAc,QAA0D;AACxG,KAAI,CAAC,OAAQ,QAAO,KAAA;AAEpB,MAAK,MAAM,CAAC,SAAS,WAAW,OAAO,QAAQ,OAAO,CACpD,KAAI,eAAe,MAAM,QAAQ,CAC/B,QAAO,OAAO"}
1
+ {"version":3,"file":"routes-4rMzRyTk.mjs","names":[],"sources":["../src/shared/routes.ts"],"sourcesContent":["import type { RouteConfig } from '../types'\nimport { matchesPattern } from '../utils'\n\nexport function shouldLog(path: string, include?: string[], exclude?: string[]): boolean {\n // Check exclusions first (they take precedence)\n if (exclude && exclude.length > 0) {\n if (exclude.some(pattern => matchesPattern(path, pattern))) {\n return false\n }\n }\n\n // If no include patterns, log everything (that wasn't excluded)\n if (!include || include.length === 0) {\n return true\n }\n\n // Log only if path matches at least one include pattern\n return include.some(pattern => matchesPattern(path, pattern))\n}\n\n/**\n * Find the service name for a given path based on route patterns.\n *\n * When multiple patterns match the same path, the first matching pattern wins\n * based on object iteration order. To ensure predictable behavior, order your\n * route patterns from most specific to most general.\n *\n * @param path - The request path to match\n * @param routes - Route configuration mapping patterns to service names\n * @returns The service name for the matching route, or undefined if no match\n *\n * @example\n * ```ts\n * // Good: specific patterns first, general patterns last\n * routes: {\n * '/api/auth/admin/**': { service: 'admin-service' },\n * '/api/auth/**': { service: 'auth-service' },\n * '/api/**': { service: 'api-service' },\n * }\n * ```\n */\nexport function getServiceForPath(path: string, routes?: Record<string, RouteConfig>): string | undefined {\n if (!routes) return undefined\n\n for (const [pattern, config] of Object.entries(routes)) {\n if (matchesPattern(path, pattern)) {\n return config.service\n }\n }\n\n return undefined\n}\n"],"mappings":";;AAGA,SAAgB,UAAU,MAAc,SAAoB,SAA6B;AAEvF,KAAI,WAAW,QAAQ,SAAS;MAC1B,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC,CACxD,QAAO;;AAKX,KAAI,CAAC,WAAW,QAAQ,WAAW,EACjC,QAAO;AAIT,QAAO,QAAQ,MAAK,YAAW,eAAe,MAAM,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;AAwB/D,SAAgB,kBAAkB,MAAc,QAA0D;AACxG,KAAI,CAAC,OAAQ,QAAO,KAAA;AAEpB,MAAK,MAAM,CAAC,SAAS,WAAW,OAAO,QAAQ,OAAO,CACpD,KAAI,eAAe,MAAM,QAAQ,CAC/B,QAAO,OAAO"}
@@ -1,4 +1,4 @@
1
- import { G as Log, K as LogLevel, st as TransportConfig } from "../../audit-DVdkntSO.mjs";
1
+ import { X as LogLevel, Y as Log, dt as TransportConfig } from "../../audit-BUAajsPU.mjs";
2
2
 
3
3
  //#region src/runtime/client/log.d.ts
4
4
  declare function setIdentity(identity: Record<string, unknown>): void;
@@ -1,5 +1,5 @@
1
- import { _ as getEnvironment, y as getGlobalPluginRunner } from "../../../../audit-BUI3af4w.mjs";
2
1
  import { filterSafeHeaders } from "../../../../utils.mjs";
2
+ import { _ as getEnvironment, y as getGlobalPluginRunner } from "../../../../audit-BFwTUxBJ.mjs";
3
3
  import { createError, defineEventHandler, getHeader, getHeaders, getRequestHost, readBody, setResponseStatus } from "h3";
4
4
  import { useNitroApp } from "nitropack/runtime";
5
5
  //#region src/runtime/server/routes/_evlog/ingest.post.ts
@@ -1,2 +1,2 @@
1
- import { t as useLogger } from "../../useLogger-CqvH6qOf.mjs";
1
+ import { t as useLogger } from "../../useLogger-Dv52PDpH.mjs";
2
2
  export { useLogger };
@@ -1,3 +1,3 @@
1
- import { J as ParsedError } from "../../audit-DVdkntSO.mjs";
2
- import { t as parseError } from "../../parseError-D4PIxEWo.mjs";
1
+ import { Q as ParsedError } from "../../audit-BUAajsPU.mjs";
2
+ import { t as parseError } from "../../parseError-Cagr-Ctc.mjs";
3
3
  export { ParsedError, parseError };
@@ -1,4 +1,4 @@
1
- import { t as extractErrorStatus } from "../../errors-BQgyQ9xe.mjs";
1
+ import { t as extractErrorStatus } from "../../errors-DA0cyr8q.mjs";
2
2
  //#region src/runtime/utils/parseError.ts
3
3
  function pickCode(value) {
4
4
  if (value && typeof value === "object" && "code" in value) {
@@ -18,4 +18,4 @@ const OTEL_SEVERITY_TEXT = {
18
18
  //#endregion
19
19
  export { OTEL_SEVERITY_TEXT as n, OTEL_SEVERITY_NUMBER as t };
20
20
 
21
- //# sourceMappingURL=severity-R5Egq3qz.mjs.map
21
+ //# sourceMappingURL=severity-CwXUSHt3.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"severity-R5Egq3qz.mjs","names":[],"sources":["../src/shared/severity.ts"],"sourcesContent":["import type { LogLevel } from '../types'\n\n/**\n * OpenTelemetry severity numbers per evlog log level.\n * @see https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber\n */\nexport const OTEL_SEVERITY_NUMBER: Record<LogLevel, number> = {\n debug: 5,\n info: 9,\n warn: 13,\n error: 17,\n}\n\nexport const OTEL_SEVERITY_TEXT: Record<LogLevel, string> = {\n debug: 'DEBUG',\n info: 'INFO',\n warn: 'WARN',\n error: 'ERROR',\n}\n"],"mappings":";;;;;AAMA,MAAa,uBAAiD;CAC5D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR;AAED,MAAa,qBAA+C;CAC1D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR"}
1
+ {"version":3,"file":"severity-CwXUSHt3.mjs","names":[],"sources":["../src/shared/severity.ts"],"sourcesContent":["import type { LogLevel } from '../types'\n\n/**\n * OpenTelemetry severity numbers per evlog log level.\n * @see https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitynumber\n */\nexport const OTEL_SEVERITY_NUMBER: Record<LogLevel, number> = {\n debug: 5,\n info: 9,\n warn: 13,\n error: 17,\n}\n\nexport const OTEL_SEVERITY_TEXT: Record<LogLevel, string> = {\n debug: 'DEBUG',\n info: 'INFO',\n warn: 'WARN',\n error: 'ERROR',\n}\n"],"mappings":";;;;;AAMA,MAAa,uBAAiD;CAC5D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR;AAED,MAAa,qBAA+C;CAC1D,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;CACR"}
@@ -1162,4 +1162,4 @@ function createSourceLocationPlugin(enabled) {
1162
1162
  //#endregion
1163
1163
  export { walk as a, shouldTransform as i, createStripPlugin as n, MagicString as o, TRANSFORM_FILTER as r, createSourceLocationPlugin as t };
1164
1164
 
1165
- //# sourceMappingURL=source-location-Dco0cRTz.mjs.map
1165
+ //# sourceMappingURL=source-location-xkDGiERl.mjs.map