Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "zenstack-monorepo",
"version": "2.7.1",
"version": "2.7.2",
"description": "",
"scripts": {
"build": "pnpm -r build",
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ plugins {
}

group = "dev.zenstack"
version = "2.7.1"
version = "2.7.2"

repositories {
mavenCentral()
Expand Down
2 changes: 1 addition & 1 deletion packages/ide/jetbrains/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "jetbrains",
"version": "2.7.1",
"version": "2.7.2",
"displayName": "ZenStack JetBrains IDE Plugin",
"description": "ZenStack JetBrains IDE plugin",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/language/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/language",
"version": "2.7.1",
"version": "2.7.2",
"displayName": "ZenStack modeling language compiler",
"description": "ZenStack modeling language compiler",
"homepage": "https://zenstack.dev",
Expand Down
2 changes: 1 addition & 1 deletion packages/misc/redwood/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/redwood",
"displayName": "ZenStack RedwoodJS Integration",
"version": "2.7.1",
"version": "2.7.2",
"description": "CLI and runtime for integrating ZenStack with RedwoodJS projects.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/openapi/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/openapi",
"displayName": "ZenStack Plugin and Runtime for OpenAPI",
"version": "2.7.1",
"version": "2.7.2",
"description": "ZenStack plugin and runtime supporting OpenAPI",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/swr/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/swr",
"displayName": "ZenStack plugin for generating SWR hooks",
"version": "2.7.1",
"version": "2.7.2",
"description": "ZenStack plugin for generating SWR hooks",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/tanstack-query/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/tanstack-query",
"displayName": "ZenStack plugin for generating tanstack-query hooks",
"version": "2.7.1",
"version": "2.7.2",
"description": "ZenStack plugin for generating tanstack-query hooks",
"main": "index.js",
"exports": {
Expand Down
2 changes: 1 addition & 1 deletion packages/plugins/trpc/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/trpc",
"displayName": "ZenStack plugin for tRPC",
"version": "2.7.1",
"version": "2.7.2",
"description": "ZenStack plugin for tRPC",
"main": "index.js",
"repository": {
Expand Down
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@zenstackhq/runtime",
"displayName": "ZenStack Runtime Library",
"version": "2.7.1",
"version": "2.7.2",
"description": "Runtime of ZenStack for both client-side and server-side environments.",
"repository": {
"type": "git",
Expand Down
2 changes: 1 addition & 1 deletion packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"publisher": "zenstack",
"displayName": "ZenStack Language Tools",
"description": "FullStack enhancement for Prisma ORM: seamless integration from database to UI",
"version": "2.7.1",
"version": "2.7.2",
"author": {
"name": "ZenStack Team"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,7 @@ import {
isEnum,
isStringLiteral,
} from '@zenstackhq/language/ast';
import {
getLiteral,
getModelFieldsWithBases,
getModelIdFields,
getModelUniqueFields,
isDelegateModel,
} from '@zenstackhq/sdk';
import { getModelFieldsWithBases, getModelIdFields, getModelUniqueFields, isDelegateModel } from '@zenstackhq/sdk';
import { AstNode, DiagnosticInfo, ValidationAcceptor, getDocument } from 'langium';
import { findUpInheritance } from '../../utils/ast-utils';
import { IssueCodes, SCALAR_TYPES } from '../constants';
Expand Down Expand Up @@ -147,14 +141,13 @@ export default class DataModelValidator implements AstValidator<DataModel> {
}
}

if (!fields && !references) {
return { attr: relAttr, name, fields, references, valid: true };
}

if (!fields || !references) {
if (this.isSelfRelation(field, name)) {
// self relations are partial
// https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations
} else {
if (accept) {
accept('error', `Both "fields" and "references" must be provided`, { node: relAttr });
}
if (accept) {
accept('error', `"fields" and "references" must be provided together`, { node: relAttr });
}
} else {
// validate "fields" and "references" typing consistency
Expand Down Expand Up @@ -203,34 +196,8 @@ export default class DataModelValidator implements AstValidator<DataModel> {
return { attr: relAttr, name, fields, references, valid };
}

private isSelfRelation(field: DataModelField, relationName?: string) {
if (field.type.reference?.ref === field.$container) {
// field directly references back to its type
return true;
}

if (relationName) {
// field's relation points to another type, and that type's opposite relation field
// points back
const oppositeModel = field.type.reference?.ref as DataModel;
if (oppositeModel) {
const oppositeModelFields = getModelFieldsWithBases(oppositeModel);
for (const oppositeField of oppositeModelFields) {
// find the opposite relation with the matching name
const relAttr = oppositeField.attributes.find((a) => a.decl.ref?.name === '@relation');
if (relAttr) {
const relNameExpr = relAttr.args.find((a) => !a.name || a.name === 'name');
const relName = getLiteral<string>(relNameExpr?.value);
if (relName === relationName && oppositeField.type.reference?.ref === field.$container) {
// found an opposite relation field that points back to this field's type
return true;
}
}
}
}
}

return false;
private isSelfRelation(field: DataModelField) {
return field.type.reference?.ref === field.$container;
}

private validateRelationField(contextModel: DataModel, field: DataModelField, accept: ValidationAcceptor) {
Expand Down Expand Up @@ -330,10 +297,10 @@ export default class DataModelValidator implements AstValidator<DataModel> {
// if both the field is array, then it's an implicit many-to-many relation
if (!(field.type.array && oppositeField.type.array)) {
[field, oppositeField].forEach((f) => {
if (!this.isSelfRelation(f, thisRelation.name)) {
if (!this.isSelfRelation(f)) {
accept(
'error',
'Field for one side of relation must carry @relation attribute with both "fields" and "references" fields',
'Field for one side of relation must carry @relation attribute with both "fields" and "references"',
{ node: f }
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -451,7 +451,7 @@ describe('Data Model Validation Tests', () => {
aId String
}
`)
).toMatchObject(errorLike(`Both "fields" and "references" must be provided`));
).toMatchObject(errorLike(`"fields" and "references" must be provided together`));

// one-to-one inconsistent attribute
expect(
Expand Down Expand Up @@ -541,7 +541,7 @@ describe('Data Model Validation Tests', () => {
`)
).toMatchObject(
errorLike(
`Field for one side of relation must carry @relation attribute with both "fields" and "references" fields`
`Field for one side of relation must carry @relation attribute with both "fields" and "references"`
)
);

Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/sdk",
"version": "2.7.1",
"version": "2.7.2",
"description": "ZenStack plugin development SDK",
"main": "index.js",
"scripts": {
Expand Down
2 changes: 1 addition & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/server",
"version": "2.7.1",
"version": "2.7.2",
"displayName": "ZenStack Server-side Adapters",
"description": "ZenStack server-side adapters",
"homepage": "https://zenstack.dev",
Expand Down
5 changes: 3 additions & 2 deletions packages/server/src/api/rest/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1231,15 +1231,16 @@ class RequestHandler extends APIHandlerBase {
}

private makePrismaIdFilter(idFields: FieldInfo[], resourceId: string) {
const decodedId = decodeURIComponent(resourceId);
if (idFields.length === 1) {
return { [idFields[0].name]: this.coerce(idFields[0].type, resourceId) };
return { [idFields[0].name]: this.coerce(idFields[0].type, decodedId) };
} else {
return {
// TODO: support `@@id` with custom name
[idFields.map((idf) => idf.name).join(prismaIdDivider)]: idFields.reduce(
(acc, curr, idx) => ({
...acc,
[curr.name]: this.coerce(curr.type, resourceId.split(this.idDivider)[idx]),
[curr.name]: this.coerce(curr.type, decodedId.split(this.idDivider)[idx]),
}),
{}
),
Expand Down
2 changes: 1 addition & 1 deletion packages/testtools/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@zenstackhq/testtools",
"version": "2.7.1",
"version": "2.7.2",
"description": "ZenStack Test Tools",
"main": "index.js",
"private": true,
Expand Down
Loading