Skip to content

fix(pipeline): resolve ../ climbs in tsconfig path alias targets#766

Open
apappas1129 wants to merge 2 commits into
DeusData:mainfrom
apappas1129:fix/730-tsconfig-alias-dotdot-climb
Open

fix(pipeline): resolve ../ climbs in tsconfig path alias targets#766
apappas1129 wants to merge 2 commits into
DeusData:mainfrom
apappas1129:fix/730-tsconfig-alias-dotdot-climb

Conversation

@apappas1129

@apappas1129 apappas1129 commented Jul 2, 2026

Copy link
Copy Markdown

What does this PR do?

Closes #730: tsconfig.json paths aliases that climb out of their config's
directory (e.g. a tsconfig at apps/web/tsconfig.json mapping @shared/*
to ../../packages/shared/src/* — the standard monorepo layout) resolved
to a broken repo-relative path.

resolve_target_relative() in src/pipeline/path_alias.c only stripped a
single leading "./" and otherwise concatenated dir_prefix and target
verbatim, so a ../../ target left literal ".." segments in the
resolved path (e.g. apps/web/../../packages/shared/src/*). That string
never matches a real module's FQN, since cbm_pipeline_fqn_module
tokenizes on / without collapsing .. — so every cross-package import
through such an alias was invisible to the graph and looked like dead
code.

This is also why #308 regressed: the original fix (v0.7.0) handled the
simple "./src" case but never normalized ../ climbs, which is the
pattern monorepos actually use for cross-package aliases.

The fix makes resolve_target_relative() walk the target's path segments
and pop a directory off dir_prefix for each .., mirroring the
normalization cbm_pipeline_resolve_relative_import already does for
plain relative imports in fqn.c.

Checklist

  • Every commit is signed off (git commit -s)
  • Tests pass locally (make -f Makefile.cbm test) — full suite green
    except one pre-existing, unrelated RSS-ceiling test in
    test_incremental.c (2550MB vs 2048MB limit) on this machine
  • Lint passes (make -f Makefile.cbm lint-ci) — could not verify
    locally, cppcheck/clang-format are not installed in this
    environment; relying on CI
  • New behavior is covered by a test: added
    path_alias_loader_monorepo_dotdot_climb in tests/test_path_alias.c,
    an end-to-end test with a real tsconfig containing a ../../ alias
    target, asserting the resolved path is correct

tsconfig.json `paths` entries that climb out of their config's directory
(e.g. a tsconfig at apps/web/tsconfig.json mapping "@shared/*" to
"../../packages/shared/src/*", the standard monorepo layout) resolved to
a broken path: resolve_target_relative() only stripped a single leading
"./" and otherwise concatenated dir_prefix and target verbatim, leaving
literal ".." segments in the result. Those never match a real module's
FQN, since cbm_pipeline_fqn_module tokenizes on '/' without collapsing
them - so every cross-package import through such an alias looked like
dead code.

resolve_target_relative now walks the target's path segments and pops
a directory off dir_prefix for each "..", the same normalization
cbm_pipeline_resolve_relative_import already does for plain relative
imports.

Closes DeusData#730.

Signed-off-by: Alexandros Pappas <11921291+apappas1129@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

codebase-memory graph it doesn't resolve TypeScript aliases like @packages/shared

1 participant