@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.
- package/assets/iconfont/iconfont.ttf +0 -0
- package/assets/iconfont/iconfont.woff +0 -0
- package/assets/iconfont/iconfont.woff2 +0 -0
- package/assets/ipipfree.ipdb +0 -0
- package/dist/bin/mindbase.js +4 -13
- package/dist/bin/mindbase.js.map +1 -1
- package/dist/{chunk-375GNKXH.js → chunk-QQREALNB.js} +151 -80
- package/dist/chunk-QQREALNB.js.map +1 -0
- package/dist/index.d.ts +15 -23
- package/dist/index.js +1 -3
- package/package.json +4 -11
- package/dist/chunk-375GNKXH.js.map +0 -1
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/bin/mindbase.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
init
|
|
4
|
-
} from "../chunk-
|
|
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 \
|
|
33
|
-
frontend \
|
|
34
|
-
admin \
|
|
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) => {
|
package/dist/bin/mindbase.js.map
CHANGED
|
@@ -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
|
|
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: "
|
|
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: "
|
|
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
|
|
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.
|
|
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: "
|
|
267
|
+
type: "text",
|
|
253
268
|
name: "port",
|
|
254
269
|
message: "\u670D\u52A1\u7AEF\u53E3",
|
|
255
|
-
initial:
|
|
256
|
-
validate: (value) =>
|
|
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"] = "
|
|
353
|
-
pkg.scripts["start"] = "
|
|
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"] = "
|
|
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["
|
|
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
|
|
363
|
-
const packageName =
|
|
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
|
-
|
|
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, "..", "
|
|
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: "
|
|
597
|
+
type: "text",
|
|
549
598
|
name: "port",
|
|
550
599
|
message: "\u5F00\u53D1\u670D\u52A1\u5668\u7AEF\u53E3",
|
|
551
|
-
initial: 5173,
|
|
552
|
-
validate: (value) =>
|
|
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
|
|
606
|
-
|
|
678
|
+
const allPackages = resolveFrontendDependencies(config.appType);
|
|
679
|
+
for (const packageName of allPackages) {
|
|
607
680
|
pkg.dependencies = pkg.dependencies || {};
|
|
608
|
-
pkg.dependencies[
|
|
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 {
|
|
696
|
+
const viteConfigContent = `import { defineConfig } from "vite";
|
|
697
|
+
import vue from "@vitejs/plugin-vue";
|
|
698
|
+
import path from "path";
|
|
624
699
|
|
|
625
|
-
export default
|
|
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
|
-
|
|
653
|
-
skipLibCheck: true,
|
|
721
|
+
target: "ES2022",
|
|
654
722
|
module: "ESNext",
|
|
655
723
|
moduleResolution: "bundler",
|
|
656
|
-
allowSyntheticDefaultImports: true,
|
|
657
724
|
strict: true,
|
|
658
|
-
|
|
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(
|
|
663
|
-
Logger_default.info("\u2713 tsconfig.
|
|
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
|
|
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(
|
|
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-
|
|
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
|
-
|
|
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[]):
|
|
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:
|
|
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,
|
|
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-
|
|
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.
|
|
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"]}
|