zenstack 0.2.9 → 0.2.11
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/README.md +1 -1
- package/bundle/cli/index.js +155 -155
- package/bundle/cli/index.js.map +7 -0
- package/bundle/extension.js.map +7 -0
- package/bundle/language-server/main.js.map +7 -0
- package/package.json +7 -7
- package/src/cli/cli-util.ts +34 -0
- package/src/cli/index.ts +6 -24
- package/src/generator/index.ts +24 -49
- package/src/generator/next-auth/index.ts +4 -0
- package/src/generator/prisma/index.ts +4 -0
- package/src/generator/prisma/query-guard-generator.ts +2 -1
- package/src/generator/react-hooks/index.ts +4 -0
- package/src/generator/service/index.ts +4 -0
- package/src/generator/tsc/index.ts +52 -0
- package/src/generator/types.ts +1 -0
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publisher": "zenstack",
|
|
4
4
|
"displayName": "ZenStack Language Tools",
|
|
5
5
|
"description": "ZenStack is a toolkit that simplifies full-stack development",
|
|
6
|
-
"version": "0.2.
|
|
6
|
+
"version": "0.2.11",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "ZenStack Team"
|
|
9
9
|
},
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"url": "https://github.com/zenstackhq/zenstack"
|
|
21
21
|
},
|
|
22
22
|
"engines": {
|
|
23
|
-
"vscode": "^1.
|
|
23
|
+
"vscode": "^1.56.0"
|
|
24
24
|
},
|
|
25
25
|
"categories": [
|
|
26
26
|
"Programming Languages"
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
},
|
|
65
65
|
"main": "./bundle/extension.js",
|
|
66
66
|
"dependencies": {
|
|
67
|
-
"@zenstackhq/internal": "0.2.
|
|
67
|
+
"@zenstackhq/internal": "0.2.11",
|
|
68
68
|
"change-case": "^4.1.2",
|
|
69
69
|
"chevrotain": "^9.1.0",
|
|
70
70
|
"colors": "^1.4.0",
|
|
@@ -88,12 +88,12 @@
|
|
|
88
88
|
"@types/pluralize": "^0.0.29",
|
|
89
89
|
"@types/tmp": "^0.2.3",
|
|
90
90
|
"@types/uuid": "^8.3.4",
|
|
91
|
-
"@types/vscode": "^1.
|
|
92
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
93
|
-
"@typescript-eslint/parser": "^
|
|
91
|
+
"@types/vscode": "^1.56.0",
|
|
92
|
+
"@typescript-eslint/eslint-plugin": "^5.42.0",
|
|
93
|
+
"@typescript-eslint/parser": "^5.42.0",
|
|
94
94
|
"concurrently": "^7.4.0",
|
|
95
95
|
"esbuild": "^0.15.12",
|
|
96
|
-
"eslint": "^
|
|
96
|
+
"eslint": "^8.27.0",
|
|
97
97
|
"jest": "^29.2.1",
|
|
98
98
|
"langium-cli": "^0.5.0",
|
|
99
99
|
"tmp": "^0.2.1",
|
package/src/cli/cli-util.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { STD_LIB_MODULE_NAME } from '@lang/constants';
|
|
2
2
|
import { Model } from '@lang/generated/ast';
|
|
3
|
+
import { createZModelServices } from '@lang/zmodel-module';
|
|
3
4
|
import colors from 'colors';
|
|
4
5
|
import fs from 'fs';
|
|
5
6
|
import { LangiumServices } from 'langium';
|
|
7
|
+
import { NodeFileSystem } from 'langium/node';
|
|
6
8
|
import path from 'path';
|
|
9
|
+
import { ZenStackGenerator } from '../generator';
|
|
7
10
|
import { URI } from 'vscode-uri';
|
|
11
|
+
import { GENERATED_CODE_PATH } from '../generator/constants';
|
|
12
|
+
import { Context, GeneratorError } from '../generator/types';
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Loads a zmodel document from a file.
|
|
@@ -69,3 +74,32 @@ export async function loadDocument(
|
|
|
69
74
|
|
|
70
75
|
return document.parseResult.value as Model;
|
|
71
76
|
}
|
|
77
|
+
|
|
78
|
+
export async function runGenerator(
|
|
79
|
+
options: { schema: string },
|
|
80
|
+
includedGenerators?: string[],
|
|
81
|
+
clearOutput = true
|
|
82
|
+
) {
|
|
83
|
+
const services = createZModelServices(NodeFileSystem).ZModel;
|
|
84
|
+
const model = await loadDocument(options.schema, services);
|
|
85
|
+
|
|
86
|
+
const context: Context = {
|
|
87
|
+
schema: model,
|
|
88
|
+
outDir: path.dirname(options.schema),
|
|
89
|
+
// TODO: make this configurable
|
|
90
|
+
generatedCodeDir: GENERATED_CODE_PATH,
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
await new ZenStackGenerator().generate(
|
|
95
|
+
context,
|
|
96
|
+
includedGenerators,
|
|
97
|
+
clearOutput
|
|
98
|
+
);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (err instanceof GeneratorError) {
|
|
101
|
+
console.error(colors.red(err.message));
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
package/src/cli/index.ts
CHANGED
|
@@ -1,38 +1,16 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
import { Command, Option } from 'commander';
|
|
3
|
-
import { NodeFileSystem } from 'langium/node';
|
|
4
3
|
import { ZModelLanguageMetaData } from '../language-server/generated/module';
|
|
5
|
-
import { createZModelServices } from '../language-server/zmodel-module';
|
|
6
|
-
import { Context, GeneratorError } from '../generator/types';
|
|
7
|
-
import { ZenStackGenerator } from '../generator';
|
|
8
|
-
import { GENERATED_CODE_PATH } from '../generator/constants';
|
|
9
4
|
import colors from 'colors';
|
|
10
5
|
import { execSync } from '../utils/exec-utils';
|
|
11
6
|
import { paramCase } from 'change-case';
|
|
12
7
|
import path from 'path';
|
|
13
|
-
import {
|
|
8
|
+
import { runGenerator } from './cli-util';
|
|
14
9
|
|
|
15
10
|
export const generateAction = async (options: {
|
|
16
11
|
schema: string;
|
|
17
12
|
}): Promise<void> => {
|
|
18
|
-
|
|
19
|
-
const model = await loadDocument(options.schema, services);
|
|
20
|
-
|
|
21
|
-
const context: Context = {
|
|
22
|
-
schema: model,
|
|
23
|
-
outDir: path.dirname(options.schema),
|
|
24
|
-
// TODO: make this configurable
|
|
25
|
-
generatedCodeDir: GENERATED_CODE_PATH,
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
await new ZenStackGenerator().generate(context);
|
|
30
|
-
} catch (err) {
|
|
31
|
-
if (err instanceof GeneratorError) {
|
|
32
|
-
console.error(colors.red(err.message));
|
|
33
|
-
process.exit(1);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
13
|
+
await runGenerator(options);
|
|
36
14
|
};
|
|
37
15
|
|
|
38
16
|
function prismaAction(prismaCmd: string): (...args: any[]) => Promise<void> {
|
|
@@ -50,6 +28,10 @@ function prismaAction(prismaCmd: string): (...args: any[]) => Promise<void> {
|
|
|
50
28
|
);
|
|
51
29
|
})
|
|
52
30
|
.join(' ');
|
|
31
|
+
|
|
32
|
+
// regenerate prisma schema first
|
|
33
|
+
await runGenerator(options, ['prisma'], false);
|
|
34
|
+
|
|
53
35
|
const prismaExec = `npx prisma ${prismaCmd} ${command.name()} ${optStr}`;
|
|
54
36
|
console.log(prismaExec);
|
|
55
37
|
try {
|
package/src/generator/index.ts
CHANGED
|
@@ -1,13 +1,12 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
-
import { Context
|
|
2
|
+
import { Context } from './types';
|
|
3
3
|
import * as fs from 'fs';
|
|
4
4
|
import colors from 'colors';
|
|
5
5
|
import PrismaGenerator from './prisma';
|
|
6
6
|
import ServiceGenerator from './service';
|
|
7
7
|
import ReactHooksGenerator from './react-hooks';
|
|
8
8
|
import NextAuthGenerator from './next-auth';
|
|
9
|
-
import
|
|
10
|
-
import { execSync } from '../utils/exec-utils';
|
|
9
|
+
import { TypescriptCompilation } from './tsc';
|
|
11
10
|
|
|
12
11
|
/**
|
|
13
12
|
* ZenStack code generator
|
|
@@ -16,20 +15,26 @@ export class ZenStackGenerator {
|
|
|
16
15
|
/**
|
|
17
16
|
* Runs a series of nested generators
|
|
18
17
|
*/
|
|
19
|
-
async generate(
|
|
20
|
-
|
|
18
|
+
async generate(
|
|
19
|
+
context: Context,
|
|
20
|
+
includeGenerators?: string[],
|
|
21
|
+
clearOutput = true
|
|
22
|
+
): Promise<void> {
|
|
23
|
+
// ensure folder that stores generated prisma schema and migrations
|
|
21
24
|
if (!fs.existsSync(context.outDir)) {
|
|
22
25
|
fs.mkdirSync(context.outDir);
|
|
23
26
|
}
|
|
24
27
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
fs.
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
if (clearOutput) {
|
|
29
|
+
// recreate folder that stores generated zenstack code
|
|
30
|
+
if (fs.existsSync(context.generatedCodeDir)) {
|
|
31
|
+
fs.rmSync(context.generatedCodeDir, {
|
|
32
|
+
force: true,
|
|
33
|
+
recursive: true,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
fs.mkdirSync(context.generatedCodeDir);
|
|
31
37
|
}
|
|
32
|
-
fs.mkdirSync(context.generatedCodeDir);
|
|
33
38
|
|
|
34
39
|
const version = require('../../package.json').version;
|
|
35
40
|
console.log(colors.bold(`⌛️ Running ZenStack generator v${version}`));
|
|
@@ -40,49 +45,19 @@ export class ZenStackGenerator {
|
|
|
40
45
|
new ServiceGenerator(),
|
|
41
46
|
new ReactHooksGenerator(),
|
|
42
47
|
new NextAuthGenerator(),
|
|
48
|
+
new TypescriptCompilation(),
|
|
43
49
|
];
|
|
44
50
|
|
|
45
51
|
for (const generator of generators) {
|
|
52
|
+
if (
|
|
53
|
+
includeGenerators &&
|
|
54
|
+
!includeGenerators.includes(generator.name)
|
|
55
|
+
) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
46
58
|
await generator.generate(context);
|
|
47
59
|
}
|
|
48
60
|
|
|
49
|
-
// generate package.json
|
|
50
|
-
const packageJson = require(path.join(
|
|
51
|
-
__dirname,
|
|
52
|
-
'../res',
|
|
53
|
-
'package.template.json'
|
|
54
|
-
));
|
|
55
|
-
fs.writeFileSync(
|
|
56
|
-
path.join(context.generatedCodeDir, 'package.json'),
|
|
57
|
-
JSON.stringify(packageJson, undefined, 4)
|
|
58
|
-
);
|
|
59
|
-
|
|
60
|
-
// compile ts sources
|
|
61
|
-
const tsConfig = require(path.join(
|
|
62
|
-
__dirname,
|
|
63
|
-
'../res',
|
|
64
|
-
'tsconfig.template.json'
|
|
65
|
-
));
|
|
66
|
-
fs.writeFileSync(
|
|
67
|
-
path.join(context.generatedCodeDir, 'tsconfig.json'),
|
|
68
|
-
JSON.stringify(tsConfig, undefined, 4)
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
execSync(
|
|
73
|
-
`npx tsc -p "${path.join(
|
|
74
|
-
context.generatedCodeDir,
|
|
75
|
-
'tsconfig.json'
|
|
76
|
-
)}"`
|
|
77
|
-
);
|
|
78
|
-
} catch {
|
|
79
|
-
throw new GeneratorError(
|
|
80
|
-
'Something went wrong, generated runtime code failed to compile...\nPlease check errors above.'
|
|
81
|
-
);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
console.log(colors.blue(' ✔️ Typescript source files transpiled'));
|
|
85
|
-
|
|
86
61
|
console.log(
|
|
87
62
|
colors.green(
|
|
88
63
|
colors.bold('👻 All generators completed successfully!')
|
|
@@ -9,6 +9,10 @@ import { execSync } from 'child_process';
|
|
|
9
9
|
* Generates NextAuth adaptor code
|
|
10
10
|
*/
|
|
11
11
|
export default class NextAuthGenerator implements Generator {
|
|
12
|
+
get name() {
|
|
13
|
+
return 'next-auth';
|
|
14
|
+
}
|
|
15
|
+
|
|
12
16
|
private findModel(schema: Model, name: string) {
|
|
13
17
|
return schema.declarations.find(
|
|
14
18
|
(d) => isDataModel(d) && d.name === name
|
|
@@ -8,6 +8,10 @@ import QueryGuardGenerator from './query-guard-generator';
|
|
|
8
8
|
* Generates Prisma schema and db client
|
|
9
9
|
*/
|
|
10
10
|
export default class PrismaGenerator implements Generator {
|
|
11
|
+
get name() {
|
|
12
|
+
return 'prisma';
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
async generate(context: Context): Promise<void> {
|
|
12
16
|
// generate prisma schema
|
|
13
17
|
const schemaFile = await new PrismaSchemaGenerator(context).generate();
|
|
@@ -160,7 +160,8 @@ export default class QueryGuardGenerator {
|
|
|
160
160
|
.addBody();
|
|
161
161
|
|
|
162
162
|
func.addStatements(
|
|
163
|
-
|
|
163
|
+
// make suer user id is always available
|
|
164
|
+
`const user = context.user?.id ? context.user : { ...context.user, id: '${UNKNOWN_USER_ID}' };`
|
|
164
165
|
);
|
|
165
166
|
|
|
166
167
|
// r = <guard object>;
|
|
@@ -11,6 +11,10 @@ import { API_ROUTE_NAME, INTERNAL_PACKAGE } from '../constants';
|
|
|
11
11
|
* Generate react data query hooks code
|
|
12
12
|
*/
|
|
13
13
|
export default class ReactHooksGenerator implements Generator {
|
|
14
|
+
get name() {
|
|
15
|
+
return 'react-hooks';
|
|
16
|
+
}
|
|
17
|
+
|
|
14
18
|
async generate(context: Context): Promise<void> {
|
|
15
19
|
const project = new Project();
|
|
16
20
|
|
|
@@ -8,6 +8,10 @@ import { INTERNAL_PACKAGE } from '../constants';
|
|
|
8
8
|
* Generates ZenStack service code
|
|
9
9
|
*/
|
|
10
10
|
export default class ServiceGenerator implements Generator {
|
|
11
|
+
get name() {
|
|
12
|
+
return 'service';
|
|
13
|
+
}
|
|
14
|
+
|
|
11
15
|
async generate(context: Context): Promise<void> {
|
|
12
16
|
const project = new Project();
|
|
13
17
|
const sf = project.createSourceFile(
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-var-requires */
|
|
2
|
+
import colors from 'colors';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import { execSync } from '../../utils/exec-utils';
|
|
6
|
+
import { Context, Generator, GeneratorError } from '../types';
|
|
7
|
+
|
|
8
|
+
export class TypescriptCompilation implements Generator {
|
|
9
|
+
get name(): string {
|
|
10
|
+
return 'tsc';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async generate(context: Context) {
|
|
14
|
+
// generate package.json
|
|
15
|
+
const packageJson = require(path.join(
|
|
16
|
+
__dirname,
|
|
17
|
+
'../res',
|
|
18
|
+
'package.template.json'
|
|
19
|
+
));
|
|
20
|
+
|
|
21
|
+
fs.writeFileSync(
|
|
22
|
+
path.join(context.generatedCodeDir, 'package.json'),
|
|
23
|
+
JSON.stringify(packageJson, undefined, 4)
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// compile ts sources
|
|
27
|
+
const tsConfig = require(path.join(
|
|
28
|
+
__dirname,
|
|
29
|
+
'../res',
|
|
30
|
+
'tsconfig.template.json'
|
|
31
|
+
));
|
|
32
|
+
fs.writeFileSync(
|
|
33
|
+
path.join(context.generatedCodeDir, 'tsconfig.json'),
|
|
34
|
+
JSON.stringify(tsConfig, undefined, 4)
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
try {
|
|
38
|
+
execSync(
|
|
39
|
+
`npx tsc -p "${path.join(
|
|
40
|
+
context.generatedCodeDir,
|
|
41
|
+
'tsconfig.json'
|
|
42
|
+
)}"`
|
|
43
|
+
);
|
|
44
|
+
} catch {
|
|
45
|
+
throw new GeneratorError(
|
|
46
|
+
'Something went wrong, generated runtime code failed to compile...\nPlease check errors above.'
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
console.log(colors.blue(' ✔️ Typescript source files transpiled'));
|
|
51
|
+
}
|
|
52
|
+
}
|