@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/index.cjs CHANGED
@@ -101,7 +101,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
101
101
  Object.defineProperty(exports, "__esModule", ({ value: true }));
102
102
  exports.CloudRunService = void 0;
103
103
  exports.codeToZip = codeToZip;
104
- exports.parseObjectToDiffConfigItem = parseObjectToDiffConfigItem;
105
104
  const archiver_1 = __importDefault(__webpack_require__(99133));
106
105
  const fs_extra_1 = __webpack_require__(21605);
107
106
  const path_1 = __importDefault(__webpack_require__(39902));
@@ -270,7 +269,7 @@ class CloudRunService {
270
269
  /**
271
270
  * 上传部署包
272
271
  */
273
- const zipFile = await codeToZip(targetPath, { installDependency: (serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.InstallDependency) !== undefined ? serverConfig.InstallDependency : true });
272
+ const zipFile = await codeToZip(targetPath, { installDependency: true });
274
273
  await (0, utils_1.upload)({
275
274
  url: uploadUrl,
276
275
  file: zipFile,
@@ -286,14 +285,8 @@ class CloudRunService {
286
285
  if (await this._checkFunctionExist(serverName)) {
287
286
  // 更新
288
287
  const serverDetail = await this.detail({ serverName });
289
- 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
288
+ 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
290
289
  );
291
- if ((serverDetail === null || serverDetail === void 0 ? void 0 : serverDetail.ServerConfig.Tag) === 'function:') {
292
- deployInfo.BuildPacks = {
293
- LanguageVersion: '20.18',
294
- RepoLanguage: 'Node.js'
295
- };
296
- }
297
290
  deployInfo.ReleaseType = 'FULL';
298
291
  return this._upsertFunction(false, {
299
292
  name: serverName,
@@ -321,13 +314,7 @@ class CloudRunService {
321
314
  RepoLanguage: 'Node.js'
322
315
  };
323
316
  }
324
- const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC', 'MINIAPP'],
325
- // Cpu: 0,
326
- // Mem: 0,
327
- MinNum: 0,
328
- // MaxNum: 0,
329
- // PolicyDetails: [],
330
- 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:' });
317
+ 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:' });
331
318
  return this._upsertFunction(true, {
332
319
  name: serverName,
333
320
  deployInfo,
@@ -361,12 +348,11 @@ class CloudRunService {
361
348
  _upsertFunction(isNew, data) {
362
349
  const { name, deployInfo, serverConfig } = data;
363
350
  const envConfig = this.environment.lazyEnvironmentConfig;
364
- const Items = parseObjectToDiffConfigItem(serverConfig);
365
351
  return this.tcbrService.request(isNew ? 'CreateCloudRunServer' : 'UpdateCloudRunServer', {
366
352
  EnvId: envConfig.EnvId,
367
353
  ServerName: name,
368
354
  DeployInfo: deployInfo,
369
- Items,
355
+ ServerConfig: serverConfig
370
356
  });
371
357
  }
372
358
  }
@@ -439,63 +425,6 @@ async function codeToZip(cwd, options) {
439
425
  await archive.finalize();
440
426
  return bufferPromise;
441
427
  }
442
- /**
443
- * 提交参数变化映射
444
- */
445
- const SUBMIT_DIFF_MAP = {
446
- Cpu: 'CpuSpecs',
447
- Mem: 'MemSpecs',
448
- OpenAccessTypes: 'AccessTypes',
449
- EnvParams: 'EnvParam',
450
- CustomLogs: 'LogPath'
451
- };
452
- /**
453
- * 将 object 参数转为 [{key:"Port", IntValue:80}] 的格式,并且剔除空字符串
454
- */
455
- function parseObjectToDiffConfigItem(data) {
456
- const kvs = Object.entries(data);
457
- const Items = [];
458
- kvs.forEach(([k, v]) => {
459
- const Key = SUBMIT_DIFF_MAP[k] || k;
460
- if ([
461
- 'CustomLogs',
462
- 'EnvParams',
463
- 'CreateTime',
464
- 'Dockerfile',
465
- 'BuildDir',
466
- 'LogType',
467
- 'LogSetId',
468
- 'LogTopicId',
469
- 'LogParseType',
470
- 'Tag',
471
- 'InternalAccess',
472
- 'InternalDomain',
473
- 'OperationMode',
474
- 'SessionAffinity'
475
- ].includes(k)) {
476
- !!v && Items.push({ Key, Value: v });
477
- }
478
- else if (['MinNum', 'MaxNum', 'InitialDelaySeconds', 'Port'].includes(k)) {
479
- Items.push({ Key, IntValue: v });
480
- }
481
- else if (['HasDockerfile'].includes(k)) {
482
- Items.push({ Key, BoolValue: v });
483
- }
484
- else if (['Cpu', 'Mem'].includes(k)) {
485
- Items.push({ Key, FloatValue: v });
486
- }
487
- else if (['OpenAccessTypes', 'EntryPoint', 'Cmd'].includes(k)) {
488
- Items.push({ Key, ArrayValue: v });
489
- }
490
- else if (['PolicyDetails'].includes(k)) {
491
- Items.push({ Key, PolicyDetails: v });
492
- }
493
- else if (['TimerScale'].includes(k)) {
494
- Items.push({ Key, TimerScale: v });
495
- }
496
- });
497
- return Items;
498
- }
499
428
 
500
429
 
501
430
  /***/ }),
@@ -48615,7 +48544,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
48615
48544
  exports.cloudBaseRequest = cloudBaseRequest;
48616
48545
  const auth_1 = __webpack_require__(23506);
48617
48546
  const http_request_1 = __webpack_require__(72088);
48618
- const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou', 'ap-singapore'];
48547
+ const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou'];
48619
48548
  async function cloudBaseRequest(options) {
48620
48549
  // const url = 'https://tcb-admin.tencentcloudapi.com/admin'
48621
48550
  const { config, params = {}, method = 'POST', headers = {} } = options;
@@ -48629,11 +48558,11 @@ async function cloudBaseRequest(options) {
48629
48558
  let internalRegionEndpoint = '';
48630
48559
  if (finalRegion) {
48631
48560
  if (SUPPORT_REGIONS.includes(finalRegion)) {
48632
- internetRegionEndpoint = `${envId}.${finalRegion}.tcb-api.tencentcloudapi.com`;
48633
- internalRegionEndpoint = `${envId}.internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
48561
+ internetRegionEndpoint = `${finalRegion}.tcb-api.tencentcloudapi.com`;
48562
+ internalRegionEndpoint = `internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
48634
48563
  }
48635
48564
  else {
48636
- console.warn('当前仅支持上海,广州,新加坡地域,其他地域默认解析到固定域名(上海地域)');
48565
+ console.warn('当前仅支持上海,广州地域,其他地域默认解析到固定域名(上海地域)');
48637
48566
  internetRegionEndpoint = `tcb-api.tencentcloudapi.com`;
48638
48567
  internalRegionEndpoint = `internal.tcb-api.tencentcloudapi.com`;
48639
48568
  }
@@ -90226,20 +90155,19 @@ class EnvService {
90226
90155
  });
90227
90156
  }
90228
90157
  getCos() {
90229
- const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
90230
90158
  const { secretId, secretKey, token } = this.environment.getAuthConfig();
90231
90159
  const cosConfig = {
90232
90160
  SecretId: secretId,
90233
90161
  SecretKey: secretKey,
90234
90162
  SecurityToken: token,
90235
- Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
90163
+ Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
90236
90164
  };
90237
90165
  if (constant_1.COS_SDK_PROTOCOL) {
90238
90166
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
90239
90167
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
90240
90168
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
90241
90169
  }
90242
- if (internalEndpoint) {
90170
+ if (constant_1.USE_INTERNAL_ENDPOINT) {
90243
90171
  cosConfig.Protocol = 'http:';
90244
90172
  }
90245
90173
  return new cos_nodejs_sdk_v5_1.default(cosConfig);
@@ -134933,7 +134861,7 @@ class TelemetryReporter {
134933
134861
  const nodeVersion = process.version; // Node.js版本
134934
134862
  const arch = os_1.default.arch(); // 系统架构
134935
134863
  // 从构建时注入的版本号获取MCP版本信息
134936
- const mcpVersion = process.env.npm_package_version || "2.2.0" || 0;
134864
+ const mcpVersion = process.env.npm_package_version || "2.3.1" || 0;
134937
134865
  return {
134938
134866
  userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
134939
134867
  deviceId: this.deviceId,
@@ -179531,7 +179459,6 @@ exports.sleep = sleep;
179531
179459
  exports.upperCaseStringFisrt = upperCaseStringFisrt;
179532
179460
  exports.upperCaseObjKey = upperCaseObjKey;
179533
179461
  exports.fetchTemplates = fetchTemplates;
179534
- exports.successLog = successLog;
179535
179462
  const archiver_1 = __importDefault(__webpack_require__(99133));
179536
179463
  const crypto_1 = __importDefault(__webpack_require__(55511));
179537
179464
  const fs_extra_1 = __importDefault(__webpack_require__(21605));
@@ -179810,10 +179737,6 @@ const getCompleteTimeRange = (timeRange) => {
179810
179737
  };
179811
179738
  };
179812
179739
  exports.getCompleteTimeRange = getCompleteTimeRange;
179813
- function successLog(msg) {
179814
- // 空格,兼容中文字符编码长度问题
179815
- console.log(`${msg}`);
179816
- }
179817
179740
 
179818
179741
 
179819
179742
  /***/ }),
@@ -185411,7 +185334,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
185411
185334
  return (mod && mod.__esModule) ? mod : { "default": mod };
185412
185335
  };
185413
185336
  Object.defineProperty(exports, "__esModule", ({ value: true }));
185414
- exports.downloadWebTemplate = downloadWebTemplate;
185415
185337
  exports.getClaudePrompt = getClaudePrompt;
185416
185338
  exports.registerRagTools = registerRagTools;
185417
185339
  const adm_zip_1 = __importDefault(__webpack_require__(30283));
@@ -185429,6 +185351,58 @@ const KnowledgeBaseIdMap = {
185429
185351
  scf: "scfsczskzyws_4bdc",
185430
185352
  miniprogram: "xcxzskws_25d8",
185431
185353
  };
185354
+ // ============ 缓存配置 ============
185355
+ const CACHE_BASE_DIR = path.join(os.homedir(), ".cloudbase-mcp");
185356
+ const CACHE_META_FILE = path.join(CACHE_BASE_DIR, "cache-meta.json");
185357
+ const DEFAULT_CACHE_TTL_MS = 24 * 60 * 60 * 1000; // 默认 24 小时
185358
+ // 支持环境变量 CLOUDBASE_MCP_CACHE_TTL_MS 控制缓存过期时间(毫秒)
185359
+ const parsedCacheTTL = process.env.CLOUDBASE_MCP_CACHE_TTL_MS
185360
+ ? parseInt(process.env.CLOUDBASE_MCP_CACHE_TTL_MS, 10)
185361
+ : NaN;
185362
+ const CACHE_TTL_MS = Number.isNaN(parsedCacheTTL) || parsedCacheTTL < 0
185363
+ ? DEFAULT_CACHE_TTL_MS
185364
+ : parsedCacheTTL;
185365
+ if (!Number.isNaN(parsedCacheTTL) && parsedCacheTTL >= 0) {
185366
+ (0, logger_js_1.debug)("[cache] Using TTL from CLOUDBASE_MCP_CACHE_TTL_MS", {
185367
+ ttlMs: CACHE_TTL_MS,
185368
+ });
185369
+ }
185370
+ else {
185371
+ (0, logger_js_1.debug)("[cache] Using default TTL", { ttlMs: CACHE_TTL_MS });
185372
+ }
185373
+ // 共享的下载 Promise,防止并发重复下载
185374
+ let resourceDownloadPromise = null;
185375
+ // 检查缓存是否可用(未过期)
185376
+ async function canUseCache() {
185377
+ try {
185378
+ const content = await fs.readFile(CACHE_META_FILE, "utf8");
185379
+ const meta = JSON.parse(content);
185380
+ if (!meta.timestamp) {
185381
+ (0, logger_js_1.debug)("[cache] cache-meta missing timestamp, treating as invalid", {
185382
+ ttlMs: CACHE_TTL_MS,
185383
+ });
185384
+ return false;
185385
+ }
185386
+ const ageMs = Date.now() - meta.timestamp;
185387
+ const isValid = ageMs <= CACHE_TTL_MS;
185388
+ (0, logger_js_1.debug)("[cache] evaluated cache meta", {
185389
+ timestamp: meta.timestamp,
185390
+ ageMs,
185391
+ ttlMs: CACHE_TTL_MS,
185392
+ valid: isValid,
185393
+ });
185394
+ return isValid;
185395
+ }
185396
+ catch (error) {
185397
+ (0, logger_js_1.debug)("[cache] failed to read cache meta, treating as miss", { error });
185398
+ return false;
185399
+ }
185400
+ }
185401
+ // 更新缓存时间戳
185402
+ async function updateCache() {
185403
+ await fs.mkdir(CACHE_BASE_DIR, { recursive: true });
185404
+ await fs.writeFile(CACHE_META_FILE, JSON.stringify({ timestamp: Date.now() }, null, 2), "utf8");
185405
+ }
185432
185406
  // 安全 JSON.parse
185433
185407
  function safeParse(str) {
185434
185408
  try {
@@ -185455,31 +185429,141 @@ function safeStringify(obj) {
185455
185429
  return "";
185456
185430
  }
185457
185431
  }
185458
- // Download and extract web template, return extract directory path
185459
- // Always downloads and overwrites existing template
185432
+ // OpenAPI 文档 URL 列表
185433
+ const OPENAPI_SOURCES = [
185434
+ {
185435
+ name: "mysqldb",
185436
+ description: "MySQL RESTful API - 云开发 MySQL 数据库 HTTP API",
185437
+ url: "https://docs.cloudbase.net/openapi/mysqldb.v1.openapi.yaml",
185438
+ },
185439
+ {
185440
+ name: "functions",
185441
+ description: "Cloud Functions API - 云函数 HTTP API",
185442
+ url: "https://docs.cloudbase.net/openapi/functions.v1.openapi.yaml",
185443
+ },
185444
+ {
185445
+ name: "auth",
185446
+ description: "Authentication API - 身份认证 HTTP API",
185447
+ url: "https://docs.cloudbase.net/openapi/auth.v1.openapi.yaml",
185448
+ },
185449
+ {
185450
+ name: "cloudrun",
185451
+ description: "CloudRun API - 云托管服务 HTTP API",
185452
+ url: "https://docs.cloudbase.net/openapi/cloudrun.v1.openapi.yaml",
185453
+ },
185454
+ {
185455
+ name: "storage",
185456
+ description: "Storage API - 云存储 HTTP API",
185457
+ url: "https://docs.cloudbase.net/openapi/storage.v1.openapi.yaml",
185458
+ },
185459
+ ];
185460
185460
  async function downloadWebTemplate() {
185461
- const baseDir = path.join(os.homedir(), ".cloudbase-mcp");
185462
- const zipPath = path.join(baseDir, "web-cloudbase-project.zip");
185463
- const extractDir = path.join(baseDir, "web-template");
185461
+ const zipPath = path.join(CACHE_BASE_DIR, "web-cloudbase-project.zip");
185462
+ const extractDir = path.join(CACHE_BASE_DIR, "web-template");
185464
185463
  const url = "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip";
185465
- await fs.mkdir(baseDir, { recursive: true });
185466
- // Download zip to specified path (overwrite)
185467
185464
  const response = await fetch(url);
185468
185465
  if (!response.ok) {
185469
185466
  throw new Error(`下载模板失败,状态码: ${response.status}`);
185470
185467
  }
185471
185468
  const buffer = Buffer.from(await response.arrayBuffer());
185472
185469
  await fs.writeFile(zipPath, buffer);
185473
- // Clean and recreate extract directory
185474
185470
  await fs.rm(extractDir, { recursive: true, force: true });
185475
185471
  await fs.mkdir(extractDir, { recursive: true });
185476
185472
  const zip = new adm_zip_1.default(zipPath);
185477
185473
  zip.extractAllTo(extractDir, true);
185474
+ (0, logger_js_1.debug)("[downloadResources] webTemplate 下载完成");
185478
185475
  return extractDir;
185479
185476
  }
185480
- async function prepareKnowledgeBaseWebTemplate() {
185481
- const extractDir = await downloadWebTemplate();
185482
- return collectSkillDescriptions(path.join(extractDir, ".claude", "skills"));
185477
+ async function downloadOpenAPI() {
185478
+ const baseDir = path.join(CACHE_BASE_DIR, "openapi");
185479
+ await fs.mkdir(baseDir, { recursive: true });
185480
+ const results = [];
185481
+ await Promise.all(OPENAPI_SOURCES.map(async (source) => {
185482
+ try {
185483
+ const response = await fetch(source.url);
185484
+ if (!response.ok) {
185485
+ (0, logger_js_1.warn)(`[downloadOpenAPI] Failed to download ${source.name}`, {
185486
+ status: response.status,
185487
+ });
185488
+ return;
185489
+ }
185490
+ const content = await response.text();
185491
+ const filePath = path.join(baseDir, `${source.name}.openapi.yaml`);
185492
+ await fs.writeFile(filePath, content, "utf8");
185493
+ results.push({
185494
+ name: source.name,
185495
+ description: source.description,
185496
+ absolutePath: filePath,
185497
+ });
185498
+ }
185499
+ catch (error) {
185500
+ (0, logger_js_1.warn)(`[downloadOpenAPI] Failed to download ${source.name}`, {
185501
+ error,
185502
+ });
185503
+ }
185504
+ }));
185505
+ (0, logger_js_1.debug)("[downloadOpenAPI] openAPIDocs 下载完成", {
185506
+ successCount: results.length,
185507
+ total: OPENAPI_SOURCES.length,
185508
+ });
185509
+ return results;
185510
+ }
185511
+ // 实际执行下载所有资源的函数(webTemplate 和 openAPI 并发下载)
185512
+ async function _doDownloadResources() {
185513
+ // 并发下载 webTemplate 和 openAPIDocs
185514
+ const [webTemplateDir, openAPIDocs] = await Promise.all([
185515
+ // 下载 web 模板
185516
+ downloadWebTemplate(),
185517
+ // 并发下载所有 OpenAPI 文档
185518
+ downloadOpenAPI(),
185519
+ ]);
185520
+ (0, logger_js_1.debug)("[downloadResources] 所有资源下载完成");
185521
+ return { webTemplateDir, openAPIDocs };
185522
+ }
185523
+ // 下载所有资源(带缓存和共享 Promise 机制)
185524
+ async function downloadResources() {
185525
+ const webTemplateDir = path.join(CACHE_BASE_DIR, "web-template");
185526
+ const openAPIDir = path.join(CACHE_BASE_DIR, "openapi");
185527
+ // 检查缓存是否有效
185528
+ if (await canUseCache()) {
185529
+ try {
185530
+ // 检查两个目录都存在
185531
+ await Promise.all([fs.access(webTemplateDir), fs.access(openAPIDir)]);
185532
+ const files = await fs.readdir(openAPIDir);
185533
+ if (files.length > 0) {
185534
+ (0, logger_js_1.debug)("[downloadResources] 使用缓存");
185535
+ return {
185536
+ webTemplateDir,
185537
+ openAPIDocs: OPENAPI_SOURCES.map((source) => ({
185538
+ name: source.name,
185539
+ description: source.description,
185540
+ absolutePath: path.join(openAPIDir, `${source.name}.openapi.yaml`),
185541
+ })).filter((item) => files.includes(`${item.name}.openapi.yaml`)),
185542
+ };
185543
+ }
185544
+ }
185545
+ catch {
185546
+ // 缓存无效,需要重新下载
185547
+ }
185548
+ }
185549
+ // 如果已有下载任务在进行中,共享该 Promise
185550
+ if (resourceDownloadPromise) {
185551
+ (0, logger_js_1.debug)("[downloadResources] 共享已有下载任务");
185552
+ return resourceDownloadPromise;
185553
+ }
185554
+ // 创建新的下载任务
185555
+ (0, logger_js_1.debug)("[downloadResources] 开始新下载任务");
185556
+ await fs.mkdir(CACHE_BASE_DIR, { recursive: true });
185557
+ resourceDownloadPromise = _doDownloadResources()
185558
+ .then(async (result) => {
185559
+ await updateCache();
185560
+ (0, logger_js_1.debug)("[downloadResources] 缓存已更新");
185561
+ return result;
185562
+ })
185563
+ .finally(() => {
185564
+ resourceDownloadPromise = null;
185565
+ });
185566
+ return resourceDownloadPromise;
185483
185567
  }
185484
185568
  // Get CLAUDE.md prompt content
185485
185569
  // Priority: 1. From downloaded template, 2. Fallback to embedded constant
@@ -185603,23 +185687,15 @@ async function registerRagTools(server) {
185603
185687
  };
185604
185688
  }
185605
185689
  });
185606
- let skills = [];
185607
185690
  let openapis = [];
185608
- // 知识库检索
185609
- try {
185610
- skills = await prepareKnowledgeBaseWebTemplate();
185611
- }
185612
- catch (error) {
185613
- (0, logger_js_1.warn)("[searchKnowledgeBase] Failed to prepare web template", {
185614
- error,
185615
- });
185616
- }
185617
- // OpenAPI 文档准备
185691
+ let skills = [];
185618
185692
  try {
185619
- openapis = await prepareOpenAPIDocs();
185693
+ const { webTemplateDir, openAPIDocs } = await downloadResources();
185694
+ openapis = openAPIDocs;
185695
+ skills = await collectSkillDescriptions(path.join(webTemplateDir, ".claude", "skills"));
185620
185696
  }
185621
185697
  catch (error) {
185622
- (0, logger_js_1.warn)("[searchKnowledgeBase] Failed to prepare OpenAPI docs", {
185698
+ (0, logger_js_1.warn)("[downloadResources] Failed to download resources", {
185623
185699
  error,
185624
185700
  });
185625
185701
  }
@@ -185786,65 +185862,6 @@ function extractDescriptionFromFrontMatter(content) {
185786
185862
  .match(/^(?:decsription|description)\s*:\s*(.*)$/m);
185787
185863
  return match ? match[1].trim() : null;
185788
185864
  }
185789
- // OpenAPI 文档 URL 列表
185790
- const OPENAPI_SOURCES = [
185791
- {
185792
- name: "mysqldb",
185793
- description: "MySQL RESTful API - 云开发 MySQL 数据库 HTTP API",
185794
- url: "https://docs.cloudbase.net/openapi/mysqldb.v1.openapi.yaml",
185795
- },
185796
- {
185797
- name: "functions",
185798
- description: "Cloud Functions API - 云函数 HTTP API",
185799
- url: "https://docs.cloudbase.net/openapi/functions.v1.openapi.yaml",
185800
- },
185801
- {
185802
- name: "auth",
185803
- description: "Authentication API - 身份认证 HTTP API",
185804
- url: "https://docs.cloudbase.net/openapi/auth.v1.openapi.yaml",
185805
- },
185806
- {
185807
- name: "cloudrun",
185808
- description: "CloudRun API - 云托管服务 HTTP API",
185809
- url: "https://docs.cloudbase.net/openapi/cloudrun.v1.openapi.yaml",
185810
- },
185811
- {
185812
- name: "storage",
185813
- description: "Storage API - 云存储 HTTP API",
185814
- url: "https://docs.cloudbase.net/openapi/storage.v1.openapi.yaml",
185815
- },
185816
- ];
185817
- // 下载并准备 OpenAPI 文档
185818
- async function prepareOpenAPIDocs() {
185819
- const baseDir = path.join(os.homedir(), ".cloudbase-mcp", "openapi");
185820
- await fs.mkdir(baseDir, { recursive: true });
185821
- const results = [];
185822
- await Promise.all(OPENAPI_SOURCES.map(async (source) => {
185823
- try {
185824
- const response = await fetch(source.url);
185825
- if (!response.ok) {
185826
- (0, logger_js_1.warn)(`[prepareOpenAPIDocs] Failed to download ${source.name}`, {
185827
- status: response.status,
185828
- });
185829
- return;
185830
- }
185831
- const content = await response.text();
185832
- const filePath = path.join(baseDir, `${source.name}.openapi.yaml`);
185833
- await fs.writeFile(filePath, content, "utf8");
185834
- results.push({
185835
- name: source.name,
185836
- description: source.description,
185837
- absolutePath: filePath,
185838
- });
185839
- }
185840
- catch (error) {
185841
- (0, logger_js_1.warn)(`[prepareOpenAPIDocs] Failed to download ${source.name}`, {
185842
- error,
185843
- });
185844
- }
185845
- }));
185846
- return results;
185847
- }
185848
185865
  async function collectSkillDescriptions(rootDir) {
185849
185866
  const result = [];
185850
185867
  async function walk(dir) {
@@ -191142,25 +191159,20 @@ function callSuccessCallback(callback, result) {
191142
191159
  /***/ }),
191143
191160
 
191144
191161
  /***/ 65607:
191145
- /***/ ((__unused_webpack_module, exports, __webpack_require__) => {
191162
+ /***/ ((__unused_webpack_module, exports) => {
191146
191163
 
191147
191164
  "use strict";
191148
191165
 
191149
191166
  Object.defineProperty(exports, "__esModule", ({ value: true }));
191150
191167
  exports.CloudBaseContext = void 0;
191151
- const constant_1 = __webpack_require__(40762);
191152
191168
  class CloudBaseContext {
191153
- constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined }) {
191169
+ constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
191154
191170
  this.secretId = secretId;
191155
191171
  this.secretKey = secretKey;
191156
191172
  this.token = token;
191157
191173
  this.proxy = proxy;
191158
191174
  this.region = region;
191159
191175
  this.envType = envType;
191160
- this.useInternalEndpoint = useInternalEndpoint;
191161
- }
191162
- isInternalEndpoint() {
191163
- return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
191164
191176
  }
191165
191177
  }
191166
191178
  exports.CloudBaseContext = CloudBaseContext;
@@ -200687,7 +200699,7 @@ ${envIdSection}
200687
200699
  ## 环境信息
200688
200700
  - 操作系统: ${os_1.default.type()} ${os_1.default.release()}
200689
200701
  - Node.js版本: ${process.version}
200690
- - MCP 版本:${process.env.npm_package_version || "2.2.0" || 0}
200702
+ - MCP 版本:${process.env.npm_package_version || "2.3.1" || 0}
200691
200703
  - 系统架构: ${os_1.default.arch()}
200692
200704
  - 时间: ${new Date().toISOString()}
200693
200705
  - 请求ID: ${requestId}
@@ -203579,7 +203591,6 @@ class StorageService {
203579
203591
  * 获取 COS 配置
203580
203592
  */
203581
203593
  getCos(parallel = 20) {
203582
- const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
203583
203594
  const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
203584
203595
  const cosProxy = process.env.TCB_COS_PROXY;
203585
203596
  const cosConfig = {
@@ -203588,14 +203599,14 @@ class StorageService {
203588
203599
  SecretKey: secretKey,
203589
203600
  Proxy: cosProxy || proxy,
203590
203601
  SecurityToken: token,
203591
- Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
203602
+ Domain: constant_1.USE_INTERNAL_ENDPOINT ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
203592
203603
  };
203593
203604
  if (constant_1.COS_SDK_PROTOCOL) {
203594
203605
  cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
203595
203606
  ? constant_1.COS_SDK_PROTOCOL.toLowerCase()
203596
203607
  : constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
203597
203608
  }
203598
- if (internalEndpoint) {
203609
+ if (constant_1.USE_INTERNAL_ENDPOINT) {
203599
203610
  cosConfig.Protocol = 'http:';
203600
203611
  }
203601
203612
  // COSSDK 默认开启 KeepAlive,这里提供关闭的方式
@@ -215026,12 +215037,15 @@ const IDE_TYPES = [
215026
215037
  "roocode", // RooCode AI编辑器
215027
215038
  "tongyi-lingma", // 通义灵码
215028
215039
  "trae", // Trae AI编辑器
215040
+ "qoder", // Qoder AI编辑器
215041
+ "antigravity", // Google Antigravity AI编辑器
215029
215042
  "vscode", // Visual Studio Code
215030
215043
  ];
215031
215044
  // IDE到文件的映射关系
215045
+ // 注意:以 "/" 结尾的路径表示目录,会包含该目录下的所有文件
215032
215046
  const IDE_FILE_MAPPINGS = {
215033
- cursor: [".cursor/rules/cloudbase-rules.mdc", ".cursor/mcp.json"],
215034
- windsurf: [".windsurf/rules/cloudbase-rules.md"],
215047
+ cursor: [".cursor/rules/", ".cursor/mcp.json"],
215048
+ windsurf: [".windsurf/rules/"],
215035
215049
  codebuddy: [".rules/cloudbase-rules.md", "CODEBUDDY.md", ".mcp.json"],
215036
215050
  "claude-code": [
215037
215051
  "CLAUDE.md",
@@ -215041,7 +215055,7 @@ const IDE_FILE_MAPPINGS = {
215041
215055
  ".claude/commands/spec.md",
215042
215056
  ".claude/commands/no_spec.md",
215043
215057
  ],
215044
- cline: [".clinerules/cloudbase-rules.mdc"],
215058
+ cline: [".clinerules/"],
215045
215059
  "gemini-cli": [".gemini/GEMINI.md", ".gemini/settings.json"],
215046
215060
  opencode: [".opencode.json"],
215047
215061
  "qwen-code": [".qwen/QWEN.md", ".qwen/settings.json"],
@@ -215055,7 +215069,9 @@ const IDE_FILE_MAPPINGS = {
215055
215069
  "github-copilot": [".github/copilot-instructions.md"],
215056
215070
  roocode: [".roo/rules/cloudbaase-rules.md", ".roo/mcp.json"],
215057
215071
  "tongyi-lingma": [".lingma/rules/cloudbaase-rules.md"],
215058
- trae: [".trae/rules/cloudbase-rules.md"],
215072
+ trae: [".trae/rules/"],
215073
+ qoder: [".qoder/rules/"],
215074
+ antigravity: [".agent/rules/"],
215059
215075
  vscode: [".vscode/mcp.json", ".vscode/settings.json"],
215060
215076
  };
215061
215077
  // 所有IDE配置文件的完整列表 - 通过IDE_FILE_MAPPINGS计算得出
@@ -215080,6 +215096,8 @@ const IDE_DESCRIPTIONS = {
215080
215096
  roocode: "RooCode AI编辑器",
215081
215097
  "tongyi-lingma": "通义灵码",
215082
215098
  trae: "Trae AI编辑器",
215099
+ qoder: "Qoder AI编辑器",
215100
+ antigravity: "Google Antigravity AI编辑器",
215083
215101
  vscode: "Visual Studio Code",
215084
215102
  };
215085
215103
  // INTEGRATION_IDE 环境变量值到 IDE 类型的映射
@@ -215101,6 +215119,8 @@ const INTEGRATION_IDE_MAPPING = {
215101
215119
  RooCode: "roocode",
215102
215120
  "Tongyi Lingma": "tongyi-lingma",
215103
215121
  Trae: "trae",
215122
+ Qoder: "qoder",
215123
+ Antigravity: "antigravity",
215104
215124
  VSCode: "vscode",
215105
215125
  };
215106
215126
  // 根据 INTEGRATION_IDE 环境变量获取默认 IDE 类型
@@ -215251,6 +215271,17 @@ function validateIDE(ide) {
215251
215271
  }
215252
215272
  return { valid: true };
215253
215273
  }
215274
+ // 检查文件是否匹配给定的路径(支持文件和目录)
215275
+ function matchesPath(file, pathPattern) {
215276
+ if (pathPattern.endsWith("/")) {
215277
+ // 目录路径:检查文件是否在该目录下
215278
+ return file.startsWith(pathPattern);
215279
+ }
215280
+ else {
215281
+ // 文件路径:精确匹配
215282
+ return file === pathPattern;
215283
+ }
215284
+ }
215254
215285
  // 文件过滤函数
215255
215286
  function filterFilesByIDE(files, ide) {
215256
215287
  if (ide === "all") {
@@ -215261,9 +215292,32 @@ function filterFilesByIDE(files, ide) {
215261
215292
  return files; // 如果找不到映射,返回所有文件
215262
215293
  }
215263
215294
  // 计算需要排除的IDE文件(除了当前IDE需要的文件)
215264
- const filesToExclude = ALL_IDE_FILES.filter((file) => !ideFiles.includes(file));
215295
+ const filesToExclude = [];
215296
+ // 遍历所有IDE文件,找出不属于当前IDE的文件
215297
+ for (const ideFile of ALL_IDE_FILES) {
215298
+ // 检查这个文件是否属于当前IDE需要的文件
215299
+ let isCurrentIDEFile = false;
215300
+ for (const currentIDEFile of ideFiles) {
215301
+ if (matchesPath(ideFile, currentIDEFile)) {
215302
+ isCurrentIDEFile = true;
215303
+ break;
215304
+ }
215305
+ }
215306
+ // 如果不属于当前IDE,加入排除列表
215307
+ if (!isCurrentIDEFile) {
215308
+ filesToExclude.push(ideFile);
215309
+ }
215310
+ }
215265
215311
  // 排除不需要的IDE配置文件,保留其他所有文件
215266
- return files.filter((file) => !filesToExclude.includes(file));
215312
+ return files.filter((file) => {
215313
+ // 检查文件是否应该被排除
215314
+ for (const excludePath of filesToExclude) {
215315
+ if (matchesPath(file, excludePath)) {
215316
+ return false; // 排除
215317
+ }
215318
+ }
215319
+ return true; // 保留
215320
+ });
215267
215321
  }
215268
215322
  // 创建过滤后的目录结构
215269
215323
  async function createFilteredDirectory(extractDir, filteredFiles, ide) {
@@ -215290,7 +215344,7 @@ function registerSetupTools(server) {
215290
215344
  title: "下载项目模板",
215291
215345
  description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
215292
215346
 
215293
- **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)`,
215347
+ **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)`,
215294
215348
  inputSchema: {
215295
215349
  template: zod_1.z
215296
215350
  .enum(["react", "vue", "miniprogram", "uniapp", "rules"])
@@ -226392,7 +226446,6 @@ class CloudService {
226392
226446
  this.cloudBaseContext = context;
226393
226447
  }
226394
226448
  get baseUrl() {
226395
- const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
226396
226449
  const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
226397
226450
  const urlMap = {
226398
226451
  tcb,
@@ -226406,7 +226459,7 @@ class CloudService {
226406
226459
  const intranetUrlMap = Object.keys(urlMap).map((service) => ({
226407
226460
  [service]: `https://${service}.internal.tencentcloudapi.com`,
226408
226461
  })).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
226409
- if (internalEndpoint) {
226462
+ if (constant_1.USE_INTERNAL_ENDPOINT) {
226410
226463
  return intranetUrlMap[this.service];
226411
226464
  }
226412
226465
  if (urlMap[this.service]) {
@@ -270039,7 +270092,7 @@ class CloudBase {
270039
270092
  }
270040
270093
  constructor(config = {}) {
270041
270094
  this.cloudBaseConfig = {};
270042
- let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint } = config;
270095
+ let { secretId, secretKey, token, envId, proxy, region, envType } = config;
270043
270096
  // config 中传入的 secretId secretkey 必须同时存在
270044
270097
  if ((secretId && !secretKey) || (!secretId && secretKey)) {
270045
270098
  throw new Error('secretId and secretKey must be a pair');
@@ -270051,8 +270104,7 @@ class CloudBase {
270051
270104
  envId,
270052
270105
  envType,
270053
270106
  proxy,
270054
- region,
270055
- useInternalEndpoint
270107
+ region
270056
270108
  };
270057
270109
  // 初始化 context
270058
270110
  this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
@@ -270107,9 +270159,6 @@ class CloudBase {
270107
270159
  getManagerConfig() {
270108
270160
  return this.cloudBaseConfig;
270109
270161
  }
270110
- get isInternalEndpoint() {
270111
- return this.context.isInternalEndpoint();
270112
- }
270113
270162
  }
270114
270163
  module.exports = CloudBase;
270115
270164
 
@@ -272188,7 +272237,6 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
272188
272237
  exports.FunctionService = void 0;
272189
272238
  const fs_1 = __importDefault(__webpack_require__(29021));
272190
272239
  const path_1 = __importDefault(__webpack_require__(39902));
272191
- const lodash_1 = __importDefault(__webpack_require__(2543));
272192
272240
  const packer_1 = __webpack_require__(5147);
272193
272241
  const error_1 = __webpack_require__(40430);
272194
272242
  const utils_1 = __webpack_require__(62358);
@@ -272435,96 +272483,20 @@ class FunctionService {
272435
272483
  });
272436
272484
  return data;
272437
272485
  }
272438
- /**
272439
- * 列出所有函数
272440
- * @param {IListFunctionOptions} options
272441
- * @returns {Promise<Record<string, string>[]>}
272442
- */
272443
- async listAllFunctions(options) {
272444
- const allFunctions = [];
272445
- let currentOffset = 0;
272446
- const pageSize = 20;
272447
- const { envId } = options;
272448
- while (true) {
272449
- try {
272450
- const res = await this.scfService.request('ListFunctions', {
272451
- Namespace: envId,
272452
- Limit: pageSize,
272453
- Offset: currentOffset
272454
- });
272455
- const { Functions = [], TotalCount } = res;
272456
- if (Functions.length === 0) {
272457
- break;
272458
- }
272459
- allFunctions.push(...Functions);
272460
- // 检查是否已获取所有函数
272461
- if (allFunctions.length >= TotalCount || Functions.length < pageSize) {
272462
- break;
272463
- }
272464
- currentOffset += pageSize;
272465
- }
272466
- catch (error) {
272467
- throw new error_1.CloudBaseError(`获取函数列表失败: ${error.message}`);
272468
- }
272469
- }
272470
- // 格式化数据
272471
- const data = [];
272472
- allFunctions.forEach(func => {
272473
- const { FunctionId, FunctionName, Runtime, AddTime, ModTime, Status } = func;
272474
- data.push({
272475
- FunctionId,
272476
- FunctionName,
272477
- Runtime,
272478
- AddTime,
272479
- ModTime,
272480
- Status
272481
- });
272482
- });
272483
- return data;
272484
- }
272485
272486
  /**
272486
272487
  * 删除云函数
272487
272488
  * @param {string} name 云函数名称
272488
272489
  * @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
272489
272490
  * @returns {Promise<IResponseInfo>}
272490
272491
  */
272491
- async deleteFunction({ name }) {
272492
- var _a;
272492
+ async deleteFunction(name, qualifier) {
272493
272493
  const { namespace } = this.getFunctionConfig();
272494
- // 检测是否绑定了 API 网关
272495
- const accessService = this.environment.getAccessService();
272496
- const res = await accessService.getAccessList({
272497
- name
272498
- });
272499
- // 删除绑定的 API 网关
272500
- if (((_a = res === null || res === void 0 ? void 0 : res.APISet) === null || _a === void 0 ? void 0 : _a.length) > 0) {
272501
- await accessService.deleteAccess({
272502
- name
272503
- });
272504
- }
272505
- await this.scfService.request('DeleteFunction', {
272494
+ return this.scfService.request('DeleteFunction', {
272506
272495
  FunctionName: name,
272507
- Namespace: namespace
272496
+ Namespace: namespace,
272497
+ Qualifier: qualifier
272508
272498
  });
272509
272499
  }
272510
- /**
272511
- * 批量删除云函数
272512
- * @param {Object} options
272513
- * @param {string[]} options.names 云函数名称列表
272514
- * @returns {Promise<void>}
272515
- */
272516
- async batchDeleteFunctions({ names }) {
272517
- const promises = names.map(name => (async () => {
272518
- try {
272519
- await this.deleteFunction({ name });
272520
- (0, utils_1.successLog)(`[${name}] 函数删除成功!`);
272521
- }
272522
- catch (e) {
272523
- throw new error_1.CloudBaseError(e.message);
272524
- }
272525
- })());
272526
- await Promise.all(promises);
272527
- }
272528
272500
  /**
272529
272501
  * 获取云函数详细信息
272530
272502
  * @param {string} name 云函数名称
@@ -272559,35 +272531,13 @@ class FunctionService {
272559
272531
  }
272560
272532
  catch (e) {
272561
272533
  data.VpcConfig = {
272562
- vpc: 'VpcId',
272563
- subnet: 'SubnetId'
272534
+ vpc: '',
272535
+ subnet: ''
272564
272536
  };
272565
272537
  }
272566
272538
  }
272567
272539
  return data;
272568
272540
  }
272569
- /**
272570
- * 批量获取云函数详细信息
272571
- * @param {Object} options
272572
- * @param {string[]} options.names 云函数名称列表
272573
- * @param {string} options.envId 环境 ID
272574
- * @param {string} options.codeSecret
272575
- * @returns {Promise<IFunctionInfo[]>}
272576
- */
272577
- async batchGetFunctionsDetail({ names, envId, codeSecret }) {
272578
- const data = [];
272579
- const promises = names.map(name => (async () => {
272580
- try {
272581
- const info = await this.getFunctionDetail(name, codeSecret);
272582
- data.push(info);
272583
- }
272584
- catch (e) {
272585
- throw new error_1.CloudBaseError(`${name} 获取信息失败:${e.message}`);
272586
- }
272587
- })());
272588
- await Promise.all(promises);
272589
- return data;
272590
- }
272591
272541
  /**
272592
272542
  * 获取函数日志
272593
272543
  * @deprecated 请使用 getFunctionLogsV2 代替
@@ -272684,33 +272634,6 @@ class FunctionService {
272684
272634
  const res = await this.tcbService.request('GetFunctionLogDetail', params);
272685
272635
  return res;
272686
272636
  }
272687
- /**
272688
- * 获取函数的完整调用日志
272689
- * 该方法会自动完成两步操作:1. 获取日志请求ID列表。 2. 根据ID列表获取每条日志的详细内容。
272690
- * @param {IFunctionLogOptionsV2} options - 查询选项
272691
- * @returns {Promise<IFunctionLogDetailRes[]>} 返回包含完整日志详情的数组
272692
- */
272693
- async getCompleteFunctionLogs(options) {
272694
- // 调用 getFunctionLogsV2 获取日志请求ID列表
272695
- const { name } = options;
272696
- const logs = await this.getFunctionLogsV2(options);
272697
- // 如果没有日志,直接返回空数组
272698
- if (logs.LogList.length === 0) {
272699
- return [];
272700
- }
272701
- const detailPromises = logs.LogList.map(async (log) => {
272702
- // 对每一个日志ID,调用 getFunctionLogDetail
272703
- const res = await this.getFunctionLogDetail({
272704
- logRequestId: log.RequestId,
272705
- startTime: options.startTime,
272706
- endTime: options.endTime
272707
- });
272708
- return Object.assign(Object.assign({}, res), { RetCode: log.RetCode, FunctionName: name });
272709
- });
272710
- // 并发执行所有详情查询,等待它们全部完成
272711
- const detailedLogs = await Promise.all(detailPromises);
272712
- return detailedLogs;
272713
- }
272714
272637
  /**
272715
272638
  * 更新云函数配置
272716
272639
  * @param {ICloudFunction} func 云函数配置
@@ -272846,28 +272769,6 @@ class FunctionService {
272846
272769
  throw new error_1.CloudBaseError(`[${name}] 调用失败:\n${e.message}`);
272847
272770
  }
272848
272771
  }
272849
- /**
272850
- * 批量调用云函数
272851
- * @param {IFunctionBatchOptions} options
272852
- * @returns {Promise<IFunctionInvokeRes[]>}
272853
- */
272854
- async batchInvokeFunctions(options) {
272855
- const { functions, envId, log = false } = options;
272856
- const promises = functions.map(func => (async () => {
272857
- try {
272858
- const result = await this.invokeFunction(func.name, func.params);
272859
- if (log) {
272860
- (0, utils_1.successLog)(`[${func.name}] 调用成功\n响应结果:\n`);
272861
- console.log(result);
272862
- }
272863
- return result;
272864
- }
272865
- catch (e) {
272866
- throw new error_1.CloudBaseError(`${func.name} 函数调用失败:${e.message}`);
272867
- }
272868
- })());
272869
- return Promise.all(promises);
272870
- }
272871
272772
  /**
272872
272773
  * 复制云函数
272873
272774
  * @param {string} name 云函数名称
@@ -272910,34 +272811,12 @@ class FunctionService {
272910
272811
  TriggerDesc: item.config
272911
272812
  };
272912
272813
  });
272913
- try {
272914
- return await this.scfService.request('BatchCreateTrigger', {
272915
- FunctionName: name,
272916
- Namespace: namespace,
272917
- Triggers: JSON.stringify(parsedTriggers),
272918
- Count: parsedTriggers.length
272919
- });
272920
- }
272921
- catch (e) {
272922
- throw new error_1.CloudBaseError(`[${name}] 创建触发器失败:${e.message}`, {
272923
- action: e.action,
272924
- code: e.code
272925
- });
272926
- }
272927
- }
272928
- // 批量部署函数触发器
272929
- async batchCreateTriggers(options) {
272930
- const { functions, envId } = options;
272931
- const promises = functions.map(func => (async () => {
272932
- try {
272933
- await this.createFunctionTriggers(func.name, func.triggers);
272934
- (0, utils_1.successLog)(`[${func.name}] 创建云函数触发器成功!`);
272935
- }
272936
- catch (e) {
272937
- throw new error_1.CloudBaseError(e.message);
272938
- }
272939
- })());
272940
- await Promise.all(promises);
272814
+ return this.scfService.request('BatchCreateTrigger', {
272815
+ FunctionName: name,
272816
+ Namespace: namespace,
272817
+ Triggers: JSON.stringify(parsedTriggers),
272818
+ Count: parsedTriggers.length
272819
+ });
272941
272820
  }
272942
272821
  /**
272943
272822
  * 删除云函数触发器
@@ -272947,50 +272826,12 @@ class FunctionService {
272947
272826
  */
272948
272827
  async deleteFunctionTrigger(name, triggerName) {
272949
272828
  const { namespace } = this.getFunctionConfig();
272950
- try {
272951
- await this.scfService.request('DeleteTrigger', {
272952
- FunctionName: name,
272953
- Namespace: namespace,
272954
- TriggerName: triggerName,
272955
- Type: 'timer'
272956
- });
272957
- (0, utils_1.successLog)(`[${name}] 删除云函数触发器 ${triggerName} 成功!`);
272958
- }
272959
- catch (e) {
272960
- throw new error_1.CloudBaseError(`[${name}] 删除触发器失败:${e.message}`);
272961
- }
272962
- }
272963
- async batchDeleteTriggers(options) {
272964
- const { functions, envId } = options;
272965
- const promises = functions.map(func => (async () => {
272966
- try {
272967
- func.triggers.forEach(async (trigger) => {
272968
- await this.deleteFunctionTrigger(func.name, trigger.name);
272969
- });
272970
- }
272971
- catch (e) {
272972
- throw new error_1.CloudBaseError(e.message);
272973
- }
272974
- })());
272975
- await Promise.all(promises);
272976
- }
272977
- /**
272978
- * 下载云函数代码
272979
- * @param {IFunctionCodeOptions} options
272980
- * @returns {Promise<void>}
272981
- */
272982
- async downloadFunctionCode(options) {
272983
- const { destPath, envId, functionName, codeSecret } = options;
272984
- // 检验路径是否存在
272985
- (0, utils_1.checkFullAccess)(destPath, true);
272986
- // 获取下载链接
272987
- const { Url } = await this.scfService.request('GetFunctionAddress', {
272988
- FunctionName: functionName,
272989
- Namespace: envId,
272990
- CodeSecret: codeSecret
272829
+ return this.scfService.request('DeleteTrigger', {
272830
+ FunctionName: name,
272831
+ Namespace: namespace,
272832
+ TriggerName: triggerName,
272833
+ Type: 'timer'
272991
272834
  });
272992
- // 下载文件
272993
- return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
272994
272835
  }
272995
272836
  /**
272996
272837
  * 获取云函数代码下载 链接
@@ -273016,68 +272857,6 @@ class FunctionService {
273016
272857
  throw new error_1.CloudBaseError(`[${functionName}] 获取函数代码下载链接失败:\n${e.message}`);
273017
272858
  }
273018
272859
  }
273019
- // 函数绑定文件层
273020
- async attachLayer(options) {
273021
- const { envId, functionName, layerName, layerVersion, codeSecret } = options;
273022
- let { Layers = [] } = await this.getFunctionDetail(functionName, codeSecret);
273023
- Layers = Layers.map(item => lodash_1.default.pick(item, ['LayerName', 'LayerVersion']));
273024
- // 新加的文件层添加到最后
273025
- Layers.push({
273026
- LayerName: layerName,
273027
- LayerVersion: layerVersion
273028
- });
273029
- const res = await this.scfService.request('UpdateFunctionConfiguration', {
273030
- Layers,
273031
- Namespace: envId,
273032
- FunctionName: functionName
273033
- });
273034
- return res;
273035
- }
273036
- // 函数解绑文件层
273037
- async unAttachLayer(options) {
273038
- const { envId, functionName, layerName, layerVersion, codeSecret } = options;
273039
- let { Layers } = await this.getFunctionDetail(functionName, codeSecret);
273040
- Layers = Layers.map(item => lodash_1.default.pick(item, ['LayerName', 'LayerVersion']));
273041
- const index = Layers.findIndex(item => item.LayerName === layerName && item.LayerVersion === layerVersion);
273042
- if (index === -1) {
273043
- throw new error_1.CloudBaseError('层不存在');
273044
- }
273045
- // 删除指定的层
273046
- Layers.splice(index, 1);
273047
- const apiParams = {
273048
- Namespace: envId,
273049
- FunctionName: functionName,
273050
- Layers: Layers.length > 0 ? Layers : [{
273051
- LayerName: '',
273052
- LayerVersion: 0
273053
- }]
273054
- };
273055
- return this.scfService.request('UpdateFunctionConfiguration', apiParams);
273056
- }
273057
- // 更新云函数层
273058
- async updateFunctionLayer(options) {
273059
- const { envId, functionName, layers } = options;
273060
- return this.scfService.request('UpdateFunctionConfiguration', {
273061
- Layers: layers,
273062
- Namespace: envId,
273063
- FunctionName: functionName
273064
- });
273065
- }
273066
- // 下载文件层 ZIP 文件
273067
- async downloadLayer(options) {
273068
- const { name, version, destPath } = options;
273069
- const res = await this.scfService.request('GetLayerVersion', {
273070
- LayerName: name,
273071
- LayerVersion: version
273072
- });
273073
- const url = res === null || res === void 0 ? void 0 : res.Location;
273074
- const zipPath = path_1.default.join(destPath, `${name}-${version}.zip`);
273075
- if ((0, utils_1.checkFullAccess)(zipPath)) {
273076
- throw new error_1.CloudBaseError(`文件已存在:${zipPath}`);
273077
- }
273078
- // 下载文件
273079
- return (0, utils_1.downloadAndExtractRemoteZip)(url, destPath);
273080
- }
273081
272860
  // 创建文件层版本
273082
272861
  async createLayer(options) {
273083
272862
  const { env } = this.getFunctionConfig();
@@ -273150,7 +272929,7 @@ class FunctionService {
273150
272929
  Limit: limit,
273151
272930
  Offset: offset,
273152
272931
  SearchKey: searchKey,
273153
- // SearchSrc: `TCB_${env}`
272932
+ SearchSrc: `TCB_${env}`
273154
272933
  };
273155
272934
  if (runtime) {
273156
272935
  param.CompatibleRuntime = runtime;
@@ -273479,18 +273258,12 @@ __decorate([
273479
273258
  __decorate([
273480
273259
  (0, utils_1.preLazy)()
273481
273260
  ], FunctionService.prototype, "listFunctions", null);
273482
- __decorate([
273483
- (0, utils_1.preLazy)()
273484
- ], FunctionService.prototype, "listAllFunctions", null);
273485
273261
  __decorate([
273486
273262
  (0, utils_1.preLazy)()
273487
273263
  ], FunctionService.prototype, "deleteFunction", null);
273488
273264
  __decorate([
273489
273265
  (0, utils_1.preLazy)()
273490
273266
  ], FunctionService.prototype, "getFunctionDetail", null);
273491
- __decorate([
273492
- (0, utils_1.preLazy)()
273493
- ], FunctionService.prototype, "batchGetFunctionsDetail", null);
273494
273267
  __decorate([
273495
273268
  (0, utils_1.preLazy)()
273496
273269
  ], FunctionService.prototype, "getFunctionLogs", null);
@@ -273500,9 +273273,6 @@ __decorate([
273500
273273
  __decorate([
273501
273274
  (0, utils_1.preLazy)()
273502
273275
  ], FunctionService.prototype, "getFunctionLogDetail", null);
273503
- __decorate([
273504
- (0, utils_1.preLazy)()
273505
- ], FunctionService.prototype, "getCompleteFunctionLogs", null);
273506
273276
  __decorate([
273507
273277
  (0, utils_1.preLazy)()
273508
273278
  ], FunctionService.prototype, "updateFunctionConfig", null);
@@ -273512,9 +273282,6 @@ __decorate([
273512
273282
  __decorate([
273513
273283
  (0, utils_1.preLazy)()
273514
273284
  ], FunctionService.prototype, "invokeFunction", null);
273515
- __decorate([
273516
- (0, utils_1.preLazy)()
273517
- ], FunctionService.prototype, "batchInvokeFunctions", null);
273518
273285
  __decorate([
273519
273286
  (0, utils_1.preLazy)()
273520
273287
  ], FunctionService.prototype, "copyFunction", null);
@@ -273527,18 +273294,6 @@ __decorate([
273527
273294
  __decorate([
273528
273295
  (0, utils_1.preLazy)()
273529
273296
  ], FunctionService.prototype, "getFunctionDownloadUrl", null);
273530
- __decorate([
273531
- (0, utils_1.preLazy)()
273532
- ], FunctionService.prototype, "attachLayer", null);
273533
- __decorate([
273534
- (0, utils_1.preLazy)()
273535
- ], FunctionService.prototype, "unAttachLayer", null);
273536
- __decorate([
273537
- (0, utils_1.preLazy)()
273538
- ], FunctionService.prototype, "updateFunctionLayer", null);
273539
- __decorate([
273540
- (0, utils_1.preLazy)()
273541
- ], FunctionService.prototype, "downloadLayer", null);
273542
273297
  __decorate([
273543
273298
  (0, utils_1.preLazy)()
273544
273299
  ], FunctionService.prototype, "createLayer", null);