@mindbase/cli 1.0.14 → 1.0.16

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.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  init
4
- } from "../chunk-6QWYOGLJ.js";
4
+ } from "../chunk-N7POXTPM.js";
5
5
 
6
6
  // src/bin/mindbase.ts
7
7
  var args = process.argv.slice(2);
@@ -403,11 +403,10 @@ function setupBackendPackageJson(cwd, config) {
403
403
  pkg.scripts["start"] = "ts-node --transpile-only --require tsconfig-paths/register ./src/app";
404
404
  pkg.scripts["prepare-data"] = "ts-node prepare.js";
405
405
  pkg.scripts["init-admin"] = "mindbase-auth init-admin";
406
- pkg.scripts["db:generate"] = "drizzle-kit generate";
407
- pkg.scripts["db:migrate"] = "drizzle-kit migrate";
406
+ pkg.scripts["db:generate"] = "drizzle-kit generate --config drizzle.config.cjs";
407
+ pkg.scripts["db:migrate"] = "drizzle-kit migrate --config drizzle.config.cjs";
408
408
  pkg.scripts["init"] = "npm run prepare-data && npm run db:generate && npm run db:migrate && npm run init-admin";
409
- pkg.scripts["db:push"] = "drizzle-kit push";
410
- pkg.scripts["db:studio"] = "drizzle-kit studio";
409
+ pkg.scripts["db:studio"] = "drizzle-kit studio --config drizzle.config.cjs";
411
410
  pkg.dependencies["@mindbase/express-common"] = "^1.0.0";
412
411
  for (const module of config.modules) {
413
412
  const packageName = module.package;
@@ -457,7 +456,7 @@ function setupDrizzleConfig(cwd, config) {
457
456
  const drizzleConfigContent = `const fs = require("fs");
458
457
 
459
458
  // \u52A8\u6001\u8BFB\u53D6\u7531 db:sync \u811A\u672C\u751F\u6210\u7684 schema \u8DEF\u5F84\u6E05\u5355
460
- const schemaJson = "./.drizzle-schemas.json";
459
+ const schemaJson = "./drizzle-schemas.json";
461
460
  const schemas = fs.existsSync(schemaJson)
462
461
  ? JSON.parse(fs.readFileSync(schemaJson, "utf-8"))
463
462
  : ["./src/**/*.schema.ts"];
@@ -978,4 +977,4 @@ export {
978
977
  setupPublicDir,
979
978
  init
980
979
  };
981
- //# sourceMappingURL=chunk-6QWYOGLJ.js.map
980
+ //# sourceMappingURL=chunk-N7POXTPM.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 type: \"module\",\n private: true,\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.45.1\",\n \"drizzle-zod\": \"^0.5.1\",\n express: \"^5.2.1\",\n \"express-art-template\": \"^1.0.1\",\n \"fs-extra\": \"^11.2.0\",\n glob: \"^11.0.0\",\n \"ipip-ipdb\": \"^0.6.0\",\n \"mime-types\": \"^2.1.35\",\n multer: \"^2.0.0\",\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/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\"] = \"ts-node-dev --transpile-only --require tsconfig-paths/register ./src/app\";\n pkg.scripts[\"debugger\"] = \"node --inspect-brk=9229 -r ts-node/register -r tsconfig-paths/register ./src/app\";\n pkg.scripts[\"start\"] = \"ts-node --transpile-only --require tsconfig-paths/register ./src/app\";\n pkg.scripts[\"prepare-data\"] = \"ts-node prepare.js\";\n pkg.scripts[\"init-admin\"] = \"mindbase-auth init-admin\";\n pkg.scripts[\"db:generate\"] = \"drizzle-kit generate --config drizzle.config.cjs\";\n pkg.scripts[\"db:migrate\"] = \"drizzle-kit migrate --config drizzle.config.cjs\";\n pkg.scripts[\"init\"] = \"npm run prepare-data && npm run db:generate && npm run db:migrate && npm run init-admin\";\n pkg.scripts[\"db:studio\"] = \"drizzle-kit studio --config drizzle.config.cjs\";\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.cjs\");\n const drizzleConfigContent = `const fs = require(\"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\nmodule.exports = {\n schema: schemas,\n out: \"./drizzle\",\n dialect: \"sqlite\",\n dbCredentials: {\n url: \"./data/app.db\",\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 baseUrl: \".\",\n target: \"ES2022\",\n module: \"CommonJS\",\n lib: [\"ES2022\"],\n moduleResolution: \"node\",\n esModuleInterop: true,\n allowSyntheticDefaultImports: true,\n strict: false,\n noImplicitAny: false,\n strictNullChecks: false,\n strictFunctionTypes: false,\n strictBindCallApply: false,\n strictPropertyInitialization: false,\n noImplicitThis: false,\n alwaysStrict: false,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: false,\n resolveJsonModule: true,\n declaration: true,\n declarationMap: true,\n sourceMap: true,\n experimentalDecorators: false,\n emitDecoratorMetadata: false,\n noUnusedLocals: false,\n noUnusedParameters: false,\n noImplicitReturns: false,\n noFallthroughCasesInSwitch: false,\n isolatedModules: false,\n allowJs: true,\n checkJs: false,\n paths: {\n \"#/*\": [\"src/*\"],\n },\n outDir: \"dist\",\n },\n include: [\"src/**/*\"],\n exclude: [\"node_modules\"],\n \"ts-node\": {\n require: [\"tsconfig-paths/register\"],\n compilerOptions: {\n sourceMap: true,\n },\n },\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 = `import { prepare } from '@mindbase/express-common';\nprepare();`;\n fs.writeFileSync(preparePath, prepareContent);\n logger.info(\"✓ prepare.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.13.0\",\n \"@element-plus/icons-vue\": \"^2.3.2\",\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 \"sass-embedded\": \"^1.79.4\",\n typescript: \"^5.6.0\",\n vite: \"^5.4.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`;\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 commonjs from 'vite-plugin-commonjs'\nimport { fileURLToPath, URL } from 'node:url'\n\nexport default defineConfig({\n plugins: [vue(),commonjs({\n filter(id) {\n if (id.includes('node_modules/dayjs')) {\n return true\n }\n if (id.includes('node_modules/spark-md5')) {\n return true\n }\n }\n })],\n resolve: {\n alias: [\n { find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) },\n ]\n },\n optimizeDeps: {\n include: [\n 'dayjs',\n 'spark-md5',\n 'dayjs/plugin/*' \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} 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\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.js CHANGED
@@ -21,7 +21,7 @@ import {
21
21
  setupPublicDir,
22
22
  setupTsConfig,
23
23
  setupViteConfig
24
- } from "./chunk-6QWYOGLJ.js";
24
+ } from "./chunk-N7POXTPM.js";
25
25
  export {
26
26
  BACKEND_MODULES,
27
27
  FRONTEND_APP_TYPES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mindbase/cli",
3
- "version": "1.0.14",
3
+ "version": "1.0.16",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "mindbase": "./dist/bin/mindbase.js"
@@ -30,4 +30,4 @@
30
30
  "publishConfig": {
31
31
  "access": "public"
32
32
  }
33
- }
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","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 type: \"module\",\n private: true,\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.45.1\",\n \"drizzle-zod\": \"^0.5.1\",\n express: \"^5.2.1\",\n \"express-art-template\": \"^1.0.1\",\n \"fs-extra\": \"^11.2.0\",\n glob: \"^11.0.0\",\n \"ipip-ipdb\": \"^0.6.0\",\n \"mime-types\": \"^2.1.35\",\n multer: \"^2.0.0\",\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/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\"] = \"ts-node-dev --transpile-only --require tsconfig-paths/register ./src/app\";\n pkg.scripts[\"debugger\"] = \"node --inspect-brk=9229 -r ts-node/register -r tsconfig-paths/register ./src/app\";\n pkg.scripts[\"start\"] = \"ts-node --transpile-only --require tsconfig-paths/register ./src/app\";\n pkg.scripts[\"prepare-data\"] = \"ts-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-data && 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.cjs\");\n const drizzleConfigContent = `const fs = require(\"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\nmodule.exports = {\n schema: schemas,\n out: \"./drizzle\",\n dialect: \"sqlite\",\n dbCredentials: {\n url: \"./data/app.db\",\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 baseUrl: \".\",\n target: \"ES2022\",\n module: \"CommonJS\",\n lib: [\"ES2022\"],\n moduleResolution: \"node\",\n esModuleInterop: true,\n allowSyntheticDefaultImports: true,\n strict: false,\n noImplicitAny: false,\n strictNullChecks: false,\n strictFunctionTypes: false,\n strictBindCallApply: false,\n strictPropertyInitialization: false,\n noImplicitThis: false,\n alwaysStrict: false,\n skipLibCheck: true,\n forceConsistentCasingInFileNames: false,\n resolveJsonModule: true,\n declaration: true,\n declarationMap: true,\n sourceMap: true,\n experimentalDecorators: false,\n emitDecoratorMetadata: false,\n noUnusedLocals: false,\n noUnusedParameters: false,\n noImplicitReturns: false,\n noFallthroughCasesInSwitch: false,\n isolatedModules: false,\n allowJs: true,\n checkJs: false,\n paths: {\n \"#/*\": [\"src/*\"],\n },\n outDir: \"dist\",\n },\n include: [\"src/**/*\"],\n exclude: [\"node_modules\"],\n \"ts-node\": {\n require: [\"tsconfig-paths/register\"],\n compilerOptions: {\n sourceMap: true,\n },\n },\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 = `import { prepare } from '@mindbase/express-common';\nprepare();`;\n fs.writeFileSync(preparePath, prepareContent);\n logger.info(\"✓ prepare.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.13.0\",\n \"@element-plus/icons-vue\": \"^2.3.2\",\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 \"sass-embedded\": \"^1.79.4\",\n typescript: \"^5.6.0\",\n vite: \"^5.4.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`;\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 commonjs from 'vite-plugin-commonjs'\nimport { fileURLToPath, URL } from 'node:url'\n\nexport default defineConfig({\n plugins: [vue(),commonjs({\n filter(id) {\n if (id.includes('node_modules/dayjs')) {\n return true\n }\n if (id.includes('node_modules/spark-md5')) {\n return true\n }\n }\n })],\n resolve: {\n alias: [\n { find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) },\n ]\n },\n optimizeDeps: {\n include: [\n 'dayjs',\n 'spark-md5',\n 'dayjs/plugin/*' \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} 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\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"]}