Refactor (packages/codemode/src/tool-schema.ts:43): Function with high complexity (count = 18): hasUnresolvedRef - #72
Open
vaishnavipalas wants to merge 4 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
P1B: Starter Task: Refactoring PR
1. Issue
Link to the associated GitHub issue: #68
Full path to the refactored file: packages/codemode/src/tool-schema.ts
What do you think this file does?
I think tool-schema.ts is responsible for converting JSON Schema (and Effect Schema) definitions into TypeScript-style type signatures. For example, it renders something like tools.orders.lookup(input: {...}): Promise<{...}> so that a tool catalog can display readable type signatures. To do this, the file has to handle $ref/$defs resolution, unions, and nested properties, and it needs to safely detect cycles or missing references so that it can fall back to "unknown" instead of crashing or looping forever.
What is the scope of your refactoring within that file?
I split the hasUnresolvedRef function into three separate functions:
I didn't touch any other functions in the file, and the behavior of the code is unchanged, only its internal structure changed.
Which Qlty‑reported issue did you address?
"Function with high complexity," count = 18, in hasUnresolvedRef (line 43).
2. Refactoring
How did the specific issue you chose impact the codebase’s maintainability?
At a complexity score of 18, hasUnresolvedRef packed ref-resolution logic, cycle detection, and child-schema traversal all into one function with many branch points — nested ternaries, a triple || condition, optional chaining, and inline array-building with conditionals. This made it hard to reason about which condition caused an "unresolved" verdict, hard to unit-test any single piece in isolation, and risky to modify, since a small change to one concern (like how child schemas are gathered) could silently affect the unrelated ref-resolution logic sitting in the same function body.
What changes did you make to resolve the issue?
I split the function into three:
The algorithm itself didn't change; I just distributed the same logic across named, single-purpose functions.
How do your changes improve maintainability? Did you consider alternatives?
Each function now has a low, independent complexity and can be read and tested on its own. This is actually what allowed me to identify a genuine coverage gap in the ref-propagation path that the original function's tests didn't exercise. I considered simply suppressing the complexity warning, but that wouldn't have addressed the underlying readability issue. I also considered a more substantial restructuring, such as a general-purpose schema-visitor, but concluded that extracting the two responsibilities already implicit in the original function was the smallest change that resolved the issue without altering the algorithm or its call sites.
3. Validation
How did you validate that the change is correct?
I added five test cases in test/signature.test.ts targeting the specific branches of the original hasUnresolvedRef logic: a $ref naming a missing $defs entry, a self-referencing cycle, a mutually recursive cycle across two $defs entries, a cycle reached only through anyOf/items rather than properties, and a resolved $ref whose target is itself unresolved (reached only through allOf). I then ran bun test to confirm that every line inside these new functions was actually executed. I also confirmed that the full existing test suite still passes with no regressions.
Attach a screenshot of the test coverage showing the lines were executed by the tests.

Attach a screenshot showing the tests that cover the change passing during CI

Attach a screenshot of

qlty smells --no-snippets <full/path/to/file.ts>showing fewer reported issues after the changes.