zenstack 0.1.47 → 0.1.50

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 (169) hide show
  1. package/LICENSE.md +9 -0
  2. package/bin/cli +1 -1
  3. package/bundle/asset/logo-dark-256.png +0 -0
  4. package/bundle/asset/logo-dark.png +0 -0
  5. package/bundle/asset/logo-light-256.png +0 -0
  6. package/bundle/asset/logo-light.png +0 -0
  7. package/bundle/cli/index.js +6849 -0
  8. package/bundle/cli/index.js.map +7 -0
  9. package/bundle/extension.js +39 -0
  10. package/bundle/extension.js.map +7 -0
  11. package/bundle/language-server/main.js +6105 -0
  12. package/bundle/language-server/main.js.map +7 -0
  13. package/{out/generator → bundle/res}/package.template.json +0 -0
  14. package/bundle/res/stdlib.zmodel +101 -0
  15. package/{out/generator → bundle/res}/tsconfig.template.json +0 -0
  16. package/package.json +38 -14
  17. package/src/cli/cli-util.ts +71 -0
  18. package/src/cli/index.ts +182 -0
  19. package/src/extension.ts +76 -0
  20. package/src/generator/constants.ts +5 -0
  21. package/src/generator/index.ts +102 -0
  22. package/{out/generator/next-auth/index.js → src/generator/next-auth/index.ts} +49 -58
  23. package/src/generator/prisma/expression-writer.ts +360 -0
  24. package/src/generator/prisma/index.ts +35 -0
  25. package/src/generator/prisma/prisma-builder.ts +370 -0
  26. package/src/generator/prisma/query-gard-generator.ts +213 -0
  27. package/src/generator/prisma/schema-generator.ts +305 -0
  28. package/src/generator/prisma/typescript-expression-transformer.ts +108 -0
  29. package/src/generator/react-hooks/index.ts +184 -0
  30. package/src/generator/service/index.ts +110 -0
  31. package/src/generator/types.ts +17 -0
  32. package/src/generator/utils.ts +18 -0
  33. package/src/language-server/constants.ts +28 -0
  34. package/src/language-server/generated/ast.ts +616 -0
  35. package/{out/language-server/generated/grammar.js → src/language-server/generated/grammar.ts} +5 -8
  36. package/src/language-server/generated/module.ts +24 -0
  37. package/src/language-server/langium-ext.d.ts +10 -0
  38. package/src/language-server/lsp/zmodel-definition-provider.ts +87 -0
  39. package/src/language-server/main.ts +13 -0
  40. package/src/language-server/types.ts +25 -0
  41. package/src/language-server/validator/attribute-validator.ts +11 -0
  42. package/src/language-server/validator/datamodel-validator.ts +311 -0
  43. package/src/language-server/validator/datasource-validator.ts +102 -0
  44. package/src/language-server/validator/enum-validator.ts +14 -0
  45. package/src/language-server/validator/schema-validator.ts +31 -0
  46. package/src/language-server/validator/utils.ts +158 -0
  47. package/src/language-server/validator/zmodel-validator.ts +84 -0
  48. package/src/language-server/zmodel-linker.ts +446 -0
  49. package/src/language-server/zmodel-module.ts +136 -0
  50. package/src/language-server/zmodel-scope.ts +45 -0
  51. package/src/language-server/zmodel-workspace-manager.ts +23 -0
  52. package/src/language-server/zmodel.langium +197 -0
  53. package/{out/cli → src/res}/package.template.json +2 -3
  54. package/src/res/stdlib.zmodel +101 -0
  55. package/{out/cli → src/res}/tsconfig.template.json +1 -1
  56. package/src/utils/exec-utils.ts +8 -0
  57. package/src/utils/indent-string.ts +9 -0
  58. package/LICENSE +0 -21
  59. package/out/cli/cli-util.js +0 -64
  60. package/out/cli/cli-util.js.map +0 -1
  61. package/out/cli/generator.js +0 -1
  62. package/out/cli/generator.js.map +0 -1
  63. package/out/cli/index.js +0 -124
  64. package/out/cli/index.js.map +0 -1
  65. package/out/extension.js +0 -81
  66. package/out/extension.js.map +0 -1
  67. package/out/generator/constants.js +0 -9
  68. package/out/generator/constants.js.map +0 -1
  69. package/out/generator/data-server/index.js +0 -1
  70. package/out/generator/data-server/index.js.map +0 -1
  71. package/out/generator/index.js +0 -98
  72. package/out/generator/index.js.map +0 -1
  73. package/out/generator/next-auth/index.js.map +0 -1
  74. package/out/generator/prisma/expression-writer.js +0 -287
  75. package/out/generator/prisma/expression-writer.js.map +0 -1
  76. package/out/generator/prisma/index.js +0 -44
  77. package/out/generator/prisma/index.js.map +0 -1
  78. package/out/generator/prisma/plain-expression-builder.js +0 -69
  79. package/out/generator/prisma/plain-expression-builder.js.map +0 -1
  80. package/out/generator/prisma/prisma-builder.js +0 -307
  81. package/out/generator/prisma/prisma-builder.js.map +0 -1
  82. package/out/generator/prisma/query-gard-generator.js +0 -159
  83. package/out/generator/prisma/query-gard-generator.js.map +0 -1
  84. package/out/generator/prisma/schema-generator.js +0 -193
  85. package/out/generator/prisma/schema-generator.js.map +0 -1
  86. package/out/generator/query-guard/index.js +0 -2
  87. package/out/generator/query-guard/index.js.map +0 -1
  88. package/out/generator/react-hooks/index.js +0 -179
  89. package/out/generator/react-hooks/index.js.map +0 -1
  90. package/out/generator/server/data/data-generator.js +0 -376
  91. package/out/generator/server/data/data-generator.js.map +0 -1
  92. package/out/generator/server/data/expression-writer.js +0 -287
  93. package/out/generator/server/data/expression-writer.js.map +0 -1
  94. package/out/generator/server/data/plain-expression-builder.js +0 -69
  95. package/out/generator/server/data/plain-expression-builder.js.map +0 -1
  96. package/out/generator/server/data-generator.js +0 -82
  97. package/out/generator/server/data-generator.js.map +0 -1
  98. package/out/generator/server/expression-writer.js +0 -1
  99. package/out/generator/server/expression-writer.js.map +0 -1
  100. package/out/generator/server/function/function-generator.js +0 -50
  101. package/out/generator/server/function/function-generator.js.map +0 -1
  102. package/out/generator/server/function-generator.js +0 -13
  103. package/out/generator/server/function-generator.js.map +0 -1
  104. package/out/generator/server/index.js +0 -88
  105. package/out/generator/server/index.js.map +0 -1
  106. package/out/generator/server/js-expression-builder.js +0 -1
  107. package/out/generator/server/js-expression-builder.js.map +0 -1
  108. package/out/generator/server/plain-expression-builder.js +0 -1
  109. package/out/generator/server/plain-expression-builder.js.map +0 -1
  110. package/out/generator/server/server-code-generator.js +0 -3
  111. package/out/generator/server/server-code-generator.js.map +0 -1
  112. package/out/generator/server/server-code-writer.js +0 -1
  113. package/out/generator/server/server-code-writer.js.map +0 -1
  114. package/out/generator/service/index.js +0 -133
  115. package/out/generator/service/index.js.map +0 -1
  116. package/out/generator/types.js +0 -10
  117. package/out/generator/types.js.map +0 -1
  118. package/out/generator/utils.js +0 -10
  119. package/out/generator/utils.js.map +0 -1
  120. package/out/langium-ext.js +0 -3
  121. package/out/langium-ext.js.map +0 -1
  122. package/out/language-server/constants.js +0 -20
  123. package/out/language-server/constants.js.map +0 -1
  124. package/out/language-server/generated/ast.js +0 -390
  125. package/out/language-server/generated/ast.js.map +0 -1
  126. package/out/language-server/generated/grammar.js.map +0 -1
  127. package/out/language-server/generated/module.js +0 -23
  128. package/out/language-server/generated/module.js.map +0 -1
  129. package/out/language-server/langium-ext.js +0 -3
  130. package/out/language-server/langium-ext.js.map +0 -1
  131. package/out/language-server/main.js +0 -13
  132. package/out/language-server/main.js.map +0 -1
  133. package/out/language-server/stdlib.zmodel +0 -23
  134. package/out/language-server/types.js +0 -3
  135. package/out/language-server/types.js.map +0 -1
  136. package/out/language-server/validator/attribute-validator copy.js +0 -12
  137. package/out/language-server/validator/attribute-validator copy.js.map +0 -1
  138. package/out/language-server/validator/attribute-validator.js +0 -7
  139. package/out/language-server/validator/attribute-validator.js.map +0 -1
  140. package/out/language-server/validator/datamodel-validator.js +0 -199
  141. package/out/language-server/validator/datamodel-validator.js.map +0 -1
  142. package/out/language-server/validator/datasource-validator copy.js +0 -77
  143. package/out/language-server/validator/datasource-validator copy.js.map +0 -1
  144. package/out/language-server/validator/datasource-validator.js +0 -77
  145. package/out/language-server/validator/datasource-validator.js.map +0 -1
  146. package/out/language-server/validator/enum-validator.js +0 -10
  147. package/out/language-server/validator/enum-validator.js.map +0 -1
  148. package/out/language-server/validator/model-validator.js +0 -21
  149. package/out/language-server/validator/model-validator.js.map +0 -1
  150. package/out/language-server/validator/schema-validator.js +0 -21
  151. package/out/language-server/validator/schema-validator.js.map +0 -1
  152. package/out/language-server/validator/utils.js +0 -106
  153. package/out/language-server/validator/utils.js.map +0 -1
  154. package/out/language-server/validator/zmodel-validator.js +0 -52
  155. package/out/language-server/validator/zmodel-validator.js.map +0 -1
  156. package/out/language-server/zmodel-index.js +0 -11
  157. package/out/language-server/zmodel-index.js.map +0 -1
  158. package/out/language-server/zmodel-linker.js +0 -249
  159. package/out/language-server/zmodel-linker.js.map +0 -1
  160. package/out/language-server/zmodel-module.js +0 -46
  161. package/out/language-server/zmodel-module.js.map +0 -1
  162. package/out/language-server/zmodel-scope.js +0 -41
  163. package/out/language-server/zmodel-scope.js.map +0 -1
  164. package/out/language-server/zmodel-validator.js +0 -35
  165. package/out/language-server/zmodel-validator.js.map +0 -1
  166. package/out/utils/exec-utils.js +0 -9
  167. package/out/utils/exec-utils.js.map +0 -1
  168. package/out/utils/indent-string.js +0 -9
  169. package/out/utils/indent-string.js.map +0 -1
@@ -0,0 +1,101 @@
1
+ /*
2
+ * Enum representing referential integrity related actions
3
+ */
4
+ enum ReferentialAction {
5
+ /*
6
+ * Used with "onDelete": deleting a referenced record will trigger the deletion of referencing record.
7
+ * Used with "onUpdate": updates the relation scalar fields if the referenced scalar fields of the dependent record are updated.
8
+ */
9
+ Cascade
10
+ }
11
+
12
+ /*
13
+ * Reads value from an environment variable
14
+ */
15
+ function env(name: String): String {}
16
+
17
+ /*
18
+ * Gets thec current login user
19
+ */
20
+ function auth(): Any {}
21
+
22
+ /*
23
+ * Gets current date-time (as DateTime type)
24
+ */
25
+ function now(): DateTime {}
26
+
27
+ /*
28
+ * Generate a globally unique identifier based on the UUID spec
29
+ */
30
+ function uuid(): String {}
31
+
32
+ /*
33
+ * Generate a globally unique identifier based on the CUID spec
34
+ */
35
+ function cuid(): String {}
36
+
37
+ /*
38
+ * Create a sequence of integers in the underlying database and assign the incremented
39
+ * values to the ID values of the created records based on the sequence
40
+ */
41
+ function autoincrement(): Int {}
42
+
43
+ /*
44
+ * Represents default values that cannot be expressed in the Prisma schema (such as random()).
45
+ */
46
+ function dbgenerated(expr: String): Any {}
47
+
48
+ /*
49
+ * Defines an ID on the model
50
+ */
51
+ attribute @id(map: String?)
52
+
53
+ /*
54
+ * Defines a default value for a field
55
+ */
56
+ attribute @default(_ value: ContextType)
57
+
58
+ /*
59
+ * Defines a unique constraint for this field
60
+ */
61
+ attribute @unique(map: String?)
62
+
63
+ /*
64
+ * Defines a compound unique constraint for the specified fields
65
+ */
66
+ attribute @@unique(_ fields: FieldReference[], name: String?, map: String?)
67
+
68
+ /*
69
+ * Defines an index in the database
70
+ */
71
+ attribute @@index(_ fields: FieldReference[], map: String?)
72
+
73
+ /*
74
+ * Defines meta information about the relation
75
+ */
76
+ attribute @relation(_ name: String?, fields: FieldReference[]?, references: FieldReference[]?, onDelete: ReferentialAction?, onUpdate: ReferentialAction?, map: String?)
77
+
78
+ /*
79
+ * Maps a field name or enum value from the schema to a column with a different name in the database
80
+ */
81
+ attribute @map(_ name: String)
82
+
83
+ /*
84
+ * Maps the schema model name to a table with a different name, or an enum name to a different underlying enum in the database
85
+ */
86
+ attribute @@map(_ name: String)
87
+
88
+ /*
89
+ * Automatically stores the time when a record was last updated
90
+ */
91
+ attribute @updatedAt()
92
+
93
+ /*
94
+ * Defines an access policy that allows a set of operations when the given condition is true
95
+ */
96
+ attribute @@allow(_ operation: String, _ condition: Boolean)
97
+
98
+ /*
99
+ * Defines an access policy that denies a set of operations when the given condition is true
100
+ */
101
+ attribute @@deny(_ operation: String, _ condition: Boolean)
package/package.json CHANGED
@@ -1,10 +1,26 @@
1
1
  {
2
2
  "name": "zenstack",
3
- "displayName": "ZenStack CLI and Language Tools",
4
- "description": "ZenStack CLI and Language Tools",
5
- "version": "0.1.47",
3
+ "publisher": "zenstack",
4
+ "displayName": "ZenStack Language Tools",
5
+ "description": "ZenStack is a toolkit that simplifies full-stack development",
6
+ "version": "0.1.50",
7
+ "author": {
8
+ "name": "ymc9"
9
+ },
10
+ "keywords": [
11
+ "fullstack",
12
+ "react",
13
+ "typescript",
14
+ "data modeling"
15
+ ],
16
+ "preview": true,
17
+ "icon": "asset/logo-light-256.png",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/zenstackhq/zenstack"
21
+ },
6
22
  "engines": {
7
- "vscode": "^1.56.0"
23
+ "vscode": "^1.72.0"
8
24
  },
9
25
  "categories": [
10
26
  "Programming Languages"
@@ -22,8 +38,8 @@
22
38
  ],
23
39
  "configuration": "./language-configuration.json",
24
40
  "icon": {
25
- "light": "./asset/logo-light.png",
26
- "dark": "./asset/logo-dark.png"
41
+ "light": "./asset/logo-light-256.png",
42
+ "dark": "./asset/logo-dark-256.png"
27
43
  }
28
44
  }
29
45
  ],
@@ -40,14 +56,15 @@
40
56
  ],
41
57
  "files": [
42
58
  "bin",
43
- "out"
59
+ "src",
60
+ "bundle"
44
61
  ],
45
62
  "bin": {
46
63
  "zenstack": "./bin/cli"
47
64
  },
48
- "main": "./out/extension.js",
65
+ "main": "./bundle/extension.js",
49
66
  "dependencies": {
50
- "@zenstackhq/internal": "0.1.21",
67
+ "@zenstackhq/internal": "0.1.22",
51
68
  "change-case": "^4.1.2",
52
69
  "chevrotain": "^9.1.0",
53
70
  "colors": "^1.4.0",
@@ -61,6 +78,7 @@
61
78
  "vscode-jsonrpc": "^8.0.2",
62
79
  "vscode-languageclient": "^8.0.2",
63
80
  "vscode-languageserver": "^8.0.2",
81
+ "vscode-languageserver-textdocument": "^1.0.7",
64
82
  "vscode-uri": "^3.0.6"
65
83
  },
66
84
  "devDependencies": {
@@ -74,6 +92,7 @@
74
92
  "@typescript-eslint/eslint-plugin": "^4.33.0",
75
93
  "@typescript-eslint/parser": "^4.33.0",
76
94
  "concurrently": "^7.4.0",
95
+ "esbuild": "^0.15.12",
77
96
  "eslint": "^7.32.0",
78
97
  "jest": "^29.2.1",
79
98
  "langium-cli": "^0.5.0",
@@ -82,17 +101,22 @@
82
101
  "ts-node": "^10.9.1",
83
102
  "tsc-alias": "^1.7.0",
84
103
  "tsconfig-paths-jest": "^0.0.1",
85
- "typescript": "^4.8.4"
104
+ "typescript": "^4.8.4",
105
+ "vsce": "^2.13.0"
86
106
  },
87
107
  "scripts": {
88
- "vscode:prepublish": "npm run build && npm run lint",
89
- "build": "npm run langium:generate && tsc && tsc-alias && cp src/language-server/stdlib.zmodel ./out/language-server/ && cp src/generator/*.template.json ./out/generator/",
90
- "ts:watch": "tsc --watch",
108
+ "vscode:publish": "vsce publish --no-dependencies",
109
+ "vscode:prepublish": "pnpm lint && pnpm build && pnpm bundle",
110
+ "vscode:package": "vsce package --no-dependencies",
111
+ "build": "pnpm langium:generate && tsc --noEmit",
112
+ "bundle": "node build/bundle.js --minify",
113
+ "bundle-watch": "node build/bundle.js --watch",
114
+ "ts:watch": "tsc --watch --noEmit",
91
115
  "tsc-alias:watch": "tsc-alias --watch",
92
116
  "lint": "eslint src --ext ts",
93
117
  "langium:generate": "langium generate",
94
118
  "langium:watch": "langium generate --watch",
95
- "watch": "concurrently --kill-others \"npm:langium:watch\" \"npm:ts:watch\" \"npm:tsc-alias:watch\"",
119
+ "watch": "concurrently --kill-others \"npm:langium:watch\" \"npm:bundle-watch\"",
96
120
  "test": "jest"
97
121
  }
98
122
  }
@@ -0,0 +1,71 @@
1
+ import { STD_LIB_MODULE_NAME } from '@lang/constants';
2
+ import { Model } from '@lang/generated/ast';
3
+ import colors from 'colors';
4
+ import fs from 'fs';
5
+ import { LangiumServices } from 'langium';
6
+ import path from 'path';
7
+ import { URI } from 'vscode-uri';
8
+
9
+ /**
10
+ * Loads a zmodel document from a file.
11
+ * @param fileName File name
12
+ * @param services Language services
13
+ * @returns Parsed and validated AST
14
+ */
15
+ export async function loadDocument(
16
+ fileName: string,
17
+ services: LangiumServices
18
+ ): Promise<Model> {
19
+ const extensions = services.LanguageMetaData.fileExtensions;
20
+ if (!extensions.includes(path.extname(fileName))) {
21
+ console.error(
22
+ colors.yellow(`Please choose a file with extension: ${extensions}.`)
23
+ );
24
+ process.exit(1);
25
+ }
26
+
27
+ if (!fs.existsSync(fileName)) {
28
+ console.error(colors.red(`File ${fileName} does not exist.`));
29
+ process.exit(1);
30
+ }
31
+
32
+ // load standard library
33
+ const stdLib =
34
+ services.shared.workspace.LangiumDocuments.getOrCreateDocument(
35
+ URI.file(
36
+ path.resolve(
37
+ path.join(__dirname, '../res', STD_LIB_MODULE_NAME)
38
+ )
39
+ )
40
+ );
41
+
42
+ // load the document
43
+ const document =
44
+ services.shared.workspace.LangiumDocuments.getOrCreateDocument(
45
+ URI.file(path.resolve(fileName))
46
+ );
47
+
48
+ // build the document together with standard library
49
+ await services.shared.workspace.DocumentBuilder.build([stdLib, document], {
50
+ validationChecks: 'all',
51
+ });
52
+
53
+ const validationErrors = (document.diagnostics ?? []).filter(
54
+ (e) => e.severity === 1
55
+ );
56
+ if (validationErrors.length > 0) {
57
+ console.error(colors.red('There are validation errors:'));
58
+ for (const validationError of validationErrors) {
59
+ console.error(
60
+ colors.red(
61
+ `line ${validationError.range.start.line + 1}: ${
62
+ validationError.message
63
+ } [${document.textDocument.getText(validationError.range)}]`
64
+ )
65
+ );
66
+ }
67
+ process.exit(1);
68
+ }
69
+
70
+ return document.parseResult.value as Model;
71
+ }
@@ -0,0 +1,182 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ import { Command, Option } from 'commander';
3
+ import { NodeFileSystem } from 'langium/node';
4
+ 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
+ import colors from 'colors';
10
+ import { execSync } from '../utils/exec-utils';
11
+ import { paramCase } from 'change-case';
12
+ import path from 'path';
13
+ import { loadDocument } from './cli-util';
14
+
15
+ export const generateAction = async (options: {
16
+ schema: string;
17
+ }): Promise<void> => {
18
+ const services = createZModelServices(NodeFileSystem).ZModel;
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
+ }
36
+ };
37
+
38
+ function prismaAction(prismaCmd: string): (...args: any[]) => Promise<void> {
39
+ return async (options: any, command: Command) => {
40
+ const optStr = Array.from(Object.entries<any>(options))
41
+ .map(([k, v]) => {
42
+ let optVal = v;
43
+ if (k === 'schema') {
44
+ optVal = path.join(path.dirname(v), 'schema.prisma');
45
+ }
46
+ return (
47
+ '--' +
48
+ paramCase(k) +
49
+ (typeof optVal === 'string' ? ` ${optVal}` : '')
50
+ );
51
+ })
52
+ .join(' ');
53
+ const prismaExec = `npx prisma ${prismaCmd} ${command.name()} ${optStr}`;
54
+ console.log(prismaExec);
55
+ try {
56
+ execSync(prismaExec);
57
+ } catch {
58
+ console.error(
59
+ colors.red(
60
+ 'Prisma command failed to execute. See errors above.'
61
+ )
62
+ );
63
+ process.exit(1);
64
+ }
65
+ };
66
+ }
67
+
68
+ export default function (): void {
69
+ const program = new Command('zenstack');
70
+
71
+ program.version(
72
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
73
+ require('../../package.json').version,
74
+ '-v --version',
75
+ 'display CLI version'
76
+ );
77
+
78
+ const schemaExtensions = ZModelLanguageMetaData.fileExtensions.join(', ');
79
+
80
+ program
81
+ .description(
82
+ `${colors.bold.blue(
83
+ 'ζ'
84
+ )} ZenStack simplifies fullstack development by generating backend services and Typescript clients from a data model.\n\nDocumentation: https://zenstack.dev/doc.`
85
+ )
86
+ .showHelpAfterError()
87
+ .showSuggestionAfterError();
88
+
89
+ const schemaOption = new Option(
90
+ '--schema <file>',
91
+ `schema file (with extension ${schemaExtensions})`
92
+ ).default('./zenstack/schema.zmodel');
93
+
94
+ //#region wraps Prisma commands
95
+
96
+ program
97
+ .command('generate')
98
+ .description(
99
+ 'generates RESTful API and Typescript client for your data model'
100
+ )
101
+ .addOption(schemaOption)
102
+ .action(generateAction);
103
+
104
+ const migrate = program
105
+ .command('migrate')
106
+ .description(`wraps Prisma's ${colors.cyan('migrate')} command`);
107
+
108
+ migrate
109
+ .command('dev')
110
+ .description(
111
+ `alias for ${colors.cyan(
112
+ 'prisma migrate dev'
113
+ )}\nCreate a migration, apply it to the database, generate db client.`
114
+ )
115
+ .addOption(schemaOption)
116
+ .option('--create-only', 'Create a migration without applying it')
117
+ .option('-n --name <name>', 'Name the migration')
118
+ .option('--skip-seed', 'Skip triggering seed')
119
+ .action(prismaAction('migrate'));
120
+
121
+ migrate
122
+ .command('reset')
123
+ .description(
124
+ `alias for ${colors.cyan(
125
+ 'prisma migrate reset'
126
+ )}\nReset your database and apply all migrations.`
127
+ )
128
+ .addOption(schemaOption)
129
+ .option('--force', 'Skip the confirmation prompt')
130
+ .action(prismaAction('migrate'));
131
+
132
+ migrate
133
+ .command('deploy')
134
+ .description(
135
+ `alias for ${colors.cyan(
136
+ 'prisma migrate deploy'
137
+ )}\nApply pending migrations to the database in production/staging.`
138
+ )
139
+ .addOption(schemaOption)
140
+ .action(prismaAction('migrate'));
141
+
142
+ migrate
143
+ .command('status')
144
+ .description(
145
+ `alias for ${colors.cyan(
146
+ 'prisma migrate status'
147
+ )}\nCheck the status of migrations in the production/staging database.`
148
+ )
149
+ .addOption(schemaOption)
150
+ .action(prismaAction('migrate'));
151
+
152
+ const db = program
153
+ .command('db')
154
+ .description(`wraps Prisma's ${colors.cyan('db')} command`);
155
+
156
+ db.command('push')
157
+ .description(
158
+ `alias for ${colors.cyan(
159
+ 'prisma db push'
160
+ )}\nPush the Prisma schema state to the database.`
161
+ )
162
+ .addOption(schemaOption)
163
+ .option('--accept-data-loss', 'Ignore data loss warnings')
164
+ .action(prismaAction('db'));
165
+
166
+ program
167
+ .command('studio')
168
+ .description(
169
+ `wraps Prisma's ${colors.cyan(
170
+ 'studio'
171
+ )} command. Browse your data with Prisma Studio.`
172
+ )
173
+ .addOption(schemaOption)
174
+ .option('-p --port <port>', 'Port to start Studio in')
175
+ .option('-b --browser <browser>', 'Browser to open Studio in')
176
+ .option('-n --hostname', 'Hostname to bind the Express server to')
177
+ .action(prismaAction(''));
178
+
179
+ //#endregion
180
+
181
+ program.parse(process.argv);
182
+ }
@@ -0,0 +1,76 @@
1
+ import * as vscode from 'vscode';
2
+ import * as path from 'path';
3
+ import {
4
+ LanguageClient,
5
+ LanguageClientOptions,
6
+ ServerOptions,
7
+ TransportKind,
8
+ } from 'vscode-languageclient/node';
9
+
10
+ let client: LanguageClient;
11
+
12
+ // This function is called when the extension is activated.
13
+ export function activate(context: vscode.ExtensionContext): void {
14
+ client = startLanguageClient(context);
15
+ }
16
+
17
+ // This function is called when the extension is deactivated.
18
+ export function deactivate(): Thenable<void> | undefined {
19
+ if (client) {
20
+ return client.stop();
21
+ }
22
+ return undefined;
23
+ }
24
+
25
+ function startLanguageClient(context: vscode.ExtensionContext): LanguageClient {
26
+ const serverModule = context.asAbsolutePath(
27
+ path.join('bundle', 'language-server', 'main')
28
+ );
29
+ // The debug options for the server
30
+ // --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging.
31
+ // By setting `process.env.DEBUG_BREAK` to a truthy value, the language server will wait until a debugger is attached.
32
+ const debugOptions = {
33
+ execArgv: [
34
+ '--nolazy',
35
+ `--inspect${process.env.DEBUG_BREAK ? '-brk' : ''}=${
36
+ process.env.DEBUG_SOCKET || '6009'
37
+ }`,
38
+ ],
39
+ };
40
+
41
+ // If the extension is launched in debug mode then the debug server options are used
42
+ // Otherwise the run options are used
43
+ const serverOptions: ServerOptions = {
44
+ run: { module: serverModule, transport: TransportKind.ipc },
45
+ debug: {
46
+ module: serverModule,
47
+ transport: TransportKind.ipc,
48
+ options: debugOptions,
49
+ },
50
+ };
51
+
52
+ const fileSystemWatcher =
53
+ vscode.workspace.createFileSystemWatcher('**/*.zmodel');
54
+ context.subscriptions.push(fileSystemWatcher);
55
+
56
+ // Options to control the language client
57
+ const clientOptions: LanguageClientOptions = {
58
+ documentSelector: [{ scheme: 'file', language: 'zmodel' }],
59
+ synchronize: {
60
+ // Notify the server about file changes to files contained in the workspace
61
+ fileEvents: fileSystemWatcher,
62
+ },
63
+ };
64
+
65
+ // Create the language client and start the client.
66
+ const client = new LanguageClient(
67
+ 'zmodel',
68
+ 'ZenStack Model',
69
+ serverOptions,
70
+ clientOptions
71
+ );
72
+
73
+ // Start the client. This will also launch the server
74
+ client.start();
75
+ return client;
76
+ }
@@ -0,0 +1,5 @@
1
+ export const INTERNAL_PACKAGE = '@zenstackhq/internal';
2
+ export const GUARD_FIELD_NAME = 'zenstack_guard';
3
+ export const TRANSACTION_FIELD_NAME = 'zenstack_transaction';
4
+ export const API_ROUTE_NAME = 'zenstack';
5
+ export const GENERATED_CODE_PATH = 'node_modules/.zenstack';
@@ -0,0 +1,102 @@
1
+ /* eslint-disable @typescript-eslint/no-var-requires */
2
+ import { Context, GeneratorError } from './types';
3
+ import * as fs from 'fs';
4
+ import colors from 'colors';
5
+ import PrismaGenerator from './prisma';
6
+ import ServiceGenerator from './service';
7
+ import ReactHooksGenerator from './react-hooks';
8
+ import NextAuthGenerator from './next-auth';
9
+ import path from 'path';
10
+ import { execSync } from '../utils/exec-utils';
11
+
12
+ /**
13
+ * ZenStack code generator
14
+ */
15
+ export class ZenStackGenerator {
16
+ /**
17
+ * Runs a series of nested generators
18
+ */
19
+ async generate(context: Context): Promise<void> {
20
+ // folder that stores generated prisma schema and migrations
21
+ if (!fs.existsSync(context.outDir)) {
22
+ fs.mkdirSync(context.outDir);
23
+ }
24
+
25
+ // folder that stores generated zenstack code
26
+ if (fs.existsSync(context.generatedCodeDir)) {
27
+ fs.rmSync(context.generatedCodeDir, {
28
+ force: true,
29
+ recursive: true,
30
+ });
31
+ }
32
+ fs.mkdirSync(context.generatedCodeDir);
33
+
34
+ const version = require('../../package.json').version;
35
+ console.log(colors.bold(`⌛️ Running ZenStack generator v${version}`));
36
+
37
+ // TODO: plugin mechanism
38
+ const generators = [
39
+ new PrismaGenerator(),
40
+ new ServiceGenerator(),
41
+ new ReactHooksGenerator(),
42
+ ];
43
+
44
+ try {
45
+ require('next-auth');
46
+ generators.push(new NextAuthGenerator());
47
+ } catch {
48
+ console.warn(
49
+ colors.yellow(
50
+ 'Next-auth module is not installed, skipping generating adapter.'
51
+ )
52
+ );
53
+ }
54
+
55
+ for (const generator of generators) {
56
+ await generator.generate(context);
57
+ }
58
+
59
+ // generate package.json
60
+ const packageJson = require(path.join(
61
+ __dirname,
62
+ '../res',
63
+ 'package.template.json'
64
+ ));
65
+ fs.writeFileSync(
66
+ path.join(context.generatedCodeDir, 'package.json'),
67
+ JSON.stringify(packageJson, undefined, 4)
68
+ );
69
+
70
+ // compile ts sources
71
+ const tsConfig = require(path.join(
72
+ __dirname,
73
+ '../res',
74
+ 'tsconfig.template.json'
75
+ ));
76
+ fs.writeFileSync(
77
+ path.join(context.generatedCodeDir, 'tsconfig.json'),
78
+ JSON.stringify(tsConfig, undefined, 4)
79
+ );
80
+
81
+ try {
82
+ execSync(
83
+ `npx tsc -p "${path.join(
84
+ context.generatedCodeDir,
85
+ 'tsconfig.json'
86
+ )}"`
87
+ );
88
+ } catch {
89
+ throw new GeneratorError(
90
+ 'Something went wrong, generated runtime code failed to compile...\nPlease check errors above.'
91
+ );
92
+ }
93
+
94
+ console.log(colors.blue(' ✔️ Typescript source files transpiled'));
95
+
96
+ console.log(
97
+ colors.green(
98
+ colors.bold('👻 All generators completed successfully!')
99
+ )
100
+ );
101
+ }
102
+ }