(jsPath: string)
| 41 | } |
| 42 | |
| 43 | function findInlineOrLinkedMapFromJs(jsPath: string): { key: string; text: string } | null { |
| 44 | const jsText = safeReadText(jsPath); |
| 45 | if (!jsText) return null; |
| 46 | |
| 47 | // Look for the last sourceMappingURL directive |
| 48 | // Supports both //# and /*# */ styles; capture up to line end or */ |
| 49 | const re = /[#@]\s*sourceMappingURL=([^\s*]+)(?:\s*\*\/)?/g; |
| 50 | let match: RegExpExecArray | null = null; |
| 51 | let last: RegExpExecArray | null = null; |
| 52 | while ((match = re.exec(jsText))) last = match; |
| 53 | if (!last) return null; |
| 54 | |
| 55 | const url = last[1]; |
| 56 | if (url.startsWith('data:application/json')) { |
| 57 | const base64 = url.split(',')[1]; |
| 58 | if (!base64) return null; |
| 59 | try { |
| 60 | const text = atob(base64); |
| 61 | return { key: `inline:${jsPath}`, text }; |
| 62 | } catch (_) { |
| 63 | return null; |
| 64 | } |
| 65 | } |
| 66 | |
| 67 | // Linked .map file (relative) |
| 68 | const jsDir = jsPath.substring(0, jsPath.lastIndexOf('/')); |
| 69 | const mapPath = `${jsDir}/${url}`; |
| 70 | const text = safeReadText(mapPath); |
| 71 | if (text) { |
| 72 | return { key: mapPath, text }; |
| 73 | } |
| 74 | return null; |
| 75 | } |
| 76 | |
| 77 | function loadAndExtractMap(mapPath: string, fallbackJsPath?: string) { |
| 78 | // check cache first |
no test coverage detected