Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Jun 12, 2025

Summary by CodeRabbit

  • New Features

    • Added a reusable schema module with comprehensive expression type definitions and utilities for easier schema manipulation and sharing.
    • Added linting scripts and unified ESLint configuration across packages.
    • Enhanced package exports to provide direct schema access.
  • Bug Fixes

    • Improved type consistency and immutability in various internal methods.
  • Refactor

    • Standardized and centralized expression utilities, replacing direct usage with a unified utility.
    • Updated import paths and consolidated schema type exports for better maintainability.
    • Replaced custom plain object checks with a third-party utility.
    • Removed deprecated authentication type utility from SDK and migrated it to runtime package.
  • Chores

    • Updated dependencies and build configurations.
    • Improved CI workflow for consistent testing and linting.

@coderabbitai
Copy link

coderabbitai bot commented Jun 12, 2025

Walkthrough

This change set introduces a unified expression type system by moving expression type definitions to a new SDK module and standardizing the usage of ExpressionUtils for expression utilities across the codebase. It updates import paths and ESLint configurations, adds new lint scripts, and adjusts build/test workflows. Several files are refactored for immutability and type consistency, and the handling of symlinks for dependencies is improved in test tools.

Changes

File(s) Change Summary
.eslintignore, .eslintrc.json, package.json, packages/cli/package.json, packages/runtime/package.json, packages/language/package.json, packages/sdk/package.json, packages/testtools/package.json Added or updated ESLint configuration files, added lint scripts, updated or removed ESLint-related dependencies.
.github/workflows/build-test.yml Added a GitHub Actions CI workflow for build, lint, and test with PostgreSQL service and pnpm caching.
packages/sdk/src/schema/expression.ts, packages/sdk/src/schema/index.ts, packages/sdk/src/schema/schema.ts Introduced new SDK module for expression types, re-exported types, added computedFields to ModelDef, removed AuthType from schema, and updated exports.
packages/runtime/src/schema/expression.ts, packages/runtime/src/schema/index.ts Refactored to import expression types from SDK, renamed Expression utility to ExpressionUtils, and updated exports to use SDK types.
packages/runtime/src/schema/auth.ts Added new generic type alias AuthType for schema-based authentication typing.
packages/runtime/src/client/crud/dialects/base.ts, packages/runtime/src/client/crud/dialects/postgresql.ts, packages/runtime/src/client/crud/dialects/sqlite.ts Updated type parameters for SelectQueryBuilder from {} to any for greater flexibility; improved immutability in variable declarations.
packages/runtime/src/client/crud/operations/base.ts, packages/runtime/src/client/crud/validator.ts, packages/runtime/src/client/query-builder.ts, packages/runtime/src/client/query-utils.ts, packages/runtime/src/client/result-processor.ts, packages/runtime/src/client/options.ts Updated import paths for schema types, improved immutability in variable declarations, and added ESLint rule disables where needed.
packages/runtime/src/client/client-impl.ts, packages/runtime/src/client/contract.ts Updated import paths for AuthType, added ESLint rule disables for banned types.
packages/runtime/src/client/crud/validator.ts, packages/runtime/src/client/helpers/schema-db-pusher.ts, packages/runtime/src/plugins/policy/expression-evaluator.ts, packages/runtime/src/plugins/policy/expression-transformer.ts, packages/runtime/src/plugins/policy/policy-handler.ts Replaced direct usage of Expression with ExpressionUtils for type guards and factory methods; updated imports accordingly.
packages/runtime/src/client/executor/zenstack-driver.ts, packages/runtime/src/client/executor/zenstack-query-executor.ts Added ESLint disables and updated variable declarations for immutability.
packages/runtime/src/utils/clone.ts, packages/runtime/src/utils/is-plain-object.ts Switched from local isPlainObject implementation to external package; removed local implementation file.
packages/runtime/src/utils/type-utils.ts Added ESLint disable for banned types on the Simplify type.
packages/language/.eslintrc.json Removed package-specific ESLint config.
packages/language/src/validators/expression-validator.ts, packages/language/src/validators/schema-validator.ts Removed unused imports.
packages/sdk/tsup.config.ts Added "schema" as a new entry point for the build.
packages/testtools/src/schema.ts Improved symlink logic for test dependencies, switching from a single symlink to per-package symlinks for ZenStack packages.
packages/sdk/src/ts-schema-generator.ts, packages/cli/test/ts-schema-gen.test.ts, packages/runtime/test/client-api/default-values.test.ts, packages/runtime/test/client-api/name-mapping.test.ts, packages/runtime/test/test-schema.ts, samples/blog/zenstack/schema.ts Replaced all usage of Expression with ExpressionUtils for expression construction and type guards; updated imports accordingly.
packages/runtime/test/utils.ts Updated import path for schema types.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SDK
    participant Runtime
    participant ExpressionUtils

    User->>SDK: Import expression types from SDK
    SDK->>ExpressionUtils: Provide expression utilities (type guards, factories)
    User->>Runtime: Use ExpressionUtils for expression construction and checks
    Runtime->>SDK: Import types from SDK (e.g., Expression, SchemaDef)
    Runtime->>ExpressionUtils: Use utilities for runtime logic and validation
Loading

Possibly related PRs

  • getting more policy test cases to pass #3: Introduces ESLint configurations and lint scripts, updates package.json scripts and dependencies for linting, and refactors expression utilities usage from Expression to ExpressionUtils across multiple files including tests, closely related by code changes.

Poem

In the warren of code, we hopped with delight,
Expressions now unified, all imports just right.
With ExpressionUtils we craft and we check,
No more stray types to cause a big wreck.
Lint bunnies are happy, the CI runs fast—
Our fluffy refactor is finished at last!
🐇✨


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:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • 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

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

🔭 Outside diff range comments (2)
packages/runtime/src/plugins/policy/expression-transformer.ts (1)

109-136: 🛠️ Refactor suggestion

Prefer eliminating // @ts-expect-error by tightening the method signatures

The three handlers now use // @ts-expect-error, which is definitely an improvement over a blanket @ts-ignore, but we still rely on a suppression instead of typing the parameters properly.
Given that each handler’s first parameter is strongly typed (LiteralExpression, ArrayExpression, FieldExpression) and the second parameter is either unused or already typed, the remaining error usually comes from this’s contextual this: any that decorators inject.
Consider declaring the methods as plain functions (or extracting them outside the class) and registering them explicitly, or adding

private _literal = (expr: LiteralExpression) => {/* … */}

which solves the contextual-this type problem and removes the need for the directive altogether. At a minimum, add a short reason comment (// @ts-expect-error <why>) to keep future maintainers from wondering what error is expected.

🧰 Tools
🪛 Biome (1.9.4)

[error] 109-109: This parameter is used before its declaration.

The parameter is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)


[error] 122-122: This parameter is used before its declaration.

The parameter is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)


[error] 133-133: This parameter is used before its declaration.

The parameter is declared here:

(lint/correctness/noInvalidUseBeforeDeclaration)

packages/runtime/src/client/query-utils.ts (1)

210-214: 🛠️ Refactor suggestion

Use a typed function instead of Function | undefined

Using the generic Function defeats type-safety and forces an ESLint suppression.
Keep the intent but with an explicit signature:

-        // eslint-disable-next-line @typescript-eslint/ban-types
-        let computer: Function | undefined;
+        let computer:
+            | ((eb: ExpressionBuilder<any, any>) => ExpressionWrapper<any, any, unknown>)
+            | undefined;

You can then remove the eslint-disable comment.

🧰 Tools
🪛 Biome (1.9.4)

[error] 211-211: Don't use 'Function' as a type.

Prefer explicitly define the function shape. This type accepts any function-like value, which can be a common source of bugs.

(lint/complexity/noBannedTypes)

🧹 Nitpick comments (18)
packages/runtime/src/client/executor/zenstack-driver.ts (1)

133-135: Suppress false-positive no-this-alias lint warning.
The inline ESLint directive is justified to preserve the this alias required for logging. Consider adding a brief inline comment explaining why the alias is necessary for clarity.

packages/sdk/src/ts-schema-generator.ts (3)

636-642: Minor: union order changed, but alias type name would communicate intent better

| { type: string; env: undefined; url: string } | … is verbose and repeated.
Creating a named discriminated union (e.g. type StaticUrlDS = { … }) improves readability and keeps call-sites tidy.


1034-1040: Silent catch block still swallows parsing issues

The added // ignore clarifies intent, but silently discarding an error when a malformed SQLite URL is passed can hide configuration bugs. At least log the error at debug level or return it in the thrown Error below so the user knows why the URL was rejected.


1138-1147: Same non-null assertion pattern appears multiple times

The non-null assertion on reference!.$refText is repeated for parameters and return types.
Extract a helper:

const toTypeName = (t: { type?: string; reference?: { $refText: string } }) =>
    t.type ?? t.reference?.$refText ?? 'Unknown';

and replace all occurrences. DRY, safer, and ESLint-friendly.

Also applies to: 1170-1177, 1205-1210

packages/runtime/src/client/options.ts (1)

1-2: Disable rule locally instead of file-wide

ban-types is turned off for the whole file, but only Function/{} usages usually trigger it.
Wrap the offending type with a block suppression instead:

// eslint-disable-next-line @typescript-eslint/ban-types
type Whatever = Function;

so that future code still benefits from the rule.

packages/runtime/src/client/contract.ts (1)

1-2: Same observation as in options.ts: scope the ban-types disable

Prefer a narrow // eslint-disable-next-line … above the specific line(s) that need Function or {} rather than disabling the rule for the whole file.

packages/cli/package.json (1)

24-27: Consider adding an autofix variant of the lint script

Running eslint --ext ts src is great for CI, but dev UX improves if we also provide a quick-fix command:

"lint:fix": "eslint src --ext ts --fix"

This mirrors the other packages’ scripts and shortens the feedback loop.

.eslintignore (1)

1-1: .eslintignore entry is fine but consider future-proofing

**/dist/** covers most build artefacts, but if some packages output to build/ or out/ they will still be linted.
If that is intentional, keep as-is; otherwise consider adding common build folders to avoid noisy CI.

packages/sdk/package.json (1)

6-10: Add .tsx and stricter exit flag to the lint script

  1. Source may eventually include React/JSX helpers – adding tsx extension now avoids missing files.
  2. eslint exits with 0 by default when no files match; adding --ext ts,tsx --max-warnings 0 makes CI stricter.
-        "lint": "eslint src --ext ts",
+        "lint": "eslint src --ext .ts,.tsx --max-warnings 0",
packages/runtime/src/utils/clone.ts (1)

1-2: Avoid blanket @ts-expect-error; install proper typings for is-plain-object.

Suppressing all type checks on the import hides potential issues and defeats the purpose of enabling strict lint rules. The package is-plain-object has community typings (@types/is-plain-object). Adding that (or declaring your own module) allows you to drop the directive and keep full type-safety.

-// @ts-expect-error
-import { isPlainObject } from 'is-plain-object';
+import { isPlainObject } from 'is-plain-object';

Then add

pnpm add -w -D @types/is-plain-object

or create types/is-plain-object.d.ts with a minimal declaration.

packages/runtime/package.json (2)

10-11: Lint script uses default config but ignores TS/JS files outside src/.

If tests or build scripts live under other folders (e.g. test/), they will be skipped. Consider:

-        "lint": "eslint src --ext ts",
+        "lint": "eslint \"src/**/*.ts\" \"test/**/*.ts\"",

or rely on .eslintignore.


87-90: Add typings for new dependency is-plain-object.

Same concern as in clone.ts: include @types/is-plain-object (dev-dep) or declare a module so consumers of @zenstackhq/runtime don’t need to suppress errors themselves.

.eslintrc.json (1)

1-22: Consider turning no-explicit-any to warn instead of disabling.

You already relaxed the rule for Function; keeping any as a warning provides a safety net without blocking builds.

-        "@typescript-eslint/no-explicit-any": "off",
+        "@typescript-eslint/no-explicit-any": "warn",

Optional, but aligns with the objective of “improved consistency”.

packages/runtime/src/client/crud/dialects/sqlite.ts (1)

52-57: Generic parameter relaxed to any – confirm the trade-off

Changing the third type argument of SelectQueryBuilder from {} to any eliminates the compile-time guarantee that only plain objects are passed around, effectively disabling useful structural checks on the selected row type.
If the original constraint was merely too strict, consider replacing any with a more descriptive interface (e.g. Record<string, unknown>), or introducing a helper type alias so the loss of type-safety is explicit and documented.

packages/runtime/src/client/crud/dialects/base.ts (1)

58-63: Same loosening of SelectQueryBuilder generic as in SQLite dialect

While this mirrors other files, it propagates any throughout the filtering pipeline. If total flexibility is required, consider introducing an alias (type SQB = SelectQueryBuilder<any, any, unknownRow>;) so intent is explicit and can be tightened later.

packages/runtime/src/client/crud/operations/base.ts (2)

149-153: Rename + const is 👍 but watch the shadowing

Promoting the flattened filter to a const _filter is a good immutability tweak.
Just make sure callers never confuse the original filter arg with _filter – the rename helps, but a short inline comment explaining why the extra pass is required would avoid future refactors accidentally dropping it.


465-493: Manual cursor pagination logic is brittle

The filters construction loops orderByItems.length times, recomputing a
sub-query for each level. With large compound keys this generates an OR with
quadratic predicates that Postgres optimiser may struggle with.

A lighter pattern is:

-- pseudo SQL
WHERE (key1, key2, ) >= (SELECT key1, key2  FROM t WHERE cursorFilter)

Kysely allows tuple comparisons with eb.refTuple.
Worth revisiting for performance.

packages/runtime/src/client/crud/dialects/postgresql.ts (1)

261-266: Object-args union widened – OK but document

Including SelectQueryBuilder<any,…> in objArgs broadens acceptable argument
types for jsonb_build_object. That’s powerful, yet future maintainers might
mix in builders not intended for JSON aggregation. A short JSDoc comment on
buildRelationObjectArgs describing the allowed elements would help contain
misuse.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 01580a7 and 88a6f20.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (29)
  • .eslintignore (1 hunks)
  • .eslintrc.json (1 hunks)
  • .github/workflows/build-test.yml (1 hunks)
  • package.json (1 hunks)
  • packages/cli/package.json (1 hunks)
  • packages/language/.eslintrc.json (0 hunks)
  • packages/language/src/validators/expression-validator.ts (0 hunks)
  • packages/language/src/validators/schema-validator.ts (1 hunks)
  • packages/runtime/package.json (3 hunks)
  • packages/runtime/src/client/client-impl.ts (1 hunks)
  • packages/runtime/src/client/contract.ts (1 hunks)
  • packages/runtime/src/client/crud-types.ts (1 hunks)
  • packages/runtime/src/client/crud/dialects/base.ts (4 hunks)
  • packages/runtime/src/client/crud/dialects/postgresql.ts (2 hunks)
  • packages/runtime/src/client/crud/dialects/sqlite.ts (2 hunks)
  • packages/runtime/src/client/crud/operations/base.ts (8 hunks)
  • packages/runtime/src/client/executor/zenstack-driver.ts (1 hunks)
  • packages/runtime/src/client/executor/zenstack-query-executor.ts (1 hunks)
  • packages/runtime/src/client/helpers/schema-db-pusher.ts (1 hunks)
  • packages/runtime/src/client/options.ts (1 hunks)
  • packages/runtime/src/client/query-utils.ts (1 hunks)
  • packages/runtime/src/plugins/policy/expression-transformer.ts (3 hunks)
  • packages/runtime/src/plugins/policy/policy-handler.ts (1 hunks)
  • packages/runtime/src/schema/schema.ts (1 hunks)
  • packages/runtime/src/utils/clone.ts (1 hunks)
  • packages/runtime/src/utils/is-plain-object.ts (0 hunks)
  • packages/runtime/src/utils/type-utils.ts (1 hunks)
  • packages/sdk/package.json (1 hunks)
  • packages/sdk/src/ts-schema-generator.ts (6 hunks)
💤 Files with no reviewable changes (3)
  • packages/language/src/validators/expression-validator.ts
  • packages/language/.eslintrc.json
  • packages/runtime/src/utils/is-plain-object.ts
🧰 Additional context used
🧬 Code Graph Analysis (4)
packages/runtime/src/client/helpers/schema-db-pusher.ts (1)
packages/runtime/src/schema/schema.ts (1)
  • BuiltinType (84-92)
packages/runtime/src/client/crud/dialects/base.ts (4)
packages/runtime/src/client/crud-types.ts (1)
  • FindArgs (572-591)
packages/runtime/src/schema/schema.ts (1)
  • GetModels (106-109)
packages/runtime/src/client/query-utils.ts (1)
  • flattenCompoundUniqueFilters (312-337)
packages/runtime/src/schema/expression.ts (2)
  • Expression (1-10)
  • Expression (75-195)
packages/runtime/src/client/crud/operations/base.ts (1)
packages/runtime/src/client/query-utils.ts (2)
  • flattenCompoundUniqueFilters (312-337)
  • isRelationField (140-147)
packages/runtime/src/client/crud/dialects/postgresql.ts (2)
packages/runtime/src/client/crud-types.ts (1)
  • FindArgs (572-591)
packages/runtime/src/schema/schema.ts (1)
  • GetModels (106-109)
🪛 actionlint (1.7.7)
.github/workflows/build-test.yml

14-14: label "buildjet-8vcpu-ubuntu-2204" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


36-36: the runner of "actions/checkout@v3" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (10)
packages/language/src/validators/schema-validator.ts (1)

3-3: Cleaned up unused imports.

The AST import now only brings in isDataSource and the Model type, which are actually used in validateDataSources and class signature. Removing dead imports improves readability and adheres to the new lint rules.

packages/runtime/src/client/helpers/schema-db-pusher.ts (1)

201-201: Enforce immutability by using const for result.
Switching from let to const for the result variable aligns with the repository’s immutability guidelines and ESLint rules.

packages/runtime/src/client/executor/zenstack-query-executor.ts (1)

85-85: Enforce immutability for oldQueryNode.
Changing the declaration to const ensures the original query node reference is preserved unchanged, complying with the new linting standards.

packages/runtime/src/utils/type-utils.ts (1)

44-45: Disable ban-types for the Simplify alias.
The added ESLint directive suppresses the ban on empty object types for this utility type while retaining its intended functionality.

packages/runtime/src/plugins/policy/policy-handler.ts (1)

281-281: Enforce immutability for value.
Switching from let to const for the value variable aligns with the project’s immutability and linting practices.

packages/sdk/src/ts-schema-generator.ts (1)

455-462: Potential undefined dereference via non-null assertion

field.type.reference!.$refText is now asserted non-null. Although we short-circuit when field.type.type is truthy, we still rely on an implicit invariant that “if type is falsy, reference is non-null”.
Add an explicit guard or an invariant to make that assumption guaranteed at runtime and easier to reason about:

- field.type.type ?? field.type.reference!.$refText
+ field.type.type ??
+     (invariant(field.type.reference, 'Expected reference type'), field.type.reference.$refText)
packages/runtime/src/client/crud/dialects/sqlite.ts (1)

187-187: ArgsType now allows a full SelectQueryBuilder – verify downstream calls

json_object ultimately expects scalar or JSON-producing expressions. A raw SelectQueryBuilder works only if SQLite accepts it as a correlated sub-query returning a single column / single row. Please double-check every call site that pushes a SelectQueryBuilder into objArgs; otherwise json_group_array(json_object(...)) may raise “row value misused” errors at runtime.

packages/runtime/src/client/crud/dialects/base.ts (1)

288-288: 👍 Switched letconst for immutable collection

Good catch – declaring conditions as const communicates immutability and satisfies ESLint prefer-const.

packages/runtime/src/client/crud/operations/base.ts (2)

179-186: skip switched to const – safe given current usage

skip is now immutable whereas take can still be rewritten.
Current code never mutates skip, so the change is safe and conveys intent.
No action needed.


416-426: Nice micro-refactor

Streaming all scalar fields via reduce directly into selectField removes the
temp fields accumulator and clarifies intent.

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

🧹 Nitpick comments (3)
packages/runtime/src/schema/auth.ts (1)

1-3: Guard against circular imports from . index re-export.

import type { GetModels, SchemaDef } from '.' relies on index.ts re-exporting these entities.
If index.ts also re-imports from ./auth, you will trigger a type-level circular reference that may slow TS or break in incremental builds.
Consider importing directly from './schema' instead.

packages/sdk/package.json (1)

9-10: Lint script: consider all TS/JS variants

eslint src --ext ts skips .mts, .cts, and .tsx files.
If you introduce any of those (or generated .d.ts) the CI lint job will silently ignore them.

packages/runtime/src/schema/expression.ts (1)

67-73: Minor nit: use object shorthand

Tiny readability tweak – the property value matches the identifier name.

-        return {
-            kind: 'member',
-            receiver: receiver,
-            members,
-        };
+        return {
+            kind: 'member',
+            receiver,
+            members,
+        };
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88a6f20 and fc6c855.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (35)
  • package.json (1 hunks)
  • packages/cli/test/ts-schema-gen.test.ts (4 hunks)
  • packages/language/package.json (0 hunks)
  • packages/runtime/src/client/client-impl.ts (2 hunks)
  • packages/runtime/src/client/contract.ts (1 hunks)
  • packages/runtime/src/client/crud-types.ts (2 hunks)
  • packages/runtime/src/client/crud/dialects/base.ts (4 hunks)
  • packages/runtime/src/client/crud/dialects/postgresql.ts (3 hunks)
  • packages/runtime/src/client/crud/dialects/sqlite.ts (3 hunks)
  • packages/runtime/src/client/crud/operations/base.ts (10 hunks)
  • packages/runtime/src/client/crud/validator.ts (1 hunks)
  • packages/runtime/src/client/helpers/schema-db-pusher.ts (4 hunks)
  • packages/runtime/src/client/options.ts (2 hunks)
  • packages/runtime/src/client/query-builder.ts (1 hunks)
  • packages/runtime/src/client/query-utils.ts (2 hunks)
  • packages/runtime/src/client/result-processor.ts (1 hunks)
  • packages/runtime/src/plugins/policy/expression-evaluator.ts (2 hunks)
  • packages/runtime/src/plugins/policy/expression-transformer.ts (9 hunks)
  • packages/runtime/src/plugins/policy/policy-handler.ts (4 hunks)
  • packages/runtime/src/schema/auth.ts (1 hunks)
  • packages/runtime/src/schema/expression.ts (3 hunks)
  • packages/runtime/src/schema/index.ts (1 hunks)
  • packages/runtime/test/client-api/default-values.test.ts (2 hunks)
  • packages/runtime/test/client-api/name-mapping.test.ts (2 hunks)
  • packages/runtime/test/test-schema.ts (11 hunks)
  • packages/runtime/test/utils.ts (1 hunks)
  • packages/sdk/package.json (3 hunks)
  • packages/sdk/src/schema/expression.ts (1 hunks)
  • packages/sdk/src/schema/index.ts (1 hunks)
  • packages/sdk/src/schema/schema.ts (1 hunks)
  • packages/sdk/src/ts-schema-generator.ts (16 hunks)
  • packages/sdk/tsup.config.ts (1 hunks)
  • packages/testtools/package.json (1 hunks)
  • packages/testtools/src/schema.ts (2 hunks)
  • samples/blog/zenstack/schema.ts (7 hunks)
💤 Files with no reviewable changes (1)
  • packages/language/package.json
✅ Files skipped from review due to trivial changes (13)
  • packages/runtime/test/utils.ts
  • packages/runtime/src/client/query-builder.ts
  • packages/cli/test/ts-schema-gen.test.ts
  • packages/runtime/src/client/result-processor.ts
  • packages/runtime/src/client/options.ts
  • packages/runtime/test/client-api/name-mapping.test.ts
  • packages/runtime/src/client/crud/validator.ts
  • packages/sdk/src/schema/index.ts
  • samples/blog/zenstack/schema.ts
  • packages/runtime/src/client/query-utils.ts
  • packages/runtime/src/plugins/policy/expression-evaluator.ts
  • packages/runtime/test/test-schema.ts
  • packages/sdk/src/schema/expression.ts
🚧 Files skipped from review as they are similar to previous changes (12)
  • packages/runtime/src/client/client-impl.ts
  • packages/runtime/src/client/crud-types.ts
  • packages/runtime/src/client/contract.ts
  • packages/runtime/src/client/helpers/schema-db-pusher.ts
  • packages/runtime/src/plugins/policy/policy-handler.ts
  • package.json
  • packages/runtime/src/plugins/policy/expression-transformer.ts
  • packages/sdk/src/ts-schema-generator.ts
  • packages/runtime/src/client/crud/dialects/postgresql.ts
  • packages/runtime/src/client/crud/dialects/sqlite.ts
  • packages/runtime/src/client/crud/dialects/base.ts
  • packages/runtime/src/client/crud/operations/base.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
packages/runtime/test/client-api/default-values.test.ts (1)
packages/runtime/src/schema/expression.ts (1)
  • ExpressionUtils (16-136)
packages/runtime/src/schema/auth.ts (2)
packages/sdk/src/schema/schema.ts (2)
  • SchemaDef (11-18)
  • GetModels (105-108)
packages/runtime/src/client/crud-types.ts (1)
  • ModelResult (100-146)
packages/runtime/src/schema/expression.ts (1)
packages/sdk/src/schema/expression.ts (9)
  • Expression (1-10)
  • ArrayExpression (17-20)
  • CallExpression (46-50)
  • NullExpression (56-58)
  • ThisExpression (52-54)
  • UnaryExpression (33-37)
  • BinaryExpression (39-44)
  • FieldExpression (22-25)
  • MemberExpression (27-31)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-test (20.x)
🔇 Additional comments (6)
packages/testtools/src/schema.ts (2)

2-2: Import path migration looks good

The switch to @zenstackhq/sdk/schema reflects the refactor done in the SDK package.


69-78: Path assumption may fail when dist/ is not yet built

../../${pkg}/dist presumes each ZenStack package has already been built locally.
When running tests from a clean checkout (e.g. CI), dist may be missing, causing ENOENT.

Options:

  1. Build the packages before creating symlinks.
  2. Point the symlink to the package root instead of dist, letting Node resolve exports.

Either change will make the test helper more resilient.

packages/sdk/tsup.config.ts (1)

4-7:

❓ Verification inconclusive

Double-check DTS + sub-path alignment

A new schema entry is great, but make sure the generated artifacts match the paths declared in package.json:

  • tsup usually emits dist/schema.d.ts, not schema.d.cts.
  • Mismatches will break types resolution for consumers using require.

🏁 Script executed:

#!/usr/bin/env bash
# After running `pnpm -F @zenstackhq/sdk build`, ensure the files expected
# in the export map actually exist.
fd --extension d.ts dist
fd --extension d.cts dist

Length of output: 54


Double-check DTS + sub-path alignment

File: packages/sdk/tsup.config.ts (lines 4–7):

entry: {
    index: 'src/index.ts',
    schema: 'src/schema/index.ts',
},

A new schema entry is great, but ensure your build output aligns with the export paths in package.json:

  • tsup should emit dist/schema.d.ts (not schema.d.cts)
  • After building, confirm both dist/index.d.ts and dist/schema.d.ts exist
  • Missing or misnamed .d.ts files will break type resolution for consumers using require

To verify locally:

pnpm -F @zenstackhq/sdk build
ls -1 dist/*.d.ts
packages/runtime/test/client-api/default-values.test.ts (1)

70-83:

❌ Incorrect review comment

expect(...).toSatisfy may be undefined under Vitest

Vitest doesn’t ship toSatisfy by default.
If you haven’t already set up jest-extended (or the Vitest equivalent) in your test runner, this spec will throw at runtime.

-import { describe, expect, it } from 'vitest';
+import { describe, expect, it } from 'vitest';
+// import 'vitest-extended'; // or 'jest-extended', whichever you wire up

Or switch to core matchers (e.g. toBeTruthy) if you prefer to avoid an extra dependency.


To verify if toSatisfy is available out-of-the-box or via a configured plugin, let’s check for its usage and any jest-extended/vitest-extended setup in the repo:


🏁 Script executed:

#!/bin/bash
set -e

echo "1. Instances of 'toSatisfy' in tests:"
rg -n "toSatisfy" || true

echo
echo "2. 'vitest-extended' in package.json dependencies/devDependencies:"
grep -R "\"vitest-extended\"" -n package.json || true

echo
echo "3. 'jest-extended' in package.json dependencies/devDependencies:"
grep -R "\"jest-extended\"" -n package.json || true

echo
echo "4. 'setupFiles' references in vitest config files:"
grep -R "setupFiles" -n .

echo
echo "5. Direct imports of 'vitest-extended':"
rg -n "import .*vitest-extended" || true

Length of output: 1976


toSatisfy Is Already Registered via Your Vitest Setup
Your packages/runtime/vitest.config.ts includes

setupFiles: [path.resolve(__dirname, './test/vitest-ext.ts')],

and packages/runtime/test/vitest-ext.ts pulls in and registers the matchers (e.g. from jest-extended), so expect(...).toSatisfy is defined at runtime. No import changes are needed here.

Likely an incorrect or invalid review comment.

packages/runtime/src/schema/index.ts (1)

1-4: LGTM – runtime correctly re-exports SDK schema

The new re-export keeps runtime lean and avoids divergent type definitions.
Nice cleanup.

packages/runtime/src/schema/expression.ts (1)

87-99: Confirm operator literals are included in BinaryOperator

'&&' and '||' are hard-coded here. Ensure the BinaryOperator union imported from the SDK includes both; otherwise TypeScript will flag these as incompatible.

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

♻️ Duplicate comments (2)
.github/workflows/build-test.yml (2)

14-14: ⚠️ Unknown runner label
The runs-on: buildjet-8vcpu-ubuntu-2204 label is not a default GitHub runner and was flagged previously. If this is a custom self-hosted runner, update your actionlint.yaml to include it; otherwise use a supported label (e.g., ubuntu-latest-8-cores).

🧰 Tools
🪛 actionlint (1.7.7)

14-14: label "buildjet-8vcpu-ubuntu-2204" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


72-75: 🛠️ Refactor suggestion

Remove redundant pnpm install
Running pnpm install --frozen-lockfile twice wastes CI minutes. If you need to rebuild native or internal modules instead, replace it with pnpm -r rebuild.

-           # install again for internal dependencies
-           - name: Install internal dependencies
-             run: pnpm install --frozen-lockfile
+           - name: Rebuild native/internal modules
+             run: pnpm -r rebuild
🧹 Nitpick comments (1)
.github/workflows/build-test.yml (1)

16-29: Suggestion: Pin PostgreSQL service image
For deterministic CI, pin the PostgreSQL image to a specific tag (e.g. postgres:15.3) instead of latest.

 services:
     postgres:
-        image: postgres
+        image: postgres:15.3
         env:
             POSTGRES_PASSWORD: abc123
         options: >-
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc6c855 and ca92d88.

📒 Files selected for processing (2)
  • .github/workflows/build-test.yml (1 hunks)
  • package.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • package.json
🧰 Additional context used
🪛 actionlint (1.7.7)
.github/workflows/build-test.yml

14-14: label "buildjet-8vcpu-ubuntu-2204" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-2019", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "ubuntu-20.04", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build-test (20.x)
🔇 Additional comments (12)
.github/workflows/build-test.yml (12)

1-8: Approve: Workflow trigger configuration
The name and on.pull_request.branches settings correctly scope CI to PRs on main and dev.


9-11: Approve: Permissions scope
Limiting contents: read is sufficient for lint, build, and test steps.


12-13: Approve: Job definition
The build-test job is clearly declared under jobs.


30-33: Approve: Matrix strategy
Running against Node.js 20.x in a matrix is set up correctly.


35-37: Approve: Checkout step
Using actions/checkout@v4 is up-to-date and correct.


38-42: Approve: pnpm setup
pnpm/action-setup@v2 with the specified version is valid.


43-47: Approve: Node.js setup
buildjet/setup-node@v3 with pnpm caching is correctly configured.


49-62: Approve: pnpm cache configuration
Caching the pnpm store directory by lockfile hash will speed up CI.


63-65: Approve: Install dependencies
The first pnpm install --frozen-lockfile is required for build and lint.


66-68: Approve: Build step
pnpm run build correctly compiles the project before testing.


69-71: Approve: Lint step
pnpm run lint integrates the new ESLint configs as intended.


76-78: Approve: Test step
pnpm run test will execute your test suite after build and lint.

@ymc9 ymc9 merged commit 22246e8 into dev Jun 13, 2025
2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Jun 28, 2025
@ymc9 ymc9 deleted the chore/ci-lint branch November 25, 2025 00:28
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