@zenstackhq/cli 3.0.0-beta.23 → 3.0.0-beta.25
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 -26
- package/dist/index.cjs +241 -129
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +238 -126
- package/dist/index.js.map +1 -1
- package/package.json +11 -12
- package/src/actions/action-utils.ts +27 -7
- package/src/actions/db.ts +6 -2
- package/src/actions/format.ts +27 -0
- package/src/actions/generate.ts +13 -1
- package/src/actions/index.ts +4 -2
- package/src/actions/migrate.ts +14 -2
- package/src/actions/seed.ts +38 -0
- package/src/index.ts +57 -14
- package/src/plugins/typescript.ts +12 -1
- package/src/utils/exec-utils.ts +18 -7
- package/test/db.test.ts +43 -0
- package/test/format.test.ts +33 -0
package/dist/index.js
CHANGED
|
@@ -13,39 +13,11 @@ var __export = (target, all) => {
|
|
|
13
13
|
|
|
14
14
|
// src/index.ts
|
|
15
15
|
import { ZModelLanguageMetaData } from "@zenstackhq/language";
|
|
16
|
-
import
|
|
16
|
+
import colors9 from "colors";
|
|
17
17
|
import { Command, CommanderError, Option } from "commander";
|
|
18
18
|
|
|
19
|
-
// src/actions/
|
|
20
|
-
import
|
|
21
|
-
|
|
22
|
-
// src/utils/exec-utils.ts
|
|
23
|
-
import { execSync as _exec } from "child_process";
|
|
24
|
-
import { fileURLToPath } from "url";
|
|
25
|
-
function execSync(cmd, options) {
|
|
26
|
-
const { env: env2, ...restOptions } = options ?? {};
|
|
27
|
-
const mergedEnv = env2 ? {
|
|
28
|
-
...process.env,
|
|
29
|
-
...env2
|
|
30
|
-
} : void 0;
|
|
31
|
-
_exec(cmd, {
|
|
32
|
-
encoding: "utf-8",
|
|
33
|
-
stdio: options?.stdio ?? "inherit",
|
|
34
|
-
env: mergedEnv,
|
|
35
|
-
...restOptions
|
|
36
|
-
});
|
|
37
|
-
}
|
|
38
|
-
__name(execSync, "execSync");
|
|
39
|
-
function execPrisma(args, options) {
|
|
40
|
-
let prismaPath;
|
|
41
|
-
if (typeof import.meta.resolve === "function") {
|
|
42
|
-
prismaPath = fileURLToPath(import.meta.resolve("prisma/build/index.js"));
|
|
43
|
-
} else {
|
|
44
|
-
prismaPath = __require.resolve("prisma/build/index.js");
|
|
45
|
-
}
|
|
46
|
-
execSync(`node ${prismaPath} ${args}`, options);
|
|
47
|
-
}
|
|
48
|
-
__name(execPrisma, "execPrisma");
|
|
19
|
+
// src/actions/check.ts
|
|
20
|
+
import colors2 from "colors";
|
|
49
21
|
|
|
50
22
|
// src/actions/action-utils.ts
|
|
51
23
|
import { loadDocument } from "@zenstackhq/language";
|
|
@@ -85,12 +57,12 @@ function getSchemaFile(file) {
|
|
|
85
57
|
return pkgJsonConfig.schema;
|
|
86
58
|
}
|
|
87
59
|
}
|
|
88
|
-
if (fs.existsSync("./
|
|
89
|
-
return "./zenstack/schema.zmodel";
|
|
90
|
-
} else if (fs.existsSync("./schema.zmodel")) {
|
|
60
|
+
if (fs.existsSync("./schema.zmodel")) {
|
|
91
61
|
return "./schema.zmodel";
|
|
62
|
+
} else if (fs.existsSync("./zenstack/schema.zmodel")) {
|
|
63
|
+
return "./zenstack/schema.zmodel";
|
|
92
64
|
} else {
|
|
93
|
-
throw new CliError('Schema file not found in default locations ("./
|
|
65
|
+
throw new CliError('Schema file not found in default locations ("./schema.zmodel" or "./zenstack/schema.zmodel").');
|
|
94
66
|
}
|
|
95
67
|
}
|
|
96
68
|
__name(getSchemaFile, "getSchemaFile");
|
|
@@ -133,7 +105,8 @@ __name(generateTempPrismaSchema, "generateTempPrismaSchema");
|
|
|
133
105
|
function getPkgJsonConfig(startPath) {
|
|
134
106
|
const result = {
|
|
135
107
|
schema: void 0,
|
|
136
|
-
output: void 0
|
|
108
|
+
output: void 0,
|
|
109
|
+
seed: void 0
|
|
137
110
|
};
|
|
138
111
|
const pkgJsonFile = findUp([
|
|
139
112
|
"package.json"
|
|
@@ -148,8 +121,9 @@ function getPkgJsonConfig(startPath) {
|
|
|
148
121
|
return result;
|
|
149
122
|
}
|
|
150
123
|
if (pkgJson.zenstack && typeof pkgJson.zenstack === "object") {
|
|
151
|
-
result.schema = pkgJson.zenstack.schema && path.resolve(path.dirname(pkgJsonFile), pkgJson.zenstack.schema);
|
|
152
|
-
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;
|
|
153
127
|
}
|
|
154
128
|
return result;
|
|
155
129
|
}
|
|
@@ -172,18 +146,83 @@ function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
|
|
|
172
146
|
return findUp(names, up, multiple, result);
|
|
173
147
|
}
|
|
174
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");
|
|
157
|
+
|
|
158
|
+
// src/actions/check.ts
|
|
159
|
+
async function run(options) {
|
|
160
|
+
const schemaFile = getSchemaFile(options.schema);
|
|
161
|
+
try {
|
|
162
|
+
await loadSchemaDocument(schemaFile);
|
|
163
|
+
console.log(colors2.green("\u2713 Schema validation completed successfully."));
|
|
164
|
+
} catch (error) {
|
|
165
|
+
console.error(colors2.red("\u2717 Schema validation failed."));
|
|
166
|
+
throw error;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
__name(run, "run");
|
|
170
|
+
|
|
171
|
+
// src/actions/db.ts
|
|
172
|
+
import fs2 from "fs";
|
|
173
|
+
|
|
174
|
+
// src/utils/exec-utils.ts
|
|
175
|
+
import { execSync as _exec } from "child_process";
|
|
176
|
+
import { fileURLToPath } from "url";
|
|
177
|
+
function execSync(cmd, options) {
|
|
178
|
+
const { env: env2, ...restOptions } = options ?? {};
|
|
179
|
+
const mergedEnv = env2 ? {
|
|
180
|
+
...process.env,
|
|
181
|
+
...env2
|
|
182
|
+
} : void 0;
|
|
183
|
+
_exec(cmd, {
|
|
184
|
+
encoding: "utf-8",
|
|
185
|
+
stdio: options?.stdio ?? "inherit",
|
|
186
|
+
env: mergedEnv,
|
|
187
|
+
...restOptions
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
__name(execSync, "execSync");
|
|
191
|
+
function execPackage(cmd, options) {
|
|
192
|
+
const packageManager = process?.versions?.["bun"] ? "bunx" : "npx";
|
|
193
|
+
execSync(`${packageManager} ${cmd}`, options);
|
|
194
|
+
}
|
|
195
|
+
__name(execPackage, "execPackage");
|
|
196
|
+
function execPrisma(args, options) {
|
|
197
|
+
let prismaPath;
|
|
198
|
+
try {
|
|
199
|
+
if (typeof import.meta.resolve === "function") {
|
|
200
|
+
prismaPath = fileURLToPath(import.meta.resolve("prisma/build/index.js"));
|
|
201
|
+
} else {
|
|
202
|
+
prismaPath = __require.resolve("prisma/build/index.js");
|
|
203
|
+
}
|
|
204
|
+
} catch {
|
|
205
|
+
}
|
|
206
|
+
if (!prismaPath) {
|
|
207
|
+
execPackage(`prisma ${args}`, options);
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
execSync(`node ${prismaPath} ${args}`, options);
|
|
211
|
+
}
|
|
212
|
+
__name(execPrisma, "execPrisma");
|
|
175
213
|
|
|
176
214
|
// src/actions/db.ts
|
|
177
|
-
async function
|
|
215
|
+
async function run2(command, options) {
|
|
178
216
|
switch (command) {
|
|
179
217
|
case "push":
|
|
180
218
|
await runPush(options);
|
|
181
219
|
break;
|
|
182
220
|
}
|
|
183
221
|
}
|
|
184
|
-
__name(
|
|
222
|
+
__name(run2, "run");
|
|
185
223
|
async function runPush(options) {
|
|
186
224
|
const schemaFile = getSchemaFile(options.schema);
|
|
225
|
+
await requireDataSourceUrl(schemaFile);
|
|
187
226
|
const prismaSchemaFile = await generateTempPrismaSchema(schemaFile);
|
|
188
227
|
try {
|
|
189
228
|
const cmd = [
|
|
@@ -206,11 +245,29 @@ async function runPush(options) {
|
|
|
206
245
|
}
|
|
207
246
|
__name(runPush, "runPush");
|
|
208
247
|
|
|
248
|
+
// src/actions/format.ts
|
|
249
|
+
import { formatDocument } from "@zenstackhq/language";
|
|
250
|
+
import colors3 from "colors";
|
|
251
|
+
import fs3 from "fs";
|
|
252
|
+
async function run3(options) {
|
|
253
|
+
const schemaFile = getSchemaFile(options.schema);
|
|
254
|
+
let formattedContent;
|
|
255
|
+
try {
|
|
256
|
+
formattedContent = await formatDocument(fs3.readFileSync(schemaFile, "utf-8"));
|
|
257
|
+
} catch (error) {
|
|
258
|
+
console.error(colors3.red("\u2717 Schema formatting failed."));
|
|
259
|
+
throw error;
|
|
260
|
+
}
|
|
261
|
+
fs3.writeFileSync(schemaFile, formattedContent, "utf-8");
|
|
262
|
+
console.log(colors3.green("\u2713 Schema formatting completed successfully."));
|
|
263
|
+
}
|
|
264
|
+
__name(run3, "run");
|
|
265
|
+
|
|
209
266
|
// src/actions/generate.ts
|
|
210
267
|
import { invariant } from "@zenstackhq/common-helpers";
|
|
211
268
|
import { isPlugin } from "@zenstackhq/language/ast";
|
|
212
269
|
import { getLiteral, getLiteralArray } from "@zenstackhq/language/utils";
|
|
213
|
-
import
|
|
270
|
+
import colors4 from "colors";
|
|
214
271
|
import path4 from "path";
|
|
215
272
|
import ora from "ora";
|
|
216
273
|
|
|
@@ -223,7 +280,7 @@ __export(plugins_exports, {
|
|
|
223
280
|
|
|
224
281
|
// src/plugins/prisma.ts
|
|
225
282
|
import { PrismaSchemaGenerator as PrismaSchemaGenerator2 } from "@zenstackhq/sdk";
|
|
226
|
-
import
|
|
283
|
+
import fs4 from "fs";
|
|
227
284
|
import path2 from "path";
|
|
228
285
|
var plugin = {
|
|
229
286
|
name: "Prisma Schema Generator",
|
|
@@ -232,21 +289,21 @@ var plugin = {
|
|
|
232
289
|
let outFile = path2.join(defaultOutputPath, "schema.prisma");
|
|
233
290
|
if (typeof pluginOptions["output"] === "string") {
|
|
234
291
|
outFile = path2.resolve(defaultOutputPath, pluginOptions["output"]);
|
|
235
|
-
if (!
|
|
236
|
-
|
|
292
|
+
if (!fs4.existsSync(path2.dirname(outFile))) {
|
|
293
|
+
fs4.mkdirSync(path2.dirname(outFile), {
|
|
237
294
|
recursive: true
|
|
238
295
|
});
|
|
239
296
|
}
|
|
240
297
|
}
|
|
241
298
|
const prismaSchema = await new PrismaSchemaGenerator2(model).generate();
|
|
242
|
-
|
|
299
|
+
fs4.writeFileSync(outFile, prismaSchema);
|
|
243
300
|
}
|
|
244
301
|
};
|
|
245
302
|
var prisma_default = plugin;
|
|
246
303
|
|
|
247
304
|
// src/plugins/typescript.ts
|
|
248
305
|
import { TsSchemaGenerator } from "@zenstackhq/sdk";
|
|
249
|
-
import
|
|
306
|
+
import fs5 from "fs";
|
|
250
307
|
import path3 from "path";
|
|
251
308
|
var plugin2 = {
|
|
252
309
|
name: "TypeScript Schema Generator",
|
|
@@ -255,32 +312,37 @@ var plugin2 = {
|
|
|
255
312
|
let outDir = defaultOutputPath;
|
|
256
313
|
if (typeof pluginOptions["output"] === "string") {
|
|
257
314
|
outDir = path3.resolve(defaultOutputPath, pluginOptions["output"]);
|
|
258
|
-
if (!
|
|
259
|
-
|
|
315
|
+
if (!fs5.existsSync(outDir)) {
|
|
316
|
+
fs5.mkdirSync(outDir, {
|
|
260
317
|
recursive: true
|
|
261
318
|
});
|
|
262
319
|
}
|
|
263
320
|
}
|
|
264
321
|
const lite = pluginOptions["lite"] === true;
|
|
265
322
|
const liteOnly = pluginOptions["liteOnly"] === true;
|
|
323
|
+
const importWithFileExtension = pluginOptions["importWithFileExtension"];
|
|
324
|
+
if (importWithFileExtension && typeof importWithFileExtension !== "string") {
|
|
325
|
+
throw new Error('The "importWithFileExtension" option must be a string if specified.');
|
|
326
|
+
}
|
|
266
327
|
await new TsSchemaGenerator().generate(model, {
|
|
267
328
|
outDir,
|
|
268
329
|
lite,
|
|
269
|
-
liteOnly
|
|
330
|
+
liteOnly,
|
|
331
|
+
importWithFileExtension
|
|
270
332
|
});
|
|
271
333
|
}
|
|
272
334
|
};
|
|
273
335
|
var typescript_default = plugin2;
|
|
274
336
|
|
|
275
337
|
// src/actions/generate.ts
|
|
276
|
-
async function
|
|
338
|
+
async function run4(options) {
|
|
277
339
|
const start = Date.now();
|
|
278
340
|
const schemaFile = getSchemaFile(options.schema);
|
|
279
341
|
const model = await loadSchemaDocument(schemaFile);
|
|
280
342
|
const outputPath = getOutputPath(options, schemaFile);
|
|
281
343
|
await runPlugins(schemaFile, model, outputPath, options);
|
|
282
344
|
if (!options.silent) {
|
|
283
|
-
console.log(
|
|
345
|
+
console.log(colors4.green(`Generation completed successfully in ${Date.now() - start}ms.
|
|
284
346
|
`));
|
|
285
347
|
console.log(`You can now create a ZenStack client with it.
|
|
286
348
|
|
|
@@ -296,7 +358,7 @@ const client = new ZenStackClient(schema, {
|
|
|
296
358
|
Check documentation: https://zenstack.dev/docs/3.x`);
|
|
297
359
|
}
|
|
298
360
|
}
|
|
299
|
-
__name(
|
|
361
|
+
__name(run4, "run");
|
|
300
362
|
function getOutputPath(options, schemaFile) {
|
|
301
363
|
if (options.output) {
|
|
302
364
|
return options.output;
|
|
@@ -331,9 +393,18 @@ async function runPlugins(schemaFile, model, outputPath, options) {
|
|
|
331
393
|
}
|
|
332
394
|
}
|
|
333
395
|
if (cliPlugin) {
|
|
396
|
+
const pluginOptions = getPluginOptions(plugin3);
|
|
397
|
+
if (provider === "@core/typescript") {
|
|
398
|
+
if (pluginOptions["lite"] === void 0) {
|
|
399
|
+
pluginOptions["lite"] = options.lite;
|
|
400
|
+
}
|
|
401
|
+
if (pluginOptions["liteOnly"] === void 0) {
|
|
402
|
+
pluginOptions["liteOnly"] = options.liteOnly;
|
|
403
|
+
}
|
|
404
|
+
}
|
|
334
405
|
processedPlugins.push({
|
|
335
406
|
cliPlugin,
|
|
336
|
-
pluginOptions
|
|
407
|
+
pluginOptions
|
|
337
408
|
});
|
|
338
409
|
}
|
|
339
410
|
}
|
|
@@ -400,9 +471,9 @@ function getPluginOptions(plugin3) {
|
|
|
400
471
|
__name(getPluginOptions, "getPluginOptions");
|
|
401
472
|
|
|
402
473
|
// src/actions/info.ts
|
|
403
|
-
import
|
|
474
|
+
import colors5 from "colors";
|
|
404
475
|
import path5 from "path";
|
|
405
|
-
async function
|
|
476
|
+
async function run5(projectPath) {
|
|
406
477
|
const packages = await getZenStackPackages(projectPath);
|
|
407
478
|
if (!packages) {
|
|
408
479
|
console.error("Unable to locate package.json. Are you in a valid project directory?");
|
|
@@ -414,13 +485,13 @@ async function run3(projectPath) {
|
|
|
414
485
|
if (version2) {
|
|
415
486
|
versions.add(version2);
|
|
416
487
|
}
|
|
417
|
-
console.log(` ${
|
|
488
|
+
console.log(` ${colors5.green(pkg.padEnd(20))} ${version2}`);
|
|
418
489
|
}
|
|
419
490
|
if (versions.size > 1) {
|
|
420
|
-
console.warn(
|
|
491
|
+
console.warn(colors5.yellow("WARNING: Multiple versions of Zenstack packages detected. This may cause issues."));
|
|
421
492
|
}
|
|
422
493
|
}
|
|
423
|
-
__name(
|
|
494
|
+
__name(run5, "run");
|
|
424
495
|
async function getZenStackPackages(projectPath) {
|
|
425
496
|
let pkgJson;
|
|
426
497
|
const resolvedPath = path5.resolve(projectPath);
|
|
@@ -463,8 +534,8 @@ async function getZenStackPackages(projectPath) {
|
|
|
463
534
|
__name(getZenStackPackages, "getZenStackPackages");
|
|
464
535
|
|
|
465
536
|
// src/actions/init.ts
|
|
466
|
-
import
|
|
467
|
-
import
|
|
537
|
+
import colors6 from "colors";
|
|
538
|
+
import fs6 from "fs";
|
|
468
539
|
import path6 from "path";
|
|
469
540
|
import ora2 from "ora";
|
|
470
541
|
import { detect, resolveCommand } from "package-manager-detector";
|
|
@@ -499,7 +570,7 @@ model Post {
|
|
|
499
570
|
`;
|
|
500
571
|
|
|
501
572
|
// src/actions/init.ts
|
|
502
|
-
async function
|
|
573
|
+
async function run6(projectPath) {
|
|
503
574
|
const packages = [
|
|
504
575
|
{
|
|
505
576
|
name: "@zenstackhq/cli@next",
|
|
@@ -517,7 +588,7 @@ async function run4(projectPath) {
|
|
|
517
588
|
name: "npm"
|
|
518
589
|
};
|
|
519
590
|
}
|
|
520
|
-
console.log(
|
|
591
|
+
console.log(colors6.gray(`Using package manager: ${pm.agent}`));
|
|
521
592
|
for (const pkg of packages) {
|
|
522
593
|
const resolved = resolveCommand(pm.agent, "install", [
|
|
523
594
|
pkg.name,
|
|
@@ -540,25 +611,55 @@ async function run4(projectPath) {
|
|
|
540
611
|
}
|
|
541
612
|
}
|
|
542
613
|
const generationFolder = "zenstack";
|
|
543
|
-
if (!
|
|
544
|
-
|
|
614
|
+
if (!fs6.existsSync(path6.join(projectPath, generationFolder))) {
|
|
615
|
+
fs6.mkdirSync(path6.join(projectPath, generationFolder));
|
|
545
616
|
}
|
|
546
|
-
if (!
|
|
547
|
-
|
|
617
|
+
if (!fs6.existsSync(path6.join(projectPath, generationFolder, "schema.zmodel"))) {
|
|
618
|
+
fs6.writeFileSync(path6.join(projectPath, generationFolder, "schema.zmodel"), STARTER_ZMODEL);
|
|
548
619
|
} else {
|
|
549
|
-
console.log(
|
|
620
|
+
console.log(colors6.yellow("Schema file already exists. Skipping generation of sample."));
|
|
550
621
|
}
|
|
551
|
-
console.log(
|
|
552
|
-
console.log(
|
|
553
|
-
console.log(
|
|
622
|
+
console.log(colors6.green("ZenStack project initialized successfully!"));
|
|
623
|
+
console.log(colors6.gray(`See "${generationFolder}/schema.zmodel" for your database schema.`));
|
|
624
|
+
console.log(colors6.gray("Run `zenstack generate` to compile the the schema into a TypeScript file."));
|
|
554
625
|
}
|
|
555
|
-
__name(
|
|
626
|
+
__name(run6, "run");
|
|
556
627
|
|
|
557
628
|
// src/actions/migrate.ts
|
|
558
|
-
import
|
|
629
|
+
import fs7 from "fs";
|
|
559
630
|
import path7 from "path";
|
|
560
|
-
|
|
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) {
|
|
561
661
|
const schemaFile = getSchemaFile(options.schema);
|
|
662
|
+
await requireDataSourceUrl(schemaFile);
|
|
562
663
|
const prismaSchemaDir = options.migrations ? path7.dirname(options.migrations) : void 0;
|
|
563
664
|
const prismaSchemaFile = await generateTempPrismaSchema(schemaFile, prismaSchemaDir);
|
|
564
665
|
try {
|
|
@@ -580,18 +681,19 @@ async function run5(command, options) {
|
|
|
580
681
|
break;
|
|
581
682
|
}
|
|
582
683
|
} finally {
|
|
583
|
-
if (
|
|
584
|
-
|
|
684
|
+
if (fs7.existsSync(prismaSchemaFile)) {
|
|
685
|
+
fs7.unlinkSync(prismaSchemaFile);
|
|
585
686
|
}
|
|
586
687
|
}
|
|
587
688
|
}
|
|
588
|
-
__name(
|
|
689
|
+
__name(run8, "run");
|
|
589
690
|
function runDev(prismaSchemaFile, options) {
|
|
590
691
|
try {
|
|
591
692
|
const cmd = [
|
|
592
693
|
"migrate dev",
|
|
593
694
|
` --schema "${prismaSchemaFile}"`,
|
|
594
695
|
" --skip-generate",
|
|
696
|
+
" --skip-seed",
|
|
595
697
|
options.name ? ` --name "${options.name}"` : "",
|
|
596
698
|
options.createOnly ? " --create-only" : ""
|
|
597
699
|
].join("");
|
|
@@ -601,18 +703,25 @@ function runDev(prismaSchemaFile, options) {
|
|
|
601
703
|
}
|
|
602
704
|
}
|
|
603
705
|
__name(runDev, "runDev");
|
|
604
|
-
function runReset(prismaSchemaFile, options) {
|
|
706
|
+
async function runReset(prismaSchemaFile, options) {
|
|
605
707
|
try {
|
|
606
708
|
const cmd = [
|
|
607
709
|
"migrate reset",
|
|
608
710
|
` --schema "${prismaSchemaFile}"`,
|
|
609
711
|
" --skip-generate",
|
|
712
|
+
" --skip-seed",
|
|
610
713
|
options.force ? " --force" : ""
|
|
611
714
|
].join("");
|
|
612
715
|
execPrisma(cmd);
|
|
613
716
|
} catch (err) {
|
|
614
717
|
handleSubProcessError2(err);
|
|
615
718
|
}
|
|
719
|
+
if (!options.skipSeed) {
|
|
720
|
+
await run7({
|
|
721
|
+
noWarnings: true,
|
|
722
|
+
printStatus: true
|
|
723
|
+
}, []);
|
|
724
|
+
}
|
|
616
725
|
}
|
|
617
726
|
__name(runReset, "runReset");
|
|
618
727
|
function runDeploy(prismaSchemaFile, _options) {
|
|
@@ -661,24 +770,10 @@ function handleSubProcessError2(err) {
|
|
|
661
770
|
}
|
|
662
771
|
__name(handleSubProcessError2, "handleSubProcessError");
|
|
663
772
|
|
|
664
|
-
// src/actions/check.ts
|
|
665
|
-
import colors5 from "colors";
|
|
666
|
-
async function run6(options) {
|
|
667
|
-
const schemaFile = getSchemaFile(options.schema);
|
|
668
|
-
try {
|
|
669
|
-
await loadSchemaDocument(schemaFile);
|
|
670
|
-
console.log(colors5.green("\u2713 Schema validation completed successfully."));
|
|
671
|
-
} catch (error) {
|
|
672
|
-
console.error(colors5.red("\u2717 Schema validation failed."));
|
|
673
|
-
throw error;
|
|
674
|
-
}
|
|
675
|
-
}
|
|
676
|
-
__name(run6, "run");
|
|
677
|
-
|
|
678
773
|
// src/telemetry.ts
|
|
679
774
|
import { init } from "mixpanel";
|
|
680
775
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
681
|
-
import
|
|
776
|
+
import fs12 from "fs";
|
|
682
777
|
import * as os2 from "os";
|
|
683
778
|
|
|
684
779
|
// src/constants.ts
|
|
@@ -689,14 +784,14 @@ import { env } from "process";
|
|
|
689
784
|
var isInCi = env["CI"] !== "0" && env["CI"] !== "false" && ("CI" in env || "CONTINUOUS_INTEGRATION" in env || Object.keys(env).some((key) => key.startsWith("CI_")));
|
|
690
785
|
|
|
691
786
|
// src/utils/is-container.ts
|
|
692
|
-
import
|
|
787
|
+
import fs9 from "fs";
|
|
693
788
|
|
|
694
789
|
// src/utils/is-docker.ts
|
|
695
|
-
import
|
|
790
|
+
import fs8 from "fs";
|
|
696
791
|
var isDockerCached;
|
|
697
792
|
function hasDockerEnv() {
|
|
698
793
|
try {
|
|
699
|
-
|
|
794
|
+
fs8.statSync("/.dockerenv");
|
|
700
795
|
return true;
|
|
701
796
|
} catch {
|
|
702
797
|
return false;
|
|
@@ -705,7 +800,7 @@ function hasDockerEnv() {
|
|
|
705
800
|
__name(hasDockerEnv, "hasDockerEnv");
|
|
706
801
|
function hasDockerCGroup() {
|
|
707
802
|
try {
|
|
708
|
-
return
|
|
803
|
+
return fs8.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
709
804
|
} catch {
|
|
710
805
|
return false;
|
|
711
806
|
}
|
|
@@ -723,7 +818,7 @@ __name(isDocker, "isDocker");
|
|
|
723
818
|
var cachedResult;
|
|
724
819
|
var hasContainerEnv = /* @__PURE__ */ __name(() => {
|
|
725
820
|
try {
|
|
726
|
-
|
|
821
|
+
fs9.statSync("/run/.containerenv");
|
|
727
822
|
return true;
|
|
728
823
|
} catch {
|
|
729
824
|
return false;
|
|
@@ -740,7 +835,7 @@ __name(isInContainer, "isInContainer");
|
|
|
740
835
|
// src/utils/is-wsl.ts
|
|
741
836
|
import process2 from "process";
|
|
742
837
|
import os from "os";
|
|
743
|
-
import
|
|
838
|
+
import fs10 from "fs";
|
|
744
839
|
var isWsl = /* @__PURE__ */ __name(() => {
|
|
745
840
|
if (process2.platform !== "linux") {
|
|
746
841
|
return false;
|
|
@@ -749,7 +844,7 @@ var isWsl = /* @__PURE__ */ __name(() => {
|
|
|
749
844
|
return true;
|
|
750
845
|
}
|
|
751
846
|
try {
|
|
752
|
-
return
|
|
847
|
+
return fs10.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft");
|
|
753
848
|
} catch {
|
|
754
849
|
return false;
|
|
755
850
|
}
|
|
@@ -813,8 +908,8 @@ function getMachineId() {
|
|
|
813
908
|
__name(getMachineId, "getMachineId");
|
|
814
909
|
|
|
815
910
|
// src/utils/version-utils.ts
|
|
816
|
-
import
|
|
817
|
-
import
|
|
911
|
+
import colors8 from "colors";
|
|
912
|
+
import fs11 from "fs";
|
|
818
913
|
import path8 from "path";
|
|
819
914
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
820
915
|
import semver from "semver";
|
|
@@ -823,7 +918,7 @@ var VERSION_CHECK_TAG = "next";
|
|
|
823
918
|
function getVersion() {
|
|
824
919
|
try {
|
|
825
920
|
const _dirname = typeof __dirname !== "undefined" ? __dirname : path8.dirname(fileURLToPath2(import.meta.url));
|
|
826
|
-
return JSON.parse(
|
|
921
|
+
return JSON.parse(fs11.readFileSync(path8.join(_dirname, "../package.json"), "utf8")).version;
|
|
827
922
|
} catch {
|
|
828
923
|
return void 0;
|
|
829
924
|
}
|
|
@@ -838,7 +933,7 @@ async function checkNewVersion() {
|
|
|
838
933
|
return;
|
|
839
934
|
}
|
|
840
935
|
if (latestVersion && currVersion && semver.gt(latestVersion, currVersion)) {
|
|
841
|
-
console.log(`A newer version ${
|
|
936
|
+
console.log(`A newer version ${colors8.cyan(latestVersion)} is available.`);
|
|
842
937
|
}
|
|
843
938
|
}
|
|
844
939
|
__name(checkNewVersion, "checkNewVersion");
|
|
@@ -953,7 +1048,7 @@ var Telemetry = class {
|
|
|
953
1048
|
try {
|
|
954
1049
|
const packageJsonPath = import.meta.resolve("prisma/package.json");
|
|
955
1050
|
const packageJsonUrl = new URL(packageJsonPath);
|
|
956
|
-
const packageJson = JSON.parse(
|
|
1051
|
+
const packageJson = JSON.parse(fs12.readFileSync(packageJsonUrl, "utf8"));
|
|
957
1052
|
return packageJson.version;
|
|
958
1053
|
} catch {
|
|
959
1054
|
return void 0;
|
|
@@ -964,45 +1059,62 @@ var telemetry = new Telemetry();
|
|
|
964
1059
|
|
|
965
1060
|
// src/index.ts
|
|
966
1061
|
var generateAction = /* @__PURE__ */ __name(async (options) => {
|
|
967
|
-
await telemetry.trackCommand("generate", () =>
|
|
1062
|
+
await telemetry.trackCommand("generate", () => run4(options));
|
|
968
1063
|
}, "generateAction");
|
|
969
1064
|
var migrateAction = /* @__PURE__ */ __name(async (subCommand, options) => {
|
|
970
|
-
await telemetry.trackCommand(`migrate ${subCommand}`, () =>
|
|
1065
|
+
await telemetry.trackCommand(`migrate ${subCommand}`, () => run8(subCommand, options));
|
|
971
1066
|
}, "migrateAction");
|
|
972
1067
|
var dbAction = /* @__PURE__ */ __name(async (subCommand, options) => {
|
|
973
|
-
await telemetry.trackCommand(`db ${subCommand}`, () =>
|
|
1068
|
+
await telemetry.trackCommand(`db ${subCommand}`, () => run2(subCommand, options));
|
|
974
1069
|
}, "dbAction");
|
|
975
1070
|
var infoAction = /* @__PURE__ */ __name(async (projectPath) => {
|
|
976
|
-
await telemetry.trackCommand("info", () =>
|
|
1071
|
+
await telemetry.trackCommand("info", () => run5(projectPath));
|
|
977
1072
|
}, "infoAction");
|
|
978
1073
|
var initAction = /* @__PURE__ */ __name(async (projectPath) => {
|
|
979
|
-
await telemetry.trackCommand("init", () =>
|
|
1074
|
+
await telemetry.trackCommand("init", () => run6(projectPath));
|
|
980
1075
|
}, "initAction");
|
|
981
1076
|
var checkAction = /* @__PURE__ */ __name(async (options) => {
|
|
982
|
-
await telemetry.trackCommand("check", () =>
|
|
1077
|
+
await telemetry.trackCommand("check", () => run(options));
|
|
983
1078
|
}, "checkAction");
|
|
1079
|
+
var formatAction = /* @__PURE__ */ __name(async (options) => {
|
|
1080
|
+
await telemetry.trackCommand("format", () => run3(options));
|
|
1081
|
+
}, "formatAction");
|
|
1082
|
+
var seedAction = /* @__PURE__ */ __name(async (options, args) => {
|
|
1083
|
+
await telemetry.trackCommand("db seed", () => run7(options, args));
|
|
1084
|
+
}, "seedAction");
|
|
984
1085
|
function createProgram() {
|
|
985
|
-
const program = new Command("zen");
|
|
986
|
-
program.version(getVersion(), "-v --version", "display CLI version");
|
|
1086
|
+
const program = new Command("zen").alias("zenstack").helpOption("-h, --help", "Show this help message").version(getVersion(), "-v --version", "Show CLI version");
|
|
987
1087
|
const schemaExtensions = ZModelLanguageMetaData.fileExtensions.join(", ");
|
|
988
|
-
program.description(`${
|
|
1088
|
+
program.description(`${colors9.bold.blue("\u03B6")} ZenStack is the data layer for modern TypeScript apps.
|
|
989
1089
|
|
|
990
1090
|
Documentation: https://zenstack.dev/docs/3.x`).showHelpAfterError().showSuggestionAfterError();
|
|
991
1091
|
const schemaOption = new Option("--schema <file>", `schema file (with extension ${schemaExtensions}). Defaults to "zenstack/schema.zmodel" unless specified in package.json.`);
|
|
992
1092
|
const noVersionCheckOption = new Option("--no-version-check", "do not check for new version");
|
|
993
|
-
program.command("generate").description("Run code generation plugins
|
|
1093
|
+
program.command("generate").description("Run code generation plugins").addOption(schemaOption).addOption(noVersionCheckOption).addOption(new Option("-o, --output <path>", "default output directory for code generation")).addOption(new Option("--lite", "also generate a lite version of schema without attributes").default(false)).addOption(new Option("--lite-only", "only generate lite version of schema without attributes").default(false)).addOption(new Option("--silent", "suppress all output except errors").default(false)).action(generateAction);
|
|
994
1094
|
const migrateCommand = program.command("migrate").description("Run database schema migration related tasks.");
|
|
995
1095
|
const migrationsOption = new Option("--migrations <path>", 'path that contains the "migrations" directory');
|
|
996
|
-
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
|
|
997
|
-
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));
|
|
998
|
-
migrateCommand.command("deploy").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).description("Deploy your pending migrations to your production/staging database
|
|
999
|
-
migrateCommand.command("status").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).description("Check the status of your database migrations
|
|
1000
|
-
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
|
|
1001
|
-
const dbCommand = program.command("db").description("Manage your database schema during development
|
|
1002
|
-
dbCommand.command("push").description("Push the state from your schema to your database
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
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));
|
|
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));
|
|
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));
|
|
1099
|
+
migrateCommand.command("status").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).description("Check the status of your database migrations").action((options) => migrateAction("status", options));
|
|
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));
|
|
1101
|
+
const dbCommand = program.command("db").description("Manage your database schema during development");
|
|
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));
|
|
1113
|
+
program.command("info").description("Get information of installed ZenStack packages").argument("[path]", "project path", ".").addOption(noVersionCheckOption).action(infoAction);
|
|
1114
|
+
program.command("init").description("Initialize an existing project for ZenStack").argument("[path]", "project path", ".").addOption(noVersionCheckOption).action(initAction);
|
|
1115
|
+
program.command("check").description("Check a ZModel schema for syntax or semantic errors").addOption(schemaOption).addOption(noVersionCheckOption).action(checkAction);
|
|
1116
|
+
program.command("format").description("Format a ZModel schema file").addOption(schemaOption).addOption(noVersionCheckOption).action(formatAction);
|
|
1117
|
+
program.addHelpCommand("help [command]", "Display help for a command");
|
|
1006
1118
|
program.hook("preAction", async (_thisCommand, actionCommand) => {
|
|
1007
1119
|
if (actionCommand.getOptionValue("versionCheck") !== false) {
|
|
1008
1120
|
await checkNewVersion();
|
|
@@ -1023,10 +1135,10 @@ async function main() {
|
|
|
1023
1135
|
if (e instanceof CommanderError) {
|
|
1024
1136
|
exitCode = e.exitCode;
|
|
1025
1137
|
} else if (e instanceof CliError) {
|
|
1026
|
-
console.error(
|
|
1138
|
+
console.error(colors9.red(e.message));
|
|
1027
1139
|
exitCode = 1;
|
|
1028
1140
|
} else {
|
|
1029
|
-
console.error(
|
|
1141
|
+
console.error(colors9.red(`Unhandled error: ${e}`));
|
|
1030
1142
|
exitCode = 1;
|
|
1031
1143
|
}
|
|
1032
1144
|
}
|