diff --git a/packages/schema/src/language-server/validator/attribute-application-validator.ts b/packages/schema/src/language-server/validator/attribute-application-validator.ts index 0de3a5854..9ec2074be 100644 --- a/packages/schema/src/language-server/validator/attribute-application-validator.ts +++ b/packages/schema/src/language-server/validator/attribute-application-validator.ts @@ -15,7 +15,13 @@ import { isEnum, isReferenceExpr, } from '@zenstackhq/language/ast'; -import { isDataModelFieldReference, isFutureExpr, isRelationshipField, resolved } from '@zenstackhq/sdk'; +import { + isDataModelFieldReference, + isDelegateModel, + isFutureExpr, + isRelationshipField, + resolved, +} from '@zenstackhq/sdk'; import { ValidationAcceptor, streamAst } from 'langium'; import pluralize from 'pluralize'; import { AstValidator } from '../types'; @@ -164,6 +170,31 @@ export default class AttributeApplicationValidator implements AstValidator { + if (!isReferenceExpr(item)) { + accept('error', `Expecting a field reference`, { node: item }); + return; + } + if (!isDataModelField(item.target.ref)) { + accept('error', `Expecting a field reference`, { node: item }); + return; + } + + if (item.target.ref.$container !== attr.$container && isDelegateModel(item.target.ref.$container)) { + accept('error', `Cannot use fields inherited from a polymorphic base model in \`@@unique\``, { + node: item, + }); + } + }); + } else { + accept('error', `Expected an array of field references`, { node: fields }); + } + } + private validatePolicyKinds( kind: string, candidates: string[], diff --git a/tests/regression/tests/issue-1758.test.ts b/tests/regression/tests/issue-1758.test.ts new file mode 100644 index 000000000..f07428e8e --- /dev/null +++ b/tests/regression/tests/issue-1758.test.ts @@ -0,0 +1,29 @@ +import { loadModelWithError } from '@zenstackhq/testtools'; + +describe('issue 1758', () => { + it('regression', async () => { + await expect( + loadModelWithError( + ` + model Organization { + id String @id @default(cuid()) + contents Content[] @relation("OrganizationContents") + } + + model Content { + id String @id @default(cuid()) + contentType String + organization Organization @relation("OrganizationContents", fields: [organizationId], references: [id]) + organizationId String + @@delegate(contentType) + } + + model Store extends Content { + name String + @@unique([organizationId, name]) + } + ` + ) + ).resolves.toContain('Cannot use fields inherited from a polymorphic base model in `@@unique`'); + }); +});