@cloudbase/cloudbase-mcp 2.1.0 → 2.2.0-alpha.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/dist/cli.cjs +574 -177
- package/dist/index.cjs +574 -177
- package/dist/index.js +156 -141
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -102,6 +102,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
102
102
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
103
103
|
exports.CloudRunService = void 0;
|
|
104
104
|
exports.codeToZip = codeToZip;
|
|
105
|
+
exports.parseObjectToDiffConfigItem = parseObjectToDiffConfigItem;
|
|
105
106
|
const archiver_1 = __importDefault(__webpack_require__(99133));
|
|
106
107
|
const fs_extra_1 = __webpack_require__(21605);
|
|
107
108
|
const path_1 = __importDefault(__webpack_require__(39902));
|
|
@@ -270,7 +271,7 @@ class CloudRunService {
|
|
|
270
271
|
/**
|
|
271
272
|
* 上传部署包
|
|
272
273
|
*/
|
|
273
|
-
const zipFile = await codeToZip(targetPath, { installDependency: true });
|
|
274
|
+
const zipFile = await codeToZip(targetPath, { installDependency: (serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.InstallDependency) !== undefined ? serverConfig.InstallDependency : true });
|
|
274
275
|
await (0, utils_1.upload)({
|
|
275
276
|
url: uploadUrl,
|
|
276
277
|
file: zipFile,
|
|
@@ -286,8 +287,14 @@ class CloudRunService {
|
|
|
286
287
|
if (await this._checkFunctionExist(serverName)) {
|
|
287
288
|
// 更新
|
|
288
289
|
const serverDetail = await this.detail({ serverName });
|
|
289
|
-
const _serverConfig = Object.assign(Object.assign(Object.assign({},
|
|
290
|
+
const _serverConfig = Object.assign(Object.assign(Object.assign({}, serverConfig), { OpenAccessTypes: ['OA', 'PUBLIC', 'MINIAPP'] }), ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:' ? { Port: 3000 } : {}) // 函数型不能指定端口,需要固定为3000
|
|
290
291
|
);
|
|
292
|
+
if ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:') {
|
|
293
|
+
deployInfo.BuildPacks = {
|
|
294
|
+
LanguageVersion: '20.18',
|
|
295
|
+
RepoLanguage: 'Node.js'
|
|
296
|
+
};
|
|
297
|
+
}
|
|
291
298
|
deployInfo.ReleaseType = 'FULL';
|
|
292
299
|
return this._upsertFunction(false, {
|
|
293
300
|
name: serverName,
|
|
@@ -315,7 +322,13 @@ class CloudRunService {
|
|
|
315
322
|
RepoLanguage: 'Node.js'
|
|
316
323
|
};
|
|
317
324
|
}
|
|
318
|
-
const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC'
|
|
325
|
+
const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC', 'MINIAPP'],
|
|
326
|
+
// Cpu: 0,
|
|
327
|
+
// Mem: 0,
|
|
328
|
+
MinNum: 0,
|
|
329
|
+
// MaxNum: 0,
|
|
330
|
+
// PolicyDetails: [],
|
|
331
|
+
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:' });
|
|
319
332
|
return this._upsertFunction(true, {
|
|
320
333
|
name: serverName,
|
|
321
334
|
deployInfo,
|
|
@@ -349,11 +362,12 @@ class CloudRunService {
|
|
|
349
362
|
_upsertFunction(isNew, data) {
|
|
350
363
|
const { name, deployInfo, serverConfig } = data;
|
|
351
364
|
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
365
|
+
const Items = parseObjectToDiffConfigItem(serverConfig);
|
|
352
366
|
return this.tcbrService.request(isNew ? 'CreateCloudRunServer' : 'UpdateCloudRunServer', {
|
|
353
367
|
EnvId: envConfig.EnvId,
|
|
354
368
|
ServerName: name,
|
|
355
369
|
DeployInfo: deployInfo,
|
|
356
|
-
|
|
370
|
+
Items,
|
|
357
371
|
});
|
|
358
372
|
}
|
|
359
373
|
}
|
|
@@ -426,6 +440,63 @@ async function codeToZip(cwd, options) {
|
|
|
426
440
|
await archive.finalize();
|
|
427
441
|
return bufferPromise;
|
|
428
442
|
}
|
|
443
|
+
/**
|
|
444
|
+
* 提交参数变化映射
|
|
445
|
+
*/
|
|
446
|
+
const SUBMIT_DIFF_MAP = {
|
|
447
|
+
Cpu: 'CpuSpecs',
|
|
448
|
+
Mem: 'MemSpecs',
|
|
449
|
+
OpenAccessTypes: 'AccessTypes',
|
|
450
|
+
EnvParams: 'EnvParam',
|
|
451
|
+
CustomLogs: 'LogPath'
|
|
452
|
+
};
|
|
453
|
+
/**
|
|
454
|
+
* 将 object 参数转为 [{key:"Port", IntValue:80}] 的格式,并且剔除空字符串
|
|
455
|
+
*/
|
|
456
|
+
function parseObjectToDiffConfigItem(data) {
|
|
457
|
+
const kvs = Object.entries(data);
|
|
458
|
+
const Items = [];
|
|
459
|
+
kvs.forEach(([k, v]) => {
|
|
460
|
+
const Key = SUBMIT_DIFF_MAP[k] || k;
|
|
461
|
+
if ([
|
|
462
|
+
'CustomLogs',
|
|
463
|
+
'EnvParams',
|
|
464
|
+
'CreateTime',
|
|
465
|
+
'Dockerfile',
|
|
466
|
+
'BuildDir',
|
|
467
|
+
'LogType',
|
|
468
|
+
'LogSetId',
|
|
469
|
+
'LogTopicId',
|
|
470
|
+
'LogParseType',
|
|
471
|
+
'Tag',
|
|
472
|
+
'InternalAccess',
|
|
473
|
+
'InternalDomain',
|
|
474
|
+
'OperationMode',
|
|
475
|
+
'SessionAffinity'
|
|
476
|
+
].includes(k)) {
|
|
477
|
+
!!v && Items.push({ Key, Value: v });
|
|
478
|
+
}
|
|
479
|
+
else if (['MinNum', 'MaxNum', 'InitialDelaySeconds', 'Port'].includes(k)) {
|
|
480
|
+
Items.push({ Key, IntValue: v });
|
|
481
|
+
}
|
|
482
|
+
else if (['HasDockerfile'].includes(k)) {
|
|
483
|
+
Items.push({ Key, BoolValue: v });
|
|
484
|
+
}
|
|
485
|
+
else if (['Cpu', 'Mem'].includes(k)) {
|
|
486
|
+
Items.push({ Key, FloatValue: v });
|
|
487
|
+
}
|
|
488
|
+
else if (['OpenAccessTypes', 'EntryPoint', 'Cmd'].includes(k)) {
|
|
489
|
+
Items.push({ Key, ArrayValue: v });
|
|
490
|
+
}
|
|
491
|
+
else if (['PolicyDetails'].includes(k)) {
|
|
492
|
+
Items.push({ Key, PolicyDetails: v });
|
|
493
|
+
}
|
|
494
|
+
else if (['TimerScale'].includes(k)) {
|
|
495
|
+
Items.push({ Key, TimerScale: v });
|
|
496
|
+
}
|
|
497
|
+
});
|
|
498
|
+
return Items;
|
|
499
|
+
}
|
|
429
500
|
|
|
430
501
|
|
|
431
502
|
/***/ }),
|
|
@@ -23554,7 +23625,7 @@ async function getCloudBaseManager(options = {}) {
|
|
|
23554
23625
|
secretKey,
|
|
23555
23626
|
envId: finalEnvId || loginEnvId,
|
|
23556
23627
|
token,
|
|
23557
|
-
proxy: process.env.http_proxy
|
|
23628
|
+
proxy: process.env.http_proxy,
|
|
23558
23629
|
});
|
|
23559
23630
|
return manager;
|
|
23560
23631
|
}
|
|
@@ -23571,13 +23642,8 @@ async function getCloudBaseManager(options = {}) {
|
|
|
23571
23642
|
function createCloudBaseManagerWithOptions(cloudBaseOptions) {
|
|
23572
23643
|
(0, logger_js_1.debug)('使用传入的 CloudBase 配置创建 manager:', cloudBaseOptions);
|
|
23573
23644
|
const manager = new manager_node_1.default({
|
|
23574
|
-
|
|
23575
|
-
secretKey: cloudBaseOptions.secretKey,
|
|
23576
|
-
envId: cloudBaseOptions.envId,
|
|
23577
|
-
token: cloudBaseOptions.token,
|
|
23645
|
+
...cloudBaseOptions,
|
|
23578
23646
|
proxy: cloudBaseOptions.proxy || process.env.http_proxy,
|
|
23579
|
-
region: cloudBaseOptions.region,
|
|
23580
|
-
envType: cloudBaseOptions.envType
|
|
23581
23647
|
});
|
|
23582
23648
|
return manager;
|
|
23583
23649
|
}
|
|
@@ -48550,7 +48616,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
48550
48616
|
exports.cloudBaseRequest = cloudBaseRequest;
|
|
48551
48617
|
const auth_1 = __webpack_require__(23506);
|
|
48552
48618
|
const http_request_1 = __webpack_require__(72088);
|
|
48553
|
-
const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou'];
|
|
48619
|
+
const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou', 'ap-singapore'];
|
|
48554
48620
|
async function cloudBaseRequest(options) {
|
|
48555
48621
|
// const url = 'https://tcb-admin.tencentcloudapi.com/admin'
|
|
48556
48622
|
const { config, params = {}, method = 'POST', headers = {} } = options;
|
|
@@ -48564,11 +48630,11 @@ async function cloudBaseRequest(options) {
|
|
|
48564
48630
|
let internalRegionEndpoint = '';
|
|
48565
48631
|
if (finalRegion) {
|
|
48566
48632
|
if (SUPPORT_REGIONS.includes(finalRegion)) {
|
|
48567
|
-
internetRegionEndpoint = `${finalRegion}.tcb-api.tencentcloudapi.com`;
|
|
48568
|
-
internalRegionEndpoint =
|
|
48633
|
+
internetRegionEndpoint = `${envId}.${finalRegion}.tcb-api.tencentcloudapi.com`;
|
|
48634
|
+
internalRegionEndpoint = `${envId}.internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
|
|
48569
48635
|
}
|
|
48570
48636
|
else {
|
|
48571
|
-
console.warn('
|
|
48637
|
+
console.warn('当前仅支持上海,广州,新加坡地域,其他地域默认解析到固定域名(上海地域)');
|
|
48572
48638
|
internetRegionEndpoint = `tcb-api.tencentcloudapi.com`;
|
|
48573
48639
|
internalRegionEndpoint = `internal.tcb-api.tencentcloudapi.com`;
|
|
48574
48640
|
}
|
|
@@ -90161,19 +90227,20 @@ class EnvService {
|
|
|
90161
90227
|
});
|
|
90162
90228
|
}
|
|
90163
90229
|
getCos() {
|
|
90230
|
+
const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
|
|
90164
90231
|
const { secretId, secretKey, token } = this.environment.getAuthConfig();
|
|
90165
90232
|
const cosConfig = {
|
|
90166
90233
|
SecretId: secretId,
|
|
90167
90234
|
SecretKey: secretKey,
|
|
90168
90235
|
SecurityToken: token,
|
|
90169
|
-
Domain:
|
|
90236
|
+
Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
|
|
90170
90237
|
};
|
|
90171
90238
|
if (constant_1.COS_SDK_PROTOCOL) {
|
|
90172
90239
|
cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
|
|
90173
90240
|
? constant_1.COS_SDK_PROTOCOL.toLowerCase()
|
|
90174
90241
|
: constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
|
|
90175
90242
|
}
|
|
90176
|
-
if (
|
|
90243
|
+
if (internalEndpoint) {
|
|
90177
90244
|
cosConfig.Protocol = 'http:';
|
|
90178
90245
|
}
|
|
90179
90246
|
return new cos_nodejs_sdk_v5_1.default(cosConfig);
|
|
@@ -135017,7 +135084,7 @@ class TelemetryReporter {
|
|
|
135017
135084
|
const nodeVersion = process.version; // Node.js版本
|
|
135018
135085
|
const arch = os_1.default.arch(); // 系统架构
|
|
135019
135086
|
// 从构建时注入的版本号获取MCP版本信息
|
|
135020
|
-
const mcpVersion = process.env.npm_package_version || "2.
|
|
135087
|
+
const mcpVersion = process.env.npm_package_version || "2.2.0-alpha.0" || 0;
|
|
135021
135088
|
return {
|
|
135022
135089
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
135023
135090
|
deviceId: this.deviceId,
|
|
@@ -179615,6 +179682,7 @@ exports.sleep = sleep;
|
|
|
179615
179682
|
exports.upperCaseStringFisrt = upperCaseStringFisrt;
|
|
179616
179683
|
exports.upperCaseObjKey = upperCaseObjKey;
|
|
179617
179684
|
exports.fetchTemplates = fetchTemplates;
|
|
179685
|
+
exports.successLog = successLog;
|
|
179618
179686
|
const archiver_1 = __importDefault(__webpack_require__(99133));
|
|
179619
179687
|
const crypto_1 = __importDefault(__webpack_require__(55511));
|
|
179620
179688
|
const fs_extra_1 = __importDefault(__webpack_require__(21605));
|
|
@@ -179893,6 +179961,10 @@ const getCompleteTimeRange = (timeRange) => {
|
|
|
179893
179961
|
};
|
|
179894
179962
|
};
|
|
179895
179963
|
exports.getCompleteTimeRange = getCompleteTimeRange;
|
|
179964
|
+
function successLog(msg) {
|
|
179965
|
+
// 空格,兼容中文字符编码长度问题
|
|
179966
|
+
console.log(`${msg}`);
|
|
179967
|
+
}
|
|
179896
179968
|
|
|
179897
179969
|
|
|
179898
179970
|
/***/ }),
|
|
@@ -191221,20 +191293,25 @@ function callSuccessCallback(callback, result) {
|
|
|
191221
191293
|
/***/ }),
|
|
191222
191294
|
|
|
191223
191295
|
/***/ 65607:
|
|
191224
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
191296
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
191225
191297
|
|
|
191226
191298
|
"use strict";
|
|
191227
191299
|
|
|
191228
191300
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
191229
191301
|
exports.CloudBaseContext = void 0;
|
|
191302
|
+
const constant_1 = __webpack_require__(40762);
|
|
191230
191303
|
class CloudBaseContext {
|
|
191231
|
-
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
|
|
191304
|
+
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined }) {
|
|
191232
191305
|
this.secretId = secretId;
|
|
191233
191306
|
this.secretKey = secretKey;
|
|
191234
191307
|
this.token = token;
|
|
191235
191308
|
this.proxy = proxy;
|
|
191236
191309
|
this.region = region;
|
|
191237
191310
|
this.envType = envType;
|
|
191311
|
+
this.useInternalEndpoint = useInternalEndpoint;
|
|
191312
|
+
}
|
|
191313
|
+
isInternalEndpoint() {
|
|
191314
|
+
return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
|
|
191238
191315
|
}
|
|
191239
191316
|
}
|
|
191240
191317
|
exports.CloudBaseContext = CloudBaseContext;
|
|
@@ -200761,7 +200838,7 @@ ${envIdSection}
|
|
|
200761
200838
|
## 环境信息
|
|
200762
200839
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
200763
200840
|
- Node.js版本: ${process.version}
|
|
200764
|
-
- MCP 版本:${process.env.npm_package_version || "2.
|
|
200841
|
+
- MCP 版本:${process.env.npm_package_version || "2.2.0-alpha.0" || 0}
|
|
200765
200842
|
- 系统架构: ${os_1.default.arch()}
|
|
200766
200843
|
- 时间: ${new Date().toISOString()}
|
|
200767
200844
|
- 请求ID: ${requestId}
|
|
@@ -203653,6 +203730,7 @@ class StorageService {
|
|
|
203653
203730
|
* 获取 COS 配置
|
|
203654
203731
|
*/
|
|
203655
203732
|
getCos(parallel = 20) {
|
|
203733
|
+
const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
|
|
203656
203734
|
const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
|
|
203657
203735
|
const cosProxy = process.env.TCB_COS_PROXY;
|
|
203658
203736
|
const cosConfig = {
|
|
@@ -203661,14 +203739,14 @@ class StorageService {
|
|
|
203661
203739
|
SecretKey: secretKey,
|
|
203662
203740
|
Proxy: cosProxy || proxy,
|
|
203663
203741
|
SecurityToken: token,
|
|
203664
|
-
Domain:
|
|
203742
|
+
Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
|
|
203665
203743
|
};
|
|
203666
203744
|
if (constant_1.COS_SDK_PROTOCOL) {
|
|
203667
203745
|
cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
|
|
203668
203746
|
? constant_1.COS_SDK_PROTOCOL.toLowerCase()
|
|
203669
203747
|
: constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
|
|
203670
203748
|
}
|
|
203671
|
-
if (
|
|
203749
|
+
if (internalEndpoint) {
|
|
203672
203750
|
cosConfig.Protocol = 'http:';
|
|
203673
203751
|
}
|
|
203674
203752
|
// COSSDK 默认开启 KeepAlive,这里提供关闭的方式
|
|
@@ -215060,26 +215138,26 @@ const path = __importStar(__webpack_require__(39902));
|
|
|
215060
215138
|
const zod_1 = __webpack_require__(21614);
|
|
215061
215139
|
// CloudBase 模板配置
|
|
215062
215140
|
const TEMPLATES = {
|
|
215063
|
-
|
|
215141
|
+
react: {
|
|
215064
215142
|
description: "React + CloudBase 全栈应用模板",
|
|
215065
|
-
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip"
|
|
215143
|
+
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip",
|
|
215066
215144
|
},
|
|
215067
|
-
|
|
215145
|
+
vue: {
|
|
215068
215146
|
description: "Vue + CloudBase 全栈应用模板",
|
|
215069
|
-
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip"
|
|
215147
|
+
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip",
|
|
215070
215148
|
},
|
|
215071
|
-
|
|
215149
|
+
miniprogram: {
|
|
215072
215150
|
description: "微信小程序 + 云开发模板",
|
|
215073
|
-
url: "https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip"
|
|
215151
|
+
url: "https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip",
|
|
215074
215152
|
},
|
|
215075
|
-
|
|
215153
|
+
uniapp: {
|
|
215076
215154
|
description: "UniApp + CloudBase 跨端应用模板",
|
|
215077
|
-
url: "https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip"
|
|
215155
|
+
url: "https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip",
|
|
215078
215156
|
},
|
|
215079
|
-
|
|
215157
|
+
rules: {
|
|
215080
215158
|
description: "AI编辑器配置模板(包含所有主流编辑器配置)",
|
|
215081
|
-
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip"
|
|
215082
|
-
}
|
|
215159
|
+
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip",
|
|
215160
|
+
},
|
|
215083
215161
|
};
|
|
215084
215162
|
// IDE类型枚举
|
|
215085
215163
|
const IDE_TYPES = [
|
|
@@ -215099,22 +215177,13 @@ const IDE_TYPES = [
|
|
|
215099
215177
|
"roocode", // RooCode AI编辑器
|
|
215100
215178
|
"tongyi-lingma", // 通义灵码
|
|
215101
215179
|
"trae", // Trae AI编辑器
|
|
215102
|
-
"vscode" // Visual Studio Code
|
|
215180
|
+
"vscode", // Visual Studio Code
|
|
215103
215181
|
];
|
|
215104
215182
|
// IDE到文件的映射关系
|
|
215105
215183
|
const IDE_FILE_MAPPINGS = {
|
|
215106
|
-
"cursor"
|
|
215107
|
-
|
|
215108
|
-
|
|
215109
|
-
],
|
|
215110
|
-
"windsurf": [
|
|
215111
|
-
".windsurf/rules/cloudbase-rules.md"
|
|
215112
|
-
],
|
|
215113
|
-
"codebuddy": [
|
|
215114
|
-
".rules/cloudbase-rules.md",
|
|
215115
|
-
"CODEBUDDY.md",
|
|
215116
|
-
".mcp.json"
|
|
215117
|
-
],
|
|
215184
|
+
cursor: [".cursor/rules/cloudbase-rules.mdc", ".cursor/mcp.json"],
|
|
215185
|
+
windsurf: [".windsurf/rules/cloudbase-rules.md"],
|
|
215186
|
+
codebuddy: [".rules/cloudbase-rules.md", "CODEBUDDY.md", ".mcp.json"],
|
|
215118
215187
|
"claude-code": [
|
|
215119
215188
|
"CLAUDE.md",
|
|
215120
215189
|
".mcp.json",
|
|
@@ -215123,49 +215192,22 @@ const IDE_FILE_MAPPINGS = {
|
|
|
215123
215192
|
".claude/commands/spec.md",
|
|
215124
215193
|
".claude/commands/no_spec.md",
|
|
215125
215194
|
],
|
|
215126
|
-
|
|
215127
|
-
|
|
215128
|
-
],
|
|
215129
|
-
"
|
|
215130
|
-
".gemini/GEMINI.md",
|
|
215131
|
-
".gemini/settings.json"
|
|
215132
|
-
],
|
|
215133
|
-
"opencode": [
|
|
215134
|
-
".opencode.json"
|
|
215135
|
-
],
|
|
215136
|
-
"qwen-code": [
|
|
215137
|
-
".qwen/QWEN.md",
|
|
215138
|
-
".qwen/settings.json"
|
|
215139
|
-
],
|
|
215195
|
+
cline: [".clinerules/cloudbase-rules.mdc"],
|
|
215196
|
+
"gemini-cli": [".gemini/GEMINI.md", ".gemini/settings.json"],
|
|
215197
|
+
opencode: [".opencode.json"],
|
|
215198
|
+
"qwen-code": [".qwen/QWEN.md", ".qwen/settings.json"],
|
|
215140
215199
|
"baidu-comate": [
|
|
215141
215200
|
".comate/rules/cloudbase-rules.mdr",
|
|
215142
215201
|
".comate/rules/cloudbaase-rules.mdr",
|
|
215143
|
-
".comate/mcp.json"
|
|
215144
|
-
],
|
|
215145
|
-
"openai-codex-cli": [
|
|
215146
|
-
".codex/config.toml",
|
|
215147
|
-
"AGENTS.md",
|
|
215148
|
-
],
|
|
215149
|
-
"augment-code": [
|
|
215150
|
-
".augment-guidelines"
|
|
215202
|
+
".comate/mcp.json",
|
|
215151
215203
|
],
|
|
215152
|
-
"
|
|
215153
|
-
|
|
215154
|
-
],
|
|
215155
|
-
|
|
215156
|
-
|
|
215157
|
-
|
|
215158
|
-
],
|
|
215159
|
-
"tongyi-lingma": [
|
|
215160
|
-
".lingma/rules/cloudbaase-rules.md"
|
|
215161
|
-
],
|
|
215162
|
-
"trae": [
|
|
215163
|
-
".trae/rules/cloudbase-rules.md"
|
|
215164
|
-
],
|
|
215165
|
-
"vscode": [
|
|
215166
|
-
".vscode/mcp.json",
|
|
215167
|
-
".vscode/settings.json"
|
|
215168
|
-
]
|
|
215204
|
+
"openai-codex-cli": [".codex/config.toml", "AGENTS.md"],
|
|
215205
|
+
"augment-code": [".augment-guidelines"],
|
|
215206
|
+
"github-copilot": [".github/copilot-instructions.md"],
|
|
215207
|
+
roocode: [".roo/rules/cloudbaase-rules.md", ".roo/mcp.json"],
|
|
215208
|
+
"tongyi-lingma": [".lingma/rules/cloudbaase-rules.md"],
|
|
215209
|
+
trae: [".trae/rules/cloudbase-rules.md"],
|
|
215210
|
+
vscode: [".vscode/mcp.json", ".vscode/settings.json"],
|
|
215169
215211
|
};
|
|
215170
215212
|
// 所有IDE配置文件的完整列表 - 通过IDE_FILE_MAPPINGS计算得出
|
|
215171
215213
|
const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()));
|
|
@@ -215173,51 +215215,87 @@ const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()
|
|
|
215173
215215
|
IDE_FILE_MAPPINGS["all"] = ALL_IDE_FILES;
|
|
215174
215216
|
// IDE描述映射
|
|
215175
215217
|
const IDE_DESCRIPTIONS = {
|
|
215176
|
-
|
|
215177
|
-
|
|
215178
|
-
|
|
215179
|
-
|
|
215218
|
+
all: "所有IDE配置",
|
|
215219
|
+
cursor: "Cursor AI编辑器",
|
|
215220
|
+
windsurf: "WindSurf AI编辑器",
|
|
215221
|
+
codebuddy: "CodeBuddy AI编辑器",
|
|
215180
215222
|
"claude-code": "Claude Code AI编辑器",
|
|
215181
|
-
|
|
215223
|
+
cline: "Cline AI编辑器",
|
|
215182
215224
|
"gemini-cli": "Gemini CLI",
|
|
215183
|
-
|
|
215225
|
+
opencode: "OpenCode AI编辑器",
|
|
215184
215226
|
"qwen-code": "通义灵码",
|
|
215185
215227
|
"baidu-comate": "百度Comate",
|
|
215186
215228
|
"openai-codex-cli": "OpenAI Codex CLI",
|
|
215187
215229
|
"augment-code": "Augment Code",
|
|
215188
215230
|
"github-copilot": "GitHub Copilot",
|
|
215189
|
-
|
|
215231
|
+
roocode: "RooCode AI编辑器",
|
|
215190
215232
|
"tongyi-lingma": "通义灵码",
|
|
215191
|
-
|
|
215192
|
-
|
|
215193
|
-
};
|
|
215233
|
+
trae: "Trae AI编辑器",
|
|
215234
|
+
vscode: "Visual Studio Code",
|
|
215235
|
+
};
|
|
215236
|
+
// INTEGRATION_IDE 环境变量值到 IDE 类型的映射
|
|
215237
|
+
const INTEGRATION_IDE_MAPPING = {
|
|
215238
|
+
Cursor: "cursor",
|
|
215239
|
+
WindSurf: "windsurf",
|
|
215240
|
+
CodeBuddy: "codebuddy",
|
|
215241
|
+
CodeBuddyManual: "codebuddy",
|
|
215242
|
+
CodeBuddyCode: "codebuddy",
|
|
215243
|
+
"Claude Code": "claude-code",
|
|
215244
|
+
CLINE: "cline",
|
|
215245
|
+
"Gemini CLI": "gemini-cli",
|
|
215246
|
+
OpenCode: "opencode",
|
|
215247
|
+
"Qwen Code": "qwen-code",
|
|
215248
|
+
"Baidu Comate": "baidu-comate",
|
|
215249
|
+
"OpenAI Codex CLI": "openai-codex-cli",
|
|
215250
|
+
"Augment Code": "augment-code",
|
|
215251
|
+
"GitHub Copilot": "github-copilot",
|
|
215252
|
+
RooCode: "roocode",
|
|
215253
|
+
"Tongyi Lingma": "tongyi-lingma",
|
|
215254
|
+
Trae: "trae",
|
|
215255
|
+
VSCode: "vscode",
|
|
215256
|
+
};
|
|
215257
|
+
// 根据 INTEGRATION_IDE 环境变量获取默认 IDE 类型
|
|
215258
|
+
function getDefaultIDEFromEnv() {
|
|
215259
|
+
const integrationIDE = process.env.INTEGRATION_IDE;
|
|
215260
|
+
if (integrationIDE) {
|
|
215261
|
+
const mappedIDE = INTEGRATION_IDE_MAPPING[integrationIDE];
|
|
215262
|
+
if (mappedIDE) {
|
|
215263
|
+
return mappedIDE;
|
|
215264
|
+
}
|
|
215265
|
+
}
|
|
215266
|
+
return "all";
|
|
215267
|
+
}
|
|
215194
215268
|
// 下载文件到临时目录
|
|
215195
215269
|
async function downloadFile(url, filePath) {
|
|
215196
215270
|
return new Promise((resolve, reject) => {
|
|
215197
|
-
const client = url.startsWith(
|
|
215198
|
-
client
|
|
215271
|
+
const client = url.startsWith("https:") ? https : http;
|
|
215272
|
+
client
|
|
215273
|
+
.get(url, (res) => {
|
|
215199
215274
|
if (res.statusCode === 200) {
|
|
215200
215275
|
const file = fs.createWriteStream(filePath);
|
|
215201
215276
|
res.pipe(file);
|
|
215202
|
-
file.on(
|
|
215277
|
+
file.on("finish", () => {
|
|
215203
215278
|
file.close();
|
|
215204
215279
|
resolve();
|
|
215205
215280
|
});
|
|
215206
|
-
file.on(
|
|
215281
|
+
file.on("error", reject);
|
|
215207
215282
|
}
|
|
215208
215283
|
else if (res.statusCode === 302 || res.statusCode === 301) {
|
|
215209
215284
|
// 处理重定向
|
|
215210
215285
|
if (res.headers.location) {
|
|
215211
|
-
downloadFile(res.headers.location, filePath)
|
|
215286
|
+
downloadFile(res.headers.location, filePath)
|
|
215287
|
+
.then(resolve)
|
|
215288
|
+
.catch(reject);
|
|
215212
215289
|
}
|
|
215213
215290
|
else {
|
|
215214
|
-
reject(new Error(
|
|
215291
|
+
reject(new Error("重定向但没有location header"));
|
|
215215
215292
|
}
|
|
215216
215293
|
}
|
|
215217
215294
|
else {
|
|
215218
215295
|
reject(new Error(`下载失败,状态码: ${res.statusCode}`));
|
|
215219
215296
|
}
|
|
215220
|
-
})
|
|
215297
|
+
})
|
|
215298
|
+
.on("error", reject);
|
|
215221
215299
|
});
|
|
215222
215300
|
}
|
|
215223
215301
|
// 解压ZIP文件
|
|
@@ -215230,7 +215308,7 @@ async function extractZip(zipPath, extractPath) {
|
|
|
215230
215308
|
zip.extractAllTo(extractPath, true);
|
|
215231
215309
|
}
|
|
215232
215310
|
catch (error) {
|
|
215233
|
-
throw new Error(`解压失败: ${error instanceof Error ? error.message :
|
|
215311
|
+
throw new Error(`解压失败: ${error instanceof Error ? error.message : "未知错误"}`);
|
|
215234
215312
|
}
|
|
215235
215313
|
}
|
|
215236
215314
|
// 获取目录下所有文件的相对路径列表
|
|
@@ -215254,7 +215332,7 @@ async function copyFileIfNotExists(src, dest) {
|
|
|
215254
215332
|
try {
|
|
215255
215333
|
// 检查目标文件是否存在
|
|
215256
215334
|
if (fs.existsSync(dest)) {
|
|
215257
|
-
return { copied: false, reason:
|
|
215335
|
+
return { copied: false, reason: "文件已存在" };
|
|
215258
215336
|
}
|
|
215259
215337
|
// 创建目标目录
|
|
215260
215338
|
await fsPromises.mkdir(path.dirname(dest), { recursive: true });
|
|
@@ -215263,14 +215341,17 @@ async function copyFileIfNotExists(src, dest) {
|
|
|
215263
215341
|
return { copied: true };
|
|
215264
215342
|
}
|
|
215265
215343
|
catch (error) {
|
|
215266
|
-
return {
|
|
215344
|
+
return {
|
|
215345
|
+
copied: false,
|
|
215346
|
+
reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215347
|
+
};
|
|
215267
215348
|
}
|
|
215268
215349
|
}
|
|
215269
215350
|
// 复制文件,支持覆盖模式
|
|
215270
215351
|
// 判断是否应该跳过 README.md 文件
|
|
215271
215352
|
function shouldSkipReadme(template, destPath, overwrite) {
|
|
215272
|
-
const isReadme = path.basename(destPath).toLowerCase() ===
|
|
215273
|
-
const isRulesTemplate = template ===
|
|
215353
|
+
const isReadme = path.basename(destPath).toLowerCase() === "readme.md";
|
|
215354
|
+
const isRulesTemplate = template === "rules";
|
|
215274
215355
|
const exists = fs.existsSync(destPath);
|
|
215275
215356
|
return isReadme && isRulesTemplate && exists && !overwrite;
|
|
215276
215357
|
}
|
|
@@ -215279,11 +215360,15 @@ async function copyFile(src, dest, overwrite = false, template) {
|
|
|
215279
215360
|
const destExists = fs.existsSync(dest);
|
|
215280
215361
|
// 检查是否需要跳过 README.md 文件(仅对 rules 模板)
|
|
215281
215362
|
if (template && shouldSkipReadme(template, dest, overwrite)) {
|
|
215282
|
-
return {
|
|
215363
|
+
return {
|
|
215364
|
+
copied: false,
|
|
215365
|
+
reason: "README.md 文件已存在,已保护",
|
|
215366
|
+
action: "protected",
|
|
215367
|
+
};
|
|
215283
215368
|
}
|
|
215284
215369
|
// 如果目标文件存在且不允许覆盖
|
|
215285
215370
|
if (destExists && !overwrite) {
|
|
215286
|
-
return { copied: false, reason:
|
|
215371
|
+
return { copied: false, reason: "文件已存在", action: "skipped" };
|
|
215287
215372
|
}
|
|
215288
215373
|
// 创建目标目录
|
|
215289
215374
|
await fsPromises.mkdir(path.dirname(dest), { recursive: true });
|
|
@@ -215291,11 +215376,14 @@ async function copyFile(src, dest, overwrite = false, template) {
|
|
|
215291
215376
|
await fsPromises.copyFile(src, dest);
|
|
215292
215377
|
return {
|
|
215293
215378
|
copied: true,
|
|
215294
|
-
action: destExists ?
|
|
215379
|
+
action: destExists ? "overwritten" : "created",
|
|
215295
215380
|
};
|
|
215296
215381
|
}
|
|
215297
215382
|
catch (error) {
|
|
215298
|
-
return {
|
|
215383
|
+
return {
|
|
215384
|
+
copied: false,
|
|
215385
|
+
reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215386
|
+
};
|
|
215299
215387
|
}
|
|
215300
215388
|
}
|
|
215301
215389
|
// IDE验证函数
|
|
@@ -215303,13 +215391,13 @@ function validateIDE(ide) {
|
|
|
215303
215391
|
if (ide === "all") {
|
|
215304
215392
|
return { valid: true };
|
|
215305
215393
|
}
|
|
215306
|
-
const supportedIDEs = IDE_TYPES.filter(type => type !== "all");
|
|
215394
|
+
const supportedIDEs = IDE_TYPES.filter((type) => type !== "all");
|
|
215307
215395
|
const isValid = supportedIDEs.includes(ide);
|
|
215308
215396
|
if (!isValid) {
|
|
215309
215397
|
return {
|
|
215310
215398
|
valid: false,
|
|
215311
215399
|
error: `不支持的IDE类型: ${ide}`,
|
|
215312
|
-
supportedIDEs: supportedIDEs
|
|
215400
|
+
supportedIDEs: supportedIDEs,
|
|
215313
215401
|
};
|
|
215314
215402
|
}
|
|
215315
215403
|
return { valid: true };
|
|
@@ -215324,9 +215412,9 @@ function filterFilesByIDE(files, ide) {
|
|
|
215324
215412
|
return files; // 如果找不到映射,返回所有文件
|
|
215325
215413
|
}
|
|
215326
215414
|
// 计算需要排除的IDE文件(除了当前IDE需要的文件)
|
|
215327
|
-
const filesToExclude = ALL_IDE_FILES.filter(file => !ideFiles.includes(file));
|
|
215415
|
+
const filesToExclude = ALL_IDE_FILES.filter((file) => !ideFiles.includes(file));
|
|
215328
215416
|
// 排除不需要的IDE配置文件,保留其他所有文件
|
|
215329
|
-
return files.filter(file => !filesToExclude.includes(file));
|
|
215417
|
+
return files.filter((file) => !filesToExclude.includes(file));
|
|
215330
215418
|
}
|
|
215331
215419
|
// 创建过滤后的目录结构
|
|
215332
215420
|
async function createFilteredDirectory(extractDir, filteredFiles, ide) {
|
|
@@ -215334,7 +215422,7 @@ async function createFilteredDirectory(extractDir, filteredFiles, ide) {
|
|
|
215334
215422
|
return extractDir; // 如果选择所有IDE,直接返回原目录
|
|
215335
215423
|
}
|
|
215336
215424
|
// 创建新的过滤后目录
|
|
215337
|
-
const filteredDir = path.join(path.dirname(extractDir),
|
|
215425
|
+
const filteredDir = path.join(path.dirname(extractDir), "filtered");
|
|
215338
215426
|
await fsPromises.mkdir(filteredDir, { recursive: true });
|
|
215339
215427
|
// 只复制过滤后的文件到新目录
|
|
215340
215428
|
for (const relativePath of filteredFiles) {
|
|
@@ -215353,32 +215441,42 @@ function registerSetupTools(server) {
|
|
|
215353
215441
|
title: "下载项目模板",
|
|
215354
215442
|
description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
|
|
215355
215443
|
|
|
215356
|
-
**CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置(默认)\n- cursor: Cursor AI编辑器\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.
|
|
215444
|
+
**CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置(默认)\n- cursor: Cursor AI编辑器\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.2.0-alpha.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
215357
215445
|
inputSchema: {
|
|
215358
|
-
template: zod_1.z
|
|
215359
|
-
|
|
215360
|
-
|
|
215446
|
+
template: zod_1.z
|
|
215447
|
+
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
215448
|
+
.describe("要下载的模板类型"),
|
|
215449
|
+
ide: zod_1.z
|
|
215450
|
+
.enum(IDE_TYPES)
|
|
215451
|
+
.optional()
|
|
215452
|
+
.describe("指定要下载的IDE类型。如果未指定,会根据 INTEGRATION_IDE 环境变量自动选择对应的IDE配置;如果环境变量也未设置,则默认下载所有IDE配置"),
|
|
215453
|
+
overwrite: zod_1.z
|
|
215454
|
+
.boolean()
|
|
215455
|
+
.optional()
|
|
215456
|
+
.describe("是否覆盖已存在的文件,默认为false(不覆盖)"),
|
|
215361
215457
|
},
|
|
215362
215458
|
annotations: {
|
|
215363
215459
|
readOnlyHint: false,
|
|
215364
215460
|
destructiveHint: false,
|
|
215365
215461
|
idempotentHint: false,
|
|
215366
215462
|
openWorldHint: true,
|
|
215367
|
-
category: "setup"
|
|
215368
|
-
}
|
|
215369
|
-
}, async ({ template, ide
|
|
215463
|
+
category: "setup",
|
|
215464
|
+
},
|
|
215465
|
+
}, async ({ template, ide, overwrite = false, }) => {
|
|
215370
215466
|
try {
|
|
215467
|
+
// 如果没有传入 ide 参数,根据 INTEGRATION_IDE 环境变量获取默认值
|
|
215468
|
+
const resolvedIDE = ide ?? getDefaultIDEFromEnv();
|
|
215371
215469
|
// 验证IDE类型
|
|
215372
|
-
const ideValidation = validateIDE(
|
|
215470
|
+
const ideValidation = validateIDE(resolvedIDE);
|
|
215373
215471
|
if (!ideValidation.valid) {
|
|
215374
|
-
const supportedIDEs = ideValidation.supportedIDEs?.join(
|
|
215472
|
+
const supportedIDEs = ideValidation.supportedIDEs?.join(", ") || "";
|
|
215375
215473
|
return {
|
|
215376
215474
|
content: [
|
|
215377
215475
|
{
|
|
215378
215476
|
type: "text",
|
|
215379
|
-
text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}
|
|
215380
|
-
}
|
|
215381
|
-
]
|
|
215477
|
+
text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}`,
|
|
215478
|
+
},
|
|
215479
|
+
],
|
|
215382
215480
|
};
|
|
215383
215481
|
}
|
|
215384
215482
|
const templateConfig = TEMPLATES[template];
|
|
@@ -215387,23 +215485,23 @@ function registerSetupTools(server) {
|
|
|
215387
215485
|
content: [
|
|
215388
215486
|
{
|
|
215389
215487
|
type: "text",
|
|
215390
|
-
text: `❌ 不支持的模板类型: ${template}
|
|
215391
|
-
}
|
|
215392
|
-
]
|
|
215488
|
+
text: `❌ 不支持的模板类型: ${template}`,
|
|
215489
|
+
},
|
|
215490
|
+
],
|
|
215393
215491
|
};
|
|
215394
215492
|
}
|
|
215395
215493
|
// 创建临时目录
|
|
215396
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(),
|
|
215397
|
-
const zipPath = path.join(tempDir,
|
|
215398
|
-
const extractDir = path.join(tempDir,
|
|
215494
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cloudbase-template-"));
|
|
215495
|
+
const zipPath = path.join(tempDir, "template.zip");
|
|
215496
|
+
const extractDir = path.join(tempDir, "extracted");
|
|
215399
215497
|
// 下载和解压
|
|
215400
215498
|
await downloadFile(templateConfig.url, zipPath);
|
|
215401
215499
|
await extractZip(zipPath, extractDir);
|
|
215402
215500
|
const extractedFiles = await getAllFiles(extractDir);
|
|
215403
215501
|
// 根据IDE类型过滤文件
|
|
215404
|
-
const filteredFiles = filterFilesByIDE(extractedFiles,
|
|
215502
|
+
const filteredFiles = filterFilesByIDE(extractedFiles, resolvedIDE);
|
|
215405
215503
|
// 创建过滤后的目录结构(当选择特定IDE时)
|
|
215406
|
-
const workingDir = await createFilteredDirectory(extractDir, filteredFiles,
|
|
215504
|
+
const workingDir = await createFilteredDirectory(extractDir, filteredFiles, resolvedIDE);
|
|
215407
215505
|
// 检查是否需要复制到项目目录
|
|
215408
215506
|
const workspaceFolder = process.env.WORKSPACE_FOLDER_PATHS || process.cwd();
|
|
215409
215507
|
let finalFiles = [];
|
|
@@ -215418,7 +215516,7 @@ function registerSetupTools(server) {
|
|
|
215418
215516
|
const destPath = path.join(workspaceFolder, relativePath);
|
|
215419
215517
|
const copyResult = await copyFile(srcPath, destPath, overwrite, template);
|
|
215420
215518
|
if (copyResult.copied) {
|
|
215421
|
-
if (copyResult.action ===
|
|
215519
|
+
if (copyResult.action === "overwritten") {
|
|
215422
215520
|
overwrittenCount++;
|
|
215423
215521
|
}
|
|
215424
215522
|
else {
|
|
@@ -215427,7 +215525,7 @@ function registerSetupTools(server) {
|
|
|
215427
215525
|
finalFiles.push(destPath);
|
|
215428
215526
|
}
|
|
215429
215527
|
else {
|
|
215430
|
-
if (copyResult.action ===
|
|
215528
|
+
if (copyResult.action === "protected") {
|
|
215431
215529
|
protectedCount++;
|
|
215432
215530
|
}
|
|
215433
215531
|
else {
|
|
@@ -215437,11 +215535,11 @@ function registerSetupTools(server) {
|
|
|
215437
215535
|
}
|
|
215438
215536
|
}
|
|
215439
215537
|
// 添加IDE过滤信息
|
|
215440
|
-
const ideInfo = IDE_DESCRIPTIONS[
|
|
215538
|
+
const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
|
|
215441
215539
|
results.push(`✅ ${templateConfig.description} (${ideInfo}) 同步完成`);
|
|
215442
215540
|
results.push(`📁 临时目录: ${workingDir}`);
|
|
215443
215541
|
results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
|
|
215444
|
-
if (
|
|
215542
|
+
if (resolvedIDE !== "all") {
|
|
215445
215543
|
results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
|
|
215446
215544
|
}
|
|
215447
215545
|
const stats = [];
|
|
@@ -215454,36 +215552,36 @@ function registerSetupTools(server) {
|
|
|
215454
215552
|
if (skippedCount > 0)
|
|
215455
215553
|
stats.push(`跳过 ${skippedCount} 个已存在文件`);
|
|
215456
215554
|
if (stats.length > 0) {
|
|
215457
|
-
results.push(`📊 ${stats.join(
|
|
215555
|
+
results.push(`📊 ${stats.join(",")}`);
|
|
215458
215556
|
}
|
|
215459
215557
|
if (overwrite || overwrittenCount > 0 || skippedCount > 0) {
|
|
215460
|
-
results.push(`🔄 覆盖模式: ${overwrite ?
|
|
215558
|
+
results.push(`🔄 覆盖模式: ${overwrite ? "启用" : "禁用"}`);
|
|
215461
215559
|
}
|
|
215462
215560
|
}
|
|
215463
215561
|
else {
|
|
215464
|
-
finalFiles = filteredFiles.map(relativePath => path.join(workingDir, relativePath));
|
|
215465
|
-
const ideInfo = IDE_DESCRIPTIONS[
|
|
215562
|
+
finalFiles = filteredFiles.map((relativePath) => path.join(workingDir, relativePath));
|
|
215563
|
+
const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
|
|
215466
215564
|
results.push(`✅ ${templateConfig.description} (${ideInfo}) 下载完成`);
|
|
215467
215565
|
results.push(`📁 保存在临时目录: ${workingDir}`);
|
|
215468
215566
|
results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
|
|
215469
|
-
if (
|
|
215567
|
+
if (resolvedIDE !== "all") {
|
|
215470
215568
|
results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
|
|
215471
215569
|
}
|
|
215472
|
-
results.push(
|
|
215570
|
+
results.push("💡 如需将模板(包括隐藏文件)复制到项目目录,请确保复制时包含所有隐藏文件。");
|
|
215473
215571
|
}
|
|
215474
215572
|
// 文件路径列表
|
|
215475
|
-
results.push(
|
|
215476
|
-
results.push(
|
|
215477
|
-
finalFiles.forEach(filePath => {
|
|
215573
|
+
results.push("");
|
|
215574
|
+
results.push("📋 文件列表:");
|
|
215575
|
+
finalFiles.forEach((filePath) => {
|
|
215478
215576
|
results.push(`${filePath}`);
|
|
215479
215577
|
});
|
|
215480
215578
|
return {
|
|
215481
215579
|
content: [
|
|
215482
215580
|
{
|
|
215483
215581
|
type: "text",
|
|
215484
|
-
text: results.join(
|
|
215485
|
-
}
|
|
215486
|
-
]
|
|
215582
|
+
text: results.join("\n"),
|
|
215583
|
+
},
|
|
215584
|
+
],
|
|
215487
215585
|
};
|
|
215488
215586
|
}
|
|
215489
215587
|
catch (error) {
|
|
@@ -215491,9 +215589,9 @@ function registerSetupTools(server) {
|
|
|
215491
215589
|
content: [
|
|
215492
215590
|
{
|
|
215493
215591
|
type: "text",
|
|
215494
|
-
text: `❌ 下载模板失败: ${error instanceof Error ? error.message :
|
|
215495
|
-
}
|
|
215496
|
-
]
|
|
215592
|
+
text: `❌ 下载模板失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215593
|
+
},
|
|
215594
|
+
],
|
|
215497
215595
|
};
|
|
215498
215596
|
}
|
|
215499
215597
|
});
|
|
@@ -226399,6 +226497,7 @@ class CloudService {
|
|
|
226399
226497
|
this.cloudBaseContext = context;
|
|
226400
226498
|
}
|
|
226401
226499
|
get baseUrl() {
|
|
226500
|
+
const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
|
|
226402
226501
|
const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
|
|
226403
226502
|
const urlMap = {
|
|
226404
226503
|
tcb,
|
|
@@ -226412,7 +226511,7 @@ class CloudService {
|
|
|
226412
226511
|
const intranetUrlMap = Object.keys(urlMap).map((service) => ({
|
|
226413
226512
|
[service]: `https://${service}.internal.tencentcloudapi.com`,
|
|
226414
226513
|
})).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
|
|
226415
|
-
if (
|
|
226514
|
+
if (internalEndpoint) {
|
|
226416
226515
|
return intranetUrlMap[this.service];
|
|
226417
226516
|
}
|
|
226418
226517
|
if (urlMap[this.service]) {
|
|
@@ -270045,7 +270144,7 @@ class CloudBase {
|
|
|
270045
270144
|
}
|
|
270046
270145
|
constructor(config = {}) {
|
|
270047
270146
|
this.cloudBaseConfig = {};
|
|
270048
|
-
let { secretId, secretKey, token, envId, proxy, region, envType } = config;
|
|
270147
|
+
let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint } = config;
|
|
270049
270148
|
// config 中传入的 secretId secretkey 必须同时存在
|
|
270050
270149
|
if ((secretId && !secretKey) || (!secretId && secretKey)) {
|
|
270051
270150
|
throw new Error('secretId and secretKey must be a pair');
|
|
@@ -270057,7 +270156,8 @@ class CloudBase {
|
|
|
270057
270156
|
envId,
|
|
270058
270157
|
envType,
|
|
270059
270158
|
proxy,
|
|
270060
|
-
region
|
|
270159
|
+
region,
|
|
270160
|
+
useInternalEndpoint
|
|
270061
270161
|
};
|
|
270062
270162
|
// 初始化 context
|
|
270063
270163
|
this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
|
|
@@ -270112,6 +270212,9 @@ class CloudBase {
|
|
|
270112
270212
|
getManagerConfig() {
|
|
270113
270213
|
return this.cloudBaseConfig;
|
|
270114
270214
|
}
|
|
270215
|
+
get isInternalEndpoint() {
|
|
270216
|
+
return this.context.isInternalEndpoint();
|
|
270217
|
+
}
|
|
270115
270218
|
}
|
|
270116
270219
|
module.exports = CloudBase;
|
|
270117
270220
|
|
|
@@ -272190,6 +272293,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
272190
272293
|
exports.FunctionService = void 0;
|
|
272191
272294
|
const fs_1 = __importDefault(__webpack_require__(29021));
|
|
272192
272295
|
const path_1 = __importDefault(__webpack_require__(39902));
|
|
272296
|
+
const lodash_1 = __importDefault(__webpack_require__(2543));
|
|
272193
272297
|
const packer_1 = __webpack_require__(5147);
|
|
272194
272298
|
const error_1 = __webpack_require__(40430);
|
|
272195
272299
|
const utils_1 = __webpack_require__(62358);
|
|
@@ -272436,20 +272540,96 @@ class FunctionService {
|
|
|
272436
272540
|
});
|
|
272437
272541
|
return data;
|
|
272438
272542
|
}
|
|
272543
|
+
/**
|
|
272544
|
+
* 列出所有函数
|
|
272545
|
+
* @param {IListFunctionOptions} options
|
|
272546
|
+
* @returns {Promise<Record<string, string>[]>}
|
|
272547
|
+
*/
|
|
272548
|
+
async listAllFunctions(options) {
|
|
272549
|
+
const allFunctions = [];
|
|
272550
|
+
let currentOffset = 0;
|
|
272551
|
+
const pageSize = 20;
|
|
272552
|
+
const { envId } = options;
|
|
272553
|
+
while (true) {
|
|
272554
|
+
try {
|
|
272555
|
+
const res = await this.scfService.request('ListFunctions', {
|
|
272556
|
+
Namespace: envId,
|
|
272557
|
+
Limit: pageSize,
|
|
272558
|
+
Offset: currentOffset
|
|
272559
|
+
});
|
|
272560
|
+
const { Functions = [], TotalCount } = res;
|
|
272561
|
+
if (Functions.length === 0) {
|
|
272562
|
+
break;
|
|
272563
|
+
}
|
|
272564
|
+
allFunctions.push(...Functions);
|
|
272565
|
+
// 检查是否已获取所有函数
|
|
272566
|
+
if (allFunctions.length >= TotalCount || Functions.length < pageSize) {
|
|
272567
|
+
break;
|
|
272568
|
+
}
|
|
272569
|
+
currentOffset += pageSize;
|
|
272570
|
+
}
|
|
272571
|
+
catch (error) {
|
|
272572
|
+
throw new error_1.CloudBaseError(`获取函数列表失败: ${error.message}`);
|
|
272573
|
+
}
|
|
272574
|
+
}
|
|
272575
|
+
// 格式化数据
|
|
272576
|
+
const data = [];
|
|
272577
|
+
allFunctions.forEach(func => {
|
|
272578
|
+
const { FunctionId, FunctionName, Runtime, AddTime, ModTime, Status } = func;
|
|
272579
|
+
data.push({
|
|
272580
|
+
FunctionId,
|
|
272581
|
+
FunctionName,
|
|
272582
|
+
Runtime,
|
|
272583
|
+
AddTime,
|
|
272584
|
+
ModTime,
|
|
272585
|
+
Status
|
|
272586
|
+
});
|
|
272587
|
+
});
|
|
272588
|
+
return data;
|
|
272589
|
+
}
|
|
272439
272590
|
/**
|
|
272440
272591
|
* 删除云函数
|
|
272441
272592
|
* @param {string} name 云函数名称
|
|
272442
272593
|
* @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
|
|
272443
272594
|
* @returns {Promise<IResponseInfo>}
|
|
272444
272595
|
*/
|
|
272445
|
-
async deleteFunction(name
|
|
272596
|
+
async deleteFunction({ name }) {
|
|
272597
|
+
var _a;
|
|
272446
272598
|
const { namespace } = this.getFunctionConfig();
|
|
272447
|
-
|
|
272599
|
+
// 检测是否绑定了 API 网关
|
|
272600
|
+
const accessService = this.environment.getAccessService();
|
|
272601
|
+
const res = await accessService.getAccessList({
|
|
272602
|
+
name
|
|
272603
|
+
});
|
|
272604
|
+
// 删除绑定的 API 网关
|
|
272605
|
+
if (((_a = res === null || res === void 0 ? void 0 : res.APISet) === null || _a === void 0 ? void 0 : _a.length) > 0) {
|
|
272606
|
+
await accessService.deleteAccess({
|
|
272607
|
+
name
|
|
272608
|
+
});
|
|
272609
|
+
}
|
|
272610
|
+
await this.scfService.request('DeleteFunction', {
|
|
272448
272611
|
FunctionName: name,
|
|
272449
|
-
Namespace: namespace
|
|
272450
|
-
Qualifier: qualifier
|
|
272612
|
+
Namespace: namespace
|
|
272451
272613
|
});
|
|
272452
272614
|
}
|
|
272615
|
+
/**
|
|
272616
|
+
* 批量删除云函数
|
|
272617
|
+
* @param {Object} options
|
|
272618
|
+
* @param {string[]} options.names 云函数名称列表
|
|
272619
|
+
* @returns {Promise<void>}
|
|
272620
|
+
*/
|
|
272621
|
+
async batchDeleteFunctions({ names }) {
|
|
272622
|
+
const promises = names.map(name => (async () => {
|
|
272623
|
+
try {
|
|
272624
|
+
await this.deleteFunction({ name });
|
|
272625
|
+
(0, utils_1.successLog)(`[${name}] 函数删除成功!`);
|
|
272626
|
+
}
|
|
272627
|
+
catch (e) {
|
|
272628
|
+
throw new error_1.CloudBaseError(e.message);
|
|
272629
|
+
}
|
|
272630
|
+
})());
|
|
272631
|
+
await Promise.all(promises);
|
|
272632
|
+
}
|
|
272453
272633
|
/**
|
|
272454
272634
|
* 获取云函数详细信息
|
|
272455
272635
|
* @param {string} name 云函数名称
|
|
@@ -272484,13 +272664,35 @@ class FunctionService {
|
|
|
272484
272664
|
}
|
|
272485
272665
|
catch (e) {
|
|
272486
272666
|
data.VpcConfig = {
|
|
272487
|
-
vpc: '',
|
|
272488
|
-
subnet: ''
|
|
272667
|
+
vpc: 'VpcId',
|
|
272668
|
+
subnet: 'SubnetId'
|
|
272489
272669
|
};
|
|
272490
272670
|
}
|
|
272491
272671
|
}
|
|
272492
272672
|
return data;
|
|
272493
272673
|
}
|
|
272674
|
+
/**
|
|
272675
|
+
* 批量获取云函数详细信息
|
|
272676
|
+
* @param {Object} options
|
|
272677
|
+
* @param {string[]} options.names 云函数名称列表
|
|
272678
|
+
* @param {string} options.envId 环境 ID
|
|
272679
|
+
* @param {string} options.codeSecret
|
|
272680
|
+
* @returns {Promise<IFunctionInfo[]>}
|
|
272681
|
+
*/
|
|
272682
|
+
async batchGetFunctionsDetail({ names, envId, codeSecret }) {
|
|
272683
|
+
const data = [];
|
|
272684
|
+
const promises = names.map(name => (async () => {
|
|
272685
|
+
try {
|
|
272686
|
+
const info = await this.getFunctionDetail(name, codeSecret);
|
|
272687
|
+
data.push(info);
|
|
272688
|
+
}
|
|
272689
|
+
catch (e) {
|
|
272690
|
+
throw new error_1.CloudBaseError(`${name} 获取信息失败:${e.message}`);
|
|
272691
|
+
}
|
|
272692
|
+
})());
|
|
272693
|
+
await Promise.all(promises);
|
|
272694
|
+
return data;
|
|
272695
|
+
}
|
|
272494
272696
|
/**
|
|
272495
272697
|
* 获取函数日志
|
|
272496
272698
|
* @deprecated 请使用 getFunctionLogsV2 代替
|
|
@@ -272587,6 +272789,33 @@ class FunctionService {
|
|
|
272587
272789
|
const res = await this.tcbService.request('GetFunctionLogDetail', params);
|
|
272588
272790
|
return res;
|
|
272589
272791
|
}
|
|
272792
|
+
/**
|
|
272793
|
+
* 获取函数的完整调用日志
|
|
272794
|
+
* 该方法会自动完成两步操作:1. 获取日志请求ID列表。 2. 根据ID列表获取每条日志的详细内容。
|
|
272795
|
+
* @param {IFunctionLogOptionsV2} options - 查询选项
|
|
272796
|
+
* @returns {Promise<IFunctionLogDetailRes[]>} 返回包含完整日志详情的数组
|
|
272797
|
+
*/
|
|
272798
|
+
async getCompleteFunctionLogs(options) {
|
|
272799
|
+
// 调用 getFunctionLogsV2 获取日志请求ID列表
|
|
272800
|
+
const { name } = options;
|
|
272801
|
+
const logs = await this.getFunctionLogsV2(options);
|
|
272802
|
+
// 如果没有日志,直接返回空数组
|
|
272803
|
+
if (logs.LogList.length === 0) {
|
|
272804
|
+
return [];
|
|
272805
|
+
}
|
|
272806
|
+
const detailPromises = logs.LogList.map(async (log) => {
|
|
272807
|
+
// 对每一个日志ID,调用 getFunctionLogDetail
|
|
272808
|
+
const res = await this.getFunctionLogDetail({
|
|
272809
|
+
logRequestId: log.RequestId,
|
|
272810
|
+
startTime: options.startTime,
|
|
272811
|
+
endTime: options.endTime
|
|
272812
|
+
});
|
|
272813
|
+
return Object.assign(Object.assign({}, res), { RetCode: log.RetCode, FunctionName: name });
|
|
272814
|
+
});
|
|
272815
|
+
// 并发执行所有详情查询,等待它们全部完成
|
|
272816
|
+
const detailedLogs = await Promise.all(detailPromises);
|
|
272817
|
+
return detailedLogs;
|
|
272818
|
+
}
|
|
272590
272819
|
/**
|
|
272591
272820
|
* 更新云函数配置
|
|
272592
272821
|
* @param {ICloudFunction} func 云函数配置
|
|
@@ -272722,6 +272951,28 @@ class FunctionService {
|
|
|
272722
272951
|
throw new error_1.CloudBaseError(`[${name}] 调用失败:\n${e.message}`);
|
|
272723
272952
|
}
|
|
272724
272953
|
}
|
|
272954
|
+
/**
|
|
272955
|
+
* 批量调用云函数
|
|
272956
|
+
* @param {IFunctionBatchOptions} options
|
|
272957
|
+
* @returns {Promise<IFunctionInvokeRes[]>}
|
|
272958
|
+
*/
|
|
272959
|
+
async batchInvokeFunctions(options) {
|
|
272960
|
+
const { functions, envId, log = false } = options;
|
|
272961
|
+
const promises = functions.map(func => (async () => {
|
|
272962
|
+
try {
|
|
272963
|
+
const result = await this.invokeFunction(func.name, func.params);
|
|
272964
|
+
if (log) {
|
|
272965
|
+
(0, utils_1.successLog)(`[${func.name}] 调用成功\n响应结果:\n`);
|
|
272966
|
+
console.log(result);
|
|
272967
|
+
}
|
|
272968
|
+
return result;
|
|
272969
|
+
}
|
|
272970
|
+
catch (e) {
|
|
272971
|
+
throw new error_1.CloudBaseError(`${func.name} 函数调用失败:${e.message}`);
|
|
272972
|
+
}
|
|
272973
|
+
})());
|
|
272974
|
+
return Promise.all(promises);
|
|
272975
|
+
}
|
|
272725
272976
|
/**
|
|
272726
272977
|
* 复制云函数
|
|
272727
272978
|
* @param {string} name 云函数名称
|
|
@@ -272764,12 +273015,34 @@ class FunctionService {
|
|
|
272764
273015
|
TriggerDesc: item.config
|
|
272765
273016
|
};
|
|
272766
273017
|
});
|
|
272767
|
-
|
|
272768
|
-
|
|
272769
|
-
|
|
272770
|
-
|
|
272771
|
-
|
|
272772
|
-
|
|
273018
|
+
try {
|
|
273019
|
+
return await this.scfService.request('BatchCreateTrigger', {
|
|
273020
|
+
FunctionName: name,
|
|
273021
|
+
Namespace: namespace,
|
|
273022
|
+
Triggers: JSON.stringify(parsedTriggers),
|
|
273023
|
+
Count: parsedTriggers.length
|
|
273024
|
+
});
|
|
273025
|
+
}
|
|
273026
|
+
catch (e) {
|
|
273027
|
+
throw new error_1.CloudBaseError(`[${name}] 创建触发器失败:${e.message}`, {
|
|
273028
|
+
action: e.action,
|
|
273029
|
+
code: e.code
|
|
273030
|
+
});
|
|
273031
|
+
}
|
|
273032
|
+
}
|
|
273033
|
+
// 批量部署函数触发器
|
|
273034
|
+
async batchCreateTriggers(options) {
|
|
273035
|
+
const { functions, envId } = options;
|
|
273036
|
+
const promises = functions.map(func => (async () => {
|
|
273037
|
+
try {
|
|
273038
|
+
await this.createFunctionTriggers(func.name, func.triggers);
|
|
273039
|
+
(0, utils_1.successLog)(`[${func.name}] 创建云函数触发器成功!`);
|
|
273040
|
+
}
|
|
273041
|
+
catch (e) {
|
|
273042
|
+
throw new error_1.CloudBaseError(e.message);
|
|
273043
|
+
}
|
|
273044
|
+
})());
|
|
273045
|
+
await Promise.all(promises);
|
|
272773
273046
|
}
|
|
272774
273047
|
/**
|
|
272775
273048
|
* 删除云函数触发器
|
|
@@ -272779,12 +273052,50 @@ class FunctionService {
|
|
|
272779
273052
|
*/
|
|
272780
273053
|
async deleteFunctionTrigger(name, triggerName) {
|
|
272781
273054
|
const { namespace } = this.getFunctionConfig();
|
|
272782
|
-
|
|
272783
|
-
|
|
272784
|
-
|
|
272785
|
-
|
|
272786
|
-
|
|
273055
|
+
try {
|
|
273056
|
+
await this.scfService.request('DeleteTrigger', {
|
|
273057
|
+
FunctionName: name,
|
|
273058
|
+
Namespace: namespace,
|
|
273059
|
+
TriggerName: triggerName,
|
|
273060
|
+
Type: 'timer'
|
|
273061
|
+
});
|
|
273062
|
+
(0, utils_1.successLog)(`[${name}] 删除云函数触发器 ${triggerName} 成功!`);
|
|
273063
|
+
}
|
|
273064
|
+
catch (e) {
|
|
273065
|
+
throw new error_1.CloudBaseError(`[${name}] 删除触发器失败:${e.message}`);
|
|
273066
|
+
}
|
|
273067
|
+
}
|
|
273068
|
+
async batchDeleteTriggers(options) {
|
|
273069
|
+
const { functions, envId } = options;
|
|
273070
|
+
const promises = functions.map(func => (async () => {
|
|
273071
|
+
try {
|
|
273072
|
+
func.triggers.forEach(async (trigger) => {
|
|
273073
|
+
await this.deleteFunctionTrigger(func.name, trigger.name);
|
|
273074
|
+
});
|
|
273075
|
+
}
|
|
273076
|
+
catch (e) {
|
|
273077
|
+
throw new error_1.CloudBaseError(e.message);
|
|
273078
|
+
}
|
|
273079
|
+
})());
|
|
273080
|
+
await Promise.all(promises);
|
|
273081
|
+
}
|
|
273082
|
+
/**
|
|
273083
|
+
* 下载云函数代码
|
|
273084
|
+
* @param {IFunctionCodeOptions} options
|
|
273085
|
+
* @returns {Promise<void>}
|
|
273086
|
+
*/
|
|
273087
|
+
async downloadFunctionCode(options) {
|
|
273088
|
+
const { destPath, envId, functionName, codeSecret } = options;
|
|
273089
|
+
// 检验路径是否存在
|
|
273090
|
+
(0, utils_1.checkFullAccess)(destPath, true);
|
|
273091
|
+
// 获取下载链接
|
|
273092
|
+
const { Url } = await this.scfService.request('GetFunctionAddress', {
|
|
273093
|
+
FunctionName: functionName,
|
|
273094
|
+
Namespace: envId,
|
|
273095
|
+
CodeSecret: codeSecret
|
|
272787
273096
|
});
|
|
273097
|
+
// 下载文件
|
|
273098
|
+
return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
|
|
272788
273099
|
}
|
|
272789
273100
|
/**
|
|
272790
273101
|
* 获取云函数代码下载 链接
|
|
@@ -272810,6 +273121,68 @@ class FunctionService {
|
|
|
272810
273121
|
throw new error_1.CloudBaseError(`[${functionName}] 获取函数代码下载链接失败:\n${e.message}`);
|
|
272811
273122
|
}
|
|
272812
273123
|
}
|
|
273124
|
+
// 函数绑定文件层
|
|
273125
|
+
async attachLayer(options) {
|
|
273126
|
+
const { envId, functionName, layerName, layerVersion, codeSecret } = options;
|
|
273127
|
+
let { Layers = [] } = await this.getFunctionDetail(functionName, codeSecret);
|
|
273128
|
+
Layers = Layers.map(item => lodash_1.default.pick(item, ['LayerName', 'LayerVersion']));
|
|
273129
|
+
// 新加的文件层添加到最后
|
|
273130
|
+
Layers.push({
|
|
273131
|
+
LayerName: layerName,
|
|
273132
|
+
LayerVersion: layerVersion
|
|
273133
|
+
});
|
|
273134
|
+
const res = await this.scfService.request('UpdateFunctionConfiguration', {
|
|
273135
|
+
Layers,
|
|
273136
|
+
Namespace: envId,
|
|
273137
|
+
FunctionName: functionName
|
|
273138
|
+
});
|
|
273139
|
+
return res;
|
|
273140
|
+
}
|
|
273141
|
+
// 函数解绑文件层
|
|
273142
|
+
async unAttachLayer(options) {
|
|
273143
|
+
const { envId, functionName, layerName, layerVersion, codeSecret } = options;
|
|
273144
|
+
let { Layers } = await this.getFunctionDetail(functionName, codeSecret);
|
|
273145
|
+
Layers = Layers.map(item => lodash_1.default.pick(item, ['LayerName', 'LayerVersion']));
|
|
273146
|
+
const index = Layers.findIndex(item => item.LayerName === layerName && item.LayerVersion === layerVersion);
|
|
273147
|
+
if (index === -1) {
|
|
273148
|
+
throw new error_1.CloudBaseError('层不存在');
|
|
273149
|
+
}
|
|
273150
|
+
// 删除指定的层
|
|
273151
|
+
Layers.splice(index, 1);
|
|
273152
|
+
const apiParams = {
|
|
273153
|
+
Namespace: envId,
|
|
273154
|
+
FunctionName: functionName,
|
|
273155
|
+
Layers: Layers.length > 0 ? Layers : [{
|
|
273156
|
+
LayerName: '',
|
|
273157
|
+
LayerVersion: 0
|
|
273158
|
+
}]
|
|
273159
|
+
};
|
|
273160
|
+
return this.scfService.request('UpdateFunctionConfiguration', apiParams);
|
|
273161
|
+
}
|
|
273162
|
+
// 更新云函数层
|
|
273163
|
+
async updateFunctionLayer(options) {
|
|
273164
|
+
const { envId, functionName, layers } = options;
|
|
273165
|
+
return this.scfService.request('UpdateFunctionConfiguration', {
|
|
273166
|
+
Layers: layers,
|
|
273167
|
+
Namespace: envId,
|
|
273168
|
+
FunctionName: functionName
|
|
273169
|
+
});
|
|
273170
|
+
}
|
|
273171
|
+
// 下载文件层 ZIP 文件
|
|
273172
|
+
async downloadLayer(options) {
|
|
273173
|
+
const { name, version, destPath } = options;
|
|
273174
|
+
const res = await this.scfService.request('GetLayerVersion', {
|
|
273175
|
+
LayerName: name,
|
|
273176
|
+
LayerVersion: version
|
|
273177
|
+
});
|
|
273178
|
+
const url = res === null || res === void 0 ? void 0 : res.Location;
|
|
273179
|
+
const zipPath = path_1.default.join(destPath, `${name}-${version}.zip`);
|
|
273180
|
+
if ((0, utils_1.checkFullAccess)(zipPath)) {
|
|
273181
|
+
throw new error_1.CloudBaseError(`文件已存在:${zipPath}`);
|
|
273182
|
+
}
|
|
273183
|
+
// 下载文件
|
|
273184
|
+
return (0, utils_1.downloadAndExtractRemoteZip)(url, destPath);
|
|
273185
|
+
}
|
|
272813
273186
|
// 创建文件层版本
|
|
272814
273187
|
async createLayer(options) {
|
|
272815
273188
|
const { env } = this.getFunctionConfig();
|
|
@@ -272882,7 +273255,7 @@ class FunctionService {
|
|
|
272882
273255
|
Limit: limit,
|
|
272883
273256
|
Offset: offset,
|
|
272884
273257
|
SearchKey: searchKey,
|
|
272885
|
-
SearchSrc: `TCB_${env}`
|
|
273258
|
+
// SearchSrc: `TCB_${env}`
|
|
272886
273259
|
};
|
|
272887
273260
|
if (runtime) {
|
|
272888
273261
|
param.CompatibleRuntime = runtime;
|
|
@@ -273211,12 +273584,18 @@ __decorate([
|
|
|
273211
273584
|
__decorate([
|
|
273212
273585
|
(0, utils_1.preLazy)()
|
|
273213
273586
|
], FunctionService.prototype, "listFunctions", null);
|
|
273587
|
+
__decorate([
|
|
273588
|
+
(0, utils_1.preLazy)()
|
|
273589
|
+
], FunctionService.prototype, "listAllFunctions", null);
|
|
273214
273590
|
__decorate([
|
|
273215
273591
|
(0, utils_1.preLazy)()
|
|
273216
273592
|
], FunctionService.prototype, "deleteFunction", null);
|
|
273217
273593
|
__decorate([
|
|
273218
273594
|
(0, utils_1.preLazy)()
|
|
273219
273595
|
], FunctionService.prototype, "getFunctionDetail", null);
|
|
273596
|
+
__decorate([
|
|
273597
|
+
(0, utils_1.preLazy)()
|
|
273598
|
+
], FunctionService.prototype, "batchGetFunctionsDetail", null);
|
|
273220
273599
|
__decorate([
|
|
273221
273600
|
(0, utils_1.preLazy)()
|
|
273222
273601
|
], FunctionService.prototype, "getFunctionLogs", null);
|
|
@@ -273226,6 +273605,9 @@ __decorate([
|
|
|
273226
273605
|
__decorate([
|
|
273227
273606
|
(0, utils_1.preLazy)()
|
|
273228
273607
|
], FunctionService.prototype, "getFunctionLogDetail", null);
|
|
273608
|
+
__decorate([
|
|
273609
|
+
(0, utils_1.preLazy)()
|
|
273610
|
+
], FunctionService.prototype, "getCompleteFunctionLogs", null);
|
|
273229
273611
|
__decorate([
|
|
273230
273612
|
(0, utils_1.preLazy)()
|
|
273231
273613
|
], FunctionService.prototype, "updateFunctionConfig", null);
|
|
@@ -273235,6 +273617,9 @@ __decorate([
|
|
|
273235
273617
|
__decorate([
|
|
273236
273618
|
(0, utils_1.preLazy)()
|
|
273237
273619
|
], FunctionService.prototype, "invokeFunction", null);
|
|
273620
|
+
__decorate([
|
|
273621
|
+
(0, utils_1.preLazy)()
|
|
273622
|
+
], FunctionService.prototype, "batchInvokeFunctions", null);
|
|
273238
273623
|
__decorate([
|
|
273239
273624
|
(0, utils_1.preLazy)()
|
|
273240
273625
|
], FunctionService.prototype, "copyFunction", null);
|
|
@@ -273247,6 +273632,18 @@ __decorate([
|
|
|
273247
273632
|
__decorate([
|
|
273248
273633
|
(0, utils_1.preLazy)()
|
|
273249
273634
|
], FunctionService.prototype, "getFunctionDownloadUrl", null);
|
|
273635
|
+
__decorate([
|
|
273636
|
+
(0, utils_1.preLazy)()
|
|
273637
|
+
], FunctionService.prototype, "attachLayer", null);
|
|
273638
|
+
__decorate([
|
|
273639
|
+
(0, utils_1.preLazy)()
|
|
273640
|
+
], FunctionService.prototype, "unAttachLayer", null);
|
|
273641
|
+
__decorate([
|
|
273642
|
+
(0, utils_1.preLazy)()
|
|
273643
|
+
], FunctionService.prototype, "updateFunctionLayer", null);
|
|
273644
|
+
__decorate([
|
|
273645
|
+
(0, utils_1.preLazy)()
|
|
273646
|
+
], FunctionService.prototype, "downloadLayer", null);
|
|
273250
273647
|
__decorate([
|
|
273251
273648
|
(0, utils_1.preLazy)()
|
|
273252
273649
|
], FunctionService.prototype, "createLayer", null);
|