@visulima/error 5.0.3 → 5.0.5

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 (71) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/code-frame/get-marker-lines.d.ts +19 -0
  3. package/dist/code-frame/index-to-line-column.d.ts +7 -0
  4. package/dist/code-frame/index.d.ts +15 -7
  5. package/dist/code-frame/index.js +125 -6
  6. package/dist/{packem_shared/types-CrVmNoPV.d.ts → code-frame/types.d.ts} +4 -6
  7. package/dist/error/capture-raw-stack-trace.d.ts +2 -0
  8. package/dist/error/get-error-causes.d.ts +6 -0
  9. package/dist/error/index.d.ts +12 -96
  10. package/dist/error/index.js +8 -1
  11. package/dist/error/render/error.d.ts +22 -0
  12. package/dist/error/serialize/deserialize.d.ts +14 -0
  13. package/dist/error/serialize/error-constructors.d.ts +25 -0
  14. package/dist/error/serialize/error-proto.d.ts +10 -0
  15. package/dist/error/serialize/non-error.d.ts +7 -0
  16. package/dist/error/serialize/serialize.d.ts +14 -0
  17. package/dist/error/types.d.ts +33 -0
  18. package/dist/error/visulima-error.d.ts +16 -0
  19. package/dist/index.d.ts +12 -17
  20. package/dist/index.js +16 -1
  21. package/dist/packem_shared/NonError-D5FGLYKY.js +8 -0
  22. package/dist/packem_shared/addKnownErrorConstructor-s_3SsXtQ.js +30 -0
  23. package/dist/packem_shared/aiFinder-HftEgsry.js +277 -0
  24. package/dist/packem_shared/aiSolutionResponse-CJBMLS9t.js +34 -0
  25. package/dist/packem_shared/captureRawStackTrace-ySw7cU0U.js +10 -0
  26. package/dist/packem_shared/deserializeError-E0VQnnm0.js +116 -0
  27. package/dist/packem_shared/errorHintFinder-DEaeRnRW.js +21 -0
  28. package/dist/packem_shared/formatStackFrameLine-D3_6oSWZ.js +24 -0
  29. package/dist/packem_shared/getErrorCauses-DpUsmuqw.js +43 -0
  30. package/dist/packem_shared/index-y_UPkY2Z.js +9 -0
  31. package/dist/packem_shared/indexToLineColumn-Bg8UW1bU.js +50 -0
  32. package/dist/packem_shared/isVisulimaError-DA7QsCxH.js +34 -0
  33. package/dist/packem_shared/parseStacktrace-oQvk7wYp.js +273 -0
  34. package/dist/packem_shared/renderError-C30PRFtU.js +206 -0
  35. package/dist/packem_shared/ruleBasedFinder-C2F8rQ30.js +207 -0
  36. package/dist/packem_shared/serializeError-BZ62KiYZ.js +142 -0
  37. package/dist/solution/ai/ai-finder.d.ts +12 -0
  38. package/dist/solution/ai/ai-prompt.d.ts +2 -4
  39. package/dist/solution/ai/ai-prompt.js +13 -7
  40. package/dist/{packem_shared/ai-solution-response-BuaDQAEU.d.ts → solution/ai/ai-solution-response.d.ts} +1 -2
  41. package/dist/solution/ai/index.d.ts +3 -16
  42. package/dist/solution/ai/index.js +3 -1
  43. package/dist/solution/error-hint-finder.d.ts +3 -0
  44. package/dist/solution/index.d.ts +3 -8
  45. package/dist/solution/index.js +2 -1
  46. package/dist/solution/rule-based-finder.d.ts +3 -0
  47. package/dist/{packem_shared/types-BtQS7FHG.d.ts → solution/types.d.ts} +4 -6
  48. package/dist/stacktrace/index.d.ts +3 -26
  49. package/dist/stacktrace/index.js +2 -1
  50. package/dist/stacktrace/parse-stacktrace.d.ts +6 -0
  51. package/dist/stacktrace/stringify.d.ts +15 -0
  52. package/dist/stacktrace/types.d.ts +10 -0
  53. package/dist/util/normalize-lf.d.ts +2 -0
  54. package/dist/util/process.d.ts +5 -0
  55. package/package.json +1 -1
  56. package/dist/packem_shared/NonError-CS10kwil.js +0 -1
  57. package/dist/packem_shared/addKnownErrorConstructor-BqqnTSZp.js +0 -1
  58. package/dist/packem_shared/aiFinder-DPoqj12B.js +0 -1
  59. package/dist/packem_shared/aiSolutionResponse-RD0AK1jh.js +0 -10
  60. package/dist/packem_shared/captureRawStackTrace-CQPNHvBG.js +0 -1
  61. package/dist/packem_shared/deserializeError-BJM8Kd6G.js +0 -1
  62. package/dist/packem_shared/errorHintFinder-C_g0nvml.js +0 -2
  63. package/dist/packem_shared/formatStackFrameLine-iU54KA81.js +0 -2
  64. package/dist/packem_shared/getErrorCauses-geeK5cwE.js +0 -1
  65. package/dist/packem_shared/index-CLFYRLyq.js +0 -1
  66. package/dist/packem_shared/indexToLineColumn-B1F7aNZh.js +0 -1
  67. package/dist/packem_shared/isVisulimaError-jVZgumOU.js +0 -1
  68. package/dist/packem_shared/parseStacktrace-Dnxnc4PL.js +0 -2
  69. package/dist/packem_shared/renderError-ZMlMvw1N.js +0 -18
  70. package/dist/packem_shared/ruleBasedFinder-P88d0gpK.js +0 -34
  71. package/dist/packem_shared/serializeError-CTpDr3CL.js +0 -1
@@ -0,0 +1,273 @@
1
+ const debugLog = (message, ...arguments_) => {
2
+ if (process.env.DEBUG && String(process.env.DEBUG) === "true") {
3
+ console.debug(`error:parse-stacktrace: ${message}`, ...arguments_);
4
+ }
5
+ };
6
+ const UNKNOWN_FUNCTION = "<unknown>";
7
+ const CHROMIUM_REGEX = /^.*?\s*at\s(?:(.+?\)(?:\s\[.+\])?|\(?.*?)\s?\((?:address\sat\s)?)?(?:async\s)?((?:<anonymous>|[-a-z]+:|.*bundle|\/)?.*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
8
+ const CHROMIUM_EVAL_REGEX = /\((\S+)\),\s(<[^>]+>)?:(\d+)?:(\d+)?\)?/;
9
+ const CHROMIUM_MAPPED = /(.*?):(\d+):(\d+)(\s<-\s(.+):(\d+):(\d+))?/;
10
+ const WINDOWS_EVAL_REGEX = /(eval)\sat\s(<anonymous>)\s\((.*)\)?:(\d+)?:(\d+)\),\s*(<anonymous>)?:(\d+)?:(\d+)/;
11
+ const NODE_REGEX = /^\s*in\s(?:([^\\/]+(?:\s\[as\s\S+\])?)\s\(?)?\(at?\s?(.*?):(\d+)(?::(\d+))?\)?\s*$/;
12
+ const NODE_NESTED_REGEX = /in\s(.*)\s\(at\s(.+)\)\sat/;
13
+ const REACT_ANDROID_NATIVE_REGEX = /^(?:.*@)?(.*):(\d+):(\d+)$/;
14
+ const GECKO_REGEX = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:[-a-z]+)?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js)|\/[\w\-. \/=]+)(?::(\d+))?(?::(\d+))?\s*$/i;
15
+ const GECKO_EVAL_REGEX = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
16
+ const FIREFOX_REGEX = /(\S[^\s[]*\[.*\]|.*?)@(.*):(\d+):(\d+)/;
17
+ const WEBPACK_ERROR_REGEXP = /\(error: (.*)\)/;
18
+ const extractSafariExtensionDetails = (methodName, url) => {
19
+ const isSafariExtension = methodName.includes("safari-extension");
20
+ const isSafariWebExtension = methodName.includes("safari-web-extension");
21
+ return isSafariExtension || isSafariWebExtension ? [
22
+ methodName.includes("@") ? methodName.split("@")[0] : UNKNOWN_FUNCTION,
23
+ isSafariExtension ? `safari-extension:${url}` : `safari-web-extension:${url}`
24
+ ] : [methodName, url];
25
+ };
26
+ const parseMapped = (trace, maybeMapped) => {
27
+ const match = CHROMIUM_MAPPED.exec(maybeMapped);
28
+ if (match) {
29
+ trace.file = match[1];
30
+ trace.line = +match[2];
31
+ trace.column = +match[3];
32
+ }
33
+ };
34
+ const parseNode = (line) => {
35
+ const nestedNode = NODE_NESTED_REGEX.exec(line);
36
+ if (nestedNode) {
37
+ debugLog(`parse nested node error stack line: "${line}"`, `found: ${JSON.stringify(nestedNode)}`);
38
+ const split = nestedNode[2].split(":");
39
+ return {
40
+ column: split[2] ? +split[2] : void 0,
41
+ file: split[0],
42
+ line: split[1] ? +split[1] : void 0,
43
+ methodName: nestedNode[1] || UNKNOWN_FUNCTION,
44
+ raw: line,
45
+ type: void 0
46
+ };
47
+ }
48
+ const node = NODE_REGEX.exec(line);
49
+ if (node) {
50
+ debugLog(`parse node error stack line: "${line}"`, `found: ${JSON.stringify(node)}`);
51
+ const trace = {
52
+ column: node[4] ? +node[4] : void 0,
53
+ file: node[2] ? node[2].replace(/at\s/, "") : void 0,
54
+ line: node[3] ? +node[3] : void 0,
55
+ methodName: node[1] || UNKNOWN_FUNCTION,
56
+ raw: line,
57
+ type: line.startsWith("internal") ? "internal" : void 0
58
+ };
59
+ parseMapped(trace, `${node[2]}:${node[3]}:${node[4]}`);
60
+ return trace;
61
+ }
62
+ return void 0;
63
+ };
64
+ const parseChromium = (line) => {
65
+ const parts = CHROMIUM_REGEX.exec(line);
66
+ if (parts) {
67
+ debugLog(`parse chrome error stack line: "${line}"`, `found: ${JSON.stringify(parts)}`);
68
+ const isNative = parts[2]?.startsWith("native");
69
+ const isEval = parts[2]?.startsWith("eval") || parts[1]?.startsWith("eval");
70
+ let evalOrigin;
71
+ let windowsParts;
72
+ if (isEval) {
73
+ const subMatch = CHROMIUM_EVAL_REGEX.exec(line);
74
+ if (subMatch) {
75
+ const split = /^(\S+):(\d+):(\d+)$|^(\S+):(\d+)$/.exec(subMatch[1]);
76
+ if (split) {
77
+ parts[2] = split[4] ?? split[1];
78
+ parts[3] = split[5] ?? split[2];
79
+ parts[4] = split[3];
80
+ } else if (subMatch[2]) {
81
+ parts[2] = subMatch[1];
82
+ }
83
+ if (subMatch[2]) {
84
+ evalOrigin = {
85
+ column: subMatch[4] ? +subMatch[4] : void 0,
86
+ file: subMatch[2],
87
+ line: subMatch[3] ? +subMatch[3] : void 0,
88
+ methodName: "eval",
89
+ raw: line,
90
+ type: "eval"
91
+ };
92
+ }
93
+ } else {
94
+ const windowsSubMatch = WINDOWS_EVAL_REGEX.exec(line);
95
+ if (windowsSubMatch) {
96
+ windowsParts = {
97
+ column: windowsSubMatch[5] ? +windowsSubMatch[5] : void 0,
98
+ file: windowsSubMatch[3],
99
+ line: windowsSubMatch[4] ? +windowsSubMatch[4] : void 0
100
+ };
101
+ evalOrigin = {
102
+ column: windowsSubMatch[8] ? +windowsSubMatch[8] : void 0,
103
+ file: windowsSubMatch[2],
104
+ line: windowsSubMatch[7] ? +windowsSubMatch[7] : void 0,
105
+ methodName: "eval",
106
+ raw: windowsSubMatch[0],
107
+ type: "eval"
108
+ };
109
+ }
110
+ }
111
+ }
112
+ const [methodName, file] = extractSafariExtensionDetails(
113
+ // Normalize IE's 'Anonymous function'
114
+ parts[1] ? parts[1].replace(/^Anonymous function$/, "<anonymous>") : UNKNOWN_FUNCTION,
115
+ parts[2]
116
+ );
117
+ const trace = {
118
+ column: parts[4] ? +parts[4] : void 0,
119
+ evalOrigin,
120
+ file,
121
+ line: parts[3] ? +parts[3] : void 0,
122
+ methodName,
123
+ raw: line,
124
+ // eslint-disable-next-line sonarjs/no-nested-conditional
125
+ type: isEval ? "eval" : isNative ? "native" : void 0
126
+ };
127
+ if (windowsParts) {
128
+ trace.column = windowsParts.column;
129
+ trace.file = windowsParts.file;
130
+ trace.line = windowsParts.line;
131
+ } else {
132
+ parseMapped(trace, `${file}:${parts[3]}:${parts[4]}`);
133
+ }
134
+ return trace;
135
+ }
136
+ return void 0;
137
+ };
138
+ const parseGecko = (line, topFrameMeta) => {
139
+ const parts = GECKO_REGEX.exec(line);
140
+ if (parts) {
141
+ debugLog(`parse gecko error stack line: "${line}"`, `found: ${JSON.stringify(parts)}`);
142
+ const isEval = parts[3]?.includes(" > eval");
143
+ const subMatch = isEval && parts[3] && GECKO_EVAL_REGEX.exec(parts[3]);
144
+ let evalOrigin;
145
+ if (isEval && subMatch) {
146
+ parts[3] = subMatch[1];
147
+ evalOrigin = {
148
+ column: parts[5] ? +parts[5] : void 0,
149
+ file: parts[3],
150
+ line: parts[4] ? +parts[4] : void 0,
151
+ methodName: "eval",
152
+ raw: line,
153
+ type: "eval"
154
+ };
155
+ parts[4] = subMatch[2];
156
+ }
157
+ const [methodName, file] = extractSafariExtensionDetails(
158
+ // Normalize IE's 'Anonymous function'
159
+ parts[1] ? parts[1].replace(/^Anonymous function$/, "<anonymous>") : UNKNOWN_FUNCTION,
160
+ parts[3]
161
+ );
162
+ let column;
163
+ if ((topFrameMeta?.type === "safari" || !isEval && topFrameMeta?.type === "firefox") && topFrameMeta.column) {
164
+ column = topFrameMeta.column;
165
+ } else if (!isEval && parts[5]) {
166
+ column = +parts[5];
167
+ }
168
+ let lineNumber;
169
+ if ((topFrameMeta?.type === "safari" || !isEval && topFrameMeta?.type === "firefox") && topFrameMeta.line) {
170
+ lineNumber = topFrameMeta.line;
171
+ } else if (parts[4]) {
172
+ lineNumber = +parts[4];
173
+ }
174
+ return {
175
+ column,
176
+ evalOrigin,
177
+ file,
178
+ line: lineNumber,
179
+ methodName,
180
+ raw: line,
181
+ // eslint-disable-next-line sonarjs/no-nested-conditional
182
+ type: isEval ? "eval" : file.includes("[native code]") ? "native" : void 0
183
+ };
184
+ }
185
+ return void 0;
186
+ };
187
+ const parseFirefox = (line, topFrameMeta) => {
188
+ const parts = FIREFOX_REGEX.exec(line);
189
+ const isEval = parts ? parts[2].includes(" > eval") : false;
190
+ if (!isEval && parts) {
191
+ debugLog(`parse firefox error stack line: "${line}"`, `found: ${JSON.stringify(parts)}`);
192
+ return {
193
+ column: parts[4] ? +parts[4] : topFrameMeta?.column ?? void 0,
194
+ file: parts[2],
195
+ line: parts[3] ? +parts[3] : topFrameMeta?.line ?? void 0,
196
+ methodName: parts[1] || UNKNOWN_FUNCTION,
197
+ raw: line,
198
+ type: void 0
199
+ };
200
+ }
201
+ return void 0;
202
+ };
203
+ const parseReactAndroidNative = (line) => {
204
+ const parts = REACT_ANDROID_NATIVE_REGEX.exec(line);
205
+ if (parts) {
206
+ debugLog(`parse react android native error stack line: "${line}"`, `found: ${JSON.stringify(parts)}`);
207
+ return {
208
+ column: parts[3] ? +parts[3] : void 0,
209
+ file: parts[1],
210
+ line: parts[2] ? +parts[2] : void 0,
211
+ methodName: UNKNOWN_FUNCTION,
212
+ raw: line,
213
+ type: void 0
214
+ };
215
+ }
216
+ return void 0;
217
+ };
218
+ const parseStacktrace = (error, { filter, frameLimit = 50 } = {}) => {
219
+ let lines = (error.stacktrace ?? error.stack ?? "").split("\n").map((line) => {
220
+ const cleanedLine = WEBPACK_ERROR_REGEXP.test(line) ? line.replace(WEBPACK_ERROR_REGEXP, "$1") : line;
221
+ return cleanedLine.replace(/^\s+|\s+$/g, "");
222
+ }).filter((line) => !/\S*(?:Error: |AggregateError:)/.test(line) && line !== "eval code");
223
+ if (filter) {
224
+ lines = lines.filter((element) => filter(element));
225
+ }
226
+ lines = lines.slice(0, frameLimit);
227
+ return lines.reduce((stack, line, currentIndex) => {
228
+ if (!line) {
229
+ return stack;
230
+ }
231
+ if (line.length > 1024) {
232
+ return stack;
233
+ }
234
+ let parseResult;
235
+ if (/^\s*in\s.*/.test(line)) {
236
+ parseResult = parseNode(line);
237
+ } else if (/^.*?\s*at\s.*/.test(line)) {
238
+ parseResult = parseChromium(line);
239
+ } else if (/^.*?\s*@.*|\[native code\]/.test(line)) {
240
+ let topFrameMeta;
241
+ if (currentIndex === 0) {
242
+ if (error.columnNumber || error.lineNumber) {
243
+ topFrameMeta = {
244
+ // @ts-expect-error columnNumber and columnNumber property only exists on Firefox
245
+ column: error.columnNumber,
246
+ // @ts-expect-error columnNumber and lineNumber property only exists on Firefox
247
+ line: error.lineNumber,
248
+ type: "firefox"
249
+ };
250
+ } else if (error.line || error.column) {
251
+ topFrameMeta = {
252
+ // @ts-expect-error column property only exists on safari
253
+ column: error.column,
254
+ // @ts-expect-error line property only exists on safari
255
+ line: error.line,
256
+ type: "safari"
257
+ };
258
+ }
259
+ }
260
+ parseResult = parseFirefox(line, topFrameMeta) || parseGecko(line, topFrameMeta);
261
+ } else {
262
+ parseResult = parseReactAndroidNative(line);
263
+ }
264
+ if (parseResult) {
265
+ stack.push(parseResult);
266
+ } else {
267
+ debugLog(`parse error stack line: "${line}"`, "not parser found");
268
+ }
269
+ return stack;
270
+ }, []);
271
+ };
272
+
273
+ export { parseStacktrace as default };
@@ -0,0 +1,206 @@
1
+ import { createRequire as __cjs_createRequire } from "node:module";
2
+
3
+ const __cjs_require = __cjs_createRequire(import.meta.url);
4
+
5
+ const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
6
+
7
+ const __cjs_getBuiltinModule = (module) => {
8
+ // Check if we're in Node.js and version supports getBuiltinModule
9
+ if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
10
+ const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
11
+ // Node.js 20.16.0+ and 22.3.0+
12
+ if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
13
+ return __cjs_getProcess.getBuiltinModule(module);
14
+ }
15
+ }
16
+ // Fallback to createRequire
17
+ return __cjs_require(module);
18
+ };
19
+
20
+ const {
21
+ existsSync,
22
+ readFileSync
23
+ } = __cjs_getBuiltinModule("node:fs");
24
+ const {
25
+ relative
26
+ } = __cjs_getBuiltinModule("node:path");
27
+ const {
28
+ cwd
29
+ } = __cjs_getProcess;
30
+ const {
31
+ fileURLToPath
32
+ } = __cjs_getBuiltinModule("node:url");
33
+ import { codeFrame } from '../code-frame/index.js';
34
+ import parseStacktrace from './parseStacktrace-oQvk7wYp.js';
35
+
36
+ const getPrefix = (prefix, indentation, deep) => {
37
+ if (deep === 0) {
38
+ return prefix.toString();
39
+ }
40
+ if (indentation === " ") {
41
+ return prefix + " ".repeat(deep);
42
+ }
43
+ return prefix + " ".repeat(indentation * deep);
44
+ };
45
+ const getRelativePath = (filePath, cwdPath) => {
46
+ const path = filePath.replace("async file:", "file:");
47
+ return relative(cwdPath, path.startsWith("file:") ? fileURLToPath(path) : path);
48
+ };
49
+ const getTitleText = (error, hideErrorTitle, color) => {
50
+ if (hideErrorTitle) {
51
+ return color.title(error.message);
52
+ }
53
+ const messagePart = error.message ? `: ${error.message}` : "";
54
+ return color.title(error.name + messagePart);
55
+ };
56
+ const getMessage = (error, { color, hideErrorTitle, indentation, prefix }, deep) => `${getPrefix(prefix, indentation, deep)}${getTitleText(error, hideErrorTitle, color)}
57
+ `;
58
+ const getHint = (error, { color, indentation, prefix }, deep) => {
59
+ if (error.hint === void 0) {
60
+ return void 0;
61
+ }
62
+ const spaces = getPrefix(prefix, indentation, deep);
63
+ let message = "";
64
+ if (Array.isArray(error.hint)) {
65
+ for (const line of error.hint) {
66
+ message += `${(spaces + line).toString()}
67
+ `;
68
+ }
69
+ } else {
70
+ message += spaces + error.hint;
71
+ }
72
+ return color.hint(message);
73
+ };
74
+ const getMainFrame = (trace, { color, cwd: cwdPath, displayShortPath, indentation, prefix }, deep = 0) => {
75
+ const filePath = displayShortPath ? getRelativePath(trace.file, cwdPath) : trace.file;
76
+ const { fileLine, method } = color;
77
+ return `${getPrefix(prefix, indentation, deep)}at ${trace.methodName ? `${method(trace.methodName)} ` : ""}${fileLine(filePath)}:${fileLine(
78
+ trace.line?.toString() ?? ""
79
+ )}`.toString();
80
+ };
81
+ const getCode = (trace, { color, indentation, linesAbove, linesBelow, prefix, showGutter, showLineNumbers, tabWidth }, deep) => {
82
+ if (trace.file === void 0) {
83
+ return void 0;
84
+ }
85
+ const filePath = trace.file.replace("file://", "");
86
+ if (!existsSync(filePath)) {
87
+ return void 0;
88
+ }
89
+ const fileContent = readFileSync(filePath, "utf8");
90
+ return codeFrame(
91
+ fileContent,
92
+ {
93
+ start: { column: trace.column, line: trace.line }
94
+ },
95
+ { color, linesAbove, linesBelow, prefix: getPrefix(prefix, indentation, deep), showGutter, showLineNumbers, tabWidth }
96
+ );
97
+ };
98
+ const getErrors = (error, options, deep) => {
99
+ if (error.errors.length === 0) {
100
+ return void 0;
101
+ }
102
+ let message = `${getPrefix(options.prefix, options.indentation, deep)}Errors:
103
+
104
+ `;
105
+ let first = true;
106
+ for (const error_ of error.errors) {
107
+ if (first) {
108
+ first = false;
109
+ } else {
110
+ message += "\n\n";
111
+ }
112
+ message += internalRenderError(error_, { ...options, framesMaxLimit: 1, hideErrorCodeView: options.hideErrorErrorsCodeView }, deep + 1);
113
+ }
114
+ return `
115
+ ${message}`;
116
+ };
117
+ const getCause = (error, options, deep) => {
118
+ let message = `${getPrefix(options.prefix, options.indentation, deep)}Caused by:
119
+
120
+ `;
121
+ const cause = error.cause;
122
+ message += getMessage(cause, options, deep);
123
+ const stacktrace = parseStacktrace(cause);
124
+ const mainFrame = stacktrace.shift();
125
+ const hint = getHint(cause, options, deep);
126
+ if (hint) {
127
+ message += `${hint}
128
+ `;
129
+ }
130
+ if (mainFrame) {
131
+ message += getMainFrame(mainFrame, options, deep);
132
+ if (!options.hideErrorCauseCodeView) {
133
+ const code = getCode(mainFrame, options, deep);
134
+ if (code !== void 0) {
135
+ message += `
136
+ ${code}`;
137
+ }
138
+ }
139
+ }
140
+ if (cause.cause) {
141
+ message += `
142
+ ${getCause(cause, options, deep + 1)}`;
143
+ } else if (cause instanceof AggregateError) {
144
+ const errors = getErrors(cause, options, deep);
145
+ if (errors !== void 0) {
146
+ message += `
147
+ ${errors}`;
148
+ }
149
+ }
150
+ return `
151
+ ${message}`;
152
+ };
153
+ const getStacktrace = (stack, options) => (stack.length > 0 ? "\n" : "") + stack.map((frame) => getMainFrame(frame, options)).join("\n");
154
+ const internalRenderError = (error, options, deep) => {
155
+ const config = {
156
+ cwd: cwd(),
157
+ displayShortPath: false,
158
+ filterStacktrace: void 0,
159
+ framesMaxLimit: Number.POSITIVE_INFINITY,
160
+ hideErrorCauseCodeView: false,
161
+ hideErrorCodeView: false,
162
+ hideErrorErrorsCodeView: false,
163
+ hideErrorTitle: false,
164
+ hideMessage: false,
165
+ indentation: 4,
166
+ linesAbove: 2,
167
+ linesBelow: 3,
168
+ prefix: "",
169
+ showGutter: true,
170
+ showLineNumbers: true,
171
+ tabWidth: 4,
172
+ ...options,
173
+ color: {
174
+ fileLine: (value) => value,
175
+ gutter: (value) => value,
176
+ hint: (value) => value,
177
+ marker: (value) => value,
178
+ message: (value) => value,
179
+ method: (value) => value,
180
+ title: (value) => value,
181
+ ...options.color
182
+ }
183
+ };
184
+ const stack = parseStacktrace(error, {
185
+ filter: options.filterStacktrace,
186
+ frameLimit: config.framesMaxLimit
187
+ });
188
+ const mainFrame = stack.shift();
189
+ return [
190
+ options.hideMessage ? void 0 : getMessage(error, config, deep),
191
+ getHint(error, config, deep),
192
+ mainFrame ? getMainFrame(mainFrame, config, deep) : void 0,
193
+ mainFrame && !config.hideErrorCodeView ? getCode(mainFrame, config, deep) : void 0,
194
+ error instanceof AggregateError ? getErrors(error, config, deep) : void 0,
195
+ error.cause === void 0 ? void 0 : getCause(error, config, deep),
196
+ stack.length > 0 ? getStacktrace(stack, config) : void 0
197
+ ].filter(Boolean).join("\n").replaceAll("\\", "/");
198
+ };
199
+ const renderError = (error, options = {}) => {
200
+ if (options.framesMaxLimit !== void 0 && options.framesMaxLimit <= 0) {
201
+ throw new RangeError("The 'framesMaxLimit' option must be a positive number");
202
+ }
203
+ return internalRenderError(error, options, 0);
204
+ };
205
+
206
+ export { renderError };
@@ -0,0 +1,207 @@
1
+ const code = (s) => `\`\`\`
2
+ ${s.trim()}
3
+ \`\`\``;
4
+ const bash = (s) => `\`\`\`bash
5
+ ${s.trim()}
6
+ \`\`\``;
7
+ const ts = (s) => `\`\`\`ts
8
+ ${s.trim()}
9
+ \`\`\``;
10
+ const js = (s) => `\`\`\`js
11
+ ${s.trim()}
12
+ \`\`\``;
13
+ const has = (message, ...needles) => {
14
+ const lower = message.toLowerCase();
15
+ return needles.some((n) => lower.includes(n.toLowerCase()));
16
+ };
17
+ const rules = [
18
+ {
19
+ name: "esm-cjs-interop",
20
+ test: (error) => {
21
+ const message = (error?.message || String(error || "")).toString();
22
+ if (has(
23
+ message,
24
+ "err_require_esm",
25
+ "cannot use import statement outside a module",
26
+ "must use import to load es module",
27
+ "require() of es module",
28
+ "does not provide an export named"
29
+ )) {
30
+ return {
31
+ md: [
32
+ "Your project or a dependency may be mixing CommonJS and ES Modules.",
33
+ "",
34
+ "Try:",
35
+ "- Ensure package.json has the correct `type` (either `module` or `commonjs`).",
36
+ "- Use dynamic `import()` when requiring ESM from CJS.",
37
+ "- Prefer ESM-compatible entrypoints from dependencies.",
38
+ "- In Node, align `module` resolution with your bundler config.",
39
+ "",
40
+ "Check Node resolution:",
41
+ bash("node -v\ncat package.json | jq .type"),
42
+ "",
43
+ "Example dynamic import in CJS:",
44
+ js("(async () => { const mod = await import('some-esm'); mod.default(); })();")
45
+ ].join("\n"),
46
+ title: "ESM/CJS interop"
47
+ };
48
+ }
49
+ return void 0;
50
+ }
51
+ },
52
+ {
53
+ name: "missing-default-export",
54
+ test: (error) => {
55
+ const message = (error?.message || String(error || "")).toString();
56
+ if (has(message, "default export not found", "has no default export", "does not provide an export named 'default'", "is not exported from")) {
57
+ return {
58
+ md: [
59
+ "Verify your import/export shapes.",
60
+ "",
61
+ "Default export example:",
62
+ ts("export default function Component() {}\n// import Component from './file'"),
63
+ "",
64
+ "Named export example:",
65
+ ts("export function Component() {}\n// import { Component } from './file'")
66
+ ].join("\n"),
67
+ title: "Export mismatch (default vs named)"
68
+ };
69
+ }
70
+ return void 0;
71
+ }
72
+ },
73
+ {
74
+ name: "port-in-use",
75
+ test: (error) => {
76
+ const message = (error?.message || String(error || "")).toString();
77
+ if (has(message, "eaddrinuse", "address already in use", "listen eaddrinuse")) {
78
+ return {
79
+ md: [
80
+ "Another process is using the port.",
81
+ "",
82
+ "Change the port or stop the other process.",
83
+ "",
84
+ "On macOS/Linux:",
85
+ bash("lsof -i :3000\nkill -9 <PID>"),
86
+ "",
87
+ "On Windows (PowerShell):",
88
+ bash("netstat -ano | findstr :3000\ntaskkill /PID <PID> /F")
89
+ ].join("\n"),
90
+ title: "Port already in use"
91
+ };
92
+ }
93
+ return void 0;
94
+ }
95
+ },
96
+ {
97
+ name: "file-not-found-or-case",
98
+ test: (error, file) => {
99
+ const message = (error?.message || String(error || "")).toString();
100
+ if (has(message, "enoent", "module not found", "cannot find module")) {
101
+ return {
102
+ md: [
103
+ "Check the import path and filename case (Linux/macOS are case-sensitive).",
104
+ "If using TS path aliases, verify `tsconfig.paths` and bundler aliases.",
105
+ "",
106
+ "Current file:",
107
+ code(`${file.file}:${file.line}`)
108
+ ].join("\n"),
109
+ title: "Missing file or path case mismatch"
110
+ };
111
+ }
112
+ return void 0;
113
+ }
114
+ },
115
+ {
116
+ name: "ts-path-mapping",
117
+ test: (error) => {
118
+ const message = (error?.message || String(error || "")).toString();
119
+ if (has(message, "ts2307", "cannot find module") || message.includes("TS2307")) {
120
+ return {
121
+ md: [
122
+ "If you use path aliases, align TS `paths` with Vite/Webpack resolve aliases.",
123
+ "Ensure file extensions are correct and included in resolver.",
124
+ "",
125
+ "tsconfig.json excerpt:",
126
+ ts(`{
127
+ "compilerOptions": {
128
+ "baseUrl": ".",
129
+ "paths": { "@/*": ["src/*"] }
130
+ }
131
+ }`)
132
+ ].join("\n"),
133
+ title: "TypeScript path mapping / resolution"
134
+ };
135
+ }
136
+ return void 0;
137
+ }
138
+ },
139
+ {
140
+ name: "network-dns-enotfound",
141
+ test: (error) => {
142
+ const message = (error?.message || String(error || "")).toString();
143
+ if (has(message, "enotfound", "getaddrinfo enotfound", "dns", "fetch failed", "ecconnrefused", "econnrefused")) {
144
+ return {
145
+ md: [
146
+ "The host may be unreachable or misconfigured.",
147
+ "",
148
+ "Try:",
149
+ "- Verify the hostname and protocol (http/https).",
150
+ "- Check VPN/proxy and firewall.",
151
+ "- Confirm the service is running and listening on the expected port.",
152
+ "",
153
+ bash("ping <host>\nnslookup <host>\ncurl -v http://<host>:<port>")
154
+ ].join("\n"),
155
+ title: "Network/DNS connection issue"
156
+ };
157
+ }
158
+ return void 0;
159
+ }
160
+ },
161
+ {
162
+ name: "undefined-property",
163
+ test: (error) => {
164
+ const message = (error?.message || String(error || "")).toString();
165
+ if (has(message, "cannot read properties of undefined", "reading '")) {
166
+ return {
167
+ md: [
168
+ "A variable or function returned `undefined`.",
169
+ "",
170
+ "Mitigations:",
171
+ "- Add nullish checks before property access.",
172
+ "- Validate function return values and input props/state.",
173
+ "",
174
+ ts("const value = maybe?.prop; // or: if (maybe) { use(maybe.prop) }")
175
+ ].join("\n"),
176
+ title: "Accessing property of undefined"
177
+ };
178
+ }
179
+ return void 0;
180
+ }
181
+ }
182
+ ];
183
+ const ruleBasedFinder = {
184
+ handle: async (error, file) => {
185
+ try {
186
+ const matches = rules.map((r) => {
187
+ return { match: r.test(error, file), rule: r };
188
+ }).filter((x) => Boolean(x.match));
189
+ if (matches.length === 0) {
190
+ return void 0;
191
+ }
192
+ const sections = matches.toSorted((a, b) => (a.match.priority || 0) - (b.match.priority || 0)).map((m) => `#### ${m.match.title}
193
+
194
+ ${m.match.md}`).join("\n\n---\n\n");
195
+ if (sections === "") {
196
+ return void 0;
197
+ }
198
+ return { body: sections, header: "### Potential fixes detected" };
199
+ } catch {
200
+ return void 0;
201
+ }
202
+ },
203
+ name: "ruleBasedHints",
204
+ priority: 0
205
+ };
206
+
207
+ export { ruleBasedFinder as default };