Skip to content

Commit 890aeeb

Browse files
authored
merge dev to main (release 1.6.1) (#929)
2 parents bdb95ff + 91fe8e7 commit 890aeeb

File tree

29 files changed

+278
-100
lines changed

29 files changed

+278
-100
lines changed

.github/workflows/build-test.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ jobs:
8282
java-version: 17
8383

8484
- name: Setup Gradle
85-
uses: gradle/gradle-build-action@v2
85+
uses: gradle/gradle-build-action@v2.4.2
8686
with:
8787
gradle-home-cache-cleanup: true
8888

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ Check out the [Multi-tenant Todo App](https://zenstack-todo.vercel.app/) for a r
189189
- [Next.js 13 + NextAuth + tRPC](https://github.com/zenstackhq/sample-todo-trpc)
190190
- [Nuxt V3 + TanStack Query](https://github.com/zenstackhq/sample-todo-nuxt)
191191
- [SvelteKit + TanStack Query](https://github.com/zenstackhq/sample-todo-sveltekit)
192+
- [RedwoodJS](https://github.com/zenstackhq/sample-todo-redwood)
192193

193194
### Blog App
194195

package.json

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

packages/ide/jetbrains/build.gradle.kts

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ plugins {
55
}
66

77
group = "dev.zenstack"
8-
version = "1.6.0"
8+
version = "1.6.1"
99

1010
repositories {
1111
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": "1.6.0",
3+
"version": "1.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": "1.6.0",
3+
"version": "1.6.1",
44
"displayName": "ZenStack modeling language compiler",
55
"description": "ZenStack modeling language compiler",
66
"homepage": "https://zenstack.dev",

packages/misc/redwood/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
{
22
"name": "@zenstackhq/redwood",
33
"displayName": "ZenStack RedwoodJS Integration",
4-
"version": "1.6.0",
4+
"version": "1.6.1",
55
"description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.",
66
"repository": {
77
"type": "git",
88
"url": "https://github.com/zenstackhq/zenstack"
99
},
1010
"scripts": {
1111
"clean": "rimraf dist",
12-
"build": "pnpm lint --max-warnings=0 && pnpm clean && tsc",
12+
"build": "pnpm lint --max-warnings=0 && pnpm clean && tsc && pnpm pack dist --pack-destination '../../../.build'",
1313
"watch": "tsc --watch",
1414
"lint": "eslint src --ext ts",
1515
"prepublishOnly": "pnpm build"

packages/plugins/openapi/package.json

+3-3
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.6.0",
4+
"version": "1.6.1",
55
"description": "ZenStack plugin and runtime supporting OpenAPI",
66
"main": "index.js",
77
"repository": {
@@ -32,11 +32,11 @@
3232
"change-case": "^4.1.2",
3333
"lower-case-first": "^2.0.2",
3434
"openapi-types": "^12.1.0",
35-
"semver": "^7.3.8",
35+
"semver": "^7.5.2",
3636
"tiny-invariant": "^1.3.1",
3737
"ts-pattern": "^4.3.0",
3838
"upper-case-first": "^2.0.2",
39-
"yaml": "^2.2.1",
39+
"yaml": "^2.2.2",
4040
"zod": "^3.22.4",
4141
"zod-validation-error": "^1.5.0"
4242
},

packages/plugins/swr/package.json

+2-2
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.6.0",
4+
"version": "1.6.1",
55
"description": "ZenStack plugin for generating SWR hooks",
66
"main": "index.js",
77
"repository": {
@@ -45,7 +45,7 @@
4545
"cross-fetch": "^4.0.0",
4646
"decimal.js": "^10.4.2",
4747
"lower-case-first": "^2.0.2",
48-
"semver": "^7.3.8",
48+
"semver": "^7.5.2",
4949
"ts-morph": "^16.0.0",
5050
"upper-case-first": "^2.0.2"
5151
},

packages/plugins/tanstack-query/package.json

+2-2
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.6.0",
4+
"version": "1.6.1",
55
"description": "ZenStack plugin for generating tanstack-query hooks",
66
"main": "index.js",
77
"exports": {
@@ -87,7 +87,7 @@
8787
"cross-fetch": "^4.0.0",
8888
"decimal.js": "^10.4.2",
8989
"lower-case-first": "^2.0.2",
90-
"semver": "^7.3.8",
90+
"semver": "^7.5.2",
9191
"superjson": "^1.11.0",
9292
"ts-morph": "^16.0.0",
9393
"upper-case-first": "^2.0.2"

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": "1.6.0",
4+
"version": "1.6.1",
55
"description": "ZenStack plugin for tRPC",
66
"main": "index.js",
77
"repository": {

packages/runtime/package.json

+2-2
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.6.0",
4+
"version": "1.6.1",
55
"description": "Runtime of ZenStack for both client-side and server-side environments.",
66
"repository": {
77
"type": "git",
@@ -62,7 +62,7 @@
6262
"deepcopy": "^2.1.0",
6363
"lower-case-first": "^2.0.2",
6464
"pluralize": "^8.0.0",
65-
"semver": "^7.3.8",
65+
"semver": "^7.5.2",
6666
"superjson": "^1.11.0",
6767
"tiny-invariant": "^1.3.1",
6868
"tslib": "^2.4.1",

packages/schema/package.json

+2-2
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.6.0",
6+
"version": "1.6.1",
77
"author": {
88
"name": "ZenStack Team"
99
},
@@ -95,7 +95,7 @@
9595
"pluralize": "^8.0.0",
9696
"pretty-repl": "^4.0.0",
9797
"promisify": "^0.0.3",
98-
"semver": "^7.3.8",
98+
"semver": "^7.5.2",
9999
"sleep-promise": "^9.1.0",
100100
"strip-color": "^0.1.0",
101101
"tiny-invariant": "^1.3.1",

packages/schema/src/language-server/zmodel-linker.ts

+74-18
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,12 @@ import {
5252
} from 'langium';
5353
import { match } from 'ts-pattern';
5454
import { CancellationToken } from 'vscode-jsonrpc';
55-
import { getAllDeclarationsFromImports, isAuthInvocation, getContainingDataModel } from '../utils/ast-utils';
55+
import {
56+
getAllDeclarationsFromImports,
57+
getContainingDataModel,
58+
isAuthInvocation,
59+
isCollectionPredicate,
60+
} from '../utils/ast-utils';
5661
import { mapBuiltinTypeToExpressionType } from './validator/utils';
5762

5863
interface DefaultReference extends Reference {
@@ -94,9 +99,21 @@ export class ZModelLinker extends DefaultLinker {
9499
extraScopes: ScopeProvider[],
95100
onlyFromExtraScopes = false
96101
) {
97-
if (!this.resolveFromScopeProviders(container, property, document, extraScopes) && !onlyFromExtraScopes) {
98-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
99-
const reference: Reference<AstNode> = (container as any)[property];
102+
if (this.resolveFromScopeProviders(container, property, document, extraScopes)) {
103+
return;
104+
}
105+
106+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
107+
const reference: DefaultReference = (container as any)[property];
108+
109+
if (onlyFromExtraScopes) {
110+
// if reference is not resolved from explicit scope providers and automatic linking is not allowed,
111+
// we should explicitly create a linking error
112+
reference._ref = this.createLinkingError({ reference, container, property });
113+
114+
// Add the reference to the document's array of references
115+
document.references.push(reference);
116+
} else {
100117
this.doLink({ reference, container, property }, document);
101118
}
102119
}
@@ -118,6 +135,10 @@ export class ZModelLinker extends DefaultLinker {
118135
if (target) {
119136
reference._ref = target;
120137
reference._nodeDescription = this.descriptions.createDescription(target, target.name, document);
138+
139+
// Add the reference to the document's array of references
140+
document.references.push(reference);
141+
121142
return target;
122143
}
123144
}
@@ -244,6 +265,22 @@ export class ZModelLinker extends DefaultLinker {
244265
node.args.forEach((arg) => this.resolve(arg, document, extraScopes));
245266

246267
if (node.target.ref) {
268+
// if the reference is inside the RHS of a collection predicate, it cannot be resolve to a field
269+
// not belonging to the collection's model type
270+
271+
const collectionPredicateContext = this.getCollectionPredicateContextDataModel(node);
272+
if (
273+
// inside a collection predicate RHS
274+
collectionPredicateContext &&
275+
// current ref expr is resolved to a field
276+
isDataModelField(node.target.ref) &&
277+
// the resolved field doesn't belong to the collection predicate's operand's type
278+
node.target.ref.$container !== collectionPredicateContext
279+
) {
280+
this.unresolvableRefExpr(node);
281+
return;
282+
}
283+
247284
// resolve type
248285
if (node.target.ref.$type === EnumField) {
249286
this.resolveToBuiltinTypeOrDecl(node, node.target.ref.$container);
@@ -253,6 +290,26 @@ export class ZModelLinker extends DefaultLinker {
253290
}
254291
}
255292

293+
private getCollectionPredicateContextDataModel(node: ReferenceExpr) {
294+
let curr: AstNode | undefined = node;
295+
while (curr) {
296+
if (
297+
curr.$container &&
298+
// parent is a collection predicate
299+
isCollectionPredicate(curr.$container) &&
300+
// the collection predicate's LHS is resolved to a DataModel
301+
isDataModel(curr.$container.left.$resolvedType?.decl) &&
302+
// current node is the RHS
303+
curr.$containerProperty === 'right'
304+
) {
305+
// return the resolved type of LHS
306+
return curr.$container.left.$resolvedType?.decl;
307+
}
308+
curr = curr.$container;
309+
}
310+
return undefined;
311+
}
312+
256313
private resolveArray(node: ArrayExpr, document: LangiumDocument<AstNode>, extraScopes: ScopeProvider[]) {
257314
node.items.forEach((item) => this.resolve(item, document, extraScopes));
258315

@@ -414,13 +471,8 @@ export class ZModelLinker extends DefaultLinker {
414471
if (resolved) {
415472
this.resolveToDeclaredType(item, (resolved as DataModelField).type);
416473
} else {
417-
// need to clear linked reference, because it's resolved in default scope by default
418-
const ref = item.target as DefaultReference;
419-
ref._ref = this.createLinkingError({
420-
reference: ref,
421-
container: item,
422-
property: 'target',
423-
});
474+
// mark unresolvable
475+
this.unresolvableRefExpr(item);
424476
}
425477
}
426478
});
@@ -432,13 +484,8 @@ export class ZModelLinker extends DefaultLinker {
432484
if (resolved) {
433485
this.resolveToDeclaredType(node.value, (resolved as DataModelField).type);
434486
} else {
435-
// need to clear linked reference, because it's resolved in default scope by default
436-
const ref = node.value.target as DefaultReference;
437-
ref._ref = this.createLinkingError({
438-
reference: ref,
439-
container: node.value,
440-
property: 'target',
441-
});
487+
// mark unresolvable
488+
this.unresolvableRefExpr(node.value);
442489
}
443490
}
444491
}
@@ -448,6 +495,15 @@ export class ZModelLinker extends DefaultLinker {
448495
node.$resolvedType = node.value.$resolvedType;
449496
}
450497

498+
private unresolvableRefExpr(item: ReferenceExpr) {
499+
const ref = item.target as DefaultReference;
500+
ref._ref = this.createLinkingError({
501+
reference: ref,
502+
container: item,
503+
property: 'target',
504+
});
505+
}
506+
451507
private findAttrParamForArg(arg: AttributeArg): AttributeParam | undefined {
452508
const attr = arg.$container.decl.ref;
453509
if (!attr) {

packages/schema/src/plugins/access-policy/expression-writer.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,9 @@ export class ExpressionWriter {
461461
this.writer.write(`db.${lowerCaseFirst(containingModel.name)}.fields.${expr.target.ref.name}`);
462462
}
463463

464-
private isAuthOrAuthMemberAccess(expr: Expression) {
465-
return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && isAuthInvocation(expr.operand));
464+
private isAuthOrAuthMemberAccess(expr: Expression): boolean {
465+
// recursive check for auth().x.y.z
466+
return isAuthInvocation(expr) || (isMemberAccessExpr(expr) && this.isAuthOrAuthMemberAccess(expr.operand));
466467
}
467468

468469
private writeOperator(operator: ComparisonOperator, fieldAccess: Expression, writeOperand: () => void) {

packages/schema/src/plugins/prisma/prisma-builder.ts

+2-9
Original file line numberDiff line numberDiff line change
@@ -304,17 +304,10 @@ export class FunctionCall {
304304
}
305305

306306
export class FunctionCallArg {
307-
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types, @typescript-eslint/no-explicit-any
308-
constructor(public name: string | undefined, public value: any) {}
307+
constructor(public name: string | undefined, public value: string) {}
309308

310309
toString(): string {
311-
const val =
312-
this.value === null || this.value === undefined
313-
? 'null'
314-
: typeof this.value === 'string'
315-
? `"${this.value}"`
316-
: this.value.toString();
317-
return this.name ? `${this.name}: ${val}` : val;
310+
return this.name ? `${this.name}: ${this.value}` : this.value;
318311
}
319312
}
320313

0 commit comments

Comments
 (0)