(content: string)
| 40 | |
| 41 | /** Extract exported symbol names from TS/JS source (best-effort, regex-based). */ |
| 42 | export function extractExports(content: string): Set<string> { |
| 43 | const names = new Set<string>(); |
| 44 | // export const/let/var/function/class/interface/type/enum NAME |
| 45 | const re1 = /export\s+(?:async\s+)?(?:const|let|var|function|class|interface|type|enum)\s+([A-Za-z_$][\w$]*)/g; |
| 46 | // export { A, B as C } |
| 47 | const re2 = /export\s*\{([^}]+)\}/g; |
| 48 | // export default NAME (class/function) |
| 49 | const re3 = /export\s+default\s+(?:async\s+)?(?:function|class)\s+([A-Za-z_$][\w$]*)/g; |
| 50 | let m: RegExpExecArray | null; |
| 51 | while ((m = re1.exec(content)) !== null) names.add(m[1]!); |
| 52 | while ((m = re2.exec(content)) !== null) { |
| 53 | for (const part of m[1]!.split(',')) { |
| 54 | const as = part.split(/\s+as\s+/); |
| 55 | const exported = (as[1] ?? as[0])!.trim(); |
| 56 | if (exported && exported !== 'default') names.add(exported); |
| 57 | } |
| 58 | } |
| 59 | while ((m = re3.exec(content)) !== null) names.add(m[1]!); |
| 60 | return names; |
| 61 | } |
| 62 | |
| 63 | /** Extract the named imports a file pulls from a given module path. */ |
| 64 | function importedNamesFrom(content: string, moduleHint: string): Set<string> { |
no test coverage detected