zenstack 1.0.0 → 1.0.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +126 -1
- package/bin/cli +3 -0
- package/bin/post-install.js +24 -0
- package/cli/cli-error.d.ts +5 -0
- package/cli/cli-error.js +10 -0
- package/cli/cli-error.js.map +1 -0
- package/cli/cli-util.d.ts +18 -0
- package/cli/cli-util.js +143 -0
- package/cli/cli-util.js.map +1 -0
- package/cli/index.d.ts +15 -0
- package/cli/index.js +121 -0
- package/cli/index.js.map +1 -0
- package/cli/plugin-runner.d.ts +14 -0
- package/cli/plugin-runner.js +145 -0
- package/cli/plugin-runner.js.map +1 -0
- package/constants.d.ts +1 -0
- package/constants.js +6 -0
- package/constants.js.map +1 -0
- package/language-server/constants.d.ts +15 -0
- package/language-server/constants.js +20 -0
- package/language-server/constants.js.map +1 -0
- package/language-server/main.d.ts +1 -0
- package/language-server/main.js +13 -0
- package/language-server/main.js.map +1 -0
- package/language-server/types.d.ts +10 -0
- package/language-server/types.js +3 -0
- package/language-server/types.js.map +1 -0
- package/language-server/utils.d.ts +18 -0
- package/language-server/utils.js +58 -0
- package/language-server/utils.js.map +1 -0
- package/language-server/validator/attribute-validator.d.ts +9 -0
- package/language-server/validator/attribute-validator.js +11 -0
- package/language-server/validator/attribute-validator.js.map +1 -0
- package/language-server/validator/datamodel-validator.d.ts +15 -0
- package/language-server/validator/datamodel-validator.js +278 -0
- package/language-server/validator/datamodel-validator.js.map +1 -0
- package/language-server/validator/datasource-validator.d.ts +12 -0
- package/language-server/validator/datasource-validator.js +66 -0
- package/language-server/validator/datasource-validator.js.map +1 -0
- package/language-server/validator/enum-validator.d.ts +11 -0
- package/language-server/validator/enum-validator.js +28 -0
- package/language-server/validator/enum-validator.js.map +1 -0
- package/language-server/validator/expression-validator.d.ts +10 -0
- package/language-server/validator/expression-validator.js +30 -0
- package/language-server/validator/expression-validator.js.map +1 -0
- package/language-server/validator/schema-validator.d.ts +10 -0
- package/language-server/validator/schema-validator.js +28 -0
- package/language-server/validator/schema-validator.js.map +1 -0
- package/language-server/validator/utils.d.ts +25 -0
- package/language-server/validator/utils.js +257 -0
- package/language-server/validator/utils.js.map +1 -0
- package/language-server/validator/zmodel-validator.d.ts +21 -0
- package/language-server/validator/zmodel-validator.js +69 -0
- package/language-server/validator/zmodel-validator.js.map +1 -0
- package/language-server/zmodel-code-action.d.ts +14 -0
- package/language-server/zmodel-code-action.js +93 -0
- package/language-server/zmodel-code-action.js.map +1 -0
- package/language-server/zmodel-formatter.d.ts +9 -0
- package/language-server/zmodel-formatter.js +76 -0
- package/language-server/zmodel-formatter.js.map +1 -0
- package/language-server/zmodel-linker.d.ts +29 -0
- package/language-server/zmodel-linker.js +366 -0
- package/language-server/zmodel-linker.js.map +1 -0
- package/language-server/zmodel-module.d.ts +41 -0
- package/language-server/zmodel-module.js +80 -0
- package/language-server/zmodel-module.js.map +1 -0
- package/language-server/zmodel-scope.d.ts +10 -0
- package/language-server/zmodel-scope.js +44 -0
- package/language-server/zmodel-scope.js.map +1 -0
- package/language-server/zmodel-workspace-manager.d.ts +8 -0
- package/language-server/zmodel-workspace-manager.js +37 -0
- package/language-server/zmodel-workspace-manager.js.map +1 -0
- package/package.json +133 -8
- package/plugins/access-policy/expression-writer.d.ts +39 -0
- package/plugins/access-policy/expression-writer.js +361 -0
- package/plugins/access-policy/expression-writer.js.map +1 -0
- package/plugins/access-policy/index.d.ts +4 -0
- package/plugins/access-policy/index.js +24 -0
- package/plugins/access-policy/index.js.map +1 -0
- package/plugins/access-policy/policy-guard-generator.d.ts +15 -0
- package/plugins/access-policy/policy-guard-generator.js +349 -0
- package/plugins/access-policy/policy-guard-generator.js.map +1 -0
- package/plugins/access-policy/typescript-expression-transformer.d.ts +26 -0
- package/plugins/access-policy/typescript-expression-transformer.js +111 -0
- package/plugins/access-policy/typescript-expression-transformer.js.map +1 -0
- package/plugins/access-policy/utils.d.ts +5 -0
- package/plugins/access-policy/utils.js +14 -0
- package/plugins/access-policy/utils.js.map +1 -0
- package/plugins/access-policy/zod-schema-generator.d.ts +12 -0
- package/plugins/access-policy/zod-schema-generator.js +158 -0
- package/plugins/access-policy/zod-schema-generator.js.map +1 -0
- package/plugins/model-meta/index.d.ts +4 -0
- package/plugins/model-meta/index.js +168 -0
- package/plugins/model-meta/index.js.map +1 -0
- package/plugins/plugin-utils.d.ts +16 -0
- package/plugins/plugin-utils.js +54 -0
- package/plugins/plugin-utils.js.map +1 -0
- package/plugins/prisma/indent-string.d.ts +4 -0
- package/plugins/prisma/indent-string.js +12 -0
- package/plugins/prisma/indent-string.js.map +1 -0
- package/plugins/prisma/index.d.ts +4 -0
- package/plugins/prisma/index.js +24 -0
- package/plugins/prisma/index.js.map +1 -0
- package/plugins/prisma/prisma-builder.d.ts +152 -0
- package/plugins/prisma/prisma-builder.js +363 -0
- package/plugins/prisma/prisma-builder.js.map +1 -0
- package/plugins/prisma/schema-generator.d.ts +25 -0
- package/plugins/prisma/schema-generator.js +292 -0
- package/plugins/prisma/schema-generator.js.map +1 -0
- package/plugins/prisma/zmodel-code-generator.d.ts +28 -0
- package/plugins/prisma/zmodel-code-generator.js +114 -0
- package/plugins/prisma/zmodel-code-generator.js.map +1 -0
- package/res/prism-zmodel.js +20 -0
- package/res/starter.zmodel +51 -0
- package/res/stdlib.zmodel +346 -0
- package/telemetry.d.ts +20 -0
- package/telemetry.js +119 -0
- package/telemetry.js.map +1 -0
- package/types.d.ts +12 -0
- package/types.js +3 -0
- package/types.js.map +1 -0
- package/utils/ast-utils.d.ts +16 -0
- package/utils/ast-utils.js +85 -0
- package/utils/ast-utils.js.map +1 -0
- package/utils/exec-utils.d.ts +6 -0
- package/utils/exec-utils.js +13 -0
- package/utils/exec-utils.js.map +1 -0
- package/utils/pkg-utils.d.ts +3 -0
- package/utils/pkg-utils.js +46 -0
- package/utils/pkg-utils.js.map +1 -0
- package/utils/version-utils.d.ts +1 -0
- package/utils/version-utils.js +14 -0
- package/utils/version-utils.js.map +1 -0
- package/.vscode/extensions.json +0 -7
- package/.vscode/launch.json +0 -49
- package/.vscode/settings.json +0 -4
- package/packages/internal/jest.config.ts +0 -32
- package/packages/internal/package.json +0 -42
- package/packages/internal/src/constants.ts +0 -1
- package/packages/internal/src/handler/data/guard-utils.ts +0 -7
- package/packages/internal/src/handler/data/handler.ts +0 -415
- package/packages/internal/src/handler/data/query-processor.ts +0 -504
- package/packages/internal/src/handler/index.ts +0 -1
- package/packages/internal/src/handler/types.ts +0 -20
- package/packages/internal/src/index.ts +0 -3
- package/packages/internal/src/request-handler.ts +0 -27
- package/packages/internal/src/request.ts +0 -101
- package/packages/internal/src/types.ts +0 -40
- package/packages/internal/tests/query-processor.test.ts +0 -172
- package/packages/internal/tsconfig.json +0 -21
- package/packages/runtime/auth.d.ts +0 -1
- package/packages/runtime/auth.js +0 -3
- package/packages/runtime/hooks.d.ts +0 -10
- package/packages/runtime/hooks.js +0 -3
- package/packages/runtime/index.d.ts +0 -3
- package/packages/runtime/index.js +0 -1
- package/packages/runtime/package-lock.json +0 -512
- package/packages/runtime/package.json +0 -16
- package/packages/runtime/server.d.ts +0 -1
- package/packages/runtime/server.js +0 -3
- package/packages/runtime/types.d.ts +0 -1
- package/packages/runtime/types.js +0 -3
- package/packages/schema/.eslintrc.json +0 -13
- package/packages/schema/.vscodeignore +0 -4
- package/packages/schema/asset/logo-dark.png +0 -0
- package/packages/schema/asset/logo-light.png +0 -0
- package/packages/schema/bin/cli +0 -3
- package/packages/schema/jest.config.ts +0 -32
- package/packages/schema/langium-config.json +0 -14
- package/packages/schema/langium-quickstart.md +0 -41
- package/packages/schema/language-configuration.json +0 -30
- package/packages/schema/package.json +0 -96
- package/packages/schema/src/cli/cli-util.ts +0 -80
- package/packages/schema/src/cli/index.ts +0 -64
- package/packages/schema/src/extension.ts +0 -76
- package/packages/schema/src/generator/constants.ts +0 -5
- package/packages/schema/src/generator/index.ts +0 -92
- package/packages/schema/src/generator/next-auth/index.ts +0 -197
- package/packages/schema/src/generator/package.template.json +0 -9
- package/packages/schema/src/generator/prisma/expression-writer.ts +0 -352
- package/packages/schema/src/generator/prisma/index.ts +0 -32
- package/packages/schema/src/generator/prisma/plain-expression-builder.ts +0 -91
- package/packages/schema/src/generator/prisma/prisma-builder.ts +0 -366
- package/packages/schema/src/generator/prisma/query-gard-generator.ts +0 -208
- package/packages/schema/src/generator/prisma/schema-generator.ts +0 -300
- package/packages/schema/src/generator/react-hooks/index.ts +0 -181
- package/packages/schema/src/generator/service/index.ts +0 -107
- package/packages/schema/src/generator/tsconfig.template.json +0 -17
- package/packages/schema/src/generator/types.ts +0 -17
- package/packages/schema/src/generator/utils.ts +0 -9
- package/packages/schema/src/language-server/generated/ast.ts +0 -603
- package/packages/schema/src/language-server/generated/grammar.ts +0 -2190
- package/packages/schema/src/language-server/generated/module.ts +0 -24
- package/packages/schema/src/language-server/main.ts +0 -12
- package/packages/schema/src/language-server/stdlib.zmodel +0 -22
- package/packages/schema/src/language-server/types.ts +0 -9
- package/packages/schema/src/language-server/zmodel-index.ts +0 -33
- package/packages/schema/src/language-server/zmodel-linker.ts +0 -409
- package/packages/schema/src/language-server/zmodel-module.ts +0 -90
- package/packages/schema/src/language-server/zmodel-scope.ts +0 -21
- package/packages/schema/src/language-server/zmodel-validator.ts +0 -35
- package/packages/schema/src/language-server/zmodel.langium +0 -186
- package/packages/schema/src/utils/exec-utils.ts +0 -5
- package/packages/schema/src/utils/indent-string.ts +0 -6
- package/packages/schema/syntaxes/zmodel.json +0 -57
- package/packages/schema/syntaxes/zmodel.tmLanguage.json +0 -57
- package/packages/schema/tests/generator/expression-writer.test.ts +0 -676
- package/packages/schema/tests/generator/prisma-builder.test.ts +0 -138
- package/packages/schema/tests/schema/parser.test.ts +0 -423
- package/packages/schema/tests/schema/sample-todo.test.ts +0 -14
- package/packages/schema/tests/utils.ts +0 -38
- package/packages/schema/tsconfig.json +0 -23
- package/pnpm-workspace.yaml +0 -3
- package/samples/todo/.env +0 -2
- package/samples/todo/.eslintrc.json +0 -3
- package/samples/todo/.vscode/launch.json +0 -11
- package/samples/todo/README.md +0 -34
- package/samples/todo/components/AuthGuard.tsx +0 -17
- package/samples/todo/components/Avatar.tsx +0 -22
- package/samples/todo/components/BreadCrumb.tsx +0 -44
- package/samples/todo/components/ManageMembers.tsx +0 -134
- package/samples/todo/components/NavBar.tsx +0 -57
- package/samples/todo/components/SpaceMembers.tsx +0 -76
- package/samples/todo/components/Spaces.tsx +0 -28
- package/samples/todo/components/TimeInfo.tsx +0 -17
- package/samples/todo/components/Todo.tsx +0 -72
- package/samples/todo/components/TodoList.tsx +0 -77
- package/samples/todo/lib/context.ts +0 -31
- package/samples/todo/next.config.js +0 -10
- package/samples/todo/package-lock.json +0 -7527
- package/samples/todo/package.json +0 -45
- package/samples/todo/pages/_app.tsx +0 -50
- package/samples/todo/pages/api/auth/[...nextauth].ts +0 -83
- package/samples/todo/pages/api/zenstack/[...path].ts +0 -16
- package/samples/todo/pages/create-space.tsx +0 -114
- package/samples/todo/pages/index.tsx +0 -32
- package/samples/todo/pages/space/[slug]/[listId]/index.tsx +0 -88
- package/samples/todo/pages/space/[slug]/index.tsx +0 -169
- package/samples/todo/postcss.config.js +0 -6
- package/samples/todo/public/avatar.jpg +0 -0
- package/samples/todo/public/favicon.ico +0 -0
- package/samples/todo/public/logo.png +0 -0
- package/samples/todo/public/vercel.svg +0 -4
- package/samples/todo/styles/globals.css +0 -7
- package/samples/todo/tailwind.config.js +0 -11
- package/samples/todo/tsconfig.json +0 -28
- package/samples/todo/types/next-auth.d.ts +0 -14
- package/samples/todo/types/next.d.ts +0 -16
- package/samples/todo/zenstack/migrations/20221014084317_init/migration.sql +0 -153
- package/samples/todo/zenstack/migrations/20221020094651_upate_cli/migration.sql +0 -23
- package/samples/todo/zenstack/migrations/migration_lock.toml +0 -3
- package/samples/todo/zenstack/schema.prisma +0 -126
- package/samples/todo/zenstack/schema.zmodel +0 -161
- package/tests/integration/jest.config.ts +0 -16
- package/tests/integration/package-lock.json +0 -1081
- package/tests/integration/package.json +0 -27
- package/tests/integration/tests/operation-coverate.test.ts +0 -563
- package/tests/integration/tests/operations.zmodel +0 -69
- package/tests/integration/tests/todo-e2e.test.ts +0 -577
- package/tests/integration/tests/todo.zmodel +0 -123
- package/tests/integration/tests/tsconfig.template.json +0 -10
- package/tests/integration/tests/utils.ts +0 -133
- package/tests/integration/tsconfig.json +0 -10
|
@@ -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
|
-
}
|
package/pnpm-workspace.yaml
DELETED
package/samples/todo/.env
DELETED
package/samples/todo/README.md
DELETED
|
@@ -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.
|