Skip to content

Commit 6f30022

Browse files
authored
merge dev to main (v2.6.1) (#1737)
2 parents cb2e423 + bfe6983 commit 6f30022

File tree

17 files changed

+179
-39
lines changed

17 files changed

+179
-39
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zenstack-monorepo",
3-
"version": "2.6.0",
3+
"version": "2.6.1",
44
"description": "",
55
"scripts": {
66
"build": "pnpm -r build",

packages/ide/jetbrains/CHANGELOG.md

+34-11
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,61 @@
11
# Changelog
22

33
## [Unreleased]
4+
5+
### Fixed
6+
7+
- ZModel validation issues when accessing fields defined in a base model from `future().` or `this.`.
8+
9+
## 2.5.0
10+
411
### Added
5-
- A new `path` parameter to the `@@validate` attribute for providing an optional path to the field that caused the error.
12+
13+
- A new `path` parameter to the `@@validate` attribute for providing an optional path to the field that caused the error.
614

715
## 2.4.0
16+
817
### Added
9-
- The `uuid()` function is updated to support the new UUID version feature from Prisma.
1018

11-
## 2.3.0
19+
- The `uuid()` function is updated to support the new UUID version feature from Prisma.
20+
21+
## 2.3.0
22+
1223
### Added
13-
- New `check()` policy rule function.
24+
25+
- New `check()` policy rule function.
1426

1527
### Fixed
16-
- Fixed the issue with formatting schemas containing `Unsupported` type.
28+
29+
- Fixed the issue with formatting schemas containing `Unsupported` type.
1730

1831
## 2.2.0
32+
1933
### Added
20-
- Support comparing fields from different models in mutation policy rules ("create", "update", and "delete).
34+
35+
- Support comparing fields from different models in mutation policy rules ("create", "update", and "delete).
2136

2237
## 2.1.0
38+
2339
### Added
24-
- Support using ZModel type names (e.g., `DateTime`) as model field names.
25-
- `auth()` is resolved from all reachable schema files.
40+
41+
- Support using ZModel type names (e.g., `DateTime`) as model field names.
42+
- `auth()` is resolved from all reachable schema files.
2643

2744
## 2.0.0
45+
2846
### Added
29-
- ZenStack V2 release!
47+
48+
- ZenStack V2 release!
3049

3150
## 1.11.0
51+
3252
### Added
33-
- Added support to complex usage of `@@index` attribute like `@@index([content(ops: raw("gin_trgm_ops"))], type: Gin)`.
53+
54+
- Added support to complex usage of `@@index` attribute like `@@index([content(ops: raw("gin_trgm_ops"))], type: Gin)`.
55+
3456
### Fixed
35-
- Fixed several ZModel validation issues related to model inheritance.
57+
58+
- Fixed several ZModel validation issues related to model inheritance.
3659

3760
## 1.7.0
3861

packages/ide/jetbrains/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ plugins {
99
}
1010

1111
group = "dev.zenstack"
12-
version = "2.6.0"
12+
version = "2.6.1"
1313

1414
repositories {
1515
mavenCentral()

packages/ide/jetbrains/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "jetbrains",
3-
"version": "2.6.0",
3+
"version": "2.6.1",
44
"displayName": "ZenStack JetBrains IDE Plugin",
55
"description": "ZenStack JetBrains IDE plugin",
66
"homepage": "https://zenstack.dev",

packages/language/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/language",
3-
"version": "2.6.0",
3+
"version": "2.6.1",
44
"displayName": "ZenStack modeling language compiler",
55
"description": "ZenStack modeling language compiler",
66
"homepage": "https://zenstack.dev",

packages/misc/redwood/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/redwood",
33
"displayName": "ZenStack RedwoodJS Integration",
4-
"version": "2.6.0",
4+
"version": "2.6.1",
55
"description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.",
66
"repository": {
77
"type": "git",

packages/plugins/openapi/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/openapi",
33
"displayName": "ZenStack Plugin and Runtime for OpenAPI",
4-
"version": "2.6.0",
4+
"version": "2.6.1",
55
"description": "ZenStack plugin and runtime supporting OpenAPI",
66
"main": "index.js",
77
"repository": {

packages/plugins/swr/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/swr",
33
"displayName": "ZenStack plugin for generating SWR hooks",
4-
"version": "2.6.0",
4+
"version": "2.6.1",
55
"description": "ZenStack plugin for generating SWR hooks",
66
"main": "index.js",
77
"repository": {

packages/plugins/tanstack-query/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/tanstack-query",
33
"displayName": "ZenStack plugin for generating tanstack-query hooks",
4-
"version": "2.6.0",
4+
"version": "2.6.1",
55
"description": "ZenStack plugin for generating tanstack-query hooks",
66
"main": "index.js",
77
"exports": {

packages/plugins/trpc/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/trpc",
33
"displayName": "ZenStack plugin for tRPC",
4-
"version": "2.6.0",
4+
"version": "2.6.1",
55
"description": "ZenStack plugin for tRPC",
66
"main": "index.js",
77
"repository": {

packages/runtime/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@zenstackhq/runtime",
33
"displayName": "ZenStack Runtime Library",
4-
"version": "2.6.0",
4+
"version": "2.6.1",
55
"description": "Runtime of ZenStack for both client-side and server-side environments.",
66
"repository": {
77
"type": "git",

packages/runtime/src/enhancements/node/delegate.ts

+24-14
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
233233
}
234234
}
235235

236-
private async buildSelectIncludeHierarchy(model: string, args: any) {
236+
private async buildSelectIncludeHierarchy(model: string, args: any, includeConcreteFields = true) {
237237
args = clone(args);
238238
const selectInclude: any = this.extractSelectInclude(args) || {};
239239

@@ -257,7 +257,10 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
257257

258258
if (!selectInclude.select) {
259259
this.injectBaseIncludeRecursively(model, selectInclude);
260-
await this.injectConcreteIncludeRecursively(model, selectInclude);
260+
261+
if (includeConcreteFields) {
262+
await this.injectConcreteIncludeRecursively(model, selectInclude);
263+
}
261264
}
262265
return selectInclude;
263266
}
@@ -342,19 +345,9 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
342345
for (const subModel of subModels) {
343346
// include sub model relation field
344347
const subRelationName = this.makeAuxRelationName(subModel);
345-
const includePayload: any = {};
346348

347-
if (this.options.processIncludeRelationPayload) {
348-
// use the callback in options to process the include payload, so enhancements
349-
// like 'policy' can do extra work (e.g., inject policy rules)
350-
await this.options.processIncludeRelationPayload(
351-
this.prisma,
352-
subModel.name,
353-
includePayload,
354-
this.options,
355-
this.context
356-
);
357-
}
349+
// create a payload to include the sub model relation
350+
const includePayload = await this.createConcreteRelationIncludePayload(subModel.name);
358351

359352
if (selectInclude.select) {
360353
selectInclude.include = { [subRelationName]: includePayload, ...selectInclude.select };
@@ -366,6 +359,23 @@ export class DelegateProxyHandler extends DefaultPrismaProxyHandler {
366359
}
367360
}
368361

362+
private async createConcreteRelationIncludePayload(model: string) {
363+
let result: any = {};
364+
365+
if (this.options.processIncludeRelationPayload) {
366+
// use the callback in options to process the include payload, so enhancements
367+
// like 'policy' can do extra work (e.g., inject policy rules)
368+
await this.options.processIncludeRelationPayload(this.prisma, model, result, this.options, this.context);
369+
370+
// the callback may directly reference fields from polymorphic bases, we need to fix it
371+
// into a proper hierarchy by moving base field references to the base layer relations
372+
const properHierarchy = await this.buildSelectIncludeHierarchy(model, result, false);
373+
result = { ...result, ...properHierarchy };
374+
}
375+
376+
return result;
377+
}
378+
369379
// #endregion
370380

371381
// #region create

packages/schema/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publisher": "zenstack",
44
"displayName": "ZenStack Language Tools",
55
"description": "FullStack enhancement for Prisma ORM: seamless integration from database to UI",
6-
"version": "2.6.0",
6+
"version": "2.6.1",
77
"author": {
88
"name": "ZenStack Team"
99
},

packages/sdk/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/sdk",
3-
"version": "2.6.0",
3+
"version": "2.6.1",
44
"description": "ZenStack plugin development SDK",
55
"main": "index.js",
66
"scripts": {

packages/server/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/server",
3-
"version": "2.6.0",
3+
"version": "2.6.1",
44
"displayName": "ZenStack Server-side Adapters",
55
"description": "ZenStack server-side adapters",
66
"homepage": "https://zenstack.dev",

packages/testtools/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/testtools",
3-
"version": "2.6.0",
3+
"version": "2.6.1",
44
"description": "ZenStack Test Tools",
55
"main": "index.js",
66
"private": true,
+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
import { loadSchema } from '@zenstackhq/testtools';
2+
describe('issue 1734', () => {
3+
it('regression', async () => {
4+
const { enhance, enhanceRaw, prisma } = await loadSchema(
5+
`
6+
abstract model Base {
7+
id String @id @default(cuid())
8+
createdAt DateTime @default(now())
9+
updatedAt DateTime @updatedAt
10+
}
11+
12+
model Profile extends Base {
13+
displayName String
14+
type String
15+
16+
@@allow('read', true)
17+
@@delegate(type)
18+
}
19+
20+
model User extends Profile {
21+
username String @unique
22+
access Access[]
23+
organization Organization[]
24+
}
25+
26+
model Access extends Base {
27+
user User @relation(fields: [userId], references: [id])
28+
userId String
29+
30+
organization Organization @relation(fields: [organizationId], references: [id])
31+
organizationId String
32+
33+
manage Boolean @default(false)
34+
35+
superadmin Boolean @default(false)
36+
37+
@@unique([userId,organizationId])
38+
}
39+
40+
model Organization extends Profile {
41+
owner User @relation(fields: [ownerId], references: [id])
42+
ownerId String @default(auth().id)
43+
published Boolean @default(false) @allow('read', access?[user == auth()])
44+
access Access[]
45+
}
46+
47+
`
48+
);
49+
const db = enhance();
50+
const rootDb = enhanceRaw(prisma, undefined, {
51+
kinds: ['delegate'],
52+
});
53+
54+
const user = await rootDb.user.create({
55+
data: {
56+
username: 'test',
57+
displayName: 'test',
58+
},
59+
});
60+
61+
const organization = await rootDb.organization.create({
62+
data: {
63+
displayName: 'test',
64+
owner: {
65+
connect: {
66+
id: user.id,
67+
},
68+
},
69+
access: {
70+
create: {
71+
user: {
72+
connect: {
73+
id: user.id,
74+
},
75+
},
76+
manage: true,
77+
superadmin: true,
78+
},
79+
},
80+
},
81+
});
82+
83+
const foundUser = await db.profile.findFirst({
84+
where: {
85+
id: user.id,
86+
},
87+
});
88+
expect(foundUser).toMatchObject(user);
89+
90+
const foundOrg = await db.profile.findFirst({
91+
where: {
92+
id: organization.id,
93+
},
94+
});
95+
// published field not readable
96+
expect(foundOrg).toMatchObject({ id: organization.id, displayName: 'test', type: 'Organization' });
97+
expect(foundOrg.published).toBeUndefined();
98+
99+
const foundOrg1 = await enhance({ id: user.id }).profile.findFirst({
100+
where: {
101+
id: organization.id,
102+
},
103+
});
104+
// published field readable
105+
expect(foundOrg1.published).not.toBeUndefined();
106+
});
107+
});

0 commit comments

Comments
 (0)