-
-
Notifications
You must be signed in to change notification settings - Fork 12
merge dev to main (v3.0.0-alpha.27) #185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
* fix: use z.strictObject consistently * use nominal operator for onQuery plugin callback
* fix: disallow distinct for sqlite * update * update
* feat: cli plugin support * update * update * more fixes
Co-authored-by: ymc9 <[email protected]>
WalkthroughThe PR introduces a plugin-driven CLI generation pipeline, updates SDK generator APIs and exports, refactors runtime CRUD/dialect handling (including distinct/cursor flow and operation typing), tightens validators to strict objects, adds custom-type→jsonb mapping, adjusts tests accordingly, removes baseUrl from multiple tsconfigs, updates scripts, and bumps package versions. Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Poem
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
|
Claude finished @ymc9's task —— View job PR Review: dev → mainI'll conduct a comprehensive review of this merge PR covering code quality, potential issues, performance, security, and test coverage. Review Tasks:
🔍 Comprehensive AnalysisThis PR merges significant architectural improvements and bug fixes from the dev branch to main, representing the 3.0.0-alpha.27 release. 🏗️ Major Features Added1. CLI Plugin System (#181)New Architecture:
Code Quality Assessment:
Recommendations:
2. Custom Types in DB Pusher (#184)Enhancement:
Implementation Review:
❌ Potential Issues:
🐛 Bug FixesSQLite Distinct Restriction (#180)
Input Validation Improvements (#178, #179)
🔒 Security AnalysisHigh Priority Issues:
Medium Priority:
Low Priority:
📊 Test Coverage AssessmentWell Covered: Coverage Gaps: ⚡ Performance ConsiderationsPositive:
Areas for Optimization:
🏆 Code Quality AssessmentArchitecture: ⭐⭐⭐⭐⭐ (5/5)
Type Safety: ⭐⭐⭐⭐⭐ (5/5)
Error Handling: ⭐⭐⭐⭐ (4/5)
Security: ⭐⭐ (2/5)
📝 RecommendationsCritical (Fix Before Merge)
High Priority
Medium Priority
Low Priority
✅ Approval RecommendationThe custom types feature and input validation improvements are well-implemented and ready for production. The plugin architecture is well-designed but needs security hardening. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR merges the dev branch to main, bumping the version from 3.0.0-alpha.26 to 3.0.0-alpha.27 and implementing a new CLI plugin architecture. The key changes include:
- Refactored CLI generate command to use a plugin-based architecture with core TypeScript and Prisma plugins
- Updated multiple TypeScript configuration files to remove "baseUrl" compiler option
- Enhanced runtime query builder with improved distinct support and cursor pagination
- Fixed type annotations and improved API design for better type safety
Reviewed Changes
Copilot reviewed 58 out of 59 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/e2e/package.json | Version bump to 3.0.0-alpha.27 |
| samples/blog/package.json | Version bump and updated CLI command names |
| pnpm-workspace.yaml | Updated Prisma version and added @types/node catalog entry |
| packages/zod/src/index.ts | Changed from z.object to z.strictObject for better validation |
| packages/runtime/src/client/crud/validator.ts | Enhanced validation with strictObject usage |
| packages/runtime/src/client/crud-types.ts | Added provider-specific distinct support |
| packages/cli/src/actions/generate.ts | Complete rewrite to implement plugin architecture |
| packages/sdk/src/ts-schema-generator.ts | Simplified API to accept Model directly instead of file paths |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🔭 Outside diff range comments (1)
packages/runtime/src/client/client-impl.ts (1)
369-372: Bug: post-processing uses the original args instead of the possibly overridden _argsPlugins can override args by wrapping proceed. Using the outer args here ignores those overrides and can lead to incorrect result processing (e.g., select/include).
Apply this diff:
- if (r && postProcess) { - result = resultProcessor.processResult(r, model, args); - } else { + if (r && postProcess) { + result = resultProcessor.processResult(r, model, _args as any); + } else {
🧹 Nitpick comments (32)
packages/runtime/src/client/helpers/schema-db-pusher.ts (2)
191-194: Handle arrays and provider differences for custom typesThe early return maps every custom type to plain
jsonb, which:
- bypasses the array handling below (Lines 210–216), so
CustomType[]becomesjsonbinstead ofjsonb[](PostgreSQL),- forces
jsonbon non-PostgreSQL providers, which can be an invalid or undesirable column type.Consider adding array handling and gating by provider:
- if (this.isCustomType(fieldDef.type)) { - return 'jsonb'; - } + if (this.isCustomType(fieldDef.type)) { + if (this.schema.provider.type === 'postgresql') { + return fieldDef.array ? sql.raw('jsonb[]') : 'jsonb'; + } + // Non-Postgres fallback for custom types. Consider aligning with how `Json` is handled cross-provider. + return 'text'; + }Notes:
- If you intend custom types to behave like built-in
Jsoneverywhere, mirror whatever cross-provider strategy you want forJson(today it returnsjsonbunconditionally). If keepingjsonbuniversally is intentional, at least fix the array case:return fieldDef.array ? sql.raw('jsonb[]') : 'jsonb';- To avoid accidental shadowing of built-ins by custom types named like
Int,String, etc., ensureisCustomTypeexcludes known built-ins or move custom-type resolution after built-in detection.
218-221: Make custom-type detection O(1) and more robust
Object.values(...).some(...)is O(n) per call and repeats for every field. IftypeDefsis keyed by type name (likely), you can simplify and speed this up. Also be explicit about nullability.- private isCustomType(type: string) { - return this.schema.typeDefs && Object.values(this.schema.typeDefs).some((def) => def.name === type); - } + private isCustomType(type: string) { + const defs = this.schema.typeDefs; + // If `typeDefs` is keyed by name, prefer O(1) lookup: + return !!defs && Object.prototype.hasOwnProperty.call(defs, type); + }If
typeDefsis NOT keyed by name, keep current semantics but consider precomputing a Set once for O(1) lookups:// Outside the selected lines: example approach private readonly customTypeNames = new Set<string>( Object.values(this.schema.typeDefs ?? {}).map((d) => d.name), ); private isCustomType(type: string) { return this.customTypeNames.has(type); }Optionally also add a guard to exclude known built-ins to prevent shadowing.
packages/zod/src/index.ts (1)
10-10: Optional: align the SelectSchema type with strictness
SelectSchemacurrently aliasesZodObject<...>without specifying the unknown-keys mode (defaults to 'strip'), while the runtime schema here is strict. Consider updating the type to reflect strictness for better type fidelity.If acceptable, adjust
packages/zod/src/types.ts:// before export type SelectSchema<Schema extends SchemaDef, Model extends GetModels<Schema>> = ZodObject<{ [Key in ScalarFields<Schema, Model>]: MapScalarType<Schema, Model, Key>; }>; // after (note: second generic param 'strict') export type SelectSchema<Schema extends SchemaDef, Model extends GetModels<Schema>> = ZodObject<{ [Key in ScalarFields<Schema, Model>]: MapScalarType<Schema, Model, Key>; }, 'strict'>;pnpm-workspace.yaml (1)
8-8: Keep Prisma CLI and Client in lockstep via catalogRecommend adding '@prisma/client' to the catalog with the same range as 'prisma' to avoid drift across packages and samples. This prevents subtle mismatches between generator and client.
Apply this diff:
catalog: kysely: ^0.27.6 zod: ^4.0.0 prisma: ^6.14.0 + '@prisma/client': ^6.14.0 langium: 3.5.0 langium-cli: 3.5.0 ts-pattern: ^5.7.1 typescript: ^5.0.0 '@types/node': ^20.17.24 tmp: ^0.2.3 '@types/tmp': ^0.2.6packages/language/src/validators/datamodel-validator.ts (1)
443-447: Tiny readability refactor: capture the base model ref onceTo avoid repeating property access and non-null assertions, grab a local
baseModelRefafter the invariant and reuse it.Apply this diff:
- invariant(model.baseModel.ref, 'baseModel must be resolved'); - - // check if the base model is a delegate model - if (!isDelegateModel(model.baseModel.ref!)) { + const baseModelRef = model.baseModel.ref; + invariant(baseModelRef, 'baseModel must be resolved'); + + // check if the base model is a delegate model + if (!isDelegateModel(baseModelRef)) { accept('error', `Model ${model.baseModel.$refText} cannot be extended because it's not a delegate model`, { node: model, property: 'baseModel', }); return; }.vscode/launch.json (1)
13-15: Relying on CWD for schema discovery matches the new plugin-driven flowSwitching to
args: ["generate"]withcwdpointing at the sample app’s zenstack folder is consistent with the updated CLI behavior.Optionally add verbose logging to ease debugging:
- "args": ["generate"], + "args": ["generate", "--verbose"],TODO.md (5)
12-15: Fix markdown list indentation (MD007) for nested bullets under "CLI".Current indentation uses 4 and 8 spaces; markdownlint expects 2 and 4 for 2nd/3rd levels. Adjust as below.
- - [x] plugin mechanism - - [x] built-in plugins - - [x] ts - - [x] prisma + - [x] plugin mechanism + - [x] built-in plugins + - [x] ts + - [x] prisma
17-19: Normalize indentation for "ZModel" sub-items (MD007).Use 2 spaces for the second-level list items under ZModel.
- - [x] Import + - [x] Import - - [ ] Datasource provider-scoped attributes + - [ ] Datasource provider-scoped attributes
88-89: Indentation of "Migrate to tsdown" under ORM/Misc is too deep.Expected 3rd-level indent (4 spaces) per markdownlint; reduce by 4 spaces.
- - [ ] Migrate to tsdown + - [ ] Migrate to tsdownNote: Line 89 starts the next section; ensure its indentation is consistent with its parent as well.
91-91: Indentation for "Post-mutation hooks..." under "Plugin" should be 2 spaces.- - [x] Post-mutation hooks should be called after transaction is committed + - [x] Post-mutation hooks should be called after transaction is committed
109-109: Indentation for "MySQL" under "Databases" (MD007).Make it a second-level bullet (2 spaces).
- - [ ] MySQL + - [ ] MySQLpackages/runtime/src/client/crud-types.ts (1)
633-644: Provider-gated distinct in FindArgs is correct; consider aligning validator behavior.Typing only exposes
distinctfor PostgreSQL viaProviderSupportsDistinct, which matches dialect capabilities. However, the runtime validator currently always acceptsdistinct(see validator.ts Line 212-218). Consider gating in the validator too for consistency and earlier feedback to users.If helpful, I can patch validator.ts to only allow
distinctwhenschema.provider.type === 'postgresql'.packages/runtime/src/client/crud/validator.ts (2)
212-218: Gatedistinctby provider for consistency with types and dialects.Types only allow
distinctfor PostgreSQL, but the validator accepts it unconditionally. Aligning validator prevents confusing "accepted but ignored" args on providers that don't support it.- fields['distinct'] = this.makeDistinctSchema(model).optional(); + if (this.schema.provider.type === 'postgresql') { + fields['distinct'] = this.makeDistinctSchema(model).optional(); + }
630-656: Gate relationdistinctfor to-many includes by provider as well.Same rationale as above: only PostgreSQL supports DISTINCT ON(field). Keep runtime validation aligned with type-level gating.
- ...(fieldDef.array - ? { - // to-many relations can be ordered, skipped, taken, and cursor-located - orderBy: z.lazy(() => this.makeOrderBySchema(fieldDef.type, true, false)).optional(), - skip: this.makeSkipSchema().optional(), - take: this.makeTakeSchema().optional(), - cursor: this.makeCursorSchema(fieldDef.type).optional(), - distinct: this.makeDistinctSchema(fieldDef.type).optional(), - } - : {}), + ...(fieldDef.array + ? { + // to-many relations can be ordered, skipped, taken, and cursor-located + orderBy: z.lazy(() => this.makeOrderBySchema(fieldDef.type, true, false)).optional(), + skip: this.makeSkipSchema().optional(), + take: this.makeTakeSchema().optional(), + cursor: this.makeCursorSchema(fieldDef.type).optional(), + ...(this.schema.provider.type === 'postgresql' + ? { distinct: this.makeDistinctSchema(fieldDef.type).optional() } + : {}), + } + : {}),packages/runtime/test/scripts/generate.ts (1)
24-29: Surface load warnings and improve error readabilityMinor DX improvement: print warnings from loadDocument and format errors line-by-line. This helps when schema validations fail during CI.
Apply:
- const result = await loadDocument(schemaPath, pluginModelFiles); - if (!result.success) { - throw new Error(`Failed to load schema from ${schemaPath}: ${result.errors}`); - } - await generator.generate(result.model, outputDir); + const result = await loadDocument(schemaPath, pluginModelFiles); + if (result.warnings?.length) { + console.warn(`Warnings while loading schema from ${schemaPath}:\n${result.warnings.join('\n')}`); + } + if (!result.success) { + throw new Error(`Failed to load schema from ${schemaPath}:\n${result.errors.join('\n')}`); + } + await generator.generate(result.model, outputDir);packages/cli/src/plugins/prisma.ts (2)
9-17: Always ensure the output directory exists (even for the default path)Right now mkdirSync runs only when pluginOptions.output is provided. If defaultOutputPath hasn’t been created by the caller, writeFileSync will fail. Make directory creation unconditional.
Apply this diff:
let outDir = defaultOutputPath; if (typeof pluginOptions['output'] === 'string') { outDir = path.resolve(defaultOutputPath, pluginOptions['output']); - if (!fs.existsSync(outDir)) { - fs.mkdirSync(outDir, { recursive: true }); - } } + if (!fs.existsSync(outDir)) { + fs.mkdirSync(outDir, { recursive: true }); + } const prismaSchema = await new PrismaSchemaGenerator(model).generate(); fs.writeFileSync(path.join(outDir, 'schema.prisma'), prismaSchema);
10-11: Optional: Disallow absolute output paths to keep generation confined under the default output rootIf you want to prevent plugins from writing outside defaultOutputPath, guard against absolute output values.
Example:
- if (typeof pluginOptions['output'] === 'string') { + if (typeof pluginOptions['output'] === 'string') { + if (path.isAbsolute(pluginOptions['output'])) { + throw new Error(`'output' must be a relative path`); + } outDir = path.resolve(defaultOutputPath, pluginOptions['output']);packages/cli/test/plugins/prisma-plugin.test.ts (1)
17-30: Optional: Add a quick content sanity checkTo catch accidental empty writes, consider a minimal file-size or non-empty content check in addition to existsSync. This isn’t critical but can surface regressions earlier.
Example:
const tsPath = path.join(workDir, 'generated-schema/schema.ts'); expect(fs.existsSync(tsPath)).toBe(true); expect(fs.readFileSync(tsPath, 'utf8').length).toBeGreaterThan(0);packages/cli/src/plugins/typescript.ts (2)
10-18: Unconditionally ensure the output directory existsSimilar to the Prisma plugin, mkdirSync currently happens only when pluginOptions.output is set. TsSchemaGenerator will usually create directories, but making it explicit here improves robustness and consistency.
Apply this diff:
let outDir = defaultOutputPath; if (typeof pluginOptions['output'] === 'string') { outDir = path.resolve(defaultOutputPath, pluginOptions['output']); - if (!fs.existsSync(outDir)) { - fs.mkdirSync(outDir, { recursive: true }); - } } + if (!fs.existsSync(outDir)) { + fs.mkdirSync(outDir, { recursive: true }); + } await new TsSchemaGenerator().generate(model, outDir);
9-16: Optional: Avoid duplication by extracting a shared helper for output resolutionBoth plugins share identical outDir resolution/creation logic. Consider a small helper under packages/cli/src/plugins/_utils.ts to reduce drift.
Example helper (new file: packages/cli/src/plugins/_utils.ts):
import fs from 'node:fs'; import path from 'node:path'; export function resolveOutDir(defaultOutputPath: string, pluginOptions: Record<string, unknown>) { let outDir = defaultOutputPath; const output = pluginOptions['output']; if (typeof output === 'string') { if (path.isAbsolute(output)) { throw new Error(`'output' must be a relative path`); } outDir = path.resolve(defaultOutputPath, output); } fs.mkdirSync(outDir, { recursive: true }); return outDir; }Then in each plugin:
import { resolveOutDir } from './_utils'; const outDir = resolveOutDir(defaultOutputPath, pluginOptions);packages/testtools/src/schema.ts (2)
45-48: Improve error message formatting and include all diagnosticsWhen
loadDocumentfails,result.errorsis an array; interpolating it directly results in a comma-joined string. Joining with newlines improves readability.Also consider surfacing
result.warnings(if any) to aid debugging.Apply this diff for clearer error output:
- if (!result.success) { - throw new Error(`Failed to load schema from ${zmodelPath}: ${result.errors}`); - } + if (!result.success) { + throw new Error(`Failed to load schema from ${zmodelPath}:\n${result.errors.join('\n')}`); + }Optionally, log warnings after a successful load:
- if (result.warnings.length) console.warn(
Schema warnings:\n${result.warnings.join('\n')});
85-87: Mirror the improved error formatting here as wellSame suggestion as above for better readability and diagnostics when loading from a schema path fails.
Apply this diff:
- if (!result.success) { - throw new Error(`Failed to load schema from ${schemaPath}: ${result.errors}`); - } + if (!result.success) { + throw new Error(`Failed to load schema from ${schemaPath}:\n${result.errors.join('\n')}`); + }packages/runtime/src/client/crud/operations/find.ts (1)
6-24: Guard against unsupported operations at runtimeThe handler is specific to find operations but the signature accepts any
CoreCrudOperation. Adding a lightweight runtime guard prevents accidental dispatch (and surfaces clearer errors).Apply this diff to add a defensive check:
export class FindOperationHandler<Schema extends SchemaDef> extends BaseOperationHandler<Schema> { - async handle(operation: CoreCrudOperation, args: unknown, validateArgs = true): Promise<unknown> { + async handle(operation: CoreCrudOperation, args: unknown, validateArgs = true): Promise<unknown> { + if (operation !== 'findMany' && operation !== 'findUnique' && operation !== 'findFirst') { + throw new Error(`FindOperationHandler received unsupported operation: ${operation}`); + } // normalize args to strip `undefined` fields const normalizedArgs = this.normalizeArgs(args);packages/cli/test/plugins/custom-plugin.test.ts (1)
1-50: End-to-end plugin generation test reads well; add a quick content assertionThe test exercises the custom plugin path correctly (TS compilation, CLI invocation, output path resolution). Consider also asserting the file content to catch false positives where a file exists but is empty or wrong.
Apply this diff:
runCli('generate', workDir); expect(fs.existsSync(path.join(workDir, 'custom-output/foo.txt'))).toBe(true); + expect(fs.readFileSync(path.join(workDir, 'custom-output/foo.txt'), 'utf8')).toBe('from my plugin');packages/runtime/test/client-api/find.test.ts (1)
244-249: Distinct behavior tests: good coverage, minor type nit
- Creating duplicate post titles for dedup validation is spot-on.
- Gating SQLite with an explicit rejection check is appropriate given provider capabilities.
- Include/select combinations are exercised well.
Nit: using
as anyfor distinct is understandable for cross-backend typing, but consider narrowing types in tests to avoidanywhere possible.Also applies to: 264-271, 279-305
packages/runtime/src/client/crud/dialects/base.ts (2)
62-108: Centralized where/skip-take/orderBy/distinct/cursor composition is a good consolidation; consider default order when using cursorThis method greatly improves consistency. One functional suggestion: when a
cursoris present and no explicitorderByis provided, applying the default order ensures deterministic paging.Apply this diff to enable default ordering when a cursor is used:
result = this.buildOrderBy( result, model, model, args.orderBy, - skip !== undefined || take !== undefined, + skip !== undefined || take !== undefined || args.cursor !== undefined, negateOrderBy, );Optional: For DISTINCT ON determinism, consider prepending distinct fields to the ORDER BY when supported (leftmost), or at least documenting the behavior when
orderByis omitted.
169-208: Cursor filter: make subquery scalar and ignore non-scalar orderingsTwo robustness tweaks:
- Ensure the subquery used for comparisons returns a single row (defensive, even if cursor is unique).
- Filter
orderByentries to scalar sorts only ('asc' | 'desc'), falling back to the default if none remain. This prevents accidental inclusion of relation/aggregate sorts that the lexical cursor comparison can’t handle.Apply this diff:
- const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model); - - const orderByItems = ensureArray(_orderBy).flatMap((obj) => Object.entries<SortOrder>(obj)); + const _orderBy = orderBy ?? makeDefaultOrderBy(this.schema, model); + + let orderByItems = ensureArray(_orderBy) + .flatMap((obj) => Object.entries(obj)) + .filter(([, v]) => v === 'asc' || v === 'desc') as [string, SortOrder][]; + if (orderByItems.length === 0) { + orderByItems = ensureArray(makeDefaultOrderBy(this.schema, model)) + .flatMap((obj) => Object.entries(obj)) as [string, SortOrder][]; + } @@ - eb.selectFrom(model).select(`${model}.${field}`).where(cursorFilter), + eb.selectFrom(model).select(`${model}.${field}`).where(cursorFilter).limit(1),Note: If you intend to support cursor with aggregate/relation orderings later, this area will need a different strategy (e.g., projecting computed order keys in a CTE and comparing tuples).
packages/cli/src/actions/generate.ts (5)
78-81: Improve dynamic import error messageInterpolating the error object yields “[object Object]”. Prefer the message for clarity.
Apply this diff:
- } catch (error) { - throw new CliError(`Failed to load plugin ${provider}: ${error}`); - } + } catch (error) { + throw new CliError( + `Failed to load plugin ${provider}: ${ + error instanceof Error ? error.message : String(error) + }`, + ); + }
95-99: Prefer CLI-friendly error for missing generate()Use CliError so the top-level CLI can render a consistent, user-friendly message.
Apply this diff:
- invariant( - typeof cliPlugin.generate === 'function', - `Plugin ${cliPlugin.name} does not have a generate function`, - ); + if (typeof cliPlugin.generate !== 'function') { + throw new CliError(`Plugin ${cliPlugin.name} does not have a generate function`); + }
87-92: Nit: reverse() on a single-element array is redundantdefaultPlugins contains one element; reverse() is a no-op. Consider removing for clarity.
No code change required; optional cleanup:
- const defaultPlugins = [corePlugins['typescript']].reverse(); + const defaultPlugins = [corePlugins['typescript']];
101-109: Consider honoring --silent for spinners and logsEven when options.silent is true, ora spinners (and console.warn in getPluginOptions) still emit output. Consider threading a silent flag into runPlugins to disable spinners and warnings.
If you choose to implement, minimal shape:
- Add a silent param to runPlugins and gate spinner creation with it.
- Gate console.warns in option parsing behind the same flag (or route through a logger).
Happy to provide a concrete patch if you want to wire silent through.
29-33: Add tests to verify plugin failures abort the generate commandThere’s currently no test ensuring that a plugin error prevents the
generatecommand from printing a success message. Without this, a regression could allow “Generation completed successfully” to appear even when a plugin fails. Please add a test (e.g.packages/cli/test/generate.test.ts) that:
- Installs or mocks a plugin whose
generatehook throws an error (or omits thegeneratefunction).- Invokes the CLI via
runCli('generate', workDir)(or equivalent).- Asserts that it rejects or exits with a non-zero code, not logging the success message.
This will guard against silent failures in plugin execution.
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (58)
.vscode/launch.json(1 hunks)TODO.md(3 hunks)package.json(2 hunks)packages/cli/package.json(1 hunks)packages/cli/src/actions/generate.ts(3 hunks)packages/cli/src/index.ts(0 hunks)packages/cli/src/plugins/index.ts(1 hunks)packages/cli/src/plugins/prisma.ts(1 hunks)packages/cli/src/plugins/typescript.ts(1 hunks)packages/cli/test/generate.test.ts(0 hunks)packages/cli/test/plugins/custom-plugin.test.ts(1 hunks)packages/cli/test/plugins/prisma-plugin.test.ts(1 hunks)packages/cli/tsconfig.json(0 hunks)packages/common-helpers/package.json(1 hunks)packages/common-helpers/tsconfig.json(0 hunks)packages/create-zenstack/package.json(1 hunks)packages/create-zenstack/tsconfig.json(0 hunks)packages/dialects/sql.js/package.json(1 hunks)packages/dialects/sql.js/tsconfig.json(0 hunks)packages/eslint-config/package.json(1 hunks)packages/ide/vscode/package.json(1 hunks)packages/ide/vscode/tsconfig.json(0 hunks)packages/language/package.json(1 hunks)packages/language/src/validators/datamodel-validator.ts(1 hunks)packages/language/tsconfig.json(0 hunks)packages/runtime/package.json(1 hunks)packages/runtime/src/client/client-impl.ts(20 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(1 hunks)packages/runtime/src/client/crud/dialects/sqlite.ts(1 hunks)packages/runtime/src/client/crud/operations/base.ts(5 hunks)packages/runtime/src/client/crud/operations/find.ts(1 hunks)packages/runtime/src/client/crud/validator.ts(11 hunks)packages/runtime/src/client/helpers/schema-db-pusher.ts(2 hunks)packages/runtime/src/client/plugin.ts(1 hunks)packages/runtime/test/client-api/find.test.ts(7 hunks)packages/runtime/test/schemas/typing/typecheck.ts(0 hunks)packages/runtime/test/scripts/generate.ts(2 hunks)packages/sdk/package.json(1 hunks)packages/sdk/src/cli-plugin.ts(1 hunks)packages/sdk/src/generator.ts(0 hunks)packages/sdk/src/index.ts(1 hunks)packages/sdk/src/ts-schema-generator.ts(1 hunks)packages/sdk/tsconfig.json(0 hunks)packages/tanstack-query/package.json(1 hunks)packages/tanstack-query/tsconfig.json(0 hunks)packages/testtools/package.json(2 hunks)packages/testtools/src/schema.ts(3 hunks)packages/testtools/tsconfig.json(0 hunks)packages/typescript-config/package.json(1 hunks)packages/vitest-config/package.json(1 hunks)packages/zod/package.json(1 hunks)packages/zod/src/index.ts(1 hunks)packages/zod/tsconfig.json(0 hunks)pnpm-workspace.yaml(1 hunks)samples/blog/package.json(1 hunks)tests/e2e/package.json(1 hunks)
💤 Files with no reviewable changes (14)
- packages/sdk/tsconfig.json
- packages/cli/test/generate.test.ts
- packages/dialects/sql.js/tsconfig.json
- packages/testtools/tsconfig.json
- packages/tanstack-query/tsconfig.json
- packages/runtime/test/schemas/typing/typecheck.ts
- packages/language/tsconfig.json
- packages/ide/vscode/tsconfig.json
- packages/zod/tsconfig.json
- packages/cli/tsconfig.json
- packages/sdk/src/generator.ts
- packages/create-zenstack/tsconfig.json
- packages/common-helpers/tsconfig.json
- packages/cli/src/index.ts
🧰 Additional context used
📓 Path-based instructions (2)
{packages,samples,tests}/**
📄 CodeRabbit Inference Engine (CLAUDE.md)
Packages are located in
packages/,samples/, andtests/
Files:
packages/tanstack-query/package.jsonpackages/vitest-config/package.jsonpackages/create-zenstack/package.jsonpackages/common-helpers/package.jsonpackages/sdk/package.jsonpackages/cli/src/plugins/prisma.tspackages/zod/package.jsontests/e2e/package.jsonpackages/sdk/src/cli-plugin.tspackages/language/package.jsonpackages/cli/src/plugins/index.tspackages/eslint-config/package.jsonsamples/blog/package.jsonpackages/language/src/validators/datamodel-validator.tspackages/cli/package.jsonpackages/typescript-config/package.jsonpackages/cli/test/plugins/prisma-plugin.test.tspackages/ide/vscode/package.jsonpackages/cli/src/plugins/typescript.tspackages/runtime/src/client/crud/dialects/postgresql.tspackages/testtools/package.jsonpackages/dialects/sql.js/package.jsonpackages/runtime/src/client/crud/operations/find.tspackages/zod/src/index.tspackages/runtime/package.jsonpackages/sdk/src/ts-schema-generator.tspackages/runtime/src/client/plugin.tspackages/runtime/src/client/crud/dialects/sqlite.tspackages/runtime/src/client/crud-types.tspackages/runtime/test/client-api/find.test.tspackages/runtime/test/scripts/generate.tspackages/sdk/src/index.tspackages/cli/test/plugins/custom-plugin.test.tspackages/runtime/src/client/crud/validator.tspackages/testtools/src/schema.tspackages/runtime/src/client/crud/dialects/base.tspackages/runtime/src/client/helpers/schema-db-pusher.tspackages/cli/src/actions/generate.tspackages/runtime/src/client/client-impl.tspackages/runtime/src/client/crud/operations/base.ts
tests/e2e/**
📄 CodeRabbit Inference Engine (CLAUDE.md)
E2E tests are in
tests/e2e/directory
Files:
tests/e2e/package.json
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: Database migrations still use Prisma CLI under the hood
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: `zenstack generate` compiles ZModel to TypeScript schema (`schema.ts`)
Applied to files:
packages/cli/src/plugins/prisma.ts.vscode/launch.jsonpackages/language/package.jsonpackages/cli/src/plugins/typescript.tspackages/sdk/src/ts-schema-generator.tspackages/runtime/test/scripts/generate.tspackages/sdk/src/index.tspackages/testtools/src/schema.tspackages/cli/src/actions/generate.ts
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: No runtime dependency on prisma/client
Applied to files:
pnpm-workspace.yaml
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: ZModel schema (`schema.zmodel`) defines database structure and policies
Applied to files:
packages/runtime/src/client/crud/validator.ts
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: Schema-first approach with ZModel DSL extension of Prisma schema language
Applied to files:
packages/runtime/src/client/crud/validator.ts
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: Applies to **/schema.zmodel : Always run `zenstack generate` after modifying ZModel schemas
Applied to files:
packages/testtools/src/schema.ts
🧬 Code Graph Analysis (18)
packages/cli/src/plugins/prisma.ts (2)
packages/sdk/src/cli-plugin.ts (1)
CliPlugin(32-47)packages/sdk/src/index.ts (1)
PrismaSchemaGenerator(3-3)
packages/sdk/src/cli-plugin.ts (1)
packages/runtime/src/utils/type-utils.ts (1)
MaybePromise(70-70)
packages/language/src/validators/datamodel-validator.ts (2)
packages/language/src/utils.ts (1)
isDelegateModel(153-155)packages/sdk/src/model-utils.ts (1)
isDelegateModel(69-71)
packages/cli/test/plugins/prisma-plugin.test.ts (1)
packages/cli/test/utils.ts (2)
createProject(12-18)runCli(20-23)
packages/cli/src/plugins/typescript.ts (2)
packages/sdk/src/cli-plugin.ts (1)
CliPlugin(32-47)packages/sdk/src/ts-schema-generator.ts (1)
TsSchemaGenerator(54-1388)
packages/runtime/src/client/crud/operations/find.ts (3)
packages/sdk/src/schema/schema.ts (1)
SchemaDef(10-18)packages/runtime/src/client/plugin.ts (1)
CoreCrudOperation(49-49)packages/runtime/src/client/crud/operations/base.ts (1)
CoreCrudOperation(51-66)
packages/zod/src/index.ts (2)
packages/runtime/src/client/crud/operations/base.ts (1)
schema(87-89)packages/zod/src/types.ts (1)
SelectSchema(4-6)
packages/sdk/src/ts-schema-generator.ts (2)
packages/language/src/generated/ast.ts (2)
Model(559-563)Model(565-565)packages/sdk/src/prisma/prisma-builder.ts (1)
Model(115-164)
packages/runtime/src/client/crud-types.ts (2)
packages/sdk/src/schema/schema.ts (3)
SchemaDef(10-18)GetModels(108-108)NonRelationFields(190-194)packages/runtime/src/utils/type-utils.ts (1)
OrArray(48-48)
packages/runtime/test/client-api/find.test.ts (4)
packages/runtime/test/client-api/client-specs.ts (1)
createClientSpecs(6-42)packages/runtime/test/client-api/utils.ts (1)
createUser(6-21)packages/runtime/src/client/crud/dialects/postgresql.ts (1)
provider(26-28)packages/runtime/src/client/crud/dialects/sqlite.ts (1)
provider(26-28)
packages/runtime/test/scripts/generate.ts (1)
packages/language/src/index.ts (1)
loadDocument(21-132)
packages/cli/test/plugins/custom-plugin.test.ts (2)
packages/cli/test/utils.ts (2)
createProject(12-18)runCli(20-23)packages/cli/src/utils/exec-utils.ts (1)
execSync(6-15)
packages/runtime/src/client/crud/validator.ts (2)
packages/runtime/test/schemas/basic/schema.ts (1)
schema(9-284)samples/blog/zenstack/schema.ts (1)
schema(9-228)
packages/testtools/src/schema.ts (2)
packages/language/src/index.ts (1)
loadDocument(21-132)packages/sdk/src/ts-schema-generator.ts (1)
TsSchemaGenerator(54-1388)
packages/runtime/src/client/crud/dialects/base.ts (4)
packages/sdk/src/schema/schema.ts (1)
GetModels(108-108)packages/runtime/src/client/crud-types.ts (1)
SortOrder(370-370)packages/runtime/src/client/query-utils.ts (2)
ensureArray(274-280)makeDefaultOrderBy(217-220)packages/runtime/src/client/errors.ts (1)
QueryError(13-17)
packages/cli/src/actions/generate.ts (5)
packages/language/src/generated/ast.ts (5)
Model(559-563)Model(565-565)isPlugin(628-630)Plugin(619-624)Plugin(626-626)packages/sdk/src/cli-plugin.ts (1)
CliPlugin(32-47)packages/cli/src/cli-error.ts (1)
CliError(4-4)packages/common-helpers/src/tiny-invariant.ts (1)
invariant(4-14)packages/language/src/utils.ts (2)
getLiteral(269-283)getLiteralArray(308-316)
packages/runtime/src/client/client-impl.ts (2)
packages/runtime/src/client/plugin.ts (1)
CoreCrudOperation(49-49)packages/runtime/src/client/crud/operations/base.ts (2)
CoreCrudOperation(51-66)AllCrudOperation(68-68)
packages/runtime/src/client/crud/operations/base.ts (1)
packages/runtime/src/client/plugin.ts (1)
CoreCrudOperation(49-49)
🪛 markdownlint-cli2 (0.17.2)
TODO.md
12-12: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
13-13: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
14-14: Unordered list indentation
Expected: 4; Actual: 8
(MD007, ul-indent)
15-15: Unordered list indentation
Expected: 4; Actual: 8
(MD007, ul-indent)
17-17: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
18-18: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
19-19: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
88-88: Unordered list indentation
Expected: 4; Actual: 8
(MD007, ul-indent)
89-89: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
91-91: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
109-109: Unordered list indentation
Expected: 2; Actual: 4
(MD007, ul-indent)
⏰ 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: claude-review
- GitHub Check: build-test (20.x)
🔇 Additional comments (63)
packages/zod/src/index.ts (2)
10-10: Review strict select schemas for extra-key handlingSwitching from
z.stripObjecttoz.strictObjectmeans extra keys will now trigger parse errors. Please review allmakeSelectSchemacall sites and ensure callers only pass exact shapes—or update them and add tests to assert that unexpected fields are rejected.Affected locations in
packages/runtime/src/client/crud/validator.ts:
- Line 208:
fields['select'] = this.makeSelectSchema(model).optional();- Line 587:
private makeSelectSchema(model: string) { … }- Line 637:
select: z.lazy(() => this.makeSelectSchema(fieldDef.type)).optional(),- Line 749:
select: this.makeSelectSchema(model).optional(),- Line 763:
select: this.makeSelectSchema(model).optional(),- Line 1012:
select: this.makeSelectSchema(model).optional(),- Line 1030:
select: this.makeSelectSchema(model).optional(),- Line 1041:
select: this.makeSelectSchema(model).optional(),- Line 1151:
select: this.makeSelectSchema(model).optional(),– Confirm each call site either already enforces exact keys or update the implementation/callers.
– Add or adjust unit tests to verify that passing extra properties results in parse failures.
10-10: Verify Zod version forz.strictObjectsupportOur scan found that
zodis declared only as a peerDependency with a non-specific version (catalog:) in these packages:
- packages/runtime/package.json (peerDependencies): zod@catalog:
- packages/zod/package.json (peerDependencies): zod@catalog:
Because it’s unclear which Zod release will be installed at runtime—and
z.strictObjectwas only added in Zod ≥ 3.21.4—please either:
- Confirm your end-to-end dependency resolution installs Zod ≥ 3.21.4 (in which case
z.strictObject(...)is safe),- Or switch to the well-supported
.strict()pattern to guarantee compatibility:- return z.strictObject(mapFields(schema, model)) as SelectSchema<Schema, typeof model>; + return z.object(mapFields(schema, model)).strict() as SelectSchema<Schema, typeof model>;pnpm-workspace.yaml (1)
13-13: Node types are included by default—no tsconfig changes neededAll 14
tsconfig*.jsonfiles omit a"types"array, which means TypeScript automatically picks up every installed@typespackage (including@types/node). No explicittypes: ["node"]entries are required.packages/runtime/package.json (1)
3-3: Version bump looks goodConsistent with the repo-wide alpha.27 bump. No export or dependency changes here.
packages/common-helpers/package.json (1)
3-3: Approved: package version bump onlyNo surface/API changes; aligns with the workspace version.
packages/create-zenstack/package.json (1)
3-3: Approved: version bumpNo behavioral changes; release metadata updated as expected.
packages/sdk/package.json (1)
3-3: Approved: SDK version bump – re-exports confirmedVerified that:
- packages/sdk/src/index.ts contains
export * from './cli-plugin';- packages/sdk/src/cli-plugin.ts defines and exports
export interface CliPlugin { … }No further changes needed.
packages/ide/vscode/package.json (1)
4-4: Version bump to 3.0.0-alpha.27 verified and ready to publish
- No lingering
3.0.0-alpha.26references found in the repo.engines.vscoderemains^1.63.0in packages/ide/vscode/package.json.- Version (
3.0.0-alpha.27) and publish script (pnpm build && vsce publish --no-dependencies --pre-release --follow-symlinks) are correctly configured.packages/vitest-config/package.json (1)
4-4: Consistent version bump; no functional changes hereNothing else changed in this package; safe to release with the rest of the monorepo.
packages/cli/package.json (1)
6-6: Version bump verified; update CLI changelogAll package.json versions are now at 3.0.0-alpha.27 and there are no lingering references to 3.0.0-alpha.26.
Please ensure the CLI changelog or release notes document any removed flags or behavior changes.packages/eslint-config/package.json (1)
3-3: LGTM: version bumped to 3.0.0-alpha.27No other changes; consistent with the monorepo release.
packages/zod/package.json (1)
3-3: Version bump acknowledged; exports and deps unchangedLooks good alongside the rest of the release.
packages/typescript-config/package.json (1)
3-3: LGTM: version bump to 3.0.0-alpha.27Monorepo meta version update looks consistent with the broader release bump.
tests/e2e/package.json (1)
3-3: LGTM: e2e package version bump alignedVersion aligns with the workspace release bump. No issues spotted.
packages/language/package.json (1)
4-4: LGTM: language package version bumpMatches the workspace-wide 3.0.0-alpha.27 release. No functional changes here.
package.json (1)
3-3: LGTM: root version bumped to 3.0.0-alpha.27Root version aligns with the release train.
packages/dialects/sql.js/package.json (1)
3-3: LGTM: dialect package version bumpConsistent with the monorepo version update. No API changes implied.
packages/language/src/validators/datamodel-validator.ts (1)
446-446: Non-null assertion after invariant is safe hereUsing
model.baseModel.ref!is sound given the precedinginvariant(model.baseModel.ref, ...). This also makes the type explicit at the call site.packages/tanstack-query/package.json (1)
3-3: All internal packages consistently bumped to 3.0.0-alpha.27
Verified via script – no mismatches found.packages/testtools/package.json (2)
3-3: Version bump is consistent with the release trainNo issues spotted with moving to
3.0.0-alpha.27.
44-48: Node.js types are included by default via@types/nodeAll
tsconfig.jsonfiles—includingpackages/testtools/tsconfig.json—extend the shared@zenstackhq/typescript-config/base.json, which does not specify acompilerOptions.typesarray. By TypeScript’s defaults, omittingtypesmeans all@types/*packages innode_modulesare loaded, so your added@types/nodewill be picked up without needing an explicit"types": ["node"]entry.No changes required here.
samples/blog/package.json (2)
3-3: Version bump is fine for the sample appNo functional impact beyond aligning with the workspace release.
7-9: Scripts and CLI dependency verified in samples/blog/package.jsonAll three scripts (
generate,db:push,db:migrate) match the expectedzenCLI commands, and@zenstackhq/cliis present underdevDependenciesasworkspace:*. No further changes needed.packages/runtime/src/client/crud-types.ts (2)
616-626: Good separation of concerns: FilterArgs and SortAndTakeArgs.Breaking the args into composable parts improves readability and reuse across find variants. No issues spotted.
1263-1270: Provider capability checks updated to use provider.type — LGTM.This matches how validator checks case sensitivity and aligns with SchemaDef.
packages/runtime/src/client/crud/validator.ts (11)
748-753: Strict create args: good tightening without changing shape.Switching to
z.strictObjecthere is consistent with the overall stricter validation strategy.
762-766: Switch from merge to extend: confirm no behavior drift.
extendavoids potential strictness and overlap pitfalls frommerge, but it changes composition semantics for overlapping keys. Looks fine given keys are additive (select,omit), but please confirm there are no cases wherebasemay already contain those keys and relied onmergebehavior.Would you like me to run a quick grep to confirm no callers expect
createManyAndReturn/updateManyAndReturnto accept additional keys viamergesemantics?
990-995: Strict object for connectOrCreate payload: LGTM.Tighter schema helps catch stray fields early.
998-1002: Strict object for createMany data: LGTM.Consistent with strict inputs elsewhere.
1009-1017: Strict update args: LGTM.Consistent tightening; mutual exclusivity refinements are preserved.
1020-1025: Strict updateMany args: LGTM.No concerns.
1029-1034: Switch to extend for updateManyAndReturn: same note as createManyAndReturn.Semantics are sound; just ensure no overlap assumptions existed.
I can scan tests/usages to ensure no reliance on
mergebehavior here.
1037-1046: Strict upsert args: LGTM.Matches the rest of the CRUD surface.
1150-1155: Strict delete args: LGTM.Consistent with strictness push and exclusivity checks.
1188-1199: Count aggregate input strictness: LGTM.Explicit key set prevents typos from silently passing.
1258-1271: GroupBy strict object and refinements: LGTM.Rules for by/having/orderBy are sound and now enforced on a strict base.
packages/runtime/src/client/crud/operations/base.ts (3)
51-69: CoreCrudOperation and AllCrudOperation introduction: backward-compat maintained.Clear separation of core vs. nominal “OrThrow” operations. Looks good.
99-100: Abstract handle signature switched to CoreCrudOperation: LGTM.Matches the new operation types and plugin export aliasing.
150-152: Unified filter/sort/take via dialect.buildFilterSortTake: nice consolidation.Reduces duplication and centralizes provider-specific behavior (distinct/cursor/negative take flip). No issues spotted.
If desired, I can cross-check that both sqlite and postgres dialects implement identical semantics for skip/take/order flipping and cursor filtering via a quick code scan.
packages/runtime/src/client/plugin.ts (1)
49-49: Re-exporting CoreCrudOperation as CrudOperation preserves API surface.This keeps external plugin code stable while aligning internals. LGTM.
packages/runtime/src/client/crud/dialects/sqlite.ts (1)
87-90: buildFilterSortTake usage verified with full cursor/distinct/skip/take coverage
buildFilterSortTakeis defined onBaseCrudDialectand invoked in bothsqlite.tsandpostgresql.ts.- Runtime tests exercise cursor pagination, skip/take behavior (including negative takes), distinct handling (with SQLite’s unsupported‐distinct error), and SQLite’s offset‐without‐limit workaround via
buildSkipTake.No further changes needed—merging as is.
packages/cli/src/plugins/index.ts (1)
1-2: Re-exporting core plugins from a central index is straightforward and clearThe named exports make plugin discovery simple and align with the new plugin-driven flow.
packages/runtime/src/client/crud/dialects/postgresql.ts (1)
93-95: buildFilterSortTake correctly handles DISTINCT ON and cursor pagination in Postgres
- In postgresql.ts,
supportsDistinctOnistrue, so the helper’sif (this.supportsDistinctOn)branch is taken.- The base implementation applies
buildOrderBybefore adding thedistinctOnclause and then applies the cursor filter (buildCursorFilter) using the same ordering and caret-negation logic.- Existing
findtests for PG cover bothdistinctwithskip/takeand cursor scenarios and are green.No changes needed.
packages/sdk/src/ts-schema-generator.ts (1)
55-66: Model-basedgeneratesignature applied: all call sites updatedVerified that every instantiation of
TsSchemaGeneratornow invokesgenerate(model, outputDir)and no callers rely on the old signature.
Key call-sites updated accordingly:
- packages/testtools/src/schema.ts (lines 50, 88)
- packages/runtime/test/scripts/generate.ts (line 28)
- packages/cli/src/plugins/typescript.ts (line 17)
All internal and external invocations have migrated to the new signature.
packages/cli/src/plugins/prisma.ts (1)
5-19: Solid plugin implementation; aligns with the new CLI plugin contractThe plugin’s shape, status text, and generation flow look correct and consistent with the TypeScript plugin. Using PrismaSchemaGenerator(model).generate() and writing schema.prisma under the resolved outDir is straightforward and clear.
packages/cli/test/plugins/prisma-plugin.test.ts (1)
6-60: Good end-to-end coverage for default and custom outputsThe tests validate both built-in behavior and plugin-specified outputs for TypeScript and Prisma, matching the expected directory structures. Using createProject + runCli mirrors real usage and keeps assertions focused on the contract.
packages/cli/src/plugins/typescript.ts (1)
6-19: Plugin implementation looks consistent and correctConsistent with the Prisma plugin, resolves output dir, and delegates to TsSchemaGenerator with the expected signature generate(model, outDir). Nice.
packages/sdk/src/cli-plugin.ts (3)
7-27: Context shape is clear and sufficientschemaFile, model, defaultOutputPath, and pluginOptions cover the needs for current plugins and allow future growth. The doc comments are succinct.
32-46: Interface reads well; keep the signature stableThe CliPlugin contract is minimal and easy to implement. Maintaining generate(context): MaybePromise stable across minor versions will help ecosystem plugins.
2-2: No action needed: ‘langium’ is a declared dependency
The SDK’s package.json lists “langium” under dependencies, so importingMaybePromiseas a type won’t break consumers. You can keep the existing import.Likely an incorrect or invalid review comment.
packages/sdk/src/index.ts (1)
1-7: Root exports are coherent and align with the new plugin architectureRe-exporting the CLI plugin contract and generators (Prisma/TS) from the SDK root makes consumption by the CLI plugins straightforward. Adding the ModelUtils namespace is a nice touch.
packages/testtools/src/schema.ts (3)
1-1: Import alignment with new model-based flow looks correctImporting
loadDocumentfrom@zenstackhq/languagematches the new, model-first generation flow.
51-51: Updated generator API usage is correctPassing
result.modelintoTsSchemaGenerator.generate(model, workDir)matches the updated SDK API.
89-89: Consistent generator invocationUsing
result.modelfor in-place generation is consistent and correct.packages/runtime/src/client/crud/operations/find.ts (1)
3-3: Rename to CoreCrudOperation is consistent with the base changesImport change looks aligned with the refactor introducing
CoreCrudOperation.packages/runtime/test/client-api/find.test.ts (3)
10-10: Provider-aware test matrix is a good evolutionIncluding
providerin the spec tuple improves clarity and enables backend-specific gating below.
674-695: PostgreSQL-only nested distinct scenarios are well isolatedThese assertions directly validate
distinctinterplay with nested selects/includes and ordering. Clear separation by provider avoids flaky behavior on SQLite.
913-925: Cursor within include: solid additionThis ensures cursor semantics are respected for nested relations, complementing top-level cursor tests.
packages/runtime/src/client/crud/dialects/base.ts (3)
24-25: Importing ensureArray is appropriateThe helper is used for normalizing potentially non-array inputs (e.g., distinct, orderBy).
95-102: Provider-gated distinct-on with clear error messageThrowing a
QueryErrorfor providers without DISTINCT ON support is clear and matches tests. No change requested.
815-815: Type tightening on aggregate order entriesUsing
Object.entries<SortOrder>(value)improves type clarity when iterating aggregate order keys.packages/runtime/src/client/client-impl.ts (2)
354-356: LGTM: clear split between core and nominal operationsSeparating the operation executed by handlers (CoreCrudOperation) from the nominal operation seen by plugins (AllCrudOperation) makes plugin semantics precise.
385-392: LGTM: onQuery now receives the nominal operationPassing nominalOperation to plugins aligns with developer expectations (e.g., findFirst vs findFirstOrThrow) and matches the new typing model.
Summary by CodeRabbit