zenstack 0.6.0-pre.8 → 1.0.0-alpha.100

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 (161) hide show
  1. package/README.md +111 -10
  2. package/cli/cli-error.d.ts +5 -0
  3. package/cli/cli-error.js +10 -0
  4. package/cli/cli-error.js.map +1 -0
  5. package/cli/cli-util.d.ts +21 -0
  6. package/cli/cli-util.js +239 -0
  7. package/cli/cli-util.js.map +1 -0
  8. package/cli/config.d.ts +19 -0
  9. package/cli/config.js +41 -0
  10. package/cli/config.js.map +1 -0
  11. package/cli/index.d.ts +16 -0
  12. package/cli/index.js +143 -6524
  13. package/cli/index.js.map +1 -0
  14. package/cli/plugin-runner.d.ts +14 -0
  15. package/cli/plugin-runner.js +146 -0
  16. package/cli/plugin-runner.js.map +1 -0
  17. package/constants.d.ts +1 -0
  18. package/constants.js +6 -0
  19. package/constants.js.map +1 -0
  20. package/language-server/constants.d.ts +26 -0
  21. package/language-server/constants.js +40 -0
  22. package/language-server/constants.js.map +1 -0
  23. package/language-server/main.d.ts +1 -0
  24. package/language-server/main.js +13 -6436
  25. package/language-server/main.js.map +1 -0
  26. package/language-server/types.d.ts +10 -0
  27. package/language-server/types.js +3 -0
  28. package/language-server/types.js.map +1 -0
  29. package/language-server/utils.d.ts +18 -0
  30. package/language-server/utils.js +58 -0
  31. package/language-server/utils.js.map +1 -0
  32. package/language-server/validator/attribute-validator.d.ts +9 -0
  33. package/language-server/validator/attribute-validator.js +11 -0
  34. package/language-server/validator/attribute-validator.js.map +1 -0
  35. package/language-server/validator/datamodel-validator.d.ts +15 -0
  36. package/language-server/validator/datamodel-validator.js +280 -0
  37. package/language-server/validator/datamodel-validator.js.map +1 -0
  38. package/language-server/validator/datasource-validator.d.ts +12 -0
  39. package/language-server/validator/datasource-validator.js +66 -0
  40. package/language-server/validator/datasource-validator.js.map +1 -0
  41. package/language-server/validator/enum-validator.d.ts +11 -0
  42. package/language-server/validator/enum-validator.js +28 -0
  43. package/language-server/validator/enum-validator.js.map +1 -0
  44. package/language-server/validator/expression-validator.d.ts +11 -0
  45. package/language-server/validator/expression-validator.js +57 -0
  46. package/language-server/validator/expression-validator.js.map +1 -0
  47. package/language-server/validator/function-invocation-validator.d.ts +11 -0
  48. package/language-server/validator/function-invocation-validator.js +110 -0
  49. package/language-server/validator/function-invocation-validator.js.map +1 -0
  50. package/language-server/validator/schema-validator.d.ts +10 -0
  51. package/language-server/validator/schema-validator.js +29 -0
  52. package/language-server/validator/schema-validator.js.map +1 -0
  53. package/language-server/validator/utils.d.ts +25 -0
  54. package/language-server/validator/utils.js +261 -0
  55. package/language-server/validator/utils.js.map +1 -0
  56. package/language-server/validator/zmodel-validator.d.ts +22 -0
  57. package/language-server/validator/zmodel-validator.js +74 -0
  58. package/language-server/validator/zmodel-validator.js.map +1 -0
  59. package/language-server/zmodel-code-action.d.ts +14 -0
  60. package/language-server/zmodel-code-action.js +109 -0
  61. package/language-server/zmodel-code-action.js.map +1 -0
  62. package/language-server/zmodel-formatter.d.ts +9 -0
  63. package/language-server/zmodel-formatter.js +76 -0
  64. package/language-server/zmodel-formatter.js.map +1 -0
  65. package/language-server/zmodel-linker.d.ts +30 -0
  66. package/language-server/zmodel-linker.js +375 -0
  67. package/language-server/zmodel-linker.js.map +1 -0
  68. package/language-server/zmodel-module.d.ts +41 -0
  69. package/language-server/zmodel-module.js +80 -0
  70. package/language-server/zmodel-module.js.map +1 -0
  71. package/language-server/zmodel-scope.d.ts +10 -0
  72. package/language-server/zmodel-scope.js +44 -0
  73. package/language-server/zmodel-scope.js.map +1 -0
  74. package/language-server/zmodel-workspace-manager.d.ts +12 -0
  75. package/language-server/zmodel-workspace-manager.js +138 -0
  76. package/language-server/zmodel-workspace-manager.js.map +1 -0
  77. package/package.json +31 -23
  78. package/plugins/access-policy/expression-writer.d.ts +41 -0
  79. package/plugins/access-policy/expression-writer.js +475 -0
  80. package/plugins/access-policy/expression-writer.js.map +1 -0
  81. package/plugins/access-policy/index.d.ts +4 -0
  82. package/plugins/access-policy/index.js +24 -0
  83. package/plugins/access-policy/index.js.map +1 -0
  84. package/plugins/access-policy/policy-guard-generator.d.ts +15 -0
  85. package/plugins/access-policy/policy-guard-generator.js +350 -0
  86. package/plugins/access-policy/policy-guard-generator.js.map +1 -0
  87. package/plugins/access-policy/typescript-expression-transformer.d.ts +28 -0
  88. package/plugins/access-policy/typescript-expression-transformer.js +121 -0
  89. package/plugins/access-policy/typescript-expression-transformer.js.map +1 -0
  90. package/plugins/access-policy/utils.d.ts +5 -0
  91. package/plugins/access-policy/utils.js +14 -0
  92. package/plugins/access-policy/utils.js.map +1 -0
  93. package/plugins/access-policy/zod-schema-generator.d.ts +12 -0
  94. package/plugins/access-policy/zod-schema-generator.js +157 -0
  95. package/plugins/access-policy/zod-schema-generator.js.map +1 -0
  96. package/plugins/model-meta/index.d.ts +4 -0
  97. package/plugins/model-meta/index.js +172 -0
  98. package/plugins/model-meta/index.js.map +1 -0
  99. package/plugins/plugin-utils.d.ts +15 -0
  100. package/plugins/plugin-utils.js +53 -0
  101. package/plugins/plugin-utils.js.map +1 -0
  102. package/plugins/prisma/indent-string.d.ts +4 -0
  103. package/plugins/prisma/indent-string.js +12 -0
  104. package/plugins/prisma/indent-string.js.map +1 -0
  105. package/plugins/prisma/index.d.ts +5 -0
  106. package/plugins/prisma/index.js +24 -3740
  107. package/plugins/prisma/index.js.map +1 -0
  108. package/plugins/prisma/prisma-builder.d.ts +152 -0
  109. package/plugins/prisma/prisma-builder.js +363 -0
  110. package/plugins/prisma/prisma-builder.js.map +1 -0
  111. package/plugins/prisma/schema-generator.d.ts +25 -0
  112. package/plugins/prisma/schema-generator.js +306 -0
  113. package/plugins/prisma/schema-generator.js.map +1 -0
  114. package/plugins/prisma/zmodel-code-generator.d.ts +30 -0
  115. package/plugins/prisma/zmodel-code-generator.js +122 -0
  116. package/plugins/prisma/zmodel-code-generator.js.map +1 -0
  117. package/plugins/zod/generator.d.ts +4 -0
  118. package/plugins/zod/generator.js +102 -0
  119. package/plugins/zod/generator.js.map +1 -0
  120. package/plugins/zod/index.d.ts +5 -0
  121. package/plugins/zod/index.js +21 -4808
  122. package/plugins/zod/index.js.map +1 -0
  123. package/plugins/zod/transformer.d.ts +67 -0
  124. package/plugins/zod/transformer.js +452 -0
  125. package/plugins/zod/transformer.js.map +1 -0
  126. package/plugins/zod/types.d.ts +22 -0
  127. package/plugins/zod/types.js +3 -0
  128. package/plugins/zod/types.js.map +1 -0
  129. package/plugins/zod/utils/removeDir.d.ts +1 -0
  130. package/plugins/zod/utils/removeDir.js +30 -0
  131. package/plugins/zod/utils/removeDir.js.map +1 -0
  132. package/res/prism-zmodel.js +2 -4
  133. package/res/starter.zmodel +51 -0
  134. package/res/stdlib.zmodel +194 -8
  135. package/telemetry.d.ts +20 -0
  136. package/telemetry.js +127 -0
  137. package/telemetry.js.map +1 -0
  138. package/types.d.ts +12 -0
  139. package/types.js +3 -0
  140. package/types.js.map +1 -0
  141. package/utils/ast-utils.d.ts +5 -0
  142. package/utils/ast-utils.js +49 -0
  143. package/utils/ast-utils.js.map +1 -0
  144. package/utils/exec-utils.d.ts +6 -0
  145. package/utils/exec-utils.js +13 -0
  146. package/utils/exec-utils.js.map +1 -0
  147. package/utils/pkg-utils.d.ts +3 -0
  148. package/utils/pkg-utils.js +64 -0
  149. package/utils/pkg-utils.js.map +1 -0
  150. package/utils/version-utils.d.ts +1 -0
  151. package/utils/version-utils.js +14 -0
  152. package/utils/version-utils.js.map +1 -0
  153. package/asset/logo-256-bg.png +0 -0
  154. package/asset/logo-dark-256.png +0 -0
  155. package/asset/logo-light-256.png +0 -0
  156. package/extension.js +0 -39
  157. package/plugins/policy-guard/index.js +0 -4289
  158. package/plugins/react-hooks/index.js +0 -4318
  159. package/plugins/trpc/index.js +0 -5386
  160. package/res/package.template.json +0 -9
  161. package/res/tsconfig.template.json +0 -17
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/language-server/main.ts"],"names":[],"mappings":";;AAAA,qCAA8C;AAC9C,uCAA8C;AAC9C,qDAAgF;AAChF,mDAAuD;AAEvD,oCAAoC;AACpC,MAAM,UAAU,GAAG,IAAA,uBAAgB,EAAC,uBAAgB,CAAC,GAAG,CAAC,CAAC;AAE1D,4DAA4D;AAC5D,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,oCAAoB,kBAAG,UAAU,IAAK,qBAAc,EAAG,CAAC;AAE3E,qDAAqD;AACrD,IAAA,6BAAmB,EAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { AstNode, ValidationAcceptor } from 'langium';
2
+ /**
3
+ * AST validator contract
4
+ */
5
+ export interface AstValidator<T extends AstNode> {
6
+ /**
7
+ * Validates an AST node
8
+ */
9
+ validate(node: T, accept: ValidationAcceptor): void;
10
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/language-server/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import { AstNode } from 'langium';
2
+ import { DataModel, DataModelField, Model } from '@zenstackhq/language/ast';
3
+ /**
4
+ * Gets the toplevel Model containing the given node.
5
+ */
6
+ export declare function getContainingModel(node: AstNode | undefined): Model | null;
7
+ /**
8
+ * Returns if the given node is declared in stdlib.
9
+ */
10
+ export declare function isFromStdlib(node: AstNode): boolean;
11
+ /**
12
+ * Gets id fields declared at the data model level
13
+ */
14
+ export declare function getIdFields(model: DataModel): DataModelField[];
15
+ /**
16
+ * Gets lists of unique fields declared at the data model level
17
+ */
18
+ export declare function getUniqueFields(model: DataModel): DataModelField[][];
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getUniqueFields = exports.getIdFields = exports.isFromStdlib = exports.getContainingModel = void 0;
4
+ const constants_1 = require("./constants");
5
+ const ast_1 = require("@zenstackhq/language/ast");
6
+ const sdk_1 = require("@zenstackhq/sdk");
7
+ /**
8
+ * Gets the toplevel Model containing the given node.
9
+ */
10
+ function getContainingModel(node) {
11
+ if (!node) {
12
+ return null;
13
+ }
14
+ return (0, ast_1.isModel)(node) ? node : getContainingModel(node.$container);
15
+ }
16
+ exports.getContainingModel = getContainingModel;
17
+ /**
18
+ * Returns if the given node is declared in stdlib.
19
+ */
20
+ function isFromStdlib(node) {
21
+ const model = getContainingModel(node);
22
+ return !!model && !!model.$document && model.$document.uri.path.endsWith(constants_1.STD_LIB_MODULE_NAME);
23
+ }
24
+ exports.isFromStdlib = isFromStdlib;
25
+ /**
26
+ * Gets id fields declared at the data model level
27
+ */
28
+ function getIdFields(model) {
29
+ const idAttr = model.attributes.find((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@@id'; });
30
+ if (!idAttr) {
31
+ return [];
32
+ }
33
+ const fieldsArg = idAttr.args.find((a) => { var _a; return ((_a = a.$resolvedParam) === null || _a === void 0 ? void 0 : _a.name) === 'fields'; });
34
+ if (!fieldsArg || !(0, ast_1.isArrayExpr)(fieldsArg.value)) {
35
+ return [];
36
+ }
37
+ return fieldsArg.value.items
38
+ .filter((item) => (0, ast_1.isReferenceExpr)(item))
39
+ .map((item) => (0, sdk_1.resolved)(item.target));
40
+ }
41
+ exports.getIdFields = getIdFields;
42
+ /**
43
+ * Gets lists of unique fields declared at the data model level
44
+ */
45
+ function getUniqueFields(model) {
46
+ const uniqueAttrs = model.attributes.filter((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@@unique'; });
47
+ return uniqueAttrs.map((uniqueAttr) => {
48
+ const fieldsArg = uniqueAttr.args.find((a) => { var _a; return ((_a = a.$resolvedParam) === null || _a === void 0 ? void 0 : _a.name) === 'fields'; });
49
+ if (!fieldsArg || !(0, ast_1.isArrayExpr)(fieldsArg.value)) {
50
+ return [];
51
+ }
52
+ return fieldsArg.value.items
53
+ .filter((item) => (0, ast_1.isReferenceExpr)(item))
54
+ .map((item) => (0, sdk_1.resolved)(item.target));
55
+ });
56
+ }
57
+ exports.getUniqueFields = getUniqueFields;
58
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/language-server/utils.ts"],"names":[],"mappings":";;;AACA,2CAAkD;AAClD,kDAQkC;AAClC,yCAA2C;AAE3C;;GAEG;AACH,SAAgB,kBAAkB,CAAC,IAAyB;IACxD,IAAI,CAAC,IAAI,EAAE;QACP,OAAO,IAAI,CAAC;KACf;IACD,OAAO,IAAA,aAAO,EAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;AACtE,CAAC;AALD,gDAKC;AAED;;GAEG;AACH,SAAgB,YAAY,CAAC,IAAa;IACtC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACvC,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,+BAAmB,CAAC,CAAC;AAClG,CAAC;AAHD,oCAGC;AAED;;GAEG;AACH,SAAgB,WAAW,CAAC,KAAgB;IACxC,MAAM,MAAM,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,0CAAE,IAAI,MAAK,MAAM,CAAA,EAAA,CAAC,CAAC;IAC/E,IAAI,CAAC,MAAM,EAAE;QACT,OAAO,EAAE,CAAC;KACb;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,CAAC,CAAC,cAAc,0CAAE,IAAI,MAAK,QAAQ,CAAA,EAAA,CAAC,CAAC;IAC/E,IAAI,CAAC,SAAS,IAAI,CAAC,IAAA,iBAAW,EAAC,SAAS,CAAC,KAAK,CAAC,EAAE;QAC7C,OAAO,EAAE,CAAC;KACb;IAED,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK;SACvB,MAAM,CAAC,CAAC,IAAI,EAAyB,EAAE,CAAC,IAAA,qBAAe,EAAC,IAAI,CAAC,CAAC;SAC9D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,cAAQ,EAAC,IAAI,CAAC,MAAM,CAAmB,CAAC,CAAC;AAChE,CAAC;AAbD,kCAaC;AAED;;GAEG;AACH,SAAgB,eAAe,CAAC,KAAgB;IAC5C,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,0CAAE,IAAI,MAAK,UAAU,CAAA,EAAA,CAAC,CAAC;IAC1F,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE;QAClC,MAAM,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,WAAC,OAAA,CAAA,MAAA,CAAC,CAAC,cAAc,0CAAE,IAAI,MAAK,QAAQ,CAAA,EAAA,CAAC,CAAC;QACnF,IAAI,CAAC,SAAS,IAAI,CAAC,IAAA,iBAAW,EAAC,SAAS,CAAC,KAAK,CAAC,EAAE;YAC7C,OAAO,EAAE,CAAC;SACb;QAED,OAAO,SAAS,CAAC,KAAK,CAAC,KAAK;aACvB,MAAM,CAAC,CAAC,IAAI,EAAyB,EAAE,CAAC,IAAA,qBAAe,EAAC,IAAI,CAAC,CAAC;aAC9D,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAA,cAAQ,EAAC,IAAI,CAAC,MAAM,CAAmB,CAAC,CAAC;IAChE,CAAC,CAAC,CAAC;AACP,CAAC;AAZD,0CAYC"}
@@ -0,0 +1,9 @@
1
+ import { Attribute } from '@zenstackhq/language/ast';
2
+ import { AstValidator } from '../types';
3
+ import { ValidationAcceptor } from 'langium';
4
+ /**
5
+ * Validates attribute declarations.
6
+ */
7
+ export default class AttributeValidator implements AstValidator<Attribute> {
8
+ validate(attr: Attribute, accept: ValidationAcceptor): void;
9
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ /**
4
+ * Validates attribute declarations.
5
+ */
6
+ class AttributeValidator {
7
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
8
+ validate(attr, accept) { }
9
+ }
10
+ exports.default = AttributeValidator;
11
+ //# sourceMappingURL=attribute-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attribute-validator.js","sourceRoot":"","sources":["../../../src/language-server/validator/attribute-validator.ts"],"names":[],"mappings":";;AAIA;;GAEG;AACH,MAAqB,kBAAkB;IACnC,mGAAmG;IACnG,QAAQ,CAAC,IAAe,EAAE,MAA0B,IAAS,CAAC;CACjE;AAHD,qCAGC"}
@@ -0,0 +1,15 @@
1
+ import { DataModel } from '@zenstackhq/language/ast';
2
+ import { ValidationAcceptor } from 'langium';
3
+ import { AstValidator } from '../types';
4
+ /**
5
+ * Validates data model declarations.
6
+ */
7
+ export default class DataModelValidator implements AstValidator<DataModel> {
8
+ validate(dm: DataModel, accept: ValidationAcceptor): void;
9
+ private validateFields;
10
+ private validateField;
11
+ private validateAttributes;
12
+ private parseRelation;
13
+ private isSelfRelation;
14
+ private validateRelationField;
15
+ }
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const ast_1 = require("@zenstackhq/language/ast");
4
+ const sdk_1 = require("@zenstackhq/sdk");
5
+ const constants_1 = require("../constants");
6
+ const utils_1 = require("../utils");
7
+ const utils_2 = require("./utils");
8
+ /**
9
+ * Validates data model declarations.
10
+ */
11
+ class DataModelValidator {
12
+ validate(dm, accept) {
13
+ (0, utils_2.validateDuplicatedDeclarations)(dm.fields, accept);
14
+ this.validateAttributes(dm, accept);
15
+ this.validateFields(dm, accept);
16
+ }
17
+ validateFields(dm, accept) {
18
+ 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'; }));
19
+ const modelLevelIds = (0, utils_1.getIdFields)(dm);
20
+ if (idFields.length === 0 && modelLevelIds.length === 0) {
21
+ const { allows, denies, hasFieldValidation } = (0, sdk_1.analyzePolicies)(dm);
22
+ if (allows.length > 0 || denies.length > 0 || hasFieldValidation) {
23
+ // TODO: relax this requirement to require only @unique fields
24
+ // when access policies or field valdaition is used, require an @id field
25
+ accept('error', 'Model must include a field with @id attribute or a model-level @@id attribute', {
26
+ node: dm,
27
+ });
28
+ }
29
+ }
30
+ else if (idFields.length > 0 && modelLevelIds.length > 0) {
31
+ accept('error', 'Model cannot have both field-level @id and model-level @@id attributes', {
32
+ node: dm,
33
+ });
34
+ }
35
+ else if (idFields.length > 1) {
36
+ accept('error', 'Model can include at most one field with @id attribute', {
37
+ node: dm,
38
+ });
39
+ }
40
+ else {
41
+ const fieldsToCheck = idFields.length > 0 ? idFields : modelLevelIds;
42
+ fieldsToCheck.forEach((idField) => {
43
+ if (idField.type.optional) {
44
+ accept('error', 'Field with @id attribute must not be optional', { node: idField });
45
+ }
46
+ if (idField.type.array || !idField.type.type || !constants_1.SCALAR_TYPES.includes(idField.type.type)) {
47
+ accept('error', 'Field with @id attribute must be of scalar type', { node: idField });
48
+ }
49
+ });
50
+ }
51
+ dm.fields.forEach((field) => this.validateField(field, accept));
52
+ }
53
+ validateField(field, accept) {
54
+ var _a;
55
+ if (field.type.array && field.type.optional) {
56
+ accept('error', 'Optional lists are not supported. Use either `Type[]` or `Type?`', { node: field.type });
57
+ }
58
+ field.attributes.forEach((attr) => (0, utils_2.validateAttributeApplication)(attr, accept));
59
+ if ((0, ast_1.isDataModel)((_a = field.type.reference) === null || _a === void 0 ? void 0 : _a.ref)) {
60
+ this.validateRelationField(field, accept);
61
+ }
62
+ }
63
+ validateAttributes(dm, accept) {
64
+ dm.attributes.forEach((attr) => {
65
+ (0, utils_2.validateAttributeApplication)(attr, accept);
66
+ });
67
+ }
68
+ parseRelation(field, accept) {
69
+ var _a, _b, _c, _d;
70
+ const relAttr = field.attributes.find((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@relation'; });
71
+ let name;
72
+ let fields;
73
+ let references;
74
+ let valid = true;
75
+ if (!relAttr) {
76
+ return { attr: relAttr, name, fields, references, valid: true };
77
+ }
78
+ for (const arg of relAttr.args) {
79
+ if (!arg.name || arg.name === 'name') {
80
+ if ((0, ast_1.isLiteralExpr)(arg.value)) {
81
+ name = arg.value.value;
82
+ }
83
+ }
84
+ else if (arg.name === 'fields') {
85
+ fields = arg.value.items;
86
+ if (fields.length === 0) {
87
+ if (accept) {
88
+ accept('error', `"fields" value cannot be emtpy`, {
89
+ node: arg,
90
+ });
91
+ }
92
+ valid = false;
93
+ }
94
+ }
95
+ else if (arg.name === 'references') {
96
+ references = arg.value.items;
97
+ if (references.length === 0) {
98
+ if (accept) {
99
+ accept('error', `"references" value cannot be emtpy`, {
100
+ node: arg,
101
+ });
102
+ }
103
+ valid = false;
104
+ }
105
+ }
106
+ }
107
+ if (!fields || !references) {
108
+ if (this.isSelfRelation(field, name)) {
109
+ // self relations are partial
110
+ // https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations
111
+ }
112
+ else {
113
+ if (accept) {
114
+ accept('error', `Both "fields" and "references" must be provided`, { node: relAttr });
115
+ }
116
+ }
117
+ }
118
+ else {
119
+ // validate "fields" and "references" typing consistency
120
+ if (fields.length !== references.length) {
121
+ if (accept) {
122
+ accept('error', `"references" and "fields" must have the same length`, { node: relAttr });
123
+ }
124
+ }
125
+ else {
126
+ for (let i = 0; i < fields.length; i++) {
127
+ if (!fields[i].$resolvedType) {
128
+ if (accept) {
129
+ accept('error', `field reference is unresolved`, { node: fields[i] });
130
+ }
131
+ }
132
+ if (!references[i].$resolvedType) {
133
+ if (accept) {
134
+ accept('error', `field reference is unresolved`, { node: references[i] });
135
+ }
136
+ }
137
+ 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) ||
138
+ ((_c = fields[i].$resolvedType) === null || _c === void 0 ? void 0 : _c.array) !== ((_d = references[i].$resolvedType) === null || _d === void 0 ? void 0 : _d.array)) {
139
+ if (accept) {
140
+ accept('error', `values of "references" and "fields" must have the same type`, {
141
+ node: relAttr,
142
+ });
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+ return { attr: relAttr, name, fields, references, valid };
149
+ }
150
+ isSelfRelation(field, relationName) {
151
+ var _a, _b, _c, _d;
152
+ if (((_a = field.type.reference) === null || _a === void 0 ? void 0 : _a.ref) === field.$container) {
153
+ // field directly references back to its type
154
+ return true;
155
+ }
156
+ if (relationName) {
157
+ // field's relation points to another type, and that type's opposite relation field
158
+ // points back
159
+ const oppositeModelFields = (_c = (_b = field.type.reference) === null || _b === void 0 ? void 0 : _b.ref) === null || _c === void 0 ? void 0 : _c.fields;
160
+ if (oppositeModelFields) {
161
+ for (const oppositeField of oppositeModelFields) {
162
+ // find the opposite relation with the matching name
163
+ const relAttr = oppositeField.attributes.find((a) => { var _a; return ((_a = a.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@relation'; });
164
+ if (relAttr) {
165
+ const relNameExpr = relAttr.args.find((a) => !a.name || a.name === 'name');
166
+ const relName = (0, sdk_1.getLiteral)(relNameExpr === null || relNameExpr === void 0 ? void 0 : relNameExpr.value);
167
+ if (relName === relationName && ((_d = oppositeField.type.reference) === null || _d === void 0 ? void 0 : _d.ref) === field.$container) {
168
+ // found an opposite relation field that points back to this field's type
169
+ return true;
170
+ }
171
+ }
172
+ }
173
+ }
174
+ }
175
+ return false;
176
+ }
177
+ validateRelationField(field, accept) {
178
+ var _a, _b, _c, _d, _e;
179
+ const thisRelation = this.parseRelation(field, accept);
180
+ if (!thisRelation.valid) {
181
+ return;
182
+ }
183
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
184
+ const oppositeModel = field.type.reference.ref;
185
+ let oppositeFields = oppositeModel.fields.filter((f) => { var _a; return ((_a = f.type.reference) === null || _a === void 0 ? void 0 : _a.ref) === field.$container; });
186
+ oppositeFields = oppositeFields.filter((f) => {
187
+ const fieldRel = this.parseRelation(f);
188
+ return fieldRel.valid && fieldRel.name === thisRelation.name;
189
+ });
190
+ if (oppositeFields.length === 0) {
191
+ 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 });
192
+ return;
193
+ }
194
+ else if (oppositeFields.length > 1) {
195
+ oppositeFields.forEach((f) => {
196
+ if (this.isSelfRelation(f)) {
197
+ // self relations are partial
198
+ // https://www.prisma.io/docs/concepts/components/prisma-schema/relations/self-relations
199
+ }
200
+ else {
201
+ 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 });
202
+ }
203
+ });
204
+ return;
205
+ }
206
+ const oppositeField = oppositeFields[0];
207
+ const oppositeRelation = this.parseRelation(oppositeField);
208
+ let relationOwner;
209
+ 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)) {
210
+ if ((oppositeRelation === null || oppositeRelation === void 0 ? void 0 : oppositeRelation.references) || (oppositeRelation === null || oppositeRelation === void 0 ? void 0 : oppositeRelation.fields)) {
211
+ accept('error', '"fields" and "references" must be provided only on one side of relation field', {
212
+ node: oppositeField,
213
+ });
214
+ return;
215
+ }
216
+ else {
217
+ relationOwner = oppositeField;
218
+ }
219
+ }
220
+ 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)) {
221
+ if ((thisRelation === null || thisRelation === void 0 ? void 0 : thisRelation.references) || (thisRelation === null || thisRelation === void 0 ? void 0 : thisRelation.fields)) {
222
+ accept('error', '"fields" and "references" must be provided only on one side of relation field', {
223
+ node: field,
224
+ });
225
+ return;
226
+ }
227
+ else {
228
+ relationOwner = field;
229
+ }
230
+ }
231
+ else {
232
+ // if both the field is array, then it's an implicit many-to-many relation
233
+ if (!(field.type.array && oppositeField.type.array)) {
234
+ [field, oppositeField].forEach((f) => {
235
+ if (!this.isSelfRelation(f, thisRelation.name)) {
236
+ accept('error', 'Field for one side of relation must carry @relation attribute with both "fields" and "references" fields', { node: f });
237
+ }
238
+ });
239
+ }
240
+ return;
241
+ }
242
+ if (!relationOwner.type.array && !relationOwner.type.optional) {
243
+ accept('error', 'Relation field needs to be list or optional', {
244
+ node: relationOwner,
245
+ });
246
+ return;
247
+ }
248
+ if (relationOwner !== field && !relationOwner.type.array) {
249
+ // one-to-one relation requires defining side's reference field to be @unique
250
+ // e.g.:
251
+ // model User {
252
+ // id String @id @default(cuid())
253
+ // data UserData?
254
+ // }
255
+ // model UserData {
256
+ // id String @id @default(cuid())
257
+ // user User @relation(fields: [userId], references: [id])
258
+ // userId String
259
+ // }
260
+ //
261
+ // UserData.userId field needs to be @unique
262
+ const containingModel = field.$container;
263
+ const uniqueFieldList = (0, utils_1.getUniqueFields)(containingModel);
264
+ (_e = thisRelation.fields) === null || _e === void 0 ? void 0 : _e.forEach((ref) => {
265
+ const refField = ref.target.ref;
266
+ if (refField) {
267
+ if (refField.attributes.find((a) => { var _a; return ((_a = a.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === '@unique'; })) {
268
+ return;
269
+ }
270
+ if (uniqueFieldList.some((list) => list.includes(refField))) {
271
+ return;
272
+ }
273
+ 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 });
274
+ }
275
+ });
276
+ }
277
+ }
278
+ }
279
+ exports.default = DataModelValidator;
280
+ //# 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,11 @@
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 validateBinaryExpr;
10
+ private isCollectionPredicate;
11
+ }