Skip to content

Conversation

@SoerenLinkFides
Copy link

@SoerenLinkFides SoerenLinkFides commented Oct 30, 2025

This PR adds fragment support to nestjs-query-graphql's simplifyResolveInfo method.
Previously, fields only included in a fragment were missing from the QueryService opts.resolveInfo field.

This does not affect inline fragments, as those are defined using a different Kind (Kind.INLINE_FRAGMENT).

There is no open issue for this PR.

Summary by CodeRabbit

  • Bug Fixes
    • Improved GraphQL fragment resolution so fragment spreads are correctly inlined before processing.
    • Now respects @include and @Skip directives when resolving fragments, avoiding inclusion of filtered fragments.
    • Handles nested fragments reliably, improving accuracy of query result construction.

@coderabbitai
Copy link

coderabbitai bot commented Oct 30, 2025

Walkthrough

Introduces an inlineFragments helper that recursively resolves and inlines fragment spreads (honoring @include/@Skip) using resolveInfo.fragments, and updates parseFieldNodes to apply this inlining to selections before building the resolve-info tree.

Changes

Cohort / File(s) Summary
Fragment spread inlining
packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts
Added inlineFragments helper to recursively inline FRAGMENT_SPREAD selections via resolveInfo.fragments, handling directives (@include, @skip) and nested fragments; parseFieldNodes now applies this inlining to selections before tree construction.

Sequence Diagram(s)

sequenceDiagram
    participant Caller as parseFieldNodes
    participant AST as FieldNodes AST
    participant Frags as resolveInfo.fragments
    participant Inline as inlineFragments
    participant Tree as Reduction / Tree Builder

    Caller->>AST: receive fieldNodes selections
    Caller->>Inline: inlineFragments(selections, resolveInfo)
    Inline->>AST: inspect each selection
    alt selection is FRAGMENT_SPREAD
        Inline->>Frags: lookup fragment by name
        alt directives include fragment
            Frags-->>Inline: fragment.selectionSet
            Inline->>Inline: recursively inline nested spreads
        else directives exclude fragment
            Frags-->>Inline: []
        end
    else selection is FIELD / INLINE_FRAGMENT
        AST-->>Inline: keep selection (apply directive checks)
    end
    Inline-->>Caller: return expanded selections
    Caller->>Tree: reduce expanded selections into resolve-info tree
    Tree-->>Caller: built resolve-info structure
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect inlineFragments recursion for circular fragment references and stack-safety.
  • Verify correct handling of @include/@skip directive evaluation and truthiness semantics.
  • Ensure metadata (aliases, arguments, directives, location) is preserved when inlining.
  • Confirm fallback behavior for missing fragments and performance implications for large/deep fragment graphs.

Poem

🐰 I hop through spreads and tiny skips,
I gather nodes from hidden ships,
Recursing soft through fragment leaves,
Inlined and tidy — no loose sheaves,
A rabbit's patchwork, stitched and lit. ✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "feat: support fragment parsing in parseFieldNodes" directly aligns with the main changes described in the changeset. The raw summary confirms that the primary modification is introducing fragment inlining logic to the parseFieldNodes function through a new inlineFragments helper, which addresses the objective of enabling fields within fragments to be included in resolveInfo. The title is concise, specific, and clearly conveys the core change without vague terminology or unnecessary noise, making it meaningful for teammates reviewing the commit history.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c7ed50a and f8625da.

📒 Files selected for processing (1)
  • packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts (1)

73-77: Consider adding error handling for missing fragments.

When a fragment reference is not found in resolveInfo.fragments, the code silently returns an empty array. While this might be intentional, it could hide configuration errors or typos in fragment names. Consider logging a warning in development mode to help with debugging.

  if (ast.kind === Kind.FRAGMENT_SPREAD) {
    const fragment = resolveInfo.fragments[ast.name.value]
    if (fragment) {
      return fragment.selectionSet.selections
+   } else {
+     // Optional: log warning for missing fragment
+     console.warn(`Fragment "${ast.name.value}" not found in resolveInfo.fragments`)
    }
    return []
  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d2689f and c7ed50a.

📒 Files selected for processing (1)
  • packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts (1 hunks)
🧰 Additional context used
🪛 ESLint
packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts

[error] 71-71: Replace ast with (ast)

(prettier/prettier)


[error] 73-73: Delete ;

(prettier/prettier)


[error] 75-75: Delete ;

(prettier/prettier)


[error] 77-77: Delete ;

(prettier/prettier)


[error] 79-79: Delete ;

(prettier/prettier)

🔇 Additional comments (1)
packages/query-graphql/src/decorators/graphql-resolve-info.utils.ts (1)

82-82: Good: Reduce loop now operates on inlined fragments.

This change correctly processes the inlined fragment selections instead of the original ASTs. Once the fragment inlining logic is fixed to handle nested spreads and directives (see previous comments), this will properly include all fragment fields in the resolve info.

@nx-cloud
Copy link

nx-cloud bot commented Oct 30, 2025

View your CI Pipeline Execution ↗ for commit f8625da

Command Status Duration Result
nx run-many --target=e2e --all ✅ Succeeded 1m 52s View ↗
nx run-many --target=test --all ✅ Succeeded 39s View ↗
nx run-many --target=lint --all ✅ Succeeded 29s View ↗
nx run-many --target=build --all ✅ Succeeded 5s View ↗
nx run workspace:version ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2025-11-08 14:00:27 UTC

@SoerenLinkFides
Copy link
Author

Sorry, seems this topic is a little more complicated.
Will try and resolve the issues in this PR in the next few days

@SoerenLinkFides
Copy link
Author

The PR should be ready 🙂
If there's more explanation needed from my side as to what issue this solves or an example repository, I'll be happy to provide either or both.

@TriPSs
Copy link
Owner

TriPSs commented Nov 9, 2025

@SoerenLinkFides small code sample here would be appreciated to explain what it fixes :)

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