@zenstackhq/cli 3.0.0-alpha.3 → 3.0.0-alpha.30

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/dist/index.cjs CHANGED
@@ -6,9 +6,6 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
8
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
- var __commonJS = (cb, mod) => function __require() {
10
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
- };
12
9
  var __export = (target, all) => {
13
10
  for (var name in all)
14
11
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -31,69 +28,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
31
28
  ));
32
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
30
 
34
- // package.json
35
- var require_package = __commonJS({
36
- "package.json"(exports2, module2) {
37
- module2.exports = {
38
- name: "@zenstackhq/cli",
39
- publisher: "zenstack",
40
- displayName: "ZenStack CLI",
41
- description: "FullStack database toolkit with built-in access control and automatic API generation.",
42
- version: "3.0.0-alpha.3",
43
- type: "module",
44
- author: {
45
- name: "ZenStack Team"
46
- },
47
- homepage: "https://zenstack.dev",
48
- license: "MIT",
49
- keywords: [
50
- "orm",
51
- "fullstack",
52
- "react",
53
- "typescript",
54
- "data modeling"
55
- ],
56
- bin: {
57
- zenstack: "bin/cli"
58
- },
59
- scripts: {
60
- build: "tsup-node",
61
- watch: "tsup-node --watch",
62
- lint: "eslint src --ext ts",
63
- test: "vitest",
64
- pack: "pnpm pack"
65
- },
66
- dependencies: {
67
- "@types/node": "^20.0.0",
68
- "@zenstackhq/language": "workspace:*",
69
- "@zenstackhq/sdk": "workspace:*",
70
- "async-exit-hook": "^2.0.1",
71
- colors: "1.4.0",
72
- commander: "^8.3.0",
73
- langium: "~3.3.0",
74
- ora: "^5.4.1",
75
- "package-manager-detector": "^1.3.0",
76
- "tiny-invariant": "^1.3.3",
77
- "ts-pattern": "^4.3.0"
78
- },
79
- peerDependencies: {
80
- prisma: "^6.0.0",
81
- typescript: "^5.0.0"
82
- },
83
- devDependencies: {
84
- "@types/async-exit-hook": "^2.0.0",
85
- "@types/better-sqlite3": "^7.6.13",
86
- "@types/semver": "^7.3.13",
87
- "@types/tmp": "^0.2.6",
88
- "@zenstackhq/runtime": "workspace:*",
89
- "@zenstackhq/testtools": "workspace:*",
90
- "better-sqlite3": "^11.8.1",
91
- tmp: "^0.2.3"
92
- }
93
- };
94
- }
95
- });
96
-
97
31
  // src/index.ts
98
32
  var src_exports = {};
99
33
  __export(src_exports, {
@@ -101,11 +35,11 @@ __export(src_exports, {
101
35
  });
102
36
  module.exports = __toCommonJS(src_exports);
103
37
  var import_language2 = require("@zenstackhq/language");
104
- var import_colors5 = __toESM(require("colors"), 1);
38
+ var import_colors6 = __toESM(require("colors"), 1);
105
39
  var import_commander = require("commander");
106
40
 
107
41
  // src/actions/db.ts
108
- var import_node_path2 = __toESM(require("path"), 1);
42
+ var import_node_fs2 = __toESM(require("fs"), 1);
109
43
 
110
44
  // src/utils/exec-utils.ts
111
45
  var import_child_process = require("child_process");
@@ -130,7 +64,12 @@ function execPackage(cmd, options) {
130
64
  __name(execPackage, "execPackage");
131
65
 
132
66
  // src/actions/action-utils.ts
67
+ var import_language = require("@zenstackhq/language");
68
+ var import_ast = require("@zenstackhq/language/ast");
69
+ var import_sdk = require("@zenstackhq/sdk");
70
+ var import_colors = __toESM(require("colors"), 1);
133
71
  var import_node_fs = __toESM(require("fs"), 1);
72
+ var import_node_path = __toESM(require("path"), 1);
134
73
 
135
74
  // src/cli-error.ts
136
75
  var CliError = class extends Error {
@@ -140,8 +79,6 @@ var CliError = class extends Error {
140
79
  };
141
80
 
142
81
  // src/actions/action-utils.ts
143
- var import_language = require("@zenstackhq/language");
144
- var import_colors = __toESM(require("colors"), 1);
145
82
  function getSchemaFile(file) {
146
83
  if (file) {
147
84
  if (!import_node_fs.default.existsSync(file)) {
@@ -149,6 +86,13 @@ function getSchemaFile(file) {
149
86
  }
150
87
  return file;
151
88
  }
89
+ const pkgJsonConfig = getPkgJsonConfig(process.cwd());
90
+ if (pkgJsonConfig.schema) {
91
+ if (!import_node_fs.default.existsSync(pkgJsonConfig.schema)) {
92
+ throw new CliError(`Schema file not found: ${pkgJsonConfig.schema}`);
93
+ }
94
+ return pkgJsonConfig.schema;
95
+ }
152
96
  if (import_node_fs.default.existsSync("./zenstack/schema.zmodel")) {
153
97
  return "./zenstack/schema.zmodel";
154
98
  } else if (import_node_fs.default.existsSync("./schema.zmodel")) {
@@ -161,12 +105,14 @@ __name(getSchemaFile, "getSchemaFile");
161
105
  async function loadSchemaDocument(schemaFile) {
162
106
  const loadResult = await (0, import_language.loadDocument)(schemaFile);
163
107
  if (!loadResult.success) {
164
- console.error(import_colors.default.red("Error loading schema:"));
165
108
  loadResult.errors.forEach((err) => {
166
109
  console.error(import_colors.default.red(err));
167
110
  });
168
- throw new CliError("Failed to load schema");
111
+ throw new CliError("Schema contains errors. See above for details.");
169
112
  }
113
+ loadResult.warnings.forEach((warn) => {
114
+ console.warn(import_colors.default.yellow(warn));
115
+ });
170
116
  return loadResult.model;
171
117
  }
172
118
  __name(loadSchemaDocument, "loadSchemaDocument");
@@ -178,90 +124,272 @@ function handleSubProcessError(err) {
178
124
  }
179
125
  }
180
126
  __name(handleSubProcessError, "handleSubProcessError");
127
+ async function generateTempPrismaSchema(zmodelPath, folder) {
128
+ const model = await loadSchemaDocument(zmodelPath);
129
+ if (!model.declarations.some(import_ast.isDataSource)) {
130
+ throw new CliError("Schema must define a datasource");
131
+ }
132
+ const prismaSchema = await new import_sdk.PrismaSchemaGenerator(model).generate();
133
+ if (!folder) {
134
+ folder = import_node_path.default.dirname(zmodelPath);
135
+ }
136
+ const prismaSchemaFile = import_node_path.default.resolve(folder, "~schema.prisma");
137
+ import_node_fs.default.writeFileSync(prismaSchemaFile, prismaSchema);
138
+ return prismaSchemaFile;
139
+ }
140
+ __name(generateTempPrismaSchema, "generateTempPrismaSchema");
141
+ function getPkgJsonConfig(startPath) {
142
+ const result = {
143
+ schema: void 0,
144
+ output: void 0
145
+ };
146
+ const pkgJsonFile = findUp([
147
+ "package.json"
148
+ ], startPath, false);
149
+ if (!pkgJsonFile) {
150
+ return result;
151
+ }
152
+ let pkgJson = void 0;
153
+ try {
154
+ pkgJson = JSON.parse(import_node_fs.default.readFileSync(pkgJsonFile, "utf8"));
155
+ } catch {
156
+ return result;
157
+ }
158
+ if (pkgJson.zenstack && typeof pkgJson.zenstack === "object") {
159
+ result.schema = pkgJson.zenstack.schema && import_node_path.default.resolve(import_node_path.default.dirname(pkgJsonFile), pkgJson.zenstack.schema);
160
+ result.output = pkgJson.zenstack.output && import_node_path.default.resolve(import_node_path.default.dirname(pkgJsonFile), pkgJson.zenstack.output);
161
+ }
162
+ return result;
163
+ }
164
+ __name(getPkgJsonConfig, "getPkgJsonConfig");
165
+ function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
166
+ if (!names.some((name) => !!name)) {
167
+ return void 0;
168
+ }
169
+ const target = names.find((name) => import_node_fs.default.existsSync(import_node_path.default.join(cwd, name)));
170
+ if (multiple === false && target) {
171
+ return import_node_path.default.join(cwd, target);
172
+ }
173
+ if (target) {
174
+ result.push(import_node_path.default.join(cwd, target));
175
+ }
176
+ const up = import_node_path.default.resolve(cwd, "..");
177
+ if (up === cwd) {
178
+ return multiple && result.length > 0 ? result : void 0;
179
+ }
180
+ return findUp(names, up, multiple, result);
181
+ }
182
+ __name(findUp, "findUp");
183
+
184
+ // src/actions/db.ts
185
+ async function run(command, options) {
186
+ switch (command) {
187
+ case "push":
188
+ await runPush(options);
189
+ break;
190
+ }
191
+ }
192
+ __name(run, "run");
193
+ async function runPush(options) {
194
+ const schemaFile = getSchemaFile(options.schema);
195
+ const prismaSchemaFile = await generateTempPrismaSchema(schemaFile);
196
+ try {
197
+ const cmd = [
198
+ "prisma db push",
199
+ ` --schema "${prismaSchemaFile}"`,
200
+ options.acceptDataLoss ? " --accept-data-loss" : "",
201
+ options.forceReset ? " --force-reset" : "",
202
+ " --skip-generate"
203
+ ].join("");
204
+ try {
205
+ await execPackage(cmd);
206
+ } catch (err) {
207
+ handleSubProcessError(err);
208
+ }
209
+ } finally {
210
+ if (import_node_fs2.default.existsSync(prismaSchemaFile)) {
211
+ import_node_fs2.default.unlinkSync(prismaSchemaFile);
212
+ }
213
+ }
214
+ }
215
+ __name(runPush, "runPush");
181
216
 
182
217
  // src/actions/generate.ts
183
- var import_ast = require("@zenstackhq/language/ast");
184
- var import_sdk = require("@zenstackhq/sdk");
218
+ var import_common_helpers = require("@zenstackhq/common-helpers");
219
+ var import_ast2 = require("@zenstackhq/language/ast");
220
+ var import_utils = require("@zenstackhq/language/utils");
185
221
  var import_colors2 = __toESM(require("colors"), 1);
186
- var import_node_fs2 = __toESM(require("fs"), 1);
187
- var import_node_path = __toESM(require("path"), 1);
188
- var import_tiny_invariant = __toESM(require("tiny-invariant"), 1);
189
- async function run(options) {
222
+ var import_node_path4 = __toESM(require("path"), 1);
223
+ var import_ora = __toESM(require("ora"), 1);
224
+
225
+ // src/plugins/index.ts
226
+ var plugins_exports = {};
227
+ __export(plugins_exports, {
228
+ prisma: () => prisma_default,
229
+ typescript: () => typescript_default
230
+ });
231
+
232
+ // src/plugins/prisma.ts
233
+ var import_sdk2 = require("@zenstackhq/sdk");
234
+ var import_node_fs3 = __toESM(require("fs"), 1);
235
+ var import_node_path2 = __toESM(require("path"), 1);
236
+ var plugin = {
237
+ name: "Prisma Schema Generator",
238
+ statusText: "Generating Prisma schema",
239
+ async generate({ model, schemaFile, defaultOutputPath, pluginOptions }) {
240
+ let outFile = import_node_path2.default.join(defaultOutputPath, "schema.prisma");
241
+ if (typeof pluginOptions["output"] === "string") {
242
+ outFile = import_node_path2.default.resolve(import_node_path2.default.dirname(schemaFile), pluginOptions["output"]);
243
+ if (!import_node_fs3.default.existsSync(import_node_path2.default.dirname(outFile))) {
244
+ import_node_fs3.default.mkdirSync(import_node_path2.default.dirname(outFile), {
245
+ recursive: true
246
+ });
247
+ }
248
+ }
249
+ const prismaSchema = await new import_sdk2.PrismaSchemaGenerator(model).generate();
250
+ import_node_fs3.default.writeFileSync(outFile, prismaSchema);
251
+ }
252
+ };
253
+ var prisma_default = plugin;
254
+
255
+ // src/plugins/typescript.ts
256
+ var import_sdk3 = require("@zenstackhq/sdk");
257
+ var import_node_fs4 = __toESM(require("fs"), 1);
258
+ var import_node_path3 = __toESM(require("path"), 1);
259
+ var plugin2 = {
260
+ name: "TypeScript Schema Generator",
261
+ statusText: "Generating TypeScript schema",
262
+ async generate({ model, defaultOutputPath, pluginOptions }) {
263
+ let outDir = defaultOutputPath;
264
+ if (typeof pluginOptions["output"] === "string") {
265
+ outDir = import_node_path3.default.resolve(defaultOutputPath, pluginOptions["output"]);
266
+ if (!import_node_fs4.default.existsSync(outDir)) {
267
+ import_node_fs4.default.mkdirSync(outDir, {
268
+ recursive: true
269
+ });
270
+ }
271
+ }
272
+ await new import_sdk3.TsSchemaGenerator().generate(model, outDir);
273
+ }
274
+ };
275
+ var typescript_default = plugin2;
276
+
277
+ // src/actions/generate.ts
278
+ async function run2(options) {
279
+ const start = Date.now();
190
280
  const schemaFile = getSchemaFile(options.schema);
191
281
  const model = await loadSchemaDocument(schemaFile);
192
- const outputPath = options.output ?? import_node_path.default.dirname(schemaFile);
193
- const tsSchemaFile = import_node_path.default.join(outputPath, "schema.ts");
194
- await new import_sdk.TsSchemaGenerator().generate(schemaFile, [], tsSchemaFile);
195
- await runPlugins(model, outputPath, tsSchemaFile);
196
- const prismaSchema = await new import_sdk.PrismaSchemaGenerator(model).generate();
197
- import_node_fs2.default.writeFileSync(import_node_path.default.join(outputPath, "schema.prisma"), prismaSchema);
198
- if (!options.silent) {
199
- console.log(import_colors2.default.green("Generation completed successfully."));
200
- console.log(`You can now create a ZenStack client with it.
282
+ const outputPath = getOutputPath(options, schemaFile);
283
+ await runPlugins(schemaFile, model, outputPath);
284
+ console.log(import_colors2.default.green(`Generation completed successfully in ${Date.now() - start}ms.
285
+ `));
286
+ console.log(`You can now create a ZenStack client with it.
201
287
 
202
288
  \`\`\`ts
203
289
  import { ZenStackClient } from '@zenstackhq/runtime';
204
290
  import { schema } from '${outputPath}/schema';
205
291
 
206
292
  const client = new ZenStackClient(schema, {
207
- dialectConfig: { ... }
293
+ dialect: { ... }
208
294
  });
209
- \`\`\`
210
- `);
295
+ \`\`\``);
296
+ }
297
+ __name(run2, "run");
298
+ function getOutputPath(options, schemaFile) {
299
+ if (options.output) {
300
+ return options.output;
301
+ }
302
+ const pkgJsonConfig = getPkgJsonConfig(process.cwd());
303
+ if (pkgJsonConfig.output) {
304
+ return pkgJsonConfig.output;
305
+ } else {
306
+ return import_node_path4.default.dirname(schemaFile);
211
307
  }
212
308
  }
213
- __name(run, "run");
214
- async function runPlugins(model, outputPath, tsSchemaFile) {
215
- const plugins = model.declarations.filter(import_ast.isPlugin);
216
- for (const plugin of plugins) {
217
- const providerField = plugin.fields.find((f) => f.name === "provider");
218
- (0, import_tiny_invariant.default)(providerField, `Plugin ${plugin.name} does not have a provider field`);
219
- const provider = providerField.value.value;
220
- let useProvider = provider;
221
- if (useProvider.startsWith("@core/")) {
222
- useProvider = `@zenstackhq/runtime/plugins/${useProvider.slice(6)}`;
309
+ __name(getOutputPath, "getOutputPath");
310
+ async function runPlugins(schemaFile, model, outputPath) {
311
+ const plugins = model.declarations.filter(import_ast2.isPlugin);
312
+ const processedPlugins = [];
313
+ for (const plugin3 of plugins) {
314
+ const provider = getPluginProvider(plugin3);
315
+ let cliPlugin;
316
+ if (provider.startsWith("@core/")) {
317
+ cliPlugin = plugins_exports[provider.slice("@core/".length)];
318
+ if (!cliPlugin) {
319
+ throw new CliError(`Unknown core plugin: ${provider}`);
320
+ }
321
+ } else {
322
+ let moduleSpec = provider;
323
+ if (moduleSpec.startsWith(".")) {
324
+ moduleSpec = import_node_path4.default.resolve(import_node_path4.default.dirname(schemaFile), moduleSpec);
325
+ }
326
+ try {
327
+ cliPlugin = (await import(moduleSpec)).default;
328
+ } catch (error) {
329
+ throw new CliError(`Failed to load plugin ${provider}: ${error}`);
330
+ }
223
331
  }
224
- const generator = (await import(useProvider)).default;
225
- console.log("Running generator:", provider);
226
- await generator({
227
- model,
228
- outputPath,
229
- tsSchemaFile
332
+ processedPlugins.push({
333
+ cliPlugin,
334
+ pluginOptions: getPluginOptions(plugin3)
230
335
  });
231
336
  }
232
- }
233
- __name(runPlugins, "runPlugins");
234
-
235
- // src/actions/db.ts
236
- async function run2(command, options) {
237
- const schemaFile = getSchemaFile(options.schema);
238
- await run({
239
- schema: schemaFile,
240
- silent: true
337
+ const defaultPlugins = [
338
+ typescript_default
339
+ ].reverse();
340
+ defaultPlugins.forEach((d) => {
341
+ if (!processedPlugins.some((p) => p.cliPlugin === d)) {
342
+ processedPlugins.push({
343
+ cliPlugin: d,
344
+ pluginOptions: {}
345
+ });
346
+ }
241
347
  });
242
- const prismaSchemaFile = import_node_path2.default.join(import_node_path2.default.dirname(schemaFile), "schema.prisma");
243
- switch (command) {
244
- case "push":
245
- await runPush(prismaSchemaFile, options);
246
- break;
348
+ for (const { cliPlugin, pluginOptions } of processedPlugins) {
349
+ (0, import_common_helpers.invariant)(typeof cliPlugin.generate === "function", `Plugin ${cliPlugin.name} does not have a generate function`);
350
+ const spinner = (0, import_ora.default)(cliPlugin.statusText ?? `Running plugin ${cliPlugin.name}`).start();
351
+ try {
352
+ await cliPlugin.generate({
353
+ schemaFile,
354
+ model,
355
+ defaultOutputPath: outputPath,
356
+ pluginOptions
357
+ });
358
+ spinner.succeed();
359
+ } catch (err) {
360
+ spinner.fail();
361
+ console.error(err);
362
+ }
247
363
  }
248
364
  }
249
- __name(run2, "run");
250
- async function runPush(prismaSchemaFile, options) {
251
- const cmd = `prisma db push --schema "${prismaSchemaFile}"${options.acceptDataLoss ? " --accept-data-loss" : ""}${options.forceReset ? " --force-reset" : ""} --skip-generate`;
252
- try {
253
- await execPackage(cmd, {
254
- stdio: "inherit"
255
- });
256
- } catch (err) {
257
- handleSubProcessError(err);
365
+ __name(runPlugins, "runPlugins");
366
+ function getPluginProvider(plugin3) {
367
+ const providerField = plugin3.fields.find((f) => f.name === "provider");
368
+ (0, import_common_helpers.invariant)(providerField, `Plugin ${plugin3.name} does not have a provider field`);
369
+ const provider = providerField.value.value;
370
+ return provider;
371
+ }
372
+ __name(getPluginProvider, "getPluginProvider");
373
+ function getPluginOptions(plugin3) {
374
+ const result = {};
375
+ for (const field of plugin3.fields) {
376
+ if (field.name === "provider") {
377
+ continue;
378
+ }
379
+ const value = (0, import_utils.getLiteral)(field.value) ?? (0, import_utils.getLiteralArray)(field.value);
380
+ if (value === void 0) {
381
+ console.warn(`Plugin "${plugin3.name}" option "${field.name}" has unsupported value, skipping`);
382
+ continue;
383
+ }
384
+ result[field.name] = value;
258
385
  }
386
+ return result;
259
387
  }
260
- __name(runPush, "runPush");
388
+ __name(getPluginOptions, "getPluginOptions");
261
389
 
262
390
  // src/actions/info.ts
263
391
  var import_colors3 = __toESM(require("colors"), 1);
264
- var import_node_path3 = __toESM(require("path"), 1);
392
+ var import_node_path5 = __toESM(require("path"), 1);
265
393
  async function run3(projectPath) {
266
394
  const packages = await getZenStackPackages(projectPath);
267
395
  if (!packages) {
@@ -283,14 +411,14 @@ async function run3(projectPath) {
283
411
  __name(run3, "run");
284
412
  async function getZenStackPackages(projectPath) {
285
413
  let pkgJson;
286
- const resolvedPath = import_node_path3.default.resolve(projectPath);
414
+ const resolvedPath = import_node_path5.default.resolve(projectPath);
287
415
  try {
288
- pkgJson = (await import(import_node_path3.default.join(resolvedPath, "package.json"), {
416
+ pkgJson = (await import(import_node_path5.default.join(resolvedPath, "package.json"), {
289
417
  with: {
290
418
  type: "json"
291
419
  }
292
420
  })).default;
293
- } catch (err) {
421
+ } catch {
294
422
  return [];
295
423
  }
296
424
  const packages = Array.from(new Set([
@@ -321,9 +449,9 @@ __name(getZenStackPackages, "getZenStackPackages");
321
449
 
322
450
  // src/actions/init.ts
323
451
  var import_colors4 = __toESM(require("colors"), 1);
324
- var import_node_fs3 = __toESM(require("fs"), 1);
325
- var import_node_path4 = __toESM(require("path"), 1);
326
- var import_ora = __toESM(require("ora"), 1);
452
+ var import_node_fs5 = __toESM(require("fs"), 1);
453
+ var import_node_path6 = __toESM(require("path"), 1);
454
+ var import_ora2 = __toESM(require("ora"), 1);
327
455
  var import_package_manager_detector = require("package-manager-detector");
328
456
 
329
457
  // src/actions/templates.ts
@@ -385,7 +513,7 @@ async function run4(projectPath) {
385
513
  if (!resolved) {
386
514
  throw new CliError(`Unable to determine how to install package "${pkg.name}". Please install it manually.`);
387
515
  }
388
- const spinner = (0, import_ora.default)(`Installing "${pkg.name}"`).start();
516
+ const spinner = (0, import_ora2.default)(`Installing "${pkg.name}"`).start();
389
517
  try {
390
518
  execSync(`${resolved.command} ${resolved.args.join(" ")}`, {
391
519
  cwd: projectPath
@@ -397,11 +525,11 @@ async function run4(projectPath) {
397
525
  }
398
526
  }
399
527
  const generationFolder = "zenstack";
400
- if (!import_node_fs3.default.existsSync(import_node_path4.default.join(projectPath, generationFolder))) {
401
- import_node_fs3.default.mkdirSync(import_node_path4.default.join(projectPath, generationFolder));
528
+ if (!import_node_fs5.default.existsSync(import_node_path6.default.join(projectPath, generationFolder))) {
529
+ import_node_fs5.default.mkdirSync(import_node_path6.default.join(projectPath, generationFolder));
402
530
  }
403
- if (!import_node_fs3.default.existsSync(import_node_path4.default.join(projectPath, generationFolder, "schema.zmodel"))) {
404
- import_node_fs3.default.writeFileSync(import_node_path4.default.join(projectPath, generationFolder, "schema.zmodel"), STARTER_ZMODEL);
531
+ if (!import_node_fs5.default.existsSync(import_node_path6.default.join(projectPath, generationFolder, "schema.zmodel"))) {
532
+ import_node_fs5.default.writeFileSync(import_node_path6.default.join(projectPath, generationFolder, "schema.zmodel"), STARTER_ZMODEL);
405
533
  } else {
406
534
  console.log(import_colors4.default.yellow("Schema file already exists. Skipping generation of sample."));
407
535
  }
@@ -412,35 +540,47 @@ async function run4(projectPath) {
412
540
  __name(run4, "run");
413
541
 
414
542
  // src/actions/migrate.ts
415
- var import_node_path5 = __toESM(require("path"), 1);
543
+ var import_node_fs6 = __toESM(require("fs"), 1);
544
+ var import_node_path7 = __toESM(require("path"), 1);
416
545
  async function run5(command, options) {
417
546
  const schemaFile = getSchemaFile(options.schema);
418
- await run({
419
- schema: schemaFile,
420
- silent: true
421
- });
422
- const prismaSchemaFile = import_node_path5.default.join(import_node_path5.default.dirname(schemaFile), "schema.prisma");
423
- switch (command) {
424
- case "dev":
425
- await runDev(prismaSchemaFile, options);
426
- break;
427
- case "reset":
428
- await runReset(prismaSchemaFile, options);
429
- break;
430
- case "deploy":
431
- await runDeploy(prismaSchemaFile, options);
432
- break;
433
- case "status":
434
- await runStatus(prismaSchemaFile, options);
435
- break;
547
+ const prismaSchemaDir = options.migrations ? import_node_path7.default.dirname(options.migrations) : void 0;
548
+ const prismaSchemaFile = await generateTempPrismaSchema(schemaFile, prismaSchemaDir);
549
+ try {
550
+ switch (command) {
551
+ case "dev":
552
+ await runDev(prismaSchemaFile, options);
553
+ break;
554
+ case "reset":
555
+ await runReset(prismaSchemaFile, options);
556
+ break;
557
+ case "deploy":
558
+ await runDeploy(prismaSchemaFile, options);
559
+ break;
560
+ case "status":
561
+ await runStatus(prismaSchemaFile, options);
562
+ break;
563
+ case "resolve":
564
+ await runResolve(prismaSchemaFile, options);
565
+ break;
566
+ }
567
+ } finally {
568
+ if (import_node_fs6.default.existsSync(prismaSchemaFile)) {
569
+ import_node_fs6.default.unlinkSync(prismaSchemaFile);
570
+ }
436
571
  }
437
572
  }
438
573
  __name(run5, "run");
439
- async function runDev(prismaSchemaFile, _options) {
574
+ async function runDev(prismaSchemaFile, options) {
440
575
  try {
441
- await execPackage(`prisma migrate dev --schema "${prismaSchemaFile}" --skip-generate`, {
442
- stdio: "inherit"
443
- });
576
+ const cmd = [
577
+ "prisma migrate dev",
578
+ ` --schema "${prismaSchemaFile}"`,
579
+ " --skip-generate",
580
+ options.name ? ` --name ${options.name}` : "",
581
+ options.createOnly ? " --create-only" : ""
582
+ ].join("");
583
+ await execPackage(cmd);
444
584
  } catch (err) {
445
585
  handleSubProcessError2(err);
446
586
  }
@@ -448,9 +588,12 @@ async function runDev(prismaSchemaFile, _options) {
448
588
  __name(runDev, "runDev");
449
589
  async function runReset(prismaSchemaFile, options) {
450
590
  try {
451
- await execPackage(`prisma migrate reset --schema "${prismaSchemaFile}"${options.force ? " --force" : ""}`, {
452
- stdio: "inherit"
453
- });
591
+ const cmd = [
592
+ "prisma migrate reset",
593
+ ` --schema "${prismaSchemaFile}"`,
594
+ options.force ? " --force" : ""
595
+ ].join("");
596
+ await execPackage(cmd);
454
597
  } catch (err) {
455
598
  handleSubProcessError2(err);
456
599
  }
@@ -458,9 +601,11 @@ async function runReset(prismaSchemaFile, options) {
458
601
  __name(runReset, "runReset");
459
602
  async function runDeploy(prismaSchemaFile, _options) {
460
603
  try {
461
- await execPackage(`prisma migrate deploy --schema "${prismaSchemaFile}"`, {
462
- stdio: "inherit"
463
- });
604
+ const cmd = [
605
+ "prisma migrate deploy",
606
+ ` --schema "${prismaSchemaFile}"`
607
+ ].join("");
608
+ await execPackage(cmd);
464
609
  } catch (err) {
465
610
  handleSubProcessError2(err);
466
611
  }
@@ -468,14 +613,29 @@ async function runDeploy(prismaSchemaFile, _options) {
468
613
  __name(runDeploy, "runDeploy");
469
614
  async function runStatus(prismaSchemaFile, _options) {
470
615
  try {
471
- await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`, {
472
- stdio: "inherit"
473
- });
616
+ await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`);
474
617
  } catch (err) {
475
618
  handleSubProcessError2(err);
476
619
  }
477
620
  }
478
621
  __name(runStatus, "runStatus");
622
+ async function runResolve(prismaSchemaFile, options) {
623
+ if (!options.applied && !options.rolledBack) {
624
+ throw new CliError("Either --applied or --rolled-back option must be provided");
625
+ }
626
+ try {
627
+ const cmd = [
628
+ "prisma migrate resolve",
629
+ ` --schema "${prismaSchemaFile}"`,
630
+ options.applied ? ` --applied ${options.applied}` : "",
631
+ options.rolledBack ? ` --rolled-back ${options.rolledBack}` : ""
632
+ ].join("");
633
+ await execPackage(cmd);
634
+ } catch (err) {
635
+ handleSubProcessError2(err);
636
+ }
637
+ }
638
+ __name(runResolve, "runResolve");
479
639
  function handleSubProcessError2(err) {
480
640
  if (err instanceof Error && "status" in err && typeof err.status === "number") {
481
641
  process.exit(err.status);
@@ -485,29 +645,44 @@ function handleSubProcessError2(err) {
485
645
  }
486
646
  __name(handleSubProcessError2, "handleSubProcessError");
487
647
 
648
+ // src/actions/check.ts
649
+ var import_colors5 = __toESM(require("colors"), 1);
650
+ async function run6(options) {
651
+ const schemaFile = getSchemaFile(options.schema);
652
+ try {
653
+ await loadSchemaDocument(schemaFile);
654
+ console.log(import_colors5.default.green("\u2713 Schema validation completed successfully."));
655
+ } catch (error) {
656
+ console.error(import_colors5.default.red("\u2717 Schema validation failed."));
657
+ throw error;
658
+ }
659
+ }
660
+ __name(run6, "run");
661
+
488
662
  // src/utils/version-utils.ts
663
+ var import_node_fs7 = __toESM(require("fs"), 1);
664
+ var import_node_path8 = __toESM(require("path"), 1);
665
+ var import_node_url = require("url");
666
+ var import_meta = {};
489
667
  function getVersion() {
490
668
  try {
491
- return require("../package.json").version;
669
+ const _dirname = typeof __dirname !== "undefined" ? __dirname : import_node_path8.default.dirname((0, import_node_url.fileURLToPath)(import_meta.url));
670
+ return JSON.parse(import_node_fs7.default.readFileSync(import_node_path8.default.join(_dirname, "../package.json"), "utf8")).version;
492
671
  } catch {
493
- try {
494
- return require_package().version;
495
- } catch {
496
- return void 0;
497
- }
672
+ return void 0;
498
673
  }
499
674
  }
500
675
  __name(getVersion, "getVersion");
501
676
 
502
677
  // src/index.ts
503
678
  var generateAction = /* @__PURE__ */ __name(async (options) => {
504
- await run(options);
679
+ await run2(options);
505
680
  }, "generateAction");
506
681
  var migrateAction = /* @__PURE__ */ __name(async (command, options) => {
507
682
  await run5(command, options);
508
683
  }, "migrateAction");
509
684
  var dbAction = /* @__PURE__ */ __name(async (command, options) => {
510
- await run2(command, options);
685
+ await run(command, options);
511
686
  }, "dbAction");
512
687
  var infoAction = /* @__PURE__ */ __name(async (projectPath) => {
513
688
  await run3(projectPath);
@@ -515,29 +690,46 @@ var infoAction = /* @__PURE__ */ __name(async (projectPath) => {
515
690
  var initAction = /* @__PURE__ */ __name(async (projectPath) => {
516
691
  await run4(projectPath);
517
692
  }, "initAction");
693
+ var checkAction = /* @__PURE__ */ __name(async (options) => {
694
+ await run6(options);
695
+ }, "checkAction");
518
696
  function createProgram() {
519
697
  const program2 = new import_commander.Command("zenstack");
520
698
  program2.version(getVersion(), "-v --version", "display CLI version");
521
699
  const schemaExtensions = import_language2.ZModelLanguageMetaData.fileExtensions.join(", ");
522
- program2.description(`${import_colors5.default.bold.blue("\u03B6")} ZenStack is a Prisma power pack for building full-stack apps.
700
+ program2.description(`${import_colors6.default.bold.blue("\u03B6")} ZenStack is the data layer for modern TypeScript apps.
523
701
 
524
702
  Documentation: https://zenstack.dev.`).showHelpAfterError().showSuggestionAfterError();
525
- const schemaOption = new import_commander.Option("--schema <file>", `schema file (with extension ${schemaExtensions}). Defaults to "schema.zmodel" unless specified in package.json.`);
526
- program2.command("generate").description("Run code generation.").addOption(schemaOption).addOption(new import_commander.Option("-o, --output <path>", "default output directory for core plugins")).action(generateAction);
527
- const migrateCommand = program2.command("migrate").description("Update the database schema with migrations.");
528
- migrateCommand.command("dev").addOption(schemaOption).addOption(new import_commander.Option("-n, --name <name>", "migration name")).addOption(new import_commander.Option("--create-only", "only create migration, do not apply")).description("Create a migration from changes in schema and apply it to the database.").action((options) => migrateAction("dev", options));
529
- migrateCommand.command("reset").addOption(schemaOption).addOption(new import_commander.Option("--force", "skip the confirmation prompt")).description("Reset your database and apply all migrations, all data will be lost.").action((options) => migrateAction("reset", options));
530
- migrateCommand.command("deploy").addOption(schemaOption).description("Deploy your pending migrations to your production/staging database.").action((options) => migrateAction("deploy", options));
531
- migrateCommand.command("status").addOption(schemaOption).description("check the status of your database migrations.").action((options) => migrateAction("status", options));
703
+ const schemaOption = new import_commander.Option("--schema <file>", `schema file (with extension ${schemaExtensions}). Defaults to "zenstack/schema.zmodel" unless specified in package.json.`);
704
+ program2.command("generate").description("Run code generation plugins.").addOption(schemaOption).addOption(new import_commander.Option("-o, --output <path>", "default output directory for code generation")).action(generateAction);
705
+ const migrateCommand = program2.command("migrate").description("Run database schema migration related tasks.");
706
+ const migrationsOption = new import_commander.Option("--migrations <path>", 'path that contains the "migrations" directory');
707
+ migrateCommand.command("dev").addOption(schemaOption).addOption(new import_commander.Option("-n, --name <name>", "migration name")).addOption(new import_commander.Option("--create-only", "only create migration, do not apply")).addOption(migrationsOption).description("Create a migration from changes in schema and apply it to the database.").action((options) => migrateAction("dev", options));
708
+ migrateCommand.command("reset").addOption(schemaOption).addOption(new import_commander.Option("--force", "skip the confirmation prompt")).addOption(migrationsOption).description("Reset your database and apply all migrations, all data will be lost.").action((options) => migrateAction("reset", options));
709
+ migrateCommand.command("deploy").addOption(schemaOption).addOption(migrationsOption).description("Deploy your pending migrations to your production/staging database.").action((options) => migrateAction("deploy", options));
710
+ migrateCommand.command("status").addOption(schemaOption).addOption(migrationsOption).description("Check the status of your database migrations.").action((options) => migrateAction("status", options));
711
+ migrateCommand.command("resolve").addOption(schemaOption).addOption(migrationsOption).addOption(new import_commander.Option("--applied <migration>", "record a specific migration as applied")).addOption(new import_commander.Option("--rolled-back <migration>", "record a specific migration as rolled back")).description("Resolve issues with database migrations in deployment databases.").action((options) => migrateAction("resolve", options));
532
712
  const dbCommand = program2.command("db").description("Manage your database schema during development.");
533
- dbCommand.command("push").description("Push the state from your schema to your database").addOption(schemaOption).addOption(new import_commander.Option("--accept-data-loss", "ignore data loss warnings")).addOption(new import_commander.Option("--force-reset", "force a reset of the database before push")).action((options) => dbAction("push", options));
534
- program2.command("info").description("Get information of installed ZenStack and related packages.").argument("[path]", "project path", ".").action(infoAction);
713
+ dbCommand.command("push").description("Push the state from your schema to your database.").addOption(schemaOption).addOption(new import_commander.Option("--accept-data-loss", "ignore data loss warnings")).addOption(new import_commander.Option("--force-reset", "force a reset of the database before push")).action((options) => dbAction("push", options));
714
+ program2.command("info").description("Get information of installed ZenStack packages.").argument("[path]", "project path", ".").action(infoAction);
535
715
  program2.command("init").description("Initialize an existing project for ZenStack.").argument("[path]", "project path", ".").action(initAction);
716
+ program2.command("check").description("Check a ZModel schema for syntax or semantic errors.").addOption(schemaOption).action(checkAction);
536
717
  return program2;
537
718
  }
538
719
  __name(createProgram, "createProgram");
539
720
  var program = createProgram();
540
- program.parse(process.argv);
721
+ program.parseAsync().catch((err) => {
722
+ if (err instanceof CliError) {
723
+ console.error(import_colors6.default.red(err.message));
724
+ process.exit(1);
725
+ } else if (err instanceof import_commander.CommanderError) {
726
+ process.exit(err.exitCode);
727
+ } else {
728
+ console.error(import_colors6.default.red("An unexpected error occurred:"));
729
+ console.error(err);
730
+ process.exit(1);
731
+ }
732
+ });
541
733
  // Annotate the CommonJS export names for ESM import in node:
542
734
  0 && (module.exports = {
543
735
  createProgram