@agile-team/jh4j-cloud-cli 0.3.0 → 0.4.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 +8 -0
- package/README.md +295 -86
- package/dist/index.js +54 -22
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0
|
|
4
|
+
|
|
5
|
+
- 接入 `mobile.robot-h5` 移动端 H5 模板,支持 GitHub/Gitee 双 HTTPS 源。
|
|
6
|
+
- 移动端创建流程使用应用标题、本地 API 地址等移动端语义,隐藏 PC 专属问题。
|
|
7
|
+
- CLI 与直接 clone 共用移动端模板初始化契约。
|
|
8
|
+
- 移除 `--ref` 的硬编码 `main` 默认值,允许各模板使用 Catalog 中声明的分支或标签。
|
|
9
|
+
- 重写中文 README,使说明与当前命令和能力保持一致。
|
|
10
|
+
|
|
3
11
|
## 0.3.0
|
|
4
12
|
|
|
5
13
|
- 增加“项目类型 → 具体模板 → 标准能力”的分层交互。
|
package/README.md
CHANGED
|
@@ -1,69 +1,115 @@
|
|
|
1
|
-
#
|
|
1
|
+
# JH4J Cloud CLI
|
|
2
2
|
|
|
3
|
-
JH4J Cloud
|
|
3
|
+
JH4J Cloud 团队项目脚手架,用于从受控模板快速创建结构一致、配置完整、可追溯的工程。
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
当前版本:`@agile-team/jh4j-cloud-cli@0.4.0`。
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
- pnpm 11.8+
|
|
9
|
-
- Git(使用 Git 模板源或初始化项目仓库时需要)
|
|
7
|
+
## 核心能力
|
|
10
8
|
|
|
11
|
-
|
|
9
|
+
| 能力 | 说明 |
|
|
10
|
+
| --- | --- |
|
|
11
|
+
| 分类选择 | 按前端、后端、移动端组织模板;当前已接入 PC 与移动端模板 |
|
|
12
|
+
| 交互创建 | 依次确认项目类型、模板、标准能力和项目参数 |
|
|
13
|
+
| 非交互创建 | 支持命令行参数和 JSON 配置文件,适用于 CI 与批量初始化 |
|
|
14
|
+
| 多源拉取 | 支持本地目录、Git、HTTP 压缩包和离线压缩包 |
|
|
15
|
+
| 源站容灾 | 内置模板按 GitHub → Gitee 顺序拉取,主源不可用时自动切换 |
|
|
16
|
+
| 模板缓存 | 按 `source + ref` 缓存远程模板,支持查看、清理和强制刷新 |
|
|
17
|
+
| 安全生成 | 在临时目录完成初始化与校验,成功后再原子写入目标目录 |
|
|
18
|
+
| 工程初始化 | 可自动安装依赖、初始化 `main` 分支并创建首次提交 |
|
|
19
|
+
| 来源追踪 | 生成 `.jhlc/project.json`,记录模板版本、CLI 版本和创建参数 |
|
|
20
|
+
|
|
21
|
+
生成链路:
|
|
22
|
+
|
|
23
|
+
```text
|
|
24
|
+
jh4j create
|
|
25
|
+
→ 读取 Catalog
|
|
26
|
+
→ 选择项目类型与模板
|
|
27
|
+
→ 解析可用模板源
|
|
28
|
+
→ 拉取或读取缓存
|
|
29
|
+
→ 校验 template.manifest.json
|
|
30
|
+
→ 在 staging 目录执行模板初始化
|
|
31
|
+
→ 安装依赖并初始化 Git
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 环境要求
|
|
35
|
+
|
|
36
|
+
- Node.js `^22.12.0 || ^24.0.0`,推荐 Node.js 24
|
|
37
|
+
- pnpm `>=11.8.0`
|
|
38
|
+
- Git
|
|
39
|
+
|
|
40
|
+
建议先检查本机环境:
|
|
12
41
|
|
|
13
42
|
```bash
|
|
14
|
-
|
|
15
|
-
pnpm check
|
|
16
|
-
node bin/jh4j.js doctor
|
|
43
|
+
npx @agile-team/jh4j-cloud-cli doctor
|
|
17
44
|
```
|
|
18
45
|
|
|
19
|
-
|
|
46
|
+
## 快速开始
|
|
47
|
+
|
|
48
|
+
无需全局安装:
|
|
20
49
|
|
|
21
50
|
```bash
|
|
22
|
-
npx @agile-team/jh4j-cloud-cli create
|
|
51
|
+
npx @agile-team/jh4j-cloud-cli create jh4j-ui-orders
|
|
52
|
+
```
|
|
23
53
|
|
|
24
|
-
|
|
54
|
+
或者全局安装:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
25
57
|
pnpm add -g @agile-team/jh4j-cloud-cli
|
|
26
|
-
jh4j create
|
|
58
|
+
jh4j create jh4j-ui-orders
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
交互模式会依次完成:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
项目类型
|
|
65
|
+
→ 项目模板
|
|
66
|
+
→ 标准化能力
|
|
67
|
+
→ 按模板确认项目参数与开发端口
|
|
68
|
+
→ Registry 与本地联调地址
|
|
69
|
+
→ 依赖安装与 Git 初始化
|
|
27
70
|
```
|
|
28
71
|
|
|
72
|
+
当前 Catalog 中可用模板:
|
|
73
|
+
|
|
74
|
+
| 类型 | 模板 ID | 模板 |
|
|
75
|
+
| --- | --- | --- |
|
|
76
|
+
| 前端 | `web.jh4j-mf-remote` | Vue 3 + Vite + Module Federation PC 业务子系统 |
|
|
77
|
+
| 后端 | — | 暂未接入 |
|
|
78
|
+
| 移动端 | `mobile.robot-h5` | Vue 3 + Vite 7 + Vant 4 企业级 H5 应用 |
|
|
79
|
+
|
|
29
80
|
## 创建项目
|
|
30
81
|
|
|
82
|
+
### 交互创建
|
|
83
|
+
|
|
31
84
|
```bash
|
|
32
|
-
|
|
33
|
-
|
|
85
|
+
jh4j create jh4j-ui-orders
|
|
86
|
+
```
|
|
34
87
|
|
|
35
|
-
|
|
36
|
-
# 当前后端、移动端会显示为“暂未提供”,加入 Catalog 后自动开放
|
|
88
|
+
### 使用明确参数创建
|
|
37
89
|
|
|
38
|
-
|
|
39
|
-
jh4j create
|
|
90
|
+
```bash
|
|
91
|
+
jh4j create jh4j-ui-orders \
|
|
40
92
|
--yes \
|
|
41
93
|
--category frontend \
|
|
42
94
|
--template web.jh4j-mf-remote \
|
|
43
|
-
--module
|
|
44
|
-
--title "
|
|
45
|
-
--port
|
|
46
|
-
|
|
47
|
-
# 从 JSON 文件读取项目参数
|
|
48
|
-
jh4j create my-app --yes --config ./project-input.json
|
|
49
|
-
|
|
50
|
-
# 预览,不写入项目目录
|
|
51
|
-
jh4j create my-app --yes --dry-run
|
|
52
|
-
|
|
53
|
-
# 生成源码但不安装依赖、不初始化 Git
|
|
54
|
-
jh4j create my-app --yes --skip-install --skip-git
|
|
55
|
-
|
|
56
|
-
# 使用模板但不安装完整 Git/代码标准化包
|
|
57
|
-
jh4j create my-app --yes --no-standards
|
|
95
|
+
--module orders \
|
|
96
|
+
--title "订单中心" \
|
|
97
|
+
--port 8123
|
|
58
98
|
```
|
|
59
99
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
创建过程先在当前目录的隐藏 staging 目录中完成模板初始化。只有模板脚本和项目元数据校验成功后才原子替换目标目录;即使使用 `--force`,初始化失败时原目录也会保留。
|
|
100
|
+
创建移动端项目:
|
|
63
101
|
|
|
64
|
-
|
|
102
|
+
```bash
|
|
103
|
+
jh4j create jh4j-mobile-orders \
|
|
104
|
+
--yes \
|
|
105
|
+
--category mobile \
|
|
106
|
+
--template mobile.robot-h5 \
|
|
107
|
+
--title "移动订单中心" \
|
|
108
|
+
--port 8888 \
|
|
109
|
+
--local-backend http://localhost:10010
|
|
110
|
+
```
|
|
65
111
|
|
|
66
|
-
|
|
112
|
+
### 使用 JSON 参数文件
|
|
67
113
|
|
|
68
114
|
```json
|
|
69
115
|
{
|
|
@@ -81,84 +127,163 @@ PC 模板默认启用完整的 `@robot-admin/git-standards`。也可以通过 `-
|
|
|
81
127
|
}
|
|
82
128
|
```
|
|
83
129
|
|
|
130
|
+
```bash
|
|
131
|
+
jh4j create jh4j-ui-orders --yes --config ./project-input.json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
命令行参数的优先级高于 JSON 文件中的同名配置。
|
|
135
|
+
|
|
136
|
+
### 预览生成计划
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
jh4j create jh4j-ui-orders --yes --dry-run
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
`--dry-run` 会完成模板解析和参数校验,但不会创建项目目录。
|
|
143
|
+
|
|
144
|
+
### 跳过自动步骤
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# 只生成工程文件
|
|
148
|
+
jh4j create jh4j-ui-orders --yes --skip-install --skip-git
|
|
149
|
+
|
|
150
|
+
# 不启用模板提供的完整 Git 与代码质量规范
|
|
151
|
+
jh4j create jh4j-ui-orders --yes --no-standards
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
PC 模板默认启用 `git-standards` 能力,由 `@robot-admin/git-standards` 提供 Commitizen、Commitlint、Husky、ESLint、Prettier 和 lint-staged 配置。
|
|
155
|
+
|
|
156
|
+
### 常用参数
|
|
157
|
+
|
|
158
|
+
| 参数 | 说明 |
|
|
159
|
+
| --- | --- |
|
|
160
|
+
| `-c, --category <category>` | 项目类型:`frontend`、`backend`、`mobile` |
|
|
161
|
+
| `-t, --template <id>` | 指定模板 ID |
|
|
162
|
+
| `--features <ids>` | 启用的模板能力,多个 ID 使用逗号分隔 |
|
|
163
|
+
| `--no-standards` | 禁用模板提供的 Git 与代码质量规范 |
|
|
164
|
+
| `--source <path-or-url>` | 强制使用指定模板目录、Git 地址或压缩包 |
|
|
165
|
+
| `--ref <branch-or-tag>` | 远程 Git 分支或标签,当前默认 `main` |
|
|
166
|
+
| `--config <json-file>` | 从 JSON 文件读取创建参数 |
|
|
167
|
+
| `--dry-run` | 校验并展示生成计划,不写入项目目录 |
|
|
168
|
+
| `--skip-install` | 跳过依赖安装 |
|
|
169
|
+
| `--skip-git` | 跳过 Git 初始化 |
|
|
170
|
+
| `--force` | 替换已存在的同名目录 |
|
|
171
|
+
| `--no-cache` | 不读取已有远程模板缓存 |
|
|
172
|
+
|
|
173
|
+
完整参数以命令输出为准:
|
|
174
|
+
|
|
175
|
+
```bash
|
|
176
|
+
jh4j create --help
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 生成安全性
|
|
180
|
+
|
|
181
|
+
CLI 不会直接在目标目录中边下载边修改。创建过程先在当前目录生成隐藏的 staging 目录,并依次完成:
|
|
182
|
+
|
|
183
|
+
1. 模板 Manifest 校验。
|
|
184
|
+
2. 模板初始化脚本执行。
|
|
185
|
+
3. 生成元数据校验。
|
|
186
|
+
4. staging 目录原子提升为目标目录。
|
|
187
|
+
5. 可选的依赖安装与 Git 初始化。
|
|
188
|
+
|
|
189
|
+
目标目录已存在时,默认拒绝覆盖。使用 `--force` 后,CLI 会先备份旧目录;模板初始化失败时,旧目录保持不变。依赖安装发生在工程文件生成成功之后,安装失败时会保留已生成目录,便于排查 Registry 或网络问题。
|
|
190
|
+
|
|
84
191
|
## 模板来源
|
|
85
192
|
|
|
86
193
|
支持以下来源:
|
|
87
194
|
|
|
88
195
|
- 本地模板目录
|
|
89
|
-
- Git HTTP
|
|
90
|
-
- 本地 `.tgz`、`.tar.gz`、`.tar`
|
|
196
|
+
- Git HTTP、HTTPS、SSH 和 `file://` 地址
|
|
197
|
+
- 本地 `.tgz`、`.tar.gz`、`.tar` 文件
|
|
91
198
|
- HTTP(S) 模板压缩包
|
|
92
199
|
|
|
93
|
-
|
|
200
|
+
来源解析顺序:
|
|
94
201
|
|
|
95
202
|
```text
|
|
96
203
|
--source
|
|
97
204
|
→ 模板专属环境变量
|
|
98
205
|
→ 用户配置 templateSource
|
|
99
|
-
→ Catalog defaultSource + sources
|
|
206
|
+
→ Catalog defaultSource + sources
|
|
100
207
|
```
|
|
101
208
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
209
|
+
一旦通过 `--source`、环境变量或用户配置指定来源,该来源将作为强制来源,不再自动尝试 Catalog 中的备用源。
|
|
210
|
+
|
|
211
|
+
### 内置模板源
|
|
212
|
+
|
|
213
|
+
CLI 源码开发时会优先读取工作区中的 PC、移动端模板,便于联调。
|
|
107
214
|
|
|
108
|
-
|
|
215
|
+
从 npm 安装后按以下顺序尝试远程源:
|
|
109
216
|
|
|
110
217
|
```text
|
|
111
218
|
https://github.com/ChenyCHENYU/jh4j-ui-template.git
|
|
112
219
|
→ https://gitee.com/ycyplus163/jh4j-ui-template.git
|
|
113
220
|
```
|
|
114
221
|
|
|
115
|
-
|
|
222
|
+
移动端模板按以下顺序尝试,并默认固定到 `v1.6.0`:
|
|
116
223
|
|
|
117
|
-
```
|
|
118
|
-
|
|
224
|
+
```text
|
|
225
|
+
https://github.com/ChenyCHENYU/Robot_H5.git
|
|
226
|
+
→ https://gitee.com/ycyplus163/robot_-h5.git
|
|
119
227
|
```
|
|
120
228
|
|
|
121
|
-
|
|
229
|
+
PC 模板当前默认读取 `main`。也可以通过 `--ref` 明确固定模板版本:
|
|
122
230
|
|
|
123
|
-
|
|
231
|
+
```bash
|
|
232
|
+
jh4j create jh4j-ui-orders --ref <template-tag>
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
也可以临时指定其他来源:
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
jh4j create jh4j-ui-orders \
|
|
239
|
+
--source https://git.example.com/templates/jh4j-ui-template.git \
|
|
240
|
+
--ref main
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## 模板缓存
|
|
244
|
+
|
|
245
|
+
远程 Git 和压缩包模板缓存在:
|
|
246
|
+
|
|
247
|
+
```text
|
|
248
|
+
~/.jh4j/cache/templates
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
默认缓存有效期为 60 分钟。缓存键由模板 `source + ref` 计算,不同镜像和不同分支互不覆盖。
|
|
124
252
|
|
|
125
253
|
```bash
|
|
126
254
|
jh4j cache list
|
|
127
255
|
jh4j cache list --json
|
|
128
256
|
jh4j cache clear
|
|
129
|
-
jh4j create
|
|
257
|
+
jh4j create jh4j-ui-orders --no-cache
|
|
130
258
|
```
|
|
131
259
|
|
|
132
260
|
## 用户配置
|
|
133
261
|
|
|
134
|
-
|
|
262
|
+
用户配置默认保存在 `~/.jh4j/config.json`。设置 `JH4J_HOME` 可以修改 CLI 数据根目录。
|
|
135
263
|
|
|
136
264
|
```bash
|
|
137
265
|
jh4j config list
|
|
138
266
|
jh4j config get autoInstall
|
|
139
267
|
jh4j config set autoInstall false
|
|
140
|
-
jh4j config set
|
|
268
|
+
jh4j config set autoGit false
|
|
141
269
|
jh4j config set cacheTtlMinutes 120
|
|
142
|
-
jh4j config unset
|
|
270
|
+
jh4j config unset cacheTtlMinutes
|
|
143
271
|
jh4j config reset
|
|
144
272
|
```
|
|
145
273
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
| 配置 | 说明 |
|
|
274
|
+
| 配置项 | 说明 |
|
|
149
275
|
| --- | --- |
|
|
150
276
|
| `catalogFile` | 外部 Catalog JSON 文件 |
|
|
151
|
-
| `templateSource` |
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `cacheTtlMinutes` | 模板缓存有效期,0 表示每次刷新 |
|
|
277
|
+
| `templateSource` | 全局模板源覆盖;设置后不再自动尝试 Catalog 备用源 |
|
|
278
|
+
| `npmRegistry` | npm Registry,必须能提供项目使用的企业定制包 |
|
|
279
|
+
| `jhlcRegistry` | `@jhlc` 私有 Registry |
|
|
280
|
+
| `autoInstall` | 创建后是否自动安装依赖 |
|
|
281
|
+
| `autoGit` | 创建后是否初始化 Git 仓库 |
|
|
282
|
+
| `cacheTtlMinutes` | 模板缓存有效期;`0` 表示每次刷新 |
|
|
158
283
|
|
|
159
284
|
## 外部 Catalog
|
|
160
285
|
|
|
161
|
-
通过 `JH4J_CATALOG_FILE`
|
|
286
|
+
通过 `JH4J_CATALOG_FILE` 或用户配置中的 `catalogFile` 加载外部 Catalog。相同模板 ID 会覆盖内置定义,其他 ID 会追加到模板列表。
|
|
162
287
|
|
|
163
288
|
```json
|
|
164
289
|
{
|
|
@@ -169,9 +294,9 @@ jh4j config reset
|
|
|
169
294
|
"name": "JH4J PC 微前端业务模板",
|
|
170
295
|
"description": "企业 PC 业务子系统",
|
|
171
296
|
"category": "frontend",
|
|
172
|
-
"defaultSource": "https://git.example/jh4j-ui-template.git",
|
|
297
|
+
"defaultSource": "https://git.example.com/templates/jh4j-ui-template.git",
|
|
173
298
|
"sources": [
|
|
174
|
-
"https://git-backup.example/jh4j-ui-template.git"
|
|
299
|
+
"https://git-backup.example.com/templates/jh4j-ui-template.git"
|
|
175
300
|
],
|
|
176
301
|
"sourceEnvironment": "JH4J_UI_TEMPLATE_SOURCE",
|
|
177
302
|
"defaultRef": "main",
|
|
@@ -182,23 +307,107 @@ jh4j config reset
|
|
|
182
307
|
}
|
|
183
308
|
```
|
|
184
309
|
|
|
185
|
-
|
|
310
|
+
Catalog JSON Schema 位于 [`catalog.schema.json`](./catalog.schema.json)。
|
|
311
|
+
|
|
312
|
+
## 模板接入规范
|
|
313
|
+
|
|
314
|
+
每个模板仓库至少需要提供:
|
|
315
|
+
|
|
316
|
+
```text
|
|
317
|
+
template.manifest.json # 模板 ID、版本、运行时、默认值和可选能力
|
|
318
|
+
project.config.json # 项目默认配置
|
|
319
|
+
scripts/setup-project.mjs # CLI 与直接 clone 共用的初始化入口
|
|
320
|
+
scripts/validate-template.mjs
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
模板初始化完成后必须生成 Manifest 声明的元数据文件,当前 PC 与移动端模板都使用 `.jhlc/project.json`。CLI 只有在元数据存在且模板初始化成功后才会提升 staging 目录。
|
|
324
|
+
|
|
325
|
+
校验本地模板:
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
jh4j template validate ../jh4j-ui-template
|
|
329
|
+
jh4j template validate ../../Robot_H5
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
模板列表和完整定义可通过 JSON 查看:
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
jh4j list --json
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
## 项目信息
|
|
339
|
+
|
|
340
|
+
在生成项目中查看模板与创建信息:
|
|
341
|
+
|
|
342
|
+
```bash
|
|
343
|
+
jh4j info .
|
|
344
|
+
jh4j info . --json
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
项目元数据位于 `.jhlc/project.json`,用于确认项目由哪个模板版本和 CLI 版本创建。
|
|
348
|
+
|
|
349
|
+
## 命令总览
|
|
186
350
|
|
|
187
351
|
```text
|
|
188
|
-
jh4j
|
|
189
|
-
jh4j
|
|
190
|
-
jh4j doctor [--json]
|
|
191
|
-
jh4j info [path] [--json]
|
|
192
|
-
jh4j template validate [path]
|
|
193
|
-
jh4j config list|get|set|unset|reset
|
|
194
|
-
jh4j cache list|clear
|
|
352
|
+
jh4j create [name] 创建项目
|
|
353
|
+
jh4j list [--json] 查看模板 Catalog
|
|
354
|
+
jh4j doctor [--json] 检查 Node、pnpm、Git 与模板环境
|
|
355
|
+
jh4j info [path] [--json] 查看生成项目元数据
|
|
356
|
+
jh4j template validate [path] 校验模板契约
|
|
357
|
+
jh4j config list|get|set|unset|reset 管理用户配置
|
|
358
|
+
jh4j cache list|clear 管理模板缓存
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## 本地开发
|
|
362
|
+
|
|
363
|
+
```bash
|
|
364
|
+
git clone https://github.com/ChenyCHENYU/jh4j-cloud-cli.git
|
|
365
|
+
cd jh4j-cloud-cli
|
|
366
|
+
pnpm install
|
|
367
|
+
pnpm check
|
|
368
|
+
node bin/jh4j.js doctor
|
|
195
369
|
```
|
|
196
370
|
|
|
197
|
-
|
|
371
|
+
`pnpm check` 会依次执行 TypeScript 类型检查、自动化测试和生产构建。
|
|
198
372
|
|
|
199
|
-
|
|
373
|
+
发布包检查:
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
npm pack --dry-run
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
## 常见问题
|
|
380
|
+
|
|
381
|
+
### 模板拉取失败
|
|
382
|
+
|
|
383
|
+
```bash
|
|
384
|
+
jh4j doctor
|
|
385
|
+
jh4j create jh4j-ui-orders --no-cache
|
|
386
|
+
```
|
|
200
387
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
388
|
+
先检查 GitHub、Gitee 或自定义模板源是否可访问,再检查本地 Git 代理和凭据配置。
|
|
389
|
+
|
|
390
|
+
### 依赖安装失败
|
|
391
|
+
|
|
392
|
+
生成目录会被保留。进入项目后确认 `.npmrc` 和内部 Registry 网络,再重新执行:
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
pnpm install
|
|
396
|
+
```
|
|
397
|
+
|
|
398
|
+
PC 模板包含企业定制的非 scope 依赖,默认 npm Registry 必须能够提供这些包。
|
|
399
|
+
|
|
400
|
+
### 只生成文件,不执行安装和 Git 初始化
|
|
401
|
+
|
|
402
|
+
```bash
|
|
403
|
+
jh4j create jh4j-ui-orders --yes --skip-install --skip-git
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
### 强制使用指定模板源
|
|
407
|
+
|
|
408
|
+
```bash
|
|
409
|
+
jh4j create jh4j-ui-orders \
|
|
410
|
+
--source ./jh4j-ui-template \
|
|
411
|
+
--ref main \
|
|
412
|
+
--no-cache
|
|
413
|
+
```
|
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.
|
|
9
|
+
version: "0.4.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",
|
|
@@ -126,10 +126,17 @@ async function removePath(target) {
|
|
|
126
126
|
var siblingTemplatePath = fileURLToPath(
|
|
127
127
|
new URL("../../jh4j-ui-template/", import.meta.url)
|
|
128
128
|
);
|
|
129
|
+
var siblingMobileTemplatePath = fileURLToPath(
|
|
130
|
+
new URL("../../../Robot_H5/", import.meta.url)
|
|
131
|
+
);
|
|
129
132
|
var remoteTemplateSources = [
|
|
130
133
|
"https://github.com/ChenyCHENYU/jh4j-ui-template.git",
|
|
131
134
|
"https://gitee.com/ycyplus163/jh4j-ui-template.git"
|
|
132
135
|
];
|
|
136
|
+
var remoteMobileTemplateSources = [
|
|
137
|
+
"https://github.com/ChenyCHENYU/Robot_H5.git",
|
|
138
|
+
"https://gitee.com/ycyplus163/robot_-h5.git"
|
|
139
|
+
];
|
|
133
140
|
var BUILTIN_TEMPLATES = [
|
|
134
141
|
{
|
|
135
142
|
id: "web.jh4j-mf-remote",
|
|
@@ -142,6 +149,18 @@ var BUILTIN_TEMPLATES = [
|
|
|
142
149
|
defaultRef: "main",
|
|
143
150
|
status: "beta",
|
|
144
151
|
tags: ["vue", "vite", "module-federation", "pc"]
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: "mobile.robot-h5",
|
|
155
|
+
name: "JH4J \u79FB\u52A8\u7AEF H5 \u6A21\u677F",
|
|
156
|
+
description: "Vue 3 + Vite 7 + Vant 4 \u4F01\u4E1A\u7EA7\u79FB\u52A8\u7AEF H5 \u5E94\u7528",
|
|
157
|
+
category: "mobile",
|
|
158
|
+
sourceEnvironment: TEMPLATE_SOURCE_ENV,
|
|
159
|
+
defaultSource: existsSync2(siblingMobileTemplatePath) ? siblingMobileTemplatePath : remoteMobileTemplateSources[0],
|
|
160
|
+
sources: remoteMobileTemplateSources,
|
|
161
|
+
defaultRef: "v1.6.0",
|
|
162
|
+
status: "beta",
|
|
163
|
+
tags: ["vue", "vite", "vant", "h5", "mobile"]
|
|
145
164
|
}
|
|
146
165
|
];
|
|
147
166
|
function validateCatalogTemplate(template) {
|
|
@@ -738,7 +757,7 @@ async function collectTemplateFeatures(manifest, fileConfig, options) {
|
|
|
738
757
|
}
|
|
739
758
|
return selected;
|
|
740
759
|
}
|
|
741
|
-
async function collectProjectInput(projectName, sourceConfig, fileConfig, options, userConfig, features) {
|
|
760
|
+
async function collectProjectInput(projectName, manifest, sourceConfig, fileConfig, options, userConfig, features) {
|
|
742
761
|
let moduleName = options.module ?? fileConfig.moduleName ?? inferModuleName(projectName);
|
|
743
762
|
let title = options.title ?? fileConfig.title ?? sourceConfig.title;
|
|
744
763
|
let port = options.port ?? fileConfig.devServerPort ?? sourceConfig.devServerPort;
|
|
@@ -753,28 +772,40 @@ async function collectProjectInput(projectName, sourceConfig, fileConfig, option
|
|
|
753
772
|
}
|
|
754
773
|
}
|
|
755
774
|
if (!options.yes) {
|
|
756
|
-
|
|
757
|
-
|
|
775
|
+
if (manifest.category !== "mobile") {
|
|
776
|
+
moduleName = await askText("\u6A21\u5757\u6807\u8BC6", moduleName);
|
|
777
|
+
}
|
|
778
|
+
title = await askText(
|
|
779
|
+
manifest.category === "mobile" ? "\u5E94\u7528\u6807\u9898" : "\u7CFB\u7EDF\u6807\u9898",
|
|
780
|
+
title
|
|
781
|
+
);
|
|
758
782
|
port = await askText("\u5F00\u53D1\u7AEF\u53E3", String(port));
|
|
759
783
|
npmRegistry = await askText("npm registry", npmRegistry);
|
|
760
784
|
jhlcRegistry = await askText("@jhlc \u79C1\u6709 registry", jhlcRegistry);
|
|
761
|
-
localBackendUrl = await askText(
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
if (
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
environments[env].
|
|
777
|
-
|
|
785
|
+
localBackendUrl = await askText(
|
|
786
|
+
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
|
+
);
|
|
808
|
+
}
|
|
778
809
|
}
|
|
779
810
|
}
|
|
780
811
|
}
|
|
@@ -871,6 +902,7 @@ async function generateProject(catalogTemplate, requestedProjectName, options, c
|
|
|
871
902
|
const features = await collectTemplateFeatures(manifest, fileConfig, options);
|
|
872
903
|
const input = await collectProjectInput(
|
|
873
904
|
projectName,
|
|
905
|
+
manifest,
|
|
874
906
|
{
|
|
875
907
|
...sourceProjectConfig,
|
|
876
908
|
npmRegistry: manifest.defaults.npmRegistry,
|
|
@@ -1307,7 +1339,7 @@ async function cacheClearCommand() {
|
|
|
1307
1339
|
function createProgram() {
|
|
1308
1340
|
const program = new Command();
|
|
1309
1341
|
program.name(COMMAND_NAME).description("JH4J Cloud \u4F01\u4E1A\u5185\u90E8\u6807\u51C6\u5316\u9879\u76EE\u811A\u624B\u67B6").version(CLI_VERSION);
|
|
1310
|
-
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
|
|
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);
|
|
1311
1343
|
program.command("list").description("\u5217\u51FA\u53EF\u7528\u6A21\u677F").option("--json", "\u8F93\u51FA JSON").action(listCommand);
|
|
1312
1344
|
program.command("doctor").description("\u68C0\u67E5\u672C\u673A\u73AF\u5883\u548C\u6A21\u677F\u53EF\u7528\u6027").option("--json", "\u8F93\u51FA JSON").action(doctorCommand);
|
|
1313
1345
|
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 分支或标签\", \"main\")\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.3.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 remoteTemplateSources = [\n \"https://github.com/ChenyCHENYU/jh4j-ui-template.git\",\n \"https://gitee.com/ycyplus163/jh4j-ui-template.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\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 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 moduleName = await askText(\"模块标识\", moduleName);\n title = await askText(\"系统标题\", title);\n port = await askText(\"开发端口\", String(port));\n npmRegistry = await askText(\"npm registry\", npmRegistry);\n jhlcRegistry = await askText(\"@jhlc 私有 registry\", jhlcRegistry);\n localBackendUrl = await askText(\"本地后端地址\", localBackendUrl);\n localPublicUrl = await askText(\"本地 public 地址\", localPublicUrl);\n\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 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 {\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(\"--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"]}
|