Skip to content

merge dev to main (v2.15.0) #2126

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

Merged
merged 9 commits into from
May 20, 2025
Merged

merge dev to main (v2.15.0) #2126

merged 9 commits into from
May 20, 2025

Conversation

ymc9
Copy link
Member

@ymc9 ymc9 commented May 20, 2025

No description provided.

Copy link
Contributor

coderabbitai bot commented May 20, 2025

Warning

Rate limit exceeded

@ymc9 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 25 minutes and 34 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 3ce431f and 47be505.

📒 Files selected for processing (4)
  • packages/runtime/src/enhancements/node/delegate.ts (6 hunks)
  • packages/server/tests/adapter/elysia.test.ts (1 hunks)
  • packages/server/tests/adapter/hono.test.ts (1 hunks)
  • packages/server/tests/adapter/sveltekit.test.ts (1 hunks)
📝 Walkthrough

Walkthrough

This set of changes introduces a new Elysia adapter for server integration, adds extensive tests for the adapter, and enhances model metadata and delegate logic to support relation actions (onDeleteAction, onUpdateAction) and cascading deletes. Updates are also made to handle inherited @updatedAt fields, ensure correct serialization of bigint values, and update dependencies and test schemas. Several regression and integration tests are added or improved.

Changes

File(s) Change Summary
packages/ide/jetbrains/build.gradle.kts, script/test-scaffold.ts, tests/integration/tests/cli/plugins.test.ts Updated dependency versions for JetBrains plugin and Prisma packages from 6.7.x to 6.8.x.
packages/runtime/src/cross/model-meta.ts, packages/sdk/src/model-meta-generator.ts Added support for onDeleteAction and onUpdateAction relation metadata; updated types and metadata generation to include these properties.
packages/runtime/src/enhancements/node/delegate.ts Enhanced update and delete logic to handle inherited @updatedAt fields and cascading deletes for delegate models; added helper methods for relation and timestamp handling.
packages/runtime/src/enhancements/node/policy/policy-utils.ts Refactored the internal method for injecting field-level read check selections, simplifying logic for handling scalar and relation fields.
packages/runtime/src/enhancements/node/utils.ts Modified object formatting to always serialize bigint values as strings.
packages/server/src/elysia/handler.ts, packages/server/src/elysia/index.ts Added a new Elysia adapter module for automatic CRUD API routing and re-exported its handler.
packages/server/tests/adapter/elysia.test.ts Added comprehensive integration tests for the Elysia adapter, covering both RPC and REST handlers.
tests/integration/tests/enhancements/with-delegate/enhanced-client.test.ts, tests/integration/tests/enhancements/with-delegate/plugin-interaction.test.ts, tests/integration/tests/enhancements/with-delegate/utils.ts Improved delegate model tests: added checks for updatedAt updates, a new cascade delete test, and included updatedAt in schemas and test data.
tests/regression/tests/issue-2106.test.ts, tests/regression/tests/issue-2117.test.ts Added new regression tests for BigInt field handling and field-level access control with computed fields.

Sequence Diagram(s)

Elysia Adapter Request Handling

sequenceDiagram
    participant Client
    participant ElysiaApp
    participant ElysiaHandler
    participant PrismaClient
    participant RPCApiHandler

    Client->>ElysiaApp: HTTP Request
    ElysiaApp->>ElysiaHandler: Route Handler Invocation
    ElysiaHandler->>PrismaClient: getPrisma(context)
    ElysiaHandler->>RPCApiHandler: Handle(method, path, query, body, prisma, meta, schemas, logger)
    RPCApiHandler-->>ElysiaHandler: { status, body }
    ElysiaHandler-->>ElysiaApp: Response
    ElysiaApp-->>Client: HTTP Response
Loading

Delegate Cascade Delete Flow

sequenceDiagram
    participant Client
    participant DelegateProxyHandler
    participant CrudContract

    Client->>DelegateProxyHandler: delete(model, args)
    DelegateProxyHandler->>CrudContract: Query related entities for cascade delete
    loop For each related entity with Cascade
        DelegateProxyHandler->>DelegateProxyHandler: doDelete(related model, related args)
    end
    DelegateProxyHandler->>CrudContract: Delete main entity
    DelegateProxyHandler-->>Client: Deleted entity hierarchy
Loading

Metadata Generation with Relation Actions

sequenceDiagram
    participant ModelMetaGenerator
    participant DataModelField

    ModelMetaGenerator->>DataModelField: Inspect @relation attributes
    ModelMetaGenerator->>ModelMetaGenerator: getOnDeleteAction(field)
    ModelMetaGenerator->>ModelMetaGenerator: getOnUpdateAction(field)
    ModelMetaGenerator-->>ModelMetaGenerator: Write onDeleteAction/onUpdateAction to metadata
Loading
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
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

🧹 Nitpick comments (10)
tests/regression/tests/issue-2117.test.ts (1)

21-24: Computed field doesn’t actually use the declared dependency

needs: { username: true } declares that pageUrl depends on username, yet the compute callback always returns the constant string "foo" and ignores the username argument. At best this is confusing, at worst future maintainers might rely on username being fetched unnecessarily.

If the URL is always the same, drop the needs declaration; otherwise build the URL from username.

-                            needs: { username: true },
-                            compute: () => `foo`,
+                            // needs omitted – constant string, no real dependency
+                            compute: () => 'foo',

(or compute on username if that was the intent).

tests/integration/tests/enhancements/with-delegate/enhanced-client.test.ts (4)

479-490: Flaky assertion on updatedAt – allow equality

updatedAt is stored with millisecond (or even-microsecond) precision depending on the backing database.
Two consecutive writes executed in the same tick can produce identical timestamps, which will make the strict
> assertion intermittently fail on fast machines or CI.

-expect(updated.updatedAt.getTime()).toBeGreaterThan(read.updatedAt.getTime());
+expect(updated.updatedAt.getTime()).toBeGreaterThanOrEqual(read.updatedAt.getTime());

The same reasoning applies to any other updatedAt comparison below.


618-631: Same potential flakiness for updatedAt comparison

Replicate the >= change here to avoid nondeterministic failures.


1031-1049: Same potential flakiness for updatedAt in the upsert flow

Apply the >= change here as well.


1109-1156: delete cascade test: add explicit count assertions for stronger signal

The current checks rely on findUnique returning null. Adding explicit row-count assertions makes the intent clearer and gives more precise diagnostics should the cascade break.

 await expect(db.item.findUnique({ where: { id: 2 } })).toResolveNull();
+await expect(db.item.count()).resolves.toBe(0);
 ...
 await expect(db.itemContent.findUnique({ where: { id: 3 } })).toResolveNull();
+await expect(db.itemContent.count()).resolves.toBe(0);

(optional but useful)

packages/server/src/elysia/handler.ts (3)

40-43: Repeated query-string keys are silently discarded

Object.fromEntries(url.searchParams) turns a multi-map (URLSearchParams) into a plain object, meaning only the last value of duplicate keys is kept.
If the API needs to support filters like ?id=1&id=2, this implementation will drop values.

-const query = Object.fromEntries(url.searchParams);
+const query: Record<string, string | string[]> = {};
+url.searchParams.forEach((v, k) => {
+    if (k in query) {
+        query[k] = Array.isArray(query[k]) ? [...(query[k] as string[]), v] : [query[k] as string, v];
+    } else {
+        query[k] = v;
+    }
+});

58-76: Swallowed error hinders troubleshooting

The catch-all replaces the original error with a generic message. Down-stream callers (including tests) cannot see stack traces, and production logs get no clues.

Consider at least logging the error or re-throwing it in non-production environments:

} catch (err) {
-    set.status = 500;
-    return { message: 'An internal server error occurred' };
+    options.logger?.error?.('elysia-handler', err);
+    set.status = 500;
+    return { message: 'An internal server error occurred' };
}

30-38: 500 may not be the best signal for missing Prisma client

If getPrisma returns undefined, it looks like a configuration issue rather than a server crash. Returning 503 (Service Unavailable) or 500 with a more specific hint would better reflect reality and improve observability.

packages/runtime/src/enhancements/node/delegate.ts (2)

1206-1237: Potential N+1 queries during cascade delete

For every relation field flagged Cascade, you run an extra findMany even if no matching rows exist.
On large deletes this can explode to N×M round-trips.

Consider batching the queries or pre-selecting all relations with a single include instead of per-field queries.


820-832: Duplicate logic for simpleUpdateMany flag

The same check (base fields + @updatedAt inheritance) exists in two places (updateMany and visitor’s updateMany). Extracting it into a private helper will prevent future divergence.

private isSimpleUpdateMany(model: string, data: any, where?: any): boolean { /* … */ }

Also applies to: 958-963

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting

📥 Commits

Reviewing files that changed from the base of the PR and between b79a749 and 3ce431f.

⛔ Files ignored due to path filters (23)
  • package.json is excluded by !**/*.json
  • packages/ide/jetbrains/package.json is excluded by !**/*.json
  • packages/language/package.json is excluded by !**/*.json
  • packages/misc/redwood/package.json is excluded by !**/*.json
  • packages/plugins/openapi/package.json is excluded by !**/*.json
  • packages/plugins/swr/package.json is excluded by !**/*.json
  • packages/plugins/tanstack-query/package.json is excluded by !**/*.json
  • packages/plugins/trpc/package.json is excluded by !**/*.json
  • packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • packages/plugins/trpc/tests/projects/nuxt-trpc-v10/package.json is excluded by !**/*.json
  • packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • packages/plugins/trpc/tests/projects/nuxt-trpc-v11/package.json is excluded by !**/*.json
  • packages/plugins/trpc/tests/projects/t3-trpc-v11/package-lock.json is excluded by !**/package-lock.json, !**/*.json
  • packages/plugins/trpc/tests/projects/t3-trpc-v11/package.json is excluded by !**/*.json
  • packages/runtime/package.json is excluded by !**/*.json
  • packages/schema/package.json is excluded by !**/*.json
  • packages/sdk/package.json is excluded by !**/*.json
  • packages/server/package.json is excluded by !**/*.json
  • packages/testtools/package.json is excluded by !**/*.json
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml, !**/*.yaml
  • tests/integration/test-run/package.json is excluded by !**/*.json
  • tests/integration/tests/frameworks/nextjs/test-project/package.json is excluded by !**/*.json
  • tests/integration/tests/frameworks/trpc/test-project/package.json is excluded by !**/*.json
📒 Files selected for processing (16)
  • packages/ide/jetbrains/build.gradle.kts (1 hunks)
  • packages/runtime/src/cross/model-meta.ts (2 hunks)
  • packages/runtime/src/enhancements/node/delegate.ts (6 hunks)
  • packages/runtime/src/enhancements/node/policy/policy-utils.ts (1 hunks)
  • packages/runtime/src/enhancements/node/utils.ts (1 hunks)
  • packages/sdk/src/model-meta-generator.ts (2 hunks)
  • packages/server/src/elysia/handler.ts (1 hunks)
  • packages/server/src/elysia/index.ts (1 hunks)
  • packages/server/tests/adapter/elysia.test.ts (1 hunks)
  • script/test-scaffold.ts (1 hunks)
  • tests/integration/tests/cli/plugins.test.ts (2 hunks)
  • tests/integration/tests/enhancements/with-delegate/enhanced-client.test.ts (6 hunks)
  • tests/integration/tests/enhancements/with-delegate/plugin-interaction.test.ts (4 hunks)
  • tests/integration/tests/enhancements/with-delegate/utils.ts (1 hunks)
  • tests/regression/tests/issue-2106.test.ts (1 hunks)
  • tests/regression/tests/issue-2117.test.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (7)
script/test-scaffold.ts (1)
packages/testtools/src/schema.ts (1)
  • run (45-57)
packages/sdk/src/model-meta-generator.ts (1)
packages/sdk/src/utils.ts (3)
  • getAttribute (141-157)
  • getAttributeArg (172-182)
  • isEnumFieldReference (196-198)
tests/regression/tests/issue-2117.test.ts (1)
packages/testtools/src/schema.ts (1)
  • loadSchema (163-369)
tests/regression/tests/issue-2106.test.ts (1)
packages/testtools/src/schema.ts (1)
  • loadSchema (163-369)
packages/server/src/elysia/handler.ts (3)
packages/server/src/types.ts (1)
  • AdapterBaseOptions (32-56)
packages/server/src/shared.ts (1)
  • loadAssets (5-21)
packages/runtime/src/types.ts (1)
  • DbClientContract (91-93)
packages/runtime/src/enhancements/node/policy/policy-utils.ts (1)
packages/runtime/src/cross/model-meta.ts (1)
  • resolveField (213-221)
packages/server/tests/adapter/elysia.test.ts (3)
packages/testtools/src/schema.ts (1)
  • loadSchema (163-369)
packages/server/tests/utils.ts (1)
  • schema (3-29)
packages/server/src/elysia/handler.ts (1)
  • createElysiaHandler (25-82)
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: build-test (20.x)
  • GitHub Check: build-test (20.x)
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: OSSAR-Scan
  • GitHub Check: dependency-review
  • GitHub Check: build-test (20.x)
🔇 Additional comments (17)
script/test-scaffold.ts (1)

22-22: Align Prisma and client package versions
The npm i invocation now installs prisma@6.8.x and @prisma/client@6.8.x instead of 6.7.x, keeping the scaffolded project in sync with the updated integration tests and ensuring consistent Prisma versions across your testing setup.

tests/integration/tests/cli/plugins.test.ts (2)

78-78: Update runtime Prisma client version in depPkgs
Bumped @prisma/client from 6.7.x to 6.8.x in the runtime dependencies array (depPkgs), matching the scaffold script change and avoiding version drift during test execution.


88-88: Update Prisma CLI version in devDepPkgs
Bumped prisma from 6.7.x to 6.8.x in the development dependencies array (devDepPkgs), maintaining alignment with the runtime package and the scaffold setup.

packages/ide/jetbrains/build.gradle.kts (1)

12-12: Version bump for release v2.15.0

This version update aligns with the PR objective to merge dev into main for release v2.15.0.

packages/server/src/elysia/index.ts (1)

1-1: Clean module export pattern

This barrel file provides a clean public API for the new Elysia adapter, making imports simpler for consumers.

tests/integration/tests/enhancements/with-delegate/utils.ts (1)

15-15: Added updatedAt field to Asset model

Adding the @updatedAt field to the base Asset model will ensure automatic timestamp updates on modifications, which is essential for testing the enhanced delegate update logic.

tests/integration/tests/enhancements/with-delegate/plugin-interaction.test.ts (4)

68-69: Updated test data with updatedAt field

Added updatedAt field to the test object to match the updated schema. This maintains consistency with the changes in the Asset model.


78-79: Updated test data with updatedAt field

Added updatedAt field to the test object to match the updated schema. This maintains consistency with the changes in the Asset model.


92-93: Updated test data with updatedAt field

Added updatedAt field to the test object to match the updated schema. This maintains consistency with the changes in the Asset model.


104-105: Updated test data with updatedAt field

Added updatedAt field to the test object to match the updated schema. This maintains consistency with the changes in the Asset model.

packages/runtime/src/enhancements/node/utils.ts (1)

10-10: Improved BigInt handling during serialization.

The change ensures consistent serialization of bigint values by always converting them to strings. This prevents "TypeError: Do not know how to serialize a BigInt" errors that can occur with standard JSON serialization.

packages/runtime/src/cross/model-meta.ts (2)

23-26: Good addition: RelationAction type for referential integrity.

The new RelationAction type clearly defines the possible referential actions for relations, which will be used to control behavior when related records are deleted or updated.


82-91: Solid extension of the FieldInfo type for relation actions.

These new properties allow for capturing the onDelete and onUpdate referential actions from the schema's relation fields. This is particularly important for implementing cascade delete functionality.

packages/sdk/src/model-meta-generator.ts (2)

314-325: Good implementation of relation action metadata generation.

The code correctly extracts and writes the onDeleteAction and onUpdateAction properties to the field metadata. This enables the runtime to properly handle relation behaviors like cascade deletes.


584-604: Well-structured helper functions for relation actions.

The getOnDeleteAction and getOnUpdateAction functions follow a consistent pattern for extracting relation action information from the model's attributes. They correctly handle the extraction of enum field references from the relation attribute.

tests/regression/tests/issue-2106.test.ts (1)

1-19: Good regression test for BigInt handling.

This test verifies that the system correctly handles BigInt fields during record creation, which validates the serialization improvements in formatObject. The test is concise and focuses on the specific issue it's designed to catch.

packages/runtime/src/enhancements/node/delegate.ts (1)

1163-1183: Unbounded recursive cascade delete – verify for cyclic relations

doDelete recursively calls itself for cascade relations without keeping a visited-set.
Mutually-referencing models with onDelete: Cascade could cause infinite recursion.

Please verify with a cyclic schema; if reproducible, guard with a Set<string> of (model,id) pairs.

@ymc9 ymc9 merged commit 53bf340 into main May 20, 2025
13 checks passed
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