Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Nov 14, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Improved schema file resolution when package.json points to a directory; the CLI now correctly locates the schema file.
  • Chores

    • Updated CLI to invoke the Prisma tool via a dedicated execution path and adjusted migration/push command invocation format.
  • Tests

    • Added tests for schema-directory configurations.
    • Re-enabled the CLI migrate commands test suite.

Copilot AI review requested due to automatic review settings November 14, 2025 23:35
@coderabbitai
Copy link

coderabbitai bot commented Nov 14, 2025

Walkthrough

The PR adds an execPrisma() utility for invoking the Prisma CLI under ESM/CJS, updates schema path resolution to handle directory-configured schemas, replaces execPackage with execPrisma in DB/migrate flows, and converts several migration helpers from async to synchronous functions.

Changes

Cohort / File(s) Change Summary
Schema Path Resolution
packages/cli/src/actions/action-utils.ts
getSchemaFile() now treats a configured schema path that is a directory by checking for schema.zmodel inside that directory and returning that file path if present; throws CliError if not found.
Prisma Execution Utility
packages/cli/src/utils/exec-utils.ts
Added execPrisma(args, options?) which resolves prisma/build/index.js via import.meta.resolve() for ESM or require.resolve() for CommonJS, then executes it with node using existing exec helpers.
Database Command Changes
packages/cli/src/actions/db.ts
Replaced use of execPackage with execPrisma; changed command strings to use db push (removed prisma prefix); retained error handling and temp-schema cleanup.
Migration Command Changes
packages/cli/src/actions/migrate.ts
Replaced execPackage with execPrisma; removed prisma prefix from migrate commands; converted migration helpers (runDev, runReset, runDeploy, runStatus, runResolve) from async to synchronous and call execPrisma directly.
Tests
packages/cli/test/generate.test.ts, packages/cli/test/migrate.test.ts
Added two tests validating package.json schema directory handling for generate; re-enabled previously skipped migrate test suite.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Pay attention to the ESM vs CJS resolution in execPrisma() (correct paths, fallback behavior, and error messages).
  • Verify callers of now-synchronous migration helpers no longer rely on Promise behavior or awaiting.
  • Confirm subprocess invocation semantics (no-await) don't cause premature cleanup or missed errors in DB/migrate flows.
  • Check added tests' setup/teardown for filesystem changes and portability across environments.

Possibly related PRs

Poem

🐰 I hopped through code and found a clue,
Prisma paths now choose old or new,
ESM, CJS, both in tune,
Schemas spring from folder and dune,
Sync commands hum — a tidy tune.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 30.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 PR title accurately summarizes the main changes: adding a new execPrisma function to improve Prisma command execution compatibility across ESM/CommonJS, and refactoring multiple files to use this new utility instead of execPackage.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/execute-prisma

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 912b628 and 89f0d94.

📒 Files selected for processing (1)
  • packages/cli/src/actions/migrate.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/cli/src/actions/migrate.ts
⏰ 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). (2)
  • GitHub Check: build-test (20.x, postgresql)
  • GitHub Check: build-test (20.x, sqlite)

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.

@claude
Copy link

claude bot commented Nov 14, 2025

Claude Code is working…

I'll analyze this and get back to you.

View job run

Copilot finished reviewing on behalf of ymc9 November 14, 2025 23:38
Copy link
Contributor

Copilot AI left a 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 improves compatibility for executing Prisma commands by introducing a new execPrisma utility function that directly resolves and executes the Prisma CLI binary path instead of using npx/bunx. The changes also enhance schema directory handling and re-enable previously skipped tests.

Key changes:

  • Added execPrisma function to handle Prisma command execution with ESM/CJS compatibility
  • Refactored migrate and db commands to use execPrisma instead of execPackage
  • Enhanced getSchemaFile to support directory-based schema configuration

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
packages/cli/src/utils/exec-utils.ts Added new execPrisma function with ESM/CJS module resolution for direct Prisma CLI execution
packages/cli/src/actions/migrate.ts Updated to use execPrisma and changed async functions to synchronous
packages/cli/src/actions/db.ts Updated to use execPrisma instead of execPackage
packages/cli/src/actions/action-utils.ts Enhanced getSchemaFile to handle directory paths by appending 'schema.zmodel'
packages/cli/test/migrate.test.ts Re-enabled test suite by removing .skip
packages/cli/test/generate.test.ts Added test case for package.json schema directory configuration
Comments suppressed due to low confidence (2)

packages/cli/src/actions/migrate.ts:58

  • The functions runDev, runReset, runDeploy, runStatus, and runResolve are no longer async functions (they don't return promises), but they are still being awaited. Remove the await keywords from these function calls since the functions now execute synchronously.
            case 'dev':
                await runDev(prismaSchemaFile, options as DevOptions);
                break;

            case 'reset':
                await runReset(prismaSchemaFile, options as ResetOptions);
                break;

            case 'deploy':
                await runDeploy(prismaSchemaFile, options as DeployOptions);
                break;

            case 'status':
                await runStatus(prismaSchemaFile, options as StatusOptions);
                break;

            case 'resolve':
                await runResolve(prismaSchemaFile, options as ResolveOptions);
                break;

packages/cli/src/actions/migrate.ts:137

  • The handleSubProcessError function is duplicated in this file. The same function is already exported from action-utils.ts (which is imported by db.ts). Consider importing and reusing the shared implementation from action-utils.ts to avoid code duplication.
function handleSubProcessError(err: unknown) {
    if (err instanceof Error && 'status' in err && typeof err.status === 'number') {
        process.exit(err.status);
    } else {
        process.exit(1);
    }
}

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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: 2

🧹 Nitpick comments (1)
packages/cli/src/actions/migrate.ts (1)

67-80: Remove redundant await keywords or keep functions async for consistency.

The helper functions (runDev, runReset, runDeploy, runStatus, runResolve) are now synchronous, but the main run function (lines 41, 45, 49, 53, 57) still awaits them. While not incorrect, awaiting synchronous functions is unnecessary.

Consider either:

  1. Removing await keywords when calling these functions
  2. Keeping the functions as async for consistency, even if they don't await internally

Apply this diff to remove redundant awaits:

 export async function run(command: string, options: CommonOptions) {
     const schemaFile = getSchemaFile(options.schema);
     const prismaSchemaDir = options.migrations ? path.dirname(options.migrations) : undefined;
     const prismaSchemaFile = await generateTempPrismaSchema(schemaFile, prismaSchemaDir);
 
     try {
         switch (command) {
             case 'dev':
-                await runDev(prismaSchemaFile, options as DevOptions);
+                runDev(prismaSchemaFile, options as DevOptions);
                 break;
 
             case 'reset':
-                await runReset(prismaSchemaFile, options as ResetOptions);
+                runReset(prismaSchemaFile, options as ResetOptions);
                 break;
 
             case 'deploy':
-                await runDeploy(prismaSchemaFile, options as DeployOptions);
+                runDeploy(prismaSchemaFile, options as DeployOptions);
                 break;
 
             case 'status':
-                await runStatus(prismaSchemaFile, options as StatusOptions);
+                runStatus(prismaSchemaFile, options as StatusOptions);
                 break;
 
             case 'resolve':
-                await runResolve(prismaSchemaFile, options as ResolveOptions);
+                runResolve(prismaSchemaFile, options as ResolveOptions);
                 break;
         }
     } finally {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 94679db and 912b628.

📒 Files selected for processing (6)
  • packages/cli/src/actions/action-utils.ts (1 hunks)
  • packages/cli/src/actions/db.ts (2 hunks)
  • packages/cli/src/actions/migrate.ts (2 hunks)
  • packages/cli/src/utils/exec-utils.ts (2 hunks)
  • packages/cli/test/generate.test.ts (1 hunks)
  • packages/cli/test/migrate.test.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
packages/cli/src/actions/action-utils.ts (1)
packages/cli/src/cli-error.ts (1)
  • CliError (4-4)
packages/cli/src/actions/db.ts (1)
packages/cli/src/utils/exec-utils.ts (1)
  • execPrisma (32-42)
packages/cli/test/generate.test.ts (1)
packages/cli/test/utils.ts (2)
  • createProject (12-18)
  • runCli (20-23)
packages/cli/src/actions/migrate.ts (3)
packages/cli/src/utils/exec-utils.ts (1)
  • execPrisma (32-42)
packages/cli/src/actions/action-utils.ts (1)
  • handleSubProcessError (58-64)
packages/cli/src/cli-error.ts (1)
  • CliError (4-4)
⏰ 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: build-test (20.x, sqlite)
  • GitHub Check: build-test (20.x, postgresql)
  • GitHub Check: claude-review
🔇 Additional comments (5)
packages/cli/src/actions/action-utils.ts (1)

22-30: LGTM! Directory-based schema configuration is well-implemented.

The logic correctly handles the case where pkgJsonConfig.schema points to a directory by looking for schema.zmodel inside it, with proper existence checks and clear error messages.

packages/cli/test/migrate.test.ts (1)

12-12: Good to see tests re-enabled!

Re-enabling the migrate commands test suite ensures the new execPrisma-based implementation is properly validated.

packages/cli/src/actions/db.ts (1)

2-2: LGTM! Transition to execPrisma is correct.

The changes properly replace execPackage with the new synchronous execPrisma utility. The command format is updated to remove the prisma prefix, and the function correctly maintains async for generateTempPrismaSchema.

Also applies to: 30-30, 38-38

packages/cli/test/generate.test.ts (1)

48-61: Excellent test coverage for directory-based schema configuration!

This test validates the new behavior where zenstack.schema can point to a directory containing schema.zmodel, ensuring the feature works as intended.

packages/cli/src/actions/migrate.ts (1)

67-129: LGTM! Migration to execPrisma is well-executed.

The conversion from async to synchronous functions aligns with the synchronous nature of execPrisma, and the command format updates (removing prisma prefix) are correct. Error handling via handleSubProcessError is preserved.

Note: The command injection concern for user-provided options (e.g., options.name, options.applied, options.rolledBack) is addressed in the exec-utils.ts review.

@claude
Copy link

claude bot commented Nov 14, 2025

Claude finished @ymc9's task —— View job


I'll review this PR for code quality, security, performance, and test coverage.

Review Checklist

  • Read and analyze all changed files
  • Review new execPrisma utility function
  • Check schema directory handling improvements
  • Analyze async/sync function changes
  • Evaluate security concerns
  • Assess test coverage
  • Provide comprehensive feedback

Code Review Feedback

🔴 Critical Security Issues

1. Command Injection Vulnerability in migrate.ts

Lines 73, 122-123: User-provided CLI arguments are interpolated directly into shell commands without proper escaping:

// migrate.ts:73
options.name ? ` --name "${options.name}"` : '',

// migrate.ts:122-123
options.applied ? ` --applied "${options.applied}"` : '',
options.rolledBack ? ` --rolled-back "${options.rolledBack}"` : '',

Impact: Users can inject shell metacharacters (;, |, &&, $(), backticks, etc.) to execute arbitrary commands.

Fix: These values should be properly escaped or validated before interpolation.

2. Module Resolution Issue in exec-utils.ts

Line 39: The fallback require.resolve() will fail in this ESM module because require is not available in ES modules:

// This will throw "ReferenceError: require is not defined"
prismaPath = require.resolve('prisma/build/index.js');

Fix: Use createRequire(import.meta.url) from Node's module package, or remove the fallback if import.meta.resolve is guaranteed to be available.

⚠️ Code Quality Issues

3. Inconsistent Async/Await Usage

Lines 41, 45, 49, 53, 57: The migrate helper functions were converted from async to sync, but the main run() function still awaits them:

case 'dev':
    await runDev(prismaSchemaFile, options as DevOptions); // runDev is now sync
    break;

Fix: Either remove await keywords or keep the functions async for consistency.

4. Code Duplication

Line 131: The handleSubProcessError() function is duplicated in migrate.ts when it's already available from action-utils.ts (imported by db.ts).

Fix: Import and reuse the shared implementation to reduce duplication.

✅ Positive Changes

Schema Directory Handling

The enhancement to getSchemaFile() in action-utils.ts:22-30 properly handles directory-based schema configuration with good error handling and validation.

Test Coverage Improvements

  • Added comprehensive test for directory-based schema config in generate.test.ts:48-61
  • Re-enabled previously skipped migration tests in migrate.test.ts:12

Architecture Improvements

  • The new execPrisma() utility provides better control over Prisma CLI execution
  • Removal of npx/bunx dependency for more direct execution

🔍 Performance Considerations

  • Positive: Direct execution via node + resolved path should be faster than npx/bunx
  • Neutral: No significant performance regressions identified
  • Consideration: Module resolution happens on every call - could be cached for better performance

📊 Test Coverage Assessment

Good:

  • New schema directory functionality is well-tested
  • Migration tests are re-enabled with comprehensive coverage
  • Tests cover error scenarios (invalid migration resolution)

Areas for improvement:

  • No tests for the new execPrisma() function security aspects
  • Missing tests for ESM/CJS module resolution fallback scenarios

🎯 Recommendations

  1. URGENT: Fix the command injection vulnerabilities by properly escaping user inputs
  2. URGENT: Fix the ESM module resolution fallback
  3. High: Remove redundant await keywords or keep functions async
  4. Medium: Eliminate code duplication for error handling
  5. Low: Consider caching module resolution for performance

📝 Summary

This PR makes valuable improvements to Prisma command execution and schema handling, but contains critical security vulnerabilities that must be addressed before merging. The command injection issues pose a significant security risk, and the ESM module resolution bug will cause runtime failures in certain scenarios.

The positive aspects include better schema directory support, improved test coverage, and a cleaner architecture for Prisma CLI execution.

@ymc9 ymc9 merged commit e4885b0 into dev Nov 14, 2025
5 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