zenstack 1.0.16 → 1.1.1

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 (154) hide show
  1. package/README.md +93 -24
  2. package/bin/post-install.js +1 -1
  3. package/cli/actions/generate.d.ts +13 -0
  4. package/cli/actions/generate.js +71 -0
  5. package/cli/actions/generate.js.map +1 -0
  6. package/cli/actions/index.d.ts +3 -0
  7. package/cli/actions/index.js +20 -0
  8. package/cli/actions/index.js.map +1 -0
  9. package/cli/actions/info.d.ts +4 -0
  10. package/cli/actions/info.js +63 -0
  11. package/cli/actions/info.js.map +1 -0
  12. package/cli/actions/init.d.ts +12 -0
  13. package/cli/actions/init.js +83 -0
  14. package/cli/actions/init.js.map +1 -0
  15. package/cli/cli-util.d.ts +14 -11
  16. package/cli/cli-util.js +150 -82
  17. package/cli/cli-util.js.map +1 -1
  18. package/cli/config.d.ts +10 -0
  19. package/cli/config.js +62 -0
  20. package/cli/config.js.map +1 -0
  21. package/cli/index.d.ts +4 -12
  22. package/cli/index.js +36 -29
  23. package/cli/index.js.map +1 -1
  24. package/cli/plugin-runner.d.ts +13 -3
  25. package/cli/plugin-runner.js +165 -59
  26. package/cli/plugin-runner.js.map +1 -1
  27. package/constants.js +1 -1
  28. package/language-server/constants.d.ts +7 -0
  29. package/language-server/constants.js +8 -1
  30. package/language-server/constants.js.map +1 -1
  31. package/language-server/utils.d.ts +1 -14
  32. package/language-server/utils.js +2 -38
  33. package/language-server/utils.js.map +1 -1
  34. package/language-server/validator/attribute-application-validator.d.ts +15 -0
  35. package/language-server/validator/attribute-application-validator.js +246 -0
  36. package/language-server/validator/attribute-application-validator.js.map +1 -0
  37. package/language-server/validator/attribute-validator.d.ts +1 -1
  38. package/language-server/validator/attribute-validator.js +4 -1
  39. package/language-server/validator/attribute-validator.js.map +1 -1
  40. package/language-server/validator/datamodel-validator.d.ts +7 -0
  41. package/language-server/validator/datamodel-validator.js +84 -33
  42. package/language-server/validator/datamodel-validator.js.map +1 -1
  43. package/language-server/validator/enum-validator.js +3 -6
  44. package/language-server/validator/enum-validator.js.map +1 -1
  45. package/language-server/validator/expression-validator.d.ts +1 -1
  46. package/language-server/validator/expression-validator.js +108 -3
  47. package/language-server/validator/expression-validator.js.map +1 -1
  48. package/language-server/validator/function-decl-validator.d.ts +9 -0
  49. package/language-server/validator/function-decl-validator.js +13 -0
  50. package/language-server/validator/function-decl-validator.js.map +1 -0
  51. package/language-server/validator/function-invocation-validator.d.ts +11 -0
  52. package/language-server/validator/function-invocation-validator.js +135 -0
  53. package/language-server/validator/function-invocation-validator.js.map +1 -0
  54. package/language-server/validator/schema-validator.d.ts +4 -1
  55. package/language-server/validator/schema-validator.js +28 -7
  56. package/language-server/validator/schema-validator.js.map +1 -1
  57. package/language-server/validator/utils.d.ts +3 -4
  58. package/language-server/validator/utils.js +20 -123
  59. package/language-server/validator/utils.js.map +1 -1
  60. package/language-server/validator/zmodel-validator.d.ts +5 -1
  61. package/language-server/validator/zmodel-validator.js +18 -4
  62. package/language-server/validator/zmodel-validator.js.map +1 -1
  63. package/language-server/zmodel-code-action.d.ts +2 -1
  64. package/language-server/zmodel-code-action.js +46 -21
  65. package/language-server/zmodel-code-action.js.map +1 -1
  66. package/language-server/zmodel-definition.d.ts +7 -0
  67. package/language-server/zmodel-definition.js +31 -0
  68. package/language-server/zmodel-definition.js.map +1 -0
  69. package/language-server/zmodel-formatter.js +2 -2
  70. package/language-server/zmodel-formatter.js.map +1 -1
  71. package/language-server/zmodel-linker.d.ts +3 -0
  72. package/language-server/zmodel-linker.js +122 -41
  73. package/language-server/zmodel-linker.js.map +1 -1
  74. package/language-server/zmodel-module.js +4 -1
  75. package/language-server/zmodel-module.js.map +1 -1
  76. package/language-server/zmodel-scope.d.ts +7 -1
  77. package/language-server/zmodel-scope.js +57 -1
  78. package/language-server/zmodel-scope.js.map +1 -1
  79. package/language-server/zmodel-workspace-manager.d.ts +5 -1
  80. package/language-server/zmodel-workspace-manager.js +101 -0
  81. package/language-server/zmodel-workspace-manager.js.map +1 -1
  82. package/package.json +27 -20
  83. package/plugins/access-policy/expression-writer.d.ts +7 -0
  84. package/plugins/access-policy/expression-writer.js +325 -106
  85. package/plugins/access-policy/expression-writer.js.map +1 -1
  86. package/plugins/access-policy/index.d.ts +3 -3
  87. package/plugins/access-policy/index.js +3 -5
  88. package/plugins/access-policy/index.js.map +1 -1
  89. package/plugins/access-policy/policy-guard-generator.d.ts +10 -3
  90. package/plugins/access-policy/policy-guard-generator.js +406 -121
  91. package/plugins/access-policy/policy-guard-generator.js.map +1 -1
  92. package/plugins/model-meta/index.d.ts +3 -3
  93. package/plugins/model-meta/index.js +110 -46
  94. package/plugins/model-meta/index.js.map +1 -1
  95. package/plugins/plugin-utils.d.ts +8 -7
  96. package/plugins/plugin-utils.js +55 -21
  97. package/plugins/plugin-utils.js.map +1 -1
  98. package/plugins/prisma/index.d.ts +3 -3
  99. package/plugins/prisma/index.js +3 -5
  100. package/plugins/prisma/index.js.map +1 -1
  101. package/plugins/prisma/prisma-builder.d.ts +7 -14
  102. package/plugins/prisma/prisma-builder.js +29 -34
  103. package/plugins/prisma/prisma-builder.js.map +1 -1
  104. package/plugins/prisma/schema-generator.d.ts +7 -3
  105. package/plugins/prisma/schema-generator.js +146 -102
  106. package/plugins/prisma/schema-generator.js.map +1 -1
  107. package/plugins/prisma/zmodel-code-generator.d.ts +3 -1
  108. package/plugins/prisma/zmodel-code-generator.js +12 -2
  109. package/plugins/prisma/zmodel-code-generator.js.map +1 -1
  110. package/plugins/zod/generator.d.ts +4 -0
  111. package/plugins/zod/generator.js +298 -0
  112. package/plugins/zod/generator.js.map +1 -0
  113. package/plugins/zod/index.d.ts +4 -0
  114. package/plugins/zod/index.js +24 -0
  115. package/plugins/zod/index.js.map +1 -0
  116. package/plugins/zod/transformer.d.ts +68 -0
  117. package/plugins/zod/transformer.js +554 -0
  118. package/plugins/zod/transformer.js.map +1 -0
  119. package/plugins/zod/types.d.ts +25 -0
  120. package/plugins/zod/types.js.map +1 -0
  121. package/plugins/zod/utils/removeDir.d.ts +1 -0
  122. package/plugins/zod/utils/removeDir.js +30 -0
  123. package/plugins/zod/utils/removeDir.js.map +1 -0
  124. package/plugins/zod/utils/schema-gen.d.ts +3 -0
  125. package/plugins/zod/utils/schema-gen.js +188 -0
  126. package/plugins/zod/utils/schema-gen.js.map +1 -0
  127. package/res/starter.zmodel +6 -8
  128. package/res/stdlib.zmodel +238 -74
  129. package/telemetry.d.ts +2 -1
  130. package/telemetry.js +21 -11
  131. package/telemetry.js.map +1 -1
  132. package/utils/ast-utils.d.ts +12 -15
  133. package/utils/ast-utils.js +117 -66
  134. package/utils/ast-utils.js.map +1 -1
  135. package/utils/pkg-utils.d.ts +2 -2
  136. package/utils/pkg-utils.js +34 -16
  137. package/utils/pkg-utils.js.map +1 -1
  138. package/utils/typescript-expression-transformer.d.ts +54 -0
  139. package/utils/typescript-expression-transformer.js +326 -0
  140. package/utils/typescript-expression-transformer.js.map +1 -0
  141. package/utils/version-utils.js +7 -1
  142. package/utils/version-utils.js.map +1 -1
  143. package/plugins/access-policy/typescript-expression-transformer.d.ts +0 -26
  144. package/plugins/access-policy/typescript-expression-transformer.js +0 -111
  145. package/plugins/access-policy/typescript-expression-transformer.js.map +0 -1
  146. package/plugins/access-policy/utils.d.ts +0 -5
  147. package/plugins/access-policy/utils.js +0 -14
  148. package/plugins/access-policy/utils.js.map +0 -1
  149. package/plugins/access-policy/zod-schema-generator.d.ts +0 -12
  150. package/plugins/access-policy/zod-schema-generator.js +0 -158
  151. package/plugins/access-policy/zod-schema-generator.js.map +0 -1
  152. package/types.d.ts +0 -12
  153. package/types.js.map +0 -1
  154. /package/{types.js → plugins/zod/types.js} +0 -0
package/README.md CHANGED
@@ -1,7 +1,11 @@
1
1
  <div align="center">
2
- <img src="https://user-images.githubusercontent.com/104139426/214809937-4ed30485-a683-4fea-b737-928c48e86fd7.png" style="max-width: 512px; width: 100%; height: auto; margin-bottom: 1rem;"
3
- >
4
- <div></div>
2
+ <a href="https://zenstack.dev">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/zenstackhq/zenstack-docs/main/static/img/logo-dark.png">
5
+ <img src="https://raw.githubusercontent.com/zenstackhq/zenstack-docs/main/static/img/logo.png" height="128">
6
+ </picture>
7
+ </a>
8
+ <h1>ZenStack</h1>
5
9
  <a href="https://www.npmjs.com/package/zenstack">
6
10
  <img src="https://img.shields.io/npm/v/zenstack">
7
11
  </a>
@@ -19,13 +23,19 @@
19
23
 
20
24
  ## What it is
21
25
 
22
- ZenStack is a toolkit that simplifies the development of a web app's backend. It supercharges [Prisma ORM](https://prisma.io) with a powerful access control layer and unleashes its full potential for web development.
26
+ ZenStack is a Node.js/TypeScript toolkit that simplifies the development of a web app's backend. It supercharges [Prisma ORM](https://prisma.io) with a powerful access control layer and unleashes its full potential for full-stack development.
23
27
 
24
28
  Our goal is to let you save time writing boilerplate code and focus on building real features!
25
29
 
26
30
  ## How it works
27
31
 
28
- ZenStack extended Prisma schema language for supporting custom attributes and functions and, based on that, implemented a flexible access control layer around Prisma.
32
+ > Read full documentation at 👉🏻 [zenstack.dev](https://zenstack.dev).
33
+
34
+ ZenStack incrementally extends Prisma's power with the following four layers:
35
+
36
+ ### 1. ZModel - an extended Prisma schema language
37
+
38
+ ZenStack introduces a data modeling language called "ZModel" - a superset of Prisma schema language. It extended Prisma schema with custom attributes and functions and, based on that, implemented a flexible access control layer around Prisma.
29
39
 
30
40
  ```prisma
31
41
  // schema.zmodel
@@ -45,34 +55,58 @@ model Post {
45
55
  }
46
56
  ```
47
57
 
48
- At runtime, transparent proxies are created around Prisma clients for intercepting queries and mutations to enforce access policies. Moreover, framework integration packages help you wrap an access-control-enabled Prisma client into backend APIs that can be safely called from the frontend.
58
+ The `zenstack` CLI transpiles the ZModel into a standard Prisma schema, which you can use with the regular Prisma workflows.
59
+
60
+ ### 2. Runtime enhancements to Prisma client
61
+
62
+ At runtime, transparent proxies are created around Prisma clients for intercepting queries and mutations to enforce access policies.
63
+
64
+ ```ts
65
+ import { enhance } from '@zenstackhq/runtime';
66
+
67
+ // a regular Prisma client
68
+ const prisma = new PrismaClient();
69
+
70
+ async function getPosts(userId: string) {
71
+ // create an enhanced Prisma client that has access control enabled
72
+ const enhanced = enhance(prisma, { user: userId });
73
+
74
+ // only posts that're visible to the user will be returned
75
+ return enhanced.post.findMany();
76
+ }
77
+ ```
78
+
79
+ ### 3. Automatic RESTful APIs through server adapters
80
+
81
+ Server adapter packages help you wrap an access-control-enabled Prisma client into backend CRUD APIs that can be safely called from the frontend. Here's an example for Next.js:
49
82
 
50
83
  ```ts
51
- // Next.js example: pages/api/model/[...path].ts
84
+ // pages/api/model/[...path].ts
52
85
 
53
86
  import { requestHandler } from '@zenstackhq/next';
54
- import { withPolicy } from '@zenstackhq/runtime';
87
+ import { enhance } from '@zenstackhq/runtime';
55
88
  import { getSessionUser } from '@lib/auth';
56
89
  import { prisma } from '@lib/db';
57
90
 
91
+ // Mount Prisma-style APIs: "/api/model/post/findMany", "/api/model/post/create", etc.
92
+ // Can be configured to provide standard RESTful APIs (using JSON:API) instead.
58
93
  export default requestHandler({
59
- getPrisma: (req, res) => withPolicy(prisma, { user: getSessionUser(req, res) }),
94
+ getPrisma: (req, res) => enhance(prisma, { user: getSessionUser(req, res) }),
60
95
  });
61
96
  ```
62
97
 
63
- Plugins can generate strong-typed client libraries that talk to the APIs:
98
+ ### 4. Generated client libraries (hooks) for data access
99
+
100
+ Plugins can generate strong-typed client libraries that talk to the aforementioned APIs. Here's an example for React:
64
101
 
65
102
  ```tsx
66
- // React example: components/MyPosts.tsx
103
+ // components/MyPosts.tsx
67
104
 
68
- import { usePost } from '@lib/hooks';
105
+ import { useFindManyPost } from '@lib/hooks';
69
106
 
70
107
  const MyPosts = () => {
71
- // Post CRUD hooks
72
- const { findMany } = usePost();
73
-
74
108
  // list all posts that're visible to the current user, together with their authors
75
- const { data: posts } = findMany({
109
+ const { data: posts } = useFindManyPost({
76
110
  include: { author: true },
77
111
  orderBy: { createdAt: 'desc' },
78
112
  });
@@ -89,7 +123,9 @@ const MyPosts = () => {
89
123
  };
90
124
  ```
91
125
 
92
- The following diagram gives a high-level overview of how it works.
126
+ ## Architecture
127
+
128
+ The following diagram gives a high-level architecture overview of ZenStack.
93
129
 
94
130
  ![Architecture](https://zenstack.dev/img/architecture-light.png)
95
131
 
@@ -99,27 +135,60 @@ The following diagram gives a high-level overview of how it works.
99
135
  - [Documentation](https://zenstack.dev/docs)
100
136
  - [Community chat](https://go.zenstack.dev/chat)
101
137
  - [Twitter](https://twitter.com/zenstackhq)
102
- - [Blog](https://dev.to/zenstack)
138
+ - [Blog](https://zenstack.dev/blog)
103
139
 
104
140
  ## Features
105
141
 
106
142
  - Access control and data validation rules right inside your Prisma schema
107
- - Auto-generated RESTful API and client library
143
+ - Auto-generated OpenAPI (RESTful) specifications, services, and client libraries
108
144
  - End-to-end type safety
109
145
  - Extensible: custom attributes, functions, and a plugin system
110
- - Framework agnostic
146
+ - A framework-agnostic core with framework-specific adapters
111
147
  - Uncompromised performance
112
148
 
149
+ ### Plugins
150
+
151
+ - Prisma schema generator
152
+ - Zod schema generator
153
+ - [SWR](https://github.com/vercel/swr) and [TanStack Query](https://github.com/TanStack/query) hooks generator
154
+ - OpenAPI specification generator
155
+ - [tRPC](https://trpc.io) router generator
156
+ - 🙋🏻 [Request for a plugin](https://go.zenstack.dev/chat)
157
+
158
+ ### Framework adapters
159
+
160
+ - [Next.js](https://zenstack.dev/docs/reference/server-adapters/next) (including support for the new "app directory" in Next.js 13)
161
+ - [Nuxt](https://zenstack.dev/docs/reference/server-adapters/nuxt)
162
+ - [SvelteKit](https://zenstack.dev/docs/reference/server-adapters/sveltekit)
163
+ - [Fastify](https://zenstack.dev/docs/reference/server-adapters/fastify)
164
+ - [ExpressJS](https://zenstack.dev/docs/reference/server-adapters/express)
165
+ - 🙋🏻 [Request for an adapter](https://go.zenstack.dev/chat)
166
+
167
+ ### Prisma schema extensions
168
+
169
+ - [Custom attributes and functions](https://zenstack.dev/docs/reference/zmodel-language#custom-attributes-and-functions)
170
+ - [Multi-file schema and model inheritance](https://zenstack.dev/docs/guides/multiple-schema)
171
+ - Strong-typed JSON field (coming soon)
172
+ - Polymorphism (future)
173
+ - 🙋🏻 [Request for an extension](https://go.zenstack.dev/chat)
174
+
113
175
  ## Examples
114
176
 
115
- Check out the [Collaborative Todo App](https://zenstack-todo.vercel.app/) for a running example. You can find the source code below:
177
+ Check out the [Collaborative Todo App](https://zenstack-todo.vercel.app/) for a running example. You can find different implementations below:
116
178
 
117
- - [Next.js + React hooks implementation](https://github.com/zenstackhq/sample-todo-nextjs)
118
- - [Next.js + tRPC implementation](https://github.com/zenstackhq/sample-todo-trpc)
179
+ - [Next.js + SWR hooks](https://github.com/zenstackhq/sample-todo-nextjs)
180
+ - [Next.js + TanStack Query](https://github.com/zenstackhq/sample-todo-nextjs-tanstack)
181
+ - [Next.js + tRPC](https://github.com/zenstackhq/sample-todo-trpc)
182
+ - [Nuxt + TanStack Query](https://github.com/zenstackhq/sample-todo-nuxt)
183
+ - [SvelteKit + TanStack Query](https://github.com/zenstackhq/sample-todo-sveltekit)
119
184
 
120
185
  ## Community
121
186
 
122
- Join our [discord server](https://go.zenstack.dev/chat) for chat and updates!
187
+ Join our [discord server](https://discord.gg/Ykhr738dUe) for chat and updates!
188
+
189
+ ## Contributing
190
+
191
+ If you like ZenStack, join us to make it a better tool! Please use the [Contributing Guide](CONTRIBUTING.md) for details on how to get started, and don't hesitate to join [Discord](https://discord.gg/Ykhr738dUe) to share your thoughts.
123
192
 
124
193
  ## License
125
194
 
@@ -7,7 +7,7 @@ try {
7
7
  const machineId = require('node-machine-id');
8
8
  const os = require('os');
9
9
 
10
- const mixpanel = Mixpanel.init('', {
10
+ const mixpanel = Mixpanel.init('74944eb779d7d3b4ce185be843fde9fc', {
11
11
  geolocate: true,
12
12
  });
13
13
 
@@ -0,0 +1,13 @@
1
+ declare type Options = {
2
+ schema: string;
3
+ output?: string;
4
+ dependencyCheck: boolean;
5
+ versionCheck: boolean;
6
+ compile: boolean;
7
+ defaultPlugins: boolean;
8
+ };
9
+ /**
10
+ * CLI action for generating code from schema
11
+ */
12
+ export declare function generate(projectPath: string, options: Options): Promise<void>;
13
+ export {};
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.generate = void 0;
16
+ const sdk_1 = require("@zenstackhq/sdk");
17
+ const colors_1 = __importDefault(require("colors"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const cli_error_1 = require("../cli-error");
20
+ const cli_util_1 = require("../cli-util");
21
+ const plugin_runner_1 = require("../plugin-runner");
22
+ /**
23
+ * CLI action for generating code from schema
24
+ */
25
+ function generate(projectPath, options) {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ if (options.dependencyCheck) {
28
+ (0, cli_util_1.checkRequiredPackage)('prisma', cli_util_1.requiredPrismaVersion);
29
+ (0, cli_util_1.checkRequiredPackage)('@prisma/client', cli_util_1.requiredPrismaVersion);
30
+ }
31
+ // check for multiple versions of Zenstack packages
32
+ const packages = (0, cli_util_1.getZenStackPackages)(projectPath);
33
+ if (packages) {
34
+ const versions = new Set(packages.map((p) => p.version));
35
+ if (versions.size > 1) {
36
+ console.warn(colors_1.default.yellow('WARNING: Multiple versions of Zenstack packages detected. Run "zenstack info" to see details.'));
37
+ }
38
+ }
39
+ const tasks = [runPlugins(options)];
40
+ if (options.versionCheck) {
41
+ tasks.push((0, cli_util_1.checkNewVersion)());
42
+ }
43
+ yield Promise.all(tasks);
44
+ });
45
+ }
46
+ exports.generate = generate;
47
+ function runPlugins(options) {
48
+ return __awaiter(this, void 0, void 0, function* () {
49
+ const model = yield (0, cli_util_1.loadDocument)(options.schema);
50
+ const runnerOpts = {
51
+ schema: model,
52
+ schemaPath: path_1.default.resolve(options.schema),
53
+ defaultPlugins: options.defaultPlugins,
54
+ output: options.output,
55
+ compile: options.compile,
56
+ };
57
+ try {
58
+ yield new plugin_runner_1.PluginRunner().run(runnerOpts);
59
+ }
60
+ catch (err) {
61
+ if (err instanceof sdk_1.PluginError) {
62
+ console.error(colors_1.default.red(`${err.plugin}: ${err.message}`));
63
+ throw new cli_error_1.CliError(err.message);
64
+ }
65
+ else {
66
+ throw err;
67
+ }
68
+ }
69
+ });
70
+ }
71
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/actions/generate.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,yCAA8C;AAC9C,oDAA4B;AAC5B,gDAAwB;AACxB,4CAAwC;AACxC,0CAMqB;AACrB,oDAAqE;AAWrE;;GAEG;AACH,SAAsB,QAAQ,CAAC,WAAmB,EAAE,OAAgB;;QAChE,IAAI,OAAO,CAAC,eAAe,EAAE;YACzB,IAAA,+BAAoB,EAAC,QAAQ,EAAE,gCAAqB,CAAC,CAAC;YACtD,IAAA,+BAAoB,EAAC,gBAAgB,EAAE,gCAAqB,CAAC,CAAC;SACjE;QAED,mDAAmD;QACnD,MAAM,QAAQ,GAAG,IAAA,8BAAmB,EAAC,WAAW,CAAC,CAAC;QAClD,IAAI,QAAQ,EAAE;YACV,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAS,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;YACjE,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;gBACnB,OAAO,CAAC,IAAI,CACR,gBAAM,CAAC,MAAM,CACT,+FAA+F,CAClG,CACJ,CAAC;aACL;SACJ;QAED,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;QAEpC,IAAI,OAAO,CAAC,YAAY,EAAE;YACtB,KAAK,CAAC,IAAI,CAAC,IAAA,0BAAe,GAAE,CAAC,CAAC;SACjC;QAED,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;CAAA;AA1BD,4BA0BC;AAED,SAAe,UAAU,CAAC,OAAgB;;QACtC,MAAM,KAAK,GAAG,MAAM,IAAA,uBAAY,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAEjD,MAAM,UAAU,GAAwB;YACpC,MAAM,EAAE,KAAK;YACb,UAAU,EAAE,cAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC;YACxC,cAAc,EAAE,OAAO,CAAC,cAAc;YACtC,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,OAAO;SAC3B,CAAC;QAEF,IAAI;YACA,MAAM,IAAI,4BAAY,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;SAC5C;QAAC,OAAO,GAAG,EAAE;YACV,IAAI,GAAG,YAAY,iBAAW,EAAE;gBAC5B,OAAO,CAAC,KAAK,CAAC,gBAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;gBAC3D,MAAM,IAAI,oBAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;aACnC;iBAAM;gBACH,MAAM,GAAG,CAAC;aACb;SACJ;IACL,CAAC;CAAA"}
@@ -0,0 +1,3 @@
1
+ export * from './generate';
2
+ export * from './info';
3
+ export * from './init';
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./generate"), exports);
18
+ __exportStar(require("./info"), exports);
19
+ __exportStar(require("./init"), exports);
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/actions/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,6CAA2B;AAC3B,yCAAuB;AACvB,yCAAuB"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * CLI action for getting information about installed ZenStack packages
3
+ */
4
+ export declare function info(projectPath: string): Promise<void>;
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.info = void 0;
16
+ const colors_1 = __importDefault(require("colors"));
17
+ const get_latest_version_1 = __importDefault(require("get-latest-version"));
18
+ const ora_1 = __importDefault(require("ora"));
19
+ const semver_1 = __importDefault(require("semver"));
20
+ const cli_util_1 = require("../cli-util");
21
+ /**
22
+ * CLI action for getting information about installed ZenStack packages
23
+ */
24
+ function info(projectPath) {
25
+ return __awaiter(this, void 0, void 0, function* () {
26
+ const packages = (0, cli_util_1.getZenStackPackages)(projectPath);
27
+ if (!packages) {
28
+ console.error('Unable to locate package.json. Are you in a valid project directory?');
29
+ return;
30
+ }
31
+ console.log('Installed ZenStack Packages:');
32
+ const versions = new Set();
33
+ for (const { pkg, version } of packages) {
34
+ versions.add(version);
35
+ console.log(` ${colors_1.default.green(pkg.padEnd(20))}\t${version}`);
36
+ }
37
+ if (versions.size > 1) {
38
+ console.warn(colors_1.default.yellow('WARNING: Multiple versions of Zenstack packages detected. This may cause issues.'));
39
+ }
40
+ else if (versions.size > 0) {
41
+ const spinner = (0, ora_1.default)('Checking npm registry').start();
42
+ const latest = yield (0, get_latest_version_1.default)('zenstack');
43
+ if (!latest) {
44
+ spinner.fail('unable to check for latest version');
45
+ }
46
+ else {
47
+ spinner.succeed();
48
+ const version = [...versions][0];
49
+ if (semver_1.default.gt(latest, version)) {
50
+ console.log(`A newer version of Zenstack is available: ${latest}.`);
51
+ }
52
+ else if (semver_1.default.gt(version, latest)) {
53
+ console.log('You are using a pre-release version of Zenstack.');
54
+ }
55
+ else {
56
+ console.log('You are using the latest version of Zenstack.');
57
+ }
58
+ }
59
+ }
60
+ });
61
+ }
62
+ exports.info = info;
63
+ //# sourceMappingURL=info.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"info.js","sourceRoot":"","sources":["../../../src/cli/actions/info.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,oDAA4B;AAC5B,4EAAkD;AAClD,8CAAsB;AACtB,oDAA4B;AAC5B,0CAAkD;AAElD;;GAEG;AACH,SAAsB,IAAI,CAAC,WAAmB;;QAC1C,MAAM,QAAQ,GAAG,IAAA,8BAAmB,EAAC,WAAW,CAAC,CAAC;QAClD,IAAI,CAAC,QAAQ,EAAE;YACX,OAAO,CAAC,KAAK,CAAC,sEAAsE,CAAC,CAAC;YACtF,OAAO;SACV;QAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;QACnC,KAAK,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,IAAI,QAAQ,EAAE;YACrC,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,OAAO,gBAAM,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;SAClE;QAED,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;YACnB,OAAO,CAAC,IAAI,CAAC,gBAAM,CAAC,MAAM,CAAC,kFAAkF,CAAC,CAAC,CAAC;SACnH;aAAM,IAAI,QAAQ,CAAC,IAAI,GAAG,CAAC,EAAE;YAC1B,MAAM,OAAO,GAAG,IAAA,aAAG,EAAC,uBAAuB,CAAC,CAAC,KAAK,EAAE,CAAC;YACrD,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAgB,EAAC,UAAU,CAAC,CAAC;YAElD,IAAI,CAAC,MAAM,EAAE;gBACT,OAAO,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;aACtD;iBAAM;gBACH,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,MAAM,OAAO,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjC,IAAI,gBAAM,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE;oBAC5B,OAAO,CAAC,GAAG,CAAC,6CAA6C,MAAM,GAAG,CAAC,CAAC;iBACvE;qBAAM,IAAI,gBAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE;oBACnC,OAAO,CAAC,GAAG,CAAC,kDAAkD,CAAC,CAAC;iBACnE;qBAAM;oBACH,OAAO,CAAC,GAAG,CAAC,+CAA+C,CAAC,CAAC;iBAChE;aACJ;SACJ;IACL,CAAC;CAAA;AAlCD,oBAkCC"}
@@ -0,0 +1,12 @@
1
+ import { PackageManagers } from '../../utils/pkg-utils';
2
+ declare type Options = {
3
+ prisma: string | undefined;
4
+ packageManager: PackageManagers | undefined;
5
+ versionCheck: boolean;
6
+ tag?: string;
7
+ };
8
+ /**
9
+ * CLI action for initializing an existing project
10
+ */
11
+ export declare function init(projectPath: string, options: Options): Promise<void>;
12
+ export {};
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.init = void 0;
16
+ const colors_1 = __importDefault(require("colors"));
17
+ const fs_1 = __importDefault(require("fs"));
18
+ const path_1 = __importDefault(require("path"));
19
+ const pkg_utils_1 = require("../../utils/pkg-utils");
20
+ const version_utils_1 = require("../../utils/version-utils");
21
+ const cli_error_1 = require("../cli-error");
22
+ const cli_util_1 = require("../cli-util");
23
+ /**
24
+ * CLI action for initializing an existing project
25
+ */
26
+ function init(projectPath, options) {
27
+ var _a;
28
+ return __awaiter(this, void 0, void 0, function* () {
29
+ if (!fs_1.default.existsSync(projectPath)) {
30
+ console.error(`Path does not exist: ${projectPath}`);
31
+ throw new cli_error_1.CliError('project path does not exist');
32
+ }
33
+ const defaultPrismaSchemaLocation = './prisma/schema.prisma';
34
+ let prismaSchema = options.prisma;
35
+ if (prismaSchema) {
36
+ if (!fs_1.default.existsSync(prismaSchema)) {
37
+ console.error(`Prisma schema file does not exist: ${prismaSchema}`);
38
+ throw new cli_error_1.CliError('prisma schema does not exist');
39
+ }
40
+ }
41
+ else if (fs_1.default.existsSync(defaultPrismaSchemaLocation)) {
42
+ prismaSchema = defaultPrismaSchemaLocation;
43
+ }
44
+ const zmodelFile = path_1.default.join(projectPath, './schema.zmodel');
45
+ let sampleModelGenerated = false;
46
+ if (fs_1.default.existsSync(zmodelFile)) {
47
+ console.warn(`ZenStack model already exists at ${zmodelFile}, not generating a new one.`);
48
+ }
49
+ else {
50
+ if (prismaSchema) {
51
+ // copy over schema.prisma
52
+ fs_1.default.copyFileSync(prismaSchema, zmodelFile);
53
+ }
54
+ else {
55
+ // create a new model
56
+ const starterContent = fs_1.default.readFileSync(path_1.default.join(__dirname, '../../res/starter.zmodel'), 'utf-8');
57
+ fs_1.default.writeFileSync(zmodelFile, starterContent);
58
+ sampleModelGenerated = true;
59
+ }
60
+ }
61
+ (0, pkg_utils_1.ensurePackage)('prisma', true, options.packageManager, 'latest', projectPath);
62
+ (0, pkg_utils_1.ensurePackage)('@prisma/client', false, options.packageManager, 'latest', projectPath);
63
+ const tag = (_a = options.tag) !== null && _a !== void 0 ? _a : (0, version_utils_1.getVersion)();
64
+ (0, pkg_utils_1.installPackage)('zenstack', true, options.packageManager, tag, projectPath);
65
+ (0, pkg_utils_1.installPackage)('@zenstackhq/runtime', false, options.packageManager, tag, projectPath);
66
+ if (sampleModelGenerated) {
67
+ console.log(`Sample model generated at: ${colors_1.default.blue(zmodelFile)}
68
+
69
+ Please check the following guide on how to model your app:
70
+ https://zenstack.dev/#/modeling-your-app.`);
71
+ }
72
+ else if (prismaSchema) {
73
+ console.log(`Your current Prisma schema "${prismaSchema}" has been copied to "${zmodelFile}".
74
+ Moving forward please edit this file and run "zenstack generate" to regenerate Prisma schema.`);
75
+ }
76
+ console.log(colors_1.default.green('\nProject initialized successfully!'));
77
+ if (options.versionCheck) {
78
+ yield (0, cli_util_1.checkNewVersion)();
79
+ }
80
+ });
81
+ }
82
+ exports.init = init;
83
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/actions/init.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,oDAA4B;AAC5B,4CAAoB;AACpB,gDAAwB;AACxB,qDAAuF;AACvF,6DAAuD;AACvD,4CAAwC;AACxC,0CAA8C;AAS9C;;GAEG;AACH,SAAsB,IAAI,CAAC,WAAmB,EAAE,OAAgB;;;QAC5D,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE;YAC7B,OAAO,CAAC,KAAK,CAAC,wBAAwB,WAAW,EAAE,CAAC,CAAC;YACrD,MAAM,IAAI,oBAAQ,CAAC,6BAA6B,CAAC,CAAC;SACrD;QAED,MAAM,2BAA2B,GAAG,wBAAwB,CAAC;QAC7D,IAAI,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC;QAClC,IAAI,YAAY,EAAE;YACd,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE;gBAC9B,OAAO,CAAC,KAAK,CAAC,sCAAsC,YAAY,EAAE,CAAC,CAAC;gBACpE,MAAM,IAAI,oBAAQ,CAAC,8BAA8B,CAAC,CAAC;aACtD;SACJ;aAAM,IAAI,YAAE,CAAC,UAAU,CAAC,2BAA2B,CAAC,EAAE;YACnD,YAAY,GAAG,2BAA2B,CAAC;SAC9C;QAED,MAAM,UAAU,GAAG,cAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAC7D,IAAI,oBAAoB,GAAG,KAAK,CAAC;QAEjC,IAAI,YAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE;YAC3B,OAAO,CAAC,IAAI,CAAC,oCAAoC,UAAU,6BAA6B,CAAC,CAAC;SAC7F;aAAM;YACH,IAAI,YAAY,EAAE;gBACd,0BAA0B;gBAC1B,YAAE,CAAC,YAAY,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;aAC7C;iBAAM;gBACH,qBAAqB;gBACrB,MAAM,cAAc,GAAG,YAAE,CAAC,YAAY,CAAC,cAAI,CAAC,IAAI,CAAC,SAAS,EAAE,0BAA0B,CAAC,EAAE,OAAO,CAAC,CAAC;gBAClG,YAAE,CAAC,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;gBAC7C,oBAAoB,GAAG,IAAI,CAAC;aAC/B;SACJ;QAED,IAAA,yBAAa,EAAC,QAAQ,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC7E,IAAA,yBAAa,EAAC,gBAAgB,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAEtF,MAAM,GAAG,GAAG,MAAA,OAAO,CAAC,GAAG,mCAAI,IAAA,0BAAU,GAAE,CAAC;QACxC,IAAA,0BAAc,EAAC,UAAU,EAAE,IAAI,EAAE,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QAC3E,IAAA,0BAAc,EAAC,qBAAqB,EAAE,KAAK,EAAE,OAAO,CAAC,cAAc,EAAE,GAAG,EAAE,WAAW,CAAC,CAAC;QAEvF,IAAI,oBAAoB,EAAE;YACtB,OAAO,CAAC,GAAG,CAAC,8BAA8B,gBAAM,CAAC,IAAI,CAAC,UAAU,CAAC;;;8CAG3B,CAAC,CAAC;SAC3C;aAAM,IAAI,YAAY,EAAE;YACrB,OAAO,CAAC,GAAG,CACP,+BAA+B,YAAY,yBAAyB,UAAU;8FACI,CACrF,CAAC;SACL;QAED,OAAO,CAAC,GAAG,CAAC,gBAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;QAEjE,IAAI,OAAO,CAAC,YAAY,EAAE;YACtB,MAAM,IAAA,0BAAe,GAAE,CAAC;SAC3B;;CACJ;AA1DD,oBA0DC"}
package/cli/cli-util.d.ts CHANGED
@@ -1,18 +1,21 @@
1
1
  import { Model } from '@zenstackhq/language/ast';
2
- import { LangiumServices } from 'langium';
3
- import { PackageManagers } from '../utils/pkg-utils';
4
- /**
5
- * Initializes an existing project for ZenStack
6
- */
7
- export declare function initProject(projectPath: string, prismaSchema: string | undefined, packageManager: PackageManagers | undefined, tag: string): Promise<void>;
2
+ import { LangiumDocument, LangiumDocuments } from 'langium';
3
+ import { URI } from 'vscode-uri';
4
+ import { ZModelServices } from '../language-server/zmodel-module';
5
+ export declare const requiredPrismaVersion = "4.8.0";
8
6
  /**
9
7
  * Loads a zmodel document from a file.
10
8
  * @param fileName File name
11
9
  * @param services Language services
12
10
  * @returns Parsed and validated AST
13
11
  */
14
- export declare function loadDocument(fileName: string, services: LangiumServices): Promise<Model>;
15
- export declare function runPlugins(options: {
16
- schema: string;
17
- packageManager: PackageManagers | undefined;
18
- }): Promise<void>;
12
+ export declare function loadDocument(fileName: string): Promise<Model>;
13
+ export declare function eagerLoadAllImports(document: LangiumDocument, documents: LangiumDocuments, uris?: Set<string>): URI[];
14
+ export declare function mergeImportsDeclarations(documents: LangiumDocuments, model: Model): void;
15
+ export declare function getPluginDocuments(services: ZModelServices, fileName: string): Promise<LangiumDocument[]>;
16
+ export declare function getZenStackPackages(projectPath: string): {
17
+ pkg: string;
18
+ version: any;
19
+ }[] | undefined;
20
+ export declare function checkRequiredPackage(packageName: string, minVersion?: string): void;
21
+ export declare function checkNewVersion(): Promise<void>;