(url: string)
| 41 | * otherwise so callers can fall back to a default. |
| 42 | */ |
| 43 | export function extractUrlExtension(url: string): string | undefined { |
| 44 | // Parse via URL when possible so we only look at the pathname and never |
| 45 | // mistake a TLD (e.g. the `.com` in `https://x.com/`) for a file extension. |
| 46 | let pathname: string |
| 47 | try { |
| 48 | const parsed = new URL(url) |
| 49 | pathname = parsed.pathname |
| 50 | } catch { |
| 51 | // Fall back to treating the input as a raw path when URL parsing fails |
| 52 | // (e.g. the caller passed a bare path). Still strip ?query and #fragment. |
| 53 | pathname = url.split('?')[0]?.split('#')[0] ?? url |
| 54 | } |
| 55 | // Drop trailing slashes so `/path/audio.mp3/` still yields `mp3`. |
| 56 | const normalized = pathname.replace(/\/+$/, '') |
| 57 | // Require at least one `/` — otherwise we're looking at an empty pathname |
| 58 | // (bare-host URLs like `https://x.com/` land here after stripping the |
| 59 | // trailing slash). |
| 60 | if (!normalized.includes('/')) return undefined |
| 61 | const lastSegment = normalized.split('/').pop() |
| 62 | if (!lastSegment) return undefined |
| 63 | const extension = lastSegment.split('.').pop() |
| 64 | if (!extension || extension === lastSegment) return undefined |
| 65 | return /^[a-z0-9]{2,5}$/i.test(extension) ? extension : undefined |
| 66 | } |
| 67 | |
| 68 | /** |
| 69 | * Derive a reasonable audio content-type. Prefers the explicit MIME (stripped |
no test coverage detected