(projectRoot: string)
| 12 | let cachedRoot: string = ""; |
| 13 | |
| 14 | export function loadTypeScript(projectRoot: string): any | null { |
| 15 | if (cached !== undefined && cachedRoot === projectRoot) return cached; |
| 16 | cachedRoot = projectRoot; |
| 17 | |
| 18 | // Strategy 1: createRequire from project root (works for npm/yarn) |
| 19 | try { |
| 20 | const req = createRequire(join(projectRoot, "package.json")); |
| 21 | cached = req("typescript"); |
| 22 | return cached; |
| 23 | } catch {} |
| 24 | |
| 25 | // Strategy 2: Direct path (works for pnpm with public-hoist-pattern) |
| 26 | try { |
| 27 | const directPath = join(projectRoot, "node_modules", "typescript"); |
| 28 | const req = createRequire(join(directPath, "package.json")); |
| 29 | cached = req(directPath); |
| 30 | return cached; |
| 31 | } catch {} |
| 32 | |
| 33 | // Strategy 3: Find in pnpm .pnpm store (strict mode fallback) |
| 34 | try { |
| 35 | const pnpmDir = join(projectRoot, "node_modules", ".pnpm"); |
| 36 | const entries = readdirSync(pnpmDir); |
| 37 | const tsDir = entries.find((e) => e.startsWith("typescript@")); |
| 38 | if (tsDir) { |
| 39 | const tsPath = join(pnpmDir, tsDir, "node_modules", "typescript"); |
| 40 | const req = createRequire(join(tsPath, "package.json")); |
| 41 | cached = req(tsPath); |
| 42 | return cached; |
| 43 | } |
| 44 | } catch {} |
| 45 | |
| 46 | // TypeScript not available — fall back to regex |
| 47 | cached = null; |
| 48 | return null; |
| 49 | } |
| 50 | |
| 51 | export function resetCache(): void { |
| 52 | cached = undefined; |
no test coverage detected