@cloudbase/cloudbase-mcp 2.0.6 → 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 +837 -189
- package/dist/index.cjs +837 -189
- package/dist/index.js +426 -153
- 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
|
}
|
|
@@ -38331,7 +38397,7 @@ function registerSQLDatabaseTools(server) {
|
|
|
38331
38397
|
// executeReadOnlySQL
|
|
38332
38398
|
server.registerTool?.("executeReadOnlySQL", {
|
|
38333
38399
|
title: "Execute read-only SQL query",
|
|
38334
|
-
description: "Execute a read-only SQL query on the SQL database. Note: For per-user ACL, each table should contain a fixed `_openid` column that represents the user and is used for access control.",
|
|
38400
|
+
description: "Execute a read-only SQL query on the SQL database. Note: For per-user ACL, each table should contain a fixed `_openid` column defined as `_openid VARCHAR(64) DEFAULT '' NOT NULL` that represents the user and is used for access control.",
|
|
38335
38401
|
inputSchema: {
|
|
38336
38402
|
sql: zod_1.z.string().describe("SQL query statement (SELECT queries only)"),
|
|
38337
38403
|
},
|
|
@@ -38390,7 +38456,7 @@ function registerSQLDatabaseTools(server) {
|
|
|
38390
38456
|
// executeWriteSQL
|
|
38391
38457
|
server.registerTool?.("executeWriteSQL", {
|
|
38392
38458
|
title: "Execute write SQL statement",
|
|
38393
|
-
description: "Execute a write SQL statement on the SQL database (INSERT, UPDATE, DELETE, etc.). Whenever you create a new table, you **must**
|
|
38459
|
+
description: "Execute a write SQL statement on the SQL database (INSERT, UPDATE, DELETE, etc.). Whenever you create a new table, you **must** include a fixed `_openid` column defined as `_openid VARCHAR(64) DEFAULT '' NOT NULL` that represents the user and is used for access control.",
|
|
38394
38460
|
inputSchema: {
|
|
38395
38461
|
sql: zod_1.z
|
|
38396
38462
|
.string()
|
|
@@ -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);
|
|
@@ -100307,12 +100374,14 @@ const rag_js_1 = __webpack_require__(64215);
|
|
|
100307
100374
|
const setup_js_1 = __webpack_require__(76556);
|
|
100308
100375
|
const storage_js_1 = __webpack_require__(94848);
|
|
100309
100376
|
// import { registerMiniprogramTools } from "./tools/miniprogram.js";
|
|
100377
|
+
const types_js_1 = __webpack_require__(1294);
|
|
100310
100378
|
const cloudrun_js_1 = __webpack_require__(35023);
|
|
100311
100379
|
const dataModel_js_1 = __webpack_require__(34052);
|
|
100312
100380
|
const gateway_js_1 = __webpack_require__(84319);
|
|
100313
100381
|
const invite_code_js_1 = __webpack_require__(44760);
|
|
100314
100382
|
const security_rule_js_1 = __webpack_require__(7862);
|
|
100315
100383
|
const cloud_mode_js_1 = __webpack_require__(89684);
|
|
100384
|
+
const logger_js_1 = __webpack_require__(13039);
|
|
100316
100385
|
const tool_wrapper_js_1 = __webpack_require__(71363);
|
|
100317
100386
|
// 默认插件列表
|
|
100318
100387
|
const DEFAULT_PLUGINS = [
|
|
@@ -100413,6 +100482,13 @@ async function createCloudBaseMcpServer(options) {
|
|
|
100413
100482
|
...(ide === "CodeBuddy" ? { logging: {} } : {}),
|
|
100414
100483
|
},
|
|
100415
100484
|
});
|
|
100485
|
+
// Only set logging handler if logging capability is declared
|
|
100486
|
+
if (ide === "CodeBuddy") {
|
|
100487
|
+
server.server.setRequestHandler(types_js_1.SetLevelRequestSchema, (request, extra) => {
|
|
100488
|
+
(0, logger_js_1.info)(`--- Logging level: ${request.params.level}`);
|
|
100489
|
+
return {};
|
|
100490
|
+
});
|
|
100491
|
+
}
|
|
100416
100492
|
// Store cloudBaseOptions in server instance for tools to access
|
|
100417
100493
|
if (cloudBaseOptions) {
|
|
100418
100494
|
server.cloudBaseOptions = cloudBaseOptions;
|
|
@@ -100443,10 +100519,10 @@ function getDefaultServer() {
|
|
|
100443
100519
|
}
|
|
100444
100520
|
var stdio_js_1 = __webpack_require__(6166);
|
|
100445
100521
|
Object.defineProperty(exports, "StdioServerTransport", ({ enumerable: true, get: function () { return stdio_js_1.StdioServerTransport; } }));
|
|
100446
|
-
var
|
|
100447
|
-
Object.defineProperty(exports, "error", ({ enumerable: true, get: function () { return
|
|
100448
|
-
Object.defineProperty(exports, "info", ({ enumerable: true, get: function () { return
|
|
100449
|
-
Object.defineProperty(exports, "warn", ({ enumerable: true, get: function () { return
|
|
100522
|
+
var logger_js_2 = __webpack_require__(13039);
|
|
100523
|
+
Object.defineProperty(exports, "error", ({ enumerable: true, get: function () { return logger_js_2.error; } }));
|
|
100524
|
+
Object.defineProperty(exports, "info", ({ enumerable: true, get: function () { return logger_js_2.info; } }));
|
|
100525
|
+
Object.defineProperty(exports, "warn", ({ enumerable: true, get: function () { return logger_js_2.warn; } }));
|
|
100450
100526
|
var telemetry_js_1 = __webpack_require__(45880);
|
|
100451
100527
|
Object.defineProperty(exports, "reportToolCall", ({ enumerable: true, get: function () { return telemetry_js_1.reportToolCall; } }));
|
|
100452
100528
|
Object.defineProperty(exports, "reportToolkitLifecycle", ({ enumerable: true, get: function () { return telemetry_js_1.reportToolkitLifecycle; } }));
|
|
@@ -101892,6 +101968,53 @@ class AsyncReader extends reader_1.default {
|
|
|
101892
101968
|
exports["default"] = AsyncReader;
|
|
101893
101969
|
|
|
101894
101970
|
|
|
101971
|
+
/***/ }),
|
|
101972
|
+
|
|
101973
|
+
/***/ 32720:
|
|
101974
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
101975
|
+
|
|
101976
|
+
"use strict";
|
|
101977
|
+
|
|
101978
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
101979
|
+
exports.sendDeployNotification = sendDeployNotification;
|
|
101980
|
+
const logger_js_1 = __webpack_require__(13039);
|
|
101981
|
+
/**
|
|
101982
|
+
* Send deployment notification to CodeBuddy IDE
|
|
101983
|
+
* @param server ExtendedMcpServer instance
|
|
101984
|
+
* @param notificationData Deployment notification data
|
|
101985
|
+
*/
|
|
101986
|
+
async function sendDeployNotification(server, notificationData) {
|
|
101987
|
+
// Check if current IDE is CodeBuddy (prefer server.ide, fallback to environment variable)
|
|
101988
|
+
const currentIde = server.ide || process.env.INTEGRATION_IDE;
|
|
101989
|
+
if (currentIde !== 'CodeBuddy' || !server.server) {
|
|
101990
|
+
// Not CodeBuddy IDE, skip notification
|
|
101991
|
+
return;
|
|
101992
|
+
}
|
|
101993
|
+
try {
|
|
101994
|
+
// Send notification using sendLoggingMessage
|
|
101995
|
+
server.server.sendLoggingMessage({
|
|
101996
|
+
level: "notice",
|
|
101997
|
+
data: {
|
|
101998
|
+
type: "tcb",
|
|
101999
|
+
event: "deploy",
|
|
102000
|
+
data: {
|
|
102001
|
+
type: notificationData.deployType, // "hosting" or "cloudrun"
|
|
102002
|
+
url: notificationData.url,
|
|
102003
|
+
projectId: notificationData.projectId,
|
|
102004
|
+
projectName: notificationData.projectName,
|
|
102005
|
+
consoleUrl: notificationData.consoleUrl
|
|
102006
|
+
}
|
|
102007
|
+
}
|
|
102008
|
+
});
|
|
102009
|
+
(0, logger_js_1.info)(`CodeBuddy IDE: 已发送部署通知 - ${notificationData.deployType} - ${notificationData.url}`);
|
|
102010
|
+
}
|
|
102011
|
+
catch (err) {
|
|
102012
|
+
// Log error but don't throw - notification failure should not affect deployment flow
|
|
102013
|
+
(0, logger_js_1.error)(`Failed to send deployment notification: ${err instanceof Error ? err.message : err}`, err);
|
|
102014
|
+
}
|
|
102015
|
+
}
|
|
102016
|
+
|
|
102017
|
+
|
|
101895
102018
|
/***/ }),
|
|
101896
102019
|
|
|
101897
102020
|
/***/ 32923:
|
|
@@ -110205,6 +110328,7 @@ const fs_1 = __importDefault(__webpack_require__(29021));
|
|
|
110205
110328
|
const path_1 = __importDefault(__webpack_require__(39902));
|
|
110206
110329
|
const zod_1 = __webpack_require__(21614);
|
|
110207
110330
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
110331
|
+
const notification_js_1 = __webpack_require__(32720);
|
|
110208
110332
|
// CloudRun service types
|
|
110209
110333
|
exports.CLOUDRUN_SERVICE_TYPES = ['function', 'container'];
|
|
110210
110334
|
// CloudRun access types
|
|
@@ -110709,6 +110833,58 @@ for await (let x of res.textStream) {
|
|
|
110709
110833
|
catch (error) {
|
|
110710
110834
|
// Ignore cloudbaserc.json creation errors
|
|
110711
110835
|
}
|
|
110836
|
+
// Send deployment notification to CodeBuddy IDE
|
|
110837
|
+
try {
|
|
110838
|
+
// Query service details to get access URL
|
|
110839
|
+
let serviceUrl = "";
|
|
110840
|
+
try {
|
|
110841
|
+
const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
|
|
110842
|
+
// Extract access URL from service details
|
|
110843
|
+
// Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
|
|
110844
|
+
const details = serviceDetails; // Use any to access dynamic properties
|
|
110845
|
+
if (details?.BaseInfo?.DefaultDomainName) {
|
|
110846
|
+
// DefaultDomainName is already a complete URL (e.g., https://...)
|
|
110847
|
+
serviceUrl = details.BaseInfo.DefaultDomainName;
|
|
110848
|
+
}
|
|
110849
|
+
else if (details?.BaseInfo?.CustomDomainName) {
|
|
110850
|
+
// CustomDomainName might be a domain without protocol
|
|
110851
|
+
const customDomain = details.BaseInfo.CustomDomainName;
|
|
110852
|
+
serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
|
|
110853
|
+
}
|
|
110854
|
+
else if (details?.BaseInfo?.PublicDomain) {
|
|
110855
|
+
serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
|
|
110856
|
+
}
|
|
110857
|
+
else if (details?.BaseInfo?.InternalDomain) {
|
|
110858
|
+
serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
|
|
110859
|
+
}
|
|
110860
|
+
else if (details?.AccessInfo?.PublicDomain) {
|
|
110861
|
+
serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
|
|
110862
|
+
}
|
|
110863
|
+
else {
|
|
110864
|
+
serviceUrl = ""; // URL not available
|
|
110865
|
+
}
|
|
110866
|
+
}
|
|
110867
|
+
catch (detailErr) {
|
|
110868
|
+
// If query fails, continue with empty URL
|
|
110869
|
+
serviceUrl = "";
|
|
110870
|
+
}
|
|
110871
|
+
// Extract project name from targetPath
|
|
110872
|
+
const projectName = path_1.default.basename(targetPath);
|
|
110873
|
+
// Build console URL
|
|
110874
|
+
const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
|
|
110875
|
+
// Send notification
|
|
110876
|
+
await (0, notification_js_1.sendDeployNotification)(server, {
|
|
110877
|
+
deployType: 'cloudrun',
|
|
110878
|
+
url: serviceUrl,
|
|
110879
|
+
projectId: currentEnvId,
|
|
110880
|
+
projectName: projectName,
|
|
110881
|
+
consoleUrl: consoleUrl
|
|
110882
|
+
});
|
|
110883
|
+
}
|
|
110884
|
+
catch (notifyErr) {
|
|
110885
|
+
// Notification failure should not affect deployment flow
|
|
110886
|
+
// Error is already logged in sendDeployNotification
|
|
110887
|
+
}
|
|
110712
110888
|
return {
|
|
110713
110889
|
content: [
|
|
110714
110890
|
{
|
|
@@ -114885,14 +115061,20 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) {
|
|
|
114885
115061
|
/***/ }),
|
|
114886
115062
|
|
|
114887
115063
|
/***/ 37279:
|
|
114888
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__)
|
|
115064
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
114889
115065
|
|
|
114890
115066
|
"use strict";
|
|
114891
115067
|
|
|
115068
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
115069
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
115070
|
+
};
|
|
114892
115071
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
114893
115072
|
exports.registerHostingTools = registerHostingTools;
|
|
115073
|
+
const fs_1 = __importDefault(__webpack_require__(29021));
|
|
115074
|
+
const path_1 = __importDefault(__webpack_require__(39902));
|
|
114894
115075
|
const zod_1 = __webpack_require__(21614);
|
|
114895
115076
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
115077
|
+
const notification_js_1 = __webpack_require__(32720);
|
|
114896
115078
|
function registerHostingTools(server) {
|
|
114897
115079
|
// 获取 cloudBaseOptions,如果没有则为 undefined
|
|
114898
115080
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
@@ -114929,6 +115111,43 @@ function registerHostingTools(server) {
|
|
|
114929
115111
|
// 获取环境信息
|
|
114930
115112
|
const envInfo = await cloudbase.env.getEnvInfo();
|
|
114931
115113
|
const staticDomain = envInfo.EnvInfo?.StaticStorages?.[0]?.StaticDomain;
|
|
115114
|
+
const accessUrl = staticDomain ? `https://${staticDomain}/${cloudPath || ''}` : "";
|
|
115115
|
+
// Send deployment notification to CodeBuddy IDE
|
|
115116
|
+
try {
|
|
115117
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
115118
|
+
// Extract project name from localPath
|
|
115119
|
+
let projectName = "unknown";
|
|
115120
|
+
if (localPath) {
|
|
115121
|
+
try {
|
|
115122
|
+
// If localPath is a file, get parent directory name; if it's a directory, get directory name
|
|
115123
|
+
const stats = fs_1.default.statSync(localPath);
|
|
115124
|
+
if (stats.isFile()) {
|
|
115125
|
+
projectName = path_1.default.basename(path_1.default.dirname(localPath));
|
|
115126
|
+
}
|
|
115127
|
+
else {
|
|
115128
|
+
projectName = path_1.default.basename(localPath);
|
|
115129
|
+
}
|
|
115130
|
+
}
|
|
115131
|
+
catch (statErr) {
|
|
115132
|
+
// If stat fails, try to extract from path directly
|
|
115133
|
+
projectName = path_1.default.basename(localPath);
|
|
115134
|
+
}
|
|
115135
|
+
}
|
|
115136
|
+
// Build console URL
|
|
115137
|
+
const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${envId}#/static-hosting`;
|
|
115138
|
+
// Send notification
|
|
115139
|
+
await (0, notification_js_1.sendDeployNotification)(server, {
|
|
115140
|
+
deployType: 'hosting',
|
|
115141
|
+
url: accessUrl,
|
|
115142
|
+
projectId: envId,
|
|
115143
|
+
projectName: projectName,
|
|
115144
|
+
consoleUrl: consoleUrl
|
|
115145
|
+
});
|
|
115146
|
+
}
|
|
115147
|
+
catch (notifyErr) {
|
|
115148
|
+
// Notification failure should not affect deployment flow
|
|
115149
|
+
// Error is already logged in sendDeployNotification
|
|
115150
|
+
}
|
|
114932
115151
|
return {
|
|
114933
115152
|
content: [
|
|
114934
115153
|
{
|
|
@@ -114937,7 +115156,7 @@ function registerHostingTools(server) {
|
|
|
114937
115156
|
...result,
|
|
114938
115157
|
staticDomain,
|
|
114939
115158
|
message: "文件上传成功",
|
|
114940
|
-
accessUrl:
|
|
115159
|
+
accessUrl: accessUrl
|
|
114941
115160
|
}, null, 2)
|
|
114942
115161
|
}
|
|
114943
115162
|
]
|
|
@@ -134865,7 +135084,7 @@ class TelemetryReporter {
|
|
|
134865
135084
|
const nodeVersion = process.version; // Node.js版本
|
|
134866
135085
|
const arch = os_1.default.arch(); // 系统架构
|
|
134867
135086
|
// 从构建时注入的版本号获取MCP版本信息
|
|
134868
|
-
const mcpVersion = process.env.npm_package_version || "2.0.
|
|
135087
|
+
const mcpVersion = process.env.npm_package_version || "2.2.0-alpha.0" || 0;
|
|
134869
135088
|
return {
|
|
134870
135089
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
134871
135090
|
deviceId: this.deviceId,
|
|
@@ -179463,6 +179682,7 @@ exports.sleep = sleep;
|
|
|
179463
179682
|
exports.upperCaseStringFisrt = upperCaseStringFisrt;
|
|
179464
179683
|
exports.upperCaseObjKey = upperCaseObjKey;
|
|
179465
179684
|
exports.fetchTemplates = fetchTemplates;
|
|
179685
|
+
exports.successLog = successLog;
|
|
179466
179686
|
const archiver_1 = __importDefault(__webpack_require__(99133));
|
|
179467
179687
|
const crypto_1 = __importDefault(__webpack_require__(55511));
|
|
179468
179688
|
const fs_extra_1 = __importDefault(__webpack_require__(21605));
|
|
@@ -179741,6 +179961,10 @@ const getCompleteTimeRange = (timeRange) => {
|
|
|
179741
179961
|
};
|
|
179742
179962
|
};
|
|
179743
179963
|
exports.getCompleteTimeRange = getCompleteTimeRange;
|
|
179964
|
+
function successLog(msg) {
|
|
179965
|
+
// 空格,兼容中文字符编码长度问题
|
|
179966
|
+
console.log(`${msg}`);
|
|
179967
|
+
}
|
|
179744
179968
|
|
|
179745
179969
|
|
|
179746
179970
|
/***/ }),
|
|
@@ -185531,6 +185755,7 @@ async function registerRagTools(server) {
|
|
|
185531
185755
|
}
|
|
185532
185756
|
});
|
|
185533
185757
|
let skills = [];
|
|
185758
|
+
let openapis = [];
|
|
185534
185759
|
// 知识库检索
|
|
185535
185760
|
try {
|
|
185536
185761
|
skills = await prepareKnowledgeBaseWebTemplate();
|
|
@@ -185540,22 +185765,40 @@ async function registerRagTools(server) {
|
|
|
185540
185765
|
error,
|
|
185541
185766
|
});
|
|
185542
185767
|
}
|
|
185768
|
+
// OpenAPI 文档准备
|
|
185769
|
+
try {
|
|
185770
|
+
openapis = await prepareOpenAPIDocs();
|
|
185771
|
+
}
|
|
185772
|
+
catch (error) {
|
|
185773
|
+
(0, logger_js_1.warn)("[searchKnowledgeBase] Failed to prepare OpenAPI docs", {
|
|
185774
|
+
error,
|
|
185775
|
+
});
|
|
185776
|
+
}
|
|
185543
185777
|
server.registerTool?.("searchKnowledgeBase", {
|
|
185544
185778
|
title: "云开发知识库检索",
|
|
185545
|
-
description: `云开发知识库智能检索工具,支持向量查询 (vector)
|
|
185779
|
+
description: `云开发知识库智能检索工具,支持向量查询 (vector)、固定文档 (doc) 和 OpenAPI 文档 (openapi) 查询。
|
|
185546
185780
|
|
|
185547
|
-
强烈推荐始终优先使用固定文档 (doc) 模式进行检索,仅当固定文档无法覆盖你的问题时,再使用向量查询 (vector) 模式。
|
|
185781
|
+
强烈推荐始终优先使用固定文档 (doc) 或 OpenAPI 文档 (openapi) 模式进行检索,仅当固定文档无法覆盖你的问题时,再使用向量查询 (vector) 模式。
|
|
185548
185782
|
|
|
185549
185783
|
固定文档 (doc) 查询当前支持 ${skills.length} 个固定文档,分别是:
|
|
185550
185784
|
${skills
|
|
185551
185785
|
.map((skill) => `文档名:${path.basename(path.dirname(skill.absolutePath))} 文档介绍:${skill.description}`)
|
|
185786
|
+
.join("\n")}
|
|
185787
|
+
|
|
185788
|
+
OpenAPI 文档 (openapi) 查询当前支持 ${openapis.length} 个 API 文档,分别是:
|
|
185789
|
+
${openapis
|
|
185790
|
+
.map((api) => `API名:${api.name} API介绍:${api.description}`)
|
|
185552
185791
|
.join("\n")}`,
|
|
185553
185792
|
inputSchema: {
|
|
185554
|
-
mode: zod_1.z.enum(["vector", "doc"]),
|
|
185793
|
+
mode: zod_1.z.enum(["vector", "doc", "openapi"]),
|
|
185555
185794
|
docName: zod_1.z
|
|
185556
185795
|
.enum(skills.map((skill) => path.basename(path.dirname(skill.absolutePath))))
|
|
185557
185796
|
.optional()
|
|
185558
185797
|
.describe("mode=doc 时指定。文档名称。"),
|
|
185798
|
+
apiName: zod_1.z
|
|
185799
|
+
.enum(openapis.map((api) => api.name))
|
|
185800
|
+
.optional()
|
|
185801
|
+
.describe("mode=openapi 时指定。API 名称。"),
|
|
185559
185802
|
threshold: zod_1.z
|
|
185560
185803
|
.number()
|
|
185561
185804
|
.default(0.5)
|
|
@@ -185585,7 +185828,7 @@ async function registerRagTools(server) {
|
|
|
185585
185828
|
openWorldHint: true,
|
|
185586
185829
|
category: "rag",
|
|
185587
185830
|
},
|
|
185588
|
-
}, async ({ id, content, options: { chunkExpand = [3, 3] } = {}, limit = 5, threshold = 0.5, mode, docName, }) => {
|
|
185831
|
+
}, async ({ id, content, options: { chunkExpand = [3, 3] } = {}, limit = 5, threshold = 0.5, mode, docName, apiName, }) => {
|
|
185589
185832
|
if (mode === "doc") {
|
|
185590
185833
|
const absolutePath = skills.find((skill) => skill.absolutePath.includes(docName)).absolutePath;
|
|
185591
185834
|
return {
|
|
@@ -185597,6 +185840,27 @@ async function registerRagTools(server) {
|
|
|
185597
185840
|
],
|
|
185598
185841
|
};
|
|
185599
185842
|
}
|
|
185843
|
+
if (mode === "openapi") {
|
|
185844
|
+
const api = openapis.find((api) => api.name === apiName);
|
|
185845
|
+
if (!api) {
|
|
185846
|
+
return {
|
|
185847
|
+
content: [
|
|
185848
|
+
{
|
|
185849
|
+
type: "text",
|
|
185850
|
+
text: `OpenAPI document "${apiName}" not found. Available APIs: ${openapis.map((a) => a.name).join(", ")}`,
|
|
185851
|
+
},
|
|
185852
|
+
],
|
|
185853
|
+
};
|
|
185854
|
+
}
|
|
185855
|
+
return {
|
|
185856
|
+
content: [
|
|
185857
|
+
{
|
|
185858
|
+
type: "text",
|
|
185859
|
+
text: `OpenAPI document: ${api.name}\nDescription: ${api.description}\nPath: ${api.absolutePath}\n\n${(await fs.readFile(api.absolutePath)).toString()}`,
|
|
185860
|
+
},
|
|
185861
|
+
],
|
|
185862
|
+
};
|
|
185863
|
+
}
|
|
185600
185864
|
// 枚举到后端 id 映射
|
|
185601
185865
|
const backendId = KnowledgeBaseIdMap[id] || id;
|
|
185602
185866
|
const signInRes = await fetch("https://tcb-advanced-a656fc.api.tcloudbasegateway.com/auth/v1/signin/anonymously", {
|
|
@@ -185673,6 +185937,65 @@ function extractDescriptionFromFrontMatter(content) {
|
|
|
185673
185937
|
.match(/^(?:decsription|description)\s*:\s*(.*)$/m);
|
|
185674
185938
|
return match ? match[1].trim() : null;
|
|
185675
185939
|
}
|
|
185940
|
+
// OpenAPI 文档 URL 列表
|
|
185941
|
+
const OPENAPI_SOURCES = [
|
|
185942
|
+
{
|
|
185943
|
+
name: "mysqldb",
|
|
185944
|
+
description: "MySQL RESTful API - 云开发 MySQL 数据库 HTTP API",
|
|
185945
|
+
url: "https://docs.cloudbase.net/openapi/mysqldb.v1.openapi.yaml",
|
|
185946
|
+
},
|
|
185947
|
+
{
|
|
185948
|
+
name: "functions",
|
|
185949
|
+
description: "Cloud Functions API - 云函数 HTTP API",
|
|
185950
|
+
url: "https://docs.cloudbase.net/openapi/functions.v1.openapi.yaml",
|
|
185951
|
+
},
|
|
185952
|
+
{
|
|
185953
|
+
name: "auth",
|
|
185954
|
+
description: "Authentication API - 身份认证 HTTP API",
|
|
185955
|
+
url: "https://docs.cloudbase.net/openapi/auth.v1.openapi.yaml",
|
|
185956
|
+
},
|
|
185957
|
+
{
|
|
185958
|
+
name: "cloudrun",
|
|
185959
|
+
description: "CloudRun API - 云托管服务 HTTP API",
|
|
185960
|
+
url: "https://docs.cloudbase.net/openapi/cloudrun.v1.openapi.yaml",
|
|
185961
|
+
},
|
|
185962
|
+
{
|
|
185963
|
+
name: "storage",
|
|
185964
|
+
description: "Storage API - 云存储 HTTP API",
|
|
185965
|
+
url: "https://docs.cloudbase.net/openapi/storage.v1.openapi.yaml",
|
|
185966
|
+
},
|
|
185967
|
+
];
|
|
185968
|
+
// 下载并准备 OpenAPI 文档
|
|
185969
|
+
async function prepareOpenAPIDocs() {
|
|
185970
|
+
const baseDir = path.join(os.homedir(), ".cloudbase-mcp", "openapi");
|
|
185971
|
+
await fs.mkdir(baseDir, { recursive: true });
|
|
185972
|
+
const results = [];
|
|
185973
|
+
await Promise.all(OPENAPI_SOURCES.map(async (source) => {
|
|
185974
|
+
try {
|
|
185975
|
+
const response = await fetch(source.url);
|
|
185976
|
+
if (!response.ok) {
|
|
185977
|
+
(0, logger_js_1.warn)(`[prepareOpenAPIDocs] Failed to download ${source.name}`, {
|
|
185978
|
+
status: response.status,
|
|
185979
|
+
});
|
|
185980
|
+
return;
|
|
185981
|
+
}
|
|
185982
|
+
const content = await response.text();
|
|
185983
|
+
const filePath = path.join(baseDir, `${source.name}.openapi.yaml`);
|
|
185984
|
+
await fs.writeFile(filePath, content, "utf8");
|
|
185985
|
+
results.push({
|
|
185986
|
+
name: source.name,
|
|
185987
|
+
description: source.description,
|
|
185988
|
+
absolutePath: filePath,
|
|
185989
|
+
});
|
|
185990
|
+
}
|
|
185991
|
+
catch (error) {
|
|
185992
|
+
(0, logger_js_1.warn)(`[prepareOpenAPIDocs] Failed to download ${source.name}`, {
|
|
185993
|
+
error,
|
|
185994
|
+
});
|
|
185995
|
+
}
|
|
185996
|
+
}));
|
|
185997
|
+
return results;
|
|
185998
|
+
}
|
|
185676
185999
|
async function collectSkillDescriptions(rootDir) {
|
|
185677
186000
|
const result = [];
|
|
185678
186001
|
async function walk(dir) {
|
|
@@ -190970,20 +191293,25 @@ function callSuccessCallback(callback, result) {
|
|
|
190970
191293
|
/***/ }),
|
|
190971
191294
|
|
|
190972
191295
|
/***/ 65607:
|
|
190973
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
191296
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
190974
191297
|
|
|
190975
191298
|
"use strict";
|
|
190976
191299
|
|
|
190977
191300
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
190978
191301
|
exports.CloudBaseContext = void 0;
|
|
191302
|
+
const constant_1 = __webpack_require__(40762);
|
|
190979
191303
|
class CloudBaseContext {
|
|
190980
|
-
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
|
|
191304
|
+
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined }) {
|
|
190981
191305
|
this.secretId = secretId;
|
|
190982
191306
|
this.secretKey = secretKey;
|
|
190983
191307
|
this.token = token;
|
|
190984
191308
|
this.proxy = proxy;
|
|
190985
191309
|
this.region = region;
|
|
190986
191310
|
this.envType = envType;
|
|
191311
|
+
this.useInternalEndpoint = useInternalEndpoint;
|
|
191312
|
+
}
|
|
191313
|
+
isInternalEndpoint() {
|
|
191314
|
+
return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
|
|
190987
191315
|
}
|
|
190988
191316
|
}
|
|
190989
191317
|
exports.CloudBaseContext = CloudBaseContext;
|
|
@@ -200510,7 +200838,7 @@ ${envIdSection}
|
|
|
200510
200838
|
## 环境信息
|
|
200511
200839
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
200512
200840
|
- Node.js版本: ${process.version}
|
|
200513
|
-
- MCP 版本:${process.env.npm_package_version || "2.0.
|
|
200841
|
+
- MCP 版本:${process.env.npm_package_version || "2.2.0-alpha.0" || 0}
|
|
200514
200842
|
- 系统架构: ${os_1.default.arch()}
|
|
200515
200843
|
- 时间: ${new Date().toISOString()}
|
|
200516
200844
|
- 请求ID: ${requestId}
|
|
@@ -203402,6 +203730,7 @@ class StorageService {
|
|
|
203402
203730
|
* 获取 COS 配置
|
|
203403
203731
|
*/
|
|
203404
203732
|
getCos(parallel = 20) {
|
|
203733
|
+
const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
|
|
203405
203734
|
const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
|
|
203406
203735
|
const cosProxy = process.env.TCB_COS_PROXY;
|
|
203407
203736
|
const cosConfig = {
|
|
@@ -203410,14 +203739,14 @@ class StorageService {
|
|
|
203410
203739
|
SecretKey: secretKey,
|
|
203411
203740
|
Proxy: cosProxy || proxy,
|
|
203412
203741
|
SecurityToken: token,
|
|
203413
|
-
Domain:
|
|
203742
|
+
Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
|
|
203414
203743
|
};
|
|
203415
203744
|
if (constant_1.COS_SDK_PROTOCOL) {
|
|
203416
203745
|
cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
|
|
203417
203746
|
? constant_1.COS_SDK_PROTOCOL.toLowerCase()
|
|
203418
203747
|
: constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
|
|
203419
203748
|
}
|
|
203420
|
-
if (
|
|
203749
|
+
if (internalEndpoint) {
|
|
203421
203750
|
cosConfig.Protocol = 'http:';
|
|
203422
203751
|
}
|
|
203423
203752
|
// COSSDK 默认开启 KeepAlive,这里提供关闭的方式
|
|
@@ -214809,26 +215138,26 @@ const path = __importStar(__webpack_require__(39902));
|
|
|
214809
215138
|
const zod_1 = __webpack_require__(21614);
|
|
214810
215139
|
// CloudBase 模板配置
|
|
214811
215140
|
const TEMPLATES = {
|
|
214812
|
-
|
|
215141
|
+
react: {
|
|
214813
215142
|
description: "React + CloudBase 全栈应用模板",
|
|
214814
|
-
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",
|
|
214815
215144
|
},
|
|
214816
|
-
|
|
215145
|
+
vue: {
|
|
214817
215146
|
description: "Vue + CloudBase 全栈应用模板",
|
|
214818
|
-
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",
|
|
214819
215148
|
},
|
|
214820
|
-
|
|
215149
|
+
miniprogram: {
|
|
214821
215150
|
description: "微信小程序 + 云开发模板",
|
|
214822
|
-
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",
|
|
214823
215152
|
},
|
|
214824
|
-
|
|
215153
|
+
uniapp: {
|
|
214825
215154
|
description: "UniApp + CloudBase 跨端应用模板",
|
|
214826
|
-
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",
|
|
214827
215156
|
},
|
|
214828
|
-
|
|
215157
|
+
rules: {
|
|
214829
215158
|
description: "AI编辑器配置模板(包含所有主流编辑器配置)",
|
|
214830
|
-
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip"
|
|
214831
|
-
}
|
|
215159
|
+
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip",
|
|
215160
|
+
},
|
|
214832
215161
|
};
|
|
214833
215162
|
// IDE类型枚举
|
|
214834
215163
|
const IDE_TYPES = [
|
|
@@ -214848,22 +215177,13 @@ const IDE_TYPES = [
|
|
|
214848
215177
|
"roocode", // RooCode AI编辑器
|
|
214849
215178
|
"tongyi-lingma", // 通义灵码
|
|
214850
215179
|
"trae", // Trae AI编辑器
|
|
214851
|
-
"vscode" // Visual Studio Code
|
|
215180
|
+
"vscode", // Visual Studio Code
|
|
214852
215181
|
];
|
|
214853
215182
|
// IDE到文件的映射关系
|
|
214854
215183
|
const IDE_FILE_MAPPINGS = {
|
|
214855
|
-
"cursor"
|
|
214856
|
-
|
|
214857
|
-
|
|
214858
|
-
],
|
|
214859
|
-
"windsurf": [
|
|
214860
|
-
".windsurf/rules/cloudbase-rules.md"
|
|
214861
|
-
],
|
|
214862
|
-
"codebuddy": [
|
|
214863
|
-
".rules/cloudbase-rules.md",
|
|
214864
|
-
"CODEBUDDY.md",
|
|
214865
|
-
".mcp.json"
|
|
214866
|
-
],
|
|
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"],
|
|
214867
215187
|
"claude-code": [
|
|
214868
215188
|
"CLAUDE.md",
|
|
214869
215189
|
".mcp.json",
|
|
@@ -214872,49 +215192,22 @@ const IDE_FILE_MAPPINGS = {
|
|
|
214872
215192
|
".claude/commands/spec.md",
|
|
214873
215193
|
".claude/commands/no_spec.md",
|
|
214874
215194
|
],
|
|
214875
|
-
|
|
214876
|
-
|
|
214877
|
-
],
|
|
214878
|
-
"
|
|
214879
|
-
".gemini/GEMINI.md",
|
|
214880
|
-
".gemini/settings.json"
|
|
214881
|
-
],
|
|
214882
|
-
"opencode": [
|
|
214883
|
-
".opencode.json"
|
|
214884
|
-
],
|
|
214885
|
-
"qwen-code": [
|
|
214886
|
-
".qwen/QWEN.md",
|
|
214887
|
-
".qwen/settings.json"
|
|
214888
|
-
],
|
|
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"],
|
|
214889
215199
|
"baidu-comate": [
|
|
214890
215200
|
".comate/rules/cloudbase-rules.mdr",
|
|
214891
215201
|
".comate/rules/cloudbaase-rules.mdr",
|
|
214892
|
-
".comate/mcp.json"
|
|
214893
|
-
],
|
|
214894
|
-
"openai-codex-cli": [
|
|
214895
|
-
".codex/config.toml",
|
|
214896
|
-
"AGENTS.md",
|
|
215202
|
+
".comate/mcp.json",
|
|
214897
215203
|
],
|
|
214898
|
-
"
|
|
214899
|
-
|
|
214900
|
-
],
|
|
214901
|
-
"
|
|
214902
|
-
|
|
214903
|
-
],
|
|
214904
|
-
"
|
|
214905
|
-
".roo/rules/cloudbaase-rules.md",
|
|
214906
|
-
".roo/mcp.json"
|
|
214907
|
-
],
|
|
214908
|
-
"tongyi-lingma": [
|
|
214909
|
-
".lingma/rules/cloudbaase-rules.md"
|
|
214910
|
-
],
|
|
214911
|
-
"trae": [
|
|
214912
|
-
".trae/rules/cloudbase-rules.md"
|
|
214913
|
-
],
|
|
214914
|
-
"vscode": [
|
|
214915
|
-
".vscode/mcp.json",
|
|
214916
|
-
".vscode/settings.json"
|
|
214917
|
-
]
|
|
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"],
|
|
214918
215211
|
};
|
|
214919
215212
|
// 所有IDE配置文件的完整列表 - 通过IDE_FILE_MAPPINGS计算得出
|
|
214920
215213
|
const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()));
|
|
@@ -214922,51 +215215,87 @@ const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()
|
|
|
214922
215215
|
IDE_FILE_MAPPINGS["all"] = ALL_IDE_FILES;
|
|
214923
215216
|
// IDE描述映射
|
|
214924
215217
|
const IDE_DESCRIPTIONS = {
|
|
214925
|
-
|
|
214926
|
-
|
|
214927
|
-
|
|
214928
|
-
|
|
215218
|
+
all: "所有IDE配置",
|
|
215219
|
+
cursor: "Cursor AI编辑器",
|
|
215220
|
+
windsurf: "WindSurf AI编辑器",
|
|
215221
|
+
codebuddy: "CodeBuddy AI编辑器",
|
|
214929
215222
|
"claude-code": "Claude Code AI编辑器",
|
|
214930
|
-
|
|
215223
|
+
cline: "Cline AI编辑器",
|
|
214931
215224
|
"gemini-cli": "Gemini CLI",
|
|
214932
|
-
|
|
215225
|
+
opencode: "OpenCode AI编辑器",
|
|
214933
215226
|
"qwen-code": "通义灵码",
|
|
214934
215227
|
"baidu-comate": "百度Comate",
|
|
214935
215228
|
"openai-codex-cli": "OpenAI Codex CLI",
|
|
214936
215229
|
"augment-code": "Augment Code",
|
|
214937
215230
|
"github-copilot": "GitHub Copilot",
|
|
214938
|
-
|
|
215231
|
+
roocode: "RooCode AI编辑器",
|
|
214939
215232
|
"tongyi-lingma": "通义灵码",
|
|
214940
|
-
|
|
214941
|
-
|
|
214942
|
-
};
|
|
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
|
+
}
|
|
214943
215268
|
// 下载文件到临时目录
|
|
214944
215269
|
async function downloadFile(url, filePath) {
|
|
214945
215270
|
return new Promise((resolve, reject) => {
|
|
214946
|
-
const client = url.startsWith(
|
|
214947
|
-
client
|
|
215271
|
+
const client = url.startsWith("https:") ? https : http;
|
|
215272
|
+
client
|
|
215273
|
+
.get(url, (res) => {
|
|
214948
215274
|
if (res.statusCode === 200) {
|
|
214949
215275
|
const file = fs.createWriteStream(filePath);
|
|
214950
215276
|
res.pipe(file);
|
|
214951
|
-
file.on(
|
|
215277
|
+
file.on("finish", () => {
|
|
214952
215278
|
file.close();
|
|
214953
215279
|
resolve();
|
|
214954
215280
|
});
|
|
214955
|
-
file.on(
|
|
215281
|
+
file.on("error", reject);
|
|
214956
215282
|
}
|
|
214957
215283
|
else if (res.statusCode === 302 || res.statusCode === 301) {
|
|
214958
215284
|
// 处理重定向
|
|
214959
215285
|
if (res.headers.location) {
|
|
214960
|
-
downloadFile(res.headers.location, filePath)
|
|
215286
|
+
downloadFile(res.headers.location, filePath)
|
|
215287
|
+
.then(resolve)
|
|
215288
|
+
.catch(reject);
|
|
214961
215289
|
}
|
|
214962
215290
|
else {
|
|
214963
|
-
reject(new Error(
|
|
215291
|
+
reject(new Error("重定向但没有location header"));
|
|
214964
215292
|
}
|
|
214965
215293
|
}
|
|
214966
215294
|
else {
|
|
214967
215295
|
reject(new Error(`下载失败,状态码: ${res.statusCode}`));
|
|
214968
215296
|
}
|
|
214969
|
-
})
|
|
215297
|
+
})
|
|
215298
|
+
.on("error", reject);
|
|
214970
215299
|
});
|
|
214971
215300
|
}
|
|
214972
215301
|
// 解压ZIP文件
|
|
@@ -214979,7 +215308,7 @@ async function extractZip(zipPath, extractPath) {
|
|
|
214979
215308
|
zip.extractAllTo(extractPath, true);
|
|
214980
215309
|
}
|
|
214981
215310
|
catch (error) {
|
|
214982
|
-
throw new Error(`解压失败: ${error instanceof Error ? error.message :
|
|
215311
|
+
throw new Error(`解压失败: ${error instanceof Error ? error.message : "未知错误"}`);
|
|
214983
215312
|
}
|
|
214984
215313
|
}
|
|
214985
215314
|
// 获取目录下所有文件的相对路径列表
|
|
@@ -215003,7 +215332,7 @@ async function copyFileIfNotExists(src, dest) {
|
|
|
215003
215332
|
try {
|
|
215004
215333
|
// 检查目标文件是否存在
|
|
215005
215334
|
if (fs.existsSync(dest)) {
|
|
215006
|
-
return { copied: false, reason:
|
|
215335
|
+
return { copied: false, reason: "文件已存在" };
|
|
215007
215336
|
}
|
|
215008
215337
|
// 创建目标目录
|
|
215009
215338
|
await fsPromises.mkdir(path.dirname(dest), { recursive: true });
|
|
@@ -215012,14 +215341,17 @@ async function copyFileIfNotExists(src, dest) {
|
|
|
215012
215341
|
return { copied: true };
|
|
215013
215342
|
}
|
|
215014
215343
|
catch (error) {
|
|
215015
|
-
return {
|
|
215344
|
+
return {
|
|
215345
|
+
copied: false,
|
|
215346
|
+
reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215347
|
+
};
|
|
215016
215348
|
}
|
|
215017
215349
|
}
|
|
215018
215350
|
// 复制文件,支持覆盖模式
|
|
215019
215351
|
// 判断是否应该跳过 README.md 文件
|
|
215020
215352
|
function shouldSkipReadme(template, destPath, overwrite) {
|
|
215021
|
-
const isReadme = path.basename(destPath).toLowerCase() ===
|
|
215022
|
-
const isRulesTemplate = template ===
|
|
215353
|
+
const isReadme = path.basename(destPath).toLowerCase() === "readme.md";
|
|
215354
|
+
const isRulesTemplate = template === "rules";
|
|
215023
215355
|
const exists = fs.existsSync(destPath);
|
|
215024
215356
|
return isReadme && isRulesTemplate && exists && !overwrite;
|
|
215025
215357
|
}
|
|
@@ -215028,11 +215360,15 @@ async function copyFile(src, dest, overwrite = false, template) {
|
|
|
215028
215360
|
const destExists = fs.existsSync(dest);
|
|
215029
215361
|
// 检查是否需要跳过 README.md 文件(仅对 rules 模板)
|
|
215030
215362
|
if (template && shouldSkipReadme(template, dest, overwrite)) {
|
|
215031
|
-
return {
|
|
215363
|
+
return {
|
|
215364
|
+
copied: false,
|
|
215365
|
+
reason: "README.md 文件已存在,已保护",
|
|
215366
|
+
action: "protected",
|
|
215367
|
+
};
|
|
215032
215368
|
}
|
|
215033
215369
|
// 如果目标文件存在且不允许覆盖
|
|
215034
215370
|
if (destExists && !overwrite) {
|
|
215035
|
-
return { copied: false, reason:
|
|
215371
|
+
return { copied: false, reason: "文件已存在", action: "skipped" };
|
|
215036
215372
|
}
|
|
215037
215373
|
// 创建目标目录
|
|
215038
215374
|
await fsPromises.mkdir(path.dirname(dest), { recursive: true });
|
|
@@ -215040,11 +215376,14 @@ async function copyFile(src, dest, overwrite = false, template) {
|
|
|
215040
215376
|
await fsPromises.copyFile(src, dest);
|
|
215041
215377
|
return {
|
|
215042
215378
|
copied: true,
|
|
215043
|
-
action: destExists ?
|
|
215379
|
+
action: destExists ? "overwritten" : "created",
|
|
215044
215380
|
};
|
|
215045
215381
|
}
|
|
215046
215382
|
catch (error) {
|
|
215047
|
-
return {
|
|
215383
|
+
return {
|
|
215384
|
+
copied: false,
|
|
215385
|
+
reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215386
|
+
};
|
|
215048
215387
|
}
|
|
215049
215388
|
}
|
|
215050
215389
|
// IDE验证函数
|
|
@@ -215052,13 +215391,13 @@ function validateIDE(ide) {
|
|
|
215052
215391
|
if (ide === "all") {
|
|
215053
215392
|
return { valid: true };
|
|
215054
215393
|
}
|
|
215055
|
-
const supportedIDEs = IDE_TYPES.filter(type => type !== "all");
|
|
215394
|
+
const supportedIDEs = IDE_TYPES.filter((type) => type !== "all");
|
|
215056
215395
|
const isValid = supportedIDEs.includes(ide);
|
|
215057
215396
|
if (!isValid) {
|
|
215058
215397
|
return {
|
|
215059
215398
|
valid: false,
|
|
215060
215399
|
error: `不支持的IDE类型: ${ide}`,
|
|
215061
|
-
supportedIDEs: supportedIDEs
|
|
215400
|
+
supportedIDEs: supportedIDEs,
|
|
215062
215401
|
};
|
|
215063
215402
|
}
|
|
215064
215403
|
return { valid: true };
|
|
@@ -215073,9 +215412,9 @@ function filterFilesByIDE(files, ide) {
|
|
|
215073
215412
|
return files; // 如果找不到映射,返回所有文件
|
|
215074
215413
|
}
|
|
215075
215414
|
// 计算需要排除的IDE文件(除了当前IDE需要的文件)
|
|
215076
|
-
const filesToExclude = ALL_IDE_FILES.filter(file => !ideFiles.includes(file));
|
|
215415
|
+
const filesToExclude = ALL_IDE_FILES.filter((file) => !ideFiles.includes(file));
|
|
215077
215416
|
// 排除不需要的IDE配置文件,保留其他所有文件
|
|
215078
|
-
return files.filter(file => !filesToExclude.includes(file));
|
|
215417
|
+
return files.filter((file) => !filesToExclude.includes(file));
|
|
215079
215418
|
}
|
|
215080
215419
|
// 创建过滤后的目录结构
|
|
215081
215420
|
async function createFilteredDirectory(extractDir, filteredFiles, ide) {
|
|
@@ -215083,7 +215422,7 @@ async function createFilteredDirectory(extractDir, filteredFiles, ide) {
|
|
|
215083
215422
|
return extractDir; // 如果选择所有IDE,直接返回原目录
|
|
215084
215423
|
}
|
|
215085
215424
|
// 创建新的过滤后目录
|
|
215086
|
-
const filteredDir = path.join(path.dirname(extractDir),
|
|
215425
|
+
const filteredDir = path.join(path.dirname(extractDir), "filtered");
|
|
215087
215426
|
await fsPromises.mkdir(filteredDir, { recursive: true });
|
|
215088
215427
|
// 只复制过滤后的文件到新目录
|
|
215089
215428
|
for (const relativePath of filteredFiles) {
|
|
@@ -215102,32 +215441,42 @@ function registerSetupTools(server) {
|
|
|
215102
215441
|
title: "下载项目模板",
|
|
215103
215442
|
description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
|
|
215104
215443
|
|
|
215105
|
-
**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.0.
|
|
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)`,
|
|
215106
215445
|
inputSchema: {
|
|
215107
|
-
template: zod_1.z
|
|
215108
|
-
|
|
215109
|
-
|
|
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(不覆盖)"),
|
|
215110
215457
|
},
|
|
215111
215458
|
annotations: {
|
|
215112
215459
|
readOnlyHint: false,
|
|
215113
215460
|
destructiveHint: false,
|
|
215114
215461
|
idempotentHint: false,
|
|
215115
215462
|
openWorldHint: true,
|
|
215116
|
-
category: "setup"
|
|
215117
|
-
}
|
|
215118
|
-
}, async ({ template, ide
|
|
215463
|
+
category: "setup",
|
|
215464
|
+
},
|
|
215465
|
+
}, async ({ template, ide, overwrite = false, }) => {
|
|
215119
215466
|
try {
|
|
215467
|
+
// 如果没有传入 ide 参数,根据 INTEGRATION_IDE 环境变量获取默认值
|
|
215468
|
+
const resolvedIDE = ide ?? getDefaultIDEFromEnv();
|
|
215120
215469
|
// 验证IDE类型
|
|
215121
|
-
const ideValidation = validateIDE(
|
|
215470
|
+
const ideValidation = validateIDE(resolvedIDE);
|
|
215122
215471
|
if (!ideValidation.valid) {
|
|
215123
|
-
const supportedIDEs = ideValidation.supportedIDEs?.join(
|
|
215472
|
+
const supportedIDEs = ideValidation.supportedIDEs?.join(", ") || "";
|
|
215124
215473
|
return {
|
|
215125
215474
|
content: [
|
|
215126
215475
|
{
|
|
215127
215476
|
type: "text",
|
|
215128
|
-
text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}
|
|
215129
|
-
}
|
|
215130
|
-
]
|
|
215477
|
+
text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}`,
|
|
215478
|
+
},
|
|
215479
|
+
],
|
|
215131
215480
|
};
|
|
215132
215481
|
}
|
|
215133
215482
|
const templateConfig = TEMPLATES[template];
|
|
@@ -215136,23 +215485,23 @@ function registerSetupTools(server) {
|
|
|
215136
215485
|
content: [
|
|
215137
215486
|
{
|
|
215138
215487
|
type: "text",
|
|
215139
|
-
text: `❌ 不支持的模板类型: ${template}
|
|
215140
|
-
}
|
|
215141
|
-
]
|
|
215488
|
+
text: `❌ 不支持的模板类型: ${template}`,
|
|
215489
|
+
},
|
|
215490
|
+
],
|
|
215142
215491
|
};
|
|
215143
215492
|
}
|
|
215144
215493
|
// 创建临时目录
|
|
215145
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(),
|
|
215146
|
-
const zipPath = path.join(tempDir,
|
|
215147
|
-
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");
|
|
215148
215497
|
// 下载和解压
|
|
215149
215498
|
await downloadFile(templateConfig.url, zipPath);
|
|
215150
215499
|
await extractZip(zipPath, extractDir);
|
|
215151
215500
|
const extractedFiles = await getAllFiles(extractDir);
|
|
215152
215501
|
// 根据IDE类型过滤文件
|
|
215153
|
-
const filteredFiles = filterFilesByIDE(extractedFiles,
|
|
215502
|
+
const filteredFiles = filterFilesByIDE(extractedFiles, resolvedIDE);
|
|
215154
215503
|
// 创建过滤后的目录结构(当选择特定IDE时)
|
|
215155
|
-
const workingDir = await createFilteredDirectory(extractDir, filteredFiles,
|
|
215504
|
+
const workingDir = await createFilteredDirectory(extractDir, filteredFiles, resolvedIDE);
|
|
215156
215505
|
// 检查是否需要复制到项目目录
|
|
215157
215506
|
const workspaceFolder = process.env.WORKSPACE_FOLDER_PATHS || process.cwd();
|
|
215158
215507
|
let finalFiles = [];
|
|
@@ -215167,7 +215516,7 @@ function registerSetupTools(server) {
|
|
|
215167
215516
|
const destPath = path.join(workspaceFolder, relativePath);
|
|
215168
215517
|
const copyResult = await copyFile(srcPath, destPath, overwrite, template);
|
|
215169
215518
|
if (copyResult.copied) {
|
|
215170
|
-
if (copyResult.action ===
|
|
215519
|
+
if (copyResult.action === "overwritten") {
|
|
215171
215520
|
overwrittenCount++;
|
|
215172
215521
|
}
|
|
215173
215522
|
else {
|
|
@@ -215176,7 +215525,7 @@ function registerSetupTools(server) {
|
|
|
215176
215525
|
finalFiles.push(destPath);
|
|
215177
215526
|
}
|
|
215178
215527
|
else {
|
|
215179
|
-
if (copyResult.action ===
|
|
215528
|
+
if (copyResult.action === "protected") {
|
|
215180
215529
|
protectedCount++;
|
|
215181
215530
|
}
|
|
215182
215531
|
else {
|
|
@@ -215186,11 +215535,11 @@ function registerSetupTools(server) {
|
|
|
215186
215535
|
}
|
|
215187
215536
|
}
|
|
215188
215537
|
// 添加IDE过滤信息
|
|
215189
|
-
const ideInfo = IDE_DESCRIPTIONS[
|
|
215538
|
+
const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
|
|
215190
215539
|
results.push(`✅ ${templateConfig.description} (${ideInfo}) 同步完成`);
|
|
215191
215540
|
results.push(`📁 临时目录: ${workingDir}`);
|
|
215192
215541
|
results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
|
|
215193
|
-
if (
|
|
215542
|
+
if (resolvedIDE !== "all") {
|
|
215194
215543
|
results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
|
|
215195
215544
|
}
|
|
215196
215545
|
const stats = [];
|
|
@@ -215203,36 +215552,36 @@ function registerSetupTools(server) {
|
|
|
215203
215552
|
if (skippedCount > 0)
|
|
215204
215553
|
stats.push(`跳过 ${skippedCount} 个已存在文件`);
|
|
215205
215554
|
if (stats.length > 0) {
|
|
215206
|
-
results.push(`📊 ${stats.join(
|
|
215555
|
+
results.push(`📊 ${stats.join(",")}`);
|
|
215207
215556
|
}
|
|
215208
215557
|
if (overwrite || overwrittenCount > 0 || skippedCount > 0) {
|
|
215209
|
-
results.push(`🔄 覆盖模式: ${overwrite ?
|
|
215558
|
+
results.push(`🔄 覆盖模式: ${overwrite ? "启用" : "禁用"}`);
|
|
215210
215559
|
}
|
|
215211
215560
|
}
|
|
215212
215561
|
else {
|
|
215213
|
-
finalFiles = filteredFiles.map(relativePath => path.join(workingDir, relativePath));
|
|
215214
|
-
const ideInfo = IDE_DESCRIPTIONS[
|
|
215562
|
+
finalFiles = filteredFiles.map((relativePath) => path.join(workingDir, relativePath));
|
|
215563
|
+
const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
|
|
215215
215564
|
results.push(`✅ ${templateConfig.description} (${ideInfo}) 下载完成`);
|
|
215216
215565
|
results.push(`📁 保存在临时目录: ${workingDir}`);
|
|
215217
215566
|
results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
|
|
215218
|
-
if (
|
|
215567
|
+
if (resolvedIDE !== "all") {
|
|
215219
215568
|
results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
|
|
215220
215569
|
}
|
|
215221
|
-
results.push(
|
|
215570
|
+
results.push("💡 如需将模板(包括隐藏文件)复制到项目目录,请确保复制时包含所有隐藏文件。");
|
|
215222
215571
|
}
|
|
215223
215572
|
// 文件路径列表
|
|
215224
|
-
results.push(
|
|
215225
|
-
results.push(
|
|
215226
|
-
finalFiles.forEach(filePath => {
|
|
215573
|
+
results.push("");
|
|
215574
|
+
results.push("📋 文件列表:");
|
|
215575
|
+
finalFiles.forEach((filePath) => {
|
|
215227
215576
|
results.push(`${filePath}`);
|
|
215228
215577
|
});
|
|
215229
215578
|
return {
|
|
215230
215579
|
content: [
|
|
215231
215580
|
{
|
|
215232
215581
|
type: "text",
|
|
215233
|
-
text: results.join(
|
|
215234
|
-
}
|
|
215235
|
-
]
|
|
215582
|
+
text: results.join("\n"),
|
|
215583
|
+
},
|
|
215584
|
+
],
|
|
215236
215585
|
};
|
|
215237
215586
|
}
|
|
215238
215587
|
catch (error) {
|
|
@@ -215240,9 +215589,9 @@ function registerSetupTools(server) {
|
|
|
215240
215589
|
content: [
|
|
215241
215590
|
{
|
|
215242
215591
|
type: "text",
|
|
215243
|
-
text: `❌ 下载模板失败: ${error instanceof Error ? error.message :
|
|
215244
|
-
}
|
|
215245
|
-
]
|
|
215592
|
+
text: `❌ 下载模板失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215593
|
+
},
|
|
215594
|
+
],
|
|
215246
215595
|
};
|
|
215247
215596
|
}
|
|
215248
215597
|
});
|
|
@@ -226148,6 +226497,7 @@ class CloudService {
|
|
|
226148
226497
|
this.cloudBaseContext = context;
|
|
226149
226498
|
}
|
|
226150
226499
|
get baseUrl() {
|
|
226500
|
+
const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
|
|
226151
226501
|
const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
|
|
226152
226502
|
const urlMap = {
|
|
226153
226503
|
tcb,
|
|
@@ -226161,7 +226511,7 @@ class CloudService {
|
|
|
226161
226511
|
const intranetUrlMap = Object.keys(urlMap).map((service) => ({
|
|
226162
226512
|
[service]: `https://${service}.internal.tencentcloudapi.com`,
|
|
226163
226513
|
})).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
|
|
226164
|
-
if (
|
|
226514
|
+
if (internalEndpoint) {
|
|
226165
226515
|
return intranetUrlMap[this.service];
|
|
226166
226516
|
}
|
|
226167
226517
|
if (urlMap[this.service]) {
|
|
@@ -269794,7 +270144,7 @@ class CloudBase {
|
|
|
269794
270144
|
}
|
|
269795
270145
|
constructor(config = {}) {
|
|
269796
270146
|
this.cloudBaseConfig = {};
|
|
269797
|
-
let { secretId, secretKey, token, envId, proxy, region, envType } = config;
|
|
270147
|
+
let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint } = config;
|
|
269798
270148
|
// config 中传入的 secretId secretkey 必须同时存在
|
|
269799
270149
|
if ((secretId && !secretKey) || (!secretId && secretKey)) {
|
|
269800
270150
|
throw new Error('secretId and secretKey must be a pair');
|
|
@@ -269806,7 +270156,8 @@ class CloudBase {
|
|
|
269806
270156
|
envId,
|
|
269807
270157
|
envType,
|
|
269808
270158
|
proxy,
|
|
269809
|
-
region
|
|
270159
|
+
region,
|
|
270160
|
+
useInternalEndpoint
|
|
269810
270161
|
};
|
|
269811
270162
|
// 初始化 context
|
|
269812
270163
|
this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
|
|
@@ -269861,6 +270212,9 @@ class CloudBase {
|
|
|
269861
270212
|
getManagerConfig() {
|
|
269862
270213
|
return this.cloudBaseConfig;
|
|
269863
270214
|
}
|
|
270215
|
+
get isInternalEndpoint() {
|
|
270216
|
+
return this.context.isInternalEndpoint();
|
|
270217
|
+
}
|
|
269864
270218
|
}
|
|
269865
270219
|
module.exports = CloudBase;
|
|
269866
270220
|
|
|
@@ -271939,6 +272293,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
271939
272293
|
exports.FunctionService = void 0;
|
|
271940
272294
|
const fs_1 = __importDefault(__webpack_require__(29021));
|
|
271941
272295
|
const path_1 = __importDefault(__webpack_require__(39902));
|
|
272296
|
+
const lodash_1 = __importDefault(__webpack_require__(2543));
|
|
271942
272297
|
const packer_1 = __webpack_require__(5147);
|
|
271943
272298
|
const error_1 = __webpack_require__(40430);
|
|
271944
272299
|
const utils_1 = __webpack_require__(62358);
|
|
@@ -272185,20 +272540,96 @@ class FunctionService {
|
|
|
272185
272540
|
});
|
|
272186
272541
|
return data;
|
|
272187
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
|
+
}
|
|
272188
272590
|
/**
|
|
272189
272591
|
* 删除云函数
|
|
272190
272592
|
* @param {string} name 云函数名称
|
|
272191
272593
|
* @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
|
|
272192
272594
|
* @returns {Promise<IResponseInfo>}
|
|
272193
272595
|
*/
|
|
272194
|
-
async deleteFunction(name
|
|
272596
|
+
async deleteFunction({ name }) {
|
|
272597
|
+
var _a;
|
|
272195
272598
|
const { namespace } = this.getFunctionConfig();
|
|
272196
|
-
|
|
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', {
|
|
272197
272611
|
FunctionName: name,
|
|
272198
|
-
Namespace: namespace
|
|
272199
|
-
Qualifier: qualifier
|
|
272612
|
+
Namespace: namespace
|
|
272200
272613
|
});
|
|
272201
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
|
+
}
|
|
272202
272633
|
/**
|
|
272203
272634
|
* 获取云函数详细信息
|
|
272204
272635
|
* @param {string} name 云函数名称
|
|
@@ -272233,13 +272664,35 @@ class FunctionService {
|
|
|
272233
272664
|
}
|
|
272234
272665
|
catch (e) {
|
|
272235
272666
|
data.VpcConfig = {
|
|
272236
|
-
vpc: '',
|
|
272237
|
-
subnet: ''
|
|
272667
|
+
vpc: 'VpcId',
|
|
272668
|
+
subnet: 'SubnetId'
|
|
272238
272669
|
};
|
|
272239
272670
|
}
|
|
272240
272671
|
}
|
|
272241
272672
|
return data;
|
|
272242
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
|
+
}
|
|
272243
272696
|
/**
|
|
272244
272697
|
* 获取函数日志
|
|
272245
272698
|
* @deprecated 请使用 getFunctionLogsV2 代替
|
|
@@ -272336,6 +272789,33 @@ class FunctionService {
|
|
|
272336
272789
|
const res = await this.tcbService.request('GetFunctionLogDetail', params);
|
|
272337
272790
|
return res;
|
|
272338
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
|
+
}
|
|
272339
272819
|
/**
|
|
272340
272820
|
* 更新云函数配置
|
|
272341
272821
|
* @param {ICloudFunction} func 云函数配置
|
|
@@ -272471,6 +272951,28 @@ class FunctionService {
|
|
|
272471
272951
|
throw new error_1.CloudBaseError(`[${name}] 调用失败:\n${e.message}`);
|
|
272472
272952
|
}
|
|
272473
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
|
+
}
|
|
272474
272976
|
/**
|
|
272475
272977
|
* 复制云函数
|
|
272476
272978
|
* @param {string} name 云函数名称
|
|
@@ -272513,12 +273015,34 @@ class FunctionService {
|
|
|
272513
273015
|
TriggerDesc: item.config
|
|
272514
273016
|
};
|
|
272515
273017
|
});
|
|
272516
|
-
|
|
272517
|
-
|
|
272518
|
-
|
|
272519
|
-
|
|
272520
|
-
|
|
272521
|
-
|
|
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);
|
|
272522
273046
|
}
|
|
272523
273047
|
/**
|
|
272524
273048
|
* 删除云函数触发器
|
|
@@ -272528,12 +273052,50 @@ class FunctionService {
|
|
|
272528
273052
|
*/
|
|
272529
273053
|
async deleteFunctionTrigger(name, triggerName) {
|
|
272530
273054
|
const { namespace } = this.getFunctionConfig();
|
|
272531
|
-
|
|
272532
|
-
|
|
272533
|
-
|
|
272534
|
-
|
|
272535
|
-
|
|
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
|
|
272536
273096
|
});
|
|
273097
|
+
// 下载文件
|
|
273098
|
+
return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
|
|
272537
273099
|
}
|
|
272538
273100
|
/**
|
|
272539
273101
|
* 获取云函数代码下载 链接
|
|
@@ -272559,6 +273121,68 @@ class FunctionService {
|
|
|
272559
273121
|
throw new error_1.CloudBaseError(`[${functionName}] 获取函数代码下载链接失败:\n${e.message}`);
|
|
272560
273122
|
}
|
|
272561
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
|
+
}
|
|
272562
273186
|
// 创建文件层版本
|
|
272563
273187
|
async createLayer(options) {
|
|
272564
273188
|
const { env } = this.getFunctionConfig();
|
|
@@ -272631,7 +273255,7 @@ class FunctionService {
|
|
|
272631
273255
|
Limit: limit,
|
|
272632
273256
|
Offset: offset,
|
|
272633
273257
|
SearchKey: searchKey,
|
|
272634
|
-
SearchSrc: `TCB_${env}`
|
|
273258
|
+
// SearchSrc: `TCB_${env}`
|
|
272635
273259
|
};
|
|
272636
273260
|
if (runtime) {
|
|
272637
273261
|
param.CompatibleRuntime = runtime;
|
|
@@ -272960,12 +273584,18 @@ __decorate([
|
|
|
272960
273584
|
__decorate([
|
|
272961
273585
|
(0, utils_1.preLazy)()
|
|
272962
273586
|
], FunctionService.prototype, "listFunctions", null);
|
|
273587
|
+
__decorate([
|
|
273588
|
+
(0, utils_1.preLazy)()
|
|
273589
|
+
], FunctionService.prototype, "listAllFunctions", null);
|
|
272963
273590
|
__decorate([
|
|
272964
273591
|
(0, utils_1.preLazy)()
|
|
272965
273592
|
], FunctionService.prototype, "deleteFunction", null);
|
|
272966
273593
|
__decorate([
|
|
272967
273594
|
(0, utils_1.preLazy)()
|
|
272968
273595
|
], FunctionService.prototype, "getFunctionDetail", null);
|
|
273596
|
+
__decorate([
|
|
273597
|
+
(0, utils_1.preLazy)()
|
|
273598
|
+
], FunctionService.prototype, "batchGetFunctionsDetail", null);
|
|
272969
273599
|
__decorate([
|
|
272970
273600
|
(0, utils_1.preLazy)()
|
|
272971
273601
|
], FunctionService.prototype, "getFunctionLogs", null);
|
|
@@ -272975,6 +273605,9 @@ __decorate([
|
|
|
272975
273605
|
__decorate([
|
|
272976
273606
|
(0, utils_1.preLazy)()
|
|
272977
273607
|
], FunctionService.prototype, "getFunctionLogDetail", null);
|
|
273608
|
+
__decorate([
|
|
273609
|
+
(0, utils_1.preLazy)()
|
|
273610
|
+
], FunctionService.prototype, "getCompleteFunctionLogs", null);
|
|
272978
273611
|
__decorate([
|
|
272979
273612
|
(0, utils_1.preLazy)()
|
|
272980
273613
|
], FunctionService.prototype, "updateFunctionConfig", null);
|
|
@@ -272984,6 +273617,9 @@ __decorate([
|
|
|
272984
273617
|
__decorate([
|
|
272985
273618
|
(0, utils_1.preLazy)()
|
|
272986
273619
|
], FunctionService.prototype, "invokeFunction", null);
|
|
273620
|
+
__decorate([
|
|
273621
|
+
(0, utils_1.preLazy)()
|
|
273622
|
+
], FunctionService.prototype, "batchInvokeFunctions", null);
|
|
272987
273623
|
__decorate([
|
|
272988
273624
|
(0, utils_1.preLazy)()
|
|
272989
273625
|
], FunctionService.prototype, "copyFunction", null);
|
|
@@ -272996,6 +273632,18 @@ __decorate([
|
|
|
272996
273632
|
__decorate([
|
|
272997
273633
|
(0, utils_1.preLazy)()
|
|
272998
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);
|
|
272999
273647
|
__decorate([
|
|
273000
273648
|
(0, utils_1.preLazy)()
|
|
273001
273649
|
], FunctionService.prototype, "createLayer", null);
|