@zenstackhq/cli 3.4.0-beta.1 → 3.4.0-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -42,6 +42,7 @@ var import_ast = require("@zenstackhq/language/ast");
42
42
  var import_sdk = require("@zenstackhq/sdk");
43
43
  var import_colors = __toESM(require("colors"), 1);
44
44
  var import_node_fs = __toESM(require("fs"), 1);
45
+ var import_node_module = require("module");
45
46
  var import_node_path = __toESM(require("path"), 1);
46
47
 
47
48
  // src/cli-error.ts
@@ -157,10 +158,10 @@ function findUp(names, cwd = process.cwd(), multiple = false, result = []) {
157
158
  }
158
159
  const target = names.find((name) => import_node_fs.default.existsSync(import_node_path.default.join(cwd, name)));
159
160
  if (multiple === false && target) {
160
- return import_node_path.default.join(cwd, target);
161
+ return import_node_path.default.resolve(cwd, target);
161
162
  }
162
163
  if (target) {
163
- result.push(import_node_path.default.join(cwd, target));
164
+ result.push(import_node_path.default.resolve(cwd, target));
164
165
  }
165
166
  const up = import_node_path.default.resolve(cwd, "..");
166
167
  if (up === cwd) {
@@ -189,6 +190,44 @@ function getOutputPath(options, schemaFile) {
189
190
  }
190
191
  }
191
192
  __name(getOutputPath, "getOutputPath");
193
+ async function getZenStackPackages(searchPath) {
194
+ const pkgJsonFile = findUp([
195
+ "package.json"
196
+ ], searchPath, false);
197
+ if (!pkgJsonFile) {
198
+ return [];
199
+ }
200
+ let pkgJson;
201
+ try {
202
+ pkgJson = JSON.parse(import_node_fs.default.readFileSync(pkgJsonFile, "utf8"));
203
+ } catch {
204
+ return [];
205
+ }
206
+ const packages = Array.from(new Set([
207
+ ...Object.keys(pkgJson.dependencies ?? {}),
208
+ ...Object.keys(pkgJson.devDependencies ?? {})
209
+ ].filter((p) => p.startsWith("@zenstackhq/")))).sort();
210
+ const require2 = (0, import_node_module.createRequire)(pkgJsonFile);
211
+ const result = packages.map((pkg) => {
212
+ try {
213
+ const depPkgJson = require2(`${pkg}/package.json`);
214
+ if (depPkgJson.private) {
215
+ return void 0;
216
+ }
217
+ return {
218
+ pkg,
219
+ version: depPkgJson.version
220
+ };
221
+ } catch {
222
+ return {
223
+ pkg,
224
+ version: void 0
225
+ };
226
+ }
227
+ });
228
+ return result.filter((p) => !!p);
229
+ }
230
+ __name(getZenStackPackages, "getZenStackPackages");
192
231
 
193
232
  // src/actions/check.ts
194
233
  async function run(options) {
@@ -269,6 +308,14 @@ var import_common_helpers = require("@zenstackhq/common-helpers");
269
308
  // src/actions/pull/utils.ts
270
309
  var import_ast2 = require("@zenstackhq/language/ast");
271
310
  var import_utils = require("@zenstackhq/language/utils");
311
+ function isDatabaseManagedAttribute(name) {
312
+ return [
313
+ "@relation",
314
+ "@id",
315
+ "@unique"
316
+ ].includes(name) || name.startsWith("@db.");
317
+ }
318
+ __name(isDatabaseManagedAttribute, "isDatabaseManagedAttribute");
272
319
  function getDatasource(model) {
273
320
  const datasource = model.declarations.find((d) => d.$type === "DataSource");
274
321
  if (!datasource) {
@@ -731,12 +778,84 @@ function syncRelation({ model, relation, services, options, selfRelation, simila
731
778
  });
732
779
  sourceModel.fields.splice(firstSourceFieldId, 0, sourceFieldFactory.node);
733
780
  const oppositeFieldPrefix = /[0-9]/g.test(targetModel.name.charAt(0)) ? "_" : "";
734
- const { name: oppositeFieldName } = resolveNameCasing(options.fieldCasing, similarRelations > 0 ? `${oppositeFieldPrefix}${(0, import_common_helpers.lowerCaseFirst)(sourceModel.name)}_${firstColumn}` : `${(0, import_common_helpers.lowerCaseFirst)(resolveNameCasing(options.fieldCasing, sourceModel.name).name)}${relation.references.type === "many" ? "s" : ""}`);
781
+ let { name: oppositeFieldName } = resolveNameCasing(options.fieldCasing, similarRelations > 0 ? `${oppositeFieldPrefix}${(0, import_common_helpers.lowerCaseFirst)(sourceModel.name)}_${firstColumn}` : `${(0, import_common_helpers.lowerCaseFirst)(resolveNameCasing(options.fieldCasing, sourceModel.name).name)}${relation.references.type === "many" ? "s" : ""}`);
782
+ if (targetModel.fields.find((f) => f.name === oppositeFieldName)) {
783
+ ({ name: oppositeFieldName } = resolveNameCasing(options.fieldCasing, `${(0, import_common_helpers.lowerCaseFirst)(sourceModel.name)}_${firstColumn}To${relation.references.table}_${relation.references.columns[0]}`));
784
+ }
735
785
  const targetFieldFactory = new import_factory.DataFieldFactory().setContainer(targetModel).setName(oppositeFieldName).setType((tb) => tb.setOptional(relation.references.type === "one").setArray(relation.references.type === "many").setReference(sourceModel));
736
786
  if (includeRelationName) targetFieldFactory.addAttribute((ab) => ab.setDecl(relationAttribute).addArg((ab2) => ab2.StringLiteral.setValue(relationName)));
737
787
  targetModel.fields.push(targetFieldFactory.node);
738
788
  }
739
789
  __name(syncRelation, "syncRelation");
790
+ function consolidateEnums({ newModel, oldModel }) {
791
+ const newEnums = newModel.declarations.filter((d) => (0, import_ast3.isEnum)(d));
792
+ const newDataModels = newModel.declarations.filter((d) => d.$type === "DataModel");
793
+ const oldDataModels = oldModel.declarations.filter((d) => d.$type === "DataModel");
794
+ const enumMapping = /* @__PURE__ */ new Map();
795
+ for (const newEnum of newEnums) {
796
+ for (const newDM of newDataModels) {
797
+ for (const field of newDM.fields) {
798
+ if (field.$type !== "DataField" || field.type.reference?.ref !== newEnum) continue;
799
+ const oldDM = oldDataModels.find((d) => getDbName(d) === getDbName(newDM));
800
+ if (!oldDM) continue;
801
+ const oldField = oldDM.fields.find((f) => getDbName(f) === getDbName(field));
802
+ if (!oldField || oldField.$type !== "DataField" || !oldField.type.reference?.ref) continue;
803
+ const oldEnum = oldField.type.reference.ref;
804
+ if (!(0, import_ast3.isEnum)(oldEnum)) continue;
805
+ enumMapping.set(newEnum, oldEnum);
806
+ break;
807
+ }
808
+ if (enumMapping.has(newEnum)) break;
809
+ }
810
+ }
811
+ const reverseMapping = /* @__PURE__ */ new Map();
812
+ for (const [newEnum, oldEnum] of enumMapping) {
813
+ if (!reverseMapping.has(oldEnum)) {
814
+ reverseMapping.set(oldEnum, []);
815
+ }
816
+ reverseMapping.get(oldEnum).push(newEnum);
817
+ }
818
+ for (const [oldEnum, newEnumsGroup] of reverseMapping) {
819
+ const keepEnum = newEnumsGroup[0];
820
+ if (newEnumsGroup.length === 1 && keepEnum.name === oldEnum.name) continue;
821
+ const oldValues = new Set(oldEnum.fields.map((f) => getDbName(f)));
822
+ const allMatch = newEnumsGroup.every((ne) => {
823
+ const newValues = new Set(ne.fields.map((f) => getDbName(f)));
824
+ return oldValues.size === newValues.size && [
825
+ ...oldValues
826
+ ].every((v) => newValues.has(v));
827
+ });
828
+ if (!allMatch) continue;
829
+ keepEnum.name = oldEnum.name;
830
+ keepEnum.attributes = oldEnum.attributes.map((attr) => {
831
+ const copy = {
832
+ ...attr,
833
+ $container: keepEnum
834
+ };
835
+ return copy;
836
+ });
837
+ for (let i = 1; i < newEnumsGroup.length; i++) {
838
+ const idx = newModel.declarations.indexOf(newEnumsGroup[i]);
839
+ if (idx >= 0) {
840
+ newModel.declarations.splice(idx, 1);
841
+ }
842
+ }
843
+ for (const newDM of newDataModels) {
844
+ for (const field of newDM.fields) {
845
+ if (field.$type !== "DataField") continue;
846
+ const ref = field.type.reference?.ref;
847
+ if (ref && newEnumsGroup.includes(ref)) {
848
+ field.type.reference = {
849
+ ref: keepEnum,
850
+ $refText: keepEnum.name
851
+ };
852
+ }
853
+ }
854
+ }
855
+ console.log(import_colors3.default.gray(`Consolidated enum${newEnumsGroup.length > 1 ? "s" : ""} ${newEnumsGroup.map((e) => e.name).join(", ")} \u2192 ${oldEnum.name}`));
856
+ }
857
+ }
858
+ __name(consolidateEnums, "consolidateEnums");
740
859
 
741
860
  // src/actions/pull/provider/mysql.ts
742
861
  var import_factory2 = require("@zenstackhq/language/factory");
@@ -994,6 +1113,10 @@ var mysql = {
994
1113
  return (ab) => ab.InvocationExpr.setFunction(getFunctionRef("uuid", services));
995
1114
  }
996
1115
  return (ab) => ab.StringLiteral.setValue(val);
1116
+ case "Json":
1117
+ return (ab) => ab.StringLiteral.setValue(val);
1118
+ case "Bytes":
1119
+ return (ab) => ab.StringLiteral.setValue(val);
997
1120
  }
998
1121
  if (val.includes("(") && val.includes(")")) {
999
1122
  return (ab) => ab.InvocationExpr.setFunction(getFunctionRef("dbgenerated", services)).addArg((a) => a.setValue((v) => v.StringLiteral.setValue(val)));
@@ -1592,6 +1715,26 @@ var postgresql = {
1592
1715
  return (ab) => ab.StringLiteral.setValue(val.slice(1, -1).replace(/''/g, "'"));
1593
1716
  }
1594
1717
  return (ab) => ab.StringLiteral.setValue(val);
1718
+ case "Json":
1719
+ if (val.includes("::")) {
1720
+ return typeCastingConvert({
1721
+ defaultValue,
1722
+ enums,
1723
+ val,
1724
+ services
1725
+ });
1726
+ }
1727
+ return (ab) => ab.StringLiteral.setValue(val);
1728
+ case "Bytes":
1729
+ if (val.includes("::")) {
1730
+ return typeCastingConvert({
1731
+ defaultValue,
1732
+ enums,
1733
+ val,
1734
+ services
1735
+ });
1736
+ }
1737
+ return (ab) => ab.StringLiteral.setValue(val);
1595
1738
  }
1596
1739
  if (val.includes("(") && val.includes(")")) {
1597
1740
  return (ab) => ab.InvocationExpr.setFunction(getFunctionRef("dbgenerated", services)).addArg((a) => a.setValue((v) => v.StringLiteral.setValue(val)));
@@ -2227,6 +2370,10 @@ var sqlite = {
2227
2370
  return (ab) => ab.StringLiteral.setValue(strippedName);
2228
2371
  }
2229
2372
  return (ab) => ab.StringLiteral.setValue(val);
2373
+ case "Json":
2374
+ return (ab) => ab.StringLiteral.setValue(val);
2375
+ case "Bytes":
2376
+ return (ab) => ab.StringLiteral.setValue(val);
2230
2377
  }
2231
2378
  console.warn(`Unsupported default value type: "${defaultValue}" for field type "${fieldType}". Skipping default value.`);
2232
2379
  return null;
@@ -2402,6 +2549,10 @@ async function runPull(options) {
2402
2549
  similarRelations
2403
2550
  });
2404
2551
  }
2552
+ consolidateEnums({
2553
+ newModel,
2554
+ oldModel: model
2555
+ });
2405
2556
  console.log(import_colors4.default.blue("Schema synced"));
2406
2557
  const baseDir = import_node_path2.default.dirname(import_node_path2.default.resolve(schemaFile));
2407
2558
  const baseDirUrlPath = new URL(`file://${baseDir}`).pathname;
@@ -2577,23 +2728,13 @@ async function runPull(options) {
2577
2728
  }
2578
2729
  return;
2579
2730
  }
2580
- originalField.attributes.filter((attr) => !f.attributes.find((d) => d.decl.$refText === attr.decl.$refText) && ![
2581
- "@map",
2582
- "@@map",
2583
- "@default",
2584
- "@updatedAt"
2585
- ].includes(attr.decl.$refText)).forEach((attr) => {
2731
+ originalField.attributes.filter((attr) => !f.attributes.find((d) => d.decl.$refText === attr.decl.$refText) && isDatabaseManagedAttribute(attr.decl.$refText)).forEach((attr) => {
2586
2732
  const field = attr.$container;
2587
2733
  const index = field.attributes.findIndex((d) => d === attr);
2588
2734
  field.attributes.splice(index, 1);
2589
2735
  getModelChanges(originalDataModel.name).deletedAttributes.push(import_colors4.default.yellow(`- ${attr.decl.$refText} from field: ${originalDataModel.name}.${field.name}`));
2590
2736
  });
2591
- f.attributes.filter((attr) => !originalField.attributes.find((d) => d.decl.$refText === attr.decl.$refText) && ![
2592
- "@map",
2593
- "@@map",
2594
- "@default",
2595
- "@updatedAt"
2596
- ].includes(attr.decl.$refText)).forEach((attr) => {
2737
+ f.attributes.filter((attr) => !originalField.attributes.find((d) => d.decl.$refText === attr.decl.$refText) && isDatabaseManagedAttribute(attr.decl.$refText)).forEach((attr) => {
2597
2738
  const cloned = {
2598
2739
  ...attr,
2599
2740
  $container: originalField
@@ -2691,8 +2832,8 @@ async function runPull(options) {
2691
2832
  });
2692
2833
  }
2693
2834
  const generator = new import_language2.ZModelCodeGenerator({
2694
- quote: options.quote,
2695
- indent: options.indent
2835
+ quote: options.quote ?? "single",
2836
+ indent: options.indent ?? 4
2696
2837
  });
2697
2838
  if (options.output) {
2698
2839
  if (treatAsFile) {
@@ -2829,7 +2970,13 @@ var plugin2 = {
2829
2970
  var typescript_default = plugin2;
2830
2971
 
2831
2972
  // src/actions/generate.ts
2973
+ var import_semver = __toESM(require("semver"), 1);
2832
2974
  async function run4(options) {
2975
+ try {
2976
+ await checkForMismatchedPackages(process.cwd());
2977
+ } catch (err) {
2978
+ console.warn(import_colors6.default.yellow(`Failed to check for mismatched ZenStack packages: ${err}`));
2979
+ }
2833
2980
  const model = await pureGenerate(options, false);
2834
2981
  if (options.watch) {
2835
2982
  const logsEnabled = !options.silent;
@@ -3081,13 +3228,46 @@ async function loadPluginModule(provider, basePath) {
3081
3228
  }
3082
3229
  }
3083
3230
  __name(loadPluginModule, "loadPluginModule");
3231
+ async function checkForMismatchedPackages(projectPath) {
3232
+ const packages = await getZenStackPackages(projectPath);
3233
+ if (!packages.length) {
3234
+ return false;
3235
+ }
3236
+ const versions = /* @__PURE__ */ new Set();
3237
+ for (const { version: version2 } of packages) {
3238
+ if (version2) {
3239
+ versions.add(version2);
3240
+ }
3241
+ }
3242
+ if (versions.size > 1) {
3243
+ const message = "WARNING: Multiple versions of ZenStack packages detected.\n This will probably cause issues and break your types.";
3244
+ const slashes = "/".repeat(73);
3245
+ const latestVersion = import_semver.default.sort(Array.from(versions)).reverse()[0];
3246
+ console.warn(import_colors6.default.yellow(`${slashes}
3247
+
3248
+ ${message}
3249
+ `));
3250
+ for (const { pkg, version: version2 } of packages) {
3251
+ if (!version2) continue;
3252
+ if (version2 === latestVersion) {
3253
+ console.log(` ${pkg.padEnd(32)} ${import_colors6.default.green(version2)}`);
3254
+ } else {
3255
+ console.log(` ${pkg.padEnd(32)} ${import_colors6.default.yellow(version2)}`);
3256
+ }
3257
+ }
3258
+ console.warn(`
3259
+ ${import_colors6.default.yellow(slashes)}`);
3260
+ return true;
3261
+ }
3262
+ return false;
3263
+ }
3264
+ __name(checkForMismatchedPackages, "checkForMismatchedPackages");
3084
3265
 
3085
3266
  // src/actions/info.ts
3086
3267
  var import_colors7 = __toESM(require("colors"), 1);
3087
- var import_node_path6 = __toESM(require("path"), 1);
3088
3268
  async function run5(projectPath) {
3089
3269
  const packages = await getZenStackPackages(projectPath);
3090
- if (!packages) {
3270
+ if (!packages.length) {
3091
3271
  console.error("Unable to locate package.json. Are you in a valid project directory?");
3092
3272
  return;
3093
3273
  }
@@ -3104,51 +3284,11 @@ async function run5(projectPath) {
3104
3284
  }
3105
3285
  }
3106
3286
  __name(run5, "run");
3107
- async function getZenStackPackages(projectPath) {
3108
- let pkgJson;
3109
- const resolvedPath = import_node_path6.default.resolve(projectPath);
3110
- try {
3111
- pkgJson = (await import(import_node_path6.default.join(resolvedPath, "package.json"), {
3112
- with: {
3113
- type: "json"
3114
- }
3115
- })).default;
3116
- } catch {
3117
- return [];
3118
- }
3119
- const packages = Array.from(new Set([
3120
- ...Object.keys(pkgJson.dependencies ?? {}),
3121
- ...Object.keys(pkgJson.devDependencies ?? {})
3122
- ].filter((p) => p.startsWith("@zenstackhq/") || p === "zenstack"))).sort();
3123
- const result = await Promise.all(packages.map(async (pkg) => {
3124
- try {
3125
- const depPkgJson = (await import(`${pkg}/package.json`, {
3126
- with: {
3127
- type: "json"
3128
- }
3129
- })).default;
3130
- if (depPkgJson.private) {
3131
- return void 0;
3132
- }
3133
- return {
3134
- pkg,
3135
- version: depPkgJson.version
3136
- };
3137
- } catch {
3138
- return {
3139
- pkg,
3140
- version: void 0
3141
- };
3142
- }
3143
- }));
3144
- return result.filter((p) => !!p);
3145
- }
3146
- __name(getZenStackPackages, "getZenStackPackages");
3147
3287
 
3148
3288
  // src/actions/init.ts
3149
3289
  var import_colors8 = __toESM(require("colors"), 1);
3150
3290
  var import_node_fs7 = __toESM(require("fs"), 1);
3151
- var import_node_path7 = __toESM(require("path"), 1);
3291
+ var import_node_path6 = __toESM(require("path"), 1);
3152
3292
  var import_ora3 = __toESM(require("ora"), 1);
3153
3293
  var import_package_manager_detector = require("package-manager-detector");
3154
3294
 
@@ -3223,11 +3363,11 @@ async function run6(projectPath) {
3223
3363
  }
3224
3364
  }
3225
3365
  const generationFolder = "zenstack";
3226
- if (!import_node_fs7.default.existsSync(import_node_path7.default.join(projectPath, generationFolder))) {
3227
- import_node_fs7.default.mkdirSync(import_node_path7.default.join(projectPath, generationFolder));
3366
+ if (!import_node_fs7.default.existsSync(import_node_path6.default.join(projectPath, generationFolder))) {
3367
+ import_node_fs7.default.mkdirSync(import_node_path6.default.join(projectPath, generationFolder));
3228
3368
  }
3229
- if (!import_node_fs7.default.existsSync(import_node_path7.default.join(projectPath, generationFolder, "schema.zmodel"))) {
3230
- import_node_fs7.default.writeFileSync(import_node_path7.default.join(projectPath, generationFolder, "schema.zmodel"), STARTER_ZMODEL);
3369
+ if (!import_node_fs7.default.existsSync(import_node_path6.default.join(projectPath, generationFolder, "schema.zmodel"))) {
3370
+ import_node_fs7.default.writeFileSync(import_node_path6.default.join(projectPath, generationFolder, "schema.zmodel"), STARTER_ZMODEL);
3231
3371
  } else {
3232
3372
  console.log(import_colors8.default.yellow("Schema file already exists. Skipping generation of sample."));
3233
3373
  }
@@ -3239,7 +3379,7 @@ __name(run6, "run");
3239
3379
 
3240
3380
  // src/actions/migrate.ts
3241
3381
  var import_node_fs8 = __toESM(require("fs"), 1);
3242
- var import_node_path8 = __toESM(require("path"), 1);
3382
+ var import_node_path7 = __toESM(require("path"), 1);
3243
3383
 
3244
3384
  // src/actions/seed.ts
3245
3385
  var import_colors9 = __toESM(require("colors"), 1);
@@ -3272,7 +3412,7 @@ __name(run7, "run");
3272
3412
  async function run8(command, options) {
3273
3413
  const schemaFile = getSchemaFile(options.schema);
3274
3414
  await requireDataSourceUrl(schemaFile);
3275
- const prismaSchemaDir = options.migrations ? import_node_path8.default.dirname(options.migrations) : void 0;
3415
+ const prismaSchemaDir = options.migrations ? import_node_path7.default.dirname(options.migrations) : void 0;
3276
3416
  const prismaSchemaFile = await generateTempPrismaSchema(schemaFile, prismaSchemaDir);
3277
3417
  try {
3278
3418
  switch (command) {
@@ -3397,22 +3537,22 @@ var import_cors = __toESM(require("cors"), 1);
3397
3537
  var import_express2 = __toESM(require("express"), 1);
3398
3538
  var import_jiti2 = require("jiti");
3399
3539
  var import_mysql22 = require("mysql2");
3400
- var import_node_path10 = __toESM(require("path"), 1);
3540
+ var import_node_path9 = __toESM(require("path"), 1);
3401
3541
  var import_pg2 = require("pg");
3402
3542
 
3403
3543
  // src/utils/version-utils.ts
3404
3544
  var import_colors10 = __toESM(require("colors"), 1);
3405
3545
  var import_node_fs9 = __toESM(require("fs"), 1);
3406
- var import_node_path9 = __toESM(require("path"), 1);
3546
+ var import_node_path8 = __toESM(require("path"), 1);
3407
3547
  var import_node_url2 = require("url");
3408
- var import_semver = __toESM(require("semver"), 1);
3548
+ var import_semver2 = __toESM(require("semver"), 1);
3409
3549
  var import_meta2 = {};
3410
3550
  var CHECK_VERSION_TIMEOUT = 2e3;
3411
3551
  var VERSION_CHECK_TAG = "next";
3412
3552
  function getVersion() {
3413
3553
  try {
3414
- const _dirname = typeof __dirname !== "undefined" ? __dirname : import_node_path9.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
3415
- return JSON.parse(import_node_fs9.default.readFileSync(import_node_path9.default.join(_dirname, "../package.json"), "utf8")).version;
3554
+ const _dirname = typeof __dirname !== "undefined" ? __dirname : import_node_path8.default.dirname((0, import_node_url2.fileURLToPath)(import_meta2.url));
3555
+ return JSON.parse(import_node_fs9.default.readFileSync(import_node_path8.default.join(_dirname, "../package.json"), "utf8")).version;
3416
3556
  } catch {
3417
3557
  return void 0;
3418
3558
  }
@@ -3426,7 +3566,7 @@ async function checkNewVersion() {
3426
3566
  } catch {
3427
3567
  return;
3428
3568
  }
3429
- if (latestVersion && currVersion && import_semver.default.gt(latestVersion, currVersion)) {
3569
+ if (latestVersion && currVersion && import_semver2.default.gt(latestVersion, currVersion)) {
3430
3570
  console.log(`A newer version ${import_colors10.default.cyan(latestVersion)} is available.`);
3431
3571
  }
3432
3572
  }
@@ -3441,7 +3581,7 @@ async function getLatestVersion() {
3441
3581
  if (fetchResult.ok) {
3442
3582
  const data = await fetchResult.json();
3443
3583
  const latestVersion = data?.version;
3444
- if (typeof latestVersion === "string" && import_semver.default.valid(latestVersion)) {
3584
+ if (typeof latestVersion === "string" && import_semver2.default.valid(latestVersion)) {
3445
3585
  return latestVersion;
3446
3586
  }
3447
3587
  }
@@ -3460,8 +3600,8 @@ async function run9(options) {
3460
3600
  const schemaFile = getSchemaFile(options.schema);
3461
3601
  console.log(import_colors11.default.gray(`Loading ZModel schema from: ${schemaFile}`));
3462
3602
  let outputPath = getOutputPath(options, schemaFile);
3463
- if (!import_node_path10.default.isAbsolute(outputPath)) {
3464
- outputPath = import_node_path10.default.resolve(process.cwd(), outputPath);
3603
+ if (!import_node_path9.default.isAbsolute(outputPath)) {
3604
+ outputPath = import_node_path9.default.resolve(process.cwd(), outputPath);
3465
3605
  }
3466
3606
  const model = await loadSchemaDocument(schemaFile);
3467
3607
  const dataSource = model.declarations.find(import_ast6.isDataSource);
@@ -3476,7 +3616,7 @@ async function run9(options) {
3476
3616
  const provider = (0, import_utils8.getStringLiteral)(dataSource?.fields.find((f) => f.name === "provider")?.value);
3477
3617
  const dialect = createDialect(provider, databaseUrl, outputPath);
3478
3618
  const jiti = (0, import_jiti2.createJiti)(import_meta3.url);
3479
- const schemaModule = await jiti.import(import_node_path10.default.join(outputPath, "schema"));
3619
+ const schemaModule = await jiti.import(import_node_path9.default.join(outputPath, "schema"));
3480
3620
  const schema = schemaModule.schema;
3481
3621
  const omit = {};
3482
3622
  for (const [modelName, modelDef] of Object.entries(schema.models)) {
@@ -3540,8 +3680,8 @@ function createDialect(provider, databaseUrl, outputPath) {
3540
3680
  let resolvedUrl = databaseUrl.trim();
3541
3681
  if (resolvedUrl.startsWith("file:")) {
3542
3682
  const filePath = resolvedUrl.substring("file:".length);
3543
- if (!import_node_path10.default.isAbsolute(filePath)) {
3544
- resolvedUrl = import_node_path10.default.join(outputPath, filePath);
3683
+ if (!import_node_path9.default.isAbsolute(filePath)) {
3684
+ resolvedUrl = import_node_path9.default.join(outputPath, filePath);
3545
3685
  }
3546
3686
  }
3547
3687
  console.log(import_colors11.default.gray(`Connecting to SQLite database at: ${resolvedUrl}`));
@@ -3903,7 +4043,7 @@ Documentation: https://zenstack.dev/docs`).showHelpAfterError().showSuggestionAf
3903
4043
  migrateCommand.command("resolve").addOption(schemaOption).addOption(noVersionCheckOption).addOption(migrationsOption).addOption(new import_commander.Option("--applied <migration>", "record a specific migration as applied")).addOption(new import_commander.Option("--rolled-back <migration>", "record a specific migration as rolled back")).description("Resolve issues with database migrations in deployment databases").action((options) => migrateAction("resolve", options));
3904
4044
  const dbCommand = program.command("db").description("Manage your database schema during development");
3905
4045
  dbCommand.command("push").description("Push the state from your schema to your database").addOption(schemaOption).addOption(noVersionCheckOption).addOption(new import_commander.Option("--accept-data-loss", "ignore data loss warnings")).addOption(new import_commander.Option("--force-reset", "force a reset of the database before push")).action((options) => dbAction("push", options));
3906
- dbCommand.command("pull").description("Introspect your database.").addOption(schemaOption).addOption(noVersionCheckOption).addOption(new import_commander.Option("-o, --output <path>", "set custom output path for the introspected schema. If a file path is provided, all schemas are merged into that single file. If a directory path is provided, files are written to the directory and imports are kept.")).addOption(new import_commander.Option("--model-casing <pascal|camel|snake|none>", "set the casing of generated models").default("pascal")).addOption(new import_commander.Option("--field-casing <pascal|camel|snake|none>", "set the casing of generated fields").default("camel")).addOption(new import_commander.Option("--always-map", "always add @map and @@map attributes to models and fields").default(false)).addOption(new import_commander.Option("--quote <double|single>", "set the quote style of generated schema files").default("single")).addOption(new import_commander.Option("--indent <number>", "set the indentation of the generated schema files").default(4).argParser(parseInt)).action((options) => dbAction("pull", options));
4046
+ dbCommand.command("pull").description("Introspect your database.").addOption(schemaOption).addOption(noVersionCheckOption).addOption(new import_commander.Option("-o, --output <path>", "set custom output path for the introspected schema. If a file path is provided, all schemas are merged into that single file. If a directory path is provided, files are written to the directory and imports are kept.")).addOption(new import_commander.Option("--model-casing <pascal|camel|snake|none>", "set the casing of generated models").default("pascal")).addOption(new import_commander.Option("--field-casing <pascal|camel|snake|none>", "set the casing of generated fields").default("camel")).addOption(new import_commander.Option("--always-map", "always add @map and @@map attributes to models and fields").default(false)).addOption(new import_commander.Option("--quote <double|single>", "set the quote style of generated schema files").default("single")).addOption(new import_commander.Option("--indent <number>", "set the indentation of the generated schema files").default(4)).action((options) => dbAction("pull", options));
3907
4047
  dbCommand.command("seed").description("Seed the database").allowExcessArguments(true).addHelpText("after", `
3908
4048
  Seed script is configured under the "zenstack.seed" field in package.json.
3909
4049
  E.g.: