-
-
Notifications
You must be signed in to change notification settings - Fork 17
fix(orm):typing issue with deeply nested included relations #504
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
WalkthroughThe PR fixes a type inference issue where nested relations weren't properly included in query results. It refactors Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ 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 |
|
Claude finished @ymc9's task —— View job Code Review Complete ✅I've thoroughly analyzed the PR that fixes typing issues with deeply nested included relations (#503). Here's my comprehensive feedback: Summary of ChangesThis PR addresses TypeScript typing issues when using deeply nested Core Changes:
Code Quality Assessment✅ Excellent Improvements:
✅ Comprehensive Testing:
Technical AnalysisPerformance Considerations:
Backward Compatibility:
Security & Best Practices✅ Security:
✅ Best Practices:
Minor ObservationsPackage.json Script Rename: CLI Generate.ts: VerdictExcellent implementation! This PR successfully: ✅ Solves the core issue: Fixes TypeScript compilation errors with deeply nested includes No concerns or issues identified. This is a well-executed fix that improves both functionality and code quality. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
tests/regression/test/issue-503/regression.test.ts (1)
5-30: Good regression test coverage for issue #503.The test correctly reproduces the exact scenario from the issue: creating a deeply nested relation and then selecting with a nested include. The assertion
r.messages[0]?.mediaimplicitly validates that the type system now correctly exposes themediafield on the nestedmessagesresult.Consider adding an explicit type assertion to make the compile-time verification more visible:
+ // Type assertion: media should be present in the typed result + const media: { id: number; type: string } | null | undefined = r.messages[0]?.media; expect(r.messages[0]?.media).toMatchObject({ type: 'Image' });
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (9)
packages/cli/src/actions/generate.ts(1 hunks)packages/orm/src/client/crud-types.ts(2 hunks)tests/e2e/orm/schemas/typing/typecheck.ts(1 hunks)tests/regression/package.json(1 hunks)tests/regression/test/issue-503/input.ts(1 hunks)tests/regression/test/issue-503/models.ts(1 hunks)tests/regression/test/issue-503/regression.test.ts(1 hunks)tests/regression/test/issue-503/schema.ts(1 hunks)tests/regression/test/issue-503/schema.zmodel(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.zmodel
📄 CodeRabbit inference engine (CLAUDE.md)
**/*.zmodel: Always runzenstack generateafter modifying ZModel schemas
ZModel schema files should define database structure and policies that compile to TypeScript viazenstack generate
Files:
tests/regression/test/issue-503/schema.zmodel
tests/e2e/**/*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
E2E tests should validate real-world schema compatibility with established projects
Files:
tests/e2e/orm/schemas/typing/typecheck.ts
tests/**/type*.{ts,tsx}
📄 CodeRabbit inference engine (CLAUDE.md)
Ensure TypeScript inference and type coverage are validated through type coverage tests
Files:
tests/e2e/orm/schemas/typing/typecheck.ts
🧠 Learnings (12)
📓 Common learnings
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Implement plugin hooks at ORM, Kysely, and entity mutation levels for query interception and customization
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Use Kysely as the query builder interface for low-level database queries, avoiding raw SQL when possible
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to **/*.zmodel : ZModel schema files should define database structure and policies that compile to TypeScript via `zenstack generate`
Applied to files:
packages/cli/src/actions/generate.tstests/regression/test/issue-503/models.tstests/regression/test/issue-503/schema.zmodeltests/regression/test/issue-503/schema.tstests/regression/test/issue-503/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Use Kysely as the query builder interface for low-level database queries, avoiding raw SQL when possible
Applied to files:
packages/cli/src/actions/generate.tstests/regression/test/issue-503/models.tspackages/orm/src/client/crud-types.tstests/regression/test/issue-503/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Database migrations should use Prisma CLI under the hood via ZenStack commands
Applied to files:
packages/cli/src/actions/generate.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.test.{ts,tsx} : ORM package tests should include comprehensive client API tests and policy tests
Applied to files:
packages/cli/src/actions/generate.tstests/regression/test/issue-503/regression.test.tstests/e2e/orm/schemas/typing/typecheck.tspackages/orm/src/client/crud-types.tstests/regression/test/issue-503/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/orm/**/*.{ts,tsx} : Implement plugin hooks at ORM, Kysely, and entity mutation levels for query interception and customization
Applied to files:
packages/cli/src/actions/generate.tstests/regression/test/issue-503/models.tspackages/orm/src/client/crud-types.tstests/regression/test/issue-503/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to tests/e2e/**/*.{ts,tsx} : E2E tests should validate real-world schema compatibility with established projects
Applied to files:
tests/regression/test/issue-503/models.tstests/regression/test/issue-503/regression.test.tstests/regression/package.jsontests/e2e/orm/schemas/typing/typecheck.tstests/regression/test/issue-503/schema.tstests/regression/test/issue-503/input.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to packages/zenstackhq/cli/**/*.test.{ts,tsx} : CLI package tests should focus on action-specific tests for each command
Applied to files:
tests/regression/package.json
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Use Turbo for build orchestration and run `pnpm build`, `pnpm watch`, `pnpm lint`, and `pnpm test` for development tasks
Applied to files:
tests/regression/package.json
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Applies to tests/**/type*.{ts,tsx} : Ensure TypeScript inference and type coverage are validated through type coverage tests
Applied to files:
tests/regression/package.jsontests/e2e/orm/schemas/typing/typecheck.ts
📚 Learning: 2025-11-26T01:55:04.540Z
Learnt from: CR
Repo: zenstackhq/zenstack-v3 PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-26T01:55:04.540Z
Learning: Use `pnpm` with workspaces for package management, pinned to version `pnpm10.12.1`
Applied to files:
tests/regression/package.json
📚 Learning: 2025-10-21T16:09:31.218Z
Learnt from: ymc9
Repo: zenstackhq/zenstack-v3 PR: 319
File: packages/runtime/src/client/executor/zenstack-query-executor.ts:63-72
Timestamp: 2025-10-21T16:09:31.218Z
Learning: In ZenStack, TypeDefs can be inherited by models. When a TypeDef contains fields with `map` attributes, those mapped field names need to be processed by the QueryNameMapper since they become part of the inheriting model's schema. Therefore, when checking if a schema has mapped names (e.g., in `schemaHasMappedNames`), both `schema.models` and `schema.typeDefs` must be inspected for `@map` and `map` attributes.
Applied to files:
tests/regression/test/issue-503/schema.ts
🧬 Code graph analysis (2)
packages/orm/src/client/crud-types.ts (1)
packages/schema/src/schema.ts (5)
NonRelationFields(215-219)RelationFields(221-225)RelationFieldType(233-240)ModelFieldIsOptional(242-246)FieldIsArray(266-270)
tests/regression/test/issue-503/schema.ts (2)
packages/schema/src/schema.ts (1)
SchemaDef(11-19)packages/schema/src/expression-utils.ts (1)
ExpressionUtils(19-123)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: Agent
- GitHub Check: CodeQL analysis (javascript-typescript)
- GitHub Check: claude-review
- GitHub Check: build-test (20.x, postgresql)
- GitHub Check: build-test (20.x, sqlite)
🔇 Additional comments (9)
tests/regression/package.json (1)
7-9: Script path is valid and test workflow is sound.The refactoring from "generate" to "test:generate" improves clarity. The test flow (generate TypeScript schemas from zmodel files → compile check → run vitest) properly validates the typing fix with type coverage validation through the
tsccompilation step.tests/e2e/orm/schemas/typing/typecheck.ts (1)
165-181: LGTM!The addition of
take: 1to the nested posts selection is a valid query constraint. This test exercises deeply nested relation selection (posts.author.id) which aligns with the PR's goal of verifying nested relation typing.packages/cli/src/actions/generate.ts (1)
39-39: LGTM!Using
path.relative('.', outputPath)produces a cleaner relative import path in the example snippet, improving developer experience when copying the generated code.tests/regression/test/issue-503/schema.zmodel (1)
1-23: LGTM!The schema correctly reproduces the issue #503 scenario with the three-model relationship chain (
InternalChat→Message→Media). The relation definitions properly specify foreign key fields and references.packages/orm/src/client/crud-types.ts (2)
190-218: Solid fix for deeply nested relation typing.The refactored
ModelResulttype correctly handles nested includes by passingI[Key]directly to the recursive call. The key insight is that when processing an include like{ messages: { include: { media: true } } }, the inner object{ include: { media: true } }is now passed recursively asArgs, allowing the type system to properly resolve the nestedmediarelation.The
& Record<string, unknown>constraint appropriately accommodates additional query options (take,where, etc.) that may accompanyselect/include/omit.
160-170: Consistent recursion pattern for relation fields in select.The change to pass
Select[Key]directly toModelResult(instead of extracting specific properties) ensures consistent handling of nested relation selections. This allows queries like{ select: { posts: { select: { author: { include: { profile: true } } } } } }to properly resolve all nested relations.tests/regression/test/issue-503/schema.ts (1)
1-109: LGTM!This is a correctly generated schema file that accurately reflects the ZModel definitions. The relation structures (including the optional
mediarelation with its foreign key) are properly defined to support the regression test scenario.tests/regression/test/issue-503/models.ts (1)
1-12: LGTM! Auto-generated type aliases are correct.The generated type exports correctly alias the three models using
ModelResult, which should properly reflect nested included relations if the underlying ORM type fix is working as intended.tests/regression/test/issue-503/input.ts (1)
1-70: LGTM! Generated CRUD types follow consistent patterns.The comprehensive CRUD type exports for all three models are correctly structured. The
GetPayloadtypes (lines 30, 50, 70) useSimplifiedPlainResult, which is the key type for validating that deeply nested included relations are properly reflected in query result typings.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a TypeScript typing issue (#503) where deeply nested relations with select, include, and additional query parameters (like take) caused type inference to fail. The core problem was overly complex conditional type checking that prevented TypeScript from properly narrowing types in nested scenarios.
Key Changes:
- Simplified type inference logic in
ModelResultandModelSelectResultby removing intermediateFindArgstype checks - Added
& Record<string, unknown>constraints to improve TypeScript's type narrowing in union conditionals - Enhanced test coverage with regression test demonstrating the fix
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
packages/orm/src/client/crud-types.ts |
Simplified type recursion logic by removing FindArgs checks and always delegating to ModelResult for relation fields |
tests/regression/test/issue-503/schema.zmodel |
Added test schema with 3-level relation chain (InternalChat → Message → Media) |
tests/regression/test/issue-503/schema.ts |
Generated schema file from zmodel |
tests/regression/test/issue-503/regression.test.ts |
Regression test verifying nested select with include and take parameter works correctly |
tests/regression/test/issue-503/models.ts |
Generated model types |
tests/regression/test/issue-503/input.ts |
Generated input types |
tests/e2e/orm/schemas/typing/typecheck.ts |
Added take parameter to existing typing test to ensure type safety |
tests/regression/package.json |
Renamed generate script to test:generate for consistency |
packages/cli/src/actions/generate.ts |
Improved import path in CLI output to use relative paths |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
fixes #503
Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.