@cloudbase/cloudbase-mcp 2.0.6 → 2.2.0-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +837 -189
- package/dist/index.cjs +837 -189
- package/dist/index.js +426 -153
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -101,6 +101,7 @@ 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;
|
|
104
105
|
const archiver_1 = __importDefault(__webpack_require__(99133));
|
|
105
106
|
const fs_extra_1 = __webpack_require__(21605);
|
|
106
107
|
const path_1 = __importDefault(__webpack_require__(39902));
|
|
@@ -269,7 +270,7 @@ class CloudRunService {
|
|
|
269
270
|
/**
|
|
270
271
|
* 上传部署包
|
|
271
272
|
*/
|
|
272
|
-
const zipFile = await codeToZip(targetPath, { installDependency: true });
|
|
273
|
+
const zipFile = await codeToZip(targetPath, { installDependency: (serverConfig === null || serverConfig === void 0 ? void 0 : serverConfig.InstallDependency) !== undefined ? serverConfig.InstallDependency : true });
|
|
273
274
|
await (0, utils_1.upload)({
|
|
274
275
|
url: uploadUrl,
|
|
275
276
|
file: zipFile,
|
|
@@ -285,8 +286,14 @@ class CloudRunService {
|
|
|
285
286
|
if (await this._checkFunctionExist(serverName)) {
|
|
286
287
|
// 更新
|
|
287
288
|
const serverDetail = await this.detail({ serverName });
|
|
288
|
-
const _serverConfig = Object.assign(Object.assign(Object.assign({},
|
|
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
|
|
289
290
|
);
|
|
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
|
+
}
|
|
290
297
|
deployInfo.ReleaseType = 'FULL';
|
|
291
298
|
return this._upsertFunction(false, {
|
|
292
299
|
name: serverName,
|
|
@@ -314,7 +321,13 @@ class CloudRunService {
|
|
|
314
321
|
RepoLanguage: 'Node.js'
|
|
315
322
|
};
|
|
316
323
|
}
|
|
317
|
-
const _serverConfig = Object.assign(Object.assign(Object.assign({ OpenAccessTypes: ['OA', 'PUBLIC'
|
|
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:' });
|
|
318
331
|
return this._upsertFunction(true, {
|
|
319
332
|
name: serverName,
|
|
320
333
|
deployInfo,
|
|
@@ -348,11 +361,12 @@ class CloudRunService {
|
|
|
348
361
|
_upsertFunction(isNew, data) {
|
|
349
362
|
const { name, deployInfo, serverConfig } = data;
|
|
350
363
|
const envConfig = this.environment.lazyEnvironmentConfig;
|
|
364
|
+
const Items = parseObjectToDiffConfigItem(serverConfig);
|
|
351
365
|
return this.tcbrService.request(isNew ? 'CreateCloudRunServer' : 'UpdateCloudRunServer', {
|
|
352
366
|
EnvId: envConfig.EnvId,
|
|
353
367
|
ServerName: name,
|
|
354
368
|
DeployInfo: deployInfo,
|
|
355
|
-
|
|
369
|
+
Items,
|
|
356
370
|
});
|
|
357
371
|
}
|
|
358
372
|
}
|
|
@@ -425,6 +439,63 @@ async function codeToZip(cwd, options) {
|
|
|
425
439
|
await archive.finalize();
|
|
426
440
|
return bufferPromise;
|
|
427
441
|
}
|
|
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
|
+
}
|
|
428
499
|
|
|
429
500
|
|
|
430
501
|
/***/ }),
|
|
@@ -23553,7 +23624,7 @@ async function getCloudBaseManager(options = {}) {
|
|
|
23553
23624
|
secretKey,
|
|
23554
23625
|
envId: finalEnvId || loginEnvId,
|
|
23555
23626
|
token,
|
|
23556
|
-
proxy: process.env.http_proxy
|
|
23627
|
+
proxy: process.env.http_proxy,
|
|
23557
23628
|
});
|
|
23558
23629
|
return manager;
|
|
23559
23630
|
}
|
|
@@ -23570,13 +23641,8 @@ async function getCloudBaseManager(options = {}) {
|
|
|
23570
23641
|
function createCloudBaseManagerWithOptions(cloudBaseOptions) {
|
|
23571
23642
|
(0, logger_js_1.debug)('使用传入的 CloudBase 配置创建 manager:', cloudBaseOptions);
|
|
23572
23643
|
const manager = new manager_node_1.default({
|
|
23573
|
-
|
|
23574
|
-
secretKey: cloudBaseOptions.secretKey,
|
|
23575
|
-
envId: cloudBaseOptions.envId,
|
|
23576
|
-
token: cloudBaseOptions.token,
|
|
23644
|
+
...cloudBaseOptions,
|
|
23577
23645
|
proxy: cloudBaseOptions.proxy || process.env.http_proxy,
|
|
23578
|
-
region: cloudBaseOptions.region,
|
|
23579
|
-
envType: cloudBaseOptions.envType
|
|
23580
23646
|
});
|
|
23581
23647
|
return manager;
|
|
23582
23648
|
}
|
|
@@ -38330,7 +38396,7 @@ function registerSQLDatabaseTools(server) {
|
|
|
38330
38396
|
// executeReadOnlySQL
|
|
38331
38397
|
server.registerTool?.("executeReadOnlySQL", {
|
|
38332
38398
|
title: "Execute read-only SQL query",
|
|
38333
|
-
description: "Execute a read-only SQL query on the SQL database. Note: For per-user ACL, each table should contain a fixed `_openid` column that represents the user and is used for access control.",
|
|
38399
|
+
description: "Execute a read-only SQL query on the SQL database. Note: For per-user ACL, each table should contain a fixed `_openid` column defined as `_openid VARCHAR(64) DEFAULT '' NOT NULL` that represents the user and is used for access control.",
|
|
38334
38400
|
inputSchema: {
|
|
38335
38401
|
sql: zod_1.z.string().describe("SQL query statement (SELECT queries only)"),
|
|
38336
38402
|
},
|
|
@@ -38389,7 +38455,7 @@ function registerSQLDatabaseTools(server) {
|
|
|
38389
38455
|
// executeWriteSQL
|
|
38390
38456
|
server.registerTool?.("executeWriteSQL", {
|
|
38391
38457
|
title: "Execute write SQL statement",
|
|
38392
|
-
description: "Execute a write SQL statement on the SQL database (INSERT, UPDATE, DELETE, etc.). Whenever you create a new table, you **must**
|
|
38458
|
+
description: "Execute a write SQL statement on the SQL database (INSERT, UPDATE, DELETE, etc.). Whenever you create a new table, you **must** include a fixed `_openid` column defined as `_openid VARCHAR(64) DEFAULT '' NOT NULL` that represents the user and is used for access control.",
|
|
38393
38459
|
inputSchema: {
|
|
38394
38460
|
sql: zod_1.z
|
|
38395
38461
|
.string()
|
|
@@ -48549,7 +48615,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
48549
48615
|
exports.cloudBaseRequest = cloudBaseRequest;
|
|
48550
48616
|
const auth_1 = __webpack_require__(23506);
|
|
48551
48617
|
const http_request_1 = __webpack_require__(72088);
|
|
48552
|
-
const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou'];
|
|
48618
|
+
const SUPPORT_REGIONS = ['ap-shanghai', 'ap-guangzhou', 'ap-singapore'];
|
|
48553
48619
|
async function cloudBaseRequest(options) {
|
|
48554
48620
|
// const url = 'https://tcb-admin.tencentcloudapi.com/admin'
|
|
48555
48621
|
const { config, params = {}, method = 'POST', headers = {} } = options;
|
|
@@ -48563,11 +48629,11 @@ async function cloudBaseRequest(options) {
|
|
|
48563
48629
|
let internalRegionEndpoint = '';
|
|
48564
48630
|
if (finalRegion) {
|
|
48565
48631
|
if (SUPPORT_REGIONS.includes(finalRegion)) {
|
|
48566
|
-
internetRegionEndpoint = `${finalRegion}.tcb-api.tencentcloudapi.com`;
|
|
48567
|
-
internalRegionEndpoint =
|
|
48632
|
+
internetRegionEndpoint = `${envId}.${finalRegion}.tcb-api.tencentcloudapi.com`;
|
|
48633
|
+
internalRegionEndpoint = `${envId}.internal.${finalRegion}.tcb-api.tencentcloudapi.com`;
|
|
48568
48634
|
}
|
|
48569
48635
|
else {
|
|
48570
|
-
console.warn('
|
|
48636
|
+
console.warn('当前仅支持上海,广州,新加坡地域,其他地域默认解析到固定域名(上海地域)');
|
|
48571
48637
|
internetRegionEndpoint = `tcb-api.tencentcloudapi.com`;
|
|
48572
48638
|
internalRegionEndpoint = `internal.tcb-api.tencentcloudapi.com`;
|
|
48573
48639
|
}
|
|
@@ -90160,19 +90226,20 @@ class EnvService {
|
|
|
90160
90226
|
});
|
|
90161
90227
|
}
|
|
90162
90228
|
getCos() {
|
|
90229
|
+
const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
|
|
90163
90230
|
const { secretId, secretKey, token } = this.environment.getAuthConfig();
|
|
90164
90231
|
const cosConfig = {
|
|
90165
90232
|
SecretId: secretId,
|
|
90166
90233
|
SecretKey: secretKey,
|
|
90167
90234
|
SecurityToken: token,
|
|
90168
|
-
Domain:
|
|
90235
|
+
Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
|
|
90169
90236
|
};
|
|
90170
90237
|
if (constant_1.COS_SDK_PROTOCOL) {
|
|
90171
90238
|
cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
|
|
90172
90239
|
? constant_1.COS_SDK_PROTOCOL.toLowerCase()
|
|
90173
90240
|
: constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
|
|
90174
90241
|
}
|
|
90175
|
-
if (
|
|
90242
|
+
if (internalEndpoint) {
|
|
90176
90243
|
cosConfig.Protocol = 'http:';
|
|
90177
90244
|
}
|
|
90178
90245
|
return new cos_nodejs_sdk_v5_1.default(cosConfig);
|
|
@@ -100306,12 +100373,14 @@ const rag_js_1 = __webpack_require__(64215);
|
|
|
100306
100373
|
const setup_js_1 = __webpack_require__(76556);
|
|
100307
100374
|
const storage_js_1 = __webpack_require__(94848);
|
|
100308
100375
|
// import { registerMiniprogramTools } from "./tools/miniprogram.js";
|
|
100376
|
+
const types_js_1 = __webpack_require__(1294);
|
|
100309
100377
|
const cloudrun_js_1 = __webpack_require__(35023);
|
|
100310
100378
|
const dataModel_js_1 = __webpack_require__(34052);
|
|
100311
100379
|
const gateway_js_1 = __webpack_require__(84319);
|
|
100312
100380
|
const invite_code_js_1 = __webpack_require__(44760);
|
|
100313
100381
|
const security_rule_js_1 = __webpack_require__(7862);
|
|
100314
100382
|
const cloud_mode_js_1 = __webpack_require__(89684);
|
|
100383
|
+
const logger_js_1 = __webpack_require__(13039);
|
|
100315
100384
|
const tool_wrapper_js_1 = __webpack_require__(71363);
|
|
100316
100385
|
// 默认插件列表
|
|
100317
100386
|
const DEFAULT_PLUGINS = [
|
|
@@ -100412,6 +100481,13 @@ async function createCloudBaseMcpServer(options) {
|
|
|
100412
100481
|
...(ide === "CodeBuddy" ? { logging: {} } : {}),
|
|
100413
100482
|
},
|
|
100414
100483
|
});
|
|
100484
|
+
// Only set logging handler if logging capability is declared
|
|
100485
|
+
if (ide === "CodeBuddy") {
|
|
100486
|
+
server.server.setRequestHandler(types_js_1.SetLevelRequestSchema, (request, extra) => {
|
|
100487
|
+
(0, logger_js_1.info)(`--- Logging level: ${request.params.level}`);
|
|
100488
|
+
return {};
|
|
100489
|
+
});
|
|
100490
|
+
}
|
|
100415
100491
|
// Store cloudBaseOptions in server instance for tools to access
|
|
100416
100492
|
if (cloudBaseOptions) {
|
|
100417
100493
|
server.cloudBaseOptions = cloudBaseOptions;
|
|
@@ -100442,10 +100518,10 @@ function getDefaultServer() {
|
|
|
100442
100518
|
}
|
|
100443
100519
|
var stdio_js_1 = __webpack_require__(6166);
|
|
100444
100520
|
Object.defineProperty(exports, "StdioServerTransport", ({ enumerable: true, get: function () { return stdio_js_1.StdioServerTransport; } }));
|
|
100445
|
-
var
|
|
100446
|
-
Object.defineProperty(exports, "error", ({ enumerable: true, get: function () { return
|
|
100447
|
-
Object.defineProperty(exports, "info", ({ enumerable: true, get: function () { return
|
|
100448
|
-
Object.defineProperty(exports, "warn", ({ enumerable: true, get: function () { return
|
|
100521
|
+
var logger_js_2 = __webpack_require__(13039);
|
|
100522
|
+
Object.defineProperty(exports, "error", ({ enumerable: true, get: function () { return logger_js_2.error; } }));
|
|
100523
|
+
Object.defineProperty(exports, "info", ({ enumerable: true, get: function () { return logger_js_2.info; } }));
|
|
100524
|
+
Object.defineProperty(exports, "warn", ({ enumerable: true, get: function () { return logger_js_2.warn; } }));
|
|
100449
100525
|
var telemetry_js_1 = __webpack_require__(45880);
|
|
100450
100526
|
Object.defineProperty(exports, "reportToolCall", ({ enumerable: true, get: function () { return telemetry_js_1.reportToolCall; } }));
|
|
100451
100527
|
Object.defineProperty(exports, "reportToolkitLifecycle", ({ enumerable: true, get: function () { return telemetry_js_1.reportToolkitLifecycle; } }));
|
|
@@ -101741,6 +101817,53 @@ class AsyncReader extends reader_1.default {
|
|
|
101741
101817
|
exports["default"] = AsyncReader;
|
|
101742
101818
|
|
|
101743
101819
|
|
|
101820
|
+
/***/ }),
|
|
101821
|
+
|
|
101822
|
+
/***/ 32720:
|
|
101823
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
101824
|
+
|
|
101825
|
+
"use strict";
|
|
101826
|
+
|
|
101827
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
101828
|
+
exports.sendDeployNotification = sendDeployNotification;
|
|
101829
|
+
const logger_js_1 = __webpack_require__(13039);
|
|
101830
|
+
/**
|
|
101831
|
+
* Send deployment notification to CodeBuddy IDE
|
|
101832
|
+
* @param server ExtendedMcpServer instance
|
|
101833
|
+
* @param notificationData Deployment notification data
|
|
101834
|
+
*/
|
|
101835
|
+
async function sendDeployNotification(server, notificationData) {
|
|
101836
|
+
// Check if current IDE is CodeBuddy (prefer server.ide, fallback to environment variable)
|
|
101837
|
+
const currentIde = server.ide || process.env.INTEGRATION_IDE;
|
|
101838
|
+
if (currentIde !== 'CodeBuddy' || !server.server) {
|
|
101839
|
+
// Not CodeBuddy IDE, skip notification
|
|
101840
|
+
return;
|
|
101841
|
+
}
|
|
101842
|
+
try {
|
|
101843
|
+
// Send notification using sendLoggingMessage
|
|
101844
|
+
server.server.sendLoggingMessage({
|
|
101845
|
+
level: "notice",
|
|
101846
|
+
data: {
|
|
101847
|
+
type: "tcb",
|
|
101848
|
+
event: "deploy",
|
|
101849
|
+
data: {
|
|
101850
|
+
type: notificationData.deployType, // "hosting" or "cloudrun"
|
|
101851
|
+
url: notificationData.url,
|
|
101852
|
+
projectId: notificationData.projectId,
|
|
101853
|
+
projectName: notificationData.projectName,
|
|
101854
|
+
consoleUrl: notificationData.consoleUrl
|
|
101855
|
+
}
|
|
101856
|
+
}
|
|
101857
|
+
});
|
|
101858
|
+
(0, logger_js_1.info)(`CodeBuddy IDE: 已发送部署通知 - ${notificationData.deployType} - ${notificationData.url}`);
|
|
101859
|
+
}
|
|
101860
|
+
catch (err) {
|
|
101861
|
+
// Log error but don't throw - notification failure should not affect deployment flow
|
|
101862
|
+
(0, logger_js_1.error)(`Failed to send deployment notification: ${err instanceof Error ? err.message : err}`, err);
|
|
101863
|
+
}
|
|
101864
|
+
}
|
|
101865
|
+
|
|
101866
|
+
|
|
101744
101867
|
/***/ }),
|
|
101745
101868
|
|
|
101746
101869
|
/***/ 32923:
|
|
@@ -110054,6 +110177,7 @@ const fs_1 = __importDefault(__webpack_require__(29021));
|
|
|
110054
110177
|
const path_1 = __importDefault(__webpack_require__(39902));
|
|
110055
110178
|
const zod_1 = __webpack_require__(21614);
|
|
110056
110179
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
110180
|
+
const notification_js_1 = __webpack_require__(32720);
|
|
110057
110181
|
// CloudRun service types
|
|
110058
110182
|
exports.CLOUDRUN_SERVICE_TYPES = ['function', 'container'];
|
|
110059
110183
|
// CloudRun access types
|
|
@@ -110558,6 +110682,58 @@ for await (let x of res.textStream) {
|
|
|
110558
110682
|
catch (error) {
|
|
110559
110683
|
// Ignore cloudbaserc.json creation errors
|
|
110560
110684
|
}
|
|
110685
|
+
// Send deployment notification to CodeBuddy IDE
|
|
110686
|
+
try {
|
|
110687
|
+
// Query service details to get access URL
|
|
110688
|
+
let serviceUrl = "";
|
|
110689
|
+
try {
|
|
110690
|
+
const serviceDetails = await cloudrunService.detail({ serverName: input.serverName });
|
|
110691
|
+
// Extract access URL from service details
|
|
110692
|
+
// Priority: DefaultDomainName > CustomDomainName > PublicDomain > InternalDomain
|
|
110693
|
+
const details = serviceDetails; // Use any to access dynamic properties
|
|
110694
|
+
if (details?.BaseInfo?.DefaultDomainName) {
|
|
110695
|
+
// DefaultDomainName is already a complete URL (e.g., https://...)
|
|
110696
|
+
serviceUrl = details.BaseInfo.DefaultDomainName;
|
|
110697
|
+
}
|
|
110698
|
+
else if (details?.BaseInfo?.CustomDomainName) {
|
|
110699
|
+
// CustomDomainName might be a domain without protocol
|
|
110700
|
+
const customDomain = details.BaseInfo.CustomDomainName;
|
|
110701
|
+
serviceUrl = customDomain.startsWith('http') ? customDomain : `https://${customDomain}`;
|
|
110702
|
+
}
|
|
110703
|
+
else if (details?.BaseInfo?.PublicDomain) {
|
|
110704
|
+
serviceUrl = `https://${details.BaseInfo.PublicDomain}`;
|
|
110705
|
+
}
|
|
110706
|
+
else if (details?.BaseInfo?.InternalDomain) {
|
|
110707
|
+
serviceUrl = `https://${details.BaseInfo.InternalDomain}`;
|
|
110708
|
+
}
|
|
110709
|
+
else if (details?.AccessInfo?.PublicDomain) {
|
|
110710
|
+
serviceUrl = `https://${details.AccessInfo.PublicDomain}`;
|
|
110711
|
+
}
|
|
110712
|
+
else {
|
|
110713
|
+
serviceUrl = ""; // URL not available
|
|
110714
|
+
}
|
|
110715
|
+
}
|
|
110716
|
+
catch (detailErr) {
|
|
110717
|
+
// If query fails, continue with empty URL
|
|
110718
|
+
serviceUrl = "";
|
|
110719
|
+
}
|
|
110720
|
+
// Extract project name from targetPath
|
|
110721
|
+
const projectName = path_1.default.basename(targetPath);
|
|
110722
|
+
// Build console URL
|
|
110723
|
+
const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${currentEnvId}#/platform-run/service/detail?serverName=${input.serverName}&tabId=overview&envId=${currentEnvId}`;
|
|
110724
|
+
// Send notification
|
|
110725
|
+
await (0, notification_js_1.sendDeployNotification)(server, {
|
|
110726
|
+
deployType: 'cloudrun',
|
|
110727
|
+
url: serviceUrl,
|
|
110728
|
+
projectId: currentEnvId,
|
|
110729
|
+
projectName: projectName,
|
|
110730
|
+
consoleUrl: consoleUrl
|
|
110731
|
+
});
|
|
110732
|
+
}
|
|
110733
|
+
catch (notifyErr) {
|
|
110734
|
+
// Notification failure should not affect deployment flow
|
|
110735
|
+
// Error is already logged in sendDeployNotification
|
|
110736
|
+
}
|
|
110561
110737
|
return {
|
|
110562
110738
|
content: [
|
|
110563
110739
|
{
|
|
@@ -114734,14 +114910,20 @@ module.exports = function (/*Buffer|null*/ inBuffer, /** object */ options) {
|
|
|
114734
114910
|
/***/ }),
|
|
114735
114911
|
|
|
114736
114912
|
/***/ 37279:
|
|
114737
|
-
/***/ ((__unused_webpack_module, exports, __webpack_require__)
|
|
114913
|
+
/***/ (function(__unused_webpack_module, exports, __webpack_require__) {
|
|
114738
114914
|
|
|
114739
114915
|
"use strict";
|
|
114740
114916
|
|
|
114917
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
114918
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
114919
|
+
};
|
|
114741
114920
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
114742
114921
|
exports.registerHostingTools = registerHostingTools;
|
|
114922
|
+
const fs_1 = __importDefault(__webpack_require__(29021));
|
|
114923
|
+
const path_1 = __importDefault(__webpack_require__(39902));
|
|
114743
114924
|
const zod_1 = __webpack_require__(21614);
|
|
114744
114925
|
const cloudbase_manager_js_1 = __webpack_require__(3431);
|
|
114926
|
+
const notification_js_1 = __webpack_require__(32720);
|
|
114745
114927
|
function registerHostingTools(server) {
|
|
114746
114928
|
// 获取 cloudBaseOptions,如果没有则为 undefined
|
|
114747
114929
|
const cloudBaseOptions = server.cloudBaseOptions;
|
|
@@ -114778,6 +114960,43 @@ function registerHostingTools(server) {
|
|
|
114778
114960
|
// 获取环境信息
|
|
114779
114961
|
const envInfo = await cloudbase.env.getEnvInfo();
|
|
114780
114962
|
const staticDomain = envInfo.EnvInfo?.StaticStorages?.[0]?.StaticDomain;
|
|
114963
|
+
const accessUrl = staticDomain ? `https://${staticDomain}/${cloudPath || ''}` : "";
|
|
114964
|
+
// Send deployment notification to CodeBuddy IDE
|
|
114965
|
+
try {
|
|
114966
|
+
const envId = await (0, cloudbase_manager_js_1.getEnvId)(cloudBaseOptions);
|
|
114967
|
+
// Extract project name from localPath
|
|
114968
|
+
let projectName = "unknown";
|
|
114969
|
+
if (localPath) {
|
|
114970
|
+
try {
|
|
114971
|
+
// If localPath is a file, get parent directory name; if it's a directory, get directory name
|
|
114972
|
+
const stats = fs_1.default.statSync(localPath);
|
|
114973
|
+
if (stats.isFile()) {
|
|
114974
|
+
projectName = path_1.default.basename(path_1.default.dirname(localPath));
|
|
114975
|
+
}
|
|
114976
|
+
else {
|
|
114977
|
+
projectName = path_1.default.basename(localPath);
|
|
114978
|
+
}
|
|
114979
|
+
}
|
|
114980
|
+
catch (statErr) {
|
|
114981
|
+
// If stat fails, try to extract from path directly
|
|
114982
|
+
projectName = path_1.default.basename(localPath);
|
|
114983
|
+
}
|
|
114984
|
+
}
|
|
114985
|
+
// Build console URL
|
|
114986
|
+
const consoleUrl = `https://tcb.cloud.tencent.com/dev?envId=${envId}#/static-hosting`;
|
|
114987
|
+
// Send notification
|
|
114988
|
+
await (0, notification_js_1.sendDeployNotification)(server, {
|
|
114989
|
+
deployType: 'hosting',
|
|
114990
|
+
url: accessUrl,
|
|
114991
|
+
projectId: envId,
|
|
114992
|
+
projectName: projectName,
|
|
114993
|
+
consoleUrl: consoleUrl
|
|
114994
|
+
});
|
|
114995
|
+
}
|
|
114996
|
+
catch (notifyErr) {
|
|
114997
|
+
// Notification failure should not affect deployment flow
|
|
114998
|
+
// Error is already logged in sendDeployNotification
|
|
114999
|
+
}
|
|
114781
115000
|
return {
|
|
114782
115001
|
content: [
|
|
114783
115002
|
{
|
|
@@ -114786,7 +115005,7 @@ function registerHostingTools(server) {
|
|
|
114786
115005
|
...result,
|
|
114787
115006
|
staticDomain,
|
|
114788
115007
|
message: "文件上传成功",
|
|
114789
|
-
accessUrl:
|
|
115008
|
+
accessUrl: accessUrl
|
|
114790
115009
|
}, null, 2)
|
|
114791
115010
|
}
|
|
114792
115011
|
]
|
|
@@ -134714,7 +134933,7 @@ class TelemetryReporter {
|
|
|
134714
134933
|
const nodeVersion = process.version; // Node.js版本
|
|
134715
134934
|
const arch = os_1.default.arch(); // 系统架构
|
|
134716
134935
|
// 从构建时注入的版本号获取MCP版本信息
|
|
134717
|
-
const mcpVersion = process.env.npm_package_version || "2.0.
|
|
134936
|
+
const mcpVersion = process.env.npm_package_version || "2.2.0-alpha.0" || 0;
|
|
134718
134937
|
return {
|
|
134719
134938
|
userAgent: `${osType} ${osRelease} ${arch} ${nodeVersion} CloudBase-MCP/${mcpVersion}`,
|
|
134720
134939
|
deviceId: this.deviceId,
|
|
@@ -179312,6 +179531,7 @@ exports.sleep = sleep;
|
|
|
179312
179531
|
exports.upperCaseStringFisrt = upperCaseStringFisrt;
|
|
179313
179532
|
exports.upperCaseObjKey = upperCaseObjKey;
|
|
179314
179533
|
exports.fetchTemplates = fetchTemplates;
|
|
179534
|
+
exports.successLog = successLog;
|
|
179315
179535
|
const archiver_1 = __importDefault(__webpack_require__(99133));
|
|
179316
179536
|
const crypto_1 = __importDefault(__webpack_require__(55511));
|
|
179317
179537
|
const fs_extra_1 = __importDefault(__webpack_require__(21605));
|
|
@@ -179590,6 +179810,10 @@ const getCompleteTimeRange = (timeRange) => {
|
|
|
179590
179810
|
};
|
|
179591
179811
|
};
|
|
179592
179812
|
exports.getCompleteTimeRange = getCompleteTimeRange;
|
|
179813
|
+
function successLog(msg) {
|
|
179814
|
+
// 空格,兼容中文字符编码长度问题
|
|
179815
|
+
console.log(`${msg}`);
|
|
179816
|
+
}
|
|
179593
179817
|
|
|
179594
179818
|
|
|
179595
179819
|
/***/ }),
|
|
@@ -185380,6 +185604,7 @@ async function registerRagTools(server) {
|
|
|
185380
185604
|
}
|
|
185381
185605
|
});
|
|
185382
185606
|
let skills = [];
|
|
185607
|
+
let openapis = [];
|
|
185383
185608
|
// 知识库检索
|
|
185384
185609
|
try {
|
|
185385
185610
|
skills = await prepareKnowledgeBaseWebTemplate();
|
|
@@ -185389,22 +185614,40 @@ async function registerRagTools(server) {
|
|
|
185389
185614
|
error,
|
|
185390
185615
|
});
|
|
185391
185616
|
}
|
|
185617
|
+
// OpenAPI 文档准备
|
|
185618
|
+
try {
|
|
185619
|
+
openapis = await prepareOpenAPIDocs();
|
|
185620
|
+
}
|
|
185621
|
+
catch (error) {
|
|
185622
|
+
(0, logger_js_1.warn)("[searchKnowledgeBase] Failed to prepare OpenAPI docs", {
|
|
185623
|
+
error,
|
|
185624
|
+
});
|
|
185625
|
+
}
|
|
185392
185626
|
server.registerTool?.("searchKnowledgeBase", {
|
|
185393
185627
|
title: "云开发知识库检索",
|
|
185394
|
-
description: `云开发知识库智能检索工具,支持向量查询 (vector)
|
|
185628
|
+
description: `云开发知识库智能检索工具,支持向量查询 (vector)、固定文档 (doc) 和 OpenAPI 文档 (openapi) 查询。
|
|
185395
185629
|
|
|
185396
|
-
强烈推荐始终优先使用固定文档 (doc) 模式进行检索,仅当固定文档无法覆盖你的问题时,再使用向量查询 (vector) 模式。
|
|
185630
|
+
强烈推荐始终优先使用固定文档 (doc) 或 OpenAPI 文档 (openapi) 模式进行检索,仅当固定文档无法覆盖你的问题时,再使用向量查询 (vector) 模式。
|
|
185397
185631
|
|
|
185398
185632
|
固定文档 (doc) 查询当前支持 ${skills.length} 个固定文档,分别是:
|
|
185399
185633
|
${skills
|
|
185400
185634
|
.map((skill) => `文档名:${path.basename(path.dirname(skill.absolutePath))} 文档介绍:${skill.description}`)
|
|
185635
|
+
.join("\n")}
|
|
185636
|
+
|
|
185637
|
+
OpenAPI 文档 (openapi) 查询当前支持 ${openapis.length} 个 API 文档,分别是:
|
|
185638
|
+
${openapis
|
|
185639
|
+
.map((api) => `API名:${api.name} API介绍:${api.description}`)
|
|
185401
185640
|
.join("\n")}`,
|
|
185402
185641
|
inputSchema: {
|
|
185403
|
-
mode: zod_1.z.enum(["vector", "doc"]),
|
|
185642
|
+
mode: zod_1.z.enum(["vector", "doc", "openapi"]),
|
|
185404
185643
|
docName: zod_1.z
|
|
185405
185644
|
.enum(skills.map((skill) => path.basename(path.dirname(skill.absolutePath))))
|
|
185406
185645
|
.optional()
|
|
185407
185646
|
.describe("mode=doc 时指定。文档名称。"),
|
|
185647
|
+
apiName: zod_1.z
|
|
185648
|
+
.enum(openapis.map((api) => api.name))
|
|
185649
|
+
.optional()
|
|
185650
|
+
.describe("mode=openapi 时指定。API 名称。"),
|
|
185408
185651
|
threshold: zod_1.z
|
|
185409
185652
|
.number()
|
|
185410
185653
|
.default(0.5)
|
|
@@ -185434,7 +185677,7 @@ async function registerRagTools(server) {
|
|
|
185434
185677
|
openWorldHint: true,
|
|
185435
185678
|
category: "rag",
|
|
185436
185679
|
},
|
|
185437
|
-
}, async ({ id, content, options: { chunkExpand = [3, 3] } = {}, limit = 5, threshold = 0.5, mode, docName, }) => {
|
|
185680
|
+
}, async ({ id, content, options: { chunkExpand = [3, 3] } = {}, limit = 5, threshold = 0.5, mode, docName, apiName, }) => {
|
|
185438
185681
|
if (mode === "doc") {
|
|
185439
185682
|
const absolutePath = skills.find((skill) => skill.absolutePath.includes(docName)).absolutePath;
|
|
185440
185683
|
return {
|
|
@@ -185446,6 +185689,27 @@ async function registerRagTools(server) {
|
|
|
185446
185689
|
],
|
|
185447
185690
|
};
|
|
185448
185691
|
}
|
|
185692
|
+
if (mode === "openapi") {
|
|
185693
|
+
const api = openapis.find((api) => api.name === apiName);
|
|
185694
|
+
if (!api) {
|
|
185695
|
+
return {
|
|
185696
|
+
content: [
|
|
185697
|
+
{
|
|
185698
|
+
type: "text",
|
|
185699
|
+
text: `OpenAPI document "${apiName}" not found. Available APIs: ${openapis.map((a) => a.name).join(", ")}`,
|
|
185700
|
+
},
|
|
185701
|
+
],
|
|
185702
|
+
};
|
|
185703
|
+
}
|
|
185704
|
+
return {
|
|
185705
|
+
content: [
|
|
185706
|
+
{
|
|
185707
|
+
type: "text",
|
|
185708
|
+
text: `OpenAPI document: ${api.name}\nDescription: ${api.description}\nPath: ${api.absolutePath}\n\n${(await fs.readFile(api.absolutePath)).toString()}`,
|
|
185709
|
+
},
|
|
185710
|
+
],
|
|
185711
|
+
};
|
|
185712
|
+
}
|
|
185449
185713
|
// 枚举到后端 id 映射
|
|
185450
185714
|
const backendId = KnowledgeBaseIdMap[id] || id;
|
|
185451
185715
|
const signInRes = await fetch("https://tcb-advanced-a656fc.api.tcloudbasegateway.com/auth/v1/signin/anonymously", {
|
|
@@ -185522,6 +185786,65 @@ function extractDescriptionFromFrontMatter(content) {
|
|
|
185522
185786
|
.match(/^(?:decsription|description)\s*:\s*(.*)$/m);
|
|
185523
185787
|
return match ? match[1].trim() : null;
|
|
185524
185788
|
}
|
|
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
|
+
}
|
|
185525
185848
|
async function collectSkillDescriptions(rootDir) {
|
|
185526
185849
|
const result = [];
|
|
185527
185850
|
async function walk(dir) {
|
|
@@ -190819,20 +191142,25 @@ function callSuccessCallback(callback, result) {
|
|
|
190819
191142
|
/***/ }),
|
|
190820
191143
|
|
|
190821
191144
|
/***/ 65607:
|
|
190822
|
-
/***/ ((__unused_webpack_module, exports) => {
|
|
191145
|
+
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {
|
|
190823
191146
|
|
|
190824
191147
|
"use strict";
|
|
190825
191148
|
|
|
190826
191149
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
190827
191150
|
exports.CloudBaseContext = void 0;
|
|
191151
|
+
const constant_1 = __webpack_require__(40762);
|
|
190828
191152
|
class CloudBaseContext {
|
|
190829
|
-
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '' }) {
|
|
191153
|
+
constructor({ secretId = '', secretKey = '', token = '', proxy = '', region = '', envType = '', useInternalEndpoint = undefined }) {
|
|
190830
191154
|
this.secretId = secretId;
|
|
190831
191155
|
this.secretKey = secretKey;
|
|
190832
191156
|
this.token = token;
|
|
190833
191157
|
this.proxy = proxy;
|
|
190834
191158
|
this.region = region;
|
|
190835
191159
|
this.envType = envType;
|
|
191160
|
+
this.useInternalEndpoint = useInternalEndpoint;
|
|
191161
|
+
}
|
|
191162
|
+
isInternalEndpoint() {
|
|
191163
|
+
return this.useInternalEndpoint !== undefined ? this.useInternalEndpoint : constant_1.USE_INTERNAL_ENDPOINT;
|
|
190836
191164
|
}
|
|
190837
191165
|
}
|
|
190838
191166
|
exports.CloudBaseContext = CloudBaseContext;
|
|
@@ -200359,7 +200687,7 @@ ${envIdSection}
|
|
|
200359
200687
|
## 环境信息
|
|
200360
200688
|
- 操作系统: ${os_1.default.type()} ${os_1.default.release()}
|
|
200361
200689
|
- Node.js版本: ${process.version}
|
|
200362
|
-
- MCP 版本:${process.env.npm_package_version || "2.0.
|
|
200690
|
+
- MCP 版本:${process.env.npm_package_version || "2.2.0-alpha.0" || 0}
|
|
200363
200691
|
- 系统架构: ${os_1.default.arch()}
|
|
200364
200692
|
- 时间: ${new Date().toISOString()}
|
|
200365
200693
|
- 请求ID: ${requestId}
|
|
@@ -203251,6 +203579,7 @@ class StorageService {
|
|
|
203251
203579
|
* 获取 COS 配置
|
|
203252
203580
|
*/
|
|
203253
203581
|
getCos(parallel = 20) {
|
|
203582
|
+
const internalEndpoint = this.environment.cloudBaseContext.isInternalEndpoint();
|
|
203254
203583
|
const { secretId, secretKey, token, proxy } = this.environment.getAuthConfig();
|
|
203255
203584
|
const cosProxy = process.env.TCB_COS_PROXY;
|
|
203256
203585
|
const cosConfig = {
|
|
@@ -203259,14 +203588,14 @@ class StorageService {
|
|
|
203259
203588
|
SecretKey: secretKey,
|
|
203260
203589
|
Proxy: cosProxy || proxy,
|
|
203261
203590
|
SecurityToken: token,
|
|
203262
|
-
Domain:
|
|
203591
|
+
Domain: internalEndpoint ? "{Bucket}.cos-internal.{Region}.tencentcos.cn" /* COS_ENDPOINT.INTERNAL */ : "{Bucket}.cos.{Region}.tencentcos.cn" /* COS_ENDPOINT.PUBLIC */,
|
|
203263
203592
|
};
|
|
203264
203593
|
if (constant_1.COS_SDK_PROTOCOL) {
|
|
203265
203594
|
cosConfig.Protocol = (constant_1.COS_SDK_PROTOCOL.endsWith(':')
|
|
203266
203595
|
? constant_1.COS_SDK_PROTOCOL.toLowerCase()
|
|
203267
203596
|
: constant_1.COS_SDK_PROTOCOL.toLowerCase() + ':');
|
|
203268
203597
|
}
|
|
203269
|
-
if (
|
|
203598
|
+
if (internalEndpoint) {
|
|
203270
203599
|
cosConfig.Protocol = 'http:';
|
|
203271
203600
|
}
|
|
203272
203601
|
// COSSDK 默认开启 KeepAlive,这里提供关闭的方式
|
|
@@ -214658,26 +214987,26 @@ const path = __importStar(__webpack_require__(39902));
|
|
|
214658
214987
|
const zod_1 = __webpack_require__(21614);
|
|
214659
214988
|
// CloudBase 模板配置
|
|
214660
214989
|
const TEMPLATES = {
|
|
214661
|
-
|
|
214990
|
+
react: {
|
|
214662
214991
|
description: "React + CloudBase 全栈应用模板",
|
|
214663
|
-
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip"
|
|
214992
|
+
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-react-template.zip",
|
|
214664
214993
|
},
|
|
214665
|
-
|
|
214994
|
+
vue: {
|
|
214666
214995
|
description: "Vue + CloudBase 全栈应用模板",
|
|
214667
|
-
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip"
|
|
214996
|
+
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-vue-template.zip",
|
|
214668
214997
|
},
|
|
214669
|
-
|
|
214998
|
+
miniprogram: {
|
|
214670
214999
|
description: "微信小程序 + 云开发模板",
|
|
214671
|
-
url: "https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip"
|
|
215000
|
+
url: "https://static.cloudbase.net/cloudbase-examples/miniprogram-cloudbase-miniprogram-template.zip",
|
|
214672
215001
|
},
|
|
214673
|
-
|
|
215002
|
+
uniapp: {
|
|
214674
215003
|
description: "UniApp + CloudBase 跨端应用模板",
|
|
214675
|
-
url: "https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip"
|
|
215004
|
+
url: "https://static.cloudbase.net/cloudbase-examples/universal-cloudbase-uniapp-template.zip",
|
|
214676
215005
|
},
|
|
214677
|
-
|
|
215006
|
+
rules: {
|
|
214678
215007
|
description: "AI编辑器配置模板(包含所有主流编辑器配置)",
|
|
214679
|
-
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip"
|
|
214680
|
-
}
|
|
215008
|
+
url: "https://static.cloudbase.net/cloudbase-examples/web-cloudbase-project.zip",
|
|
215009
|
+
},
|
|
214681
215010
|
};
|
|
214682
215011
|
// IDE类型枚举
|
|
214683
215012
|
const IDE_TYPES = [
|
|
@@ -214697,22 +215026,13 @@ const IDE_TYPES = [
|
|
|
214697
215026
|
"roocode", // RooCode AI编辑器
|
|
214698
215027
|
"tongyi-lingma", // 通义灵码
|
|
214699
215028
|
"trae", // Trae AI编辑器
|
|
214700
|
-
"vscode" // Visual Studio Code
|
|
215029
|
+
"vscode", // Visual Studio Code
|
|
214701
215030
|
];
|
|
214702
215031
|
// IDE到文件的映射关系
|
|
214703
215032
|
const IDE_FILE_MAPPINGS = {
|
|
214704
|
-
"cursor"
|
|
214705
|
-
|
|
214706
|
-
|
|
214707
|
-
],
|
|
214708
|
-
"windsurf": [
|
|
214709
|
-
".windsurf/rules/cloudbase-rules.md"
|
|
214710
|
-
],
|
|
214711
|
-
"codebuddy": [
|
|
214712
|
-
".rules/cloudbase-rules.md",
|
|
214713
|
-
"CODEBUDDY.md",
|
|
214714
|
-
".mcp.json"
|
|
214715
|
-
],
|
|
215033
|
+
cursor: [".cursor/rules/cloudbase-rules.mdc", ".cursor/mcp.json"],
|
|
215034
|
+
windsurf: [".windsurf/rules/cloudbase-rules.md"],
|
|
215035
|
+
codebuddy: [".rules/cloudbase-rules.md", "CODEBUDDY.md", ".mcp.json"],
|
|
214716
215036
|
"claude-code": [
|
|
214717
215037
|
"CLAUDE.md",
|
|
214718
215038
|
".mcp.json",
|
|
@@ -214721,49 +215041,22 @@ const IDE_FILE_MAPPINGS = {
|
|
|
214721
215041
|
".claude/commands/spec.md",
|
|
214722
215042
|
".claude/commands/no_spec.md",
|
|
214723
215043
|
],
|
|
214724
|
-
|
|
214725
|
-
|
|
214726
|
-
],
|
|
214727
|
-
"
|
|
214728
|
-
".gemini/GEMINI.md",
|
|
214729
|
-
".gemini/settings.json"
|
|
214730
|
-
],
|
|
214731
|
-
"opencode": [
|
|
214732
|
-
".opencode.json"
|
|
214733
|
-
],
|
|
214734
|
-
"qwen-code": [
|
|
214735
|
-
".qwen/QWEN.md",
|
|
214736
|
-
".qwen/settings.json"
|
|
214737
|
-
],
|
|
215044
|
+
cline: [".clinerules/cloudbase-rules.mdc"],
|
|
215045
|
+
"gemini-cli": [".gemini/GEMINI.md", ".gemini/settings.json"],
|
|
215046
|
+
opencode: [".opencode.json"],
|
|
215047
|
+
"qwen-code": [".qwen/QWEN.md", ".qwen/settings.json"],
|
|
214738
215048
|
"baidu-comate": [
|
|
214739
215049
|
".comate/rules/cloudbase-rules.mdr",
|
|
214740
215050
|
".comate/rules/cloudbaase-rules.mdr",
|
|
214741
|
-
".comate/mcp.json"
|
|
214742
|
-
],
|
|
214743
|
-
"openai-codex-cli": [
|
|
214744
|
-
".codex/config.toml",
|
|
214745
|
-
"AGENTS.md",
|
|
215051
|
+
".comate/mcp.json",
|
|
214746
215052
|
],
|
|
214747
|
-
"
|
|
214748
|
-
|
|
214749
|
-
],
|
|
214750
|
-
"
|
|
214751
|
-
|
|
214752
|
-
],
|
|
214753
|
-
"
|
|
214754
|
-
".roo/rules/cloudbaase-rules.md",
|
|
214755
|
-
".roo/mcp.json"
|
|
214756
|
-
],
|
|
214757
|
-
"tongyi-lingma": [
|
|
214758
|
-
".lingma/rules/cloudbaase-rules.md"
|
|
214759
|
-
],
|
|
214760
|
-
"trae": [
|
|
214761
|
-
".trae/rules/cloudbase-rules.md"
|
|
214762
|
-
],
|
|
214763
|
-
"vscode": [
|
|
214764
|
-
".vscode/mcp.json",
|
|
214765
|
-
".vscode/settings.json"
|
|
214766
|
-
]
|
|
215053
|
+
"openai-codex-cli": [".codex/config.toml", "AGENTS.md"],
|
|
215054
|
+
"augment-code": [".augment-guidelines"],
|
|
215055
|
+
"github-copilot": [".github/copilot-instructions.md"],
|
|
215056
|
+
roocode: [".roo/rules/cloudbaase-rules.md", ".roo/mcp.json"],
|
|
215057
|
+
"tongyi-lingma": [".lingma/rules/cloudbaase-rules.md"],
|
|
215058
|
+
trae: [".trae/rules/cloudbase-rules.md"],
|
|
215059
|
+
vscode: [".vscode/mcp.json", ".vscode/settings.json"],
|
|
214767
215060
|
};
|
|
214768
215061
|
// 所有IDE配置文件的完整列表 - 通过IDE_FILE_MAPPINGS计算得出
|
|
214769
215062
|
const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()));
|
|
@@ -214771,51 +215064,87 @@ const ALL_IDE_FILES = Array.from(new Set(Object.values(IDE_FILE_MAPPINGS).flat()
|
|
|
214771
215064
|
IDE_FILE_MAPPINGS["all"] = ALL_IDE_FILES;
|
|
214772
215065
|
// IDE描述映射
|
|
214773
215066
|
const IDE_DESCRIPTIONS = {
|
|
214774
|
-
|
|
214775
|
-
|
|
214776
|
-
|
|
214777
|
-
|
|
215067
|
+
all: "所有IDE配置",
|
|
215068
|
+
cursor: "Cursor AI编辑器",
|
|
215069
|
+
windsurf: "WindSurf AI编辑器",
|
|
215070
|
+
codebuddy: "CodeBuddy AI编辑器",
|
|
214778
215071
|
"claude-code": "Claude Code AI编辑器",
|
|
214779
|
-
|
|
215072
|
+
cline: "Cline AI编辑器",
|
|
214780
215073
|
"gemini-cli": "Gemini CLI",
|
|
214781
|
-
|
|
215074
|
+
opencode: "OpenCode AI编辑器",
|
|
214782
215075
|
"qwen-code": "通义灵码",
|
|
214783
215076
|
"baidu-comate": "百度Comate",
|
|
214784
215077
|
"openai-codex-cli": "OpenAI Codex CLI",
|
|
214785
215078
|
"augment-code": "Augment Code",
|
|
214786
215079
|
"github-copilot": "GitHub Copilot",
|
|
214787
|
-
|
|
215080
|
+
roocode: "RooCode AI编辑器",
|
|
214788
215081
|
"tongyi-lingma": "通义灵码",
|
|
214789
|
-
|
|
214790
|
-
|
|
214791
|
-
};
|
|
215082
|
+
trae: "Trae AI编辑器",
|
|
215083
|
+
vscode: "Visual Studio Code",
|
|
215084
|
+
};
|
|
215085
|
+
// INTEGRATION_IDE 环境变量值到 IDE 类型的映射
|
|
215086
|
+
const INTEGRATION_IDE_MAPPING = {
|
|
215087
|
+
Cursor: "cursor",
|
|
215088
|
+
WindSurf: "windsurf",
|
|
215089
|
+
CodeBuddy: "codebuddy",
|
|
215090
|
+
CodeBuddyManual: "codebuddy",
|
|
215091
|
+
CodeBuddyCode: "codebuddy",
|
|
215092
|
+
"Claude Code": "claude-code",
|
|
215093
|
+
CLINE: "cline",
|
|
215094
|
+
"Gemini CLI": "gemini-cli",
|
|
215095
|
+
OpenCode: "opencode",
|
|
215096
|
+
"Qwen Code": "qwen-code",
|
|
215097
|
+
"Baidu Comate": "baidu-comate",
|
|
215098
|
+
"OpenAI Codex CLI": "openai-codex-cli",
|
|
215099
|
+
"Augment Code": "augment-code",
|
|
215100
|
+
"GitHub Copilot": "github-copilot",
|
|
215101
|
+
RooCode: "roocode",
|
|
215102
|
+
"Tongyi Lingma": "tongyi-lingma",
|
|
215103
|
+
Trae: "trae",
|
|
215104
|
+
VSCode: "vscode",
|
|
215105
|
+
};
|
|
215106
|
+
// 根据 INTEGRATION_IDE 环境变量获取默认 IDE 类型
|
|
215107
|
+
function getDefaultIDEFromEnv() {
|
|
215108
|
+
const integrationIDE = process.env.INTEGRATION_IDE;
|
|
215109
|
+
if (integrationIDE) {
|
|
215110
|
+
const mappedIDE = INTEGRATION_IDE_MAPPING[integrationIDE];
|
|
215111
|
+
if (mappedIDE) {
|
|
215112
|
+
return mappedIDE;
|
|
215113
|
+
}
|
|
215114
|
+
}
|
|
215115
|
+
return "all";
|
|
215116
|
+
}
|
|
214792
215117
|
// 下载文件到临时目录
|
|
214793
215118
|
async function downloadFile(url, filePath) {
|
|
214794
215119
|
return new Promise((resolve, reject) => {
|
|
214795
|
-
const client = url.startsWith(
|
|
214796
|
-
client
|
|
215120
|
+
const client = url.startsWith("https:") ? https : http;
|
|
215121
|
+
client
|
|
215122
|
+
.get(url, (res) => {
|
|
214797
215123
|
if (res.statusCode === 200) {
|
|
214798
215124
|
const file = fs.createWriteStream(filePath);
|
|
214799
215125
|
res.pipe(file);
|
|
214800
|
-
file.on(
|
|
215126
|
+
file.on("finish", () => {
|
|
214801
215127
|
file.close();
|
|
214802
215128
|
resolve();
|
|
214803
215129
|
});
|
|
214804
|
-
file.on(
|
|
215130
|
+
file.on("error", reject);
|
|
214805
215131
|
}
|
|
214806
215132
|
else if (res.statusCode === 302 || res.statusCode === 301) {
|
|
214807
215133
|
// 处理重定向
|
|
214808
215134
|
if (res.headers.location) {
|
|
214809
|
-
downloadFile(res.headers.location, filePath)
|
|
215135
|
+
downloadFile(res.headers.location, filePath)
|
|
215136
|
+
.then(resolve)
|
|
215137
|
+
.catch(reject);
|
|
214810
215138
|
}
|
|
214811
215139
|
else {
|
|
214812
|
-
reject(new Error(
|
|
215140
|
+
reject(new Error("重定向但没有location header"));
|
|
214813
215141
|
}
|
|
214814
215142
|
}
|
|
214815
215143
|
else {
|
|
214816
215144
|
reject(new Error(`下载失败,状态码: ${res.statusCode}`));
|
|
214817
215145
|
}
|
|
214818
|
-
})
|
|
215146
|
+
})
|
|
215147
|
+
.on("error", reject);
|
|
214819
215148
|
});
|
|
214820
215149
|
}
|
|
214821
215150
|
// 解压ZIP文件
|
|
@@ -214828,7 +215157,7 @@ async function extractZip(zipPath, extractPath) {
|
|
|
214828
215157
|
zip.extractAllTo(extractPath, true);
|
|
214829
215158
|
}
|
|
214830
215159
|
catch (error) {
|
|
214831
|
-
throw new Error(`解压失败: ${error instanceof Error ? error.message :
|
|
215160
|
+
throw new Error(`解压失败: ${error instanceof Error ? error.message : "未知错误"}`);
|
|
214832
215161
|
}
|
|
214833
215162
|
}
|
|
214834
215163
|
// 获取目录下所有文件的相对路径列表
|
|
@@ -214852,7 +215181,7 @@ async function copyFileIfNotExists(src, dest) {
|
|
|
214852
215181
|
try {
|
|
214853
215182
|
// 检查目标文件是否存在
|
|
214854
215183
|
if (fs.existsSync(dest)) {
|
|
214855
|
-
return { copied: false, reason:
|
|
215184
|
+
return { copied: false, reason: "文件已存在" };
|
|
214856
215185
|
}
|
|
214857
215186
|
// 创建目标目录
|
|
214858
215187
|
await fsPromises.mkdir(path.dirname(dest), { recursive: true });
|
|
@@ -214861,14 +215190,17 @@ async function copyFileIfNotExists(src, dest) {
|
|
|
214861
215190
|
return { copied: true };
|
|
214862
215191
|
}
|
|
214863
215192
|
catch (error) {
|
|
214864
|
-
return {
|
|
215193
|
+
return {
|
|
215194
|
+
copied: false,
|
|
215195
|
+
reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215196
|
+
};
|
|
214865
215197
|
}
|
|
214866
215198
|
}
|
|
214867
215199
|
// 复制文件,支持覆盖模式
|
|
214868
215200
|
// 判断是否应该跳过 README.md 文件
|
|
214869
215201
|
function shouldSkipReadme(template, destPath, overwrite) {
|
|
214870
|
-
const isReadme = path.basename(destPath).toLowerCase() ===
|
|
214871
|
-
const isRulesTemplate = template ===
|
|
215202
|
+
const isReadme = path.basename(destPath).toLowerCase() === "readme.md";
|
|
215203
|
+
const isRulesTemplate = template === "rules";
|
|
214872
215204
|
const exists = fs.existsSync(destPath);
|
|
214873
215205
|
return isReadme && isRulesTemplate && exists && !overwrite;
|
|
214874
215206
|
}
|
|
@@ -214877,11 +215209,15 @@ async function copyFile(src, dest, overwrite = false, template) {
|
|
|
214877
215209
|
const destExists = fs.existsSync(dest);
|
|
214878
215210
|
// 检查是否需要跳过 README.md 文件(仅对 rules 模板)
|
|
214879
215211
|
if (template && shouldSkipReadme(template, dest, overwrite)) {
|
|
214880
|
-
return {
|
|
215212
|
+
return {
|
|
215213
|
+
copied: false,
|
|
215214
|
+
reason: "README.md 文件已存在,已保护",
|
|
215215
|
+
action: "protected",
|
|
215216
|
+
};
|
|
214881
215217
|
}
|
|
214882
215218
|
// 如果目标文件存在且不允许覆盖
|
|
214883
215219
|
if (destExists && !overwrite) {
|
|
214884
|
-
return { copied: false, reason:
|
|
215220
|
+
return { copied: false, reason: "文件已存在", action: "skipped" };
|
|
214885
215221
|
}
|
|
214886
215222
|
// 创建目标目录
|
|
214887
215223
|
await fsPromises.mkdir(path.dirname(dest), { recursive: true });
|
|
@@ -214889,11 +215225,14 @@ async function copyFile(src, dest, overwrite = false, template) {
|
|
|
214889
215225
|
await fsPromises.copyFile(src, dest);
|
|
214890
215226
|
return {
|
|
214891
215227
|
copied: true,
|
|
214892
|
-
action: destExists ?
|
|
215228
|
+
action: destExists ? "overwritten" : "created",
|
|
214893
215229
|
};
|
|
214894
215230
|
}
|
|
214895
215231
|
catch (error) {
|
|
214896
|
-
return {
|
|
215232
|
+
return {
|
|
215233
|
+
copied: false,
|
|
215234
|
+
reason: `复制失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215235
|
+
};
|
|
214897
215236
|
}
|
|
214898
215237
|
}
|
|
214899
215238
|
// IDE验证函数
|
|
@@ -214901,13 +215240,13 @@ function validateIDE(ide) {
|
|
|
214901
215240
|
if (ide === "all") {
|
|
214902
215241
|
return { valid: true };
|
|
214903
215242
|
}
|
|
214904
|
-
const supportedIDEs = IDE_TYPES.filter(type => type !== "all");
|
|
215243
|
+
const supportedIDEs = IDE_TYPES.filter((type) => type !== "all");
|
|
214905
215244
|
const isValid = supportedIDEs.includes(ide);
|
|
214906
215245
|
if (!isValid) {
|
|
214907
215246
|
return {
|
|
214908
215247
|
valid: false,
|
|
214909
215248
|
error: `不支持的IDE类型: ${ide}`,
|
|
214910
|
-
supportedIDEs: supportedIDEs
|
|
215249
|
+
supportedIDEs: supportedIDEs,
|
|
214911
215250
|
};
|
|
214912
215251
|
}
|
|
214913
215252
|
return { valid: true };
|
|
@@ -214922,9 +215261,9 @@ function filterFilesByIDE(files, ide) {
|
|
|
214922
215261
|
return files; // 如果找不到映射,返回所有文件
|
|
214923
215262
|
}
|
|
214924
215263
|
// 计算需要排除的IDE文件(除了当前IDE需要的文件)
|
|
214925
|
-
const filesToExclude = ALL_IDE_FILES.filter(file => !ideFiles.includes(file));
|
|
215264
|
+
const filesToExclude = ALL_IDE_FILES.filter((file) => !ideFiles.includes(file));
|
|
214926
215265
|
// 排除不需要的IDE配置文件,保留其他所有文件
|
|
214927
|
-
return files.filter(file => !filesToExclude.includes(file));
|
|
215266
|
+
return files.filter((file) => !filesToExclude.includes(file));
|
|
214928
215267
|
}
|
|
214929
215268
|
// 创建过滤后的目录结构
|
|
214930
215269
|
async function createFilteredDirectory(extractDir, filteredFiles, ide) {
|
|
@@ -214932,7 +215271,7 @@ async function createFilteredDirectory(extractDir, filteredFiles, ide) {
|
|
|
214932
215271
|
return extractDir; // 如果选择所有IDE,直接返回原目录
|
|
214933
215272
|
}
|
|
214934
215273
|
// 创建新的过滤后目录
|
|
214935
|
-
const filteredDir = path.join(path.dirname(extractDir),
|
|
215274
|
+
const filteredDir = path.join(path.dirname(extractDir), "filtered");
|
|
214936
215275
|
await fsPromises.mkdir(filteredDir, { recursive: true });
|
|
214937
215276
|
// 只复制过滤后的文件到新目录
|
|
214938
215277
|
for (const relativePath of filteredFiles) {
|
|
@@ -214951,32 +215290,42 @@ function registerSetupTools(server) {
|
|
|
214951
215290
|
title: "下载项目模板",
|
|
214952
215291
|
description: `自动下载并部署CloudBase项目模板。⚠️ **MANDATORY FOR NEW PROJECTS** ⚠️
|
|
214953
215292
|
|
|
214954
|
-
**CRITICAL**: This tool MUST be called FIRST when starting a new project.\n\n支持的模板:\n- react: React + CloudBase 全栈应用模板\n- vue: Vue + CloudBase 全栈应用模板\n- miniprogram: 微信小程序 + 云开发模板 \n- uniapp: UniApp + CloudBase 跨端应用模板\n- rules: 只包含AI编辑器配置文件(包含Cursor、WindSurf、CodeBuddy等所有主流编辑器配置),适合在已有项目中补充AI编辑器配置\n\n支持的IDE类型:\n- all: 下载所有IDE配置(默认)\n- cursor: Cursor AI编辑器\n- windsurf: WindSurf AI编辑器\n- codebuddy: CodeBuddy AI编辑器\n- claude-code: Claude Code AI编辑器\n- cline: Cline AI编辑器\n- gemini-cli: Gemini CLI\n- opencode: OpenCode AI编辑器\n- qwen-code: 通义灵码\n- baidu-comate: 百度Comate\n- openai-codex-cli: OpenAI Codex CLI\n- augment-code: Augment Code\n- github-copilot: GitHub Copilot\n- roocode: RooCode AI编辑器\n- tongyi-lingma: 通义灵码\n- trae: Trae AI编辑器\n- vscode: Visual Studio Code\n\n特别说明:\n- rules 模板会自动包含当前 mcp 版本号信息(版本号:${ true ? "2.0.
|
|
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-alpha.0" : 0}),便于后续维护和版本追踪\n- 下载 rules 模板时,如果项目中已存在 README.md 文件,系统会自动保护该文件不被覆盖(除非设置 overwrite=true)`,
|
|
214955
215294
|
inputSchema: {
|
|
214956
|
-
template: zod_1.z
|
|
214957
|
-
|
|
214958
|
-
|
|
215295
|
+
template: zod_1.z
|
|
215296
|
+
.enum(["react", "vue", "miniprogram", "uniapp", "rules"])
|
|
215297
|
+
.describe("要下载的模板类型"),
|
|
215298
|
+
ide: zod_1.z
|
|
215299
|
+
.enum(IDE_TYPES)
|
|
215300
|
+
.optional()
|
|
215301
|
+
.describe("指定要下载的IDE类型。如果未指定,会根据 INTEGRATION_IDE 环境变量自动选择对应的IDE配置;如果环境变量也未设置,则默认下载所有IDE配置"),
|
|
215302
|
+
overwrite: zod_1.z
|
|
215303
|
+
.boolean()
|
|
215304
|
+
.optional()
|
|
215305
|
+
.describe("是否覆盖已存在的文件,默认为false(不覆盖)"),
|
|
214959
215306
|
},
|
|
214960
215307
|
annotations: {
|
|
214961
215308
|
readOnlyHint: false,
|
|
214962
215309
|
destructiveHint: false,
|
|
214963
215310
|
idempotentHint: false,
|
|
214964
215311
|
openWorldHint: true,
|
|
214965
|
-
category: "setup"
|
|
214966
|
-
}
|
|
214967
|
-
}, async ({ template, ide
|
|
215312
|
+
category: "setup",
|
|
215313
|
+
},
|
|
215314
|
+
}, async ({ template, ide, overwrite = false, }) => {
|
|
214968
215315
|
try {
|
|
215316
|
+
// 如果没有传入 ide 参数,根据 INTEGRATION_IDE 环境变量获取默认值
|
|
215317
|
+
const resolvedIDE = ide ?? getDefaultIDEFromEnv();
|
|
214969
215318
|
// 验证IDE类型
|
|
214970
|
-
const ideValidation = validateIDE(
|
|
215319
|
+
const ideValidation = validateIDE(resolvedIDE);
|
|
214971
215320
|
if (!ideValidation.valid) {
|
|
214972
|
-
const supportedIDEs = ideValidation.supportedIDEs?.join(
|
|
215321
|
+
const supportedIDEs = ideValidation.supportedIDEs?.join(", ") || "";
|
|
214973
215322
|
return {
|
|
214974
215323
|
content: [
|
|
214975
215324
|
{
|
|
214976
215325
|
type: "text",
|
|
214977
|
-
text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}
|
|
214978
|
-
}
|
|
214979
|
-
]
|
|
215326
|
+
text: `❌ ${ideValidation.error}\n\n支持的IDE类型: ${supportedIDEs}`,
|
|
215327
|
+
},
|
|
215328
|
+
],
|
|
214980
215329
|
};
|
|
214981
215330
|
}
|
|
214982
215331
|
const templateConfig = TEMPLATES[template];
|
|
@@ -214985,23 +215334,23 @@ function registerSetupTools(server) {
|
|
|
214985
215334
|
content: [
|
|
214986
215335
|
{
|
|
214987
215336
|
type: "text",
|
|
214988
|
-
text: `❌ 不支持的模板类型: ${template}
|
|
214989
|
-
}
|
|
214990
|
-
]
|
|
215337
|
+
text: `❌ 不支持的模板类型: ${template}`,
|
|
215338
|
+
},
|
|
215339
|
+
],
|
|
214991
215340
|
};
|
|
214992
215341
|
}
|
|
214993
215342
|
// 创建临时目录
|
|
214994
|
-
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(),
|
|
214995
|
-
const zipPath = path.join(tempDir,
|
|
214996
|
-
const extractDir = path.join(tempDir,
|
|
215343
|
+
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "cloudbase-template-"));
|
|
215344
|
+
const zipPath = path.join(tempDir, "template.zip");
|
|
215345
|
+
const extractDir = path.join(tempDir, "extracted");
|
|
214997
215346
|
// 下载和解压
|
|
214998
215347
|
await downloadFile(templateConfig.url, zipPath);
|
|
214999
215348
|
await extractZip(zipPath, extractDir);
|
|
215000
215349
|
const extractedFiles = await getAllFiles(extractDir);
|
|
215001
215350
|
// 根据IDE类型过滤文件
|
|
215002
|
-
const filteredFiles = filterFilesByIDE(extractedFiles,
|
|
215351
|
+
const filteredFiles = filterFilesByIDE(extractedFiles, resolvedIDE);
|
|
215003
215352
|
// 创建过滤后的目录结构(当选择特定IDE时)
|
|
215004
|
-
const workingDir = await createFilteredDirectory(extractDir, filteredFiles,
|
|
215353
|
+
const workingDir = await createFilteredDirectory(extractDir, filteredFiles, resolvedIDE);
|
|
215005
215354
|
// 检查是否需要复制到项目目录
|
|
215006
215355
|
const workspaceFolder = process.env.WORKSPACE_FOLDER_PATHS || process.cwd();
|
|
215007
215356
|
let finalFiles = [];
|
|
@@ -215016,7 +215365,7 @@ function registerSetupTools(server) {
|
|
|
215016
215365
|
const destPath = path.join(workspaceFolder, relativePath);
|
|
215017
215366
|
const copyResult = await copyFile(srcPath, destPath, overwrite, template);
|
|
215018
215367
|
if (copyResult.copied) {
|
|
215019
|
-
if (copyResult.action ===
|
|
215368
|
+
if (copyResult.action === "overwritten") {
|
|
215020
215369
|
overwrittenCount++;
|
|
215021
215370
|
}
|
|
215022
215371
|
else {
|
|
@@ -215025,7 +215374,7 @@ function registerSetupTools(server) {
|
|
|
215025
215374
|
finalFiles.push(destPath);
|
|
215026
215375
|
}
|
|
215027
215376
|
else {
|
|
215028
|
-
if (copyResult.action ===
|
|
215377
|
+
if (copyResult.action === "protected") {
|
|
215029
215378
|
protectedCount++;
|
|
215030
215379
|
}
|
|
215031
215380
|
else {
|
|
@@ -215035,11 +215384,11 @@ function registerSetupTools(server) {
|
|
|
215035
215384
|
}
|
|
215036
215385
|
}
|
|
215037
215386
|
// 添加IDE过滤信息
|
|
215038
|
-
const ideInfo = IDE_DESCRIPTIONS[
|
|
215387
|
+
const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
|
|
215039
215388
|
results.push(`✅ ${templateConfig.description} (${ideInfo}) 同步完成`);
|
|
215040
215389
|
results.push(`📁 临时目录: ${workingDir}`);
|
|
215041
215390
|
results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
|
|
215042
|
-
if (
|
|
215391
|
+
if (resolvedIDE !== "all") {
|
|
215043
215392
|
results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
|
|
215044
215393
|
}
|
|
215045
215394
|
const stats = [];
|
|
@@ -215052,36 +215401,36 @@ function registerSetupTools(server) {
|
|
|
215052
215401
|
if (skippedCount > 0)
|
|
215053
215402
|
stats.push(`跳过 ${skippedCount} 个已存在文件`);
|
|
215054
215403
|
if (stats.length > 0) {
|
|
215055
|
-
results.push(`📊 ${stats.join(
|
|
215404
|
+
results.push(`📊 ${stats.join(",")}`);
|
|
215056
215405
|
}
|
|
215057
215406
|
if (overwrite || overwrittenCount > 0 || skippedCount > 0) {
|
|
215058
|
-
results.push(`🔄 覆盖模式: ${overwrite ?
|
|
215407
|
+
results.push(`🔄 覆盖模式: ${overwrite ? "启用" : "禁用"}`);
|
|
215059
215408
|
}
|
|
215060
215409
|
}
|
|
215061
215410
|
else {
|
|
215062
|
-
finalFiles = filteredFiles.map(relativePath => path.join(workingDir, relativePath));
|
|
215063
|
-
const ideInfo = IDE_DESCRIPTIONS[
|
|
215411
|
+
finalFiles = filteredFiles.map((relativePath) => path.join(workingDir, relativePath));
|
|
215412
|
+
const ideInfo = IDE_DESCRIPTIONS[resolvedIDE] || resolvedIDE;
|
|
215064
215413
|
results.push(`✅ ${templateConfig.description} (${ideInfo}) 下载完成`);
|
|
215065
215414
|
results.push(`📁 保存在临时目录: ${workingDir}`);
|
|
215066
215415
|
results.push(`🔍 文件过滤: ${extractedFiles.length} → ${filteredFiles.length} 个文件`);
|
|
215067
|
-
if (
|
|
215416
|
+
if (resolvedIDE !== "all") {
|
|
215068
215417
|
results.push(`✨ 已过滤IDE配置,仅保留 ${ideInfo} 相关文件`);
|
|
215069
215418
|
}
|
|
215070
|
-
results.push(
|
|
215419
|
+
results.push("💡 如需将模板(包括隐藏文件)复制到项目目录,请确保复制时包含所有隐藏文件。");
|
|
215071
215420
|
}
|
|
215072
215421
|
// 文件路径列表
|
|
215073
|
-
results.push(
|
|
215074
|
-
results.push(
|
|
215075
|
-
finalFiles.forEach(filePath => {
|
|
215422
|
+
results.push("");
|
|
215423
|
+
results.push("📋 文件列表:");
|
|
215424
|
+
finalFiles.forEach((filePath) => {
|
|
215076
215425
|
results.push(`${filePath}`);
|
|
215077
215426
|
});
|
|
215078
215427
|
return {
|
|
215079
215428
|
content: [
|
|
215080
215429
|
{
|
|
215081
215430
|
type: "text",
|
|
215082
|
-
text: results.join(
|
|
215083
|
-
}
|
|
215084
|
-
]
|
|
215431
|
+
text: results.join("\n"),
|
|
215432
|
+
},
|
|
215433
|
+
],
|
|
215085
215434
|
};
|
|
215086
215435
|
}
|
|
215087
215436
|
catch (error) {
|
|
@@ -215089,9 +215438,9 @@ function registerSetupTools(server) {
|
|
|
215089
215438
|
content: [
|
|
215090
215439
|
{
|
|
215091
215440
|
type: "text",
|
|
215092
|
-
text: `❌ 下载模板失败: ${error instanceof Error ? error.message :
|
|
215093
|
-
}
|
|
215094
|
-
]
|
|
215441
|
+
text: `❌ 下载模板失败: ${error instanceof Error ? error.message : "未知错误"}`,
|
|
215442
|
+
},
|
|
215443
|
+
],
|
|
215095
215444
|
};
|
|
215096
215445
|
}
|
|
215097
215446
|
});
|
|
@@ -226043,6 +226392,7 @@ class CloudService {
|
|
|
226043
226392
|
this.cloudBaseContext = context;
|
|
226044
226393
|
}
|
|
226045
226394
|
get baseUrl() {
|
|
226395
|
+
const internalEndpoint = this.cloudBaseContext.isInternalEndpoint();
|
|
226046
226396
|
const tcb = process.env.TCB_BASE_URL || 'https://tcb.tencentcloudapi.com';
|
|
226047
226397
|
const urlMap = {
|
|
226048
226398
|
tcb,
|
|
@@ -226056,7 +226406,7 @@ class CloudService {
|
|
|
226056
226406
|
const intranetUrlMap = Object.keys(urlMap).map((service) => ({
|
|
226057
226407
|
[service]: `https://${service}.internal.tencentcloudapi.com`,
|
|
226058
226408
|
})).reduce((acc, cur) => (Object.assign(Object.assign({}, acc), cur)), {});
|
|
226059
|
-
if (
|
|
226409
|
+
if (internalEndpoint) {
|
|
226060
226410
|
return intranetUrlMap[this.service];
|
|
226061
226411
|
}
|
|
226062
226412
|
if (urlMap[this.service]) {
|
|
@@ -269689,7 +270039,7 @@ class CloudBase {
|
|
|
269689
270039
|
}
|
|
269690
270040
|
constructor(config = {}) {
|
|
269691
270041
|
this.cloudBaseConfig = {};
|
|
269692
|
-
let { secretId, secretKey, token, envId, proxy, region, envType } = config;
|
|
270042
|
+
let { secretId, secretKey, token, envId, proxy, region, envType, useInternalEndpoint } = config;
|
|
269693
270043
|
// config 中传入的 secretId secretkey 必须同时存在
|
|
269694
270044
|
if ((secretId && !secretKey) || (!secretId && secretKey)) {
|
|
269695
270045
|
throw new Error('secretId and secretKey must be a pair');
|
|
@@ -269701,7 +270051,8 @@ class CloudBase {
|
|
|
269701
270051
|
envId,
|
|
269702
270052
|
envType,
|
|
269703
270053
|
proxy,
|
|
269704
|
-
region
|
|
270054
|
+
region,
|
|
270055
|
+
useInternalEndpoint
|
|
269705
270056
|
};
|
|
269706
270057
|
// 初始化 context
|
|
269707
270058
|
this.context = new context_1.CloudBaseContext(this.cloudBaseConfig);
|
|
@@ -269756,6 +270107,9 @@ class CloudBase {
|
|
|
269756
270107
|
getManagerConfig() {
|
|
269757
270108
|
return this.cloudBaseConfig;
|
|
269758
270109
|
}
|
|
270110
|
+
get isInternalEndpoint() {
|
|
270111
|
+
return this.context.isInternalEndpoint();
|
|
270112
|
+
}
|
|
269759
270113
|
}
|
|
269760
270114
|
module.exports = CloudBase;
|
|
269761
270115
|
|
|
@@ -271834,6 +272188,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
|
271834
272188
|
exports.FunctionService = void 0;
|
|
271835
272189
|
const fs_1 = __importDefault(__webpack_require__(29021));
|
|
271836
272190
|
const path_1 = __importDefault(__webpack_require__(39902));
|
|
272191
|
+
const lodash_1 = __importDefault(__webpack_require__(2543));
|
|
271837
272192
|
const packer_1 = __webpack_require__(5147);
|
|
271838
272193
|
const error_1 = __webpack_require__(40430);
|
|
271839
272194
|
const utils_1 = __webpack_require__(62358);
|
|
@@ -272080,20 +272435,96 @@ class FunctionService {
|
|
|
272080
272435
|
});
|
|
272081
272436
|
return data;
|
|
272082
272437
|
}
|
|
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
|
+
}
|
|
272083
272485
|
/**
|
|
272084
272486
|
* 删除云函数
|
|
272085
272487
|
* @param {string} name 云函数名称
|
|
272086
272488
|
* @param {string} qualifier 需要删除的版本号,不填默认删除函数下全部版本。
|
|
272087
272489
|
* @returns {Promise<IResponseInfo>}
|
|
272088
272490
|
*/
|
|
272089
|
-
async deleteFunction(name
|
|
272491
|
+
async deleteFunction({ name }) {
|
|
272492
|
+
var _a;
|
|
272090
272493
|
const { namespace } = this.getFunctionConfig();
|
|
272091
|
-
|
|
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', {
|
|
272092
272506
|
FunctionName: name,
|
|
272093
|
-
Namespace: namespace
|
|
272094
|
-
Qualifier: qualifier
|
|
272507
|
+
Namespace: namespace
|
|
272095
272508
|
});
|
|
272096
272509
|
}
|
|
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
|
+
}
|
|
272097
272528
|
/**
|
|
272098
272529
|
* 获取云函数详细信息
|
|
272099
272530
|
* @param {string} name 云函数名称
|
|
@@ -272128,13 +272559,35 @@ class FunctionService {
|
|
|
272128
272559
|
}
|
|
272129
272560
|
catch (e) {
|
|
272130
272561
|
data.VpcConfig = {
|
|
272131
|
-
vpc: '',
|
|
272132
|
-
subnet: ''
|
|
272562
|
+
vpc: 'VpcId',
|
|
272563
|
+
subnet: 'SubnetId'
|
|
272133
272564
|
};
|
|
272134
272565
|
}
|
|
272135
272566
|
}
|
|
272136
272567
|
return data;
|
|
272137
272568
|
}
|
|
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
|
+
}
|
|
272138
272591
|
/**
|
|
272139
272592
|
* 获取函数日志
|
|
272140
272593
|
* @deprecated 请使用 getFunctionLogsV2 代替
|
|
@@ -272231,6 +272684,33 @@ class FunctionService {
|
|
|
272231
272684
|
const res = await this.tcbService.request('GetFunctionLogDetail', params);
|
|
272232
272685
|
return res;
|
|
272233
272686
|
}
|
|
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
|
+
}
|
|
272234
272714
|
/**
|
|
272235
272715
|
* 更新云函数配置
|
|
272236
272716
|
* @param {ICloudFunction} func 云函数配置
|
|
@@ -272366,6 +272846,28 @@ class FunctionService {
|
|
|
272366
272846
|
throw new error_1.CloudBaseError(`[${name}] 调用失败:\n${e.message}`);
|
|
272367
272847
|
}
|
|
272368
272848
|
}
|
|
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
|
+
}
|
|
272369
272871
|
/**
|
|
272370
272872
|
* 复制云函数
|
|
272371
272873
|
* @param {string} name 云函数名称
|
|
@@ -272408,12 +272910,34 @@ class FunctionService {
|
|
|
272408
272910
|
TriggerDesc: item.config
|
|
272409
272911
|
};
|
|
272410
272912
|
});
|
|
272411
|
-
|
|
272412
|
-
|
|
272413
|
-
|
|
272414
|
-
|
|
272415
|
-
|
|
272416
|
-
|
|
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);
|
|
272417
272941
|
}
|
|
272418
272942
|
/**
|
|
272419
272943
|
* 删除云函数触发器
|
|
@@ -272423,12 +272947,50 @@ class FunctionService {
|
|
|
272423
272947
|
*/
|
|
272424
272948
|
async deleteFunctionTrigger(name, triggerName) {
|
|
272425
272949
|
const { namespace } = this.getFunctionConfig();
|
|
272426
|
-
|
|
272427
|
-
|
|
272428
|
-
|
|
272429
|
-
|
|
272430
|
-
|
|
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
|
|
272431
272991
|
});
|
|
272992
|
+
// 下载文件
|
|
272993
|
+
return (0, utils_1.downloadAndExtractRemoteZip)(Url, destPath);
|
|
272432
272994
|
}
|
|
272433
272995
|
/**
|
|
272434
272996
|
* 获取云函数代码下载 链接
|
|
@@ -272454,6 +273016,68 @@ class FunctionService {
|
|
|
272454
273016
|
throw new error_1.CloudBaseError(`[${functionName}] 获取函数代码下载链接失败:\n${e.message}`);
|
|
272455
273017
|
}
|
|
272456
273018
|
}
|
|
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
|
+
}
|
|
272457
273081
|
// 创建文件层版本
|
|
272458
273082
|
async createLayer(options) {
|
|
272459
273083
|
const { env } = this.getFunctionConfig();
|
|
@@ -272526,7 +273150,7 @@ class FunctionService {
|
|
|
272526
273150
|
Limit: limit,
|
|
272527
273151
|
Offset: offset,
|
|
272528
273152
|
SearchKey: searchKey,
|
|
272529
|
-
SearchSrc: `TCB_${env}`
|
|
273153
|
+
// SearchSrc: `TCB_${env}`
|
|
272530
273154
|
};
|
|
272531
273155
|
if (runtime) {
|
|
272532
273156
|
param.CompatibleRuntime = runtime;
|
|
@@ -272855,12 +273479,18 @@ __decorate([
|
|
|
272855
273479
|
__decorate([
|
|
272856
273480
|
(0, utils_1.preLazy)()
|
|
272857
273481
|
], FunctionService.prototype, "listFunctions", null);
|
|
273482
|
+
__decorate([
|
|
273483
|
+
(0, utils_1.preLazy)()
|
|
273484
|
+
], FunctionService.prototype, "listAllFunctions", null);
|
|
272858
273485
|
__decorate([
|
|
272859
273486
|
(0, utils_1.preLazy)()
|
|
272860
273487
|
], FunctionService.prototype, "deleteFunction", null);
|
|
272861
273488
|
__decorate([
|
|
272862
273489
|
(0, utils_1.preLazy)()
|
|
272863
273490
|
], FunctionService.prototype, "getFunctionDetail", null);
|
|
273491
|
+
__decorate([
|
|
273492
|
+
(0, utils_1.preLazy)()
|
|
273493
|
+
], FunctionService.prototype, "batchGetFunctionsDetail", null);
|
|
272864
273494
|
__decorate([
|
|
272865
273495
|
(0, utils_1.preLazy)()
|
|
272866
273496
|
], FunctionService.prototype, "getFunctionLogs", null);
|
|
@@ -272870,6 +273500,9 @@ __decorate([
|
|
|
272870
273500
|
__decorate([
|
|
272871
273501
|
(0, utils_1.preLazy)()
|
|
272872
273502
|
], FunctionService.prototype, "getFunctionLogDetail", null);
|
|
273503
|
+
__decorate([
|
|
273504
|
+
(0, utils_1.preLazy)()
|
|
273505
|
+
], FunctionService.prototype, "getCompleteFunctionLogs", null);
|
|
272873
273506
|
__decorate([
|
|
272874
273507
|
(0, utils_1.preLazy)()
|
|
272875
273508
|
], FunctionService.prototype, "updateFunctionConfig", null);
|
|
@@ -272879,6 +273512,9 @@ __decorate([
|
|
|
272879
273512
|
__decorate([
|
|
272880
273513
|
(0, utils_1.preLazy)()
|
|
272881
273514
|
], FunctionService.prototype, "invokeFunction", null);
|
|
273515
|
+
__decorate([
|
|
273516
|
+
(0, utils_1.preLazy)()
|
|
273517
|
+
], FunctionService.prototype, "batchInvokeFunctions", null);
|
|
272882
273518
|
__decorate([
|
|
272883
273519
|
(0, utils_1.preLazy)()
|
|
272884
273520
|
], FunctionService.prototype, "copyFunction", null);
|
|
@@ -272891,6 +273527,18 @@ __decorate([
|
|
|
272891
273527
|
__decorate([
|
|
272892
273528
|
(0, utils_1.preLazy)()
|
|
272893
273529
|
], 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);
|
|
272894
273542
|
__decorate([
|
|
272895
273543
|
(0, utils_1.preLazy)()
|
|
272896
273544
|
], FunctionService.prototype, "createLayer", null);
|