@zenstackhq/cli 3.0.0-beta.24 → 3.0.0-beta.26

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
@@ -13,7 +13,7 @@ var __export = (target, all) => {
13
13
 
14
14
  // src/index.ts
15
15
  import { ZModelLanguageMetaData } from "@zenstackhq/language";
16
- import colors8 from "colors";
16
+ import colors9 from "colors";
17
17
  import { Command, CommanderError, Option } from "commander";
18
18
 
19
19
  // src/actions/check.ts
@@ -105,7 +105,8 @@ __name(generateTempPrismaSchema, "generateTempPrismaSchema");
105
105
  function getPkgJsonConfig(startPath) {
106
106
  const result = {
107
107
  schema: void 0,
108
- output: void 0
108
+ output: void 0,
109
+ seed: void 0
109
110
  };
110
111
  const pkgJsonFile = findUp([
111
112
  "package.json"
@@ -120,8 +121,9 @@ function getPkgJsonConfig(startPath) {
120
121
  return result;
121
122
  }
122
123
  if (pkgJson.zenstack && typeof pkgJson.zenstack === "object") {
123
- result.schema = pkgJson.zenstack.schema && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.schema);
124
- result.output = pkgJson.zenstack.output && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.output);
124
+ result.schema = pkgJson.zenstack.schema && typeof pkgJson.zenstack.schema === "string" ? path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.schema) : void 0;
125
+ result.output = pkgJson.zenstack.output && typeof pkgJson.zenstack.output === "string" ? path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.output) : void 0;
126
+ result.seed = typeof pkgJson.zenstack.seed === "string" && pkgJson.zenstack.seed ? pkgJson.zenstack.seed : void 0;
125
127
  }
126
128
  return result;
127
129
  }
@@ -144,6 +146,14 @@ function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
144
146
  return findUp(names, up, multiple, result);
145
147
  }
146
148
  __name(findUp, "findUp");
149
+ async function requireDataSourceUrl(schemaFile) {
150
+ const zmodel = await loadSchemaDocument(schemaFile);
151
+ const dataSource = zmodel.declarations.find(isDataSource);
152
+ if (!dataSource?.fields.some((f) => f.name === "url")) {
153
+ throw new CliError(`The schema's "datasource" must have a "url" field to use this command.`);
154
+ }
155
+ }
156
+ __name(requireDataSourceUrl, "requireDataSourceUrl");
147
157
 
148
158
  // src/actions/check.ts
149
159
  async function run(options) {
@@ -212,6 +222,7 @@ async function run2(command, options) {
212
222
  __name(run2, "run");
213
223
  async function runPush(options) {
214
224
  const schemaFile = getSchemaFile(options.schema);
225
+ await requireDataSourceUrl(schemaFile);
215
226
  const prismaSchemaFile = await generateTempPrismaSchema(schemaFile);
216
227
  try {
217
228
  const cmd = [
@@ -617,8 +628,38 @@ __name(run6, "run");
617
628
  // src/actions/migrate.ts
618
629
  import fs7 from "fs";
619
630
  import path7 from "path";
620
- async function run7(command, options) {
631
+
632
+ // src/actions/seed.ts
633
+ import colors7 from "colors";
634
+ import { execaCommand } from "execa";
635
+ async function run7(options, args) {
636
+ const pkgJsonConfig = getPkgJsonConfig(process.cwd());
637
+ if (!pkgJsonConfig.seed) {
638
+ if (!options.noWarnings) {
639
+ console.warn(colors7.yellow("No seed script defined in package.json. Skipping seeding."));
640
+ }
641
+ return;
642
+ }
643
+ const command = `${pkgJsonConfig.seed}${args.length > 0 ? " " + args.join(" ") : ""}`;
644
+ if (options.printStatus) {
645
+ console.log(colors7.gray(`Running seed script "${command}"...`));
646
+ }
647
+ try {
648
+ await execaCommand(command, {
649
+ stdout: "inherit",
650
+ stderr: "inherit"
651
+ });
652
+ } catch (err) {
653
+ console.error(colors7.red(err instanceof Error ? err.message : String(err)));
654
+ throw new CliError("Failed to seed the database. Please check the error message above for details.");
655
+ }
656
+ }
657
+ __name(run7, "run");
658
+
659
+ // src/actions/migrate.ts
660
+ async function run8(command, options) {
621
661
  const schemaFile = getSchemaFile(options.schema);
662
+ await requireDataSourceUrl(schemaFile);
622
663
  const prismaSchemaDir = options.migrations ? path7.dirname(options.migrations) : void 0;
623
664
  const prismaSchemaFile = await generateTempPrismaSchema(schemaFile, prismaSchemaDir);
624
665
  try {
@@ -645,13 +686,14 @@ async function run7(command, options) {
645
686
  }
646
687
  }
647
688
  }
648
- __name(run7, "run");
689
+ __name(run8, "run");
649
690
  function runDev(prismaSchemaFile, options) {
650
691
  try {
651
692
  const cmd = [
652
693
  "migrate dev",
653
694
  ` --schema "${prismaSchemaFile}"`,
654
695
  " --skip-generate",
696
+ " --skip-seed",
655
697
  options.name ? ` --name "${options.name}"` : "",
656
698
  options.createOnly ? " --create-only" : ""
657
699
  ].join("");
@@ -661,18 +703,25 @@ function runDev(prismaSchemaFile, options) {
661
703
  }
662
704
  }
663
705
  __name(runDev, "runDev");
664
- function runReset(prismaSchemaFile, options) {
706
+ async function runReset(prismaSchemaFile, options) {
665
707
  try {
666
708
  const cmd = [
667
709
  "migrate reset",
668
710
  ` --schema "${prismaSchemaFile}"`,
669
711
  " --skip-generate",
712
+ " --skip-seed",
670
713
  options.force ? " --force" : ""
671
714
  ].join("");
672
715
  execPrisma(cmd);
673
716
  } catch (err) {
674
717
  handleSubProcessError2(err);
675
718
  }
719
+ if (!options.skipSeed) {
720
+ await run7({
721
+ noWarnings: true,
722
+ printStatus: true
723
+ }, []);
724
+ }
676
725
  }
677
726
  __name(runReset, "runReset");
678
727
  function runDeploy(prismaSchemaFile, _options) {
@@ -859,7 +908,7 @@ function getMachineId() {
859
908
  __name(getMachineId, "getMachineId");
860
909
 
861
910
  // src/utils/version-utils.ts
862
- import colors7 from "colors";
911
+ import colors8 from "colors";
863
912
  import fs11 from "fs";
864
913
  import path8 from "path";
865
914
  import { fileURLToPath as fileURLToPath2 } from "url";
@@ -884,7 +933,7 @@ async function checkNewVersion() {
884
933
  return;
885
934
  }
886
935
  if (latestVersion && currVersion && semver.gt(latestVersion, currVersion)) {
887
- console.log(`A newer version ${colors7.cyan(latestVersion)} is available.`);
936
+ console.log(`A newer version ${colors8.cyan(latestVersion)} is available.`);
888
937
  }
889
938
  }
890
939
  __name(checkNewVersion, "checkNewVersion");
@@ -1013,7 +1062,7 @@ var generateAction = /* @__PURE__ */ __name(async (options) => {
1013
1062
  await telemetry.trackCommand("generate", () => run4(options));
1014
1063
  }, "generateAction");
1015
1064
  var migrateAction = /* @__PURE__ */ __name(async (subCommand, options) => {
1016
- await telemetry.trackCommand(`migrate ${subCommand}`, () => run7(subCommand, options));
1065
+ await telemetry.trackCommand(`migrate ${subCommand}`, () => run8(subCommand, options));
1017
1066
  }, "migrateAction");
1018
1067
  var dbAction = /* @__PURE__ */ __name(async (subCommand, options) => {
1019
1068
  await telemetry.trackCommand(`db ${subCommand}`, () => run2(subCommand, options));
@@ -1030,10 +1079,13 @@ var checkAction = /* @__PURE__ */ __name(async (options) => {
1030
1079
  var formatAction = /* @__PURE__ */ __name(async (options) => {
1031
1080
  await telemetry.trackCommand("format", () => run3(options));
1032
1081
  }, "formatAction");
1082
+ var seedAction = /* @__PURE__ */ __name(async (options, args) => {
1083
+ await telemetry.trackCommand("db seed", () => run7(options, args));
1084
+ }, "seedAction");
1033
1085
  function createProgram() {
1034
1086
  const program = new Command("zen").alias("zenstack").helpOption("-h, --help", "Show this help message").version(getVersion(), "-v --version", "Show CLI version");
1035
1087
  const schemaExtensions = ZModelLanguageMetaData.fileExtensions.join(", ");
1036
- program.description(`${colors8.bold.blue("\u03B6")} ZenStack is the data layer for modern TypeScript apps.
1088
+ program.description(`${colors9.bold.blue("\u03B6")} ZenStack is the data layer for modern TypeScript apps.
1037
1089
 
1038
1090
  Documentation: https://zenstack.dev/docs/3.x`).showHelpAfterError().showSuggestionAfterError();
1039
1091
  const schemaOption = new Option("--schema <file>", `schema file (with extension ${schemaExtensions}). Defaults to "zenstack/schema.zmodel" unless specified in package.json.`);
@@ -1042,12 +1094,22 @@ Documentation: https://zenstack.dev/docs/3.x`).showHelpAfterError().showSuggesti
1042
1094
  const migrateCommand = program.command("migrate").description("Run database schema migration related tasks.");
1043
1095
  const migrationsOption = new Option("--migrations <path>", 'path that contains the "migrations" directory');
1044
1096
  migrateCommand.command("dev").addOption(schemaOption).addOption(noVersionCheckOption).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));
1045
- migrateCommand.command("reset").addOption(schemaOption).addOption(new Option("--force", "skip the confirmation prompt")).addOption(migrationsOption).addOption(noVersionCheckOption).description("Reset your database and apply all migrations, all data will be lost").action((options) => migrateAction("reset", options));
1097
+ migrateCommand.command("reset").addOption(schemaOption).addOption(new Option("--force", "skip the confirmation prompt")).addOption(migrationsOption).addOption(new Option("--skip-seed", "skip seeding the database after reset")).addOption(noVersionCheckOption).description("Reset your database and apply all migrations, all data will be lost").addHelpText("after", "\nIf there is a seed script defined in package.json, it will be run after the reset. Use --skip-seed to skip it.").action((options) => migrateAction("reset", options));
1046
1098
  migrateCommand.command("deploy").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).description("Deploy your pending migrations to your production/staging database").action((options) => migrateAction("deploy", options));
1047
1099
  migrateCommand.command("status").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).description("Check the status of your database migrations").action((options) => migrateAction("status", options));
1048
1100
  migrateCommand.command("resolve").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).addOption(new Option("--applied <migration>", "record a specific migration as applied")).addOption(new 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));
1049
1101
  const dbCommand = program.command("db").description("Manage your database schema during development");
1050
1102
  dbCommand.command("push").description("Push the state from your schema to your database").addOption(schemaOption).addOption(noVersionCheckOption).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));
1103
+ dbCommand.command("seed").description("Seed the database").allowExcessArguments(true).addHelpText("after", `
1104
+ Seed script is configured under the "zenstack.seed" field in package.json.
1105
+ E.g.:
1106
+ {
1107
+ "zenstack": {
1108
+ "seed": "ts-node ./zenstack/seed.ts"
1109
+ }
1110
+ }
1111
+
1112
+ Arguments following -- are passed to the seed script. E.g.: "zen db seed -- --users 10"`).addOption(noVersionCheckOption).action((options, command) => seedAction(options, command.args));
1051
1113
  program.command("info").description("Get information of installed ZenStack packages").argument("[path]", "project path", ".").addOption(noVersionCheckOption).action(infoAction);
1052
1114
  program.command("init").description("Initialize an existing project for ZenStack").argument("[path]", "project path", ".").addOption(noVersionCheckOption).action(initAction);
1053
1115
  program.command("check").description("Check a ZModel schema for syntax or semantic errors").addOption(schemaOption).addOption(noVersionCheckOption).action(checkAction);
@@ -1073,10 +1135,10 @@ async function main() {
1073
1135
  if (e instanceof CommanderError) {
1074
1136
  exitCode = e.exitCode;
1075
1137
  } else if (e instanceof CliError) {
1076
- console.error(colors8.red(e.message));
1138
+ console.error(colors9.red(e.message));
1077
1139
  exitCode = 1;
1078
1140
  } else {
1079
- console.error(colors8.red(`Unhandled error: ${e}`));
1141
+ console.error(colors9.red(`Unhandled error: ${e}`));
1080
1142
  exitCode = 1;
1081
1143
  }
1082
1144
  }