Skip to content

fix(client): apply result extensions for nested and fluent relations#29218

Merged
jacek-prisma merged 7 commits intoprisma:mainfrom
LucianBuzzo:lucianbuzzo/extension-nested-queries
Feb 18, 2026
Merged

fix(client): apply result extensions for nested and fluent relations#29218
jacek-prisma merged 7 commits intoprisma:mainfrom
LucianBuzzo:lucianbuzzo/extension-nested-queries

Conversation

@LucianBuzzo
Copy link
Copy Markdown
Contributor

@LucianBuzzo LucianBuzzo commented Feb 18, 2026

Result extensions were always applied using the root request model/args in getPrismaClient._request. That works for regular top-level results, but fluent relation calls use dataPath unpacking first, so the payload handed to applyAllResultExtensions is already the nested relation object/list. In that case, walking extensions with the root model context skips nested computed fields (for example post extensions on user.findUnique(...).posts()).

This change resolves the effective extension context from dataPath before applying result extensions. The new resolveResultExtensionContext helper strips select/include tokens, follows relation fields through runtimeDataModel, and derives the matching nested args branch. If resolution is invalid it safely falls back to the root context.

I also added regression coverage for nested reads/writes and fluent relation calls in functional extensions tests, plus focused unit tests for context resolution (including fluent-style unwrapped payload behavior).

Summary by CodeRabbit

  • New Features

    • Result extensions can compute and expose additional nested fields (e.g., derived labels) on related models.
  • Improvements

    • More reliable resolution of nested model context for result extensions across fluent select/include paths, including when relation fields are named "select" or "include".
    • Extension application now uses resolved nested context for more accurate behavior in nested queries.
  • Bug Fixes

    • Prevents dropped nested selections when selector segments appear in relation paths.
  • Tests

    • Added comprehensive unit and functional tests covering nested resolution and computed-field propagation.

…esults

Result extensions were always applied using the root request model/args in getPrismaClient._request. That works for regular top-level results, but fluent relation calls use dataPath unpacking first, so the payload handed to applyAllResultExtensions is already the nested relation object/list. In that case, walking extensions with the root model context skips nested computed fields (for example post extensions on user.findUnique(...).posts()).

This change resolves the effective extension context from dataPath before applying result extensions. The new resolveResultExtensionContext helper strips select/include tokens, follows relation fields through runtimeDataModel, and derives the matching nested args branch. If resolution is invalid it safely falls back to the root context.

I also added regression coverage for nested reads/writes and fluent relation calls in functional extensions tests, plus focused unit tests for context resolution (including fluent-style unwrapped payload behavior).

Validation run:\n- pnpm --filter @prisma/client test -- src/runtime/core/extensions\n- pnpm --filter @prisma/client test:functional:code --adapter js_better_sqlite3 extensions
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Feb 18, 2026

CLA assistant check
All committers have signed the CLA.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Feb 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds a resolver that derives result-extension context from fluent-style dataPath (alternating select/include hops), integrates it into the client request flow to compute modelName/args for result extensions, and adds unit and functional tests plus a documentation note about dataPath semantics and testing/runtime considerations.

Changes

Cohort / File(s) Summary
Documentation
AGENTS.md
Documents that the Fluent API builds dataPath as alternating `['select'
Result Extension Resolver
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
New module resolveResultExtensionContext that parses dataPath into relation hops, traverses runtimeDataModel, and resolves { modelName, args } for applying result extensions; returns root context or throws on invalid relation field.
Resolver Unit Tests
packages/client/src/runtime/core/extensions/resolve-result-extension-context.test.ts
Adds comprehensive tests for empty/root dataPath, single- and multi-hop fluent select/include resolution, missing-relation errors, defaulting nested args, literal relation fields named select/include, and applying result extensions to unwrapped fluent results.
Runtime Integration
packages/client/src/runtime/getPrismaClient.ts
Imports and invokes resolveResultExtensionContext in the request flow when a model exists; computes extensionContext from dataPath, modelName, args, and runtimeDataModel, and applies result extensions using extensionContext.modelName/args instead of requestParams.
Functional Tests (result extensions)
packages/client/tests/functional/extensions/result.ts
Adds functional tests that register result-layer extensions computing nested fields (e.g., user.fullName, post.postLabel) and validate behavior across includes/selects and nested create/update shapes, exercising fluent and nested interactions.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: applying result extensions for nested and fluent relations, which is directly supported by the code changes across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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
Copy Markdown
Contributor

@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

- Rename new resolver files to kebab-case\n- Update imports to new filenames\n- Add doc comment to exported resolveResultExtensionContext
Copy link
Copy Markdown
Contributor

@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: 1

Copy link
Copy Markdown
Contributor

@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: 1

Copy link
Copy Markdown
Contributor

@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: 1

@LucianBuzzo
Copy link
Copy Markdown
Contributor Author

@jacek-prisma I've applied your suggestions and fixed a minor typescript error in a test file. Should be good to go now.

@jacek-prisma jacek-prisma merged commit 77bfc96 into prisma:main Feb 18, 2026
253 of 254 checks passed
jacek-prisma pushed a commit that referenced this pull request Feb 19, 2026
…29218)

Result extensions were always applied using the root request model/args
in getPrismaClient._request. That works for regular top-level results,
but fluent relation calls use dataPath unpacking first, so the payload
handed to applyAllResultExtensions is already the nested relation
object/list. In that case, walking extensions with the root model
context skips nested computed fields (for example post extensions on
user.findUnique(...).posts()).

This change resolves the effective extension context from dataPath
before applying result extensions. The new resolveResultExtensionContext
helper strips select/include tokens, follows relation fields through
runtimeDataModel, and derives the matching nested args branch. If
resolution is invalid it safely falls back to the root context.

I also added regression coverage for nested reads/writes and fluent
relation calls in functional extensions tests, plus focused unit tests
for context resolution (including fluent-style unwrapped payload
behavior).


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Result extensions can compute and expose additional nested fields
(e.g., derived labels) on related models.

* **Improvements**
* More reliable resolution of nested model context for result extensions
across fluent select/include paths, including when relation fields are
named "select" or "include".
* Extension application now uses resolved nested context for more
accurate behavior in nested queries.

* **Bug Fixes**
* Prevents dropped nested selections when selector segments appear in
relation paths.

* **Tests**
* Added comprehensive unit and functional tests covering nested
resolution and computed-field propagation.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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.

3 participants