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.
Files changed (264) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +126 -1
  3. package/bin/cli +3 -0
  4. package/bin/post-install.js +24 -0
  5. package/cli/cli-error.d.ts +5 -0
  6. package/cli/cli-error.js +10 -0
  7. package/cli/cli-error.js.map +1 -0
  8. package/cli/cli-util.d.ts +18 -0
  9. package/cli/cli-util.js +143 -0
  10. package/cli/cli-util.js.map +1 -0
  11. package/cli/index.d.ts +15 -0
  12. package/cli/index.js +121 -0
  13. package/cli/index.js.map +1 -0
  14. package/cli/plugin-runner.d.ts +14 -0
  15. package/cli/plugin-runner.js +145 -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 +15 -0
  21. package/language-server/constants.js +20 -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 -0
  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 +278 -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 +10 -0
  45. package/language-server/validator/expression-validator.js +30 -0
  46. package/language-server/validator/expression-validator.js.map +1 -0
  47. package/language-server/validator/schema-validator.d.ts +10 -0
  48. package/language-server/validator/schema-validator.js +28 -0
  49. package/language-server/validator/schema-validator.js.map +1 -0
  50. package/language-server/validator/utils.d.ts +25 -0
  51. package/language-server/validator/utils.js +257 -0
  52. package/language-server/validator/utils.js.map +1 -0
  53. package/language-server/validator/zmodel-validator.d.ts +21 -0
  54. package/language-server/validator/zmodel-validator.js +69 -0
  55. package/language-server/validator/zmodel-validator.js.map +1 -0
  56. package/language-server/zmodel-code-action.d.ts +14 -0
  57. package/language-server/zmodel-code-action.js +93 -0
  58. package/language-server/zmodel-code-action.js.map +1 -0
  59. package/language-server/zmodel-formatter.d.ts +9 -0
  60. package/language-server/zmodel-formatter.js +76 -0
  61. package/language-server/zmodel-formatter.js.map +1 -0
  62. package/language-server/zmodel-linker.d.ts +29 -0
  63. package/language-server/zmodel-linker.js +366 -0
  64. package/language-server/zmodel-linker.js.map +1 -0
  65. package/language-server/zmodel-module.d.ts +41 -0
  66. package/language-server/zmodel-module.js +80 -0
  67. package/language-server/zmodel-module.js.map +1 -0
  68. package/language-server/zmodel-scope.d.ts +10 -0
  69. package/language-server/zmodel-scope.js +44 -0
  70. package/language-server/zmodel-scope.js.map +1 -0
  71. package/language-server/zmodel-workspace-manager.d.ts +8 -0
  72. package/language-server/zmodel-workspace-manager.js +37 -0
  73. package/language-server/zmodel-workspace-manager.js.map +1 -0
  74. package/package.json +133 -8
  75. package/plugins/access-policy/expression-writer.d.ts +39 -0
  76. package/plugins/access-policy/expression-writer.js +361 -0
  77. package/plugins/access-policy/expression-writer.js.map +1 -0
  78. package/plugins/access-policy/index.d.ts +4 -0
  79. package/plugins/access-policy/index.js +24 -0
  80. package/plugins/access-policy/index.js.map +1 -0
  81. package/plugins/access-policy/policy-guard-generator.d.ts +15 -0
  82. package/plugins/access-policy/policy-guard-generator.js +349 -0
  83. package/plugins/access-policy/policy-guard-generator.js.map +1 -0
  84. package/plugins/access-policy/typescript-expression-transformer.d.ts +26 -0
  85. package/plugins/access-policy/typescript-expression-transformer.js +111 -0
  86. package/plugins/access-policy/typescript-expression-transformer.js.map +1 -0
  87. package/plugins/access-policy/utils.d.ts +5 -0
  88. package/plugins/access-policy/utils.js +14 -0
  89. package/plugins/access-policy/utils.js.map +1 -0
  90. package/plugins/access-policy/zod-schema-generator.d.ts +12 -0
  91. package/plugins/access-policy/zod-schema-generator.js +158 -0
  92. package/plugins/access-policy/zod-schema-generator.js.map +1 -0
  93. package/plugins/model-meta/index.d.ts +4 -0
  94. package/plugins/model-meta/index.js +168 -0
  95. package/plugins/model-meta/index.js.map +1 -0
  96. package/plugins/plugin-utils.d.ts +16 -0
  97. package/plugins/plugin-utils.js +54 -0
  98. package/plugins/plugin-utils.js.map +1 -0
  99. package/plugins/prisma/indent-string.d.ts +4 -0
  100. package/plugins/prisma/indent-string.js +12 -0
  101. package/plugins/prisma/indent-string.js.map +1 -0
  102. package/plugins/prisma/index.d.ts +4 -0
  103. package/plugins/prisma/index.js +24 -0
  104. package/plugins/prisma/index.js.map +1 -0
  105. package/plugins/prisma/prisma-builder.d.ts +152 -0
  106. package/plugins/prisma/prisma-builder.js +363 -0
  107. package/plugins/prisma/prisma-builder.js.map +1 -0
  108. package/plugins/prisma/schema-generator.d.ts +25 -0
  109. package/plugins/prisma/schema-generator.js +292 -0
  110. package/plugins/prisma/schema-generator.js.map +1 -0
  111. package/plugins/prisma/zmodel-code-generator.d.ts +28 -0
  112. package/plugins/prisma/zmodel-code-generator.js +114 -0
  113. package/plugins/prisma/zmodel-code-generator.js.map +1 -0
  114. package/res/prism-zmodel.js +20 -0
  115. package/res/starter.zmodel +51 -0
  116. package/res/stdlib.zmodel +346 -0
  117. package/telemetry.d.ts +20 -0
  118. package/telemetry.js +119 -0
  119. package/telemetry.js.map +1 -0
  120. package/types.d.ts +12 -0
  121. package/types.js +3 -0
  122. package/types.js.map +1 -0
  123. package/utils/ast-utils.d.ts +16 -0
  124. package/utils/ast-utils.js +85 -0
  125. package/utils/ast-utils.js.map +1 -0
  126. package/utils/exec-utils.d.ts +6 -0
  127. package/utils/exec-utils.js +13 -0
  128. package/utils/exec-utils.js.map +1 -0
  129. package/utils/pkg-utils.d.ts +3 -0
  130. package/utils/pkg-utils.js +46 -0
  131. package/utils/pkg-utils.js.map +1 -0
  132. package/utils/version-utils.d.ts +1 -0
  133. package/utils/version-utils.js +14 -0
  134. package/utils/version-utils.js.map +1 -0
  135. package/.vscode/extensions.json +0 -7
  136. package/.vscode/launch.json +0 -49
  137. package/.vscode/settings.json +0 -4
  138. package/packages/internal/jest.config.ts +0 -32
  139. package/packages/internal/package.json +0 -42
  140. package/packages/internal/src/constants.ts +0 -1
  141. package/packages/internal/src/handler/data/guard-utils.ts +0 -7
  142. package/packages/internal/src/handler/data/handler.ts +0 -415
  143. package/packages/internal/src/handler/data/query-processor.ts +0 -504
  144. package/packages/internal/src/handler/index.ts +0 -1
  145. package/packages/internal/src/handler/types.ts +0 -20
  146. package/packages/internal/src/index.ts +0 -3
  147. package/packages/internal/src/request-handler.ts +0 -27
  148. package/packages/internal/src/request.ts +0 -101
  149. package/packages/internal/src/types.ts +0 -40
  150. package/packages/internal/tests/query-processor.test.ts +0 -172
  151. package/packages/internal/tsconfig.json +0 -21
  152. package/packages/runtime/auth.d.ts +0 -1
  153. package/packages/runtime/auth.js +0 -3
  154. package/packages/runtime/hooks.d.ts +0 -10
  155. package/packages/runtime/hooks.js +0 -3
  156. package/packages/runtime/index.d.ts +0 -3
  157. package/packages/runtime/index.js +0 -1
  158. package/packages/runtime/package-lock.json +0 -512
  159. package/packages/runtime/package.json +0 -16
  160. package/packages/runtime/server.d.ts +0 -1
  161. package/packages/runtime/server.js +0 -3
  162. package/packages/runtime/types.d.ts +0 -1
  163. package/packages/runtime/types.js +0 -3
  164. package/packages/schema/.eslintrc.json +0 -13
  165. package/packages/schema/.vscodeignore +0 -4
  166. package/packages/schema/asset/logo-dark.png +0 -0
  167. package/packages/schema/asset/logo-light.png +0 -0
  168. package/packages/schema/bin/cli +0 -3
  169. package/packages/schema/jest.config.ts +0 -32
  170. package/packages/schema/langium-config.json +0 -14
  171. package/packages/schema/langium-quickstart.md +0 -41
  172. package/packages/schema/language-configuration.json +0 -30
  173. package/packages/schema/package.json +0 -96
  174. package/packages/schema/src/cli/cli-util.ts +0 -80
  175. package/packages/schema/src/cli/index.ts +0 -64
  176. package/packages/schema/src/extension.ts +0 -76
  177. package/packages/schema/src/generator/constants.ts +0 -5
  178. package/packages/schema/src/generator/index.ts +0 -92
  179. package/packages/schema/src/generator/next-auth/index.ts +0 -197
  180. package/packages/schema/src/generator/package.template.json +0 -9
  181. package/packages/schema/src/generator/prisma/expression-writer.ts +0 -352
  182. package/packages/schema/src/generator/prisma/index.ts +0 -32
  183. package/packages/schema/src/generator/prisma/plain-expression-builder.ts +0 -91
  184. package/packages/schema/src/generator/prisma/prisma-builder.ts +0 -366
  185. package/packages/schema/src/generator/prisma/query-gard-generator.ts +0 -208
  186. package/packages/schema/src/generator/prisma/schema-generator.ts +0 -300
  187. package/packages/schema/src/generator/react-hooks/index.ts +0 -181
  188. package/packages/schema/src/generator/service/index.ts +0 -107
  189. package/packages/schema/src/generator/tsconfig.template.json +0 -17
  190. package/packages/schema/src/generator/types.ts +0 -17
  191. package/packages/schema/src/generator/utils.ts +0 -9
  192. package/packages/schema/src/language-server/generated/ast.ts +0 -603
  193. package/packages/schema/src/language-server/generated/grammar.ts +0 -2190
  194. package/packages/schema/src/language-server/generated/module.ts +0 -24
  195. package/packages/schema/src/language-server/main.ts +0 -12
  196. package/packages/schema/src/language-server/stdlib.zmodel +0 -22
  197. package/packages/schema/src/language-server/types.ts +0 -9
  198. package/packages/schema/src/language-server/zmodel-index.ts +0 -33
  199. package/packages/schema/src/language-server/zmodel-linker.ts +0 -409
  200. package/packages/schema/src/language-server/zmodel-module.ts +0 -90
  201. package/packages/schema/src/language-server/zmodel-scope.ts +0 -21
  202. package/packages/schema/src/language-server/zmodel-validator.ts +0 -35
  203. package/packages/schema/src/language-server/zmodel.langium +0 -186
  204. package/packages/schema/src/utils/exec-utils.ts +0 -5
  205. package/packages/schema/src/utils/indent-string.ts +0 -6
  206. package/packages/schema/syntaxes/zmodel.json +0 -57
  207. package/packages/schema/syntaxes/zmodel.tmLanguage.json +0 -57
  208. package/packages/schema/tests/generator/expression-writer.test.ts +0 -676
  209. package/packages/schema/tests/generator/prisma-builder.test.ts +0 -138
  210. package/packages/schema/tests/schema/parser.test.ts +0 -423
  211. package/packages/schema/tests/schema/sample-todo.test.ts +0 -14
  212. package/packages/schema/tests/utils.ts +0 -38
  213. package/packages/schema/tsconfig.json +0 -23
  214. package/pnpm-workspace.yaml +0 -3
  215. package/samples/todo/.env +0 -2
  216. package/samples/todo/.eslintrc.json +0 -3
  217. package/samples/todo/.vscode/launch.json +0 -11
  218. package/samples/todo/README.md +0 -34
  219. package/samples/todo/components/AuthGuard.tsx +0 -17
  220. package/samples/todo/components/Avatar.tsx +0 -22
  221. package/samples/todo/components/BreadCrumb.tsx +0 -44
  222. package/samples/todo/components/ManageMembers.tsx +0 -134
  223. package/samples/todo/components/NavBar.tsx +0 -57
  224. package/samples/todo/components/SpaceMembers.tsx +0 -76
  225. package/samples/todo/components/Spaces.tsx +0 -28
  226. package/samples/todo/components/TimeInfo.tsx +0 -17
  227. package/samples/todo/components/Todo.tsx +0 -72
  228. package/samples/todo/components/TodoList.tsx +0 -77
  229. package/samples/todo/lib/context.ts +0 -31
  230. package/samples/todo/next.config.js +0 -10
  231. package/samples/todo/package-lock.json +0 -7527
  232. package/samples/todo/package.json +0 -45
  233. package/samples/todo/pages/_app.tsx +0 -50
  234. package/samples/todo/pages/api/auth/[...nextauth].ts +0 -83
  235. package/samples/todo/pages/api/zenstack/[...path].ts +0 -16
  236. package/samples/todo/pages/create-space.tsx +0 -114
  237. package/samples/todo/pages/index.tsx +0 -32
  238. package/samples/todo/pages/space/[slug]/[listId]/index.tsx +0 -88
  239. package/samples/todo/pages/space/[slug]/index.tsx +0 -169
  240. package/samples/todo/postcss.config.js +0 -6
  241. package/samples/todo/public/avatar.jpg +0 -0
  242. package/samples/todo/public/favicon.ico +0 -0
  243. package/samples/todo/public/logo.png +0 -0
  244. package/samples/todo/public/vercel.svg +0 -4
  245. package/samples/todo/styles/globals.css +0 -7
  246. package/samples/todo/tailwind.config.js +0 -11
  247. package/samples/todo/tsconfig.json +0 -28
  248. package/samples/todo/types/next-auth.d.ts +0 -14
  249. package/samples/todo/types/next.d.ts +0 -16
  250. package/samples/todo/zenstack/migrations/20221014084317_init/migration.sql +0 -153
  251. package/samples/todo/zenstack/migrations/20221020094651_upate_cli/migration.sql +0 -23
  252. package/samples/todo/zenstack/migrations/migration_lock.toml +0 -3
  253. package/samples/todo/zenstack/schema.prisma +0 -126
  254. package/samples/todo/zenstack/schema.zmodel +0 -161
  255. package/tests/integration/jest.config.ts +0 -16
  256. package/tests/integration/package-lock.json +0 -1081
  257. package/tests/integration/package.json +0 -27
  258. package/tests/integration/tests/operation-coverate.test.ts +0 -563
  259. package/tests/integration/tests/operations.zmodel +0 -69
  260. package/tests/integration/tests/todo-e2e.test.ts +0 -577
  261. package/tests/integration/tests/todo.zmodel +0 -123
  262. package/tests/integration/tests/tsconfig.template.json +0 -10
  263. package/tests/integration/tests/utils.ts +0 -133
  264. package/tests/integration/tsconfig.json +0 -10
@@ -0,0 +1,349 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const ast_1 = require("@zenstackhq/language/ast");
16
+ const sdk_1 = require("@zenstackhq/sdk");
17
+ const change_case_1 = require("change-case");
18
+ const langium_1 = require("langium");
19
+ const path_1 = __importDefault(require("path"));
20
+ const ts_morph_1 = require("ts-morph");
21
+ const _1 = require(".");
22
+ const utils_1 = require("../../language-server/utils");
23
+ const ast_utils_1 = require("../../utils/ast-utils");
24
+ const plugin_utils_1 = require("../plugin-utils");
25
+ const expression_writer_1 = require("./expression-writer");
26
+ const utils_2 = require("./utils");
27
+ const zod_schema_generator_1 = require("./zod-schema-generator");
28
+ /**
29
+ * Generates source file that contains Prisma query guard objects used for injecting database queries
30
+ */
31
+ class PolicyGenerator {
32
+ generate(model, options) {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ const output = options.output ? options.output : (0, plugin_utils_1.getDefaultOutputFolder)();
35
+ if (!output) {
36
+ console.error(`Unable to determine output path, not running plugin ${_1.name}`);
37
+ return;
38
+ }
39
+ const project = new ts_morph_1.Project();
40
+ const sf = project.createSourceFile(path_1.default.join(output, 'policy.ts'), undefined, { overwrite: true });
41
+ sf.addImportDeclaration({
42
+ namedImports: [{ name: 'QueryContext' }],
43
+ moduleSpecifier: `${plugin_utils_1.RUNTIME_PACKAGE}`,
44
+ isTypeOnly: true,
45
+ });
46
+ sf.addImportDeclaration({
47
+ namedImports: [{ name: 'z' }],
48
+ moduleSpecifier: 'zod',
49
+ });
50
+ // import enums
51
+ for (const e of model.declarations.filter((d) => (0, ast_1.isEnum)(d))) {
52
+ sf.addImportDeclaration({
53
+ namedImports: [{ name: e.name }],
54
+ moduleSpecifier: '@prisma/client',
55
+ });
56
+ }
57
+ const models = model.declarations.filter((d) => (0, ast_1.isDataModel)(d));
58
+ const policyMap = {};
59
+ for (const model of models) {
60
+ policyMap[model.name] = yield this.generateQueryGuardForModel(model, sf);
61
+ }
62
+ const zodGenerator = new zod_schema_generator_1.ZodSchemaGenerator();
63
+ sf.addVariableStatement({
64
+ declarationKind: ts_morph_1.VariableDeclarationKind.Const,
65
+ declarations: [
66
+ {
67
+ name: 'policy',
68
+ initializer: (writer) => {
69
+ writer.block(() => {
70
+ writer.write('guard:');
71
+ writer.inlineBlock(() => {
72
+ for (const [model, map] of Object.entries(policyMap)) {
73
+ writer.write(`${(0, change_case_1.camelCase)(model)}:`);
74
+ writer.inlineBlock(() => {
75
+ for (const [op, func] of Object.entries(map)) {
76
+ if (typeof func === 'object') {
77
+ writer.write(`${op}: ${JSON.stringify(func)},`);
78
+ }
79
+ else {
80
+ writer.write(`${op}: ${func},`);
81
+ }
82
+ }
83
+ });
84
+ writer.write(',');
85
+ }
86
+ });
87
+ writer.writeLine(',');
88
+ writer.write('schema:');
89
+ zodGenerator.generate(writer, models);
90
+ });
91
+ },
92
+ },
93
+ ],
94
+ });
95
+ sf.addStatements('export default policy');
96
+ sf.formatText();
97
+ yield project.save();
98
+ yield project.emit();
99
+ });
100
+ }
101
+ getPolicyExpressions(model, kind, operation) {
102
+ const attrs = model.attributes.filter((attr) => { var _a; return ((_a = attr.decl.ref) === null || _a === void 0 ? void 0 : _a.name) === `@@${kind}`; });
103
+ const checkOperation = operation === 'postUpdate' ? 'update' : operation;
104
+ let result = attrs
105
+ .filter((attr) => {
106
+ const opsValue = (0, sdk_1.getLiteral)(attr.args[0].value);
107
+ if (!opsValue) {
108
+ return false;
109
+ }
110
+ const ops = opsValue.split(',').map((s) => s.trim());
111
+ return ops.includes(checkOperation) || ops.includes('all');
112
+ })
113
+ .map((attr) => attr.args[1].value);
114
+ if (operation === 'update') {
115
+ result = this.processUpdatePolicies(result, false);
116
+ }
117
+ else if (operation === 'postUpdate') {
118
+ result = this.processUpdatePolicies(result, true);
119
+ }
120
+ return result;
121
+ }
122
+ processUpdatePolicies(expressions, postUpdate) {
123
+ return expressions
124
+ .map((expr) => this.visitPolicyExpression(expr, postUpdate))
125
+ .filter((e) => !!e);
126
+ }
127
+ visitPolicyExpression(expr, postUpdate) {
128
+ if ((0, ast_1.isBinaryExpr)(expr) && (expr.operator === '&&' || expr.operator === '||')) {
129
+ const left = this.visitPolicyExpression(expr.left, postUpdate);
130
+ const right = this.visitPolicyExpression(expr.right, postUpdate);
131
+ if (!left)
132
+ return right;
133
+ if (!right)
134
+ return left;
135
+ return Object.assign(Object.assign({}, expr), { left, right });
136
+ }
137
+ if ((0, ast_1.isUnaryExpr)(expr) && expr.operator === '!') {
138
+ const operand = this.visitPolicyExpression(expr.operand, postUpdate);
139
+ if (!operand)
140
+ return undefined;
141
+ return Object.assign(Object.assign({}, expr), { operand });
142
+ }
143
+ if (postUpdate && !this.hasFutureReference(expr)) {
144
+ return undefined;
145
+ }
146
+ else if (!postUpdate && this.hasFutureReference(expr)) {
147
+ return undefined;
148
+ }
149
+ return expr;
150
+ }
151
+ hasFutureReference(expr) {
152
+ var _a;
153
+ for (const node of (0, langium_1.streamAllContents)(expr)) {
154
+ if ((0, ast_1.isInvocationExpr)(node) && ((_a = node.function.ref) === null || _a === void 0 ? void 0 : _a.name) === 'future' && (0, utils_1.isFromStdlib)(node.function.ref)) {
155
+ return true;
156
+ }
157
+ }
158
+ return false;
159
+ }
160
+ generateQueryGuardForModel(model, sourceFile) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ const result = {};
163
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
164
+ const policies = (0, ast_utils_1.analyzePolicies)(model);
165
+ for (const kind of plugin_utils_1.ALL_OPERATION_KINDS) {
166
+ if (policies[kind] === true || policies[kind] === false) {
167
+ result[kind] = policies[kind];
168
+ continue;
169
+ }
170
+ const denies = this.getPolicyExpressions(model, 'deny', kind);
171
+ const allows = this.getPolicyExpressions(model, 'allow', kind);
172
+ if (kind === 'update' && allows.length === 0) {
173
+ // no allow rule for 'update', policy is constant based on if there's
174
+ // post-update counterpart
175
+ if (this.getPolicyExpressions(model, 'allow', 'postUpdate').length === 0) {
176
+ result[kind] = false;
177
+ continue;
178
+ }
179
+ else {
180
+ result[kind] = true;
181
+ continue;
182
+ }
183
+ }
184
+ if (kind === 'postUpdate' && allows.length === 0 && denies.length === 0) {
185
+ // no rule 'postUpdate', always allow
186
+ result[kind] = true;
187
+ continue;
188
+ }
189
+ const func = this.generateQueryGuardFunction(sourceFile, model, kind, allows, denies);
190
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
191
+ result[kind] = func.getName();
192
+ if (kind === 'postUpdate') {
193
+ const preValueSelect = this.generatePreValueSelect(model, allows, denies);
194
+ if (preValueSelect) {
195
+ result['preValueSelect'] = preValueSelect;
196
+ }
197
+ }
198
+ }
199
+ return result;
200
+ });
201
+ }
202
+ // generates an object that can be used as the 'select' argument when fetching pre-update
203
+ // entity value
204
+ generatePreValueSelect(model, allows, denies) {
205
+ var _a;
206
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
207
+ const result = {};
208
+ const addPath = (path) => {
209
+ let curr = result;
210
+ path.forEach((seg, i) => {
211
+ if (i === path.length - 1) {
212
+ curr[seg] = true;
213
+ }
214
+ else {
215
+ if (!curr[seg]) {
216
+ curr[seg] = { select: {} };
217
+ }
218
+ curr = curr[seg].select;
219
+ }
220
+ });
221
+ };
222
+ const visit = (node) => {
223
+ if ((0, ast_1.isReferenceExpr)(node)) {
224
+ const target = (0, sdk_1.resolved)(node.target);
225
+ if ((0, ast_1.isDataModelField)(target)) {
226
+ // a field selection, it's a terminal
227
+ return [target.name];
228
+ }
229
+ }
230
+ else if ((0, ast_1.isMemberAccessExpr)(node)) {
231
+ if ((0, utils_2.isFutureExpr)(node.operand)) {
232
+ // future().field is not subject to pre-update select
233
+ return undefined;
234
+ }
235
+ // build a selection path inside-out for chained member access
236
+ const inner = visit(node.operand);
237
+ if (inner) {
238
+ return [...inner, node.member.$refText];
239
+ }
240
+ }
241
+ return undefined;
242
+ };
243
+ for (const rule of [...allows, ...denies]) {
244
+ for (const expr of (0, langium_1.streamAllContents)(rule).filter((node) => (0, ast_1.isExpression)(node))) {
245
+ // only care about member access and reference expressions
246
+ if (!(0, ast_1.isMemberAccessExpr)(expr) && !(0, ast_1.isReferenceExpr)(expr)) {
247
+ continue;
248
+ }
249
+ if (expr.$container.$type === ast_1.MemberAccessExpr) {
250
+ // only visit top-level member access
251
+ continue;
252
+ }
253
+ const path = visit(expr);
254
+ if (path) {
255
+ if ((0, ast_1.isDataModel)((_a = expr.$resolvedType) === null || _a === void 0 ? void 0 : _a.decl)) {
256
+ // member selection ended at a data model field, include its 'id'
257
+ path.push('id');
258
+ }
259
+ addPath(path);
260
+ }
261
+ }
262
+ }
263
+ return Object.keys(result).length === 0 ? null : result;
264
+ }
265
+ generateQueryGuardFunction(sourceFile, model, kind, allows, denies) {
266
+ const func = sourceFile
267
+ .addFunction({
268
+ name: model.name + '_' + kind,
269
+ returnType: 'any',
270
+ parameters: [
271
+ {
272
+ name: 'context',
273
+ type: 'QueryContext',
274
+ },
275
+ ],
276
+ })
277
+ .addBody();
278
+ // check if any allow or deny rule contains 'auth()' invocation
279
+ let hasAuthRef = false;
280
+ for (const node of [...denies, ...allows]) {
281
+ for (const child of (0, langium_1.streamAllContents)(node)) {
282
+ if ((0, ast_1.isInvocationExpr)(child) && (0, sdk_1.resolved)(child.function).name === 'auth') {
283
+ hasAuthRef = true;
284
+ break;
285
+ }
286
+ }
287
+ if (hasAuthRef) {
288
+ break;
289
+ }
290
+ }
291
+ if (hasAuthRef) {
292
+ const userModel = model.$container.declarations.find((decl) => (0, ast_1.isDataModel)(decl) && decl.name === 'User');
293
+ if (!userModel) {
294
+ throw new sdk_1.PluginError('User model not found');
295
+ }
296
+ const userIdField = (0, ast_utils_1.getIdField)(userModel);
297
+ if (!userIdField) {
298
+ throw new sdk_1.PluginError('User model does not have an id field');
299
+ }
300
+ // normalize user to null to avoid accidentally use undefined in filter
301
+ func.addStatements(`const user = context.user ?? null;`);
302
+ }
303
+ // r = <guard object>;
304
+ func.addStatements((writer) => {
305
+ writer.write('return ');
306
+ const exprWriter = new expression_writer_1.ExpressionWriter(writer, kind === 'postUpdate');
307
+ const writeDenies = () => {
308
+ writer.conditionalWrite(denies.length > 1, '{ AND: [');
309
+ denies.forEach((expr, i) => {
310
+ writer.inlineBlock(() => {
311
+ writer.write('NOT: ');
312
+ exprWriter.write(expr);
313
+ });
314
+ writer.conditionalWrite(i !== denies.length - 1, ',');
315
+ });
316
+ writer.conditionalWrite(denies.length > 1, ']}');
317
+ };
318
+ const writeAllows = () => {
319
+ writer.conditionalWrite(allows.length > 1, '{ OR: [');
320
+ allows.forEach((expr, i) => {
321
+ exprWriter.write(expr);
322
+ writer.conditionalWrite(i !== allows.length - 1, ',');
323
+ });
324
+ writer.conditionalWrite(allows.length > 1, ']}');
325
+ };
326
+ if (allows.length > 0 && denies.length > 0) {
327
+ writer.write('{ AND: [');
328
+ writeDenies();
329
+ writer.write(',');
330
+ writeAllows();
331
+ writer.write(']}');
332
+ }
333
+ else if (denies.length > 0) {
334
+ writeDenies();
335
+ }
336
+ else if (allows.length > 0) {
337
+ writeAllows();
338
+ }
339
+ else {
340
+ // disallow any operation
341
+ writer.write(`{ ${sdk_1.GUARD_FIELD_NAME}: false }`);
342
+ }
343
+ writer.write(';');
344
+ });
345
+ return func;
346
+ }
347
+ }
348
+ exports.default = PolicyGenerator;
349
+ //# sourceMappingURL=policy-guard-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"policy-guard-generator.js","sourceRoot":"","sources":["../../../src/plugins/access-policy/policy-guard-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { Expression } from '@zenstackhq/language/ast';
2
+ /**
3
+ * Transforms ZModel expression to plain TypeScript expression.
4
+ */
5
+ export default class TypeScriptExpressionTransformer {
6
+ private readonly isPostGuard;
7
+ /**
8
+ * Constructs a new TypeScriptExpressionTransformer.
9
+ *
10
+ * @param isPostGuard indicates if we're writing for post-update conditions
11
+ */
12
+ constructor(isPostGuard?: boolean);
13
+ /**
14
+ *
15
+ * @param expr
16
+ * @returns
17
+ */
18
+ transform(expr: Expression): string;
19
+ private this;
20
+ private memberAccess;
21
+ private invocation;
22
+ private reference;
23
+ private null;
24
+ private array;
25
+ private literal;
26
+ }
@@ -0,0 +1,111 @@
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 ast_utils_1 = require("../../utils/ast-utils");
6
+ const utils_1 = require("./utils");
7
+ /**
8
+ * Transforms ZModel expression to plain TypeScript expression.
9
+ */
10
+ class TypeScriptExpressionTransformer {
11
+ /**
12
+ * Constructs a new TypeScriptExpressionTransformer.
13
+ *
14
+ * @param isPostGuard indicates if we're writing for post-update conditions
15
+ */
16
+ constructor(isPostGuard = false) {
17
+ this.isPostGuard = isPostGuard;
18
+ }
19
+ /**
20
+ *
21
+ * @param expr
22
+ * @returns
23
+ */
24
+ transform(expr) {
25
+ switch (expr.$type) {
26
+ case ast_1.LiteralExpr:
27
+ return this.literal(expr);
28
+ case ast_1.ArrayExpr:
29
+ return this.array(expr);
30
+ case ast_1.NullExpr:
31
+ return this.null();
32
+ case ast_1.ThisExpr:
33
+ return this.this(expr);
34
+ case ast_1.ReferenceExpr:
35
+ return this.reference(expr);
36
+ case ast_1.InvocationExpr:
37
+ return this.invocation(expr);
38
+ case ast_1.MemberAccessExpr:
39
+ return this.memberAccess(expr);
40
+ default:
41
+ throw new sdk_1.PluginError(`Unsupported expression type: ${expr.$type}`);
42
+ }
43
+ }
44
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
45
+ this(expr) {
46
+ // "this" is mapped to id comparison
47
+ return 'id';
48
+ }
49
+ memberAccess(expr) {
50
+ if (!expr.member.ref) {
51
+ throw new sdk_1.PluginError(`Unresolved MemberAccessExpr`);
52
+ }
53
+ if ((0, ast_1.isThisExpr)(expr.operand)) {
54
+ return expr.member.ref.name;
55
+ }
56
+ else if ((0, utils_1.isFutureExpr)(expr.operand)) {
57
+ if (!this.isPostGuard) {
58
+ throw new sdk_1.PluginError(`future() is only supported in postUpdate rules`);
59
+ }
60
+ return expr.member.ref.name;
61
+ }
62
+ else {
63
+ // normalize field access to null instead of undefined to avoid accidentally use undefined in filter
64
+ return `(${this.transform(expr.operand)} ? ${this.transform(expr.operand)}.${expr.member.ref.name} : null)`;
65
+ }
66
+ }
67
+ invocation(expr) {
68
+ var _a;
69
+ if ((0, ast_utils_1.isAuthInvocation)(expr)) {
70
+ return 'user';
71
+ }
72
+ else {
73
+ throw new sdk_1.PluginError(`Function invocation is not supported: ${(_a = expr.function.ref) === null || _a === void 0 ? void 0 : _a.name}`);
74
+ }
75
+ }
76
+ reference(expr) {
77
+ if (!expr.target.ref) {
78
+ throw new sdk_1.PluginError(`Unresolved ReferenceExpr`);
79
+ }
80
+ if ((0, ast_1.isEnumField)(expr.target.ref)) {
81
+ return `${expr.target.ref.$container.name}.${expr.target.ref.name}`;
82
+ }
83
+ else {
84
+ if (this.isPostGuard) {
85
+ // if we're processing post-update, any direct field access should be
86
+ // treated as access to context.preValue, which is entity's value before
87
+ // the update
88
+ return `context.preValue?.${expr.target.ref.name}`;
89
+ }
90
+ else {
91
+ return expr.target.ref.name;
92
+ }
93
+ }
94
+ }
95
+ null() {
96
+ return 'null';
97
+ }
98
+ array(expr) {
99
+ return `[${expr.items.map((item) => this.transform(item)).join(', ')}]`;
100
+ }
101
+ literal(expr) {
102
+ if (typeof expr.value === 'string') {
103
+ return `'${expr.value}'`;
104
+ }
105
+ else {
106
+ return expr.value.toString();
107
+ }
108
+ }
109
+ }
110
+ exports.default = TypeScriptExpressionTransformer;
111
+ //# sourceMappingURL=typescript-expression-transformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typescript-expression-transformer.js","sourceRoot":"","sources":["../../../src/plugins/access-policy/typescript-expression-transformer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import { Expression } from '@zenstackhq/language/ast';
2
+ /**
3
+ * Returns if the given expression is a "future()" method call.
4
+ */
5
+ export declare function isFutureExpr(expr: Expression): boolean;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isFutureExpr = void 0;
4
+ const ast_1 = require("@zenstackhq/language/ast");
5
+ const utils_1 = require("../../language-server/utils");
6
+ /**
7
+ * Returns if the given expression is a "future()" method call.
8
+ */
9
+ function isFutureExpr(expr) {
10
+ var _a;
11
+ return !!((0, ast_1.isInvocationExpr)(expr) && ((_a = expr.function.ref) === null || _a === void 0 ? void 0 : _a.name) === 'future' && (0, utils_1.isFromStdlib)(expr.function.ref));
12
+ }
13
+ exports.isFutureExpr = isFutureExpr;
14
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/plugins/access-policy/utils.ts"],"names":[],"mappings":";;;AAAA,kDAAwE;AACxE,uDAA2D;AAE3D;;GAEG;AACH,SAAgB,YAAY,CAAC,IAAgB;;IACzC,OAAO,CAAC,CAAC,CAAC,IAAA,sBAAgB,EAAC,IAAI,CAAC,IAAI,CAAA,MAAA,IAAI,CAAC,QAAQ,CAAC,GAAG,0CAAE,IAAI,MAAK,QAAQ,IAAI,IAAA,oBAAY,EAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AACjH,CAAC;AAFD,oCAEC"}
@@ -0,0 +1,12 @@
1
+ import { DataModel } from '@zenstackhq/language/ast';
2
+ import { CodeBlockWriter } from 'ts-morph';
3
+ /**
4
+ * Writes Zod schema for data models.
5
+ */
6
+ export declare class ZodSchemaGenerator {
7
+ generate(writer: CodeBlockWriter, models: DataModel[]): void;
8
+ private hasValidationAttributes;
9
+ private makeFieldValidator;
10
+ private makeZodSchema;
11
+ private getAttrLiteralArg;
12
+ }