@svton/cli 2.0.0 → 2.1.0

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.js CHANGED
@@ -860,11 +860,16 @@ function collectEnvVars(features, config) {
860
860
  }
861
861
  return envVars;
862
862
  }
863
- async function generateEnvExample(features, config, targetPath) {
863
+ async function generateEnvExample(features, config, targetPath, database = "mysql") {
864
864
  const envVars = collectEnvVars(features, config);
865
865
  if (envVars.length === 0) {
866
866
  return;
867
867
  }
868
+ const databaseUrls = {
869
+ mysql: "mysql://root:root123456@localhost:3306/{{PROJECT_NAME}}",
870
+ postgresql: "postgresql://postgres:postgres@localhost:5432/{{PROJECT_NAME}}",
871
+ sqlite: "file:./dev.db"
872
+ };
868
873
  const content = [
869
874
  "# ========================================",
870
875
  "# Environment Variables",
@@ -884,7 +889,7 @@ async function generateEnvExample(features, config, targetPath) {
884
889
  "# ========================================",
885
890
  "# Database Configuration",
886
891
  "# ========================================",
887
- "DATABASE_URL=mysql://root:root123456@localhost:3306/{{PROJECT_NAME}}",
892
+ `DATABASE_URL=${databaseUrls[database] || databaseUrls.mysql}`,
888
893
  ""
889
894
  ];
890
895
  const featureGroups = {};
@@ -1011,7 +1016,7 @@ ${featuresList}
1011
1016
  await import_fs_extra5.default.writeFile(indexPath, content);
1012
1017
  logger.info("Generated capabilities index");
1013
1018
  }
1014
- async function copyPrismaTemplates(templateDir, targetPath) {
1019
+ async function copyPrismaTemplates(templateDir, targetPath, database = "mysql") {
1015
1020
  const prismaTemplatesDir = import_path3.default.join(templateDir, "apps/backend/prisma");
1016
1021
  const prismaDestDir = import_path3.default.join(targetPath, "apps/backend/prisma");
1017
1022
  if (await import_fs_extra5.default.pathExists(prismaTemplatesDir)) {
@@ -1022,10 +1027,13 @@ async function copyPrismaTemplates(templateDir, targetPath) {
1022
1027
  if (file.endsWith(".tpl")) {
1023
1028
  const filePath = import_path3.default.join(prismaDestDir, file);
1024
1029
  const newPath = filePath.replace(/\.tpl$/, "");
1025
- await import_fs_extra5.default.rename(filePath, newPath);
1030
+ let content = await import_fs_extra5.default.readFile(filePath, "utf-8");
1031
+ content = content.replace(/provider\s*=\s*"postgresql"/, `provider = "${database}"`);
1032
+ await import_fs_extra5.default.writeFile(newPath, content);
1033
+ await import_fs_extra5.default.remove(filePath);
1026
1034
  }
1027
1035
  }
1028
- logger.info("Copied Prisma templates");
1036
+ logger.info(`Copied Prisma templates with ${database} database`);
1029
1037
  } else {
1030
1038
  logger.warn(`Prisma templates not found: ${prismaTemplatesDir}`);
1031
1039
  }
@@ -1217,6 +1225,8 @@ async function createProject(projectName, options = {}) {
1217
1225
  answers = {
1218
1226
  org: options.org || projectName,
1219
1227
  template: options.template || "full-stack",
1228
+ database: "mysql",
1229
+ // 默认使用 MySQL
1220
1230
  features: [],
1221
1231
  // 默认不选择额外功能
1222
1232
  packageManager: options.packageManager || "pnpm",
@@ -1247,6 +1257,18 @@ async function createProject(projectName, options = {}) {
1247
1257
  ],
1248
1258
  default: options.template || "full-stack"
1249
1259
  },
1260
+ {
1261
+ type: "list",
1262
+ name: "database",
1263
+ message: "Choose a database:",
1264
+ choices: [
1265
+ { name: "MySQL", value: "mysql" },
1266
+ { name: "PostgreSQL", value: "postgresql" },
1267
+ { name: "SQLite", value: "sqlite" }
1268
+ ],
1269
+ default: "mysql",
1270
+ when: (answers2) => answers2.template === "backend-only" || answers2.template === "full-stack"
1271
+ },
1250
1272
  {
1251
1273
  type: "checkbox",
1252
1274
  name: "features",
@@ -1279,6 +1301,7 @@ async function createProject(projectName, options = {}) {
1279
1301
  projectName,
1280
1302
  orgName: answers.org.startsWith("@") ? answers.org : `@${answers.org}`,
1281
1303
  template: answers.template,
1304
+ database: answers.database || "mysql",
1282
1305
  features: answers.features || [],
1283
1306
  packageManager: answers.packageManager,
1284
1307
  installDeps: answers.installDeps,
@@ -1290,6 +1313,9 @@ async function createProject(projectName, options = {}) {
1290
1313
  logger.info(` Project Name: ${import_chalk2.default.white(config.projectName)}`);
1291
1314
  logger.info(` Organization: ${import_chalk2.default.white(config.orgName)}`);
1292
1315
  logger.info(` Template: ${import_chalk2.default.white(config.template)}`);
1316
+ if (config.template === "backend-only" || config.template === "full-stack") {
1317
+ logger.info(` Database: ${import_chalk2.default.white(config.database)}`);
1318
+ }
1293
1319
  if (config.features.length > 0) {
1294
1320
  logger.info(` Features: ${import_chalk2.default.white(config.features.join(", "))}`);
1295
1321
  }
@@ -1374,9 +1400,9 @@ async function createProjectFromTemplate(config) {
1374
1400
  await copyExampleFiles(config.features, featuresConfig, templateDir, config.projectPath);
1375
1401
  await copySkillFiles(config.features, featuresConfig, templateDir, config.projectPath);
1376
1402
  if (config.template === "backend-only" || config.template === "full-stack") {
1377
- await copyPrismaTemplates(templateDir, config.projectPath);
1403
+ await copyPrismaTemplates(templateDir, config.projectPath, config.database);
1378
1404
  }
1379
- await generateEnvExample(config.features, featuresConfig, config.projectPath);
1405
+ await generateEnvExample(config.features, featuresConfig, config.projectPath, config.database);
1380
1406
  if (config.template === "backend-only" || config.template === "full-stack") {
1381
1407
  await updateAppModule(config.features, featuresConfig, config.projectPath);
1382
1408
  }
@@ -1384,6 +1410,19 @@ async function createProjectFromTemplate(config) {
1384
1410
  if (config.installDeps) {
1385
1411
  spinner.text = "Installing dependencies...";
1386
1412
  await installDependencies(config.packageManager);
1413
+ if (config.template === "backend-only" || config.template === "full-stack") {
1414
+ spinner.text = "Generating Prisma client...";
1415
+ try {
1416
+ const { execSync: execSync4 } = require("child_process");
1417
+ execSync4(`${config.packageManager} --filter=backend prisma:generate`, {
1418
+ cwd: config.projectPath,
1419
+ stdio: "inherit"
1420
+ });
1421
+ logger.info("Prisma client generated successfully");
1422
+ } catch (error) {
1423
+ logger.warn('Failed to generate Prisma client. Please run "pnpm --filter=backend prisma:generate" manually.');
1424
+ }
1425
+ }
1387
1426
  }
1388
1427
  if (config.initGit) {
1389
1428
  spinner.text = "Initializing Git repository...";
@@ -1401,7 +1440,7 @@ async function createProjectFromTemplate(config) {
1401
1440
  }
1402
1441
 
1403
1442
  // package.json
1404
- var version = "2.0.0";
1443
+ var version = "2.1.0";
1405
1444
 
1406
1445
  // src/index.ts
1407
1446
  async function cli() {
package/dist/index.mjs CHANGED
@@ -697,11 +697,16 @@ function collectEnvVars(features, config) {
697
697
  }
698
698
  return envVars;
699
699
  }
700
- async function generateEnvExample(features, config, targetPath) {
700
+ async function generateEnvExample(features, config, targetPath, database = "mysql") {
701
701
  const envVars = collectEnvVars(features, config);
702
702
  if (envVars.length === 0) {
703
703
  return;
704
704
  }
705
+ const databaseUrls = {
706
+ mysql: "mysql://root:root123456@localhost:3306/{{PROJECT_NAME}}",
707
+ postgresql: "postgresql://postgres:postgres@localhost:5432/{{PROJECT_NAME}}",
708
+ sqlite: "file:./dev.db"
709
+ };
705
710
  const content = [
706
711
  "# ========================================",
707
712
  "# Environment Variables",
@@ -721,7 +726,7 @@ async function generateEnvExample(features, config, targetPath) {
721
726
  "# ========================================",
722
727
  "# Database Configuration",
723
728
  "# ========================================",
724
- "DATABASE_URL=mysql://root:root123456@localhost:3306/{{PROJECT_NAME}}",
729
+ `DATABASE_URL=${databaseUrls[database] || databaseUrls.mysql}`,
725
730
  ""
726
731
  ];
727
732
  const featureGroups = {};
@@ -848,7 +853,7 @@ ${featuresList}
848
853
  await fs4.writeFile(indexPath, content);
849
854
  logger.info("Generated capabilities index");
850
855
  }
851
- async function copyPrismaTemplates(templateDir, targetPath) {
856
+ async function copyPrismaTemplates(templateDir, targetPath, database = "mysql") {
852
857
  const prismaTemplatesDir = path3.join(templateDir, "apps/backend/prisma");
853
858
  const prismaDestDir = path3.join(targetPath, "apps/backend/prisma");
854
859
  if (await fs4.pathExists(prismaTemplatesDir)) {
@@ -859,10 +864,13 @@ async function copyPrismaTemplates(templateDir, targetPath) {
859
864
  if (file.endsWith(".tpl")) {
860
865
  const filePath = path3.join(prismaDestDir, file);
861
866
  const newPath = filePath.replace(/\.tpl$/, "");
862
- await fs4.rename(filePath, newPath);
867
+ let content = await fs4.readFile(filePath, "utf-8");
868
+ content = content.replace(/provider\s*=\s*"postgresql"/, `provider = "${database}"`);
869
+ await fs4.writeFile(newPath, content);
870
+ await fs4.remove(filePath);
863
871
  }
864
872
  }
865
- logger.info("Copied Prisma templates");
873
+ logger.info(`Copied Prisma templates with ${database} database`);
866
874
  } else {
867
875
  logger.warn(`Prisma templates not found: ${prismaTemplatesDir}`);
868
876
  }
@@ -1054,6 +1062,8 @@ async function createProject(projectName, options = {}) {
1054
1062
  answers = {
1055
1063
  org: options.org || projectName,
1056
1064
  template: options.template || "full-stack",
1065
+ database: "mysql",
1066
+ // 默认使用 MySQL
1057
1067
  features: [],
1058
1068
  // 默认不选择额外功能
1059
1069
  packageManager: options.packageManager || "pnpm",
@@ -1084,6 +1094,18 @@ async function createProject(projectName, options = {}) {
1084
1094
  ],
1085
1095
  default: options.template || "full-stack"
1086
1096
  },
1097
+ {
1098
+ type: "list",
1099
+ name: "database",
1100
+ message: "Choose a database:",
1101
+ choices: [
1102
+ { name: "MySQL", value: "mysql" },
1103
+ { name: "PostgreSQL", value: "postgresql" },
1104
+ { name: "SQLite", value: "sqlite" }
1105
+ ],
1106
+ default: "mysql",
1107
+ when: (answers2) => answers2.template === "backend-only" || answers2.template === "full-stack"
1108
+ },
1087
1109
  {
1088
1110
  type: "checkbox",
1089
1111
  name: "features",
@@ -1116,6 +1138,7 @@ async function createProject(projectName, options = {}) {
1116
1138
  projectName,
1117
1139
  orgName: answers.org.startsWith("@") ? answers.org : `@${answers.org}`,
1118
1140
  template: answers.template,
1141
+ database: answers.database || "mysql",
1119
1142
  features: answers.features || [],
1120
1143
  packageManager: answers.packageManager,
1121
1144
  installDeps: answers.installDeps,
@@ -1127,6 +1150,9 @@ async function createProject(projectName, options = {}) {
1127
1150
  logger.info(` Project Name: ${chalk2.white(config.projectName)}`);
1128
1151
  logger.info(` Organization: ${chalk2.white(config.orgName)}`);
1129
1152
  logger.info(` Template: ${chalk2.white(config.template)}`);
1153
+ if (config.template === "backend-only" || config.template === "full-stack") {
1154
+ logger.info(` Database: ${chalk2.white(config.database)}`);
1155
+ }
1130
1156
  if (config.features.length > 0) {
1131
1157
  logger.info(` Features: ${chalk2.white(config.features.join(", "))}`);
1132
1158
  }
@@ -1211,9 +1237,9 @@ async function createProjectFromTemplate(config) {
1211
1237
  await copyExampleFiles(config.features, featuresConfig, templateDir, config.projectPath);
1212
1238
  await copySkillFiles(config.features, featuresConfig, templateDir, config.projectPath);
1213
1239
  if (config.template === "backend-only" || config.template === "full-stack") {
1214
- await copyPrismaTemplates(templateDir, config.projectPath);
1240
+ await copyPrismaTemplates(templateDir, config.projectPath, config.database);
1215
1241
  }
1216
- await generateEnvExample(config.features, featuresConfig, config.projectPath);
1242
+ await generateEnvExample(config.features, featuresConfig, config.projectPath, config.database);
1217
1243
  if (config.template === "backend-only" || config.template === "full-stack") {
1218
1244
  await updateAppModule(config.features, featuresConfig, config.projectPath);
1219
1245
  }
@@ -1221,6 +1247,19 @@ async function createProjectFromTemplate(config) {
1221
1247
  if (config.installDeps) {
1222
1248
  spinner.text = "Installing dependencies...";
1223
1249
  await installDependencies(config.packageManager);
1250
+ if (config.template === "backend-only" || config.template === "full-stack") {
1251
+ spinner.text = "Generating Prisma client...";
1252
+ try {
1253
+ const { execSync: execSync4 } = __require("child_process");
1254
+ execSync4(`${config.packageManager} --filter=backend prisma:generate`, {
1255
+ cwd: config.projectPath,
1256
+ stdio: "inherit"
1257
+ });
1258
+ logger.info("Prisma client generated successfully");
1259
+ } catch (error) {
1260
+ logger.warn('Failed to generate Prisma client. Please run "pnpm --filter=backend prisma:generate" manually.');
1261
+ }
1262
+ }
1224
1263
  }
1225
1264
  if (config.initGit) {
1226
1265
  spinner.text = "Initializing Git repository...";
@@ -1238,7 +1277,7 @@ async function createProjectFromTemplate(config) {
1238
1277
  }
1239
1278
 
1240
1279
  // package.json
1241
- var version = "2.0.0";
1280
+ var version = "2.1.0";
1242
1281
 
1243
1282
  // src/index.ts
1244
1283
  async function cli() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@svton/cli",
3
- "version": "2.0.0",
3
+ "version": "2.1.0",
4
4
  "description": "Svton CLI - Create full-stack applications with NestJS, Next.js, and Taro",
5
5
  "keywords": [
6
6
  "cli",