From 9e93985589abc4d22eba433b7927193b4fd405a6 Mon Sep 17 00:00:00 2001 From: Yiming Date: Sat, 7 Sep 2024 09:00:44 -0700 Subject: [PATCH] fix: unintended changes to "backlink" of abstract model's metadata (#1691) --- package.json | 2 +- packages/ide/jetbrains/build.gradle.kts | 2 +- packages/ide/jetbrains/package.json | 2 +- packages/language/package.json | 2 +- packages/misc/redwood/package.json | 2 +- packages/plugins/openapi/package.json | 2 +- packages/plugins/swr/package.json | 2 +- packages/plugins/tanstack-query/package.json | 2 +- packages/plugins/trpc/package.json | 2 +- packages/runtime/package.json | 2 +- packages/schema/package.json | 2 +- packages/sdk/package.json | 2 +- packages/sdk/src/model-meta-generator.ts | 12 ++- packages/server/package.json | 2 +- packages/testtools/package.json | 2 +- .../enhancements/with-policy/abstract.test.ts | 91 +++++++++++++++++++ 16 files changed, 115 insertions(+), 16 deletions(-) create mode 100644 tests/integration/tests/enhancements/with-policy/abstract.test.ts diff --git a/package.json b/package.json index e896bb5f3..a0350c892 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "2.5.0", + "version": "2.5.1", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/ide/jetbrains/build.gradle.kts b/packages/ide/jetbrains/build.gradle.kts index d3a2d9fb2..4de7e00da 100644 --- a/packages/ide/jetbrains/build.gradle.kts +++ b/packages/ide/jetbrains/build.gradle.kts @@ -9,7 +9,7 @@ plugins { } group = "dev.zenstack" -version = "2.5.0" +version = "2.5.1" repositories { mavenCentral() diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json index b48439ad0..996d97e52 100644 --- a/packages/ide/jetbrains/package.json +++ b/packages/ide/jetbrains/package.json @@ -1,6 +1,6 @@ { "name": "jetbrains", - "version": "2.5.0", + "version": "2.5.1", "displayName": "ZenStack JetBrains IDE Plugin", "description": "ZenStack JetBrains IDE plugin", "homepage": "https://zenstack.dev", diff --git a/packages/language/package.json b/packages/language/package.json index 2369cbab9..70391df8f 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "2.5.0", + "version": "2.5.1", "displayName": "ZenStack modeling language compiler", "description": "ZenStack modeling language compiler", "homepage": "https://zenstack.dev", diff --git a/packages/misc/redwood/package.json b/packages/misc/redwood/package.json index 784826caf..48dc879e0 100644 --- a/packages/misc/redwood/package.json +++ b/packages/misc/redwood/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/redwood", "displayName": "ZenStack RedwoodJS Integration", - "version": "2.5.0", + "version": "2.5.1", "description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.", "repository": { "type": "git", diff --git a/packages/plugins/openapi/package.json b/packages/plugins/openapi/package.json index 38f55551b..b8d5a5bdb 100644 --- a/packages/plugins/openapi/package.json +++ b/packages/plugins/openapi/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/openapi", "displayName": "ZenStack Plugin and Runtime for OpenAPI", - "version": "2.5.0", + "version": "2.5.1", "description": "ZenStack plugin and runtime supporting OpenAPI", "main": "index.js", "repository": { diff --git a/packages/plugins/swr/package.json b/packages/plugins/swr/package.json index 7b36c0533..0f2c93588 100644 --- a/packages/plugins/swr/package.json +++ b/packages/plugins/swr/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/swr", "displayName": "ZenStack plugin for generating SWR hooks", - "version": "2.5.0", + "version": "2.5.1", "description": "ZenStack plugin for generating SWR hooks", "main": "index.js", "repository": { diff --git a/packages/plugins/tanstack-query/package.json b/packages/plugins/tanstack-query/package.json index c35644f88..1dd116b90 100644 --- a/packages/plugins/tanstack-query/package.json +++ b/packages/plugins/tanstack-query/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/tanstack-query", "displayName": "ZenStack plugin for generating tanstack-query hooks", - "version": "2.5.0", + "version": "2.5.1", "description": "ZenStack plugin for generating tanstack-query hooks", "main": "index.js", "exports": { diff --git a/packages/plugins/trpc/package.json b/packages/plugins/trpc/package.json index 4f457071f..89053c149 100644 --- a/packages/plugins/trpc/package.json +++ b/packages/plugins/trpc/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/trpc", "displayName": "ZenStack plugin for tRPC", - "version": "2.5.0", + "version": "2.5.1", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index ec9e03ffb..923f76884 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "2.5.0", + "version": "2.5.1", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", diff --git a/packages/schema/package.json b/packages/schema/package.json index 75b71d619..5d71d44a1 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "FullStack enhancement for Prisma ORM: seamless integration from database to UI", - "version": "2.5.0", + "version": "2.5.1", "author": { "name": "ZenStack Team" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 6cd796584..3d1cf97d5 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "2.5.0", + "version": "2.5.1", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { diff --git a/packages/sdk/src/model-meta-generator.ts b/packages/sdk/src/model-meta-generator.ts index d4cf52ab9..469cfa888 100644 --- a/packages/sdk/src/model-meta-generator.ts +++ b/packages/sdk/src/model-meta-generator.ts @@ -29,6 +29,7 @@ import { getRelationField, hasAttribute, isAuthInvocation, + isDelegateModel, isEnumFieldReference, isForeignKeyField, isIdField, @@ -298,8 +299,15 @@ function getBackLink(field: DataModelField) { const relName = getRelationName(field); - // in case of polymorphism, the source model is the base delegate model - const sourceModel = field.$inheritedFrom ?? (field.$container as DataModel); + let sourceModel: DataModel; + if (field.$inheritedFrom && isDelegateModel(field.$inheritedFrom)) { + // field is inherited from a delegate model, use it as the source + sourceModel = field.$inheritedFrom; + } else { + // otherwise use the field's container model as the source + sourceModel = field.$container as DataModel; + } + const targetModel = field.type.reference.ref as DataModel; for (const otherField of targetModel.fields) { diff --git a/packages/server/package.json b/packages/server/package.json index f3e913956..3c2854f46 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "2.5.0", + "version": "2.5.1", "displayName": "ZenStack Server-side Adapters", "description": "ZenStack server-side adapters", "homepage": "https://zenstack.dev", diff --git a/packages/testtools/package.json b/packages/testtools/package.json index aa8562163..6a1b1a039 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "2.5.0", + "version": "2.5.1", "description": "ZenStack Test Tools", "main": "index.js", "private": true, diff --git a/tests/integration/tests/enhancements/with-policy/abstract.test.ts b/tests/integration/tests/enhancements/with-policy/abstract.test.ts new file mode 100644 index 000000000..0987df37d --- /dev/null +++ b/tests/integration/tests/enhancements/with-policy/abstract.test.ts @@ -0,0 +1,91 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('Abstract models', () => { + it('connect test1', async () => { + const { enhance } = await loadSchema( + ` + model User { + id Int @id @default(autoincrement()) + profile Profile? @relation(fields: [profileId], references: [id]) + profileId Int? @unique + + @@allow('create,read', true) + @@allow('update', auth().id == 1) + } + + abstract model BaseProfile { + id Int @id @default(autoincrement()) + user User? + + @@allow('all', true) + } + + model Profile extends BaseProfile { + name String + } + ` + ); + + const db = enhance({ id: 2 }); + const user = await db.user.create({ data: { id: 1 } }); + const profile = await db.profile.create({ data: { id: 1, name: 'John' } }); + await expect( + db.profile.update({ where: { id: 1 }, data: { user: { connect: { id: user.id } } } }) + ).toBeRejectedByPolicy(); + await expect( + db.user.update({ where: { id: 1 }, data: { profile: { connect: { id: profile.id } } } }) + ).toBeRejectedByPolicy(); + + const db1 = enhance({ id: 1 }); + await expect( + db1.profile.update({ where: { id: 1 }, data: { user: { connect: { id: user.id } } } }) + ).toResolveTruthy(); + await expect( + db1.user.update({ where: { id: 1 }, data: { profile: { connect: { id: profile.id } } } }) + ).toResolveTruthy(); + }); + + it('connect test2', async () => { + const { enhance } = await loadSchema( + ` + model User { + id Int @id @default(autoincrement()) + profile Profile? + + @@allow('all', true) + } + + abstract model BaseProfile { + id Int @id @default(autoincrement()) + user User? @relation(fields: [userId], references: [id]) + userId Int? @unique + + @@allow('create,read', true) + @@allow('update', auth().id == 1) + } + + model Profile extends BaseProfile { + name String + } + ` + ); + + const db = enhance({ id: 2 }); + const user = await db.user.create({ data: { id: 1 } }); + const profile = await db.profile.create({ data: { id: 1, name: 'John' } }); + await expect( + db.profile.update({ where: { id: 1 }, data: { user: { connect: { id: user.id } } } }) + ).toBeRejectedByPolicy(); + await expect( + db.user.update({ where: { id: 1 }, data: { profile: { connect: { id: profile.id } } } }) + ).toBeRejectedByPolicy(); + + const db1 = enhance({ id: 1 }); + await expect( + db1.profile.update({ where: { id: 1 }, data: { user: { connect: { id: user.id } } } }) + ).toResolveTruthy(); + await expect( + db1.user.update({ where: { id: 1 }, data: { profile: { connect: { id: profile.id } } } }) + ).toResolveTruthy(); + }); +});