@moluoxixi/create-app 2.0.4 → 2.0.403

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.
Files changed (264) hide show
  1. package/LICENSE.txt +21 -21
  2. package/README.md +129 -129
  3. package/dist/commands/create.d.ts +2 -1
  4. package/dist/commands/create.js +12 -8
  5. package/dist/commands/index.d.ts +1 -2
  6. package/dist/commands/index.js +1 -2
  7. package/dist/constants/index.d.ts +17 -0
  8. package/dist/constants/index.js +17 -0
  9. package/dist/generators/index.d.ts +3 -4
  10. package/dist/generators/index.js +3 -4
  11. package/dist/generators/project.d.ts +3 -2
  12. package/dist/generators/project.js +5 -4
  13. package/dist/generators/react.d.ts +4 -2
  14. package/dist/generators/react.js +10 -30
  15. package/dist/generators/vue.d.ts +4 -2
  16. package/dist/generators/vue.js +10 -31
  17. package/dist/index.d.ts +0 -1
  18. package/dist/index.js +21 -3
  19. package/dist/test.d.ts +5 -2
  20. package/dist/test.js +252 -206
  21. package/dist/types/ejs.d.ts +0 -1
  22. package/dist/types/ejs.js +0 -1
  23. package/dist/types/features.d.ts +1 -2
  24. package/dist/types/features.js +1 -1
  25. package/dist/types/index.d.ts +2 -4
  26. package/dist/types/index.js +2 -4
  27. package/dist/types/packageJson.d.ts +24 -0
  28. package/dist/types/packageJson.js +4 -0
  29. package/dist/types/viteConfig.d.ts +11 -9
  30. package/dist/types/viteConfig.js +0 -1
  31. package/dist/utils/deepMerge.d.ts +3 -1
  32. package/dist/utils/deepMerge.js +8 -1
  33. package/dist/utils/ejs.d.ts +3 -2
  34. package/dist/utils/ejs.js +2 -1
  35. package/dist/utils/featureMapping.d.ts +44 -0
  36. package/dist/utils/featureMapping.js +119 -0
  37. package/dist/utils/file.d.ts +22 -2
  38. package/dist/utils/file.js +35 -2
  39. package/dist/utils/generateFrameworkProject.d.ts +27 -0
  40. package/dist/utils/generateFrameworkProject.js +47 -0
  41. package/dist/utils/index.d.ts +11 -9
  42. package/dist/utils/index.js +11 -9
  43. package/dist/utils/install.d.ts +7 -4
  44. package/dist/utils/install.js +55 -12
  45. package/dist/utils/npmConfig.d.ts +15 -0
  46. package/dist/utils/npmConfig.js +79 -0
  47. package/dist/utils/prompts.d.ts +3 -2
  48. package/dist/utils/prompts.js +51 -5
  49. package/dist/utils/renderFeatures.d.ts +3 -2
  50. package/dist/utils/renderFeatures.js +41 -37
  51. package/dist/utils/renderTemplate.d.ts +13 -1
  52. package/dist/utils/renderTemplate.js +128 -61
  53. package/dist/utils/sortDependencies.d.ts +3 -2
  54. package/dist/utils/sortDependencies.js +3 -2
  55. package/dist/utils/viteConfigRender.d.ts +11 -14
  56. package/dist/utils/viteConfigRender.js +10 -173
  57. package/package.json +4 -2
  58. package/templates/common/base/.env +7 -7
  59. package/templates/common/base/.env.development +5 -5
  60. package/templates/common/base/.env.production +5 -5
  61. package/templates/common/base/package.json +23 -27
  62. package/templates/common/base/scripts/build.mts +37 -31
  63. package/templates/common/base/src/apis/index.ts +8 -8
  64. package/templates/common/base/src/apis/request.ts +43 -43
  65. package/templates/common/base/src/apis/services/example.ts +61 -40
  66. package/templates/common/base/src/apis/services/user.ts +33 -23
  67. package/templates/common/base/src/apis/types/common.ts +43 -28
  68. package/templates/common/base/src/apis/types/example.ts +15 -3
  69. package/templates/common/base/src/apis/types/index.ts +7 -7
  70. package/templates/common/base/src/apis/types/user.ts +39 -24
  71. package/templates/common/base/src/assets/fonts/index.css +7 -7
  72. package/templates/common/base/src/assets/styles/base.scss +72 -72
  73. package/templates/common/base/src/assets/styles/custom.scss +7 -7
  74. package/templates/common/base/src/assets/styles/tailwind.scss +6 -6
  75. package/templates/common/base/src/constants/index.ts +29 -29
  76. package/templates/common/base/src/utils/index.ts +88 -83
  77. package/templates/{vue/base/vite.config.ts → common/base/vite.config.ts.ejs} +28 -11
  78. package/templates/common/features/husky/.cz-config.cjs +35 -35
  79. package/templates/common/features/husky/commitlint.config.ts +32 -32
  80. package/templates/common/features/husky/node_modules/.bin/commitizen +17 -0
  81. package/templates/common/features/husky/node_modules/.bin/commitizen.CMD +12 -0
  82. package/templates/common/features/husky/node_modules/.bin/commitizen.ps1 +41 -0
  83. package/templates/common/features/husky/node_modules/.bin/commitlint +17 -0
  84. package/templates/common/features/husky/node_modules/.bin/commitlint.CMD +12 -0
  85. package/templates/common/features/husky/node_modules/.bin/commitlint.ps1 +41 -0
  86. package/templates/common/features/husky/node_modules/.bin/cz +17 -0
  87. package/templates/common/features/husky/node_modules/.bin/cz-cust +17 -0
  88. package/templates/common/features/husky/node_modules/.bin/cz-cust.CMD +12 -0
  89. package/templates/common/features/husky/node_modules/.bin/cz-cust.ps1 +41 -0
  90. package/templates/common/features/husky/node_modules/.bin/cz-customizable +17 -0
  91. package/templates/common/features/husky/node_modules/.bin/cz-customizable.CMD +12 -0
  92. package/templates/common/features/husky/node_modules/.bin/cz-customizable.ps1 +41 -0
  93. package/templates/common/features/husky/node_modules/.bin/cz.CMD +12 -0
  94. package/templates/common/features/husky/node_modules/.bin/cz.ps1 +41 -0
  95. package/templates/common/features/husky/node_modules/.bin/git-cz +17 -0
  96. package/templates/common/features/husky/node_modules/.bin/git-cz.CMD +12 -0
  97. package/templates/common/features/husky/node_modules/.bin/git-cz.ps1 +41 -0
  98. package/templates/common/features/husky/node_modules/.bin/husky +17 -0
  99. package/templates/common/features/husky/node_modules/.bin/husky.CMD +12 -0
  100. package/templates/common/features/husky/node_modules/.bin/husky.ps1 +41 -0
  101. package/templates/common/features/husky/node_modules/.bin/lint-staged +17 -0
  102. package/templates/common/features/husky/node_modules/.bin/lint-staged.CMD +12 -0
  103. package/templates/common/features/husky/node_modules/.bin/lint-staged.ps1 +41 -0
  104. package/templates/common/features/husky/package.json +6 -6
  105. package/templates/react/base/env.d.ts +19 -19
  106. package/templates/react/base/index.html +14 -14
  107. package/templates/react/base/node_modules/.bin/vite +17 -0
  108. package/templates/react/base/node_modules/.bin/vite.CMD +12 -0
  109. package/templates/react/base/node_modules/.bin/vite.ps1 +41 -0
  110. package/templates/react/base/package.json +18 -15
  111. package/templates/react/base/src/App.tsx +18 -18
  112. package/templates/react/base/src/assets/styles/main.scss +8 -8
  113. package/templates/react/base/src/main.tsx.ejs +51 -6
  114. package/templates/react/base/src/pages/about/index.tsx +14 -14
  115. package/templates/react/base/src/pages/home/index.tsx +14 -14
  116. package/templates/react/base/tsconfig.app.json +17 -17
  117. package/templates/react/base/tsconfig.base.json +23 -23
  118. package/templates/react/base/tsconfig.json +12 -12
  119. package/templates/react/base/tsconfig.node.json +15 -15
  120. package/templates/react/features/ant-design/package.json +6 -7
  121. package/templates/react/features/eslint/node_modules/.bin/eslint +17 -0
  122. package/templates/react/features/eslint/node_modules/.bin/eslint.CMD +12 -0
  123. package/templates/react/features/eslint/node_modules/.bin/eslint.ps1 +41 -0
  124. package/templates/react/features/eslint/package.json +3 -3
  125. package/templates/react/features/i18n/package.json +6 -7
  126. package/templates/react/features/i18n/src/locales/index.ts +7 -0
  127. package/templates/{common/base → react/features/i18n}/src/locales/lang/en.ts +30 -30
  128. package/templates/{common/base → react/features/i18n}/src/locales/lang/es.ts +30 -30
  129. package/templates/{common/base → react/features/i18n}/src/locales/lang/zh.ts +30 -30
  130. package/templates/react/features/manualRoutes/src/router/routes.tsx +13 -0
  131. package/templates/react/features/pageRoutes/package.json +1 -2
  132. package/templates/react/features/qiankun/package.json +6 -0
  133. package/templates/react/features/qiankun/src/qiankun/index.ts +80 -0
  134. package/templates/react/features/router/package.json +1 -1
  135. package/templates/react/features/sentry/package.json +6 -7
  136. package/templates/react/features/sentry/src/utils/sentry.ts +10 -0
  137. package/templates/react/features/zustand/package.json +1 -1
  138. package/templates/react/features/zustand/src/stores/user.ts +42 -6
  139. package/templates/react/features/zustand/src/types/stores.ts +8 -1
  140. package/templates/vue/base/env.d.ts +27 -27
  141. package/templates/vue/base/index.html +14 -14
  142. package/templates/vue/base/node_modules/.bin/vite +17 -0
  143. package/templates/vue/base/node_modules/.bin/vite.CMD +12 -0
  144. package/templates/vue/base/node_modules/.bin/vite.ps1 +41 -0
  145. package/templates/vue/base/node_modules/.bin/vue-tsc +17 -0
  146. package/templates/vue/base/node_modules/.bin/vue-tsc.CMD +12 -0
  147. package/templates/vue/base/node_modules/.bin/vue-tsc.ps1 +41 -0
  148. package/templates/vue/base/package.json +16 -13
  149. package/templates/vue/base/src/App.vue +13 -13
  150. package/templates/vue/base/src/assets/styles/main.scss +9 -9
  151. package/templates/vue/base/src/directives/index.ts +36 -36
  152. package/templates/vue/base/src/layouts/index.ts +5 -7
  153. package/templates/vue/base/src/main.ts.ejs +9 -25
  154. package/templates/vue/base/src/pages/about/index.vue +31 -31
  155. package/templates/vue/base/src/pages/home/index.vue +31 -31
  156. package/templates/vue/base/src/router/index.ts.ejs +10 -13
  157. package/templates/vue/base/tsconfig.app.json +17 -17
  158. package/templates/vue/base/tsconfig.base.json +23 -23
  159. package/templates/vue/base/tsconfig.json +12 -12
  160. package/templates/vue/base/tsconfig.node.json +15 -15
  161. package/templates/vue/features/ant-design-vue/package.json +6 -7
  162. package/templates/vue/{base → features/ant-design-vue}/src/layouts/AntDesign.vue +86 -86
  163. package/templates/vue/features/element-plus/package.json +6 -7
  164. package/templates/vue/{base → features/element-plus}/src/assets/styles/element/index.scss +27 -27
  165. package/templates/vue/features/element-plus/src/components/SubMenu/index.ts +9 -0
  166. package/templates/vue/{base → features/element-plus}/src/components/SubMenu/src/_types/index.ts +6 -6
  167. package/templates/vue/{base → features/element-plus}/src/components/SubMenu/src/_types/props.ts +11 -11
  168. package/templates/vue/{base → features/element-plus}/src/components/SubMenu/src/index.vue +24 -24
  169. package/templates/vue/{base → features/element-plus}/src/layouts/element.vue +81 -81
  170. package/templates/vue/features/eslint/node_modules/.bin/eslint +17 -0
  171. package/templates/vue/features/eslint/node_modules/.bin/eslint.CMD +12 -0
  172. package/templates/vue/features/eslint/node_modules/.bin/eslint.ps1 +41 -0
  173. package/templates/vue/features/eslint/package.json +3 -3
  174. package/templates/vue/features/i18n/package.json +5 -5
  175. package/templates/vue/features/i18n/src/locales/index.ts +23 -16
  176. package/templates/vue/features/i18n/src/locales/lang/en.ts +30 -0
  177. package/templates/vue/features/i18n/src/locales/lang/es.ts +30 -0
  178. package/templates/vue/features/i18n/src/locales/lang/zh.ts +30 -0
  179. package/templates/vue/features/manualRoutes/src/router/routes.ts +35 -27
  180. package/templates/vue/features/pageRoutes/package.json +5 -5
  181. package/templates/vue/features/pinia/package.json +3 -2
  182. package/templates/vue/features/pinia/src/stores/index.ts +8 -0
  183. package/templates/vue/features/pinia/src/stores/system.ts +60 -0
  184. package/templates/vue/features/pinia/src/stores/user.ts +33 -13
  185. package/templates/vue/features/qiankun/package.json +5 -5
  186. package/templates/vue/features/qiankun/src/qiankun/index.ts +19 -0
  187. package/templates/vue/features/router/package.json +1 -1
  188. package/templates/vue/features/sentry/package.json +6 -6
  189. package/templates/vue/features/sentry/src/utils/sentry.ts +12 -0
  190. package/dist/commands/create.d.ts.map +0 -1
  191. package/dist/commands/create.js.map +0 -1
  192. package/dist/commands/index.d.ts.map +0 -1
  193. package/dist/commands/index.js.map +0 -1
  194. package/dist/generators/index.d.ts.map +0 -1
  195. package/dist/generators/index.js.map +0 -1
  196. package/dist/generators/project.d.ts.map +0 -1
  197. package/dist/generators/project.js.map +0 -1
  198. package/dist/generators/react.d.ts.map +0 -1
  199. package/dist/generators/react.js.map +0 -1
  200. package/dist/generators/vue.d.ts.map +0 -1
  201. package/dist/generators/vue.js.map +0 -1
  202. package/dist/index.d.ts.map +0 -1
  203. package/dist/index.js.map +0 -1
  204. package/dist/test.d.ts.map +0 -1
  205. package/dist/test.js.map +0 -1
  206. package/dist/types/ejs.d.ts.map +0 -1
  207. package/dist/types/ejs.js.map +0 -1
  208. package/dist/types/features.d.ts.map +0 -1
  209. package/dist/types/features.js.map +0 -1
  210. package/dist/types/index.d.ts.map +0 -1
  211. package/dist/types/index.js.map +0 -1
  212. package/dist/types/viteConfig.d.ts.map +0 -1
  213. package/dist/types/viteConfig.js.map +0 -1
  214. package/dist/utils/deepMerge.d.ts.map +0 -1
  215. package/dist/utils/deepMerge.js.map +0 -1
  216. package/dist/utils/ejs.d.ts.map +0 -1
  217. package/dist/utils/ejs.js.map +0 -1
  218. package/dist/utils/file.d.ts.map +0 -1
  219. package/dist/utils/file.js.map +0 -1
  220. package/dist/utils/index.d.ts.map +0 -1
  221. package/dist/utils/index.js.map +0 -1
  222. package/dist/utils/install.d.ts.map +0 -1
  223. package/dist/utils/install.js.map +0 -1
  224. package/dist/utils/prompts.d.ts.map +0 -1
  225. package/dist/utils/prompts.js.map +0 -1
  226. package/dist/utils/renderFeatures.d.ts.map +0 -1
  227. package/dist/utils/renderFeatures.js.map +0 -1
  228. package/dist/utils/renderTemplate.d.ts.map +0 -1
  229. package/dist/utils/renderTemplate.js.map +0 -1
  230. package/dist/utils/sortDependencies.d.ts.map +0 -1
  231. package/dist/utils/sortDependencies.js.map +0 -1
  232. package/dist/utils/viteConfigRender.d.ts.map +0 -1
  233. package/dist/utils/viteConfigRender.js.map +0 -1
  234. package/templates/common/base/pnpm-workspace.yaml +0 -37
  235. package/templates/common/features/husky/pnpm-workspace.yaml +0 -9
  236. package/templates/react/base/pnpm-workspace.yaml +0 -9
  237. package/templates/react/base/src/stores/user.ts +0 -39
  238. package/templates/react/base/vite.config.ts +0 -52
  239. package/templates/react/features/ant-design/pnpm-workspace.yaml +0 -5
  240. package/templates/react/features/eslint/pnpm-workspace.yaml +0 -6
  241. package/templates/react/features/i18n/pnpm-workspace.yaml +0 -5
  242. package/templates/react/features/pageRoutes/pnpm-workspace.yaml +0 -4
  243. package/templates/react/features/pageRoutes/vite.config.data.ts +0 -10
  244. package/templates/react/features/router/pnpm-workspace.yaml +0 -3
  245. package/templates/react/features/sentry/pnpm-workspace.yaml +0 -5
  246. package/templates/react/features/sentry/vite.config.data.ts +0 -23
  247. package/templates/react/features/zustand/pnpm-workspace.yaml +0 -3
  248. package/templates/vue/base/pnpm-workspace.yaml +0 -6
  249. package/templates/vue/base/src/components/SubMenu/index.ts +0 -9
  250. package/templates/vue/base/src/stores/index.ts +0 -16
  251. package/templates/vue/base/src/stores/modules/system.ts +0 -52
  252. package/templates/vue/base/src/stores/modules/user.ts +0 -48
  253. package/templates/vue/features/ant-design-vue/pnpm-workspace.yaml +0 -5
  254. package/templates/vue/features/element-plus/pnpm-workspace.yaml +0 -5
  255. package/templates/vue/features/element-plus/vite.config.data.ts +0 -15
  256. package/templates/vue/features/eslint/pnpm-workspace.yaml +0 -6
  257. package/templates/vue/features/i18n/pnpm-workspace.yaml +0 -3
  258. package/templates/vue/features/pageRoutes/pnpm-workspace.yaml +0 -4
  259. package/templates/vue/features/pageRoutes/vite.config.data.ts +0 -9
  260. package/templates/vue/features/pinia/pnpm-workspace.yaml +0 -4
  261. package/templates/vue/features/qiankun/pnpm-workspace.yaml +0 -3
  262. package/templates/vue/features/router/pnpm-workspace.yaml +0 -3
  263. package/templates/vue/features/sentry/pnpm-workspace.yaml +0 -4
  264. package/templates/vue/features/sentry/vite.config.data.ts +0 -23
@@ -2,36 +2,79 @@
2
2
  * 依赖安装工具
3
3
  * 执行包管理器安装依赖
4
4
  */
5
- import { execSync } from 'node:child_process';
5
+ import { exec } from 'node:child_process';
6
+ import { promisify } from 'node:util';
7
+ import { validatePath } from "./file.js";
8
+ const execAsync = promisify(exec);
9
+ /** 重试延迟基数(毫秒) */
10
+ const RETRY_DELAY_BASE_MS = 1000;
11
+ /**
12
+ * 验证命令参数安全性
13
+ * @param packageManager 包管理器类型
14
+ * @param cwd 工作目录
15
+ * @throws {Error} 如果参数不安全
16
+ */
17
+ function validateInstallParams(packageManager, cwd) {
18
+ // 验证包管理器类型
19
+ const validPackageManagers = ['pnpm', 'npm', 'yarn'];
20
+ if (!validPackageManagers.includes(packageManager)) {
21
+ throw new Error(`不支持的包管理器: ${packageManager}`);
22
+ }
23
+ // 验证工作目录路径(防止路径遍历攻击)
24
+ validatePath(cwd);
25
+ }
6
26
  /**
7
27
  * 安装依赖
8
28
  * @param packageManager 包管理器
9
29
  * @param cwd 工作目录
30
+ * @param retries 重试次数,默认 0(不重试)
31
+ * @returns Promise<void>
32
+ * @throws {Error} 如果安装失败
10
33
  */
11
- export function installDependencies(packageManager, cwd) {
34
+ export async function installDependencies(packageManager, cwd, retries = 0) {
35
+ // 验证参数安全性
36
+ validateInstallParams(packageManager, cwd);
12
37
  const commands = {
13
38
  pnpm: 'pnpm install',
14
39
  npm: 'npm install',
15
40
  yarn: 'yarn install',
16
41
  };
17
42
  const command = commands[packageManager];
18
- execSync(command, {
19
- cwd,
20
- stdio: 'inherit',
21
- });
43
+ let lastError;
44
+ for (let attempt = 0; attempt <= retries; attempt++) {
45
+ try {
46
+ await execAsync(command, {
47
+ cwd,
48
+ });
49
+ return; // 成功则返回
50
+ }
51
+ catch (error) {
52
+ lastError = error instanceof Error ? error : new Error(String(error));
53
+ if (attempt < retries) {
54
+ // 等待后重试(指数退避)
55
+ await new Promise(resolve => setTimeout(resolve, RETRY_DELAY_BASE_MS * (attempt + 1)));
56
+ }
57
+ }
58
+ }
59
+ // 所有重试都失败,抛出详细错误
60
+ throw new Error(`依赖安装失败 (${packageManager}): ${lastError?.message || '未知错误'}\n`
61
+ + `工作目录: ${cwd}\n`
62
+ + `命令: ${command}`, { cause: lastError });
22
63
  }
23
64
  /**
24
65
  * 初始化 Git 仓库
25
66
  * @param cwd 工作目录
67
+ * @returns Promise<void>
26
68
  */
27
- export function initGit(cwd) {
69
+ export async function initGit(cwd) {
28
70
  try {
29
- execSync('git init', { cwd, stdio: 'ignore' });
30
- execSync('git add .', { cwd, stdio: 'ignore' });
31
- execSync('git commit -m "chore: initial commit"', { cwd, stdio: 'ignore' });
71
+ // 验证路径安全性
72
+ validatePath(cwd);
73
+ await execAsync('git init', { cwd });
74
+ await execAsync('git add .', { cwd });
75
+ await execAsync('git commit -m "chore: initial commit"', { cwd });
32
76
  }
33
77
  catch {
34
- // Git 初始化失败不影响项目创建
78
+ // Git 初始化失败不影响项目创建,静默失败
35
79
  }
36
80
  }
37
- //# sourceMappingURL=install.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * 读取 npm 配置工具
3
+ * 用于获取全局配置作为默认值
4
+ */
5
+ /**
6
+ * 获取默认作者信息
7
+ * 优先级:npm init-author-name/email > git user.name/email
8
+ * @returns 作者字符串,格式:Name <email> 或 Name
9
+ */
10
+ export declare function getDefaultAuthor(): string;
11
+ /**
12
+ * 获取默认许可证
13
+ * @returns 许可证名称,默认为 'MIT'
14
+ */
15
+ export declare function getDefaultLicense(): string;
@@ -0,0 +1,79 @@
1
+ /**
2
+ * 读取 npm 配置工具
3
+ * 用于获取全局配置作为默认值
4
+ */
5
+ import { execSync } from 'node:child_process';
6
+ /**
7
+ * 读取 npm 配置值
8
+ * @param key 配置键名
9
+ * @returns 配置值,如果不存在则返回 null
10
+ */
11
+ function getNpmConfig(key) {
12
+ try {
13
+ // 使用 stdio: 'pipe' 并只读取 stdout,忽略 stderr 中的警告
14
+ const result = execSync(`npm config get ${key}`, {
15
+ encoding: 'utf-8',
16
+ stdio: ['ignore', 'pipe', 'ignore'], // stdin: ignore, stdout: pipe, stderr: ignore
17
+ });
18
+ const value = result.trim();
19
+ // npm config get 返回 "undefined" 字符串表示未设置
20
+ if (value === 'undefined' || value === '') {
21
+ return null;
22
+ }
23
+ return value;
24
+ }
25
+ catch {
26
+ return null;
27
+ }
28
+ }
29
+ /**
30
+ * 读取 Git 配置值
31
+ * @param key 配置键名
32
+ * @returns 配置值,如果不存在则返回 null
33
+ */
34
+ function getGitConfig(key) {
35
+ try {
36
+ const value = execSync(`git config --global ${key}`, { encoding: 'utf-8' }).trim();
37
+ if (value === '') {
38
+ return null;
39
+ }
40
+ return value;
41
+ }
42
+ catch {
43
+ return null;
44
+ }
45
+ }
46
+ /**
47
+ * 获取默认作者信息
48
+ * 优先级:npm init-author-name/email > git user.name/email
49
+ * @returns 作者字符串,格式:Name <email> 或 Name
50
+ */
51
+ export function getDefaultAuthor() {
52
+ // 优先从 npm 配置读取
53
+ const npmName = getNpmConfig('init-author-name');
54
+ const npmEmail = getNpmConfig('init-author-email');
55
+ const npmUrl = getNpmConfig('init-author-url');
56
+ // 如果 npm 配置不存在,尝试从 git 配置读取
57
+ const gitName = npmName || getGitConfig('user.name');
58
+ const gitEmail = npmEmail || getGitConfig('user.email');
59
+ // 组合作者信息
60
+ const parts = [];
61
+ if (gitName) {
62
+ parts.push(gitName);
63
+ }
64
+ if (gitEmail) {
65
+ parts.push(`<${gitEmail}>`);
66
+ }
67
+ if (npmUrl && !gitEmail) {
68
+ // 如果有 URL 但没有邮箱,添加 URL
69
+ parts.push(`(${npmUrl})`);
70
+ }
71
+ return parts.join(' ') || '';
72
+ }
73
+ /**
74
+ * 获取默认许可证
75
+ * @returns 许可证名称,默认为 'MIT'
76
+ */
77
+ export function getDefaultLicense() {
78
+ return getNpmConfig('init-license') || 'MIT';
79
+ }
@@ -2,15 +2,16 @@
2
2
  * 交互式问答工具
3
3
  * 收集用户的项目配置信息(对标 create-vue)
4
4
  */
5
- import type { ProjectConfigType } from '../types';
5
+ import type { ProjectConfigType } from '../types/index.ts';
6
6
  /**
7
7
  * 收集项目配置信息
8
8
  * @param projectName 项目名称(可选)
9
+ * @returns 项目配置对象
9
10
  */
10
11
  export declare function collectProjectConfig(projectName?: string): Promise<ProjectConfigType>;
11
12
  /**
12
13
  * 确认覆盖目录
13
14
  * @param dirPath 目录路径
15
+ * @returns 是否确认覆盖
14
16
  */
15
17
  export declare function confirmOverwrite(dirPath: string): Promise<boolean>;
16
- //# sourceMappingURL=prompts.d.ts.map
@@ -2,13 +2,18 @@
2
2
  * 交互式问答工具
3
3
  * 收集用户的项目配置信息(对标 create-vue)
4
4
  */
5
+ import fs from 'node:fs';
5
6
  import process from 'node:process';
6
7
  import inquirer from 'inquirer';
8
+ import { getDefaultAuthor } from "./npmConfig.js";
7
9
  /**
8
10
  * 收集项目配置信息
9
11
  * @param projectName 项目名称(可选)
12
+ * @returns 项目配置对象
10
13
  */
11
14
  export async function collectProjectConfig(projectName) {
15
+ // 获取默认作者信息
16
+ const defaultAuthor = getDefaultAuthor();
12
17
  const answers = await inquirer.prompt([
13
18
  // 项目名称
14
19
  {
@@ -17,12 +22,53 @@ export async function collectProjectConfig(projectName) {
17
22
  message: '项目名称:',
18
23
  default: projectName || 'my-project',
19
24
  validate: (input) => {
20
- if (!input.trim()) {
25
+ const trimmed = input.trim();
26
+ if (!trimmed) {
21
27
  return '项目名称不能为空';
22
28
  }
23
- if (!/^[\w-]+$/.test(input)) {
29
+ const minLength = 1;
30
+ const maxLength = 214;
31
+ if (trimmed.length < minLength || trimmed.length > maxLength) {
32
+ return `项目名称长度必须在 ${minLength}-${maxLength} 个字符之间`;
33
+ }
34
+ if (!/^[\w-]+$/.test(trimmed)) {
24
35
  return '项目名称只能包含字母、数字、连字符和下划线';
25
36
  }
37
+ const reservedNames = [
38
+ 'node',
39
+ 'npm',
40
+ 'test',
41
+ 'lib',
42
+ 'api',
43
+ 'www',
44
+ 'admin',
45
+ 'root',
46
+ 'config',
47
+ 'build',
48
+ 'dist',
49
+ 'src',
50
+ 'public',
51
+ 'private',
52
+ ];
53
+ if (reservedNames.includes(trimmed.toLowerCase())) {
54
+ return `项目名称不能使用保留名称: ${trimmed}`;
55
+ }
56
+ // 检查目标目录是否已存在且不为空
57
+ const targetDir = `${process.cwd()}/${trimmed}`;
58
+ if (fs.existsSync(targetDir)) {
59
+ try {
60
+ const stats = fs.statSync(targetDir);
61
+ if (stats.isDirectory()) {
62
+ const files = fs.readdirSync(targetDir);
63
+ if (files.length > 0) {
64
+ return `目录 ${targetDir} 已存在且不为空,请选择其他名称或先清空该目录`;
65
+ }
66
+ }
67
+ }
68
+ catch {
69
+ // 忽略检查错误,让后续流程处理
70
+ }
71
+ }
26
72
  return true;
27
73
  },
28
74
  },
@@ -38,7 +84,7 @@ export async function collectProjectConfig(projectName) {
38
84
  type: 'input',
39
85
  name: 'author',
40
86
  message: '作者:',
41
- default: '',
87
+ default: defaultAuthor,
42
88
  },
43
89
  // 框架选择
44
90
  {
@@ -130,7 +176,7 @@ export async function collectProjectConfig(projectName) {
130
176
  message: '是否启用 Git Hooks (husky + commitlint)?',
131
177
  default: true,
132
178
  },
133
- // 包管理器
179
+ // 包管理器选择
134
180
  {
135
181
  type: 'list',
136
182
  name: 'packageManager',
@@ -165,6 +211,7 @@ export async function collectProjectConfig(projectName) {
165
211
  /**
166
212
  * 确认覆盖目录
167
213
  * @param dirPath 目录路径
214
+ * @returns 是否确认覆盖
168
215
  */
169
216
  export async function confirmOverwrite(dirPath) {
170
217
  const { confirm } = await inquirer.prompt([
@@ -177,4 +224,3 @@ export async function confirmOverwrite(dirPath) {
177
224
  ]);
178
225
  return confirm;
179
226
  }
180
- //# sourceMappingURL=prompts.js.map
@@ -2,17 +2,18 @@
2
2
  * Features 渲染工具
3
3
  * 统一处理 features 的渲染逻辑
4
4
  */
5
- import type { ProjectConfigType } from '../types';
5
+ import type { ProjectConfigType } from '../types/index.ts';
6
6
  /**
7
7
  * 渲染框架特定的 features
8
8
  * @param config 项目配置
9
9
  * @param targetDir 目标目录
10
+ * @throws {Error} 如果路径不安全或模板渲染失败
10
11
  */
11
12
  export declare function renderFrameworkFeatures(config: ProjectConfigType, targetDir: string): void;
12
13
  /**
13
14
  * 渲染公共 features
14
15
  * @param config 项目配置
15
16
  * @param targetDir 目标目录
17
+ * @throws {Error} 如果路径不安全或模板渲染失败
16
18
  */
17
19
  export declare function renderCommonFeatures(config: ProjectConfigType, targetDir: string): void;
18
- //# sourceMappingURL=renderFeatures.d.ts.map
@@ -3,25 +3,48 @@
3
3
  * 统一处理 features 的渲染逻辑
4
4
  */
5
5
  import path from 'node:path';
6
- import { getTemplatesDir } from './file.js';
7
- import { renderTemplate } from './renderTemplate.js';
6
+ import { getTemplatesDir } from "./file.js";
7
+ import { renderTemplate } from "./renderTemplate.js";
8
+ import { getCommonFeatureMap, getConfigToFeatureMap, getRouteModeFeature, getUILibraryFeature, } from "./featureMapping.js";
9
+ /**
10
+ * 检查 UI 库是否适用于指定框架
11
+ * @param framework 框架类型
12
+ * @param uiLibrary UI 库类型
13
+ * @returns 是否适用
14
+ */
15
+ function isUILibrarySupported(framework, uiLibrary) {
16
+ if (framework === 'vue') {
17
+ return uiLibrary === 'element-plus' || uiLibrary === 'ant-design-vue';
18
+ }
19
+ if (framework === 'react') {
20
+ return uiLibrary === 'ant-design';
21
+ }
22
+ return false;
23
+ }
24
+ /**
25
+ * 渲染 UI 库特性模板
26
+ * @param config 项目配置
27
+ * @param targetDir 目标目录
28
+ * @param templatesDir 模板目录
29
+ * @throws {Error} 如果路径不安全或模板渲染失败
30
+ */
31
+ function renderUILibraryFeature(config, targetDir, templatesDir) {
32
+ const { framework, uiLibrary } = config;
33
+ if (isUILibrarySupported(framework, uiLibrary)) {
34
+ const uiLibraryFeature = getUILibraryFeature(uiLibrary);
35
+ renderTemplate(path.join(templatesDir, framework, 'features', uiLibraryFeature), targetDir);
36
+ }
37
+ }
8
38
  /**
9
39
  * 渲染框架特定的 features
10
40
  * @param config 项目配置
11
41
  * @param targetDir 目标目录
42
+ * @throws {Error} 如果路径不安全或模板渲染失败
12
43
  */
13
44
  export function renderFrameworkFeatures(config, targetDir) {
14
45
  const templatesDir = getTemplatesDir();
15
46
  const framework = config.framework;
16
- // 定义 features 映射:配置项名称 -> feature 目录名称
17
- const featureMap = {
18
- router: 'router',
19
- stateManagement: framework === 'vue' ? 'pinia' : 'zustand',
20
- eslint: 'eslint',
21
- i18n: 'i18n',
22
- sentry: 'sentry',
23
- qiankun: 'qiankun',
24
- };
47
+ const featureMap = getConfigToFeatureMap(framework);
25
48
  // 统一处理布尔类型的 features
26
49
  for (const [configKey, featureName] of Object.entries(featureMap)) {
27
50
  if (config[configKey] === true) {
@@ -29,39 +52,21 @@ export function renderFrameworkFeatures(config, targetDir) {
29
52
  renderTemplate(featurePath, targetDir);
30
53
  }
31
54
  }
32
- // 特殊处理:路由模式相关的 features
33
- if (config.routeMode === 'manual') {
34
- renderTemplate(path.join(templatesDir, framework, 'features', 'manualRoutes'), targetDir);
35
- }
36
- else if (config.routeMode === 'file-system') {
37
- renderTemplate(path.join(templatesDir, framework, 'features', 'pageRoutes'), targetDir);
38
- }
39
- // 特殊处理:UI 库相关的 features
40
- if (framework === 'vue') {
41
- if (config.uiLibrary === 'element-plus') {
42
- renderTemplate(path.join(templatesDir, framework, 'features', 'element-plus'), targetDir);
43
- }
44
- else if (config.uiLibrary === 'ant-design-vue') {
45
- renderTemplate(path.join(templatesDir, framework, 'features', 'ant-design-vue'), targetDir);
46
- }
47
- }
48
- else if (framework === 'react') {
49
- if (config.uiLibrary === 'ant-design') {
50
- renderTemplate(path.join(templatesDir, framework, 'features', 'ant-design'), targetDir);
51
- }
52
- }
55
+ // 路由模式
56
+ const routeModeFeature = getRouteModeFeature(config.routeMode);
57
+ renderTemplate(path.join(templatesDir, framework, 'features', routeModeFeature), targetDir);
58
+ // UI 库
59
+ renderUILibraryFeature(config, targetDir, templatesDir);
53
60
  }
54
61
  /**
55
62
  * 渲染公共 features
56
63
  * @param config 项目配置
57
64
  * @param targetDir 目标目录
65
+ * @throws {Error} 如果路径不安全或模板渲染失败
58
66
  */
59
67
  export function renderCommonFeatures(config, targetDir) {
60
68
  const templatesDir = getTemplatesDir();
61
- // 公共 features 映射
62
- const commonFeatureMap = {
63
- gitHooks: 'husky',
64
- };
69
+ const commonFeatureMap = getCommonFeatureMap();
65
70
  for (const [configKey, featureName] of Object.entries(commonFeatureMap)) {
66
71
  if (config[configKey] === true) {
67
72
  const featurePath = path.join(templatesDir, 'common', 'features', featureName);
@@ -69,4 +74,3 @@ export function renderCommonFeatures(config, targetDir) {
69
74
  }
70
75
  }
71
76
  }
72
- //# sourceMappingURL=renderFeatures.js.map
@@ -1,6 +1,18 @@
1
1
  /**
2
2
  * 渲染模板到目标目录
3
3
  * 支持物理路径合并和配置文件深度合并
4
+ * @param src 源路径
5
+ * @param dest 目标路径
6
+ * @throws {Error} 如果路径不安全、文件操作失败
4
7
  */
5
8
  export declare function renderTemplate(src: string, dest: string): void;
6
- //# sourceMappingURL=renderTemplate.d.ts.map
9
+ /**
10
+ * 更新 package.json 的元数据字段(name, description, author, packageManager)
11
+ * @param packageJsonPath package.json 文件路径
12
+ * @param projectName 项目名称
13
+ * @param description 项目描述
14
+ * @param author 作者
15
+ * @param packageManager 包管理器类型
16
+ * @throws {Error} 如果文件读取失败、JSON 解析失败或写入失败
17
+ */
18
+ export declare function updatePackageJsonMetadata(packageJsonPath: string, projectName: string, description: string, author: string, packageManager: string): void;