@cloudbase/manager-node 4.3.1 → 4.3.3
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/lib/agent/index.js +70 -0
- package/lib/agent/type.js +2 -0
- package/lib/cloudrun/index.js +184 -4
- package/lib/environment.js +5 -0
- package/lib/index.js +3 -0
- package/lib/utils/index.js +70 -19
- package/package.json +1 -1
- package/types/agent/index.d.ts +20 -0
- package/types/agent/type.d.ts +22 -0
- package/types/cloudrun/index.d.ts +34 -1
- package/types/environment.d.ts +3 -0
- package/types/index.d.ts +2 -0
- package/types/utils/index.d.ts +24 -2
|
@@ -0,0 +1,70 @@
|
|
|
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 __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.AgentService = void 0;
|
|
13
|
+
const cloudrun_1 = require("../cloudrun");
|
|
14
|
+
const utils_1 = require("../utils");
|
|
15
|
+
const path_1 = __importDefault(require("path"));
|
|
16
|
+
/**
|
|
17
|
+
* Agent 管理类
|
|
18
|
+
*/
|
|
19
|
+
class AgentService {
|
|
20
|
+
constructor(environment) {
|
|
21
|
+
this.environment = environment;
|
|
22
|
+
this.tcbService = new utils_1.CloudService(environment.cloudBaseContext, 'tcb', '2018-06-08');
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 创建函数型 Agent
|
|
26
|
+
* @param {string} [cwd=process.cwd()] 工作目录
|
|
27
|
+
* @param {ICreateFunctionAgentParams} agentInfo Agent 信息
|
|
28
|
+
* @returns {Promise<{ BotId: string; RequestId: string }>} Agent 创建结果
|
|
29
|
+
*/
|
|
30
|
+
async createFunctionAgent(cwd = process.cwd(), agentInfo) {
|
|
31
|
+
const { BotId } = agentInfo;
|
|
32
|
+
const targetPath = path_1.default.join(cwd);
|
|
33
|
+
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
34
|
+
/**
|
|
35
|
+
* 判断 params.IbotId 的数据格式是否为 ibot-xxx-xxx 的格式
|
|
36
|
+
*/
|
|
37
|
+
if (!/^ibot-[a-z0-9_]+-[a-z0-9_]+$/.test(BotId)) {
|
|
38
|
+
throw new Error('BotId格式应为"ibot-xxx-xxx",其中 xxx 仅支持小写字母、数字或下划线');
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 获取函数型云托管服务的名称:ibot-xxx-xxx 中的 ibot-xxx
|
|
42
|
+
*/
|
|
43
|
+
const serverName = BotId.split('-').slice(0, 2).join('-');
|
|
44
|
+
/**
|
|
45
|
+
* 获取部署包上传信息
|
|
46
|
+
*/
|
|
47
|
+
const { UploadUrl: uploadUrl, UploadHeaders: uploadHeaders, PackageName: packageName, PackageVersion: packageVersion } = await this.tcbService.request('DescribeCloudBaseBuildService', {
|
|
48
|
+
EnvId: envConfig.EnvId,
|
|
49
|
+
ServiceName: serverName
|
|
50
|
+
});
|
|
51
|
+
/**
|
|
52
|
+
* 上传部署包
|
|
53
|
+
*/
|
|
54
|
+
const zipFile = await (0, cloudrun_1.codeToZip)(targetPath, { installDependency: true });
|
|
55
|
+
await (0, utils_1.upload)({
|
|
56
|
+
url: uploadUrl,
|
|
57
|
+
file: zipFile,
|
|
58
|
+
headers: (uploadHeaders || []).reduce((map, item) => {
|
|
59
|
+
map[item.Key] = item.Value;
|
|
60
|
+
return map;
|
|
61
|
+
}, {}) || {},
|
|
62
|
+
method: 'PUT'
|
|
63
|
+
});
|
|
64
|
+
return this.tcbService.request('CreateBot', Object.assign(Object.assign({}, agentInfo), { EnvId: envConfig.EnvId, PackageName: packageName, PackageVersion: packageVersion }));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
exports.AgentService = AgentService;
|
|
68
|
+
__decorate([
|
|
69
|
+
(0, utils_1.preLazy)()
|
|
70
|
+
], AgentService.prototype, "createFunctionAgent", null);
|
package/lib/cloudrun/index.js
CHANGED
|
@@ -10,6 +10,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.CloudRunService = void 0;
|
|
13
|
+
exports.codeToZip = codeToZip;
|
|
14
|
+
const archiver_1 = __importDefault(require("archiver"));
|
|
15
|
+
const fs_extra_1 = require("fs-extra");
|
|
13
16
|
const path_1 = __importDefault(require("path"));
|
|
14
17
|
const utils_1 = require("../utils");
|
|
15
18
|
/**
|
|
@@ -63,10 +66,7 @@ class CloudRunService {
|
|
|
63
66
|
/**
|
|
64
67
|
* 获取最新版本
|
|
65
68
|
*/
|
|
66
|
-
const cloudRunServerDetailRes = await this.
|
|
67
|
-
EnvId: envConfig.EnvId,
|
|
68
|
-
ServerName: serverName
|
|
69
|
-
});
|
|
69
|
+
const cloudRunServerDetailRes = await this.detail({ serverName });
|
|
70
70
|
const version = (_b = (_a = cloudRunServerDetailRes.OnlineVersionInfos) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.VersionName;
|
|
71
71
|
if (!version) {
|
|
72
72
|
throw new Error('未找到云托管服务版本');
|
|
@@ -131,6 +131,107 @@ class CloudRunService {
|
|
|
131
131
|
ServerName: params.serverName // 要删除的服务名称
|
|
132
132
|
});
|
|
133
133
|
}
|
|
134
|
+
/**
|
|
135
|
+
* 本地代码部署云托管服务
|
|
136
|
+
* @param {Object} params 部署参数
|
|
137
|
+
* @param {string} params.serverName 要部署的服务名称
|
|
138
|
+
* @param {string} params.targetPath 本地代码路径
|
|
139
|
+
* @param {Object} [params.serverConfig] 服务配置项(可选)
|
|
140
|
+
* @param {string[]} [params.serverConfig.OpenAccessTypes] 开放访问类型
|
|
141
|
+
* @param {number} [params.serverConfig.Cpu] CPU规格
|
|
142
|
+
* @param {number} [params.serverConfig.Mem] 内存规格
|
|
143
|
+
* @param {number} [params.serverConfig.MinNum] 最小实例数
|
|
144
|
+
* @param {number} [params.serverConfig.MaxNum] 最大实例数
|
|
145
|
+
* @param {Object} [params.serverConfig.PolicyDetails] 策略详情
|
|
146
|
+
* @param {Object} [params.serverConfig.CustomLogs] 自定义日志配置
|
|
147
|
+
* @param {Object} [params.serverConfig.EnvParams] 环境变量参数
|
|
148
|
+
* @param {number} [params.serverConfig.Port] 端口(函数型服务不允许设置)
|
|
149
|
+
* @param {string} [params.serverConfig.Dockerfile] Dockerfile路径
|
|
150
|
+
* @param {string} [params.serverConfig.BuildDir] 构建目录
|
|
151
|
+
* @param {boolean} [params.serverConfig.InternalAccess] 是否开启内网访问
|
|
152
|
+
* @param {string} [params.serverConfig.InternalDomain] 内网域名
|
|
153
|
+
* @param {string} [params.serverConfig.EntryPoint] 入口文件
|
|
154
|
+
* @param {string} [params.serverConfig.Cmd] 启动命令
|
|
155
|
+
* @returns {Promise<IResponseInfo>} 返回部署操作的响应信息
|
|
156
|
+
*/
|
|
157
|
+
async deploy(params) {
|
|
158
|
+
const { serverName, targetPath = process.cwd(), serverConfig } = params;
|
|
159
|
+
/**
|
|
160
|
+
* 参数校验和默认值设置
|
|
161
|
+
*/
|
|
162
|
+
if (!serverName) {
|
|
163
|
+
throw new Error('Missing required parameters: serviceName');
|
|
164
|
+
}
|
|
165
|
+
// 获取当前环境配置(包含EnvId)
|
|
166
|
+
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
167
|
+
/**
|
|
168
|
+
* 获取部署包上传信息
|
|
169
|
+
*/
|
|
170
|
+
const { UploadUrl: uploadUrl, UploadHeaders: uploadHeaders, PackageName: packageName, PackageVersion: packageVersion } = await this.tcbService.request('DescribeCloudBaseBuildService', {
|
|
171
|
+
EnvId: envConfig.EnvId,
|
|
172
|
+
ServiceName: serverName
|
|
173
|
+
});
|
|
174
|
+
const deployInfo = {
|
|
175
|
+
DeployType: 'package',
|
|
176
|
+
PackageName: packageName,
|
|
177
|
+
PackageVersion: packageVersion
|
|
178
|
+
};
|
|
179
|
+
/**
|
|
180
|
+
* 上传部署包
|
|
181
|
+
*/
|
|
182
|
+
const zipFile = await codeToZip(targetPath, { installDependency: true });
|
|
183
|
+
await (0, utils_1.upload)({
|
|
184
|
+
url: uploadUrl,
|
|
185
|
+
file: zipFile,
|
|
186
|
+
headers: (uploadHeaders || []).reduce((map, item) => {
|
|
187
|
+
map[item.Key] = item.Value;
|
|
188
|
+
return map;
|
|
189
|
+
}, {}) || {},
|
|
190
|
+
method: 'PUT'
|
|
191
|
+
});
|
|
192
|
+
/**
|
|
193
|
+
* 执行部署
|
|
194
|
+
*/
|
|
195
|
+
if (await this._checkFunctionExist(serverName)) {
|
|
196
|
+
// 更新
|
|
197
|
+
const serverDetail = await this.detail({ serverName });
|
|
198
|
+
const _serverConfig = Object.assign(Object.assign(Object.assign({}, ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig) || {})), serverConfig), ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:' ? { Port: 3000 } : {}) // 函数型不能指定端口,需要固定为3000
|
|
199
|
+
);
|
|
200
|
+
deployInfo.ReleaseType = 'FULL';
|
|
201
|
+
return this._upsertFunction(false, {
|
|
202
|
+
name: serverName,
|
|
203
|
+
deployInfo,
|
|
204
|
+
serverConfig: _serverConfig
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
// 创建
|
|
209
|
+
/**
|
|
210
|
+
* 判断是容器器还是函数型
|
|
211
|
+
*/
|
|
212
|
+
let type = 'function';
|
|
213
|
+
if (serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.Dockerfile) {
|
|
214
|
+
type = 'container';
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
if (await (0, fs_extra_1.pathExists)(path_1.default.join(targetPath, 'Dockerfile'))) {
|
|
218
|
+
type = 'container';
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if (type === 'function') {
|
|
222
|
+
deployInfo.BuildPacks = {
|
|
223
|
+
LanguageVersion: '20.18',
|
|
224
|
+
RepoLanguage: 'Node.js'
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC'], Cpu: 0, Mem: 0, MinNum: 0, MaxNum: 0, PolicyDetails: [], EnvParams: JSON.stringify({}), InitialDelaySeconds: 0, CustomLogs: '', HasDockerfile: true, CreateTime: '', EnvId: envConfig.EnvId, ServerName: serverName, Port: type === 'container' ? 80 : 3000, Dockerfile: 'Dockerfile', BuildDir: '' }, serverConfig), (type === 'function' ? { Port: 3000 } : {})), { Tag: type === 'container' ? '' : 'function:' });
|
|
228
|
+
return this._upsertFunction(true, {
|
|
229
|
+
name: serverName,
|
|
230
|
+
deployInfo,
|
|
231
|
+
serverConfig: _serverConfig
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
}
|
|
134
235
|
/**
|
|
135
236
|
* 获取云托管服务模板列表
|
|
136
237
|
* @returns {Promise<ITemplate[]>} 返回模板数组
|
|
@@ -138,6 +239,32 @@ class CloudRunService {
|
|
|
138
239
|
async getTemplates() {
|
|
139
240
|
return (0, utils_1.fetchTemplates)(['tcbrFunc', 'tcbrContainer']);
|
|
140
241
|
}
|
|
242
|
+
async _checkFunctionExist(name) {
|
|
243
|
+
try {
|
|
244
|
+
await this.detail({
|
|
245
|
+
serverName: name
|
|
246
|
+
});
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
catch (e) {
|
|
250
|
+
if (e.code === 'ResourceNotFound' ||
|
|
251
|
+
// 备注:以下条件当 NotFound 处理(已与 fisheryan 确认过)
|
|
252
|
+
(e.code === 'InvalidParameter' && e.original.Message === 'service data illegal')) {
|
|
253
|
+
return false;
|
|
254
|
+
}
|
|
255
|
+
throw e;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
_upsertFunction(isNew, data) {
|
|
259
|
+
const { name, deployInfo, serverConfig } = data;
|
|
260
|
+
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
261
|
+
return this.tcbrService.request(isNew ? 'CreateCloudRunServer' : 'UpdateCloudRunServer', {
|
|
262
|
+
EnvId: envConfig.EnvId,
|
|
263
|
+
ServerName: name,
|
|
264
|
+
DeployInfo: deployInfo,
|
|
265
|
+
ServerConfig: serverConfig
|
|
266
|
+
});
|
|
267
|
+
}
|
|
141
268
|
}
|
|
142
269
|
exports.CloudRunService = CloudRunService;
|
|
143
270
|
__decorate([
|
|
@@ -155,3 +282,56 @@ __decorate([
|
|
|
155
282
|
__decorate([
|
|
156
283
|
(0, utils_1.preLazy)()
|
|
157
284
|
], CloudRunService.prototype, "delete", null);
|
|
285
|
+
__decorate([
|
|
286
|
+
(0, utils_1.preLazy)()
|
|
287
|
+
], CloudRunService.prototype, "deploy", null);
|
|
288
|
+
async function codeToZip(cwd, options) {
|
|
289
|
+
const archive = (0, archiver_1.default)('zip', {
|
|
290
|
+
zlib: { level: 1 } // 保持与之前相同的压缩级别
|
|
291
|
+
});
|
|
292
|
+
const chunks = [];
|
|
293
|
+
const bufferPromise = new Promise((resolve, reject) => {
|
|
294
|
+
archive.on('data', (chunk) => {
|
|
295
|
+
chunks.push(chunk);
|
|
296
|
+
});
|
|
297
|
+
archive.on('end', () => {
|
|
298
|
+
resolve(Buffer.concat(chunks));
|
|
299
|
+
});
|
|
300
|
+
archive.on('error', err => {
|
|
301
|
+
reject(err);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
async function addFilesToArchive(dir, root = false, relativePath = '') {
|
|
305
|
+
const entries = await (0, fs_extra_1.readdir)(dir, { withFileTypes: true });
|
|
306
|
+
for (let entry of entries) {
|
|
307
|
+
const fullPath = path_1.default.join(dir, entry.name);
|
|
308
|
+
const entryRelativePath = path_1.default.join(relativePath, entry.name);
|
|
309
|
+
if (entry.isDirectory()) {
|
|
310
|
+
if (['logs', '.git'].includes(entry.name)) {
|
|
311
|
+
// 忽略 logs 等目录
|
|
312
|
+
continue;
|
|
313
|
+
}
|
|
314
|
+
if (options === null || options === void 0 ? void 0 : options.installDependency) {
|
|
315
|
+
// 忽略 node_modules 等目录
|
|
316
|
+
if (['node_modules'].includes(entry.name)) {
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
await addFilesToArchive(fullPath, false, entryRelativePath);
|
|
321
|
+
}
|
|
322
|
+
else {
|
|
323
|
+
if (root) {
|
|
324
|
+
// 可以配置忽略指定文件名的文件
|
|
325
|
+
if ([''].includes(entry.name)) {
|
|
326
|
+
continue;
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
// 保持与之前相同的文件添加方式,包括相对路径处理
|
|
330
|
+
archive.file(fullPath, { name: entryRelativePath });
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
await addFilesToArchive(path_1.default.resolve(cwd), true);
|
|
335
|
+
await archive.finalize();
|
|
336
|
+
return bufferPromise;
|
|
337
|
+
}
|
package/lib/environment.js
CHANGED
|
@@ -4,6 +4,7 @@ exports.Environment = void 0;
|
|
|
4
4
|
const database_1 = require("./database");
|
|
5
5
|
const function_1 = require("./function");
|
|
6
6
|
const cloudrun_1 = require("./cloudrun");
|
|
7
|
+
const agent_1 = require("./agent");
|
|
7
8
|
const storage_1 = require("./storage");
|
|
8
9
|
const env_1 = require("./env");
|
|
9
10
|
const common_1 = require("./common");
|
|
@@ -24,6 +25,7 @@ class Environment {
|
|
|
24
25
|
// 拉取当前环境 的环境信息 todo
|
|
25
26
|
this.functionService = new function_1.FunctionService(this);
|
|
26
27
|
this.cloudRunService = new cloudrun_1.CloudRunService(this);
|
|
28
|
+
this.agentService = new agent_1.AgentService(this);
|
|
27
29
|
this.databaseService = new database_1.DatabaseService(this);
|
|
28
30
|
this.storageService = new storage_1.StorageService(this);
|
|
29
31
|
this.envService = new env_1.EnvService(this);
|
|
@@ -67,6 +69,9 @@ class Environment {
|
|
|
67
69
|
getCloudRunService() {
|
|
68
70
|
return this.cloudRunService;
|
|
69
71
|
}
|
|
72
|
+
getAgentService() {
|
|
73
|
+
return this.agentService;
|
|
74
|
+
}
|
|
70
75
|
getEnvService() {
|
|
71
76
|
return this.envService;
|
|
72
77
|
}
|
package/lib/index.js
CHANGED
|
@@ -49,6 +49,9 @@ class CloudBase {
|
|
|
49
49
|
get cloudrun() {
|
|
50
50
|
return this.currentEnvironment().getCloudRunService();
|
|
51
51
|
}
|
|
52
|
+
get agent() {
|
|
53
|
+
return this.currentEnvironment().getAgentService();
|
|
54
|
+
}
|
|
52
55
|
get storage() {
|
|
53
56
|
return this.currentEnvironment().getStorageService();
|
|
54
57
|
}
|
package/lib/utils/index.js
CHANGED
|
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
20
20
|
exports.guid6 = void 0;
|
|
21
21
|
exports.compressToZip = compressToZip;
|
|
22
22
|
exports.downloadAndExtractRemoteZip = downloadAndExtractRemoteZip;
|
|
23
|
+
exports.upload = upload;
|
|
23
24
|
exports.getRuntime = getRuntime;
|
|
24
25
|
exports.getEnvVar = getEnvVar;
|
|
25
26
|
exports.rsaEncrypt = rsaEncrypt;
|
|
@@ -69,8 +70,8 @@ async function compressToZip(option) {
|
|
|
69
70
|
});
|
|
70
71
|
}
|
|
71
72
|
/**
|
|
72
|
-
*
|
|
73
|
-
* @param {string} downloadUrl
|
|
73
|
+
* 下载并解压压缩包到指定目录
|
|
74
|
+
* @param {string} downloadUrl 压缩包下载地址
|
|
74
75
|
* @param {string} targetPath 目标路径
|
|
75
76
|
* @returns {Promise<void>}
|
|
76
77
|
* @throws 当下载失败或解压失败时抛出错误
|
|
@@ -91,29 +92,79 @@ async function downloadAndExtractRemoteZip(downloadUrl, targetPath) {
|
|
|
91
92
|
let fileCount = 0;
|
|
92
93
|
let extractedCount = 0;
|
|
93
94
|
downloadResponse
|
|
94
|
-
.body.pipe(unzipper_1.default.Parse())
|
|
95
|
+
.body.pipe(unzipper_1.default.Parse())
|
|
95
96
|
.on('error', reject)
|
|
96
|
-
.on('entry', entry => {
|
|
97
|
-
fileCount++;
|
|
97
|
+
.on('entry', async (entry) => {
|
|
98
98
|
const filePath = path_1.default.join(dirPath, entry.path);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
.
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
if (extractedCount === fileCount) {
|
|
107
|
-
resolve('');
|
|
99
|
+
try {
|
|
100
|
+
// 确保父目录存在(处理嵌套目录情况)
|
|
101
|
+
await fs_extra_1.default.ensureDir(path_1.default.dirname(filePath));
|
|
102
|
+
// 如果是目录则创建,否则写入文件
|
|
103
|
+
if (entry.type === 'Directory') {
|
|
104
|
+
await fs_extra_1.default.ensureDir(filePath);
|
|
105
|
+
extractedCount++;
|
|
108
106
|
}
|
|
109
|
-
|
|
107
|
+
else {
|
|
108
|
+
fileCount++;
|
|
109
|
+
entry
|
|
110
|
+
.pipe(fs_extra_1.default.createWriteStream(filePath))
|
|
111
|
+
.on('error', reject)
|
|
112
|
+
.on('finish', () => {
|
|
113
|
+
extractedCount++;
|
|
114
|
+
checkCompletion();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (err) {
|
|
119
|
+
reject(err);
|
|
120
|
+
}
|
|
110
121
|
})
|
|
111
|
-
.on('close',
|
|
112
|
-
|
|
113
|
-
if (fileCount === extractedCount) {
|
|
122
|
+
.on('close', checkCompletion);
|
|
123
|
+
function checkCompletion() {
|
|
124
|
+
if (fileCount > 0 && fileCount === extractedCount) {
|
|
114
125
|
resolve('');
|
|
115
126
|
}
|
|
116
|
-
}
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* 将文件上传到指定 URL 地址
|
|
132
|
+
* @param {Object} options - 上传配置项
|
|
133
|
+
* @param {string} options.url - 目标上传地址
|
|
134
|
+
* @param {File|Blob|Buffer} options.file - 要上传的文件对象
|
|
135
|
+
* @param {string} [options.method='POST'] - HTTP 方法,默认为 POST
|
|
136
|
+
* @param {Object} [options.headers={}] - 自定义请求头
|
|
137
|
+
* @param {boolean} [options.withCredentials=false] - 是否携带跨域凭据
|
|
138
|
+
*/
|
|
139
|
+
function upload({ url, file, method = 'POST', headers = {}, withCredentials = false }) {
|
|
140
|
+
return (0, http_request_1.fetchStream)(url, {
|
|
141
|
+
method,
|
|
142
|
+
headers,
|
|
143
|
+
body: file,
|
|
144
|
+
credentials: withCredentials ? 'include' : 'same-origin'
|
|
145
|
+
})
|
|
146
|
+
.then(async (response) => {
|
|
147
|
+
const text = await response.text();
|
|
148
|
+
const dataMeta = {
|
|
149
|
+
data: null,
|
|
150
|
+
context: {
|
|
151
|
+
response,
|
|
152
|
+
file
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
try {
|
|
156
|
+
dataMeta.data = JSON.parse(text);
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
// If parsing fails, keep data as null
|
|
160
|
+
}
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
throw new Error(`${response.status} ${response.statusText} HTTP ERROR`);
|
|
163
|
+
}
|
|
164
|
+
return dataMeta;
|
|
165
|
+
})
|
|
166
|
+
.catch(error => {
|
|
167
|
+
throw error; // 或者可以在这里进行错误转换
|
|
117
168
|
});
|
|
118
169
|
}
|
|
119
170
|
function getRuntime() {
|
package/package.json
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Environment } from '../environment';
|
|
2
|
+
import { ICreateFunctionAgentParams } from './type';
|
|
3
|
+
/**
|
|
4
|
+
* Agent 管理类
|
|
5
|
+
*/
|
|
6
|
+
export declare class AgentService {
|
|
7
|
+
private environment;
|
|
8
|
+
private tcbService;
|
|
9
|
+
constructor(environment: Environment);
|
|
10
|
+
/**
|
|
11
|
+
* 创建函数型 Agent
|
|
12
|
+
* @param {string} [cwd=process.cwd()] 工作目录
|
|
13
|
+
* @param {ICreateFunctionAgentParams} agentInfo Agent 信息
|
|
14
|
+
* @returns {Promise<{ BotId: string; RequestId: string }>} Agent 创建结果
|
|
15
|
+
*/
|
|
16
|
+
createFunctionAgent(cwd: string, agentInfo: ICreateFunctionAgentParams): Promise<{
|
|
17
|
+
BotId: string;
|
|
18
|
+
RequestId: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface ICreateFunctionAgentParams {
|
|
2
|
+
/**
|
|
3
|
+
* 智能体名称
|
|
4
|
+
* @example "hello"
|
|
5
|
+
*/
|
|
6
|
+
Name: string;
|
|
7
|
+
/**
|
|
8
|
+
* 智能体ID
|
|
9
|
+
* @example "ibot-aaa-bbb"
|
|
10
|
+
*/
|
|
11
|
+
BotId: string;
|
|
12
|
+
/**
|
|
13
|
+
* 智能体简介
|
|
14
|
+
* @example "这是一个智能体"
|
|
15
|
+
*/
|
|
16
|
+
Introduction?: string;
|
|
17
|
+
/**
|
|
18
|
+
* 智能体头像
|
|
19
|
+
* @example "https://picsum.photos/200"
|
|
20
|
+
*/
|
|
21
|
+
Avatar?: string;
|
|
22
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Environment } from '../environment';
|
|
2
2
|
import { IResponseInfo } from '../interfaces';
|
|
3
|
-
import { CloudrunServerType, ICloudrunDetailResponse, ICloudrunListResponse, ITemplate } from './type';
|
|
3
|
+
import { CloudrunServerType, ICloudrunDetailResponse, ICloudrunListResponse, ICloudrunServerBaseConfig, ITemplate } from './type';
|
|
4
4
|
/**
|
|
5
5
|
* 云托管服务管理类
|
|
6
6
|
* 提供云托管服务的初始化、下载、列表查询和删除等功能
|
|
@@ -73,9 +73,42 @@ export declare class CloudRunService {
|
|
|
73
73
|
delete(params: {
|
|
74
74
|
serverName: string;
|
|
75
75
|
}): Promise<IResponseInfo>;
|
|
76
|
+
/**
|
|
77
|
+
* 本地代码部署云托管服务
|
|
78
|
+
* @param {Object} params 部署参数
|
|
79
|
+
* @param {string} params.serverName 要部署的服务名称
|
|
80
|
+
* @param {string} params.targetPath 本地代码路径
|
|
81
|
+
* @param {Object} [params.serverConfig] 服务配置项(可选)
|
|
82
|
+
* @param {string[]} [params.serverConfig.OpenAccessTypes] 开放访问类型
|
|
83
|
+
* @param {number} [params.serverConfig.Cpu] CPU规格
|
|
84
|
+
* @param {number} [params.serverConfig.Mem] 内存规格
|
|
85
|
+
* @param {number} [params.serverConfig.MinNum] 最小实例数
|
|
86
|
+
* @param {number} [params.serverConfig.MaxNum] 最大实例数
|
|
87
|
+
* @param {Object} [params.serverConfig.PolicyDetails] 策略详情
|
|
88
|
+
* @param {Object} [params.serverConfig.CustomLogs] 自定义日志配置
|
|
89
|
+
* @param {Object} [params.serverConfig.EnvParams] 环境变量参数
|
|
90
|
+
* @param {number} [params.serverConfig.Port] 端口(函数型服务不允许设置)
|
|
91
|
+
* @param {string} [params.serverConfig.Dockerfile] Dockerfile路径
|
|
92
|
+
* @param {string} [params.serverConfig.BuildDir] 构建目录
|
|
93
|
+
* @param {boolean} [params.serverConfig.InternalAccess] 是否开启内网访问
|
|
94
|
+
* @param {string} [params.serverConfig.InternalDomain] 内网域名
|
|
95
|
+
* @param {string} [params.serverConfig.EntryPoint] 入口文件
|
|
96
|
+
* @param {string} [params.serverConfig.Cmd] 启动命令
|
|
97
|
+
* @returns {Promise<IResponseInfo>} 返回部署操作的响应信息
|
|
98
|
+
*/
|
|
99
|
+
deploy(params: {
|
|
100
|
+
serverName: string;
|
|
101
|
+
targetPath: string;
|
|
102
|
+
serverConfig?: Partial<Pick<ICloudrunServerBaseConfig, 'OpenAccessTypes' | 'Cpu' | 'Mem' | 'MinNum' | 'MaxNum' | 'PolicyDetails' | 'CustomLogs' | 'EnvParams' | 'Port' | 'Dockerfile' | 'BuildDir' | 'InternalAccess' | 'InternalDomain' | 'EntryPoint' | 'Cmd'>>;
|
|
103
|
+
}): Promise<IResponseInfo>;
|
|
76
104
|
/**
|
|
77
105
|
* 获取云托管服务模板列表
|
|
78
106
|
* @returns {Promise<ITemplate[]>} 返回模板数组
|
|
79
107
|
*/
|
|
80
108
|
getTemplates(): Promise<ITemplate[]>;
|
|
109
|
+
private _checkFunctionExist;
|
|
110
|
+
private _upsertFunction;
|
|
81
111
|
}
|
|
112
|
+
export declare function codeToZip(cwd: string, options?: {
|
|
113
|
+
installDependency?: boolean;
|
|
114
|
+
}): Promise<Buffer>;
|
package/types/environment.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { DatabaseService } from './database';
|
|
2
2
|
import { FunctionService } from './function';
|
|
3
3
|
import { CloudRunService } from './cloudrun';
|
|
4
|
+
import { AgentService } from './agent';
|
|
4
5
|
import { StorageService } from './storage';
|
|
5
6
|
import { EnvService } from './env';
|
|
6
7
|
import { CommonService } from './common';
|
|
@@ -19,6 +20,7 @@ export declare class Environment {
|
|
|
19
20
|
private envType?;
|
|
20
21
|
private functionService;
|
|
21
22
|
private cloudRunService;
|
|
23
|
+
private agentService;
|
|
22
24
|
private databaseService;
|
|
23
25
|
private storageService;
|
|
24
26
|
private envService;
|
|
@@ -35,6 +37,7 @@ export declare class Environment {
|
|
|
35
37
|
getDatabaseService(): DatabaseService;
|
|
36
38
|
getFunctionService(): FunctionService;
|
|
37
39
|
getCloudRunService(): CloudRunService;
|
|
40
|
+
getAgentService(): AgentService;
|
|
38
41
|
getEnvService(): EnvService;
|
|
39
42
|
getHostingService(): HostingService;
|
|
40
43
|
getThirdService(): ThirdService;
|
package/types/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { EnvService } from './env';
|
|
2
2
|
import { FunctionService } from './function';
|
|
3
3
|
import { CloudRunService } from './cloudrun';
|
|
4
|
+
import { AgentService } from './agent';
|
|
4
5
|
import { StorageService } from './storage';
|
|
5
6
|
import { DatabaseService } from './database';
|
|
6
7
|
import { CommonService } from './common';
|
|
@@ -39,6 +40,7 @@ declare class CloudBase {
|
|
|
39
40
|
currentEnvironment(): Environment;
|
|
40
41
|
get functions(): FunctionService;
|
|
41
42
|
get cloudrun(): CloudRunService;
|
|
43
|
+
get agent(): AgentService;
|
|
42
44
|
get storage(): StorageService;
|
|
43
45
|
get database(): DatabaseService;
|
|
44
46
|
get hosting(): HostingService;
|
package/types/utils/index.d.ts
CHANGED
|
@@ -14,13 +14,35 @@ interface IZipOption {
|
|
|
14
14
|
}
|
|
15
15
|
export declare function compressToZip(option: IZipOption): Promise<unknown>;
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
* @param {string} downloadUrl
|
|
17
|
+
* 下载并解压压缩包到指定目录
|
|
18
|
+
* @param {string} downloadUrl 压缩包下载地址
|
|
19
19
|
* @param {string} targetPath 目标路径
|
|
20
20
|
* @returns {Promise<void>}
|
|
21
21
|
* @throws 当下载失败或解压失败时抛出错误
|
|
22
22
|
*/
|
|
23
23
|
export declare function downloadAndExtractRemoteZip(downloadUrl: string, targetPath: string): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* 将文件上传到指定 URL 地址
|
|
26
|
+
* @param {Object} options - 上传配置项
|
|
27
|
+
* @param {string} options.url - 目标上传地址
|
|
28
|
+
* @param {File|Blob|Buffer} options.file - 要上传的文件对象
|
|
29
|
+
* @param {string} [options.method='POST'] - HTTP 方法,默认为 POST
|
|
30
|
+
* @param {Object} [options.headers={}] - 自定义请求头
|
|
31
|
+
* @param {boolean} [options.withCredentials=false] - 是否携带跨域凭据
|
|
32
|
+
*/
|
|
33
|
+
export declare function upload({ url, file, method, headers, withCredentials }: {
|
|
34
|
+
url: string;
|
|
35
|
+
file: File | Blob | Buffer;
|
|
36
|
+
method?: string;
|
|
37
|
+
headers?: Record<string, any>;
|
|
38
|
+
withCredentials?: boolean;
|
|
39
|
+
}): Promise<{
|
|
40
|
+
data: any;
|
|
41
|
+
context: {
|
|
42
|
+
response: import("node-fetch").Response;
|
|
43
|
+
file: Buffer | File | Blob;
|
|
44
|
+
};
|
|
45
|
+
}>;
|
|
24
46
|
export declare function getRuntime(): string;
|
|
25
47
|
export declare function getEnvVar(envName: string): string;
|
|
26
48
|
export declare function rsaEncrypt(data: string): string;
|