@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/.turbo/turbo-build.log +8 -8
- package/dist/index.cjs +76 -14
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +76 -14
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
- package/src/actions/action-utils.ts +23 -3
- package/src/actions/db.ts +6 -2
- package/src/actions/index.ts +2 -1
- package/src/actions/migrate.ts +14 -2
- package/src/actions/seed.ts +38 -0
- package/src/index.ts +29 -0
- package/test/db.test.ts +43 -0
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @zenstackhq/cli@3.0.0-beta.
|
|
2
|
+
> @zenstackhq/cli@3.0.0-beta.26 build /home/runner/work/zenstack-v3/zenstack-v3/packages/cli
|
|
3
3
|
> tsc --noEmit && tsup-node
|
|
4
4
|
|
|
5
5
|
[34mCLI[39m Building entry: {"index":"src/index.ts"}
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
[34mCLI[39m Cleaning output folder
|
|
11
11
|
[34mESM[39m Build start
|
|
12
12
|
[34mCJS[39m Build start
|
|
13
|
-
[
|
|
14
|
-
[
|
|
15
|
-
[
|
|
16
|
-
[
|
|
17
|
-
[
|
|
18
|
-
[
|
|
13
|
+
[32mCJS[39m [1mdist/index.cjs [22m[32m41.99 KB[39m
|
|
14
|
+
[32mCJS[39m [1mdist/index.cjs.map [22m[32m80.26 KB[39m
|
|
15
|
+
[32mCJS[39m ⚡️ Build success in 130ms
|
|
16
|
+
[32mESM[39m [1mdist/index.js [22m[32m37.94 KB[39m
|
|
17
|
+
[32mESM[39m [1mdist/index.js.map [22m[32m79.68 KB[39m
|
|
18
|
+
[32mESM[39m ⚡️ Build success in 132ms
|
|
19
19
|
[34mDTS[39m Build start
|
|
20
|
-
[32mDTS[39m ⚡️ Build success in
|
|
20
|
+
[32mDTS[39m ⚡️ Build success in 2493ms
|
|
21
21
|
[32mDTS[39m [1mdist/index.d.ts [22m[32m13.00 B[39m
|
|
22
22
|
[32mDTS[39m [1mdist/index.d.cts [22m[32m13.00 B[39m
|
package/dist/index.cjs
CHANGED
|
@@ -29,7 +29,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
29
29
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var import_language3 = require("@zenstackhq/language");
|
|
32
|
-
var
|
|
32
|
+
var import_colors9 = __toESM(require("colors"), 1);
|
|
33
33
|
var import_commander = require("commander");
|
|
34
34
|
|
|
35
35
|
// src/actions/check.ts
|
|
@@ -121,7 +121,8 @@ __name(generateTempPrismaSchema, "generateTempPrismaSchema");
|
|
|
121
121
|
function getPkgJsonConfig(startPath) {
|
|
122
122
|
const result = {
|
|
123
123
|
schema: void 0,
|
|
124
|
-
output: void 0
|
|
124
|
+
output: void 0,
|
|
125
|
+
seed: void 0
|
|
125
126
|
};
|
|
126
127
|
const pkgJsonFile = findUp([
|
|
127
128
|
"package.json"
|
|
@@ -136,8 +137,9 @@ function getPkgJsonConfig(startPath) {
|
|
|
136
137
|
return result;
|
|
137
138
|
}
|
|
138
139
|
if (pkgJson.zenstack && typeof pkgJson.zenstack === "object") {
|
|
139
|
-
result.schema = pkgJson.zenstack.schema && import_node_path.default.resolve(import_node_path.default.dirname(pkgJsonFile), pkgJson.zenstack.schema);
|
|
140
|
-
result.output = pkgJson.zenstack.output && import_node_path.default.resolve(import_node_path.default.dirname(pkgJsonFile), pkgJson.zenstack.output);
|
|
140
|
+
result.schema = pkgJson.zenstack.schema && typeof pkgJson.zenstack.schema === "string" ? import_node_path.default.resolve(import_node_path.default.dirname(pkgJsonFile), pkgJson.zenstack.schema) : void 0;
|
|
141
|
+
result.output = pkgJson.zenstack.output && typeof pkgJson.zenstack.output === "string" ? import_node_path.default.resolve(import_node_path.default.dirname(pkgJsonFile), pkgJson.zenstack.output) : void 0;
|
|
142
|
+
result.seed = typeof pkgJson.zenstack.seed === "string" && pkgJson.zenstack.seed ? pkgJson.zenstack.seed : void 0;
|
|
141
143
|
}
|
|
142
144
|
return result;
|
|
143
145
|
}
|
|
@@ -160,6 +162,14 @@ function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
|
|
|
160
162
|
return findUp(names, up, multiple, result);
|
|
161
163
|
}
|
|
162
164
|
__name(findUp, "findUp");
|
|
165
|
+
async function requireDataSourceUrl(schemaFile) {
|
|
166
|
+
const zmodel = await loadSchemaDocument(schemaFile);
|
|
167
|
+
const dataSource = zmodel.declarations.find(import_ast.isDataSource);
|
|
168
|
+
if (!dataSource?.fields.some((f) => f.name === "url")) {
|
|
169
|
+
throw new CliError(`The schema's "datasource" must have a "url" field to use this command.`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
__name(requireDataSourceUrl, "requireDataSourceUrl");
|
|
163
173
|
|
|
164
174
|
// src/actions/check.ts
|
|
165
175
|
async function run(options) {
|
|
@@ -229,6 +239,7 @@ async function run2(command, options) {
|
|
|
229
239
|
__name(run2, "run");
|
|
230
240
|
async function runPush(options) {
|
|
231
241
|
const schemaFile = getSchemaFile(options.schema);
|
|
242
|
+
await requireDataSourceUrl(schemaFile);
|
|
232
243
|
const prismaSchemaFile = await generateTempPrismaSchema(schemaFile);
|
|
233
244
|
try {
|
|
234
245
|
const cmd = [
|
|
@@ -634,8 +645,38 @@ __name(run6, "run");
|
|
|
634
645
|
// src/actions/migrate.ts
|
|
635
646
|
var import_node_fs7 = __toESM(require("fs"), 1);
|
|
636
647
|
var import_node_path7 = __toESM(require("path"), 1);
|
|
637
|
-
|
|
648
|
+
|
|
649
|
+
// src/actions/seed.ts
|
|
650
|
+
var import_colors7 = __toESM(require("colors"), 1);
|
|
651
|
+
var import_execa = require("execa");
|
|
652
|
+
async function run7(options, args) {
|
|
653
|
+
const pkgJsonConfig = getPkgJsonConfig(process.cwd());
|
|
654
|
+
if (!pkgJsonConfig.seed) {
|
|
655
|
+
if (!options.noWarnings) {
|
|
656
|
+
console.warn(import_colors7.default.yellow("No seed script defined in package.json. Skipping seeding."));
|
|
657
|
+
}
|
|
658
|
+
return;
|
|
659
|
+
}
|
|
660
|
+
const command = `${pkgJsonConfig.seed}${args.length > 0 ? " " + args.join(" ") : ""}`;
|
|
661
|
+
if (options.printStatus) {
|
|
662
|
+
console.log(import_colors7.default.gray(`Running seed script "${command}"...`));
|
|
663
|
+
}
|
|
664
|
+
try {
|
|
665
|
+
await (0, import_execa.execaCommand)(command, {
|
|
666
|
+
stdout: "inherit",
|
|
667
|
+
stderr: "inherit"
|
|
668
|
+
});
|
|
669
|
+
} catch (err) {
|
|
670
|
+
console.error(import_colors7.default.red(err instanceof Error ? err.message : String(err)));
|
|
671
|
+
throw new CliError("Failed to seed the database. Please check the error message above for details.");
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
__name(run7, "run");
|
|
675
|
+
|
|
676
|
+
// src/actions/migrate.ts
|
|
677
|
+
async function run8(command, options) {
|
|
638
678
|
const schemaFile = getSchemaFile(options.schema);
|
|
679
|
+
await requireDataSourceUrl(schemaFile);
|
|
639
680
|
const prismaSchemaDir = options.migrations ? import_node_path7.default.dirname(options.migrations) : void 0;
|
|
640
681
|
const prismaSchemaFile = await generateTempPrismaSchema(schemaFile, prismaSchemaDir);
|
|
641
682
|
try {
|
|
@@ -662,13 +703,14 @@ async function run7(command, options) {
|
|
|
662
703
|
}
|
|
663
704
|
}
|
|
664
705
|
}
|
|
665
|
-
__name(
|
|
706
|
+
__name(run8, "run");
|
|
666
707
|
function runDev(prismaSchemaFile, options) {
|
|
667
708
|
try {
|
|
668
709
|
const cmd = [
|
|
669
710
|
"migrate dev",
|
|
670
711
|
` --schema "${prismaSchemaFile}"`,
|
|
671
712
|
" --skip-generate",
|
|
713
|
+
" --skip-seed",
|
|
672
714
|
options.name ? ` --name "${options.name}"` : "",
|
|
673
715
|
options.createOnly ? " --create-only" : ""
|
|
674
716
|
].join("");
|
|
@@ -678,18 +720,25 @@ function runDev(prismaSchemaFile, options) {
|
|
|
678
720
|
}
|
|
679
721
|
}
|
|
680
722
|
__name(runDev, "runDev");
|
|
681
|
-
function runReset(prismaSchemaFile, options) {
|
|
723
|
+
async function runReset(prismaSchemaFile, options) {
|
|
682
724
|
try {
|
|
683
725
|
const cmd = [
|
|
684
726
|
"migrate reset",
|
|
685
727
|
` --schema "${prismaSchemaFile}"`,
|
|
686
728
|
" --skip-generate",
|
|
729
|
+
" --skip-seed",
|
|
687
730
|
options.force ? " --force" : ""
|
|
688
731
|
].join("");
|
|
689
732
|
execPrisma(cmd);
|
|
690
733
|
} catch (err) {
|
|
691
734
|
handleSubProcessError2(err);
|
|
692
735
|
}
|
|
736
|
+
if (!options.skipSeed) {
|
|
737
|
+
await run7({
|
|
738
|
+
noWarnings: true,
|
|
739
|
+
printStatus: true
|
|
740
|
+
}, []);
|
|
741
|
+
}
|
|
693
742
|
}
|
|
694
743
|
__name(runReset, "runReset");
|
|
695
744
|
function runDeploy(prismaSchemaFile, _options) {
|
|
@@ -876,7 +925,7 @@ function getMachineId() {
|
|
|
876
925
|
__name(getMachineId, "getMachineId");
|
|
877
926
|
|
|
878
927
|
// src/utils/version-utils.ts
|
|
879
|
-
var
|
|
928
|
+
var import_colors8 = __toESM(require("colors"), 1);
|
|
880
929
|
var import_node_fs11 = __toESM(require("fs"), 1);
|
|
881
930
|
var import_node_path8 = __toESM(require("path"), 1);
|
|
882
931
|
var import_node_url = require("url");
|
|
@@ -902,7 +951,7 @@ async function checkNewVersion() {
|
|
|
902
951
|
return;
|
|
903
952
|
}
|
|
904
953
|
if (latestVersion && currVersion && import_semver.default.gt(latestVersion, currVersion)) {
|
|
905
|
-
console.log(`A newer version ${
|
|
954
|
+
console.log(`A newer version ${import_colors8.default.cyan(latestVersion)} is available.`);
|
|
906
955
|
}
|
|
907
956
|
}
|
|
908
957
|
__name(checkNewVersion, "checkNewVersion");
|
|
@@ -1032,7 +1081,7 @@ var generateAction = /* @__PURE__ */ __name(async (options) => {
|
|
|
1032
1081
|
await telemetry.trackCommand("generate", () => run4(options));
|
|
1033
1082
|
}, "generateAction");
|
|
1034
1083
|
var migrateAction = /* @__PURE__ */ __name(async (subCommand, options) => {
|
|
1035
|
-
await telemetry.trackCommand(`migrate ${subCommand}`, () =>
|
|
1084
|
+
await telemetry.trackCommand(`migrate ${subCommand}`, () => run8(subCommand, options));
|
|
1036
1085
|
}, "migrateAction");
|
|
1037
1086
|
var dbAction = /* @__PURE__ */ __name(async (subCommand, options) => {
|
|
1038
1087
|
await telemetry.trackCommand(`db ${subCommand}`, () => run2(subCommand, options));
|
|
@@ -1049,10 +1098,13 @@ var checkAction = /* @__PURE__ */ __name(async (options) => {
|
|
|
1049
1098
|
var formatAction = /* @__PURE__ */ __name(async (options) => {
|
|
1050
1099
|
await telemetry.trackCommand("format", () => run3(options));
|
|
1051
1100
|
}, "formatAction");
|
|
1101
|
+
var seedAction = /* @__PURE__ */ __name(async (options, args) => {
|
|
1102
|
+
await telemetry.trackCommand("db seed", () => run7(options, args));
|
|
1103
|
+
}, "seedAction");
|
|
1052
1104
|
function createProgram() {
|
|
1053
1105
|
const program = new import_commander.Command("zen").alias("zenstack").helpOption("-h, --help", "Show this help message").version(getVersion(), "-v --version", "Show CLI version");
|
|
1054
1106
|
const schemaExtensions = import_language3.ZModelLanguageMetaData.fileExtensions.join(", ");
|
|
1055
|
-
program.description(`${
|
|
1107
|
+
program.description(`${import_colors9.default.bold.blue("\u03B6")} ZenStack is the data layer for modern TypeScript apps.
|
|
1056
1108
|
|
|
1057
1109
|
Documentation: https://zenstack.dev/docs/3.x`).showHelpAfterError().showSuggestionAfterError();
|
|
1058
1110
|
const schemaOption = new import_commander.Option("--schema <file>", `schema file (with extension ${schemaExtensions}). Defaults to "zenstack/schema.zmodel" unless specified in package.json.`);
|
|
@@ -1061,12 +1113,22 @@ Documentation: https://zenstack.dev/docs/3.x`).showHelpAfterError().showSuggesti
|
|
|
1061
1113
|
const migrateCommand = program.command("migrate").description("Run database schema migration related tasks.");
|
|
1062
1114
|
const migrationsOption = new import_commander.Option("--migrations <path>", 'path that contains the "migrations" directory');
|
|
1063
1115
|
migrateCommand.command("dev").addOption(schemaOption).addOption(noVersionCheckOption).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));
|
|
1064
|
-
migrateCommand.command("reset").addOption(schemaOption).addOption(new import_commander.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));
|
|
1116
|
+
migrateCommand.command("reset").addOption(schemaOption).addOption(new import_commander.Option("--force", "skip the confirmation prompt")).addOption(migrationsOption).addOption(new import_commander.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));
|
|
1065
1117
|
migrateCommand.command("deploy").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).description("Deploy your pending migrations to your production/staging database").action((options) => migrateAction("deploy", options));
|
|
1066
1118
|
migrateCommand.command("status").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).description("Check the status of your database migrations").action((options) => migrateAction("status", options));
|
|
1067
1119
|
migrateCommand.command("resolve").addOption(schemaOption).addOption(noVersionCheckOption).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));
|
|
1068
1120
|
const dbCommand = program.command("db").description("Manage your database schema during development");
|
|
1069
1121
|
dbCommand.command("push").description("Push the state from your schema to your database").addOption(schemaOption).addOption(noVersionCheckOption).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));
|
|
1122
|
+
dbCommand.command("seed").description("Seed the database").allowExcessArguments(true).addHelpText("after", `
|
|
1123
|
+
Seed script is configured under the "zenstack.seed" field in package.json.
|
|
1124
|
+
E.g.:
|
|
1125
|
+
{
|
|
1126
|
+
"zenstack": {
|
|
1127
|
+
"seed": "ts-node ./zenstack/seed.ts"
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
Arguments following -- are passed to the seed script. E.g.: "zen db seed -- --users 10"`).addOption(noVersionCheckOption).action((options, command) => seedAction(options, command.args));
|
|
1070
1132
|
program.command("info").description("Get information of installed ZenStack packages").argument("[path]", "project path", ".").addOption(noVersionCheckOption).action(infoAction);
|
|
1071
1133
|
program.command("init").description("Initialize an existing project for ZenStack").argument("[path]", "project path", ".").addOption(noVersionCheckOption).action(initAction);
|
|
1072
1134
|
program.command("check").description("Check a ZModel schema for syntax or semantic errors").addOption(schemaOption).addOption(noVersionCheckOption).action(checkAction);
|
|
@@ -1092,10 +1154,10 @@ async function main() {
|
|
|
1092
1154
|
if (e instanceof import_commander.CommanderError) {
|
|
1093
1155
|
exitCode = e.exitCode;
|
|
1094
1156
|
} else if (e instanceof CliError) {
|
|
1095
|
-
console.error(
|
|
1157
|
+
console.error(import_colors9.default.red(e.message));
|
|
1096
1158
|
exitCode = 1;
|
|
1097
1159
|
} else {
|
|
1098
|
-
console.error(
|
|
1160
|
+
console.error(import_colors9.default.red(`Unhandled error: ${e}`));
|
|
1099
1161
|
exitCode = 1;
|
|
1100
1162
|
}
|
|
1101
1163
|
}
|