zenstack 1.0.0 → 1.0.16
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.
- package/LICENSE +1 -1
- package/README.md +126 -1
- package/bin/cli +3 -0
- package/bin/post-install.js +24 -0
- package/cli/cli-error.d.ts +5 -0
- package/cli/cli-error.js +10 -0
- package/cli/cli-error.js.map +1 -0
- package/cli/cli-util.d.ts +18 -0
- package/cli/cli-util.js +143 -0
- package/cli/cli-util.js.map +1 -0
- package/cli/index.d.ts +15 -0
- package/cli/index.js +121 -0
- package/cli/index.js.map +1 -0
- package/cli/plugin-runner.d.ts +14 -0
- package/cli/plugin-runner.js +145 -0
- package/cli/plugin-runner.js.map +1 -0
- package/constants.d.ts +1 -0
- package/constants.js +6 -0
- package/constants.js.map +1 -0
- package/language-server/constants.d.ts +15 -0
- package/language-server/constants.js +20 -0
- package/language-server/constants.js.map +1 -0
- package/language-server/main.d.ts +1 -0
- package/language-server/main.js +13 -0
- package/language-server/main.js.map +1 -0
- package/language-server/types.d.ts +10 -0
- package/language-server/types.js +3 -0
- package/language-server/types.js.map +1 -0
- package/language-server/utils.d.ts +18 -0
- package/language-server/utils.js +58 -0
- package/language-server/utils.js.map +1 -0
- package/language-server/validator/attribute-validator.d.ts +9 -0
- package/language-server/validator/attribute-validator.js +11 -0
- package/language-server/validator/attribute-validator.js.map +1 -0
- package/language-server/validator/datamodel-validator.d.ts +15 -0
- package/language-server/validator/datamodel-validator.js +278 -0
- package/language-server/validator/datamodel-validator.js.map +1 -0
- package/language-server/validator/datasource-validator.d.ts +12 -0
- package/language-server/validator/datasource-validator.js +66 -0
- package/language-server/validator/datasource-validator.js.map +1 -0
- package/language-server/validator/enum-validator.d.ts +11 -0
- package/language-server/validator/enum-validator.js +28 -0
- package/language-server/validator/enum-validator.js.map +1 -0
- package/language-server/validator/expression-validator.d.ts +10 -0
- package/language-server/validator/expression-validator.js +30 -0
- package/language-server/validator/expression-validator.js.map +1 -0
- package/language-server/validator/schema-validator.d.ts +10 -0
- package/language-server/validator/schema-validator.js +28 -0
- package/language-server/validator/schema-validator.js.map +1 -0
- package/language-server/validator/utils.d.ts +25 -0
- package/language-server/validator/utils.js +257 -0
- package/language-server/validator/utils.js.map +1 -0
- package/language-server/validator/zmodel-validator.d.ts +21 -0
- package/language-server/validator/zmodel-validator.js +69 -0
- package/language-server/validator/zmodel-validator.js.map +1 -0
- package/language-server/zmodel-code-action.d.ts +14 -0
- package/language-server/zmodel-code-action.js +93 -0
- package/language-server/zmodel-code-action.js.map +1 -0
- package/language-server/zmodel-formatter.d.ts +9 -0
- package/language-server/zmodel-formatter.js +76 -0
- package/language-server/zmodel-formatter.js.map +1 -0
- package/language-server/zmodel-linker.d.ts +29 -0
- package/language-server/zmodel-linker.js +366 -0
- package/language-server/zmodel-linker.js.map +1 -0
- package/language-server/zmodel-module.d.ts +41 -0
- package/language-server/zmodel-module.js +80 -0
- package/language-server/zmodel-module.js.map +1 -0
- package/language-server/zmodel-scope.d.ts +10 -0
- package/language-server/zmodel-scope.js +44 -0
- package/language-server/zmodel-scope.js.map +1 -0
- package/language-server/zmodel-workspace-manager.d.ts +8 -0
- package/language-server/zmodel-workspace-manager.js +37 -0
- package/language-server/zmodel-workspace-manager.js.map +1 -0
- package/package.json +133 -8
- package/plugins/access-policy/expression-writer.d.ts +39 -0
- package/plugins/access-policy/expression-writer.js +361 -0
- package/plugins/access-policy/expression-writer.js.map +1 -0
- package/plugins/access-policy/index.d.ts +4 -0
- package/plugins/access-policy/index.js +24 -0
- package/plugins/access-policy/index.js.map +1 -0
- package/plugins/access-policy/policy-guard-generator.d.ts +15 -0
- package/plugins/access-policy/policy-guard-generator.js +349 -0
- package/plugins/access-policy/policy-guard-generator.js.map +1 -0
- package/plugins/access-policy/typescript-expression-transformer.d.ts +26 -0
- package/plugins/access-policy/typescript-expression-transformer.js +111 -0
- package/plugins/access-policy/typescript-expression-transformer.js.map +1 -0
- package/plugins/access-policy/utils.d.ts +5 -0
- package/plugins/access-policy/utils.js +14 -0
- package/plugins/access-policy/utils.js.map +1 -0
- package/plugins/access-policy/zod-schema-generator.d.ts +12 -0
- package/plugins/access-policy/zod-schema-generator.js +158 -0
- package/plugins/access-policy/zod-schema-generator.js.map +1 -0
- package/plugins/model-meta/index.d.ts +4 -0
- package/plugins/model-meta/index.js +168 -0
- package/plugins/model-meta/index.js.map +1 -0
- package/plugins/plugin-utils.d.ts +16 -0
- package/plugins/plugin-utils.js +54 -0
- package/plugins/plugin-utils.js.map +1 -0
- package/plugins/prisma/indent-string.d.ts +4 -0
- package/plugins/prisma/indent-string.js +12 -0
- package/plugins/prisma/indent-string.js.map +1 -0
- package/plugins/prisma/index.d.ts +4 -0
- package/plugins/prisma/index.js +24 -0
- package/plugins/prisma/index.js.map +1 -0
- package/plugins/prisma/prisma-builder.d.ts +152 -0
- package/plugins/prisma/prisma-builder.js +363 -0
- package/plugins/prisma/prisma-builder.js.map +1 -0
- package/plugins/prisma/schema-generator.d.ts +25 -0
- package/plugins/prisma/schema-generator.js +292 -0
- package/plugins/prisma/schema-generator.js.map +1 -0
- package/plugins/prisma/zmodel-code-generator.d.ts +28 -0
- package/plugins/prisma/zmodel-code-generator.js +114 -0
- package/plugins/prisma/zmodel-code-generator.js.map +1 -0
- package/res/prism-zmodel.js +20 -0
- package/res/starter.zmodel +51 -0
- package/res/stdlib.zmodel +346 -0
- package/telemetry.d.ts +20 -0
- package/telemetry.js +119 -0
- package/telemetry.js.map +1 -0
- package/types.d.ts +12 -0
- package/types.js +3 -0
- package/types.js.map +1 -0
- package/utils/ast-utils.d.ts +16 -0
- package/utils/ast-utils.js +85 -0
- package/utils/ast-utils.js.map +1 -0
- package/utils/exec-utils.d.ts +6 -0
- package/utils/exec-utils.js +13 -0
- package/utils/exec-utils.js.map +1 -0
- package/utils/pkg-utils.d.ts +3 -0
- package/utils/pkg-utils.js +46 -0
- package/utils/pkg-utils.js.map +1 -0
- package/utils/version-utils.d.ts +1 -0
- package/utils/version-utils.js +14 -0
- package/utils/version-utils.js.map +1 -0
- package/.vscode/extensions.json +0 -7
- package/.vscode/launch.json +0 -49
- package/.vscode/settings.json +0 -4
- package/packages/internal/jest.config.ts +0 -32
- package/packages/internal/package.json +0 -42
- package/packages/internal/src/constants.ts +0 -1
- package/packages/internal/src/handler/data/guard-utils.ts +0 -7
- package/packages/internal/src/handler/data/handler.ts +0 -415
- package/packages/internal/src/handler/data/query-processor.ts +0 -504
- package/packages/internal/src/handler/index.ts +0 -1
- package/packages/internal/src/handler/types.ts +0 -20
- package/packages/internal/src/index.ts +0 -3
- package/packages/internal/src/request-handler.ts +0 -27
- package/packages/internal/src/request.ts +0 -101
- package/packages/internal/src/types.ts +0 -40
- package/packages/internal/tests/query-processor.test.ts +0 -172
- package/packages/internal/tsconfig.json +0 -21
- package/packages/runtime/auth.d.ts +0 -1
- package/packages/runtime/auth.js +0 -3
- package/packages/runtime/hooks.d.ts +0 -10
- package/packages/runtime/hooks.js +0 -3
- package/packages/runtime/index.d.ts +0 -3
- package/packages/runtime/index.js +0 -1
- package/packages/runtime/package-lock.json +0 -512
- package/packages/runtime/package.json +0 -16
- package/packages/runtime/server.d.ts +0 -1
- package/packages/runtime/server.js +0 -3
- package/packages/runtime/types.d.ts +0 -1
- package/packages/runtime/types.js +0 -3
- package/packages/schema/.eslintrc.json +0 -13
- package/packages/schema/.vscodeignore +0 -4
- package/packages/schema/asset/logo-dark.png +0 -0
- package/packages/schema/asset/logo-light.png +0 -0
- package/packages/schema/bin/cli +0 -3
- package/packages/schema/jest.config.ts +0 -32
- package/packages/schema/langium-config.json +0 -14
- package/packages/schema/langium-quickstart.md +0 -41
- package/packages/schema/language-configuration.json +0 -30
- package/packages/schema/package.json +0 -96
- package/packages/schema/src/cli/cli-util.ts +0 -80
- package/packages/schema/src/cli/index.ts +0 -64
- package/packages/schema/src/extension.ts +0 -76
- package/packages/schema/src/generator/constants.ts +0 -5
- package/packages/schema/src/generator/index.ts +0 -92
- package/packages/schema/src/generator/next-auth/index.ts +0 -197
- package/packages/schema/src/generator/package.template.json +0 -9
- package/packages/schema/src/generator/prisma/expression-writer.ts +0 -352
- package/packages/schema/src/generator/prisma/index.ts +0 -32
- package/packages/schema/src/generator/prisma/plain-expression-builder.ts +0 -91
- package/packages/schema/src/generator/prisma/prisma-builder.ts +0 -366
- package/packages/schema/src/generator/prisma/query-gard-generator.ts +0 -208
- package/packages/schema/src/generator/prisma/schema-generator.ts +0 -300
- package/packages/schema/src/generator/react-hooks/index.ts +0 -181
- package/packages/schema/src/generator/service/index.ts +0 -107
- package/packages/schema/src/generator/tsconfig.template.json +0 -17
- package/packages/schema/src/generator/types.ts +0 -17
- package/packages/schema/src/generator/utils.ts +0 -9
- package/packages/schema/src/language-server/generated/ast.ts +0 -603
- package/packages/schema/src/language-server/generated/grammar.ts +0 -2190
- package/packages/schema/src/language-server/generated/module.ts +0 -24
- package/packages/schema/src/language-server/main.ts +0 -12
- package/packages/schema/src/language-server/stdlib.zmodel +0 -22
- package/packages/schema/src/language-server/types.ts +0 -9
- package/packages/schema/src/language-server/zmodel-index.ts +0 -33
- package/packages/schema/src/language-server/zmodel-linker.ts +0 -409
- package/packages/schema/src/language-server/zmodel-module.ts +0 -90
- package/packages/schema/src/language-server/zmodel-scope.ts +0 -21
- package/packages/schema/src/language-server/zmodel-validator.ts +0 -35
- package/packages/schema/src/language-server/zmodel.langium +0 -186
- package/packages/schema/src/utils/exec-utils.ts +0 -5
- package/packages/schema/src/utils/indent-string.ts +0 -6
- package/packages/schema/syntaxes/zmodel.json +0 -57
- package/packages/schema/syntaxes/zmodel.tmLanguage.json +0 -57
- package/packages/schema/tests/generator/expression-writer.test.ts +0 -676
- package/packages/schema/tests/generator/prisma-builder.test.ts +0 -138
- package/packages/schema/tests/schema/parser.test.ts +0 -423
- package/packages/schema/tests/schema/sample-todo.test.ts +0 -14
- package/packages/schema/tests/utils.ts +0 -38
- package/packages/schema/tsconfig.json +0 -23
- package/pnpm-workspace.yaml +0 -3
- package/samples/todo/.env +0 -2
- package/samples/todo/.eslintrc.json +0 -3
- package/samples/todo/.vscode/launch.json +0 -11
- package/samples/todo/README.md +0 -34
- package/samples/todo/components/AuthGuard.tsx +0 -17
- package/samples/todo/components/Avatar.tsx +0 -22
- package/samples/todo/components/BreadCrumb.tsx +0 -44
- package/samples/todo/components/ManageMembers.tsx +0 -134
- package/samples/todo/components/NavBar.tsx +0 -57
- package/samples/todo/components/SpaceMembers.tsx +0 -76
- package/samples/todo/components/Spaces.tsx +0 -28
- package/samples/todo/components/TimeInfo.tsx +0 -17
- package/samples/todo/components/Todo.tsx +0 -72
- package/samples/todo/components/TodoList.tsx +0 -77
- package/samples/todo/lib/context.ts +0 -31
- package/samples/todo/next.config.js +0 -10
- package/samples/todo/package-lock.json +0 -7527
- package/samples/todo/package.json +0 -45
- package/samples/todo/pages/_app.tsx +0 -50
- package/samples/todo/pages/api/auth/[...nextauth].ts +0 -83
- package/samples/todo/pages/api/zenstack/[...path].ts +0 -16
- package/samples/todo/pages/create-space.tsx +0 -114
- package/samples/todo/pages/index.tsx +0 -32
- package/samples/todo/pages/space/[slug]/[listId]/index.tsx +0 -88
- package/samples/todo/pages/space/[slug]/index.tsx +0 -169
- package/samples/todo/postcss.config.js +0 -6
- package/samples/todo/public/avatar.jpg +0 -0
- package/samples/todo/public/favicon.ico +0 -0
- package/samples/todo/public/logo.png +0 -0
- package/samples/todo/public/vercel.svg +0 -4
- package/samples/todo/styles/globals.css +0 -7
- package/samples/todo/tailwind.config.js +0 -11
- package/samples/todo/tsconfig.json +0 -28
- package/samples/todo/types/next-auth.d.ts +0 -14
- package/samples/todo/types/next.d.ts +0 -16
- package/samples/todo/zenstack/migrations/20221014084317_init/migration.sql +0 -153
- package/samples/todo/zenstack/migrations/20221020094651_upate_cli/migration.sql +0 -23
- package/samples/todo/zenstack/migrations/migration_lock.toml +0 -3
- package/samples/todo/zenstack/schema.prisma +0 -126
- package/samples/todo/zenstack/schema.zmodel +0 -161
- package/tests/integration/jest.config.ts +0 -16
- package/tests/integration/package-lock.json +0 -1081
- package/tests/integration/package.json +0 -27
- package/tests/integration/tests/operation-coverate.test.ts +0 -563
- package/tests/integration/tests/operations.zmodel +0 -69
- package/tests/integration/tests/todo-e2e.test.ts +0 -577
- package/tests/integration/tests/todo.zmodel +0 -123
- package/tests/integration/tests/tsconfig.template.json +0 -10
- package/tests/integration/tests/utils.ts +0 -133
- package/tests/integration/tsconfig.json +0 -10
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ast_1 = require("@zenstackhq/language/ast");
|
|
4
|
+
const ast_utils_1 = require("../../utils/ast-utils");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
const utils_1 = require("../utils");
|
|
7
|
+
const utils_2 = require("./utils");
|
|
8
|
+
const sdk_1 = require("@zenstackhq/sdk");
|
|
9
|
+
/**
|
|
10
|
+
* Validates data model declarations.
|
|
11
|
+
*/
|
|
12
|
+
class DataModelValidator {
|
|
13
|
+
validate(dm, accept) {
|
|
14
|
+
(0, utils_2.validateDuplicatedDeclarations)(dm.fields, accept);
|
|
15
|
+
this.validateAttributes(dm, accept);
|
|
16
|
+
this.validateFields(dm, accept);
|
|
17
|
+
}
|
|
18
|
+
validateFields(dm, accept) {
|
|
19
|
+
const idFields = dm.fields.filter((f) => f.attributes.find((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@id'; }));
|
|
20
|
+
const modelLevelIds = (0, utils_1.getIdFields)(dm);
|
|
21
|
+
if (idFields.length === 0 && modelLevelIds.length === 0) {
|
|
22
|
+
const { allows, denies, hasFieldValidation } = (0, ast_utils_1.analyzePolicies)(dm);
|
|
23
|
+
if (allows.length > 0 || denies.length > 0 || hasFieldValidation) {
|
|
24
|
+
// TODO: relax this requirement to require only @unique fields
|
|
25
|
+
// when access policies or field valdaition is used, require an @id field
|
|
26
|
+
accept('error', 'Model must include a field with @id attribute or a model-level @@id attribute', {
|
|
27
|
+
node: dm,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
else if (idFields.length > 0 && modelLevelIds.length > 0) {
|
|
32
|
+
accept('error', 'Model cannot have both field-level @id and model-level @@id attributes', {
|
|
33
|
+
node: dm,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
else if (idFields.length > 1) {
|
|
37
|
+
accept('error', 'Model can include at most one field with @id attribute', {
|
|
38
|
+
node: dm,
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const fieldsToCheck = idFields.length > 0 ? idFields : modelLevelIds;
|
|
43
|
+
fieldsToCheck.forEach((idField) => {
|
|
44
|
+
if (idField.type.optional) {
|
|
45
|
+
accept('error', 'Field with @id attribute must not be optional', { node: idField });
|
|
46
|
+
}
|
|
47
|
+
if (idField.type.array || !idField.type.type || !constants_1.SCALAR_TYPES.includes(idField.type.type)) {
|
|
48
|
+
accept('error', 'Field with @id attribute must be of scalar type', { node: idField });
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
dm.fields.forEach((field) => this.validateField(field, accept));
|
|
53
|
+
}
|
|
54
|
+
validateField(field, accept) {
|
|
55
|
+
var _a;
|
|
56
|
+
if (field.type.array && field.type.optional) {
|
|
57
|
+
accept('error', 'Optional lists are not supported. Use either `Type[]` or `Type?`', { node: field.type });
|
|
58
|
+
}
|
|
59
|
+
field.attributes.forEach((attr) => (0, utils_2.validateAttributeApplication)(attr, accept));
|
|
60
|
+
if ((0, ast_1.isDataModel)((_a = field.type.reference) === null || _a === void 0 ? void 0 : _a.ref)) {
|
|
61
|
+
this.validateRelationField(field, accept);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
validateAttributes(dm, accept) {
|
|
65
|
+
dm.attributes.forEach((attr) => {
|
|
66
|
+
(0, utils_2.validateAttributeApplication)(attr, accept);
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
parseRelation(field, accept) {
|
|
70
|
+
var _a, _b, _c, _d;
|
|
71
|
+
const relAttr = field.attributes.find((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@relation'; });
|
|
72
|
+
let name;
|
|
73
|
+
let fields;
|
|
74
|
+
let references;
|
|
75
|
+
let valid = true;
|
|
76
|
+
if (!relAttr) {
|
|
77
|
+
return { attr: relAttr, name, fields, references, valid: true };
|
|
78
|
+
}
|
|
79
|
+
for (const arg of relAttr.args) {
|
|
80
|
+
if (!arg.name || arg.name === 'name') {
|
|
81
|
+
if ((0, ast_1.isLiteralExpr)(arg.value)) {
|
|
82
|
+
name = arg.value.value;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
else if (arg.name === 'fields') {
|
|
86
|
+
fields = arg.value.items;
|
|
87
|
+
if (fields.length === 0) {
|
|
88
|
+
if (accept) {
|
|
89
|
+
accept('error', `"fields" value cannot be emtpy`, {
|
|
90
|
+
node: arg,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
valid = false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else if (arg.name === 'references') {
|
|
97
|
+
references = arg.value.items;
|
|
98
|
+
if (references.length === 0) {
|
|
99
|
+
if (accept) {
|
|
100
|
+
accept('error', `"references" value cannot be emtpy`, {
|
|
101
|
+
node: arg,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
valid = false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (!fields || !references) {
|
|
109
|
+
if (this.isSelfRelation(field, name)) {
|
|
110
|
+
// self relations are partial
|
|
111
|
+
// https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
if (accept) {
|
|
115
|
+
accept('error', `Both "fields" and "references" must be provided`, { node: relAttr });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// validate "fields" and "references" typing consistency
|
|
121
|
+
if (fields.length !== references.length) {
|
|
122
|
+
if (accept) {
|
|
123
|
+
accept('error', `"references" and "fields" must have the same length`, { node: relAttr });
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
for (let i = 0; i < fields.length; i++) {
|
|
128
|
+
if (!fields[i].$resolvedType) {
|
|
129
|
+
if (accept) {
|
|
130
|
+
accept('error', `field reference is unresolved`, { node: fields[i] });
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (!references[i].$resolvedType) {
|
|
134
|
+
if (accept) {
|
|
135
|
+
accept('error', `field reference is unresolved`, { node: references[i] });
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (((_a = fields[i].$resolvedType) === null || _a === void 0 ? void 0 : _a.decl) !== ((_b = references[i].$resolvedType) === null || _b === void 0 ? void 0 : _b.decl) ||
|
|
139
|
+
((_c = fields[i].$resolvedType) === null || _c === void 0 ? void 0 : _c.array) !== ((_d = references[i].$resolvedType) === null || _d === void 0 ? void 0 : _d.array)) {
|
|
140
|
+
if (accept) {
|
|
141
|
+
accept('error', `values of "references" and "fields" must have the same type`, {
|
|
142
|
+
node: relAttr,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { attr: relAttr, name, fields, references, valid };
|
|
150
|
+
}
|
|
151
|
+
isSelfRelation(field, relationName) {
|
|
152
|
+
var _a, _b, _c, _d;
|
|
153
|
+
if (((_a = field.type.reference) === null || _a === void 0 ? void 0 : _a.ref) === field.$container) {
|
|
154
|
+
// field directly references back to its type
|
|
155
|
+
return true;
|
|
156
|
+
}
|
|
157
|
+
if (relationName) {
|
|
158
|
+
// field's relation points to another type, and that type's opposite relation field
|
|
159
|
+
// points back
|
|
160
|
+
const oppositeModelFields = (_c = (_b = field.type.reference) === null || _b === void 0 ? void 0 : _b.ref) === null || _c === void 0 ? void 0 : _c.fields;
|
|
161
|
+
if (oppositeModelFields) {
|
|
162
|
+
for (const oppositeField of oppositeModelFields) {
|
|
163
|
+
// find the opposite relation with the matching name
|
|
164
|
+
const relAttr = oppositeField.attributes.find((a) => { var _a; return ((_a = a.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@relation'; });
|
|
165
|
+
if (relAttr) {
|
|
166
|
+
const relNameExpr = relAttr.args.find((a) => !a.name || a.name === 'name');
|
|
167
|
+
const relName = (0, sdk_1.getLiteral)(relNameExpr === null || relNameExpr === void 0 ? void 0 : relNameExpr.value);
|
|
168
|
+
if (relName === relationName && ((_d = oppositeField.type.reference) === null || _d === void 0 ? void 0 : _d.ref) === field.$container) {
|
|
169
|
+
// found an opposite relation field that points back to this field's type
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return false;
|
|
177
|
+
}
|
|
178
|
+
validateRelationField(field, accept) {
|
|
179
|
+
var _a, _b, _c, _d, _e;
|
|
180
|
+
const thisRelation = this.parseRelation(field, accept);
|
|
181
|
+
if (!thisRelation.valid) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
185
|
+
const oppositeModel = field.type.reference.ref;
|
|
186
|
+
let oppositeFields = oppositeModel.fields.filter((f) => { var _a; return ((_a = f.type.reference) === null || _a === void 0 ? void 0 : _a.ref) === field.$container; });
|
|
187
|
+
oppositeFields = oppositeFields.filter((f) => {
|
|
188
|
+
const fieldRel = this.parseRelation(f);
|
|
189
|
+
return fieldRel.valid && fieldRel.name === thisRelation.name;
|
|
190
|
+
});
|
|
191
|
+
if (oppositeFields.length === 0) {
|
|
192
|
+
accept('error', `The relation field "${field.name}" on model "${field.$container.name}" is missing an opposite relation field on model "${oppositeModel.name}"`, { node: field, code: constants_1.IssueCodes.MissingOppositeRelation });
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
else if (oppositeFields.length > 1) {
|
|
196
|
+
oppositeFields.forEach((f) => {
|
|
197
|
+
if (this.isSelfRelation(f)) {
|
|
198
|
+
// self relations are partial
|
|
199
|
+
// https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
accept('error', `Fields ${oppositeFields.map((f) => '"' + f.name + '"').join(', ')} on model "${oppositeModel.name}" refer to the same relation to model "${field.$container.name}"`, { node: f });
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
const oppositeField = oppositeFields[0];
|
|
208
|
+
const oppositeRelation = this.parseRelation(oppositeField);
|
|
209
|
+
let relationOwner;
|
|
210
|
+
if (((_a = thisRelation === null || thisRelation === void 0 ? void 0 : thisRelation.references) === null || _a === void 0 ? void 0 : _a.length) && ((_b = thisRelation.fields) === null || _b === void 0 ? void 0 : _b.length)) {
|
|
211
|
+
if ((oppositeRelation === null || oppositeRelation === void 0 ? void 0 : oppositeRelation.references) || (oppositeRelation === null || oppositeRelation === void 0 ? void 0 : oppositeRelation.fields)) {
|
|
212
|
+
accept('error', '"fields" and "references" must be provided only on one side of relation field', {
|
|
213
|
+
node: oppositeField,
|
|
214
|
+
});
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
else {
|
|
218
|
+
relationOwner = oppositeField;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
else if (((_c = oppositeRelation === null || oppositeRelation === void 0 ? void 0 : oppositeRelation.references) === null || _c === void 0 ? void 0 : _c.length) && ((_d = oppositeRelation.fields) === null || _d === void 0 ? void 0 : _d.length)) {
|
|
222
|
+
if ((thisRelation === null || thisRelation === void 0 ? void 0 : thisRelation.references) || (thisRelation === null || thisRelation === void 0 ? void 0 : thisRelation.fields)) {
|
|
223
|
+
accept('error', '"fields" and "references" must be provided only on one side of relation field', {
|
|
224
|
+
node: field,
|
|
225
|
+
});
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
else {
|
|
229
|
+
relationOwner = field;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
[field, oppositeField].forEach((f) => {
|
|
234
|
+
if (!this.isSelfRelation(f, thisRelation.name)) {
|
|
235
|
+
accept('error', 'Field for one side of relation must carry @relation attribute with both "fields" and "references" fields', { node: f });
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
if (!relationOwner.type.array && !relationOwner.type.optional) {
|
|
241
|
+
accept('error', 'Relation field needs to be list or optional', {
|
|
242
|
+
node: relationOwner,
|
|
243
|
+
});
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if (relationOwner !== field && !relationOwner.type.array) {
|
|
247
|
+
// one-to-one relation requires defining side's reference field to be @unique
|
|
248
|
+
// e.g.:
|
|
249
|
+
// model User {
|
|
250
|
+
// id String @id @default(cuid())
|
|
251
|
+
// data UserData?
|
|
252
|
+
// }
|
|
253
|
+
// model UserData {
|
|
254
|
+
// id String @id @default(cuid())
|
|
255
|
+
// user User @relation(fields: [userId], references: [id])
|
|
256
|
+
// userId String
|
|
257
|
+
// }
|
|
258
|
+
//
|
|
259
|
+
// UserData.userId field needs to be @unique
|
|
260
|
+
const containingModel = field.$container;
|
|
261
|
+
const uniqueFieldList = (0, utils_1.getUniqueFields)(containingModel);
|
|
262
|
+
(_e = thisRelation.fields) === null || _e === void 0 ? void 0 : _e.forEach((ref) => {
|
|
263
|
+
const refField = ref.target.ref;
|
|
264
|
+
if (refField) {
|
|
265
|
+
if (refField.attributes.find((a) => { var _a; return ((_a = a.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@unique'; })) {
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
if (uniqueFieldList.some((list) => list.includes(refField))) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
accept('error', `Field "${refField.name}" is part of a one-to-one relation and must be marked as @unique or be part of a model-level @@unique attribute`, { node: refField });
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
exports.default = DataModelValidator;
|
|
278
|
+
//# sourceMappingURL=datamodel-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datamodel-validator.js","sourceRoot":"","sources":["../../../src/language-server/validator/datamodel-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { DataSource } from '@zenstackhq/language/ast';
|
|
2
|
+
import { AstValidator } from '../types';
|
|
3
|
+
import { ValidationAcceptor } from 'langium';
|
|
4
|
+
/**
|
|
5
|
+
* Validates data source declarations.
|
|
6
|
+
*/
|
|
7
|
+
export default class DataSourceValidator implements AstValidator<DataSource> {
|
|
8
|
+
validate(ds: DataSource, accept: ValidationAcceptor): void;
|
|
9
|
+
private validateProvider;
|
|
10
|
+
private validateUrl;
|
|
11
|
+
private validateRelationMode;
|
|
12
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ast_1 = require("@zenstackhq/language/ast");
|
|
4
|
+
const utils_1 = require("./utils");
|
|
5
|
+
const constants_1 = require("../constants");
|
|
6
|
+
/**
|
|
7
|
+
* Validates data source declarations.
|
|
8
|
+
*/
|
|
9
|
+
class DataSourceValidator {
|
|
10
|
+
validate(ds, accept) {
|
|
11
|
+
(0, utils_1.validateDuplicatedDeclarations)(ds.fields, accept);
|
|
12
|
+
this.validateProvider(ds, accept);
|
|
13
|
+
this.validateUrl(ds, accept);
|
|
14
|
+
this.validateRelationMode(ds, accept);
|
|
15
|
+
}
|
|
16
|
+
validateProvider(ds, accept) {
|
|
17
|
+
const provider = ds.fields.find((f) => f.name === 'provider');
|
|
18
|
+
if (!provider) {
|
|
19
|
+
accept('error', 'datasource must include a "provider" field', {
|
|
20
|
+
node: ds,
|
|
21
|
+
});
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const value = (0, utils_1.getStringLiteral)(provider.value);
|
|
25
|
+
if (!value) {
|
|
26
|
+
accept('error', '"provider" must be set to a string literal', {
|
|
27
|
+
node: provider.value,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
else if (!constants_1.SUPPORTED_PROVIDERS.includes(value)) {
|
|
31
|
+
accept('error', `Provider "${value}" is not supported. Choose from ${constants_1.SUPPORTED_PROVIDERS.map((p) => '"' + p + '"').join(' | ')}.`, { node: provider.value });
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
validateUrl(ds, accept) {
|
|
35
|
+
var _a;
|
|
36
|
+
const url = ds.fields.find((f) => f.name === 'url');
|
|
37
|
+
if (!url) {
|
|
38
|
+
accept('error', 'datasource must include a "url" field', {
|
|
39
|
+
node: ds,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
for (const fieldName of ['url', 'shadowDatabaseUrl']) {
|
|
43
|
+
const field = ds.fields.find((f) => f.name === fieldName);
|
|
44
|
+
if (!field) {
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
const value = (0, utils_1.getStringLiteral)(field.value);
|
|
48
|
+
if (!value && !((0, ast_1.isInvocationExpr)(field.value) && ((_a = field.value.function.ref) === null || _a === void 0 ? void 0 : _a.name) === 'env')) {
|
|
49
|
+
accept('error', `"${fieldName}" must be set to a string literal or an invocation of "env" function`, {
|
|
50
|
+
node: field.value,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
validateRelationMode(ds, accept) {
|
|
56
|
+
const field = ds.fields.find((f) => f.name === 'relationMode');
|
|
57
|
+
if (field) {
|
|
58
|
+
const val = (0, utils_1.getStringLiteral)(field.value);
|
|
59
|
+
if (!val || !['foreignKeys', 'prisma'].includes(val)) {
|
|
60
|
+
accept('error', '"relationMode" must be set to "foreignKeys" or "prisma"', { node: field.value });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
exports.default = DataSourceValidator;
|
|
66
|
+
//# sourceMappingURL=datasource-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"datasource-validator.js","sourceRoot":"","sources":["../../../src/language-server/validator/datasource-validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Enum } from '@zenstackhq/language/ast';
|
|
2
|
+
import { ValidationAcceptor } from 'langium';
|
|
3
|
+
import { AstValidator } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Validates enum declarations.
|
|
6
|
+
*/
|
|
7
|
+
export default class EnumValidator implements AstValidator<Enum> {
|
|
8
|
+
validate(_enum: Enum, accept: ValidationAcceptor): void;
|
|
9
|
+
private validateAttributes;
|
|
10
|
+
private validateField;
|
|
11
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const utils_1 = require("./utils");
|
|
4
|
+
/**
|
|
5
|
+
* Validates enum declarations.
|
|
6
|
+
*/
|
|
7
|
+
class EnumValidator {
|
|
8
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
9
|
+
validate(_enum, accept) {
|
|
10
|
+
(0, utils_1.validateDuplicatedDeclarations)(_enum.fields, accept);
|
|
11
|
+
this.validateAttributes(_enum, accept);
|
|
12
|
+
_enum.fields.forEach((field) => {
|
|
13
|
+
this.validateField(field, accept);
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
validateAttributes(_enum, accept) {
|
|
17
|
+
_enum.attributes.forEach((attr) => {
|
|
18
|
+
(0, utils_1.validateAttributeApplication)(attr, accept);
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
validateField(field, accept) {
|
|
22
|
+
field.attributes.forEach((attr) => {
|
|
23
|
+
(0, utils_1.validateAttributeApplication)(attr, accept);
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = EnumValidator;
|
|
28
|
+
//# sourceMappingURL=enum-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"enum-validator.js","sourceRoot":"","sources":["../../../src/language-server/validator/enum-validator.ts"],"names":[],"mappings":";;AAGA,mCAAuF;AAEvF;;GAEG;AACH,MAAqB,aAAa;IAC9B,6EAA6E;IAC7E,QAAQ,CAAC,KAAW,EAAE,MAA0B;QAC5C,IAAA,sCAA8B,EAAC,KAAK,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACrD,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YAC3B,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,kBAAkB,CAAC,KAAW,EAAE,MAA0B;QAC9D,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC9B,IAAA,oCAA4B,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,aAAa,CAAC,KAAgB,EAAE,MAA0B;QAC9D,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;YAC9B,IAAA,oCAA4B,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;IACP,CAAC;CACJ;AArBD,gCAqBC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Expression } from '@zenstackhq/language/ast';
|
|
2
|
+
import { ValidationAcceptor } from 'langium';
|
|
3
|
+
import { AstValidator } from '../types';
|
|
4
|
+
/**
|
|
5
|
+
* Validates expressions.
|
|
6
|
+
*/
|
|
7
|
+
export default class ExpressionValidator implements AstValidator<Expression> {
|
|
8
|
+
validate(expr: Expression, accept: ValidationAcceptor): void;
|
|
9
|
+
private isCollectionPredicate;
|
|
10
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const ast_1 = require("@zenstackhq/language/ast");
|
|
4
|
+
const ast_utils_1 = require("../../utils/ast-utils");
|
|
5
|
+
/**
|
|
6
|
+
* Validates expressions.
|
|
7
|
+
*/
|
|
8
|
+
class ExpressionValidator {
|
|
9
|
+
validate(expr, accept) {
|
|
10
|
+
if (!expr.$resolvedType) {
|
|
11
|
+
if ((0, ast_utils_1.isAuthInvocation)(expr)) {
|
|
12
|
+
// check was done at link time
|
|
13
|
+
accept('error', 'auth() cannot be resolved because no "User" model is defined', { node: expr });
|
|
14
|
+
}
|
|
15
|
+
else if (this.isCollectionPredicate(expr)) {
|
|
16
|
+
accept('error', 'collection predicate can only be used on an array of model type', { node: expr });
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
accept('error', 'expression cannot be resolved', {
|
|
20
|
+
node: expr,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
isCollectionPredicate(expr) {
|
|
26
|
+
return (0, ast_1.isBinaryExpr)(expr) && ['?', '!', '^'].includes(expr.operator);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
exports.default = ExpressionValidator;
|
|
30
|
+
//# sourceMappingURL=expression-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"expression-validator.js","sourceRoot":"","sources":["../../../src/language-server/validator/expression-validator.ts"],"names":[],"mappings":";;AAAA,kDAAoE;AAEpE,qDAAyD;AAGzD;;GAEG;AACH,MAAqB,mBAAmB;IACpC,QAAQ,CAAC,IAAgB,EAAE,MAA0B;QACjD,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE;YACrB,IAAI,IAAA,4BAAgB,EAAC,IAAI,CAAC,EAAE;gBACxB,8BAA8B;gBAC9B,MAAM,CAAC,OAAO,EAAE,8DAA8D,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACnG;iBAAM,IAAI,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE;gBACzC,MAAM,CAAC,OAAO,EAAE,iEAAiE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;aACtG;iBAAM;gBACH,MAAM,CAAC,OAAO,EAAE,+BAA+B,EAAE;oBAC7C,IAAI,EAAE,IAAI;iBACb,CAAC,CAAC;aACN;SACJ;IACL,CAAC;IAEO,qBAAqB,CAAC,IAAgB;QAC1C,OAAO,IAAA,kBAAY,EAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;CACJ;AAnBD,sCAmBC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Model } from '@zenstackhq/language/ast';
|
|
2
|
+
import { AstValidator } from '../types';
|
|
3
|
+
import { ValidationAcceptor } from 'langium';
|
|
4
|
+
/**
|
|
5
|
+
* Validates toplevel schema.
|
|
6
|
+
*/
|
|
7
|
+
export default class SchemaValidator implements AstValidator<Model> {
|
|
8
|
+
validate(model: Model, accept: ValidationAcceptor): void;
|
|
9
|
+
private validateDataSources;
|
|
10
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const constants_1 = require("../constants");
|
|
4
|
+
const ast_1 = require("@zenstackhq/language/ast");
|
|
5
|
+
const utils_1 = require("./utils");
|
|
6
|
+
/**
|
|
7
|
+
* Validates toplevel schema.
|
|
8
|
+
*/
|
|
9
|
+
class SchemaValidator {
|
|
10
|
+
validate(model, accept) {
|
|
11
|
+
var _a;
|
|
12
|
+
(0, utils_1.validateDuplicatedDeclarations)(model.declarations, accept);
|
|
13
|
+
if (!((_a = model.$document) === null || _a === void 0 ? void 0 : _a.uri.path.endsWith(constants_1.STD_LIB_MODULE_NAME))) {
|
|
14
|
+
this.validateDataSources(model, accept);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
validateDataSources(model, accept) {
|
|
18
|
+
const dataSources = model.declarations.filter((d) => (0, ast_1.isDataSource)(d));
|
|
19
|
+
if (dataSources.length === 0) {
|
|
20
|
+
accept('error', 'Model must define a datasource', { node: model });
|
|
21
|
+
}
|
|
22
|
+
else if (dataSources.length > 1) {
|
|
23
|
+
accept('error', 'Multiple datasource declarations are not allowed', { node: dataSources[1] });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.default = SchemaValidator;
|
|
28
|
+
//# sourceMappingURL=schema-validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema-validator.js","sourceRoot":"","sources":["../../../src/language-server/validator/schema-validator.ts"],"names":[],"mappings":";;AAAA,4CAAmD;AACnD,kDAA+D;AAG/D,mCAAyD;AAEzD;;GAEG;AACH,MAAqB,eAAe;IAChC,QAAQ,CAAC,KAAY,EAAE,MAA0B;;QAC7C,IAAA,sCAA8B,EAAC,KAAK,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAE3D,IAAI,CAAC,CAAA,MAAA,KAAK,CAAC,SAAS,0CAAE,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,+BAAmB,CAAC,CAAA,EAAE;YAC1D,IAAI,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;SAC3C;IACL,CAAC;IAEO,mBAAmB,CAAC,KAAY,EAAE,MAA0B;QAChE,MAAM,WAAW,GAAG,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,kBAAY,EAAC,CAAC,CAAC,CAAC,CAAC;QACtE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;YAC1B,MAAM,CAAC,OAAO,EAAE,gCAAgC,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;SACtE;aAAM,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE;YAC/B,MAAM,CAAC,OAAO,EAAE,kDAAkD,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SACjG;IACL,CAAC;CACJ;AAjBD,kCAiBC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { AttributeArg, AttributeParam, BuiltinType, DataModelAttribute, DataModelFieldAttribute, Expression, ExpressionType } from '@zenstackhq/language/ast';
|
|
2
|
+
import { AstNode, ValidationAcceptor } from 'langium';
|
|
3
|
+
/**
|
|
4
|
+
* Checks if the given declarations have duplicated names
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateDuplicatedDeclarations(decls: Array<AstNode & {
|
|
7
|
+
name: string;
|
|
8
|
+
}>, accept: ValidationAcceptor): void;
|
|
9
|
+
/**
|
|
10
|
+
* Try getting string value from a potential string literal expression
|
|
11
|
+
*/
|
|
12
|
+
export declare function getStringLiteral(node: AstNode | undefined): string | undefined;
|
|
13
|
+
/**
|
|
14
|
+
* Determines if the given sourceType is assignable to a destination of destType
|
|
15
|
+
*/
|
|
16
|
+
export declare function typeAssignable(destType: ExpressionType, sourceType: ExpressionType, sourceExpr?: Expression): boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Maps a ZModel builtin type to expression type
|
|
19
|
+
*/
|
|
20
|
+
export declare function mapBuiltinTypeToExpressionType(type: BuiltinType | 'Any' | 'Null'): ExpressionType | 'Any';
|
|
21
|
+
/**
|
|
22
|
+
* Determines if the given attribute argument is assignable to the given attribute parameter
|
|
23
|
+
*/
|
|
24
|
+
export declare function assignableToAttributeParam(arg: AttributeArg, param: AttributeParam, attr: DataModelAttribute | DataModelFieldAttribute): boolean;
|
|
25
|
+
export declare function validateAttributeApplication(attr: DataModelAttribute | DataModelFieldAttribute, accept: ValidationAcceptor): boolean | undefined;
|