@zenstackhq/cli 3.0.0-alpha.2 → 3.0.0-alpha.20

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.js CHANGED
@@ -1,86 +1,13 @@
1
1
  var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
4
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
5
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
6
- }) : x)(function(x) {
7
- if (typeof require !== "undefined") return require.apply(this, arguments);
8
- throw Error('Dynamic require of "' + x + '" is not supported');
9
- });
10
- var __commonJS = (cb, mod) => function __require2() {
11
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
12
- };
13
-
14
- // package.json
15
- var require_package = __commonJS({
16
- "package.json"(exports, module) {
17
- module.exports = {
18
- name: "@zenstackhq/cli",
19
- publisher: "zenstack",
20
- displayName: "ZenStack CLI",
21
- description: "FullStack database toolkit with built-in access control and automatic API generation.",
22
- version: "3.0.0-alpha.2",
23
- type: "module",
24
- author: {
25
- name: "ZenStack Team"
26
- },
27
- homepage: "https://zenstack.dev",
28
- license: "MIT",
29
- keywords: [
30
- "orm",
31
- "fullstack",
32
- "react",
33
- "typescript",
34
- "data modeling"
35
- ],
36
- bin: {
37
- zenstack: "bin/cli"
38
- },
39
- scripts: {
40
- build: "tsup-node",
41
- watch: "tsup-node --watch",
42
- lint: "eslint src --ext ts",
43
- test: "vitest",
44
- pack: "pnpm pack"
45
- },
46
- dependencies: {
47
- "@types/node": "^20.0.0",
48
- "@zenstackhq/language": "workspace:*",
49
- "@zenstackhq/sdk": "workspace:*",
50
- "async-exit-hook": "^2.0.1",
51
- colors: "1.4.0",
52
- commander: "^8.3.0",
53
- langium: "~3.3.0",
54
- ora: "^5.4.1",
55
- "package-manager-detector": "^1.3.0",
56
- "tiny-invariant": "^1.3.3",
57
- "ts-pattern": "^4.3.0"
58
- },
59
- peerDependencies: {
60
- prisma: "^6.0.0",
61
- typescript: "^5.0.0"
62
- },
63
- devDependencies: {
64
- "@types/async-exit-hook": "^2.0.0",
65
- "@types/better-sqlite3": "^7.6.13",
66
- "@types/semver": "^7.3.13",
67
- "@types/tmp": "^0.2.6",
68
- "@zenstackhq/runtime": "workspace:*",
69
- "@zenstackhq/testtools": "workspace:*",
70
- "better-sqlite3": "^11.8.1",
71
- tmp: "^0.2.3"
72
- }
73
- };
74
- }
75
- });
76
3
 
77
4
  // src/index.ts
78
5
  import { ZModelLanguageMetaData } from "@zenstackhq/language";
79
- import colors5 from "colors";
80
- import { Command, Option } from "commander";
6
+ import colors6 from "colors";
7
+ import { Command, CommanderError, Option } from "commander";
81
8
 
82
9
  // src/actions/db.ts
83
- import path2 from "node:path";
10
+ import fs2 from "fs";
84
11
 
85
12
  // src/utils/exec-utils.ts
86
13
  import { execSync as _exec } from "child_process";
@@ -105,7 +32,12 @@ function execPackage(cmd, options) {
105
32
  __name(execPackage, "execPackage");
106
33
 
107
34
  // src/actions/action-utils.ts
108
- import fs from "node:fs";
35
+ import { loadDocument } from "@zenstackhq/language";
36
+ import { isDataSource } from "@zenstackhq/language/ast";
37
+ import { PrismaSchemaGenerator } from "@zenstackhq/sdk";
38
+ import colors from "colors";
39
+ import fs from "fs";
40
+ import path from "path";
109
41
 
110
42
  // src/cli-error.ts
111
43
  var CliError = class extends Error {
@@ -115,8 +47,6 @@ var CliError = class extends Error {
115
47
  };
116
48
 
117
49
  // src/actions/action-utils.ts
118
- import { loadDocument } from "@zenstackhq/language";
119
- import colors from "colors";
120
50
  function getSchemaFile(file) {
121
51
  if (file) {
122
52
  if (!fs.existsSync(file)) {
@@ -124,6 +54,13 @@ function getSchemaFile(file) {
124
54
  }
125
55
  return file;
126
56
  }
57
+ const pkgJsonConfig = getPkgJsonConfig(process.cwd());
58
+ if (pkgJsonConfig.schema) {
59
+ if (!fs.existsSync(pkgJsonConfig.schema)) {
60
+ throw new CliError(`Schema file not found: ${pkgJsonConfig.schema}`);
61
+ }
62
+ return pkgJsonConfig.schema;
63
+ }
127
64
  if (fs.existsSync("./zenstack/schema.zmodel")) {
128
65
  return "./zenstack/schema.zmodel";
129
66
  } else if (fs.existsSync("./schema.zmodel")) {
@@ -136,12 +73,14 @@ __name(getSchemaFile, "getSchemaFile");
136
73
  async function loadSchemaDocument(schemaFile) {
137
74
  const loadResult = await loadDocument(schemaFile);
138
75
  if (!loadResult.success) {
139
- console.error(colors.red("Error loading schema:"));
140
76
  loadResult.errors.forEach((err) => {
141
77
  console.error(colors.red(err));
142
78
  });
143
- throw new CliError("Failed to load schema");
79
+ throw new CliError("Schema contains errors. See above for details.");
144
80
  }
81
+ loadResult.warnings.forEach((warn) => {
82
+ console.warn(colors.yellow(warn));
83
+ });
145
84
  return loadResult.model;
146
85
  }
147
86
  __name(loadSchemaDocument, "loadSchemaDocument");
@@ -153,37 +92,149 @@ function handleSubProcessError(err) {
153
92
  }
154
93
  }
155
94
  __name(handleSubProcessError, "handleSubProcessError");
95
+ async function generateTempPrismaSchema(zmodelPath, folder) {
96
+ const model = await loadSchemaDocument(zmodelPath);
97
+ if (!model.declarations.some(isDataSource)) {
98
+ throw new CliError("Schema must define a datasource");
99
+ }
100
+ const prismaSchema = await new PrismaSchemaGenerator(model).generate();
101
+ if (!folder) {
102
+ folder = path.dirname(zmodelPath);
103
+ }
104
+ const prismaSchemaFile = path.resolve(folder, "~schema.prisma");
105
+ fs.writeFileSync(prismaSchemaFile, prismaSchema);
106
+ return prismaSchemaFile;
107
+ }
108
+ __name(generateTempPrismaSchema, "generateTempPrismaSchema");
109
+ function getPkgJsonConfig(startPath) {
110
+ const result = {
111
+ schema: void 0,
112
+ output: void 0
113
+ };
114
+ const pkgJsonFile = findUp([
115
+ "package.json"
116
+ ], startPath, false);
117
+ if (!pkgJsonFile) {
118
+ return result;
119
+ }
120
+ let pkgJson = void 0;
121
+ try {
122
+ pkgJson = JSON.parse(fs.readFileSync(pkgJsonFile, "utf8"));
123
+ } catch {
124
+ return result;
125
+ }
126
+ if (pkgJson.zenstack && typeof pkgJson.zenstack === "object") {
127
+ result.schema = pkgJson.zenstack.schema && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.schema);
128
+ result.output = pkgJson.zenstack.output && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.output);
129
+ }
130
+ return result;
131
+ }
132
+ __name(getPkgJsonConfig, "getPkgJsonConfig");
133
+ function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
134
+ if (!names.some((name) => !!name)) {
135
+ return void 0;
136
+ }
137
+ const target = names.find((name) => fs.existsSync(path.join(cwd, name)));
138
+ if (multiple === false && target) {
139
+ return path.join(cwd, target);
140
+ }
141
+ if (target) {
142
+ result.push(path.join(cwd, target));
143
+ }
144
+ const up = path.resolve(cwd, "..");
145
+ if (up === cwd) {
146
+ return multiple && result.length > 0 ? result : void 0;
147
+ }
148
+ return findUp(names, up, multiple, result);
149
+ }
150
+ __name(findUp, "findUp");
151
+
152
+ // src/actions/db.ts
153
+ async function run(command, options) {
154
+ switch (command) {
155
+ case "push":
156
+ await runPush(options);
157
+ break;
158
+ }
159
+ }
160
+ __name(run, "run");
161
+ async function runPush(options) {
162
+ const schemaFile = getSchemaFile(options.schema);
163
+ const prismaSchemaFile = await generateTempPrismaSchema(schemaFile);
164
+ try {
165
+ const cmd = [
166
+ "prisma db push",
167
+ ` --schema "${prismaSchemaFile}"`,
168
+ options.acceptDataLoss ? " --accept-data-loss" : "",
169
+ options.forceReset ? " --force-reset" : "",
170
+ " --skip-generate"
171
+ ].join("");
172
+ try {
173
+ await execPackage(cmd);
174
+ } catch (err) {
175
+ handleSubProcessError(err);
176
+ }
177
+ } finally {
178
+ if (fs2.existsSync(prismaSchemaFile)) {
179
+ fs2.unlinkSync(prismaSchemaFile);
180
+ }
181
+ }
182
+ }
183
+ __name(runPush, "runPush");
156
184
 
157
185
  // src/actions/generate.ts
186
+ import { invariant } from "@zenstackhq/common-helpers";
158
187
  import { isPlugin } from "@zenstackhq/language/ast";
159
- import { PrismaSchemaGenerator, TsSchemaGenerator } from "@zenstackhq/sdk";
188
+ import { PrismaSchemaGenerator as PrismaSchemaGenerator2, TsSchemaGenerator } from "@zenstackhq/sdk";
160
189
  import colors2 from "colors";
161
- import fs2 from "node:fs";
162
- import path from "node:path";
163
- import invariant from "tiny-invariant";
164
- async function run(options) {
190
+ import fs3 from "fs";
191
+ import path2 from "path";
192
+ async function run2(options) {
193
+ const start = Date.now();
165
194
  const schemaFile = getSchemaFile(options.schema);
166
195
  const model = await loadSchemaDocument(schemaFile);
167
- const outputPath = options.output ?? path.dirname(schemaFile);
168
- const tsSchemaFile = path.join(outputPath, "schema.ts");
169
- await new TsSchemaGenerator().generate(schemaFile, [], tsSchemaFile);
196
+ const outputPath = getOutputPath(options, schemaFile);
197
+ const tsSchemaFile = path2.join(outputPath, "schema.ts");
198
+ await new TsSchemaGenerator().generate(schemaFile, [], outputPath);
170
199
  await runPlugins(model, outputPath, tsSchemaFile);
171
- const prismaSchema = await new PrismaSchemaGenerator(model).generate();
172
- fs2.writeFileSync(path.join(outputPath, "schema.prisma"), prismaSchema);
200
+ if (options.savePrismaSchema) {
201
+ const prismaSchema = await new PrismaSchemaGenerator2(model).generate();
202
+ let prismaSchemaFile = path2.join(outputPath, "schema.prisma");
203
+ if (typeof options.savePrismaSchema === "string") {
204
+ prismaSchemaFile = path2.resolve(outputPath, options.savePrismaSchema);
205
+ fs3.mkdirSync(path2.dirname(prismaSchemaFile), {
206
+ recursive: true
207
+ });
208
+ }
209
+ fs3.writeFileSync(prismaSchemaFile, prismaSchema);
210
+ }
173
211
  if (!options.silent) {
174
- console.log(colors2.green("Generation completed successfully."));
212
+ console.log(colors2.green(`Generation completed successfully in ${Date.now() - start}ms.`));
175
213
  console.log(`You can now create a ZenStack client with it.
176
214
 
177
- \`\`\`
215
+ \`\`\`ts
178
216
  import { ZenStackClient } from '@zenstackhq/runtime';
179
217
  import { schema } from '${outputPath}/schema';
180
218
 
181
- const client = new ZenStackClient(schema);
182
- \`\`\`
183
- `);
219
+ const client = new ZenStackClient(schema, {
220
+ dialect: { ... }
221
+ });
222
+ \`\`\``);
184
223
  }
185
224
  }
186
- __name(run, "run");
225
+ __name(run2, "run");
226
+ function getOutputPath(options, schemaFile) {
227
+ if (options.output) {
228
+ return options.output;
229
+ }
230
+ const pkgJsonConfig = getPkgJsonConfig(process.cwd());
231
+ if (pkgJsonConfig.output) {
232
+ return pkgJsonConfig.output;
233
+ } else {
234
+ return path2.dirname(schemaFile);
235
+ }
236
+ }
237
+ __name(getOutputPath, "getOutputPath");
187
238
  async function runPlugins(model, outputPath, tsSchemaFile) {
188
239
  const plugins = model.declarations.filter(isPlugin);
189
240
  for (const plugin of plugins) {
@@ -205,36 +256,9 @@ async function runPlugins(model, outputPath, tsSchemaFile) {
205
256
  }
206
257
  __name(runPlugins, "runPlugins");
207
258
 
208
- // src/actions/db.ts
209
- async function run2(command, options) {
210
- const schemaFile = getSchemaFile(options.schema);
211
- await run({
212
- schema: schemaFile,
213
- silent: true
214
- });
215
- const prismaSchemaFile = path2.join(path2.dirname(schemaFile), "schema.prisma");
216
- switch (command) {
217
- case "push":
218
- await runPush(prismaSchemaFile, options);
219
- break;
220
- }
221
- }
222
- __name(run2, "run");
223
- async function runPush(prismaSchemaFile, options) {
224
- const cmd = `prisma db push --schema "${prismaSchemaFile}"${options.acceptDataLoss ? " --accept-data-loss" : ""}${options.forceReset ? " --force-reset" : ""} --skip-generate`;
225
- try {
226
- await execPackage(cmd, {
227
- stdio: "inherit"
228
- });
229
- } catch (err) {
230
- handleSubProcessError(err);
231
- }
232
- }
233
- __name(runPush, "runPush");
234
-
235
259
  // src/actions/info.ts
236
260
  import colors3 from "colors";
237
- import path3 from "node:path";
261
+ import path3 from "path";
238
262
  async function run3(projectPath) {
239
263
  const packages = await getZenStackPackages(projectPath);
240
264
  if (!packages) {
@@ -263,7 +287,7 @@ async function getZenStackPackages(projectPath) {
263
287
  type: "json"
264
288
  }
265
289
  })).default;
266
- } catch (err) {
290
+ } catch {
267
291
  return [];
268
292
  }
269
293
  const packages = Array.from(new Set([
@@ -294,8 +318,8 @@ __name(getZenStackPackages, "getZenStackPackages");
294
318
 
295
319
  // src/actions/init.ts
296
320
  import colors4 from "colors";
297
- import fs3 from "node:fs";
298
- import path4 from "node:path";
321
+ import fs4 from "fs";
322
+ import path4 from "path";
299
323
  import ora from "ora";
300
324
  import { detect, resolveCommand } from "package-manager-detector";
301
325
 
@@ -370,11 +394,11 @@ async function run4(projectPath) {
370
394
  }
371
395
  }
372
396
  const generationFolder = "zenstack";
373
- if (!fs3.existsSync(path4.join(projectPath, generationFolder))) {
374
- fs3.mkdirSync(path4.join(projectPath, generationFolder));
397
+ if (!fs4.existsSync(path4.join(projectPath, generationFolder))) {
398
+ fs4.mkdirSync(path4.join(projectPath, generationFolder));
375
399
  }
376
- if (!fs3.existsSync(path4.join(projectPath, generationFolder, "schema.zmodel"))) {
377
- fs3.writeFileSync(path4.join(projectPath, generationFolder, "schema.zmodel"), STARTER_ZMODEL);
400
+ if (!fs4.existsSync(path4.join(projectPath, generationFolder, "schema.zmodel"))) {
401
+ fs4.writeFileSync(path4.join(projectPath, generationFolder, "schema.zmodel"), STARTER_ZMODEL);
378
402
  } else {
379
403
  console.log(colors4.yellow("Schema file already exists. Skipping generation of sample."));
380
404
  }
@@ -385,35 +409,44 @@ async function run4(projectPath) {
385
409
  __name(run4, "run");
386
410
 
387
411
  // src/actions/migrate.ts
388
- import path5 from "node:path";
412
+ import fs5 from "fs";
413
+ import path5 from "path";
389
414
  async function run5(command, options) {
390
415
  const schemaFile = getSchemaFile(options.schema);
391
- await run({
392
- schema: schemaFile,
393
- silent: true
394
- });
395
- const prismaSchemaFile = path5.join(path5.dirname(schemaFile), "schema.prisma");
396
- switch (command) {
397
- case "dev":
398
- await runDev(prismaSchemaFile, options);
399
- break;
400
- case "reset":
401
- await runReset(prismaSchemaFile, options);
402
- break;
403
- case "deploy":
404
- await runDeploy(prismaSchemaFile, options);
405
- break;
406
- case "status":
407
- await runStatus(prismaSchemaFile, options);
408
- break;
416
+ const prismaSchemaDir = options.migrations ? path5.dirname(options.migrations) : void 0;
417
+ const prismaSchemaFile = await generateTempPrismaSchema(schemaFile, prismaSchemaDir);
418
+ try {
419
+ switch (command) {
420
+ case "dev":
421
+ await runDev(prismaSchemaFile, options);
422
+ break;
423
+ case "reset":
424
+ await runReset(prismaSchemaFile, options);
425
+ break;
426
+ case "deploy":
427
+ await runDeploy(prismaSchemaFile, options);
428
+ break;
429
+ case "status":
430
+ await runStatus(prismaSchemaFile, options);
431
+ break;
432
+ }
433
+ } finally {
434
+ if (fs5.existsSync(prismaSchemaFile)) {
435
+ fs5.unlinkSync(prismaSchemaFile);
436
+ }
409
437
  }
410
438
  }
411
439
  __name(run5, "run");
412
- async function runDev(prismaSchemaFile, _options) {
440
+ async function runDev(prismaSchemaFile, options) {
413
441
  try {
414
- await execPackage(`prisma migrate dev --schema "${prismaSchemaFile}" --skip-generate`, {
415
- stdio: "inherit"
416
- });
442
+ const cmd = [
443
+ "prisma migrate dev",
444
+ ` --schema "${prismaSchemaFile}"`,
445
+ " --skip-generate",
446
+ options.name ? ` --name ${options.name}` : "",
447
+ options.createOnly ? " --create-only" : ""
448
+ ].join("");
449
+ await execPackage(cmd);
417
450
  } catch (err) {
418
451
  handleSubProcessError2(err);
419
452
  }
@@ -421,9 +454,12 @@ async function runDev(prismaSchemaFile, _options) {
421
454
  __name(runDev, "runDev");
422
455
  async function runReset(prismaSchemaFile, options) {
423
456
  try {
424
- await execPackage(`prisma migrate reset --schema "${prismaSchemaFile}"${options.force ? " --force" : ""}`, {
425
- stdio: "inherit"
426
- });
457
+ const cmd = [
458
+ "prisma migrate reset",
459
+ ` --schema "${prismaSchemaFile}"`,
460
+ options.force ? " --force" : ""
461
+ ].join("");
462
+ await execPackage(cmd);
427
463
  } catch (err) {
428
464
  handleSubProcessError2(err);
429
465
  }
@@ -431,9 +467,11 @@ async function runReset(prismaSchemaFile, options) {
431
467
  __name(runReset, "runReset");
432
468
  async function runDeploy(prismaSchemaFile, _options) {
433
469
  try {
434
- await execPackage(`prisma migrate deploy --schema "${prismaSchemaFile}"`, {
435
- stdio: "inherit"
436
- });
470
+ const cmd = [
471
+ "prisma migrate deploy",
472
+ ` --schema "${prismaSchemaFile}"`
473
+ ].join("");
474
+ await execPackage(cmd);
437
475
  } catch (err) {
438
476
  handleSubProcessError2(err);
439
477
  }
@@ -441,9 +479,7 @@ async function runDeploy(prismaSchemaFile, _options) {
441
479
  __name(runDeploy, "runDeploy");
442
480
  async function runStatus(prismaSchemaFile, _options) {
443
481
  try {
444
- await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`, {
445
- stdio: "inherit"
446
- });
482
+ await execPackage(`prisma migrate status --schema "${prismaSchemaFile}"`);
447
483
  } catch (err) {
448
484
  handleSubProcessError2(err);
449
485
  }
@@ -458,29 +494,43 @@ function handleSubProcessError2(err) {
458
494
  }
459
495
  __name(handleSubProcessError2, "handleSubProcessError");
460
496
 
497
+ // src/actions/validate.ts
498
+ import colors5 from "colors";
499
+ async function run6(options) {
500
+ const schemaFile = getSchemaFile(options.schema);
501
+ try {
502
+ await loadSchemaDocument(schemaFile);
503
+ console.log(colors5.green("\u2713 Schema validation completed successfully."));
504
+ } catch (error) {
505
+ console.error(colors5.red("\u2717 Schema validation failed."));
506
+ throw error;
507
+ }
508
+ }
509
+ __name(run6, "run");
510
+
461
511
  // src/utils/version-utils.ts
512
+ import fs6 from "fs";
513
+ import path6 from "path";
514
+ import { fileURLToPath } from "url";
462
515
  function getVersion() {
463
516
  try {
464
- return __require("../package.json").version;
517
+ const _dirname = typeof __dirname !== "undefined" ? __dirname : path6.dirname(fileURLToPath(import.meta.url));
518
+ return JSON.parse(fs6.readFileSync(path6.join(_dirname, "../package.json"), "utf8")).version;
465
519
  } catch {
466
- try {
467
- return require_package().version;
468
- } catch {
469
- return void 0;
470
- }
520
+ return void 0;
471
521
  }
472
522
  }
473
523
  __name(getVersion, "getVersion");
474
524
 
475
525
  // src/index.ts
476
526
  var generateAction = /* @__PURE__ */ __name(async (options) => {
477
- await run(options);
527
+ await run2(options);
478
528
  }, "generateAction");
479
529
  var migrateAction = /* @__PURE__ */ __name(async (command, options) => {
480
530
  await run5(command, options);
481
531
  }, "migrateAction");
482
532
  var dbAction = /* @__PURE__ */ __name(async (command, options) => {
483
- await run2(command, options);
533
+ await run(command, options);
484
534
  }, "dbAction");
485
535
  var infoAction = /* @__PURE__ */ __name(async (projectPath) => {
486
536
  await run3(projectPath);
@@ -488,29 +538,45 @@ var infoAction = /* @__PURE__ */ __name(async (projectPath) => {
488
538
  var initAction = /* @__PURE__ */ __name(async (projectPath) => {
489
539
  await run4(projectPath);
490
540
  }, "initAction");
541
+ var validateAction = /* @__PURE__ */ __name(async (options) => {
542
+ await run6(options);
543
+ }, "validateAction");
491
544
  function createProgram() {
492
545
  const program2 = new Command("zenstack");
493
546
  program2.version(getVersion(), "-v --version", "display CLI version");
494
547
  const schemaExtensions = ZModelLanguageMetaData.fileExtensions.join(", ");
495
- program2.description(`${colors5.bold.blue("\u03B6")} ZenStack is a Prisma power pack for building full-stack apps.
548
+ program2.description(`${colors6.bold.blue("\u03B6")} ZenStack is a database access toolkit for TypeScript apps.
496
549
 
497
550
  Documentation: https://zenstack.dev.`).showHelpAfterError().showSuggestionAfterError();
498
551
  const schemaOption = new Option("--schema <file>", `schema file (with extension ${schemaExtensions}). Defaults to "schema.zmodel" unless specified in package.json.`);
499
- program2.command("generate").description("Run code generation.").addOption(schemaOption).addOption(new Option("-o, --output <path>", "default output directory for core plugins")).action(generateAction);
552
+ program2.command("generate").description("Run code generation.").addOption(schemaOption).addOption(new Option("--silent", "do not print any output")).addOption(new Option("--save-prisma-schema [path]", "save a Prisma schema file, by default into the output directory")).addOption(new Option("-o, --output <path>", "default output directory for core plugins")).action(generateAction);
500
553
  const migrateCommand = program2.command("migrate").description("Update the database schema with migrations.");
501
- migrateCommand.command("dev").addOption(schemaOption).addOption(new Option("-n, --name <name>", "migration name")).addOption(new 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));
502
- migrateCommand.command("reset").addOption(schemaOption).addOption(new Option("--force", "skip the confirmation prompt")).description("Reset your database and apply all migrations, all data will be lost.").action((options) => migrateAction("reset", options));
503
- migrateCommand.command("deploy").addOption(schemaOption).description("Deploy your pending migrations to your production/staging database.").action((options) => migrateAction("deploy", options));
504
- migrateCommand.command("status").addOption(schemaOption).description("check the status of your database migrations.").action((options) => migrateAction("status", options));
554
+ const migrationsOption = new Option("--migrations <path>", "path for migrations");
555
+ migrateCommand.command("dev").addOption(schemaOption).addOption(new Option("-n, --name <name>", "migration name")).addOption(new 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));
556
+ migrateCommand.command("reset").addOption(schemaOption).addOption(new 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));
557
+ migrateCommand.command("deploy").addOption(schemaOption).addOption(migrationsOption).description("Deploy your pending migrations to your production/staging database.").action((options) => migrateAction("deploy", options));
558
+ migrateCommand.command("status").addOption(schemaOption).addOption(migrationsOption).description("check the status of your database migrations.").action((options) => migrateAction("status", options));
505
559
  const dbCommand = program2.command("db").description("Manage your database schema during development.");
506
560
  dbCommand.command("push").description("Push the state from your schema to your database").addOption(schemaOption).addOption(new Option("--accept-data-loss", "ignore data loss warnings")).addOption(new Option("--force-reset", "force a reset of the database before push")).action((options) => dbAction("push", options));
507
561
  program2.command("info").description("Get information of installed ZenStack and related packages.").argument("[path]", "project path", ".").action(infoAction);
508
562
  program2.command("init").description("Initialize an existing project for ZenStack.").argument("[path]", "project path", ".").action(initAction);
563
+ program2.command("validate").description("Validate a ZModel schema.").addOption(schemaOption).action(validateAction);
509
564
  return program2;
510
565
  }
511
566
  __name(createProgram, "createProgram");
512
567
  var program = createProgram();
513
- program.parse(process.argv);
568
+ program.parseAsync().catch((err) => {
569
+ if (err instanceof CliError) {
570
+ console.error(colors6.red(err.message));
571
+ process.exit(1);
572
+ } else if (err instanceof CommanderError) {
573
+ process.exit(err.exitCode);
574
+ } else {
575
+ console.error(colors6.red("An unexpected error occurred:"));
576
+ console.error(err);
577
+ process.exit(1);
578
+ }
579
+ });
514
580
  export {
515
581
  createProgram
516
582
  };