@mindbase/cli 1.0.1 → 1.0.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.
Binary file
Binary file
Binary file
Binary file
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  init
4
- } from "../chunk-375GNKXH.js";
4
+ } from "../chunk-QQREALNB.js";
5
5
 
6
6
  // src/bin/mindbase.ts
7
7
  var args = process.argv.slice(2);
@@ -12,12 +12,6 @@ async function main() {
12
12
  case "init":
13
13
  await init(type);
14
14
  break;
15
- case "precache":
16
- console.log("\n\u63D0\u793A: precache \u547D\u4EE4\u9700\u8981\u4ECE @mindbase/express-common \u4E2D\u4F7F\u7528");
17
- console.log(`\u8BF7\u5728\u9879\u76EE\u4E2D\u8FD0\u884C: node -e "require('@mindbase/express-common').precache()"`);
18
- console.log(`\u6216\u5728 package.json \u4E2D\u6DFB\u52A0: "precache": "node -e 'require(\\"@mindbase/express-common\\").precache()'"
19
- `);
20
- break;
21
15
  default:
22
16
  showHelp();
23
17
  break;
@@ -29,17 +23,14 @@ function showHelp() {
29
23
 
30
24
  \u547D\u4EE4:
31
25
  init [type] \u521D\u59CB\u5316\u65B0\u9879\u76EE
32
- backend \u521D\u59CB\u5316\u540E\u7AEF\u9879\u76EE
33
- frontend \u521D\u59CB\u5316\u524D\u7AEF\u9879\u76EE
34
- admin \u5FEB\u6377\uFF1A\u521D\u59CB\u5316\u5B8C\u6574\u7BA1\u7406\u540E\u53F0\uFF08\u524D\u540E\u7AEF\u4E00\u4F53\uFF09
35
-
36
- precache \u9884\u751F\u6210\u7F13\u5B58\uFF08\u63D0\u5347\u542F\u52A8\u901F\u5EA6\uFF09
26
+ backend \u540E\u7AEF\u9879\u76EE
27
+ frontend \u524D\u7AEF\u9879\u76EE
28
+ admin \u7BA1\u7406\u540E\u53F0\u524D\u540E\u7AEF
37
29
 
38
30
  \u793A\u4F8B:
39
31
  mindbase init backend # \u4EA4\u4E92\u5F0F\u9009\u62E9\u540E\u7AEF\u6A21\u5757
40
32
  mindbase init frontend # \u4EA4\u4E92\u5F0F\u9009\u62E9\u524D\u7AEF\u5E94\u7528\u5F62\u6001
41
33
  mindbase init admin # \u4E00\u952E\u521D\u59CB\u5316\u5B8C\u6574\u7BA1\u7406\u540E\u53F0
42
- mindbase precache # \u9884\u751F\u6210\u7F13\u5B58
43
34
  `);
44
35
  }
45
36
  main().catch((err) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/bin/mindbase.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { init } from \"../commands/init\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\nconst type = args[1];\n\nasync function main() {\n switch (command) {\n case \"init\":\n await init(type);\n break;\n case \"precache\":\n console.log(\"\\n提示: precache 命令需要从 @mindbase/express-common 中使用\");\n console.log(\"请在项目中运行: node -e \\\"require('@mindbase/express-common').precache()\\\"\");\n console.log(\"或在 package.json 中添加: \\\"precache\\\": \\\"node -e 'require(\\\\\\\"@mindbase/express-common\\\\\\\").precache()'\\\"\\n\");\n break;\n default:\n showHelp();\n break;\n }\n}\n\nfunction showHelp() {\n console.log(`\n用法: mindbase <command> [type]\n\n命令:\n init [type] 初始化新项目\n backend 初始化后端项目\n frontend 初始化前端项目\n admin 快捷:初始化完整管理后台(前后端一体)\n\n precache 预生成缓存(提升启动速度)\n\n示例:\n mindbase init backend # 交互式选择后端模块\n mindbase init frontend # 交互式选择前端应用形态\n mindbase init admin # 一键初始化完整管理后台\n mindbase precache # 预生成缓存\n `);\n}\n\nmain().catch((err) => {\n console.error(\"❌ 执行失败:\", err);\n process.exit(1);\n});\n"],"mappings":";;;;;;AAGA,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,UAAU,KAAK,CAAC;AACtB,IAAM,OAAO,KAAK,CAAC;AAEnB,eAAe,OAAO;AACpB,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,YAAM,KAAK,IAAI;AACf;AAAA,IACF,KAAK;AACH,cAAQ,IAAI,qGAAmD;AAC/D,cAAQ,IAAI,sGAAqE;AACjF,cAAQ,IAAI;AAAA,CAAyG;AACrH;AAAA,IACF;AACE,eAAS;AACT;AAAA,EACJ;AACF;AAEA,SAAS,WAAW;AAClB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAgBX;AACH;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,oCAAW,GAAG;AAC5B,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/bin/mindbase.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { init } from \"../commands/init\";\n\nconst args = process.argv.slice(2);\nconst command = args[0];\nconst type = args[1];\n\nasync function main() {\n switch (command) {\n case \"init\":\n await init(type);\n break;\n default:\n showHelp();\n break;\n }\n}\n\nfunction showHelp() {\n console.log(`\n用法: mindbase <command> [type]\n\n命令:\n init [type] 初始化新项目\n backend 后端项目\n frontend 前端项目\n admin 管理后台前后端\n\n示例:\n mindbase init backend # 交互式选择后端模块\n mindbase init frontend # 交互式选择前端应用形态\n mindbase init admin # 一键初始化完整管理后台\n `);\n}\n\nmain().catch((err) => {\n console.error(\"❌ 执行失败:\", err);\n process.exit(1);\n});\n"],"mappings":";;;;;;AAGA,IAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;AACjC,IAAM,UAAU,KAAK,CAAC;AACtB,IAAM,OAAO,KAAK,CAAC;AAEnB,eAAe,OAAO;AACpB,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,YAAM,KAAK,IAAI;AACf;AAAA,IACF;AACE,eAAS;AACT;AAAA,EACJ;AACF;AAEA,SAAS,WAAW;AAClB,UAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAaX;AACH;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,oCAAW,GAAG;AAC5B,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
@@ -165,35 +165,24 @@ var Logger_default = logger;
165
165
  // src/utils/prompts.ts
166
166
  var BACKEND_MODULES = [
167
167
  { name: "auth", required: true, description: "\u8BA4\u8BC1\u6743\u9650", package: "@mindbase/express-auth" },
168
- { name: "admin", dependencies: ["auth"], description: "\u7528\u6237\u7BA1\u7406", package: "@mindbase/express-admin" },
169
- { name: "storage", dependencies: ["auth", "kv"], description: "\u5B58\u50A8", package: "@mindbase/express-storage" },
170
168
  { name: "kv", description: "\u952E\u503C\u5B58\u50A8", package: "@mindbase/express-kv" },
171
- { name: "explorer", description: "\u78C1\u76D8\u6D4F\u89C8", package: "@mindbase/express-explorer" },
169
+ { name: "admin", dependencies: ["auth"], description: "\u7528\u6237\u7BA1\u7406", package: "@mindbase/express-admin" },
170
+ { name: "storage", dependencies: ["auth", "kv"], description: "\u6587\u4EF6\u5B58\u50A8", package: "@mindbase/express-storage" },
171
+ { name: "explorer", description: "\u6587\u4EF6\u7BA1\u7406", package: "@mindbase/express-explorer" },
172
172
  { name: "knowledge", dependencies: ["auth"], description: "\u77E5\u8BC6\u5E93", package: "@mindbase/express-knowledge" },
173
- { name: "command-runner", description: "\u5B9A\u65F6\u4EFB\u52A1", package: "@mindbase/express-command-runner" }
173
+ { name: "commandRunner", description: "\u547D\u4EE4\u7BA1\u7406", package: "@mindbase/express-command-runner" }
174
174
  ];
175
175
  var FRONTEND_APP_TYPES = [
176
176
  {
177
177
  name: "admin-app",
178
178
  description: "\u7BA1\u7406\u540E\u53F0 - \u5B8C\u6574\u7684\u7BA1\u7406\u754C\u9762",
179
179
  package: "@mindbase/vue3-admin-app",
180
- available: true
181
- },
182
- {
183
- name: "custom-app",
184
- description: "\u5BA2\u6237\u7AEF\u5E94\u7528 - \u9762\u5411\u7EC8\u7AEF\u7528\u6237",
185
- package: "@mindbase/vue3-custom-app",
186
- available: false
187
- },
188
- {
189
- name: "mobile-app",
190
- description: "\u79FB\u52A8\u7AEF\u5E94\u7528",
191
- package: "@mindbase/vue3-mobile-app",
192
- available: false
180
+ available: true,
181
+ dependencies: ["@mindbase/vue3-auth", "@mindbase/vue3-kv", "@mindbase/vue3-client"]
193
182
  }
194
183
  ];
195
184
  function resolveDependencies(selectedModules) {
196
- const result = /* @__PURE__ */ new Set();
185
+ const result = /* @__PURE__ */ new Map();
197
186
  function addModule(name) {
198
187
  if (result.has(name)) return;
199
188
  const module = BACKEND_MODULES.find((m) => m.name === name);
@@ -203,16 +192,12 @@ function resolveDependencies(selectedModules) {
203
192
  addModule(dep);
204
193
  }
205
194
  }
206
- result.add(name);
195
+ result.set(module.name, module);
207
196
  }
208
197
  for (const name of selectedModules) {
209
198
  addModule(name);
210
199
  }
211
- return Array.from(result);
212
- }
213
- function getModulePackage(moduleName) {
214
- const module = BACKEND_MODULES.find((m) => m.name === moduleName);
215
- return module?.package;
200
+ return Array.from(result.values());
216
201
  }
217
202
  function getFrontendPackage(appType) {
218
203
  const app = FRONTEND_APP_TYPES.find((a) => a.name === appType);
@@ -221,6 +206,36 @@ function getFrontendPackage(appType) {
221
206
  function getAvailableFrontendApps() {
222
207
  return FRONTEND_APP_TYPES.filter((app) => app.available);
223
208
  }
209
+ var KNOWN_PACKAGE_DEPS = {
210
+ "@mindbase/vue3-auth": ["@mindbase/vue3-kit", "@mindbase/vue3-client"],
211
+ "@mindbase/vue3-kv": ["@mindbase/vue3-kit", "@mindbase/vue3-client"],
212
+ "@mindbase/vue3-storage": ["@mindbase/vue3-kit", "@mindbase/vue3-client", "spark-md5"],
213
+ "@mindbase/vue3-command": ["@mindbase/vue3-kit", "@mindbase/vue3-client"],
214
+ "@mindbase/vue3-explorer": ["@mindbase/vue3-kit", "@mindbase/vue3-client"]
215
+ };
216
+ function resolveFrontendDependencies(appType) {
217
+ const packages = /* @__PURE__ */ new Set();
218
+ function addPackage(packageName) {
219
+ if (packages.has(packageName)) return;
220
+ packages.add(packageName);
221
+ const app2 = FRONTEND_APP_TYPES.find((a) => a.package === packageName);
222
+ if (app2?.dependencies) {
223
+ for (const dep of app2.dependencies) {
224
+ addPackage(dep);
225
+ }
226
+ }
227
+ if (KNOWN_PACKAGE_DEPS[packageName]) {
228
+ for (const dep of KNOWN_PACKAGE_DEPS[packageName]) {
229
+ addPackage(dep);
230
+ }
231
+ }
232
+ }
233
+ const app = FRONTEND_APP_TYPES.find((a) => a.name === appType);
234
+ if (app) {
235
+ addPackage(app.package);
236
+ }
237
+ return Array.from(packages);
238
+ }
224
239
 
225
240
  // src/utils/BackendInitializer.ts
226
241
  import fs from "fs";
@@ -249,11 +264,17 @@ async function collectBackendConfig(cwd) {
249
264
  initial: ""
250
265
  },
251
266
  {
252
- type: "number",
267
+ type: "text",
253
268
  name: "port",
254
269
  message: "\u670D\u52A1\u7AEF\u53E3",
255
- initial: 3e3,
256
- validate: (value) => value >= 1 && value <= 65535 ? true : "\u7AEF\u53E3\u53F7\u5FC5\u987B\u5728 1-65535 \u4E4B\u95F4"
270
+ initial: "3000",
271
+ validate: (value) => {
272
+ const val = typeof value === "number" ? value : parseInt(value, 10);
273
+ if (isNaN(val) || val < 1 || val > 65535) {
274
+ return "\u7AEF\u53E3\u53F7\u5FC5\u987B\u4E3A\u5728 1-65535 \u4E4B\u95F4\u7684\u6570\u5B57";
275
+ }
276
+ return true;
277
+ }
257
278
  },
258
279
  {
259
280
  type: "text",
@@ -264,12 +285,14 @@ async function collectBackendConfig(cwd) {
264
285
  {
265
286
  type: "text",
266
287
  name: "staticPath",
267
- message: "\u9759\u6001\u76EE\u5F55\u8DEF\u5F84 (\u7559\u7A7A\u5219\u4E0D\u521B\u5EFA\uFF0C\u4F8B\u5982: public)"
288
+ message: "\u9759\u6001\u76EE\u5F55\u8DEF\u5F84 (\u7559\u7A7A\u5219\u4E0D\u521B\u5EFA\uFF0C\u4F8B\u5982: public)",
289
+ initial: "public"
268
290
  },
269
291
  {
270
292
  type: "text",
271
293
  name: "apiPrefix",
272
- message: "API \u524D\u7F00 (\u7559\u7A7A\u5219\u65E0\u524D\u7F00\uFF0C\u4F8B\u5982: /api)"
294
+ message: "API \u524D\u7F00 (\u7559\u7A7A\u5219\u65E0\u524D\u7F00\uFF0C\u4F8B\u5982: /api)",
295
+ initial: "/api"
273
296
  },
274
297
  {
275
298
  type: "confirm",
@@ -318,7 +341,7 @@ async function collectBackendConfig(cwd) {
318
341
  }
319
342
  const selectedModules = response.modules;
320
343
  const allModules = resolveDependencies(selectedModules);
321
- Logger_default.info(`\u5DF2\u9009\u62E9\u7684\u6A21\u5757: ${allModules.join(", ")}`);
344
+ Logger_default.info(`\u5DF2\u9009\u62E9\u7684\u6A21\u5757: ${allModules.map((item) => item.name).join(", ")}`);
322
345
  return { ...response, modules: allModules };
323
346
  }
324
347
  function setupBackendPackageJson(cwd, config) {
@@ -333,9 +356,29 @@ function setupBackendPackageJson(cwd, config) {
333
356
  version: "1.0.0",
334
357
  description: config.description,
335
358
  author: config.author,
336
- main: "dist/index.js",
337
359
  scripts: {},
338
- dependencies: {},
360
+ dependencies: {
361
+ "art-template": "^4.13.4",
362
+ "better-sqlite3": "^11.10.0",
363
+ "cookie-parser": "^1.4.7",
364
+ cron: "^3.1.9",
365
+ dayjs: "^1.11.13",
366
+ "drizzle-orm": "^0.44.7",
367
+ "drizzle-zod": "^0.5.0",
368
+ express: "^5.2.1",
369
+ "express-art-template": "^1.0.1",
370
+ "fs-extra": "^11.2.0",
371
+ glob: "^10.0.0",
372
+ "ipip-ipdb": "^0.6.0",
373
+ "mime-types": "^2.1.35",
374
+ multer: "^1.4.5-lts.1",
375
+ radash: "12.1.1",
376
+ "ts-morph": "^27.0.0",
377
+ "ua-parser-js": "^2.0.0",
378
+ uuid: "^10.0.0",
379
+ xss: "^1.0.14",
380
+ zod: "^3.24.0"
381
+ },
339
382
  devDependencies: {
340
383
  "@types/express": "^5.0.6",
341
384
  "@types/node": "^20.0.0",
@@ -343,26 +386,31 @@ function setupBackendPackageJson(cwd, config) {
343
386
  "ts-node-dev": "^2.0.0",
344
387
  typescript: "^5.1.3",
345
388
  "tsconfig-paths": "^4.2.0",
346
- "drizzle-kit": "^0.31.7"
389
+ "drizzle-kit": "^0.31.7",
390
+ "@types/better-sqlite3": "^7.6.11",
391
+ "@types/fs-extra": "^11.0.4",
392
+ "@types/multer": "^1.4.11",
393
+ "@types/prompts": "^2.4.9",
394
+ "@types/uuid": "^10.0.0"
347
395
  }
348
396
  };
349
397
  Logger_default.info("\u2713 \u6B63\u5728\u751F\u6210 package.json...");
350
398
  }
351
399
  pkg.scripts = pkg.scripts || {};
352
- pkg.scripts["dev"] = "ts-node-dev --transpile-only --require tsconfig-paths/register ./src/app.ts";
353
- pkg.scripts["start"] = "ts-node --transpile-only --require tsconfig-paths/register ./src/app.ts";
400
+ pkg.scripts["dev"] = "tsx --watch --tsconfig-paths ./src/app.ts";
401
+ pkg.scripts["start"] = "tsx --tsconfig-paths ./src/app.ts";
354
402
  pkg.scripts["prepare"] = "node prepare.js";
355
- pkg.scripts["init-admin"] = "npm run prepare && mindbase-auth init-admin";
356
- pkg.scripts["db:push"] = "drizzle-kit push";
403
+ pkg.scripts["init-admin"] = "mindbase-auth init-admin";
357
404
  pkg.scripts["db:generate"] = "drizzle-kit generate";
358
405
  pkg.scripts["db:migrate"] = "drizzle-kit migrate";
359
- pkg.scripts["db"] = "npm run prepare && npm run db:generate && npm run db:migrate";
406
+ pkg.scripts["init"] = "npm run prepare && npm run db:generate && npm run db:migrate && npm run init-admin";
407
+ pkg.scripts["db:push"] = "drizzle-kit push";
360
408
  pkg.scripts["db:studio"] = "drizzle-kit studio";
361
- pkg.dependencies["@mindbase/express-common"] = "*";
362
- for (const moduleName of config.modules) {
363
- const packageName = getModulePackage(moduleName);
409
+ pkg.dependencies["@mindbase/express-common"] = "^1.0.0";
410
+ for (const module of config.modules) {
411
+ const packageName = module.package;
364
412
  if (packageName) {
365
- pkg.dependencies[packageName] = "*";
413
+ pkg.dependencies[packageName] = "^1.0.0";
366
414
  }
367
415
  }
368
416
  pkg.dependencies["express"] = "^5.2.1";
@@ -452,17 +500,18 @@ function setupTsConfig(cwd) {
452
500
  Logger_default.info("\u2713 tsconfig.json \u5DF2\u5C31\u7EEA");
453
501
  }
454
502
  }
455
- function setupAppEntry(cwd) {
503
+ function setupAppEntry(cwd, config) {
456
504
  const appPath = path2.join(cwd, "src/app.ts");
457
505
  if (!fs.existsSync(appPath)) {
458
506
  const appContent = `import { createApp } from "@mindbase/express-common";
507
+ ${config.modules.map((module) => "import " + module.name + ' from "' + module.package + '";').join("\n")}
459
508
  import config from "./config";
460
509
 
461
510
  async function bootstrap() {
462
511
  const app = await createApp(config);
463
512
 
464
513
  // \u5728\u6B64\u5904\u4F7F\u7528\u63D2\u4EF6\u6216\u4E2D\u95F4\u4EF6
465
- // app.use(...);
514
+ ${config.modules.map(({ name }) => " app.use(" + name + ")").join("\n")}
466
515
 
467
516
  await app.startup();
468
517
  }
@@ -476,7 +525,7 @@ bootstrap();
476
525
  }
477
526
  function copyAssets(cwd) {
478
527
  const ipdbPath = path2.join(cwd, "ipipfree.ipdb");
479
- const sourceIpdb = path2.join(__dirname, "..", "..", "..", "common", "ipipfree.ipdb");
528
+ const sourceIpdb = path2.join(__dirname, "..", "assets", "ipipfree.ipdb");
480
529
  if (fs.existsSync(sourceIpdb)) {
481
530
  if (!fs.existsSync(ipdbPath)) {
482
531
  fs.copyFileSync(sourceIpdb, ipdbPath);
@@ -545,11 +594,17 @@ async function collectFrontendConfig(cwd) {
545
594
  initial: ""
546
595
  },
547
596
  {
548
- type: "number",
597
+ type: "text",
549
598
  name: "port",
550
599
  message: "\u5F00\u53D1\u670D\u52A1\u5668\u7AEF\u53E3",
551
- initial: 5173,
552
- validate: (value) => value >= 1 && value <= 65535 ? true : "\u7AEF\u53E3\u53F7\u5FC5\u987B\u5728 1-65535 \u4E4B\u95F4"
600
+ initial: "5173",
601
+ validate: (value) => {
602
+ const val = typeof value === "number" ? value : parseInt(value, 10);
603
+ if (isNaN(val) || val < 1 || val > 65535) {
604
+ return "\u7AEF\u53E3\u53F7\u5FC5\u987B\u4E3A\u5728 1-65535 \u4E4B\u95F4\u7684\u6570\u5B57";
605
+ }
606
+ return true;
607
+ }
553
608
  },
554
609
  {
555
610
  type: "text",
@@ -593,7 +648,25 @@ function setupFrontendPackageJson(cwd, config) {
593
648
  description: config.description,
594
649
  author: config.author,
595
650
  private: true,
596
- type: "module"
651
+ type: "module",
652
+ dependencies: {
653
+ axios: "^1.7.0",
654
+ "crypto-js": "^4.2.0",
655
+ dayjs: "^1.11.19",
656
+ "element-plus": "^2.9.0",
657
+ "element-plus/icons-vue": "^2.9.0",
658
+ "lodash-es": "^4.17.21",
659
+ pinia: "^2.2.0",
660
+ "spark-md5": "^3.0.2",
661
+ vue: "^3.5.0",
662
+ "vue-router": "^4.5.0"
663
+ },
664
+ devDependencies: {
665
+ "@vitejs/plugin-vue": "^5.2.0",
666
+ typescript: "^5.6.0",
667
+ vite: "^6.0.0",
668
+ "vue-tsc": "^2.2.0"
669
+ }
597
670
  };
598
671
  Logger_default.info("\u2713 \u6B63\u5728\u751F\u6210 package.json...");
599
672
  }
@@ -602,10 +675,10 @@ function setupFrontendPackageJson(cwd, config) {
602
675
  pkg.scripts["dev"] = `vite --port ${config.port}`;
603
676
  pkg.scripts["build"] = "vue-tsc -b && vite build";
604
677
  pkg.scripts["preview"] = "vite preview";
605
- const appPackage = getFrontendPackage(config.appType);
606
- if (appPackage) {
678
+ const allPackages = resolveFrontendDependencies(config.appType);
679
+ for (const packageName of allPackages) {
607
680
  pkg.dependencies = pkg.dependencies || {};
608
- pkg.dependencies[appPackage] = "*";
681
+ pkg.dependencies[packageName] = "^1.0.0";
609
682
  }
610
683
  pkg.devDependencies = pkg.devDependencies || {};
611
684
  pkg.devDependencies["vue-tsc"] = "^2.2.0";
@@ -620,9 +693,17 @@ function setupViteConfig(cwd, config) {
620
693
  changeOrigin: true,
621
694
  },
622
695
  }` : "undefined";
623
- const viteConfigContent = `import { createBaseConfig } from "@mindbase/vite";
696
+ const viteConfigContent = `import { defineConfig } from "vite";
697
+ import vue from "@vitejs/plugin-vue";
698
+ import path from "path";
624
699
 
625
- export default createBaseConfig({
700
+ export default defineConfig({
701
+ plugins: [vue()],
702
+ resolve: {
703
+ alias: {
704
+ "@": path.resolve(__dirname, "./src"),
705
+ },
706
+ },
626
707
  server: {
627
708
  port: ${config.port},
628
709
  proxy: ${proxyConfig},
@@ -636,31 +717,24 @@ function setupFrontendTsConfig(cwd) {
636
717
  const tsconfigPath = path3.join(cwd, "tsconfig.json");
637
718
  if (!fs2.existsSync(tsconfigPath)) {
638
719
  const tsconfigContent = {
639
- extends: "../../tsconfig.base.json",
640
- compilerOptions: {
641
- baseUrl: "."
642
- },
643
- include: ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"]
644
- };
645
- fs2.writeFileSync(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));
646
- Logger_default.info("\u2713 tsconfig.json \u5DF2\u5C31\u7EEA");
647
- }
648
- const tsconfigNodePath = path3.join(cwd, "tsconfig.node.json");
649
- if (!fs2.existsSync(tsconfigNodePath)) {
650
- const tsconfigNodeContent = {
651
720
  compilerOptions: {
652
- composite: true,
653
- skipLibCheck: true,
721
+ target: "ES2022",
654
722
  module: "ESNext",
655
723
  moduleResolution: "bundler",
656
- allowSyntheticDefaultImports: true,
657
724
  strict: true,
658
- noEmit: true
725
+ esModuleInterop: true,
726
+ skipLibCheck: true,
727
+ forceConsistentCasingInFileNames: true,
728
+ resolveJsonModule: true,
729
+ isolatedModules: true,
730
+ noEmit: true,
731
+ lib: ["ES2022", "DOM", "DOM.Iterable"],
732
+ types: ["vite/client"]
659
733
  },
660
- include: ["vite.config.ts"]
734
+ include: ["src/**/*.ts", "src/**/*.vue", "vite.config.ts"]
661
735
  };
662
- fs2.writeFileSync(tsconfigNodePath, JSON.stringify(tsconfigNodeContent, null, 2));
663
- Logger_default.info("\u2713 tsconfig.node.json \u5DF2\u5C31\u7EEA");
736
+ fs2.writeFileSync(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));
737
+ Logger_default.info("\u2713 tsconfig.json \u5DF2\u5C31\u7EEA");
664
738
  }
665
739
  }
666
740
  function setupIndexHtml(cwd, config) {
@@ -690,7 +764,6 @@ function setupAppFiles(cwd, config) {
690
764
  createGlobComponentMap,
691
765
  } from "${getFrontendPackage(config.appType)}";
692
766
 
693
- // \u521B\u5EFA\u5E94\u7528
694
767
  const { app, pinia } = createMindBaseApp({
695
768
  router: {},
696
769
  componentMap: createGlobComponentMap(import.meta.glob("./views/**/*.vue"), "./views/"),
@@ -725,8 +798,7 @@ body,
725
798
  if (!fs2.existsSync(viewsDir)) fs2.mkdirSync(viewsDir);
726
799
  const exampleView = `<template>
727
800
  <div class="home">
728
- <h1>\u6B22\u8FCE\u4F7F\u7528 MindBase</h1>
729
- <p>\u5728 src/views \u76EE\u5F55\u4E0B\u521B\u5EFA\u9875\u9762\uFF0C\u8DEF\u7531\u5C06\u81EA\u52A8\u6CE8\u518C</p>
801
+ <h1>\u6B22\u8FCE\u4F7F\u7528 ${config.name}</h1>
730
802
  </div>
731
803
  </template>
732
804
 
@@ -754,7 +826,7 @@ function copyAdminAssets(cwd, config) {
754
826
  if (config.appType !== "admin-app") {
755
827
  return;
756
828
  }
757
- const sourceDir = path3.join(cwd, "../../packages/admin-app/style/mb-iconfont");
829
+ const sourceDir = path3.join(__dirname, "../assets/iconfont");
758
830
  if (!fs2.existsSync(sourceDir)) {
759
831
  Logger_default.warn("\u5B57\u4F53\u6E90\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u590D\u5236");
760
832
  return;
@@ -790,7 +862,7 @@ async function initBackend() {
790
862
  setupAppConfig(cwd, config);
791
863
  setupDrizzleConfig(cwd, config);
792
864
  setupTsConfig(cwd);
793
- setupAppEntry(cwd);
865
+ setupAppEntry(cwd, config);
794
866
  copyAssets(cwd);
795
867
  setupPrepareScript(cwd);
796
868
  setupPrecacheScript(cwd);
@@ -863,7 +935,6 @@ export {
863
935
  BACKEND_MODULES,
864
936
  FRONTEND_APP_TYPES,
865
937
  resolveDependencies,
866
- getModulePackage,
867
938
  getFrontendPackage,
868
939
  getAvailableFrontendApps,
869
940
  collectBackendConfig,
@@ -884,4 +955,4 @@ export {
884
955
  setupPublicDir,
885
956
  init
886
957
  };
887
- //# sourceMappingURL=chunk-375GNKXH.js.map
958
+ //# sourceMappingURL=chunk-QQREALNB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../node_modules/tsup/assets/esm_shims.js","../src/utils/Logger.ts","../src/utils/prompts.ts","../src/utils/BackendInitializer.ts","../src/utils/FrontendInitializer.ts","../src/commands/init/backend.ts","../src/commands/init/frontend.ts","../src/commands/init/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n\nconst LOG_LEVELS = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4,\n} as const;\n\nlet currentLogLevel: LogLevel = \"info\";\n\nconst COLORS: Record<LogLevel | \"reset\", string> = {\n debug: \"\\x1b[36m\",\n info: \"\\x1b[32m\",\n warn: \"\\x1b[33m\",\n error: \"\\x1b[31m\",\n silent: \"\\x1b[0m\",\n reset: \"\\x1b[0m\",\n};\n\n/**\n * 格式化时间戳\n */\nfunction formatTimestamp(): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, \"0\");\n const day = String(now.getDate()).padStart(2, \"0\");\n const hours = String(now.getHours()).padStart(2, \"0\");\n const minutes = String(now.getMinutes()).padStart(2, \"0\");\n const seconds = String(now.getSeconds()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * 计算字符串在终端中的视觉宽度\n * 修复:区分单宽符号 (如 ✓) 和双宽符号 (如 中文、Emoji)\n */\nfunction getVisualWidth(str: string): number {\n let width = 0;\n const segmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n for (const { segment } of segmenter.segment(str)) {\n const charCode = segment.charCodeAt(0);\n\n // 1. 基础 ASCII\n if (charCode <= 255) {\n width += 1;\n continue;\n }\n\n // 2. CJK 字符集范围 (常用中文、标点、全角符号)\n const isCJK =\n (charCode >= 0x4e00 && charCode <= 0x9fff) || // CJK Unified Ideographs\n (charCode >= 0x3000 && charCode <= 0x303f) || // CJK Symbols and Punctuation\n (charCode >= 0xff00 && charCode <= 0xffef); // Fullwidth Forms\n\n // 3. Emoji 或代理对 (通常 segment.length > 1)\n const isMultiByte = segment.length > 1;\n\n if (isCJK || isMultiByte) {\n width += 2;\n } else {\n // 4. 其他特殊符号 (如 ✓, ★, ☎) 在大多数终端占 1 格\n width += 1;\n }\n }\n return width;\n}\n\n/**\n * 截断字符串以适应视觉宽度,从头部截断并保留末尾\n */\nfunction truncateToWidth(str: string, maxWidth: number): string {\n const segmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n const segments = Array.from(segmenter.segment(str)).map((s) => s.segment);\n\n if (getVisualWidth(str) <= maxWidth) return str;\n\n let currentWidth = 3; // 为 \"...\" 预留\n let result = \"\";\n\n // 从后往前遍历 segments\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i];\n const segmentWidth = getVisualWidth(segment);\n if (currentWidth + segmentWidth > maxWidth) break;\n result = segment + result;\n currentWidth += segmentWidth;\n }\n return \"...\" + result;\n}\n\nfunction formatMessage(level: LogLevel, message: string): string {\n const timestamp = formatTimestamp();\n const terminalWidth = process.stdout.columns || 80;\n const timeStr = ` ${timestamp}`;\n const timeWidth = getVisualWidth(timeStr);\n const maxMessageWidth = terminalWidth - timeWidth - 2;\n\n let displayMessage = message;\n const messageWidth = getVisualWidth(displayMessage);\n\n if (messageWidth > maxMessageWidth) {\n displayMessage = truncateToWidth(displayMessage, maxMessageWidth);\n }\n\n const currentMsgWidth = getVisualWidth(displayMessage);\n const paddingCount = Math.max(0, terminalWidth - currentMsgWidth - timeWidth);\n const padding = \" \".repeat(paddingCount);\n\n return `${COLORS[level]}${displayMessage}${padding}${timeStr}${COLORS.reset}`;\n}\n\nconst startupTime = Date.now();\n\n// 标签填充函数(目标显示宽度 8,空格分散到字符间)\nfunction padTag(tag: string, targetWidth = 8): string {\n const currentWidth = getVisualWidth(tag);\n const padding = Math.max(0, targetWidth - currentWidth);\n\n if (padding === 0) return tag;\n\n // 将空格均匀分散到字符之间\n const chars = [...tag]; // 按码点分割\n const gapCount = chars.length + 1; // 间隙数 = 字符数 + 1(前后和中间)\n\n // 计算每个间隙的空格数\n const baseSpaces = Math.floor(padding / gapCount);\n const extraSpaces = padding % gapCount;\n\n let result = \"\";\n for (let i = 0; i < chars.length; i++) {\n // 每个间隙的空格 = 基础空格 + 额外空格(前 extraSpaces 个间隙多1个)\n const spaces = baseSpaces + (i < extraSpaces ? 1 : 0);\n result += \" \".repeat(spaces) + chars[i];\n }\n // 最后一个间隙\n result += \" \".repeat(baseSpaces + (chars.length < extraSpaces ? 1 : 0));\n\n return result;\n}\n\nfunction startupMessage(message: string, tag?: string): string {\n const diff = Date.now() - startupTime;\n const timeStr = diff.toString().padStart(6, \"0\");\n const tagStr = tag ? `【${padTag(tag)}】` : \"\";\n return `${COLORS[\"warn\"]}[${timeStr}] ${tagStr}${message}${COLORS[\"reset\"]}`;\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return LOG_LEVELS[level] >= LOG_LEVELS[currentLogLevel];\n}\n\nfunction formatArgs(args: any[]): string {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.message;\n }\n if (typeof arg === \"object\") {\n return JSON.stringify(arg, null, 2);\n }\n return String(arg);\n })\n .join(\" \");\n}\n\nexport const logger = {\n debug(...args: any[]): void {\n if (shouldLog(\"debug\")) {\n console.log(formatMessage(\"debug\", formatArgs(args)));\n }\n },\n\n info(...args: any[]): void {\n if (shouldLog(\"info\")) {\n console.log(formatMessage(\"info\", formatArgs(args)));\n }\n },\n\n warn(...args: any[]): void {\n if (shouldLog(\"warn\")) {\n console.warn(formatMessage(\"warn\", formatArgs(args)));\n }\n },\n\n error(...args: any[]): void {\n if (shouldLog(\"error\")) {\n // 先打印带颜色的格式化消息\n console.error(formatMessage(\"error\", formatArgs(args)));\n // 如果有 Error 对象,用 console.error 单独打印以显示堆栈\n const errorArg = args.find((arg) => arg instanceof Error);\n if (errorArg) {\n console.error(errorArg);\n }\n }\n },\n\n startup(tagOrMessage: string, ...args: any[]): void {\n // 如果有额外参数,第一个是标签,其余是消息\n // 否则第一个参数是消息,无标签\n if (args.length > 0) {\n console.log(startupMessage(formatArgs(args), tagOrMessage));\n } else {\n console.log(startupMessage(tagOrMessage));\n }\n },\n\n setLevel(level: LogLevel): void {\n currentLogLevel = level;\n },\n\n getLevel(): LogLevel {\n return currentLogLevel;\n },\n};\n\nexport default logger;\n","export interface BackendModule {\n name: string;\n required?: boolean;\n description: string;\n package: string;\n dependencies?: string[];\n}\n\n/**\n * 后端模块定义\n */\nexport const BACKEND_MODULES: BackendModule[] = [\n { name: \"auth\", required: true, description: \"认证权限\", package: \"@mindbase/express-auth\" },\n { name: \"kv\", description: \"键值存储\", package: \"@mindbase/express-kv\" },\n { name: \"admin\", dependencies: [\"auth\"], description: \"用户管理\", package: \"@mindbase/express-admin\" },\n { name: \"storage\", dependencies: [\"auth\", \"kv\"], description: \"文件存储\", package: \"@mindbase/express-storage\" },\n { name: \"explorer\", description: \"文件管理\", package: \"@mindbase/express-explorer\" },\n { name: \"knowledge\", dependencies: [\"auth\"], description: \"知识库\", package: \"@mindbase/express-knowledge\" },\n { name: \"commandRunner\", description: \"命令管理\", package: \"@mindbase/express-command-runner\" },\n];\n\n/**\n * 前端应用形态定义\n */\nexport interface FrontendAppType {\n name: string;\n description: string;\n package: string;\n available: boolean;\n dependencies?: string[];\n}\n\nexport const FRONTEND_APP_TYPES: FrontendAppType[] = [\n {\n name: \"admin-app\",\n description: \"管理后台 - 完整的管理界面\",\n package: \"@mindbase/vue3-admin-app\",\n available: true,\n dependencies: [\"@mindbase/vue3-auth\", \"@mindbase/vue3-kv\", \"@mindbase/vue3-client\"],\n },\n];\n\n/**\n * 解析模块依赖关系\n * @param selectedModules 用户选择的模块列表\n * @returns 包含所有依赖的完整模块列表\n */\nexport function resolveDependencies(selectedModules: string[]): BackendModule[] {\n const result = new Map<string, BackendModule>();\n\n function addModule(name: string) {\n if (result.has(name)) return;\n\n const module = BACKEND_MODULES.find((m) => m.name === name);\n if (!module) return;\n\n // 先添加依赖\n if (module.dependencies) {\n for (const dep of module.dependencies) {\n addModule(dep);\n }\n }\n\n // 再添加自己\n result.set(module.name, module);\n }\n\n for (const name of selectedModules) {\n addModule(name);\n }\n\n return Array.from(result.values());\n}\n\n/**\n * 获取前端应用的包名\n * @param appType 应用类型\n * @returns npm 包名\n */\nexport function getFrontendPackage(appType: string): string | undefined {\n const app = FRONTEND_APP_TYPES.find((a) => a.name === appType);\n return app?.package;\n}\n\n/**\n * 获取可用的前端应用列表\n * @returns 可用的应用类型列表\n */\nexport function getAvailableFrontendApps() {\n return FRONTEND_APP_TYPES.filter((app) => app.available);\n}\n\n/**\n * 已知包的依赖关系(来自 sdk-meta.json)\n */\nconst KNOWN_PACKAGE_DEPS: Record<string, string[]> = {\n \"@mindbase/vue3-auth\": [\"@mindbase/vue3-kit\", \"@mindbase/vue3-client\"],\n \"@mindbase/vue3-kv\": [\"@mindbase/vue3-kit\", \"@mindbase/vue3-client\"],\n \"@mindbase/vue3-storage\": [\"@mindbase/vue3-kit\", \"@mindbase/vue3-client\", \"spark-md5\"],\n \"@mindbase/vue3-command\": [\"@mindbase/vue3-kit\", \"@mindbase/vue3-client\"],\n \"@mindbase/vue3-explorer\": [\"@mindbase/vue3-kit\", \"@mindbase/vue3-client\"],\n};\n\n/**\n * 解析前端应用依赖的包\n * @param appType 应用类型\n * @returns 包含所有依赖的完整包列表\n */\nexport function resolveFrontendDependencies(appType: string): string[] {\n const packages = new Set<string>();\n\n function addPackage(packageName: string) {\n if (packages.has(packageName)) return;\n\n // 添加当前包\n packages.add(packageName);\n\n // 查找是否有应用定义了这个包\n const app = FRONTEND_APP_TYPES.find((a) => a.package === packageName);\n if (app?.dependencies) {\n for (const dep of app.dependencies) {\n addPackage(dep);\n }\n }\n\n // 处理已知的基础依赖关系\n if (KNOWN_PACKAGE_DEPS[packageName]) {\n for (const dep of KNOWN_PACKAGE_DEPS[packageName]) {\n addPackage(dep);\n }\n }\n }\n\n const app = FRONTEND_APP_TYPES.find((a) => a.name === appType);\n if (app) {\n addPackage(app.package);\n }\n\n return Array.from(packages);\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport logger from \"./Logger\";\nimport { BACKEND_MODULES, resolveDependencies, type BackendModule } from \"./prompts\";\n\nexport interface BackendConfig {\n name: string;\n description: string;\n author: string;\n port: number;\n dbPath: string;\n staticPath: string;\n apiPrefix: string;\n userAgent: boolean;\n ip: boolean;\n cors: boolean;\n logLevel: \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n modules: BackendModule[];\n}\n\n/**\n * 收集后端项目初始化配置\n */\nexport async function collectBackendConfig(cwd: string): Promise<BackendConfig> {\n const folderName = path.basename(cwd);\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"name\",\n message: \"项目名称\",\n initial: folderName,\n validate: (value: string) => value.length > 0 || \"项目名称不能为空\",\n },\n {\n type: \"text\",\n name: \"description\",\n message: \"项目描述\",\n initial: \"MindBase 驱动的应用项目\",\n },\n {\n type: \"text\",\n name: \"author\",\n message: \"作者\",\n initial: \"\",\n },\n {\n type: \"text\",\n name: \"port\",\n message: \"服务端口\",\n initial: \"3000\",\n validate: (value: string) => {\n const val = typeof value === \"number\" ? value : parseInt(value, 10);\n if (isNaN(val) || val < 1 || val > 65535) {\n return \"端口号必须为在 1-65535 之间的数字\";\n }\n return true;\n },\n },\n {\n type: \"text\",\n name: \"dbPath\",\n message: \"数据库路径 (建议: ./data/app.db)\",\n initial: \"./data/app.db\",\n },\n {\n type: \"text\",\n name: \"staticPath\",\n message: \"静态目录路径 (留空则不创建,例如: public)\",\n initial: \"public\",\n },\n {\n type: \"text\",\n name: \"apiPrefix\",\n message: \"API 前缀 (留空则无前缀,例如: /api)\",\n initial: \"/api\",\n },\n {\n type: \"confirm\",\n name: \"userAgent\",\n message: \"启用 User-Agent 解析中间件?\",\n initial: true,\n },\n {\n type: \"confirm\",\n name: \"ip\",\n message: \"启用 IP 解析中间件?\",\n initial: true,\n },\n {\n type: \"confirm\",\n name: \"cors\",\n message: \"启用 CORS 跨域中间件?\",\n initial: true,\n },\n {\n type: \"select\",\n name: \"logLevel\",\n message: \"日志级别\",\n choices: [\n { title: \"debug(显示所有)\", value: \"debug\" },\n { title: \"info(默认)\", value: \"info\" },\n { title: \"warn(警告)\", value: \"warn\" },\n { title: \"error(仅错误)\", value: \"error\" },\n { title: \"silent(静默)\", value: \"silent\" },\n ],\n initial: 1,\n },\n {\n type: \"multiselect\",\n name: \"modules\",\n message: \"选择要包含的模块\",\n choices: BACKEND_MODULES.map((m) => ({\n title: `${m.name} (${m.description})${m.required ? \" - 必选\" : \"\"}`,\n value: m.name,\n selected: m.required,\n })),\n },\n ]);\n\n if (Object.keys(response).length < 12) {\n throw new Error(\"用户取消了初始化流程\");\n }\n\n // 解析模块依赖\n const selectedModules = response.modules as string[];\n const allModules = resolveDependencies(selectedModules);\n\n logger.info(`已选择的模块: ${allModules.map((item) => item.name).join(\", \")}`);\n\n return { ...response, modules: allModules } as BackendConfig;\n}\n\n/**\n * 初始化 package.json\n */\nexport function setupBackendPackageJson(cwd: string, config: BackendConfig) {\n const pkgPath = path.join(cwd, \"package.json\");\n let pkg: any = {};\n\n if (fs.existsSync(pkgPath)) {\n pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n logger.info(\"✓ 检测到已存在的 package.json,正在更新配置...\");\n } else {\n pkg = {\n name: config.name,\n version: \"1.0.0\",\n description: config.description,\n author: config.author,\n scripts: {},\n dependencies: {\n \"art-template\": \"^4.13.4\",\n \"better-sqlite3\": \"^11.10.0\",\n \"cookie-parser\": \"^1.4.7\",\n cron: \"^3.1.9\",\n dayjs: \"^1.11.13\",\n \"drizzle-orm\": \"^0.44.7\",\n \"drizzle-zod\": \"^0.5.0\",\n express: \"^5.2.1\",\n \"express-art-template\": \"^1.0.1\",\n \"fs-extra\": \"^11.2.0\",\n glob: \"^10.0.0\",\n \"ipip-ipdb\": \"^0.6.0\",\n \"mime-types\": \"^2.1.35\",\n multer: \"^1.4.5-lts.1\",\n radash: \"12.1.1\",\n \"ts-morph\": \"^27.0.0\",\n \"ua-parser-js\": \"^2.0.0\",\n uuid: \"^10.0.0\",\n xss: \"^1.0.14\",\n zod: \"^3.24.0\",\n },\n devDependencies: {\n \"@types/express\": \"^5.0.6\",\n \"@types/node\": \"^20.0.0\",\n \"ts-node\": \"^10.9.0\",\n \"ts-node-dev\": \"^2.0.0\",\n typescript: \"^5.1.3\",\n \"tsconfig-paths\": \"^4.2.0\",\n \"drizzle-kit\": \"^0.31.7\",\n \"@types/better-sqlite3\": \"^7.6.11\",\n \"@types/fs-extra\": \"^11.0.4\",\n \"@types/multer\": \"^1.4.11\",\n \"@types/prompts\": \"^2.4.9\",\n \"@types/uuid\": \"^10.0.0\",\n },\n };\n logger.info(\"✓ 正在生成 package.json...\");\n }\n\n // 注入标准脚本\n pkg.scripts = pkg.scripts || {};\n pkg.scripts[\"dev\"] = \"tsx --watch --tsconfig-paths ./src/app.ts\";\n pkg.scripts[\"start\"] = \"tsx --tsconfig-paths ./src/app.ts\";\n pkg.scripts[\"prepare\"] = \"node prepare.js\";\n pkg.scripts[\"init-admin\"] = \"mindbase-auth init-admin\";\n pkg.scripts[\"db:generate\"] = \"drizzle-kit generate\";\n pkg.scripts[\"db:migrate\"] = \"drizzle-kit migrate\";\n pkg.scripts[\"init\"] = \"npm run prepare && npm run db:generate && npm run db:migrate && npm run init-admin\";\n pkg.scripts[\"db:push\"] = \"drizzle-kit push\";\n pkg.scripts[\"db:studio\"] = \"drizzle-kit studio\";\n\n // 添加依赖\n pkg.dependencies[\"@mindbase/express-common\"] = \"^1.0.0\";\n\n // 根据模块选择添加依赖\n for (const module of config.modules) {\n const packageName = module.package;\n if (packageName) {\n pkg.dependencies[packageName] = \"^1.0.0\";\n }\n }\n\n // 添加 express 和其他必要依赖\n pkg.dependencies[\"express\"] = \"^5.2.1\";\n pkg.dependencies[\"cross-env\"] = \"^7.0.3\";\n\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));\n logger.info(\"✓ package.json 已就绪\");\n}\n\n/**\n * 初始化应用配置 src/config/index.ts\n */\nexport function setupAppConfig(cwd: string, config: BackendConfig) {\n const configDir = path.join(cwd, \"src/config\");\n const configFilePath = path.join(configDir, \"index.ts\");\n const configContent = `import { MindBaseAppOptions } from \"@mindbase/express-common\";\n\nconst config: MindBaseAppOptions = {\n port: ${config.port},\n logging: true,\n logLevel: \"${config.logLevel}\",\n database: {\n path: \"${config.dbPath}\",\n },\n staticPath: ${config.staticPath ? `\"${config.staticPath}\"` : \"undefined\"},\n apiPrefix: ${config.apiPrefix ? `\"${config.apiPrefix}\"` : \"undefined\"},\n userAgent: ${config.userAgent},\n ip: ${config.ip},\n cors: ${config.cors},\n};\n\nexport default config;\n`;\n if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configFilePath, configContent);\n logger.info(\"✓ src/config/index.ts 已就绪\");\n\n // 同步创建静态目录\n if (config.staticPath) {\n const staticDir = path.join(cwd, config.staticPath);\n if (!fs.existsSync(staticDir)) {\n fs.mkdirSync(staticDir, { recursive: true });\n logger.info(`✓ 静态目录已创建: ${config.staticPath}`);\n }\n }\n}\n\n/**\n * 初始化 Drizzle 配置 drizzle.config.ts\n */\nexport function setupDrizzleConfig(cwd: string, config: BackendConfig) {\n const drizzleConfigPath = path.join(cwd, \"drizzle.config.ts\");\n const drizzleConfigContent = `import { defineConfig } from \"drizzle-kit\";\nimport fs from \"fs\";\n\n// 动态读取由 db:sync 脚本生成的 schema 路径清单\nconst schemaJson = \"./.drizzle-schemas.json\";\nconst schemas = fs.existsSync(schemaJson)\n ? JSON.parse(fs.readFileSync(schemaJson, \"utf-8\"))\n : [\"./src/**/*.schema.ts\"];\n\nexport default defineConfig({\n schema: schemas,\n out: \"./drizzle\",\n dialect: \"sqlite\",\n dbCredentials: {\n url: \"${config.dbPath}\",\n },\n});\n`;\n fs.writeFileSync(drizzleConfigPath, drizzleConfigContent);\n logger.info(\"✓ drizzle.config.ts 已就绪\");\n}\n\n/**\n * 初始化 TypeScript 配置 tsconfig.json\n */\nexport function setupTsConfig(cwd: string) {\n const tsconfigPath = path.join(cwd, \"tsconfig.json\");\n if (!fs.existsSync(tsconfigPath)) {\n const tsconfigContent = {\n compilerOptions: {\n target: \"ESNext\",\n module: \"CommonJS\",\n moduleResolution: \"node\",\n baseUrl: \".\",\n paths: {\n \"#/*\": [\"src/*\"],\n },\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n experimentalDecorators: true,\n emitDecoratorMetadata: true,\n outDir: \"dist\",\n },\n include: [\"src/**/*\"],\n exclude: [\"node_modules\"],\n };\n fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));\n logger.info(\"✓ tsconfig.json 已就绪\");\n }\n}\n\n/**\n * 初始化应用入口 src/app.ts\n */\nexport function setupAppEntry(cwd: string, config: BackendConfig) {\n const appPath = path.join(cwd, \"src/app.ts\");\n if (!fs.existsSync(appPath)) {\n const appContent = `import { createApp } from \"@mindbase/express-common\";\n${config.modules.map((module) => \"import \" + module.name + ' from \"' + module.package + '\";').join(\"\\n\")}\nimport config from \"./config\";\n\nasync function bootstrap() {\n const app = await createApp(config);\n\n // 在此处使用插件或中间件\n${config.modules.map(({ name }) => \" app.use(\" + name + \")\").join(\"\\n\")}\n\n await app.startup();\n}\n\nbootstrap();\n`;\n if (!fs.existsSync(path.join(cwd, \"src\"))) fs.mkdirSync(path.join(cwd, \"src\"));\n fs.writeFileSync(appPath, appContent);\n logger.info(\"✓ src/app.ts 已就绪\");\n }\n}\n\n/**\n * 拷贝静态资源\n */\nexport function copyAssets(cwd: string) {\n const ipdbPath = path.join(cwd, \"ipipfree.ipdb\");\n const sourceIpdb = path.join(__dirname, \"..\", \"assets\", \"ipipfree.ipdb\");\n\n if (fs.existsSync(sourceIpdb)) {\n if (!fs.existsSync(ipdbPath)) {\n fs.copyFileSync(sourceIpdb, ipdbPath);\n logger.info(\"✓ ipipfree.ipdb 已就绪\");\n } else {\n logger.info(\"- ipipfree.ipdb 已存在,跳过拷贝\");\n }\n } else {\n logger.warn(`! 未能找到 ipipfree.ipdb 源文件: ${sourceIpdb}`);\n }\n}\n\n/**\n * 生成 prepare.js 环境准备脚本\n */\nexport function setupPrepareScript(cwd: string) {\n const preparePath = path.join(cwd, \"prepare.js\");\n if (!fs.existsSync(preparePath)) {\n const prepareContent = `require('ts-node').register({\n transpileOnly: true\n});\nrequire('tsconfig-paths/register');\nconst { prepare } = require('@mindbase/express-common');\nprepare();\n`;\n fs.writeFileSync(preparePath, prepareContent);\n logger.info(\"✓ prepare.js 已就绪\");\n }\n}\n\n/**\n * 生成 precache.js 预缓存脚本\n */\nexport function setupPrecacheScript(cwd: string) {\n const precachePath = path.join(cwd, \"precache.js\");\n if (!fs.existsSync(precachePath)) {\n const precacheContent = `require('ts-node').register({\n transpileOnly: true\n});\nrequire('tsconfig-paths/register');\nconst { precache } = require('@mindbase/express-common');\nprecache();\n`;\n fs.writeFileSync(precachePath, precacheContent);\n logger.info(\"✓ precache.js 已就绪\");\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport logger from \"./Logger\";\nimport {\n FRONTEND_APP_TYPES,\n getFrontendPackage,\n getAvailableFrontendApps,\n resolveFrontendDependencies,\n} from \"./prompts\";\n\nexport interface FrontendConfig {\n name: string;\n description: string;\n author: string;\n port: number;\n proxyTarget: string;\n proxyPath: string;\n appType: string;\n}\n\n/**\n * 收集前端项目初始化配置\n */\nexport async function collectFrontendConfig(cwd: string): Promise<FrontendConfig> {\n const folderName = path.basename(cwd);\n const availableApps = getAvailableFrontendApps();\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"name\",\n message: \"项目名称\",\n initial: folderName,\n validate: (value: string) => value.length > 0 || \"项目名称不能为空\",\n },\n {\n type: \"text\",\n name: \"description\",\n message: \"项目描述\",\n initial: \"MindBase 前端应用\",\n },\n {\n type: \"text\",\n name: \"author\",\n message: \"作者\",\n initial: \"\",\n },\n {\n type: \"text\",\n name: \"port\",\n message: \"开发服务器端口\",\n initial: \"5173\",\n validate: (value: string) => {\n const val = typeof value === \"number\" ? value : parseInt(value, 10);\n if (isNaN(val) || val < 1 || val > 65535) {\n return \"端口号必须为在 1-65535 之间的数字\";\n }\n return true;\n },\n },\n {\n type: \"text\",\n name: \"proxyTarget\",\n message: \"API 代理目标地址\",\n initial: \"http://localhost:3000\",\n },\n {\n type: \"text\",\n name: \"proxyPath\",\n\n message: \"API 代理路径 (留空则不代理)\",\n initial: \"/api\",\n },\n {\n type: \"select\",\n name: \"appType\",\n message: \"选择应用形态\",\n choices: availableApps.map((app) => ({\n title: app.description,\n value: app.name,\n })),\n initial: 0,\n },\n ]);\n\n if (Object.keys(response).length < 7) {\n throw new Error(\"用户取消了初始化流程\");\n }\n\n logger.info(`已选择应用形态: ${response.appType}`);\n\n return response as FrontendConfig;\n}\n\n/**\n * 初始化 package.json\n */\nexport function setupFrontendPackageJson(cwd: string, config: FrontendConfig) {\n const pkgPath = path.join(cwd, \"package.json\");\n let pkg: any = {};\n\n if (fs.existsSync(pkgPath)) {\n pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n logger.info(\"✓ 检测到已存在的 package.json,正在更新配置...\");\n } else {\n pkg = {\n name: config.name,\n version: \"1.0.0\",\n description: config.description,\n author: config.author,\n private: true,\n type: \"module\",\n dependencies: {\n axios: \"^1.7.0\",\n \"crypto-js\": \"^4.2.0\",\n dayjs: \"^1.11.19\",\n \"element-plus\": \"^2.9.0\",\n \"element-plus/icons-vue\": \"^2.9.0\",\n \"lodash-es\": \"^4.17.21\",\n pinia: \"^2.2.0\",\n \"spark-md5\": \"^3.0.2\",\n vue: \"^3.5.0\",\n \"vue-router\": \"^4.5.0\",\n },\n devDependencies: {\n \"@vitejs/plugin-vue\": \"^5.2.0\",\n typescript: \"^5.6.0\",\n vite: \"^6.0.0\",\n \"vue-tsc\": \"^2.2.0\",\n },\n };\n logger.info(\"✓ 正在生成 package.json...\");\n }\n\n // 注入标准脚本\n pkg.scripts = pkg.scripts || {};\n pkg.scripts[\"start\"] = \"npm run dev\";\n pkg.scripts[\"dev\"] = `vite --port ${config.port}`;\n pkg.scripts[\"build\"] = \"vue-tsc -b && vite build\";\n pkg.scripts[\"preview\"] = \"vite preview\";\n\n // 添加依赖(包含所有依赖包)\n const allPackages = resolveFrontendDependencies(config.appType);\n for (const packageName of allPackages) {\n pkg.dependencies = pkg.dependencies || {};\n pkg.dependencies[packageName] = \"^1.0.0\";\n }\n\n pkg.devDependencies = pkg.devDependencies || {};\n pkg.devDependencies[\"vue-tsc\"] = \"^2.2.0\";\n\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));\n logger.info(\"✓ package.json 已就绪\");\n}\n\n/**\n * 初始化 Vite 配置 vite.config.ts\n */\nexport function setupViteConfig(cwd: string, config: FrontendConfig) {\n const viteConfigPath = path.join(cwd, \"vite.config.ts\");\n\n const proxyConfig = config.proxyPath\n ? `{\n '${config.proxyPath}': {\n target: '${config.proxyTarget}',\n changeOrigin: true,\n },\n }`\n : \"undefined\";\n\n const viteConfigContent = `import { defineConfig } from \"vite\";\nimport vue from \"@vitejs/plugin-vue\";\nimport path from \"path\";\n\nexport default defineConfig({\n plugins: [vue()],\n resolve: {\n alias: {\n \"@\": path.resolve(__dirname, \"./src\"),\n },\n },\n server: {\n port: ${config.port},\n proxy: ${proxyConfig},\n },\n});\n`;\n fs.writeFileSync(viteConfigPath, viteConfigContent);\n logger.info(\"✓ vite.config.ts 已就绪\");\n}\n\n/**\n * 初始化 TypeScript 配置\n */\nexport function setupFrontendTsConfig(cwd: string) {\n // tsconfig.json\n const tsconfigPath = path.join(cwd, \"tsconfig.json\");\n if (!fs.existsSync(tsconfigPath)) {\n const tsconfigContent = {\n compilerOptions: {\n target: \"ES2022\",\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n resolveJsonModule: true,\n isolatedModules: true,\n noEmit: true,\n lib: [\"ES2022\", \"DOM\", \"DOM.Iterable\"],\n types: [\"vite/client\"],\n },\n include: [\"src/**/*.ts\", \"src/**/*.vue\", \"vite.config.ts\"],\n };\n fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));\n logger.info(\"✓ tsconfig.json 已就绪\");\n }\n}\n\n/**\n * 初始化 index.html\n */\nexport function setupIndexHtml(cwd: string, config: FrontendConfig) {\n const htmlPath = path.join(cwd, \"index.html\");\n\n const htmlContent = `<!DOCTYPE html>\n<html lang=\"zh-CN\">\n <head>\n <meta charset=\"UTF-8\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.ico\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${config.name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`;\n fs.writeFileSync(htmlPath, htmlContent);\n logger.info(\"✓ index.html 已就绪\");\n}\n\n/**\n * 初始化源文件\n */\nexport function setupAppFiles(cwd: string, config: FrontendConfig) {\n const srcDir = path.join(cwd, \"src\");\n if (!fs.existsSync(srcDir)) fs.mkdirSync(srcDir, { recursive: true });\n\n // main.ts\n const mainContent = `import {\n createMindBaseApp,\n createGlobComponentMap,\n} from \"${getFrontendPackage(config.appType)}\";\n\nconst { app, pinia } = createMindBaseApp({\n router: {},\n componentMap: createGlobComponentMap(import.meta.glob(\"./views/**/*.vue\"), \"./views/\"),\n});\n\napp.mount(\"#app\");\n`;\n fs.writeFileSync(path.join(srcDir, \"main.ts\"), mainContent);\n logger.info(\"✓ src/main.ts 已就绪\");\n\n // App.vue\n const appContent = `<template>\n <router-view />\n</template>\n\n<script setup lang=\"ts\">\n// 根组件\n</script>\n\n<style>\nhtml,\nbody,\n#app {\n margin: 0;\n padding: 0;\n width: 100%;\n height: 100%;\n}\n</style>\n`;\n fs.writeFileSync(path.join(srcDir, \"App.vue\"), appContent);\n logger.info(\"✓ src/App.vue 已就绪\");\n\n // views 目录\n const viewsDir = path.join(srcDir, \"views\");\n if (!fs.existsSync(viewsDir)) fs.mkdirSync(viewsDir);\n\n // 示例页面\n const exampleView = `<template>\n <div class=\"home\">\n <h1>欢迎使用 ${config.name}</h1>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n// 页面逻辑\n</script>\n\n<style scoped>\n.home {\n padding: 20px;\n}\n</style>\n`;\n fs.writeFileSync(path.join(viewsDir, \"index.vue\"), exampleView);\n logger.info(\"✓ src/views/index.vue 已就绪\");\n}\n\n/**\n * 创建 public 目录\n */\nexport function setupPublicDir(cwd: string) {\n const publicDir = path.join(cwd, \"public\");\n if (!fs.existsSync(publicDir)) {\n fs.mkdirSync(publicDir, { recursive: true });\n logger.info(\"✓ public 目录已创建\");\n }\n}\n\n/**\n * 复制 admin 专用资源(如字体文件)\n * @param cwd 项目根目录\n * @param config 前端配置\n */\nexport function copyAdminAssets(cwd: string, config: FrontendConfig) {\n // 只处理 admin-app 类型\n if (config.appType !== \"admin-app\") {\n return;\n }\n\n const sourceDir = path.join(__dirname, \"../assets/iconfont\");\n\n // 检查源目录是否存在\n if (!fs.existsSync(sourceDir)) {\n logger.warn(\"字体源目录不存在,跳过复制\");\n return;\n }\n\n // 目标目录:public/assets/mb-iconfont/\n const targetDir = path.join(cwd, \"public/assets/mb-iconfont\");\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n // 复制字体文件\n const fonts = [\"iconfont.woff2\", \"iconfont.woff\", \"iconfont.ttf\"];\n let copiedCount = 0;\n\n fonts.forEach((font) => {\n const sourcePath = path.join(sourceDir, font);\n const targetPath = path.join(targetDir, font);\n\n if (fs.existsSync(sourcePath)) {\n fs.copyFileSync(sourcePath, targetPath);\n copiedCount++;\n }\n });\n\n if (copiedCount > 0) {\n logger.info(`✓ 已复制 ${copiedCount} 个字体文件到 public/assets/mb-iconfont/`);\n }\n}\n","import {\n collectBackendConfig,\n setupBackendPackageJson,\n setupAppConfig,\n setupDrizzleConfig,\n setupTsConfig,\n setupAppEntry,\n copyAssets,\n setupPrepareScript,\n setupPrecacheScript,\n} from \"../../utils/BackendInitializer\";\nimport logger from \"../../utils/Logger\";\n\nexport async function initBackend() {\n const cwd = process.cwd();\n logger.info(`\\n🚀 正在初始化 MindBase 后端项目: ${cwd}\\n`);\n\n try {\n // 1. 交互式收集配置\n const config = await collectBackendConfig(cwd);\n\n // 2. 执行各个初始化步骤\n setupBackendPackageJson(cwd, config);\n setupAppConfig(cwd, config);\n setupDrizzleConfig(cwd, config);\n setupTsConfig(cwd);\n setupAppEntry(cwd, config);\n copyAssets(cwd);\n setupPrepareScript(cwd);\n setupPrecacheScript(cwd);\n\n logger.info(\"\\n✨ 后端项目初始化成功!建议运行: npm install\\n\");\n } catch (err) {\n throw err;\n }\n}\n","import {\n collectFrontendConfig,\n setupFrontendPackageJson,\n setupViteConfig,\n setupFrontendTsConfig,\n setupIndexHtml,\n setupAppFiles,\n setupPublicDir,\n copyAdminAssets,\n} from \"../../utils/FrontendInitializer\";\nimport logger from \"../../utils/Logger\";\n\nexport async function initFrontend() {\n const cwd = process.cwd();\n logger.info(`\\n🚀 正在初始化 MindBase 前端项目: ${cwd}\\n`);\n\n try {\n // 1. 交互式收集配置\n const config = await collectFrontendConfig(cwd);\n\n // 2. 执行各个初始化步骤\n setupFrontendPackageJson(cwd, config);\n setupViteConfig(cwd, config);\n setupFrontendTsConfig(cwd);\n setupIndexHtml(cwd, config);\n setupAppFiles(cwd, config);\n setupPublicDir(cwd);\n copyAdminAssets(cwd, config);\n\n logger.info(\"\\n✨ 前端项目初始化成功!建议运行: npm install\\n\");\n } catch (err) {\n throw err;\n }\n}\n","import { initBackend } from \"./backend\";\nimport { initFrontend } from \"./frontend\";\n\nexport async function init(type?: string) {\n switch (type) {\n case \"backend\":\n await initBackend();\n break;\n case \"frontend\":\n await initFrontend();\n break;\n case \"admin\":\n await initAdmin();\n break;\n default:\n console.log(`\n用法: mindbase init <type>\n\n类型:\n backend 初始化后端项目\n frontend 初始化前端项目\n admin 快捷:初始化完整管理后台(前后端一体)\n `);\n break;\n }\n}\n\n/**\n * 快捷方式:初始化完整管理后台\n * 先初始化后端,再初始化前端,前端自动配置代理到后端\n */\nasync function initAdmin() {\n console.log(\"\\n🎯 正在初始化完整管理后台...\\n\");\n\n // 1. 初始化后端(使用默认配置)\n console.log(\"第一步:初始化后端\");\n await initBackend();\n\n // 2. 初始化前端(使用默认配置)\n console.log(\"\\n第二步:初始化前端\");\n await initFrontend();\n\n console.log(\"\\n✨ 完整管理后台初始化成功!\");\n console.log(\"\\n后续步骤:\");\n console.log(\" 1. cd backend && npm install && npm run dev\");\n console.log(\" 2. cd frontend && npm install && npm run dev\");\n console.log(\" 3. 前端会自动代理 API 到后端 http://localhost:3000\\n\");\n}\n\nexport default init;\n"],"mappings":"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","names":["app","path","path","fs","path","prompts","path","prompts","fs"]}
package/dist/index.d.ts CHANGED
@@ -9,37 +9,34 @@ declare const logger: {
9
9
  getLevel(): LogLevel;
10
10
  };
11
11
 
12
- /**
13
- * 后端模块定义
14
- */
15
- declare const BACKEND_MODULES: Array<{
12
+ interface BackendModule {
16
13
  name: string;
17
14
  required?: boolean;
18
15
  description: string;
19
16
  package: string;
20
17
  dependencies?: string[];
21
- }>;
18
+ }
19
+ /**
20
+ * 后端模块定义
21
+ */
22
+ declare const BACKEND_MODULES: BackendModule[];
22
23
  /**
23
24
  * 前端应用形态定义
24
25
  */
25
- declare const FRONTEND_APP_TYPES: Array<{
26
+ interface FrontendAppType {
26
27
  name: string;
27
28
  description: string;
28
29
  package: string;
29
30
  available: boolean;
30
- }>;
31
+ dependencies?: string[];
32
+ }
33
+ declare const FRONTEND_APP_TYPES: FrontendAppType[];
31
34
  /**
32
35
  * 解析模块依赖关系
33
36
  * @param selectedModules 用户选择的模块列表
34
37
  * @returns 包含所有依赖的完整模块列表
35
38
  */
36
- declare function resolveDependencies(selectedModules: string[]): string[];
37
- /**
38
- * 获取模块的包名
39
- * @param moduleName 模块名称
40
- * @returns npm 包名
41
- */
42
- declare function getModulePackage(moduleName: string): string | undefined;
39
+ declare function resolveDependencies(selectedModules: string[]): BackendModule[];
43
40
  /**
44
41
  * 获取前端应用的包名
45
42
  * @param appType 应用类型
@@ -50,12 +47,7 @@ declare function getFrontendPackage(appType: string): string | undefined;
50
47
  * 获取可用的前端应用列表
51
48
  * @returns 可用的应用类型列表
52
49
  */
53
- declare function getAvailableFrontendApps(): {
54
- name: string;
55
- description: string;
56
- package: string;
57
- available: boolean;
58
- }[];
50
+ declare function getAvailableFrontendApps(): FrontendAppType[];
59
51
 
60
52
  interface BackendConfig {
61
53
  name: string;
@@ -69,7 +61,7 @@ interface BackendConfig {
69
61
  ip: boolean;
70
62
  cors: boolean;
71
63
  logLevel: "debug" | "info" | "warn" | "error" | "silent";
72
- modules: string[];
64
+ modules: BackendModule[];
73
65
  }
74
66
  /**
75
67
  * 收集后端项目初始化配置
@@ -94,7 +86,7 @@ declare function setupTsConfig(cwd: string): void;
94
86
  /**
95
87
  * 初始化应用入口 src/app.ts
96
88
  */
97
- declare function setupAppEntry(cwd: string): void;
89
+ declare function setupAppEntry(cwd: string, config: BackendConfig): void;
98
90
  /**
99
91
  * 拷贝静态资源
100
92
  */
@@ -148,4 +140,4 @@ declare function setupPublicDir(cwd: string): void;
148
140
 
149
141
  declare function init(type?: string): Promise<void>;
150
142
 
151
- export { BACKEND_MODULES, type BackendConfig, FRONTEND_APP_TYPES, type FrontendConfig, type LogLevel, collectBackendConfig, collectFrontendConfig, copyAssets, logger as default, getAvailableFrontendApps, getFrontendPackage, getModulePackage, init, resolveDependencies, setupAppConfig, setupAppEntry, setupAppFiles, setupBackendPackageJson, setupDrizzleConfig, setupFrontendPackageJson, setupFrontendTsConfig, setupIndexHtml, setupPrecacheScript, setupPrepareScript, setupPublicDir, setupTsConfig, setupViteConfig };
143
+ export { BACKEND_MODULES, type BackendConfig, FRONTEND_APP_TYPES, type FrontendConfig, type LogLevel, collectBackendConfig, collectFrontendConfig, copyAssets, logger as default, getAvailableFrontendApps, getFrontendPackage, init, resolveDependencies, setupAppConfig, setupAppEntry, setupAppFiles, setupBackendPackageJson, setupDrizzleConfig, setupFrontendPackageJson, setupFrontendTsConfig, setupIndexHtml, setupPrecacheScript, setupPrepareScript, setupPublicDir, setupTsConfig, setupViteConfig };
package/dist/index.js CHANGED
@@ -6,7 +6,6 @@ import {
6
6
  copyAssets,
7
7
  getAvailableFrontendApps,
8
8
  getFrontendPackage,
9
- getModulePackage,
10
9
  init,
11
10
  logger,
12
11
  resolveDependencies,
@@ -23,7 +22,7 @@ import {
23
22
  setupPublicDir,
24
23
  setupTsConfig,
25
24
  setupViteConfig
26
- } from "./chunk-375GNKXH.js";
25
+ } from "./chunk-QQREALNB.js";
27
26
  export {
28
27
  BACKEND_MODULES,
29
28
  FRONTEND_APP_TYPES,
@@ -33,7 +32,6 @@ export {
33
32
  logger as default,
34
33
  getAvailableFrontendApps,
35
34
  getFrontendPackage,
36
- getModulePackage,
37
35
  init,
38
36
  resolveDependencies,
39
37
  setupAppConfig,
package/package.json CHANGED
@@ -1,26 +1,19 @@
1
1
  {
2
2
  "name": "@mindbase/cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
- "main": "./dist/index.js",
6
- "types": "./dist/index.d.ts",
7
5
  "bin": {
8
6
  "mindbase": "./dist/bin/mindbase.js"
9
7
  },
10
- "exports": {
11
- ".": {
12
- "types": "./dist/index.d.ts",
13
- "import": "./dist/index.js"
14
- },
15
- "./bin/*": "./dist/bin/*.js"
16
- },
17
8
  "files": [
9
+ "assets",
18
10
  "dist"
19
11
  ],
20
12
  "engines": {
21
13
  "node": ">=20.0.0"
22
14
  },
23
15
  "dependencies": {
16
+ "@vitejs/plugin-vue": "^4.0.0",
24
17
  "prompts": "^2.4.2",
25
18
  "radash": "12.1.1"
26
19
  },
@@ -37,4 +30,4 @@
37
30
  "publishConfig": {
38
31
  "access": "public"
39
32
  }
40
- }
33
+ }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../node_modules/tsup/assets/esm_shims.js","../src/utils/Logger.ts","../src/utils/prompts.ts","../src/utils/BackendInitializer.ts","../src/utils/FrontendInitializer.ts","../src/commands/init/backend.ts","../src/commands/init/frontend.ts","../src/commands/init/index.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","export type LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n\nconst LOG_LEVELS = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n silent: 4,\n} as const;\n\nlet currentLogLevel: LogLevel = \"info\";\n\nconst COLORS: Record<LogLevel | \"reset\", string> = {\n debug: \"\\x1b[36m\",\n info: \"\\x1b[32m\",\n warn: \"\\x1b[33m\",\n error: \"\\x1b[31m\",\n silent: \"\\x1b[0m\",\n reset: \"\\x1b[0m\",\n};\n\n/**\n * 格式化时间戳\n */\nfunction formatTimestamp(): string {\n const now = new Date();\n const year = now.getFullYear();\n const month = String(now.getMonth() + 1).padStart(2, \"0\");\n const day = String(now.getDate()).padStart(2, \"0\");\n const hours = String(now.getHours()).padStart(2, \"0\");\n const minutes = String(now.getMinutes()).padStart(2, \"0\");\n const seconds = String(now.getSeconds()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\n/**\n * 计算字符串在终端中的视觉宽度\n * 修复:区分单宽符号 (如 ✓) 和双宽符号 (如 中文、Emoji)\n */\nfunction getVisualWidth(str: string): number {\n let width = 0;\n const segmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n for (const { segment } of segmenter.segment(str)) {\n const charCode = segment.charCodeAt(0);\n\n // 1. 基础 ASCII\n if (charCode <= 255) {\n width += 1;\n continue;\n }\n\n // 2. CJK 字符集范围 (常用中文、标点、全角符号)\n const isCJK =\n (charCode >= 0x4e00 && charCode <= 0x9fff) || // CJK Unified Ideographs\n (charCode >= 0x3000 && charCode <= 0x303f) || // CJK Symbols and Punctuation\n (charCode >= 0xff00 && charCode <= 0xffef); // Fullwidth Forms\n\n // 3. Emoji 或代理对 (通常 segment.length > 1)\n const isMultiByte = segment.length > 1;\n\n if (isCJK || isMultiByte) {\n width += 2;\n } else {\n // 4. 其他特殊符号 (如 ✓, ★, ☎) 在大多数终端占 1 格\n width += 1;\n }\n }\n return width;\n}\n\n/**\n * 截断字符串以适应视觉宽度,从头部截断并保留末尾\n */\nfunction truncateToWidth(str: string, maxWidth: number): string {\n const segmenter = new Intl.Segmenter(undefined, { granularity: \"grapheme\" });\n const segments = Array.from(segmenter.segment(str)).map((s) => s.segment);\n\n if (getVisualWidth(str) <= maxWidth) return str;\n\n let currentWidth = 3; // 为 \"...\" 预留\n let result = \"\";\n\n // 从后往前遍历 segments\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i];\n const segmentWidth = getVisualWidth(segment);\n if (currentWidth + segmentWidth > maxWidth) break;\n result = segment + result;\n currentWidth += segmentWidth;\n }\n return \"...\" + result;\n}\n\nfunction formatMessage(level: LogLevel, message: string): string {\n const timestamp = formatTimestamp();\n const terminalWidth = process.stdout.columns || 80;\n const timeStr = ` ${timestamp}`;\n const timeWidth = getVisualWidth(timeStr);\n const maxMessageWidth = terminalWidth - timeWidth - 2;\n\n let displayMessage = message;\n const messageWidth = getVisualWidth(displayMessage);\n\n if (messageWidth > maxMessageWidth) {\n displayMessage = truncateToWidth(displayMessage, maxMessageWidth);\n }\n\n const currentMsgWidth = getVisualWidth(displayMessage);\n const paddingCount = Math.max(0, terminalWidth - currentMsgWidth - timeWidth);\n const padding = \" \".repeat(paddingCount);\n\n return `${COLORS[level]}${displayMessage}${padding}${timeStr}${COLORS.reset}`;\n}\n\nconst startupTime = Date.now();\n\n// 标签填充函数(目标显示宽度 8,空格分散到字符间)\nfunction padTag(tag: string, targetWidth = 8): string {\n const currentWidth = getVisualWidth(tag);\n const padding = Math.max(0, targetWidth - currentWidth);\n\n if (padding === 0) return tag;\n\n // 将空格均匀分散到字符之间\n const chars = [...tag]; // 按码点分割\n const gapCount = chars.length + 1; // 间隙数 = 字符数 + 1(前后和中间)\n\n // 计算每个间隙的空格数\n const baseSpaces = Math.floor(padding / gapCount);\n const extraSpaces = padding % gapCount;\n\n let result = \"\";\n for (let i = 0; i < chars.length; i++) {\n // 每个间隙的空格 = 基础空格 + 额外空格(前 extraSpaces 个间隙多1个)\n const spaces = baseSpaces + (i < extraSpaces ? 1 : 0);\n result += \" \".repeat(spaces) + chars[i];\n }\n // 最后一个间隙\n result += \" \".repeat(baseSpaces + (chars.length < extraSpaces ? 1 : 0));\n\n return result;\n}\n\nfunction startupMessage(message: string, tag?: string): string {\n const diff = Date.now() - startupTime;\n const timeStr = diff.toString().padStart(6, \"0\");\n const tagStr = tag ? `【${padTag(tag)}】` : \"\";\n return `${COLORS[\"warn\"]}[${timeStr}] ${tagStr}${message}${COLORS[\"reset\"]}`;\n}\n\nfunction shouldLog(level: LogLevel): boolean {\n return LOG_LEVELS[level] >= LOG_LEVELS[currentLogLevel];\n}\n\nfunction formatArgs(args: any[]): string {\n return args\n .map((arg) => {\n if (arg instanceof Error) {\n return arg.message;\n }\n if (typeof arg === \"object\") {\n return JSON.stringify(arg, null, 2);\n }\n return String(arg);\n })\n .join(\" \");\n}\n\nexport const logger = {\n debug(...args: any[]): void {\n if (shouldLog(\"debug\")) {\n console.log(formatMessage(\"debug\", formatArgs(args)));\n }\n },\n\n info(...args: any[]): void {\n if (shouldLog(\"info\")) {\n console.log(formatMessage(\"info\", formatArgs(args)));\n }\n },\n\n warn(...args: any[]): void {\n if (shouldLog(\"warn\")) {\n console.warn(formatMessage(\"warn\", formatArgs(args)));\n }\n },\n\n error(...args: any[]): void {\n if (shouldLog(\"error\")) {\n // 先打印带颜色的格式化消息\n console.error(formatMessage(\"error\", formatArgs(args)));\n // 如果有 Error 对象,用 console.error 单独打印以显示堆栈\n const errorArg = args.find((arg) => arg instanceof Error);\n if (errorArg) {\n console.error(errorArg);\n }\n }\n },\n\n startup(tagOrMessage: string, ...args: any[]): void {\n // 如果有额外参数,第一个是标签,其余是消息\n // 否则第一个参数是消息,无标签\n if (args.length > 0) {\n console.log(startupMessage(formatArgs(args), tagOrMessage));\n } else {\n console.log(startupMessage(tagOrMessage));\n }\n },\n\n setLevel(level: LogLevel): void {\n currentLogLevel = level;\n },\n\n getLevel(): LogLevel {\n return currentLogLevel;\n },\n};\n\nexport default logger;\n","/**\n * 后端模块定义\n */\nexport const BACKEND_MODULES: Array<{\n name: string;\n required?: boolean;\n description: string;\n package: string;\n dependencies?: string[];\n}> = [\n { name: \"auth\", required: true, description: \"认证权限\", package: \"@mindbase/express-auth\" },\n { name: \"admin\", dependencies: [\"auth\"], description: \"用户管理\", package: \"@mindbase/express-admin\" },\n { name: \"storage\", dependencies: [\"auth\", \"kv\"], description: \"存储\", package: \"@mindbase/express-storage\" },\n { name: \"kv\", description: \"键值存储\", package: \"@mindbase/express-kv\" },\n { name: \"explorer\", description: \"磁盘浏览\", package: \"@mindbase/express-explorer\" },\n { name: \"knowledge\", dependencies: [\"auth\"], description: \"知识库\", package: \"@mindbase/express-knowledge\" },\n { name: \"command-runner\", description: \"定时任务\", package: \"@mindbase/express-command-runner\" },\n];\n\n/**\n * 前端应用形态定义\n */\nexport const FRONTEND_APP_TYPES: Array<{\n name: string;\n description: string;\n package: string;\n available: boolean;\n}> = [\n {\n name: \"admin-app\",\n description: \"管理后台 - 完整的管理界面\",\n package: \"@mindbase/vue3-admin-app\",\n available: true,\n },\n {\n name: \"custom-app\",\n description: \"客户端应用 - 面向终端用户\",\n package: \"@mindbase/vue3-custom-app\",\n available: false,\n },\n {\n name: \"mobile-app\",\n description: \"移动端应用\",\n package: \"@mindbase/vue3-mobile-app\",\n available: false,\n },\n];\n\n/**\n * 解析模块依赖关系\n * @param selectedModules 用户选择的模块列表\n * @returns 包含所有依赖的完整模块列表\n */\nexport function resolveDependencies(selectedModules: string[]): string[] {\n const result = new Set<string>();\n\n function addModule(name: string) {\n if (result.has(name)) return;\n\n const module = BACKEND_MODULES.find((m) => m.name === name);\n if (!module) return;\n\n // 先添加依赖\n if (module.dependencies) {\n for (const dep of module.dependencies) {\n addModule(dep);\n }\n }\n\n // 再添加自己\n result.add(name);\n }\n\n for (const name of selectedModules) {\n addModule(name);\n }\n\n return Array.from(result);\n}\n\n/**\n * 获取模块的包名\n * @param moduleName 模块名称\n * @returns npm 包名\n */\nexport function getModulePackage(moduleName: string): string | undefined {\n const module = BACKEND_MODULES.find((m) => m.name === moduleName);\n return module?.package;\n}\n\n/**\n * 获取前端应用的包名\n * @param appType 应用类型\n * @returns npm 包名\n */\nexport function getFrontendPackage(appType: string): string | undefined {\n const app = FRONTEND_APP_TYPES.find((a) => a.name === appType);\n return app?.package;\n}\n\n/**\n * 获取可用的前端应用列表\n * @returns 可用的应用类型列表\n */\nexport function getAvailableFrontendApps() {\n return FRONTEND_APP_TYPES.filter((app) => app.available);\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport logger from \"./Logger\";\nimport { BACKEND_MODULES, resolveDependencies, getModulePackage } from \"./prompts\";\n\nexport interface BackendConfig {\n name: string;\n description: string;\n author: string;\n port: number;\n dbPath: string;\n staticPath: string;\n apiPrefix: string;\n userAgent: boolean;\n ip: boolean;\n cors: boolean;\n logLevel: \"debug\" | \"info\" | \"warn\" | \"error\" | \"silent\";\n modules: string[];\n}\n\n/**\n * 收集后端项目初始化配置\n */\nexport async function collectBackendConfig(cwd: string): Promise<BackendConfig> {\n const folderName = path.basename(cwd);\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"name\",\n message: \"项目名称\",\n initial: folderName,\n validate: (value: string) => value.length > 0 || \"项目名称不能为空\",\n },\n {\n type: \"text\",\n name: \"description\",\n message: \"项目描述\",\n initial: \"MindBase 驱动的应用项目\",\n },\n {\n type: \"text\",\n name: \"author\",\n message: \"作者\",\n initial: \"\",\n },\n {\n type: \"number\",\n name: \"port\",\n message: \"服务端口\",\n initial: 3000,\n validate: (value: number) => (value >= 1 && value <= 65535 ? true : \"端口号必须在 1-65535 之间\"),\n },\n {\n type: \"text\",\n name: \"dbPath\",\n message: \"数据库路径 (建议: ./data/app.db)\",\n initial: \"./data/app.db\",\n },\n {\n type: \"text\",\n name: \"staticPath\",\n message: \"静态目录路径 (留空则不创建,例如: public)\",\n },\n {\n type: \"text\",\n name: \"apiPrefix\",\n message: \"API 前缀 (留空则无前缀,例如: /api)\",\n },\n {\n type: \"confirm\",\n name: \"userAgent\",\n message: \"启用 User-Agent 解析中间件?\",\n initial: true,\n },\n {\n type: \"confirm\",\n name: \"ip\",\n message: \"启用 IP 解析中间件?\",\n initial: true,\n },\n {\n type: \"confirm\",\n name: \"cors\",\n message: \"启用 CORS 跨域中间件?\",\n initial: true,\n },\n {\n type: \"select\",\n name: \"logLevel\",\n message: \"日志级别\",\n choices: [\n { title: \"debug(显示所有)\", value: \"debug\" },\n { title: \"info(默认)\", value: \"info\" },\n { title: \"warn(警告)\", value: \"warn\" },\n { title: \"error(仅错误)\", value: \"error\" },\n { title: \"silent(静默)\", value: \"silent\" },\n ],\n initial: 1,\n },\n {\n type: \"multiselect\",\n name: \"modules\",\n message: \"选择要包含的模块\",\n choices: BACKEND_MODULES.map((m) => ({\n title: `${m.name} (${m.description})${m.required ? \" - 必选\" : \"\"}`,\n value: m.name,\n selected: m.required,\n })),\n },\n ]);\n\n if (Object.keys(response).length < 12) {\n throw new Error(\"用户取消了初始化流程\");\n }\n\n // 解析模块依赖\n const selectedModules = response.modules as string[];\n const allModules = resolveDependencies(selectedModules);\n\n logger.info(`已选择的模块: ${allModules.join(\", \")}`);\n\n return { ...response, modules: allModules } as BackendConfig;\n}\n\n/**\n * 初始化 package.json\n */\nexport function setupBackendPackageJson(cwd: string, config: BackendConfig) {\n const pkgPath = path.join(cwd, \"package.json\");\n let pkg: any = {};\n\n if (fs.existsSync(pkgPath)) {\n pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n logger.info(\"✓ 检测到已存在的 package.json,正在更新配置...\");\n } else {\n pkg = {\n name: config.name,\n version: \"1.0.0\",\n description: config.description,\n author: config.author,\n main: \"dist/index.js\",\n scripts: {},\n dependencies: {},\n devDependencies: {\n \"@types/express\": \"^5.0.6\",\n \"@types/node\": \"^20.0.0\",\n \"ts-node\": \"^10.9.0\",\n \"ts-node-dev\": \"^2.0.0\",\n typescript: \"^5.1.3\",\n \"tsconfig-paths\": \"^4.2.0\",\n \"drizzle-kit\": \"^0.31.7\",\n },\n };\n logger.info(\"✓ 正在生成 package.json...\");\n }\n\n // 注入标准脚本\n pkg.scripts = pkg.scripts || {};\n pkg.scripts[\"dev\"] = \"ts-node-dev --transpile-only --require tsconfig-paths/register ./src/app.ts\";\n pkg.scripts[\"start\"] = \"ts-node --transpile-only --require tsconfig-paths/register ./src/app.ts\";\n pkg.scripts[\"prepare\"] = \"node prepare.js\";\n pkg.scripts[\"init-admin\"] = \"npm run prepare && mindbase-auth init-admin\";\n pkg.scripts[\"db:push\"] = \"drizzle-kit push\";\n pkg.scripts[\"db:generate\"] = \"drizzle-kit generate\";\n pkg.scripts[\"db:migrate\"] = \"drizzle-kit migrate\";\n pkg.scripts[\"db\"] = \"npm run prepare && npm run db:generate && npm run db:migrate\";\n pkg.scripts[\"db:studio\"] = \"drizzle-kit studio\";\n\n // 添加依赖\n pkg.dependencies[\"@mindbase/express-common\"] = \"*\";\n\n // 根据模块选择添加依赖\n for (const moduleName of config.modules) {\n const packageName = getModulePackage(moduleName);\n if (packageName) {\n pkg.dependencies[packageName] = \"*\";\n }\n }\n\n // 添加 express 和其他必要依赖\n pkg.dependencies[\"express\"] = \"^5.2.1\";\n pkg.dependencies[\"cross-env\"] = \"^7.0.3\";\n\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));\n logger.info(\"✓ package.json 已就绪\");\n}\n\n/**\n * 初始化应用配置 src/config/index.ts\n */\nexport function setupAppConfig(cwd: string, config: BackendConfig) {\n const configDir = path.join(cwd, \"src/config\");\n const configFilePath = path.join(configDir, \"index.ts\");\n const configContent = `import { MindBaseAppOptions } from \"@mindbase/express-common\";\n\nconst config: MindBaseAppOptions = {\n port: ${config.port},\n logging: true,\n logLevel: \"${config.logLevel}\",\n database: {\n path: \"${config.dbPath}\",\n },\n staticPath: ${config.staticPath ? `\"${config.staticPath}\"` : \"undefined\"},\n apiPrefix: ${config.apiPrefix ? `\"${config.apiPrefix}\"` : \"undefined\"},\n userAgent: ${config.userAgent},\n ip: ${config.ip},\n cors: ${config.cors},\n};\n\nexport default config;\n`;\n if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });\n fs.writeFileSync(configFilePath, configContent);\n logger.info(\"✓ src/config/index.ts 已就绪\");\n\n // 同步创建静态目录\n if (config.staticPath) {\n const staticDir = path.join(cwd, config.staticPath);\n if (!fs.existsSync(staticDir)) {\n fs.mkdirSync(staticDir, { recursive: true });\n logger.info(`✓ 静态目录已创建: ${config.staticPath}`);\n }\n }\n}\n\n/**\n * 初始化 Drizzle 配置 drizzle.config.ts\n */\nexport function setupDrizzleConfig(cwd: string, config: BackendConfig) {\n const drizzleConfigPath = path.join(cwd, \"drizzle.config.ts\");\n const drizzleConfigContent = `import { defineConfig } from \"drizzle-kit\";\nimport fs from \"fs\";\n\n// 动态读取由 db:sync 脚本生成的 schema 路径清单\nconst schemaJson = \"./.drizzle-schemas.json\";\nconst schemas = fs.existsSync(schemaJson)\n ? JSON.parse(fs.readFileSync(schemaJson, \"utf-8\"))\n : [\"./src/**/*.schema.ts\"];\n\nexport default defineConfig({\n schema: schemas,\n out: \"./drizzle\",\n dialect: \"sqlite\",\n dbCredentials: {\n url: \"${config.dbPath}\",\n },\n});\n`;\n fs.writeFileSync(drizzleConfigPath, drizzleConfigContent);\n logger.info(\"✓ drizzle.config.ts 已就绪\");\n}\n\n/**\n * 初始化 TypeScript 配置 tsconfig.json\n */\nexport function setupTsConfig(cwd: string) {\n const tsconfigPath = path.join(cwd, \"tsconfig.json\");\n if (!fs.existsSync(tsconfigPath)) {\n const tsconfigContent = {\n compilerOptions: {\n target: \"ESNext\",\n module: \"CommonJS\",\n moduleResolution: \"node\",\n baseUrl: \".\",\n paths: {\n \"#/*\": [\"src/*\"],\n },\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: true,\n experimentalDecorators: true,\n emitDecoratorMetadata: true,\n outDir: \"dist\",\n },\n include: [\"src/**/*\"],\n exclude: [\"node_modules\"],\n };\n fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));\n logger.info(\"✓ tsconfig.json 已就绪\");\n }\n}\n\n/**\n * 初始化应用入口 src/app.ts\n */\nexport function setupAppEntry(cwd: string) {\n const appPath = path.join(cwd, \"src/app.ts\");\n if (!fs.existsSync(appPath)) {\n const appContent = `import { createApp } from \"@mindbase/express-common\";\nimport config from \"./config\";\n\nasync function bootstrap() {\n const app = await createApp(config);\n\n // 在此处使用插件或中间件\n // app.use(...);\n\n await app.startup();\n}\n\nbootstrap();\n`;\n if (!fs.existsSync(path.join(cwd, \"src\"))) fs.mkdirSync(path.join(cwd, \"src\"));\n fs.writeFileSync(appPath, appContent);\n logger.info(\"✓ src/app.ts 已就绪\");\n }\n}\n\n/**\n * 拷贝静态资源\n */\nexport function copyAssets(cwd: string) {\n const ipdbPath = path.join(cwd, \"ipipfree.ipdb\");\n const sourceIpdb = path.join(__dirname, \"..\", \"..\", \"..\", \"common\", \"ipipfree.ipdb\");\n\n if (fs.existsSync(sourceIpdb)) {\n if (!fs.existsSync(ipdbPath)) {\n fs.copyFileSync(sourceIpdb, ipdbPath);\n logger.info(\"✓ ipipfree.ipdb 已就绪\");\n } else {\n logger.info(\"- ipipfree.ipdb 已存在,跳过拷贝\");\n }\n } else {\n logger.warn(`! 未能找到 ipipfree.ipdb 源文件: ${sourceIpdb}`);\n }\n}\n\n/**\n * 生成 prepare.js 环境准备脚本\n */\nexport function setupPrepareScript(cwd: string) {\n const preparePath = path.join(cwd, \"prepare.js\");\n if (!fs.existsSync(preparePath)) {\n const prepareContent = `require('ts-node').register({\n transpileOnly: true\n});\nrequire('tsconfig-paths/register');\nconst { prepare } = require('@mindbase/express-common');\nprepare();\n`;\n fs.writeFileSync(preparePath, prepareContent);\n logger.info(\"✓ prepare.js 已就绪\");\n }\n}\n\n/**\n * 生成 precache.js 预缓存脚本\n */\nexport function setupPrecacheScript(cwd: string) {\n const precachePath = path.join(cwd, \"precache.js\");\n if (!fs.existsSync(precachePath)) {\n const precacheContent = `require('ts-node').register({\n transpileOnly: true\n});\nrequire('tsconfig-paths/register');\nconst { precache } = require('@mindbase/express-common');\nprecache();\n`;\n fs.writeFileSync(precachePath, precacheContent);\n logger.info(\"✓ precache.js 已就绪\");\n }\n}\n","import fs from \"fs\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport logger from \"./Logger\";\nimport { FRONTEND_APP_TYPES, getFrontendPackage, getAvailableFrontendApps } from \"./prompts\";\n\nexport interface FrontendConfig {\n name: string;\n description: string;\n author: string;\n port: number;\n proxyTarget: string;\n proxyPath: string;\n appType: string;\n}\n\n/**\n * 收集前端项目初始化配置\n */\nexport async function collectFrontendConfig(cwd: string): Promise<FrontendConfig> {\n const folderName = path.basename(cwd);\n const availableApps = getAvailableFrontendApps();\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"name\",\n message: \"项目名称\",\n initial: folderName,\n validate: (value: string) => value.length > 0 || \"项目名称不能为空\",\n },\n {\n type: \"text\",\n name: \"description\",\n message: \"项目描述\",\n initial: \"MindBase 前端应用\",\n },\n {\n type: \"text\",\n name: \"author\",\n message: \"作者\",\n initial: \"\",\n },\n {\n type: \"number\",\n name: \"port\",\n message: \"开发服务器端口\",\n initial: 5173,\n validate: (value: number) => (value >= 1 && value <= 65535 ? true : \"端口号必须在 1-65535 之间\"),\n },\n {\n type: \"text\",\n name: \"proxyTarget\",\n message: \"API 代理目标地址\",\n initial: \"http://localhost:3000\",\n },\n {\n type: \"text\",\n name: \"proxyPath\",\n message: \"API 代理路径 (留空则不代理)\",\n initial: \"/api\",\n },\n {\n type: \"select\",\n name: \"appType\",\n message: \"选择应用形态\",\n choices: availableApps.map((app) => ({\n title: app.description,\n value: app.name,\n })),\n initial: 0,\n },\n ]);\n\n if (Object.keys(response).length < 7) {\n throw new Error(\"用户取消了初始化流程\");\n }\n\n logger.info(`已选择应用形态: ${response.appType}`);\n\n return response as FrontendConfig;\n}\n\n/**\n * 初始化 package.json\n */\nexport function setupFrontendPackageJson(cwd: string, config: FrontendConfig) {\n const pkgPath = path.join(cwd, \"package.json\");\n let pkg: any = {};\n\n if (fs.existsSync(pkgPath)) {\n pkg = JSON.parse(fs.readFileSync(pkgPath, \"utf-8\"));\n logger.info(\"✓ 检测到已存在的 package.json,正在更新配置...\");\n } else {\n pkg = {\n name: config.name,\n version: \"1.0.0\",\n description: config.description,\n author: config.author,\n private: true,\n type: \"module\",\n };\n logger.info(\"✓ 正在生成 package.json...\");\n }\n\n // 注入标准脚本\n pkg.scripts = pkg.scripts || {};\n pkg.scripts[\"start\"] = \"npm run dev\";\n pkg.scripts[\"dev\"] = `vite --port ${config.port}`;\n pkg.scripts[\"build\"] = \"vue-tsc -b && vite build\";\n pkg.scripts[\"preview\"] = \"vite preview\";\n\n // 添加依赖\n const appPackage = getFrontendPackage(config.appType);\n if (appPackage) {\n pkg.dependencies = pkg.dependencies || {};\n pkg.dependencies[appPackage] = \"*\";\n }\n\n pkg.devDependencies = pkg.devDependencies || {};\n pkg.devDependencies[\"vue-tsc\"] = \"^2.2.0\";\n\n fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));\n logger.info(\"✓ package.json 已就绪\");\n}\n\n/**\n * 初始化 Vite 配置 vite.config.ts\n */\nexport function setupViteConfig(cwd: string, config: FrontendConfig) {\n const viteConfigPath = path.join(cwd, \"vite.config.ts\");\n\n const proxyConfig = config.proxyPath\n ? `{\n '${config.proxyPath}': {\n target: '${config.proxyTarget}',\n changeOrigin: true,\n },\n }`\n : \"undefined\";\n\n const viteConfigContent = `import { createBaseConfig } from \"@mindbase/vite\";\n\nexport default createBaseConfig({\n server: {\n port: ${config.port},\n proxy: ${proxyConfig},\n },\n});\n`;\n fs.writeFileSync(viteConfigPath, viteConfigContent);\n logger.info(\"✓ vite.config.ts 已就绪\");\n}\n\n/**\n * 初始化 TypeScript 配置\n */\nexport function setupFrontendTsConfig(cwd: string) {\n // tsconfig.json\n const tsconfigPath = path.join(cwd, \"tsconfig.json\");\n if (!fs.existsSync(tsconfigPath)) {\n const tsconfigContent = {\n extends: \"../../tsconfig.base.json\",\n compilerOptions: {\n baseUrl: \".\",\n },\n include: [\"src/**/*.ts\", \"src/**/*.vue\", \"vite.config.ts\"],\n };\n fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));\n logger.info(\"✓ tsconfig.json 已就绪\");\n }\n\n // tsconfig.node.json\n const tsconfigNodePath = path.join(cwd, \"tsconfig.node.json\");\n if (!fs.existsSync(tsconfigNodePath)) {\n const tsconfigNodeContent = {\n compilerOptions: {\n composite: true,\n skipLibCheck: true,\n module: \"ESNext\",\n moduleResolution: \"bundler\",\n allowSyntheticDefaultImports: true,\n strict: true,\n noEmit: true,\n },\n include: [\"vite.config.ts\"],\n };\n fs.writeFileSync(tsconfigNodePath, JSON.stringify(tsconfigNodeContent, null, 2));\n logger.info(\"✓ tsconfig.node.json 已就绪\");\n }\n}\n\n/**\n * 初始化 index.html\n */\nexport function setupIndexHtml(cwd: string, config: FrontendConfig) {\n const htmlPath = path.join(cwd, \"index.html\");\n\n const htmlContent = `<!DOCTYPE html>\n<html lang=\"zh-CN\">\n <head>\n <meta charset=\"UTF-8\" />\n <link rel=\"icon\" type=\"image/svg+xml\" href=\"/favicon.ico\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n <title>${config.name}</title>\n </head>\n <body>\n <div id=\"app\"></div>\n <script type=\"module\" src=\"/src/main.ts\"></script>\n </body>\n</html>\n`;\n fs.writeFileSync(htmlPath, htmlContent);\n logger.info(\"✓ index.html 已就绪\");\n}\n\n/**\n * 初始化源文件\n */\nexport function setupAppFiles(cwd: string, config: FrontendConfig) {\n const srcDir = path.join(cwd, \"src\");\n if (!fs.existsSync(srcDir)) fs.mkdirSync(srcDir, { recursive: true });\n\n // main.ts\n const mainContent = `import {\n createMindBaseApp,\n createGlobComponentMap,\n} from \"${getFrontendPackage(config.appType)}\";\n\n// 创建应用\nconst { app, pinia } = createMindBaseApp({\n router: {},\n componentMap: createGlobComponentMap(import.meta.glob(\"./views/**/*.vue\"), \"./views/\"),\n});\n\napp.mount(\"#app\");\n`;\n fs.writeFileSync(path.join(srcDir, \"main.ts\"), mainContent);\n logger.info(\"✓ src/main.ts 已就绪\");\n\n // App.vue\n const appContent = `<template>\n <router-view />\n</template>\n\n<script setup lang=\"ts\">\n// 根组件\n</script>\n\n<style>\nhtml,\nbody,\n#app {\n margin: 0;\n padding: 0;\n width: 100%;\n height: 100%;\n}\n</style>\n`;\n fs.writeFileSync(path.join(srcDir, \"App.vue\"), appContent);\n logger.info(\"✓ src/App.vue 已就绪\");\n\n // views 目录\n const viewsDir = path.join(srcDir, \"views\");\n if (!fs.existsSync(viewsDir)) fs.mkdirSync(viewsDir);\n\n // 示例页面\n const exampleView = `<template>\n <div class=\"home\">\n <h1>欢迎使用 MindBase</h1>\n <p>在 src/views 目录下创建页面,路由将自动注册</p>\n </div>\n</template>\n\n<script setup lang=\"ts\">\n// 页面逻辑\n</script>\n\n<style scoped>\n.home {\n padding: 20px;\n}\n</style>\n`;\n fs.writeFileSync(path.join(viewsDir, \"index.vue\"), exampleView);\n logger.info(\"✓ src/views/index.vue 已就绪\");\n}\n\n/**\n * 创建 public 目录\n */\nexport function setupPublicDir(cwd: string) {\n const publicDir = path.join(cwd, \"public\");\n if (!fs.existsSync(publicDir)) {\n fs.mkdirSync(publicDir, { recursive: true });\n logger.info(\"✓ public 目录已创建\");\n }\n}\n\n/**\n * 复制 admin 专用资源(如字体文件)\n * @param cwd 项目根目录\n * @param config 前端配置\n */\nexport function copyAdminAssets(cwd: string, config: FrontendConfig) {\n // 只处理 admin-app 类型\n if (config.appType !== \"admin-app\") {\n return;\n }\n\n // 字体源路径:从 cwd (apps/admin/) 到 packages/admin-app/style/mb-iconfont/\n const sourceDir = path.join(cwd, \"../../packages/admin-app/style/mb-iconfont\");\n\n // 检查源目录是否存在\n if (!fs.existsSync(sourceDir)) {\n logger.warn(\"字体源目录不存在,跳过复制\");\n return;\n }\n\n // 目标目录:public/assets/mb-iconfont/\n const targetDir = path.join(cwd, \"public/assets/mb-iconfont\");\n if (!fs.existsSync(targetDir)) {\n fs.mkdirSync(targetDir, { recursive: true });\n }\n\n // 复制字体文件\n const fonts = [\"iconfont.woff2\", \"iconfont.woff\", \"iconfont.ttf\"];\n let copiedCount = 0;\n\n fonts.forEach((font) => {\n const sourcePath = path.join(sourceDir, font);\n const targetPath = path.join(targetDir, font);\n\n if (fs.existsSync(sourcePath)) {\n fs.copyFileSync(sourcePath, targetPath);\n copiedCount++;\n }\n });\n\n if (copiedCount > 0) {\n logger.info(`✓ 已复制 ${copiedCount} 个字体文件到 public/assets/mb-iconfont/`);\n }\n}\n","import {\n collectBackendConfig,\n setupBackendPackageJson,\n setupAppConfig,\n setupDrizzleConfig,\n setupTsConfig,\n setupAppEntry,\n copyAssets,\n setupPrepareScript,\n setupPrecacheScript,\n} from \"../../utils/BackendInitializer\";\nimport logger from \"../../utils/Logger\";\n\nexport async function initBackend() {\n const cwd = process.cwd();\n logger.info(`\\n🚀 正在初始化 MindBase 后端项目: ${cwd}\\n`);\n\n try {\n // 1. 交互式收集配置\n const config = await collectBackendConfig(cwd);\n\n // 2. 执行各个初始化步骤\n setupBackendPackageJson(cwd, config);\n setupAppConfig(cwd, config);\n setupDrizzleConfig(cwd, config);\n setupTsConfig(cwd);\n setupAppEntry(cwd);\n copyAssets(cwd);\n setupPrepareScript(cwd);\n setupPrecacheScript(cwd);\n\n logger.info(\"\\n✨ 后端项目初始化成功!建议运行: npm install\\n\");\n } catch (err) {\n throw err;\n }\n}\n","import {\n collectFrontendConfig,\n setupFrontendPackageJson,\n setupViteConfig,\n setupFrontendTsConfig,\n setupIndexHtml,\n setupAppFiles,\n setupPublicDir,\n copyAdminAssets,\n} from \"../../utils/FrontendInitializer\";\nimport logger from \"../../utils/Logger\";\n\nexport async function initFrontend() {\n const cwd = process.cwd();\n logger.info(`\\n🚀 正在初始化 MindBase 前端项目: ${cwd}\\n`);\n\n try {\n // 1. 交互式收集配置\n const config = await collectFrontendConfig(cwd);\n\n // 2. 执行各个初始化步骤\n setupFrontendPackageJson(cwd, config);\n setupViteConfig(cwd, config);\n setupFrontendTsConfig(cwd);\n setupIndexHtml(cwd, config);\n setupAppFiles(cwd, config);\n setupPublicDir(cwd);\n copyAdminAssets(cwd, config);\n\n logger.info(\"\\n✨ 前端项目初始化成功!建议运行: npm install\\n\");\n } catch (err) {\n throw err;\n }\n}\n","import { initBackend } from \"./backend\";\nimport { initFrontend } from \"./frontend\";\n\nexport async function init(type?: string) {\n switch (type) {\n case \"backend\":\n await initBackend();\n break;\n case \"frontend\":\n await initFrontend();\n break;\n case \"admin\":\n // 快捷方式:初始化完整管理后台(前后端一体)\n await initAdmin();\n break;\n default:\n console.log(`\n用法: mindbase init <type>\n\n类型:\n backend 初始化后端项目\n frontend 初始化前端项目\n admin 快捷:初始化完整管理后台(前后端一体)\n `);\n break;\n }\n}\n\n/**\n * 快捷方式:初始化完整管理后台\n * 先初始化后端,再初始化前端,前端自动配置代理到后端\n */\nasync function initAdmin() {\n console.log(\"\\n🎯 正在初始化完整管理后台...\\n\");\n\n // 1. 初始化后端(使用默认配置)\n console.log(\"第一步:初始化后端\");\n await initBackend();\n\n // 2. 初始化前端(使用默认配置)\n console.log(\"\\n第二步:初始化前端\");\n await initFrontend();\n\n console.log(\"\\n✨ 完整管理后台初始化成功!\");\n console.log(\"\\n后续步骤:\");\n console.log(\" 1. cd backend && npm install && npm run dev\");\n console.log(\" 2. cd frontend && npm install && npm run dev\");\n console.log(\" 3. 前端会自动代理 API 到后端 http://localhost:3000\\n\");\n}\n\nexport default init;\n"],"mappings":"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","names":["path","path","fs","path","prompts","path","prompts","fs"]}