@@ -7,13 +7,7 @@ import {
7
7
isEnum ,
8
8
isStringLiteral ,
9
9
} 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' ;
17
11
import { AstNode , DiagnosticInfo , ValidationAcceptor , getDocument } from 'langium' ;
18
12
import { findUpInheritance } from '../../utils/ast-utils' ;
19
13
import { IssueCodes , SCALAR_TYPES } from '../constants' ;
@@ -147,15 +141,15 @@ export default class DataModelValidator implements AstValidator<DataModel> {
147
141
}
148
142
}
149
143
144
+ if ( ! fields && ! references ) {
145
+ return { attr : relAttr , name, fields, references, valid : true } ;
146
+ }
147
+
150
148
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 } ) ;
158
151
}
152
+ // }
159
153
} else {
160
154
// validate "fields" and "references" typing consistency
161
155
if ( fields . length !== references . length ) {
@@ -203,34 +197,8 @@ export default class DataModelValidator implements AstValidator<DataModel> {
203
197
return { attr : relAttr , name, fields, references, valid } ;
204
198
}
205
199
206
- private isSelfRelation ( field : DataModelField , relationName ?: string ) {
207
- if ( field . type . reference ?. ref === field . $container ) {
208
- // field directly references back to its type
209
- return true ;
210
- }
211
-
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
-
233
- return false ;
200
+ private isSelfRelation ( field : DataModelField ) {
201
+ return field . type . reference ?. ref === field . $container ;
234
202
}
235
203
236
204
private validateRelationField ( contextModel : DataModel , field : DataModelField , accept : ValidationAcceptor ) {
@@ -330,10 +298,10 @@ export default class DataModelValidator implements AstValidator<DataModel> {
330
298
// if both the field is array, then it's an implicit many-to-many relation
331
299
if ( ! ( field . type . array && oppositeField . type . array ) ) {
332
300
[ field , oppositeField ] . forEach ( ( f ) => {
333
- if ( ! this . isSelfRelation ( f , thisRelation . name ) ) {
301
+ if ( ! this . isSelfRelation ( f ) ) {
334
302
accept (
335
303
'error' ,
336
- 'Field for one side of relation must carry @relation attribute with both "fields" and "references" fields ' ,
304
+ 'Field for one side of relation must carry @relation attribute with both "fields" and "references"' ,
337
305
{ node : f }
338
306
) ;
339
307
}
0 commit comments