From 4417d2026109ad8a821417191d014474aabf2639 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 13 Dec 2025 21:39:57 +0800 Subject: [PATCH 1/3] chore: bump version 3.0.0-beta.30 (#487) Co-authored-by: ymc9 <104139426+ymc9@users.noreply.github.com> --- package.json | 2 +- packages/auth-adapters/better-auth/package.json | 2 +- packages/cli/package.json | 2 +- packages/clients/tanstack-query/package.json | 2 +- packages/common-helpers/package.json | 2 +- packages/config/eslint-config/package.json | 2 +- packages/config/typescript-config/package.json | 2 +- packages/config/vitest-config/package.json | 2 +- packages/create-zenstack/package.json | 2 +- packages/language/package.json | 2 +- packages/orm/package.json | 2 +- packages/plugins/policy/package.json | 2 +- packages/schema/package.json | 2 +- packages/sdk/package.json | 2 +- packages/server/package.json | 2 +- packages/testtools/package.json | 2 +- packages/zod/package.json | 2 +- samples/next.js/package.json | 2 +- samples/orm/package.json | 2 +- tests/e2e/package.json | 2 +- tests/regression/package.json | 2 +- tests/runtimes/bun/package.json | 2 +- tests/runtimes/edge-runtime/package.json | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/package.json b/package.json index c117e8b46..95aa72c77 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-v3", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack", "packageManager": "pnpm@10.23.0", "type": "module", diff --git a/packages/auth-adapters/better-auth/package.json b/packages/auth-adapters/better-auth/package.json index 3bfd0b948..b4018ce1d 100644 --- a/packages/auth-adapters/better-auth/package.json +++ b/packages/auth-adapters/better-auth/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/better-auth", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack Better Auth Adapter. This adapter is modified from better-auth's Prisma adapter.", "type": "module", "scripts": { diff --git a/packages/cli/package.json b/packages/cli/package.json index 622d65b14..3803497d5 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack CLI", "description": "FullStack database toolkit with built-in access control and automatic API generation.", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "type": "module", "author": { "name": "ZenStack Team" diff --git a/packages/clients/tanstack-query/package.json b/packages/clients/tanstack-query/package.json index bbcf25858..2a32050c6 100644 --- a/packages/clients/tanstack-query/package.json +++ b/packages/clients/tanstack-query/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/tanstack-query", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "TanStack Query Client for consuming ZenStack v3's CRUD service", "main": "index.js", "type": "module", diff --git a/packages/common-helpers/package.json b/packages/common-helpers/package.json index 442e243ac..9ac11a006 100644 --- a/packages/common-helpers/package.json +++ b/packages/common-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/common-helpers", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack Common Helpers", "type": "module", "scripts": { diff --git a/packages/config/eslint-config/package.json b/packages/config/eslint-config/package.json index 4c3561078..a126f18b0 100644 --- a/packages/config/eslint-config/package.json +++ b/packages/config/eslint-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/eslint-config", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "type": "module", "private": true, "license": "MIT" diff --git a/packages/config/typescript-config/package.json b/packages/config/typescript-config/package.json index 257e1835d..864cb27da 100644 --- a/packages/config/typescript-config/package.json +++ b/packages/config/typescript-config/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/typescript-config", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "private": true, "license": "MIT" } diff --git a/packages/config/vitest-config/package.json b/packages/config/vitest-config/package.json index 65a2b7fc9..b36ed6f1a 100644 --- a/packages/config/vitest-config/package.json +++ b/packages/config/vitest-config/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/vitest-config", "type": "module", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "private": true, "license": "MIT", "exports": { diff --git a/packages/create-zenstack/package.json b/packages/create-zenstack/package.json index 312bd0e85..11b5f41f1 100644 --- a/packages/create-zenstack/package.json +++ b/packages/create-zenstack/package.json @@ -1,6 +1,6 @@ { "name": "create-zenstack", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "Create a new ZenStack project", "type": "module", "scripts": { diff --git a/packages/language/package.json b/packages/language/package.json index df63be591..5c0fb5a2b 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/language", "description": "ZenStack ZModel language specification", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "license": "MIT", "author": "ZenStack Team", "files": [ diff --git a/packages/orm/package.json b/packages/orm/package.json index 0de776c50..76228f7c4 100644 --- a/packages/orm/package.json +++ b/packages/orm/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/orm", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack ORM", "type": "module", "scripts": { diff --git a/packages/plugins/policy/package.json b/packages/plugins/policy/package.json index 875b5d668..b22a2c54b 100644 --- a/packages/plugins/policy/package.json +++ b/packages/plugins/policy/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/plugin-policy", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack Policy Plugin", "type": "module", "scripts": { diff --git a/packages/schema/package.json b/packages/schema/package.json index 788ea0be0..cbe286472 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/schema", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack Runtime Schema", "type": "module", "scripts": { diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 20657cb41..3483d78ee 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack SDK", "type": "module", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index 8795cf32f..a6b2e1c0b 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack automatic CRUD API handlers and server adapters", "type": "module", "scripts": { diff --git a/packages/testtools/package.json b/packages/testtools/package.json index 83dd5ae82..ff2f50ec0 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "ZenStack Test Tools", "type": "module", "scripts": { diff --git a/packages/zod/package.json b/packages/zod/package.json index 219355485..d18fcc0b3 100644 --- a/packages/zod/package.json +++ b/packages/zod/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/zod", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "", "type": "module", "main": "index.js", diff --git a/samples/next.js/package.json b/samples/next.js/package.json index 977f78a53..f4ebdf964 100644 --- a/samples/next.js/package.json +++ b/samples/next.js/package.json @@ -1,6 +1,6 @@ { "name": "next.js", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "private": true, "scripts": { "generate": "zen generate --lite", diff --git a/samples/orm/package.json b/samples/orm/package.json index 23a793223..426709446 100644 --- a/samples/orm/package.json +++ b/samples/orm/package.json @@ -1,6 +1,6 @@ { "name": "sample-blog", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "description": "", "main": "index.js", "private": true, diff --git a/tests/e2e/package.json b/tests/e2e/package.json index 3cc450543..c6cf00094 100644 --- a/tests/e2e/package.json +++ b/tests/e2e/package.json @@ -1,6 +1,6 @@ { "name": "e2e", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "private": true, "type": "module", "scripts": { diff --git a/tests/regression/package.json b/tests/regression/package.json index 6565b4731..442ee9a21 100644 --- a/tests/regression/package.json +++ b/tests/regression/package.json @@ -1,6 +1,6 @@ { "name": "regression", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "private": true, "type": "module", "scripts": { diff --git a/tests/runtimes/bun/package.json b/tests/runtimes/bun/package.json index b41bdeb5d..90c0e9992 100644 --- a/tests/runtimes/bun/package.json +++ b/tests/runtimes/bun/package.json @@ -1,6 +1,6 @@ { "name": "bun-e2e", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "private": true, "type": "module", "scripts": { diff --git a/tests/runtimes/edge-runtime/package.json b/tests/runtimes/edge-runtime/package.json index 0e449278e..9e1de1473 100644 --- a/tests/runtimes/edge-runtime/package.json +++ b/tests/runtimes/edge-runtime/package.json @@ -1,6 +1,6 @@ { "name": "edge-runtime-e2e", - "version": "3.0.0-beta.29", + "version": "3.0.0-beta.30", "private": true, "type": "module", "scripts": { From eb1a0c222df8682e36bf9fc5b75534a879c670bf Mon Sep 17 00:00:00 2001 From: Yiming Cao Date: Sat, 13 Dec 2025 21:40:12 +0800 Subject: [PATCH 2/3] fix(delegate): exclude uninheritable attributes properly (#488) * fix(delegate): exclude uninheritable attributes properly * fix tests --- packages/language/src/utils.ts | 8 +++++++- packages/sdk/src/prisma/prisma-schema-generator.ts | 13 +------------ tests/e2e/orm/schemas/delegate/schema.ts | 1 + tests/e2e/orm/schemas/delegate/schema.zmodel | 2 ++ .../regression/test/v2-migrated/issue-1243.test.ts | 4 ++-- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/packages/language/src/utils.ts b/packages/language/src/utils.ts index 885a11d68..be6d968f4 100644 --- a/packages/language/src/utils.ts +++ b/packages/language/src/utils.ts @@ -561,7 +561,8 @@ export function getAllAttributes( if (isDataModel(decl) && decl.baseModel) { if (decl.baseModel.ref) { - attributes.push(...getAllAttributes(decl.baseModel.ref, seen)); + const attrs = getAllAttributes(decl.baseModel.ref, seen).filter((attr) => !isNonInheritableAttribute(attr)); + attributes.push(...attrs); } } @@ -569,6 +570,11 @@ export function getAllAttributes( return attributes; } +function isNonInheritableAttribute(attr: DataModelAttribute) { + const attrName = attr.decl.ref?.name ?? attr.decl.$refText; + return ['@@map', '@@unique', '@@index'].includes(attrName); +} + /** * Retrieve the document in which the given AST node is contained. A reference to the document is * usually held by the root node of the AST. diff --git a/packages/sdk/src/prisma/prisma-schema-generator.ts b/packages/sdk/src/prisma/prisma-schema-generator.ts index cb1967981..553658add 100644 --- a/packages/sdk/src/prisma/prisma-schema-generator.ts +++ b/packages/sdk/src/prisma/prisma-schema-generator.ts @@ -196,9 +196,7 @@ export class PrismaSchemaGenerator { } } - const allAttributes = getAllAttributes(decl).filter( - (attr) => this.isPrismaAttribute(attr) && !this.isInheritedMapAttribute(attr, decl), - ); + const allAttributes = getAllAttributes(decl).filter((attr) => this.isPrismaAttribute(attr)); for (const attr of allAttributes) { this.generateContainerAttribute(model, attr); @@ -241,15 +239,6 @@ export class PrismaSchemaGenerator { return getStringLiteral(defaultSchemaField?.value) ?? 'public'; } - private isInheritedMapAttribute(attr: DataModelAttribute, contextModel: DataModel) { - if (attr.$container === contextModel) { - return false; - } - - const attrName = attr.decl.ref?.name ?? attr.decl.$refText; - return attrName === '@@map'; - } - private isPrismaAttribute(attr: DataModelAttribute | DataFieldAttribute) { if (!attr.decl.ref) { return false; diff --git a/tests/e2e/orm/schemas/delegate/schema.ts b/tests/e2e/orm/schemas/delegate/schema.ts index 4ad907ed2..d24bd749e 100644 --- a/tests/e2e/orm/schemas/delegate/schema.ts +++ b/tests/e2e/orm/schemas/delegate/schema.ts @@ -145,6 +145,7 @@ export class SchemaType implements SchemaDef { } }, attributes: [ + { name: "@@index", args: [{ name: "fields", value: ExpressionUtils.array([ExpressionUtils.field("ownerId")]) }] }, { name: "@@delegate", args: [{ name: "discriminator", value: ExpressionUtils.field("assetType") }] } ], idFields: ["id"], diff --git a/tests/e2e/orm/schemas/delegate/schema.zmodel b/tests/e2e/orm/schemas/delegate/schema.zmodel index 9ecc5a830..f97bd8bec 100644 --- a/tests/e2e/orm/schemas/delegate/schema.zmodel +++ b/tests/e2e/orm/schemas/delegate/schema.zmodel @@ -28,6 +28,8 @@ model Asset { comments Comment[] assetType String + @@index([ownerId]) + @@delegate(assetType) } diff --git a/tests/regression/test/v2-migrated/issue-1243.test.ts b/tests/regression/test/v2-migrated/issue-1243.test.ts index 1122f90f5..9d1e6f166 100644 --- a/tests/regression/test/v2-migrated/issue-1243.test.ts +++ b/tests/regression/test/v2-migrated/issue-1243.test.ts @@ -24,7 +24,7 @@ describe('Regression for issue 1243', () => { } `; - await createTestClient(schema); + await createTestClient(schema, { usePrismaPush: true }); }); it('multiple id fields', async () => { @@ -47,6 +47,6 @@ describe('Regression for issue 1243', () => { } `; - await createTestClient(schema); + await createTestClient(schema, { usePrismaPush: true }); }); }); From 081e434581a145b694160891923535e03e66ab9f Mon Sep 17 00:00:00 2001 From: Yiming Cao Date: Sun, 14 Dec 2025 10:23:00 +0800 Subject: [PATCH 3/3] fix(zmodel): rejects delegate models with missing opposite relation (#490) --- .../src/validators/datamodel-validator.ts | 6 +-- packages/language/test/delegate.test.ts | 50 +++++++++++++++++++ 2 files changed, 53 insertions(+), 3 deletions(-) diff --git a/packages/language/src/validators/datamodel-validator.ts b/packages/language/src/validators/datamodel-validator.ts index 40d74dbfd..f3b9f25c8 100644 --- a/packages/language/src/validators/datamodel-validator.ts +++ b/packages/language/src/validators/datamodel-validator.ts @@ -250,7 +250,7 @@ export default class DataModelValidator implements AstValidator { return; } - if (this.isFieldInheritedFromDelegateModel(field)) { + if (this.isFieldInheritedFromDelegateModel(field, contextModel)) { // relation fields inherited from delegate model don't need opposite relation return; } @@ -431,8 +431,8 @@ export default class DataModelValidator implements AstValidator { } // checks if the given field is inherited directly or indirectly from a delegate model - private isFieldInheritedFromDelegateModel(field: DataField) { - return isDelegateModel(field.$container); + private isFieldInheritedFromDelegateModel(field: DataField, contextModel: DataModel) { + return field.$container !== contextModel && isDelegateModel(field.$container); } private validateInherits(model: DataModel, accept: ValidationAcceptor) { diff --git a/packages/language/test/delegate.test.ts b/packages/language/test/delegate.test.ts index 8791275f3..31d61d35d 100644 --- a/packages/language/test/delegate.test.ts +++ b/packages/language/test/delegate.test.ts @@ -114,4 +114,54 @@ describe('Delegate Tests', () => { 'can only be applied once', ); }); + + it('rejects relation missing the opposite side', async () => { + await loadSchemaWithError( + ` + datasource db { + provider = 'sqlite' + url = 'file:./dev.db' + } + + model A { + id Int @id @default(autoincrement()) + b B @relation(fields: [bId], references: [id]) + bId Int + type String + @@delegate(type) + } + + model B { + id Int @id @default(autoincrement()) + } + `, + 'missing an opposite relation', + ); + + await loadSchema( + ` + datasource db { + provider = 'sqlite' + url = 'file:./dev.db' + } + + model A { + id Int @id @default(autoincrement()) + b B @relation(fields: [bId], references: [id]) + bId Int + type String + @@delegate(type) + } + + model B { + id Int @id @default(autoincrement()) + a A[] + } + + model C extends A { + c String + } + `, + ); + }); });