@vectorx/xhs-cloud-cli 0.1.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 +34 -0
- package/bin/rcb.js +264 -0
- package/lib/commands/agent/build.js +222 -0
- package/lib/commands/agent/dev.js +112 -0
- package/lib/commands/agent/index.js +19 -0
- package/lib/commands/agent/new.js +125 -0
- package/lib/commands/auth/index.js +18 -0
- package/lib/commands/auth/login.js +196 -0
- package/lib/commands/auth/logout.js +87 -0
- package/lib/commands/index.js +18 -0
- package/lib/constants/cmd.js +37 -0
- package/lib/core/base.js +95 -0
- package/lib/decorators/auth.js +49 -0
- package/lib/decorators/captureError.js +28 -0
- package/lib/decorators/constants.js +15 -0
- package/lib/decorators/index.js +20 -0
- package/lib/decorators/injectParams.js +57 -0
- package/lib/decorators/params/common.js +16 -0
- package/lib/decorators/params/index.js +29 -0
- package/lib/index.js +17 -0
- package/lib/main.js +20 -0
- package/lib/output.js +7 -0
- package/package.json +103 -0
- package/templates/chatbox-agent/.env.template +2 -0
- package/templates/chatbox-agent/agent-cloudbase-functions.json +11 -0
- package/templates/chatbox-agent/package.json +11 -0
- package/templates/chatbox-agent/project.config.json +5 -0
- package/templates/chatbox-agent/src/index.js +50 -0
- package/templates/weather-agent/index.js +92 -0
- package/templates/weather-agent/project.config.json +4 -0
- package/types/commands/agent/build.d.ts +26 -0
- package/types/commands/agent/dev.d.ts +15 -0
- package/types/commands/agent/index.d.ts +3 -0
- package/types/commands/agent/new.d.ts +16 -0
- package/types/commands/auth/index.d.ts +2 -0
- package/types/commands/auth/login.d.ts +13 -0
- package/types/commands/auth/logout.d.ts +7 -0
- package/types/commands/index.d.ts +2 -0
- package/types/constants/cmd.d.ts +11 -0
- package/types/core/base.d.ts +40 -0
- package/types/decorators/auth.d.ts +1 -0
- package/types/decorators/captureError.d.ts +1 -0
- package/types/decorators/constants.d.ts +11 -0
- package/types/decorators/index.d.ts +4 -0
- package/types/decorators/injectParams.d.ts +1 -0
- package/types/decorators/params/common.d.ts +4 -0
- package/types/decorators/params/index.d.ts +8 -0
- package/types/index.d.ts +1 -0
- package/types/main.d.ts +3 -0
- package/types/output.d.ts +3 -0
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# xhs cloud 命令行工具
|
|
2
|
+
xhs-cloud-cli 主要用于如下场景:
|
|
3
|
+
- agent 调试、发布
|
|
4
|
+
- cloud 云函数的调试、部署
|
|
5
|
+
|
|
6
|
+
使用方式:
|
|
7
|
+
- xhs-cloud-cli agent dev
|
|
8
|
+
|
|
9
|
+
- xhs-cloud-cli cloud dev
|
|
10
|
+
|
|
11
|
+
## 安装 CloudBase CLI
|
|
12
|
+
|
|
13
|
+
src/
|
|
14
|
+
├── commands/
|
|
15
|
+
│ └── agent/
|
|
16
|
+
│ └── dev.ts # agent dev 命令实现
|
|
17
|
+
├── core/
|
|
18
|
+
│ └── server/
|
|
19
|
+
│ ├── server.node.ts # Koa 服务器实现
|
|
20
|
+
│ └── function-loader.ts # 函数加载器实现
|
|
21
|
+
|
|
22
|
+
### npm
|
|
23
|
+
|
|
24
|
+
```shell
|
|
25
|
+
npm install -g @cloudbase/cli
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## 命令
|
|
29
|
+
> xhs-cloud-cli
|
|
30
|
+
|
|
31
|
+
## 命令
|
|
32
|
+
- deploy
|
|
33
|
+
- dev
|
|
34
|
+
|
package/bin/rcb.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const yargsParser = require("yargs-parser");
|
|
3
|
+
const chalk = require("chalk");
|
|
4
|
+
const { program } = require("commander");
|
|
5
|
+
const logSymbols = require("log-symbols");
|
|
6
|
+
const didYouMean = require("didyoumean");
|
|
7
|
+
const updateNotifier = require("update-notifier");
|
|
8
|
+
const { Confirm } = require("enquirer");
|
|
9
|
+
const execa = require("execa");
|
|
10
|
+
const semver = require("semver");
|
|
11
|
+
const { registerCommands, ALL_COMMANDS } = require("../lib");
|
|
12
|
+
|
|
13
|
+
const pkg = require("../package.json");
|
|
14
|
+
|
|
15
|
+
async function main() {
|
|
16
|
+
let processArgv = process.argv;
|
|
17
|
+
const isBeta = pkg.version.indexOf("-") > -1;
|
|
18
|
+
process.CLI_VERSION = pkg.version;
|
|
19
|
+
|
|
20
|
+
const currentMajorVersion = +semver.major(process.version);
|
|
21
|
+
|
|
22
|
+
// 定义最小版本和推荐版本
|
|
23
|
+
const NODE_MIN_VERSION = 18;
|
|
24
|
+
|
|
25
|
+
// 检查当前版本是否满足最小版本要求
|
|
26
|
+
if (NODE_MIN_VERSION > currentMajorVersion) {
|
|
27
|
+
console.error(
|
|
28
|
+
chalk.bold.red(
|
|
29
|
+
`当前 Node.js 版本为 v${currentMajorVersion}。请升级到至少 v${NODE_MIN_VERSION} 版本。`
|
|
30
|
+
)
|
|
31
|
+
);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// 输出版本信息
|
|
36
|
+
console.log(chalk.gray(`RedCloudBase CLI ${pkg.version}`));
|
|
37
|
+
console.log(`[API Config] Env: ${process.env.AGENT_BUILD_ENV || 'production'}`);
|
|
38
|
+
|
|
39
|
+
const yargsParsedResult = yargsParser(process.argv.slice(2));
|
|
40
|
+
|
|
41
|
+
await registerCommands();
|
|
42
|
+
|
|
43
|
+
// 设置 options 选项
|
|
44
|
+
program.storeOptionsAsProperties(false);
|
|
45
|
+
program.option("-r, --region <region>", "指定环境地域");
|
|
46
|
+
|
|
47
|
+
const isCommandEmpty = yargsParsedResult._.length === 0;
|
|
48
|
+
|
|
49
|
+
// 处理无效命令
|
|
50
|
+
program.action(() => {
|
|
51
|
+
const args = program.args;
|
|
52
|
+
if (!Array.isArray(args) || !args.length) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
const cmd = args.join(" ");
|
|
56
|
+
console.log(chalk.bold.red("Error: ") + `${cmd} 不是有效的命令`);
|
|
57
|
+
didYouMean.threshold = 0.5;
|
|
58
|
+
didYouMean.caseSensitive = false;
|
|
59
|
+
const suggest = didYouMean(cmd, ALL_COMMANDS);
|
|
60
|
+
if (suggest) {
|
|
61
|
+
console.log(chalk.bold(`\n您是不是想使用命令:rcb ${suggest}\n`));
|
|
62
|
+
}
|
|
63
|
+
console.log(`💡使用 ${chalk.bold("rcb -h")} 查看所有命令`);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// 没有使用命令
|
|
67
|
+
if (isCommandEmpty) {
|
|
68
|
+
program.outputHelp();
|
|
69
|
+
// 需要隐藏的选项
|
|
70
|
+
const hideArgs = ["-h", "--help"];
|
|
71
|
+
hideArgs.forEach((arg) => {
|
|
72
|
+
const index = processArgv.indexOf(arg);
|
|
73
|
+
if (index > -1) {
|
|
74
|
+
processArgv.splice(index, 1);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
const { output } = require("../lib/output");
|
|
78
|
+
output.helpInfo();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
try {
|
|
82
|
+
program.parse(processArgv);
|
|
83
|
+
} catch (e) {
|
|
84
|
+
const errMsg = `${logSymbols.error} ${
|
|
85
|
+
e.message || "参数异常,请检查您是否使用了正确的命令!"
|
|
86
|
+
}`;
|
|
87
|
+
console.log(errMsg);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* 处理异常
|
|
92
|
+
*/
|
|
93
|
+
async function errorHandler(err) {
|
|
94
|
+
process.emit("processExit");
|
|
95
|
+
|
|
96
|
+
// 3 空格,兼容中文字符编码长度问题
|
|
97
|
+
if (err && err.message) {
|
|
98
|
+
let errMsg = logSymbols.error + " " + err.message;
|
|
99
|
+
errMsg += err.requestId ? `\n${err.requestId}` : "";
|
|
100
|
+
console.log(errMsg);
|
|
101
|
+
|
|
102
|
+
// 多地域错误提示
|
|
103
|
+
if (errMsg.includes("Environment") && errMsg.includes("not found")) {
|
|
104
|
+
// 检查是否已经指定了 -r 或 --region 参数,如未指定则尝试获取地域信息
|
|
105
|
+
const regionSpecified =
|
|
106
|
+
processArgv.indexOf("-r") !== -1 ||
|
|
107
|
+
processArgv.indexOf("--region") !== -1;
|
|
108
|
+
const region = yargsParsedResult.r || yargsParsedResult.region;
|
|
109
|
+
const multiRegionErrMsg = `\n此环境可能不属于当前账号,或为非${
|
|
110
|
+
regionSupportedMap[region] || "上海"
|
|
111
|
+
}地域环境,如需切换地域请追加参数(例:-r gz),请检查环境归属,参考多地域使用方法:https://docs.cloudbase.net/cli-v1/region.html`;
|
|
112
|
+
if (!regionSpecified) {
|
|
113
|
+
// 从 -e 参数、--envId 参数和配置文件中获取环境 id
|
|
114
|
+
const envId =
|
|
115
|
+
yargsParsedResult.e || yargsParsedResult.envId || config.envId;
|
|
116
|
+
|
|
117
|
+
// 调用 API 接口尝试查询环境信息
|
|
118
|
+
const predictRegion = await tryTellEnvRegion(envId);
|
|
119
|
+
|
|
120
|
+
if (regionSupported.includes(predictRegion)) {
|
|
121
|
+
// 让用户选择是否切换地域
|
|
122
|
+
const prompt = new Confirm({
|
|
123
|
+
type: "confirm",
|
|
124
|
+
name: "confirm",
|
|
125
|
+
message: `该环境可能属于 ${regionSupportedMap[predictRegion]} 地域,是否切换地域并重新执行命令?`,
|
|
126
|
+
initial: "Y",
|
|
127
|
+
});
|
|
128
|
+
const confirm = await prompt.run();
|
|
129
|
+
if (confirm) {
|
|
130
|
+
// 检查原始命令是否已经追加了 -r 参数,如果有则替换,如果没有则追加
|
|
131
|
+
const regionArgIndex = processArgv.indexOf("-r");
|
|
132
|
+
if (regionArgIndex !== -1) {
|
|
133
|
+
processArgv[regionArgIndex + 1] = predictRegion;
|
|
134
|
+
} else {
|
|
135
|
+
processArgv.push("-r", predictRegion);
|
|
136
|
+
}
|
|
137
|
+
// 重新执行命令
|
|
138
|
+
const newArgvStr = processArgv.slice(2).join(" ");
|
|
139
|
+
console.log(
|
|
140
|
+
`\n${chalk.yellow.bold(
|
|
141
|
+
"正在重新执行命令:"
|
|
142
|
+
)} tcb ${newArgvStr}\n`
|
|
143
|
+
);
|
|
144
|
+
await execa("tcb", processArgv.slice(2), {
|
|
145
|
+
stdio: "inherit",
|
|
146
|
+
});
|
|
147
|
+
process.emit("tcbExit");
|
|
148
|
+
process.exit(0);
|
|
149
|
+
} else {
|
|
150
|
+
console.log(chalk.yellow.bold(multiRegionErrMsg));
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
console.log(chalk.yellow.bold(multiRegionErrMsg));
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// 输出详细的错误信息
|
|
160
|
+
if (processArgv.includes("--verbose")) {
|
|
161
|
+
console.log(err);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
process.emit("processError");
|
|
165
|
+
setTimeout(() => {
|
|
166
|
+
process.exit(1);
|
|
167
|
+
}, 1000);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const isTokenExpired = (credential, gap = 120) =>
|
|
171
|
+
credential.accessTokenExpired &&
|
|
172
|
+
Number(credential.accessTokenExpired) < Date.now() + gap * 1000;
|
|
173
|
+
|
|
174
|
+
async function tryTellEnvRegion(envId) {
|
|
175
|
+
// 依次调用不同地域的 API 接口查询环境信息
|
|
176
|
+
const fetchedRegion = await Promise.all(
|
|
177
|
+
regionSupported.map(async (region) => {
|
|
178
|
+
const { EnvList = [] } = await fetchEnvInfoWithRegion(envId, region);
|
|
179
|
+
if (
|
|
180
|
+
EnvList.length !== 0 &&
|
|
181
|
+
EnvList.find((item) => item.EnvId === envId)
|
|
182
|
+
) {
|
|
183
|
+
return res.EnvList[0].Region;
|
|
184
|
+
}
|
|
185
|
+
return "";
|
|
186
|
+
})
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
let predictRegion = "";
|
|
190
|
+
fetchedRegion.forEach((region) => {
|
|
191
|
+
if (region) {
|
|
192
|
+
predictRegion = region;
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
return predictRegion;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 在指定地域调用 API 接口查询环境信息
|
|
199
|
+
async function fetchEnvInfoWithRegion(envId, region) {
|
|
200
|
+
let commonCredential = {};
|
|
201
|
+
const commonOpts = {
|
|
202
|
+
service: "tcb",
|
|
203
|
+
version: "2019-09-24",
|
|
204
|
+
proxy: getProxy(),
|
|
205
|
+
timeout: 15000,
|
|
206
|
+
getCredential: async () => {
|
|
207
|
+
if (commonCredential.secretId && !isTokenExpired(commonCredential)) {
|
|
208
|
+
return commonCredential;
|
|
209
|
+
}
|
|
210
|
+
const credential = await getCredentialWithoutCheck();
|
|
211
|
+
if (!credential) {
|
|
212
|
+
throw new Error("无有效身份信息,请使用 cloudbase login 登录");
|
|
213
|
+
}
|
|
214
|
+
commonCredential = credential;
|
|
215
|
+
return {
|
|
216
|
+
...credential,
|
|
217
|
+
tokenExpired: Number(credential.accessTokenExpired),
|
|
218
|
+
};
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
const apiName = "DescribeEnvs";
|
|
222
|
+
const tcbApi = new CloudApiService({
|
|
223
|
+
...commonOpts,
|
|
224
|
+
region,
|
|
225
|
+
});
|
|
226
|
+
const res = await tcbApi.request(apiName, {
|
|
227
|
+
EnvId: envId,
|
|
228
|
+
});
|
|
229
|
+
return res;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
process.on("uncaughtException", errorHandler);
|
|
233
|
+
process.on("unhandledRejection", errorHandler);
|
|
234
|
+
|
|
235
|
+
// 检查更新
|
|
236
|
+
const ONE_DAY = 86400000;
|
|
237
|
+
// Beta 版 1 个小时检查一次,稳定版 1 天检查一次
|
|
238
|
+
const CheckInterval = isBeta ? 3600000 : ONE_DAY;
|
|
239
|
+
|
|
240
|
+
const notifier = updateNotifier({
|
|
241
|
+
pkg,
|
|
242
|
+
distTag: isBeta ? "beta" : "latest",
|
|
243
|
+
// 检查更新间隔 1 天
|
|
244
|
+
updateCheckInterval: CheckInterval,
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
notifier.notify({
|
|
248
|
+
isGlobal: true,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (require.main === module) {
|
|
253
|
+
try {
|
|
254
|
+
main();
|
|
255
|
+
} catch (error) {
|
|
256
|
+
console.log(error);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
process.on("unhandledRejection", (err) => {
|
|
261
|
+
console.log("unhandledRejection", err);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
exports.main = main;
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
15
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
16
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
17
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
18
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
19
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
20
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
24
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
25
|
+
};
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.AgentDeployCommand = exports.AgentBuildCommand = void 0;
|
|
28
|
+
const fs_1 = __importDefault(require("fs"));
|
|
29
|
+
const path_1 = __importDefault(require("path"));
|
|
30
|
+
const cloud_toolkit_1 = require("@vectorx/cloud-toolkit");
|
|
31
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
32
|
+
const semver_1 = __importDefault(require("semver"));
|
|
33
|
+
const base_1 = require("../../core/base");
|
|
34
|
+
const decorators_1 = require("../../decorators");
|
|
35
|
+
const auth_1 = require("../../decorators/auth");
|
|
36
|
+
let AgentBuildCommand = class AgentBuildCommand extends base_1.Command {
|
|
37
|
+
execute(options, log) {
|
|
38
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
39
|
+
const workDir = options.dir || process.cwd();
|
|
40
|
+
log.info(`工作目录: ${workDir}`);
|
|
41
|
+
try {
|
|
42
|
+
const buildSpinner = log.spinner("构建项目中...");
|
|
43
|
+
const { outputPath, size } = yield (0, cloud_toolkit_1.build)({
|
|
44
|
+
workDir,
|
|
45
|
+
outputDir: options.output ? path_1.default.resolve(options.output) : undefined,
|
|
46
|
+
filename: options.filename,
|
|
47
|
+
upload: options.upload,
|
|
48
|
+
});
|
|
49
|
+
buildSpinner.succeed(chalk_1.default.green(`构建完成: ${outputPath}`));
|
|
50
|
+
log.info(`文件大小: ${(size / 1024 / 1024).toFixed(2)} MB`);
|
|
51
|
+
if (options.upload) {
|
|
52
|
+
log.info(chalk_1.default.green("✅ 部署完成"));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
log.error(`构建失败: ${error.message}`);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
get options() {
|
|
62
|
+
return {
|
|
63
|
+
cmd: "agent",
|
|
64
|
+
childCmd: "build",
|
|
65
|
+
desc: "打包 agent 项目",
|
|
66
|
+
options: [
|
|
67
|
+
{
|
|
68
|
+
flags: "-d, --dir <dir>",
|
|
69
|
+
desc: "指定 agent 项目所在的目录,默认为当前目录",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
flags: "-o, --output <output>",
|
|
73
|
+
desc: "指定构建输出目录,默认为项目目录下的 dist 文件夹",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
flags: "-n, --filename <filename>",
|
|
77
|
+
desc: "指定输出文件名,默认为 agent.zip",
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
flags: "-u, --upload",
|
|
81
|
+
desc: "构建完成后自动部署到云端",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
exports.AgentBuildCommand = AgentBuildCommand;
|
|
88
|
+
__decorate([
|
|
89
|
+
(0, decorators_1.InjectParams)(),
|
|
90
|
+
__param(0, (0, decorators_1.ArgsOptions)()),
|
|
91
|
+
__param(1, (0, decorators_1.Log)()),
|
|
92
|
+
__metadata("design:type", Function),
|
|
93
|
+
__metadata("design:paramtypes", [Object, Function]),
|
|
94
|
+
__metadata("design:returntype", Promise)
|
|
95
|
+
], AgentBuildCommand.prototype, "execute", null);
|
|
96
|
+
exports.AgentBuildCommand = AgentBuildCommand = __decorate([
|
|
97
|
+
(0, auth_1.AuthGuard)(),
|
|
98
|
+
(0, base_1.ICommand)()
|
|
99
|
+
], AgentBuildCommand);
|
|
100
|
+
let AgentDeployCommand = class AgentDeployCommand extends base_1.Command {
|
|
101
|
+
execute(options, log) {
|
|
102
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
103
|
+
const targetPath = options.targetPath;
|
|
104
|
+
const projectConfig = (options === null || options === void 0 ? void 0 : options.projectConfig) || path_1.default.resolve(process.cwd(), "project.config.json");
|
|
105
|
+
if (!fs_1.default.existsSync(projectConfig)) {
|
|
106
|
+
log.error(`项目配置文件不存在: ${projectConfig}`);
|
|
107
|
+
log.breakLine();
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
if (!targetPath) {
|
|
111
|
+
log.error(`请指定部署文件路径`);
|
|
112
|
+
log.breakLine();
|
|
113
|
+
console.log(chalk_1.default.gray("💡 可能的解决方案:"));
|
|
114
|
+
console.log(chalk_1.default.gray(" • 请检查文件路径是否正确"));
|
|
115
|
+
console.log(chalk_1.default.gray(" • 请确保文件存在"));
|
|
116
|
+
console.log(chalk_1.default.gray(" • 使用示例 rcb agent deploy -t ./dist/agent.zip"));
|
|
117
|
+
log.breakLine();
|
|
118
|
+
process.exit(1);
|
|
119
|
+
}
|
|
120
|
+
if (!fs_1.default.existsSync(targetPath)) {
|
|
121
|
+
log.error(`文件不存在: ${targetPath}`);
|
|
122
|
+
log.breakLine();
|
|
123
|
+
console.log(chalk_1.default.gray("💡 可能的解决方案:"));
|
|
124
|
+
console.log(chalk_1.default.gray(" • 请检查文件路径是否正确"));
|
|
125
|
+
console.log(chalk_1.default.gray(" • 请确保文件存在"));
|
|
126
|
+
console.log(chalk_1.default.gray(" • 使用示例 rcb agent build -d ./ -o ./dist"));
|
|
127
|
+
log.breakLine();
|
|
128
|
+
process.exit(1);
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
const projectInfo = JSON.parse(fs_1.default.readFileSync(projectConfig, "utf-8"));
|
|
132
|
+
if (!projectInfo.agentId || !projectInfo.version || !projectInfo.desc) {
|
|
133
|
+
log.error(`项目配置文件中缺少必要字段: ${projectConfig}`);
|
|
134
|
+
log.breakLine();
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
if (!projectInfo.version || !projectInfo.agentId) {
|
|
138
|
+
log.error(`项目配置文件中缺少必要字段: ${projectConfig}`);
|
|
139
|
+
log.breakLine();
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
if (!semver_1.default.valid(projectInfo.version)) {
|
|
143
|
+
log.error(`项目配置文件中 version 字段不符合 semver 规范: ${projectConfig}`);
|
|
144
|
+
log.breakLine();
|
|
145
|
+
process.exit(1);
|
|
146
|
+
}
|
|
147
|
+
const uploadService = cloud_toolkit_1.container.get(cloud_toolkit_1.SERVICE_IDENTIFIERS.UploadService);
|
|
148
|
+
try {
|
|
149
|
+
const buildPreCheckResult = yield uploadService.buildPreCheck({
|
|
150
|
+
agent_id: projectInfo.agentId,
|
|
151
|
+
version: projectInfo.version,
|
|
152
|
+
desc: projectInfo.desc || `Agent 发布:${projectInfo.version}`,
|
|
153
|
+
});
|
|
154
|
+
if (!buildPreCheckResult.success) {
|
|
155
|
+
log.error(`部署上传预检失败:${buildPreCheckResult.msg}`);
|
|
156
|
+
log.breakLine();
|
|
157
|
+
process.exit(1);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
log.error(`部署预检异常 ${error.message}`);
|
|
162
|
+
log.breakLine();
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
const deploySpinner = require("ora")("开始部署 agent 项目...");
|
|
166
|
+
const result = yield uploadService.deploy({
|
|
167
|
+
targetPath,
|
|
168
|
+
agentId: projectInfo.agentId,
|
|
169
|
+
version: projectInfo.version,
|
|
170
|
+
desc: projectInfo.desc,
|
|
171
|
+
});
|
|
172
|
+
if (result.success && result.code === 0) {
|
|
173
|
+
log.breakLine();
|
|
174
|
+
deploySpinner.succeed(chalk_1.default.green(`部署完成 ✅`));
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
throw new Error(result.msg);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (e) {
|
|
181
|
+
log.error(`部署失败: ${e.message}`);
|
|
182
|
+
log.breakLine();
|
|
183
|
+
console.log(chalk_1.default.gray("💡 可能的解决方案:"));
|
|
184
|
+
console.log(chalk_1.default.gray(" • 请检查文件路径是否正确"));
|
|
185
|
+
console.log(chalk_1.default.gray(" • 请确保文件存在"));
|
|
186
|
+
console.log(chalk_1.default.gray(" • 使用示例 rcb agent build -d ./ -o ./dist"));
|
|
187
|
+
log.breakLine();
|
|
188
|
+
process.exit(1);
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
get options() {
|
|
193
|
+
return {
|
|
194
|
+
cmd: "agent",
|
|
195
|
+
childCmd: "deploy",
|
|
196
|
+
desc: "部署 agent 项目",
|
|
197
|
+
options: [
|
|
198
|
+
{
|
|
199
|
+
flags: "-t, --targetPath <targetPath>",
|
|
200
|
+
desc: "指定 agent 产物文件所在的目录(不指定则默认读取当前目录)",
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
flags: "-c, --projectConfig <projectConfig>",
|
|
204
|
+
desc: "指定 agent project.config.json项目配置文件(不指定则默认读取当前目录)",
|
|
205
|
+
},
|
|
206
|
+
],
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
};
|
|
210
|
+
exports.AgentDeployCommand = AgentDeployCommand;
|
|
211
|
+
__decorate([
|
|
212
|
+
(0, decorators_1.InjectParams)(),
|
|
213
|
+
__param(0, (0, decorators_1.ArgsOptions)()),
|
|
214
|
+
__param(1, (0, decorators_1.Log)()),
|
|
215
|
+
__metadata("design:type", Function),
|
|
216
|
+
__metadata("design:paramtypes", [Object, Function]),
|
|
217
|
+
__metadata("design:returntype", Promise)
|
|
218
|
+
], AgentDeployCommand.prototype, "execute", null);
|
|
219
|
+
exports.AgentDeployCommand = AgentDeployCommand = __decorate([
|
|
220
|
+
(0, base_1.ICommand)(),
|
|
221
|
+
(0, auth_1.AuthGuard)()
|
|
222
|
+
], AgentDeployCommand);
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
15
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
16
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
17
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
18
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
19
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
20
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
24
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
25
|
+
};
|
|
26
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
27
|
+
exports.AgentDevCommand = void 0;
|
|
28
|
+
const fs_1 = __importDefault(require("fs"));
|
|
29
|
+
const cloud_toolkit_1 = require("@vectorx/cloud-toolkit");
|
|
30
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
31
|
+
const base_1 = require("../../core/base");
|
|
32
|
+
const decorators_1 = require("../../decorators");
|
|
33
|
+
const prefix = chalk_1.default.bgGreenBright(" 🚀 [rcb-ff log] ");
|
|
34
|
+
let AgentDevCommand = class AgentDevCommand extends base_1.Command {
|
|
35
|
+
execute(options, log) {
|
|
36
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const workDir = options.dir || process.cwd();
|
|
38
|
+
if (!fs_1.default.existsSync(workDir)) {
|
|
39
|
+
throw new Error(`目录不存在: ${workDir}`);
|
|
40
|
+
}
|
|
41
|
+
try {
|
|
42
|
+
const { simulatorPort } = yield (0, cloud_toolkit_1.startDev)({
|
|
43
|
+
workDir,
|
|
44
|
+
port: options.port ? Number.parseInt(options.port) : undefined,
|
|
45
|
+
simulatorPort: options.simulatorport ? Number.parseInt(options.simulatorport) : undefined,
|
|
46
|
+
watch: options.watch,
|
|
47
|
+
open: false,
|
|
48
|
+
});
|
|
49
|
+
if (options.open) {
|
|
50
|
+
log.info(`${prefix} 正在打开浏览器访问 localhost:${simulatorPort}`);
|
|
51
|
+
(0, cloud_toolkit_1.openBrowser)("localhost", simulatorPort);
|
|
52
|
+
}
|
|
53
|
+
log.info(`${prefix} ${chalk_1.default.greenBright("开发环境启动完成!")}`);
|
|
54
|
+
this.setupProcessCleanup(log);
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
log.error(`${prefix} 启动开发环境失败: ${error.message}`);
|
|
58
|
+
throw error;
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
setupProcessCleanup(log) {
|
|
63
|
+
const cleanupHandler = () => {
|
|
64
|
+
log.info(`${prefix} 正在关闭服务...`);
|
|
65
|
+
(0, cloud_toolkit_1.cleanup)();
|
|
66
|
+
process.exit(0);
|
|
67
|
+
};
|
|
68
|
+
process.on("SIGINT", cleanupHandler);
|
|
69
|
+
process.on("SIGTERM", cleanupHandler);
|
|
70
|
+
}
|
|
71
|
+
get options() {
|
|
72
|
+
return {
|
|
73
|
+
cmd: "agent",
|
|
74
|
+
childCmd: "dev",
|
|
75
|
+
desc: "启动 agent 开发服务器",
|
|
76
|
+
options: [
|
|
77
|
+
{
|
|
78
|
+
flags: "-d, --dir <dir>",
|
|
79
|
+
desc: "指定服务调试的目录,默认为当前目录",
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
flags: "-o, --open",
|
|
83
|
+
desc: "自动打开浏览器访问模拟器",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
flags: "-p, --port <port>",
|
|
87
|
+
desc: "指定 Agent Server 端口,默认自动分配",
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
flags: "-sp, --simulatorport <port>",
|
|
91
|
+
desc: "指定 Agent 模拟器端口,默认自动分配",
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
flags: "-w, --watch",
|
|
95
|
+
desc: "启用文件监听模式,文件变化时自动重启服务",
|
|
96
|
+
},
|
|
97
|
+
],
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
exports.AgentDevCommand = AgentDevCommand;
|
|
102
|
+
__decorate([
|
|
103
|
+
(0, decorators_1.InjectParams)(),
|
|
104
|
+
__param(0, (0, decorators_1.ArgsOptions)()),
|
|
105
|
+
__param(1, (0, decorators_1.Log)()),
|
|
106
|
+
__metadata("design:type", Function),
|
|
107
|
+
__metadata("design:paramtypes", [Object, Function]),
|
|
108
|
+
__metadata("design:returntype", Promise)
|
|
109
|
+
], AgentDevCommand.prototype, "execute", null);
|
|
110
|
+
exports.AgentDevCommand = AgentDevCommand = __decorate([
|
|
111
|
+
(0, base_1.ICommand)()
|
|
112
|
+
], AgentDevCommand);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./dev"), exports);
|
|
18
|
+
__exportStar(require("./build"), exports);
|
|
19
|
+
__exportStar(require("./new"), exports);
|