Skip to content
This repository was archived by the owner on Mar 1, 2026. It is now read-only.

feat(cli): ZenStack proxy#597

Merged
jiashengguo merged 5 commits intodevfrom
proxy
Jan 18, 2026
Merged

feat(cli): ZenStack proxy#597
jiashengguo merged 5 commits intodevfrom
proxy

Conversation

@jiashengguo
Copy link
Copy Markdown
Member

@jiashengguo jiashengguo commented Jan 15, 2026

Summary by CodeRabbit

  • New Features

    • Added a new CLI command "proxy" (alias "studio") to start a proxy server (default port 8008) exposing RPC and schema endpoints; supports schema, output, database URL, and log level options with graceful shutdown.
  • Improvements

    • More robust generate/watch flow with improved error handling, watcher update logic, and unified output-path resolution.
  • Chores

    • Updated package dependencies and TypeScript type packages; removed some deprecated/dev-only devDependencies.

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings January 15, 2026 12:52
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 15, 2026

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

📝 Walkthrough

Walkthrough

Adds a new Express-based proxy CLI command and wiring, extracts getOutputPath into a shared utility, updates generate watch/debounce and watcher path handling, and updates packages/cli/package.json runtime dependencies and TypeScript type packages.

Changes

Cohort / File(s) Summary
Package manifest
packages/cli/package.json
Added runtime deps: @zenstackhq/orm, @zenstackhq/server, cors, express, pg; added type defs: @types/cors, @types/express, @types/pg; removed better-sqlite3 and moved @zenstackhq/orm out of devDependencies.
Shared utility
packages/cli/src/actions/action-utils.ts
New exported getOutputPath(options, schemaFile) resolving output from CLI opts → package.json config → schema file dir.
Generate action
packages/cli/src/actions/generate.ts
Now imports getOutputPath (local impl removed). Reworked debounced reGenerateSchema to handle errors inside the debounced callback; watcher logic updated to add/remove model paths using a local watchedPaths set and watcher APIs.
Proxy action & exports
packages/cli/src/actions/proxy.ts, packages/cli/src/actions/index.ts
New proxy action: resolves schema/output, evaluates datasource URL (env-aware), supports sqlite/postgres dialects, instantiates ZenStackClient, dynamically imports generated schema, serves /api/model and /api/schema via Express, graceful shutdown. proxy re-exported in actions index.
CLI wiring
packages/cli/src/index.ts
New proxy (alias studio) subcommand with options (--schema, -p/--port, -o/--output, -d/--databaseUrl, -l/--logLevel, --no-version-check); telemetry.trackCommand for proxy; main exit-flow updated to treat proxy as long-running.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

🐰 I hopped from schema to a listening port,
I bundled models, fetched the DB report,
Env carrots twitched, URLs came through,
Express served endpoints — RPCs and view,
Proxy up — I nibble logs and cheer! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.09% 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 'feat(cli): ZenStack proxy' directly and clearly describes the main change: introducing a new ZenStack proxy feature to the CLI.

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

✨ Finishing touches
  • 📝 Generate docstrings


📜 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 311af3f and 832b84e.

📒 Files selected for processing (1)
  • packages/cli/src/index.ts
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-12-30T15:07:06.254Z
Learnt from: mwillbanks
Repo: zenstackhq/zenstack-v3 PR: 550
File: packages/orm/src/client/crud/operations/base.ts:158-159
Timestamp: 2025-12-30T15:07:06.254Z
Learning: Do not use ts-expect-error in production code within the zenstackhq/zenstack-v3 repo (e.g., packages/*). Use explicit type annotations, targeted type assertions, or refactor to resolve the type error. ts-expect-error may be acceptable only in test files for stubbing or temporary silencing. Ensure production code is type-safe and maintainable.

Applied to files:

  • packages/cli/src/index.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 **/*.zmodel : ZModel schema files should define database structure and policies that compile to TypeScript via `zenstack generate`

Applied to files:

  • packages/cli/src/index.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:

  • packages/cli/src/index.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). (3)
  • GitHub Check: claude-review
  • GitHub Check: build-test (22.x, postgresql)
  • GitHub Check: build-test (22.x, sqlite)
🔇 Additional comments (3)
packages/cli/src/index.ts (3)

41-43: LGTM!

The proxyAction function follows the established pattern of other action handlers in this file, with proper telemetry tracking and type-safe options forwarding.


193-203: Proxy command structure looks good overall.

The command definition follows the established patterns in this file with appropriate option reuse (schemaOption, noVersionCheckOption) and the studio alias for discoverability. The options cover the essential configuration for a proxy server.


240-243: Logic correctly prevents termination for long-running proxy/studio commands.

The condition properly identifies the proxy server as a persistent process that shouldn't terminate immediately, consistent with how watch mode is handled. Using .some() for the command check is clean.

Note: The program.args.includes() approach could theoretically match if 'proxy' or 'studio' appeared as an option value rather than a command, but this matches the existing pattern for watch mode detection and is acceptable for this use case.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.


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

claude bot commented Jan 15, 2026

Claude finished @jiashengguo's task —— View job


PR Review: ZenStack Proxy Feature

Review Tasks

  • Analyze the new proxy implementation
  • Check code quality and best practices
  • Review security implications
  • Assess performance considerations
  • Evaluate test coverage
  • Provide comprehensive feedback

🔍 Code Review Summary

I've thoroughly reviewed the new proxy functionality which adds a development server for ZenStack. Here's my comprehensive analysis:

Positive Aspects

  1. Clean CLI Integration: The proxy command is properly integrated with the CLI structure and follows established patterns
  2. Good Error Handling: Proper error messages and graceful shutdown handling
  3. Database Support: Supports both SQLite and PostgreSQL with proper dialect configuration
  4. Flexible Configuration: Multiple ways to specify database URL (schema file, CLI option, environment variables)

⚠️ Security Concerns

Critical: Code Injection Vulnerability

Location: packages/cli/src/actions/proxy.ts:94

const urlFn = new Function('env', `return ${value}`);

Issue: Using Function constructor with user-controlled input creates a code injection vulnerability. The value comes from the schema file and could contain malicious JavaScript.

Impact: Arbitrary code execution when processing untrusted schema files.

Recommendation: Use a proper expression parser or whitelist allowed patterns instead of Function constructor.

Missing Authentication

Location: packages/cli/src/actions/proxy.ts:138-143

The middleware doesn't implement getSessionUser, defaulting to an open API without authentication. This is noted in the comment but should be more prominently documented as a security consideration.

🐛 Potential Bugs

  1. Path Resolution Issue (proxy.ts:112-113):

    if (!path.isAbsolute(filePath)) {
        resolvedUrl = path.join(outputPath, filePath);
    }

    Should use resolvedUrl = 'file:' + path.resolve(outputPath, filePath) to maintain the file: protocol.

  2. Missing Database Connection Validation: The code calls db.$connect() but doesn't properly handle connection failures or timeouts.

Performance Considerations

  1. Dynamic Schema Loading: Using jiti to dynamically import the schema is flexible but adds runtime overhead
  2. No Connection Pooling Configuration: PostgreSQL pool uses default settings which may not be optimal for all use cases
  3. Express Server: Uses basic Express setup without compression or other performance optimizations

📝 Code Quality Issues

  1. Magic Numbers: Port default (8008) and log level filtering could be constants
  2. Type Safety: Several any types used (schemaModule, schema parameter)
  3. Error Messages: Some error messages could be more descriptive

Missing Test Coverage

Critical Issue: No tests found for the new proxy functionality. The CLI package has extensive tests for other commands, but proxy functionality is completely untested.

Recommendations:

  • Add unit tests for URL evaluation logic
  • Add integration tests for server startup/shutdown
  • Add tests for different database configurations
  • Test error scenarios (invalid schema, connection failures)

🔧 Recommendations

High Priority (Security)

  1. Fix code injection vulnerability - Replace Function constructor with safe expression evaluation
  2. Add security documentation - Document authentication requirements clearly

Medium Priority (Reliability)

  1. Add comprehensive tests - Critical for a new CLI command
  2. Fix path resolution - Ensure file: URLs work correctly
  3. Improve error handling - Better database connection error handling

Low Priority (Quality)

  1. Type improvements - Remove any types where possible
  2. Performance optimizations - Consider adding connection pool configuration options
  3. Code organization - Extract constants and improve modularity

🎯 Overall Assessment

While the feature implementation is solid and follows good CLI patterns, the critical security vulnerability and complete lack of test coverage need immediate attention before merging. The proxy functionality would benefit from security hardening and comprehensive testing.

Recommendation: Address security issues and add tests before merging to main branch.


Copy link
Copy Markdown

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

🤖 Fix all issues with AI agents
In `@packages/cli/src/actions/proxy.ts`:
- Line 29: Fix the typo in the console log by removing the extra colon in the
template string used in the console.log call (console.log(colors.gray(`Loading
ZModel schema from:: ${schemaFile}`))); change "from::" to "from:" so it reads
`Loading ZModel schema from: ${schemaFile}`.
- Around line 156-171: The signal handlers for 'SIGTERM' and 'SIGINT' call
client.$disconnect() but don't await it before calling process.exit(0), so
convert the server.close callback to a promise (e.g., new Promise(resolve =>
server.close(resolve)) or use util.promisify) inside the process.on handlers,
await that promise and then await client.$disconnect() (wrap awaits in
try/catch), and only call process.exit(0) after both awaits complete to ensure
graceful cleanup; update both handlers where process.on('SIGTERM', async () => {
... }) and process.on('SIGINT', async () => { ... }) reference server.close and
client.$disconnect.
- Around line 58-60: The code passes an undefined provider into createDialect
because dataSource or its provider field may be missing; update the logic around
dataSource, the fields.find(...) result, and getStringLiteral to validate that a
provider string was actually found before calling createDialect, and if not,
throw or return a clear error (e.g., "Missing or invalid datasource provider")
that references the dataSource and provider, rather than allowing
createDialect(provider, ...) to receive undefined and produce an ambiguous
message.

In `@packages/cli/src/index.ts`:
- Around line 193-202: The port CLI option is parsed as a string by Commander
but your Options type and downstream functions (run(), startServer()) expect a
number; update the proxy command setup (the .addOption for '-p, --port <port>'
in the program.command('proxy') block) to parse the value into a number (e.g.,
use Option.argParser(Number) or a parseInt wrapper) and keep the default as a
numeric 8008, and ensure proxyAction signature/usage reads the parsed numeric
port to pass to run()/startServer().
🧹 Nitpick comments (3)
packages/cli/src/index.ts (1)

239-242: Consider a more robust check for the proxy command.

The check program.args.includes('proxy') could match if "proxy" appears as a value to another option (e.g., --output proxy). While unlikely, this mirrors the existing pattern for generate --watch. If this becomes problematic, consider tracking the executed command name explicitly.

packages/cli/src/actions/proxy.ts (2)

84-85: Variable shadowing reduces readability.

The inner value shadows the outer value parameter. Consider renaming for clarity.

Suggested fix
     const env = (varName: string) => {
-        const value = process.env[varName];
-        if (!value) {
+        const envValue = process.env[varName];
+        if (!envValue) {
             throw new CliError(`Environment variable ${varName} is not set`);
         }
-        return value;
+        return envValue;
     };

150-153: Consider adding a default port.

If options.port is undefined, Express will listen on a random port. Consider providing a sensible default for better developer experience.

Suggested fix
-    const server = app.listen(options.port, () => {
-        console.log(`ZenStack proxy server is running on port: ${options.port}`);
+    const port = options.port ?? 3000;
+    const server = app.listen(port, () => {
+        console.log(`ZenStack proxy server is running on port: ${port}`);
📜 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 154ba29 and 9be59d7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (6)
  • packages/cli/package.json
  • packages/cli/src/actions/action-utils.ts
  • packages/cli/src/actions/generate.ts
  • packages/cli/src/actions/index.ts
  • packages/cli/src/actions/proxy.ts
  • packages/cli/src/index.ts
🧰 Additional context used
🧠 Learnings (8)
📓 Common learnings
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
📚 Learning: 2025-12-30T15:07:06.254Z
Learnt from: mwillbanks
Repo: zenstackhq/zenstack-v3 PR: 550
File: packages/orm/src/client/crud/operations/base.ts:158-159
Timestamp: 2025-12-30T15:07:06.254Z
Learning: Do not use ts-expect-error in production code within the zenstackhq/zenstack-v3 repo (e.g., packages/*). Use explicit type annotations, targeted type assertions, or refactor to resolve the type error. ts-expect-error may be acceptable only in test files for stubbing or temporary silencing. Ensure production code is type-safe and maintainable.

Applied to files:

  • packages/cli/src/actions/action-utils.ts
  • packages/cli/src/actions/proxy.ts
  • packages/cli/src/index.ts
  • packages/cli/src/actions/index.ts
  • 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 **/*.zmodel : ZModel schema files should define database structure and policies that compile to TypeScript via `zenstack generate`

Applied to files:

  • packages/cli/src/actions/proxy.ts
  • packages/cli/package.json
  • 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/cli/**/*.test.{ts,tsx} : CLI package tests should focus on action-specific tests for each command

Applied to files:

  • packages/cli/src/index.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/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 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/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 packages/zenstackhq/orm/**/*.test.{ts,tsx} : ORM package tests should include comprehensive client API tests and policy tests

Applied to files:

  • packages/cli/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 `pnpm` with workspaces for package management, pinned to version `pnpm10.12.1`

Applied to files:

  • packages/cli/package.json
🧬 Code graph analysis (1)
packages/cli/src/actions/generate.ts (2)
packages/language/src/generated/ast.ts (4)
  • Model (561-565)
  • Model (567-567)
  • AbstractDeclaration (89-89)
  • AbstractDeclaration (91-91)
packages/common-helpers/src/single-debounce.ts (1)
  • singleDebounce (1-34)
⏰ 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). (4)
  • GitHub Check: CodeQL analysis (javascript-typescript)
  • GitHub Check: Agent
  • GitHub Check: claude-review
  • GitHub Check: build-test (22.x, sqlite)
🔇 Additional comments (6)
packages/cli/src/actions/action-utils.ts (1)

147-158: LGTM!

The getOutputPath utility is well-structured with a sensible fallback chain: CLI option → package.json config → schema file directory. Good extraction for reuse across actions.

packages/cli/src/actions/generate.ts (2)

15-15: LGTM!

Import correctly updated to use the extracted getOutputPath utility from action-utils.


68-105: LGTM!

The debounced regeneration logic is well-structured:

  • Error handling inside the async callback prevents unhandled promise rejections
  • Watcher path management (add/unwatch) correctly maintains the watchedPaths set
  • The singleDebounce with reRunOnInProgressCall: true ensures changes during generation aren't lost
packages/cli/src/actions/index.ts (1)

9-11: LGTM!

The proxy action is correctly imported and exported following the established pattern for other CLI actions.

packages/cli/src/index.ts (1)

41-43: LGTM!

The proxyAction wrapper correctly follows the established pattern for telemetry tracking, consistent with other CLI actions.

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

105-130: LGTM!

The dialect creation logic correctly handles SQLite file path resolution and PostgreSQL connection pooling, with appropriate error handling for unsupported providers.

✏️ Tip: You can disable this entire section by setting review_details to false in your review settings.

Comment thread packages/cli/src/actions/proxy.ts Outdated
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/index.ts
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jan 15, 2026

Claude finished @jiashengguo's task —— View job


PR Review: ZenStack Proxy Feature

Review Tasks

  • Analyze the new proxy implementation
  • Check code quality and best practices
  • Review security implications
  • Assess performance considerations
  • Evaluate test coverage
  • Provide comprehensive feedback

🔍 Code Review Summary

I've thoroughly reviewed the new proxy functionality which adds a development server for ZenStack. Here's my comprehensive analysis:

Positive Aspects

  1. Clean CLI Integration: The proxy command is properly integrated with the CLI structure and follows established patterns
  2. Good Error Handling: Proper error messages and graceful shutdown handling
  3. Database Support: Supports both SQLite and PostgreSQL with proper dialect configuration
  4. Flexible Configuration: Multiple ways to specify database URL (schema file, CLI option, environment variables)

⚠️ Security Concerns

Critical: Code Injection Vulnerability

Location: packages/cli/src/actions/proxy.ts:94

const urlFn = new Function('env', `return ${value}`);

Issue: Using Function constructor with user-controlled input creates a code injection vulnerability. The value comes from the schema file and could contain malicious JavaScript.

Impact: Arbitrary code execution when processing untrusted schema files.

Recommendation: Use a proper expression parser or whitelist allowed patterns instead of Function constructor.

Missing Authentication

Location: packages/cli/src/actions/proxy.ts:138-143

The middleware doesn't implement getSessionUser, defaulting to an open API without authentication. This is noted in the comment but should be more prominently documented as a security consideration.

🐛 Potential Bugs

  1. Path Resolution Issue (proxy.ts:112-113):

    if (!path.isAbsolute(filePath)) {
        resolvedUrl = path.join(outputPath, filePath);
    }

    Should use resolvedUrl = 'file:' + path.resolve(outputPath, filePath) to maintain the file: protocol.

  2. Missing Database Connection Validation: The code calls db.$connect() but doesn't properly handle connection failures or timeouts.

Performance Considerations

  1. Dynamic Schema Loading: Using jiti to dynamically import the schema is flexible but adds runtime overhead
  2. No Connection Pooling Configuration: PostgreSQL pool uses default settings which may not be optimal for all use cases
  3. Express Server: Uses basic Express setup without compression or other performance optimizations

📝 Code Quality Issues

  1. Magic Numbers: Port default (8008) and log level filtering could be constants
  2. Type Safety: Several any types used (schemaModule, schema parameter)
  3. Error Messages: Some error messages could be more descriptive

Missing Test Coverage

Critical Issue: No tests found for the new proxy functionality. The CLI package has extensive tests for other commands, but proxy functionality is completely untested.

Recommendations:

  • Add unit tests for URL evaluation logic
  • Add integration tests for server startup/shutdown
  • Add tests for different database configurations
  • Test error scenarios (invalid schema, connection failures)

🔧 Recommendations

High Priority (Security)

  1. Fix code injection vulnerability - Replace Function constructor with safe expression evaluation
  2. Add security documentation - Document authentication requirements clearly

Medium Priority (Reliability)

  1. Add comprehensive tests - Critical for a new CLI command
  2. Fix path resolution - Ensure file: URLs work correctly
  3. Improve error handling - Better database connection error handling

Low Priority (Quality)

  1. Type improvements - Remove any types where possible
  2. Performance optimizations - Consider adding connection pool configuration options
  3. Code organization - Extract constants and improve modularity

🎯 Overall Assessment

While the feature implementation is solid and follows good CLI patterns, the critical security vulnerability and complete lack of test coverage need immediate attention before merging. The proxy functionality would benefit from security hardening and comprehensive testing.

Recommendation: Address security issues and add tests before merging to main branch.

Copy link
Copy Markdown
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 pull request adds a new proxy command to the ZenStack CLI that starts a proxy server for connecting to ZenStack databases. The proxy server exposes REST API endpoints for database operations and schema introspection, enabling tools like ZenStack Studio to interact with the database.

Changes:

  • Added new proxy command with support for SQLite and PostgreSQL databases
  • Refactored getOutputPath utility to be shared between generate and proxy commands
  • Moved @zenstackhq/orm, @zenstackhq/server, and database driver dependencies from devDependencies to dependencies

Reviewed changes

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

Show a summary per file
File Description
packages/cli/src/actions/proxy.ts New file implementing the proxy server functionality with database connection, Express server setup, and graceful shutdown handlers
packages/cli/src/actions/index.ts Exports the new proxy action
packages/cli/src/index.ts Adds proxy command definition with CLI options and prevents process termination for long-running proxy server
packages/cli/src/actions/generate.ts Refactored to use shared getOutputPath utility and improved code formatting
packages/cli/src/actions/action-utils.ts Added getOutputPath utility function extracted from generate.ts
packages/cli/package.json Moved runtime dependencies from devDependencies and added new dependencies for server functionality
pnpm-lock.yaml Updated lock file with new dependencies and their type definitions
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

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

Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/actions/proxy.ts Outdated
Comment on lines +122 to +126
console.log(colors.gray(`Connecting to PostgreSQL database at: ${databaseUrl}`));
return new PostgresDialect({
pool: new Pool({
connectionString: databaseUrl,
}),
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For PostgreSQL connections, the Pool is created but never explicitly closed during shutdown. While client.$disconnect() might handle this, it's better to explicitly close the pool to ensure proper cleanup of database resources. Consider storing the pool reference and calling pool.end() in the shutdown handlers.

Copilot uses AI. Check for mistakes.
Comment thread packages/cli/src/index.ts
.command('proxy')
.description('Start the ZenStack proxy server')
.addOption(schemaOption)
.addOption(new Option('-p, --port <port>', 'port to run the proxy server on').default(8008))
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The port option accepts any number value without validation. Consider adding validation to ensure the port is within the valid range (1-65535) and providing a helpful error message if an invalid port is specified.

Copilot uses AI. Check for mistakes.
Comment thread packages/cli/package.json
Comment on lines +48 to +50
"cors": "^2.8.5",
"execa": "^9.6.0",
"express": "^5.0.0",
Copy link

Copilot AI Jan 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The cors package is added as a dependency in package.json and the type definitions are included, but cors is never imported or used in the code. If CORS functionality is needed for the Express server, it should be imported and applied using app.use(cors()). If not needed, the dependency should be removed.

Copilot uses AI. Check for mistakes.
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/actions/generate.ts
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jan 15, 2026

Claude finished @jiashengguo's task —— View job


PR Review: ZenStack Proxy Feature

Review Tasks

  • Analyze the new proxy implementation
  • Check code quality and best practices
  • Review security implications
  • Assess performance considerations
  • Evaluate test coverage
  • Provide comprehensive feedback

🔍 Code Review Summary

I've thoroughly reviewed the new proxy functionality which adds a development server for ZenStack. Here's my comprehensive analysis:

Positive Aspects

  1. Clean CLI Integration: The proxy command is properly integrated with the CLI structure and follows established patterns
  2. Good Error Handling: Proper error messages and graceful shutdown handling
  3. Database Support: Supports both SQLite and PostgreSQL with proper dialect configuration
  4. Flexible Configuration: Multiple ways to specify database URL (schema file, CLI option, environment variables)

⚠️ Security Concerns

Critical: Code Injection Vulnerability

Location: packages/cli/src/actions/proxy.ts:99

const urlFn = new Function('env', `return ${value}`);

Issue: Using Function constructor with user-controlled input creates a code injection vulnerability. The value comes from the schema file and could contain malicious JavaScript.

Impact: Arbitrary code execution when processing untrusted schema files.

Recommendation: Use a proper expression parser or whitelist allowed patterns instead of Function constructor.

Missing Authentication

Location: packages/cli/src/actions/proxy.ts:149

The middleware doesn't implement getSessionUser, defaulting to an open API without authentication. This is noted in the comment but should be more prominently documented as a security consideration.

🐛 Potential Bugs

  1. Path Resolution Issue (proxy.ts:117):

    if (!path.isAbsolute(filePath)) {
        resolvedUrl = path.join(outputPath, filePath);
    }

    Should use resolvedUrl = 'file:' + path.resolve(outputPath, filePath) to maintain the file: protocol.

  2. Missing Database Connection Validation: The code calls db.$connect() but doesn't properly handle connection failures or timeouts.

Performance Considerations

  1. Dynamic Schema Loading: Using jiti to dynamically import the schema is flexible but adds runtime overhead
  2. No Connection Pooling Configuration: PostgreSQL pool uses default settings which may not be optimal for all use cases
  3. Express Server: Uses basic Express setup without compression or other performance optimizations

📝 Code Quality Issues

  1. Magic Numbers: Port default (8008) and log level filtering could be constants
  2. Type Safety: Several any types used (schemaModule, schema parameter)
  3. Error Messages: Some error messages could be more descriptive

Missing Test Coverage

Critical Issue: No tests found for the new proxy functionality. The CLI package has extensive tests for other commands, but proxy functionality is completely untested.

Recommendations:

  • Add unit tests for URL evaluation logic
  • Add integration tests for server startup/shutdown
  • Add tests for different database configurations
  • Test error scenarios (invalid schema, connection failures)

🔧 Recommendations

High Priority (Security)

  1. Fix code injection vulnerability - Replace Function constructor with safe expression evaluation
  2. Add security documentation - Document authentication requirements clearly

Medium Priority (Reliability)

  1. Add comprehensive tests - Critical for a new CLI command
  2. Fix path resolution - Ensure file: URLs work correctly
  3. Improve error handling - Better database connection error handling

Low Priority (Quality)

  1. Type improvements - Remove any types where possible
  2. Performance optimizations - Consider adding connection pool configuration options
  3. Code organization - Extract constants and improve modularity

🎯 Overall Assessment

While the feature implementation is solid and follows good CLI patterns, the critical security vulnerability and complete lack of test coverage need immediate attention before merging. The proxy functionality would benefit from security hardening and comprehensive testing.

Recommendation: Address security issues and add tests before merging to main branch.

Comment thread packages/cli/src/index.ts Outdated
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/actions/proxy.ts Outdated
Comment thread packages/cli/src/actions/proxy.ts
Comment thread packages/cli/src/index.ts
@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jan 16, 2026

Claude finished @jiashengguo's task —— View job


PR Review: ZenStack Proxy Feature

Review Tasks

  • Analyze the new proxy implementation
  • Check code quality and best practices
  • Review security implications
  • Assess performance considerations
  • Evaluate test coverage
  • Provide comprehensive feedback

🔍 Code Review Summary

I've thoroughly reviewed the new proxy functionality which adds a development server for ZenStack. Here's my comprehensive analysis:

Positive Aspects

  1. Clean CLI Integration: The proxy command is properly integrated with the CLI structure and follows established patterns
  2. Good Error Handling: Proper error messages and graceful shutdown handling
  3. Database Support: Supports both SQLite and PostgreSQL with proper dialect configuration
  4. Flexible Configuration: Multiple ways to specify database URL (schema file, CLI option, environment variables)

⚠️ Security Concerns

Critical: Code Injection Vulnerability

Location: packages/cli/src/actions/proxy.ts:99

const urlFn = new Function('env', `return ${value}`);

Issue: Using Function constructor with user-controlled input creates a code injection vulnerability. The value comes from the schema file and could contain malicious JavaScript.

Impact: Arbitrary code execution when processing untrusted schema files.

Recommendation: Use a proper expression parser or whitelist allowed patterns instead of Function constructor.

Missing Authentication

Location: packages/cli/src/actions/proxy.ts:149

The middleware doesn't implement getSessionUser, defaulting to an open API without authentication. This is noted in the comment but should be more prominently documented as a security consideration.

🐛 Potential Bugs

  1. Path Resolution Issue (proxy.ts:117):

    if (!path.isAbsolute(filePath)) {
        resolvedUrl = path.join(outputPath, filePath);
    }

    Should use resolvedUrl = 'file:' + path.resolve(outputPath, filePath) to maintain the file: protocol.

  2. Missing Database Connection Validation: The code calls db.$connect() but doesn't properly handle connection failures or timeouts.

Performance Considerations

  1. Dynamic Schema Loading: Using jiti to dynamically import the schema is flexible but adds runtime overhead
  2. No Connection Pooling Configuration: PostgreSQL pool uses default settings which may not be optimal for all use cases
  3. Express Server: Uses basic Express setup without compression or other performance optimizations

📝 Code Quality Issues

  1. Magic Numbers: Port default (8008) and log level filtering could be constants
  2. Type Safety: Several any types used (schemaModule, schema parameter)
  3. Error Messages: Some error messages could be more descriptive

Missing Test Coverage

Critical Issue: No tests found for the new proxy functionality. The CLI package has extensive tests for other commands, but proxy functionality is completely untested.

Recommendations:

  • Add unit tests for URL evaluation logic
  • Add integration tests for server startup/shutdown
  • Add tests for different database configurations
  • Test error scenarios (invalid schema, connection failures)

🔧 Recommendations

High Priority (Security)

  1. Fix code injection vulnerability - Replace Function constructor with safe expression evaluation
  2. Add security documentation - Document authentication requirements clearly

Medium Priority (Reliability)

  1. Add comprehensive tests - Critical for a new CLI command
  2. Fix path resolution - Ensure file: URLs work correctly
  3. Improve error handling - Better database connection error handling

Low Priority (Quality)

  1. Type improvements - Remove any types where possible
  2. Performance optimizations - Consider adding connection pool configuration options
  3. Code organization - Extract constants and improve modularity

🎯 Overall Assessment

While the feature implementation is solid and follows good CLI patterns, the critical security vulnerability and complete lack of test coverage need immediate attention before merging. The proxy functionality would benefit from security hardening and comprehensive testing.

Recommendation: Address security issues and add tests before merging to main branch.


@claude
Copy link
Copy Markdown
Contributor

claude bot commented Jan 16, 2026

Claude finished @jiashengguo's task —— View job


PR Review: ZenStack Proxy Feature

Review Tasks

  • Analyze the new proxy implementation
  • Check code quality and best practices
  • Review security implications
  • Assess performance considerations
  • Evaluate test coverage
  • Provide comprehensive feedback

🔍 Code Review Summary

I've thoroughly reviewed the new proxy functionality which adds a development server for ZenStack. Here's my comprehensive analysis:

Positive Aspects

  1. Clean CLI Integration: The proxy command is properly integrated with the CLI structure and follows established patterns
  2. Good Error Handling: Proper error messages and graceful shutdown handling
  3. Database Support: Supports both SQLite and PostgreSQL with proper dialect configuration
  4. Flexible Configuration: Multiple ways to specify database URL (schema file, CLI option, environment variables)

⚠️ Security Concerns

Critical: Code Injection Vulnerability

Location: packages/cli/src/actions/proxy.ts:99

const urlFn = new Function('env', `return ${value}`);

Issue: Using Function constructor with user-controlled input creates a code injection vulnerability. The value comes from the schema file and could contain malicious JavaScript.

Impact: Arbitrary code execution when processing untrusted schema files.

Recommendation: Use a proper expression parser or whitelist allowed patterns instead of Function constructor.

Missing Authentication

Location: packages/cli/src/actions/proxy.ts:149

The middleware doesn't implement getSessionUser, defaulting to an open API without authentication. This is noted in the comment but should be more prominently documented as a security consideration.

🐛 Potential Bugs

  1. Path Resolution Issue (proxy.ts:117):

    if (!path.isAbsolute(filePath)) {
        resolvedUrl = path.join(outputPath, filePath);
    }

    Should use resolvedUrl = 'file:' + path.resolve(outputPath, filePath) to maintain the file: protocol.

  2. Missing Database Connection Validation: The code calls db.$connect() but doesn't properly handle connection failures or timeouts.

Performance Considerations

  1. Dynamic Schema Loading: Using jiti to dynamically import the schema is flexible but adds runtime overhead
  2. No Connection Pooling Configuration: PostgreSQL pool uses default settings which may not be optimal for all use cases
  3. Express Server: Uses basic Express setup without compression or other performance optimizations

📝 Code Quality Issues

  1. Magic Numbers: Port default (8008) and log level filtering could be constants
  2. Type Safety: Several any types used (schemaModule, schema parameter)
  3. Error Messages: Some error messages could be more descriptive

Missing Test Coverage

Critical Issue: No tests found for the new proxy functionality. The CLI package has extensive tests for other commands, but proxy functionality is completely untested.

Recommendations:

  • Add unit tests for URL evaluation logic
  • Add integration tests for server startup/shutdown
  • Add tests for different database configurations
  • Test error scenarios (invalid schema, connection failures)

🔧 Recommendations

High Priority (Security)

  1. Fix code injection vulnerability - Replace Function constructor with safe expression evaluation
  2. Add security documentation - Document authentication requirements clearly

Medium Priority (Reliability)

  1. Add comprehensive tests - Critical for a new CLI command
  2. Fix path resolution - Ensure file: URLs work correctly
  3. Improve error handling - Better database connection error handling

Low Priority (Quality)

  1. Type improvements - Remove any types where possible
  2. Performance optimizations - Consider adding connection pool configuration options
  3. Code organization - Extract constants and improve modularity

🎯 Overall Assessment

While the feature implementation is solid and follows good CLI patterns, the critical security vulnerability and complete lack of test coverage need immediate attention before merging. The proxy functionality would benefit from security hardening and comprehensive testing.

Recommendation: Address security issues and add tests before merging to main branch.


@jiashengguo jiashengguo merged commit 94c5c8a into dev Jan 18, 2026
7 of 10 checks passed
@jiashengguo jiashengguo deleted the proxy branch January 18, 2026 13:13
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants