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
@@ -1,138 +0,0 @@
1
- import {
2
- DataSourceUrl,
3
- PrismaModel,
4
- FieldAttribute,
5
- AttributeArg,
6
- FunctionCall,
7
- AttributeArgValue,
8
- ModelFieldType,
9
- FieldReference,
10
- FieldReferenceArg,
11
- } from '../../src/generator/prisma/prisma-builder';
12
- import { getDMMF } from '@prisma/internals';
13
-
14
- async function validate(model: PrismaModel) {
15
- const content = model.toString();
16
- try {
17
- return await getDMMF({ datamodel: content });
18
- } catch (err) {
19
- console.error(`Failed to load DMMF: ${err}`);
20
- throw err;
21
- }
22
- }
23
-
24
- describe('Prisma Builder Tests', () => {
25
- it('datasource', async () => {
26
- let model = new PrismaModel();
27
- model.addDataSource(
28
- 'db',
29
- 'postgresql',
30
- new DataSourceUrl('DATABASE_URL', true)
31
- );
32
- await validate(model);
33
-
34
- model = new PrismaModel();
35
- model.addDataSource(
36
- 'db',
37
- 'postgresql',
38
- new DataSourceUrl(
39
- 'postgresql://postgres:abc123@localhost:5432/sample?schema=public',
40
- false
41
- )
42
- );
43
- await validate(model);
44
- });
45
-
46
- it('enum', async () => {
47
- let model = new PrismaModel();
48
- model.addEnum('UserRole', ['USER', 'ADMIN']);
49
- await validate(model);
50
- });
51
-
52
- it('generator', async () => {
53
- let model = new PrismaModel();
54
- model.addGenerator('client', 'prisma-client-js', '.prisma');
55
- await validate(model);
56
- });
57
-
58
- it('model', async () => {
59
- let model = new PrismaModel();
60
- const dm = model.addModel('User');
61
- dm.addField('id', 'String', [new FieldAttribute('id')]);
62
- dm.addField('createdAt', 'DateTime', [
63
- new FieldAttribute('default', [
64
- new AttributeArg(
65
- undefined,
66
- new AttributeArgValue(
67
- 'FunctionCall',
68
- new FunctionCall('now')
69
- )
70
- ),
71
- ]),
72
- ]);
73
- await validate(model);
74
- });
75
-
76
- it('relation', async () => {
77
- let model = new PrismaModel();
78
- const user = model.addModel('User');
79
- user.addField('id', 'String', [new FieldAttribute('id')]);
80
- user.addField('posts', new ModelFieldType('Post', true));
81
-
82
- const post = model.addModel('Post');
83
- post.addField('id', 'String', [new FieldAttribute('id')]);
84
- post.addField('user', 'User', [
85
- new FieldAttribute('relation', [
86
- new AttributeArg(
87
- 'fields',
88
- new AttributeArgValue('Array', [
89
- new AttributeArgValue('FieldReference', 'userId'),
90
- ])
91
- ),
92
- new AttributeArg(
93
- 'references',
94
- new AttributeArgValue('Array', [
95
- new AttributeArgValue('FieldReference', 'id'),
96
- ])
97
- ),
98
- new AttributeArg(
99
- 'onDelete',
100
- new AttributeArgValue(
101
- 'FieldReference',
102
- new FieldReference('Cascade')
103
- )
104
- ),
105
- ]),
106
- ]);
107
- post.addField('userId', 'String');
108
-
109
- await validate(model);
110
- });
111
-
112
- it('model attribute', async () => {
113
- let model = new PrismaModel();
114
- const post = model.addModel('Post');
115
- post.addField('id', 'String', [new FieldAttribute('id')]);
116
- post.addField('slug', 'String');
117
- post.addField('space', 'String');
118
- post.addAttribute('unique', [
119
- new AttributeArg(
120
- 'fields',
121
- new AttributeArgValue('Array', [
122
- new AttributeArgValue(
123
- 'FieldReference',
124
- new FieldReference('space')
125
- ),
126
- new AttributeArgValue(
127
- 'FieldReference',
128
- new FieldReference('slug', [
129
- new FieldReferenceArg('sort', 'Desc'),
130
- ])
131
- ),
132
- ])
133
- ),
134
- ]);
135
-
136
- await validate(model);
137
- });
138
- });
@@ -1,423 +0,0 @@
1
- import {
2
- BinaryExpr,
3
- LiteralExpr,
4
- InvocationExpr,
5
- DataSource,
6
- DataModel,
7
- Function,
8
- AttributeArg,
9
- Enum,
10
- UnaryExpr,
11
- ReferenceExpr,
12
- ArrayExpr,
13
- } from '../../src/language-server/generated/ast';
14
- import { loadModel } from '../utils';
15
-
16
- describe('Basic Tests', () => {
17
- it('data source', async () => {
18
- const content = `
19
- datasource db {
20
- provider = 'postgresql'
21
- url = env('DATABASE_URL')
22
- }
23
- `;
24
- const doc = await loadModel(content);
25
- expect(doc.declarations).toHaveLength(1);
26
- const ds = doc.declarations[0] as DataSource;
27
-
28
- expect(ds.name).toBe('db');
29
- expect(ds.fields).toHaveLength(2);
30
-
31
- expect(ds.fields[0]).toEqual(
32
- expect.objectContaining({
33
- name: 'provider',
34
- value: expect.objectContaining({ value: 'postgresql' }),
35
- })
36
- );
37
- expect(ds.fields[1].name).toBe('url');
38
- expect((ds.fields[1].value as InvocationExpr).function.ref?.name).toBe(
39
- 'env'
40
- );
41
- expect((ds.fields[1].value as InvocationExpr).args[0].value.$type).toBe(
42
- LiteralExpr
43
- );
44
- });
45
-
46
- it('enum', async () => {
47
- const content = `
48
- enum UserRole {
49
- USER
50
- ADMIN
51
- }
52
-
53
- model User {
54
- role UserRole @default(USER)
55
- }
56
- `;
57
- const doc = await loadModel(content);
58
- const enumDecl = doc.declarations[0];
59
- expect(enumDecl.name).toBe('UserRole');
60
- expect((enumDecl as Enum).fields.map((f) => f.name)).toEqual(
61
- expect.arrayContaining(['USER', 'ADMIN'])
62
- );
63
-
64
- const model = doc.declarations[1] as DataModel;
65
- expect(model.fields[0].type.reference?.ref?.name).toBe('UserRole');
66
-
67
- const attrVal = model.fields[0].attributes[0].args[0] as AttributeArg;
68
- expect((attrVal.value as ReferenceExpr).target.ref?.name).toBe('USER');
69
- });
70
-
71
- it('model field types', async () => {
72
- const content = `
73
- model User {
74
- id String
75
- age Int
76
- activated Boolean
77
- createdAt DateTime
78
- metadata JSON
79
- }
80
- `;
81
- const doc = await loadModel(content);
82
- const model = doc.declarations[0] as DataModel;
83
- expect(model.fields).toHaveLength(5);
84
- expect(model.fields.map((f) => f.type.type)).toEqual(
85
- expect.arrayContaining([
86
- 'String',
87
- 'Int',
88
- 'Boolean',
89
- 'JSON',
90
- 'DateTime',
91
- ])
92
- );
93
- });
94
-
95
- it('model field modifiers', async () => {
96
- const content = `
97
- model User {
98
- name String?
99
- tags String[]
100
- }
101
- `;
102
- const doc = await loadModel(content);
103
- const model = doc.declarations[0] as DataModel;
104
- expect(model.fields[0].type.optional).toBeTruthy();
105
- expect(model.fields[1].type.array).toBeTruthy();
106
- });
107
-
108
- it('model field attributes', async () => {
109
- const content = `
110
- model User {
111
- id String @id
112
- activated Boolean @default(false) @unique
113
- }
114
- `;
115
- const doc = await loadModel(content);
116
- const model = doc.declarations[0] as DataModel;
117
- expect(model.fields[0].attributes[0].decl.ref?.name).toBe('id');
118
- expect(model.fields[1].attributes[0].args[0].value.$type).toBe(
119
- LiteralExpr
120
- );
121
- expect(model.fields[1].attributes[1].decl.ref?.name).toBe('unique');
122
- });
123
-
124
- it('model attributes', async () => {
125
- const content = `
126
- model Model {
127
- a String
128
- b String
129
- @@unique([a, b])
130
- @@unique([a(sort: Asc), b])
131
- @@unique(b(sort: Desc))
132
- }
133
- `;
134
- const doc = await loadModel(content);
135
- const model = doc.declarations[0] as DataModel;
136
- expect(model.attributes).toHaveLength(3);
137
- expect(model.attributes[0].decl.ref?.name).toBe('unique');
138
- expect(
139
- (model.attributes[0].args[0].value as ArrayExpr).items.map(
140
- (item) => (item as ReferenceExpr).target.ref?.name
141
- )
142
- ).toEqual(expect.arrayContaining(['a', 'b']));
143
-
144
- expect(
145
- (
146
- (model.attributes[1].args[0].value as ArrayExpr)
147
- .items[0] as ReferenceExpr
148
- ).args[0]
149
- ).toEqual(
150
- expect.objectContaining({
151
- name: 'sort',
152
- value: 'Asc',
153
- })
154
- );
155
-
156
- expect(
157
- (model.attributes[2].args[0].value as ReferenceExpr).target.ref
158
- ?.name
159
- ).toBe('b');
160
- expect(
161
- (model.attributes[2].args[0].value as ReferenceExpr).args[0]
162
- ).toEqual(
163
- expect.objectContaining({
164
- name: 'sort',
165
- value: 'Desc',
166
- })
167
- );
168
- });
169
-
170
- it('model relation', async () => {
171
- const content = `
172
- model User {
173
- id String
174
- posts Post[]
175
- }
176
-
177
- model Post {
178
- id String
179
- owner User @relation(references: [id], onDelete: Cascade, onUpdate: Cascade)
180
- }
181
- `;
182
- const doc = await loadModel(content);
183
- const models = doc.declarations as DataModel[];
184
- expect(models[0].fields[1].type.reference?.ref?.name === 'Post');
185
- expect(models[1].fields[1].type.reference?.ref?.name === 'User');
186
- });
187
-
188
- it('policy expressions', async () => {
189
- const content = `
190
- model Model {
191
- a Int
192
- b Int
193
- c Boolean
194
-
195
- @@deny('all', !c)
196
- @@deny('all', a < 0)
197
- // @@deny(a + b < 10)
198
- }
199
- `;
200
- const doc = await loadModel(content);
201
- const model = doc.declarations[0] as DataModel;
202
- const attrs = model.attributes;
203
-
204
- expect(attrs[0].args[1].value.$type).toBe(UnaryExpr);
205
- expect((attrs[0].args[1].value as UnaryExpr).operand.$type).toBe(
206
- ReferenceExpr
207
- );
208
-
209
- expect(attrs[1].args[1].value.$type).toBe(BinaryExpr);
210
- expect((attrs[1].args[1].value as BinaryExpr).left.$type).toBe(
211
- ReferenceExpr
212
- );
213
- expect((attrs[1].args[1].value as BinaryExpr).right.$type).toBe(
214
- LiteralExpr
215
- );
216
-
217
- expect(attrs[1].args[1].value.$type).toBe(BinaryExpr);
218
- expect((attrs[1].args[1].value as BinaryExpr).left.$type).toBe(
219
- ReferenceExpr
220
- );
221
- expect((attrs[1].args[1].value as BinaryExpr).right.$type).toBe(
222
- LiteralExpr
223
- );
224
-
225
- // expect(attrs[2].args[0].value.$type).toBe(BinaryExpr);
226
- // expect((attrs[2].args[0].value as BinaryExpr).left.$type).toBe(
227
- // BinaryExpr
228
- // );
229
- });
230
-
231
- it('policy expression precedence', async () => {
232
- const content = `
233
- model Model {
234
- a Int
235
- b Int
236
- // @@deny(a + b * 2 > 0)
237
- // @@deny((a + b) * 2 > 0)
238
- @@deny('all', a > 0 && b < 0)
239
- @@deny('all', a >= 0 && b <= 0)
240
- @@deny('all', a == 0 || b != 0)
241
- }
242
- `;
243
-
244
- await loadModel(content);
245
-
246
- // const doc = await loadModel(content);
247
- // const attrs = (doc.declarations[0] as DataModel).attributes;
248
-
249
- // expect(attrs[0].args[0].value.$type).toBe(BinaryExpr);
250
-
251
- // // 1: a + b * 2 > 0
252
-
253
- // // >
254
- // expect((attrs[0].args[0].value as BinaryExpr).operator).toBe('>');
255
-
256
- // // a + b * 2
257
- // expect((attrs[0].args[0].value as BinaryExpr).left.$type).toBe(
258
- // BinaryExpr
259
- // );
260
-
261
- // // 0
262
- // expect((attrs[0].args[0].value as BinaryExpr).right.$type).toBe(
263
- // LiteralExpr
264
- // );
265
-
266
- // // +
267
- // expect(
268
- // ((attrs[0].args[0].value as BinaryExpr).left as BinaryExpr).operator
269
- // ).toBe('+');
270
-
271
- // // a
272
- // expect(
273
- // ((attrs[0].args[0].value as BinaryExpr).left as BinaryExpr).left
274
- // .$type
275
- // ).toBe(ReferenceExpr);
276
-
277
- // // b * 2
278
- // expect(
279
- // ((attrs[0].args[0].value as BinaryExpr).left as BinaryExpr).right
280
- // .$type
281
- // ).toBe(BinaryExpr);
282
-
283
- // // 2: (a + b) * 2 > 0
284
-
285
- // // >
286
- // expect((attrs[1].args[0].value as BinaryExpr).operator).toBe('>');
287
-
288
- // // (a + b) * 2
289
- // expect((attrs[1].args[0].value as BinaryExpr).left.$type).toBe(
290
- // BinaryExpr
291
- // );
292
-
293
- // // 0
294
- // expect((attrs[1].args[0].value as BinaryExpr).right.$type).toBe(
295
- // LiteralExpr
296
- // );
297
-
298
- // // *
299
- // expect(
300
- // ((attrs[1].args[0].value as BinaryExpr).left as BinaryExpr).operator
301
- // ).toBe('*');
302
-
303
- // // (a + b)
304
- // expect(
305
- // ((attrs[1].args[0].value as BinaryExpr).left as BinaryExpr).left
306
- // .$type
307
- // ).toBe(BinaryExpr);
308
-
309
- // // a
310
- // expect(
311
- // (
312
- // ((attrs[1].args[0].value as BinaryExpr).left as BinaryExpr)
313
- // .left as BinaryExpr
314
- // ).left.$type
315
- // ).toBe(ReferenceExpr);
316
-
317
- // // b
318
- // expect(
319
- // (
320
- // ((attrs[1].args[0].value as BinaryExpr).left as BinaryExpr)
321
- // .left as BinaryExpr
322
- // ).right.$type
323
- // ).toBe(ReferenceExpr);
324
-
325
- // // 2
326
- // expect(
327
- // ((attrs[1].args[0].value as BinaryExpr).left as BinaryExpr).right
328
- // .$type
329
- // ).toBe(LiteralExpr);
330
- });
331
-
332
- it('function', async () => {
333
- const content = `
334
- model M {
335
- a Int
336
- b Int
337
- c N[]
338
- @@deny('all', foo(a, b))
339
- @@deny('all', bar(c))
340
- }
341
-
342
- model N {
343
- x Int
344
- }
345
-
346
- function foo(a Int, b Int) Boolean {
347
- }
348
-
349
- function bar(items N[]) Boolean {
350
- }
351
- `;
352
- const doc = await loadModel(content);
353
- const model = doc.declarations[0] as DataModel;
354
- const foo = doc.declarations[2] as Function;
355
- const bar = doc.declarations[3] as Function;
356
-
357
- expect(foo.name).toBe('foo');
358
- expect(foo.params.map((p) => p.type.type)).toEqual(
359
- expect.arrayContaining(['Int', 'Int'])
360
- );
361
-
362
- expect(bar.name).toBe('bar');
363
- expect(bar.params[0].type.reference?.ref?.name).toBe('N');
364
- expect(bar.params[0].type.array).toBeTruthy();
365
-
366
- expect(model.attributes[0].args[1].value.$type).toBe(InvocationExpr);
367
- });
368
-
369
- it('member access', async () => {
370
- const content = `
371
- model M {
372
- a N
373
- @@deny('all', a.x.y < 0)
374
- @@deny('all', foo(a))
375
- }
376
-
377
- model N {
378
- x P
379
- }
380
-
381
- model P {
382
- y Int
383
- }
384
-
385
- function foo(n N) Boolean {
386
- n.x < 0
387
- }
388
- `;
389
- await loadModel(content);
390
- });
391
-
392
- it('collection predicate', async () => {
393
- const content = `
394
- model M {
395
- n N[]
396
- @@deny('all', n?[x < 0])
397
- }
398
-
399
- model N {
400
- x Int
401
- }
402
- `;
403
- await loadModel(content);
404
- });
405
-
406
- it('collection predicate chained', async () => {
407
- const content = `
408
- model M {
409
- n N[]
410
- @@deny('all', n?[p?[x < 0]])
411
- }
412
-
413
- model N {
414
- p P[]
415
- }
416
-
417
- model P {
418
- x Int
419
- }
420
- `;
421
- await loadModel(content);
422
- });
423
- });
@@ -1,14 +0,0 @@
1
- import { loadModel } from '../utils';
2
- import * as fs from 'fs';
3
-
4
- describe('Basic Tests', () => {
5
- it('sample todo schema', async () => {
6
- const content = fs.readFileSync(
7
- '../../samples/todo/zenstack/schema.zmodel',
8
- {
9
- encoding: 'utf-8',
10
- }
11
- );
12
- await loadModel(content);
13
- });
14
- });
@@ -1,38 +0,0 @@
1
- import { createZModelServices } from '../src/language-server/zmodel-module';
2
- import { URI } from 'vscode-uri';
3
- import * as fs from 'fs';
4
- import * as path from 'path';
5
- import { Model } from '../src/language-server/generated/ast';
6
- import * as tmp from 'tmp';
7
-
8
- export async function loadModel(content: string) {
9
- const { name: docPath } = tmp.fileSync({ postfix: '.zmodel' });
10
- fs.writeFileSync(docPath, content);
11
- const { shared } = createZModelServices();
12
- const stdLib = shared.workspace.LangiumDocuments.getOrCreateDocument(
13
- URI.file(path.resolve('src/language-server/stdlib.zmodel'))
14
- );
15
- const doc = shared.workspace.LangiumDocuments.getOrCreateDocument(
16
- URI.file(docPath)
17
- );
18
- await shared.workspace.DocumentBuilder.build([stdLib, doc], {
19
- validationChecks: 'all',
20
- });
21
-
22
- const validationErrors = (doc.diagnostics ?? []).filter(
23
- (e) => e.severity === 1
24
- );
25
- if (validationErrors.length > 0) {
26
- for (const validationError of validationErrors) {
27
- console.error(
28
- `line ${validationError.range.start.line + 1}: ${
29
- validationError.message
30
- } [${doc.textDocument.getText(validationError.range)}]`
31
- );
32
- }
33
- throw new Error('Validation error');
34
- }
35
-
36
- const model = (await doc.parseResult.value) as Model;
37
- return model;
38
- }
@@ -1,23 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES6",
4
- "module": "commonjs",
5
- "lib": ["ESNext"],
6
- "sourceMap": true,
7
- "outDir": "out",
8
- "strict": true,
9
- "noUnusedLocals": true,
10
- "noImplicitReturns": true,
11
- "moduleResolution": "node",
12
- "esModuleInterop": true,
13
- "skipLibCheck": true,
14
- "forceConsistentCasingInFileNames": true,
15
- "baseUrl": ".",
16
- "paths": {
17
- "@lang/*": ["src/language-server/*"]
18
- },
19
- "resolveJsonModule": true
20
- },
21
- "include": ["src/**/*.ts"],
22
- "exclude": ["out", "node_modules"]
23
- }
@@ -1,3 +0,0 @@
1
- packages:
2
- - 'packages/*'
3
- - 'tests/*'
package/samples/todo/.env DELETED
@@ -1,2 +0,0 @@
1
- NEXTAUTH_SECRET=abc123
2
- DATABASE_URL="postgresql://postgres:abc123@localhost:5432/todo?schema=public"
@@ -1,3 +0,0 @@
1
- {
2
- "extends": ["next/core-web-vitals"]
3
- }
@@ -1,11 +0,0 @@
1
- {
2
- "version": "0.2.0",
3
- "configurations": [
4
- {
5
- "name": "Next.js: debug server-side",
6
- "type": "node-terminal",
7
- "request": "launch",
8
- "command": "npm run dev"
9
- }
10
- ]
11
- }
@@ -1,34 +0,0 @@
1
- This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
2
-
3
- ## Getting Started
4
-
5
- First, run the development server:
6
-
7
- ```bash
8
- npm run dev
9
- # or
10
- yarn dev
11
- ```
12
-
13
- Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
14
-
15
- You can start editing the page by modifying `pages/index.tsx`. The page auto-updates as you edit the file.
16
-
17
- [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.ts`.
18
-
19
- The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
20
-
21
- ## Learn More
22
-
23
- To learn more about Next.js, take a look at the following resources:
24
-
25
- - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
26
- - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
27
-
28
- You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
29
-
30
- ## Deploy on Vercel
31
-
32
- The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
33
-
34
- Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.