@mindbase/cli 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/mindbase.d.ts +1 -0
- package/dist/bin/mindbase.js +49 -0
- package/dist/bin/mindbase.js.map +1 -0
- package/dist/chunk-375GNKXH.js +887 -0
- package/dist/chunk-375GNKXH.js.map +1 -0
- package/dist/index.d.ts +151 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
init
|
|
4
|
+
} from "../chunk-375GNKXH.js";
|
|
5
|
+
|
|
6
|
+
// src/bin/mindbase.ts
|
|
7
|
+
var args = process.argv.slice(2);
|
|
8
|
+
var command = args[0];
|
|
9
|
+
var type = args[1];
|
|
10
|
+
async function main() {
|
|
11
|
+
switch (command) {
|
|
12
|
+
case "init":
|
|
13
|
+
await init(type);
|
|
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
|
+
default:
|
|
22
|
+
showHelp();
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function showHelp() {
|
|
27
|
+
console.log(`
|
|
28
|
+
\u7528\u6CD5: mindbase <command> [type]
|
|
29
|
+
|
|
30
|
+
\u547D\u4EE4:
|
|
31
|
+
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
|
|
37
|
+
|
|
38
|
+
\u793A\u4F8B:
|
|
39
|
+
mindbase init backend # \u4EA4\u4E92\u5F0F\u9009\u62E9\u540E\u7AEF\u6A21\u5757
|
|
40
|
+
mindbase init frontend # \u4EA4\u4E92\u5F0F\u9009\u62E9\u524D\u7AEF\u5E94\u7528\u5F62\u6001
|
|
41
|
+
mindbase init admin # \u4E00\u952E\u521D\u59CB\u5316\u5B8C\u6574\u7BA1\u7406\u540E\u53F0
|
|
42
|
+
mindbase precache # \u9884\u751F\u6210\u7F13\u5B58
|
|
43
|
+
`);
|
|
44
|
+
}
|
|
45
|
+
main().catch((err) => {
|
|
46
|
+
console.error("\u274C \u6267\u884C\u5931\u8D25:", err);
|
|
47
|
+
process.exit(1);
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=mindbase.js.map
|
|
@@ -0,0 +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":[]}
|
|
@@ -0,0 +1,887 @@
|
|
|
1
|
+
// ../../node_modules/tsup/assets/esm_shims.js
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
var getFilename = () => fileURLToPath(import.meta.url);
|
|
5
|
+
var getDirname = () => path.dirname(getFilename());
|
|
6
|
+
var __dirname = /* @__PURE__ */ getDirname();
|
|
7
|
+
|
|
8
|
+
// src/utils/Logger.ts
|
|
9
|
+
var LOG_LEVELS = {
|
|
10
|
+
debug: 0,
|
|
11
|
+
info: 1,
|
|
12
|
+
warn: 2,
|
|
13
|
+
error: 3,
|
|
14
|
+
silent: 4
|
|
15
|
+
};
|
|
16
|
+
var currentLogLevel = "info";
|
|
17
|
+
var COLORS = {
|
|
18
|
+
debug: "\x1B[36m",
|
|
19
|
+
info: "\x1B[32m",
|
|
20
|
+
warn: "\x1B[33m",
|
|
21
|
+
error: "\x1B[31m",
|
|
22
|
+
silent: "\x1B[0m",
|
|
23
|
+
reset: "\x1B[0m"
|
|
24
|
+
};
|
|
25
|
+
function formatTimestamp() {
|
|
26
|
+
const now = /* @__PURE__ */ new Date();
|
|
27
|
+
const year = now.getFullYear();
|
|
28
|
+
const month = String(now.getMonth() + 1).padStart(2, "0");
|
|
29
|
+
const day = String(now.getDate()).padStart(2, "0");
|
|
30
|
+
const hours = String(now.getHours()).padStart(2, "0");
|
|
31
|
+
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
32
|
+
const seconds = String(now.getSeconds()).padStart(2, "0");
|
|
33
|
+
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
34
|
+
}
|
|
35
|
+
function getVisualWidth(str) {
|
|
36
|
+
let width = 0;
|
|
37
|
+
const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
38
|
+
for (const { segment } of segmenter.segment(str)) {
|
|
39
|
+
const charCode = segment.charCodeAt(0);
|
|
40
|
+
if (charCode <= 255) {
|
|
41
|
+
width += 1;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const isCJK = charCode >= 19968 && charCode <= 40959 || // CJK Unified Ideographs
|
|
45
|
+
charCode >= 12288 && charCode <= 12351 || // CJK Symbols and Punctuation
|
|
46
|
+
charCode >= 65280 && charCode <= 65519;
|
|
47
|
+
const isMultiByte = segment.length > 1;
|
|
48
|
+
if (isCJK || isMultiByte) {
|
|
49
|
+
width += 2;
|
|
50
|
+
} else {
|
|
51
|
+
width += 1;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return width;
|
|
55
|
+
}
|
|
56
|
+
function truncateToWidth(str, maxWidth) {
|
|
57
|
+
const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
58
|
+
const segments = Array.from(segmenter.segment(str)).map((s) => s.segment);
|
|
59
|
+
if (getVisualWidth(str) <= maxWidth) return str;
|
|
60
|
+
let currentWidth = 3;
|
|
61
|
+
let result = "";
|
|
62
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
63
|
+
const segment = segments[i];
|
|
64
|
+
const segmentWidth = getVisualWidth(segment);
|
|
65
|
+
if (currentWidth + segmentWidth > maxWidth) break;
|
|
66
|
+
result = segment + result;
|
|
67
|
+
currentWidth += segmentWidth;
|
|
68
|
+
}
|
|
69
|
+
return "..." + result;
|
|
70
|
+
}
|
|
71
|
+
function formatMessage(level, message) {
|
|
72
|
+
const timestamp = formatTimestamp();
|
|
73
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
74
|
+
const timeStr = ` ${timestamp}`;
|
|
75
|
+
const timeWidth = getVisualWidth(timeStr);
|
|
76
|
+
const maxMessageWidth = terminalWidth - timeWidth - 2;
|
|
77
|
+
let displayMessage = message;
|
|
78
|
+
const messageWidth = getVisualWidth(displayMessage);
|
|
79
|
+
if (messageWidth > maxMessageWidth) {
|
|
80
|
+
displayMessage = truncateToWidth(displayMessage, maxMessageWidth);
|
|
81
|
+
}
|
|
82
|
+
const currentMsgWidth = getVisualWidth(displayMessage);
|
|
83
|
+
const paddingCount = Math.max(0, terminalWidth - currentMsgWidth - timeWidth);
|
|
84
|
+
const padding = " ".repeat(paddingCount);
|
|
85
|
+
return `${COLORS[level]}${displayMessage}${padding}${timeStr}${COLORS.reset}`;
|
|
86
|
+
}
|
|
87
|
+
var startupTime = Date.now();
|
|
88
|
+
function padTag(tag, targetWidth = 8) {
|
|
89
|
+
const currentWidth = getVisualWidth(tag);
|
|
90
|
+
const padding = Math.max(0, targetWidth - currentWidth);
|
|
91
|
+
if (padding === 0) return tag;
|
|
92
|
+
const chars = [...tag];
|
|
93
|
+
const gapCount = chars.length + 1;
|
|
94
|
+
const baseSpaces = Math.floor(padding / gapCount);
|
|
95
|
+
const extraSpaces = padding % gapCount;
|
|
96
|
+
let result = "";
|
|
97
|
+
for (let i = 0; i < chars.length; i++) {
|
|
98
|
+
const spaces = baseSpaces + (i < extraSpaces ? 1 : 0);
|
|
99
|
+
result += " ".repeat(spaces) + chars[i];
|
|
100
|
+
}
|
|
101
|
+
result += " ".repeat(baseSpaces + (chars.length < extraSpaces ? 1 : 0));
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
function startupMessage(message, tag) {
|
|
105
|
+
const diff = Date.now() - startupTime;
|
|
106
|
+
const timeStr = diff.toString().padStart(6, "0");
|
|
107
|
+
const tagStr = tag ? `\u3010${padTag(tag)}\u3011` : "";
|
|
108
|
+
return `${COLORS["warn"]}[${timeStr}] ${tagStr}${message}${COLORS["reset"]}`;
|
|
109
|
+
}
|
|
110
|
+
function shouldLog(level) {
|
|
111
|
+
return LOG_LEVELS[level] >= LOG_LEVELS[currentLogLevel];
|
|
112
|
+
}
|
|
113
|
+
function formatArgs(args) {
|
|
114
|
+
return args.map((arg) => {
|
|
115
|
+
if (arg instanceof Error) {
|
|
116
|
+
return arg.message;
|
|
117
|
+
}
|
|
118
|
+
if (typeof arg === "object") {
|
|
119
|
+
return JSON.stringify(arg, null, 2);
|
|
120
|
+
}
|
|
121
|
+
return String(arg);
|
|
122
|
+
}).join(" ");
|
|
123
|
+
}
|
|
124
|
+
var logger = {
|
|
125
|
+
debug(...args) {
|
|
126
|
+
if (shouldLog("debug")) {
|
|
127
|
+
console.log(formatMessage("debug", formatArgs(args)));
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
info(...args) {
|
|
131
|
+
if (shouldLog("info")) {
|
|
132
|
+
console.log(formatMessage("info", formatArgs(args)));
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
warn(...args) {
|
|
136
|
+
if (shouldLog("warn")) {
|
|
137
|
+
console.warn(formatMessage("warn", formatArgs(args)));
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
error(...args) {
|
|
141
|
+
if (shouldLog("error")) {
|
|
142
|
+
console.error(formatMessage("error", formatArgs(args)));
|
|
143
|
+
const errorArg = args.find((arg) => arg instanceof Error);
|
|
144
|
+
if (errorArg) {
|
|
145
|
+
console.error(errorArg);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
startup(tagOrMessage, ...args) {
|
|
150
|
+
if (args.length > 0) {
|
|
151
|
+
console.log(startupMessage(formatArgs(args), tagOrMessage));
|
|
152
|
+
} else {
|
|
153
|
+
console.log(startupMessage(tagOrMessage));
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
setLevel(level) {
|
|
157
|
+
currentLogLevel = level;
|
|
158
|
+
},
|
|
159
|
+
getLevel() {
|
|
160
|
+
return currentLogLevel;
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
var Logger_default = logger;
|
|
164
|
+
|
|
165
|
+
// src/utils/prompts.ts
|
|
166
|
+
var BACKEND_MODULES = [
|
|
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
|
+
{ name: "kv", description: "\u952E\u503C\u5B58\u50A8", package: "@mindbase/express-kv" },
|
|
171
|
+
{ name: "explorer", description: "\u78C1\u76D8\u6D4F\u89C8", package: "@mindbase/express-explorer" },
|
|
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" }
|
|
174
|
+
];
|
|
175
|
+
var FRONTEND_APP_TYPES = [
|
|
176
|
+
{
|
|
177
|
+
name: "admin-app",
|
|
178
|
+
description: "\u7BA1\u7406\u540E\u53F0 - \u5B8C\u6574\u7684\u7BA1\u7406\u754C\u9762",
|
|
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
|
|
193
|
+
}
|
|
194
|
+
];
|
|
195
|
+
function resolveDependencies(selectedModules) {
|
|
196
|
+
const result = /* @__PURE__ */ new Set();
|
|
197
|
+
function addModule(name) {
|
|
198
|
+
if (result.has(name)) return;
|
|
199
|
+
const module = BACKEND_MODULES.find((m) => m.name === name);
|
|
200
|
+
if (!module) return;
|
|
201
|
+
if (module.dependencies) {
|
|
202
|
+
for (const dep of module.dependencies) {
|
|
203
|
+
addModule(dep);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
result.add(name);
|
|
207
|
+
}
|
|
208
|
+
for (const name of selectedModules) {
|
|
209
|
+
addModule(name);
|
|
210
|
+
}
|
|
211
|
+
return Array.from(result);
|
|
212
|
+
}
|
|
213
|
+
function getModulePackage(moduleName) {
|
|
214
|
+
const module = BACKEND_MODULES.find((m) => m.name === moduleName);
|
|
215
|
+
return module?.package;
|
|
216
|
+
}
|
|
217
|
+
function getFrontendPackage(appType) {
|
|
218
|
+
const app = FRONTEND_APP_TYPES.find((a) => a.name === appType);
|
|
219
|
+
return app?.package;
|
|
220
|
+
}
|
|
221
|
+
function getAvailableFrontendApps() {
|
|
222
|
+
return FRONTEND_APP_TYPES.filter((app) => app.available);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// src/utils/BackendInitializer.ts
|
|
226
|
+
import fs from "fs";
|
|
227
|
+
import path2 from "path";
|
|
228
|
+
import prompts from "prompts";
|
|
229
|
+
async function collectBackendConfig(cwd) {
|
|
230
|
+
const folderName = path2.basename(cwd);
|
|
231
|
+
const response = await prompts([
|
|
232
|
+
{
|
|
233
|
+
type: "text",
|
|
234
|
+
name: "name",
|
|
235
|
+
message: "\u9879\u76EE\u540D\u79F0",
|
|
236
|
+
initial: folderName,
|
|
237
|
+
validate: (value) => value.length > 0 || "\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
type: "text",
|
|
241
|
+
name: "description",
|
|
242
|
+
message: "\u9879\u76EE\u63CF\u8FF0",
|
|
243
|
+
initial: "MindBase \u9A71\u52A8\u7684\u5E94\u7528\u9879\u76EE"
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
type: "text",
|
|
247
|
+
name: "author",
|
|
248
|
+
message: "\u4F5C\u8005",
|
|
249
|
+
initial: ""
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
type: "number",
|
|
253
|
+
name: "port",
|
|
254
|
+
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"
|
|
257
|
+
},
|
|
258
|
+
{
|
|
259
|
+
type: "text",
|
|
260
|
+
name: "dbPath",
|
|
261
|
+
message: "\u6570\u636E\u5E93\u8DEF\u5F84 (\u5EFA\u8BAE: ./data/app.db)",
|
|
262
|
+
initial: "./data/app.db"
|
|
263
|
+
},
|
|
264
|
+
{
|
|
265
|
+
type: "text",
|
|
266
|
+
name: "staticPath",
|
|
267
|
+
message: "\u9759\u6001\u76EE\u5F55\u8DEF\u5F84 (\u7559\u7A7A\u5219\u4E0D\u521B\u5EFA\uFF0C\u4F8B\u5982: public)"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
type: "text",
|
|
271
|
+
name: "apiPrefix",
|
|
272
|
+
message: "API \u524D\u7F00 (\u7559\u7A7A\u5219\u65E0\u524D\u7F00\uFF0C\u4F8B\u5982: /api)"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
type: "confirm",
|
|
276
|
+
name: "userAgent",
|
|
277
|
+
message: "\u542F\u7528 User-Agent \u89E3\u6790\u4E2D\u95F4\u4EF6?",
|
|
278
|
+
initial: true
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
type: "confirm",
|
|
282
|
+
name: "ip",
|
|
283
|
+
message: "\u542F\u7528 IP \u89E3\u6790\u4E2D\u95F4\u4EF6?",
|
|
284
|
+
initial: true
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
type: "confirm",
|
|
288
|
+
name: "cors",
|
|
289
|
+
message: "\u542F\u7528 CORS \u8DE8\u57DF\u4E2D\u95F4\u4EF6?",
|
|
290
|
+
initial: true
|
|
291
|
+
},
|
|
292
|
+
{
|
|
293
|
+
type: "select",
|
|
294
|
+
name: "logLevel",
|
|
295
|
+
message: "\u65E5\u5FD7\u7EA7\u522B",
|
|
296
|
+
choices: [
|
|
297
|
+
{ title: "debug\uFF08\u663E\u793A\u6240\u6709\uFF09", value: "debug" },
|
|
298
|
+
{ title: "info\uFF08\u9ED8\u8BA4\uFF09", value: "info" },
|
|
299
|
+
{ title: "warn\uFF08\u8B66\u544A\uFF09", value: "warn" },
|
|
300
|
+
{ title: "error\uFF08\u4EC5\u9519\u8BEF\uFF09", value: "error" },
|
|
301
|
+
{ title: "silent\uFF08\u9759\u9ED8\uFF09", value: "silent" }
|
|
302
|
+
],
|
|
303
|
+
initial: 1
|
|
304
|
+
},
|
|
305
|
+
{
|
|
306
|
+
type: "multiselect",
|
|
307
|
+
name: "modules",
|
|
308
|
+
message: "\u9009\u62E9\u8981\u5305\u542B\u7684\u6A21\u5757",
|
|
309
|
+
choices: BACKEND_MODULES.map((m) => ({
|
|
310
|
+
title: `${m.name} (${m.description})${m.required ? " - \u5FC5\u9009" : ""}`,
|
|
311
|
+
value: m.name,
|
|
312
|
+
selected: m.required
|
|
313
|
+
}))
|
|
314
|
+
}
|
|
315
|
+
]);
|
|
316
|
+
if (Object.keys(response).length < 12) {
|
|
317
|
+
throw new Error("\u7528\u6237\u53D6\u6D88\u4E86\u521D\u59CB\u5316\u6D41\u7A0B");
|
|
318
|
+
}
|
|
319
|
+
const selectedModules = response.modules;
|
|
320
|
+
const allModules = resolveDependencies(selectedModules);
|
|
321
|
+
Logger_default.info(`\u5DF2\u9009\u62E9\u7684\u6A21\u5757: ${allModules.join(", ")}`);
|
|
322
|
+
return { ...response, modules: allModules };
|
|
323
|
+
}
|
|
324
|
+
function setupBackendPackageJson(cwd, config) {
|
|
325
|
+
const pkgPath = path2.join(cwd, "package.json");
|
|
326
|
+
let pkg = {};
|
|
327
|
+
if (fs.existsSync(pkgPath)) {
|
|
328
|
+
pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
329
|
+
Logger_default.info("\u2713 \u68C0\u6D4B\u5230\u5DF2\u5B58\u5728\u7684 package.json\uFF0C\u6B63\u5728\u66F4\u65B0\u914D\u7F6E...");
|
|
330
|
+
} else {
|
|
331
|
+
pkg = {
|
|
332
|
+
name: config.name,
|
|
333
|
+
version: "1.0.0",
|
|
334
|
+
description: config.description,
|
|
335
|
+
author: config.author,
|
|
336
|
+
main: "dist/index.js",
|
|
337
|
+
scripts: {},
|
|
338
|
+
dependencies: {},
|
|
339
|
+
devDependencies: {
|
|
340
|
+
"@types/express": "^5.0.6",
|
|
341
|
+
"@types/node": "^20.0.0",
|
|
342
|
+
"ts-node": "^10.9.0",
|
|
343
|
+
"ts-node-dev": "^2.0.0",
|
|
344
|
+
typescript: "^5.1.3",
|
|
345
|
+
"tsconfig-paths": "^4.2.0",
|
|
346
|
+
"drizzle-kit": "^0.31.7"
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
Logger_default.info("\u2713 \u6B63\u5728\u751F\u6210 package.json...");
|
|
350
|
+
}
|
|
351
|
+
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";
|
|
354
|
+
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";
|
|
357
|
+
pkg.scripts["db:generate"] = "drizzle-kit generate";
|
|
358
|
+
pkg.scripts["db:migrate"] = "drizzle-kit migrate";
|
|
359
|
+
pkg.scripts["db"] = "npm run prepare && npm run db:generate && npm run db:migrate";
|
|
360
|
+
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);
|
|
364
|
+
if (packageName) {
|
|
365
|
+
pkg.dependencies[packageName] = "*";
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
pkg.dependencies["express"] = "^5.2.1";
|
|
369
|
+
pkg.dependencies["cross-env"] = "^7.0.3";
|
|
370
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
371
|
+
Logger_default.info("\u2713 package.json \u5DF2\u5C31\u7EEA");
|
|
372
|
+
}
|
|
373
|
+
function setupAppConfig(cwd, config) {
|
|
374
|
+
const configDir = path2.join(cwd, "src/config");
|
|
375
|
+
const configFilePath = path2.join(configDir, "index.ts");
|
|
376
|
+
const configContent = `import { MindBaseAppOptions } from "@mindbase/express-common";
|
|
377
|
+
|
|
378
|
+
const config: MindBaseAppOptions = {
|
|
379
|
+
port: ${config.port},
|
|
380
|
+
logging: true,
|
|
381
|
+
logLevel: "${config.logLevel}",
|
|
382
|
+
database: {
|
|
383
|
+
path: "${config.dbPath}",
|
|
384
|
+
},
|
|
385
|
+
staticPath: ${config.staticPath ? `"${config.staticPath}"` : "undefined"},
|
|
386
|
+
apiPrefix: ${config.apiPrefix ? `"${config.apiPrefix}"` : "undefined"},
|
|
387
|
+
userAgent: ${config.userAgent},
|
|
388
|
+
ip: ${config.ip},
|
|
389
|
+
cors: ${config.cors},
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
export default config;
|
|
393
|
+
`;
|
|
394
|
+
if (!fs.existsSync(configDir)) fs.mkdirSync(configDir, { recursive: true });
|
|
395
|
+
fs.writeFileSync(configFilePath, configContent);
|
|
396
|
+
Logger_default.info("\u2713 src/config/index.ts \u5DF2\u5C31\u7EEA");
|
|
397
|
+
if (config.staticPath) {
|
|
398
|
+
const staticDir = path2.join(cwd, config.staticPath);
|
|
399
|
+
if (!fs.existsSync(staticDir)) {
|
|
400
|
+
fs.mkdirSync(staticDir, { recursive: true });
|
|
401
|
+
Logger_default.info(`\u2713 \u9759\u6001\u76EE\u5F55\u5DF2\u521B\u5EFA: ${config.staticPath}`);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
function setupDrizzleConfig(cwd, config) {
|
|
406
|
+
const drizzleConfigPath = path2.join(cwd, "drizzle.config.ts");
|
|
407
|
+
const drizzleConfigContent = `import { defineConfig } from "drizzle-kit";
|
|
408
|
+
import fs from "fs";
|
|
409
|
+
|
|
410
|
+
// \u52A8\u6001\u8BFB\u53D6\u7531 db:sync \u811A\u672C\u751F\u6210\u7684 schema \u8DEF\u5F84\u6E05\u5355
|
|
411
|
+
const schemaJson = "./.drizzle-schemas.json";
|
|
412
|
+
const schemas = fs.existsSync(schemaJson)
|
|
413
|
+
? JSON.parse(fs.readFileSync(schemaJson, "utf-8"))
|
|
414
|
+
: ["./src/**/*.schema.ts"];
|
|
415
|
+
|
|
416
|
+
export default defineConfig({
|
|
417
|
+
schema: schemas,
|
|
418
|
+
out: "./drizzle",
|
|
419
|
+
dialect: "sqlite",
|
|
420
|
+
dbCredentials: {
|
|
421
|
+
url: "${config.dbPath}",
|
|
422
|
+
},
|
|
423
|
+
});
|
|
424
|
+
`;
|
|
425
|
+
fs.writeFileSync(drizzleConfigPath, drizzleConfigContent);
|
|
426
|
+
Logger_default.info("\u2713 drizzle.config.ts \u5DF2\u5C31\u7EEA");
|
|
427
|
+
}
|
|
428
|
+
function setupTsConfig(cwd) {
|
|
429
|
+
const tsconfigPath = path2.join(cwd, "tsconfig.json");
|
|
430
|
+
if (!fs.existsSync(tsconfigPath)) {
|
|
431
|
+
const tsconfigContent = {
|
|
432
|
+
compilerOptions: {
|
|
433
|
+
target: "ESNext",
|
|
434
|
+
module: "CommonJS",
|
|
435
|
+
moduleResolution: "node",
|
|
436
|
+
baseUrl: ".",
|
|
437
|
+
paths: {
|
|
438
|
+
"#/*": ["src/*"]
|
|
439
|
+
},
|
|
440
|
+
strict: true,
|
|
441
|
+
esModuleInterop: true,
|
|
442
|
+
skipLibCheck: true,
|
|
443
|
+
forceConsistentCasingInFileNames: true,
|
|
444
|
+
experimentalDecorators: true,
|
|
445
|
+
emitDecoratorMetadata: true,
|
|
446
|
+
outDir: "dist"
|
|
447
|
+
},
|
|
448
|
+
include: ["src/**/*"],
|
|
449
|
+
exclude: ["node_modules"]
|
|
450
|
+
};
|
|
451
|
+
fs.writeFileSync(tsconfigPath, JSON.stringify(tsconfigContent, null, 2));
|
|
452
|
+
Logger_default.info("\u2713 tsconfig.json \u5DF2\u5C31\u7EEA");
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
function setupAppEntry(cwd) {
|
|
456
|
+
const appPath = path2.join(cwd, "src/app.ts");
|
|
457
|
+
if (!fs.existsSync(appPath)) {
|
|
458
|
+
const appContent = `import { createApp } from "@mindbase/express-common";
|
|
459
|
+
import config from "./config";
|
|
460
|
+
|
|
461
|
+
async function bootstrap() {
|
|
462
|
+
const app = await createApp(config);
|
|
463
|
+
|
|
464
|
+
// \u5728\u6B64\u5904\u4F7F\u7528\u63D2\u4EF6\u6216\u4E2D\u95F4\u4EF6
|
|
465
|
+
// app.use(...);
|
|
466
|
+
|
|
467
|
+
await app.startup();
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
bootstrap();
|
|
471
|
+
`;
|
|
472
|
+
if (!fs.existsSync(path2.join(cwd, "src"))) fs.mkdirSync(path2.join(cwd, "src"));
|
|
473
|
+
fs.writeFileSync(appPath, appContent);
|
|
474
|
+
Logger_default.info("\u2713 src/app.ts \u5DF2\u5C31\u7EEA");
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
function copyAssets(cwd) {
|
|
478
|
+
const ipdbPath = path2.join(cwd, "ipipfree.ipdb");
|
|
479
|
+
const sourceIpdb = path2.join(__dirname, "..", "..", "..", "common", "ipipfree.ipdb");
|
|
480
|
+
if (fs.existsSync(sourceIpdb)) {
|
|
481
|
+
if (!fs.existsSync(ipdbPath)) {
|
|
482
|
+
fs.copyFileSync(sourceIpdb, ipdbPath);
|
|
483
|
+
Logger_default.info("\u2713 ipipfree.ipdb \u5DF2\u5C31\u7EEA");
|
|
484
|
+
} else {
|
|
485
|
+
Logger_default.info("- ipipfree.ipdb \u5DF2\u5B58\u5728\uFF0C\u8DF3\u8FC7\u62F7\u8D1D");
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
Logger_default.warn(`! \u672A\u80FD\u627E\u5230 ipipfree.ipdb \u6E90\u6587\u4EF6: ${sourceIpdb}`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
function setupPrepareScript(cwd) {
|
|
492
|
+
const preparePath = path2.join(cwd, "prepare.js");
|
|
493
|
+
if (!fs.existsSync(preparePath)) {
|
|
494
|
+
const prepareContent = `require('ts-node').register({
|
|
495
|
+
transpileOnly: true
|
|
496
|
+
});
|
|
497
|
+
require('tsconfig-paths/register');
|
|
498
|
+
const { prepare } = require('@mindbase/express-common');
|
|
499
|
+
prepare();
|
|
500
|
+
`;
|
|
501
|
+
fs.writeFileSync(preparePath, prepareContent);
|
|
502
|
+
Logger_default.info("\u2713 prepare.js \u5DF2\u5C31\u7EEA");
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
function setupPrecacheScript(cwd) {
|
|
506
|
+
const precachePath = path2.join(cwd, "precache.js");
|
|
507
|
+
if (!fs.existsSync(precachePath)) {
|
|
508
|
+
const precacheContent = `require('ts-node').register({
|
|
509
|
+
transpileOnly: true
|
|
510
|
+
});
|
|
511
|
+
require('tsconfig-paths/register');
|
|
512
|
+
const { precache } = require('@mindbase/express-common');
|
|
513
|
+
precache();
|
|
514
|
+
`;
|
|
515
|
+
fs.writeFileSync(precachePath, precacheContent);
|
|
516
|
+
Logger_default.info("\u2713 precache.js \u5DF2\u5C31\u7EEA");
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
// src/utils/FrontendInitializer.ts
|
|
521
|
+
import fs2 from "fs";
|
|
522
|
+
import path3 from "path";
|
|
523
|
+
import prompts2 from "prompts";
|
|
524
|
+
async function collectFrontendConfig(cwd) {
|
|
525
|
+
const folderName = path3.basename(cwd);
|
|
526
|
+
const availableApps = getAvailableFrontendApps();
|
|
527
|
+
const response = await prompts2([
|
|
528
|
+
{
|
|
529
|
+
type: "text",
|
|
530
|
+
name: "name",
|
|
531
|
+
message: "\u9879\u76EE\u540D\u79F0",
|
|
532
|
+
initial: folderName,
|
|
533
|
+
validate: (value) => value.length > 0 || "\u9879\u76EE\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
type: "text",
|
|
537
|
+
name: "description",
|
|
538
|
+
message: "\u9879\u76EE\u63CF\u8FF0",
|
|
539
|
+
initial: "MindBase \u524D\u7AEF\u5E94\u7528"
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
type: "text",
|
|
543
|
+
name: "author",
|
|
544
|
+
message: "\u4F5C\u8005",
|
|
545
|
+
initial: ""
|
|
546
|
+
},
|
|
547
|
+
{
|
|
548
|
+
type: "number",
|
|
549
|
+
name: "port",
|
|
550
|
+
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"
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
type: "text",
|
|
556
|
+
name: "proxyTarget",
|
|
557
|
+
message: "API \u4EE3\u7406\u76EE\u6807\u5730\u5740",
|
|
558
|
+
initial: "http://localhost:3000"
|
|
559
|
+
},
|
|
560
|
+
{
|
|
561
|
+
type: "text",
|
|
562
|
+
name: "proxyPath",
|
|
563
|
+
message: "API \u4EE3\u7406\u8DEF\u5F84 (\u7559\u7A7A\u5219\u4E0D\u4EE3\u7406)",
|
|
564
|
+
initial: "/api"
|
|
565
|
+
},
|
|
566
|
+
{
|
|
567
|
+
type: "select",
|
|
568
|
+
name: "appType",
|
|
569
|
+
message: "\u9009\u62E9\u5E94\u7528\u5F62\u6001",
|
|
570
|
+
choices: availableApps.map((app) => ({
|
|
571
|
+
title: app.description,
|
|
572
|
+
value: app.name
|
|
573
|
+
})),
|
|
574
|
+
initial: 0
|
|
575
|
+
}
|
|
576
|
+
]);
|
|
577
|
+
if (Object.keys(response).length < 7) {
|
|
578
|
+
throw new Error("\u7528\u6237\u53D6\u6D88\u4E86\u521D\u59CB\u5316\u6D41\u7A0B");
|
|
579
|
+
}
|
|
580
|
+
Logger_default.info(`\u5DF2\u9009\u62E9\u5E94\u7528\u5F62\u6001: ${response.appType}`);
|
|
581
|
+
return response;
|
|
582
|
+
}
|
|
583
|
+
function setupFrontendPackageJson(cwd, config) {
|
|
584
|
+
const pkgPath = path3.join(cwd, "package.json");
|
|
585
|
+
let pkg = {};
|
|
586
|
+
if (fs2.existsSync(pkgPath)) {
|
|
587
|
+
pkg = JSON.parse(fs2.readFileSync(pkgPath, "utf-8"));
|
|
588
|
+
Logger_default.info("\u2713 \u68C0\u6D4B\u5230\u5DF2\u5B58\u5728\u7684 package.json\uFF0C\u6B63\u5728\u66F4\u65B0\u914D\u7F6E...");
|
|
589
|
+
} else {
|
|
590
|
+
pkg = {
|
|
591
|
+
name: config.name,
|
|
592
|
+
version: "1.0.0",
|
|
593
|
+
description: config.description,
|
|
594
|
+
author: config.author,
|
|
595
|
+
private: true,
|
|
596
|
+
type: "module"
|
|
597
|
+
};
|
|
598
|
+
Logger_default.info("\u2713 \u6B63\u5728\u751F\u6210 package.json...");
|
|
599
|
+
}
|
|
600
|
+
pkg.scripts = pkg.scripts || {};
|
|
601
|
+
pkg.scripts["start"] = "npm run dev";
|
|
602
|
+
pkg.scripts["dev"] = `vite --port ${config.port}`;
|
|
603
|
+
pkg.scripts["build"] = "vue-tsc -b && vite build";
|
|
604
|
+
pkg.scripts["preview"] = "vite preview";
|
|
605
|
+
const appPackage = getFrontendPackage(config.appType);
|
|
606
|
+
if (appPackage) {
|
|
607
|
+
pkg.dependencies = pkg.dependencies || {};
|
|
608
|
+
pkg.dependencies[appPackage] = "*";
|
|
609
|
+
}
|
|
610
|
+
pkg.devDependencies = pkg.devDependencies || {};
|
|
611
|
+
pkg.devDependencies["vue-tsc"] = "^2.2.0";
|
|
612
|
+
fs2.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
613
|
+
Logger_default.info("\u2713 package.json \u5DF2\u5C31\u7EEA");
|
|
614
|
+
}
|
|
615
|
+
function setupViteConfig(cwd, config) {
|
|
616
|
+
const viteConfigPath = path3.join(cwd, "vite.config.ts");
|
|
617
|
+
const proxyConfig = config.proxyPath ? `{
|
|
618
|
+
'${config.proxyPath}': {
|
|
619
|
+
target: '${config.proxyTarget}',
|
|
620
|
+
changeOrigin: true,
|
|
621
|
+
},
|
|
622
|
+
}` : "undefined";
|
|
623
|
+
const viteConfigContent = `import { createBaseConfig } from "@mindbase/vite";
|
|
624
|
+
|
|
625
|
+
export default createBaseConfig({
|
|
626
|
+
server: {
|
|
627
|
+
port: ${config.port},
|
|
628
|
+
proxy: ${proxyConfig},
|
|
629
|
+
},
|
|
630
|
+
});
|
|
631
|
+
`;
|
|
632
|
+
fs2.writeFileSync(viteConfigPath, viteConfigContent);
|
|
633
|
+
Logger_default.info("\u2713 vite.config.ts \u5DF2\u5C31\u7EEA");
|
|
634
|
+
}
|
|
635
|
+
function setupFrontendTsConfig(cwd) {
|
|
636
|
+
const tsconfigPath = path3.join(cwd, "tsconfig.json");
|
|
637
|
+
if (!fs2.existsSync(tsconfigPath)) {
|
|
638
|
+
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
|
+
compilerOptions: {
|
|
652
|
+
composite: true,
|
|
653
|
+
skipLibCheck: true,
|
|
654
|
+
module: "ESNext",
|
|
655
|
+
moduleResolution: "bundler",
|
|
656
|
+
allowSyntheticDefaultImports: true,
|
|
657
|
+
strict: true,
|
|
658
|
+
noEmit: true
|
|
659
|
+
},
|
|
660
|
+
include: ["vite.config.ts"]
|
|
661
|
+
};
|
|
662
|
+
fs2.writeFileSync(tsconfigNodePath, JSON.stringify(tsconfigNodeContent, null, 2));
|
|
663
|
+
Logger_default.info("\u2713 tsconfig.node.json \u5DF2\u5C31\u7EEA");
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
function setupIndexHtml(cwd, config) {
|
|
667
|
+
const htmlPath = path3.join(cwd, "index.html");
|
|
668
|
+
const htmlContent = `<!DOCTYPE html>
|
|
669
|
+
<html lang="zh-CN">
|
|
670
|
+
<head>
|
|
671
|
+
<meta charset="UTF-8" />
|
|
672
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
|
|
673
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
674
|
+
<title>${config.name}</title>
|
|
675
|
+
</head>
|
|
676
|
+
<body>
|
|
677
|
+
<div id="app"></div>
|
|
678
|
+
<script type="module" src="/src/main.ts"></script>
|
|
679
|
+
</body>
|
|
680
|
+
</html>
|
|
681
|
+
`;
|
|
682
|
+
fs2.writeFileSync(htmlPath, htmlContent);
|
|
683
|
+
Logger_default.info("\u2713 index.html \u5DF2\u5C31\u7EEA");
|
|
684
|
+
}
|
|
685
|
+
function setupAppFiles(cwd, config) {
|
|
686
|
+
const srcDir = path3.join(cwd, "src");
|
|
687
|
+
if (!fs2.existsSync(srcDir)) fs2.mkdirSync(srcDir, { recursive: true });
|
|
688
|
+
const mainContent = `import {
|
|
689
|
+
createMindBaseApp,
|
|
690
|
+
createGlobComponentMap,
|
|
691
|
+
} from "${getFrontendPackage(config.appType)}";
|
|
692
|
+
|
|
693
|
+
// \u521B\u5EFA\u5E94\u7528
|
|
694
|
+
const { app, pinia } = createMindBaseApp({
|
|
695
|
+
router: {},
|
|
696
|
+
componentMap: createGlobComponentMap(import.meta.glob("./views/**/*.vue"), "./views/"),
|
|
697
|
+
});
|
|
698
|
+
|
|
699
|
+
app.mount("#app");
|
|
700
|
+
`;
|
|
701
|
+
fs2.writeFileSync(path3.join(srcDir, "main.ts"), mainContent);
|
|
702
|
+
Logger_default.info("\u2713 src/main.ts \u5DF2\u5C31\u7EEA");
|
|
703
|
+
const appContent = `<template>
|
|
704
|
+
<router-view />
|
|
705
|
+
</template>
|
|
706
|
+
|
|
707
|
+
<script setup lang="ts">
|
|
708
|
+
// \u6839\u7EC4\u4EF6
|
|
709
|
+
</script>
|
|
710
|
+
|
|
711
|
+
<style>
|
|
712
|
+
html,
|
|
713
|
+
body,
|
|
714
|
+
#app {
|
|
715
|
+
margin: 0;
|
|
716
|
+
padding: 0;
|
|
717
|
+
width: 100%;
|
|
718
|
+
height: 100%;
|
|
719
|
+
}
|
|
720
|
+
</style>
|
|
721
|
+
`;
|
|
722
|
+
fs2.writeFileSync(path3.join(srcDir, "App.vue"), appContent);
|
|
723
|
+
Logger_default.info("\u2713 src/App.vue \u5DF2\u5C31\u7EEA");
|
|
724
|
+
const viewsDir = path3.join(srcDir, "views");
|
|
725
|
+
if (!fs2.existsSync(viewsDir)) fs2.mkdirSync(viewsDir);
|
|
726
|
+
const exampleView = `<template>
|
|
727
|
+
<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>
|
|
730
|
+
</div>
|
|
731
|
+
</template>
|
|
732
|
+
|
|
733
|
+
<script setup lang="ts">
|
|
734
|
+
// \u9875\u9762\u903B\u8F91
|
|
735
|
+
</script>
|
|
736
|
+
|
|
737
|
+
<style scoped>
|
|
738
|
+
.home {
|
|
739
|
+
padding: 20px;
|
|
740
|
+
}
|
|
741
|
+
</style>
|
|
742
|
+
`;
|
|
743
|
+
fs2.writeFileSync(path3.join(viewsDir, "index.vue"), exampleView);
|
|
744
|
+
Logger_default.info("\u2713 src/views/index.vue \u5DF2\u5C31\u7EEA");
|
|
745
|
+
}
|
|
746
|
+
function setupPublicDir(cwd) {
|
|
747
|
+
const publicDir = path3.join(cwd, "public");
|
|
748
|
+
if (!fs2.existsSync(publicDir)) {
|
|
749
|
+
fs2.mkdirSync(publicDir, { recursive: true });
|
|
750
|
+
Logger_default.info("\u2713 public \u76EE\u5F55\u5DF2\u521B\u5EFA");
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
function copyAdminAssets(cwd, config) {
|
|
754
|
+
if (config.appType !== "admin-app") {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
const sourceDir = path3.join(cwd, "../../packages/admin-app/style/mb-iconfont");
|
|
758
|
+
if (!fs2.existsSync(sourceDir)) {
|
|
759
|
+
Logger_default.warn("\u5B57\u4F53\u6E90\u76EE\u5F55\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7\u590D\u5236");
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
const targetDir = path3.join(cwd, "public/assets/mb-iconfont");
|
|
763
|
+
if (!fs2.existsSync(targetDir)) {
|
|
764
|
+
fs2.mkdirSync(targetDir, { recursive: true });
|
|
765
|
+
}
|
|
766
|
+
const fonts = ["iconfont.woff2", "iconfont.woff", "iconfont.ttf"];
|
|
767
|
+
let copiedCount = 0;
|
|
768
|
+
fonts.forEach((font) => {
|
|
769
|
+
const sourcePath = path3.join(sourceDir, font);
|
|
770
|
+
const targetPath = path3.join(targetDir, font);
|
|
771
|
+
if (fs2.existsSync(sourcePath)) {
|
|
772
|
+
fs2.copyFileSync(sourcePath, targetPath);
|
|
773
|
+
copiedCount++;
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
if (copiedCount > 0) {
|
|
777
|
+
Logger_default.info(`\u2713 \u5DF2\u590D\u5236 ${copiedCount} \u4E2A\u5B57\u4F53\u6587\u4EF6\u5230 public/assets/mb-iconfont/`);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
// src/commands/init/backend.ts
|
|
782
|
+
async function initBackend() {
|
|
783
|
+
const cwd = process.cwd();
|
|
784
|
+
Logger_default.info(`
|
|
785
|
+
\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 MindBase \u540E\u7AEF\u9879\u76EE: ${cwd}
|
|
786
|
+
`);
|
|
787
|
+
try {
|
|
788
|
+
const config = await collectBackendConfig(cwd);
|
|
789
|
+
setupBackendPackageJson(cwd, config);
|
|
790
|
+
setupAppConfig(cwd, config);
|
|
791
|
+
setupDrizzleConfig(cwd, config);
|
|
792
|
+
setupTsConfig(cwd);
|
|
793
|
+
setupAppEntry(cwd);
|
|
794
|
+
copyAssets(cwd);
|
|
795
|
+
setupPrepareScript(cwd);
|
|
796
|
+
setupPrecacheScript(cwd);
|
|
797
|
+
Logger_default.info("\n\u2728 \u540E\u7AEF\u9879\u76EE\u521D\u59CB\u5316\u6210\u529F\uFF01\u5EFA\u8BAE\u8FD0\u884C: npm install\n");
|
|
798
|
+
} catch (err) {
|
|
799
|
+
throw err;
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
// src/commands/init/frontend.ts
|
|
804
|
+
async function initFrontend() {
|
|
805
|
+
const cwd = process.cwd();
|
|
806
|
+
Logger_default.info(`
|
|
807
|
+
\u{1F680} \u6B63\u5728\u521D\u59CB\u5316 MindBase \u524D\u7AEF\u9879\u76EE: ${cwd}
|
|
808
|
+
`);
|
|
809
|
+
try {
|
|
810
|
+
const config = await collectFrontendConfig(cwd);
|
|
811
|
+
setupFrontendPackageJson(cwd, config);
|
|
812
|
+
setupViteConfig(cwd, config);
|
|
813
|
+
setupFrontendTsConfig(cwd);
|
|
814
|
+
setupIndexHtml(cwd, config);
|
|
815
|
+
setupAppFiles(cwd, config);
|
|
816
|
+
setupPublicDir(cwd);
|
|
817
|
+
copyAdminAssets(cwd, config);
|
|
818
|
+
Logger_default.info("\n\u2728 \u524D\u7AEF\u9879\u76EE\u521D\u59CB\u5316\u6210\u529F\uFF01\u5EFA\u8BAE\u8FD0\u884C: npm install\n");
|
|
819
|
+
} catch (err) {
|
|
820
|
+
throw err;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
// src/commands/init/index.ts
|
|
825
|
+
async function init(type) {
|
|
826
|
+
switch (type) {
|
|
827
|
+
case "backend":
|
|
828
|
+
await initBackend();
|
|
829
|
+
break;
|
|
830
|
+
case "frontend":
|
|
831
|
+
await initFrontend();
|
|
832
|
+
break;
|
|
833
|
+
case "admin":
|
|
834
|
+
await initAdmin();
|
|
835
|
+
break;
|
|
836
|
+
default:
|
|
837
|
+
console.log(`
|
|
838
|
+
\u7528\u6CD5: mindbase init <type>
|
|
839
|
+
|
|
840
|
+
\u7C7B\u578B:
|
|
841
|
+
backend \u521D\u59CB\u5316\u540E\u7AEF\u9879\u76EE
|
|
842
|
+
frontend \u521D\u59CB\u5316\u524D\u7AEF\u9879\u76EE
|
|
843
|
+
admin \u5FEB\u6377\uFF1A\u521D\u59CB\u5316\u5B8C\u6574\u7BA1\u7406\u540E\u53F0\uFF08\u524D\u540E\u7AEF\u4E00\u4F53\uFF09
|
|
844
|
+
`);
|
|
845
|
+
break;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
async function initAdmin() {
|
|
849
|
+
console.log("\n\u{1F3AF} \u6B63\u5728\u521D\u59CB\u5316\u5B8C\u6574\u7BA1\u7406\u540E\u53F0...\n");
|
|
850
|
+
console.log("\u7B2C\u4E00\u6B65\uFF1A\u521D\u59CB\u5316\u540E\u7AEF");
|
|
851
|
+
await initBackend();
|
|
852
|
+
console.log("\n\u7B2C\u4E8C\u6B65\uFF1A\u521D\u59CB\u5316\u524D\u7AEF");
|
|
853
|
+
await initFrontend();
|
|
854
|
+
console.log("\n\u2728 \u5B8C\u6574\u7BA1\u7406\u540E\u53F0\u521D\u59CB\u5316\u6210\u529F\uFF01");
|
|
855
|
+
console.log("\n\u540E\u7EED\u6B65\u9AA4\uFF1A");
|
|
856
|
+
console.log(" 1. cd backend && npm install && npm run dev");
|
|
857
|
+
console.log(" 2. cd frontend && npm install && npm run dev");
|
|
858
|
+
console.log(" 3. \u524D\u7AEF\u4F1A\u81EA\u52A8\u4EE3\u7406 API \u5230\u540E\u7AEF http://localhost:3000\n");
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
export {
|
|
862
|
+
logger,
|
|
863
|
+
BACKEND_MODULES,
|
|
864
|
+
FRONTEND_APP_TYPES,
|
|
865
|
+
resolveDependencies,
|
|
866
|
+
getModulePackage,
|
|
867
|
+
getFrontendPackage,
|
|
868
|
+
getAvailableFrontendApps,
|
|
869
|
+
collectBackendConfig,
|
|
870
|
+
setupBackendPackageJson,
|
|
871
|
+
setupAppConfig,
|
|
872
|
+
setupDrizzleConfig,
|
|
873
|
+
setupTsConfig,
|
|
874
|
+
setupAppEntry,
|
|
875
|
+
copyAssets,
|
|
876
|
+
setupPrepareScript,
|
|
877
|
+
setupPrecacheScript,
|
|
878
|
+
collectFrontendConfig,
|
|
879
|
+
setupFrontendPackageJson,
|
|
880
|
+
setupViteConfig,
|
|
881
|
+
setupFrontendTsConfig,
|
|
882
|
+
setupIndexHtml,
|
|
883
|
+
setupAppFiles,
|
|
884
|
+
setupPublicDir,
|
|
885
|
+
init
|
|
886
|
+
};
|
|
887
|
+
//# sourceMappingURL=chunk-375GNKXH.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","/**\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"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
type LogLevel = "debug" | "info" | "warn" | "error" | "silent";
|
|
2
|
+
declare const logger: {
|
|
3
|
+
debug(...args: any[]): void;
|
|
4
|
+
info(...args: any[]): void;
|
|
5
|
+
warn(...args: any[]): void;
|
|
6
|
+
error(...args: any[]): void;
|
|
7
|
+
startup(tagOrMessage: string, ...args: any[]): void;
|
|
8
|
+
setLevel(level: LogLevel): void;
|
|
9
|
+
getLevel(): LogLevel;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 后端模块定义
|
|
14
|
+
*/
|
|
15
|
+
declare const BACKEND_MODULES: Array<{
|
|
16
|
+
name: string;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
description: string;
|
|
19
|
+
package: string;
|
|
20
|
+
dependencies?: string[];
|
|
21
|
+
}>;
|
|
22
|
+
/**
|
|
23
|
+
* 前端应用形态定义
|
|
24
|
+
*/
|
|
25
|
+
declare const FRONTEND_APP_TYPES: Array<{
|
|
26
|
+
name: string;
|
|
27
|
+
description: string;
|
|
28
|
+
package: string;
|
|
29
|
+
available: boolean;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* 解析模块依赖关系
|
|
33
|
+
* @param selectedModules 用户选择的模块列表
|
|
34
|
+
* @returns 包含所有依赖的完整模块列表
|
|
35
|
+
*/
|
|
36
|
+
declare function resolveDependencies(selectedModules: string[]): string[];
|
|
37
|
+
/**
|
|
38
|
+
* 获取模块的包名
|
|
39
|
+
* @param moduleName 模块名称
|
|
40
|
+
* @returns npm 包名
|
|
41
|
+
*/
|
|
42
|
+
declare function getModulePackage(moduleName: string): string | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* 获取前端应用的包名
|
|
45
|
+
* @param appType 应用类型
|
|
46
|
+
* @returns npm 包名
|
|
47
|
+
*/
|
|
48
|
+
declare function getFrontendPackage(appType: string): string | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* 获取可用的前端应用列表
|
|
51
|
+
* @returns 可用的应用类型列表
|
|
52
|
+
*/
|
|
53
|
+
declare function getAvailableFrontendApps(): {
|
|
54
|
+
name: string;
|
|
55
|
+
description: string;
|
|
56
|
+
package: string;
|
|
57
|
+
available: boolean;
|
|
58
|
+
}[];
|
|
59
|
+
|
|
60
|
+
interface BackendConfig {
|
|
61
|
+
name: string;
|
|
62
|
+
description: string;
|
|
63
|
+
author: string;
|
|
64
|
+
port: number;
|
|
65
|
+
dbPath: string;
|
|
66
|
+
staticPath: string;
|
|
67
|
+
apiPrefix: string;
|
|
68
|
+
userAgent: boolean;
|
|
69
|
+
ip: boolean;
|
|
70
|
+
cors: boolean;
|
|
71
|
+
logLevel: "debug" | "info" | "warn" | "error" | "silent";
|
|
72
|
+
modules: string[];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* 收集后端项目初始化配置
|
|
76
|
+
*/
|
|
77
|
+
declare function collectBackendConfig(cwd: string): Promise<BackendConfig>;
|
|
78
|
+
/**
|
|
79
|
+
* 初始化 package.json
|
|
80
|
+
*/
|
|
81
|
+
declare function setupBackendPackageJson(cwd: string, config: BackendConfig): void;
|
|
82
|
+
/**
|
|
83
|
+
* 初始化应用配置 src/config/index.ts
|
|
84
|
+
*/
|
|
85
|
+
declare function setupAppConfig(cwd: string, config: BackendConfig): void;
|
|
86
|
+
/**
|
|
87
|
+
* 初始化 Drizzle 配置 drizzle.config.ts
|
|
88
|
+
*/
|
|
89
|
+
declare function setupDrizzleConfig(cwd: string, config: BackendConfig): void;
|
|
90
|
+
/**
|
|
91
|
+
* 初始化 TypeScript 配置 tsconfig.json
|
|
92
|
+
*/
|
|
93
|
+
declare function setupTsConfig(cwd: string): void;
|
|
94
|
+
/**
|
|
95
|
+
* 初始化应用入口 src/app.ts
|
|
96
|
+
*/
|
|
97
|
+
declare function setupAppEntry(cwd: string): void;
|
|
98
|
+
/**
|
|
99
|
+
* 拷贝静态资源
|
|
100
|
+
*/
|
|
101
|
+
declare function copyAssets(cwd: string): void;
|
|
102
|
+
/**
|
|
103
|
+
* 生成 prepare.js 环境准备脚本
|
|
104
|
+
*/
|
|
105
|
+
declare function setupPrepareScript(cwd: string): void;
|
|
106
|
+
/**
|
|
107
|
+
* 生成 precache.js 预缓存脚本
|
|
108
|
+
*/
|
|
109
|
+
declare function setupPrecacheScript(cwd: string): void;
|
|
110
|
+
|
|
111
|
+
interface FrontendConfig {
|
|
112
|
+
name: string;
|
|
113
|
+
description: string;
|
|
114
|
+
author: string;
|
|
115
|
+
port: number;
|
|
116
|
+
proxyTarget: string;
|
|
117
|
+
proxyPath: string;
|
|
118
|
+
appType: string;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* 收集前端项目初始化配置
|
|
122
|
+
*/
|
|
123
|
+
declare function collectFrontendConfig(cwd: string): Promise<FrontendConfig>;
|
|
124
|
+
/**
|
|
125
|
+
* 初始化 package.json
|
|
126
|
+
*/
|
|
127
|
+
declare function setupFrontendPackageJson(cwd: string, config: FrontendConfig): void;
|
|
128
|
+
/**
|
|
129
|
+
* 初始化 Vite 配置 vite.config.ts
|
|
130
|
+
*/
|
|
131
|
+
declare function setupViteConfig(cwd: string, config: FrontendConfig): void;
|
|
132
|
+
/**
|
|
133
|
+
* 初始化 TypeScript 配置
|
|
134
|
+
*/
|
|
135
|
+
declare function setupFrontendTsConfig(cwd: string): void;
|
|
136
|
+
/**
|
|
137
|
+
* 初始化 index.html
|
|
138
|
+
*/
|
|
139
|
+
declare function setupIndexHtml(cwd: string, config: FrontendConfig): void;
|
|
140
|
+
/**
|
|
141
|
+
* 初始化源文件
|
|
142
|
+
*/
|
|
143
|
+
declare function setupAppFiles(cwd: string, config: FrontendConfig): void;
|
|
144
|
+
/**
|
|
145
|
+
* 创建 public 目录
|
|
146
|
+
*/
|
|
147
|
+
declare function setupPublicDir(cwd: string): void;
|
|
148
|
+
|
|
149
|
+
declare function init(type?: string): Promise<void>;
|
|
150
|
+
|
|
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 };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BACKEND_MODULES,
|
|
3
|
+
FRONTEND_APP_TYPES,
|
|
4
|
+
collectBackendConfig,
|
|
5
|
+
collectFrontendConfig,
|
|
6
|
+
copyAssets,
|
|
7
|
+
getAvailableFrontendApps,
|
|
8
|
+
getFrontendPackage,
|
|
9
|
+
getModulePackage,
|
|
10
|
+
init,
|
|
11
|
+
logger,
|
|
12
|
+
resolveDependencies,
|
|
13
|
+
setupAppConfig,
|
|
14
|
+
setupAppEntry,
|
|
15
|
+
setupAppFiles,
|
|
16
|
+
setupBackendPackageJson,
|
|
17
|
+
setupDrizzleConfig,
|
|
18
|
+
setupFrontendPackageJson,
|
|
19
|
+
setupFrontendTsConfig,
|
|
20
|
+
setupIndexHtml,
|
|
21
|
+
setupPrecacheScript,
|
|
22
|
+
setupPrepareScript,
|
|
23
|
+
setupPublicDir,
|
|
24
|
+
setupTsConfig,
|
|
25
|
+
setupViteConfig
|
|
26
|
+
} from "./chunk-375GNKXH.js";
|
|
27
|
+
export {
|
|
28
|
+
BACKEND_MODULES,
|
|
29
|
+
FRONTEND_APP_TYPES,
|
|
30
|
+
collectBackendConfig,
|
|
31
|
+
collectFrontendConfig,
|
|
32
|
+
copyAssets,
|
|
33
|
+
logger as default,
|
|
34
|
+
getAvailableFrontendApps,
|
|
35
|
+
getFrontendPackage,
|
|
36
|
+
getModulePackage,
|
|
37
|
+
init,
|
|
38
|
+
resolveDependencies,
|
|
39
|
+
setupAppConfig,
|
|
40
|
+
setupAppEntry,
|
|
41
|
+
setupAppFiles,
|
|
42
|
+
setupBackendPackageJson,
|
|
43
|
+
setupDrizzleConfig,
|
|
44
|
+
setupFrontendPackageJson,
|
|
45
|
+
setupFrontendTsConfig,
|
|
46
|
+
setupIndexHtml,
|
|
47
|
+
setupPrecacheScript,
|
|
48
|
+
setupPrepareScript,
|
|
49
|
+
setupPublicDir,
|
|
50
|
+
setupTsConfig,
|
|
51
|
+
setupViteConfig
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mindbase/cli",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"mindbase": "./dist/bin/mindbase.js"
|
|
9
|
+
},
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"import": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"./bin/*": "./dist/bin/*.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist"
|
|
19
|
+
],
|
|
20
|
+
"engines": {
|
|
21
|
+
"node": ">=20.0.0"
|
|
22
|
+
},
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"prompts": "^2.4.2",
|
|
25
|
+
"radash": "12.1.1"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@types/prompts": "^2.4.9",
|
|
29
|
+
"tsup": "^8.0.0",
|
|
30
|
+
"typescript": "^5.1.3"
|
|
31
|
+
},
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "tsup",
|
|
34
|
+
"build:watch": "tsup --watch",
|
|
35
|
+
"prepublishOnly": "npm run build"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
}
|
|
40
|
+
}
|