Skip to content

Commit 492dd36

Browse files
committed
fix(cli): regular relation fields are incorrectly recognized as self-relation
1 parent c39f596 commit 492dd36

File tree

2 files changed

+12
-39
lines changed

2 files changed

+12
-39
lines changed

packages/schema/src/language-server/validator/datamodel-validator.ts

Lines changed: 10 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,7 @@ import {
77
isEnum,
88
isStringLiteral,
99
} from '@zenstackhq/language/ast';
10-
import {
11-
getLiteral,
12-
getModelFieldsWithBases,
13-
getModelIdFields,
14-
getModelUniqueFields,
15-
isDelegateModel,
16-
} from '@zenstackhq/sdk';
10+
import { getModelFieldsWithBases, getModelIdFields, getModelUniqueFields, isDelegateModel } from '@zenstackhq/sdk';
1711
import { AstNode, DiagnosticInfo, ValidationAcceptor, getDocument } from 'langium';
1812
import { findUpInheritance } from '../../utils/ast-utils';
1913
import { IssueCodes, SCALAR_TYPES } from '../constants';
@@ -147,15 +141,15 @@ export default class DataModelValidator implements AstValidator<DataModel> {
147141
}
148142
}
149143

144+
if (!fields && !references) {
145+
return { attr: relAttr, name, fields, references, valid: true };
146+
}
147+
150148
if (!fields || !references) {
151-
if (this.isSelfRelation(field, name)) {
152-
// self relations are partial
153-
// https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations
154-
} else {
155-
if (accept) {
156-
accept('error', `Both "fields" and "references" must be provided`, { node: relAttr });
157-
}
149+
if (accept) {
150+
accept('error', `"fields" and "references" must be provided together`, { node: relAttr });
158151
}
152+
// }
159153
} else {
160154
// validate "fields" and "references" typing consistency
161155
if (fields.length !== references.length) {
@@ -203,33 +197,12 @@ export default class DataModelValidator implements AstValidator<DataModel> {
203197
return { attr: relAttr, name, fields, references, valid };
204198
}
205199

206-
private isSelfRelation(field: DataModelField, relationName?: string) {
200+
private isSelfRelation(field: DataModelField, _relationName?: string) {
207201
if (field.type.reference?.ref === field.$container) {
208202
// field directly references back to its type
209203
return true;
210204
}
211205

212-
if (relationName) {
213-
// field's relation points to another type, and that type's opposite relation field
214-
// points back
215-
const oppositeModel = field.type.reference?.ref as DataModel;
216-
if (oppositeModel) {
217-
const oppositeModelFields = getModelFieldsWithBases(oppositeModel);
218-
for (const oppositeField of oppositeModelFields) {
219-
// find the opposite relation with the matching name
220-
const relAttr = oppositeField.attributes.find((a) => a.decl.ref?.name === '@relation');
221-
if (relAttr) {
222-
const relNameExpr = relAttr.args.find((a) => !a.name || a.name === 'name');
223-
const relName = getLiteral<string>(relNameExpr?.value);
224-
if (relName === relationName && oppositeField.type.reference?.ref === field.$container) {
225-
// found an opposite relation field that points back to this field's type
226-
return true;
227-
}
228-
}
229-
}
230-
}
231-
}
232-
233206
return false;
234207
}
235208

@@ -333,7 +306,7 @@ export default class DataModelValidator implements AstValidator<DataModel> {
333306
if (!this.isSelfRelation(f, thisRelation.name)) {
334307
accept(
335308
'error',
336-
'Field for one side of relation must carry @relation attribute with both "fields" and "references" fields',
309+
'Field for one side of relation must carry @relation attribute with both "fields" and "references"',
337310
{ node: f }
338311
);
339312
}

packages/schema/tests/schema/validation/datamodel-validation.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -451,7 +451,7 @@ describe('Data Model Validation Tests', () => {
451451
aId String
452452
}
453453
`)
454-
).toMatchObject(errorLike(`Both "fields" and "references" must be provided`));
454+
).toMatchObject(errorLike(`"fields" and "references" must be provided together`));
455455

456456
// one-to-one inconsistent attribute
457457
expect(
@@ -541,7 +541,7 @@ describe('Data Model Validation Tests', () => {
541541
`)
542542
).toMatchObject(
543543
errorLike(
544-
`Field for one side of relation must carry @relation attribute with both "fields" and "references" fields`
544+
`Field for one side of relation must carry @relation attribute with both "fields" and "references"`
545545
)
546546
);
547547

0 commit comments

Comments
 (0)