@zenstackhq/cli 3.4.0-beta.1 → 3.4.0-beta.2
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 +219 -79
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +219 -79
- package/dist/index.js.map +1 -1
- package/package.json +11 -11
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.
|
|
161
|
+
return import_node_path.default.resolve(cwd, target);
|
|
161
162
|
}
|
|
162
163
|
if (target) {
|
|
163
|
-
result.push(import_node_path.default.
|
|
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
|
-
|
|
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
|
|
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(
|
|
3227
|
-
import_node_fs7.default.mkdirSync(
|
|
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(
|
|
3230
|
-
import_node_fs7.default.writeFileSync(
|
|
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
|
|
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 ?
|
|
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
|
|
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
|
|
3546
|
+
var import_node_path8 = __toESM(require("path"), 1);
|
|
3407
3547
|
var import_node_url2 = require("url");
|
|
3408
|
-
var
|
|
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 :
|
|
3415
|
-
return JSON.parse(import_node_fs9.default.readFileSync(
|
|
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 &&
|
|
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" &&
|
|
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 (!
|
|
3464
|
-
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(
|
|
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 (!
|
|
3544
|
-
resolvedUrl =
|
|
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)
|
|
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.:
|