diff --git a/package.json b/package.json index 9b0b3d158..b4d98eba0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "zenstack-monorepo", - "version": "2.1.0", + "version": "2.1.1", "description": "", "scripts": { "build": "pnpm -r build", diff --git a/packages/ide/jetbrains/CHANGELOG.md b/packages/ide/jetbrains/CHANGELOG.md index 008c27d6a..71f088804 100644 --- a/packages/ide/jetbrains/CHANGELOG.md +++ b/packages/ide/jetbrains/CHANGELOG.md @@ -2,6 +2,11 @@ ## [Unreleased] ### Added +- Support using ZModel type names (e.g., `DateTime`) as model field names. +- `auth()` is resolved from all reachable schema files. + +## 2.0.0 +### Added - ZenStack V2 release! ## 1.11.0 diff --git a/packages/ide/jetbrains/build.gradle.kts b/packages/ide/jetbrains/build.gradle.kts index 24b570e37..60efe7461 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.1.0" +version = "2.1.1" repositories { mavenCentral() diff --git a/packages/ide/jetbrains/package.json b/packages/ide/jetbrains/package.json index 296e9da55..de6dcd161 100644 --- a/packages/ide/jetbrains/package.json +++ b/packages/ide/jetbrains/package.json @@ -1,6 +1,6 @@ { "name": "jetbrains", - "version": "2.1.0", + "version": "2.1.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 56121c456..6e7d71fb1 100644 --- a/packages/language/package.json +++ b/packages/language/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/language", - "version": "2.1.0", + "version": "2.1.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 f5d7bdfaa..7f9fba909 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.1.0", + "version": "2.1.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 75103e17f..3cd8ca4fa 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.1.0", + "version": "2.1.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 6a6992553..b7766549d 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.1.0", + "version": "2.1.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 d663d12f1..62881ab68 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.1.0", + "version": "2.1.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 08538d870..e09c1b19f 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.1.0", + "version": "2.1.1", "description": "ZenStack plugin for tRPC", "main": "index.js", "repository": { diff --git a/packages/runtime/package.json b/packages/runtime/package.json index 94d8a587b..9496b42d8 100644 --- a/packages/runtime/package.json +++ b/packages/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@zenstackhq/runtime", "displayName": "ZenStack Runtime Library", - "version": "2.1.0", + "version": "2.1.1", "description": "Runtime of ZenStack for both client-side and server-side environments.", "repository": { "type": "git", diff --git a/packages/runtime/res/enhance.d.ts b/packages/runtime/res/enhance.d.ts index 4ae717bc4..1e79b73be 100644 --- a/packages/runtime/res/enhance.d.ts +++ b/packages/runtime/res/enhance.d.ts @@ -1 +1 @@ -export { enhance } from '.zenstack/enhance'; +export { auth, enhance } from '.zenstack/enhance'; diff --git a/packages/runtime/src/enhancements/policy/policy-utils.ts b/packages/runtime/src/enhancements/policy/policy-utils.ts index b288063c0..1af05b03e 100644 --- a/packages/runtime/src/enhancements/policy/policy-utils.ts +++ b/packages/runtime/src/enhancements/policy/policy-utils.ts @@ -960,13 +960,9 @@ export class PolicyUtil extends QueryUtils { * @returns */ injectReadCheckSelect(model: string, args: any) { - if (this.hasFieldLevelPolicy(model)) { - // recursively inject selection for fields needed for field-level read checks - const readFieldSelect = this.getReadFieldSelect(model); - if (readFieldSelect) { - this.doInjectReadCheckSelect(model, args, { select: readFieldSelect }); - } - } + // we need to recurse into relation fields before injecting the current level, because + // injection into current level can result in relation being selected/included, which + // can then cause infinite recursion when we visit relation later // recurse into relation fields for (const [k, v] of Object.entries(args.select ?? args.include ?? {})) { @@ -975,6 +971,14 @@ export class PolicyUtil extends QueryUtils { this.injectReadCheckSelect(field.type, v); } } + + if (this.hasFieldLevelPolicy(model)) { + // recursively inject selection for fields needed for field-level read checks + const readFieldSelect = this.getReadFieldSelect(model); + if (readFieldSelect) { + this.doInjectReadCheckSelect(model, args, { select: readFieldSelect }); + } + } } private doInjectReadCheckSelect(model: string, args: any, input: any) { diff --git a/packages/schema/package.json b/packages/schema/package.json index 55515cbf5..c6386f328 100644 --- a/packages/schema/package.json +++ b/packages/schema/package.json @@ -3,7 +3,7 @@ "publisher": "zenstack", "displayName": "ZenStack Language Tools", "description": "Build scalable web apps with minimum code by defining authorization and validation rules inside the data schema that closer to the database", - "version": "2.1.0", + "version": "2.1.1", "author": { "name": "ZenStack Team" }, diff --git a/packages/sdk/package.json b/packages/sdk/package.json index e0489d48f..6beb065f4 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/sdk", - "version": "2.1.0", + "version": "2.1.1", "description": "ZenStack plugin development SDK", "main": "index.js", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index 390378154..d2209d51c 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/server", - "version": "2.1.0", + "version": "2.1.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 8cb635d5b..5bb0c3738 100644 --- a/packages/testtools/package.json +++ b/packages/testtools/package.json @@ -1,6 +1,6 @@ { "name": "@zenstackhq/testtools", - "version": "2.1.0", + "version": "2.1.1", "description": "ZenStack Test Tools", "main": "index.js", "private": true, diff --git a/tests/regression/tests/issue-1451.test.ts b/tests/regression/tests/issue-1451.test.ts new file mode 100644 index 000000000..f54a0ca4f --- /dev/null +++ b/tests/regression/tests/issue-1451.test.ts @@ -0,0 +1,58 @@ +import { loadSchema } from '@zenstackhq/testtools'; + +describe('issue 1452', () => { + it('regression', async () => { + const { prisma, enhance } = await loadSchema( + ` + model User { + id String @id + memberships Membership[] + } + + model Space { + id String @id + memberships Membership[] + } + + model Membership { + userId String + user User @relation(fields: [userId], references: [id], onDelete: Cascade) + spaceId String + space Space @relation(fields: [spaceId], references: [id], onDelete: Cascade) + + role String @deny("update", auth() == user) + employeeReference String? @deny("read, update", space.memberships?[auth() == user && !(role in ['owner', 'admin'])]) + + createdAt DateTime @default(now()) + updatedAt DateTime @updatedAt + + @@id([userId, spaceId]) + @@allow('all', true) + } + `, + { logPrismaQuery: true } + ); + + await prisma.user.create({ + data: { id: '1' }, + }); + + await prisma.space.create({ + data: { id: '1' }, + }); + + await prisma.membership.create({ + data: { + user: { connect: { id: '1' } }, + space: { connect: { id: '1' } }, + role: 'foo', + employeeReference: 'xyz', + }, + }); + + const db = enhance({ id: '1' }); + const r = await db.membership.findMany(); + expect(r).toHaveLength(1); + expect(r[0].employeeReference).toBeUndefined(); + }); +});