@birchcraft/mcp-weapp-cli 1.0.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/README.md +207 -0
- package/dist/cli-client.d.ts +132 -0
- package/dist/cli-client.d.ts.map +1 -0
- package/dist/cli-client.js +363 -0
- package/dist/cli-client.js.map +1 -0
- package/dist/client.d.ts +9 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +129 -0
- package/dist/client.js.map +1 -0
- package/dist/config.d.ts +52 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +171 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/server.d.ts +41 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +292 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/auth.d.ts +6 -0
- package/dist/tools/auth.d.ts.map +1 -0
- package/dist/tools/auth.js +128 -0
- package/dist/tools/auth.js.map +1 -0
- package/dist/tools/automation.d.ts +35 -0
- package/dist/tools/automation.d.ts.map +1 -0
- package/dist/tools/automation.js +245 -0
- package/dist/tools/automation.js.map +1 -0
- package/dist/tools/build.d.ts +14 -0
- package/dist/tools/build.d.ts.map +1 -0
- package/dist/tools/build.js +210 -0
- package/dist/tools/build.js.map +1 -0
- package/dist/tools/cloud.d.ts +72 -0
- package/dist/tools/cloud.d.ts.map +1 -0
- package/dist/tools/cloud.js +479 -0
- package/dist/tools/cloud.js.map +1 -0
- package/dist/tools/index.d.ts +23 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +35 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/preview.d.ts +41 -0
- package/dist/tools/preview.d.ts.map +1 -0
- package/dist/tools/preview.js +311 -0
- package/dist/tools/preview.js.map +1 -0
- package/dist/tools/project.d.ts +50 -0
- package/dist/tools/project.d.ts.map +1 -0
- package/dist/tools/project.js +308 -0
- package/dist/tools/project.js.map +1 -0
- package/dist/types.d.ts +133 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/helpers.d.ts +45 -0
- package/dist/utils/helpers.d.ts.map +1 -0
- package/dist/utils/helpers.js +116 -0
- package/dist/utils/helpers.js.map +1 -0
- package/dist/utils/logger.d.ts +22 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +50 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# 微信小程序开发者工具 MCP 服务器
|
|
2
|
+
|
|
3
|
+
一个完整的 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) 服务器实现,封装了微信开发者工具 CLI 的所有功能。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- 🔧 **完整 CLI 覆盖**: 支持微信开发者工具 CLI 的全部 20+ 个命令
|
|
8
|
+
- 🤖 **AI 集成**: 让 AI 助手能够通过自然语言调用小程序开发工具
|
|
9
|
+
- 📦 **类型安全**: 使用 TypeScript 开发,提供完整的类型定义
|
|
10
|
+
- 🔒 **错误处理**: 完善的错误处理和参数验证
|
|
11
|
+
- 📝 **资源与提示符**: 支持 MCP Resources 和 Prompts
|
|
12
|
+
|
|
13
|
+
## 支持的工具
|
|
14
|
+
|
|
15
|
+
### 登录管理
|
|
16
|
+
- `weapp_login` - 登录微信开发者工具
|
|
17
|
+
- `weapp_check_login` - 检查登录状态
|
|
18
|
+
|
|
19
|
+
### 预览与上传
|
|
20
|
+
- `weapp_preview` - 生成预览二维码
|
|
21
|
+
- `weapp_auto_preview` - 自动预览
|
|
22
|
+
- `weapp_upload` - 上传代码到微信公众平台
|
|
23
|
+
|
|
24
|
+
### 项目管理
|
|
25
|
+
- `weapp_open` - 打开工具/项目
|
|
26
|
+
- `weapp_open_other` - 以"其他"模式打开项目
|
|
27
|
+
- `weapp_close` - 关闭项目
|
|
28
|
+
- `weapp_quit` - 退出工具
|
|
29
|
+
|
|
30
|
+
### 构建
|
|
31
|
+
- `weapp_build_npm` - 构建 npm
|
|
32
|
+
- `weapp_clear_cache` - 清除缓存
|
|
33
|
+
|
|
34
|
+
### 自动化测试
|
|
35
|
+
- `weapp_auto` - 开启自动化功能
|
|
36
|
+
- `weapp_auto_replay` - 自动化测试回放
|
|
37
|
+
|
|
38
|
+
### 云开发
|
|
39
|
+
- `weapp_cloud_env_list` - 获取云环境列表
|
|
40
|
+
- `weapp_cloud_functions_list` - 获取云函数列表
|
|
41
|
+
- `weapp_cloud_functions_info` - 获取云函数信息
|
|
42
|
+
- `weapp_cloud_functions_deploy` - 部署云函数
|
|
43
|
+
- `weapp_cloud_functions_inc_deploy` - 增量部署云函数
|
|
44
|
+
- `weapp_cloud_functions_download` - 下载云函数
|
|
45
|
+
|
|
46
|
+
## 安装
|
|
47
|
+
|
|
48
|
+
### 前置要求
|
|
49
|
+
|
|
50
|
+
- Node.js >= 18
|
|
51
|
+
- 微信开发者工具(已安装并开启服务端口)
|
|
52
|
+
|
|
53
|
+
### 使用 npx 运行(推荐)
|
|
54
|
+
|
|
55
|
+
无需安装,直接使用 npx 运行:
|
|
56
|
+
|
|
57
|
+
```json
|
|
58
|
+
{
|
|
59
|
+
"mcpServers": {
|
|
60
|
+
"weapp-devtools": {
|
|
61
|
+
"command": "npx",
|
|
62
|
+
"args": ["-y", "@birchcraft/mcp-weapp-cli"],
|
|
63
|
+
"env": {
|
|
64
|
+
"WEAPP_PORT": "9420",
|
|
65
|
+
"WEAPP_LANG": "zh"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### 全局安装
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm install -g @birchcraft/mcp-weapp-cli
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 从源码安装
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# 克隆仓库
|
|
82
|
+
git clone <repository-url>
|
|
83
|
+
cd mcp-weapp-cli
|
|
84
|
+
|
|
85
|
+
# 安装依赖
|
|
86
|
+
npm install
|
|
87
|
+
|
|
88
|
+
# 编译
|
|
89
|
+
npm run build
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## 配置
|
|
93
|
+
|
|
94
|
+
### 环境变量
|
|
95
|
+
|
|
96
|
+
| 变量名 | 说明 | 默认值 |
|
|
97
|
+
|--------|------|--------|
|
|
98
|
+
| `WEAPP_CLI_PATH` | CLI 工具路径 | 自动检测 |
|
|
99
|
+
| `WEAPP_PORT` | HTTP 服务端口 | 9420 |
|
|
100
|
+
| `WEAPP_LANG` | 语言 (en/zh) | zh |
|
|
101
|
+
| `WEAPP_DEBUG` | 调试模式 | false |
|
|
102
|
+
|
|
103
|
+
### MCP 客户端配置
|
|
104
|
+
|
|
105
|
+
#### Claude Desktop / Cursor
|
|
106
|
+
|
|
107
|
+
编辑配置文件:
|
|
108
|
+
- **Windows**: `%APPDATA%/Claude/claude_desktop_config.json`
|
|
109
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
110
|
+
|
|
111
|
+
**使用 npx(推荐):**
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"mcpServers": {
|
|
116
|
+
"weapp-devtools": {
|
|
117
|
+
"command": "npx",
|
|
118
|
+
"args": ["-y", "@birchcraft/mcp-weapp-cli"],
|
|
119
|
+
"env": {
|
|
120
|
+
"WEAPP_PORT": "9420",
|
|
121
|
+
"WEAPP_LANG": "zh"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
**使用本地路径:**
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"mcpServers": {
|
|
133
|
+
"weapp-devtools": {
|
|
134
|
+
"command": "node",
|
|
135
|
+
"args": ["D:\\Projects\\WeappMCP\\dist\\index.js"],
|
|
136
|
+
"env": {
|
|
137
|
+
"WEAPP_PORT": "9420",
|
|
138
|
+
"WEAPP_LANG": "zh"
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## 使用示例
|
|
146
|
+
|
|
147
|
+
### 登录开发者工具
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
使用 weapp_login 工具登录微信开发者工具
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 预览项目
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
使用 weapp_preview 工具为项目 D:\Projects\MyMiniApp 生成预览二维码
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### 上传代码
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
使用 weapp_upload 工具上传项目 D:\Projects\MyMiniApp,版本 1.0.0,描述 "初始版本"
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### 构建 npm
|
|
166
|
+
|
|
167
|
+
```
|
|
168
|
+
使用 weapp_build_npm 工具为项目 D:\Projects\MyMiniApp 构建 npm
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## 开发
|
|
172
|
+
|
|
173
|
+
```bash
|
|
174
|
+
# 开发模式(自动编译)
|
|
175
|
+
npm run dev
|
|
176
|
+
|
|
177
|
+
# 运行测试
|
|
178
|
+
npm test
|
|
179
|
+
|
|
180
|
+
# 代码格式化
|
|
181
|
+
npm run format
|
|
182
|
+
|
|
183
|
+
# 代码检查
|
|
184
|
+
npm run lint
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## CLI 路径自动检测
|
|
188
|
+
|
|
189
|
+
如果没有设置 `WEAPP_CLI_PATH`,服务器会自动检测以下常见路径:
|
|
190
|
+
|
|
191
|
+
### Windows
|
|
192
|
+
- `C:\Program Files (x86)\Tencent\微信web开发者工具\cli.bat`
|
|
193
|
+
- `C:\Program Files\Tencent\微信web开发者工具\cli.bat`
|
|
194
|
+
|
|
195
|
+
### macOS
|
|
196
|
+
- `/Applications/wechatwebdevtools.app/Contents/MacOS/cli`
|
|
197
|
+
- `/Applications/微信开发者工具.app/Contents/MacOS/cli`
|
|
198
|
+
|
|
199
|
+
## 文档
|
|
200
|
+
|
|
201
|
+
- [MCP 基础知识](./docs/MCP基础知识.md)
|
|
202
|
+
- [设计方案](./docs/设计方案.md)
|
|
203
|
+
- [微信开发者工具 CLI 文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/cli.html)
|
|
204
|
+
|
|
205
|
+
## 许可证
|
|
206
|
+
|
|
207
|
+
MIT License
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { CLIResult, CLIExecuteOptions, CacheType, QRFormat, QRSize, CompileType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* CLI 客户端类
|
|
4
|
+
*/
|
|
5
|
+
export declare class CLIClient {
|
|
6
|
+
private cliPath;
|
|
7
|
+
private isInitialized;
|
|
8
|
+
/**
|
|
9
|
+
* 初始化 CLI 客户端
|
|
10
|
+
*/
|
|
11
|
+
initialize(): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* 设置 CLI 路径
|
|
14
|
+
*/
|
|
15
|
+
setCliPath(path: string): void;
|
|
16
|
+
/**
|
|
17
|
+
* 获取 CLI 路径
|
|
18
|
+
*/
|
|
19
|
+
getCliPath(): string;
|
|
20
|
+
/**
|
|
21
|
+
* 构建全局参数
|
|
22
|
+
*/
|
|
23
|
+
private buildGlobalArgs;
|
|
24
|
+
/**
|
|
25
|
+
* 执行 CLI 命令
|
|
26
|
+
*/
|
|
27
|
+
execute(subCommand: string, args?: string[], options?: CLIExecuteOptions): Promise<CLIResult>;
|
|
28
|
+
/**
|
|
29
|
+
* 登录
|
|
30
|
+
*/
|
|
31
|
+
login(qrFormat?: QRFormat, qrSize?: QRSize, qrOutput?: string, resultOutput?: string): Promise<CLIResult>;
|
|
32
|
+
/**
|
|
33
|
+
* 检查登录状态
|
|
34
|
+
*/
|
|
35
|
+
checkLogin(): Promise<CLIResult>;
|
|
36
|
+
/**
|
|
37
|
+
* 预览
|
|
38
|
+
*/
|
|
39
|
+
preview(projectPath: string, qrFormat?: QRFormat, qrOutput?: string, infoOutput?: string): Promise<CLIResult>;
|
|
40
|
+
/**
|
|
41
|
+
* 自动预览
|
|
42
|
+
*/
|
|
43
|
+
autoPreview(projectPath: string, infoOutput?: string): Promise<CLIResult>;
|
|
44
|
+
/**
|
|
45
|
+
* 上传
|
|
46
|
+
*/
|
|
47
|
+
upload(projectPath: string, version: string, desc: string, infoOutput?: string): Promise<CLIResult>;
|
|
48
|
+
/**
|
|
49
|
+
* 打开工具/项目
|
|
50
|
+
*/
|
|
51
|
+
open(projectPath?: string): Promise<CLIResult>;
|
|
52
|
+
/**
|
|
53
|
+
* 以其他模式打开
|
|
54
|
+
*/
|
|
55
|
+
openOther(projectPath: string): Promise<CLIResult>;
|
|
56
|
+
/**
|
|
57
|
+
* 关闭项目
|
|
58
|
+
*/
|
|
59
|
+
close(projectPath?: string): Promise<CLIResult>;
|
|
60
|
+
/**
|
|
61
|
+
* 退出工具
|
|
62
|
+
*/
|
|
63
|
+
quit(): Promise<CLIResult>;
|
|
64
|
+
/**
|
|
65
|
+
* 构建 npm
|
|
66
|
+
*/
|
|
67
|
+
buildNpm(projectPath: string, compileType?: CompileType): Promise<CLIResult>;
|
|
68
|
+
/**
|
|
69
|
+
* 清除缓存
|
|
70
|
+
*/
|
|
71
|
+
clearCache(clean: CacheType): Promise<CLIResult>;
|
|
72
|
+
/**
|
|
73
|
+
* 开启自动化
|
|
74
|
+
*/
|
|
75
|
+
auto(projectPath: string, options?: {
|
|
76
|
+
autoPort?: number;
|
|
77
|
+
autoAccount?: string;
|
|
78
|
+
trustProject?: boolean;
|
|
79
|
+
ticket?: string;
|
|
80
|
+
}): Promise<CLIResult>;
|
|
81
|
+
/**
|
|
82
|
+
* 自动化测试回放
|
|
83
|
+
*/
|
|
84
|
+
autoReplay(projectPath: string, options?: {
|
|
85
|
+
replayAll?: boolean;
|
|
86
|
+
replayConfigPath?: string;
|
|
87
|
+
trustProject?: boolean;
|
|
88
|
+
ticket?: string;
|
|
89
|
+
}): Promise<CLIResult>;
|
|
90
|
+
/**
|
|
91
|
+
* 获取云环境列表
|
|
92
|
+
*/
|
|
93
|
+
cloudEnvList(projectPath: string): Promise<CLIResult>;
|
|
94
|
+
/**
|
|
95
|
+
* 获取云函数列表
|
|
96
|
+
*/
|
|
97
|
+
cloudFunctionsList(projectPath: string, env: string): Promise<CLIResult>;
|
|
98
|
+
/**
|
|
99
|
+
* 获取云函数信息
|
|
100
|
+
*/
|
|
101
|
+
cloudFunctionsInfo(projectPath: string, env: string, names: string[]): Promise<CLIResult>;
|
|
102
|
+
/**
|
|
103
|
+
* 部署云函数
|
|
104
|
+
*/
|
|
105
|
+
cloudFunctionsDeploy(projectPath: string, env: string, options?: {
|
|
106
|
+
names?: string[];
|
|
107
|
+
paths?: string[];
|
|
108
|
+
remoteNpmInstall?: boolean;
|
|
109
|
+
}): Promise<CLIResult>;
|
|
110
|
+
/**
|
|
111
|
+
* 增量部署云函数
|
|
112
|
+
*/
|
|
113
|
+
cloudFunctionsIncDeploy(projectPath: string, env: string, options?: {
|
|
114
|
+
names?: string[];
|
|
115
|
+
paths?: string[];
|
|
116
|
+
remoteNpmInstall?: boolean;
|
|
117
|
+
}): Promise<CLIResult>;
|
|
118
|
+
/**
|
|
119
|
+
* 下载云函数
|
|
120
|
+
*/
|
|
121
|
+
cloudFunctionsDownload(projectPath: string, env: string, name: string): Promise<CLIResult>;
|
|
122
|
+
/**
|
|
123
|
+
* 重置文件监听
|
|
124
|
+
*/
|
|
125
|
+
resetFileutils(projectPath?: string): Promise<CLIResult>;
|
|
126
|
+
/**
|
|
127
|
+
* 引擎构建
|
|
128
|
+
*/
|
|
129
|
+
engineBuild(projectPath: string): Promise<CLIResult>;
|
|
130
|
+
}
|
|
131
|
+
export declare const cliClient: CLIClient;
|
|
132
|
+
//# sourceMappingURL=cli-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-client.d.ts","sourceRoot":"","sources":["../src/cli-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI 客户端模块
|
|
3
|
+
* 负责与微信开发者工具 CLI 交互
|
|
4
|
+
*/
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { CLICommand } from './types.js';
|
|
7
|
+
import { configManager } from './config.js';
|
|
8
|
+
import { logger } from './utils/logger.js';
|
|
9
|
+
import { formatError } from './utils/helpers.js';
|
|
10
|
+
/**
|
|
11
|
+
* CLI 客户端类
|
|
12
|
+
*/
|
|
13
|
+
export class CLIClient {
|
|
14
|
+
cliPath = '';
|
|
15
|
+
isInitialized = false;
|
|
16
|
+
/**
|
|
17
|
+
* 初始化 CLI 客户端
|
|
18
|
+
*/
|
|
19
|
+
async initialize() {
|
|
20
|
+
if (this.isInitialized)
|
|
21
|
+
return;
|
|
22
|
+
// 尝试自动检测 CLI 路径
|
|
23
|
+
const detectedPath = await configManager.detectCliPath();
|
|
24
|
+
if (detectedPath) {
|
|
25
|
+
this.cliPath = detectedPath;
|
|
26
|
+
logger.info(`CLI 路径: ${this.cliPath}`);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
throw new Error('无法找到微信开发者工具 CLI。请设置 WEAPP_CLI_PATH 环境变量或确保工具已安装。');
|
|
30
|
+
}
|
|
31
|
+
this.isInitialized = true;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* 设置 CLI 路径
|
|
35
|
+
*/
|
|
36
|
+
setCliPath(path) {
|
|
37
|
+
this.cliPath = path;
|
|
38
|
+
configManager.setCliPath(path);
|
|
39
|
+
this.isInitialized = true;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* 获取 CLI 路径
|
|
43
|
+
*/
|
|
44
|
+
getCliPath() {
|
|
45
|
+
return this.cliPath;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 构建全局参数
|
|
49
|
+
*/
|
|
50
|
+
buildGlobalArgs() {
|
|
51
|
+
const config = configManager.getConfig();
|
|
52
|
+
const args = [];
|
|
53
|
+
if (config.port) {
|
|
54
|
+
args.push('--port', String(config.port));
|
|
55
|
+
}
|
|
56
|
+
if (config.lang) {
|
|
57
|
+
args.push('--lang', config.lang);
|
|
58
|
+
}
|
|
59
|
+
if (config.debug) {
|
|
60
|
+
args.push('--debug');
|
|
61
|
+
}
|
|
62
|
+
return args;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* 执行 CLI 命令
|
|
66
|
+
*/
|
|
67
|
+
async execute(subCommand, args = [], options = {}) {
|
|
68
|
+
await this.initialize();
|
|
69
|
+
const { timeout = 300000, cwd, env } = options; // 默认5分钟超时
|
|
70
|
+
const globalArgs = this.buildGlobalArgs();
|
|
71
|
+
const allArgs = [subCommand, ...args, ...globalArgs];
|
|
72
|
+
logger.debug(`执行命令: ${this.cliPath} ${allArgs.join(' ')}`);
|
|
73
|
+
return new Promise((resolve, reject) => {
|
|
74
|
+
const child = spawn(this.cliPath, allArgs, {
|
|
75
|
+
cwd,
|
|
76
|
+
env: { ...process.env, ...env },
|
|
77
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
78
|
+
windowsHide: true,
|
|
79
|
+
shell: true, // 使用 shell 执行,解决 Windows 上 .bat 文件的执行问题
|
|
80
|
+
});
|
|
81
|
+
let stdout = '';
|
|
82
|
+
let stderr = '';
|
|
83
|
+
let timeoutId = null;
|
|
84
|
+
// 设置超时
|
|
85
|
+
if (timeout > 0) {
|
|
86
|
+
timeoutId = setTimeout(() => {
|
|
87
|
+
child.kill('SIGTERM');
|
|
88
|
+
reject(new Error(`命令执行超时 (${timeout}ms)`));
|
|
89
|
+
}, timeout);
|
|
90
|
+
}
|
|
91
|
+
// 收集标准输出
|
|
92
|
+
child.stdout?.on('data', (data) => {
|
|
93
|
+
const chunk = data.toString();
|
|
94
|
+
stdout += chunk;
|
|
95
|
+
logger.debug('stdout:', chunk);
|
|
96
|
+
});
|
|
97
|
+
// 收集错误输出
|
|
98
|
+
child.stderr?.on('data', (data) => {
|
|
99
|
+
const chunk = data.toString();
|
|
100
|
+
stderr += chunk;
|
|
101
|
+
logger.debug('stderr:', chunk);
|
|
102
|
+
});
|
|
103
|
+
// 进程结束
|
|
104
|
+
child.on('close', (code) => {
|
|
105
|
+
if (timeoutId)
|
|
106
|
+
clearTimeout(timeoutId);
|
|
107
|
+
const result = {
|
|
108
|
+
success: code === 0,
|
|
109
|
+
code: code ?? -1,
|
|
110
|
+
stdout: stdout.trim(),
|
|
111
|
+
stderr: stderr.trim(),
|
|
112
|
+
};
|
|
113
|
+
logger.debug(`命令执行完成,退出码: ${code}`);
|
|
114
|
+
resolve(result);
|
|
115
|
+
});
|
|
116
|
+
// 错误处理
|
|
117
|
+
child.on('error', (error) => {
|
|
118
|
+
if (timeoutId)
|
|
119
|
+
clearTimeout(timeoutId);
|
|
120
|
+
logger.error('命令执行失败:', formatError(error));
|
|
121
|
+
reject(error);
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
// ==================== 登录相关 ====================
|
|
126
|
+
/**
|
|
127
|
+
* 登录
|
|
128
|
+
*/
|
|
129
|
+
async login(qrFormat = 'terminal', qrSize, qrOutput, resultOutput) {
|
|
130
|
+
const args = ['--qr-format', qrFormat];
|
|
131
|
+
if (qrSize && qrFormat === 'terminal') {
|
|
132
|
+
args.push('--qr-size', qrSize);
|
|
133
|
+
}
|
|
134
|
+
if (qrOutput) {
|
|
135
|
+
args.push('--qr-output', qrOutput);
|
|
136
|
+
}
|
|
137
|
+
if (resultOutput) {
|
|
138
|
+
args.push('--result-output', resultOutput);
|
|
139
|
+
}
|
|
140
|
+
return this.execute(CLICommand.LOGIN, args, { timeout: 300000 }); // 登录可能需要较长时间
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* 检查登录状态
|
|
144
|
+
*/
|
|
145
|
+
async checkLogin() {
|
|
146
|
+
return this.execute(CLICommand.IS_LOGIN);
|
|
147
|
+
}
|
|
148
|
+
// ==================== 预览/上传 ====================
|
|
149
|
+
/**
|
|
150
|
+
* 预览
|
|
151
|
+
*/
|
|
152
|
+
async preview(projectPath, qrFormat = 'terminal', qrOutput, infoOutput) {
|
|
153
|
+
const args = ['--project', projectPath, '--qr-format', qrFormat];
|
|
154
|
+
if (qrOutput) {
|
|
155
|
+
args.push('--qr-output', qrOutput);
|
|
156
|
+
}
|
|
157
|
+
if (infoOutput) {
|
|
158
|
+
args.push('--info-output', infoOutput);
|
|
159
|
+
}
|
|
160
|
+
return this.execute(CLICommand.PREVIEW, args, { timeout: 120000 });
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* 自动预览
|
|
164
|
+
*/
|
|
165
|
+
async autoPreview(projectPath, infoOutput) {
|
|
166
|
+
const args = ['--project', projectPath];
|
|
167
|
+
if (infoOutput) {
|
|
168
|
+
args.push('--info-output', infoOutput);
|
|
169
|
+
}
|
|
170
|
+
return this.execute(CLICommand.AUTO_PREVIEW, args, { timeout: 120000 });
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* 上传
|
|
174
|
+
*/
|
|
175
|
+
async upload(projectPath, version, desc, infoOutput) {
|
|
176
|
+
const args = [
|
|
177
|
+
'--project', projectPath,
|
|
178
|
+
'--version', version,
|
|
179
|
+
'--desc', desc,
|
|
180
|
+
];
|
|
181
|
+
if (infoOutput) {
|
|
182
|
+
args.push('--info-output', infoOutput);
|
|
183
|
+
}
|
|
184
|
+
return this.execute(CLICommand.UPLOAD, args, { timeout: 300000 });
|
|
185
|
+
}
|
|
186
|
+
// ==================== 项目管理 ====================
|
|
187
|
+
/**
|
|
188
|
+
* 打开工具/项目
|
|
189
|
+
*/
|
|
190
|
+
async open(projectPath) {
|
|
191
|
+
const args = [];
|
|
192
|
+
if (projectPath) {
|
|
193
|
+
args.push('--project', projectPath);
|
|
194
|
+
}
|
|
195
|
+
return this.execute(CLICommand.OPEN, args);
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* 以其他模式打开
|
|
199
|
+
*/
|
|
200
|
+
async openOther(projectPath) {
|
|
201
|
+
return this.execute(CLICommand.OPEN_OTHER, ['--project', projectPath]);
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* 关闭项目
|
|
205
|
+
*/
|
|
206
|
+
async close(projectPath) {
|
|
207
|
+
const args = [];
|
|
208
|
+
if (projectPath) {
|
|
209
|
+
args.push('--project', projectPath);
|
|
210
|
+
}
|
|
211
|
+
return this.execute(CLICommand.CLOSE, args);
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* 退出工具
|
|
215
|
+
*/
|
|
216
|
+
async quit() {
|
|
217
|
+
return this.execute(CLICommand.QUIT);
|
|
218
|
+
}
|
|
219
|
+
// ==================== 构建 ====================
|
|
220
|
+
/**
|
|
221
|
+
* 构建 npm
|
|
222
|
+
*/
|
|
223
|
+
async buildNpm(projectPath, compileType) {
|
|
224
|
+
const args = ['--project', projectPath];
|
|
225
|
+
if (compileType) {
|
|
226
|
+
args.push('--compile-type', compileType);
|
|
227
|
+
}
|
|
228
|
+
return this.execute(CLICommand.BUILD_NPM, args, { timeout: 120000 });
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* 清除缓存
|
|
232
|
+
*/
|
|
233
|
+
async clearCache(clean) {
|
|
234
|
+
return this.execute(CLICommand.CACHE, ['--clean', clean]);
|
|
235
|
+
}
|
|
236
|
+
// ==================== 自动化 ====================
|
|
237
|
+
/**
|
|
238
|
+
* 开启自动化
|
|
239
|
+
*/
|
|
240
|
+
async auto(projectPath, options = {}) {
|
|
241
|
+
const args = ['--project', projectPath];
|
|
242
|
+
if (options.autoPort) {
|
|
243
|
+
args.push('--auto-port', String(options.autoPort));
|
|
244
|
+
}
|
|
245
|
+
if (options.autoAccount) {
|
|
246
|
+
args.push('--auto-account', options.autoAccount);
|
|
247
|
+
}
|
|
248
|
+
if (options.trustProject) {
|
|
249
|
+
args.push('--trust-project');
|
|
250
|
+
}
|
|
251
|
+
if (options.ticket) {
|
|
252
|
+
args.push('--ticket', options.ticket);
|
|
253
|
+
}
|
|
254
|
+
return this.execute(CLICommand.AUTO, args);
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 自动化测试回放
|
|
258
|
+
*/
|
|
259
|
+
async autoReplay(projectPath, options = {}) {
|
|
260
|
+
const args = ['--project', projectPath];
|
|
261
|
+
if (options.replayAll) {
|
|
262
|
+
args.push('--replay-all');
|
|
263
|
+
}
|
|
264
|
+
if (options.replayConfigPath) {
|
|
265
|
+
args.push('--replay-config-path', options.replayConfigPath);
|
|
266
|
+
}
|
|
267
|
+
if (options.trustProject) {
|
|
268
|
+
args.push('--trust-project');
|
|
269
|
+
}
|
|
270
|
+
if (options.ticket) {
|
|
271
|
+
args.push('--ticket', options.ticket);
|
|
272
|
+
}
|
|
273
|
+
return this.execute(CLICommand.AUTO_REPLAY, args);
|
|
274
|
+
}
|
|
275
|
+
// ==================== 云开发 ====================
|
|
276
|
+
/**
|
|
277
|
+
* 获取云环境列表
|
|
278
|
+
*/
|
|
279
|
+
async cloudEnvList(projectPath) {
|
|
280
|
+
return this.execute(CLICommand.CLOUD_ENV_LIST, ['--project', projectPath]);
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* 获取云函数列表
|
|
284
|
+
*/
|
|
285
|
+
async cloudFunctionsList(projectPath, env) {
|
|
286
|
+
return this.execute(CLICommand.CLOUD_FUNCTIONS_LIST, [
|
|
287
|
+
'--project', projectPath,
|
|
288
|
+
'--env', env,
|
|
289
|
+
]);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* 获取云函数信息
|
|
293
|
+
*/
|
|
294
|
+
async cloudFunctionsInfo(projectPath, env, names) {
|
|
295
|
+
return this.execute(CLICommand.CLOUD_FUNCTIONS_INFO, [
|
|
296
|
+
'--project', projectPath,
|
|
297
|
+
'--env', env,
|
|
298
|
+
'--names', ...names,
|
|
299
|
+
]);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* 部署云函数
|
|
303
|
+
*/
|
|
304
|
+
async cloudFunctionsDeploy(projectPath, env, options = {}) {
|
|
305
|
+
const args = ['--project', projectPath, '--env', env];
|
|
306
|
+
if (options.names && options.names.length > 0) {
|
|
307
|
+
args.push('--names', ...options.names);
|
|
308
|
+
}
|
|
309
|
+
if (options.paths && options.paths.length > 0) {
|
|
310
|
+
args.push('--paths', ...options.paths);
|
|
311
|
+
}
|
|
312
|
+
if (options.remoteNpmInstall) {
|
|
313
|
+
args.push('--remote-npm-install');
|
|
314
|
+
}
|
|
315
|
+
return this.execute(CLICommand.CLOUD_FUNCTIONS_DEPLOY, args, { timeout: 300000 });
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* 增量部署云函数
|
|
319
|
+
*/
|
|
320
|
+
async cloudFunctionsIncDeploy(projectPath, env, options = {}) {
|
|
321
|
+
const args = ['--project', projectPath, '--env', env];
|
|
322
|
+
if (options.names && options.names.length > 0) {
|
|
323
|
+
args.push('--names', ...options.names);
|
|
324
|
+
}
|
|
325
|
+
if (options.paths && options.paths.length > 0) {
|
|
326
|
+
args.push('--paths', ...options.paths);
|
|
327
|
+
}
|
|
328
|
+
if (options.remoteNpmInstall) {
|
|
329
|
+
args.push('--remote-npm-install');
|
|
330
|
+
}
|
|
331
|
+
return this.execute(CLICommand.CLOUD_FUNCTIONS_INC_DEPLOY, args, { timeout: 300000 });
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* 下载云函数
|
|
335
|
+
*/
|
|
336
|
+
async cloudFunctionsDownload(projectPath, env, name) {
|
|
337
|
+
return this.execute(CLICommand.CLOUD_FUNCTIONS_DOWNLOAD, [
|
|
338
|
+
'--project', projectPath,
|
|
339
|
+
'--env', env,
|
|
340
|
+
'--name', name,
|
|
341
|
+
]);
|
|
342
|
+
}
|
|
343
|
+
// ==================== 其他 ====================
|
|
344
|
+
/**
|
|
345
|
+
* 重置文件监听
|
|
346
|
+
*/
|
|
347
|
+
async resetFileutils(projectPath) {
|
|
348
|
+
const args = [];
|
|
349
|
+
if (projectPath) {
|
|
350
|
+
args.push('--project', projectPath);
|
|
351
|
+
}
|
|
352
|
+
return this.execute(CLICommand.RESET_FILEUTILS, args);
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* 引擎构建
|
|
356
|
+
*/
|
|
357
|
+
async engineBuild(projectPath) {
|
|
358
|
+
return this.execute(CLICommand.ENGINE_BUILD, [projectPath]);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
// 导出单例
|
|
362
|
+
export const cliClient = new CLIClient();
|
|
363
|
+
//# sourceMappingURL=cli-client.js.map
|