Skip to content

[2.x] Add resolveTypePath helper to visitors-core - #1190

Merged
lorisleiva merged 1 commit into
mainfrom
09-29-add_resolvetypepath_helper_to_visitors-core
Sep 30, 2026
Merged

lorisleiva merged 1 commit into
mainfrom
09-29-add_resolvetypepath_helper_to_visitors-core

Conversation

@lorisleiva

@lorisleiva lorisleiva commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

This PR adds resolveTypePath to @codama/visitors-core, which resolves a path expression such as config.fees[0] against a type and returns the full NodePath of the node it points to.

  • Field segments select struct fields and index segments select tuple items or the items of arrays and sets.
  • Struct fields, enum variants and definedTypeLinkNodes along the way resolve to their types, following links through the path of their definitions so subsequent links resolve in the right program. The last node is returned as addressed.
  • Adds the generic CANNOT_RESOLVE_PATH error, thrown when a segment of a path expression cannot be followed, and throws LINKED_NODE_NOT_FOUND for dangling links.
  • Moves parsePath from @codama/visitors to @codama/visitors-core and documents both helpers in the README.

@codama/dynamic-parsers now uses it to resolve fieldDiscriminatorNode paths, attaching the CANNOT_RESOLVE_PATH error as the cause of DISCRIMINATOR_FIELD_NOT_FOUND.

@changeset-bot

changeset-bot Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 145c154

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@lorisleiva

Copy link
Copy Markdown
Member Author

@trevor-cortex

@trevor-cortex trevor-cortex left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Adds resolveTypePath(source, path, linkables) to @codama/visitors-core: it walks a PathString (config.fees[0]) from the type at the end of source, transparently resolving struct fields / enum variants / definedTypeLinkNodes to their underlying type between segments, and returns the full NodePath of the addressed node. Links are followed through the definition's path so nested links resolve in the defining program, alias cycles are detected via a per-segment Set<DefinedTypeNode>, and failures surface as the new generic CANNOT_RESOLVE_PATH (with nodePath / path / segment context) or the existing LINKED_NODE_NOT_FOUND. parsePath + PathSegment move from @codama/visitors (where they weren't publicly exported) into visitors-core, and @codama/dynamic-parsers replaces its bespoke findDataField with the helper, wrapping CANNOT_RESOLVE_PATH as the cause of DISCRIMINATOR_FIELD_NOT_FOUND and rejecting non-struct-field results (e.g. pair[0]).

The implementation is clean and the semantics are well pinned down by tests (cross-program link following, "last node returned as addressed", per-segment error contexts, dangling links, alias cycles). The dynamic-parsers migration is behaviour-preserving for the previously supported cases and strictly more informative on failure. The types line up: RegisteredTypeNode = EnumVariantTypeNode | StandaloneTypeNode | StructFieldTypeNode in 2.x, so TypePathNode = DefinedTypeLinkNode | RegisteredTypeNode covers exactly the set resolveContainer knows how to unwrap.

Things to address

  • Missing changeset. CONTRIBUTING.md asks for one on any user-facing change, and this PR has several: a new public export in @codama/visitors-core (resolveTypePath, parsePath, PathSegment, TypePath, TypePathNode), a new error code in @codama/errors, and the cause/tuple-item behaviour change in @codama/dynamic-parsers. visitors-core and errors are in the fixed group so one entry covers both; dynamic-parsers versions independently and probably wants its own line. Happy to approve once that's in.
  • Import member ordering in packages/dynamic-parsers/src/discriminators.ts, packages/dynamic-parsers/test/discriminators.test.ts (L6) and packages/visitors-core/test/resolveTypePath.test.ts (L1): CODAMA_ERROR__CANNOT_RESOLVE_PATH is inserted after DISCRIMINATOR_* / LINKED_NODE_NOT_FOUND rather than alphabetically. packages/errors/src/context.ts and messages.ts have it in the right place. Every other import block in these files is case-insensitively sorted, so I'd expect oxlint to flag this — pnpm lint:fix should sort it out. (Inline comment on the first occurrence only.)

Non-blocking notes

  • createPathResolver.rewrite in packages/visitors/src/updateHelpers.ts still hand-rolls the same walk (link following via linkables.getPath, followedDefinedTypes cycle set, tuple/array/set indexing). It can't just call resolveTypePath because it needs per-segment owner/prefix bookkeeping and must be lenient rather than throw, so I don't think this PR should touch it — but it's now the second copy of the stepping logic. If a third consumer shows up, exposing a per-segment step (resolveContainer + one segment application) from resolveTypePath.ts would let rewrite reuse it.
  • Array/set indices aren't bounds-checked against fixedCountNode ([5] on a 2-element array resolves to the item). That matches rewrite and the README wording ("the item of an array or set"), so I assume it's deliberate; left a one-line docblock nit inline.

Notes for subsequent reviewers

  • The dynamic-parsers change keeps context.stack.withPath(resolved, …) semantics identical: the old findDataField also switched to the linked definition's path when it followed a link, so codec resolution inside the discriminator field's type still happens in the defining program.
  • expectCodamaError in the new test file compares error.context with toStrictEqual, which is sufficient to also assert the error code since CodamaError stores __code in context.
  • parsePath was only ever exported from updateHelpers.ts, not from the @codama/visitors barrel, so the move is additive rather than breaking.

Comment thread packages/dynamic-parsers/src/discriminators.ts Outdated
Comment thread packages/visitors-core/src/resolveTypePath.ts
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from 3a6273a to 68219e1 Compare September 30, 2026 14:09
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from 1cebd8a to 6c5a99a Compare September 30, 2026 14:09
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from 68219e1 to 6196991 Compare September 30, 2026 14:11
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from 6c5a99a to 2b6c7e2 Compare September 30, 2026 14:11
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from 6196991 to dc5006a Compare September 30, 2026 14:12
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch 2 times, most recently from 255d061 to 96a40c4 Compare September 30, 2026 14:13
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from dc5006a to 3e253c1 Compare September 30, 2026 14:13
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from 255d061 to 96a40c4 Compare September 30, 2026 14:13
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch 2 times, most recently from 3e253c1 to 84c1df6 Compare September 30, 2026 14:14
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from 96a40c4 to 482f178 Compare September 30, 2026 14:14
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from 84c1df6 to e61eb74 Compare September 30, 2026 14:15
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from 482f178 to 03fbdb7 Compare September 30, 2026 14:15
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from e61eb74 to db2faeb Compare September 30, 2026 14:16
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from 03fbdb7 to 053d723 Compare September 30, 2026 14:16
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from db2faeb to 85168fd Compare September 30, 2026 14:17
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch 2 times, most recently from 79f9ef3 to f5179fa Compare September 30, 2026 14:18
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch from 85168fd to b694ad7 Compare September 30, 2026 14:18
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from f5179fa to adec517 Compare September 30, 2026 14:18
@lorisleiva
lorisleiva force-pushed the 09-28-adapt_dynamic-parsers_to_codama_v2 branch 2 times, most recently from 6651ab9 to c6ff34d Compare September 30, 2026 14:19
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from adec517 to aedbf44 Compare September 30, 2026 14:19
Base automatically changed from 09-28-adapt_dynamic-parsers_to_codama_v2 to main September 30, 2026 14:20
@lorisleiva
lorisleiva force-pushed the 09-29-add_resolvetypepath_helper_to_visitors-core branch from aedbf44 to 145c154 Compare September 30, 2026 14:20
@lorisleiva
lorisleiva marked this pull request as ready for review September 30, 2026 14:20
@lorisleiva
lorisleiva merged commit 9e49f67 into main Sep 30, 2026
0 of 2 checks passed
@lorisleiva
lorisleiva deleted the 09-29-add_resolvetypepath_helper_to_visitors-core branch September 30, 2026 14:20
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.

2 participants