Repository navigation
TypeScript: a method call on an object imported through a re-export barrel produces no CALLS edge #2718
Description
v0.12.1, macOS arm64, index_repository --mode full. Follow-up to #1974, which v0.12.0 fixed for us — thank you!
Repro
Seven files, a Bun/npm workspace with one library package that re-exports from src/index.ts.
package.json
{ "name": "barrel-repro", "private": true, "workspaces": ["apps/*", "packages/*"] }packages/lib/package.json
{ "name": "@x/lib", "type": "module", "module": "src/index.ts" }packages/lib/src/repo.ts
export const fooRepo = { async findOne(id: string) { return id } }
export function plainFn(id: string) { return id }packages/lib/src/index.ts
export { fooRepo, plainFn } from './repo'packages/lib/src/internal.ts — same package, through its own barrel
import { fooRepo, plainFn } from './index'
export async function viaOwnBarrel() { await fooRepo.findOne('c'); plainFn('c') }apps/app/package.json
{ "name": "@x/app", "type": "module", "dependencies": { "@x/lib": "workspace:*" } }apps/app/src/job.ts — through the package name
import { fooRepo, plainFn } from '@x/lib'
export async function viaPackage() { await fooRepo.findOne('a'); plainFn('a') }apps/app/src/direct.ts — control: straight from the defining file
import { fooRepo, plainFn } from '../../../packages/lib/src/repo'
export async function viaDirect() { await fooRepo.findOne('b'); plainFn('b') }Observed
IMPORTS edges are all there: job.ts → lib/src/index.ts, internal.ts → lib/src/index.ts, lib/src/index.ts → lib/src/repo.ts, direct.ts → lib/src/repo.ts.
CALLS edges:
| caller | → findOne |
→ plainFn |
|---|---|---|
viaDirect |
✅ lsp_ts_namespace |
✅ lsp_ts_import |
viaPackage |
❌ none (only USAGE → fooRepo) |
unique_name |
viaOwnBarrel |
❌ none (only USAGE → fooRepo) |
unique_name |
So the package specifier is not the problem — the same loss happens with a relative ./index barrel. The chain is lost at the export { … } from './repo' hop: the method on the re-exported object gets no edge at all, and the plain function lands only via the name heuristic rather than the import (with a non-unique name that path is not guaranteed). Same result with "main" or "exports": { ".": "./src/index.ts" } instead of "module".
Expected
A named re-export is followed to the defining module the way a direct import is, so viaPackage → findOne and viaOwnBarrel → findOne resolve like viaDirect → findOne, and plainFn resolves via the import.
Impact
Our Bun monorepo has one library package that re-exports its repositories (object literals) from src/index.ts; the other apps import them by package name. After v0.12.1 intra-package calls resolve, but every cross-app call to those repositories still shows zero callers — e.g. expireLapsedSubscriptions, needsRun, takeDirty, insertIncoming, bumpInbound, each with 1–2 real call sites. As in #1974, this is indistinguishable from a true negative.
Related but different: #1557 §3 (aliased re-exports produce no node), #2297 (renamed named import).
Activity