fix(client): apply result extensions for nested and fluent relations#29218
Conversation
…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
|
Note Reviews pausedIt 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 Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds 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
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
packages/client/src/runtime/core/extensions/resolveResultExtensionContext.test.ts
Outdated
Show resolved
Hide resolved
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
Show resolved
Hide resolved
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
Show resolved
Hide resolved
- Rename new resolver files to kebab-case\n- Update imports to new filenames\n- Add doc comment to exported resolveResultExtensionContext
packages/client/src/runtime/core/extensions/resolve-result-extension-context.test.ts
Outdated
Show resolved
Hide resolved
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
Outdated
Show resolved
Hide resolved
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
Outdated
Show resolved
Hide resolved
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
Show resolved
Hide resolved
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
Show resolved
Hide resolved
packages/client/src/runtime/core/extensions/resolve-result-extension-context.ts
Show resolved
Hide resolved
|
@jacek-prisma I've applied your suggestions and fixed a minor typescript error in a test file. Should be good to go now. |
…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 -->
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
Improvements
Bug Fixes
Tests