| 17 | const cwd = process.cwd(); |
| 18 | |
| 19 | function getCallSite(): string | null { |
| 20 | const stack = new Error().stack; |
| 21 | |
| 22 | if (!stack) { |
| 23 | return null; |
| 24 | } |
| 25 | |
| 26 | const lines = stack.split('\n'); |
| 27 | |
| 28 | // Find the first stack frame that's not in setup.ts |
| 29 | for (let i = 1; i < lines.length; i++) { |
| 30 | const callerLine = lines[i]; |
| 31 | |
| 32 | if (!callerLine || callerLine.includes('tests/setup.ts')) { |
| 33 | continue; |
| 34 | } |
| 35 | |
| 36 | const match = /\((.*):(\d+):(\d+)\)/.exec(callerLine) || /at (.*):(\d+):(\d+)/.exec(callerLine); |
| 37 | |
| 38 | if (!match) { |
| 39 | continue; |
| 40 | } |
| 41 | |
| 42 | // eslint-disable-next-line prefer-const |
| 43 | let [, file, line, col] = match; |
| 44 | |
| 45 | if (file.startsWith('file://')) { |
| 46 | file = fileURLToPath(file); |
| 47 | } |
| 48 | |
| 49 | if (file.startsWith('node:')) { |
| 50 | continue; |
| 51 | } |
| 52 | |
| 53 | const rel = path.relative(cwd, file); |
| 54 | |
| 55 | return `${rel}:${line}:${col}`; |
| 56 | } |
| 57 | |
| 58 | return null; |
| 59 | } |
| 60 | |
| 61 | for (const key of ['log', 'warn', 'error'] as const) { |
| 62 | const original = console[key].bind(console); |