@cloudbase/cloudbase-mcp 2.2.0 → 2.3.1

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 CHANGED
@@ -102,7 +102,6 @@ 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;
106
105
  const archiver_1 = __importDefault(__webpack_require__(99133));
107
106
  const fs_extra_1 = __webpack_require__(21605);
108
107
  const path_1 = __importDefault(__webpack_require__(39902));
@@ -271,7 +270,7 @@ class CloudRunService {
271
270
  /**
272
271
  * 上传部署包
273
272
  */
274
- const zipFile = await codeToZip(targetPath, { installDependency: (serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.InstallDependency) !== undefined ? serverConfig.InstallDependency : true });
273
+ const zipFile = await codeToZip(targetPath, { installDependency: true });
275
274
  await (0, utils_1.upload)({
276
275
  url: uploadUrl,
277
276
  file: zipFile,
@@ -287,14 +286,8 @@ class CloudRunService {
287
286
  if (await this._checkFunctionExist(serverName)) {
288
287
  // 更新
289
288
  const serverDetail = await this.detail({ serverName });
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
289
+ const _serverConfig = Object.assign(Object.assign(Object.assign({}, ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig) || {})), serverConfig), ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:' ? { Port: 3000 } : {}) // 函数型不能指定端口,需要固定为3000
291
290
  );
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
- }
298
291
  deployInfo.ReleaseType = 'FULL';
299
292
  return this._upsertFunction(false, {
300
293
  name: serverName,
@@ -322,13 +315,7 @@ class CloudRunService {
322
315
  RepoLanguage: 'Node.js'
323
316
  };
324
317
  }
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:' });
318
+ const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC'], Cpu: 0, Mem: 0, MinNum: 0, MaxNum: 0, PolicyDetails: [], EnvParams: JSON.stringify({}), InitialDelaySeconds: 0, CustomLogs: '', HasDockerfile: true, CreateTime: '', EnvId: envConfig.EnvId, ServerName: serverName, Port: type === 'container' ? 80 : 3000, Dockerfile: 'Dockerfile', BuildDir: '' }, serverConfig), (type === 'function' ? { Port: 3000 } : {})), { Tag: type === 'container' ? '' : 'function:' });
332
319
  return this._upsertFunction(true, {
333
320
  name: serverName,
334
321
  deployInfo,
@@ -362,12 +349,11 @@ class CloudRunService {
362
349
  _upsertFunction(isNew, data) {
363
350
  const { name, deployInfo, serverConfig } = data;
364
351
  const envConfig = this.environment.lazyEnvironmentConfig;
365
- const Items = parseObjectToDiffConfigItem(serverConfig);
366
352
  return this.tcbrService.request(isNew ? 'CreateCloudRunServer' : 'UpdateCloudRunServer', {
367
353
  EnvId: envConfig.EnvId,
368
354
  ServerName: name,
369
355
  DeployInfo: deployInfo,
370
- Items,
356
+ ServerConfig: serverConfig
371
357
  });
372
358
  }
373
359
  }
@@ -440,63 +426,6 @@ async function codeToZip(cwd, options) {
440
426
  await archive.finalize();
441
427
  return bufferPromise;
442
428
  }
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
- }
500
429
 
501
430
 
502
431
  /***/ }),
@@ -48616,7 +48545,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
48616
48545
  exports.cloudBaseRequest = cloudBaseRequest;
48617
48546
  const auth_1 = __webpack_require__(23506);
48618
48547
  const http_request_1 = __webpack_require__(72088);
48619
- const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou', 'ap-singapore'];
48548
+ const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou'];
48620
48549
  async function cloudBaseRequest(options) {
48621
48550
  // const url = 'https://tcb-admin.tencentcloudapi.com/admin'
48622
48551
  const { config, params = {}, method = 'POST', headers = {} } = options;
@@ -48630,11 +48559,11 @@ async function cloudBaseRequest(options) {
48630
48559
  let internalRegionEndpoint = '';
48631
48560
  if (finalRegion) {
48632
48561
  if (SUPPORT_REGIONS.includes(finalRegion)) {
48633
- internetRegionEndpoint = `${envId}.${finalRegion}.tcb-api.tencentcloudapi.com`;
48634
- internalRegionEndpoint = `${envId}.internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
48562
+ internetRegionEndpoint = `${finalRegion}.tcb-api.tencentcloudapi.com`;
48563
+ internalRegionEndpoint = `internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
48635
48564
  }
48636
48565
  else {
48637
- console.warn('当前仅支持上海,广州,新加坡地域,其他地域默认解析到固定域名(上海地域)');
48566
+ console.warn('当前仅支持上海,广州地域,其他地域默认解析到固定域名(上海地域)');
48638
48567
  internetRegionEndpoint = `tcb-api.tencentcloudapi.com`;
48639
48568
  internalRegionEndpoint = `internal.tcb-api.tencentcloudapi.com`;
48640
48569
  }
@@ -90227,20 +90156,19 @@ class EnvService {
90227
90156
  });
90228
90157
  }
90229
90158
  getCos() {
90230
- const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
90231
90159
  const { secretId, secretKey, token } = this.environment.getAuthConfig();
90232
90160
  const cosConfig = {
90233
90161
  SecretId: secretId,
90234
90162
  SecretKey: secretKey,
90235
90163
  SecurityToken: token,
90236
- Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
90164
+ Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
90237
90165
  };
90238
90166
  if (constant_1.COS_SDK_PROTOCOL) {
90239
90167
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
90240
90168
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
90241
90169
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
90242
90170
  }
90243
- if (internalEndpoint) {
90171
+ if (constant_1.USE_INTERNAL_ENDPOINT) {
90244
90172
  cosConfig.Protocol = 'http:';
90245
90173
  }
90246
90174
  return new cos_nodejs_sdk_v5_1.default(cosConfig);
@@ -135084,7 +135012,7 @@ class TelemetryReporter {
135084
135012
  const nodeVersion = process.version; // Node.js版本
135085
135013
  const arch = os_1.default.arch(); // 系统架构
135086
135014
  // 从构建时注入的版本号获取MCP版本信息
135087
- const mcpVersion = process.env.npm_package_version || "2.2.0" || 0;
135015
+ const mcpVersion = process.env.npm_package_version || "2.3.1" || 0;
135088
135016
  return {
135089
135017
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
135090
135018
  deviceId: this.deviceId,
@@ -179682,7 +179610,6 @@ exports.sleep = sleep;
179682
179610
  exports.upperCaseStringFisrt = upperCaseStringFisrt;
179683
179611
  exports.upperCaseObjKey = upperCaseObjKey;
179684
179612
  exports.fetchTemplates = fetchTemplates;
179685
- exports.successLog = successLog;
179686
179613
  const archiver_1 = __importDefault(__webpack_require__(99133));
179687
179614
  const crypto_1 = __importDefault(__webpack_require__(55511));
179688
179615
  const fs_extra_1 = __importDefault(__webpack_require__(21605));
@@ -179961,10 +179888,6 @@ const getCompleteTimeRange = (timeRange) => {
179961
179888
  };
179962
179889
  };
179963
179890
  exports.getCompleteTimeRange = getCompleteTimeRange;
179964
- function successLog(msg) {
179965
- // 空格,兼容中文字符编码长度问题
179966
- console.log(`${msg}`);
179967
- }
179968
179891
 
179969
179892
 
179970
179893
  /***/ }),
@@ -185562,7 +185485,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
185562
185485
  return (mod && mod.__esModule) ? mod : { "default": mod };
185563
185486
  };
185564
185487
  Object.defineProperty(exports, "__esModule", ({ value: true }));
185565
- exports.downloadWebTemplate = downloadWebTemplate;
185566
185488
  exports.getClaudePrompt = getClaudePrompt;
185567
185489
  exports.registerRagTools = registerRagTools;
185568
185490
  const adm_zip_1 = __importDefault(__webpack_require__(30283));
@@ -185580,6 +185502,58 @@ const KnowledgeBaseIdMap = {
185580
185502
  scf: "scfsczskzyws_4bdc",
185581
185503
  miniprogram: "xcxzskws_25d8",
185582
185504
  };
185505
+ // ============ 缓存配置 ============
185506
+ const CACHE_BASE_DIR = path.join(os.homedir(), ".cloudbase-mcp");
185507
+ const CACHE_META_FILE = path.join(CACHE_BASE_DIR, "cache-meta.json");
185508
+ const DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 默认 24 小时
185509
+ // 支持环境变量 CLOUDBASE_MCP_CACHE_TTL_MS 控制缓存过期时间(毫秒)
185510
+ const parsedCacheTTL = process.env.CLOUDBASE_MCP_CACHE_TTL_MS
185511
+ ? parseInt(process.env.CLOUDBASE_MCP_CACHE_TTL_MS, 10)
185512
+ : NaN;
185513
+ const CACHE_TTL_MS = Number.isNaN(parsedCacheTTL) || parsedCacheTTL < 0
185514
+ ? DEFAULT_CACHE_TTL_MS
185515
+ : parsedCacheTTL;
185516
+ if (!Number.isNaN(parsedCacheTTL) && parsedCacheTTL >= 0) {
185517
+ (0, logger_js_1.debug)("[cache] Using TTL from CLOUDBASE_MCP_CACHE_TTL_MS", {
185518
+ ttlMs: CACHE_TTL_MS,
185519
+ });
185520
+ }
185521
+ else {
185522
+ (0, logger_js_1.debug)("[cache] Using default TTL", { ttlMs: CACHE_TTL_MS });
185523
+ }
185524
+ // 共享的下载 Promise,防止并发重复下载
185525
+ let resourceDownloadPromise = null;
185526
+ // 检查缓存是否可用(未过期)
185527
+ async function canUseCache() {
185528
+ try {
185529
+ const content = await fs.readFile(CACHE_META_FILE, "utf8");
185530
+ const meta = JSON.parse(content);
185531
+ if (!meta.timestamp) {
185532
+ (0, logger_js_1.debug)("[cache] cache-meta missing timestamp, treating as invalid", {
185533
+ ttlMs: CACHE_TTL_MS,
185534
+ });
185535
+ return false;
185536
+ }
185537
+ const ageMs = Date.now() - meta.timestamp;
185538
+ const isValid = ageMs <= CACHE_TTL_MS;
185539
+ (0, logger_js_1.debug)("[cache] evaluated cache meta", {
185540
+ timestamp: meta.timestamp,
185541
+ ageMs,
185542
+ ttlMs: CACHE_TTL_MS,
185543
+ valid: isValid,
185544
+ });
185545
+ return isValid;
185546
+ }
185547
+ catch (error) {
185548
+ (0, logger_js_1.debug)("[cache] failed to read cache meta, treating as miss", { error });
185549
+ return false;
185550
+ }
185551
+ }
185552
+ // 更新缓存时间戳
185553
+ async function updateCache() {
185554
+ await fs.mkdir(CACHE_BASE_DIR, { recursive: true });
185555
+ await fs.writeFile(CACHE_META_FILE, JSON.stringify({ timestamp: Date.now() }, null, 2), "utf8");
185556
+ }
185583
185557
  // 安全 JSON.parse
185584
185558
  function safeParse(str) {
185585
185559
  try {
@@ -185606,31 +185580,141 @@ function safeStringify(obj) {
185606
185580
  return "";
185607
185581
  }
185608
185582
  }
185609
- // Download and extract web template, return extract directory path
185610
- // Always downloads and overwrites existing template
185583
+ // OpenAPI 文档 URL 列表
185584
+ const OPENAPI_SOURCES = [
185585
+ {
185586
+ name: "mysqldb",
185587
+ description: "MySQL RESTful API - 云开发 MySQL 数据库 HTTP API",
185588
+ url: "https://docs.cloudbase.net/openapi/mysqldb.v1.openapi.yaml",
185589
+ },
185590
+ {
185591
+ name: "functions",
185592
+ description: "Cloud Functions API - 云函数 HTTP API",
185593
+ url: "https://docs.cloudbase.net/openapi/functions.v1.openapi.yaml",
185594
+ },
185595
+ {
185596
+ name: "auth",
185597
+ description: "Authentication API - 身份认证 HTTP API",
185598
+ url: "https://docs.cloudbase.net/openapi/auth.v1.openapi.yaml",
185599
+ },
185600
+ {
185601
+ name: "cloudrun",
185602
+ description: "CloudRun API - 云托管服务 HTTP API",
185603
+ url: "https://docs.cloudbase.net/openapi/cloudrun.v1.openapi.yaml",
185604
+ },
185605
+ {
185606
+ name: "storage",
185607
+ description: "Storage API - 云存储 HTTP API",
185608
+ url: "https://docs.cloudbase.net/openapi/storage.v1.openapi.yaml",
185609
+ },
185610
+ ];
185611
185611
  async function downloadWebTemplate() {
185612
- const baseDir = path.join(os.homedir(), ".cloudbase-mcp");
185613
- const zipPath = path.join(baseDir, "web-cloudbase-project.zip");
185614
- const extractDir = path.join(baseDir, "web-template");
185612
+ const zipPath = path.join(CACHE_BASE_DIR, "web-cloudbase-project.zip");
185613
+ const extractDir = path.join(CACHE_BASE_DIR, "web-template");
185615
185614
  const url = "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip";
185616
- await fs.mkdir(baseDir, { recursive: true });
185617
- // Download zip to specified path (overwrite)
185618
185615
  const response = await fetch(url);
185619
185616
  if (!response.ok) {
185620
185617
  throw new Error(`下载模板失败,状态码: ${response.status}`);
185621
185618
  }
185622
185619
  const buffer = Buffer.from(await response.arrayBuffer());
185623
185620
  await fs.writeFile(zipPath, buffer);
185624
- // Clean and recreate extract directory
185625
185621
  await fs.rm(extractDir, { recursive: true, force: true });
185626
185622
  await fs.mkdir(extractDir, { recursive: true });
185627
185623
  const zip = new adm_zip_1.default(zipPath);
185628
185624
  zip.extractAllTo(extractDir, true);
185625
+ (0, logger_js_1.debug)("[downloadResources] webTemplate 下载完成");
185629
185626
  return extractDir;
185630
185627
  }
185631
- async function prepareKnowledgeBaseWebTemplate() {
185632
- const extractDir = await downloadWebTemplate();
185633
- return collectSkillDescriptions(path.join(extractDir, ".claude", "skills"));
185628
+ async function downloadOpenAPI() {
185629
+ const baseDir = path.join(CACHE_BASE_DIR, "openapi");
185630
+ await fs.mkdir(baseDir, { recursive: true });
185631
+ const results = [];
185632
+ await Promise.all(OPENAPI_SOURCES.map(async (source) => {
185633
+ try {
185634
+ const response = await fetch(source.url);
185635
+ if (!response.ok) {
185636
+ (0, logger_js_1.warn)(`[downloadOpenAPI] Failed to download ${source.name}`, {
185637
+ status: response.status,
185638
+ });
185639
+ return;
185640
+ }
185641
+ const content = await response.text();
185642
+ const filePath = path.join(baseDir, `${source.name}.openapi.yaml`);
185643
+ await fs.writeFile(filePath, content, "utf8");
185644
+ results.push({
185645
+ name: source.name,
185646
+ description: source.description,
185647
+ absolutePath: filePath,
185648
+ });
185649
+ }
185650
+ catch (error) {
185651
+ (0, logger_js_1.warn)(`[downloadOpenAPI] Failed to download ${source.name}`, {
185652
+ error,
185653
+ });
185654
+ }
185655
+ }));
185656
+ (0, logger_js_1.debug)("[downloadOpenAPI] openAPIDocs 下载完成", {
185657
+ successCount: results.length,
185658
+ total: OPENAPI_SOURCES.length,
185659
+ });
185660
+ return results;
185661
+ }
185662
+ // 实际执行下载所有资源的函数(webTemplate 和 openAPI 并发下载)
185663
+ async function _doDownloadResources() {
185664
+ // 并发下载 webTemplate 和 openAPIDocs
185665
+ const [webTemplateDir, openAPIDocs] = await Promise.all([
185666
+ // 下载 web 模板
185667
+ downloadWebTemplate(),
185668
+ // 并发下载所有 OpenAPI 文档
185669
+ downloadOpenAPI(),
185670
+ ]);
185671
+ (0, logger_js_1.debug)("[downloadResources] 所有资源下载完成");
185672
+ return { webTemplateDir, openAPIDocs };
185673
+ }
185674
+ // 下载所有资源(带缓存和共享 Promise 机制)
185675
+ async function downloadResources() {
185676
+ const webTemplateDir = path.join(CACHE_BASE_DIR, "web-template");
185677
+ const openAPIDir = path.join(CACHE_BASE_DIR, "openapi");
185678
+ // 检查缓存是否有效
185679
+ if (await canUseCache()) {
185680
+ try {
185681
+ // 检查两个目录都存在
185682
+ await Promise.all([fs.access(webTemplateDir), fs.access(openAPIDir)]);
185683
+ const files = await fs.readdir(openAPIDir);
185684
+ if (files.length > 0) {
185685
+ (0, logger_js_1.debug)("[downloadResources] 使用缓存");
185686
+ return {
185687
+ webTemplateDir,
185688
+ openAPIDocs: OPENAPI_SOURCES.map((source) => ({
185689
+ name: source.name,
185690
+ description: source.description,
185691
+ absolutePath: path.join(openAPIDir, `${source.name}.openapi.yaml`),
185692
+ })).filter((item) => files.includes(`${item.name}.openapi.yaml`)),
185693
+ };
185694
+ }
185695
+ }
185696
+ catch {
185697
+ // 缓存无效,需要重新下载
185698
+ }
185699
+ }
185700
+ // 如果已有下载任务在进行中,共享该 Promise
185701
+ if (resourceDownloadPromise) {
185702
+ (0, logger_js_1.debug)("[downloadResources] 共享已有下载任务");
185703
+ return resourceDownloadPromise;
185704
+ }
185705
+ // 创建新的下载任务
185706
+ (0, logger_js_1.debug)("[downloadResources] 开始新下载任务");
185707
+ await fs.mkdir(CACHE_BASE_DIR, { recursive: true });
185708
+ resourceDownloadPromise = _doDownloadResources()
185709
+ .then(async (result) => {
185710
+ await updateCache();
185711
+ (0, logger_js_1.debug)("[downloadResources] 缓存已更新");
185712
+ return result;
185713
+ })
185714
+ .finally(() => {
185715
+ resourceDownloadPromise = null;
185716
+ });
185717
+ return resourceDownloadPromise;
185634
185718
  }
185635
185719
  // Get CLAUDE.md prompt content
185636
185720
  // Priority: 1. From downloaded template, 2. Fallback to embedded constant
@@ -185754,23 +185838,15 @@ async function registerRagTools(server) {
185754
185838
  };
185755
185839
  }
185756
185840
  });
185757
- let skills = [];
185758
185841
  let openapis = [];
185759
- // 知识库检索
185760
- try {
185761
- skills = await prepareKnowledgeBaseWebTemplate();
185762
- }
185763
- catch (error) {
185764
- (0, logger_js_1.warn)("[searchKnowledgeBase] Failed to prepare web template", {
185765
- error,
185766
- });
185767
- }
185768
- // OpenAPI 文档准备
185842
+ let skills = [];
185769
185843
  try {
185770
- openapis = await prepareOpenAPIDocs();
185844
+ const { webTemplateDir, openAPIDocs } = await downloadResources();
185845
+ openapis = openAPIDocs;
185846
+ skills = await collectSkillDescriptions(path.join(webTemplateDir, ".claude", "skills"));
185771
185847
  }
185772
185848
  catch (error) {
185773
- (0, logger_js_1.warn)("[searchKnowledgeBase] Failed to prepare OpenAPI docs", {
185849
+ (0, logger_js_1.warn)("[downloadResources] Failed to download resources", {
185774
185850
  error,
185775
185851
  });
185776
185852
  }
@@ -185937,65 +186013,6 @@ function extractDescriptionFromFrontMatter(content) {
185937
186013
  .match(/^(?:decsription|description)\s*:\s*(.*)$/m);
185938
186014
  return match ? match[1].trim() : null;
185939
186015
  }
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
- }
185999
186016
  async function collectSkillDescriptions(rootDir) {
186000
186017
  const result = [];
186001
186018
  async function walk(dir) {
@@ -191293,25 +191310,20 @@ function callSuccessCallback(callback, result) {
191293
191310
  /***/ }),
191294
191311
 
191295
191312
  /***/ 65607:
191296
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
191313
+ /***/ ((__unused_webpack_module, exports) => {
191297
191314
 
191298
191315
  "use strict";
191299
191316
 
191300
191317
  Object.defineProperty(exports, "__esModule", ({ value: true }));
191301
191318
  exports.CloudBaseContext = void 0;
191302
- const constant_1 = __webpack_require__(40762);
191303
191319
  class CloudBaseContext {
191304
- constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined }) {
191320
+ constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
191305
191321
  this.secretId = secretId;
191306
191322
  this.secretKey = secretKey;
191307
191323
  this.token = token;
191308
191324
  this.proxy = proxy;
191309
191325
  this.region = region;
191310
191326
  this.envType = envType;
191311
- this.useInternalEndpoint = useInternalEndpoint;
191312
- }
191313
- isInternalEndpoint() {
191314
- return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
191315
191327
  }
191316
191328
  }
191317
191329
  exports.CloudBaseContext = CloudBaseContext;
@@ -200838,7 +200850,7 @@ ${envIdSection}
200838
200850
  ## 环境信息
200839
200851
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
200840
200852
  - Node.js版本: ${process.version}
200841
- - MCP 版本:${process.env.npm_package_version || "2.2.0" || 0}
200853
+ - MCP 版本:${process.env.npm_package_version || "2.3.1" || 0}
200842
200854
  - 系统架构: ${os_1.default.arch()}
200843
200855
  - 时间: ${new Date().toISOString()}
200844
200856
  - 请求ID: ${requestId}
@@ -203730,7 +203742,6 @@ class StorageService {
203730
203742
  * 获取 COS 配置
203731
203743
  */
203732
203744
  getCos(parallel = 20) {
203733
- const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
203734
203745
  const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
203735
203746
  const cosProxy = process.env.TCB_COS_PROXY;
203736
203747
  const cosConfig = {
@@ -203739,14 +203750,14 @@ class StorageService {
203739
203750
  SecretKey: secretKey,
203740
203751
  Proxy: cosProxy || proxy,
203741
203752
  SecurityToken: token,
203742
- Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
203753
+ Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
203743
203754
  };
203744
203755
  if (constant_1.COS_SDK_PROTOCOL) {
203745
203756
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
203746
203757
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
203747
203758
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
203748
203759
  }
203749
- if (internalEndpoint) {
203760
+ if (constant_1.USE_INTERNAL_ENDPOINT) {
203750
203761
  cosConfig.Protocol = 'http:';
203751
203762
  }
203752
203763
  // COSSDK 默认开启 KeepAlive,这里提供关闭的方式
@@ -215177,12 +215188,15 @@ const IDE_TYPES = [
215177
215188
  "roocode", // RooCode AI编辑器
215178
215189
  "tongyi-lingma", // 通义灵码
215179
215190
  "trae", // Trae AI编辑器
215191
+ "qoder", // Qoder AI编辑器
215192
+ "antigravity", // Google Antigravity AI编辑器
215180
215193
  "vscode", // Visual Studio Code
215181
215194
  ];
215182
215195
  // IDE到文件的映射关系
215196
+ // 注意:以 "/" 结尾的路径表示目录,会包含该目录下的所有文件
215183
215197
  const IDE_FILE_MAPPINGS = {
215184
- cursor: [".cursor/rules/cloudbase-rules.mdc", ".cursor/mcp.json"],
215185
- windsurf: [".windsurf/rules/cloudbase-rules.md"],
215198
+ cursor: [".cursor/rules/", ".cursor/mcp.json"],
215199
+ windsurf: [".windsurf/rules/"],
215186
215200
  codebuddy: [".rules/cloudbase-rules.md", "CODEBUDDY.md", ".mcp.json"],
215187
215201
  "claude-code": [
215188
215202
  "CLAUDE.md",
@@ -215192,7 +215206,7 @@ const IDE_FILE_MAPPINGS = {
215192
215206
  ".claude/commands/spec.md",
215193
215207
  ".claude/commands/no_spec.md",
215194
215208
  ],
215195
- cline: [".clinerules/cloudbase-rules.mdc"],
215209
+ cline: [".clinerules/"],
215196
215210
  "gemini-cli": [".gemini/GEMINI.md", ".gemini/settings.json"],
215197
215211
  opencode: [".opencode.json"],
215198
215212
  "qwen-code": [".qwen/QWEN.md", ".qwen/settings.json"],
@@ -215206,7 +215220,9 @@ const IDE_FILE_MAPPINGS = {
215206
215220
  "github-copilot": [".github/copilot-instructions.md"],
215207
215221
  roocode: [".roo/rules/cloudbaase-rules.md", ".roo/mcp.json"],
215208
215222
  "tongyi-lingma": [".lingma/rules/cloudbaase-rules.md"],
215209
- trae: [".trae/rules/cloudbase-rules.md"],
215223
+ trae: [".trae/rules/"],
215224
+ qoder: [".qoder/rules/"],
215225
+ antigravity: [".agent/rules/"],
215210
215226
  vscode: [".vscode/mcp.json", ".vscode/settings.json"],
215211
215227
  };
215212
215228
  // 所有IDE配置文件的完整列表 - 通过IDE_FILE_MAPPINGS计算得出
@@ -215231,6 +215247,8 @@ const IDE_DESCRIPTIONS = {
215231
215247
  roocode: "RooCode AI编辑器",
215232
215248
  "tongyi-lingma": "通义灵码",
215233
215249
  trae: "Trae AI编辑器",
215250
+ qoder: "Qoder AI编辑器",
215251
+ antigravity: "Google Antigravity AI编辑器",
215234
215252
  vscode: "Visual Studio Code",
215235
215253
  };
215236
215254
  // INTEGRATION_IDE 环境变量值到 IDE 类型的映射
@@ -215252,6 +215270,8 @@ const INTEGRATION_IDE_MAPPING = {
215252
215270
  RooCode: "roocode",
215253
215271
  "Tongyi Lingma": "tongyi-lingma",
215254
215272
  Trae: "trae",
215273
+ Qoder: "qoder",
215274
+ Antigravity: "antigravity",
215255
215275
  VSCode: "vscode",
215256
215276
  };
215257
215277
  // 根据 INTEGRATION_IDE 环境变量获取默认 IDE 类型
@@ -215402,6 +215422,17 @@ function validateIDE(ide) {
215402
215422
  }
215403
215423
  return { valid: true };
215404
215424
  }
215425
+ // 检查文件是否匹配给定的路径(支持文件和目录)
215426
+ function matchesPath(file, pathPattern) {
215427
+ if (pathPattern.endsWith("/")) {
215428
+ // 目录路径:检查文件是否在该目录下
215429
+ return file.startsWith(pathPattern);
215430
+ }
215431
+ else {
215432
+ // 文件路径:精确匹配
215433
+ return file === pathPattern;
215434
+ }
215435
+ }
215405
215436
  // 文件过滤函数
215406
215437
  function filterFilesByIDE(files, ide) {
215407
215438
  if (ide === "all") {
@@ -215412,9 +215443,32 @@ function filterFilesByIDE(files, ide) {
215412
215443
  return files; // 如果找不到映射,返回所有文件
215413
215444
  }
215414
215445
  // 计算需要排除的IDE文件(除了当前IDE需要的文件)
215415
- const filesToExclude = ALL_IDE_FILES.filter((file) => !ideFiles.includes(file));
215446
+ const filesToExclude = [];
215447
+ // 遍历所有IDE文件,找出不属于当前IDE的文件
215448
+ for (const ideFile of ALL_IDE_FILES) {
215449
+ // 检查这个文件是否属于当前IDE需要的文件
215450
+ let isCurrentIDEFile = false;
215451
+ for (const currentIDEFile of ideFiles) {
215452
+ if (matchesPath(ideFile, currentIDEFile)) {
215453
+ isCurrentIDEFile = true;
215454
+ break;
215455
+ }
215456
+ }
215457
+ // 如果不属于当前IDE,加入排除列表
215458
+ if (!isCurrentIDEFile) {
215459
+ filesToExclude.push(ideFile);
215460
+ }
215461
+ }
215416
215462
  // 排除不需要的IDE配置文件,保留其他所有文件
215417
- return files.filter((file) => !filesToExclude.includes(file));
215463
+ return files.filter((file) => {
215464
+ // 检查文件是否应该被排除
215465
+ for (const excludePath of filesToExclude) {
215466
+ if (matchesPath(file, excludePath)) {
215467
+ return false; // 排除
215468
+ }
215469
+ }
215470
+ return true; // 保留
215471
+ });
215418
215472
  }
215419
215473
  // 创建过滤后的目录结构
215420
215474
  async function createFilteredDirectory(extractDir, filteredFiles, ide) {
@@ -215441,7 +215495,7 @@ function registerSetupTools(server) {
215441
215495
  title: "下载项目模板",
215442
215496
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
215443
215497
 
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" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
215498
+ **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- qoder: Qoder AI编辑器\n- antigravity: Google Antigravity AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.3.1" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
215445
215499
  inputSchema: {
215446
215500
  template: zod_1.z
215447
215501
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
@@ -226497,7 +226551,6 @@ class CloudService {
226497
226551
  this.cloudBaseContext = context;
226498
226552
  }
226499
226553
  get baseUrl() {
226500
- const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
226501
226554
  const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
226502
226555
  const urlMap = {
226503
226556
  tcb,
@@ -226511,7 +226564,7 @@ class CloudService {
226511
226564
  const intranetUrlMap = Object.keys(urlMap).map((service) => ({
226512
226565
  [service]: `https://${service}.internal.tencentcloudapi.com`,
226513
226566
  })).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
226514
- if (internalEndpoint) {
226567
+ if (constant_1.USE_INTERNAL_ENDPOINT) {
226515
226568
  return intranetUrlMap[this.service];
226516
226569
  }
226517
226570
  if (urlMap[this.service]) {
@@ -270144,7 +270197,7 @@ class CloudBase {
270144
270197
  }
270145
270198
  constructor(config = {}) {
270146
270199
  this.cloudBaseConfig = {};
270147
- let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint } = config;
270200
+ let { secretId, secretKey, token, envId, proxy, region, envType } = config;
270148
270201
  // config 中传入的 secretId secretkey 必须同时存在
270149
270202
  if ((secretId && !secretKey) || (!secretId && secretKey)) {
270150
270203
  throw new Error('secretId and secretKey must be a pair');
@@ -270156,8 +270209,7 @@ class CloudBase {
270156
270209
  envId,
270157
270210
  envType,
270158
270211
  proxy,
270159
- region,
270160
- useInternalEndpoint
270212
+ region
270161
270213
  };
270162
270214
  // 初始化 context
270163
270215
  this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
@@ -270212,9 +270264,6 @@ class CloudBase {
270212
270264
  getManagerConfig() {
270213
270265
  return this.cloudBaseConfig;
270214
270266
  }
270215
- get isInternalEndpoint() {
270216
- return this.context.isInternalEndpoint();
270217
- }
270218
270267
  }
270219
270268
  module.exports = CloudBase;
270220
270269
 
@@ -272293,7 +272342,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
272293
272342
  exports.FunctionService = void 0;
272294
272343
  const fs_1 = __importDefault(__webpack_require__(29021));
272295
272344
  const path_1 = __importDefault(__webpack_require__(39902));
272296
- const lodash_1 = __importDefault(__webpack_require__(2543));
272297
272345
  const packer_1 = __webpack_require__(5147);
272298
272346
  const error_1 = __webpack_require__(40430);
272299
272347
  const utils_1 = __webpack_require__(62358);
@@ -272540,96 +272588,20 @@ class FunctionService {
272540
272588
  });
272541
272589
  return data;
272542
272590
  }
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
- }
272590
272591
  /**
272591
272592
  * 删除云函数
272592
272593
  * @param {string} name 云函数名称
272593
272594
  * @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
272594
272595
  * @returns {Promise<IResponseInfo>}
272595
272596
  */
272596
- async deleteFunction({ name }) {
272597
- var _a;
272597
+ async deleteFunction(name, qualifier) {
272598
272598
  const { namespace } = this.getFunctionConfig();
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', {
272599
+ return this.scfService.request('DeleteFunction', {
272611
272600
  FunctionName: name,
272612
- Namespace: namespace
272601
+ Namespace: namespace,
272602
+ Qualifier: qualifier
272613
272603
  });
272614
272604
  }
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
- }
272633
272605
  /**
272634
272606
  * 获取云函数详细信息
272635
272607
  * @param {string} name 云函数名称
@@ -272664,35 +272636,13 @@ class FunctionService {
272664
272636
  }
272665
272637
  catch (e) {
272666
272638
  data.VpcConfig = {
272667
- vpc: 'VpcId',
272668
- subnet: 'SubnetId'
272639
+ vpc: '',
272640
+ subnet: ''
272669
272641
  };
272670
272642
  }
272671
272643
  }
272672
272644
  return data;
272673
272645
  }
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
- }
272696
272646
  /**
272697
272647
  * 获取函数日志
272698
272648
  * @deprecated 请使用 getFunctionLogsV2 代替
@@ -272789,33 +272739,6 @@ class FunctionService {
272789
272739
  const res = await this.tcbService.request('GetFunctionLogDetail', params);
272790
272740
  return res;
272791
272741
  }
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
- }
272819
272742
  /**
272820
272743
  * 更新云函数配置
272821
272744
  * @param {ICloudFunction} func 云函数配置
@@ -272951,28 +272874,6 @@ class FunctionService {
272951
272874
  throw new error_1.CloudBaseError(`[${name}] 调用失败:\n${e.message}`);
272952
272875
  }
272953
272876
  }
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
- }
272976
272877
  /**
272977
272878
  * 复制云函数
272978
272879
  * @param {string} name 云函数名称
@@ -273015,34 +272916,12 @@ class FunctionService {
273015
272916
  TriggerDesc: item.config
273016
272917
  };
273017
272918
  });
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);
272919
+ return this.scfService.request('BatchCreateTrigger', {
272920
+ FunctionName: name,
272921
+ Namespace: namespace,
272922
+ Triggers: JSON.stringify(parsedTriggers),
272923
+ Count: parsedTriggers.length
272924
+ });
273046
272925
  }
273047
272926
  /**
273048
272927
  * 删除云函数触发器
@@ -273052,50 +272931,12 @@ class FunctionService {
273052
272931
  */
273053
272932
  async deleteFunctionTrigger(name, triggerName) {
273054
272933
  const { namespace } = this.getFunctionConfig();
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
272934
+ return this.scfService.request('DeleteTrigger', {
272935
+ FunctionName: name,
272936
+ Namespace: namespace,
272937
+ TriggerName: triggerName,
272938
+ Type: 'timer'
273096
272939
  });
273097
- // 下载文件
273098
- return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
273099
272940
  }
273100
272941
  /**
273101
272942
  * 获取云函数代码下载 链接
@@ -273121,68 +272962,6 @@ class FunctionService {
273121
272962
  throw new error_1.CloudBaseError(`[${functionName}] 获取函数代码下载链接失败:\n${e.message}`);
273122
272963
  }
273123
272964
  }
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
- }
273186
272965
  // 创建文件层版本
273187
272966
  async createLayer(options) {
273188
272967
  const { env } = this.getFunctionConfig();
@@ -273255,7 +273034,7 @@ class FunctionService {
273255
273034
  Limit: limit,
273256
273035
  Offset: offset,
273257
273036
  SearchKey: searchKey,
273258
- // SearchSrc: `TCB_${env}`
273037
+ SearchSrc: `TCB_${env}`
273259
273038
  };
273260
273039
  if (runtime) {
273261
273040
  param.CompatibleRuntime = runtime;
@@ -273584,18 +273363,12 @@ __decorate([
273584
273363
  __decorate([
273585
273364
  (0, utils_1.preLazy)()
273586
273365
  ], FunctionService.prototype, "listFunctions", null);
273587
- __decorate([
273588
- (0, utils_1.preLazy)()
273589
- ], FunctionService.prototype, "listAllFunctions", null);
273590
273366
  __decorate([
273591
273367
  (0, utils_1.preLazy)()
273592
273368
  ], FunctionService.prototype, "deleteFunction", null);
273593
273369
  __decorate([
273594
273370
  (0, utils_1.preLazy)()
273595
273371
  ], FunctionService.prototype, "getFunctionDetail", null);
273596
- __decorate([
273597
- (0, utils_1.preLazy)()
273598
- ], FunctionService.prototype, "batchGetFunctionsDetail", null);
273599
273372
  __decorate([
273600
273373
  (0, utils_1.preLazy)()
273601
273374
  ], FunctionService.prototype, "getFunctionLogs", null);
@@ -273605,9 +273378,6 @@ __decorate([
273605
273378
  __decorate([
273606
273379
  (0, utils_1.preLazy)()
273607
273380
  ], FunctionService.prototype, "getFunctionLogDetail", null);
273608
- __decorate([
273609
- (0, utils_1.preLazy)()
273610
- ], FunctionService.prototype, "getCompleteFunctionLogs", null);
273611
273381
  __decorate([
273612
273382
  (0, utils_1.preLazy)()
273613
273383
  ], FunctionService.prototype, "updateFunctionConfig", null);
@@ -273617,9 +273387,6 @@ __decorate([
273617
273387
  __decorate([
273618
273388
  (0, utils_1.preLazy)()
273619
273389
  ], FunctionService.prototype, "invokeFunction", null);
273620
- __decorate([
273621
- (0, utils_1.preLazy)()
273622
- ], FunctionService.prototype, "batchInvokeFunctions", null);
273623
273390
  __decorate([
273624
273391
  (0, utils_1.preLazy)()
273625
273392
  ], FunctionService.prototype, "copyFunction", null);
@@ -273632,18 +273399,6 @@ __decorate([
273632
273399
  __decorate([
273633
273400
  (0, utils_1.preLazy)()
273634
273401
  ], 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);
273647
273402
  __decorate([
273648
273403
  (0, utils_1.preLazy)()
273649
273404
  ], FunctionService.prototype, "createLayer", null);