zenstack 0.5.0 → 0.6.0-pre.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/{LICENSE.md → LICENSE} +0 -0
  2. package/bin/cli +1 -1
  3. package/package.json +18 -13
  4. package/bin/post-install.js +0 -0
  5. package/bundle/asset/logo-256-bg.png +0 -0
  6. package/bundle/asset/logo-dark-256.png +0 -0
  7. package/bundle/asset/logo-light-256.png +0 -0
  8. package/bundle/cli/index.js +0 -6952
  9. package/bundle/extension.js +0 -39
  10. package/bundle/language-server/main.js +0 -6208
  11. package/bundle/res/package.template.json +0 -9
  12. package/bundle/res/prism-zmodel.js +0 -22
  13. package/bundle/res/stdlib.zmodel +0 -218
  14. package/bundle/res/tsconfig.template.json +0 -17
  15. package/src/cli/cli-error.ts +0 -4
  16. package/src/cli/cli-util.ts +0 -214
  17. package/src/cli/index.ts +0 -246
  18. package/src/extension.ts +0 -76
  19. package/src/generator/ast-utils.ts +0 -18
  20. package/src/generator/constants.ts +0 -6
  21. package/src/generator/field-constraint/index.ts +0 -304
  22. package/src/generator/index.ts +0 -86
  23. package/src/generator/prisma/expression-writer.ts +0 -360
  24. package/src/generator/prisma/index.ts +0 -44
  25. package/src/generator/prisma/prisma-builder.ts +0 -370
  26. package/src/generator/prisma/query-guard-generator.ts +0 -249
  27. package/src/generator/prisma/schema-generator.ts +0 -313
  28. package/src/generator/prisma/typescript-expression-transformer.ts +0 -108
  29. package/src/generator/react-hooks/index.ts +0 -273
  30. package/src/generator/service/index.ts +0 -113
  31. package/src/generator/tsc/index.ts +0 -59
  32. package/src/generator/types.ts +0 -20
  33. package/src/global.d.ts +0 -3
  34. package/src/language-server/constants.ts +0 -29
  35. package/src/language-server/generated/ast.ts +0 -643
  36. package/src/language-server/generated/grammar.ts +0 -2492
  37. package/src/language-server/generated/module.ts +0 -24
  38. package/src/language-server/langium-ext.d.ts +0 -22
  39. package/src/language-server/main.ts +0 -13
  40. package/src/language-server/types.ts +0 -25
  41. package/src/language-server/utils.ts +0 -21
  42. package/src/language-server/validator/attribute-validator.ts +0 -11
  43. package/src/language-server/validator/datamodel-validator.ts +0 -426
  44. package/src/language-server/validator/datasource-validator.ts +0 -102
  45. package/src/language-server/validator/enum-validator.ts +0 -14
  46. package/src/language-server/validator/expression-validator.ts +0 -48
  47. package/src/language-server/validator/schema-validator.ts +0 -31
  48. package/src/language-server/validator/utils.ts +0 -158
  49. package/src/language-server/validator/zmodel-validator.ts +0 -91
  50. package/src/language-server/zmodel-linker.ts +0 -453
  51. package/src/language-server/zmodel-module.ts +0 -131
  52. package/src/language-server/zmodel-scope.ts +0 -45
  53. package/src/language-server/zmodel-workspace-manager.ts +0 -23
  54. package/src/language-server/zmodel.langium +0 -207
  55. package/src/res/package.template.json +0 -9
  56. package/src/res/prism-zmodel.js +0 -22
  57. package/src/res/stdlib.zmodel +0 -218
  58. package/src/res/tsconfig.template.json +0 -17
  59. package/src/telemetry.ts +0 -119
  60. package/src/utils/exec-utils.ts +0 -8
  61. package/src/utils/indent-string.ts +0 -9
  62. package/src/utils/pkg-utils.ts +0 -63
@@ -1,24 +0,0 @@
1
- /******************************************************************************
2
- * This file was generated by langium-cli 0.5.0.
3
- * DO NOT EDIT MANUALLY!
4
- ******************************************************************************/
5
-
6
- import { LangiumGeneratedServices, LangiumGeneratedSharedServices, LangiumSharedServices, LangiumServices, LanguageMetaData, Module } from 'langium';
7
- import { ZModelAstReflection } from './ast';
8
- import { ZModelGrammar } from './grammar';
9
-
10
- export const ZModelLanguageMetaData: LanguageMetaData = {
11
- languageId: 'zmodel',
12
- fileExtensions: ['.zmodel'],
13
- caseInsensitive: false
14
- };
15
-
16
- export const ZModelGeneratedSharedModule: Module<LangiumSharedServices, LangiumGeneratedSharedServices> = {
17
- AstReflection: () => new ZModelAstReflection()
18
- };
19
-
20
- export const ZModelGeneratedModule: Module<LangiumServices, LangiumGeneratedServices> = {
21
- Grammar: () => ZModelGrammar(),
22
- LanguageMetaData: () => ZModelLanguageMetaData,
23
- parser: {}
24
- };
@@ -1,22 +0,0 @@
1
- import { ResolvedType } from '@lang/types';
2
- import { AttributeParam } from './generated/ast';
3
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
4
- import { AttributeArg } from './generated/ast';
5
-
6
- declare module 'langium' {
7
- export interface AstNode {
8
- /**
9
- * Resolved type information attached to expressions
10
- */
11
- $resolvedType?: ResolvedType;
12
- }
13
- }
14
-
15
- declare module './generated/ast' {
16
- interface AttributeArg {
17
- /**
18
- * Resolved attribute param declaration
19
- */
20
- $resolvedParam?: AttributeParam;
21
- }
22
- }
@@ -1,13 +0,0 @@
1
- import { startLanguageServer } from 'langium';
2
- import { NodeFileSystem } from 'langium/node';
3
- import { createConnection, ProposedFeatures } from 'vscode-languageserver/node';
4
- import { createZModelServices } from './zmodel-module';
5
-
6
- // Create a connection to the client
7
- const connection = createConnection(ProposedFeatures.all);
8
-
9
- // Inject the shared services and language-specific services
10
- const { shared } = createZModelServices({ connection, ...NodeFileSystem });
11
-
12
- // Start the language server with the shared services
13
- startLanguageServer(shared);
@@ -1,25 +0,0 @@
1
- import { AstNode, ValidationAcceptor } from 'langium';
2
- import { AbstractDeclaration, ExpressionType } from './generated/ast';
3
-
4
- /**
5
- * Shape of type resolution result: an expression type or reference to a declaration
6
- */
7
- export type ResolvedShape = ExpressionType | AbstractDeclaration;
8
-
9
- /**
10
- * Resolved type information (attached to expressions by linker)
11
- */
12
- export type ResolvedType = {
13
- decl?: ResolvedShape;
14
- array?: boolean;
15
- };
16
-
17
- /**
18
- * AST validator contract
19
- */
20
- export interface AstValidator<T extends AstNode> {
21
- /**
22
- * Validates an AST node
23
- */
24
- validate(node: T, accept: ValidationAcceptor): void;
25
- }
@@ -1,21 +0,0 @@
1
- import { AstNode } from 'langium';
2
- import { STD_LIB_MODULE_NAME } from './constants';
3
- import { isModel, Model } from './generated/ast';
4
-
5
- /**
6
- * Gets the toplevel Model containing the given node.
7
- */
8
- export function getContainingModel(node: AstNode | undefined): Model | null {
9
- if (!node) {
10
- return null;
11
- }
12
- return isModel(node) ? node : getContainingModel(node.$container);
13
- }
14
-
15
- /**
16
- * Returns if the given node is declared in stdlib.
17
- */
18
- export function isFromStdlib(node: AstNode) {
19
- const model = getContainingModel(node);
20
- return model && model.$document?.uri.path.endsWith(STD_LIB_MODULE_NAME);
21
- }
@@ -1,11 +0,0 @@
1
- import { Attribute } from '@lang/generated/ast';
2
- import { AstValidator } from '@lang/types';
3
- import { ValidationAcceptor } from 'langium';
4
-
5
- /**
6
- * Validates attribute declarations.
7
- */
8
- export default class AttributeValidator implements AstValidator<Attribute> {
9
- // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
10
- validate(attr: Attribute, accept: ValidationAcceptor): void {}
11
- }
@@ -1,426 +0,0 @@
1
- import { SCALAR_TYPES } from '@lang/constants';
2
- import {
3
- ArrayExpr,
4
- Attribute,
5
- AttributeParam,
6
- DataModel,
7
- DataModelAttribute,
8
- DataModelField,
9
- DataModelFieldAttribute,
10
- isAttribute,
11
- isDataModel,
12
- isDataModelField,
13
- isLiteralExpr,
14
- ReferenceExpr,
15
- } from '@lang/generated/ast';
16
- import { AstValidator } from '@lang/types';
17
- import { ValidationAcceptor } from 'langium';
18
- import {
19
- assignableToAttributeParam,
20
- validateDuplicatedDeclarations,
21
- } from './utils';
22
- import pluralize from 'pluralize';
23
-
24
- /**
25
- * Validates data model declarations.
26
- */
27
- export default class DataModelValidator implements AstValidator<DataModel> {
28
- validate(dm: DataModel, accept: ValidationAcceptor): void {
29
- validateDuplicatedDeclarations(dm.fields, accept);
30
- this.validateFields(dm, accept);
31
- this.validateAttributes(dm, accept);
32
- }
33
-
34
- private validateFields(dm: DataModel, accept: ValidationAcceptor) {
35
- const idFields = dm.fields.filter((f) =>
36
- f.attributes.find((attr) => attr.decl.ref?.name === '@id')
37
- );
38
- if (idFields.length === 0) {
39
- accept('error', 'Model must include a field with @id attribute', {
40
- node: dm,
41
- });
42
- } else if (idFields.length > 1) {
43
- accept(
44
- 'error',
45
- 'Model can include at most one field with @id attribute',
46
- {
47
- node: dm,
48
- }
49
- );
50
- } else {
51
- if (idFields[0].type.optional) {
52
- accept(
53
- 'error',
54
- 'Field with @id attribute must not be optional',
55
- { node: idFields[0] }
56
- );
57
- }
58
-
59
- if (
60
- idFields[0].type.array ||
61
- !idFields[0].type.type ||
62
- !SCALAR_TYPES.includes(idFields[0].type.type)
63
- ) {
64
- accept(
65
- 'error',
66
- 'Field with @id attribute must be of scalar type',
67
- { node: idFields[0] }
68
- );
69
- }
70
- }
71
-
72
- dm.fields.forEach((field) => this.validateField(field, accept));
73
- }
74
-
75
- private validateField(
76
- field: DataModelField,
77
- accept: ValidationAcceptor
78
- ): void {
79
- if (field.type.array && field.type.optional) {
80
- accept(
81
- 'error',
82
- 'Optional lists are not supported. Use either `Type[]` or `Type?`',
83
- { node: field.type }
84
- );
85
- }
86
-
87
- field.attributes.forEach((attr) =>
88
- this.validateAttributeApplication(attr, accept)
89
- );
90
-
91
- if (isDataModel(field.type.reference?.ref)) {
92
- this.validateRelationField(field, accept);
93
- }
94
- }
95
-
96
- private validateAttributes(dm: DataModel, accept: ValidationAcceptor) {
97
- dm.attributes.forEach((attr) => {
98
- this.validateAttributeApplication(attr, accept);
99
- });
100
- }
101
-
102
- private validateAttributeApplication(
103
- attr: DataModelAttribute | DataModelFieldAttribute,
104
- accept: ValidationAcceptor
105
- ) {
106
- const decl = attr.decl.ref;
107
- if (!decl) {
108
- return;
109
- }
110
-
111
- const targetDecl = attr.$container;
112
- if (decl.name === '@@@targetField' && !isAttribute(targetDecl)) {
113
- accept(
114
- 'error',
115
- `attribute "${decl.name}" can only be used on attribute declarations`,
116
- { node: attr }
117
- );
118
- return;
119
- }
120
-
121
- if (
122
- isDataModelField(targetDecl) &&
123
- !this.isValidAttributeTarget(decl, targetDecl)
124
- ) {
125
- accept(
126
- 'error',
127
- `attribute "${decl.name}" cannot be used on this type of field`,
128
- { node: attr }
129
- );
130
- }
131
-
132
- const filledParams = new Set<AttributeParam>();
133
-
134
- for (const arg of attr.args) {
135
- let paramDecl: AttributeParam | undefined;
136
- if (!arg.name) {
137
- paramDecl = decl.params.find(
138
- (p) => p.default && !filledParams.has(p)
139
- );
140
- if (!paramDecl) {
141
- accept('error', `Unexpected unnamed argument`, {
142
- node: arg,
143
- });
144
- return false;
145
- }
146
- } else {
147
- paramDecl = decl.params.find((p) => p.name === arg.name);
148
- if (!paramDecl) {
149
- accept(
150
- 'error',
151
- `Attribute "${decl.name}" doesn't have a parameter named "${arg.name}"`,
152
- {
153
- node: arg,
154
- }
155
- );
156
- return false;
157
- }
158
- }
159
-
160
- if (!assignableToAttributeParam(arg, paramDecl, attr)) {
161
- accept('error', `Value is not assignable to parameter`, {
162
- node: arg,
163
- });
164
- return false;
165
- }
166
-
167
- if (filledParams.has(paramDecl)) {
168
- accept(
169
- 'error',
170
- `Parameter "${paramDecl.name}" is already provided`,
171
- { node: arg }
172
- );
173
- return false;
174
- }
175
- filledParams.add(paramDecl);
176
- arg.$resolvedParam = paramDecl;
177
- }
178
-
179
- const missingParams = decl.params.filter(
180
- (p) => !p.type.optional && !filledParams.has(p)
181
- );
182
- if (missingParams.length > 0) {
183
- accept(
184
- 'error',
185
- `Required ${pluralize(
186
- 'parameter',
187
- missingParams.length
188
- )} not provided: ${missingParams
189
- .map((p) => p.name)
190
- .join(', ')}`,
191
- { node: attr }
192
- );
193
- return false;
194
- }
195
-
196
- return true;
197
- }
198
-
199
- private isValidAttributeTarget(
200
- attrDecl: Attribute,
201
- targetDecl: DataModelField
202
- ) {
203
- const targetField = attrDecl.attributes.find(
204
- (attr) => attr.decl.ref?.name === '@@@targetField'
205
- );
206
- if (!targetField) {
207
- // no field type constraint
208
- return true;
209
- }
210
-
211
- const fieldTypes = (targetField.args[0].value as ArrayExpr).items.map(
212
- (item) => (item as ReferenceExpr).target.ref?.name
213
- );
214
-
215
- let allowed = false;
216
- for (const allowedType of fieldTypes) {
217
- switch (allowedType) {
218
- case 'StringField':
219
- allowed = allowed || targetDecl.type.type === 'String';
220
- break;
221
- case 'IntField':
222
- allowed = allowed || targetDecl.type.type === 'Int';
223
- break;
224
- case 'FloatField':
225
- allowed = allowed || targetDecl.type.type === 'Float';
226
- break;
227
- case 'DecimalField':
228
- allowed = allowed || targetDecl.type.type === 'Decimal';
229
- break;
230
- case 'BooleanField':
231
- allowed = allowed || targetDecl.type.type === 'Boolean';
232
- break;
233
- case 'DateTimeField':
234
- allowed = allowed || targetDecl.type.type === 'DateTime';
235
- break;
236
- case 'JsonField':
237
- allowed = allowed || targetDecl.type.type === 'Json';
238
- break;
239
- case 'BytesField':
240
- allowed = allowed || targetDecl.type.type === 'Bytes';
241
- break;
242
- case 'ModelField':
243
- allowed =
244
- allowed || isDataModel(targetDecl.type.reference?.ref);
245
- break;
246
- default:
247
- break;
248
- }
249
- if (allowed) {
250
- break;
251
- }
252
- }
253
-
254
- return allowed;
255
- }
256
-
257
- private parseRelation(field: DataModelField, accept?: ValidationAcceptor) {
258
- const relAttr = field.attributes.find(
259
- (attr) => attr.decl.ref?.name === '@relation'
260
- );
261
-
262
- let name: string | undefined;
263
- let fields: ReferenceExpr[] | undefined;
264
- let references: ReferenceExpr[] | undefined;
265
- let valid = true;
266
-
267
- if (!relAttr) {
268
- return { attr: relAttr, name, fields, references, valid: true };
269
- }
270
-
271
- for (const arg of relAttr.args) {
272
- if (!arg.name || arg.name === 'name') {
273
- if (isLiteralExpr(arg.value)) {
274
- name = arg.value.value as string;
275
- }
276
- } else if (arg.name === 'fields') {
277
- fields = (arg.value as ArrayExpr).items as ReferenceExpr[];
278
- if (fields.length === 0) {
279
- if (accept) {
280
- accept('error', `"fields" value cannot be emtpy`, {
281
- node: arg,
282
- });
283
- }
284
- valid = false;
285
- }
286
- } else if (arg.name === 'references') {
287
- references = (arg.value as ArrayExpr).items as ReferenceExpr[];
288
- if (references.length === 0) {
289
- if (accept) {
290
- accept('error', `"references" value cannot be emtpy`, {
291
- node: arg,
292
- });
293
- }
294
- valid = false;
295
- }
296
- }
297
- }
298
-
299
- return { attr: relAttr, name, fields, references, valid };
300
- }
301
-
302
- private validateRelationField(
303
- field: DataModelField,
304
- accept: ValidationAcceptor
305
- ) {
306
- const thisRelation = this.parseRelation(field, accept);
307
- if (!thisRelation.valid) {
308
- return;
309
- }
310
-
311
- // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
312
- const oppositeModel = field.type.reference!.ref! as DataModel;
313
-
314
- let oppositeFields = oppositeModel.fields.filter(
315
- (f) => f.type.reference?.ref === field.$container
316
- );
317
- oppositeFields = oppositeFields.filter((f) => {
318
- const fieldRel = this.parseRelation(f);
319
- return fieldRel.valid && fieldRel.name === thisRelation.name;
320
- });
321
-
322
- if (oppositeFields.length === 0) {
323
- accept(
324
- 'error',
325
- `The relation field "${field.name}" on model "${field.$container.name}" is missing an opposite relation field on model "${oppositeModel.name}"`,
326
- { node: field }
327
- );
328
- return;
329
- } else if (oppositeFields.length > 1) {
330
- oppositeFields.forEach((f) =>
331
- accept(
332
- 'error',
333
- `Fields ${oppositeFields
334
- .map((f) => '"' + f.name + '"')
335
- .join(', ')} on model "${
336
- oppositeModel.name
337
- }" refer to the same relation to model "${
338
- field.$container.name
339
- }"`,
340
- { node: f }
341
- )
342
- );
343
- return;
344
- }
345
-
346
- const oppositeField = oppositeFields[0];
347
- const oppositeRelation = this.parseRelation(oppositeField);
348
-
349
- let relationOwner: DataModelField;
350
-
351
- if (thisRelation?.references?.length && thisRelation.fields?.length) {
352
- if (oppositeRelation?.references || oppositeRelation?.fields) {
353
- accept(
354
- 'error',
355
- '"fields" and "references" must be provided only on one side of relation field',
356
- { node: oppositeField }
357
- );
358
- return;
359
- } else {
360
- relationOwner = oppositeField;
361
- }
362
- } else if (
363
- oppositeRelation?.references?.length &&
364
- oppositeRelation.fields?.length
365
- ) {
366
- if (thisRelation?.references || thisRelation?.fields) {
367
- accept(
368
- 'error',
369
- '"fields" and "references" must be provided only on one side of relation field',
370
- { node: field }
371
- );
372
- return;
373
- } else {
374
- relationOwner = field;
375
- }
376
- } else {
377
- [field, oppositeField].forEach((f) =>
378
- accept(
379
- 'error',
380
- 'Field for one side of relation must carry @relation attribute with both "fields" and "references" fields',
381
- { node: f }
382
- )
383
- );
384
- return;
385
- }
386
-
387
- if (!relationOwner.type.array && !relationOwner.type.optional) {
388
- accept('error', 'Relation field needs to be list or optional', {
389
- node: relationOwner,
390
- });
391
- return;
392
- }
393
-
394
- if (relationOwner !== field && !relationOwner.type.array) {
395
- // one-to-one relation requires defining side's reference field to be @unique
396
- // e.g.:
397
- // model User {
398
- // id String @id @default(cuid())
399
- // data UserData?
400
- // }
401
- // model UserData {
402
- // id String @id @default(cuid())
403
- // user User @relation(fields: [userId], references: [id])
404
- // userId String
405
- // }
406
- //
407
- // UserData.userId field needs to be @unique
408
-
409
- thisRelation.fields?.forEach((ref) => {
410
- const refField = ref.target.ref as DataModelField;
411
- if (
412
- refField &&
413
- !refField.attributes.find(
414
- (a) => a.decl.ref?.name === '@unique'
415
- )
416
- ) {
417
- accept(
418
- 'error',
419
- `Field "${refField.name}" is part of a one-to-one relation and must be marked as @unique`,
420
- { node: refField }
421
- );
422
- }
423
- });
424
- }
425
- }
426
- }
@@ -1,102 +0,0 @@
1
- import { DataSource, isInvocationExpr } from '@lang/generated/ast';
2
- import { AstValidator } from '@lang/types';
3
- import { ValidationAcceptor } from 'langium';
4
- import { getStringLiteral, validateDuplicatedDeclarations } from './utils';
5
- import { SUPPORTED_PROVIDERS } from '../constants';
6
-
7
- const supportedFields = [
8
- 'provider',
9
- 'url',
10
- 'shadowDatabaseUrl',
11
- 'relationMode',
12
- ];
13
-
14
- /**
15
- * Validates data source declarations.
16
- */
17
- export default class DataSourceValidator implements AstValidator<DataSource> {
18
- validate(ds: DataSource, accept: ValidationAcceptor): void {
19
- validateDuplicatedDeclarations(ds.fields, accept);
20
- this.validateFields(ds, accept);
21
- this.validateProvider(ds, accept);
22
- this.validateUrl(ds, accept);
23
- this.validateRelationMode(ds, accept);
24
- }
25
-
26
- private validateFields(ds: DataSource, accept: ValidationAcceptor) {
27
- ds.fields.forEach((f) => {
28
- if (!supportedFields.includes(f.name)) {
29
- accept('error', `Unexpected field "${f.name}"`, { node: f });
30
- }
31
- });
32
- }
33
-
34
- private validateProvider(ds: DataSource, accept: ValidationAcceptor) {
35
- const provider = ds.fields.find((f) => f.name === 'provider');
36
- if (!provider) {
37
- accept('error', 'datasource must include a "provider" field', {
38
- node: ds,
39
- });
40
- return;
41
- }
42
-
43
- const value = getStringLiteral(provider.value);
44
- if (!value) {
45
- accept('error', '"provider" must be set to a string literal', {
46
- node: provider.value,
47
- });
48
- } else if (!SUPPORTED_PROVIDERS.includes(value)) {
49
- accept(
50
- 'error',
51
- `Provider "${value}" is not supported. Choose from ${SUPPORTED_PROVIDERS.map(
52
- (p) => '"' + p + '"'
53
- ).join(' | ')}.`,
54
- { node: provider.value }
55
- );
56
- }
57
- }
58
-
59
- private validateUrl(ds: DataSource, accept: ValidationAcceptor) {
60
- const url = ds.fields.find((f) => f.name === 'url');
61
- if (!url) {
62
- accept('error', 'datasource must include a "url" field', {
63
- node: ds,
64
- });
65
- }
66
-
67
- for (const fieldName of ['url', 'shadowDatabaseUrl']) {
68
- const field = ds.fields.find((f) => f.name === fieldName);
69
- if (!field) {
70
- continue;
71
- }
72
- const value = getStringLiteral(field.value);
73
- if (
74
- !value &&
75
- !(
76
- isInvocationExpr(field.value) &&
77
- field.value.function.ref?.name === 'env'
78
- )
79
- ) {
80
- accept(
81
- 'error',
82
- `"${fieldName}" must be set to a string literal or an invocation of "env" function`,
83
- { node: field.value }
84
- );
85
- }
86
- }
87
- }
88
-
89
- private validateRelationMode(ds: DataSource, accept: ValidationAcceptor) {
90
- const field = ds.fields.find((f) => f.name === 'relationMode');
91
- if (field) {
92
- const val = getStringLiteral(field.value);
93
- if (!val || !['foreignKeys', 'prisma'].includes(val)) {
94
- accept(
95
- 'error',
96
- '"relationMode" must be set to "foreignKeys" or "prisma"',
97
- { node: field.value }
98
- );
99
- }
100
- }
101
- }
102
- }
@@ -1,14 +0,0 @@
1
- import { Enum } from '@lang/generated/ast';
2
- import { AstValidator } from '@lang/types';
3
- import { ValidationAcceptor } from 'langium';
4
- import { validateDuplicatedDeclarations } from './utils';
5
-
6
- /**
7
- * Validates enum declarations.
8
- */
9
- export default class EnumValidator implements AstValidator<Enum> {
10
- // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
11
- validate(_enum: Enum, accept: ValidationAcceptor) {
12
- validateDuplicatedDeclarations(_enum.fields, accept);
13
- }
14
- }