@agile-team/jh4j-cloud-cli 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0
4
+
5
+ - 精简交互流程:单模板自动选择,标准能力直接采用模板默认值。
6
+ - 模块标识自动从项目名推导,不再询问 Registry、public 地址和五套环境配置。
7
+ - 默认不安装依赖,创建完成后提示开发者手动执行 `pnpm install`。
8
+ - 增加显式 `--install` 参数,仍可按需启用自动安装。
9
+ - 完成提示中列出项目配置、Registry 和环境文件的修改位置。
10
+ - 只展示当前可用的项目类型,并使用互不混淆的固定技术栈标签。
11
+ - 项目名自动转为小写短横线格式,标题、端口和 URL 在输入时就地校验。
12
+ - 模板下载阶段显示进度状态,单模板自动选择后明确显示模板名称。
13
+
3
14
  ## 0.4.0
4
15
 
5
16
  - 接入 `mobile.robot-h5` 移动端 H5 模板,支持 GitHub/Gitee 双 HTTPS 源。
package/README.md CHANGED
@@ -2,20 +2,21 @@
2
2
 
3
3
  JH4J Cloud 团队项目脚手架,用于从受控模板快速创建结构一致、配置完整、可追溯的工程。
4
4
 
5
- 当前版本:`@agile-team/jh4j-cloud-cli@0.4.0`。
5
+ 当前版本:`@agile-team/jh4j-cloud-cli@0.5.0`。
6
6
 
7
7
  ## 核心能力
8
8
 
9
9
  | 能力 | 说明 |
10
10
  | --- | --- |
11
11
  | 分类选择 | 按前端、后端、移动端组织模板;当前已接入 PC 与移动端模板 |
12
- | 交互创建 | 依次确认项目类型、模板、标准能力和项目参数 |
12
+ | 精简交互 | 只确认项目类型、标题、端口和本地服务地址;其余采用模板默认值 |
13
+ | 即时校验 | 项目名自动规范化,端口和 URL 错误在当前输入步骤直接提示 |
13
14
  | 非交互创建 | 支持命令行参数和 JSON 配置文件,适用于 CI 与批量初始化 |
14
15
  | 多源拉取 | 支持本地目录、Git、HTTP 压缩包和离线压缩包 |
15
16
  | 源站容灾 | 内置模板按 GitHub → Gitee 顺序拉取,主源不可用时自动切换 |
16
17
  | 模板缓存 | 按 `source + ref` 缓存远程模板,支持查看、清理和强制刷新 |
17
18
  | 安全生成 | 在临时目录完成初始化与校验,成功后再原子写入目标目录 |
18
- | 工程初始化 | 可自动安装依赖、初始化 `main` 分支并创建首次提交 |
19
+ | 工程初始化 | 默认不安装依赖;可初始化 `main` 分支并创建首次提交 |
19
20
  | 来源追踪 | 生成 `.jhlc/project.json`,记录模板版本、CLI 版本和创建参数 |
20
21
 
21
22
  生成链路:
@@ -28,7 +29,8 @@ jh4j create
28
29
  → 拉取或读取缓存
29
30
  → 校验 template.manifest.json
30
31
  → 在 staging 目录执行模板初始化
31
- 安装依赖并初始化 Git
32
+ 生成项目并初始化 Git
33
+ → 开发者按需修改配置并手动安装依赖
32
34
  ```
33
35
 
34
36
  ## 环境要求
@@ -58,17 +60,21 @@ pnpm add -g @agile-team/jh4j-cloud-cli
58
60
  jh4j create jh4j-ui-orders
59
61
  ```
60
62
 
61
- 交互模式会依次完成:
63
+ 交互模式只确认必要信息,直接回车即可接受当前默认值:
62
64
 
63
65
  ```text
64
66
  项目类型
65
- 项目模板
66
- 标准化能力
67
- 按模板确认项目参数与开发端口
68
- Registry 与本地联调地址
69
- 依赖安装与 Git 初始化
67
+ 单个可用模板自动选中
68
+ 系统/应用标题
69
+ 开发端口
70
+ 本地后端/API 地址
71
+ 生成项目并初始化 Git
70
72
  ```
71
73
 
74
+ 标准能力默认启用,Registry、模块标识和各套环境配置不再逐项询问。需要调整时,创建完成后直接修改项目中的 `project.config.json`、`.npmrc` 和 `.env*` 文件。
75
+
76
+ 项目名允许输入常见的人类可读形式,CLI 会自动转为适合目录和 `package.json` 的小写名称。例如 `JH4J 移动端 H5 模板` 会转换为 `jh4j-h5`;如果输入无法得到任何字母或数字,会在当前输入框中直接提示。
77
+
72
78
  当前 Catalog 中可用模板:
73
79
 
74
80
  | 类型 | 模板 ID | 模板 |
@@ -141,17 +147,23 @@ jh4j create jh4j-ui-orders --yes --dry-run
141
147
 
142
148
  `--dry-run` 会完成模板解析和参数校验,但不会创建项目目录。
143
149
 
144
- ### 跳过自动步骤
150
+ ### 安装依赖与可选步骤
145
151
 
146
152
  ```bash
147
- # 只生成工程文件
148
- jh4j create jh4j-ui-orders --yes --skip-install --skip-git
153
+ # 默认只生成项目,依赖由开发者手动安装
154
+ jh4j create jh4j-ui-orders --yes
155
+
156
+ # 确实需要创建后自动安装时显式指定
157
+ jh4j create jh4j-ui-orders --yes --install
158
+
159
+ # 跳过 Git 初始化
160
+ jh4j create jh4j-ui-orders --yes --skip-git
149
161
 
150
162
  # 不启用模板提供的完整 Git 与代码质量规范
151
163
  jh4j create jh4j-ui-orders --yes --no-standards
152
164
  ```
153
165
 
154
- PC 模板默认启用 `git-standards` 能力,由 `@robot-admin/git-standards` 提供 Commitizen、Commitlint、Husky、ESLint、Prettier 和 lint-staged 配置。
166
+ PC 与移动端模板默认启用 `git-standards` 能力。创建时不再重复确认;需要关闭时使用 `--no-standards`。
155
167
 
156
168
  ### 常用参数
157
169
 
@@ -162,10 +174,11 @@ PC 模板默认启用 `git-standards` 能力,由 `@robot-admin/git-standards`
162
174
  | `--features <ids>` | 启用的模板能力,多个 ID 使用逗号分隔 |
163
175
  | `--no-standards` | 禁用模板提供的 Git 与代码质量规范 |
164
176
  | `--source <path-or-url>` | 强制使用指定模板目录、Git 地址或压缩包 |
165
- | `--ref <branch-or-tag>` | 远程 Git 分支或标签,当前默认 `main` |
177
+ | `--ref <branch-or-tag>` | 覆盖 Catalog 为模板配置的默认分支或标签 |
166
178
  | `--config <json-file>` | 从 JSON 文件读取创建参数 |
167
179
  | `--dry-run` | 校验并展示生成计划,不写入项目目录 |
168
- | `--skip-install` | 跳过依赖安装 |
180
+ | `--install` | 创建完成后自动安装依赖;默认不安装 |
181
+ | `--skip-install` | 明确不安装依赖,兼容旧命令 |
169
182
  | `--skip-git` | 跳过 Git 初始化 |
170
183
  | `--force` | 替换已存在的同名目录 |
171
184
  | `--no-cache` | 不读取已有远程模板缓存 |
@@ -184,9 +197,9 @@ CLI 不会直接在目标目录中边下载边修改。创建过程先在当前
184
197
  2. 模板初始化脚本执行。
185
198
  3. 生成元数据校验。
186
199
  4. staging 目录原子提升为目标目录。
187
- 5. 可选的依赖安装与 Git 初始化。
200
+ 5. Git 初始化,以及显式 `--install` 时的依赖安装。
188
201
 
189
- 目标目录已存在时,默认拒绝覆盖。使用 `--force` 后,CLI 会先备份旧目录;模板初始化失败时,旧目录保持不变。依赖安装发生在工程文件生成成功之后,安装失败时会保留已生成目录,便于排查 Registry 或网络问题。
202
+ 目标目录已存在时,默认拒绝覆盖。使用 `--force` 后,CLI 会先备份旧目录;模板初始化失败时,旧目录保持不变。默认不安装依赖,避免网络或 Registry 问题阻塞项目生成。
190
203
 
191
204
  ## 模板来源
192
205
 
@@ -264,7 +277,7 @@ jh4j create jh4j-ui-orders --no-cache
264
277
  ```bash
265
278
  jh4j config list
266
279
  jh4j config get autoInstall
267
- jh4j config set autoInstall false
280
+ jh4j config set autoInstall true
268
281
  jh4j config set autoGit false
269
282
  jh4j config set cacheTtlMinutes 120
270
283
  jh4j config unset cacheTtlMinutes
@@ -277,7 +290,7 @@ jh4j config reset
277
290
  | `templateSource` | 全局模板源覆盖;设置后不再自动尝试 Catalog 备用源 |
278
291
  | `npmRegistry` | npm Registry,必须能提供项目使用的企业定制包 |
279
292
  | `jhlcRegistry` | `@jhlc` 私有 Registry |
280
- | `autoInstall` | 创建后是否自动安装依赖 |
293
+ | `autoInstall` | 创建后是否自动安装依赖,默认 `false`;通常保持默认即可 |
281
294
  | `autoGit` | 创建后是否初始化 Git 仓库 |
282
295
  | `cacheTtlMinutes` | 模板缓存有效期;`0` 表示每次刷新 |
283
296
 
@@ -387,9 +400,9 @@ jh4j create jh4j-ui-orders --no-cache
387
400
 
388
401
  先检查 GitHub、Gitee 或自定义模板源是否可访问,再检查本地 Git 代理和凭据配置。
389
402
 
390
- ### 依赖安装失败
403
+ ### 手动安装依赖
391
404
 
392
- 生成目录会被保留。进入项目后确认 `.npmrc` 和内部 Registry 网络,再重新执行:
405
+ 项目生成完成后,确认 `.npmrc` 和内部 Registry 网络,再手动执行:
393
406
 
394
407
  ```bash
395
408
  pnpm install
@@ -397,10 +410,10 @@ pnpm install
397
410
 
398
411
  PC 模板包含企业定制的非 scope 依赖,默认 npm Registry 必须能够提供这些包。
399
412
 
400
- ### 只生成文件,不执行安装和 Git 初始化
413
+ ### 只生成文件,不初始化 Git
401
414
 
402
415
  ```bash
403
- jh4j create jh4j-ui-orders --yes --skip-install --skip-git
416
+ jh4j create jh4j-ui-orders --yes --skip-git
404
417
  ```
405
418
 
406
419
  ### 强制使用指定模板源
package/dist/index.js CHANGED
@@ -6,7 +6,7 @@ import { Command } from "commander";
6
6
  // package.json
7
7
  var package_default = {
8
8
  name: "@agile-team/jh4j-cloud-cli",
9
- version: "0.4.0",
9
+ version: "0.5.0",
10
10
  description: "JH4J Cloud \u4F01\u4E1A\u5185\u90E8\u6807\u51C6\u5316\u9879\u76EE\u811A\u624B\u67B6",
11
11
  repository: {
12
12
  type: "git",
@@ -296,7 +296,7 @@ import path3 from "path";
296
296
  import { existsSync as existsSync3 } from "fs";
297
297
  var DEFAULT_USER_CONFIG = {
298
298
  schemaVersion: USER_CONFIG_SCHEMA_VERSION,
299
- autoInstall: true,
299
+ autoInstall: false,
300
300
  autoGit: true,
301
301
  cacheTtlMinutes: 60
302
302
  };
@@ -666,10 +666,13 @@ var ENV_NAMES = ["dev", "sit", "uat", "pre", "prd"];
666
666
  function cancelled(value) {
667
667
  return prompts.isCancel(value);
668
668
  }
669
+ function normalizeProjectName(value) {
670
+ return value.trim().toLowerCase().replace(/\s+/g, "-").replace(/^[._-]+/, "").replace(/[^a-z0-9._-]+/g, "-").replace(/-{2,}/g, "-").replace(/[-._]+$/, "");
671
+ }
669
672
  function ensureProjectName(value) {
670
- const name = value.trim();
673
+ const name = normalizeProjectName(value);
671
674
  if (!/^[a-z0-9][a-z0-9._-]*$/.test(name)) {
672
- throw new Error("\u9879\u76EE\u540D\u79F0\u53EA\u80FD\u5305\u542B\u5C0F\u5199\u5B57\u6BCD\u3001\u6570\u5B57\u3001\u70B9\u3001\u4E0B\u5212\u7EBF\u548C\u8FDE\u5B57\u7B26");
675
+ throw new Error("\u9879\u76EE\u540D\u79F0\u81F3\u5C11\u9700\u8981\u5305\u542B\u4E00\u4E2A\u5B57\u6BCD\u6216\u6570\u5B57");
673
676
  }
674
677
  return name;
675
678
  }
@@ -700,8 +703,13 @@ function ensureHttpUrl(value, label) {
700
703
  throw new Error(`${label} \u5FC5\u987B\u662F http/https URL`);
701
704
  }
702
705
  }
703
- async function askText(message, initialValue) {
704
- const answer = await prompts.text({ message, initialValue });
706
+ async function askText(message, initialValue, validate) {
707
+ const answer = await prompts.text({
708
+ message,
709
+ placeholder: initialValue,
710
+ defaultValue: initialValue,
711
+ validate
712
+ });
705
713
  if (cancelled(answer)) throw new Error("\u7528\u6237\u53D6\u6D88\u521B\u5EFA");
706
714
  return String(answer).trim() || initialValue;
707
715
  }
@@ -731,25 +739,6 @@ async function collectTemplateFeatures(manifest, fileConfig, options) {
731
739
  return feature?.package !== "@robot-admin/git-standards";
732
740
  });
733
741
  }
734
- if (!options.yes) {
735
- const selectable = available.filter(
736
- (feature) => options.standards !== false || feature.package !== "@robot-admin/git-standards"
737
- );
738
- if (selectable.length) {
739
- const answer = await prompts.multiselect({
740
- message: "\u9009\u62E9\u9879\u76EE\u6807\u51C6\u5316\u80FD\u529B",
741
- options: selectable.map((feature) => ({
742
- value: feature.id,
743
- label: feature.name,
744
- hint: `${feature.description}${feature.package ? ` \xB7 ${feature.package}` : ""}`
745
- })),
746
- initialValues: selected,
747
- required: false
748
- });
749
- if (cancelled(answer)) throw new Error("\u7528\u6237\u53D6\u6D88\u521B\u5EFA");
750
- selected = answer.map(String);
751
- }
752
- }
753
742
  for (const feature of available) {
754
743
  if (feature.required && !selected.includes(feature.id)) {
755
744
  selected.push(feature.id);
@@ -772,42 +761,27 @@ async function collectProjectInput(projectName, manifest, sourceConfig, fileConf
772
761
  }
773
762
  }
774
763
  if (!options.yes) {
775
- if (manifest.category !== "mobile") {
776
- moduleName = await askText("\u6A21\u5757\u6807\u8BC6", moduleName);
777
- }
778
764
  title = await askText(
779
765
  manifest.category === "mobile" ? "\u5E94\u7528\u6807\u9898" : "\u7CFB\u7EDF\u6807\u9898",
780
- title
766
+ title,
767
+ (value) => value?.trim() ? void 0 : "\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A"
781
768
  );
782
- port = await askText("\u5F00\u53D1\u7AEF\u53E3", String(port));
783
- npmRegistry = await askText("npm registry", npmRegistry);
784
- jhlcRegistry = await askText("@jhlc \u79C1\u6709 registry", jhlcRegistry);
769
+ port = await askText("\u5F00\u53D1\u7AEF\u53E3", String(port), (value) => {
770
+ const parsed = Number(value);
771
+ return Number.isInteger(parsed) && parsed >= 1024 && parsed <= 65535 ? void 0 : "\u8BF7\u8F93\u5165 1024 \u5230 65535 \u4E4B\u95F4\u7684\u7AEF\u53E3";
772
+ });
785
773
  localBackendUrl = await askText(
786
774
  manifest.category === "mobile" ? "\u672C\u5730 API \u5730\u5740" : "\u672C\u5730\u540E\u7AEF\u5730\u5740",
787
- localBackendUrl
788
- );
789
- if (manifest.category !== "mobile") {
790
- localPublicUrl = await askText("\u672C\u5730 public \u5730\u5740", localPublicUrl);
791
- }
792
- if (manifest.category !== "mobile") {
793
- const configureEnvironments = await prompts.confirm({
794
- message: "\u662F\u5426\u9010\u9879\u786E\u8BA4\u4E94\u5957\u73AF\u5883\u5730\u5740",
795
- initialValue: false
796
- });
797
- if (cancelled(configureEnvironments)) throw new Error("\u7528\u6237\u53D6\u6D88\u521B\u5EFA");
798
- if (configureEnvironments) {
799
- for (const env of ENV_NAMES) {
800
- environments[env].webUrl = await askText(
801
- `${env.toUpperCase()} \u5E73\u53F0\u5730\u5740`,
802
- environments[env].webUrl
803
- );
804
- environments[env].apiPrefix = await askText(
805
- `${env.toUpperCase()} API \u524D\u7F00`,
806
- environments[env].apiPrefix
807
- );
775
+ localBackendUrl,
776
+ (value) => {
777
+ try {
778
+ const url = new URL(value ?? "");
779
+ return url.protocol === "http:" || url.protocol === "https:" ? void 0 : "\u8BF7\u8F93\u5165 http/https \u5730\u5740";
780
+ } catch {
781
+ return "\u8BF7\u8F93\u5165\u5B8C\u6574\u7684 http/https \u5730\u5740";
808
782
  }
809
783
  }
810
- }
784
+ );
811
785
  }
812
786
  if (!title.trim()) throw new Error("\u7CFB\u7EDF\u6807\u9898\u4E0D\u80FD\u4E3A\u7A7A");
813
787
  for (const env of ENV_NAMES) {
@@ -876,10 +850,19 @@ async function generateProject(catalogTemplate, requestedProjectName, options, c
876
850
  options.source,
877
851
  userConfig.templateSource
878
852
  );
879
- const acquired = await acquireTemplateFromSources(sourceValues, ref, {
880
- noCache: options.cache === false,
881
- cacheTtlMinutes: userConfig.cacheTtlMinutes
882
- });
853
+ const acquisitionSpinner = options.yes ? void 0 : prompts.spinner({ indicator: "timer" });
854
+ acquisitionSpinner?.start("\u6B63\u5728\u83B7\u53D6\u5E76\u6821\u9A8C\u6A21\u677F");
855
+ let acquired;
856
+ try {
857
+ acquired = await acquireTemplateFromSources(sourceValues, ref, {
858
+ noCache: options.cache === false,
859
+ cacheTtlMinutes: userConfig.cacheTtlMinutes
860
+ });
861
+ acquisitionSpinner?.stop("\u6A21\u677F\u51C6\u5907\u5B8C\u6210");
862
+ } catch (error) {
863
+ acquisitionSpinner?.error("\u6A21\u677F\u83B7\u53D6\u5931\u8D25");
864
+ throw error;
865
+ }
883
866
  const stagingRoot = path7.join(
884
867
  resolvedCwd,
885
868
  `.${projectName}.jh4j-tmp-${process.pid}-${Date.now()}`
@@ -913,7 +896,7 @@ async function generateProject(catalogTemplate, requestedProjectName, options, c
913
896
  userConfig,
914
897
  features
915
898
  );
916
- const shouldInstall = !options.skipInstall && userConfig.autoInstall;
899
+ const shouldInstall = !options.skipInstall && (options.install === true || userConfig.autoInstall);
917
900
  const shouldInitializeGit = !options.skipGit && userConfig.autoGit;
918
901
  if (options.dryRun) {
919
902
  prompts.note(
@@ -1014,9 +997,9 @@ ${error.message}`
1014
997
 
1015
998
  // src/commands/create.ts
1016
999
  var CATEGORY_OPTIONS = [
1017
- { value: "frontend", label: "\u524D\u7AEF", hint: "PC\u3001Web \u4E0E\u5FAE\u524D\u7AEF\u5E94\u7528" },
1018
- { value: "backend", label: "\u540E\u7AEF", hint: "Java \u670D\u52A1\u4E0E\u4E91\u539F\u751F\u5E94\u7528" },
1019
- { value: "mobile", label: "\u79FB\u52A8\u7AEF", hint: "App\u3001H5 \u4E0E\u8DE8\u7AEF\u5E94\u7528" }
1000
+ { value: "frontend", label: "PC \u524D\u7AEF \xB7 Vue 3 / \u5FAE\u524D\u7AEF" },
1001
+ { value: "backend", label: "\u540E\u7AEF\u670D\u52A1 \xB7 Java / \u4E91\u539F\u751F" },
1002
+ { value: "mobile", label: "\u79FB\u52A8\u7AEF H5 \xB7 Vue 3 / Vant" }
1020
1003
  ];
1021
1004
  function isCategory(value) {
1022
1005
  return CATEGORY_OPTIONS.some((item) => item.value === value);
@@ -1024,6 +1007,11 @@ function isCategory(value) {
1024
1007
  function templatesByCategory(templates, category) {
1025
1008
  return templates.filter((template) => template.category === category);
1026
1009
  }
1010
+ function categoryOptionsFor(templates) {
1011
+ return CATEGORY_OPTIONS.filter(
1012
+ (item) => templatesByCategory(templates, item.value).length > 0
1013
+ ).map(({ value, label }) => ({ value, label }));
1014
+ }
1027
1015
  async function selectCategory(templates, requestedCategory, nonInteractive) {
1028
1016
  if (requestedCategory) {
1029
1017
  if (!isCategory(requestedCategory)) {
@@ -1041,17 +1029,14 @@ async function selectCategory(templates, requestedCategory, nonInteractive) {
1041
1029
  );
1042
1030
  if (!firstAvailable) throw new Error("Catalog \u4E2D\u6CA1\u6709\u53EF\u7528\u6A21\u677F");
1043
1031
  if (nonInteractive) return firstAvailable.value;
1032
+ const availableOptions = categoryOptionsFor(templates);
1033
+ if (availableOptions.length === 1) return availableOptions[0].value;
1044
1034
  const selected = await prompts2.select({
1045
1035
  message: "\u9009\u62E9\u9879\u76EE\u7C7B\u578B",
1046
- options: CATEGORY_OPTIONS.map((item) => {
1047
- const count = templatesByCategory(templates, item.value).length;
1048
- return {
1049
- value: item.value,
1050
- label: item.label,
1051
- hint: count ? `${item.hint} \xB7 ${count} \u4E2A\u6A21\u677F` : `${item.hint} \xB7 \u6682\u672A\u63D0\u4F9B`,
1052
- disabled: count === 0
1053
- };
1054
- })
1036
+ options: availableOptions.map((item) => ({
1037
+ value: item.value,
1038
+ label: item.label
1039
+ }))
1055
1040
  });
1056
1041
  if (prompts2.isCancel(selected)) throw new Error("\u7528\u6237\u53D6\u6D88\u521B\u5EFA");
1057
1042
  return selected;
@@ -1073,12 +1058,16 @@ async function selectTemplate(templates, options) {
1073
1058
  );
1074
1059
  const candidates = templatesByCategory(templates, category);
1075
1060
  if (options.yes) return findTemplate(candidates);
1061
+ if (candidates.length === 1) {
1062
+ const selected2 = candidates[0];
1063
+ prompts2.log.info(`\u4F7F\u7528\u6A21\u677F\uFF1A${selected2.name}`);
1064
+ return selected2;
1065
+ }
1076
1066
  const selected = await prompts2.select({
1077
1067
  message: "\u9009\u62E9\u9879\u76EE\u6A21\u677F",
1078
1068
  options: candidates.map((template) => ({
1079
1069
  value: template.id,
1080
- label: template.name,
1081
- hint: `${template.status} \xB7 ${template.description}`
1070
+ label: `${template.name} \xB7 ${template.description}`
1082
1071
  }))
1083
1072
  });
1084
1073
  if (prompts2.isCancel(selected)) throw new Error("\u7528\u6237\u53D6\u6D88\u521B\u5EFA");
@@ -1088,17 +1077,30 @@ async function createCommand(requestedName, options) {
1088
1077
  prompts2.intro("JH4J Cloud \u9879\u76EE\u521B\u5EFA");
1089
1078
  const userConfig = await loadUserConfig();
1090
1079
  const catalog = await loadCatalog(userConfig);
1080
+ const template = await selectTemplate(catalog, options);
1091
1081
  let projectName = requestedName;
1092
1082
  if (!projectName) {
1093
1083
  if (options.yes) throw new Error("\u975E\u4EA4\u4E92\u6A21\u5F0F\u5FC5\u987B\u6307\u5B9A\u9879\u76EE\u540D\u79F0");
1084
+ const defaultProjectName = template.category === "mobile" ? "jh4j-mobile-app" : "jh4j-ui-app";
1094
1085
  const answer = await prompts2.text({
1095
1086
  message: "\u9879\u76EE\u540D\u79F0",
1096
- placeholder: "jh4j-ui-app"
1087
+ placeholder: defaultProjectName,
1088
+ defaultValue: defaultProjectName,
1089
+ validate(value) {
1090
+ return !value || normalizeProjectName(value) ? void 0 : "\u8BF7\u8F93\u5165\u81F3\u5C11\u4E00\u4E2A\u5B57\u6BCD\u6216\u6570\u5B57\uFF0C\u4F8B\u5982 jh4j-mobile-app";
1091
+ }
1097
1092
  });
1098
1093
  if (prompts2.isCancel(answer)) throw new Error("\u7528\u6237\u53D6\u6D88\u521B\u5EFA");
1099
- projectName = String(answer);
1094
+ projectName = String(answer).trim() || defaultProjectName;
1095
+ }
1096
+ const rawProjectName = projectName;
1097
+ projectName = normalizeProjectName(rawProjectName);
1098
+ if (!projectName) {
1099
+ throw new Error("\u9879\u76EE\u540D\u79F0\u81F3\u5C11\u9700\u8981\u5305\u542B\u4E00\u4E2A\u5B57\u6BCD\u6216\u6570\u5B57");
1100
+ }
1101
+ if (projectName !== rawProjectName) {
1102
+ prompts2.log.info(`\u9879\u76EE\u540D\u79F0\u5DF2\u89C4\u8303\u5316\uFF1A${projectName}`);
1100
1103
  }
1101
- const template = await selectTemplate(catalog, options);
1102
1104
  const result = await generateProject(
1103
1105
  template,
1104
1106
  projectName,
@@ -1115,17 +1117,22 @@ async function createCommand(requestedName, options) {
1115
1117
  `\u76EE\u5F55: ${result.targetRoot}`,
1116
1118
  `\u6A21\u677F: ${result.templateId}@${result.templateVersion}`,
1117
1119
  `\u6765\u6E90: ${result.source}`,
1118
- `\u80FD\u529B: ${result.features.length ? result.features.join(", ") : "\u65E0\u53EF\u9009\u80FD\u529B"}`,
1119
- `\u4F9D\u8D56: ${result.installed ? "\u5DF2\u5B89\u88C5" : "\u672A\u5B89\u88C5"}`,
1120
+ `\u9ED8\u8BA4\u80FD\u529B: ${result.features.length ? result.features.join(", ") : "\u65E0"}`,
1121
+ `\u4F9D\u8D56: ${result.installed ? "\u5DF2\u5B89\u88C5" : "\u672A\u5B89\u88C5\uFF08\u9ED8\u8BA4\u7531\u5F00\u53D1\u8005\u624B\u52A8\u5B89\u88C5\uFF09"}`,
1120
1122
  `Git: ${result.gitInitialized ? "main \u5DF2\u521D\u59CB\u5316" : "\u672A\u521D\u59CB\u5316"}`,
1121
1123
  "",
1124
+ "\u9700\u8981\u8C03\u6574\u914D\u7F6E\u65F6\uFF0C\u76F4\u63A5\u4FEE\u6539\u751F\u6210\u9879\u76EE\u4E2D\u7684\uFF1A",
1125
+ " project.config.json \u9879\u76EE\u3001\u8054\u8C03\u4E0E\u73AF\u5883\u53C2\u6570",
1126
+ " .npmrc Registry \u914D\u7F6E",
1127
+ " .env* \u5404\u7AEF\u8FD0\u884C\u73AF\u5883\u914D\u7F6E\uFF08\u5982\u5B58\u5728\uFF09",
1128
+ "",
1122
1129
  `cd ${projectName}`,
1123
1130
  ...!result.installed ? ["pnpm install"] : [],
1124
1131
  "pnpm dev"
1125
1132
  ].join("\n"),
1126
1133
  "\u521B\u5EFA\u6210\u529F"
1127
1134
  );
1128
- prompts2.outro("Happy coding!");
1135
+ prompts2.outro("\u9879\u76EE\u5DF2\u51C6\u5907\u597D");
1129
1136
  }
1130
1137
 
1131
1138
  // src/commands/doctor.ts
@@ -1339,7 +1346,7 @@ async function cacheClearCommand() {
1339
1346
  function createProgram() {
1340
1347
  const program = new Command();
1341
1348
  program.name(COMMAND_NAME).description("JH4J Cloud \u4F01\u4E1A\u5185\u90E8\u6807\u51C6\u5316\u9879\u76EE\u811A\u624B\u67B6").version(CLI_VERSION);
1342
- program.command("create [name]").description("\u6839\u636E\u6807\u51C6\u6A21\u677F\u521B\u5EFA\u9879\u76EE").option("-c, --category <category>", "\u9879\u76EE\u7C7B\u578B\uFF1Afrontend\u3001backend \u6216 mobile").option("-t, --template <id>", "\u6A21\u677F ID").option("--features <ids>", "\u542F\u7528\u7684\u6A21\u677F\u80FD\u529B\uFF0C\u591A\u4E2A ID \u4F7F\u7528\u9017\u53F7\u5206\u9694").option("--no-standards", "\u4E0D\u542F\u7528\u6A21\u677F\u63D0\u4F9B\u7684 Git/\u4EE3\u7801\u6807\u51C6\u5316\u80FD\u529B").option("--source <path-or-url>", "\u8986\u76D6\u6A21\u677F\u6E90\uFF08\u672C\u5730\u76EE\u5F55\u6216 Git URL\uFF09").option("--ref <branch-or-tag>", "Git \u5206\u652F\u6216\u6807\u7B7E\uFF1B\u9ED8\u8BA4\u4F7F\u7528\u6A21\u677F Catalog \u914D\u7F6E").option("--module <name>", "\u5E73\u53F0\u6A21\u5757\u6807\u8BC6").option("--title <title>", "\u7CFB\u7EDF\u6807\u9898").option("--port <port>", "\u5F00\u53D1\u7AEF\u53E3").option("--npm-registry <url>", "npm registry\uFF08\u9700\u5305\u542B\u4F01\u4E1A\u5B9A\u5236\u5305\uFF09").option("--jhlc-registry <url>", "@jhlc \u79C1\u6709 registry").option("--local-backend <url>", "\u672C\u5730\u540E\u7AEF\u5730\u5740").option("--local-public <url>", "\u672C\u5730 public \u5730\u5740").option("--config <json-file>", "\u4ECE JSON \u6587\u4EF6\u8BFB\u53D6\u521B\u5EFA\u53C2\u6570").option("-y, --yes", "\u63A5\u53D7\u6A21\u677F\u9ED8\u8BA4\u503C\uFF0C\u975E\u4EA4\u4E92\u521B\u5EFA").option("--dry-run", "\u53EA\u9884\u89C8\uFF0C\u4E0D\u5199\u5165\u6587\u4EF6").option("--skip-install", "\u8DF3\u8FC7\u4F9D\u8D56\u5B89\u88C5").option("--skip-git", "\u8DF3\u8FC7 Git \u521D\u59CB\u5316").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u540C\u540D\u76EE\u5F55").option("--no-cache", "\u4E0D\u4F7F\u7528\u5DF2\u6709\u8FDC\u7A0B\u6A21\u677F\u7F13\u5B58").action(createCommand);
1349
+ program.command("create [name]").description("\u6839\u636E\u6807\u51C6\u6A21\u677F\u521B\u5EFA\u9879\u76EE").option("-c, --category <category>", "\u9879\u76EE\u7C7B\u578B\uFF1Afrontend\u3001backend \u6216 mobile").option("-t, --template <id>", "\u6A21\u677F ID").option("--features <ids>", "\u542F\u7528\u7684\u6A21\u677F\u80FD\u529B\uFF0C\u591A\u4E2A ID \u4F7F\u7528\u9017\u53F7\u5206\u9694").option("--no-standards", "\u4E0D\u542F\u7528\u6A21\u677F\u63D0\u4F9B\u7684 Git/\u4EE3\u7801\u6807\u51C6\u5316\u80FD\u529B").option("--source <path-or-url>", "\u8986\u76D6\u6A21\u677F\u6E90\uFF08\u672C\u5730\u76EE\u5F55\u6216 Git URL\uFF09").option("--ref <branch-or-tag>", "Git \u5206\u652F\u6216\u6807\u7B7E\uFF1B\u9ED8\u8BA4\u4F7F\u7528\u6A21\u677F Catalog \u914D\u7F6E").option("--module <name>", "\u5E73\u53F0\u6A21\u5757\u6807\u8BC6").option("--title <title>", "\u7CFB\u7EDF\u6807\u9898").option("--port <port>", "\u5F00\u53D1\u7AEF\u53E3").option("--npm-registry <url>", "npm registry\uFF08\u9700\u5305\u542B\u4F01\u4E1A\u5B9A\u5236\u5305\uFF09").option("--jhlc-registry <url>", "@jhlc \u79C1\u6709 registry").option("--local-backend <url>", "\u672C\u5730\u540E\u7AEF\u5730\u5740").option("--local-public <url>", "\u672C\u5730 public \u5730\u5740").option("--config <json-file>", "\u4ECE JSON \u6587\u4EF6\u8BFB\u53D6\u521B\u5EFA\u53C2\u6570").option("-y, --yes", "\u63A5\u53D7\u6A21\u677F\u9ED8\u8BA4\u503C\uFF0C\u975E\u4EA4\u4E92\u521B\u5EFA").option("--dry-run", "\u53EA\u9884\u89C8\uFF0C\u4E0D\u5199\u5165\u6587\u4EF6").option("--install", "\u521B\u5EFA\u5B8C\u6210\u540E\u5B89\u88C5\u4F9D\u8D56\uFF08\u9ED8\u8BA4\u4E0D\u5B89\u88C5\uFF09").option("--skip-install", "\u4E0D\u5B89\u88C5\u4F9D\u8D56\uFF08\u517C\u5BB9\u65E7\u547D\u4EE4\uFF09").option("--skip-git", "\u8DF3\u8FC7 Git \u521D\u59CB\u5316").option("--force", "\u8986\u76D6\u5DF2\u5B58\u5728\u7684\u540C\u540D\u76EE\u5F55").option("--no-cache", "\u4E0D\u4F7F\u7528\u5DF2\u6709\u8FDC\u7A0B\u6A21\u677F\u7F13\u5B58").action(createCommand);
1343
1350
  program.command("list").description("\u5217\u51FA\u53EF\u7528\u6A21\u677F").option("--json", "\u8F93\u51FA JSON").action(listCommand);
1344
1351
  program.command("doctor").description("\u68C0\u67E5\u672C\u673A\u73AF\u5883\u548C\u6A21\u677F\u53EF\u7528\u6027").option("--json", "\u8F93\u51FA JSON").action(doctorCommand);
1345
1352
  program.command("info [path]").description("\u663E\u793A\u5DF2\u751F\u6210\u9879\u76EE\u7684\u6A21\u677F\u4E0E\u7248\u672C\u4FE1\u606F").option("--json", "\u8F93\u51FA JSON").action(infoCommand);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../package.json","../src/constants.ts","../src/catalog.ts","../src/utils/fs.ts","../src/core/template-source.ts","../src/utils/process.ts","../src/core/template-cache.ts","../src/core/user-config.ts","../src/commands/create.ts","../src/core/project-generator.ts","../src/core/template-manifest.ts","../src/commands/doctor.ts","../src/commands/info.ts","../src/commands/list.ts","../src/commands/template.ts","../src/commands/config.ts","../src/commands/cache.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { COMMAND_NAME, CLI_VERSION } from \"./constants.js\";\nimport { findTemplate, loadCatalog } from \"./catalog.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./core/template-source.js\";\nimport { loadUserConfig } from \"./core/user-config.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { infoCommand } from \"./commands/info.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { validateTemplateCommand } from \"./commands/template.js\";\nimport {\n configGetCommand,\n configListCommand,\n configResetCommand,\n configSetCommand,\n configUnsetCommand\n} from \"./commands/config.js\";\nimport { cacheClearCommand, cacheListCommand } from \"./commands/cache.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n program\n .name(COMMAND_NAME)\n .description(\"JH4J Cloud 企业内部标准化项目脚手架\")\n .version(CLI_VERSION);\n\n program\n .command(\"create [name]\")\n .description(\"根据标准模板创建项目\")\n .option(\"-c, --category <category>\", \"项目类型:frontend、backend 或 mobile\")\n .option(\"-t, --template <id>\", \"模板 ID\")\n .option(\"--features <ids>\", \"启用的模板能力,多个 ID 使用逗号分隔\")\n .option(\"--no-standards\", \"不启用模板提供的 Git/代码标准化能力\")\n .option(\"--source <path-or-url>\", \"覆盖模板源(本地目录或 Git URL)\")\n .option(\"--ref <branch-or-tag>\", \"Git 分支或标签;默认使用模板 Catalog 配置\")\n .option(\"--module <name>\", \"平台模块标识\")\n .option(\"--title <title>\", \"系统标题\")\n .option(\"--port <port>\", \"开发端口\")\n .option(\"--npm-registry <url>\", \"npm registry(需包含企业定制包)\")\n .option(\"--jhlc-registry <url>\", \"@jhlc 私有 registry\")\n .option(\"--local-backend <url>\", \"本地后端地址\")\n .option(\"--local-public <url>\", \"本地 public 地址\")\n .option(\"--config <json-file>\", \"从 JSON 文件读取创建参数\")\n .option(\"-y, --yes\", \"接受模板默认值,非交互创建\")\n .option(\"--dry-run\", \"只预览,不写入文件\")\n .option(\"--skip-install\", \"跳过依赖安装\")\n .option(\"--skip-git\", \"跳过 Git 初始化\")\n .option(\"--force\", \"覆盖已存在的同名目录\")\n .option(\"--no-cache\", \"不使用已有远程模板缓存\")\n .action(createCommand);\n\n program\n .command(\"list\")\n .description(\"列出可用模板\")\n .option(\"--json\", \"输出 JSON\")\n .action(listCommand);\n program\n .command(\"doctor\")\n .description(\"检查本机环境和模板可用性\")\n .option(\"--json\", \"输出 JSON\")\n .action(doctorCommand);\n program\n .command(\"info [path]\")\n .description(\"显示已生成项目的模板与版本信息\")\n .option(\"--json\", \"输出 JSON\")\n .action(infoCommand);\n\n const template = program.command(\"template\").description(\"模板维护命令\");\n template\n .command(\"validate [path]\")\n .description(\"校验模板 manifest 与模板契约\")\n .action(async (templatePath?: string) => {\n if (templatePath) return validateTemplateCommand(templatePath);\n const config = await loadUserConfig();\n const selected = findTemplate(await loadCatalog(config));\n const acquired = await acquireTemplateFromSources(\n resolveTemplateSources(selected, undefined, config.templateSource),\n config.templateRef ?? selected.defaultRef,\n { cacheTtlMinutes: config.cacheTtlMinutes }\n );\n try {\n return await validateTemplateCommand(acquired.root);\n } finally {\n await acquired.cleanup();\n }\n });\n\n const config = program.command(\"config\").description(\"管理用户默认配置\");\n config\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(configListCommand);\n config.command(\"get <key>\").action(configGetCommand);\n config.command(\"set <key> <value>\").action(configSetCommand);\n config.command(\"unset <key>\").action(configUnsetCommand);\n config.command(\"reset\").action(configResetCommand);\n\n const cache = program.command(\"cache\").description(\"管理远程模板缓存\");\n cache\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(cacheListCommand);\n cache.command(\"clear\").action(cacheClearCommand);\n\n return program;\n}\n\nexport async function runCli(argv = process.argv): Promise<void> {\n await createProgram().parseAsync(argv);\n}\n","{\n \"name\": \"@agile-team/jh4j-cloud-cli\",\n \"version\": \"0.4.0\",\n \"description\": \"JH4J Cloud 企业内部标准化项目脚手架\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/ChenyCHENYU/jh4j-cloud-cli.git\"\n },\n \"homepage\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli/issues\"\n },\n \"type\": \"module\",\n \"engines\": {\n \"node\": \"^22.12.0 || ^24.0.0\",\n \"pnpm\": \">=11.8.0\"\n },\n \"packageManager\": \"pnpm@11.8.0\",\n \"bin\": {\n \"jh4j\": \"bin/jh4j.js\"\n },\n \"files\": [\n \"bin\",\n \"dist\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"catalog.schema.json\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"start\": \"node bin/jh4j.js\",\n \"check\": \"pnpm typecheck && pnpm test && pnpm build\",\n \"prepack\": \"pnpm check\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.7.0\",\n \"commander\": \"^15.0.0\",\n \"semver\": \"^7.8.5\",\n \"tar\": \"^7.5.19\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.13.3\",\n \"@types/semver\": \"7.7.1\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\",\n \"vitest\": \"4.1.10\"\n }\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\n\nexport const CLI_NAME = \"@agile-team/jh4j-cloud-cli\";\nexport const CLI_VERSION = packageJson.version;\nexport const COMMAND_NAME = \"jh4j\";\nexport const SUPPORTED_NODE_MAJORS = new Set([22, 24]);\nexport const TEMPLATE_SOURCE_ENV = \"JH4J_UI_TEMPLATE_SOURCE\";\nexport const JH4J_HOME_ENV = \"JH4J_HOME\";\nexport const CATALOG_FILE_ENV = \"JH4J_CATALOG_FILE\";\nexport const USER_CONFIG_SCHEMA_VERSION = 1;\n","import { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { CATALOG_FILE_ENV, TEMPLATE_SOURCE_ENV } from \"./constants.js\";\nimport { readJson } from \"./utils/fs.js\";\nimport type { CatalogFile, CatalogTemplate, UserConfig } from \"./types.js\";\n\nconst siblingTemplatePath = fileURLToPath(\n new URL(\"../../jh4j-ui-template/\", import.meta.url)\n);\nconst siblingMobileTemplatePath = fileURLToPath(\n new URL(\"../../../Robot_H5/\", import.meta.url)\n);\nconst remoteTemplateSources = [\n \"https://github.com/ChenyCHENYU/jh4j-ui-template.git\",\n \"https://gitee.com/ycyplus163/jh4j-ui-template.git\"\n];\nconst remoteMobileTemplateSources = [\n \"https://github.com/ChenyCHENYU/Robot_H5.git\",\n \"https://gitee.com/ycyplus163/robot_-h5.git\"\n];\n\nexport const BUILTIN_TEMPLATES: CatalogTemplate[] = [\n {\n id: \"web.jh4j-mf-remote\",\n name: \"JH4J PC 微前端业务模板\",\n description: \"Vue 3 + Vite + Module Federation 标准业务子系统\",\n category: \"frontend\",\n sourceEnvironment: TEMPLATE_SOURCE_ENV,\n defaultSource: existsSync(siblingTemplatePath)\n ? siblingTemplatePath\n : remoteTemplateSources[0],\n sources: remoteTemplateSources,\n defaultRef: \"main\",\n status: \"beta\",\n tags: [\"vue\", \"vite\", \"module-federation\", \"pc\"]\n },\n {\n id: \"mobile.robot-h5\",\n name: \"JH4J 移动端 H5 模板\",\n description: \"Vue 3 + Vite 7 + Vant 4 企业级移动端 H5 应用\",\n category: \"mobile\",\n sourceEnvironment: TEMPLATE_SOURCE_ENV,\n defaultSource: existsSync(siblingMobileTemplatePath)\n ? siblingMobileTemplatePath\n : remoteMobileTemplateSources[0],\n sources: remoteMobileTemplateSources,\n defaultRef: \"v1.6.0\",\n status: \"beta\",\n tags: [\"vue\", \"vite\", \"vant\", \"h5\", \"mobile\"]\n }\n];\n\nfunction validateCatalogTemplate(template: CatalogTemplate): void {\n if (!template.id || !template.name || !template.category) {\n throw new Error(\"Catalog 模板缺少 id、name 或 category\");\n }\n if (!new Set([\"frontend\", \"backend\", \"mobile\"]).has(template.category)) {\n throw new Error(`Catalog 模板 ${template.id} 的 category 无效`);\n }\n if (!new Set([\"stable\", \"beta\"]).has(template.status)) {\n throw new Error(`Catalog 模板 ${template.id} 的 status 无效`);\n }\n if (!template.defaultRef) {\n throw new Error(`Catalog 模板 ${template.id} 缺少 defaultRef`);\n }\n if (!template.defaultSource && !template.sourceEnvironment) {\n throw new Error(`Catalog 模板 ${template.id} 没有可解析的模板源`);\n }\n if (template.sources?.some((source) => !source.trim())) {\n throw new Error(`Catalog 模板 ${template.id} 包含空的备用源`);\n }\n}\n\nfunction resolveCatalogSource(source: string, catalogDirectory: string): string {\n const isRemote =\n /^(?:https?|ssh|file):\\/\\//.test(source) || source.startsWith(\"git@\");\n return isRemote || path.isAbsolute(source)\n ? source\n : path.resolve(catalogDirectory, source);\n}\n\nexport async function loadCatalog(config?: UserConfig): Promise<CatalogTemplate[]> {\n const configuredFile = process.env[CATALOG_FILE_ENV] || config?.catalogFile;\n if (!configuredFile) return [...BUILTIN_TEMPLATES];\n\n const catalogPath = path.resolve(configuredFile);\n if (!existsSync(catalogPath)) {\n throw new Error(`Catalog 文件不存在: ${catalogPath}`);\n }\n const external = await readJson<CatalogFile>(catalogPath);\n if (external.schemaVersion !== 1 || !Array.isArray(external.templates)) {\n throw new Error(`Catalog 文件格式无效: ${catalogPath}`);\n }\n const catalogDirectory = path.dirname(catalogPath);\n external.templates = external.templates.map((template) => {\n return {\n ...template,\n defaultSource: resolveCatalogSource(\n template.defaultSource,\n catalogDirectory\n ),\n sources: template.sources?.map((source) =>\n resolveCatalogSource(source, catalogDirectory)\n )\n };\n });\n external.templates.forEach(validateCatalogTemplate);\n\n const merged = new Map(BUILTIN_TEMPLATES.map((item) => [item.id, item]));\n external.templates.forEach((item) => merged.set(item.id, item));\n return [...merged.values()];\n}\n\nexport function findTemplate(\n catalog: CatalogTemplate[],\n id?: string\n): CatalogTemplate {\n const selected = id ?? catalog[0]?.id;\n const template = catalog.find((item) => item.id === selected);\n if (!template) {\n throw new Error(\n `模板不存在: ${selected}。可用模板: ${catalog.map((item) => item.id).join(\", \")}`\n );\n }\n return template;\n}\n","import { cp, mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst EXCLUDED_TEMPLATE_PATHS = new Set([\n \".git\",\n \".jhlc\",\n \"dist\",\n \"node_modules\"\n]);\n\nexport async function readJson<T>(file: string): Promise<T> {\n return JSON.parse(await readFile(file, \"utf8\")) as T;\n}\n\nexport async function writeJson(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function isDirectory(directory: string): Promise<boolean> {\n try {\n return (await stat(directory)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function isDirectoryEmpty(directory: string): Promise<boolean> {\n if (!existsSync(directory)) return true;\n const { readdir } = await import(\"node:fs/promises\");\n return (await readdir(directory)).length === 0;\n}\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n targetRoot: string\n): Promise<void> {\n await mkdir(targetRoot, { recursive: true });\n await cp(sourceRoot, targetRoot, {\n recursive: true,\n force: true,\n filter(source) {\n const relative = path.relative(sourceRoot, source);\n if (!relative) return true;\n const [topLevel] = relative.split(path.sep);\n return !EXCLUDED_TEMPLATE_PATHS.has(topLevel);\n }\n });\n}\n\nexport async function removePath(target: string): Promise<void> {\n await rm(target, { recursive: true, force: true, maxRetries: 3 });\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { x as extractTar } from \"tar\";\nimport type { CatalogTemplate } from \"../types.js\";\nimport { isDirectory } from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n createTemplateCacheStaging,\n isTemplateCacheFresh,\n readTemplateCacheEntry\n} from \"./template-cache.js\";\n\nconst MAX_ARCHIVE_BYTES = 200 * 1024 * 1024;\n\nexport interface AcquiredTemplate {\n root: string;\n source: string;\n cleanup(): Promise<void>;\n}\n\nexport function resolveTemplateSource(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string {\n return resolveTemplateSources(template, override, configuredSource)[0];\n}\n\nexport function resolveTemplateSources(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string[] {\n const exclusiveSource =\n override ||\n (template.sourceEnvironment\n ? process.env[template.sourceEnvironment]\n : undefined) ||\n configuredSource;\n if (exclusiveSource) return [exclusiveSource];\n return [...new Set([template.defaultSource, ...(template.sources ?? [])])];\n}\n\nfunction isGitSource(source: string): boolean {\n return (\n source.startsWith(\"git@\") ||\n source.startsWith(\"ssh://\") ||\n source.startsWith(\"file://\") ||\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.endsWith(\".git\")\n );\n}\n\nfunction isArchiveSource(source: string): boolean {\n const pathname = source.split(/[?#]/, 1)[0].toLowerCase();\n return pathname.endsWith(\".tgz\") || pathname.endsWith(\".tar.gz\") || pathname.endsWith(\".tar\");\n}\n\nasync function getFreshCache(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate | null> {\n const cacheEntry = await readTemplateCacheEntry(source, ref);\n if (\n !options.noCache &&\n cacheEntry &&\n isTemplateCacheFresh(cacheEntry, options.cacheTtlMinutes ?? 60)\n ) {\n return {\n root: cacheEntry.root,\n source: `${source}#${ref} (cache)`,\n async cleanup() {}\n };\n }\n return null;\n}\n\nasync function normalizeExtractedTemplate(\n stagingRoot: string,\n templateRoot: string\n): Promise<void> {\n if (existsSync(path.join(templateRoot, \"template.manifest.json\"))) return;\n const children = await readdir(templateRoot, { withFileTypes: true });\n const candidates = children.filter(\n (entry) =>\n entry.isDirectory() &&\n existsSync(path.join(templateRoot, entry.name, \"template.manifest.json\"))\n );\n if (candidates.length !== 1) {\n throw new Error(\"压缩包根目录或唯一一级目录中未找到 template.manifest.json\");\n }\n const normalizedRoot = path.join(stagingRoot, \".normalized-template\");\n await rename(path.join(templateRoot, candidates[0].name), normalizedRoot);\n await rm(templateRoot, { recursive: true, force: true });\n await rename(normalizedRoot, templateRoot);\n}\n\nasync function acquireArchiveTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate> {\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n const archiveFile = path.join(cacheStaging.stagingRoot, \"template.tgz\");\n try {\n if (source.startsWith(\"http://\") || source.startsWith(\"https://\")) {\n const response = await fetch(source, { signal: AbortSignal.timeout(60_000) });\n if (!response.ok) {\n throw new Error(`模板压缩包下载失败: HTTP ${response.status}`);\n }\n const declaredLength = Number(response.headers.get(\"content-length\") || 0);\n if (declaredLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n const archiveBuffer = Buffer.from(await response.arrayBuffer());\n if (archiveBuffer.byteLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n await writeFile(archiveFile, archiveBuffer);\n } else {\n const { copyFile } = await import(\"node:fs/promises\");\n await copyFile(path.resolve(source), archiveFile);\n }\n await mkdir(cacheStaging.templateRoot, { recursive: true });\n await extractTar({ file: archiveFile, cwd: cacheStaging.templateRoot });\n await normalizeExtractedTemplate(\n cacheStaging.stagingRoot,\n cacheStaging.templateRoot\n );\n await rm(archiveFile, { force: true });\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source} (archive)`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n const localPath = path.resolve(source);\n if (existsSync(localPath)) {\n if (await isDirectory(localPath)) {\n return {\n root: localPath,\n source: localPath,\n async cleanup() {}\n };\n }\n if (isArchiveSource(localPath)) {\n return acquireArchiveTemplate(localPath, ref, options);\n }\n throw new Error(`模板源不是目录或支持的 tar 压缩包: ${localPath}`);\n }\n\n if (isArchiveSource(source)) {\n return acquireArchiveTemplate(source, ref, options);\n }\n\n if (!isGitSource(source)) {\n throw new Error(`模板源不存在: ${source}`);\n }\n\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n try {\n await runCommand(\n \"git\",\n [\n \"-c\",\n \"http.lowSpeedLimit=1024\",\n \"-c\",\n \"http.lowSpeedTime=15\",\n \"clone\",\n \"--depth\",\n \"1\",\n \"--branch\",\n ref,\n source,\n cacheStaging.templateRoot\n ],\n { stdio: \"pipe\", env: { GIT_TERMINAL_PROMPT: \"0\" } }\n );\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source}#${ref}`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplateFromSources(\n sources: string[],\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n if (!sources.length) throw new Error(\"没有可用的模板源\");\n const failures: string[] = [];\n for (const source of [...new Set(sources)]) {\n try {\n return await acquireTemplate(source, ref, options);\n } catch (error) {\n failures.push(`${source}: ${(error as Error).message}`);\n }\n }\n throw new Error(`所有模板源均不可用:\\n- ${failures.join(\"\\n- \")}`);\n}\n","import { spawn } from \"node:child_process\";\n\nexport interface RunCommandOptions {\n cwd?: string;\n stdio?: \"inherit\" | \"pipe\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport function platformCommand(command: string): string {\n if (process.platform !== \"win32\") return command;\n return command === \"pnpm\" || command === \"npm\" || command === \"npx\"\n ? `${command}.cmd`\n : command;\n}\n\nexport async function runCommand(\n command: string,\n args: string[],\n options: RunCommandOptions = {}\n): Promise<string> {\n const stdio = options.stdio ?? \"inherit\";\n return new Promise((resolve, reject) => {\n const executable = platformCommand(command);\n const isWindowsCommand =\n process.platform === \"win32\" && executable.endsWith(\".cmd\");\n const spawnExecutable = isWindowsCommand\n ? process.env.ComSpec || \"cmd.exe\"\n : executable;\n const spawnArgs = isWindowsCommand\n ? [\"/d\", \"/s\", \"/c\", executable, ...args]\n : args;\n const child = spawn(spawnExecutable, spawnArgs, {\n cwd: options.cwd,\n stdio,\n env: { ...process.env, ...options.env },\n windowsHide: true\n });\n\n let output = \"\";\n if (stdio === \"pipe\") {\n child.stdout?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n }\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) {\n resolve(output.trim());\n return;\n }\n reject(\n new Error(\n `${command} ${args.join(\" \")} 执行失败(exit ${code ?? \"unknown\"})${output ? `\\n${output.trim()}` : \"\"}`\n )\n );\n });\n });\n}\n\nexport async function inspectCommand(\n command: string,\n args: string[] = [\"--version\"]\n): Promise<{ ok: boolean; output: string }> {\n try {\n return { ok: true, output: await runCommand(command, args, { stdio: \"pipe\" }) };\n } catch (error) {\n return { ok: false, output: (error as Error).message };\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getJh4jHome } from \"./user-config.js\";\nimport { readJson, removePath, writeJson } from \"../utils/fs.js\";\nimport type { TemplateCacheMetadata } from \"../types.js\";\n\nconst CACHE_SCHEMA_VERSION = 1;\n\nexport interface TemplateCacheEntry {\n key: string;\n root: string;\n metadata: TemplateCacheMetadata;\n sizeBytes: number;\n}\n\nexport function getTemplateCacheRoot(): string {\n return path.join(getJh4jHome(), \"cache\", \"templates\");\n}\n\nexport function getTemplateCacheKey(source: string, ref: string): string {\n return createHash(\"sha256\").update(`${source}\\0${ref}`).digest(\"hex\").slice(0, 20);\n}\n\nfunction getEntryPaths(key: string) {\n const entryRoot = path.join(getTemplateCacheRoot(), key);\n return {\n entryRoot,\n templateRoot: path.join(entryRoot, \"template\"),\n metadataPath: path.join(entryRoot, \"metadata.json\")\n };\n}\n\nexport async function readTemplateCacheEntry(\n source: string,\n ref: string\n): Promise<TemplateCacheEntry | null> {\n const key = getTemplateCacheKey(source, ref);\n const paths = getEntryPaths(key);\n if (!existsSync(paths.templateRoot) || !existsSync(paths.metadataPath)) return null;\n try {\n const metadata = await readJson<TemplateCacheMetadata>(paths.metadataPath);\n if (\n metadata.schemaVersion !== CACHE_SCHEMA_VERSION ||\n metadata.source !== source ||\n metadata.ref !== ref\n ) {\n return null;\n }\n return {\n key,\n root: paths.templateRoot,\n metadata,\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n };\n } catch {\n return null;\n }\n}\n\nexport function isTemplateCacheFresh(\n entry: TemplateCacheEntry,\n ttlMinutes: number\n): boolean {\n if (ttlMinutes <= 0) return false;\n const cachedAt = Date.parse(entry.metadata.cachedAt);\n return Number.isFinite(cachedAt) && Date.now() - cachedAt < ttlMinutes * 60_000;\n}\n\nexport async function createTemplateCacheStaging(\n source: string,\n ref: string\n): Promise<{\n key: string;\n entryRoot: string;\n stagingRoot: string;\n templateRoot: string;\n commit(): Promise<void>;\n cleanup(): Promise<void>;\n}> {\n const key = getTemplateCacheKey(source, ref);\n const cacheRoot = getTemplateCacheRoot();\n await mkdir(cacheRoot, { recursive: true });\n const stagingRoot = path.join(\n cacheRoot,\n `.${key}.tmp-${process.pid}-${Date.now()}`\n );\n const templateRoot = path.join(stagingRoot, \"template\");\n const entryRoot = path.join(cacheRoot, key);\n await mkdir(stagingRoot, { recursive: true });\n\n return {\n key,\n entryRoot,\n stagingRoot,\n templateRoot,\n async commit() {\n await writeJson(path.join(stagingRoot, \"metadata.json\"), {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source,\n ref,\n cachedAt: new Date().toISOString()\n } satisfies TemplateCacheMetadata);\n await removePath(entryRoot);\n await rename(stagingRoot, entryRoot);\n },\n cleanup: () => removePath(stagingRoot)\n };\n}\n\nasync function calculateDirectorySize(directory: string): Promise<number> {\n let total = 0;\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(directory, entry.name);\n if (entry.isDirectory()) total += await calculateDirectorySize(absolute);\n else if (entry.isFile()) total += (await stat(absolute)).size;\n }\n return total;\n}\n\nexport async function listTemplateCache(): Promise<TemplateCacheEntry[]> {\n const cacheRoot = getTemplateCacheRoot();\n if (!existsSync(cacheRoot)) return [];\n const entries: TemplateCacheEntry[] = [];\n for (const directory of await readdir(cacheRoot, { withFileTypes: true })) {\n if (!directory.isDirectory() || directory.name.startsWith(\".\")) continue;\n const paths = getEntryPaths(directory.name);\n if (!existsSync(paths.metadataPath) || !existsSync(paths.templateRoot)) continue;\n try {\n entries.push({\n key: directory.name,\n root: paths.templateRoot,\n metadata: await readJson<TemplateCacheMetadata>(paths.metadataPath),\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n });\n } catch {\n // 损坏条目由 clear 或下一次拉取覆盖。\n }\n }\n return entries.sort((a, b) =>\n b.metadata.cachedAt.localeCompare(a.metadata.cachedAt)\n );\n}\n\nexport async function clearTemplateCache(): Promise<void> {\n await removePath(getTemplateCacheRoot());\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { JH4J_HOME_ENV, USER_CONFIG_SCHEMA_VERSION } from \"../constants.js\";\nimport { readJson, writeJson } from \"../utils/fs.js\";\nimport type { UserConfig } from \"../types.js\";\n\nexport const DEFAULT_USER_CONFIG: UserConfig = {\n schemaVersion: USER_CONFIG_SCHEMA_VERSION,\n autoInstall: true,\n autoGit: true,\n cacheTtlMinutes: 60\n};\n\nexport function getJh4jHome(): string {\n return path.resolve(process.env[JH4J_HOME_ENV] || path.join(os.homedir(), \".jh4j\"));\n}\n\nexport function getUserConfigPath(): string {\n return path.join(getJh4jHome(), \"config.json\");\n}\n\nexport async function loadUserConfig(): Promise<UserConfig> {\n const configPath = getUserConfigPath();\n if (!existsSync(configPath)) return { ...DEFAULT_USER_CONFIG };\n\n const stored = await readJson<Partial<UserConfig>>(configPath);\n if (\n stored.schemaVersion !== undefined &&\n stored.schemaVersion !== USER_CONFIG_SCHEMA_VERSION\n ) {\n throw new Error(\n `不支持的用户配置版本: ${stored.schemaVersion},当前要求 ${USER_CONFIG_SCHEMA_VERSION}`\n );\n }\n return { ...DEFAULT_USER_CONFIG, ...stored };\n}\n\nexport async function saveUserConfig(config: UserConfig): Promise<void> {\n await writeJson(getUserConfigPath(), {\n ...config,\n schemaVersion: USER_CONFIG_SCHEMA_VERSION\n });\n}\n\nconst CONFIG_KEYS = new Set<keyof UserConfig>([\n \"catalogFile\",\n \"templateSource\",\n \"templateRef\",\n \"npmRegistry\",\n \"jhlcRegistry\",\n \"autoInstall\",\n \"autoGit\",\n \"cacheTtlMinutes\"\n]);\n\nexport function parseUserConfigValue(\n key: string,\n rawValue: string\n): [keyof UserConfig, UserConfig[keyof UserConfig]] {\n if (!CONFIG_KEYS.has(key as keyof UserConfig)) {\n throw new Error(`不支持的配置项: ${key}`);\n }\n const typedKey = key as keyof UserConfig;\n if (typedKey === \"autoInstall\" || typedKey === \"autoGit\") {\n const normalized = rawValue.toLowerCase();\n if (!new Set([\"true\", \"false\"]).has(normalized)) {\n throw new Error(`${key} 只能是 true 或 false`);\n }\n return [typedKey, normalized === \"true\"];\n }\n if (typedKey === \"cacheTtlMinutes\") {\n const value = Number(rawValue);\n if (!Number.isInteger(value) || value < 0 || value > 10080) {\n throw new Error(\"cacheTtlMinutes 必须是 0 到 10080 之间的整数\");\n }\n return [typedKey, value];\n }\n return [typedKey, rawValue.trim()];\n}\n","import * as prompts from \"@clack/prompts\";\nimport { findTemplate, loadCatalog } from \"../catalog.js\";\nimport { generateProject } from \"../core/project-generator.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n TemplateCategory\n} from \"../types.js\";\n\nconst CATEGORY_OPTIONS: Array<{\n value: TemplateCategory;\n label: string;\n hint: string;\n}> = [\n { value: \"frontend\", label: \"前端\", hint: \"PC、Web 与微前端应用\" },\n { value: \"backend\", label: \"后端\", hint: \"Java 服务与云原生应用\" },\n { value: \"mobile\", label: \"移动端\", hint: \"App、H5 与跨端应用\" }\n];\n\nfunction isCategory(value: string): value is TemplateCategory {\n return CATEGORY_OPTIONS.some((item) => item.value === value);\n}\n\nexport function templatesByCategory(\n templates: CatalogTemplate[],\n category: TemplateCategory\n): CatalogTemplate[] {\n return templates.filter((template) => template.category === category);\n}\n\nasync function selectCategory(\n templates: CatalogTemplate[],\n requestedCategory: string | undefined,\n nonInteractive: boolean\n): Promise<TemplateCategory> {\n if (requestedCategory) {\n if (!isCategory(requestedCategory)) {\n throw new Error(\n `项目类型无效: ${requestedCategory}。可用值: frontend、backend、mobile`\n );\n }\n if (!templatesByCategory(templates, requestedCategory).length) {\n throw new Error(`项目类型 ${requestedCategory} 暂无可用模板`);\n }\n return requestedCategory;\n }\n\n const firstAvailable = CATEGORY_OPTIONS.find(\n (item) => templatesByCategory(templates, item.value).length > 0\n );\n if (!firstAvailable) throw new Error(\"Catalog 中没有可用模板\");\n if (nonInteractive) return firstAvailable.value;\n\n const selected = await prompts.select({\n message: \"选择项目类型\",\n options: CATEGORY_OPTIONS.map((item) => {\n const count = templatesByCategory(templates, item.value).length;\n return {\n value: item.value,\n label: item.label,\n hint: count ? `${item.hint} · ${count} 个模板` : `${item.hint} · 暂未提供`,\n disabled: count === 0\n };\n })\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return selected as TemplateCategory;\n}\n\nasync function selectTemplate(\n templates: CatalogTemplate[],\n options: CreateOptions\n): Promise<CatalogTemplate> {\n if (options.template) {\n const selected = findTemplate(templates, options.template);\n if (options.category && selected.category !== options.category) {\n throw new Error(\n `模板 ${selected.id} 属于 ${selected.category},与 --category ${options.category} 不一致`\n );\n }\n return selected;\n }\n\n const category = await selectCategory(\n templates,\n options.category,\n Boolean(options.yes)\n );\n const candidates = templatesByCategory(templates, category);\n if (options.yes) return findTemplate(candidates);\n\n const selected = await prompts.select({\n message: \"选择项目模板\",\n options: candidates.map((template) => ({\n value: template.id,\n label: template.name,\n hint: `${template.status} · ${template.description}`\n }))\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return findTemplate(candidates, String(selected));\n}\n\nexport async function createCommand(\n requestedName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n prompts.intro(\"JH4J Cloud 项目创建\");\n const userConfig = await loadUserConfig();\n const catalog = await loadCatalog(userConfig);\n\n let projectName = requestedName;\n if (!projectName) {\n if (options.yes) throw new Error(\"非交互模式必须指定项目名称\");\n const answer = await prompts.text({\n message: \"项目名称\",\n placeholder: \"jh4j-ui-app\"\n });\n if (prompts.isCancel(answer)) throw new Error(\"用户取消创建\");\n projectName = String(answer);\n }\n\n const template = await selectTemplate(catalog, options);\n const result = await generateProject(\n template,\n projectName,\n options,\n process.cwd(),\n userConfig\n );\n if (options.dryRun) {\n prompts.outro(\"Dry Run 完成,未写入任何项目文件\");\n return;\n }\n\n prompts.note(\n [\n `目录: ${result.targetRoot}`,\n `模板: ${result.templateId}@${result.templateVersion}`,\n `来源: ${result.source}`,\n `能力: ${result.features.length ? result.features.join(\", \") : \"无可选能力\"}`,\n `依赖: ${result.installed ? \"已安装\" : \"未安装\"}`,\n `Git: ${result.gitInitialized ? \"main 已初始化\" : \"未初始化\"}`,\n \"\",\n `cd ${projectName}`,\n ...(!result.installed ? [\"pnpm install\"] : []),\n \"pnpm dev\"\n ].join(\"\\n\"),\n \"创建成功\"\n );\n prompts.outro(\"Happy coding!\");\n}\n","import { existsSync } from \"node:fs\";\nimport { rename, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as prompts from \"@clack/prompts\";\nimport { satisfies } from \"semver\";\nimport { CLI_NAME, CLI_VERSION } from \"../constants.js\";\nimport {\n copyTemplateTree,\n isDirectoryEmpty,\n readJson,\n removePath,\n writeJson\n} from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./template-source.js\";\nimport { loadTemplateManifest } from \"./template-manifest.js\";\nimport { DEFAULT_USER_CONFIG } from \"./user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n ProjectInput,\n TemplateManifest,\n UserConfig\n} from \"../types.js\";\n\nconst ENV_NAMES = [\"dev\", \"sit\", \"uat\", \"pre\", \"prd\"] as const;\ntype PartialProjectInput = Partial<Omit<ProjectInput, \"environments\">> & {\n environments?: Partial<ProjectInput[\"environments\"]>;\n};\n\nfunction cancelled(value: unknown): value is symbol {\n return prompts.isCancel(value);\n}\n\nfunction ensureProjectName(value: string): string {\n const name = value.trim();\n if (!/^[a-z0-9][a-z0-9._-]*$/.test(name)) {\n throw new Error(\"项目名称只能包含小写字母、数字、点、下划线和连字符\");\n }\n return name;\n}\n\nfunction inferModuleName(projectName: string): string {\n const inferred = projectName\n .replace(/^(?:jh4j|wl)-ui-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return /^[a-z][a-z0-9-]*$/.test(inferred) ? inferred : \"app\";\n}\n\nfunction ensureModuleName(value: string): string {\n const name = value.trim();\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n throw new Error(\"模块标识必须以小写字母开头,只能包含小写字母、数字和连字符\");\n }\n return name;\n}\n\nfunction ensurePort(value: string | number): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1024 || port > 65535) {\n throw new Error(\"开发端口必须是 1024 到 65535 之间的整数\");\n }\n return port;\n}\n\nfunction ensureHttpUrl(value: string, label: string): string {\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error();\n return value.replace(/\\/+$/, \"\");\n } catch {\n throw new Error(`${label} 必须是 http/https URL`);\n }\n}\n\nasync function askText(message: string, initialValue: string): Promise<string> {\n const answer = await prompts.text({ message, initialValue });\n if (cancelled(answer)) throw new Error(\"用户取消创建\");\n return String(answer).trim() || initialValue;\n}\n\nasync function loadCreateConfig(\n configFile: string | undefined,\n cwd: string\n): Promise<PartialProjectInput> {\n if (!configFile) return {};\n const resolved = path.resolve(cwd, configFile);\n if (!existsSync(resolved)) throw new Error(`创建配置文件不存在: ${resolved}`);\n return readJson<PartialProjectInput>(resolved);\n}\n\nfunction parseFeatureIds(value: string): string[] {\n return [...new Set(value.split(\",\").map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function collectTemplateFeatures(\n manifest: TemplateManifest,\n fileConfig: PartialProjectInput,\n options: CreateOptions\n): Promise<string[]> {\n const available = manifest.features ?? [];\n if (!available.length) return [];\n\n const knownIds = new Set(available.map((feature) => feature.id));\n let selected = options.features\n ? parseFeatureIds(options.features)\n : Array.isArray(fileConfig.features)\n ? fileConfig.features\n : available\n .filter((feature) => feature.defaultEnabled || feature.required)\n .map((feature) => feature.id);\n\n const unknown = selected.filter((id) => !knownIds.has(id));\n if (unknown.length) {\n throw new Error(\n `模板不支持以下能力: ${unknown.join(\", \")}。可用能力: ${[...knownIds].join(\", \")}`\n );\n }\n\n if (options.standards === false) {\n selected = selected.filter((id) => {\n const feature = available.find((item) => item.id === id);\n return feature?.package !== \"@robot-admin/git-standards\";\n });\n }\n\n if (!options.yes) {\n const selectable = available.filter(\n (feature) =>\n options.standards !== false ||\n feature.package !== \"@robot-admin/git-standards\"\n );\n if (selectable.length) {\n const answer = await prompts.multiselect({\n message: \"选择项目标准化能力\",\n options: selectable.map((feature) => ({\n value: feature.id,\n label: feature.name,\n hint: `${feature.description}${feature.package ? ` · ${feature.package}` : \"\"}`\n })),\n initialValues: selected,\n required: false\n });\n if (cancelled(answer)) throw new Error(\"用户取消创建\");\n selected = answer.map(String);\n }\n }\n\n for (const feature of available) {\n if (feature.required && !selected.includes(feature.id)) {\n selected.push(feature.id);\n }\n }\n return selected;\n}\n\nasync function collectProjectInput(\n projectName: string,\n manifest: TemplateManifest,\n sourceConfig: ProjectInput,\n fileConfig: PartialProjectInput,\n options: CreateOptions,\n userConfig: UserConfig,\n features: string[]\n): Promise<ProjectInput> {\n let moduleName = options.module ?? fileConfig.moduleName ?? inferModuleName(projectName);\n let title = options.title ?? fileConfig.title ?? sourceConfig.title;\n let port: string | number =\n options.port ?? fileConfig.devServerPort ?? sourceConfig.devServerPort;\n let npmRegistry =\n options.npmRegistry ??\n fileConfig.npmRegistry ??\n userConfig.npmRegistry ??\n sourceConfig.npmRegistry;\n let jhlcRegistry =\n options.jhlcRegistry ??\n fileConfig.jhlcRegistry ??\n userConfig.jhlcRegistry ??\n sourceConfig.jhlcRegistry;\n let localBackendUrl =\n options.localBackend ?? fileConfig.localBackendUrl ?? sourceConfig.localBackendUrl;\n let localPublicUrl =\n options.localPublic ?? fileConfig.localPublicUrl ?? sourceConfig.localPublicUrl;\n const environments = structuredClone(sourceConfig.environments);\n for (const [env, value] of Object.entries(fileConfig.environments ?? {})) {\n if (value && environments[env]) {\n environments[env] = { ...environments[env], ...value };\n }\n }\n\n if (!options.yes) {\n if (manifest.category !== \"mobile\") {\n moduleName = await askText(\"模块标识\", moduleName);\n }\n title = await askText(\n manifest.category === \"mobile\" ? \"应用标题\" : \"系统标题\",\n title\n );\n port = await askText(\"开发端口\", String(port));\n npmRegistry = await askText(\"npm registry\", npmRegistry);\n jhlcRegistry = await askText(\"@jhlc 私有 registry\", jhlcRegistry);\n localBackendUrl = await askText(\n manifest.category === \"mobile\" ? \"本地 API 地址\" : \"本地后端地址\",\n localBackendUrl\n );\n if (manifest.category !== \"mobile\") {\n localPublicUrl = await askText(\"本地 public 地址\", localPublicUrl);\n }\n\n if (manifest.category !== \"mobile\") {\n const configureEnvironments = await prompts.confirm({\n message: \"是否逐项确认五套环境地址\",\n initialValue: false\n });\n if (cancelled(configureEnvironments)) throw new Error(\"用户取消创建\");\n if (configureEnvironments) {\n for (const env of ENV_NAMES) {\n environments[env].webUrl = await askText(\n `${env.toUpperCase()} 平台地址`,\n environments[env].webUrl\n );\n environments[env].apiPrefix = await askText(\n `${env.toUpperCase()} API 前缀`,\n environments[env].apiPrefix\n );\n }\n }\n }\n }\n\n if (!title.trim()) throw new Error(\"系统标题不能为空\");\n for (const env of ENV_NAMES) {\n if (!environments[env]) throw new Error(`缺少 ${env.toUpperCase()} 环境配置`);\n environments[env] = {\n webUrl: ensureHttpUrl(environments[env].webUrl, `${env.toUpperCase()} 平台地址`),\n apiPrefix: environments[env].apiPrefix.replace(/^\\/+|\\/+$/g, \"\")\n };\n if (!environments[env].apiPrefix) {\n throw new Error(`${env.toUpperCase()} API 前缀不能为空`);\n }\n }\n\n return {\n projectName,\n moduleName: ensureModuleName(moduleName),\n title: title.trim(),\n devServerPort: ensurePort(port),\n npmRegistry: ensureHttpUrl(npmRegistry, \"npm registry\"),\n jhlcRegistry: ensureHttpUrl(jhlcRegistry, \"@jhlc 私有 registry\"),\n localBackendUrl: ensureHttpUrl(localBackendUrl, \"本地后端地址\"),\n localPublicUrl: ensureHttpUrl(localPublicUrl, \"本地 public 地址\"),\n environments,\n features\n };\n}\n\nfunction assertSafeTarget(cwd: string, target: string): void {\n if (path.dirname(target) !== cwd || target === cwd) {\n throw new Error(\"仅允许在当前目录创建一级项目目录\");\n }\n}\n\nasync function promoteStaging(\n stagingRoot: string,\n targetRoot: string,\n force: boolean\n): Promise<void> {\n const targetExists = existsSync(targetRoot);\n if (!targetExists) {\n await rename(stagingRoot, targetRoot);\n return;\n }\n\n if (!(await isDirectoryEmpty(targetRoot)) && !force) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const backupRoot = `${targetRoot}.jh4j-backup-${Date.now()}`;\n await rename(targetRoot, backupRoot);\n try {\n await rename(stagingRoot, targetRoot);\n } catch (error) {\n await rename(backupRoot, targetRoot);\n throw error;\n }\n try {\n await removePath(backupRoot);\n } catch {\n prompts.log.warn(`旧目录备份未能自动清理: ${backupRoot}`);\n }\n}\n\nexport interface GenerateProjectResult {\n targetRoot: string;\n templateId: string;\n templateVersion: string;\n source: string;\n features: string[];\n installed: boolean;\n gitInitialized: boolean;\n}\n\nexport async function generateProject(\n catalogTemplate: CatalogTemplate,\n requestedProjectName: string,\n options: CreateOptions,\n cwd = process.cwd(),\n configuredUserConfig: UserConfig = DEFAULT_USER_CONFIG\n): Promise<GenerateProjectResult> {\n const userConfig = { ...DEFAULT_USER_CONFIG, ...configuredUserConfig };\n const projectName = ensureProjectName(requestedProjectName);\n const resolvedCwd = path.resolve(cwd);\n const targetRoot = path.resolve(resolvedCwd, projectName);\n assertSafeTarget(resolvedCwd, targetRoot);\n if (\n existsSync(targetRoot) &&\n !(await isDirectoryEmpty(targetRoot)) &&\n !options.force\n ) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const ref = options.ref ?? userConfig.templateRef ?? catalogTemplate.defaultRef;\n const sourceValues = resolveTemplateSources(\n catalogTemplate,\n options.source,\n userConfig.templateSource\n );\n const acquired = await acquireTemplateFromSources(sourceValues, ref, {\n noCache: options.cache === false,\n cacheTtlMinutes: userConfig.cacheTtlMinutes\n });\n const stagingRoot = path.join(\n resolvedCwd,\n `.${projectName}.jh4j-tmp-${process.pid}-${Date.now()}`\n );\n let promoted = false;\n\n try {\n const manifest = await loadTemplateManifest(acquired.root);\n if (manifest.id !== catalogTemplate.id) {\n throw new Error(\n `模板 ID 不匹配:Catalog=${catalogTemplate.id},Manifest=${manifest.id}`\n );\n }\n if (!satisfies(process.versions.node, manifest.runtime.node)) {\n throw new Error(\n `当前 Node ${process.versions.node} 不满足模板要求 ${manifest.runtime.node}`\n );\n }\n\n const sourceProjectConfig = await readJson<\n Omit<ProjectInput, \"npmRegistry\" | \"jhlcRegistry\">\n >(path.join(acquired.root, \"project.config.json\"));\n const fileConfig = await loadCreateConfig(options.config, resolvedCwd);\n const features = await collectTemplateFeatures(manifest, fileConfig, options);\n const input = await collectProjectInput(\n projectName,\n manifest,\n {\n ...sourceProjectConfig,\n npmRegistry: manifest.defaults.npmRegistry,\n jhlcRegistry: manifest.defaults.jhlcRegistry\n },\n fileConfig,\n options,\n userConfig,\n features\n );\n\n const shouldInstall = !options.skipInstall && userConfig.autoInstall;\n const shouldInitializeGit = !options.skipGit && userConfig.autoGit;\n\n if (options.dryRun) {\n prompts.note(\n [\n `模板: ${manifest.id}@${manifest.version}`,\n `来源: ${acquired.source}`,\n `目标: ${targetRoot}`,\n `模块: ${input.moduleName}`,\n `端口: ${input.devServerPort}`,\n `能力: ${input.features.length ? input.features.join(\", \") : \"无可选能力\"}`,\n `安装依赖: ${shouldInstall ? \"是\" : \"否\"}`,\n `初始化 Git: ${shouldInitializeGit ? \"是\" : \"否\"}`\n ].join(\"\\n\"),\n \"Dry Run\"\n );\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: false,\n gitInitialized: false\n };\n }\n\n await copyTemplateTree(acquired.root, stagingRoot);\n const inputFile = path.join(stagingRoot, \".jh4j-cli-input.json\");\n await writeJson(inputFile, input);\n try {\n await runCommand(\n process.execPath,\n [\n path.join(stagingRoot, \"scripts\", \"setup-project.mjs\"),\n \"--yes\",\n \"--config\",\n inputFile,\n \"--created-by\",\n `${CLI_NAME}@${CLI_VERSION}`\n ],\n { cwd: stagingRoot, stdio: \"pipe\" }\n );\n } finally {\n await rm(inputFile, { force: true });\n }\n\n if (!existsSync(path.join(stagingRoot, manifest.generatedMetadata))) {\n throw new Error(`模板初始化未生成元数据: ${manifest.generatedMetadata}`);\n }\n await promoteStaging(stagingRoot, targetRoot, Boolean(options.force));\n promoted = true;\n\n let gitInitialized = false;\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"init\", \"-b\", \"main\"], {\n cwd: targetRoot,\n stdio: \"pipe\"\n });\n gitInitialized = true;\n }\n\n if (shouldInstall) {\n try {\n await runCommand(\"pnpm\", [\"install\"], { cwd: targetRoot });\n } catch (error) {\n throw new Error(\n `项目已生成,但依赖安装失败;目录已保留在 ${targetRoot}\\n${(error as Error).message}`\n );\n }\n }\n\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"add\", \"-A\"], { cwd: targetRoot, stdio: \"pipe\" });\n try {\n await runCommand(\n \"git\",\n [\"commit\", \"-m\", `feat(init): 基于 ${manifest.id}@${manifest.version} 初始化`],\n {\n cwd: targetRoot,\n stdio: \"pipe\",\n env: { HUSKY: \"0\" }\n }\n );\n } catch (error) {\n prompts.log.warn(`Git 已初始化,但初始提交未完成:${(error as Error).message}`);\n }\n }\n\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: shouldInstall,\n gitInitialized\n };\n } finally {\n if (!promoted && existsSync(stagingRoot)) await removePath(stagingRoot);\n await acquired.cleanup();\n }\n}\n","import path from \"node:path\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { TemplateManifest } from \"../types.js\";\n\nexport async function loadTemplateManifest(\n templateRoot: string\n): Promise<TemplateManifest> {\n const manifest = await readJson<TemplateManifest>(\n path.join(templateRoot, \"template.manifest.json\")\n );\n const errors: string[] = [];\n\n if (manifest.schemaVersion !== 1) errors.push(\"schemaVersion 必须为 1\");\n if (!manifest.id) errors.push(\"缺少模板 id\");\n if (!manifest.name) errors.push(\"缺少模板名称\");\n if (!/^\\d+\\.\\d+\\.\\d+([+-].+)?$/.test(manifest.version ?? \"\")) {\n errors.push(\"模板 version 不是有效的语义化版本\");\n }\n if (!manifest.runtime?.node || !manifest.runtime?.packageManager) {\n errors.push(\"缺少模板运行时约束\");\n }\n if (!manifest.entry?.nonInteractive) {\n errors.push(\"缺少非交互初始化入口\");\n }\n const featureIds = new Set<string>();\n for (const feature of manifest.features ?? []) {\n if (!/^[a-z][a-z0-9-]*$/.test(feature.id)) {\n errors.push(`模板能力 id 无效: ${feature.id}`);\n }\n if (featureIds.has(feature.id)) {\n errors.push(`模板能力 id 重复: ${feature.id}`);\n }\n featureIds.add(feature.id);\n if (!feature.name || !feature.description) {\n errors.push(`模板能力 ${feature.id} 缺少名称或说明`);\n }\n }\n\n if (errors.length) {\n throw new Error(`模板 manifest 无效:\\n- ${errors.join(\"\\n- \")}`);\n }\n return manifest;\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, writeFile, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { coerce, gte, satisfies } from \"semver\";\nimport { loadCatalog } from \"../catalog.js\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { resolveTemplateSources } from \"../core/template-source.js\";\nimport { getJh4jHome, loadUserConfig } from \"../core/user-config.js\";\nimport { inspectCommand } from \"../utils/process.js\";\nimport type { CatalogTemplate, UserConfig } from \"../types.js\";\n\nexport interface CheckResult {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nasync function checkHomeWritable(): Promise<CheckResult> {\n const home = getJh4jHome();\n const probe = path.join(home, `.write-probe-${process.pid}`);\n try {\n await mkdir(home, { recursive: true });\n await writeFile(probe, \"ok\", \"utf8\");\n await rm(probe, { force: true });\n return { name: \"JH4J_HOME\", ok: true, detail: home };\n } catch (error) {\n return { name: \"JH4J_HOME\", ok: false, detail: (error as Error).message };\n }\n}\n\nexport async function collectDoctorChecks(\n suppliedConfig?: UserConfig,\n suppliedCatalog?: CatalogTemplate[]\n): Promise<CheckResult[]> {\n const config = suppliedConfig ?? (await loadUserConfig());\n const catalog = suppliedCatalog ?? (await loadCatalog(config));\n const [git, pnpm, home] = await Promise.all([\n inspectCommand(\"git\"),\n inspectCommand(\"pnpm\"),\n checkHomeWritable()\n ]);\n const pnpmVersion = coerce(pnpm.output)?.version;\n const checks: CheckResult[] = [\n {\n name: \"Node.js\",\n ok: satisfies(process.versions.node, \"^22.12.0 || ^24.0.0\"),\n detail: `${process.versions.node}(要求 Node 22.12+ 或 24.x)`\n },\n { name: \"Git\", ok: git.ok, detail: git.output },\n {\n name: \"pnpm\",\n ok: pnpm.ok && Boolean(pnpmVersion && gte(pnpmVersion, \"11.8.0\")),\n detail: pnpm.output\n },\n home\n ];\n\n for (const template of catalog) {\n const sources = resolveTemplateSources(\n template,\n undefined,\n config.templateSource\n );\n const source = sources[0];\n if (!existsSync(source)) {\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.startsWith(\"git@\"),\n detail: `远程候选源(创建时依次验证): ${sources.join(\" → \")}`\n });\n continue;\n }\n try {\n const manifest = await loadTemplateManifest(source);\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n manifest.id === template.id &&\n satisfies(process.versions.node, manifest.runtime.node),\n detail: `${manifest.id}@${manifest.version} (${source})`\n });\n } catch (error) {\n checks.push({\n name: `模板 ${template.id}`,\n ok: false,\n detail: (error as Error).message\n });\n }\n }\n return checks;\n}\n\nexport async function doctorCommand(options: { json?: boolean } = {}): Promise<void> {\n const checks = await collectDoctorChecks();\n const failed = checks.filter((check) => !check.ok);\n if (options.json) {\n console.log(JSON.stringify({ ok: failed.length === 0, checks }, null, 2));\n } else {\n for (const check of checks) {\n console.log(`${check.ok ? \"✓\" : \"✗\"} ${check.name}: ${check.detail}`);\n }\n console.log(`\\n结果: ${checks.length - failed.length} 通过, ${failed.length} 失败`);\n }\n if (failed.length) process.exitCode = 1;\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { ProjectMetadata } from \"../types.js\";\n\nexport async function infoCommand(\n projectPath = process.cwd(),\n options: { json?: boolean } = {}\n): Promise<void> {\n const root = path.resolve(projectPath);\n const metadataPath = path.join(root, \".jhlc\", \"project.json\");\n if (!existsSync(metadataPath)) {\n throw new Error(`当前目录不是 JH4J CLI 创建的项目: ${metadataPath}`);\n }\n const metadata = await readJson<ProjectMetadata>(metadataPath);\n if (options.json) {\n console.log(JSON.stringify({ projectRoot: root, ...metadata }, null, 2));\n return;\n }\n console.log(`项目目录: ${root}`);\n console.log(`模板: ${metadata.template.id}@${metadata.template.version}`);\n console.log(`平台版本: ${metadata.platformVersion ?? \"未声明\"}`);\n console.log(`创建时间: ${metadata.createdAt}`);\n console.log(`创建工具: ${metadata.createdBy}`);\n console.log(\"项目参数:\");\n console.log(JSON.stringify(metadata.parameters, null, 2));\n}\n","import { loadCatalog } from \"../catalog.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\n\nexport async function listCommand(options: { json?: boolean } = {}): Promise<void> {\n const templates = await loadCatalog(await loadUserConfig());\n if (options.json) {\n console.log(JSON.stringify(templates, null, 2));\n return;\n }\n console.table(\n templates.map((template) => ({\n ID: template.id,\n 名称: template.name,\n 类型: template.category,\n 状态: template.status,\n 默认分支: template.defaultRef,\n 标签: template.tags?.join(\", \") ?? \"\"\n }))\n );\n}\n","import path from \"node:path\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { runCommand } from \"../utils/process.js\";\n\nexport async function validateTemplateCommand(templatePath: string): Promise<void> {\n const root = path.resolve(templatePath);\n const manifest = await loadTemplateManifest(root);\n await runCommand(process.execPath, [path.join(root, \"scripts\", \"validate-template.mjs\")], {\n cwd: root\n });\n console.log(`模板可用: ${manifest.id}@${manifest.version}`);\n}\n","import {\n DEFAULT_USER_CONFIG,\n getUserConfigPath,\n loadUserConfig,\n parseUserConfigValue,\n saveUserConfig\n} from \"../core/user-config.js\";\n\nexport async function configListCommand(options: { json?: boolean } = {}): Promise<void> {\n const config = await loadUserConfig();\n if (options.json) console.log(JSON.stringify(config, null, 2));\n else console.table(Object.entries(config).map(([key, value]) => ({ key, value })));\n console.log(`配置文件: ${getUserConfigPath()}`);\n}\n\nexport async function configGetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in config)) throw new Error(`配置项不存在: ${key}`);\n console.log(String((config as unknown as Record<string, unknown>)[key]));\n}\n\nexport async function configSetCommand(key: string, value: string): Promise<void> {\n const config = await loadUserConfig();\n const [typedKey, typedValue] = parseUserConfigValue(key, value);\n (config as unknown as Record<string, unknown>)[typedKey] = typedValue;\n await saveUserConfig(config);\n console.log(`已设置 ${typedKey}=${String(typedValue)}`);\n}\n\nexport async function configUnsetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in DEFAULT_USER_CONFIG) && !(key in config)) {\n throw new Error(`配置项不存在: ${key}`);\n }\n const defaults = DEFAULT_USER_CONFIG as unknown as Record<string, unknown>;\n const mutable = config as unknown as Record<string, unknown>;\n if (key in defaults) mutable[key] = defaults[key];\n else delete mutable[key];\n await saveUserConfig(config);\n console.log(`已重置配置项: ${key}`);\n}\n\nexport async function configResetCommand(): Promise<void> {\n await saveUserConfig({ ...DEFAULT_USER_CONFIG });\n console.log(`用户配置已恢复默认值: ${getUserConfigPath()}`);\n}\n","import {\n clearTemplateCache,\n getTemplateCacheRoot,\n listTemplateCache\n} from \"../core/template-cache.js\";\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 ** 2) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / 1024 ** 2).toFixed(1)} MB`;\n}\n\nexport async function cacheListCommand(options: { json?: boolean } = {}): Promise<void> {\n const entries = await listTemplateCache();\n if (options.json) {\n console.log(JSON.stringify(entries, null, 2));\n return;\n }\n if (!entries.length) {\n console.log(`模板缓存为空: ${getTemplateCacheRoot()}`);\n return;\n }\n console.table(\n entries.map((entry) => ({\n Key: entry.key,\n 来源: entry.metadata.source,\n Ref: entry.metadata.ref,\n 缓存时间: entry.metadata.cachedAt,\n 大小: formatBytes(entry.sizeBytes)\n }))\n );\n}\n\nexport async function cacheClearCommand(): Promise<void> {\n await clearTemplateCache();\n console.log(`模板缓存已清理: ${getTemplateCacheRoot()}`);\n}\n","import { runCli } from \"./cli.js\";\n\nrunCli().catch((error) => {\n console.error(`\\n错误: ${(error as Error).message}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["path","existsSync","readdir","existsSync","path","path","existsSync","mkdir","readdir","rename","rm","writeFile","existsSync","mkdir","stat","path","path","existsSync","path","existsSync","path","existsSync","mkdir","stat","existsSync","path","readdir","rename","rm","writeFile","mkdir","prompts","existsSync","rename","rm","path","path","path","path","existsSync","rename","rm","selected","existsSync","mkdir","writeFile","rm","path","satisfies","path","mkdir","writeFile","rm","satisfies","existsSync","path","existsSync","path","existsSync","path","path","config"]}
1
+ {"version":3,"sources":["../src/cli.ts","../package.json","../src/constants.ts","../src/catalog.ts","../src/utils/fs.ts","../src/core/template-source.ts","../src/utils/process.ts","../src/core/template-cache.ts","../src/core/user-config.ts","../src/commands/create.ts","../src/core/project-generator.ts","../src/core/template-manifest.ts","../src/commands/doctor.ts","../src/commands/info.ts","../src/commands/list.ts","../src/commands/template.ts","../src/commands/config.ts","../src/commands/cache.ts","../src/index.ts"],"sourcesContent":["import { Command } from \"commander\";\nimport { COMMAND_NAME, CLI_VERSION } from \"./constants.js\";\nimport { findTemplate, loadCatalog } from \"./catalog.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./core/template-source.js\";\nimport { loadUserConfig } from \"./core/user-config.js\";\nimport { createCommand } from \"./commands/create.js\";\nimport { doctorCommand } from \"./commands/doctor.js\";\nimport { infoCommand } from \"./commands/info.js\";\nimport { listCommand } from \"./commands/list.js\";\nimport { validateTemplateCommand } from \"./commands/template.js\";\nimport {\n configGetCommand,\n configListCommand,\n configResetCommand,\n configSetCommand,\n configUnsetCommand\n} from \"./commands/config.js\";\nimport { cacheClearCommand, cacheListCommand } from \"./commands/cache.js\";\n\nexport function createProgram(): Command {\n const program = new Command();\n program\n .name(COMMAND_NAME)\n .description(\"JH4J Cloud 企业内部标准化项目脚手架\")\n .version(CLI_VERSION);\n\n program\n .command(\"create [name]\")\n .description(\"根据标准模板创建项目\")\n .option(\"-c, --category <category>\", \"项目类型:frontend、backend 或 mobile\")\n .option(\"-t, --template <id>\", \"模板 ID\")\n .option(\"--features <ids>\", \"启用的模板能力,多个 ID 使用逗号分隔\")\n .option(\"--no-standards\", \"不启用模板提供的 Git/代码标准化能力\")\n .option(\"--source <path-or-url>\", \"覆盖模板源(本地目录或 Git URL)\")\n .option(\"--ref <branch-or-tag>\", \"Git 分支或标签;默认使用模板 Catalog 配置\")\n .option(\"--module <name>\", \"平台模块标识\")\n .option(\"--title <title>\", \"系统标题\")\n .option(\"--port <port>\", \"开发端口\")\n .option(\"--npm-registry <url>\", \"npm registry(需包含企业定制包)\")\n .option(\"--jhlc-registry <url>\", \"@jhlc 私有 registry\")\n .option(\"--local-backend <url>\", \"本地后端地址\")\n .option(\"--local-public <url>\", \"本地 public 地址\")\n .option(\"--config <json-file>\", \"从 JSON 文件读取创建参数\")\n .option(\"-y, --yes\", \"接受模板默认值,非交互创建\")\n .option(\"--dry-run\", \"只预览,不写入文件\")\n .option(\"--install\", \"创建完成后安装依赖(默认不安装)\")\n .option(\"--skip-install\", \"不安装依赖(兼容旧命令)\")\n .option(\"--skip-git\", \"跳过 Git 初始化\")\n .option(\"--force\", \"覆盖已存在的同名目录\")\n .option(\"--no-cache\", \"不使用已有远程模板缓存\")\n .action(createCommand);\n\n program\n .command(\"list\")\n .description(\"列出可用模板\")\n .option(\"--json\", \"输出 JSON\")\n .action(listCommand);\n program\n .command(\"doctor\")\n .description(\"检查本机环境和模板可用性\")\n .option(\"--json\", \"输出 JSON\")\n .action(doctorCommand);\n program\n .command(\"info [path]\")\n .description(\"显示已生成项目的模板与版本信息\")\n .option(\"--json\", \"输出 JSON\")\n .action(infoCommand);\n\n const template = program.command(\"template\").description(\"模板维护命令\");\n template\n .command(\"validate [path]\")\n .description(\"校验模板 manifest 与模板契约\")\n .action(async (templatePath?: string) => {\n if (templatePath) return validateTemplateCommand(templatePath);\n const config = await loadUserConfig();\n const selected = findTemplate(await loadCatalog(config));\n const acquired = await acquireTemplateFromSources(\n resolveTemplateSources(selected, undefined, config.templateSource),\n config.templateRef ?? selected.defaultRef,\n { cacheTtlMinutes: config.cacheTtlMinutes }\n );\n try {\n return await validateTemplateCommand(acquired.root);\n } finally {\n await acquired.cleanup();\n }\n });\n\n const config = program.command(\"config\").description(\"管理用户默认配置\");\n config\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(configListCommand);\n config.command(\"get <key>\").action(configGetCommand);\n config.command(\"set <key> <value>\").action(configSetCommand);\n config.command(\"unset <key>\").action(configUnsetCommand);\n config.command(\"reset\").action(configResetCommand);\n\n const cache = program.command(\"cache\").description(\"管理远程模板缓存\");\n cache\n .command(\"list\")\n .option(\"--json\", \"输出 JSON\")\n .action(cacheListCommand);\n cache.command(\"clear\").action(cacheClearCommand);\n\n return program;\n}\n\nexport async function runCli(argv = process.argv): Promise<void> {\n await createProgram().parseAsync(argv);\n}\n","{\n \"name\": \"@agile-team/jh4j-cloud-cli\",\n \"version\": \"0.5.0\",\n \"description\": \"JH4J Cloud 企业内部标准化项目脚手架\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/ChenyCHENYU/jh4j-cloud-cli.git\"\n },\n \"homepage\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/ChenyCHENYU/jh4j-cloud-cli/issues\"\n },\n \"type\": \"module\",\n \"engines\": {\n \"node\": \"^22.12.0 || ^24.0.0\",\n \"pnpm\": \">=11.8.0\"\n },\n \"packageManager\": \"pnpm@11.8.0\",\n \"bin\": {\n \"jh4j\": \"bin/jh4j.js\"\n },\n \"files\": [\n \"bin\",\n \"dist\",\n \"README.md\",\n \"CHANGELOG.md\",\n \"catalog.schema.json\"\n ],\n \"scripts\": {\n \"build\": \"tsup\",\n \"dev\": \"tsup --watch\",\n \"typecheck\": \"tsc --noEmit\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"start\": \"node bin/jh4j.js\",\n \"check\": \"pnpm typecheck && pnpm test && pnpm build\",\n \"prepack\": \"pnpm check\"\n },\n \"dependencies\": {\n \"@clack/prompts\": \"^1.7.0\",\n \"commander\": \"^15.0.0\",\n \"semver\": \"^7.8.5\",\n \"tar\": \"^7.5.19\"\n },\n \"publishConfig\": {\n \"access\": \"public\",\n \"registry\": \"https://registry.npmjs.org/\"\n },\n \"devDependencies\": {\n \"@types/node\": \"^24.13.3\",\n \"@types/semver\": \"7.7.1\",\n \"tsup\": \"8.5.1\",\n \"typescript\": \"7.0.2\",\n \"vitest\": \"4.1.10\"\n }\n}\n","import packageJson from \"../package.json\" with { type: \"json\" };\n\nexport const CLI_NAME = \"@agile-team/jh4j-cloud-cli\";\nexport const CLI_VERSION = packageJson.version;\nexport const COMMAND_NAME = \"jh4j\";\nexport const SUPPORTED_NODE_MAJORS = new Set([22, 24]);\nexport const TEMPLATE_SOURCE_ENV = \"JH4J_UI_TEMPLATE_SOURCE\";\nexport const JH4J_HOME_ENV = \"JH4J_HOME\";\nexport const CATALOG_FILE_ENV = \"JH4J_CATALOG_FILE\";\nexport const USER_CONFIG_SCHEMA_VERSION = 1;\n","import { fileURLToPath } from \"node:url\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { CATALOG_FILE_ENV, TEMPLATE_SOURCE_ENV } from \"./constants.js\";\nimport { readJson } from \"./utils/fs.js\";\nimport type { CatalogFile, CatalogTemplate, UserConfig } from \"./types.js\";\n\nconst siblingTemplatePath = fileURLToPath(\n new URL(\"../../jh4j-ui-template/\", import.meta.url)\n);\nconst siblingMobileTemplatePath = fileURLToPath(\n new URL(\"../../../Robot_H5/\", import.meta.url)\n);\nconst remoteTemplateSources = [\n \"https://github.com/ChenyCHENYU/jh4j-ui-template.git\",\n \"https://gitee.com/ycyplus163/jh4j-ui-template.git\"\n];\nconst remoteMobileTemplateSources = [\n \"https://github.com/ChenyCHENYU/Robot_H5.git\",\n \"https://gitee.com/ycyplus163/robot_-h5.git\"\n];\n\nexport const BUILTIN_TEMPLATES: CatalogTemplate[] = [\n {\n id: \"web.jh4j-mf-remote\",\n name: \"JH4J PC 微前端业务模板\",\n description: \"Vue 3 + Vite + Module Federation 标准业务子系统\",\n category: \"frontend\",\n sourceEnvironment: TEMPLATE_SOURCE_ENV,\n defaultSource: existsSync(siblingTemplatePath)\n ? siblingTemplatePath\n : remoteTemplateSources[0],\n sources: remoteTemplateSources,\n defaultRef: \"main\",\n status: \"beta\",\n tags: [\"vue\", \"vite\", \"module-federation\", \"pc\"]\n },\n {\n id: \"mobile.robot-h5\",\n name: \"JH4J 移动端 H5 模板\",\n description: \"Vue 3 + Vite 7 + Vant 4 企业级移动端 H5 应用\",\n category: \"mobile\",\n sourceEnvironment: TEMPLATE_SOURCE_ENV,\n defaultSource: existsSync(siblingMobileTemplatePath)\n ? siblingMobileTemplatePath\n : remoteMobileTemplateSources[0],\n sources: remoteMobileTemplateSources,\n defaultRef: \"v1.6.0\",\n status: \"beta\",\n tags: [\"vue\", \"vite\", \"vant\", \"h5\", \"mobile\"]\n }\n];\n\nfunction validateCatalogTemplate(template: CatalogTemplate): void {\n if (!template.id || !template.name || !template.category) {\n throw new Error(\"Catalog 模板缺少 id、name 或 category\");\n }\n if (!new Set([\"frontend\", \"backend\", \"mobile\"]).has(template.category)) {\n throw new Error(`Catalog 模板 ${template.id} 的 category 无效`);\n }\n if (!new Set([\"stable\", \"beta\"]).has(template.status)) {\n throw new Error(`Catalog 模板 ${template.id} 的 status 无效`);\n }\n if (!template.defaultRef) {\n throw new Error(`Catalog 模板 ${template.id} 缺少 defaultRef`);\n }\n if (!template.defaultSource && !template.sourceEnvironment) {\n throw new Error(`Catalog 模板 ${template.id} 没有可解析的模板源`);\n }\n if (template.sources?.some((source) => !source.trim())) {\n throw new Error(`Catalog 模板 ${template.id} 包含空的备用源`);\n }\n}\n\nfunction resolveCatalogSource(source: string, catalogDirectory: string): string {\n const isRemote =\n /^(?:https?|ssh|file):\\/\\//.test(source) || source.startsWith(\"git@\");\n return isRemote || path.isAbsolute(source)\n ? source\n : path.resolve(catalogDirectory, source);\n}\n\nexport async function loadCatalog(config?: UserConfig): Promise<CatalogTemplate[]> {\n const configuredFile = process.env[CATALOG_FILE_ENV] || config?.catalogFile;\n if (!configuredFile) return [...BUILTIN_TEMPLATES];\n\n const catalogPath = path.resolve(configuredFile);\n if (!existsSync(catalogPath)) {\n throw new Error(`Catalog 文件不存在: ${catalogPath}`);\n }\n const external = await readJson<CatalogFile>(catalogPath);\n if (external.schemaVersion !== 1 || !Array.isArray(external.templates)) {\n throw new Error(`Catalog 文件格式无效: ${catalogPath}`);\n }\n const catalogDirectory = path.dirname(catalogPath);\n external.templates = external.templates.map((template) => {\n return {\n ...template,\n defaultSource: resolveCatalogSource(\n template.defaultSource,\n catalogDirectory\n ),\n sources: template.sources?.map((source) =>\n resolveCatalogSource(source, catalogDirectory)\n )\n };\n });\n external.templates.forEach(validateCatalogTemplate);\n\n const merged = new Map(BUILTIN_TEMPLATES.map((item) => [item.id, item]));\n external.templates.forEach((item) => merged.set(item.id, item));\n return [...merged.values()];\n}\n\nexport function findTemplate(\n catalog: CatalogTemplate[],\n id?: string\n): CatalogTemplate {\n const selected = id ?? catalog[0]?.id;\n const template = catalog.find((item) => item.id === selected);\n if (!template) {\n throw new Error(\n `模板不存在: ${selected}。可用模板: ${catalog.map((item) => item.id).join(\", \")}`\n );\n }\n return template;\n}\n","import { cp, mkdir, readFile, rm, stat, writeFile } from \"node:fs/promises\";\nimport { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst EXCLUDED_TEMPLATE_PATHS = new Set([\n \".git\",\n \".jhlc\",\n \"dist\",\n \"node_modules\"\n]);\n\nexport async function readJson<T>(file: string): Promise<T> {\n return JSON.parse(await readFile(file, \"utf8\")) as T;\n}\n\nexport async function writeJson(file: string, value: unknown): Promise<void> {\n await mkdir(path.dirname(file), { recursive: true });\n await writeFile(file, `${JSON.stringify(value, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function isDirectory(directory: string): Promise<boolean> {\n try {\n return (await stat(directory)).isDirectory();\n } catch {\n return false;\n }\n}\n\nexport async function isDirectoryEmpty(directory: string): Promise<boolean> {\n if (!existsSync(directory)) return true;\n const { readdir } = await import(\"node:fs/promises\");\n return (await readdir(directory)).length === 0;\n}\n\nexport async function copyTemplateTree(\n sourceRoot: string,\n targetRoot: string\n): Promise<void> {\n await mkdir(targetRoot, { recursive: true });\n await cp(sourceRoot, targetRoot, {\n recursive: true,\n force: true,\n filter(source) {\n const relative = path.relative(sourceRoot, source);\n if (!relative) return true;\n const [topLevel] = relative.split(path.sep);\n return !EXCLUDED_TEMPLATE_PATHS.has(topLevel);\n }\n });\n}\n\nexport async function removePath(target: string): Promise<void> {\n await rm(target, { recursive: true, force: true, maxRetries: 3 });\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, rm, writeFile } from \"node:fs/promises\";\nimport { x as extractTar } from \"tar\";\nimport type { CatalogTemplate } from \"../types.js\";\nimport { isDirectory } from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n createTemplateCacheStaging,\n isTemplateCacheFresh,\n readTemplateCacheEntry\n} from \"./template-cache.js\";\n\nconst MAX_ARCHIVE_BYTES = 200 * 1024 * 1024;\n\nexport interface AcquiredTemplate {\n root: string;\n source: string;\n cleanup(): Promise<void>;\n}\n\nexport function resolveTemplateSource(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string {\n return resolveTemplateSources(template, override, configuredSource)[0];\n}\n\nexport function resolveTemplateSources(\n template: CatalogTemplate,\n override?: string,\n configuredSource?: string\n): string[] {\n const exclusiveSource =\n override ||\n (template.sourceEnvironment\n ? process.env[template.sourceEnvironment]\n : undefined) ||\n configuredSource;\n if (exclusiveSource) return [exclusiveSource];\n return [...new Set([template.defaultSource, ...(template.sources ?? [])])];\n}\n\nfunction isGitSource(source: string): boolean {\n return (\n source.startsWith(\"git@\") ||\n source.startsWith(\"ssh://\") ||\n source.startsWith(\"file://\") ||\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.endsWith(\".git\")\n );\n}\n\nfunction isArchiveSource(source: string): boolean {\n const pathname = source.split(/[?#]/, 1)[0].toLowerCase();\n return pathname.endsWith(\".tgz\") || pathname.endsWith(\".tar.gz\") || pathname.endsWith(\".tar\");\n}\n\nasync function getFreshCache(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate | null> {\n const cacheEntry = await readTemplateCacheEntry(source, ref);\n if (\n !options.noCache &&\n cacheEntry &&\n isTemplateCacheFresh(cacheEntry, options.cacheTtlMinutes ?? 60)\n ) {\n return {\n root: cacheEntry.root,\n source: `${source}#${ref} (cache)`,\n async cleanup() {}\n };\n }\n return null;\n}\n\nasync function normalizeExtractedTemplate(\n stagingRoot: string,\n templateRoot: string\n): Promise<void> {\n if (existsSync(path.join(templateRoot, \"template.manifest.json\"))) return;\n const children = await readdir(templateRoot, { withFileTypes: true });\n const candidates = children.filter(\n (entry) =>\n entry.isDirectory() &&\n existsSync(path.join(templateRoot, entry.name, \"template.manifest.json\"))\n );\n if (candidates.length !== 1) {\n throw new Error(\"压缩包根目录或唯一一级目录中未找到 template.manifest.json\");\n }\n const normalizedRoot = path.join(stagingRoot, \".normalized-template\");\n await rename(path.join(templateRoot, candidates[0].name), normalizedRoot);\n await rm(templateRoot, { recursive: true, force: true });\n await rename(normalizedRoot, templateRoot);\n}\n\nasync function acquireArchiveTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number }\n): Promise<AcquiredTemplate> {\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n const archiveFile = path.join(cacheStaging.stagingRoot, \"template.tgz\");\n try {\n if (source.startsWith(\"http://\") || source.startsWith(\"https://\")) {\n const response = await fetch(source, { signal: AbortSignal.timeout(60_000) });\n if (!response.ok) {\n throw new Error(`模板压缩包下载失败: HTTP ${response.status}`);\n }\n const declaredLength = Number(response.headers.get(\"content-length\") || 0);\n if (declaredLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n const archiveBuffer = Buffer.from(await response.arrayBuffer());\n if (archiveBuffer.byteLength > MAX_ARCHIVE_BYTES) {\n throw new Error(\"模板压缩包超过 200 MB 限制\");\n }\n await writeFile(archiveFile, archiveBuffer);\n } else {\n const { copyFile } = await import(\"node:fs/promises\");\n await copyFile(path.resolve(source), archiveFile);\n }\n await mkdir(cacheStaging.templateRoot, { recursive: true });\n await extractTar({ file: archiveFile, cwd: cacheStaging.templateRoot });\n await normalizeExtractedTemplate(\n cacheStaging.stagingRoot,\n cacheStaging.templateRoot\n );\n await rm(archiveFile, { force: true });\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source} (archive)`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplate(\n source: string,\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n const localPath = path.resolve(source);\n if (existsSync(localPath)) {\n if (await isDirectory(localPath)) {\n return {\n root: localPath,\n source: localPath,\n async cleanup() {}\n };\n }\n if (isArchiveSource(localPath)) {\n return acquireArchiveTemplate(localPath, ref, options);\n }\n throw new Error(`模板源不是目录或支持的 tar 压缩包: ${localPath}`);\n }\n\n if (isArchiveSource(source)) {\n return acquireArchiveTemplate(source, ref, options);\n }\n\n if (!isGitSource(source)) {\n throw new Error(`模板源不存在: ${source}`);\n }\n\n const cached = await getFreshCache(source, ref, options);\n if (cached) return cached;\n\n const cacheStaging = await createTemplateCacheStaging(source, ref);\n try {\n await runCommand(\n \"git\",\n [\n \"-c\",\n \"http.lowSpeedLimit=1024\",\n \"-c\",\n \"http.lowSpeedTime=15\",\n \"clone\",\n \"--depth\",\n \"1\",\n \"--branch\",\n ref,\n source,\n cacheStaging.templateRoot\n ],\n { stdio: \"pipe\", env: { GIT_TERMINAL_PROMPT: \"0\" } }\n );\n await cacheStaging.commit();\n return {\n root: path.join(cacheStaging.entryRoot, \"template\"),\n source: `${source}#${ref}`,\n async cleanup() {}\n };\n } catch (error) {\n await cacheStaging.cleanup();\n throw error;\n }\n}\n\nexport async function acquireTemplateFromSources(\n sources: string[],\n ref: string,\n options: { noCache?: boolean; cacheTtlMinutes?: number } = {}\n): Promise<AcquiredTemplate> {\n if (!sources.length) throw new Error(\"没有可用的模板源\");\n const failures: string[] = [];\n for (const source of [...new Set(sources)]) {\n try {\n return await acquireTemplate(source, ref, options);\n } catch (error) {\n failures.push(`${source}: ${(error as Error).message}`);\n }\n }\n throw new Error(`所有模板源均不可用:\\n- ${failures.join(\"\\n- \")}`);\n}\n","import { spawn } from \"node:child_process\";\n\nexport interface RunCommandOptions {\n cwd?: string;\n stdio?: \"inherit\" | \"pipe\";\n env?: NodeJS.ProcessEnv;\n}\n\nexport function platformCommand(command: string): string {\n if (process.platform !== \"win32\") return command;\n return command === \"pnpm\" || command === \"npm\" || command === \"npx\"\n ? `${command}.cmd`\n : command;\n}\n\nexport async function runCommand(\n command: string,\n args: string[],\n options: RunCommandOptions = {}\n): Promise<string> {\n const stdio = options.stdio ?? \"inherit\";\n return new Promise((resolve, reject) => {\n const executable = platformCommand(command);\n const isWindowsCommand =\n process.platform === \"win32\" && executable.endsWith(\".cmd\");\n const spawnExecutable = isWindowsCommand\n ? process.env.ComSpec || \"cmd.exe\"\n : executable;\n const spawnArgs = isWindowsCommand\n ? [\"/d\", \"/s\", \"/c\", executable, ...args]\n : args;\n const child = spawn(spawnExecutable, spawnArgs, {\n cwd: options.cwd,\n stdio,\n env: { ...process.env, ...options.env },\n windowsHide: true\n });\n\n let output = \"\";\n if (stdio === \"pipe\") {\n child.stdout?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n child.stderr?.on(\"data\", (chunk) => {\n output += chunk.toString();\n });\n }\n\n child.on(\"error\", reject);\n child.on(\"exit\", (code) => {\n if (code === 0) {\n resolve(output.trim());\n return;\n }\n reject(\n new Error(\n `${command} ${args.join(\" \")} 执行失败(exit ${code ?? \"unknown\"})${output ? `\\n${output.trim()}` : \"\"}`\n )\n );\n });\n });\n}\n\nexport async function inspectCommand(\n command: string,\n args: string[] = [\"--version\"]\n): Promise<{ ok: boolean; output: string }> {\n try {\n return { ok: true, output: await runCommand(command, args, { stdio: \"pipe\" }) };\n } catch (error) {\n return { ok: false, output: (error as Error).message };\n }\n}\n","import { createHash } from \"node:crypto\";\nimport { existsSync } from \"node:fs\";\nimport { mkdir, readdir, rename, stat } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { getJh4jHome } from \"./user-config.js\";\nimport { readJson, removePath, writeJson } from \"../utils/fs.js\";\nimport type { TemplateCacheMetadata } from \"../types.js\";\n\nconst CACHE_SCHEMA_VERSION = 1;\n\nexport interface TemplateCacheEntry {\n key: string;\n root: string;\n metadata: TemplateCacheMetadata;\n sizeBytes: number;\n}\n\nexport function getTemplateCacheRoot(): string {\n return path.join(getJh4jHome(), \"cache\", \"templates\");\n}\n\nexport function getTemplateCacheKey(source: string, ref: string): string {\n return createHash(\"sha256\").update(`${source}\\0${ref}`).digest(\"hex\").slice(0, 20);\n}\n\nfunction getEntryPaths(key: string) {\n const entryRoot = path.join(getTemplateCacheRoot(), key);\n return {\n entryRoot,\n templateRoot: path.join(entryRoot, \"template\"),\n metadataPath: path.join(entryRoot, \"metadata.json\")\n };\n}\n\nexport async function readTemplateCacheEntry(\n source: string,\n ref: string\n): Promise<TemplateCacheEntry | null> {\n const key = getTemplateCacheKey(source, ref);\n const paths = getEntryPaths(key);\n if (!existsSync(paths.templateRoot) || !existsSync(paths.metadataPath)) return null;\n try {\n const metadata = await readJson<TemplateCacheMetadata>(paths.metadataPath);\n if (\n metadata.schemaVersion !== CACHE_SCHEMA_VERSION ||\n metadata.source !== source ||\n metadata.ref !== ref\n ) {\n return null;\n }\n return {\n key,\n root: paths.templateRoot,\n metadata,\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n };\n } catch {\n return null;\n }\n}\n\nexport function isTemplateCacheFresh(\n entry: TemplateCacheEntry,\n ttlMinutes: number\n): boolean {\n if (ttlMinutes <= 0) return false;\n const cachedAt = Date.parse(entry.metadata.cachedAt);\n return Number.isFinite(cachedAt) && Date.now() - cachedAt < ttlMinutes * 60_000;\n}\n\nexport async function createTemplateCacheStaging(\n source: string,\n ref: string\n): Promise<{\n key: string;\n entryRoot: string;\n stagingRoot: string;\n templateRoot: string;\n commit(): Promise<void>;\n cleanup(): Promise<void>;\n}> {\n const key = getTemplateCacheKey(source, ref);\n const cacheRoot = getTemplateCacheRoot();\n await mkdir(cacheRoot, { recursive: true });\n const stagingRoot = path.join(\n cacheRoot,\n `.${key}.tmp-${process.pid}-${Date.now()}`\n );\n const templateRoot = path.join(stagingRoot, \"template\");\n const entryRoot = path.join(cacheRoot, key);\n await mkdir(stagingRoot, { recursive: true });\n\n return {\n key,\n entryRoot,\n stagingRoot,\n templateRoot,\n async commit() {\n await writeJson(path.join(stagingRoot, \"metadata.json\"), {\n schemaVersion: CACHE_SCHEMA_VERSION,\n source,\n ref,\n cachedAt: new Date().toISOString()\n } satisfies TemplateCacheMetadata);\n await removePath(entryRoot);\n await rename(stagingRoot, entryRoot);\n },\n cleanup: () => removePath(stagingRoot)\n };\n}\n\nasync function calculateDirectorySize(directory: string): Promise<number> {\n let total = 0;\n const entries = await readdir(directory, { withFileTypes: true });\n for (const entry of entries) {\n const absolute = path.join(directory, entry.name);\n if (entry.isDirectory()) total += await calculateDirectorySize(absolute);\n else if (entry.isFile()) total += (await stat(absolute)).size;\n }\n return total;\n}\n\nexport async function listTemplateCache(): Promise<TemplateCacheEntry[]> {\n const cacheRoot = getTemplateCacheRoot();\n if (!existsSync(cacheRoot)) return [];\n const entries: TemplateCacheEntry[] = [];\n for (const directory of await readdir(cacheRoot, { withFileTypes: true })) {\n if (!directory.isDirectory() || directory.name.startsWith(\".\")) continue;\n const paths = getEntryPaths(directory.name);\n if (!existsSync(paths.metadataPath) || !existsSync(paths.templateRoot)) continue;\n try {\n entries.push({\n key: directory.name,\n root: paths.templateRoot,\n metadata: await readJson<TemplateCacheMetadata>(paths.metadataPath),\n sizeBytes: await calculateDirectorySize(paths.entryRoot)\n });\n } catch {\n // 损坏条目由 clear 或下一次拉取覆盖。\n }\n }\n return entries.sort((a, b) =>\n b.metadata.cachedAt.localeCompare(a.metadata.cachedAt)\n );\n}\n\nexport async function clearTemplateCache(): Promise<void> {\n await removePath(getTemplateCacheRoot());\n}\n","import os from \"node:os\";\nimport path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { JH4J_HOME_ENV, USER_CONFIG_SCHEMA_VERSION } from \"../constants.js\";\nimport { readJson, writeJson } from \"../utils/fs.js\";\nimport type { UserConfig } from \"../types.js\";\n\nexport const DEFAULT_USER_CONFIG: UserConfig = {\n schemaVersion: USER_CONFIG_SCHEMA_VERSION,\n autoInstall: false,\n autoGit: true,\n cacheTtlMinutes: 60\n};\n\nexport function getJh4jHome(): string {\n return path.resolve(process.env[JH4J_HOME_ENV] || path.join(os.homedir(), \".jh4j\"));\n}\n\nexport function getUserConfigPath(): string {\n return path.join(getJh4jHome(), \"config.json\");\n}\n\nexport async function loadUserConfig(): Promise<UserConfig> {\n const configPath = getUserConfigPath();\n if (!existsSync(configPath)) return { ...DEFAULT_USER_CONFIG };\n\n const stored = await readJson<Partial<UserConfig>>(configPath);\n if (\n stored.schemaVersion !== undefined &&\n stored.schemaVersion !== USER_CONFIG_SCHEMA_VERSION\n ) {\n throw new Error(\n `不支持的用户配置版本: ${stored.schemaVersion},当前要求 ${USER_CONFIG_SCHEMA_VERSION}`\n );\n }\n return { ...DEFAULT_USER_CONFIG, ...stored };\n}\n\nexport async function saveUserConfig(config: UserConfig): Promise<void> {\n await writeJson(getUserConfigPath(), {\n ...config,\n schemaVersion: USER_CONFIG_SCHEMA_VERSION\n });\n}\n\nconst CONFIG_KEYS = new Set<keyof UserConfig>([\n \"catalogFile\",\n \"templateSource\",\n \"templateRef\",\n \"npmRegistry\",\n \"jhlcRegistry\",\n \"autoInstall\",\n \"autoGit\",\n \"cacheTtlMinutes\"\n]);\n\nexport function parseUserConfigValue(\n key: string,\n rawValue: string\n): [keyof UserConfig, UserConfig[keyof UserConfig]] {\n if (!CONFIG_KEYS.has(key as keyof UserConfig)) {\n throw new Error(`不支持的配置项: ${key}`);\n }\n const typedKey = key as keyof UserConfig;\n if (typedKey === \"autoInstall\" || typedKey === \"autoGit\") {\n const normalized = rawValue.toLowerCase();\n if (!new Set([\"true\", \"false\"]).has(normalized)) {\n throw new Error(`${key} 只能是 true 或 false`);\n }\n return [typedKey, normalized === \"true\"];\n }\n if (typedKey === \"cacheTtlMinutes\") {\n const value = Number(rawValue);\n if (!Number.isInteger(value) || value < 0 || value > 10080) {\n throw new Error(\"cacheTtlMinutes 必须是 0 到 10080 之间的整数\");\n }\n return [typedKey, value];\n }\n return [typedKey, rawValue.trim()];\n}\n","import * as prompts from \"@clack/prompts\";\nimport { findTemplate, loadCatalog } from \"../catalog.js\";\nimport {\n generateProject,\n normalizeProjectName\n} from \"../core/project-generator.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n TemplateCategory\n} from \"../types.js\";\n\nconst CATEGORY_OPTIONS: Array<{\n value: TemplateCategory;\n label: string;\n}> = [\n { value: \"frontend\", label: \"PC 前端 · Vue 3 / 微前端\" },\n { value: \"backend\", label: \"后端服务 · Java / 云原生\" },\n { value: \"mobile\", label: \"移动端 H5 · Vue 3 / Vant\" }\n];\n\nfunction isCategory(value: string): value is TemplateCategory {\n return CATEGORY_OPTIONS.some((item) => item.value === value);\n}\n\nexport function templatesByCategory(\n templates: CatalogTemplate[],\n category: TemplateCategory\n): CatalogTemplate[] {\n return templates.filter((template) => template.category === category);\n}\n\nexport function categoryOptionsFor(\n templates: CatalogTemplate[]\n): Array<{ value: TemplateCategory; label: string }> {\n return CATEGORY_OPTIONS.filter(\n (item) => templatesByCategory(templates, item.value).length > 0\n ).map(({ value, label }) => ({ value, label }));\n}\n\nasync function selectCategory(\n templates: CatalogTemplate[],\n requestedCategory: string | undefined,\n nonInteractive: boolean\n): Promise<TemplateCategory> {\n if (requestedCategory) {\n if (!isCategory(requestedCategory)) {\n throw new Error(\n `项目类型无效: ${requestedCategory}。可用值: frontend、backend、mobile`\n );\n }\n if (!templatesByCategory(templates, requestedCategory).length) {\n throw new Error(`项目类型 ${requestedCategory} 暂无可用模板`);\n }\n return requestedCategory;\n }\n\n const firstAvailable = CATEGORY_OPTIONS.find(\n (item) => templatesByCategory(templates, item.value).length > 0\n );\n if (!firstAvailable) throw new Error(\"Catalog 中没有可用模板\");\n if (nonInteractive) return firstAvailable.value;\n\n const availableOptions = categoryOptionsFor(templates);\n if (availableOptions.length === 1) return availableOptions[0].value;\n\n const selected = await prompts.select({\n message: \"选择项目类型\",\n options: availableOptions.map((item) => ({\n value: item.value,\n label: item.label\n }))\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return selected as TemplateCategory;\n}\n\nasync function selectTemplate(\n templates: CatalogTemplate[],\n options: CreateOptions\n): Promise<CatalogTemplate> {\n if (options.template) {\n const selected = findTemplate(templates, options.template);\n if (options.category && selected.category !== options.category) {\n throw new Error(\n `模板 ${selected.id} 属于 ${selected.category},与 --category ${options.category} 不一致`\n );\n }\n return selected;\n }\n\n const category = await selectCategory(\n templates,\n options.category,\n Boolean(options.yes)\n );\n const candidates = templatesByCategory(templates, category);\n if (options.yes) return findTemplate(candidates);\n if (candidates.length === 1) {\n const selected = candidates[0];\n prompts.log.info(`使用模板:${selected.name}`);\n return selected;\n }\n\n const selected = await prompts.select({\n message: \"选择项目模板\",\n options: candidates.map((template) => ({\n value: template.id,\n label: `${template.name} · ${template.description}`\n }))\n });\n if (prompts.isCancel(selected)) throw new Error(\"用户取消创建\");\n return findTemplate(candidates, String(selected));\n}\n\nexport async function createCommand(\n requestedName: string | undefined,\n options: CreateOptions\n): Promise<void> {\n prompts.intro(\"JH4J Cloud 项目创建\");\n const userConfig = await loadUserConfig();\n const catalog = await loadCatalog(userConfig);\n const template = await selectTemplate(catalog, options);\n\n let projectName = requestedName;\n if (!projectName) {\n if (options.yes) throw new Error(\"非交互模式必须指定项目名称\");\n const defaultProjectName =\n template.category === \"mobile\" ? \"jh4j-mobile-app\" : \"jh4j-ui-app\";\n const answer = await prompts.text({\n message: \"项目名称\",\n placeholder: defaultProjectName,\n defaultValue: defaultProjectName,\n validate(value) {\n return !value || normalizeProjectName(value)\n ? undefined\n : \"请输入至少一个字母或数字,例如 jh4j-mobile-app\";\n }\n });\n if (prompts.isCancel(answer)) throw new Error(\"用户取消创建\");\n projectName = String(answer).trim() || defaultProjectName;\n }\n\n const rawProjectName = projectName;\n projectName = normalizeProjectName(rawProjectName);\n if (!projectName) {\n throw new Error(\"项目名称至少需要包含一个字母或数字\");\n }\n if (projectName !== rawProjectName) {\n prompts.log.info(`项目名称已规范化:${projectName}`);\n }\n\n const result = await generateProject(\n template,\n projectName,\n options,\n process.cwd(),\n userConfig\n );\n if (options.dryRun) {\n prompts.outro(\"Dry Run 完成,未写入任何项目文件\");\n return;\n }\n\n prompts.note(\n [\n `目录: ${result.targetRoot}`,\n `模板: ${result.templateId}@${result.templateVersion}`,\n `来源: ${result.source}`,\n `默认能力: ${result.features.length ? result.features.join(\", \") : \"无\"}`,\n `依赖: ${result.installed ? \"已安装\" : \"未安装(默认由开发者手动安装)\"}`,\n `Git: ${result.gitInitialized ? \"main 已初始化\" : \"未初始化\"}`,\n \"\",\n \"需要调整配置时,直接修改生成项目中的:\",\n \" project.config.json 项目、联调与环境参数\",\n \" .npmrc Registry 配置\",\n \" .env* 各端运行环境配置(如存在)\",\n \"\",\n `cd ${projectName}`,\n ...(!result.installed ? [\"pnpm install\"] : []),\n \"pnpm dev\"\n ].join(\"\\n\"),\n \"创建成功\"\n );\n prompts.outro(\"项目已准备好\");\n}\n","import { existsSync } from \"node:fs\";\nimport { rename, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport * as prompts from \"@clack/prompts\";\nimport { satisfies } from \"semver\";\nimport { CLI_NAME, CLI_VERSION } from \"../constants.js\";\nimport {\n copyTemplateTree,\n isDirectoryEmpty,\n readJson,\n removePath,\n writeJson\n} from \"../utils/fs.js\";\nimport { runCommand } from \"../utils/process.js\";\nimport {\n acquireTemplateFromSources,\n resolveTemplateSources\n} from \"./template-source.js\";\nimport { loadTemplateManifest } from \"./template-manifest.js\";\nimport { DEFAULT_USER_CONFIG } from \"./user-config.js\";\nimport type {\n CatalogTemplate,\n CreateOptions,\n ProjectInput,\n TemplateManifest,\n UserConfig\n} from \"../types.js\";\n\nconst ENV_NAMES = [\"dev\", \"sit\", \"uat\", \"pre\", \"prd\"] as const;\ntype PartialProjectInput = Partial<Omit<ProjectInput, \"environments\">> & {\n environments?: Partial<ProjectInput[\"environments\"]>;\n};\n\nfunction cancelled(value: unknown): value is symbol {\n return prompts.isCancel(value);\n}\n\nexport function normalizeProjectName(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/\\s+/g, \"-\")\n .replace(/^[._-]+/, \"\")\n .replace(/[^a-z0-9._-]+/g, \"-\")\n .replace(/-{2,}/g, \"-\")\n .replace(/[-._]+$/, \"\");\n}\n\nfunction ensureProjectName(value: string): string {\n const name = normalizeProjectName(value);\n if (!/^[a-z0-9][a-z0-9._-]*$/.test(name)) {\n throw new Error(\"项目名称至少需要包含一个字母或数字\");\n }\n return name;\n}\n\nfunction inferModuleName(projectName: string): string {\n const inferred = projectName\n .replace(/^(?:jh4j|wl)-ui-/, \"\")\n .replace(/[^a-z0-9-]/g, \"-\")\n .replace(/^-+|-+$/g, \"\");\n return /^[a-z][a-z0-9-]*$/.test(inferred) ? inferred : \"app\";\n}\n\nfunction ensureModuleName(value: string): string {\n const name = value.trim();\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n throw new Error(\"模块标识必须以小写字母开头,只能包含小写字母、数字和连字符\");\n }\n return name;\n}\n\nfunction ensurePort(value: string | number): number {\n const port = Number(value);\n if (!Number.isInteger(port) || port < 1024 || port > 65535) {\n throw new Error(\"开发端口必须是 1024 到 65535 之间的整数\");\n }\n return port;\n}\n\nfunction ensureHttpUrl(value: string, label: string): string {\n try {\n const url = new URL(value);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") throw new Error();\n return value.replace(/\\/+$/, \"\");\n } catch {\n throw new Error(`${label} 必须是 http/https URL`);\n }\n}\n\nasync function askText(\n message: string,\n initialValue: string,\n validate?: (value: string | undefined) => string | undefined\n): Promise<string> {\n const answer = await prompts.text({\n message,\n placeholder: initialValue,\n defaultValue: initialValue,\n validate\n });\n if (cancelled(answer)) throw new Error(\"用户取消创建\");\n return String(answer).trim() || initialValue;\n}\n\nasync function loadCreateConfig(\n configFile: string | undefined,\n cwd: string\n): Promise<PartialProjectInput> {\n if (!configFile) return {};\n const resolved = path.resolve(cwd, configFile);\n if (!existsSync(resolved)) throw new Error(`创建配置文件不存在: ${resolved}`);\n return readJson<PartialProjectInput>(resolved);\n}\n\nfunction parseFeatureIds(value: string): string[] {\n return [...new Set(value.split(\",\").map((item) => item.trim()).filter(Boolean))];\n}\n\nasync function collectTemplateFeatures(\n manifest: TemplateManifest,\n fileConfig: PartialProjectInput,\n options: CreateOptions\n): Promise<string[]> {\n const available = manifest.features ?? [];\n if (!available.length) return [];\n\n const knownIds = new Set(available.map((feature) => feature.id));\n let selected = options.features\n ? parseFeatureIds(options.features)\n : Array.isArray(fileConfig.features)\n ? fileConfig.features\n : available\n .filter((feature) => feature.defaultEnabled || feature.required)\n .map((feature) => feature.id);\n\n const unknown = selected.filter((id) => !knownIds.has(id));\n if (unknown.length) {\n throw new Error(\n `模板不支持以下能力: ${unknown.join(\", \")}。可用能力: ${[...knownIds].join(\", \")}`\n );\n }\n\n if (options.standards === false) {\n selected = selected.filter((id) => {\n const feature = available.find((item) => item.id === id);\n return feature?.package !== \"@robot-admin/git-standards\";\n });\n }\n\n for (const feature of available) {\n if (feature.required && !selected.includes(feature.id)) {\n selected.push(feature.id);\n }\n }\n return selected;\n}\n\nasync function collectProjectInput(\n projectName: string,\n manifest: TemplateManifest,\n sourceConfig: ProjectInput,\n fileConfig: PartialProjectInput,\n options: CreateOptions,\n userConfig: UserConfig,\n features: string[]\n): Promise<ProjectInput> {\n let moduleName = options.module ?? fileConfig.moduleName ?? inferModuleName(projectName);\n let title = options.title ?? fileConfig.title ?? sourceConfig.title;\n let port: string | number =\n options.port ?? fileConfig.devServerPort ?? sourceConfig.devServerPort;\n let npmRegistry =\n options.npmRegistry ??\n fileConfig.npmRegistry ??\n userConfig.npmRegistry ??\n sourceConfig.npmRegistry;\n let jhlcRegistry =\n options.jhlcRegistry ??\n fileConfig.jhlcRegistry ??\n userConfig.jhlcRegistry ??\n sourceConfig.jhlcRegistry;\n let localBackendUrl =\n options.localBackend ?? fileConfig.localBackendUrl ?? sourceConfig.localBackendUrl;\n let localPublicUrl =\n options.localPublic ?? fileConfig.localPublicUrl ?? sourceConfig.localPublicUrl;\n const environments = structuredClone(sourceConfig.environments);\n for (const [env, value] of Object.entries(fileConfig.environments ?? {})) {\n if (value && environments[env]) {\n environments[env] = { ...environments[env], ...value };\n }\n }\n\n if (!options.yes) {\n title = await askText(\n manifest.category === \"mobile\" ? \"应用标题\" : \"系统标题\",\n title,\n (value) => (value?.trim() ? undefined : \"标题不能为空\")\n );\n port = await askText(\"开发端口\", String(port), (value) => {\n const parsed = Number(value);\n return Number.isInteger(parsed) && parsed >= 1024 && parsed <= 65535\n ? undefined\n : \"请输入 1024 到 65535 之间的端口\";\n });\n localBackendUrl = await askText(\n manifest.category === \"mobile\" ? \"本地 API 地址\" : \"本地后端地址\",\n localBackendUrl,\n (value) => {\n try {\n const url = new URL(value ?? \"\");\n return url.protocol === \"http:\" || url.protocol === \"https:\"\n ? undefined\n : \"请输入 http/https 地址\";\n } catch {\n return \"请输入完整的 http/https 地址\";\n }\n }\n );\n }\n\n if (!title.trim()) throw new Error(\"系统标题不能为空\");\n for (const env of ENV_NAMES) {\n if (!environments[env]) throw new Error(`缺少 ${env.toUpperCase()} 环境配置`);\n environments[env] = {\n webUrl: ensureHttpUrl(environments[env].webUrl, `${env.toUpperCase()} 平台地址`),\n apiPrefix: environments[env].apiPrefix.replace(/^\\/+|\\/+$/g, \"\")\n };\n if (!environments[env].apiPrefix) {\n throw new Error(`${env.toUpperCase()} API 前缀不能为空`);\n }\n }\n\n return {\n projectName,\n moduleName: ensureModuleName(moduleName),\n title: title.trim(),\n devServerPort: ensurePort(port),\n npmRegistry: ensureHttpUrl(npmRegistry, \"npm registry\"),\n jhlcRegistry: ensureHttpUrl(jhlcRegistry, \"@jhlc 私有 registry\"),\n localBackendUrl: ensureHttpUrl(localBackendUrl, \"本地后端地址\"),\n localPublicUrl: ensureHttpUrl(localPublicUrl, \"本地 public 地址\"),\n environments,\n features\n };\n}\n\nfunction assertSafeTarget(cwd: string, target: string): void {\n if (path.dirname(target) !== cwd || target === cwd) {\n throw new Error(\"仅允许在当前目录创建一级项目目录\");\n }\n}\n\nasync function promoteStaging(\n stagingRoot: string,\n targetRoot: string,\n force: boolean\n): Promise<void> {\n const targetExists = existsSync(targetRoot);\n if (!targetExists) {\n await rename(stagingRoot, targetRoot);\n return;\n }\n\n if (!(await isDirectoryEmpty(targetRoot)) && !force) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const backupRoot = `${targetRoot}.jh4j-backup-${Date.now()}`;\n await rename(targetRoot, backupRoot);\n try {\n await rename(stagingRoot, targetRoot);\n } catch (error) {\n await rename(backupRoot, targetRoot);\n throw error;\n }\n try {\n await removePath(backupRoot);\n } catch {\n prompts.log.warn(`旧目录备份未能自动清理: ${backupRoot}`);\n }\n}\n\nexport interface GenerateProjectResult {\n targetRoot: string;\n templateId: string;\n templateVersion: string;\n source: string;\n features: string[];\n installed: boolean;\n gitInitialized: boolean;\n}\n\nexport async function generateProject(\n catalogTemplate: CatalogTemplate,\n requestedProjectName: string,\n options: CreateOptions,\n cwd = process.cwd(),\n configuredUserConfig: UserConfig = DEFAULT_USER_CONFIG\n): Promise<GenerateProjectResult> {\n const userConfig = { ...DEFAULT_USER_CONFIG, ...configuredUserConfig };\n const projectName = ensureProjectName(requestedProjectName);\n const resolvedCwd = path.resolve(cwd);\n const targetRoot = path.resolve(resolvedCwd, projectName);\n assertSafeTarget(resolvedCwd, targetRoot);\n if (\n existsSync(targetRoot) &&\n !(await isDirectoryEmpty(targetRoot)) &&\n !options.force\n ) {\n throw new Error(`目标目录已存在且非空: ${targetRoot}`);\n }\n\n const ref = options.ref ?? userConfig.templateRef ?? catalogTemplate.defaultRef;\n const sourceValues = resolveTemplateSources(\n catalogTemplate,\n options.source,\n userConfig.templateSource\n );\n const acquisitionSpinner = options.yes\n ? undefined\n : prompts.spinner({ indicator: \"timer\" });\n acquisitionSpinner?.start(\"正在获取并校验模板\");\n let acquired: Awaited<ReturnType<typeof acquireTemplateFromSources>>;\n try {\n acquired = await acquireTemplateFromSources(sourceValues, ref, {\n noCache: options.cache === false,\n cacheTtlMinutes: userConfig.cacheTtlMinutes\n });\n acquisitionSpinner?.stop(\"模板准备完成\");\n } catch (error) {\n acquisitionSpinner?.error(\"模板获取失败\");\n throw error;\n }\n const stagingRoot = path.join(\n resolvedCwd,\n `.${projectName}.jh4j-tmp-${process.pid}-${Date.now()}`\n );\n let promoted = false;\n\n try {\n const manifest = await loadTemplateManifest(acquired.root);\n if (manifest.id !== catalogTemplate.id) {\n throw new Error(\n `模板 ID 不匹配:Catalog=${catalogTemplate.id},Manifest=${manifest.id}`\n );\n }\n if (!satisfies(process.versions.node, manifest.runtime.node)) {\n throw new Error(\n `当前 Node ${process.versions.node} 不满足模板要求 ${manifest.runtime.node}`\n );\n }\n\n const sourceProjectConfig = await readJson<\n Omit<ProjectInput, \"npmRegistry\" | \"jhlcRegistry\">\n >(path.join(acquired.root, \"project.config.json\"));\n const fileConfig = await loadCreateConfig(options.config, resolvedCwd);\n const features = await collectTemplateFeatures(manifest, fileConfig, options);\n const input = await collectProjectInput(\n projectName,\n manifest,\n {\n ...sourceProjectConfig,\n npmRegistry: manifest.defaults.npmRegistry,\n jhlcRegistry: manifest.defaults.jhlcRegistry\n },\n fileConfig,\n options,\n userConfig,\n features\n );\n\n const shouldInstall =\n !options.skipInstall && (options.install === true || userConfig.autoInstall);\n const shouldInitializeGit = !options.skipGit && userConfig.autoGit;\n\n if (options.dryRun) {\n prompts.note(\n [\n `模板: ${manifest.id}@${manifest.version}`,\n `来源: ${acquired.source}`,\n `目标: ${targetRoot}`,\n `模块: ${input.moduleName}`,\n `端口: ${input.devServerPort}`,\n `能力: ${input.features.length ? input.features.join(\", \") : \"无可选能力\"}`,\n `安装依赖: ${shouldInstall ? \"是\" : \"否\"}`,\n `初始化 Git: ${shouldInitializeGit ? \"是\" : \"否\"}`\n ].join(\"\\n\"),\n \"Dry Run\"\n );\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: false,\n gitInitialized: false\n };\n }\n\n await copyTemplateTree(acquired.root, stagingRoot);\n const inputFile = path.join(stagingRoot, \".jh4j-cli-input.json\");\n await writeJson(inputFile, input);\n try {\n await runCommand(\n process.execPath,\n [\n path.join(stagingRoot, \"scripts\", \"setup-project.mjs\"),\n \"--yes\",\n \"--config\",\n inputFile,\n \"--created-by\",\n `${CLI_NAME}@${CLI_VERSION}`\n ],\n { cwd: stagingRoot, stdio: \"pipe\" }\n );\n } finally {\n await rm(inputFile, { force: true });\n }\n\n if (!existsSync(path.join(stagingRoot, manifest.generatedMetadata))) {\n throw new Error(`模板初始化未生成元数据: ${manifest.generatedMetadata}`);\n }\n await promoteStaging(stagingRoot, targetRoot, Boolean(options.force));\n promoted = true;\n\n let gitInitialized = false;\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"init\", \"-b\", \"main\"], {\n cwd: targetRoot,\n stdio: \"pipe\"\n });\n gitInitialized = true;\n }\n\n if (shouldInstall) {\n try {\n await runCommand(\"pnpm\", [\"install\"], { cwd: targetRoot });\n } catch (error) {\n throw new Error(\n `项目已生成,但依赖安装失败;目录已保留在 ${targetRoot}\\n${(error as Error).message}`\n );\n }\n }\n\n if (shouldInitializeGit) {\n await runCommand(\"git\", [\"add\", \"-A\"], { cwd: targetRoot, stdio: \"pipe\" });\n try {\n await runCommand(\n \"git\",\n [\"commit\", \"-m\", `feat(init): 基于 ${manifest.id}@${manifest.version} 初始化`],\n {\n cwd: targetRoot,\n stdio: \"pipe\",\n env: { HUSKY: \"0\" }\n }\n );\n } catch (error) {\n prompts.log.warn(`Git 已初始化,但初始提交未完成:${(error as Error).message}`);\n }\n }\n\n return {\n targetRoot,\n templateId: manifest.id,\n templateVersion: manifest.version,\n source: acquired.source,\n features: input.features,\n installed: shouldInstall,\n gitInitialized\n };\n } finally {\n if (!promoted && existsSync(stagingRoot)) await removePath(stagingRoot);\n await acquired.cleanup();\n }\n}\n","import path from \"node:path\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { TemplateManifest } from \"../types.js\";\n\nexport async function loadTemplateManifest(\n templateRoot: string\n): Promise<TemplateManifest> {\n const manifest = await readJson<TemplateManifest>(\n path.join(templateRoot, \"template.manifest.json\")\n );\n const errors: string[] = [];\n\n if (manifest.schemaVersion !== 1) errors.push(\"schemaVersion 必须为 1\");\n if (!manifest.id) errors.push(\"缺少模板 id\");\n if (!manifest.name) errors.push(\"缺少模板名称\");\n if (!/^\\d+\\.\\d+\\.\\d+([+-].+)?$/.test(manifest.version ?? \"\")) {\n errors.push(\"模板 version 不是有效的语义化版本\");\n }\n if (!manifest.runtime?.node || !manifest.runtime?.packageManager) {\n errors.push(\"缺少模板运行时约束\");\n }\n if (!manifest.entry?.nonInteractive) {\n errors.push(\"缺少非交互初始化入口\");\n }\n const featureIds = new Set<string>();\n for (const feature of manifest.features ?? []) {\n if (!/^[a-z][a-z0-9-]*$/.test(feature.id)) {\n errors.push(`模板能力 id 无效: ${feature.id}`);\n }\n if (featureIds.has(feature.id)) {\n errors.push(`模板能力 id 重复: ${feature.id}`);\n }\n featureIds.add(feature.id);\n if (!feature.name || !feature.description) {\n errors.push(`模板能力 ${feature.id} 缺少名称或说明`);\n }\n }\n\n if (errors.length) {\n throw new Error(`模板 manifest 无效:\\n- ${errors.join(\"\\n- \")}`);\n }\n return manifest;\n}\n","import { existsSync } from \"node:fs\";\nimport { mkdir, writeFile, rm } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { coerce, gte, satisfies } from \"semver\";\nimport { loadCatalog } from \"../catalog.js\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { resolveTemplateSources } from \"../core/template-source.js\";\nimport { getJh4jHome, loadUserConfig } from \"../core/user-config.js\";\nimport { inspectCommand } from \"../utils/process.js\";\nimport type { CatalogTemplate, UserConfig } from \"../types.js\";\n\nexport interface CheckResult {\n name: string;\n ok: boolean;\n detail: string;\n}\n\nasync function checkHomeWritable(): Promise<CheckResult> {\n const home = getJh4jHome();\n const probe = path.join(home, `.write-probe-${process.pid}`);\n try {\n await mkdir(home, { recursive: true });\n await writeFile(probe, \"ok\", \"utf8\");\n await rm(probe, { force: true });\n return { name: \"JH4J_HOME\", ok: true, detail: home };\n } catch (error) {\n return { name: \"JH4J_HOME\", ok: false, detail: (error as Error).message };\n }\n}\n\nexport async function collectDoctorChecks(\n suppliedConfig?: UserConfig,\n suppliedCatalog?: CatalogTemplate[]\n): Promise<CheckResult[]> {\n const config = suppliedConfig ?? (await loadUserConfig());\n const catalog = suppliedCatalog ?? (await loadCatalog(config));\n const [git, pnpm, home] = await Promise.all([\n inspectCommand(\"git\"),\n inspectCommand(\"pnpm\"),\n checkHomeWritable()\n ]);\n const pnpmVersion = coerce(pnpm.output)?.version;\n const checks: CheckResult[] = [\n {\n name: \"Node.js\",\n ok: satisfies(process.versions.node, \"^22.12.0 || ^24.0.0\"),\n detail: `${process.versions.node}(要求 Node 22.12+ 或 24.x)`\n },\n { name: \"Git\", ok: git.ok, detail: git.output },\n {\n name: \"pnpm\",\n ok: pnpm.ok && Boolean(pnpmVersion && gte(pnpmVersion, \"11.8.0\")),\n detail: pnpm.output\n },\n home\n ];\n\n for (const template of catalog) {\n const sources = resolveTemplateSources(\n template,\n undefined,\n config.templateSource\n );\n const source = sources[0];\n if (!existsSync(source)) {\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n source.startsWith(\"http://\") ||\n source.startsWith(\"https://\") ||\n source.startsWith(\"git@\"),\n detail: `远程候选源(创建时依次验证): ${sources.join(\" → \")}`\n });\n continue;\n }\n try {\n const manifest = await loadTemplateManifest(source);\n checks.push({\n name: `模板 ${template.id}`,\n ok:\n manifest.id === template.id &&\n satisfies(process.versions.node, manifest.runtime.node),\n detail: `${manifest.id}@${manifest.version} (${source})`\n });\n } catch (error) {\n checks.push({\n name: `模板 ${template.id}`,\n ok: false,\n detail: (error as Error).message\n });\n }\n }\n return checks;\n}\n\nexport async function doctorCommand(options: { json?: boolean } = {}): Promise<void> {\n const checks = await collectDoctorChecks();\n const failed = checks.filter((check) => !check.ok);\n if (options.json) {\n console.log(JSON.stringify({ ok: failed.length === 0, checks }, null, 2));\n } else {\n for (const check of checks) {\n console.log(`${check.ok ? \"✓\" : \"✗\"} ${check.name}: ${check.detail}`);\n }\n console.log(`\\n结果: ${checks.length - failed.length} 通过, ${failed.length} 失败`);\n }\n if (failed.length) process.exitCode = 1;\n}\n","import path from \"node:path\";\nimport { existsSync } from \"node:fs\";\nimport { readJson } from \"../utils/fs.js\";\nimport type { ProjectMetadata } from \"../types.js\";\n\nexport async function infoCommand(\n projectPath = process.cwd(),\n options: { json?: boolean } = {}\n): Promise<void> {\n const root = path.resolve(projectPath);\n const metadataPath = path.join(root, \".jhlc\", \"project.json\");\n if (!existsSync(metadataPath)) {\n throw new Error(`当前目录不是 JH4J CLI 创建的项目: ${metadataPath}`);\n }\n const metadata = await readJson<ProjectMetadata>(metadataPath);\n if (options.json) {\n console.log(JSON.stringify({ projectRoot: root, ...metadata }, null, 2));\n return;\n }\n console.log(`项目目录: ${root}`);\n console.log(`模板: ${metadata.template.id}@${metadata.template.version}`);\n console.log(`平台版本: ${metadata.platformVersion ?? \"未声明\"}`);\n console.log(`创建时间: ${metadata.createdAt}`);\n console.log(`创建工具: ${metadata.createdBy}`);\n console.log(\"项目参数:\");\n console.log(JSON.stringify(metadata.parameters, null, 2));\n}\n","import { loadCatalog } from \"../catalog.js\";\nimport { loadUserConfig } from \"../core/user-config.js\";\n\nexport async function listCommand(options: { json?: boolean } = {}): Promise<void> {\n const templates = await loadCatalog(await loadUserConfig());\n if (options.json) {\n console.log(JSON.stringify(templates, null, 2));\n return;\n }\n console.table(\n templates.map((template) => ({\n ID: template.id,\n 名称: template.name,\n 类型: template.category,\n 状态: template.status,\n 默认分支: template.defaultRef,\n 标签: template.tags?.join(\", \") ?? \"\"\n }))\n );\n}\n","import path from \"node:path\";\nimport { loadTemplateManifest } from \"../core/template-manifest.js\";\nimport { runCommand } from \"../utils/process.js\";\n\nexport async function validateTemplateCommand(templatePath: string): Promise<void> {\n const root = path.resolve(templatePath);\n const manifest = await loadTemplateManifest(root);\n await runCommand(process.execPath, [path.join(root, \"scripts\", \"validate-template.mjs\")], {\n cwd: root\n });\n console.log(`模板可用: ${manifest.id}@${manifest.version}`);\n}\n","import {\n DEFAULT_USER_CONFIG,\n getUserConfigPath,\n loadUserConfig,\n parseUserConfigValue,\n saveUserConfig\n} from \"../core/user-config.js\";\n\nexport async function configListCommand(options: { json?: boolean } = {}): Promise<void> {\n const config = await loadUserConfig();\n if (options.json) console.log(JSON.stringify(config, null, 2));\n else console.table(Object.entries(config).map(([key, value]) => ({ key, value })));\n console.log(`配置文件: ${getUserConfigPath()}`);\n}\n\nexport async function configGetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in config)) throw new Error(`配置项不存在: ${key}`);\n console.log(String((config as unknown as Record<string, unknown>)[key]));\n}\n\nexport async function configSetCommand(key: string, value: string): Promise<void> {\n const config = await loadUserConfig();\n const [typedKey, typedValue] = parseUserConfigValue(key, value);\n (config as unknown as Record<string, unknown>)[typedKey] = typedValue;\n await saveUserConfig(config);\n console.log(`已设置 ${typedKey}=${String(typedValue)}`);\n}\n\nexport async function configUnsetCommand(key: string): Promise<void> {\n const config = await loadUserConfig();\n if (!(key in DEFAULT_USER_CONFIG) && !(key in config)) {\n throw new Error(`配置项不存在: ${key}`);\n }\n const defaults = DEFAULT_USER_CONFIG as unknown as Record<string, unknown>;\n const mutable = config as unknown as Record<string, unknown>;\n if (key in defaults) mutable[key] = defaults[key];\n else delete mutable[key];\n await saveUserConfig(config);\n console.log(`已重置配置项: ${key}`);\n}\n\nexport async function configResetCommand(): Promise<void> {\n await saveUserConfig({ ...DEFAULT_USER_CONFIG });\n console.log(`用户配置已恢复默认值: ${getUserConfigPath()}`);\n}\n","import {\n clearTemplateCache,\n getTemplateCacheRoot,\n listTemplateCache\n} from \"../core/template-cache.js\";\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 ** 2) return `${(bytes / 1024).toFixed(1)} KB`;\n return `${(bytes / 1024 ** 2).toFixed(1)} MB`;\n}\n\nexport async function cacheListCommand(options: { json?: boolean } = {}): Promise<void> {\n const entries = await listTemplateCache();\n if (options.json) {\n console.log(JSON.stringify(entries, null, 2));\n return;\n }\n if (!entries.length) {\n console.log(`模板缓存为空: ${getTemplateCacheRoot()}`);\n return;\n }\n console.table(\n entries.map((entry) => ({\n Key: entry.key,\n 来源: entry.metadata.source,\n Ref: entry.metadata.ref,\n 缓存时间: entry.metadata.cachedAt,\n 大小: formatBytes(entry.sizeBytes)\n }))\n );\n}\n\nexport async function cacheClearCommand(): Promise<void> {\n await clearTemplateCache();\n console.log(`模板缓存已清理: ${getTemplateCacheRoot()}`);\n}\n","import { runCli } from \"./cli.js\";\n\nrunCli().catch((error) => {\n console.error(`\\n错误: ${(error as Error).message}\\n`);\n process.exitCode = 1;\n});\n"],"mappings":"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","names":["path","existsSync","readdir","existsSync","path","path","existsSync","mkdir","readdir","rename","rm","writeFile","existsSync","mkdir","stat","path","path","existsSync","path","existsSync","path","existsSync","mkdir","stat","existsSync","path","readdir","rename","rm","writeFile","mkdir","prompts","existsSync","rename","rm","path","path","path","path","existsSync","rename","rm","selected","existsSync","mkdir","writeFile","rm","path","satisfies","path","mkdir","writeFile","rm","satisfies","existsSync","path","existsSync","path","existsSync","path","path","config"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agile-team/jh4j-cloud-cli",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "JH4J Cloud 企业内部标准化项目脚手架",
5
5
  "repository": {
6
6
  "type": "git",