@zenstackhq/cli 3.0.0-alpha.2 → 3.0.0-alpha.21
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 +22 -23
- package/bin/cli +1 -1
- package/dist/index.cjs +244 -170
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +245 -179
- package/dist/index.js.map +1 -1
- package/eslint.config.js +4 -0
- package/package.json +15 -16
- package/src/actions/action-utils.ts +81 -10
- package/src/actions/db.ts +30 -29
- package/src/actions/generate.ts +37 -22
- package/src/actions/index.ts +2 -1
- package/src/actions/info.ts +9 -18
- package/src/actions/init.ts +6 -27
- package/src/actions/migrate.ts +61 -63
- package/src/actions/templates.ts +7 -1
- package/src/actions/validate.ts +22 -0
- package/src/index.ts +45 -41
- package/src/utils/exec-utils.ts +2 -5
- package/src/utils/version-utils.ts +9 -9
- package/test/db.test.ts +18 -0
- package/test/generate.test.ts +59 -0
- package/test/init.test.ts +13 -0
- package/test/migrate.test.ts +41 -0
- package/test/ts-schema-gen.test.ts +180 -2
- package/test/utils.ts +23 -0
- package/test/validate.test.ts +101 -0
- package/tsconfig.json +1 -1
- package/vitest.config.ts +1 -1
- package/.turbo/turbo-lint.log +0 -18
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
|
|
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
|
|
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
|
|
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("
|
|
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
|
|
162
|
-
import
|
|
163
|
-
|
|
164
|
-
|
|
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
|
|
168
|
-
const tsSchemaFile =
|
|
169
|
-
await new TsSchemaGenerator().generate(schemaFile, [],
|
|
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
|
-
|
|
172
|
-
|
|
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(
|
|
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(
|
|
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 "
|
|
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
|
|
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
|
|
298
|
-
import path4 from "
|
|
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 (!
|
|
374
|
-
|
|
397
|
+
if (!fs4.existsSync(path4.join(projectPath, generationFolder))) {
|
|
398
|
+
fs4.mkdirSync(path4.join(projectPath, generationFolder));
|
|
375
399
|
}
|
|
376
|
-
if (!
|
|
377
|
-
|
|
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
|
|
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
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
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,
|
|
440
|
+
async function runDev(prismaSchemaFile, options) {
|
|
413
441
|
try {
|
|
414
|
-
|
|
415
|
-
|
|
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
|
-
|
|
425
|
-
|
|
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
|
-
|
|
435
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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(`${
|
|
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
|
-
|
|
502
|
-
migrateCommand.command("
|
|
503
|
-
migrateCommand.command("
|
|
504
|
-
migrateCommand.command("
|
|
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.
|
|
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
|
};
|