Skip to content

Commit 599444c

Browse files
authored
merge dev to main (v1.11.0) (#1146)
2 parents 336abf4 + f8f214d commit 599444c

File tree

18 files changed

+152
-30
lines changed

18 files changed

+152
-30
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "zenstack-monorepo",
3-
"version": "1.10.3",
3+
"version": "1.11.0",
44
"description": "",
55
"scripts": {
66
"build": "pnpm -r build",

packages/ide/jetbrains/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ plugins {
99
}
1010

1111
group = "dev.zenstack"
12-
version = "1.10.3"
12+
version = "1.11.0"
1313

1414
repositories {
1515
mavenCentral()

packages/ide/jetbrains/package.json

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

packages/language/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/language",
3-
"version": "1.10.3",
3+
"version": "1.11.0",
44
"displayName": "ZenStack modeling language compiler",
55
"description": "ZenStack modeling language compiler",
66
"homepage": "https://zenstack.dev",

packages/misc/redwood/package.json

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

packages/plugins/openapi/package.json

Lines changed: 1 addition & 1 deletion
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": "1.10.3",
4+
"version": "1.11.0",
55
"description": "ZenStack plugin and runtime supporting OpenAPI",
66
"main": "index.js",
77
"repository": {

packages/plugins/swr/package.json

Lines changed: 1 addition & 1 deletion
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": "1.10.3",
4+
"version": "1.11.0",
55
"description": "ZenStack plugin for generating SWR hooks",
66
"main": "index.js",
77
"repository": {

packages/plugins/tanstack-query/package.json

Lines changed: 1 addition & 1 deletion
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": "1.10.3",
4+
"version": "1.11.0",
55
"description": "ZenStack plugin for generating tanstack-query hooks",
66
"main": "index.js",
77
"exports": {

packages/plugins/trpc/package.json

Lines changed: 1 addition & 1 deletion
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": "1.10.3",
4+
"version": "1.11.0",
55
"description": "ZenStack plugin for tRPC",
66
"main": "index.js",
77
"repository": {

packages/runtime/package.json

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

packages/schema/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"publisher": "zenstack",
44
"displayName": "ZenStack Language Tools",
55
"description": "Build scalable web apps with minimum code by defining authorization and validation rules inside the data schema that closer to the database",
6-
"version": "1.10.3",
6+
"version": "1.11.0",
77
"author": {
88
"name": "ZenStack Team"
99
},

packages/schema/src/utils/ast-utils.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import {
1818
import { isFromStdlib } from '@zenstackhq/sdk';
1919
import { AstNode, getDocument, LangiumDocuments, Mutable } from 'langium';
2020
import { URI, Utils } from 'vscode-uri';
21+
import { findNodeModulesFile } from './pkg-utils';
22+
import {isAbsolute} from 'node:path'
2123

2224
export function extractDataModelsWithAllowRules(model: Model): DataModel[] {
2325
return model.declarations.filter(
@@ -94,15 +96,21 @@ export function getDataModelFieldReference(expr: Expression): DataModelField | u
9496
}
9597

9698
export function resolveImportUri(imp: ModelImport): URI | undefined {
97-
if (imp.path === undefined || imp.path.length === 0) {
98-
return undefined;
99+
if (!imp.path) return undefined; // This will return true if imp.path is undefined, null, or an empty string ("").
100+
101+
if (!imp.path.endsWith('.zmodel')) {
102+
imp.path += '.zmodel';
99103
}
100-
const dirUri = Utils.dirname(getDocument(imp).uri);
101-
let grammarPath = imp.path;
102-
if (!grammarPath.endsWith('.zmodel')) {
103-
grammarPath += '.zmodel';
104+
105+
if (
106+
!imp.path.startsWith('.') // Respect relative paths
107+
&& !isAbsolute(imp.path) // Respect Absolute paths
108+
) {
109+
imp.path = findNodeModulesFile(imp.path) ?? imp.path;
104110
}
105-
return Utils.resolvePath(dirUri, grammarPath);
111+
112+
const dirUri = Utils.dirname(getDocument(imp).uri);
113+
return Utils.resolvePath(dirUri, imp.path);
106114
}
107115

108116
export function resolveTransitiveImports(documents: LangiumDocuments, model: Model): Model[] {

packages/schema/src/utils/pkg-utils.ts

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,18 @@ import { execSync } from './exec-utils';
55
export type PackageManagers = 'npm' | 'yarn' | 'pnpm';
66

77
/**
8-
* A type named FindUp that takes a type parameter e which extends boolean.
9-
* If e extends true, it returns a union type of string[] or undefined.
8+
* A type named FindUp that takes a type parameter e which extends boolean.
9+
* If e extends true, it returns a union type of string[] or undefined.
1010
* If e does not extend true, it returns a union type of string or undefined.
1111
*
1212
* @export
1313
* @template e A type parameter that extends boolean
1414
*/
1515
export type FindUp<e extends boolean> = e extends true ? string[] | undefined : string | undefined
1616
/**
17-
* Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path.
18-
* Optionally return a single path or multiple paths.
19-
* If multiple allowed, return all paths found.
17+
* Find and return file paths by searching parent directories based on the given names list and current working directory (cwd) path.
18+
* Optionally return a single path or multiple paths.
19+
* If multiple allowed, return all paths found.
2020
* If no paths are found, return undefined.
2121
*
2222
* @export
@@ -37,6 +37,30 @@ export function findUp<e extends boolean = false>(names: string[], cwd: string =
3737
return findUp(names, up, multiple, result);
3838
}
3939

40+
41+
/**
42+
* Find a Node module/file given its name in a specific directory, with a fallback to the current working directory.
43+
* If the name is empty, return undefined.
44+
* Try to resolve the module/file using require.resolve with the specified directory as the starting point.
45+
* Return the resolved path if successful, otherwise return undefined.
46+
*
47+
* @export
48+
* @param {string} name The name of the module/file to find
49+
* @param {string} [cwd=process.cwd()]
50+
* @returns {*} Finds a specified module or file using require.resolve starting from a specified directory path, or the current working directory if not provided.
51+
*/
52+
export function findNodeModulesFile(name: string, cwd: string = process.cwd()) {
53+
if (!name) return undefined;
54+
try {
55+
// Use require.resolve to find the module/file. The paths option allows specifying the directory to start from.
56+
const resolvedPath = require.resolve(name, { paths: [cwd] })
57+
return resolvedPath
58+
} catch (error) {
59+
// If require.resolve fails to find the module/file, it will throw an error.
60+
return undefined
61+
}
62+
}
63+
4064
function getPackageManager(projectPath = '.'): PackageManagers {
4165
const lockFile = findUp(['yarn.lock', 'pnpm-lock.yaml', 'package-lock.json'], projectPath);
4266

@@ -106,7 +130,7 @@ export function ensurePackage(
106130
}
107131

108132
/**
109-
* A function that searches for the nearest package.json file starting from the provided search path or the current working directory if no search path is provided.
133+
* A function that searches for the nearest package.json file starting from the provided search path or the current working directory if no search path is provided.
110134
* It iterates through the directory structure going one level up at a time until it finds a package.json file. If no package.json file is found, it returns undefined.
111135
* @deprecated Use findUp instead @see findUp
112136
*/

packages/sdk/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/sdk",
3-
"version": "1.10.3",
3+
"version": "1.11.0",
44
"description": "ZenStack plugin development SDK",
55
"main": "index.js",
66
"scripts": {

packages/sdk/src/utils.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -218,11 +218,14 @@ export function isIdField(field: DataModelField) {
218218
return true;
219219
}
220220

221+
// NOTE: we have to use name to match fields because the fields
222+
// may be inherited from an abstract base and have cloned identities
223+
221224
const model = field.$container as DataModel;
222225

223226
// model-level @@id attribute with a list of fields
224227
const modelLevelIds = getModelIdFields(model);
225-
if (modelLevelIds.includes(field)) {
228+
if (modelLevelIds.map((f) => f.name).includes(field.name)) {
226229
return true;
227230
}
228231

@@ -234,12 +237,12 @@ export function isIdField(field: DataModelField) {
234237
// then, the first field with @unique can be used as id
235238
const firstUniqueField = model.fields.find((f) => hasAttribute(f, '@unique'));
236239
if (firstUniqueField) {
237-
return firstUniqueField === field;
240+
return firstUniqueField.name === field.name;
238241
}
239242

240243
// last, the first model level @@unique can be used as id
241244
const modelLevelUnique = getModelUniqueFields(model);
242-
if (modelLevelUnique.includes(field)) {
245+
if (modelLevelUnique.map((f) => f.name).includes(field.name)) {
243246
return true;
244247
}
245248

packages/server/package.json

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

packages/testtools/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@zenstackhq/testtools",
3-
"version": "1.10.3",
3+
"version": "1.11.0",
44
"description": "ZenStack Test Tools",
55
"main": "index.js",
66
"private": true,
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
import { createPostgresDb, dropPostgresDb, loadSchema } from '@zenstackhq/testtools';
2+
3+
describe('Regression for issue 1129', () => {
4+
it('regression', async () => {
5+
let prisma;
6+
const dbUrl = await createPostgresDb('regression-issue-1129');
7+
8+
try {
9+
const r = await loadSchema(
10+
`
11+
model Relation1 {
12+
id String @id @default(cuid())
13+
field1 String
14+
concrete Concrete[]
15+
@@allow('all', true)
16+
}
17+
18+
model Relation2 {
19+
id String @id @default(cuid())
20+
field2 String
21+
concrete Concrete[]
22+
@@allow('all', true)
23+
}
24+
25+
abstract model WithRelation1 {
26+
relation1Id String
27+
relation1 Relation1 @relation(fields: [relation1Id], references: [id])
28+
}
29+
abstract model WithRelation2 {
30+
relation2Id String
31+
relation2 Relation2 @relation(fields: [relation2Id], references: [id])
32+
}
33+
34+
model Concrete extends WithRelation1, WithRelation2 {
35+
concreteField String
36+
@@id([relation1Id, relation2Id])
37+
@@allow('all', true)
38+
}
39+
`,
40+
{ provider: 'postgresql', dbUrl }
41+
);
42+
43+
prisma = r.prisma;
44+
const db = r.enhance();
45+
46+
await db.$transaction(async (tx: any) => {
47+
await tx.relation2.createMany({
48+
data: [
49+
{
50+
id: 'relation2Id1',
51+
field2: 'field2Value1',
52+
},
53+
{
54+
id: 'relation2Id2',
55+
field2: 'field2Value2',
56+
},
57+
],
58+
});
59+
60+
await tx.relation1.create({
61+
data: {
62+
field1: 'field1Value',
63+
concrete: {
64+
createMany: {
65+
data: [
66+
{
67+
concreteField: 'concreteFieldValue1',
68+
relation2Id: 'relation2Id1',
69+
},
70+
{
71+
concreteField: 'concreteFieldValue2',
72+
relation2Id: 'relation2Id2',
73+
},
74+
],
75+
},
76+
},
77+
},
78+
});
79+
});
80+
} finally {
81+
if (prisma) {
82+
await prisma.$disconnect();
83+
}
84+
await dropPostgresDb('regression-issue-1129');
85+
}
86+
});
87+
});

0 commit comments

Comments
 (0)