@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/.turbo/turbo-build.log +22 -23
- package/bin/cli +1 -1
- package/dist/index.cjs +385 -193
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +387 -199
- package/dist/index.js.map +1 -1
- package/eslint.config.js +4 -0
- package/package.json +16 -17
- package/src/actions/action-utils.ts +81 -10
- package/src/actions/check.ts +22 -0
- package/src/actions/db.ts +30 -29
- package/src/actions/generate.ts +101 -38
- 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 +90 -63
- package/src/actions/templates.ts +4 -3
- package/src/index.ts +57 -47
- package/src/plugins/index.ts +2 -0
- package/src/plugins/prisma.ts +21 -0
- package/src/plugins/typescript.ts +21 -0
- package/src/utils/exec-utils.ts +2 -5
- package/src/utils/version-utils.ts +9 -9
- package/test/check.test.ts +101 -0
- package/test/db.test.ts +18 -0
- package/test/generate.test.ts +47 -0
- package/test/init.test.ts +13 -0
- package/test/migrate.test.ts +72 -0
- package/test/plugins/custom-plugin.test.ts +50 -0
- package/test/plugins/prisma-plugin.test.ts +60 -0
- package/test/ts-schema-gen.test.ts +180 -1
- package/test/utils.ts +23 -0
- package/tsconfig.json +1 -4
- package/vitest.config.ts +1 -1
- package/.turbo/turbo-lint.log +0 -18
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
|
|
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
|
|
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("
|
|
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
|
|
184
|
-
var
|
|
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
|
|
187
|
-
var
|
|
188
|
-
|
|
189
|
-
|
|
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
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
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
|
-
|
|
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(
|
|
214
|
-
async function runPlugins(model, outputPath
|
|
215
|
-
const plugins = model.declarations.filter(
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
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
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
model,
|
|
228
|
-
outputPath,
|
|
229
|
-
tsSchemaFile
|
|
332
|
+
processedPlugins.push({
|
|
333
|
+
cliPlugin,
|
|
334
|
+
pluginOptions: getPluginOptions(plugin3)
|
|
230
335
|
});
|
|
231
336
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
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
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
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(
|
|
250
|
-
|
|
251
|
-
const
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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(
|
|
388
|
+
__name(getPluginOptions, "getPluginOptions");
|
|
261
389
|
|
|
262
390
|
// src/actions/info.ts
|
|
263
391
|
var import_colors3 = __toESM(require("colors"), 1);
|
|
264
|
-
var
|
|
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 =
|
|
414
|
+
const resolvedPath = import_node_path5.default.resolve(projectPath);
|
|
287
415
|
try {
|
|
288
|
-
pkgJson = (await import(
|
|
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
|
|
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
|
|
325
|
-
var
|
|
326
|
-
var
|
|
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,
|
|
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 (!
|
|
401
|
-
|
|
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 (!
|
|
404
|
-
|
|
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
|
|
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
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
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,
|
|
574
|
+
async function runDev(prismaSchemaFile, options) {
|
|
440
575
|
try {
|
|
441
|
-
|
|
442
|
-
|
|
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
|
-
|
|
452
|
-
|
|
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
|
-
|
|
462
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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(`${
|
|
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
|
|
527
|
-
const migrateCommand = program2.command("migrate").description("
|
|
528
|
-
|
|
529
|
-
migrateCommand.command("
|
|
530
|
-
migrateCommand.command("
|
|
531
|
-
migrateCommand.command("
|
|
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
|
|
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.
|
|
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
|