/** * ESM resolve hook: map `@shared/foo.js` → `shared/src/foo.ts` for smoke-extractors. * Extractor manifests use tsconfig path aliases; plain `tsx` does not apply them to * dynamic `import()` unless each package's tsconfig includes `manifest.ts`. */ import { existsSync } from "node:fs"; import { dirname, join } from "node:path"; import { fileURLToPath, pathToFileURL } from "node:url"; const repoRoot = join(dirname(fileURLToPath(import.meta.url)), ".."); const sharedSrc = join(repoRoot, "shared", "src"); export async function resolve(specifier, context, nextResolve) { if (specifier.startsWith("@shared/")) { const subpath = specifier.slice("@shared/".length).replace(/\.js$/i, ""); const candidates = [ join(sharedSrc, `${subpath}.ts`), join(sharedSrc, `${subpath}.tsx`), join(sharedSrc, subpath, "index.ts"), ]; for (const filePath of candidates) { if (existsSync(filePath)) { return nextResolve(pathToFileURL(filePath).href, context); } } } return nextResolve(specifier, context); }